diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/sci/engine/script_patches.cpp | 47 | ||||
-rw-r--r-- | engines/sludge/fonttext.h | 2 | ||||
-rw-r--r-- | engines/titanic/core/view_item.cpp | 53 | ||||
-rw-r--r-- | engines/titanic/events.cpp | 17 | ||||
-rw-r--r-- | engines/titanic/game/computer_screen.cpp | 14 | ||||
-rw-r--r-- | engines/titanic/game/computer_screen.h | 1 | ||||
-rw-r--r-- | engines/titanic/game/transport/lift.cpp | 12 | ||||
-rw-r--r-- | engines/titanic/messages/messages.h | 1 | ||||
-rw-r--r-- | engines/titanic/moves/move_player_in_parrot_room.cpp | 12 | ||||
-rw-r--r-- | engines/titanic/moves/move_player_in_parrot_room.h | 9 | ||||
-rw-r--r-- | engines/titanic/npcs/bilge_succubus.cpp | 9 | ||||
-rw-r--r-- | engines/titanic/npcs/succubus.cpp | 15 | ||||
-rw-r--r-- | engines/titanic/npcs/succubus.h | 2 | ||||
-rw-r--r-- | engines/titanic/star_control/star_control.h | 5 | ||||
-rw-r--r-- | engines/titanic/star_control/star_view.cpp | 7 | ||||
-rw-r--r-- | engines/titanic/star_control/star_view.h | 6 |
16 files changed, 158 insertions, 54 deletions
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index 5e85c39f51..5ef75f86a8 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -4092,6 +4092,52 @@ static const SciScriptPatcherEntry pq3Signatures[] = { #pragma mark - #pragma mark Police Quest 4 +// In Police Quest 4 inside the Bitty Kitty show (room 315), the player has to first talk with a young woman, show her the police badge, then +// show her the red shoe. She will tell the player that may "Barbie" knows more. +// After leaving and entering later (not detailed here), Barbie will be available. +// Now the player needs to show her the police badge as well and then it goes a bit weird. +// +// The player can show her the red shoe immediately, which will work dialog-wise, but points won't be awarded and the corresponding flag will also not get set. +// Internally the game checks if some regular talking dialog (for Barbie) has been accessed before awarding the points and setting the flags. +// When the player does not recognize this, the player may get stuck and it will look as if a game breaking glitch has happened. +// +// Showing the red shoe to the young woman AND showing it to Barbie is all done using the same script. +// It works via shoeShoe::changeState. +// +// The code in there of state 0 checks first who is currently inside the room using stripper::noun. +// Afterwards for the young woman it checks local 3 if it's zero or not zero. +// Local 3 is set, when the player has shown the police badge to the person, that is currently inside the room. +// +// For Barbie strangely global 9Ah is checked instead, which then causes those issues. +// +// We change the Barbie code to also check local 3, which seems to work out. +// We can't simply remove the check, otherwise the flag will get set even when the player +// hasn't shown the badge, which will cause Barbie to not answer the question and the player +// won't be able to show her the shoe a second time. +// +// This of course also happened, when using the original interpreter. +// +// Applies to at least: English floppy, German floppy, English CD +// Responsible method: showShoe::changeState(0) - script 315 +// Fixes bug: #9849 +static const uint16 pq4BittyKittyShowBarieRedShoeSignature[] = { + // stripper::noun check is for checking, if police badge was shown + SIG_MAGICDWORD, + 0x89, 0x9a, // lsg global[9Ah] + 0x35, 0x02, // ldi 02 + 0x1e, // gt? + 0x30, SIG_UINT16(0x0028), // bnt [skip 2 points code] + 0x39, 0x61, // pushi 61h (flag) + SIG_END +}; + +static const uint16 pq4BittyKittyShowBarbieRedShoePatch[] = { + 0x83, 0x03, // lal local[3] + 0x30, PATCH_UINT16(0x002b), // bnt [skip 2 points code] + 0x33, 1, // jmp 1 (waste some bytes) + PATCH_END +}; + // In Police Quest 4 scripts for room 390 (city hall) use ticks instead of seconds. // Ticks are not behaving the same as seconds. Ticks will also go down within game menus including inventory. // When getting attacked, the player has almost no time to draw the gun - and even when the player has the gun @@ -4182,6 +4228,7 @@ static const uint16 pq4FloppyCityHallCuffEnemyTimerPatch[] = { // script, description, signature patch static const SciScriptPatcherEntry pq4Signatures[] = { + { true, 315, "show barbie the red shoe points fix", 1, pq4BittyKittyShowBarieRedShoeSignature, pq4BittyKittyShowBarbieRedShoePatch }, { true, 390, "floppy: city hall: draw gun timer", 1, pq4FloppyCityHallDrawGunTimerSignature, pq4FloppyCityHallDrawGunTimerPatch }, { true, 390, "floppy: city hall: tell enemy drop weapon timer", 1, pq4FloppyCityHallTellEnemyDropWeaponTimerSignature, pq4FloppyCityHallTellEnemyDropWeaponTimerPatch }, { true, 390, "floppy: city hall: tell enemy turn around timer", 1, pq4FloppyCityHallTellEnemyTurnAroundTimerSignature, pq4FloppyCityHallTellEnemyTurnAroundTimerPatch }, diff --git a/engines/sludge/fonttext.h b/engines/sludge/fonttext.h index c8038cb28d..3170a3e12f 100644 --- a/engines/sludge/fonttext.h +++ b/engines/sludge/fonttext.h @@ -30,7 +30,7 @@ namespace Sludge { struct SpriteBank; -struct SpritePalette; +class SpritePalette; class TextManager { public: diff --git a/engines/titanic/core/view_item.cpp b/engines/titanic/core/view_item.cpp index 401553d55d..f98b015feb 100644 --- a/engines/titanic/core/view_item.cpp +++ b/engines/titanic/core/view_item.cpp @@ -340,6 +340,7 @@ CString CViewItem::getNodeViewName() const { bool CViewItem::MovementMsg(CMovementMsg *msg) { Point pt; + bool foundPt = false; // First allow any child objects to handle it for (CTreeItem *treeItem = getFirstChild(); treeItem; @@ -348,31 +349,41 @@ bool CViewItem::MovementMsg(CMovementMsg *msg) { return true; } - // Iterate through the view's contents to find a link or item - // with the appropriate movement action - for (CTreeItem *treeItem = getFirstChild(); treeItem; - treeItem = treeItem->scan(this)) { - CLinkItem *link = dynamic_cast<CLinkItem *>(treeItem); - CGameObject *gameObj = dynamic_cast<CGameObject *>(treeItem); - - if (link) { - // Skip links that aren't for the desired direction - if (link->getMovement() != msg->_movement) - continue; - - pt = Point((link->_bounds.left + link->_bounds.right) / 2, - (link->_bounds.top + link->_bounds.bottom) / 2); - } else if (gameObj) { - if (!gameObj->_visible || gameObj->getMovement() != msg->_movement) + if (msg->_posToUse.x != 0 || msg->_posToUse.y != 0) { + pt = msg->_posToUse; + foundPt = true; + } else { + // Iterate through the view's contents to find a link or item + // with the appropriate movement action + for (CTreeItem *treeItem = getFirstChild(); treeItem; + treeItem = treeItem->scan(this)) { + CLinkItem *link = dynamic_cast<CLinkItem *>(treeItem); + CGameObject *gameObj = dynamic_cast<CGameObject *>(treeItem); + + if (link) { + // Skip links that aren't for the desired direction + if (link->getMovement() != msg->_movement) + continue; + + pt = Point((link->_bounds.left + link->_bounds.right) / 2, + (link->_bounds.top + link->_bounds.bottom) / 2); + } else if (gameObj) { + if (!gameObj->_visible || gameObj->getMovement() != msg->_movement) + continue; + + if (!gameObj->findPoint(pt)) + continue; + } else { + // Not a link or object, so ignore continue; + } - if (!gameObj->findPoint(pt)) - continue; - } else { - // Not a link or object, so ignore - continue; + foundPt = true; + break; } + } + if (foundPt) { // We've found a point on the object or link that has a // cursor for the given direction. So simulate a mouse // press and release on the desired point diff --git a/engines/titanic/events.cpp b/engines/titanic/events.cpp index f554796d09..f946f7b214 100644 --- a/engines/titanic/events.cpp +++ b/engines/titanic/events.cpp @@ -27,6 +27,7 @@ #include "titanic/events.h" #include "titanic/titanic.h" #include "titanic/main_game_window.h" +#include "titanic/star_control/star_control.h" namespace Titanic { @@ -108,10 +109,22 @@ void Events::pollEventsAndWait() { pollEvents(); g_system->delayMillis(10); - // Regularly update the sound mixer CGameManager *gameManager = g_vm->_window->_gameManager; - if (gameManager) + if (gameManager) { + // Regularly update the sound mixer gameManager->_sound.updateMixer(); + + // WORKAROUND: If in the Star Control view, update the camera + // frequently, to accomodate that the original had a higher + // draw rate than the ScummVM implementation does + CViewItem *view = gameManager->getView(); + if (view->getFullViewName() == "Bridge.Node 4.N") { + CStarControl *starControl = dynamic_cast<CStarControl *>( + view->findChildInstanceOf(CStarControl::_type)); + if (starControl && starControl->_visible) + starControl->updateCamera(); + } + } } bool Events::checkForNextFrameCounter() { diff --git a/engines/titanic/game/computer_screen.cpp b/engines/titanic/game/computer_screen.cpp index be9c87a540..179063d1b0 100644 --- a/engines/titanic/game/computer_screen.cpp +++ b/engines/titanic/game/computer_screen.cpp @@ -31,6 +31,7 @@ BEGIN_MESSAGE_MAP(CComputerScreen, CGameObject) ON_MESSAGE(MovieEndMsg) ON_MESSAGE(EnterViewMsg) ON_MESSAGE(TimerMsg) + ON_MESSAGE(MovementMsg) END_MESSAGE_MAP() CComputerScreen::CComputerScreen() : CGameObject() { @@ -68,9 +69,22 @@ bool CComputerScreen::MovieEndMsg(CMovieEndMsg *msg) { bool CComputerScreen::EnterViewMsg(CEnterViewMsg *msg) { loadFrame(26); + + // WORKAROUND: The original game leaves in a debug link that + // allows skipping of Doorbot arrival sequence. Disable it + static_cast<CLinkItem *>(getParent()->findByName("_TRACK,3,e-cu,4,E"))->_bounds.clear(); + return true; } +bool CComputerScreen::MovementMsg(CMovementMsg *msg) { + if (msg->_movement != MOVE_BACKWARDS) + return true; + + msg->_posToUse = Common::Point(320, 50); + return false; +} + bool CComputerScreen::TimerMsg(CTimerMsg *msg) { int handle; diff --git a/engines/titanic/game/computer_screen.h b/engines/titanic/game/computer_screen.h index 8fb1dcd4dc..8affef3aed 100644 --- a/engines/titanic/game/computer_screen.h +++ b/engines/titanic/game/computer_screen.h @@ -33,6 +33,7 @@ class CComputerScreen : public CGameObject { bool MovieEndMsg(CMovieEndMsg *msg); bool EnterViewMsg(CEnterViewMsg *msg); bool TimerMsg(CTimerMsg *msg); + bool MovementMsg(CMovementMsg *msg); public: CLASSDEF; CComputerScreen(); diff --git a/engines/titanic/game/transport/lift.cpp b/engines/titanic/game/transport/lift.cpp index ca5b74467a..17f1783494 100644 --- a/engines/titanic/game/transport/lift.cpp +++ b/engines/titanic/game/transport/lift.cpp @@ -22,6 +22,7 @@ #include "titanic/game/transport/lift.h" #include "titanic/pet_control/pet_control.h" +#include "titanic/moves/multi_move.h" #include "titanic/titanic.h" namespace Titanic { @@ -289,6 +290,17 @@ bool CLift::ActMsg(CActMsg *msg) { actMsg1.execute("RPanInLiftW"); CActMsg actMsg2("Lift.Node 2.S"); actMsg2.execute("LPanInLiftW"); + + // WORKAROUND: In the original, when Lift 4's head is removed, the other + // view directions use Node 2. These "removed" views have links, but their + // movement cursors weren't correctly set. This fixes them + CNamedItem *node2 = findRoom()->findByName("Node 2"); + static_cast<CMultiMove *>(node2->findByName("LMultiLiftPan"))->_cursorId = CURSOR_MOVE_LEFT; + static_cast<CLinkItem *>(node2->findByName("_PANR,2,N,E"))->_cursorId = CURSOR_MOVE_RIGHT; + static_cast<CLinkItem *>(node2->findByName("_PANL,2,E,N"))->_cursorId = CURSOR_MOVE_LEFT; + static_cast<CLinkItem *>(node2->findByName("_PANR,2,E,S"))->_cursorId = CURSOR_MOVE_RIGHT; + static_cast<CLinkItem *>(node2->findByName("_PANL,2,S,E"))->_cursorId = CURSOR_MOVE_LEFT; + static_cast<CMultiMove *>(node2->findByName("RMultiLiftPan"))->_cursorId = CURSOR_MOVE_RIGHT; } else if (msg->_action == "AddWrongHead") { _hasHead = true; _hasCorrectHead = false; diff --git a/engines/titanic/messages/messages.h b/engines/titanic/messages/messages.h index b5c8dd4e21..115976a70d 100644 --- a/engines/titanic/messages/messages.h +++ b/engines/titanic/messages/messages.h @@ -230,6 +230,7 @@ enum Movement { class CMovementMsg : public CMessage { public: Movement _movement; + Point _posToUse; public: CLASSDEF; CMovementMsg() : _movement(MOVE_NONE) {} diff --git a/engines/titanic/moves/move_player_in_parrot_room.cpp b/engines/titanic/moves/move_player_in_parrot_room.cpp index 186e448bba..dfe8cf547e 100644 --- a/engines/titanic/moves/move_player_in_parrot_room.cpp +++ b/engines/titanic/moves/move_player_in_parrot_room.cpp @@ -27,6 +27,7 @@ namespace Titanic { BEGIN_MESSAGE_MAP(CMovePlayerInParrotRoom, CMovePlayerTo) ON_MESSAGE(ActMsg) ON_MESSAGE(MouseButtonDownMsg) + ON_MESSAGE(MovementMsg) END_MESSAGE_MAP() CMovePlayerInParrotRoom::CMovePlayerInParrotRoom() : CMovePlayerTo() { @@ -58,13 +59,10 @@ bool CMovePlayerInParrotRoom::MouseButtonDownMsg(CMouseButtonDownMsg *msg) { return true; } -bool CMovePlayerInParrotRoom::findPoint(Point &pt) { - if (_destination == "ParrotLobby.Node 1.E") { - pt = Point(600, 180); - return true; - } else { - return CMovePlayerTo::findPoint(pt); - } +bool CMovePlayerInParrotRoom::MovementMsg(CMovementMsg *msg) { + if (msg->_movement == TURN_RIGHT) + msg->_posToUse = Point(600, 180); + return false; } } // End of namespace Titanic diff --git a/engines/titanic/moves/move_player_in_parrot_room.h b/engines/titanic/moves/move_player_in_parrot_room.h index 50a0b2a00e..637c8b8211 100644 --- a/engines/titanic/moves/move_player_in_parrot_room.h +++ b/engines/titanic/moves/move_player_in_parrot_room.h @@ -31,6 +31,7 @@ class CMovePlayerInParrotRoom : public CMovePlayerTo { DECLARE_MESSAGE_MAP; bool ActMsg(CActMsg *msg); bool MouseButtonDownMsg(CMouseButtonDownMsg *msg); + bool MovementMsg(CMovementMsg *msg); public: CLASSDEF; CMovePlayerInParrotRoom(); @@ -44,14 +45,6 @@ public: * Load the data for the class from file */ virtual void load(SimpleFile *file); - - /** - * Returns a point that falls within the object. Used for simulating - * mouse clicks for movement when arrow keys are pressed - * @param pt Return point - * @returns True if a point was found - */ - virtual bool findPoint(Point &pt); }; } // End of namespace Titanic diff --git a/engines/titanic/npcs/bilge_succubus.cpp b/engines/titanic/npcs/bilge_succubus.cpp index 84baa1865c..a1fc46874c 100644 --- a/engines/titanic/npcs/bilge_succubus.cpp +++ b/engines/titanic/npcs/bilge_succubus.cpp @@ -73,7 +73,8 @@ bool CBilgeSuccUBus::FrameMsg(CFrameMsg *msg) { bool CBilgeSuccUBus::PETReceiveMsg(CPETReceiveMsg *msg) { CPetControl *pet = getPetControl(); - if (_style) { + if (_motherBlocked) { + // Mother hasn't yet been unblocked, so don't receive anything if (_receiveStartFrame >= 0) playMovie(_receiveStartFrame, _receiveEndFrame, MOVIE_WAIT_FOR_FINISH); if (_afterReceiveStartFrame >= 0) @@ -130,7 +131,7 @@ bool CBilgeSuccUBus::PETDeliverMsg(CPETDeliverMsg *msg) { _isFeathers = mailObject->getName() == "Feathers"; _sendAction = SA_SENT; - if (_style) { + if (_motherBlocked) { if (_isFeathers) { startTalking(this, 230022); _sendAction = SA_FEATHERS; @@ -189,7 +190,7 @@ bool CBilgeSuccUBus::MovieEndMsg(CMovieEndMsg *msg) { playSound("z#30.wav"); } else { if (msg->_endFrame == _onEndFrame && pet) { - if (_style) { + if (_motherBlocked) { startTalking(this, getRandomNumber(1) ? 230062 : 230063); } else if (!findMail(pet->getRoomFlags())) { switch (getRandomNumber(4)) { @@ -254,7 +255,7 @@ bool CBilgeSuccUBus::MovieEndMsg(CMovieEndMsg *msg) { } else if (msg->_endFrame == _sneezing2EndFrame) { changeView("BilgeRoomWith.Node 1.N", ""); - _style = false; + _motherBlocked = false; resetMail(); if (_mailP) { diff --git a/engines/titanic/npcs/succubus.cpp b/engines/titanic/npcs/succubus.cpp index ef681f64b8..522269b41b 100644 --- a/engines/titanic/npcs/succubus.cpp +++ b/engines/titanic/npcs/succubus.cpp @@ -47,7 +47,7 @@ BEGIN_MESSAGE_MAP(CSuccUBus, CTrueTalkNPC) END_MESSAGE_MAP() bool CSuccUBus::_isOn; -bool CSuccUBus::_style; +bool CSuccUBus::_motherBlocked; bool CSuccUBus::_enabled; CSuccUBus::CSuccUBus() : CTrueTalkNPC() { @@ -118,7 +118,7 @@ void CSuccUBus::save(SimpleFile *file, int indent) { file->writeNumberLine(_okEndFrame, indent); file->writeNumberLine(_flagsComparison, indent); - file->writeNumberLine(_style, indent); + file->writeNumberLine(_motherBlocked, indent); file->writeNumberLine(_afterReceiveStartFrame, indent); file->writeNumberLine(_afterReceiveEndFrame, indent); file->writeNumberLine(_trayOutStartFrame, indent); @@ -181,7 +181,7 @@ void CSuccUBus::load(SimpleFile *file) { _okEndFrame = file->readNumber(); _flagsComparison = (RoomFlagsComparison)file->readNumber(); - _style = file->readNumber(); + _motherBlocked = file->readNumber(); _afterReceiveStartFrame = file->readNumber(); _afterReceiveEndFrame = file->readNumber(); _trayOutStartFrame = file->readNumber(); @@ -385,9 +385,10 @@ bool CSuccUBus::PETDeliverMsg(CPETDeliverMsg *msg) { if (!pet) return true; - uint destRoomFlags = pet->getRoomFlags(); - CGameObject *mailObject = findMail(destRoomFlags); + uint srcRoomFlags = pet->getRoomFlags(); + CGameObject *mailObject = findMail(srcRoomFlags); if (!mailObject) { + // Nothing to send switch (getRandomNumber(2)) { case 0: startTalking(this, 70111, findView()); @@ -422,7 +423,7 @@ bool CSuccUBus::PETDeliverMsg(CPETDeliverMsg *msg) { if (_isFeathers) { // The feather has special handling to be rejected by the SuccUBus _sendLost = false; - sendMail(destRoomFlags, roomFlags); + sendMail(srcRoomFlags, roomFlags); pet->phonographAction(""); if (_okStartFrame >= 0) { @@ -570,7 +571,7 @@ bool CSuccUBus::MovieEndMsg(CMovieEndMsg *msg) { stopSound(_soundHandle); _soundHandle = -1; - switch (getRandomNumber(_style ? 7 : 5, &_priorRandomVal2)) { + switch (getRandomNumber(_motherBlocked ? 7 : 5, &_priorRandomVal2)) { case 2: startTalking(this, 230001, findView()); break; diff --git a/engines/titanic/npcs/succubus.h b/engines/titanic/npcs/succubus.h index 483ef54f47..94e0bebe54 100644 --- a/engines/titanic/npcs/succubus.h +++ b/engines/titanic/npcs/succubus.h @@ -50,7 +50,7 @@ class CSuccUBus : public CTrueTalkNPC { bool MouseDragStartMsg(CMouseDragStartMsg *msg); protected: static bool _isOn; - static bool _style; + static bool _motherBlocked; static bool _enabled; protected: int _initialStartFrame; diff --git a/engines/titanic/star_control/star_control.h b/engines/titanic/star_control/star_control.h index 8013eed850..90de2eb3eb 100644 --- a/engines/titanic/star_control/star_control.h +++ b/engines/titanic/star_control/star_control.h @@ -97,6 +97,11 @@ public: * Called when a star destination is set */ void starDestinationSet(); + + /** + * Updates the camerea for the star view + */ + void updateCamera() { _view.updateCamera(); } }; } // End of namespace Titanic diff --git a/engines/titanic/star_control/star_view.cpp b/engines/titanic/star_control/star_view.cpp index 576fd87b54..465e974d44 100644 --- a/engines/titanic/star_control/star_view.cpp +++ b/engines/titanic/star_control/star_view.cpp @@ -97,7 +97,7 @@ void CStarView::draw(CScreenManager *screenManager) { if (_homePhotoMask) _homePhotoMask->draw(screenManager, Point(20, 187)); } else { - fn1(); + updateCamera(); // Render the display _videoSurface->clear(); @@ -255,7 +255,10 @@ void CStarView::resetPosition() { _camera.setPosition(FVector(0.0, 0.0, 0.0)); } -bool CStarView::fn1() { +bool CStarView::updateCamera() { + if (_fader.isActive() || _showingPhoto) + return false; + if (_videoSurface) { CErrorCode errorCode; _camera.updatePosition(&errorCode); diff --git a/engines/titanic/star_control/star_view.h b/engines/titanic/star_control/star_view.h index a98886eb51..204c02336c 100644 --- a/engines/titanic/star_control/star_view.h +++ b/engines/titanic/star_control/star_view.h @@ -50,7 +50,6 @@ private: bool _field218; bool _showingPhoto; private: - bool fn1(); void fn18(CStarCamera *camera); void fn19(int v); @@ -95,6 +94,11 @@ public: void draw(CScreenManager *screenManager); /** + * Updates the camera, allowing for movement + */ + bool updateCamera(); + + /** * Handles mouse down messages */ bool MouseButtonDownMsg(int unused, const Point &pt); |