bool res_file_t::get_resource(uint32 type, int id, LoadedResource &rsrc) const { rsrc.Unload(); // Find resource in map type_map_t::const_iterator i = types.find(type); if (i != types.end()) { id_map_t::const_iterator j = i->second.find(id); if (j != i->second.end()) { // Found, read data size SDL_RWseek(f, j->second, SEEK_SET); uint32 size = SDL_ReadBE32(f); // Allocate memory and read data void *p = malloc(size); if (p == NULL) { return false; } SDL_RWread(f, p, 1, size); #ifdef mac rsrc.SetData(p, size); #else rsrc.p = p; rsrc.size = size; #endif // fprintf(stderr, "get_resource type %c%c%c%c, id %d -> data %p, size %d\n", type >> 24, type >> 16, type >> 8, type, id, p, size); return true; } } return false; }
void build_color_table( color_table *table, LoadedResource& clut_rsrc) { int i,n; ColorSpec *src; rgb_color *dst; CTabHandle clut = CTabHandle(clut_rsrc.GetHandle()); n=(*clut)->ctSize+1; if (n<0) { n=0; } else if (n>256) { n=256; } table->color_count=n; src=(*clut)->ctTable; dst=table->colors; for (i=0; i<n; i++) { dst->red=src->rgb.red; dst->green=src->rgb.green; dst->blue=src->rgb.blue; src++; dst++; } }
bool res_file_t::get_ind_resource(uint32 type, int index, LoadedResource &rsrc) const { rsrc.Unload(); // Find resource in map type_map_t::const_iterator i = types.find(type); if (i != types.end()) { if (index < 1 || index > int(i->second.size())) return false; id_map_t::const_iterator j = i->second.begin(); for (int k=1; k<index; k++) ++j; // Read data size SDL_RWseek(f, j->second, SEEK_SET); uint32 size = SDL_ReadBE32(f); // Allocate memory and read data void *p = malloc(size); if (p == NULL) return false; SDL_RWread(f, p, 1, size); rsrc.p = p; rsrc.size = size; // fprintf(stderr, "get_ind_resource type %c%c%c%c, index %d -> data %p, size %d\n", type >> 24, type >> 16, type >> 8, type, index, p, size); return true; } return false; }
// Loads all those in resource 128 in a map file (or some appropriate equivalent) void LoadLevelScripts(FileSpecifier& MapFile) { // Because all the files are to live in the map file's parent directory MapFile.ToDirectory(MapParentDir); // Get rid of the previous level script // ghs: unless it's the first time, in which case we would be clearing // any external level scripts, so don't static bool FirstTime = true; if (FirstTime) { FirstTime = false; } else{ LevelScripts.clear(); } // Set these to their defaults before trying to change them EndScreenIndex = 99; NumEndScreens = 1; // Lazy setup of XML parsing definitions SetupLSParseTree(); LSXML_Loader.CurrentElement = &LSRootParser; // OpenedResourceFile OFile; // if (!MapFile.Open(OFile)) return; // The script is stored at a special resource ID; // simply quit if it could not be found LoadedResource ScriptRsrc; // if (!OFile.Get('T','E','X','T',128,ScriptRsrc)) return; if (!get_text_resource_from_scenario(128,ScriptRsrc)) { return; } // Load the script LSXML_Loader.SourceName = "[Map Script]"; LSXML_Loader.ParseData((char *)ScriptRsrc.GetPointer(),ScriptRsrc.GetLength()); }
sdl_font_info *load_sdl_font(const TextSpec &spec) { sdl_font_info *info = NULL; // Look for ID/size in list of loaded fonts id_and_size_t id_and_size(spec.font, spec.size); font_list_t::const_iterator it = font_list.find(id_and_size); if (it != font_list.end()) { // already loaded info = it->second; info->ref_count++; return info; } // Load font family resource LoadedResource fond; if (!get_resource(FOUR_CHARS_TO_INT('F', 'O', 'N', 'D'), spec.font, fond)) { fprintf(stderr, "Font family resource for font ID %d not found\n", spec.font); return NULL; } SDL_RWops *p = SDL_RWFromMem(fond.GetPointer(), (int)fond.GetLength()); assert(p); // Look for font size in association table SDL_RWseek(p, 52, SEEK_SET); int num_assoc = SDL_ReadBE16(p) + 1; while (num_assoc--) { int size = SDL_ReadBE16(p); SDL_ReadBE16(p); // skip style int id = SDL_ReadBE16(p); if (size == spec.size) { // Size found, load bitmap font resource info = new sdl_font_info; if (!get_resource(FOUR_CHARS_TO_INT('N', 'F', 'N', 'T'), id, info->rsrc)) get_resource(FOUR_CHARS_TO_INT('F', 'O', 'N', 'T'), id, info->rsrc); if (info->rsrc.IsLoaded()) { // Found, switch stream to font resource SDL_RWclose(p); p = SDL_RWFromMem(info->rsrc.GetPointer(), (int)info->rsrc.GetLength()); assert(p); void *font_ptr = info->rsrc.GetPointer(true); // Read font information SDL_RWseek(p, 2, SEEK_CUR); info->first_character = static_cast<uint8>(SDL_ReadBE16(p)); info->last_character = static_cast<uint8>(SDL_ReadBE16(p)); SDL_RWseek(p, 2, SEEK_CUR); info->maximum_kerning = SDL_ReadBE16(p); SDL_RWseek(p, 2, SEEK_CUR); info->rect_width = SDL_ReadBE16(p); info->rect_height = SDL_ReadBE16(p); SDL_RWseek(p, 2, SEEK_CUR); info->ascent = SDL_ReadBE16(p); info->descent = SDL_ReadBE16(p); info->leading = SDL_ReadBE16(p); int bytes_per_row = SDL_ReadBE16(p) * 2; //printf(" first %d, last %d, max_kern %d, rect_w %d, rect_h %d, ascent %d, descent %d, leading %d, bytes_per_row %d\n", // info->first_character, info->last_character, info->maximum_kerning, // info->rect_width, info->rect_height, info->ascent, info->descent, info->leading, bytes_per_row); // Convert bitmap to pixmap (1 byte/pixel) info->bytes_per_row = bytes_per_row * 8; uint8 *src = (uint8 *)font_ptr + SDL_RWtell(p); uint8 *dst = info->pixmap = (uint8 *)malloc(info->rect_height * info->bytes_per_row); assert(dst); for (int y=0; y<info->rect_height; y++) { for (int x=0; x<bytes_per_row; x++) { uint8 b = *src++; *dst++ = (b & 0x80) ? 0xff : 0x00; *dst++ = (b & 0x40) ? 0xff : 0x00; *dst++ = (b & 0x20) ? 0xff : 0x00; *dst++ = (b & 0x10) ? 0xff : 0x00; *dst++ = (b & 0x08) ? 0xff : 0x00; *dst++ = (b & 0x04) ? 0xff : 0x00; *dst++ = (b & 0x02) ? 0xff : 0x00; *dst++ = (b & 0x01) ? 0xff : 0x00; } } SDL_RWseek(p, info->rect_height * bytes_per_row, SEEK_CUR); // Set table pointers int table_size = info->last_character - info->first_character + 3; // Tables contain 2 additional entries info->location_table = (uint16 *)((uint8 *)font_ptr + SDL_RWtell(p)); byte_swap_memory(info->location_table, _2byte, table_size); SDL_RWseek(p, table_size * 2, SEEK_CUR); info->width_table = (int8 *)font_ptr + SDL_RWtell(p); // Add font information to list of known fonts info->ref_count++; font_list[id_and_size] = info; } else { delete info; info = NULL; fprintf(stderr, "Bitmap font resource ID %d not found\n", id); } } } // Free resources SDL_RWclose(p); return info; }
// Search for level script and then run it void GeneralRunScript(int LevelIndex) { // Find the pointer to the current script CurrScriptPtr = NULL; for (vector<LevelScriptHeader>::iterator ScriptIter = LevelScripts.begin(); ScriptIter < LevelScripts.end(); ScriptIter++) { if (ScriptIter->Level == LevelIndex) { CurrScriptPtr = &(*ScriptIter); // Iterator to pointer break; } } if (!CurrScriptPtr) { return; } // Insures that this order is the last order set Music::instance()->LevelMusicRandom(CurrScriptPtr->RandomOrder); // OpenedResourceFile OFile; // FileSpecifier& MapFile = get_map_file(); // if (!MapFile.Open(OFile)) return; for (unsigned k=0; k<CurrScriptPtr->Commands.size(); k++) { LevelScriptCommand& Cmd = CurrScriptPtr->Commands[k]; // Data to parse char *Data = NULL; size_t DataLen = 0; // First, try to load a resource (only for scripts) LoadedResource ScriptRsrc; switch(Cmd.Type) { case LevelScriptCommand::MML: #ifdef HAVE_LUA case LevelScriptCommand::Lua: #endif /* HAVE_LUA */ // if (Cmd.RsrcPresent() && OFile.Get('T','E','X','T',Cmd.RsrcID,ScriptRsrc)) if (Cmd.RsrcPresent() && get_text_resource_from_scenario(Cmd.RsrcID,ScriptRsrc)) { Data = (char *)ScriptRsrc.GetPointer(); DataLen = ScriptRsrc.GetLength(); } } switch(Cmd.Type) { case LevelScriptCommand::MML: { // Skip if not loaded if (Data == NULL || DataLen <= 0) { break; } // Set to the MML root parser char ObjName[256]; sprintf(ObjName,"[Map Rsrc %hd for Level %d]",Cmd.RsrcID,LevelIndex); LSXML_Loader.SourceName = ObjName; LSXML_Loader.CurrentElement = &RootParser; LSXML_Loader.ParseData(Data,DataLen); } break; #ifdef HAVE_LUA case LevelScriptCommand::Lua: { // Skip if not loaded if (Data == NULL || DataLen <= 0) { break; } // Load and indicate whether loading was successful if (LoadLuaScript(Data, DataLen, _embedded_lua_script)) { LuaFound = true; } } break; #endif /* HAVE_LUA */ case LevelScriptCommand::Music: { FileSpecifier MusicFile; if (MusicFile.SetNameWithPath(&Cmd.FileSpec[0])) { Music::instance()->PushBackLevelMusic(MusicFile); } } break; #ifdef HAVE_OPENGL case LevelScriptCommand::LoadScreen: { if (Cmd.FileSpec.size() > 0) { if (Cmd.L || Cmd.T || Cmd.R || Cmd.B) { OGL_LoadScreen::instance()->Set(Cmd.FileSpec, Cmd.Stretch, Cmd.Scale, Cmd.L, Cmd.T, Cmd.R - Cmd.L, Cmd.B - Cmd.T); OGL_LoadScreen::instance()->Colors()[0] = Cmd.Colors[0]; OGL_LoadScreen::instance()->Colors()[1] = Cmd.Colors[1]; } else{ OGL_LoadScreen::instance()->Set(Cmd.FileSpec, Cmd.Stretch, Cmd.Scale); } } } #endif // The movie info is handled separately } } }