Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

View File

@@ -0,0 +1,570 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
// Disable symbol overrides so that we can use system headers.
#define FORBIDDEN_SYMBOL_ALLOW_ALL
#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;
uint32 fileStart = 0x000AC600;
class HitRectList;
class RectList;
class MessageList;
class NavigationList;
void addMessageList(uint32 messageListCount, uint32 messageListOffset);
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) {
return data + offset - dataStart + fileStart;
}
const char *getStringP(uint32 offset) {
return offset != 0 ? (const char*)getData(offset) : nullptr;
}
uint32 calcHash(const char *value) {
if (!value)
return 0;
uint32 hash = 0, shiftValue = 0;
while (*value != 0) {
char ch = *value++;
if (ch >= 'a' && ch <= 'z')
ch -= 32;
else if (ch >= '0' && ch <= '9')
ch += 22;
shiftValue += ch - 64;
if (shiftValue >= 32)
shiftValue -= 32;
hash ^= 1 << shiftValue;
}
return hash;
}
struct HitRect {
int16 x1, y1, x2, y2;
uint16 messageNum;
void load(uint32 offset) {
byte *item = getData(offset);
x1 = READ_LE_UINT16(item + 0);
y1 = READ_LE_UINT16(item + 2);
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);
writeUint16LE(fd, y1);
writeUint16LE(fd, x2);
writeUint16LE(fd, y2);
writeUint16LE(fd, messageNum);
}
int getItemSize() const {
return 10;
}
};
struct MessageItem {
uint16 messageNum;
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 {
int16 x1, y1, x2, y2;
uint32 messageListCount;
uint32 messageListOffset;
void load(uint32 offset) {
byte *item = getData(offset);
x1 = READ_LE_UINT16(item + 0);
y1 = READ_LE_UINT16(item + 2);
x2 = READ_LE_UINT16(item + 4);
y2 = READ_LE_UINT16(item + 6);
messageListCount = READ_LE_UINT32(item + 8);
messageListOffset = READ_LE_UINT32(item + 12);
// Add the message to the message list
addMessageList(messageListCount, messageListOffset);
}
void save(FILE *fd) {
writeUint16LE(fd, x1);
writeUint16LE(fd, y1);
writeUint16LE(fd, x2);
writeUint16LE(fd, y2);
writeUint32LE(fd, messageListOffset);
}
int getItemSize() const {
return 16;
}
};
struct RectItem {
int16 x1, y1, x2, y2;
uint32 subRectListCount;
uint32 subRectListOffset;
std::vector<SubRectItem> subRectItems;
void load(uint32 offset) {
byte *item = getData(offset);
uint32 subItemOffset;
x1 = READ_LE_UINT16(item + 0);
y1 = READ_LE_UINT16(item + 2);
x2 = READ_LE_UINT16(item + 4);
y2 = READ_LE_UINT16(item + 6);
subRectListCount = READ_LE_UINT32(item + 8);
subRectListOffset = READ_LE_UINT32(item + 12);
subItemOffset = subRectListOffset;
for (uint32 j = 0; j < subRectListCount; j++) {
SubRectItem subRectItem;
subRectItem.load(subItemOffset);
subItemOffset += 16;
subRectItems.push_back(subRectItem);
}
}
void save(FILE *fd) {
writeUint16LE(fd, x1);
writeUint16LE(fd, y1);
writeUint16LE(fd, x2);
writeUint16LE(fd, y2);
writeUint32LE(fd, subRectItems.size());
for (uint32 j = 0; j < subRectItems.size(); j++)
subRectItems[j].save(fd);
}
int getItemSize() const {
return 16;
}
};
struct NavigationItem {
uint32 fileHash;
uint32 leftSmackerFileHash;
uint32 rightSmackerFileHash;
uint32 middleSmackerFileHash;
byte interactive;
byte middleFlag;
uint32 mouseCursorFileHash;
void load(uint32 offset) {
byte *item = getData(offset);
fileHash = READ_LE_UINT32(item + 0);
leftSmackerFileHash = READ_LE_UINT32(item + 4);
rightSmackerFileHash = READ_LE_UINT32(item + 8);
middleSmackerFileHash = READ_LE_UINT32(item + 12);
interactive = item[16];
middleFlag = item[17];
mouseCursorFileHash = READ_LE_UINT32(item + 20);
}
void save(FILE *fd) {
writeUint32LE(fd, fileHash);
writeUint32LE(fd, leftSmackerFileHash);
writeUint32LE(fd, rightSmackerFileHash);
writeUint32LE(fd, middleSmackerFileHash);
writeByte(fd, interactive);
writeByte(fd, middleFlag);
writeUint32LE(fd, mouseCursorFileHash);
}
int getItemSize() const {
return 24;
}
};
struct SceneInfo140Item {
uint32 id;
uint32 bgFilename1;
uint32 bgFilename2;
uint32 txFilename;
uint32 bgFilename3;
byte xPosIndex;
byte count;
void load(uint32 offset) {
byte *item = getData(offset);
id = offset;
// Only save the hashes instead of the full names
bgFilename1 = calcHash(getStringP(READ_LE_UINT32(item + 0)));
bgFilename2 = calcHash(getStringP(READ_LE_UINT32(item + 4)));
txFilename = calcHash(getStringP(READ_LE_UINT32(item + 8)));
bgFilename3 = calcHash(getStringP(READ_LE_UINT32(item + 12)));
xPosIndex = item[16];
count = item[17];
}
void save(FILE *fd) {
writeUint32LE(fd, id);
writeUint32LE(fd, bgFilename1);
writeUint32LE(fd, bgFilename2);
writeUint32LE(fd, txFilename);
writeUint32LE(fd, bgFilename3);
writeByte(fd, xPosIndex);
writeByte(fd, count);
}
};
struct SceneInfo2700Item {
uint32 id;
uint32 bgFilename;
uint32 class437Filename;
uint32 dataResourceFilename;
uint32 pointListName;
uint32 rectListName;
uint32 exPaletteFilename2;
uint32 exPaletteFilename1;
uint32 mouseCursorFilename;
int16 which1;
int16 which2;
void load(uint32 offset) {
byte *item = getData(offset);
id = offset;
// Only save the hashes instead of the full names
bgFilename = calcHash(getStringP(READ_LE_UINT32(item + 0)));
class437Filename = calcHash(getStringP(READ_LE_UINT32(item + 4)));
dataResourceFilename = calcHash(getStringP(READ_LE_UINT32(item + 8)));
pointListName = calcHash(getStringP(READ_LE_UINT32(item + 12)));
rectListName = calcHash(getStringP(READ_LE_UINT32(item + 16)));
exPaletteFilename2 = calcHash(getStringP(READ_LE_UINT32(item + 20)));
exPaletteFilename1 = calcHash(getStringP(READ_LE_UINT32(item + 24)));
mouseCursorFilename = calcHash(getStringP(READ_LE_UINT32(item + 28)));
which1 = READ_LE_UINT16(item + 32);
which2 = READ_LE_UINT16(item + 34);
}
void save(FILE *fd) {
writeUint32LE(fd, id);
writeUint32LE(fd, bgFilename);
writeUint32LE(fd, class437Filename);
writeUint32LE(fd, dataResourceFilename);
writeUint32LE(fd, pointListName);
writeUint32LE(fd, rectListName);
writeUint32LE(fd, exPaletteFilename2);
writeUint32LE(fd, exPaletteFilename1);
writeUint32LE(fd, mouseCursorFilename);
writeUint16LE(fd, which1);
writeUint16LE(fd, which2);
}
};
template<class ITEMCLASS>
class StaticDataList {
public:
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;
}
void loadList(uint32 count, uint32 offset) {
id = offset;
if (!specialLoadList(count, offset)) {
for (uint32 i = 0; i < count; i++) {
ITEMCLASS listItem;
listItem.load(offset);
offset += listItem.getItemSize();
add(listItem);
}
}
}
void saveList(FILE *fd) {
writeUint32LE(fd, id);
writeUint32LE(fd, getCount());
for (int i = 0; i < getCount(); i++) {
items[i].save(fd);
}
}
};
class HitRectList : public StaticDataList<HitRect> {
};
class RectList : public StaticDataList<RectItem> {
};
class MessageList : public StaticDataList<MessageItem> {
public:
bool specialLoadList(uint32 count, uint32 offset) override {
// Special code for message lists which are set at runtime (but otherwise constant)
switch (offset) {
// Scene 1002 rings
case 0x004B4200:
add(MessageItem(0x4800, 258));
add(MessageItem(0x100D, 0x4A845A00));
add(MessageItem(0x4805, 1));
return true;
case 0x004B4218:
add(MessageItem(0x4800, 297));
add(MessageItem(0x100D, 0x43807801));
add(MessageItem(0x4805, 2));
return true;
case 0x004B4230:
add(MessageItem(0x4800, 370));
add(MessageItem(0x100D, 0x46C26A01));
return true;
case 0x004B4240:
add(MessageItem(0x4800, 334));
add(MessageItem(0x100D, 0x468C7B11));
add(MessageItem(0x4805, 1));
return true;
case 0x004B4258:
add(MessageItem(0x4800, 425));
add(MessageItem(0x100D, 0x42845B19));
add(MessageItem(0x4805, 1));
return true;
// Scene 1302 rings
case 0x004B0888:
add(MessageItem(0x4800, 218));
add(MessageItem(0x100D, 0x4A845A00));
add(MessageItem(0x4805, 1));
return true;
case 0x004B08A0:
add(MessageItem(0x4800, 218 + 32));
add(MessageItem(0x100D, 0x43807801));
return true;
case 0x004B08B0:
add(MessageItem(0x4800, 218 + 32 + 32));
add(MessageItem(0x100D, 0x46C26A01));
add(MessageItem(0x4805, 1));
return true;
case 0x004B08C8:
add(MessageItem(0x4800, 218 + 32 + 32 + 32));
add(MessageItem(0x100D, 0x468C7B11));
return true;
case 0x004B08D8:
add(MessageItem(0x4800, 218 + 32 + 32 + 32 + 32));
add(MessageItem(0x100D, 0x42845B19));
add(MessageItem(0x4805, 4));
return true;
default:
break;
}
return false;
}
};
class NavigationList : public StaticDataList<NavigationItem> {
};
template<class LISTCLASS>
class StaticDataListVector {
public:
std::vector<LISTCLASS*> lists;
void add(LISTCLASS *list) {
bool doAppend = true;
for (typename std::vector<LISTCLASS*>::iterator it = lists.begin(); it != lists.end(); it++) {
if ((*it)->id == list->id) {
doAppend = false;
break;
}
}
if (doAppend)
lists.push_back(list);
}
void loadListVector(const uint32 *offsets) {
for (int i = 0; offsets[i] != 0; i += 2) {
LISTCLASS *list = new LISTCLASS();
list->loadList(offsets[i], offsets[i + 1]);
bool doAppend = true;
for (typename std::vector<LISTCLASS*>::iterator it = lists.begin(); it != lists.end(); it++) {
if ((*it)->id == list->id) {
doAppend = false;
break;
}
}
if (doAppend)
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++) {
(*it)->saveList(fd);
}
}
};
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;
item.load(offsets[i]);
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++) {
(*it).save(fd);
}
}
};
StaticDataListVector<MessageList> *messageLists;
void addMessageList(uint32 messageListCount, uint32 messageListOffset) {
MessageList *messageList = new MessageList();
messageList->loadList(messageListCount, messageListOffset);
messageLists->add(messageList);
}
int main(int argc, char *argv[]) {
StaticDataListVector<HitRectList> hitRectLists;
StaticDataListVector<RectList> rectLists;
StaticDataListVector<NavigationList> navigationLists;
StaticDataVector<SceneInfo140Item> sceneInfo140Items;
StaticDataVector<SceneInfo2700Item> sceneInfo2700Items;
messageLists = new StaticDataListVector<MessageList>;
if (!loadExe("nhc.exe") ||
!validateMd5())
return 1;
FILE *datFile;
hitRectLists.loadListVector(hitRectListOffsets);
rectLists.loadListVector(rectListOffsets);
messageLists->loadListVector(messageListOffsets);
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);
navigationLists.saveListVector(datFile);
sceneInfo140Items.saveVector(datFile);
sceneInfo2700Items.saveVector(datFile);
delete messageLists;
fclose(datFile);
printf("Done.\n");
return 0;
}

View File

@@ -0,0 +1,27 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef CREATE_NEVERHOOD_H
#define CREATE_NEVERHOOD_H
#include "util.h"
#endif

View File

@@ -0,0 +1,272 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
// Disable symbol overrides so that we can use system headers.
#define FORBIDDEN_SYMBOL_ALLOW_ALL
#include "md5.h"
#define GET_UINT32(n, b, i) (n) = READ_LE_UINT32(b + i)
#define PUT_UINT32(n, b, i) WRITE_LE_UINT32(b + i, n)
void md5_starts(md5_context *ctx) {
ctx->total[0] = 0;
ctx->total[1] = 0;
ctx->state[0] = 0x67452301;
ctx->state[1] = 0xEFCDAB89;
ctx->state[2] = 0x98BADCFE;
ctx->state[3] = 0x10325476;
}
static void md5_process(md5_context *ctx, const uint8 data[64]) {
uint32 X[16], A, B, C, D;
GET_UINT32(X[0], data, 0);
GET_UINT32(X[1], data, 4);
GET_UINT32(X[2], data, 8);
GET_UINT32(X[3], data, 12);
GET_UINT32(X[4], data, 16);
GET_UINT32(X[5], data, 20);
GET_UINT32(X[6], data, 24);
GET_UINT32(X[7], data, 28);
GET_UINT32(X[8], data, 32);
GET_UINT32(X[9], data, 36);
GET_UINT32(X[10], data, 40);
GET_UINT32(X[11], data, 44);
GET_UINT32(X[12], data, 48);
GET_UINT32(X[13], data, 52);
GET_UINT32(X[14], data, 56);
GET_UINT32(X[15], data, 60);
#define S(x, n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
#define P(a, b, c, d, k, s, t) \
{ \
a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
}
A = ctx->state[0];
B = ctx->state[1];
C = ctx->state[2];
D = ctx->state[3];
#define F(x, y, z) (z ^ (x & (y ^ z)))
P(A, B, C, D, 0, 7, 0xD76AA478);
P(D, A, B, C, 1, 12, 0xE8C7B756);
P(C, D, A, B, 2, 17, 0x242070DB);
P(B, C, D, A, 3, 22, 0xC1BDCEEE);
P(A, B, C, D, 4, 7, 0xF57C0FAF);
P(D, A, B, C, 5, 12, 0x4787C62A);
P(C, D, A, B, 6, 17, 0xA8304613);
P(B, C, D, A, 7, 22, 0xFD469501);
P(A, B, C, D, 8, 7, 0x698098D8);
P(D, A, B, C, 9, 12, 0x8B44F7AF);
P(C, D, A, B, 10, 17, 0xFFFF5BB1);
P(B, C, D, A, 11, 22, 0x895CD7BE);
P(A, B, C, D, 12, 7, 0x6B901122);
P(D, A, B, C, 13, 12, 0xFD987193);
P(C, D, A, B, 14, 17, 0xA679438E);
P(B, C, D, A, 15, 22, 0x49B40821);
#undef F
#define F(x, y, z) (y ^ (z & (x ^ y)))
P(A, B, C, D, 1, 5, 0xF61E2562);
P(D, A, B, C, 6, 9, 0xC040B340);
P(C, D, A, B, 11, 14, 0x265E5A51);
P(B, C, D, A, 0, 20, 0xE9B6C7AA);
P(A, B, C, D, 5, 5, 0xD62F105D);
P(D, A, B, C, 10, 9, 0x02441453);
P(C, D, A, B, 15, 14, 0xD8A1E681);
P(B, C, D, A, 4, 20, 0xE7D3FBC8);
P(A, B, C, D, 9, 5, 0x21E1CDE6);
P(D, A, B, C, 14, 9, 0xC33707D6);
P(C, D, A, B, 3, 14, 0xF4D50D87);
P(B, C, D, A, 8, 20, 0x455A14ED);
P(A, B, C, D, 13, 5, 0xA9E3E905);
P(D, A, B, C, 2, 9, 0xFCEFA3F8);
P(C, D, A, B, 7, 14, 0x676F02D9);
P(B, C, D, A, 12, 20, 0x8D2A4C8A);
#undef F
#define F(x, y, z) (x ^ y ^ z)
P(A, B, C, D, 5, 4, 0xFFFA3942);
P(D, A, B, C, 8, 11, 0x8771F681);
P(C, D, A, B, 11, 16, 0x6D9D6122);
P(B, C, D, A, 14, 23, 0xFDE5380C);
P(A, B, C, D, 1, 4, 0xA4BEEA44);
P(D, A, B, C, 4, 11, 0x4BDECFA9);
P(C, D, A, B, 7, 16, 0xF6BB4B60);
P(B, C, D, A, 10, 23, 0xBEBFBC70);
P(A, B, C, D, 13, 4, 0x289B7EC6);
P(D, A, B, C, 0, 11, 0xEAA127FA);
P(C, D, A, B, 3, 16, 0xD4EF3085);
P(B, C, D, A, 6, 23, 0x04881D05);
P(A, B, C, D, 9, 4, 0xD9D4D039);
P(D, A, B, C, 12, 11, 0xE6DB99E5);
P(C, D, A, B, 15, 16, 0x1FA27CF8);
P(B, C, D, A, 2, 23, 0xC4AC5665);
#undef F
#define F(x, y, z) (y ^ (x | ~z))
P(A, B, C, D, 0, 6, 0xF4292244);
P(D, A, B, C, 7, 10, 0x432AFF97);
P(C, D, A, B, 14, 15, 0xAB9423A7);
P(B, C, D, A, 5, 21, 0xFC93A039);
P(A, B, C, D, 12, 6, 0x655B59C3);
P(D, A, B, C, 3, 10, 0x8F0CCC92);
P(C, D, A, B, 10, 15, 0xFFEFF47D);
P(B, C, D, A, 1, 21, 0x85845DD1);
P(A, B, C, D, 8, 6, 0x6FA87E4F);
P(D, A, B, C, 15, 10, 0xFE2CE6E0);
P(C, D, A, B, 6, 15, 0xA3014314);
P(B, C, D, A, 13, 21, 0x4E0811A1);
P(A, B, C, D, 4, 6, 0xF7537E82);
P(D, A, B, C, 11, 10, 0xBD3AF235);
P(C, D, A, B, 2, 15, 0x2AD7D2BB);
P(B, C, D, A, 9, 21, 0xEB86D391);
#undef F
ctx->state[0] += A;
ctx->state[1] += B;
ctx->state[2] += C;
ctx->state[3] += D;
}
void md5_update(md5_context *ctx, const uint8 *input, uint32 length) {
uint32 left, fill;
if (!length)
return;
left = ctx->total[0] & 0x3F;
fill = 64 - left;
ctx->total[0] += length;
ctx->total[0] &= 0xFFFFFFFF;
if (ctx->total[0] < length)
ctx->total[1]++;
if (left && length >= fill) {
memcpy((void *)(ctx->buffer + left), (const void *)input, fill);
md5_process(ctx, ctx->buffer);
length -= fill;
input += fill;
left = 0;
}
while (length >= 64) {
md5_process(ctx, input);
length -= 64;
input += 64;
}
if (length) {
memcpy((void *)(ctx->buffer + left), (const void *)input, length);
}
}
static const uint8 md5_padding[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
void md5_finish(md5_context *ctx, uint8 digest[16]) {
uint32 last, padn;
uint32 high, low;
uint8 msglen[8];
high = (ctx->total[0] >> 29) | (ctx->total[1] << 3);
low = (ctx->total[0] << 3);
PUT_UINT32(low, msglen, 0);
PUT_UINT32(high, msglen, 4);
last = ctx->total[0] & 0x3F;
padn = (last < 56) ? (56 - last) : (120 - last);
md5_update(ctx, md5_padding, padn);
md5_update(ctx, msglen, 8);
PUT_UINT32(ctx->state[0], digest, 0);
PUT_UINT32(ctx->state[1], digest, 4);
PUT_UINT32(ctx->state[2], digest, 8);
PUT_UINT32(ctx->state[3], digest, 12);
}
bool md5_file(const char *name, uint8 digest[16], uint32 length) {
FILE *f;
f = fopen(name, "rb");
if (f == nullptr) {
printf("md5_file couldn't open '%s'\n", name);
return false;
}
md5_context ctx;
uint32 i;
unsigned char buf[1000];
bool restricted = (length != 0);
int readlen;
if (!restricted || sizeof(buf) <= length)
readlen = sizeof(buf);
else
readlen = length;
md5_starts(&ctx);
while ((i = (uint32)fread(buf, 1, readlen, f)) > 0) {
md5_update(&ctx, buf, i);
length -= i;
if (restricted && length == 0)
break;
if (restricted && sizeof(buf) > length)
readlen = length;
}
md5_finish(&ctx, digest);
fclose(f);
return true;
}
void md5_buffer(byte *buf, uint32 len, uint8 digest[16]) {
md5_context ctx;
md5_starts(&ctx);
md5_update(&ctx, buf, len);
md5_finish(&ctx, digest);
}

View File

@@ -0,0 +1,40 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef COMMON_MD5_H
#define COMMON_MD5_H
#include "util.h"
typedef struct {
uint32 total[2];
uint32 state[4];
uint8 buffer[64];
} md5_context;
void md5_starts(md5_context *ctx);
void md5_update(md5_context *ctx, const uint8 *input, uint32 length);
void md5_finish(md5_context *ctx, uint8 digest[16]);
bool md5_file(const char *name, uint8 digest[16], uint32 length = 0);
void md5_buffer(byte *buf, uint32 len, uint8 digest[16]);
#endif

View File

@@ -0,0 +1,13 @@
MODULE := devtools/create_neverhood
MODULE_OBJS := \
create_neverhood.o \
md5.o \
util.o
# Set the name of the executable
TOOL_EXECUTABLE := create_neverhood
# Include common rules
include $(srcdir)/rules.mk

View File

@@ -0,0 +1,716 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
static const uint32 hitRectListOffsets[] = {
// Scene1001
1, 0x004B4860,
// Scene1002
1, 0x004B4138,
// Scene1201
4, 0x004AEBD0,
// Scene1302
1, 0x004B0858,
// Scene1705
1, 0x004B69D8,
// Scene2203
1, 0x004B8320,
// Scene2205
1, 0x004B0620,
0, 0
};
static const uint32 rectListOffsets[] = {
// Scene1001
1, 0x004B49F0,
1, 0x004B4A00,
// Scene1002
3, 0x004B43A0,
1, 0x004B4418,
// Scene1004
1, 0x004B7C70,
// Scene1109
1, 0x004B63A8,
1, 0x004B6398,
// Scene1201
1, 0x004AEE58,
1, 0x004AEDC8,
1, 0x004AEE18,
1, 0x004AED88,
// Scene1302
2, 0x004B0A38,
// Scene1303
1, 0x004AF9E8,
// Scene1304
1, 0x004B91A8,
// Scene1305
1, 0x004B6E98,
// Scene1306
1, 0x004AFD28,
1, 0x004AFD18,
// Scene1308
1, 0x004B5990,
1, 0x004B5980,
1, 0x004B59A0,
// Scene1401
1, 0x004B6758,
// Scene1402
1, 0x004B0C48,
1, 0x004B0C98,
// Scene1403
1, 0x004B1FF8,
1, 0x004B2008,
// Scene1404
1, 0x004B8D80,
// Scene1608
1, 0x004B47D0,
1, 0x004B4810,
// Scene1705
1, 0x004B6B40,
1, 0x004B6B30,
// Scene1901
1, 0x004B34C8,
// Scene2001
1, 0x004B3680,
1, 0x004B3670,
// Scene2101
1, 0x004B9008,
1, 0x004B8FF8,
// Scene2203
1, 0x004B8420,
// Scene2206
1, 0x004B8AF8,
1, 0x004B8B58,
// Scene2207
3, 0x004B38B8,
1, 0x004B3948,
// Scene2242
1, 0x004B3DC8,
1, 0x004B3E18,
// HallOfRecordsScene
1, 0x004B2BF8,
1, 0x004B2BB8,
// Scene2247
1, 0x004B5588,
1, 0x004B55C8,
// Scene2401
1, 0x004B3140,
// Scene2402
1, 0x004AF900,
// Scene2403
1, 0x004B5E18,
1, 0x004B5E28,
// Scene2406
1, 0x004B78C8,
1, 0x004B78D8,
// Scene2501
1, 0x004B2608,
// Scene2732
1, 0x004AE360,
// Scene2801
1, 0x004B6CE0,
1, 0x004B6CD0,
1, 0x004B6CF0,
// Scene2805
1, 0x004AE318,
1, 0x004AE308,
// Scene2810
1, 0x004AE810,
1, 0x004AE800,
// Scene2812
1, 0x004AF700,
1, 0x004AF710,
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,
// Scene1002
1, 0x004B4270,
1, 0x004B4478,
3, 0x004B4298,
1, 0x004B4470,
4, 0x004B4428,
5, 0x004B4448,
1, 0x004B44B8,
2, 0x004B44A8,
1, 0x004B44A0,
2, 0x004B43D0,
4, 0x004B4480,
2, 0x004B41E0,
5, 0x004B4148,
// Scene1004
3, 0x004B7BF0,
2, 0x004B7C08,
1, 0x004B7C18,
2, 0x004B7C20,
// Scene1109
1, 0x004B6260,
2, 0x004B6268,
4, 0x004B6318,
2, 0x004B6278,
1, 0x004B6258,
// Scene1201
1, 0x004AEC08,
2, 0x004AEC10,
2, 0x004AEC20,
2, 0x004AEC30,
4, 0x004AEC90,
2, 0x004AECB0,
2, 0x004AECC0,
5, 0x004AECF0,
2, 0x004AECD0,
2, 0x004AECE0,
2, 0x004AED38,
// Scene1302
4, 0x004B08F0,
3, 0x004B0920,
1, 0x004B0950,
2, 0x004B0940,
1, 0x004B0938,
2, 0x004B0910,
1, 0x004B0968,
2, 0x004B0878,
4, 0x004B0978,
1, 0x004B0870,
1, 0x004B0868,
// Scene1303
1, 0x004AF9A0,
2, 0x004AF9B8,
// Scene1304
1, 0x004B90E8,
1, 0x004B90F0,
2, 0x004B9158,
2, 0x004B9130,
2, 0x004B9140,
// Scene1305
1, 0x004B6E40,
1, 0x004B6E48,
// Scene1306
1, 0x004AFAD0,
2, 0x004AFAF0,
1, 0x004AFBC8,
1, 0x004AFC30,
4, 0x004AFC38,
2, 0x004AFB00,
1, 0x004AFBD0,
4, 0x004AFBD8,
2, 0x004AFAE0,
1, 0x004AFAD8,
2, 0x004AFC58,
2, 0x004AFC68,
// Scene1308
1, 0x004B57C0,
1, 0x004B57C8,
1, 0x004B58B0,
3, 0x004B57D0,
3, 0x004B57E8,
2, 0x004B5868,
4, 0x004B5848,
3, 0x004B5830,
2, 0x004B5800,
2, 0x004B5868,
2, 0x004B58E0,
// Scene1401
1, 0x004B65C8,
1, 0x004B65D0,
1, 0x004B65D8,
1, 0x004B65E8,
3, 0x004B6670,
4, 0x004B6690,
1, 0x004B66B0,
3, 0x004B6658,
2, 0x004B65F0,
// Scene1402
1, 0x004B0B48,
1, 0x004B0B50,
1, 0x004B0B58,
1, 0x004B0B60,
2, 0x004B0B68,
3, 0x004B0BB8,
3, 0x004B0BD0,
// Scene1403
1, 0x004B1F18,
1, 0x004B1F20,
3, 0x004B1F70,
2, 0x004B1FA8,
4, 0x004B1F88,
3, 0x004B1F58,
2, 0x004B1F28,
2, 0x004B1FB8,
// Scene1404
1, 0x004B8C28,
1, 0x004B8C30,
1, 0x004B8C38,
1, 0x004B8D28,
3, 0x004B8CB8,
2, 0x004B8C40,
6, 0x004B8CE8,
3, 0x004B8CA0,
2, 0x004B8CD0,
2, 0x004B8D18,
// Scene1608
1, 0x004B46A8,
1, 0x004B46B0,
1, 0x004B47A8,
3, 0x004B4748,
2, 0x004B4770,
2, 0x004B46C8,
2, 0x004B4760,
// Scene1705
1, 0x004B69E8,
2, 0x004B6A08,
4, 0x004B6AA0,
2, 0x004B6A18,
1, 0x004B69F0,
2, 0x004B6AC0,
// Scene1901
1, 0x004B3408,
1, 0x004B3410,
1, 0x004B3400,
// Scene2001
1, 0x004B3538,
2, 0x004B3540,
4, 0x004B35F0,
2, 0x004B3550,
1, 0x004B3530,
// Scene2101
1, 0x004B8E48,
3, 0x004B8E50,
4, 0x004B8F58,
2, 0x004B8EB0,
2, 0x004B8EA0,
1, 0x004B8F50,
1, 0x004B8F48,
4, 0x004B8E80,
1, 0x004B8EC8,
2, 0x004B8F78,
3, 0x004B8F00,
// Scene2201
1, 0x004B8118,
1, 0x004B8130,
1, 0x004B8178,
2, 0x004B8120,
3, 0x004B81A0,
1, 0x004B81B8,
2, 0x004B8108,
5, 0x004B8150,
4, 0x004B8180,
3, 0x004B8138,
2, 0x004B8108,
2, 0x004B81C8,
// Scene2203
1, 0x004B8340,
1, 0x004B8350,
1, 0x004B8358,
1, 0x004B8348,
3, 0x004B83B0,
3, 0x004B83C8,
2, 0x004B8370,
2, 0x004B8360,
2, 0x004B83E0,
2, 0x004B83F0,
// Scene2205
1, 0x004B0658,
2, 0x004B0648,
1, 0x004B0640,
4, 0x004B0690,
2, 0x004B0630,
// Scene2206
1, 0x004B88A8,
2, 0x004B88B8,
1, 0x004B88C8,
1, 0x004B8A70,
1, 0x004B88B0,
5, 0x004B8948,
2, 0x004B8970,
2, 0x004B8988,
4, 0x004B8998,
4, 0x004B89B8,
4, 0x004B89D8,
5, 0x004B89F8,
5, 0x004B8A20,
5, 0x004B8A48,
// Scene2207
1, 0x004B38E8,
4, 0x004B38F0,
2, 0x004B37D8,
2, 0x004B3958,
3, 0x004B3920,
// Scene2242
1, 0x004B3C18,
1, 0x004B3D60,
1, 0x004B3D48,
1, 0x004B3C20,
2, 0x004B3D50,
5, 0x004B3CF8,
5, 0x004B3D20,
4, 0x004B3CB8,
4, 0x004B3CD8,
// HallOfRecordsScene
1, 0x004B2900,
2, 0x004B2910,
1, 0x004B2B70,
1, 0x004B2908,
2, 0x004B2920,
4, 0x004B2978,
4, 0x004B2998,
4, 0x004B29B8,
4, 0x004B29D8,
4, 0x004B29F8,
4, 0x004B2A18,
4, 0x004B2A38,
5, 0x004B2A58,
5, 0x004B2A80,
5, 0x004B2AA8,
5, 0x004B2AD0,
5, 0x004B2AF8,
5, 0x004B2B20,
5, 0x004B2B48,
// Scene2247
1, 0x004B5428,
2, 0x004B5438,
1, 0x004B5530,
1, 0x004B5430,
4, 0x004B54A0,
4, 0x004B54C0,
5, 0x004B54E0,
5, 0x004B5508,
// Scene2401
1, 0x004B2F70,
1, 0x004B2F80,
1, 0x004B2F78,
4, 0x004B3090,
2, 0x004B30B0,
6, 0x004B3020,
2, 0x004B3050,
4, 0x004B2FA8,
4, 0x004B2FC8,
// Scene2402
1, 0x004AF7C8,
2, 0x004AF7D8,
1, 0x004AF888,
1, 0x004AF7D0,
3, 0x004AF800,
1, 0x004AF818,
2, 0x004AF890,
// Scene2403
1, 0x004B5C98,
1, 0x004B5D70,
4, 0x004B5CA0,
2, 0x004B5D98,
// Scene2406
1, 0x004B76C8,
3, 0x004B76D8,
1, 0x004B77C0,
1, 0x004B7810,
1, 0x004B76D0,
2, 0x004B77C8,
2, 0x004B77D8,
2, 0x004B7758,
4, 0x004B7738,
// Scene2501
7, 0x004B2538,
6, 0x004B2570,
// Scene2732
1, 0x004AE328,
// Scene2801
1, 0x004B6BB8,
1, 0x004B6BC0,
1, 0x004B6C10,
1, 0x004B6BB0,
2, 0x004B6C40,
// Scene2803b
1, 0x004B60D8,
1, 0x004B6100,
1, 0x004B60F8,
1, 0x004B6100,
3, 0x004B6138,
3, 0x004B60E0,
3, 0x004B6180,
1, 0x004B6198,
6, 0x004B6108,
3, 0x004B6150,
3, 0x004B6168,
1, 0x004B61A0,
5, 0x004B61A8,
// Scene2803
1, 0x004B79F0,
5, 0x004B79C8,
1, 0x004B7A00,
2, 0x004B7A78,
1, 0x004B79F8,
1, 0x004B79C0,
1, 0x004B7A50,
2, 0x004B7A58,
5, 0x004B7A08,
4, 0x004B7A30,
2, 0x004B7A68,
7, 0x004B7A88,
// Scene2805
1, 0x004AE1C8,
2, 0x004AE1D0,
4, 0x004AE288,
2, 0x004AE1E0,
1, 0x004AE1C0,
// Scene2806
1, 0x004AF098,
1, 0x004AF098,
3, 0x004AF0C8,
5, 0x004AF0A0,
1, 0x004AF090,
2, 0x004AF0E0,
// Scene2809
1, 0x004B5B90,
3, 0x004B5BD0,
5, 0x004B5BA8,
1, 0x004B5B88,
2, 0x004B5B98,
1, 0x004AE438,
3, 0x004AE440,
3, 0x004AE738,
1, 0x004AE6D8,
2, 0x004AE6E8,
1, 0x004AE6E0,
2, 0x004AE428,
2, 0x004AE418,
1, 0x004AE410,
4, 0x004AE458,
5, 0x004AE4A8,
5, 0x004AE4D0,
5, 0x004AE4F8,
5, 0x004AE520,
5, 0x004AE548,
5, 0x004AE570,
5, 0x004AE598,
5, 0x004AE5C0,
5, 0x004AE5E8,
5, 0x004AE610,
5, 0x004AE638,
5, 0x004AE660,
5, 0x004AE688,
2, 0x004AE750,
// Scene2812
1, 0x004AF560,
1, 0x004AF588,
1, 0x004AF5F0,
4, 0x004AF568,
2, 0x004AF658,
2, 0x004AF668,
0, 0
};
static const uint32 navigationListOffsets[] = {
// Module1100
2, 0x004B8430,
2, 0x004B8460,
4, 0x004B84F0,
4, 0x004B8490,
2, 0x004B8580,
2, 0x004B8550,
// Module1300
6, 0x004B2718,
2, 0x004B27A8,
2, 0x004B27D8,
2, 0x004B2808,
2, 0x004B2838,
// Module1600
4, 0x004B39D0,
2, 0x004B3A30,
2, 0x004B3A60,
6, 0x004B3A90,
2, 0x004B3B20,
2, 0x004B3B50,
2, 0x004B3B80,
// Module1700
2, 0x004AE8B8,
3, 0x004AE8E8,
// Module1800
4, 0x004AFD38,
1, 0x004AFD98,
2, 0x004AFDB0,
4, 0x004AFDE0,
2, 0x004AFE40,
// Module2300
2, 0x004B67B8,
6, 0x004B67E8,
2, 0x004B6878,
3, 0x004B68F0,
3, 0x004B68A8,
// Module2000
3, 0x004B7B48,
3, 0x004B7B00,
// Module2600
2, 0x004B8608,
4, 0x004B8638,
2, 0x004B8698,
2, 0x004B86C8,
4, 0x004B8758,
4, 0x004B86F8,
2, 0x004B87B8,
// Module3000
2, 0x004B7C80,
2, 0x004B7CE0,
2, 0x004B7CB0,
3, 0x004B7D58,
3, 0x004B7D10,
4, 0x004B7E60,
4, 0x004B7DA0,
4, 0x004B7E00,
4, 0x004B7F20,
4, 0x004B7EC0,
2, 0x004B7F80,
1, 0x004B7FB0,
0, 0
};
// Hall of Records scene definitions
static const uint32 sceneInfo140Offsets[] = {
0x004B7180,
0x004B7198,
0x004B71B0,
0x004B71C8,
0x004B71E0,
0x004B71F8,
0x004B7210,
0x004B7228,
0x004B7240,
0x004B7258,
0x004B7270,
0x004B7288,
0x004B72A0,
0x004B72B8,
0x004B72D0,
0x004B72E8,
0x004B7300,
0x004B7318,
0x004B7330,
0x004B7348,
0x004B7360,
0x004B7378,
0x004B7390,
0x004B73A8,
0x004B73C0,
0x004B73D8,
0x004B73F0,
0x004B7408,
0x004B7420,
0x004B7438,
0x004B7450,
0x004B7468,
0x004B7480,
0x004B7498,
0x004B74B0,
0x004B74C8,
0
};
static const uint32 sceneInfo2700Offsets[] = {
//
0x004B1710,
0x004B1738,
0x004B1760,
0x004B1788,
0x004B17B0,
0x004B17D8,
0x004B1800,
0x004B1828,
0x004B1850,
0x004B1878,
0x004B18A0,
0x004B18C8,
0x004B18F0,
0x004B1918,
//
0x004B19E0,
0x004B1A08,
0x004B1A30,
0x004B1A58,
0x004B1A80,
0x004B1AA8,
0x004B1AD0,
0x004B1AF8,
0x004B1B20,
0x004B1B48,
0x004B1B70,
0x004B1B98,
0x004B1BC0,
0x004B1BE8,
0x004B1C10,
0x004B1C38,
0x004B1C60,
0x004B1C88,
0x004B1CB0,
0x004B1CD8,
0x004B1D00,
0x004B1D28,
0x004B1D50,
0x004B1D78,
//
0x004B1DB0,
//
0x004B1DE8,
0x004B1E10,
0x004B1E38,
0x004B1E60,
//
0x004B1950,
//
0x004B2240,
//
0x004B5F68,
0x004B5F8C,
0x004B5FB0,
0x004B5FD8,
0x004B5FFC,
0x004B6020,
// Scene2501
0x004B2628,
0x004B264C,
0x004B2670,
// Scene2502
0x004B01B8,
// Scene2503
0x004B01E0,
0x004B0208,
// Scene2505
0x004B0230,
// Scene2506
0x004B0268,
// Scene2507
0x004B02A0,
// Scene2508
0x004B02C8,
// Scene2706
0x004B22A0,
0x004B22C4,
0x004B22E8,
0
};

View File

@@ -0,0 +1,151 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
// 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;
}

View File

@@ -0,0 +1,55 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#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, ...);
using namespace Common;
#endif