aboutsummaryrefslogtreecommitdiff
path: root/devtools/create_supernova/create_supernova.cpp
diff options
context:
space:
mode:
authorThierry Crozat2017-09-26 23:05:46 +0100
committerThierry Crozat2018-01-23 02:15:32 +0000
commitf9310e11d8c01c20e32251678a7046e8c2e7b131 (patch)
tree3a480520d961a08b7d6110f47f8667f444da5430 /devtools/create_supernova/create_supernova.cpp
parent65d30cf720db9d3395ca5d3fa002a228c0549a80 (diff)
downloadscummvm-rg350-f9310e11d8c01c20e32251678a7046e8c2e7b131.tar.gz
scummvm-rg350-f9310e11d8c01c20e32251678a7046e8c2e7b131.tar.bz2
scummvm-rg350-f9310e11d8c01c20e32251678a7046e8c2e7b131.zip
SUPERNOVA: Add tool skeleton to generate engine data file
The tool is only a skeleton at this point. Most of the logic is there but it is missing the data to write the German strings and it is missing the logic to write the translated strings. This means that currently the only data written are bitmap images.
Diffstat (limited to 'devtools/create_supernova/create_supernova.cpp')
-rw-r--r--devtools/create_supernova/create_supernova.cpp193
1 files changed, 193 insertions, 0 deletions
diff --git a/devtools/create_supernova/create_supernova.cpp b/devtools/create_supernova/create_supernova.cpp
new file mode 100644
index 0000000000..0d4ebe2fe7
--- /dev/null
+++ b/devtools/create_supernova/create_supernova.cpp
@@ -0,0 +1,193 @@
+#include "create_supernova.h"
+#include "gametext.h"
+#include "file.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) {
+ File poFile;
+ char fileName[16];
+ sprintf(fileName, "strings-%s.po", language);
+ if (!poFile.open(fileName, kFileReadMode)) {
+ 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);
+
+
+
+ // TODO: read all the strings
+ // build german - translated map
+ // Then iterate on gameText and for each (german) string look for the corresponding translated string
+ // and write it (or write "" if not found).
+ // Doing so also count the number of byte written.
+ // Then finally go back to block size pos and write the block size.
+ // And go back to end of file.
+
+
+
+ poFile.close();
+
+ // 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("supernova.dat", kFileWriteMode)) {
+ printf("Cannot create file 'supernova.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("MSN", 3);
+ outputFile.writeByte(VERSION);
+
+ // German strings
+ writeGermanStrings(outputFile);
+
+ // 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;
+}