From 2eabfd5f287686b7f5186af71cc199b99cf06bdd Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Mon, 1 May 2006 12:43:50 +0000 Subject: - More differences in Draw_v2::spriteOperation() - GOB2 handles _frontSurface/_backSurface a bit differently, this fixes (most of) the drawing glitches in the intro - Added using a fallback when the user's game version doesn't have the requested language - off_2E51B et al. stubs, I think it has something to do with the menu svn-id: r22254 --- engines/gob/draw.cpp | 8 +- engines/gob/draw.h | 1 + engines/gob/draw_v2.cpp | 93 ++++----- engines/gob/game.cpp | 519 ++++++++++++++++------------------------------- engines/gob/game.h | 60 +++++- engines/gob/game_v1.cpp | 340 +++++++++++++++++++++++++++++++ engines/gob/game_v2.cpp | 390 ++++++++++++++++++++++++++++++++++- engines/gob/gob.cpp | 3 +- engines/gob/init.cpp | 41 +--- engines/gob/init.h | 23 ++- engines/gob/init_v1.cpp | 79 ++++++++ engines/gob/init_v2.cpp | 82 ++++++++ engines/gob/inter.cpp | 4 +- engines/gob/inter.h | 4 + engines/gob/inter_v1.cpp | 6 + engines/gob/inter_v2.cpp | 143 ++++++++++++- engines/gob/module.mk | 2 + engines/gob/mult_v2.cpp | 4 +- engines/gob/video.cpp | 78 +------ engines/gob/video.h | 10 +- engines/gob/video_v1.cpp | 75 +++++++ engines/gob/video_v2.cpp | 81 ++++++++ 22 files changed, 1505 insertions(+), 541 deletions(-) create mode 100644 engines/gob/init_v1.cpp create mode 100644 engines/gob/init_v2.cpp (limited to 'engines') diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp index 06f44a794d..19a10947b3 100644 --- a/engines/gob/draw.cpp +++ b/engines/gob/draw.cpp @@ -493,10 +493,10 @@ void Draw::initBigSprite(int16 index, int16 width, int16 height, int16 flags) { _bigSpritesParts[index][i] = 0; _spritesHeights[index] = height; - if (_vm->_video->getRectSize(width, height, flags, _vm->_global->_videoMode) > 6500) { + if (_vm->_video->getRectSize(width, height, flags, _vm->_global->_videoMode) > 65000) { _spritesHeights[index] = height & 0xFFFE; while (_vm->_video->getRectSize(width, _spritesHeights[index], flags, - _vm->_global->_videoMode) > 6500) { + _vm->_global->_videoMode) > 65000) { _spritesHeights[index] -= 2; } @@ -521,10 +521,10 @@ void Draw::initBigSprite(int16 index, int16 width, int16 height, int16 flags) { fragment++; } } else - _vm->_video->initSurfDesc(_vm->_global->_videoMode, width, height, flags); + _spritesArray[index] = + _vm->_video->initSurfDesc(_vm->_global->_videoMode, width, height, flags); _vm->_video->clearSurf(_spritesArray[index]); - // '------ } diff --git a/engines/gob/draw.h b/engines/gob/draw.h index 5dfc231668..76d53a5108 100644 --- a/engines/gob/draw.h +++ b/engines/gob/draw.h @@ -96,6 +96,7 @@ public: int16 _cursorYDeltaVar; Video::SurfaceDesc *_cursorSprites; + Video::SurfaceDesc *_cursorSpritesBack; Video::SurfaceDesc *_cursorBack; int16 _cursorAnim; int8 _cursorAnimLow[40]; diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp index ec57577eca..b5459750b2 100644 --- a/engines/gob/draw_v2.cpp +++ b/engines/gob/draw_v2.cpp @@ -425,7 +425,6 @@ void Draw_v2::spriteOperation(int16 operation) { int16 i; int16 x; int16 y; - int16 perLine; Video::SurfaceDesc *sourceSurf; Video::SurfaceDesc *destSurf; bool deltaveto; @@ -440,7 +439,6 @@ void Draw_v2::spriteOperation(int16 operation) { int16 destSurface; int16 sourceSurface; // .--- - Video::SurfaceDesc *off_2E51B = 0; int8 word_2F2D2 = -1; // '--- @@ -483,8 +481,8 @@ void Draw_v2::spriteOperation(int16 operation) { destSurface = _destSurface; sourceSurface = _sourceSurface; -// warning("GOB2 Stub! off_2E51B"); - if (off_2E51B != 0) { +// warning("GOB2 Stub! _off_2E51B"); + if (_vm->_game->_off_2E51B != 0) { if ((_frontSurface->height <= _destSpriteY) && ((_destSurface == 20) || (_destSurface == 21))) { _destSpriteY -= _frontSurface->height; @@ -494,7 +492,7 @@ void Draw_v2::spriteOperation(int16 operation) { _spriteBottom -= _frontSurface->height; } if (_destSurface == 21) - invalidateRect(0, _frontSurface->height, 319, _frontSurface->height+off_2E51B->height-1); + invalidateRect(0, _frontSurface->height, 319, _frontSurface->height+_vm->_game->_off_2E51B->height-1); destSurface += 4; } if ((_frontSurface->height <= _spriteTop) && (operation == DRAW_BLITSURF) @@ -731,22 +729,39 @@ void Draw_v2::spriteOperation(int16 operation) { break; case DRAW_DRAWBAR: - _vm->_video->drawLine(_spritesArray[_destSurface], - _destSpriteX, _spriteBottom, - _spriteRight, _spriteBottom, _frontColor); + if (_word_2E8E2 != 2) { + _vm->_video->fillRect(_spritesArray[_destSurface], + _destSpriteX, _spriteBottom - 1, + _spriteRight, _spriteBottom, _frontColor); - _vm->_video->drawLine(_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, - _destSpriteX, _spriteBottom, _frontColor); + _vm->_video->fillRect(_spritesArray[_destSurface], + _destSpriteX, _destSpriteY, + _destSpriteX + 1, _spriteBottom, _frontColor); - _vm->_video->drawLine(_spritesArray[_destSurface], - _spriteRight, _destSpriteY, - _spriteRight, _spriteBottom, _frontColor); + _vm->_video->fillRect(_spritesArray[_destSurface], + _spriteRight - 1, _destSpriteY, + _spriteRight, _spriteBottom, _frontColor); - _vm->_video->drawLine(_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, - _spriteRight, _destSpriteY, _frontColor); + _vm->_video->fillRect(_spritesArray[_destSurface], + _destSpriteX, _destSpriteY, + _spriteRight, _destSpriteY + 1, _frontColor); + } else { + _vm->_video->drawLine(_spritesArray[_destSurface], + _destSpriteX, _spriteBottom, + _spriteRight, _spriteBottom, _frontColor); + _vm->_video->drawLine(_spritesArray[_destSurface], + _destSpriteX, _destSpriteY, + _destSpriteX, _spriteBottom, _frontColor); + + _vm->_video->drawLine(_spritesArray[_destSurface], + _spriteRight, _destSpriteY, + _spriteRight, _spriteBottom, _frontColor); + + _vm->_video->drawLine(_spritesArray[_destSurface], + _destSpriteX, _destSpriteY, + _spriteRight, _destSpriteY, _frontColor); + } if (_destSurface == 21) { invalidateRect(_destSpriteX, _destSpriteY, _spriteRight, _spriteBottom); @@ -754,7 +769,7 @@ void Draw_v2::spriteOperation(int16 operation) { break; case DRAW_CLEARRECT: - if (_backColor < 16) { + if ((_backColor != 16) && (_backColor != 144)) { _vm->_video->fillRect(_spritesArray[_destSurface], _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, @@ -776,35 +791,21 @@ void Draw_v2::spriteOperation(int16 operation) { _spriteRight, _spriteBottom); } break; + } - perLine = - _spritesArray[(int16)_fontToSprite[_fontIndex]. - sprite]->width / _fontToSprite[_fontIndex].width; - - y = (_letterToPrint - - _fontToSprite[_fontIndex].base) / perLine * - _fontToSprite[_fontIndex].height; - - x = (_letterToPrint - - _fontToSprite[_fontIndex].base) % perLine * - _fontToSprite[_fontIndex].width; - - if (_destSurface == 21) { - invalidateRect(_destSpriteX, _destSpriteY, - _destSpriteX + - _fontToSprite[_fontIndex].width, - _destSpriteY + - _fontToSprite[_fontIndex].height); - } - - _vm->_video->drawSprite(_spritesArray[(int16)_fontToSprite - [_fontIndex].sprite], - _spritesArray[_destSurface], x, y, - x + _fontToSprite[_fontIndex].width, - y + _fontToSprite[_fontIndex].height, - _destSpriteX, _destSpriteY, _transparency); - - break; + _spriteLeft = spriteLeft; + _spriteTop = spriteTop; + _spriteRight = spriteRight; + _spriteLeft = spriteBottom; + _destSpriteX = destSpriteX; + _destSpriteY = destSpriteY; + _destSurface = destSurface; + _sourceSurface = sourceSurface; + + if (operation == DRAW_PRINTTEXT) { + len = _fonts[_fontIndex]->itemWidth; + adjustCoords(1, &len, 0); + _destSpriteX += len * strlen(_textToPrint); } if ((_renderFlags & RENDERFLAG_USEDELTAS) && !deltaveto) { diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp index 3bdf9bc2c0..a737502060 100644 --- a/engines/gob/game.cpp +++ b/engines/gob/game.cpp @@ -59,7 +59,7 @@ Game::Game(GobEngine *vm) : _vm(vm) { _collStackSize = 0; int i; - for (i = 0; i < 3; i++) { + for (i = 0; i < 5; i++) { _collStack[i] = 0; _collStackElemSizes[i] = 0; } @@ -103,6 +103,14 @@ Game::Game(GobEngine *vm) : _vm(vm) { _variablesArray[i] = 0; _curTotFileArray[i][0] = 0; } + + warning("GOB2 Stub! _byte_2FC9B, _word_2FC9C, _word_2FC9E, _word_2E51F, _off_2E51B, _off_2E517"); + _byte_2FC9B = 0; + _word_2FC9C = 0; + _word_2FC9E = 0; + _word_2E51F = 0; + _off_2E51B = 0; + _off_2E517 = 0; } char *Game::loadExtData(int16 itemId, int16 *pResWidth, int16 *pResHeight) { @@ -200,49 +208,6 @@ void Game::freeCollision(int16 id) { } } -void Game::pushCollisions(char all) { - Collision *srcPtr; - Collision *destPtr; - int16 size; - - debugC(1, DEBUG_COLLISIONS, "pushCollisions"); - for (size = 0, srcPtr = _collisionAreas; srcPtr->left != -1; - srcPtr++) { - if (all || (srcPtr->id & 0x8000)) - size++; - } - - destPtr = new Collision[size]; - _collStack[_collStackSize] = destPtr; - _collStackElemSizes[_collStackSize] = size; - _collStackSize++; - - for (srcPtr = _collisionAreas; srcPtr->left != -1; srcPtr++) { - if (all || (srcPtr->id & 0x8000)) { - memcpy(destPtr, srcPtr, sizeof(Collision)); - srcPtr->left = -1; - destPtr++; - } - } -} - -void Game::popCollisions(void) { - Collision *destPtr; - Collision *srcPtr; - - debugC(1, DEBUG_COLLISIONS, "popCollision"); - - _collStackSize--; - for (destPtr = _collisionAreas; destPtr->left != -1; destPtr++); - - srcPtr = _collStack[_collStackSize]; - memcpy(destPtr, srcPtr, - _collStackElemSizes[_collStackSize] * - sizeof(Collision)); - - free(_collStack[_collStackSize]); -} - int16 Game::checkMousePoint(int16 all, int16 *resId, int16 *resIndex) { Collision *ptr; int16 i; @@ -407,255 +372,6 @@ void Game::freeSoundSlot(int16 slot) { } -int16 Game::checkKeys(int16 *pMouseX, int16 *pMouseY, int16 *pButtons, char handleMouse) { - _vm->_util->processInput(); - - if (VAR(58) != 0) { - if (_vm->_mult->_frameStart != (int)VAR(58) - 1) - _vm->_mult->_frameStart++; - else - _vm->_mult->_frameStart = 0; - - _vm->_mult->playMult(_vm->_mult->_frameStart + VAR(57), _vm->_mult->_frameStart + VAR(57), 1, - handleMouse); - } - - if (_vm->_inter->_soundEndTimeKey != 0 - && _vm->_util->getTimeKey() >= _vm->_inter->_soundEndTimeKey) { - _vm->_snd->stopSound(_vm->_inter->_soundStopVal); - _vm->_inter->_soundEndTimeKey = 0; - } - - if (_vm->_global->_useMouse == 0) - error("checkKeys: Can't work without mouse!"); - - _vm->_util->getMouseState(pMouseX, pMouseY, pButtons); - - if (*pButtons == 3) - *pButtons = 0; - - return _vm->_util->checkKey(); -} - -int16 Game::checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, - int16 *pResIndex) { - char *savedIP; - int16 resIndex; - int16 key; - int16 oldIndex; - int16 oldId; - uint32 timeKey; - - if (deltaTime >= -1) { - _lastCollKey = 0; - _lastCollAreaIndex = 0; - _lastCollId = 0; - } - - if (pResId != 0) - *pResId = 0; - - resIndex = 0; - - if (_vm->_draw->_cursorIndex == -1 && handleMouse != 0 - && _lastCollKey == 0) { - _lastCollKey = - checkMousePoint(1, &_lastCollId, - &_lastCollAreaIndex); - - if (_lastCollKey != 0 && (_lastCollId & 0x8000) != 0) { - savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = (char *)_totFileData + - _collisionAreas[_lastCollAreaIndex].funcEnter; - - _vm->_inter->funcBlock(0); - _vm->_global->_inter_execPtr = savedIP; - } - } - - if (handleMouse != 0) - _vm->_draw->animateCursor(-1); - - timeKey = _vm->_util->getTimeKey(); - while (1) { - if (_vm->_inter->_terminate) { - if (handleMouse) - _vm->_draw->blitCursor(); - return 0; - } - - if (_vm->_draw->_noInvalidated == 0) { - if (handleMouse) - _vm->_draw->animateCursor(-1); - else - _vm->_draw->blitInvalidated(); - } - - // NOTE: the original asm does the below checkKeys call - // _before_ this check. However, that can cause keypresses to get lost - // since there's a return statement in this check. - // Additionally, I added a 'deltaTime == -1' check there, since - // when this function is called with deltaTime == -1 in inputArea, - // and the return value is then discarded. - if (deltaTime < 0) { - uint32 curtime = _vm->_util->getTimeKey(); - if (deltaTime == -1 || curtime + deltaTime > timeKey) { - if (pResId != 0) - *pResId = 0; - - if (pResIndex != 0) - *pResIndex = 0; - - return 0; - } - } - - key = checkKeys(&_vm->_global->_inter_mouseX, &_vm->_global->_inter_mouseY, - &_mouseButtons, handleMouse); - - if (handleMouse == 0 && _mouseButtons != 0) { - _vm->_util->waitMouseRelease(0); - key = 3; - } - - if (key != 0) { - - if (handleMouse == 1) - _vm->_draw->blitCursor(); - - if (pResId != 0) - *pResId = 0; - - if (pResIndex != 0) - *pResIndex = 0; - - if (_lastCollKey != 0 && - _collisionAreas[_lastCollAreaIndex].funcLeave != 0) { - savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = (char *)_totFileData + - _collisionAreas[_lastCollAreaIndex].funcLeave; - - _vm->_inter->funcBlock(0); - _vm->_global->_inter_execPtr = savedIP; - } - - _lastCollKey = 0; - if (key != 0) - return key; - } - - if (handleMouse != 0) { - if (_mouseButtons != 0) { - oldIndex = 0; - - _vm->_draw->animateCursor(2); - if (deltaTime <= 0) { - if (handleMouse == 1) - _vm->_util->waitMouseRelease(1); - } else if (deltaTime > 0) { - _vm->_util->delay(deltaTime); - } - - _vm->_draw->animateCursor(-1); - if (pResId != 0) - *pResId = 0; - - key = checkMousePoint(0, pResId, &resIndex); - - if (pResIndex != 0) - *pResIndex = resIndex; - - if (key != 0 || (pResId != 0 && *pResId != 0)) { - if (handleMouse == 1 && (deltaTime <= 0 - || _mouseButtons == 0)) - _vm->_draw->blitCursor(); - - if (_lastCollKey != 0 && - _collisionAreas[_lastCollAreaIndex].funcLeave != 0) { - savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = - (char *)_totFileData + - _collisionAreas[_lastCollAreaIndex].funcLeave; - - _vm->_inter->funcBlock(0); - _vm->_global->_inter_execPtr = savedIP; - } - _lastCollKey = 0; - return key; - } - - if (_lastCollKey != 0 && - _collisionAreas[_lastCollAreaIndex].funcLeave != 0) { - savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = - (char *)_totFileData + - _collisionAreas[_lastCollAreaIndex].funcLeave; - - _vm->_inter->funcBlock(0); - _vm->_global->_inter_execPtr = savedIP; - } - - _lastCollKey = - checkMousePoint(1, &_lastCollId, - &_lastCollAreaIndex); - - if (_lastCollKey != 0 - && (_lastCollId & 0x8000) != 0) { - savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = - (char *)_totFileData + - _collisionAreas[_lastCollAreaIndex].funcEnter; - - _vm->_inter->funcBlock(0); - _vm->_global->_inter_execPtr = savedIP; - } - } else { - - if (handleMouse != 0 && - (_vm->_global->_inter_mouseX != _vm->_draw->_cursorX - || _vm->_global->_inter_mouseY != _vm->_draw->_cursorY)) { - oldIndex = _lastCollAreaIndex; - oldId = _lastCollId; - - key = - checkMousePoint(1, - &_lastCollId, - &_lastCollAreaIndex); - - if (key != _lastCollKey) { - if (_lastCollKey != 0 - && (oldId & 0x8000) != 0) { - savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = (char *)_totFileData + - _collisionAreas[oldIndex].funcLeave; - - _vm->_inter->funcBlock(0); - _vm->_global->_inter_execPtr = savedIP; - } - - _lastCollKey = key; - if (_lastCollKey != 0 && (_lastCollId & 0x8000) != 0) { - savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = (char *)_totFileData + - _collisionAreas[_lastCollAreaIndex].funcEnter; - - _vm->_inter->funcBlock(0); - _vm->_global->_inter_execPtr = savedIP; - } - } - } - } - } - - if (handleMouse != 0) - _vm->_draw->animateCursor(-1); - - _vm->_util->delay(10); - - _vm->_snd->loopSounds(); - } -} - int16 Game::inputArea(int16 xPos, int16 yPos, int16 width, int16 height, int16 backColor, int16 frontColor, char *str, int16 fontIndex, char inpType, int16 *pTotTime) { int16 handleMouse; @@ -1575,54 +1291,6 @@ void Game::collisionsBlock(void) { _vm->_global->_inter_execPtr = savedIP; } -void Game::prepareStart(void) { - int16 i; - - clearCollisions(); - - _vm->_global->_pPaletteDesc->unused2 = _vm->_draw->_unusedPalette2; - _vm->_global->_pPaletteDesc->unused1 = _vm->_draw->_unusedPalette1; - _vm->_global->_pPaletteDesc->vgaPal = _vm->_draw->_vgaPalette; - - _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); - - _vm->_draw->_backSurface = _vm->_video->initSurfDesc(_vm->_global->_videoMode, 320, 200, 0); - - _vm->_video->fillRect(_vm->_draw->_backSurface, 0, 0, 319, 199, 1); - _vm->_draw->_frontSurface = _vm->_global->_pPrimarySurfDesc; - _vm->_video->fillRect(_vm->_draw->_frontSurface, 0, 0, 319, 199, 1); - - _vm->_util->setMousePos(152, 92); - - _vm->_draw->_cursorX = 152; - _vm->_global->_inter_mouseX = 152; - - _vm->_draw->_cursorY = 92; - _vm->_global->_inter_mouseY = 92; - _vm->_draw->_invalidatedCount = 0; - _vm->_draw->_noInvalidated = 1; - _vm->_draw->_applyPal = 0; - _vm->_draw->_paletteCleared = 0; - _vm->_draw->_cursorWidth = 16; - _vm->_draw->_cursorHeight = 16; - _vm->_draw->_transparentCursor = 1; - - for (i = 0; i < 40; i++) { - _vm->_draw->_cursorAnimLow[i] = -1; - _vm->_draw->_cursorAnimDelays[i] = 0; - _vm->_draw->_cursorAnimHigh[i] = 0; - } - - _vm->_draw->_cursorAnimLow[1] = 0; - _vm->_draw->_cursorSprites = _vm->_video->initSurfDesc(_vm->_global->_videoMode, 32, 16, 2); - _vm->_draw->_cursorBack = _vm->_video->initSurfDesc(_vm->_global->_videoMode, 16, 16, 0); - _vm->_draw->_renderFlags = 0; - _vm->_draw->_backDeltaX = 0; - _vm->_draw->_backDeltaY = 0; - - _startTimeKey = _vm->_util->getTimeKey(); -} - void Game::loadTotFile(char *path) { int16 handle; @@ -1746,7 +1414,7 @@ void Game::totSub(int8 flags, char *newTotFile) { if (_vm->_inter->_terminate != 2) _vm->_inter->_terminate = 0; - warning("GOB2 Stub! sub_18072"); + popCollisions(); if ((flags & 1) && (_vm->_global->_inter_variables != 0)) delete[] _vm->_global->_inter_variables; @@ -1769,13 +1437,15 @@ void Game::totSub(int8 flags, char *newTotFile) { strcat(_curExtFile, ".EXT"); } -char *Game::loadLocTexts(void) { - char locTextFile[20]; - int16 handle; +int16 Game::openLocTextFile(char *locTextFile, int language) { + int n; - strcpy(locTextFile, _curTotFile); - locTextFile[strlen(locTextFile) - 4] = 0; - switch (_vm->_global->_language) { + n = strlen(locTextFile); + if (n < 4) + return -1; + + locTextFile[n - 4] = 0; + switch (language) { case 0: strcat(locTextFile, ".dat"); break; @@ -1804,8 +1474,26 @@ char *Game::loadLocTexts(void) { strcat(locTextFile, ".ang"); break; } + return _vm->_dataio->openData(locTextFile); +} + +char *Game::loadLocTexts(void) { + char locTextFile[20]; + int16 handle; + int i; + + strcpy(locTextFile, _curTotFile); + + handle = openLocTextFile(locTextFile, _vm->_global->_language); + if ((handle < 0) && !scumm_stricmp(_vm->_game->_curTotFile, "intro0.tot")) { + warning("Your game version doesn't support the requested language, using the first one available"); + for (i = 0; i < 10; i++) { + handle = openLocTextFile(locTextFile, i); + if (handle >= 0) + _vm->_global->_language = i; + } + } - handle = _vm->_dataio->openData(locTextFile); if (handle >= 0) { _vm->_dataio->closeData(handle); return _vm->_dataio->getData(locTextFile); @@ -1813,4 +1501,137 @@ char *Game::loadLocTexts(void) { return 0; } +void Game::setCollisions(void) { + char *savedIP; + int16 left; + int16 top; + int16 width; + int16 height; + Collision *collArea; + + for (collArea = _collisionAreas; collArea->left != -1; collArea++) { + if (((collArea->id & 0xC000) != 0x8000) || (collArea->field_12 == 0)) + continue; + + savedIP = _vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr = _totFileData + collArea->field_12; + left = _vm->_parse->parseValExpr(); + top = _vm->_parse->parseValExpr(); + width = _vm->_parse->parseValExpr(); + height = _vm->_parse->parseValExpr(); + if ((_vm->_draw->_renderFlags != 8) && (left != -1)) { + left += _vm->_draw->_backDeltaX; + top += _vm->_draw->_backDeltaY; + } + if (_vm->_draw->_word_2E8E2 != 2) { + _vm->_draw->adjustCoords(0, &left, &top); + if ((collArea->flags & 0x0F) < 3) + _vm->_draw->adjustCoords(2, &width, &height); + else { + height &= 0xFFFE; + _vm->_draw->adjustCoords(2, 0, &height); + } + } + collArea->left = left; + collArea->top = top; + collArea->right = left + width - 1; + collArea->bottom = top + height - 1; + _vm->_global->_inter_execPtr = savedIP; + } +} + +void Game::collSub(int16 offset) { + char *savedIP; + int16 collStackSize; + + savedIP = _vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr = _totFileData + offset; + + _shouldPushColls = 1; + collStackSize = _collStackSize; + + _vm->_inter->funcBlock(0); + + if (collStackSize != _collStackSize) + popCollisions(); + + _shouldPushColls = 0; + _vm->_global->_inter_execPtr = savedIP; + setCollisions(); +} + +void Game::collAreaSub(int16 index, int8 enter) { + uint16 collId; + + collId = _collisionAreas[index].id & 0xF000; + + if ((collId == 0xA000) || (collId == 0x9000)) + WRITE_VAR(17, collId); + else if (enter == 0) + WRITE_VAR(17, -(collId & 0x0FFF)); + else + WRITE_VAR(17, collId & 0x0FFF); + + if (enter != 0) { + if (_collisionAreas[index].funcEnter != 0) + collSub(_collisionAreas[index].funcEnter); + } else { + if (_collisionAreas[index].funcLeave != 0) + collSub(_collisionAreas[index].funcLeave); + } +} + +void Game::sub_ADD2(void) { + _word_2FC9C = 0; + _word_2FC9E = 0; + + if (_word_2E51F != 0) { + _off_2E51B = new Video::SurfaceDesc; + memcpy(_off_2E51B, _vm->_draw->_frontSurface, sizeof(Video::SurfaceDesc)); + _off_2E51B->height = _vm->_global->_primaryHeight - _word_2E51F; + _vm->_draw->_frontSurface->height -= _off_2E51B->height; + _vm->_draw->_frontSurface->vidPtr = + _off_2E51B->vidPtr + ((_off_2E51B->width * _off_2E51B->height) / 4); + + _off_2E517 = new Video::SurfaceDesc; + memcpy(_off_2E517, _off_2E51B, sizeof(Video::SurfaceDesc)); + _off_2E517->width = _vm->_global->_primaryWidth; + _off_2E517->vidPtr = _vm->_draw->_frontSurface->vidPtr + + ((_vm->_draw->_frontSurface->width * _vm->_draw->_frontSurface->height ) / 4); + } + _vm->_draw->initBigSprite(21, 320, 200, 0); + _vm->_draw->_backSurface = _vm->_draw->_spritesArray[21]; + _vm->_video->clearSurf(_vm->_draw->_backSurface); + + _vm->_draw->initBigSprite(23, 32, 16, 2); + // TODO: That assignment is not in the original assembly, why? + _vm->_draw->_cursorSpritesBack = _vm->_draw->_spritesArray[23]; + _vm->_draw->_cursorSprites = _vm->_draw->_cursorSpritesBack; + _vm->_draw->_cursorBack = _vm->_video->initSurfDesc(_vm->_global->_videoMode, 16, 16, 0); + + _vm->_draw->_spritesArray[20] = _vm->_draw->_frontSurface; + _vm->_draw->_spritesArray[21] = _vm->_draw->_backSurface; + +/* if (_word_2E51F != 0) { + dword_2F92D = _off_2E51B; + dword_2F931 = _off_2E517; + }*/ +} + +void Game::sub_BB28(void) { + _vm->_draw->freeSprite(23); + _vm->_video->freeSurfDesc(_vm->_draw->_cursorBack); + if (_off_2E51B != 0) { + memcpy(_vm->_draw->_frontSurface, _off_2E51B, sizeof(Video::SurfaceDesc)); + _vm->_draw->_frontSurface->width = 320; + _vm->_draw->_frontSurface->height = 200; + delete _off_2E51B; + delete _off_2E517; + _off_2E51B = 0; + _off_2E517 = 0; + } + if (_vm->_draw->_frontSurface != _vm->_draw->_backSurface) + _vm->_draw->freeSprite(21); +} + } // End of namespace Gob diff --git a/engines/gob/game.h b/engines/gob/game.h index 713051cc86..d0c70e5fba 100644 --- a/engines/gob/game.h +++ b/engines/gob/game.h @@ -24,6 +24,7 @@ #define GOB_GAME_H #include "gob/sound.h" +#include "gob/video.h" namespace Gob { @@ -97,7 +98,7 @@ public: TotResTable *_totResourceTable; Collision *_collisionAreas; - Collision *_collStack[3]; + Collision *_collStack[5]; TotTextTable *_totTextData; @@ -142,10 +143,6 @@ public: void capturePop(char doDraw); void freeSoundSlot(int16 slot); - int16 checkKeys(int16 *pMousex, int16 *pMouseY, int16 *pButtons, - char handleMouse); - int16 checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, - int16 *pResIndex); void freeCollision(int16 id); void loadSound(int16 slot, char *dataPtr); @@ -155,7 +152,6 @@ public: InputDesc * inpDesc); int16 adjustKey(int16 key); void collisionsBlock(void); - void prepareStart(void); void loadTotFile(char *path); void loadExtTable(void); void loadImFile(void); @@ -167,7 +163,20 @@ public: virtual void clearCollisions(void) = 0; virtual void addNewCollision(int16 id, int16 left, int16 top, int16 right, int16 bottom, int16 flags, int16 key, int16 funcEnter, int16 funcLeave) = 0; - + virtual int16 checkKeys(int16 *pMousex, int16 *pMouseY, int16 *pButtons, + char handleMouse) = 0; + virtual int16 checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, + int16 *pResIndex) = 0; + virtual void prepareStart(void) = 0; + + int8 _byte_2FC9B; + int16 _word_2FC9C; + int16 _word_2FC9E; + int16 _word_2E51F; + Video::SurfaceDesc *_off_2E51B; + Video::SurfaceDesc *_off_2E517; + void sub_ADD2(void); + void sub_BB28(void); protected: int16 _lastCollKey; @@ -185,7 +194,7 @@ protected: char _curImaFile[18]; int16 _collStackSize; - int16 _collStackElemSizes[3]; + int16 _collStackElemSizes[5]; char _shouldPushColls; @@ -197,9 +206,14 @@ protected: GobEngine *_vm; - void pushCollisions(char all); - void popCollisions(void); int16 checkMousePoint(int16 all, int16 *resId, int16 *resIndex); + void setCollisions(void); + void collSub(int16 offset); + void collAreaSub(int16 index, int8 enter); + int16 openLocTextFile(char *locTextFile, int language); + + virtual void pushCollisions(char all) = 0; + virtual void popCollisions(void) = 0; }; class Game_v1 : public Game { @@ -208,9 +222,18 @@ public: virtual void clearCollisions(void); virtual void addNewCollision(int16 id, int16 left, int16 top, int16 right, int16 bottom, int16 flags, int16 key, int16 funcEnter, int16 funcLeave); + virtual int16 checkKeys(int16 *pMousex, int16 *pMouseY, int16 *pButtons, + char handleMouse); + virtual int16 checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, + int16 *pResIndex); + virtual void prepareStart(void); Game_v1(GobEngine *vm); virtual ~Game_v1() {}; + +protected: + virtual void pushCollisions(char all); + virtual void popCollisions(void); }; class Game_v2 : public Game_v1 { @@ -219,9 +242,26 @@ public: virtual void clearCollisions(void); virtual void addNewCollision(int16 id, int16 left, int16 top, int16 right, int16 bottom, int16 flags, int16 key, int16 funcEnter, int16 funcLeave); + virtual int16 checkKeys(int16 *pMousex, int16 *pMouseY, int16 *pButtons, + char handleMouse); + virtual int16 checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, + int16 *pResIndex); + virtual void prepareStart(void); Game_v2(GobEngine *vm); virtual ~Game_v2() {}; + +protected: + struct CollLast { + int16 key; + int16 id; + int16 areaIndex; + }; + + CollLast _collLasts[5]; + + virtual void pushCollisions(char all); + virtual void popCollisions(void); }; } // End of namespace Gob diff --git a/engines/gob/game_v1.cpp b/engines/gob/game_v1.cpp index 2050fae242..8b97027d2d 100644 --- a/engines/gob/game_v1.cpp +++ b/engines/gob/game_v1.cpp @@ -290,4 +290,344 @@ void Game_v1::addNewCollision(int16 id, int16 left, int16 top, int16 right, int1 error("addNewCollision: Collision array full!\n"); } +void Game_v1::pushCollisions(char all) { + Collision *srcPtr; + Collision *destPtr; + int16 size; + + debugC(1, DEBUG_COLLISIONS, "pushCollisions"); + for (size = 0, srcPtr = _collisionAreas; srcPtr->left != -1; + srcPtr++) { + if (all || (srcPtr->id & 0x8000)) + size++; + } + + destPtr = new Collision[size]; + _collStack[_collStackSize] = destPtr; + _collStackElemSizes[_collStackSize] = size; + _collStackSize++; + + for (srcPtr = _collisionAreas; srcPtr->left != -1; srcPtr++) { + if (all || (srcPtr->id & 0x8000)) { + memcpy(destPtr, srcPtr, sizeof(Collision)); + srcPtr->left = -1; + destPtr++; + } + } +} + +void Game_v1::popCollisions(void) { + Collision *destPtr; + Collision *srcPtr; + + debugC(1, DEBUG_COLLISIONS, "popCollision"); + + _collStackSize--; + for (destPtr = _collisionAreas; destPtr->left != -1; destPtr++); + + srcPtr = _collStack[_collStackSize]; + memcpy(destPtr, srcPtr, + _collStackElemSizes[_collStackSize] * + sizeof(Collision)); + + delete[] _collStack[_collStackSize]; +} + +int16 Game_v1::checkKeys(int16 *pMouseX, int16 *pMouseY, int16 *pButtons, char handleMouse) { + _vm->_util->processInput(); + + if (VAR(58) != 0) { + if (_vm->_mult->_frameStart != (int)VAR(58) - 1) + _vm->_mult->_frameStart++; + else + _vm->_mult->_frameStart = 0; + + _vm->_mult->playMult(_vm->_mult->_frameStart + VAR(57), _vm->_mult->_frameStart + VAR(57), 1, + handleMouse); + } + + if (_vm->_inter->_soundEndTimeKey != 0 + && _vm->_util->getTimeKey() >= _vm->_inter->_soundEndTimeKey) { + _vm->_snd->stopSound(_vm->_inter->_soundStopVal); + _vm->_inter->_soundEndTimeKey = 0; + } + + if (_vm->_global->_useMouse == 0) + error("checkKeys: Can't work without mouse!"); + + _vm->_util->getMouseState(pMouseX, pMouseY, pButtons); + + if (*pButtons == 3) + *pButtons = 0; + + return _vm->_util->checkKey(); +} + +int16 Game_v1::checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, + int16 *pResIndex) { + char *savedIP; + int16 resIndex; + int16 key; + int16 oldIndex; + int16 oldId; + uint32 timeKey; + + if (deltaTime >= -1) { + _lastCollKey = 0; + _lastCollAreaIndex = 0; + _lastCollId = 0; + } + + if (pResId != 0) + *pResId = 0; + + resIndex = 0; + + if (_vm->_draw->_cursorIndex == -1 && handleMouse != 0 + && _lastCollKey == 0) { + _lastCollKey = + checkMousePoint(1, &_lastCollId, + &_lastCollAreaIndex); + + if (_lastCollKey != 0 && (_lastCollId & 0x8000) != 0) { + savedIP = _vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr = (char *)_totFileData + + _collisionAreas[_lastCollAreaIndex].funcEnter; + + _vm->_inter->funcBlock(0); + _vm->_global->_inter_execPtr = savedIP; + } + } + + if (handleMouse != 0) + _vm->_draw->animateCursor(-1); + + timeKey = _vm->_util->getTimeKey(); + while (1) { + if (_vm->_inter->_terminate) { + if (handleMouse) + _vm->_draw->blitCursor(); + return 0; + } + + if (_vm->_draw->_noInvalidated == 0) { + if (handleMouse) + _vm->_draw->animateCursor(-1); + else + _vm->_draw->blitInvalidated(); + } + + // NOTE: the original asm does the below checkKeys call + // _before_ this check. However, that can cause keypresses to get lost + // since there's a return statement in this check. + // Additionally, I added a 'deltaTime == -1' check there, since + // when this function is called with deltaTime == -1 in inputArea, + // and the return value is then discarded. + if (deltaTime < 0) { + uint32 curtime = _vm->_util->getTimeKey(); + if (deltaTime == -1 || curtime + deltaTime > timeKey) { + if (pResId != 0) + *pResId = 0; + + if (pResIndex != 0) + *pResIndex = 0; + + return 0; + } + } + + key = checkKeys(&_vm->_global->_inter_mouseX, &_vm->_global->_inter_mouseY, + &_mouseButtons, handleMouse); + + if (handleMouse == 0 && _mouseButtons != 0) { + _vm->_util->waitMouseRelease(0); + key = 3; + } + + if (key != 0) { + + if (handleMouse == 1) + _vm->_draw->blitCursor(); + + if (pResId != 0) + *pResId = 0; + + if (pResIndex != 0) + *pResIndex = 0; + + if (_lastCollKey != 0 && + _collisionAreas[_lastCollAreaIndex].funcLeave != 0) { + savedIP = _vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr = (char *)_totFileData + + _collisionAreas[_lastCollAreaIndex].funcLeave; + + _vm->_inter->funcBlock(0); + _vm->_global->_inter_execPtr = savedIP; + } + + _lastCollKey = 0; + if (key != 0) + return key; + } + + if (handleMouse != 0) { + if (_mouseButtons != 0) { + oldIndex = 0; + + _vm->_draw->animateCursor(2); + if (deltaTime <= 0) { + if (handleMouse == 1) + _vm->_util->waitMouseRelease(1); + } else if (deltaTime > 0) { + _vm->_util->delay(deltaTime); + } + + _vm->_draw->animateCursor(-1); + if (pResId != 0) + *pResId = 0; + + key = checkMousePoint(0, pResId, &resIndex); + + if (pResIndex != 0) + *pResIndex = resIndex; + + if (key != 0 || (pResId != 0 && *pResId != 0)) { + if (handleMouse == 1 && (deltaTime <= 0 + || _mouseButtons == 0)) + _vm->_draw->blitCursor(); + + if (_lastCollKey != 0 && + _collisionAreas[_lastCollAreaIndex].funcLeave != 0) { + savedIP = _vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr = + (char *)_totFileData + + _collisionAreas[_lastCollAreaIndex].funcLeave; + + _vm->_inter->funcBlock(0); + _vm->_global->_inter_execPtr = savedIP; + } + _lastCollKey = 0; + return key; + } + + if (_lastCollKey != 0 && + _collisionAreas[_lastCollAreaIndex].funcLeave != 0) { + savedIP = _vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr = + (char *)_totFileData + + _collisionAreas[_lastCollAreaIndex].funcLeave; + + _vm->_inter->funcBlock(0); + _vm->_global->_inter_execPtr = savedIP; + } + + _lastCollKey = + checkMousePoint(1, &_lastCollId, + &_lastCollAreaIndex); + + if (_lastCollKey != 0 + && (_lastCollId & 0x8000) != 0) { + savedIP = _vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr = + (char *)_totFileData + + _collisionAreas[_lastCollAreaIndex].funcEnter; + + _vm->_inter->funcBlock(0); + _vm->_global->_inter_execPtr = savedIP; + } + } else { + + if (handleMouse != 0 && + (_vm->_global->_inter_mouseX != _vm->_draw->_cursorX + || _vm->_global->_inter_mouseY != _vm->_draw->_cursorY)) { + oldIndex = _lastCollAreaIndex; + oldId = _lastCollId; + + key = + checkMousePoint(1, + &_lastCollId, + &_lastCollAreaIndex); + + if (key != _lastCollKey) { + if (_lastCollKey != 0 + && (oldId & 0x8000) != 0) { + savedIP = _vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr = (char *)_totFileData + + _collisionAreas[oldIndex].funcLeave; + + _vm->_inter->funcBlock(0); + _vm->_global->_inter_execPtr = savedIP; + } + + _lastCollKey = key; + if (_lastCollKey != 0 && (_lastCollId & 0x8000) != 0) { + savedIP = _vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr = (char *)_totFileData + + _collisionAreas[_lastCollAreaIndex].funcEnter; + + _vm->_inter->funcBlock(0); + _vm->_global->_inter_execPtr = savedIP; + } + } + } + } + } + + if (handleMouse != 0) + _vm->_draw->animateCursor(-1); + + _vm->_util->delay(10); + + _vm->_snd->loopSounds(); + } +} + +void Game_v1::prepareStart(void) { + int16 i; + + clearCollisions(); + + _vm->_global->_pPaletteDesc->unused2 = _vm->_draw->_unusedPalette2; + _vm->_global->_pPaletteDesc->unused1 = _vm->_draw->_unusedPalette1; + _vm->_global->_pPaletteDesc->vgaPal = _vm->_draw->_vgaPalette; + + _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); + + _vm->_draw->_backSurface = _vm->_video->initSurfDesc(_vm->_global->_videoMode, 320, 200, 0); + + _vm->_video->fillRect(_vm->_draw->_backSurface, 0, 0, 319, 199, 1); + _vm->_draw->_frontSurface = _vm->_global->_pPrimarySurfDesc; + _vm->_video->fillRect(_vm->_draw->_frontSurface, 0, 0, 319, 199, 1); + + _vm->_util->setMousePos(152, 92); + + _vm->_draw->_cursorX = 152; + _vm->_global->_inter_mouseX = 152; + + _vm->_draw->_cursorY = 92; + _vm->_global->_inter_mouseY = 92; + _vm->_draw->_invalidatedCount = 0; + _vm->_draw->_noInvalidated = 1; + _vm->_draw->_applyPal = 0; + _vm->_draw->_paletteCleared = 0; + _vm->_draw->_cursorWidth = 16; + _vm->_draw->_cursorHeight = 16; + _vm->_draw->_transparentCursor = 1; + + for (i = 0; i < 40; i++) { + _vm->_draw->_cursorAnimLow[i] = -1; + _vm->_draw->_cursorAnimDelays[i] = 0; + _vm->_draw->_cursorAnimHigh[i] = 0; + } + + _vm->_draw->_cursorAnimLow[1] = 0; + _vm->_draw->_cursorSprites = _vm->_video->initSurfDesc(_vm->_global->_videoMode, 32, 16, 2); + _vm->_draw->_cursorBack = _vm->_video->initSurfDesc(_vm->_global->_videoMode, 16, 16, 0); + _vm->_draw->_renderFlags = 0; + _vm->_draw->_backDeltaX = 0; + _vm->_draw->_backDeltaY = 0; + + _startTimeKey = _vm->_util->getTimeKey(); +} + } // End of namespace Gob diff --git a/engines/gob/game_v2.cpp b/engines/gob/game_v2.cpp index 6a47288c0e..8c9819efb8 100644 --- a/engines/gob/game_v2.cpp +++ b/engines/gob/game_v2.cpp @@ -94,7 +94,7 @@ void Game_v2::playTot(int16 skipPlay) { _vm->_draw->_spritesArray[20] = _vm->_draw->_frontSurface; _vm->_draw->_spritesArray[21] = _vm->_draw->_backSurface; - _vm->_draw->_spritesArray[23] = _vm->_draw->_cursorSprites; + _vm->_draw->_cursorSpritesBack = _vm->_draw->_cursorSprites; for (i = 0; i < 20; i++) _soundSamples[i] = 0; @@ -299,4 +299,392 @@ void Game_v2::addNewCollision(int16 id, int16 left, int16 top, int16 right, int1 error("addNewCollision: Collision array full!\n"); } +void Game_v2::pushCollisions(char all) { + Collision *srcPtr; + Collision *destPtr; + int16 size; + + debugC(1, DEBUG_COLLISIONS, "pushCollisions"); + for (size = 0, srcPtr = _collisionAreas; srcPtr->left != -1; + srcPtr++) { + if (all || (srcPtr->id >= 20)) + size++; + } + + destPtr = new Collision[size]; + _collStack[_collStackSize] = destPtr; + _collStackElemSizes[_collStackSize] = size; + + if (_shouldPushColls != 0) + _collStackElemSizes[_collStackSize] |= 0x8000; + + _shouldPushColls = 0; + _collLasts[_collStackSize].key = _lastCollKey; + _collLasts[_collStackSize].id = _lastCollId; + _collLasts[_collStackSize].areaIndex = _lastCollAreaIndex; + _collStackSize++; + + for (srcPtr = _collisionAreas; srcPtr->left != -1; srcPtr++) { + if (all || (srcPtr->id >= 20)) { + memcpy(destPtr, srcPtr, sizeof(Collision)); + srcPtr->left = -1; + destPtr++; + } + } +} + +void Game_v2::popCollisions(void) { + Collision *destPtr; + Collision *srcPtr; + + debugC(1, DEBUG_COLLISIONS, "popCollision"); + + _collStackSize--; + + _shouldPushColls = _collStackElemSizes[_collStackSize] & 0x8000 ? 1 : 0; + _collStackElemSizes[_collStackSize] &= 0x7FFF; + + _lastCollKey = _collLasts[_collStackSize].key; + _lastCollId = _collLasts[_collStackSize].id; + _lastCollAreaIndex = _collLasts[_collStackSize].areaIndex; + + for (destPtr = _collisionAreas; destPtr->left != -1; destPtr++); + + srcPtr = _collStack[_collStackSize]; + memcpy(destPtr, srcPtr, + _collStackElemSizes[_collStackSize] * + sizeof(Collision)); + + delete[] _collStack[_collStackSize]; +} + +int16 Game_v2::checkKeys(int16 *pMouseX, int16 *pMouseY, int16 *pButtons, char handleMouse) { + _vm->_util->processInput(); + + if ((_vm->_global->_inter_variables != 0) && (VAR(58) != 0)) { + if (_vm->_mult->_frameStart != (int)VAR(58) - 1) + _vm->_mult->_frameStart++; + else + _vm->_mult->_frameStart = 0; + + _vm->_mult->playMult(_vm->_mult->_frameStart + VAR(57), _vm->_mult->_frameStart + VAR(57), 1, + handleMouse); + } + + if (_vm->_inter->_soundEndTimeKey != 0 + && _vm->_util->getTimeKey() >= _vm->_inter->_soundEndTimeKey) { + _vm->_snd->stopSound(_vm->_inter->_soundStopVal); + _vm->_inter->_soundEndTimeKey = 0; + } + + if (_vm->_global->_useMouse == 0) + error("checkKeys: Can't work without mouse!"); + + _vm->_util->getMouseState(pMouseX, pMouseY, pButtons); + + if (*pButtons == 3) + *pButtons = 0; + + return _vm->_util->checkKey(); +} + +int16 Game_v2::checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, + int16 *pResIndex) { + int16 resIndex; + int16 key; + int16 oldIndex; + int16 oldId; + uint32 timeKey; + + if (deltaTime >= -1) { + _lastCollKey = 0; + _lastCollAreaIndex = 0; + _lastCollId = 0; + } + + if (pResId != 0) + *pResId = 0; + + resIndex = 0; + + if (_vm->_draw->_cursorIndex == -1 && handleMouse != 0 + && _lastCollKey == 0) { + _lastCollKey = + checkMousePoint(1, &_lastCollId, + &_lastCollAreaIndex); + + if ((_lastCollKey != 0) && (_lastCollId & 0x8000)) + collAreaSub(_lastCollAreaIndex, 1); + } + + if (handleMouse != 0) + _vm->_draw->animateCursor(-1); + + timeKey = _vm->_util->getTimeKey(); + while (1) { + if (_vm->_inter->_terminate) { + if (handleMouse) + _vm->_draw->blitCursor(); + return 0; + } + + if (_vm->_draw->_noInvalidated == 0) { + if (handleMouse) + _vm->_draw->animateCursor(-1); + else + _vm->_draw->blitInvalidated(); + } + + // NOTE: the original asm does the below checkKeys call + // _before_ this check. However, that can cause keypresses to get lost + // since there's a return statement in this check. + // Additionally, I added a 'deltaTime == -1' check there, since + // when this function is called with deltaTime == -1 in inputArea, + // and the return value is then discarded. + if (deltaTime < 0) { + uint32 curtime = _vm->_util->getTimeKey(); + if (deltaTime == -1 || curtime + deltaTime > timeKey) { + if (pResId != 0) + *pResId = 0; + + if (pResIndex != 0) + *pResIndex = 0; + + return 0; + } + } + + key = checkKeys(&_vm->_global->_inter_mouseX, &_vm->_global->_inter_mouseY, + &_mouseButtons, handleMouse); + + // TODO: What of this is needed? + int16 width; + int16 height; + int16 sWidth; + int16 sHeight; + int16 cursorRight; + int16 cursorBottom; + int16 oldWord_2FC9C; + int16 oldWord_2FC9E; + if ((_vm->_video->_extraMode) && (handleMouse != 0)) { + width = _vm->_draw->_frontSurface->width; + height = _vm->_draw->_frontSurface->height; + if ((width > _vm->_global->_primaryWidth) || (height > _vm->_global->_primaryHeight) + || ((_off_2E51B != 0) && (height > _off_2E51B->height))) { + sWidth = _vm->_global->_primaryWidth; + sHeight = _vm->_global->_primaryHeight; + if (_off_2E51B != 0) + sHeight -= _off_2E51B->height; + oldWord_2FC9E = _word_2FC9E; + oldWord_2FC9C = _word_2FC9C; + if ((width > sWidth) && (_vm->_global->_inter_mouseX >= _word_2FC9E)) { + cursorRight = _vm->_global->_inter_mouseX + _vm->_draw->_cursorWidth; + if (cursorRight > (_word_2FC9E + sWidth)) + _word_2FC9E = MIN(cursorRight - sWidth, width - sWidth); + } else if(_vm->_global->_inter_mouseX < _word_2FC9E) + _word_2FC9E = _vm->_global->_inter_mouseX; + height = _vm->_draw->_frontSurface->height; + if ((height > sHeight) && (_vm->_global->_inter_mouseY >= _word_2FC9C)) { + cursorBottom = _vm->_global->_inter_mouseY + _vm->_draw->_cursorHeight; + if (cursorBottom > (_word_2FC9C + sHeight)) + _word_2FC9C = MIN(cursorBottom - sHeight, height - sHeight); + } else if(_vm->_global->_inter_mouseY < _word_2FC9C) + _word_2FC9C = _vm->_global->_inter_mouseY; + if ((oldWord_2FC9E != _word_2FC9E) || (oldWord_2FC9C != _word_2FC9C)) { + if (_byte_2FC9B == 0) { + _word_2FC9E = oldWord_2FC9E; + _word_2FC9C = oldWord_2FC9C; + if ((_vm->_draw->_frontSurface->width > sWidth) && + (_vm->_global->_inter_mouseX >= oldWord_2FC9E)) { + if ((_vm->_global->_inter_mouseX + _vm->_draw->_cursorWidth) > + (_word_2FC9E + sWidth)) + _vm->_global->_inter_mouseX = _word_2FC9E + sWidth - _vm->_draw->_cursorWidth; + } else if(_vm->_global->_inter_mouseX < oldWord_2FC9E) + _vm->_global->_inter_mouseX = oldWord_2FC9E; + + if ((_vm->_draw->_frontSurface->height > sHeight) && + (_vm->_global->_inter_mouseY >= _word_2FC9C)) { + if ((_vm->_global->_inter_mouseY + _vm->_draw->_cursorHeight) > + (_word_2FC9C + sHeight)) + _vm->_global->_inter_mouseY = _word_2FC9C + sHeight - _vm->_draw->_cursorHeight; + } else if(_vm->_global->_inter_mouseY < oldWord_2FC9E) + _vm->_global->_inter_mouseY = _word_2FC9C; + } else { + if (oldWord_2FC9E > _word_2FC9E) { + _vm->_global->_inter_mouseX += (oldWord_2FC9E - _word_2FC9E) / 2; + _word_2FC9E += (oldWord_2FC9E - _word_2FC9E) / 2; + } else { + _vm->_global->_inter_mouseX -= (_word_2FC9E - oldWord_2FC9E) / 2; + _word_2FC9E -= (_word_2FC9E - oldWord_2FC9E) / 2; + } + if (oldWord_2FC9C > _word_2FC9C) { + _vm->_global->_inter_mouseY += (oldWord_2FC9C - _word_2FC9C) / 2; + _word_2FC9C += (oldWord_2FC9C - _word_2FC9C) / 2; + if (_word_2FC9C < 2) + _word_2FC9C = 0; + } else { + _vm->_global->_inter_mouseY -= (_word_2FC9C - oldWord_2FC9C) / 2; + _word_2FC9C -= (_word_2FC9C - oldWord_2FC9C) / 2; + } + if (_off_2E51B == 0) + warning("_vid_setPixelShift(_word_2FC9E, _word_2FC9C);"); + else + warning("_vid_setPixelShift(_word_2FC9E, _word_2FC9C + _off_2E51B->height);"); + } + _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY); + } + } + } + + if (handleMouse == 0 && _mouseButtons != 0) { + _vm->_util->waitMouseRelease(0); + key = 3; + } + + if (key != 0) { + + if (handleMouse == 1) + _vm->_draw->blitCursor(); + + if (pResId != 0) + *pResId = 0; + + if (pResIndex != 0) + *pResIndex = 0; + + if (_lastCollKey != 0) + collAreaSub(_lastCollAreaIndex, 0); + + _lastCollKey = 0; + if (key != 0) + return key; + } + + if (handleMouse != 0) { + if (_mouseButtons != 0) { + oldIndex = 0; + + _vm->_draw->animateCursor(2); + if (deltaTime <= 0) { + if (handleMouse == 1) + _vm->_util->waitMouseRelease(1); + } else if (deltaTime > 0) { + _vm->_util->delay(deltaTime); + } + + _vm->_draw->animateCursor(-1); + if (pResId != 0) + *pResId = 0; + + key = checkMousePoint(0, pResId, &resIndex); + + if (pResIndex != 0) + *pResIndex = resIndex; + + if (key != 0 || (pResId != 0 && *pResId != 0)) { + if (handleMouse == 1 && (deltaTime <= 0 + || _mouseButtons == 0)) + _vm->_draw->blitCursor(); + + if ((_lastCollKey != 0) && (key = _lastCollKey)) + collAreaSub(_lastCollAreaIndex, 0); + + _lastCollKey = 0; + return key; + } + + if (handleMouse & 4) + return key; + + if (_lastCollKey != 0) + collAreaSub(_lastCollAreaIndex, 0); + + _lastCollKey = + checkMousePoint(1, &_lastCollId, + &_lastCollAreaIndex); + + if (_lastCollKey != 0) + collAreaSub(_lastCollAreaIndex, 1); + + // loc_189D3 + if (handleMouse != 0 && + (_vm->_global->_inter_mouseX != _vm->_draw->_cursorX + || _vm->_global->_inter_mouseY != _vm->_draw->_cursorY)) { + oldIndex = _lastCollAreaIndex; + oldId = _lastCollId; + + key = + checkMousePoint(1, + &_lastCollId, + &_lastCollAreaIndex); + + if (key != _lastCollKey) { + if (_lastCollKey != 0) + collAreaSub(_lastCollAreaIndex, 0); + + _lastCollKey = key; + + if (_lastCollKey != 0) + collAreaSub(_lastCollAreaIndex, 1); + } + } + } + } + + if (handleMouse != 0) + _vm->_draw->animateCursor(-1); + + _vm->_util->delay(10); + + _vm->_snd->loopSounds(); + } +} + +void Game_v2::prepareStart(void) { + int16 i; + + clearCollisions(); + + _vm->_global->_pPaletteDesc->unused2 = _vm->_draw->_unusedPalette2; + _vm->_global->_pPaletteDesc->unused1 = _vm->_draw->_unusedPalette1; + _vm->_global->_pPaletteDesc->vgaPal = _vm->_draw->_vgaPalette; + + _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); + + _vm->_draw->_backSurface = _vm->_video->initSurfDesc(_vm->_global->_videoMode, 320, 200, 0); + + sub_ADD2(); + _vm->_video->fillRect(_vm->_draw->_frontSurface, 0, 0, 319, 199, 1); + + _vm->_util->setMousePos(152, 92); + + _vm->_draw->_cursorX = 152; + _vm->_global->_inter_mouseX = 152; + + _vm->_draw->_cursorY = 92; + _vm->_global->_inter_mouseY = 92; + _vm->_draw->_invalidatedCount = 0; + _vm->_draw->_noInvalidated = 1; + // byte_2E521 = 1; + _vm->_draw->_applyPal = 0; + _vm->_draw->_paletteCleared = 0; + _vm->_draw->_cursorWidth = 16; + _vm->_draw->_cursorHeight = 16; + _vm->_draw->_transparentCursor = 1; + + for (i = 0; i < 40; i++) { + _vm->_draw->_cursorAnimLow[i] = -1; + _vm->_draw->_cursorAnimDelays[i] = 0; + _vm->_draw->_cursorAnimHigh[i] = 0; + } + + // byte_2F392 = 0; + + _vm->_draw->_renderFlags = 0; + _vm->_draw->_backDeltaX = 0; + _vm->_draw->_backDeltaY = 0; + + _startTimeKey = _vm->_util->getTimeKey(); +} + } // End of namespace Gob diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index 6fd6255a9a..7fa54445f6 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -197,7 +197,6 @@ int GobEngine::init() { _cdrom = new CDROM(this); _dataio = new DataIO(this); _goblin = new Goblin(this); - _init = new Init(this); _map = new Map(this); _pack = new Pack(); _palanim = new PalAnim(this); @@ -211,6 +210,7 @@ int GobEngine::init() { _draw = new Draw_v1(this); _game = new Game_v1(this); _video = new Video_v1(this); + _init = new Init_v1(this); } else if (_features & Gob::GF_GOB2) { _inter = new Inter_v2(this); @@ -219,6 +219,7 @@ int GobEngine::init() { _draw = new Draw_v2(this); _game = new Game_v2(this); _video = new Video_v2(this); + _init = new Init_v2(this); } else error("GobEngine::init(): Unknown version of game engine"); diff --git a/engines/gob/init.cpp b/engines/gob/init.cpp index a5ba883590..1bfd0aadb5 100644 --- a/engines/gob/init.cpp +++ b/engines/gob/init.cpp @@ -64,46 +64,6 @@ void Init::findBestCfg(void) { _vm->_global->_soundFlags = 0; } -void Init::soundVideo(int32 smallHeap, int16 flag) { - if (_vm->_global->_videoMode != 0x13 && _vm->_global->_videoMode != 0) - error("soundVideo: Video mode 0x%x is not supported!", - _vm->_global->_videoMode); - - //if ((flag & 4) == 0) - // _vm->_video->findVideo(); - - _vm->_global->_mousePresent = 1; - - _vm->_global->_inVM = 0; - - _vm->_global->_presentSound = 0; // FIXME: sound is not supported yet - - _vm->_global->_sprAllocated = 0; - _vm->_gtimer->enableTimer(); - - // _vm->_snd->setResetTimerFlag(debugFlag); // TODO - - if (_vm->_global->_videoMode == 0x13) - _vm->_global->_colorCount = 256; - - _vm->_global->_pPaletteDesc = &_vm->_global->_paletteStruct; - _vm->_global->_pPaletteDesc->vgaPal = _vm->_draw->_vgaPalette; - _vm->_global->_pPaletteDesc->unused1 = _vm->_global->_unusedPalette1; - _vm->_global->_pPaletteDesc->unused2 = _vm->_global->_unusedPalette2; - _vm->_global->_pPrimarySurfDesc = &_vm->_global->_primarySurfDesc; - - if (_vm->_global->_videoMode != 0) - _vm->_video->initSurfDesc(_vm->_global->_videoMode, 320, 200, PRIMARY_SURFACE); - - if (_vm->_global->_soundFlags & MIDI_FLAG) { - _vm->_global->_soundFlags &= _vm->_global->_presentSound; - if (_vm->_global->_presentSound & ADLIB_FLAG) - _vm->_global->_soundFlags |= MIDI_FLAG; - } else { - _vm->_global->_soundFlags &= _vm->_global->_presentSound; - } -} - void Init::cleanup(void) { if (_vm->_global->_debugFlag == 0) _vm->_gtimer->disableTimer(); @@ -154,6 +114,7 @@ memBlocks = word ptr -2*/ _vm->_global->_disableVideoCfg = 0x11; _vm->_global->_disableMouseCfg = 0x15; + soundVideo(1000, 1); handle2 = _vm->_dataio->openData("intro.stk"); diff --git a/engines/gob/init.h b/engines/gob/init.h index 62cbb44f63..b0a7ed2f82 100644 --- a/engines/gob/init.h +++ b/engines/gob/init.h @@ -23,16 +23,19 @@ #ifndef GOB_INIT_H #define GOB_INIT_H +#include "gob/video.h" + namespace Gob { class Init { public: void findBestCfg(void); - void soundVideo(int32 smallHeapSize, int16 flag); - void initGame(char *totFile); + virtual void soundVideo(int32 smallHeapSize, int16 flag) = 0; + Init(GobEngine *vm); + virtual ~Init() {}; protected: Video::PalDesc *_palDesc; @@ -42,6 +45,22 @@ protected: void cleanup(void); }; +class Init_v1 : public Init { +public: + virtual void soundVideo(int32 smallHeapSize, int16 flag); + + Init_v1(GobEngine *vm); + virtual ~Init_v1() {}; +}; + +class Init_v2 : public Init_v1 { +public: + virtual void soundVideo(int32 smallHeapSize, int16 flag); + + Init_v2(GobEngine *vm); + virtual ~Init_v2() {}; +}; + } // End of namespace Gob #endif diff --git a/engines/gob/init_v1.cpp b/engines/gob/init_v1.cpp new file mode 100644 index 0000000000..d24b939153 --- /dev/null +++ b/engines/gob/init_v1.cpp @@ -0,0 +1,79 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2004 Ivan Dubrov + * Copyright (C) 2004-2006 The ScummVM project + * + * 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 "common/stdafx.h" +#include "common/endian.h" + +#include "gob/gob.h" +#include "gob/init.h" +#include "gob/global.h" +#include "gob/timer.h" +#include "gob/video.h" +#include "gob/draw.h" + +namespace Gob { + +Init_v1::Init_v1(GobEngine *vm) : Init(vm) { +} + +void Init_v1::soundVideo(int32 smallHeap, int16 flag) { + if (_vm->_global->_videoMode != 0x13 && _vm->_global->_videoMode != 0) + error("soundVideo: Video mode 0x%x is not supported!", + _vm->_global->_videoMode); + + //if ((flag & 4) == 0) + // _vm->_video->findVideo(); + + _vm->_global->_mousePresent = 1; + + _vm->_global->_inVM = 0; + + _vm->_global->_presentSound = 0; // FIXME: sound is not supported yet + + _vm->_global->_sprAllocated = 0; + _vm->_gtimer->enableTimer(); + + // _vm->_snd->setResetTimerFlag(debugFlag); // TODO + + if (_vm->_global->_videoMode == 0x13) + _vm->_global->_colorCount = 256; + + _vm->_global->_pPaletteDesc = &_vm->_global->_paletteStruct; + _vm->_global->_pPaletteDesc->vgaPal = _vm->_draw->_vgaPalette; + _vm->_global->_pPaletteDesc->unused1 = _vm->_global->_unusedPalette1; + _vm->_global->_pPaletteDesc->unused2 = _vm->_global->_unusedPalette2; + _vm->_global->_pPrimarySurfDesc = &_vm->_global->_primarySurfDesc; + + if (_vm->_global->_videoMode != 0) + _vm->_video->initSurfDesc(_vm->_global->_videoMode, 320, 200, PRIMARY_SURFACE); + + if (_vm->_global->_soundFlags & MIDI_FLAG) { + _vm->_global->_soundFlags &= _vm->_global->_presentSound; + if (_vm->_global->_presentSound & ADLIB_FLAG) + _vm->_global->_soundFlags |= MIDI_FLAG; + } else { + _vm->_global->_soundFlags &= _vm->_global->_presentSound; + } +} + +} // End of namespace Gob diff --git a/engines/gob/init_v2.cpp b/engines/gob/init_v2.cpp new file mode 100644 index 0000000000..36b6492979 --- /dev/null +++ b/engines/gob/init_v2.cpp @@ -0,0 +1,82 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2004 Ivan Dubrov + * Copyright (C) 2004-2006 The ScummVM project + * + * 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 "common/stdafx.h" +#include "common/endian.h" + +#include "gob/gob.h" +#include "gob/init.h" +#include "gob/global.h" +#include "gob/timer.h" +#include "gob/video.h" +#include "gob/draw.h" + +namespace Gob { + +Init_v2::Init_v2(GobEngine *vm) : Init_v1(vm) { +} + +void Init_v2::soundVideo(int32 smallHeap, int16 flag) { + if (_vm->_global->_videoMode != 0x13 && _vm->_global->_videoMode != 0) + error("soundVideo: Video mode 0x%x is not supported!", + _vm->_global->_videoMode); + + _vm->_draw->_frontSurface = &_vm->_global->_primarySurfDesc; + _vm->_video->initSurfDesc(_vm->_global->_videoMode, 320, 200, 0x80); + + //if ((flag & 4) == 0) + // _vm->_video->findVideo(); + + _vm->_global->_mousePresent = 1; + + _vm->_global->_inVM = 0; + + _vm->_global->_presentSound = 0; // FIXME: sound is not supported yet + + _vm->_global->_sprAllocated = 0; + _vm->_gtimer->enableTimer(); + + // _vm->_snd->setResetTimerFlag(debugFlag); // TODO + + if (_vm->_global->_videoMode == 0x13) + _vm->_global->_colorCount = 256; + + _vm->_global->_pPaletteDesc = &_vm->_global->_paletteStruct; + _vm->_global->_pPaletteDesc->vgaPal = _vm->_draw->_vgaPalette; + _vm->_global->_pPaletteDesc->unused1 = _vm->_global->_unusedPalette1; + _vm->_global->_pPaletteDesc->unused2 = _vm->_global->_unusedPalette2; +// _vm->_global->_pPrimarySurfDesc = &_vm->_global->_primarySurfDesc; + + if (_vm->_global->_videoMode != 0) + _vm->_video->initSurfDesc(_vm->_global->_videoMode, 320, 200, PRIMARY_SURFACE); + + if (_vm->_global->_soundFlags & MIDI_FLAG) { + _vm->_global->_soundFlags &= _vm->_global->_presentSound; + if (_vm->_global->_presentSound & ADLIB_FLAG) + _vm->_global->_soundFlags |= MIDI_FLAG; + } else { + _vm->_global->_soundFlags &= _vm->_global->_presentSound; + } +} + +} // End of namespace Gob diff --git a/engines/gob/inter.cpp b/engines/gob/inter.cpp index 72bbe3194e..ed51ab7893 100644 --- a/engines/gob/inter.cpp +++ b/engines/gob/inter.cpp @@ -206,9 +206,7 @@ void Inter::funcBlock(int16 retFlag) { void Inter::storeKey(int16 key) { WRITE_VAR(12, _vm->_util->getTimeKey() - _vm->_game->_startTimeKey); - WRITE_VAR(2, _vm->_global->_inter_mouseX); - WRITE_VAR(3, _vm->_global->_inter_mouseY); - WRITE_VAR(4, _vm->_game->_mouseButtons); + storeMouse(); WRITE_VAR(1, _vm->_snd->_playingSound); if (key == 0x4800) diff --git a/engines/gob/inter.h b/engines/gob/inter.h index ce99528f6d..d62cc33aef 100644 --- a/engines/gob/inter.h +++ b/engines/gob/inter.h @@ -62,6 +62,7 @@ public: void renewTimeInVars(void); void manipulateMap(int16 xPos, int16 yPos, int16 item); virtual int16 loadSound(int16 slot) = 0; + virtual void storeMouse(void) = 0; Inter(GobEngine *vm); virtual ~Inter() {}; @@ -84,6 +85,7 @@ public: Inter_v1(GobEngine *vm); virtual ~Inter_v1() {}; virtual int16 loadSound(int16 slot); + virtual void storeMouse(void); protected: typedef void (Inter_v1::*OpcodeDrawProcV1)(void); @@ -274,6 +276,7 @@ public: Inter_v2(GobEngine *vm); virtual ~Inter_v2() {}; virtual int16 loadSound(int16 search); + virtual void storeMouse(void); protected: typedef void (Inter_v2::*OpcodeDrawProcV2)(void); @@ -324,6 +327,7 @@ protected: void o2_freeLIC(void); void o2_getCDTrackPos(void); void o2_playMult(void); + void o2_initCursor(void); }; } // End of namespace Gob diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp index 269ea0e861..0bfad6575e 100644 --- a/engines/gob/inter_v1.cpp +++ b/engines/gob/inter_v1.cpp @@ -2758,4 +2758,10 @@ void Inter_v1::loadMult(void) { } } +void Inter_v1::storeMouse(void) { + WRITE_VAR(2, _vm->_global->_inter_mouseX); + WRITE_VAR(3, _vm->_global->_inter_mouseY); + WRITE_VAR(4, _vm->_game->_mouseButtons); +} + } // End of namespace Gob diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp index 9631761e31..93529a2257 100644 --- a/engines/gob/inter_v2.cpp +++ b/engines/gob/inter_v2.cpp @@ -131,7 +131,7 @@ void Inter_v2::setupOpcodes(void) { {NULL, ""}, {NULL, ""}, {NULL, ""}, - OPCODE(o1_initCursor), + OPCODE(o2_initCursor), /* 08 */ OPCODE(o1_initCursorAnim), OPCODE(o1_clearCursorAnim), @@ -720,12 +720,74 @@ void Inter_v2::o2_stub0x56(void) { } void Inter_v2::o2_stub0x80(void) { - _vm->_global->_inter_execPtr += 2; + int16 start; + int16 videoMode; + int16 width; + int16 height; - int16 expr1 = _vm->_parse->parseValExpr(); - int16 expr2 = _vm->_parse->parseValExpr(); + start = load16(); + + videoMode = start & 0xFF; + start = (start >> 8) & 0xFF; + + width = _vm->_parse->parseValExpr(); + height = _vm->_parse->parseValExpr(); + + if ((videoMode == _vm->_global->_videoMode) && (width == -1)) + return; + + if (videoMode == 0x14) { + videoMode = 0x13; + _vm->_video->_extraMode = true; + } + else + _vm->_video->_extraMode = false; + + _vm->_game->sub_BB28(); + _vm->_util->clearPalette(); + memset(_vm->_global->_redPalette, 0, 256); + memset(_vm->_global->_greenPalette, 0, 256); + memset(_vm->_global->_bluePalette, 0, 256); + warning("GOB2 Stub! _vid_setStubDriver"); + + if (videoMode == 0x10) { + _vm->_global->_videoMode = 0x12; + _vm->_video->initPrimary(0xE); + _vm->_global->_videoMode = 0x10; + warning("GOB2 Stub! Set VGA CRT Maximum Scan Line to 0"); + _vm->_draw->_frontSurface->height = 400; + } else { + _vm->_global->_videoMode = videoMode; + _vm->_video->initPrimary(videoMode); + } + WRITE_VAR(15, _vm->_global->_videoMode); + + _vm->_global->_setAllPalette = 1; + + if ((width != -1) && _vm->_video->_extraMode) { + _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(); - warning("STUB: Gob2 drawOperation 0x80 (%d %d)", expr1, expr2); + if (start == 0) + _vm->_game->_word_2E51F = 0; + else + _vm->_game->_word_2E51F = _vm->_global->_primaryHeight - start; + _vm->_game->sub_ADD2(); + + if (_vm->_game->_off_2E51B != 0) { + warning("GOB2 Stub! _vid_setSplit(_vm->_global->_primaryHeight - start);"); + warning("GOB2 Stub! _vid_setPixelShift(0, start);"); + } } int16 Inter_v2::loadSound(int16 search) { @@ -1263,7 +1325,6 @@ void Inter_v2::o2_initMult(void) { _vm->_draw->adjustCoords(0, &_vm->_anim->_areaWidth, &_vm->_anim->_areaHeight); - warning("===> %d", _vm->_global->_videoMode); if (_vm->_anim->_animSurf == 0) { if (_vm->_global->_videoMode == 18) { _vm->_anim->_animSurf = new Video::SurfaceDesc; @@ -1368,6 +1429,63 @@ void Inter_v2::o2_playMult(void) { _vm->_mult->playMult(VAR(57), -1, checkEscape & 0x1, 0); } +void Inter_v2::o2_initCursor(void) { + int16 width; + int16 height; + int16 count; + int16 i; + + _vm->_draw->_cursorXDeltaVar = _vm->_parse->parseVarIndex() / 4; + _vm->_draw->_cursorYDeltaVar = _vm->_parse->parseVarIndex() / 4; + + width = load16(); + if (width < 16) + width = 16; + + height = load16(); + if (height < 16) + height = 16; + + _vm->_draw->adjustCoords(0, &width, &height); + + count = load16(); + if (count < 2) + count = 2; + + if (width != _vm->_draw->_cursorWidth || height != _vm->_draw->_cursorHeight || + _vm->_draw->_cursorSprites->width != width * count) { + + _vm->_video->freeSurfDesc(_vm->_draw->_cursorSprites); + _vm->_video->freeSurfDesc(_vm->_draw->_cursorBack); + + _vm->_draw->_cursorWidth = width; + _vm->_draw->_cursorHeight = height; + + if (count < 0x80) + _vm->_draw->_transparentCursor = 1; + else + _vm->_draw->_transparentCursor = 0; + + if (count > 0x80) + count -= 0x80; + + _vm->_draw->_cursorSprites = + _vm->_video->initSurfDesc(_vm->_global->_videoMode, _vm->_draw->_cursorWidth * count, + _vm->_draw->_cursorHeight, 2); + _vm->_draw->_spritesArray[23] = _vm->_draw->_cursorSprites; + + _vm->_draw->_cursorBack = + _vm->_video->initSurfDesc(_vm->_global->_videoMode, _vm->_draw->_cursorWidth, + _vm->_draw->_cursorHeight, 0); + for (i = 0; i < 40; i++) { + _vm->_draw->_cursorAnimLow[i] = -1; + _vm->_draw->_cursorAnimDelays[i] = 0; + _vm->_draw->_cursorAnimHigh[i] = 0; + } + _vm->_draw->_cursorAnimLow[1] = 0; + } +} + void Inter_v2::o2_totSub(void) { char totFile[14]; int flags; @@ -1391,4 +1509,17 @@ void Inter_v2::o2_totSub(void) { _vm->_game->totSub(flags, totFile); } +void Inter_v2::storeMouse(void) { + int16 x; + int16 y; + + x = _vm->_global->_inter_mouseX; + y = _vm->_global->_inter_mouseY; + _vm->_draw->adjustCoords(1, &x, &y); + + WRITE_VAR(2, x); + WRITE_VAR(3, y); + WRITE_VAR(4, _vm->_game->_mouseButtons); +} + } // End of namespace Gob diff --git a/engines/gob/module.mk b/engines/gob/module.mk index bded301193..5a19baa6f8 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -15,6 +15,8 @@ MODULE_OBJS := \ gob.o \ goblin.o \ init.o \ + init_v1.o \ + init_v2.o \ inter.o \ inter_v1.o \ inter_v2.o \ diff --git a/engines/gob/mult_v2.cpp b/engines/gob/mult_v2.cpp index fd56f321b5..050b26b2bc 100644 --- a/engines/gob/mult_v2.cpp +++ b/engines/gob/mult_v2.cpp @@ -244,7 +244,7 @@ void Mult_v2::loadMult(int16 resId) { if (_vm->_game->_totFileData[0x29] >= 51) { size = (int16)READ_LE_UINT16(_dataPtr); _multData2->somepointer10 = new char[size * 20]; - memcpy(_multData2->somepointer09 /*WTF???*/, _dataPtr+2, size * 20); + memcpy(_multData2->somepointer09 /*???*/, _dataPtr+2, size * 20); _dataPtr += size * 20 + 2; size = _vm->_inter->load16(); if (size > 0) { @@ -900,7 +900,7 @@ void Mult_v2::animate(void) { animObj1->someFlag = 0; // TODO: the region around off_2CE67 is messed up - // Should be some heigh value so that MIN() works + // Should be some high value so that MIN() works animObj1->somethingTop = off_2CE67; // seg011:0AA7 animObj1->somethingLeft = off_2CE67; animObj1->somethingBottom = 0; diff --git a/engines/gob/video.cpp b/engines/gob/video.cpp index db88e547d3..41680b343b 100644 --- a/engines/gob/video.cpp +++ b/engines/gob/video.cpp @@ -27,6 +27,7 @@ #include "gob/global.h" #include "gob/video.h" #include "gob/dataio.h" +#include "gob/draw.h" #include "gob/driver_vga.h" @@ -35,15 +36,7 @@ namespace Gob { /* NOT IMPLEMENTED */ Video::Video(GobEngine *vm) : _vm(vm) { -} - -//XXX: Use this function to update the screen for now. -// This should be moved to a better location later on. -void Video::waitRetrace(int16) { - if (_vm->_global->_pPrimarySurfDesc) { - g_system->copyRectToScreen(_vm->_global->_pPrimarySurfDesc->vidPtr, 320, 0, 0, 320, 200); - g_system->updateScreen(); - } + _extraMode = false; } char Video::initDriver(int16 vidMode) { @@ -87,71 +80,6 @@ int32 Video::getRectSize(int16 width, int16 height, int16 flag, int16 mode) { return size; } -Video::SurfaceDesc *Video::initSurfDesc(int16 vidMode, int16 width, int16 height, int16 flags) { - int8 flagsAnd2; - byte *vidMem = 0; - int32 sprSize; - int16 someFlags = 1; - SurfaceDesc *descPtr; - - if (flags != PRIMARY_SURFACE) - _vm->_global->_sprAllocated++; - - if (flags & RETURN_PRIMARY) - return _vm->_global->_pPrimarySurfDesc; - - if (vidMode != 0x13) - error("Video::initSurfDesc: Only VGA 0x13 mode is supported!"); - - if ((flags & PRIMARY_SURFACE) == 0) - vidMode += 0x80; - - if (flags & 2) - flagsAnd2 = 1; - else - flagsAnd2 = 0; - - if (flags & PRIMARY_SURFACE) { - _vm->_global->_primaryWidth = width; - _vm->_global->_mouseMaxCol = width; - _vm->_global->_primaryHeight = height; - _vm->_global->_mouseMaxRow = height; - sprSize = 0; - } else { - sprSize = Video::getRectSize(width, height, flagsAnd2, vidMode); - if (flagsAnd2) - someFlags += 0x80; - } - if (flags & PRIMARY_SURFACE) { - descPtr = _vm->_global->_pPrimarySurfDesc; - delete[] descPtr->vidPtr; - assert(descPtr); - vidMem = new byte[320 * 200]; - } else { - if (flags & DISABLE_SPR_ALLOC) { - descPtr = new SurfaceDesc; - // this case causes vidPtr to be set to invalid memory - assert(false); - } else { - descPtr = new SurfaceDesc; - descPtr->vidPtr = new byte[sprSize]; - vidMem = descPtr->vidPtr; - } - } - if (descPtr == 0) - return 0; - - descPtr->width = width; - descPtr->height = height; - descPtr->flag = someFlags; - descPtr->vidMode = vidMode; - descPtr->vidPtr = vidMem; - - descPtr->reserved1 = 0; - descPtr->reserved2 = 0; - return descPtr; -} - void Video::freeSurfDesc(SurfaceDesc * surfDesc) { delete[] surfDesc->vidPtr; // GOB2: surfDesc != _vm->_draw->_frontSurface (since _frontSurface is set @@ -454,7 +382,7 @@ void Video::initPrimary(int16 mode) { Video::initDriver(mode); if (mode != 3) { - Video::initSurfDesc(mode, 320, 200, PRIMARY_SURFACE); + initSurfDesc(mode, 320, 200, PRIMARY_SURFACE); if (_vm->_global->_dontSetPalette) return; diff --git a/engines/gob/video.h b/engines/gob/video.h index 02b9090cc9..293643ed55 100644 --- a/engines/gob/video.h +++ b/engines/gob/video.h @@ -89,10 +89,11 @@ public: PalDesc() : vgaPal(0), unused1(0), unused2(0) {} }; + bool _extraMode; + Video(class GobEngine *vm); virtual ~Video() {}; int32 getRectSize(int16 width, int16 height, int16 flag, int16 mode); - SurfaceDesc *initSurfDesc(int16 vidMode, int16 width, int16 height, int16 flags); void freeSurfDesc(SurfaceDesc * surfDesc); int16 clampValue(int16 val, int16 max); void drawSprite(SurfaceDesc * source, SurfaceDesc * dest, int16 left, @@ -113,12 +114,13 @@ public: void initPrimary(int16 mode); char spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, int16 x, int16 y, int16 transp, SurfaceDesc * destDesc); - void waitRetrace(int16); void freeDriver(void); void setHandlers(); virtual void drawLetter(int16 item, int16 x, int16 y, FontDesc * fontDesc, int16 color1, int16 color2, int16 transp, SurfaceDesc * dest) = 0; + virtual SurfaceDesc *initSurfDesc(int16 vidMode, int16 width, int16 height, int16 flags) = 0; + virtual void waitRetrace(int16) = 0; protected: class VideoDriver *_videoDriver; @@ -131,6 +133,8 @@ class Video_v1 : public Video { public: virtual void drawLetter(int16 item, int16 x, int16 y, FontDesc * fontDesc, int16 color1, int16 color2, int16 transp, SurfaceDesc * dest); + virtual SurfaceDesc *initSurfDesc(int16 vidMode, int16 width, int16 height, int16 flags); + virtual void waitRetrace(int16); Video_v1(GobEngine *vm); virtual ~Video_v1() {}; @@ -140,6 +144,8 @@ class Video_v2 : public Video_v1 { public: virtual void drawLetter(int16 item, int16 x, int16 y, FontDesc * fontDesc, int16 color1, int16 color2, int16 transp, SurfaceDesc * dest); + virtual SurfaceDesc *initSurfDesc(int16 vidMode, int16 width, int16 height, int16 flags); + virtual void waitRetrace(int16); Video_v2(GobEngine *vm); virtual ~Video_v2() {}; diff --git a/engines/gob/video_v1.cpp b/engines/gob/video_v1.cpp index e1d20f01d4..cafea57d1e 100644 --- a/engines/gob/video_v1.cpp +++ b/engines/gob/video_v1.cpp @@ -25,6 +25,7 @@ #include "common/endian.h" #include "gob/gob.h" +#include "gob/global.h" #include "gob/video.h" namespace Gob { @@ -32,10 +33,84 @@ namespace Gob { Video_v1::Video_v1(GobEngine *vm) : Video(vm) { } +//XXX: Use this function to update the screen for now. +// This should be moved to a better location later on. +void Video_v1::waitRetrace(int16) { + if (_vm->_global->_pPrimarySurfDesc) { + g_system->copyRectToScreen(_vm->_global->_pPrimarySurfDesc->vidPtr, 320, 0, 0, 320, 200); + g_system->updateScreen(); + } +} + void Video_v1::drawLetter(int16 item, int16 x, int16 y, FontDesc *fontDesc, int16 color1, int16 color2, int16 transp, SurfaceDesc *dest) { _videoDriver->drawLetter((unsigned char) item, x, y, fontDesc, color1, color2, transp, dest); } +Video::SurfaceDesc *Video_v1::initSurfDesc(int16 vidMode, int16 width, int16 height, int16 flags) { + int8 flagsAnd2; + byte *vidMem = 0; + int32 sprSize; + int16 someFlags = 1; + SurfaceDesc *descPtr; + + if (flags != PRIMARY_SURFACE) + _vm->_global->_sprAllocated++; + + if (flags & RETURN_PRIMARY) + return _vm->_global->_pPrimarySurfDesc; + + if (vidMode != 0x13) + error("Video::initSurfDesc: Only VGA 0x13 mode is supported!"); + + if ((flags & PRIMARY_SURFACE) == 0) + vidMode += 0x80; + + if (flags & 2) + flagsAnd2 = 1; + else + flagsAnd2 = 0; + + if (flags & PRIMARY_SURFACE) { + _vm->_global->_primaryWidth = width; + _vm->_global->_mouseMaxCol = width; + _vm->_global->_primaryHeight = height; + _vm->_global->_mouseMaxRow = height; + sprSize = 0; + } else { + sprSize = Video::getRectSize(width, height, flagsAnd2, vidMode); + if (flagsAnd2) + someFlags += 0x80; + } + if (flags & PRIMARY_SURFACE) { + descPtr = _vm->_global->_pPrimarySurfDesc; + delete[] descPtr->vidPtr; + assert(descPtr); + vidMem = new byte[320 * 200]; + } else { + if (flags & DISABLE_SPR_ALLOC) { + descPtr = new SurfaceDesc; + // this case causes vidPtr to be set to invalid memory + assert(false); + } else { + descPtr = new SurfaceDesc; + descPtr->vidPtr = new byte[sprSize]; + vidMem = descPtr->vidPtr; + } + } + if (descPtr == 0) + return 0; + + descPtr->width = width; + descPtr->height = height; + descPtr->flag = someFlags; + descPtr->vidMode = vidMode; + descPtr->vidPtr = vidMem; + + descPtr->reserved1 = 0; + descPtr->reserved2 = 0; + return descPtr; +} + } // End of namespace Gob diff --git a/engines/gob/video_v2.cpp b/engines/gob/video_v2.cpp index 0d0a7be9e1..d6f311ed62 100644 --- a/engines/gob/video_v2.cpp +++ b/engines/gob/video_v2.cpp @@ -25,13 +25,24 @@ #include "common/endian.h" #include "gob/gob.h" +#include "gob/global.h" #include "gob/video.h" +#include "gob/draw.h" namespace Gob { Video_v2::Video_v2(GobEngine *vm) : Video_v1(vm) { } +//XXX: Use this function to update the screen for now. +// This should be moved to a better location later on. +void Video_v2::waitRetrace(int16) { + if (_vm->_draw->_frontSurface) { + g_system->copyRectToScreen(_vm->_draw->_frontSurface->vidPtr, 320, 0, 0, 320, 200); + g_system->updateScreen(); + } +} + void Video_v2::drawLetter(int16 item, int16 x, int16 y, FontDesc *fontDesc, int16 color1, int16 color2, int16 transp, SurfaceDesc *dest) { int16 videoMode; @@ -71,4 +82,74 @@ void Video_v2::drawLetter(int16 item, int16 x, int16 y, FontDesc *fontDesc, int1 dest->vidMode = videoMode; } +Video::SurfaceDesc *Video_v2::initSurfDesc(int16 vidMode, int16 width, int16 height, int16 flags) { + int8 flagsAnd2; + byte *vidMem = 0; + int32 sprSize; + int16 someFlags = 1; + SurfaceDesc *descPtr; + + if (flags != PRIMARY_SURFACE) + _vm->_global->_sprAllocated++; + + if (flags & RETURN_PRIMARY) + return _vm->_draw->_frontSurface; + + if (vidMode != 0x13) + error("Video::initSurfDesc: Only VGA 0x13 mode is supported!"); + + if ((flags & PRIMARY_SURFACE) == 0) + vidMode += 0x80; + + if (flags & 2) + flagsAnd2 = 1; + else + flagsAnd2 = 0; + + width = (width + 7) & 0xFFF8; + + if (flags & PRIMARY_SURFACE) { + _vm->_global->_primaryWidth = width; + _vm->_global->_mouseMaxCol = width; + _vm->_global->_primaryHeight = height; + _vm->_global->_mouseMaxRow = height; + sprSize = 0; + } else { + vidMem = 0; + sprSize = Video::getRectSize(width, height, flagsAnd2, vidMode); + someFlags = 4; + if (flagsAnd2) + someFlags += 0x80; + } + if (flags & PRIMARY_SURFACE) { + descPtr = _vm->_draw->_frontSurface; + assert(descPtr); + if (descPtr->vidPtr != 0) + delete[] descPtr->vidPtr; + vidMem = new byte[320 * 200]; + } else { + if (flags & DISABLE_SPR_ALLOC) { + descPtr = new SurfaceDesc; + // this case causes vidPtr to be set to invalid memory + assert(false); + } else { + descPtr = new SurfaceDesc; + descPtr->vidPtr = new byte[sprSize]; + vidMem = descPtr->vidPtr; + } + } + if (descPtr == 0) + return 0; + + descPtr->width = width; + descPtr->height = height; + descPtr->flag = someFlags; + descPtr->vidMode = vidMode; + descPtr->vidPtr = vidMem; + + descPtr->reserved1 = 0; + descPtr->reserved2 = 0; + return descPtr; +} + } // End of namespace Gob -- cgit v1.2.3