From d5127d49ee50e9b3cfb8bcc6643dfb81b49ca96b Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 26 Feb 2012 17:29:45 +1100 Subject: TSAGE: Implemented the initial loading logic for R2R animation player --- engines/tsage/core.cpp | 6 +- engines/tsage/core.h | 2 +- engines/tsage/globals.cpp | 2 + engines/tsage/globals.h | 1 + engines/tsage/ringworld2/ringworld2_logic.cpp | 120 ++++++++++++++++++++---- engines/tsage/ringworld2/ringworld2_logic.h | 50 ++++++++-- engines/tsage/ringworld2/ringworld2_scenes0.cpp | 10 +- engines/tsage/tsage.h | 3 +- 8 files changed, 158 insertions(+), 36 deletions(-) diff --git a/engines/tsage/core.cpp b/engines/tsage/core.cpp index c2ce426052..0a8c4ef1b4 100644 --- a/engines/tsage/core.cpp +++ b/engines/tsage/core.cpp @@ -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++; diff --git a/engines/tsage/core.h b/engines/tsage/core.h index 45bb3506d5..60a7930eab 100644 --- a/engines/tsage/core.h +++ b/engines/tsage/core.h @@ -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(); diff --git a/engines/tsage/globals.cpp b/engines/tsage/globals.cpp index b4c3127ea8..59eb59b194 100644 --- a/engines/tsage/globals.cpp +++ b/engines/tsage/globals.cpp @@ -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); diff --git a/engines/tsage/globals.h b/engines/tsage/globals.h index d80e4d9859..45226c921b 100644 --- a/engines/tsage/globals.h +++ b/engines/tsage/globals.h @@ -260,6 +260,7 @@ public: Rect _v5589E; Rect _v558B6; int _v558C2; + int _animationCtr; int _v565E1; int _v565E3; int _v565E5; diff --git a/engines/tsage/ringworld2/ringworld2_logic.cpp b/engines/tsage/ringworld2/ringworld2_logic.cpp index b420a375a3..8a1030597a 100644 --- a/engines/tsage/ringworld2/ringworld2_logic.cpp +++ b/engines/tsage/ringworld2/ringworld2_logic.cpp @@ -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(); diff --git a/engines/tsage/ringworld2/ringworld2_logic.h b/engines/tsage/ringworld2/ringworld2_logic.h index 651cfec763..4ad0c3b15a 100644 --- a/engines/tsage/ringworld2/ringworld2_logic.h +++ b/engines/tsage/ringworld2/ringworld2_logic.h @@ -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 { diff --git a/engines/tsage/ringworld2/ringworld2_scenes0.cpp b/engines/tsage/ringworld2/ringworld2_scenes0.cpp index 3c9956282a..7d5ab6318d 100644 --- a/engines/tsage/ringworld2/ringworld2_scenes0.cpp +++ b/engines/tsage/ringworld2/ringworld2_scenes0.cpp @@ -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; diff --git a/engines/tsage/tsage.h b/engines/tsage/tsage.h index eb36cf0790..41179c4915 100644 --- a/engines/tsage/tsage.h +++ b/engines/tsage/tsage.h @@ -54,7 +54,8 @@ enum { enum { kRingDebugScripts = 1 << 0, ktSageSound = 1 << 1, - ktSageCore = 1 << 2 + ktSageCore = 1 << 2, + ktSageDebugGraphics = 1 << 3 }; struct tSageGameDescription; -- cgit v1.2.3