[Scummvm-cvs-logs] scummvm master -> 734e4f628be88a37b09965dacc77e60152dca25d

dreammaster dreammaster at scummvm.org
Fri Aug 26 11:12:25 CEST 2011


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
734e4f628b TSAGE: Implemented lots more Blue Force functionality, and started on first in-game scene


Commit: 734e4f628be88a37b09965dacc77e60152dca25d
    https://github.com/scummvm/scummvm/commit/734e4f628be88a37b09965dacc77e60152dca25d
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2011-08-26T02:07:43-07:00

Commit Message:
TSAGE: Implemented lots more Blue Force functionality, and started on first in-game scene

Changed paths:
  A engines/tsage/blue_force/blueforce_scenes3.cpp
  A engines/tsage/blue_force/blueforce_scenes3.h
    engines/tsage/blue_force/blueforce_logic.cpp
    engines/tsage/blue_force/blueforce_logic.h
    engines/tsage/blue_force/blueforce_scenes1.h
    engines/tsage/blue_force/blueforce_ui.cpp
    engines/tsage/core.cpp
    engines/tsage/core.h
    engines/tsage/events.cpp
    engines/tsage/events.h
    engines/tsage/globals.cpp
    engines/tsage/globals.h
    engines/tsage/module.mk
    engines/tsage/ringworld/ringworld_logic.h
    engines/tsage/saveload.h
    engines/tsage/sound.cpp
    engines/tsage/sound.h
    engines/tsage/tsage.h



diff --git a/engines/tsage/blue_force/blueforce_logic.cpp b/engines/tsage/blue_force/blueforce_logic.cpp
index 82d70e5..60bbddb 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 SceneItemType1::startMove(SceneObject *sceneObj, va_list va) {
-	warning("TODO: sub_1621C");
+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 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,6 +294,124 @@ 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");
 
@@ -352,6 +506,142 @@ void SceneHandlerExt::process(Event &event) {
 
 /*--------------------------------------------------------------------------*/
 
+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),
diff --git a/engines/tsage/blue_force/blueforce_logic.h b/engines/tsage/blue_force/blueforce_logic.h
index 39f0b9b..d756d85 100644
--- a/engines/tsage/blue_force/blueforce_logic.h
+++ b/engines/tsage/blue_force/blueforce_logic.h
@@ -29,8 +29,6 @@
 #include "tsage/scenes.h"
 #include "tsage/globals.h"
 
-#define BF_INTERFACE_Y 168
-
 namespace TsAGE {
 
 namespace BlueForce {
@@ -71,27 +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 SceneItemType3: public SceneItemType1 {
+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 {
@@ -133,8 +173,44 @@ 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 {
diff --git a/engines/tsage/blue_force/blueforce_scenes1.h b/engines/tsage/blue_force/blueforce_scenes1.h
index 0769c6e..2b07e2b 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 0000000..696945b
--- /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: {
+		Common::Point pt(BF_GLOBALS._player._position.x - 8, BF_GLOBALS._player._position.y);
+		ADD_PLAYER_MOVER_THIS(BF_GLOBALS._player, pt.x, pt.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: {
+		Common::Point pt(BF_GLOBALS._player._position.x + 8, BF_GLOBALS._player._position.y);
+		ADD_MOVER(BF_GLOBALS._player, pt.x, pt.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 0000000..42ae69f
--- /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
index 9214f2b..e27c744 100644
--- a/engines/tsage/blue_force/blueforce_ui.cpp
+++ b/engines/tsage/blue_force/blueforce_ui.cpp
@@ -68,10 +68,7 @@ void UIQuestion::showDescription(int lineNum) {
 		// Unknown object description
 	} else {
 		// Display object description
-		SceneItem::display(9001, lineNum, SET_WIDTH, 312, SET_X, 4, 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);
+		SceneItem::display2(9001, lineNum);
 	}
 }
 
diff --git a/engines/tsage/core.cpp b/engines/tsage/core.cpp
index cb97a29..49abf29 100644
--- a/engines/tsage/core.cpp
+++ b/engines/tsage/core.cpp
@@ -1583,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) {
@@ -1606,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:
@@ -1615,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);
@@ -1631,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);
 }
 
 /*--------------------------------------------------------------------------*/
@@ -2323,22 +2380,6 @@ void AltSceneObject::draw() {
 
 /*--------------------------------------------------------------------------*/
 
-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;
diff --git a/engines/tsage/core.h b/engines/tsage/core.h
index d9fa59a..b1cbf74 100644
--- a/engines/tsage/core.h
+++ b/engines/tsage/core.h
@@ -162,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;
@@ -406,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 {
@@ -432,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,
@@ -579,27 +591,6 @@ public:
 	virtual void draw();
 };
 
-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 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;
diff --git a/engines/tsage/events.cpp b/engines/tsage/events.cpp
index 44c79bd..a6471dc 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 c36db59..db19410 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 b20280a..52bd42f 100644
--- a/engines/tsage/globals.cpp
+++ b/engines/tsage/globals.cpp
@@ -187,6 +187,7 @@ BlueForceGlobals::BlueForceGlobals(): Globals() {
 	_interfaceY = 0;
 	_v51C44 = 1;
 	_v4CEA2 = 0;
+	_v4CEA4 = 0;
 	_v4CEA8 = 0;
 	_v4CEF2 = 0;
 	_v4CEF4 = 0;
@@ -196,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) {
@@ -205,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 fb95f00..f5d4aaa 100644
--- a/engines/tsage/globals.h
+++ b/engines/tsage/globals.h
@@ -116,6 +116,7 @@ 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 2e775a6..ed6fb29 100644
--- a/engines/tsage/module.mk
+++ b/engines/tsage/module.mk
@@ -4,6 +4,7 @@ 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 \
diff --git a/engines/tsage/ringworld/ringworld_logic.h b/engines/tsage/ringworld/ringworld_logic.h
index 73ecc97..69e5520 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 03beafe..a15637d 100644
--- a/engines/tsage/saveload.h
+++ b/engines/tsage/saveload.h
@@ -138,6 +138,18 @@ public:
 			}
 		}
 	}
+
+	void addBefore(T existingItem, T newItem) {
+		SynchronizedList<T>::iterator i = this->begin();
+		while ((i != this->end()) && (*i != existingItem)) ++i;
+		this->insert(i, newItem);
+	}
+	void addAfter(T existingItem, T newItem) {
+		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 0b77628..2139056 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 afcc8f6..a8ff348 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 88175f9..7bb3c7a 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:






More information about the Scummvm-git-logs mailing list