aboutsummaryrefslogtreecommitdiff
path: root/engines/tsage
diff options
context:
space:
mode:
Diffstat (limited to 'engines/tsage')
-rw-r--r--engines/tsage/blue_force/blueforce_logic.cpp448
-rw-r--r--engines/tsage/blue_force/blueforce_logic.h175
-rw-r--r--engines/tsage/blue_force/blueforce_scenes1.h3
-rw-r--r--engines/tsage/blue_force/blueforce_scenes3.cpp602
-rw-r--r--engines/tsage/blue_force/blueforce_scenes3.h137
-rw-r--r--engines/tsage/blue_force/blueforce_ui.cpp366
-rw-r--r--engines/tsage/blue_force/blueforce_ui.h135
-rw-r--r--engines/tsage/core.cpp108
-rw-r--r--engines/tsage/core.h50
-rw-r--r--engines/tsage/events.cpp15
-rw-r--r--engines/tsage/events.h5
-rw-r--r--engines/tsage/globals.cpp8
-rw-r--r--engines/tsage/globals.h3
-rw-r--r--engines/tsage/module.mk2
-rw-r--r--engines/tsage/ringworld/ringworld_logic.h24
-rw-r--r--engines/tsage/saveload.h12
-rw-r--r--engines/tsage/sound.cpp13
-rw-r--r--engines/tsage/sound.h7
-rw-r--r--engines/tsage/tsage.h1
19 files changed, 2034 insertions, 80 deletions
diff --git a/engines/tsage/blue_force/blueforce_logic.cpp b/engines/tsage/blue_force/blueforce_logic.cpp
index 46c9307632..60bbddbabc 100644
--- a/engines/tsage/blue_force/blueforce_logic.cpp
+++ b/engines/tsage/blue_force/blueforce_logic.cpp
@@ -23,8 +23,10 @@
#include "tsage/blue_force/blueforce_logic.h"
#include "tsage/blue_force/blueforce_scenes0.h"
#include "tsage/blue_force/blueforce_scenes1.h"
+#include "tsage/blue_force/blueforce_scenes3.h"
#include "tsage/scenes.h"
#include "tsage/tsage.h"
+#include "tsage/graphics.h"
#include "tsage/staticres.h"
namespace TsAGE {
@@ -33,7 +35,7 @@ namespace BlueForce {
void BlueForceGame::start() {
// Start the game
- _globals->_sceneManager.changeScene(50);
+ _globals->_sceneManager.changeScene(300);
_globals->_events.setCursor(CURSOR_WALK);
}
@@ -76,6 +78,8 @@ Scene *BlueForceGame::createScene(int sceneNumber) {
case 280:
error("Scene group 2 not implemented");
case 300:
+ // Outside Police Station
+ return new Scene300();
case 315:
case 325:
case 330:
@@ -212,6 +216,13 @@ void Timer::remove() {
((Scene100 *)BF_GLOBALS._sceneManager._scene)->removeTimer(this);
}
+void Timer::synchronize(Serializer &s) {
+ EventHandler::synchronize(s);
+ SYNC_POINTER(_tickAction);
+ SYNC_POINTER(_endAction);
+ s.syncAsUint32LE(_endFrame);
+}
+
void Timer::signal() {
assert(_endAction);
Action *action = _endAction;
@@ -231,24 +242,49 @@ void Timer::dispatch() {
}
}
-void Timer::set(uint32 delay, Action *action) {
+void Timer::set(uint32 delay, Action *endAction) {
assert(delay != 0);
_endFrame = BF_GLOBALS._sceneHandler->getFrameDifference() + delay;
- _endAction = action;
+ _endAction = endAction;
((SceneExt *)BF_GLOBALS._sceneManager._scene)->addTimer(this);
}
/*--------------------------------------------------------------------------*/
-void SceneItemType1::process(Event &event) {
- if (_action)
- _action->process(event);
+TimerExt::TimerExt(): Timer() {
+ _action = NULL;
+}
+
+void TimerExt::set(uint32 delay, Action *endAction, Action *newAction) {
+ _newAction = newAction;
+ Timer::set(delay, endAction);
+}
+
+void TimerExt::synchronize(Serializer &s) {
+ EventHandler::synchronize(s);
+ SYNC_POINTER(_action);
}
-void SceneItemType1::startMove(SceneObject *sceneObj, va_list va) {
- warning("TODO: sub_1621C");
+void TimerExt::remove() {
+ _action = NULL;
+ remove();
+}
+
+void TimerExt::signal() {
+ Action *endAction = _endAction;
+ Action *newAction = _newAction;
+ remove();
+
+ // If the end action doesn't have an action anymore, set it to the specified new action
+ assert(endAction);
+ if (!endAction->_action)
+ endAction->setAction(newAction);
+}
+
+void TimerExt::dispatch() {
+
}
/*--------------------------------------------------------------------------*/
@@ -258,12 +294,130 @@ void SceneItemType2::startMove(SceneObject *sceneObj, va_list va) {
/*--------------------------------------------------------------------------*/
+void NamedObject::postInit(SceneObjectList *OwnerList) {
+ _lookLineNum = _talkLineNum = _useLineNum = -1;
+ SceneObject::postInit();
+}
+
+void NamedObject::synchronize(Serializer &s) {
+ SceneObject::synchronize(s);
+ s.syncAsSint16LE(_resNum);
+ s.syncAsSint16LE(_lookLineNum);
+ s.syncAsSint16LE(_talkLineNum);
+ s.syncAsSint16LE(_useLineNum);
+}
+
+void NamedObject::setup(int resNum, int lookLineNum, int talkLineNum, int useLineNum, int mode, SceneItem *item) {
+ _resNum = resNum;
+ _lookLineNum = lookLineNum;
+ _talkLineNum = talkLineNum;
+ _useLineNum = useLineNum;
+
+ switch (mode) {
+ case 2:
+ _globals->_sceneItems.push_front(this);
+ break;
+ case 4:
+ _globals->_sceneItems.addBefore(item, this);
+ break;
+ case 5:
+ _globals->_sceneItems.addAfter(item, this);
+ break;
+ default:
+ _globals->_sceneItems.push_back(this);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+CountdownObject::CountdownObject(): NamedObject() {
+ _countDown = 0;
+}
+
+void CountdownObject::synchronize(Serializer &s) {
+ SceneObject::synchronize(s);
+ s.syncAsSint16LE(_countDown);
+}
+
+void CountdownObject::dispatch() {
+ int frameNum = _frame;
+ SceneObject::dispatch();
+
+ if ((frameNum != _frame) && (_countDown > 0)) {
+ if (--_countDown == 0) {
+ animate(ANIM_MODE_NONE, 0);
+ _frame = 1;
+ }
+ }
+}
+
+void CountdownObject::fixCountdown(int mode, ...) {
+ if (mode == 8) {
+ va_list va;
+ va_start(va, mode);
+
+ _countDown = va_arg(va, int);
+ animate(ANIM_MODE_8, _countDown, NULL);
+ va_end(va);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+FollowerObject::FollowerObject(): NamedObject() {
+ _object = NULL;
+}
+
+void FollowerObject::synchronize(Serializer &s) {
+ NamedObject::synchronize(s);
+ SYNC_POINTER(_object);
+}
+
+void FollowerObject::remove() {
+ NamedObject::remove();
+ _object = NULL;
+}
+
+void FollowerObject::dispatch() {
+ SceneObject::dispatch();
+ assert(_object);
+
+ if ((_object->_flags & OBJFLAG_HIDE) || ((_object->_visage != 307) &&
+ ((_object->_visage != 308) || (_object->_strip != 1)))) {
+ hide();
+ } else if ((_object->_visage != 308) || (_object->_strip != 1)) {
+ show();
+ setStrip(_object->_strip);
+ setPosition(_object->_position, _object->_yDiff);
+ }
+}
+
+void FollowerObject::reposition() {
+ assert(_object);
+ setStrip(_object->_strip);
+ setPosition(_object->_position, _object->_yDiff);
+ reposition();
+}
+
+void FollowerObject::setup(SceneObject *object, int visage, int frameNum, int yDiff) {
+ SceneObject::postInit();
+ _object = object;
+ _yDiff = yDiff;
+ setVisage(visage);
+ setFrame(frameNum);
+
+ dispatch();
+}
+
+/*--------------------------------------------------------------------------*/
+
SceneExt::SceneExt(): Scene() {
warning("TODO: dword_503AA/dword_503AE/dword_53030");
_field372 = 0;
_field37A = 0;
- _field37C = NULL;
+ _eventHandler = NULL;
}
void SceneExt::postInit(SceneObjectList *OwnerList) {
@@ -350,6 +504,282 @@ void SceneHandlerExt::process(Event &event) {
// TODO: All the new stuff from Blue Force
}
+/*--------------------------------------------------------------------------*/
+
+VisualSpeaker::VisualSpeaker(): Speaker() {
+ _textWidth = 312;
+ _color1 = 19;
+ _hideObjects = false;
+ _removeObject1 = false;
+ _removeObject2 = false;
+ _field20E = 160;
+ _fontNumber = 4;
+ _color2 = 82;
+ _offsetPos = Common::Point(4, 170);
+ _numFrames = 0;
+}
+
+void VisualSpeaker::remove() {
+ if (_removeObject2)
+ _object2.remove();
+ if (_removeObject1)
+ _object1.remove();
+
+ Speaker::remove();
+}
+
+void VisualSpeaker::synchronize(Serializer &s) {
+ Speaker::synchronize(s);
+
+ s.syncAsByte(_removeObject1);
+ s.syncAsByte(_removeObject2);
+ s.syncAsSint16LE(_field20C);
+ s.syncAsSint16LE(_field20E);
+ s.syncAsSint16LE(_numFrames);
+ s.syncAsSint16LE(_offsetPos.x);
+ s.syncAsSint16LE(_offsetPos.y);
+}
+
+void VisualSpeaker::proc12(Action *action) {
+ Speaker::proc12(action);
+ _textPos = Common::Point(_offsetPos.x + BF_GLOBALS._sceneManager._scene->_sceneBounds.left,
+ _offsetPos.y + BF_GLOBALS._sceneManager._scene->_sceneBounds.top);
+ _numFrames = 0;
+}
+
+void VisualSpeaker::setText(const Common::String &msg) {
+ BF_GLOBALS._events.waitForPress();
+ _objectList.draw();
+
+ _sceneText._color1 = _color1;
+ _sceneText._color2 = _color2;
+ _sceneText._color3 = _color3;
+ _sceneText._width = _textWidth;
+ _sceneText._fontNumber = _fontNumber;
+ _sceneText._textMode = _textMode;
+ _sceneText.setup(msg);
+
+ // Get the string bounds
+ GfxFont f;
+ f.setFontNumber(_fontNumber);
+ Rect bounds;
+ f.getStringBounds(msg.c_str(), bounds, _textWidth);
+
+ // Set the position for the text
+ switch (_textMode) {
+ case ALIGN_LEFT:
+ case ALIGN_JUSTIFIED:
+ _sceneText.setPosition(_textPos);
+ break;
+ case ALIGN_CENTER:
+ _sceneText.setPosition(Common::Point(_textPos.x + (_textWidth - bounds.width()) / 2, _textPos.y));
+ break;
+ case ALIGN_RIGHT:
+ _sceneText.setPosition(Common::Point(_textPos.x + _textWidth - bounds.width(), _textPos.y));
+ break;
+ default:
+ break;
+ }
+
+ // Ensure the text is in the foreground
+ _sceneText.fixPriority(256);
+
+ // Count the number of words (by spaces) in the string
+ const char *s = msg.c_str();
+ int spaceCount = 0;
+ while (*s) {
+ if (*s++ == ' ')
+ ++spaceCount;
+ }
+
+ _numFrames = spaceCount * 3 + 2;
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerSutter::SpeakerSutter() {
+ _speakerName = "SUTTER";
+ _color1 = 20;
+ _color2 = 22;
+ _textMode = ALIGN_CENTER;
+}
+
+void SpeakerSutter::setText(const Common::String &msg) {
+ _removeObject1 = _removeObject2 = true;
+
+ _object1.postInit();
+ _object1.setVisage(329);
+ _object1.setStrip2(2);
+ _object1.fixPriority(254);
+ _object1.changeZoom(100);
+ _object1.setPosition(Common::Point(BF_GLOBALS._sceneManager._scene->_sceneBounds.left + 45,
+ BF_GLOBALS._sceneManager._scene->_sceneBounds.top + 166));
+
+ _object2.postInit();
+ _object2.setVisage(329);
+ _object2.setStrip2(1);
+ _object2.fixPriority(255);
+ _object1.setPosition(Common::Point(BF_GLOBALS._sceneManager._scene->_sceneBounds.left + 45,
+ BF_GLOBALS._sceneManager._scene->_sceneBounds.top + 166));
+
+ VisualSpeaker::setText(msg);
+ _object2.fixCountdown(8, _numFrames);
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerDoug::SpeakerDoug(): VisualSpeaker() {
+ _color1 = 32;
+ _speakerName = "DOUG";
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerJakeNoHead::SpeakerJakeNoHead(): VisualSpeaker() {
+ _color1 = 13;
+ _speakerName = "JAKE_NO_HEAD";
+}
+
+/*--------------------------------------------------------------------------*/
+
+BlueForceInvObjectList::BlueForceInvObjectList():
+ _business_card(9, 4, 2, 0),
+ _lauras_sweater(9, 4, 3, 0),
+ _handcuffs(9, 1, 4, 0),
+ _magnum(9, 1, 5, 0),
+ _ticket_book(9, 1, 6, 0),
+ _miranda_card(9, 1, 7, 0),
+ _forest_follet(9, 1, 8, 0),
+ _bradford_id(9, 1, 9, 0),
+ _baseball_card(9, 1, 10, 0),
+ _slip_bradford(9, 1, 11, 0),
+ _flare(9, 1, 12, 0),
+ _rap_sheet(9, 1, 13, 0),
+ _cartridges(9, 1, 14, 0),
+ _rifle(9, 1, 15, 0),
+ _wig(9, 1, 16, 0),
+ _frankies_id(9, 1, 17, 0),
+ _tyrones_id(9, 1, 18, 0),
+ _pistol22(9, 1, 19, 0),
+ _unused(1, 1, 1, 0),
+ _slip_frankie(9, 2, 1, 0),
+ _slip_tyrone(9, 2, 2, 0),
+ _atf_teletype(9, 2, 3, 0),
+ _da_note(9, 2, 4, 0),
+ _blueprints(9, 2, 5, 0),
+ _planter_key(9, 2, 6, 0),
+ _center_punch(9, 2, 7, 0),
+ _tranquilizer(9, 2, 8, 0),
+ _boat_hook(9, 2, 9, 0),
+ _oily_rags(9, 2, 10, 0),
+ _fuel_jar(9, 2, 11, 0),
+ _screwdriver(9, 2, 12, 0),
+ _floppy_disk1(9, 2, 13, 0),
+ _floppy_disk2(9, 2, 14, 0),
+ _driftwood(9, 2, 15, 0),
+ _crate_piece1(9, 2, 16, 0),
+ _crate_piece2(9, 2, 17, 0),
+ _shoebox(9, 2, 18, 0),
+ _badge(9, 2, 19, 0),
+ _unused2(1, 1, 1, 0),
+ _rental_coupons(9, 3, 1, 0),
+ _nickel(9, 3, 2, 0),
+ _calendar(9, 3, 3, 0),
+ _dixon_note(9, 3, 4, 0),
+ _cobb_mugshot(9, 3, 5, 0),
+ _murder_article(9, 3, 6, 0),
+ _microfiche(9, 3, 7, 0),
+ _future_wave_keys(9, 3, 8, 0),
+ _rental_boat_keys(9, 3, 9, 0),
+ _napkin(9, 3, 10, 0),
+ _cobb_printout(9, 3, 11, 0),
+ _fishing_net(9, 3, 12, 0),
+ _id(9, 3, 13, 0),
+ _rounds_9mm(9, 3, 14, 0),
+ _dates_note(9, 3, 15, 0),
+ _hand_grenade(9, 3, 16, 0),
+ _cord_110(9, 3, 17, 0),
+ _cord_110_plug(9, 3, 18, 0),
+ _cord_220(9, 3, 19, 0),
+ _unused3(1, 1, 1, 0),
+ _cord_220_plug(9, 4, 1, 0),
+ _official_document(9, 4, 2, 0),
+ _red_sweater(9, 4, 3, 0),
+ _jackknife(9, 4, 4, 0),
+ _whistle(9, 4, 5, 0),
+ _gun(9, 1, 2, 0),
+ _alley_cat_key(9, 4, 7, 0) {
+
+ // Add the items to the list
+ _itemList.push_back(&_business_card);
+ _itemList.push_back(&_lauras_sweater);
+ _itemList.push_back(&_handcuffs);
+ _itemList.push_back(&_magnum);
+ _itemList.push_back(&_ticket_book);
+ _itemList.push_back(&_miranda_card);
+ _itemList.push_back(&_forest_follet);
+ _itemList.push_back(&_bradford_id);
+ _itemList.push_back(&_baseball_card);
+ _itemList.push_back(&_slip_bradford);
+ _itemList.push_back(&_flare);
+ _itemList.push_back(&_rap_sheet);
+ _itemList.push_back(&_cartridges);
+ _itemList.push_back(&_rifle);
+ _itemList.push_back(&_wig);
+ _itemList.push_back(&_frankies_id);
+ _itemList.push_back(&_tyrones_id);
+ _itemList.push_back(&_pistol22);
+ _itemList.push_back(&_unused);
+ _itemList.push_back(&_slip_frankie);
+ _itemList.push_back(&_slip_tyrone);
+ _itemList.push_back(&_atf_teletype);
+ _itemList.push_back(&_da_note);
+ _itemList.push_back(&_blueprints);
+ _itemList.push_back(&_planter_key);
+ _itemList.push_back(&_center_punch);
+ _itemList.push_back(&_tranquilizer);
+ _itemList.push_back(&_boat_hook);
+ _itemList.push_back(&_oily_rags);
+ _itemList.push_back(&_fuel_jar);
+ _itemList.push_back(&_screwdriver);
+ _itemList.push_back(&_floppy_disk1);
+ _itemList.push_back(&_floppy_disk2);
+ _itemList.push_back(&_driftwood);
+ _itemList.push_back(&_crate_piece1);
+ _itemList.push_back(&_crate_piece2);
+ _itemList.push_back(&_shoebox);
+ _itemList.push_back(&_badge);
+ _itemList.push_back(&_unused2);
+ _itemList.push_back(&_rental_coupons);
+ _itemList.push_back(&_nickel);
+ _itemList.push_back(&_calendar);
+ _itemList.push_back(&_dixon_note);
+ _itemList.push_back(&_cobb_mugshot);
+ _itemList.push_back(&_murder_article);
+ _itemList.push_back(&_microfiche);
+ _itemList.push_back(&_future_wave_keys);
+ _itemList.push_back(&_rental_boat_keys);
+ _itemList.push_back(&_napkin);
+ _itemList.push_back(&_cobb_printout);
+ _itemList.push_back(&_fishing_net);
+ _itemList.push_back(&_id);
+ _itemList.push_back(&_rounds_9mm);
+ _itemList.push_back(&_dates_note);
+ _itemList.push_back(&_hand_grenade);
+ _itemList.push_back(&_cord_110);
+ _itemList.push_back(&_cord_110_plug);
+ _itemList.push_back(&_cord_220);
+ _itemList.push_back(&_unused3);
+ _itemList.push_back(&_cord_220_plug);
+ _itemList.push_back(&_official_document);
+ _itemList.push_back(&_red_sweater);
+ _itemList.push_back(&_jackknife);
+ _itemList.push_back(&_whistle);
+ _itemList.push_back(&_gun);
+ _itemList.push_back(&_alley_cat_key);
+}
+
+
} // End of namespace BlueForce
} // End of namespace TsAGE
diff --git a/engines/tsage/blue_force/blueforce_logic.h b/engines/tsage/blue_force/blueforce_logic.h
index 9ab8a87a0c..d756d85cb3 100644
--- a/engines/tsage/blue_force/blueforce_logic.h
+++ b/engines/tsage/blue_force/blueforce_logic.h
@@ -29,14 +29,14 @@
#include "tsage/scenes.h"
#include "tsage/globals.h"
-#define BF_INTERFACE_Y 168
-
namespace TsAGE {
namespace BlueForce {
using namespace TsAGE;
+#define BLUE_INVENTORY (*((::TsAGE::BlueForce::BlueForceInvObjectList *)_globals->_inventory))
+
class BlueForceGame: public Game {
public:
virtual void start();
@@ -69,22 +69,69 @@ public:
uint32 _endFrame;
public:
Timer();
- void set(uint32 delay, Action *action);
+ void set(uint32 delay, Action *endAction);
+ virtual Common::String getClassName() { return "Timer"; }
+ virtual void synchronize(Serializer &s);
virtual void remove();
virtual void signal();
virtual void dispatch();
};
-class SceneItemType1: public SceneItem {
+class TimerExt: public Timer {
+public:
+ Action *_newAction;
+public:
+ TimerExt();
+ void set(uint32 delay, Action *endAction, Action *action);
+
+ virtual Common::String getClassName() { return "TimerExt"; }
+ virtual void synchronize(Serializer &s);
+ virtual void remove();
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class SceneItemType2: public SceneHotspot {
public:
- virtual void process(Event &event);
virtual void startMove(SceneObject *sceneObj, va_list va);
};
-class SceneItemType2: public SceneItemType1 {
+class NamedObject: public SceneObject {
public:
- virtual void startMove(SceneObject *sceneObj, va_list va);
+ int _resNum;
+ int _lookLineNum, _talkLineNum, _useLineNum;
+
+ virtual Common::String getClassName() { return "NamedObject"; }
+ virtual void synchronize(Serializer &s);
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+
+ void setup(int resNum, int lookLineNum, int talkLineNum, int useLineNum, int mode, SceneItem *item);
+};
+
+class CountdownObject: public NamedObject {
+public:
+ int _countDown;
+ CountdownObject();
+ void fixCountdown(int mode, ...);
+
+ virtual Common::String getClassName() { return "CountdownObject"; }
+ virtual void synchronize(Serializer &s);
+ virtual void dispatch();
+};
+
+class FollowerObject: public NamedObject {
+public:
+ SceneObject *_object;
+ FollowerObject();
+
+ virtual Common::String getClassName() { return "SceneObjectExt4"; }
+ virtual void synchronize(Serializer &s);
+ virtual void remove();
+ virtual void dispatch();
+ virtual void reposition();
+
+ void setup(SceneObject *object, int visage, int frameNum, int yDiff);
};
class SceneExt: public Scene {
@@ -92,7 +139,7 @@ public:
AObjectArray _timerList, _objArray2;
int _field372;
int _field37A;
- EventHandler *_field37C;
+ EventHandler *_eventHandler;
Rect _v51C34;
public:
@@ -126,8 +173,118 @@ public:
virtual void process(Event &event);
};
-class BlueAnimatedSpeaker: public Speaker {
+class VisualSpeaker: public Speaker {
public:
+ NamedObject _object1;
+ CountdownObject _object2;
+ bool _removeObject1, _removeObject2;
+ int _field20C, _field20E;
+ int _numFrames;
+ Common::Point _offsetPos;
+public:
+ VisualSpeaker();
+
+ virtual Common::String getClassName() { return "VisualSpeaker"; }
+ virtual void synchronize(Serializer &s);
+ virtual void remove();
+ virtual void proc12(Action *action);
+ virtual void setText(const Common::String &msg);
+};
+
+class SpeakerSutter: public VisualSpeaker {
+public:
+ SpeakerSutter();
+
+ virtual Common::String getClassName() { return "SpeakerSutter"; }
+ virtual void setText(const Common::String &msg);
+};
+
+class SpeakerDoug: public VisualSpeaker {
+public:
+ SpeakerDoug();
+
+ virtual Common::String getClassName() { return "SpeakerDoug"; }
+};
+
+class SpeakerJakeNoHead: public VisualSpeaker {
+public:
+ SpeakerJakeNoHead();
+
+ virtual Common::String getClassName() { return "SpeakerJakeNoHead"; }
+};
+
+class BlueForceInvObjectList : public InvObjectList {
+public:
+ InvObject _business_card;
+ InvObject _lauras_sweater;
+ InvObject _handcuffs;
+ InvObject _magnum;
+ InvObject _ticket_book;
+ InvObject _miranda_card;
+ InvObject _forest_follet;
+ InvObject _bradford_id;
+ InvObject _baseball_card;
+ InvObject _slip_bradford;
+ InvObject _flare;
+ InvObject _rap_sheet;
+ InvObject _cartridges;
+ InvObject _rifle;
+ InvObject _wig;
+ InvObject _frankies_id;
+ InvObject _tyrones_id;
+ InvObject _pistol22;
+ InvObject _unused;
+ InvObject _slip_frankie;
+ InvObject _slip_tyrone;
+ InvObject _atf_teletype;
+ InvObject _da_note;
+ InvObject _blueprints;
+ InvObject _planter_key;
+ InvObject _center_punch;
+ InvObject _tranquilizer;
+ InvObject _boat_hook;
+ InvObject _oily_rags;
+ InvObject _fuel_jar;
+ InvObject _screwdriver;
+ InvObject _floppy_disk1;
+ InvObject _floppy_disk2;
+ InvObject _driftwood;
+ InvObject _crate_piece1;
+ InvObject _crate_piece2;
+ InvObject _shoebox;
+ InvObject _badge;
+ InvObject _unused2;
+ InvObject _rental_coupons;
+ InvObject _nickel;
+ InvObject _calendar;
+ InvObject _dixon_note;
+ InvObject _cobb_mugshot;
+ InvObject _murder_article;
+ InvObject _microfiche;
+ InvObject _future_wave_keys;
+ InvObject _rental_boat_keys;
+ InvObject _napkin;
+ InvObject _cobb_printout;
+ InvObject _fishing_net;
+ InvObject _id;
+ InvObject _rounds_9mm;
+ InvObject _dates_note;
+ InvObject _hand_grenade;
+ InvObject _cord_110;
+ InvObject _cord_110_plug;
+ InvObject _cord_220;
+ InvObject _unused3;
+ InvObject _cord_220_plug;
+ InvObject _official_document;
+ InvObject _red_sweater;
+ InvObject _jackknife;
+ InvObject _whistle;
+ InvObject _gun;
+ InvObject _alley_cat_key;
+
+ BlueForceInvObjectList();
+
+ virtual Common::String getClassName() { return "BlueForceInvObjectList"; }
};
} // End of namespace BlueForce
diff --git a/engines/tsage/blue_force/blueforce_scenes1.h b/engines/tsage/blue_force/blueforce_scenes1.h
index 0769c6e3c6..2b07e2b48f 100644
--- a/engines/tsage/blue_force/blueforce_scenes1.h
+++ b/engines/tsage/blue_force/blueforce_scenes1.h
@@ -71,7 +71,7 @@ public:
Action1 _action1;
Action2 _action2;
ScenePalette _scenePalette;
- SceneObjectExt2 _object1, _object2, _object3, _object4, _object5;
+ NamedObject _object1, _object2, _object3, _object4, _object5;
int _index;
Scene100();
@@ -115,7 +115,6 @@ public:
SceneObject _object1, _object2, _protaginist2, _protaginist1, _object5;
SceneObject _drunk, _object7, _bartender, _object9, _object10;
Text _text;
- BlueAnimatedSpeaker _speaker;
Action1 _action1;
Action _action2, _action3;
public:
diff --git a/engines/tsage/blue_force/blueforce_scenes3.cpp b/engines/tsage/blue_force/blueforce_scenes3.cpp
new file mode 100644
index 0000000000..e49037abf9
--- /dev/null
+++ b/engines/tsage/blue_force/blueforce_scenes3.cpp
@@ -0,0 +1,602 @@
+/* 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_scenes3.h"
+#include "tsage/scenes.h"
+#include "tsage/tsage.h"
+#include "tsage/staticres.h"
+#include "tsage/globals.h"
+
+namespace TsAGE {
+
+namespace BlueForce {
+
+/*--------------------------------------------------------------------------
+ * Scene 300 - Outside Police Station
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene300::Object::startMover(CursorType action) {
+ if (action == CURSOR_TALK) {
+ Scene300 *scene = (Scene300 *)BF_GLOBALS._sceneManager._scene;
+ scene->_stripManager.start(_stripNumber, scene);
+ } else {
+ NamedObject::startMover(action);
+ }
+}
+
+void Scene300::Object17::startMover(CursorType action) {
+ if ((action != CURSOR_USE) || !BF_GLOBALS.getFlag(3)) {
+ NamedObject::startMover(action);
+ } else if ((BF_GLOBALS._v4CEA2 != 2) || (BF_GLOBALS._bikiniHutState >= 12)) {
+ Scene300 *scene = (Scene300 *)BF_GLOBALS._sceneManager._scene;
+ setAction(&scene->_action4);
+ } else {
+ SceneItem::display2(300, 33);
+ }
+}
+
+void Scene300::Item1::startMover(CursorType action) {
+ if (action == CURSOR_TALK) {
+ Scene300 *scene = (Scene300 *)BF_GLOBALS._sceneManager._scene;
+ BF_GLOBALS._player.disableControl();
+ scene->_sceneMode = 305;
+ scene->setAction(&scene->_sequenceManager1, scene, 305, &BF_GLOBALS._player,
+ &scene->_object8, NULL);
+ } else {
+ NamedHotspot::startMover(action);
+ }
+}
+
+void Scene300::Item2::startMover(CursorType action) {
+ if ((action == CURSOR_LOOK) || (action == CURSOR_USE)) {
+ Scene300 *scene = (Scene300 *)BF_GLOBALS._sceneManager._scene;
+ scene->setAction(&scene->_sequenceManager1, scene, 304, &scene->_object11, NULL);
+ } else {
+ NamedHotspot::startMover(action);
+ }
+}
+
+void Scene300::Item14::startMover(CursorType action) {
+ ADD_PLAYER_MOVER_NULL(BF_GLOBALS._player, 151, 54);
+}
+
+void Scene300::Item15::startMover(CursorType action) {
+ ADD_PLAYER_MOVER_NULL(BF_GLOBALS._player, 316, 90);
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene300::Action1::signal() {
+ switch (_actionIndex++) {
+ case 0:
+ BF_GLOBALS._player.disableControl();
+ setDelay(1);
+ break;
+ case 1:
+ if (BF_GLOBALS.getFlag(7))
+ SceneItem::display2(300, 0);
+ else
+ SceneItem::display2(666, 27);
+ setDelay(1);
+ break;
+ case 2: {
+ ADD_PLAYER_MOVER_THIS(BF_GLOBALS._player, BF_GLOBALS._player._position.x - 8,
+ BF_GLOBALS._player._position.y);
+ break;
+ }
+ case 3:
+ BF_GLOBALS._player.enableControl();
+ remove();
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene300::Action2::signal() {
+ switch (_actionIndex++) {
+ case 0:
+ BF_GLOBALS._player.disableControl();
+ setDelay(1);
+ break;
+ case 1:
+ SceneItem::display2(300, 28);
+ setDelay(1);
+ break;
+ case 2: {
+ ADD_MOVER(BF_GLOBALS._player, BF_GLOBALS._player._position.x + 8,
+ BF_GLOBALS._player._position.y);
+ break;
+ }
+ case 3:
+ BF_GLOBALS._player.enableControl();
+ remove();
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene300::Action3::signal() {
+ Scene300 *scene = (Scene300 *)BF_GLOBALS._sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ BF_GLOBALS._player.disableControl();
+ setDelay(1);
+ break;
+ case 1:
+ BF_GLOBALS._player.setAction(&scene->_sequenceManager1, this, 306, &BF_GLOBALS._player,
+ &scene->_object8, NULL);
+ break;
+ case 2:
+ SceneItem::display2(300, 35);
+ setDelay(1);
+ break;
+ case 3:
+ BF_GLOBALS._player.enableControl();
+ remove();
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene300::Action4::signal() {
+ Scene300 *scene = (Scene300 *)BF_GLOBALS._sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ BF_GLOBALS._player.disableControl();
+ setDelay(1);
+ break;
+ case 1:
+ setAction(&scene->_sequenceManager1, this, 316, &BF_GLOBALS._player, &scene->_object19, NULL);
+ break;
+ case 2:
+ BF_GLOBALS._sceneManager.changeScene(15);
+ break;
+ case 3:
+ setAction(&scene->_sequenceManager1, this, 319, &scene->_object19, NULL);
+ break;
+ case 4:
+ BF_GLOBALS.setFlag(2);
+ BF_GLOBALS._sceneManager.changeScene(190);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene300::Action5::signal() {
+ Scene300 *scene = (Scene300 *)BF_GLOBALS._sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ BF_GLOBALS._player.disableControl();
+ scene->_field2760 = 1;
+ setDelay(1);
+ break;
+ case 1:
+ setAction(&scene->_sequenceManager1, this, 1306, &scene->_object1, &scene->_object8, NULL);
+ break;
+ case 2:
+ scene->_stripManager.start(3004, this);
+ BF_GLOBALS._sceneManager.changeScene(15);
+ break;
+ case 3: {
+ ADD_PLAYER_MOVER_NULL(BF_GLOBALS._player, 186, 140);
+ break;
+ }
+ case 4:
+ remove();
+ break;
+ default:
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene300::Scene300(): SceneExt(), _object13(3000), _object14(3001), _object15(3002),
+ _object16(3003) {
+ _field2760 = _field2762 = 0;
+}
+
+void Scene300::postInit(SceneObjectList *OwnerList) {
+ SceneExt::postInit();
+ loadScene(300);
+
+ // Add the speakers
+ _stripManager.addSpeaker(&_gameTextSpeaker);
+ _stripManager.addSpeaker(&_sutterSpeaker);
+ _stripManager.addSpeaker(&_dougSpeaker);
+ _stripManager.addSpeaker(&_jakeSpeaker);
+
+ _field2762 = 0;
+ _item14.setup(Rect(144, 27, 160, 60), 300, -1, -1, -1, 1, NULL);
+ _item15.setup(Rect(310, 76, SCREEN_WIDTH, 105), 300, -1, -1, -1, 1, NULL);
+
+ // Setup the player
+ int playerVisage = BF_GLOBALS._player._visage;
+ BF_GLOBALS._player.postInit();
+ BF_GLOBALS._player.setVisage(playerVisage);
+ BF_GLOBALS._player.setStrip(3);
+ BF_GLOBALS._player.setPosition(Common::Point(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2));
+ BF_GLOBALS._player.setObjectWrapper(new SceneObjectWrapper());
+ BF_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ BF_GLOBALS._player._moveDiff = Common::Point(3, 1);
+ BF_GLOBALS._player.disableControl();
+
+ _object8.setStrip(2);
+ _object8.setPosition(Common::Point(300, 77));
+
+ if ((BF_GLOBALS._v4CEA2 != 2) || (BF_GLOBALS._bikiniHutState < 12)) {
+ _object17.postInit();
+ _object17.setVisage(301);
+ _object17.setStrip(1);
+ _object17.setPosition(Common::Point(87, 88));
+ _object17.setup(300, 11, 13, 2, 1, NULL);
+
+ _object18.postInit();
+ _object18.setVisage(301);
+ _object18.setStrip(1);
+ _object18.setPosition(Common::Point(137, 92));
+ _object18.setup(300, 11, 13, 3, 1, NULL);
+ }
+
+ _object19.postInit();
+ _object19.setVisage(301);
+ _object19.setStrip(1);
+ _object19.setPosition(Common::Point(175, 99));
+ _object19.setup(300, 11, 13, 34, 1, NULL);
+
+ _object11.postInit();
+ _object11.setVisage(301);
+ _object11.setStrip(8);
+ _object11.setPosition(Common::Point(265, 91));
+ _object11.hide();
+
+ //***DEBUG***
+BF_GLOBALS.setFlag(2);
+BF_GLOBALS._sceneManager._previousScene = 190;
+BF_GLOBALS._player.setVisage(190);
+
+ switch (BF_GLOBALS._sceneManager._previousScene) {
+ case 50:
+ case 60:
+ BF_GLOBALS.clearFlag(2);
+ if (BF_GLOBALS.getFlag(3)) {
+ BF_GLOBALS._player.disableControl();
+ _sceneMode = 318;
+ setAction(&_sequenceManager1, this, 318, &BF_GLOBALS._player, &_object19, NULL);
+ } else {
+ BF_GLOBALS._player.disableControl();
+ _sceneMode = 300;
+ setAction(&_sequenceManager1, this, 1300, &BF_GLOBALS._player, NULL);
+ }
+ break;
+ case 190:
+ _sceneMode = 0;
+ if (!BF_GLOBALS.getFlag(2)) {
+ _sceneMode = 7308;
+ BF_GLOBALS._player.setPosition(Common::Point(175, 50));
+ ADD_PLAYER_MOVER_THIS(BF_GLOBALS._player, 123, 71);
+
+ if ((BF_GLOBALS._v4CEA2 == 2) && (BF_GLOBALS._bikiniHutState < 12))
+ setup();
+ } else if (!BF_GLOBALS.getFlag(3)) {
+ BF_GLOBALS._player.disableControl();
+ _sceneMode = 300;
+ setAction(&_sequenceManager1, this, 300, &BF_GLOBALS._player, NULL);
+ } else {
+ BF_GLOBALS._player.disableControl();
+ _sceneMode = 318;
+ setAction(&_sequenceManager1, this, 318, &BF_GLOBALS._player, &_object19, NULL);
+ }
+ break;
+ case 315:
+ BF_GLOBALS._player.setPosition(Common::Point(305, 66));
+ if ((BF_GLOBALS._v4CEA2 != 2) || (BF_GLOBALS._bikiniHutState >= 12)) {
+ BF_GLOBALS._player.setVisage(BF_GLOBALS.getFlag(3) ? 1304 : 303);
+ BF_GLOBALS._player.disableControl();
+ _sceneMode = 0;
+ setAction(&_sequenceManager1, this, 306, &BF_GLOBALS._player, &_object8, NULL);
+ } else {
+ BF_GLOBALS._player.setVisage(1304);
+ setup();
+ BF_GLOBALS._player.disableControl();
+ _sceneMode = 0;
+ setAction(&_sequenceManager1, this, 306, &BF_GLOBALS._player, &_object8, NULL);
+ }
+ break;
+ default:
+ _sceneMode = 0;
+ BF_GLOBALS._player.setVisage(1304);
+ BF_GLOBALS._player.disableControl();
+ setAction(&_sequenceManager1, this, 306, &BF_GLOBALS._player, &_object8, NULL);
+ break;
+ }
+}
+
+void Scene300::signal() {
+ switch (_sceneMode) {
+ case 300:
+ BF_GLOBALS._sound1.fadeSound(33);
+ BF_GLOBALS.clearFlag(2);
+ _sceneMode = 0;
+
+ if ((BF_GLOBALS._v4CEA2 != 1) || (BF_GLOBALS._bikiniHutState != 0)) {
+ signal();
+ } else {
+ _stripManager.start(3005, this);
+ }
+ break;
+ case 301:
+ if (_field2760) {
+ _sceneMode = 1302;
+ signal();
+ } else {
+ BF_GLOBALS._player.disableControl();
+ _sceneMode = 1302;
+ setAction(&_sequenceManager1, this, 306, &_object1, &_object8, NULL);
+ }
+
+ _object12.show();
+ _object5.dispatch();
+ BF_GLOBALS._player.hide();
+ break;
+ case 303:
+ BF_GLOBALS._player.disableControl();
+ _sceneMode = 2307;
+ setAction(&_sequenceManager1, this, 303, &_object13, &_object1, NULL);
+ break;
+ case 305:
+ if ((BF_GLOBALS._v4CEA2 == 4) || (BF_GLOBALS._v4CEA2 == 5)) {
+ _sceneMode = 0;
+ setAction(&_action3);
+ } else {
+ BF_GLOBALS._sound1.fadeOut2(NULL);
+ BF_GLOBALS._sceneManager.changeScene(315);
+ }
+ break;
+ case 309:
+ BF_GLOBALS._player.disableControl();
+ _sceneMode = 3307;
+ setAction(&_sequenceManager1, this, 309, &_object14, &_object1, NULL);
+ break;
+ case 310:
+ BF_GLOBALS._player.disableControl();
+ _sceneMode = 4307;
+ setAction(&_sequenceManager1, this, 310, &_object12, &_object1, NULL);
+ break;
+ case 311:
+ BF_GLOBALS._player.disableControl();
+ _sceneMode = 5307;
+ setAction(&_sequenceManager1, this, 311, &_object15, &_object1, NULL);
+ break;
+ case 312:
+ case 5307:
+ BF_GLOBALS._player.disableControl();
+ _sceneMode = 1305;
+ setAction(&_sequenceManager1, this, 312, &_object1, &_object16, NULL);
+ break;
+ case 317:
+ BF_GLOBALS.setFlag(2);
+ BF_GLOBALS._sceneManager.changeScene(60);
+ break;
+ case 318:
+ BF_GLOBALS.clearFlag(2);
+ _sceneMode = 0;
+ signal();
+ break;
+ case 1302:
+ _field2762 = 0;
+ BF_GLOBALS._player.disableControl();
+ _sceneMode = 1308;
+ setAction(&_sequenceManager1, this, 302, &_object1, NULL);
+ break;
+ case 1305:
+ BF_GLOBALS._player.disableControl();
+ _sceneMode = 1313;
+ setAction(&_sequenceManager1, this, 305, &_object1, &_object8, NULL);
+ BF_GLOBALS._player.show();
+ _object12.hide();
+ break;
+ case 1307:
+ case 2308:
+ BF_GLOBALS._player.disableControl();
+ _sceneMode = 303;
+ setAction(&_sequenceManager1, this, 308, &_object14, NULL);
+ break;
+ case 1308:
+ BF_GLOBALS._player.disableControl();
+ _sceneMode = 1307;
+ setAction(&_sequenceManager1, this, 308, &_object13, NULL);
+ break;
+ case 1313:
+ BF_GLOBALS._player.disableControl();
+ _sceneMode = 0;
+ _object15.setAction(&_sequenceManager4, NULL, 315, &_object15, &_object16, NULL);
+ _object13.setAction(&_sequenceManager2, NULL, 313, &_object13, &_object17, NULL);
+ _object14.setAction(&_sequenceManager3, this, 314, &_object14, &_object18, NULL);
+
+ BF_GLOBALS._bikiniHutState = 12;
+ BF_GLOBALS._sound1.changeSound(33);
+ break;
+ case 2307:
+ case 3308:
+ BF_GLOBALS._player.disableControl();
+ _sceneMode = 309;
+ setAction(&_sequenceManager1, this, 308, &_object12, NULL);
+ break;
+ case 3307:
+ _object9.postInit();
+ _object9.hide();
+ _object10.postInit();
+ _object10.hide();
+
+ if (BF_GLOBALS.getFlag(1)) {
+ BF_GLOBALS._player.disableControl();
+ _sceneMode = 4308;
+ setAction(&_sequenceManager1, this, 6307, &_object2, &_object1, &_object9, &_object10, NULL);
+ } else {
+ BF_GLOBALS._player.disableControl();
+ _sceneMode = 4308;
+ setAction(&_sequenceManager1, this, 7307, &_object12, &_object1, &_object9, &_object10, NULL);
+ }
+ break;
+ case 4307:
+ case 5308:
+ BF_GLOBALS._player.disableControl();
+ _sceneMode = 311;
+ setAction(&_sequenceManager1, this, 308, &_object16, NULL);
+ break;
+ case 4308:
+ BF_GLOBALS._player.disableControl();
+ _sceneMode = 310;
+ setAction(&_sequenceManager1, this, 308, &_object15, NULL);
+ break;
+ case 6308:
+ BF_GLOBALS._sceneManager.changeScene(190);
+ break;
+ case 7308:
+ if (_field2762) {
+ BF_GLOBALS._player.disableControl();
+ _sceneMode = 301;
+ setAction(&_sequenceManager1, this, 301, &BF_GLOBALS._player, NULL);
+ } else {
+ BF_GLOBALS._player.enableControl();
+ }
+ break;
+ case 0:
+ default:
+ if (_field2762) {
+ BF_GLOBALS._player.disableControl();
+ _sceneMode = 301;
+ setAction(&_sequenceManager1, this, 301, &BF_GLOBALS._player, NULL);
+ } else {
+ BF_GLOBALS._player.enableControl();
+ }
+ break;
+ }
+}
+
+void Scene300::process(Event &event) {
+ if ((BF_GLOBALS._player._field8E != 0) && !_eventHandler && (event.mousePos.y < (BF_INTERFACE_Y - 1))) {
+ Visage visage;
+
+ if (_item14.contains(event.mousePos)) {
+ visage.setVisage(1, 8);
+ GfxSurface surface = visage.getFrame(2);
+ BF_GLOBALS._events.setCursor(surface);
+ } else if (_item15.contains(event.mousePos)) {
+ visage.setVisage(1, 8);
+ GfxSurface surface = visage.getFrame(3);
+ BF_GLOBALS._events.setCursor(surface);
+ } else {
+ CursorType cursorId = BF_GLOBALS._events.hideCursor();
+ BF_GLOBALS._events.setCursor(cursorId);
+ }
+ }
+}
+
+void Scene300::dispatch() {
+ SceneExt::dispatch();
+
+ if (_action) {
+ int regionIndex = BF_GLOBALS._player.getRegionIndex();
+ if ((regionIndex == 1) && (_field2762 == 1)) {
+ BF_GLOBALS._player.disableControl();
+ _sceneMode = 301;
+ setAction(&_sequenceManager1, this, 301, &BF_GLOBALS._player, NULL);
+ }
+
+ if ((BF_GLOBALS._player._position.y < 59) && (BF_GLOBALS._player._position.x > 137) &&
+ (_sceneMode != 6308) && (_sceneMode != 7308)) {
+ BF_GLOBALS._v4CEA4 = 3;
+ _sceneMode = 6308;
+ BF_GLOBALS._player.disableControl();
+ ADD_MOVER(BF_GLOBALS._player, BF_GLOBALS._player._position.x + 20,
+ BF_GLOBALS._player._position.y - 5);
+ }
+ }
+}
+
+void Scene300::setup() {
+ _object13.postInit();
+ _object13.setVisage(307);
+ _object13.setStrip(6);
+ _object13.setPosition(Common::Point(156, 134));
+ _object13._moveDiff = Common::Point(3, 1);
+ _object3.setup(&_object13, 306, 1, 29);
+
+ _object14.postInit();
+ _object14.setVisage(307);
+ _object14.setStrip(6);
+ _object14.setPosition(Common::Point(171, 137));
+ _object14._moveDiff = Common::Point(3, 1);
+ _object4.setup(&_object14, 306, 2, 29);
+
+ _object12.postInit();
+ _object12.setVisage(307);
+ _object12.setStrip(6);
+ _object12.setPosition(Common::Point(186, 140));
+ _object12._moveDiff = Common::Point(3, 1);
+ _object5.setup(&_object12, 306, 2, 29);
+ _object12.hide();
+
+ _object15.postInit();
+ _object15.setVisage(307);
+ _object15.setStrip(6);
+ _object15.setPosition(Common::Point(201, 142));
+ _object15._moveDiff = Common::Point(3, 1);
+ _object6.setup(&_object15, 306, 3, 29);
+
+ _object16.postInit();
+ _object16.setVisage(307);
+ _object16.setStrip(6);
+ _object16.setPosition(Common::Point(216, 145));
+ _object16._moveDiff = Common::Point(3, 1);
+ _object7.setup(&_object16, 306, 1, 29);
+
+ _object1.postInit();
+ _object1.setVisage(307);
+ _object1.setStrip(6);
+ _object1.setPosition(Common::Point(305, 66));
+ _object1._moveDiff = Common::Point(3, 1);
+ _object1.setObjectWrapper(new SceneObjectWrapper());
+ _object1.animate(ANIM_MODE_1, NULL);
+ _object2.setup(&_object1, 306, 4, 9);
+
+ BF_GLOBALS._sceneItems.addItems(&_object13, &_object14, &_object15, &_object16, NULL);
+ _timer.set(3600, this, &_action5);
+
+ _field2760 = 0;
+ _field2762 = 1;
+}
+
+} // End of namespace BlueForce
+
+} // End of namespace TsAGE
diff --git a/engines/tsage/blue_force/blueforce_scenes3.h b/engines/tsage/blue_force/blueforce_scenes3.h
new file mode 100644
index 0000000000..42ae69fc3f
--- /dev/null
+++ b/engines/tsage/blue_force/blueforce_scenes3.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_SCENES3_H
+#define TSAGE_BLUEFORCE_SCENES3_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 Scene300: public SceneExt {
+ /* Objects */
+ class Object: public NamedObject {
+ public:
+ int _stripNumber;
+ public:
+ Object(int stripNumber) { _stripNumber = stripNumber; }
+
+ virtual void startMover(CursorType action);
+ };
+ class Object17: public NamedObject {
+ public:
+ virtual void startMover(CursorType action);
+ };
+
+ /* Items */
+ class Item1: public NamedHotspot {
+ public:
+ virtual void startMover(CursorType action);
+ };
+ class Item2: public NamedHotspot {
+ public:
+ virtual void startMover(CursorType action);
+ };
+ class Item14: public NamedHotspot {
+ public:
+ virtual void startMover(CursorType action);
+ };
+ class Item15: public NamedHotspot {
+ public:
+ virtual void startMover(CursorType action);
+ };
+
+ /* 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();
+ };
+ class Action4: public Action {
+ public:
+ virtual void signal();
+ };
+ class Action5: public Action {
+ public:
+ virtual void signal();
+ };
+private:
+ void setup();
+public:
+ SequenceManager _sequenceManager1, _sequenceManager2;
+ SequenceManager _sequenceManager3, _sequenceManager4;
+ NamedObject _object1;
+ FollowerObject _object2, _object3, _object4, _object5, _object6, _object7;
+ SceneObject _object8, _object9, _object10;
+ NamedObject _object11, _object12;
+ Object _object13, _object14, _object15, _object16;
+ Object17 _object17;
+ NamedObject _object18, _object19;
+ Item1 _item1;
+ Item2 _item2;
+ NamedHotspot _item3, _item4, _item5, _item6, _item7;
+ NamedHotspot _item8, _item9, _item10, _item11;
+ NamedHotspot _item12, _item13;
+ Item14 _item14;
+ Item15 _item15;
+ Action1 _action1;
+ Action2 _action2;
+ Action3 _action3;
+ Action4 _action4;
+ Action5 _action5;
+ SpeakerGameText _gameTextSpeaker;
+ SpeakerSutter _sutterSpeaker;
+ SpeakerDoug _dougSpeaker;
+ SpeakerJakeNoHead _jakeSpeaker;
+ TimerExt _timer;
+ int _field2760, _field2762;
+
+ Scene300();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void process(Event &event);
+ virtual void dispatch();
+};
+
+} // End of namespace BlueForce
+
+} // End of namespace TsAGE
+
+#endif
diff --git a/engines/tsage/blue_force/blueforce_ui.cpp b/engines/tsage/blue_force/blueforce_ui.cpp
new file mode 100644
index 0000000000..e27c744486
--- /dev/null
+++ b/engines/tsage/blue_force/blueforce_ui.cpp
@@ -0,0 +1,366 @@
+/* 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_ui.h"
+#include "tsage/blue_force/blueforce_logic.h"
+#include "tsage/tsage.h"
+#include "tsage/core.h"
+
+namespace TsAGE {
+
+namespace BlueForce {
+
+void UIElement::synchronize(Serializer &s) {
+ AltSceneObject::synchronize(s);
+ s.syncAsSint16LE(_field88);
+ s.syncAsSint16LE(_enabled);
+ s.syncAsSint16LE(_frameNum);
+}
+
+void UIElement::setup(int visage, int stripNum, int frameNum, int posX, int posY, int priority) {
+ _field88 = 0;
+ _frameNum = frameNum;
+ _enabled = true;
+
+ SceneObject::setup(visage, stripNum, frameNum, posX, posY, priority);
+}
+
+void UIElement::setEnabled(bool flag) {
+ if (_enabled != flag) {
+ _enabled = flag;
+ setFrame(_enabled ? _frameNum : _frameNum + 2);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void UIQuestion::process(Event &event) {
+ if (event.eventType == EVENT_BUTTON_DOWN) {
+ int currentCursor = GLOBALS._events.getCursor();
+ GLOBALS._events.hideCursor();
+ showDescription(currentCursor);
+
+ event.handled = true;
+ }
+}
+
+void UIQuestion::showDescription(int lineNum) {
+ if (lineNum == 8) {
+ // Unknown object description
+ } else {
+ // Display object description
+ SceneItem::display2(9001, lineNum);
+ }
+}
+
+void UIQuestion::setEnabled(bool flag) {
+ if (_enabled != flag) {
+ UIElement::setEnabled(flag);
+ BF_GLOBALS._uiElements.draw();
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void UIScore::postInit(SceneObjectList *OwnerList) {
+ int xp = 266;
+ _digit3.setup(1, 6, 1, 266, 180, 255);
+ xp += 7;
+ _digit2.setup(1, 6, 1, 266, 180, 255);
+ xp += 7;
+ _digit1.setup(1, 6, 1, 266, 180, 255);
+ xp += 7;
+ _digit0.setup(1, 6, 1, 266, 180, 255);
+}
+
+void UIScore::draw() {
+ _digit3.draw();
+ _digit2.draw();
+ _digit1.draw();
+ _digit0.draw();
+}
+
+void UIScore::updateScore() {
+ int score = BF_GLOBALS._uiElements._scoreValue;
+
+ _digit3.setFrame(score / 1000); score %= 1000;
+ _digit2.setFrame(score / 100); score %= 100;
+ _digit1.setFrame(score / 10); score %= 10;
+ _digit0.setFrame(score);
+}
+
+/*--------------------------------------------------------------------------*/
+
+UIInventorySlot::UIInventorySlot(): UIElement() {
+ _objIndex = 0;
+}
+
+void UIInventorySlot::synchronize(Serializer &s) {
+ UIElement::synchronize(s);
+ s.syncAsSint16LE(_objIndex);
+}
+
+void UIInventorySlot::process(Event &event) {
+ if (event.eventType == EVENT_BUTTON_DOWN) {
+ event.handled = true;
+
+ if (_objIndex == 66) {
+ // Handle showing gun and ammo
+ warning("TODO: show gun");
+ } else if (_objIndex != 0) {
+ GLOBALS._events.setCursor((CursorType)_objIndex);
+ }
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+UIInventoryScroll::UIInventoryScroll() {
+ _isLeft = false;
+}
+
+void UIInventoryScroll::synchronize(Serializer &s) {
+ UIElement::synchronize(s);
+ s.syncAsSint16LE(_isLeft);
+}
+
+void UIInventoryScroll::process(Event &event) {
+ if (event.eventType == EVENT_BUTTON_DOWN) {
+ warning("TODO: UIInventoryScroll::process");
+ event.handled = true;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+UICollection::UICollection(): EventHandler() {
+ _clearScreen = false;
+ _visible = false;
+ _field4E = 0;
+}
+
+void UICollection::setup(const Common::Point &pt) {
+ _position = pt;
+ _bounds.left = _bounds.right = pt.x;
+ _bounds.top = _bounds.bottom = pt.y;
+}
+
+void UICollection::hide() {
+ erase();
+ _visible = false;
+}
+
+void UICollection::erase() {
+ if (_clearScreen) {
+ Rect tempRect(0, BF_INTERFACE_Y, SCREEN_WIDTH, SCREEN_HEIGHT);
+ GLOBALS._screenSurface.fillRect(tempRect, 0);
+ _clearScreen = false;
+ }
+}
+
+void UICollection::resetClear() {
+ _clearScreen = false;
+}
+
+void UICollection::draw() {
+ if (_visible) {
+ // Draw the elements
+ for (uint idx = 0; idx < _objList.size(); ++idx)
+ _objList[idx]->draw();
+
+ // Update the screen
+ g_system->updateScreen();
+ _clearScreen = 1;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void UIElements::process(Event &event) {
+ if (_clearScreen && BF_GLOBALS._player._field8E && (BF_GLOBALS._sceneManager._sceneNumber != 50)) {
+ if (_bounds.contains(event.mousePos)) {
+
+ } else if (_field4E) {
+ BF_GLOBALS._events.hideCursor();
+ BF_GLOBALS._events.setCursor((CursorType)1);
+ _field4E = 0;
+
+ SceneExt *scene = (SceneExt *)BF_GLOBALS._sceneManager._scene;
+ if (scene->_eventHandler) {
+ error("TODO: UIElements::process _eventHandler");
+ }
+ }
+ }
+}
+
+void UIElements::setup(const Common::Point &pt) {
+ _slotStart = 0;
+ _itemList.clear();
+ _scoreValue = 0;
+ _field820 = 1;
+ UICollection::setup(pt);
+ hide();
+
+ _object1.setup(1, 3, 1, 0, 0, 255);
+ add(&_object1);
+
+ // Set up the inventory slots
+ for (int idx = 0; idx < 4; ++idx) {
+ UIElement *item = NULL;
+ switch (idx) {
+ case 0:
+ item = &_slot1;
+ break;
+ case 1:
+ item = &_slot2;
+ break;
+ case 2:
+ item = &_slot3;
+ break;
+ case 3:
+ item = &_slot4;
+ break;
+ }
+
+ item->setup(9, 1, idx, idx * 63 + 2, 4, 255);
+ add(item);
+ }
+
+ // Setup bottom-right hand buttons
+ int xp = 62;
+ _question.setup(1, 4, 7, xp, 16, 255);
+ _question.setEnabled(false);
+
+ xp += 21;
+ _scrollLeft.setup(1, 4, 1, xp, 16, 255);
+ add(&_scrollLeft);
+ _scrollLeft._isLeft = true;
+
+ xp += 22;
+ _scrollRight.setup(1, 4, 4, xp, 16, 255);
+ add(&_scrollRight);
+ _scrollRight._isLeft = false;
+
+ // Set up the score
+ _score.postInit();
+ add(&_score);
+
+ // Set interface area
+ _bounds = Rect(0, BF_INTERFACE_Y - 1, SCREEN_WIDTH, SCREEN_HEIGHT);
+
+ updateInventory();
+}
+
+void UIElements::add(UIElement *obj) {
+ // Add object
+ assert(_objList.size() < 12);
+ _objList.push_back(obj);
+
+ obj->setPosition(Common::Point(_bounds.left + obj->_bounds.left, _bounds.top + obj->_bounds.top));
+ GfxSurface s = obj->getFrame();
+ s.draw(obj->_position);
+}
+
+/**
+ * Handles updating the visual inventory in the user interface
+ */
+void UIElements::updateInventory() {
+ _score.updateScore();
+ updateInvList();
+
+ // Enable scroll buttons if the player has more than four items
+ if (_itemCount > 4) {
+ _scrollLeft.setEnabled(true);
+ _scrollRight.setEnabled(true);
+ } else {
+ _scrollLeft.setEnabled(false);
+ _scrollRight.setEnabled(false);
+ }
+
+ // Handle cropping the slots start within inventory
+ int last = (_itemList.size() - 1) / 4 + 1;
+ if (_slotStart < 0)
+ _slotStart = last - 1;
+ else if (_slotStart > (last - 1))
+ _slotStart = 0;
+
+ // Handle refreshing slot graphics
+ UIInventorySlot *slotList[4] = { &_slot1, &_slot2, &_slot3, &_slot4 };
+
+ SynchronizedList<InvObject *>::iterator i;
+ int objIndex = 0;
+ for (i = BLUE_INVENTORY._itemList.begin(); i != BLUE_INVENTORY._itemList.end(); ++i, ++objIndex) {
+ InvObject *obj = *i;
+
+ for (int slotIndex = 0; slotIndex < 4; ++slotIndex) {
+ int idx = _slotStart + slotIndex;
+ int objectIdx = (idx < (int)_itemList.size()) ? _itemList[idx] : 0;
+
+ if (objectIdx == objIndex) {
+ UIInventorySlot *slot = slotList[slotIndex];
+
+ slot->_objIndex = objIndex;
+ slot->setVisage(obj->_visage);
+ slot->setStrip(obj->_strip);
+ slot->setFrame(obj->_frame);
+ }
+ }
+ }
+
+ if (_field820)
+ draw();
+}
+
+/**
+ * Update the list of the indexes of items in the player's inventory
+ */
+void UIElements::updateInvList() {
+ // Update the index list of items in the player's inventory
+ _itemList.clear();
+
+ SynchronizedList<InvObject *>::iterator i;
+ int itemIndex = 0;
+ for (i = BF_GLOBALS._inventory->_itemList.begin(); i != BF_GLOBALS._inventory->_itemList.end(); ++i, ++itemIndex) {
+ InvObject *invObject = *i;
+ if (invObject->inInventory())
+ _itemList.push_back(itemIndex);
+ }
+}
+
+/**
+ * Updates an inventory slot with the item to be displayed
+
+void UIElements::updateInvSlot(UIInventorySlot *slot, int objIndex) {
+ slot->_objIndex = objIndex;
+ int itemId = (objIndex < (int)_itemList.size()) ? _itemList[objIndex] : 0;
+ InvObject *obj = BF_GLOBALS._inventory->_itemList[itemId + 2];
+
+ // TODO: Validate usage of fields
+ slot->setVisage(obj._displayResNum);
+ slot->setStrip(obj._rlbNum);
+ slot->setFrame(obj._cursorNum);
+}
+*/
+
+} // End of namespace BlueForce
+
+} // End of namespace TsAGE
diff --git a/engines/tsage/blue_force/blueforce_ui.h b/engines/tsage/blue_force/blueforce_ui.h
new file mode 100644
index 0000000000..15e7a760d9
--- /dev/null
+++ b/engines/tsage/blue_force/blueforce_ui.h
@@ -0,0 +1,135 @@
+/* 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_UI_H
+#define TSAGE_BLUEFORCE_UI_H
+
+#include "common/scummsys.h"
+#include "tsage/core.h"
+#include "tsage/sound.h"
+
+namespace TsAGE {
+
+namespace BlueForce {
+
+using namespace TsAGE;
+
+class UIElement: public AltSceneObject {
+public:
+ int _field88;
+ bool _enabled;
+ int _frameNum;
+
+ virtual Common::String getClassName() { return "UIElement"; }
+ virtual void synchronize(Serializer &s);
+
+ void setup(int visage, int stripNum, int frameNum, int posX, int posY, int priority);
+ void setEnabled(bool flag);
+};
+
+// This class implements the Question mark button
+class UIQuestion: public UIElement {
+private:
+ void showDescription(int lineNum);
+public:
+ virtual void process(Event &event);
+ void setEnabled(bool flag);
+};
+
+// This class implements the score counter
+class UIScore: public UIElement {
+private:
+ void showDescription(int lineNum);
+public:
+ UIElement _digit3, _digit2, _digit1, _digit0;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void draw();
+
+ void updateScore();
+};
+
+class UIInventorySlot: public UIElement {
+public:
+ int _objIndex;
+
+ UIInventorySlot();
+ virtual Common::String getClassName() { return "UIInventorySlot"; }
+ virtual void synchronize(Serializer &s);
+ virtual void process(Event &event);
+};
+
+class UIInventoryScroll: public UIElement {
+public:
+ bool _isLeft;
+
+ UIInventoryScroll();
+ virtual Common::String getClassName() { return "UIInventoryScroll"; }
+ virtual void synchronize(Serializer &s);
+ virtual void process(Event &event);
+};
+
+class UICollection: public EventHandler {
+protected:
+ void erase();
+public:
+ Common::Point _position;
+ Rect _bounds;
+ bool _visible;
+ bool _clearScreen;
+ int _field4E;
+ Common::Array<UIElement *> _objList;
+
+ UICollection();
+ void setup(const Common::Point &pt);
+ void hide();
+ void resetClear();
+ void draw();
+};
+
+class UIElements: public UICollection {
+private:
+ void add(UIElement *obj);
+ void updateInventory();
+ void updateInvList();
+public:
+ UIElement _object1;
+ UIQuestion _question;
+ UIScore _score;
+ UIInventorySlot _slot1, _slot2, _slot3, _slot4;
+ UIInventoryScroll _scrollLeft, _scrollRight;
+ ASound _sound;
+ int _itemCount, _slotStart, _scoreValue;
+ bool _field820;
+ Common::Array<int> _itemList;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL) { error("Wrong init() called"); }
+ virtual void process(Event &event);
+
+ void setup(const Common::Point &pt);
+};
+
+} // End of namespace BlueForce
+
+} // End of namespace TsAGE
+
+#endif
diff --git a/engines/tsage/core.cpp b/engines/tsage/core.cpp
index 42cb1d039f..3a489e0024 100644
--- a/engines/tsage/core.cpp
+++ b/engines/tsage/core.cpp
@@ -55,6 +55,13 @@ InvObject::InvObject(int sceneNumber, int rlbNum, int cursorNum, CursorType curs
DEALLOCATE(imgData);
}
+InvObject::InvObject(int visage, int strip, int frame, int sceneNumber) {
+ _visage = visage;
+ _strip = strip;
+ _frame = frame;
+ _sceneNumber = sceneNumber;
+}
+
void InvObject::setCursor() {
_globals->_events._currentCursor = _cursorId;
@@ -1576,6 +1583,17 @@ void SceneItem::display(int resNum, int lineNum, ...) {
}
}
+void SceneItem::display2(int resNum, int lineNum) {
+ if (_vm->getGameID() == GType_BlueForce)
+ display(resNum, lineNum, SET_WIDTH, 312,
+ SET_X, 4 + GLOBALS._sceneManager._scene->_sceneBounds.left,
+ SET_Y, GLOBALS._sceneManager._scene->_sceneBounds.top + BF_INTERFACE_Y + 2,
+ SET_FONT, 4, SET_BG_COLOR, 1, SET_FG_COLOR, 19, SET_EXT_BGCOLOR, 9,
+ SET_EXT_FGCOLOR, 13, LIST_END);
+ else
+ display(resNum, lineNum, SET_WIDTH, 200, SET_EXT_BGCOLOR, 7, LIST_END);
+}
+
/*--------------------------------------------------------------------------*/
void SceneHotspot::doAction(int action) {
@@ -1599,6 +1617,11 @@ void SceneHotspot::doAction(int action) {
/*--------------------------------------------------------------------------*/
+NamedHotspot::NamedHotspot() : SceneHotspot() {
+ _resNum = 0;
+ _lookLineNum = _useLineNum = _talkLineNum = -1;
+}
+
void NamedHotspot::doAction(int action) {
switch (action) {
case CURSOR_WALK:
@@ -1608,13 +1631,19 @@ void NamedHotspot::doAction(int action) {
if (_lookLineNum == -1)
SceneHotspot::doAction(action);
else
- SceneItem::display(_resnum, _lookLineNum, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOR, 7, LIST_END);
+ SceneItem::display(_resNum, _lookLineNum, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOR, 7, LIST_END);
break;
case CURSOR_USE:
if (_useLineNum == -1)
SceneHotspot::doAction(action);
else
- SceneItem::display(_resnum, _useLineNum, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOR, 7, LIST_END);
+ SceneItem::display(_resNum, _useLineNum, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOR, 7, LIST_END);
+ break;
+ case CURSOR_TALK:
+ if (_talkLineNum == -1)
+ SceneHotspot::doAction(action);
+ else
+ SceneItem::display2(_resNum, _talkLineNum);
break;
default:
SceneHotspot::doAction(action);
@@ -1624,17 +1653,52 @@ void NamedHotspot::doAction(int action) {
void NamedHotspot::setup(int ys, int xs, int ye, int xe, const int resnum, const int lookLineNum, const int useLineNum) {
setBounds(ys, xe, ye, xs);
- _resnum = resnum;
+ _resNum = resnum;
_lookLineNum = lookLineNum;
_useLineNum = useLineNum;
+ _talkLineNum = -1;
_globals->_sceneItems.addItems(this, NULL);
}
+void NamedHotspot::setup(const Rect &bounds, int resNum, int lookLineNum, int talkLineNum, int useLineNum, int mode, SceneItem *item) {
+ setBounds(bounds);
+ _resNum = resNum;
+ _lookLineNum = lookLineNum;
+ _talkLineNum = talkLineNum;
+ _useLineNum = useLineNum;
+
+ switch (mode) {
+ case 2:
+ _globals->_sceneItems.push_front(this);
+ break;
+ case 4:
+ _globals->_sceneItems.addBefore(item, this);
+ break;
+ case 5:
+ _globals->_sceneItems.addAfter(item, this);
+ break;
+ default:
+ _globals->_sceneItems.push_back(this);
+ break;
+ }
+}
+
+void NamedHotspot::setup(int sceneRegionId, int resNum, int lookLineNum, int talkLineNum, int useLineNum, int mode) {
+ _sceneRegionId = sceneRegionId;
+ _resNum = resNum;
+ _lookLineNum = lookLineNum;
+ _talkLineNum = talkLineNum;
+ _useLineNum = useLineNum;
+}
+
void NamedHotspot::synchronize(Serializer &s) {
SceneHotspot::synchronize(s);
- s.syncAsSint16LE(_resnum);
+ s.syncAsSint16LE(_resNum);
s.syncAsSint16LE(_lookLineNum);
s.syncAsSint16LE(_useLineNum);
+
+ if (_vm->getGameID() == GType_BlueForce)
+ s.syncAsSint16LE(_talkLineNum);
}
/*--------------------------------------------------------------------------*/
@@ -2008,6 +2072,7 @@ void SceneObject::animate(AnimateMode animMode, ...) {
break;
case ANIM_MODE_8:
+ case ANIM_MODE_9:
_field68 = va_arg(va, int);
_endAction = va_arg(va, Action *);
_frameChange = 1;
@@ -2194,7 +2259,25 @@ void SceneObject::dispatch() {
} else {
setFrame(changeFrame());
}
+ break;
+
+ case ANIM_MODE_9:
+ if (_frame == _endFrame) {
+ if (_frameChange != -1) {
+ _frameChange = -1;
+ _strip = ((_strip - 1) ^ 1) + 1;
+ _endFrame = 1;
+ } else if ((_field68 == 0) || (--_field68 != 0)) {
+ _frameChange = 1;
+ _endFrame = getFrameCount();
+ setFrame(changeFrame());
+ } else {
+ animEnded();
+ }
+ } else {
+ setFrame(changeFrame());
+ }
break;
default:
@@ -2306,18 +2389,12 @@ 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 AltSceneObject::postInit(SceneObjectList *OwnerList) {
+ SceneObject::postInit(&_globals->_sceneManager._altSceneObjects);
}
-void SceneObjectExt2::synchronize(Serializer &s) {
- SceneObject::synchronize(s);
- s.syncAsSint16LE(_v8A);
- s.syncAsSint16LE(_v8C);
- s.syncAsSint16LE(_v8E);
+void AltSceneObject::draw() {
+ SceneObject::draw();
}
/*--------------------------------------------------------------------------*/
@@ -2750,6 +2827,9 @@ void Player::synchronize(Serializer &s) {
s.syncAsByte(_canWalk);
s.syncAsByte(_uiEnabled);
s.syncAsSint16LE(_field8C);
+
+ if (_vm->getGameID() == GType_BlueForce)
+ s.syncAsSint16LE(_field8E);
}
/*--------------------------------------------------------------------------*/
diff --git a/engines/tsage/core.h b/engines/tsage/core.h
index 19987ed399..b1cbf74bd3 100644
--- a/engines/tsage/core.h
+++ b/engines/tsage/core.h
@@ -55,8 +55,13 @@ public:
CursorType _cursorId;
Common::String _description;
int _iconResNum;
+
+ int _visage;
+ int _strip;
+ int _frame;
public:
InvObject(int sceneNumber, int rlbNum, int cursorNum, CursorType cursorId, const Common::String description);
+ InvObject(int visage, int strip, int frame, int sceneNumber);
bool inInventory() const { return _sceneNumber == 1; }
void setCursor();
@@ -157,6 +162,18 @@ public:
int _state;
};
+#define ADD_PLAYER_MOVER(X, Y) { Common::Point pt(X, Y); PlayerMover *mover = new PlayerMover(); \
+ _globals->_player.addMover(mover, &pt, this); }
+#define ADD_PLAYER_MOVER_NULL(OBJ, X, Y) { Common::Point pt(X, Y); PlayerMover *mover = new PlayerMover(); \
+ OBJ.addMover(mover, &pt, NULL); }
+#define ADD_PLAYER_MOVER_THIS(OBJ, X, Y) { Common::Point pt(X, Y); PlayerMover *mover = new PlayerMover(); \
+ OBJ.addMover(mover, &pt, this); }
+
+#define ADD_MOVER(OBJ, X, Y) { Common::Point pt(X, Y); NpcMover *mover = new NpcMover(); \
+ OBJ.addMover(mover, &pt, this); }
+#define ADD_MOVER_NULL(OBJ, X, Y) { Common::Point pt(X, Y); NpcMover *mover = new NpcMover(); \
+ OBJ.addMover(mover, &pt, NULL); }
+
class ObjectMover : public EventHandler {
public:
Common::Point _destPosition;
@@ -401,9 +418,7 @@ public:
void setBounds(const Rect &newBounds) { _bounds = newBounds; }
void setBounds(const int ys, const int xe, const int ye, const int xs) { _bounds = Rect(MIN(xs, xe), MIN(ys, ye), MAX(xs, xe), MAX(ys, ye)); }
static void display(int resNum, int lineNum, ...);
- static void display2(int resNum, int lineNum) {
- display(resNum, lineNum, SET_WIDTH, 200, SET_EXT_BGCOLOR, 7, LIST_END);
- }
+ static void display2(int resNum, int lineNum);
};
class SceneItemExt : public SceneItem {
@@ -427,13 +442,15 @@ public:
class NamedHotspot : public SceneHotspot {
public:
- int _resnum, _lookLineNum, _useLineNum;
- NamedHotspot() : SceneHotspot() {}
+ int _resNum, _lookLineNum, _useLineNum, _talkLineNum;
+ NamedHotspot();
- void setup(int ys, int xs, int ye, int xe, const int resnum, const int lookLineNum, const int useLineNum);
virtual void doAction(int action);
virtual Common::String getClassName() { return "NamedHotspot"; }
virtual void synchronize(Serializer &s);
+ void setup(int ys, int xs, int ye, int xe, const int resnum, const int lookLineNum, const int useLineNum);
+ virtual void setup(const Rect &bounds, int resNum, int lookLineNum, int talkLineNum, int useLineNum, int mode, SceneItem *item);
+ virtual void setup(int sceneRegionId, int resNum, int lookLineNum, int talkLineNum, int useLineNum, int mode);
};
enum AnimateMode {ANIM_MODE_NONE = 0, ANIM_MODE_1 = 1, ANIM_MODE_2 = 2, ANIM_MODE_3 = 3,
@@ -567,27 +584,13 @@ public:
void setup(int visage, int stripFrameNum, int frameNum, int posX, int posY, int priority);
};
-class SceneObjectExt : public SceneObject {
+class AltSceneObject: public SceneObject {
public:
- int _state;
-
- virtual void synchronize(Serializer &s) {
- SceneObject::synchronize(s);
- s.syncAsSint16LE(_state);
- }
- 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 Common::String getClassName() { return "AltObjectExt"; }
virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void draw();
};
-
class SceneText : public SceneObject {
public:
int _fontNumber;
@@ -613,6 +616,7 @@ public:
bool _canWalk;
bool _uiEnabled;
int _field8C;
+ int _field8E;
public:
Player();
diff --git a/engines/tsage/events.cpp b/engines/tsage/events.cpp
index 44c79bd2fe..a6471dc8ab 100644
--- a/engines/tsage/events.cpp
+++ b/engines/tsage/events.cpp
@@ -270,6 +270,17 @@ void EventsClass::setCursor(Graphics::Surface &cursor, int transColor, const Com
_currentCursor = cursorId;
}
+void EventsClass::setCursor(GfxSurface &cursor) {
+ // TODO: Find proper parameters for this form in Blue Force
+ Graphics::Surface s = cursor.lockSurface();
+
+ const byte *cursorData = (const byte *)s.getBasePtr(0, 0);
+ CursorMan.replaceCursor(cursorData, cursor.getBounds().width(), cursor.getBounds().height(),
+ cursor._centroid.x, cursor._centroid.y, cursor._transColor);
+
+ _currentCursor = CURSOR_NONE;
+}
+
void EventsClass::setCursorFromFlag() {
setCursor(isCursorVisible() ? _currentCursor : CURSOR_NONE);
}
@@ -278,8 +289,10 @@ void EventsClass::showCursor() {
setCursor(_currentCursor);
}
-void EventsClass::hideCursor() {
+CursorType EventsClass::hideCursor() {
+ CursorType oldCursor = _currentCursor;
setCursor(CURSOR_NONE);
+ return oldCursor;
}
bool EventsClass::isCursorVisible() const {
diff --git a/engines/tsage/events.h b/engines/tsage/events.h
index c36db59270..db1941082d 100644
--- a/engines/tsage/events.h
+++ b/engines/tsage/events.h
@@ -67,6 +67,8 @@ enum CursorType {
CURSOR_NONE = -1, CURSOR_CROSSHAIRS = -2, CURSOR_ARROW = -3
};
+class GfxSurface;
+
class EventsClass : public SaveListener {
private:
Common::Event _event;
@@ -84,10 +86,11 @@ public:
void pushCursor(CursorType cursorType);
void popCursor();
void setCursor(Graphics::Surface &cursor, int transColor, const Common::Point &hotspot, CursorType cursorId);
+ void setCursor(GfxSurface &cursor);
void setCursorFromFlag();
CursorType getCursor() const { return _currentCursor; }
void showCursor();
- void hideCursor();
+ CursorType hideCursor();
bool isCursorVisible() const;
bool pollEvent();
diff --git a/engines/tsage/globals.cpp b/engines/tsage/globals.cpp
index 27067c7d1c..52bd42fc5c 100644
--- a/engines/tsage/globals.cpp
+++ b/engines/tsage/globals.cpp
@@ -121,6 +121,7 @@ Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screenSurface
case GType_BlueForce:
_game = new BlueForce::BlueForceGame();
+ _inventory = new BlueForce::BlueForceInvObjectList();
_sceneHandler = new BlueForce::SceneHandlerExt();
break;
}
@@ -186,6 +187,7 @@ BlueForceGlobals::BlueForceGlobals(): Globals() {
_interfaceY = 0;
_v51C44 = 1;
_v4CEA2 = 0;
+ _v4CEA4 = 0;
_v4CEA8 = 0;
_v4CEF2 = 0;
_v4CEF4 = 0;
@@ -195,7 +197,7 @@ BlueForceGlobals::BlueForceGlobals(): Globals() {
_v51C42 = 0;
_bikiniHutState = 0;
_mapLocationId = 1;
- Common::set_to(&_globalFlags[0], &_globalFlags[12], 0);
+ Common::set_to(_globalFlags, _globalFlags + 12, 0);
}
void BlueForceGlobals::synchronize(Serializer &s) {
@@ -204,11 +206,11 @@ void BlueForceGlobals::synchronize(Serializer &s) {
}
bool BlueForceGlobals::getFlag(int v) {
- return _globalFlags[v / 16] & (1 << (v % 8));
+ return _globalFlags[v / 8] & (1 << (v % 8));
}
void BlueForceGlobals::setFlag(int v) {
- _globalFlags[v / 16] |= 1 << (v % 8);
+ _globalFlags[v / 8] |= 1 << (v % 8);
}
} // end of namespace BlueForce
diff --git a/engines/tsage/globals.h b/engines/tsage/globals.h
index 2d409b6343..f5d4aaa16f 100644
--- a/engines/tsage/globals.h
+++ b/engines/tsage/globals.h
@@ -30,6 +30,7 @@
#include "tsage/events.h"
#include "tsage/sound.h"
#include "tsage/saveload.h"
+#include "tsage/blue_force/blueforce_ui.h"
namespace TsAGE {
@@ -113,7 +114,9 @@ using namespace TsAGE;
class BlueForceGlobals: public Globals {
public:
ASoundExt _sound1, _sound2, _sound3;
+ UIElements _uiElements;
int _v4CEA2;
+ int _v4CEA4;
int _v4CEA8;
int _v4CEF2;
int _v4CEF4;
diff --git a/engines/tsage/module.mk b/engines/tsage/module.mk
index 5c7104936e..ed6fb296a0 100644
--- a/engines/tsage/module.mk
+++ b/engines/tsage/module.mk
@@ -4,6 +4,8 @@ MODULE_OBJS := \
blue_force/blueforce_logic.o \
blue_force/blueforce_scenes0.o \
blue_force/blueforce_scenes1.o \
+ blue_force/blueforce_scenes3.o \
+ blue_force/blueforce_ui.o \
converse.o \
core.o \
debugger.o \
diff --git a/engines/tsage/ringworld/ringworld_logic.h b/engines/tsage/ringworld/ringworld_logic.h
index 73ecc9722b..69e5520581 100644
--- a/engines/tsage/ringworld/ringworld_logic.h
+++ b/engines/tsage/ringworld/ringworld_logic.h
@@ -35,19 +35,6 @@ 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); }
-#define ADD_PLAYER_MOVER_NULL(OBJ, X, Y) { Common::Point pt(X, Y); PlayerMover *mover = new PlayerMover(); \
- OBJ.addMover(mover, &pt, NULL); }
-#define ADD_PLAYER_MOVER_THIS(OBJ, X, Y) { Common::Point pt(X, Y); PlayerMover *mover = new PlayerMover(); \
- OBJ.addMover(mover, &pt, this); }
-
-#define ADD_MOVER(OBJ, X, Y) { Common::Point pt(X, Y); NpcMover *mover = new NpcMover(); \
- OBJ.addMover(mover, &pt, this); }
-#define ADD_MOVER_NULL(OBJ, X, Y) { Common::Point pt(X, Y); NpcMover *mover = new NpcMover(); \
- OBJ.addMover(mover, &pt, NULL); }
-
-
class SceneFactory {
public:
static Scene *createScene(int sceneNumber);
@@ -79,6 +66,17 @@ public:
}
};
+class SceneObjectExt : public SceneObject {
+public:
+ int _state;
+
+ virtual void synchronize(Serializer &s) {
+ SceneObject::synchronize(s);
+ s.syncAsSint16LE(_state);
+ }
+ virtual Common::String getClassName() { return "SceneObjectExt"; }
+};
+
class SceneArea : public SavedObject {
public:
GfxSurface _surface;
diff --git a/engines/tsage/saveload.h b/engines/tsage/saveload.h
index 03beafed7c..f81454d5e9 100644
--- a/engines/tsage/saveload.h
+++ b/engines/tsage/saveload.h
@@ -138,6 +138,18 @@ public:
}
}
}
+
+ void addBefore(T existingItem, T newItem) {
+ typename SynchronizedList<T>::iterator i = this->begin();
+ while ((i != this->end()) && (*i != existingItem)) ++i;
+ this->insert(i, newItem);
+ }
+ void addAfter(T existingItem, T newItem) {
+ typename SynchronizedList<T>::iterator i = this->begin();
+ while ((i != this->end()) && (*i != existingItem)) ++i;
+ if (i != this->end()) ++i;
+ this->insert(i, newItem);
+ }
};
/**
diff --git a/engines/tsage/sound.cpp b/engines/tsage/sound.cpp
index 0b77628801..2139056770 100644
--- a/engines/tsage/sound.cpp
+++ b/engines/tsage/sound.cpp
@@ -2456,7 +2456,7 @@ void ASound::unPrime() {
_action = NULL;
}
-void ASound::fade(int fadeDest, int fadeSteps, int fadeTicks, bool stopAfterFadeFlag, Action *action) {
+void ASound::fade(int fadeDest, int fadeSteps, int fadeTicks, bool stopAfterFadeFlag, EventHandler *action) {
if (action)
_action = action;
@@ -2485,10 +2485,19 @@ void ASoundExt::signal() {
}
}
-void ASoundExt::fadeOut2(Action *action) {
+void ASoundExt::fadeOut2(EventHandler *action) {
fade(0, 10, 10, true, action);
}
+void ASoundExt::changeSound(int soundNum) {
+ if (isPlaying()) {
+ _soundNum = soundNum;
+ fadeOut2(this);
+ } else {
+ fadeSound(soundNum);
+ }
+}
+
/*--------------------------------------------------------------------------*/
SoundDriver::SoundDriver() {
diff --git a/engines/tsage/sound.h b/engines/tsage/sound.h
index afcc8f6377..a8ff348bc6 100644
--- a/engines/tsage/sound.h
+++ b/engines/tsage/sound.h
@@ -365,7 +365,7 @@ public:
class ASound: public EventHandler {
public:
Sound _sound;
- Action *_action;
+ EventHandler *_action;
int _cueValue;
ASound();
@@ -385,7 +385,7 @@ public:
bool isMuted() const { return _sound.isMuted(); }
void pause(bool flag) { _sound.pause(flag); }
void mute(bool flag) { _sound.mute(flag); }
- void fade(int fadeDest, int fadeSteps, int fadeTicks, bool stopAfterFadeFlag, Action *action);
+ void fade(int fadeDest, int fadeSteps, int fadeTicks, bool stopAfterFadeFlag, EventHandler *action);
void fadeIn() { fade(127, 5, 10, false, NULL); }
void fadeOut(Action *action) { fade(0, 5, 10, true, action); }
void setTimeIndex(uint32 timeIndex) { _sound.setTimeIndex(timeIndex); }
@@ -406,7 +406,8 @@ public:
int _soundNum;
ASoundExt();
- void fadeOut2(Action *action);
+ void fadeOut2(EventHandler *action);
+ void changeSound(int soundNum);
virtual Common::String getClassName() { return "ASoundExt"; }
virtual void synchronize(Serializer &s);
diff --git a/engines/tsage/tsage.h b/engines/tsage/tsage.h
index 88175f92ce..7bb3c7a989 100644
--- a/engines/tsage/tsage.h
+++ b/engines/tsage/tsage.h
@@ -62,6 +62,7 @@ struct tSageGameDescription;
#define SCREEN_HEIGHT 200
#define SCREEN_CENTER_X 160
#define SCREEN_CENTER_Y 100
+#define BF_INTERFACE_Y 168
class TSageEngine : public Engine {
private: