aboutsummaryrefslogtreecommitdiff
path: root/tools/create_kyradat/create_kyradat.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/create_kyradat/create_kyradat.cpp')
-rw-r--r--tools/create_kyradat/create_kyradat.cpp164
1 files changed, 119 insertions, 45 deletions
diff --git a/tools/create_kyradat/create_kyradat.cpp b/tools/create_kyradat/create_kyradat.cpp
index dad9e3289d..f97d0adf62 100644
--- a/tools/create_kyradat/create_kyradat.cpp
+++ b/tools/create_kyradat/create_kyradat.cpp
@@ -36,6 +36,9 @@
#include "md5.h"
+#include <string>
+#include <map>
+
enum {
kKyraDatVersion = 63,
kIndexSize = 12
@@ -327,12 +330,6 @@ const SpecialExtension specialTable[] = {
{ kDemoVersion, "DEM" },
{ kTalkieDemoVersion, "CD.DEM" },
- { kTalkieFile1, "CD" },
- { kTalkieFile2, "CD" },
-
- { kTalkieDemoFile1, "CD.DEM" },
- { kTalkieDemoFile2, "CD.DEM" },
-
{ -1, 0 }
};
@@ -375,11 +372,11 @@ enum {
uint32 getFeatures(const Game *g) {
uint32 features = 0;
- if (g->special == kTalkieVersion || g->special == kTalkieFile1 || g->special == kTalkieFile2 || g->game == kKyra3)
+ if (g->special == kTalkieVersion || g->game == kKyra3)
features |= GF_TALKIE;
else if (g->special == kDemoVersion)
features |= GF_DEMO;
- else if (g->special == kTalkieDemoVersion || g->special == kTalkieDemoFile1 || g->special == kTalkieDemoFile2)
+ else if (g->special == kTalkieDemoVersion)
features |= (GF_DEMO | GF_TALKIE);
else if (g->platform == kPlatformFMTowns || g->platform == kPlatformPC98) // HACK
features |= GF_FMTOWNS;
@@ -488,6 +485,19 @@ void printHelp(const char *f) {
bool process(PAKFile &out, const Game *g, const byte *data, const uint32 size);
const Game *findGame(const byte *buffer, const uint32 size);
+typedef std::map<std::string, std::string> MD5Map;
+MD5Map createMD5Sums(int files, const char * const *filenames);
+
+struct File {
+ File() : data(0), size(0) {}
+ File(uint8 *d, uint32 s) : data(d), size(s) {}
+
+ uint8 *data;
+ uint32 size;
+};
+typedef std::map<const Game *, File> GameMap;
+GameMap createGameMap(const MD5Map &map);
+
int main(int argc, char *argv[]) {
if (argc < 3) {
printHelp(argv[0]);
@@ -538,13 +548,66 @@ int main(int argc, char *argv[]) {
PAKFile out;
out.loadFile(argv[1], false);
- for (int i = 2; i < argc; ++i) {
- FILE *input = fopen(argv[i], "rb");
+ MD5Map inputFiles = createMD5Sums(argc - 2, &argv[2]);
- if (!input) {
- warning("skipping missing file '%s'", argv[i]);
- continue;
- }
+ GameMap games = createGameMap(inputFiles);
+
+ // Check for unused input files
+ MD5Map unusedFiles = inputFiles;
+ for (GameMap::const_iterator i = games.begin(); i != games.end(); ++i) {
+ unusedFiles.erase(i->first->md5[0]);
+ if (i->first->md5[1])
+ unusedFiles.erase(i->first->md5[1]);
+ }
+
+ for (MD5Map::const_iterator i = unusedFiles.begin(); i != unusedFiles.end(); ++i)
+ printf("Input file '%s' with md5 sum '%s' is not known.\n", i->second.c_str(), i->first.c_str());
+
+ unusedFiles.clear();
+
+ // Process all games found
+ for (GameMap::const_iterator i = games.begin(); i != games.end(); ++i) {
+ MD5Map::const_iterator f1 = inputFiles.find(i->first->md5[0]);
+ MD5Map::const_iterator f2 = inputFiles.end();
+ if (i->first->md5[1])
+ f2 = inputFiles.find(i->first->md5[1]);
+
+ if (f2 != inputFiles.end())
+ printf("Processing files '%s' and '%s'...\n", f1->second.c_str(), f2->second.c_str());
+ else
+ printf("Processing file '%s'...\n", f1->second.c_str());
+
+ process(out, i->first, i->second.data, i->second.size);
+ }
+
+ // Free up memory
+ for (GameMap::iterator i = games.begin(); i != games.end(); ++i)
+ delete[] i->second.data;
+ games.clear();
+ inputFiles.clear();
+
+ 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;
+}
+
+MD5Map createMD5Sums(int files, const char * const *filenames) {
+ MD5Map result;
+
+ while (files--) {
+ const char *inputFile = *filenames++;
+ FILE *input = fopen(inputFile, "rb");
uint32 size = fileSize(input);
fseek(input, 0, SEEK_SET);
@@ -553,7 +616,7 @@ int main(int argc, char *argv[]) {
assert(buffer);
if (fread(buffer, 1, size, input) != size) {
- warning("couldn't read from file '%s', skipping it", argv[i]);
+ warning("couldn't read from file '%s', skipping it", inputFile);
delete[] buffer;
fclose(input);
continue;
@@ -571,46 +634,57 @@ int main(int argc, char *argv[]) {
for (int j = 0; j < 16; ++j)
sprintf(md5Str + j*2, "%02x", (int)digest[j]);
- printf("Processing file '%s'...\n", argv[i]);
+ delete[] buffer;
- bool variantProcessed = false;
+ result[md5Str] = inputFile;
+ }
- for (const Game **game = gameDescs; *game != 0; ++game) {
- for (const Game *variant = *game; variant->md5 != 0; ++variant) {
- if (!std::strcmp(variant->md5, md5Str)) {
- variantProcessed = true;
+ return result;
+}
- if (!process(out, variant, buffer, size))
- fprintf(stderr, "ERROR: couldn't process file\n");
+GameMap createGameMap(const MD5Map &map) {
+ GameMap result;
- // We do not break the loop here, so all registered game
- // variants will be processed. Like it is for example
- // required for multi language executables.
- }
+ for (const Game * const *g = gameDescs; *g != 0; ++g) {
+ for (const Game *sub = *g; sub->game != -1; ++sub) {
+ MD5Map::const_iterator file1 = map.find(sub->md5[0]);
+ if (file1 == map.end())
+ continue;
+
+ MD5Map::const_iterator file2 = map.end();
+ if (sub->md5[1] != 0) {
+ file2 = map.find(sub->md5[1]);
+ if (file2 == map.end())
+ continue;
}
- }
- if (!variantProcessed)
- fprintf(stderr, "ERROR: File '%s' with md5 sum \"%s\" has no variant registered\n", argv[i], md5Str);
+ FILE *f1 = fopen(file1->second.c_str(), "rb");
+ FILE *f2 = 0;
- // delete the current entry
- delete[] buffer;
- }
+ if (file2 != map.end())
+ f2 = fopen(file2->second.c_str(), "rb");
- if (!out.saveFile(argv[1]))
- error("couldn't save changes to '%s'", argv[1]);
+ uint32 file1Size = fileSize(f1);
+ uint32 file2Size = 0;
+ if (f2)
+ file2Size = fileSize(f2);
- 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);
+ uint8 *buffer = new uint8[file1Size + file2Size];
+ assert(buffer);
- return 0;
+ fread(buffer, 1, file1Size, f1);
+ if (f2)
+ fread(buffer + file1Size, 1, file2Size, f2);
+
+ fclose(f1);
+ if (f2)
+ fclose(f2);
+
+ result[sub] = File(buffer, file1Size + file2Size);
+ }
+ }
+
+ return result;
}
const char *getIdString(const int id) {