ALERROR WriteResource (const CString &sFilename, const CString &sFolder, CSymbolTable &Resources, CDataFile &Out) { ALERROR error; CString sFilespec = pathAddComponent(sFolder, sFilename); CFileReadBlock theFile(sFilespec); if (error = theFile.Open()) { printf("Unable to open '%s'\n", sFilespec.GetASCIIZPointer()); return error; } CString sData(theFile.GetPointer(0, -1), theFile.GetLength(), TRUE); int iEntry; if (error = Out.AddEntry(sData, &iEntry)) { printf("Unable to store '%s'\n", sFilespec.GetASCIIZPointer()); return error; } Resources.AddEntry(sFilespec, (CObject *)iEntry); printf(" %s\n", sFilespec.GetASCIIZPointer()); return NOERROR; }
ALERROR WriteModuleSounds (CTDBCompiler &Ctx, CXMLElement *pModule, const CString &sFolder, CDataFile &Out) { ALERROR error; int i; for (i = 0; i < pModule->GetContentElementCount(); i++) { CXMLElement *pItem = pModule->GetContentElement(i); if (strEquals(pItem->GetTag(), TAG_SOUNDS)) { CString sSubFolder = pathAddComponent(sFolder, pItem->GetAttribute(ATTRIB_FOLDER)); if (error = WriteModuleSounds(Ctx, pItem, sSubFolder, Out)) return error; } else if (strEquals(pItem->GetTag(), TAG_SOUND)) { CString sFilename = pItem->GetAttribute(ATTRIB_FILENAME); if (error = WriteResource(Ctx, sFilename, sFolder, false, Out)) continue; } } return NOERROR; }
ALERROR WriteModuleImages (CXMLElement *pModule, const CString &sFolder, CSymbolTable &Resources, CDataFile &Out) { ALERROR error; int i; for (i = 0; i < pModule->GetContentElementCount(); i++) { CXMLElement *pItem = pModule->GetContentElement(i); if (strEquals(pItem->GetTag(), TAG_IMAGES)) { CString sSubFolder = pathAddComponent(sFolder, pItem->GetAttribute(ATTRIB_FOLDER)); if (error = WriteModuleImages(pItem, sSubFolder, Resources, Out)) return error; } else if (strEquals(pItem->GetTag(), TAG_IMAGE)) { CString sFilename = pItem->GetAttribute(ATTRIB_BITMAP); if (!sFilename.IsBlank()) { if (error = WriteResource(sFilename, sFolder, Resources, Out)) continue; } sFilename = pItem->GetAttribute(ATTRIB_BITMASK); if (!sFilename.IsBlank()) { if (error = WriteResource(sFilename, sFolder, Resources, Out)) continue; } } } return NOERROR; }
ALERROR CExtension::LoadImagesElement (SDesignLoadCtx &Ctx, CXMLElement *pDesc) // LoadImagesElement // // Loads <Images> element // (For backwards compatibility) { ALERROR error; int i; // Figure out if we've got a special folder for the images CString sOldFolder = Ctx.sFolder; CString sFolder = pDesc->GetAttribute(FOLDER_ATTRIB); if (!sFolder.IsBlank()) Ctx.sFolder = pathAddComponent(Ctx.sFolder, sFolder); // Load all images for (i = 0; i < pDesc->GetContentElementCount(); i++) { CXMLElement *pItem = pDesc->GetContentElement(i); if (error = LoadDesignType(Ctx, pItem)) return error; } // Restore folder Ctx.sFolder = sOldFolder; return NOERROR; }
ALERROR CResourceDb::LoadSound (CSoundMgr &SoundMgr, const CString &sFolder, const CString &sFilename, int *retiChannel) // LoadSound // // Loads a sound file { ALERROR error; if (m_bResourcesInDb && m_pDb) { ASSERT(m_pResourceMap); CString sFilespec; if (m_iVersion >= 11) sFilespec = pathAddComponent(sFolder, sFilename); else sFilespec = sFilename; // Look-up the resource in the map int iEntry; if ((error = m_pResourceMap->Lookup(sFilespec, (CObject **)&iEntry))) return error; CString sData; if ((error = m_pDb->ReadEntry(iEntry, &sData))) return error; CBufferReadBlock Data(sData); if ((error = Data.Open())) return error; if ((error = SoundMgr.LoadWaveFromBuffer(Data, retiChannel))) return error; } else { CString sFilespec = pathAddComponent(m_sRoot, sFolder); sFilespec = pathAddComponent(sFilespec, sFilename); if ((error = SoundMgr.LoadWaveFile(sFilespec, retiChannel))) return error; } return NOERROR; }
ALERROR CMainController::Boot (CUApplication *pApp) // Boot // // Create the main window { ALERROR error; AutoSizeDesc AutoSize; CUFrame *pFrame; // Set context m_pApp = pApp; // Set icon m_pApp->SetIconRes("LL1"); // Don't open full screen if the shift-key is down DWORD dwFlags = WINDOW_FLAG_ANIMATE; if (!IsShiftDown()) dwFlags |= WINDOW_FLAG_FULLSCREEN; // Create the main window if (error = m_pApp->CreateNewWindow(this, 0, dwFlags, &m_pWindow)) return error; m_pWindow->SetTitle(LITERAL("Library Link")); m_pWindow->SetQueryCloseMsg((ControllerNotifyProc)&CMainController::CmdQueryClose); // Create the main page AutoSize.SetFull(); if (error = m_pWindow->CreateFrame(NULL, MAINPAGE_ID, 0, &AutoSize, &pFrame)) return error; m_pMainPage = new CLibraryPage(this); if (m_pMainPage == NULL) return ERR_MEMORY; if (error = m_pMainPage->Boot(pFrame)) return error; // Open the default core CString sPath = m_pApp->GetExecutablePath(); sPath = pathAddComponent(sPath, LITERAL(DEFAULT_CORE_FILENAME)); if (error = m_pMainPage->OpenCore(sPath)) return error; return NOERROR; }
ALERROR WriteResource (CTDBCompiler &Ctx, const CString &sFilename, const CString &sFolder, bool bCompress, CDataFile &Out) { ALERROR error; CString sFilespec = pathAddComponent(sFolder, sFilename); CFileReadBlock theFile(pathAddComponent(Ctx.GetRootPath(), sFilespec)); if (error = theFile.Open()) { Ctx.ReportError(strPatternSubst(CONSTLIT("Unable to open '%s'."), sFilespec)); return error; } CString sData(theFile.GetPointer(0, -1), theFile.GetLength(), TRUE); if (bCompress) { CBufferReadBlock Input(sData); CMemoryWriteStream Output; if (error = Output.Create()) return ERR_FAIL; CString sError; if (!zipCompress(Input, compressionZlib, Output, &sError)) { Ctx.ReportError(sError); return ERR_FAIL; } sData = CString(Output.GetPointer(), Output.GetLength()); } int iEntry; if (error = Out.AddEntry(sData, &iEntry)) { Ctx.ReportError(strPatternSubst(CONSTLIT("Unable to store '%s'."), sFilespec)); return error; } Ctx.AddResource(sFilespec, iEntry, bCompress); printf(" %s\n", sFilespec.GetASCIIZPointer()); return NOERROR; }
ALERROR WriteModuleImages (CTDBCompiler &Ctx, CXMLElement *pModule, const CString &sFolder, CDataFile &Out) { ALERROR error; int i; for (i = 0; i < pModule->GetContentElementCount(); i++) { CXMLElement *pItem = pModule->GetContentElement(i); if (strEquals(pItem->GetTag(), TAG_IMAGES)) { CString sSubFolder = pathAddComponent(sFolder, pItem->GetAttribute(ATTRIB_FOLDER)); if (error = WriteModuleImages(Ctx, pItem, sSubFolder, Out)) return error; } else if (strEquals(pItem->GetTag(), TAG_IMAGE)) { CString sFilename = pItem->GetAttribute(ATTRIB_BITMAP); if (!sFilename.IsBlank()) { bool bCompress = strEquals(strToLower(pathGetExtension(sFilename)), CONSTLIT("bmp")); if (error = WriteResource(Ctx, sFilename, sFolder, bCompress, Out)) continue; } sFilename = pItem->GetAttribute(ATTRIB_BITMASK); if (!sFilename.IsBlank()) { bool bCompress = strEquals(strToLower(pathGetExtension(sFilename)), CONSTLIT("bmp")); if (error = WriteResource(Ctx, sFilename, sFolder, bCompress, Out)) continue; } sFilename = pItem->GetAttribute(ATTRIB_SHADOW_MASK); if (!sFilename.IsBlank()) { bool bCompress = strEquals(strToLower(pathGetExtension(sFilename)), CONSTLIT("bmp")); if (error = WriteResource(Ctx, sFilename, sFolder, bCompress, Out)) continue; } sFilename = pItem->GetAttribute(ATTRIB_HIT_MASK); if (!sFilename.IsBlank()) { bool bCompress = strEquals(strToLower(pathGetExtension(sFilename)), CONSTLIT("bmp")); if (error = WriteResource(Ctx, sFilename, sFolder, bCompress, Out)) continue; } } } return NOERROR; }
void CSoundMgr::AddMusicFolder (const CString &sFolder, TArray<CString> *retCatalog) // AddMusicFolder // // This is a recursive function that adds all the music files in sFolder (and // any subfolders) to retCatalog { CFileDirectory Dir(pathAddComponent(sFolder, CONSTLIT("*.*"))); while (Dir.HasMore()) { SFileDesc FileDesc; Dir.GetNextDesc(&FileDesc); // Skip hidden or system files if (FileDesc.bHiddenFile || FileDesc.bSystemFile) continue; // Skip any file or directory that starts with a dot if (*FileDesc.sFilename.GetASCIIZPointer() == '.') continue; // Get the full filename CString sFilepath = pathAddComponent(sFolder, FileDesc.sFilename); // If this is a folder then recurse if (FileDesc.bFolder) AddMusicFolder(sFilepath, retCatalog); // Otherwise add the filespec else retCatalog->Insert(sFilepath); } }
ALERROR CResourceDb::LoadEntities (CString *retsError) // LoadEntities // // Loads the entities of a game file { ALERROR error; if (m_pMainDb == NULL) { if (m_bGameFileInDb && m_pDb) { ASSERT(m_pResourceMap); CString sGameFile; if ((error = m_pDb->ReadEntry(m_iGameFile, &sGameFile))) { *retsError = strPatternSubst(CONSTLIT("%s is corrupt"), m_sGameFile.GetASCIIZPointer()); return error; } // Parse the XML file from the buffer CBufferReadBlock GameFile(sGameFile); CString sError; if ((error = CXMLElement::ParseEntityTable(&GameFile, &m_Entities, &sError))) { *retsError = strPatternSubst(CONSTLIT("Unable to parse %s: %s"), m_sGameFile.GetASCIIZPointer(), sError.GetASCIIZPointer()); return error; } } else { // Parse the XML file on disk CFileReadBlock DataFile(pathAddComponent(m_sRoot, m_sGameFile)); CString sError; if ((error = CXMLElement::ParseEntityTable(&DataFile, &m_Entities, &sError))) { *retsError = strPatternSubst(CONSTLIT("Unable to parse %s: %s"), m_sGameFile.GetASCIIZPointer(), sError.GetASCIIZPointer()); return error; } } } return NOERROR; }
ALERROR CTransmuterController::OnInit (CString *retsError) // OnInit // // Initialize after HI has booted. { // Initialize the model CTransmuterModel::SInitDesc Ctx; Ctx.bDebugMode = m_Settings.GetValueBoolean(SETTING_DEBUG_MODE); Ctx.bForceTDB = m_Settings.GetValueBoolean(SETTING_FORCE_TDB); Ctx.sCollectionFolder = pathAddComponent(m_Settings.GetUserFolder(), FOLDER_COLLECTION); Ctx.ExtensionFolders.Insert(pathAddComponent(m_Settings.GetUserFolder(), FOLDER_EXTENSIONS)); Ctx.SaveFileFolders.Insert(pathAddComponent(m_Settings.GetUserFolder(), FOLDER_SAVE_FILES)); if (!m_Model.Init(Ctx, retsError)) return ERR_FAIL; m_HI.ShowSession(new CTransmuterSession(m_HI, m_Model)); return NOERROR; }
CString CResourceDb::GetRootTag (void) // GetRootTag // // Returns the tag of the root element (or NULL_STR if there is an error) { if (m_bGameFileInDb && m_pDb) { ASSERT(m_pResourceMap); int iReadSize = Min(m_pDb->GetEntryLength(m_iGameFile), 1024); CString sGameFile; if (m_pDb->ReadEntryPartial(m_iGameFile, 0, iReadSize, &sGameFile) != NOERROR) return NULL_STR; // Parse the XML file from the buffer CBufferReadBlock GameFile(sGameFile); CString sTag; if (CXMLElement::ParseRootTag(&GameFile, &sTag) != NOERROR) return NULL_STR; return sTag; } else { // Parse the XML file on disk CFileReadBlock DataFile(pathAddComponent(m_sRoot, m_sGameFile)); CString sTag; if (CXMLElement::ParseRootTag(&DataFile, &sTag) != NOERROR) return NULL_STR; return sTag; } }
ALERROR CExtension::LoadSoundsElement (SDesignLoadCtx &Ctx, CXMLElement *pDesc) // LoadSoundsElement // // Loads <Sounds> element // (For backwards compatibility) { ALERROR error; int i; // Nothing to do if we don't want sound resources if (Ctx.bNoResources || g_pUniverse->GetSoundMgr() == NULL) return NOERROR; // Figure out if we've got a special folder for the resources CString sOldFolder = Ctx.sFolder; CString sFolder = pDesc->GetAttribute(FOLDER_ATTRIB); if (!sFolder.IsBlank()) Ctx.sFolder = pathAddComponent(Ctx.sFolder, sFolder); // Loop over all sound resources for (i = 0; i < pDesc->GetContentElementCount(); i++) { CXMLElement *pItem = pDesc->GetContentElement(i); if (error = LoadSoundElement(Ctx, pItem)) return error; } // Restore folder Ctx.sFolder = sOldFolder; return NOERROR; }
CResourceDb::CResourceDb (const CString &sFilespec, CResourceDb *pMainDb, bool bExtension) : m_iVersion(TDB_VERSION), m_pDb(NULL), m_pResourceMap(NULL), m_pMainDb(NULL) // CResourceDb constructor // // sFilespec = "Extensions/MyExtension" // // If Extensions/MyExtension.tdb exists, then look for the definitions // and the resources in the .tdb file. // // Otherwise, use Extensions/MyExtension.xml for the definitions and // Look for resource files in the Extensions folder. { if (pMainDb || bExtension) { // We assume this is an extension CString sTDB = sFilespec; sTDB.Append(CONSTLIT(".")); sTDB.Append(FILE_TYPE_TDB); if (pathExists(sTDB)) { m_pDb = new CDataFile(sTDB); m_sRoot = pathGetPath(sTDB); m_sGameFile = pathGetFilename(sTDB); m_bGameFileInDb = true; m_bResourcesInDb = true; } else { CString sXML = sFilespec; sXML.Append(CONSTLIT(".")); sXML.Append(FILE_TYPE_XML); m_pDb = NULL; m_sRoot = pathGetPath(sFilespec); m_sGameFile = pathGetFilename(sXML); m_bGameFileInDb = false; m_bResourcesInDb = false; } m_pMainDb = pMainDb; } else { CString sType = pathGetExtension(sFilespec); if (sType.IsBlank()) { CString sXML = sFilespec; sXML.Append(CONSTLIT(".")); sXML.Append(FILE_TYPE_XML); // If Transcendence.xml exists, then use the file and load // the resources from the same location. if (pathExists(sXML)) { m_sRoot = pathGetPath(sXML); m_sGameFile = pathGetFilename(sXML); m_bGameFileInDb = false; // If a resources path exists, then use the resources in the // folder. Otherwise, use resources in the tdb CString sResourcesPath = pathAddComponent(m_sRoot, RESOURCES_FOLDER); if (pathExists(sResourcesPath)) { m_pDb = NULL; m_bResourcesInDb = false; } // Otherwise, use the tdb file else { CString sTDB = sFilespec; sTDB.Append(CONSTLIT(".")); sTDB.Append(FILE_TYPE_TDB); m_pDb = new CDataFile(sTDB); m_bResourcesInDb = true; } } // Otherwise, use the .tdb file for both else { CString sTDB = sFilespec; sTDB.Append(CONSTLIT(".")); sTDB.Append(FILE_TYPE_TDB); m_pDb = new CDataFile(sTDB); m_bGameFileInDb = true; m_bResourcesInDb = true; } } else if (strEquals(sType, FILE_TYPE_XML)) { m_sRoot = pathGetPath(sFilespec); m_sGameFile = pathGetFilename(sFilespec); m_pDb = NULL; m_bGameFileInDb = false; m_bResourcesInDb = false; } else { m_pDb = new CDataFile(sFilespec); m_bGameFileInDb = true; m_bResourcesInDb = true; } // This is the main file m_pMainDb = NULL; } }
ALERROR CExtension::LoadModuleElement (SDesignLoadCtx &Ctx, CXMLElement *pDesc) // LoadModuleElement // // Loads <Module> { ALERROR error; CString sFilename = pDesc->GetAttribute(FILENAME_ATTRIB); // Load the module XML CXMLElement *pModuleXML; if (error = Ctx.pResDb->LoadModule(Ctx.sFolder, sFilename, &pModuleXML, &Ctx.sError)) { if (error == ERR_NOTFOUND) Ctx.sError = strPatternSubst(CONSTLIT("%s: %s"), Ctx.pResDb->GetFilespec(), Ctx.sError); return error; } if (!strEquals(pModuleXML->GetTag(), TRANSCENDENCE_MODULE_TAG)) { delete pModuleXML; Ctx.sError = strPatternSubst(CONSTLIT("Module must have <TranscendenceModule> root element: %s"), sFilename); return ERR_FAIL; } // We are loading a module bool bOldLoadModule = Ctx.bLoadModule; Ctx.bLoadModule = true; // Look for resources relative to the module path CString sOldFolder = Ctx.sFolder; CString sFolder = pathGetPath(sFilename); if (!sFolder.IsBlank() && Ctx.GetAPIVersion() >= 26) Ctx.sFolder = pathAddComponent(Ctx.sFolder, sFolder); // Errors credited to this file. CString sOldErrorFilespec = Ctx.sErrorFilespec; if (strEquals(pathGetExtension(sOldErrorFilespec), FILESPEC_TDB_EXTENSION)) Ctx.sErrorFilespec = strPatternSubst(CONSTLIT("%s#%s"), sOldErrorFilespec, sFilename); else Ctx.sErrorFilespec = sFilename; // Process each design element in the module if (error = LoadModuleContent(Ctx, pModuleXML)) return error; // Clean up Ctx.sFolder = sOldFolder; Ctx.sErrorFilespec = sOldErrorFilespec; Ctx.bLoadModule = bOldLoadModule; // If we're keeping the XML, then add it to our table if (Ctx.bKeepXML && !m_ModuleXML.Find(sFilename)) m_ModuleXML.Insert(sFilename, pModuleXML); else delete pModuleXML; return NOERROR; }
ALERROR CObjectImage::OnCreateFromXML (SDesignLoadCtx &Ctx, CXMLElement *pDesc) // CreateFromXML // // Creates the object from and XML element { ALERROR error; // Load on use m_bLoadOnUse = pDesc->GetAttributeBool(LOAD_ON_USE_ATTRIB); // Get the file paths m_sResourceDb = Ctx.sResDb; if (Ctx.sFolder.IsBlank()) { m_sBitmap = pDesc->GetAttribute(BITMAP_ATTRIB); m_sBitmask = pDesc->GetAttribute(BITMASK_ATTRIB); } else { CString sFilespec; if (pDesc->FindAttribute(BITMAP_ATTRIB, &sFilespec)) m_sBitmap = pathAddComponent(Ctx.sFolder, sFilespec); if (pDesc->FindAttribute(BITMASK_ATTRIB, &sFilespec)) m_sBitmask = pathAddComponent(Ctx.sFolder, sFilespec); } // Transparent color CString sTransColor; if (m_bTransColor = pDesc->FindAttribute(BACK_COLOR_ATTRIB, &sTransColor)) m_wTransColor = LoadRGBColor(sTransColor); // Sprite m_bSprite = pDesc->GetAttributeBool(SPRITE_ATTRIB); // Pre-multiply transparency m_bPreMult = !pDesc->GetAttributeBool(NO_PM_ATTRIB); // Initialize m_bMarked = false; m_bLocked = false; m_pBitmap = NULL; // If we're loading on use, make sure the image exists. For other // images we don't bother checking because we will load them // soon enough. if (m_bLoadOnUse) if (error = Exists(Ctx)) return error; // Done return NOERROR; }
ALERROR CGameSettings::Load (const CString &sFilespec, CString *retsError) // Load // // Load game settings from a file. If the file does not exist, then we // set settings to default values { ALERROR error; int i; // Initialize from defaults for (i = 0; i < OPTIONS_COUNT; i++) SetValue(i, CString(g_OptionData[i].pszDefaultValue, -1, true), true); // Look for a file in the current directory and see if it is writable. If // not, then look in AppData. We remember the place where we found a valid // file as our AppData root (and we base other directories off that). if (pathIsWritable(sFilespec)) { // AppData is current directory m_sAppData = NULL_STR; } else { m_sAppData = pathAddComponent(pathGetSpecialFolder(folderAppData), TRANSCENDENCE_APP_DATA); if (!pathCreate(m_sAppData) || !pathIsWritable(m_sAppData)) { *retsError = strPatternSubst(CONSTLIT("Unable to write to AppData folder: %s"), m_sAppData); return ERR_FAIL; } } // Settings file CString sSettingsFilespec = pathAddComponent(m_sAppData, sFilespec); // Load XML CFileReadBlock DataFile(sSettingsFilespec); CXMLElement *pData; CString sError; if (error = CXMLElement::ParseXML(&DataFile, &pData, retsError)) { // ERR_NOTFOUND means that we couldn't find the Settings.xml // file. In that case, initialize from defaults if (error == ERR_NOTFOUND) { LoadFromRegistry(); m_bModified = true; return NOERROR; } // Otherwise, it means that we got an error parsing the file. // Return the error, but leave the settings initialized to defaults // (We should be OK to continue, even with an error). else { m_bModified = false; return error; } } // Initialize to unmodified (as we load settings we might change this) m_bModified = false; // Loop over all elements for (i = 0; i < pData->GetContentElementCount(); i++) { CXMLElement *pItem = pData->GetContentElement(i); if (strEquals(pItem->GetTag(), OPTION_TAG)) { int iOption = FindOptionData(pItem->GetAttribute(NAME_ATTRIB)); if (iOption == -1) { kernelDebugLogMessage("Unknown option: %s", pItem->GetAttribute(NAME_ATTRIB)); continue; } SetValue(iOption, pItem->GetAttribute(VALUE_ATTRIB), true); } else if (strEquals(pItem->GetTag(), KEY_MAP_TAG)) { if (error = m_KeyMap.ReadFromXML(pItem)) return error; } else if (strEquals(pItem->GetTag(), EXTENSION_FOLDER_TAG)) { CString sFolder; if (pItem->FindAttribute(PATH_ATTRIB, &sFolder)) m_ExtensionFolders.Insert(sFolder); } else if (strEquals(pItem->GetTag(), EXTENSIONS_TAG)) { if (error = m_Extensions.ReadFromXML(pItem)) return error; } else if (m_pExtra) { bool bModified; if (error = m_pExtra->OnLoadSettings(pItem, &bModified)) return error; if (bModified) m_bModified = true; } } // Done delete pData; return NOERROR; }
ALERROR WriteModule (CTDBCompiler &Ctx, const CString &sFilename, const CString &sFolder, CDataFile &Out, int *retiModuleEntry, bool bCore) { ALERROR error; int i; // Parse the file CXMLElement *pModule; CExternalEntityTable *pEntityTable = new CExternalEntityTable; CFileReadBlock DataFile(pathAddComponent(Ctx.GetRootPath(), sFilename)); CString sError; printf("Parsing %s...", sFilename.GetASCIIZPointer()); if (error = CXMLElement::ParseXML(&DataFile, Ctx.GetCoreEntities(), &pModule, &sError, pEntityTable)) { printf("\n"); Ctx.ReportError(sError); return error; } // If this is a core module (embedded in the root XML) then we add these // entities to the core. [Ctx takes ownership.] if (bCore) Ctx.AddEntityTable(pEntityTable); // Chain entity tables (so that any modules that we load get the benefit). // This will chain Ctx.pCoreEntities (and restore it in the destructor). // // NOTE: If this is a core module, then we don't do this, since we've // already added the entities to the context block. CSaveEntitiesTable SavedEntities(Ctx, (!bCore ? pEntityTable : NULL)); printf("done.\n"); // Compress if this is NOT the main file. We can't compress the // main file because we sometimes need to read it partially. bool bCompress = (retiModuleEntry == NULL); // Write the module itself int iEntry; if (error = WriteGameFile(Ctx, sFilename, bCompress, Out, &iEntry)) return error; // If the caller doesn't want the module entry, then it means that this is // a module (instead of the main file). If so, add it to the resources table if (retiModuleEntry == NULL) Ctx.AddResource(sFilename, iEntry, bCompress); // Store all the image resources if (error = WriteModuleImages(Ctx, pModule, sFolder, Out)) return error; // Store all the sound resources if (error = WriteModuleSounds(Ctx, pModule, sFolder, Out)) return error; // Store all modules if (error = WriteSubModules(Ctx, pModule, sFolder, Out)) return error; // The root module may have a TranscendenceAdventure tag with modules in it for (i = 0; i < pModule->GetContentElementCount(); i++) { CXMLElement *pItem = pModule->GetContentElement(i); if (strEquals(pItem->GetTag(), TAG_CORE_LIBRARY) || strEquals(pItem->GetTag(), TAG_TRANSCENDENCE_ADVENTURE) || strEquals(pItem->GetTag(), TAG_TRANSCENDENCE_LIBRARY)) { // If we have a filename, then we need to save the target as a // module. CString sFilename; if (pItem->FindAttribute(ATTRIB_FILENAME, &sFilename)) { // Write out the module, making sure to set the core flag. if (error = WriteModule(Ctx, sFilename, sFolder, Out, NULL, true)) return error; // We ignore any other elements. continue; } // Store all the image resources if (error = WriteModuleImages(Ctx, pItem, sFolder, Out)) return error; // Store all the sound resources if (error = WriteModuleSounds(Ctx, pItem, sFolder, Out)) return error; // Modules if (error = WriteSubModules(Ctx, pItem, sFolder, Out)) return error; } } // Done if (retiModuleEntry) *retiModuleEntry = iEntry; return NOERROR; }
ALERROR CGameSettings::Save (const CString &sFilespec) // Save // // Save game settings to a file (if necessary) { int i; ALERROR error; if (!m_bModified) return NOERROR; // Settings file CString sSettingsFilespec = pathAddComponent(m_sAppData, sFilespec); // Create the file CFileWriteStream DataFile(sSettingsFilespec, FALSE); if (error = DataFile.Create()) return error; // Write the XML header CString sData = CONSTLIT("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n\r\n<TranscendenceSettings>\r\n\r\n"); if (error = DataFile.Write(sData.GetPointer(), sData.GetLength(), NULL)) return error; // Write extension folders if (m_ExtensionFolders.GetCount() > 0) { for (i = 0; i < m_ExtensionFolders.GetCount(); i++) { sData = strPatternSubst(CONSTLIT("\t<ExtensionFolder path=\"%s\"/>\r\n"), m_ExtensionFolders[i]); if (error = DataFile.Write(sData.GetPointer(), sData.GetLength())) return error; } if (error = DataFile.Write("\r\n", 2, NULL)) return error; } // Loop over options for (i = 0; i < OPTIONS_COUNT; i++) { // Compose option element and write sData = strPatternSubst(CONSTLIT("\t<Option name=\"%s\"\tvalue=\"%s\"/>\r\n"), CString(g_OptionData[i].pszName, -1, true), strToXMLText(m_Options[i].sSettingsValue)); if (error = DataFile.Write(sData.GetPointer(), sData.GetLength(), NULL)) return error; } // Write the key map if (error = DataFile.Write("\r\n", 2, NULL)) return error; if (error = m_KeyMap.WriteAsXML(&DataFile)) return error; // Write the extensions list if (error = DataFile.Write("\r\n", 2)) return error; if (error = m_Extensions.WriteAsXML(&DataFile)) return error; // Write additional settings if (m_pExtra) { if (error = DataFile.Write("\r\n", 2, NULL)) return error; if (error = m_pExtra->OnSaveSettings(&DataFile)) return error; } // Done sData = CONSTLIT("\r\n</TranscendenceSettings>\r\n"); if (error = DataFile.Write(sData.GetPointer(), sData.GetLength(), NULL)) return error; if (error = DataFile.Close()) return error; return NOERROR; }
/* ALERROR CResourceDb::LoadImage (const CString &sFolder, const CString &sFilename, HBITMAP *rethImage) // LoadImage // // Loads an image and returns it { assert(0); } */ ALERROR CResourceDb::LoadModule (const CString &sFolder, const CString &sFilename, CXMLElement **retpData, CString *retsError) // LoadModule // // Loads a module { ALERROR error; if (m_bGameFileInDb && m_pDb) { ASSERT(m_pResourceMap); CString sFilespec; if (m_iVersion >= 11) sFilespec = pathAddComponent(sFolder, sFilename); else sFilespec = sFilename; // Look up the file in the map int iEntry; TRY(m_pResourceMap->Lookup(sFilespec, (CObject **)&iEntry)); if (error) { *retsError = strPatternSubst(CONSTLIT("%s: Resource map corrupt."), m_sGameFile.GetASCIIZPointer()); return error; } CString sGameFile; TRY(m_pDb->ReadEntry(iEntry, &sGameFile)); if (error) { *retsError = strPatternSubst(CONSTLIT("%s: Unable to read entry: %d"), m_sGameFile.GetASCIIZPointer(), iEntry); return error; } // Parse the XML file from the buffer CBufferReadBlock GameFile(sGameFile); CString sError; TRY(CXMLElement::ParseXML(&GameFile, &m_Entities, retpData, &sError)); if (error) { *retsError = strPatternSubst(CONSTLIT("%s: %s"), m_sGameFile.GetASCIIZPointer(), sError.GetASCIIZPointer()); return error; } } else { // Parse the XML file on disk CFileReadBlock DataFile(pathAddComponent(m_sRoot, pathAddComponent(sFolder, sFilename))); CString sError; if ((error = CXMLElement::ParseXML(&DataFile, &m_Entities, retpData, &sError))) { *retsError = strPatternSubst(CONSTLIT("Unable to parse %s: %s"), sFilename.GetASCIIZPointer(), sError.GetASCIIZPointer()); return error; } } return NOERROR; }