diff options
-rw-r--r-- | engines/gob/draw.cpp | 18 | ||||
-rw-r--r-- | engines/gob/draw.h | 4 | ||||
-rw-r--r-- | engines/gob/draw_v2.cpp | 8 | ||||
-rw-r--r-- | engines/gob/game_v2.cpp | 89 | ||||
-rw-r--r-- | engines/gob/init_v2.cpp | 7 | ||||
-rw-r--r-- | engines/gob/inter.cpp | 54 | ||||
-rw-r--r-- | engines/gob/inter.h | 4 | ||||
-rw-r--r-- | engines/gob/inter_bargon.cpp | 6 | ||||
-rw-r--r-- | engines/gob/inter_v1.cpp | 179 | ||||
-rw-r--r-- | engines/gob/inter_v2.cpp | 160 | ||||
-rw-r--r-- | engines/gob/mult_v2.cpp | 6 | ||||
-rw-r--r-- | engines/gob/util.cpp | 5 | ||||
-rw-r--r-- | engines/gob/util.h | 2 | ||||
-rw-r--r-- | engines/gob/video.cpp | 6 | ||||
-rw-r--r-- | engines/gob/video.h | 4 | ||||
-rw-r--r-- | engines/gob/video_v2.cpp | 9 |
16 files changed, 325 insertions, 236 deletions
diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp index b4dd65ef6f..d1d19d0179 100644 --- a/engines/gob/draw.cpp +++ b/engines/gob/draw.cpp @@ -129,10 +129,11 @@ Draw::Draw(GobEngine *vm) : _vm(vm) { _cursorTimeKey = 0; - warning("GOB2 Stub! _word_2E8E2, _word_2FC9C, _word_2FC9E, _word_2E51F, _off_2E51B, _off_2E517"); + _scrollOffsetX = 0; + _scrollOffsetY = 0; + + warning("GOB2 Stub! _word_2E8E2, _word_2E51F, _off_2E51B, _off_2E517"); _word_2E8E2 = 2; - _word_2FC9C = 0; - _word_2FC9E = 0; _word_2E51F = 0; _off_2E51B = 0; _off_2E517 = 0; @@ -157,7 +158,8 @@ void Draw::invalidateRect(int16 left, int16 top, int16 right, int16 bottom) { bottom = temp; } - if (left > (_vm->_video->_surfWidth - 1) || right < 0 || top > 199 || bottom < 0) + if ((left > (_vm->_video->_surfWidth - 1)) || (right < 0) || + (top > (_vm->_video->_surfHeight - 1)) || (bottom < 0)) return; _noInvalidated = 0; @@ -166,7 +168,7 @@ void Draw::invalidateRect(int16 left, int16 top, int16 right, int16 bottom) { _invalidatedLefts[0] = 0; _invalidatedTops[0] = 0; _invalidatedRights[0] = _vm->_video->_surfWidth - 1; - _invalidatedBottoms[0] = 199; + _invalidatedBottoms[0] = _vm->_video->_surfHeight - 1; _invalidatedCount = 1; return; } @@ -180,8 +182,8 @@ void Draw::invalidateRect(int16 left, int16 top, int16 right, int16 bottom) { if (top < 0) top = 0; - if (bottom > 199) - bottom = 199; + if (bottom > (_vm->_video->_surfHeight - 1)) + bottom = _vm->_video->_surfHeight - 1; left &= 0xfff0; right |= 0x000f; @@ -266,7 +268,7 @@ void Draw::blitInvalidated(void) { clearPalette(); _vm->_video->drawSprite(_backSurface, _frontSurface, 0, 0, - _vm->_video->_surfWidth - 1, 199, 0, 0, 0); + _vm->_video->_surfWidth - 1, _vm->_video->_surfHeight - 1, 0, 0, 0); setPalette(); _invalidatedCount = 0; _noInvalidated = 1; diff --git a/engines/gob/draw.h b/engines/gob/draw.h index 07a53bc073..8859b93088 100644 --- a/engines/gob/draw.h +++ b/engines/gob/draw.h @@ -114,8 +114,8 @@ public: int16 _palLoadData2[4]; int16 _word_2E8E2; - int16 _word_2FC9C; - int16 _word_2FC9E; + int16 _scrollOffsetY; + int16 _scrollOffsetX; int16 _word_2E51F; Video::SurfaceDesc *_off_2E51B; Video::SurfaceDesc *_off_2E517; diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp index 86998c1436..77e95921b7 100644 --- a/engines/gob/draw_v2.cpp +++ b/engines/gob/draw_v2.cpp @@ -957,8 +957,8 @@ void Draw_v2::animateCursor(int16 cursor) { } void Draw_v2::initScreen(void) { - _word_2FC9C = 0; - _word_2FC9E = 0; + _scrollOffsetX = 0; + _scrollOffsetY = 0; if (_word_2E51F != 0) { _off_2E51B = new Video::SurfaceDesc; @@ -974,7 +974,7 @@ void Draw_v2::initScreen(void) { _off_2E517->vidPtr = _frontSurface->vidPtr + ((_frontSurface->width * _frontSurface->height ) / 4); } - initBigSprite(21, _vm->_video->_surfWidth, 200, 0); + initBigSprite(21, _vm->_video->_surfWidth, _vm->_video->_surfHeight, 0); _backSurface = _spritesArray[21]; _vm->_video->clearSurf(_backSurface); @@ -1002,7 +1002,7 @@ void Draw_v2::closeScreen(void) { if (_off_2E51B != 0) { memcpy(_frontSurface, _off_2E51B, sizeof(Video::SurfaceDesc)); _frontSurface->width = _vm->_video->_surfWidth; - _frontSurface->height = 200; + _frontSurface->height = _vm->_video->_surfHeight; delete _off_2E51B; delete _off_2E517; _off_2E51B = 0; diff --git a/engines/gob/game_v2.cpp b/engines/gob/game_v2.cpp index 1b6cd1f123..c85482fb6c 100644 --- a/engines/gob/game_v2.cpp +++ b/engines/gob/game_v2.cpp @@ -452,15 +452,15 @@ int16 Game_v2::checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, &_mouseButtons, handleMouse); // TODO: What of this is needed? - // Scrolling? + // Mouse position calculation in scrollable screen? int16 width; int16 height; int16 sWidth; int16 sHeight; int16 cursorRight; int16 cursorBottom; - int16 oldWord_2FC9C; - int16 oldWord_2FC9E; + int16 oldOffY; + int16 oldOffX; if ((_vm->_global->_videoMode == 0x14) && (handleMouse != 0)) { width = _vm->_draw->_frontSurface->width; height = _vm->_draw->_frontSurface->height; @@ -470,64 +470,65 @@ int16 Game_v2::checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, sHeight = _vm->_global->_primaryHeight; if (_vm->_draw->_off_2E51B != 0) sHeight -= _vm->_draw->_off_2E51B->height; - oldWord_2FC9E = _vm->_draw->_word_2FC9E; - oldWord_2FC9C = _vm->_draw->_word_2FC9C; - if ((width > sWidth) && (_vm->_global->_inter_mouseX >= _vm->_draw->_word_2FC9E)) { + oldOffX = _vm->_draw->_scrollOffsetX; + oldOffY = _vm->_draw->_scrollOffsetY; + if ((width > sWidth) && (_vm->_global->_inter_mouseX >= _vm->_draw->_scrollOffsetX)) { cursorRight = _vm->_global->_inter_mouseX + _vm->_draw->_cursorWidth; - if (cursorRight > (_vm->_draw->_word_2FC9E + sWidth)) - _vm->_draw->_word_2FC9E = MIN(cursorRight - sWidth, width - sWidth); - } else if (_vm->_global->_inter_mouseX < _vm->_draw->_word_2FC9E) - _vm->_draw->_word_2FC9E = _vm->_global->_inter_mouseX; + if (cursorRight > (_vm->_draw->_scrollOffsetX + sWidth)) + _vm->_draw->_scrollOffsetX = MIN(cursorRight - sWidth, width - sWidth); + } else if (_vm->_global->_inter_mouseX < _vm->_draw->_scrollOffsetX) + _vm->_draw->_scrollOffsetX = _vm->_global->_inter_mouseX; height = _vm->_draw->_frontSurface->height; - if ((height > sHeight) && (_vm->_global->_inter_mouseY >= _vm->_draw->_word_2FC9C)) { + if ((height > sHeight) && (_vm->_global->_inter_mouseY >= _vm->_draw->_scrollOffsetY)) { cursorBottom = _vm->_global->_inter_mouseY + _vm->_draw->_cursorHeight; - if (cursorBottom > (_vm->_draw->_word_2FC9C + sHeight)) - _vm->_draw->_word_2FC9C = MIN(cursorBottom - sHeight, height - sHeight); - } else if (_vm->_global->_inter_mouseY < _vm->_draw->_word_2FC9C) - _vm->_draw->_word_2FC9C = _vm->_global->_inter_mouseY; - if ((oldWord_2FC9E != _vm->_draw->_word_2FC9E) || - (oldWord_2FC9C != _vm->_draw->_word_2FC9C)) { + if (cursorBottom > (_vm->_draw->_scrollOffsetY + sHeight)) + _vm->_draw->_scrollOffsetY = MIN(cursorBottom - sHeight, height - sHeight); + } else if (_vm->_global->_inter_mouseY < _vm->_draw->_scrollOffsetY) + _vm->_draw->_scrollOffsetY = _vm->_global->_inter_mouseY; + if ((oldOffX != _vm->_draw->_scrollOffsetX) || + (oldOffY != _vm->_draw->_scrollOffsetY)) { if (_byte_2FC9B == 0) { - _vm->_draw->_word_2FC9E = oldWord_2FC9E; - _vm->_draw->_word_2FC9C = oldWord_2FC9C; + _vm->_draw->_scrollOffsetX = oldOffX; + _vm->_draw->_scrollOffsetY = oldOffY; if ((_vm->_draw->_frontSurface->width > sWidth) && - (_vm->_global->_inter_mouseX >= oldWord_2FC9E)) { + (_vm->_global->_inter_mouseX >= oldOffX)) { if ((_vm->_global->_inter_mouseX + _vm->_draw->_cursorWidth) > - (_vm->_draw->_word_2FC9E + sWidth)) - _vm->_global->_inter_mouseX = _vm->_draw->_word_2FC9E + + (_vm->_draw->_scrollOffsetX + sWidth)) + _vm->_global->_inter_mouseX = _vm->_draw->_scrollOffsetX + sWidth - _vm->_draw->_cursorWidth; - } else if (_vm->_global->_inter_mouseX < oldWord_2FC9E) - _vm->_global->_inter_mouseX = oldWord_2FC9E; + } else if (_vm->_global->_inter_mouseX < oldOffX) + _vm->_global->_inter_mouseX = oldOffX; if ((_vm->_draw->_frontSurface->height > sHeight) && - (_vm->_global->_inter_mouseY >= _vm->_draw->_word_2FC9C)) { + (_vm->_global->_inter_mouseY >= _vm->_draw->_scrollOffsetY)) { if ((_vm->_global->_inter_mouseY + _vm->_draw->_cursorHeight) > - (_vm->_draw->_word_2FC9C + sHeight)) - _vm->_global->_inter_mouseY = _vm->_draw->_word_2FC9C + + (_vm->_draw->_scrollOffsetY + sHeight)) + _vm->_global->_inter_mouseY = _vm->_draw->_scrollOffsetY + sHeight - _vm->_draw->_cursorHeight; - } else if (_vm->_global->_inter_mouseY < oldWord_2FC9E) - _vm->_global->_inter_mouseY = _vm->_draw->_word_2FC9C; + } else if (_vm->_global->_inter_mouseY < oldOffX) + _vm->_global->_inter_mouseY = _vm->_draw->_scrollOffsetY; } else { - if (oldWord_2FC9E > _vm->_draw->_word_2FC9E) { - _vm->_global->_inter_mouseX += (oldWord_2FC9E - _vm->_draw->_word_2FC9E) / 2; - _vm->_draw->_word_2FC9E += (oldWord_2FC9E - _vm->_draw->_word_2FC9E) / 2; + if (oldOffX > _vm->_draw->_scrollOffsetX) { + _vm->_global->_inter_mouseX += (oldOffX - _vm->_draw->_scrollOffsetX) / 2; + _vm->_draw->_scrollOffsetX += (oldOffX - _vm->_draw->_scrollOffsetX) / 2; } else { - _vm->_global->_inter_mouseX -= (_vm->_draw->_word_2FC9E - oldWord_2FC9E) / 2; - _vm->_draw->_word_2FC9E -= (_vm->_draw->_word_2FC9E - oldWord_2FC9E) / 2; + _vm->_global->_inter_mouseX -= (_vm->_draw->_scrollOffsetX - oldOffX) / 2; + _vm->_draw->_scrollOffsetX -= (_vm->_draw->_scrollOffsetX - oldOffX) / 2; } - if (oldWord_2FC9C > _vm->_draw->_word_2FC9C) { - _vm->_global->_inter_mouseY += (oldWord_2FC9C - _vm->_draw->_word_2FC9C) / 2; - _vm->_draw->_word_2FC9C += (oldWord_2FC9C - _vm->_draw->_word_2FC9C) / 2; - if (_vm->_draw->_word_2FC9C < 2) - _vm->_draw->_word_2FC9C = 0; + if (oldOffY > _vm->_draw->_scrollOffsetY) { + _vm->_global->_inter_mouseY += (oldOffY - _vm->_draw->_scrollOffsetY) / 2; + _vm->_draw->_scrollOffsetY += (oldOffY - _vm->_draw->_scrollOffsetY) / 2; + if (_vm->_draw->_scrollOffsetY < 2) + _vm->_draw->_scrollOffsetY = 0; } else { - _vm->_global->_inter_mouseY -= (_vm->_draw->_word_2FC9C - oldWord_2FC9C) / 2; - _vm->_draw->_word_2FC9C -= (_vm->_draw->_word_2FC9C - oldWord_2FC9C) / 2; + _vm->_global->_inter_mouseY -= (_vm->_draw->_scrollOffsetY - oldOffY) / 2; + _vm->_draw->_scrollOffsetY -= (_vm->_draw->_scrollOffsetY - oldOffY) / 2; } if (_vm->_draw->_off_2E51B == 0) - warning("_vid_setPixelShift(_vm->_draw->_word_2FC9E, _vm->_draw->_word_2FC9C);"); + _vm->_util->setScrollOffset(); else - warning("_vid_setPixelShift(_vm->_draw->_word_2FC9E, _vm->_draw->_word_2FC9C + _vm->_draw->_off_2E51B->height);"); + _vm->_util->setScrollOffset(_vm->_draw->_scrollOffsetX, + _vm->_draw->_scrollOffsetY + _vm->_draw->_off_2E51B->height);; } _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY); } @@ -646,7 +647,7 @@ void Game_v2::prepareStart(void) { _vm->_draw->initScreen(); _vm->_video->fillRect(_vm->_draw->_frontSurface, 0, 0, - _vm->_video->_surfWidth - 1, 199, 1); + _vm->_video->_surfWidth - 1, _vm->_video->_surfHeight - 1, 1); _vm->_util->setMousePos(152, 92); diff --git a/engines/gob/init_v2.cpp b/engines/gob/init_v2.cpp index 129f75ebd5..e8ab0283da 100644 --- a/engines/gob/init_v2.cpp +++ b/engines/gob/init_v2.cpp @@ -43,7 +43,8 @@ void Init_v2::soundVideo(int32 smallHeap, int16 flag) { _vm->_global->_videoMode); _vm->_draw->_frontSurface = &_vm->_global->_primarySurfDesc; - _vm->_video->initSurfDesc(_vm->_global->_videoMode, _vm->_video->_surfWidth, 200, 0x80); + _vm->_video->initSurfDesc(_vm->_global->_videoMode, _vm->_video->_surfWidth, + _vm->_video->_surfHeight, 0x80); _vm->_global->_mousePresent = 1; @@ -61,8 +62,8 @@ void Init_v2::soundVideo(int32 smallHeap, int16 flag) { _vm->_global->_pPaletteDesc->unused2 = _vm->_global->_unusedPalette2; if (_vm->_global->_videoMode != 0) - _vm->_video->initSurfDesc(_vm->_global->_videoMode, _vm->_video->_surfWidth, 200, - PRIMARY_SURFACE); + _vm->_video->initSurfDesc(_vm->_global->_videoMode, _vm->_video->_surfWidth, + _vm->_video->_surfHeight, PRIMARY_SURFACE); } } // End of namespace Gob diff --git a/engines/gob/inter.cpp b/engines/gob/inter.cpp index ef9a34e23c..7515be82a9 100644 --- a/engines/gob/inter.cpp +++ b/engines/gob/inter.cpp @@ -190,60 +190,6 @@ void Inter::funcBlock(int16 retFlag) { return; } -void Inter::checkSwitchTable(char **ppExec) { - int16 i; - int16 len; - char found; - int32 value; - char notFound; - char defFlag; - - found = 0; - notFound = 1; - *ppExec = 0; - value = _vm->_parse->parseVarIndex(); - value = VAR_OFFSET(value); - - do { - len = *(int8*)_vm->_global->_inter_execPtr++; // must be a signed char typ and char is not default signed on all platforms. - - if (len == -5) - break; - - for (i = 0; i < len; i++) { - evalExpr(0); - - if (_terminate) - return; - - if (_vm->_global->_inter_resVal == value) { - found = 1; - notFound = 0; - } - } - - if (found != 0) - *ppExec = _vm->_global->_inter_execPtr; - - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; - found = 0; - } while (len != -5); - - if (len != -5) - _vm->_global->_inter_execPtr++; - - defFlag = *_vm->_global->_inter_execPtr; - defFlag >>= 4; - if (defFlag != 4) - return; - _vm->_global->_inter_execPtr++; - - if (notFound) - *ppExec = _vm->_global->_inter_execPtr; - - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; -} - void Inter::callSub(int16 retFlag) { int16 block; while (!_vm->_quitRequested && _vm->_global->_inter_execPtr != 0 && (char *)_vm->_global->_inter_execPtr != _vm->_game->_totFileData) { diff --git a/engines/gob/inter.h b/engines/gob/inter.h index ef75815e69..a6d25f53ad 100644 --- a/engines/gob/inter.h +++ b/engines/gob/inter.h @@ -58,11 +58,11 @@ public: char evalExpr(int16 *pRes); char evalBoolResult(void); void funcBlock(int16 retFlag); - void checkSwitchTable(char **ppExec); void callSub(int16 retFlag); void initControlVars(char full); void renewTimeInVars(void); void manipulateMap(int16 xPos, int16 yPos, int16 item); + virtual void checkSwitchTable(char **ppExec) = 0; virtual int16 loadSound(int16 slot) = 0; virtual void storeKey(int16 key) = 0; virtual void storeMouse(void) = 0; @@ -95,6 +95,7 @@ class Inter_v1 : public Inter { public: Inter_v1(GobEngine *vm); virtual ~Inter_v1() {}; + virtual void checkSwitchTable(char **ppExec); virtual int16 loadSound(int16 slot); virtual void storeKey(int16 key); virtual void storeMouse(void); @@ -288,6 +289,7 @@ class Inter_v2 : public Inter_v1 { public: Inter_v2(GobEngine *vm); virtual ~Inter_v2() {}; + virtual void checkSwitchTable(char **ppExec); virtual int16 loadSound(int16 search); virtual void storeKey(int16 key); virtual void storeMouse(void); diff --git a/engines/gob/inter_bargon.cpp b/engines/gob/inter_bargon.cpp index e9f73d893e..1e3ab00e76 100644 --- a/engines/gob/inter_bargon.cpp +++ b/engines/gob/inter_bargon.cpp @@ -743,11 +743,11 @@ void Inter_Bargon::oBargon_intro2(int16 &extraData, int32 *retVarPtr, _vm->_video->drawSprite(surface, _vm->_draw->_frontSurface, 0, 0, 319, 199, 0, 0, 0); _vm->_video->drawPackedSprite("2ille4.ims", surface); _vm->_video->drawSprite(surface, _vm->_draw->_frontSurface, 0, 0, 319, 199, 320, 0, 0); - _vm->_util->setScrollOffset(320); + _vm->_util->setScrollOffset(320, 0); _vm->_palanim->fade(_vm->_global->_pPaletteDesc, -2, 0); _vm->_util->longDelay(1000); for (i = 320; i >= 0; i--) { - _vm->_util->setScrollOffset(i); + _vm->_util->setScrollOffset(i, 0); if ((_vm->_game->checkKeys(&mouseX, &mouseY, &buttons, 0) == 0x11B) || _vm->_quitRequested) { _vm->_palanim->fade(0, -2, 0); @@ -760,7 +760,7 @@ void Inter_Bargon::oBargon_intro2(int16 &extraData, int32 *retVarPtr, } } if (!_vm->_quitRequested) - _vm->_util->setScrollOffset(0); + _vm->_util->setScrollOffset(0, 0); _vm->_video->freeSurfDesc(surface); if (VAR(57) == ((uint32) -1)) return; diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp index 1e8084febb..0a2468a4c8 100644 --- a/engines/gob/inter_v1.cpp +++ b/engines/gob/inter_v1.cpp @@ -646,6 +646,117 @@ void Inter_v1::setupOpcodes(void) { _opcodesGoblinV1 = opcodesGoblin; } +void Inter_v1::executeDrawOpcode(byte i) { + debugC(1, kDebugDrawOp, "opcodeDraw %d [0x%x] (%s)", i, i, getOpcodeDrawDesc(i)); + + OpcodeDrawProcV1 op = _opcodesDrawV1[i].proc; + + if (op == NULL) + warning("unimplemented opcodeDraw: %d", i); + else + (this->*op) (); +} + +bool Inter_v1::executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, int16 &retFlag) { + debugC(1, kDebugFuncOp, "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); + return false; + } + + OpcodeFuncProcV1 op = _opcodesFuncV1[i*16 + j].proc; + + if (op == NULL) + warning("unimplemented opcodeFunc: %d.%d", i, j); + else + return (this->*op) (cmdCount, counter, retFlag); + return false; +} + +void Inter_v1::executeGoblinOpcode(int i, int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { + debugC(1, kDebugGobOp, "opcodeGoblin %d [0x%x] (%s)", i, i, getOpcodeGoblinDesc(i)); + + OpcodeGoblinProcV1 op = NULL; + + for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++) + if (_goblinFuncLookUp[j][0] == i) { + op = _opcodesGoblinV1[_goblinFuncLookUp[j][1]].proc; + break; + } + + if (op == NULL) { + warning("unimplemented opcodeGoblin: %d", i); + _vm->_global->_inter_execPtr -= 2; + int16 cmd = load16(); + _vm->_global->_inter_execPtr += cmd * 2; + } + else + (this->*op) (extraData, retVarPtr, objDesc); +} + +const char *Inter_v1::getOpcodeDrawDesc(byte i) { + return _opcodesDrawV1[i].desc; +} + +const char *Inter_v1::getOpcodeFuncDesc(byte i, byte j) { + if ((i > 4) || (j > 15)) + return ""; + + return _opcodesFuncV1[i*16 + j].desc; +} + +const char *Inter_v1::getOpcodeGoblinDesc(int i) { + for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++) + if (_goblinFuncLookUp[j][0] == i) + return _opcodesGoblinV1[_goblinFuncLookUp[j][1]].desc; + return ""; +} + +void Inter_v1::checkSwitchTable(char **ppExec) { + int i; + int16 len; + int32 value; + bool found; + bool notFound; + + found = false; + notFound = true; + *ppExec = 0; + value = VAR_OFFSET(_vm->_parse->parseVarIndex()); + + len = (int8) *_vm->_global->_inter_execPtr++; + while (len != -5) { + for (i = 0; i < len; i++) { + evalExpr(0); + + if (_terminate) + return; + + if (_vm->_global->_inter_resVal == value) { + found = true; + notFound = false; + } + } + + if (found) + *ppExec = _vm->_global->_inter_execPtr; + + _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + found = false; + len = (int8) *_vm->_global->_inter_execPtr++; + } + + if ((*_vm->_global->_inter_execPtr >> 4) != 4) + return; + + _vm->_global->_inter_execPtr++; + if (notFound) + *ppExec = _vm->_global->_inter_execPtr; + + _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; +} + bool Inter_v1::o1_setMousePos(char &cmdCount, int16 &counter, int16 &retFlag) { _vm->_global->_inter_mouseX = _vm->_parse->parseValExpr(); _vm->_global->_inter_mouseY = _vm->_parse->parseValExpr(); @@ -1303,6 +1414,7 @@ bool Inter_v1::o1_loadSpriteToPos(char &cmdCount, int16 &counter, int16 &retFlag _vm->_draw->_destSurface = 101; _vm->_draw->_transparency &= 1; _vm->_global->_inter_execPtr += 2; + _vm->_draw->spriteOperation(DRAW_LOADSPRITE); return false; @@ -1696,73 +1808,6 @@ void Inter_v1::o1_freeFontToSprite(void) { _vm->_draw->_fontToSprite[i].height = -1; } -void Inter_v1::executeDrawOpcode(byte i) { - debugC(1, kDebugDrawOp, "opcodeDraw %d [0x%x] (%s)", i, i, getOpcodeDrawDesc(i)); - - OpcodeDrawProcV1 op = _opcodesDrawV1[i].proc; - - if (op == NULL) - warning("unimplemented opcodeDraw: %d", i); - else - (this->*op) (); -} - -bool Inter_v1::executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, int16 &retFlag) { - debugC(1, kDebugFuncOp, "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); - return false; - } - - OpcodeFuncProcV1 op = _opcodesFuncV1[i*16 + j].proc; - - if (op == NULL) - warning("unimplemented opcodeFunc: %d.%d", i, j); - else - return (this->*op) (cmdCount, counter, retFlag); - return false; -} - -void Inter_v1::executeGoblinOpcode(int i, int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - debugC(1, kDebugGobOp, "opcodeGoblin %d [0x%x] (%s)", i, i, getOpcodeGoblinDesc(i)); - - OpcodeGoblinProcV1 op = NULL; - - for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++) - if (_goblinFuncLookUp[j][0] == i) { - op = _opcodesGoblinV1[_goblinFuncLookUp[j][1]].proc; - break; - } - - if (op == NULL) { - warning("unimplemented opcodeGoblin: %d", i); - _vm->_global->_inter_execPtr -= 2; - int16 cmd = load16(); - _vm->_global->_inter_execPtr += cmd * 2; - } - else - (this->*op) (extraData, retVarPtr, objDesc); -} - -const char *Inter_v1::getOpcodeDrawDesc(byte i) { - return _opcodesDrawV1[i].desc; -} - -const char *Inter_v1::getOpcodeFuncDesc(byte i, byte j) { - if ((i > 4) || (j > 15)) - return ""; - - return _opcodesFuncV1[i*16 + j].desc; -} - -const char *Inter_v1::getOpcodeGoblinDesc(int i) { - for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++) - if (_goblinFuncLookUp[j][0] == i) - return _opcodesGoblinV1[_goblinFuncLookUp[j][1]].desc; - return ""; -} - bool Inter_v1::o1_callSub(char &cmdCount, int16 &counter, int16 &retFlag) { char *storedIP = _vm->_global->_inter_execPtr; diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp index a262680f8f..7df944c76c 100644 --- a/engines/gob/inter_v2.cpp +++ b/engines/gob/inter_v2.cpp @@ -715,6 +715,96 @@ const char *Inter_v2::getOpcodeGoblinDesc(int i) { return ""; } +void Inter_v2::checkSwitchTable(char **ppExec) { + int i; + byte cmd; + int16 len; + int32 value; + bool found; + + found = false; + *ppExec = 0; + + cmd = *_vm->_global->_inter_execPtr; + + value = _vm->_parse->parseVarIndex(); + + switch (cmd) { + case 16: + case 18: + value = (int8) READ_VARO_UINT8(value); + break; + + case 23: + case 26: + value = READ_VARO_UINT32(value); + break; + + default: + value = READ_VARO_UINT16(value); + break; + } + + if (_terminate) + return; + + len = (int8) *_vm->_global->_inter_execPtr++; + while (len != -5) { + for (i = 0; i < len; i++) { + cmd = *_vm->_global->_inter_execPtr; + + switch(cmd) { + case 19: + _vm->_global->_inter_execPtr++; + if (!found && + (value == (int32) (READ_LE_UINT32(_vm->_global->_inter_execPtr)))) + found = true; + _vm->_global->_inter_execPtr += 5; + break; + + case 20: + _vm->_global->_inter_execPtr++; + if (!found && + (value == (int16) (READ_LE_UINT16(_vm->_global->_inter_execPtr)))) + found = true; + _vm->_global->_inter_execPtr += 3; + break; + + case 21: + _vm->_global->_inter_execPtr++; + if (!found && (value == (int8) *_vm->_global->_inter_execPtr)) + found = true; + _vm->_global->_inter_execPtr += 2; + break; + + default: + if (!found) { + evalExpr(0); + if (value == _vm->_global->_inter_resVal) + found = true; + } else + _vm->_parse->skipExpr(99); + break; + } + } + + if (found && (*ppExec == 0)) + *ppExec = _vm->_global->_inter_execPtr; + + _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + len = (int8) *_vm->_global->_inter_execPtr++; + } + + if ((*_vm->_global->_inter_execPtr >> 4) != 4) + return; + + _vm->_global->_inter_execPtr++; + if (*ppExec == 0) + *ppExec = _vm->_global->_inter_execPtr; + + _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; +} + void Inter_v2::o2_stub0x54(void) { int16 index = _vm->_parse->parseValExpr(); @@ -879,7 +969,7 @@ int16 Inter_v2::loadSound(int16 search) { } else { if (id >= 30000) { if (!isADL && (_vm->_game->_totFileData[0x29] >= 51)) { // loc_9763 - if (_vm->_inter->_terminate != 0) + if (_terminate != 0) return slot; soundDesc = new Snd::SoundDesc; extData = _vm->_game->loadExtData(id, 0, 0); @@ -1869,7 +1959,7 @@ void Inter_v2::o2_initMult(void) { if (_vm->_mult->_objects == 0) { _vm->_mult->_renderData2 = new Mult::Mult_Object*[_vm->_mult->_objCount]; memset(_vm->_mult->_renderData2, 0, _vm->_mult->_objCount * sizeof(Mult::Mult_Object*)); - if (_vm->_inter->_terminate) + if (_terminate) return; _vm->_mult->_orderArray = new int8[_vm->_mult->_objCount]; memset(_vm->_mult->_orderArray, 0, _vm->_mult->_objCount * sizeof(int8)); @@ -2115,15 +2205,15 @@ void Inter_v2::o2_playImd(void) { } void Inter_v2::o2_initScreen(void) { - int16 start; + int16 offY; int16 videoMode; int16 width; int16 height; - start = load16(); + offY = load16(); - videoMode = start & 0xFF; - start = (start >> 8) & 0xFF; + videoMode = offY & 0xFF; + offY = (offY >> 8) & 0xFF; width = _vm->_parse->parseValExpr(); height = _vm->_parse->parseValExpr(); @@ -2131,7 +2221,10 @@ void Inter_v2::o2_initScreen(void) { if ((videoMode == _vm->_global->_videoMode) && (width == -1)) return; - _vm->_video->_surfWidth = videoMode == 0x14 ? 640 : 320; + if (width > 0) + _vm->_video->_surfWidth = width; + if (height > 0) + _vm->_video->_surfHeight = height; _vm->_draw->closeScreen(); _vm->_util->clearPalette(); @@ -2153,36 +2246,27 @@ void Inter_v2::o2_initScreen(void) { _vm->_global->_setAllPalette = 1; - if ((width != -1) && (_vm->_global->_videoMode == 0x14)) { + if ((width != -1) && (_vm->_global->_videoMode == 0x14)) _vm->_game->_byte_2FC9B = 1; -/* - if (width > 960) - width = 960; - _vm->_draw->_frontSurface->width = width; - _vm->_draw->_frontSurface->height = height; - warning("GOB2 Stub! _vid_setVirtRes(_vm->_draw->_frontSurface);"); - _vm->_global->_mouseMaxCol = width; - _vm->_global->_mouseMaxRow = height; -*/ - } _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY); _vm->_util->clearPalette(); - if (start == 0) + // Split screen (word_2E51F ^= splitScreenHeight, off_2E51B ^= splitScreenSurf)? + if (offY == 0) _vm->_draw->_word_2E51F = 0; else - _vm->_draw->_word_2E51F = _vm->_global->_primaryHeight - start; + _vm->_draw->_word_2E51F = _vm->_global->_primaryHeight - offY; _vm->_draw->initScreen(); - if (_vm->_draw->_off_2E51B != 0) { - _vm->_video->_scrollOffset = 0; + _vm->_util->setScrollOffset(); /* - warning("_vid_setSplit(%d)", _vm->_global->_primaryHeight - start); - warning("_vid_setPixelShift(0, %d", start); -*/ + if (_vm->_draw->_off_2E51B != 0) { + warning("_vid_setSplit(%d)", _vm->_global->_primaryHeight - offY); + warning("_vid_setPixelShift(0, %d", offY); } +*/ } void Inter_v2::o2_setScrollOffset(void) { @@ -2194,20 +2278,24 @@ void Inter_v2::o2_setScrollOffset(void) { if (_vm->_game->_byte_2FC9B != 0) _vm->_game->_byte_2FC9B = 1; _vm->_parse->parseValExpr(); - WRITE_VAR(2, _vm->_draw->_word_2FC9E); - WRITE_VAR(3, _vm->_draw->_word_2FC9C); + WRITE_VAR(2, _vm->_draw->_scrollOffsetX); + WRITE_VAR(3, _vm->_draw->_scrollOffsetY); } else { - _vm->_draw->_word_2FC9E = offset; - _vm->_draw->_word_2FC9C = _vm->_parse->parseValExpr(); + _vm->_draw->_scrollOffsetX = offset; + _vm->_draw->_scrollOffsetY = _vm->_parse->parseValExpr(); } - _vm->_util->setScrollOffset(_vm->_draw->_word_2FC9E); + if (_vm->_draw->_off_2E51B != 0) + _vm->_util->setScrollOffset(_vm->_draw->_scrollOffsetX, + _vm->_draw->_scrollOffsetY + 200 - _vm->_draw->_word_2E51F); + else + _vm->_util->setScrollOffset(); _noBusyWait = true; /* if (_vm->_draw->_off_2E51B != 0) - warning("_vid_setPixelShift(%d, %d)", _vm->_draw->_word_2FC9E, _vm->_draw->_word_2FC9C + 200 - _vm->_draw->_word_2E51F); + warning("_vid_setPixelShift(%d, %d)", _vm->_draw->_scrollOffsetX, _vm->_draw->_scrollOffsetY + 200 - _vm->_draw->_word_2E51F); else - warning("_vid_setPixelShift(%d, %d)", _vm->_draw->_word_2FC9E, _vm->_draw->_word_2FC9C);; + warning("_vid_setPixelShift(%d, %d)", _vm->_draw->_scrollOffsetX, _vm->_draw->_scrollOffsetY);; */ } @@ -2228,16 +2316,14 @@ void Inter_v2::o2_scroll(void) { stepX = _vm->_parse->parseValExpr(); stepY = _vm->_parse->parseValExpr(); - if ((stepY != 0) || (startY > 0) || (endY > 0)) - warning("GOB2 Stub! Vertical scrolling / high surfaces"); - curX = startX; curY = startY; while (!_vm->_quitRequested && ((curX != endX) || (curY != endY))) { curX = stepX > 0 ? MIN(curX + stepX, (int) endX) : MAX(curX + stepX, (int) endX); curY = stepY > 0 ? MIN(curY + stepY, (int) endY) : MAX(curY + stepY, (int) endY); - _vm->_draw->_word_2FC9E = curX; - _vm->_util->setScrollOffset(_vm->_draw->_word_2FC9E); + _vm->_draw->_scrollOffsetX = curX; + _vm->_draw->_scrollOffsetY = curY; + _vm->_util->setScrollOffset(); } } diff --git a/engines/gob/mult_v2.cpp b/engines/gob/mult_v2.cpp index 539b4fa41d..56f96f4d97 100644 --- a/engines/gob/mult_v2.cpp +++ b/engines/gob/mult_v2.cpp @@ -424,7 +424,7 @@ void Mult_v2::playMult(int16 startFrame, int16 endFrame, char checkEscape, _vm->_anim->_areaTop = 0; _vm->_anim->_areaLeft = 0; _vm->_anim->_areaWidth = _vm->_video->_surfWidth; - _vm->_anim->_areaHeight = 200; + _vm->_anim->_areaHeight = _vm->_video->_surfHeight; _objCount = 4; if (_objects) @@ -478,7 +478,7 @@ void Mult_v2::playMult(int16 startFrame, int16 endFrame, char checkEscape, _vm->_draw->_spriteLeft = 0; _vm->_draw->_spriteTop = 0; _vm->_draw->_spriteRight = _vm->_video->_surfWidth; - _vm->_draw->_spriteBottom = 200; + _vm->_draw->_spriteBottom = _vm->_video->_surfHeight; _vm->_draw->_transparency = 0; _vm->_draw->spriteOperation(0); _animDataAllocated = 1; @@ -609,7 +609,7 @@ char Mult_v2::drawStatics(char stop) { _vm->_draw->_spriteLeft = 0; _vm->_draw->_spriteTop = 0; _vm->_draw->_spriteRight = _vm->_video->_surfWidth; - _vm->_draw->_spriteBottom = 200; + _vm->_draw->_spriteBottom = _vm->_video->_surfHeight; _vm->_draw->_transparency = 0; _vm->_draw->spriteOperation(0); } diff --git a/engines/gob/util.cpp b/engines/gob/util.cpp index 7698262e26..6dfa5b4d7c 100644 --- a/engines/gob/util.cpp +++ b/engines/gob/util.cpp @@ -494,9 +494,10 @@ void Util::forceMouseUp(void) { _mouseButtons = 0; } -void Util::setScrollOffset(int16 scrollOffset) { +void Util::setScrollOffset(int16 x, int16 y) { processInput(); - _vm->_video->_scrollOffset = scrollOffset; + _vm->_video->_scrollOffsetX = x >= 0 ? x : _vm->_draw->_scrollOffsetX; + _vm->_video->_scrollOffsetY = y >= 0 ? y : _vm->_draw->_scrollOffsetY; _vm->_video->waitRetrace(_vm->_global->_videoMode); } diff --git a/engines/gob/util.h b/engines/gob/util.h index 8f4d6867c6..de9e6224b9 100644 --- a/engines/gob/util.h +++ b/engines/gob/util.h @@ -84,7 +84,7 @@ public: static void prepareStr(char *str); void waitMouseRelease(char drawMouse); void forceMouseUp(void); - void setScrollOffset(int16 scrollOffset); + void setScrollOffset(int16 x = -1, int16 y = -1); static const char trStr1[]; static const char trStr2[]; diff --git a/engines/gob/video.cpp b/engines/gob/video.cpp index 675d7a6f23..bbe909e189 100644 --- a/engines/gob/video.cpp +++ b/engines/gob/video.cpp @@ -38,7 +38,9 @@ namespace Gob { Video::Video(GobEngine *vm) : _vm(vm) { _videoDriver = 0; _surfWidth = 320; - _scrollOffset = 0; + _surfHeight = 200; + _scrollOffsetX = 0; + _scrollOffsetY = 0; } char Video::initDriver(int16 vidMode) { @@ -396,7 +398,7 @@ void Video::initPrimary(int16 mode) { Video::initDriver(mode); if (mode != 3) { - initSurfDesc(mode, _surfWidth, 200, PRIMARY_SURFACE); + initSurfDesc(mode, _surfWidth, _vm->_video->_surfHeight, PRIMARY_SURFACE); if (_vm->_global->_dontSetPalette) return; diff --git a/engines/gob/video.h b/engines/gob/video.h index f59fa48191..99127e64bb 100644 --- a/engines/gob/video.h +++ b/engines/gob/video.h @@ -91,7 +91,9 @@ public: }; int16 _surfWidth; - int16 _scrollOffset; + int16 _surfHeight; + int16 _scrollOffsetX; + int16 _scrollOffsetY; Video(class GobEngine *vm); virtual ~Video() {}; diff --git a/engines/gob/video_v2.cpp b/engines/gob/video_v2.cpp index 2f71412b69..d4bbd7ada8 100644 --- a/engines/gob/video_v2.cpp +++ b/engines/gob/video_v2.cpp @@ -45,8 +45,9 @@ void Video_v2::waitRetrace(int16, bool mouse) { CursorMan.showMouse((_vm->_draw->_showCursor & 2) != 0); if (_vm->_draw->_frontSurface) { time = _vm->_util->getTimeKey(); - g_system->copyRectToScreen(_vm->_draw->_frontSurface->vidPtr + _scrollOffset, - _surfWidth, 0, 0, 320, 200); + g_system->copyRectToScreen(_vm->_draw->_frontSurface->vidPtr + + _scrollOffsetY * _surfWidth + _scrollOffsetX, _surfWidth, + 0, 0, 320, 200); g_system->updateScreen(); _vm->_util->delay(MAX(1, 10 - (int)(_vm->_util->getTimeKey() - time))); } @@ -136,8 +137,8 @@ Video::SurfaceDesc *Video_v2::initSurfDesc(int16 vidMode, int16 width, int16 hei assert(descPtr); if (descPtr->vidPtr != 0) delete[] descPtr->vidPtr; - vidMem = new byte[_surfWidth * 200]; - memset(vidMem, 0, _surfWidth * 200); + vidMem = new byte[_surfWidth * _surfHeight]; + memset(vidMem, 0, _surfWidth * _surfHeight); } else { if (flags & DISABLE_SPR_ALLOC) { descPtr = new SurfaceDesc; |