diff options
author | Johannes Schickel | 2009-09-17 02:25:55 +0000 |
---|---|---|
committer | Johannes Schickel | 2009-09-17 02:25:55 +0000 |
commit | c5ec398bbf5202569dba8d3904416548f49a9452 (patch) | |
tree | fcf7f86cc0a0ddc0b61e49802582e817cb9934e4 | |
parent | 8aa04a8b9dfca7934bf9de41b67b2d38dcd13bd0 (diff) | |
download | scummvm-rg350-c5ec398bbf5202569dba8d3904416548f49a9452.tar.gz scummvm-rg350-c5ec398bbf5202569dba8d3904416548f49a9452.tar.bz2 scummvm-rg350-c5ec398bbf5202569dba8d3904416548f49a9452.zip |
Move extraction functionality to new file "extract.cpp".
svn-id: r44133
-rw-r--r-- | tools/create_kyradat/create_kyradat.cpp | 783 | ||||
-rw-r--r-- | tools/create_kyradat/extract.cpp | 806 | ||||
-rw-r--r-- | tools/create_kyradat/module.mk | 1 |
3 files changed, 807 insertions, 783 deletions
diff --git a/tools/create_kyradat/create_kyradat.cpp b/tools/create_kyradat/create_kyradat.cpp index 9cc4dd95d0..23c0f5fd97 100644 --- a/tools/create_kyradat/create_kyradat.cpp +++ b/tools/create_kyradat/create_kyradat.cpp @@ -62,10 +62,6 @@ bool extractRaw16(PAKFile &out, const Game *g, const byte *data, const uint32 si bool extractRaw32(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch); bool extractLolButtonDefs(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch); -int extractHofSeqData_checkString(const void *ptr, uint8 checkSize); -int extractHofSeqData_isSequence(const void *ptr, const Game *g, uint32 maxCheckSize); -int extractHofSeqData_isControl(const void *ptr, uint32 size); - void createFilename(char *dstFilename, const int gid, const int lang, const int special, const char *filename); void createLangFilename(char *dstFilename, const int gid, const int lang, const int special, const char *filename); @@ -414,785 +410,6 @@ void createLangFilename(char *dstFilename, const int gid, const int lang, const } } -// extraction - -bool extractRaw(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { - uint8 *buffer = new uint8[size]; - assert(buffer); - memcpy(buffer, data, size); - - return out.addFile(filename, buffer, size); -} - -bool extractStrings(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { - uint32 entries = 0; - uint32 targetsize = size + 4; - for (uint32 i = 0; i < size; ++i) { - if (!data[i]) { - if (g->special == kAmigaVersion) { - if (i + 1 >= size) - ++entries; - else if (!data[i+1] && !(i & 1)) - continue; - else - ++entries; - } else { - ++entries; - } - - if (g->special == kFMTownsVersionE || g->special == kFMTownsVersionJ || - g->special == k2TownsFile1E || g->special == k2TownsFile1J || - g->special == k2TownsFile2E || g->special == k2TownsFile2J) { - // prevents creation of empty entries (which we have mostly between all strings in the FM-TOWNS version) - while (!data[++i]) { - if (i == size) - break; - targetsize--; - } - if (fmtPatch == 1) { - // Here is the first step of the extra treatment for all FM-TOWNS string arrays that - // contain more than one string and which the original code - // addresses via stringname[boolJapanese]. - // We simply skip every other string - if (i == size) - continue; - uint32 len = strlen((const char*) data + i); - i += len; - - targetsize = targetsize - 1 - len; - - while (!data[++i]) { - if (i == len) - break; - targetsize--; - } - } - } - } - } - - if (fmtPatch == 2) { - if (g->special == kFMTownsVersionE) { - targetsize--; - entries += 1; - } else if (g->special == kFMTownsVersionJ) { - targetsize += 2; - entries += 2; - } - } - - if (fmtPatch == 3) { - entries++; - targetsize++; - } - - if (fmtPatch == 4) { - targetsize -= 9; - } - - uint8 *buffer = new uint8[targetsize]; - assert(buffer); - memset(buffer, 0, targetsize); - uint8 *output = buffer; - const uint8 *input = (const uint8*) data; - - WRITE_BE_UINT32(output, entries); output += 4; - if (g->special == kFMTownsVersionE || g->special == kFMTownsVersionJ || - g->special == k2TownsFile1E || g->special == k2TownsFile1J || - g->special == k2TownsFile2E || g->special == k2TownsFile2J) { - const byte *c = data + size; - do { - if (fmtPatch == 2 && input - data == 0x3C0 && input[0x10] == 0x32) { - memcpy(output, input, 0x0F); - input += 0x11; output += 0x0F; - } - - strcpy((char*) output, (const char*) input); - uint32 stringsize = strlen((const char*)output) + 1; - input += stringsize; output += stringsize; - // skip empty entries - while (!*input) { - // Write one empty string into intro strings file - if (fmtPatch == 2) { - if ((g->special == kFMTownsVersionE && input - data == 0x260) || - (g->special == kFMTownsVersionJ && input - data == 0x2BD) || - (g->special == kFMTownsVersionJ && input - data == 0x2BE)) - *output++ = *input; - } - - // insert one dummy string at hof sequence strings position 59 - if (fmtPatch == 3) { - if ((g->special == k2TownsFile1E && input - data == 0x695) || - (g->special == k2TownsFile1J && input - data == 0x598)) - *output++ = *input; - } - - if (++input == c) - break; - } - - if (fmtPatch == 1) { - // Here is the extra treatment for all FM-TOWNS string arrays that - // contain more than one string and which the original code - // addresses via stringname[boolJapanese]. - // We simply skip every other string - if (input == c) - continue; - input += strlen((const char*)input); - while (!*input) { - if (++input == c) - break; - } - } - - } while (input < c); - } else if (g->special == kAmigaVersion) { - // we need to strip some aligment zeros out here - int dstPos = 0; - for (uint32 i = 0; i < size; ++i) { - if (!data[i] && !(i & 1)) { - if (i + 1 > size) - continue; - else if (i + 1 < size && !data[i+1]) - continue; - } - - *output++ = data[i]; - ++dstPos; - } - targetsize = dstPos + 4; - } else { - uint32 copySize = size; - if (fmtPatch == 4) { - memcpy(output, data, 44); - output += 44; - data += 44; - for (int t = 1; t != 10; t++) { - sprintf((char*) output, "COST%d_SH.PAK", t); - output += 13; - } - data += 126; - copySize -= 170; - } - memcpy(output, data, copySize); - } - - return out.addFile(filename, buffer, targetsize); -} - -bool extractStrings10(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { - const int strSize = 10; - uint32 entries = (size + (strSize - 1)) / strSize; - uint32 targetSize = 4; - - uint8 *buffer = new uint8[size + 4]; - assert(buffer); - uint8 *output = buffer; - WRITE_BE_UINT32(output, entries); output += 4; - - for (uint32 i = 0; i < entries; ++i) { - const byte *src = data + i * strSize; - - while (*src) - *output++ = *src++; - *output++ = '\0'; - } - - return out.addFile(filename, buffer, output - buffer); -} - -bool extractRooms(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { - // different entry size for the FM-TOWNS version - const int roomEntrySize = (g->special == kFMTownsVersionE || g->special == kFMTownsVersionJ) ? (0x69) : ((g->special == kAmigaVersion) ? 0x52 : 0x51); - const int countRooms = size / roomEntrySize; - - uint8 *buffer = new uint8[countRooms * 9 + 4]; - assert(buffer); - uint8 *output = buffer; - - WRITE_BE_UINT32(output, countRooms); output += 4; - - const byte *src = data; - if (g->special == kAmigaVersion) { - for (int i = 0; i < countRooms; ++i) { - *output++ = *src++; assert(*src == 0); ++src; - memcpy(output, src, 8); output += 0x8; - src += roomEntrySize - 0x2; - } - } else { - for (int i = 0; i < countRooms; ++i) { - *output++ = *src++; - WRITE_BE_UINT16(output, READ_LE_UINT16(src)); output += 2; src += 2; - WRITE_BE_UINT16(output, READ_LE_UINT16(src)); output += 2; src += 2; - WRITE_BE_UINT16(output, READ_LE_UINT16(src)); output += 2; src += 2; - WRITE_BE_UINT16(output, READ_LE_UINT16(src)); output += 2; src += 2; - src += roomEntrySize - 0x9; - } - } - - return out.addFile(filename, buffer, countRooms * 9 + 4); -} - -bool extractShapes(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { - byte *buffer = new byte[size + 1 * 4]; - assert(buffer); - byte *output = buffer; - - const int count = size / 0x07; - WRITE_BE_UINT32(output, count); output += 4; - memcpy(output, data, size); - - return out.addFile(filename, buffer, size + 1 * 4); -} - -bool extractAmigaSfx(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { - const uint32 entries = size / 8; - byte *buffer = new byte[entries * 6 + 1 * 4]; - - byte *output = buffer; - WRITE_BE_UINT32(output, entries); output += 4; - - for (uint32 i = 0; i < entries; ++i) { - *output++ = *data++; // Note - *output++ = *data++; // Patch - data += 2; // Unused - WRITE_BE_UINT16(output, READ_BE_UINT16(data)); output += 2; data += 2; // Duration - *output++ = *data++; // Volume - *output++ = *data++; // Pan - } - - return out.addFile(filename, buffer, entries * 6 + 1 * 4); -} - -bool extractWdSfx(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { - const int bufferSize = 0x12602; - - uint8 *buffer = new uint8[0x12602]; - assert(buffer); - memcpy(buffer, data, 0x7EE5); - memcpy(buffer + 0x7EE5, data + 0x7EE7, 0x7FFF); - memcpy(buffer + 0xFEE4, data + 0xFEE8, 0x271E); - - return out.addFile(filename, buffer, bufferSize); -} - -bool extractHofSeqData(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { - int numSequences = 0; - int numNestedSequences = 0; - - uint16 headerSize = 50 * sizeof(uint16); - uint16 bufferSize = size + headerSize; - byte *buffer = new byte[bufferSize]; - assert(buffer); - memset(buffer, 0, bufferSize ); - uint16 *header = (uint16*) buffer; - byte *output = buffer + headerSize; - uint16 *hdout = header; - - //debug(1, "\nProcessing Hand of Fate sequence data:\n--------------------------------------\n"); - for (int cycle = 0; cycle < 2; cycle++) { - const byte *ptr = data; - hdout++; - - const byte * endOffs = (const byte *)(data + size); - - // detect sequence structs - while (ptr < endOffs) { - if (ptr[1]) { - error("invalid sequence data encountered"); - delete[] buffer; - return false; - } - - int v = extractHofSeqData_isSequence(ptr, g, endOffs - ptr); - - if (cycle == 0 && v == 1) { - if ((g->special == k2FloppyFile1 && *ptr == 5) || (g->special == k2DemoVersion && (ptr - data == 312))) { - // patch for floppy version: skips invalid ferb sequence - // patch for demo: skips invalid title sequence - ptr += 54; - continue; - } - - numSequences++; - uint16 relOffs = (uint16) (output - buffer); - WRITE_BE_UINT16(hdout, relOffs); - hdout++; - - WRITE_BE_UINT16(output, READ_LE_UINT16(ptr)); // flags - ptr += 2; - output += 2; - - memcpy(output, ptr, 28); // wsa and cps file names - ptr += 28; - output += 28; - - if (g->special == k2TownsFile1E) { // startupCommand + finalCommand - memcpy(output , ptr, 2); - ptr += 2; - output += 2; - } else { - *output++ = READ_LE_UINT16(ptr) & 0xff; - ptr += 2; - *output++ = READ_LE_UINT16(ptr) & 0xff; - ptr += 2; - } - - for (int w = 0; w < 7; w++) { //stringIndex1 to yPos - WRITE_BE_UINT16(output, READ_LE_UINT16(ptr)); - ptr += 2; - output += 2; - } - - ptr += 4; - WRITE_BE_UINT16(output, READ_LE_UINT16(ptr)); // duration - ptr += 2; - output+= 2; - - } else if (cycle == 1 && v != 1 && v != -2) { - uint16 controlOffs = 0; - uint16 ctrSize = 0; - if (v) { - const byte *ctrStart = ptr; - while (v && v != -2) { - ptr++; - v = extractHofSeqData_isSequence(ptr, g, endOffs - ptr); - } - - if (v == -2) - break; - - ctrSize = (uint16)(ptr - ctrStart); - - if (g->special != k2DemoVersion && - extractHofSeqData_isControl(ctrStart, ctrSize)) { - controlOffs = (uint16) (output - buffer); - *output++ = ctrSize >> 2; - - for (int cc = 0; cc < ctrSize; cc += 2) - WRITE_BE_UINT16(output + cc, READ_LE_UINT16(ctrStart + cc)); // frame control - output += ctrSize; - } - } - - numNestedSequences++; - uint16 relOffs = (uint16) (output - buffer); - WRITE_BE_UINT16(hdout, relOffs); - hdout++; - - WRITE_BE_UINT16(output, READ_LE_UINT16(ptr)); // flags - ptr += 2; - output += 2; - - memcpy(output, ptr, 14); // wsa file name - ptr += 14; - output += 14; - - // startframe - WRITE_BE_UINT16(output, READ_LE_UINT16(ptr)); - ptr += 2; - output += 2; - - // endFrame - WRITE_BE_UINT16(output, (ctrSize && ((ctrSize >> 2) < READ_LE_UINT16(ptr))) ? (ctrSize >> 2) : READ_LE_UINT16(ptr)); - ptr += 2; - output += 2; - - // frameDelay - WRITE_BE_UINT16(output, READ_LE_UINT16(ptr)); - ptr += 2; - output += 2; - - ptr += 4; - - for (int w = 0; w < 2; w++) { //x, y - WRITE_BE_UINT16(output, READ_LE_UINT16(ptr)); - ptr += 2; - output += 2; - } - - if (!READ_LE_UINT32(ptr)) - controlOffs = 0; - - WRITE_BE_UINT16(output, controlOffs); - if (g->special != k2DemoVersion && g->special != k2DemoLol) - ptr += 4; - output += 2; - - if (g->special != k2DemoVersion && g->special != k2DemoLol) { - for (int w = 0; w < 2; w++) { //startupCommand, finalCommand - WRITE_BE_UINT16(output, READ_LE_UINT16(ptr)); - ptr += 2; - output += 2; - } - } else { - memset(output, 0, 4); - output += 4; - } - - if (g->special == k2TownsFile1E) - ptr += 2; - - } else if (cycle == 0) { - while (v != 1 && v != -2) { - ptr++; - v = extractHofSeqData_isSequence(ptr, g, endOffs - ptr); - } - - if (v == -2) - break; - - - } else if (cycle == 1) { - while (v == 1 && v != -2) { - ptr++; - v = extractHofSeqData_isSequence(ptr, g, endOffs - ptr); - } - - if (v == -2) - break; - } - } - } - - uint16 finHeaderSize = (2 + numSequences + numNestedSequences) * sizeof(uint16); - uint16 finBufferSize = ((output - buffer) - headerSize) + finHeaderSize; - byte *finBuffer = new byte[finBufferSize]; - assert(finBuffer); - uint16 diff = headerSize - finHeaderSize; - uint16 *finHeader = (uint16*) finBuffer; - - for (int i = 1; i < finHeaderSize; i++) - WRITE_BE_UINT16(&finHeader[i], (READ_BE_UINT16(&header[i]) - diff)); - WRITE_BE_UINT16(finHeader, numSequences); - WRITE_BE_UINT16(&finHeader[numSequences + 1], numNestedSequences); - memcpy (finBuffer + finHeaderSize, buffer + headerSize, finBufferSize - finHeaderSize); - delete[] buffer; - - finHeader = (uint16*) (finBuffer + ((numSequences + 2) * sizeof(uint16))); - for (int i = 0; i < numNestedSequences; i++) { - uint8 * offs = finBuffer + READ_BE_UINT16(finHeader++) + 26; - uint16 ctrl = READ_BE_UINT16(offs); - if (ctrl) - ctrl -= diff; - WRITE_BE_UINT16(offs, ctrl); - } - - return out.addFile(filename, finBuffer, finBufferSize); -} - -int extractHofSeqData_checkString(const void *ptr, uint8 checkSize) { - // return values: 1 = text; 0 = zero string; -1 = other - - int t = 0; - int c = checkSize; - const uint8 *s = (const uint8*)ptr; - - // check for character string - while (c--) { - if (*s > 31 && *s < 123) - t++; - s++; - } - - if (t == checkSize) - return 1; - - // check for zero string - c = checkSize; - uint32 sum = 0; - s = (const uint8*)ptr; - while (c--) - sum += *s++; - - return (sum) ? -1 : 0; -} - -int extractHofSeqData_isSequence(const void *ptr, const Game *g, uint32 maxCheckSize) { - // return values: 1 = Sequence; 0 = Nested Sequence; -1 = other; -2 = overflow - - if (maxCheckSize < 30) - return -2; - - const uint8 * s = (const uint8*)ptr; - int c1 = extractHofSeqData_checkString(s + 2, 6); - int c2 = extractHofSeqData_checkString(s + 16, 6); - int c3 = extractHofSeqData_checkString(s + 2, 14); - int c4 = extractHofSeqData_checkString(s + 16, 14); - int c0 = s[1]; - int c5 = s[0]; - - if (c0 == 0 && c5 && ((c1 + c2) >= 1) && (!(c3 == 0 && c2 != 1)) && (!(c4 == 0 && c1 != 1))) { - if (maxCheckSize < 41) - return -2; - - if (g->special == k2TownsFile1E) { - if (!(s[37] | s[39]) && s[38] > s[36]) - return 1; - } else { - if (!(s[39] | s[41]) && s[40] > s[38]) - return 1; - } - } - - if (c0 == 0 && c5 == 4 && c3 == 0 && c4 == 0) { - if (maxCheckSize >= 41 && READ_LE_UINT32(s + 34) && !(s[39] | s[41]) && s[40] > s[38]) - return 1; - } - - if (c0 == 0 && c5 && c1 == 1 && c4 == -1 && s[20]) - return 0; - - return -1; -} - -int extractHofSeqData_isControl(const void *ptr, uint32 size) { - // return values: 1 = possible frame control data; 0 = definitely not frame control data - - const uint8 *s = (const uint8*)ptr; - for (uint32 i = 2; i < size; i += 4) { - if (!s[i]) - return 0; - } - - for (uint32 i = 1; i < size; i += 2) { - if (s[i]) - return 0; - } - return 1; -} - -bool extractHofShapeAnimDataV1(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { - int outsize = 1; - uint8 *buffer = new uint8[size + 1]; - const uint8 *src = data; - uint8 *dst = buffer + 1; - - for (int i = 0; i < 4; i++) { - WRITE_BE_UINT16(dst, READ_LE_UINT16(src)); - src += 2; - dst += 2; - WRITE_BE_UINT16(dst, READ_LE_UINT16(src)); - src += 4; - dst += 2; - outsize += 4; - - for (int j = 0; j < 20; j++) { - WRITE_BE_UINT16(dst, READ_LE_UINT16(src)); - src += 2; - dst += 2; - outsize += 2; - } - - }; - - *buffer = 4; // number of items - - return out.addFile(filename, buffer, outsize); -} - -bool extractHofShapeAnimDataV2(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { - int outsize = 1; - uint8 *buffer = new uint8[size + 1]; - const uint8 *src = data; - uint8 *dst = buffer + 1; - const uint8 *fin = data + size; - int count = 0; - - do { - if (READ_LE_UINT16(src) == 0xffff) - break; - - count++; - - WRITE_BE_UINT16(dst, READ_LE_UINT16(src)); - src += 2; - dst += 2; - - uint8 numFrames = *src; - *dst++ = numFrames; - src += 6; - outsize += 3; - - for (int i = 0; i < (numFrames << 1); i++) { - WRITE_BE_UINT16(dst, READ_LE_UINT16(src)); - src += 2; - dst += 2; - outsize += 2; - } - - src += (48 - (numFrames << 2)); - - } while (src < fin); - - *buffer = count; // number of items - - return out.addFile(filename, buffer, outsize); -} - -bool extractStringsWoSuffix(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { - int outsize = size + 4; - uint8 *buffer = new uint8[outsize]; - const uint8 *src = data; - uint8 *dst = buffer + 4; - const uint8 *fin = src + size; - int entries = 0; - - while (src < fin) { - while (!*src && src < fin) - src++; - while (*src && *src != '.' && src < fin) - *dst++ = *src++; - - *dst++ = '\0'; - entries++; - - if (*src == '.') { - while (*src && src < fin) - src++; - } - } - - WRITE_BE_UINT32(buffer, entries); - outsize = dst - buffer; - - return out.addFile(filename, buffer, outsize); -} - -bool extractPaddedStrings(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { - int outsize = size + 4; - uint8 *buffer = new uint8[outsize]; - const uint8 *src = data; - uint8 *dst = buffer + 4; - const uint8 *fin = src + size; - int entries = 0; - - while (src < fin) { - while (!*src && src < fin) - src++; - while (*src && src < fin) - *dst++ = *src++; - - *dst++ = '\0'; - entries++; - } - - WRITE_BE_UINT32(buffer, entries); - outsize = dst - buffer; - - return out.addFile(filename, buffer, outsize); -} - -bool extractRaw16to8(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { - int outsize = size >> 1; - uint8 *buffer = new uint8[outsize]; - const uint8 *src = data; - uint8 *dst = buffer; - - for (int i = 0; i < outsize; i++) { - *dst++ = *src++; - *src++; - } - - return out.addFile(filename, buffer, outsize); -} - -bool extractRaw16(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { - uint8 *buffer = new uint8[size]; - const uint8 *src = data; - uint8 *dst = buffer; - - for (uint32 i = 0; i < (size >> 1); i++) { - WRITE_BE_UINT16(dst, READ_LE_UINT16(src)); - src += 2; - dst += 2; - } - - return out.addFile(filename, buffer, size); -} - -bool extractRaw32(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { - uint8 *buffer = new uint8[size]; - const uint8 *src = data; - uint8 *dst = buffer; - - for (uint32 i = 0; i < (size >> 2); i++) { - WRITE_BE_UINT32(dst, READ_LE_UINT32(src)); - src += 4; - dst += 4; - } - - return out.addFile(filename, buffer, size); -} - -bool extractLolButtonDefs(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { - int num = size / 22; - uint8 *buffer = new uint8[size]; - uint32 outsize = num * 18; - const uint8 *src = data; - uint8 *dst = buffer; - - for (int i = 0; i < num; i++) { - WRITE_BE_UINT16(dst, READ_LE_UINT16(src)); - src += 2; dst += 2; - WRITE_BE_UINT16(dst, READ_LE_UINT16(src)); - src += 2; dst += 2; - WRITE_BE_UINT16(dst, READ_LE_UINT16(src)); - src += 6; dst += 2; - WRITE_BE_UINT16(dst, READ_LE_UINT16(src)); - src += 2; dst += 2; - WRITE_BE_UINT16(dst, READ_LE_UINT16(src)); - src += 2; dst += 2; - WRITE_BE_UINT16(dst, READ_LE_UINT16(src)); - src += 2; dst += 2; - WRITE_BE_UINT16(dst, READ_LE_UINT16(src)); - src += 2; dst += 2; - WRITE_BE_UINT16(dst, READ_LE_UINT16(src)); - src += 2; dst += 2; - WRITE_BE_UINT16(dst, READ_LE_UINT16(src)); - src += 2; dst += 2; - } - - return out.addFile(filename, buffer, outsize); -} - -bool extractMrShapeAnimData(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { - int outsize = 1; - uint8 *buffer = new uint8[size + 1]; - const uint8 *src2 = data; - const uint8 *src1 = data + 324; - uint8 *dst = buffer + 1; - const uint8 *fin = data + size; - int count = 0; - - do { - if (READ_LE_UINT16(src1) == 0xffff) - break; - - count++; - - WRITE_BE_UINT16(dst, READ_LE_UINT16(src1)); - src1 += 2; - dst += 2; - - uint8 numFrames = *src1; - *dst++ = numFrames; - src1 += 10; - outsize += 3; - - for (int i = 0; i < (numFrames << 1); i++) { - WRITE_BE_UINT16(dst, READ_LE_UINT16(src2)); - src2 += 2; - dst += 2; - outsize += 2; - } - } while (src1 < fin); - - *buffer = count; // number of items - - return out.addFile(filename, buffer, outsize); -} - // index generation enum { diff --git a/tools/create_kyradat/extract.cpp b/tools/create_kyradat/extract.cpp new file mode 100644 index 0000000000..7584ef7093 --- /dev/null +++ b/tools/create_kyradat/extract.cpp @@ -0,0 +1,806 @@ +/* ScummVM Tools + * Copyright (C) 2009 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + + +#include "create_kyradat.h" + +bool extractRaw(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { + uint8 *buffer = new uint8[size]; + assert(buffer); + memcpy(buffer, data, size); + + return out.addFile(filename, buffer, size); +} + +bool extractStrings(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { + uint32 entries = 0; + uint32 targetsize = size + 4; + for (uint32 i = 0; i < size; ++i) { + if (!data[i]) { + if (g->special == kAmigaVersion) { + if (i + 1 >= size) + ++entries; + else if (!data[i+1] && !(i & 1)) + continue; + else + ++entries; + } else { + ++entries; + } + + if (g->special == kFMTownsVersionE || g->special == kFMTownsVersionJ || + g->special == k2TownsFile1E || g->special == k2TownsFile1J || + g->special == k2TownsFile2E || g->special == k2TownsFile2J) { + // prevents creation of empty entries (which we have mostly between all strings in the FM-TOWNS version) + while (!data[++i]) { + if (i == size) + break; + targetsize--; + } + if (fmtPatch == 1) { + // Here is the first step of the extra treatment for all FM-TOWNS string arrays that + // contain more than one string and which the original code + // addresses via stringname[boolJapanese]. + // We simply skip every other string + if (i == size) + continue; + uint32 len = strlen((const char*) data + i); + i += len; + + targetsize = targetsize - 1 - len; + + while (!data[++i]) { + if (i == len) + break; + targetsize--; + } + } + } + } + } + + if (fmtPatch == 2) { + if (g->special == kFMTownsVersionE) { + targetsize--; + entries += 1; + } else if (g->special == kFMTownsVersionJ) { + targetsize += 2; + entries += 2; + } + } + + if (fmtPatch == 3) { + entries++; + targetsize++; + } + + if (fmtPatch == 4) { + targetsize -= 9; + } + + uint8 *buffer = new uint8[targetsize]; + assert(buffer); + memset(buffer, 0, targetsize); + uint8 *output = buffer; + const uint8 *input = (const uint8*) data; + + WRITE_BE_UINT32(output, entries); output += 4; + if (g->special == kFMTownsVersionE || g->special == kFMTownsVersionJ || + g->special == k2TownsFile1E || g->special == k2TownsFile1J || + g->special == k2TownsFile2E || g->special == k2TownsFile2J) { + const byte *c = data + size; + do { + if (fmtPatch == 2 && input - data == 0x3C0 && input[0x10] == 0x32) { + memcpy(output, input, 0x0F); + input += 0x11; output += 0x0F; + } + + strcpy((char*) output, (const char*) input); + uint32 stringsize = strlen((const char*)output) + 1; + input += stringsize; output += stringsize; + // skip empty entries + while (!*input) { + // Write one empty string into intro strings file + if (fmtPatch == 2) { + if ((g->special == kFMTownsVersionE && input - data == 0x260) || + (g->special == kFMTownsVersionJ && input - data == 0x2BD) || + (g->special == kFMTownsVersionJ && input - data == 0x2BE)) + *output++ = *input; + } + + // insert one dummy string at hof sequence strings position 59 + if (fmtPatch == 3) { + if ((g->special == k2TownsFile1E && input - data == 0x695) || + (g->special == k2TownsFile1J && input - data == 0x598)) + *output++ = *input; + } + + if (++input == c) + break; + } + + if (fmtPatch == 1) { + // Here is the extra treatment for all FM-TOWNS string arrays that + // contain more than one string and which the original code + // addresses via stringname[boolJapanese]. + // We simply skip every other string + if (input == c) + continue; + input += strlen((const char*)input); + while (!*input) { + if (++input == c) + break; + } + } + + } while (input < c); + } else if (g->special == kAmigaVersion) { + // we need to strip some aligment zeros out here + int dstPos = 0; + for (uint32 i = 0; i < size; ++i) { + if (!data[i] && !(i & 1)) { + if (i + 1 > size) + continue; + else if (i + 1 < size && !data[i+1]) + continue; + } + + *output++ = data[i]; + ++dstPos; + } + targetsize = dstPos + 4; + } else { + uint32 copySize = size; + if (fmtPatch == 4) { + memcpy(output, data, 44); + output += 44; + data += 44; + for (int t = 1; t != 10; t++) { + sprintf((char*) output, "COST%d_SH.PAK", t); + output += 13; + } + data += 126; + copySize -= 170; + } + memcpy(output, data, copySize); + } + + return out.addFile(filename, buffer, targetsize); +} + +bool extractStrings10(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { + const int strSize = 10; + uint32 entries = (size + (strSize - 1)) / strSize; + uint32 targetSize = 4; + + uint8 *buffer = new uint8[size + 4]; + assert(buffer); + uint8 *output = buffer; + WRITE_BE_UINT32(output, entries); output += 4; + + for (uint32 i = 0; i < entries; ++i) { + const byte *src = data + i * strSize; + + while (*src) + *output++ = *src++; + *output++ = '\0'; + } + + return out.addFile(filename, buffer, output - buffer); +} + +bool extractRooms(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { + // different entry size for the FM-TOWNS version + const int roomEntrySize = (g->special == kFMTownsVersionE || g->special == kFMTownsVersionJ) ? (0x69) : ((g->special == kAmigaVersion) ? 0x52 : 0x51); + const int countRooms = size / roomEntrySize; + + uint8 *buffer = new uint8[countRooms * 9 + 4]; + assert(buffer); + uint8 *output = buffer; + + WRITE_BE_UINT32(output, countRooms); output += 4; + + const byte *src = data; + if (g->special == kAmigaVersion) { + for (int i = 0; i < countRooms; ++i) { + *output++ = *src++; assert(*src == 0); ++src; + memcpy(output, src, 8); output += 0x8; + src += roomEntrySize - 0x2; + } + } else { + for (int i = 0; i < countRooms; ++i) { + *output++ = *src++; + WRITE_BE_UINT16(output, READ_LE_UINT16(src)); output += 2; src += 2; + WRITE_BE_UINT16(output, READ_LE_UINT16(src)); output += 2; src += 2; + WRITE_BE_UINT16(output, READ_LE_UINT16(src)); output += 2; src += 2; + WRITE_BE_UINT16(output, READ_LE_UINT16(src)); output += 2; src += 2; + src += roomEntrySize - 0x9; + } + } + + return out.addFile(filename, buffer, countRooms * 9 + 4); +} + +bool extractShapes(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { + byte *buffer = new byte[size + 1 * 4]; + assert(buffer); + byte *output = buffer; + + const int count = size / 0x07; + WRITE_BE_UINT32(output, count); output += 4; + memcpy(output, data, size); + + return out.addFile(filename, buffer, size + 1 * 4); +} + +bool extractAmigaSfx(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { + const uint32 entries = size / 8; + byte *buffer = new byte[entries * 6 + 1 * 4]; + + byte *output = buffer; + WRITE_BE_UINT32(output, entries); output += 4; + + for (uint32 i = 0; i < entries; ++i) { + *output++ = *data++; // Note + *output++ = *data++; // Patch + data += 2; // Unused + WRITE_BE_UINT16(output, READ_BE_UINT16(data)); output += 2; data += 2; // Duration + *output++ = *data++; // Volume + *output++ = *data++; // Pan + } + + return out.addFile(filename, buffer, entries * 6 + 1 * 4); +} + +bool extractWdSfx(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { + const int bufferSize = 0x12602; + + uint8 *buffer = new uint8[0x12602]; + assert(buffer); + memcpy(buffer, data, 0x7EE5); + memcpy(buffer + 0x7EE5, data + 0x7EE7, 0x7FFF); + memcpy(buffer + 0xFEE4, data + 0xFEE8, 0x271E); + + return out.addFile(filename, buffer, bufferSize); +} + +int extractHofSeqData_checkString(const void *ptr, uint8 checkSize); +int extractHofSeqData_isSequence(const void *ptr, const Game *g, uint32 maxCheckSize); +int extractHofSeqData_isControl(const void *ptr, uint32 size); + +bool extractHofSeqData(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { + int numSequences = 0; + int numNestedSequences = 0; + + uint16 headerSize = 50 * sizeof(uint16); + uint16 bufferSize = size + headerSize; + byte *buffer = new byte[bufferSize]; + assert(buffer); + memset(buffer, 0, bufferSize ); + uint16 *header = (uint16*) buffer; + byte *output = buffer + headerSize; + uint16 *hdout = header; + + //debug(1, "\nProcessing Hand of Fate sequence data:\n--------------------------------------\n"); + for (int cycle = 0; cycle < 2; cycle++) { + const byte *ptr = data; + hdout++; + + const byte * endOffs = (const byte *)(data + size); + + // detect sequence structs + while (ptr < endOffs) { + if (ptr[1]) { + error("invalid sequence data encountered"); + delete[] buffer; + return false; + } + + int v = extractHofSeqData_isSequence(ptr, g, endOffs - ptr); + + if (cycle == 0 && v == 1) { + if ((g->special == k2FloppyFile1 && *ptr == 5) || (g->special == k2DemoVersion && (ptr - data == 312))) { + // patch for floppy version: skips invalid ferb sequence + // patch for demo: skips invalid title sequence + ptr += 54; + continue; + } + + numSequences++; + uint16 relOffs = (uint16) (output - buffer); + WRITE_BE_UINT16(hdout, relOffs); + hdout++; + + WRITE_BE_UINT16(output, READ_LE_UINT16(ptr)); // flags + ptr += 2; + output += 2; + + memcpy(output, ptr, 28); // wsa and cps file names + ptr += 28; + output += 28; + + if (g->special == k2TownsFile1E) { // startupCommand + finalCommand + memcpy(output , ptr, 2); + ptr += 2; + output += 2; + } else { + *output++ = READ_LE_UINT16(ptr) & 0xff; + ptr += 2; + *output++ = READ_LE_UINT16(ptr) & 0xff; + ptr += 2; + } + + for (int w = 0; w < 7; w++) { //stringIndex1 to yPos + WRITE_BE_UINT16(output, READ_LE_UINT16(ptr)); + ptr += 2; + output += 2; + } + + ptr += 4; + WRITE_BE_UINT16(output, READ_LE_UINT16(ptr)); // duration + ptr += 2; + output+= 2; + + } else if (cycle == 1 && v != 1 && v != -2) { + uint16 controlOffs = 0; + uint16 ctrSize = 0; + if (v) { + const byte *ctrStart = ptr; + while (v && v != -2) { + ptr++; + v = extractHofSeqData_isSequence(ptr, g, endOffs - ptr); + } + + if (v == -2) + break; + + ctrSize = (uint16)(ptr - ctrStart); + + if (g->special != k2DemoVersion && + extractHofSeqData_isControl(ctrStart, ctrSize)) { + controlOffs = (uint16) (output - buffer); + *output++ = ctrSize >> 2; + + for (int cc = 0; cc < ctrSize; cc += 2) + WRITE_BE_UINT16(output + cc, READ_LE_UINT16(ctrStart + cc)); // frame control + output += ctrSize; + } + } + + numNestedSequences++; + uint16 relOffs = (uint16) (output - buffer); + WRITE_BE_UINT16(hdout, relOffs); + hdout++; + + WRITE_BE_UINT16(output, READ_LE_UINT16(ptr)); // flags + ptr += 2; + output += 2; + + memcpy(output, ptr, 14); // wsa file name + ptr += 14; + output += 14; + + // startframe + WRITE_BE_UINT16(output, READ_LE_UINT16(ptr)); + ptr += 2; + output += 2; + + // endFrame + WRITE_BE_UINT16(output, (ctrSize && ((ctrSize >> 2) < READ_LE_UINT16(ptr))) ? (ctrSize >> 2) : READ_LE_UINT16(ptr)); + ptr += 2; + output += 2; + + // frameDelay + WRITE_BE_UINT16(output, READ_LE_UINT16(ptr)); + ptr += 2; + output += 2; + + ptr += 4; + + for (int w = 0; w < 2; w++) { //x, y + WRITE_BE_UINT16(output, READ_LE_UINT16(ptr)); + ptr += 2; + output += 2; + } + + if (!READ_LE_UINT32(ptr)) + controlOffs = 0; + + WRITE_BE_UINT16(output, controlOffs); + if (g->special != k2DemoVersion && g->special != k2DemoLol) + ptr += 4; + output += 2; + + if (g->special != k2DemoVersion && g->special != k2DemoLol) { + for (int w = 0; w < 2; w++) { //startupCommand, finalCommand + WRITE_BE_UINT16(output, READ_LE_UINT16(ptr)); + ptr += 2; + output += 2; + } + } else { + memset(output, 0, 4); + output += 4; + } + + if (g->special == k2TownsFile1E) + ptr += 2; + + } else if (cycle == 0) { + while (v != 1 && v != -2) { + ptr++; + v = extractHofSeqData_isSequence(ptr, g, endOffs - ptr); + } + + if (v == -2) + break; + + + } else if (cycle == 1) { + while (v == 1 && v != -2) { + ptr++; + v = extractHofSeqData_isSequence(ptr, g, endOffs - ptr); + } + + if (v == -2) + break; + } + } + } + + uint16 finHeaderSize = (2 + numSequences + numNestedSequences) * sizeof(uint16); + uint16 finBufferSize = ((output - buffer) - headerSize) + finHeaderSize; + byte *finBuffer = new byte[finBufferSize]; + assert(finBuffer); + uint16 diff = headerSize - finHeaderSize; + uint16 *finHeader = (uint16*) finBuffer; + + for (int i = 1; i < finHeaderSize; i++) + WRITE_BE_UINT16(&finHeader[i], (READ_BE_UINT16(&header[i]) - diff)); + WRITE_BE_UINT16(finHeader, numSequences); + WRITE_BE_UINT16(&finHeader[numSequences + 1], numNestedSequences); + memcpy (finBuffer + finHeaderSize, buffer + headerSize, finBufferSize - finHeaderSize); + delete[] buffer; + + finHeader = (uint16*) (finBuffer + ((numSequences + 2) * sizeof(uint16))); + for (int i = 0; i < numNestedSequences; i++) { + uint8 * offs = finBuffer + READ_BE_UINT16(finHeader++) + 26; + uint16 ctrl = READ_BE_UINT16(offs); + if (ctrl) + ctrl -= diff; + WRITE_BE_UINT16(offs, ctrl); + } + + return out.addFile(filename, finBuffer, finBufferSize); +} + +int extractHofSeqData_checkString(const void *ptr, uint8 checkSize) { + // return values: 1 = text; 0 = zero string; -1 = other + + int t = 0; + int c = checkSize; + const uint8 *s = (const uint8*)ptr; + + // check for character string + while (c--) { + if (*s > 31 && *s < 123) + t++; + s++; + } + + if (t == checkSize) + return 1; + + // check for zero string + c = checkSize; + uint32 sum = 0; + s = (const uint8*)ptr; + while (c--) + sum += *s++; + + return (sum) ? -1 : 0; +} + +int extractHofSeqData_isSequence(const void *ptr, const Game *g, uint32 maxCheckSize) { + // return values: 1 = Sequence; 0 = Nested Sequence; -1 = other; -2 = overflow + + if (maxCheckSize < 30) + return -2; + + const uint8 * s = (const uint8*)ptr; + int c1 = extractHofSeqData_checkString(s + 2, 6); + int c2 = extractHofSeqData_checkString(s + 16, 6); + int c3 = extractHofSeqData_checkString(s + 2, 14); + int c4 = extractHofSeqData_checkString(s + 16, 14); + int c0 = s[1]; + int c5 = s[0]; + + if (c0 == 0 && c5 && ((c1 + c2) >= 1) && (!(c3 == 0 && c2 != 1)) && (!(c4 == 0 && c1 != 1))) { + if (maxCheckSize < 41) + return -2; + + if (g->special == k2TownsFile1E) { + if (!(s[37] | s[39]) && s[38] > s[36]) + return 1; + } else { + if (!(s[39] | s[41]) && s[40] > s[38]) + return 1; + } + } + + if (c0 == 0 && c5 == 4 && c3 == 0 && c4 == 0) { + if (maxCheckSize >= 41 && READ_LE_UINT32(s + 34) && !(s[39] | s[41]) && s[40] > s[38]) + return 1; + } + + if (c0 == 0 && c5 && c1 == 1 && c4 == -1 && s[20]) + return 0; + + return -1; +} + +int extractHofSeqData_isControl(const void *ptr, uint32 size) { + // return values: 1 = possible frame control data; 0 = definitely not frame control data + + const uint8 *s = (const uint8*)ptr; + for (uint32 i = 2; i < size; i += 4) { + if (!s[i]) + return 0; + } + + for (uint32 i = 1; i < size; i += 2) { + if (s[i]) + return 0; + } + return 1; +} + +bool extractHofShapeAnimDataV1(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { + int outsize = 1; + uint8 *buffer = new uint8[size + 1]; + const uint8 *src = data; + uint8 *dst = buffer + 1; + + for (int i = 0; i < 4; i++) { + WRITE_BE_UINT16(dst, READ_LE_UINT16(src)); + src += 2; + dst += 2; + WRITE_BE_UINT16(dst, READ_LE_UINT16(src)); + src += 4; + dst += 2; + outsize += 4; + + for (int j = 0; j < 20; j++) { + WRITE_BE_UINT16(dst, READ_LE_UINT16(src)); + src += 2; + dst += 2; + outsize += 2; + } + + }; + + *buffer = 4; // number of items + + return out.addFile(filename, buffer, outsize); +} + +bool extractHofShapeAnimDataV2(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { + int outsize = 1; + uint8 *buffer = new uint8[size + 1]; + const uint8 *src = data; + uint8 *dst = buffer + 1; + const uint8 *fin = data + size; + int count = 0; + + do { + if (READ_LE_UINT16(src) == 0xffff) + break; + + count++; + + WRITE_BE_UINT16(dst, READ_LE_UINT16(src)); + src += 2; + dst += 2; + + uint8 numFrames = *src; + *dst++ = numFrames; + src += 6; + outsize += 3; + + for (int i = 0; i < (numFrames << 1); i++) { + WRITE_BE_UINT16(dst, READ_LE_UINT16(src)); + src += 2; + dst += 2; + outsize += 2; + } + + src += (48 - (numFrames << 2)); + + } while (src < fin); + + *buffer = count; // number of items + + return out.addFile(filename, buffer, outsize); +} + +bool extractStringsWoSuffix(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { + int outsize = size + 4; + uint8 *buffer = new uint8[outsize]; + const uint8 *src = data; + uint8 *dst = buffer + 4; + const uint8 *fin = src + size; + int entries = 0; + + while (src < fin) { + while (!*src && src < fin) + src++; + while (*src && *src != '.' && src < fin) + *dst++ = *src++; + + *dst++ = '\0'; + entries++; + + if (*src == '.') { + while (*src && src < fin) + src++; + } + } + + WRITE_BE_UINT32(buffer, entries); + outsize = dst - buffer; + + return out.addFile(filename, buffer, outsize); +} + +bool extractPaddedStrings(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { + int outsize = size + 4; + uint8 *buffer = new uint8[outsize]; + const uint8 *src = data; + uint8 *dst = buffer + 4; + const uint8 *fin = src + size; + int entries = 0; + + while (src < fin) { + while (!*src && src < fin) + src++; + while (*src && src < fin) + *dst++ = *src++; + + *dst++ = '\0'; + entries++; + } + + WRITE_BE_UINT32(buffer, entries); + outsize = dst - buffer; + + return out.addFile(filename, buffer, outsize); +} + +bool extractRaw16to8(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { + int outsize = size >> 1; + uint8 *buffer = new uint8[outsize]; + const uint8 *src = data; + uint8 *dst = buffer; + + for (int i = 0; i < outsize; i++) { + *dst++ = *src++; + *src++; + } + + return out.addFile(filename, buffer, outsize); +} + +bool extractRaw16(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { + uint8 *buffer = new uint8[size]; + const uint8 *src = data; + uint8 *dst = buffer; + + for (uint32 i = 0; i < (size >> 1); i++) { + WRITE_BE_UINT16(dst, READ_LE_UINT16(src)); + src += 2; + dst += 2; + } + + return out.addFile(filename, buffer, size); +} + +bool extractRaw32(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { + uint8 *buffer = new uint8[size]; + const uint8 *src = data; + uint8 *dst = buffer; + + for (uint32 i = 0; i < (size >> 2); i++) { + WRITE_BE_UINT32(dst, READ_LE_UINT32(src)); + src += 4; + dst += 4; + } + + return out.addFile(filename, buffer, size); +} + +bool extractLolButtonDefs(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { + int num = size / 22; + uint8 *buffer = new uint8[size]; + uint32 outsize = num * 18; + const uint8 *src = data; + uint8 *dst = buffer; + + for (int i = 0; i < num; i++) { + WRITE_BE_UINT16(dst, READ_LE_UINT16(src)); + src += 2; dst += 2; + WRITE_BE_UINT16(dst, READ_LE_UINT16(src)); + src += 2; dst += 2; + WRITE_BE_UINT16(dst, READ_LE_UINT16(src)); + src += 6; dst += 2; + WRITE_BE_UINT16(dst, READ_LE_UINT16(src)); + src += 2; dst += 2; + WRITE_BE_UINT16(dst, READ_LE_UINT16(src)); + src += 2; dst += 2; + WRITE_BE_UINT16(dst, READ_LE_UINT16(src)); + src += 2; dst += 2; + WRITE_BE_UINT16(dst, READ_LE_UINT16(src)); + src += 2; dst += 2; + WRITE_BE_UINT16(dst, READ_LE_UINT16(src)); + src += 2; dst += 2; + WRITE_BE_UINT16(dst, READ_LE_UINT16(src)); + src += 2; dst += 2; + } + + return out.addFile(filename, buffer, outsize); +} + +bool extractMrShapeAnimData(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { + int outsize = 1; + uint8 *buffer = new uint8[size + 1]; + const uint8 *src2 = data; + const uint8 *src1 = data + 324; + uint8 *dst = buffer + 1; + const uint8 *fin = data + size; + int count = 0; + + do { + if (READ_LE_UINT16(src1) == 0xffff) + break; + + count++; + + WRITE_BE_UINT16(dst, READ_LE_UINT16(src1)); + src1 += 2; + dst += 2; + + uint8 numFrames = *src1; + *dst++ = numFrames; + src1 += 10; + outsize += 3; + + for (int i = 0; i < (numFrames << 1); i++) { + WRITE_BE_UINT16(dst, READ_LE_UINT16(src2)); + src2 += 2; + dst += 2; + outsize += 2; + } + } while (src1 < fin); + + *buffer = count; // number of items + + return out.addFile(filename, buffer, outsize); +} + diff --git a/tools/create_kyradat/module.mk b/tools/create_kyradat/module.mk index b5bd955b88..1471155184 100644 --- a/tools/create_kyradat/module.mk +++ b/tools/create_kyradat/module.mk @@ -5,6 +5,7 @@ MODULE := tools/create_kyradat MODULE_OBJS := \ create_kyradat.o \ + extract.o \ pak.o \ md5.o \ util.o \ |