scummvm/engines/mohawk/console.cpp
Matthew Hoops 58139baf37 MOHAWK: Sound cleanup
Merge the Riven sound file code with the main Riven resource code and remove the mainSoundFile parameter from Sound::playSound(). Reasoning: The sound id's do not collide with the sound id's in the main data files. The sound archives only exist because the original CD version had the ability to choose between low and high quality audio.

svn-id: r52631
2010-09-07 20:18:30 +00:00

695 lines
19 KiB
C++

/* 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.
*
* $URL$
* $Id$
*
*/
#include "mohawk/console.h"
#include "mohawk/myst.h"
#include "mohawk/myst_scripts.h"
#include "mohawk/graphics.h"
#include "mohawk/riven.h"
#include "mohawk/riven_external.h"
#include "mohawk/livingbooks.h"
#include "mohawk/sound.h"
#include "mohawk/video.h"
namespace Mohawk {
MystConsole::MystConsole(MohawkEngine_Myst *vm) : GUI::Debugger(), _vm(vm) {
DCmd_Register("changeCard", WRAP_METHOD(MystConsole, Cmd_ChangeCard));
DCmd_Register("curCard", WRAP_METHOD(MystConsole, Cmd_CurCard));
DCmd_Register("var", WRAP_METHOD(MystConsole, Cmd_Var));
DCmd_Register("curStack", WRAP_METHOD(MystConsole, Cmd_CurStack));
DCmd_Register("changeStack", WRAP_METHOD(MystConsole, Cmd_ChangeStack));
DCmd_Register("drawImage", WRAP_METHOD(MystConsole, Cmd_DrawImage));
DCmd_Register("drawRect", WRAP_METHOD(MystConsole, Cmd_DrawRect));
DCmd_Register("setResourceEnable", WRAP_METHOD(MystConsole, Cmd_SetResourceEnable));
DCmd_Register("playSound", WRAP_METHOD(MystConsole, Cmd_PlaySound));
DCmd_Register("stopSound", WRAP_METHOD(MystConsole, Cmd_StopSound));
DCmd_Register("playMovie", WRAP_METHOD(MystConsole, Cmd_PlayMovie));
DCmd_Register("disableInitOpcodes", WRAP_METHOD(MystConsole, Cmd_DisableInitOpcodes));
DCmd_Register("cache", WRAP_METHOD(MystConsole, Cmd_Cache));
}
MystConsole::~MystConsole() {
}
void MystConsole::preEnter() {
_vm->_sound->pauseSound();
}
void MystConsole::postEnter() {
_vm->_sound->resumeSound();
}
bool MystConsole::Cmd_ChangeCard(int argc, const char **argv) {
if (argc < 2) {
DebugPrintf("Usage: changeCard <card>\n");
return true;
}
_vm->_sound->stopSound();
_vm->changeToCard((uint16)atoi(argv[1]));
return false;
}
bool MystConsole::Cmd_CurCard(int argc, const char **argv) {
DebugPrintf("Current Card: %d\n", _vm->getCurCard());
return true;
}
bool MystConsole::Cmd_Var(int argc, const char **argv) {
if (argc == 1) {
DebugPrintf("Usage: var <var> (<value>)\n");
return true;
}
if (argc > 2)
_vm->_varStore->setVar((uint16)atoi(argv[1]), (uint32)atoi(argv[2]));
DebugPrintf("%d = %d\n", (uint16)atoi(argv[1]), _vm->_varStore->getVar((uint16)atoi(argv[1])));
return true;
}
static const char *mystStackNames[12] = {
"Channelwood",
"Credits",
"Demo",
"D'ni",
"Intro",
"MakingOf",
"Mechanical",
"Myst",
"Selenitic",
"Slideshow",
"SneakPreview",
"Stoneship"
};
static const uint16 default_start_card[12] = {
3137,
10000,
2001, // TODO: Should be 2000?
5038,
2, // TODO: Should be 1?
1,
6122,
4134,
1282,
1000,
3000,
2029
};
bool MystConsole::Cmd_CurStack(int argc, const char **argv) {
DebugPrintf("Current Stack: %s\n", mystStackNames[_vm->getCurStack()]);
return true;
}
bool MystConsole::Cmd_ChangeStack(int argc, const char **argv) {
if (argc != 2 && argc != 3) {
DebugPrintf("Usage: changeStack <stack> [<card>]\n\n");
DebugPrintf("Stacks:\n=======\n");
for (byte i = 0; i < ARRAYSIZE(mystStackNames); i++)
DebugPrintf(" %s\n", mystStackNames[i]);
DebugPrintf("\n");
return true;
}
byte stackNum = 0;
for (byte i = 1; i <= ARRAYSIZE(mystStackNames); i++)
if (!scumm_stricmp(argv[1], mystStackNames[i - 1])) {
stackNum = i;
break;
}
if (!stackNum) {
DebugPrintf("\'%s\' is not a stack name!\n", argv[1]);
return true;
}
// We need to stop any playing sound when we change the stack
// as the next card could continue playing it if it.
_vm->_sound->stopSound();
_vm->changeToStack(stackNum - 1);
if (argc == 3)
_vm->changeToCard((uint16)atoi(argv[2]));
else
_vm->changeToCard(default_start_card[stackNum - 1]);
return false;
}
bool MystConsole::Cmd_DrawImage(int argc, const char **argv) {
if (argc != 2 && argc != 6) {
DebugPrintf("Usage: drawImage <image> [<left> <top> <right> <bottom>]\n");
return true;
}
Common::Rect rect;
if (argc == 2)
rect = Common::Rect(0, 0, 544, 333);
else
rect = Common::Rect((uint16)atoi(argv[2]), (uint16)atoi(argv[3]), (uint16)atoi(argv[4]), (uint16)atoi(argv[5]));
_vm->_gfx->copyImageToScreen((uint16)atoi(argv[1]), rect);
return false;
}
bool MystConsole::Cmd_DrawRect(int argc, const char **argv) {
if (argc < 5) {
DebugPrintf("Usage: drawRect <left> <top> <right> <bottom>\n");
return true;
}
_vm->_gfx->drawRect(Common::Rect((uint16)atoi(argv[1]), (uint16)atoi(argv[2]), (uint16)atoi(argv[3]), (uint16)atoi(argv[4])), true);
return false;
}
bool MystConsole::Cmd_SetResourceEnable(int argc, const char **argv) {
if (argc < 3) {
DebugPrintf("Usage: setResourceEnable <resource id> <bool>\n");
return true;
}
_vm->setResourceEnabled((uint16)atoi(argv[1]), atoi(argv[2]) == 1);
return true;
}
bool MystConsole::Cmd_PlaySound(int argc, const char **argv) {
if (argc == 1) {
DebugPrintf("Usage: playSound <value>\n");
return true;
}
_vm->_sound->stopSound();
_vm->_sound->playSound((uint16)atoi(argv[1]));
return false;
}
bool MystConsole::Cmd_StopSound(int argc, const char **argv) {
DebugPrintf("Stopping Sound\n");
_vm->_sound->stopSound();
return true;
}
bool MystConsole::Cmd_PlayMovie(int argc, const char **argv) {
if (argc < 2) {
DebugPrintf("Usage: playMovie <name> [<stack>] [<left> <top>]\n");
DebugPrintf("NOTE: The movie will play *once* in the background.\n");
return true;
}
int8 stackNum = 0;
if (argc == 3 || argc > 4) {
for (byte i = 1; i <= ARRAYSIZE(mystStackNames); i++)
if (!scumm_stricmp(argv[2], mystStackNames[i - 1])) {
stackNum = i;
break;
}
if (!stackNum) {
DebugPrintf("\'%s\' is not a stack name!\n", argv[2]);
return true;
}
}
if (argc == 2)
_vm->_video->playBackgroundMovie(argv[1], 0, 0);
else if (argc == 3)
_vm->_video->playBackgroundMovie(_vm->wrapMovieFilename(argv[1], stackNum - 1), 0, 0);
else if (argc == 4)
_vm->_video->playBackgroundMovie(argv[1], atoi(argv[2]), atoi(argv[3]));
else
_vm->_video->playBackgroundMovie(_vm->wrapMovieFilename(argv[1], stackNum - 1), atoi(argv[3]), atoi(argv[4]));
return false;
}
bool MystConsole::Cmd_DisableInitOpcodes(int argc, const char **argv) {
if (argc != 1) {
DebugPrintf("Usage: disableInitOpcodes\n");
return true;
}
_vm->_scriptParser->disableInitOpcodes();
return true;
}
bool MystConsole::Cmd_Cache(int argc, const char **argv) {
if (argc > 2) {
DebugPrintf("Usage: cache on/off - Omit parameter to get current state\n");
return true;
}
bool state = false;
if (argc == 1) {
state = _vm->getCacheState();
} else {
if (!scumm_stricmp(argv[1], "on"))
state = true;
_vm->setCacheState(state);
}
DebugPrintf("Cache: %s\n", state ? "Enabled" : "Disabled");
return true;
}
RivenConsole::RivenConsole(MohawkEngine_Riven *vm) : GUI::Debugger(), _vm(vm) {
DCmd_Register("changeCard", WRAP_METHOD(RivenConsole, Cmd_ChangeCard));
DCmd_Register("curCard", WRAP_METHOD(RivenConsole, Cmd_CurCard));
DCmd_Register("var", WRAP_METHOD(RivenConsole, Cmd_Var));
DCmd_Register("playSound", WRAP_METHOD(RivenConsole, Cmd_PlaySound));
DCmd_Register("playSLST", WRAP_METHOD(RivenConsole, Cmd_PlaySLST));
DCmd_Register("stopSound", WRAP_METHOD(RivenConsole, Cmd_StopSound));
DCmd_Register("curStack", WRAP_METHOD(RivenConsole, Cmd_CurStack));
DCmd_Register("changeStack", WRAP_METHOD(RivenConsole, Cmd_ChangeStack));
DCmd_Register("restart", WRAP_METHOD(RivenConsole, Cmd_Restart));
DCmd_Register("hotspots", WRAP_METHOD(RivenConsole, Cmd_Hotspots));
DCmd_Register("zipMode", WRAP_METHOD(RivenConsole, Cmd_ZipMode));
DCmd_Register("dumpScript", WRAP_METHOD(RivenConsole, Cmd_DumpScript));
DCmd_Register("listZipCards", WRAP_METHOD(RivenConsole, Cmd_ListZipCards));
DCmd_Register("getRMAP", WRAP_METHOD(RivenConsole, Cmd_GetRMAP));
DCmd_Register("combos", WRAP_METHOD(RivenConsole, Cmd_Combos));
DCmd_Register("sliderState", WRAP_METHOD(RivenConsole, Cmd_SliderState));
}
RivenConsole::~RivenConsole() {
}
void RivenConsole::preEnter() {
_vm->_sound->pauseSound();
_vm->_sound->pauseSLST();
}
void RivenConsole::postEnter() {
_vm->_sound->resumeSound();
_vm->_sound->resumeSLST();
}
bool RivenConsole::Cmd_ChangeCard(int argc, const char **argv) {
if (argc < 2) {
DebugPrintf("Usage: changeCard <card>\n");
return true;
}
_vm->_sound->stopSound();
_vm->_sound->stopAllSLST();
_vm->changeToCard((uint16)atoi(argv[1]));
return false;
}
bool RivenConsole::Cmd_CurCard(int argc, const char **argv) {
DebugPrintf("Current Card: %d\n", _vm->getCurCard());
return true;
}
bool RivenConsole::Cmd_Var(int argc, const char **argv) {
if (argc == 1) {
DebugPrintf("Usage: var <var name> (<value>)\n");
return true;
}
uint32 *globalVar = _vm->getVar(argv[1]);
if (!globalVar) {
DebugPrintf("Unknown variable \'%s\'\n", argv[1]);
return true;
}
if (argc > 2)
*globalVar = (uint32)atoi(argv[2]);
DebugPrintf("%s = %d\n", argv[1], *globalVar);
return true;
}
bool RivenConsole::Cmd_PlaySound(int argc, const char **argv) {
if (argc < 2) {
DebugPrintf("Usage: playSound <value>\n");
return true;
}
_vm->_sound->stopSound();
_vm->_sound->stopAllSLST();
_vm->_sound->playSound((uint16)atoi(argv[1]));
return false;
}
bool RivenConsole::Cmd_PlaySLST(int argc, const char **argv) {
if (argc < 2) {
DebugPrintf("Usage: playSLST <slst index> <card, default = current>\n");
return true;
}
_vm->_sound->stopSound();
_vm->_sound->stopAllSLST();
uint16 card = (argc == 3) ? (uint16)atoi(argv[2]) : _vm->getCurCard();
_vm->_sound->playSLST((uint16)atoi(argv[1]), card);
return false;
}
bool RivenConsole::Cmd_StopSound(int argc, const char **argv) {
DebugPrintf("Stopping Sound\n");
_vm->_sound->stopSound();
_vm->_sound->stopAllSLST();
return true;
}
bool RivenConsole::Cmd_CurStack(int argc, const char **argv) {
DebugPrintf("Current Stack: %s\n", _vm->getStackName(_vm->getCurStack()).c_str());
return true;
}
bool RivenConsole::Cmd_ChangeStack(int argc, const char **argv) {
byte i;
if (argc < 3) {
DebugPrintf("Usage: changeStack <stack> <card>\n\n");
DebugPrintf("Stacks:\n=======\n");
for (i = 0; i <= tspit; i++)
DebugPrintf(" %s\n", _vm->getStackName(i).c_str());
DebugPrintf("\n");
return true;
}
byte stackNum = 0;
for (i = 1; i <= tspit + 1; i++)
if (!scumm_stricmp(argv[1], _vm->getStackName(i - 1).c_str())) {
stackNum = i;
break;
}
if (!stackNum) {
DebugPrintf("\'%s\' is not a stack name!\n", argv[1]);
return true;
}
_vm->changeToStack(stackNum - 1);
_vm->changeToCard((uint16)atoi(argv[2]));
return false;
}
bool RivenConsole::Cmd_Restart(int argc, const char **argv) {
_vm->initVars();
_vm->changeToStack(aspit);
_vm->changeToCard(1);
return false;
}
bool RivenConsole::Cmd_Hotspots(int argc, const char **argv) {
DebugPrintf("Current card (%d) has %d hotspots:\n", _vm->getCurCard(), _vm->getHotspotCount());
for (uint16 i = 0; i < _vm->getHotspotCount(); i++) {
DebugPrintf("Hotspot %d, index %d, BLST ID %d (", i, _vm->_hotspots[i].index, _vm->_hotspots[i].blstID);
if (_vm->_hotspots[i].enabled)
DebugPrintf("enabled");
else
DebugPrintf("disabled");
DebugPrintf(") - (%d, %d, %d, %d)\n", _vm->_hotspots[i].rect.left, _vm->_hotspots[i].rect.top, _vm->_hotspots[i].rect.right, _vm->_hotspots[i].rect.bottom);
DebugPrintf(" Name = %s\n", _vm->getHotspotName(i).c_str());
}
return true;
}
bool RivenConsole::Cmd_ZipMode(int argc, const char **argv) {
uint32 *zipModeActive = _vm->getVar("azip");
*zipModeActive = !(*zipModeActive);
DebugPrintf("Zip Mode is ");
DebugPrintf((*zipModeActive) ? "Enabled" : "Disabled");
DebugPrintf("\n");
return true;
}
bool RivenConsole::Cmd_DumpScript(int argc, const char **argv) {
if (argc < 4) {
DebugPrintf("Usage: dumpScript <stack> <CARD or HSPT> <card>\n");
return true;
}
uint16 oldStack = _vm->getCurStack();
byte newStack = 0;
for (byte i = 1; i <= tspit + 1; i++)
if (!scumm_stricmp(argv[1], _vm->getStackName(i - 1).c_str())) {
newStack = i;
break;
}
if (!newStack) {
DebugPrintf("\'%s\' is not a stack name!\n", argv[1]);
return true;
}
newStack--;
_vm->changeToStack(newStack);
// Load in Variable Names
Common::SeekableReadStream *nameStream = _vm->getRawData(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;
// Load in External Command Names
nameStream = _vm->getRawData(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;
// Get CARD/HSPT data and dump their scripts
if (!scumm_stricmp(argv[2], "CARD")) {
printf ("\n\nDumping scripts for %s\'s card %d!\n", argv[1], (uint16)atoi(argv[3]));
printf ("==================================\n\n");
Common::SeekableReadStream *cardStream = _vm->getRawData(MKID_BE('CARD'), (uint16)atoi(argv[3]));
cardStream->seek(4);
RivenScriptList scriptList = _vm->_scriptMan->readScripts(cardStream, false);
for (uint32 i = 0; i < scriptList.size(); i++) {
scriptList[i]->dumpScript(varNames, xNames, 0);
delete scriptList[i];
}
delete cardStream;
} else if (!scumm_stricmp(argv[2], "HSPT")) {
printf ("\n\nDumping scripts for %s\'s card %d hotspots!\n", argv[1], (uint16)atoi(argv[3]));
printf ("===========================================\n\n");
Common::SeekableReadStream *hsptStream = _vm->getRawData(MKID_BE('HSPT'), (uint16)atoi(argv[3]));
uint16 hotspotCount = hsptStream->readUint16BE();
for (uint16 i = 0; i < hotspotCount; i++) {
printf ("Hotspot %d:\n", i);
hsptStream->seek(22, SEEK_CUR); // Skip non-script related stuff
RivenScriptList scriptList = _vm->_scriptMan->readScripts(hsptStream, false);
for (uint32 j = 0; j < scriptList.size(); j++) {
scriptList[j]->dumpScript(varNames, xNames, 1);
delete scriptList[j];
}
}
delete hsptStream;
} else {
DebugPrintf("%s doesn't have any scripts!\n", argv[2]);
}
printf("\n\n");
_vm->changeToStack(oldStack);
DebugPrintf("Script dump complete.\n");
return true;
}
bool RivenConsole::Cmd_ListZipCards(int argc, const char **argv) {
if (_vm->_zipModeData.size() == 0) {
DebugPrintf("No zip card data.\n");
} else {
DebugPrintf("Listing zip cards:\n");
for (uint32 i = 0; i < _vm->_zipModeData.size(); i++)
DebugPrintf("ID = %d, Name = %s\n", _vm->_zipModeData[i].id, _vm->_zipModeData[i].name.c_str());
}
return true;
}
bool RivenConsole::Cmd_GetRMAP(int argc, const char **argv) {
uint32 rmapCode = _vm->getCurCardRMAP();
DebugPrintf("RMAP for %s %d = %08x\n", _vm->getStackName(_vm->getCurStack()).c_str(), _vm->getCurCard(), rmapCode);
return true;
}
bool RivenConsole::Cmd_Combos(int argc, const char **argv) {
// In the vain of SCUMM's 'drafts' command, this command will list
// out all combinations needed in Riven, decoded from the variables.
// You'll need to look up the Rebel Tunnel puzzle on your own; the
// solution is constant.
uint32 teleCombo = *_vm->getVar("tcorrectorder");
uint32 prisonCombo = *_vm->getVar("pcorrectorder");
uint32 domeCombo = *_vm->getVar("adomecombo");
DebugPrintf("Telescope Combo:\n ");
for (int i = 0; i < 5; i++)
DebugPrintf("%d ", _vm->_externalScriptHandler->getComboDigit(teleCombo, i));
DebugPrintf("\nPrison Combo:\n ");
for (int i = 0; i < 5; i++)
DebugPrintf("%d ", _vm->_externalScriptHandler->getComboDigit(prisonCombo, i));
DebugPrintf("\nDome Combo:\n ");
for (int i = 1; i <= 25; i++)
if (domeCombo & (1 << (25 - i)))
DebugPrintf("%d ", i);
DebugPrintf("\n");
return true;
}
bool RivenConsole::Cmd_SliderState(int argc, const char **argv) {
if (argc > 1)
_vm->_externalScriptHandler->setDomeSliderState((uint32)atoi(argv[1]));
DebugPrintf("Dome Slider State = %08x\n", _vm->_externalScriptHandler->getDomeSliderState());
return true;
}
LivingBooksConsole::LivingBooksConsole(MohawkEngine_LivingBooks *vm) : GUI::Debugger(), _vm(vm) {
DCmd_Register("playSound", WRAP_METHOD(LivingBooksConsole, Cmd_PlaySound));
DCmd_Register("stopSound", WRAP_METHOD(LivingBooksConsole, Cmd_StopSound));
DCmd_Register("drawImage", WRAP_METHOD(LivingBooksConsole, Cmd_DrawImage));
}
LivingBooksConsole::~LivingBooksConsole() {
}
void LivingBooksConsole::preEnter() {
_vm->_sound->pauseSound();
}
void LivingBooksConsole::postEnter() {
_vm->_sound->resumeSound();
}
bool LivingBooksConsole::Cmd_PlaySound(int argc, const char **argv) {
if (argc == 1) {
DebugPrintf("Usage: playSound <value>\n");
return true;
}
_vm->_sound->stopSound();
_vm->_sound->playSound((uint16)atoi(argv[1]));
return false;
}
bool LivingBooksConsole::Cmd_StopSound(int argc, const char **argv) {
DebugPrintf("Stopping Sound\n");
_vm->_sound->stopSound();
return true;
}
bool LivingBooksConsole::Cmd_DrawImage(int argc, const char **argv) {
if (argc == 1) {
DebugPrintf("Usage: drawImage <value>\n");
return true;
}
if (_vm->getGameType() == GType_LIVINGBOOKSV1)
DebugPrintf("This isn't supported in the old Living Books games (yet)!\n");
_vm->_gfx->copyImageToScreen((uint16)atoi(argv[1]));
return _vm->getGameType() != GType_LIVINGBOOKSV1;
}
} // End of namespace Mohawk