/* * xrick/resources.c * * Copyright (C) 2008-2014 Pierluigi Vicinanza. All rights reserved. * * The use and distribution terms for this software are contained in the file * named README, which can be found in the root of this distribution. By * using this software in any fashion, you are agreeing to be bound by the * terms of this license. * * You must not remove this notice, or any other, from this software. */ #include "xrick/resources.h" #include "xrick/draw.h" #include "xrick/ents.h" #include "xrick/maps.h" #include "xrick/util.h" #include "xrick/data/sprites.h" #include "xrick/data/tiles.h" #include "xrick/data/pics.h" #include "xrick/system/basic_funcs.h" #include "xrick/system/miniz_config.h" #include "xrick/3rd_party/miniz/miniz.c" /* * prototypes */ static bool readFile(const unsigned id); static bool checkCrc32(const unsigned id); static bool readHeader(file_t fp, const unsigned id); static bool loadString(file_t fp, char ** str, const char terminator); static void unloadString(char ** buffer); static bool loadResourceFilelist(file_t fp); static void unloadResourceFilelist(void); static bool loadResourceEntdata(file_t fp); static void unloadResourceEntdata(void); static bool loadRawData(file_t fp, void ** buffer, const size_t size, size_t * count); static void unloadRawData(void ** buffer, size_t * count); static bool loadResourceMaps(file_t fp); static void unloadResourceMaps(void); static bool loadResourceSubmaps(file_t fp); static void unloadResourceSubmaps(void); static bool loadResourceImapsteps(file_t fp); static void unloadResourceImapsteps(void); static bool loadResourceImaptext(file_t fp); static void unloadResourceImaptext(void); static bool loadResourceHighScores(file_t fp); static void unloadResourceHighScores(void); static bool loadResourceSpritesData(file_t fp); static void unloadResourceSpritesData(void); static bool loadResourceTilesData(file_t fp); static void unloadResourceTilesData(void); static bool loadImage(file_t fp, img_t ** image); static void unloadImage(img_t ** image); #ifdef GFXST static bool loadPicture(file_t fp, pic_t ** picture); static void unloadPicture(pic_t ** picture); #endif /* GFXST */ #ifdef ENABLE_SOUND static bool fromResourceIdToSound(const unsigned id, sound_t *** sound); static bool loadSound(const unsigned id); static void unloadSound(const unsigned id); #endif /* ENABLE_SOUND */ /* * local vars */ static char * resourceFiles[Resource_MAX_COUNT] = { BOOTSTRAP_RESOURCE_NAME, /* the rest initialised to NULL by default */ }; /* * load 16b length + not-terminated string */ static bool loadString(file_t fp, char ** buffer, const char terminator) { size_t length; U16 u16Temp; char * bufferTemp; if (sysfile_read(fp, &u16Temp, sizeof(u16Temp), 1) != 1) { return false; } length = letoh16(u16Temp); bufferTemp = sysmem_push(length + 1); *buffer = bufferTemp; if (!bufferTemp) { return false; } if (length) { if (sysfile_read(fp, bufferTemp, length, 1) != 1) { return false; } } bufferTemp[length] = terminator; return true; } /* * */ static void unloadString(char ** buffer) { sysmem_pop(*buffer); *buffer = NULL; } /* * */ static bool loadResourceFilelist(file_t fp) { unsigned id; for (id = Resource_PALETTE; id < Resource_MAX_COUNT; ++id) { if (!loadString(fp, &(resourceFiles[id]), 0x00)) { return false; } } return true; } /* * */ static void unloadResourceFilelist() { unsigned id; for (id = Resource_MAX_COUNT - 1; id >= Resource_PALETTE; --id) { unloadString(&(resourceFiles[id])); } } /* * */ static bool loadResourceEntdata(file_t fp) { size_t i; U16 u16Temp; resource_entdata_t dataTemp; if (sysfile_read(fp, &u16Temp, sizeof(u16Temp), 1) != 1) { return false; } ent_nbr_entdata = letoh16(u16Temp); ent_entdata = sysmem_push(ent_nbr_entdata * sizeof(*ent_entdata)); if (!ent_entdata) { return false; } for (i = 0; i < ent_nbr_entdata; ++i) { if (sysfile_read(fp, &dataTemp, sizeof(dataTemp), 1) != 1) { return false; } ent_entdata[i].w = dataTemp.w; ent_entdata[i].h = dataTemp.h; memcpy(&u16Temp, dataTemp.spr, sizeof(U16)); ent_entdata[i].spr = letoh16(u16Temp); memcpy(&u16Temp, dataTemp.sni, sizeof(U16)); ent_entdata[i].sni = letoh16(u16Temp); ent_entdata[i].trig_w = dataTemp.trig_w; ent_entdata[i].trig_h = dataTemp.trig_h; ent_entdata[i].snd = dataTemp.snd; } return true; } /* * */ static void unloadResourceEntdata() { sysmem_pop(ent_entdata); ent_entdata = NULL; ent_nbr_entdata = 0; } /* * */ static bool loadRawData(file_t fp, void ** buffer, const size_t size, size_t * count) { U16 u16Temp; if (sysfile_read(fp, &u16Temp, sizeof(u16Temp), 1) != 1) { return false; } *count = letoh16(u16Temp); *buffer = sysmem_push((*count) * size); if (!(*buffer)) { return false; } if (sysfile_read(fp, *buffer, size, *count) != (int)(*count)) { return false; } return true; } /* * */ static void unloadRawData(void ** buffer, size_t * count) { sysmem_pop(*buffer); *buffer = NULL; *count = 0; } /* * */ static bool loadResourceMaps(file_t fp) { size_t i; U16 u16Temp; resource_map_t dataTemp; if (sysfile_read(fp, &u16Temp, sizeof(u16Temp), 1) != 1) { return false; } map_nbr_maps = letoh16(u16Temp); map_maps = sysmem_push(map_nbr_maps * sizeof(*map_maps)); if (!map_maps) { return false; } for (i = 0; i < map_nbr_maps; ++i) { #ifdef ENABLE_SOUND sound_t **soundTemp; #endif if (sysfile_read(fp, &dataTemp, sizeof(dataTemp), 1) != 1) { return false; } memcpy(&u16Temp, dataTemp.x, sizeof(U16)); map_maps[i].x = letoh16(u16Temp); memcpy(&u16Temp, dataTemp.y, sizeof(U16)); map_maps[i].y = letoh16(u16Temp); memcpy(&u16Temp, dataTemp.row, sizeof(U16)); map_maps[i].row = letoh16(u16Temp); memcpy(&u16Temp, dataTemp.submap, sizeof(U16)); map_maps[i].submap = letoh16(u16Temp); #ifdef ENABLE_SOUND memcpy(&u16Temp, dataTemp.tuneId, sizeof(U16)); if (!fromResourceIdToSound(letoh16(u16Temp), &soundTemp)) { return false; } map_maps[i].tune = *soundTemp; #endif /* ENABLE_SOUND */ } return true; } /* * */ static void unloadResourceMaps() { sysmem_pop(map_maps); map_maps = NULL; map_nbr_maps = 0; } /* * */ static bool loadResourceSubmaps(file_t fp) { size_t i; U16 u16Temp; resource_submap_t dataTemp; if (sysfile_read(fp, &u16Temp, sizeof(u16Temp), 1) != 1) { return false; } map_nbr_submaps = letoh16(u16Temp); map_submaps = sysmem_push(map_nbr_submaps * sizeof(*map_submaps)); if (!map_submaps) { return false; } for (i = 0; i < map_nbr_submaps; ++i) { if (sysfile_read(fp, &dataTemp, sizeof(dataTemp), 1) != 1) { return false; } memcpy(&u16Temp, dataTemp.page, sizeof(U16)); map_submaps[i].page = letoh16(u16Temp); memcpy(&u16Temp, dataTemp.bnum, sizeof(U16)); map_submaps[i].bnum = letoh16(u16Temp); memcpy(&u16Temp, dataTemp.connect, sizeof(U16)); map_submaps[i].connect = letoh16(u16Temp); memcpy(&u16Temp, dataTemp.mark, sizeof(U16)); map_submaps[i].mark = letoh16(u16Temp); } return true; } /* * */ static void unloadResourceSubmaps() { sysmem_pop(map_submaps); map_submaps = NULL; map_nbr_submaps = 0; } /* * */ static bool loadResourceImapsteps(file_t fp) { size_t i; U16 u16Temp; resource_imapsteps_t dataTemp; if (sysfile_read(fp, &u16Temp, sizeof(u16Temp), 1) != 1) { return false; } screen_nbr_imapstesps = letoh16(u16Temp); screen_imapsteps = sysmem_push(screen_nbr_imapstesps * sizeof(*screen_imapsteps)); if (!screen_imapsteps) { return false; } for (i = 0; i < screen_nbr_imapstesps; ++i) { if (sysfile_read(fp, &dataTemp, sizeof(dataTemp), 1) != 1) { return false; } memcpy(&u16Temp, dataTemp.count, sizeof(U16)); screen_imapsteps[i].count = letoh16(u16Temp); memcpy(&u16Temp, dataTemp.dx, sizeof(U16)); screen_imapsteps[i].dx = letoh16(u16Temp); memcpy(&u16Temp, dataTemp.dy, sizeof(U16)); screen_imapsteps[i].dy = letoh16(u16Temp); memcpy(&u16Temp, dataTemp.base, sizeof(U16)); screen_imapsteps[i].base = letoh16(u16Temp); } return true; } /* * */ static void unloadResourceImapsteps() { sysmem_pop(screen_imapsteps); screen_imapsteps = NULL; screen_nbr_imapstesps = 0; } /* * */ static bool loadResourceImaptext(file_t fp) { size_t i; U16 u16Temp; if (sysfile_read(fp, &u16Temp, sizeof(u16Temp), 1) != 1) { return false; } screen_nbr_imaptext = letoh16(u16Temp); screen_imaptext = sysmem_push(screen_nbr_imaptext * sizeof(*screen_imaptext)); if (!screen_imapsteps) { return false; } for (i = 0; i < screen_nbr_imaptext; ++i) { if (!loadString(fp, (char **)(&(screen_imaptext[i])), 0xFE)) { return false; } } return true; } /* * */ static void unloadResourceImaptext() { int i; for (i = screen_nbr_imaptext - 1; i >= 0; --i) { unloadString((char **)(&(screen_imaptext[i]))); } sysmem_pop(screen_imaptext); screen_imaptext = NULL; screen_nbr_imaptext = 0; } /* * */ static bool loadResourceHighScores(file_t fp) { size_t i; U16 u16Temp; U32 u32Temp; resource_hiscore_t dataTemp; if (sysfile_read(fp, &u16Temp, sizeof(u16Temp), 1) != 1) { return false; } screen_nbr_hiscores = letoh16(u16Temp); screen_highScores = sysmem_push(screen_nbr_hiscores * sizeof(*screen_highScores)); if (!screen_highScores) { return false; } for (i = 0; i < screen_nbr_hiscores; ++i) { if (sysfile_read(fp, &dataTemp, sizeof(dataTemp), 1) != 1) { return false; } memcpy(&u32Temp, dataTemp.score, sizeof(U32)); screen_highScores[i].score = letoh32(u32Temp); memcpy(screen_highScores[i].name, dataTemp.name, HISCORE_NAME_SIZE); } return true; } /* * */ static void unloadResourceHighScores() { sysmem_pop(screen_highScores); screen_highScores = NULL; screen_nbr_hiscores = 0; } /* * */ static bool loadResourceSpritesData(file_t fp) { size_t i, j; U16 u16Temp; if (sysfile_read(fp, &u16Temp, sizeof(u16Temp), 1) != 1) { return false; } sprites_nbr_sprites = letoh16(u16Temp); sprites_data = sysmem_push(sprites_nbr_sprites * sizeof(*sprites_data)); if (!sprites_data) { return false; } #ifdef GFXST for (i = 0; i < sprites_nbr_sprites; ++i) { for (j = 0; j < SPRITES_NBR_DATA; ++j) { U32 u32Temp; if (sysfile_read(fp, &u32Temp, sizeof(u32Temp), 1) != 1) { return false; } sprites_data[i][j] = letoh32(u32Temp); } } #endif /* GFXST */ #ifdef GFXPC for (i = 0; i < sprites_nbr_sprites; ++i) { for (j = 0; j < SPRITES_NBR_COLS; ++j) { size_t k; for (k = 0; k < SPRITES_NBR_ROWS; ++k) { resource_spriteX_t dataTemp; if (sysfile_read(fp, &dataTemp, sizeof(dataTemp), 1) != 1) { return false; } memcpy(&u16Temp, dataTemp.mask, sizeof(U16)); sprites_data[i][j][k].mask = letoh16(u16Temp); memcpy(&u16Temp, dataTemp.pict, sizeof(U16)); sprites_data[i][j][k].pict = letoh16(u16Temp); } } } #endif /* GFXPC */ return true; } /* * */ static void unloadResourceSpritesData() { sysmem_pop(sprites_data); sprites_data = NULL; sprites_nbr_sprites = 0; } /* * */ static bool loadResourceTilesData(file_t fp) { size_t i, j, k; U16 u16Temp; if (sysfile_read(fp, &u16Temp, sizeof(u16Temp), 1) != 1) { return false; } tiles_nbr_banks = letoh16(u16Temp); tiles_data = sysmem_push(tiles_nbr_banks * TILES_NBR_TILES * sizeof(*tiles_data)); if (!tiles_data) { return false; } for (i = 0; i < tiles_nbr_banks ; ++i) { for (j = 0; j < TILES_NBR_TILES; ++j) { for (k = 0; k < TILES_NBR_LINES ; ++k) { #ifdef GFXPC if (sysfile_read(fp, &u16Temp, sizeof(u16Temp), 1) != 1) { return false; } tiles_data[i * TILES_NBR_TILES + j][k] = letoh16(u16Temp); #endif /* GFXPC */ #ifdef GFXST U32 u32Temp; if (sysfile_read(fp, &u32Temp, sizeof(u32Temp), 1) != 1) { return false; } tiles_data[i * TILES_NBR_TILES + j][k] = letoh32(u32Temp); #endif /* GFXST */ } } } return true; } /* * */ static void unloadResourceTilesData() { sysmem_pop(tiles_data); tiles_data = NULL; tiles_nbr_banks = 0; } /* * */ static bool loadImage(file_t fp, img_t ** image) { U16 u16Temp; size_t pixelCount, colorCount; resource_pic_t dataTemp; img_t * imgTemp; void * vp; bool success; imgTemp = sysmem_push(sizeof(*imgTemp)); *image = imgTemp; if (!imgTemp) { return false; } if (sysfile_read(fp, &dataTemp, sizeof(dataTemp), 1) != 1) { return false; } memcpy(&u16Temp, dataTemp.width, sizeof(U16)); imgTemp->width = letoh16(u16Temp); memcpy(&u16Temp, dataTemp.height, sizeof(U16)); imgTemp->height = letoh16(u16Temp); memcpy(&u16Temp, dataTemp.xPos, sizeof(U16)); imgTemp->xPos = letoh16(u16Temp); memcpy(&u16Temp, dataTemp.yPos, sizeof(U16)); imgTemp->yPos = letoh16(u16Temp); vp = imgTemp->colors; success = loadRawData(fp, &vp, sizeof(*imgTemp->colors), &colorCount); imgTemp->ncolors = colorCount; imgTemp->colors = vp; if (!success) { return false; } pixelCount = (imgTemp->width * imgTemp->height); /*we use 8b per pixel*/ imgTemp->pixels = sysmem_push(pixelCount * sizeof(U8)); if (!imgTemp->pixels) { return false; } if (sysfile_read(fp, imgTemp->pixels, sizeof(U8), pixelCount) != (int)pixelCount) { return false; } return true; } /* * */ static void unloadImage(img_t ** image) { if (*image) { sysmem_pop((*image)->pixels); sysmem_pop((*image)->colors); } sysmem_pop(*image); *image = NULL; } /* * */ #ifdef GFXST static bool loadPicture(file_t fp, pic_t ** picture) { U16 u16Temp; size_t i, pixelWords32b; resource_pic_t dataTemp; pic_t * picTemp; picTemp = sysmem_push(sizeof(*picTemp)); *picture = picTemp; if (!picTemp) { return false; } if (sysfile_read(fp, &dataTemp, sizeof(dataTemp), 1) != 1) { return false; } memcpy(&u16Temp, dataTemp.width, sizeof(U16)); picTemp->width = letoh16(u16Temp); memcpy(&u16Temp, dataTemp.height, sizeof(U16)); picTemp->height = letoh16(u16Temp); memcpy(&u16Temp, dataTemp.xPos, sizeof(U16)); picTemp->xPos = letoh16(u16Temp); memcpy(&u16Temp, dataTemp.yPos, sizeof(U16)); picTemp->yPos = letoh16(u16Temp); pixelWords32b = (picTemp->width * picTemp->height) / 8; /*we use 4b per pixel*/ picTemp->pixels = sysmem_push(pixelWords32b * sizeof(U32)); if (!picTemp->pixels) { return false; } for (i = 0; i < pixelWords32b; ++i) { U32 u32Temp; if (sysfile_read(fp, &u32Temp, sizeof(u32Temp), 1) != 1) { return false; } picTemp->pixels[i] = letoh32(u32Temp); } return true; } /* * */ static void unloadPicture(pic_t ** picture) { if (*picture) { sysmem_pop((*picture)->pixels); } sysmem_pop(*picture); *picture = NULL; } #endif /* GFXST */ #ifdef ENABLE_SOUND /* * */ static bool fromResourceIdToSound(const unsigned id, sound_t *** sound) { switch (id) { case Resource_SOUNDBOMBSHHT: *sound = &soundBombshht; return true; case Resource_SOUNDBONUS: *sound = &soundBonus; return true; case Resource_SOUNDBOX: *sound = &soundBox; return true; case Resource_SOUNDBULLET: *sound = &soundBullet; return true; case Resource_SOUNDCRAWL: *sound = &soundCrawl; return true; case Resource_SOUNDDIE: *sound = &soundDie; return true; case Resource_SOUNDENTITY0: *sound = &(soundEntity[0]); return true; case Resource_SOUNDENTITY1: *sound = &(soundEntity[1]); return true; case Resource_SOUNDENTITY2: *sound = &(soundEntity[2]); return true; case Resource_SOUNDENTITY3: *sound = &(soundEntity[3]); return true; case Resource_SOUNDENTITY4: *sound = &(soundEntity[4]); return true; case Resource_SOUNDENTITY5: *sound = &(soundEntity[5]); return true; case Resource_SOUNDENTITY6: *sound = &(soundEntity[6]); return true; case Resource_SOUNDENTITY7: *sound = &(soundEntity[7]); return true; case Resource_SOUNDENTITY8: *sound = &(soundEntity[8]); return true; case Resource_SOUNDEXPLODE: *sound = &soundExplode; return true; case Resource_SOUNDGAMEOVER: *sound = &soundGameover; return true; case Resource_SOUNDJUMP: *sound = &soundJump; return true; case Resource_SOUNDPAD: *sound = &soundPad; return true; case Resource_SOUNDSBONUS1: *sound = &soundSbonus1; return true; case Resource_SOUNDSBONUS2: *sound = &soundSbonus2; return true; case Resource_SOUNDSTICK: *sound = &soundStick; return true; case Resource_SOUNDTUNE0: *sound = &soundTune0; return true; case Resource_SOUNDTUNE1: *sound = &soundTune1; return true; case Resource_SOUNDTUNE2: *sound = &soundTune2; return true; case Resource_SOUNDTUNE3: *sound = &soundTune3; return true; case Resource_SOUNDTUNE4: *sound = &soundTune4; return true; case Resource_SOUNDTUNE5: *sound = &soundTune5; return true; case Resource_SOUNDWALK: *sound = &soundWalk; return true; default: { sys_error("(resources) no associated sound found for ID %d", id); return false; } } } /* * */ static bool loadSound(const unsigned id) { sound_t ** sound; file_t fp; wave_header_t header; U16 u16Temp; U32 u32Temp; int bytesRead; bool isHeaderValid; if (!fromResourceIdToSound(id, &sound)) { return false; } *sound = sysmem_push(sizeof(**sound)); if (!*sound) { return false; } (*sound)->buf = NULL; (*sound)->dispose = true; /* sounds are "fire and forget" by default */ (*sound)->name = u_strdup(resourceFiles[id]); if (!(*sound)->name) { return false; } fp = sysfile_open(resourceFiles[id]); if (!fp) { sys_error("(resources) unable to open \"%s\"", resourceFiles[id]); return false; } bytesRead = sysfile_read(fp, &header, sizeof(header), 1); sysfile_close(fp); if (bytesRead != 1) { sys_error("(resources) unable to read WAVE header from \"%s\"", resourceFiles[id]); return false; } isHeaderValid = false; for (;;) { if (memcmp(header.riffChunkId, "RIFF", 4) || memcmp(header.riffType, "WAVE", 4) || memcmp(header.formatChunkId, "fmt ", 4) || memcmp(header.dataChunkId, "data", 4)) { break; } memcpy(&u16Temp, header.audioFormat, sizeof(u16Temp)); if (letoh16(u16Temp) != Wave_AUDIO_FORMAT) { break; } memcpy(&u16Temp, header.channelCount, sizeof(u16Temp)); if (letoh16(u16Temp) != Wave_CHANNEL_COUNT) { break; } memcpy(&u32Temp, header.sampleRate, sizeof(u32Temp)); if (letoh32(u32Temp) != Wave_SAMPLE_RATE) { isHeaderValid = false; break; } memcpy(&u16Temp, header.bitsPerSample, sizeof(u16Temp)); if (letoh16(u16Temp) != Wave_BITS_PER_SAMPLE) { isHeaderValid = false; break; } memcpy(&u32Temp, header.dataChunkSize, sizeof(u32Temp)); (*sound)->len = letoh32(u32Temp); isHeaderValid = true; break; } if (!isHeaderValid) { sys_error("(resources) incompatible WAVE header for \"%s\"", resourceFiles[id]); return false; } return true; } /* * */ static void unloadSound(const unsigned id) { sound_t ** sound; if (!fromResourceIdToSound(id, &sound)) { return; } if (!*sound) { return; } sysmem_pop((*sound)->name); sysmem_pop(*sound); *sound = NULL; } #endif /* ENABLE_SOUND */ /* * */ static bool readHeader(file_t fp, const unsigned id) { resource_header_t header; U16 u16Temp; if (sysfile_read(fp, &header, sizeof(header), 1) != 1) { sys_error("(resources) unable to read header from \"%s\"", resourceFiles[id]); return false; } if (memcmp(header.magic, resource_magic, sizeof(header.magic)) != 0) { sys_error("(resources) wrong header for \"%s\"", resourceFiles[id]); return false; } memcpy(&u16Temp, header.version, sizeof(u16Temp)); u16Temp = htole16(u16Temp); if (u16Temp != DATA_VERSION) { sys_error("(resources) incompatible version for \"%s\"", resourceFiles[id]); return false; } memcpy(&u16Temp, header.resourceId, sizeof(u16Temp)); u16Temp = htole16(u16Temp); if (u16Temp != id) { sys_error("(resources) mismatching ID for \"%s\"", resourceFiles[id]); return false; } return true; } /* * */ static bool checkCrc32(const unsigned id) { int bytesRead; U8 tempBuffer[1024]; U32 expectedCrc32, calculatedCrc32 = MZ_CRC32_INIT; file_t fp = sysfile_open(resourceFiles[id]); if (fp == NULL) { sys_error("(resources) unable to open \"%s\"", resourceFiles[id]); return false; } bytesRead = sysfile_read(fp, tempBuffer, sizeof(U32), 1); /* prepare beginning of buffer for the following loop */ if (bytesRead != 1) { sys_error("(resources) not enough data for \"%s\"", resourceFiles[id]); sysfile_close(fp); return false; } do { bytesRead = sysfile_read(fp, tempBuffer + sizeof(U32), sizeof(U8), sizeof(tempBuffer) - sizeof(U32)); calculatedCrc32 = mz_crc32(calculatedCrc32, tempBuffer, bytesRead); memcpy(tempBuffer, tempBuffer + bytesRead, sizeof(U32)); } while (bytesRead == sizeof(tempBuffer) - sizeof(U32)); sysfile_close(fp); memcpy(&expectedCrc32, tempBuffer, sizeof(U32)); expectedCrc32 = letoh32(expectedCrc32); if (expectedCrc32 != calculatedCrc32) { sys_error("(resources) crc check failed for \"%s\"", resourceFiles[id]); return false; } return true; } /* * */ static bool readFile(const unsigned id) { bool success; file_t fp; void * vp; switch (id) { #ifndef GFXST case Resource_PICHAF: /* fallthrough */ case Resource_PICCONGRATS: /* fallthrough */ case Resource_PICSPLASH: return true; #endif /* ndef GFXST */ #ifndef GFXPC case Resource_IMAINHOFT: /* fallthrough */ case Resource_IMAINRDT: /* fallthrough */ case Resource_IMAINCDC: /* fallthrough */ case Resource_SCREENCONGRATS: return true; #endif /* ndef GFXPC */ default: break; } if (resourceFiles[id] == NULL) { sys_error("(resources) resource ID %d not available", id); return false; } if (!checkCrc32(id)) { return false; } fp = sysfile_open(resourceFiles[id]); if (fp == NULL) { if (id == Resource_FILELIST) sys_error("Please install resource files!"); else sys_error("(resources) unable to open \"%s\"", resourceFiles[id]); return false; } success = readHeader(fp, id); if (success) { switch (id) { case Resource_FILELIST: success = loadResourceFilelist(fp); break; case Resource_PALETTE: { vp = game_colors; success = loadRawData(fp, &vp, sizeof(*game_colors), &game_color_count); game_colors = vp; break; } case Resource_ENTDATA: success = loadResourceEntdata(fp); break; case Resource_SPRSEQ: { vp = ent_sprseq; success = loadRawData(fp, &vp, sizeof(*ent_sprseq), &ent_nbr_sprseq); ent_sprseq = vp; break; } case Resource_MVSTEP: { vp = ent_mvstep; success = loadRawData(fp, &vp, sizeof(*ent_mvstep), &ent_nbr_mvstep); ent_mvstep = vp; break; } case Resource_MAPS: success = loadResourceMaps(fp); break; case Resource_SUBMAPS: success = loadResourceSubmaps(fp); break; case Resource_CONNECT: { vp = map_connect; success = loadRawData(fp, &vp, sizeof(*map_connect), &map_nbr_connect); map_connect = vp; break; } case Resource_BNUMS: { vp = map_bnums; success = loadRawData(fp, &vp, sizeof(*map_bnums), &map_nbr_bnums); map_bnums = vp; break; } case Resource_BLOCKS: { vp = map_blocks; success = loadRawData(fp, &vp, sizeof(*map_blocks), &map_nbr_blocks); map_blocks = vp; break; } case Resource_MARKS: { vp = map_marks; success = loadRawData(fp, &vp, sizeof(*map_marks), &map_nbr_marks); map_marks = vp; break; } case Resource_EFLGC: { vp = map_eflg_c; success = loadRawData(fp, &vp, sizeof(*map_eflg_c), &map_nbr_eflgc); map_eflg_c = vp; break; } case Resource_IMAPSL: { vp = screen_imapsl; success = loadRawData(fp, &vp, sizeof(*screen_imapsl), &screen_nbr_imapsl); screen_imapsl = vp; break; } case Resource_IMAPSTEPS: success = loadResourceImapsteps(fp); break; case Resource_IMAPSOFS: { vp = screen_imapsofs; success = loadRawData(fp, &vp, sizeof(*screen_imapsofs), &screen_nbr_imapsofs); screen_imapsofs = vp; break; } case Resource_IMAPTEXT: success = loadResourceImaptext(fp); break; case Resource_GAMEOVERTXT: success = loadString(fp, (char **)(&screen_gameovertxt), 0xFE); break; case Resource_PAUSEDTXT: success = loadString(fp, (char **)(&screen_pausedtxt), 0xFE); break; case Resource_SPRITESDATA: success = loadResourceSpritesData(fp); break; case Resource_TILESDATA: success = loadResourceTilesData(fp); break; case Resource_HIGHSCORES: success = loadResourceHighScores(fp); break; case Resource_IMGSPLASH: success = loadImage(fp, &img_splash); break; #ifdef GFXST case Resource_PICHAF: success = loadPicture(fp, &pic_haf); break; case Resource_PICCONGRATS: success = loadPicture(fp, &pic_congrats); break; case Resource_PICSPLASH: success = loadPicture(fp, &pic_splash); break; #endif /* GFXST */ #ifdef GFXPC case Resource_IMAINHOFT: success = loadString(fp, (char **)(&screen_imainhoft), 0xFE); break; case Resource_IMAINRDT: success = loadString(fp, (char **)(&screen_imainrdt), 0xFE); break; case Resource_IMAINCDC: success = loadString(fp, (char **)(&screen_imaincdc), 0xFE); break; case Resource_SCREENCONGRATS: success = loadString(fp, (char **)(&screen_congrats), 0xFE); break; #endif /* GFXPC */ default: success = false; break; } } if (!success) { sys_error("(resources) error when parsing \"%s\"", resourceFiles[id]); } sysfile_close(fp); return success; } /* * */ bool resources_load() { bool success; unsigned id; /* note: loading order is important: file list first, then sounds, then the rest */ success = readFile(Resource_FILELIST); #ifdef ENABLE_SOUND for (id = Resource_SOUNDBOMBSHHT; (id <= Resource_SOUNDWALK) && success; ++id) { success = loadSound(id); } #endif /* ENABLE_SOUND */ for (id = Resource_PALETTE; (id <= Resource_SCREENCONGRATS) && success; ++id) { success = readFile(id); } return success; } /* * */ void resources_unload() { int id; void * vp; for (id = Resource_SCREENCONGRATS; id >= Resource_PALETTE; --id) { switch (id) { case Resource_PALETTE: { vp = game_colors; unloadRawData(&vp, &game_color_count); game_colors = vp; break; } case Resource_ENTDATA: unloadResourceEntdata(); break; case Resource_SPRSEQ: { vp = ent_sprseq; unloadRawData(&vp, &ent_nbr_sprseq); ent_sprseq = vp; break; } case Resource_MVSTEP: { vp = ent_mvstep; unloadRawData(&vp, &ent_nbr_mvstep); ent_mvstep = vp; break; } case Resource_MAPS: unloadResourceMaps(); break; case Resource_SUBMAPS: unloadResourceSubmaps(); break; case Resource_CONNECT: { vp = map_connect; unloadRawData(&vp, &map_nbr_connect); map_connect = vp; break; } case Resource_BNUMS: { vp = map_bnums; unloadRawData(&vp, &map_nbr_bnums); map_bnums = vp; break; } case Resource_BLOCKS: { vp = map_blocks; unloadRawData(&vp, &map_nbr_blocks); map_blocks = vp; break; } case Resource_MARKS: { vp = map_marks; unloadRawData(&vp, &map_nbr_marks); map_marks = vp; break; } case Resource_EFLGC: { vp = map_eflg_c; unloadRawData(&vp, &map_nbr_eflgc); map_eflg_c = vp; break; } case Resource_IMAPSL: { vp = screen_imapsl; unloadRawData(&vp, &screen_nbr_imapsl); screen_imapsl = vp; break; } case Resource_IMAPSTEPS: unloadResourceImapsteps(); break; case Resource_IMAPSOFS: { vp = screen_imapsofs; unloadRawData(&vp, &screen_nbr_imapsofs); screen_imapsofs = vp; break; } case Resource_IMAPTEXT: unloadResourceImaptext(); break; case Resource_GAMEOVERTXT: unloadString((char **)(&screen_gameovertxt)); break; case Resource_PAUSEDTXT: unloadString((char **)(&screen_pausedtxt)); break; case Resource_SPRITESDATA: unloadResourceSpritesData(); break; case Resource_TILESDATA: unloadResourceTilesData(); break; case Resource_HIGHSCORES: unloadResourceHighScores(); break; case Resource_IMGSPLASH: unloadImage(&img_splash); break; #ifdef GFXST case Resource_PICHAF: unloadPicture(&pic_haf); break; case Resource_PICCONGRATS: unloadPicture(&pic_congrats); break; case Resource_PICSPLASH: unloadPicture(&pic_splash); break; #endif /* GFXST */ #ifdef GFXPC case Resource_IMAINHOFT: unloadString((char **)(&screen_imainhoft)); break; case Resource_IMAINRDT: unloadString((char **)(&screen_imainrdt)); break; case Resource_IMAINCDC: unloadString((char **)(&screen_imaincdc)); break; case Resource_SCREENCONGRATS: unloadString((char **)(&screen_congrats)); break; #endif /* GFXPC */ default: break; } } #ifdef ENABLE_SOUND for (id = Resource_SOUNDWALK; id >= Resource_SOUNDBOMBSHHT; --id) { unloadSound(id); } #endif /* ENABLE_SOUND */ unloadResourceFilelist(); } /* eof */