TSAGE: Implemented the initial loading logic for R2R animation player

This commit is contained in:
Paul Gilbert 2012-02-26 17:29:45 +11:00
parent 69e7e11743
commit d5127d49ee
8 changed files with 158 additions and 36 deletions

View File

@ -1354,13 +1354,15 @@ void ScenePalette::setEntry(int index, uint r, uint g, uint b) {
* @param g G component
* @param b B component
* @param threshold Closeness threshold.
* @param start Starting index
* @param count Number of indexes to scan
* @remarks A threshold may be provided to specify how close the matching color must be
*/
uint8 ScenePalette::indexOf(uint r, uint g, uint b, int threshold) {
uint8 ScenePalette::indexOf(uint r, uint g, uint b, int threshold, int start, int count) {
int palIndex = -1;
byte *palData = &_palette[0];
for (int i = 0; i < 256; ++i) {
for (int i = start; i < (start + count); ++i) {
byte ir = *palData++;
byte ig = *palData++;
byte ib = *palData++;

View File

@ -378,7 +378,7 @@ public:
void setPalette(int index, int count);
void getEntry(int index, uint *r, uint *g, uint *b);
void setEntry(int index, uint r, uint g, uint b);
uint8 indexOf(uint r, uint g, uint b, int threshold = 0xffff);
uint8 indexOf(uint r, uint g, uint b, int threshold = 0xffff, int start = 0, int count = 256);
void getPalette(int start = 0, int count = 256);
void signalListeners();
void clearListeners();

View File

@ -380,6 +380,7 @@ void Ringworld2Globals::reset() {
_v5589E.set(0, 0, 0, 0);
_v558B6.set(0, 0, 0, 0);
_v558C2 = 0;
_animationCtr = 0;
_v5657C = 0;
_v565E1 = 0;
_v565E3 = 0;
@ -493,6 +494,7 @@ void Ringworld2Globals::synchronize(Serializer &s) {
_v558B6.synchronize(s);
s.syncAsSint16LE(_v558C2);
s.syncAsSint16LE(_animationCtr);
s.syncAsSint16LE(_v5657C);
s.syncAsSint16LE(_v565E1);
s.syncAsSint16LE(_v565E3);

View File

@ -260,6 +260,7 @@ public:
Rect _v5589E;
Rect _v558B6;
int _v558C2;
int _animationCtr;
int _v565E1;
int _v565E3;
int _v565E5;

View File

@ -1551,14 +1551,52 @@ void Scene1200::sub9DAD6(int indx) {
/*--------------------------------------------------------------------------*/
void AnimationSplice::load(Common::File &f) {
_spliceOffset = f.readUint32LE();
f.skip(6);
_drawMode = f.readByte();
_fieldB = f.readByte();
}
/*--------------------------------------------------------------------------*/
AnimationSplices::AnimationSplices() {
_pixelData = NULL;
}
AnimationSplices::~AnimationSplices() {
delete[] _pixelData;
}
void AnimationSplices::load(Common::File &f) {
f.skip(4);
_dataSize = f.readUint32LE();
f.skip(40);
// Load the four splice indexes
for (int idx = 0; idx < 4; ++idx)
_splices[idx].load(f);
}
int AnimationSplices::loadPixels(Common::File &f, int splicesSize) {
delete[] _pixelData;
_pixelData = new byte[splicesSize];
return f.read(_pixelData, splicesSize);
}
/*--------------------------------------------------------------------------*/
void AnimationPlayerSubData::load(Common::File &f) {
uint32 posStart = f.pos();
f.skip(6);
_field6 = f.readUint16LE();
f.skip(2);
_fieldA = f.readUint16LE();
_fieldC = f.readUint16LE();
f.skip(4);
_field12 = f.readUint16LE();
_fieldE = f.readUint16LE();
f.skip(2);
_sliceSize = f.readUint16LE();
_field14 = f.readUint16LE();
_field16 = f.readUint16LE();
f.skip(4);
@ -1567,7 +1605,10 @@ void AnimationPlayerSubData::load(Common::File &f) {
f.read(_palData, 768);
_field320 = f.readSint32LE();
f.skip(12);
f.read(_field330, 96);
_splices.load(f);
uint32 posEnd = f.pos();
assert((posEnd - posStart) == 0x390);
}
/*--------------------------------------------------------------------------*/
@ -1575,14 +1616,14 @@ void AnimationPlayerSubData::load(Common::File &f) {
AnimationPlayer::AnimationPlayer(): EventHandler() {
_endAction = NULL;
_fieldA = NULL;
_field16 = NULL;
_animData1 = NULL;
_animData2 = NULL;
_screenBounds = R2_GLOBALS._gfxManagerInstance._bounds;
_rect1 = R2_GLOBALS._gfxManagerInstance._bounds;
_field3C = 0;
_paletteMode = 0;
_field3A = 1;
_field5A = 0;
_sliceHeight = 0;
_field58 = 0;
_endAction = NULL;
}
@ -1590,6 +1631,9 @@ AnimationPlayer::AnimationPlayer(): EventHandler() {
AnimationPlayer::~AnimationPlayer() {
if (!method3())
method4();
delete[] _animData;
delete[] _animData2;
}
void AnimationPlayer::synchronize(Serializer &s) {
@ -1654,33 +1698,71 @@ bool AnimationPlayer::load(int animId, Action *endAction) {
_gameFrame = R2_GLOBALS._events.getFrameNumber() - _field910;
if (_subData._field320) {
_field900 = _subData._field320;
_dataNeeded = _subData._field320;
} else {
int v = (_subData._field12 + 2) * _subData._field14 * _subData._fieldC;
_field900 = (_subData._field16 / _subData._fieldC) + v + 96;
int v = (_subData._sliceSize + 2) * _subData._field14 * _subData._fieldC;
_dataNeeded = (_subData._field16 / _subData._fieldC) + v + 96;
}
debugC(1, ktSageDebugGraphics, "Data needed %d", _dataNeeded);
_animData = _fieldA = new byte[_field900];
// Set up animation data array
_animData1 = new AnimationData[_dataNeeded / 60];
_animData = _animData1;
if (_subData._fieldC <= 1) {
_subData._field16 = NULL;
_animData2 = NULL;
_animPtr = _animData;
} else {
_field16 = new byte[_field900];
_animPtr = _field16;
_animData2 = new AnimationData[_dataNeeded / 60];
_animPtr = _animData2;
}
_field90C = 0;
_field90E = 1;
// TODO: Stuff
if (_field3C) {
// Load up the first splices set
_animData->_dataSize = _subData._splices._dataSize;
_animData->_splices = _subData._splices;
int splicesSize = _animData->_dataSize - 96;
int readSize = _animData->_splices.loadPixels(_resourceFile, splicesSize);
_animData->_animSlicesSize = readSize + 96;
if (_animPtr != _animData) {
getSlices();
}
// Handle starting palette
switch (_paletteMode) {
case 0:
// Use existing active palette
_palette.getPalette();
for (int idx = _subData._palStart; idx < (_subData._palStart + _subData._palSize); ++idx) {
uint r, g, b;
_palette.getEntry(idx, &r, &g, &b);
R2_GLOBALS._scenePalette.setEntry(idx, r, g, b);
}
return false;
R2_GLOBALS._sceneManager._hasPalette = true;
break;
case 2:
break;
default:
for (int idx = _subData._palStart; idx < (_subData._palStart + _subData._palSize); ++idx) {
byte r = _subData._palData[idx * 3];
byte g = _subData._palData[idx * 3 + 1];
byte b = _subData._palData[idx * 3 + 2];
int palIndex = R2_GLOBALS._scenePalette.indexOf(r, g, b);
_palIndexes[idx] = palIndex;
}
break;
}
++R2_GLOBALS._animationCtr;
_field38 = 1;
return true;
}
void AnimationPlayer::drawFrame(int frameIndex) {
@ -1713,7 +1795,7 @@ bool AnimationPlayer::method3() {
void AnimationPlayer::method4() {
if (_field38) {
switch (_field3C) {
switch (_paletteMode) {
case 0:
R2_GLOBALS._scenePalette.replace(&_palette);
changePane();

View File

@ -325,38 +325,71 @@ public:
virtual Common::String getClassName() { return "UnkObject1200"; }
};
/*--------------------------------------------------------------------------*/
class AnimationSplice {
public:
int _spliceOffset;
int _drawMode;
int _fieldB;
public:
void load(Common::File &f);
};
class AnimationSplices {
public:
int _dataSize;
AnimationSplice _splices[4];
byte *_pixelData;
public:
AnimationSplices();
~AnimationSplices();
void load(Common::File &f);
int loadPixels(Common::File &f, int splicesSize);
};
class AnimationPlayerSubData {
public:
int _field6;
int _fieldA;
int _fieldC;
int _field12;
int _fieldE;
int _sliceSize;
int _field14;
int _field16;
int _palStart;
int _palSize;
byte _palData[256 * 3];
int32 _field320;
byte _field330[96];
AnimationSplices _splices;
public:
void load(Common::File &f);
};
class AnimationData {
public:
AnimationSplices _splices;
int _dataSize;
int _animSlicesSize;
};
class AnimationPlayer: public EventHandler {
public:
byte *_fieldA;
byte *_field16;
byte *_animData, *_animPtr;
AnimationData *_animData;
AnimationData *_animData1, *_animData2;
AnimationData *_animPtr;
Common::File _resourceFile;
Rect _rect1, _screenBounds;
int _field38;
int _field3A, _field3C;
int _field3A, _paletteMode;
int _field56;
int _field58, _field5A;
int _field58, _sliceHeight;
byte _palIndexes[256];
ScenePalette _palette;
AnimationPlayerSubData _subData;
Action *_endAction;
int _field900;
int _dataNeeded;
int _field904;
int _field908;
int _field90C;
@ -381,6 +414,7 @@ public:
bool method3();
void method4();
void method5() {}
void getSlices() {}
};
class AnimationPlayerExt: public AnimationPlayer {

View File

@ -1555,7 +1555,7 @@ void Scene180::signal() {
case 1:
_field412 = 1;
R2_GLOBALS._sceneManager._hasPalette = true;
_animationPlayer._field3C = 2;
_animationPlayer._paletteMode = 2;
_animationPlayer._v = 1;
_animationPlayer._field56 = 1;
R2_GLOBALS._scene180Mode = 1;
@ -1598,7 +1598,7 @@ void Scene180::signal() {
break;
case 5:
_animationPlayer._field3C = 2;
_animationPlayer._paletteMode = 2;
_animationPlayer._v = 1;
_animationPlayer._field56 = 1;
R2_GLOBALS._scene180Mode = 2;
@ -1701,7 +1701,7 @@ void Scene180::signal() {
case 29:
_field412 = 1;
_animationPlayer._field3C = 0;
_animationPlayer._paletteMode = 0;
_animationPlayer._v = 1;
_animationPlayer._field56 = 42;
R2_GLOBALS._scene180Mode = 3;
@ -1801,7 +1801,7 @@ void Scene180::signal() {
break;
case 40:
_animationPlayer._field3C = 2;
_animationPlayer._paletteMode = 2;
_animationPlayer._field56 = 1;
R2_GLOBALS._scene180Mode = 4;
if (_animationPlayer.load(4)) {
@ -1839,7 +1839,7 @@ void Scene180::signal() {
case 48:
_field412 = 1;
_animationPlayer._field3C = 2;
_animationPlayer._paletteMode = 2;
_animationPlayer._v = 1;
_animationPlayer._field56 = 1;
R2_GLOBALS._scene180Mode = 15;

View File

@ -54,7 +54,8 @@ enum {
enum {
kRingDebugScripts = 1 << 0,
ktSageSound = 1 << 1,
ktSageCore = 1 << 2
ktSageCore = 1 << 2,
ktSageDebugGraphics = 1 << 3
};
struct tSageGameDescription;