aboutsummaryrefslogtreecommitdiff
path: root/engines/tsage/core.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/tsage/core.cpp')
-rw-r--r--engines/tsage/core.cpp276
1 files changed, 118 insertions, 158 deletions
diff --git a/engines/tsage/core.cpp b/engines/tsage/core.cpp
index b929beec23..76714a6f10 100644
--- a/engines/tsage/core.cpp
+++ b/engines/tsage/core.cpp
@@ -31,6 +31,7 @@
#include "tsage/scenes.h"
#include "tsage/staticres.h"
#include "tsage/globals.h"
+#include "tsage/sound.h"
namespace tSage {
@@ -521,24 +522,30 @@ void PlayerMover::pathfind(Common::Point *routeList, Common::Point srcPos, Commo
break;
}
- int var6;
- proc1(routeRegions, srcRegion, destRegion, var6);
+ bool tempVar; // This is used only as internal state for the function.
+ calculateRestOfRoute(routeRegions, srcRegion, destRegion, tempVar);
+ // Empty route?
if (!routeRegions[0]) {
regionIndexes.push_back(destRegion);
continue;
}
- _globals->_walkRegions._field18[0]._pt1 = srcPos;
- _globals->_walkRegions._field18[0]._pt2 = srcPos;
- _globals->_walkRegions._field18[1]._pt1 = destPos;
- _globals->_walkRegions._field18[1]._pt2 = destPos;
+ // field 0 holds the start, and field 1 holds the destination
+ WRField18 &currSrcField = _globals->_walkRegions._field18[0];
+ WRField18 &currDestField = _globals->_walkRegions._field18[1];
+
+ currSrcField._pt1 = srcPos;
+ currSrcField._pt2 = srcPos;
+ currDestField._pt1 = destPos;
+ currDestField._pt2 = destPos;
int tempList[REGION_LIST_SIZE];
tempList[0] = 0;
int endIndex = 0;
int idx = 1;
+ // Find the indexes for each entry in the found route.
do {
int breakEntry = routeRegions[idx];
int breakEntry2 = routeRegions[idx + 1];
@@ -556,49 +563,52 @@ void PlayerMover::pathfind(Common::Point *routeList, Common::Point srcPos, Commo
tempList[idx] = 1;
for (int listIndex = 1; listIndex <= endIndex; ++listIndex) {
- int var10 = tempList[listIndex];
- int var12 = tempList[listIndex + 1];
+ int thisIdx = tempList[listIndex];
+ int nextIdx = tempList[listIndex + 1];
+
+ WRField18 &thisField = _globals->_walkRegions._field18[thisIdx];
+ WRField18 &nextField = _globals->_walkRegions._field18[nextIdx];
- if (sub_F8E5(_globals->_walkRegions._field18[0]._pt1, _globals->_walkRegions._field18[var12]._pt1,
- _globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[var10]._pt2) &&
- sub_F8E5(_globals->_walkRegions._field18[0]._pt1, _globals->_walkRegions._field18[var12]._pt2,
- _globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[var10]._pt2))
+ if (sub_F8E5_calculatePoint(currSrcField._pt1, nextField._pt1,
+ thisField._pt1, thisField._pt2) &&
+ sub_F8E5_calculatePoint(currSrcField._pt1, nextField._pt2,
+ thisField._pt1, thisField._pt2))
continue;
Common::Point tempPt;
- if (sub_F8E5(_globals->_walkRegions._field18[0]._pt1, _globals->_walkRegions._field18[1]._pt1,
- _globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[var10]._pt2, &tempPt)) {
+ if (sub_F8E5_calculatePoint(currSrcField._pt1, currDestField._pt1,
+ thisField._pt1, thisField._pt2, &tempPt)) {
// Add point to the route list
- _globals->_walkRegions._field18[0]._pt1 = tempPt;
+ currSrcField._pt1 = tempPt;
*routeList++ = tempPt;
} else {
- int v16 =
- (findDistance(_globals->_walkRegions._field18[0]._pt1, _globals->_walkRegions._field18[var10]._pt1) << 1) +
- (findDistance(_globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[1]._pt1) << 1) +
- findDistance(_globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[var12]._pt1) +
- findDistance(_globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[var12]._pt2);
-
- int v1A =
- (findDistance(_globals->_walkRegions._field18[0]._pt1, _globals->_walkRegions._field18[var10]._pt2) << 1) +
- (findDistance(_globals->_walkRegions._field18[var10]._pt2, _globals->_walkRegions._field18[1]._pt2) << 1) +
- findDistance(_globals->_walkRegions._field18[var10]._pt2, _globals->_walkRegions._field18[var12]._pt1) +
- findDistance(_globals->_walkRegions._field18[var10]._pt2, _globals->_walkRegions._field18[var12]._pt2);
-
- if (v16 < v1A) {
- checkMovement2(_globals->_walkRegions._field18[var10]._pt1,
- _globals->_walkRegions._field18[var10]._pt2, 1, objPos);
+ int dist1 =
+ (findDistance(currSrcField._pt1, thisField._pt1) << 1) +
+ (findDistance(thisField._pt1, currDestField._pt1) << 1) +
+ findDistance(thisField._pt1, nextField._pt1) +
+ findDistance(thisField._pt1, nextField._pt2);
+
+ int dist2 =
+ (findDistance(currSrcField._pt1, thisField._pt2) << 1) +
+ (findDistance(thisField._pt2, currDestField._pt2) << 1) +
+ findDistance(thisField._pt2, nextField._pt1) +
+ findDistance(thisField._pt2, nextField._pt2);
+
+ // Do 1 step of movement, storing the new position in objPos.
+ if (dist1 < dist2) {
+ doStepsOfNpcMovement(thisField._pt1, thisField._pt2, 1, objPos);
} else {
- checkMovement2(_globals->_walkRegions._field18[var10]._pt2,
- _globals->_walkRegions._field18[var10]._pt1, 1, objPos);
+ doStepsOfNpcMovement(thisField._pt2, thisField._pt1, 1, objPos);
}
- _globals->_walkRegions._field18[0]._pt1 = objPos;
+ // Update the current position.
+ currSrcField._pt1 = objPos;
*routeList++ = objPos;
}
}
// Add in the route entry
- *routeList++ = _globals->_walkRegions._field18[1]._pt1;
+ *routeList++ = currDestField._pt1;
}
// Mark the end of the path
@@ -746,7 +756,7 @@ int PlayerMover::checkMover(Common::Point &srcPos, const Common::Point &destPos)
return regionIndex;
}
-void PlayerMover::checkMovement2(const Common::Point &srcPos, const Common::Point &destPos, int numSteps, Common::Point &ptOut) {
+void PlayerMover::doStepsOfNpcMovement(const Common::Point &srcPos, const Common::Point &destPos, int numSteps, Common::Point &ptOut) {
Common::Point objPos = _sceneObject->_position;
_sceneObject->_position = srcPos;
uint32 regionBitList = _sceneObject->_regionBitList;
@@ -771,9 +781,10 @@ void PlayerMover::checkMovement2(const Common::Point &srcPos, const Common::Poin
_sceneObject->_mover = this;
}
-int PlayerMover::proc1(int *routeList, int srcRegion, int destRegion, int &v) {
+int PlayerMover::calculateRestOfRoute(int *routeList, int srcRegion, int destRegion, bool &foundRoute) {
+ // Make a copy of the provided route. The first entry is the size.
int tempList[REGION_LIST_SIZE + 1];
- v = 0;
+ foundRoute = false;
for (int idx = 0; idx <= *routeList; ++idx)
tempList[idx] = routeList[idx];
@@ -791,24 +802,28 @@ int PlayerMover::proc1(int *routeList, int srcRegion, int destRegion, int &v) {
WalkRegion &srcWalkRegion = _globals->_walkRegions[srcRegion];
int distance;
if (!routeList[0]) {
- // No route
+ // The route is empty (new route).
distance = 0;
} else {
+ // Find the distance from the last region in the route.
WalkRegion &region = _globals->_walkRegions[routeList[*routeList]];
distance = findDistance(srcWalkRegion._pt, region._pt);
}
+ // Add the srcRegion to the end of the route.
tempList[++*tempList] = srcRegion;
- int newIndex = *tempList;
+ int ourListSize = *tempList;
if (srcRegion == destRegion) {
- v = 1;
- for (int idx = newIndex; idx <= *tempList; ++idx) {
+ // We made a route to the destination; copy that route and return.
+ foundRoute = true;
+ for (int idx = ourListSize; idx <= *tempList; ++idx) {
routeList[idx] = tempList[idx];
++*routeList;
}
return distance;
} else {
+ // Find the first connected region leading to our destination.
int foundIndex = 0;
int idx = 0;
int currDest;
@@ -821,27 +836,32 @@ int PlayerMover::proc1(int *routeList, int srcRegion, int destRegion, int &v) {
++idx;
}
- int resultOffset = 31990;
- while (((currDest = _globals->_walkRegions._idxList[srcWalkRegion._idxListIndex + foundIndex]) != 0) && (v == 0)) {
- int newDistance = proc1(tempList, currDest, destRegion, v);
+ // Check every connected region until we find a route to the destination (or we have no more to check).
+ int bestDistance = 31990;
+ while (((currDest = _globals->_walkRegions._idxList[srcWalkRegion._idxListIndex + foundIndex]) != 0) && (!foundRoute)) {
+ int newDistance = calculateRestOfRoute(tempList, currDest, destRegion, foundRoute);
+
+ if ((newDistance <= bestDistance) || foundRoute) {
+ // We found a shorter possible route, or one leading to the destination.
- if ((newDistance <= resultOffset) || v) {
- routeList[0] = newIndex - 1;
+ // Overwrite the route with this new one.
+ routeList[0] = ourListSize - 1;
- for (int i = newIndex; i <= tempList[0]; ++i) {
+ for (int i = ourListSize; i <= tempList[0]; ++i) {
routeList[i] = tempList[i];
++routeList[0];
}
- resultOffset = newDistance;
+ bestDistance = newDistance;
}
- tempList[0] = newIndex;
+ // Truncate our local list to the size it was before the call.
+ tempList[0] = ourListSize;
++foundIndex;
}
- v = 0;
- return resultOffset + distance;
+ foundRoute = false;
+ return bestDistance + distance;
}
}
@@ -855,71 +875,62 @@ int PlayerMover::findDistance(const Common::Point &pt1, const Common::Point &pt2
return (int)sqrt(xx + yy);
}
-bool PlayerMover::sub_F8E5(const Common::Point &pt1, const Common::Point &pt2, const Common::Point &pt3,
+bool PlayerMover::sub_F8E5_calculatePoint(const Common::Point &pt1, const Common::Point &pt2, const Common::Point &pt3,
const Common::Point &pt4, Common::Point *ptOut) {
- double diff1 = pt2.x - pt1.x;
- double diff2 = pt2.y - pt1.y;
- double diff3 = pt4.x - pt3.x;
- double diff4 = pt4.y - pt3.y;
- double var10 = 0.0, var8 = 0.0;
- double var18 = 0.0, var20 = 0.0;
+ double diffX1 = pt2.x - pt1.x;
+ double diffY1 = pt2.y - pt1.y;
+ double diffX2 = pt4.x - pt3.x;
+ double diffY2 = pt4.y - pt3.y;
+ double ratio1 = 0.0, ratio2 = 0.0;
+ double adjustedY1 = 0.0, adjustedY2 = 0.0;
- if (diff1 != 0.0) {
- var8 = diff2 / diff1;
- var18 = pt1.y - (pt1.x * var8);
+ // Calculate the ratios between the X and Y points.
+ if (diffX1 != 0.0) {
+ ratio1 = diffY1 / diffX1;
+ adjustedY1 = pt1.y - (pt1.x * ratio1);
}
- if (diff3 != 0.0) {
- var10 = diff4 / diff3;
- var20 = pt3.y - (pt3.x * var10);
+ if (diffX2 != 0.0) {
+ ratio2 = diffY2 / diffX2;
+ adjustedY2 = pt3.y - (pt3.x * ratio2);
}
- if (var8 == var10)
+ if (ratio1 == ratio2)
return false;
- double var48, var50;
- if (diff1 == 0) {
- if (diff3 == 0)
+ double xPos, yPos;
+ if (diffX1 == 0) {
+ if (diffX2 == 0)
return false;
- var48 = pt1.x;
- var50 = var10 * var48 + var20;
+ xPos = pt1.x;
+ yPos = ratio2 * xPos + adjustedY2;
} else {
- var48 = (diff3 == 0) ? pt3.x : (var20 - var18) / (var8 - var10);
- var50 = var8 * var48 + var18;
+ xPos = (diffX2 == 0) ? pt3.x : (adjustedY2 - adjustedY1) / (ratio1 - ratio2);
+ yPos = ratio1 * xPos + adjustedY1;
}
- bool var52 = false, var56 = false, var54 = false, var58 = false;
- Common::Point tempPt((int)(var48 + 0.5), (int)(var50 + 0.5));
-
- if ((tempPt.x >= pt3.x) && (tempPt.x <= pt4.x))
- var56 = true;
- else if ((tempPt.x >= pt4.x) && (tempPt.x <= pt3.x))
- var56 = true;
- if (var56) {
- if ((tempPt.y >= pt3.y) && (tempPt.y <= pt4.y))
- var58 = true;
- else if ((tempPt.y >= pt4.y) && (tempPt.y <= pt3.y))
- var58 = true;
- }
+ // This is our candidate point, which we must check for validity.
+ Common::Point tempPt((int)(xPos + 0.5), (int)(yPos + 0.5));
- if ((tempPt.x >= pt1.x) && (tempPt.x <= pt2.x))
- var52 = true;
- else if ((tempPt.x >= pt2.x) && (tempPt.x <= pt1.x))
- var52 = true;
- if (var52) {
- if ((tempPt.y >= pt1.y) && (tempPt.y <= pt2.y))
- var54 = true;
- else if ((tempPt.y >= pt2.y) && (tempPt.y <= pt1.y))
- var54 = true;
- }
+ // Is tempPt inside the second bounds?
+ if (!((tempPt.x >= pt3.x) && (tempPt.x <= pt4.x)))
+ if (!((tempPt.x >= pt4.x) && (tempPt.x <= pt3.x)))
+ return false;
+ if (!((tempPt.y >= pt3.y) && (tempPt.y <= pt4.y)))
+ if (!((tempPt.y >= pt4.y) && (tempPt.y <= pt3.y)))
+ return false;
- if (var52 && var54 && var56 && var58) {
- if (ptOut)
- *ptOut = tempPt;
- return true;
- }
+ // Is tempPt inside the first bounds?
+ if (!((tempPt.x >= pt1.x) && (tempPt.x <= pt2.x)))
+ if (!((tempPt.x >= pt2.x) && (tempPt.x <= pt1.x)))
+ return false;
+ if (!((tempPt.y >= pt1.y) && (tempPt.y <= pt2.y)))
+ if (!((tempPt.y >= pt2.y) && (tempPt.y <= pt1.y)))
+ return false;
- return false;
+ if (ptOut)
+ *ptOut = tempPt;
+ return true;
}
/*--------------------------------------------------------------------------*/
@@ -2858,8 +2869,6 @@ void Region::draw() {
}
void Region::uniteLine(int yp, LineSliceSet &sliceSet) {
- // TODO: More properly implement like the original
-
// First expand the bounds as necessary to fit in the row
if (_ySlices.empty()) {
_bounds = Rect(sliceSet.items[0].xs, yp, sliceSet.items[sliceSet.items.size() - 1].xe, yp + 1);
@@ -2951,55 +2960,6 @@ int SceneRegions::indexOf(const Common::Point &pt) {
/*--------------------------------------------------------------------------*/
-SoundHandler::SoundHandler() {
- _action = NULL;
- _field280 = -1;
- if (_globals)
- _globals->_sceneListeners.push_back(this);
-}
-
-SoundHandler::~SoundHandler() {
- if (_globals)
- _globals->_sceneListeners.remove(this);
-}
-
-void SoundHandler::dispatch() {
- EventHandler::dispatch();
- int v = _sound.proc12();
-
- if (v != -1) {
- _field280 = v;
- _sound.proc2(-1);
-
- if (_action)
- _action->signal();
- }
-
- if (_field280 != -1) {
- // FIXME: Hardcoded to only flag a sound ended if an action has been set
- if (_action) {
-// if (!_sound.proc3()) {
- _field280 = -1;
- if (_action) {
- _action->signal();
- _action = NULL;
- }
- }
- }
-}
-
-void SoundHandler::startSound(int soundNum, Action *action, int volume) {
- _action = action;
- _field280 = 0;
- setVolume(volume);
- _sound.startSound(soundNum);
-
- warning("TODO: SoundHandler::startSound");
-}
-
-
-/*--------------------------------------------------------------------------*/
-
void SceneItemList::addItems(SceneItem *first, ...) {
va_list va;
va_start(va, first);
@@ -3062,13 +3022,12 @@ void WalkRegion::loadProcessList(byte *dataP, int dataSize, int &dataIndex, int
int yp = READ_LE_UINT16(dataP + idx * 4 + 2);
if (yp != y1) {
/*
- * Commented out: doesn't seem to be used
+ * Commented out: v doesn't seem to be used
int v;
if (idx == (dataSize - 1))
v = READ_LE_UINT16(dataP + 2);
else
v = process1(idx, dataP, dataSize);
- warning("TODO: v not used? - %d", v);
*/
process2(dataIndex, x1, y1, xp, yp);
++dataIndex;
@@ -3480,8 +3439,9 @@ void SceneHandler::postInit(SceneObjectList *OwnerList) {
_globals->_scenePalette.loadPalette(0);
_globals->_scenePalette.refresh();
- // TODO: Bunch of other scene related setup goes here
_globals->_soundManager.postInit();
+ _globals->_soundManager.buildDriverList(true);
+ _globals->_soundManager.installConfigDrivers();
_globals->_game->start();
}
@@ -3584,9 +3544,10 @@ void SceneHandler::dispatch() {
if (_globals->_sceneManager._scene)
_globals->_sceneManager._scene->dispatch();
- //TODO: Figure out purpose of the given list
- //_globals->_regions.forEach(SceneHandler::handleListener);
+ // Not actually used
+ //_eventListeners.forEach(SceneHandler::handleListener);
+ // Handle pending eents
Event event;
while (_globals->_events.getEvent(event))
process(event);
@@ -3610,7 +3571,6 @@ void SceneHandler::dispatchObject(EventHandler *obj) {
}
void SceneHandler::saveListener(Serializer &ser) {
- warning("TODO: SceneHandler::saveListener");
}
} // End of namespace tSage