178 lines
4.5 KiB
C
178 lines
4.5 KiB
C
// extract tilesxxx.bmp from uncompressed DAVE.EXE
|
|
#include <stdint.h>
|
|
#include <inttypes.h>
|
|
#include <stdio.h>
|
|
|
|
#include "util.h"
|
|
|
|
// all tiles in the exe
|
|
static SDL_Surface* tile_sfc[NUM_EXE_TILES];
|
|
|
|
// export all tiles to bmp
|
|
void Util_SaveTiles() {
|
|
// Save out the all tile surfaces
|
|
for ( int curtil = 0; curtil < NUM_EXE_TILES; ++curtil ) {
|
|
SDL_Surface* sfc = tile_sfc[curtil];
|
|
printf( "Saving tile%03d.bmp (%ux%u)...\n", curtil, sfc->w, sfc->h );
|
|
char fname[1024];
|
|
snprintf( fname, 1024, "./tiles/tile%03d.bmp", curtil );
|
|
SDL_SaveBMP( sfc, fname );
|
|
}
|
|
}
|
|
|
|
// return tile surface array for external use
|
|
SDL_Surface** Util_GetTileSurfaces() {
|
|
return tile_sfc;
|
|
}
|
|
|
|
// fill global tile array with tiles from exe
|
|
void Util_LoadTiles() {
|
|
const uint32_t vga_data_addr = 0x120f0;
|
|
const uint32_t vga_pal_addr = 0x26b0a;
|
|
// exe assumed uncompressed
|
|
SDL_RWops* ddexe = SDL_RWFromFile( "res/DAVE.EXE", "rb" );
|
|
if ( ddexe != NULL ) printf( "SUCCESS! (%"PRIi64" bytes)\n", SDL_RWsize( ddexe ) );
|
|
else { fprintf( stderr, "Error opening DAVE.EXE for tiles!\n" ); exit( EXIT_FAILURE ); }
|
|
|
|
// tileset
|
|
SDL_RWseek( ddexe, vga_data_addr, RW_SEEK_SET );
|
|
uint32_t tssz;
|
|
SDL_RWread( ddexe, &tssz, 4, 1 );
|
|
printf( "Uncompressed tileset size: %u\n", tssz );
|
|
uint8_t* tsdat = malloc( tssz );
|
|
memset( tsdat, 0, tssz );
|
|
uint8_t bytebuf = 0;
|
|
uint8_t* tsbyte = tsdat; // current output byte to be written to
|
|
// uncompress RLE
|
|
while ( (tsbyte - tsdat) < tssz ) {
|
|
SDL_RWread( ddexe, &bytebuf, 1, 1 );
|
|
|
|
if ( bytebuf & 0x80 ) { // unchanged
|
|
uint32_t cnt = ((bytebuf & 0x7f) + 1);
|
|
|
|
while ( cnt-- ) {
|
|
SDL_RWread( ddexe, &bytebuf, 1, 1 );
|
|
*tsbyte = bytebuf; tsbyte++;
|
|
}
|
|
} else { // repeated
|
|
uint32_t cnt = bytebuf + 3;
|
|
SDL_RWread( ddexe, &bytebuf, 1, 1 ); // byte to be repeated
|
|
while ( cnt-- ) {
|
|
*tsbyte = bytebuf; tsbyte++;
|
|
}
|
|
}
|
|
}
|
|
|
|
// palette
|
|
SDL_RWseek( ddexe, vga_pal_addr, RW_SEEK_SET );
|
|
uint8_t paldat[768];
|
|
memset( paldat, 0, 768 );
|
|
// reach each color and convert from 6bit to 8bit
|
|
for ( int i = 0; i < 256; ++i ) {
|
|
SDL_RWread( ddexe, paldat + (i * 3), 3, 1 );
|
|
paldat[i*3] <<= 2;
|
|
paldat[i*3+1] <<= 2;
|
|
paldat[i*3+2] <<= 2;
|
|
}
|
|
|
|
// note: extra byte every 65536 bytes
|
|
// total tile count
|
|
SDL_RWops* tsfil = SDL_RWFromMem( tsdat, tssz );
|
|
uint32_t tscnt;
|
|
SDL_RWread( tsfil, &tscnt, 4, 1 );
|
|
printf( "Tile count: %u\n", tscnt );
|
|
|
|
// tile offsets
|
|
uint32_t tsoffs[tscnt+1];
|
|
for ( int i = 0; i < tscnt; ++i ) {
|
|
SDL_RWread( tsfil, &tsoffs[i], 4, 1 );
|
|
//printf( "ts%u: %u -- ", i, tsoffs[i] );
|
|
}
|
|
// last tile ends at EOF
|
|
tsoffs[tscnt] = tssz;
|
|
|
|
uint16_t tw, th;
|
|
uint32_t curbyte;
|
|
uint8_t curtil;
|
|
// read each tile
|
|
for ( curtil = 0; curtil < tscnt; curtil++ ) {
|
|
//curtilbyte = 0;
|
|
curbyte = tsoffs[curtil];
|
|
tw = 16; th = 16;
|
|
// skip extra byte
|
|
if ( curbyte > 65280 )
|
|
curbyte++;
|
|
// curbyte is now actual offset to raw image data
|
|
SDL_RWseek( tsfil, curbyte, RW_SEEK_SET );
|
|
|
|
// check if dimension thats not 16x16, assumed if current chunk size is not 256
|
|
if ( tsoffs[curtil+1] - tsoffs[curtil] != 256 ) {
|
|
SDL_RWread( tsfil, &tw, 2, 1 );
|
|
SDL_RWread( tsfil, &th, 2, 1 );
|
|
curbyte += 4;
|
|
}
|
|
|
|
// fill a new 32bpp surface using palette
|
|
SDL_Surface* tilsfc = SDL_CreateRGBSurface( 0, tw, th, 32, 0,0,0,0 );//SDL_PIXELFORMAT_RGBA32 );
|
|
SDL_LockSurface( tilsfc );
|
|
uint8_t* pxp = (uint8_t*)(tilsfc->pixels);
|
|
|
|
for ( int p = 0; p < tw * th; ++p ) {
|
|
uint8_t ix;
|
|
SDL_RWread( tsfil, &ix, 1, 1 );
|
|
size_t pos = p * 4;
|
|
// bgra
|
|
pxp[pos] = paldat[ix*3+2];
|
|
pxp[pos+1] = paldat[ix*3+1];
|
|
pxp[pos+2] = paldat[ix*3];
|
|
pxp[pos+3] = 255;//(ix == 0) ? 0 : 255;
|
|
}
|
|
SDL_UnlockSurface( tilsfc );
|
|
// store surface in global tile array
|
|
tile_sfc[curtil] = tilsfc;
|
|
|
|
//SDL_FreeSurface( tilsfc );
|
|
|
|
//printf( "ts%u (%ux%u) @ %u -- ", curtil, tw, th, curbyte );
|
|
}
|
|
|
|
SDL_RWclose( tsfil );
|
|
free( tsdat );
|
|
|
|
// done with exe
|
|
SDL_RWclose( ddexe );
|
|
}
|
|
|
|
// free all loaded exe's tile surfaces
|
|
void Util_FreeTileSurfaces() {
|
|
for ( int i = 0; i < NUM_EXE_TILES; ++i ) {
|
|
SDL_FreeSurface( tile_sfc[i] );
|
|
}
|
|
}
|
|
|
|
#ifdef UTIL_BIN
|
|
int main( int argc, char** argv ) {
|
|
// high scores
|
|
/*SDL_RWops* dscor = SDL_RWFromFile( "res/DSCORES.DAV", "rb" );
|
|
uint8_t lscor[9];
|
|
while ( SDL_RWread( dscor, lscor, 9, 1 ) ) {
|
|
printf( "LVL %u - SCORE: %u%u%u%u%u - NAM: %.3s\n", lscor[0],
|
|
lscor[1], lscor[2], lscor[3], lscor[4], lscor[5], (char*)&lscor[6] );
|
|
}
|
|
SDL_RWclose( dscor );*/
|
|
|
|
Util_LoadTiles();
|
|
Util_SaveTiles();
|
|
|
|
// LEVELS
|
|
Util_LoadLevels();
|
|
Util_SaveLevels();
|
|
Util_CreateWorldMap();
|
|
|
|
Util_FreeTileSurfaces();
|
|
|
|
return 0;
|
|
}
|
|
#endif
|
|
|