void writeResponseTree() { outputFile.seek(dataOffset); const uint OFFSETS[3] = { 0x619520, 0x618340, 0x617380 }; for (int idx = 0; idx < 1022; ++idx) { inputFile.seek(OFFSETS[_version] - FILE_DIFF[_version] + idx * 8); uint id = inputFile.readLong(); uint offset = inputFile.readLong(); outputFile.writeLong(id); if (!id) { // An end of list id } else if (offset >= OFFSETS[_version] && offset <= (OFFSETS[_version] + 0x1FF0)) { // Offset to another table outputFile.writeByte(0); outputFile.writeLong((offset - OFFSETS[_version]) / 8); } else { // Offset to ASCIIZ string outputFile.writeByte(1); writeString(offset); } } uint size = outputFile.size() - dataOffset; writeEntryHeader("TEXT/TREE", dataOffset, size); dataOffset += size; }
void writeSoundNames(const char *sourceFilename, Common::File &target, uint offset) { Common::File source; if (!source.open(sourceFilename)) { error("Unable to open '%s'", sourceFilename); } source.seek(offset); // Count the sounds uint count = 0; while (1) { uint32 id = source.readUint32LE(); if (!id) break; source.skip(32); count++; } target.writeLong(count); source.seek(offset); for (uint i = 0; i < count; i++) { uint32 id = source.readUint32LE(); char name[32]; source.read(name, sizeof(name)); target.writeLong(id); target.write(name, sizeof(name)); } source.close(); }
int main(int argc, char *argv[]) { if (argc < 2) { printf("Usage: %s [exe folder]\n", argv[0]); printf("Where [exe folder] contains the following files:\n"); printf("- M3_EN_127.exe: English v1.27 Window binary from the DVD release\n"); printf("- M3_FR_122.exe: French v1.22 Window binary from the update patch\n"); printf("- M3_FR_122.exe: English v1.22 Window binary from the update patch\n"); printf("- M3_XBOX_PAL.xbe: PAL XBox binary\n"); printf("- M3_XBOX_NTSC.xbe: NTSC XBox binary\n"); return -1; } std::string path = argv[1]; std::string dvdExe = path + "M3_EN_127.exe"; std::string cdIntlExe = path + "M3_FR_122.exe"; std::string cdEnglishExe = path + "M3_EN_122.exe"; std::string xboxPalExe = path + "M3_XBOX_PAL.xbe"; std::string xboxNtscExe = path + "M3_XBOX_NTSC.xbe"; Common::File temp; if (!temp.open("data.tmp", Common::kFileWriteMode)) { error("Unable to open '%s'", "data.tmp"); } writeScriptData(dvdExe.c_str(), temp, roomScripts, ARRAYSIZE(roomScripts)); writeScriptData(dvdExe.c_str(), temp, menuScriptsDvd, ARRAYSIZE(menuScriptsDvd)); writeScriptData(cdIntlExe.c_str(), temp, menuScriptsCdIntl, ARRAYSIZE(menuScriptsCdIntl)); writeScriptData(cdEnglishExe.c_str(), temp, menuScriptsCdEnglish, ARRAYSIZE(menuScriptsCdEnglish)); writeScriptData(xboxPalExe.c_str(), temp, roomScriptsXBox, ARRAYSIZE(roomScriptsXBox)); writeScriptData(xboxPalExe.c_str(), temp, menuScriptsXboxIntl, ARRAYSIZE(menuScriptsXboxIntl)); writeScriptData(xboxNtscExe.c_str(), temp, menuScriptsXboxEnglish, ARRAYSIZE(menuScriptsXboxEnglish)); Common::File target; if (!target.open("myst3.dat", Common::kFileWriteMode)) { error("Unable to open '%s'", "myst3.dat"); } target.writeLong(MKTAG('M', 'Y', 'S', 'T')); target.writeLong(kVersion); writeScriptIndex(target, roomScripts, ARRAYSIZE(roomScripts)); writeScriptIndex(target, menuScriptsDvd, ARRAYSIZE(menuScriptsDvd)); writeScriptIndex(target, menuScriptsCdIntl, ARRAYSIZE(menuScriptsCdIntl)); writeScriptIndex(target, menuScriptsCdEnglish, ARRAYSIZE(menuScriptsCdEnglish)); writeScriptIndex(target, roomScriptsXBox, ARRAYSIZE(roomScriptsXBox)); writeScriptIndex(target, menuScriptsXboxIntl, ARRAYSIZE(menuScriptsXboxIntl)); writeScriptIndex(target, menuScriptsXboxEnglish, ARRAYSIZE(menuScriptsXboxEnglish)); writeSoundNames(dvdExe.c_str(), target, 549360); writeSoundNames(xboxPalExe.c_str(), target, 913960); copyData(temp, target); temp.close(); target.close(); return 0; }
void writeScriptIndex(Common::File &target, RoomScripts *scripts, uint scriptCount) { target.writeLong(scriptCount); for (uint i = 0; i < scriptCount; i++) { target.writeString(scripts[i].room); target.writeLong(scripts[i].type); target.writeLong(scripts[i].targetOffset); target.writeLong(scripts[i].size); } }
void writeEntryHeader(const char *name, uint offset, uint size) { assert(headerOffset < HEADER_SIZE); outputFile.seek(headerOffset); outputFile.writeLong(offset); outputFile.writeLong(size); outputFile.writeString(name); headerOffset += 8 + strlen(name) + 1; }
void writeBedheadGroup(const BedheadEntry *data, int count) { for (int idx = 0; idx < count; ++idx, ++data) { outputFile.writeString(data->_name1); outputFile.writeString(data->_name2); outputFile.writeString(data->_name3); outputFile.writeString(data->_name4); outputFile.writeLong(data->_startFrame); outputFile.writeLong(data->_endFrame); } }
void writeBarbotFrameRanges() { outputFile.seek(dataOffset); for (int idx = 0; idx < 60; ++idx) { outputFile.writeLong(BARBOT_FRAME_RANGES[idx]._startFrame); outputFile.writeLong(BARBOT_FRAME_RANGES[idx]._endFrame); } uint size = outputFile.size() - dataOffset; writeEntryHeader("FRAMES/BARBOT", dataOffset, size); dataOffset += size; }
void writePhrases(const char *name, const CommonPhrase *phrases) { for (uint idx = 0; phrases->_str; ++idx, ++phrases) { outputFile.seek(dataOffset + idx * 4); outputFile.writeString(phrases->_str); outputFile.writeLong(phrases->_dialogueId); outputFile.writeLong(phrases->_roomNum); outputFile.writeLong(phrases->_val1); } uint size = outputFile.size() - dataOffset; writeEntryHeader("Phrases/Bellbot", dataOffset, size); dataOffset += size; }
void writeSentenceMappings(const char *name, uint offset, int numValues) { inputFile.seek(offset - FILE_DIFF[_version]); outputFile.seek(dataOffset); uint id; while ((id = inputFile.readLong()) != 0) { outputFile.writeLong(id); for (int ctr = 0; ctr < numValues; ++ctr) outputFile.writeLong(inputFile.readLong()); } uint size = outputFile.size() - dataOffset; writeEntryHeader(name, dataOffset, size); dataOffset += size; }
void writeBitmap(const char *name, Common::File *file) { outputFile.seek(dataOffset); // Write out the necessary bitmap header so that the ScummVM // BMP decoder can properly handle decoding the bitmaps outputFile.write("BM", 2); outputFile.writeLong(file->size() + 14); // Filesize outputFile.writeLong(0); // res1 & res2 outputFile.writeLong(0x436); // image offset outputFile.write(*file, file->size()); writeEntryHeader(name, dataOffset, file->size() + 14); dataOffset += file->size() + 14; delete file; }
void writeSentenceEntries(const char *name, uint tableOffset) { outputFile.seek(dataOffset); uint v1, v2, v9, v11, v12, v13; uint offset3, offset5, offset6, offset7, offset8, offset10; for (uint idx = 0; ; ++idx) { inputFile.seek(tableOffset - FILE_DIFF[_version] + idx * 0x34); v1 = inputFile.readLong(); if (!v1) // Reached end of list break; // Read data fields v2 = inputFile.readLong(); offset3 = inputFile.readLong(); /* v4 = */inputFile.readLong(); offset5 = inputFile.readLong(); offset6 = inputFile.readLong(); offset7 = inputFile.readLong(); offset8 = inputFile.readLong(); v9 = inputFile.readLong(); offset10 = inputFile.readLong(); v11 = inputFile.readLong(); v12 = inputFile.readLong(); v13 = inputFile.readLong(); outputFile.writeLong(v1); outputFile.writeLong(v2); writeString(offset3); outputFile.writeLong(v1); writeString(offset5); writeString(offset6); writeString(offset7); writeString(offset8); outputFile.writeLong(v9); writeString(offset10); outputFile.writeLong(v11); outputFile.writeLong(v12); outputFile.writeLong(v13); } uint size = outputFile.size() - dataOffset; writeEntryHeader(name, dataOffset, size); dataOffset += size; }
void writeNumbers() { outputFile.seek(dataOffset); // Iterate through writing each string for (int idx = 0; idx < 76; ++idx) { outputFile.writeString(NUMBERS[idx]._text); outputFile.writeLong(NUMBERS[idx]._value); outputFile.writeLong(NUMBERS[idx]._flags); } uint size = outputFile.size() - dataOffset; writeEntryHeader("TEXT/NUMBERS", dataOffset, size); dataOffset += size; }
void writeStarfieldPoints2() { outputFile.seek(dataOffset); const int OFFSETS[3] = { 0x5A2F28, 0x5A2CC8, 0x5A1CF8 }; for (int rootCtr = 0; rootCtr < 80; ++rootCtr) { inputFile.seek(OFFSETS[_version] - FILE_DIFF[_version] + rootCtr * 8); uint offset = inputFile.readUint32LE(); uint count = inputFile.readUint32LE(); outputFile.writeLong(count); inputFile.seek(offset - FILE_DIFF[_version]); outputFile.write(inputFile, count * 4 * 4); } uint size = outputFile.size() - dataOffset; outputFile.write(inputFile, size); writeEntryHeader("STARFIELD/POINTS2", dataOffset, size); dataOffset += size; }
void writeWords(const char *name, uint tableOffset, int recordCount = 2) { outputFile.seek(dataOffset); int recordSize = recordCount * 4; uint val, strOffset; for (uint idx = 0; ; ++idx) { inputFile.seek(tableOffset - FILE_DIFF[_version] + idx * recordSize); val = inputFile.readLong(); strOffset = inputFile.readLong(); if (!val) // Reached end of list break; outputFile.writeLong(val); writeString(strOffset); } uint size = outputFile.size() - dataOffset; writeEntryHeader(name, dataOffset, size); dataOffset += size; }
void writeFinalEntryHeader() { assert(headerOffset <= (HEADER_SIZE - 8)); outputFile.seek(headerOffset); outputFile.writeLong(0); outputFile.writeLong(0); }