Hola.
Bueno, despues de ponerme a migrar algunos juegos de Fenix o Div a Bennu, me entero que hay siempre pequeñas cosas que por un motivo o otro fallan despues en Bennu.
Creo que seria bueno empezar a poner aqui las pequeñas diferencias, errores, o sencillamente cosas que funcionaban de una forma poco lógica en alguna versión de Fenix, etc, y que en Bennu es necessário arreglar para que funcionen correctamente.
De una parte pondria diferencias identificadas, y de otra las cosillas que van surgiendo y buscar la forma de arreglar esa diferencia, para que otros usuarios que seguramente pasarán por alguno de estos problemas, puedan desde un principio con nuestra ayuda, resolver facilmente estas diferencias ya identificadas.
Esto para mi es un mal necessário, pues ya tuve algunos en el primer port, y en los que estoy trabajando tambien estoy encontrando cosas nuevas. Y como todos sabemos, si una cosa no se exprime al máximo, dificilmente sabremos si todo funciona al 100%
Empiezo con una diferencia, y os pido ayuda para ver la forma de poner a funcionar en Bennu:
Tengo un procedimiento disparo(x, y) que en Fenix (Versión 0.84) me funciona perfectamente (lo mismo que en DIV 2), utilizo el siguiente IF, para hacer swith entre distintas colisiones y identificar a cual enemigo estoy tocando:
If(id_colision = collision(Type enemigo1) XOR collision(Type enemigo2) XOR...)
// Despues hago operaciones para el respectivo enemigo
id_colision.vida -= 1;
etc.
En Bennu me da el siguiente error:
Al colisionar con el enemigo: Process 1 not active
o sea, no reconoce el valor de id_colision
Si cambio por
If(id_colision == collision(Type enemigo1) XOR id_colision == collision(Type enemigo2) XOR...)
Error: Process 0 not active, tambien al colidir
Si cambio por
If(id_colision == collision(Type enemigo1) OR id_colision == collision(Type enemigo2) OR...)
me da el mismo error que el de arriba, pero aqui ni necessito que colida, con llamar la funcion disparo peta al instante.
Sugerencias ?¿
Gracias.
vamos por partes...
el proceso no active no te lo da ahi, sino el uso posterior que le das...
en la primer linea tenes = y no ==
XOR es un operador logico, por ende retorna 0 o 1... lo que necesitas es un BXOR o un ^
aunque yo no lo haria de esa forma, ya que el XOR implica ejecucion de ambos terminos, y cuando llamas a un collision con un valor diferente de la llamada anterior, resetea el mismo... por otro lado, al usar XOR si ambos dan colision entonces estarias recibiendo cualquier cosa...
no te sugiero para nada esa forma de uso que le estas dando.
tampoco entiendo como eso funcionaba en Fenix o DIV2, deberia funcionar solo si al menos alguno de los 2 da falso... si ambos dar ok, deberia no detectar...
como bien has dicho, cosas que "funcionaban" de forma poco logicas en fenix, ahora no lo hacen en bennu, efectivamente porque eso se debe a correcciones de bugs... que fenix tenia y ahora bennu no... de no haber existido bennu, seguramente el fenix actual funcionaria de la misma forma que lo hace ahora bennu, ya que se deben a bugs corregidos.
gracias por la consulta.
Si, pero lo que quiero es una solución ;)
El original que funciona en Div1 y Fenix es el primero:
If(id_colision = collision(Type enemigo1) XOR collision(Type enemigo2) XOR...)
, en el segundo pongo == porque sino me da error al compilar, ya que si pongo
If(id_colision = collision(Type enemigo1) XOR id_colision = collision(Type enemigo2) XOR...) me dice que requiere la variable '='.
Probando con BXOR o '^' me dice Process 0 not active al colisionar.
Vamos, lo unico que quiero es que el id_colision se atribuya al la colision originada, que se asigne al processo de esa colision...
pero eso no te va a funcionar bien... si colisiona con mas de 1 objeto a la vez, no va a funcionar correctamente, va a retornar cualquier cosa como id_colision...
claro, por lo que te digo, no es correcto que eso funcione... y si funciona es erratico...
lo mas correcto seria OR
if ( ( id_colision = collision(type ...) ) OR ( id_colision = collision(type ...) ) OR ( id_colision = collision(type ...) ) )
pero... tene en cuenta que va a procesar la primera, si encuentra, no va a testear por las otras colisiones, o sea, que hasta que no termine de barrer el primer type, no va a pasar al 2do... y cuando complete el primero y pase al 2do, retornara solo la primer colision del 2do y luego volvera a escanear el primero...
te digo, esta mal que lo hagas asi
tenes que hacerlo por separado.
1 - Entiendo perfectamente a que te refieres, pero creeme, funciona bien de esa forma aunque no lo parezca, el juego se juega perfectamente y los enemigos muerren todos en simultaneo o solos, y no se interfieren entre ellos.
Esto porque las operaciones que hago para cada uno de ellos es instantanea, se basa practicamente en quitarle enegia y el proceso disparo se hace un break, por eso creo que funciona bien de esta forma, esto hablando con lógica, porque en la practica funciona, recuerda que esto es un port, no me estoy inventando de nuevo el processo de disparo :)
El problema a que me referia no es ese, es que no se asignaba el id_colision a la respectiva colision dada en ese instante, para asignar la variable local al respectivo processo.
2 - Probando ahora mismo tu ejemplo:
Funciona!, a la perfección como en el original de DIV y Fenix :)
Muchas gracias.
Como curiosidad decirte que Bennu es el único que este tipo de condición se escribe de forma distinta a Div, Fenix y al otro comercial :) para que funcione.
Muchas gracias.
Mañana más ;)
misterioso, no entiendo el XOR ese ni pa atrás. ¿De donde sacastes esa formula?
A mi me da que si trabaja a nivel de bits, en el caso de colisionar varios puede devolver un id inexistente, de ahí el error, el misterio es cómo lo resolverá DIV.
a= (0x0001) XOR (0x1011) XOR (0x1001)
( 1010 )
( 0011 )
Si trabaja a nivel de valor haría algo igual de raro porque siempre devolvería o 1 o 0 como id.
a = true XOR true XOR true => da de resultado true
En cambio
a = true XOR false XOR true => da de resultado false
Podría valer para saber si hay un número par de procesos colisionados o no.
En serio, Me intriga pensar quien diseño esa funcionalidad y para qué.
exacto dcelso, no deberia funcionar correctamente si colisionan mas de 1 a la vez
Yo creo que lo que intenta es que colisione sólo con un único tipo de proceso, y a la vez guardar el valor de la colisión en la misma variable.
Creo que lo que realmente intenta es:
If(collision(Type enemigo1) XOR collision(Type enemigo2) XOR...)
Y que el "id_collision=" es de copiar y pegar código sin entender por qué se hace así, si no, no entiendo que guarde TODAS las colisiones en la misma variable, machacando el dato una y otra vez para que sólo quede la última colisión que haga.
De todas formas, es posible que Fenix se hiciera un lio por no poner ningún paréntesis. No me he puesto a analizar el orden de operaciones, pero a poco que no sea el que el programador ha previsto o haya un pequeño bug/error en la interpretación, los resultados pueden ser, buf, ni me lo imagino.
Os resuelvo el misterio chicos:
El XOR lo utilizaba cojido de un ejemplo que vi en DIV, esto hace 10 años.
Tampoco mire en su momento su lógica, solo me interesaban los resultados, ya que estaba prácticamente aprendiendo a programar algo que no fuera basic.
Siempre funciono bien el juego, incluso si el tiro cojia mas de un enemigo en simultaneo (lo que ya os digo que tambien es raro que ocurra).
Despues de este tiempo, lo miro como vosotros, no veo su utilidad, con OR tiene más logica, pero para respetar el original lo dejaria, aunque despues de tener que cambiar el IF en Bennu, tambien los cambie por OR, y funciona exactamente todo igual.
En realidad tambien me parece que funciona por una sencilla razón. el tiro se autodestruye al colidir, el IF asigna el id al primer processo que pille y se destruye el processo (tiro que tenia el IF), así que como dentro hay un case, seguramente el primer case que pille ya hace que el procedimiento asigne el id al primer processo enemigo que pille haciendo acto seguido un Break, el siguiente tiro ya será otro processo, que podrá o no pillar un enemigo distinto.
Tampoco le quiero dar más vueltas ;)
Quote from: Drumpi on October 01, 2009, 12:13:07 AM
Yo creo que lo que intenta es que colisione sólo con un único tipo de proceso, y a la vez guardar el valor de la colisión en la misma variable.
Creo que lo que realmente intenta es:
If(collision(Type enemigo1) XOR collision(Type enemigo2) XOR...)
Y que el "id_collision=" es de copiar y pegar código sin entender por qué se hace así, si no, no entiendo que guarde TODAS las colisiones en la misma variable, machacando el dato una y otra vez para que sólo quede la última colisión que haga.
De todas formas, es posible que Fenix se hiciera un lio por no poner ningún paréntesis. No me he puesto a analizar el orden de operaciones, pero a poco que no sea el que el programador ha previsto o haya un pequeño bug/error en la interpretación, los resultados pueden ser, buf, ni me lo imagino.
Exacto! Lo has entendido perfectamente, sólo quiero que lo asigne a un único tipo de proceso. Aunque con el OR da igual, va pillar sólo uno tambien.
Lo de los parentesis es cierto, Bennu parece que da importancia a la contrución lógica de if's con parentesis, pero por ejemplo en div o fenix, no necesitabas poner tantos parentesis, tenia un ejemplo en algun if que lo demonstraba no se ya donde se daba el caso, pero creo que es mas o menos esto que se me ocurre de ejemplo:
En Div o Fenix, esto te funcionaria correctamente, ejecutar la misma acción con los botones A + B, o solo con el boton C:
IF( key(_a) AND key(_b) OR key(_c) ) accion()
pero en Bennu, tienes que poner los parentesis para definir bien las agrupaciones, sino se lia:
IF( (key(_a) AND key(_b)) OR key(_c)) accion()
Quote from: FreeYourMind on October 01, 2009, 12:20:39 AM
Os resuelvo el misterio chicos:
El XOR lo utilizaba cojido de un ejemplo que vi en DIV, esto hace 10 años.
Tampoco mire en su momento su lógica, solo me interesaban los resultados, ya que estaba prácticamente aprendiendo a programar algo que no fuera basic.
Siempre funciono bien el juego, incluso si el tiro cojia mas de un enemigo en simultaneo (lo que ya os digo que tambien es raro que ocurra).
Despues de este tiempo, lo miro como vosotros, no veo su utilidad, con OR tiene más logica, pero para respetar el original lo dejaria, aunque despues de tener que cambiar el IF en Bennu, tambien los cambie por OR, y funciona exactamente todo igual.
En realidad tambien me parece que funciona por una sencilla razón. el tiro se autodestruye al colidir, el IF asigna el id al primer processo que pille y se destruye el processo (tiro que tenia el IF), así que como dentro hay un case, seguramente el primer case que pille ya hace que el procedimiento asigne el id al primer processo enemigo que pille haciendo acto seguido un Break, el siguiente tiro ya será otro processo, que podrá o no pillar un enemigo distinto.
Tampoco le quiero dar más vueltas ;)
claro, ahi en lo ultimo esta la cosa... seguro funciona porque colisiona 1, lo mata, en el siguiente frame colisiona el otro, pero si fueran casos donde 2 procesos colisionan a la vez contra el objeto y solo en un unico frame, entonces en el siguiente la colision no se producira... como sea, es raro que funcione correctamente... pero bueno...
en realidad no es que bennu se lia, sino que bennu maneja con mas logica las presendecias de los operadores.
Quote from: SplinterGU on October 01, 2009, 12:53:43 AM
en realidad no es que bennu se lia, sino que bennu maneja con mas logica las presendecias de los operadores.
Si claro, es bueno para entender mejor las inumeras condiciones que pongamos, pero si te fijas casi todos los lenguajes evitan que pongamos tantos parentesis, que el resultado será el mismo.
no son necesarios los parentesis mientras sigas estas reglas...
http://forum.bennugd.org/index.php?topic=124.0
lo que sucede es que en fenix se comportan diferente y en div tambien son diferentes a fenix... y si no estas ducho con las reglas es mejor usar los parentesis para evitar errores, ademas que deja bien claro para un analisis humano de los mismos.
El problema viene con las asignaciones Y comparaciones lógicas sin usar paréntesis. Puedes usar los AND y OR sin paréntesis (álgebra aparte), pero con las asignaciones se puede liar.
Es una de las razones por las que nunca hago las asignaciones dentro de los IFs.
Y como dice mi profe de programación y mi profe de análisis vectorial: "los paréntesis, más vale que sobren que no que falten" ;D
FreeYourMind me interesaría muy mucho ver el ejemplo de div del que copiaste la idea, ya que sigo sin entender la utilidad del XOR y oye no está de más aprender algo nuevo de esta función. Todo lo que habeis dicho me sigue pareciendo absurdo, sigo sin ver el resultado de la ejecución, estoy deacuerdo con splinter que de una manera u otra eso no va bien ni por asomo ni en DIV,FENIX,BENNU si hay colisión multiple. solo funciona si hay una única colisión. Quizás ese sea el misterio que viene en el ejemplo de DIV, algo como supongamos que no hay colisiones múltiples en nuestro ejemplo o algo así.
De todas formas, si no recuerdo mal, en DIV los identificadores de los procesos eran siempre números impares, a lo mejor esto, mezclado con un XOR hace que en un id puedas llevar en un mismo id más de un proceso identificado.
Free, ¿serías tan amable de buscar el juego DIV del que copiaste la lógica y compartinos el fuente y los recursos?
Gracias de antemano.
No tiene nada de mas, es el ejemplo es el que puse despues hay un case, te lo completo para que veas, aunque yo ahora utilizo el OR, pero es lo mismo, lo que hace es que al colidir pilla el id del grafico colidido, es muyyyy dificil que pille 2 en el mismo momento, pero me imagino ya que esto de los numeros tiene siempre una orden, que si pilla 2 internamente habra siempre uno primero que otro.
Te pongo el original:
Process disparo(x,y,angle)
Begin
graph=graf_disp;
Repeat
If(id_colision=collision(Type enemigo1) XOR collision(Type enemigo2) XOR collision(Type enemigo3))
Switch(graf_disp); // gráfico de disparo
Case 1:
id_colision.vida-=5; // vida es una variable comun en cada proceso enemigo
If(id_colision.vida > 0) explosion_del_tiro(x, y); End
Break;
End
End
Case 2:
id_colision.vida -= 10;
If(id_colision.vida > 0) explosion_del_tiro(x, y); End
Break;
End
End
advance(10);
Frame;
Until(y<0);
End
ya esta con esto le quita energia al id pillado, y desaparece el tiro con una pequeña explosion de impacto :)
------------------------------
Ahora tengo un nuevo problema, parece que es con el advance() del proceso disparo,
que funciona bien en DIV y Fenix pero no en Bennu:
El tiro se desplaza en el eje Y pero no lo hace en el eje X....
Ejemplo:
Creo 3 tiros:
disparo(x, y, 90000); // Hacia arriba
disparo(x - 6, y, 95000); // Hacia Arriba, Izquierda
disparo(x + 6, y, 85000); // Hacia Arriba, derecha
como se puede ver en el proceso disparo Process disparo(x,y,angle), con advance(10) el tiro se desloca en el eje Y (hacia arriba)
y en el eje X (un tiro hacia la derecha y otro hacia la izquierda), esto funciona en DIV y en Fenix, pero en Bennu, solo se esta moviendo
en el eje Y, no se mueve en el eje X !!!
Soluciones ?¿
Gracias.
Sin ver el proceso disparo es posible que sea cosa del resolution o que le pases mal el ángulo a advance.
El proceso de disparo lo tienes tambien en el mensaje, esta recortado como ejemplo, pero lo relacionado con el movimiento del tiro esta todo ahí.
¿Podrías pasarme el ejemplo completo original de DIV, con recursos y todo?
quisera probarlo, gracis de antemano.
Ups, perdón, no me acordaba.
Bueno, he visto el fallo: suponiendo un desplazamiento de 95º y un desplazamiento de 10 pixels, tu desplazamiento horizontal por cada pixel sería de:
cos(95º)*10=-0,87155742747658173558064270837474
O sea, que en cada avance se mueve aproximadamente 0.8 píxels, que al redondear a entero se queda en 0 pixels.
Puedes crear un float que vaya incrementándose con este valor, pero lo recomendable en tu caso es que uses al menos resolution=10 y reescales a mano todas las constantes de movimiento multiplicando por ese valor (por ejemplo, el advance ahora sería advance(100), y nada más entrar hacer x*=10 e y*=10)
Jo muy buena tu observación Drumpi, si tuviera más carmas que el único que tengo te lo regalaba :)
Pero me temo que no sea ese el problema, el 10 lo puse en el ejemplo, en realidad hacia un advance(16); en el original y estoy haciendo un advance(8); en el port, ya que tiene mitad de la resolución :)
Y tampoco funciona ninguna de las dos en el eje X.
Como funciona eso de float ?, se pueden poner posiciones con float ?? por ejemplo es posible poner un gráfico en la posición x = 3,5 ??
Ese es otro problema al reducir todas las coordenadas cuando se hace un port para mitad de la resolución, con las posiciones que son impares en el original.
Me moskea que con la función de rescalado de resolucion interna lo haga pero a pelo no sepa si es posible ....
Otra cosa, dices que redondear 0.8 se queda en 0, pero no se queda en 1 ?? yo estoy teniendo en cuenta que por ejemplo si es mayor que 1,5 lo redondea a 2, como se hace en las matematicas en general, un redondeo para abajo no tiene sentido !!!
Los valores de posición y movimiento que me dan valores con comas, por ejemplo 2,5, las estoy arredondando manualmente para el valor siguiente, o sea, en este caso seria valor 3.
Quote from: DCelso on October 01, 2009, 01:20:01 PM
¿Podrías pasarme el ejemplo completo original de DIV, con recursos y todo?
quisera probarlo, gracis de antemano.
El ejemplo esta completo en lo que te pongo, solo tiene mas enemigos y cases. El ejemplo funcionando ya lo veras cuando saque el port en 2, 3 dias :) Recortarte ahora el ejemplo del juego y ponerte una demo seria laborioso, pero vamos el resultado ya lo veras en el juego.
Si lo quieres ver ahora mismo, y con XOR's, ya que se me olvidaba, en el port pongo OR's (pero que funciona igual), bajate la versión Windows de mi página:
www.gecasoft.no.sapo.pt
Saludos.
P.S. El ejemplo original no lo tengo y ni se ya de donde era, eso fue hace 10 años, ya ni se donde he estado ayer ;)
He probado con disparo(x + 3, y, 50000); y si que tambien se desloca en el eje X, pero con este valor hace una perfecta diagonal, y yo quiero hacer solo un ligero desvio, como en el original.
Pero con esto, es lo que comentas Drumpi, solo puede ser originado por redondeos de Bennu, Splinter que solución tiene esto ??
Porque en Div y Fenix esto iba bien, que cambios hiciste en la funcion advance ?? Que tengo que hacer ?
Gracias.
Haciendo más pruebas , la verdad yo flipo en colores con esto, sólo me fallan 2 casos, los que habia puesto:
disparo(x - 3, y, 95000);
disparo(x + 3, y, 85000);
disparo(x - 3, y, 100000);
disparo(x + 3, y, 80000);
disparo(x - 3, y, 105000);
disparo(x + 3, y, 75000);
disparo(x - 3, y, 110000);
disparo(x + 3, y, 70000);
disparo(x - 3, y, 115000);
disparo(x + 3, y, 65000);
Esto crea 10 ramas de tiros, cada vez mas distantes del centro que las crea, hacia la derecha y izquierda.
Y sólo los 2 primeros no se desplazan en el eje del x.
Ya he encontrado el error, te sobra un punto y coma al final del switch, quitalo, pero esto no es el problema, el problema es que también te sobra un end al final del primer case.
He hecho un ejemplo con mi dragon, he puesto tus 10 disparos, he hecho que vaya más lento para poder contarlos y salen los 10 disparos y cada uno va para su lado. Me ha encantado el resultado, queda muy chulo :D.
Id colision debería de ser una variable local o privada para evitar problemas de ámbito, no se si la tendrás como global, cámbiala en ese caso.
Process disparo(x,y,angle)
local
id_colision;
Begin
graph=graf_disp;
Repeat
If(id_colision=collision(Type enemigo1) XOR collision(Type enemigo2) XOR collision(Type enemigo3))
Switch(graf_disp); // gráfico de disparo
Case 1:
//id_colision.vida-=5; // vida es una variable comun en cada proceso enemigo
//If(id_colision.vida > 0) explosion_del_tiro(x, y); End
Break;
End
Case 2:
//id_colision.vida -= 10;
//If(id_colision.vida > 0) explosion_del_tiro(x, y); End
Break;
end
End
End
advance(5);
Frame(500);
Until(y<0);
End
Por cierto, si ese código te fué en fenix fué de chiripa :D
Perdona pero es código de todo el proceso que te puse ya sabia que podria faltarle un end, o algo, lo he contruido por partes porque una parte era para hablar del xor y la otra del advance ;)
Perdonar si llevasteis el ejemplo a la letra haciendo copy / paste para probarlo.
Sobre lo del advance() sigo con el problema de que para
disparo(x - 3, y, 95000);
disparo(x + 3, y, 85000);
no se mueve en el eje X.
Por favor compruebalo en tu ejemplo, ya que lo has montado, y dime si tambien te ocurre :)
Gracias.
Si, corre bien. Pero he detectado un bug, creo en advance, he acotado el problema y voy a informar de ello.
Este bug no afecta a tu código, es decir, que va bien, pero mejor es que se localize y elimine :D.
Vas a tener que revisar mi ejemplo para ver en que se diferencia del tuyo porque en este si va, si pones tu codigo completo quizas podamos dar con el error en cuestión.
Oye, pero tu estas probando en Div no ?? :)
Porque el mio tb funciona bien en div o fenix, el problema del advance es solo en Bennu y solo para esos 2 angulos en concreto.
Tu ejemplo solo puede funcionar en div o fenix, porque el if que has construido (que es igual al mio original) se tiene que modificar para para que funcione en Bennu, como ya comentamos en este post antes:
IF((id_colision = collision(Type enemigo1)) OR (id_colision = collision(Type enemigo2)) OR (id_colision = collision(Type enemigo3))
Edito: Yo tambien la tengo declarada como local pero al principio del programa. Y como te decia, de la forma que lo tienes tambien compila en Bennu pero al chocar me daba error de 'Process 0,1 not active'
Quote from: DCelso on October 01, 2009, 07:44:17 AM
...
De todas formas, si no recuerdo mal, en DIV los identificadores de los procesos eran siempre números impares, a lo mejor esto, mezclado con un XOR hace que en un id puedas llevar en un mismo id más de un proceso identificado.
par o impar no tiene nada que ver.
Quote from: FreeYourMind on October 01, 2009, 10:14:55 AM
No tiene nada de mas, es el ejemplo es el que puse despues hay un case, te lo completo para que veas, aunque yo ahora utilizo el OR, pero es lo mismo, lo que hace es que al colidir pilla el id del grafico colidido, es muyyyy dificil que pille 2 en el mismo momento, pero me imagino ya que esto de los numeros tiene siempre una orden, que si pilla 2 internamente habra siempre uno primero que otro.
Te pongo el original:
Process disparo(x,y,angle)
Begin
graph=graf_disp;
Repeat
If(id_colision=collision(Type enemigo1) XOR collision(Type enemigo2) XOR collision(Type enemigo3))
Switch(graf_disp); // gráfico de disparo
Case 1:
id_colision.vida-=5; // vida es una variable comun en cada proceso enemigo
If(id_colision.vida > 0) explosion_del_tiro(x, y); End
Break;
End
End
Case 2:
id_colision.vida -= 10;
If(id_colision.vida > 0) explosion_del_tiro(x, y); End
Break;
End
End
advance(10);
Frame;
Until(y<0);
End
ya esta con esto le quita energia al id pillado, y desaparece el tiro con una pequeña explosion de impacto :)
------------------------------
Ahora tengo un nuevo problema, parece que es con el advance() del proceso disparo,
que funciona bien en DIV y Fenix pero no en Bennu:
El tiro se desplaza en el eje Y pero no lo hace en el eje X....
Ejemplo:
Creo 3 tiros:
disparo(x, y, 90000); // Hacia arriba
disparo(x - 6, y, 95000); // Hacia Arriba, Izquierda
disparo(x + 6, y, 85000); // Hacia Arriba, derecha
como se puede ver en el proceso disparo Process disparo(x,y,angle), con advance(10) el tiro se desloca en el eje Y (hacia arriba)
y en el eje X (un tiro hacia la derecha y otro hacia la izquierda), esto funciona en DIV y en Fenix, pero en Bennu, solo se esta moviendo
en el eje Y, no se mueve en el eje X !!!
Soluciones ?¿
Gracias.
OR y XOR no son lo mismo para nada...
una condicion con OR, si el primer terminos unido al OR da TRUE, entonces ya no se chequean las condiciones/terminos siguiente... y XOR evalua todos los terminos, esto con los operadores logicos...
DIV y FENIX (version antigua)... los operadores logicos no existen, son todos operadores binarios, lo que implica que todos los terminos se ejecuten si o si... pero en las ultimas version de Fenix, eso no es asi, hay operadores logicos y binarios por separados... los logicos cuando la condicion evaluada resuelve toda la expresion, ya no se sigue evaluando las demas condiciones... con los operadores binarios, se evaluan todas las condiciones, porque logicamente se necesitan...
sin embargo XOR (logico o binario, el logico solo existe en Bennu y ultimas version de fenix, en ningun otro lenguaje que yo conozca existe), necesita si o si se evaluen todos los terminos de la expresion... por la propiedad del XOR.
esa es la gran diferencia...
y el ejemplo, solo te funciona en div y viejas versiones de fenix, solo si la colision se produce en cantidades impares de disparos simultaneamente... o sea, el if sera en esos casos disparado por TRUE... pero el id sera el del ultimo tipo controlado.
como sea, no es un buen mecanismo.
con respecto al avance... cuando se usa avance hay que usar resolution... porque en casos donde de valores entre 0-1 (angulos rectos o casi rectos) puede al redondear nunca se incremente alguna de las coordenadas (como dijo drumpi).
por ejemplos completos, no sirve de mucho trozos de codigo en los que agregas nuevos bugs...
el escalado nativo de bennu, es solo representacion de los datos en pantalla, el juego sigue corriendo (y todo se sigue dibujando) en la resolucion original, solo el dumpeo a pantalla se hace escalado...
ahora si vos estas haciendo un escalado a mano de todo tu codigo, entonces el problema quizas viene por ahi.
otra cosa, es que las coordenadas son enteras, asi que no sirve de nada que hagas un +.5 o -.5 (segun el caso), el redondeo es siempre quitando la parte decimal, es el redondeo natural que se hace en los ordenadores.
debes usar resolution (que nada tiene que ver con el escalado de imagen)
Quote from: FreeYourMind on October 01, 2009, 02:39:09 PM
Jo muy buena tu observación Drumpi, si tuviera más carmas que el único que tengo te lo regalaba :)
Pero me temo que no sea ese el problema, el 10 lo puse en el ejemplo, en realidad hacia un advance(16); en el original y estoy haciendo un advance(8); en el port, ya que tiene mitad de la resolución :)
Y tampoco funciona ninguna de las dos en el eje X.
Como funciona eso de float ?, se pueden poner posiciones con float ?? por ejemplo es posible poner un gráfico en la posición x = 3,5 ??
Ese es otro problema al reducir todas las coordenadas cuando se hace un port para mitad de la resolución, con las posiciones que son impares en el original.
Me moskea que con la función de rescalado de resolucion interna lo haga pero a pelo no sepa si es posible ....
Otra cosa, dices que redondear 0.8 se queda en 0, pero no se queda en 1 ?? yo estoy teniendo en cuenta que por ejemplo si es mayor que 1,5 lo redondea a 2, como se hace en las matematicas en general, un redondeo para abajo no tiene sentido !!!
Los valores de posición y movimiento que me dan valores con comas, por ejemplo 2,5, las estoy arredondando manualmente para el valor siguiente, o sea, en este caso seria valor 3.
Lo del XOR lo he entendido ya hace varios post. No soy yo que sigo insistiendo, lo mejor seria no mezclar las cosas :)
Ahora el problema es el advance, y tienes el ejemplo completo, puedes mirarlo ya compilado con esta modificacion del ejemplo de
DCelso, con la tecla 'd' puedes echar lineas continuas de disparos, estos 2 angulos no me funcionan, no se mueve en el eje X:
disparo(x - 3, y, 95000);
disparo(x + 3, y, 85000);
veras que estos disparos solo se mueven en la vertical y los otros se mueven tb en el eje x formando lineas oblicuas en forma de piramide.
Por favor dime como utilizar el resolution, que ya lo intente pero no consegui nada. Si puedes ponlo en el ejemplo para que los 10 tiros funcionen todos correctamente, en especial estos 2 que son los que no van.
Gracias.
Quote from: splinter_work on October 01, 2009, 06:35:03 PM
el escalado nativo de bennu, es solo representacion de los datos en pantalla, el juego sigue corriendo (y todo se sigue dibujando) en la resolucion original, solo el dumpeo a pantalla se hace escalado...
ahora si vos estas haciendo un escalado a mano de todo tu codigo, entonces el problema quizas viene por ahi.
otra cosa, es que las coordenadas son enteras, asi que no sirve de nada que hagas un +.5 o -.5 (segun el caso), el redondeo es siempre quitando la parte decimal, es el redondeo natural que se hace en los ordenadores.
debes usar resolution (que nada tiene que ver con el escalado de imagen)
Esto que dices es lo mismo que decia yo :)
Lo se, la pregunta es:
En los casos en que no quieres usar el escalado nativo (como el caso) por problemas de definición de algunos gráficos o fuentes.
Por código no hay forma de definir posiciones x o y con valores decimales ??
Porque como comente haciendo el rescalado manualmente por código, como trabajas con enteros vas a tener este problema en algunos casos, en que con el redondeo no vas a tener la posicíón exacta o deslocación identica al original en el port de menor resolución.
Y sobre el rescalado, al hacer la representación en pantalla, esta representación segun parece si pone todos los gráficos en su respectiva posición exacta al rescalar el juego a mitad de resolución.
ok, voy a ver
Tenías razón Splinter y tu tambien Drumpi, este problema es por resolución. Probado
Free, el resolution es una variable local, como x, e y. Sirve para hacer que las coordenadas del proceso se refieran al width y height puestos en set mode multiplicados por resolution. Es decir, si set mode es tal que asi set_mode(320,200,32) y en un proceso ponemos resolution =10;
para ese proceso los valores posibles en pantalla serán los comprendidos enre 3200 y 2000, por tanto un advance(1) en este contexto sería parecido (ya que no se puede) a hacer un advance(0.1) sin resolution.
Así que para aprovecharnos de la resolucion, tenemos que cambiarla en el proceso, multipicar x e y de entrada por este valor y multiplicar el advance también por este valor.
El código ejemplo que me pasaste lo he modificado para que veas su funcionamiento.
Por otro lado el while(key(_d))frame;end, es un truco para evitar el encadenamiento masivo de llamadas al disparo, lo que dice es mientras esté pulsada la tecla d pasa al siguiente frame y no hagas nada, quiere decir que hasta que no soltemos la tecla no saldremos del bucle por tanto no se generarán nuevos disparos, para hacer dos disparos deberias de pulsar dos veces la tecla.
import "mod_key"
import "mod_proc"
import "mod_map"
import "mod_video"
import "mod_time"
import "mod_grproc"
global
int graf_disp;
type st_pose
int graph;
int m_sec;
end
Begin
set_mode(320,240,32);
graf_disp=load_png("recursos/bolafuego.png");
dragon();
Repeat
frame;
Until(key(_ESC))
exit();
End
Process dragon()
Private
st_pose poses[5];
i;
int cur_pos;
int ini_time,passed;
Begin
x=160;
y=200;
for (i=0;i<5;i++)
poses[i].graph = load_png("recursos/dragon"+(i+1)+".png");
poses[i].m_sec = 200;
end
poses[0].m_sec = 1000;
poses[4].m_sec = 300;
ini_time = get_timer();
while(!key(_esc))
passed = get_timer() - ini_time;
if (passed > poses[cur_pos].m_sec)
ini_time = get_timer();
cur_pos++;
if (cur_pos >= 5)
cur_pos = 0;
end
end
graph=poses[cur_pos].graph;
if (key(_d))
disparo(x - 3, y, 95000);
disparo(x + 3, y, 85000);
while(key(_d)) frame; end
end
frame;
End
for (i=0;i<5;i++)
unload_map(0,poses[i].graph);
end
End
Process enemigo1()
begin
end
Process enemigo2()
begin
end
Process enemigo3()
begin
end
Process disparo(x,y,angle)
local
id_colision;
Begin
resolution = 10;
x*=resolution;
y*=resolution;
graph=graf_disp;
Repeat
If(id_colision=collision(Type enemigo1) XOR collision(Type enemigo2) XOR collision(Type enemigo3))
Switch(graf_disp); // gráfico de disparo
Case 1:
//id_colision.vida-=5; // vida es una variable comun en cada proceso enemigo
//If(id_colision.vida > 0) explosion_del_tiro(x, y); End
Break;
End
Case 2:
//id_colision.vida -= 10;
//If(id_colision.vida > 0) explosion_del_tiro(x, y); End
Break;
end
End
End
advance(5*resolution);
Frame;//(500);
Until(y<0);
End
Verás, Freeyourmind, X e Y no pueden tener nunca valores decimales porque se refieren a pixels en pantalla, y por definición, un pixel es la unidad mínima de información de una pantalla.
Sin embargo, resolution te da una alternativa, resolution indica cuantos puntos hay dentro de un pixel. Si vale dos, significa que para pasar de un pixel a otro tendrás que moverte 2 puntos (sumar 2 a la coordenada X), si vale diez los incrementos deberán ser de 10.
Obviamente, si resolution vale 10, cuando se vaya a dibujar en pantalla, la x=357 de sibujará en el pixel horizontal x=35. Los lenguajes de programación no redondean, truncan (eliminan las cifras de menor peso), que es como decir que redondean hacia cero.
Para moverte 0.08 pixels deberías tener resolution=100 y moverte 8 pixels por frame. Espero que con el código que te ha puesto DCelso esté más claro.
Para que los ángulos funcionen perfectos se recomiendan valores de resolution de 1000, pero esto provoca un desbordamiento de int demasiado pronto (mi FZero me lo advirtió), así que un valor de 100 es más que suficiente.
Por cierto: los ID de los procesos valen números impares, es cierto, y en DIV y Fenix era un detalle importante, porque antes de que Splinter le metirea mano al código, TODOS los valores impares eran equivalentes a TRUE, y TODOS los pares a FALSE. A partir de Fenix 0.85 hasta el Bennu actual sólo el cero se considera valor FALSE, y el resto TRUE.
DCelso, ya habia visto tu ejemplo en el post del bug de advance :)
Dumpi, gracias a los dos, ya me habia dado cuenta por el ejemplo de DCelso mas o menos del tema.
Sólo hay unos pocos casos contados en que tendria problema al dividir coordenadas de x,y a la mitad (o sea, casos en que eran impares y la división da un decimal 1,5; 2,5,etc.) En estos casos lo que hice fue redondear manualmente el valor de x,y.
Ya me entero que el compilador en redondeos ignora el segundo quitando el decimal y quedandose solo con la parte entera.
Si por ejemplo tuvieramos 2,8 el valor final seria 2.
Aunque esto no es visible a nuestos ojos, lo hara en sus funciones internas como por ejemplo el advance(), porque si pones por ejemplo x=2,5 el compilador te va da error de compilación, así que tampoco te lo deja poner :) o que es lo mismo, tampoco va efectuar ningun redondeo en ese caso :)
Hacer el resolution para estos casos de posición seria entonces una solución, pero para lo engoroso que puede resultar en algunos casos, es mejor dejar un entero aproximado que ponerse con eso, ya que en ese proceso puede que utilizemos los valores de x,y para otras operaciones en que no tengamos problemas de division con decimales al hacer el rescalado manualmente, y tendriamos que adaptar todos los x,y teniendo en cuanta que los estabamos afectando con el resolution.
---------
Para terminar el tema del advance(), queda por resolver la otra diferencia que comentaba en el foro de 'bug de advance', es que utilizando el resolution para crear los 10 disparos, no se forma una piramide perfecta (linea horizontal en la parte de arriba del flujo de tiro), pero si un arco (que queda chulo, pero no es mismo comportamiento, para una conversión pixel perfect:)), es como si en las lineas de disparo que tienen mayor angulo (desde la origen del tiro, o sea las lineas externas) a medida que el angulo aumenta el valor de la velocidad del Y diminuye, y deberia ser la misma velocidad en todas las lineas, porque al poner por ejemplo advance(8) el desplazamiento deberia ser identico en eje Y, independientemente del angulo, vamos, como lo hace Fenix (0.84) o Div (y que estos no tienen problemas con angulos pequeños, ni tenemos que usar el resolution para estos angulos, pero eso ya es otra historia).
Por eso hay que tener en cuenta el uso de resolution desde el principio.
Respondiendo al segundo tema, te remito al hilo que mencionas.
fenix, versiones anteriores hacian mal las cosas, y menos esa version soportaba decimales... el advance no se comportaba realmente bien, que avance en angulos pequeños no significaba que lo estaba haciendo bien... de hecho lo hacia mal, ahora que ese comportamiento incorrecto te daba un efecto atractivo es otra cosa... pero era incorrecto...
el usar resolution, no es para nada engorroso, al contrario, es la idea de solucion simple... y existe desde tiempo de div... y advance es una de las razones de porque existe resolution, por eso me extraña que te funcione... si miras los ejemplos del help de div lo veras.
por otra parte, el compilador no da error al asignar decimales a x, el error esta en que el separador de decimales es el punto y no la coma.
gracias por reportar/preguntar estas cosas, ayudan a que muchos aprendan cosas nuevas que de otra forma no tenemos tiempo de explicar espontaneamente...
saludos...
Me imagino que del advance() o del resolution ya se hablo en más ocasiones, pero el problema el lo que dices, uno se pierde o no puede ver todo lo que se dice en todos los foros.
Que funcionara mal en Fenix se entiende, pero es que en Div funcionaba igual, entonces Div como producto comercial tambien funcionaba mal :)
Ya sabemos que Fenix tuvo lo suyo de ingenieria inversa para ser compatible con Div, pero con tantas funciones que tienen los mismos problemas/bugs que Div, tambien pienso que 'algo' del código de Div sirvio para crear Fenix :)
Y sobre lo de reportar cosas, y diferencias, para eso he abierto este hilo, en el cual pretendo poco a poco poner todas las diferencias que ya he vivido en los ports de Fenix a Bennu, que ayudaran a mas de uno que haga sus ports a Bennu, de eso estoy seguro :)
te entiendo, uno no puede ver todo, no te hagas problemas...
asi es, como ya te dije, agradezco que hagas estas preguntas... nos da pie a dar informacion util para muchos...
gracias
Free, veo que se han mezclado los dos "topics" y no tiene sentido leer uno sin el otro, están relativamente encadenados.
Yo por mi parte intenté separarlos en dos temas independiente, el que te pasaba a tí de la resolución, este. Y el que me pasó a mí de solapamiento de procesos, el otro. Ya me parece casi imposible separarlos :(.
Yo suguiero para futuros posts intentar no mezclaros ya que , por ejemplo , en este caso se han resuelto las cosas dos veces y aún así quedan lagunas :D. Si ves, para este he usado tu ejemplo de disparo al completo, y para el otro he reducido al mínimo el ejemplo para mostrar el problema que tenía de solapamiento.
La verdad el tema del solapamiento que decias no entendi muy bien.
:D, nah, simplemente era que se veían en pantalla menos de 10 disparos cuando yo lanzaba justo 10.
Era debido a que algunos de ellos estaban detrás de otros lo que hacía pensar que no estaban cuando en realidad sí que estaban.
Al poner un valor de alpha = 100 se ve más claro ya que los que están sin solapar se ven más claruchos y los que están solapados se ven más oscuros porque mezclan sus colores, no lo mezcan en sí, pero como uno deja ver lo que hay por debajo y el otro está por debajo pues da esa sensación.
bueno, a decir verdad si se mezclan... cosas internas del blitter... :D
Nueva diferencia en migrácion, en este caso no se si en Fenix hay diferencia en relación a Bennu (me imagino que funcione como en DIV), la diferencia es entre DIV y Bennu:
En DIV si definimos un texto como varible local o global seria por ejemplo:
GLOBAL
mi_texto;
BEGIN
mi_texto = "Hola Mundo!";
write(0, 160, 120, 4, mi_texto);
FRAME(400);
--> Imprime "Hola Mundo!" en pantalla.
En Bennu no funciona, te imprime "0";
Hay que declarar mi_texto como string para que funcione:
GLOBAL
string mi_texto;
BEGIN
mi_texto = "Hola Mundo!";
write(0, 160, 120, 4, mi_texto);
FRAME(400);
Saludos.
es correcto, asi es... los tipos se definen en el momento de declaracion, no en runtime... en fenix es igual a bennu...
Nuevos problemas:
En este caso es diferencia entre DIV y Bennu (me imagino que en Fenix sea como en Bennu):
En DIV1 funciona perfectamente.
Tengo definida la siguiente estructura global:
STRUCT sl[2000]
x, y, graf, tipo;
END
2 - En una funcion tengo los siguientes case:
...
CASE 1:
load("nivel1.lvl", OFFSET sl);
END
CASE 2:
load("nivel2.lvl", &sl);
END
...
Problemas:
Tanto poniendo OFFSET como & dice que la variable sl es requerida.
Como tengo que escribir el load para los 2 casos ?
Nota: poniendo load("nivel1.lvl", sl) funciona, pero tengo un problema con la información que saco de este fichero, ya que parece
que no la saca toda (como si no pillara todo el tamaño de este).
creo que esto ya te lo dije, no tenes que usar ni offset ni &... directamente la variable...
cuando hiciste el save, tenes que haberlo hecho tambien sin el offset...
Deberías poner el texto completo del error, porque el omitir algunas palabras cambia todo el contexto del error.
En teoría, si pones load("nivel1.lvl", sl) debería cargarte las 2000 estructuras, no se qué quieres decir con que no saca todos los datos ¿qué datos no te saca? Tambien puede ser porque no has especificado el tipo de los datos dentro de la struct, últimamente tanto Fenix como Bennu son bastante quisquillosos con los tipos (algo que se agradece para pillar buenas costumbres... pero que tendrá a los novatos nerviosos).
Si ya hablamos del tema en su momento.
Este es otro caso que tenia pendiente, aqui no se hace ningun save sólo es para leer, he estado debugeando y al final llegue al problema, y este viene de aqui, porque yo
lo tenia con:
load("nivel1.lvl", sl);
pero como ya dije no me esta extrayendo correctamente la información de este fichero.
Este fichero en realidad tiene la información del mapa (me imagino que sea los (x,y) que cada objeto tiene), o sea lo le, y hace un map_block_copy de los objetos y pinta el respectivo mapa del nivel (que se carga como .map vacio pero que se llena en ejecución. En realidad son 3 mapas distintos por nivel).
No se como coño o con que herramientas hizo los mapas para guardar su información en estos ficheros, ya que DIV1 no permite crear estes ficheros. He contactado el autor del original, pero parece que no visita mucho su email :)
Os pongo las funciones que pintan el mapa, o sea, el sistema de tiles que utiliza, el original de DIV comentado y el que adapte (le puse 0 en el ultimo parametro de entrada que es nuevo de Bennu y tampoco se lo que significa):
PROCESS BuildMap()
BEGIN
FOR (typ = 0; typ <= 2000; typ++)
IF (sl[typ].graf <> 0)
PutTile(sl[typ].x, sl[typ].y, sl[typ].graf, sl[typ].tipo);
END
END
END
PROCESS PutTile(x, y, graf, tip)
BEGIN
/*
IF (tip == 0)
Map_Block_Copy(TilesFile, ScrollMap, x - graphic_info(TilesFile, graf, g_x_center), y - graphic_info(TilesFile, graf, g_y_center), graf, 0, 0, graphic_info(TilesFile, graf, g_wide), graphic_info(TilesFile, graf, g_height));
END
IF (tip == 1)
Map_Block_Copy(TilesFile, FrontMap, x - graphic_info(TilesFile, graf, g_x_center), y - graphic_info(TilesFile, graf, g_y_center), graf, 0, 0, graphic_info(TilesFile, graf, g_wide), graphic_info(TilesFile, graf, g_height));
END
IF (tip == 2)
Map_Block_Copy(TilesFile, ColMap, x - graphic_info(TilesFile, graf, g_x_center), y - graphic_info(TilesFile, graf, g_y_center), graf, 0, 0, graphic_info(TilesFile, graf, g_wide), graphic_info(TilesFile, graf, g_height));
END
*/
IF (tip == 0) // ScrollMap: Objetos del escenário
Map_Block_Copy(TilesFile, ScrollMap, x - graphic_info(TilesFile, graf, g_x_center), y - graphic_info(TilesFile, graf, g_y_center),
graf, 0, 0, graphic_info(TilesFile, graf, g_wide), graphic_info(TilesFile, graf, g_height), 0); // Bennu
END
IF (tip == 1) // FrontMap: Suelo del escenário
Map_Block_Copy(TilesFile, FrontMap, x - graphic_info(TilesFile, graf, g_x_center), y - graphic_info(TilesFile, graf, g_y_center),
graf, 0, 0, graphic_info(TilesFile, graf, g_wide), graphic_info(TilesFile, graf, g_height), 0); // Bennu
END
IF (tip == 2) // ColMap: Paredes del escenário
Map_Block_Copy(TilesFile, ColMap, x - graphic_info(TilesFile, graf, g_x_center), y - graphic_info(TilesFile, graf, g_y_center),
graf, 0, 0, graphic_info(TilesFile, graf, g_wide), graphic_info(TilesFile, graf, g_height), 0); // Bennu
END
END
antes de probar directamente con este archivo, no te parece que seria mejor hacer una prueba aislada? un save y load de un array de una estructura de este tipo...
El Load se hace porque sino no me salen los gráficos.
Os pongo unas pantallas (hasta hoy no habia puesto fotos de betas para que no entraran ganas, pero poco importa):
(http://forum.bennugd.org/index.php?action=dlattach;topic=803.0;attach=619)
(http://forum.bennugd.org/index.php?action=dlattach;topic=803.0;attach=621)
Como puedes ver, hay tiles de los cuales su información de posición (x,y) no se ha leido, ya que no salen y son datos del principio del fichero ya que falla al principo del pintado ...
De todos modos ya me pondré debuggeando para ver que valores obtiene del fichero.
nunca supongas, es mejor siempre hacer una prueba aislada, para ver que diferencias hay que considerar o simplemente para ver si existe algun bug... pero probar algo dentro de un contexto no te ayuda mucho a determinar donde esta el problema... luego si todos los elementos separados funcionan bien, asi si analizas el contexto...
He estando haciendo pruebas, no llego a ningun sitio ;(
He imprimido los siguientes resultados:
sl = 2712
sl[0] = 2712
sl[1] = 664
sl[2] = 18
sl[3] = 18
sl[4] = 18
sl[5] = 17
sl[6] = 82
sl[7] = 82
sl[8] = 82
sl[9] = 82
sl[10] = 146
sl[11] = 146
&sl[11].x = 146
sl[12] = 146
sl[13] = 146
sl[14] = 210
sl[15] = 210
sl[16] = 210
sl[17] = 210
sl[18] = 274
sl[19] = 274
sl[20] = 274
sl[500] = 2878
sl[501] = 2878
sl[502] = 2878
sl[503] = 2878
sl[800] = 2324
sl[900] = 2804
sl[901] = 2052
sl[902] = 3002
sl[903] = 2804
sl[1000] = 0
sl[1500] = 0
sl[2000] = 0
sl[2210] = 0
sl[2711] = 0
sl[2712] = 0
Traigo más datos:
&sl[0].x = 0108071C
&sl[0].y = 140
&sl[0].graf = 6
&sl[0].tipo = 0
&sl[1].x = 669
&sl[1].y = 376
&sl[1].graf = 42
&sl[1].tipo = 0
&sl[2].x = 18
&sl[2].y = 116
&sl[2].graf = 52
&sl[2].tipo = 0
&sl[3].x = 18
&sl[3].y = 72
&sl[3].graf = 52
&sl[3].tipo = 0
&sl[4].x = 10
&sl[4].y = 28
&sl[4].graf = 52
Aqui se puede observar un valor muy raro:
&sl[0].x = 0108071C
o sea, el valor de X no puede tener ese valor, me imagino que es lo que provoca que ese (x,y) no se pinte...
A ver que os parece.
Una pregunta ¿cómo has obtenido esos datos?
con el write en pantalla ::)
Pues quizás deberías haber escrito sl[0].x en lugar de &sl[0].x, porque así parece que te está pasando la dirección de memoria en lugar del contenido ¿no?
No se, tengo sueño, cerebro apagado.
sl[0].x hace BOOOOOOOOOOOMMMMMMMMMM CRASSSSSSSSSSSSHHHHH BAAAAAAAAAAAAANNNNNNNNNGGGGGGGG
Petete Bennu...
Y por cierto mira los otros valores, crees que son direcciones de memória ??? a mi no....
Despues de ver casos como el sizeof de DIV ya no entiendo nada....
Más pruebas, ya se lo que hace crash:
Con poner sólo Write(0, 10, 10, 0, sl[0].x); frame;
obtengo sl[0].x = 2712
poniendo sólo Write_INT(0, 10, 20, 0, sl[0].y); frame;
obtengo el crash!!!!!!!! de Bennu
o sea, tenemos el resumen:
sl[0].x = 2712
&sl[0].x = 0108071C
sl[0].y = crash
&sl[0].y = 140
sl[0].graf = crash
&sl[0].graf = 6
sl[0].tipo = crash
&sl[0].tipo = 0
A partir del registro 2, el comportamiento es distinto:
sl[1].x = crash
&sl[1].x = 669
sl[1].y = crash
&sl[1].y = 376
...
Conclusión,
los valores de &sl[0].x y sl[0].x exclusivamente para la primera posición tienen valores supuestamente correctos:
sl[0].x = 2712 // valor de x
&sl[0].x = 0108071C // posición de memória
lo que ya no ocurre para
sl[1].x = Petete al leer valor, y deberia sel la posición de memória, aparte de poder leerse, como ocurre para el primer registro
&sl[1].x = // Valor de x (deberia ser de la posición de memória)
...
Esto huele a bug...
En algo la cagas, puede que estés sobrepasando el número de writes en pantalla o algo así.
La forma correcta de usar write es guardando lo que devuelve en un id y borrándolo después de cada frame.
Para mostrar el valor cambiante de una variable se usa write_var. Prueba este ejemplo donde se ven las diferencias de uso y que va perfectamente si hacer crash como dices tu.
Puedes mover el cuadrado rosa con las flechas.
import "mod_key"
import "mod_video"
import "mod_text"
import "mod_wm"
import "mod_map"
import "mod_draw"
Global
STRUCT sl[2000]
x, y, graf, tipo;
END
id_writes[4];
id_write_estatico;
End
Begin
set_mode (640,480,32);
cuadrado();
sl[0].x=100;
sl[0].y=100;
sl[0].graf=map_new(30,30,32);
map_clear(0,sl[0].graf,RGB(255,0,255));
id_write_estatico= write(0,200,20,0,sl[0].x); // muestra unicamente el valor inicial
write_Var(0,150,20,0,sl[0].x);// muestra en cada frame el valor actual
write_var(0,150,60,0,sl[0].y);
while (!key(_esc) )
id_writes[0]= write(0,20,20,0,sl[0].x); // muestra el valor actual
id_writes[1]= write(0,60,20,0,&sl[0].x);
id_writes[2]= write(0,20,60,0,sl[0].y);
id_writes[3]= write(0,60,60,0,&sl[0].y);
frame;
delete_text(id_writes[0]); // borramos el tecto de este identificador
delete_text(id_writes[1]);
delete_text(id_writes[2]);
delete_text(id_writes[3]);
end
delete_text(id_write_estatico);
unload_map(0,sl[0].graf);
End
Process cuadrado()
Begin
control_cuadrado();
while (!key(_esc) )
x=sl[0].x;
y=sl[0].y;
graph=sl[0].graf;
frame;
end;
End
Process control_cuadrado()
Begin
while (!key(_esc) )
if(key(_up))
sl[0].y--;
end
if(key(_down))
sl[0].y++;
end
if(key(_right))
sl[0].x++;
end
if(key(_left))
sl[0].x--;
end
frame;
end;
End
Gracias.
He adaptado tus writes a mi sl[]:
id_write_estatico= write(0,10,20,0,sl[0].x); // muestra unicamente el valor inicial
write_Var(0,10,30,0,sl[0].x);// muestra en cada frame el valor actual
write_var(0,10,40,0,sl[0].y);
while (!key(_esc) )
id_writes[0]= write(0,10,50,0,sl[0].x); // muestra el valor actual
id_writes[1]= write(0,10,60,0,&sl[0].x);
id_writes[2]= write(0,10,70,0,sl[0].y);
id_writes[3]= write(0,10,80,0,&sl[0].y);
frame;
delete_text(id_writes[0]); // borramos el tecto de este identificador
delete_text(id_writes[1]);
delete_text(id_writes[2]);
delete_text(id_writes[3]);
end
Output (en la misma orden de arriba):
sl[0].x = 2712
sl[0].x = 2712
sl[0].y = 140
sl[0].x = 2712
&sl[0].x = 0112070C
sl[0].y = 140
&sl[0].y = 01120720
Como se puede ver ya se recupera correctamente tantos los valores de x,y como su posición en memória.
O sea, como se puede ver a lo largo de varios valores que ya imprimi antes, el valor de x es creciente a medida que recorremos sl[], ya que va pintando el mapa y lógicamente lo hace desde el principio hasta el final (de izquierda a derecha).
Tomando esto como cierto, pues sl[0].x = 2712 es un x muy elevado, tendre que imprimir unos 20 primeros a ver realmente cual su orden (a ver si hay algunos iniciales que tengan la x muy grande, ya que al principio hay varios tiles que no se pintan por lo menos al principio del mapa).
Si esto es cierto, algo mal se le de este fichero externo, porque en Div se pinta el mapa bien, otra vez deduzco que por ejemplo estes primeros valores del x sean distintos ejecutado en DIV.
He intentado compilar en DIV2, pero no consigo, ya que el DosBox se queda sin memória, encima que es código de DIV1 y no funciona totalmente en DIV2, sin hacer algunos ajustes...
Bueno, he perdido algun tiempo a registrar varios valores de x, aqui el resultado:
sl[0].x = 2712
sl[1].x = 669
sl[2].x = 18
sl[3].x = 18
sl[4].x = 18
sl[5].x = 17
sl[6].x = 82
sl[7].x = 82
sl[8].x = 82
sl[9].x = 82
sl[10].x = 146
sl[11].x = 146
sl[12].x = 146
sl[13].x = 146
sl[14].x = 210
sl[15].x = 210
sl[16].x = 210
sl[17].x = 210
sl[18].x = 274
sl[19].x = 274
sl[20].x = 274
sl[21].x = 274
sl[22].x = 1341
sl[23].x = 1162
sl[24].x = 625
sl[25].x = 676
sl[26].x = 727
sl[27].x = 778
sl[28].x = 643
sl[29].x = 694
sl[30].x = 670
sl[31].x = 979
sl[32].x = 937
sl[33].x = 895
sl[34].x = 941
sl[35].x = 1577
sl[36].x = 1577
sl[37].x = 1577
sl[38].x = 1577
sl[39].x = 1641
sl[100].x = 3798
sl[200].x = 4913
sl[300].x = 279
sl[400].x = 1589
sl[800].x = 2324
Como se puede ver, hay valores de x que no cuadran en el orden creciente de x, posiblemente sea donde se notan errores gráficos despues al ver el mapa pintado....
Voy a intentar hacer una pequeña demo en DIV que sólo lea el fichero e imprima los valores leidos....
Os pongo tambien el fichero por si quereis hacer pruebas.
Gracias.
Estoy desesperao, no se como obtenerlos en DIV1 (incluso Gemix que tiene un output algo parecido a DIV), que verguenza....
Os pongo el .prg de prueba, uno para Bennu que funciona bien (con los valores ya comentados), y otro para DIV, el cual no me pilla bien los valores, sólo cosas raras, este ultimo de DIV1 si lo arreglais para que funcione en DIV os quedo agradecidos.
Pongo tambien pantallas para los que no tengan DIV1 con el resultado que sale, una con el ejemplo de Bennu directamente probado en DIV1/Gemix y otro con el cambio de sl a &sl en sus llamadas (probe abrir con OFFSET sl, en DIV1 pero es igual).
bien... efectivamente hay un bug... en algo estas fallando...
repito... ejemplos aislados... y simples...
**** save ****
import "mod_say";
import "mod_file";
global
STRUCT sl[2000]
x, y, graf, tipo;
END
private
i;
begin
for(i=0;i<=2000;i++)
sl[i].x = i;
sl[i].y = 10000+i;
sl[i].graf = 100000+i;
sl[i].tipo = -i;
end
for(i=0;i<=2000;i++)
say ( "i="+i+" x="+sl[i].x+" y="+sl[i].y+" graf="+sl[i].graf+" tipo="+sl[i].tipo);
end
save( "mylevel.dat", sl );
end
**** load ****
import "mod_say";
import "mod_file";
global
STRUCT sl[2000]
x, y, graf, tipo;
END
private
i;
begin
load( "mylevel.dat", sl );
for(i=0;i<=2000;i++)
say ( "i="+i+" x="+sl[i].x+" y="+sl[i].y+" graf="+sl[i].graf+" tipo="+sl[i].tipo);
end
end
**** load + write_int + write ****
import "mod_say";
import "mod_file";
import "mod_video";
import "mod_text";
import "mod_key";
global
STRUCT sl[2000]
x, y, graf, tipo;
END
private
i;
begin
load( "mylevel.dat", sl );
for(i=0;i<=2000;i++)
say ( "i="+i+" x="+sl[i].x+" y="+sl[i].y+" graf="+sl[i].graf+" tipo="+sl[i].tipo);
end
set_mode(1024,768);
for(i=0;i<=70;i++)
write_int( 0, 0, 10+i*10, 0, &sl[i].x );
end
while(!key(_ESC)) frame; end
while(key(_ESC)) frame; end
delete_text(all_text);
for(i=0;i<=70;i++)
write( 0, 0, 10+i*10, 0, sl[i].y );
end
while(!key(_ESC)) frame; end
end
bien, lamento informarte que esos valores son los que tiene tu lvl... es tan simple como tomar un editor hexadecimal y hacer los calculos pertinentes...
nunca hay que asumir nada... no se porque asumiste que las x tienen que ser crecientes... no asumas, chequea los datos... has pruebas simples...
Muchas grácias Splinter, voy a probar tu ejemplo a ver que dice el say.
Igual con el save ya podre salvar uno con valores corregidos aunque me parece que va ser un currazo, ya que no puedo estar poniendo objectos (x,y) a ciegas en un mapa...
Si diera con el editor de tiles que el utilizo, es que no me responde al email...
A ver si conoceis estos editores y los más utilizados para juegos C.
Vamos a ver, entonces el .lvl no está hecho con div sino con un editor de niveles externo.
Entonces puede ser problema de alineación. Lo que no comprendo es que en div vaya y en bennu no.
Quizas puedas hacer un programa en div que lea el .lvl, que se supone que lo hace bien, y luego lo guarde otra vez a ver si esta vez lo guarda bien.
Si no va esto, y suponiendo siempre que div abre bien el .lvl, puedes hacer otra cosa, un programa en div que abra el .lvl y luego posteriormente recorres la estructura y guardas en texto plano (.txt) los datos uno a uno por línea sabiendo que cada tres líneas tienes un dato. algo así como que si tienes esto:
sl[0].x=1;
sl[0].y=17;
sl[0].graph=6;
sl[1].x=44;
sl[2].y=15;
sl[3].graph=7;
Tu guardas string a string
1
17
6
44
15
7
..
..
Luego ya este formato puedes leerlo exactamente igual en bennu usando un split.
dcelso... no hay problema de alineacion... abre el archivo y mira... ya le dimos demasiados posts a este tema como para seguir suponiendo...
Amigos, el fichero esta perfecto y lo le bien.
El error no es del fichero:
Ya tengo resultados, he aqui una analisis paso a paso que he echo:
Filtrando por los de tipo = 1 (suelo del mapa)
y por grap=16
hay 37 resultados:
rectangulo gris del suelo --> Gráfico (71 largura x 35 altura)
y por graf=62 hay unos 70
cuadrado gris del suelo --> Gráfico (100 largura x 100 altura)
Por suerte en la foto tengo una referencia muy buena, que son 3
paredes transparentes (ventanas de arambres que tapan el prota),
en bennu la primera de arriba no sale, sólo tengo que filtrar por x < 500
por ejemplo.
mirando cuantos encuentra para:
tipo=1, graf=8
Perfecto ya he descubierto que el bug no esta en este fichero, porque tengo
el siguiente resultado:
i=674, x=46, y=88, graf=8, tipo=1 // Ventana de abajo (forma parte de la primera, skull esta dentro de ella :))
i=675, x=46, y=16, graf=8, tipo=1 // Ventana de arriba (forma parte de la primera)
i=676, x=146, y=88, graf=8, tipo=1 // tercera ventana
i=677, x=246, y=88, graf=8, tipo=1 // cuarta ventana
Todo cuadra a la perfección, son las 4 que se pintan en el original DIV
y en Bennu las 2 situadas en la posición:
i=674, x=46, y=88, graf=8, tipo=1 // Ventana de abajo (forma parte de la primera, skull esta dentro de ella :))
i=675, x=46, y=16, graf=8, tipo=1 // Ventana de arriba (forma parte de la primera)
no salen como se puede recordar en la foto adjunta.
(http://forum.bennugd.org/index.php?action=dlattach;topic=803.0;attach=619)
Otra cosa que no habia comentado es que la parte de arriba del scroll
tambien esta deslocado algunos puntos hacia abajo, igual el problema
es de definición de scroll.
Por lo menos se cierra el tema del fichero externo, es de otra cosa.
Como mola debugear ;)
Hay avances, poniendo:
//PutTile(46, 16, 8, 1); // Son eliminados
//PutTile(46, 88, 8, 1);
PutTile(52, 46, 8, 1);
PutTile(52, 88, 8, 1);
He conseguido pintar los tiles en pantalla, lo que esta ocurriendo es que algo me esta borrando los tiles que con posición x < 52 y < 46.
(http://forum.bennugd.org/index.php?action=dlattach;topic=803.0;attach=625)
Ya queda menos....
Quote from: FreeYourMind on October 25, 2009, 03:51:36 PM
Hay avances, poniendo:
//PutTile(46, 16, 8, 1); // Son eliminados
//PutTile(46, 88, 8, 1);
PutTile(52, 46, 8, 1);
PutTile(52, 88, 8, 1);
He conseguido pintar los tiles en pantalla, lo que esta ocurriendo es que algo me esta borrando los tiles que con posición x < 52 y < 46.
O sea, parece que si tocan las margenes x=0 y y=0 estos no se pintan...
(http://forum.bennugd.org/index.php?action=dlattach;topic=803.0;attach=625)
Ya queda menos....
Entonces no entiendo nada, no debo ver la diferencia entre lo que hace div y lo que hace bennu, ¿puedes resartármela con una imagen contra otra?
En cuanto al problema de alineación no lo dije así a la virulé, eso me pasó a mi al guardar una estructura con c y luego intentar abrirla con bennu, los datos hexadecimales que guarda c no siempre son los mismos que guarda bennu, en c una estructura debe ser múltiplo de 16 bits si no lo es redondea hasta el número próximo múltiplo por lo que se produce una desalineación a nivel de bytes.
Por esto mismo pregunte si se había guardado el fichero lvl con un programa externo a div/bennu.
Y digo yo ¿y si vas leyendo los valores uno a uno en lugar de lanzarte a saco y cargar toda la info de golpe? ya que conoces el formato, no será complicado montarte un programita que lea de uno en uno y los escriba en pantalla. Puede que así te des cuenta de donde te falla.
Es lo que me pasó a mi hace tiempo con el motor de tiles v2 y el port UFenix: el fichero que usaba era una versión antigua.
Diferencia tiene que haber, lo que pasa es que no es al leer el fichero (que por cierto ya tengo el ejemplo funcional en DIV/Gemix y saca los mismos valores).
La seguire buscando... Pero es un aburrimiento total, me tiene todo harto ya.
Estaba mirando los out_region, pero aún no llegue a nada.
Lo único que tengo comprobado es que si pongo un tile que toque una margen (x <= 0 o y <=0) este no se pinta...
En la ultima imagen la puse lo mas cercano posible sin tocar estos valores, por eso se pintan, pero si te fijas en las paredes que faltaban, estas estan deslocadas hacia la derecha, incluso parte del arambre se queda por encima de la pared de arambres siguiente, para poder pintarla sino desaparece.
El suelo por ejemplo desaparece en la lateral izquierda porque parte de este tile tiene una región o margen de su gráfico con x <= 0, y desaparece todo el tile por eso.
Quote from: Drumpi on October 25, 2009, 05:27:01 PM
Y digo yo ¿y si vas leyendo los valores uno a uno en lugar de lanzarte a saco y cargar toda la info de golpe? ya que conoces el formato, no será complicado montarte un programita que lea de uno en uno y los escriba en pantalla. Puede que así te des cuenta de donde te falla.
Es lo que me pasó a mi hace tiempo con el motor de tiles v2 y el port UFenix: el fichero que usaba era una versión antigua.
Estas atrasado :) Eso ya esta, cortesia de Splinter, y el problema ya no tiene que ver con este fichero (por suerte, prefiero que sea otro, ya que volver a generar estos ficheros era casi imposible porque no se que herramienta visual utilizó para colocar las cosas en el sitio exacto).
no logro entender cual es el problema? no tendras problemas de Z?
Problema de Z !!!!
No tiene nada que ver.
La cosa es muy sencilla, ya he repasao todo el código sólo se me ocurre que el problema sea el Map_Block_Copy...
Mi pregunta es la siguiente, si se copia un mapa a otro, este tiene que colarse totalmente sobre la area del mapa destino, o puede colocarse por ejemplo más a la izquierda y que en realidad sólo una parte coincida con el gráfico destino ??
No se si me explico, se resume a que si pongo un tile que ultrapasa el scroll visible (camara), este no se pinta, o sea, si parte del gráfico coincide con x<0 o y<0, este sencillamente, con el map_block_copy, no se pinta en el mapa destino...
Ejemplo, si pongo:
PutTile(46, 16, 8, 1);
PutTile(46, 88, 8, 1);
estes no se pintan porque ultrapasan el margen x<0 o y<0.
Si pongo esto:
PutTile(52, 46, 8, 1);
PutTile(52, 88, 8, 1);
ya se pintan, porque la region de los tiles ya no chocan con x<0 o y<0.
La condición que ocurre en la funcion PutTile, es esta:
IF (tip == 1) // FrontMap: Suelo, objetos que tapan
Map_Block_Copy(TilesFile, FrontMap, x - graphic_info(TilesFile, graf, g_x_center), y - graphic_info(TilesFile, graf, g_y_center),
graf, 0, 0, graphic_info(TilesFile, graf, g_wide), graphic_info(TilesFile, graf, g_height), 0); // Bennu
END
Os pongo el mapa vacio que cargo que será el destino, a ver si mirando o cambiando su dimensión esto se arregla...
Los 3 mapas se cargan como ya dijé en otra ocasion, á partir del mismo fichero origen:
ScrollMap = load_map("Map/Nivel.map");
FrontMap = load_map("Map/Nivel.map"); // Suelo o objetos que quedan enfrente del prota
ColMap = load_map("Map/Nivel.map"); // Paredes
la llamada se hace al principio del nivel:
BuildMap();
Start_Scroll(0, TilesFile, ScrollMap, info[2], 0, 0); // info[2]: Mapa de fondo
Front(); // Pone en el scroll el FrontMap
....
Os pongo la funcion Front() que aún no habia enseñado, que es la que define el Z que comentas (que no es un problema):
PROCESS Front() // Objectos del FrontMap
BEGIN
ctype = c_scroll;
graph = FrontMap;
x = 2500; // Cuanto mayor x, más deslocado hacia la derecha se quedan estos objetos (mapa)
y = 250;
z = -100;
LOOP
FRAME;
END
END
es que no entiendo con ver las capturas que esta mal y que esta bien... estaria bueno que señales con un circulo o algo lo que vos consideras es un error...
por otro lado, si haces un map_block_copy se dibujan las areas que tienen coincidencia, que se unen, o como quieras verlo... resumiendo, puede dibujarse parcialmente... asi que entiendo que vos decis que si no entra completo, no se dibuja... pues bueno, eso no es asi, si no entra completo, se dibuja lo que entra.
Exacto, a mi me pasa lo mismo, no veo en las imágenes lo que falla.
Ostras, ya lo he visto.
(http://forum.bennugd.org/index.php?action=dlattach;topic=803.0;attach=628)
A ver, yo necesitaría los gráficos para poder hacer una reconstrucción de los echos para ver donde falla la lógica en bennu.
Pero a priori dices que puede que el problema sea intentar hacer un map_block copy en una posición x, e y, menor a 0.
En la imagen ejemplo, si el negro es el destino, el rosa no sería válido y no se dibujaría y el verde sí sería válido y solo se dibujaría la parte que se puede.
Pues no se, tendré que hacer un mini ejemplo para probar esto, pero según splinter parece que si que se podría poner el rosa.
(http://forum.bennugd.org/index.php?action=dlattach;topic=803.0;attach=630)
Exacto!!!!! Pero en Div por lo que veo el rosa es válido porque los pinta :)
Cuando pueda hago un mini ejemplo. Karma Up+++
buenoo, ya he hecho un ejemplo y he visto que efectivamente bennu el rosa no lo pinta.
He realizado una solución un poco para salir del paso, un map_block_copy2, que para cuando x o y es menor a cero crea un mapa mas grande, dibuja en él y luego lo recorta.
Es bastante lenta ya que necesita de bastantes pasos intermedios. Quiza se pueda optimizar usando map_put en vez de map_block_copy.
Con las teclas w,s,a,d (arriba,abajo,izquierda,derecha respectivamente) se puede mover el bloque rosa para ver el efecto.
Con las teclas up,down,left,right se pueden mover los bloques finales.
Program map_block_copy_example;
import "mod_map"
import "mod_key"
import "mod_video"
import "mod_text"
import "mod_say"
Global
Int id_text[4];
Begin
set_mode(640,480,32);
my_map(200,200 );
my_map2(335,200);
id_text[0]=write(0,100,20,0,"x_pink:");
id_text[1]=write(0,100,40,0,"y_pink:");
id_text[2]=write(0,150,130,0,"map_block_copy");
id_text[3]=write(0,280,130,0,"map_block_copy2");
While(!Key(_esc))
Frame;
End
delete_text(id_text[0]);
delete_text(id_text[1]);
delete_text(id_text[2]);
delete_text(id_text[3]);
End
Process my_map( x,y )
Private
Int square[3];
Int x_pink;
Int y_pink;
Begin
square[0] = new_map(20,20,32);
map_clear(0,square[0],RGB(255,0,255));
square[1] = new_map(20,20,32);
map_clear(0,square[1],RGB(0,255,0));
square[2] = new_map(100,100,32);
map_clear(0,square[2],RGB(255,255,255));
graph = new_map(100,100,32);
map_block_copy (0,graph,0,0,square[2],0,0,100,100,0);
map_block_copy (0,graph,90,10,square[1],0,0,20,20,0);
map_block_copy (0,graph,x_pink,y_pink,square[0],0,0,20,20,0);
write_var(0,160,20,0,x_pink);
write_var(0,160,40,0,y_pink);
While(!Key(_esc))
if (key(_up)) y--;end
if (key(_down)) y++;end
if (key(_left)) x--;end
if (key(_right)) x++;end
if (key(_w) OR key(_a) OR key(_s) OR key(_d))
if (key(_w)) y_pink--; End
if (key(_s)) y_pink++; End
if (key(_a)) x_pink--; End
if (key(_d)) x_pink++; End
map_block_copy (0,graph,0,0,square[2],0,0,100,100,0);
map_block_copy (0,graph,90,10,square[1],0,0,20,20,0);
map_block_copy (0,graph,x_pink,y_pink,square[0],0,0,20,20,0);
End
Frame;
End
unload_map(0,square[0]);
unload_map(0,square[1]);
unload_map(0,square[2]);
unload_map(0,graph);
End
Process my_map2( x,y )
Private
Int square[3];
Int x_pink;
Int y_pink;
Begin
square[0] = new_map(20,20,32);
map_clear(0,square[0],RGB(255,0,255));
square[1] = new_map(20,20,32);
map_clear(0,square[1],RGB(0,255,0));
square[2] = new_map(100,100,32);
map_clear(0,square[2],RGB(255,255,255));
graph = new_map(100,100,32);
map_block_copy2 (0,graph,0,0,square[2],0,0,100,100,0);
map_block_copy2 (0,graph,90,10,square[1],0,0,20,20,0);
map_block_copy2 (0,graph,x_pink,y_pink,square[0],0,0,20,20,0);
write_var(0,160,20,0,x_pink);
write_var(0,160,40,0,y_pink);
While(!Key(_esc))
if (key(_up)) y--;end
if (key(_down)) y++;end
if (key(_left)) x--;end
if (key(_right)) x++;end
if (key(_w) OR key(_a) OR key(_s) OR key(_d))
if (key(_w)) y_pink--; End
if (key(_s)) y_pink++; End
if (key(_a)) x_pink--; End
if (key(_d)) x_pink++; End
map_block_copy2 (0,graph,0,0,square[2],0,0,100,100,0);
map_block_copy2 (0,graph,90,10,square[1],0,0,20,20,0);
map_block_copy2 (0,graph,x_pink,y_pink,square[0],0,0,20,20,0);
End
Frame;
End
unload_map(0,square[0]);
unload_map(0,square[1]);
unload_map(0,square[2]);
unload_map(0,graph);
End
function map_block_copy2(INT fileID , INT destinationGraphID , INT destinationX , INT destinationY , INT originGraphID , INT x , INT y , INT width , INT height, INT blitflags)
Private
dest_width;
dest_height;
dest_graph;
orig_width;
orig_height;
orig_graph;
x_correction;
y_correction;
Begin
if ( destinationX>=0 AND destinationY>=0 )
return map_block_copy( fileID , destinationGraphID , destinationX , destinationY , originGraphID , x , y , width , height, blitflags);
End
dest_width = graphic_info(fileID,destinationGraphID,G_WIDTH);
dest_height = graphic_info(fileID,destinationGraphID,G_HEIGHT);
dest_graph = new_map(dest_width,dest_height,32);
map_xputnp(0,dest_graph,fileId,destinationGraphID,dest_width/2,dest_height/2,0,100,100,blitflags);
orig_width = graphic_info(fileID,originGraphID,G_WIDTH);
orig_height = graphic_info(fileID,originGraphID,G_HEIGHT);
orig_graph = new_map(orig_width,orig_height,32);
map_xputnp(0,orig_graph,fileId,originGraphID,orig_width/2,orig_height/2,0,100,100,blitflags);
if (destinationX < 0)
dest_width -= destinationX;
x_correction = -destinationX;
End
if (destinationY < 0)
dest_height -= destinationY;
y_correction = -destinationY;
End
graph = new_map(dest_width,dest_height,32);
map_block_copy(0,graph,x_correction,y_correction,dest_graph,0,0,dest_width,dest_height,blitflags);
map_block_copy(0,graph,x_correction+destinationX,y_correction+destinationY,orig_graph,0,0,orig_width,orig_height,blitflags);
map_block_copy(0,dest_graph,0,0,graph,x_correction,y_correction,dest_width,dest_height,blitflags);
map_xputnp(fileId,destinationGraphID,0,dest_graph,(dest_width-x_correction)/2,(dest_height-y_correction)/2,0,100,100,blitflags);
unload_map(0,dest_graph);
unload_map(0,orig_graph);
unload_map(0,graph);
return;
End
caramba que para diagnosticar son tan buenos como yo hablando de futbol... menos mal que probe el ejemplo... cuando dicen el rosa no pinta, pareciera que hay un problema con el color rosa, cosa que no tiene que ver con el error...
ya esta, el error es que si se quiere poner un grafico en una coordenada negativa dentro del destino, la funcion no dibuja, aun cuando estos se superpongan... ya se donde esta el error...
gracias...
ya tengo la correccion hecha y probada... luego subo el fix... donde estoy ahora no tengo accceso...
saludos y gracias.
La pregunta es, lo vas a poner compatible ???
Me algeraria muchissimo y creo que a más gente que pase por lo mismo.
Seria complicado tener que crear gráficos más peques para tapar estos agujeros, el del principo no es muy dificil, pero a lo gargo del nivel los que coinciden con y<0 son un problema.
Tambien es bueno que pinte fuera, porque por ejemplo en el juego pinta una pared fuera de la area visible para que skull no se caiga por la izquierda, aunque en este caso seria facil resolverlo, hacer que skull no se moviera o saltará para x < 0.
Como sabes las posiciones las tengo en el fichero externo que fue creado con un editor de tiles, con lo que tener que corregir esto creando un visualizador del mapa para encontrar las posiciones que fallan y corregirlas, teniendo en cuanta que tambien son 9 niveles seria un autentico caos....
Encima que va ser mi primer juego multiplataforma con el mismo dcb, y segun la maquina en que se juega va tener caracteristicas distintas :)
Por ahora contemplo Windows, Wiz, y si puedo volver a desenpolvorar alguna distribución de Linux Live CD, tambien Linux.
Para Linux como ejecutais o donde instalais los juegos ?
Es algo parecido a la ruta de los ficheros .gpe de Wiz (ya que usa Linux) ??
Muchas grácias a los 2, realmente os mereceis de nuevo Karma Uppps, me ahorraste el ejemplo DCelso, ya que llego a casa echo polvo del curro, eso se agradece :)
Quote from: splinter_work on October 26, 2009, 06:57:53 PM
ya tengo la correccion hecha y probada... luego subo el fix... donde estoy ahora no tengo accceso...
saludos y gracias.
Grácias, no me habia fijado, me vas ahorrar horas de curro que tendria para ajustar los gráficos :)
no entiendo que me decis... era un bug... ya esta corregido, no pinta mas alla del grafico, no es logico eso, se pinta sobre el grafico lo que aplique...
ahora mismo no puedo compilarlos, y armar los paquetes... lo compile en linux y probe ahi... suguiero si tenes posibilidad de usar linux, que lo uses, bajes los fuentes del svn y los compiles... asi podras seguir trabajando...
Ok, pues yo esto no lo consideraba un bug en sí. Me parecía lógico que con x o y negativo no hiciera nada la función :D.
DCelso, depende de dónde estuviera el centro del mapa. Sería lógico si el centro estuviera en la esquina inferior derecha, pero si está en el centro y se dibuja en (-1,-1) siempre habrá al menos un tile que se pueda pintar en el mapa destino.
Es curioso, nunca detecté fallo en este tipo de cosas, y eso que hice un scroll tileado que dibujaba en gráfico, y los tiles tenían todas las posiciones habidas y por haber (valores negativos incluidos), pero claro, en Fénix yo usaba map_xputnp.
no, con map_*put no hay problemas, solo con map_block_copy...
Muchas grácias por el Update del rc112.
Como se puede observar parece que ya esta perfecta la compatibilidad con DIV, aparte de que pensaba que el scroll tambien tenia un problema de margen, y al final provenia de lo mismo. Así que en principio, ya se pintan todo a la perfección.
(http://forum.bennugd.org/index.php?action=dlattach;topic=803.0;attach=649)
me alegra mucho... gracias por probar y REPORTAR! (NO TODOS LO HACEN!...)
Vengo con otro problema, este me suena más a Bug.
En Div funciona perfectamente (vamos que esto ya no deberia decirlo, ya que estoy poniendo siempre cosas que funcionan en DIV tal como las expongo).
Tengo un gancho que se mueve donde el prota se cuelga, este processo le asigna varios valores al proceso del prota (o sea, le cambia algunas propriedades), lo que ocurre es que, la única variable que no se cambia es el gráfico:
Ejemplo:
tenemos el proceso prota(x, y), dentro de el hay varias condiciones que cambian el gráfico (salto, movimiento, etc), o sea lo normal.
Tengo una asignación global que acede a sus propriedades y que tambien las cambia:
idprota = prota(10, 100);
Ahora dentro del proceso gancho(), cuando el prota colisiona con el, este se queda pegao al gancho y le cambio las propriedades:
idprota.x = x - 4; // Le ajusto la posición al quedarse pegao al gancho
idprota.y = y + 30;
idprota.z = - 102;
idprota.graph = 124; // Aqui le cambio tambien el gráfico, pero no me lo cabia... es este el problema de incompatibilidad
Entiendo que los gráficos asignados dentro de prota(x,y) afecten este que asigno despues, pero no deberia, este última asignación deberia tener prioridad cuando el prota esta pegado al objeto gancho().
Entiendo que haciendo esta comprobación dentro del proprio processo prota(x,y) igual podria poner el gráfico correcto bajo estas condiciones.
A ver vuestra opinión y Splinter a ver si esto es un Bug o no, y porque hay diferencias.
Grácias
Si cambias el grafico tanto en el prota como en el gancho, puede que esté ahí el problema.
Son procesos ejecutandose en paralelo, y dejará el gráfico el proceso que se ejecute más tarde.
Tendrías que hacer algo para evitar esto, algo en el prota que diga si estoy en el gancho no entonces no cambio de grafico.
Si, entiendo que el problema en Bennu surge por eso, pero es una pena porque en relación a la posición esta se controla en el proceso gancho, o sea que si muevo el personaje se cae del gancho, pero que haga esto lo defino en el proceso gancho, no en el proceso prota(x,y), o sea para las propriedades de posicion funciona bien.
Lo lógico era que hiciera lo mismo para el gráfico, ya que al moverlo las condiciones definidas en gancho() se sobreponen a las definidas en prota(x,y).
Ya lo he arreglado, he puesto en la condición de salto del prota (x,y) lo siguiente:
IF (collision (TYPE gancho))
graph = 124; // Gráfico de aggarao al gancho
flags = 0; // Para que al mover el personaje este no mire hacia la izquierda.
ELSE
graph = 4; // Gráfico de salto
END
en la funcion del gancho he quitado los
graph = 124; // Gráfico de aggarao al gancho
flags = 0; // Para que al mover el personaje este no mire hacia la izquierda.
Hasta otra ;)
el problema es que no debes tener seteado "priority" o lo tenes mal seteado...
si bien en DIV el orden de ejecucion de los procesos estaba relacionada con el orden de creacion de los mismos, eso era simplemente una casualidad... en el help del mismo lenguaje dice, que el orden de ejecucion de los procesos con misma prioridad es indeterminado... que se debe usar priority si necesitamos establecer un orden determinado. Este tema ya se hablo y hay varias referencias al respecto. Bennu se comporta como debe comportarse al respecto.
repito algo que dije muchas veces, nunca hay que asumir nada....
En este caso se puede asumir, porque es sencillamente ejecución del mismo código, así que la ejecución es identica siempre en cada caso (aqui no estamos hablando de randoms o variables :))
Nunca utilicé lo de priority en mi vida, voy a probarlo a ver que tal, igual resulta más limpio el código.
Gracias por la aclaración.
no, no, este caso no es distinto... al contrario... no tiene nada que ver eso de ejecucion identica... depende de muchos factores (creacion y muerte de otros procesos, por ejemplo)... y no es predecible...
Me refiero a que los pasos de creación de procesos es siempre el mismo, en este caso sólo entran en juego 2 procesos, y uno se crea antes del otro (el prota antes del gancho). Y lo puedes ejecutar 1000 veces seguidas, en Bennu siempre el proceso prota tendra prioridad sobre el gancho y en Div al reves...
Con esto no te estoy contrariando, sólo informando de lo que ocurre al probar el juego.
no, no siempre sera asi... o mejor dicho, eso no asegura que a lo largo de la vida de los mismos esto se mantenga... pero por otro lado (actualmente) en todo caso seria al revez, si ejecutas primero protagonista y luego gancho, entonces luego de la primera ejecucion gancho se ejecutar antes que protagonista (o incluso en la primera ejecucion, depende de muchos factores)... pero esto no siempre puede ser asi... y el orden puede cambiar en cualquier momento o constantemente... no hay que asumir nunca nada, en ningun caso... asumir es el mas grande error de un programador...
hay que hablar de muchas cosas para explicar los porque de esto, y escapa de la consulta... pero como bien dice el help de DIV, en procesos con igual prioridad el orden de ejecucion de los mismos es indeterminado... hay que usar priority...
Para entendernos: en teoría, dos procesos de identica prioridad deberían ejecutarse a la vez, pero no es posible. Existe otro proceso, creado por el sistema, que decide quien se ejecuta antes. Este proceso tiene un código y siempre actúa igual, obviamente.
Pero si, por ejemplo, un proceso ejecuta "frame(0)", este se volverá a ejecutar al final (no ha llegado al 100% del frame) y puede cambiar el orden.
Ahora no se me ocurren otros factores que afecten, pero decir que "siempre se ejecutará en el mismo orden" es como pensar que los ID de los FPG "valen lo mismo que en el orden en que se cargaron".
...
no me agrada repetir temas... pero vamos de nuevo...
1) bennu/fenix/div/etc... no tienen multithread para la ejecucion de procesos... no ejecutan procesos concurrentemente... la filosofia multiproceso de la vm, no es mas que una secuenciacion en la ejecucion de los mismos...
2) frame(0) y otras yerbas, no tiene nada que ver con el orden de los procesos que estamos hablando... veamos... la creacion/destruccion de procesos representa la manipulacion de varias listas enlazadas y hasheadas por varias caracteristicas... cuando un proceso se borra o se crea uno nuevo, estas listas se ven afectadas en cuanto a orden, por cuestiones de rendimiento y optimizaciones... pero si (como dice drumpi) hay que entender que por estas caracteristicas yh otras no siempre se ejecutan en el mismo orden... lo unico que define la ejecucion de uno antes que otro es la prioridad (variable local priority)
http://wiki.bennugd.org/index.php?title=Priority
¿Y quien ha dicho nada de procesamiento paralelo? ;D
Cómo se nota que la última asignatura que me quedaba de la carrera iba sobre SO y sistemas en tiempo real :D :D :D
Respecto al uso de frame(0), pensaba que al terminar su estado de "ejecutando", al no competar un frame al 100%, este volvía a la lista de procesos "ready", colocándose detrás del último proceso en dicha lista con la misma prioridad, con lo cual, si luego todos esos procesos terminan de ejecutarse, se habrán añadido a la lista de "ejecutados" en distinto orden al original. Si no es así, pido disculpas por mi error (a base de ellos se aprende).
Vale vale chicos. Lo que pasa realmente es que no estoy para mirar el código interno de Bennu para salir de mis dudas. Para eso estais vosotros ;D
Ahora me entero que el fullscreen = true; de Fenix no funciona en Bennu !!!
Please help :o
¿Como que no funciona? ¿Has probado a hacer el set_mode después?
http://wiki.bennugd.org/index.php?title=Fullscreen
Creo que no llegaste a usarlo en fenix :D.
Si, antes y despues y no va. Si lo mire de un juego de fenix ::)
Que raro! ahora ejecute de nuevo y ha funcionado (con el mismo prg).
Bueno, hay alguna forma de obtener la resolucion que tenemos en nuestro desktop ??
Esto seria muy util ya que quisiera ponerlo a fullscreen pero sketch, o sea a pantalla completa sin margenes negras.
pues algo anda mal, yo en casi todos mis ejemplos pongo
If (key(_f))
full_screen=!full_screen;
set_mode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_DEPTH);
end
Y va de perlas.
¿donde lo pruebas?
ok, ya decia yop. ;)
Supongo que esta get_desktop_size(), no se, no está documentada la mod_wm aún en la wiki, meavisó osk, en cuanto saque un hueco inserto la info.
Quote from: Drumpi on November 02, 2009, 06:20:35 PM
¿Y quien ha dicho nada de procesamiento paralelo? ;D
Cómo se nota que la última asignatura que me quedaba de la carrera iba sobre SO y sistemas en tiempo real :D :D :D
Respecto al uso de frame(0), pensaba que al terminar su estado de "ejecutando", al no competar un frame al 100%, este volvía a la lista de procesos "ready", colocándose detrás del último proceso en dicha lista con la misma prioridad, con lo cual, si luego todos esos procesos terminan de ejecutarse, se habrán añadido a la lista de "ejecutados" en distinto orden al original. Si no es así, pido disculpas por mi error (a base de ellos se aprende).
frame(0)... lo manda al final de toda la lista, no importa la prioridad... o sea, lo manda a la cola...
Si existe get_desktop_size() entonces Bennu esta cojonudo, con la opcion de rescalar de bajas resoluciones a mayores resoluciones, implementada recientemente, esa opción va venir de maravilla, ya que permitiria rescalar un juego en fullscreen siempre al tamaño de la resolución de nuestro ordenador.
Lamentablemente hasta que no arregle el portatil no voy poder probarlo.
Bueno despues de 2 semanas parado, estoy intentando seguir con mi proyecto de Bennu (lo que cuesta volver ;)).
Como puedo utilizar el INT GET_DESKTOP_SIZE(POINTER, POINTER) ??
No se que poner como parametros de entrada, antes de probar pensando que no tendria parametros, seria algo así:
scale_resolution = get_desktop_size();
Más cosillas:
1 - Si se ejecuta sobre DOS, como no tenemos Desktop tendriamos problemas ?
2 - Puede que Bennu no admita la resolución obtenida de nuestro Desktop ? en caso afirmativo como contornariamos el error para asignar una resolución admitida ?
Grácias.
http://wiki.bennugd.org/index.php?title=Get_window_size
esa funcion no tiene parametros de entrada, son de salida... por eso son punteros...
&alto, &ancho
y te va a devolver esos valores.
Me saltan dudas y mas dudas:
El ejemplo de la Wikipedia no me sirve o no lo entiendo, en el se define ya la resolución del desktop en variables globales, yo quiero saberlas a traves de la funcion, no soy yo que las tengo que poner!
O sea yo quiero hacer algo por el estilo:
scale_resolution = m1024x768;
set_mode(m320x200);
Esto rescalaria el juego de su resolución original de 320x200 a la resolución 1024x768,
siendo esta ultima obtenida con get_desktop_size.
Otra cosa, mi desktop esta a 1280x800, resolución que Bennu no reconoce, pero he probado con 1024x768 que es inferior
y el juego se queda verticalmente ajustado y en horizontal ultrapasa la pantalla, con esto deduzco que el fullscreen a pantalla entera es una resolucion con 1024xAAA siendo AAA menor que 768.
Los que son valores más pequeños que la resolución de mi desktop!!! Lo ideal era una funcion que me diera la resolución exacta para hacer un 'Sketch' o sea poner el juego a pantalla completa tenga la resolucion que tenga, esta caracteristica es muy comun en emuladores, que te ponen el juego a pantalla entera, como el Mame.
la tenes... busca donde se describe la funcion get_desktop_size dentro del foro... y ahi tenes el juego completo...
No tengo experiencia con resolution, sólo aconsejo:
Recuerda que tu PC no puede soportar en Bennu una resolución que tu tarjeta gráfica no soporte, en cristiano: "Si haces clic derecho y Propiedades en el Escritorio de Windows puedes ver en Configuración las resoluciones soportadas, las hay panorámicas y 4:3, quizás mode_is_ok ( ) pueda ayudarte".
Siento no tener demasiada experiencia con resolution, pero cuando empecé a usarlo me dí cuenta de que mode_is_ok era importante para conocer la resolución a la que se está ejecutando finalmente.
Quote from: SplinterGU on November 12, 2009, 01:35:02 AM
la tenes... busca donde se describe la funcion get_desktop_size dentro del foro... y ahi tenes el juego completo...
Haz caso a Splinter, y Bennu sí que reconoce 1280x800. Con mi portátil (Pantalla panorámica) en Bennu 3D siempre uso esa resolución, pero si is_mode_ok no la da como válida paso a 1024x768 (Pantallas CRT).
Yo dijé que Bennu no la soporta porque no me compila, poniendo tanto:
scale_resolution = m1280x800; (desconocido)
como
scale_resolution = 1280x800; (error ; esperando x800)
Sobre que el ordenador no soporte una resolución que no soporte la tarjeta, pues eso lo se claro ;)
Por eso quiero obtener la resolución del Desktop y no ponerla a pelo...
Y sobre que si fallaba al obtener la resolucion perguntaba por una forma de contornar el problema, para poner otra por defecto, y me has dado la respuesta con el mode_is_ok.
Luego por la noche lo vuelvo a mirar.
Grácias.
El ejemplo lo hice yo ayer ante tu pregunta. Miralo de nuevo con lo que te digo a continuación.
Lo que hace el ejemplo es crear una ventana Bennu con la resolución mayor posible que quepa en tu escritorio, si por cualquier motivo hay un fallo al obtener los datos, entonces pone por defecto 640x480.
Para ello lo que hace es :
obtener los datos de ancho y alto de tu escritorio (descktop_height y desktop_width)
Obtener los datos de ancho y alto del marco de ventana bennu (window_height y window_width).
Obtener los datos de ancho y alto de la ventana embebida bennu (client_heigth y client_width)
Ahora usa una fórmula para calcular el mayor ancho y el mayor alto disponible en tu escritorio con todos estos datos.
Para ello restas el ancho del marco de la ventana con el ancho de la ventana embebida, esto te da justo un valor que corresponde a los perfiles izquierdo y derecho del marco.
Hacemos lo mismo con el alto, obteniendo el valor de los perfiles de arriba y abajo del marco.
Ahora al ancho del escritorio restamos el valor de los perfiles izquierdo y derecho obteniendo el ancho mayor posible en tu desktop para que también se vean los perfiles de la ventana.
Y al alto restamos los perfles de arriba y abajo obteniendo el alto mayor posible para que también se vea la barra de título (y la barra de estado si hubiera)
Adjunto imagen para que se vea más claro, pero vamos, lo suyo es que ejecutes el código ejemplo también para ver efectos.
http://wiki.bennugd.org/index.php?title=Get_window_size
¿Qué es eso de la ventana cliente embebida en Bennu? Yo me quedé en region ???
Yo lo probe ayer y me salia la resolucion normal del juego, igual daba error como dices (cambie la resolución por defecto a la de mi juego que es de 320*200).
Otra cosa es que esto lo hago con fullscreen, que es como ya dije para completar toda la pantalla del pc con el juego.
no lo se, pero desktop_size creo que no va para fullscreen, ahi no hay desktop... creo, no estoy seguro...
por otro lado, para que si estas en fullscreen haces desktop_size?, ya tenes el modo cuando hiciste set_mode, en pc se ajusta solo a fullscreen...
la verdad que no entiendo que estas queriendo hacer...
Quote from: FreeYourMind on November 12, 2009, 07:12:11 AM
Yo dijé que Bennu no la soporta porque no me compila, poniendo tanto:
scale_resolution = m1280x800; (desconocido)
como
scale_resolution = 1280x800; (error ; esperando x800)
Sobre que el ordenador no soporte una resolución que no soporte la tarjeta, pues eso lo se claro ;)
Por eso quiero obtener la resolución del Desktop y no ponerla a pelo...
Y sobre que si fallaba al obtener la resolucion perguntaba por una forma de contornar el problema, para poner otra por defecto, y me has dado la respuesta con el mode_is_ok.
Luego por la noche lo vuelvo a mirar.
Grácias.
puf!!! caramba, es imposible y ridiculo tener definidas todas las constantes que referencien al modo 1x1 hasta NxN... si ves el valor de la constante podrias entender como se compone dicha constante... es mas lo explique con scale_resolution...
ES HHHHWWWW 4 digitos para cada dimension... si queres 1280x800 tenes que poner 12800800...
dios, yo pense que te referias a un problema real... por eso es importante cuando alguien dice que algo no funciona, poner el codigo de lo que no funciona...
Quote from: DCelso on November 12, 2009, 10:34:33 AM
El ejemplo lo hice yo ayer ante tu pregunta. Miralo de nuevo con lo que te digo a continuación.
Lo que hace el ejemplo es crear una ventana Bennu con la resolución mayor posible que quepa en tu escritorio, si por cualquier motivo hay un fallo al obtener los datos, entonces pone por defecto 640x480.
Para ello lo que hace es :
obtener los datos de ancho y alto de tu escritorio (descktop_height y desktop_width)
Obtener los datos de ancho y alto del marco de ventana bennu (window_height y window_width).
Obtener los datos de ancho y alto de la ventana embebida bennu (client_heigth y client_width)
Ahora usa una fórmula para calcular el mayor ancho y el mayor alto disponible en tu escritorio con todos estos datos.
Para ello restas el ancho del marco de la ventana con el ancho de la ventana embebida, esto te da justo un valor que corresponde a los perfiles izquierdo y derecho del marco.
Hacemos lo mismo con el alto, obteniendo el valor de los perfiles de arriba y abajo del marco.
Ahora al ancho del escritorio restamos el valor de los perfiles izquierdo y derecho obteniendo el ancho mayor posible en tu desktop para que también se vean los perfiles de la ventana.
Y al alto restamos los perfles de arriba y abajo obteniendo el alto mayor posible para que también se vea la barra de título (y la barra de estado si hubiera)
Adjunto imagen para que se vea más claro, pero vamos, lo suyo es que ejecutes el código ejemplo también para ver efectos.
http://wiki.bennugd.org/index.php?title=Get_window_size
eso mismo ya lo he explicado... hay que usar el boton de buscar...
Quote from: Windgate on November 12, 2009, 12:59:48 PM
¿Qué es eso de la ventana cliente embebida en Bennu? Yo me quedé en region ???
es el area de trabajo de la ventana... lo demas son bordes/marcos de la ventana... :P
Si es que me explico como un libro cerrado :D, pero para eso puse la imagen, ¿la viste?, gracias Splinter.
si, la imagen excelente... vale mas una imagen que mil palabras...
A ver, voy ahora a empezar a probar de nuevo, antes os aclaro:
1 - No entiendo esto:
ES HHHHWWWW 4 digitos para cada dimension... si queres 1280x800 tenes que poner 12800800...
, entonces porque esto así se define correctamente: m320x200 (o esto 1280x800), tambien lo tenia que poner 03200200 !!!???
2 -
no lo se, pero desktop_size creo que no va para fullscreen, ahi no hay desktop... creo, no estoy seguro...
por otro lado, para que si estas en fullscreen haces desktop_size?, ya tenes el modo cuando hiciste set_mode, en pc se ajusta solo a fullscreen...
la verdad que no entiendo que estas queriendo hacer...
Pues es muy sencillo, si pongo fullscreen la imagen se queda con bordes negros, ya que el juego esta a 320x200, lo que quiero es rescalar el tamaño de la ventana del juego para que ocupe toda la pantalla, sea el pc que sea.... A mi me parece facil de entender esto, los usuarios de emuladores tienen esta opcion en casi todos los emuladores....
Con scale_resolution veo la solución, sólo tengo que saber que valores elejir para cada pantalla del pc en que se ejecute y ponerselos, para eso pergunto si es posible obtenerlos...
Ya tengo una solución, ahora solo me falta que me ayudeis en otra cosa, necesito pegar 2 textos o valores, pero no sumarlos, seria juntarlos creando un texto con la junción de los 2.
O sea, la solución es esta:
Private
string juntar;
Begin
fullscreen = true;
// Es aqui que necesito ayuda, como puedo juntar estas 2 variables en un texto por extenso (y no sumarlas)
juntar = desktop_width-window_width+client_width, desktop_height-window_height+client_height; // 1280, 0800
scale_resolution = juntar; // Valor pretendido: 12800800;
set_mode(m320x200);
Con esto ya tendria el rescalado del juego a pantalla completa manteniendo las proporciones del juego original.
Me queda sólo sabe como manipular strings en Bennu y juntarlas, ya que parece que al igualar int con strings hace la conversión y se pueden igualar.
hombre te suenan la constantes?
en bennu hay ciertas constantes predefinidas... las standards para los modos de video... m320x240 es una constante que tiene un valor numerico... dicho valor es 3200240... hombre 0!!!!
un numero con 4 digitos para una dimension y 4 para la otra...
tu formula no es ninguna solucion, no sirve.... por 2 motivos...
1) "&" da la direccion (puntero) de(a) la variable y no el valor de la misma
2) si tuvieras en dichas variables 1280x800, entonces seria
1280 + 800 = 2080
y eso dista muchisimo de ser 12800800... repito 0800
lo correcto es...
scale_resolution = alto * 10000 + ancho
EDIT: Veo que cambiaste tu formula... igual no va... aca tenes la solucion... :P
Me estoy liando totalmente, perdonar, me apetece llorar.
Edito, que tonto soy, ni comento porque esta parte fallaba ;)
He puesto con window mode, lo siguiente:
write_int(0, 10, 10, 3, &window_width);
write_int(0, 10, 30, 3, &client_width);
write_int(0, 10, 50, 3, &desktop_height);
tengo:
0
0
200
o sea, el código de DCelso no me esta pillando valores de window_width y client_width para poder hacer calculos,
esto:
set_mode (desktop_width-window_width+client_width,desktop_height-window_height+client_height);
me pone la resolucion que tengo por defecto para desktop_width y desktop_height, o sea, 320x200, porque ocurre ? falla al obtener valores para client y window ??
Sobre lo que comentas Splinter, scale_resolution = alto * 10000 + ancho
es la solución ??? no la entiendo, que valores tiene alto y ancho, son los que defino por defecto, o sea, 320x200 ?? y porque se multiplica por 10000 !!!!
Estoy cada vez más perdido... Sólo quiero obtener el valor para poner en el scale_resolution... teniendo por defecto 320x200...
no, no llores... a ver...
si usas el flag fullscreen, entonces no hay windows... en fullscreen lo que vos pongas como set_mode es lo que obtendras en el get_desktop_size (por lo menos asi deberia ser en teoria)... asi que no te sirve de nada... pero no entiendo bien que es lo que queres hacer, asi que esta explicacion puede no serte util...
la formula es: ancho * 10000 + alto (perdon)
con respecto a la multiplicacion por 10000, el porque es demasiado simple, porque 1280 x 10000 = 12800000 = 1280 0000 = WWWW HHHH = 4 digitos de ancho que son 1280
en el caso de:
ancho 1280
alto 800
ancho * 10000 = 1280 * 10000 = 12800000
valor = ancho * 10000 + alto
valor = 12800000 + 800 = 12800800
si modo de video es WWWWHHHH = 12800800 = WWWW HHHH = 1280 0800
wwww = ancho = 1280 = 1280
hhhhh = alto = 0800 = 800
Vale, antes de leer mejor tu ultima explicación, te comento la solución que me funcionaria, en ella solo tengo que saber como juntar 2 valores por extenso para poner en scale_resolution, igual en tu respuesta tengo la solución, pero antes te pongo el código y despues ya miro con calma tu respuesta a ver si puedo de una vez resolver el tema:
full_screen = true;
get_desktop_size(& desktop_width, & desktop_height);
// Como nota aparte, si utilizo get_desktop_size con full_screen=true tambien pilla bien los valores del desktop, pero al final al salir del juego Bennu me da un crash!!, pero utilizando tambien scale_resolution, ya no lo hace, que es justo lo que quiero tambien hacer, así que se queda sólo como nota, no es un problema en este caso
// Parte que falta terminar:
scale_resolution = quiero poner: 12800800 que es juntar &desktop_width con &desktop_height pero por extenso (no su suma)
set_mode(m320x200);
con esto ya hago lo que quiero, sólo me falta poner los valores por extenso.
Vale ya te entiendo, pero hacer eso me peta bennu:
ancho 1280
alto 800
ancho * 10000 = 1280 * 10000 = 12800000
valor = ancho * 10000 + alto
valor = 12800000 + 800 = 12800800
//write_int(0, 10, 20, 3, &desktop_width); --> 1280
//write_int(0, 10, 50, 3, &desktop_height); --> 800
scale_resolution = &desktop_width * 1000 + &desktop_height; // Bennu crash
PERDONAR.... Parece que he bebido, ostias no me puedo creer lo torpe que estoy, me pongo multiplicando punteros, y encima que le falta un cero a la multiplicación...
Solución:
scale_resolution = desktop_width * 10000 + desktop_height;
Perdonar.... grácias por todo vuestro tiempo malgastado :-\
:)
lo importante es que ya salio...
Si :) y por cierto ha sido una de las cosas que más me ha gustado, me encanta poder hacer un Fullscreen Sketch
lastima que se deforma como los tv 16:9 con las señales 4:3... pero bueno... sirve...
Después de tanto lío y no habiendo usado aún scale_resolution me gustaría que pusieses en descarga lo que has conseguido a ver cómo es de vello ;)
A ver si aprendo algo, eso de fullscreen sketch suena bien pero no comprendo a qué te refieres :P
La verdad nunca he visto que una cosa tan sencilla nadie la entienda, a ver si lo explico sin poner fotos :)
Como sabes en la rc112, splinter hizo que el scale_resolution puediera rescalar un juego de menor resolución a mayor resolución (antes sólo lo hacia al reves).
Bueno con esto y obteniendo la resolución del Desktop de tu PC ya se consigue hacer el Fullscreen Sketch.
Esto no es más que poder poner tu juego tenga la resolución que tenga, a pantalla completa (con los incovenientes en la calidad de imagen que esto pueda tener).
Por ejemplo mi juego esta a 320*200, con el Fullscreen=true; , te lo ponia a pantalla completa sin ventanas, pero con unos marcos negros enormes (que completan el resto de la pantalla ya que tiene mayor resolución que el juego).
O sea, con esto tengo una opcion más de video al empezar el juego, y puedo si quiero, que el juego en fullscreen rellene toda mi pantalla (que es lo mismo, un fullscreen Sketh).
Esto en mi portatil con pantalla 16:9 tiene sus incovenienetes, pero yo adoro poder hacerlo, y me encanta ver semejante pixelado moviendose por pantalla :)
Esta opción abunda en juegos echos en C y emuladores.
Espero que por fin lo entiendas, con esta tranquila explicación, ya que me piro ahora mismo del curro :)
Saludos.
Es que en según qué monitores y tarjetas de video, la resolución 320x240 no se soporta, por lo que internamente busca la más pequeña soportada (en mi caso 640x480) y rodea el juego de bandas negras. Si el PC es antiguo si es posible que el 320x240 rellene toda la pantalla.
Lo que entiendo que intenta hacer es buscar la resolución de pantalla y escalar el juego para que la rellene con scale resolution.
Yo hice algo similar, pero en lugar de complicarme tanto, como 640x480 si que se acepta, pues use el 2x_scale :D
Cuando lo pase a Bennu también lo usaré, pero sin fltro, a mi tambien me gustan los gráficos old school (y tampoco me voy a poner a pixelar cosas más grandes :P)
Si de echo tienes razón, ya que mi juego con fullscreen la pantalla es algo más grande, más propria de 640x480.
Pero bueno, con esta técnica sabras siempre que el juego estará a pantalla completa sea la máquina que sea, ya que obtendrá el valor que tengas en el Desktop, y si lo tienes es porque es soportado :)
Incluso, imagina que la pantalla ni soporta los 320x200, pues lo rescalará a menor tamaño, el juego estará a toda pantalla y será compatible :) (que es lo que hacia antes, vease los ejemplos de juegos a 640x480 corriendo en la Wiz que tiene resolución 320x240) ;D
Ahora sí, aunque no me resulta de mucha utilidad te entiendo, gracias FreeYourMind, pero si subes el ejemplito se agradecerá (Mucho pedir?) xD
El ejemplo lo he ido poniendo, tambien es cierto que habia cosas que estaban mal y uno se lia, te pongo el código, es muy sencillo.
Partiendo de que tenemos una resolucion de 320x200 (aqui pondras la que utilizes en tu juego por defecto, o en variables como prefieras):
Por ejemplo si tienes un menu inicial donde el usuario puede elejir entre window mode o fullscreen, o varias resoluciones, el fullscreen sketch seria:
IF(key(_1)) // Fullscreen Mode: Desktop Resolution (Fullscreen sketch)
full_screen = true;
get_desktop_size(& desktop_width, & desktop_height);
scale_resolution = desktop_width * 10000 + desktop_height; // ejemplo: 1280 width * 800 height = 12800800 (12800000 + 800)
set_mode(m320x200);
delete_text(all_text);
intro();
END
Ok, así de sencillo, me alegro, es que mi duda era si podía hacerse en una FUNCTION que se ejecute una vez al principio (Que es el caso) o si había que estar programando todo el tiempo teniendo en cuenta la scale_resolution, karma++ por el aporte final xD
Quote from: Windgate on November 13, 2009, 07:11:11 PM
Ok, así de sencillo, me alegro, es que mi duda era si podía hacerse en una FUNCTION que se ejecute una vez al principio (Que es el caso) o si había que estar programando todo el tiempo teniendo en cuenta la scale_resolution, karma++ por el aporte final xD
muchas gracias por el karma a freeyourmind por la formula que suministre yo! fantastico...
El karma se lo merece Splinter :) Pero vamos con honestidad a mi ni me van ni me vienen ;D
jeje... lo dije en chiste...
Pero hombre te lo mereces tu todo, no se que hariamos sin ti ;)
Y por cierto, diste la formula, si, pero la lógica la puse yo, y por otra parte era un tema que nadie habia pensado :)
Y la formula no fue otra cosa que hacer cuentas para poder juntar por extenso 2 valores enteros, en C# (que utilizo en el curro) eso es muy fácil de hacer :)
Splinter se merece todo, si algún día quieres venir de vacaciones a España cuenta con alojamiento... Es un hilo que leí al final y el ejemplo me lo suministró FreeYourMind, sólo eso :'(
je, mira que te tomo la palabra... deci que perdi mis 900 puntos libres de pasajes de avion por consumirlos en 3 años... pero ya estoy acumulando de nuevo y a buen ritmo... con 600 creo que voy a españa ida y vuelta...
Os pongo unas pantallas de Recalado de Bennu Vs. Rescalado de DOSBox.
En la primera esta la Versión 4.1 para Bennu con doble rescalado (de 320x200 para 640x400) y en la segunda la Version 4.0 de DIV para DOS ejecutandose con DOSBox (el cual internamente parece que hace un rescalado automatico tambien para el doble, o sea, tambien esta a 640x400).
Mola poder ejecutar las 2 al mismo tiempo y comprobar las diferencias en tiempo real :)
Como positivo para Bennu, al cambiar para esta version, la musica toca con más calidad (más alta).
Como cosas negativas, pues me quedan algunas diferencias de ejecución por resolver, por ejemplo la protección de Skull cuando la tiene esta se retarda en obtener la posición x,y de Skull (ya me ocurrio lo mismo en mi anterior port, donde las llamas del reactor de la nave tambien se alejaban de la nave), tengo un suelo de hielo donde skull desliza, pues en Bennu no lo hace y camina normal, sonidos que fallan, etc.
La verdad no me estoy divirtiendo ultimamente con este port, lo que no ocurrio con los anteriores ;(
Espero que al final el balance sea positivo y haya merecido la pena, por lo menos eso creo :)
(http://forum.bennugd.org/index.php?action=dlattach;topic=803.0;attach=698)