Me encanta programar generadores de código:
Hasta ahora estaba usando una hoja de cálculo para organizar los slots del fichero ROM. Cada uno de los archivos de datos los colocaba en una columna junto a su tamaño en bytes y con algunas formulas calculaba manualmente en que slot colocarlo: Comparaba el tamaño del fichero con el primer slot con hueco suficiente.
El problema es cuando el programa empieza a crecer y los archivos cambian de tamaño, al hacer retoques de gráficos o en los mapas. Una organización inicialmente válida, puede no ser válida después de retocar.
Por eso he programado "EL EMPAQUETADOR", que se encarga de localizar todos los archivos (tiles, sprites, mapas y letras), comprobar su tamaño y repartirlos en slots, optimizando el espacio.
Hecho el reparto, genera archivos ASM para incluirlos en el codigo fuente. Así solo tengo que ejecutar el empaquetador antes de compilar sin preocuparme de donde van colocados los ficheros.
Genera 4 archivos diferentes:
-DATOS.ASM
Indica en que posición de memoria dentro de que slot está cada fichero.
phase 0x8000 inicio_codigo_slot_38: til32a4: incbin "tiles\til32a4.g9b" ; 0x8000 til32a7: incbin "tiles\til32a7.g9b" ; 0x80DA til32a8: incbin "tiles\til32a8.g9b" ; 0x8158 til34a4: incbin "tiles\til34a4.g9b" ; 0x822E til36a4: incbin "tiles\til36a4.g9b" ; 0x82FF til37a4: incbin "tiles\til37a4.g9b" ; 0x83F4 til42a5: incbin "tiles\til42a5.g9b" ; 0x84E9 til53a4: incbin "tiles\til53a4.g9b" ; 0x85D3 til71a1: incbin "tiles\til71a1.g9b" ; 0x8690 map21a0: incbin "mapas\map21a0.dat.exo.opt" ; 0x8731 map34b2: incbin "mapas\map34b2.dat.exo.opt" ; 0x87FE map41a1: incbin "mapas\map41a1.dat.exo.opt" ; 0x887A map42a1: incbin "mapas\map42a1.dat.exo.opt" ; 0x88D3 map52a3: incbin "mapas\map52a3.dat.exo.opt" ; 0x899D map52a4: incbin "mapas\map52a4.dat.exo.opt" ; 0x8A5F map61a1: incbin "mapas\map61a1.dat.exo.opt" ; 0x8AFE map62b1: incbin "mapas\map62b1.dat.exo.opt" ; 0x8BD6 ds 0xa000-$ if ($>0xa000) error "Slot_38 overflow" endif dephase fin_codigo_slot_38:
-BLOQUES_MAPAS.ASM
Es una estructura con la información de cada mapa: número de bloques a cargar, y por cada bloque el slot donde está y la dirección.
Se carga con:
ld hl,bloques_mapas_fase_32
call inicializa_mapas
Es una estructura con la información de cada mapa: número de bloques a cargar, y por cada bloque el slot donde está y la dirección.
Se carga con:
ld hl,bloques_mapas_fase_32
call inicializa_mapas
bloques_mapas_fase_32: db 4 ;número de bloques ;Capa a db 42; 0x2A dw map32a0 ; 0x8D7C db 41; 0x29 dw map32a1 ; 0x8A57 ;Capa b db 44; 0x2C dw map32b0 ; 0x8769 db 41; 0x29 dw map32b1 ; 0x8C5B
-BLOQUES_TILES.ASM / BLOQUES_LETRAS_Y_SPRITES.ASMTiene estructuras con la información de los gráficos.Los dos ficheros tienen el mismo formato, pero al haber fases divididas en subfases, están divididos para poder cargar los sprites y letras (comunes a todas las subfases) por un lado y los tiles de cada subfase por otro.
Es una estructura con la información de cada gráfico: número de bloques a cargar, y por cada bloque los siguientes datos:
-Slot ROM
-Dirección de memoria
-Bytes Bajo y medio de destino en VRAM
-Byte alto de destino en VRAM
-Posición de la paleta (16 colores*4 bytes [solo se usan 3]* numero de paleta)
Se carga con:
call carga_bloques_tiles
bloques_letras_y_sprites_fase_10: db 3 ;número de bloques
db 40; 0x28 slot dw let10 ; ; 0x9E58 dw 0xe000 ;hl dw 0x0003;iy, solo se usa iyl db 16*4*2 db 55; 0x37 slot dw spr10e ;Todos los enemigos de Knightmare ; 0x8000 dw 0xd000 ;hl dw 0x0000;iy, solo se usa iyl db 16*4*3 db 49; 0x31 slot dw spr10p ;Todas las poses de Paulo Knightmare ; 0x8000 dw 0x8000 ;hl dw 0x0000;iy, solo se usa iyl db 16*4*2Todo este follón es necesario ya que estamos tratando,de momento, 170 ficheros de datos, a falta de incluir los ficheros de música y sonido y los gráficos de las intros.Actualmente el juego está metido en una ROM de 512KB, pero espero poder dejarlo finalmente en 256KB. Todos los datos se descomprimen en RAM porque el acceso a ROM en el TurboR es más lento que a RAM. Si fuera necesario, he pensado en comprimir además el código de cada fase, dejando en ROM solo sin comprimir el engine del juego.I love programming code generator:Until now I was using a spreadsheet to organize ROM file slots. Each of the data files was placed in a column next to its size in bytes and with some formulas manually calculated the slot, comparing file size with the first slot with enough space. The problem began when the program gets bigger, with every change in map files or graphics files. A initial valid configuration becomes unusable. "EL EMPAQUETADOR" (The packer) searchs for the files (tiles, sprites, maps, chars), and then fits them in slots, optimizing the total space.When the files are located, the program generate ASM files to include in the source code. I only need to execute the packer without worries about where are the files.It generates 4 diferent files:-DATOS.ASMThis file reports in which slot and memory address are each file.phase 0x8000 inicio_codigo_slot_38: til32a4: incbin "tiles\til32a4.g9b" ; 0x8000 til32a7: incbin "tiles\til32a7.g9b" ; 0x80DA til32a8: incbin "tiles\til32a8.g9b" ; 0x8158 til34a4: incbin "tiles\til34a4.g9b" ; 0x822E til36a4: incbin "tiles\til36a4.g9b" ; 0x82FF til37a4: incbin "tiles\til37a4.g9b" ; 0x83F4 til42a5: incbin "tiles\til42a5.g9b" ; 0x84E9 til53a4: incbin "tiles\til53a4.g9b" ; 0x85D3 til71a1: incbin "tiles\til71a1.g9b" ; 0x8690 map21a0: incbin "mapas\map21a0.dat.exo.opt" ; 0x8731 map34b2: incbin "mapas\map34b2.dat.exo.opt" ; 0x87FE map41a1: incbin "mapas\map41a1.dat.exo.opt" ; 0x887A map42a1: incbin "mapas\map42a1.dat.exo.opt" ; 0x88D3 map52a3: incbin "mapas\map52a3.dat.exo.opt" ; 0x899D map52a4: incbin "mapas\map52a4.dat.exo.opt" ; 0x8A5F map61a1: incbin "mapas\map61a1.dat.exo.opt" ; 0x8AFE map62b1: incbin "mapas\map62b1.dat.exo.opt" ; 0x8BD6 ds 0xa000-$ if ($>0xa000) error "Slot_38 overflow" endif dephase fin_codigo_slot_38:
-BLOQUES_MAPAS.ASM
This file has structures with information of each map: numbers of blocks to load and foe each block, the slot and memory addres.
ld hl,bloques_mapas_fase_32The structure is loaded with:
call inicializa_mapas
bloques_mapas_fase_32: db 4 ;número de bloques ;Capa a db 42; 0x2A dw map32a0 ; 0x8D7C db 41; 0x29 dw map32a1 ; 0x8A57 ;Capa b db 44; 0x2C dw map32b0 ; 0x8769 db 41; 0x29 dw map32b1 ; 0x8C5B
-BLOQUES_TILES.ASM / BLOQUES_LETRAS_Y_SPRITES.ASMThey have structures with graph data.
Both files have the same format. As some stages have many sub-stages, the files are divided to load the sprites and character (common to all substages), and the tiles independently.
The structure is: number of blocks to load, and blocks. Each block is:
-ROM Slot
-Memory address
-Low and medium byte of destination VRAM addres
-High byte of destination VRAM address
-Palette position (16 colors*4 bytes [only 3 are used 3]* palette number)The structure is loaded with:ld hl,bloques_tiles_fase_51call carga_bloques_tilesbloques_letras_y_sprites_fase_10: db 3 ;número de bloques
db 40; 0x28 slot dw let10 ; ; 0x9E58 dw 0xe000 ;hl dw 0x0003;iy, solo se usa iyl db 16*4*2 db 55; 0x37 slot dw spr10e ;Todos los enemigos de Knightmare ; 0x8000 dw 0xd000 ;hl dw 0x0000;iy, solo se usa iyl db 16*4*3 db 49; 0x31 slot dw spr10p ;Todas las poses de Paulo Knightmare ; 0x8000 dw 0x8000 ;hl dw 0x0000;iy, solo se usa iyl db 16*4*2All this mess is necessary because we are using, so far, 170 data files, without include music and audio files and intros.Currently the game fits into a 512KB ROM, but I hope to finally fit in 256KB. All data is decompressed in RAM because accessing the TurboR ROM is slower than RAM. If necessary, I thought further compress the code of each stage, leaving only uncompressed the game engine.
No hay comentarios:
Publicar un comentario