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.cpp238
1 files changed, 176 insertions, 62 deletions
diff --git a/engines/tsage/core.cpp b/engines/tsage/core.cpp
index b0220b53e0..16fe45044b 100644
--- a/engines/tsage/core.cpp
+++ b/engines/tsage/core.cpp
@@ -860,6 +860,8 @@ void PlayerMover::doStepsOfNpcMovement(const Common::Point &srcPos, const Common
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];
+ memset(tempList, 0, sizeof(tempList));
+
foundRoute = false;
for (int idx = 0; idx <= *routeList; ++idx)
tempList[idx] = routeList[idx];
@@ -1151,6 +1153,13 @@ void PaletteRotation::signal() {
if (flag)
_currIndex = _start;
}
+
+ // Added in Return to Ringworld
+ if (_currIndex < _start) {
+ flag = decDuration();
+ if (flag)
+ _currIndex = _end;
+ }
break;
case 2:
_currIndex += _idxChange;
@@ -1292,7 +1301,6 @@ ScenePalette::ScenePalette() {
*palData++ = idx;
}
- _field412 = 0;
_redColor = _greenColor = _blueColor = 0;
_aquaColor = 0;
_purpleColor = 0;
@@ -1304,7 +1312,6 @@ ScenePalette::~ScenePalette() {
}
ScenePalette::ScenePalette(int paletteNum) {
- _field412 = 0;
_redColor = _greenColor = _blueColor = 0;
_aquaColor = 0;
_purpleColor = 0;
@@ -1536,7 +1543,11 @@ void ScenePalette::synchronize(Serializer &s) {
s.syncAsSint32LE(_colors.foreground);
s.syncAsSint32LE(_colors.background);
- s.syncAsSint32LE(_field412);
+ if (s.getVersion() < 12) {
+ int useless = 0;
+ s.syncAsSint32LE(useless);
+ }
+
s.syncAsByte(_redColor);
s.syncAsByte(_greenColor);
s.syncAsByte(_blueColor);
@@ -1552,8 +1563,13 @@ void SceneItem::synchronize(Serializer &s) {
_bounds.synchronize(s);
s.syncString(_msg);
- s.syncAsSint32LE(_fieldE);
- s.syncAsSint32LE(_field10);
+
+ if (s.getVersion() < 15) {
+ int useless = 0;
+ s.syncAsSint32LE(useless);
+ s.syncAsSint32LE(useless);
+ }
+
s.syncAsSint16LE(_position.x); s.syncAsSint32LE(_position.y);
s.syncAsSint16LE(_yDiff);
s.syncAsSint32LE(_sceneRegionId);
@@ -1619,7 +1635,8 @@ void SceneItem::display(int resNum, int lineNum, ...) {
Common::String msg = (!resNum || (resNum == -1)) ? Common::String() :
g_resourceManager->getMessage(resNum, lineNum);
- if ((g_vm->getGameID() != GType_Ringworld) && T2_GLOBALS._uiElements._active)
+ if ((g_vm->getGameID() != GType_Ringworld) && (g_vm->getGameID() != GType_Ringworld2)
+ && T2_GLOBALS._uiElements._active)
T2_GLOBALS._uiElements.hide();
if (g_globals->_sceneObjects->contains(&g_globals->_sceneText)) {
@@ -1729,9 +1746,13 @@ void SceneItem::display(int resNum, int lineNum, ...) {
font.setFontNumber(g_globals->_sceneText._fontNumber);
font.getStringBounds(msg.c_str(), textRect, maxWidth);
+ Rect screenBounds = g_globals->gfxManager()._bounds;
+ if (g_vm->getGameID() == GType_Ringworld2)
+ screenBounds.collapse(20, 15);
+
// Center the text at the specified position, and then constrain it to be-
textRect.center(pos.x, pos.y);
- textRect.contain(g_globals->gfxManager()._bounds);
+ textRect.contain(screenBounds);
if (centerText) {
g_globals->_sceneText._color1 = g_globals->_sceneText._color2;
@@ -1749,9 +1770,22 @@ void SceneItem::display(int resNum, int lineNum, ...) {
}
g_globals->_sceneText.fixPriority(255);
+
+ // In Return to Ringworld, if in voice mode only, don't show the text
+ if ((g_vm->getGameID() == GType_Ringworld2) && (R2_GLOBALS._speechSubtitles & SPEECH_VOICE)
+ && !(R2_GLOBALS._speechSubtitles & SPEECH_TEXT))
+ g_globals->_sceneText.hide();
+
g_globals->_sceneObjects->draw();
}
+ // For Return to Ringworld, play the voice overs in sequence
+ if ((g_vm->getGameID() == GType_Ringworld2) && (R2_GLOBALS._speechSubtitles & SPEECH_VOICE)
+ && !playList.empty()) {
+ R2_GLOBALS._playStream.play(*playList.begin(), NULL);
+ playList.pop_front();
+ }
+
// Unless the flag is set to keep the message on-screen, show it until a mouse or keypress, then remove it
if (!keepOnscreen && !msg.empty()) {
Event event;
@@ -1761,18 +1795,31 @@ void SceneItem::display(int resNum, int lineNum, ...) {
EVENT_BUTTON_DOWN | EVENT_KEYPRESS)) {
GLOBALS._screenSurface.updateScreen();
g_system->delayMillis(10);
- }
- // For Return to Ringworld, play the voice overs in sequence
- if ((g_vm->getGameID() == GType_Ringworld2) && !playList.empty() && !R2_GLOBALS._playStream.isPlaying()) {
- R2_GLOBALS._playStream.play(*playList.begin(), NULL);
- playList.pop_front();
+ if ((g_vm->getGameID() == GType_Ringworld2) && (R2_GLOBALS._speechSubtitles & SPEECH_VOICE)) {
+ // Allow the play stream to do processing
+ R2_GLOBALS._playStream.dispatch();
+ if (!R2_GLOBALS._playStream.isPlaying()) {
+ // Check if there are further voice samples to play
+ if (!playList.empty()) {
+ R2_GLOBALS._playStream.play(*playList.begin(), NULL);
+ playList.pop_front();
+ } else if (!(R2_GLOBALS._speechSubtitles & SPEECH_TEXT)) {
+ // If not showing text, don't both waiting for a click to end
+ break;
+ }
+ }
+ }
}
+ if (g_vm->getGameID() == GType_Ringworld2)
+ R2_GLOBALS._playStream.stop();
+
g_globals->_sceneText.remove();
}
- if ((g_vm->getGameID() != GType_Ringworld) && T2_GLOBALS._uiElements._active) {
+ if ((g_vm->getGameID() != GType_Ringworld) && (g_vm->getGameID() != GType_Ringworld2)
+ && T2_GLOBALS._uiElements._active) {
// Show user interface
T2_GLOBALS._uiElements.show();
@@ -2066,18 +2113,18 @@ SceneObject::SceneObject() : SceneHotspot() {
_visage = 0;
_strip = 0;
_frame = 0;
- _effect = 0;
- _shade = _shade2 = 0;
+ _effect = EFFECT_NONE;
+ _shade = _oldShade = 0;
_linkedActor = NULL;
- _field8A = Common::Point(0, 0);
+ _actorDestPos = Common::Point(0, 0);
_angle = 0;
_xs = 0;
_xe = 0;
_endFrame = 0;
- _field68 = 0;
+ _loopCount = 0;
_regionIndex = 0;
- _field9C = NULL;
+ _shadowMap = NULL;
}
SceneObject::SceneObject(const SceneObject &so) : SceneHotspot() {
@@ -2324,7 +2371,7 @@ void SceneObject::animate(AnimateMode animMode, ...) {
case ANIM_MODE_1:
_frameChange = 1;
- _field2E = _position;
+ _oldPosition = _position;
_endAction = 0;
break;
@@ -2372,9 +2419,9 @@ void SceneObject::animate(AnimateMode animMode, ...) {
case ANIM_MODE_9:
if (_animateMode == ANIM_MODE_9 && g_vm->getGameID() == GType_Ringworld2) {
_frameChange = -1;
- _field2E = _position;
+ _oldPosition = _position;
} else {
- _field68 = va_arg(va, int);
+ _loopCount = va_arg(va, int);
_endAction = va_arg(va, Action *);
_frameChange = 1;
_endFrame = getFrameCount();
@@ -2441,7 +2488,7 @@ void SceneObject::synchronize(Serializer &s) {
s.syncAsUint32LE(_updateStartFrame);
s.syncAsUint32LE(_walkStartFrame);
- s.syncAsSint16LE(_field2E.x); s.syncAsSint16LE(_field2E.y);
+ s.syncAsSint16LE(_oldPosition.x); s.syncAsSint16LE(_oldPosition.y);
s.syncAsSint16LE(_percent);
s.syncAsSint16LE(_priority);
s.syncAsSint16LE(_angle);
@@ -2456,7 +2503,7 @@ void SceneObject::synchronize(Serializer &s) {
SYNC_ENUM(_animateMode, AnimateMode);
s.syncAsSint32LE(_frame);
s.syncAsSint32LE(_endFrame);
- s.syncAsSint32LE(_field68);
+ s.syncAsSint32LE(_loopCount);
s.syncAsSint32LE(_frameChange);
s.syncAsSint32LE(_numFrames);
s.syncAsSint32LE(_regionIndex);
@@ -2464,8 +2511,8 @@ void SceneObject::synchronize(Serializer &s) {
s.syncAsSint16LE(_moveDiff.x); s.syncAsSint16LE(_moveDiff.y);
s.syncAsSint32LE(_moveRate);
if (g_vm->getGameID() == GType_Ringworld2) {
- s.syncAsSint16LE(_field8A.x);
- s.syncAsSint16LE(_field8A.y);
+ s.syncAsSint16LE(_actorDestPos.x);
+ s.syncAsSint16LE(_actorDestPos.y);
}
SYNC_POINTER(_endAction);
s.syncAsUint32LE(_regionBitList);
@@ -2473,7 +2520,7 @@ void SceneObject::synchronize(Serializer &s) {
if (g_vm->getGameID() == GType_Ringworld2) {
s.syncAsSint16LE(_effect);
s.syncAsSint16LE(_shade);
- s.syncAsSint16LE(_shade2);
+ s.syncAsSint16LE(_oldShade);
SYNC_POINTER(_linkedActor);
}
}
@@ -2482,7 +2529,8 @@ void SceneObject::postInit(SceneObjectList *OwnerList) {
if (!OwnerList)
OwnerList = g_globals->_sceneObjects;
- if (!OwnerList->contains(this) || ((_flags & OBJFLAG_REMOVE) != 0)) {
+ bool isExisting = OwnerList->contains(this);
+ if (!isExisting || ((_flags & OBJFLAG_REMOVE) != 0)) {
_percent = 100;
_priority = 255;
_flags = OBJFLAG_ZOOMED;
@@ -2501,7 +2549,8 @@ void SceneObject::postInit(SceneObjectList *OwnerList) {
_numFrames = 10;
_regionBitList = 0;
- OwnerList->push_back(this);
+ if (!isExisting)
+ OwnerList->push_back(this);
_flags |= OBJFLAG_PANES;
}
}
@@ -2519,9 +2568,9 @@ void SceneObject::remove() {
void SceneObject::dispatch() {
if (g_vm->getGameID() == GType_Ringworld2) {
- if (_shade != _shade2)
+ if (_shade != _oldShade)
_flags |= OBJFLAG_PANES;
- _shade2 = _shade;
+ _oldShade = _shade;
}
uint32 currTime = g_globals->_events.getFrameNumber();
@@ -2541,9 +2590,9 @@ void SceneObject::dispatch() {
case ANIM_MODE_1:
if (isNoMover())
setFrame(1);
- else if ((_field2E.x != _position.x) || (_field2E.y != _position.y)) {
+ else if ((_oldPosition.x != _position.x) || (_oldPosition.y != _position.y)) {
setFrame(changeFrame());
- _field2E = _position;
+ _oldPosition = _position;
}
break;
@@ -2586,7 +2635,7 @@ void SceneObject::dispatch() {
_endFrame = 1;
setFrame(changeFrame());
- } else if (!_field68 || (--_field68 > 0)) {
+ } else if (!_loopCount || (--_loopCount > 0)) {
_frameChange = 1;
_endFrame = getFrameCount();
@@ -2605,7 +2654,7 @@ void SceneObject::dispatch() {
_frameChange = -1;
_strip = ((_strip - 1) ^ 1) + 1;
_endFrame = 1;
- } else if ((_field68 == 0) || (--_field68 != 0)) {
+ } else if (!_loopCount || (--_loopCount > 0)) {
_frameChange = 1;
_endFrame = getFrameCount();
@@ -2639,8 +2688,9 @@ void SceneObject::dispatch() {
_linkedActor->setFrame(_frame);
}
- if ((_effect == 1) && (getRegionIndex() < 11))
- _shade = 0;
+ int regionIndex = getRegionIndex();
+ if ((_effect == EFFECT_SHADED) && (regionIndex < 11))
+ _shade = regionIndex;
}
}
@@ -2669,11 +2719,46 @@ void SceneObject::removeObject() {
GfxSurface SceneObject::getFrame() {
_visageImages.setVisage(_visage, _strip);
- return _visageImages.getFrame(_frame);
+ GfxSurface frame = _visageImages.getFrame(_frame);
+
+ // Reset any centroid adjustment flags, in
+ frame._flags &= ~(FRAME_FLIP_CENTROID_X | FRAME_FLIP_CENTROID_Y);
+
+ // For later games, check whether the appropriate object flags are set for flipping
+ if (g_vm->getGameID() != GType_Ringworld) {
+ if ((_flags & OBJFLAG_FLIP_CENTROID_X) || _visageImages._flipHoriz)
+ frame._flags |= FRAME_FLIP_CENTROID_X;
+ if ((_flags & OBJFLAG_FLIP_CENTROID_Y) || _visageImages._flipVert)
+ frame._flags |= FRAME_FLIP_CENTROID_Y;
+ }
+
+ // If shading is needed, post apply the shadiing onto the frame
+ if ((g_vm->getGameID() == GType_Ringworld2) && (_shade >= 1)) {
+ Graphics::Surface s = frame.lockSurface();
+ byte *p = (byte *)s.getPixels();
+ byte *endP = p + s.w * s.h;
+
+ while (p < endP) {
+ if (*p != frame._transColor)
+ *p = R2_GLOBALS._fadePaletteMap[_shade - 1][*p];
+ ++p;
+ }
+
+ frame.unlockSurface();
+ }
+
+ return frame;
}
void SceneObject::reposition() {
+ if (g_vm->getGameID() == GType_Ringworld2) {
+ if (!(_flags & OBJFLAG_ZOOMED)) {
+ setZoom(g_globals->_sceneManager._scene->_zoomPercents[MIN(_position.y, (int16)255)]);
+ }
+ }
+
GfxSurface frame = getFrame();
+
_bounds.resize(frame, _position.x, _position.y - _yDiff, _percent);
_xs = _bounds.left;
_xe = _bounds.right;
@@ -2684,11 +2769,27 @@ void SceneObject::reposition() {
*/
void SceneObject::draw() {
Rect destRect = _bounds;
- destRect.translate(-g_globals->_sceneManager._scene->_sceneBounds.left,
- -g_globals->_sceneManager._scene->_sceneBounds.top);
- Region *priorityRegion = g_globals->_sceneManager._scene->_priorities.find(_priority);
+ Scene *scene = g_globals->_sceneManager._scene;
+ destRect.translate(-scene->_sceneBounds.left, -scene->_sceneBounds.top);
GfxSurface frame = getFrame();
- g_globals->gfxManager().copyFrom(frame, destRect, priorityRegion);
+ Region *priorityRegion = scene->_priorities.find(_priority);
+
+ if (g_vm->getGameID() == GType_Ringworld2) {
+ switch (_effect) {
+ case EFFECT_SHADOW_MAP: {
+ if (!_shadowMap)
+ _shadowMap = static_cast<Ringworld2::SceneExt *>(scene)->_shadowPaletteMap;
+
+ GLOBALS.gfxManager().getSurface().copyFrom(frame, frame.getBounds(),
+ destRect, priorityRegion, _shadowMap);
+ return;
+ }
+ default:
+ break;
+ }
+ }
+
+ GLOBALS.gfxManager().copyFrom(frame, destRect, priorityRegion);
}
/**
@@ -2790,10 +2891,17 @@ void BackgroundSceneObject::setup2(int visage, int stripFrameNum, int frameNum,
setFrame(frameNum);
setPosition(Common::Point(posX, posY));
fixPriority(priority);
+
+ _effect = effect;
}
void BackgroundSceneObject::copySceneToBackground() {
GLOBALS._sceneManager._scene->_backSurface.copyFrom(g_globals->gfxManager().getSurface(), 0, 0);
+
+ // WORKAROUND: Since savegames don't store the active screen data, once we copy the
+ // foreground objects to the background, we have to prevent the scene being saved.
+ if (g_vm->getGameID() == GType_Ringworld2)
+ ((Ringworld2::SceneExt *)GLOBALS._sceneManager._scene)->_preventSaving = true;
}
/*--------------------------------------------------------------------------*/
@@ -2856,8 +2964,9 @@ void SceneObjectList::draw() {
g_globals->_sceneManager._sceneBgOffset.y);
}
- // Set up the flag mask
- uint32 flagMask = (paneNum == 0) ? OBJFLAG_PANE_0 : OBJFLAG_PANE_1;
+ // Set up the flag mask. Currently, paneNum is always set to 0, so the check is meaningless
+ // uint32 flagMask = (paneNum == 0) ? OBJFLAG_PANE_0 : OBJFLAG_PANE_1;
+ uint32 flagMask = OBJFLAG_PANE_0;
// Initial loop to set up object list and update object position, priority, and flags
for (SynchronizedList<SceneObject *>::iterator i = g_globals->_sceneObjects->begin();
@@ -3260,7 +3369,6 @@ Player::Player(): SceneObject() {
_canWalk = false;
_enabled = false;
_uiEnabled = false;
- _field8C = 0;
// Return to Ringworld specific fields
_characterIndex = R2_NONE;
@@ -3279,18 +3387,14 @@ void Player::postInit(SceneObjectList *OwnerList) {
_canWalk = true;
_uiEnabled = true;
_percent = 100;
- _field8C = 10;
- if (g_vm->getGameID() != GType_Ringworld2)
- {
+ if (g_vm->getGameID() != GType_Ringworld2) {
_moveDiff.x = 4;
_moveDiff.y = 2;
- }
- else
- {
+ } else {
_moveDiff.x = 3;
_moveDiff.y = 2;
- _effect = 1;
+ _effect = EFFECT_SHADED;
_shade = 0;
_linkedActor = NULL;
@@ -3304,20 +3408,24 @@ void Player::postInit(SceneObjectList *OwnerList) {
void Player::disableControl() {
_canWalk = false;
- _uiEnabled = false;
g_globals->_events.setCursor(CURSOR_NONE);
_enabled = false;
- if ((g_vm->getGameID() != GType_Ringworld) && T2_GLOBALS._uiElements._active)
- T2_GLOBALS._uiElements.hide();
+ if (g_vm->getGameID() != GType_Ringworld2) {
+ _uiEnabled = false;
+
+ if ((g_vm->getGameID() != GType_Ringworld) && T2_GLOBALS._uiElements._active)
+ T2_GLOBALS._uiElements.hide();
+ }
}
void Player::enableControl() {
CursorType cursor;
_canWalk = true;
- _uiEnabled = true;
_enabled = true;
+ if (g_vm->getGameID() != GType_Ringworld2)
+ _uiEnabled = true;
switch (g_vm->getGameID()) {
case GType_BlueForce:
@@ -3325,7 +3433,7 @@ void Player::enableControl() {
cursor = g_globals->_events.getCursor();
g_globals->_events.setCursor(cursor);
- if (T2_GLOBALS._uiElements._active)
+ if (g_vm->getGameID() == GType_BlueForce && T2_GLOBALS._uiElements._active)
T2_GLOBALS._uiElements.show();
break;
@@ -3391,7 +3499,10 @@ void Player::synchronize(Serializer &s) {
s.syncAsByte(_canWalk);
s.syncAsByte(_uiEnabled);
- s.syncAsSint16LE(_field8C);
+ if (s.getVersion() < 15) {
+ int useless = 0;
+ s.syncAsSint16LE(useless);
+ }
if (g_vm->getGameID() != GType_Ringworld)
s.syncAsByte(_enabled);
@@ -4139,7 +4250,6 @@ double FloatSet::sqrt(FloatSet &floatSet) {
GameHandler::GameHandler() : EventHandler() {
_nextWaitCtr = 1;
_waitCtr.setCtr(1);
- _field14 = 10;
}
GameHandler::~GameHandler() {
@@ -4161,7 +4271,11 @@ void GameHandler::synchronize(Serializer &s) {
_lockCtr.synchronize(s);
_waitCtr.synchronize(s);
s.syncAsSint16LE(_nextWaitCtr);
- s.syncAsSint16LE(_field14);
+
+ if (s.getVersion() < 14) {
+ int useless = 0;
+ s.syncAsSint16LE(useless);
+ }
}
/*--------------------------------------------------------------------------*/
@@ -4235,11 +4349,11 @@ void SceneHandler::process(Event &event) {
g_vm->_debugger->onFrame();
}
- if ((event.eventType == EVENT_KEYPRESS) && g_globals->_player._enabled && g_globals->_player._canWalk) {
+ if ((event.eventType == EVENT_KEYPRESS) && g_globals->_player._enabled) {
// Keyboard shortcuts for different actions
switch (event.kbd.keycode) {
case Common::KEYCODE_w:
- g_globals->_events.setCursor(CURSOR_WALK);
+ g_globals->_events.setCursor(GLOBALS._player._canWalk ? CURSOR_WALK : CURSOR_USE);
event.handled = true;
break;
case Common::KEYCODE_l:
@@ -4273,7 +4387,7 @@ void SceneHandler::process(Event &event) {
// Scan the item list to find one the mouse is within
SynchronizedList<SceneItem *>::iterator i;
for (i = g_globals->_sceneItems.begin(); i != g_globals->_sceneItems.end(); ++i) {
- SceneItem *item = *i;
+ SceneItem *item = *i;
if (item->contains(event.mousePos)) {
// Pass the action to the item
bool handled = item->startAction(g_globals->_events.getCursor(), event);