aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/mohawk/console.cpp50
-rw-r--r--engines/mohawk/module.mk1
-rw-r--r--engines/mohawk/riven.cpp105
-rw-r--r--engines/mohawk/riven.h18
-rw-r--r--engines/mohawk/riven_card.cpp4
-rw-r--r--engines/mohawk/riven_external.cpp2
-rw-r--r--engines/mohawk/riven_scripts.cpp26
-rw-r--r--engines/mohawk/riven_scripts.h8
-rw-r--r--engines/mohawk/riven_stack.cpp102
-rw-r--r--engines/mohawk/riven_stack.h60
-rw-r--r--engines/mohawk/riven_vars.cpp2
11 files changed, 245 insertions, 133 deletions
diff --git a/engines/mohawk/console.cpp b/engines/mohawk/console.cpp
index 41dd535c3a..b95b999123 100644
--- a/engines/mohawk/console.cpp
+++ b/engines/mohawk/console.cpp
@@ -564,50 +564,6 @@ bool RivenConsole::Cmd_DumpScript(int argc, const char **argv) {
_vm->changeToStack(newStack);
- // Load in Variable Names
- Common::SeekableReadStream *nameStream = _vm->getResource(ID_NAME, VariableNames);
- Common::StringArray varNames;
-
- uint16 namesCount = nameStream->readUint16BE();
- uint16 *stringOffsets = new uint16[namesCount];
- for (uint16 i = 0; i < namesCount; i++)
- stringOffsets[i] = nameStream->readUint16BE();
- nameStream->seek(namesCount * 2, SEEK_CUR);
- int32 curNamesPos = nameStream->pos();
-
- for (uint32 i = 0; i < namesCount; i++) {
- nameStream->seek(curNamesPos + stringOffsets[i]);
-
- Common::String name;
- for (char c = nameStream->readByte(); c; c = nameStream->readByte())
- name += c;
- varNames.push_back(name);
- }
- delete nameStream;
- delete[] stringOffsets;
-
- // Load in External Command Names
- nameStream = _vm->getResource(ID_NAME, ExternalCommandNames);
- Common::StringArray xNames;
-
- namesCount = nameStream->readUint16BE();
- stringOffsets = new uint16[namesCount];
- for (uint16 i = 0; i < namesCount; i++)
- stringOffsets[i] = nameStream->readUint16BE();
- nameStream->seek(namesCount * 2, SEEK_CUR);
- curNamesPos = nameStream->pos();
-
- for (uint32 i = 0; i < namesCount; i++) {
- nameStream->seek(curNamesPos + stringOffsets[i]);
-
- Common::String name;
- for (char c = nameStream->readByte(); c; c = nameStream->readByte())
- name += c;
- xNames.push_back(name);
- }
- delete nameStream;
- delete[] stringOffsets;
-
// Get CARD/HSPT data and dump their scripts
if (!scumm_stricmp(argv[2], "CARD")) {
// Use debugN to print these because the scripts can get very large and would
@@ -623,7 +579,7 @@ bool RivenConsole::Cmd_DumpScript(int argc, const char **argv) {
RivenScriptList scriptList = _vm->_scriptMan->readScripts(cardStream);
for (uint32 i = 0; i < scriptList.size(); i++) {
debugN("Stream Type %d:\n", scriptList[i].type);
- scriptList[i].script->dumpScript(varNames, xNames, 0);
+ scriptList[i].script->dumpScript(0);
}
delete cardStream;
} else if (!scumm_stricmp(argv[2], "HSPT")) {
@@ -640,8 +596,8 @@ bool RivenConsole::Cmd_DumpScript(int argc, const char **argv) {
hsptStream->seek(22, SEEK_CUR); // Skip non-script related stuff
RivenScriptList scriptList = _vm->_scriptMan->readScripts(hsptStream);
for (uint32 j = 0; j < scriptList.size(); j++) {
- debugN("\tStream Type %d:\n", scriptList[i].type);
- scriptList[j].script->dumpScript(varNames, xNames, 1);
+ debugN("\tStream Type %d:\n", scriptList[j].type);
+ scriptList[j].script->dumpScript(1);
}
}
diff --git a/engines/mohawk/module.mk b/engines/mohawk/module.mk
index 8a186b1526..7de2a1636c 100644
--- a/engines/mohawk/module.mk
+++ b/engines/mohawk/module.mk
@@ -59,6 +59,7 @@ MODULE_OBJS += \
riven_saveload.o \
riven_scripts.o \
riven_sound.o \
+ riven_stack.o \
riven_vars.o
endif
diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp
index 8e30080972..4d30755a32 100644
--- a/engines/mohawk/riven.cpp
+++ b/engines/mohawk/riven.cpp
@@ -50,7 +50,8 @@ Common::Rect *g_cathJournalRect3;
Common::Rect *g_trapBookRect3;
Common::Rect *g_demoExitRect;
-MohawkEngine_Riven::MohawkEngine_Riven(OSystem *syst, const MohawkGameDescription *gamedesc) : MohawkEngine(syst, gamedesc) {
+MohawkEngine_Riven::MohawkEngine_Riven(OSystem *syst, const MohawkGameDescription *gamedesc) :
+ MohawkEngine(syst, gamedesc) {
_showHotspots = false;
_gameOver = false;
_activatedPLST = false;
@@ -345,6 +346,13 @@ void MohawkEngine_Riven::changeToStack(uint16 n) {
if (_mhk.empty())
error("Could not load stack %s", getStackName(_curStack).c_str());
+ // Load stack specific names
+ _varNames = RivenNameList(this, kVariableNames);
+ _externalCommandNames = RivenNameList(this, kExternalCommandNames);
+ _stackNames = RivenNameList(this, kStackNames);
+ _cardNames = RivenNameList(this, kCardNames);
+ _hotspotNames = RivenNameList(this, kHotspotNames);
+
// Stop any currently playing sounds
_sound->stopAllSLST();
}
@@ -516,65 +524,6 @@ Common::SeekableReadStream *MohawkEngine_Riven::getExtrasResource(uint32 tag, ui
return _extrasFile->getResource(tag, id);
}
-Common::String MohawkEngine_Riven::getName(uint16 nameResource, uint16 nameID) {
- Common::SeekableReadStream* nameStream = getResource(ID_NAME, nameResource);
- uint16 fieldCount = nameStream->readUint16BE();
- uint16* stringOffsets = new uint16[fieldCount];
- Common::String name;
- char c;
-
- if (nameID < fieldCount) {
- for (uint16 i = 0; i < fieldCount; i++)
- stringOffsets[i] = nameStream->readUint16BE();
- for (uint16 i = 0; i < fieldCount; i++)
- nameStream->readUint16BE(); // Skip unknown values
-
- nameStream->seek(stringOffsets[nameID], SEEK_CUR);
- c = (char)nameStream->readByte();
-
- while (c) {
- name += c;
- c = (char)nameStream->readByte();
- }
- }
-
- delete nameStream;
- delete[] stringOffsets;
- return name;
-}
-
-int16 MohawkEngine_Riven::getIdFromName(uint16 nameResource, const Common::String &name) {
- //TODO: Use proper data structures
-
- Common::SeekableReadStream *nameStream = getResource(ID_NAME, nameResource);
- uint16 fieldCount = nameStream->readUint16BE();
- uint16 *stringOffsets = new uint16[fieldCount];
-
- for (uint16 i = 0; i < fieldCount; i++)
- stringOffsets[i] = nameStream->readUint16BE();
- for (uint16 i = 0; i < fieldCount; i++)
- nameStream->readUint16BE(); // Skip unknown values
-
- for (uint16 i = 0; i < fieldCount; i++) {
- nameStream->seek(stringOffsets[i], SEEK_CUR);
-
- Common::String readName;
- char c = (char)nameStream->readByte();
- while (c) {
- readName += c;
- c = (char)nameStream->readByte();
- }
-
- if (readName.equalsIgnoreCase(name)) {
- return i;
- }
- }
-
- delete nameStream;
- delete[] stringOffsets;
- return -1;
-}
-
uint16 MohawkEngine_Riven::matchRMAPToCard(uint32 rmapCode) {
uint16 index = 0;
Common::SeekableReadStream *rmapStream = getResource(ID_RMAP, 1);
@@ -911,7 +860,7 @@ void MohawkEngine_Riven::checkSunnerAlertClick() {
}
void MohawkEngine_Riven::addZipVisitedCard(uint16 cardId, uint16 cardNameId) {
- Common::String cardName = getName(CardNames, cardNameId);
+ Common::String cardName = getName(kCardNames, cardNameId);
if (cardName.empty())
return;
ZipMode zip;
@@ -934,6 +883,40 @@ bool MohawkEngine_Riven::isZipVisitedCard(const Common::String &hotspotName) con
return foundMatch;
}
+Common::String MohawkEngine_Riven::getName(uint16 nameResource, uint16 nameID) {
+ switch (nameResource) {
+ case kVariableNames:
+ return _varNames.getName(nameID);
+ case kExternalCommandNames:
+ return _externalCommandNames.getName(nameID);
+ case kStackNames:
+ return _stackNames.getName(nameID);
+ case kCardNames:
+ return _cardNames.getName(nameID);
+ case kHotspotNames:
+ return _hotspotNames.getName(nameID);
+ default:
+ error("Unknown name resource %d", nameResource);
+ }
+}
+
+int16 MohawkEngine_Riven::getIdFromName(uint16 nameResource, const Common::String &name) {
+ switch (nameResource) {
+ case kVariableNames:
+ return _varNames.getNameId(name);
+ case kExternalCommandNames:
+ return _externalCommandNames.getNameId(name);
+ case kStackNames:
+ return _stackNames.getNameId(name);
+ case kCardNames:
+ return _cardNames.getNameId(name);
+ case kHotspotNames:
+ return _hotspotNames.getNameId(name);
+ default:
+ error("Unknown name resource %d", nameResource);
+ }
+}
+
bool ZipMode::operator== (const ZipMode &z) const {
return z.name == name && z.id == id;
}
diff --git a/engines/mohawk/riven.h b/engines/mohawk/riven.h
index 4cff24eb94..53789af3d7 100644
--- a/engines/mohawk/riven.h
+++ b/engines/mohawk/riven.h
@@ -25,6 +25,7 @@
#include "mohawk/installer_archive.h"
#include "mohawk/mohawk.h"
+#include "mohawk/riven_stack.h"
#include "mohawk/riven_scripts.h"
#include "common/hashmap.h"
@@ -63,11 +64,11 @@ enum {
// NAME Resource ID's
enum {
- CardNames = 1,
- HotspotNames = 2,
- ExternalCommandNames = 3,
- VariableNames = 4,
- StackNames = 5
+ kCardNames = 1,
+ kHotspotNames = 2,
+ kExternalCommandNames = 3,
+ kVariableNames = 4,
+ kStackNames = 5
};
enum RivenTransitionSpeed {
@@ -134,6 +135,13 @@ private:
uint16 _curStack;
void handleEvents();
+ // Stack resource names
+ RivenNameList _varNames;
+ RivenNameList _externalCommandNames;
+ RivenNameList _hotspotNames;
+ RivenNameList _cardNames;
+ RivenNameList _stackNames;
+
// Hotspot related functions and variables
void checkInventoryClick();
bool _showHotspots;
diff --git a/engines/mohawk/riven_card.cpp b/engines/mohawk/riven_card.cpp
index b3ec0657a0..39a818c6a9 100644
--- a/engines/mohawk/riven_card.cpp
+++ b/engines/mohawk/riven_card.cpp
@@ -246,7 +246,7 @@ Common::Array<RivenHotspot *> RivenCard::getHotspots() const {
}
RivenHotspot *RivenCard::getHotspotByName(const Common::String &name) const {
- int16 nameId = _vm->getIdFromName(HotspotNames, name);
+ int16 nameId = _vm->getIdFromName(kHotspotNames, name);
for (uint i = 0; i < _hotspots.size(); i++) {
if (_hotspots[i]->getNameId() == nameId) {
@@ -345,7 +345,7 @@ Common::String RivenHotspot::getName() const {
if (_nameResource < 0)
return Common::String();
- return _vm->getName(HotspotNames, _nameResource);
+ return _vm->getName(kHotspotNames, _nameResource);
}
uint16 RivenHotspot::getIndex() const {
diff --git a/engines/mohawk/riven_external.cpp b/engines/mohawk/riven_external.cpp
index 88718db1a6..1be119dc79 100644
--- a/engines/mohawk/riven_external.cpp
+++ b/engines/mohawk/riven_external.cpp
@@ -198,7 +198,7 @@ void RivenExternal::setupCommands() {
}
void RivenExternal::runCommand(uint16 argc, uint16 *argv) {
- Common::String externalCommandName = _vm->getName(ExternalCommandNames, argv[0]);
+ Common::String externalCommandName = _vm->getName(kExternalCommandNames, argv[0]);
for (uint16 i = 0; i < _externalCommands.size(); i++)
if (externalCommandName == _externalCommands[i]->desc) {
diff --git a/engines/mohawk/riven_scripts.cpp b/engines/mohawk/riven_scripts.cpp
index f43c33f7b3..0595c77919 100644
--- a/engines/mohawk/riven_scripts.cpp
+++ b/engines/mohawk/riven_scripts.cpp
@@ -163,9 +163,9 @@ RivenScript::~RivenScript() {
}
}
-void RivenScript::dumpScript(const Common::StringArray &varNames, const Common::StringArray &xNames, byte tabs) {
+void RivenScript::dumpScript(byte tabs) {
for (uint16 i = 0; i < _commands.size(); i++) {
- _commands[i]->dump(varNames, xNames, tabs);
+ _commands[i]->dump(tabs);
}
}
@@ -455,7 +455,7 @@ void RivenSimpleCommand::incrementVariable(uint16 op, uint16 argc, uint16 *argv)
// Command 27: go to stack (stack name, code high, code low)
void RivenSimpleCommand::changeStack(uint16 op, uint16 argc, uint16 *argv) {
- Common::String stackName = _vm->getName(StackNames, argv[0]);
+ Common::String stackName = _vm->getName(kStackNames, argv[0]);
int8 index = -1;
for (byte i = 0; i < 8; i++)
@@ -650,14 +650,15 @@ void RivenSimpleCommand::activateMLST(uint16 op, uint16 argc, uint16 *argv) {
_vm->_video->activateMLST(argv[0], _vm->getCurCard()->getId());
}
-void RivenSimpleCommand::dump(const Common::StringArray &varNames, const Common::StringArray &xNames, byte tabs) {
+void RivenSimpleCommand::dump(byte tabs) {
printTabs(tabs);
if (_type == 7) { // Use the variable name
- uint16 var = _arguments[0];
- debugN("%s = %d;\n", varNames[var].c_str(), _arguments[1]);
+ Common::String varName = _vm->getName(kVariableNames, _arguments[0]);
+ debugN("%s = %d;\n", varName.c_str(), _arguments[1]);
} else if (_type == 17) { // Use the external command name
- debugN("%s(", xNames[_arguments[0]].c_str());
+ Common::String externalCommandName = _vm->getName(kVariableNames, _arguments[0]);
+ debugN("%s(", externalCommandName.c_str());
uint16 varCount = _arguments[1];
for (uint16 j = 0; j < varCount; j++) {
debugN("%d", _arguments[1 + j]);
@@ -666,8 +667,8 @@ void RivenSimpleCommand::dump(const Common::StringArray &varNames, const Common:
}
debugN(");\n");
} else if (_type == 24) { // Use the variable name
- uint16 var = _arguments[0];
- debugN("%s += %d;\n", varNames[var].c_str(), _arguments[1]);
+ Common::String varName = _vm->getName(kVariableNames, _arguments[0]);
+ debugN("%s += %d;\n", varName.c_str(), _arguments[1]);
} else {
debugN("%s(", _opcodes[_type].desc);
for (uint16 j = 0; j < _arguments.size(); j++) {
@@ -727,15 +728,16 @@ RivenSwitchCommand *RivenSwitchCommand::createFromStream(MohawkEngine_Riven *vm,
return command;
}
-void RivenSwitchCommand::dump(const Common::StringArray &varNames, const Common::StringArray &xNames, byte tabs) {
- printTabs(tabs); debugN("switch (%s) {\n", varNames[_variableId].c_str());
+void RivenSwitchCommand::dump(byte tabs) {
+ Common::String varName = _vm->getName(kVariableNames, _variableId);
+ printTabs(tabs); debugN("switch (%s) {\n", varName.c_str());
for (uint16 j = 0; j < _branches.size(); j++) {
printTabs(tabs + 1);
if (_branches[j].value == 0xFFFF)
debugN("default:\n");
else
debugN("case %d:\n", _branches[j].value);
- _branches[j].script->dumpScript(varNames, xNames, tabs + 2);
+ _branches[j].script->dumpScript(tabs + 2);
printTabs(tabs + 2); debugN("break;\n");
}
printTabs(tabs); debugN("}\n");
diff --git a/engines/mohawk/riven_scripts.h b/engines/mohawk/riven_scripts.h
index b05b99ed28..8710026143 100644
--- a/engines/mohawk/riven_scripts.h
+++ b/engines/mohawk/riven_scripts.h
@@ -79,7 +79,7 @@ public:
void run();
/** Print script details to the standard output */
- void dumpScript(const Common::StringArray &varNames, const Common::StringArray &xNames, byte tabs);
+ void dumpScript(byte tabs);
/** Stop the script after the current command */
void stopRunning() { _continueRunning = false; }
@@ -158,7 +158,7 @@ public:
virtual ~RivenCommand();
/** Print details about the command to standard output */
- virtual void dump(const Common::StringArray &varNames, const Common::StringArray &xNames, byte tabs) = 0;
+ virtual void dump(byte tabs) = 0;
/** Execute the command */
virtual void execute() = 0;
@@ -180,7 +180,7 @@ public:
virtual ~RivenSimpleCommand();
// RivenCommand API
- virtual void dump(const Common::StringArray &varNames, const Common::StringArray &xNames, byte tabs) override;
+ virtual void dump(byte tabs) override;
virtual void execute() override;
private:
@@ -253,7 +253,7 @@ public:
virtual ~RivenSwitchCommand();
// RivenCommand API
- virtual void dump(const Common::StringArray &varNames, const Common::StringArray &xNames, byte tabs) override;
+ virtual void dump(byte tabs) override;
virtual void execute() override;
private:
diff --git a/engines/mohawk/riven_stack.cpp b/engines/mohawk/riven_stack.cpp
new file mode 100644
index 0000000000..3ff34e7478
--- /dev/null
+++ b/engines/mohawk/riven_stack.cpp
@@ -0,0 +1,102 @@
+/* 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.
+ *
+ */
+
+#include "mohawk/riven_stack.h"
+
+#include "mohawk/riven.h"
+#include "mohawk/resource.h"
+
+namespace Mohawk {
+
+RivenNameList::RivenNameList() {
+
+}
+
+RivenNameList::RivenNameList(MohawkEngine_Riven *vm, uint16 id) {
+ loadResource(vm, id);
+}
+
+RivenNameList::~RivenNameList() {
+
+}
+
+void RivenNameList::loadResource(MohawkEngine_Riven *vm, uint16 id) {
+ Common::SeekableReadStream *nameStream = vm->getResource(ID_NAME, id);
+
+ uint16 namesCount = nameStream->readUint16BE();
+
+ Common::Array<uint16> stringOffsets;
+ stringOffsets.resize(namesCount);
+ for (uint16 i = 0; i < namesCount; i++) {
+ stringOffsets[i] = nameStream->readUint16BE();
+ }
+
+ _index.resize(namesCount);
+ for (uint16 i = 0; i < namesCount; i++) {
+ _index[i] = nameStream->readUint16BE();
+ }
+
+ int32 curNamesPos = nameStream->pos();
+
+ _names.resize(namesCount);
+ for (uint32 i = 0; i < namesCount; i++) {
+ nameStream->seek(curNamesPos + stringOffsets[i]);
+
+ Common::String name;
+ for (char c = nameStream->readByte(); c; c = nameStream->readByte())
+ name += c;
+
+ _names[i] = name;
+ }
+
+ delete nameStream;
+}
+
+Common::String RivenNameList::getName(uint16 nameID) const {
+ return _names[nameID];
+}
+
+int16 RivenNameList::getNameId(const Common::String &name) const {
+ int low = 0;
+ int high = _index.size() - 1;
+ int midpoint = 0;
+
+ // Binary search using the sorted _index array
+ while (low <= high) {
+ midpoint = low + (high - low) / 2;
+
+ const Common::String &midpointName = _names[_index[midpoint]];
+
+ int comparison = name.compareToIgnoreCase(midpointName);
+ if (comparison == 0) {
+ return _index[midpoint];
+ } else if (comparison < 0) {
+ high = midpoint - 1;
+ } else {
+ low = midpoint + 1;
+ }
+ }
+
+ return -1;
+}
+
+} // End of namespace Mohawk
diff --git a/engines/mohawk/riven_stack.h b/engines/mohawk/riven_stack.h
new file mode 100644
index 0000000000..ca513a15cc
--- /dev/null
+++ b/engines/mohawk/riven_stack.h
@@ -0,0 +1,60 @@
+/* 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 RIVEN_STACK_H
+#define RIVEN_STACK_H
+
+#include "common/str-array.h"
+
+namespace Mohawk {
+
+class MohawkEngine_Riven;
+
+/**
+ * Name lists provide bidirectional association between an object's name and its id
+ */
+class RivenNameList {
+public:
+ RivenNameList();
+ RivenNameList(MohawkEngine_Riven *vm, uint16 id);
+ ~RivenNameList();
+
+ /** Get the name of an object using its id */
+ Common::String getName(uint16 nameID) const;
+
+ /**
+ * Get the id of an object using its name
+ *
+ * This query is case insensitive.
+ */
+ int16 getNameId(const Common::String &name) const;
+
+private:
+ Common::StringArray _names;
+ Common::Array<uint16> _index;
+
+ void loadResource(MohawkEngine_Riven *vm, uint16 id);
+};
+
+} // End of namespace Mohawk
+
+#endif
diff --git a/engines/mohawk/riven_vars.cpp b/engines/mohawk/riven_vars.cpp
index f09aba7f90..c45b464b4d 100644
--- a/engines/mohawk/riven_vars.cpp
+++ b/engines/mohawk/riven_vars.cpp
@@ -268,7 +268,7 @@ static const char *variableNames[] = {
};
uint32 &MohawkEngine_Riven::getStackVar(uint32 index) {
- Common::String name = getName(VariableNames, index);
+ Common::String name = getName(kVariableNames, index);
if (!_vars.contains(name))
error("Could not find variable '%s' (stack variable %d)", name.c_str(), index);