bool CFileSystem::FileExists( const string_t& fileName ) { IFile* file = this->OpenFile( fileName, fileMode_Read ); if ( file ) { file->Close(); SafeDelete(file); return true; } else return false; }
bool CConfigFile::Load(const char* filename, IFileSystem& fs) { m_sections.erase(m_sections.begin(), m_sections.end()); // open the file IFile* file = fs.Open(filename, IFileSystem::read); if (file == NULL) { return false; } std::string current_section = ""; bool eof = false; while (!eof) { // read a line std::string line; eof = !read_line(file, line); const char* string = line.c_str(); // parse it // eliminate whitespace skip_whitespace(string); if (string[0] == '[') { // it's a section string++; current_section = ""; while (*string != ']') { current_section += *string++; } string++; } else { // it's a key=value pair // read key std::string key; while (*string != '=' && *string) { key += *string++; } if (*string == 0) { continue; // skip lines without equals } string++; // skip the '=' std::string value; while (*string) { value += *string++; } // add the item WriteString(current_section.c_str(), key.c_str(), value.c_str()); } } file->Close(); return true; }
bool sTileset::Load(const char* filename, IFileSystem& fs) { IFile* file = fs.Open(filename, IFileSystem::read); if (file == NULL) return false; bool result = LoadFromFile(file); file->Close(); return result; }
bool sTileset::Save(const char* filename, IFileSystem& fs) const { // open the file IFile* file = fs.Open(filename, IFileSystem::write); if (file == NULL) return false; bool result = SaveToFile(file); file->Close(); return result; }
bool CConfigFile::Save(const char* filename, IFileSystem& fs) const { IFile* file = fs.Open(filename, IFileSystem::write); if (file == NULL) { return false; } // find the section without a name and write that first std::map<std::string, Section>::const_iterator i; for (i = m_sections.begin(); i != m_sections.end(); i++) { if (i->first == "") { const Section& s = i->second; std::map<std::string, std::string>::const_iterator j; for (j = s.entries.begin(); j != s.entries.end(); j++) { write_string(file, j->first); file->Write("=", 1); write_string(file, j->second); file->Write("\n", 1); } file->Write("\n", 1); } } // write the rest of the sections for (i = m_sections.begin(); i != m_sections.end(); i++) { if (i->first != "") { file->Write("[", 1); write_string(file, i->first); file->Write("]\n", 2); const Section& s = i->second; std::map<std::string, std::string>::const_iterator j; for (j = s.entries.begin(); j != s.entries.end(); j++) { write_string(file, j->first); file->Write("=", 1); write_string(file, j->second); file->Write("\n", 1); } file->Write("\n", 1); } } file->Close(); return true; }
int KGTestMapDisuseResource::FindResInPVS(const char cszResourceName[], set<string>& setResList) { //参照KG3DRepresentObjectPVS::LoadPvsFile int nRetCode = false; int nResult = false; HRESULT hrRetCode = E_FAIL; IFile* pFile = NULL; DWORD dwVersion = PVS_FILE_VERSION; char szSourcePathName[MAX_PATH] = {0}; char szResName[MAX_PATH] = {0}; long lOffset = 0; size_t objNum = 0; KG_ASSERT_EXIT(cszResourceName); KGLOG_PROCESS_ERROR(cszResourceName[0] != '\0'); nRetCode = _snprintf_s(szSourcePathName, sizeof(szSourcePathName), sizeof(szSourcePathName) - 1, "%s%s", m_szClientPath, cszResourceName); KGLOG_PROCESS_ERROR(nRetCode > 0); pFile = g_OpenFile(cszResourceName, false, false); KGLOG_PROCESS_ERROR(pFile); /* read version */ pFile->Read(&dwVersion, sizeof(dwVersion)); /* load border, the frist model of the pvs object is it's ouside border and the second model is it's inside border */ pFile->Read(szResName, sizeof(szResName)); FindResource(szResName, setResList); pFile->Read(szResName, sizeof(szResName)); FindResource(szResName, setResList); /* load inside objects, the object may be is pvs object too */ pFile->Read(&objNum, sizeof(objNum)); for (size_t i = 0; i < objNum; i++) { DWORD dwObjType = 0; pFile->Read(&dwObjType, sizeof(dwObjType)); switch (dwObjType) { case REPRESENTOBJECT_PVS : case REPRESENTOBJECT_SET : { pFile->Read(szResName, sizeof(szResName)); FindResource(szResName, setResList); } break; case REPRESENTOBJECT_DEFAULT : { /* is normal object */ DWORD dwCount = 0; DWORD dwColor = 0; DWORD dwType = 0; char szAnins[MAX_PATH] = {0}; pFile->Read(&dwCount, sizeof(dwCount)); for (DWORD i = 0; i < dwCount; i++) { pFile->Read(szResName, sizeof(szResName)); FindResource(szResName, setResList); if (dwVersion > PVS_FILE_VERSION_1) { pFile->Read(szAnins, sizeof(szAnins)); FindResource(szAnins, setResList); } TypeInfo* pInfo = NULL; IEKG3DEngineManager* pIEEngineMgr = NULL; IEKG3DModelTable* pIEModelTable = NULL; KG3DModelTable* pModelTable = NULL; pIEEngineMgr = (IEKG3DEngineManager*)m_pEngineMgr; hrRetCode = pIEEngineMgr->GetIEKG3DModelTable(&pIEModelTable); KGLOG_COM_PROCESS_ERROR(hrRetCode); pModelTable= (KG3DModelTable*)pIEModelTable; hrRetCode = pModelTable->GetTypeInfoByFileName(&pInfo, szResName); if (pInfo) dwType = pInfo->dwType; else dwType = MESHTYPE_DEFAULT; switch (dwType) { case MESHTYPE_POINTLIGHT : { pFile->Read(&dwColor, sizeof(dwColor)); } break; default : break; } } } break; default : _ASSERTE(false); break; } lOffset = sizeof(D3DXVECTOR3) + //ScalingCenter sizeof(D3DXQUATERNION) + //ScalingRotation sizeof(D3DXVECTOR3) + //Scaling sizeof(D3DXVECTOR3) + //RotationCenter sizeof(D3DXQUATERNION) + //Rotation sizeof(D3DXVECTOR3) + //Translation sizeof(AABBOX); //aabox pFile->Seek(lOffset, SEEK_CUR); lOffset = 0; } pFile->Close(); SAFE_RELEASE(pFile); nResult = true; Exit0: if (pFile) { pFile->Close(); SAFE_RELEASE(pFile); } return nResult; }
int KGTestMapDisuseResource::FindResInSTree(const char cszResourceName[], set<string>& setResList) { //参照KG3DModelSpeedTree::_LoadFromFile int nRetCode = false; int nResult = false; IFile* pFile = NULL; DWORD dwMark = 0; char szSourcePathName[MAX_PATH] = {0}; char szTreeMeshName[MAX_PATH] = {0}; char szTreeMtlName [MAX_PATH] = {0}; char szPathName[MAX_PATH] = {0}; char szDriver[MAX_PATH] = {0}; char szPath[MAX_PATH] = {0}; char szFileName[MAX_PATH] = {0}; char szExt[MAX_PATH] = {0}; KG_ASSERT_EXIT(cszResourceName); KGLOG_PROCESS_ERROR(cszResourceName[0] != '\0'); nRetCode = _snprintf_s(szSourcePathName, sizeof(szSourcePathName), sizeof(szSourcePathName) - 1, "%s%s", m_szClientPath, cszResourceName); KGLOG_PROCESS_ERROR(nRetCode > 0); pFile = g_OpenFile(szSourcePathName); KGLOG_PROCESS_ERROR(pFile); pFile->Read(&dwMark, sizeof(DWORD)); //Mesh Name pFile->Read(szTreeMeshName, sizeof(char) * MAX_PATH); nRetCode = _splitpath_s( cszResourceName, szDriver, sizeof(szDriver), szPath, sizeof(szPath), NULL, 0, NULL, 0 ); KGLOG_PROCESS_ERROR(nRetCode == 0); nRetCode = _splitpath_s( szTreeMeshName, NULL, 0, NULL, 0, szFileName, sizeof(szFileName), szExt, sizeof(szExt) ); KGLOG_PROCESS_ERROR(nRetCode == 0); nRetCode = _snprintf_s( szPathName, sizeof(szPathName), sizeof(szPathName) - 1, "%s%s", szDriver, szPath ); KGLOG_PROCESS_ERROR(nRetCode > 0); nRetCode = _snprintf_s( szTreeMeshName, sizeof(szTreeMeshName), sizeof(szTreeMeshName) - 1, "%s%s%s", szPathName, szFileName, szExt ); KGLOG_PROCESS_ERROR(nRetCode > 0); FindResource(szTreeMeshName, setResList); //Mtl Name pFile->Read(szTreeMtlName, sizeof(char) * MAX_PATH); nRetCode = _splitpath_s( szTreeMtlName, NULL, 0, NULL, 0, szFileName, sizeof(szFileName), szExt, sizeof(szExt) ); KGLOG_PROCESS_ERROR(nRetCode == 0); nRetCode = _snprintf_s( szTreeMtlName, sizeof(szTreeMtlName), sizeof(szTreeMtlName) - 1, "%s%s%s", szPathName, szFileName, szExt ); KGLOG_PROCESS_ERROR(nRetCode > 0); FindResource(szTreeMtlName, setResList); //Mtl Name nRetCode = _splitpath_s( cszResourceName, NULL, 0, NULL, 0, szFileName, sizeof(szFileName), NULL, 0 ); KGLOG_PROCESS_ERROR(nRetCode == 0); nRetCode = _snprintf_s( szTreeMtlName, sizeof(szTreeMtlName), sizeof(szTreeMtlName) - 1, "%s%s.Mtl", szPathName, szFileName ); KGLOG_PROCESS_ERROR(nRetCode > 0); FindResource(szTreeMtlName, setResList); nResult = true; Exit0: if (pFile) { pFile->Close(); SAFE_RELEASE(pFile); } return nResult; }
bool sTileset::Import_TST(const char* filename, IFileSystem& fs) { // TST file format created by Christoper B. Matthews for the RPG Toolkit Development System IFile* file = fs.Open(filename, IFileSystem::read); if (file == NULL) return false; // read header word version; word numtiles; word detail; file->Read(&version, 2); file->Read(&numtiles, 2); file->Read(&detail, 2); // check header for errors // only support details 2, 4, 6 if (version != 20 && (detail == 2 || detail == 4 || detail == 6)) { file->Close(); return false; } // allocate new tiles m_Tiles.clear(); m_Tiles.resize(numtiles); // read them from file for (int i = 0; i < m_Tiles.size(); i++) { sTile& tile = m_Tiles[i]; switch (detail) { case 2: // 16x16, 24-bit color { for (int ix = 0; ix < 16; ix++) for (int iy = 0; iy < 16; iy++) { RGB rgb; file->Read(&rgb, 3); byte alpha = 255; if (rgb.red == 0 && rgb.green == 1 && rgb.blue == 2) alpha = 0; tile.GetPixels()[iy * 16 + ix].red = rgb.red; tile.GetPixels()[iy * 16 + ix].green = rgb.green; tile.GetPixels()[iy * 16 + ix].blue = rgb.blue; tile.GetPixels()[iy * 16 + ix].alpha = alpha; } break; } case 4: // 16x16, 8-bit color case 6: // 16x16, 4-bit color // these two are effectively the same format { for (int ix = 0; ix < 16; ix++) for (int iy = 0; iy < 16; iy++) { byte b; file->Read(&b, 1); RGB rgb = dos_palette[b]; byte alpha = 255; if (b == 255) alpha = 0; tile.GetPixels()[iy * 16 + ix].red = rgb.red; tile.GetPixels()[iy * 16 + ix].green = rgb.green; tile.GetPixels()[iy * 16 + ix].blue = rgb.blue; tile.GetPixels()[iy * 16 + ix].alpha = alpha; } break; } } } file->Close(); return true; }
bool sTileset::Import_VSP(const char* filename, IFileSystem& fs) { IFile* file = fs.Open(filename, IFileSystem::read); if (file == NULL) return false; word version; RGB palette[256]; word numtiles; file->Read(&version, 2); file->Read(palette, 3 * 256); file->Read(&numtiles, 2); m_Tiles.clear(); m_Tiles.resize(numtiles); // decode the file if (version == 2) { for (int i = 0; i < numtiles; i++) { byte tile[256]; file->Read(tile, 256); for (int x = 0; x < 16; x++) for (int y = 0; y < 16; y++) { RGBA color; byte c = tile[y * 16 + x]; if (c == 0) { color.red = 0; color.green = 0; color.blue = 0; color.alpha = 0; } else { color.red = (byte)(palette[c].red * 4); color.green = (byte)(palette[c].green * 4); color.blue = (byte)(palette[c].blue * 4); color.alpha = 255; } m_Tiles[i].GetPixels()[y * 16 + x] = color; } } } else { // for that wierd thing aen never told me in the vsp code dword dw; file->Read(&dw, 4); // create a temporary buffer while setting up the decoding stuff... byte* buffer = (byte*)malloc(numtiles * 256); int len = numtiles * 256; int counter = 0; //start decoding! while (counter < len) { byte c; file->Read(&c, 1); // if the c was 255 then it's a compressed value if (c == 255) { byte run, color; file->Read(&run, 1); file->Read(&color, 1); for (int i = 0; i < run; i++) { buffer[counter] = color; counter++; } } else // it's a normal value { buffer[counter] = c; counter++; } } // now, tranfer the decoded stuff into the tiles' data structure for (int i = 0; i < numtiles; i++) for (int j = 0; j < 256; j++) { if (buffer[i * 256 + j] == 0) { m_Tiles[i].GetPixels()[j].red = 0; m_Tiles[i].GetPixels()[j].green = 0; m_Tiles[i].GetPixels()[j].blue = 0; m_Tiles[i].GetPixels()[j].alpha = 0; } else { m_Tiles[i].GetPixels()[j].red = (palette[buffer[i * 256 + j]].red) * 4; m_Tiles[i].GetPixels()[j].green = (palette[buffer[i * 256 + j]].green) * 4; m_Tiles[i].GetPixels()[j].blue = (palette[buffer[i * 256 + j]].blue) * 4; m_Tiles[i].GetPixels()[j].alpha = 255; } } } file->Close(); return true; }
bool sMap::Import_VergeMAP(const char* filename, const char* tilesetFilename, IFileSystem& fs) { m_MusicFile = ""; m_EntryScript = ""; m_ExitScript = ""; m_Layers.clear(); m_Entities.clear(); IFile* file = fs.Open(filename, IFileSystem::read); if (file == NULL) return false; // check for v1 maps (ver 4) and v2 maps (ver 5) char signature[6]; file->Read(signature, 6); file->Seek(0); bool success = false; if (signature[0] == 4) { V1MAP_HEADER header; file->Read(&header, sizeof(header)); word* layer_background = new word[header.layer_size_x * header.layer_size_y]; word* layer_foreground = new word[header.layer_size_x * header.layer_size_y]; file->Read(layer_background, header.layer_size_x * header.layer_size_y * sizeof(word)); file->Read(layer_foreground, header.layer_size_x * header.layer_size_y * sizeof(word)); sTileset tileset; if (strcmp_ci(tilesetFilename + strlen(tilesetFilename) - 4, ".vsp") == 0) success = tileset.Import_VSP(tilesetFilename, fs); else success = tileset.Load(tilesetFilename, fs); sLayer layer[2]; if (success) { // process map and see if the map has tiles that are out of range int highestTileIndex = 0; for (int j=0; j<header.layer_size_y; j++) for (int i=0; i<header.layer_size_x; i++) if (layer_background[j * header.layer_size_x + i] >= highestTileIndex) highestTileIndex = layer_background[j * header.layer_size_x + i]; else if (layer_foreground[j * header.layer_size_x + i] >= highestTileIndex) highestTileIndex = layer_foreground[j * header.layer_size_x + i]; if (highestTileIndex >= tileset.GetNumTiles()) success = false; // transfer data across into the sMap now... if (success) { layer[0].SetName("Background"); layer[1].SetName("Foreground"); layer[0].Resize(header.layer_size_x, header.layer_size_y); layer[1].Resize(header.layer_size_x, header.layer_size_y); for (int j=0; j<header.layer_size_y; j++) for (int i=0; i<header.layer_size_x; i++) { layer[0].SetTile(i,j, layer_background[j * header.layer_size_x + i]); if (layer_foreground[j * header.layer_size_x + i]) layer[1].SetTile(i,j, layer_foreground[j * header.layer_size_x + i]); else layer[1].SetTile(i,j, tileset.GetNumTiles()); } tileset.AppendTiles(1); memset(tileset.GetTile(tileset.GetNumTiles() - 1).GetPixels(), 0, 256 * sizeof(RGBA)); m_Tileset = tileset; AppendLayer(layer[0]); AppendLayer(layer[1]); SetMusicFile((char*)header.music_fname); SetStartX(header.x_start); SetStartX(header.y_start); SetStartDirection(4); // calculate the parallax mode for (int i=0; i<2; i++) { // FIXME (set parallax properly) // GetLayer(i).SetParallaxX(1, 1); // GetLayer(i).SetParallaxY(1, 1); // GetLayer(i).SetScrollingX(1, 1); // GetLayer(i).SetScrollingX(1, 1); } switch(header.parallax_mode) { case 0: SetStartLayer(0); break; case 1: SetStartLayer(1); break; case 2: // FIXME (set parallax properly) SetStartLayer(1); // GetLayer(0).SetParallaxX(header.parallax_multiplier, header.parallax_divisor); // GetLayer(0).SetParallaxY(header.parallax_multiplier, header.parallax_divisor); break; case 3: // FIXME (set parallax properly) SetStartLayer(0); // GetLayer(1).SetParallaxX(header.parallax_multiplier, header.parallax_divisor); // GetLayer(1).SetParallaxY(header.parallax_multiplier, header.parallax_divisor); break; } } } // cleanup delete[] layer_background; delete[] layer_foreground; } else if (strcmp(signature, "MAPù5") == 0) { V2MAP_HEADER header; V2MAP_LAYERINFO LayerInfo[7]; sTileset tileset; word *mapLayer[7]; int i,j,k; int highestTileIndex = 0; file->Read(&header, sizeof(header)); for (i=0; i<header.num_layers; i++) { file->Read(LayerInfo + i, sizeof(V2MAP_LAYERINFO)); //bug for v2's map: two bytes are added for no reason word w; file->Read(&w, 2); } // get info about map and uncompress it for (i=0; i<header.num_layers; i++) mapLayer[i] = new word[LayerInfo[i].size_x * LayerInfo[i].size_y]; for (i=0; i<header.num_layers; i++) { // god, this is so dumb. It's supposed to be the buffersize, but do I look like I need it? file->Read(&j, 4); for (j=0; j<LayerInfo[i].size_x*LayerInfo[i].size_y; j++) { word value; byte run; file->Read(&value, sizeof(word)); if ((value & 0xFF00) == 0xFF00) { run = (byte)value & 0x00FF; file->Read(&value, sizeof(word)); mapLayer[i][j] = value; for (k=1; k<run; k++) { j++; mapLayer[i][j] = value; } } else { mapLayer[i][j] = value; } } } if (strcmp_ci(tilesetFilename + strlen(tilesetFilename) - 4, ".vsp") == 0) success = tileset.Import_VSP(tilesetFilename); else success = tileset.Load(tilesetFilename); // transfer map array into the class if (success) { highestTileIndex = 0; // check for any tile index larger than the tilset's index for (i=0; i<header.num_layers; i++) for (j=0; j<LayerInfo[i].size_x*LayerInfo[i].size_y; j++) if (mapLayer[i][j] >= highestTileIndex) highestTileIndex = mapLayer[i][j]; if (highestTileIndex >= tileset.GetNumTiles()) success = false; if (success) { sLayer *layer; layer = new sLayer[header.num_layers]; for (i=0; i<header.num_layers; i++) { char Name[7]; memcpy(Name, "Layer A", 8); Name[6] += i; layer[i].SetName(Name); layer[i].Resize(LayerInfo[i].size_x, LayerInfo[i].size_y); } for (i=0; i<header.num_layers; i++) { for (j=0; j<LayerInfo[i].size_y; j++) for (k=0; k<LayerInfo[i].size_x; k++) layer[i].SetTile(k, j, mapLayer[i][(j * LayerInfo[i].size_x) + k]); // FIXME: set parallax properly // layer[i].SetParallaxX(LayerInfo[i].multx, LayerInfo[i].pdivx); // layer[i].SetParallaxY(LayerInfo[i].multy, LayerInfo[i].pdivy); // layer[i].SetScrollingX(1,1); // layer[i].SetScrollingY(1,1); } for (i=0; i<(int)strlen((char*)header.renderstring); i++) switch(header.renderstring[i]) { case '1': AppendLayer(layer[0]); j = 0; break; case '2': AppendLayer(layer[1]); j = 1; break; case '3': AppendLayer(layer[2]); j = 2; break; case '4': AppendLayer(layer[3]); j = 3; break; case '5': AppendLayer(layer[4]); j = 4; break; case '6': AppendLayer(layer[5]); j = 5; break; case 'E': SetStartLayer(j); break; } SetMusicFile((char*)header.music_name); SetStartX(header.x_start); SetStartY(header.y_start); m_Tileset = tileset; delete[] layer; } } for (i=0; i<header.num_layers; i++) delete mapLayer[i]; } file->Close(); return success; }
bool sMap::Save(const char* filename, IFileSystem& fs) { // do some preliminary checking... // the start layer should not have parallax m_Layers[m_StartLayer].EnableParallax(false); IFile* file = fs.Open(filename, IFileSystem::write); if (file == NULL) return false; // write the map header MAP_HEADER header; memset(&header, 0, sizeof(header)); memcpy(header.signature, ".rmp", 4); header.version = 1; header.num_layers = m_Layers.size(); header.num_entities = m_Entities.size(); header.startx = m_StartX; header.starty = m_StartY; header.startlayer = m_StartLayer; header.startdirection = m_StartDirection; header.num_strings = 9; file->Write(&header, sizeof(header)); // write the strings WriteMapString(file, ""); // OBSOLETE WriteMapString(file, m_MusicFile.c_str()); WriteMapString(file, ""); // OBSOLETE WriteMapString(file, m_EntryScript.c_str()); WriteMapString(file, m_ExitScript.c_str()); WriteMapString(file, m_EdgeScripts[0].c_str()); WriteMapString(file, m_EdgeScripts[1].c_str()); WriteMapString(file, m_EdgeScripts[2].c_str()); WriteMapString(file, m_EdgeScripts[3].c_str()); // write layers for (int i = 0; i < m_Layers.size(); i++) { const sLayer& layer = m_Layers[i]; const sObstructionMap& obstructions = layer.GetObstructionMap(); // write the header LAYER_HEADER lh; memset(&lh, 0, sizeof(lh)); lh.width = m_Layers[i].GetWidth(); lh.height = m_Layers[i].GetHeight(); lh.flags = (m_Layers[i].IsVisible() ? 0 : 1) | (m_Layers[i].HasParallax() ? 2 : 0); lh.parallax_x = m_Layers[i].GetXParallax(); lh.parallax_y = m_Layers[i].GetYParallax(); lh.scrolling_x = m_Layers[i].GetXScrolling(); lh.scrolling_y = m_Layers[i].GetYScrolling(); lh.num_segments = obstructions.GetNumSegments(); lh.reflective = (m_Layers[i].IsReflective() ? 1 : 0); file->Write(&lh, sizeof(lh)); // write the layer name WriteMapString(file, m_Layers[i].GetName()); // write the layer data for (int iy = 0; iy < m_Layers[i].GetHeight(); iy++) for (int ix = 0; ix < m_Layers[i].GetWidth(); ix++) { word w = m_Layers[i].GetTile(ix, iy); file->Write(&w, 2); } // write the obstruction map for (int i = 0; i < obstructions.GetNumSegments(); i++) { const sObstructionMap::Segment& s = obstructions.GetSegment(i); dword x1 = s.x1; dword y1 = s.y1; dword x2 = s.x2; dword y2 = s.y2; file->Write(&x1, sizeof(dword)); file->Write(&y1, sizeof(dword)); file->Write(&x2, sizeof(dword)); file->Write(&y2, sizeof(dword)); } } // end for layer // write entities for (int i = 0; i < m_Entities.size(); i++) { // write the header ENTITY_HEADER eh; memset(&eh, 0, sizeof(eh)); eh.mapx = m_Entities[i]->x; eh.mapy = m_Entities[i]->y; eh.layer = m_Entities[i]->layer; switch (m_Entities[i]->GetEntityType()) { case sEntity::PERSON: eh.type = 1; break; case sEntity::TRIGGER: eh.type = 2; break; } file->Write(&eh, sizeof(eh)); // write the entity data switch (m_Entities[i]->GetEntityType()) { case sEntity::PERSON: { sPersonEntity* person = (sPersonEntity*)m_Entities[i]; WriteMapString(file, person->name.c_str()); WriteMapString(file, person->spriteset.c_str()); WriteMapWord(file, 5); // four scripts // scripts WriteMapString(file, person->script_create.c_str()); WriteMapString(file, person->script_destroy.c_str()); WriteMapString(file, person->script_activate_touch.c_str()); WriteMapString(file, person->script_activate_talk.c_str()); WriteMapString(file, person->script_generate_commands.c_str()); // reserved for (int i = 0; i < 16; i++) { WriteMapByte(file, 0); } break; } case sEntity::TRIGGER: { sTriggerEntity* trigger = (sTriggerEntity*)m_Entities[i]; WriteMapString(file, trigger->script.c_str()); break; } } // end switch entity type } // end for entity // write the zones for (int i = 0; i < m_Zones.size(); i++) { ZONE_HEADER zh; memset(&zh, 0, sizeof(zh)); zh.x1 = m_Zones[i].x1; zh.y1 = m_Zones[i].y1; zh.x2 = m_Zones[i].x2; zh.y2 = m_Zones[i].y2; zh.layer = m_Zones[i].layer; zh.reactivate_in_num_steps = m_Zones[i].reactivate_in_num_steps; file->Write(&zh, sizeof(zh)); WriteMapString(file, m_Zones[i].script.c_str()); } // end for zones // save the tileset if (!m_Tileset.SaveToFile(file)) { file->Close(); return false; } file->Close(); return true; }
bool sMap::Load(const char* filename, IFileSystem& fs) { // open the file IFile* file = fs.Open(filename, IFileSystem::read); if (file == NULL) { return false; } // read the header MAP_HEADER header; file->Read(&header, sizeof(header)); // make sure it's valid if (memcmp(header.signature, ".rmp", 4) != 0 || header.version != 1 || (header.num_strings != 3 && header.num_strings != 5 && header.num_strings != 9)) { file->Close(); return false; } m_StartX = header.startx; m_StartY = header.starty; m_StartLayer = header.startlayer; m_StartDirection = header.startdirection; // read the strings (tileset, music, script) std::string tileset_file = ReadMapString(file); // OBSOLETE m_MusicFile = ReadMapString(file); ReadMapString(file); // script file if (header.num_strings == 3) { m_EntryScript = ""; m_ExitScript = ""; } else { m_EntryScript = ReadMapString(file); m_ExitScript = ReadMapString(file); } if (header.num_strings > 5) { m_EdgeScripts[0] = ReadMapString(file); m_EdgeScripts[1] = ReadMapString(file); m_EdgeScripts[2] = ReadMapString(file); m_EdgeScripts[3] = ReadMapString(file); } // delete the old layer array and allocate a new one m_Layers.clear(); m_Layers.resize(header.num_layers); // read the layers for (int i = 0; i < header.num_layers; i++) { // read the layer header LAYER_HEADER lh; file->Read(&lh, sizeof(lh)); // read the layer name std::string name = ReadMapString(file); // set all layer attributes m_Layers[i].SetName(name.c_str()); m_Layers[i].Resize(lh.width, lh.height); m_Layers[i].SetXParallax(lh.parallax_x); m_Layers[i].SetYParallax(lh.parallax_y); m_Layers[i].SetXScrolling(lh.scrolling_x); m_Layers[i].SetYScrolling(lh.scrolling_y); m_Layers[i].SetVisible((lh.flags & 1) == 0); m_Layers[i].EnableParallax((lh.flags & 2) != 0); m_Layers[i].SetReflective(lh.reflective != 0); // read the layer data for (int iy = 0; iy < lh.height; iy++) { for (int ix = 0; ix < lh.width; ix++) { word tile; file->Read(&tile, sizeof(tile)); m_Layers[i].SetTile(ix, iy, tile); } } // load the obstruction map for (int j = 0; j < lh.num_segments; j++) { dword x1; file->Read(&x1, sizeof(dword)); dword y1; file->Read(&y1, sizeof(dword)); dword x2; file->Read(&x2, sizeof(dword)); dword y2; file->Read(&y2, sizeof(dword)); m_Layers[i].GetObstructionMap().AddSegment(x1, y1, x2, y2); } } // end for layer // delete the old entities m_Entities.clear(); // read entities for (int i = 0; i < header.num_entities; i++) { ENTITY_HEADER eh; file->Read(&eh, sizeof(eh)); sEntity* entity; switch (eh.type) { // PERSON case 1: { sPersonEntity* person = new sPersonEntity; // read the person data person->name = ReadMapString(file); person->spriteset = ReadMapString(file); word num_strings = ReadMapWord(file); // strings if (num_strings >= 1) person->script_create = ReadMapString(file); if (num_strings >= 2) person->script_destroy = ReadMapString(file); if (num_strings >= 3) person->script_activate_touch = ReadMapString(file); if (num_strings >= 4) person->script_activate_talk = ReadMapString(file); if (num_strings >= 5) person->script_generate_commands = ReadMapString(file); // reserved for (int i = 0; i < 16; i++) ReadMapByte(file); entity = person; break; } // TRIGGER case 2: { sTriggerEntity* trigger = new sTriggerEntity; // read/set the trigger data trigger->script = ReadMapString(file); entity = trigger; break; } default: // unknown continue; } // end switch entity->x = eh.mapx; entity->y = eh.mapy; entity->layer = eh.layer; AddEntity(entity); } // clear the zones m_Zones.clear(); // load the zones for (int i = 0; i < header.num_zones; i++) { ZONE_HEADER zh; sZone zone; file->Read(&zh, sizeof(zh)); zone.x1 = zh.x1; zone.y1 = zh.y1; zone.x2 = zh.x2; zone.y2 = zh.y2; zone.layer = zh.layer; zone.reactivate_in_num_steps = zh.reactivate_in_num_steps; zone.script = ReadMapString(file); m_Zones.push_back(zone); } // if no tileset file was specified, it is appended to the map file if (tileset_file.length() == 0) { if (!m_Tileset.LoadFromFile(file)) { file->Close(); return false; } } else m_Tileset.Clear(); file->Close(); return true; }