Movimiento de sprites a 50fps

Todo sobre la creación, diseño y programación de nuevo software para
nuestro Spectrum

Moderador: Sir Cilve Sinclair

Avatar de Usuario
climacus
Sabreman
Mensajes: 411
Registrado: Mar Ago 25, 2009 1:46 pm

Movimiento de sprites a 50fps

Mensaje por climacus » Lun May 12, 2014 1:04 pm

He empezado a cacharrear con una rutina de sprites a 50pfs usando el método utilizado en Cobra. Es decir, borrando la pantalla destrás del raster.

He conseguido que me funcione bien con 7 sprites en pantalla, pero hay cosas que no entiendo.

En principio, cuando el puerto 255 vale distinto de 255 se empieza a imprimir la primera línea de la pantalla y esto ocurre en el estado 14366. Pero pongo un breakpoint y el contador de estados no siempre tiene es valor. Parece como si dependiera de la duración de las rutinas de volcado de sprites.
No debería valer siempre 14366?
Lo digo porque después de un Halt siempre es fijo (sobre los 97 estados) y si el borde siempre se tarda en imprimir lo mismo...

El puerto 255 es distinto de 255 también cuando el raster alcanza el borde de abajo?

De hecho, en la rutina que me funciona cuando el puerto 255 es distinto de 255 el contador de estados vale sobre los 26200.
Además nunca es igual. Oscila sobre +- 200 estados.

Por supuesto, tengo las interrupciones quitadas, aunque supongo que ese valor debería ser igual siempre no?
Y estoy con el modelo 48k
Todos mis juegos en formato físico
http://www.matranet.net/boutique/zx/zx.php

Avatar de Usuario
Metalbrain
Freddy Hardest
Mensajes: 592
Registrado: Lun May 07, 2007 8:17 am
Ubicación: Sevilla
Contactar:

Re: Movimiento de sprites a 50fps

Mensaje por Metalbrain » Lun May 12, 2014 3:23 pm

climacus escribió:He empezado a cacharrear con una rutina de sprites a 50pfs usando el método utilizado en Cobra. Es decir, borrando la pantalla destrás del raster.

He conseguido que me funcione bien con 7 sprites en pantalla, pero hay cosas que no entiendo.

En principio, cuando el puerto 255 vale distinto de 255 se empieza a imprimir la primera línea de la pantalla y esto ocurre en el estado 14366. Pero pongo un breakpoint y el contador de estados no siempre tiene es valor. Parece como si dependiera de la duración de las rutinas de volcado de sprites.
No debería valer siempre 14366?


Dependerá de cuanto tarda en ejecutarse el test del puerto. Si tarda X estados, se detectará entre 14366 y 14365+X. Y ten en cuenta que por lo general no puedes controlar con que estado entras en la interrupción (dependerá de cuantos estados quedan por ejecutar de la instrucción que estaba pendiente al final del frame anterior).
SevenuP se escribe con u minúscula y P mayúscula.

Avatar de Usuario
climacus
Sabreman
Mensajes: 411
Registrado: Mar Ago 25, 2009 1:46 pm

Re: Movimiento de sprites a 50fps

Mensaje por climacus » Lun May 12, 2014 5:45 pm

Metalbrain escribió:
Dependerá de cuanto tarda en ejecutarse el test del puerto. Si tarda X estados, se detectará entre 14366 y 14365+X. Y ten en cuenta que por lo general no puedes controlar con que estado entras en la interrupción (dependerá de cuantos estados quedan por ejecutar de la instrucción que estaba pendiente al final del frame anterior).


Pero la instrucción del test de puerto tiene una duración constante, no?
Porque al empezar a imprimirse la pantalla (la primera línea del borde) el contador de estados se pone a cero, no?


Si yo hago un bucle hasta que el puerto 255 no valga 255, al acabar el contador de estados debería estar siempre en 14366 más o menos, no? y no depender de lo que dure la rutina de sprites. Simplemente si intento imprimir más sprites de los que puedo antes de que se vuelva a imprimir la pantalla, el juego iría a 25fps. Me explico. Si mi rutina de sprites hace que el contador se ponga a cero y termine en 30000, el bucle debería de esperar hasta que el puerto no valga 255 que esto sería cuando el contador de estados sea 14366.
Todos mis juegos en formato físico
http://www.matranet.net/boutique/zx/zx.php

Avatar de Usuario
Metalbrain
Freddy Hardest
Mensajes: 592
Registrado: Lun May 07, 2007 8:17 am
Ubicación: Sevilla
Contactar:

Re: Movimiento de sprites a 50fps

Mensaje por Metalbrain » Lun May 12, 2014 6:51 pm

climacus escribió:Si yo hago un bucle hasta que el puerto 255 no valga 255, al acabar el contador de estados debería estar siempre en 14366 más o menos, no? y no depender de lo que dure la rutina de sprites. Simplemente si intento imprimir más sprites de los que puedo antes de que se vuelva a imprimir la pantalla, el juego iría a 25fps. Me explico. Si mi rutina de sprites hace que el contador se ponga a cero y termine en 30000, el bucle debería de esperar hasta que el puerto no valga 255 que esto sería cuando el contador de estados sea 14366.


A ver, el puerto 255 vale 255 durante el borde. Durante la generación de la pantalla, vale (creo que) el valor del atributo que acaba de ser leido por la ULA. Si tu rutina de sprites termina por el estado 30000, y enseguida pruebas a esperar que el puerto no valga 255, lo detectará enseguida.

Si quieres que se detecte sobre el 14366 (no será exacto porque aunque la pantalla comienza a generarse en el estado 0, el Z80 no lanza la interrupción hasta que no termina la ejecución de la instrucción que estaba en curso), lo mejor que puedes hacer es esperar a la interrupcción.
SevenuP se escribe con u minúscula y P mayúscula.

Avatar de Usuario
climacus
Sabreman
Mensajes: 411
Registrado: Mar Ago 25, 2009 1:46 pm

Re: Movimiento de sprites a 50fps

Mensaje por climacus » Lun May 12, 2014 8:42 pm

Acabáramos!!! Pensé que sólo valía distinto de 255 al empezar a pintar la pantalla, pero luego ya no. .Qué torpe!!!
Muchísimas gracias. Así me volveré un poco menos loco :)
Todos mis juegos en formato físico
http://www.matranet.net/boutique/zx/zx.php

Avatar de Usuario
antoniovillena
Nonamed
Mensajes: 1164
Registrado: Dom Ene 09, 2011 8:55 am

Re: Movimiento de sprites a 50fps

Mensaje por antoniovillena » Lun May 12, 2014 9:03 pm

A grandes rasgos:
  • La única sincronización válida para todos los modelos de spectrum es la del ciclo 0 y se consigue vía interrupciones.
  • Para evitar parpadeos hay 2 puntos de sincronización interesantes: el borde superior de la zona jugable y el borde inferior de la zona jugable. No tienen por qué coincidir con los bordes superior e inferior de la pantalla.
  • A modo de referencia, la posición del borde inferior (de la pantalla) es 14300 y pico y el inferior 57300 y pico.
  • El borde superior es muy fácil de sincronizar con el puerto flotante (válido para modelos 48K, 128K heatsink y +2, no válido para +2A/+3).
  • El borde inferior es muy difícil de sincronizar, requiere rutinas muy precisas.
  • También puedes sincronizarte a cualquier punto de la pantalla poniendo una banda negra (o cualquier otro color) de 8 líneas justo debajo de la zona jugable.
  • La sincronización con borde superior es útil para hacer juegos con scroll como el Cobra. Si ajustas el ancho de tu zona jugable hasta tener 224 ciclos de reloj por línea (no menos, si no adelantarías al raster) puedes acabar unas pocas líneas debajo del borde inferior, por lo que también te vale para pintar sprites.
  • La sincronización con borde inferior te vale para pintar sprites si parpadeo. Si tu zona jugable es de 192 líneas (máximo) tienes unos 30000 ciclos para pintar sprites sin problemas de parpadeo. A menos líneas de zona jugable, más ciclos para poder pintar sprites sin parpadeo (a 224 ciclos/línea)
  • Con una sincronización por interrupción sólo tenemos 14300 ciclos para pintar sprites sin parpadeo, esto da para muy pocos sprites. Lo que suelen hacer los juegos es pintar en cualquier momento pero siguiendo otro orden distinto para despistar al raster. Por ejemplo primero pinto la línea 0 de todos los sprites, luego la línea 1, etc... Con esto se evita parpadeo pero los sprites no son perfectos, a veces se cortan (la cabeza corresponde a otra animación que el cuerpo).
  • Toda sincronización que hagas por puerto flotante no funciona en +2A/+3, por lo que sería recomendable hacer 2 rutinas distintas, una que sincronice al puerto flotante y otra que sincronice a interrupciones y use shadow screen. Al comienzo del juego detectas el modelo y ejecutas siempre una de esas 2 rutinas.

Con todo lo que te he dicho, aplicado a tu juego a 50fps. Yo haría lo siguiente para la rutina con puerto flotante:
  • Sincronízate a 14300 (borde superior) al comienzo de tu rutina. Olvídate de sincronizarte previamente por interrupción, vas a perder más tiempo y va a ser redundante.
  • Haz tu scroll ajustando el ancho de pantalla. Pruébalo en emulador, siempre será un poco más lento a la cuenta que tu hayas hecho por la contención.
  • Haciendo cuentas, si tu rutina tarda 230 ciclos por línea y tu juego tiene 160 líneas, me salen 36800 ciclos. Por lo que si te sincronizas a 14300 ciclos (la zona jugable debe comenzar en el borde superior) acabarías en el ciclo 51100.
  • Justo después tienes todo el tiempo para pintar sprites. Da igual el orden que emplees, si primero sprites y luego lógica del juego. Desde el ciclo 51100 hasta el 14300 del siguiente frame puedes hacer lo que quieras que no habrá parpadeo. Tienes 33000 ciclos (medio frame). Los sprites prerrotados de 16x16 suelen pintarse en 2000-2500 ciclos cada uno, por lo que el máximo sería entre 13 y 16. Nunca vas a llegar al máximo, algo razonable sería la mitad (entre 6 y 8 sprites).
  • Así a bote pronto tendrías un 50% del frame para el scroll, un 25% para sprites y el 25% restante para todo lo demás.
Imagen

Avatar de Usuario
antoniovillena
Nonamed
Mensajes: 1164
Registrado: Dom Ene 09, 2011 8:55 am

Re: Movimiento de sprites a 50fps

Mensaje por antoniovillena » Lun May 12, 2014 9:12 pm

climacus escribió:Acabáramos!!! Pensé que sólo valía distinto de 255 al empezar a pintar la pantalla, pero luego ya no. .Qué torpe!!!
Muchísimas gracias. Así me volveré un poco menos loco :)


Esto más o menos funciona así:
  • Por encima del borde superior y por debajo del borde superior (estoy hablando del haz de electrones) vale siempre 255.
  • Entre borde superior e inferior a veces vale 255 y a veces no.
  • Una línea dura 224 ciclos. Pues en los 128 primeros ciclos es posible que valga 255, en los restantes 96 (borde vertical o retrazo horizontal) siempre vale 255.
  • De los 128 ciclos en teoría hay una probabilidad de un 50% que valga 255. En realidad se repiten cada 8 ciclos la misma secuencia donde en los 4 primeros ciclos se leen del puerto 4 bytes de atributos/bitmaps alternados (aquí es donde casi seguro es distinto de 255) y los 4 últimos ciclos valen siempre 255.
Imagen

Avatar de Usuario
climacus
Sabreman
Mensajes: 411
Registrado: Mar Ago 25, 2009 1:46 pm

Re: Movimiento de sprites a 50fps

Mensaje por climacus » Lun May 12, 2014 9:30 pm

antoniovillena escribió:A grandes rasgos:
  • La única sincronización válida para todos los modelos de spectrum es la del ciclo 0 y se consigue vía interrupciones.
  • Para evitar parpadeos hay 2 puntos de sincronización interesantes: el borde superior de la zona jugable y el borde inferior de la zona jugable. No tienen por qué coincidir con los bordes superior e inferior de la pantalla.
  • A modo de referencia, la posición del borde inferior (de la pantalla) es 14300 y pico y el inferior 57300 y pico.
  • El borde superior es muy fácil de sincronizar con el puerto flotante (válido para modelos 48K, 128K heatsink y +2, no válido para +2A/+3).
  • El borde inferior es muy difícil de sincronizar, requiere rutinas muy precisas.
  • También puedes sincronizarte a cualquier punto de la pantalla poniendo una banda negra (o cualquier otro color) de 8 líneas justo debajo de la zona jugable.
  • La sincronización con borde superior es útil para hacer juegos con scroll como el Cobra. Si ajustas el ancho de tu zona jugable hasta tener 224 ciclos de reloj por línea (no menos, si no adelantarías al raster) puedes acabar unas pocas líneas debajo del borde inferior, por lo que también te vale para pintar sprites.
  • La sincronización con borde inferior te vale para pintar sprites si parpadeo. Si tu zona jugable es de 192 líneas (máximo) tienes unos 30000 ciclos para pintar sprites sin problemas de parpadeo. A menos líneas de zona jugable, más ciclos para poder pintar sprites sin parpadeo (a 224 ciclos/línea)
  • Con una sincronización por interrupción sólo tenemos 14300 ciclos para pintar sprites sin parpadeo, esto da para muy pocos sprites. Lo que suelen hacer los juegos es pintar en cualquier momento pero siguiendo otro orden distinto para despistar al raster. Por ejemplo primero pinto la línea 0 de todos los sprites, luego la línea 1, etc... Con esto se evita parpadeo pero los sprites no son perfectos, a veces se cortan (la cabeza corresponde a otra animación que el cuerpo).
  • Toda sincronización que hagas por puerto flotante no funciona en +2A/+3, por lo que sería recomendable hacer 2 rutinas distintas, una que sincronice al puerto flotante y otra que sincronice a interrupciones y use shadow screen. Al comienzo del juego detectas el modelo y ejecutas siempre una de esas 2 rutinas.

Con todo lo que te he dicho, aplicado a tu juego a 50fps. Yo haría lo siguiente para la rutina con puerto flotante:
  • Sincronízate a 14300 (borde superior) al comienzo de tu rutina. Olvídate de sincronizarte previamente por interrupción, vas a perder más tiempo y va a ser redundante.
  • Haz tu scroll ajustando el ancho de pantalla. Pruébalo en emulador, siempre será un poco más lento a la cuenta que tu hayas hecho por la contención.
  • Haciendo cuentas, si tu rutina tarda 230 ciclos por línea y tu juego tiene 160 líneas, me salen 36800 ciclos. Por lo que si te sincronizas a 14300 ciclos (la zona jugable debe comenzar en el borde superior) acabarías en el ciclo 51100.
  • Justo después tienes todo el tiempo para pintar sprites. Da igual el orden que emplees, si primero sprites y luego lógica del juego. Desde el ciclo 51100 hasta el 14300 del siguiente frame puedes hacer lo que quieras que no habrá parpadeo. Tienes 33000 ciclos (medio frame). Los sprites prerrotados de 16x16 suelen pintarse en 2000-2500 ciclos cada uno, por lo que el máximo sería entre 13 y 16. Nunca vas a llegar al máximo, algo razonable sería la mitad (entre 6 y 8 sprites).
  • Así a bote pronto tendrías un 50% del frame para el scroll, un 25% para sprites y el 25% restante para todo lo demás.


Estos no son grandes rasgos. Es la Biblia de los 50 fps.!!!!
De momento estoy moviendo sprites solamente y más o menos me funciona con unos 7.
Todavía tengo que pensar una rutina rápida para el scroll siguiendo el raster.
Muchas gracias. La verdad es que es muy interesante!!!
Todos mis juegos en formato físico
http://www.matranet.net/boutique/zx/zx.php

Avatar de Usuario
antoniovillena
Nonamed
Mensajes: 1164
Registrado: Dom Ene 09, 2011 8:55 am

Re: Movimiento de sprites a 50fps

Mensaje por antoniovillena » Lun May 12, 2014 9:45 pm

climacus escribió:Estos no son grandes rasgos. Es la Biblia de los 50 fps.!!!!
De momento estoy moviendo sprites solamente y más o menos me funciona con unos 7.
Todavía tengo que pensar una rutina rápida para el scroll siguiendo el raster.
Muchas gracias. La verdad es que es muy interesante!!!


¿Puedes decirme a cuantos ciclos toca cada cada sprite? Pon a dibujar los 7 sprites, un punto de ruptura al comienzo, otro al final, restas y divides entre 7. Me da la impresión de que tu rutina de pintado es algo lenta (>4000 ciclos)

Para el scroll una rutina muy rápida es la que usa Cobra, échale un vistazo. La idea es trabajar con la pila y pushear los distintos tiles. Un registro de 16 bits te da para una línea de un tile. Esto te limita un poco el mapeo, donde no puedes tener muchos tiles distintos en la misma línea (viene limitado por el número de registros de la CPU). Pero vamos que no es una limitación muy grave y se consigue mucha velocidad (más ancho de zona jugable si ajustas la línea a 224 ciclos).
Imagen

Avatar de Usuario
climacus
Sabreman
Mensajes: 411
Registrado: Mar Ago 25, 2009 1:46 pm

Re: Movimiento de sprites a 50fps

Mensaje por climacus » Lun May 12, 2014 10:06 pm

antoniovillena escribió:
climacus escribió:Estos no son grandes rasgos. Es la Biblia de los 50 fps.!!!!
De momento estoy moviendo sprites solamente y más o menos me funciona con unos 7.
Todavía tengo que pensar una rutina rápida para el scroll siguiendo el raster.
Muchas gracias. La verdad es que es muy interesante!!!


¿Puedes decirme a cuantos ciclos toca cada cada sprite? Pon a dibujar los 7 sprites, un punto de ruptura al comienzo, otro al final, restas y divides entre 7. Me da la impresión de que tu rutina de pintado es algo lenta (>4000 ciclos)

Para el scroll una rutina muy rápida es la que usa Cobra, échale un vistazo. La idea es trabajar con la pila y pushear los distintos tiles. Un registro de 16 bits te da para una línea de un tile. Esto te limita un poco el mapeo, donde no puedes tener muchos tiles distintos en la misma línea (viene limitado por el número de registros de la CPU). Pero vamos que no es una limitación muy grave y se consigue mucha velocidad (más ancho de zona jugable si ajustas la línea a 224 ciclos).


En cuanto pueda te lo digo. Pero creo que se podría optimizar algo.

La rutina de Cobra la miré hace tiempo y tengo el concepto más o menos. Pero antes de estudiarla más prefiero intentarlo por mí mismo que es más divertido. De hecho la rutina de tu demo (flipante, por cierto) sólo la he mirado un poquito;)
Todos mis juegos en formato físico
http://www.matranet.net/boutique/zx/zx.php

Avatar de Usuario
antoniovillena
Nonamed
Mensajes: 1164
Registrado: Dom Ene 09, 2011 8:55 am

Re: Movimiento de sprites a 50fps

Mensaje por antoniovillena » Lun May 12, 2014 10:21 pm

climacus escribió:La rutina de Cobra la miré hace tiempo y tengo el concepto más o menos. Pero antes de estudiarla más prefiero intentarlo por mí mismo que es más divertido. De hecho la rutina de tu demo (flipante, por cierto) sólo la he mirado un poquito;)


En esta web tienes algunas rutinas de Cobra desensambladas:

https://sites.google.com/site/kevinphai ... hescroller

Mi demo no hace scroll pero repinta el fondo a 2/3 del ancho de la pantalla. Nunca he probado a hacer scroll pero si quieres conseguir 50fps lo más seguro es que te quedes a la mitad del ancho de pantalla (Cobra usa todo el ancho pero 25fps). Lo bueno del scroll es que puedes separar volcado de rotación de tiles. Así puedes tener más ancho, volcando durante raster y rotando después del raster (con el pintado de sprites y el resto de rutinas).
Imagen

Avatar de Usuario
climacus
Sabreman
Mensajes: 411
Registrado: Mar Ago 25, 2009 1:46 pm

Re: Movimiento de sprites a 50fps

Mensaje por climacus » Lun May 12, 2014 10:36 pm

antoniovillena escribió:
climacus escribió:La rutina de Cobra la miré hace tiempo y tengo el concepto más o menos. Pero antes de estudiarla más prefiero intentarlo por mí mismo que es más divertido. De hecho la rutina de tu demo (flipante, por cierto) sólo la he mirado un poquito;)


En esta web tienes algunas rutinas de Cobra desensambladas:

https://sites.google.com/site/kevinphai ... hescroller

Mi demo no hace scroll pero repinta el fondo a 2/3 del ancho de la pantalla. Nunca he probado a hacer scroll pero si quieres conseguir 50fps lo más seguro es que te quedes a la mitad del ancho de pantalla (Cobra usa todo el ancho pero 25fps). Lo bueno del scroll es que puedes separar volcado de rotación de tiles. Así puedes tener más ancho, volcando durante raster y rotando después del raster (con el pintado de sprites y el resto de rutinas).


Me estás tentando con el desensamblado de Cobra!!!
No me importaría que todo esto me funcionara a 25fps!!
Todos mis juegos en formato físico
http://www.matranet.net/boutique/zx/zx.php

Avatar de Usuario
Hark0
Freddy Hardest
Mensajes: 545
Registrado: Mar Nov 13, 2012 12:42 pm
Ubicación: Cornella de Llobregat - Barcelona
Contactar:

Re: Movimiento de sprites a 50fps

Mensaje por Hark0 » Mar May 13, 2014 7:58 am

hmmm eso es lo que me estoy preguntando desde que iniciaste el hilo...

50fps?

hacen falta tantos?
litiopixel.blogspot.com - Desarrollo videojuegos Indie · Pixel-Art · Retroinformática · Electrónica

Avatar de Usuario
climacus
Sabreman
Mensajes: 411
Registrado: Mar Ago 25, 2009 1:46 pm

Re: Movimiento de sprites a 50fps

Mensaje por climacus » Mar May 13, 2014 8:29 am

Hark0 escribió:hmmm eso es lo que me estoy preguntando desde que iniciaste el hilo...

50fps?

hacen falta tantos?


Más que nada por reto personal. Pero a 25 sobra y encima le puedes dar mucha más variedad en pantalla.
Todos mis juegos en formato físico
http://www.matranet.net/boutique/zx/zx.php

Avatar de Usuario
Hark0
Freddy Hardest
Mensajes: 545
Registrado: Mar Nov 13, 2012 12:42 pm
Ubicación: Cornella de Llobregat - Barcelona
Contactar:

Re: Movimiento de sprites a 50fps

Mensaje por Hark0 » Mar May 13, 2014 8:33 am

Me lo imaginaba... a 50fps... ni que fuera una xbox... :lol:

pd/ot: ¿sigues escribiendo el juego de "trenes"?
litiopixel.blogspot.com - Desarrollo videojuegos Indie · Pixel-Art · Retroinformática · Electrónica

Responder

¿Quién está conectado?

Usuarios navegando por este Foro: Ahrefs [Bot], Google [Bot] y 5 invitados