diff options
author | Alyssa Milburn | 2011-08-22 20:03:05 +0200 |
---|---|---|
committer | Alyssa Milburn | 2011-08-22 20:03:05 +0200 |
commit | 84063dc9727a9f55e09d39574027beab695680e6 (patch) | |
tree | d71a9599cb550d9f7949a2d3209574064e054d85 /engines/tsage | |
parent | c6e89df3d940747a85d447f172e2323c800f5eaf (diff) | |
parent | a39a3eda46aea108a51556f001617ad28d29e520 (diff) | |
download | scummvm-rg350-84063dc9727a9f55e09d39574027beab695680e6.tar.gz scummvm-rg350-84063dc9727a9f55e09d39574027beab695680e6.tar.bz2 scummvm-rg350-84063dc9727a9f55e09d39574027beab695680e6.zip |
Merge remote-tracking branch 'origin/master' into soltys_wip2
Diffstat (limited to 'engines/tsage')
57 files changed, 2547 insertions, 612 deletions
diff --git a/engines/tsage/blue_force/blueforce_logic.cpp b/engines/tsage/blue_force/blueforce_logic.cpp new file mode 100644 index 0000000000..46c9307632 --- /dev/null +++ b/engines/tsage/blue_force/blueforce_logic.cpp @@ -0,0 +1,355 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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. + * + */ + +#include "tsage/blue_force/blueforce_logic.h" +#include "tsage/blue_force/blueforce_scenes0.h" +#include "tsage/blue_force/blueforce_scenes1.h" +#include "tsage/scenes.h" +#include "tsage/tsage.h" +#include "tsage/staticres.h" + +namespace TsAGE { + +namespace BlueForce { + +void BlueForceGame::start() { + // Start the game + _globals->_sceneManager.changeScene(50); + + _globals->_events.setCursor(CURSOR_WALK); +} + +Scene *BlueForceGame::createScene(int sceneNumber) { + switch (sceneNumber) { + /* Scene Group #0 */ + case 20: + // Tsunami Title Screen + return new Scene20(); + case 50: + return new Scene50(); + case 60: + error("Scene group 0 not implemented"); + /* Scene Group #1 */ + case 100: + // Tsnunami Title Screen #2 + return new Scene100(); + case 109: + // Introduction Bar Room + return new Scene109(); + case 110: + + case 114: + case 115: + case 125: + case 140: + case 150: + case 160: + case 180: + case 190: + error("Scene group 1 not implemented"); + case 200: + case 210: + case 220: + case 225: + case 265: + case 270: + case 271: + case 280: + error("Scene group 2 not implemented"); + case 300: + case 315: + case 325: + case 330: + case 340: + case 342: + case 350: + case 355: + case 360: + case 370: + case 380: + case 385: + case 390: + error("Scene group 3 not implemented"); + case 410: + case 415: + case 440: + case 450: + error("Scene group 4 not implemented"); + case 550: + case 551: + case 560: + case 570: + case 580: + case 590: + error("Scene group 5 not implemented"); + case 600: + case 620: + case 666: + case 690: + error("Scene group 6 not implemented"); + case 710: + error("Scene group 7 not implemented"); + case 800: + case 810: + case 820: + case 830: + case 840: + case 850: + case 860: + case 870: + case 880: + error("Scene group 8 not implemented"); + case 900: + case 910: + case 920: + case 930: + case 935: + case 940: + error("Scene group 9 not implemented"); + default: + error("Unknown scene number - %d", sceneNumber); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +AObjectArray::AObjectArray(): EventHandler() { + _inUse = false; + clear(); +} + +void AObjectArray::clear() { + for (int i = 0; i < OBJ_ARRAY_SIZE; ++i) + _objList[i] = NULL; +} + +void AObjectArray::synchronize(Serializer &s) { + EventHandler::synchronize(s); + for (int i = 0; i < OBJ_ARRAY_SIZE; ++i) + SYNC_POINTER(_objList[i]); +} + +void AObjectArray::process(Event &event) { + if (_inUse) + error("Array error"); + _inUse = true; + + for (int i = 0; i < OBJ_ARRAY_SIZE; ++i) { + if (_objList[i]) + _objList[i]->process(event); + } + + _inUse = false; +} + +void AObjectArray::dispatch() { + if (_inUse) + error("Array error"); + _inUse = true; + + for (int i = 0; i < OBJ_ARRAY_SIZE; ++i) { + if (_objList[i]) + _objList[i]->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; +} + +void SceneExt::postInit(SceneObjectList *OwnerList) { + Scene::postInit(OwnerList); + if (BF_GLOBALS._v4CEA2) { + // Blank out the bottom portion of the screen + BF_GLOBALS._interfaceY = BF_INTERFACE_Y; + + Rect r(0, BF_INTERFACE_Y, SCREEN_WIDTH, SCREEN_HEIGHT); + BF_GLOBALS.gfxManager().getSurface().fillRect(r, 0); + } +} + +void SceneExt::process(Event &event) { + _objArray2.process(event); + if (!event.handled) + Scene::process(event); +} + +void SceneExt::dispatch() { + _timerList.dispatch(); + + if (_field37A) { + if ((--_field37A == 0) && BF_GLOBALS._v4CEA2) { + if (BF_GLOBALS._v4E238 && (BF_GLOBALS._v4CF9E == 1)) { + warning("sub_1B052"); + } + + _field37A = 0; + } + } + + Scene::dispatch(); +} + +void SceneExt::loadScene(int sceneNum) { + Scene::loadScene(sceneNum); + + _v51C34.top = 0; + _v51C34.bottom = 300; +} + +/*--------------------------------------------------------------------------*/ + +GameScene::GameScene() { + +} + +void GameScene::postInit(SceneObjectList *OwnerList) { + _field794 = 0; + _field412 = 1; + SceneExt::postInit(OwnerList); +} + +void GameScene::remove() { + SceneExt::remove(); + if (_field794 == 1) { + for (SynchronizedList<SceneObject *>::iterator i = BF_GLOBALS._sceneObjects->begin(); + i != BF_GLOBALS._sceneObjects->end(); ++i) + (*i)->remove(); + + BF_GLOBALS._sceneObjects->draw(); + BF_GLOBALS._scenePalette.loadPalette(2); + BF_GLOBALS._v51C44 = 1; + BF_GLOBALS._v51C42 = 1; + } + + 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 new file mode 100644 index 0000000000..9ab8a87a0c --- /dev/null +++ b/engines/tsage/blue_force/blueforce_logic.h @@ -0,0 +1,137 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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. + * + */ + +#ifndef TSAGE_BLUEFORCE_LOGIC_H +#define TSAGE_BLUEFORCE_LOGIC_H + +#include "common/scummsys.h" +#include "tsage/events.h" +#include "tsage/core.h" +#include "tsage/scenes.h" +#include "tsage/globals.h" + +#define BF_INTERFACE_Y 168 + +namespace TsAGE { + +namespace BlueForce { + +using namespace TsAGE; + +class BlueForceGame: public Game { +public: + virtual void start(); + virtual Scene *createScene(int sceneNumber); +}; + +#define OBJ_ARRAY_SIZE 10 +class AObjectArray: public EventHandler { +public: + EventHandler *_objList[OBJ_ARRAY_SIZE]; + bool _inUse; + int getNewIndex(); +public: + AObjectArray(); + void clear(); + + 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: + AObjectArray _timerList, _objArray2; + int _field372; + int _field37A; + EventHandler *_field37C; + + Rect _v51C34; +public: + SceneExt(); + + virtual Common::String getClassName() { return "SceneExt"; } + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void process(Event &event); + 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 { +public: + int _field412; + int _field794; +public: + GameScene(); + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void remove(); +}; + +class SceneHandlerExt: public SceneHandler { +public: + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void process(Event &event); +}; + +class BlueAnimatedSpeaker: public Speaker { +public: +}; + +} // End of namespace BlueForce + +} // End of namespace TsAGE + +#endif diff --git a/engines/tsage/blue_force/blueforce_scenes0.cpp b/engines/tsage/blue_force/blueforce_scenes0.cpp new file mode 100644 index 0000000000..f1b714ec6c --- /dev/null +++ b/engines/tsage/blue_force/blueforce_scenes0.cpp @@ -0,0 +1,501 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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. + * + */ + +#include "tsage/blue_force/blueforce_scenes0.h" +#include "tsage/scenes.h" +#include "tsage/tsage.h" +#include "tsage/staticres.h" + +namespace TsAGE { + +namespace BlueForce { + +/*-------------------------------------------------------------------------- + * Scene 20 - Tsunami Title Screen + * + *--------------------------------------------------------------------------*/ + +void Scene20::Action1::signal() { + Scene20 *scene = (Scene20 *)BF_GLOBALS._sceneManager._scene; + static byte black[3] = { 0, 0, 0 }; + + switch (_actionIndex++) { + case 0: + setDelay(2); + break; + case 1: + _sound.play(1); + BF_GLOBALS._scenePalette.addRotation(64, 127, -1, 1, this); + break; + case 2: + scene->_object1.setVisage(22); + scene->_object1._strip = 1; + scene->_object1._frame = 1; + scene->_object1.changeZoom(100); + + scene->_object2.setVisage(22); + scene->_object2._strip = 2; + scene->_object2._frame = 1; + scene->_object2.changeZoom(100); + + scene->_object3.setVisage(22); + scene->_object3._strip = 3; + scene->_object3._frame = 1; + scene->_object3.changeZoom(100); + + scene->_object4.setVisage(22); + scene->_object4._strip = 4; + scene->_object4._frame = 1; + scene->_object4.changeZoom(100); + + scene->_object5.setVisage(22); + scene->_object5._strip = 5; + scene->_object5._frame = 1; + scene->_object5.changeZoom(100); + + scene->_object6.setVisage(22); + scene->_object6._strip = 6; + scene->_object6._frame = 1; + scene->_object6.changeZoom(100); + + scene->_object7.setVisage(22); + scene->_object7._strip = 7; + scene->_object7._frame = 1; + scene->_object7.changeZoom(100); + + scene->_object8.setVisage(22); + scene->_object8._strip = 8; + scene->_object8._frame = 1; + scene->_object8.changeZoom(100); + + setDelay(1); + break; + case 3: + BF_GLOBALS._scenePalette.addFader(scene->_scenePalette._palette, 256, 8, this); + break; + case 4: + setDelay(60); + break; + case 5: + scene->_object2.animate(ANIM_MODE_5, NULL); + scene->_object3.animate(ANIM_MODE_5, NULL); + scene->_object4.animate(ANIM_MODE_5, NULL); + scene->_object5.animate(ANIM_MODE_5, NULL); + scene->_object6.animate(ANIM_MODE_5, NULL); + scene->_object7.animate(ANIM_MODE_5, this); + break; + case 6: + setDelay(120); + break; + case 7: + BF_GLOBALS._scenePalette.addFader(black, 1, 5, this); + break; + case 8: + BF_GLOBALS._sceneManager.changeScene(100); + remove(); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene20::postInit(SceneObjectList *OwnerList) { + loadScene(20); + Scene::postInit(); + setZoomPercents(60, 85, 200, 100); + + _scenePalette.loadPalette(1); + _scenePalette.loadPalette(22); + + _object1.postInit(); + _object1.setVisage(21); + _object1._strip = 1; + _object1._frame = 1; + _object1.animate(ANIM_MODE_NONE, NULL); + _object1.setPosition(Common::Point(62, 85)); + _object1.changeZoom(100); + + _object2.postInit(); + _object2.setVisage(21); + _object2._strip = 2; + _object2._frame = 1; + _object2.animate(ANIM_MODE_NONE, NULL); + _object2.setPosition(Common::Point(27, 94)); + _object2.changeZoom(100); + + _object3.postInit(); + _object3.setVisage(21); + _object3._strip = 2; + _object3._frame = 2; + _object3.animate(ANIM_MODE_NONE, NULL); + _object3.setPosition(Common::Point(68, 94)); + _object3.changeZoom(100); + + _object4.postInit(); + _object4.setVisage(21); + _object4._strip = 2; + _object4._frame = 3; + _object4.animate(ANIM_MODE_NONE, NULL); + _object4.setPosition(Common::Point(110, 94)); + _object4.changeZoom(100); + + _object5.postInit(); + _object5.setVisage(21); + _object5._strip = 2; + _object5._frame = 4; + _object5.animate(ANIM_MODE_NONE, NULL); + _object5.setPosition(Common::Point(154, 94)); + _object5.changeZoom(100); + + _object6.postInit(); + _object6.setVisage(21); + _object6._strip = 2; + _object6._frame = 5; + _object6.animate(ANIM_MODE_NONE, NULL); + _object6.setPosition(Common::Point(199, 94)); + _object6.changeZoom(100); + + _object7.postInit(); + _object7.setVisage(21); + _object7._strip = 2; + _object7._frame = 6; + _object7.animate(ANIM_MODE_NONE, NULL); + _object7.setPosition(Common::Point(244, 94)); + _object7.changeZoom(100); + + _object8.postInit(); + _object8.setVisage(21); + _object8._strip = 2; + _object8._frame = 7; + _object8.animate(ANIM_MODE_NONE, NULL); + _object8.setPosition(Common::Point(286, 94)); + _object8.changeZoom(100); + + setAction(&_action1); +} + +/*-------------------------------------------------------------------------- + * Scene 50 - Map Screen + * + *--------------------------------------------------------------------------*/ + +Scene50::Tooltip::Tooltip(): SavedObject() { + _newSceneNumber = _locationId = 0; +} + +void Scene50::Tooltip::synchronize(Serializer &s) { + SavedObject::synchronize(s); + _bounds.synchronize(s); + s.syncString(_msg); +} + +void Scene50::Tooltip2::signal() { + switch (_actionIndex++) { + case 0: + setDelay(60); + break; + case 1: { + Common::Point pt(410, 181); + NpcMover *mover = new NpcMover(); + ((SceneObject *)_owner)->addMover(mover, &pt, this); + break; + } + case 2: + _owner->remove(); + break; + default: + break; + } +} + +void Scene50::Tooltip2::dispatch() { + Action::dispatch(); + SceneObject *owner = (SceneObject *)_owner; + + if ((_actionIndex == 2) && (owner->_percent < 100)) { + owner->changeZoom(owner->_percent + 1); + } +} + +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; + } + + _timer.set(240, this); + _sceneBounds.center(xp, SCREEN_HEIGHT / 2); + loadScene(55); + _sceneMode = 2; + + loadBackground(xp - 160, 0); + tooltip->update(); +} + +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 new file mode 100644 index 0000000000..5c98184ed8 --- /dev/null +++ b/engines/tsage/blue_force/blueforce_scenes0.h @@ -0,0 +1,103 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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. + * + */ + +#ifndef TSAGE_BLUEFORCE_SCENES0_H +#define TSAGE_BLUEFORCE_SCENES0_H + +#include "common/scummsys.h" +#include "tsage/blue_force/blueforce_logic.h" +#include "tsage/converse.h" +#include "tsage/events.h" +#include "tsage/core.h" +#include "tsage/scenes.h" +#include "tsage/globals.h" +#include "tsage/sound.h" + +namespace TsAGE { + +namespace BlueForce { + +using namespace TsAGE; + +class Scene20 : public SceneExt { + /* Actions */ + class Action1 : public Action { + private: + ASoundExt _sound; + public: + virtual void signal(); + }; +public: + Action1 _action1; + ScenePalette _scenePalette; + SceneObject _object1, _object2, _object3, _object4; + SceneObject _object5, _object6, _object7, _object8; + + virtual void postInit(SceneObjectList *OwnerList = NULL); +}; + +class Scene50: public SceneExt { + class Tooltip: public SavedObject { + public: + Rect _bounds; + 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); + }; + class Tooltip2: public Action { + public: + Tooltip2(): Action() {} + + virtual Common::String getClassName() { return "Scene50_Tooltip2"; } + virtual void signal(); + 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 + +} // End of namespace TsAGE + +#endif diff --git a/engines/tsage/blue_force/blueforce_scenes1.cpp b/engines/tsage/blue_force/blueforce_scenes1.cpp new file mode 100644 index 0000000000..650b63c24b --- /dev/null +++ b/engines/tsage/blue_force/blueforce_scenes1.cpp @@ -0,0 +1,432 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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. + * + */ + +#include "common/config-manager.h" +#include "tsage/blue_force/blueforce_scenes1.h" +#include "tsage/scenes.h" +#include "tsage/tsage.h" +#include "tsage/staticres.h" +#include "tsage/globals.h" + +namespace TsAGE { + +namespace BlueForce { + +/*-------------------------------------------------------------------------- + * Scene 100 - Tsunami Title Screen #2 + * + *--------------------------------------------------------------------------*/ + +void Scene100::Text::dispatch() { + SceneText::dispatch(); + + // Keep the second text string below the first one + Scene100 *scene = (Scene100 *)BF_GLOBALS._sceneManager._scene; + Common::Point &pt = scene->_action1._sceneText1._position; + scene->_action1._sceneText2.setPosition(Common::Point(pt.x, + pt.y + scene->_action1._textHeight)); +} + + +void Scene100::Action1::signal() { + static byte black[3] = { 0, 0, 0 }; + + switch (_actionIndex++) { + case 0: + _state = 0; + setDelay(6); + break; + case 1: { + Common::String msg1 = _resourceManager->getMessage(100, _state++); + if (msg1.compareTo("LASTCREDIT")) { + Common::String msg2 = _resourceManager->getMessage(100, _state++); + setTextStrings(msg1, msg2, this); + --_actionIndex; + } else { + setTextStrings(BF_NAME, BF_ALL_RIGHTS_RESERVED, this); + + Common::Point pt(_sceneText1._position.x, 80); + NpcMover *mover = new NpcMover(); + _sceneText1.addMover(mover, &pt, this); + } + break; + } + case 2: + setDelay(600); + break; + case 3: + BF_GLOBALS._sound1.fade(0, 10, 10, 1, this); + GLOBALS._scenePalette.addFader(black, 1, 2, NULL); + break; + case 4: + error("??exit"); + break; + } +} + +void Scene100::Action1::setTextStrings(const Common::String &msg1, const Common::String &msg2, Action *action) { + // Set data for first text control + _sceneText1._fontNumber = 10; + _sceneText1._width = 160; + _sceneText1._textMode = ALIGN_RIGHT; + _sceneText1._color1 = BF_GLOBALS._scenePalette._colors.foreground; + _sceneText1._color2 = BF_GLOBALS._scenePalette._colors.background; + _sceneText1._color3 = BF_GLOBALS._scenePalette._colors.foreground; + _sceneText1.setup(msg1); + _sceneText1.fixPriority(255); + _sceneText1.setPosition(Common::Point( + (SCREEN_WIDTH - _sceneText1.getFrame().getBounds().width()) / 2, 202)); + _sceneText1._moveRate = 30; + _sceneText1._moveDiff.y = 1; + + // Set data for second text control + _sceneText2._fontNumber = 10; + _sceneText2._width = _sceneText1._width; + _sceneText2._textMode = _sceneText1._textMode; + _sceneText2._color1 = _sceneText1._color1; + _sceneText2._color2 = 31; + _sceneText2._color3 = _sceneText1._color3; + _sceneText2.setup(msg2); + _sceneText2.fixPriority(255); + GfxSurface textSurface = _sceneText2.getFrame(); + _sceneText2.setPosition(Common::Point((SCREEN_WIDTH - textSurface.getBounds().width()) / 2, 202)); + _sceneText2._moveRate = 30; + _sceneText2._moveDiff.y = 1; + + _textHeight = textSurface.getBounds().height(); + int yp = -(_textHeight * 2); + + Common::Point pt(_sceneText1._position.x, yp); + NpcMover *mover = new NpcMover(); + _sceneText1.addMover(mover, &pt, action); +} + +void Scene100::Action2::signal() { + Scene100 *scene = (Scene100 *)_globals->_sceneManager._scene; + static byte black[3] = {0, 0, 0}; + + switch (_actionIndex++) { + case 0: + BF_GLOBALS._scenePalette.addFader(black, 1, -2, this); + break; + case 1: + setDelay(180); + break; + case 2: { + const char *SEEN_INTRO = "seen_intro"; + if (!ConfMan.hasKey(SEEN_INTRO) || !ConfMan.getBool(SEEN_INTRO)) { + // First time being played, so will need to show the intro + ConfMan.setBool(SEEN_INTRO, true); + ConfMan.flushToDisk(); + } else { + // Prompt user for whether to start play or watch introduction + _globals->_player.enableControl(); + + if (MessageDialog::show2(WATCH_INTRO_MSG, START_PLAY_BTN_STRING, INTRODUCTION_BTN_STRING) == 0) { + // Signal to start the game + scene->_index = 190; + remove(); + return; + } + } + + // At this point the introduction needs to start + _globals->_scenePalette.addFader(black, 1, 2, this); + break; + } + case 3: + remove(); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +Scene100::Scene100(): SceneExt() { + _index = 0; +} + +void Scene100::postInit(SceneObjectList *OwnerList) { + BF_GLOBALS._scenePalette.loadPalette(2); + BF_GLOBALS._v51C44 = 1; + Scene::postInit(); + BF_GLOBALS._interfaceY = SCREEN_HEIGHT; + + _globals->_player.enableControl(); + _globals->_player.hide(); + _globals->_player.disableControl(); + _index = 109; + + if (BF_GLOBALS._v4CEA2 < 6) { + // Title + loadScene(100); + BF_GLOBALS._sound1.play(2); + setAction(&_action2, this); + } else { + // Credits + loadScene(101); + BF_GLOBALS._sound1.play(118); + setAction(&_action1, this); + } +} + +void Scene100::signal() { + ++_sceneMode; + if (BF_GLOBALS._v4CEA2 < 6) { + BF_GLOBALS._scenePalette.clearListeners(); + BF_GLOBALS._scenePalette.loadPalette(100); + BF_GLOBALS._sceneManager.changeScene(_index); + } else { + if (_sceneMode > 1) + BF_GLOBALS._events.setCursor(CURSOR_ARROW); + + setAction(this, &_action1, this); + } +} + +/*-------------------------------------------------------------------------- + * Scene 109 - Introduction Bar Room + * + *--------------------------------------------------------------------------*/ + +void Scene109::Action1::signal() { + Scene109 *scene = (Scene109 *)BF_GLOBALS._sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(30); + break; + case 1: + BF_GLOBALS._sound1.play(12); + BF_GLOBALS._sceneObjects->draw(); + BF_GLOBALS._scenePalette.loadPalette(2); + BF_GLOBALS._scenePalette.refresh(); + setDelay(10); + break; + case 2: + scene->_text.setup(BF_19840515, this); + break; + case 3: + BF_GLOBALS._v51C44 = 1; + scene->loadScene(115); + + scene->_protaginist2.show(); + scene->_protaginist2.setPriority(133); + scene->_protaginist1.show(); + scene->_bartender.show(); + scene->_object1.show(); + scene->_drunk.show(); + scene->_drunk.setAction(&scene->_action3); + scene->_object2.show(); + scene->_object9.show(); + scene->_object9.setAction(&scene->_action2); + + BF_GLOBALS._v501FC = 170; + setDelay(60); + break; + case 4: + // Start drinking + scene->_bartender.setAction(&scene->_sequenceManager4, NULL, 109, &scene->_bartender, &scene->_object2, NULL); + scene->_protaginist1.setAction(&scene->_sequenceManager5, NULL, 107, &scene->_protaginist1, NULL); + scene->_protaginist2.setAction(&scene->_sequenceManager6, this, 106, &scene->_protaginist2, NULL); + break; + case 5: + // Open briefcase and pass over disk + setAction(&scene->_sequenceManager6, this, 105, &scene->_object10, NULL); + break; + case 6: + // Protaginist 2 walk to the bar + scene->_object10.remove(); + setAction(&scene->_sequenceManager6, this, 100, &scene->_protaginist2, NULL); + break; + case 7: + // Two thugs enter and walk to table + scene->_object7.setAction(&scene->_sequenceManager7, NULL, 103, &scene->_object7, NULL); + scene->_object5.setAction(&scene->_sequenceManager8, this, 102, &scene->_object5, NULL); + scene->_protaginist2.setAction(&scene->_sequenceManager6, NULL, 104, &scene->_protaginist2, &scene->_bartender, NULL); + break; + case 8: + // Protaginist 1 leaves, protaginist 2 stands up + setAction(&scene->_sequenceManager8, this, 101, &scene->_object5, &scene->_protaginist1, NULL); + break; + case 9: + // Shots fired! + scene->_protaginist1.setAction(&scene->_sequenceManager5, this, 98, &scene->_protaginist1, NULL); + scene->_object7.setAction(&scene->_sequenceManager7, NULL, 99, &scene->_object7, NULL); + break; + case 10: + // End scene + scene->_sceneMode = 1; + remove(); + break; + } +} + +void Scene109::Action2::signal() { + Scene109 *scene = (Scene109 *)BF_GLOBALS._sceneManager._scene; + scene->setAction(&scene->_sequenceManager2, this, 3117, &scene->_object9, NULL); +} + +void Scene109::Action3::signal() { + Scene109 *scene = (Scene109 *)BF_GLOBALS._sceneManager._scene; + scene->setAction(&scene->_sequenceManager3, this, 108, &scene->_drunk, NULL); +} + +/*--------------------------------------------------------------------------*/ + +Scene109::Text::Text(): SceneText() { + _action = NULL; + _frameNumber = 0; + _diff = 0; +} + +void Scene109::Text::setup(const Common::String &msg, Action *action) { + _frameNumber = BF_GLOBALS._events.getFrameNumber(); + _diff = 180; + _action = action; + _fontNumber = 4; + _width = 300; + _textMode = ALIGN_CENTER; + _color1 = BF_GLOBALS._scenePalette._colors.background; + _color2 = _color3 = 0; + + SceneText::setup(msg); + + // Center the text on-screen + reposition(); + _bounds.center(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2); + + // Set the new position + _position.x = _bounds.left; + _position.y = _bounds.top; +} + +void Scene109::Text::synchronize(Serializer &s) { + SceneText::synchronize(s); + SYNC_POINTER(_action); + s.syncAsUint32LE(_frameNumber); + s.syncAsSint16LE(_diff); +} + +void Scene109::Text::dispatch() { + if (_diff) { + uint32 frameNumber = BF_GLOBALS._events.getFrameNumber(); + if (_frameNumber < frameNumber) { + _diff -= frameNumber - _frameNumber; + _frameNumber = frameNumber; + + if (_diff <= 0) { + // Time has expired, so remove the text and signal the designated action + remove(); + if (_action) + _action->signal(); + } + } + } +} + +/*--------------------------------------------------------------------------*/ + +Scene109::Scene109(): GameScene() { +} + +void Scene109::postInit(SceneObjectList *OwnerList) { + GameScene::postInit(OwnerList); + loadScene(999); + + _protaginist2.postInit(); + _protaginist2.setVisage(119); + _protaginist2.setFrame(11); + _protaginist2.fixPriority(133); + _protaginist2.setPosition(Common::Point(165, 124)); + _protaginist2.hide(); + + _protaginist1.postInit(); + _protaginist1.setVisage(118); + _protaginist1.setStrip(1); + _protaginist1.setFrame(8); + _protaginist1.fixPriority(132); + _protaginist1.setPosition(Common::Point(143, 125)); + _protaginist1.hide(); + + _bartender.postInit(); + _bartender.setVisage(121); + _bartender.setStrip(2); + _bartender.setFrame(1); + _bartender.setPriority(-1); + _bartender.setPosition(Common::Point(92, 64)); + _bartender.hide(); + + _object1.postInit(); + _object1.setVisage(121); + _object1.setStrip(6); + _object1.setFrame(1); + _object1.setPriority(-1); + _object1.setPosition(Common::Point(110, 64)); + _object1.hide(); + + _drunk.postInit(); + _drunk.setVisage(120); + _drunk.setStrip(2); + _drunk.setFrame(5); + _drunk.setPriority(-1); + _drunk.setPosition(Common::Point(127, 97)); + _drunk.hide(); + + _object2.postInit(); + _object2.setVisage(121); + _object2.setStrip(5); + _object2.setFrame(1); + _object2.setPriority(-1); + _object2.setPosition(Common::Point(104, 64)); + _object2.hide(); + + _object9.postInit(); + _object9.setVisage(115); + _object9.setStrip(4); + _object9.setFrame(1); + _object9.setPosition(Common::Point(262, 29)); + _object9.hide(); + + _object5.postInit(); + _object5.hide(); + + _object7.postInit(); + _object7.hide(); + + _object10.postInit(); + _object10.hide(); + + BF_GLOBALS._player.disableControl(); + setAction(&_action1, this); +} + +void Scene109::signal() { + if (_sceneMode == 1) { + BF_GLOBALS._scenePalette.clearListeners(); + BF_GLOBALS._sceneManager.changeScene(110); + } +} + +} // End of namespace BlueForce + +} // End of namespace TsAGE diff --git a/engines/tsage/blue_force/blueforce_scenes1.h b/engines/tsage/blue_force/blueforce_scenes1.h new file mode 100644 index 0000000000..0769c6e3c6 --- /dev/null +++ b/engines/tsage/blue_force/blueforce_scenes1.h @@ -0,0 +1,132 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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. + * + */ + +#ifndef TSAGE_BLUEFORCE_SCENES1_H +#define TSAGE_BLUEFORCE_SCENES1_H + +#include "common/scummsys.h" +#include "tsage/blue_force/blueforce_logic.h" +#include "tsage/converse.h" +#include "tsage/events.h" +#include "tsage/core.h" +#include "tsage/scenes.h" +#include "tsage/globals.h" +#include "tsage/sound.h" + +namespace TsAGE { + +namespace BlueForce { + +using namespace TsAGE; + +class Scene100: public SceneExt { + /* Support classes */ + class Text: public SceneText { + public: + virtual Common::String getClassName() { return "BF100Text"; } + virtual void dispatch(); + }; + + /* Actions */ + class Action1: public ActionExt { + private: + void setTextStrings(const Common::String &msg1, const Common::String &msg2, Action *action); + public: + Text _sceneText1; + SceneText _sceneText2; + int _textHeight; + + virtual Common::String getClassName() { return "BF100Action1"; } + virtual void synchronize(Serializer &s) { + ActionExt::synchronize(s); + s.syncAsSint16LE(_textHeight); + } + virtual void signal(); + }; + class Action2: public ActionExt { + public: + virtual void signal(); + }; +public: + SequenceManager _sequenceManager; + Action1 _action1; + Action2 _action2; + ScenePalette _scenePalette; + SceneObjectExt2 _object1, _object2, _object3, _object4, _object5; + int _index; + + Scene100(); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); +}; + +class Scene109: public GameScene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + class Action3: public Action { + public: + virtual void signal(); + }; + + /* Texts */ + class Text: public SceneText { + public: + Action *_action; + uint32 _frameNumber; + int _diff; + public: + Text(); + void setup(const Common::String &msg, Action *action); + + virtual Common::String getClassName() { return "BF109Text"; } + virtual void synchronize(Serializer &s); + virtual void dispatch(); + }; +public: + SequenceManager _sequenceManager1, _sequenceManager2, _sequenceManager3; + SequenceManager _sequenceManager4, _sequenceManager5, _sequenceManager6; + SequenceManager _sequenceManager7, _sequenceManager8; + SceneObject _object1, _object2, _protaginist2, _protaginist1, _object5; + SceneObject _drunk, _object7, _bartender, _object9, _object10; + Text _text; + BlueAnimatedSpeaker _speaker; + Action1 _action1; + Action _action2, _action3; +public: + Scene109(); + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); +}; + +} // End of namespace BlueForce + +} // End of namespace TsAGE + +#endif diff --git a/engines/tsage/blueforce_logic.cpp b/engines/tsage/blueforce_logic.cpp deleted file mode 100644 index d266d5e1d9..0000000000 --- a/engines/tsage/blueforce_logic.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * 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. - * - */ - -#include "tsage/blueforce_logic.h" -#include "tsage/scenes.h" -#include "tsage/tsage.h" -#include "tsage/staticres.h" - -namespace tSage { - -void BlueForceGame::start() { - // Start the game - _globals->_sceneManager.changeScene(20); - - _globals->_events.setCursor(CURSOR_WALK); -} - -Scene *BlueForceGame::createScene(int sceneNumber) { - switch (sceneNumber) { - case 20: - case 50: - case 60: - error("Scene group 0 not implemented"); - case 100: - case 109: - case 110: - case 114: - case 115: - case 125: - case 140: - case 150: - case 160: - case 180: - case 190: - error("Scene group 1 not implemented"); - case 200: - case 210: - case 220: - case 225: - case 265: - case 270: - case 271: - case 280: - error("Scene group 2 not implemented"); - case 300: - case 315: - case 325: - case 330: - case 340: - case 342: - case 350: - case 355: - case 360: - case 370: - case 380: - case 385: - case 390: - error("Scene group 3 not implemented"); - case 410: - case 415: - case 440: - case 450: - error("Scene group 4 not implemented"); - case 550: - case 551: - case 560: - case 570: - case 580: - case 590: - error("Scene group 5 not implemented"); - case 600: - case 620: - case 666: - case 690: - error("Scene group 6 not implemented"); - case 710: - error("Scene group 7 not implemented"); - case 800: - case 810: - case 820: - case 830: - case 840: - case 850: - case 860: - case 870: - case 880: - error("Scene group 8 not implemented"); - case 900: - case 910: - case 920: - case 930: - case 935: - case 940: - error("Scene group 9 not implemented"); - default: - error("Unknown scene number - %d", sceneNumber); - break; - } -} - -} // End of namespace tSage diff --git a/engines/tsage/blueforce_logic.h b/engines/tsage/blueforce_logic.h deleted file mode 100644 index 9237e50a13..0000000000 --- a/engines/tsage/blueforce_logic.h +++ /dev/null @@ -1,42 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * 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. - * - */ - -#ifndef TSAGE_BLUEFORCE_LOGIC_H -#define TSAGE_BLUEFORCE_LOGIC_H - -#include "common/scummsys.h" -#include "tsage/events.h" -#include "tsage/core.h" -#include "tsage/scenes.h" -#include "tsage/globals.h" - -namespace tSage { - -class BlueForceGame: public Game { -public: - virtual void start(); - virtual Scene *createScene(int sceneNumber); -}; - -} // End of namespace tSage - -#endif diff --git a/engines/tsage/converse.cpp b/engines/tsage/converse.cpp index b475310533..615b1c36fd 100644 --- a/engines/tsage/converse.cpp +++ b/engines/tsage/converse.cpp @@ -26,7 +26,7 @@ #include "tsage/globals.h" #include "tsage/staticres.h" -namespace tSage { +namespace TsAGE { #define STRIP_WORD_DELAY 30 @@ -34,7 +34,7 @@ namespace tSage { SequenceManager::SequenceManager() : Action() { Common::set_to(&_objectList[0], &_objectList[6], (SceneObject *)NULL); _sequenceData.clear(); - _field24 = 0; + _fontNum = 0; _sequenceOffset = 0; _resNum = 0; _field26 = 0; @@ -56,7 +56,7 @@ void SequenceManager::synchronize(Serializer &s) { s.syncAsSint32LE(_resNum); s.syncAsSint32LE(_sequenceOffset); s.syncAsByte(_keepActive); - s.syncAsSint32LE(_field24); + s.syncAsSint32LE(_fontNum); s.syncAsSint32LE(_field26); s.syncAsSint32LE(_objectIndex); @@ -284,6 +284,32 @@ void SequenceManager::signal() { _objectList[objIndex3], _objectList[objIndex4], _objectList[objIndex5], _objectList[objIndex6], NULL); break; } + /* Following indexes were introduced for Blue Force */ + case 35: + v1 = getNextValue(); + _sceneObject->updateAngle(_objectList[v1]); + break; + case 36: + _sceneObject->animate(ANIM_MODE_9, NULL); + break; + case 37: + v1 = getNextValue(); + v2 = getNextValue(); + warning("TODO: dword_53030(%d,%d)", v1, v2); + break; + case 38: { + int resNum = getNextValue(); + int lineNum = getNextValue(); + int fontNum = getNextValue(); + int color1 = getNextValue(); + int color2 = getNextValue(); + int color3 = getNextValue(); + int xp = getNextValue(); + int yp = getNextValue(); + int width = getNextValue(); + setMessage(resNum, lineNum, fontNum, color1, color2, color3, Common::Point(xp, yp), width); + break; + } default: error("SequenceManager::signal - Unknown action %d at offset %xh", idx, _sequenceOffset - 2); break; @@ -337,10 +363,15 @@ uint16 SequenceManager::getNextValue() { } void SequenceManager::setMessage(int resNum, int lineNum, int color, const Common::Point &pt, int width) { - _sceneText._color1 = color; - _sceneText._color2 = 0; - _sceneText._color3 = 0; - _sceneText._fontNumber = 2; + setMessage(resNum, lineNum, 2, color, 0, 0, pt, width); +} + +void SequenceManager::setMessage(int resNum, int lineNum, int fontNum, int color1, int color2, int color3, + const Common::Point &pt, int width) { + _sceneText._color1 = color1; + _sceneText._color2 = color2; + _sceneText._color3 = color3; + _sceneText._fontNumber = fontNum; _sceneText._width = width; // Get the display message @@ -416,13 +447,13 @@ int ConversationChoiceDialog::execute(const Common::StringArray &choiceList) { // Event handling loop Event event; - while (!_vm->getEventManager()->shouldQuit()) { + while (!_vm->shouldQuit()) { while (!_globals->_events.getEvent(event, EVENT_KEYPRESS | EVENT_BUTTON_DOWN | EVENT_MOUSE_MOVE) && - !_vm->getEventManager()->shouldQuit()) { + !_vm->shouldQuit()) { g_system->delayMillis(10); g_system->updateScreen(); } - if (_vm->getEventManager()->shouldQuit()) + if (_vm->shouldQuit()) break; if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode >= Common::KEYCODE_1) && @@ -954,4 +985,4 @@ void AnimatedSpeaker::removeText() { _objectList.draw(); } -} // end of namespace tSage +} // end of namespace TsAGE diff --git a/engines/tsage/converse.h b/engines/tsage/converse.h index 13c490e995..e263a12d12 100644 --- a/engines/tsage/converse.h +++ b/engines/tsage/converse.h @@ -27,7 +27,7 @@ #include "tsage/dialogs.h" #include "tsage/sound.h" -namespace tSage { +namespace TsAGE { class StripCallback : public Action { public: @@ -39,13 +39,15 @@ private: void setup(); uint16 getNextValue(); void setMessage(int resNum, int lineNum, int color, const Common::Point &pt, int width); + void setMessage(int resNum, int lineNum, int fontNum, int color1, int color2, int color3, + const Common::Point &pt, int width); SequenceManager *globalManager(); public: SceneText _sceneText; int _resNum; uint _sequenceOffset; bool _keepActive; - int _field24; + int _fontNum; int _field26; Common::Array<byte> _sequenceData; int _objectIndex; @@ -222,6 +224,6 @@ public: void addSpeaker(Speaker *speaker); }; -} // End of namespace tSage +} // End of namespace TsAGE #endif diff --git a/engines/tsage/core.cpp b/engines/tsage/core.cpp index 76714a6f10..42cb1d039f 100644 --- a/engines/tsage/core.cpp +++ b/engines/tsage/core.cpp @@ -33,7 +33,7 @@ #include "tsage/globals.h" #include "tsage/sound.h" -namespace tSage { +namespace TsAGE { // The engine uses ScumMVM screen buffering, so all logic is hardcoded to use pane buffer 0 #define CURRENT_PANENUM 0 @@ -1161,6 +1161,20 @@ void PaletteFader::remove() { action->signal(); } +void PaletteFader::setPalette(ScenePalette *palette, int step) { + if (step < 0) { + // Reverse step means moving from dest palette to source, so swap the two palettes + byte tempPal[256 * 3]; + Common::copy(&palette->_palette[0], &palette->_palette[256 * 3], &tempPal[0]); + Common::copy(&this->_palette[0], &this->_palette[256 * 3], &palette->_palette[0]); + Common::copy(&tempPal[0], &tempPal[256 * 3], &this->_palette[0]); + + step = -step; + } + + PaletteModifierCached::setPalette(palette, step); +} + /*--------------------------------------------------------------------------*/ ScenePalette::ScenePalette() { @@ -1314,7 +1328,7 @@ PaletteRotation *ScenePalette::addRotation(int start, int end, int rotationMode, return obj; } -PaletteFader *ScenePalette::addFader(const byte *arrBufferRGB, int palSize, int percent, Action *action) { +PaletteFader *ScenePalette::addFader(const byte *arrBufferRGB, int palSize, int step, Action *action) { PaletteFader *fader = new PaletteFader(); fader->_action = action; for (int i = 0; i < 256 * 3; i += 3) { @@ -1326,7 +1340,7 @@ PaletteFader *ScenePalette::addFader(const byte *arrBufferRGB, int palSize, int arrBufferRGB += 3; } - fader->setPalette(this, percent); + fader->setPalette(this, step); _globals->_scenePalette._listeners.push_back(fader); return fader; } @@ -1552,7 +1566,7 @@ void SceneItem::display(int resNum, int lineNum, ...) { Event event; // Keep event on-screen until a mouse or keypress - while (!_vm->getEventManager()->shouldQuit() && !_globals->_events.getEvent(event, + while (!_vm->shouldQuit() && !_globals->_events.getEvent(event, EVENT_BUTTON_DOWN | EVENT_KEYPRESS)) { g_system->updateScreen(); g_system->delayMillis(10); @@ -1641,6 +1655,11 @@ void SceneObjectWrapper::remove() { } void SceneObjectWrapper::dispatch() { + if (_vm->getGameID() == GType_Ringworld) + check(); +} + +void SceneObjectWrapper::check() { _visageImages.setVisage(_sceneObject->_visage); int frameCount = _visageImages.getFrameCount(); int angle = _sceneObject->_angle; @@ -1699,6 +1718,7 @@ SceneObject::SceneObject() : SceneHotspot() { _sceneRegionId = 0; _percent = 100; _flags |= OBJFLAG_PANES; + _priority = 0; _frameChange = 0; _visage = 0; @@ -2263,6 +2283,18 @@ void SceneObject::updateScreen() { } } +void SceneObject::updateAngle(SceneObject *sceneObj) { + checkAngle(sceneObj); + if (_objectWrapper) + _objectWrapper->check(); +} + +void SceneObject::changeAngle(int angle) { + _angle = angle; + if (_objectWrapper) + _objectWrapper->check(); +} + void SceneObject::setup(int visage, int stripFrameNum, int frameNum, int posX, int posY, int priority) { postInit(); setVisage(visage); @@ -2274,6 +2306,22 @@ void SceneObject::setup(int visage, int stripFrameNum, int frameNum, int posX, i /*--------------------------------------------------------------------------*/ +void SceneObjectExt2::postInit(SceneObjectList *OwnerList) { + _v8A = -1; + _v8C = -1; + _v8E = -1; + SceneObject::postInit(); +} + +void SceneObjectExt2::synchronize(Serializer &s) { + SceneObject::synchronize(s); + s.syncAsSint16LE(_v8A); + s.syncAsSint16LE(_v8C); + s.syncAsSint16LE(_v8E); +} + +/*--------------------------------------------------------------------------*/ + void SceneObjectList::draw() { Common::Array<SceneObject *> objList; int paneNum = 0; @@ -3426,6 +3474,7 @@ void GameHandler::synchronize(Serializer &s) { SceneHandler::SceneHandler() { _saveGameSlot = -1; _loadGameSlot = -1; + _prevFrameNumber = 0; } void SceneHandler::registerHandler() { @@ -3433,6 +3482,10 @@ void SceneHandler::registerHandler() { _globals->_game->addHandler(this); } +uint32 SceneHandler::getFrameDifference() { + return GLOBALS._events.getFrameNumber() - _prevFrameNumber; +} + void SceneHandler::postInit(SceneObjectList *OwnerList) { _delayTicks = 2; @@ -3547,10 +3600,19 @@ void SceneHandler::dispatch() { // Not actually used //_eventListeners.forEach(SceneHandler::handleListener); - // Handle pending eents + // Handle pending events Event event; - while (_globals->_events.getEvent(event)) + if (_globals->_events.getEvent(event)) { + // Process pending events + do { + process(event); + } while (_globals->_events.getEvent(event)); + } else if (_vm->getGameID() == GType_BlueForce) { + // For Blue Force, 'none' events need to be generated in the absence of any + event.eventType = EVENT_NONE; + event.mousePos = _globals->_events._mousePos; process(event); + } // Handle drawing the contents of the scene if (_globals->_sceneManager._scene) @@ -3573,4 +3635,4 @@ void SceneHandler::dispatchObject(EventHandler *obj) { void SceneHandler::saveListener(Serializer &ser) { } -} // End of namespace tSage +} // End of namespace TsAGE diff --git a/engines/tsage/core.h b/engines/tsage/core.h index b86e2f63fe..19987ed399 100644 --- a/engines/tsage/core.h +++ b/engines/tsage/core.h @@ -34,7 +34,7 @@ #include "tsage/resources.h" #include "tsage/saveload.h" -namespace tSage { +namespace TsAGE { #define MAX_FLAGS 256 @@ -287,7 +287,7 @@ public: PaletteModifierCached(); - void setPalette(ScenePalette *palette, int step); + virtual void setPalette(ScenePalette *palette, int step); virtual Common::String getClassName() { return "PaletteModifierCached"; } virtual void synchronize(Serializer &s); }; @@ -323,6 +323,7 @@ public: virtual void synchronize(Serializer &s); virtual void signal(); virtual void remove(); + virtual void setPalette(ScenePalette *palette, int step); }; /*--------------------------------------------------------------------------*/ @@ -356,7 +357,7 @@ public: void clearListeners(); void fade(const byte *adjustData, bool fullAdjust, int percent); PaletteRotation *addRotation(int start, int end, int rotationMode, int duration = 0, Action *action = NULL); - PaletteFader *addFader(const byte *arrBufferRGB, int palSize, int percent, Action *action); + PaletteFader *addFader(const byte *arrBufferRGB, int palSize, int step, Action *action); static void changeBackground(const Rect &bounds, FadeMode fadeMode); @@ -436,7 +437,10 @@ public: }; enum AnimateMode {ANIM_MODE_NONE = 0, ANIM_MODE_1 = 1, ANIM_MODE_2 = 2, ANIM_MODE_3 = 3, - ANIM_MODE_4 = 4, ANIM_MODE_5 = 5, ANIM_MODE_6 = 6, ANIM_MODE_7 = 7, ANIM_MODE_8 = 8}; + ANIM_MODE_4 = 4, ANIM_MODE_5 = 5, ANIM_MODE_6 = 6, ANIM_MODE_7 = 7, ANIM_MODE_8 = 8, + // Introduced in Blue Force + ANIM_MODE_9 = 9 +}; class SceneObject; @@ -467,6 +471,7 @@ public: virtual ~SceneObjectWrapper() {} void setSceneObject(SceneObject *so); + void check(); virtual void synchronize(Serializer &s); virtual Common::String getClassName() { return "SceneObjectWrapper"; } @@ -555,6 +560,10 @@ public: virtual void draw(); virtual void proc19() {} virtual void updateScreen(); + // New methods introduced by Blue FOrce + virtual void updateAngle(SceneObject *sceneObj); + virtual void changeAngle(int angle); + void setup(int visage, int stripFrameNum, int frameNum, int posX, int posY, int priority); }; @@ -569,6 +578,16 @@ public: virtual Common::String getClassName() { return "SceneObjectExt"; } }; +class SceneObjectExt2: public SceneObject { +public: + int _v88, _v8A, _v8C, _v8E; + + virtual Common::String getClassName() { return "BF100Object"; } + virtual void synchronize(Serializer &s); + virtual void postInit(SceneObjectList *OwnerList = NULL); +}; + + class SceneText : public SceneObject { public: int _fontNumber; @@ -695,7 +714,7 @@ public: SynchronizedList<SceneObject *>::iterator begin() { return _objList.begin(); } SynchronizedList<SceneObject *>::iterator end() { return _objList.end(); } int size() const { return _objList.size(); } - bool contains(SceneObject *sceneObj) { return tSage::contains(_objList, sceneObj); } + bool contains(SceneObject *sceneObj) { return TsAGE::contains(_objList, sceneObj); } void push_back(SceneObject *sceneObj) { _objList.push_back(sceneObj); } void push_front(SceneObject *sceneObj) { _objList.push_front(sceneObj); } void remove(SceneObject *sceneObj) { @@ -827,9 +846,11 @@ public: int _loadGameSlot; int _delayTicks; Common::String _saveName; + uint32 _prevFrameNumber; public: SceneHandler(); void registerHandler(); + uint32 getFrameDifference(); virtual Common::String getClassName() { return "SceneHandler"; } virtual void postInit(SceneObjectList *OwnerList = NULL); @@ -840,6 +861,6 @@ public: static void saveListener(Serializer &ser); }; -} // End of namespace tSage +} // End of namespace TsAGE #endif diff --git a/engines/tsage/debugger.cpp b/engines/tsage/debugger.cpp index 9277fd429a..e3c4569dd2 100644 --- a/engines/tsage/debugger.cpp +++ b/engines/tsage/debugger.cpp @@ -23,9 +23,9 @@ #include "tsage/debugger.h" #include "tsage/globals.h" #include "tsage/graphics.h" -#include "tsage/ringworld_logic.h" +#include "tsage/ringworld/ringworld_logic.h" -namespace tSage { +namespace TsAGE { Debugger::Debugger() : GUI::Debugger() { DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit)); @@ -38,6 +38,7 @@ Debugger::Debugger() : GUI::Debugger() { DCmd_Register("listobjects", WRAP_METHOD(Debugger, Cmd_ListObjects)); DCmd_Register("moveobject", WRAP_METHOD(Debugger, Cmd_MoveObject)); DCmd_Register("hotspots", WRAP_METHOD(Debugger, Cmd_Hotspots)); + DCmd_Register("sound", WRAP_METHOD(Debugger, Cmd_Sound)); } static int strToInt(const char *s) { @@ -434,5 +435,18 @@ bool Debugger::Cmd_Hotspots(int argc, const char **argv) { return false; } +/** + * Play the specified sound + */ +bool Debugger::Cmd_Sound(int argc, const char **argv) { + if (argc != 2) { + DebugPrintf("Usage: %s <sound number>\n", argv[0]); + return true; + } + + int soundNum = strToInt(argv[1]); + _globals->_soundHandler.play(soundNum); + return false; +} -} // End of namespace tSage +} // End of namespace TsAGE diff --git a/engines/tsage/debugger.h b/engines/tsage/debugger.h index 3c14cd7bed..8bc1b06336 100644 --- a/engines/tsage/debugger.h +++ b/engines/tsage/debugger.h @@ -26,7 +26,7 @@ #include "common/scummsys.h" #include "gui/debugger.h" -namespace tSage { +namespace TsAGE { class Debugger : public GUI::Debugger { public: @@ -42,10 +42,10 @@ protected: bool Cmd_ClearFlag(int argc, const char **argv); bool Cmd_ListObjects(int argc, const char **argv); bool Cmd_MoveObject(int argc, const char **argv); - bool Cmd_Hotspots(int argc, const char **argv); + bool Cmd_Sound(int argc, const char **argv); }; -} // End of namespace tSage +} // End of namespace TsAGE #endif diff --git a/engines/tsage/detection.cpp b/engines/tsage/detection.cpp index aaa9030a04..f12efc02e8 100644 --- a/engines/tsage/detection.cpp +++ b/engines/tsage/detection.cpp @@ -30,7 +30,7 @@ #include "tsage/tsage.h" -namespace tSage { +namespace TsAGE { struct tSageGameDescription { ADGameDescription desc; @@ -55,11 +55,11 @@ Common::String TSageEngine::getPrimaryFilename() const { return Common::String(_gameDescription->desc.filesDescriptions[0].fileName); } -} // End of namespace tSage +} // End of namespace TsAGE static const PlainGameDescriptor tSageGameTitles[] = { { "tsage", "Unknown Tsunami TSAGE-based Game" }, - { "ring", "Ringworld: Revenge of the Patriarch" }, + { "ringworld", "Ringworld: Revenge of the Patriarch" }, { "blueforce", "Blue Force" }, { 0, 0 } }; @@ -72,7 +72,7 @@ enum { class TSageMetaEngine : public AdvancedMetaEngine { public: - TSageMetaEngine() : AdvancedMetaEngine(tSage::gameDescriptions, sizeof(tSage::tSageGameDescription), tSageGameTitles) { + TSageMetaEngine() : AdvancedMetaEngine(TsAGE::gameDescriptions, sizeof(TsAGE::tSageGameDescription), tSageGameTitles) { _md5Bytes = 5000; _singleid = "tsage"; _guioptions = Common::GUIO_NOSPEECH; @@ -103,7 +103,7 @@ public: virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const { if (desc) { - *engine = new tSage::TSageEngine(syst, (const tSage::tSageGameDescription *)desc); + *engine = new TsAGE::TSageEngine(syst, (const TsAGE::tSageGameDescription *)desc); } return desc != 0; } @@ -118,7 +118,7 @@ public: Common::StringArray filenames = g_system->getSavefileManager()->listSavefiles(pattern); sort(filenames.begin(), filenames.end()); - tSage::tSageSavegameHeader header; + TsAGE::tSageSavegameHeader header; SaveStateList saveList; for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) { @@ -129,7 +129,7 @@ public: Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file); if (in) { - if (tSage::Saver::readSavegameHeader(in, header)) { + if (TsAGE::Saver::readSavegameHeader(in, header)) { saveList.push_back(SaveStateDescriptor(slot, header.saveName)); delete header.thumbnail; } @@ -156,8 +156,8 @@ public: generateGameStateFileName(target, slot)); assert(f); - tSage::tSageSavegameHeader header; - tSage::Saver::readSavegameHeader(f, header); + TsAGE::tSageSavegameHeader header; + TsAGE::Saver::readSavegameHeader(f, header); delete f; // Create the return descriptor diff --git a/engines/tsage/detection_tables.h b/engines/tsage/detection_tables.h index 8b80edf89d..4b69549673 100644 --- a/engines/tsage/detection_tables.h +++ b/engines/tsage/detection_tables.h @@ -20,19 +20,33 @@ * */ -namespace tSage { +namespace TsAGE { static const tSageGameDescription gameDescriptions[] = { - // Ringworld CD and First Wave versions + // Ringworld English CD and First Wave versions { { - "ring", + "ringworld", "CD", AD_ENTRY1s("ring.rlb", "466f0e6492d9d0f34d35c5cd088de90f", 37847618), Common::EN_ANY, Common::kPlatformPC, - ADGF_UNSTABLE, + ADGF_TESTING | ADGF_CD, + Common::GUIO_NOSPEECH | Common::GUIO_NOSFX + }, + GType_Ringworld, + GF_CD | GF_ALT_REGIONS + }, + // Ringworld Spanish CD + { + { + "ringworld", + "CD", + AD_ENTRY1s("ring.rlb", "cb8bba91b30cd172712371d7123bd763", 7427980), + Common::ES_ESP, + Common::kPlatformPC, + ADGF_TESTING | ADGF_CD, Common::GUIO_NOSPEECH | Common::GUIO_NOSFX }, GType_Ringworld, @@ -41,12 +55,12 @@ static const tSageGameDescription gameDescriptions[] = { // Ringworld English Floppy version { { - "ring", + "ringworld", "Floppy", AD_ENTRY1s("ring.rlb", "7b7f0c5b37b58fa5ec06ebb2ca0d0d9d", 8438770), Common::EN_ANY, Common::kPlatformPC, - ADGF_UNSTABLE, + ADGF_TESTING, Common::GUIO_NOSPEECH | Common::GUIO_NOSFX }, GType_Ringworld, @@ -55,7 +69,7 @@ static const tSageGameDescription gameDescriptions[] = { // Ringworld English Floppy Demo #1 version { { - "ring", + "ringworld", "Floppy Demo", AD_ENTRY1s("tsage.rlb", "3b3604a97c06c91f3735d3e9d341f63f", 833453), Common::EN_ANY, @@ -70,7 +84,7 @@ static const tSageGameDescription gameDescriptions[] = { // Ringworld English Floppy Demo #2 version { { - "ring", + "ringworld", "Floppy Demo", AD_ENTRY1s("demoring.rlb", "64050e1806203b15bb03876140eb4f56", 832206), Common::EN_ANY, @@ -106,11 +120,11 @@ static const tSageGameDescription gameDescriptions[] = { AD_ENTRY1s("blue.rlb", "17eabb456cb1546c66baf1aff387ba6a", 10032614), Common::EN_ANY, Common::kPlatformPC, - ADGF_NO_FLAGS, + ADGF_UNSTABLE, Common::GUIO_NOSPEECH | Common::GUIO_NOSFX }, GType_BlueForce, - GF_FLOPPY + GF_FLOPPY | GF_ALT_REGIONS }, // Blue Force CD and First Wave use the same files { @@ -120,13 +134,13 @@ static const tSageGameDescription gameDescriptions[] = { AD_ENTRY1s("blue.rlb", "99983f48cb218f1f3760cf2f9a7ef11d", 63863322), Common::EN_ANY, Common::kPlatformPC, - ADGF_NO_FLAGS, + ADGF_CD | ADGF_UNSTABLE, Common::GUIO_NOSPEECH | Common::GUIO_NOSFX }, GType_BlueForce, - GF_CD + GF_CD | GF_ALT_REGIONS }, { AD_TABLE_END_MARKER, 0, 0 } }; -} // End of namespace tSage +} // End of namespace TsAGE diff --git a/engines/tsage/dialogs.cpp b/engines/tsage/dialogs.cpp index 86fbbc8e43..ae385b8c15 100644 --- a/engines/tsage/dialogs.cpp +++ b/engines/tsage/dialogs.cpp @@ -30,9 +30,9 @@ #include "tsage/dialogs.h" #include "tsage/staticres.h" #include "tsage/globals.h" -#include "tsage/ringworld_logic.h" +#include "tsage/ringworld/ringworld_logic.h" -namespace tSage { +namespace TsAGE { /*--------------------------------------------------------------------------*/ @@ -243,7 +243,7 @@ void RightClickDialog::execute() { // Dialog event handler loop _gfxManager.activate(); - while (!_vm->getEventManager()->shouldQuit() && (_selectedAction == -1)) { + while (!_vm->shouldQuit() && (_selectedAction == -1)) { Event evt; while (_globals->_events.getEvent(evt, EVENT_MOUSE_MOVE | EVENT_BUTTON_DOWN)) { evt.mousePos.x -= _bounds.left; @@ -465,14 +465,14 @@ void InventoryDialog::execute() { bool lookFlag = false; _gfxManager.activate(); - while (!_vm->getEventManager()->shouldQuit()) { + while (!_vm->shouldQuit()) { // Get events Event event; - while (!_globals->_events.getEvent(event) && !_vm->getEventManager()->shouldQuit()) { + while (!_globals->_events.getEvent(event) && !_vm->shouldQuit()) { g_system->delayMillis(10); g_system->updateScreen(); } - if (_vm->getEventManager()->shouldQuit()) + if (_vm->shouldQuit()) break; hiliteObj = NULL; @@ -595,4 +595,4 @@ OptionsDialog::OptionsDialog() { } -} // End of namespace tSage +} // End of namespace TsAGE diff --git a/engines/tsage/dialogs.h b/engines/tsage/dialogs.h index a50307f775..55adb6c813 100644 --- a/engines/tsage/dialogs.h +++ b/engines/tsage/dialogs.h @@ -30,7 +30,7 @@ #include "common/rect.h" #include "common/system.h" -namespace tSage { +namespace TsAGE { class MessageDialog : public GfxDialog { public: @@ -128,6 +128,6 @@ public: static void show(); }; -} // End of namespace tSage +} // End of namespace TsAGE #endif diff --git a/engines/tsage/events.cpp b/engines/tsage/events.cpp index a24f65421b..44c79bd2fe 100644 --- a/engines/tsage/events.cpp +++ b/engines/tsage/events.cpp @@ -31,7 +31,7 @@ #include "tsage/tsage.h" #include "tsage/globals.h" -namespace tSage { +namespace TsAGE { EventsClass::EventsClass() { _currentCursor = CURSOR_NONE; @@ -40,6 +40,7 @@ EventsClass::EventsClass() { _priorFrameTime = 0; _prevDelayFrame = 0; _saver->addListener(this); + _saver->addLoadNotifier(&EventsClass::loadNotifierProc); } bool EventsClass::pollEvent() { @@ -78,7 +79,7 @@ bool EventsClass::pollEvent() { void EventsClass::waitForPress(int eventMask) { Event evt; - while (!_vm->getEventManager()->shouldQuit() && !getEvent(evt, eventMask)) + while (!_vm->shouldQuit() && !getEvent(evt, eventMask)) g_system->delayMillis(10); } @@ -86,7 +87,7 @@ void EventsClass::waitForPress(int eventMask) { * Standard event retrieval, which only returns keyboard and mouse clicks */ bool EventsClass::getEvent(Event &evt, int eventMask) { - while (pollEvent() && !_vm->getEventManager()->shouldQuit()) { + while (pollEvent() && !_vm->shouldQuit()) { evt.handled = false; evt.eventType = EVENT_NONE; evt.mousePos = _event.mouse; @@ -154,7 +155,7 @@ void EventsClass::setCursor(CursorType cursorType) { // No cursor _globals->setFlag(122); - if (_vm->getFeatures() & GF_DEMO) { + if ((_vm->getFeatures() & GF_DEMO) || (_vm->getGameID() == GType_BlueForce)) { CursorMan.showMouse(false); return; } @@ -315,4 +316,13 @@ void EventsClass::listenerSynchronize(Serializer &s) { } } -} // end of namespace tSage +void EventsClass::loadNotifierProc(bool postFlag) { + if (postFlag) { + if (_globals->_events._lastCursor == CURSOR_NONE) + _globals->_events._lastCursor = _globals->_events._currentCursor; + else + _globals->_events._lastCursor = CURSOR_NONE; + } +} + +} // end of namespace TsAGE diff --git a/engines/tsage/events.h b/engines/tsage/events.h index e0fbd88745..c36db59270 100644 --- a/engines/tsage/events.h +++ b/engines/tsage/events.h @@ -29,7 +29,7 @@ #include "graphics/surface.h" #include "tsage/saveload.h" -namespace tSage { +namespace TsAGE { enum EventType {EVENT_NONE = 0, EVENT_BUTTON_DOWN = 1, EVENT_BUTTON_UP = 2, EVENT_KEYPRESS = 4, EVENT_MOUSE_MOVE = 8}; @@ -100,8 +100,9 @@ public: void delay(int numFrames); virtual void listenerSynchronize(Serializer &s); + static void loadNotifierProc(bool postFlag); }; -} // End of namespace tSage +} // End of namespace TsAGE #endif diff --git a/engines/tsage/globals.cpp b/engines/tsage/globals.cpp index 34b26ec311..27067c7d1c 100644 --- a/engines/tsage/globals.cpp +++ b/engines/tsage/globals.cpp @@ -22,11 +22,11 @@ #include "tsage/globals.h" #include "tsage/tsage.h" -#include "tsage/blueforce_logic.h" -#include "tsage/ringworld_demo.h" -#include "tsage/ringworld_logic.h" +#include "tsage/blue_force/blueforce_logic.h" +#include "tsage/ringworld/ringworld_demo.h" +#include "tsage/ringworld/ringworld_logic.h" -namespace tSage { +namespace TsAGE { Globals *_globals = NULL; ResourceManager *_resourceManager = NULL; @@ -51,7 +51,7 @@ static SavedObject *classFactoryProc(const Common::String &className) { /*--------------------------------------------------------------------------*/ Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screenSurface), - _randomSource("tsage"), _unkColor1(0), _unkColor2(255), _unkColor3(255) { + _randomSource("tsage"), _color1(0), _color2(255), _color3(255) { reset(); _stripNum = 0; _gfxEdgeAdjust = 3; @@ -64,18 +64,26 @@ Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screenSurface _fontColors.foreground = 6; _dialogCenter.y = 80; // Workaround in order to use later version of the engine - _unkColor1 = _gfxColors.foreground; - _unkColor2 = _gfxColors.foreground; - _unkColor3 = _gfxColors.foreground; + _color1 = _gfxColors.foreground; + _color2 = _gfxColors.foreground; + _color3 = _gfxColors.foreground; + } else if (_vm->getGameID() == GType_BlueForce) { + // Blue Force + _gfxFontNumber = 0; + _gfxColors.background = 89; + _gfxColors.foreground = 83; + _fontColors.background = 88; + _fontColors.foreground = 92; + _dialogCenter.y = 165; } else if ((_vm->getGameID() == GType_Ringworld) && (_vm->getFeatures() & GF_CD)) { _gfxFontNumber = 50; _gfxColors.background = 53; _gfxColors.foreground = 0; _fontColors.background = 51; _fontColors.foreground = 54; - _unkColor1 = 18; - _unkColor2 = 18; - _unkColor3 = 18; + _color1 = 18; + _color2 = 18; + _color3 = 18; } else { _gfxFontNumber = 50; _gfxColors.background = 53; @@ -83,9 +91,9 @@ Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screenSurface _fontColors.background = 51; _fontColors.foreground = 54; // Workaround in order to use later version of the engine - _unkColor1 = _gfxColors.foreground; - _unkColor2 = _gfxColors.foreground; - _unkColor3 = _gfxColors.foreground; + _color1 = _gfxColors.foreground; + _color2 = _gfxColors.foreground; + _color3 = _gfxColors.foreground; } _screenSurface.setScreenSurface(); _gfxManagers.push_back(&_gfxManagerInstance); @@ -103,21 +111,25 @@ Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screenSurface switch (_vm->getGameID()) { case GType_Ringworld: if (!(_vm->getFeatures() & GF_DEMO)) { - _inventory = new RingworldInvObjectList(); - _game = new RingworldGame(); + _inventory = new Ringworld::RingworldInvObjectList(); + _game = new Ringworld::RingworldGame(); } else { - _game = new RingworldDemoGame(); + _game = new Ringworld::RingworldDemoGame(); } + _sceneHandler = new SceneHandler(); break; case GType_BlueForce: - _game = new BlueForceGame(); + _game = new BlueForce::BlueForceGame(); + _sceneHandler = new BlueForce::SceneHandlerExt(); break; } } Globals::~Globals() { + _scenePalette.clearListeners(); delete _inventory; + delete _sceneHandler; delete _game; _globals = NULL; } @@ -142,9 +154,9 @@ void Globals::synchronize(Serializer &s) { s.syncAsSint32LE(_fontColors.foreground); if (s.getVersion() >= 4) { - s.syncAsByte(_unkColor1); - s.syncAsByte(_unkColor2); - s.syncAsByte(_unkColor3); + s.syncAsByte(_color1); + s.syncAsByte(_color2); + s.syncAsByte(_color3); } s.syncAsSint16LE(_dialogCenter.x); s.syncAsSint16LE(_dialogCenter.y); @@ -166,5 +178,39 @@ void Globals::dispatchSounds() { Common::for_each(_sounds.begin(), _sounds.end(), Globals::dispatchSound); } +/*--------------------------------------------------------------------------*/ + +namespace BlueForce { + +BlueForceGlobals::BlueForceGlobals(): Globals() { + _interfaceY = 0; + _v51C44 = 1; + _v4CEA2 = 0; + _v4CEA8 = 0; + _v4CEF2 = 0; + _v4CEF4 = 0; + _v4CF9E = 0; + _v4E238 = 0; + _v501FC = 0; + _v51C42 = 0; + _bikiniHutState = 0; + _mapLocationId = 1; + Common::set_to(&_globalFlags[0], &_globalFlags[12], 0); +} + +void BlueForceGlobals::synchronize(Serializer &s) { + Globals::synchronize(s); + error("Sync variables"); +} + +bool BlueForceGlobals::getFlag(int v) { + return _globalFlags[v / 16] & (1 << (v % 8)); +} + +void BlueForceGlobals::setFlag(int v) { + _globalFlags[v / 16] |= 1 << (v % 8); +} + +} // end of namespace BlueForce -} // end of namespace tSage +} // end of namespace TsAGE diff --git a/engines/tsage/globals.h b/engines/tsage/globals.h index 7cfec718e2..2d409b6343 100644 --- a/engines/tsage/globals.h +++ b/engines/tsage/globals.h @@ -31,7 +31,7 @@ #include "tsage/sound.h" #include "tsage/saveload.h" -namespace tSage { +namespace TsAGE { class Globals : public SavedObject { private: @@ -40,7 +40,7 @@ public: GfxSurface _screenSurface; GfxManager _gfxManagerInstance; Common::List<GfxManager *> _gfxManagers; - SceneHandler _sceneHandler; + SceneHandler *_sceneHandler; Game *_game; EventsClass _events; SceneManager _sceneManager; @@ -54,7 +54,7 @@ public: int _gfxFontNumber; GfxColors _gfxColors; GfxColors _fontColors; - byte _unkColor1, _unkColor2, _unkColor3; + byte _color1, _color2, _color3; SoundManager _soundManager; Common::Point _dialogCenter; WalkRegions _walkRegions; @@ -98,10 +98,45 @@ public: extern Globals *_globals; +#define GLOBALS (*_globals) +#define BF_GLOBALS (*((::TsAGE::BlueForce::BlueForceGlobals *)_globals)) + // Note: Currently this can't be part of the _globals structure, since it needs to be constructed // prior to many of the fields in Globals execute their constructors extern ResourceManager *_resourceManager; -} // End of namespace tSage + +namespace BlueForce { + +using namespace TsAGE; + +class BlueForceGlobals: public Globals { +public: + ASoundExt _sound1, _sound2, _sound3; + int _v4CEA2; + int _v4CEA8; + int _v4CEF2; + int _v4CEF4; + int _v4CF9E; + int _v4E238; + int _v501FC; + int _v51C42; + int _v51C44; + int _interfaceY; + int _bikiniHutState; + int _mapLocationId; + uint8 _globalFlags[12]; + + BlueForceGlobals(); + virtual Common::String getClassName() { return "BFGlobals"; } + virtual void synchronize(Serializer &s); + + void setFlag(int v); + bool getFlag(int v); +}; + +} // End of namespace BlueForce + +} // End of namespace TsAGE #endif diff --git a/engines/tsage/graphics.cpp b/engines/tsage/graphics.cpp index fce9e1317d..1884bfb4f5 100644 --- a/engines/tsage/graphics.cpp +++ b/engines/tsage/graphics.cpp @@ -30,7 +30,7 @@ #include "graphics/surface.h" #include "tsage/globals.h" -namespace tSage { +namespace TsAGE { /** * Creates a new graphics surface with the specified area of another surface @@ -408,7 +408,7 @@ bool GfxSurface::displayText(const Common::String &msg, const Common::Point &pt) // Write for a mouse or keypress Event event; - while (!_globals->_events.getEvent(event, EVENT_BUTTON_DOWN | EVENT_KEYPRESS) && !_vm->getEventManager()->shouldQuit()) + while (!_globals->_events.getEvent(event, EVENT_BUTTON_DOWN | EVENT_KEYPRESS) && !_vm->shouldQuit()) ; // Restore the display area @@ -626,9 +626,9 @@ void GfxElement::setDefaults() { _fontNumber = _globals->_gfxFontNumber; _colors = _globals->_gfxColors; _fontColors = _globals->_fontColors; - _unkColor1 = _globals->_unkColor1; - _unkColor2 = _globals->_unkColor2; - _unkColor3 = _globals->_unkColor3; + _color1 = _globals->_color1; + _color2 = _globals->_color2; + _color3 = _globals->_color3; } /** @@ -718,7 +718,7 @@ bool GfxElement::focusedEvent(Event &event) { int xOffset = mousePos.x - _globals->_events._mousePos.x; int yOffset = mousePos.y - _globals->_events._mousePos.y; - while (event.eventType != EVENT_BUTTON_UP && !_vm->getEventManager()->shouldQuit()) { + while (event.eventType != EVENT_BUTTON_UP && !_vm->shouldQuit()) { g_system->delayMillis(10); if (_bounds.contains(mousePos)) { @@ -824,9 +824,9 @@ void GfxMessage::draw() { gfxManager.setFillFlag(false); gfxManager._font.setFontNumber(_fontNumber); - gfxManager._font._colors.foreground = this->_unkColor1; - gfxManager._font._colors2.background = this->_unkColor2; - gfxManager._font._colors2.foreground = this->_unkColor3; + gfxManager._font._colors.foreground = this->_color1; + gfxManager._font._colors2.background = this->_color2; + gfxManager._font._colors2.foreground = this->_color3; // Display the text gfxManager._font.writeLines(_message.c_str(), _bounds, _textAlign); @@ -867,9 +867,9 @@ void GfxButton::draw() { gfxManager._font.setFontNumber(_fontNumber); // - gfxManager._font._colors.foreground = this->_unkColor1; - gfxManager._font._colors2.background = this->_unkColor2; - gfxManager._font._colors2.foreground = this->_unkColor3; + gfxManager._font._colors.foreground = this->_color1; + gfxManager._font._colors2.background = this->_color2; + gfxManager._font._colors2.foreground = this->_color3; // Display the button's text Rect tempRect(_bounds); @@ -1029,7 +1029,7 @@ GfxButton *GfxDialog::execute(GfxButton *defaultButton) { GfxButton *selectedButton = NULL; bool breakFlag = false; - while (!_vm->getEventManager()->shouldQuit() && !breakFlag) { + while (!_vm->shouldQuit() && !breakFlag) { Event event; while (_globals->_events.getEvent(event) && !breakFlag) { // Adjust mouse positions to be relative within the dialog @@ -1512,4 +1512,4 @@ GfxFontBackup::~GfxFontBackup() { } -} // End of namespace tSage +} // End of namespace TsAGE diff --git a/engines/tsage/graphics.h b/engines/tsage/graphics.h index e09e1093a3..06b482d7b5 100644 --- a/engines/tsage/graphics.h +++ b/engines/tsage/graphics.h @@ -30,7 +30,7 @@ #include "common/system.h" #include "graphics/surface.h" -namespace tSage { +namespace TsAGE { class GfxSurface; class Region; @@ -177,7 +177,7 @@ public: uint16 _fontNumber; GfxColors _colors; GfxColors _fontColors; - byte _unkColor1, _unkColor2, _unkColor3; + byte _color1, _color2, _color3; uint16 _keycode; public: GfxElement(); @@ -343,6 +343,6 @@ GfxSurface *Surface_getArea(GfxSurface &src, const Rect &bounds); GfxSurface surfaceFromRes(const byte *imgData); GfxSurface surfaceFromRes(int resNum, int rlbNum, int subNum); -} // End of namespace tSage +} // End of namespace TsAGE #endif diff --git a/engines/tsage/module.mk b/engines/tsage/module.mk index aefc8b0992..5c7104936e 100644 --- a/engines/tsage/module.mk +++ b/engines/tsage/module.mk @@ -1,7 +1,9 @@ MODULE := engines/tsage MODULE_OBJS := \ - blueforce_logic.o \ + blue_force/blueforce_logic.o \ + blue_force/blueforce_scenes0.o \ + blue_force/blueforce_scenes1.o \ converse.o \ core.o \ debugger.o \ @@ -11,16 +13,16 @@ MODULE_OBJS := \ globals.o \ graphics.o \ resources.o \ - ringworld_demo.o \ - ringworld_logic.o \ - ringworld_scenes1.o \ - ringworld_scenes2.o \ - ringworld_scenes3.o \ - ringworld_scenes4.o \ - ringworld_scenes5.o \ - ringworld_scenes6.o \ - ringworld_scenes8.o \ - ringworld_scenes10.o \ + ringworld/ringworld_demo.o \ + ringworld/ringworld_logic.o \ + ringworld/ringworld_scenes1.o \ + ringworld/ringworld_scenes2.o \ + ringworld/ringworld_scenes3.o \ + ringworld/ringworld_scenes4.o \ + ringworld/ringworld_scenes5.o \ + ringworld/ringworld_scenes6.o \ + ringworld/ringworld_scenes8.o \ + ringworld/ringworld_scenes10.o \ saveload.o \ scenes.o \ sound.o \ @@ -34,4 +36,3 @@ endif # Include common rules include $(srcdir)/rules.mk - diff --git a/engines/tsage/resources.cpp b/engines/tsage/resources.cpp index 6d2c6b5837..99b431b5dc 100644 --- a/engines/tsage/resources.cpp +++ b/engines/tsage/resources.cpp @@ -28,7 +28,7 @@ #include "tsage/resources.h" #include "tsage/tsage.h" -namespace tSage { +namespace TsAGE { MemoryManager::MemoryManager() { @@ -504,4 +504,4 @@ Common::String ResourceManager::getMessage(int resNum, int lineNum, bool suppres return result; } -} // end of namespace tSage +} // end of namespace TsAGE diff --git a/engines/tsage/resources.h b/engines/tsage/resources.h index efbb86b24e..176d60fcc4 100644 --- a/engines/tsage/resources.h +++ b/engines/tsage/resources.h @@ -33,7 +33,7 @@ #include "common/util.h" #include "graphics/surface.h" -namespace tSage { +namespace TsAGE { // Magic number used by original game to identify valid memory blocks const uint32 MEMORY_ENTRY_ID = 0xE11DA722; @@ -175,6 +175,6 @@ public: }; -} // end of namespace tSage +} // end of namespace TsAGE #endif diff --git a/engines/tsage/ringworld_demo.cpp b/engines/tsage/ringworld/ringworld_demo.cpp index b24fec98f9..5612325aff 100644 --- a/engines/tsage/ringworld_demo.cpp +++ b/engines/tsage/ringworld/ringworld_demo.cpp @@ -20,12 +20,14 @@ * */ -#include "tsage/ringworld_demo.h" +#include "tsage/ringworld/ringworld_demo.h" #include "tsage/scenes.h" #include "tsage/tsage.h" #include "tsage/staticres.h" -namespace tSage { +namespace TsAGE { + +namespace Ringworld { void RingworldDemoGame::start() { // Start the demo's single scene @@ -117,4 +119,6 @@ void RingworldDemoScene::process(Event &event) { } -} // End of namespace tSage +} // End of namespace Ringworld + +} // End of namespace TsAGE diff --git a/engines/tsage/ringworld_demo.h b/engines/tsage/ringworld/ringworld_demo.h index 3e7431e107..30527b0aea 100644 --- a/engines/tsage/ringworld_demo.h +++ b/engines/tsage/ringworld/ringworld_demo.h @@ -30,7 +30,11 @@ #include "tsage/globals.h" #include "tsage/sound.h" -namespace tSage { +namespace TsAGE { + +namespace Ringworld { + +using namespace TsAGE; class RingworldDemoGame: public Game { private: @@ -54,6 +58,8 @@ public: virtual void signal(); }; -} // End of namespace tSage +} // End of namespace Ringworld + +} // End of namespace TsAGE #endif diff --git a/engines/tsage/ringworld_logic.cpp b/engines/tsage/ringworld/ringworld_logic.cpp index 58501172af..2a34e49b39 100644 --- a/engines/tsage/ringworld_logic.cpp +++ b/engines/tsage/ringworld/ringworld_logic.cpp @@ -23,21 +23,23 @@ #include "common/config-manager.h" #include "common/translation.h" #include "gui/saveload.h" -#include "tsage/ringworld_logic.h" +#include "tsage/ringworld/ringworld_logic.h" #include "tsage/scenes.h" #include "tsage/tsage.h" #include "tsage/staticres.h" -#include "tsage/ringworld_demo.h" -#include "tsage/ringworld_scenes1.h" -#include "tsage/ringworld_scenes2.h" -#include "tsage/ringworld_scenes3.h" -#include "tsage/ringworld_scenes4.h" -#include "tsage/ringworld_scenes5.h" -#include "tsage/ringworld_scenes6.h" -#include "tsage/ringworld_scenes8.h" -#include "tsage/ringworld_scenes10.h" - -namespace tSage { +#include "tsage/ringworld/ringworld_demo.h" +#include "tsage/ringworld/ringworld_scenes1.h" +#include "tsage/ringworld/ringworld_scenes2.h" +#include "tsage/ringworld/ringworld_scenes3.h" +#include "tsage/ringworld/ringworld_scenes4.h" +#include "tsage/ringworld/ringworld_scenes5.h" +#include "tsage/ringworld/ringworld_scenes6.h" +#include "tsage/ringworld/ringworld_scenes8.h" +#include "tsage/ringworld/ringworld_scenes10.h" + +namespace TsAGE { + +namespace Ringworld { Scene *RingworldGame::createScene(int sceneNumber) { switch (sceneNumber) { @@ -296,7 +298,7 @@ void SceneArea::draw(bool flag) { void SceneArea::wait() { // Wait until a mouse or keypress Event event; - while (!_vm->getEventManager()->shouldQuit() && !_globals->_events.getEvent(event)) { + while (!_vm->shouldQuit() && !_globals->_events.getEvent(event)) { g_system->updateScreen(); g_system->delayMillis(10); } @@ -1285,7 +1287,7 @@ void RingworldGame::saveGame() { MessageDialog::show(SAVING_NOT_ALLOWED_MSG, OK_BTN_STRING); else { // Show the save dialog - handleSaveLoad(true, _globals->_sceneHandler._saveGameSlot, _globals->_sceneHandler._saveName); + handleSaveLoad(true, _globals->_sceneHandler->_saveGameSlot, _globals->_sceneHandler->_saveName); } } @@ -1294,7 +1296,7 @@ void RingworldGame::restoreGame() { MessageDialog::show(RESTORING_NOT_ALLOWED_MSG, OK_BTN_STRING); else { // Show the load dialog - handleSaveLoad(false, _globals->_sceneHandler._loadGameSlot, _globals->_sceneHandler._saveName); + handleSaveLoad(false, _globals->_sceneHandler->_loadGameSlot, _globals->_sceneHandler->_saveName); } } @@ -1346,7 +1348,7 @@ void RingworldGame::start() { } if (slot >= 0) - _globals->_sceneHandler._loadGameSlot = slot; + _globals->_sceneHandler->_loadGameSlot = slot; else // Switch to the title screen _globals->_sceneManager.setNewScene(1000); @@ -1363,8 +1365,8 @@ void RingworldGame::restart() { _globals->setFlag(34); // Clear save/load slots - _globals->_sceneHandler._saveGameSlot = -1; - _globals->_sceneHandler._loadGameSlot = -1; + _globals->_sceneHandler->_saveGameSlot = -1; + _globals->_sceneHandler->_loadGameSlot = -1; _globals->_stripNum = 0; _globals->_events.setCursor(CURSOR_WALK); @@ -1429,8 +1431,8 @@ void RingworldGame::endGame(int resNum, int lineNum) { restart(); breakFlag = true; } else { - handleSaveLoad(false, _globals->_sceneHandler._loadGameSlot, _globals->_sceneHandler._saveName); - breakFlag = _globals->_sceneHandler._loadGameSlot >= 0; + handleSaveLoad(false, _globals->_sceneHandler->_loadGameSlot, _globals->_sceneHandler->_saveName); + breakFlag = _globals->_sceneHandler->_loadGameSlot >= 0; } } while (!breakFlag); } @@ -1487,4 +1489,6 @@ void RingworldGame::processEvent(Event &event) { } } -} // End of namespace tSage +} // End of namespace Ringworld + +} // End of namespace TsAGE diff --git a/engines/tsage/ringworld_logic.h b/engines/tsage/ringworld/ringworld_logic.h index 19b0f10b42..73ecc9722b 100644 --- a/engines/tsage/ringworld_logic.h +++ b/engines/tsage/ringworld/ringworld_logic.h @@ -29,7 +29,11 @@ #include "tsage/scenes.h" #include "tsage/globals.h" -namespace tSage { +namespace TsAGE { + +namespace Ringworld { + +using namespace TsAGE; #define ADD_PLAYER_MOVER(X, Y) { Common::Point pt(X, Y); PlayerMover *mover = new PlayerMover(); \ _globals->_player.addMover(mover, &pt, this); } @@ -438,7 +442,7 @@ public: virtual Common::String getClassName() { return "RingworldInvObjectList"; } }; -#define RING_INVENTORY (*((RingworldInvObjectList *)_globals->_inventory)) +#define RING_INVENTORY (*((::TsAGE::Ringworld::RingworldInvObjectList *)_globals->_inventory)) class RingworldGame: public Game { protected: @@ -456,6 +460,8 @@ public: virtual void processEvent(Event &event); }; -} // End of namespace tSage +} // End of namespace Ringworld + +} // End of namespace TsAGE #endif diff --git a/engines/tsage/ringworld_scenes1.cpp b/engines/tsage/ringworld/ringworld_scenes1.cpp index 8299a05967..20af25561c 100644 --- a/engines/tsage/ringworld_scenes1.cpp +++ b/engines/tsage/ringworld/ringworld_scenes1.cpp @@ -20,12 +20,14 @@ * */ -#include "tsage/ringworld_scenes1.h" +#include "tsage/ringworld/ringworld_scenes1.h" #include "tsage/scenes.h" #include "tsage/tsage.h" #include "tsage/staticres.h" -namespace tSage { +namespace TsAGE { + +namespace Ringworld { /*-------------------------------------------------------------------------- * Scene 10 - Kziniti Palace (Introduction) @@ -1330,6 +1332,24 @@ void Scene40::Action8::signal() { } } +void Scene40::Action8::dispatch() { + if (_action) + _action->dispatch(); + + if (_delayFrames) { + uint32 frameNumber = _globals->_events.getFrameNumber(); + if ((_startFrame + 60) < frameNumber) { + --_delayFrames; + _startFrame = frameNumber; + + if (_delayFrames <= 0) { + _delayFrames = 0; + signal(); + } + } + } +} + /*--------------------------------------------------------------------------*/ void Scene40::DyingKzin::doAction(int action) { @@ -1416,7 +1436,7 @@ void Scene40::Item2::doAction(int action) { SceneItem::display2(40, 37); break; default: - SceneItem::doAction(action); + SceneHotspot::doAction(action); break; } } @@ -1437,7 +1457,7 @@ void Scene40::Item6::doAction(int action) { SceneItem::display2(40, 36); break; default: - SceneItem::doAction(action); + SceneHotspot::doAction(action); break; } } @@ -1446,7 +1466,7 @@ void Scene40::Item6::doAction(int action) { Scene40::Scene40() : _item1(2, OBJECT_SCANNER, 40, 24, OBJECT_STUNNER, 40, 25, CURSOR_LOOK, 40, 7, CURSOR_USE, 40, 16, LIST_END), - _item3(5, OBJECT_SCANNER, 40, 26, OBJECT_STUNNER, 40, 27, CURSOR_LOOK, 40, 9, CURSOR_USE, 40, 17, LIST_END), + _item3(5, OBJECT_SCANNER, 40, 28, OBJECT_STUNNER, 40, 27, CURSOR_LOOK, 40, 2, CURSOR_USE, 40, 30, LIST_END), _item4(6, OBJECT_SCANNER, 40, 31, OBJECT_STUNNER, 40, 32, CURSOR_LOOK, 40, 5, CURSOR_USE, 40, 33, LIST_END), _item5(0, CURSOR_LOOK, 40, 11, LIST_END), _item7(4, OBJECT_SCANNER, 40, 26, OBJECT_STUNNER, 40, 27, CURSOR_LOOK, 40, 9, CURSOR_USE, 40, 17, LIST_END), @@ -2271,7 +2291,7 @@ void Scene60::Item::doAction(int action) { setAction(&scene->_sequenceManager, this, 62, NULL); break; default: - SceneItem::doAction(action); + SceneHotspot::doAction(action); break; } } @@ -3148,7 +3168,7 @@ Scene6100::Scene6100(): Scene() { _angle = 0; _msgActive = false; - _globals->_sceneHandler._delayTicks = 8; + _globals->_sceneHandler->_delayTicks = 8; _globals->_player.disableControl(); _globals->_events.setCursor(CURSOR_WALK); @@ -3324,4 +3344,6 @@ void Scene6100::showMessage(const Common::String &msg, int color, Action *action } } -} // End of namespace tSage +} // End of namespace Ringworld + +} // End of namespace TsAGE diff --git a/engines/tsage/ringworld_scenes1.h b/engines/tsage/ringworld/ringworld_scenes1.h index 283cf68e07..49ea65eb3a 100644 --- a/engines/tsage/ringworld_scenes1.h +++ b/engines/tsage/ringworld/ringworld_scenes1.h @@ -24,7 +24,7 @@ #define TSAGE_RINGWORLD_SCENES1_H #include "common/scummsys.h" -#include "tsage/ringworld_logic.h" +#include "tsage/ringworld/ringworld_logic.h" #include "tsage/converse.h" #include "tsage/events.h" #include "tsage/core.h" @@ -32,7 +32,11 @@ #include "tsage/globals.h" #include "tsage/sound.h" -namespace tSage { +namespace TsAGE { + +namespace Ringworld { + +using namespace TsAGE; class Scene10 : public Scene { /* Actions */ @@ -201,6 +205,7 @@ class Scene40 : public Scene { class Action8 : public Action { public: virtual void signal(); + virtual void dispatch(); }; /* Objects */ @@ -214,15 +219,15 @@ class Scene40 : public Scene { }; /* Items */ - class Item2 : public SceneItem { + class Item2 : public SceneHotspot { public: virtual void doAction(int action); }; - class Item6 : public SceneItem { + class Item6 : public SceneHotspot { public: virtual void doAction(int action); }; - class Item8 : public SceneItem { + class Item8 : public SceneHotspot { public: virtual void doAction(int action); }; @@ -532,6 +537,8 @@ public: }; -} // End of namespace tSage +} // End of namespace Ringworld + +} // End of namespace TsAGE #endif diff --git a/engines/tsage/ringworld_scenes10.cpp b/engines/tsage/ringworld/ringworld_scenes10.cpp index ba4060548e..df25c324ab 100644 --- a/engines/tsage/ringworld_scenes10.cpp +++ b/engines/tsage/ringworld/ringworld_scenes10.cpp @@ -21,12 +21,14 @@ */ #include "graphics/cursorman.h" -#include "tsage/ringworld_scenes10.h" +#include "tsage/ringworld/ringworld_scenes10.h" #include "tsage/scenes.h" #include "tsage/tsage.h" #include "tsage/staticres.h" -namespace tSage { +namespace TsAGE { + +namespace Ringworld { Scene2::Scene2() : Scene() { _sceneState = 0; @@ -1746,7 +1748,8 @@ void Scene9900::strAction2::signal() { frameWidth = _txtArray2[_txtArray1Index].getFrame().getBounds().width(); _txtArray2[_txtArray1Index].setPosition(Common::Point((320 - frameWidth) / 2, 200 + frameHeight)); } else { - _globals->_player.enableControl(); + // WORKAROUND: Fix inventory becoming available at end of credits + _globals->_events.setCursor(CURSOR_WALK); _actionIndex = 3; signal(); } @@ -2085,4 +2088,6 @@ void Scene9999::postInit(SceneObjectList *OwnerList) { } -} // End of namespace tSage +} // End of namespace Ringworld + +} // End of namespace TsAGE diff --git a/engines/tsage/ringworld_scenes10.h b/engines/tsage/ringworld/ringworld_scenes10.h index 33b16d0014..02c42f3d01 100644 --- a/engines/tsage/ringworld_scenes10.h +++ b/engines/tsage/ringworld/ringworld_scenes10.h @@ -24,13 +24,17 @@ #define TSAGE_RINGWORLD_SCENES10_H #include "common/scummsys.h" -#include "tsage/ringworld_logic.h" +#include "tsage/ringworld/ringworld_logic.h" #include "tsage/events.h" #include "tsage/core.h" #include "tsage/scenes.h" #include "tsage/globals.h" -namespace tSage { +namespace TsAGE { + +namespace Ringworld { + +using namespace TsAGE; class SceneObject9150 : public SceneObject { public: @@ -526,7 +530,8 @@ public: virtual void postInit(SceneObjectList *OwnerList = NULL); }; +} // End of namespace Ringworld -} // End of namespace tSage +} // End of namespace TsAGE #endif diff --git a/engines/tsage/ringworld_scenes2.cpp b/engines/tsage/ringworld/ringworld_scenes2.cpp index 0154123c3d..cfd3e3d8f7 100644 --- a/engines/tsage/ringworld_scenes2.cpp +++ b/engines/tsage/ringworld/ringworld_scenes2.cpp @@ -21,12 +21,14 @@ */ #include "common/config-manager.h" -#include "tsage/ringworld_scenes2.h" +#include "tsage/ringworld/ringworld_scenes2.h" #include "tsage/scenes.h" #include "tsage/tsage.h" #include "tsage/staticres.h" -namespace tSage { +namespace TsAGE { + +namespace Ringworld { /*-------------------------------------------------------------------------- * Scene 1000 - Title Screen @@ -925,4 +927,6 @@ void Scene1500::postInit(SceneObjectList *OwnerList) { } } -} // End of namespace tSage +} // End of namespace Ringworld + +} // End of namespace TsAGE diff --git a/engines/tsage/ringworld_scenes2.h b/engines/tsage/ringworld/ringworld_scenes2.h index 93a8f04fd4..3502aea15b 100644 --- a/engines/tsage/ringworld_scenes2.h +++ b/engines/tsage/ringworld/ringworld_scenes2.h @@ -24,13 +24,17 @@ #define TSAGE_RINGWORLD_SCENES2_H #include "common/scummsys.h" -#include "tsage/ringworld_logic.h" +#include "tsage/ringworld/ringworld_logic.h" #include "tsage/events.h" #include "tsage/core.h" #include "tsage/scenes.h" #include "tsage/globals.h" -namespace tSage { +namespace TsAGE { + +namespace Ringworld { + +using namespace TsAGE; class Scene1000 : public Scene { /* Actions */ @@ -142,8 +146,8 @@ public: virtual void postInit(SceneObjectList *OwnerList = NULL); }; +} // End of namespace Ringworld - -} // End of namespace tSage +} // End of namespace TsAGE #endif diff --git a/engines/tsage/ringworld_scenes3.cpp b/engines/tsage/ringworld/ringworld_scenes3.cpp index 824a96a18b..f744a98c33 100644 --- a/engines/tsage/ringworld_scenes3.cpp +++ b/engines/tsage/ringworld/ringworld_scenes3.cpp @@ -21,12 +21,14 @@ */ #include "common/config-manager.h" -#include "tsage/ringworld_scenes3.h" +#include "tsage/ringworld/ringworld_scenes3.h" #include "tsage/scenes.h" #include "tsage/tsage.h" #include "tsage/staticres.h" -namespace tSage { +namespace TsAGE { + +namespace Ringworld { /*-------------------------------------------------------------------------- * Scene 2000 - Cockpit cutscenes @@ -324,7 +326,7 @@ void Scene2000::Action14::signal() { scene->_stripManager.start(2001, this, scene); break; case 6: - _globals->_soundHandler.fadeOut(0/* was false */); + _globals->_soundHandler.fadeOut(NULL); scene->_object8.setStrip(1); scene->_object8.setFrame(scene->_object8.getFrameCount()); scene->_object8.animate(ANIM_MODE_6, this); @@ -526,7 +528,7 @@ void Scene2100::Action1::signal() { _state = 0; _globals->_events.setCursor(CURSOR_USE); - while (!_state && !_vm->getEventManager()->shouldQuit()) { + while (!_state && !_vm->shouldQuit()) { // Wait for an event Event event; if (!_globals->_events.getEvent(event)) { @@ -786,7 +788,7 @@ void Scene2100::Action9::signal() { scene->_stripManager.start(6051, this, scene); break; case 4: - scene->_soundHandler.fadeOut(0/* was false */); + scene->_soundHandler.fadeOut(NULL); scene->_object4.setStrip(1); scene->_object4.setFrame(scene->_object4.getFrameCount()); scene->_object4.animate(ANIM_MODE_6, this); @@ -1105,7 +1107,7 @@ void Scene2100::Action14::signal() { scene->_stripManager.start(6009, this, scene); break; case 6: - scene->_soundHandler.fadeOut(0/* was false */); + scene->_soundHandler.fadeOut(NULL); scene->_object4.setStrip(1); scene->_object4.setFrame(scene->_object4.getFrameCount()); scene->_object4.animate(ANIM_MODE_6, this); @@ -2257,7 +2259,7 @@ void Scene2150::Action1::signal() { _state = 0; _globals->_events.setCursor(CURSOR_USE); - while (!_state && !_vm->getEventManager()->shouldQuit()) { + while (!_state && !_vm->shouldQuit()) { // Wait for an event Event event; if (!_globals->_events.getEvent(event)) { @@ -5112,7 +5114,7 @@ void Scene2320::Action3::signal() { _state = 0; _globals->_events.setCursor(CURSOR_USE); - while (!_state && !_vm->getEventManager()->shouldQuit()) { + while (!_state && !_vm->shouldQuit()) { // Wait for an event Event event; if (!_globals->_events.getEvent(event)) { @@ -6130,4 +6132,6 @@ void Scene2400::postInit(SceneObjectList *OwnerList) { _globals->_soundHandler.play(153); } -} // End of namespace tSage +} // End of namespace Ringworld + +} // End of namespace TsAGE diff --git a/engines/tsage/ringworld_scenes3.h b/engines/tsage/ringworld/ringworld_scenes3.h index 711360c190..2dbdc27211 100644 --- a/engines/tsage/ringworld_scenes3.h +++ b/engines/tsage/ringworld/ringworld_scenes3.h @@ -26,9 +26,13 @@ #include "common/scummsys.h" #include "tsage/core.h" #include "tsage/converse.h" -#include "tsage/ringworld_logic.h" +#include "tsage/ringworld/ringworld_logic.h" -namespace tSage { +namespace TsAGE { + +namespace Ringworld { + +using namespace TsAGE; class Scene2000 : public Scene { /* Actions */ @@ -890,6 +894,8 @@ public: virtual void postInit(SceneObjectList *OwnerList = NULL); }; -} // End of namespace tSage +} // End of namespace Ringworld + +} // End of namespace TsAGE #endif diff --git a/engines/tsage/ringworld_scenes4.cpp b/engines/tsage/ringworld/ringworld_scenes4.cpp index 838769e4af..0f4c3e49a0 100644 --- a/engines/tsage/ringworld_scenes4.cpp +++ b/engines/tsage/ringworld/ringworld_scenes4.cpp @@ -21,12 +21,14 @@ */ #include "common/config-manager.h" -#include "tsage/ringworld_scenes4.h" +#include "tsage/ringworld/ringworld_scenes4.h" #include "tsage/scenes.h" #include "tsage/tsage.h" #include "tsage/staticres.h" -namespace tSage { +namespace TsAGE { + +namespace Ringworld { /*-------------------------------------------------------------------------- * Scene 3500 - Ringworld Scan @@ -227,7 +229,7 @@ void Scene3700::Action1::signal() { /*--------------------------------------------------------------------------*/ -void Scene3700::postInit(tSage::SceneObjectList *OwnerList) { +void Scene3700::postInit(TsAGE::SceneObjectList *OwnerList) { Scene::postInit(); loadScene(3700); @@ -247,4 +249,6 @@ void Scene3700::postInit(tSage::SceneObjectList *OwnerList) { _globals->_soundHandler.play(195); } -} // End of namespace tSage +} // End of namespace Ringworld + +} // End of namespace TsAGE diff --git a/engines/tsage/ringworld_scenes4.h b/engines/tsage/ringworld/ringworld_scenes4.h index 0b575d02d3..af31de84b9 100644 --- a/engines/tsage/ringworld_scenes4.h +++ b/engines/tsage/ringworld/ringworld_scenes4.h @@ -26,9 +26,13 @@ #include "common/scummsys.h" #include "tsage/core.h" #include "tsage/converse.h" -#include "tsage/ringworld_logic.h" +#include "tsage/ringworld/ringworld_logic.h" -namespace tSage { +namespace TsAGE { + +namespace Ringworld { + +using namespace TsAGE; class Scene3500 : public Scene { /* Actions */ @@ -87,6 +91,8 @@ public: virtual void postInit(SceneObjectList *OwnerList = NULL); }; -} // End of namespace tSage +} // End of namespace Ringworld + +} // End of namespace TsAGE #endif diff --git a/engines/tsage/ringworld_scenes5.cpp b/engines/tsage/ringworld/ringworld_scenes5.cpp index fccc7e1b50..58f47d7f82 100644 --- a/engines/tsage/ringworld_scenes5.cpp +++ b/engines/tsage/ringworld/ringworld_scenes5.cpp @@ -21,12 +21,14 @@ */ #include "common/config-manager.h" -#include "tsage/ringworld_scenes5.h" +#include "tsage/ringworld/ringworld_scenes5.h" #include "tsage/scenes.h" #include "tsage/tsage.h" #include "tsage/staticres.h" -namespace tSage { +namespace TsAGE { + +namespace Ringworld { /*-------------------------------------------------------------------------- * Scene 4000 - Village @@ -3520,7 +3522,7 @@ Scene4250::Scene4250() : _hotspot7(0, CURSOR_LOOK, 4250, 0, LIST_END) { } -void Scene4250::postInit(tSage::SceneObjectList *OwnerList) { +void Scene4250::postInit(TsAGE::SceneObjectList *OwnerList) { loadScene(4250); Scene::postInit(); setZoomPercents(160, 90, 185, 100); @@ -4438,4 +4440,6 @@ void Scene4301::dispatch() { } } -} // End of namespace tSage +} // End of namespace Ringworld + +} // End of namespace TsAGE diff --git a/engines/tsage/ringworld_scenes5.h b/engines/tsage/ringworld/ringworld_scenes5.h index c3ae9f4aa9..6c6b6b6f32 100644 --- a/engines/tsage/ringworld_scenes5.h +++ b/engines/tsage/ringworld/ringworld_scenes5.h @@ -26,9 +26,13 @@ #include "common/scummsys.h" #include "tsage/core.h" #include "tsage/converse.h" -#include "tsage/ringworld_logic.h" +#include "tsage/ringworld/ringworld_logic.h" -namespace tSage { +namespace TsAGE { + +namespace Ringworld { + +using namespace TsAGE; class Scene4000 : public Scene { /* Actions */ @@ -687,7 +691,8 @@ public: } }; +} // End of namespace Ringworld -} // End of namespace tSage +} // End of namespace TsAGE #endif diff --git a/engines/tsage/ringworld_scenes6.cpp b/engines/tsage/ringworld/ringworld_scenes6.cpp index 68c184196c..f21ae59478 100644 --- a/engines/tsage/ringworld_scenes6.cpp +++ b/engines/tsage/ringworld/ringworld_scenes6.cpp @@ -20,12 +20,14 @@ * */ -#include "tsage/ringworld_scenes6.h" +#include "tsage/ringworld/ringworld_scenes6.h" #include "tsage/scenes.h" #include "tsage/tsage.h" #include "tsage/staticres.h" -namespace tSage { +namespace TsAGE { + +namespace Ringworld { /*-------------------------------------------------------------------------- * Scene 5000 - Caverns - Entrance @@ -2196,5 +2198,6 @@ void Scene5300::signal() { } } +} // End of namespace Ringworld -} // End of namespace tSage +} // End of namespace TsAGE diff --git a/engines/tsage/ringworld_scenes6.h b/engines/tsage/ringworld/ringworld_scenes6.h index 2e99f5ab87..79e604a177 100644 --- a/engines/tsage/ringworld_scenes6.h +++ b/engines/tsage/ringworld/ringworld_scenes6.h @@ -24,13 +24,17 @@ #define TSAGE_RINGWORLD_SCENES6_H #include "common/scummsys.h" -#include "tsage/ringworld_logic.h" +#include "tsage/ringworld/ringworld_logic.h" #include "tsage/events.h" #include "tsage/core.h" #include "tsage/scenes.h" #include "tsage/globals.h" -namespace tSage { +namespace TsAGE { + +namespace Ringworld { + +using namespace TsAGE; class Scene5000 : public Scene { /* Actions */ @@ -324,7 +328,8 @@ public: } }; +} // End of namespace Ringworld -} // End of namespace tSage +} // End of namespace TsAGE #endif diff --git a/engines/tsage/ringworld_scenes8.cpp b/engines/tsage/ringworld/ringworld_scenes8.cpp index 2b329b958a..5f1ff5cdca 100644 --- a/engines/tsage/ringworld_scenes8.cpp +++ b/engines/tsage/ringworld/ringworld_scenes8.cpp @@ -21,12 +21,14 @@ */ #include "graphics/cursorman.h" -#include "tsage/ringworld_scenes8.h" +#include "tsage/ringworld/ringworld_scenes8.h" #include "tsage/scenes.h" #include "tsage/tsage.h" #include "tsage/staticres.h" -namespace tSage { +namespace TsAGE { + +namespace Ringworld { void NamedHotspotMult::synchronize(Serializer &s) { SceneHotspot::synchronize(s); @@ -2223,7 +2225,7 @@ void Scene7700::signal() { } break; case 7702: - _soundHandler.fadeOut(0); + _globals->_soundHandler.fadeOut(NULL); _globals->_sceneManager.changeScene(7600); break; case 7703: @@ -2542,4 +2544,6 @@ void Scene7700::synchronize(Serializer &s) { } } -} // End of namespace tSage +} // End of namespace Ringworld + +} // End of namespace TsAGE diff --git a/engines/tsage/ringworld_scenes8.h b/engines/tsage/ringworld/ringworld_scenes8.h index fe9560d9d8..4878db5cc8 100644 --- a/engines/tsage/ringworld_scenes8.h +++ b/engines/tsage/ringworld/ringworld_scenes8.h @@ -24,13 +24,17 @@ #define TSAGE_RINGWORLD_SCENES8_H #include "common/scummsys.h" -#include "tsage/ringworld_logic.h" +#include "tsage/ringworld/ringworld_logic.h" #include "tsage/events.h" #include "tsage/core.h" #include "tsage/scenes.h" #include "tsage/globals.h" -namespace tSage { +namespace TsAGE { + +namespace Ringworld { + +using namespace TsAGE; class NamedHotspotMult : public SceneHotspot { public: @@ -485,6 +489,8 @@ public: virtual void synchronize(Serializer &s); }; -} // End of namespace tSage +} // End of namespace Ringworld + +} // End of namespace TsAGE #endif diff --git a/engines/tsage/saveload.cpp b/engines/tsage/saveload.cpp index 40444cd630..45e655037d 100644 --- a/engines/tsage/saveload.cpp +++ b/engines/tsage/saveload.cpp @@ -30,7 +30,7 @@ #include "tsage/sound.h" #include "tsage/tsage.h" -namespace tSage { +namespace TsAGE { Saver *_saver; @@ -249,12 +249,9 @@ bool Saver::readSavegameHeader(Common::InSaveFile *in, tSageSavegameHeader &head while ((ch = (char)in->readByte()) != '\0') header.saveName += ch; // Get the thumbnail - header.thumbnail = new Graphics::Surface(); - if (!Graphics::loadThumbnail(*in, *header.thumbnail)) { - delete header.thumbnail; - header.thumbnail = NULL; + header.thumbnail = Graphics::loadThumbnail(*in); + if (!header.thumbnail) return false; - } // Read in save date/time header.saveYear = in->readSint16LE(); @@ -413,4 +410,4 @@ void Saver::resolveLoadPointers() { error("Could not resolve savegame block pointers"); } -} // End of namespace tSage +} // End of namespace TsAGE diff --git a/engines/tsage/saveload.h b/engines/tsage/saveload.h index ce181cbc8f..03beafed7c 100644 --- a/engines/tsage/saveload.h +++ b/engines/tsage/saveload.h @@ -29,7 +29,7 @@ #include "common/savefile.h" #include "common/serializer.h" -namespace tSage { +namespace TsAGE { typedef void (*SaveNotifierFn)(bool postFlag); @@ -222,6 +222,6 @@ public: extern Saver *_saver; -} // End of namespace tSage +} // End of namespace TsAGE #endif diff --git a/engines/tsage/scenes.cpp b/engines/tsage/scenes.cpp index 18b3da2698..5aeacda6fe 100644 --- a/engines/tsage/scenes.cpp +++ b/engines/tsage/scenes.cpp @@ -22,11 +22,11 @@ #include "tsage/scenes.h" #include "tsage/globals.h" -#include "tsage/ringworld_logic.h" +#include "tsage/ringworld/ringworld_logic.h" #include "tsage/tsage.h" #include "tsage/saveload.h" -namespace tSage { +namespace TsAGE { SceneManager::SceneManager() { _scene = NULL; @@ -38,6 +38,7 @@ SceneManager::SceneManager() { _scrollerRect = Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); _saver->addListener(this); _objectCount = 0; + _loadMode = 0; } SceneManager::~SceneManager() { @@ -45,7 +46,7 @@ SceneManager::~SceneManager() { } void SceneManager::setNewScene(int sceneNumber) { - warning("SetNewScene(%d)", sceneNumber); + debug(1, "SetNewScene(%d)", sceneNumber); _nextSceneNumber = sceneNumber; } @@ -113,7 +114,7 @@ void SceneManager::sceneChange() { assert(_objectCount == _saver->getObjectCount()); } _objectCount = _saver->getObjectCount(); - _globals->_sceneHandler._delayTicks = 2; + _globals->_sceneHandler->_delayTicks = 2; // Instantiate and set the new scene _scene = getNewScene(); @@ -146,7 +147,7 @@ void SceneManager::fadeInIfNecessary() { } void SceneManager::changeScene(int newSceneNumber) { - warning("changeScene(%d)", newSceneNumber); + debug(1, "changeScene(%d)", newSceneNumber); // Fade out the scene ScenePalette scenePalette; uint32 adjustData = 0; @@ -173,6 +174,11 @@ void SceneManager::changeScene(int newSceneNumber) { // Blank out the screen _globals->_screenSurface.fillRect(_globals->_screenSurface.getBounds(), 0); + // If there are any fading sounds, wait until fading is complete + while (_globals->_soundManager.isFading()) { + g_system->delayMillis(10); + } + // Set the new scene to be loaded setNewScene(newSceneNumber); } @@ -252,6 +258,7 @@ void SceneManager::listenerSynchronize(Serializer &s) { Scene::Scene() : _sceneBounds(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), _backgroundBounds(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT) { _sceneMode = 0; + _activeScreenNumber = 0; _oldSceneBounds = Rect(4000, 4000, 4100, 4100); Common::set_to(&_zoomPercents[0], &_zoomPercents[256], 0); } @@ -296,7 +303,7 @@ void Scene::dispatch() { } void Scene::loadScene(int sceneNum) { - warning("loadScene(%d)", sceneNum); + debug(1, "loadScene(%d)", sceneNum); _screenNumber = sceneNum; if (_globals->_scenePalette.loadPalette(sceneNum)) _globals->_sceneManager._hasPalette = true; @@ -419,6 +426,11 @@ void Scene::refreshBackground(int xAmount, int yAmount) { (xSectionSrc + 1) * 160, (ySectionSrc + 1) * 100); Rect destBounds(xSectionDest * 160, ySectionDest * 100, (xSectionDest + 1) * 160, (ySectionDest + 1) * 100); + if (_vm->getGameID() == GType_BlueForce) { + // For Blue Force, if the scene has an interface area, exclude it from the copy + srcBounds.bottom = MIN<int16>(srcBounds.bottom, BF_GLOBALS._interfaceY); + destBounds.bottom = MIN<int16>(destBounds.bottom, BF_GLOBALS._interfaceY); + } _backSurface.copyFrom(_backSurface, srcBounds, destBounds); } @@ -511,7 +523,7 @@ void Game::execute() { activeFlag = true; } } - } while (activeFlag && !_vm->getEventManager()->shouldQuit()); + } while (activeFlag && !_vm->shouldQuit()); } -} // End of namespace tSage +} // End of namespace TsAGE diff --git a/engines/tsage/scenes.h b/engines/tsage/scenes.h index 5845efaec9..7e8c26f912 100644 --- a/engines/tsage/scenes.h +++ b/engines/tsage/scenes.h @@ -29,7 +29,7 @@ #include "tsage/core.h" #include "tsage/saveload.h" -namespace tSage { +namespace TsAGE { class Scene : public StripCallback { private: @@ -134,6 +134,6 @@ public: virtual void processEvent(Event &event) {} }; -} // End of namespace tSage +} // End of namespace TsAGE #endif diff --git a/engines/tsage/sound.cpp b/engines/tsage/sound.cpp index e26b3d1544..0b77628801 100644 --- a/engines/tsage/sound.cpp +++ b/engines/tsage/sound.cpp @@ -20,6 +20,7 @@ * */ +#include "audio/decoders/raw.h" #include "common/config-manager.h" #include "tsage/core.h" #include "tsage/globals.h" @@ -27,7 +28,7 @@ #include "tsage/graphics.h" #include "tsage/tsage.h" -namespace tSage { +namespace TsAGE { static SoundManager *_soundManager = NULL; @@ -53,6 +54,7 @@ SoundManager::SoundManager() { SoundManager::~SoundManager() { if (__sndmgrReady) { Common::StackLock slock(_serverDisabledMutex); + _vm->_mixer->stopAll(); for (Common::List<Sound *>::iterator i = _soundList.begin(); i != _soundList.end(); ) { Sound *s = *i; @@ -66,7 +68,15 @@ SoundManager::~SoundManager() { } _sfTerminate(); - g_system->getTimerManager()->removeTimerProc(_sfUpdateCallback); +// g_system->getTimerManager()->removeTimerProc(_sfUpdateCallback); + } + + // Free any allocated voice type structures + for (int idx = 0; idx < SOUND_ARR_SIZE; ++idx) { + if (sfManager()._voiceTypeStructPtrs[idx]) { + delete sfManager()._voiceTypeStructPtrs[idx]; + sfManager()._voiceTypeStructPtrs[idx] = NULL; + } } _soundManager = NULL; @@ -78,9 +88,12 @@ void SoundManager::postInit() { _saver->addLoadNotifier(&SoundManager::loadNotifier); _saver->addListener(this); - // Install a timer for handling sound manager updates at 60Hz - g_system->getTimerManager()->installTimerProc(_sfUpdateCallback, 1000000 / GAME_FRAME_RATE, NULL); +// I originally separated the sound manager update method into a separate thread, since +// it handles updates for both music and Fx. However, since Adlib updates also get done in a +// thread, and doesn't get too far ahead, I've left it to the AdlibSoundDriver class to +// call the update method, rather than having it be called separately +// g_system->getTimerManager()->installTimerProc(_sfUpdateCallback, 1000000 / SOUND_FREQUENCY, NULL, "tsageSoundUpdate"); __sndmgrReady = true; } } @@ -155,9 +168,7 @@ Common::List<SoundDriverEntry> &SoundManager::buildDriverList(bool detectFlag) { void SoundManager::installConfigDrivers() { installDriver(ADLIB_DRIVER_NUM); -#ifdef DEBUG installDriver(SBLASTER_DRIVER_NUM); -#endif } Common::List<SoundDriverEntry> &SoundManager::getDriverList(bool detectFlag) { @@ -226,7 +237,7 @@ SoundDriver *SoundManager::instantiateDriver(int driverNum) { case ADLIB_DRIVER_NUM: return new AdlibSoundDriver(); case SBLASTER_DRIVER_NUM: - return new AdlibFxSoundDriver(); + return new SoundBlasterDriver(); default: error("Unknown sound driver - %d", driverNum); } @@ -357,9 +368,6 @@ void SoundManager::rethinkVoiceTypes() { } void SoundManager::_sfSoundServer() { - Common::StackLock slock1(sfManager()._serverDisabledMutex); - Common::StackLock slock2(sfManager()._serverSuspendedMutex); - if (sfManager()._needToRethink) { _sfRethinkVoiceTypes(); sfManager()._needToRethink = false; @@ -451,6 +459,22 @@ void SoundManager::_sfProcessFading() { } } +bool SoundManager::isFading() { + Common::StackLock slock(sfManager()._serverSuspendedMutex); + + // Loop through any active sounds to see if any are being actively faded + Common::List<Sound *>::iterator i = sfManager()._playList.begin(); + while (i != sfManager()._playList.end()) { + Sound *s = *i; + ++i; + + if (s->_fadeDest != -1) + return true; + } + + return false; +} + void SoundManager::_sfUpdateVoiceStructs() { for (int voiceIndex = 0; voiceIndex < SOUND_ARR_SIZE; ++voiceIndex) { VoiceTypeStruct *vs = sfManager()._voiceTypeStructPtrs[voiceIndex]; @@ -1341,7 +1365,7 @@ bool SoundManager::_sfInstallDriver(SoundDriver *driver) { sfManager()._installedDrivers.push_back(driver); driver->_groupOffset = driver->getGroupData(); - driver->_groupMask = READ_LE_UINT32(driver->_groupOffset); + driver->_groupMask = driver->_groupOffset->groupMask; _sfExtractGroupMask(); _sfRethinkSoundDrivers(); @@ -1967,9 +1991,9 @@ void Sound::_soServiceTrackType0(int trackIndex, const byte *channelData) { if (channelNum != -1) { if (voiceType != VOICETYPE_0) { if (chFlags & 0x10) - _soProc42(vtStruct, channelNum, chVoiceType, v); + _soPlaySound2(vtStruct, channelData, channelNum, chVoiceType, v); else - _soProc32(vtStruct, channelNum, chVoiceType, v, b); + _soPlaySound(vtStruct, channelData, channelNum, chVoiceType, v, b); } else if (voiceNum != -1) { assert(driver); driver->proc20(voiceNum, chVoiceType); @@ -2137,7 +2161,7 @@ void Sound::_soUpdateDamper(VoiceTypeStruct *voiceType, int channelNum, VoiceTyp } } -void Sound::_soProc32(VoiceTypeStruct *vtStruct, int channelNum, VoiceType voiceType, int v0, int v1) { +void Sound::_soPlaySound(VoiceTypeStruct *vtStruct, const byte *channelData, int channelNum, VoiceType voiceType, int v0, int v1) { int entryIndex = _soFindSound(vtStruct, channelNum); if (entryIndex != -1) { SoundDriver *driver = vtStruct->_entries[entryIndex]._driver; @@ -2147,11 +2171,11 @@ void Sound::_soProc32(VoiceTypeStruct *vtStruct, int channelNum, VoiceType voice vtStruct->_entries[entryIndex]._type1._field4 = v0; vtStruct->_entries[entryIndex]._type1._field5 = 0; - driver->proc32(this, vtStruct->_entries[entryIndex]._voiceNum, _chProgram[channelNum], v0, v1); + driver->playSound(channelData, 0, _chProgram[channelNum], vtStruct->_entries[entryIndex]._voiceNum, v0, v1); } } -void Sound::_soProc42(VoiceTypeStruct *vtStruct, int channelNum, VoiceType voiceType, int v0) { +void Sound::_soPlaySound2(VoiceTypeStruct *vtStruct, const byte *channelData, int channelNum, VoiceType voiceType, int v0) { for (int trackCtr = 0; trackCtr < _trackInfo._numTracks; ++trackCtr) { const byte *instrument = _channelData[trackCtr]; if ((*(instrument + 13) == v0) && (*instrument == 1)) { @@ -2160,13 +2184,14 @@ void Sound::_soProc42(VoiceTypeStruct *vtStruct, int channelNum, VoiceType voice if (entryIndex != -1) { SoundDriver *driver = vtStruct->_entries[entryIndex]._driver; assert(driver); + byte *trackData = _channelData[trackCtr]; vtStruct->_entries[entryIndex]._type1._field6 = 0; vtStruct->_entries[entryIndex]._type1._field4 = v0; vtStruct->_entries[entryIndex]._type1._field5 = 0; int v1, v2; - driver->proc32(this, vtStruct->_entries[entryIndex]._voiceNum, -1, v0, 0x7F); + driver->playSound(trackData, 14, -1, vtStruct->_entries[entryIndex]._voiceNum, v0, 0x7F); driver->proc42(vtStruct->_entries[entryIndex]._voiceNum, voiceType, 0, &v1, &v2); } break; @@ -2295,24 +2320,26 @@ void Sound::_soServiceTrackType1(int trackIndex, const byte *channelData) { vtStruct->_entries[entryIndex]._type1._field5 = 0; int v1, v2; - driver->proc32(this, vtStruct->_entries[entryIndex]._voiceNum, -1, *(channelData + 1), 0x7f); + driver->playSound(channelData, 14, -1, vtStruct->_entries[entryIndex]._voiceNum, *(channelData + 1), 0x7f); driver->proc42(vtStruct->_entries[entryIndex]._voiceNum, *(channelData + 1), _loop ? 1 : 0, &v1, &v2); + _trkState[trackIndex] = 2; } } else { for (uint entryIndex = 0; entryIndex < vtStruct->_entries.size(); ++entryIndex) { VoiceStructEntry &vte = vtStruct->_entries[entryIndex]; VoiceStructEntryType1 &vse = vte._type1; - if ((vse._sound == this) && (vse._channelNum == channel) && (vse._field4 == vtStruct->_total)) { + if ((vse._sound == this) && (vse._channelNum == channel) && (vse._field4 == *(channelData + 1))) { SoundDriver *driver = vte._driver; - int v1, v2; - driver->proc42(vte._voiceNum, vtStruct->_total, _loop ? 1 : 0, &v1, &v2); - if (v2) { + int isEnded, resetTimer; + driver->proc42(vte._voiceNum, vtStruct->_total, _loop ? 1 : 0, &isEnded, &resetTimer); + if (isEnded) { _trkState[trackIndex] = 0; - } else if (vtStruct->_total) { + } else if (resetTimer) { _timer = 0; } + return; } } @@ -2436,6 +2463,31 @@ void ASound::fade(int fadeDest, int fadeSteps, int fadeTicks, bool stopAfterFade _sound.fade(fadeDest, fadeSteps, fadeTicks, stopAfterFadeFlag); } +void ASound::fadeSound(int soundNum) { + play(soundNum, NULL, 0); + fade(127, 5, 1, false, NULL); +} + +/*--------------------------------------------------------------------------*/ + +ASoundExt::ASoundExt(): ASound() { + _soundNum = 0; +} + +void ASoundExt::synchronize(Serializer &s) { + ASound::synchronize(s); + s.syncAsSint16LE(_soundNum); +} + +void ASoundExt::signal() { + if (_soundNum != 0) { + fadeSound(_soundNum); + } +} + +void ASoundExt::fadeOut2(Action *action) { + fade(0, 10, 10, true, action); +} /*--------------------------------------------------------------------------*/ @@ -2488,7 +2540,12 @@ AdlibSoundDriver::AdlibSoundDriver(): SoundDriver() { _opl = OPL::Config::create(); assert(_opl); _opl->init(_sampleRate); - + + _samplesTillCallback = 0; + _samplesTillCallbackRemainder = 0; + _samplesPerCallback = getRate() / CALLBACKS_PER_SECOND; + _samplesPerCallbackRemainder = getRate() % CALLBACKS_PER_SECOND; + _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true); Common::set_to(_channelVoiced, _channelVoiced + ADLIB_CHANNEL_COUNT, false); @@ -2558,7 +2615,7 @@ int AdlibSoundDriver::setMasterVolume(int volume) { return oldVolume; } -void AdlibSoundDriver::proc32(Sound *sound, int channel, int program, int v0, int v1) { +void AdlibSoundDriver::playSound(const byte *channelData, int dataOffset, int program, int channel, int v0, int v1) { if (program == -1) return; @@ -2750,34 +2807,38 @@ void AdlibSoundDriver::setFrequency(int channel) { } int AdlibSoundDriver::readBuffer(int16 *buffer, const int numSamples) { - update(buffer, numSamples); - return numSamples; -} - -void AdlibSoundDriver::update(int16 *buf, int len) { - static int samplesLeft = 0; - while (len != 0) { - int count = samplesLeft; - if (count > len) { - count = len; - } - samplesLeft -= count; - len -= count; - _opl->readBuffer(buf, count); - if (samplesLeft == 0) { + Common::StackLock slock1(SoundManager::sfManager()._serverDisabledMutex); + Common::StackLock slock2(SoundManager::sfManager()._serverSuspendedMutex); + + int32 samplesLeft = numSamples; + memset(buffer, 0, sizeof(int16) * numSamples); + while (samplesLeft) { + if (!_samplesTillCallback) { + SoundManager::_sfUpdateCallback(NULL); flush(); - samplesLeft = _sampleRate / 50; + + _samplesTillCallback = _samplesPerCallback; + _samplesTillCallbackRemainder += _samplesPerCallbackRemainder; + if (_samplesTillCallbackRemainder >= CALLBACKS_PER_SECOND) { + _samplesTillCallback++; + _samplesTillCallbackRemainder -= CALLBACKS_PER_SECOND; + } } - buf += count; + + int32 render = MIN<int>(samplesLeft, _samplesTillCallback); + samplesLeft -= render; + _samplesTillCallback -= render; + + _opl->readBuffer(buffer, render); + buffer += render; } + return numSamples; } /*--------------------------------------------------------------------------*/ -const byte adlibFx_group_data[] = { 3, 1, 1, 0, 0xff }; - -AdlibFxSoundDriver::AdlibFxSoundDriver(): SoundDriver() { +SoundBlasterDriver::SoundBlasterDriver(): SoundDriver() { _minVersion = 0x102; _maxVersion = 0x10A; _masterVolume = 0; @@ -2785,167 +2846,99 @@ AdlibFxSoundDriver::AdlibFxSoundDriver(): SoundDriver() { _groupData.groupMask = 1; _groupData.v1 = 0x3E; _groupData.v2 = 0; - _groupData.pData = &adlib_group_data[0]; + static byte const group_data[] = { 3, 1, 1, 0, 0xff }; + _groupData.pData = group_data; _mixer = _vm->_mixer; _sampleRate = _mixer->getOutputRate(); - _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true); -/* - Common::set_to(_channelVoiced, _channelVoiced + ADLIB_CHANNEL_COUNT, false); - memset(_channelVolume, 0, ADLIB_CHANNEL_COUNT * sizeof(int)); - memset(_v4405E, 0, ADLIB_CHANNEL_COUNT * sizeof(int)); - memset(_v44067, 0, ADLIB_CHANNEL_COUNT * sizeof(int)); - memset(_v44070, 0, ADLIB_CHANNEL_COUNT * sizeof(int)); - memset(_v44079, 0, ADLIB_CHANNEL_COUNT * sizeof(int)); - memset(_v44082, 0, ADLIB_CHANNEL_COUNT * sizeof(int)); - _v44082[ADLIB_CHANNEL_COUNT] = 0x90; - Common::set_to(_pitchBlend, _pitchBlend + ADLIB_CHANNEL_COUNT, 0x2000); - memset(_v4409E, 0, ADLIB_CHANNEL_COUNT * sizeof(int)); - _patchData = NULL; -*/ + _audioStream = NULL; + _channelData = NULL; } -AdlibFxSoundDriver::~AdlibFxSoundDriver() { +SoundBlasterDriver::~SoundBlasterDriver() { _mixer->stopHandle(_soundHandle); } -bool AdlibFxSoundDriver::open() { - write209(); - write(64); - write(165); - - // for (int idx = 0; idx < 5000 * 16; ++idx) al = port[21h] - -// _v45071 = 1; -// _v4506F = 0; - +bool SoundBlasterDriver::open() { return true; } -void AdlibFxSoundDriver::close() { - write(208); - write211(); - +void SoundBlasterDriver::close() { } -bool AdlibFxSoundDriver::reset() { - +bool SoundBlasterDriver::reset() { return true; } -const GroupData *AdlibFxSoundDriver::getGroupData() { +const GroupData *SoundBlasterDriver::getGroupData() { return &_groupData; } -void AdlibFxSoundDriver::poll() { - if (!_masterVolume || !_channelVolume) { - if (_v45046) - write211(); - } else { - if (!_v45046) - write209(); - } -} - -int AdlibFxSoundDriver::setMasterVolume(int volume) { +int SoundBlasterDriver::setMasterVolume(int volume) { int oldVolume = _masterVolume; _masterVolume = volume; return oldVolume; } -void AdlibFxSoundDriver::proc32(Sound *sound, int channel, int program, int v0, int v1) { - if (program == -1) +void SoundBlasterDriver::playSound(const byte *channelData, int dataOffset, int program, int channel, int v0, int v1) { + if (program != -1) return; - if (_sound) + assert(channel == 0); + + // If sound data has been previously set, then release it + if (_channelData) updateVoice(channel); - // TODO: Stuff + // Set the new channel data + _channelData = channelData + dataOffset; + // Make a copy of the buffer + int dataSize = _vm->_memoryManager.getSize(channelData); + byte *soundData = (byte *)malloc(dataSize - dataOffset); + Common::copy(_channelData, _channelData + (dataSize - dataOffset), soundData); + _audioStream = Audio::makeQueuingAudioStream(11025, false); + _audioStream->queueBuffer(soundData, dataSize - dataOffset, DisposeAfterUse::YES, Audio::FLAG_UNSIGNED); + // Start the new sound + if (!_mixer->isSoundHandleActive(_soundHandle)) + _mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle, _audioStream); } -void AdlibFxSoundDriver::updateVoice(int channel) { - if (_sound) { - write(208); +void SoundBlasterDriver::updateVoice(int channel) { + // Stop the playing voice + if (_mixer->isSoundHandleActive(_soundHandle)) + _mixer->stopHandle(_soundHandle); - _sound = NULL; - _v45062 = 0; - _v45066 = 0; - _v45068 = 0; - } + _audioStream = NULL; + _channelData = NULL; } -void AdlibFxSoundDriver::proc38(int channel, int cmd, int value) { +void SoundBlasterDriver::proc38(int channel, int cmd, int value) { if (cmd == 7) { // Set channel volume _channelVolume = value; + _mixer->setChannelVolume(_soundHandle, (byte)MIN(255, value * 2)); } } -void AdlibFxSoundDriver::proc42(int channel, int cmd, int value, int *v1, int *v2) { - _v4506A = value; - *v1 = _v4506B; +void SoundBlasterDriver::proc42(int channel, int cmd, int value, int *v1, int *v2) { + // TODO: v2 is used for flagging a reset of the timer. I'm not sure if it's needed + *v1 = 0; *v2 = 0; - _v4506B = 0; - - if (!_sound) - *v2 = 1; -} - -void AdlibFxSoundDriver::write(int v) { - /* - port[adlib_port + 12] = v; - for (int i = 0; i < 100; ++i) { - if (!port[adlib_port + 12] & 0x80) - break; - } - */ -} - -void AdlibFxSoundDriver::flush() { - Common::StackLock slock(SoundManager::sfManager()._serverDisabledMutex); - - // No data output yet -} - - -int AdlibFxSoundDriver::readBuffer(int16 *buffer, const int numSamples) { - update(buffer, numSamples); - return numSamples; -} - -void AdlibFxSoundDriver::update(int16 *buf, int len) { -/* - static int samplesLeft = 0; - while (len != 0) { - int count = samplesLeft; - if (count > len) { - count = len; - } - samplesLeft -= count; - len -= count; - YM3812UpdateOne(_opl, buf, count); - if (samplesLeft == 0) { - flush(); - samplesLeft = _sampleRate / 50; - } - buf += count; + // Note: Checking whether a playing Fx sound had finished was originally done in another + // method in the sample playing code. But since we're using the ScummVM audio soundsystem, + // it's easier simply to do the check right here + if (_audioStream && (_audioStream->numQueuedStreams() == 0)) { + updateVoice(channel); } -*/ -} - -void AdlibFxSoundDriver::write209() { - write(209); - _v45046 = true; -} -void AdlibFxSoundDriver::write211() { - write(211); - _v45046 = false; + if (!_channelData) + // Flag that sound isn't playing + *v1 = 1; } -} // End of namespace tSage +} // End of namespace TsAGE diff --git a/engines/tsage/sound.h b/engines/tsage/sound.h index 6a47a1aaf5..afcc8f6377 100644 --- a/engines/tsage/sound.h +++ b/engines/tsage/sound.h @@ -33,7 +33,7 @@ #include "tsage/saveload.h" #include "tsage/core.h" -namespace tSage { +namespace TsAGE { class Sound; @@ -41,6 +41,7 @@ class Sound; #define ROLAND_DRIVER_NUM 2 #define ADLIB_DRIVER_NUM 3 #define SBLASTER_DRIVER_NUM 4 +#define CALLBACKS_PER_SECOND 60 struct trackInfoStruct { int _numTracks; @@ -107,7 +108,7 @@ public: virtual void setProgram(int channel, int program) {} // Method #13 virtual void setVolume1(int channel, int v2, int v3, int volume) {} virtual void setPitchBlend(int channel, int pitchBlend) {} // Method #15 - virtual void proc32(Sound *sound, int channel, int program, int v0, int v1) {}// Method #16 + virtual void playSound(const byte *channelData, int dataOffset, int program, int channel, int v0, int v1) {}// Method #16 virtual void updateVoice(int channel) {} // Method #17 virtual void proc36() {} // Method #18 virtual void proc38(int channel, int cmd, int value) {} // Method #19 @@ -224,6 +225,7 @@ public: int getMasterVol() const; void loadSound(int soundNum, bool showErrors); void unloadSound(int soundNum); + bool isFading(); // _sf methods static SoundManager &sfManager(); @@ -348,8 +350,8 @@ public: void _soRemoteReceive(); void _soServiceTrackType0(int trackIndex, const byte *channelData); void _soUpdateDamper(VoiceTypeStruct *voiceType, int channelNum, VoiceType mode, int v0); - void _soProc32(VoiceTypeStruct *vtStruct, int channelNum, VoiceType voiceType, int v0, int v1); - void _soProc42(VoiceTypeStruct *vtStruct, int channelNum, VoiceType voiceType, int v0); + void _soPlaySound(VoiceTypeStruct *vtStruct, const byte *channelData, int channelNum, VoiceType voiceType, int v0, int v1); + void _soPlaySound2(VoiceTypeStruct *vtStruct, const byte *channelData, int channelNum, VoiceType voiceType, int v0); void _soProc38(VoiceTypeStruct *vtStruct, int channelNum, VoiceType voiceType, int cmd, int value); void _soProc40(VoiceTypeStruct *vtStruct, int channelNum, int pitchBlend); void _soDoTrackCommand(int channelNum, int command, int value); @@ -396,8 +398,22 @@ public: int getVol() const { return _sound.getVol(); } void holdAt(int v) { _sound.holdAt(v); } void release() { _sound.release(); } + void fadeSound(int soundNum); }; +class ASoundExt: public ASound { +public: + int _soundNum; + + ASoundExt(); + void fadeOut2(Action *action); + + virtual Common::String getClassName() { return "ASoundExt"; } + virtual void synchronize(Serializer &s); + virtual void signal(); +}; + + #define ADLIB_CHANNEL_COUNT 9 class AdlibSoundDriver: public SoundDriver, Audio::AudioStream { @@ -411,6 +427,10 @@ private: const byte *_patchData; int _masterVolume; Common::Queue<RegisterValue> _queue; + int _samplesTillCallback; + int _samplesTillCallbackRemainder; + int _samplesPerCallback; + int _samplesPerCallbackRemainder; bool _channelVoiced[ADLIB_CHANNEL_COUNT]; int _channelVolume[ADLIB_CHANNEL_COUNT]; @@ -440,7 +460,7 @@ public: virtual const GroupData *getGroupData(); virtual void installPatch(const byte *data, int size); virtual int setMasterVolume(int volume); - virtual void proc32(Sound *sound, int channel, int program, int v0, int v1); + virtual void playSound(const byte *channelData, int dataOffset, int program, int channel, int v0, int v1); virtual void updateVoice(int channel); virtual void proc38(int channel, int cmd, int value); virtual void setPitch(int channel, int pitchBlend); @@ -454,54 +474,33 @@ public: void update(int16 *buf, int len); }; -class AdlibFxSoundDriver: public SoundDriver, Audio::AudioStream { +class SoundBlasterDriver: public SoundDriver { private: - Common::Queue<RegisterValue> _queue; GroupData _groupData; Audio::Mixer *_mixer; Audio::SoundHandle _soundHandle; + Audio::QueuingAudioStream *_audioStream; int _sampleRate; - int _v45062; - int _v45066; - int _v45068; - int _v4506A; - int _v4506B; - bool _v45046; byte _masterVolume; byte _channelVolume; - Sound *_sound; - - void write(int v); - void flush(); - void sub_4556E(); - void write209(); - void write211(); + const byte *_channelData; public: - AdlibFxSoundDriver(); - virtual ~AdlibFxSoundDriver(); + SoundBlasterDriver(); + virtual ~SoundBlasterDriver(); virtual bool open(); virtual void close(); virtual bool reset(); virtual const GroupData *getGroupData(); - virtual void poll(); virtual int setMasterVolume(int volume); - virtual void proc32(Sound *sound, int channel, int program, int v0, int v1); + virtual void playSound(const byte *channelData, int dataOffset, int program, int channel, int v0, int v1); virtual void updateVoice(int channel); virtual void proc38(int channel, int cmd, int value); virtual void proc42(int channel, int cmd, int value, int *v1, int *v2); - - // AudioStream interface - virtual int readBuffer(int16 *buffer, const int numSamples); - virtual bool isStereo() const { return false; } - virtual bool endOfData() const { return false; } - virtual int getRate() const { return _sampleRate; } - - void update(int16 *buf, int len); }; -} // End of namespace tSage +} // End of namespace TsAGE #endif diff --git a/engines/tsage/staticres.cpp b/engines/tsage/staticres.cpp index 9f36268ce3..819cf56f31 100644 --- a/engines/tsage/staticres.cpp +++ b/engines/tsage/staticres.cpp @@ -22,7 +22,7 @@ #include "tsage/staticres.h" -namespace tSage { +namespace TsAGE { const byte CURSOR_ARROW_DATA[] = { 15, 0, 15, 0, 0, 0, 0, 0, 9, 0, @@ -73,7 +73,6 @@ const char *SAVE_ERROR_MSG = "Error occurred saving game. Please do not try to r const char *SAVING_NOT_ALLOWED_MSG = "Saving is not allowed at this time."; const char *RESTORING_NOT_ALLOWED_MSG = "Restoring is not allowed at this time."; const char *RESTART_CONFIRM_MSG = "Do you want to restart your game?"; -const char *WATCH_INTRO_MSG = "Do you wish to watch the introduction?"; const char *INV_EMPTY_MSG = "You have nothing in your possesion."; const char *HELP_MSG = "Ringworld\rRevenge of the Patriarch\x14\rScummVM Version\r\r\ @@ -93,9 +92,16 @@ const char *SOUND_BTN_STRING = "Sound"; const char *RESUME_BTN_STRING = " Resume \rplay"; const char *LOOK_BTN_STRING = "Look"; const char *PICK_BTN_STRING = "Pick"; + + +namespace Ringworld { + +// Dialog resources +const char *WATCH_INTRO_MSG = "Do you wish to watch the introduction?"; const char *START_PLAY_BTN_STRING = " Start Play "; const char *INTRODUCTION_BTN_STRING = "Introduction"; +// Scene specific resources const char *EXIT_MSG = " EXIT "; const char *SCENE6100_CAREFUL = "Be careful! The probe cannot handle too much of that."; const char *SCENE6100_TOUGHER = "Hey! This is tougher than it looks!"; @@ -118,4 +124,37 @@ const char *EXIT_BTN_STRING = "Exit"; const char *DEMO_BTN_STRING = "Demo"; const char *DEMO_RESUME_BTN_STRING = "Resume"; -} // End of namespace tSage +} // End of namespace Ringworld + +namespace BlueForce { + +// Dialog resources +const char *WATCH_INTRO_MSG = "Do you wish to watch the introduction?"; +const char *START_PLAY_BTN_STRING = " Play "; +const char *INTRODUCTION_BTN_STRING = " Watch "; + +// Blue Force general messages +const char *BF_NAME = "Blue Force"; +const char *BF_COPYRIGHT = " Copyright, 1993 Tsunami Media, Inc."; +const char *BF_ALL_RIGHTS_RESERVED = "All Rights Reserved"; +const char *BF_19840518 = "May 18, 1984"; +const char *BF_19840515 = "May 15, 1984"; +const char *BF_3_DAYS = "Three days later"; +const char *BF_11_YEARS = "Eleven years later."; +const char *BF_NEXT_DAY = "The Next Day"; +const char *BF_ACADEMY = "Here we are at the Academy"; + +// Scene 50 hotspots +const char *GRANDMA_FRANNIE = "Grandma Frannie"; +const char *MARINA = "Marina"; +const char *POLICE_DEPARTMENT = "Police Department"; +const char *TONYS_BAR = "Tony's Bar"; +const char *CHILD_PROTECTIVE_SERVICES = "Child Protective Services"; +const char *ALLEY_CAT = "Alley Cat"; +const char *CITY_HALL_JAIL = "City Hall & Jail"; +const char *JAMISON_RYAN = "Jamison & Ryan"; +const char *BIKINI_HUT = "Bikini Hut"; + +} // End of namespace BlueForce + +} // End of namespace TsAGE diff --git a/engines/tsage/staticres.h b/engines/tsage/staticres.h index fa93511779..b08e92def2 100644 --- a/engines/tsage/staticres.h +++ b/engines/tsage/staticres.h @@ -25,7 +25,7 @@ #include "common/scummsys.h" -namespace tSage { +namespace TsAGE { extern const byte CURSOR_ARROW_DATA[]; @@ -40,7 +40,6 @@ extern const char *SAVE_ERROR_MSG; extern const char *SAVING_NOT_ALLOWED_MSG; extern const char *RESTORING_NOT_ALLOWED_MSG; extern const char *RESTART_CONFIRM_MSG; -extern const char *WATCH_INTRO_MSG; // Dialogs extern const char *HELP_MSG; @@ -59,6 +58,11 @@ extern const char *RESUME_BTN_STRING; extern const char *LOOK_BTN_STRING; extern const char *PICK_BTN_STRING; extern const char *INV_EMPTY_MSG; + +namespace Ringworld { + +// Dialog resources +extern const char *WATCH_INTRO_MSG; extern const char *START_PLAY_BTN_STRING; extern const char *INTRODUCTION_BTN_STRING; @@ -86,6 +90,39 @@ extern const char *EXIT_BTN_STRING; extern const char *DEMO_BTN_STRING; extern const char *DEMO_RESUME_BTN_STRING; -} // End of namespace tSage +} // End of namespace Ringworld + +namespace BlueForce { + +// Dialog resources +extern const char *WATCH_INTRO_MSG; +extern const char *START_PLAY_BTN_STRING; +extern const char *INTRODUCTION_BTN_STRING; + +// Blue Force messages +extern const char *BF_NAME; +extern const char *BF_COPYRIGHT; +extern const char *BF_ALL_RIGHTS_RESERVED; +extern const char *BF_19840518; +extern const char *BF_19840515; +extern const char *BF_3_DAYS; +extern const char *BF_11_YEARS; +extern const char *BF_NEXT_DAY; +extern const char *BF_ACADEMY; + +// Scene 50 tooltips +extern const char *GRANDMA_FRANNIE; +extern const char *MARINA; +extern const char *POLICE_DEPARTMENT; +extern const char *TONYS_BAR; +extern const char *CHILD_PROTECTIVE_SERVICES; +extern const char *ALLEY_CAT; +extern const char *CITY_HALL_JAIL; +extern const char *JAMISON_RYAN; +extern const char *BIKINI_HUT; + +} // End of namespace BlueForce + +} // End of namespace TsAGE #endif diff --git a/engines/tsage/tsage.cpp b/engines/tsage/tsage.cpp index 41f3d58897..2fcabff16c 100644 --- a/engines/tsage/tsage.cpp +++ b/engines/tsage/tsage.cpp @@ -30,7 +30,7 @@ #include "tsage/resources.h" #include "tsage/globals.h" -namespace tSage { +namespace TsAGE { TSageEngine *_vm = NULL; @@ -68,18 +68,22 @@ void TSageEngine::initialize() { if (_vm->getFeatures() & GF_DEMO) { // Add the single library file associated with the demo _resourceManager->addLib(getPrimaryFilename()); + _globals = new Globals(); + } else if (_vm->getGameID() == GType_Ringworld) { _resourceManager->addLib("RING.RLB"); _resourceManager->addLib("TSAGE.RLB"); + _globals = new Globals(); + } else if (_vm->getGameID() == GType_BlueForce) { _resourceManager->addLib("BLUE.RLB"); if (_vm->getFeatures() & GF_FLOPPY) { _resourceManager->addLib("FILES.RLB"); _resourceManager->addLib("TSAGE.RLB"); } + _globals = new BlueForce::BlueForceGlobals(); } - _globals = new Globals(); _globals->gfxManager().setDefaults(); // Setup sound settings @@ -98,7 +102,7 @@ Common::Error TSageEngine::run() { // Basic initialisation initialize(); - _globals->_sceneHandler.registerHandler(); + _globals->_sceneHandler->registerHandler(); _globals->_game->execute(); deinitialize(); @@ -147,4 +151,8 @@ void TSageEngine::syncSoundSettings() { _globals->_soundManager.syncSounds(); } -} // End of namespace tSage +bool TSageEngine::shouldQuit() { + return getEventManager()->shouldQuit() || getEventManager()->shouldRTL(); +} + +} // End of namespace TsAGE diff --git a/engines/tsage/tsage.h b/engines/tsage/tsage.h index f004c7f625..88175f92ce 100644 --- a/engines/tsage/tsage.h +++ b/engines/tsage/tsage.h @@ -36,7 +36,7 @@ #include "tsage/resources.h" -namespace tSage { +namespace TsAGE { enum { GType_Ringworld = 0, @@ -78,6 +78,7 @@ public: uint32 getGameID() const; uint32 getFeatures() const; Common::String getPrimaryFilename() const; + bool shouldQuit(); virtual Common::Error init(); virtual Common::Error run(); @@ -98,6 +99,6 @@ extern TSageEngine *_vm; #define ALLOCATE(x) _vm->_memoryManager.allocate2(x) #define DEALLOCATE(x) _vm->_memoryManager.deallocate(x) -} // End of namespace tSage +} // End of namespace TsAGE #endif |