aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS5
-rw-r--r--backends/events/sdl/sdl-events.cpp5
-rwxr-xr-xconfigure2
-rw-r--r--engines/bladerunner/actor.cpp277
-rw-r--r--engines/bladerunner/actor.h27
-rw-r--r--engines/bladerunner/actor_walk.cpp10
-rw-r--r--engines/bladerunner/bladerunner.cpp68
-rw-r--r--engines/bladerunner/bladerunner.h1
-rw-r--r--engines/bladerunner/gameflags.cpp2
-rw-r--r--engines/bladerunner/module.mk3
-rw-r--r--engines/bladerunner/movement_track.cpp40
-rw-r--r--engines/bladerunner/movement_track.h14
-rw-r--r--engines/bladerunner/scene.cpp12
-rw-r--r--engines/bladerunner/scene_objects.cpp10
-rw-r--r--engines/bladerunner/script/ai_00_mccoy.cpp13
-rw-r--r--engines/bladerunner/script/ai_00_mccoy.h11
-rw-r--r--engines/bladerunner/script/ai_15_runciter.cpp656
-rw-r--r--engines/bladerunner/script/ai_15_runciter.h65
-rw-r--r--engines/bladerunner/script/ai_23_officer_leroy.cpp1217
-rw-r--r--engines/bladerunner/script/ai_23_officer_leroy.h (renamed from engines/bladerunner/script/aiscript_officer_leroy.h)24
-rw-r--r--engines/bladerunner/script/aiscript_officer_leroy.cpp134
-rw-r--r--engines/bladerunner/script/script.cpp205
-rw-r--r--engines/bladerunner/script/script.h37
-rw-r--r--engines/director/archive.cpp8
-rw-r--r--engines/director/events.cpp24
-rw-r--r--engines/director/frame.cpp12
-rw-r--r--engines/director/lingo/lingo-builtins.cpp2
-rw-r--r--engines/director/lingo/lingo-funcs.cpp11
-rw-r--r--engines/director/lingo/lingo.cpp9
-rw-r--r--engines/director/resource.cpp70
-rw-r--r--engines/director/score.cpp66
-rw-r--r--engines/director/util.cpp2
-rw-r--r--engines/gnap/fontdata.h140
-rw-r--r--engines/gnap/gamesys.cpp11
-rw-r--r--engines/mohawk/detection_tables.h18
-rw-r--r--engines/mohawk/myst_scripts.cpp21
-rw-r--r--engines/mohawk/myst_stacks/channelwood.cpp2
-rw-r--r--engines/mohawk/myst_stacks/myst.cpp2
-rw-r--r--engines/sci/engine/script_patches.cpp256
-rw-r--r--engines/sci/engine/script_patches.h36
-rw-r--r--engines/titanic/star_control/base_star.cpp6
-rw-r--r--engines/titanic/star_control/base_star.h20
-rw-r--r--engines/titanic/star_control/dmatrix.cpp35
-rw-r--r--engines/titanic/star_control/dmatrix.h5
-rw-r--r--engines/titanic/star_control/dvector.cpp3
-rw-r--r--engines/titanic/star_control/dvector.h36
-rw-r--r--engines/titanic/star_control/fmatrix.cpp18
-rw-r--r--engines/titanic/star_control/fmatrix.h17
-rw-r--r--engines/titanic/star_control/fvector.cpp29
-rw-r--r--engines/titanic/star_control/fvector.h14
-rw-r--r--engines/titanic/star_control/star_control_sub12.cpp340
-rw-r--r--engines/titanic/star_control/star_control_sub12.h12
-rw-r--r--engines/titanic/star_control/star_control_sub13.cpp22
-rw-r--r--engines/titanic/star_control/star_control_sub20.cpp14
-rw-r--r--engines/titanic/star_control/star_control_sub20.h11
-rw-r--r--engines/titanic/star_control/star_control_sub21.cpp12
-rw-r--r--engines/titanic/star_control/star_control_sub21.h2
-rw-r--r--engines/titanic/star_control/star_control_sub22.cpp19
-rw-r--r--engines/titanic/star_control/star_control_sub22.h2
-rw-r--r--engines/titanic/star_control/star_control_sub23.cpp14
-rw-r--r--engines/titanic/star_control/star_control_sub23.h4
-rw-r--r--engines/titanic/star_control/star_control_sub24.cpp134
-rw-r--r--engines/titanic/star_control/star_control_sub24.h2
-rw-r--r--engines/titanic/star_control/star_control_sub25.cpp17
-rw-r--r--engines/titanic/star_control/star_control_sub25.h1
-rw-r--r--engines/titanic/star_control/star_control_sub26.cpp4
-rw-r--r--engines/titanic/star_control/star_control_sub26.h2
-rw-r--r--engines/titanic/star_control/star_control_sub27.cpp8
-rw-r--r--engines/titanic/star_control/star_control_sub27.h2
-rw-r--r--engines/titanic/star_control/star_control_sub5.cpp478
-rw-r--r--engines/titanic/star_control/star_control_sub5.h27
-rw-r--r--engines/titanic/star_control/star_control_sub6.cpp152
-rw-r--r--engines/titanic/star_control/star_control_sub6.h8
-rw-r--r--engines/titanic/star_control/star_control_sub7.cpp46
-rw-r--r--engines/titanic/star_control/star_control_sub8.cpp136
-rw-r--r--engines/titanic/star_control/star_control_sub8.h4
-rw-r--r--engines/titanic/star_control/star_field.cpp2
-rw-r--r--engines/titanic/star_control/star_points1.cpp2
-rw-r--r--engines/titanic/star_control/star_points2.cpp4
-rw-r--r--engines/titanic/star_control/star_ref.cpp3
-rw-r--r--engines/titanic/star_control/star_view.cpp2
-rw-r--r--gui/gui-manager.cpp2
-rw-r--r--gui/options.cpp2
83 files changed, 4303 insertions, 898 deletions
diff --git a/NEWS b/NEWS
index a3d3f1ed0e..6316de0b4b 100644
--- a/NEWS
+++ b/NEWS
@@ -39,6 +39,11 @@ Drascula:
MADS:
- Fixed a bug that caused a crash after starting Rex Nebular and the Cosmic Gender Bender.
+ SCI:
+ - Fixed a script bug in Laura Bow 2: Dagger of Amon Ra that made it impossible to exit the
+ party room with the large golden head inside the museum (room 350).
+ This bug is also present, when using the original interpreter.
+
TsAGE:
- Fixed recently introduced bug preventing animations in Return to Ringworld from playing.
diff --git a/backends/events/sdl/sdl-events.cpp b/backends/events/sdl/sdl-events.cpp
index a1657468a8..946a1af23f 100644
--- a/backends/events/sdl/sdl-events.cpp
+++ b/backends/events/sdl/sdl-events.cpp
@@ -545,11 +545,6 @@ bool SdlEventSource::dispatchSDLEvent(SDL_Event &ev, Common::Event &event) {
#if SDL_VERSION_ATLEAST(2, 0, 0)
case SDL_MOUSEWHEEL: {
Sint32 yDir = ev.wheel.y;
-#if SDL_VERSION_ATLEAST(2, 0, 4)
- if (ev.wheel.direction == SDL_MOUSEWHEEL_FLIPPED) {
- yDir *= -1;
- }
-#endif
// HACK: It seems we want the mouse coordinates supplied
// with a mouse wheel event. However, SDL2 does not supply
// these, thus we use whatever we got last time. It seems
diff --git a/configure b/configure
index d958c0e411..57607bb53b 100755
--- a/configure
+++ b/configure
@@ -2791,7 +2791,7 @@ if test -n "$_host"; then
_mt32emu=no
_timidity=no
;;
- androidsdl | androidsdl-armeabi | androidsdl-armeabi-v7a | androidsdl-mips | androidsdl-x86 | androidsdl-arm64-v8a)
+ androidsdl | androidsdl-armeabi | androidsdl-armeabi-v7a | androidsdl-mips | androidsdl-x86 | androidsdl-arm64-v8a | androidsdl-x86_64)
DEFINES="$DEFINES -DANDROIDSDL"
_unix=yes
_seq_midi=no
diff --git a/engines/bladerunner/actor.cpp b/engines/bladerunner/actor.cpp
index 9a8892cf6c..597dc60454 100644
--- a/engines/bladerunner/actor.cpp
+++ b/engines/bladerunner/actor.cpp
@@ -91,6 +91,9 @@ void Actor::setup(int actorId) {
_retiredWidth = 0;
_retiredHeight = 0;
+ _movementTrackWalkingToWaypointId = -1;
+ _movementTrackDelayOnNextWaypoint = -1;
+
for (int i = 0; i != 7; ++i) {
_timersRemain[i] = 0;
_timersStart[i] = _vm->getTotalPlayTime();
@@ -107,6 +110,12 @@ void Actor::setup(int actorId) {
_maxHP = 50;
_goalNumber = -1;
+ _movementTrackPaused = false;
+ _movementTrackNextWaypointId = -1;
+ _movementTrackNextDelay = -1;
+ _movementTrackNextAngle = -1;
+ _movementTrackNextRunning = false;
+
_timersRemain[4] = 60000;
_animationMode = -1;
_screenRectangle = Common::Rect(-1, -1, -1, -1);
@@ -151,30 +160,174 @@ void Actor::setFPS(int fps) {
}
}
-void Actor::processMovement() {
- /*if (movementTrack::is_paused(this->movementTrack) != 1 && this->id)
- {
- if (this->walkingWaypointId >= 0 && this->timeoutWalkingWaypoint >= 0)
- {
- worldWaypoints::get_sceneId(WorldWaypoints, this->walkingWaypointId);
- if (!this->timeoutWalkingWaypoint)
- {
- this->timeoutWalkingWaypoint = 1;
+void Actor::countdownTimerStart(int timerId, int interval) {
+ assert(timerId >= 0 && timerId < 7);
+ _timersRemain[timerId] = interval;
+ _timersStart[timerId] = _vm->getTotalPlayTime();
+}
+
+void Actor::countdownTimerReset(int timerId) {
+ assert(timerId >= 0 && timerId < 7);
+ _timersRemain[timerId] = 0;
+}
+
+int Actor::countdownTimerGetRemainingTime(int timerId) {
+ assert(timerId >= 0 && timerId < 7);
+ return _timersRemain[timerId];
+}
+
+void Actor::countdownTimersUpdate() {
+ for (int i = 0; i <= 6; i++) {
+ countdownTimerUpdate(i);
+ }
+}
+
+void Actor::countdownTimerUpdate(int timerId) {
+ if (_timersRemain[timerId] == 0) {
+ return;
+ }
+
+ uint32 now = _vm->getTotalPlayTime();
+ int tickInterval = now - _timersStart[timerId];
+ _timersStart[timerId] = now;
+
+ //warning("tickInterval: %d", tickInterval);
+ _timersRemain[timerId] -= tickInterval;
+
+ if (_timersRemain[timerId] <= 0) {
+ switch (timerId) {
+ case 0:
+ case 1:
+ case 2:
+ if (!_vm->_aiScripts->IsInsideScript() && !_vm->_script->IsInsideScript()) {
+ _vm->_aiScripts->TimerExpired(this->_id, timerId);
+ this->_timersRemain[timerId] = 0;
+ } else {
+ this->_timersRemain[timerId] = 1;
+ }
+ break;
+ case 3:
+ _timersRemain[3] = 0;
+ if (_movementTrack->isPaused()) {
+ _timersRemain[3] = 1;
+ } else {
+ movementTrackNext(false);
+ }
+ break;
+ case 4:
+ // Something timer
+ break;
+ case 5:
+ // Actor animation frame timer
+ break;
+ case 6:
+ if (isRunning()) {
+ if (_fps > 15) {
+ int newFps = _fps - 2;
+ if (newFps < 15) {
+ newFps = 15;
+ }
+ setFPS(newFps);
+ }
+ }
+ _timersRemain[6] = 200;
+ break;
+ }
+ }
+}
+
+void Actor::movementTrackNext(bool omitAiScript) {
+ bool hasNextMovement;
+ int waypointSetId;
+ int running;
+ int angle;
+ int delay;
+ int waypointId;
+ Vector3 waypointPosition;
+ bool stopped;
+
+ hasNextMovement = _movementTrack->next(&waypointId, &delay, &angle, &running);
+ _movementTrackNextWaypointId = waypointId;
+ _movementTrackNextDelay = delay;
+ _movementTrackNextAngle = angle;
+ _movementTrackNextRunning = running;
+ if (hasNextMovement) {
+ if (angle == -1) {
+ angle = 0;
+ }
+ waypointSetId = _vm->_waypoints->getSetId(waypointId);
+ _vm->_waypoints->getXYZ(waypointId, &waypointPosition.x, &waypointPosition.y, &waypointPosition.z);
+ if (_setId == waypointSetId && waypointSetId == _vm->_actors[0]->_setId) {
+ stopWalking(false);
+ _walkInfo->setup(_id, running, _position, waypointPosition, false, &stopped);
+
+ _movementTrackWalkingToWaypointId = waypointId;
+ _movementTrackDelayOnNextWaypoint = delay;
+ if (stopped) {
+ movementTrackWaypointReached();
+ }
+ } else {
+ setSetId(waypointSetId);
+ setAtXYZ(waypointPosition, angle, true, false, false);
+
+ if (!delay) {
+ delay = 1;
+ }
+ if (delay > 1) {
+ changeAnimationMode(0, false);
+ }
+ countdownTimerStart(3, delay);
+ }
+ //return true;
+ } else {
+ if (!omitAiScript) {
+ _vm->_aiScripts->CompletedMovementTrack(_id);
+ }
+ //return false;
+ }
+}
+
+void Actor::movementTrackPause() {
+ _movementTrack->pause();
+ if (isWalking()) {
+ _movementTrackPaused = true;
+ stopWalking(false);
+ } else {
+ _movementTrackPaused = false;
+ }
+}
+
+void Actor::movementTrackUnpause() {
+ Vector3 waypointPosition;
+ bool stopped;
+
+ _movementTrack->unpause();
+ if (_movementTrackNextWaypointId >= 0 && _movementTrackPaused) {
+ _vm->_waypoints->getXYZ(_movementTrackNextWaypointId, &waypointPosition.x, &waypointPosition.y, &waypointPosition.z);
+ _walkInfo->setup(_id, _movementTrackNextRunning, _position, waypointPosition, false, &stopped);
+ _movementTrackPaused = false;
+ }
+}
+
+void Actor::movementTrackWaypointReached() {
+ int seconds;
+ if (!_movementTrack->isPaused() && _id != 0) {
+ if (_movementTrackWalkingToWaypointId >= 0 && _movementTrackDelayOnNextWaypoint) {
+ if (!_movementTrackDelayOnNextWaypoint) {
+ _movementTrackDelayOnNextWaypoint = 1;
}
- if (actorScript::call_ReachedMovementTrackWaypoint(ActorScript, this->id, this->walkingWaypointId) == 1)
- {
- seconds = this->timeoutWalkingWaypoint;
- if (seconds > 1)
- {
- actor::changeAnimationMode(this, 0, 0);
- seconds = this->timeoutWalkingWaypoint;
+ if (_vm->_aiScripts->ReachedMovementTrackWaypoint(_id, _movementTrackWalkingToWaypointId)) {
+ seconds = _movementTrackDelayOnNextWaypoint;
+ if (seconds > 1) {
+ changeAnimationMode(0, false);
+ seconds = _movementTrackDelayOnNextWaypoint; // todo: analyze if movement is changed in some aiscript->ChangeAnimationMode?
}
- actor::startTimer(this, 3, seconds);
+ countdownTimerStart(3, seconds);
}
}
- this->walkingWaypointId = -1;
- this->timeoutWalkingWaypoint = 0;
- }*/
+ _movementTrackWalkingToWaypointId = -1;
+ _movementTrackDelayOnNextWaypoint = 0;
+ }
}
bool Actor::loopWalkToActor(int otherActorId, int destinationOffset, int a3, bool run, bool a5, bool *isRunning) {
@@ -203,10 +356,10 @@ void Actor::setAtXYZ(const Vector3 &position, int facing, bool snapFacing, bool
setBoundingBox(_position, retired);
- _vm->_sceneObjects->remove(_id);
+ _vm->_sceneObjects->remove(_id + SCENE_OBJECTS_ACTORS_OFFSET);
if (_vm->_scene->getSetId() == _setId) {
- _vm->_sceneObjects->addActor(_id, _bbox, &_screenRectangle, 1, moving, _isTargetable, retired);
+ _vm->_sceneObjects->addActor(_id + SCENE_OBJECTS_ACTORS_OFFSET, _bbox, &_screenRectangle, 1, moving, _isTargetable, retired);
}
}
@@ -375,10 +528,8 @@ bool Actor::loopWalkToSceneObject(const char *objectName, int destinationOffset,
}
bool Actor::loopWalkToWaypoint(int waypointId, int destinationOffset, int a3, bool run, bool a5, bool *isRunning) {
- float x, y, z;
- _vm->_waypoints->getXYZ(waypointId, &x, &y, &z);
- Vector3 waypointPosition(x, y, z);
-
+ Vector3 waypointPosition;
+ _vm->_waypoints->getXYZ(waypointId, &waypointPosition.x, &waypointPosition.y, &waypointPosition.z);
return loopWalk(waypointPosition, destinationOffset, a3, run, _position, 0.0f, 24.0f, a5, isRunning, false);
}
@@ -432,7 +583,7 @@ bool Actor::tick(bool forceDraw) {
if (walked) {
_vm->_actors[_id]->changeAnimationMode(0);
- this->processMovement();
+ this->movementTrackWaypointReached();
if (this->inCombat()) {
this->changeAnimationMode(this->_combatAnimationMode, false);
} else {
@@ -477,7 +628,7 @@ bool Actor::tick(bool forceDraw) {
this->_position.z = this->_position.z + positionChange.x * sinx + positionChange.y * cosx;
this->_position.y = this->_position.y + positionChange.z;
- if (_vm->_sceneObjects->existsOnXZ(this->_id, this->_position.x, this->_position.z, false, false) == 1 && !this->_isImmuneToObstacles) {
+ if (_vm->_sceneObjects->existsOnXZ(this->_id + SCENE_OBJECTS_ACTORS_OFFSET, this->_position.x, this->_position.z, false, false) == 1 && !this->_isImmuneToObstacles) {
this->_position.x = originalX;
this->_position.y = originalY;
this->_position.z = originalZ;
@@ -530,16 +681,16 @@ void Actor::setSetId(int setId) {
if (_setId > 0) {
for (i = 0; i < (int)_vm->_gameInfo->getActorCount(); i++) {
if (_vm->_actors[i]->_id != _id && _vm->_actors[i]->_setId == _setId) {
- // TODO: _vm->_aiScripts->OtherAgentExitedThisScene( i, _id);
+ _vm->_aiScripts->OtherAgentExitedThisScene(i, _id);
}
}
}
_setId = setId;
- // TODO: _vm->_aiScripts->EnteredScene(_id, set);
+ _vm->_aiScripts->EnteredScene(_id, _setId);
if (_setId > 0) {
for (i = 0; i < (int)_vm->_gameInfo->getActorCount(); i++) {
if (_vm->_actors[i]->_id != _id && _vm->_actors[i]->_setId == _setId) {
- // TODO: _vm->_aiScripts->OtherAgentEnteredThisScene(i, _id);
+ _vm->_aiScripts->OtherAgentEnteredThisScene(i, _id);
}
}
}
@@ -613,6 +764,10 @@ bool Actor::isWalking() {
return _walkInfo->isWalking();
}
+bool Actor::isRunning() {
+ return _walkInfo->isRunning();
+}
+
void Actor::stopWalking(bool value) {
if (value && _id == 0) {
_vm->_playerActorIdle = true;
@@ -851,12 +1006,14 @@ int Actor::getAnimationMode() {
}
void Actor::setGoal(int goalNumber) {
- if (goalNumber == _goalNumber)
+ int oldGoalNumber = _goalNumber;
+ _goalNumber = goalNumber;
+ if (goalNumber == oldGoalNumber) {
return;
+ }
- //TODO: _vm->actorScript->GoalChanged(_id, _goalNumber, goalNumber);
-
- _vm->_script->ActorChangedGoal(_id, goalNumber, _goalNumber, _vm->_scene->getSetId() == _setId);
+ _vm->_aiScripts->GoalChanged(_id, oldGoalNumber, goalNumber);
+ _vm->_script->ActorChangedGoal(_id, goalNumber, oldGoalNumber, _vm->_scene->getSetId() == _setId);
}
int Actor::getGoal() {
@@ -927,56 +1084,6 @@ int Actor::soundBalance() {
return 127.0f * (MAX(MIN(screenPosition.x / 640.0f, 1.0f), 0.0f) * 2.0f - 1.0f);
}
-void Actor::countdownTimerStart(int timerId, int interval) {
- assert(timerId >= 0 && timerId < 7);
- _timersRemain[timerId] = interval;
- _timersStart[timerId] = _vm->getTotalPlayTime();
-}
-
-void Actor::countdownTimerReset(int timerId) {
- assert(timerId >= 0 && timerId < 7);
- _timersRemain[timerId] = 0;
-}
-
-int Actor::countdownTimerGetRemainingTime(int timerId) {
- assert(timerId >= 0 && timerId < 7);
- return _timersRemain[timerId];
-}
-
-void Actor::countdownTimerUpdate(int timerId) {
- if (_timersRemain[timerId] == 0)
- return;
-
- uint32 now = _vm->getTotalPlayTime();
- int tickInterval = now - _timersStart[timerId];
- _timersStart[timerId] = now;
-
- // warning("tickInterval: %d", tickInterval);
- _timersRemain[timerId] -= tickInterval;
-
- if (_timersRemain[timerId] <= 0) {
- switch (timerId) {
- case 0:
- case 1:
- case 2:
- // AI timers, call AI dll
- break;
- case 3:
- // Movement track timer
- break;
- case 4:
- // Something timer
- break;
- case 5:
- // Actor animation frame timer
- break;
- case 6:
- // Slow down actor run timer?
- break;
- }
- }
-}
-
bool Actor::walkFindU1(const Vector3 &startPosition, const Vector3 &targetPosition, float size, Vector3 *newDestination) {
newDestination->x = 0.0f;
newDestination->y = 0.0f;
diff --git a/engines/bladerunner/actor.h b/engines/bladerunner/actor.h
index b2b52c623d..d924730b4b 100644
--- a/engines/bladerunner/actor.h
+++ b/engines/bladerunner/actor.h
@@ -78,6 +78,16 @@ private:
bool _isMoving;
bool _damageAnimIfMoving;
+ // Movement
+ bool _movementTrackPaused;
+ int _movementTrackNextWaypointId;
+ int _movementTrackNextDelay; // probably not used
+ int _movementTrackNextAngle; // probably not used
+ bool _movementTrackNextRunning;
+
+ int _movementTrackWalkingToWaypointId;
+ int _movementTrackDelayOnNextWaypoint;
+
// Animation
int _width;
int _height;
@@ -122,7 +132,16 @@ public:
void changeAnimationMode(int animationMode, bool force = false);
void setFPS(int fps);
- void processMovement();
+ void countdownTimerStart(int timerId, int interval);
+ void countdownTimerReset(int timerId);
+ int countdownTimerGetRemainingTime(int timerId);
+ void countdownTimersUpdate();
+ void countdownTimerUpdate(int timerId);
+
+ void movementTrackNext(bool omitAiScript);
+ void movementTrackPause();
+ void movementTrackUnpause();
+ void movementTrackWaypointReached();
bool loopWalkToActor(int otherActorId, int destinationOffset, int a3, bool run, bool a5, bool *isRunning);
bool loopWalkToItem(int itemId, int destinationOffset, int a3, bool run, bool a5, bool *isRunning);
@@ -133,11 +152,6 @@ public:
bool tick(bool forceUpdate);
void draw();
- void countdownTimerStart(int timerId, int interval);
- void countdownTimerReset(int timerId);
- int countdownTimerGetRemainingTime(int timerId);
- void countdownTimerUpdate(int timerId);
-
int getSetId();
void setSetId(int setId);
BoundingBox *getBoundingBox() { return _bbox; }
@@ -151,6 +165,7 @@ public:
bool isMoving() { return _isMoving; }
void setMoving(bool value) { _isMoving = value; }
bool isWalking();
+ bool isRunning();
void stopWalking(bool value);
void faceActor(int otherActorId, bool animate);
diff --git a/engines/bladerunner/actor_walk.cpp b/engines/bladerunner/actor_walk.cpp
index 556f7b9afa..6287ac8ad0 100644
--- a/engines/bladerunner/actor_walk.cpp
+++ b/engines/bladerunner/actor_walk.cpp
@@ -146,7 +146,7 @@ void ActorWalk::setRunning() {
}
void ActorWalk::stop(int actorId, bool unknown, int combatAnimationMode, int animationMode) {
- _vm->_sceneObjects->setMoving(actorId, false);
+ _vm->_sceneObjects->setMoving(actorId + SCENE_OBJECTS_ACTORS_OFFSET, false);
_vm->_actors[actorId]->setMoving(false);
if (_vm->_actors[actorId]->inCombat()) {
@@ -173,7 +173,7 @@ bool ActorWalk::isXYZEmpty(float x, float y, float z, int actorId) {
if (_vm->_actors[actorId]->isImmuneToObstacles()) {
return false;
}
- return _vm->_sceneObjects->existsOnXZ(actorId, x, z, false, false);
+ return _vm->_sceneObjects->existsOnXZ(actorId + SCENE_OBJECTS_ACTORS_OFFSET, x, z, false, false);
}
int ActorWalk::findU1(int actorId, const Vector3 &to, int dist, Vector3 *out) {
@@ -206,14 +206,14 @@ int ActorWalk::findU1(int actorId, const Vector3 &to, int dist, Vector3 *out) {
x = to.x + sin_1024(v24) * dist;
z = to.z + cos_1024(v24) * dist;
- if (!_vm->_sceneObjects->existsOnXZ(actorId, x, z, true, true) && _vm->_scene->_set->findWalkbox(x, z) >= 0) {
+ if (!_vm->_sceneObjects->existsOnXZ(actorId + SCENE_OBJECTS_ACTORS_OFFSET, x, z, true, true) && _vm->_scene->_set->findWalkbox(x, z) >= 0) {
break;
}
x = to.x + sin_1024(v23) * dist;
z = to.z + cos_1024(v23) * dist;
- if (!_vm->_sceneObjects->existsOnXZ(actorId, x, z, true, true) && _vm->_scene->_set->findWalkbox(x, z) >= 0) {
+ if (!_vm->_sceneObjects->existsOnXZ(actorId + SCENE_OBJECTS_ACTORS_OFFSET, x, z, true, true) && _vm->_scene->_set->findWalkbox(x, z) >= 0) {
break;
}
@@ -252,7 +252,7 @@ int ActorWalk::nextOnPath(int actorId, const Vector3 &from, const Vector3 &to, V
if (_vm->_scene->_set->findWalkbox(to.x, to.z) == -1) {
return 0;
}
- if (_vm->_sceneObjects->existsOnXZ(actorId, to.x, to.z, false, false)) {
+ if (_vm->_sceneObjects->existsOnXZ(actorId + SCENE_OBJECTS_ACTORS_OFFSET, to.x, to.z, false, false)) {
return 0;
}
Vector3 next1;
diff --git a/engines/bladerunner/bladerunner.cpp b/engines/bladerunner/bladerunner.cpp
index e60fe77d26..6a06422a24 100644
--- a/engines/bladerunner/bladerunner.cpp
+++ b/engines/bladerunner/bladerunner.cpp
@@ -60,7 +60,7 @@
#include "engines/util.h"
#include "graphics/pixelformat.h"
-#include "suspects_database.h"
+#include "suspects_database.h"
namespace BladeRunner {
@@ -337,7 +337,7 @@ bool BladeRunnerEngine::startup(bool hasSavegames) {
initScript.SCRIPT_Initialize_Game();
// TODO: Load AI-ACT1.DLL
- _aiScripts = new AIScripts(this);
+ _aiScripts = new AIScripts(this, actorCount);
initChapterAndScene();
@@ -488,6 +488,9 @@ void BladeRunnerEngine::shutdown() {
delete _actors[i];
_actors[i] = nullptr;
}
+ delete _actors[VOICEOVER_ACTOR];
+ _actors[VOICEOVER_ACTOR] = nullptr;
+
_playerActor = nullptr;
// TODO: Delete proper ZBuf class
@@ -619,17 +622,20 @@ void BladeRunnerEngine::gameTick() {
#endif
// TODO: Render overlays
- // TODO: Tick Actor AI and Timers
- if (_settings->getNewScene() == -1 || _script->_inScriptCounter /* || in_ai */) {
+ //if (!dialogueMenu)
+ actorsUpdate();
+
+ if (_settings->getNewScene() == -1 || _script->IsInsideScript() || _aiScripts->IsInsideScript()) {
_sliceRenderer->setView(*_view);
// Tick and draw all actors in current set
- //int setId = _scene->_setId;
+ int setId = _scene->getSetId();
for (int i = 0, end = _gameInfo->getActorCount(); i != end; ++i) {
- //if (_actors[i]->getSetId() == setId) {
- if (i == 0 || i == 23) { // Currently limited to McCoy and Officer Leroy
- _actors[i]->tick(backgroundChanged);
+ if (_actors[i]->getSetId() == setId) {
+ if (i == 0 || i == 15 || i == 23) { // Currently limited to McCoy, Runciter and Officer Leroy
+ _actors[i]->tick(backgroundChanged);
+ }
}
}
@@ -724,16 +730,30 @@ void BladeRunnerEngine::gameTick() {
}
- for (int i = 0; i < (int)_lights->_lights.size(); i++) {
- Light *light = _lights->_lights[i];
- Matrix4x3 m = light->_matrix;
- Vector3 pos = Vector3(m(0, 3), m(1, 3), m(2, 3));
+// for (int i = 0; i < (int)_lights->_lights.size(); i++) {
+// Light *light = _lights->_lights[i];
+// Matrix4x3 m = light->_matrix;
+// Vector3 pos = Vector3(m(0, 3), m(1, 3), m(2, 3));
+// Vector3 size = Vector3(5.0f, 5.0f, 5.0f);
+// int colorR = (light->_color.r * 31.0f);
+// int colorG = (light->_color.g * 31.0f);
+// int colorB = (light->_color.b * 31.0f);
+// int color = (colorR << 10) + (colorG << 5) + colorB;
+// drawBBox(pos - size, pos + size, _view, &_surface2, color);
+// }
+
+ for(int i = 0; i < _waypoints->_count; i++) {
+ Waypoint *waypoint = &_waypoints->_waypoints[i];
+ if(waypoint->_setId != _scene->getSetId())
+ continue;
+ Vector3 pos = waypoint->_position;
Vector3 size = Vector3(5.0f, 5.0f, 5.0f);
- int colorR = (light->_color.r * 31.0f);
- int colorG = (light->_color.g * 31.0f);
- int colorB = (light->_color.b * 31.0f);
- int color = (colorR << 10) + (colorG << 5) + colorB;
+ int color = 0b111111111111111;
drawBBox(pos - size, pos + size, _view, &_surface2, color);
+ Vector3 spos = _view->calculateScreenPosition(pos);
+ char waypointText[40];
+ sprintf(waypointText, "waypoint %i", i);
+ _mainFont->drawColor(waypointText, _surface2, spos.x, spos.y, color);
}
#endif
@@ -745,6 +765,22 @@ void BladeRunnerEngine::gameTick() {
}
}
+void BladeRunnerEngine::actorsUpdate() {
+ int actorCount = (int)_gameInfo->getActorCount();
+ int setId = _scene->getSetId();
+
+ //TODO: original game updates every non-visible characters by updating only one character in one frame
+ if (setId != 89 || _gameVars[1] != 4 || _gameFlags->query(670) != 1 || !_aiScripts->IsInsideScript()) {
+ for (int i = 0; i < actorCount; i++) {
+ Actor *actor = _actors[i];
+ if (actor->getSetId() == setId) {
+ _aiScripts->Update(i);
+ actor->countdownTimersUpdate();
+ }
+ }
+ }
+}
+
void BladeRunnerEngine::handleEvents() {
if (shouldQuit()) {
_gameIsRunning = false;
diff --git a/engines/bladerunner/bladerunner.h b/engines/bladerunner/bladerunner.h
index 23ea88b43a..0aab57625b 100644
--- a/engines/bladerunner/bladerunner.h
+++ b/engines/bladerunner/bladerunner.h
@@ -155,6 +155,7 @@ public:
void gameLoop();
void gameTick();
+ void actorsUpdate();
void handleEvents();
void handleMouseClick(int x, int y);
void handleMouseClickExit(int x, int y, int exitIndex);
diff --git a/engines/bladerunner/gameflags.cpp b/engines/bladerunner/gameflags.cpp
index db4271d9d5..0e04a1c49d 100644
--- a/engines/bladerunner/gameflags.cpp
+++ b/engines/bladerunner/gameflags.cpp
@@ -59,7 +59,7 @@ void GameFlags::reset(int flag) {
}
bool GameFlags::query(int flag) {
- debug("GameFlags::query(%d): %d", flag, !!(flags[flag / 32] & (1 << (flag % 32))));
+ //debug("GameFlags::query(%d): %d", flag, !!(flags[flag / 32] & (1 << (flag % 32))));
assert(flag >= 0 && flag <= flagCount);
return !!(flags[flag / 32] & (1 << (flag % 32)));
diff --git a/engines/bladerunner/module.mk b/engines/bladerunner/module.mk
index fb656efac1..f8394e9318 100644
--- a/engines/bladerunner/module.mk
+++ b/engines/bladerunner/module.mk
@@ -39,7 +39,8 @@ MODULE_OBJS = \
scene.o \
scene_objects.o \
script/ai_00_mccoy.o \
- script/aiscript_officer_leroy.o \
+ script/ai_15_runciter.o \
+ script/ai_23_officer_leroy.o \
script/init.o \
script/kia.o \
script/vk.o \
diff --git a/engines/bladerunner/movement_track.cpp b/engines/bladerunner/movement_track.cpp
index bd74116566..702a1187f1 100644
--- a/engines/bladerunner/movement_track.cpp
+++ b/engines/bladerunner/movement_track.cpp
@@ -34,9 +34,9 @@ MovementTrack::~MovementTrack() {
void MovementTrack::reset() {
_currentIndex = -1;
- _lastIndex = -1;
- _hasNext = 0;
- _paused = 0;
+ _lastIndex = 0;
+ _hasNext = false;
+ _paused = false;
for (int i = 0; i < 100; i++) {
_entries[i].waypointId = -1;
_entries[i].delay = -1;
@@ -49,9 +49,10 @@ int MovementTrack::append(int waypointId, int delay, int running) {
return append(waypointId, delay, -1, running);
}
-int MovementTrack::append(int waypointId, int delay, int angle, int running) {
- if (_lastIndex >= ARRAYSIZE(_entries))
+int MovementTrack::append(int waypointId, int delay, int angle, int running) {
+ if (_lastIndex >= 100) {
return 0;
+ }
_entries[_lastIndex].waypointId = waypointId;
_entries[_lastIndex].delay = delay;
@@ -59,7 +60,7 @@ int MovementTrack::append(int waypointId, int delay, int angle, int running) {
_entries[_lastIndex].running = running;
_lastIndex++;
- _hasNext = 1;
+ _hasNext = true;
_currentIndex = 0;
return 1;
}
@@ -70,42 +71,39 @@ void MovementTrack::flush() {
void MovementTrack::repeat() {
_currentIndex = 0;
- _hasNext = 1;
+ _hasNext = true;
}
-int MovementTrack::pause() {
- _paused = 1;
- return 1;
+void MovementTrack::pause() {
+ _paused = true;
}
-int MovementTrack::unpause() {
- _paused = 0;
- return 1;
+void MovementTrack::unpause() {
+ _paused = false;
}
-int MovementTrack::isPaused() {
+bool MovementTrack::isPaused() {
return _paused;
}
-int MovementTrack::hasNext() {
+bool MovementTrack::hasNext() {
return _hasNext;
}
-int MovementTrack::next(int *waypointId, int *delay, int *angle, int *running) {
- if (_currentIndex < _lastIndex && this->_hasNext)
- {
+bool MovementTrack::next(int *waypointId, int *delay, int *angle, int *running) {
+ if (_currentIndex < _lastIndex && _hasNext) {
*waypointId = _entries[_currentIndex].waypointId;
*delay = _entries[_currentIndex].delay;
*angle = _entries[_currentIndex].angle;
*running = _entries[_currentIndex++].running;
- return 1;
+ return true;
} else {
*waypointId = -1;
*delay = -1;
*angle = -1;
*running = 0;
- _hasNext = 0;
- return 0;
+ _hasNext = false;
+ return false;
}
}
diff --git a/engines/bladerunner/movement_track.h b/engines/bladerunner/movement_track.h
index 450592210a..bffac4855a 100644
--- a/engines/bladerunner/movement_track.h
+++ b/engines/bladerunner/movement_track.h
@@ -43,8 +43,8 @@ class MovementTrack {
private:
int _currentIndex;
int _lastIndex;
- int _hasNext;
- int _paused;
+ bool _hasNext;
+ bool _paused;
MovementTrackEntry _entries[100];
void reset();
@@ -55,11 +55,11 @@ public:
int append(int waypointId, int delay, int angle, int running);
void flush();
void repeat();
- int pause();
- int unpause();
- int isPaused();
- int hasNext();
- int next(int *waypointId, int *delay, int *angle, int *running);
+ void pause();
+ void unpause();
+ bool isPaused();
+ bool hasNext();
+ bool next(int *waypointId, int *delay, int *angle, int *running);
//int saveGame();
};
diff --git a/engines/bladerunner/scene.cpp b/engines/bladerunner/scene.cpp
index c29a6345cc..abf0285660 100644
--- a/engines/bladerunner/scene.cpp
+++ b/engines/bladerunner/scene.cpp
@@ -108,7 +108,7 @@ bool Scene::open(int setId, int sceneId, bool isLoadingGame) {
_vm->_scene->advanceFrame(_vm->_surface1, _vm->_zBuffer1);
_vm->_playerActor->setAtXYZ(_actorStartPosition, _actorStartFacing);
- //_vm->_playerActor->setSetId(setId);
+ _vm->_playerActor->setSetId(setId);
_vm->_script->SceneLoaded();
@@ -120,7 +120,7 @@ bool Scene::open(int setId, int sceneId, bool isLoadingGame) {
Actor *actor = _vm->_actors[i];
if (actor->getSetId() == setId) {
_vm->_sceneObjects->addActor(
- i,
+ i + SCENE_OBJECTS_ACTORS_OFFSET,
actor->getBoundingBox(),
actor->getScreenRectangle(),
1,
@@ -251,14 +251,14 @@ bool Scene::objectGetBoundingBox(int objectId, BoundingBox *boundingBox) {
void Scene::objectSetIsClickable(int objectId, bool isClickable, bool sceneLoaded) {
_set->objectSetIsClickable(objectId, isClickable);
if (sceneLoaded) {
- _vm->_sceneObjects->setIsClickable(objectId + 198, isClickable);
+ _vm->_sceneObjects->setIsClickable(objectId + SCENE_OBJECTS_OBJECTS_OFFSET, isClickable);
}
}
void Scene::objectSetIsObstacle(int objectId, bool isObstacle, bool sceneLoaded, bool updateWalkpath) {
_set->objectSetIsObstacle(objectId, isObstacle);
if (sceneLoaded) {
- _vm->_sceneObjects->setIsObstacle(objectId + 198, isObstacle);
+ _vm->_sceneObjects->setIsObstacle(objectId + SCENE_OBJECTS_OBJECTS_OFFSET, isObstacle);
if (updateWalkpath) {
_vm->_sceneObjects->updateObstacles();
}
@@ -270,7 +270,7 @@ void Scene::objectSetIsObstacleAll(bool isObstacle, bool sceneLoaded) {
for (i = 0; i < (int)_set->getObjectCount(); i++) {
_set->objectSetIsObstacle(i, isObstacle);
if (sceneLoaded) {
- _vm->_sceneObjects->setIsObstacle(i + 198, isObstacle);
+ _vm->_sceneObjects->setIsObstacle(i + SCENE_OBJECTS_OBJECTS_OFFSET, isObstacle);
}
}
}
@@ -278,7 +278,7 @@ void Scene::objectSetIsObstacleAll(bool isObstacle, bool sceneLoaded) {
void Scene::objectSetIsTarget(int objectId, bool isTarget, bool sceneLoaded) {
_set->objectSetIsTarget(objectId, isTarget);
if (sceneLoaded) {
- _vm->_sceneObjects->setIsTarget(objectId + 198, isTarget);
+ _vm->_sceneObjects->setIsTarget(objectId + SCENE_OBJECTS_OBJECTS_OFFSET, isTarget);
}
}
diff --git a/engines/bladerunner/scene_objects.cpp b/engines/bladerunner/scene_objects.cpp
index c55097358d..b66467e859 100644
--- a/engines/bladerunner/scene_objects.cpp
+++ b/engines/bladerunner/scene_objects.cpp
@@ -86,7 +86,7 @@ bool SceneObjects::remove(int sceneObjectId) {
if (i == -1) {
return false;
}
-
+ _sceneObjects[i]._present = 0;
int j;
for (j = 0; j < _count; ++j) {
if (_sceneObjectsSortedByDistance[j] == i) {
@@ -107,7 +107,7 @@ int SceneObjects::findByXYZ(int *isClickable, int *isObstacle, int *isTarget, fl
*isTarget = 0;
for (int i = 0; i < _count; ++i) {
- assert(_sceneObjectsSortedByDistance[i] < _count);
+ assert(_sceneObjectsSortedByDistance[i] < SCENE_OBJECTS_COUNT);
SceneObject &sceneObject = _sceneObjects[_sceneObjectsSortedByDistance[i]];
@@ -171,8 +171,10 @@ bool SceneObjects::existsOnXZ(int exceptSceneObjectId, float x, float z, bool a5
int SceneObjects::findById(int sceneObjectId) {
for (int i = 0; i < _count; ++i) {
- if (_sceneObjects[i]._present && _sceneObjects[i]._sceneObjectId == sceneObjectId) {
- return i;
+ int j = this->_sceneObjectsSortedByDistance[i];
+
+ if (_sceneObjects[j]._present && _sceneObjects[j]._sceneObjectId == sceneObjectId) {
+ return j;
}
}
return -1;
diff --git a/engines/bladerunner/script/ai_00_mccoy.cpp b/engines/bladerunner/script/ai_00_mccoy.cpp
index fa37efb63e..70f127213f 100644
--- a/engines/bladerunner/script/ai_00_mccoy.cpp
+++ b/engines/bladerunner/script/ai_00_mccoy.cpp
@@ -211,13 +211,13 @@ void AIScript_McCoy::ClickedByPlayer() {
void AIScript_McCoy::EnteredScene(int sceneId) {
}
-void AIScript_McCoy::OtherAgentEnteredThisScene() {
+void AIScript_McCoy::OtherAgentEnteredThisScene(int otherActorId) {
}
-void AIScript_McCoy::OtherAgentExitedThisScene() {
+void AIScript_McCoy::OtherAgentExitedThisScene(int otherActorId) {
}
-void AIScript_McCoy::OtherAgentEnteredCombatMode() {
+void AIScript_McCoy::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
}
void AIScript_McCoy::ShotAtAndMissed() {
@@ -248,7 +248,8 @@ void AIScript_McCoy::Retired(int byActorId) {
}
}
-void AIScript_McCoy::GetFriendlinessModifierIfGetsClue() {
+int AIScript_McCoy::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
+ return 0;
}
bool AIScript_McCoy::GoalChanged(int currentGoalNumber, int newGoalNumber) {
@@ -1660,10 +1661,12 @@ void AIScript_McCoy::SetAnimationState(int animationState, int a2, int a3, int a
dword_46271C = a4;
}
-bool AIScript_McCoy::ReachedMovementTrackWaypoint() {
+bool AIScript_McCoy::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
+void AIScript_McCoy::FledCombat() {}
+
void AIScript_McCoy::sub_4053E0() {
float x, y, z;
Actor_Query_XYZ(0, &x, &y, &z);
diff --git a/engines/bladerunner/script/ai_00_mccoy.h b/engines/bladerunner/script/ai_00_mccoy.h
index eedae2f99b..2fda82f2de 100644
--- a/engines/bladerunner/script/ai_00_mccoy.h
+++ b/engines/bladerunner/script/ai_00_mccoy.h
@@ -54,19 +54,20 @@ public:
void ReceivedClue(int clueId, int fromActorId);
void ClickedByPlayer();
void EnteredScene(int sceneId);
- void OtherAgentEnteredThisScene();
- void OtherAgentExitedThisScene();
- void OtherAgentEnteredCombatMode();
+ void OtherAgentEnteredThisScene(int otherActorId);
+ void OtherAgentExitedThisScene(int otherActorId);
+ void OtherAgentEnteredCombatMode(int otherActorId, int combatMode);
void ShotAtAndMissed();
void ShotAtAndHit();
void Retired(int byActorId);
- void GetFriendlinessModifierIfGetsClue();
+ int GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId);
bool GoalChanged(int currentGoalNumber, int newGoalNumber);
bool UpdateAnimation(int *animation, int *frame);
bool ChangeAnimationMode(int mode);
void QueryAnimationState(int *animationState, int *a2, int *a3, int *a4);
void SetAnimationState(int animationState, int a2, int a3, int a4);
- bool ReachedMovementTrackWaypoint();
+ bool ReachedMovementTrackWaypoint(int a1);
+ void FledCombat();
private:
void sub_4053E0();
diff --git a/engines/bladerunner/script/ai_15_runciter.cpp b/engines/bladerunner/script/ai_15_runciter.cpp
new file mode 100644
index 0000000000..b26339b653
--- /dev/null
+++ b/engines/bladerunner/script/ai_15_runciter.cpp
@@ -0,0 +1,656 @@
+/* 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 "bladerunner/script/ai_15_runciter.h"
+
+namespace BladeRunner {
+
+AIScript_Runciter::AIScript_Runciter(BladeRunnerEngine *vm)
+ : AIScriptBase(vm) {}
+
+void AIScript_Runciter::Initialize() {
+ var_45CD70_animation_state = 0;
+ var_45CD74_animation_frame = 0;
+ var_462800 = 0;
+ var_45CD78 = 0;
+ var_45CD7C = 6;
+ var_45CD80 = 1;
+ var_45CD84 = 0;
+ var_45CD88 = 0;
+ Actor_Set_Goal_Number(15, 0);
+}
+
+bool AIScript_Runciter::Update() {
+ if (Actor_Query_Goal_Number(15) == 0 && Game_Flag_Query(186)) {
+ Actor_Set_Goal_Number(15, 2);
+ }
+ if (Global_Variable_Query(1) == 4 && Actor_Query_Goal_Number(15) < 300) {
+ Actor_Set_Goal_Number(15, 300);
+ }
+ return false;
+}
+
+void AIScript_Runciter::TimerExpired(int timer) {}
+
+void AIScript_Runciter::CompletedMovementTrack() {
+ if (Actor_Query_Goal_Number(15) == 1) {
+ if (Player_Query_Current_Scene() == 79) {
+ switch (Random_Query(1, 5)) {
+ case 2:
+ case 3:
+ ADQ_Add(15, 530, -1);
+ break;
+ case 1:
+ case 5:
+ ADQ_Add(15, 80, -1);
+ break;
+ case 4:
+ ADQ_Add(15, 930, -1);
+ break;
+ }
+ }
+ Actor_Set_Goal_Number(15, 99);
+ Actor_Set_Goal_Number(15, 1);
+ //return true;
+ }
+ //return false;
+}
+
+void AIScript_Runciter::ReceivedClue(int clueId, int fromActorId) {}
+
+void AIScript_Runciter::ClickedByPlayer() {}
+
+void AIScript_Runciter::EnteredScene(int sceneId) {}
+
+void AIScript_Runciter::OtherAgentEnteredThisScene(int otherActorId) {}
+
+void AIScript_Runciter::OtherAgentExitedThisScene(int otherActorId) {}
+
+void AIScript_Runciter::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
+ if (Actor_Query_Goal_Number(15) == 300 && combatMode == 1 && !Game_Flag_Query(705)) {
+ Actor_Set_Targetable(15, true);
+ Actor_Face_Actor(15, 0, true);
+ Actor_Says(15, 420, 12);
+ Actor_Face_Actor(0, 15, true);
+ Actor_Change_Animation_Mode(0, 5);
+ if (Actor_Clue_Query(0, 158)) {
+ Actor_Says(0, 4770, -1);
+ Actor_Says(15, 590, 13);
+ Actor_Says(0, 4775, -1);
+ Actor_Says(15, 600, 17);
+ Sound_Play(492, 100, 0, 100, 50);
+ Actor_Says(0, 4780, -1);
+ Actor_Says(15, 610, 18);
+ Actor_Says(0, 4785, -1);
+ Actor_Says(15, 620, 15);
+ if (Game_Flag_Query(46)) {
+ Actor_Says(15, 630, 12);
+ Actor_Says(15, 640, 17);
+ Actor_Says(0, 4790, -1);
+ Actor_Says(15, 650, 18);
+ Actor_Says(15, 660, 19);
+ Actor_Clue_Acquire(0, 280, 1, 15);
+ } else {
+ Actor_Says(15, 670, 18);
+ Actor_Says(0, 4795, -1);
+ Actor_Says(15, 730, 17);
+ }
+ } else if (Actor_Clue_Query(0, 76)) {
+ Actor_Says(0, 4730, -1);
+ Actor_Says(15, 480, 17);
+ Actor_Says(0, 4735, -1);
+ Actor_Says(15, 490, 16);
+ Sound_Play(492, 100, 0, 100, 50);
+ Actor_Says(0, 4740, -1);
+ Actor_Says(15, 500, 18);
+ Actor_Says(15, 510, 19);
+ Actor_Says(0, 4745, -1);
+ Actor_Says(0, 4750, -1);
+ Actor_Says(15, 520, 17);
+ Actor_Says(15, 530, 18);
+ Actor_Says(15, 540, 16);
+ }
+ Game_Flag_Set(705);
+ }
+}
+
+void AIScript_Runciter::ShotAtAndMissed() {}
+
+void AIScript_Runciter::ShotAtAndHit() {
+ Actor_Set_Targetable(15, false);
+ Actor_Change_Animation_Mode(15, 48);
+ Actor_Set_Goal_Number(15, 599);
+ Delay(2000);
+ if (Actor_Clue_Query(0, 158)) {
+ Actor_Voice_Over(2050, 99);
+ Actor_Voice_Over(2060, 99);
+ } else {
+ Actor_Voice_Over(2070, 99);
+ Actor_Voice_Over(2080, 99);
+ Actor_Voice_Over(2090, 99);
+ }
+ Actor_Modify_Friendliness_To_Other(5, 0, 3);
+}
+
+void AIScript_Runciter::Retired(int byActorId) {}
+
+int AIScript_Runciter::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
+ return 0;
+}
+
+bool AIScript_Runciter::GoalChanged(int currentGoalNumber, int newGoalNumber) {
+ if (newGoalNumber == 0) {
+ Actor_Put_In_Set(15, 16);
+ Actor_Set_At_Waypoint(15, 92, 567);
+ return false;
+ }
+ if (newGoalNumber == 1) {
+ AI_Movement_Track_Flush(15);
+ if (Random_Query(0, 1) == 1) {
+ if (Random_Query(0, 1) == 0) {
+ AI_Movement_Track_Append_With_Facing(15, 89, Random_Query(6, 10), 567);
+ }
+ AI_Movement_Track_Append_With_Facing(15, 93, Random_Query(2, 6), 1002);
+ AI_Movement_Track_Append(15, 92, 5);
+ } else {
+ AI_Movement_Track_Append_With_Facing(15, 91, Random_Query(3, 10), 120);
+ if (Random_Query(1, 3) == 1) {
+ AI_Movement_Track_Append_With_Facing(15, 93, Random_Query(2, 6), 1002);
+ }
+ AI_Movement_Track_Append_With_Facing(15, 90, Random_Query(5, 10), 170);
+ }
+ AI_Movement_Track_Repeat(15);
+ return true;
+ }
+ if (newGoalNumber == 2) {
+ AI_Movement_Track_Flush(15);
+ AI_Movement_Track_Append(15, 39, 120);
+ AI_Movement_Track_Append(15, 40, 0);
+ AI_Movement_Track_Repeat(15);
+ return false;
+ }
+ if (newGoalNumber == 300) {
+ Actor_Put_In_Set(15, 16);
+ Actor_Set_At_Waypoint(15, 93, 1007);
+ return false;
+ }
+ return false;
+}
+
+bool AIScript_Runciter::UpdateAnimation(int *animation, int *frame) {
+
+ switch (var_45CD70_animation_state) {
+ case 15:
+ *animation = 528;
+ var_45CD74_animation_frame = Slice_Animation_Query_Number_Of_Frames(528) - 1;
+ *frame = var_45CD74_animation_frame;
+ break;
+ case 14:
+ *animation = 528;
+ var_45CD74_animation_frame++;
+ if (var_45CD74_animation_frame >= Slice_Animation_Query_Number_Of_Frames(528) - 1) {
+ *animation = 528;
+ var_45CD70_animation_state = 15;
+ }
+ *frame = var_45CD74_animation_frame;
+ break;
+ case 13:
+ if (var_45CD78 == 0) {
+ var_45CD74_animation_frame = 0;
+ var_45CD70_animation_state = var_462800;
+ *animation = var_462804;
+ } else if (var_45CD78 == 1) {
+ *animation = 530;
+ var_45CD74_animation_frame += 3;
+ if (var_45CD74_animation_frame >= Slice_Animation_Query_Number_Of_Frames(530)) {
+ var_45CD74_animation_frame = 0;
+ var_45CD70_animation_state = var_462800;
+ *animation = var_462804;
+ }
+ } else if (var_45CD78 == 2) {
+ *animation = 531;
+ var_45CD74_animation_frame -= 3;
+ if (var_45CD74_animation_frame - 3 < 0) {
+ var_45CD74_animation_frame = 0;
+ var_45CD70_animation_state = var_462800;
+ *animation = var_462804;
+ }
+ }
+ *frame = var_45CD74_animation_frame;
+ break;
+ case 12:
+ *animation = 532;
+ var_45CD74_animation_frame++;
+ if (var_45CD74_animation_frame >= Slice_Animation_Query_Number_Of_Frames(532)) {
+ *animation = 529;
+ var_45CD70_animation_state = 0;
+ var_45CD74_animation_frame = 0;
+ var_45CD78 = 0;
+ Actor_Change_Animation_Mode(15, 0);
+ }
+ *frame = var_45CD74_animation_frame;
+ break;
+ case 11:
+ *animation = 541;
+ if (var_45CD74_animation_frame >= Slice_Animation_Query_Number_Of_Frames(541)) {
+ var_45CD74_animation_frame = 0;
+ if (var_45CD88) {
+ *animation = 529;
+ var_45CD70_animation_state = 0;
+ var_45CD78 = 0;
+ } else {
+ *animation = 533;
+ var_45CD70_animation_state = 2;
+ }
+ }
+ *frame = var_45CD74_animation_frame;
+ break;
+ case 10:
+ *animation = 540;
+ var_45CD74_animation_frame++;
+ if (var_45CD74_animation_frame >= Slice_Animation_Query_Number_Of_Frames(540)) {
+ var_45CD74_animation_frame = 0;
+ if (var_45CD88) {
+ *animation = 529;
+ var_45CD70_animation_state = 0;
+ var_45CD78 = 0;
+ } else {
+ *animation = 533;
+ var_45CD70_animation_state = 2;
+ }
+ }
+ *frame = var_45CD74_animation_frame;
+ break;
+ case 9:
+ *animation = 539;
+ var_45CD74_animation_frame++;
+ if (var_45CD74_animation_frame >= Slice_Animation_Query_Number_Of_Frames(539)) {
+ var_45CD74_animation_frame = 0;
+ if (var_45CD88) {
+ *animation = 529;
+ var_45CD70_animation_state = 0;
+ var_45CD78 = 0;
+ } else {
+ *animation = 533;
+ var_45CD70_animation_state = 2;
+ }
+ }
+ *frame = var_45CD74_animation_frame;
+ break;
+ case 8:
+ *animation = 538;
+ var_45CD74_animation_frame++;
+ if (var_45CD74_animation_frame >= Slice_Animation_Query_Number_Of_Frames(538)) {
+ var_45CD74_animation_frame = 0;
+ if (var_45CD88) {
+ *animation = 529;
+ var_45CD70_animation_state = 0;
+ var_45CD78 = 0;
+ } else {
+ *animation = 533;
+ var_45CD70_animation_state = 2;
+ }
+ }
+ *frame = var_45CD74_animation_frame;
+ break;
+ case 7:
+ *animation = 537;
+ var_45CD74_animation_frame++;
+ if (var_45CD74_animation_frame >= Slice_Animation_Query_Number_Of_Frames(537)) {
+ var_45CD74_animation_frame = 0;
+ if (var_45CD88) {
+ *animation = 529;
+ var_45CD70_animation_state = 0;
+ var_45CD78 = 0;
+ } else {
+ *animation = 533;
+ var_45CD70_animation_state = 2;
+ }
+ }
+ *frame = var_45CD74_animation_frame;
+ break;
+ case 6:
+ *animation = 536;
+ var_45CD74_animation_frame++;
+ if (var_45CD74_animation_frame >= Slice_Animation_Query_Number_Of_Frames(536)) {
+ var_45CD74_animation_frame = 0;
+ if (var_45CD88) {
+ *animation = 529;
+ var_45CD70_animation_state = 0;
+ var_45CD78 = 0;
+ } else {
+ *animation = 533;
+ var_45CD70_animation_state = 2;
+ }
+ }
+ *frame = var_45CD74_animation_frame;
+ break;
+ case 5:
+ *animation = 535;
+ var_45CD74_animation_frame++;
+ if (var_45CD74_animation_frame >= Slice_Animation_Query_Number_Of_Frames(535)) {
+ var_45CD74_animation_frame = 0;
+ if (var_45CD88) {
+ *animation = 529;
+ var_45CD70_animation_state = 0;
+ var_45CD78 = 0;
+ } else {
+ *animation = 533;
+ var_45CD70_animation_state = 2;
+ }
+ }
+ *frame = var_45CD74_animation_frame;
+ break;
+ case 4:
+ *animation = 534;
+ var_45CD74_animation_frame++;
+ if (var_45CD74_animation_frame >= Slice_Animation_Query_Number_Of_Frames(534)) {
+ var_45CD74_animation_frame = 0;
+ if (var_45CD88) {
+ *animation = 529;
+ var_45CD70_animation_state = 0;
+ var_45CD78 = 0;
+ } else {
+ *animation = 533;
+ var_45CD70_animation_state = 2;
+ }
+ }
+ *frame = var_45CD74_animation_frame;
+ break;
+ case 2:
+ *animation = 533;
+ var_45CD74_animation_frame++;
+ if (var_45CD74_animation_frame >= Slice_Animation_Query_Number_Of_Frames(533)) {
+ var_45CD74_animation_frame = 0;
+ if (var_45CD88) {
+ *animation = 529;
+ var_45CD70_animation_state = 0;
+ var_45CD78 = 0;
+ } else {
+ var_45CD70_animation_state = 4;
+ }
+ }
+ *frame = var_45CD74_animation_frame;
+ break;
+ case 1:
+ *animation = 526;
+ var_45CD74_animation_frame++;
+ if (var_45CD74_animation_frame >= Slice_Animation_Query_Number_Of_Frames(526)) {
+ var_45CD74_animation_frame = 0;
+ }
+ *frame = var_45CD74_animation_frame;
+ break;
+ case 0:
+ if (var_45CD78 == 0) {
+ *animation = 529;
+ if (var_45CD84) {
+ var_45CD84--;
+ } else {
+ var_45CD74_animation_frame += var_45CD80;
+ if (var_45CD74_animation_frame >= Slice_Animation_Query_Number_Of_Frames(529)) {
+ var_45CD74_animation_frame = 0;
+ }
+ if (var_45CD74_animation_frame < 0) {
+ var_45CD74_animation_frame = Slice_Animation_Query_Number_Of_Frames(529) - 1;
+ }
+ --var_45CD7C;
+ if (var_45CD7C == 0) {
+ var_45CD80 = 2 * Random_Query(0, 1) - 1;
+ var_45CD7C = Random_Query(6, 14);
+ var_45CD84 = Random_Query(0, 4);
+ }
+ if (var_45CD74_animation_frame == 0) {
+ if (Random_Query(0, 1) == 1) {
+ var_45CD78 = Random_Query(1, 2);
+ var_45CD80 = 1;
+ var_45CD84 = 0;
+ }
+ }
+ }
+ } else if (var_45CD78 == 1) {
+ *animation = 530;
+ var_45CD74_animation_frame++;
+ if (var_45CD74_animation_frame >= Slice_Animation_Query_Number_Of_Frames(530)) {
+ var_45CD74_animation_frame = 0;
+ var_45CD78 = 0;
+ *animation = 529;
+ var_45CD7C = Random_Query(6, 14);
+ var_45CD80 = 2 * Random_Query(0, 1) - 1;
+ }
+ } else if (var_45CD78 == 2) {
+ *animation = 531;
+ if (var_45CD84) {
+ var_45CD84--;
+ } else {
+ var_45CD74_animation_frame += var_45CD80;
+ if (var_45CD74_animation_frame >= Slice_Animation_Query_Number_Of_Frames(*animation) - 1) {
+ var_45CD84 = Random_Query(5, 15);
+ var_45CD80 = -1;
+ }
+ if (var_45CD74_animation_frame <= 0) {
+ var_45CD74_animation_frame = 0;
+ var_45CD78 = 0;
+ *animation = 529;
+ var_45CD7C = Random_Query(6, 14);
+ var_45CD80 = 2 * Random_Query(0, 1) - 1;
+ }
+ }
+ }
+ *frame = var_45CD74_animation_frame;
+ break;
+ default:
+ *animation = 399;
+ var_45CD74_animation_frame = 0;
+ *frame = var_45CD74_animation_frame;
+ break;
+ }
+ return true;
+}
+
+bool AIScript_Runciter::ChangeAnimationMode(int mode) {
+
+ switch (mode) {
+ case 23:
+ var_45CD70_animation_state = 12;
+ var_45CD74_animation_frame = 0;
+ break;
+ case 19:
+ if (var_45CD70_animation_state) {
+ var_45CD70_animation_state = 2;
+ var_45CD74_animation_frame = 0;
+ } else {
+ var_45CD70_animation_state = 13;
+ var_462800 = 11;
+ var_462804 = 541;
+ }
+ var_45CD88 = 0;
+ break;
+ case 18:
+ if (var_45CD70_animation_state) {
+ var_45CD70_animation_state = 2;
+ var_45CD74_animation_frame = 0;
+ } else {
+ var_45CD70_animation_state = 13;
+ var_462800 = 10;
+ var_462804 = 540;
+ }
+ var_45CD88 = 0;
+ break;
+ case 17:
+ if (var_45CD70_animation_state) {
+ var_45CD70_animation_state = 2;
+ var_45CD74_animation_frame = 0;
+ } else {
+ var_45CD70_animation_state = 13;
+ var_462800 = 9;
+ var_462804 = 539;
+ }
+ var_45CD88 = 0;
+ break;
+ case 16:
+ if (var_45CD70_animation_state) {
+ var_45CD70_animation_state = 2;
+ var_45CD74_animation_frame = 0;
+ } else {
+ var_45CD70_animation_state = 13;
+ var_462800 = 8;
+ var_462804 = 538;
+ }
+ var_45CD88 = 0;
+ break;
+ case 15:
+ if (var_45CD70_animation_state) {
+ var_45CD70_animation_state = 2;
+ var_45CD74_animation_frame = 0;
+ } else {
+ var_45CD70_animation_state = 13;
+ var_462800 = 7;
+ var_462804 = 537;
+ }
+ var_45CD88 = 0;
+ break;
+ case 14:
+ if (var_45CD70_animation_state) {
+ var_45CD70_animation_state = 2;
+ var_45CD74_animation_frame = 0;
+ } else {
+ var_45CD70_animation_state = 13;
+ var_462800 = 6;
+ var_462804 = 536;
+ }
+ var_45CD88 = 0;
+ break;
+ case 13:
+ if (var_45CD70_animation_state) {
+ var_45CD70_animation_state = 2;
+ var_45CD74_animation_frame = 0;
+ } else {
+ var_45CD70_animation_state = 13;
+ var_462800 = 5;
+ var_462804 = 535;
+ }
+ var_45CD88 = 0;
+ break;
+ case 12:
+ if (var_45CD70_animation_state) {
+ var_45CD70_animation_state = 2;
+ var_45CD74_animation_frame = 0;
+ } else {
+ var_45CD70_animation_state = 13;
+ var_462800 = 4;
+ var_462804 = 534;
+ }
+ var_45CD88 = 0;
+ break;
+ case 3:
+ if (var_45CD70_animation_state) {
+ var_45CD70_animation_state = 2;
+ var_45CD74_animation_frame = 0;
+ } else {
+ var_45CD70_animation_state = 13;
+ var_462800 = 2;
+ var_462804 = 526;
+ }
+ var_45CD88 = 0;
+ break;
+ case 1:
+ if (var_45CD70_animation_state > 1) {
+ var_45CD70_animation_state = 1;
+ var_45CD74_animation_frame = 0;
+ } else if (!var_45CD70_animation_state) {
+ var_45CD70_animation_state = 13;
+ var_462800 = 1;
+ var_462804 = 526;
+ }
+ break;
+ case 0:
+ if (var_45CD70_animation_state >= 2 && var_45CD70_animation_state <= 11) {
+ var_45CD88 = 1;
+ } else {
+ var_45CD70_animation_state = 0;
+ var_45CD74_animation_frame = 0;
+ var_45CD78 = 0;
+ }
+ break;
+ case 2:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ case 20:
+ case 21:
+ case 22:
+ break;
+ default:
+ if (mode == 48) {
+ var_45CD70_animation_state = 14;
+ var_45CD74_animation_frame = 0;
+ }
+ break;
+ }
+ return true;
+}
+
+void AIScript_Runciter::QueryAnimationState(int *animationState, int *animationFrame, int *a3, int *a4) {
+ *animationState = var_45CD70_animation_state;
+ *animationFrame = var_45CD74_animation_frame;
+ *a3 = var_462800;
+ *a4 = var_462804;
+}
+
+void AIScript_Runciter::SetAnimationState(int animationState, int animationFrame, int a3, int a4) {
+ var_45CD70_animation_state = animationState;
+ var_45CD74_animation_frame = animationFrame;
+ var_462800 = a3;
+ var_462804 = a4;
+}
+
+bool AIScript_Runciter::ReachedMovementTrackWaypoint(int waypointId) {
+ switch (waypointId) {
+ case 93:
+ Actor_Face_Heading(15, 1002, true);
+ break;
+ case 92:
+ Actor_Face_Heading(15, 664, true);
+ break;
+ case 91:
+ Actor_Face_Heading(15, 120, true);
+ break;
+ case 90:
+ Actor_Face_Heading(15, 170, true);
+ break;
+ case 89:
+ Actor_Face_Heading(15, 567, true);
+ break;
+ default:
+ return true;
+ }
+ return true;
+}
+
+void AIScript_Runciter::FledCombat() {}
+
+} // End of namespace BladeRunner
diff --git a/engines/bladerunner/script/ai_15_runciter.h b/engines/bladerunner/script/ai_15_runciter.h
new file mode 100644
index 0000000000..b2cb70d2f8
--- /dev/null
+++ b/engines/bladerunner/script/ai_15_runciter.h
@@ -0,0 +1,65 @@
+/* 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 "bladerunner/script/script.h"
+
+#include "bladerunner/bladerunner.h"
+
+namespace BladeRunner {
+
+class AIScript_Runciter : public AIScriptBase {
+ int var_45CD70_animation_state;
+ int var_45CD74_animation_frame;
+ int var_462800;
+ int var_462804;
+ int var_45CD78;
+ int var_45CD7C;
+ int var_45CD80;
+ int var_45CD84;
+ int var_45CD88;
+public:
+ AIScript_Runciter(BladeRunnerEngine *vm);
+
+ void Initialize();
+ bool Update();
+ void TimerExpired(int timer);
+ void CompletedMovementTrack();
+ void ReceivedClue(int clueId, int fromActorId);
+ void ClickedByPlayer();
+ void EnteredScene(int sceneId);
+ void OtherAgentEnteredThisScene(int otherActorId);
+ void OtherAgentExitedThisScene(int otherActorId);
+ void OtherAgentEnteredCombatMode(int otherActorId, int combatMode);
+ void ShotAtAndMissed();
+ void ShotAtAndHit();
+ void Retired(int byActorId);
+ int GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId);
+ bool GoalChanged(int currentGoalNumber, int newGoalNumber);
+ bool UpdateAnimation(int *animation, int *frame);
+ bool ChangeAnimationMode(int mode);
+ void QueryAnimationState(int *animationState, int *animationFrame, int *a3, int *a4);
+ void SetAnimationState(int animationState, int animationFrame, int a3, int a4);
+ bool ReachedMovementTrackWaypoint(int a1);
+ void FledCombat();
+};
+
+} // End of namespace BladeRunner
diff --git a/engines/bladerunner/script/ai_23_officer_leroy.cpp b/engines/bladerunner/script/ai_23_officer_leroy.cpp
new file mode 100644
index 0000000000..8f97466a8a
--- /dev/null
+++ b/engines/bladerunner/script/ai_23_officer_leroy.cpp
@@ -0,0 +1,1217 @@
+/* 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 "bladerunner/script/ai_23_officer_leroy.h"
+
+namespace BladeRunner {
+
+AIScript_Officer_Leroy::AIScript_Officer_Leroy(BladeRunnerEngine *vm)
+ : AIScriptBase(vm), var_45D5B0_animation_state(0), var_45D5B4_animation_frame(0), var_45D5B8(0), var_45D5BC(0), var_462880(0), var_462884(0) {}
+
+void AIScript_Officer_Leroy::Initialize() {
+ var_45D5B0_animation_state = 0;
+ var_45D5B4_animation_frame = 0;
+ var_462880 = 0;
+ var_45D5B8 = 0;
+ var_45D5BC = 0;
+
+ Actor_Put_In_Set(23, 69);
+ Actor_Set_At_XYZ(23, -261.80f, 6.00f, 79.58f, 512);
+ Actor_Set_Goal_Number(23, 0);
+ Actor_Set_Frame_Rate_FPS(23, 8);
+}
+
+bool AIScript_Officer_Leroy::Update() {
+ if (Global_Variable_Query(1) == 4 && Actor_Query_Goal_Number(23) < 300) {
+ AI_Movement_Track_Flush(23);
+ Actor_Set_Goal_Number(23, 300);
+ } else if (Global_Variable_Query(1) == 5 && Actor_Query_Goal_Number(23) < 400) {
+ AI_Movement_Track_Flush(23);
+ Actor_Set_Goal_Number(23, 400);
+ } else if (!Game_Flag_Query(182) && Game_Flag_Query(147) == 1 && Game_Flag_Query(163) == 1 && Player_Query_Current_Scene() != 78 && Global_Variable_Query(1) < 3) {
+ Game_Flag_Set(186);
+ Actor_Set_Goal_Number(23, 3);
+ } else if (Actor_Query_Goal_Number(23) != 1 && Actor_Query_Goal_Number(23) != 2 && Game_Flag_Query(199) == 1) {
+ Game_Flag_Reset(199);
+ } else if (Global_Variable_Query(15) > 4 && !Actor_Clue_Query(23, 239)) {
+ Actor_Clue_Acquire(23, 239, 1, -1);
+ } else if (Game_Flag_Query(629) == 1) {
+ Game_Flag_Reset(629);
+ } else if (Game_Flag_Query(623) == 1 && !Game_Flag_Query(664)) {
+ Game_Flag_Set(664);
+ Actor_Set_Goal_Number(23, 305);
+ } else if (Actor_Query_Goal_Number(23) == 310 && Actor_Query_Which_Set_In(23) != Player_Query_Current_Set()) {
+ Non_Player_Actor_Combat_Mode_Off(23);
+ Actor_Set_Goal_Number(23, 305);
+ } else if (Actor_Query_Goal_Number(23) == 599 && Actor_Query_Which_Set_In(23) != Player_Query_Current_Set()) {
+ Actor_Set_Health(23, 40, 40);
+ Actor_Set_Goal_Number(23, 305);
+ } else if (Actor_Query_Goal_Number(23) == 305) {
+ switch (Actor_Query_Which_Set_In(23)) {
+ case 7:
+ if (Actor_Query_Which_Set_In(23) == Player_Query_Current_Set()) {
+ Actor_Set_Goal_Number(23, 310);
+ Non_Player_Actor_Combat_Mode_On(23, 0, 1, 0, 0, 4, 7, 8, -1, -1, -1, 10, 300, 0);
+ }
+ break;
+ case 20:
+ if (Actor_Query_Which_Set_In(23) == Player_Query_Current_Set()) {
+ Actor_Set_Goal_Number(23, 310);
+ Non_Player_Actor_Combat_Mode_On(23, 0, 1, 0, 1, 4, 7, 8, -1, -1, -1, 10, 300, 0);
+ }
+ break;
+ case 33:
+ if (Actor_Query_Which_Set_In(23) == Player_Query_Current_Set()) {
+ Actor_Set_Goal_Number(23, 310);
+ Non_Player_Actor_Combat_Mode_On(23, 0, 1, 0, 5, 4, 7, 8, -1, -1, -1, 10, 300, 0);
+ }
+ break;
+ case 53:
+ if (Actor_Query_Which_Set_In(23) == Player_Query_Current_Set()) {
+ Actor_Set_Goal_Number(23, 310);
+ Non_Player_Actor_Combat_Mode_On(23, 0, 1, 0, 7, 4, 7, 8, -1, -1, -1, 10, 300, 0);
+ }
+ break;
+ case 54:
+ if (Actor_Query_Which_Set_In(23) == Player_Query_Current_Set()) {
+ Actor_Set_Goal_Number(23, 310);
+ Non_Player_Actor_Combat_Mode_On(23, 0, 1, 0, 3, 4, 7, 8, -1, -1, -1, 10, 300, 0);
+ }
+ break;
+ case 70:
+ if (Actor_Query_Which_Set_In(23) == Player_Query_Current_Set()) {
+ Actor_Set_Goal_Number(23, 310);
+ Non_Player_Actor_Combat_Mode_On(23, 0, 1, 0, 18, 4, 7, 8, -1, -1, -1, 10, 300, 0);
+ }
+ break;
+ case 74:
+ if (Actor_Query_Which_Set_In(23) == Player_Query_Current_Set()) {
+ Actor_Set_Goal_Number(23, 310);
+ Non_Player_Actor_Combat_Mode_On(23, 0, 1, 0, 11, 4, 7, 8, -1, -1, -1, 10, 300, 0);
+ }
+ break;
+ case 77:
+ case 78:
+ case 79:
+ if (Actor_Query_Which_Set_In(23) == Player_Query_Current_Set()) {
+ Actor_Set_Goal_Number(23, 310);
+ Non_Player_Actor_Combat_Mode_On(23, 0, 1, 0, 10, 4, 7, 8, -1, -1, -1, 10, 300, 0);
+ }
+ break;
+ case 81:
+ if (Actor_Query_Which_Set_In(23) == Player_Query_Current_Set()) {
+ Actor_Set_Goal_Number(23, 310);
+ Non_Player_Actor_Combat_Mode_On(23, 0, 1, 0, 13, 4, 7, 8, -1, -1, -1, 10, 300, 0);
+ }
+ break;
+ case 83:
+ if (Actor_Query_Which_Set_In(23) == Player_Query_Current_Set()) {
+ Actor_Set_Goal_Number(23, 310);
+ Non_Player_Actor_Combat_Mode_On(23, 0, 1, 0, 14, 4, 7, 8, -1, -1, -1, 10, 300, 0);
+ }
+ break;
+ case 84:
+ if (Actor_Query_Which_Set_In(23) == Player_Query_Current_Set()) {
+ Actor_Set_Goal_Number(23, 310);
+ Non_Player_Actor_Combat_Mode_On(23, 0, 1, 0, 16, 4, 7, 8, -1, -1, -1, 10, 300, 0);
+ }
+ break;
+ case 86:
+ if (Actor_Query_Which_Set_In(23) == Player_Query_Current_Set()) {
+ Actor_Set_Goal_Number(23, 310);
+ Non_Player_Actor_Combat_Mode_On(23, 0, 1, 0, 17, 4, 7, 8, -1, -1, -1, 10, 300, 0);
+ }
+ break;
+ }
+ }
+ return false;
+}
+
+void AIScript_Officer_Leroy::TimerExpired(int timer) {
+ if (timer == 1) {
+ AI_Countdown_Timer_Reset(23, 1);
+ if (Actor_Query_In_Set(0, 41)) {
+ Actor_Set_Goal_Number(23, 430);
+ Actor_Set_Goal_Number(24, 430);
+ } else {
+ Game_Flag_Set(684);
+ }
+ } else if (timer == 2) {
+ AI_Countdown_Timer_Reset(23, 2);
+ sub_431420();
+ }
+}
+
+void AIScript_Officer_Leroy::CompletedMovementTrack() {
+ int v0;
+ unsigned int v1;
+
+ v0 = Actor_Query_Goal_Number(23);
+ if (v0 == 1) {
+ Actor_Set_Goal_Number(23, 2);
+ return;
+ }
+ //todo: tidyup
+ v1 = v0 - 305;
+ if (v1 > 3) {
+ return;
+ }
+ if (!v1) {
+ Actor_Set_Goal_Number(23, 306);
+ return;
+ }
+ if (v1 != 2) {
+ if (v1 == 3) {
+ Actor_Change_Animation_Mode(23, 4);
+ Actor_Face_Actor(23, 0, true);
+ Actor_Set_Goal_Number(23, 309);
+ }
+ return;
+ }
+ Non_Player_Actor_Combat_Mode_On(23, 0, 1, 0, 12, 4, 7, 8, 0, -1, -1, 15, 300, 0);
+}
+
+void AIScript_Officer_Leroy::ReceivedClue(int clueId, int fromActorId) {
+ if (clueId == 222) {
+ Actor_Modify_Friendliness_To_Other(23, 0, 5);
+ }
+ if (clueId == 215) {
+ Actor_Modify_Friendliness_To_Other(23, 0, -4);
+ }
+}
+
+void AIScript_Officer_Leroy::ClickedByPlayer() {}
+
+void AIScript_Officer_Leroy::EnteredScene(int sceneId) {}
+
+void AIScript_Officer_Leroy::OtherAgentEnteredThisScene(int otherActorId) {}
+
+void AIScript_Officer_Leroy::OtherAgentExitedThisScene(int otherActorId) {}
+
+void AIScript_Officer_Leroy::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {}
+
+void AIScript_Officer_Leroy::ShotAtAndMissed() {}
+
+void AIScript_Officer_Leroy::ShotAtAndHit() {
+ if (Actor_Query_Goal_Number(23) == 307) {
+ Actor_Set_Health(23, 50, 50);
+ }
+}
+
+void AIScript_Officer_Leroy::Retired(int byActorId) {
+ Actor_Set_Goal_Number(23, 599);
+ Game_Flag_Set(607);
+}
+
+int AIScript_Officer_Leroy::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
+ if (otherActorId) {
+ return 0;
+ }
+ switch (clueId) {
+ case 242:
+ return -6;
+ case 240:
+ return -2;
+ case 239:
+ return -5;
+ case 228:
+ return 2;
+ case 227:
+ return 4;
+ case 226:
+ return 4;
+ case 225:
+ return 3;
+ case 224:
+ return 3;
+ case 223:
+ return 2;
+ case 222:
+ return 3;
+ case 215:
+ return -5;
+ }
+ return 0;
+}
+
+bool AIScript_Officer_Leroy::GoalChanged(int currentGoalNumber, int newGoalNumber) {
+ switch (newGoalNumber) {
+ case 1:
+ AI_Movement_Track_Flush(23);
+ if (Random_Query(1, 2) == 1) {
+ AI_Movement_Track_Append(23, 57, 7);
+ AI_Movement_Track_Append(23, 58, 7);
+ } else {
+ AI_Movement_Track_Append(23, 58, 7);
+ AI_Movement_Track_Append(23, 57, 7);
+ }
+ AI_Movement_Track_Repeat(23);
+ return true;
+ case 2:
+ if (Random_Query(1, 3) == 1) {
+ if (Random_Query(1, 2) == 1 && !Actor_Clue_Query(23, 16)) {
+ Actor_Clue_Acquire(23, 16, 0, -1);
+ } else if (!Actor_Clue_Query(23, 17)) {
+ Actor_Clue_Acquire(23, 17, 0, -1);
+ }
+ }
+ if (Game_Flag_Query(182)) {
+ if (Actor_Clue_Query(23, 16) && Actor_Clue_Query(23, 17)) {
+ Actor_Set_Goal_Number(23, 0);
+ } else {
+ Actor_Set_Goal_Number(23, 1);
+ }
+ } else {
+ Actor_Set_Goal_Number(23, 0);
+ }
+ return true;
+ case 3:
+ AI_Movement_Track_Flush(23);
+ AI_Movement_Track_Append(23, 39, Random_Query(120, 240));
+ AI_Movement_Track_Append(23, 35, 0);
+ AI_Movement_Track_Repeat(23);
+ return true;
+ case 99:
+ AI_Movement_Track_Flush(23);
+ return false;
+ case 102:
+ AI_Movement_Track_Flush(23);
+ AI_Movement_Track_Append(23, 107, 0);
+ AI_Movement_Track_Append(23, 108, 0);
+ AI_Movement_Track_Repeat(23);
+ return true;
+ case 300:
+ Actor_Set_Goal_Number(23, 305);
+ return true;
+ case 305:
+ AI_Movement_Track_Flush(23);
+ switch (Random_Query(1, 10)) {
+ case 1:
+ AI_Movement_Track_Append(23, 398, 15);
+ AI_Movement_Track_Append(23, 399, 0);
+ AI_Movement_Track_Append(23, 400, 0);
+ AI_Movement_Track_Append(23, 401, 0);
+ AI_Movement_Track_Append_With_Facing(23, 402, 3, 276);
+ AI_Movement_Track_Append(23, 403, 0);
+ AI_Movement_Track_Append(23, 404, 15);
+ AI_Movement_Track_Repeat(23);
+ break;
+ case 2:
+ AI_Movement_Track_Append(23, 385, 10);
+ AI_Movement_Track_Append(23, 242, 2);
+ AI_Movement_Track_Append(23, 386, 2);
+ AI_Movement_Track_Append(23, 387, 15);
+ AI_Movement_Track_Repeat(23);
+ break;
+ case 3:
+ AI_Movement_Track_Append(23, 390, 10);
+ AI_Movement_Track_Append(23, 391, 0);
+ AI_Movement_Track_Append(23, 392, 5);
+ AI_Movement_Track_Append(23, 345, 0);
+ AI_Movement_Track_Append(23, 393, 15);
+ AI_Movement_Track_Repeat(23);
+ break;
+ case 4:
+ AI_Movement_Track_Append(23, 381, 15);
+ AI_Movement_Track_Append(23, 382, 0);
+ AI_Movement_Track_Append(23, 383, 15);
+ AI_Movement_Track_Append(23, 382, 3);
+ AI_Movement_Track_Append(23, 384, 0);
+ AI_Movement_Track_Append(23, 35, 30);
+ AI_Movement_Track_Repeat(23);
+ break;
+ case 5:
+ AI_Movement_Track_Append(23, 388, 10);
+ AI_Movement_Track_Append(23, 389, 10);
+ AI_Movement_Track_Append(23, 35, 30);
+ AI_Movement_Track_Repeat(23);
+ break;
+ case 6:
+ AI_Movement_Track_Append(23, 385, 10);
+ AI_Movement_Track_Append(23, 242, 2);
+ AI_Movement_Track_Append(23, 386, 2);
+ AI_Movement_Track_Append(23, 387, 15);
+ AI_Movement_Track_Repeat(23);
+ break;
+ case 7:
+ AI_Movement_Track_Append(23, 394, 15);
+ AI_Movement_Track_Append(23, 395, 0);
+ AI_Movement_Track_Append(23, 396, 0);
+ AI_Movement_Track_Append(23, 397, 15);
+ AI_Movement_Track_Append(23, 396, 0);
+ AI_Movement_Track_Append(23, 395, 0);
+ AI_Movement_Track_Append(23, 430, 15);
+ AI_Movement_Track_Append(23, 35, 30);
+ AI_Movement_Track_Repeat(23);
+ break;
+ case 8:
+ switch (Random_Query(1, 7)) {
+ case 1:
+ AI_Movement_Track_Append(23, 302, 0);
+ AI_Movement_Track_Append(23, 407, 0);
+ AI_Movement_Track_Append(23, 408, 0);
+ AI_Movement_Track_Append(23, 35, 30);
+ AI_Movement_Track_Repeat(23);
+ break;
+ case 2:
+ AI_Movement_Track_Append(23, 536, 0);
+ AI_Movement_Track_Append(23, 537, 0);
+ AI_Movement_Track_Append(23, 538, 1);
+ AI_Movement_Track_Append(23, 537, 0);
+ AI_Movement_Track_Append(23, 536, 0);
+ AI_Movement_Track_Repeat(23);
+ break;
+ case 3:
+ AI_Movement_Track_Append(23, 296, 10);
+ AI_Movement_Track_Append(23, 409, 2);
+ AI_Movement_Track_Append(23, 296, 10);
+ AI_Movement_Track_Append(23, 35, 30);
+ AI_Movement_Track_Repeat(23);
+ break;
+ case 4:
+ AI_Movement_Track_Append(23, 411, 10);
+ AI_Movement_Track_Append(23, 412, 5);
+ AI_Movement_Track_Append(23, 411, 0);
+ AI_Movement_Track_Append(23, 35, 30);
+ AI_Movement_Track_Repeat(23);
+ break;
+ case 5:
+ AI_Movement_Track_Append(23, 413, 10);
+ AI_Movement_Track_Append(23, 414, 0);
+ AI_Movement_Track_Append_With_Facing(23, 431, 0, 1017);
+ AI_Movement_Track_Append(23, 432, 10);
+ AI_Movement_Track_Append(23, 35, 30);
+ AI_Movement_Track_Repeat(23);
+ break;
+ case 6:
+ AI_Movement_Track_Append(23, 415, 0);
+ AI_Movement_Track_Append_With_Facing(23, 416, 0, 620);
+ AI_Movement_Track_Append(23, 417, 0);
+ AI_Movement_Track_Append(23, 418, 0);
+ AI_Movement_Track_Append(23, 35, 30);
+ AI_Movement_Track_Repeat(23);
+ break;
+ case 7:
+ AI_Movement_Track_Append(23, 405, 10);
+ AI_Movement_Track_Append(23, 406, 0);
+ AI_Movement_Track_Append(23, 35, 30);
+ AI_Movement_Track_Repeat(23);
+ return false;
+ default:
+ return false;
+ }
+ //no break
+ case 9:
+ if (Random_Query(1, 2) - 1 == 1) {
+ AI_Movement_Track_Append(23, 433, 10);
+ AI_Movement_Track_Append(23, 434, 0);
+ AI_Movement_Track_Append(23, 435, 0);
+ AI_Movement_Track_Append(23, 35, 30);
+ AI_Movement_Track_Repeat(23);
+ return false;
+ }
+ AI_Movement_Track_Append(23, 420, 10);
+ AI_Movement_Track_Append(23, 422, 2);
+ AI_Movement_Track_Append(23, 421, 1);
+ AI_Movement_Track_Append_With_Facing(23, 422, 4, 182);
+ AI_Movement_Track_Append(23, 420, 10);
+ AI_Movement_Track_Append(23, 35, 30);
+ AI_Movement_Track_Repeat(23);
+ //no break
+ case 10:
+ AI_Movement_Track_Append(23, 310, 0);
+ AI_Movement_Track_Append(23, 307, 0);
+ AI_Movement_Track_Append(23, 309, 0);
+ AI_Movement_Track_Append(23, 310, 0);
+ AI_Movement_Track_Append(23, 35, 30);
+ AI_Movement_Track_Repeat(23);
+ return false;
+ default:
+ return false;
+ }
+ //no break
+ case 306:
+ Actor_Set_Goal_Number(23, 305);
+ return true;
+ case 307:
+ AI_Movement_Track_Flush(23);
+ AI_Movement_Track_Append_With_Facing(23, 416, 0, 556);
+ Actor_Change_Animation_Mode(23, 4);
+ AI_Movement_Track_Repeat(23);
+ return true;
+ case 308:
+ AI_Movement_Track_Flush(23);
+ AI_Movement_Track_Append_Run_With_Facing(23, 440, 2, 355);
+ AI_Movement_Track_Append_Run_With_Facing(23, 441, 0, 825);
+ AI_Movement_Track_Repeat(23);
+ return true;
+ case 400:
+ AI_Movement_Track_Flush(23);
+ AI_Movement_Track_Append(23, 35, 0);
+ AI_Movement_Track_Repeat(23);
+ Actor_Set_Goal_Number(23, 410);
+ return true;
+ case 420:
+ AI_Countdown_Timer_Reset(23, 1);
+ AI_Countdown_Timer_Start(23, 1, 120);
+ Actor_Set_Goal_Number(23, 410);
+ return true;
+ case 425:
+ AI_Countdown_Timer_Reset(23, 1);
+ AI_Countdown_Timer_Start(23, 1, 60);
+ Actor_Set_Goal_Number(23, 410);
+ return true;
+ case 430:
+ Actor_Set_Goal_Number(23, 410);
+ Actor_Set_Goal_Number(24, 410);
+ return false;
+ default:
+ return false;
+ }
+}
+
+bool AIScript_Officer_Leroy::UpdateAnimation(int *animation, int *frame) {
+ int v57;
+ int a1;
+
+ switch (var_45D5B0_animation_state) {
+ case 32:
+ *animation = 603;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame >= Slice_Animation_Query_Number_Of_Frames(603)) {
+ *animation = 589;
+ var_45D5B0_animation_state = 0;
+ var_45D5B8 = 0;
+ var_45D5B4_animation_frame = 0;
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 31:
+ *animation = 604;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame >= Slice_Animation_Query_Number_Of_Frames(604)) {
+ *animation = 601;
+ var_45D5B0_animation_state = 1;
+ var_45D5B4_animation_frame = 0;
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 30:
+ *animation = 587;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame >= Slice_Animation_Query_Number_Of_Frames(587)) {
+ *animation = 589;
+ var_45D5B0_animation_state = 0;
+ var_45D5B4_animation_frame = 0;
+ Actor_Change_Animation_Mode(23, 0);
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 29:
+ *animation = 586;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame >= Slice_Animation_Query_Number_Of_Frames(586)) {
+ *animation = 589;
+ var_45D5B0_animation_state = 0;
+ var_45D5B4_animation_frame = 0;
+ Actor_Change_Animation_Mode(23, 0);
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 28:
+ *animation = 576;
+ if (var_45D5B4_animation_frame < Slice_Animation_Query_Number_Of_Frames(576) - 1) {
+ ++var_45D5B4_animation_frame;
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 27:
+ *animation = 588;
+ if (var_45D5B4_animation_frame < Slice_Animation_Query_Number_Of_Frames(588) - 1) {
+ ++var_45D5B4_animation_frame;
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 26:
+ *animation = 573;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame >= Slice_Animation_Query_Number_Of_Frames(573)) {
+ var_45D5B0_animation_state = 21;
+ var_45D5B4_animation_frame = 0;
+ *animation = 571;
+ Actor_Change_Animation_Mode(23, 4);
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 25:
+ *animation = 572;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame >= Slice_Animation_Query_Number_Of_Frames(572)) {
+ var_45D5B0_animation_state = 21;
+ var_45D5B4_animation_frame = 0;
+ *animation = 571;
+ Actor_Change_Animation_Mode(23, 4);
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 24:
+ *animation = 581;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame == 4) {
+ if (Random_Query(1, 2) == 1) {
+ Sound_Play_Speech_Line(23, 9010, 75, 0, 99);
+ } else {
+ Sound_Play_Speech_Line(23, 9015, 75, 0, 99);
+ }
+ }
+ if (var_45D5B4_animation_frame == 5) {
+ Actor_Combat_AI_Hit_Attempt(23);
+ }
+ if (var_45D5B4_animation_frame >= Slice_Animation_Query_Number_Of_Frames(581)) {
+ var_45D5B0_animation_state = 21;
+ var_45D5B4_animation_frame = 0;
+ *animation = 571;
+ Actor_Change_Animation_Mode(23, 4);
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 23:
+ *animation = 580;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame >= Slice_Animation_Query_Number_Of_Frames(580)) {
+ *animation = 589;
+ var_45D5B0_animation_state = 0;
+ var_45D5B4_animation_frame = 0;
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 22:
+ *animation = 579;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame >= Slice_Animation_Query_Number_Of_Frames(579)) {
+ var_45D5B0_animation_state = 21;
+ var_45D5B4_animation_frame = 0;
+ *animation = 571;
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 21:
+ *animation = 571;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame >= Slice_Animation_Query_Number_Of_Frames(571)) {
+ var_45D5B4_animation_frame = 0;
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 20:
+ *animation = 571;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame > Slice_Animation_Query_Number_Of_Frames(571) - 1) {
+ var_45D5B4_animation_frame = 0;
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 19:
+ *animation = 600;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame >= Slice_Animation_Query_Number_Of_Frames(600)) {
+ var_45D5B0_animation_state = 11;
+ var_45D5B4_animation_frame = 0;
+ *animation = 592;
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 18:
+ *animation = 599;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame >= Slice_Animation_Query_Number_Of_Frames(599)) {
+ var_45D5B0_animation_state = 11;
+ var_45D5B4_animation_frame = 0;
+ *animation = 592;
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 17:
+ *animation = 598;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame >= Slice_Animation_Query_Number_Of_Frames(598)) {
+ var_45D5B0_animation_state = 11;
+ var_45D5B4_animation_frame = 0;
+ *animation = 592;
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 16:
+ *animation = 597;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame >= Slice_Animation_Query_Number_Of_Frames(597)) {
+ var_45D5B0_animation_state = 11;
+ var_45D5B4_animation_frame = 0;
+ *animation = 592;
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 15:
+ *animation = 596;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame >= Slice_Animation_Query_Number_Of_Frames(596)) {
+ var_45D5B0_animation_state = 11;
+ var_45D5B4_animation_frame = 0;
+ *animation = 592;
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 14:
+ *animation = 595;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame >= Slice_Animation_Query_Number_Of_Frames(595)) {
+ var_45D5B0_animation_state = 11;
+ var_45D5B4_animation_frame = 0;
+ *animation = 592;
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 13:
+ *animation = 594;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame >= Slice_Animation_Query_Number_Of_Frames(594)) {
+ var_45D5B0_animation_state = 11;
+ var_45D5B4_animation_frame = 0;
+ *animation = 592;
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 12:
+ *animation = 593;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame >= Slice_Animation_Query_Number_Of_Frames(593)) {
+ var_45D5B0_animation_state = 11;
+ var_45D5B4_animation_frame = 0;
+ *animation = 592;
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 11:
+ if (var_45D5BC && var_45D5B4_animation_frame <= 2) {
+ var_45D5BC = 0;
+ var_45D5B0_animation_state = 0;
+ var_45D5B4_animation_frame = 0;
+ *animation = 589;
+ var_45D5B8 = Random_Query(0, 1);
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ }
+
+ *animation = 592;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame >= Slice_Animation_Query_Number_Of_Frames(592)) {
+ var_45D5B4_animation_frame = 0;
+ if (var_45D5BC) {
+ var_45D5BC = 0;
+ var_45D5B0_animation_state = 0;
+ var_45D5B4_animation_frame = 0;
+ *animation = 589;
+ var_45D5B8 = Random_Query(0, 1);
+ } else {
+ var_45D5B0_animation_state = Random_Query(0, 8) + 11;
+ }
+ var_45D5B4_animation_frame = 0;
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 10:
+ *animation = 578;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame >= Slice_Animation_Query_Number_Of_Frames(578)) {
+ var_45D5B4_animation_frame = 0;
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 9:
+ *animation = 577;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame >= Slice_Animation_Query_Number_Of_Frames(577)) {
+ var_45D5B4_animation_frame = 0;
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 8:
+ *animation = 575;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame >= Slice_Animation_Query_Number_Of_Frames(575)) {
+ var_45D5B4_animation_frame = 0;
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 7:
+ *animation = 574;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame >= Slice_Animation_Query_Number_Of_Frames(574)) {
+ var_45D5B4_animation_frame = 0;
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 6:
+ *animation = 585;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame >= Slice_Animation_Query_Number_Of_Frames(585)) {
+ var_45D5B4_animation_frame = 0;
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 5:
+ *animation = 584;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame >= Slice_Animation_Query_Number_Of_Frames(584)) {
+ var_45D5B4_animation_frame = 0;
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 4:
+ *animation = 583;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame >= Slice_Animation_Query_Number_Of_Frames(583)) {
+ var_45D5B4_animation_frame = 0;
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 3:
+ *animation = 582;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame >= Slice_Animation_Query_Number_Of_Frames(582)) {
+ var_45D5B4_animation_frame = 0;
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 2:
+ if (Game_Flag_Query(199)) {
+ *animation = 603;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame > Slice_Animation_Query_Number_Of_Frames(603) - 1) {
+ Game_Flag_Reset(199);
+ var_45D5B4_animation_frame = 0;
+ var_45D5B0_animation_state = var_462880;
+ *animation = var_462884;
+ }
+ } else {
+ if (var_45D5B8 == 0) {
+ *animation = 589;
+ }
+ if (var_45D5B8 == 1) {
+ *animation = 590;
+ }
+ if (var_45D5B8 == 2) {
+ *animation = 591;
+ }
+ if (var_45D5B4_animation_frame > Slice_Animation_Query_Number_Of_Frames(*animation) / 2) {
+ a1 = *animation;
+ var_45D5B4_animation_frame += 3;
+ v57 = var_45D5B4_animation_frame;
+ if (v57 > Slice_Animation_Query_Number_Of_Frames(a1) - 1) {
+ var_45D5B4_animation_frame = 0;
+ var_45D5B0_animation_state = var_462880;
+ *animation = var_462884;
+ }
+ } else {
+ var_45D5B4_animation_frame -= 3;
+ if (var_45D5B4_animation_frame < 0) {
+ var_45D5B4_animation_frame = 0;
+ var_45D5B0_animation_state = var_462880;
+ *animation = var_462884;
+ }
+ }
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 1:
+ *animation = 601;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame >= Slice_Animation_Query_Number_Of_Frames(601)) {
+ var_45D5B4_animation_frame = 0;
+ }
+ if (!Game_Flag_Query(199)) {
+ var_45D5B0_animation_state = 32;
+ var_45D5B4_animation_frame = 0;
+ *animation = 603;
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ case 0:
+ if (Game_Flag_Query(199) && !Game_Flag_Query(392)) {
+ var_45D5B0_animation_state = 31;
+ var_45D5B4_animation_frame = 0;
+ *animation = 604;
+ } else if (var_45D5B8 == 1) {
+ *animation = 590;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame >= Slice_Animation_Query_Number_Of_Frames(590)) {
+ var_45D5B8 = Random_Query(0, 2);
+ var_45D5B4_animation_frame = 0;
+ }
+ } else if (var_45D5B8 == 2) {
+ *animation = 591;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame >= Slice_Animation_Query_Number_Of_Frames(591)) {
+ var_45D5B8 = Random_Query(0, 2);
+ var_45D5B4_animation_frame = 0;
+ }
+ } else if (var_45D5B8 == 0) {
+ *animation = 589;
+ var_45D5B4_animation_frame++;
+ if (var_45D5B4_animation_frame >= Slice_Animation_Query_Number_Of_Frames(589)) {
+ var_45D5B8 = Random_Query(0, 2);
+ var_45D5B4_animation_frame = 0;
+ }
+ }
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ default:
+ *animation = 399;
+ *frame = var_45D5B4_animation_frame;
+ return true;
+ }
+}
+
+bool AIScript_Officer_Leroy::ChangeAnimationMode(int mode) {
+ int v1;
+
+ switch (mode) {
+ case 28:
+ Game_Flag_Set(199);
+ break;
+ case 27:
+ Game_Flag_Reset(199);
+ break;
+ case 22:
+ if (Random_Query(0, 1)) {
+ var_45D5B0_animation_state = 25;
+ } else {
+ var_45D5B0_animation_state = 26;
+ }
+ var_45D5B4_animation_frame = 0;
+ break;
+ case 21:
+ if (var_45D5B0_animation_state == 21 || var_45D5B0_animation_state == 24) {
+ if (Random_Query(0, 1)) {
+ var_45D5B0_animation_state = 25;
+ } else {
+ var_45D5B0_animation_state = 26;
+ }
+ var_45D5B4_animation_frame = 0;
+ } else {
+ if (Random_Query(0, 1)) {
+ var_45D5B0_animation_state = 29;
+ } else {
+ var_45D5B0_animation_state = 30;
+ }
+ var_45D5B4_animation_frame = 0;
+ }
+ break;
+ case 19:
+ if (var_45D5B0_animation_state == 0 || var_45D5B0_animation_state == 1) {
+ var_45D5B0_animation_state = 2;
+ var_462880 = 19;
+ var_462884 = 600;
+ if (Game_Flag_Query(199) == 1) {
+ var_45D5B4_animation_frame = 0;
+ }
+ } else if (var_45D5B0_animation_state < 11 || var_45D5B0_animation_state > 19) {
+ var_45D5B0_animation_state = 19;
+ var_45D5B4_animation_frame = 0;
+ var_45D5BC = 0;
+ }
+ break;
+ case 18:
+ if (var_45D5B0_animation_state == 0 || var_45D5B0_animation_state == 1) {
+ var_45D5B0_animation_state = 2;
+ var_462880 = 18;
+ var_462884 = 599;
+ if (Game_Flag_Query(199) == 1) {
+ var_45D5B4_animation_frame = 0;
+ }
+ } else if (var_45D5B0_animation_state < 11 || var_45D5B0_animation_state > 19) {
+ var_45D5B0_animation_state = 18;
+ var_45D5B4_animation_frame = 0;
+ var_45D5BC = 0;
+ }
+ break;
+ case 17:
+ if (var_45D5B0_animation_state == 0 || var_45D5B0_animation_state == 1) {
+ var_45D5B0_animation_state = 2;
+ var_462880 = 17;
+ var_462884 = 598;
+ if (Game_Flag_Query(199) == 1) {
+ var_45D5B4_animation_frame = 0;
+ }
+ } else if (var_45D5B0_animation_state < 11 || var_45D5B0_animation_state > 19) {
+ var_45D5B0_animation_state = 17;
+ var_45D5B4_animation_frame = 0;
+ var_45D5BC = 0;
+ }
+ break;
+ case 16:
+ if (var_45D5B0_animation_state == 0 || var_45D5B0_animation_state == 1) {
+ var_45D5B0_animation_state = 2;
+ var_462880 = 16;
+ var_462884 = 597;
+ if (Game_Flag_Query(199) == 1) {
+ var_45D5B4_animation_frame = 0;
+ }
+ } else if (var_45D5B0_animation_state < 11 || var_45D5B0_animation_state > 19) {
+ var_45D5B0_animation_state = 16;
+ var_45D5B4_animation_frame = 0;
+ var_45D5BC = 0;
+ }
+ break;
+ case 15:
+ if (var_45D5B0_animation_state == 0 || var_45D5B0_animation_state == 1) {
+ var_45D5B0_animation_state = 2;
+ var_462880 = 15;
+ var_462884 = 596;
+ if (Game_Flag_Query(199) == 1) {
+ var_45D5B4_animation_frame = 0;
+ }
+ } else if (var_45D5B0_animation_state < 11 || var_45D5B0_animation_state > 19) {
+ var_45D5B0_animation_state = 15;
+ var_45D5B4_animation_frame = 0;
+ var_45D5BC = 0;
+ }
+ break;
+ case 14:
+ if (var_45D5B0_animation_state == 0 || var_45D5B0_animation_state == 1) {
+ var_45D5B0_animation_state = 2;
+ var_462880 = 14;
+ var_462884 = 595;
+ if (Game_Flag_Query(199) == 1) {
+ var_45D5B4_animation_frame = 0;
+ }
+ } else if (var_45D5B0_animation_state < 11 || var_45D5B0_animation_state > 19) {
+ var_45D5B0_animation_state = 14;
+ var_45D5B4_animation_frame = 0;
+ var_45D5BC = 0;
+ }
+ break;
+ case 13:
+ if (var_45D5B0_animation_state == 0 || var_45D5B0_animation_state == 1) {
+ var_45D5B0_animation_state = 2;
+ var_462880 = 13;
+ var_462884 = 594;
+ if (Game_Flag_Query(199) == 1) {
+ var_45D5B4_animation_frame = 0;
+ }
+ } else if (var_45D5B0_animation_state < 11 || var_45D5B0_animation_state > 19) {
+ var_45D5B0_animation_state = 13;
+ var_45D5B4_animation_frame = 0;
+ var_45D5BC = 0;
+ }
+ break;
+ case 12:
+ if (var_45D5B0_animation_state == 0 || var_45D5B0_animation_state == 1) {
+ var_45D5B0_animation_state = 2;
+ var_462880 = 12;
+ var_462884 = 593;
+ if (Game_Flag_Query(199) == 1) {
+ var_45D5B4_animation_frame = 0;
+ }
+ } else if (var_45D5B0_animation_state < 11 || var_45D5B0_animation_state > 19) {
+ var_45D5B0_animation_state = 12;
+ var_45D5B4_animation_frame = 0;
+ var_45D5BC = 0;
+ }
+ break;
+ case 8:
+ var_45D5B0_animation_state = 8;
+ var_45D5B4_animation_frame = 0;
+ break;
+ case 7:
+ var_45D5B0_animation_state = 7;
+ var_45D5B4_animation_frame = 0;
+ break;
+ case 6:
+ var_45D5B0_animation_state = 24;
+ var_45D5B4_animation_frame = 0;
+ break;
+ case 4:
+ switch (var_45D5B0_animation_state) {
+ case 21:
+ case 22:
+ case 24:
+ return true;
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ var_45D5B0_animation_state = 21;
+ var_45D5B4_animation_frame = 0;
+ break;
+ case 0:
+ var_45D5B0_animation_state = 22;
+ var_45D5B4_animation_frame = 0;
+ break;
+ default:
+ var_45D5B0_animation_state = 21;
+ var_45D5B4_animation_frame = 0;
+ break;
+ }
+ break;
+ case 3:
+ if (var_45D5B0_animation_state == 0 || var_45D5B0_animation_state == 1) {
+ var_45D5B0_animation_state = 2;
+ var_462880 = 11;
+ var_462884 = 592;
+ if (Game_Flag_Query(199) == 1) {
+ var_45D5B4_animation_frame = 0;
+ }
+ } else if (var_45D5B0_animation_state < 11 || var_45D5B0_animation_state > 19) {
+ var_45D5B0_animation_state = 11;
+ var_45D5B4_animation_frame = 0;
+ var_45D5BC = 0;
+ }
+ break;
+ case 2:
+ var_45D5B0_animation_state = 4;
+ var_45D5B4_animation_frame = 0;
+ break;
+ case 1:
+ var_45D5B0_animation_state = 3;
+ var_45D5B4_animation_frame = 0;
+ break;
+ case 0:
+ switch (var_45D5B0_animation_state) {
+ case 21:
+ case 24:
+ var_45D5B0_animation_state = 23;
+ var_45D5B4_animation_frame = 0;
+ break;
+ case 20:
+ v1 = var_45D5B4_animation_frame;
+ Actor_Change_Animation_Mode(23, 4);
+ var_45D5B4_animation_frame = v1;
+ var_45D5B0_animation_state = 21;
+ break;
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ case 16:
+ case 17:
+ case 18:
+ case 19:
+ var_45D5BC = 1;
+ break;
+ case 0:
+ case 23:
+ return true;
+ default:
+ var_45D5B0_animation_state = 0;
+ var_45D5B4_animation_frame = 0;
+ var_45D5B8 = Random_Query(0, 1);
+ break;
+ }
+ break;
+ case 5:
+ case 9:
+ case 10:
+ case 11:
+ case 20:
+ case 23:
+ case 24:
+ case 25:
+ case 26:
+ return true;
+ default:
+ switch (mode) {
+ case 58:
+ var_45D5B0_animation_state = 20;
+ var_45D5B4_animation_frame = 0;
+ break;
+ case 48:
+ if (var_45D5B0_animation_state == 21 || var_45D5B0_animation_state == 22 || var_45D5B0_animation_state == 24) {
+ var_45D5B0_animation_state = 28;
+ var_45D5B4_animation_frame = 0;
+ } else {
+ var_45D5B0_animation_state = 27;
+ var_45D5B4_animation_frame = 0;
+ }
+ break;
+ case 47:
+ var_45D5B0_animation_state = 10;
+ var_45D5B4_animation_frame = 0;
+ break;
+ case 46:
+ var_45D5B0_animation_state = 9;
+ var_45D5B4_animation_frame = 0;
+ break;
+ case 45:
+ var_45D5B0_animation_state = 6;
+ var_45D5B4_animation_frame = 0;
+ break;
+ case 44:
+ var_45D5B0_animation_state = 5;
+ var_45D5B4_animation_frame = 0;
+ break;
+ default:
+ return true;
+ }
+ break;
+ }
+ return true;
+}
+
+void AIScript_Officer_Leroy::QueryAnimationState(int *animationState, int *animationFrame, int *a3, int *a4) {
+ *animationState = var_45D5B0_animation_state;
+ *animationFrame = var_45D5B4_animation_frame;
+ *a3 = var_462880;
+ *a4 = var_462884;
+}
+
+void AIScript_Officer_Leroy::SetAnimationState(int animationState, int animationFrame, int a3, int a4) {
+ var_45D5B0_animation_state = animationState;
+ var_45D5B4_animation_frame = animationFrame;
+ var_462880 = a3;
+ var_462884 = a4;
+}
+
+bool AIScript_Officer_Leroy::ReachedMovementTrackWaypoint(int waypointId) {
+ if (waypointId == 57 || waypointId == 58) {
+ sub_431408();
+ AI_Countdown_Timer_Reset(23, 2);
+ AI_Countdown_Timer_Start(23, 2, 6);
+ }
+ return true;
+}
+
+void AIScript_Officer_Leroy::FledCombat() {
+ Actor_Set_Goal_Number(23, 300);
+}
+
+bool AIScript_Officer_Leroy::sub_431408() {
+ Game_Flag_Set(199);
+ return true;
+}
+
+bool AIScript_Officer_Leroy::sub_431420() {
+ Game_Flag_Reset(199);
+ return true;
+}
+} // End of namespace BladeRunner
diff --git a/engines/bladerunner/script/aiscript_officer_leroy.h b/engines/bladerunner/script/ai_23_officer_leroy.h
index 152ba83463..c78d80db4e 100644
--- a/engines/bladerunner/script/aiscript_officer_leroy.h
+++ b/engines/bladerunner/script/ai_23_officer_leroy.h
@@ -28,8 +28,11 @@ namespace BladeRunner {
class AIScript_Officer_Leroy : public AIScriptBase {
int var_45D5B0_animation_state;
- int var_45D5B4_frame;
+ int var_45D5B4_animation_frame;
int var_45D5B8;
+ int var_45D5BC;
+ int var_462880;
+ int var_462884;
public:
AIScript_Officer_Leroy(BladeRunnerEngine *vm);
@@ -40,19 +43,24 @@ public:
void ReceivedClue(int clueId, int fromActorId);
void ClickedByPlayer();
void EnteredScene(int sceneId);
- void OtherAgentEnteredThisScene();
- void OtherAgentExitedThisScene();
- void OtherAgentEnteredCombatMode();
+ void OtherAgentEnteredThisScene(int otherActorId);
+ void OtherAgentExitedThisScene(int otherActorId);
+ void OtherAgentEnteredCombatMode(int otherActorId, int combatMode);
void ShotAtAndMissed();
void ShotAtAndHit();
void Retired(int byActorId);
- void GetFriendlinessModifierIfGetsClue();
+ int GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId);
bool GoalChanged(int currentGoalNumber, int newGoalNumber);
bool UpdateAnimation(int *animation, int *frame);
bool ChangeAnimationMode(int mode);
- void QueryAnimationState(int *animationState, int *a2, int *a3, int *a4);
- void SetAnimationState(int animationState, int a2, int a3, int a4);
- bool ReachedMovementTrackWaypoint();
+ void QueryAnimationState(int *animationState, int *animationFrame, int *a3, int *a4);
+ void SetAnimationState(int animationState, int animationFrame, int a3, int a4);
+ bool ReachedMovementTrackWaypoint(int a1);
+ void FledCombat();
+
+private:
+ bool sub_431408();
+ bool sub_431420();
};
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/script/aiscript_officer_leroy.cpp b/engines/bladerunner/script/aiscript_officer_leroy.cpp
deleted file mode 100644
index 7881984154..0000000000
--- a/engines/bladerunner/script/aiscript_officer_leroy.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "bladerunner/script/aiscript_officer_leroy.h"
-
-namespace BladeRunner {
-
-AIScript_Officer_Leroy::AIScript_Officer_Leroy(BladeRunnerEngine *vm)
- : AIScriptBase(vm) {
-}
-
-void AIScript_Officer_Leroy::Initialize() {
- var_45D5B0_animation_state = 0;
- var_45D5B4_frame = 0;
- var_45D5B8 = 0;
-
- Actor_Put_In_Set(23, 69);
- Actor_Set_At_XYZ(23, -261.80f, 6.00f, 79.58f, 512);
- // Actor_Set_Goal_Number(23, 0);
- // Actor_Set_Frame_Rate_FPS(23, 8);
-}
-
-bool AIScript_Officer_Leroy::Update() {
- return false;
-}
-
-void AIScript_Officer_Leroy::TimerExpired(int timer) {
-}
-
-void AIScript_Officer_Leroy::CompletedMovementTrack() {
-}
-
-void AIScript_Officer_Leroy::ReceivedClue(int clueId, int fromActorId) {
-}
-
-void AIScript_Officer_Leroy::ClickedByPlayer() {
-}
-
-void AIScript_Officer_Leroy::EnteredScene(int sceneId) {
-}
-
-void AIScript_Officer_Leroy::OtherAgentEnteredThisScene() {
-}
-
-void AIScript_Officer_Leroy::OtherAgentExitedThisScene() {
-}
-
-void AIScript_Officer_Leroy::OtherAgentEnteredCombatMode() {
-}
-
-void AIScript_Officer_Leroy::ShotAtAndMissed() {
-}
-
-void AIScript_Officer_Leroy::ShotAtAndHit() {
-}
-
-void AIScript_Officer_Leroy::Retired(int byActorId) {
-}
-
-void AIScript_Officer_Leroy::GetFriendlinessModifierIfGetsClue() {
-}
-
-bool AIScript_Officer_Leroy::GoalChanged(int currentGoalNumber, int newGoalNumber) {
- return false;
-}
-
-bool AIScript_Officer_Leroy::UpdateAnimation(int *animation, int *frame) {
- if (var_45D5B8 == 0) {
- *animation = 589;
- var_45D5B4_frame++;
-
- if (var_45D5B4_frame >= Slice_Animation_Query_Number_Of_Frames(589)) {
- var_45D5B4_frame = 0;
- var_45D5B8 = Random_Query(0, 2);
- }
- } else if (var_45D5B8 == 1) {
- *animation = 590;
- var_45D5B4_frame++;
-
- if (var_45D5B4_frame >= Slice_Animation_Query_Number_Of_Frames(590)) {
- var_45D5B4_frame = 0;
- var_45D5B8 = Random_Query(0, 2);
- }
- } else if (var_45D5B8 == 2) {
- *animation = 591;
- var_45D5B4_frame++;
-
- if (var_45D5B4_frame >= Slice_Animation_Query_Number_Of_Frames(591)) {
- var_45D5B4_frame = 0;
- var_45D5B8 = Random_Query(0, 2);
- }
- }
- *frame = var_45D5B4_frame;
- return true;
-}
-
-bool AIScript_Officer_Leroy::ChangeAnimationMode(int mode) {
- switch (mode) {
- case 1:
- var_45D5B0_animation_state = 32;
- break;
- }
- return true;
-}
-
-void AIScript_Officer_Leroy::QueryAnimationState(int *animationState, int *a2, int *a3, int *a4) {
-}
-
-void AIScript_Officer_Leroy::SetAnimationState(int animationState, int a2, int a3, int a4) {
-}
-
-bool AIScript_Officer_Leroy::ReachedMovementTrackWaypoint() {
- return false;
-}
-} // End of namespace BladeRunner
diff --git a/engines/bladerunner/script/script.cpp b/engines/bladerunner/script/script.cpp
index 45b23120d5..bc6679051c 100644
--- a/engines/bladerunner/script/script.cpp
+++ b/engines/bladerunner/script/script.cpp
@@ -48,7 +48,8 @@
#include "bladerunner/waypoints.h"
#include "bladerunner/script/ai_00_mccoy.h"
-#include "bladerunner/script/aiscript_officer_leroy.h"
+#include "bladerunner/script/ai_15_runciter.h"
+#include "bladerunner/script/ai_23_officer_leroy.h"
namespace BladeRunner {
@@ -190,7 +191,7 @@ void ScriptBase::Actor_Set_At_XYZ(int actorId, float x, float y, float z, int di
}
void ScriptBase::Actor_Set_At_Waypoint(int actorId, int waypointId, int angle) {
- _vm->_actors[actorId]->setAtWaypoint(waypointId, angle, 0, 0);
+ _vm->_actors[actorId]->setAtWaypoint(waypointId, angle, 0, false);
}
bool ScriptBase::Region_Check(int left, int top, int right, int down) {
@@ -500,11 +501,11 @@ bool ScriptBase::Actor_Query_In_Between_Two_Actors(int actorId, int otherActor1I
float z1 = _vm->_actors[otherActor1Id]->getZ();
float x2 = _vm->_actors[otherActor2Id]->getX();
float z2 = _vm->_actors[otherActor2Id]->getZ();
- return _vm->_sceneObjects->isBetweenTwoXZ(actorId, x1, z1, x2, z1)
- || _vm->_sceneObjects->isBetweenTwoXZ(actorId, x1 - 12.0f, z1 - 12.0f, x2 - 12.0f, z2 - 12.0f)
- || _vm->_sceneObjects->isBetweenTwoXZ(actorId, x1 + 12.0f, z1 - 12.0f, x2 + 12.0f, z2 - 12.0f)
- || _vm->_sceneObjects->isBetweenTwoXZ(actorId, x1 + 12.0f, z1 + 12.0f, x2 + 12.0f, z2 + 12.0f)
- || _vm->_sceneObjects->isBetweenTwoXZ(actorId, x1 - 12.0f, z1 + 12.0f, x2 - 12.0f, z2 + 12.0f);
+ return _vm->_sceneObjects->isBetweenTwoXZ(actorId + SCENE_OBJECTS_ACTORS_OFFSET, x1, z1, x2, z1)
+ || _vm->_sceneObjects->isBetweenTwoXZ(actorId + SCENE_OBJECTS_ACTORS_OFFSET, x1 - 12.0f, z1 - 12.0f, x2 - 12.0f, z2 - 12.0f)
+ || _vm->_sceneObjects->isBetweenTwoXZ(actorId + SCENE_OBJECTS_ACTORS_OFFSET, x1 + 12.0f, z1 - 12.0f, x2 + 12.0f, z2 - 12.0f)
+ || _vm->_sceneObjects->isBetweenTwoXZ(actorId + SCENE_OBJECTS_ACTORS_OFFSET, x1 + 12.0f, z1 + 12.0f, x2 + 12.0f, z2 + 12.0f)
+ || _vm->_sceneObjects->isBetweenTwoXZ(actorId + SCENE_OBJECTS_ACTORS_OFFSET, x1 - 12.0f, z1 + 12.0f, x2 - 12.0f, z2 + 12.0f);
}
void ScriptBase::Actor_Set_Goal_Number(int actorId, int goalNumber) {
@@ -542,26 +543,61 @@ int ScriptBase::Actor_Query_Animation_Mode(int actorId) {
}
bool ScriptBase::Loop_Actor_Walk_To_Actor(int actorId, int otherActorId, int a3, int a4, bool run) {
- //TODO
- warning("Loop_Actor_Walk_To_Actor(%d, %d, %d, %d, %d)", actorId, otherActorId, a3, a4, run);
- return false;
+ _vm->gameWaitForActive();
+
+ if (actorId == _vm->_walkingActorId) {
+ run = true;
+ }
+ _vm->_playerActorIdle = false;
+ bool isRunning;
+ bool result = _vm->_actors[actorId]->loopWalkToActor(otherActorId, a3, a4, run, true, &isRunning);
+ if (_vm->_playerActorIdle) {
+ result = true;
+ _vm->_playerActorIdle = false;
+ }
+ if (isRunning == 1) {
+ _vm->_walkingActorId = actorId;
+ }
+ Global_Variable_Set(37, actorId);
+ Global_Variable_Set(38, isRunning);
+ return result;
}
bool ScriptBase::Loop_Actor_Walk_To_Item(int actorId, int itemId, int a3, int a4, bool run) {
- //TODO
- warning("Loop_Actor_Walk_To_Item(%d, %d, %d, %d, %d)", actorId, itemId, a3, a4, run);
- return false;
+ _vm->gameWaitForActive();
+
+ if (_vm->_walkingActorId == actorId) {
+ run = true;
+ }
+ _vm->_playerActorIdle = false;
+ bool isRunning;
+ bool result = _vm->_actors[actorId]->loopWalkToItem(itemId, a3, a4, run, true, &isRunning);
+ if (_vm->_playerActorIdle == 1) {
+ result = true;
+ _vm->_playerActorIdle = false;
+ }
+ if (isRunning == 1) {
+ _vm->_walkingActorId = actorId;
+ }
+ Global_Variable_Set(37, actorId);
+ Global_Variable_Set(38, isRunning);
+ return result;
}
bool ScriptBase::Loop_Actor_Walk_To_Scene_Object(int actorId, const char *objectName, int destinationOffset, bool a4, bool run) {
_vm->gameWaitForActive();
- if(_vm->_walkingActorId == actorId) {
+ if (_vm->_walkingActorId == actorId) {
run = true;
}
+ _vm->_playerActorIdle = false;
bool isRunning;
bool result = _vm->_actors[actorId]->loopWalkToSceneObject(objectName, destinationOffset, a4, run, true, &isRunning);
- if(isRunning == 1) {
+ if (_vm->_playerActorIdle) {
+ result = true;
+ _vm->_playerActorIdle = false;
+ }
+ if (isRunning == 1) {
_vm->_walkingActorId = actorId;
}
Global_Variable_Set(37, actorId);
@@ -1070,28 +1106,21 @@ void ScriptBase::Scene_2D_Region_Remove(int index) {
_vm->_scene->_regions->remove(index);
}
-void ScriptBase::World_Waypoint_Set(int waypointId, int sceneId, float x, float y, float z) {
- //TODO
- warning("World_Waypoint_Set(%d, %d, %f, %f, %f)", waypointId, sceneId, x, y, z);
+void ScriptBase::World_Waypoint_Set(int waypointId, int setId, float x, float y, float z) {
+ _vm->_waypoints->set(waypointId, setId, Vector3(x, y, z));
}
// ScriptBase::World_Waypoint_Reset
float ScriptBase::World_Waypoint_Query_X(int waypointId) {
- //TODO
- warning("World_Waypoint_Query_X(%d)", waypointId);
- return 0.0f;
+ return _vm->_waypoints->getX(waypointId);
}
float ScriptBase::World_Waypoint_Query_Y(int waypointId) {
- //TODO
- warning("World_Waypoint_Query_Y(%d)", waypointId);
- return 0.0f;
+ return _vm->_waypoints->getY(waypointId);
}
float ScriptBase::World_Waypoint_Query_Z(int waypointId) {
- //TODO
- warning("World_Waypoint_Query_Z(%d)", waypointId);
- return 0.0f;
+ return _vm->_waypoints->getZ(waypointId);
}
void ScriptBase::Combat_Cover_Waypoint_Set_Data(int combatCoverId, int a2, int sceneId, int a4, float x, float y, float z) {
@@ -1243,7 +1272,7 @@ void ScriptBase::Actor_Retired_Here(int actorId, int width, int height, int reti
actor->getXYZ(&actorPosition.x, &actorPosition.y, &actorPosition.z);
actor->retire(retired, width, height, retiredByActorId);
actor->setAtXYZ(actorPosition, actor->getFacing(), true, 0, true);
- _vm->_sceneObjects->setRetired(actorId, true);
+ _vm->_sceneObjects->setRetired(actorId + SCENE_OBJECTS_ACTORS_OFFSET, true);
}
void ScriptBase::Clickable_Object(const char *objectName) {
@@ -1335,26 +1364,28 @@ void ScriptBase::I_Sez(const char *str) {
}
void ScriptBase::AI_Countdown_Timer_Start(int actorId, signed int timer, int seconds) {
-// if (timer >= 0 && timer <= 2)
-// _vm->_actors[actorId]->timerSet(timer, 1000 * seconds);
+ if (timer >= 0 && timer <= 2) {
+ _vm->_actors[actorId]->countdownTimerStart(timer, 1000 * seconds);
+ }
}
void ScriptBase::AI_Countdown_Timer_Reset(int actorId, int timer) {
-// if (timer >= 0 && timer <= 2)
-// _vm->_actors[actorId]->timerReset(timer);
+ if (timer >= 0 && timer <= 2) {
+ _vm->_actors[actorId]->countdownTimerReset(timer);
+ }
}
void ScriptBase::AI_Movement_Track_Unpause(int actorId) {
- //_vm->_actors[actorId]->movementTrackUnpause();
+ _vm->_actors[actorId]->movementTrackUnpause();
}
void ScriptBase::AI_Movement_Track_Pause(int actorId) {
- //_vm->_actors[actorId]->movementTrackPause();
+ _vm->_actors[actorId]->movementTrackPause();
}
void ScriptBase::AI_Movement_Track_Repeat(int actorId) {
_vm->_actors[actorId]->_movementTrack->repeat();
- //_vm->_actors[actorId]->movementTrackRepeat(1);
+ _vm->_actors[actorId]->movementTrackNext(true);
}
void ScriptBase::AI_Movement_Track_Append_Run_With_Facing(int actorId, int waypointId, int delay, int angle) {
@@ -1423,37 +1454,131 @@ void ScriptBase::VK_Play_Speech_Line(int actorIndex, int a2, float a3) {
warning("VK_Play_Speech_Line(%d, %d, %g)", actorIndex, a2, a3);
}
-AIScripts::AIScripts(BladeRunnerEngine *vm) : _vm(vm), _inScriptCounter(0) {
- for (int i = 0; i != 100; ++i)
+AIScripts::AIScripts(BladeRunnerEngine *vm, int actorsCount) : _vm(vm), _inScriptCounter(0) {
+ _actorsCount = actorsCount;
+ _actorUpdating = new bool[actorsCount];
+ _AIScripts = new AIScriptBase*[actorsCount];
+ for (int i = 0; i < actorsCount; ++i) {
_AIScripts[i] = nullptr;
+ _actorUpdating[i] = false;
+ }
_AIScripts[0] = new AIScript_McCoy(_vm);
+ _AIScripts[15] = new AIScript_Runciter(_vm);
_AIScripts[23] = new AIScript_Officer_Leroy(_vm);
}
AIScripts::~AIScripts() {
- for (int i = 0; i != 100; ++i) {
+ for (int i = 0; i < _actorsCount; ++i) {
delete _AIScripts[i];
_AIScripts[i] = nullptr;
}
+ delete[] _AIScripts;
+ delete[] _actorUpdating;
}
void AIScripts::Initialize(int actor) {
+ assert(actor < _actorsCount);
if (_AIScripts[actor])
_AIScripts[actor]->Initialize();
}
+void AIScripts::Update(int actor) {
+ assert(actor < _actorsCount);
+ if (this->_actorUpdating[actor] != 1) {
+ this->_actorUpdating[actor] = true;
+ ++this->_inScriptCounter;
+ if (_AIScripts[actor])
+ _AIScripts[actor]->Update();
+ --this->_inScriptCounter;
+ this->_actorUpdating[actor] = false;
+ }
+}
+
+void AIScripts::TimerExpired(int actor, int timer) {
+ assert(actor < _actorsCount);
+ _inScriptCounter++;
+ if (_AIScripts[actor]) {
+ _AIScripts[actor]->TimerExpired(timer);
+ }
+ _inScriptCounter--;
+}
+
+void AIScripts::CompletedMovementTrack(int actor) {
+ assert(actor < _actorsCount);
+ if (!_vm->_actors[actor]->inCombat()) {
+ _inScriptCounter++;
+ if (_AIScripts[actor]) {
+ _AIScripts[actor]->CompletedMovementTrack();
+ }
+ _inScriptCounter--;
+ }
+}
+
+void AIScripts::EnteredScene(int actor, int setId) {
+ assert(actor < _actorsCount);
+ _inScriptCounter++;
+ if (_AIScripts[actor]) {
+ _AIScripts[actor]->EnteredScene(setId);
+ }
+ _inScriptCounter--;
+}
+
+void AIScripts::OtherAgentEnteredThisScene(int actor, int otherActorId) {
+ assert(actor < _actorsCount);
+ _inScriptCounter++;
+ if (_AIScripts[actor]) {
+ _AIScripts[actor]->OtherAgentEnteredThisScene(otherActorId);
+ }
+ _inScriptCounter--;
+}
+
+void AIScripts::OtherAgentExitedThisScene(int actor, int otherActorId) {
+ assert(actor < _actorsCount);
+ _inScriptCounter++;
+ if (_AIScripts[actor]) {
+ _AIScripts[actor]->OtherAgentExitedThisScene(otherActorId);
+ }
+ _inScriptCounter--;
+}
+
+void AIScripts::GoalChanged(int actor, int currentGoalNumber, int newGoalNumber) {
+ assert(actor < _actorsCount);
+ _inScriptCounter++;
+ if (_AIScripts[actor]) {
+ _AIScripts[actor]->GoalChanged(currentGoalNumber, newGoalNumber);
+ }
+ _inScriptCounter--;
+}
+
+bool AIScripts::ReachedMovementTrackWaypoint(int actor, int waypointId) {
+ assert(actor < _actorsCount);
+ bool result = false;
+ if (!_vm->_actors[actor]->inCombat()) {
+ _inScriptCounter++;
+ if (_AIScripts[actor]) {
+ result = _AIScripts[actor]->ReachedMovementTrackWaypoint(waypointId);
+ }
+ _inScriptCounter--;
+ }
+ return result;
+}
+
void AIScripts::UpdateAnimation(int actor, int *animation, int *frame) {
+ assert(actor < _actorsCount);
_inScriptCounter++;
- if (_AIScripts[actor])
+ if (_AIScripts[actor]) {
_AIScripts[actor]->UpdateAnimation(animation, frame);
+ }
_inScriptCounter--;
}
void AIScripts::ChangeAnimationMode(int actor, int mode) {
+ assert(actor < _actorsCount);
_inScriptCounter++;
- if (_AIScripts[actor])
+ if (_AIScripts[actor]) {
_AIScripts[actor]->ChangeAnimationMode(mode);
+ }
_inScriptCounter--;
}
diff --git a/engines/bladerunner/script/script.h b/engines/bladerunner/script/script.h
index 5966b67868..8577078c0d 100644
--- a/engines/bladerunner/script/script.h
+++ b/engines/bladerunner/script/script.h
@@ -304,11 +304,12 @@ public:
*/
class Script {
-public:
+protected:
BladeRunnerEngine *_vm;
int _inScriptCounter;
SceneScriptBase *_currentScript;
+public:
Script(BladeRunnerEngine *vm)
: _vm(vm),
_inScriptCounter(0),
@@ -331,6 +332,7 @@ public:
void PlayerWalkedIn();
void PlayerWalkedOut();
void DialogueQueueFlushed(int a1);
+ bool IsInsideScript() { return _inScriptCounter > 0; }
};
#define DECLARE_SCRIPT(name) \
@@ -820,34 +822,47 @@ public:
virtual void CompletedMovementTrack() = 0;
virtual void ReceivedClue(int clueId, int fromActorId) = 0;
virtual void ClickedByPlayer() = 0;
- virtual void EnteredScene(int sceneId) = 0;
- virtual void OtherAgentEnteredThisScene() = 0;
- virtual void OtherAgentExitedThisScene() = 0;
- virtual void OtherAgentEnteredCombatMode() = 0;
+ virtual void EnteredScene(int setId) = 0;
+ virtual void OtherAgentEnteredThisScene(int otherActorId) = 0;
+ virtual void OtherAgentExitedThisScene(int otherActorId) = 0;
+ virtual void OtherAgentEnteredCombatMode(int otherActorId, int combatMode) = 0;
virtual void ShotAtAndMissed() = 0;
virtual void ShotAtAndHit() = 0;
virtual void Retired(int byActorId) = 0;
- virtual void GetFriendlinessModifierIfGetsClue() = 0;
+ virtual int GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) = 0;
virtual bool GoalChanged(int currentGoalNumber, int newGoalNumber) = 0;
virtual bool UpdateAnimation(int *animation, int *frame) = 0;
virtual bool ChangeAnimationMode(int mode) = 0;
virtual void QueryAnimationState(int *animationState, int *a2, int *a3, int *a4) = 0;
virtual void SetAnimationState(int animationState, int a2, int a3, int a4) = 0;
- virtual bool ReachedMovementTrackWaypoint() = 0;
+ virtual bool ReachedMovementTrackWaypoint(int waypointId) = 0;
+ virtual void FledCombat() = 0;
};
class AIScripts {
-public:
+private:
BladeRunnerEngine *_vm;
int _inScriptCounter;
- AIScriptBase *_AIScripts[100];
-
- AIScripts(BladeRunnerEngine *vm);
+ int _actorsCount;
+ AIScriptBase **_AIScripts;
+ bool *_actorUpdating;
+public:
+ AIScripts(BladeRunnerEngine *vm, int actorsCount);
~AIScripts();
void Initialize(int actor);
+ void Update(int actor);
+ void TimerExpired(int actor, int timer);
+ void CompletedMovementTrack(int actor);
+ void EnteredScene(int actor, int setId);
+ void OtherAgentEnteredThisScene(int actor, int otherActorId);
+ void OtherAgentExitedThisScene(int actor, int otherActorId);
+ void GoalChanged(int actor, int currentGoalNumber, int newGoalNumber);
+ bool ReachedMovementTrackWaypoint(int actor, int waypointId);
void UpdateAnimation(int actor, int *animation, int *frame);
void ChangeAnimationMode(int actor, int mode);
+
+ bool IsInsideScript() { return _inScriptCounter > 0; }
};
} // End of namespace BladeRunner
diff --git a/engines/director/archive.cpp b/engines/director/archive.cpp
index f426107ee3..340db3d9c1 100644
--- a/engines/director/archive.cpp
+++ b/engines/director/archive.cpp
@@ -275,8 +275,8 @@ bool RIFFArchive::openStream(Common::SeekableReadStream *stream, uint32 startOff
if (tag == 0)
break;
- uint16 startResPos = stream->pos();
- stream->seek(offset + 12);
+ uint32 startResPos = stream->pos();
+ stream->seek(startOffset + offset + 12);
Common::String name = "";
byte nameSize = stream->readByte();
@@ -289,11 +289,11 @@ bool RIFFArchive::openStream(Common::SeekableReadStream *stream, uint32 startOff
stream->seek(startResPos);
- debug(3, "Found RIFF resource '%s' %d: %d @ 0x%08x", tag2str(tag), id, size, offset);
+ debug(3, "Found RIFF resource '%s' %d: %d @ 0x%08x", tag2str(tag), id, size, startOffset + offset);
ResourceMap &resMap = _types[tag];
Resource &res = resMap[id];
- res.offset = offset;
+ res.offset = offset + startOffset;
res.size = size;
res.name = name;
}
diff --git a/engines/director/events.cpp b/engines/director/events.cpp
index 32fe58859e..f4806f332e 100644
--- a/engines/director/events.cpp
+++ b/engines/director/events.cpp
@@ -46,13 +46,13 @@ void DirectorEngine::processEvents() {
uint endTime = g_system->getMillis() + 200;
Score *sc = getCurrentScore();
+ if (sc->getCurrentFrame() >= sc->_frames.size()) {
+ warning("processEvents: request to access frame %d of %d", sc->getCurrentFrame(), sc->_frames.size() - 1);
+ return;
+ }
Frame *currentFrame = sc->_frames[sc->getCurrentFrame()];
uint16 spriteId = 0;
- // TODO: re-instate when we know which script to run.
- //if (currentFrame > 0)
- // _lingo->processEvent(kEventIdle, currentFrame - 1);
-
Common::Point pos;
while (g_system->getMillis() < endTime) {
@@ -70,6 +70,8 @@ void DirectorEngine::processEvents() {
spriteId = currentFrame->getSpriteIDFromPos(pos);
sc->_currentMouseDownSpriteId = spriteId;
+ debugC(3, kDebugEvents, "event: Button Down @(%d, %d), sprite id: %d", pos.x, pos.y, spriteId);
+
if (getVersion() > 3) {
// TODO: check that this is the order of script execution!
_lingo->processEvent(kEventMouseDown, kCastScript, currentFrame->_sprites[spriteId]->_castId);
@@ -85,16 +87,19 @@ void DirectorEngine::processEvents() {
pos = g_system->getEventManager()->getMousePos();
spriteId = currentFrame->getSpriteIDFromPos(pos);
+
+ debugC(3, kDebugEvents, "event: Button Up @(%d, %d), sprite id: %d", pos.x, pos.y, spriteId);
+
if (getVersion() > 3) {
// TODO: check that this is the order of script execution!
- _lingo->processEvent(kEventMouseUp, kCastScript, currentFrame->_sprites[spriteId]->_castId);
- _lingo->processEvent(kEventMouseUp, kSpriteScript, currentFrame->_sprites[spriteId]->_scriptId);
+ _lingo->processEvent(kEventNone, kCastScript, currentFrame->_sprites[spriteId]->_castId);
+ _lingo->processEvent(kEventNone, kSpriteScript, currentFrame->_sprites[spriteId]->_scriptId);
} else {
// Frame script overrides sprite script
if (!currentFrame->_sprites[spriteId]->_scriptId)
- _lingo->processEvent(kEventMouseUp, kSpriteScript, currentFrame->_sprites[spriteId]->_castId + 1024);
+ _lingo->processEvent(kEventNone, kSpriteScript, currentFrame->_sprites[spriteId]->_castId + 1024);
else
- _lingo->processEvent(kEventMouseUp, kFrameScript, currentFrame->_sprites[spriteId]->_scriptId);
+ _lingo->processEvent(kEventNone, kFrameScript, currentFrame->_sprites[spriteId]->_scriptId);
}
sc->_currentMouseDownSpriteId = 0;
@@ -131,6 +136,9 @@ void DirectorEngine::processEvents() {
g_system->updateScreen();
g_system->delayMillis(10);
+
+ if (sc->getCurrentFrame() > 0)
+ _lingo->processEvent(kEventIdle, kFrameScript, sc->getCurrentFrame());
}
}
diff --git a/engines/director/frame.cpp b/engines/director/frame.cpp
index cceecdd579..92aa851d06 100644
--- a/engines/director/frame.cpp
+++ b/engines/director/frame.cpp
@@ -222,10 +222,14 @@ void Frame::readChannels(Common::ReadStreamEndian *stream) {
sprite._unk3 = stream->readUint32();
}
- debugC(kDebugLoading, 8, "%03d(%d)[%x,%x,%04x,%d/%d/%d/%d/%d] script:%d",
- sprite._castId, sprite._enabled, sprite._x1, sprite._x2, sprite._flags,
- sprite._startPoint.x, sprite._startPoint.y, sprite._width, sprite._height,
- sprite._lineSize, sprite._scriptId);
+ if (sprite._castId) {
+ debugC(kDebugLoading, 4, "CH: %-3d castId: %03d(%s) (e:%d) [%x,%x, flags:%04x, %dx%d@%d,%d linesize: %d] script: %d",
+ i + 1, sprite._castId, numToCastNum(sprite._castId), sprite._enabled, sprite._x1, sprite._x2, sprite._flags,
+ sprite._width, sprite._height, sprite._startPoint.x, sprite._startPoint.y,
+ sprite._lineSize, sprite._scriptId);
+ } else {
+ debugC(kDebugLoading, 4, "CH: %-3d castId: 000", i + 1);
+ }
}
}
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index cb6a7d67ec..e12b20a3c2 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -1232,7 +1232,7 @@ void Lingo::b_rollOver(int nargs) {
Frame *frame = g_director->getCurrentScore()->_frames[g_director->getCurrentScore()->getCurrentFrame()];
- if (arg >= frame->_sprites.size()) {
+ if (arg >= (int32) frame->_sprites.size()) {
g_lingo->push(d);
return;
}
diff --git a/engines/director/lingo/lingo-funcs.cpp b/engines/director/lingo/lingo-funcs.cpp
index 307d79a0a2..0f2110d8f1 100644
--- a/engines/director/lingo/lingo-funcs.cpp
+++ b/engines/director/lingo/lingo-funcs.cpp
@@ -182,14 +182,15 @@ void Lingo::func_goto(Datum &frame, Datum &movie) {
Common::String cleanedFilename;
- for (const byte *p = (const byte *)movie.u.s->c_str(); *p; p++)
- if (*p >= 0x20 && *p <= 0x7f)
- cleanedFilename += (const char) *p;
-
bool fileExists = false;
if (_vm->getPlatform() == Common::kPlatformMacintosh) {
Common::MacResManager resMan;
+
+ for (const byte *p = (const byte *)movie.u.s->c_str(); *p; p++)
+ if (*p >= 0x20 && *p <= 0x7f)
+ cleanedFilename += (const char) *p;
+
if (resMan.open(*movie.u.s)) {
fileExists = true;
cleanedFilename = *movie.u.s;
@@ -198,6 +199,8 @@ void Lingo::func_goto(Datum &frame, Datum &movie) {
}
} else {
Common::File file;
+ cleanedFilename = *movie.u.s + ".MMM";
+
if (file.open(*movie.u.s)) {
fileExists = true;
cleanedFilename = *movie.u.s;
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index f00d9a7d32..482531d455 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -299,7 +299,7 @@ void Lingo::processEvent(LEvent event, ScriptType st, int entityId) {
if (entityId < 0)
return;
- debugC(1, kDebugEvents, "Lingo::processEvent(%s, %s, %d)", _eventHandlerTypes[event], scriptType2str(st), entityId);
+ debugC(9, kDebugEvents, "Lingo::processEvent(%s, %s, %d)", _eventHandlerTypes[event], scriptType2str(st), entityId);
_currentEntityId = entityId;
@@ -307,11 +307,14 @@ void Lingo::processEvent(LEvent event, ScriptType st, int entityId) {
error("processEvent: Unknown event %d for entity %d", event, entityId);
if (_handlers.contains(ENTITY_INDEX(event, entityId))) {
+ debugC(1, kDebugEvents, "Lingo::processEvent(%s, %s, %d), _eventHandler", _eventHandlerTypes[event], scriptType2str(st), entityId);
call(_eventHandlerTypes[event], 0); // D4+ Events
- } else if (_scripts[st].contains(entityId)) {
+ } else if (event == kEventNone && _scripts[st].contains(entityId)) {
+ debugC(1, kDebugEvents, "Lingo::processEvent(%s, %s, %d), script", _eventHandlerTypes[event], scriptType2str(st), entityId);
+
executeScript(st, entityId); // D3 list of scripts.
} else {
- debugC(3, kDebugLingoExec, "STUB: processEvent(%s) for %d", _eventHandlerTypes[event], entityId);
+ //debugC(3, kDebugLingoExec, "STUB: processEvent(%s) for %d", _eventHandlerTypes[event], entityId);
}
}
diff --git a/engines/director/resource.cpp b/engines/director/resource.cpp
index 5a964c1687..dc961b86eb 100644
--- a/engines/director/resource.cpp
+++ b/engines/director/resource.cpp
@@ -20,7 +20,9 @@
*
*/
+#include "common/config-manager.h"
#include "common/macresman.h"
+
#include "graphics/macgui/macwindowmanager.h"
#include "graphics/macgui/macfontmanager.h"
@@ -76,6 +78,7 @@ void DirectorEngine::loadEXE(const Common::String movie) {
exeStream->seek(exeStream->readUint32LE());
switch (getVersion()) {
+ case 2:
case 3:
loadEXEv3(exeStream);
break;
@@ -100,16 +103,51 @@ void DirectorEngine::loadEXEv3(Common::SeekableReadStream *stream) {
stream->skip(5); // unknown
- stream->readUint32LE(); // Main MMM size
+ uint32 mmmSize = stream->readUint32LE(); // Main MMM size
+
Common::String mmmFileName = stream->readPascalString();
Common::String directoryName = stream->readPascalString();
debugC(1, kDebugLoading, "Main MMM: '%s'", mmmFileName.c_str());
debugC(1, kDebugLoading, "Directory Name: '%s'", directoryName.c_str());
+ debugC(1, kDebugLoading, "Main mmmSize: %d (0x%x)", mmmSize, mmmSize);
- openMainArchive(mmmFileName);
+ if (mmmSize) {
+ uint32 riffOffset = stream->pos();
+
+ debugC(1, kDebugLoading, "RIFF offset: %d (%x)", riffOffset, riffOffset);
+
+ if (ConfMan.getBool("dump_scripts")) {
+ Common::DumpFile out;
+ byte *buf = (byte *)malloc(mmmSize);
+ stream->read(buf, mmmSize);
+ stream->seek(riffOffset);
+ Common::String fname = Common::String::format("./dumps/%s", mmmFileName.c_str());
+
+
+ if (!out.open(fname.c_str())) {
+ warning("Can not open dump file %s", fname.c_str());
+ return;
+ }
+
+ out.write(buf, mmmSize);
+
+ out.flush();
+ out.close();
+
+ free(buf);
+ }
+
+
+ _mainArchive = new RIFFArchive();
+
+ if (!_mainArchive->openStream(stream, riffOffset))
+ error("Failed to load RIFF from EXE");
+
+ return;
+ }
- delete stream;
+ openMainArchive(mmmFileName);
}
void DirectorEngine::loadEXEv4(Common::SeekableReadStream *stream) {
@@ -200,13 +238,7 @@ void DirectorEngine::loadMac(const Common::String movie) {
void DirectorEngine::loadSharedCastsFrom(Common::String filename) {
Archive *shardcst = createArchive();
- debug(0, "Loading Shared cast '%s'", filename.c_str());
-
- if (!shardcst->openFile(filename)) {
- warning("No shared cast %s", filename.c_str());
-
- return;
- }
+ debug(0, "****** Loading Shared cast '%s'", filename.c_str());
_sharedDIB = new Common::HashMap<int, Common::SeekableSubReadStreamEndian *>;
_sharedSTXT = new Common::HashMap<int, Common::SeekableSubReadStreamEndian *>;
@@ -214,6 +246,12 @@ void DirectorEngine::loadSharedCastsFrom(Common::String filename) {
_sharedBMP = new Common::HashMap<int, Common::SeekableSubReadStreamEndian *>;
_sharedScore = new Score(this);
+ if (!shardcst->openFile(filename)) {
+ warning("No shared cast %s", filename.c_str());
+
+ return;
+ }
+
_sharedScore->setArchive(shardcst);
if (shardcst->hasResource(MKTAG('F', 'O', 'N', 'D'), -1)) {
@@ -229,12 +267,16 @@ void DirectorEngine::loadSharedCastsFrom(Common::String filename) {
Common::Array<uint16> cast = shardcst->getResourceIDList(MKTAG('C','A','S','t'));
if (cast.size() > 0) {
+ debug(0, "****** Loading %d CASt resources", cast.size());
+
for (Common::Array<uint16>::iterator iterator = cast.begin(); iterator != cast.end(); ++iterator)
_sharedScore->loadCastData(*shardcst->getResource(MKTAG('C','A','S','t'), *iterator), *iterator, NULL);
}
Common::Array<uint16> vwci = shardcst->getResourceIDList(MKTAG('V', 'W', 'C', 'I'));
if (vwci.size() > 0) {
+ debug(0, "****** Loading %d CastInfo resources", vwci.size());
+
for (Common::Array<uint16>::iterator iterator = vwci.begin(); iterator != vwci.end(); ++iterator)
_sharedScore->loadCastInfo(*shardcst->getResource(MKTAG('V', 'W', 'C', 'I'), *iterator), *iterator);
}
@@ -243,7 +285,7 @@ void DirectorEngine::loadSharedCastsFrom(Common::String filename) {
Common::Array<uint16> dib = shardcst->getResourceIDList(MKTAG('D','I','B',' '));
if (dib.size() != 0) {
- debugC(3, kDebugLoading, "Loading %d DIBs", dib.size());
+ debugC(3, kDebugLoading, "****** Loading %d DIBs", dib.size());
for (Common::Array<uint16>::iterator iterator = dib.begin(); iterator != dib.end(); ++iterator) {
debugC(3, kDebugLoading, "Shared DIB %d", *iterator);
@@ -253,7 +295,7 @@ void DirectorEngine::loadSharedCastsFrom(Common::String filename) {
Common::Array<uint16> stxt = shardcst->getResourceIDList(MKTAG('S','T','X','T'));
if (stxt.size() != 0) {
- debugC(3, kDebugLoading, "Loading %d STXTs", stxt.size());
+ debugC(3, kDebugLoading, "****** Loading %d STXTs", stxt.size());
for (Common::Array<uint16>::iterator iterator = stxt.begin(); iterator != stxt.end(); ++iterator) {
debugC(3, kDebugLoading, "Shared STXT %d", *iterator);
@@ -263,7 +305,7 @@ void DirectorEngine::loadSharedCastsFrom(Common::String filename) {
Common::Array<uint16> bmp = shardcst->getResourceIDList(MKTAG('B','I','T','D'));
if (bmp.size() != 0) {
- debugC(3, kDebugLoading, "Loading %d BITDs", bmp.size());
+ debugC(3, kDebugLoading, "****** Loading %d BITDs", bmp.size());
for (Common::Array<uint16>::iterator iterator = bmp.begin(); iterator != bmp.end(); ++iterator) {
debugC(3, kDebugLoading, "Shared BITD %d (%s)", *iterator, numToCastNum(*iterator - 1024));
_sharedBMP->setVal(*iterator, shardcst->getResource(MKTAG('B','I','T','D'), *iterator));
@@ -272,7 +314,7 @@ void DirectorEngine::loadSharedCastsFrom(Common::String filename) {
Common::Array<uint16> sound = shardcst->getResourceIDList(MKTAG('S','N','D',' '));
if (sound.size() != 0) {
- debugC(3, kDebugLoading, "Loading %d SNDs", sound.size());
+ debugC(3, kDebugLoading, "****** Loading %d SNDs", sound.size());
for (Common::Array<uint16>::iterator iterator = sound.begin(); iterator != sound.end(); ++iterator) {
debugC(3, kDebugLoading, "Shared SND %d", *iterator);
_sharedSound->setVal(*iterator, shardcst->getResource(MKTAG('S','N','D',' '), *iterator));
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 97152f818c..4b65044baa 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -120,6 +120,7 @@ void Score::loadArchive() {
} else {
Common::SeekableSubReadStreamEndian *pal = _movieArchive->getResource(MKTAG('C', 'L', 'U', 'T'), clutList[0]);
+ debugC(2, kDebugLoading, "****** Loading Palette");
loadPalette(*pal);
g_system->getPaletteManager()->setPalette(_vm->getPalette(), 0, _vm->getPaletteColorCount());
}
@@ -155,12 +156,16 @@ void Score::loadArchive() {
Common::Array<uint16> vwci = _movieArchive->getResourceIDList(MKTAG('V', 'W', 'C', 'I'));
if (vwci.size() > 0) {
+ debugC(2, kDebugLoading, "****** Loading %d CastInfos", vwci.size());
+
for (Common::Array<uint16>::iterator iterator = vwci.begin(); iterator != vwci.end(); ++iterator)
loadCastInfo(*_movieArchive->getResource(MKTAG('V', 'W', 'C', 'I'), *iterator), *iterator);
}
Common::Array<uint16> cast = _movieArchive->getResourceIDList(MKTAG('C', 'A', 'S', 't'));
if (cast.size() > 0) {
+ debugC(2, kDebugLoading, "****** Loading %d CASt resources", cast.size());
+
for (Common::Array<uint16>::iterator iterator = cast.begin(); iterator != cast.end(); ++iterator) {
Common::SeekableSubReadStreamEndian *stream = _movieArchive->getResource(MKTAG('C', 'A', 'S', 't'), *iterator);
Resource res = _movieArchive->getResourceDetail(MKTAG('C', 'A', 'S', 't'), *iterator);
@@ -175,6 +180,8 @@ void Score::loadArchive() {
if (_vm->getVersion() <= 3) {
Common::Array<uint16> stxt = _movieArchive->getResourceIDList(MKTAG('S','T','X','T'));
if (stxt.size() > 0) {
+ debugC(2, kDebugLoading, "****** Loading %d STXT resources", stxt.size());
+
for (Common::Array<uint16>::iterator iterator = stxt.begin(); iterator != stxt.end(); ++iterator) {
loadScriptText(*_movieArchive->getResource(MKTAG('S','T','X','T'), *iterator));
}
@@ -183,6 +190,8 @@ void Score::loadArchive() {
}
void Score::loadSpriteImages(bool isSharedCast) {
+ debugC(1, kDebugLoading, "****** Preloading sprite images");
+
Common::HashMap<int, BitmapCast *>::iterator bc;
for (bc = _loadedBitmaps->begin(); bc != _loadedBitmaps->end(); ++bc) {
if (bc->_value) {
@@ -277,6 +286,8 @@ void Score::loadPalette(Common::SeekableSubReadStreamEndian &stream) {
}
void Score::loadFrames(Common::SeekableSubReadStreamEndian &stream) {
+ debugC(1, kDebugLoading, "****** Loading frames");
+
uint32 size = stream.readUint32();
size -= 4;
@@ -306,7 +317,7 @@ void Score::loadFrames(Common::SeekableSubReadStreamEndian &stream) {
byte channelData[kChannelDataSize];
memset(channelData, 0, kChannelDataSize);
- while (size != 0) {
+ while (size != 0 && !stream.eos()) {
uint16 frameSize = stream.readUint16();
debugC(kDebugLoading, 8, "++++ score frame %d (frameSize %d) size %d", _frames.size(), frameSize, size);
size -= frameSize;
@@ -334,7 +345,7 @@ void Score::loadFrames(Common::SeekableSubReadStreamEndian &stream) {
//Common::hexdump(channelData, ARRAYSIZE(channelData));
frame->readChannels(str);
- debugC(3, kDebugLoading, "Frame %d actionId: %d", _frames.size() + 1, frame->_actionId);
+ debugC(3, kDebugLoading, "Frame %d actionId: %d", _frames.size(), frame->_actionId);
delete str;
@@ -343,6 +354,8 @@ void Score::loadFrames(Common::SeekableSubReadStreamEndian &stream) {
}
void Score::loadConfig(Common::SeekableSubReadStreamEndian &stream) {
+ debugC(1, kDebugLoading, "****** Loading Config");
+
/*uint16 unk1 = */ stream.readUint16();
/*ver1 = */ stream.readUint16();
_movieRect = Score::readRect(stream);
@@ -362,7 +375,7 @@ void Score::readVersion(uint32 rid) {
}
void Score::loadCastDataVWCR(Common::SeekableSubReadStreamEndian &stream) {
- debugC(1, kDebugLoading, "Score::loadCastDataVWCR(). start: %d, end: %d", _castArrayStart, _castArrayEnd);
+ debugC(1, kDebugLoading, "****** Score::loadCastDataVWCR(). start: %d, end: %d", _castArrayStart, _castArrayEnd);
for (uint16 id = _castArrayStart; id <= _castArrayEnd; id++) {
byte size = stream.readByte();
@@ -376,18 +389,22 @@ void Score::loadCastDataVWCR(Common::SeekableSubReadStreamEndian &stream) {
switch (castType) {
case kCastBitmap:
+ debugC(3, kDebugLoading, "CastTypes id: %d BitmapCast", id);
_loadedBitmaps->setVal(id, new BitmapCast(stream));
_castTypes[id] = kCastBitmap;
break;
case kCastText:
+ debugC(3, kDebugLoading, "CastTypes id: %d TextCast", id);
_loadedText->setVal(id, new TextCast(stream));
_castTypes[id] = kCastText;
break;
case kCastShape:
+ debugC(3, kDebugLoading, "CastTypes id: %d ShapeCast", id);
_loadedShapes->setVal(id, new ShapeCast(stream));
_castTypes[id] = kCastShape;
break;
case kCastButton:
+ debugC(3, kDebugLoading, "CastTypes id: %d ButtonCast", id);
_loadedButtons->setVal(id, new ButtonCast(stream));
_castTypes[id] = kCastButton;
break;
@@ -612,15 +629,15 @@ void Score::setCastMemberModified(int castId) {
void Score::loadLabels(Common::SeekableSubReadStreamEndian &stream) {
_labels = new Common::SortedArray<Label *>(compareLabels);
uint16 count = stream.readUint16() + 1;
- uint16 offset = count * 4 + 2;
+ uint32 offset = count * 4 + 2;
uint16 frame = stream.readUint16();
- uint16 stringPos = stream.readUint16() + offset;
+ uint32 stringPos = stream.readUint16() + offset;
for (uint16 i = 0; i < count; i++) {
uint16 nextFrame = stream.readUint16();
- uint16 nextStringPos = stream.readUint16() + offset;
- uint16 streamPos = stream.pos();
+ uint32 nextStringPos = stream.readUint16() + offset;
+ uint32 streamPos = stream.pos();
stream.seek(stringPos);
Common::String label;
@@ -638,6 +655,7 @@ void Score::loadLabels(Common::SeekableSubReadStreamEndian &stream) {
Common::SortedArray<Label *>::iterator j;
+ debugC(2, kDebugLoading, "****** Loading labels");
for (j = _labels->begin(); j != _labels->end(); ++j) {
debugC(2, kDebugLoading, "Frame %d, Label %s", (*j)->number, (*j)->name.c_str());
}
@@ -648,19 +666,21 @@ int Score::compareLabels(const void *a, const void *b) {
}
void Score::loadActions(Common::SeekableSubReadStreamEndian &stream) {
+ debugC(2, kDebugLoading, "****** Loading Actions");
+
uint16 count = stream.readUint16() + 1;
- uint16 offset = count * 4 + 2;
+ uint32 offset = count * 4 + 2;
byte id = stream.readByte();
byte subId = stream.readByte(); // I couldn't find how it used in continuity (except print). Frame actionId = 1 byte.
- uint16 stringPos = stream.readUint16() + offset;
+ uint32 stringPos = stream.readUint16() + offset;
for (uint16 i = 0; i < count; i++) {
uint16 nextId = stream.readByte();
byte nextSubId = stream.readByte();
- uint16 nextStringPos = stream.readUint16() + offset;
- uint16 streamPos = stream.pos();
+ uint32 nextStringPos = stream.readUint16() + offset;
+ uint32 streamPos = stream.pos();
stream.seek(stringPos);
@@ -672,7 +692,7 @@ void Score::loadActions(Common::SeekableSubReadStreamEndian &stream) {
_actions[i + 1] += ch;
}
- debugC(3, kDebugLoading, "id: %d nextId: %d subId: %d, code: %s", id, nextId, subId, _actions[id].c_str());
+ debugC(3, kDebugLoading, "Action id: %d nextId: %d subId: %d, code: %s", id, nextId, subId, _actions[id].c_str());
stream.seek(streamPos);
@@ -935,6 +955,8 @@ Common::String Score::getString(Common::String str) {
}
void Score::loadFileInfo(Common::SeekableSubReadStreamEndian &stream) {
+ debugC(2, kDebugLoading, "****** Loading FileInfo");
+
Common::Array<Common::String> fileInfoStrings = loadStrings(stream, _flags);
_script = fileInfoStrings[0];
@@ -964,6 +986,8 @@ Common::Array<Common::String> Score::loadStrings(Common::SeekableSubReadStreamEn
uint16 count = stream.readUint16() + 1;
+ debugC(3, kDebugLoading, "Strings: %d entries", count);
+
uint32 *entries = (uint32 *)calloc(count, sizeof(uint32));
for (uint i = 0; i < count; i++)
@@ -982,6 +1006,8 @@ Common::Array<Common::String> Score::loadStrings(Common::SeekableSubReadStreamEn
entryString += data[j];
strings.push_back(entryString);
+
+ debugC(6, kDebugLoading, "String %d:\n%s\n", i, entryString.c_str());
}
free(data);
@@ -994,9 +1020,11 @@ void Score::loadFontMap(Common::SeekableSubReadStreamEndian &stream) {
if (stream.size() == 0)
return;
+ debugC(2, kDebugLoading, "****** Loading FontMap");
+
uint16 count = stream.readUint16();
uint32 offset = (count * 2) + 2;
- uint16 currentRawPosition = offset;
+ uint32 currentRawPosition = offset;
for (uint16 i = 0; i < count; i++) {
uint16 id = stream.readUint16();
@@ -1014,7 +1042,7 @@ void Score::loadFontMap(Common::SeekableSubReadStreamEndian &stream) {
_fontMap[id] = font;
_vm->_wm->_fontMan->registerFontMapping(id, font);
- debug(3, "Fontmap. ID %d Font %s", id, font.c_str());
+ debugC(3, kDebugLoading, "Fontmap. ID %d Font %s", id, font.c_str());
currentRawPosition = stream.pos();
stream.seek(positionInfo);
}
@@ -1050,7 +1078,9 @@ void Score::startLoop() {
while (!_stopPlay && _currentFrame < _frames.size()) {
debugC(1, kDebugImages, "****************************** Current frame: %d", _currentFrame + 1);
update();
- _vm->processEvents();
+
+ if (_currentFrame < _frames.size())
+ _vm->processEvents();
}
}
@@ -1065,7 +1095,7 @@ void Score::update() {
// Enter and exit from previous frame (Director 4)
_lingo->processEvent(kEventEnterFrame, kFrameScript, _frames[_currentFrame]->_actionId);
- _lingo->processEvent(kEventExitFrame, kFrameScript, _frames[_currentFrame]->_actionId);
+ _lingo->processEvent(kEventNone, kFrameScript, _frames[_currentFrame]->_actionId);
// TODO Director 6 - another order
// TODO Director 6 step: send beginSprite event to any sprites whose span begin in the upcoming frame
@@ -1133,11 +1163,13 @@ void Score::update() {
}
}
+ _lingo->processEvent(kEventExitFrame, kFrameScript, _frames[_currentFrame]->_actionId);
+
_nextFrameTime = g_system->getMillis() + (float)_currentFrameRate / 60 * 1000;
}
Sprite *Score::getSpriteById(uint16 id) {
- if (_currentFrame >= _frames.size() || _currentFrame < 0 || id >= _frames[_currentFrame]->_sprites.size()) {
+ if (_currentFrame >= _frames.size() || id >= _frames[_currentFrame]->_sprites.size()) {
warning("Score::getSpriteById(%d): out of bounds. frame: %d", id, _currentFrame);
return nullptr;
}
diff --git a/engines/director/util.cpp b/engines/director/util.cpp
index ccde2b3127..dbd1cd351f 100644
--- a/engines/director/util.cpp
+++ b/engines/director/util.cpp
@@ -48,7 +48,7 @@ char *numToCastNum(int num) {
res[3] = '\0';
num--;
- if (num > 0 && num <= 512) {
+ if (num >= 0 && num < 512) {
int c = num / 64;
res[0] = 'A' + c;
num -= 64 * c;
diff --git a/engines/gnap/fontdata.h b/engines/gnap/fontdata.h
index 0631d1d214..10f7b15ba5 100644
--- a/engines/gnap/fontdata.h
+++ b/engines/gnap/fontdata.h
@@ -747,105 +747,51 @@ const byte _dejaVuSans9ptCharBitmaps[] = {
};
/* Character descriptors for DejaVu Sans 9pt */
-/* { [Char width in bits], [Offset into dejaVuSans9ptCharBitmaps in bytes] } */
-const FONT_CHAR_INFO _dejaVuSans9ptCharDescriptors[] = {
- FONT_CHAR_INFO(5, 0), /* */
- FONT_CHAR_INFO(1, 10), /* ! */
- FONT_CHAR_INFO(3, 12), /* " */
- FONT_CHAR_INFO(8, 18), /* # */
- FONT_CHAR_INFO(5, 34), /* $ */
- FONT_CHAR_INFO(10, 44), /* % */
- FONT_CHAR_INFO(8, 64), /* & */
- FONT_CHAR_INFO(1, 80), /* ' */
- FONT_CHAR_INFO(3, 82), /* ( */
- FONT_CHAR_INFO(3, 88), /* ) */
- FONT_CHAR_INFO(5, 94), /* * */
- FONT_CHAR_INFO(7, 104), /* + */
- FONT_CHAR_INFO(1, 118), /* , */
- FONT_CHAR_INFO(3, 120), /* - */
- FONT_CHAR_INFO(1, 126), /* . */
- FONT_CHAR_INFO(4, 128), /* / */
- FONT_CHAR_INFO(6, 136), /* 0 */
- FONT_CHAR_INFO(5, 148), /* 1 */
- FONT_CHAR_INFO(6, 158), /* 2 */
- FONT_CHAR_INFO(6, 170), /* 3 */
- FONT_CHAR_INFO(6, 182), /* 4 */
- FONT_CHAR_INFO(6, 194), /* 5 */
- FONT_CHAR_INFO(6, 206), /* 6 */
- FONT_CHAR_INFO(6, 218), /* 7 */
- FONT_CHAR_INFO(6, 230), /* 8 */
- FONT_CHAR_INFO(6, 242), /* 9 */
- FONT_CHAR_INFO(1, 254), /* : */
- FONT_CHAR_INFO(1, 256), /* ; */
- FONT_CHAR_INFO(8, 258), /* < */
- FONT_CHAR_INFO(8, 274), /* = */
- FONT_CHAR_INFO(8, 290), /* > */
- FONT_CHAR_INFO(5, 306), /* ? */
- FONT_CHAR_INFO(11, 316), /* @ */
- FONT_CHAR_INFO(8, 338), /* A */
- FONT_CHAR_INFO(6, 354), /* B */
- FONT_CHAR_INFO(6, 366), /* C */
- FONT_CHAR_INFO(7, 378), /* D */
- FONT_CHAR_INFO(6, 392), /* E */
- FONT_CHAR_INFO(5, 404), /* F */
- FONT_CHAR_INFO(7, 414), /* G */
- FONT_CHAR_INFO(7, 428), /* H */
- FONT_CHAR_INFO(1, 442), /* I */
- FONT_CHAR_INFO(3, 444), /* J */
- FONT_CHAR_INFO(6, 450), /* K */
- FONT_CHAR_INFO(5, 462), /* L */
- FONT_CHAR_INFO(8, 472), /* M */
- FONT_CHAR_INFO(7, 488), /* N */
- FONT_CHAR_INFO(7, 502), /* O */
- FONT_CHAR_INFO(6, 516), /* P */
- FONT_CHAR_INFO(7, 528), /* Q */
- FONT_CHAR_INFO(7, 542), /* R */
- FONT_CHAR_INFO(6, 556), /* S */
- FONT_CHAR_INFO(7, 568), /* T */
- FONT_CHAR_INFO(7, 582), /* U */
- FONT_CHAR_INFO(8, 596), /* V */
- FONT_CHAR_INFO(11, 612), /* W */
- FONT_CHAR_INFO(7, 634), /* X */
- FONT_CHAR_INFO(7, 648), /* Y */
- FONT_CHAR_INFO(7, 662), /* Z */
- FONT_CHAR_INFO(2, 676), /* [ */
- FONT_CHAR_INFO(4, 680), /* \ */
- FONT_CHAR_INFO(2, 688), /* ] */
- FONT_CHAR_INFO(6, 692), /* ^ */
- FONT_CHAR_INFO(6, 704), /* _ */
- FONT_CHAR_INFO(2, 716), /* ` */
- FONT_CHAR_INFO(6, 720), /* a */
- FONT_CHAR_INFO(6, 732), /* b */
- FONT_CHAR_INFO(5, 744), /* c */
- FONT_CHAR_INFO(6, 754), /* d */
- FONT_CHAR_INFO(6, 766), /* e */
- FONT_CHAR_INFO(4, 778), /* f */
- FONT_CHAR_INFO(6, 786), /* g */
- FONT_CHAR_INFO(6, 798), /* h */
- FONT_CHAR_INFO(1, 810), /* i */
- FONT_CHAR_INFO(2, 812), /* j */
- FONT_CHAR_INFO(5, 816), /* k */
- FONT_CHAR_INFO(1, 826), /* l */
- FONT_CHAR_INFO(9, 828), /* m */
- FONT_CHAR_INFO(6, 846), /* n */
- FONT_CHAR_INFO(6, 858), /* o */
- FONT_CHAR_INFO(6, 870), /* p */
- FONT_CHAR_INFO(6, 882), /* q */
- FONT_CHAR_INFO(4, 894), /* r */
- FONT_CHAR_INFO(5, 902), /* s */
- FONT_CHAR_INFO(4, 912), /* t */
- FONT_CHAR_INFO(6, 920), /* u */
- FONT_CHAR_INFO(6, 932), /* v */
- FONT_CHAR_INFO(9, 944), /* w */
- FONT_CHAR_INFO(6, 962), /* x */
- FONT_CHAR_INFO(6, 974), /* y */
- FONT_CHAR_INFO(5, 986), /* z */
- FONT_CHAR_INFO(5, 996), /* { */
- FONT_CHAR_INFO(1, 1006), /* | */
- FONT_CHAR_INFO(5, 1008), /* ) */
- FONT_CHAR_INFO(8, 1018) /* ~ */
+const byte _dejaVuSans9ptWidth[] = {
+ 5, /* */ 1, /* ! */ 3, /* " */ 8, /* # */ 5, /* $ */
+ 10,/* % */ 8, /* & */ 1, /* ' */ 3, /* ( */ 3, /* ) */
+ 5, /* * */ 7, /* + */ 1, /* , */ 3, /* - */ 1, /* . */
+ 4, /* / */ 6, /* 0 */ 5, /* 1 */ 6, /* 2 */ 6, /* 3 */
+ 6, /* 4 */ 6, /* 5 */ 6, /* 6 */ 6, /* 7 */ 6, /* 8 */
+ 6, /* 9 */ 1, /* : */ 1, /* ; */ 8, /* < */ 8, /* = */
+ 8, /* > */ 5, /* ? */ 11,/* @ */ 8, /* A */ 6, /* B */
+ 6, /* C */ 7, /* D */ 6, /* E */ 5, /* F */ 7, /* G */
+ 7, /* H */ 1, /* I */ 3, /* J */ 6, /* K */ 5, /* L */
+ 8, /* M */ 7, /* N */ 7, /* O */ 6, /* P */ 7, /* Q */
+ 7, /* R */ 6, /* S */ 7, /* T */ 7, /* U */ 8, /* V */
+ 11,/* W */ 7, /* X */ 7, /* Y */ 7, /* Z */ 2, /* [ */
+ 4, /* \ */ 2, /* ] */ 6, /* ^ */ 6, /* _ */ 2, /* ` */
+ 6, /* a */ 6, /* b */ 5, /* c */ 6, /* d */ 6, /* e */
+ 4, /* f */ 6, /* g */ 6, /* h */ 1, /* i */ 2, /* j */
+ 5, /* k */ 1, /* l */ 9, /* m */ 6, /* n */ 6, /* o */
+ 6, /* p */ 6, /* q */ 4, /* r */ 5, /* s */ 4, /* t */
+ 6, /* u */ 6, /* v */ 9, /* w */ 6, /* x */ 6, /* y */
+ 5, /* z */ 5, /* { */ 1, /* | */ 5, /* ) */ 8 /* ~ */
+};
+
+const uint16 _dejaVuSans9ptOffsets[] = {
+ 0, /* */ 10, /* ! */ 12, /* " */ 18, /* # */ 34, /* $ */
+ 44, /* % */ 64, /* & */ 80, /* ' */ 82, /* ( */ 88, /* */
+ 94, /* * */ 104, /* + */ 118, /* , */ 120, /* - */ 126, /* . */
+ 128, /* / */ 136, /* 0 */ 148, /* 1 */ 158, /* 2 */ 170, /* 3 */
+ 182, /* 4 */ 194, /* 5 */ 206, /* 6 */ 218, /* 7 */ 230, /* 8 */
+ 242, /* 9 */ 254, /* : */ 256, /* ; */ 258, /* < */ 274, /* = */
+ 290, /* > */ 306, /* ? */ 316, /* @ */ 338, /* A */ 354, /* B */
+ 366, /* C */ 378, /* D */ 392, /* E */ 404, /* F */ 414, /* G */
+ 428, /* H */ 442, /* I */ 444, /* J */ 450, /* K */ 462, /* L */
+ 472, /* M */ 488, /* N */ 502, /* O */ 516, /* P */ 528, /* Q */
+ 542, /* R */ 556, /* S */ 568, /* T */ 582, /* U */ 596, /* V */
+ 612, /* W */ 634, /* X */ 648, /* Y */ 662, /* Z */ 676, /* [ */
+ 680, /* \ */ 688, /* ] */ 692, /* ^ */ 704, /* _ */ 716, /* ` */
+ 720, /* a */ 732, /* b */ 744, /* c */ 754, /* d */ 766, /* e */
+ 778, /* f */ 786, /* g */ 798, /* h */ 810, /* i */ 812, /* j */
+ 816, /* k */ 826, /* l */ 828, /* m */ 846, /* n */ 858, /* o */
+ 870, /* p */ 882, /* q */ 894, /* r */ 902, /* s */ 912, /* t */
+ 920, /* u */ 932, /* v */ 944, /* w */ 962, /* x */ 974, /* y */
+ 986, /* z */ 996, /* { */ 1006, /* | */ 1008, /* */ 1018 /* ~ */
};
} // End of namespace Gnap
#endif // GNAP_RESOURCE_H
+
diff --git a/engines/gnap/gamesys.cpp b/engines/gnap/gamesys.cpp
index 08a4af39ee..04247c5d46 100644
--- a/engines/gnap/gamesys.cpp
+++ b/engines/gnap/gamesys.cpp
@@ -294,8 +294,8 @@ void GameSys::drawTextToSurface(Graphics::Surface *surface, int x, int y, byte r
if (c < 32 || c >= 127)
c = (byte)'_';
c -= 32;
- int w = _dejaVuSans9ptCharDescriptors[c]._width;
- const byte *data = _dejaVuSans9ptCharBitmaps + _dejaVuSans9ptCharDescriptors[c]._offset;
+ int w = _dejaVuSans9ptWidth[c];
+ const byte *data = _dejaVuSans9ptCharBitmaps + _dejaVuSans9ptOffsets[c];
for (int xc = 0; xc < w; ++xc) {
for (int yc = 15; yc >= 0; --yc) {
byte *dst = (byte *)surface->getBasePtr(x + xc, y + yc);
@@ -319,7 +319,7 @@ int GameSys::getTextHeight(const char *text) {
if (c < 32 || c >= 127)
c = (byte)'_';
c -= 32;
- height = MAX(height, _dejaVuSans9ptCharDescriptors[c]._width);
+ height = MAX(height, _dejaVuSans9ptWidth[c]);
}
return height;
}
@@ -331,7 +331,7 @@ int GameSys::getTextWidth(const char *text) {
if (c < 32 || c >= 127)
c = (byte)'_';
c -= 32;
- width += _dejaVuSans9ptCharDescriptors[c]._width + 1;
+ width += _dejaVuSans9ptWidth[c] + 1;
}
return width;
}
@@ -555,6 +555,7 @@ void GameSys::seqRemoveGfx(int sequenceId, int id) {
bool GameSys::updateSequenceDuration(int sequenceId, int id, int *outDuration) {
bool found = false;
int duration = 0x7FFFFFFF;
+ *outDuration = 0;
for (int i = 0; i < _gfxItemsCount; ++i) {
GfxItem *gfxItem = &_gfxItems[i];
if (gfxItem->_sequenceId == sequenceId && gfxItem->_id == id) {
@@ -577,8 +578,10 @@ bool GameSys::updateSequenceDuration(int sequenceId, int id, int *outDuration) {
}
}
}
+
if (found)
*outDuration = duration;
+
return found;
}
diff --git a/engines/mohawk/detection_tables.h b/engines/mohawk/detection_tables.h
index 9cc52a78b3..7da3c14633 100644
--- a/engines/mohawk/detection_tables.h
+++ b/engines/mohawk/detection_tables.h
@@ -48,6 +48,24 @@ static const MohawkGameDescription gameDescriptions[] = {
0,
},
+ // Myst
+ // English Windows 3.11, v1.0
+ // From vonLeheCreative, #9645
+ {
+ {
+ "myst",
+ "",
+ AD_ENTRY1("MYST.DAT", "0e4b6fcbd2419d4371365314fb7443f8"),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ GUI_OPTIONS_MYST
+ },
+ GType_MYST,
+ 0,
+ 0,
+ },
+
// Myst Demo
// English Windows 3.11
// From CD-ROM Today July, 1994
diff --git a/engines/mohawk/myst_scripts.cpp b/engines/mohawk/myst_scripts.cpp
index 596180ddb2..267d644b65 100644
--- a/engines/mohawk/myst_scripts.cpp
+++ b/engines/mohawk/myst_scripts.cpp
@@ -355,7 +355,26 @@ void MystScriptParser::o_changeCardSwitchRtL(uint16 op, uint16 var, uint16 argc,
}
void MystScriptParser::o_takePage(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- uint16 cursorId = argv[0];
+ // In most game releases, the first opcode argument is the new mouse cursor.
+ // However, in the original v1.0 English release this opcode takes no argument.
+ uint16 cursorId; // = argv[0];
+ switch (var) {
+ case 41: // Vault white page
+ cursorId = kWhitePageCursor;
+ break;
+ case 25: // Fireplace red page
+ case 102: // Red page
+ cursorId = kRedPageCursor;
+ break;
+ case 24: // Fireplace blue page
+ case 103: // Blue page
+ cursorId = kBluePageCursor;
+ break;
+ default:
+ warning("Unexpected take page variable '%d'", var);
+ cursorId = kDefaultMystCursor;
+ }
+
uint16 oldPage = _globals.heldPage;
debugC(kDebugScript, "Opcode %d: takePage Var %d CursorId %d", op, var, cursorId);
diff --git a/engines/mohawk/myst_stacks/channelwood.cpp b/engines/mohawk/myst_stacks/channelwood.cpp
index 21c3042359..f006a8e3ea 100644
--- a/engines/mohawk/myst_stacks/channelwood.cpp
+++ b/engines/mohawk/myst_stacks/channelwood.cpp
@@ -368,6 +368,7 @@ void Channelwood::o_waterTankValveOpen(uint16 op, uint16 var, uint16 argc, uint1
for (uint i = 0; i < 2; i++)
for (uint16 imageId = 3601; imageId >= 3595; imageId--) {
_vm->_gfx->copyImageToScreen(imageId, rect);
+ _vm->pollAndDiscardEvents();
_vm->_system->updateScreen();
}
@@ -699,6 +700,7 @@ void Channelwood::o_waterTankValveClose(uint16 op, uint16 var, uint16 argc, uint
for (uint i = 0; i < 2; i++)
for (uint16 imageId = 3595; imageId <= 3601; imageId++) {
_vm->_gfx->copyImageToScreen(imageId, rect);
+ _vm->pollAndDiscardEvents();
_vm->_system->updateScreen();
}
diff --git a/engines/mohawk/myst_stacks/myst.cpp b/engines/mohawk/myst_stacks/myst.cpp
index f9ba6a42fa..424dd2f07c 100644
--- a/engines/mohawk/myst_stacks/myst.cpp
+++ b/engines/mohawk/myst_stacks/myst.cpp
@@ -864,6 +864,7 @@ void Myst::o_fireplaceToggleButton(uint16 op, uint16 var, uint16 argc, uint16 *a
// Unset button
for (uint i = 4795; i >= 4779; i--) {
_vm->_gfx->copyImageToScreen(i, getInvokingResource<MystArea>()->getRect());
+ _vm->pollAndDiscardEvents();
_vm->_system->updateScreen();
}
_fireplaceLines[var - 17] &= ~bitmask;
@@ -871,6 +872,7 @@ void Myst::o_fireplaceToggleButton(uint16 op, uint16 var, uint16 argc, uint16 *a
// Set button
for (uint i = 4779; i <= 4795; i++) {
_vm->_gfx->copyImageToScreen(i, getInvokingResource<MystArea>()->getRect());
+ _vm->pollAndDiscardEvents();
_vm->_system->updateScreen();
}
_fireplaceLines[var - 17] |= bitmask;
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index c542be7ef2..cf3a981347 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -103,6 +103,7 @@ static const char *const selectorNameTable[] = {
"modNum", // King's Quest 6 CD / Laura Bow 2 CD for audio+text support
"cycler", // Space Quest 4 / system selector
"setLoop", // Laura Bow 1 Colonel's Bequest
+ "ignoreActors", // Laura Bow 1 Colonel's Bequest
#ifdef ENABLE_SCI32
"newWith", // SCI2 array script
"scrollSelections", // GK2
@@ -135,7 +136,8 @@ enum ScriptPatcherSelectors {
SELECTOR_startAudio,
SELECTOR_modNum,
SELECTOR_cycler,
- SELECTOR_setLoop
+ SELECTOR_setLoop,
+ SELECTOR_ignoreActors
#ifdef ENABLE_SCI32
,
SELECTOR_newWith,
@@ -554,14 +556,12 @@ static const uint16 freddypharkasSignatureIntroScaling[] = {
static const uint16 freddypharkasPatchIntroScaling[] = {
// remove setLoop(), objects in heap are already prepared, saves 5 bytes
0x38,
- PATCH_GETORIGINALBYTE(+6),
- PATCH_GETORIGINALBYTE(+7), // pushi (setStep)
+ PATCH_GETORIGINALUINT16(+6), // pushi (setStep)
0x7a, // push2
0x39, 0x05, // pushi 05
0x3c, // dup
0x72,
- PATCH_GETORIGINALBYTE(+13),
- PATCH_GETORIGINALBYTE(+14), // lofsa (view)
+ PATCH_GETORIGINALUINT16(+13), // lofsa (view)
0x4a, 0x18, // send 18 - adjusted
0x35, 0x0a, // ldi 0a
0xa3, 0x02, // sal local[2]
@@ -1314,8 +1314,7 @@ static const uint16 kq6PatchInventoryStackFix[] = {
0x12, // and
0x65, 0x30, // aTop state
0x38, // pushi "show"
- PATCH_GETORIGINALBYTE(+22),
- PATCH_GETORIGINALBYTE(+23),
+ PATCH_GETORIGINALUINT16(+22),
0x78, // push1
0x87, 0x00, // lap param[0]
0x31, 0x04, // bnt [call show using global 0]
@@ -1600,8 +1599,7 @@ static const uint16 kq6CDPatchAudioTextSupport3[] = {
0x65, 0x12, // aTop dialog
// followed by original addText-calling code
0x38,
- PATCH_GETORIGINALBYTE(+95),
- PATCH_GETORIGINALBYTE(+96), // pushi addText
+ PATCH_GETORIGINALUINT16(+95), // pushi (addText)
0x78, // push1
0x8f, 0x02, // lsp param[2]
0x59, 0x03, // &rest 03
@@ -1949,8 +1947,7 @@ static const uint16 kq7PatchSubtitleFix3[] = {
PATCH_ADDTOOFFSET(+2), // skip over "pToa initialized code"
0x2f, 0x0c, // bt [skip init code] - saved 1 byte
0x38,
- PATCH_GETORIGINALBYTE(+6),
- PATCH_GETORIGINALBYTE(+7), // pushi (init)
+ PATCH_GETORIGINALUINT16(+6), // pushi (init)
0x76, // push0
0x54, PATCH_UINT16(0x0004), // self 04
// additionally set background color here (5 bytes)
@@ -2488,12 +2485,79 @@ static const uint16 laurabow1PatchArmorOilingArmFix[] = {
PATCH_END
};
+// When you tell Lilly about Gertie in room 35, Lilly will then walk to the left and off the screen.
+// In case Laura (ego) is in the way, the whole game will basically block and you won't be able
+// to do anything except saving + restoring the game.
+//
+// If this happened already, the player can enter
+// "send Lillian ignoreActors 1" inside the debugger to fix this situation.
+//
+// This issue is very difficult to solve, because Lilly also walks diagonally after walking to the left right
+// under the kitchen table. This means that even if we added a few more rectangle checks, there could still be
+// spots, where the game would block.
+//
+// Also the mover "PathOut" is used for Lillian instead of the regular "MoveTo", which would avoid other
+// actors by itself.
+//
+// So instead we set Lilly to ignore other actors during that cutscene, which is the least invasive solution.
+//
+// Applies to at least: English PC Floppy, English Amiga Floppy, English Atari ST Floppy
+// Responsible method: goSee::changeState(1) in script 236
+// Fixes bug: (happened during GOG Let's Play)
+static const uint16 laurabow1SignatureTellLillyAboutGerieBlockingFix1[] = {
+ 0x7a, // puah2
+ SIG_MAGICDWORD,
+ 0x38, SIG_UINT16(0x00c1), // pushi 00C1h
+ 0x38, SIG_UINT16(0x008f), // pushi 008Fh
+ 0x38, SIG_SELECTOR16(ignoreActors), // pushi (ignoreActors)
+ 0x78, // push1
+ 0x76, // push0
+ SIG_END
+};
+
+static const uint16 laurabow1PatchTellLillyAboutGertieBlockingFix1[] = {
+ PATCH_ADDTOOFFSET(+11), // skip over until push0
+ 0x78, // push1 (change push0 to push1)
+ PATCH_END
+};
+
+// a second patch to call Lillian::ignoreActors(1) on goSee::changeState(9) in script 236
+static const uint16 laurabow1SignatureTellLillyAboutGerieBlockingFix2[] = {
+ 0x3c, // dup
+ 0x35, 0x09, // ldi 09
+ 0x1a, // eq?
+ 0x30, SIG_UINT16(0x003f), // bnt [ret]
+ 0x39, SIG_ADDTOOFFSET(+1), // pushi (view)
+ 0x78, // push1
+ 0x38, SIG_UINT16(0x0203), // pushi 203h (515d)
+ 0x38, SIG_ADDTOOFFSET(+2), // pushi (posn)
+ 0x7a, // push2
+ 0x38, SIG_UINT16(0x00c9), // pushi C9h (201d)
+ SIG_MAGICDWORD,
+ 0x38, SIG_UINT16(0x0084), // pushi 84h (132d)
+ 0x72, SIG_ADDTOOFFSET(+2), // lofsa Lillian (different offsets for different platforms)
+ 0x4a, 0x0e, // send 0Eh
+ SIG_END
+};
+
+static const uint16 laurabow1PatchTellLillyAboutGertieBlockingFix2[] = {
+ 0x38, PATCH_SELECTOR16(ignoreActors), // pushi (ignoreActors)
+ 0x78, // push1
+ 0x76, // push0
+ 0x33, 0x00, // ldi 00 (waste 2 bytes)
+ PATCH_ADDTOOFFSET(+19), // skip over until send
+ 0x4a, 0x14, // send 14h
+ PATCH_END
+};
+
// script, description, signature patch
static const SciScriptPatcherEntry laurabow1Signatures[] = {
- { true, 4, "easter egg view fix", 1, laurabow1SignatureEasterEggViewFix, laurabow1PatchEasterEggViewFix },
- { true, 37, "armor open visor fix", 1, laurabow1SignatureArmorOpenVisorFix, laurabow1PatchArmorOpenVisorFix },
- { true, 37, "armor move to fix", 2, laurabow1SignatureArmorMoveToFix, laurabow1PatchArmorMoveToFix },
- { true, 37, "allowing input, after oiling arm", 1, laurabow1SignatureArmorOilingArmFix, laurabow1PatchArmorOilingArmFix },
+ { true, 4, "easter egg view fix", 1, laurabow1SignatureEasterEggViewFix, laurabow1PatchEasterEggViewFix },
+ { true, 37, "armor open visor fix", 1, laurabow1SignatureArmorOpenVisorFix, laurabow1PatchArmorOpenVisorFix },
+ { true, 37, "armor move to fix", 2, laurabow1SignatureArmorMoveToFix, laurabow1PatchArmorMoveToFix },
+ { true, 37, "allowing input, after oiling arm", 1, laurabow1SignatureArmorOilingArmFix, laurabow1PatchArmorOilingArmFix },
+ { true, 236, "tell Lilly about Gertie blocking fix 1/2", 1, laurabow1SignatureTellLillyAboutGerieBlockingFix1, laurabow1PatchTellLillyAboutGertieBlockingFix1 },
+ { true, 236, "tell Lilly about Gertie blocking fix 2/2", 1, laurabow1SignatureTellLillyAboutGerieBlockingFix2, laurabow1PatchTellLillyAboutGertieBlockingFix2 },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -2614,6 +2678,98 @@ static const uint16 laurabow2CDPatchFixProblematicIconBar[] = {
PATCH_END
};
+// When entering the main musem party room (w/ the golden Egyptian head),
+// Laura is waslking a bit into the room automatically.
+// In case you press a mouse button while this is happening, you will get
+// stuck inside that room and won't be able to exit it anymore.
+//
+// Users, who played the game w/ a previous version of ScummVM can simply
+// enter the debugger and then enter "send rm350 script 0:0", which will
+// fix the script state.
+//
+// This is caused by the user controls not being locked at that point.
+// Pressing a button will cause the cue from the PolyPath walker to never
+// happen, which then causes sEnterSouth to never dispose itself.
+//
+// User controls are locked in the previous room 335, but controls
+// are unlocked by frontDoor::cue.
+// We do not want to change this, because it could have side-effects.
+// We instead add another LB2::handsOff call inside the script responsible
+// for making Laura walk into the room (sEnterSouth::changeState(0).
+//
+// Applies to at least: English PC-CD, English PC-Floppy, German PC-Floppy
+// Responsible method: sEnterSouth::changeState
+// Fixes bug: (no bug report, from GOG forum post)
+static const uint16 laurabow2SignatureMuseumPartyFixEnteringSouth1[] = {
+ 0x3c, // dup
+ 0x35, 0x00, // ldi 00
+ 0x1a, // eq?
+ 0x30, SIG_UINT16(0x0097), // bnt [state 1 code]
+ SIG_ADDTOOFFSET(+141), // skip to end of follow-up code
+ 0x32, SIG_ADDTOOFFSET(+2), // jmp [ret] (0x008d for CD, 0x007d for floppy)
+ 0x35, 0x01, // ldi 01
+ 0x65, 0x1a, // aTop cycles
+ 0x32, SIG_ADDTOOFFSET(+2), // jmp [ret] (0x0086 for CD, 0x0076 for floppy)
+ // state 1 code
+ 0x3c, // dup
+ 0x35, 0x01, // ldi 01
+ 0x1a, // eq?
+ SIG_MAGICDWORD,
+ 0x31, 0x05, // bnt [state 2 code]
+ 0x35, 0x00, // ldi 00
+ 0x32, SIG_ADDTOOFFSET(+2), // jmp [ret] (0x007b for CD, 0x006b for floppy)
+ // state 2 code
+ 0x3c, // dup
+ SIG_END
+};
+
+static const uint16 laurabow2PatchMuseumPartyFixEnteringSouth1[] = {
+ 0x2e, PATCH_UINT16(0x00a6), // bt [state 2 code] (we skip state 1, because it's a NOP anyways)
+ // state 0 processing
+ 0x32, PATCH_UINT16(+151),
+ SIG_ADDTOOFFSET(+149), // skip to end of follow-up code
+ // save 1 byte by replacing jump to [ret] into straight toss/ret
+ 0x3a, // toss
+ 0x48, // ret
+
+ // additional code, that gets called right at the start of step 0 processing
+ 0x18, // not -- this here is where pushi handsOff will be inserted by the second patch
+ 0x18, // not offset and handsOff is different for floppy + CD, that's why we do this
+ 0x18, // not floppy also does not have a selector table, so we can't go by "handsOff" name
+ 0x18, // not
+ 0x76, // push0
+ 0x81, 0x01, // lag global[1]
+ 0x4a, 0x04, // send 04
+ 0x32, PATCH_UINT16(0xFF5e), // jmp [back to start of step 0 processing]
+ PATCH_END
+};
+
+// second patch, which only inserts pushi handsOff inside our new code
+// There is no other way to do this except making 2 full patches for floppy + CD, because handsOff/handsOn
+// is not the same value between floppy + CD *and* floppy doesn't even have a vocab, so we can't figure out the id
+// by ourselves.
+static const uint16 laurabow2SignatureMuseumPartyFixEnteringSouth2[] = {
+ 0x18, // our injected code
+ 0x18,
+ 0x18,
+ SIG_ADDTOOFFSET(+92), // skip to the handsOn code, that we are interested in
+ 0x38, SIG_ADDTOOFFSET(+2), // pushi handsOn (0x0189 for CD, 0x024b for floppy)
+ 0x76, // push0
+ 0x81, 0x01, // lag global[1]
+ 0x4a, 0x04, // send 04
+ 0x38, SIG_ADDTOOFFSET(+2), // pushi 0274h
+ SIG_MAGICDWORD,
+ 0x78, // push1
+ 0x38, SIG_UINT16(0x033f), // pushi 033f
+ SIG_END
+};
+
+static const uint16 laurabow2PatchMuseumPartyFixEnteringSouth2[] = {
+ 0x38, // pushi
+ PATCH_GETORIGINALUINT16ADJUST(+96, -1), // get handsOff code and ubstract 1 from it to get handsOn
+ PATCH_END
+};
+
// Opening/Closing the east door in the pterodactyl room doesn't
// check, if it's locked and will open/close the door internally
// even when it is.
@@ -2628,7 +2784,7 @@ static const uint16 laurabow2CDPatchFixProblematicIconBar[] = {
// Responsible method (CD): eastDoor::doVerb
// Responsible method (Floppy): eastDoor::<noname300>
// Fixes bug: #6458 (partly, see additional patch below)
-static const uint16 laurabow2CDSignatureFixWiredEastDoor[] = {
+static const uint16 laurabow2SignatureFixWiredEastDoor[] = {
0x30, SIG_UINT16(0x0022), // bnt [skip hand action]
0x67, SIG_ADDTOOFFSET(+1), // pTos CD: doorState, Floppy: state
0x35, 0x00, // ldi 00
@@ -2651,7 +2807,7 @@ static const uint16 laurabow2CDSignatureFixWiredEastDoor[] = {
SIG_END
};
-static const uint16 laurabow2CDPatchFixWiredEastDoor[] = {
+static const uint16 laurabow2PatchFixWiredEastDoor[] = {
0x31, 0x23, // bnt [skip hand action] (saves 1 byte)
0x81, 97, // lag 97d (get our eastDoor-wired-global)
0x31, 0x04, // bnt [skip setting locked property]
@@ -2780,20 +2936,22 @@ static const uint16 laurabow2CDPatchAudioTextMenuSupport2[] = {
// script, description, signature patch
static const SciScriptPatcherEntry laurabow2Signatures[] = {
- { true, 560, "CD: painting closing immediately", 1, laurabow2CDSignaturePaintingClosing, laurabow2CDPatchPaintingClosing },
- { true, 0, "CD: fix problematic icon bar", 1, laurabow2CDSignatureFixProblematicIconBar, laurabow2CDPatchFixProblematicIconBar },
- { true, 430, "CD/Floppy: make wired east door persistent", 1, laurabow2SignatureRememberWiredEastDoor, laurabow2PatchRememberWiredEastDoor },
- { true, 430, "CD/Floppy: fix wired east door", 1, laurabow2CDSignatureFixWiredEastDoor, laurabow2CDPatchFixWiredEastDoor },
+ { true, 560, "CD: painting closing immediately", 1, laurabow2CDSignaturePaintingClosing, laurabow2CDPatchPaintingClosing },
+ { true, 0, "CD: fix problematic icon bar", 1, laurabow2CDSignatureFixProblematicIconBar, laurabow2CDPatchFixProblematicIconBar },
+ { true, 350, "CD/Floppy: museum party fix entering south 1/2", 1, laurabow2SignatureMuseumPartyFixEnteringSouth1, laurabow2PatchMuseumPartyFixEnteringSouth1 },
+ { true, 350, "CD/Floppy: museum party fix entering south 2/2", 1, laurabow2SignatureMuseumPartyFixEnteringSouth2, laurabow2PatchMuseumPartyFixEnteringSouth2 },
+ { true, 430, "CD/Floppy: make wired east door persistent", 1, laurabow2SignatureRememberWiredEastDoor, laurabow2PatchRememberWiredEastDoor },
+ { true, 430, "CD/Floppy: fix wired east door", 1, laurabow2SignatureFixWiredEastDoor, laurabow2PatchFixWiredEastDoor },
// King's Quest 6 and Laura Bow 2 share basic patches for audio + text support
- { false, 924, "CD: audio + text support 1", 1, kq6laurabow2CDSignatureAudioTextSupport1, kq6laurabow2CDPatchAudioTextSupport1 },
- { false, 924, "CD: audio + text support 2", 1, kq6laurabow2CDSignatureAudioTextSupport2, kq6laurabow2CDPatchAudioTextSupport2 },
- { false, 924, "CD: audio + text support 3", 1, kq6laurabow2CDSignatureAudioTextSupport3, kq6laurabow2CDPatchAudioTextSupport3 },
- { false, 928, "CD: audio + text support 4", 1, kq6laurabow2CDSignatureAudioTextSupport4, kq6laurabow2CDPatchAudioTextSupport4 },
- { false, 928, "CD: audio + text support 5", 2, kq6laurabow2CDSignatureAudioTextSupport5, kq6laurabow2CDPatchAudioTextSupport5 },
- { false, 0, "CD: audio + text support disable mode reset", 1, laurabow2CDSignatureAudioTextSupportModeReset, laurabow2CDPatchAudioTextSupportModeReset },
- { false, 100, "CD: audio + text support disable mode reset", 1, laurabow2CDSignatureAudioTextSupportModeReset, laurabow2CDPatchAudioTextSupportModeReset },
- { false, 24, "CD: audio + text support LB2 menu 1", 1, laurabow2CDSignatureAudioTextMenuSupport1, laurabow2CDPatchAudioTextMenuSupport1 },
- { false, 24, "CD: audio + text support LB2 menu 2", 1, laurabow2CDSignatureAudioTextMenuSupport2, laurabow2CDPatchAudioTextMenuSupport2 },
+ { false, 924, "CD: audio + text support 1", 1, kq6laurabow2CDSignatureAudioTextSupport1, kq6laurabow2CDPatchAudioTextSupport1 },
+ { false, 924, "CD: audio + text support 2", 1, kq6laurabow2CDSignatureAudioTextSupport2, kq6laurabow2CDPatchAudioTextSupport2 },
+ { false, 924, "CD: audio + text support 3", 1, kq6laurabow2CDSignatureAudioTextSupport3, kq6laurabow2CDPatchAudioTextSupport3 },
+ { false, 928, "CD: audio + text support 4", 1, kq6laurabow2CDSignatureAudioTextSupport4, kq6laurabow2CDPatchAudioTextSupport4 },
+ { false, 928, "CD: audio + text support 5", 2, kq6laurabow2CDSignatureAudioTextSupport5, kq6laurabow2CDPatchAudioTextSupport5 },
+ { false, 0, "CD: audio + text support disable mode reset", 1, laurabow2CDSignatureAudioTextSupportModeReset, laurabow2CDPatchAudioTextSupportModeReset },
+ { false, 100, "CD: audio + text support disable mode reset", 1, laurabow2CDSignatureAudioTextSupportModeReset, laurabow2CDPatchAudioTextSupportModeReset },
+ { false, 24, "CD: audio + text support LB2 menu 1", 1, laurabow2CDSignatureAudioTextMenuSupport1, laurabow2CDPatchAudioTextMenuSupport1 },
+ { false, 24, "CD: audio + text support LB2 menu 2", 1, laurabow2CDSignatureAudioTextMenuSupport2, laurabow2CDPatchAudioTextMenuSupport2 },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -3939,8 +4097,7 @@ static const uint16 qfg3PatchMissingPoints1[] = {
PATCH_UINT16(0xFFD6), // -42 "Greet"
PATCH_UINT16(0xFFB0), // -80 "Say Good-bye"
PATCH_UINT16(0x03E7), // 999 END MARKER
- PATCH_GETORIGINALBYTE(+28), // local[$aa][0].low
- PATCH_GETORIGINALBYTE(+29), // local[$aa][0].high
+ PATCH_GETORIGINALUINT16(+28), // local[$aa][0]
PATCH_END
};
@@ -4841,14 +4998,6 @@ void ScriptPatcher::applyPatch(const SciScriptPatcherEntry *patchEntry, byte *sc
break;
}
case PATCH_CODE_GETORIGINALBYTE: {
- // get original byte from script
- if (patchValue >= orgDataSize)
- error("Script-Patcher: can not get requested original byte from script");
- scriptData[offset] = orgData[patchValue];
- offset++;
- break;
- }
- case PATCH_CODE_GETORIGINALBYTEADJUST: {
// get original byte from script and adjust it
if (patchValue >= orgDataSize)
error("Script-Patcher: can not get requested original byte from script");
@@ -4859,6 +5008,30 @@ void ScriptPatcher::applyPatch(const SciScriptPatcherEntry *patchEntry, byte *sc
offset++;
break;
}
+ case PATCH_CODE_GETORIGINALUINT16: {
+ // get original byte from script and adjust it
+ if ((patchValue >= orgDataSize) || (((uint32)patchValue + 1) >= orgDataSize))
+ error("Script-Patcher: can not get requested original uint16 from script");
+ uint16 orgUINT16;
+ int16 adjustValue;
+
+ if (!_isMacSci11) {
+ orgUINT16 = orgData[patchValue] | (orgData[patchValue + 1] << 8);
+ } else {
+ orgUINT16 = orgData[patchValue + 1] | (orgData[patchValue] << 8);
+ }
+ patchData++; adjustValue = (int16)(*patchData);
+ orgUINT16 += adjustValue;
+ if (!_isMacSci11) {
+ scriptData[offset] = orgUINT16 & 0xFF;
+ scriptData[offset + 1] = orgUINT16 >> 8;
+ } else {
+ scriptData[offset] = orgUINT16 >> 8;
+ scriptData[offset + 1] = orgUINT16 & 0xFF;
+ }
+ offset += 2;
+ break;
+ }
case PATCH_CODE_UINT16:
case PATCH_CODE_SELECTOR16: {
byte byte1;
@@ -5134,7 +5307,8 @@ void ScriptPatcher::calculateMagicDWordAndVerify(const char *signatureDescriptio
}
break;
}
- case PATCH_CODE_GETORIGINALBYTEADJUST: {
+ case PATCH_CODE_GETORIGINALBYTE:
+ case PATCH_CODE_GETORIGINALUINT16: {
signatureData++; // skip over extra uint16
break;
}
diff --git a/engines/sci/engine/script_patches.h b/engines/sci/engine/script_patches.h
index f95806a3f3..b5797be847 100644
--- a/engines/sci/engine/script_patches.h
+++ b/engines/sci/engine/script_patches.h
@@ -44,23 +44,25 @@ namespace Sci {
#define SIG_UINT16(_value_) SIG_CODE_UINT16 | ((_value_) & 0xFF), ((_value_) >> 8)
#define SIG_CODE_BYTE 0x0000
-#define PATCH_END SIG_END
-#define PATCH_COMMANDMASK SIG_COMMANDMASK
-#define PATCH_VALUEMASK SIG_VALUEMASK
-#define PATCH_BYTEMASK SIG_BYTEMASK
-#define PATCH_CODE_ADDTOOFFSET SIG_CODE_ADDTOOFFSET
-#define PATCH_ADDTOOFFSET(_offset_) SIG_CODE_ADDTOOFFSET | (_offset_)
-#define PATCH_CODE_GETORIGINALBYTE 0xD000
-#define PATCH_GETORIGINALBYTE(_offset_) PATCH_CODE_GETORIGINALBYTE | (_offset_)
-#define PATCH_CODE_GETORIGINALBYTEADJUST 0xC000
-#define PATCH_GETORIGINALBYTEADJUST(_offset_, _adjustValue_) PATCH_CODE_GETORIGINALBYTEADJUST | (_offset_), (uint16)(_adjustValue_)
-#define PATCH_CODE_SELECTOR16 SIG_CODE_SELECTOR16
-#define PATCH_SELECTOR16(_selectorID_) SIG_CODE_SELECTOR16 | SELECTOR_##_selectorID_
-#define PATCH_CODE_SELECTOR8 SIG_CODE_SELECTOR8
-#define PATCH_SELECTOR8(_selectorID_) SIG_CODE_SELECTOR8 | SELECTOR_##_selectorID_
-#define PATCH_CODE_UINT16 SIG_CODE_UINT16
-#define PATCH_UINT16(_value_) SIG_CODE_UINT16 | ((_value_) & 0xFF), ((_value_) >> 8)
-#define PATCH_CODE_BYTE SIG_CODE_BYTE
+#define PATCH_END SIG_END
+#define PATCH_COMMANDMASK SIG_COMMANDMASK
+#define PATCH_VALUEMASK SIG_VALUEMASK
+#define PATCH_BYTEMASK SIG_BYTEMASK
+#define PATCH_CODE_ADDTOOFFSET SIG_CODE_ADDTOOFFSET
+#define PATCH_ADDTOOFFSET(_offset_) SIG_CODE_ADDTOOFFSET | (_offset_)
+#define PATCH_CODE_GETORIGINALBYTE 0xC000
+#define PATCH_GETORIGINALBYTE(_offset_) PATCH_CODE_GETORIGINALBYTE | (_offset_), 0
+#define PATCH_GETORIGINALBYTEADJUST(_offset_, _adjustValue_) PATCH_CODE_GETORIGINALBYTE | (_offset_), (uint16)(_adjustValue_)
+#define PATCH_CODE_GETORIGINALUINT16 0xD000
+#define PATCH_GETORIGINALUINT16(_offset_) PATCH_CODE_GETORIGINALUINT16 | (_offset_), 0
+#define PATCH_GETORIGINALUINT16ADJUST(_offset_, _adjustValue_) PATCH_CODE_GETORIGINALUINT16 | (_offset_), (uint16)(_adjustValue_)
+#define PATCH_CODE_SELECTOR16 SIG_CODE_SELECTOR16
+#define PATCH_SELECTOR16(_selectorID_) SIG_CODE_SELECTOR16 | SELECTOR_##_selectorID_
+#define PATCH_CODE_SELECTOR8 SIG_CODE_SELECTOR8
+#define PATCH_SELECTOR8(_selectorID_) SIG_CODE_SELECTOR8 | SELECTOR_##_selectorID_
+#define PATCH_CODE_UINT16 SIG_CODE_UINT16
+#define PATCH_UINT16(_value_) SIG_CODE_UINT16 | ((_value_) & 0xFF), ((_value_) >> 8)
+#define PATCH_CODE_BYTE SIG_CODE_BYTE
// defines maximum scratch area for getting original bytes from unpatched script data
#define PATCH_VALUELIMIT 4096
diff --git a/engines/titanic/star_control/base_star.cpp b/engines/titanic/star_control/base_star.cpp
index ffe5fd05b4..b1e813b0ae 100644
--- a/engines/titanic/star_control/base_star.cpp
+++ b/engines/titanic/star_control/base_star.cpp
@@ -214,4 +214,10 @@ int CBaseStar::baseFn2(CSurfaceArea *surfaceArea, CStarControlSub12 *sub12) {
return ref._index;
}
+/*------------------------------------------------------------------------*/
+
+void CStarVector::apply() {
+ _owner->addMatrixRow(_vector);
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/base_star.h b/engines/titanic/star_control/base_star.h
index 1c75efd26b..ff096520e5 100644
--- a/engines/titanic/star_control/base_star.h
+++ b/engines/titanic/star_control/base_star.h
@@ -53,11 +53,14 @@ struct CBaseStarEntry {
bool operator==(const CBaseStarEntry &s) const;
};
-struct CStarPosition {
- Common::Point _position;
+struct CStarPosition : public Common::Point {
int _index1;
int _index2;
CStarPosition() : _index1(0), _index2(0) {}
+
+ bool operator==(const CStarPosition &sp) const {
+ return x == sp.x && y == sp.y && _index1 == sp._index1 && _index2 == sp._index2;
+ }
};
class CBaseStar {
@@ -143,6 +146,19 @@ public:
int baseFn2(CSurfaceArea *surfaceArea, CStarControlSub12 *sub12);
};
+class CStarVector {
+private:
+ CStarControlSub12 *_owner;
+ FVector _vector;
+public:
+ CStarVector(CStarControlSub12 *owner, const FVector &v) : _owner(owner), _vector(v) {}
+
+ /**
+ * Applies the saved vector
+ */
+ void apply();
+};
+
} // End of namespace Titanic
#endif /* TITANIC_STAR_CONTROL_SUB3_H */
diff --git a/engines/titanic/star_control/dmatrix.cpp b/engines/titanic/star_control/dmatrix.cpp
index 1405f4f693..1808b13dc2 100644
--- a/engines/titanic/star_control/dmatrix.cpp
+++ b/engines/titanic/star_control/dmatrix.cpp
@@ -29,21 +29,30 @@ namespace Titanic {
DMatrix *DMatrix::_static;
DMatrix::DMatrix() :
- _row1(1.875, 0.0, 0.0), _row2(0.0, 1.875, 0.0), _row3(0.0, 0.0, 1.875) {
+ _row1(0.0, 0.0, 0.0), _row2(0.0, 0.0, 0.0), _row3(0.0, 0.0, 0.0) {
}
-DMatrix::DMatrix(int mode, const FMatrix *src) {
- assert(!mode);
-
- _row1._x = 1.875;
- _row2._y = 1.875;
- _row3._z = 1.875;
- _frow1._x = src->_row1._x;
- _frow1._y = src->_row1._y;
- _frow1._z = src->_row1._z;
- _frow2._x = src->_row2._x;
- _frow2._y = src->_row2._y;
- _frow2._z = src->_row2._z;
+DMatrix::DMatrix(int mode, const DVector &src) {
+ switch (mode) {
+ case 0:
+ _row1._x = 1.0;
+ _row2._y = 1.0;
+ _row3._z = 1.0;
+ _row4 = src;
+ break;
+
+ case 1:
+ _row1._x = src._x;
+ _row2._y = src._y;
+ _row3._z = src._z;
+ break;
+
+ default:
+ _row1._x = 1.0;
+ _row2._y = 1.0;
+ _row3._z = 1.0;
+ break;
+ }
}
DMatrix::DMatrix(Axis axis, double amount) {
diff --git a/engines/titanic/star_control/dmatrix.h b/engines/titanic/star_control/dmatrix.h
index a015ebdb1d..c3490770fb 100644
--- a/engines/titanic/star_control/dmatrix.h
+++ b/engines/titanic/star_control/dmatrix.h
@@ -42,14 +42,13 @@ public:
DVector _row1;
DVector _row2;
DVector _row3;
- FVector _frow1;
- FVector _frow2;
+ DVector _row4;
public:
static void init();
static void deinit();
public:
DMatrix();
- DMatrix(int mode, const FMatrix *src);
+ DMatrix(int mode, const DVector &src);
DMatrix(Axis axis, double amount);
DMatrix(const FMatrix &src);
diff --git a/engines/titanic/star_control/dvector.cpp b/engines/titanic/star_control/dvector.cpp
index dc1376537e..9cd610fc0a 100644
--- a/engines/titanic/star_control/dvector.cpp
+++ b/engines/titanic/star_control/dvector.cpp
@@ -38,8 +38,9 @@ double DVector::getDistance(const DVector &src) {
return sqrt((src._x - _x) * (src._x - _x) + (src._y - _y) * (src._y - _y) + (src._z - _z) * (src._z - _z));
}
-void DVector::fn1(DVector &dest, const DMatrix &m) {
+DVector *DVector::fn1(DVector &dest, const DMatrix &m) {
// TODO
+ return nullptr;
}
void DVector::fn2(double val) {
diff --git a/engines/titanic/star_control/dvector.h b/engines/titanic/star_control/dvector.h
index a216be15fe..a447f253e1 100644
--- a/engines/titanic/star_control/dvector.h
+++ b/engines/titanic/star_control/dvector.h
@@ -48,11 +48,45 @@ public:
*/
double getDistance(const DVector &src);
- void fn1(DVector &dest, const DMatrix &m);
+ DVector *fn1(DVector &dest, const DMatrix &m);
void fn2(double val);
void fn3(DVector &dest);
const DMatrix *fn4(const DVector &v, DMatrix &m);
void fn5(DMatrix &dest);
+
+ /**
+ * Returns true if the passed vector equals this one
+ */
+ bool operator==(const DVector &src) const {
+ return _x != src._x || _y != src._y || _z != src._z;
+ }
+
+ /**
+ * Returns true if the passed vector does not equal this one
+ */
+ bool operator!=(const DVector &src) const {
+ return !operator==(src);
+ }
+
+ DVector operator+(const DVector &delta) const {
+ return DVector(_x + delta._x, _y + delta._y, _z + delta._z);
+ }
+
+ DVector operator-(const DVector &delta) const {
+ return DVector(_x - delta._x, _y - delta._y, _z - delta._z);
+ }
+
+ void operator+=(const DVector &delta) {
+ _x += delta._x;
+ _y += delta._y;
+ _z += delta._z;
+ }
+
+ void operator-=(const DVector &delta) {
+ _x -= delta._x;
+ _y -= delta._y;
+ _z -= delta._z;
+ }
};
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/fmatrix.cpp b/engines/titanic/star_control/fmatrix.cpp
index e0c270ba7d..54e674cad8 100644
--- a/engines/titanic/star_control/fmatrix.cpp
+++ b/engines/titanic/star_control/fmatrix.cpp
@@ -78,10 +78,16 @@ void FMatrix::identity() {
_row3 = FVector(0.0, 0.0, 1.0);
}
-void FMatrix::set(FVector *row1, FVector *row2, FVector *row3) {
- _row1 = *row1;
- _row2 = *row2;
- _row3 = *row3;
+void FMatrix::set(const FVector &row1, const FVector &row2, const FVector &row3) {
+ _row1 = row1;
+ _row2 = row2;
+ _row3 = row3;
+}
+
+void FMatrix::set(const DVector &row1, const DVector &row2, const DVector &row3) {
+ _row1 = row1;
+ _row2 = row2;
+ _row3 = row3;
}
void FMatrix::fn1(const FVector &v) {
@@ -94,13 +100,13 @@ void FMatrix::fn1(const FVector &v) {
_row2._y = tempVector._y;
_row2._z = tempVector._z;
- _row3.crossProduct(&tempVector, &_row2);
+ _row3.crossProduct(tempVector, _row2);
_row1._x = _row2._x;
_row1._y = _row2._y;
_row1._z = _row2._z;
_row1.normalize();
- _row3.crossProduct(&tempVector, &_row1);
+ _row3.crossProduct(tempVector, _row1);
_row2._x = _row1._x;
_row2._y = _row1._y;
_row2._z = _row1._z;
diff --git a/engines/titanic/star_control/fmatrix.h b/engines/titanic/star_control/fmatrix.h
index 7ab90fb7e1..0cbecb2ff8 100644
--- a/engines/titanic/star_control/fmatrix.h
+++ b/engines/titanic/star_control/fmatrix.h
@@ -29,6 +29,7 @@
namespace Titanic {
class DMatrix;
+class DVector;
/**
* Floating point matrix class.
@@ -72,7 +73,12 @@ public:
/**
* Sets the data for the matrix
*/
- void set(FVector *row1, FVector *row2, FVector *row3);
+ void set(const FVector &row1, const FVector &row2, const FVector &row3);
+
+ /**
+ * Sets the data for the matrix
+ */
+ void set(const DVector &row1, const DVector &row2, const DVector &row3);
void fn1(const FVector &v);
void fn2(const FMatrix &m);
@@ -91,6 +97,15 @@ public:
bool operator!=(const FMatrix &src) {
return !operator==(src);
}
+
+ /**
+ * Allows accessing rows as an array
+ */
+ FVector &operator[](int idx) {
+ assert(idx >= 0 && idx <= 2);
+ FVector *rows[3] = { &_row1, &_row2, &_row3 };
+ return *rows[idx];
+ }
};
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/fvector.cpp b/engines/titanic/star_control/fvector.cpp
index b0667c532b..666b22eb3a 100644
--- a/engines/titanic/star_control/fvector.cpp
+++ b/engines/titanic/star_control/fvector.cpp
@@ -21,12 +21,16 @@
*/
#include "titanic/star_control/fvector.h"
+#include "titanic/star_control/dvector.h"
#include "titanic/star_control/star_control_sub6.h"
#include "common/algorithm.h"
#include "common/textconsole.h"
namespace Titanic {
+FVector::FVector(const DVector &src) : _x(src._x), _y(src._y), _z(src._z) {
+}
+
void FVector::fn1(FVector *v) {
v->_x = (ABS(_x - _y) < 0.00001 && ABS(_y - _z) < 0.00001 &&
ABS(_x - _z) < 0.00001) ? -_x : _x;
@@ -34,10 +38,10 @@ void FVector::fn1(FVector *v) {
v->_z = _z;
}
-void FVector::crossProduct(FVector *dest, const FVector *src) {
- dest->_x = (src->_z * _y) - (_z * src->_y);
- dest->_y = (src->_x * _z) - (_x * src->_z);
- dest->_z = (src->_y * _x) - (_y * src->_x);
+void FVector::crossProduct(FVector &dest, const FVector &src) {
+ dest._x = (src._z * _y) - (_z * src._y);
+ dest._y = (src._x * _z) - (_x * src._z);
+ dest._z = (src._y * _x) - (_y * src._x);
}
double FVector::normalize() {
@@ -50,22 +54,23 @@ double FVector::normalize() {
return hyp;
}
-void FVector::addAndNormalize(FVector *dest, const FVector *v1, const FVector *v2) {
- FVector tempVector(v1->_x + v2->_x, v1->_y + v2->_y, v1->_z + v2->_z);
+const FVector *FVector::addAndNormalize(FVector &dest, const FVector &v1, const FVector &v2) {
+ FVector tempVector(v1._x + v2._x, v1._y + v2._y, v1._z + v2._z);
tempVector.normalize();
- *dest = tempVector;
+ dest = tempVector;
+ return &dest;
}
-double FVector::getDistance(const FVector *src) const {
- double xd = src->_x - _x;
- double yd = src->_y - _y;
- double zd = src->_z - _z;
+double FVector::getDistance(const FVector &src) const {
+ double xd = src._x - _x;
+ double yd = src._y - _y;
+ double zd = src._z - _z;
return sqrt(xd * xd + yd * yd + zd * zd);
}
-void FVector::fn5(FVector *dest, const CStarControlSub6 *sub6) const {
+FVector FVector::fn5(const CStarControlSub6 *sub6) const {
error("TODO: FVector::fn5");
}
diff --git a/engines/titanic/star_control/fvector.h b/engines/titanic/star_control/fvector.h
index bf446fc640..67eba6b5c9 100644
--- a/engines/titanic/star_control/fvector.h
+++ b/engines/titanic/star_control/fvector.h
@@ -30,6 +30,7 @@ namespace Titanic {
enum Axis { X_AXIS, Y_AXIS, Z_AXIS };
class CStarControlSub6;
+class DVector;
/**
* Floating point vector class.
@@ -41,6 +42,7 @@ public:
public:
FVector() : _x(0), _y(0), _z(0) {}
FVector(double x, double y, double z) : _x(x), _y(y), _z(z) {}
+ FVector(const DVector &src);
/**
* Clears the vector
@@ -54,7 +56,7 @@ public:
/**
* Calculates the cross-product between this matrix and a passed one
*/
- void crossProduct(FVector *dest, const FVector *src);
+ void crossProduct(FVector &dest, const FVector &src);
/**
* Normalizes the vector so the length from origin equals 1.0
@@ -64,14 +66,14 @@ public:
/**
* Adds two vectors together and then normalizes the result
*/
- static void addAndNormalize(FVector *dest, const FVector *v1, const FVector *v2);
+ static const FVector *addAndNormalize(FVector &dest, const FVector &v1, const FVector &v2);
/**
* Returns the distance between a specified point and this one
*/
- double getDistance(const FVector *src) const;
+ double getDistance(const FVector &src) const;
- void fn5(FVector *dest, const CStarControlSub6 *sub6) const;
+ FVector fn5(const CStarControlSub6 *sub6) const;
/**
* Returns true if the passed vector equals this one
@@ -95,6 +97,10 @@ public:
return FVector(_x - delta._x, _y - delta._y, _z - delta._z);
}
+ const FVector operator*(double right) const {
+ return FVector(_x * right, _y * right, _z * right);
+ }
+
void operator+=(const FVector &delta) {
_x += delta._x;
_y += delta._y;
diff --git a/engines/titanic/star_control/star_control_sub12.cpp b/engines/titanic/star_control/star_control_sub12.cpp
index 7ed65357d3..45cebec836 100644
--- a/engines/titanic/star_control/star_control_sub12.cpp
+++ b/engines/titanic/star_control/star_control_sub12.cpp
@@ -23,6 +23,8 @@
#include "titanic/star_control/star_control_sub12.h"
#include "titanic/star_control/star_control_sub21.h"
#include "titanic/star_control/star_control_sub22.h"
+#include "titanic/star_control/dmatrix.h"
+#include "titanic/star_control/fmatrix.h"
namespace Titanic {
@@ -30,12 +32,12 @@ FMatrix *CStarControlSub12::_matrix1;
FMatrix *CStarControlSub12::_matrix2;
CStarControlSub12::CStarControlSub12(const CStar20Data *data) :
- _currentIndex(-1), _handlerP(nullptr), _field108(0) {
+ _matrixRow(-1), _handlerP(nullptr), _field108(0) {
setupHandler(data);
}
CStarControlSub12::CStarControlSub12(CStarControlSub13 *src) :
- _currentIndex(-1), _handlerP(nullptr), _field108(0), _sub13(src) {
+ _matrixRow(-1), _handlerP(nullptr), _field108(0), _sub13(src) {
}
void CStarControlSub12::init() {
@@ -215,22 +217,204 @@ FVector CStarControlSub12::proc31(int index, const FVector &v) {
return _sub13.fn18(index, v);
}
-void CStarControlSub12::setViewportPosition(const FPoint &pt) {
- // TODO
+void CStarControlSub12::setViewportPosition(const FPoint &angles) {
+ if (isLocked())
+ return;
+
+ if (_matrixRow == -1) {
+ CStarControlSub6 subX(X_AXIS, angles._x);
+ CStarControlSub6 subY(Y_AXIS, angles._y);
+ CStarControlSub6 sub(&subX, &subY);
+ subY.copyFrom(&sub);
+ proc22(subY);
+ } else if (_matrixRow == 0) {
+ FVector row1 = _matrix._row1;
+ CStarControlSub6 subX(X_AXIS, angles._x);
+ CStarControlSub6 subY(Y_AXIS, angles._y);
+ CStarControlSub6 sub(&subX, &subY);
+ subX.copyFrom(&sub);
+
+ FMatrix m1 = _sub13.getMatrix();
+ FVector tempV1 = _sub13._position;
+ FVector tempV2, tempV3, tempV4, tempV5, tempV6;
+ tempV2._y = m1._row1._y * 100000.0;
+ tempV2._z = m1._row1._z * 100000.0;
+ tempV3._x = m1._row1._x * 100000.0 + tempV1._x;
+ tempV4._x = tempV3._x;
+ tempV3._y = tempV2._y + tempV1._y;
+ tempV4._y = tempV3._y;
+ tempV3._z = tempV2._z + tempV1._z;
+ tempV4._z = tempV3._z;
+ tempV2._x = m1._row2._x * 100000.0;
+ tempV2._y = m1._row2._y * 100000.0;
+ tempV2._z = m1._row2._z * 100000.0;
+ tempV2._x = m1._row3._x * 100000.0;
+ tempV2._y = m1._row3._y * 100000.0;
+ tempV2._z = m1._row3._z * 100000.0;
+ tempV2._x = tempV2._x + tempV1._x;
+ tempV2._y = tempV2._y + tempV1._y;
+ tempV2._z = tempV2._z + tempV1._z;
+ tempV3._x = tempV2._x + tempV1._x;
+ tempV3._y = tempV2._y + tempV1._y;
+ tempV5._x = tempV2._x;
+ tempV5._y = tempV2._y;
+ tempV3._z = tempV2._z + tempV1._z;
+ tempV5._z = tempV2._z;
+ tempV6._x = tempV3._x;
+ tempV6._y = tempV3._y;
+ tempV6._z = tempV3._z;
+ tempV1._x = tempV1._x - row1._x;
+ tempV1._y = tempV1._y - row1._y;
+ tempV1._z = tempV1._z - row1._z;
+ tempV4._x = tempV3._x - row1._x;
+ tempV4._y = tempV4._y - row1._y;
+ tempV4._z = tempV4._z - row1._z;
+ tempV5._x = tempV2._x - row1._x;
+
+ tempV5._y = tempV5._y - row1._y;
+ tempV5._z = tempV5._z - row1._z;
+ tempV6._x = tempV3._x - row1._x;
+ tempV6._y = tempV6._y - row1._y;
+ tempV6._z = tempV6._z - row1._z;
+
+ FVector modV1 = tempV1.fn5(&subX);
+ FVector modV2 = tempV4.fn5(&subX);
+ FVector modV3 = tempV5.fn5(&subX);
+ FVector modV4 = tempV6.fn5(&subX);
+ tempV1 = modV1;
+ tempV4 = modV2;
+ tempV5 = modV3;
+ tempV4 = modV4;
+
+ tempV2._x = tempV4._x - tempV1._x;
+ tempV2._y = tempV4._y - tempV1._y;
+ tempV2._z = tempV4._z - tempV1._z;
+ tempV4._x = tempV2._x;
+ tempV4._y = tempV2._y;
+ tempV2._x = tempV5._x - tempV1._x;
+ tempV4._z = tempV2._z;
+ tempV5._x = tempV2._x;
+ tempV2._y = tempV5._y - tempV1._y;
+ tempV5._y = tempV2._y;
+ tempV2._z = tempV5._z - tempV1._z;
+ tempV5._z = tempV2._z;
+ tempV2._x = tempV6._x - tempV1._x;
+ tempV2._y = tempV6._y - tempV1._y;
+ tempV2._z = tempV6._z - tempV1._z;
+ tempV6 = tempV2;
+
+ tempV4.normalize();
+ tempV5.normalize();
+ tempV6.normalize();
+ tempV1 += row1;
+
+ m1.set(tempV4, tempV5, tempV6);
+ _sub13.setMatrix(m1);
+ _sub13.setPosition(tempV1);
+ } else if (_matrixRow == 1) {
+ FVector tempV2;
+ DMatrix m1, m2, sub;
+ DVector mrow1, mrow2, mrow3;
+ DVector tempV1, diffV, multV, multV2, tempV3, tempV4, tempV5, tempV6, tempV7;
+ DVector tempV8, tempV9, tempV10, tempV11, tempV12;
+ DVector tempV13, tempV14, tempV15, tempV16;
+
+ DMatrix subX(0, _matrix._row1);
+ DMatrix subY(Y_AXIS, angles._x);
+
+ tempV1 = _matrix._row2 - _matrix._row1;
+ diffV = tempV1;
+ diffV.fn5(m1);
+ sub.fn4(sub, m1, subX);
+ m1 = sub;
+ m1.fn1(subX);
+ subX.fn4(m2, subX, subY);
+ subX = m2;
+
+ FMatrix m3 = _sub13.getMatrix();
+ tempV2 = _sub13._position;
+ multV._x = m3._row1._x * 1000000.0;
+ multV._y = m3._row1._y * 1000000.0;
+ multV._z = m3._row1._z * 1000000.0;
+ tempV3._x = tempV2._x;
+ tempV3._y = tempV2._y;
+ tempV3._z = tempV2._z;
+ multV2._z = m3._row2._z * 1000000.0;
+
+ tempV1._x = multV._x + tempV3._x;
+ tempV1._y = multV._y + tempV3._y;
+ tempV1._z = multV._z + tempV3._z;
+ mrow3._z = 0.0;
+ mrow3._y = 0.0;
+ mrow3._x = 0.0;
+ multV2._x = m3._row2._x * 1000000.0;
+ multV2._y = m3._row2._y * 1000000.0;
+ mrow1 = tempV1;
+ multV = multV2 + tempV3;
+ mrow2 = multV;
+
+ tempV7._z = m3._row3._z * 1000000.0 + tempV3._z;
+ tempV7._y = m3._row3._y * 1000000.0 + tempV3._y;
+ tempV7._x = m3._row3._x * 1000000.0 + tempV3._x;
+
+ mrow3 = tempV8;
+ DVector *v = tempV3.fn1(tempV9, subX);
+ tempV3 = *v;
+ v = mrow1.fn1(tempV10, subX);
+ mrow1 = *v;
+ v = mrow2.fn1(tempV11, subX);
+ mrow2 = *v;
+ v = mrow3.fn1(tempV12, subX);
+ mrow3 = *v;
+
+ v = tempV3.fn1(tempV13, m1);
+ tempV3 = *v;
+ v = mrow1.fn1(tempV14, m1);
+ mrow1 = *v;
+ v = mrow2.fn1(tempV15, m1);
+ mrow2 = *v;
+ v = mrow3.fn1(tempV16, m1);
+ mrow3 = *v;
+
+ mrow1 -= tempV3;
+ mrow2 -= tempV3;
+ mrow3 -= tempV3;
+ mrow1.normalize();
+ mrow2.normalize();
+ mrow3.normalize();
+ tempV16 = tempV3;
+
+ m3.set(mrow1, mrow2, mrow3);
+ _sub13.setMatrix(m3);
+ _sub13.setPosition(tempV16);
+ }
}
-bool CStarControlSub12::setArrayVector(const FVector &v) {
- if (_currentIndex >= 2)
+bool CStarControlSub12::addMatrixRow(const FVector &v) {
+ if (_matrixRow >= 2)
return false;
- error("TODO: CStarControlSub12::setArrayVector");
+ CStar20Data data;
+ _handlerP->copyTo(&data);
+ deleteHandler();
+
+ FVector &row = _matrix[++_matrixRow];
+ row = v;
+ setupHandler(&data);
+ return true;
}
-bool CStarControlSub12::proc35() {
- if (_currentIndex == -1)
+bool CStarControlSub12::removeMatrixRow() {
+ if (_matrixRow == -1)
return false;
- error("TODO: CStarControlSub12::proc35");
+ CStar20Data data;
+ _handlerP->copyTo(&data);
+ deleteHandler();
+
+ --_matrixRow;
+ setupHandler(&data);
+ return true;
}
void CStarControlSub12::proc36(double *v1, double *v2, double *v3, double *v4) {
@@ -248,7 +432,7 @@ void CStarControlSub12::save(SimpleFile *file, int indent) {
bool CStarControlSub12::setupHandler(const CStar20Data *src) {
CStarControlSub20 *handler = nullptr;
- switch (_currentIndex) {
+ switch (_matrixRow) {
case -1:
handler = new CStarControlSub21(src);
break;
@@ -281,15 +465,143 @@ void CStarControlSub12::deleteHandler() {
}
void CStarControlSub12::fn1(CStarControlSub13 *sub13, const FVector &v) {
- // TODO
+ if (_matrixRow == 1) {
+ FMatrix m1 = sub13->getMatrix();
+ FMatrix m2 = _sub13.getMatrix();
+ FVector v1 = sub13->_position;
+ FVector v2 = _sub13._position;
+
+ _handlerP->proc8(v2, v1, m2, m1);
+ CStarVector *sv = new CStarVector(this, v);
+ _handlerP->setVector(sv);
+ }
}
void CStarControlSub12::fn2(FVector v1, FVector v2, FVector v3) {
- // TODO
+ if (_matrixRow == -1) {
+ FVector tempV;
+ tempV._z = _sub13._field10;
+ v3._z = v1._z;
+ tempV._x = _sub13._fieldD0 * v1._y * v1._z / _sub13._fieldC8;
+ v3._y = _sub13._fieldCC * tempV._z * v3._x / _sub13._fieldC8;
+ v3._x = _sub13._fieldCC * v1._x * v1._z / _sub13._fieldC8 - _sub13._valArray[2];
+ tempV._y = _sub13._fieldD0 * tempV._z * v3._y / _sub13._fieldC8;
+ tempV._x = tempV._x - _sub13._valArray[2];
+
+ v3.normalize();
+ tempV.normalize();
+
+ FMatrix matrix = _sub13.getMatrix();
+ const FVector &pos = _sub13._position;
+ _handlerP->proc10(v3, tempV, pos, matrix);
+
+ CStarVector *sv = new CStarVector(this, v2);
+ _handlerP->setVector(sv);
+ }
}
void CStarControlSub12::fn3(CStarControlSub13 *sub13, const FVector &v) {
- // TODO
+ if (_matrixRow != 0)
+ return;
+
+ DMatrix m1;
+ DVector tempV1 = _matrix._row1;
+ DMatrix m2(0, tempV1);
+
+ tempV1 = v - _matrix._row1;
+ tempV1.fn5(m1);
+
+ DMatrix m3;
+ const DMatrix *m = m1.fn4(m3, m1, m2);
+ m1 = *m;
+ m1.fn1(m2);
+
+ DVector tempV2 = _sub13._position;
+ DMatrix m4;
+ m4._row1 = sub13->_position;
+ m4._row2 = DVector(0.0, 0.0, 0.0);
+ m4._row3 = DVector(0.0, 0.0, 0.0);
+ m4._row4 = DVector(0.0, 0.0, 0.0);
+
+ FMatrix m5 = sub13->getMatrix();
+ DVector tempV3, tempV4;
+ tempV4._x = m5._row1._x * 1000000.0 + m4._row1._x;
+ tempV4._y = m5._row1._y * 1000000.0 + m4._row1._y;
+ tempV4._z = m5._row1._z * 1000000.0 + m4._row1._z;
+ tempV3._x = m5._row2._x * 1000000.0 + m4._row1._x;
+ tempV3._y = m5._row2._y * 1000000.0 + m4._row1._y;
+ tempV3._z = m5._row2._z * 1000000.0 + m4._row1._z;
+ m4._row3 = tempV4;
+ m4._row2 = tempV3;
+
+ tempV4._x = m5._row3._x * 1000000.0;
+ tempV4._y = m5._row3._y * 1000000.0;
+ tempV3._x = tempV4._x + m4._row1._x;
+ tempV3._y = tempV4._y + m4._row1._y;
+ tempV3._z = m5._row3._z * 1000000.0 + m4._row1._z;
+ m4._row4 = tempV3;
+
+ DVector *dv = tempV2.fn1(tempV3, m2);
+ tempV3 = *dv;
+ dv = m4._row1.fn1(tempV3, m2);
+ m4._row1 = *dv;
+ dv = m4._row3.fn1(tempV3, m2);
+ m4._row3 = *dv;
+ dv = m4._row2.fn1(tempV3, m2);
+ m4._row2 = *dv;
+ dv = m4._row4.fn1(tempV3, m2);
+ m4._row4 = *dv;
+
+ // Find the angle that gives the minimum distance
+ DVector tempV5;
+ double minDistance = 1.0e20;
+ int minDegree = 0;
+ for (int degree = 0; degree < 360; ++degree) {
+ tempV5 = m4._row1;
+ tempV5.fn2((double)degree);
+ double distance = tempV2.getDistance(tempV5);
+
+ if (distance < minDistance) {
+ minDistance = distance;
+ minDegree = degree;
+ }
+ }
+
+ m4._row1.fn2((double)minDegree);
+ m4._row2.fn2((double)minDegree);
+ m4._row3.fn2((double)minDegree);
+ m4._row4.fn2((double)minDegree);
+ dv = m4._row1.fn1(tempV3, m1);
+ m4._row1 = *dv;
+ dv = m4._row3.fn1(tempV3, m1);
+ m4._row3 = *dv;
+ dv = m4._row2.fn1(tempV3, m1);
+ m4._row2 = *dv;
+ dv = m4._row4.fn1(tempV3, m1);
+ m4._row4 = *dv;
+
+ m4._row3._x -= m4._row1._x;
+ m4._row3._y -= m4._row1._y;
+ m4._row3._z -= m4._row1._z;
+ m4._row2._x -= m4._row1._x;
+ m4._row2._y -= m4._row1._y;
+ m4._row2._z = m4._row2._z - m4._row1._z;
+
+ m4._row4._x = m4._row4._x - m4._row1._x;
+ m4._row4._y = m4._row4._y - m4._row1._y;
+ m4._row4._z = m4._row4._z - m4._row1._z;
+
+ m4._row3.normalize();
+ m4._row2.normalize();
+ m4._row4.normalize();
+ m5.set(m4._row3, m4._row2, m4._row4);
+
+ FVector tempV6 = m4._row1;
+ FMatrix m6 = _sub13.getMatrix();
+ _handlerP->proc8(_sub13._position, tempV6, m6, m5);
+
+ CStarVector *sv = new CStarVector(this, v);
+ _handlerP->setVector(sv);
}
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub12.h b/engines/titanic/star_control/star_control_sub12.h
index fbd7b88f9d..c36960e24a 100644
--- a/engines/titanic/star_control/star_control_sub12.h
+++ b/engines/titanic/star_control/star_control_sub12.h
@@ -38,8 +38,8 @@ private:
static FMatrix *_matrix1;
static FMatrix *_matrix2;
private:
- int _currentIndex;
- FVector _array[3];
+ int _matrixRow;
+ FMatrix _matrix;
CStarControlSub20 *_handlerP;
CStarControlSub13 _sub13;
int _field108;
@@ -100,11 +100,11 @@ public:
/**
* Sets the viewport position within the starfield
*/
- virtual void setViewportPosition(const FPoint &pt);
+ virtual void setViewportPosition(const FPoint &angles);
- virtual int getCurrentIndex() const { return _currentIndex; }
- virtual bool setArrayVector(const FVector &v);
- virtual bool proc35();
+ virtual int getMatrixRow() const { return _matrixRow; }
+ virtual bool addMatrixRow(const FVector &v);
+ virtual bool removeMatrixRow();
virtual void proc36(double *v1, double *v2, double *v3, double *v4);
/**
diff --git a/engines/titanic/star_control/star_control_sub13.cpp b/engines/titanic/star_control/star_control_sub13.cpp
index e82ad3a3f1..190ae20179 100644
--- a/engines/titanic/star_control/star_control_sub13.cpp
+++ b/engines/titanic/star_control/star_control_sub13.cpp
@@ -68,6 +68,7 @@ void CStarControlSub13::copyFrom(const CStarControlSub13 *src) {
_position = src->_position;
_fieldC = src->_field18;
_field10 = src->_field1C;
+ error("TODO: Remainder of CStarControlSub13::copyFrom");
}
}
@@ -116,8 +117,7 @@ void CStarControlSub13::setPosition(const FVector &v) {
}
void CStarControlSub13::setPosition(const CStarControlSub6 *sub6) {
- FVector vector;
- _position.fn5(&vector, sub6);
+ _position.fn5(sub6);
_position = sub6->_row1;
_flag = false;
}
@@ -163,12 +163,10 @@ void CStarControlSub13::fn12() {
CStarControlSub6 m2(Y_AXIS, g_vm->getRandomNumber(359));
CStarControlSub6 m3(Z_AXIS, g_vm->getRandomNumber(359));
- CStarControlSub6 s1, s2;
- CStarControlSub6 *s;
- s = CStarControlSub6::setup(&s1, &m1, &m2);
- s = CStarControlSub6::setup(&s2, s, &m3);
+ CStarControlSub6 s1(&m1, &m2);
+ CStarControlSub6 s2(&s1, &m3);
- m1.copyFrom(*s);
+ m1.copyFrom(s2);
_matrix.fn2(m1);
_flag = false;
}
@@ -225,9 +223,8 @@ void CStarControlSub13::fn16(int index, const FVector &src, FVector &dest) {
FVector CStarControlSub13::fn17(int index, const FVector &src) {
FVector dest;
- FVector tv;
CStarControlSub6 sub6 = getSub1();
- src.fn5(&tv, &sub6);
+ FVector tv = src.fn5(&sub6);
dest._x = (_valArray[index] + tv._x)
* _fieldC8 / (_fieldCC * tv._z);
@@ -238,9 +235,8 @@ FVector CStarControlSub13::fn17(int index, const FVector &src) {
FVector CStarControlSub13::fn18(int index, const FVector &src) {
FVector dest;
- FVector tv;
CStarControlSub6 sub6 = getSub2();
- src.fn5(&tv, &sub6);
+ FVector tv = src.fn5(&sub6);
dest._x = (_valArray[index] + tv._x)
* _fieldC8 / (_fieldCC * tv._z);
@@ -257,13 +253,13 @@ void CStarControlSub13::fn19(double *v1, double *v2, double *v3, double *v4) {
}
void CStarControlSub13::reset() {
- const double FACTOR = 3.1415927 * 0.0055555557;
+ const double FACTOR = 2 * M_PI / 360.0;
_sub2.copyFrom(_matrix);
_sub2._vector._x = _position._x;
_sub2._vector._y = _position._y;
_sub2._vector._z = _position._z;
- _sub2.fn3(_sub1);
+ _sub2.fn4(&_sub1);
double widthV = (double)_width * 0.5;
double heightV = (double)_height * 0.5;
diff --git a/engines/titanic/star_control/star_control_sub20.cpp b/engines/titanic/star_control/star_control_sub20.cpp
index ca60cc9948..fd12573fac 100644
--- a/engines/titanic/star_control/star_control_sub20.cpp
+++ b/engines/titanic/star_control/star_control_sub20.cpp
@@ -27,7 +27,7 @@ namespace Titanic {
CStarControlSub20::CStarControlSub20(const CStar20Data *src) {
_lockCounter = 0;
- _dataP = nullptr;
+ _starVector = nullptr;
if (src) {
copyFrom(src);
@@ -90,7 +90,7 @@ void CStarControlSub20::proc7() {
}
}
-void CStarControlSub20::proc11(CErrorCode &errorCode, FVector &v, const FMatrix &m) {
+void CStarControlSub20::proc11(CErrorCode &errorCode, FVector &v, FMatrix &m) {
if (_size > 0.0) {
v._x += m._row3._x * _size;
v._y += m._row3._y * _size;
@@ -100,15 +100,15 @@ void CStarControlSub20::proc11(CErrorCode &errorCode, FVector &v, const FMatrix
}
}
-void CStarControlSub20::setData(void *data) {
+void CStarControlSub20::setVector(CStarVector *sv) {
clear();
- _dataP = (byte *)data;
+ _starVector = sv;
}
void CStarControlSub20::clear() {
- if (_dataP) {
- delete _dataP;
- _dataP = nullptr;
+ if (_starVector) {
+ delete _starVector;
+ _starVector = nullptr;
}
}
diff --git a/engines/titanic/star_control/star_control_sub20.h b/engines/titanic/star_control/star_control_sub20.h
index 49b63d5d5d..eed5e94ad1 100644
--- a/engines/titanic/star_control/star_control_sub20.h
+++ b/engines/titanic/star_control/star_control_sub20.h
@@ -24,6 +24,7 @@
#define TITANIC_STAR_CONTROL_SUB20_H
#include "titanic/support/simple_file.h"
+#include "titanic/star_control/base_star.h"
#include "titanic/star_control/error_code.h"
#include "titanic/star_control/fmatrix.h"
@@ -43,7 +44,7 @@ struct CStar20Data {
class CStarControlSub20 : public CStar20Data {
public:
int _lockCounter;
- byte *_dataP;
+ CStarVector *_starVector;
public:
CStarControlSub20(const CStar20Data *src);
virtual ~CStarControlSub20();
@@ -57,12 +58,8 @@ public:
virtual void proc8(FVector &v1, FVector &v2, FMatrix &m1, FMatrix &m2) {}
virtual void proc9(FVector &v1, FVector &v2, FMatrix &matrix) {}
virtual void proc10(const FVector &v1, const FVector &v2, const FVector &v3, const FMatrix &m) {}
- virtual void proc11(CErrorCode &errorCode, FVector &v, const FMatrix &m);
-
- /**
- * Set the data
- */
- virtual void setData(void *data);
+ virtual void proc11(CErrorCode &errorCode, FVector &v, FMatrix &m);
+ virtual void setVector(CStarVector *sv);
/**
* Clear the class
diff --git a/engines/titanic/star_control/star_control_sub21.cpp b/engines/titanic/star_control/star_control_sub21.cpp
index 1e676b7703..a70460aa53 100644
--- a/engines/titanic/star_control/star_control_sub21.cpp
+++ b/engines/titanic/star_control/star_control_sub21.cpp
@@ -53,18 +53,22 @@ void CStarControlSub21::proc10(const FVector &v1, const FVector &v2, const FVect
incLockCount();
}
-void CStarControlSub21::proc11(CErrorCode &errorCode, FVector &v, const FMatrix &m) {
+void CStarControlSub21::proc11(CErrorCode &errorCode, FVector &v, FMatrix &m) {
if (_sub24.get8()) {
+ decLockCount();
int val = _sub24.proc5(errorCode, v, m);
if (val == 1)
incLockCount();
if (val == 2) {
proc7();
- error("TODO: _dataP");
+ if (_starVector)
+ _starVector->apply();
}
} else if (_size != 0.0) {
- // TODO
- error("TODO");
+ v._x += m._row3._x * _size;
+ v._y += m._row3._y * _size;
+ v._z += m._row3._z * _size;
+ errorCode.set();
}
}
diff --git a/engines/titanic/star_control/star_control_sub21.h b/engines/titanic/star_control/star_control_sub21.h
index 66ce535993..17e0a427a6 100644
--- a/engines/titanic/star_control/star_control_sub21.h
+++ b/engines/titanic/star_control/star_control_sub21.h
@@ -37,7 +37,7 @@ public:
virtual void proc9(FVector &v1, FVector &v2, FMatrix &matrix);
virtual void proc10(const FVector &v1, const FVector &v2, const FVector &v3, const FMatrix &m);
- virtual void proc11(CErrorCode &errorCode, FVector &v, const FMatrix &m);
+ virtual void proc11(CErrorCode &errorCode, FVector &v, FMatrix &m);
};
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub22.cpp b/engines/titanic/star_control/star_control_sub22.cpp
index b76d96e47a..68681c0a6f 100644
--- a/engines/titanic/star_control/star_control_sub22.cpp
+++ b/engines/titanic/star_control/star_control_sub22.cpp
@@ -37,8 +37,23 @@ void CStarControlSub22::proc8(FVector &v1, FVector &v2, FMatrix &m1, FMatrix &m2
incLockCount();
}
-void CStarControlSub22::proc11(CErrorCode &errorCode, FVector &v, const FMatrix &m) {
- // TODO
+void CStarControlSub22::proc11(CErrorCode &errorCode, FVector &v, FMatrix &m) {
+ if (_sub27.get8()) {
+ decLockCount();
+ int val = _sub27.proc5(errorCode, v, m);
+ if (val == 1)
+ incLockCount();
+ if (val == 2) {
+ proc7();
+ if (_starVector)
+ _starVector->apply();
+ }
+ } else if (_size != 0.0) {
+ v._x += m._row3._x * _size;
+ v._y += m._row3._y * _size;
+ v._z += m._row3._z * _size;
+ errorCode.set();
+ }
}
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub22.h b/engines/titanic/star_control/star_control_sub22.h
index 61f60b10f1..704cfa7d6c 100644
--- a/engines/titanic/star_control/star_control_sub22.h
+++ b/engines/titanic/star_control/star_control_sub22.h
@@ -36,7 +36,7 @@ public:
virtual ~CStarControlSub22() {}
virtual void proc8(FVector &v1, FVector &v2, FMatrix &m1, FMatrix &m2);
- virtual void proc11(CErrorCode &errorCode, FVector &v, const FMatrix &m);
+ virtual void proc11(CErrorCode &errorCode, FVector &v, FMatrix &m);
};
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub23.cpp b/engines/titanic/star_control/star_control_sub23.cpp
index 4587fd3e27..ad4cb65f8a 100644
--- a/engines/titanic/star_control/star_control_sub23.cpp
+++ b/engines/titanic/star_control/star_control_sub23.cpp
@@ -37,10 +37,8 @@ CStarControlSub23::CStarControlSub23() : _row1(0.0, 1000000.0, 0.0) {
_field48 = 0;
_field4C = 0;
_field54 = 0;
- _field58 = 0;
- _field5C = 0;
- _field60 = 0;
- _field64 = 0;
+ _field58 = 0.0;
+ _field60 = 0.0;
}
void CStarControlSub23::proc2(FVector &v1, FVector &v2, FMatrix &m1, FMatrix &m2) {
@@ -52,7 +50,7 @@ void CStarControlSub23::proc2(FVector &v1, FVector &v2, FMatrix &m1, FMatrix &m2
_field58 = 0;
_field8 = 0;
_field34 = 0;
- _field5C = 1.875;
+ _field58 = 1.0;
_field40 = -1;
_field44 = -1;
_field48 = -1;
@@ -62,11 +60,10 @@ void CStarControlSub23::proc2(FVector &v1, FVector &v2, FMatrix &m1, FMatrix &m2
void CStarControlSub23::proc3(const FMatrix &m1, const FMatrix &m2) {
_row1.clear();
_row2.clear();
- _field58 = 0;
+ _field58 = 1.0;
_field24 = 0.0;
_field8 = 0;
_field34 = 0;
- _field5C = 1.875;
}
void CStarControlSub23::proc4(FVector &v1, FVector &v2, FMatrix &m) {
@@ -82,8 +79,7 @@ void CStarControlSub23::proc4(FVector &v1, FVector &v2, FMatrix &m) {
_field44 = -1;
_field48 = -1;
_field4C = -1;
- _field58 = 0;
- _field5C = 1.875;
+ _field58 = 1.0;
}
void CStarControlSub23::proc6(int val1, int val2, float val) {
diff --git a/engines/titanic/star_control/star_control_sub23.h b/engines/titanic/star_control/star_control_sub23.h
index 9e90e021a2..d8233ec91d 100644
--- a/engines/titanic/star_control/star_control_sub23.h
+++ b/engines/titanic/star_control/star_control_sub23.h
@@ -46,10 +46,8 @@ protected:
int _field4C;
Common::Array<double> _powers;
int _field54;
- int _field58;
- double _field5C;
+ double _field58;
double _field60;
- double _field64;
CStarControlSub25 _sub25;
public:
CStarControlSub23();
diff --git a/engines/titanic/star_control/star_control_sub24.cpp b/engines/titanic/star_control/star_control_sub24.cpp
index 27f29b41ca..28b69f71a7 100644
--- a/engines/titanic/star_control/star_control_sub24.cpp
+++ b/engines/titanic/star_control/star_control_sub24.cpp
@@ -26,18 +26,142 @@
namespace Titanic {
void CStarControlSub24::proc3(const FMatrix &m1, const FMatrix &m2) {
-
+ CStarControlSub23::proc3(m1, m2);
+ _sub25.fn1(m1, m2);
+ _field60 = 0.1;
+ _field58 = 0.0;
+ _field40 = _field44 = _field48 = -1;
+ _field8 = 1;
}
void CStarControlSub24::proc4(FVector &v1, FVector &v2, FMatrix &m) {
CStarControlSub23::proc4(v1, v2, m);
- // TODO
+ if (_field24 > 8000.0) {
+ _field8 = 1;
+ _field34 = 1;
+ proc6(120, 4, _field24 - 8000.0);
+ }
+
+ FVector row3 = m._row3;
+ double mult = _row3._x * row3._x + _row3._y * row3._y+ _row3._z * row3._z;
+ _field58 = 1.0;
+
+ bool flag = false;
+ if (mult < 1.0) {
+ if (mult >= 1.0 - 1.0e-10)
+ flag = true;
+ } else {
+ if (mult <= 1.0 + 1.0e-10)
+ flag = true;
+ }
+
+ if (!flag) {
+ const FVector *tv;
+ FVector tempV1, tempV2;
+ FVector::addAndNormalize(tempV1, row3, _row3);
+ tv = FVector::addAndNormalize(tempV2, row3, tempV1);
+ tempV1 = *tv;
+
+ tv = FVector::addAndNormalize(tempV2, row3, tempV1);
+ tempV1 = *tv;
+
+ tv = FVector::addAndNormalize(tempV2, row3, tempV1);
+ tempV1 = *tv;
+
+ FMatrix m1;
+ m1.fn1(tempV1);
+ _sub25.fn1(m, m1);
+
+ _field58 = 0.0;
+ _field60 = 0.1;
+ _field8 = 1;
+ }
}
-int CStarControlSub24::proc5(CErrorCode &errorCode, FVector &v, const FMatrix &m) {
- // TODO
- return 0;
+int CStarControlSub24::proc5(CErrorCode &errorCode, FVector &v, FMatrix &m) {
+ FVector v1, v2, v3, v4;
+ const FVector *tv;
+
+ if (_field8)
+ return 0;
+
+ if (_field58 < 1.0) {
+ _sub25.fn2(_field60 + _field58, m);
+ errorCode.set();
+ return 1;
+ }
+
+ if (!_field34) {
+ _field8 = 0;
+ return 2;
+ }
+
+ v2 = m._row3;
+ v3 = _row2 - v;
+ v3.normalize();
+
+ double val = m._row3._x * v3._x + m._row3._y * v3._y + m._row3._z * v3._z;
+ bool flag = false;
+ if (val > 1.0) {
+ if (val >= 1.0 - 1.0e-10)
+ flag = true;
+ } else {
+ if (val <= 1.0 + 1.0e-10)
+ flag = true;
+ }
+
+ if (!flag) {
+ v2.addAndNormalize(v1, v2, v3);
+ tv = v2.addAndNormalize(v4, v2, v1);
+ v1 = *tv;
+ tv = v2.addAndNormalize(v4, v2, v1);
+ v1 = *tv;
+ tv = v2.addAndNormalize(v4, v2, v1);
+ v1 = *tv;
+
+ m.fn1(v1);
+ v2 = v1;
+ }
+
+ if (_field40 >= 0) {
+ double powVal = _powers[_field40];
+ v1 = v2 * powVal;
+ v += v1;
+
+ --_field40;
+ errorCode.set();
+ return 1;
+ }
+
+ if (_field44 > 0) {
+ v1._z = v2._z * _field38;
+ v1._x = v2._x * _field38;
+ v._x = v1._x + v._x;
+ v._y = v2._y * _field38 + v._y;
+ v._z = v1._z + v._z;
+
+ --_field44;
+ errorCode.set();
+ return 1;
+ }
+
+ if (_field48 >= 0) {
+ double powVal = _powers[31 - _field48];
+ v1._y = v2._y * powVal;
+ v1._z = v2._z * powVal;
+ v1._x = v2._x * powVal;
+ v._y = v1._y + v._y;
+ v._z = v1._z + v._z;
+ v._x = v._x + v1._x;
+
+ --_field48;
+ errorCode.set();
+ return 1;
+ }
+
+ _field8 = 0;
+ return 2;
}
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub24.h b/engines/titanic/star_control/star_control_sub24.h
index 34b9cf4eac..16f53610ec 100644
--- a/engines/titanic/star_control/star_control_sub24.h
+++ b/engines/titanic/star_control/star_control_sub24.h
@@ -33,7 +33,7 @@ public:
virtual void proc3(const FMatrix &m1, const FMatrix &m2);
virtual void proc4(FVector &v1, FVector &v2, FMatrix &m);
- virtual int proc5(CErrorCode &errorCode, FVector &v, const FMatrix &m);
+ virtual int proc5(CErrorCode &errorCode, FVector &v, FMatrix &m);
};
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub25.cpp b/engines/titanic/star_control/star_control_sub25.cpp
index 73c72e6a77..a8e13473f2 100644
--- a/engines/titanic/star_control/star_control_sub25.cpp
+++ b/engines/titanic/star_control/star_control_sub25.cpp
@@ -21,7 +21,7 @@
*/
#include "titanic/star_control/star_control_sub25.h"
-#include "common/textconsole.h"
+#include "titanic/star_control/dmatrix.h"
namespace Titanic {
@@ -31,4 +31,19 @@ void CStarControlSub25::fn1(const FMatrix &m1, const FMatrix &m2) {
}
+void CStarControlSub25::fn2(double val, FMatrix &m) {
+ if (val < 0.0) {
+ m = _matrix1;
+ } else if (val > 1.0) {
+ m = _matrix2;
+ } else {
+ CStarControlSub26 sub26;
+ sub26.fn5(val, &_sub2, &sub26);
+
+ DMatrix m1;
+ m1.fn3(&sub26);
+ m = m1;
+ }
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub25.h b/engines/titanic/star_control/star_control_sub25.h
index 85692cf62d..cb7d61023e 100644
--- a/engines/titanic/star_control/star_control_sub25.h
+++ b/engines/titanic/star_control/star_control_sub25.h
@@ -36,6 +36,7 @@ public:
CStarControlSub26 _sub2;
public:
void fn1(const FMatrix &m1, const FMatrix &m2);
+ void fn2(double val, FMatrix &m);
};
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub26.cpp b/engines/titanic/star_control/star_control_sub26.cpp
index 546a3e9fae..91dd1576f9 100644
--- a/engines/titanic/star_control/star_control_sub26.cpp
+++ b/engines/titanic/star_control/star_control_sub26.cpp
@@ -42,4 +42,8 @@ void CStarControlSub26::copyFrom(const CStarControlSub26 *src) {
_sub = src->_sub;
}
+void CStarControlSub26::fn5(double val, CStarControlSub26 *s1, CStarControlSub26 *s2) {
+ // TODO
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub26.h b/engines/titanic/star_control/star_control_sub26.h
index 9023da906c..670007efa8 100644
--- a/engines/titanic/star_control/star_control_sub26.h
+++ b/engines/titanic/star_control/star_control_sub26.h
@@ -50,7 +50,7 @@ public:
void copyFrom(const CStarControlSub26 *src);
double fn1() const;
-
+ void fn5(double val, CStarControlSub26 *s1, CStarControlSub26 *s2);
};
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub27.cpp b/engines/titanic/star_control/star_control_sub27.cpp
index 706e947a05..e9559b250b 100644
--- a/engines/titanic/star_control/star_control_sub27.cpp
+++ b/engines/titanic/star_control/star_control_sub27.cpp
@@ -37,12 +37,10 @@ void CStarControlSub27::proc2(FVector &v1, FVector &v2, FMatrix &m1, FMatrix &m2
if (m1 != m2) {
_sub25.fn1(m1, m2);
- _field58 = 0;
- _field5C = 0.0;
+ _field58 = 0.0;
if (_field4C == 0) {
- _field60 = -1.5881868e-23;
- _field64 = 1.4499999;
+ _field60 = 0.1;
_field8 = 1;
} else {
_field60 = 1.0 / (double)v24;
@@ -51,7 +49,7 @@ void CStarControlSub27::proc2(FVector &v1, FVector &v2, FMatrix &m1, FMatrix &m2
}
}
-int CStarControlSub27::proc5(CErrorCode &errorCode, FVector &v, const FMatrix &m) {
+int CStarControlSub27::proc5(CErrorCode &errorCode, FVector &v, FMatrix &m) {
// TODO
return 0;
}
diff --git a/engines/titanic/star_control/star_control_sub27.h b/engines/titanic/star_control/star_control_sub27.h
index 801591294e..f8aa3d6ce7 100644
--- a/engines/titanic/star_control/star_control_sub27.h
+++ b/engines/titanic/star_control/star_control_sub27.h
@@ -32,7 +32,7 @@ public:
virtual ~CStarControlSub27() {}
virtual void proc2(FVector &v1, FVector &v2, FMatrix &m1, FMatrix &m2);
- virtual int proc5(CErrorCode &errorCode, FVector &v, const FMatrix &m);
+ virtual int proc5(CErrorCode &errorCode, FVector &v, FMatrix &m);
};
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub5.cpp b/engines/titanic/star_control/star_control_sub5.cpp
index 4ca22ff922..8c332975c6 100644
--- a/engines/titanic/star_control/star_control_sub5.cpp
+++ b/engines/titanic/star_control/star_control_sub5.cpp
@@ -26,6 +26,8 @@
namespace Titanic {
+#define MKTAG_BE(a3,a2,a1,a0) ((uint32)((a3) | ((a2) << 8) | ((a1) << 16) | ((a0) << 24)))
+
void CStarControlSub5::SubEntry::clear() {
_data1.clear();
_data2.clear();
@@ -37,7 +39,7 @@ bool CStarControlSub5::SineTable::setup() {
if (_data.empty()) {
_data.resize(1024);
for (int idx = 0; idx < 1024; ++idx)
- _data[idx] = sin((double)idx * 6.283185307179586 * 0.001953125);
+ _data[idx] = sin((double)idx * 2 * M_PI / 512.0);
}
return true;
@@ -63,7 +65,7 @@ bool CStarControlSub5::setup() {
bool CStarControlSub5::setup2(int val1, int val2) {
// TODO: Original set an explicit random seed here. Could be
// problematic if following random values need to be deterministic
- const double FACTOR = 3.1415927 * 0.0055555557;
+ const double FACTOR = 2 * M_PI / 360.0;
const int VALUES1[] = { 0x800, 0xC00, 0x1000, 0x1400, 0x1800 };
const int VALUES2[] = {
0xF95BCD, 0xA505A0, 0xFFAD43, 0x98F4EB, 0xF3EFA5, 0,
@@ -76,9 +78,9 @@ bool CStarControlSub5::setup2(int val1, int val2) {
for (int idx = 0; idx < 256; ++idx) {
if (idx == 0) {
e->_field0 = 0x4C8;
- e->_field4 = 0x40;
- e->_field5 = 0x40;
- e->_field6 = 0x40;
+ e->_pixel1 = 0x40;
+ e->_pixel2 = 0x40;
+ e->_pixel3 = 0x40;
e->_field8 = g_vm->getRandomNumber(3) + 3;
e->_fieldC = g_vm->getRandomNumber(255);
e->_field10 = FACTOR * 7.0;
@@ -86,9 +88,9 @@ bool CStarControlSub5::setup2(int val1, int val2) {
++e;
e->_field0 = 0x574;
- e->_field4 = 0x7f;
- e->_field5 = 0;
- e->_field6 = 0;
+ e->_pixel1 = 0x7f;
+ e->_pixel2 = 0;
+ e->_pixel3 = 0;
e->_field8 = g_vm->getRandomNumber(3) + 3;
e->_fieldC = g_vm->getRandomNumber(255);
e->_field10 = FACTOR * 3.0;
@@ -96,9 +98,9 @@ bool CStarControlSub5::setup2(int val1, int val2) {
++e;
e->_field0 = 0x603;
- e->_field4 = 0;
- e->_field5 = 0;
- e->_field6 = 0xff;
+ e->_pixel1 = 0;
+ e->_pixel2 = 0;
+ e->_pixel3 = 0xff;
e->_field8 = g_vm->getRandomNumber(3) + 3;
e->_fieldC = g_vm->getRandomNumber(255);
e->_field10 = 0;
@@ -106,9 +108,9 @@ bool CStarControlSub5::setup2(int val1, int val2) {
++e;
e->_field0 = 0x712;
- e->_field4 = 0xff;
- e->_field5 = 0;
- e->_field6 = 0;
+ e->_pixel1 = 0xff;
+ e->_pixel2 = 0;
+ e->_pixel3 = 0;
e->_field8 = g_vm->getRandomNumber(3) + 3;
e->_fieldC = g_vm->getRandomNumber(255);
e->_field10 = FACTOR * 2.0;
@@ -116,9 +118,9 @@ bool CStarControlSub5::setup2(int val1, int val2) {
++e;
e->_field0 = 0xe7f;
- e->_field4 = 0xe6;
- e->_field5 = 0xbe;
- e->_field6 = 0;
+ e->_pixel1 = 0xe6;
+ e->_pixel2 = 0xbe;
+ e->_pixel3 = 0;
e->_field8 = g_vm->getRandomNumber(3) + 3;
e->_fieldC = g_vm->getRandomNumber(255);
e->_field10 = FACTOR * 1.0;
@@ -126,9 +128,9 @@ bool CStarControlSub5::setup2(int val1, int val2) {
++e;
e->_field0 = 0x173f;
- e->_field4 = 0xf0;
- e->_field5 = 0xf0;
- e->_field6 = 0xe6;
+ e->_pixel1 = 0xf0;
+ e->_pixel2 = 0xf0;
+ e->_pixel3 = 0xe6;
e->_field8 = g_vm->getRandomNumber(3) + 3;
e->_fieldC = g_vm->getRandomNumber(255);
e->_field10 = FACTOR * 3.0;
@@ -136,9 +138,9 @@ bool CStarControlSub5::setup2(int val1, int val2) {
++e;
e->_field0 = 0x2ab8;
- e->_field4 = 0x28;
- e->_field5 = 0x32;
- e->_field6 = 0x28;
+ e->_pixel1 = 0x28;
+ e->_pixel2 = 0x32;
+ e->_pixel3 = 0x28;
e->_field8 = g_vm->getRandomNumber(3) + 3;
e->_fieldC = g_vm->getRandomNumber(255);
e->_field10 = FACTOR * 1.0;
@@ -146,9 +148,9 @@ bool CStarControlSub5::setup2(int val1, int val2) {
++e;
e->_field0 = 0x40ac;
- e->_field4 = 0x0;
- e->_field5 = 0xbe;
- e->_field6 = 0xf0;
+ e->_pixel1 = 0x0;
+ e->_pixel2 = 0xbe;
+ e->_pixel3 = 0xf0;
e->_field8 = g_vm->getRandomNumber(3) + 3;
e->_fieldC = g_vm->getRandomNumber(255);
e->_field10 = FACTOR * 2.0;
@@ -156,27 +158,27 @@ bool CStarControlSub5::setup2(int val1, int val2) {
++e;
e->_field0 = 0x539c;
- e->_field4 = 0x20;
- e->_field5 = 0x20;
- e->_field6 = 0x20;
+ e->_pixel1 = 0x20;
+ e->_pixel2 = 0x20;
+ e->_pixel3 = 0x20;
e->_field8 = g_vm->getRandomNumber(3) + 3;
e->_fieldC = g_vm->getRandomNumber(255);
e->_field10 = FACTOR * 17.0;
- e->_field14 = 0.00390625;
+ e->_field14 = 1 / 256.0;
} else {
for (int ctr = 0; ctr < 5; ++ctr) {
e->_field0 = static_cast<int>(g_vm->getRandomFloat() * 1350.0
- 675.0) + VALUES1[idx];
int val = VALUES2[g_vm->getRandomNumber(15)];
- e->_field4 = val & 0xff;
- e->_field5 = (val >> 8) & 0xff;
- e->_field6 = (val >> 16) & 0xff;
+ e->_pixel1 = val & 0xff;
+ e->_pixel2 = (val >> 8) & 0xff;
+ e->_pixel3 = (val >> 16) & 0xff;
e->_field8 = g_vm->getRandomNumber(3) + 3;
e->_fieldC = g_vm->getRandomNumber(255);
e->_field10 = FACTOR * (double)g_vm->getRandomNumber(15);
e->_field14 = ((double)g_vm->getRandomNumber(0xfffffffe)
- * 50.0 * 0.000015259022) * 0.00390625;
+ * 50.0 / 65536.0) / 256.0;
}
}
}
@@ -194,13 +196,23 @@ void CStarControlSub5::proc2(CStarControlSub6 *sub6, FVector *vector, double v1,
const int VALUES[] = { 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4 };
double val1 = sub12->proc25();
int val2 = sub12->proc27();
+ if (!_flag)
+ return;
+
+ int f1, f3, size2, size1;
+ double f2, f4, f5, f6, f7, f8, f9;
+ double f10, f11, f12, f13, f14, f15, f16, f17, f18, f19;
+ double f20, f21, f22, f23, f24, f25, f26, f27, f28;
+ double f34, f35, f36, f37, f38, f39, f40;
+ double f41, f42, f43, f44, f45, f46;
+ FVector tempV;
if (v3 >= 6.0e9) {
int count, start;
if (vector->_x != 0.0 && (vector->_y != 0.0 || vector->_z != 0.0)) {
- // TODO: Non-sensical randSeed((int)vector->_x);
+ // WORKAROUND: Ignoring non-sensical randSeed((int)vector->_x);
count = VALUES[g_vm->getRandomNumber(15)];
- start = g_vm->getRandomNumber(255);
+ start = 5 * g_vm->getRandomNumber(255);
} else {
count = 9;
start = 0;
@@ -208,45 +220,280 @@ void CStarControlSub5::proc2(CStarControlSub6 *sub6, FVector *vector, double v1,
Entry *entryP = &_entries[start];
for (; count > 0; --count, ++entryP) {
- //eax=sineIndex1, ecx=sineIndex2,
- int sineIndex1 = (entryP->_field8 * _multiplier) & 0x1ff;
- int sineIndex2 = (entryP->_fieldC * _multiplier + entryP->_fieldC) & 0x1ff;
-
- double t1 = _sineTable[sineIndex2];
- double t2 = sin(_sineTable[sineIndex1] * entryP->_field10);
- double t3 = cos(_sineTable[sineIndex1] * entryP->_field10);
- double t4 = _sineTable[sineIndex2 + 512];
- double t5 = t3 * t4;
- t3 = t3 * t1;
- double t6 = entryP->_field14 * t5;
- double t7 = t2 * entryP->_field14;
- double t8 = entryP->_field14 * t3;
- double t9 = -(t2 * t4 * entryP->_field14);
- double t10 = t3 * entryP->_field14;
- double t11 = -(t2 * t1 * entryP->_field14);
- t4 = -(t1 * entryP->_field14);
- t1 = t4 * entryP->_field14;
-
- _sub1._row1._x = t6;
- _sub1._row1._y = t2 * entryP->_field14;
- _sub1._row1._z = entryP->_field14 * t3;
- _sub1._row2._x = -(t2 * t4 * entryP->_field14);
- _sub1._row2._y = t3 * entryP->_field14;
- _sub1._row2._z = -(t2 * t1 * entryP->_field14);
- _sub1._row3._x = -(t1 * entryP->_field14);
- _sub1._row3._z = t4 * entryP->_field14;
-
- double t12 = entryP->_field0;
- _sub1._vector._x = t12 * t5 + vector->_x;
- _sub1._vector._y = t12 * t2 + vector->_y;
- _sub1._vector._z = t12 * t3 + vector->_z;
-
- // TODO
- warning("TODO: %f %f %f %f %f %f %d", t7, t8, t9, t10, t11, val1, val2);
+ f1 = _multiplier * entryP->_field8;
+ f2 = entryP->_field14;
+ f3 = (f1 + entryP->_fieldC) & 0x1FF;
+ f4 = _sineTable[f1 & 0x1FF] * entryP->_field10;
+ f5 = _sineTable[f3];
+ f6 = cos(f4);
+ f7 = sin(f4);
+ f8 = _sineTable[f3 + 128];
+ f9 = f7;
+ f10 = f6 * f8;
+ f11 = f6;
+ f12 = f6 * f5;
+ f13 = f2 * f10;
+ f14 = f8 * f2;
+ f15 = f9 * f2;
+ f16 = f2 * f12;
+ f17 = -(f7 * f8 * f2);
+ f18 = f11 * f2;
+ f19 = -(f9 * f5 * f2);
+ f20 = -(f5 * f2);
+ f21 = f14;
+ _sub1._row1._x = f13;
+ _sub1._row1._y = f15;
+ _sub1._row1._z = f16;
+ _sub1._row2._x = f17;
+ _sub1._row2._y = f18;
+ _sub1._row2._z = f19;
+ _sub1._row3._x = f20;
+ _sub1._row3._z = f14;
+
+ f22 = (double)entryP->_field0;
+ _sub1._vector._x = f22 * f10 + vector->_x;
+ _sub1._vector._y = f9 * f22 + vector->_y;
+ _sub1._vector._z = f22 * f12 + vector->_z;
+ _sub2._row1._x = sub6->_row1._x * f13 + f16 * sub6->_row3._x + f15 * sub6->_row2._x;
+ _sub2._row1._y = f15 * sub6->_row2._y + f16 * sub6->_row3._y + f13 * sub6->_row1._y;
+ _sub2._row1._z = f16 * sub6->_row3._z + f13 * sub6->_row1._z + f15 * sub6->_row2._z;
+ _sub2._row2._x = sub6->_row1._x * f17 + f19 * sub6->_row3._x + f18 * sub6->_row2._x;
+ _sub2._row2._y = f18 * sub6->_row2._y + f17 * sub6->_row1._y + f19 * sub6->_row3._y;
+ _sub2._row2._z = f18 * sub6->_row2._z + f19 * sub6->_row3._z + f17 * sub6->_row1._z;
+ _sub2._row3._x = sub6->_row1._x * f20 + f21 * sub6->_row3._x;
+ _sub2._row3._y = f20 * sub6->_row1._y + f21 * sub6->_row3._y;
+ _sub2._row3._z = f20 * sub6->_row1._z + f21 * sub6->_row3._z;
+
+ f23 = _sub1._vector._y;
+ f24 = _sub1._vector._z;
+ f25 = _sub1._vector._x;
+ f26 = _sub1._vector._z;
+ f27 = _sub1._vector._x;
+
+ f28 = _sub1._vector._y;
+ _sub2._vector._x = sub6->_row1._x * _sub1._vector._x
+ + sub6->_row3._x * _sub1._vector._z
+ + sub6->_row2._x * f28
+ + sub6->_vector._x;
+ _sub2._vector._y = f23 * sub6->_row2._y
+ + f24 * sub6->_row3._y
+ + f25 * sub6->_row1._y
+ + sub6->_vector._y;
+ _sub2._vector._z = f26 * sub6->_row3._z
+ + f27 * sub6->_row1._z
+ + f28 * sub6->_row2._z
+ + sub6->_vector._z;
+
+ size2 = (int)_array[1]._data2.size();
+ size1 = (int)_array[1]._data1.size();
+
+ if (size2 > 0) {
+ for (int ctr2 = 0; ctr2 < size2; ++ctr2) {
+ FVector &currVector = _array[1]._data2[ctr2];
+ GridEntry &gridEntry = _grid[ctr2];
+
+ f34 = currVector._x;
+ f35 = currVector._y;
+ f36 = f35 * _sub2._row2._x;
+ f37 = currVector._z;
+ f38 = f37 * _sub2._row3._x + f36;
+ f39 = f38 + f34 * _sub2._row1._x;
+ f40 = f39 + _sub2._vector._x;
+
+ gridEntry._x = f40;
+ gridEntry._y = f37 * _sub2._row3._y
+ + f35 * _sub2._row2._y
+ + f34 * _sub2._row1._y
+ + _sub2._vector._y;
+ gridEntry._z = f37 * _sub2._row3._z
+ + f35 * _sub2._row2._z
+ + f34 * _sub2._row1._z
+ + _sub2._vector._z;
+ }
+ }
+
+ if (val2 <= 0) {
+ surfaceArea->setMode(SA_NONE);
+ surfaceArea->_pixel = MKTAG_BE(entryP->_pixel1, entryP->_pixel2,
+ entryP->_pixel3, 0);
+ surfaceArea->setColorFromPixel();
+
+ for (int ctr2 = 0; ctr2 < size2; ++ctr2) {
+ GridEntry &gridEntry = _grid[ctr2];
+ sub12->proc28(2, gridEntry, tempV);
+ gridEntry._position._x = tempV._x;
+ gridEntry._position._y = tempV._y + v2;
+ }
+
+ for (int ctr2 = 0; ctr2 < size1; ++ctr2) {
+ Data1 &d1 = _array[1]._data1[ctr2];
+ GridEntry &grid1 = _grid[d1._index1];
+ GridEntry &grid2 = _grid[d1._index2];
+
+ if (grid1._z > val1 && grid2._z > val1) {
+ surfaceArea->fn1(FRect(grid1._position._x, grid1._position._y,
+ grid2._position._x, grid2._position._y));
+ }
+ }
+ } else {
+ surfaceArea->setMode(SA_NONE);
+ surfaceArea->_pixel = entryP->_pixel1;
+ surfaceArea->setColorFromPixel();
+
+ for (int ctr2 = 0; ctr2 < size2; ++ctr2) {
+ GridEntry &gridEntry = _grid[ctr2];
+ sub12->proc28(0, gridEntry, tempV);
+ gridEntry._position._x = tempV._x + v1;
+ gridEntry._position._y = tempV._y + v2;
+ }
+
+ for (int ctr2 = 0; ctr2 < size1; ++ctr2) {
+ Data1 &d1 = _array[1]._data1[ctr2];
+ GridEntry &grid1 = _grid[d1._index1];
+ GridEntry &grid2 = _grid[d1._index2];
+
+ if (grid1._z > val1 && grid2._z > val1) {
+ surfaceArea->fn1(FRect(grid1._position._x, grid1._position._y,
+ grid2._position._x, grid2._position._y));
+ }
+ }
+
+ surfaceArea->_pixel = entryP->_pixel3;
+ surfaceArea->setColorFromPixel();
+ surfaceArea->setMode(SA_MODE2);
+
+ for (int ctr2 = 0; ctr2 < size2; ++ctr2) {
+ GridEntry &gridEntry = _grid[ctr2];
+ sub12->proc28(1, gridEntry, tempV);
+ gridEntry._position._x = tempV._x + v1;
+ gridEntry._position._y = tempV._y + v2;
+ }
+
+ for (int ctr2 = 0; ctr2 < size1; ++ctr2) {
+ Data1 &d1 = _array[1]._data1[ctr2];
+ GridEntry &grid1 = _grid[d1._index1];
+ GridEntry &grid2 = _grid[d1._index2];
+
+ if (grid1._z > val1 && grid2._z > val1) {
+ surfaceArea->fn1(FRect(grid1._position._x, grid1._position._y,
+ grid2._position._x, grid2._position._y));
+ }
+ }
+ }
+ }
+ }
+
+ uint pixel1 = 0x81EEF5, pixel2 = 0xF5, pixel3 = 0x810000;
+ int arrIndex = 0;
+
+ if (v3 >= 200000000.0) {
+ if (v3 >= 900000000.0) {
+ if (v3 >= 6000000000.0) {
+ arrIndex = 3;
+ if (v3 >= 1.0e10)
+ arrIndex = 4;
+ } else {
+ arrIndex = 2;
+ }
+ } else {
+ arrIndex = 1;
}
+ } else {
+ arrIndex = 0;
}
- // TODO
+ SubEntry &entry = _array[arrIndex];
+
+ for (uint ctr = 0; ctr < entry._data2.size(); ++ctr) {
+ GridEntry &gridEntry = _grid[ctr];
+ const FVector &d2v = entry._data2[ctr];
+ FVector newV = d2v + *vector;
+
+ f41 = sub6->_row1._x;
+ f42 = sub6->_row3._x;
+ f43 = sub6->_row2._x;
+ f44 = f43 * newV._y;
+ f45 = f41 * newV._x + f42 * newV._z + f44;
+ f46 = f45 + sub6->_vector._x;
+
+ gridEntry._x = f46;
+ gridEntry._y = newV._y * sub6->_row2._y
+ + newV._z * sub6->_row3._y
+ + newV._x * sub6->_row1._y
+ + sub6->_vector._y;
+ gridEntry._z = newV._z * sub6->_row3._z
+ + newV._y * sub6->_row2._z
+ + newV._x * sub6->_row1._z
+ + sub6->_vector._z;
+ }
+
+ if (val2 <= 0) {
+ surfaceArea->setMode(SA_NONE);
+ surfaceArea->_pixel = pixel1;
+ surfaceArea->setColorFromPixel();
+
+ for (uint ctr = 0; ctr < entry._data2.size(); ++ctr) {
+ GridEntry &gridEntry = _grid[ctr];
+ sub12->proc28(2, gridEntry, tempV);
+ gridEntry._position._x = tempV._x + v1;
+ gridEntry._position._y = tempV._y + v2;
+ }
+
+ for (uint ctr = 0; ctr < entry._data1.size(); ++ctr) {
+ Data1 &d1 = entry._data1[ctr];
+ GridEntry &grid1 = _grid[d1._index1];
+ GridEntry &grid2 = _grid[d1._index2];
+
+ if (grid2._z > val1 && grid1._z > val1) {
+ surfaceArea->fn1(FRect(grid1._position._x, grid1._position._y,
+ grid2._position._x, grid2._position._y));
+ }
+ }
+ } else {
+ surfaceArea->setMode(SA_NONE);
+ surfaceArea->_pixel = pixel2;
+ surfaceArea->setColorFromPixel();
+
+ for (uint ctr = 0; ctr < entry._data2.size(); ++ctr) {
+ GridEntry &gridEntry = _grid[ctr];
+ sub12->proc28(2, gridEntry, tempV);
+ gridEntry._position._x = tempV._x + v1;
+ gridEntry._position._y = tempV._y + v2;
+ }
+
+ for (uint ctr = 0; ctr < entry._data1.size(); ++ctr) {
+ Data1 &d1 = entry._data1[ctr];
+ GridEntry &grid1 = _grid[d1._index1];
+ GridEntry &grid2 = _grid[d1._index2];
+
+ if (grid2._z > val1 && grid1._z > val1) {
+ surfaceArea->fn1(FRect(grid1._position._x, grid1._position._y,
+ grid2._position._x, grid2._position._y));
+ }
+ }
+
+ surfaceArea->_pixel = pixel3;
+ surfaceArea->setColorFromPixel();
+ surfaceArea->setMode(SA_MODE2);
+
+ for (uint ctr = 0; ctr < entry._data2.size(); ++ctr) {
+ GridEntry &gridEntry = _grid[ctr];
+ sub12->proc28(2, gridEntry, tempV);
+ gridEntry._position._x = tempV._x + v1;
+ gridEntry._position._y = tempV._y + v2;
+ }
+
+ for (uint ctr = 0; ctr < entry._data1.size(); ++ctr) {
+ Data1 &d1 = entry._data1[ctr];
+ GridEntry &grid1 = _grid[d1._index1];
+ GridEntry &grid2 = _grid[d1._index2];
+
+ if (grid2._z > val1 && grid1._z > val1) {
+ surfaceArea->fn1(FRect(grid1._position._x, grid1._position._y,
+ grid2._position._x, grid2._position._y));
+ }
+ }
+ }
}
void CStarControlSub5::proc3(CErrorCode *errorCode) {
@@ -259,40 +506,85 @@ void CStarControlSub5::fn1() {
}
bool CStarControlSub5::setupEntry(int width, int height, int index, double val) {
- /*
if (width < 2 || height < 3)
return false;
SubEntry &entry = _array[index];
entry.clear();
- int height2 = height - 2;
- int height1 = height - 1;
- entry._data1.resize((2 * height - 3) * width);
- entry._data2.resize(width * height2 + 2);
- entry._data2[0] = FVector(0.0, val, 0.0);
+ const double FACTOR = 2 * M_PI / 360.0;
+ int d1Count, d2Count, size3, height1;
+ int ctr, ctr2, idx, offset, f11;
+ double vx, vy, f5, f6, f7, f8, f9, f10;
+
+ d1Count = width * (2 * height - 3);
+ d2Count = (height - 2) * width + 2;
+ entry._data1.resize(d1Count);
+ entry._data2.resize(d2Count);
+
+ height1 = height - 1;
+ entry._data2[0]._y = val;
+
+ vy = 180.0 / (double)height1;
+ vx = 360.0 / (double)width;
+
+ for (ctr = height - 2, idx = 0; ctr > 0; --ctr, vy *= 2) {
+ f5 = 0.0;
+ f6 = cos(vy * FACTOR);
+ f7 = sin(vy * FACTOR);
- index = 1;
- double vy = 180.0 / (double)height1;
- double vx = 360.0 / (double)width;
- const double FACTOR = 3.1415927 * 0.0055555557;
+ if (width > 0) {
+ f8 = f6 * val;
- if (height1 > 1) {
- double yAmount = vy;
- int width12 = width * 12;
- for (int yCtr = height1 - 1; yCtr > 0; --yCtr, yAmount += vy) {
- double sineVal = sin(yAmount * FACTOR);
+ for (int xp = width; xp > 0; --xp, ++idx, f5 += vx) {
+ f9 = f5 * FACTOR;
+ f10 = cos(f9) * f7 * val;
+ FVector &tempV = entry._data2[idx];
+ tempV._x = sin(f9) * f7 * val;
+ tempV._y = f8;
+ tempV._z = f10;
+ }
+ }
+ }
+ entry._data2[idx] = FVector(0.0, -1.0, 0.0);
+
+ size3 = width * (height - 3) + 1;
+ offset = 0;
+ Data1 *data1P = &entry._data1[0];
+ for (ctr = 0; ctr < width; ++ctr, ++size3) {
+ data1P->_index1 = 0;
+ data1P->_index2 = size3 - width * (height - 3);
+ ++data1P;
+
+ data1P->_index1 = d2Count - 1;
+ data1P->_index2 = size3;
+ ++data1P;
+ }
- | 0.0 * FACTOR |
- | cos(yAmount * FACTOR) * val |
- | 0.0 |
- |yAmount|
+ f11 = 1;
+ for (ctr = 1; ctr < height1; ++ctr, f11 += width) {
+ data1P = &entry._data1[offset];
+
+ for (ctr2 = 0; ctr2 < width; ++ctr2) {
+ data1P->_index1 = ctr2 + f11;
+ if (ctr2 == width - 1)
+ data1P->_index2 = f11;
+ else
+ data1P->_index2 = ctr2 + f11 + 1;
+
+ ++offset;
+ ++data1P;
+
+ if (ctr < height - 2) {
+ data1P->_index1 = ctr2 + f11;
+ ++offset;
+ data1P->_index2 = width + ctr2 + f11;
+ ++data1P;
+ }
}
}
- // TODO
- */
return true;
}
diff --git a/engines/titanic/star_control/star_control_sub5.h b/engines/titanic/star_control/star_control_sub5.h
index 32094f5227..b5e5bb1b6a 100644
--- a/engines/titanic/star_control/star_control_sub5.h
+++ b/engines/titanic/star_control/star_control_sub5.h
@@ -33,8 +33,14 @@ namespace Titanic {
class CStarControlSub12;
class CStarControlSub5 {
+ struct Data1 {
+ int _index1;
+ int _index2;
+ Data1() : _index1(0), _index2(0) {}
+ };
+
struct SubEntry {
- Common::Array<FPoint> _data1;
+ Common::Array<Data1> _data1;
Common::Array<FVector> _data2;
~SubEntry() { clear(); }
@@ -46,28 +52,23 @@ class CStarControlSub5 {
struct Entry {
int _field0;
- byte _field4;
- byte _field5;
- byte _field6;
+ byte _pixel1;
+ byte _pixel2;
+ byte _pixel3;
int _field8;
int _fieldC;
double _field10;
double _field14;
- Entry() : _field0(0), _field4(0), _field5(0), _field6(0), _field8(0),
+ Entry() : _field0(0), _pixel1(0), _pixel2(0), _pixel3(0), _field8(0),
_fieldC(0), _field10(0), _field14(0) {}
};
- struct GridEntry {
- int _field0;
- int _field4;
- int _field8;
- int _fieldC;
- int _field10;
+ struct GridEntry : public FVector {
+ FPoint _position;
int _field14;
- GridEntry() : _field0(0), _field4(0), _field8(0), _fieldC(0),
- _field10(0), _field14(0) {}
+ GridEntry() : FVector(), _field14(0) {}
};
/**
diff --git a/engines/titanic/star_control/star_control_sub6.cpp b/engines/titanic/star_control/star_control_sub6.cpp
index e45d6d2c57..0ced3df9fe 100644
--- a/engines/titanic/star_control/star_control_sub6.cpp
+++ b/engines/titanic/star_control/star_control_sub6.cpp
@@ -38,6 +38,48 @@ CStarControlSub6::CStarControlSub6(const CStarControlSub6 *src) {
copyFrom(src);
}
+CStarControlSub6::CStarControlSub6(const CStarControlSub6 *s1, const CStarControlSub6 *s2) {
+ _row1._x = s2->_row1._x * s1->_row1._x
+ + s1->_row1._z * s2->_row3._x
+ + s1->_row1._y * s2->_row2._x;
+ _row1._y = s1->_row1._x * s2->_row1._y
+ + s2->_row3._y * s1->_row1._z
+ + s2->_row2._y * s1->_row1._y;
+ _row1._z = s1->_row1._x * s2->_row1._z
+ + s2->_row3._z * s1->_row1._z
+ + s2->_row2._z * s1->_row1._y;
+ _row2._x = s2->_row1._x * s1->_row2._x
+ + s1->_row2._y * s2->_row2._x
+ + s1->_row2._z * s2->_row3._x;
+ _row2._y = s1->_row2._y * s2->_row2._y
+ + s1->_row2._z * s2->_row3._y
+ + s2->_row1._y * s1->_row2._x;
+ _row2._z = s2->_row1._z * s1->_row2._x
+ + s1->_row2._y * s2->_row2._z
+ + s1->_row2._z * s2->_row3._z;
+ _row3._x = s2->_row1._x * s1->_row3._x
+ + s1->_row3._y * s2->_row2._x
+ + s1->_row3._z * s2->_row3._x;
+ _row3._y = s1->_row3._z * s2->_row3._y
+ + s1->_row3._y * s2->_row2._y
+ + s2->_row1._y * s1->_row3._x;
+ _row3._z = s2->_row3._z * s1->_row3._z
+ + s2->_row2._z * s1->_row3._y
+ + s2->_row1._z * s1->_row3._x;
+ _vector._x = s2->_row1._x * s1->_vector._x
+ + s1->_vector._y * s2->_row2._x
+ + s1->_vector._z * s2->_row3._x
+ + s2->_vector._x;
+ _vector._y = s1->_vector._z * s2->_row3._y
+ + s1->_vector._y * s2->_row2._y
+ + s1->_vector._x * s2->_row1._y
+ + s2->_vector._y;
+ _vector._z = s1->_vector._y * s2->_row2._z
+ + s1->_vector._z * s2->_row3._z
+ + s1->_vector._x * s2->_row1._z
+ + s2->_vector._z;
+}
+
void CStarControlSub6::init() {
_static = nullptr;
}
@@ -53,7 +95,7 @@ void CStarControlSub6::identity() {
}
void CStarControlSub6::setRotationMatrix(Axis axis, double amount) {
- const double ROTATION = 3.1415927 * 0.0055555557;
+ const double ROTATION = 2 * M_PI / 360.0;
double sinVal = sin(amount * ROTATION);
double cosVal = cos(amount * ROTATION);
@@ -114,53 +156,67 @@ void CStarControlSub6::copyFrom(const FMatrix &src) {
_row3 = src._row3;
}
-CStarControlSub6 *CStarControlSub6::setup(CStarControlSub6 *dest, const CStarControlSub6 *s2, const CStarControlSub6 *s3) {
- CStarControlSub6 &d = *dest;
-
- d._row1._x = s3->_row1._x * s2->_row1._x
- + s2->_row1._z * s3->_row3._x
- + s2->_row1._y * s3->_row2._x;
- d._row1._y = s2->_row1._x * s3->_row1._y
- + s3->_row3._y * s2->_row1._z
- + s3->_row2._y * s2->_row1._y;
- d._row1._z = s2->_row1._x * s3->_row1._z
- + s3->_row3._z * s2->_row1._z
- + s3->_row2._z * s2->_row1._y;
- d._row2._x = s3->_row1._x * s2->_row2._x
- + s2->_row2._y * s3->_row2._x
- + s2->_row2._z * s3->_row3._x;
- d._row2._y = s2->_row2._y * s3->_row2._y
- + s2->_row2._z * s3->_row3._y
- + s3->_row1._y * s2->_row2._x;
- d._row2._z = s3->_row1._z * s2->_row2._x
- + s2->_row2._y * s3->_row2._z
- + s2->_row2._z * s3->_row3._z;
- d._row3._x = s3->_row1._x * s2->_row3._x
- + s2->_row3._y * s3->_row2._x
- + s2->_row3._z * s3->_row3._x;
- d._row3._y = s2->_row3._z * s3->_row3._y
- + s2->_row3._y * s3->_row2._y
- + s3->_row1._y * s2->_row3._x;
- d._row3._z = s3->_row3._z * s2->_row3._z
- + s3->_row2._z * s2->_row3._y
- + s3->_row1._z * s2->_row3._x;
- d._vector._x = s3->_row1._x * s2->_vector._x
- + s2->_vector._y * s3->_row2._x
- + s2->_vector._z * s3->_row3._x
- + s3->_vector._x;
- d._vector._y = s2->_vector._z * s3->_row3._y
- + s2->_vector._y * s3->_row2._y
- + s2->_vector._x * s3->_row1._y
- + s3->_vector._y;
- d._vector._z = s2->_vector._y * s3->_row2._z
- + s2->_vector._z * s3->_row3._z
- + s2->_vector._x * s3->_row1._z
- + s3->_vector._z;
- return dest;
-}
-
-void CStarControlSub6::fn1(CStarControlSub6 *sub6) {
- // TODO
+void CStarControlSub6::fn4(CStarControlSub6 *sub6) {
+ double v2, v3, v6, v7, v8, v9, v10, v11;
+ double v12, v13, v14, v15, v16, v17, v18;
+
+ v16 = _row3._z * _row2._y;
+ v2 = _row1._x * v16;
+ v3 = 0.0;
+ v18 = v2;
+ if (v2 < 0.0) {
+ v3 = v18;
+ v2 = 0.0;
+ }
+ v6 = _row3._x * _row1._y * _row2._z;
+ if (v6 < 0.0)
+ v3 = v3 + v6;
+ else
+ v2 = v2 + v6;
+ v7 = _row3._y * _row1._z * _row2._x;
+ if (v7 < 0.0)
+ v3 = v3 + v7;
+ else
+ v2 = v2 + v7;
+ if (-(_row3._x * _row1._z * _row2._y) < 0.0)
+ v3 = v3 - _row3._x * _row1._z * _row2._y;
+ else
+ v2 = v2 - _row3._x * _row1._z * _row2._y;
+ if (-(_row1._y * _row2._x * _row3._z) < 0.0)
+ v3 = v3 - _row1._y * _row2._x * _row3._z;
+ else
+ v2 = v2 - _row1._y * _row2._x * _row3._z;
+ v17 = _row2._z * _row3._y;
+ if (-(_row1._x * v17) < 0.0)
+ v3 = v3 - _row1._x * v17;
+ else
+ v2 = v2 - _row1._x * v17;
+ v18 = v3 + v2;
+ assert(!(v18 == 0.0 || fabs(v18 / (v2 - v3)) < 1.0e-10));
+
+ v8 = 1.0 / v18;
+ v18 = v8;
+ sub6->_row1._x = (v16 - v17) * v8;
+ sub6->_row2._x = -(_row2._x * _row3._z - _row3._x * _row2._z) * v8;
+ sub6->_row3._x = (_row3._y * _row2._x - _row3._x * _row2._y) * v8;
+ sub6->_row1._y = -(_row1._y * _row3._z - _row3._y * _row1._z) * v8;
+ sub6->_row2._y = (_row1._x * _row3._z - _row3._x * _row1._z) * v8;
+ sub6->_row3._y = -(_row1._x * _row3._y - _row3._x * _row1._y) * v8;
+ sub6->_row1._z = (_row1._y * _row2._z - _row1._z * _row2._y) * v8;
+ sub6->_row2._z = -(_row1._x * _row2._z - _row1._z * _row2._x) * v8;
+ v9 = sub6->_row1._x;
+ v10 = sub6->_row2._y;
+ v11 = sub6->_row3._y;
+ v12 = sub6->_row1._z;
+ v13 = sub6->_row2._z;
+ sub6->_row3._z = (_row1._x * _row2._y - _row1._y * _row2._x) * v18;
+ v14 = v9;
+ v15 = sub6->_row3._z;
+ sub6->_vector._x = -(v14 * _vector._x
+ + _vector._y * sub6->_row2._x
+ + _vector._z * sub6->_row3._x);
+ sub6->_vector._y = -(_vector._x * sub6->_row1._y + v10 * _vector._y + v11 * _vector._z);
+ sub6->_vector._z = -(v12 * _vector._x + v13 * _vector._y + v15 * _vector._z);
}
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub6.h b/engines/titanic/star_control/star_control_sub6.h
index 27b91628ba..91def29973 100644
--- a/engines/titanic/star_control/star_control_sub6.h
+++ b/engines/titanic/star_control/star_control_sub6.h
@@ -39,6 +39,7 @@ public:
CStarControlSub6();
CStarControlSub6(Axis axis, double amount);
CStarControlSub6(const CStarControlSub6 *src);
+ CStarControlSub6(const CStarControlSub6 *s1, const CStarControlSub6 *s2);
/**
* Sets an identity matrix
@@ -46,11 +47,6 @@ public:
void identity();
/**
- * Sets up a passed instance from the specified two other ones
- */
- static CStarControlSub6 *setup(CStarControlSub6 *dest, const CStarControlSub6 *s2, const CStarControlSub6 *s3);
-
- /**
* Sets a rotation matrix for the given axis for the given amount
*/
void setRotationMatrix(Axis axis, double val);
@@ -62,7 +58,7 @@ public:
*/
void copyFrom(const FMatrix &src);
- void fn1(CStarControlSub6 *sub6);
+ void fn4(CStarControlSub6 *sub6);
};
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub7.cpp b/engines/titanic/star_control/star_control_sub7.cpp
index c2c9030700..8386e7305f 100644
--- a/engines/titanic/star_control/star_control_sub7.cpp
+++ b/engines/titanic/star_control/star_control_sub7.cpp
@@ -21,11 +21,55 @@
*/
#include "titanic/star_control/star_control_sub7.h"
+#include "titanic/star_control/star_control_sub12.h"
namespace Titanic {
void CStarControlSub7::draw(CSurfaceArea *surfaceArea, CStarControlSub12 *sub12, CStarControlSub5 *sub5) {
- // TODO
+ if (_data.empty())
+ return;
+
+ CStarControlSub6 sub6 = sub12->proc23();
+ double threshold = sub12->proc25();
+ FPoint center((double)surfaceArea->_width * 0.5,
+ surfaceArea->_height * 0.5);
+ FVector newV;
+
+ uint savedPixel = surfaceArea->_pixel;
+ surfaceArea->_pixel = 0xffff;
+ surfaceArea->setColorFromPixel();
+
+ for (uint idx = 0; idx < _data.size(); ++idx) {
+ const CBaseStarEntry &star = _data[idx];
+
+ newV._x = sub6._row1._x * star._position._x + sub6._row3._x * star._position._z
+ + sub6._row2._x * star._position._y + sub6._vector._x;
+ newV._y = sub6._row1._y * star._position._x + sub6._row3._y * star._position._z
+ + sub6._row2._y * star._position._x + sub6._vector._y;
+ newV._z = sub6._row1._z * star._position._x + sub6._row3._z * star._position._z
+ + sub6._row2._z * star._position._y + sub6._vector._z;
+
+ if (newV._z > threshold) {
+ FVector vTemp;
+ sub12->proc28(2, newV, vTemp);
+
+ FRect r1(center._x + vTemp._x, center._y + vTemp._y,
+ center._x + vTemp._x + 4.0, center._y + vTemp._y + 4.0);
+ surfaceArea->fn1(r1);
+
+ FRect r2(r1.right, r1.bottom, r1.right + 4.0, r1.top);
+ surfaceArea->fn1(r2);
+
+ FRect r3(r2.right, r1.top, r1.right, r1.top - 4.0);
+ surfaceArea->fn1(r3);
+
+ FRect r4(r1.right, r1.top - 4.0, r1.left, r1.top);
+ surfaceArea->fn1(r4);
+ }
+ }
+
+ surfaceArea->_pixel = savedPixel;
+ surfaceArea->setColorFromPixel();
}
bool CStarControlSub7::addStar(const CBaseStarEntry *entry) {
diff --git a/engines/titanic/star_control/star_control_sub8.cpp b/engines/titanic/star_control/star_control_sub8.cpp
index 19be7f9d41..bf29b053c5 100644
--- a/engines/titanic/star_control/star_control_sub8.cpp
+++ b/engines/titanic/star_control/star_control_sub8.cpp
@@ -31,14 +31,66 @@ namespace Titanic {
CStarControlSub8::CStarControlSub8() : _field8(-1), _entryIndex(-1) {
}
-int CStarControlSub8::findStar(const Common::Point &pt) {
- // TODO
- return -1;
-}
-
void CStarControlSub8::selectStar(int index, CVideoSurface *surface,
CStarField *starField, CStarControlSub7 *sub7) {
- // TODO
+ if (_entryIndex >= 0) {
+ if (_entryIndex == _field8) {
+ if (_field8 != 2) {
+ if (_positions[index] != _positions[_entryIndex + 1]) {
+ surface->lock();
+
+ CSurfaceArea surfaceArea(surface);
+ fn4(index, &surfaceArea);
+ surface->unlock();
+
+ ++_entryIndex;
+ CStarPosition &newP = _positions[_entryIndex + 1];
+ newP = _positions[index];
+
+ const CBaseStarEntry *starP = starField->getDataPtr(_positions[index]._index1);
+ sub7->addStar(starP);
+ }
+ }
+ } else if (_entryIndex == _field8 + 1) {
+ if (_positions[index] == _positions[_entryIndex + 1]) {
+ surface->lock();
+ CSurfaceArea surfaceArea(surface);
+ fn6(&surfaceArea);
+ surface->unlock();
+
+ --_entryIndex;
+ const CBaseStarEntry *starP = starField->getDataPtr(_positions[index]._index1);
+ sub7->addStar(starP);
+ } else {
+ surface->lock();
+ CSurfaceArea surfaceArea(surface);
+ fn6(&surfaceArea);
+ fn4(index, &surfaceArea);
+ surface->unlock();
+
+ const CBaseStarEntry *starP;
+ starP = starField->getDataPtr(_positions[_entryIndex]._index1);
+ sub7->addStar(starP);
+ starP = starField->getDataPtr(_positions[index]._index1);
+ sub7->addStar(starP);
+
+ CStarPosition &newP = _positions[_entryIndex + 1];
+ newP = _positions[index];
+ }
+ }
+ } else {
+ surface->lock();
+ CSurfaceArea surfaceArea(surface);
+ fn4(index, &surfaceArea);
+ surface->unlock();
+
+ ++_entryIndex;
+ CStarPosition &newP = _positions[_entryIndex + 1];
+ newP = _positions[index];
+
+ const CBaseStarEntry *starP = starField->getDataPtr(_positions[index]._index1);
+ sub7->addStar(starP);
+ }
}
bool CStarControlSub8::fn1(CStarField *starField, CSurfaceArea *surfaceArea, CStarControlSub12 *sub12) {
@@ -53,13 +105,21 @@ bool CStarControlSub8::fn1(CStarField *starField, CSurfaceArea *surfaceArea, CSt
clear();
return false;
}
-
- // TODO
- return true;
}
void CStarControlSub8::fn2(CVideoSurface *surface, CStarField *starField, CStarControlSub7 *sub7) {
- // TODO
+ if (_field8 <= -1) {
+ if (_entryIndex > -1) {
+ fn5(_entryIndex, surface, starField, sub7);
+ --_entryIndex;
+ }
+ } else {
+ --_field8;
+ if (_entryIndex - _field8 > 1) {
+ fn5(_entryIndex, surface, starField, sub7);
+ --_entryIndex;
+ }
+ }
}
void CStarControlSub8::fn3() {
@@ -69,26 +129,29 @@ void CStarControlSub8::fn3() {
FPoint CStarControlSub8::getPosition() const {
return (_entryIndex >= 0 && _entryIndex <= 2) ?
- FPoint(_entries[_entryIndex].left, _entries[_entryIndex].top) : FPoint();
+ FPoint(_entries[_entryIndex]) : FPoint();
}
void CStarControlSub8::draw(CSurfaceArea *surfaceArea) {
if (!_positions.empty()) {
- uint oldPixel = surfaceArea->_pixel;
- surfaceArea->_pixel = 0xFF;
+ uint savedPixel = surfaceArea->_pixel;
+ surfaceArea->_pixel = 0xff;
surfaceArea->setColorFromPixel();
- SurfaceAreaMode oldMode = surfaceArea->setMode(SA_NONE);
+ SurfaceAreaMode savedMode = surfaceArea->setMode(SA_NONE);
- // TODO: Loop
- /*
for (int idx = 0; idx < _entryIndex; ++idx) {
- Common::Rect &r = _entries[idx];
+ const CStarPosition &src = _entries[idx];
+ double xp = src.x, yp = src.y;
+ surfaceArea->fn1(FRect(xp - 8.0, yp, xp - 4.0, yp));
+ surfaceArea->fn1(FRect(xp + 4.0, yp, xp + 8.0, yp));
+ surfaceArea->fn1(FRect(xp, yp - 8.0, xp, yp - 4.0));
+ surfaceArea->fn1(FRect(xp, yp + 4.0, xp, yp + 8.0));
}
- */
- surfaceArea->_pixel = oldPixel;
- surfaceArea->setMode(oldMode);
+ surfaceArea->_pixel = savedPixel;
+ surfaceArea->setColorFromPixel();
+ surfaceArea->setMode(savedMode);
}
}
@@ -112,7 +175,7 @@ int CStarControlSub8::indexOf(const Common::Point &pt) const {
Common::Rect r(pt.x - 2, pt.y - 2, pt.x + 2, pt.y + 2);
for (int idx = 0; idx < (int)_positions.size(); ++idx) {
- if (r.contains(_positions[idx]._position))
+ if (r.contains(_positions[idx]))
return idx;
}
@@ -120,19 +183,42 @@ int CStarControlSub8::indexOf(const Common::Point &pt) const {
}
void CStarControlSub8::fn4(int index, CSurfaceArea *surfaceArea) {
- // TODO
+ if (index >= 0 && index < (int)_positions.size()) {
+ const CStarPosition &pt = _positions[index];
+ fn7(pt, surfaceArea);
+ }
}
void CStarControlSub8::fn5(int index, CVideoSurface *surface, CStarField *starField, CStarControlSub7 *sub7) {
- // TODO
+ surface->lock();
+ CSurfaceArea surfaceArea(surface);
+ fn7(_positions[index + 1], &surfaceArea);
+ surface->unlock();
+
+ const CBaseStarEntry *starP = starField->getDataPtr(_positions[index + 1]._index1);
+ sub7->addStar(starP);
}
void CStarControlSub8::fn6(CSurfaceArea *surfaceArea) {
- // TODO
+ const CStarPosition &pt = _positions[_entryIndex];
+ fn7(pt, surfaceArea);
}
void CStarControlSub8::fn7(const FPoint &pt, CSurfaceArea *surfaceArea) {
- // TODO
+ uint savedPixel = surfaceArea->_pixel;
+ surfaceArea->_pixel = 255;
+ surfaceArea->setColorFromPixel();
+ SurfaceAreaMode savedMode = surfaceArea->setMode(SA_MODE3);
+
+
+ surfaceArea->fn1(FRect(pt._x - 8.0, pt._y, pt._x - 4.0, pt._y));
+ surfaceArea->fn1(FRect(pt._x - -4.0, pt._y, pt._x + 8.0, pt._y));
+ surfaceArea->fn1(FRect(pt._x, pt._y - 8.0, pt._x, pt._y - 4.0));
+ surfaceArea->fn1(FRect(pt._x, pt._y + 4.0, pt._x, pt._y + 8.0));
+
+ surfaceArea->_pixel = savedPixel;
+ surfaceArea->setColorFromPixel();
+ surfaceArea->setMode(savedMode);
}
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub8.h b/engines/titanic/star_control/star_control_sub8.h
index b9b544d78e..4939179481 100644
--- a/engines/titanic/star_control/star_control_sub8.h
+++ b/engines/titanic/star_control/star_control_sub8.h
@@ -41,7 +41,7 @@ class CStarControlSub8 {
private:
Common::Array<CStarPosition> _positions;
int _entryIndex;
- Common::Rect _entries[3];
+ CStarPosition _entries[3];
private:
/**
* Allocates space in the _rects array
@@ -69,8 +69,6 @@ public:
*/
void save(SimpleFile *file, int indent) {}
- int findStar(const Common::Point &pt);
-
void selectStar(int starNum, CVideoSurface *surface, CStarField *starField,
CStarControlSub7 *sub7);
diff --git a/engines/titanic/star_control/star_field.cpp b/engines/titanic/star_control/star_field.cpp
index 07c5ff4a73..5c22e5e308 100644
--- a/engines/titanic/star_control/star_field.cpp
+++ b/engines/titanic/star_control/star_field.cpp
@@ -232,7 +232,7 @@ bool CStarField::mouseButtonDown(CVideoSurface *surface, CStarControlSub12 *sub1
CSurfaceArea surfaceArea(surface);
return selectStar(&surfaceArea, sub12, pt);
} else {
- int starNum = _sub8.findStar(pt);
+ int starNum = _sub8.indexOf(pt);
if (starNum >= 0) {
_sub8.selectStar(starNum, surface, this, &_sub7);
return true;
diff --git a/engines/titanic/star_control/star_points1.cpp b/engines/titanic/star_control/star_points1.cpp
index c72795f11d..ab5da111ac 100644
--- a/engines/titanic/star_control/star_points1.cpp
+++ b/engines/titanic/star_control/star_points1.cpp
@@ -27,7 +27,7 @@
namespace Titanic {
#define ARRAY_COUNT 876
-const double FACTOR = 3.1415927 * 0.0055555557;
+const double FACTOR = 2 * M_PI / 360.0;
CStarPoints1::CStarPoints1() {
}
diff --git a/engines/titanic/star_control/star_points2.cpp b/engines/titanic/star_control/star_points2.cpp
index 9c4cfe8cf5..7a3e873e90 100644
--- a/engines/titanic/star_control/star_points2.cpp
+++ b/engines/titanic/star_control/star_points2.cpp
@@ -27,7 +27,7 @@
namespace Titanic {
#define ARRAY_COUNT 80
-const double FACTOR = 3.1415927 * 0.0055555557;
+const double FACTOR = 2 * M_PI / 360.0;
bool CStarPoints2::initialize() {
// Get a reference to the starfield points resource
@@ -47,7 +47,7 @@ bool CStarPoints2::initialize() {
v1 = stream->readSint32LE();
v2 = stream->readSint32LE();
v1 *= 0.015 * FACTOR;
- v2 *= 0.0099999998 * FACTOR;
+ v2 *= FACTOR / 100.0;
entry._x = cos(v1) * 3000000.0 * cos(v2);
entry._y = sin(v1) * 3000000.0 * cos(v2);
diff --git a/engines/titanic/star_control/star_ref.cpp b/engines/titanic/star_control/star_ref.cpp
index 0b9898035f..7f36ae7473 100644
--- a/engines/titanic/star_control/star_ref.cpp
+++ b/engines/titanic/star_control/star_ref.cpp
@@ -47,7 +47,8 @@ bool CStarRef2::check(const Common::Point &pt, int index) {
return false;
CStarPosition &sp = (*_positions)[index];
- sp._position = pt;
+ sp.x = pt.x;
+ sp.y = pt.y;
sp._index1 = sp._index2 = index;
return true;
}
diff --git a/engines/titanic/star_control/star_view.cpp b/engines/titanic/star_control/star_view.cpp
index 34fd371bac..6ed5f3b2f3 100644
--- a/engines/titanic/star_control/star_view.cpp
+++ b/engines/titanic/star_control/star_view.cpp
@@ -409,7 +409,7 @@ void CStarView::fn16() {
void CStarView::fn17() {
if (_starField && !_showingPhoto) {
- _sub12.proc35();
+ _sub12.removeMatrixRow();
_starField->fn8(_videoSurface2);
}
}
diff --git a/gui/gui-manager.cpp b/gui/gui-manager.cpp
index 6f9fd8b13a..76f557711d 100644
--- a/gui/gui-manager.cpp
+++ b/gui/gui-manager.cpp
@@ -261,7 +261,7 @@ void GuiManager::addToTrash(GuiObject* object, Dialog* parent) {
t.parent = 0;
// If a dialog was provided, check it is in the dialog stack
if (parent != 0) {
- for (int i = 0 ; i < _dialogStack.size() ; ++i) {
+ for (uint i = 0 ; i < _dialogStack.size() ; ++i) {
if (_dialogStack[i] == parent) {
t.parent = parent;
break;
diff --git a/gui/options.cpp b/gui/options.cpp
index 179fa65991..d9361493d0 100644
--- a/gui/options.cpp
+++ b/gui/options.cpp
@@ -567,7 +567,7 @@ void OptionsDialog::apply() {
if (_enableShaderSettings) {
if (g_system->hasFeature(OSystem::kFeatureShader)) {
if (_shaderPopUp) {
- if (ConfMan.getInt("shader", _domain) != _shaderPopUp->getSelectedTag()) {
+ if (ConfMan.getInt("shader", _domain) != (int32)_shaderPopUp->getSelectedTag()) {
ConfMan.setInt("shader", _shaderPopUp->getSelectedTag(), _domain);
g_system->setShader(_shaderPopUp->getSelectedTag());
}