From a21133ed12228e9a818b696bbc148f5b53946a30 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 20 Aug 2011 19:14:23 +1000 Subject: TSAGE: Implemented Blue Force Scene #50 - Map Scene --- engines/tsage/blue_force/blueforce_logic.cpp | 114 ++++++++++- engines/tsage/blue_force/blueforce_logic.h | 46 ++++- engines/tsage/blue_force/blueforce_scenes0.cpp | 263 ++++++++++++++++++++++++- engines/tsage/blue_force/blueforce_scenes0.h | 24 ++- 4 files changed, 429 insertions(+), 18 deletions(-) (limited to 'engines/tsage/blue_force') diff --git a/engines/tsage/blue_force/blueforce_logic.cpp b/engines/tsage/blue_force/blueforce_logic.cpp index ec85e48fbf..46c9307632 100644 --- a/engines/tsage/blue_force/blueforce_logic.cpp +++ b/engines/tsage/blue_force/blueforce_logic.cpp @@ -33,7 +33,7 @@ namespace BlueForce { void BlueForceGame::start() { // Start the game - _globals->_sceneManager.changeScene(100); + _globals->_sceneManager.changeScene(50); _globals->_events.setCursor(CURSOR_WALK); } @@ -45,6 +45,7 @@ Scene *BlueForceGame::createScene(int sceneNumber) { // Tsunami Title Screen return new Scene20(); case 50: + return new Scene50(); case 60: error("Scene group 0 not implemented"); /* Scene Group #1 */ @@ -55,6 +56,7 @@ Scene *BlueForceGame::createScene(int sceneNumber) { // Introduction Bar Room return new Scene109(); case 110: + case 114: case 115: case 125: @@ -131,23 +133,23 @@ Scene *BlueForceGame::createScene(int sceneNumber) { /*--------------------------------------------------------------------------*/ -ObjArray::ObjArray(): EventHandler() { +AObjectArray::AObjectArray(): EventHandler() { _inUse = false; clear(); } -void ObjArray::clear() { +void AObjectArray::clear() { for (int i = 0; i < OBJ_ARRAY_SIZE; ++i) _objList[i] = NULL; } -void ObjArray::synchronize(Serializer &s) { +void AObjectArray::synchronize(Serializer &s) { EventHandler::synchronize(s); for (int i = 0; i < OBJ_ARRAY_SIZE; ++i) SYNC_POINTER(_objList[i]); } -void ObjArray::process(Event &event) { +void AObjectArray::process(Event &event) { if (_inUse) error("Array error"); _inUse = true; @@ -160,7 +162,7 @@ void ObjArray::process(Event &event) { _inUse = false; } -void ObjArray::dispatch() { +void AObjectArray::dispatch() { if (_inUse) error("Array error"); _inUse = true; @@ -173,12 +175,94 @@ void ObjArray::dispatch() { _inUse = false; } +int AObjectArray::getNewIndex() { + for (int i = 0; i < OBJ_ARRAY_SIZE; ++i) { + if (!_objList[i]) + return i; + } + error("AObjectArray too full."); +} + +void AObjectArray::add(EventHandler *obj) { + int idx = getNewIndex(); + _objList[idx] = obj; +} + +void AObjectArray::remove(EventHandler *obj) { + for (int i = 0; i < OBJ_ARRAY_SIZE; ++i) { + if (_objList[i] == obj) { + _objList[i] = NULL; + return; + } + } +} + +/*--------------------------------------------------------------------------*/ + +Timer::Timer() { + _endFrame = 0; + _endAction = NULL; + _tickAction = NULL; +} + +void Timer::remove() { + _endFrame = 0; + _endAction = NULL; + + ((Scene100 *)BF_GLOBALS._sceneManager._scene)->removeTimer(this); +} + +void Timer::signal() { + assert(_endAction); + Action *action = _endAction; + remove(); + action->signal(); +} + +void Timer::dispatch() { + if (_tickAction) + _tickAction->dispatch(); + + if (_endFrame) { + uint32 frameNumber = BF_GLOBALS._events.getFrameNumber(); + if (frameNumber > _endFrame) + // Timer has expired + signal(); + } +} + +void Timer::set(uint32 delay, Action *action) { + assert(delay != 0); + + _endFrame = BF_GLOBALS._sceneHandler->getFrameDifference() + delay; + _endAction = action; + + ((SceneExt *)BF_GLOBALS._sceneManager._scene)->addTimer(this); +} + +/*--------------------------------------------------------------------------*/ + +void SceneItemType1::process(Event &event) { + if (_action) + _action->process(event); +} + +void SceneItemType1::startMove(SceneObject *sceneObj, va_list va) { + warning("TODO: sub_1621C"); +} + +/*--------------------------------------------------------------------------*/ + +void SceneItemType2::startMove(SceneObject *sceneObj, va_list va) { +} + /*--------------------------------------------------------------------------*/ SceneExt::SceneExt(): Scene() { warning("TODO: dword_503AA/dword_503AE/dword_53030"); _field372 = 0; + _field37A = 0; _field37C = NULL; } @@ -200,7 +284,7 @@ void SceneExt::process(Event &event) { } void SceneExt::dispatch() { - _objArray1.dispatch(); + _timerList.dispatch(); if (_field37A) { if ((--_field37A == 0) && BF_GLOBALS._v4CEA2) { @@ -250,6 +334,22 @@ void GameScene::remove() { BF_GLOBALS._scenePalette._field412 = 1; } +/*--------------------------------------------------------------------------*/ + +void SceneHandlerExt::postInit(SceneObjectList *OwnerList) { + SceneHandler::postInit(OwnerList); + + // Load the low end palette data + GLOBALS._scenePalette.loadPalette(2); + GLOBALS._scenePalette.refresh(); +} + +void SceneHandlerExt::process(Event &event) { + SceneHandler::process(event); + + // TODO: All the new stuff from Blue Force +} + } // End of namespace BlueForce } // End of namespace TsAGE diff --git a/engines/tsage/blue_force/blueforce_logic.h b/engines/tsage/blue_force/blueforce_logic.h index 1ff6ecf507..9ab8a87a0c 100644 --- a/engines/tsage/blue_force/blueforce_logic.h +++ b/engines/tsage/blue_force/blueforce_logic.h @@ -44,23 +44,52 @@ public: }; #define OBJ_ARRAY_SIZE 10 -class ObjArray: public EventHandler { +class AObjectArray: public EventHandler { public: EventHandler *_objList[OBJ_ARRAY_SIZE]; bool _inUse; + int getNewIndex(); public: - ObjArray(); + AObjectArray(); void clear(); - virtual Common::String getClassName() { return "ObjArray"; } + virtual Common::String getClassName() { return "AObjectArray"; } virtual void synchronize(Serializer &s); virtual void process(Event &event); virtual void dispatch(); + + void add(EventHandler *obj); + void remove(EventHandler *obj); +}; + +class Timer: public EventHandler { +public: + Action *_tickAction; + Action *_endAction; + uint32 _endFrame; +public: + Timer(); + void set(uint32 delay, Action *action); + + virtual void remove(); + virtual void signal(); + virtual void dispatch(); +}; + +class SceneItemType1: public SceneItem { +public: + virtual void process(Event &event); + virtual void startMove(SceneObject *sceneObj, va_list va); +}; + +class SceneItemType2: public SceneItemType1 { +public: + virtual void startMove(SceneObject *sceneObj, va_list va); }; class SceneExt: public Scene { public: - ObjArray _objArray1, _objArray2; + AObjectArray _timerList, _objArray2; int _field372; int _field37A; EventHandler *_field37C; @@ -75,6 +104,9 @@ public: virtual void dispatch(); virtual void loadScene(int sceneNum); virtual void proc13() { warning("TODO: SceneExt::proc13"); } + + void addTimer(Timer *timer) { _timerList.add(timer); } + void removeTimer(Timer *timer) { _timerList.remove(timer); } }; class GameScene: public SceneExt { @@ -88,6 +120,12 @@ public: virtual void remove(); }; +class SceneHandlerExt: public SceneHandler { +public: + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void process(Event &event); +}; + class BlueAnimatedSpeaker: public Speaker { public: }; diff --git a/engines/tsage/blue_force/blueforce_scenes0.cpp b/engines/tsage/blue_force/blueforce_scenes0.cpp index cc0f9bb1fd..bf9a7572ae 100644 --- a/engines/tsage/blue_force/blueforce_scenes0.cpp +++ b/engines/tsage/blue_force/blueforce_scenes0.cpp @@ -199,14 +199,13 @@ void Scene20::postInit(SceneObjectList *OwnerList) { *--------------------------------------------------------------------------*/ Scene50::Tooltip::Tooltip(): SavedObject() { - strcpy(_msg, ""); - _field60 = _field62 = 0; + _newSceneNumber = _locationId = 0; } void Scene50::Tooltip::synchronize(Serializer &s) { SavedObject::synchronize(s); _bounds.synchronize(s); - s.syncBytes((byte *)&_msg[0], 84); + s.syncString(_msg); } void Scene50::Tooltip2::signal() { @@ -237,8 +236,266 @@ void Scene50::Tooltip2::dispatch() { } } +void Scene50::Tooltip::set(const Rect &bounds, int v60, const Common::String &msg, int v62) { + _bounds = bounds; + _newSceneNumber = v60; + _msg = msg; + _locationId = v62; +} + +void Scene50::Tooltip::update() { + // Set up the text object for the scene with the appropriate settings + Scene50 *scene = (Scene50 *)BF_GLOBALS._sceneManager._scene; + scene->_text._fontNumber = 10; + scene->_text._color1 = BF_GLOBALS._scenePalette._colors.foreground; + scene->_text._color2 = BF_GLOBALS._scenePalette._colors.background; + scene->_text.setup(_msg); + + int yp = (scene->_text._textSurface.getBounds().height() == 0) ? _bounds.bottom : _bounds.top; + scene->_text.setPosition(Common::Point(_bounds.left, yp)); +} + +void Scene50::Tooltip::highlight(bool btnDown) { + Scene50 *scene = (Scene50 *)BF_GLOBALS._sceneManager._scene; + + scene->_field382 = _newSceneNumber; + if ((scene->_field380 != 0) || (scene->_field380 != _newSceneNumber)) + update(); + + if (btnDown) { + if ((BF_GLOBALS._bikiniHutState == 14) && BF_GLOBALS.getFlag(98)) + scene->_sceneNumber = 600; + else if (BF_GLOBALS._bikiniHutState == 5) + scene->_sceneNumber = 410; + else { + BF_GLOBALS._v4CEF4 = _newSceneNumber; + + switch (BF_GLOBALS._v4CEF2) { + case 330: + case 340: + case 342: + BF_GLOBALS._player.disableControl(); + if (_locationId != BF_GLOBALS._mapLocationId) { + scene->_sceneNumber = 330; + } else { + scene->_sceneNumber = (BF_GLOBALS._v4CEA2 != 1) || (BF_GLOBALS._bikiniHutState < 1) || + (BF_GLOBALS._bikiniHutState >= 2) ? 342 : 340; + } + break; + + case 410: + case 551: + if (BF_GLOBALS.getFlag((BF_GLOBALS._v4CEF2 == 410) ? 41 : 40)) { + BF_GLOBALS._mapLocationId = _locationId; + BF_GLOBALS._player.disableControl(); + scene->_sceneNumber = _newSceneNumber; + } else { + BF_GLOBALS._v4CEA8 = 4; + BF_GLOBALS._sceneManager.changeScene(666); + return; + } + break; + + case 300: + if (_locationId == 1) { + BF_GLOBALS._v4CEF4 = 300; + _newSceneNumber = 300; + } + // Deliberate fall through to default + default: + BF_GLOBALS._mapLocationId = _locationId; + BF_GLOBALS._player.disableControl(); + scene->_sceneNumber = _newSceneNumber; + break; + } + + // Signal the scene to change to the new scene + scene->_sceneMode = 1; + scene->signal(); + } + } +} + /*--------------------------------------------------------------------------*/ +Scene50::Scene50(): SceneExt() { + _field382 = 0; + _field380 = 0; +} + +void Scene50::postInit(SceneObjectList *OwnerList) { + SceneExt::postInit(); + + BF_GLOBALS._interfaceY = 200; + BF_GLOBALS._player.postInit(); + BF_GLOBALS._player.setVisage(830); + BF_GLOBALS._player.setStrip(3); + BF_GLOBALS._player.setPosition(Common::Point(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2)); + BF_GLOBALS._player.hide(); + BF_GLOBALS._player.enableControl(); + BF_GLOBALS._player._uiEnabled = false; + + BF_GLOBALS._scrollFollower = NULL; + _text._color1 = 19; + _text._color2 = 9; + _text._color3 = 9; + _text._width = 75; + _text._fontNumber = 4; + _text._textMode = ALIGN_LEFT; + _text.fixPriority(256); + + // Set all the hotspots + _location3.set(Rect(10, 92, 24, 105), 180, GRANDMA_FRANNIE, 4); + _location2.set(Rect(443, 149, 508, 178), 330, MARINA, 2); + _location1.set(Rect(573, 103, 604, 130), 190, POLICE_DEPARTMENT, 1); + _location4.set(Rect(313, 21, 325, 33), 114, TONYS_BAR, 8); + _location8.set(Rect(69, 79, 82, 88), 580, CHILD_PROTECTIVE_SERVICES, 256); + _location6.set(Rect(242, 131, 264, 144), 440, ALLEY_CAT, 64); + _location5.set(Rect(383, 57, 402, 70), 380, CITY_HALL_JAIL, 32); + _location7.set(Rect(128, 32, 143, 42), 800, JAMISON_RYAN, 128); + _location9.set(Rect(349, 125, 359, 132), + (BF_GLOBALS._bikiniHutState == 13) || (BF_GLOBALS._bikiniHutState == 14) ? 551 : 550, + BIKINI_HUT, 16); + + _item.setBounds(Rect(0, 0, SCREEN_WIDTH * 2, SCREEN_HEIGHT)); + BF_GLOBALS._sceneItems.push_back(&_item); + + // Find the location to start at + int selectedTooltip = BF_GLOBALS._mapLocationId; + Tooltip *tooltip = NULL; + int xp = 0; + + switch (selectedTooltip) { + case 1: + tooltip = &_location1; + xp = 588; + break; + case 2: + tooltip = &_location2; + xp = 475; + break; + case 4: + tooltip = &_location3; + xp = 17; + break; + case 8: + tooltip = &_location4; + xp = 319; + break; + case 32: + tooltip = &_location5; + xp = 392; + break; + case 64: + tooltip = &_location6; + xp = 253; + break; + case 128: + tooltip = &_location7; + xp = 135; + break; + case 16: + tooltip = &_location9; + xp = 354; + break; + case 256: + tooltip = &_location8; + xp = 75; + break; + } + + loadBackground(xp - 160, 0); + tooltip->update(); + + _timer.set(240, this); + _sceneBounds.center(xp, SCREEN_HEIGHT / 2); + loadScene(55); + _sceneMode = 2; +} + +void Scene50::remove() { + // Blank out the screen + BF_GLOBALS._screenSurface.fillRect(BF_GLOBALS._screenSurface.getBounds(), 0); + + SceneExt::remove(); + BF_GLOBALS._v4E238 = 1; +} + +void Scene50::signal() { + if (_sceneMode == 1) { + // Destination selected + if ((BF_GLOBALS._v4CEF2 == 551) && (_sceneNumber != BF_GLOBALS._v4CEF2)) { + BF_GLOBALS.setFlag(109); + BF_GLOBALS.setFlag(115); + BF_GLOBALS.setFlag(121); + BF_GLOBALS.setFlag(127); + BF_GLOBALS.setFlag(133); + } + + if ((BF_GLOBALS._v4CEF2 == 410) && (_sceneNumber != BF_GLOBALS._v4CEF2)) { + BF_GLOBALS.setFlag(125); + } + + if ((BF_GLOBALS._v4CEF2 == 340) && (_sceneNumber != BF_GLOBALS._v4CEF2)) { + BF_GLOBALS.setFlag(123); + } + + if ((BF_GLOBALS._v4CEF2 == 380) && (_sceneNumber != BF_GLOBALS._v4CEF2)) { + if (BF_GLOBALS._bikiniHutState >= 4) + BF_GLOBALS.setFlag(129); + if (BF_GLOBALS._bikiniHutState >= 6) + BF_GLOBALS.setFlag(131); + if (BF_GLOBALS._bikiniHutState == 3) { + BF_GLOBALS._v4CEA8 = 19; + _sceneNumber = 666; + } + } + + if ((_sceneNumber == 551) && BF_GLOBALS.getFlag(147)) + _sceneNumber = 550; + + BF_GLOBALS._sound1.fadeOut2(NULL); + BF_GLOBALS._sceneManager.changeScene(_sceneNumber); + + } else if (_sceneMode == 2) { + // Initial delay complete, time to switch to interactive mode + _text.remove(); + BF_GLOBALS._player.enableControl(); + _sceneMode = 0; + _field380 = 0; + } +} + +void Scene50::process(Event &event) { + SceneExt::process(event); + Common::Point pt(event.mousePos.x + _sceneBounds.left, event.mousePos.y + _sceneBounds.top); + bool mouseDown = false; + _field382 = 0; + + if ((event.mousePos.x > 270 && (_sceneBounds.right < (SCREEN_WIDTH * 2)))) + loadBackground(4, 0); + else if ((event.mousePos.x < 50) && (_sceneBounds.left > 0)) + loadBackground(-4, 0); + else + mouseDown = event.eventType == EVENT_BUTTON_DOWN; + + if (BF_GLOBALS._player._uiEnabled) { + Tooltip *tooltipList[9] = { &_location1, &_location2, &_location3, &_location4, + &_location5, &_location6, &_location7, &_location8, &_location9 }; + + for (int idx = 0; idx < 9; ++idx) { + if (tooltipList[idx]->_bounds.contains(pt)) { + // Found a tooltip to highlight + tooltipList[idx]->highlight(mouseDown); + return; + } + } + + // No hotspot selected, so remove any current tooltip display + _text.remove(); + } +} + } // End of namespace BlueForce } // End of namespace TsAGE diff --git a/engines/tsage/blue_force/blueforce_scenes0.h b/engines/tsage/blue_force/blueforce_scenes0.h index 587941e59e..5c98184ed8 100644 --- a/engines/tsage/blue_force/blueforce_scenes0.h +++ b/engines/tsage/blue_force/blueforce_scenes0.h @@ -59,11 +59,14 @@ class Scene50: public SceneExt { class Tooltip: public SavedObject { public: Rect _bounds; - char _msg[80]; - int _field60; - int _field62; + Common::String _msg; + int _newSceneNumber; + int _locationId; public: Tooltip(); + void set(const Rect &bounds, int v60, const Common::String &msg, int v62); + void update(); + void highlight(bool btnDown); virtual Common::String getClassName() { return "Scene50_Tooltip"; } virtual void synchronize(Serializer &s); @@ -77,7 +80,20 @@ class Scene50: public SceneExt { virtual void dispatch(); }; public: - + int _field380, _field382; + int _sceneNumber; + SceneText _text; + SceneItemType2 _item; + Tooltip _location1, _location2, _location3, _location4, _location5; + Tooltip _location6, _location7, _location8, _location9; + Timer _timer; +public: + Scene50(); + virtual Common::String getClassName() { return "Scene50"; } + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void remove(); + virtual void signal(); + virtual void process(Event &event); }; } // End of namespace BlueForce -- cgit v1.2.3