Sincronización de imagen

Chit chat general. Habla con los MojonTwins y con los amigos de los MojonTwins. Reza a Vah-ka. Delinque. Aviso: está PROHIBIDO tirarse peos fuerte. Si les cortas el pescuezo, vale.

Moderador: na_th_an

Avatar de Usuario
radastan
Mensajes: 692
Registrado: Vie, 20 Ago 2010, 12:54
Contactar:

Sincronización de imagen

Mensajepor radastan » Mar, 10 Dic 2013, 10:25

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).
Adjuntos
juego.tap
Ejemplo de Baile de San Vito
(1.73 KiB) Descargado 176 veces
Avatar de Usuario
na_th_an
Mensajes: 26413
Registrado: Vie, 09 Ene 2009, 12:18

Re: Sincronización de imagen

Mensajepor na_th_an » Mar, 10 Dic 2013, 10:35

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.
Como diría Rorshach: "Urm..."
Avatar de Usuario
radastan
Mensajes: 692
Registrado: Vie, 20 Ago 2010, 12:54
Contactar:

Re: Sincronización de imagen

Mensajepor radastan » Mar, 10 Dic 2013, 10:42

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.
Avatar de Usuario
na_th_an
Mensajes: 26413
Registrado: Vie, 09 Ene 2009, 12:18

Re: Sincronización de imagen

Mensajepor na_th_an » Mar, 10 Dic 2013, 11:03

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.
Como diría Rorshach: "Urm..."
Avatar de Usuario
radastan
Mensajes: 692
Registrado: Vie, 20 Ago 2010, 12:54
Contactar:

Re: Sincronización de imagen

Mensajepor radastan » Mar, 10 Dic 2013, 16:51

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.
Avatar de Usuario
D_Skywalk
Mensajes: 352
Registrado: Mar, 01 Oct 2013, 13:36

Re: Sincronización de imagen

Mensajepor D_Skywalk » Mar, 10 Dic 2013, 20:19

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:
David Skywalker
Weblog: http://david.dantoine.org
Avatar de Usuario
radastan
Mensajes: 692
Registrado: Vie, 20 Ago 2010, 12:54
Contactar:

Re: Sincronización de imagen

Mensajepor radastan » Mar, 10 Dic 2013, 21:40

$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.