From 61a0266a926208bd45e1c378f6062921b03f8724 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Mon, 1 May 2006 16:04:53 +0000 Subject: More stubs; GOB2 goes in-game for a second, then segfaults in the Global-constructor; valgrind shows invalid reads in parseValExpr() and parseExpr() while accessing _inter_variables and _inter_execPtr svn-id: r22262 --- engines/gob/game_v2.cpp | 3 +-- engines/gob/inter.h | 5 +++++ engines/gob/inter_v1.cpp | 6 +++--- engines/gob/inter_v2.cpp | 51 +++++++++++++++++++++++++++++++++++++++-------- engines/gob/mult.h | 3 +++ engines/gob/mult_v1.cpp | 4 ++++ engines/gob/mult_v2.cpp | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ engines/gob/parse.cpp | 3 +++ engines/gob/parse_v2.cpp | 2 ++ 9 files changed, 116 insertions(+), 13 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/game_v2.cpp b/engines/gob/game_v2.cpp index 8c9819efb8..8da4a92e03 100644 --- a/engines/gob/game_v2.cpp +++ b/engines/gob/game_v2.cpp @@ -181,8 +181,7 @@ void Game_v2::playTot(int16 skipPlay) { if (_vm->_global->_inter_variables == 0) { variablesCount = READ_LE_UINT32((char *)_totFileData + 0x2c); _vm->_global->_inter_variables = new char[variablesCount * 4]; - for (i = 0; i < variablesCount; i++) - WRITE_VAR(i, 0); + memset(_vm->_global->_inter_variables, 0, variablesCount * 4); } _vm->_global->_inter_execPtr = (char *)_totFileData; diff --git a/engines/gob/inter.h b/engines/gob/inter.h index d62cc33aef..a5e95ac5a0 100644 --- a/engines/gob/inter.h +++ b/engines/gob/inter.h @@ -310,6 +310,9 @@ protected: void o2_drawStub(void) { warning("Gob2 stub"); } void o2_totSub(void); + void o2_stub0x52(void); + void o2_stub0x53(void); + void o2_stub0x54(void); void o2_stub0x56(void); void o2_stub0x80(void); void o2_renderStatic(void); @@ -318,6 +321,7 @@ protected: bool o2_loadTot(char &cmdCount, int16 &counter, int16 &retFlag); bool o2_freeSprite(char &cmdCount, int16 &counter, int16 &retFlag); bool o2_loadSound(char &cmdCount, int16 &counter, int16 &retFlag); + void o2_multSub(void); void o2_setRenderFlags(void); void o2_initMult(void); void o2_loadCurLayer(void); @@ -328,6 +332,7 @@ protected: void o2_getCDTrackPos(void); void o2_playMult(void); void o2_initCursor(void); + void o2_setPickable(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); }; } // End of namespace Gob diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp index 0bfad6575e..59785fc46e 100644 --- a/engines/gob/inter_v1.cpp +++ b/engines/gob/inter_v1.cpp @@ -1647,7 +1647,7 @@ void Inter_v1::o1_freeFontToSprite(void) { } void Inter_v1::executeDrawOpcode(byte i) { - debugC(1, DEBUG_DRAWOP, "opcodeDraw %d (%s)", i, getOpcodeDrawDesc(i)); + debugC(1, DEBUG_DRAWOP, "opcodeDraw %d [0x%x] (%s)", i, i, getOpcodeDrawDesc(i)); OpcodeDrawProcV1 op = _opcodesDrawV1[i].proc; @@ -1658,7 +1658,7 @@ void Inter_v1::executeDrawOpcode(byte i) { } bool Inter_v1::executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, int16 &retFlag) { - debugC(1, DEBUG_FUNCOP, "opcodeFunc %d.%d (%s)", i, j, getOpcodeFuncDesc(i, j)); + debugC(1, DEBUG_FUNCOP, "opcodeFunc %d.%d [0x%x.0x%x] (%s)", i, j, i, j, getOpcodeFuncDesc(i, j)); if ((i > 4) || (j > 15)) { warning("unimplemented opcodeFunc: %d.%d", i, j); @@ -1675,7 +1675,7 @@ bool Inter_v1::executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, } void Inter_v1::executeGoblinOpcode(int i, int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - debugC(1, DEBUG_GOBOP, "opcodeGoblin %d (%s)", i, getOpcodeGoblinDesc(i)); + debugC(1, DEBUG_GOBOP, "opcodeGoblin %d [0x%x] (%s)", i, i, getOpcodeGoblinDesc(i)); OpcodeGoblinProcV1 op = NULL; diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp index 93529a2257..4879b8006a 100644 --- a/engines/gob/inter_v2.cpp +++ b/engines/gob/inter_v2.cpp @@ -146,7 +146,7 @@ void Inter_v2::setupOpcodes(void) { OPCODE(o1_loadAnim), OPCODE(o1_freeAnim), OPCODE(o1_updateAnim), - OPCODE(o2_drawStub), + OPCODE(o2_multSub), /* 14 */ OPCODE(o2_initMult), OPCODE(o1_multFreeMult), @@ -225,10 +225,10 @@ void Inter_v2::setupOpcodes(void) { /* 50 */ OPCODE(o2_drawStub), OPCODE(o2_drawStub), - OPCODE(o2_drawStub), - OPCODE(o2_drawStub), + OPCODE(o2_stub0x52), + OPCODE(o2_stub0x53), /* 54 */ - OPCODE(o2_drawStub), + OPCODE(o2_stub0x54), OPCODE(o2_drawStub), OPCODE(o2_stub0x56), {NULL, ""}, @@ -560,7 +560,7 @@ void Inter_v2::setupOpcodes(void) { OPCODE(o1_setType), /* 08 */ OPCODE(o1_setNoTick), - OPCODE(o1_setPickable), + OPCODE(o2_setPickable), OPCODE(o1_setXPos), OPCODE(o1_setYPos), /* 0C */ @@ -645,7 +645,7 @@ void Inter_v2::setupOpcodes(void) { } void Inter_v2::executeDrawOpcode(byte i) { - debugC(1, DEBUG_DRAWOP, "opcodeDraw %d (%s)", i, getOpcodeDrawDesc(i)); + debugC(1, DEBUG_DRAWOP, "opcodeDraw %d [0x%x] (%s)", i, i, getOpcodeDrawDesc(i)); OpcodeDrawProcV2 op = _opcodesDrawV2[i].proc; @@ -656,7 +656,7 @@ void Inter_v2::executeDrawOpcode(byte i) { } bool Inter_v2::executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, int16 &retFlag) { - debugC(1, DEBUG_FUNCOP, "opcodeFunc %d.%d (%s)", i, j, getOpcodeFuncDesc(i, j)); + debugC(1, DEBUG_FUNCOP, "opcodeFunc %d.%d [0x%x.0x%x] (%s)", i, j, i, j, getOpcodeFuncDesc(i, j)); if ((i > 4) || (j > 15)) { warning("unimplemented opcodeFunc: %d.%d", i, j); @@ -673,7 +673,7 @@ bool Inter_v2::executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, } void Inter_v2::executeGoblinOpcode(int i, int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - debugC(1, DEBUG_GOBOP, "opcodeGoblin %d (%s)", i, getOpcodeGoblinDesc(i)); + debugC(1, DEBUG_GOBOP, "opcodeGoblin %d [0x%x] (%s)", i, i, getOpcodeGoblinDesc(i)); OpcodeGoblinProcV2 op = NULL; @@ -710,6 +710,33 @@ const char *Inter_v2::getOpcodeGoblinDesc(int i) { return ""; } +void Inter_v2::o2_stub0x52(void) { + int16 expr1 = _vm->_parse->parseValExpr(); + int16 expr2 = _vm->_parse->parseValExpr(); + int16 expr3 = _vm->_parse->parseValExpr(); + + warning("STUB: Gob2 drawOperation 0x52 (%d %d %d)", expr1, expr2, expr3); +} + +void Inter_v2::o2_stub0x53(void) { + int16 var1 = _vm->_parse->parseVarIndex() >> 2; + int16 var2 = _vm->_parse->parseVarIndex() >> 2; + int16 index = _vm->_parse->parseValExpr(); + + warning("STUB: Gob2 drawOperation 0x53 (%d %d %d)", var1, var2, index); + +// WRITE_VAR(var1, _vm->_mult->_objects[index].field_1A); +// WRITE_VAR(var2, _vm->_mult->_objects[index].field_1B); +} + +void Inter_v2::o2_stub0x54(void) { + int16 index = _vm->_parse->parseValExpr(); + + warning("STUB: Gob2 drawOperation 0x54 (%d)", index); + +// _vm->_mult->_objects[index].pAnimData->field_12 = 4; +} + void Inter_v2::o2_stub0x56(void) { int16 expr1 = _vm->_parse->parseValExpr(); int16 expr2 = _vm->_parse->parseValExpr(); @@ -942,6 +969,10 @@ int16 Inter_v2::loadSound(int16 search) { _vm->_game->loadSound(slot, dataPtr);*/ } +void Inter_v2::o2_multSub(void) { + _vm->_mult->multSub(_vm->_parse->parseValExpr()); +} + void Inter_v2::o2_renderStatic(void) { int16 layer; int16 index; @@ -1522,4 +1553,8 @@ void Inter_v2::storeMouse(void) { WRITE_VAR(4, _vm->_game->_mouseButtons); } +void Inter_v2::o2_setPickable(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { + warning("GOB2 Stub! o2_setPickable"); +} + } // End of namespace Gob diff --git a/engines/gob/mult.h b/engines/gob/mult.h index 14df0d01c6..65b3a02238 100644 --- a/engines/gob/mult.h +++ b/engines/gob/mult.h @@ -196,6 +196,7 @@ public: void initAll(void); virtual void setMultData(uint16 multindex) = 0; + virtual void multSub(uint16 multindex) = 0; virtual void loadMult(int16 resId) = 0; virtual void playMult(int16 startFrame, int16 endFrame, char checkEscape, char handleMouse) = 0; @@ -226,6 +227,7 @@ public: virtual ~Mult_v1() {}; virtual void setMultData(uint16 multindex); + virtual void multSub(uint16 multindex); virtual void loadMult(int16 resId); virtual void playMult(int16 startFrame, int16 endFrame, char checkEscape, char handleMouse); @@ -307,6 +309,7 @@ public: virtual ~Mult_v2() {}; virtual void setMultData(uint16 multindex); + virtual void multSub(uint16 multindex); virtual void loadMult(int16 resId); virtual void playMult(int16 startFrame, int16 endFrame, char checkEscape, char handleMouse); diff --git a/engines/gob/mult_v1.cpp b/engines/gob/mult_v1.cpp index 2d1669afa5..37ede23366 100644 --- a/engines/gob/mult_v1.cpp +++ b/engines/gob/mult_v1.cpp @@ -207,6 +207,10 @@ void Mult_v1::setMultData(uint16 multindex) { error("Switching mults not supported for Gob1"); } +void Mult_v1::multSub(uint16 multindex) { + error("Switching mults not supported for Gob1"); +} + void Mult_v1::playMult(int16 startFrame, int16 endFrame, char checkEscape, char handleMouse) { char stopNoClear; diff --git a/engines/gob/mult_v2.cpp b/engines/gob/mult_v2.cpp index 050b26b2bc..09ddef4b43 100644 --- a/engines/gob/mult_v2.cpp +++ b/engines/gob/mult_v2.cpp @@ -33,6 +33,7 @@ #include "gob/anim.h" #include "gob/draw.h" #include "gob/palanim.h" +#include "gob/parse.h" namespace Gob { @@ -276,6 +277,57 @@ void Mult_v2::setMultData(uint16 multindex) { _multData2 = _multDatas[multindex]; } +void Mult_v2::multSub(uint16 multindex) { + uint16 flags; + int16 expr; + int i; + int16 di; + + flags = multindex; + multindex = (multindex >> 12) & 0xF; + + if (multindex > 7) + error("Multindex out of range"); + + debugC(4, DEBUG_GAMEFLOW, "Sub mult %d", multindex); + _multData2 = _multDatas[multindex]; + + if (_multData2 == 0) { + _vm->_parse->parseValExpr(); + _vm->_parse->parseValExpr(); + _vm->_parse->parseValExpr(); + _vm->_parse->parseValExpr(); + return; + } + + if (flags & 0x200) + di = 3; + else if (flags & 0x100) + di = 2; + else if (flags & 0x80) + di = 1; + else + di = 0; + + if (flags & 0x400) { + flags = 0x400; + _multData2->field_156 = -1; + } else { + _multData2->field_156 = 1; + flags &= 0x7F; + } + + _multData2->field_124[di][0] = flags; + for (i = 1; i < 4; i++) { + _multData2->field_124[di][i] = _vm->_parse->parseValExpr(); + } + expr = _vm->_parse->parseValExpr(); + _multData2->animKeysIndices1[di] = expr; + _multData2->animKeysIndices2[di] = expr; + // loc_5D0E + warning("GOB2 Stub! Mult_v2::multSub()"); +} + void Mult_v2::playMult(int16 startFrame, int16 endFrame, char checkEscape, char handleMouse) { char stopNoClear; diff --git a/engines/gob/parse.cpp b/engines/gob/parse.cpp index d8373cf58f..01e8d007c1 100644 --- a/engines/gob/parse.cpp +++ b/engines/gob/parse.cpp @@ -160,6 +160,9 @@ void Parse::printExpr(char stopToken) { char saved = 0; static char *savedPos = 0; + // TODO: There seems to be a problem here, GOB2 runs into an endless loop + return; + if (savedPos == 0) { savedPos = _vm->_global->_inter_execPtr; saved = 1; diff --git a/engines/gob/parse_v2.cpp b/engines/gob/parse_v2.cpp index dce5c37995..63aaadb8e4 100644 --- a/engines/gob/parse_v2.cpp +++ b/engines/gob/parse_v2.cpp @@ -365,6 +365,8 @@ int16 Parse_v2::parseExpr(char stopToken, byte *arg_2) { int16 stkPos; int16 brackStart; + memset(operStack, 0, 20); + stkPos = -1; operPtr = (char *)(operStack - 1); valPtr = values - 1; -- cgit v1.2.3