void save_level (FILE* file, const Level& level) { fprintf(file, "Level: %d x %d\n", level.w, level.h); for (int y = 0; y < level.h; ++y) { for (int x = 0; x < level.w; ++x) { save_tile(file, level.tile(x, y)); } fprintf(file, "\n"); } }
bool Tile_map::save() { std::ofstream file(map_info.filename , std::ios_base::out | std::ios_base::binary ); uint8_t * buffer = new uint8_t (8); buffer[0] = 0xA9; buffer[1] = 0xB2; buffer[2] = 0x18; buffer[3] = 0x04; buffer[4] = 0xE1; buffer[5] = 0x64; buffer[6] = 0xF5; buffer[7] = 0x9D; // initialize the map by checksum for(int a=0 ; a < 8 ; a++) { file<<buffer[a]; } delete [] buffer; // save major and minor map version file<<map_info.major_version; file<<map_info.minor_version; // save map name file<<map_info.map_name<<'\n'; file<<map_info.width<<' '; file<<map_info.height<<' '; if(player) { file<<Chunk_type::player<<' '; save_player(file); } for(auto & a : sets_of_tiles) { file<<Chunk_type::tile_set<<' '; save_tile_set(file,a); } for(auto & a : types_of_tile) { file<<Chunk_type::tile_type<<' '; save_tile_type(file,a); } for(auto & a : tiles) { file<<Chunk_type::tile<<' '; save_tile(file,a); } if(background) { file<<Chunk_type::background<<' '; save_background(file); } return true; }
static void loadsty(char* filename, char* exprt, char* setname_tex, char* setname_spr, char* setname_font, char* etiles, char* esprites) { sty = fopen(filename,"rb"); fseek(sty,0,2); int filesize = ftell(sty); fseek(sty,0,0); printf("Reading %s...\n",filename); FREAD(&chunkheader, 1, 4, sty, filename, printf); FREAD(&chunkdata, 2, 1, sty, filename, printf); if (chunkheader != 0x54534247) { //GBST printf("Not a GTA2 style file!\n"); return; } if ((chunkdata & 0xFFFF) != 700) { printf("Bad GTA2 style file version (must be 700)\n"); return; } sprite_count = 0; bool TilesPresent = false; bool SpritesPresent = false; //read map chunks while (ftell(sty) < filesize) { FREAD(&chunkheader, 1, 4, sty, filename, printf); FREAD(&chunkdata, 1, 4, sty, filename, printf); printf("\n"); /* PALX palette index PPAL physical palettes PALB palette base TILE tiles SPRG sprite graphics SPRX sprite index SPRB sprites bases DELS delta store DELX delta index FONB font base CARI car info OBJI map object info PSXT PSX tiles RECY car recycling info*/ switch (chunkheader) { case 0x584C4150: //PALX printf("PALX: Found PALX chunk [size: %d]\n",chunkdata); printf("PALX: Reading %d pallete entries\n",chunkdata/2); FREAD(&pallete_index,1,32768,sty, filename, printf); break; case 0x4C415050: //PPAL printf("PPAL: Found PPAL chunk [size: %d]\n",chunkdata); printf("PPAL: Reading %d pallete pages (%d palletes)\n",chunkdata/(64*1024),chunkdata/(1024)); FREAD(&pallete,4,chunkdata/4,sty, filename, printf); break; case 0x424C4150: //PALB printf("PALB: Found PALB chunk [size: %d]\n",chunkdata); printf("PALB: Reading pallete bases...\n"); FREAD(&palletebase.tile,2,1,sty, filename, printf); FREAD(&palletebase.sprite,2,1,sty, filename, printf); FREAD(&palletebase.car_remap,2,1,sty, filename, printf); FREAD(&palletebase.ped_remap,2,1,sty, filename, printf); FREAD(&palletebase.code_obj_remap,2,1,sty, filename, printf); FREAD(&palletebase.map_obj_remap,2,1,sty, filename, printf); FREAD(&palletebase.user_remap,2,1,sty, filename, printf); FREAD(&palletebase.font_remap,2,1,sty, filename, printf); printf("PALB: tile base: %d\n",palletebase.tile); printf("PALB: sprite base: %d\n",palletebase.sprite); printf("PALB: car_remap base: %d\n",palletebase.car_remap); printf("PALB: ped_remap base: %d\n",palletebase.ped_remap); printf("PALB: code_obj_remap base: %d\n",palletebase.code_obj_remap); printf("PALB: map_obj_remap base: %d\n",palletebase.map_obj_remap); printf("PALB: user_remap base: %d\n",palletebase.user_remap); printf("PALB: font_remap base: %d\n",palletebase.font_remap); break; case 0x454C4954: //TILE printf("TILE: Found TILE chunk [size: %d]\n",chunkdata); printf("TILE: Reading %d tiles...\n",chunkdata/(64*64)); FREAD(&tile_data,1,chunkdata,sty, filename, printf); TilesPresent = true; break; case 0x47525053: //SPRG printf("SPRG: Found SPRG chunk [size: %d]\n",chunkdata); printf("SPRG: Reading sprite graphics\n"); FREAD(&spritedata[0],1,chunkdata,sty, filename, printf); SpritesPresent = true; break; case 0x58525053: //SPRX printf("SPRX: Found SPRX chunk [size: %d]\n",chunkdata); printf("SPRX: Reading %d sprites...\n",chunkdata/8); FREAD(&sprite_entries[0],1,chunkdata,sty, filename, printf); sprite_count = chunkdata/8; break; case 0x42525053: //SPRB unsigned short temp; printf("SPRB: Found SPRB chunk [size: %d]\n",chunkdata); printf("SPRB: Reading sprite bases...\n"); spritebase.car = 0; FREAD(&temp,2,1,sty, filename, printf); spritebase.ped = spritebase.car + temp; FREAD(&temp,2,1,sty, filename, printf); spritebase.code_obj = spritebase.ped + temp; FREAD(&temp,2,1,sty, filename, printf); spritebase.map_obj = spritebase.code_obj + temp; FREAD(&temp,2,1,sty, filename, printf); spritebase.user = spritebase.map_obj + temp; FREAD(&temp,2,1,sty, filename, printf); spritebase.font = spritebase.user + temp; FREAD(&temp,2,1,sty, filename, printf); /*spritebase.ped = spritebase.car; spritebase.car = 0; spritebase.code_obj += spritebase.ped; spritebase.map_obj += spritebase.code_obj; spritebase.user += spritebase.map_obj; spritebase.font += spritebase.user;*/ printf("SPRB: car base: %d\n",spritebase.car); printf("SPRB: ped base: %d\n",spritebase.ped); printf("SPRB: code_obj base: %d\n",spritebase.code_obj); printf("SPRB: map_obj base: %d\n",spritebase.map_obj); printf("SPRB: user base: %d\n",spritebase.user); printf("SPRB: font base: %d\n",spritebase.font); break; case 0x534C4544: //DELS printf("DELS: Found DELS chunk [size: %d]\n",chunkdata); fseek(sty,chunkdata,1); break; case 0x584C4544: //DELX printf("DELX: Found DELX chunk [size: %d]\n",chunkdata); fseek(sty,chunkdata,1); break; case 0x424E4F46: //FONB printf("FONB: Found FONB chunk [size: %d]\n",chunkdata); //fseek(sty,chunkdata,1); FREAD(&fontbase.font_count,2,1,sty, filename, printf); printf("FONB: Found %d fonts...\n",fontbase.font_count); fontbase.sprbase[0] = spritebase.font; for (int i=0;i<fontbase.font_count;i++) { FREAD(&fontbase.base[i],2,1,sty, filename, printf); if (i > 0) fontbase.sprbase[i] = fontbase.sprbase[i-1] + fontbase.base[i]; printf("FONB: Font %d [%d characters, sprbase %d]\n",i,fontbase.base[i],fontbase.sprbase[i]); } break; case 0x49524143: //CARI printf("CARI: Found CARI chunk [size: %d]\n",chunkdata); fseek(sty,chunkdata,1); break; case 0x494A424F: //OBJI printf("OBJI: Found OBJI chunk [size: %d]\n",chunkdata); fseek(sty,chunkdata,1); break; case 0x54585350: //PSXT printf("PSXT: Found PSXT chunk, skipping (dont need PSX tiles) [size: %d]\n",chunkdata); fseek(sty,chunkdata,1); break; case 0x59434552: //RECY printf("RECY: Found RECY chunk [size: %d]\n",chunkdata); fseek(sty,chunkdata,1); break; case 0x43455053: //SPEC printf("SPEC: Undocumented SPEC chunk, skipping [size: %d]\n",chunkdata); fseek(sty,chunkdata,1); break; default: printf("UNKN: Unknown/unsupported chunk, skipping [size: %d]\n",chunkdata); fseek(sty,chunkdata,SEEK_CUR); break; } } if (strcmp(exprt,"true") == 0) { if (strcmp(etiles,"true") != 0) { printf("\nExporting tiles...\n"); for (int i=0;i<992;i++) { char tilename[256]; sprintf(&tilename[0],"tile_%d.bmp",i); save_tile(&tilename[0],i); printf("..writing tile bitmaps %d\r",i); } } if (strcmp(esprites,"true") == 0) { printf("\n\nExporting sprites...\n"); for (int i=0;i<sprite_count;i++) { char tilename[256]; sprintf(&tilename[0],"sprite_%d.bmp",i); save_sprite(&tilename[0],i); printf("..writing sprite %d\r",i); } } } printf("\nSaving graphics (opengta.tex)\n"); bmp = fopen("opengta.tex","wb+"); char header[5] = "ZTEX"; int chunksize = 4; int texversion = 130; fwrite(&header[0],1,4,bmp); //"ZTEX" fwrite(&chunksize,4,1,bmp); fwrite(&texversion,4,1,bmp); printf("\tchunk %s (%d bytes)\n",header,chunksize); if (strcmp(etiles,"true") != 0) { TilesPresent = false; } if (strcmp(esprites,"true") != 0) { SpritesPresent = false; } //Write tile data int cpos; if (TilesPresent) { sprintf(header,"%s","TILE"); chunksize = 0; fwrite(&header[0],1,4,bmp); //"TILE" cpos = ftell(bmp); chunksize += fwrite(&chunksize,4,1,bmp); texversion = strlen(setname_tex); chunksize += fwrite(&texversion,1,1,bmp); //TILEID: 0 chunksize += fwrite(&setname_tex[0],1,texversion,bmp); printf("\t\tGenerating texture atlas for tiles\n"); Texture_Atlas tileAtlas; tileAtlas.createEmpty(2048,2048); tileAtlas.atlasStart(1024); for (int i=0;i<992;i++) { copy_tile(i); printf("\t\tTile: %d out of %d\r",i,992); tileAtlas.atlasAdd(0x1,0x0,4,64,64,(unsigned char*)&sprite_buffer[0]); //write_tile_tex(i); } printf("\nEffective atlas size: %d bytes (%d KB)\n",tileAtlas.effectiveSize(),tileAtlas.effectiveSize() / 1024); tileAtlas.atlasStop(); tileAtlas.dumpBMP("tiles.bmp"); //Write atlas chunksize += fwrite(tileAtlas.textureData,1,tileAtlas.effectiveSize(),bmp); //for (int y = 0; y < tileAtlas.atlasHeight; y++) //for (int x = 0; x < tileAtlas.atlasWidth; x++) //fwrite(&tileAtlas.textureData[x+y*tileAtlas.atlasWidth],4,1,bmp); tileAtlas.releaseTexture(); printf("\tchunk %s (%d bytes)\n",header,chunksize); fseek(bmp,cpos,0); fwrite(&chunksize,4,1,bmp); fseek(bmp,chunksize,1); } //Write sprite data if (SpritesPresent) { sprintf(header,"%s","SPR0"); chunksize = 0; fwrite(&header[0],1,4,bmp); //"SPR0" (sprite data) cpos = ftell(bmp); fwrite(&chunksize,4,1,bmp); texversion = strlen(setname_spr); chunksize += fwrite(&texversion,1,1,bmp); //TILEID: 0 chunksize += fwrite(&setname_spr[0],1,texversion,bmp); //Prepare tiles for (int i = 0; i < sprite_count; i++) sprite_entries[i].pad = i; sort_tiles(); printf("\t\tGenerating texture atlas for sprites (takes a while)\n"); Texture_Atlas spriteAtlas; spriteAtlas.createEmpty(2048,2048); spriteAtlas.atlasStart(8192); //sprite_count = 64; int atlasid[8192]; for (int i=0;i<sprite_count;i++) { copy_sprite(i); printf("\t\tSprite: %d out of %d\r",i,sprite_count); atlasid[sprite_entries[i].pad] = spriteAtlas.atlasAdd(0x1,0x0,4,sprite_entries[i].w,sprite_entries[i].h,(unsigned char*)&sprite_buffer[0]); } printf("\nEffective atlas size: %d bytes (%d KB)\n",spriteAtlas.effectiveSize(),spriteAtlas.effectiveSize() / 1024); printf("\t\tWriting sprites\n"); //Unsort sprites (from previous sort request) bool all_sort; do { all_sort = true; for (int i = 0; i < sprite_count; i++) if (sprite_entries[i].pad != i) { int j = sprite_entries[i].pad; sprite_entry tmp = sprite_entries[i]; sprite_entries[i] = sprite_entries[j]; sprite_entries[j] = tmp; all_sort = false; } } while (all_sort == false); //Write sprite information chunksize += 4*fwrite(&sprite_count,4,1,bmp); for (int i=0;i<sprite_count;i++) { char spritename[256]; sprintf(&spritename[0],"%s_%d",setname_spr,i); unsigned char namelen = strlen(&spritename[0]); chunksize += fwrite(&namelen,1,1,bmp); chunksize += fwrite(&spritename[0],1,namelen,bmp); //chunksize += fwrite(&sprite_entries[i].w,1,1,bmp); //chunksize += fwrite(&sprite_entries[i].h,1,1,bmp); //chunksize += fwrite(&sprite_entries[i].,1,1,bmp); chunksize += 4*fwrite(&spriteAtlas.atlasTextures[atlasid[i]].Left,4,1,bmp); chunksize += 4*fwrite(&spriteAtlas.atlasTextures[atlasid[i]].Right,4,1,bmp); chunksize += 4*fwrite(&spriteAtlas.atlasTextures[atlasid[i]].Top,4,1,bmp); chunksize += 4*fwrite(&spriteAtlas.atlasTextures[atlasid[i]].Bottom,4,1,bmp); } spriteAtlas.atlasStop(); spriteAtlas.dumpBMP("sprites.bmp"); //Write atlas chunksize += fwrite(spriteAtlas.textureData,1,spriteAtlas.effectiveSize(),bmp); //for (int y = 0; y < spriteAtlas.atlasHeight; y++) //for (int x = 0; x < spriteAtlas.atlasWidth; x++) //fwrite(&spriteAtlas.textureData[x+y*spriteAtlas.atlasWidth],4,1,bmp); spriteAtlas.releaseTexture(); printf(" chunk %s (%d bytes)\n",header,chunksize); fseek(bmp,cpos,0); fwrite(&chunksize,4,1,bmp); fseek(bmp,chunksize,1); sprintf(header,"%s","FNT0"); chunksize = 0; fwrite(&header[0],1,4,bmp); //"FNT0" (sprite data) cpos = ftell(bmp); fwrite(&chunksize,4,1,bmp); chunksize += 2*fwrite(&fontbase.font_count,2,1,bmp); //Font count //texversion = strlen(setname_spr); //chunksize += fwrite(&texversion,1,1,bmp); //TILEID: 0 //chunksize += fwrite(&setname_spr[0],1,texversion,bmp); printf("\t\tWriting fonts\n"); for (int i=0;i<fontbase.font_count;i++) { char fontname[256]; sprintf(&fontname[0],"%s_%d",setname_font,i); unsigned char namelen = strlen(&fontname[0]); unsigned short numchars = fontbase.base[i] + '!'; chunksize += fwrite(&namelen,1,1,bmp); chunksize += fwrite(&fontname[0],1,namelen,bmp); chunksize += 2*fwrite(&numchars,2,1,bmp); for (int k = 0; k < numchars; k++) { char charname[256]; if ((k >= '!') && (k <= numchars)) { sprintf(charname,"%s_%d",setname_spr,k-'!'+fontbase.sprbase[i]); namelen = strlen(charname); } else { namelen = 0; } chunksize += fwrite(&namelen,1,1,bmp); chunksize += fwrite(&charname[0],1,namelen,bmp); } } printf(" chunk %s (%d bytes)\n",header,chunksize); fseek(bmp,cpos,0); fwrite(&chunksize,4,1,bmp); fseek(bmp,chunksize,1); } fclose(bmp); /* ZTEX Texture file header SPR0 GTA2-exported sprites (2048x2048 atlas) SPR1 GTA2-exported sprites (1024x1024 atlas) SPR2 GTA2-exported sprites (256x256 atlas) SPR3 OpenGTA2 sprites (variable atlas size) TILE GTA2-exported tiles (2048x2048 atlas by 64x64 tiles) TIL1 GTA2-exported tiles (1024x1024 atlas) TIL2 GTA2-exported tiles (256x256 atlas) TIL3 OpenGTA2 tiles (variable tile size, variable atlas size) FNT0 GTA2-exported fonts FNT1 OpenGTA2 fonts (sprite based) FNT2 OpenGTA2 fonts (with font graphics) PACK Packed information (unpacked into different chunk) */ printf("\nDone!\n"); fclose(sty); }
int main(){ fp = fopen("11f_gs01.bin", "r+"); save_tile(1, 3, BLANK_CHAR); save_tile(0, 0, PIXO_TAIL_E); save_tile(1, 0, PIXO_TAIL2_E); save_tile(2, 0, PIXO_BODY_E); save_tile(3, 0, PIXO_CLOSED_HEAD_E); save_tile(4, 0, PIXO_CLOSED_MOUTH_E); save_tile(5, 0, PIXO_CLOSED_LIPS_E); save_tile(2, 1, PIXO_OPEN_HEAD_E); save_tile(3, 1, PIXO_OPEN_MOUTH_E); save_tile(4, 1, PIXO_OPEN_LIPS_E); save_tile(3, 2, PIXO_OPEN_MOUTH2_E); save_tile(4, 2, PIXO_OPEN_LIPS2_E); save_tile(4, 3, PIXO_TAIL_S); save_tile(4, 4, PIXO_TAIL2_S); save_tile(4, 5, PIXO_BODY_S); save_tile(4, 6, PIXO_CLOSED_HEAD_S); save_tile(4, 7, PIXO_CLOSED_MOUTH_S); save_tile(4, 8, PIXO_CLOSED_LIPS_S); save_tile(3, 5, PIXO_OPEN_HEAD_S); save_tile(3, 6, PIXO_OPEN_MOUTH_S); save_tile(3, 7, PIXO_OPEN_LIPS_S); save_tile(2, 6, PIXO_OPEN_MOUTH2_S); save_tile(2, 7, PIXO_OPEN_LIPS2_S); save_tile(5, 7, PIXO_TAIL_N); save_tile(5, 6, PIXO_TAIL2_N); save_tile(5, 5, PIXO_BODY_N); save_tile(5, 4, PIXO_CLOSED_HEAD_N); save_tile(5, 3, PIXO_CLOSED_MOUTH_N); save_tile(5, 2, PIXO_CLOSED_LIPS_N); save_tile(6, 5, PIXO_OPEN_HEAD_N); save_tile(6, 4, PIXO_OPEN_MOUTH_N); save_tile(6, 3, PIXO_OPEN_LIPS_N); save_tile(7, 4, PIXO_OPEN_MOUTH2_N); save_tile(7, 3, PIXO_OPEN_LIPS2_N); save_tile(11, 2, PIXO_TAIL_W); save_tile(10, 2, PIXO_TAIL2_W); save_tile(9, 2, PIXO_BODY_W); save_tile(8, 2, PIXO_CLOSED_HEAD_W); save_tile(7, 2, PIXO_CLOSED_MOUTH_W); save_tile(6, 2, PIXO_CLOSED_LIPS_W); save_tile(9, 1, PIXO_OPEN_HEAD_W); save_tile(8, 1, PIXO_OPEN_MOUTH_W); save_tile(7, 1, PIXO_OPEN_LIPS_W); save_tile(8, 0, PIXO_OPEN_MOUTH2_W); save_tile(7, 0, PIXO_OPEN_LIPS2_W); save_tile(2, 2, PIXO_BODY_E_THEN_S); save_tile(2, 4, PIXO_BODY_S_THEN_W); save_tile(0, 4, PIXO_BODY_W_THEN_N); save_tile(0, 1, PIXO_BODY_N_THEN_E); save_tile(8, 3, CORNER_TOP_LEFT); save_tile(11, 3, CORNER_TOP_RIGHT); save_tile(8, 6, CORNER_BOTTOM_LEFT); save_tile(11, 6, CORNER_BOTTOM_RIGHT); save_tile(9, 3, TOP_BORDER__LEFT); save_tile(10, 3, TOP_BORDER__RIGHT); save_tile(9, 6, BOTTOM_BORDER__LEFT); save_tile(10, 6, BOTTOM_BORDER__RIGHT); save_tile(8, 4, LEFT_BORDER__TOP); save_tile(8, 5, LEFT_BORDER__BOTTOM); save_tile(11, 4, RIGHT_BORDER__TOP); save_tile(11, 5, RIGHT_BORDER__BOTTOM); fclose(fp); return 0; }