domingo, 10 de noviembre de 2013

Empaquetador v1.0

---English version below---


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


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.ASM                                           
Tiene 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:
ld hl,bloques_tiles_fase_51
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*2

Todo 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.ASM                                                                    
This 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.

The structure is loaded with:
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.ASM                                           
They 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_51
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*2

All 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.
Retroinvaders blogs retro informatica