diff options
Diffstat (limited to 'engines/tsage/core.cpp')
-rw-r--r-- | engines/tsage/core.cpp | 238 |
1 files changed, 176 insertions, 62 deletions
diff --git a/engines/tsage/core.cpp b/engines/tsage/core.cpp index b0220b53e0..16fe45044b 100644 --- a/engines/tsage/core.cpp +++ b/engines/tsage/core.cpp @@ -860,6 +860,8 @@ void PlayerMover::doStepsOfNpcMovement(const Common::Point &srcPos, const Common int PlayerMover::calculateRestOfRoute(int *routeList, int srcRegion, int destRegion, bool &foundRoute) { // Make a copy of the provided route. The first entry is the size. int tempList[REGION_LIST_SIZE + 1]; + memset(tempList, 0, sizeof(tempList)); + foundRoute = false; for (int idx = 0; idx <= *routeList; ++idx) tempList[idx] = routeList[idx]; @@ -1151,6 +1153,13 @@ void PaletteRotation::signal() { if (flag) _currIndex = _start; } + + // Added in Return to Ringworld + if (_currIndex < _start) { + flag = decDuration(); + if (flag) + _currIndex = _end; + } break; case 2: _currIndex += _idxChange; @@ -1292,7 +1301,6 @@ ScenePalette::ScenePalette() { *palData++ = idx; } - _field412 = 0; _redColor = _greenColor = _blueColor = 0; _aquaColor = 0; _purpleColor = 0; @@ -1304,7 +1312,6 @@ ScenePalette::~ScenePalette() { } ScenePalette::ScenePalette(int paletteNum) { - _field412 = 0; _redColor = _greenColor = _blueColor = 0; _aquaColor = 0; _purpleColor = 0; @@ -1536,7 +1543,11 @@ void ScenePalette::synchronize(Serializer &s) { s.syncAsSint32LE(_colors.foreground); s.syncAsSint32LE(_colors.background); - s.syncAsSint32LE(_field412); + if (s.getVersion() < 12) { + int useless = 0; + s.syncAsSint32LE(useless); + } + s.syncAsByte(_redColor); s.syncAsByte(_greenColor); s.syncAsByte(_blueColor); @@ -1552,8 +1563,13 @@ void SceneItem::synchronize(Serializer &s) { _bounds.synchronize(s); s.syncString(_msg); - s.syncAsSint32LE(_fieldE); - s.syncAsSint32LE(_field10); + + if (s.getVersion() < 15) { + int useless = 0; + s.syncAsSint32LE(useless); + s.syncAsSint32LE(useless); + } + s.syncAsSint16LE(_position.x); s.syncAsSint32LE(_position.y); s.syncAsSint16LE(_yDiff); s.syncAsSint32LE(_sceneRegionId); @@ -1619,7 +1635,8 @@ void SceneItem::display(int resNum, int lineNum, ...) { Common::String msg = (!resNum || (resNum == -1)) ? Common::String() : g_resourceManager->getMessage(resNum, lineNum); - if ((g_vm->getGameID() != GType_Ringworld) && T2_GLOBALS._uiElements._active) + if ((g_vm->getGameID() != GType_Ringworld) && (g_vm->getGameID() != GType_Ringworld2) + && T2_GLOBALS._uiElements._active) T2_GLOBALS._uiElements.hide(); if (g_globals->_sceneObjects->contains(&g_globals->_sceneText)) { @@ -1729,9 +1746,13 @@ void SceneItem::display(int resNum, int lineNum, ...) { font.setFontNumber(g_globals->_sceneText._fontNumber); font.getStringBounds(msg.c_str(), textRect, maxWidth); + Rect screenBounds = g_globals->gfxManager()._bounds; + if (g_vm->getGameID() == GType_Ringworld2) + screenBounds.collapse(20, 15); + // Center the text at the specified position, and then constrain it to be- textRect.center(pos.x, pos.y); - textRect.contain(g_globals->gfxManager()._bounds); + textRect.contain(screenBounds); if (centerText) { g_globals->_sceneText._color1 = g_globals->_sceneText._color2; @@ -1749,9 +1770,22 @@ void SceneItem::display(int resNum, int lineNum, ...) { } g_globals->_sceneText.fixPriority(255); + + // In Return to Ringworld, if in voice mode only, don't show the text + if ((g_vm->getGameID() == GType_Ringworld2) && (R2_GLOBALS._speechSubtitles & SPEECH_VOICE) + && !(R2_GLOBALS._speechSubtitles & SPEECH_TEXT)) + g_globals->_sceneText.hide(); + g_globals->_sceneObjects->draw(); } + // For Return to Ringworld, play the voice overs in sequence + if ((g_vm->getGameID() == GType_Ringworld2) && (R2_GLOBALS._speechSubtitles & SPEECH_VOICE) + && !playList.empty()) { + R2_GLOBALS._playStream.play(*playList.begin(), NULL); + playList.pop_front(); + } + // Unless the flag is set to keep the message on-screen, show it until a mouse or keypress, then remove it if (!keepOnscreen && !msg.empty()) { Event event; @@ -1761,18 +1795,31 @@ void SceneItem::display(int resNum, int lineNum, ...) { EVENT_BUTTON_DOWN | EVENT_KEYPRESS)) { GLOBALS._screenSurface.updateScreen(); g_system->delayMillis(10); - } - // For Return to Ringworld, play the voice overs in sequence - if ((g_vm->getGameID() == GType_Ringworld2) && !playList.empty() && !R2_GLOBALS._playStream.isPlaying()) { - R2_GLOBALS._playStream.play(*playList.begin(), NULL); - playList.pop_front(); + if ((g_vm->getGameID() == GType_Ringworld2) && (R2_GLOBALS._speechSubtitles & SPEECH_VOICE)) { + // Allow the play stream to do processing + R2_GLOBALS._playStream.dispatch(); + if (!R2_GLOBALS._playStream.isPlaying()) { + // Check if there are further voice samples to play + if (!playList.empty()) { + R2_GLOBALS._playStream.play(*playList.begin(), NULL); + playList.pop_front(); + } else if (!(R2_GLOBALS._speechSubtitles & SPEECH_TEXT)) { + // If not showing text, don't both waiting for a click to end + break; + } + } + } } + if (g_vm->getGameID() == GType_Ringworld2) + R2_GLOBALS._playStream.stop(); + g_globals->_sceneText.remove(); } - if ((g_vm->getGameID() != GType_Ringworld) && T2_GLOBALS._uiElements._active) { + if ((g_vm->getGameID() != GType_Ringworld) && (g_vm->getGameID() != GType_Ringworld2) + && T2_GLOBALS._uiElements._active) { // Show user interface T2_GLOBALS._uiElements.show(); @@ -2066,18 +2113,18 @@ SceneObject::SceneObject() : SceneHotspot() { _visage = 0; _strip = 0; _frame = 0; - _effect = 0; - _shade = _shade2 = 0; + _effect = EFFECT_NONE; + _shade = _oldShade = 0; _linkedActor = NULL; - _field8A = Common::Point(0, 0); + _actorDestPos = Common::Point(0, 0); _angle = 0; _xs = 0; _xe = 0; _endFrame = 0; - _field68 = 0; + _loopCount = 0; _regionIndex = 0; - _field9C = NULL; + _shadowMap = NULL; } SceneObject::SceneObject(const SceneObject &so) : SceneHotspot() { @@ -2324,7 +2371,7 @@ void SceneObject::animate(AnimateMode animMode, ...) { case ANIM_MODE_1: _frameChange = 1; - _field2E = _position; + _oldPosition = _position; _endAction = 0; break; @@ -2372,9 +2419,9 @@ void SceneObject::animate(AnimateMode animMode, ...) { case ANIM_MODE_9: if (_animateMode == ANIM_MODE_9 && g_vm->getGameID() == GType_Ringworld2) { _frameChange = -1; - _field2E = _position; + _oldPosition = _position; } else { - _field68 = va_arg(va, int); + _loopCount = va_arg(va, int); _endAction = va_arg(va, Action *); _frameChange = 1; _endFrame = getFrameCount(); @@ -2441,7 +2488,7 @@ void SceneObject::synchronize(Serializer &s) { s.syncAsUint32LE(_updateStartFrame); s.syncAsUint32LE(_walkStartFrame); - s.syncAsSint16LE(_field2E.x); s.syncAsSint16LE(_field2E.y); + s.syncAsSint16LE(_oldPosition.x); s.syncAsSint16LE(_oldPosition.y); s.syncAsSint16LE(_percent); s.syncAsSint16LE(_priority); s.syncAsSint16LE(_angle); @@ -2456,7 +2503,7 @@ void SceneObject::synchronize(Serializer &s) { SYNC_ENUM(_animateMode, AnimateMode); s.syncAsSint32LE(_frame); s.syncAsSint32LE(_endFrame); - s.syncAsSint32LE(_field68); + s.syncAsSint32LE(_loopCount); s.syncAsSint32LE(_frameChange); s.syncAsSint32LE(_numFrames); s.syncAsSint32LE(_regionIndex); @@ -2464,8 +2511,8 @@ void SceneObject::synchronize(Serializer &s) { s.syncAsSint16LE(_moveDiff.x); s.syncAsSint16LE(_moveDiff.y); s.syncAsSint32LE(_moveRate); if (g_vm->getGameID() == GType_Ringworld2) { - s.syncAsSint16LE(_field8A.x); - s.syncAsSint16LE(_field8A.y); + s.syncAsSint16LE(_actorDestPos.x); + s.syncAsSint16LE(_actorDestPos.y); } SYNC_POINTER(_endAction); s.syncAsUint32LE(_regionBitList); @@ -2473,7 +2520,7 @@ void SceneObject::synchronize(Serializer &s) { if (g_vm->getGameID() == GType_Ringworld2) { s.syncAsSint16LE(_effect); s.syncAsSint16LE(_shade); - s.syncAsSint16LE(_shade2); + s.syncAsSint16LE(_oldShade); SYNC_POINTER(_linkedActor); } } @@ -2482,7 +2529,8 @@ void SceneObject::postInit(SceneObjectList *OwnerList) { if (!OwnerList) OwnerList = g_globals->_sceneObjects; - if (!OwnerList->contains(this) || ((_flags & OBJFLAG_REMOVE) != 0)) { + bool isExisting = OwnerList->contains(this); + if (!isExisting || ((_flags & OBJFLAG_REMOVE) != 0)) { _percent = 100; _priority = 255; _flags = OBJFLAG_ZOOMED; @@ -2501,7 +2549,8 @@ void SceneObject::postInit(SceneObjectList *OwnerList) { _numFrames = 10; _regionBitList = 0; - OwnerList->push_back(this); + if (!isExisting) + OwnerList->push_back(this); _flags |= OBJFLAG_PANES; } } @@ -2519,9 +2568,9 @@ void SceneObject::remove() { void SceneObject::dispatch() { if (g_vm->getGameID() == GType_Ringworld2) { - if (_shade != _shade2) + if (_shade != _oldShade) _flags |= OBJFLAG_PANES; - _shade2 = _shade; + _oldShade = _shade; } uint32 currTime = g_globals->_events.getFrameNumber(); @@ -2541,9 +2590,9 @@ void SceneObject::dispatch() { case ANIM_MODE_1: if (isNoMover()) setFrame(1); - else if ((_field2E.x != _position.x) || (_field2E.y != _position.y)) { + else if ((_oldPosition.x != _position.x) || (_oldPosition.y != _position.y)) { setFrame(changeFrame()); - _field2E = _position; + _oldPosition = _position; } break; @@ -2586,7 +2635,7 @@ void SceneObject::dispatch() { _endFrame = 1; setFrame(changeFrame()); - } else if (!_field68 || (--_field68 > 0)) { + } else if (!_loopCount || (--_loopCount > 0)) { _frameChange = 1; _endFrame = getFrameCount(); @@ -2605,7 +2654,7 @@ void SceneObject::dispatch() { _frameChange = -1; _strip = ((_strip - 1) ^ 1) + 1; _endFrame = 1; - } else if ((_field68 == 0) || (--_field68 != 0)) { + } else if (!_loopCount || (--_loopCount > 0)) { _frameChange = 1; _endFrame = getFrameCount(); @@ -2639,8 +2688,9 @@ void SceneObject::dispatch() { _linkedActor->setFrame(_frame); } - if ((_effect == 1) && (getRegionIndex() < 11)) - _shade = 0; + int regionIndex = getRegionIndex(); + if ((_effect == EFFECT_SHADED) && (regionIndex < 11)) + _shade = regionIndex; } } @@ -2669,11 +2719,46 @@ void SceneObject::removeObject() { GfxSurface SceneObject::getFrame() { _visageImages.setVisage(_visage, _strip); - return _visageImages.getFrame(_frame); + GfxSurface frame = _visageImages.getFrame(_frame); + + // Reset any centroid adjustment flags, in + frame._flags &= ~(FRAME_FLIP_CENTROID_X | FRAME_FLIP_CENTROID_Y); + + // For later games, check whether the appropriate object flags are set for flipping + if (g_vm->getGameID() != GType_Ringworld) { + if ((_flags & OBJFLAG_FLIP_CENTROID_X) || _visageImages._flipHoriz) + frame._flags |= FRAME_FLIP_CENTROID_X; + if ((_flags & OBJFLAG_FLIP_CENTROID_Y) || _visageImages._flipVert) + frame._flags |= FRAME_FLIP_CENTROID_Y; + } + + // If shading is needed, post apply the shadiing onto the frame + if ((g_vm->getGameID() == GType_Ringworld2) && (_shade >= 1)) { + Graphics::Surface s = frame.lockSurface(); + byte *p = (byte *)s.getPixels(); + byte *endP = p + s.w * s.h; + + while (p < endP) { + if (*p != frame._transColor) + *p = R2_GLOBALS._fadePaletteMap[_shade - 1][*p]; + ++p; + } + + frame.unlockSurface(); + } + + return frame; } void SceneObject::reposition() { + if (g_vm->getGameID() == GType_Ringworld2) { + if (!(_flags & OBJFLAG_ZOOMED)) { + setZoom(g_globals->_sceneManager._scene->_zoomPercents[MIN(_position.y, (int16)255)]); + } + } + GfxSurface frame = getFrame(); + _bounds.resize(frame, _position.x, _position.y - _yDiff, _percent); _xs = _bounds.left; _xe = _bounds.right; @@ -2684,11 +2769,27 @@ void SceneObject::reposition() { */ void SceneObject::draw() { Rect destRect = _bounds; - destRect.translate(-g_globals->_sceneManager._scene->_sceneBounds.left, - -g_globals->_sceneManager._scene->_sceneBounds.top); - Region *priorityRegion = g_globals->_sceneManager._scene->_priorities.find(_priority); + Scene *scene = g_globals->_sceneManager._scene; + destRect.translate(-scene->_sceneBounds.left, -scene->_sceneBounds.top); GfxSurface frame = getFrame(); - g_globals->gfxManager().copyFrom(frame, destRect, priorityRegion); + Region *priorityRegion = scene->_priorities.find(_priority); + + if (g_vm->getGameID() == GType_Ringworld2) { + switch (_effect) { + case EFFECT_SHADOW_MAP: { + if (!_shadowMap) + _shadowMap = static_cast<Ringworld2::SceneExt *>(scene)->_shadowPaletteMap; + + GLOBALS.gfxManager().getSurface().copyFrom(frame, frame.getBounds(), + destRect, priorityRegion, _shadowMap); + return; + } + default: + break; + } + } + + GLOBALS.gfxManager().copyFrom(frame, destRect, priorityRegion); } /** @@ -2790,10 +2891,17 @@ void BackgroundSceneObject::setup2(int visage, int stripFrameNum, int frameNum, setFrame(frameNum); setPosition(Common::Point(posX, posY)); fixPriority(priority); + + _effect = effect; } void BackgroundSceneObject::copySceneToBackground() { GLOBALS._sceneManager._scene->_backSurface.copyFrom(g_globals->gfxManager().getSurface(), 0, 0); + + // WORKAROUND: Since savegames don't store the active screen data, once we copy the + // foreground objects to the background, we have to prevent the scene being saved. + if (g_vm->getGameID() == GType_Ringworld2) + ((Ringworld2::SceneExt *)GLOBALS._sceneManager._scene)->_preventSaving = true; } /*--------------------------------------------------------------------------*/ @@ -2856,8 +2964,9 @@ void SceneObjectList::draw() { g_globals->_sceneManager._sceneBgOffset.y); } - // Set up the flag mask - uint32 flagMask = (paneNum == 0) ? OBJFLAG_PANE_0 : OBJFLAG_PANE_1; + // Set up the flag mask. Currently, paneNum is always set to 0, so the check is meaningless + // uint32 flagMask = (paneNum == 0) ? OBJFLAG_PANE_0 : OBJFLAG_PANE_1; + uint32 flagMask = OBJFLAG_PANE_0; // Initial loop to set up object list and update object position, priority, and flags for (SynchronizedList<SceneObject *>::iterator i = g_globals->_sceneObjects->begin(); @@ -3260,7 +3369,6 @@ Player::Player(): SceneObject() { _canWalk = false; _enabled = false; _uiEnabled = false; - _field8C = 0; // Return to Ringworld specific fields _characterIndex = R2_NONE; @@ -3279,18 +3387,14 @@ void Player::postInit(SceneObjectList *OwnerList) { _canWalk = true; _uiEnabled = true; _percent = 100; - _field8C = 10; - if (g_vm->getGameID() != GType_Ringworld2) - { + if (g_vm->getGameID() != GType_Ringworld2) { _moveDiff.x = 4; _moveDiff.y = 2; - } - else - { + } else { _moveDiff.x = 3; _moveDiff.y = 2; - _effect = 1; + _effect = EFFECT_SHADED; _shade = 0; _linkedActor = NULL; @@ -3304,20 +3408,24 @@ void Player::postInit(SceneObjectList *OwnerList) { void Player::disableControl() { _canWalk = false; - _uiEnabled = false; g_globals->_events.setCursor(CURSOR_NONE); _enabled = false; - if ((g_vm->getGameID() != GType_Ringworld) && T2_GLOBALS._uiElements._active) - T2_GLOBALS._uiElements.hide(); + if (g_vm->getGameID() != GType_Ringworld2) { + _uiEnabled = false; + + if ((g_vm->getGameID() != GType_Ringworld) && T2_GLOBALS._uiElements._active) + T2_GLOBALS._uiElements.hide(); + } } void Player::enableControl() { CursorType cursor; _canWalk = true; - _uiEnabled = true; _enabled = true; + if (g_vm->getGameID() != GType_Ringworld2) + _uiEnabled = true; switch (g_vm->getGameID()) { case GType_BlueForce: @@ -3325,7 +3433,7 @@ void Player::enableControl() { cursor = g_globals->_events.getCursor(); g_globals->_events.setCursor(cursor); - if (T2_GLOBALS._uiElements._active) + if (g_vm->getGameID() == GType_BlueForce && T2_GLOBALS._uiElements._active) T2_GLOBALS._uiElements.show(); break; @@ -3391,7 +3499,10 @@ void Player::synchronize(Serializer &s) { s.syncAsByte(_canWalk); s.syncAsByte(_uiEnabled); - s.syncAsSint16LE(_field8C); + if (s.getVersion() < 15) { + int useless = 0; + s.syncAsSint16LE(useless); + } if (g_vm->getGameID() != GType_Ringworld) s.syncAsByte(_enabled); @@ -4139,7 +4250,6 @@ double FloatSet::sqrt(FloatSet &floatSet) { GameHandler::GameHandler() : EventHandler() { _nextWaitCtr = 1; _waitCtr.setCtr(1); - _field14 = 10; } GameHandler::~GameHandler() { @@ -4161,7 +4271,11 @@ void GameHandler::synchronize(Serializer &s) { _lockCtr.synchronize(s); _waitCtr.synchronize(s); s.syncAsSint16LE(_nextWaitCtr); - s.syncAsSint16LE(_field14); + + if (s.getVersion() < 14) { + int useless = 0; + s.syncAsSint16LE(useless); + } } /*--------------------------------------------------------------------------*/ @@ -4235,11 +4349,11 @@ void SceneHandler::process(Event &event) { g_vm->_debugger->onFrame(); } - if ((event.eventType == EVENT_KEYPRESS) && g_globals->_player._enabled && g_globals->_player._canWalk) { + if ((event.eventType == EVENT_KEYPRESS) && g_globals->_player._enabled) { // Keyboard shortcuts for different actions switch (event.kbd.keycode) { case Common::KEYCODE_w: - g_globals->_events.setCursor(CURSOR_WALK); + g_globals->_events.setCursor(GLOBALS._player._canWalk ? CURSOR_WALK : CURSOR_USE); event.handled = true; break; case Common::KEYCODE_l: @@ -4273,7 +4387,7 @@ void SceneHandler::process(Event &event) { // Scan the item list to find one the mouse is within SynchronizedList<SceneItem *>::iterator i; for (i = g_globals->_sceneItems.begin(); i != g_globals->_sceneItems.end(); ++i) { - SceneItem *item = *i; + SceneItem *item = *i; if (item->contains(event.mousePos)) { // Pass the action to the item bool handled = item->startAction(g_globals->_events.getCursor(), event); |