aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/console.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/console.cpp')
-rw-r--r--engines/sci/console.cpp131
1 files changed, 90 insertions, 41 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index d77ac858c8..60bd129efc 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -40,12 +40,16 @@
#include "sci/sound/music.h"
#include "sci/sound/drivers/mididriver.h"
#include "sci/sound/drivers/map-mt32-to-gm.h"
+#include "sci/graphics/animate.h"
+#include "sci/graphics/cache.h"
#include "sci/graphics/cursor.h"
#include "sci/graphics/screen.h"
#include "sci/graphics/paint.h"
#include "sci/graphics/paint16.h"
#include "sci/graphics/paint32.h"
#include "sci/graphics/palette.h"
+#include "sci/graphics/ports.h"
+#include "sci/graphics/view.h"
#include "sci/parser/vocabulary.h"
@@ -123,6 +127,10 @@ Console::Console(SciEngine *engine) : GUI::Debugger(),
DCmd_Register("undither", WRAP_METHOD(Console, cmdUndither));
DCmd_Register("pic_visualize", WRAP_METHOD(Console, cmdPicVisualize));
DCmd_Register("play_video", WRAP_METHOD(Console, cmdPlayVideo));
+ DCmd_Register("animate_list", WRAP_METHOD(Console, cmdAnimateList));
+ DCmd_Register("al", WRAP_METHOD(Console, cmdAnimateList)); // alias
+ DCmd_Register("window_list", WRAP_METHOD(Console, cmdWindowList));
+ DCmd_Register("wl", WRAP_METHOD(Console, cmdWindowList)); // alias
// Segments
DCmd_Register("segment_table", WRAP_METHOD(Console, cmdPrintSegmentTable));
DCmd_Register("segtable", WRAP_METHOD(Console, cmdPrintSegmentTable)); // alias
@@ -354,6 +362,8 @@ bool Console::cmdHelp(int argc, const char **argv) {
DebugPrintf(" draw_cel - Draws a cel from a view resource\n");
DebugPrintf(" pic_visualize - Enables visualization of the drawing process of EGA pictures\n");
DebugPrintf(" undither - Enable/disable undithering\n");
+ DebugPrintf(" play_video - Plays a SEQ, AVI, VMD, RBT or DUK video\n");
+ DebugPrintf(" animate_object_list / al - Shows the current list of objects in kAnimate's draw list\n");
DebugPrintf("\n");
DebugPrintf("Segments:\n");
DebugPrintf(" segment_table / segtable - Lists all segments\n");
@@ -432,7 +442,7 @@ ResourceType parseResourceType(const char *resid) {
}
bool Console::cmdGetVersion(int argc, const char **argv) {
- const char *viewTypeDesc[] = { "Unknown", "EGA", "VGA", "VGA SCI1.1", "Amiga" };
+ const char *viewTypeDesc[] = { "Unknown", "EGA", "Amiga ECS 32 colors", "Amiga AGA 64 colors", "VGA", "VGA SCI1.1" };
bool hasVocab997 = g_sci->getResMan()->testResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SELECTORS)) ? true : false;
Common::String gameVersion = "N/A";
@@ -623,7 +633,7 @@ 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(s->r_acc), PRINT_REG(s->r_prev), s->restAdjust);
+ DebugPrintf("acc=%04x:%04x prev=%04x:%04x &rest=%x\n", PRINT_REG(s->r_acc), PRINT_REG(s->r_prev), s->r_rest);
if (!s->_executionStack.empty()) {
DebugPrintf("pc=%04x:%04x obj=%04x:%04x fp=ST:%04x sp=ST:%04x\n",
@@ -1434,7 +1444,7 @@ bool Console::cmdSaid(int argc, const char **argv) {
_engine->getVocabulary()->dumpParseTree();
_engine->getVocabulary()->parserIsValid = true;
- int ret = said(_engine->_gamestate, (byte*)spec, true);
+ int ret = said((byte*)spec, true);
DebugPrintf("kSaid: %s\n", (ret == SAID_NO_MATCH ? "No match" : "Match"));
}
@@ -1503,7 +1513,14 @@ bool Console::cmdDrawCel(int argc, const char **argv) {
uint16 loopNo = atoi(argv[2]);
uint16 celNo = atoi(argv[3]);
- _engine->_gfxPaint->kernelDrawCel(resourceId, loopNo, celNo, 50, 50, 0, 0, false, NULL_REG);
+ if (_engine->_gfxPaint16) {
+ _engine->_gfxPaint16->kernelDrawCel(resourceId, loopNo, celNo, 50, 50, 0, 0, 128, 128, false, NULL_REG);
+ } else {
+ GfxView *view = _engine->_gfxCache->getView(resourceId);
+ Common::Rect celRect(50, 50, 50 + view->getWidth(loopNo, celNo), 50 + view->getHeight(loopNo, celNo));
+ view->draw(celRect, celRect, celRect, loopNo, celNo, 255, 0, false);
+ _engine->_gfxScreen->copyRectToScreen(celRect);
+ }
return true;
}
@@ -1567,6 +1584,22 @@ bool Console::cmdPlayVideo(int argc, const char **argv) {
}
}
+bool Console::cmdAnimateList(int argc, const char **argv) {
+ if (_engine->_gfxAnimate) {
+ DebugPrintf("Animate list:\n");
+ _engine->_gfxAnimate->printAnimateList(this);
+ }
+ return true;
+}
+
+bool Console::cmdWindowList(int argc, const char **argv) {
+ if (_engine->_gfxPorts) {
+ DebugPrintf("Window list:\n");
+ _engine->_gfxPorts->printWindowList(this);
+ }
+ return true;
+
+}
bool Console::cmdParseGrammar(int argc, const char **argv) {
DebugPrintf("Parse grammar, in strict GNF:\n");
@@ -1701,9 +1734,7 @@ bool Console::segmentInfo(int nr) {
for (uint i = 0; i < ct->_table.size(); i++)
if (ct->isValidEntry(i)) {
- reg_t objpos;
- objpos.offset = i;
- objpos.segment = nr;
+ reg_t objpos = make_reg(nr, i);
DebugPrintf(" [%04x] %s; copy of ", i, _engine->_gamestate->_segMan->getObjectName(objpos));
// Object header
const Object *obj = _engine->_gamestate->_segMan->getObject(ct->_table[i].getPos());
@@ -2189,7 +2220,7 @@ bool Console::cmdStack(int argc, const char **argv) {
return true;
}
- ExecStack &xs = _engine->_gamestate->_executionStack.back();
+ const ExecStack &xs = _engine->_gamestate->_executionStack.back();
int nr = atoi(argv[1]);
for (int i = nr; i > 0; i--) {
@@ -2438,12 +2469,12 @@ bool Console::cmdScriptSteps(int argc, const char **argv) {
bool Console::cmdBacktrace(int argc, const char **argv) {
DebugPrintf("Call stack (current base: 0x%x):\n", _engine->_gamestate->executionStackBase);
- Common::List<ExecStack>::iterator iter;
+ Common::List<ExecStack>::const_iterator iter;
uint i = 0;
for (iter = _engine->_gamestate->_executionStack.begin();
iter != _engine->_gamestate->_executionStack.end(); ++iter, ++i) {
- ExecStack &call = *iter;
+ const ExecStack &call = *iter;
const char *objname = _engine->_gamestate->_segMan->getObjectName(call.sendp);
int paramc, totalparamc;
@@ -2607,7 +2638,7 @@ bool Console::cmdDisassemble(int argc, const char **argv) {
const Object *obj = _engine->_gamestate->_segMan->getObject(objAddr);
int selectorId = _engine->getKernel()->findSelector(argv[2]);
- reg_t addr;
+ reg_t addr = NULL_REG;
if (!obj) {
DebugPrintf("Not an object.");
@@ -2626,13 +2657,22 @@ bool Console::cmdDisassemble(int argc, const char **argv) {
for (int i = 3; i < argc; i++) {
if (!scumm_stricmp(argv[i], "bwt"))
- printBytecode = true;
- else if (!scumm_stricmp(argv[i], "bc"))
printBWTag = true;
+ else if (!scumm_stricmp(argv[i], "bc"))
+ printBytecode = true;
}
+ reg_t farthestTarget = addr;
do {
+ reg_t prevAddr = addr;
+ reg_t jumpTarget;
+ if (isJumpOpcode(_engine->_gamestate, addr, jumpTarget)) {
+ if (jumpTarget > farthestTarget)
+ farthestTarget = jumpTarget;
+ }
addr = disassemble(_engine->_gamestate, addr, printBWTag, printBytecode);
+ if (addr.isNull() && prevAddr < farthestTarget)
+ addr = prevAddr + 1; // skip past the ret
} while (addr.offset > 0);
return true;
@@ -2699,26 +2739,30 @@ void Console::printKernelCallsFound(int kernelFuncNum, bool showFoundScripts) {
int scriptSegment;
Script *script;
- SegManager *segMan = _engine->getEngineState()->_segMan;
+ // Create a custom segment manager here, so that the game's segment
+ // manager won't be affected by loading and unloading scripts here.
+ SegManager *customSegMan = new SegManager(_engine->getResMan());
while (itr != resources->end()) {
- if (_engine->getGameId() == GID_KQ5 && itr->getNumber() == 980) {
- // Ignore script 980 in KQ5. Seems to be a leftover, as it
- // uses a superclass from script 988, which doesn't exist
+ // Ignore specific leftover scripts, which require other non-existing scripts
+ if ((_engine->getGameId() == GID_HOYLE3 && itr->getNumber() == 995) ||
+ (_engine->getGameId() == GID_KQ5 && itr->getNumber() == 980) ||
+ (_engine->getGameId() == GID_SLATER && itr->getNumber() == 947) ||
+ (_engine->getGameId() == GID_MOTHERGOOSE256 && itr->getNumber() == 980)) {
itr++;
continue;
}
// Load script
- scriptSegment = segMan->instantiateScript(itr->getNumber());
- script = segMan->getScript(scriptSegment);
+ scriptSegment = customSegMan->instantiateScript(itr->getNumber());
+ script = customSegMan->getScript(scriptSegment);
// Iterate through all the script's objects
ObjMap::iterator it;
const ObjMap::iterator end = script->_objects.end();
for (it = script->_objects.begin(); it != end; ++it) {
- const Object *obj = segMan->getObject(it->_value.getPos());
- const char *objName = segMan->getObjectName(it->_value.getPos());
+ const Object *obj = customSegMan->getObject(it->_value.getPos());
+ const char *objName = customSegMan->getObjectName(it->_value.getPos());
// Now dissassemble each method of the script object
for (uint16 i = 0; i < obj->getMethodCount(); i++) {
@@ -2761,10 +2805,12 @@ void Console::printKernelCallsFound(int kernelFuncNum, bool showFoundScripts) {
} // for (uint16 i = 0; i < obj->getMethodCount(); i++)
} // for (it = script->_objects.begin(); it != end; ++it)
- segMan->uninstantiateScript(itr->getNumber());
+ customSegMan->uninstantiateScript(itr->getNumber());
++itr;
}
+ delete customSegMan;
+
delete resources;
}
@@ -3108,10 +3154,9 @@ bool Console::cmdBreakpointKernel(int argc, const char **argv) {
}
bool Console::cmdBreakpointFunction(int argc, const char **argv) {
- // TODO/FIXME: Why does this accept 2 parameters (the high and the low part of the address)?"
if (argc != 3) {
DebugPrintf("Sets a breakpoint on the execution of the specified exported function.\n");
- DebugPrintf("Usage: %s <addr1> <addr2>\n", argv[0]);
+ DebugPrintf("Usage: %s <script number> <export number\n", argv[0]);
return true;
}
@@ -3120,6 +3165,7 @@ bool Console::cmdBreakpointFunction(int argc, const char **argv) {
A breakpoint set on an invalid method name will just never trigger. */
Breakpoint bp;
bp.type = BREAK_EXPORT;
+ // script number, export number
bp.address = (atoi(argv[1]) << 16 | atoi(argv[2]));
_debugState._breakpoints.push_back(bp);
@@ -3758,11 +3804,16 @@ int Console::printObject(reg_t pos) {
return 0;
}
+static void printChar(byte c) {
+ if (c < 32 || c >= 127)
+ c = '.';
+ debugN("%c", c);
+}
+
void Console::hexDumpReg(const reg_t *data, int len, int regsPerLine, int startOffset, bool isArray) {
// reg_t version of Common::hexdump
assert(1 <= regsPerLine && regsPerLine <= 8);
int i;
- byte c;
int offset = startOffset;
while (len >= regsPerLine) {
debugN("%06x: ", offset);
@@ -3771,14 +3822,13 @@ void Console::hexDumpReg(const reg_t *data, int len, int regsPerLine, int startO
}
debugN(" |");
for (i = 0; i < regsPerLine; i++) {
- c = data[i].toUint16() & 0xff;
- if (c < 32 || c >= 127)
- c = '.';
- debugN("%c", c);
- c = data[i].toUint16() >> 8;
- if (c < 32 || c >= 127)
- c = '.';
- debugN("%c", c);
+ if (g_sci->isBE()) {
+ printChar(data[i].toUint16() >> 8);
+ printChar(data[i].toUint16() & 0xff);
+ } else {
+ printChar(data[i].toUint16() & 0xff);
+ printChar(data[i].toUint16() >> 8);
+ }
}
debugN("|\n");
data += regsPerLine;
@@ -3798,14 +3848,13 @@ void Console::hexDumpReg(const reg_t *data, int len, int regsPerLine, int startO
}
debugN(" |");
for (i = 0; i < len; i++) {
- c = data[i].toUint16() & 0xff;
- if (c < 32 || c >= 127)
- c = '.';
- debugN("%c", c);
- c = data[i].toUint16() >> 8;
- if (c < 32 || c >= 127)
- c = '.';
- debugN("%c", c);
+ if (g_sci->isBE()) {
+ printChar(data[i].toUint16() >> 8);
+ printChar(data[i].toUint16() & 0xff);
+ } else {
+ printChar(data[i].toUint16() & 0xff);
+ printChar(data[i].toUint16() >> 8);
+ }
}
for (; i < regsPerLine; i++)
debugN(" ");