diff options
-rw-r--r-- | devtools/create_neverhood/create_neverhood.cpp | 257 | ||||
-rw-r--r-- | devtools/create_neverhood/create_neverhood.h | 28 | ||||
-rw-r--r-- | devtools/create_neverhood/module.mk | 12 | ||||
-rw-r--r-- | devtools/create_neverhood/tables.h | 49 | ||||
-rw-r--r-- | devtools/create_neverhood/util.cpp | 152 | ||||
-rw-r--r-- | devtools/create_neverhood/util.h | 57 | ||||
-rw-r--r-- | dists/engine-data/neverhood.dat | bin | 0 -> 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 Binary files differnew file mode 100644 index 0000000000..bbd7419ec8 --- /dev/null +++ b/dists/engine-data/neverhood.dat |