From de19c946282256074c121b8f893e717574dc9d2f Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Sat, 3 Feb 2007 14:52:02 +0000 Subject: Adding create_kyradat here now. svn-id: r25349 --- tools/create_kyradat/Makefile | 29 ++ tools/create_kyradat/create_kyradat.cpp | 601 ++++++++++++++++++++++++++++++++ tools/create_kyradat/create_kyradat.h | 202 +++++++++++ tools/create_kyradat/eng.h | 190 ++++++++++ tools/create_kyradat/esp.h | 39 +++ tools/create_kyradat/fre.h | 79 +++++ tools/create_kyradat/ger.h | 80 +++++ tools/create_kyradat/md5.cpp | 261 ++++++++++++++ tools/create_kyradat/md5.h | 40 +++ tools/create_kyradat/misc.h | 207 +++++++++++ tools/create_kyradat/pak.cpp | 244 +++++++++++++ tools/create_kyradat/pak.h | 107 ++++++ tools/create_kyradat/util.c | 137 ++++++++ tools/create_kyradat/util.h | 265 ++++++++++++++ 14 files changed, 2481 insertions(+) create mode 100644 tools/create_kyradat/Makefile create mode 100644 tools/create_kyradat/create_kyradat.cpp create mode 100644 tools/create_kyradat/create_kyradat.h create mode 100644 tools/create_kyradat/eng.h create mode 100644 tools/create_kyradat/esp.h create mode 100644 tools/create_kyradat/fre.h create mode 100644 tools/create_kyradat/ger.h create mode 100644 tools/create_kyradat/md5.cpp create mode 100644 tools/create_kyradat/md5.h create mode 100644 tools/create_kyradat/misc.h create mode 100644 tools/create_kyradat/pak.cpp create mode 100644 tools/create_kyradat/pak.h create mode 100644 tools/create_kyradat/util.c create mode 100644 tools/create_kyradat/util.h (limited to 'tools') diff --git a/tools/create_kyradat/Makefile b/tools/create_kyradat/Makefile new file mode 100644 index 0000000000..b90f8940b7 --- /dev/null +++ b/tools/create_kyradat/Makefile @@ -0,0 +1,29 @@ +CXX ?= g++ +CC ?= gcc + +LDFLAGS ?= +CXXFLAGS ?= -O2 +CFLAGS ?= -O2 +CPPFLAGS ?= + +BIN=create_kyradat + +OBJS=create_kyradat.o pak.o md5.o util.o + +all: $(BIN) + +$(BIN): $(OBJS) + $(CXX) $(OBJS) $(LDFLAGS) -o $(BIN) + +clean: + rm -f $(BIN) + rm -f $(OBJS) + +create_kyradat.o: eng.h esp.h fre.h ger.h misc.h pak.h util.h md5.h +pak.o: pak.h util.h + +%.o: %.cpp + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@ + +%.o: %.c + $(CXX) $(CPPFLAGS) $(CFLAGS) -c $< -o $@ diff --git a/tools/create_kyradat/create_kyradat.cpp b/tools/create_kyradat/create_kyradat.cpp new file mode 100644 index 0000000000..5210dd2054 --- /dev/null +++ b/tools/create_kyradat/create_kyradat.cpp @@ -0,0 +1,601 @@ +/* ScummVM Tools + * Copyright (C) 2007 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" + +#include "md5.h" + +enum { + kKyraDatVersion = 14, + kIndexSize = 12 +}; + +// tables + +#include "misc.h" +#include "eng.h" +#include "esp.h" +#include "fre.h" +#include "ger.h" + +bool extractRaw(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename); +bool extractStrings(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename); +bool extractRooms(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename); +bool extractShapes(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename); + +void createFilename(char *dstFilename, const int lang, const int special, const char *filename); +void createLangFilename(char *dstFilename, const int lang, const int special, const char *filename); + +const ExtractType extractTypeTable[] = { + { kTypeLanguageList, extractStrings, createLangFilename }, + { kTypeStringList, extractStrings, createFilename }, + { kTypeRoomList, extractRooms, createFilename }, + { kTypeShapeList, extractShapes, createFilename }, + { kTypeRawData, extractRaw, createFilename }, + { -1, 0 } +}; + +const ExtractFilename extractFilenames[] = { + // INTRO / OUTRO sequences + { kForestSeq, kTypeRawData, "FOREST.SEQ" }, + { kKallakWritingSeq, kTypeRawData, "KALLAK-WRITING.SEQ" }, + { kKyrandiaLogoSeq, kTypeRawData, "KYRANDIA-LOGO.SEQ" }, + { kKallakMalcolmSeq, kTypeRawData, "KALLAK-MALCOLM.SEQ" }, + { kMalcolmTreeSeq, kTypeRawData, "MALCOLM-TREE.SEQ" }, + { kWestwoodLogoSeq, kTypeRawData, "WESTWOOD-LOGO.SEQ" }, + { kDemo1Seq, kTypeRawData, "DEMO1.SEQ" }, + { kDemo2Seq, kTypeRawData, "DEMO2.SEQ" }, + { kDemo3Seq, kTypeRawData, "DEMO3.SEQ" }, + { kDemo4Seq, kTypeRawData, "DEMO4.SEQ" }, + { kOutroReunionSeq, kTypeRawData, "REUNION.SEQ" }, + + // INTRO / OUTRO strings + { kIntroCPSStrings, kTypeStringList, "INTRO-CPS.TXT" }, + { kIntroCOLStrings, kTypeStringList, "INTRO-COL.TXT" }, + { kIntroWSAStrings, kTypeStringList, "INTRO-WSA.TXT" }, + { kIntroStrings, kTypeLanguageList, "INTRO-STRINGS" }, + { kOutroHomeString, kTypeLanguageList, "HOME" }, + + // INGAME strings + { kItemNames, kTypeLanguageList, "ITEMLIST" }, + { kTakenStrings, kTypeLanguageList, "TAKEN" }, + { kPlacedStrings, kTypeLanguageList, "PLACED" }, + { kDroppedStrings, kTypeLanguageList, "DROPPED" }, + { kNoDropStrings, kTypeLanguageList, "NODROP" }, + { kPutDownString, kTypeLanguageList, "PUTDOWN" }, + { kWaitAmuletString, kTypeLanguageList, "WAITAMUL" }, + { kBlackJewelString, kTypeLanguageList, "BLACKJEWEL" }, + { kPoisonGoneString, kTypeLanguageList, "POISONGONE" }, + { kHealingTipString, kTypeLanguageList, "HEALINGTIP" }, + { kThePoisonStrings, kTypeLanguageList, "THEPOISON" }, + { kFluteStrings, kTypeLanguageList, "FLUTE" }, + { kWispJewelStrings, kTypeLanguageList, "WISPJEWEL" }, + { kMagicJewelStrings, kTypeLanguageList, "MAGICJEWEL" }, + { kFlaskFullString, kTypeLanguageList, "FLASKFULL" }, + { kFullFlaskString, kTypeLanguageList, "FULLFLASK" }, + { kVeryCleverString, kTypeLanguageList, "VERYCLEVER" }, + { kNewGameString, kTypeLanguageList, "NEWGAME" }, + + // GUI strings table + { kGUIStrings, kTypeLanguageList, "GUISTRINGS" }, + { kConfigStrings, kTypeLanguageList, "CONFIGSTRINGS" }, + + // ROOM table/filenames + { kRoomList, kTypeRoomList, "ROOM-TABLE.ROOM" }, + { kRoomFilenames, kTypeStringList, "ROOM-FILENAMES.TXT" }, + + // SHAPE tables + { kDefaultShapes, kTypeShapeList, "SHAPES-DEFAULT.SHP" }, + { kHealing1Shapes, kTypeShapeList, "HEALING.SHP" }, + { kHealing2Shapes, kTypeShapeList, "HEALING2.SHP" }, + { kPoisonDeathShapes, kTypeShapeList, "POISONDEATH.SHP" }, + { kFluteShapes, kTypeShapeList, "FLUTE.SHP" }, + { kWinter1Shapes, kTypeShapeList, "WINTER1.SHP" }, + { kWinter2Shapes, kTypeShapeList, "WINTER2.SHP" }, + { kWinter3Shapes, kTypeShapeList, "WINTER3.SHP" }, + { kDrinkShapes, kTypeShapeList, "DRINK.SHP" }, + { kWispShapes, kTypeShapeList, "WISP.SHP" }, + { kMagicAnimShapes, kTypeShapeList, "MAGICANIM.SHP" }, + { kBranStoneShapes, kTypeShapeList, "BRANSTONE.SHP" }, + + // IMAGE filename table + { kCharacterImageFilenames, kTypeStringList, "CHAR-IMAGE.TXT" }, + + // AMULET anim + { kAmuleteAnimSeq, kTypeRawData, "AMULETEANIM.SEQ" }, + + // PALETTE table + { kPaletteList1, kTypeRawData, "PALTABLE1.PAL" }, + { kPaletteList2, kTypeRawData, "PALTABLE2.PAL" }, + { kPaletteList3, kTypeRawData, "PALTABLE3.PAL" }, + { kPaletteList4, kTypeRawData, "PALTABLE4.PAL" }, + { kPaletteList5, kTypeRawData, "PALTABLE5.PAL" }, + { kPaletteList6, kTypeRawData, "PALTABLE6.PAL" }, + { kPaletteList7, kTypeRawData, "PALTABLE7.PAL" }, + { kPaletteList8, kTypeRawData, "PALTABLE8.PAL" }, + { kPaletteList9, kTypeRawData, "PALTABLE9.PAL" }, + { kPaletteList10, kTypeRawData, "PALTABLE10.PAL" }, + { kPaletteList11, kTypeRawData, "PALTABLE11.PAL" }, + { kPaletteList12, kTypeRawData, "PALTABLE12.PAL" }, + { kPaletteList13, kTypeRawData, "PALTABLE13.PAL" }, + { kPaletteList14, kTypeRawData, "PALTABLE14.PAL" }, + { kPaletteList15, kTypeRawData, "PALTABLE15.PAL" }, + { kPaletteList16, kTypeRawData, "PALTABLE16.PAL" }, + { kPaletteList17, kTypeRawData, "PALTABLE17.PAL" }, + { kPaletteList18, kTypeRawData, "PALTABLE18.PAL" }, + { kPaletteList19, kTypeRawData, "PALTABLE19.PAL" }, + { kPaletteList20, kTypeRawData, "PALTABLE20.PAL" }, + { kPaletteList21, kTypeRawData, "PALTABLE21.PAL" }, + { kPaletteList22, kTypeRawData, "PALTABLE22.PAL" }, + { kPaletteList23, kTypeRawData, "PALTABLE23.PAL" }, + { kPaletteList24, kTypeRawData, "PALTABLE24.PAL" }, + { kPaletteList25, kTypeRawData, "PALTABLE25.PAL" }, + { kPaletteList26, kTypeRawData, "PALTABLE26.PAL" }, + { kPaletteList27, kTypeRawData, "PALTABLE27.PAL" }, + { kPaletteList28, kTypeRawData, "PALTABLE28.PAL" }, + { kPaletteList29, kTypeRawData, "PALTABLE29.PAL" }, + { kPaletteList30, kTypeRawData, "PALTABLE30.PAL" }, + { kPaletteList31, kTypeRawData, "PALTABLE31.PAL" }, + { kPaletteList32, kTypeRawData, "PALTABLE32.PAL" }, + { kPaletteList33, kTypeRawData, "PALTABLE33.PAL" }, + + // FM-TOWNS specific + { kKyra1TownsSFXTable, kTypeRawData, "SFXTABLE.TSX" }, + + { -1, 0, 0 } +}; + +const ExtractFilename *getFilenameDesc(const int id) { + for (const ExtractFilename *i = extractFilenames; i->id != -1; ++i) { + if (i->id == id) + return i; + } + return 0; +} + +// type processing + +const ExtractType *findExtractType(const int type) { + for (const ExtractType *i = extractTypeTable; i->type != -1; ++i) { + if (i->type == type) + return i; + } + return 0; +} + +// filename processing + +bool getFilename(char *dstFilename, const Game *g, const int id) { + const ExtractFilename *i = getFilenameDesc(id); + + if (!i) + return false; + + const ExtractType *type = findExtractType(i->type); + type->createFilename(dstFilename, g->lang, g->special, i->filename); + return true; +} + +void createFilename(char *dstFilename, const int lang, const int special, const char *filename) { + strcpy(dstFilename, filename); + + for (const SpecialExtension *specialE = specialTable; specialE->special != -1; ++specialE) { + if (specialE->special == special) { + strcat(dstFilename, "."); + strcat(dstFilename, specialE->ext); + break; + } + } +} + +void createLangFilename(char *dstFilename, const int lang, const int special, const char *filename) { + strcpy(dstFilename, filename); + + for (const Language *langE = languageTable; langE->lang != -1; ++langE) { + if (langE->lang == lang) { + strcat(dstFilename, "."); + strcat(dstFilename, langE->ext); + break; + } + } + + for (const SpecialExtension *specialE = specialTable; specialE->special != -1; ++specialE) { + if (specialE->special == special) { + strcat(dstFilename, "."); + strcat(dstFilename, specialE->ext); + break; + } + } +} + +// entry checking + +int hashEntries(const int *entries) { + int hash = 0; + for (const int *i = entries; *i != -1; ++i) { + hash += *i; + } + return hash; +} + +bool hasEntry(const ExtractEntry *entries, const int id) { + for (const ExtractEntry *i = entries; i->id != -1; ++i) { + if (i->id == id) + return true; + } + return false; +} + +int hashEntries(const Game *game, const GameNeed *need, const PAKFile *file) { + int hash = 0; + char filename[128]; + for (const int *i = need->entries; *i != -1; ++i) { + if (hasEntry(game->entries, *i)) { + hash += *i; + continue; + } + + if (file) { + filename[0] = 0; + + if (!getFilename(filename, game, *i)) + error("couldn't find filename for id %d", *i); + + PAKFile::cFileList *list = file->getFileList(); + if (list && list->findEntry(filename) != 0) + hash += *i; + } + } + + return hash; +} + +bool hasNeededEntries(const Game *game, const PAKFile *file) { + for (const GameNeed *need = gameNeedTable; need->game != -1; ++need) { + if (need->game == game->game && need->special == game->special) { + if (hashEntries(need->entries) == hashEntries(game, need, file)) + return true; + } + } + + return false; +} + +// extraction + +bool extractRaw(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename) { + 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) { + uint32 entries = 0; + for (uint32 i = 0; i < size; ++i) { + if (!data[i]) + ++entries; + } + + uint8 *buffer = new uint8[size + 4]; + assert(buffer); + uint8 *output = buffer; + + WRITE_BE_UINT32(output, entries); output += 4; + memcpy(output, data, size); + + return out.addFile(filename, buffer, size + 4); +} + +bool extractRooms(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename) { + const int countRooms = size / 0x51; + + uint8 *buffer = new uint8[countRooms * 9 + 4]; + assert(buffer); + uint8 *output = buffer; + + WRITE_BE_UINT32(output, countRooms); output += 4; + + const byte *src = data; + 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 += (0x51 - 9); + } + + return out.addFile(filename, buffer, countRooms * 9 + 4); +} + +bool extractShapes(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename) { + 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); +} + +// index generation + +enum { + GF_FLOPPY = 1 << 0, + GF_TALKIE = 1 << 1, + GF_FMTOWNS = 1 << 2, + GF_DEMO = 1 << 3, + GF_ENGLISH = 1 << 4, + GF_FRENCH = 1 << 5, + GF_GERMAN = 1 << 6, + GF_SPANISH = 1 << 7, + GF_ITALIAN = 1 << 8, + GF_JAPANESE = 1 << 9, + // ... + GF_LNGUNK = 1 << 16, + GF_AMIGA = 1 << 17 +}; + +uint32 getFeatures(const Game *g) { + uint32 features = 0; + + if (g->special == kTalkieVersion) + features |= GF_TALKIE; + else if (g->special == kDemoVersion) + features |= GF_DEMO; + else if (g->special == kFMTownsVersion) + features |= GF_FMTOWNS; + else + features |= GF_FLOPPY; + + if (g->lang == EN_ANY) + features |= GF_ENGLISH; + else if (g->lang == DE_DEU) + features |= GF_GERMAN; + else if (g->lang == FR_FRA) + features |= GF_FRENCH; + else if (g->lang == ES_ESP) + features |= GF_SPANISH; + else if (g->lang == IT_ITA) + features |= GF_ITALIAN; + + return features; +} + +bool updateIndex(byte *dst, const int dstSize, const Game *g) { + if ((size_t)dstSize < kIndexSize) + return false; + + WRITE_BE_UINT32(dst, kKyraDatVersion); dst += 4; + WRITE_BE_UINT32(dst, g->game); dst += 4; + uint32 features = READ_BE_UINT32(dst); + features |= getFeatures(g); + WRITE_BE_UINT32(dst, features); dst += 4; + + return true; +} + +bool checkIndex(const byte *s, const int srcSize) { + if ((size_t)srcSize < sizeof(uint32)) + return false; + uint32 version = READ_BE_UINT32(s); + return (version == kKyraDatVersion); +} + +bool updateIndex(PAKFile &out, const Game *g) { + char filename[32]; + createFilename(filename, -1, g->special, "INDEX"); + + byte *index = new byte[kIndexSize]; + assert(index); + memset(index, 0, kIndexSize); + + uint32 size = 0; + const uint8 *data = out.getFileData(filename, &size); + if (data) + memcpy(index, data, size); + + if (!updateIndex(index, kIndexSize, g)) { + delete [] index; + return false; + } + + out.removeFile(filename); + if (!out.addFile(filename, index, kIndexSize)) { + fprintf(stderr, "ERROR: couldn't update %s file", filename); + delete [] index; + return false; + } + + return true; +} + +bool checkIndex(PAKFile &out, const Game *g) { + char filename[32]; + createFilename(filename, -1, g->special, "INDEX"); + + uint32 size = 0; + const uint8 *data = out.getFileData(filename, &size); + if (!data) + return true; + + return checkIndex(data, size); +} + +// main processing + +void printHelp(const char *f) { + printf("Usage:\n"); + printf("%s output inputfiles ...", f); +} + +bool process(PAKFile &out, const Game *g, const byte *data, const uint32 size); +const Game *findGame(const byte *buffer, const uint32 size); + +int main(int argc, char *argv[]) { + if (argc < 3) { + printHelp(argv[0]); + return -1; + } + + PAKFile out; + out.loadFile(argv[1], false); + + for (int i = 2; i < argc; ++i) { + FILE *input = fopen(argv[i], "rb"); + + if (!input) { + warning("skipping missing file '%s'", argv[i]); + continue; + } + + uint32 size = fileSize(input); + fseek(input, 0, SEEK_SET); + + byte *buffer = new uint8[size]; + assert(buffer); + + if (fread(buffer, 1, size, input) != size) { + warning("couldn't read from file '%s', skipping it", argv[i]); + delete [] buffer; + fclose(input); + continue; + } + fclose(input); + + const Game *g = findGame(buffer, size); + if (!g) { + warning("skipping unknown file '%s'", argv[i]); + delete [] buffer; + continue; + } + + if (!hasNeededEntries(g, &out)) { + warning("file '%s' is missing offset entries and thus can't be processed", argv[i]); + delete [] buffer; + continue; + } + + if (!process(out, g, buffer, size)) + fprintf(stderr, "ERROR: couldn't process file '%s'", argv[i]); + + delete [] buffer; + } + + if (!out.saveFile(argv[1])) + error("couldn't save changes to '%s'", argv[1]); + + uint8 digest[16]; + if (!md5_file(argv[1], digest, 0)) + error("couldn't calc. md5 for file '%s'", argv[1]); + FILE *f = fopen(argv[1], "ab"); + if (!f) + error("couldn't open file '%s'", argv[1]); + if (fwrite(digest, 1, 16, f) != 16) + error("couldn't write md5sum to file '%s'", argv[1]); + fclose(f); + + return 0; +} + +bool process(PAKFile &out, const Game *g, const byte *data, const uint32 size) { + char filename[128]; + + if (!checkIndex(out, g)) { + fprintf(stderr, "ERROR: corrupted INDEX file\n"); + return false; + } + + for (const ExtractEntry *i = g->entries; i->id != -1; ++i) { + if (!getFilename(filename, g, i->id)) { + fprintf(stderr, "ERROR: couldn't get filename for id %d\n", i->id); + return false; + } + + const ExtractFilename *fDesc = getFilenameDesc(i->id); + + if (!fDesc) { + fprintf(stderr, "ERROR: couldn't find file description for id %d\n", i->id); + return false; + } + + const ExtractType *tDesc = findExtractType(fDesc->type); + + if (!tDesc) { + fprintf(stderr, "ERROR: couldn't find type description for id %d\n", i->id); + return false; + } + + PAKFile::cFileList *list = out.getFileList(); + if (list && list->findEntry(filename) != 0) + continue; + + if (!tDesc->extract(out, g, data + i->startOff, i->endOff - i->startOff, filename)) { + fprintf(stderr, "ERROR: couldn't extract id %d\n", i->id); + return false; + } + } + + if (!updateIndex(out, g)) { + error("couldn't update INDEX file, stop processing of all files"); + return false; + } + + return true; +} + +// game data detection + +const Game *gameDescs[] = { + kyra1EngGames, + kyra1EspGames, + kyra1FreGames, + kyra1GerGames, + 0 +}; + +const Game *findGame(const byte *buffer, const uint32 size) { + md5_context ctx; + uint8 digest[16]; + char md5str[33]; + + md5_starts(&ctx); + md5_update(&ctx, buffer, size); + md5_finish(&ctx, digest); + + for (int j = 0; j < 16; ++j) { + sprintf(md5str + j*2, "%02x", (int)digest[j]); + } + + for (const Game **i = gameDescs; *i != 0; ++i) { + for (const Game *p = *i; p->game != -1; ++p) { + if (strcmp(md5str, p->md5) == 0) + return p; + } + } + + printf("file is not supported (unknown md5 \"%s\")\n", md5str); + return 0; +} diff --git a/tools/create_kyradat/create_kyradat.h b/tools/create_kyradat/create_kyradat.h new file mode 100644 index 0000000000..4bcf289fad --- /dev/null +++ b/tools/create_kyradat/create_kyradat.h @@ -0,0 +1,202 @@ +/* ScummVM Tools + * Copyright (C) 2007 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$ + * + */ + +#ifndef CREATE_KYRADAT_H +#define CREATE_KYRADAT_H + +#include "util.h" +#include "pak.h" + +struct Language { + int lang; + const char *ext; +}; + +enum kExtractID { + kForestSeq = 1, + kKallakWritingSeq, + kKyrandiaLogoSeq, + kKallakMalcolmSeq, + kMalcolmTreeSeq, + kWestwoodLogoSeq, + + kDemo1Seq, + kDemo2Seq, + kDemo3Seq, + kDemo4Seq, + + kAmuleteAnimSeq, + + kOutroReunionSeq, + + kIntroCPSStrings, + kIntroCOLStrings, + kIntroWSAStrings, + kIntroStrings, + + kOutroHomeString, + + kRoomFilenames, + kRoomList, + + kCharacterImageFilenames, + + kItemNames, + kTakenStrings, + kPlacedStrings, + kDroppedStrings, + kNoDropStrings, + + kPutDownString, + kWaitAmuletString, + kBlackJewelString, + kPoisonGoneString, + kHealingTipString, + kWispJewelStrings, + kMagicJewelStrings, + + kThePoisonStrings, + kFluteStrings, + + kFlaskFullString, + kFullFlaskString, + + kVeryCleverString, + kNewGameString, + + kDefaultShapes, + kHealing1Shapes, + kHealing2Shapes, + kPoisonDeathShapes, + kFluteShapes, + kWinter1Shapes, + kWinter2Shapes, + kWinter3Shapes, + kDrinkShapes, + kWispShapes, + kMagicAnimShapes, + kBranStoneShapes, + + kPaletteList1, + kPaletteList2, + kPaletteList3, + kPaletteList4, + kPaletteList5, + kPaletteList6, + kPaletteList7, + kPaletteList8, + kPaletteList9, + kPaletteList10, + kPaletteList11, + kPaletteList12, + kPaletteList13, + kPaletteList14, + kPaletteList15, + kPaletteList16, + kPaletteList17, + kPaletteList18, + kPaletteList19, + kPaletteList20, + kPaletteList21, + kPaletteList22, + kPaletteList23, + kPaletteList24, + kPaletteList25, + kPaletteList26, + kPaletteList27, + kPaletteList28, + kPaletteList29, + kPaletteList30, + kPaletteList31, + kPaletteList32, + kPaletteList33, + + kGUIStrings, + kConfigStrings, + + kKyra1TownsSFXTable, + + kMaxResIDs +}; + +struct ExtractEntry { + int id; + uint32 startOff; + uint32 endOff; +}; + +struct ExtractFilename { + int id; + int type; + const char *filename; +}; + +enum kSpecial { + kTalkieVersion = 0, + kDemoVersion = 1, + kFMTownsVersion = 2 +}; + +struct SpecialExtension { + int special; + const char *ext; +}; + +enum kGame { + kKyra1 = 0, + kKyra2, + kKyra3 +}; + +struct Game { + int game; + int lang; + int special; + + const char *md5; + const ExtractEntry *entries; +}; + +#define GAME_DUMMY_ENTRY { -1, -1, -1, 0, 0 } + +struct GameNeed { + int game; + int special; + + const int *entries; +}; + +enum kExtractType { + kTypeLanguageList = 0, + kTypeStringList, + kTypeRoomList, + kTypeShapeList, + kTypeRawData +}; + +struct ExtractType { + int type; + bool (*extract)(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename); + void (*createFilename)(char *dstFilename, const int lang, const int special, const char *filename); +}; + +#endif diff --git a/tools/create_kyradat/eng.h b/tools/create_kyradat/eng.h new file mode 100644 index 0000000000..72feff62e7 --- /dev/null +++ b/tools/create_kyradat/eng.h @@ -0,0 +1,190 @@ +const ExtractEntry kyra1EngFloppy[] = { + { kKallakWritingSeq, 0x0002FE5E, 0x00030653 }, + { kMalcolmTreeSeq, 0x00030653, 0x00030869 }, + { kWestwoodLogoSeq, 0x00030869, 0x000308B4 }, + { kKyrandiaLogoSeq, 0x000308B4, 0x00030910 }, + { kKallakMalcolmSeq, 0x00030910, 0x00030B7B }, + { kForestSeq, 0x00030B7B, 0x00030D10 }, + { kIntroCPSStrings, 0x00030D10, 0x00030D24 }, + { kIntroWSAStrings, 0x00030D24, 0x00030DA4 }, + { kIntroCOLStrings, 0x00030DA4, 0x00030DCF }, + { kIntroStrings, 0x00030DCF, 0x000312C4 }, + { kRoomList, 0x00028020, 0x0002CDF6 }, + { kRoomFilenames, 0x0003386A, 0x00033B46 }, + { kCharacterImageFilenames, 0x0003268D, 0x00032771 }, + { kDefaultShapes, 0x0002CFB0, 0x0002D43A }, + { kItemNames, 0x00033F2E, 0x00034396 }, + { kTakenStrings, 0x00033822, 0x00033832 }, + { kPlacedStrings, 0x00033832, 0x0003383B }, + { kDroppedStrings, 0x00033860, 0x0003386A }, + { kNoDropStrings, 0x000337DA, 0x00033821 }, + { kAmuleteAnimSeq, 0x0002EA9C, 0x0002EAC6 }, + { kPaletteList1, 0x00025100, 0x00025115 }, + { kPaletteList2, 0x00025115, 0x00025148 }, + { kPaletteList3, 0x00025148, 0x0002517B }, + { kPaletteList4, 0x0002517B, 0x000251AE }, + { kPaletteList5, 0x000251AE, 0x000251E1 }, + { kPaletteList6, 0x000251E1, 0x00025214 }, + { kPaletteList7, 0x00025214, 0x0002524A }, + { kPaletteList8, 0x0002524A, 0x00025280 }, + { kPaletteList9, 0x00025280, 0x000252AD }, + { kPaletteList10, 0x000252AD, 0x000252DA }, + { kPaletteList11, 0x000252DA, 0x00025307 }, + { kPaletteList12, 0x00025307, 0x00025334 }, + { kPaletteList13, 0x00025334, 0x00025361 }, + { kPaletteList14, 0x00025361, 0x0002539D }, + { kPaletteList15, 0x0002539D, 0x000253CA }, + { kPaletteList16, 0x000253CA, 0x000253EB }, + { kPaletteList17, 0x000253EB, 0x0002540C }, + { kPaletteList18, 0x0002540C, 0x00025421 }, + { kPaletteList19, 0x00025421, 0x00025436 }, + { kPaletteList20, 0x00025436, 0x0002544B }, + { kPaletteList21, 0x0002544B, 0x00025460 }, + { kPaletteList22, 0x00025460, 0x00025475 }, + { kPaletteList23, 0x00025475, 0x0002548A }, + { kPaletteList24, 0x0002548A, 0x000254BA }, + { kPaletteList25, 0x000254BA, 0x000254EA }, + { kPaletteList26, 0x000254EA, 0x0002551A }, + { kPaletteList27, 0x0002551A, 0x0002554A }, + { kPaletteList28, 0x0002554A, 0x0002557A }, + { kPaletteList29, 0x0002557A, 0x000255AA }, + { kPaletteList30, 0x000255AA, 0x000255E6 }, + { kPaletteList31, 0x000255E6, 0x0002560D }, + { kPaletteList32, 0x0002560D, 0x00025634 }, + { kPaletteList33, 0x00025634, 0x00025670 }, + { kPutDownString, 0x0002EBCE, 0x0002EBF4 }, + { kWaitAmuletString, 0x0002EBF4, 0x0002EC31 }, + { kBlackJewelString, 0x0002EC31, 0x0002EC54 }, + { kHealingTipString, 0x0002EC54, 0x0002EC81 }, + { kPoisonGoneString, 0x0002ECE7, 0x0002ED14 }, + { kHealing1Shapes, 0x0002D4A3, 0x0002D53D }, + { kHealing2Shapes, 0x0002D53D, 0x0002D60F }, + { kThePoisonStrings, 0x0002F8DC, 0x0002F933 }, + { kFluteStrings, 0x00031C7B, 0x00031CB7 }, + { kPoisonDeathShapes, 0x0002D903, 0x0002D98F }, + { kFluteShapes, 0x0002D807, 0x0002D903 }, + { kWinter1Shapes, 0x0002D60F, 0x0002D640 }, + { kWinter2Shapes, 0x0002D640, 0x0002D735 }, + { kWinter3Shapes, 0x0002D735, 0x0002D751 }, + { kDrinkShapes, 0x0002D43A, 0x0002D4A3 }, + { kWispShapes, 0x0002D751, 0x0002D807 }, + { kMagicAnimShapes, 0x0002D98F, 0x0002D9B2 }, + { kBranStoneShapes, 0x0002D9B2, 0x0002DA20 }, + { kWispJewelStrings, 0x0002EC81, 0x0002ECD4 }, + { kMagicJewelStrings, 0x0002ECD4, 0x0002ECE7 }, + { kFlaskFullString, 0x0002F9EB, 0x0002FA07 }, + { kFullFlaskString, 0x0002F954, 0x0002F9EB }, + { kOutroReunionSeq, 0x000313C1, 0x00031908 }, + { kOutroHomeString, 0x000319C2, 0x000319C7 }, + { kVeryCleverString, 0x00031922, 0x00031954 }, + { kGUIStrings, 0x0002EE7A, 0x0002F02A }, + { kNewGameString, 0x00032466, 0x0003247B }, + { kConfigStrings, 0x0002f870, 0x0002f8af }, + { -1, 0, 0 } +}; + +const ExtractEntry kyra1EngCD[] = { + { kKallakWritingSeq, 0x0003008F, 0x00030894 }, + { kMalcolmTreeSeq, 0x00030894, 0x00030AC4 }, + { kWestwoodLogoSeq, 0x00030AC4, 0x00030B0F }, + { kKyrandiaLogoSeq, 0x00030B0F, 0x00030BB5 }, + { kKallakMalcolmSeq, 0x00030BB5, 0x00030E6D }, + { kForestSeq, 0x00030E6D, 0x000310E0 }, + { kIntroCPSStrings, 0x000310E0, 0x000310F5 }, + { kIntroWSAStrings, 0x000310F5, 0x00031175 }, + { kIntroCOLStrings, 0x00031175, 0x000311A0 }, + { kIntroStrings, 0x000311A0, 0x00031696 }, + { kRoomList, 0x00028280, 0x0002D056 }, + { kRoomFilenames, 0x00033F2C, 0x00034208 }, + { kCharacterImageFilenames, 0x00032F22, 0x00033006 }, + { kDefaultShapes, 0x0002D210, 0x0002D69A }, + { kItemNames, 0x00034442, 0x000348AA }, + { kTakenStrings, 0x00033EE4, 0x00033EF4 }, + { kPlacedStrings, 0x00033EF4, 0x00033EFD }, + { kDroppedStrings, 0x00033F22, 0x00033F2C }, + { kNoDropStrings, 0x00033E9C, 0x00033EE3 }, + { kAmuleteAnimSeq, 0x0002EE1C, 0x0002EE46 }, + { kPaletteList1, 0x00025530, 0x00025545 }, + { kPaletteList2, 0x00025545, 0x00025578 }, + { kPaletteList3, 0x00025578, 0x000255AB }, + { kPaletteList4, 0x000255AB, 0x000255DE }, + { kPaletteList5, 0x000255DE, 0x00025611 }, + { kPaletteList6, 0x00025611, 0x00025644 }, + { kPaletteList7, 0x00025644, 0x0002567A }, + { kPaletteList8, 0x0002567A, 0x000256B0 }, + { kPaletteList9, 0x000256B0, 0x000256DD }, + { kPaletteList10, 0x000256DD, 0x0002570A }, + { kPaletteList11, 0x0002570A, 0x00025737 }, + { kPaletteList12, 0x00025737, 0x00025764 }, + { kPaletteList13, 0x00025764, 0x00025791 }, + { kPaletteList14, 0x00025791, 0x000257CD }, + { kPaletteList15, 0x000257CD, 0x000257FA }, + { kPaletteList16, 0x000257FA, 0x0002581B }, + { kPaletteList17, 0x0002581B, 0x0002583C }, + { kPaletteList18, 0x0002583C, 0x00025851 }, + { kPaletteList19, 0x00025851, 0x00025866 }, + { kPaletteList20, 0x00025866, 0x0002587B }, + { kPaletteList21, 0x0002587B, 0x00025890 }, + { kPaletteList22, 0x00025890, 0x000258A5 }, + { kPaletteList23, 0x000258A5, 0x000258BA }, + { kPaletteList24, 0x000258BA, 0x000258EA }, + { kPaletteList25, 0x000258EA, 0x0002591A }, + { kPaletteList26, 0x0002591A, 0x0002594A }, + { kPaletteList27, 0x0002594A, 0x0002597A }, + { kPaletteList28, 0x0002597A, 0x000259AA }, + { kPaletteList29, 0x000259AA, 0x000259DA }, + { kPaletteList30, 0x000259DA, 0x00025A16 }, + { kPaletteList31, 0x00025A16, 0x00025A3D }, + { kPaletteList32, 0x00025A3D, 0x00025A64 }, + { kPaletteList33, 0x00025A64, 0x00025AA0 }, + { kPutDownString, 0x0002EF50, 0x0002EF76 }, + { kWaitAmuletString, 0x0002EF76, 0x0002EFB3 }, + { kBlackJewelString, 0x0002EFB3, 0x0002EFD6 }, + { kHealingTipString, 0x0002EFD6, 0x0002F003 }, + { kPoisonGoneString, 0x0002F068, 0x0002F095 }, + { kHealing1Shapes, 0x0002D703, 0x0002D79D }, + { kHealing2Shapes, 0x0002D79D, 0x0002D86F }, + { kThePoisonStrings, 0x0002FCCA, 0x0002FD21 }, + { kFluteStrings, 0x00032510, 0x000325AC }, + { kPoisonDeathShapes, 0x0002DB63, 0x0002DBEF }, + { kFluteShapes, 0x0002DA67, 0x0002DB63 }, + { kWinter1Shapes, 0x0002D86F, 0x0002D8A0 }, + { kWinter2Shapes, 0x0002D8A0, 0x0002D995 }, + { kWinter3Shapes, 0x0002D995, 0x0002D9B1 }, + { kDrinkShapes, 0x0002D69A, 0x0002D703 }, + { kWispShapes, 0x0002D9B1, 0x0002DA67 }, + { kMagicAnimShapes, 0x0002DBEF, 0x0002DC12 }, + { kBranStoneShapes, 0x0002DC12, 0x0002DC80 }, + { kWispJewelStrings, 0x0002F003, 0x0002F055 }, + { kMagicJewelStrings, 0x0002F055, 0x0002F068 }, + { kFlaskFullString, 0x0002FDE1, 0x0002FDFD }, + { kFullFlaskString, 0x0002FD4A, 0x0002FDE1 }, + { kOutroReunionSeq, 0x00031791, 0x00031D76 }, + { kOutroHomeString, 0x00031E3A, 0x00031E3F }, + { kVeryCleverString, 0x00031D90, 0x00031DC2 }, + { kGUIStrings, 0x0002F1EE, 0x0002F3F7 }, + { kNewGameString, 0x00032CFB, 0x00032D10 }, + { kConfigStrings, 0x0002fc3d, 0x0002fc9e }, + { -1, 0, 0 } +}; + +const ExtractEntry kyra1EngDemo[] = { + { kWestwoodLogoSeq, 0x00015327, 0x0001536B }, + { kKyrandiaLogoSeq, 0x0001536B, 0x000153BF }, + { kIntroCPSStrings, 0x000154B1, 0x000154BD }, + { kIntroWSAStrings, 0x000154BD, 0x0001550A }, + { kIntroCOLStrings, 0x0001550A, 0x00015550 }, + { kIntroStrings, 0x00015550, 0x0001584A }, + { kDemo1Seq, 0x000153BF, 0x000153E5 }, + { kDemo2Seq, 0x000153E5, 0x00015408 }, + { kDemo3Seq, 0x00015408, 0x00015461 }, + { kDemo4Seq, 0x00015461, 0x00015481 }, + { -1, 0, 0 } +}; + +const Game kyra1EngGames[] = { + { kKyra1, EN_ANY, -1, "76a4fc84e173cadb6369785787e1546e", kyra1EngFloppy }, + { kKyra1, EN_ANY, kTalkieVersion, "1ebc18f3e7fbb72474a55cb0fa089ed4", kyra1EngCD }, + { kKyra1, EN_ANY, kDemoVersion, "7b7504c8560ffc914d34c44c71b3094c", kyra1EngDemo }, + GAME_DUMMY_ENTRY +}; diff --git a/tools/create_kyradat/esp.h b/tools/create_kyradat/esp.h new file mode 100644 index 0000000000..79d8bd00e7 --- /dev/null +++ b/tools/create_kyradat/esp.h @@ -0,0 +1,39 @@ +const ExtractEntry kyra1EspFloppy[] = { + { kKallakWritingSeq, 0x00030462, 0x00030C57 }, + { kMalcolmTreeSeq, 0x00030C57, 0x00030E6D }, + { kWestwoodLogoSeq, 0x00030E6D, 0x00030EB8 }, + { kKyrandiaLogoSeq, 0x00030EB8, 0x00030F14 }, + { kKallakMalcolmSeq, 0x00030F14, 0x0003117F }, + { kForestSeq, 0x0003117F, 0x00031314 }, + { kIntroCPSStrings, 0x00031314, 0x00031328 }, + { kIntroWSAStrings, 0x00031328, 0x000313A8 }, + { kIntroCOLStrings, 0x000313A8, 0x000313D3 }, + { kIntroStrings, 0x000313D3, 0x000319A2 }, + { kItemNames, 0x0003467A, 0x00034BAA }, + { kTakenStrings, 0x00033F14, 0x00033F28 }, + { kPlacedStrings, 0x00033F28, 0x00033F35 }, + { kDroppedStrings, 0x00033F5E, 0x00033F66 }, + { kNoDropStrings, 0x00033ED6, 0x00033F13 }, + { kPutDownString, 0x0002F100, 0x0002F12D }, + { kWaitAmuletString, 0x0002F12D, 0x0002F16F }, + { kBlackJewelString, 0x0002F16F, 0x0002F194 }, + { kHealingTipString, 0x0002F194, 0x0002F1BC }, + { kPoisonGoneString, 0x0002F22C, 0x0002F25F }, + { kThePoisonStrings, 0x0002FEC6, 0x0002FF1F }, + { kFluteStrings, 0x00032361, 0x000323B3 }, + { kWispJewelStrings, 0x0002F1BC, 0x0002F21B }, + { kMagicJewelStrings, 0x0002F21B, 0x0002F22C }, + { kFlaskFullString, 0x0002FFDA, 0x0002FFF5 }, + { kFullFlaskString, 0x0002FF40, 0x0002FFDA }, + { kOutroHomeString, 0x000320A8, 0x000320AD }, + { kVeryCleverString, 0x00032004, 0x0003203A }, + { kGUIStrings, 0x0002f3d0, 0x0002f60a }, + { kNewGameString, 0x00032b62, 0x00032b7d }, + { kConfigStrings, 0x0002fe50, 0x0002fe9a }, + { -1, 0, 0 } +}; + +const Game kyra1EspGames[] = { + { kKyra1, ES_ESP, -1, "9ff130d2558bcd674d4074849d93c362", kyra1EspFloppy }, + GAME_DUMMY_ENTRY +}; diff --git a/tools/create_kyradat/fre.h b/tools/create_kyradat/fre.h new file mode 100644 index 0000000000..970769f95a --- /dev/null +++ b/tools/create_kyradat/fre.h @@ -0,0 +1,79 @@ +const ExtractEntry kyra1FreFloppy[] = { + { kKallakWritingSeq, 0x00030598, 0x00030D8D }, + { kMalcolmTreeSeq, 0x00030D8D, 0x00030FA3 }, + { kWestwoodLogoSeq, 0x00030FA3, 0x00030FEE }, + { kKyrandiaLogoSeq, 0x00030FEE, 0x0003104A }, + { kKallakMalcolmSeq, 0x0003104A, 0x000312B5 }, + { kForestSeq, 0x000312B5, 0x0003144A }, + { kIntroCPSStrings, 0x0003144A, 0x0003145E }, + { kIntroWSAStrings, 0x0003145E, 0x000314DE }, + { kIntroCOLStrings, 0x000314DE, 0x00031509 }, + { kIntroStrings, 0x00031509, 0x00031AF8 }, + { kItemNames, 0x00034862, 0x00034d68 }, + { kTakenStrings, 0x00034062, 0x00034080 }, + { kPlacedStrings, 0x00034080, 0x00034091 }, + { kDroppedStrings, 0x0003412f, 0x00034140 }, + { kNoDropStrings, 0x00034016, 0x00034062 }, + { kPutDownString, 0x0002f240, 0x0002f26e }, + { kWaitAmuletString, 0x0002f26e, 0x0002f2b7 }, + { kBlackJewelString, 0x0002f2b7, 0x0002f2e2 }, + { kHealingTipString, 0x0002f2e2, 0x0002f318 }, + { kPoisonGoneString, 0x0002f384, 0x0002f3dd }, + { kThePoisonStrings, 0x0003000e, 0x00030076 }, + { kFluteStrings, 0x000324af, 0x000324f4 }, + { kWispJewelStrings, 0x0002f318, 0x0002f373 }, + { kMagicJewelStrings, 0x0002f373, 0x0002f384 }, + { kFlaskFullString, 0x0003011c, 0x0003013a }, + { kFullFlaskString, 0x00030096, 0x0003011c }, + { kOutroHomeString, 0x000321f4, 0x000321fb }, + { kVeryCleverString, 0x0003215e, 0x00032185 }, + { kGUIStrings, 0x0002f51c, 0x0002f750 }, + { kNewGameString, 0x00032ca2, 0x00032cbf }, + { kConfigStrings, 0x0002ff96, 0x0002ffe1 }, + { -1, 0, 0 } +}; + +const ExtractEntry kyra1FreCD[] = { + { kKallakWritingSeq, 0x0003023D, 0x00030A42 }, + { kMalcolmTreeSeq, 0x00030A42, 0x00030C72 }, + { kWestwoodLogoSeq, 0x00030C72, 0x00030CBD }, + { kKyrandiaLogoSeq, 0x00030CBD, 0x00030D63 }, + { kKallakMalcolmSeq, 0x00030D63, 0x0003101B }, + { kForestSeq, 0x0003101B, 0x0003128E }, + { kIntroCPSStrings, 0x0003128E, 0x000312A3 }, + { kIntroWSAStrings, 0x000312A3, 0x00031323 }, + { kIntroCOLStrings, 0x00031323, 0x0003134E }, + { kIntroStrings, 0x0003134E, 0x0003193E }, + { kRoomList, 0x000283A0, 0x0002D176 }, + { kRoomFilenames, 0x000342AA, 0x00034586 }, + { kCharacterImageFilenames, 0x00033206, 0x000332EA }, + { kDefaultShapes, 0x0002D330, 0x0002D823 }, + { kItemNames, 0x000347C0, 0x00034CC6 }, + { kTakenStrings, 0x0003427B, 0x0003428A }, + { kPlacedStrings, 0x000341EA, 0x000341FB }, + { kDroppedStrings, 0x00034299, 0x000342AA }, + { kNoDropStrings, 0x00034180, 0x000341CC }, + { kPutDownString, 0x0002F070, 0x0002F09E }, + { kWaitAmuletString, 0x0002F09E, 0x0002F0E7 }, + { kBlackJewelString, 0x0002F0E7, 0x0002F112 }, + { kHealingTipString, 0x0002F112, 0x0002F148 }, + { kPoisonGoneString, 0x0002F1A9, 0x0002F1D3 }, + { kThePoisonStrings, 0x0002FE76, 0x0002FEDE }, + { kFluteStrings, 0x000327EA, 0x0003282F }, + { kWispJewelStrings, 0x0002F148, 0x0002F198 }, + { kMagicJewelStrings, 0x0002F198, 0x0002F1A9 }, + { kFlaskFullString, 0x0002FF8C, 0x0002FFAA }, + { kFullFlaskString, 0x0002FF06, 0x0002FF8C }, + { kOutroHomeString, 0x000320D6, 0x000320DD }, + { kVeryCleverString, 0x00032038, 0x0003205F }, + { kGUIStrings, 0x0002f32c, 0x0002f589 }, + { kNewGameString, 0x00032FDF, 0x00032FFC }, + { kConfigStrings, 0x0002fdcf, 0x0002fe49 }, + { -1, 0, 0 } +}; + +const Game kyra1FreGames[] = { + { kKyra1, FR_FRA, -1, "aa9d6d78d8b199deaf48efeca6d19af2", kyra1FreFloppy }, + { kKyra1, FR_FRA, kTalkieVersion, "307c5d4a554d9068ac3d326e350ae4a6", kyra1FreCD }, + GAME_DUMMY_ENTRY +}; diff --git a/tools/create_kyradat/ger.h b/tools/create_kyradat/ger.h new file mode 100644 index 0000000000..5ecfc7e644 --- /dev/null +++ b/tools/create_kyradat/ger.h @@ -0,0 +1,80 @@ +const ExtractEntry kyra1GerFloppy[] = { + { kKallakWritingSeq, 0x000304F2, 0x00030CE7 }, + { kMalcolmTreeSeq, 0x00030CE7, 0x00030EFD }, + { kWestwoodLogoSeq, 0x00030EFD, 0x00030F48 }, + { kKyrandiaLogoSeq, 0x00030F48, 0x00030FA4 }, + { kKallakMalcolmSeq, 0x00030FA4, 0x0003120F }, + { kForestSeq, 0x0003120F, 0x000313A4 }, + { kIntroCPSStrings, 0x000313A4, 0x000313B8 }, + { kIntroWSAStrings, 0x000313B8, 0x00031438 }, + { kIntroCOLStrings, 0x00031438, 0x00031463 }, + { kIntroStrings, 0x00031463, 0x00031A68 }, + { kRoomFilenames, 0x00034058, 0x00034334 }, + { kItemNames, 0x00034776, 0x00034C88 }, + { kTakenStrings, 0x00033FEE, 0x0003400A }, + { kPlacedStrings, 0x0003400A, 0x00034015 }, + { kDroppedStrings, 0x00034046, 0x00034057 }, + { kNoDropStrings, 0x00033FA2, 0x00033FEE }, + { kPutDownString, 0x0002F100, 0x0002F128 }, + { kWaitAmuletString, 0x0002F128, 0x0002F170 }, + { kBlackJewelString, 0x0002F170, 0x0002F1A1 }, + { kHealingTipString, 0x0002F1A1, 0x0002F1DD }, + { kPoisonGoneString, 0x0002F252, 0x0002F288 }, + { kThePoisonStrings, 0x0002FF00, 0x0002FF72 }, + { kFluteStrings, 0x0003243F, 0x0003247F }, + { kWispJewelStrings, 0x0002F1DD, 0x0002F23E }, + { kMagicJewelStrings, 0x0002F23E, 0x0002F252 }, + { kFlaskFullString, 0x00030041, 0x0003005F }, + { kFullFlaskString, 0x0002FF92, 0x00030041 }, + { kOutroHomeString, 0x0003217E, 0x0003218C }, + { kVeryCleverString, 0x000320CC, 0x0003210F }, + { kGUIStrings, 0x0002f3fa, 0x0002f630 }, + { kNewGameString, 0x00032c2e, 0x00032c4b }, + { kConfigStrings, 0x0002fe76, 0x0002fed4 }, + { -1, 0, 0 } +}; + +const ExtractEntry kyra1GerCD[] = { + { kKallakWritingSeq, 0x0003018F, 0x00030994 }, + { kMalcolmTreeSeq, 0x00030994, 0x00030BC4 }, + { kWestwoodLogoSeq, 0x00030BC4, 0x00030C0F }, + { kKyrandiaLogoSeq, 0x00030C0F, 0x00030CB5 }, + { kKallakMalcolmSeq, 0x00030CB5, 0x00030F6D }, + { kForestSeq, 0x00030F6D, 0x000311E0 }, + { kIntroCPSStrings, 0x000311E0, 0x000311F5 }, + { kIntroWSAStrings, 0x000311F5, 0x00031275 }, + { kIntroCOLStrings, 0x00031275, 0x000312A0 }, + { kIntroStrings, 0x000312A0, 0x000318A6 }, + { kRoomList, 0x00028280, 0x0002D056 }, + { kRoomFilenames, 0x000341FA, 0x000344D6 }, + { kCharacterImageFilenames, 0x000331CA, 0x000332AE }, + { kDefaultShapes, 0x0002D210, 0x0002D703 }, + { kItemNames, 0x00034710, 0x00034C22 }, + { kTakenStrings, 0x00034190, 0x000341AC }, + { kPlacedStrings, 0x000341AC, 0x000341B7 }, + { kDroppedStrings, 0x000341E8, 0x000341F9 }, + { kNoDropStrings, 0x00034144, 0x00034190 }, + { kPutDownString, 0x0002EF50, 0x0002EF78 }, + { kWaitAmuletString, 0x0002EF78, 0x0002EFC0 }, + { kBlackJewelString, 0x0002EFC0, 0x0002EFF1 }, + { kHealingTipString, 0x0002EFF1, 0x0002F02D }, + { kPoisonGoneString, 0x0002F099, 0x0002F0CF }, + { kThePoisonStrings, 0x0002FD82, 0x0002FDF4 }, + { kFluteStrings, 0x000327B4, 0x000327F4 }, + { kWispJewelStrings, 0x0002F02D, 0x0002F085 }, + { kMagicJewelStrings, 0x0002F085, 0x0002F099 }, + { kFlaskFullString, 0x0002FECB, 0x0002FEE9 }, + { kFullFlaskString, 0x0002FE1C, 0x0002FECB }, + { kOutroHomeString, 0x0003205A, 0x00032068 }, + { kVeryCleverString, 0x00031FA0, 0x00031FE3 }, + { kGUIStrings, 0x0002F22C, 0x0002F48D }, + { kNewGameString, 0x00032FA3, 0x00032FC0 }, + { kConfigStrings, 0x0002fcd3, 0x0002fd55 }, + { -1, 0, 0 } +}; + +const Game kyra1GerGames[] = { + { kKyra1, DE_DEU, -1, "9442d6f7db6a41f3dd4aa4de5d36e107", kyra1GerFloppy }, + { kKyra1, DE_DEU, kTalkieVersion, "c65d381184f98ac26d9efd2d45baef51", kyra1GerCD }, + GAME_DUMMY_ENTRY +}; diff --git a/tools/create_kyradat/md5.cpp b/tools/create_kyradat/md5.cpp new file mode 100644 index 0000000000..abdc002eb0 --- /dev/null +++ b/tools/create_kyradat/md5.cpp @@ -0,0 +1,261 @@ +/* Scumm Tools + * Copyright (C) 2004-2006 The ScummVM Team + * + * 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/tools/trunk/utils/md5.cpp $ + * $Id: md5.cpp 23138 2006-06-15 15:44:06Z h00ligan $ + * + */ + +#include "md5.h" + +#define GET_UINT32(n, b, i) (n) = READ_LE_UINT32(b + i) +#define PUT_UINT32(n, b, i) WRITE_LE_UINT32(b + i, n) + +void md5_starts(md5_context *ctx) { + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; +} + +static void md5_process(md5_context *ctx, const uint8 data[64]) { + uint32 X[16], A, B, C, D; + + GET_UINT32(X[0], data, 0); + GET_UINT32(X[1], data, 4); + GET_UINT32(X[2], data, 8); + GET_UINT32(X[3], data, 12); + GET_UINT32(X[4], data, 16); + GET_UINT32(X[5], data, 20); + GET_UINT32(X[6], data, 24); + GET_UINT32(X[7], data, 28); + GET_UINT32(X[8], data, 32); + GET_UINT32(X[9], data, 36); + GET_UINT32(X[10], data, 40); + GET_UINT32(X[11], data, 44); + GET_UINT32(X[12], data, 48); + GET_UINT32(X[13], data, 52); + GET_UINT32(X[14], data, 56); + GET_UINT32(X[15], data, 60); + +#define S(x, n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) + +#define P(a, b, c, d, k, s, t) \ +{ \ + a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \ +} + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + +#define F(x, y, z) (z ^ (x & (y ^ z))) + + P(A, B, C, D, 0, 7, 0xD76AA478); + P(D, A, B, C, 1, 12, 0xE8C7B756); + P(C, D, A, B, 2, 17, 0x242070DB); + P(B, C, D, A, 3, 22, 0xC1BDCEEE); + P(A, B, C, D, 4, 7, 0xF57C0FAF); + P(D, A, B, C, 5, 12, 0x4787C62A); + P(C, D, A, B, 6, 17, 0xA8304613); + P(B, C, D, A, 7, 22, 0xFD469501); + P(A, B, C, D, 8, 7, 0x698098D8); + P(D, A, B, C, 9, 12, 0x8B44F7AF); + P(C, D, A, B, 10, 17, 0xFFFF5BB1); + P(B, C, D, A, 11, 22, 0x895CD7BE); + P(A, B, C, D, 12, 7, 0x6B901122); + P(D, A, B, C, 13, 12, 0xFD987193); + P(C, D, A, B, 14, 17, 0xA679438E); + P(B, C, D, A, 15, 22, 0x49B40821); + +#undef F + +#define F(x, y, z) (y ^ (z & (x ^ y))) + + P(A, B, C, D, 1, 5, 0xF61E2562); + P(D, A, B, C, 6, 9, 0xC040B340); + P(C, D, A, B, 11, 14, 0x265E5A51); + P(B, C, D, A, 0, 20, 0xE9B6C7AA); + P(A, B, C, D, 5, 5, 0xD62F105D); + P(D, A, B, C, 10, 9, 0x02441453); + P(C, D, A, B, 15, 14, 0xD8A1E681); + P(B, C, D, A, 4, 20, 0xE7D3FBC8); + P(A, B, C, D, 9, 5, 0x21E1CDE6); + P(D, A, B, C, 14, 9, 0xC33707D6); + P(C, D, A, B, 3, 14, 0xF4D50D87); + P(B, C, D, A, 8, 20, 0x455A14ED); + P(A, B, C, D, 13, 5, 0xA9E3E905); + P(D, A, B, C, 2, 9, 0xFCEFA3F8); + P(C, D, A, B, 7, 14, 0x676F02D9); + P(B, C, D, A, 12, 20, 0x8D2A4C8A); + +#undef F + +#define F(x, y, z) (x ^ y ^ z) + + P(A, B, C, D, 5, 4, 0xFFFA3942); + P(D, A, B, C, 8, 11, 0x8771F681); + P(C, D, A, B, 11, 16, 0x6D9D6122); + P(B, C, D, A, 14, 23, 0xFDE5380C); + P(A, B, C, D, 1, 4, 0xA4BEEA44); + P(D, A, B, C, 4, 11, 0x4BDECFA9); + P(C, D, A, B, 7, 16, 0xF6BB4B60); + P(B, C, D, A, 10, 23, 0xBEBFBC70); + P(A, B, C, D, 13, 4, 0x289B7EC6); + P(D, A, B, C, 0, 11, 0xEAA127FA); + P(C, D, A, B, 3, 16, 0xD4EF3085); + P(B, C, D, A, 6, 23, 0x04881D05); + P(A, B, C, D, 9, 4, 0xD9D4D039); + P(D, A, B, C, 12, 11, 0xE6DB99E5); + P(C, D, A, B, 15, 16, 0x1FA27CF8); + P(B, C, D, A, 2, 23, 0xC4AC5665); + +#undef F + +#define F(x, y, z) (y ^ (x | ~z)) + + P(A, B, C, D, 0, 6, 0xF4292244); + P(D, A, B, C, 7, 10, 0x432AFF97); + P(C, D, A, B, 14, 15, 0xAB9423A7); + P(B, C, D, A, 5, 21, 0xFC93A039); + P(A, B, C, D, 12, 6, 0x655B59C3); + P(D, A, B, C, 3, 10, 0x8F0CCC92); + P(C, D, A, B, 10, 15, 0xFFEFF47D); + P(B, C, D, A, 1, 21, 0x85845DD1); + P(A, B, C, D, 8, 6, 0x6FA87E4F); + P(D, A, B, C, 15, 10, 0xFE2CE6E0); + P(C, D, A, B, 6, 15, 0xA3014314); + P(B, C, D, A, 13, 21, 0x4E0811A1); + P(A, B, C, D, 4, 6, 0xF7537E82); + P(D, A, B, C, 11, 10, 0xBD3AF235); + P(C, D, A, B, 2, 15, 0x2AD7D2BB); + P(B, C, D, A, 9, 21, 0xEB86D391); + +#undef F + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; +} + +void md5_update(md5_context *ctx, const uint8 *input, uint32 length) { + uint32 left, fill; + + if (!length) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += length; + ctx->total[0] &= 0xFFFFFFFF; + + if (ctx->total[0] < length) + ctx->total[1]++; + + if (left && length >= fill) { + memcpy((void *)(ctx->buffer + left), (const void *)input, fill); + md5_process(ctx, ctx->buffer); + length -= fill; + input += fill; + left = 0; + } + + while (length >= 64) { + md5_process(ctx, input); + length -= 64; + input += 64; + } + + if (length) { + memcpy((void *)(ctx->buffer + left), (const void *)input, length); + } +} + +static const uint8 md5_padding[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +void md5_finish(md5_context *ctx, uint8 digest[16]) { + uint32 last, padn; + uint32 high, low; + uint8 msglen[8]; + + high = (ctx->total[0] >> 29) | (ctx->total[1] << 3); + low = (ctx->total[0] << 3); + + PUT_UINT32(low, msglen, 0); + PUT_UINT32(high, msglen, 4); + + last = ctx->total[0] & 0x3F; + padn = (last < 56) ? (56 - last) : (120 - last); + + md5_update(ctx, md5_padding, padn); + md5_update(ctx, msglen, 8); + + PUT_UINT32(ctx->state[0], digest, 0); + PUT_UINT32(ctx->state[1], digest, 4); + PUT_UINT32(ctx->state[2], digest, 8); + PUT_UINT32(ctx->state[3], digest, 12); +} + +bool md5_file(const char *name, uint8 digest[16], uint32 length) { + FILE *f; + + f = fopen(name, "rb"); + if (f == NULL) { + printf("md5_file couldn't open '%s'", name); + return false; + } + + md5_context ctx; + uint32 i; + unsigned char buf[1000]; + bool restricted = (length != 0); + int readlen; + + if (!restricted || sizeof(buf) <= length) + readlen = sizeof(buf); + else + readlen = length; + + md5_starts(&ctx); + + + while ((i = (uint32)fread(buf, 1, readlen, f)) > 0) { + md5_update(&ctx, buf, i); + + length -= i; + if (restricted && length == 0) + break; + + if (restricted && sizeof(buf) > length) + readlen = length; + } + + md5_finish(&ctx, digest); + fclose(f); + return true; +} diff --git a/tools/create_kyradat/md5.h b/tools/create_kyradat/md5.h new file mode 100644 index 0000000000..c945684d83 --- /dev/null +++ b/tools/create_kyradat/md5.h @@ -0,0 +1,40 @@ +/* Scumm Tools + * Copyright (C) 2004-2006 The ScummVM Team + * + * 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/tools/trunk/utils/md5.h $ + * $Id: md5.h 23138 2006-06-15 15:44:06Z h00ligan $ + * + */ + +#ifndef COMMON_MD5_H +#define COMMON_MD5_H + +#include "util.h" + +typedef struct { + uint32 total[2]; + uint32 state[4]; + uint8 buffer[64]; +} md5_context; + +void md5_starts(md5_context *ctx); +void md5_update(md5_context *ctx, const uint8 *input, uint32 length); +void md5_finish(md5_context *ctx, uint8 digest[16]); + +bool md5_file(const char *name, uint8 digest[16], uint32 length = 0); + +#endif diff --git a/tools/create_kyradat/misc.h b/tools/create_kyradat/misc.h new file mode 100644 index 0000000000..191abf3370 --- /dev/null +++ b/tools/create_kyradat/misc.h @@ -0,0 +1,207 @@ +const int kyra1FloppyNeed[] = { + kKallakWritingSeq, + kMalcolmTreeSeq, + kWestwoodLogoSeq, + kKyrandiaLogoSeq, + kKallakMalcolmSeq, + kForestSeq, + kIntroCPSStrings, + kIntroCOLStrings, + kIntroWSAStrings, + kIntroStrings, + kRoomList, + kRoomFilenames, + kCharacterImageFilenames, + kDefaultShapes, + kItemNames, + kTakenStrings, + kPlacedStrings, + kDroppedStrings, + kNoDropStrings, + kAmuleteAnimSeq, + kPaletteList1, + kPaletteList2, + kPaletteList3, + kPaletteList4, + kPaletteList5, + kPaletteList6, + kPaletteList7, + kPaletteList8, + kPaletteList9, + kPaletteList10, + kPaletteList11, + kPaletteList12, + kPaletteList13, + kPaletteList14, + kPaletteList15, + kPaletteList16, + kPaletteList17, + kPaletteList18, + kPaletteList19, + kPaletteList20, + kPaletteList21, + kPaletteList22, + kPaletteList23, + kPaletteList24, + kPaletteList25, + kPaletteList26, + kPaletteList27, + kPaletteList28, + kPaletteList29, + kPaletteList30, + kPaletteList31, + kPaletteList32, + kPaletteList33, + kPutDownString, + kWaitAmuletString, + kBlackJewelString, + kHealingTipString, + kPoisonGoneString, + kHealing1Shapes, + kHealing2Shapes, + kThePoisonStrings, + kFluteStrings, + kPoisonDeathShapes, + kFluteShapes, + kWinter1Shapes, + kWinter2Shapes, + kWinter3Shapes, + kDrinkShapes, + kWispShapes, + kMagicAnimShapes, + kBranStoneShapes, + kWispJewelStrings, + kMagicJewelStrings, + kFlaskFullString, + kFullFlaskString, + kOutroReunionSeq, + kOutroHomeString, + kVeryCleverString, + kGUIStrings, + kNewGameString, + kConfigStrings, + -1 +}; + +const int kyra1CDNeed[] = { + kKallakWritingSeq, + kMalcolmTreeSeq, + kWestwoodLogoSeq, + kKyrandiaLogoSeq, + kKallakMalcolmSeq, + kForestSeq, + kIntroCPSStrings, + kIntroCOLStrings, + kIntroWSAStrings, + kIntroStrings, + kRoomList, + kRoomFilenames, + kCharacterImageFilenames, + kDefaultShapes, + kItemNames, + kTakenStrings, + kPlacedStrings, + kDroppedStrings, + kNoDropStrings, + kAmuleteAnimSeq, + kPaletteList1, + kPaletteList2, + kPaletteList3, + kPaletteList4, + kPaletteList5, + kPaletteList6, + kPaletteList7, + kPaletteList8, + kPaletteList9, + kPaletteList10, + kPaletteList11, + kPaletteList12, + kPaletteList13, + kPaletteList14, + kPaletteList15, + kPaletteList16, + kPaletteList17, + kPaletteList18, + kPaletteList19, + kPaletteList20, + kPaletteList21, + kPaletteList22, + kPaletteList23, + kPaletteList24, + kPaletteList25, + kPaletteList26, + kPaletteList27, + kPaletteList28, + kPaletteList29, + kPaletteList30, + kPaletteList31, + kPaletteList32, + kPaletteList33, + kPutDownString, + kWaitAmuletString, + kBlackJewelString, + kHealingTipString, + kPoisonGoneString, + kHealing1Shapes, + kHealing2Shapes, + kThePoisonStrings, + kFluteStrings, + kPoisonDeathShapes, + kFluteShapes, + kWinter1Shapes, + kWinter2Shapes, + kWinter3Shapes, + kDrinkShapes, + kWispShapes, + kMagicAnimShapes, + kBranStoneShapes, + kWispJewelStrings, + kMagicJewelStrings, + kFlaskFullString, + kFullFlaskString, + kOutroReunionSeq, + kOutroHomeString, + kVeryCleverString, + kGUIStrings, + kNewGameString, + kConfigStrings, + -1 +}; + +const int kyra1DemoNeed[] = { + kWestwoodLogoSeq, + kKyrandiaLogoSeq, + kIntroCPSStrings, + kIntroCOLStrings, + kIntroWSAStrings, + kIntroStrings, + kDemo1Seq, + kDemo2Seq, + kDemo3Seq, + kDemo4Seq, + -1 +}; + +const GameNeed gameNeedTable[] = { + { kKyra1, -1, kyra1FloppyNeed }, + { kKyra1, kTalkieVersion, kyra1CDNeed }, + { kKyra1, kDemoVersion, kyra1DemoNeed }, + { -1, -1, 0 } +}; + +const SpecialExtension specialTable[] = { + { kTalkieVersion, "CD" }, + { kDemoVersion, "DEM" }, + { kFMTownsVersion, "TNS" }, + { -1, 0 } +}; + +const Language languageTable[] = { + { EN_ANY, "ENG" }, + { DE_DEU, "GER" }, + { FR_FRA, "FRE" }, + { IT_ITA, "ITA" }, + { ES_ESP, "SPA" }, + { JA_JPN, "JPN" }, + { -1, 0 } +}; diff --git a/tools/create_kyradat/pak.cpp b/tools/create_kyradat/pak.cpp new file mode 100644 index 0000000000..63e9792d23 --- /dev/null +++ b/tools/create_kyradat/pak.cpp @@ -0,0 +1,244 @@ +/* Scumm Tools + * Copyright (C) 2007 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 "pak.h" + +bool PAKFile::loadFile(const char *file, const bool isAmiga) { + _isAmiga = isAmiga; + if (!file) + return true; + + delete _fileList; + _fileList = 0; + + FILE *pakfile = fopen(file, "rb"); + if (!pakfile) + return false; + + uint32 filesize = fileSize(pakfile); + + // TODO: get rid of temp. buffer + uint8 *buffer = new uint8[filesize]; + assert(buffer); + + fread(buffer, filesize, 1, pakfile); + + fclose(pakfile); + + const char *currentName = 0; + + uint32 startoffset = _isAmiga ? READ_BE_UINT32(buffer) : READ_LE_UINT32(buffer); + uint32 endoffset = 0; + uint8* position = buffer + 4; + + while (true) { + uint32 strlgt = strlen((const char*)position); + currentName = (const char*)position; + + if (!(*currentName)) + break; + + position += strlgt + 1; + endoffset = _isAmiga ? READ_BE_UINT32(position) : READ_LE_UINT32(position); + if (endoffset > filesize) { + endoffset = filesize; + } else if (endoffset == 0) { + endoffset = filesize; + } + position += 4; + + uint8 *data = new uint8[endoffset - startoffset]; + assert(data); + memcpy(data, buffer + startoffset, endoffset - startoffset); + addFile(currentName, data, endoffset - startoffset); + data = 0; + + if (endoffset == filesize) + break; + + startoffset = endoffset; + } + + delete [] buffer; + return true; +} + +bool PAKFile::saveFile(const char *file) { + if (!_fileList) + return true; + + FILE *f = fopen(file, "wb"); + if (!f) { + error("couldn't open file '%s' for writing", file); + return false; + } + + // TODO: implement error handling + uint32 startAddr = _fileList->getTableSize()+5+4; + static const char *zeroName = "\0\0\0\0\0"; + + uint32 curAddr = startAddr; + for (FileList *cur = _fileList; cur; cur = cur->next) { + if (_isAmiga) + writeUint32BE(f, curAddr); + else + writeUint32LE(f, curAddr); + fwrite(cur->filename, 1, strlen(cur->filename) + 1, f); + curAddr += cur->size; + } + if (_isAmiga) + writeUint32BE(f, curAddr); + else + writeUint32LE(f, curAddr); + fwrite(zeroName, 1, 5, f); + + for (FileList *cur = _fileList; cur; cur = cur->next) + fwrite(cur->data, 1, cur->size, f); + + fclose(f); + return true; +} + +void PAKFile::drawFileList() { + FileList *cur = _fileList; + while (cur) { + printf("Filename: '%s' size: %d\n", cur->filename, cur->size); + cur = cur->next; + } +} + +bool PAKFile::outputAllFiles() { + FileList *cur = _fileList; + while (cur) { + FILE *file = fopen(cur->filename, "wb"); + if (!file) { + error("couldn't open file '%s' for writing", cur->filename); + return false; + } + printf("Exracting file '%s'...", cur->filename); + if (fwrite(cur->data, 1, cur->size, file) == cur->size) { + printf("OK\n"); + } else { + printf("FAILED\n"); + return false; + } + fclose(file); + cur = cur->next; + } + return true; +} + +bool PAKFile::outputFileAs(const char *f, const char *fn) { + FileList *cur = (_fileList != 0) ? _fileList->findEntry(f) : 0; + + if (!cur) { + error("file '%s' not found"); + return false; + } + + FILE *file = fopen(fn, "wb"); + if (!file) { + error("couldn't open file '%s' in write mode", fn); + return false; + } + printf("Exracting file '%s' to file '%s'...", cur->filename, fn); + if (fwrite(cur->data, 1, cur->size, file) == cur->size) { + printf("OK\n"); + } else { + printf("FAILED\n"); + return false; + } + fclose(file); + return true; +} + +const uint8 *PAKFile::getFileData(const char *file, uint32 *size) { + FileList *cur = (_fileList != 0) ? _fileList->findEntry(file) : 0; + + if (!cur) + return 0; + + if (size) + *size = cur->size; + return cur->data; +} + +bool PAKFile::addFile(const char *name, const char *file) { + if (_fileList && _fileList->findEntry(name)) { + error("entry '%s' already exists"); + return false; + } + + FILE *f = fopen(file, "rb"); + if (!f) { + error("couldn't open file '%s'", file); + return false; + } + + uint32 filesize = fileSize(f); + uint8 *data = new uint8[filesize]; + assert(data); + if (fread(data, 1, filesize, f) != filesize) { + error("couldn't read from file '%s'", file); + return false; + } + fclose(f); + return addFile(name, data, filesize); +} + +bool PAKFile::addFile(const char *name, uint8 *data, uint32 size) { + if (_fileList && _fileList->findEntry(name)) { + error("entry '%s' already exists"); + return false; + } + + FileList *newEntry = new FileList; + assert(newEntry); + newEntry->filename = new char[strlen(name)+1]; + assert(newEntry->filename); + strncpy(newEntry->filename, name, strlen(name)+1); + newEntry->size = size; + newEntry->data = data; + + if (_fileList) { + _fileList->addEntry(newEntry); + } else { + _fileList = newEntry; + } + return true; +} + +bool PAKFile::removeFile(const char *name) { + for (FileList *cur = _fileList, *last = 0; cur; last = cur, cur = cur->next) { + if (scumm_stricmp(cur->filename, name) == 0) { + FileList *next = cur->next; + cur->next = 0; + delete cur; + if (last) + last->next = next; + else + _fileList = next; + return true; + } + } + return false; +} diff --git a/tools/create_kyradat/pak.h b/tools/create_kyradat/pak.h new file mode 100644 index 0000000000..f81e0be011 --- /dev/null +++ b/tools/create_kyradat/pak.h @@ -0,0 +1,107 @@ +/* Scumm Tools + * Copyright (C) 2007 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$ + * + */ + +#ifndef KYRA_PAK_H +#define KYRA_PAK_H + +#include "util.h" +#include + +class PAKFile { +public: + PAKFile() : _fileList(0), _isAmiga(false) {} + ~PAKFile() { delete _fileList; } + + bool loadFile(const char *file, const bool isAmiga); + bool saveFile(const char *file); + void clearFile() { delete _fileList; _fileList = 0; } + + const uint32 getFileSize() const { return _fileList->getTableSize()+5+4+_fileList->getFileSize(); } + + void drawFileList(); + + bool outputAllFiles(); + + bool outputFile(const char *file) { return outputFileAs(file, file); } + bool outputFileAs(const char *file, const char *outputName); + const uint8 *getFileData(const char *file, uint32 *size); + + bool addFile(const char *name, const char *file); + bool addFile(const char *name, uint8 *data, uint32 size); + + bool removeFile(const char *name); +public: + struct FileList { + FileList() : filename(0), size(0), data(0), next(0) {} + ~FileList() { + delete [] filename; + delete [] data; + delete next; + } + + FileList *findEntry(const char *f) { + for (FileList *cur = this; cur; cur = cur->next) { + if (scumm_stricmp(cur->filename, f) != 0) + continue; + return cur; + } + return 0; + } + + const FileList *findEntry(const char *f) const { + for (const FileList *cur = this; cur; cur = cur->next) { + if (scumm_stricmp(cur->filename, f) != 0) + continue; + return cur; + } + return 0; + } + + void addEntry(FileList *e) { + if (next) + next->addEntry(e); + else + next = e; + } + uint32 getTableSize() const { + return strlen(filename)+1+4+((next != 0) ? next->getTableSize() : 0); + } + uint32 getFileSize() const { + return size + (next != 0 ? next->getFileSize() : 0); + } + + char *filename; + uint32 size; + uint8 *data; + + FileList *next; + }; + + typedef const FileList cFileList; + + cFileList *getFileList() const { return _fileList; } +private: + FileList *_fileList; + bool _isAmiga; +}; + +#endif diff --git a/tools/create_kyradat/util.c b/tools/create_kyradat/util.c new file mode 100644 index 0000000000..a2680e6a26 --- /dev/null +++ b/tools/create_kyradat/util.c @@ -0,0 +1,137 @@ +/* Scumm Tools + * Copyright (C) 2003-2006 The ScummVM Team + * + * 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/tools/trunk/util.c $ + * $Id: util.c 23136 2006-06-15 14:34:46Z h00ligan $ + * + */ + +#include "util.h" +#include + +#ifdef _MSC_VER + #define vsnprintf _vsnprintf +#endif + +void error(const char *s, ...) { + char buf[1024]; + va_list va; + + va_start(va, s); + vsnprintf(buf, 1024, s, va); + va_end(va); + + fprintf(stderr, "ERROR: %s!\n", buf); + + exit(1); +} + +void warning(const char *s, ...) { + char buf[1024]; + va_list va; + + va_start(va, s); + vsnprintf(buf, 1024, s, va); + va_end(va); + + fprintf(stderr, "WARNING: %s!\n", buf); +} + +void debug(int level, const char *s, ...) { + char buf[1024]; + va_list va; + + va_start(va, s); + vsnprintf(buf, 1024, s, va); + va_end(va); + + fprintf(stderr, "DEBUG: %s!\n", buf); +} + +uint8 readByte(FILE *fp) { + return fgetc(fp); +} + +uint16 readUint16BE(FILE *fp) { + uint16 ret = 0; + ret |= fgetc(fp) << 8; + ret |= fgetc(fp); + return ret; +} + +uint16 readUint16LE(FILE *fp) { + uint16 ret = 0; + ret |= fgetc(fp); + ret |= fgetc(fp) << 8; + return ret; +} + +uint32 readUint32BE(FILE *fp) { + uint32 ret = 0; + ret |= fgetc(fp) << 24; + ret |= fgetc(fp) << 16; + ret |= fgetc(fp) << 8; + ret |= fgetc(fp); + return ret; +} + +uint32 readUint32LE(FILE *fp) { + uint32 ret = 0; + ret |= fgetc(fp); + ret |= fgetc(fp) << 8; + ret |= fgetc(fp) << 16; + ret |= fgetc(fp) << 24; + return ret; +} + +void writeByte(FILE *fp, uint8 b) { + fwrite(&b, 1, 1, fp); +} + +void writeUint16BE(FILE *fp, uint16 value) { + writeByte(fp, (uint8)(value >> 8)); + writeByte(fp, (uint8)(value)); +} + +void writeUint16LE(FILE *fp, uint16 value) { + writeByte(fp, (uint8)(value)); + writeByte(fp, (uint8)(value >> 8)); +} + +void writeUint32BE(FILE *fp, uint32 value) { + writeByte(fp, (uint8)(value >> 24)); + writeByte(fp, (uint8)(value >> 16)); + writeByte(fp, (uint8)(value >> 8)); + writeByte(fp, (uint8)(value)); +} + +void writeUint32LE(FILE *fp, uint32 value) { + writeByte(fp, (uint8)(value)); + writeByte(fp, (uint8)(value >> 8)); + writeByte(fp, (uint8)(value >> 16)); + writeByte(fp, (uint8)(value >> 24)); +} + +uint32 fileSize(FILE *fp) { + uint32 sz; + uint32 pos = ftell(fp); + fseek(fp, 0, SEEK_END); + sz = ftell(fp); + fseek(fp, pos, SEEK_SET); + return sz; +} + diff --git a/tools/create_kyradat/util.h b/tools/create_kyradat/util.h new file mode 100644 index 0000000000..9826e22f70 --- /dev/null +++ b/tools/create_kyradat/util.h @@ -0,0 +1,265 @@ +/* Scumm Tools + * Copyright (C) 2002-2006 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/tools/trunk/util.h $ + * $Id: util.h 23139 2006-06-15 16:58:09Z eriktorbjorn $ + * + */ + +#ifndef UTIL_H +#define UTIL_H + +#include +#include +#include +#include +#include +#include + +#if !defined(_MSC_VER) +#include +#endif + +#ifdef WIN32 +#include +#include +#endif + + +/* + * Some useful types + */ + +typedef unsigned char byte; +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint32; +typedef signed char int8; +typedef signed short int16; +typedef signed int int32; + +#if !defined(__cplusplus) +typedef uint8 bool; +#define false 0 +#define true 1 + +/* If your C compiler doesn't support 'inline', please add a check for it. */ +#if defined(_MSC_VER) +#define inline __inline +#endif + +#endif + + +/* + * Various utility macros + */ + +#if defined(_MSC_VER) + + #define scumm_stricmp stricmp + #define scumm_strnicmp _strnicmp + #define snprintf _snprintf + + #define SCUMM_LITTLE_ENDIAN + + #define START_PACK_STRUCTS pack(push, 1) + #define END_PACK_STRUCTS pack(pop) + + +#elif defined(__MINGW32__) + + #define scumm_stricmp stricmp + #define scumm_strnicmp strnicmp + + #define SCUMM_LITTLE_ENDIAN + + #define START_PACK_STRUCTS pack(push, 1) + #define END_PACK_STRUCTS pack(pop) + + + #ifndef _HEAPOK + #define _HEAPOK (-2) + #endif + +#elif defined(UNIX) + + #define scumm_stricmp strcasecmp + #define scumm_strnicmp strncasecmp + + #if defined(__DECCXX) /* Assume alpha architecture */ + #define INVERSE_MKID + #define SCUMM_NEED_ALIGNMENT + #endif + + #if !defined(__GNUC__) + #define START_PACK_STRUCTS pack (1) + #define END_PACK_STRUCTS pack () + #endif + +#else + + #error No system type defined + +#endif + + +/* + * GCC specific stuff + */ +#if defined(__GNUC__) + #define GCC_PACK __attribute__((packed)) + #define NORETURN __attribute__((__noreturn__)) + #define GCC_PRINTF(x,y) __attribute__((format(printf, x, y))) +#else + #define GCC_PACK + #define GCC_PRINTF(x,y) +#endif + +#define READ_UINT16(a) READ_LE_UINT16(a) +#define READ_UINT32(a) READ_LE_UINT32(a) + +#define WRITE_UINT16(a, v) WRITE_LE_UINT16(a, v) +#define WRITE_UINT32(a, v) WRITE_LE_UINT32(a, v) + +#define FROM_LE_32(a) ((uint32)(a)) +#define FROM_LE_16(a) ((uint16)(a)) + +#define TO_LE_32(a) ((uint32)(a)) +#define TO_LE_16(a) ((uint16)(a)) + +#define TO_BE_32(a) SWAP_BYTES_32(a) +#define TO_BE_16(a) SWAP_BYTES_16(a) + +#define ARRAYSIZE(x) ((int)(sizeof(x) / sizeof(x[0]))) + +static inline uint32 SWAP_32(uint32 a) { + return ((a >> 24) & 0xFF) | ((a >> 8) & 0xFF00) | ((a << 8) & 0xFF0000) | + ((a << 24) & 0xFF000000); +} + +static inline uint16 SWAP_16(uint16 a) { + return ((a >> 8) & 0xFF) | ((a << 8) & 0xFF00); +} + +#define FORCEINLINE static inline + +FORCEINLINE uint16 READ_LE_UINT16(const void *ptr) { + const byte *b = (const byte *)ptr; + return (b[1] << 8) + b[0]; +} +FORCEINLINE uint32 READ_LE_UINT32(const void *ptr) { + const byte *b = (const byte *)ptr; + return (b[3] << 24) + (b[2] << 16) + (b[1] << 8) + (b[0]); +} +FORCEINLINE void WRITE_LE_UINT16(void *ptr, uint16 value) { + byte *b = (byte *)ptr; + b[0] = (byte)(value >> 0); + b[1] = (byte)(value >> 8); +} +FORCEINLINE void WRITE_LE_UINT32(void *ptr, uint32 value) { + byte *b = (byte *)ptr; + b[0] = (byte)(value >> 0); + b[1] = (byte)(value >> 8); + b[2] = (byte)(value >> 16); + b[3] = (byte)(value >> 24); +} + +FORCEINLINE uint16 READ_BE_UINT16(const void *ptr) { + const byte *b = (const byte *)ptr; + return (b[0] << 8) + b[1]; +} +FORCEINLINE uint32 READ_BE_UINT32(const void *ptr) { + const byte *b = (const byte*)ptr; + return (b[0] << 24) + (b[1] << 16) + (b[2] << 8) + (b[3]); +} +FORCEINLINE void WRITE_BE_UINT16(void *ptr, uint16 value) { + byte *b = (byte *)ptr; + b[0] = (byte)(value >> 8); + b[1] = (byte)(value >> 0); +} +FORCEINLINE void WRITE_BE_UINT32(void *ptr, uint32 value) { + byte *b = (byte *)ptr; + b[0] = (byte)(value >> 24); + b[1] = (byte)(value >> 16); + b[2] = (byte)(value >> 8); + b[3] = (byte)(value >> 0); +} + +#if defined(__GNUC__) +#define NORETURN_PRE +#define NORETURN_POST __attribute__((__noreturn__)) +#elif defined(_MSC_VER) +#define NORETURN_PRE _declspec(noreturn) +#define NORETURN_POST +#else +#define NORETURN_PRE +#define NORETURN_POST +#endif + + +#if defined(__cplusplus) +extern "C" { +#endif + +/* File I/O */ +uint8 readByte(FILE *fp); +uint16 readUint16BE(FILE *fp); +uint16 readUint16LE(FILE *fp); +uint32 readUint32BE(FILE *fp); +uint32 readUint32LE(FILE *fp); +void writeByte(FILE *fp, uint8 b); +void writeUint16BE(FILE *fp, uint16 value); +void writeUint16LE(FILE *fp, uint16 value); +void writeUint32BE(FILE *fp, uint32 value); +void writeUint32LE(FILE *fp, uint32 value); +uint32 fileSize(FILE *fp); + +/* Misc stuff */ +void NORETURN_PRE error(const char *s, ...) NORETURN_POST; +void warning(const char *s, ...); +void debug(int level, const char *s, ...); + +enum { + EN_ANY, // Generic English (when only one game version exist) + EN_USA, + EN_GRB, + + DE_DEU, + FR_FRA, + IT_ITA, + PT_BRA, + ES_ESP, + JA_JPN, + ZH_TWN, + KO_KOR, + SE_SWE, + HB_ISR, + RU_RUS, + CZ_CZE, + NL_NLD, + NB_NOR, + PL_POL, + + UNK_LANG = -1 // Use default language (i.e. none specified) +}; + +#if defined(__cplusplus) +} +#endif + +#endif -- cgit v1.2.3