From a6f1280fcc5f0811f799824dab9b29e46dbb989f Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 4 Nov 2009 08:38:32 +0000 Subject: Added support for loading the game's object list svn-id: r45651 --- engines/m4/console.cpp | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++ engines/m4/console.h | 1 + engines/m4/globals.cpp | 30 ++++++++++++++++++++++++- engines/m4/globals.h | 35 ++++++++++++++++++++++++++--- engines/m4/m4.cpp | 4 ++-- 5 files changed, 124 insertions(+), 6 deletions(-) (limited to 'engines') diff --git a/engines/m4/console.cpp b/engines/m4/console.cpp index 1950371edd..1a59d72bb4 100644 --- a/engines/m4/console.cpp +++ b/engines/m4/console.cpp @@ -47,11 +47,26 @@ Console::Console(M4Engine *vm) : GUI::Debugger() { DCmd_Register("textview", WRAP_METHOD(Console, cmdShowTextview)); DCmd_Register("animview", WRAP_METHOD(Console, cmdShowAnimview)); DCmd_Register("anim", WRAP_METHOD(Console, cmdPlayAnimation)); + DCmd_Register("object", WRAP_METHOD(Console, cmdObject)); } Console::~Console() { } +static int strToInt(const char *s) { + if (!*s) + // No string at all + return 0; + else if (toupper(s[strlen(s) - 1]) != 'H') + // Standard decimal string + return atoi(s); + + // Hexadecimal string + uint tmp; + sscanf(s, "%xh", &tmp); + return (int)tmp; +} + bool Console::cmdLoadScene(int argc, const char **argv) { if (argc != 2) { DebugPrintf("Usage: %s \n", argv[0]); @@ -284,4 +299,49 @@ bool Console::cmdPlayAnimation(int argc, const char **argv) { return true; } +bool Console::cmdObject(int argc, const char **argv) { + if (_vm->isM4()) { + DebugPrintf("Command not implemented for M4 games\n"); + } else if (argc == 1) { + DebugPrintf("Usage: object ['list' | '#objnum']\n"); + } else if (!strcmp(argv[1], "list")) { + // List of objects + for (uint objStart = 0; objStart < _vm->_globals->getObjectsSize(); objStart += 5) { + DebugPrintf("%2d - ", objStart); + for (uint objId = objStart; objId < MIN(_vm->_globals->getObjectsSize(), objStart + 5); ++objId) { + if (objId != objStart) DebugPrintf(", "); + uint16 descId = _vm->_globals->getObject(objId)->descId - 1; + DebugPrintf("%s", _vm->_globals->getVocab(descId)); + } + + DebugPrintf("\n"); + } + + DebugPrintf("\n"); + } else { + // Print the details of a specific object + int id = strToInt(argv[1]); + + if ((id < 0) || (id >= (int)_vm->_globals->getObjectsSize())) + DebugPrintf("Invalid object specified\n"); + else { + const MadsObject *obj = _vm->_globals->getObject(id); + + DebugPrintf("Object #%d (%s) room=%d vocabs=%d", id, _vm->_globals->getVocab(obj->descId - 1), + obj->roomNumber, obj->vocabCount); + if (obj->vocabCount > 0) { + DebugPrintf(" - "); + for (int i = 0; i < obj->vocabCount; ++i) { + if (i != 0) DebugPrintf(", "); + DebugPrintf("%s (%d)/%d", _vm->_globals->getVocab(obj->vocabList[i].vocabId - 1), + obj->vocabList[i].vocabId, obj->vocabList[i].unk); + } + } + DebugPrintf("\n"); + } + } + + return true; +} + } // End of namespace M4 diff --git a/engines/m4/console.h b/engines/m4/console.h index 3ec8637d2b..f34fa627b8 100644 --- a/engines/m4/console.h +++ b/engines/m4/console.h @@ -53,6 +53,7 @@ private: bool cmdShowTextview(int argc, const char **argv); bool cmdShowAnimview(int argc, const char **argv); bool cmdPlayAnimation(int argc, const char **argv); + bool cmdObject(int argc, const char **argv); private: M4Engine *_vm; diff --git a/engines/m4/globals.cpp b/engines/m4/globals.cpp index 7028569c6b..55a8e61cd7 100644 --- a/engines/m4/globals.cpp +++ b/engines/m4/globals.cpp @@ -359,7 +359,17 @@ void Globals::loadMadsMessagesInfo() { _vm->res()->toss("messages.dat"); } -char* Globals::loadMessage(uint index) { +void Globals::loadMadsObjects() { + Common::SeekableReadStream *objList = _vm->res()->get("objects.dat"); + int numObjects = objList->readUint16LE(); + + for (int i = 0; i < numObjects; ++i) + _madsObjects.push_back(MadsObjectArray::value_type(new MadsObject(objList))); + + _vm->res()->toss("objects.dat"); +} + +const char *Globals::loadMessage(uint index) { if (index > _madsMessages.size() - 1) { warning("Invalid message index: %i", index); return NULL; @@ -451,5 +461,23 @@ bool Player::saidAny(const char *word1, const char *word2, const char *word3, return false; } +/*--------------------------------------------------------------------------*/ + +MadsObject::MadsObject(Common::SeekableReadStream *stream) { + // Get the next data block + uint8 obj[0x30]; + stream->read(obj, 0x30); + + // Extract object data fields + descId = READ_LE_UINT16(&obj[0]); + roomNumber = READ_LE_UINT16(&obj[2]); + vocabCount = obj[5]; + assert(vocabCount <= 3); + + for (int i = 0; i < vocabCount; ++i) { + vocabList[i].unk = READ_LE_UINT16(&obj[6 + i * 4]); + vocabList[i].vocabId = READ_LE_UINT16(&obj[8 + i * 4]); + } +} } // End of namespace M4 diff --git a/engines/m4/globals.h b/engines/m4/globals.h index aaf05fb94f..37348b1367 100644 --- a/engines/m4/globals.h +++ b/engines/m4/globals.h @@ -30,6 +30,9 @@ #include "common/rect.h" #include "common/scummsys.h" +#include "common/file.h" +#include "common/ptr.h" + namespace M4 { class M4Engine; @@ -146,6 +149,27 @@ public: #define TOTAL_NUM_VARIABLES 256 +#define PLAYER_INVENTORY 2 + +struct VocabEntry { + uint16 unk; + uint16 vocabId; +}; + +class MadsObject { +public: + MadsObject() {}; + MadsObject(Common::SeekableReadStream *stream); + bool isInInventory() const { return roomNumber == PLAYER_INVENTORY; }; + + uint16 descId; + uint16 roomNumber; + uint8 vocabCount; + VocabEntry vocabList[3]; +}; + +typedef Common::Array > MadsObjectArray; + class Globals { private: struct MessageItem { @@ -159,6 +183,7 @@ private: Common::Array _madsVocab; Common::Array _madsQuotes; Common::Array _madsMessages; + MadsObjectArray _madsObjects; public: Globals(M4Engine *vm); ~Globals(); @@ -169,15 +194,19 @@ public: void loadMadsVocab(); uint32 getVocabSize() { return _madsVocab.size(); } - char* getVocab(uint32 index) { return _madsVocab[index]; } + const char *getVocab(uint32 index) { return _madsVocab[index]; } void loadMadsQuotes(); uint32 getQuotesSize() { return _madsQuotes.size(); } - char* getQuote(uint32 index) { return _madsQuotes[index]; } + const char *getQuote(uint32 index) { return _madsQuotes[index]; } void loadMadsMessagesInfo(); uint32 getMessagesSize() { return _madsMessages.size(); } - char* loadMessage(uint index); + const char *loadMessage(uint index); + + void loadMadsObjects(); + uint32 getObjectsSize() { return _madsObjects.size(); } + const MadsObject *getObject(uint32 index) { return _madsObjects[index].get(); } }; #define PLAYER_FIELD_LENGTH 40 diff --git a/engines/m4/m4.cpp b/engines/m4/m4.cpp index 79ffd7bfd0..80fcbc4122 100644 --- a/engines/m4/m4.cpp +++ b/engines/m4/m4.cpp @@ -282,8 +282,8 @@ Common::Error M4Engine::goMADS() { _globals->loadMadsVocab(); // vocab.dat _globals->loadMadsQuotes(); // quotes.dat _globals->loadMadsMessagesInfo(); // messages.dat - // TODO: objects.dat - // TODO: hoganus.dat (what is it used for?) + _globals->loadMadsObjects(); + // Test code to dump all messages to the console //for (int i = 0; i < _globals->getMessagesSize(); i++) -- cgit v1.2.3