› Foros › Retro y descatalogado › Consolas clásicas
replace restart {
ld a,%1
add a,#0xFF
ld %1,a
or a, a
} by {
dec %1
} if notUsed('a')
kusfo79 escribió:@Red Ninja Wonder
Buenas!!
Primero de todo, pedirte disculpas de que a veces no explico todo al detalle (mas que nada para que no se eternice cada lección), pero para eso estoy aquí para solucionar las dudas, jeje.
Primero de todo, los archivos .rel son archivos binarios puros, que son el resultado de compilar un fichero .c. Normalmente, en gcc o otros compiladores de C, suelen tener extensión .o, pero en SDCC decidieron usar la extensión .rel. Estos ficheros los usamos en el paso de linkado para genera el ihx y finalmente la rom.
Por otro lado, las peep-rules son reglas de optimización que se usan en la compilación para optimizar ciertas partes del código. En el github están cambiadas por que de hecho, toda la libreria ha ido evolucionando bastante, y ya no se corresponde exactamente con lo que había cuando empecé el tutorial (de hecho, cuando avance un par de lecciones más, empezaré un minijuego desde cero, y cogeremos las últimas versiones de la librería y usaremos assets2bank en lugar de bank2c, etc). Yo de momento no me preocuparía por eso.
aranya escribió:Hola @kusfo79 , perdona el offtopic, aunque no sea del todo, pero pensé en preguntarlo aquí mejor que en abrir un hilo.
Mira, estaba dando una vuelta por SMSPower, y he leído algo que tú una vez creo que comentaste.
El hilo de SMSPower es este:
http://www.smspower.org/forums/14976-Go ... sterSystem
Dice que en el Golden Axe, no hay sprites, sino que es el fondo que se va actualizando continuamente, sino lo he comprendido mal. Me suena que alguna vez lo has comentado.
¿Por que se hace esto?, ¿Que ventajas tiene?, ¿Es por evitar el flickering?, ¿Por eso es un poco "tosco"?.
Por cierto, justo con el tema Golden Axe, ayer vi este vídeo:
https://m.youtube.com/watch?v=cjeqBOtn6XU
Me llama mucho la atención, el Golden Axe de Spectrum, que es primero que sale, ¡y es 2 players!
El de MS, 1 player y SOLO con Ax Battler...
Perdona por abusar un poco de tu conocimiento.
Un saludo a todos los que están por este hilo.
Gammenon escribió:aranya escribió:Hola @kusfo79 , perdona el offtopic, aunque no sea del todo, pero pensé en preguntarlo aquí mejor que en abrir un hilo.
Mira, estaba dando una vuelta por SMSPower, y he leído algo que tú una vez creo que comentaste.
El hilo de SMSPower es este:
http://www.smspower.org/forums/14976-Go ... sterSystem
Dice que en el Golden Axe, no hay sprites, sino que es el fondo que se va actualizando continuamente, sino lo he comprendido mal. Me suena que alguna vez lo has comentado.
¿Por que se hace esto?, ¿Que ventajas tiene?, ¿Es por evitar el flickering?, ¿Por eso es un poco "tosco"?.
Por cierto, justo con el tema Golden Axe, ayer vi este vídeo:
https://m.youtube.com/watch?v=cjeqBOtn6XU
Me llama mucho la atención, el Golden Axe de Spectrum, que es primero que sale, ¡y es 2 players!
El de MS, 1 player y SOLO con Ax Battler...
Perdona por abusar un poco de tu conocimiento.
Un saludo a todos los que están por este hilo.
Esa técnica se ha usado en varios juegos de Master System y otras consolas de 8 bits. Hay gente que lo llama "software sprites" y efectivamente es ir cambiando los tiles del plano del fondo en tiempo real para dar la ilusión de que son sprites. En Master System lo hace Golden Axe, como has dicho (y por eso no hay opción de 2 jugadores seguramente), Altered Beast, los Mortal Kombat (un personaje está hecho a base de sprites y el otro a base de tiles del fondo), el Street Fighter 2, el Space Harrier, etc. De hecho los MK y SF2 no parpadean, pero Master of Combat sí porque ambos luchadores están formados enteramente de sprites. El que es una bestia es el noseque 3, el VS ese coreano que muestra a las claras los pedazo de juegos de lucha que podría haber hecho la Master System: sprites enormes con una sensación arcade bastante conseguida.
Red Ninja Wonder escribió:Gammenon escribió:aranya escribió:Hola @kusfo79 , perdona el offtopic, aunque no sea del todo, pero pensé en preguntarlo aquí mejor que en abrir un hilo.
Mira, estaba dando una vuelta por SMSPower, y he leído algo que tú una vez creo que comentaste.
El hilo de SMSPower es este:
http://www.smspower.org/forums/14976-Go ... sterSystem
Dice que en el Golden Axe, no hay sprites, sino que es el fondo que se va actualizando continuamente, sino lo he comprendido mal. Me suena que alguna vez lo has comentado.
¿Por que se hace esto?, ¿Que ventajas tiene?, ¿Es por evitar el flickering?, ¿Por eso es un poco "tosco"?.
Por cierto, justo con el tema Golden Axe, ayer vi este vídeo:
https://m.youtube.com/watch?v=cjeqBOtn6XU
Me llama mucho la atención, el Golden Axe de Spectrum, que es primero que sale, ¡y es 2 players!
El de MS, 1 player y SOLO con Ax Battler...
Perdona por abusar un poco de tu conocimiento.
Un saludo a todos los que están por este hilo.
Esa técnica se ha usado en varios juegos de Master System y otras consolas de 8 bits. Hay gente que lo llama "software sprites" y efectivamente es ir cambiando los tiles del plano del fondo en tiempo real para dar la ilusión de que son sprites. En Master System lo hace Golden Axe, como has dicho (y por eso no hay opción de 2 jugadores seguramente), Altered Beast, los Mortal Kombat (un personaje está hecho a base de sprites y el otro a base de tiles del fondo), el Street Fighter 2, el Space Harrier, etc. De hecho los MK y SF2 no parpadean, pero Master of Combat sí porque ambos luchadores están formados enteramente de sprites. El que es una bestia es el noseque 3, el VS ese coreano que muestra a las claras los pedazo de juegos de lucha que podría haber hecho la Master System: sprites enormes con una sensación arcade bastante conseguida.
Pues justo Altered Beast y Golden Axe me parecen de los peores juegos de Master por lo tosco de su movimiento.
aranya escribió:¿Pero entonces esta técnica tiene de ventaja que evitamos el parpadeo tan molesto no?, ¿pero limita a que el Golden Axe sea 1 player?
Sin tener ni idea, le veo de ventaja que parece, o me da la impresión de que no parpadean estos juegos, pero en cambio son un poco bruscos, como el Golden Axe, que a mi me parece muy buen juego, no así el Altered Beast.
kusfo79 escribió:@aranya
El compañero @Gammenon ya lo ha explicado de maravilla. Lo de usar los tiles de fondo como "sprites por software" tiene básicamente una ventaja, que es que te saltas el límite de 8 sprites por scanline. A cambio, requiere bastante proceso, y el movimiento suele ser más brusco. Gaunlet dibuja todos los enemigos con los tiles del fondo para ser capaz de dibujar decenas de enemigos simultáneos.
Si queréis ver como funcionan los juegos, es bastante interesante bajarse el emulicious ( o el Meka), y usar sus opciones de debug para ver lo que es sprite y lo que es tile de fondo. Aquí lo he hecho por ejemplo en el Gauntlet:
Si os fijais, el prota y los disparos son sprites, pero el resto es tilemap(fondo)
kusfo79 escribió:Si queréis, puedo subir más capturas de diferentes juegos en emulicious, y explicar como funcionan. Os gustaria esto?
aranya escribió:@Diskover , vaya, imagino que la NES tendrá que tirar de los mismos trucos que MAS, además de algunos chips en cartuchos puntuales.
aranya escribió:@kusfo79 , vaya, he probado el Brawler con Emulicious y sin tener ni idea, sorprende que en 8 horas fueras capaz de hacerlo. ¿Lo estás continuando?
He entrado en 1985 alternativo pero no he visto nada.
Sobre lo de los sprites y fondos, acabo de probar varios juegos, como The Flash, SoR1 y SoR2, Renegade, y el SF2. El único en el que he visto algo un poco raro, ha sido en el Sf2, ya que en los otros, funcionan como es esperado, es decir, el fondo es fondo, y los personajes Sprites, o por lo menos eso es lo que yo he visto. Pero en el Sf2, el personaje controlado por el player es Sprite, y el controlado por la máquina, es fondo.
kusfo79 escribió:@aranya
De momento no lo estoy continuando, pero lo vamos a continuar en algún momento, también los gráficos que tiene son mockups y cosas ripeadas, y hay problemas con las animaciones, pero si, en algún momento lo continuaremos.
Por otro lado, como ha dicho @Gammenon , lo de poner uno de los dos players como fondo lo hacen tanto este street fighter como los mortal kombat, es una buena solución en general.
@Red Ninja Wonder
Cuando dices barrido, exactamente a que te refieres? Efectos de raster?
Sobre el scroll, es cierto que va al revés de lo habitual. Te pego la definición que dan desde la documentación del VDP
-------------------------------------------------------------------------------
Register $08 can be divided into two parts, the upper five bits are the
starting column, and the lower three bits are the fine scroll value.
On each scanline, the VDP has a column counter that goes from 0 to 31.
The exact pixel on which the VDP starts rendering columns is offset to the
right by the fine scroll value.
For example, if the fine scroll value is set to 7, then 31 columns are
fully visible and the first pixel of the 32nd column is shown at the far
right edge of the display.
The starting column value gives the first column in the name table to use,
calculated by subtracting it from the value 32. So if the starting column
value was $1D, the difference of it from 32 would be $02, hence the first
column drawn is number 2 from the name table.
After each column is drawn, the starting column value is incremented by
one. It wraps at 32. When bit 7 of register #1 is set, it is the column
counter, not the starting column value, that is checked to see when the
vertical scroll value will be set to zero on columns 24 to 31.
-------------------------------------------------------------------------------
Si activamos la flag para que la primera columna de la izquierda de la pantalla se apague, resulta más evidente ver como el "viewport" se desplaza a través del tilemap.
Y si, la variable se resetea sola a 0 cuando llega a 255, dado que la hemos definido como unsigned char, y dado que el plano es precisamente de 256 pixeles, nos va de perlas.
Red Ninja Wonder escribió:Hola compañero, por barrido vertical me refiero al dibujado vertical. Es para entender bien esta función:
SMS_waitForVBlank(): Esta función se queda esperando la interrupción de dibujado vertical. Esta interrupción salta cuando el haz de electrones ha acabado de dibujar la pantalla completa. Es muy útil para sincronizar la velocidad del juego, ya que esta función sincronizará la ejecución a 50 vueltas de bucle (en PAL) o a 60 (en NTSC).
No he encontrado cómo funciona un TV antiguo en ese aspecto.
No sé comó se hace eso de la flag compañero, me temo que mis conocimientos distan aún mucho de los vuestros
Gammenon escribió:Red Ninja Wonder escribió:Hola compañero, por barrido vertical me refiero al dibujado vertical. Es para entender bien esta función:
SMS_waitForVBlank(): Esta función se queda esperando la interrupción de dibujado vertical. Esta interrupción salta cuando el haz de electrones ha acabado de dibujar la pantalla completa. Es muy útil para sincronizar la velocidad del juego, ya que esta función sincronizará la ejecución a 50 vueltas de bucle (en PAL) o a 60 (en NTSC).
No he encontrado cómo funciona un TV antiguo en ese aspecto.
No sé comó se hace eso de la flag compañero, me temo que mis conocimientos distan aún mucho de los vuestros
Las televisiones antiguas, "de tubo" o CRT funcionan con un haz de electrones que barre la pantalla de izquierda a derecha y de arriba abajo. Así se pinta cada píxel de la pantalla, pasito a pasito. El haz va tan rápido que en un sistema PAL tarda 1/50 de segundo en pintar la pantalla entera (por lo que puede actualizar la pantalla entera 50 veces por segundo). Cuando el haz termina un frame el juego, que estaba bloqueado en la llamada a SMS_waitForVBlank(), sigue su ejecución.Así sincronizas el juego con el framerate de la pantalla.
kusfo79 escribió:Vale, el compi @Gammenon lo ha explicado muy bien. El tema es que en estas consolas, hay dos interrupciones, HBLANK y VBLANK, que saltan cada vez que el haz de electrones acaba de dibujar una línea (HBLANK), y otra cada vez que acaba con la última línea de la pantalla (VBLANK). La gracia está que cuando te salta la HBLANK, tienes unos pocos ciclos antes de que el haz de electrones empiece a dibujar la siguente línea. Cuando salta la VBLANK, por otro lado, tienes bastante ciclos antes de que el haz vuelva a empezar por la parte superior de la pantalla.
Las interrupciones de HBLANK son útiles para hacer ciertos efectos raster. Por ejemplo, si cargáis el Sagaia en el emulicious, veréis que en la primera fase el fondo ondula (por el calor del magma). Viendo el tilemap viewer, el fondo es estático, no tiene ninguna ondulación. ¿Como está hecho esto? Lo que se hace es cambiar el valor del scroll horizontal cada ciertas lineas de la pantalla, usando el HBLANK (no se exactamente como está hecho en el juego, pero podría ser algo del tipo: cada 5 lineas, restale uno al scroll, hasta llegar a tal valor, a partir de ese valor, cada 5 líneas súmale uno al scroll).
Por otro lado, el VBLANK sirve para empezar a actualizar el tilemap y los sprites justo cuando se ha acabado de dibujar el frame actual. Es el mejor momento para hacerlo, dado que te aseguras que el haz no está dibujando en la pantalla, y puedes cambiar la posición del scroll o de los sprites sin que aparezcan "cortados" a mitad de pantalla. Lo que hace la función que tenemos, SMS_waitForVBlank(), es parar la ejecución hasta que llega la interrupción. Con esto te aseguras que la velocidad del juego sea mas o menos constante (sinó, iría muy rápido si no hubiera enemigos o cosas en la pantalla).
@Red Ninja Wonder Y sobre la flag, prueba de poner esto en las inicializaciones del VDP: SMS_VDPturnOnFeature(VDPFEATURE_HIDEFIRSTCOL);
justo después de SMS_init();
SMS_loadBGPalette(spyvspypalette_bin);
SMS_loadSpritePalette(spyvspypalette_bin);
SMS_loadPSGaidencompressedTiles (backgroundtiles_psgcompr,0);
SMS_loadPSGaidencompressedTiles (spyvspytiles_psgcompr,256);
kusfo79 escribió:@Red Ninja Wonder
Buenas, hay un par de errores por aquí, que ya me sirven para explicar cosas que igual no han quedado muy claras (Como digo, explico las cosas bastante en general, pero si tenéis dudas, podéis preguntarme sin problema!)
Primero de todo, el tema del tilemap. Los tilemaps, como bien has deducido, los usamos solo para los fondos. Al ser los sprites de 8x8 o de 8x16 (dependiendo del modo escogido), hemos de crear en nuestro código un sprite por cada tile (o por cada dos en el modo 8x16), y hemos de componer nuestro muñeco "a mano". Si avanzas un poco más en la lección, verás la diferencia en como organizamos los tiles de nuestro sprite dependiendo de como hacemos las animaciones.
Luego, el problema que tienes en la carga de los tiles, son dos diferentes. El primero, que estás cargando la paleta de los sprites en la paleta de los fondos, por que estás usando la función:SMS_loadBGPalette(spyvspypalette_bin);
en lugar deSMS_loadSpritePalette(spyvspypalette_bin);
Recuerda que la master tiene dos paletas diferentes disponibles, una para fondos, y otra para sprites, aunque los fondos pueden usar la de sprites en algunos tiles.
Por otro lado, el segundo parámetro que usamos para cargar los tiles es la posición de la vram donde los queremos cargar. Normalmente los fondos usan los 256 tiles de la vram, y los sprites el resto (aunque puedes hacer que los sprites usen los tiles de los fondos con algunos tejemanejes). Así que haríamos algo así:SMS_loadPSGaidencompressedTiles (backgroundtiles_psgcompr,0);
SMS_loadPSGaidencompressedTiles (spyvspytiles_psgcompr,256);
kusfo79 escribió:Es que la scene de Master System daba penita, solo había smspower, pero ahora con el devkitSMS de sverx, la cosa ha cambiado bastante!
Y yo no hago nada hombre, solo un pobre tutorial!
unsigned char player_x;
unsigned char player_y;
#define PLAYER_INITAL_X 30
#define PLAYER_INITAL_Y 130
player_x = PLAYER_INITAL_X;
player_y = PLAYER_INITAL_Y;
int a = 15000;
kusfo79 escribió:Vaya, esto si que es culpa mia, que no lo puse bien. Son dos variables creadas por nosotros, las definimos arriba de todo como así:unsigned char player_x;
unsigned char player_y;
definimos adicionalmente dos constantes:#define PLAYER_INITAL_X 30
#define PLAYER_INITAL_Y 130
Y al principio del main le damos valor así:player_x = PLAYER_INITAL_X;
player_y = PLAYER_INITAL_Y;
Igualmente, recuerda que hay zips con todo el código al final de cada lección
Gammenon escribió:La Master System tiene enteros de 16 bits de forma nativa? Es decir, si hago unint a = 15000;
las operaciones que haga con ese entero tendrán contrapartidas en las instrucciones del Z80 o bien el compilador los imitará por software?
The Z80 processor is able to directly add or subtract both 8 and 16-bit numbers.
struct sprite{
unsigned char x;
unsigned char y;
unsigned char name;
unsigned char state;
}
struct sprite player;
struct sprite enemy;
struct sprite jarron;
struct sprite loquetesalgadelnabo;
player.x = 25;
enemy.name = 'DRAGON';
jarron.y = 100;