diff options
Diffstat (limited to 'devtools/create_neverhood/create_neverhood.cpp')
-rw-r--r-- | devtools/create_neverhood/create_neverhood.cpp | 105 |
1 files changed, 67 insertions, 38 deletions
diff --git a/devtools/create_neverhood/create_neverhood.cpp b/devtools/create_neverhood/create_neverhood.cpp index 323066d8b1..a37ff99ca9 100644 --- a/devtools/create_neverhood/create_neverhood.cpp +++ b/devtools/create_neverhood/create_neverhood.cpp @@ -30,12 +30,18 @@ #undef main #endif // main -#include <vector> #include "create_neverhood.h" +#include <vector> +#include "md5.h" #include "tables.h" const int DAT_VERSION = 0; +// The MD5 hash of the nhc.exe used to extract the tables from +const uint8 kNhcExeMd5[16] = { + 0x37, 0xD6, 0x54, 0xA2, 0xA7, 0xBB, 0xB0, 0x1F, + 0x8C, 0x41, 0x9A, 0xB8, 0x49, 0xFF, 0x29, 0xD4}; + uint32 dataSize; byte *data; uint32 dataStart = 0x004AE000; @@ -48,12 +54,33 @@ class NavigationList; void addMessageList(uint32 messageListCount, uint32 messageListOffset); -void loadExe(const char *filename) { +bool loadExe(const char *filename) { FILE *exe = fopen(filename, "rb"); + if (!exe) { + printf("Could not open nhc.exe for reading! Quitting...\n"); + return false; + } dataSize = fileSize(exe); data = new byte[dataSize]; fread(data, dataSize, 1, exe); fclose(exe); + return true; +} + +bool validateMd5() { + uint8 digest[16]; + + md5_buffer(data, dataSize, digest); + + printf("MD5 of nhc.exe is %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", + digest[0], digest[1], digest[2], digest[3], digest[4], digest[5], digest[6], digest[7], + digest[8], digest[9], digest[10], digest[11], digest[12], digest[13], digest[14], digest[15]); + + if (memcmp(kNhcExeMd5, digest, 16)) { + printf("MD5 hash of nhc.exe doesn't match the expected value! Quitting...\n"); + return false; + } + return true; } byte *getData(uint32 offset) { @@ -85,7 +112,7 @@ uint32 calcHash(const char *value) { struct HitRect { int16 x1, y1, x2, y2; uint16 messageNum; - + void load(uint32 offset) { byte *item = getData(offset); x1 = READ_LE_UINT16(item + 0); @@ -93,7 +120,7 @@ struct HitRect { x2 = READ_LE_UINT16(item + 4); y2 = READ_LE_UINT16(item + 6); messageNum = READ_LE_UINT16(item + 8); - } + } void save(FILE *fd) { writeUint16LE(fd, x1); @@ -102,11 +129,11 @@ struct HitRect { writeUint16LE(fd, y2); writeUint16LE(fd, messageNum); } - + int getItemSize() const { return 10; } - + }; struct MessageItem { @@ -114,22 +141,22 @@ struct MessageItem { uint32 messageParam; MessageItem() {} MessageItem(uint16 msgNum, uint32 msgParam) : messageNum(msgNum), messageParam(msgParam) {} - + void load(uint32 offset) { byte *item = getData(offset); messageNum = READ_LE_UINT16(item + 0); messageParam = READ_LE_UINT32(item + 4); - } + } void save(FILE *fd) { writeUint16LE(fd, messageNum); writeUint32LE(fd, messageParam); } - + int getItemSize() const { return 8; } - + }; struct SubRectItem { @@ -148,7 +175,7 @@ struct SubRectItem { // Add the message to the message list addMessageList(messageListCount, messageListOffset); } - + void save(FILE *fd) { writeUint16LE(fd, x1); writeUint16LE(fd, y1); @@ -156,11 +183,11 @@ struct SubRectItem { writeUint16LE(fd, y2); writeUint32LE(fd, messageListOffset); } - + int getItemSize() const { return 16; } - + }; struct RectItem { @@ -185,7 +212,7 @@ struct RectItem { subItemOffset += 16; subRectItems.push_back(subRectItem); } - } + } void save(FILE *fd) { writeUint16LE(fd, x1); @@ -196,11 +223,11 @@ struct RectItem { for (uint32 j = 0; j < subRectItems.size(); j++) subRectItems[j].save(fd); } - + int getItemSize() const { return 16; } - + }; struct NavigationItem { @@ -211,10 +238,10 @@ struct NavigationItem { byte interactive; byte middleFlag; uint32 mouseCursorFileHash; - + void load(uint32 offset) { byte *item = getData(offset); - fileHash = READ_LE_UINT32(item + 0); + fileHash = READ_LE_UINT32(item + 0); leftSmackerFileHash = READ_LE_UINT32(item + 4); rightSmackerFileHash = READ_LE_UINT32(item + 8); middleSmackerFileHash = READ_LE_UINT32(item + 12); @@ -236,7 +263,7 @@ struct NavigationItem { int getItemSize() const { return 24; } - + }; struct SceneInfo140Item { @@ -320,24 +347,24 @@ struct SceneInfo2700Item { template<class ITEMCLASS> class StaticDataList { public: - uint32 id; + uint32 id; std::vector<ITEMCLASS> items; - + virtual ~StaticDataList() { } - + void add(ITEMCLASS item) { items.push_back(item); } - + int getCount() const { return items.size(); } - + ITEMCLASS *getListItem(int index) { return &items[index]; } - + virtual bool specialLoadList(uint32 count, uint32 offset) { return false; } @@ -371,7 +398,7 @@ class RectList : public StaticDataList<RectItem> { }; class MessageList : public StaticDataList<MessageItem> { -public: +public: virtual bool specialLoadList(uint32 count, uint32 offset) { // Special code for message lists which are set at runtime (but otherwise constant) @@ -428,7 +455,7 @@ public: } return false; } - + }; class NavigationList : public StaticDataList<NavigationItem> { @@ -438,11 +465,11 @@ template<class LISTCLASS> class StaticDataListVector { public: std::vector<LISTCLASS*> lists; - + void add(LISTCLASS *list) { lists.push_back(list); } - + void loadListVector(const uint32 *offsets) { for (int i = 0; offsets[i] != 0; i += 2) { LISTCLASS *list = new LISTCLASS(); @@ -459,7 +486,7 @@ public: lists.push_back(list); } } - + void saveListVector(FILE *fd) { writeUint32LE(fd, lists.size()); for (typename std::vector<LISTCLASS*>::iterator it = lists.begin(); it != lists.end(); it++) { @@ -473,7 +500,7 @@ template<class ITEMCLASS> class StaticDataVector { public: std::vector<ITEMCLASS> items; - + void loadVector(const uint32 *offsets) { for (int i = 0; offsets[i] != 0; i++) { ITEMCLASS item; @@ -481,7 +508,7 @@ public: items.push_back(item); } } - + void saveVector(FILE *fd) { writeUint32LE(fd, items.size()); for (typename std::vector<ITEMCLASS>::iterator it = items.begin(); it != items.end(); it++) { @@ -495,8 +522,8 @@ StaticDataListVector<HitRectList> hitRectLists; StaticDataListVector<RectList> rectLists; StaticDataListVector<MessageList> messageLists; StaticDataListVector<NavigationList> navigationLists; -StaticDataVector<SceneInfo140Item> sceneInfo140Items; -StaticDataVector<SceneInfo2700Item> sceneInfo2700Items; +StaticDataVector<SceneInfo140Item> sceneInfo140Items; +StaticDataVector<SceneInfo2700Item> sceneInfo2700Items; void addMessageList(uint32 messageListCount, uint32 messageListOffset) { MessageList *messageList = new MessageList(); @@ -506,9 +533,11 @@ void addMessageList(uint32 messageListCount, uint32 messageListOffset) { int main(int argc, char *argv[]) { - FILE *datFile; + if (!loadExe("nhc.exe") || + !validateMd5()) + return 1; - loadExe("nhc.exe"); + FILE *datFile; hitRectLists.loadListVector(hitRectListOffsets); rectLists.loadListVector(rectListOffsets); @@ -516,12 +545,12 @@ int main(int argc, char *argv[]) { navigationLists.loadListVector(navigationListOffsets); sceneInfo140Items.loadVector(sceneInfo140Offsets); sceneInfo2700Items.loadVector(sceneInfo2700Offsets); - + datFile = fopen("neverhood.dat", "wb"); writeUint32LE(datFile, 0x11223344); // Some magic writeUint32LE(datFile, DAT_VERSION); - + messageLists.saveListVector(datFile); rectLists.saveListVector(datFile); hitRectLists.saveListVector(datFile); |