Página 1 de 1

Sincronización de imagen

Publicado: Mar, 10 Dic 2013, 10:25
por radastan
Bien, veamos.

Desde ensamblador puedo hacer un HALT y espero al retrazo vertical, o eso tengo entendido. Sin embargo si hago eso imprimiendo muchos sprites obtengo en pantalla "el baile de San Vito", es decir, los sprites lo mismo corren que andan.

¿Qué forma tengo de producir una interrupción que no sea HALT y que sea admitida por Z88DK?

Ahora mismo esto haciendo algo así:

$this->bbcode_second_pass_code('', '
while(1)
{
disable_int();
for (x=2;x<30;x=x+4)
{
put_sprite_x16 (sprite_prota1, x, 20);
put_sprite_x16 (sprite_malo1, x+2, 20);
}
enable_int();
wait_retrace();
disable_int();
for (x=2;x<30;x=x+4)
{
put_sprite_x16 (sprite_prota2, x, 20);
put_sprite_x16 (sprite_malo2, x+2, 20);

}
enable_int();
wait_retrace();
}')

diable_int() deshabilita las interrupciones
enable_int() habilita las interrupciones
wait_retrace() fuerza un HALT

¿Hay otra forma de hacer que un juego vaya a X imágenes por segundo? es decir, que haga como HALT pero en más ciclos (cada dos retrazos por ejemplo).

Re: Sincronización de imagen

Publicado: Mar, 10 Dic 2013, 10:35
por na_th_an
halt no produce una interrupción, sino que para la CPU hasta que se produzca la próxima. Es la ULA quien interrumpe a la CPU una vez cada 20ms, justo antes de empezar a trazar la imagen (bueno, a trazar el borde superior).

Si tienes "baile de san vito" es porque algunas iteraciones duran más que un frame, y otras menos. Entonces hay veces que tienes un iteraciones que duran dos frames (porque se termina después de que haya terminado uno, y halt espera al siguiente) y otros cuadros que duran un frame (porque dio tiempo).

Este es el problema del que he estado hablando todo este tiempo. Hay que buscarse una forma de poder actualizar sin tener que sincronizarse, y por eso splib2 funciona de la forma que lo hace.

Además, si vas habilitando e inhabilitando las interrupciones el pifostio se acrecenta. Si vas a usar halt, ¿por qué no las dejas activadas?

Lo que tú quieres hacer podría conseguirse con una ISR. Instalas una ISR en modo IM2 que lo único que haga es incrementar un contador. Entonces, en tu bucle de juego, cuando hayas terminado de hacerlo todo, simplemente esperas a que el contador valga 2, y luego lo vuelves a poner a cero. De ese modo los ciclos durarán 2 frames. Pero necesitas una ISR.

Luego puedes usar esa ISR para hacer más cosas, como tocar música AY.

El problema, de todos modos, es que seguramente estés cambiando cosas en la pantalla cuando la ULA la esté mandando a la tele, y se verán parpadeos.

Re: Sincronización de imagen

Publicado: Mar, 10 Dic 2013, 10:42
por radastan
Lo curioso es que si deshabilito las interrupciones cuando dibujo todo va más lento.
si hago sólo HALT hace el baile de San Vito, pero sólo de vez en cuando.

Tendré que mirar con ISR a ver que pasa, podría ser una solución. No me importa algún parpadeo.

EDITADO:

Nones, la solución buena es la clásica. Hago una función de espera de X milisegundos y que cada uno ajuste el valor de espera según lo rápido que vaya su juego. Es muy sencillo, fácilmente entendible, y no toco las interrupciones.

Es más, deshabilito todas las interrupciones de momento y que sólo la música, cuando llegue a esa parte, sea la que tenga inteprrupciones.

Re: Sincronización de imagen

Publicado: Mar, 10 Dic 2013, 11:03
por na_th_an
Seguramente tus problemas tengan que ver con la ISR de BASIC, que hace cosas. Lo suyo es activar el modo IM2 y tener tu propia ISR, aunque esté vacía y no haga nada.

El problema de lo que planteas es que exiges que el código de cada uno dure exactamente lo mismo en cada iteración, pero tampoco es problema.

Re: Sincronización de imagen

Publicado: Mar, 10 Dic 2013, 16:51
por radastan
Lo dicho, la solución del retardo es C O J O N U D A. Sólo hay que tener cuidado de meter un retardo adicional en las pantallas donde haya menos enemigos y listo. Evidentemente puede haber algún parpadeo (que se soluciona con un truco que hacía en BASIC) y habrá situaciones en los que el juego vaya más rápido o más lento, pero son males menores para un curso de introducción a Z88DK.

Da gustito ver 28 cabezones danzando en la pantalla.

Re: Sincronización de imagen

Publicado: Mar, 10 Dic 2013, 20:19
por D_Skywalk
Seguro que es un imposible, pero ¿no podríamos usar algo que contara lo que necesitas en el bucle principal y adaptar la espera?

Tengo ganas de leerlo :adore: :adore:

Re: Sincronización de imagen

Publicado: Mar, 10 Dic 2013, 21:40
por radastan
$this->bbcode_second_pass_quote('D_Skywalk', 'S')eguro que es un imposible, pero ¿no podríamos usar algo que contara lo que necesitas en el bucle principal y adaptar la espera?

Tengo ganas de leerlo :adore: :adore:


Los milagros los hacen Antonio Villena y Na_Th_An, yo soy un pardillo a su lado.

Re: Sincronización de imagen

Publicado: Mar, 10 Dic 2013, 23:17
por antoniovillena
A ver, sin usar el bus flotante a lo único que puedes sincronizarte es a las interrupciones, esto es una vez cada frame en el ciclo 0 (de 69888). La pantalla comienza a dibujarse a partir del ciclo 14400 aproximadamente, por lo que tienes esos ciclos para hacer lo que te dé la gana sin problemas de parpadeos. Le puedes meter el retardo que quieras para sincronizarte en un ciclo determinado, pero meter un retardo a secas es tiempo que desaprovechas para hacer algo útil. Y hay muy pocas cosas útiles que se puedan hacer donde tengas el tiempo controlado, por ejemplo un copiado desde un buffer para borrar los sprites o bien un scroll (como hace Cobra).

Ahora bien con bus flotante (sólo en modelos 48k) hay dos puntos interesantes a los que te puedes sincronizar, esto es al comienzo del retrazo (los 14400 ciclos de antes) o al finalizar el retrazo (unos 15000 ciclos antes de que acabe el frame). Si te sincronizas en este segundo punto tendrías casi 30000 ciclos para pintar sprites sin problemas de parpadeos. Lo que yo estoy intentando en el nuevo engine es poder sincronizarme en cualquier punto y así ganar ciclos extra, para ello necesito 2 líneas con unos patrones fijos, creo que funciona pero hasta que no termine la demo no te puedo decir.

Re: Sincronización de imagen

Publicado: Mié, 11 Dic 2013, 08:22
por na_th_an
$this->bbcode_second_pass_quote('D_Skywalk', 'S')eguro que es un imposible, pero ¿no podríamos usar algo que contara lo que necesitas en el bucle principal y adaptar la espera?

Tengo ganas de leerlo :adore: :adore:


Es la solución que propuse: hacer un ISR con un contador, luego tú en el bucle principal miras el valor del contador y esperas o no, según te haga falta.