PRINCE: installBackAnims implementation, first frames drawing

This commit is contained in:
lukaslw 2014-05-22 19:52:38 +02:00
parent 67956c5805
commit 277ac36761
8 changed files with 138 additions and 30 deletions

View file

@ -117,10 +117,10 @@ Graphics::Surface *Animation::getFrame(uint frameIndex) {
byte *frameData = _data + READ_LE_UINT32(_data + 16 + frameIndex * 4); byte *frameData = _data + READ_LE_UINT32(_data + 16 + frameIndex * 4);
int16 width = READ_LE_UINT16(frameData + 0); int16 width = READ_LE_UINT16(frameData + 0);
int16 height = READ_LE_UINT16(frameData + 2); int16 height = READ_LE_UINT16(frameData + 2);
debug("width = %d; height = %d", width, height); //debug("width = %d; height = %d", width, height);
Graphics::Surface *surf = new Graphics::Surface(); Graphics::Surface *surf = new Graphics::Surface();
surf->create(width, height, Graphics::PixelFormat::createFormatCLUT8()); surf->create(width, height, Graphics::PixelFormat::createFormatCLUT8());
debug("frameData %p", frameData); //debug("frameData %p", frameData);
if (READ_BE_UINT32(frameData + 4) == MKTAG('m', 'a', 's', 'm')) { if (READ_BE_UINT32(frameData + 4) == MKTAG('m', 'a', 's', 'm')) {
// Compressed // Compressed
Decompressor dec; Decompressor dec;

View file

@ -33,7 +33,6 @@ namespace Prince {
class Animation { class Animation {
public: public:
bool loadFromStream(Common::SeekableReadStream &stream); bool loadFromStream(Common::SeekableReadStream &stream);
//const Graphics::Surface *getSurface(uint16 frameIndex);
Animation(); Animation();
Animation(byte *data, uint32 dataSize); Animation(byte *data, uint32 dataSize);

View file

@ -69,7 +69,7 @@ bool Hero::loadAnimSet(uint32 animSetNr) {
Animation *anim = NULL; Animation *anim = NULL;
if (animSet[i] != NULL) { if (animSet[i] != NULL) {
anim = new Animation(); anim = new Animation();
Resource::loadResource(anim, animSet[i]); Resource::loadResource(anim, animSet[i], true);
} }
_moveSet[i] = anim; _moveSet[i] = anim;
} }

View file

@ -76,7 +76,7 @@ void PrinceEngine::debugEngine(const char *s, ...) {
PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) : PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) :
Engine(syst), _gameDescription(gameDesc), _graph(nullptr), _script(nullptr), _interpreter(nullptr), _flags(nullptr), Engine(syst), _gameDescription(gameDesc), _graph(nullptr), _script(nullptr), _interpreter(nullptr), _flags(nullptr),
_locationNr(0), _debugger(nullptr), _midiPlayer(nullptr), _room(nullptr), _locationNr(0), _debugger(nullptr), _midiPlayer(nullptr), _room(nullptr), testAnimNr(0), testAnimFrame(0),
_cameraX(0), _newCameraX(0), _frameNr(0), _cursor1(nullptr), _cursor2(nullptr), _font(nullptr), _cameraX(0), _newCameraX(0), _frameNr(0), _cursor1(nullptr), _cursor2(nullptr), _font(nullptr),
_suitcaseBmp(nullptr), _roomBmp(nullptr), _cursorNr(0), _picWindowX(0), _picWindowY(0) { _suitcaseBmp(nullptr), _roomBmp(nullptr), _cursorNr(0), _picWindowX(0), _picWindowY(0) {
@ -163,25 +163,25 @@ void PrinceEngine::init() {
_midiPlayer = new MusicPlayer(this); _midiPlayer = new MusicPlayer(this);
_font = new Font(); _font = new Font();
Resource::loadResource(_font, "font1.raw"); Resource::loadResource(_font, "font1.raw", true);
_suitcaseBmp = new MhwanhDecoder(); _suitcaseBmp = new MhwanhDecoder();
Resource::loadResource(_suitcaseBmp, "walizka"); Resource::loadResource(_suitcaseBmp, "walizka", true);
_script = new Script(); _script = new Script(this);
Resource::loadResource(_script, "skrypt.dat"); Resource::loadResource(_script, "skrypt.dat", true);
_flags = new InterpreterFlags(); _flags = new InterpreterFlags();
_interpreter = new Interpreter(this, _script, _flags); _interpreter = new Interpreter(this, _script, _flags);
_variaTxt = new VariaTxt(); _variaTxt = new VariaTxt();
Resource::loadResource(_variaTxt, "variatxt.dat"); Resource::loadResource(_variaTxt, "variatxt.dat", true);
_cursor1 = new Cursor(); _cursor1 = new Cursor();
Resource::loadResource(_cursor1, "mouse1.cur"); Resource::loadResource(_cursor1, "mouse1.cur", true);
_cursor2 = new Cursor(); _cursor2 = new Cursor();
Resource::loadResource(_cursor2, "mouse2.cur"); Resource::loadResource(_cursor2, "mouse2.cur", true);
Common::SeekableReadStream *talkTxtStream = SearchMan.createReadStreamForMember("talktxt.dat"); Common::SeekableReadStream *talkTxtStream = SearchMan.createReadStreamForMember("talktxt.dat");
if (!talkTxtStream) { if (!talkTxtStream) {
@ -207,7 +207,7 @@ void PrinceEngine::init() {
void PrinceEngine::showLogo() { void PrinceEngine::showLogo() {
MhwanhDecoder logo; MhwanhDecoder logo;
if (Resource::loadResource(&logo, "logo.raw")) { if (Resource::loadResource(&logo, "logo.raw", true)) {
_graph->setPalette(logo.getPalette()); _graph->setPalette(logo.getPalette());
_graph->draw(0, 0, logo.getSurface()); _graph->draw(0, 0, logo.getSurface());
_graph->update(); _graph->update();
@ -246,7 +246,6 @@ bool AnimListItem::loadFromStream(Common::SeekableReadStream &stream) {
debug("AnimListItem type %d, fileNumber %d, x %d, y %d, flags %d", _type, _fileNumber, _x, _y, _flags); debug("AnimListItem type %d, fileNumber %d, x %d, y %d, flags %d", _type, _fileNumber, _x, _y, _flags);
// 32 byte aligment // 32 byte aligment
stream.seek(pos + 32); stream.seek(pos + 32);
@ -288,7 +287,7 @@ bool PrinceEngine::loadLocation(uint16 locationNr) {
_midiPlayer->loadMidi(musName); _midiPlayer->loadMidi(musName);
// load location background, replace old one // load location background, replace old one
Resource::loadResource(_roomBmp, "room"); Resource::loadResource(_roomBmp, "room", true);
if (_roomBmp->getSurface()) { if (_roomBmp->getSurface()) {
_sceneWidth = _roomBmp->getSurface()->w; _sceneWidth = _roomBmp->getSurface()->w;
_graph->setPalette(_roomBmp->getPalette()); _graph->setPalette(_roomBmp->getPalette());
@ -318,6 +317,7 @@ bool PrinceEngine::loadLocation(uint16 locationNr) {
_mainHero->setShadowScale(_script->getShadowScale(_locationNr)); _mainHero->setShadowScale(_script->getShadowScale(_locationNr));
_room->loadRoom(_script->getRoomOffset(_locationNr)); _room->loadRoom(_script->getRoomOffset(_locationNr));
_script->installBackAnims(_backAnimList, _room->_backAnim);
_graph->makeShadowTable(70, _graph->_shadowTable70); _graph->makeShadowTable(70, _graph->_shadowTable70);
_graph->makeShadowTable(50, _graph->_shadowTable50); _graph->makeShadowTable(50, _graph->_shadowTable50);
@ -524,9 +524,15 @@ void PrinceEngine::keyHandler(Common::Event event) {
break; break;
case Common::KEYCODE_LEFT: case Common::KEYCODE_LEFT:
scrollCameraLeft(32); scrollCameraLeft(32);
if(testAnimNr > 0) {
testAnimNr--;
}
debug("testAnimNr: %d", testAnimNr);
break; break;
case Common::KEYCODE_RIGHT: case Common::KEYCODE_RIGHT:
scrollCameraRight(32); scrollCameraRight(32);
testAnimNr++;
debug("testAnimNr: %d", testAnimNr);
break; break;
case Common::KEYCODE_ESCAPE: case Common::KEYCODE_ESCAPE:
_flags->setFlagValue(Flags::ESCAPED2, 1); _flags->setFlagValue(Flags::ESCAPED2, 1);
@ -534,11 +540,15 @@ void PrinceEngine::keyHandler(Common::Event event) {
case Common::KEYCODE_UP: case Common::KEYCODE_UP:
_mainHero->_phase++; _mainHero->_phase++;
debugEngine("%d", _mainHero->_phase); debugEngine("%d", _mainHero->_phase);
testAnimFrame++;
break; break;
case Common::KEYCODE_DOWN: case Common::KEYCODE_DOWN:
if(_mainHero->_phase > 0) { if(_mainHero->_phase > 0) {
_mainHero->_phase--; _mainHero->_phase--;
} }
if (testAnimFrame > 0) {
testAnimFrame--;
}
debugEngine("%d", _mainHero->_phase); debugEngine("%d", _mainHero->_phase);
break; break;
case Common::KEYCODE_w: case Common::KEYCODE_w:
@ -698,6 +708,10 @@ void PrinceEngine::drawScreen() {
} }
} }
*/ */
for (int i = 0; i < _backAnimList.size() ; i++) {
_graph->drawTransparent(_backAnimList[i]._x, _backAnimList[i]._y, _backAnimList[i]._animData->getFrame(testAnimFrame));
}
hotspot(); hotspot();
showTexts(); showTexts();

View file

@ -86,10 +86,57 @@ struct AnimListItem {
uint16 _loopType; uint16 _loopType;
uint16 _nextAnim; uint16 _nextAnim;
uint16 _flags; uint16 _flags;
bool loadFromStream(Common::SeekableReadStream &stream); bool loadFromStream(Common::SeekableReadStream &stream);
}; };
struct BAS {
int32 _type; // type of sequence
int32 _data; // additional data
int32 _anims; // number of animations
int32 _current; // actual number of animation
int32 _counter; // time counter for animation
int32 _currRelative; //actual relative number for animation
int32 _data2; // additional data for measurements
};
struct BASA {
int16 _num; // animation number
int16 _start; // initial frame
int16 _end; // final frame
int16 _pad; // fulfilment to 8 bytes
};
// background and normal animation
struct Anim {
int32 _addr; //animation adress
int32 _seq;
int16 _usage;
int16 _state; // state of animation: 0 - turning on, 1 - turning off
int16 _flags;
int16 _frame; // number of phase to show
int16 _lastFrame; // last phase
int16 _loopFrame; // first frame of loop
int16 _showFrame; // actual visible frame of animation
int16 _loopType; // type of loop (0 - last frame; 1 - normal loop (begin from _loopFrame); 2 - no loop; 3 - load new animation)
int16 _nextAnim; // number of next animation to load after actual
int16 _x;
int16 _y;
int32 _currFrame;
int16 _currX;
int16 _currY;
int16 _currW;
int16 _currH;
int16 _packFlag;
int32 _shadow;
int32 _currShadowFrame;
int16 _packShadowFlag;
int32 _shadowBack;
int16 _relX;
int16 _relY;
Animation *_animData;
Animation *_shadowData;
};
struct DebugChannel { struct DebugChannel {
enum Type { enum Type {
@ -149,6 +196,12 @@ public:
uint32 _picWindowY; uint32 _picWindowY;
Image::BitmapDecoder *_roomBmp; Image::BitmapDecoder *_roomBmp;
Common::Array<AnimListItem> _animList;
Common::Array<Anim> _backAnimList;
int testAnimNr;
int testAnimFrame;
private: private:
bool playNextFrame(); bool playNextFrame();
void keyHandler(Common::Event event); void keyHandler(Common::Event event);
@ -187,7 +240,6 @@ private:
Animation *_zoom; Animation *_zoom;
Common::Array<Mob> _mobList; Common::Array<Mob> _mobList;
Common::Array<Object *> _objList; Common::Array<Object *> _objList;
Common::Array<AnimListItem> _animList;
bool _flicLooped; bool _flicLooped;

View file

@ -38,7 +38,7 @@ namespace Resource {
} }
template<typename T> template<typename T>
bool loadResource(T *resource, const char *resourceName, bool required = true) { bool loadResource(T *resource, const char *resourceName, bool required) {
Common::ScopedPtr<Common::SeekableReadStream> stream(SearchMan.createReadStreamForMember(resourceName)); Common::ScopedPtr<Common::SeekableReadStream> stream(SearchMan.createReadStreamForMember(resourceName));
if (!stream) { if (!stream) {
if (required) if (required)

View file

@ -27,6 +27,7 @@
#include "prince/font.h" #include "prince/font.h"
#include "prince/hero.h" #include "prince/hero.h"
#include "prince/resource.h" #include "prince/resource.h"
#include "prince/animation.h"
#include "common/debug.h" #include "common/debug.h"
#include "common/debug-channels.h" #include "common/debug-channels.h"
@ -139,7 +140,7 @@ bool Room::loadFromStream(Common::SeekableReadStream &stream) {
} }
*/ */
Script::Script() : _data(nullptr), _dataSize(0) { Script::Script(PrinceEngine *vm) : _vm(vm), _data(nullptr), _dataSize(0) {
} }
Script::~Script() { Script::~Script() {
@ -205,15 +206,54 @@ uint8 *Script::getRoomOffset(int locationNr) {
return &_data[_scriptInfo.rooms + locationNr * 64]; return &_data[_scriptInfo.rooms + locationNr * 64];
} }
void Script::installBackAnims(int offset) { void Script::installBackAnims(Common::Array<Anim> &_backanimList, int offset) {
// 3760 for (uint i = 0; i < 64; i++) {
int numberOfSubAnimations = READ_UINT32(&_data[offset]); int animOffset = READ_UINT32(&_data[offset]);
debug("nrOfSubAnimations: %d", numberOfSubAnimations); int animNumber = READ_UINT16(&_data[animOffset + 28]);
// begin data of animations: Anim newAnim;
int value1 = READ_UINT32(&_data[offset + 28]); //size of BAS - first anim Nr if (animOffset != 0) {
debug("firstAnimNr: %d", value1); const Common::String animName = Common::String::format("AN%02d", animNumber);
int value2 = READ_UINT32(&_data[offset + 28 + 8]); // + size of BASA - next anim Nr const Common::String shadowName = Common::String::format("AN%02dS", animNumber, false);
debug("secondAnimNr: %d", value2); newAnim._animData = new Animation();
newAnim._shadowData = new Animation();
Resource::loadResource(newAnim._animData, animName.c_str(), true);
if (!Resource::loadResource(newAnim._shadowData, shadowName.c_str(), false)) {
newAnim._shadowData = nullptr;
}
newAnim._seq = 0;
newAnim._usage = 0;
newAnim._state = 0; // enabled
if ((_vm->_animList[animNumber]._flags & 4) != 0) {
newAnim._state = 1;
newAnim._frame = _vm->_animList[animNumber]._endPhase;
newAnim._showFrame = _vm->_animList[animNumber]._endPhase;
} else {
newAnim._frame = _vm->_animList[animNumber]._startPhase;
newAnim._showFrame = _vm->_animList[animNumber]._startPhase;
}
newAnim._flags = _vm->_animList[animNumber]._flags;
newAnim._lastFrame = _vm->_animList[animNumber]._endPhase;
newAnim._loopFrame = _vm->_animList[animNumber]._loopPhase;
newAnim._loopType = _vm->_animList[animNumber]._loopType;
newAnim._nextAnim = _vm->_animList[animNumber]._nextAnim;
newAnim._x = _vm->_animList[animNumber]._x;
newAnim._y = _vm->_animList[animNumber]._y;
newAnim._currFrame = 0;
newAnim._currX = _vm->_animList[animNumber]._x;
newAnim._currY = _vm->_animList[animNumber]._y;
newAnim._currW = 0;
newAnim._currH = 0;
newAnim._packFlag = 0;
//newAnim._currShadowFrame =
//newAnim._packShadowFlag =
newAnim._shadowBack = _vm->_animList[animNumber]._type;
//newAnim._relX =
//newAnim._relY =
_backanimList.push_back(newAnim);
debug("animNo: %d", animNumber);
}
offset += 4;
}
} }
InterpreterFlags::InterpreterFlags() { InterpreterFlags::InterpreterFlags() {

View file

@ -36,6 +36,8 @@ namespace Common {
namespace Prince { namespace Prince {
class PrinceEngine; class PrinceEngine;
class Animation;
struct Anim;
namespace Detail { namespace Detail {
template <typename T> T LittleEndianReader(void *data); template <typename T> T LittleEndianReader(void *data);
@ -91,7 +93,7 @@ private:
class Script { class Script {
public: public:
Script(); Script(PrinceEngine *vm);
~Script(); ~Script();
struct ScriptInfo { struct ScriptInfo {
@ -130,13 +132,14 @@ public:
int16 getLightY(int locationNr); int16 getLightY(int locationNr);
int32 getShadowScale(int locationNr); int32 getShadowScale(int locationNr);
uint8 *getRoomOffset(int locationNr); uint8 *getRoomOffset(int locationNr);
void installBackAnims(int offset); void installBackAnims(Common::Array<Anim> &_backanimList, int offset);
const char *getString(uint32 offset) { const char *getString(uint32 offset) {
return (const char *)(&_data[offset]); return (const char *)(&_data[offset]);
} }
private: private:
PrinceEngine *_vm;
uint8 *_data; uint8 *_data;
uint32 _dataSize; uint32 _dataSize;
Common::Array<Room> _roomList; Common::Array<Room> _roomList;