diff options
author | Jaromir Wysoglad | 2019-05-27 18:49:01 +0200 |
---|---|---|
committer | Thierry Crozat | 2019-07-28 15:09:14 +0100 |
commit | 0ed3dbf21f5dc2eb6bb90324d77937e68189a43a (patch) | |
tree | 1a251dd153bff0e28ee970e5cf52f829b7dc9b44 /devtools/create_supernova2/create_supernova2.cpp | |
parent | 9bf7dc817fb76e59b97c673f7f4cd555ffcdd42c (diff) | |
download | scummvm-rg350-0ed3dbf21f5dc2eb6bb90324d77937e68189a43a.tar.gz scummvm-rg350-0ed3dbf21f5dc2eb6bb90324d77937e68189a43a.tar.bz2 scummvm-rg350-0ed3dbf21f5dc2eb6bb90324d77937e68189a43a.zip |
SUPERNOVA2: add tool to generate engine data file
Most of the tool is copied from create supernova
Add correct gametext.h and strings_en.po for supernova2
Doesn't handle images yet
Diffstat (limited to 'devtools/create_supernova2/create_supernova2.cpp')
-rw-r--r-- | devtools/create_supernova2/create_supernova2.cpp | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/devtools/create_supernova2/create_supernova2.cpp b/devtools/create_supernova2/create_supernova2.cpp new file mode 100644 index 0000000000..ff19728c59 --- /dev/null +++ b/devtools/create_supernova2/create_supernova2.cpp @@ -0,0 +1,197 @@ +#include "create_supernova2.h" +#include "gametext.h" +#include "file.h" +#include "po_parser.h" + +// HACK to allow building with the SDL backend on MinGW +// see bug #1800764 "TOOLS: MinGW tools building broken" +#ifdef main +#undef main +#endif // main + +// List of languages to look for. To add new languages you only need to change the array below +// and add the supporting files: +// - 640x480 bitmap picture for the newpaper named 'img1-##.pbm' and 'img2-##.pbm' +// in pbm binary format (you can use gimp to generate those) +// - strings in a po file named 'strings-##.po' that uses CP850 encoding + +const char *lang[] = { + "en", + NULL +}; + +void writeImage(File& outputFile, const char *name, const char* language) { + File imgFile; + char fileName[16]; + sprintf(fileName, "%s-%s.pbm", name, language); + if (!imgFile.open(fileName, kFileReadMode)) { + printf("Cannot find image '%s' for language '%s'. This image will be skipped.\n", name, language); + return; + } + + char str[256]; + + // Read header (and check we have a binary PBM file) + imgFile.readString(str, 256); + if (strcmp(str, "P4") != 0) { + imgFile.close(); + printf("File '%s' doesn't seem to be a binary pbm file! This image will be skipped.\n", fileName); + return; + } + + // Skip comments and then read and check size + do { + imgFile.readString(str, 256); + } while (str[0] == '#'); + int w = 0, h = 0; + if (sscanf(str, "%d %d", &w, &h) != 2 || w != 640 || h != 480) { + imgFile.close(); + printf("Binary pbm file '%s' doesn't have the expected size (expected: 640x480, read: %dx%d). This image will be skipped.\n", fileName, w, h); + return; + } + + // Write block header in output file (4 bytes). + // We convert the image name to upper case. + for (int i = 0 ; i < 4 ; ++i) { + if (name[i] >= 97 && name[i] <= 122) + outputFile.writeByte(name[i] - 32); + else + outputFile.writeByte(name[i]); + } + // And write the language code on 4 bytes as well (padded with 0 if needed). + int languageLength = strlen(language); + for (int i = 0 ; i < 4 ; ++i) { + if (i < languageLength) + outputFile.writeByte(language[i]); + else + outputFile.writeByte(0); + } + + // Write block size (640*480 / 8) + outputFile.writeLong(38400); + + // Write all the bytes. We should have 38400 bytes (640 * 480 / 8) + // However we need to invert the bits has the engine expects 1 for the background and 0 for the text (black) + // but pbm uses 0 for white and 1 for black. + for (int i = 0 ; i < 38400 ; ++i) { + byte b = imgFile.readByte(); + outputFile.writeByte(~b); + } + + imgFile.close(); +} + +void writeGermanStrings(File& outputFile) { + // Write header and language + outputFile.write("TEXT", 4); + outputFile.write("de\0\0", 4); + + // Reserve the size for the block size, but we will write it at the end once we know what it is. + uint32 blockSizePos = outputFile.pos(); + uint32 blockSize = 0; + outputFile.writeLong(blockSize); + + // Write all the strings + const char **s = &gameText[0]; + while (*s) { + outputFile.writeString(*s); + blockSize += strlen(*s) + 1; + ++s; + } + + // Now write the block size and then go back to the end of the file. + outputFile.seek(blockSizePos, SEEK_SET); + outputFile.writeLong(blockSize); + outputFile.seek(0, SEEK_END); +} + +void writeStrings(File& outputFile, const char* language) { + char fileName[16]; + sprintf(fileName, "strings-%s.po", language); + PoMessageList* poList = parsePoFile(fileName); + if (!poList) { + printf("Cannot find strings file for language '%s'.\n", language); + return; + } + + // Write block header + outputFile.write("TEXT", 4); + + // And write the language code on 4 bytes as well (padded with 0 if needed). + int languageLength = strlen(language); + for (int i = 0 ; i < 4 ; ++i) { + if (i < languageLength) + outputFile.writeByte(language[i]); + else + outputFile.writeByte(0); + } + + // Reserve the size for the block size, but we will write it at the end once we know what it is. + uint32 blockSizePos = outputFile.pos(); + uint32 blockSize = 0; + outputFile.writeLong(blockSize); + + // Write all the strings. + // If a string is not translated we use the German one. + const char **s = &gameText[0]; + while (*s) { + const char* translation = poList->findTranslation(*s); + if (translation) { + outputFile.writeString(translation); + blockSize += strlen(translation) + 1; + } else { + outputFile.writeString(*s); + blockSize += strlen(*s) + 1; + } + ++s; + } + delete poList; + + // Now write the block size and then go back to the end of the file. + outputFile.seek(blockSizePos, SEEK_SET); + outputFile.writeLong(blockSize); + outputFile.seek(0, SEEK_END); +} + + +/** + * Main method + */ +int main(int argc, char *argv[]) { + File outputFile; + if (!outputFile.open("supernova2.dat", kFileWriteMode)) { + printf("Cannot create file 'supernova2.dat' in current directory.\n"); + exit(0); + } + + // The generated file is of the form: + // 3 bytes: 'MSN' + // 1 byte: version + // -- data blocks + // 4 bytes: header 'IMG1' and 'IMG2' for newspaper images (for file 1 and file 2 respectively), + // 'TEXT' for strings + // 4 bytes: language code ('en\0', 'de\0'- see common/language.cpp) + // 4 bytes: block size n (uint32) + // n bytes: data + // --- + + // Header + outputFile.write("MS2", 3); + outputFile.writeByte(VERSION); + + // German strings + writeGermanStrings(outputFile); + + // TODO make the needed images and reenable writing them to the .dat file + // Other languages + const char **l = &lang[0]; + while(*l) { + // writeImage(outputFile, "img1", *l); + // writeImage(outputFile, "img2", *l); + writeStrings(outputFile, *l); + ++l; + } + + outputFile.close(); + return 0; +} |