diff options
Diffstat (limited to 'engines/sci/console.cpp')
-rw-r--r-- | engines/sci/console.cpp | 171 |
1 files changed, 103 insertions, 68 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index 540b7c84d8..2549be9403 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -47,6 +47,7 @@ #include "sci/graphics/cursor.h" #include "sci/graphics/screen.h" #include "sci/graphics/paint.h" +#include "sci/graphics/paint16.h" #include "sci/graphics/palette.h" #include "sci/parser/vocabulary.h" @@ -74,10 +75,10 @@ Console::Console(SciEngine *engine) : GUI::Debugger() { // Variables DVar_Register("sleeptime_factor", &g_debug_sleeptime_factor, DVAR_INT, 0); - DVar_Register("gc_interval", &script_gc_interval, DVAR_INT, 0); + DVar_Register("gc_interval", &engine->_gamestate->script_gc_interval, DVAR_INT, 0); DVar_Register("simulated_key", &g_debug_simulated_key, DVAR_INT, 0); DVar_Register("track_mouse_clicks", &g_debug_track_mouse_clicks, DVAR_BOOL, 0); - DVar_Register("script_abort_flag", &script_abort_flag, DVAR_INT, 0); + DVar_Register("script_abort_flag", &_engine->_gamestate->script_abort_flag, DVAR_INT, 0); // General DCmd_Register("help", WRAP_METHOD(Console, cmdHelp)); @@ -104,6 +105,7 @@ Console::Console(SciEngine *engine) : GUI::Debugger() { DCmd_Register("resource_types", WRAP_METHOD(Console, cmdResourceTypes)); DCmd_Register("list", WRAP_METHOD(Console, cmdList)); DCmd_Register("hexgrep", WRAP_METHOD(Console, cmdHexgrep)); + DCmd_Register("verify_scripts", WRAP_METHOD(Console, cmdVerifyScripts)); // Game DCmd_Register("save_game", WRAP_METHOD(Console, cmdSaveGame)); DCmd_Register("restore_game", WRAP_METHOD(Console, cmdRestoreGame)); @@ -276,8 +278,8 @@ void Console::postEnter() { #if 0 // Unused #define LOOKUP_SPECIES(species) (\ - (species >= 1000) ? species : *(s->_classtable[species].scriptposp) \ - + s->_classtable[species].class_offset) + (species >= 1000) ? species : *(s->_classTable[species].scriptposp) \ + + s->_classTable[species].class_offset) #endif bool Console::cmdHelp(int argc, const char **argv) { @@ -323,6 +325,7 @@ bool Console::cmdHelp(int argc, const char **argv) { DebugPrintf(" resource_types - Shows the valid resource types\n"); DebugPrintf(" list - Lists all the resources of a given type\n"); DebugPrintf(" hexgrep - Searches some resources for a particular sequence of bytes, represented as hexadecimal numbers\n"); + DebugPrintf(" verify_scripts - Performs sanity checks on SCI1.1-SCI2.1 game scripts (e.g. if they're up to 64KB in total)\n"); DebugPrintf("\n"); DebugPrintf("Game:\n"); DebugPrintf(" save_game - Saves the current game state to the hard disk\n"); @@ -421,10 +424,9 @@ const char *selector_name(EngineState *s, int selector) { bool Console::cmdGetVersion(int argc, const char **argv) { const char *viewTypeDesc[] = { "Unknown", "EGA", "VGA", "VGA SCI1.1", "Amiga" }; - EngineState *s = _engine->_gamestate; bool hasVocab997 = g_sci->getResMan()->testResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SELECTORS)) ? true : false; - DebugPrintf("Game ID: %s\n", s->_gameId.c_str()); + DebugPrintf("Game ID: %s\n", _engine->getGameID()); DebugPrintf("Emulated interpreter version: %s\n", getSciVersionDesc(getSciVersion())); DebugPrintf("\n"); DebugPrintf("Detected features:\n"); @@ -593,14 +595,14 @@ bool Console::cmdSetParseNodes(int argc, const char **argv) { } bool Console::cmdRegisters(int argc, const char **argv) { + EngineState *s = _engine->_gamestate; DebugPrintf("Current register values:\n"); - DebugPrintf("acc=%04x:%04x prev=%04x:%04x &rest=%x\n", PRINT_REG(_engine->_gamestate->r_acc), PRINT_REG(_engine->_gamestate->r_prev), scriptState.restAdjust); + DebugPrintf("acc=%04x:%04x prev=%04x:%04x &rest=%x\n", PRINT_REG(s->r_acc), PRINT_REG(s->r_prev), s->restAdjust); - if (!_engine->_gamestate->_executionStack.empty()) { - EngineState *s = _engine->_gamestate; // for PRINT_STK + if (!s->_executionStack.empty()) { DebugPrintf("pc=%04x:%04x obj=%04x:%04x fp=ST:%04x sp=ST:%04x\n", - PRINT_REG(scriptState.xs->addr.pc), PRINT_REG(scriptState.xs->objp), - (unsigned)(scriptState.xs->fp - s->stack_base), (unsigned)(scriptState.xs->sp - s->stack_base)); + PRINT_REG(s->xs->addr.pc), PRINT_REG(s->xs->objp), + (unsigned)(s->xs->fp - s->stack_base), (unsigned)(s->xs->sp - s->stack_base)); } else DebugPrintf("<no execution stack: pc,obj,fp omitted>\n"); @@ -811,6 +813,40 @@ bool Console::cmdHexgrep(int argc, const char **argv) { return true; } +bool Console::cmdVerifyScripts(int argc, const char **argv) { + if (getSciVersion() < SCI_VERSION_1_1) { + DebugPrintf("This script check is only meant for SCI1.1-SCI2.1 games\n"); + return true; + } + + Common::List<ResourceId> *resources = _engine->getResMan()->listResources(kResourceTypeScript); + sort(resources->begin(), resources->end(), ResourceIdLess()); + Common::List<ResourceId>::iterator itr = resources->begin(); + + DebugPrintf("%d SCI1.1-SCI2.1 scripts found, performing sanity checks...\n", resources->size()); + + Resource *script, *heap; + while (itr != resources->end()) { + script = _engine->getResMan()->findResource(*itr, false); + if (!script) + DebugPrintf("Error: script %d couldn't be loaded\n", itr->number); + + heap = _engine->getResMan()->findResource(*itr, false); + if (!heap) + DebugPrintf("Error: script %d doesn't have a corresponding heap\n", itr->number); + + if (script && heap && (script->size + heap->size > 65535)) + DebugPrintf("Error: script and heap %d together are larger than 64KB (%d bytes)\n", + itr->number, script->size + heap->size); + + ++itr; + } + + DebugPrintf("SCI1.1-SCI2.1 script check finished\n"); + + return true; +} + bool Console::cmdList(int argc, const char **argv) { if (argc < 2) { DebugPrintf("Lists all the resources of a given type\n"); @@ -921,35 +957,19 @@ bool Console::cmdRestoreGame(int argc, const char **argv) { } bool Console::cmdRestartGame(int argc, const char **argv) { - if (argc != 2) { - DebugPrintf("Restarts the game. There are two ways to restart a SCI game:\n"); - DebugPrintf("%s play - calls the game object's play() method\n", argv[0]); - DebugPrintf("%s replay - calls the replay() methody\n", argv[0]); - return true; - } - - if (!scumm_stricmp(argv[1], "play")) { - _engine->_gamestate->restarting_flags |= SCI_GAME_WAS_RESTARTED_AT_LEAST_ONCE; - } else if (!scumm_stricmp(argv[1], "replay")) { - _engine->_gamestate->restarting_flags &= ~SCI_GAME_WAS_RESTARTED_AT_LEAST_ONCE; - } else { - DebugPrintf("Invalid usage of %s\n", argv[0]); - return true; - } - _engine->_gamestate->restarting_flags |= SCI_GAME_IS_RESTARTING_NOW; - script_abort_flag = 1; + _engine->_gamestate->script_abort_flag = 1; return false; } bool Console::cmdClassTable(int argc, const char **argv) { DebugPrintf("Available classes:\n"); - for (uint i = 0; i < _engine->_gamestate->_segMan->_classtable.size(); i++) { - if (_engine->_gamestate->_segMan->_classtable[i].reg.segment) { + for (uint i = 0; i < _engine->_gamestate->_segMan->classTableSize(); i++) { + if (_engine->_gamestate->_segMan->_classTable[i].reg.segment) { DebugPrintf(" Class 0x%x at %04x:%04x (script 0x%x)\n", i, - PRINT_REG(_engine->_gamestate->_segMan->_classtable[i].reg), - _engine->_gamestate->_segMan->_classtable[i].script); + PRINT_REG(_engine->_gamestate->_segMan->_classTable[i].reg), + _engine->_gamestate->_segMan->_classTable[i].script); } } @@ -1129,7 +1149,11 @@ bool Console::cmdUndither(int argc, const char **argv) { bool flag = atoi(argv[1]) ? true : false; _engine->_gfxScreen->debugUnditherSetState(flag); - return false; + if (flag) + DebugPrintf("undithering ENABLED\n"); + else + DebugPrintf("undithering DISABLED\n"); + return true; } bool Console::cmdPicVisualize(int argc, const char **argv) { @@ -1141,7 +1165,16 @@ bool Console::cmdPicVisualize(int argc, const char **argv) { bool state = atoi(argv[1]) ? true : false; - return _engine->_gui->debugEGAdrawingVisualize(state); + if (_engine->_resMan->getViewType() == kViewEga) { + _engine->_gfxPaint16->debugSetEGAdrawingVisualize(state); + if (state) + DebugPrintf("picture visualization ENABLED\n"); + else + DebugPrintf("picture visualization DISABLED\n"); + } else { + DebugPrintf("picture visualization only available for EGA games\n"); + } + return true; } bool Console::cmdPlayVideo(int argc, const char **argv) { @@ -1248,13 +1281,13 @@ bool Console::segmentInfo(int nr) { case SEG_TYPE_SCRIPT: { Script *scr = (Script *)mobj; - DebugPrintf("script.%03d locked by %d, bufsize=%d (%x)\n", scr->_nr, scr->getLockers(), (uint)scr->_bufSize, (uint)scr->_bufSize); - if (scr->_exportTable) - DebugPrintf(" Exports: %4d at %d\n", scr->_numExports, (int)(((byte *)scr->_exportTable) - ((byte *)scr->_buf))); + DebugPrintf("script.%03d locked by %d, bufsize=%d (%x)\n", scr->_nr, scr->getLockers(), (uint)scr->getBufSize(), (uint)scr->getBufSize()); + if (scr->getExportTable()) + DebugPrintf(" Exports: %4d at %d\n", scr->getExportsNr(), (int)(((const byte *)scr->getExportTable()) - ((const byte *)scr->_buf))); else DebugPrintf(" Exports: none\n"); - DebugPrintf(" Synonyms: %4d\n", scr->_numSynonyms); + DebugPrintf(" Synonyms: %4d\n", scr->getSynonymsNr()); if (scr->_localsBlock) DebugPrintf(" Locals : %4d in segment 0x%x\n", scr->_localsBlock->_locals.size(), scr->_localsSegment); @@ -1268,7 +1301,7 @@ bool Console::segmentInfo(int nr) { for (it = scr->_objects.begin(); it != end; ++it) { DebugPrintf(" "); // Object header - Object *obj = _engine->_gamestate->_segMan->getObject(it->_value.getPos()); + const Object *obj = _engine->_gamestate->_segMan->getObject(it->_value.getPos()); if (obj) DebugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(it->_value.getPos()), _engine->_gamestate->_segMan->getObjectName(it->_value.getPos()), @@ -1315,7 +1348,7 @@ bool Console::segmentInfo(int nr) { objpos.segment = nr; DebugPrintf(" [%04x] %s; copy of ", i, _engine->_gamestate->_segMan->getObjectName(objpos)); // Object header - Object *obj = _engine->_gamestate->_segMan->getObject(ct->_table[i].getPos()); + const Object *obj = _engine->_gamestate->_segMan->getObject(ct->_table[i].getPos()); if (obj) DebugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(ct->_table[i].getPos()), _engine->_gamestate->_segMan->getObjectName(ct->_table[i].getPos()), @@ -1523,12 +1556,12 @@ bool Console::cmdToggleSound(int argc, const char **argv) { int handle = id.segment << 16 | id.offset; // frobnicate handle if (id.segment) { - SegManager *segMan = _engine->_gamestate->_segMan; // for PUT_SEL32V + SegManager *segMan = _engine->_gamestate->_segMan; // for writeSelectorValue _engine->_gamestate->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED); _engine->_gamestate->_sound.sfx_remove_song(handle); - PUT_SEL32V(segMan, id, SELECTOR(signal), SIGNAL_OFFSET); - PUT_SEL32V(segMan, id, SELECTOR(nodePtr), 0); - PUT_SEL32V(segMan, id, SELECTOR(handle), 0); + writeSelectorValue(segMan, id, SELECTOR(signal), SIGNAL_OFFSET); + writeSelectorValue(segMan, id, SELECTOR(nodePtr), 0); + writeSelectorValue(segMan, id, SELECTOR(handle), 0); } #else @@ -1733,14 +1766,15 @@ bool Console::cmdGCNormalize(int argc, const char **argv) { } bool Console::cmdVMVarlist(int argc, const char **argv) { + EngineState *s = _engine->_gamestate; const char *varnames[] = {"global", "local", "temp", "param"}; DebugPrintf("Addresses of variables in the VM:\n"); for (int i = 0; i < 4; i++) { - DebugPrintf("%s vars at %04x:%04x ", varnames[i], PRINT_REG(make_reg(scriptState.variables_seg[i], scriptState.variables[i] - scriptState.variables_base[i]))); - if (scriptState.variables_max) - DebugPrintf(" total %d", scriptState.variables_max[i]); + DebugPrintf("%s vars at %04x:%04x ", varnames[i], PRINT_REG(make_reg(s->variables_seg[i], s->variables[i] - s->variables_base[i]))); + if (s->variables_max) + DebugPrintf(" total %d", s->variables_max[i]); DebugPrintf("\n"); } @@ -1758,6 +1792,7 @@ bool Console::cmdVMVars(int argc, const char **argv) { return true; } + EngineState *s = _engine->_gamestate; const char *varnames[] = {"global", "local", "temp", "param"}; const char *varabbrev = "gltp"; const char *vartype_pre = strchr(varabbrev, *argv[1]); @@ -1796,17 +1831,17 @@ bool Console::cmdVMVars(int argc, const char **argv) { return true; } - if ((scriptState.variables_max) && (scriptState.variables_max[vartype] <= idx)) { - DebugPrintf("Max. index is %d (0x%x)\n", scriptState.variables_max[vartype], scriptState.variables_max[vartype]); + if ((s->variables_max) && (s->variables_max[vartype] <= idx)) { + DebugPrintf("Max. index is %d (0x%x)\n", s->variables_max[vartype], s->variables_max[vartype]); return true; } switch (argc) { case 3: - DebugPrintf("%s var %d == %04x:%04x\n", varnames[vartype], idx, PRINT_REG(scriptState.variables[vartype][idx])); + DebugPrintf("%s var %d == %04x:%04x\n", varnames[vartype], idx, PRINT_REG(s->variables[vartype][idx])); break; case 4: - if (parse_reg_t(_engine->_gamestate, argv[3], &scriptState.variables[vartype][idx], true)) { + if (parse_reg_t(_engine->_gamestate, argv[3], &s->variables[vartype][idx], true)) { DebugPrintf("Invalid value/address passed.\n"); DebugPrintf("Check the \"addresses\" command on how to use addresses\n"); DebugPrintf("Or pass a decimal or hexadecimal value directly (e.g. 12, 1Ah)\n"); @@ -2039,7 +2074,7 @@ bool Console::cmdViewObject(int argc, const char **argv) { bool Console::cmdViewActiveObject(int argc, const char **argv) { DebugPrintf("Information on the currently active object or class:\n"); - printObject(scriptState.xs->objp); + printObject(_engine->_gamestate->xs->objp); return true; } @@ -2052,7 +2087,7 @@ bool Console::cmdViewAccumulatorObject(int argc, const char **argv) { } bool Console::cmdScriptSteps(int argc, const char **argv) { - DebugPrintf("Number of executed SCI operations: %d\n", script_step_counter); + DebugPrintf("Number of executed SCI operations: %d\n", _engine->_gamestate->script_step_counter); return true; } @@ -2229,8 +2264,8 @@ bool Console::cmdDisassemble(int argc, const char **argv) { return true; } - Object *obj = _engine->_gamestate->_segMan->getObject(objAddr); - int selector_id = _engine->getKernel()->findSelector(argv[2]); + const Object *obj = _engine->_gamestate->_segMan->getObject(objAddr); + int selectorId = _engine->getKernel()->findSelector(argv[2]); reg_t addr; if (!obj) { @@ -2238,12 +2273,12 @@ bool Console::cmdDisassemble(int argc, const char **argv) { return true; } - if (selector_id < 0) { + if (selectorId < 0) { DebugPrintf("Not a valid selector name."); return true; } - if (lookup_selector(_engine->_gamestate->_segMan, objAddr, selector_id, NULL, &addr) != kSelectorMethod) { + if (lookupSelector(_engine->_gamestate->_segMan, objAddr, selectorId, NULL, &addr) != kSelectorMethod) { DebugPrintf("Not a method."); return true; } @@ -2323,20 +2358,20 @@ bool Console::cmdSend(int argc, const char **argv) { } const char *selector_name = argv[2]; - int selector_id = _engine->getKernel()->findSelector(selector_name); + int selectorId = _engine->getKernel()->findSelector(selector_name); - if (selector_id < 0) { + if (selectorId < 0) { DebugPrintf("Unknown selector: \"%s\"\n", selector_name); return true; } - Object *o = _engine->_gamestate->_segMan->getObject(object); + const Object *o = _engine->_gamestate->_segMan->getObject(object); if (o == NULL) { DebugPrintf("Address \"%04x:%04x\" is not an object\n", PRINT_REG(object)); return true; } - SelectorType selector_type = lookup_selector(_engine->_gamestate->_segMan, object, selector_id, 0, 0); + SelectorType selector_type = lookupSelector(_engine->_gamestate->_segMan, object, selectorId, 0, 0); if (selector_type == kSelectorNone) { DebugPrintf("Object does not support selector: \"%s\"\n", selector_name); @@ -2349,7 +2384,7 @@ bool Console::cmdSend(int argc, const char **argv) { // Create the data block for send_selecor() at the top of the stack: // [selector_number][argument_counter][arguments...] StackPtr stackframe = _engine->_gamestate->_executionStack.back().sp; - stackframe[0] = make_reg(0, selector_id); + stackframe[0] = make_reg(0, selectorId); stackframe[1] = make_reg(0, send_argc); for (int i = 0; i < send_argc; i++) { if (parse_reg_t(_engine->_gamestate, argv[3+i], &stackframe[2+i], false)) { @@ -2696,7 +2731,7 @@ bool Console::cmdQuit(int argc, const char **argv) { if (!scumm_stricmp(argv[1], "game")) { // Quit gracefully - script_abort_flag = 1; // Terminate VM + _engine->_gamestate->script_abort_flag = 1; // Terminate VM g_debugState.seeking = kDebugSeekNothing; g_debugState.runningStep = 0; @@ -3021,8 +3056,8 @@ int Console::printNode(reg_t addr) { int Console::printObject(reg_t pos) { EngineState *s = _engine->_gamestate; // for the several defines in this function - Object *obj = s->_segMan->getObject(pos); - Object *var_container = obj; + const Object *obj = s->_segMan->getObject(pos); + const Object *var_container = obj; uint i; if (!obj) { @@ -3034,7 +3069,7 @@ int Console::printObject(reg_t pos) { DebugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(pos), s->_segMan->getObjectName(pos), obj->getVarCount(), obj->getMethodCount()); - if (!(obj->getInfoSelector().offset & SCRIPT_INFO_CLASS)) + if (!obj->isClass()) var_container = s->_segMan->getObject(obj->getSuperClassSelector()); DebugPrintf(" -- member variables:\n"); for (i = 0; (uint)i < obj->getVarCount(); i++) { @@ -3051,7 +3086,7 @@ int Console::printObject(reg_t pos) { if (!val.segment) DebugPrintf(" (%d)", val.offset); - Object *ref = s->_segMan->getObject(val); + const Object *ref = s->_segMan->getObject(val); if (ref) DebugPrintf(" (%s)", s->_segMan->getObjectName(val)); @@ -3063,7 +3098,7 @@ int Console::printObject(reg_t pos) { DebugPrintf(" [%03x] %s = %04x:%04x\n", obj->getFuncSelector(i), selector_name(s, obj->getFuncSelector(i)), PRINT_REG(fptr)); } if (s->_segMan->_heap[pos.segment]->getType() == SEG_TYPE_SCRIPT) - DebugPrintf("\nOwner script:\t%d\n", s->_segMan->getScript(pos.segment)->_nr); + DebugPrintf("\nOwner script: %d\n", s->_segMan->getScript(pos.segment)->_nr); return 0; } |