/* 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 "m4/m4.h" #include "m4/console.h" #include "m4/dialogs.h" #include "m4/scene.h" #include "m4/staticres.h" namespace M4 { Console::Console(MadsM4Engine *vm) : GUI::Debugger() { _vm = vm; DCmd_Register("scene", WRAP_METHOD(Console, cmdLoadScene)); DCmd_Register("start", WRAP_METHOD(Console, cmdStartingScene)); DCmd_Register("show_hotspots", WRAP_METHOD(Console, cmdShowHotSpots)); DCmd_Register("list_hotspots", WRAP_METHOD(Console, cmdListHotSpots)); DCmd_Register("play_sound", WRAP_METHOD(Console, cmdPlaySound)); DCmd_Register("play_dsr_sound", WRAP_METHOD(Console, cmdPlayDSRSound)); DCmd_Register("show_resources", WRAP_METHOD(Console, cmdShowResources)); DCmd_Register("show_codes", WRAP_METHOD(Console, cmdShowCodes)); DCmd_Register("dump_file", WRAP_METHOD(Console, cmdDumpFile)); DCmd_Register("sprite", WRAP_METHOD(Console, cmdShowSprite)); DCmd_Register("start_conv", WRAP_METHOD(Console, cmdStartConversation)); DCmd_Register("textview", WRAP_METHOD(Console, cmdShowTextview)); DCmd_Register("animview", WRAP_METHOD(Console, cmdShowAnimview)); } 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]); return true; } else { if (_vm->isM4()) _vm->_kernel->newRoom = atoi(argv[1]); else _vm->_scene->loadScene(atoi(argv[1])); return false; } } bool Console::cmdStartingScene(int argc, const char **argv) { if (_vm->getGameType() != GType_Riddle) { if (_vm->isM4()) _vm->_kernel->newRoom = FIRST_SCENE; else _vm->_scene->loadScene(FIRST_SCENE); return false; } else { DebugPrintf("%s: Riddle of Master Lu is not supported", argv[0]); return true; } } bool Console::cmdShowHotSpots(int argc, const char **argv) { _vm->_scene->showHotSpots(); return false; } bool Console::cmdListHotSpots(int argc, const char **argv) { DebugPrintf("Scene hotspots\n"); _vm->_scene->getSceneResources().hotspots->dump(); if (_vm->isM4()) { DebugPrintf("Scene parallax\n"); _m4Vm->scene()->getSceneResources().parallax->dump(); DebugPrintf("Scene dynamic hotspots\n"); _vm->_scene->getSceneResources().dynamicHotspots->dump(); } return true; } bool Console::cmdPlaySound(int argc, const char **argv) { if (argc != 2) { DebugPrintf("Usage: %s \n", argv[0]); } else { _vm->_sound->playSound(argv[1], 255, false); } return true; } bool Console::cmdPlayDSRSound(int argc, const char **argv) { if (argc != 2 && argc != 3) { DebugPrintf("Usage: %s \n", argv[0]); DebugPrintf("The DSR file parameter is optional, and specifies which DSR to load\n", argv[0]); } else { if (argc == 3) _vm->_sound->loadDSRFile(argv[2]); _vm->_sound->playDSRSound(atoi(argv[1]), 255, false); } return true; } bool Console::cmdShowResources(int argc, const char **argv) { _vm->res()->dump(); return true; } bool Console::cmdShowCodes(int argc, const char **argv) { _vm->_scene->showCodes(); return false; } bool Console::cmdDumpFile(int argc, const char **argv) { if (argc != 2 && argc != 3) { DebugPrintf("Usage: %s \n", argv[0]); DebugPrintf("If uncompress is 1, the file is uncompressed (for MADS games)\n"); } else { if (argc == 2) { _vm->dumpFile(strdup(argv[1])); } else { if (argc == 3 && atoi(argv[2]) == 1) _vm->dumpFile(strdup(argv[1]), true); else _vm->dumpFile(strdup(argv[1])); } } return true; } bool Console::cmdShowSprite(int argc, const char **argv) { View *view = _vm->_viewManager->getView(VIEWID_SCENE); if (view == NULL) DebugPrintf("The scene view isn't currently active\n"); else if (argc < 2) DebugPrintf("Usage: %s resource_name\n", argv[0]); else { char resourceName[20]; strncpy(resourceName, argv[1], 15); resourceName[15] = '\0'; if (!strchr(resourceName, '.')) strcat(resourceName, ".SS"); _vm->_viewManager->moveToFront(view); Common::SeekableReadStream *data = _vm->res()->get(resourceName); SpriteAsset *asset = new SpriteAsset(_vm, data, data->size(), resourceName); _vm->res()->toss(resourceName); RGBList *palData = new RGBList(asset->getColorCount(), asset->getPalette(), true); _vm->_palette->addRange(palData); // Get the scene background surface M4Surface *bg = _vm->_scene->getBackgroundSurface(); // Write the sprite onto the screen int x = 0, y = 0, yMax = 0; for (int index = 0; index < asset->getCount(); index++) { M4Sprite *spr = asset->getFrame(index); spr->translate(palData); // sprite pixel translation if ((x + spr->width() >= bg->width()) && (yMax != 0)) { x = 0; y += yMax; yMax = 0; } if (y >= bg->height()) break; spr->copyTo(bg, x, y, (int)spr->getTransparencyIndex()); x += spr->width(); yMax = MAX(yMax, spr->height()); } view->restore(0, 0, view->width(), view->height()); return false; } return true; } bool Console::cmdStartConversation(int argc, const char **argv) { if (argc != 2) { DebugPrintf("Usage: %s \n", argv[0]); return true; } else if (_vm->isM4()) { ((M4Engine *)_vm)->_converse->startConversation(argv[1]); return false; } else { error("MADS engine does not support conversations yet"); return false; } } bool Console::cmdShowTextview(int argc, const char **argv) { if (argc != 2) { DebugPrintf("Usage: %s \n", argv[0]); return true; } _vm->_viewManager->showTextView(argv[1], false); return false; } bool Console::cmdShowAnimview(int argc, const char **argv) { if (argc != 2) { DebugPrintf("Usage: %s \n", argv[0]); return true; } char resName[80]; strcpy(resName, "@"); strcat(resName, *argv[1] == '@' ? argv[1] + 1 : argv[1]); _vm->_viewManager->showAnimView(resName, false); return false; } /*--------------------------------------------------------------------------*/ MadsConsole::MadsConsole(MadsEngine *vm): Console(vm) { _vm = vm; DCmd_Register("object", WRAP_METHOD(MadsConsole, cmdObject)); DCmd_Register("message", WRAP_METHOD(MadsConsole, cmdMessage)); DCmd_Register("scene_info", WRAP_METHOD(MadsConsole, cmdSceneInfo)); DCmd_Register("anim", WRAP_METHOD(MadsConsole, cmdPlayAnimation)); } bool MadsConsole::cmdObject(int argc, const char **argv) { if (argc == 1) { DebugPrintf("Usage: object ['list' | '#objnum' | 'add #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; DebugPrintf("%s", _vm->globals()->getVocab(descId)); } DebugPrintf("\n"); } DebugPrintf("\n"); } else if (!strcmp(argv[1], "add") && (argc == 3)) { // Add the specified object to the player's inventory int objNum = strToInt(argv[2]); if ((objNum < 0) || (objNum >= (int)_vm->globals()->getObjectsSize())) DebugPrintf("Invalid object specified\n"); else if (_vm->isM4()) DebugPrintf("Not implemented for M4 games\n"); else { _vm->_scene->getInterface()->addObjectToInventory(objNum); return false; } } else { // Print the details of a specific object int objNum = strToInt(argv[1]); if ((objNum < 0) || (objNum >= (int)_vm->globals()->getObjectsSize())) DebugPrintf("Invalid object specified\n"); else { const MadsObject *obj = _vm->globals()->getObject(objNum); DebugPrintf("Object #%d (%s) room=%d article=%d/%s vocabs=%d", objNum, _vm->globals()->getVocab(obj->descId), obj->roomNumber, (int)obj->article, englishMADSArticleList[obj->article], obj->vocabCount); if (obj->vocabCount > 0) { DebugPrintf(" - "); for (int i = 0; i < obj->vocabCount; ++i) { if (i != 0) DebugPrintf(", "); DebugPrintf("%s (%d)/%d,%d", _vm->globals()->getVocab(obj->vocabList[i].vocabId), obj->vocabList[i].vocabId, obj->vocabList[i].flags1, obj->vocabList[i].flags2); } } DebugPrintf("\n"); } } return true; } bool MadsConsole::cmdMessage(int argc, const char **argv) { if (argc == 1) { DebugPrintf("message 'objnum'\n"); } else if (!strcmp(argv[1], "list_quotes")) { // Dump the quotes list FILE *destFile = fopen("mads_quotes.txt", "wb"); for (uint i = 0; i < _vm->globals()->getQuotesSize(); ++i) fprintf(destFile, "%.3d - %s\n", i, _vm->globals()->getQuote(i)); fclose(destFile); } else if (!strcmp(argv[1], "list_vocab")) { // Dump the vocab list FILE *destFile = fopen("mads_vocab.txt", "wb"); for (uint i = 1; i <= _vm->globals()->getVocabSize(); ++i) fprintf(destFile, "%.3d/%.3x - %s\n", i, i, _vm->globals()->getVocab(i)); fclose(destFile); } else { int messageIdx = strToInt(argv[1]); if ((argc != 3) || (strcmp(argv[2], "idx") != 0)) messageIdx = _vm->globals()->messageIndexOf(messageIdx); const char *msg = _vm->globals()->loadMessage(messageIdx); if (!msg) DebugPrintf("Unknown message\n"); else { Dialog *dlg = new Dialog(_vm, msg, "TEST DIALOG"); _vm->_viewManager->addView(dlg); _vm->_viewManager->moveToFront(dlg); return false; } } return true; } bool MadsConsole::cmdSceneInfo(int argc, const char **argv) { DebugPrintf("Current scene is: %i\n", _vm->_scene->getCurrentScene()); return true; } bool MadsConsole::cmdPlayAnimation(int argc, const char **argv) { View *view = _vm->_viewManager->getView(VIEWID_SCENE); if (view == NULL) { DebugPrintf("The scene view isn't currently active\n"); } else if (argc != 2 && argc != 3) { DebugPrintf("Usage: %s \n", argv[0]); DebugPrintf("If fullscreen is 1, the screen palette is replaced with the palette of the animation\n"); } else { char resourceName[20]; strncpy(resourceName, argv[1], 15); resourceName[15] = '\0'; if (!strchr(resourceName, '.')) strcat(resourceName, ".AA"); _vm->_viewManager->moveToFront(view); if (argc == 3 && atoi(argv[2]) == 1) _madsVm->_palette->deleteAllRanges(); _madsVm->scene()->_sceneAnimation->load(resourceName, 0); view->restore(0, 0, view->width(), view->height()); return false; } return true; } /*--------------------------------------------------------------------------*/ M4Console::M4Console(M4Engine *vm): Console(vm) { _vm = vm; DCmd_Register("scene_info", WRAP_METHOD(M4Console, cmdSceneInfo)); } bool M4Console::cmdSceneInfo(int argc, const char **argv) { DebugPrintf("Current scene is: %i\n", _m4Vm->scene()->getCurrentScene()); DebugPrintf("Scene resources:\n"); DebugPrintf("artBase: %s\n", _m4Vm->scene()->getSceneResources().artBase); DebugPrintf("pictureBase: %s\n", _m4Vm->scene()->getSceneResources().pictureBase); DebugPrintf("hotspotCount: %i\n", _m4Vm->scene()->getSceneResources().hotspots->size()); DebugPrintf("parallaxCount: %i\n", _m4Vm->scene()->getSceneResources().parallaxCount); DebugPrintf("dynHotspotCount: %i\n", _m4Vm->scene()->getSceneResources().dynamicHotspots->size()); DebugPrintf("frontY: %i\n", _m4Vm->scene()->getSceneResources().frontY); DebugPrintf("backY: %i\n", _m4Vm->scene()->getSceneResources().backY); DebugPrintf("frontScale: %i\n", _m4Vm->scene()->getSceneResources().frontScale); DebugPrintf("backScale: %i\n", _m4Vm->scene()->getSceneResources().backScale); DebugPrintf("depthTable: "); for (uint i = 0; i < 16; i++) DebugPrintf("%i ", _m4Vm->scene()->getSceneResources().depthTable[i]); DebugPrintf("\n"); DebugPrintf("railNodeCount: %i\n", _m4Vm->scene()->getSceneResources().railNodeCount); return true; } } // End of namespace M4