ALERROR WriteSubModules (CTDBCompiler &Ctx, CXMLElement *pModule, const CString &sFolder, CDataFile &Out) { int i, j; for (i = 0; i < pModule->GetContentElementCount(); i++) { CXMLElement *pItem = pModule->GetContentElement(i); if (strEquals(pItem->GetTag(), TAG_MODULES)) { for (j = 0; j < pItem->GetContentElementCount(); j++) { CXMLElement *pDesc = pItem->GetContentElement(j); CString sFilename = pDesc->GetAttribute(ATTRIB_FILENAME); if (WriteModule(Ctx, sFilename, sFolder, Out) != NOERROR) continue; } } else if (strEquals(pItem->GetTag(), TAG_MODULE)) { CString sFilename = pItem->GetAttribute(ATTRIB_FILENAME); if (WriteModule(Ctx, sFilename, sFolder, Out) != NOERROR) continue; } } 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; }
void TransCompiler (CXMLElement *pCmdLine) // TransCompiler // // Compile the Transcendence game and resource files // // <TransCompiler // input="{input filespec}" // output="{output filespec}" // /> { ALERROR error; printf("TransCompiler v1.0\n"); printf("Copyright (c) 2003 by Neurohack, Inc. All Rights Reserved.\n\n"); if (pCmdLine->GetAttributeBool(NOARGS) || pCmdLine->GetAttributeBool(SWITCH_HELP)) { printf(" /input:{input filespec}\n"); printf(" /output:{output filespec}\n"); printf("\n"); return; } // Figure out the folder for the input filespec. All filenames will // be relative to this root. CString sInputFilespec = pCmdLine->GetAttribute(ATTRIB_INPUT); if (sInputFilespec.IsBlank()) sInputFilespec = CONSTLIT("Transcendence.xml"); CString sRoot = pathGetPath(sInputFilespec); // Figure out the output filespec CString sOutputFilespec = pCmdLine->GetAttribute(ATTRIB_OUTPUT); if (sOutputFilespec.IsBlank()) sOutputFilespec = CONSTLIT("Transcendence.tdb"); // Create the output file if (error = CDataFile::Create(sOutputFilespec, 4096, 0)) { printf("Unable to create '%s'\n", sOutputFilespec.GetASCIIZPointer()); return; } CDataFile Out(sOutputFilespec); if (error = Out.Open()) { printf("Unable to open '%s'\n", sOutputFilespec.GetASCIIZPointer()); return; } // Prepare a symbol table to hold all the resource files CSymbolTable Resources(FALSE, TRUE); // Write out the main module and recurse int iGameFile; if (error = WriteModule(sInputFilespec, NULL_STR, NULL, Resources, Out, &iGameFile)) return; // Write out the header if (error = WriteHeader(iGameFile, Resources, Out)) return; // Done Out.Close(); }
void CreateTDB (const CString &sInputFilespec, CXMLElement *pCmdLine) { ALERROR error; CString sError; int i; // Prepare a context block CTDBCompiler Ctx; // Figure out the output filespec CString sOutputFilespec = pCmdLine->GetAttribute(ATTRIB_OUTPUT); if (sOutputFilespec.IsBlank() && !sInputFilespec.IsBlank()) sOutputFilespec = strPatternSubst(CONSTLIT("%s.tdb"), pathStripExtension(pathGetFilename(sInputFilespec))); // Optional entities file. CString sEntities = pCmdLine->GetAttribute(ATTRIB_ENTITIES); TArray<CString> EntityFilespecs; if (strDelimitEx(sEntities, ',', DELIMIT_TRIM_WHITESPACE, 0, &EntityFilespecs) != NOERROR) { printf("error : Unable to parse list of entity filespecs.\n"); return; } // Initialize our compiler. if (!Ctx.Init(sInputFilespec, sOutputFilespec, EntityFilespecs, pCmdLine, &sError)) { printf("error: %s.\n", sError.GetASCIIZPointer()); return; } // Create the output file if (error = CDataFile::Create(sOutputFilespec, 4096, 0)) { printf("error : Unable to create '%s'\n", sOutputFilespec.GetASCIIZPointer()); return; } CDataFile Out(sOutputFilespec); if (error = Out.Open()) { printf("error : Unable to open '%s'\n", sOutputFilespec.GetASCIIZPointer()); return; } // Write out the main module and recurse int iGameFile; if (error = WriteModule(Ctx, pathGetFilename(sInputFilespec), NULL_STR, Out, &iGameFile)) goto Done; // Write out the header if (error = WriteHeader(Ctx, iGameFile, Out)) goto Done; // Done with the file Out.Close(); // If necessary create a digest if (pCmdLine->GetAttributeBool(ATTRIB_DIGEST)) { CIntegerIP Digest; if (fileCreateDigest(sOutputFilespec, &Digest) != NOERROR) { Ctx.ReportError(strPatternSubst(CONSTLIT("Unable to create digest for '%s'."), sOutputFilespec)); goto Done; } // Output C++ style constant printf("\nstatic BYTE g_Digest[] =\n\t{"); BYTE *pDigest = Digest.GetBytes(); for (i = 0; i < Digest.GetLength(); i++) { if ((i % 10) == 0) printf("\n\t"); printf("%3d, ", (DWORD)pDigest[i]); } printf("\n\t};\n"); } Done: Ctx.ReportErrorCount(); }
ALERROR WriteModule (const CString &sFilename, const CString &sFolder, CExternalEntityTable *pEntityTable, CSymbolTable &Resources, CDataFile &Out, int *retiModuleEntry) { ALERROR error; int i; // Parse the file CXMLElement *pModule; CExternalEntityTable EntityTable; if (pEntityTable) { CFileReadBlock DataFile(sFilename); CString sError; printf("Parsing %s...", sFilename.GetASCIIZPointer()); if (error = CXMLElement::ParseXML(&DataFile, pEntityTable, &pModule, &sError)) { printf("\n%s\n", sError.GetASCIIZPointer()); return error; } printf("done.\n"); } else { CFileReadBlock DataFile(sFilename); CString sError; printf("Parsing %s...", sFilename.GetASCIIZPointer()); if (error = CXMLElement::ParseXML(&DataFile, &pModule, &sError, &EntityTable)) { printf("\n%s\n", sError.GetASCIIZPointer()); return error; } pEntityTable = &EntityTable; printf("done.\n"); } // Write the module itself int iEntry; if (error = WriteGameFile(sFilename, 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) Resources.AddEntry(sFilename, (CObject *)iEntry); // Store all the image resources if (error = WriteModuleImages(pModule, sFolder, Resources, Out)) return error; // Store all the sound resources if (error = WriteModuleSounds(pModule, sFolder, Resources, Out)) return error; // Store all modules CXMLElement *pModules = pModule->GetContentElementByTag(TAG_MODULES); if (pModules) { for (i = 0; i < pModules->GetContentElementCount(); i++) { CXMLElement *pItem = pModules->GetContentElement(i); CString sFilename = pItem->GetAttribute(ATTRIB_FILENAME); if (error = WriteModule(sFilename, sFolder, pEntityTable, Resources, Out, NULL)) continue; } } // Done if (retiModuleEntry) *retiModuleEntry = iEntry; return NOERROR; }