aboutsummaryrefslogtreecommitdiff
path: root/devtools
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
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')
-rw-r--r--devtools/create_supernova/create_supernova.cpp193
-rw-r--r--devtools/create_supernova/create_supernova.h33
-rw-r--r--devtools/create_supernova/file.cpp72
-rw-r--r--devtools/create_supernova/file.h59
-rw-r--r--devtools/create_supernova/gametext.h271
-rw-r--r--devtools/create_supernova/module.mk11
6 files changed, 639 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;
+}
diff --git a/devtools/create_supernova/create_supernova.h b/devtools/create_supernova/create_supernova.h
new file mode 100644
index 0000000000..7447a7ece6
--- /dev/null
+++ b/devtools/create_supernova/create_supernova.h
@@ -0,0 +1,33 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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.
+ *
+ * This is a utility for generating a data file for the supernova engine.
+ * It contains strings extracted from the original executable as well
+ * as translations and is required for the engine to work properly.
+ */
+
+#ifndef CREATE_SUPERNOVA_H
+#define CREATE_SUPERNOVA_H
+
+#define VERSION 1
+
+
+
+#endif // CREATE_SUPERNOVA_H
diff --git a/devtools/create_supernova/file.cpp b/devtools/create_supernova/file.cpp
new file mode 100644
index 0000000000..5fb842aff6
--- /dev/null
+++ b/devtools/create_supernova/file.cpp
@@ -0,0 +1,72 @@
+#include "file.h"
+
+bool File::open(const char *filename, AccessMode mode) {
+ f = fopen(filename, (mode == kFileReadMode) ? "rb" : "wb");
+ return (f != NULL);
+}
+
+void File::close() {
+ fclose(f);
+ f = NULL;
+}
+
+int File::seek(int32 offset, int whence) {
+ return fseek(f, offset, whence);
+}
+
+long File::read(void *buffer, int len) {
+ return fread(buffer, 1, len, f);
+}
+void File::write(const void *buffer, int len) {
+ fwrite(buffer, 1, len, f);
+}
+
+byte File::readByte() {
+ byte v;
+ read(&v, sizeof(byte));
+ return v;
+}
+
+uint16 File::readWord() {
+ uint16 v;
+ read(&v, sizeof(uint16));
+ return FROM_LE_16(v);
+}
+
+uint32 File::readLong() {
+ uint32 v;
+ read(&v, sizeof(uint32));
+ return FROM_LE_32(v);
+}
+
+void File::readString(char* string, int bufferLength) {
+ int i = 0;
+ while (i < bufferLength - 1 && fread(string + i, 1, 1, f) == 1) {
+ if (string[i] == '\n' || string[i] == 0)
+ break;
+ ++ i;
+ }
+ string[i] = 0;
+}
+
+void File::writeByte(byte v) {
+ write(&v, sizeof(byte));
+}
+
+void File::writeWord(uint16 v) {
+ uint16 vTemp = TO_LE_16(v);
+ write(&vTemp, sizeof(uint16));
+}
+
+void File::writeLong(uint32 v) {
+ uint32 vTemp = TO_LE_32(v);
+ write(&vTemp, sizeof(uint32));
+}
+
+void File::writeString(const char *s) {
+ write(s, strlen(s) + 1);
+}
+
+uint32 File::pos() {
+ return ftell(f);
+}
diff --git a/devtools/create_supernova/file.h b/devtools/create_supernova/file.h
new file mode 100644
index 0000000000..dd33e410f9
--- /dev/null
+++ b/devtools/create_supernova/file.h
@@ -0,0 +1,59 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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.
+ *
+ * This is a utility for generating a data file for the supernova engine.
+ * It contains strings extracted from the original executable as well
+ * as translations and is required for the engine to work properly.
+ */
+
+#ifndef FILE_H
+#define FILE_H
+
+// Disable symbol overrides so that we can use system headers.
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+#include "common/endian.h"
+
+enum AccessMode {
+ kFileReadMode = 1,
+ kFileWriteMode = 2
+};
+
+class File {
+private:
+ FILE *f;
+public:
+ bool open(const char *filename, AccessMode mode = kFileReadMode);
+ void close();
+ int seek(int32 offset, int whence = SEEK_SET);
+ uint32 pos();
+ long read(void *buffer, int len);
+ void write(const void *buffer, int len);
+
+ byte readByte();
+ uint16 readWord();
+ uint32 readLong();
+ void readString(char*, int bufferLength);
+ void writeByte(byte v);
+ void writeWord(uint16 v);
+ void writeLong(uint32 v);
+ void writeString(const char *s);
+};
+
+#endif // FILE_H
diff --git a/devtools/create_supernova/gametext.h b/devtools/create_supernova/gametext.h
new file mode 100644
index 0000000000..a05526088e
--- /dev/null
+++ b/devtools/create_supernova/gametext.h
@@ -0,0 +1,271 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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.
+ *
+ * This is a utility for generating a data file for the supernova engine.
+ * It contains strings extracted from the original executable as well
+ * as translations and is required for the engine to work properly.
+ */
+
+#ifndef GAMETEXT_H
+#define GAMETEXT_H
+
+#include <stddef.h>
+
+// This file contains the strings in German and is encoded using CP850 encoding.
+// Other language should be provided as po files also using the CP850 encoding.
+
+// TODO: add the strings from the engine here, add an Id string in comment.
+// And in the engine add a StringId enum with all the Ids = index in this array.
+
+const char *gameText[] = {
+ // 0
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 5
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 10
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 15
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 20
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 25
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 30
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 35
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 40
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 45
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 50
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 55
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 60
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 65
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 70
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 75
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 80
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 85
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 90
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 95
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 100
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 105
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 110
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 115
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 120
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 125
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 130
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 135
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 140
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 145
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 150
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 155
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 160
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 165
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 170
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 175
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 180
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ // 185
+ "", //
+ "", //
+ "", //
+ "", //
+ "", //
+ NULL
+};
+
+
+
+#endif // GAMETEXT_H
diff --git a/devtools/create_supernova/module.mk b/devtools/create_supernova/module.mk
new file mode 100644
index 0000000000..9591233168
--- /dev/null
+++ b/devtools/create_supernova/module.mk
@@ -0,0 +1,11 @@
+MODULE := devtools/create_supernova
+
+MODULE_OBJS := \
+ file.o \
+ create_supernova.o
+
+# Set the name of the executable
+TOOL_EXECUTABLE := create_supernova
+
+# Include common rules
+include $(srcdir)/rules.mk