TSAGE: Added new walking code for Blue Force that uses flipped horizontal images

This commit is contained in:
Paul Gilbert 2011-09-06 19:54:22 +10:00
parent e6162f1a78
commit ad85a25f88
2 changed files with 66 additions and 27 deletions

View File

@ -22,6 +22,7 @@
#include "common/system.h"
#include "common/config-manager.h"
#include "common/util.h"
#include "engines/engine.h"
#include "graphics/palette.h"
#include "tsage/tsage.h"
@ -307,8 +308,12 @@ void ObjectMover::dispatch() {
void ObjectMover::setup(const Common::Point &destPos) {
_sceneObject->calcAngle(destPos);
if ((_sceneObject->_objectWrapper) && !(_sceneObject->_flags & OBJFLAG_SUPPRESS_DISPATCH))
_sceneObject->_objectWrapper->dispatch();
if ((_sceneObject->_objectWrapper) && !(_sceneObject->_flags & OBJFLAG_SUPPRESS_DISPATCH)) {
if (_vm->getGameID() == GType_Ringworld)
_sceneObject->_objectWrapper->dispatch();
else
_sceneObject->updateAngle(destPos);
}
// Get the difference
int diffX = destPos.x - _sceneObject->_position.x;
@ -1799,11 +1804,11 @@ void SceneObjectWrapper::dispatch() {
void SceneObjectWrapper::check() {
_visageImages.setVisage(_sceneObject->_visage);
int frameCount = _visageImages.getFrameCount();
int visageCount = _visageImages.getFrameCount();
int angle = _sceneObject->_angle;
int strip = _sceneObject->_strip;
if (frameCount == 4) {
if (visageCount == 4) {
if ((angle > 314) || (angle < 45))
strip = 4;
if ((angle > 44) && (angle < 135))
@ -1812,7 +1817,7 @@ void SceneObjectWrapper::check() {
strip = 3;
if ((angle >= 225) && (angle < 315))
strip = 2;
} else if (frameCount == 8) {
} else if (visageCount == 8) {
if ((angle > 330) || (angle < 30))
strip = 4;
if ((angle >= 30) && (angle < 70))
@ -1831,8 +1836,8 @@ void SceneObjectWrapper::check() {
strip = 8;
}
if (strip > frameCount)
strip = frameCount;
if (strip > visageCount)
strip = visageCount;
_sceneObject->setStrip(strip);
}
@ -2165,9 +2170,16 @@ SceneObject *SceneObject::clone() const {
}
void SceneObject::checkAngle(const SceneObject *obj) {
_angle = GfxManager::getAngle(_position, obj->_position);
checkAngle(obj->_position);
}
if (_objectWrapper)
void SceneObject::checkAngle(const Common::Point &pt) {
int angleAmount = GfxManager::getAngle(_position, pt);
if ((_vm->getGameID() == GType_Ringworld) ||
((angleAmount != -1) && (_animateMode == ANIM_MODE_9)))
_angle = angleAmount;
if (_objectWrapper && (_vm->getGameID() == GType_Ringworld))
_objectWrapper->dispatch();
}
@ -2438,8 +2450,8 @@ void SceneObject::updateScreen() {
}
}
void SceneObject::updateAngle(SceneObject *sceneObj) {
checkAngle(sceneObj);
void SceneObject::updateAngle(const Common::Point &pt) {
checkAngle(pt);
if (_objectWrapper)
_objectWrapper->check();
}
@ -2780,8 +2792,10 @@ void SceneText::synchronize(Serializer &s) {
}
void SceneText::updateScreen() {
// In Blue Force, stop clearing text in the user interface area screwing up user interface
if ((_vm->getGameID() != GType_BlueForce) || (_bounds.top < BF_INTERFACE_Y))
// FIXME: Hack for Blue Force to handle not refreshing the screen if the user interface
// has been re-activated after showing some scene text
if ((_vm->getGameID() != GType_BlueForce) || (_bounds.top < BF_INTERFACE_Y) ||
!BF_GLOBALS._uiElements._active)
SceneObject::updateScreen();
}
@ -2791,6 +2805,7 @@ Visage::Visage() {
_resNum = -1;
_rlbNum = -1;
_data = NULL;
_flipHoriz = false;
}
Visage::Visage(const Visage &v) {
@ -2821,20 +2836,25 @@ void Visage::setVisage(int resNum, int rlbNum) {
// In Ringworld, we immediately get the data
_data = _resourceManager->getResource(RES_VISAGE, resNum, rlbNum);
} else {
// Blue Force has an extra indirection via a visage index file
// Blue Force has an extra indirection via the visage index file
byte *indexData = _resourceManager->getResource(RES_VISAGE, resNum, 9999);
if (rlbNum == 0)
rlbNum = 1;
if (rlbNum == 9999) {
_data = indexData;
} else {
if (rlbNum == 0)
rlbNum = 1;
// Get the flags/rlbNum to use
uint32 flags = READ_LE_UINT32(indexData + (rlbNum - 1) * 4 + 2);
// Get the flags/rlbNum to use
uint32 v = READ_LE_UINT32(indexData + (rlbNum - 1) * 4 + 2);
int flags = v >> 30;
if (flags & 0xC0000000) {
// TODO: See whether rest of flags dword is needed
rlbNum = (int)(flags & 0xff);
if (flags & 3) {
rlbNum = (int)(v & 0xff);
}
_flipHoriz = flags & 1;
_data = _resourceManager->getResource(RES_VISAGE, resNum, rlbNum);
}
_data = _resourceManager->getResource(RES_VISAGE, resNum, rlbNum);
}
assert(_data);
@ -2855,13 +2875,28 @@ GfxSurface Visage::getFrame(int frameNum) {
int offset = READ_LE_UINT32(_data + 2 + frameNum * 4);
byte *frameData = _data + offset;
return surfaceFromRes(frameData);
GfxSurface result = surfaceFromRes(frameData);
if (_flipHoriz) flip(result);
return result;
}
int Visage::getFrameCount() const {
return READ_LE_UINT16(_data);
}
void Visage::flip(GfxSurface &gfxSurface) {
Graphics::Surface s = gfxSurface.lockSurface();
for (int y = 0; y < s.h; ++y) {
// Flip the line
byte *lineP = (byte *)s.getBasePtr(0, y);
for (int x = 0; x < (s.w / 2); ++x)
SWAP(lineP[x], lineP[s.w - x - 1]);
}
gfxSurface.unlockSurface();
}
/*--------------------------------------------------------------------------*/
Player::Player(): SceneObject() {

View File

@ -467,9 +467,12 @@ class SceneObject;
class Visage {
private:
byte *_data;
void flip(GfxSurface &s);
public:
int _resNum;
int _rlbNum;
bool _flipHoriz;
public:
Visage();
Visage(const Visage &v);
@ -478,7 +481,7 @@ public:
void setVisage(int resNum, int rlbNum = 9999);
GfxSurface getFrame(int frameNum);
int getFrameCount() const;
Visage &operator=(const Visage &s);
Visage &operator=(const Visage &gfxSurface);
};
class SceneObjectWrapper : public EventHandler {
@ -562,6 +565,7 @@ public:
void animate(AnimateMode animMode, ...);
SceneObject *clone() const;
void checkAngle(const SceneObject *obj);
void checkAngle(const Common::Point &pt);
void hide();
void show();
int getSpliceArea(const SceneObject *obj);
@ -580,8 +584,8 @@ public:
virtual void draw();
virtual void proc19() {}
virtual void updateScreen();
// New methods introduced by Blue FOrce
virtual void updateAngle(SceneObject *sceneObj);
// New methods introduced by Blue Force
virtual void updateAngle(const Common::Point &pt);
virtual void changeAngle(int angle);
void setup(int visage, int stripFrameNum, int frameNum, int posX, int posY, int priority);