diff options
Diffstat (limited to 'engines/gob/game_v2.cpp')
-rw-r--r-- | engines/gob/game_v2.cpp | 390 |
1 files changed, 389 insertions, 1 deletions
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 |