aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--devtools/create_neverhood/create_neverhood.cpp257
-rw-r--r--devtools/create_neverhood/create_neverhood.h28
-rw-r--r--devtools/create_neverhood/module.mk12
-rw-r--r--devtools/create_neverhood/tables.h49
-rw-r--r--devtools/create_neverhood/util.cpp152
-rw-r--r--devtools/create_neverhood/util.h57
-rw-r--r--dists/engine-data/neverhood.datbin0 -> 494 bytes
7 files changed, 555 insertions, 0 deletions
diff --git a/devtools/create_neverhood/create_neverhood.cpp b/devtools/create_neverhood/create_neverhood.cpp
new file mode 100644
index 0000000000..951a2f0ef1
--- /dev/null
+++ b/devtools/create_neverhood/create_neverhood.cpp
@@ -0,0 +1,257 @@
+/* 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.
+ *
+ */
+
+// Disable symbol overrides so that we can use system headers.
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+
+// HACK to allow building with the SDL backend on MinGW
+// see bug #1800764 "TOOLS: MinGW tools building broken"
+#ifdef main
+#undef main
+#endif // main
+
+#include <vector>
+#include "create_neverhood.h"
+#include "tables.h"
+
+const int DAT_VERSION = 0;
+
+uint32 dataSize;
+byte *data;
+uint32 dataStart = 0x004AE000;
+uint32 fileStart = 0x000AC600;
+
+void loadExe(const char *filename) {
+ FILE *exe = fopen(filename, "rb");
+ dataSize = fileSize(exe);
+ data = new byte[dataSize];
+ fread(data, dataSize, 1, exe);
+ fclose(exe);
+}
+
+struct HitRect {
+ int16 x1, y1, x2, y2;
+ uint16 messageNum;
+};
+
+typedef std::vector<HitRect> HitRects;
+
+struct SubRectItem {
+ int16 x1, y1, x2, y2;
+ uint32 messageListCount;
+ uint32 messageListOffset;
+};
+
+typedef std::vector<SubRectItem> SubRectItems;
+
+struct RectItem {
+ int16 x1, y1, x2, y2;
+ uint32 subRectListCount;
+ uint32 subRectListOffset;
+ SubRectItems subRectItems;
+};
+
+typedef std::vector<RectItem> RectItems;
+
+struct MessageItem {
+ uint16 messageNum;
+ uint32 messageParam;
+};
+
+typedef std::vector<MessageItem> MessageItems;
+
+struct HitRectList {
+ uint32 id;
+ HitRects hitRects;
+};
+
+struct RectList {
+ uint32 id;
+ RectItems rectItems;
+};
+
+struct MessageList {
+ uint32 id;
+ MessageItems messageItems;
+};
+
+std::vector<HitRectList*> hitRectLists;
+std::vector<RectList*> rectLists;
+std::vector<MessageList*> messageLists;
+
+byte *getData(uint32 offset) {
+ return data + offset - dataStart + fileStart;
+}
+
+void addHitRect(uint32 offset) {
+ HitRectList *hitRectList = new HitRectList();
+ hitRectList->id = offset;
+ byte *item = getData(offset);
+ uint32 count = READ_LE_UINT32(item);
+ //printf("count = %d\n", count);
+ // Align to 16 bytes
+ item = data + ((offset + 4 + 16) & 0xFFFFFFF0) - dataStart + fileStart;
+ for (uint32 i = 0; i < count; i++) {
+ HitRect hitRect;
+ hitRect.x1 = READ_LE_UINT16(item + 0);
+ hitRect.y1 = READ_LE_UINT16(item + 2);
+ hitRect.x2 = READ_LE_UINT16(item + 4);
+ hitRect.y2 = READ_LE_UINT16(item + 6);
+ hitRect.messageNum = READ_LE_UINT16(item + 8);
+ item += 10;
+ //printf("(%d, %d, %d, %d) -> %04X\n", hitRect.x1, hitRect.y1, hitRect.x2, hitRect.y2, hitRect.messageNum);
+ hitRectList->hitRects.push_back(hitRect);
+ }
+ hitRectLists.push_back(hitRectList);
+}
+
+void addMessage(uint32 count, uint32 offset) {
+ MessageList *messageList = new MessageList();
+ messageList->id = offset;
+ byte *item = getData(offset);
+ for (uint32 i = 0; i < count; i++) {
+ MessageItem messageItem;
+ messageItem.messageNum = READ_LE_UINT16(item + 0);
+ messageItem.messageParam = READ_LE_UINT32(item + 4);
+ //printf("%04X, %08X\n", messageItem.messageNum, messageItem.messageParam);
+ item += 8;
+ messageList->messageItems.push_back(messageItem);
+ }
+ messageLists.push_back(messageList);
+}
+
+void addRect(uint32 count, uint32 offset) {
+ RectList *rectList = new RectList();
+ rectList->id = offset;
+ byte *item = getData(offset);
+ for (uint32 i = 0; i < count; i++) {
+ RectItem rectItem;
+ byte *subItem;
+ rectItem.x1 = READ_LE_UINT16(item + 0);
+ rectItem.y1 = READ_LE_UINT16(item + 2);
+ rectItem.x2 = READ_LE_UINT16(item + 4);
+ rectItem.y2 = READ_LE_UINT16(item + 6);
+ rectItem.subRectListCount = READ_LE_UINT32(item + 8);
+ rectItem.subRectListOffset = READ_LE_UINT32(item + 12);
+ //printf("(%d, %d, %d, %d), %d, %08X\n", rectItem.x1, rectItem.y1, rectItem.x2, rectItem.y2, rectItem.subRectListCount, rectItem.subRectListOffset);
+ subItem = getData(rectItem.subRectListOffset);
+ for (uint32 j = 0; j < rectItem.subRectListCount; j++) {
+ SubRectItem subRectItem;
+ subRectItem.x1 = READ_LE_UINT16(subItem + 0);
+ subRectItem.y1 = READ_LE_UINT16(subItem + 2);
+ subRectItem.x2 = READ_LE_UINT16(subItem + 4);
+ subRectItem.y2 = READ_LE_UINT16(subItem + 6);
+ subRectItem.messageListCount = READ_LE_UINT32(subItem + 8);
+ subRectItem.messageListOffset = READ_LE_UINT32(subItem + 12);
+ subItem += 16;
+ //printf("(%d, %d, %d, %d), %d, %08X\n", subRectItem.x1, subRectItem.y1, subRectItem.x2, subRectItem.y2, subRectItem.messageListCount, subRectItem.messageListOffset);
+ addMessage(subRectItem.messageListCount, subRectItem.messageListOffset);
+ rectItem.subRectItems.push_back(subRectItem);
+ }
+ item += 16;
+ rectList->rectItems.push_back(rectItem);
+ }
+ rectLists.push_back(rectList);
+}
+
+int main(int argc, char *argv[]) {
+
+ FILE *datFile;
+
+ loadExe("nhc.exe");
+
+ for (int i = 0; hitRectListOffsets[i] != 0; i++) {
+ addHitRect(hitRectListOffsets[i]);
+ }
+
+ for (int i = 0; rectListOffsets[i] != 0; i += 2) {
+ addRect(rectListOffsets[i], rectListOffsets[i + 1]);
+ }
+
+ for (int i = 0; messageListOffsets[i] != 0; i += 2) {
+ addMessage(messageListOffsets[i], messageListOffsets[i + 1]);
+ }
+
+ datFile = fopen("neverhood.dat", "wb");
+
+ writeUint32LE(datFile, 0x11223344); // Some magic
+ writeUint32LE(datFile, DAT_VERSION);
+
+ // Write all message lists
+ writeUint32LE(datFile, messageLists.size());
+ for (std::vector<MessageList*>::iterator it = messageLists.begin(); it != messageLists.end(); it++) {
+ MessageList *messageList = *it;
+ writeUint32LE(datFile, messageList->id);
+ writeUint32LE(datFile, messageList->messageItems.size());
+ for (uint32 i = 0; i < messageList->messageItems.size(); i++) {
+ writeUint16LE(datFile, messageList->messageItems[i].messageNum);
+ writeUint32LE(datFile, messageList->messageItems[i].messageParam);
+ }
+ }
+
+ // Write all rect lists
+ writeUint32LE(datFile, rectLists.size());
+ for (std::vector<RectList*>::iterator it = rectLists.begin(); it != rectLists.end(); it++) {
+ RectList *rectList = *it;
+ writeUint32LE(datFile, rectList->id);
+ writeUint32LE(datFile, rectList->rectItems.size());
+ for (uint32 i = 0; i < rectList->rectItems.size(); i++) {
+ const RectItem &rectItem = rectList->rectItems[i];
+ writeUint16LE(datFile, rectItem.x1);
+ writeUint16LE(datFile, rectItem.y1);
+ writeUint16LE(datFile, rectItem.x2);
+ writeUint16LE(datFile, rectItem.y2);
+ writeUint32LE(datFile, rectItem.subRectItems.size());
+ for (uint32 j = 0; j < rectItem.subRectItems.size(); j++) {
+ const SubRectItem &subRectItem = rectItem.subRectItems[j];
+ writeUint16LE(datFile, subRectItem.x1);
+ writeUint16LE(datFile, subRectItem.y1);
+ writeUint16LE(datFile, subRectItem.x2);
+ writeUint16LE(datFile, subRectItem.y2);
+ writeUint32LE(datFile, subRectItem.messageListOffset);
+ }
+ }
+ }
+
+ // Write all hit rect lists
+ writeUint32LE(datFile, hitRectLists.size());
+ for (std::vector<HitRectList*>::iterator it = hitRectLists.begin(); it != hitRectLists.end(); it++) {
+ HitRectList *hitRectList = *it;
+ writeUint32LE(datFile, hitRectList->id);
+ writeUint32LE(datFile, hitRectList->hitRects.size());
+ for (uint32 i = 0; i < hitRectList->hitRects.size(); i++) {
+ const HitRect &hitRect = hitRectList->hitRects[i];
+ writeUint16LE(datFile, hitRect.x1);
+ writeUint16LE(datFile, hitRect.y1);
+ writeUint16LE(datFile, hitRect.x2);
+ writeUint16LE(datFile, hitRect.y2);
+ writeUint16LE(datFile, hitRect.messageNum);
+ }
+ }
+
+ fclose(datFile);
+
+ printf("Done.\n");
+
+ return 0;
+}
diff --git a/devtools/create_neverhood/create_neverhood.h b/devtools/create_neverhood/create_neverhood.h
new file mode 100644
index 0000000000..6382c87375
--- /dev/null
+++ b/devtools/create_neverhood/create_neverhood.h
@@ -0,0 +1,28 @@
+/* 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.
+ *
+ */
+
+#ifndef CREATE_NEVERHOOD_H
+#define CREATE_NEVERHOOD_H
+
+#include "util.h"
+
+#endif
diff --git a/devtools/create_neverhood/module.mk b/devtools/create_neverhood/module.mk
new file mode 100644
index 0000000000..284e19105d
--- /dev/null
+++ b/devtools/create_neverhood/module.mk
@@ -0,0 +1,12 @@
+
+MODULE := devtools/create_neverhood
+
+MODULE_OBJS := \
+ create_neverhood.o \
+ util.o
+
+# Set the name of the executable
+TOOL_EXECUTABLE := create_neverhood
+
+# Include common rules
+include $(srcdir)/rules.mk
diff --git a/devtools/create_neverhood/tables.h b/devtools/create_neverhood/tables.h
new file mode 100644
index 0000000000..6f1fc48250
--- /dev/null
+++ b/devtools/create_neverhood/tables.h
@@ -0,0 +1,49 @@
+/* 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.
+ *
+ */
+
+static const uint32 hitRectListOffsets[] = {
+ // Scene1001
+ 0x004B4858,
+ 0
+};
+
+static const uint32 rectListOffsets[] = {
+ // Scene1001
+ 1, 0x004B49F0,
+ 1, 0x004B4A00,
+ 0, 0
+};
+
+static const uint32 messageListOffsets[] = {
+ // Scene1001
+ 1, 0x004B4888,
+ 2, 0x004B4898,
+ 1, 0x004B4970,
+ 1, 0x004B4890,
+ 3, 0x004B4910,
+ 5, 0x004B4938,
+ 1, 0x004B4960,
+ 4, 0x004B48A8,
+ 3, 0x004B48C8,
+ 0, 0
+};
+
diff --git a/devtools/create_neverhood/util.cpp b/devtools/create_neverhood/util.cpp
new file mode 100644
index 0000000000..5ce8237b85
--- /dev/null
+++ b/devtools/create_neverhood/util.cpp
@@ -0,0 +1,152 @@
+/* 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.
+ *
+ */
+
+// Disable symbol overrides so that we can use system headers.
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+#include "util.h"
+#include <stdarg.h>
+
+#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);
+}
+
+int scumm_stricmp(const char *s1, const char *s2) {
+ byte l1, l2;
+ do {
+ // Don't use ++ inside tolower, in case the macro uses its
+ // arguments more than once.
+ l1 = (byte)*s1++;
+ l1 = tolower(l1);
+ l2 = (byte)*s2++;
+ l2 = tolower(l2);
+ } while (l1 == l2 && l1 != 0);
+ return l1 - l2;
+}
+
+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/devtools/create_neverhood/util.h b/devtools/create_neverhood/util.h
new file mode 100644
index 0000000000..a2783cca71
--- /dev/null
+++ b/devtools/create_neverhood/util.h
@@ -0,0 +1,57 @@
+/* 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.
+ *
+ */
+
+#ifndef UTIL_H
+#define UTIL_H
+
+#include "common/scummsys.h"
+#include "common/endian.h"
+#include "common/util.h"
+
+#ifdef WIN32
+#include <io.h>
+#include <process.h>
+#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, ...);
+int scumm_stricmp(const char *s1, const char *s2);
+
+using namespace Common;
+
+#endif
diff --git a/dists/engine-data/neverhood.dat b/dists/engine-data/neverhood.dat
new file mode 100644
index 0000000000..bbd7419ec8
--- /dev/null
+++ b/dists/engine-data/neverhood.dat
Binary files differ