ALERROR CExtension::CreateExtensionFromRoot (const CString &sFilespec, CXMLElement *pDesc, EFolderTypes iFolder, CExternalEntityTable *pEntities, DWORD dwInheritAPIVersion, CExtension **retpExtension, CString *retsError) // CreateExtension // // Loads the given extension or adventure. We take ownership of pEntities. { int i; // Create an extension object CExtension *pExtension = new CExtension; pExtension->m_sFilespec = sFilespec; pExtension->m_dwUNID = pDesc->GetAttributeInteger(UNID_ATTRIB); if (pExtension->m_dwUNID == 0) { delete pExtension; *retsError = CONSTLIT("Invalid UNID."); return ERR_FAIL; } if (strEquals(pDesc->GetTag(), TRANSCENDENCE_ADVENTURE_TAG)) { pExtension->m_iGame = gameTranscendence; pExtension->m_iType = extAdventure; } else if (strEquals(pDesc->GetTag(), TRANSCENDENCE_LIBRARY_TAG)) { pExtension->m_iGame = gameTranscendence; pExtension->m_iType = extLibrary; } else if (strEquals(pDesc->GetTag(), TRANSCENDENCE_EXTENSION_TAG)) { pExtension->m_iGame = gameTranscendence; pExtension->m_iType = extExtension; } else if (strEquals(pDesc->GetTag(), CORE_LIBRARY_TAG)) { // For core libraries, we don't care what game it is. It's always // whatever game the base file is. pExtension->m_iGame = gameUnknown; pExtension->m_iType = extLibrary; } else { delete pExtension; *retsError = strPatternSubst(CONSTLIT("Unknown root element: %s"), pDesc->GetTag()); return ERR_FAIL; } pExtension->m_iLoadState = loadEntities; pExtension->m_iFolderType = iFolder; pExtension->m_pEntities = pEntities; pExtension->m_ModifiedTime = fileGetModifiedTime(sFilespec); pExtension->m_bDebugOnly = pDesc->GetAttributeBool(DEBUG_ONLY_ATTRIB); pExtension->m_bRegistered = IsRegisteredUNID(pExtension->m_dwUNID); pExtension->m_bPrivate = pDesc->GetAttributeBool(PRIVATE_ATTRIB); pExtension->m_bAutoInclude = pDesc->GetAttributeBool(AUTO_INCLUDE_ATTRIB); pExtension->m_bUsesXML = pDesc->GetAttributeBool(USES_XML_ATTRIB); // API version CString sAPIVersion; if (pDesc->FindAttribute(API_VERSION_ATTRIB, &sAPIVersion)) { pExtension->m_dwAPIVersion = (DWORD)strToInt(sAPIVersion, 0); if (pExtension->m_dwAPIVersion < 12) pExtension->m_dwAPIVersion = 0; pExtension->m_sVersion = pDesc->GetAttribute(VERSION_ATTRIB); } else if (dwInheritAPIVersion) { pExtension->m_dwAPIVersion = dwInheritAPIVersion; pExtension->m_sVersion = pDesc->GetAttribute(VERSION_ATTRIB); } else { sAPIVersion = pDesc->GetAttribute(VERSION_ATTRIB); pExtension->m_dwAPIVersion = ::LoadExtensionVersion(sAPIVersion); } if (pExtension->m_dwAPIVersion == 0) { pExtension->m_pEntities = NULL; // Let our parent clean up. delete pExtension; *retsError = strPatternSubst(CONSTLIT("Unable to load extension: incompatible version: %s"), sAPIVersion); return ERR_FAIL; } // If this is a later version, then disabled it if (pExtension->m_dwAPIVersion > API_VERSION) pExtension->SetDisabled(CONSTLIT("Requires a newer version of Transcendence.exe")); // Release pExtension->m_dwRelease = pDesc->GetAttributeInteger(RELEASE_ATTRIB); // Registered extensions default to release 1. if (pExtension->m_dwRelease == 0 && iFolder == folderCollection) pExtension->m_dwRelease = 1; // Name pExtension->m_sName = pDesc->GetAttribute(NAME_ATTRIB); if (pExtension->m_sName.IsBlank()) pExtension->m_sName = strPatternSubst(CONSTLIT("Extension %x"), pExtension->m_dwUNID); // Image pExtension->m_dwCoverUNID = (DWORD)pDesc->GetAttributeInteger(COVER_IMAGE_UNID_ATTRIB); // Load credits (we parse them into a string array) CString sCredits = pDesc->GetAttribute(CREDITS_ATTRIB); if (!sCredits.IsBlank()) strDelimitEx(sCredits, ';', DELIMIT_TRIM_WHITESPACE, 0, &pExtension->m_Credits); // Load extends attrib CString sExtends = pDesc->GetAttribute(EXTENDS_ATTRIB); if (!sExtends.IsBlank()) { TArray<CString> Extends; strDelimitEx(sExtends, ';', DELIMIT_TRIM_WHITESPACE, 0, &Extends); for (i = 0; i < Extends.GetCount(); i++) { DWORD dwUNID = strToInt(Extends[i], INVALID_UNID); if (dwUNID != INVALID_UNID) pExtension->m_Extends.Insert(dwUNID); } } // Other options pExtension->m_dwAutoIncludeAPIVersion = (DWORD)pDesc->GetAttributeIntegerBounded(AUTO_INCLUDE_FOR_COMPATIBILITY_ATTRIB, 0, -1, 0); // Done *retpExtension = pExtension; return NOERROR; }
ALERROR CListSaveFilesTask::OnExecute (ITaskProcessor *pProcessor, CString *retsResult) // OnExecute // // Execute the task { int i; const CVisualPalette &VI = m_HI.GetVisuals(); // Make a list of all files in the directory TArray<CString> SaveFiles; bool bAtLeastOneFolder = false; for (i = 0; i < m_Folders.GetCount(); i++) { if (!fileGetFileList(m_Folders[i], NULL_STR, CONSTLIT("*.sav"), 0, &SaveFiles)) ::kernelDebugLogMessage("Unable to read from save file folder: %s", m_Folders[i]); else bAtLeastOneFolder = true; } // If we couldn't read from any folder, return an error if (!bAtLeastOneFolder) { *retsResult = ERR_DIRECTORY_FAILED; return ERR_FAIL; } // Sort by modified time (most recent first) TSortMap<CTimeDate, CString> SortedList(DescendingSort); for (i = 0; i < SaveFiles.GetCount(); i++) SortedList.Insert(fileGetModifiedTime(SaveFiles[i]), SaveFiles[i]); // Generate a Reanimator list of the profile. The root will be a CAniListBox m_pList = new CAniListBox; m_pList->SetPropertyMetric(PROP_FADE_EDGE_HEIGHT, 0.0); m_pList->SetPropertyMetric(PROP_PADDING_BOTTOM, (Metric)MAJOR_PADDING_BOTTOM); // Set the selection style for the list IAnimatron *pStyle = new CAniRoundedRect; pStyle->SetPropertyColor(PROP_COLOR, VI.GetColor(colorAreaDialogInputFocus)); pStyle->SetPropertyOpacity(PROP_OPACITY, 255); pStyle->SetPropertyString(PROP_LINE_TYPE, LINE_TYPE_SOLID); pStyle->SetPropertyColor(PROP_LINE_COLOR, VI.GetColor(colorAreaDialogHighlight)); pStyle->SetPropertyInteger(PROP_LINE_WIDTH, SELECTION_BORDER_WIDTH); pStyle->SetPropertyInteger(PROP_UL_RADIUS, SELECTION_CORNER_RADIUS); pStyle->SetPropertyInteger(PROP_UR_RADIUS, SELECTION_CORNER_RADIUS); pStyle->SetPropertyInteger(PROP_LL_RADIUS, SELECTION_CORNER_RADIUS); pStyle->SetPropertyInteger(PROP_LR_RADIUS, SELECTION_CORNER_RADIUS); m_pList->SetStyle(STYLE_SELECTION_FOCUS, pStyle); pStyle = new CAniRoundedRect; pStyle->SetPropertyColor(PROP_COLOR, VI.GetColor(colorAreaDialogInputFocus)); pStyle->SetPropertyOpacity(PROP_OPACITY, 255); pStyle->SetPropertyInteger(PROP_UL_RADIUS, SELECTION_CORNER_RADIUS); pStyle->SetPropertyInteger(PROP_UR_RADIUS, SELECTION_CORNER_RADIUS); pStyle->SetPropertyInteger(PROP_LL_RADIUS, SELECTION_CORNER_RADIUS); pStyle->SetPropertyInteger(PROP_LR_RADIUS, SELECTION_CORNER_RADIUS); m_pList->SetStyle(STYLE_SELECTION, pStyle); // No need to log image load g_pUniverse->SetLogImageLoad(false); // Loop over all files and add them to the scroller int y = MAJOR_PADDING_TOP; for (i = 0; i < SortedList.GetCount(); i++) { CString sFilename = SortedList[i]; CGameFile GameFile; // Ignore files that we can't open if (GameFile.Open(sFilename) != NOERROR) continue; // If the universe is not valid, then this is not a proper save file // (this can happen in the first system). if (!GameFile.IsUniverseValid()) continue; // If we're signed in, then we only show games for the given user // (or unregistered games). if (GameFile.IsRegistered() && !strEquals(GameFile.GetUsername(), m_sUsername)) continue; // Generate a record for the file IAnimatron *pEntry; int cyHeight; CreateFileEntry(GameFile, SortedList.GetKey(i), y, &pEntry, &cyHeight); m_pList->AddEntry(sFilename, pEntry); y += cyHeight + INTER_LINE_SPACING; // Done GameFile.Close(); } g_pUniverse->SetLogImageLoad(true); // Done return NOERROR; }
ALERROR CExtension::CreateBaseFile (SDesignLoadCtx &Ctx, EGameTypes iGame, CXMLElement *pDesc, CExternalEntityTable *pEntities, CExtension **retpBase, TArray<CXMLElement *> *retEmbedded) // CreateBaseFile // // Loads a new extension from the base file. { ALERROR error; int i; // Create an extension object CExtension *pExtension = new CExtension; pExtension->m_sFilespec = Ctx.sResDb; pExtension->m_dwUNID = 0; // Base is the only extension with 0 UNID. pExtension->m_iGame = iGame; pExtension->m_iType = extBase; pExtension->m_iLoadState = loadEntities; pExtension->m_iFolderType = folderBase; pExtension->m_pEntities = pEntities; pExtension->m_ModifiedTime = fileGetModifiedTime(Ctx.sResDb); pExtension->m_bRegistered = true; pExtension->m_bPrivate = true; pExtension->m_bAutoInclude = true; pExtension->m_bUsesXML = false; pExtension->m_bUsesCompatibilityLibrary = false; // Load the apiVersion CString sAPIVersion; if (pDesc->FindAttribute(API_VERSION_ATTRIB, &sAPIVersion)) { pExtension->m_dwAPIVersion = (DWORD)strToInt(sAPIVersion, 0); if (pExtension->m_dwAPIVersion < 12) pExtension->m_dwAPIVersion = 0; } // If this version is later than what we expect, then we fail. if (pExtension->m_dwAPIVersion > API_VERSION) { pExtension->m_pEntities = NULL; // Let our parent clean up delete pExtension; Ctx.sError = CONSTLIT("Newer version of the Transcendence engine is required."); return ERR_FAIL; } // We return the base extension *retpBase = pExtension; // Set up context Ctx.pExtension = pExtension; // Load the Main XML file for (i = 0; i < pDesc->GetContentElementCount(); i++) { CXMLElement *pItem = pDesc->GetContentElement(i); // <Images> if (strEquals(pItem->GetTag(), IMAGES_TAG)) error = pExtension->LoadImagesElement(Ctx, pItem); // <Sounds> else if (strEquals(pItem->GetTag(), SOUNDS_TAG)) error = pExtension->LoadSoundsElement(Ctx, pItem); // <SystemTypes> else if (strEquals(pItem->GetTag(), SYSTEM_TYPES_TAG)) error = pExtension->LoadSystemTypesElement(Ctx, pItem); // <TranscendenceAdventure> else if (strEquals(pItem->GetTag(), TRANSCENDENCE_ADVENTURE_TAG) || strEquals(pItem->GetTag(), TRANSCENDENCE_LIBRARY_TAG) || strEquals(pItem->GetTag(), CORE_LIBRARY_TAG)) { // Return this as an embedded extension retEmbedded->Insert(pItem); error = NOERROR; } // Other types else error = pExtension->LoadDesignElement(Ctx, pItem); // Check for error if (error) { pExtension->m_pEntities = NULL; // Let our parent clean up delete pExtension; return error; } } // Restore Ctx.pExtension = NULL; // Done pExtension->m_iLoadState = loadComplete; return NOERROR; }