aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/pink/cel_decoder.cpp103
-rw-r--r--engines/pink/cel_decoder.h17
-rw-r--r--engines/pink/director.cpp7
-rw-r--r--engines/pink/module.mk1
-rw-r--r--engines/pink/objects/actions/action_cel.cpp21
-rw-r--r--engines/pink/objects/actions/action_cel.h6
-rw-r--r--engines/pink/objects/actions/action_play.cpp7
-rw-r--r--engines/pink/objects/actions/action_still.cpp3
-rw-r--r--engines/pink/objects/pages/page.cpp2
-rw-r--r--engines/pink/objects/pages/page.h2
-rw-r--r--engines/pink/resource_mgr.cpp5
-rw-r--r--engines/pink/resource_mgr.h3
12 files changed, 153 insertions, 24 deletions
diff --git a/engines/pink/cel_decoder.cpp b/engines/pink/cel_decoder.cpp
index 5d20e415d3..bff0e4a5bc 100644
--- a/engines/pink/cel_decoder.cpp
+++ b/engines/pink/cel_decoder.cpp
@@ -20,6 +20,107 @@
*
*/
+#include <common/stream.h>
+#include "cel_decoder.h"
+
namespace Pink {
-} \ No newline at end of file
+bool CelDecoder::loadStream(Common::SeekableReadStream *stream) {
+ close();
+
+ /* uint32 frameSize = */ stream->readUint32LE();
+ uint16 frameType = stream->readUint16LE();
+
+ // Check FLC magic number
+ if (frameType != 0xAF12) {
+ warning("FlicDecoder::loadStream(): attempted to load non-FLC data (type = 0x%04X)", frameType);
+ return false;
+ }
+
+ uint16 frameCount = stream->readUint16LE();
+ uint16 width = stream->readUint16LE();
+ uint16 height = stream->readUint16LE();
+ uint16 colorDepth = stream->readUint16LE();
+ if (colorDepth != 8) {
+ warning("FlicDecoder::loadStream(): attempted to load an FLC with a palette of color depth %d. Only 8-bit color palettes are supported", colorDepth);
+ return false;
+ }
+
+ addTrack(new CelVideoTrack(stream, frameCount, width, height));
+ return true;
+}
+
+uint32 CelDecoder::getX(){
+ CelVideoTrack *track = (CelVideoTrack*) getTrack(0);
+ if (!track)
+ return -1;
+ return track->getX();
+}
+
+uint32 CelDecoder::getY() {
+ CelVideoTrack *track = (CelVideoTrack*) getTrack(0);
+ if (!track)
+ return -1;
+ return track->getY();
+}
+
+CelDecoder::CelVideoTrack::CelVideoTrack(Common::SeekableReadStream *stream, uint16 frameCount, uint16 width, uint16 height, bool skipHeader)
+ : FlicVideoTrack(stream, frameCount, width, height, 1) {
+ readHeader();
+}
+
+#define PREFIX_TYPE 0xF100
+#define CEL_DATA 3
+
+void CelDecoder::CelVideoTrack::readPrefixChunk() {
+ _fileStream->seek(0x80);
+ uint32 chunkSize = _fileStream->readUint32LE();
+ uint16 chunkType = _fileStream->readUint16LE();
+ if (chunkType != PREFIX_TYPE)
+ return;
+ uint32 offset = 6;
+ while (offset < chunkSize) {
+ uint32 subchunkSize = _fileStream->readUint32LE();
+ uint16 subchunkType = _fileStream->readUint16LE();
+ switch (subchunkType) {
+ case CEL_DATA:
+ _fileStream->skip(2); // Unknown field
+ _center.x = _fileStream->readUint16LE();
+ _center.y = _fileStream->readUint16LE();
+ _fileStream->skip(subchunkSize - 6 - 6);
+ break;
+ default:
+ _fileStream->skip(subchunkSize - 6);
+ break;
+ }
+ offset += subchunkSize;
+ }
+}
+
+void CelDecoder::CelVideoTrack::readHeader() {
+ _fileStream->readUint16LE(); // flags
+ // Note: The normal delay is a 32-bit integer (dword), whereas the overridden delay is a 16-bit integer (word)
+ // the frame delay is the FLIC "speed", in milliseconds.
+ _frameDelay = _startFrameDelay = _fileStream->readUint32LE();
+
+ _fileStream->seek(80);
+ _offsetFrame1 = _fileStream->readUint32LE();
+ _offsetFrame2 = _fileStream->readUint32LE();
+
+ if (_offsetFrame1 > 0x80) {
+ readPrefixChunk();
+ }
+
+ // Seek to the first frame
+ _fileStream->seek(_offsetFrame1);
+}
+
+uint32 CelDecoder::CelVideoTrack::getX() const {
+ return _center.x - getWidth() / 2;
+}
+
+uint32 CelDecoder::CelVideoTrack::getY() const {
+ return _center.y - getHeight() / 2;
+}
+
+} // End of namepsace Pink \ No newline at end of file
diff --git a/engines/pink/cel_decoder.h b/engines/pink/cel_decoder.h
index 0e8d6120e6..c096793f1c 100644
--- a/engines/pink/cel_decoder.h
+++ b/engines/pink/cel_decoder.h
@@ -29,8 +29,25 @@
namespace Pink {
class CelDecoder : public Video::FlicDecoder {
+public:
+ uint32 getX();
+ uint32 getY();
+ virtual bool loadStream(Common::SeekableReadStream *stream);
+protected:
+ class CelVideoTrack : public FlicVideoTrack {
+ public:
+ CelVideoTrack(Common::SeekableReadStream *stream, uint16 frameCount, uint16 width, uint16 height, bool skipHeader = false);
+ virtual void readHeader();
+
+ uint32 getX() const;
+ uint32 getY() const;
+
+ private:
+ void readPrefixChunk();
+ Common::Point _center;
+ };
};
}
diff --git a/engines/pink/director.cpp b/engines/pink/director.cpp
index cdc60c8aa4..f45948b9e7 100644
--- a/engines/pink/director.cpp
+++ b/engines/pink/director.cpp
@@ -24,6 +24,7 @@
#include <engines/pink/objects/actions/action_cel.h>
#include "graphics/surface.h"
#include "graphics/palette.h"
+#include "cel_decoder.h"
namespace Pink {
Director::Director(OSystem *system)
@@ -32,10 +33,12 @@ Director::Director(OSystem *system)
void Director::draw() {
bool needUpdate = 0;
for (int i = 0; i < _sprites.size(); ++i) {
- Video::FlicDecoder *decoder = _sprites[i]->getDecoder();
+ CelDecoder *decoder = _sprites[i]->getDecoder();
if (decoder->needsUpdate()) {
const Graphics::Surface *surface = decoder->decodeNextFrame();
- _system->copyRectToScreen(surface->getPixels(), surface->pitch, 0, 0, surface->w, surface->h);
+ _system->copyRectToScreen(surface->getPixels(), surface->pitch,
+ decoder->getX(), decoder->getY(),
+ surface->w, surface->h);
needUpdate = 1;
}
}
diff --git a/engines/pink/module.mk b/engines/pink/module.mk
index 1b833738b3..4bff006ed0 100644
--- a/engines/pink/module.mk
+++ b/engines/pink/module.mk
@@ -2,6 +2,7 @@ MODULE := engines/pink
MODULE_OBJS = \
archive.o \
+ cel_decoder.o \
console.o \
cursor_mgr.o \
detection.o \
diff --git a/engines/pink/objects/actions/action_cel.cpp b/engines/pink/objects/actions/action_cel.cpp
index 5385386b39..abfc59373e 100644
--- a/engines/pink/objects/actions/action_cel.cpp
+++ b/engines/pink/objects/actions/action_cel.cpp
@@ -26,11 +26,12 @@
#include "engines/pink/archive.h"
#include "engines/pink/objects/pages/game_page.h"
#include "pink/pink.h"
+#include "pink/cel_decoder.h"
namespace Pink {
ActionCEL::ActionCEL()
- : _flicDecoder(nullptr) {
+ : _decoder(nullptr) {
}
@@ -40,30 +41,30 @@ void ActionCEL::deserialize(Archive &archive) {
}
void ActionCEL::start(bool unk) {
- if (!_flicDecoder)
- _flicDecoder = _actor->getPage()->loadCel(_fileName);
+ if (!_decoder)
+ _decoder = _actor->getPage()->loadCel(_fileName);
_actor->getPage()->getGame()->getDirector()->addSprite(this);
this->onStart();
}
void ActionCEL::end() {
_actor->getPage()->getGame()->getDirector()->removeSprite(this);
- delete _flicDecoder;
- _flicDecoder = nullptr;
+ delete _decoder;
+ _decoder = nullptr;
}
uint32 ActionCEL::getZ() {
return _z;
}
-Video::FlicDecoder *ActionCEL::getDecoder() {
- return _flicDecoder;
+CelDecoder *ActionCEL::getDecoder() {
+ return _decoder;
}
bool ActionCEL::initPallete(Director *director) {
- _flicDecoder = _actor->getPage()->loadCel(_fileName);
- _flicDecoder->decodeNextFrame();
- director->setPallette(_flicDecoder->getPalette());
+ _decoder = _actor->getPage()->loadCel(_fileName);
+ _decoder->decodeNextFrame();
+ director->setPallette(_decoder->getPalette());
return 1;
}
diff --git a/engines/pink/objects/actions/action_cel.h b/engines/pink/objects/actions/action_cel.h
index 92986fb1bc..4dc37724df 100644
--- a/engines/pink/objects/actions/action_cel.h
+++ b/engines/pink/objects/actions/action_cel.h
@@ -28,6 +28,8 @@
namespace Pink {
+class CelDecoder;
+
class ActionCEL : public Action {
public:
ActionCEL();
@@ -36,13 +38,13 @@ public:
virtual void end();
uint32 getZ();
- Video::FlicDecoder *getDecoder();
+ CelDecoder *getDecoder();
virtual bool initPallete(Director *director);
protected:
virtual void onStart() {} ;
- Video::FlicDecoder *_flicDecoder;
+ CelDecoder *_decoder;
Common::String _fileName;
uint32 _z;
};
diff --git a/engines/pink/objects/actions/action_play.cpp b/engines/pink/objects/actions/action_play.cpp
index 3945fe62a2..969eacf035 100644
--- a/engines/pink/objects/actions/action_play.cpp
+++ b/engines/pink/objects/actions/action_play.cpp
@@ -24,6 +24,7 @@
#include "action_play.h"
#include "../actors/actor.h"
#include "engines/pink/archive.h"
+#include "pink/cel_decoder.h"
namespace Pink {
@@ -44,10 +45,10 @@ void ActionPlay::end() {
void ActionPlay::onStart() {
debug("Actor %s has now ActionPlay %s", _actor->getName().c_str(), _name.c_str());
- _flicDecoder->seekToFrame(_startFrame);
+ _decoder->seekToFrame(_startFrame);
if (_stopFrame != -1)
- _flicDecoder->setEndFrame(_stopFrame);
- _flicDecoder->start();
+ _decoder->setEndFrame(_stopFrame);
+ _decoder->start();
}
} // End of namespace Pink
diff --git a/engines/pink/objects/actions/action_still.cpp b/engines/pink/objects/actions/action_still.cpp
index 8e90c836bb..563af93c28 100644
--- a/engines/pink/objects/actions/action_still.cpp
+++ b/engines/pink/objects/actions/action_still.cpp
@@ -24,6 +24,7 @@
#include "action_still.h"
#include "engines/pink/archive.h"
#include <engines/pink/objects/actors/actor.h>
+#include "pink/cel_decoder.h"
namespace Pink {
@@ -44,7 +45,7 @@ void ActionStill::end() {
void ActionStill::onStart() {
debug("Actor %s has now ActionStill %s", _actor->getName().c_str(), _name.c_str());
- _flicDecoder->seekToFrame(_startFrame);
+ _decoder->seekToFrame(_startFrame);
}
} // End of namespace Pink \ No newline at end of file
diff --git a/engines/pink/objects/pages/page.cpp b/engines/pink/objects/pages/page.cpp
index dc2bb43c51..a57860e11d 100644
--- a/engines/pink/objects/pages/page.cpp
+++ b/engines/pink/objects/pages/page.cpp
@@ -45,7 +45,7 @@ Sound *Page::loadSound(Common::String &fileName) {
}
-Video::FlicDecoder *Page::loadCel(Common::String &fileName) {
+CelDecoder *Page::loadCel(Common::String &fileName) {
return _resMgr.loadCEL(fileName);
}
diff --git a/engines/pink/objects/pages/page.h b/engines/pink/objects/pages/page.h
index 5244ed9ae9..282d061f1e 100644
--- a/engines/pink/objects/pages/page.h
+++ b/engines/pink/objects/pages/page.h
@@ -40,7 +40,7 @@ public:
void load(Archive &archive);
Actor *findActor(Common::String &name);
Sound* loadSound(Common::String &fileName);
- Video::FlicDecoder *loadCel(Common::String &fileName);
+ CelDecoder *loadCel(Common::String &fileName);
virtual void toConsole();
diff --git a/engines/pink/resource_mgr.cpp b/engines/pink/resource_mgr.cpp
index b367a52e36..c91101ec67 100644
--- a/engines/pink/resource_mgr.cpp
+++ b/engines/pink/resource_mgr.cpp
@@ -28,6 +28,7 @@
#include "pink.h"
#include "sound.h"
#include "engines/pink/objects/pages/game_page.h"
+#include "cel_decoder.h"
namespace Pink {
@@ -77,8 +78,8 @@ PinkEngine *ResourceMgr::getGame() const {
return _game;
}
-Video::FlicDecoder *ResourceMgr::loadCEL(Common::String &name) {
- Video::FlicDecoder *decoder = new Video::FlicDecoder();
+CelDecoder *ResourceMgr::loadCEL(Common::String &name) {
+ CelDecoder *decoder = new CelDecoder();
decoder->loadStream(getResourceStream(name));
return decoder;
}
diff --git a/engines/pink/resource_mgr.h b/engines/pink/resource_mgr.h
index 8d04ec7df7..cc52ee8bd0 100644
--- a/engines/pink/resource_mgr.h
+++ b/engines/pink/resource_mgr.h
@@ -37,6 +37,7 @@ class PinkEngine;
class OrbFile;
class BroFile;
class Sound;
+class CelDecoder;
struct ResourceDescription;
@@ -49,7 +50,7 @@ public:
//Common::String loadText(Common::String &name);
Sound *loadSound(Common::String &name);
- Video::FlicDecoder *loadCEL(Common::String &name);
+ CelDecoder *loadCEL(Common::String &name);
PinkEngine *getGame() const;
private: