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);
int16 width = READ_LE_UINT16(frameData + 0);
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();
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')) {
// Compressed
Decompressor dec;

View file

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

View file

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

View file

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

View file

@ -86,10 +86,57 @@ struct AnimListItem {
uint16 _loopType;
uint16 _nextAnim;
uint16 _flags;
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 {
enum Type {
@ -149,6 +196,12 @@ public:
uint32 _picWindowY;
Image::BitmapDecoder *_roomBmp;
Common::Array<AnimListItem> _animList;
Common::Array<Anim> _backAnimList;
int testAnimNr;
int testAnimFrame;
private:
bool playNextFrame();
void keyHandler(Common::Event event);
@ -187,7 +240,6 @@ private:
Animation *_zoom;
Common::Array<Mob> _mobList;
Common::Array<Object *> _objList;
Common::Array<AnimListItem> _animList;
bool _flicLooped;

View file

@ -38,7 +38,7 @@ namespace Resource {
}
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));
if (!stream) {
if (required)

View file

@ -27,6 +27,7 @@
#include "prince/font.h"
#include "prince/hero.h"
#include "prince/resource.h"
#include "prince/animation.h"
#include "common/debug.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() {
@ -205,15 +206,54 @@ uint8 *Script::getRoomOffset(int locationNr) {
return &_data[_scriptInfo.rooms + locationNr * 64];
}
void Script::installBackAnims(int offset) {
// 3760
int numberOfSubAnimations = READ_UINT32(&_data[offset]);
debug("nrOfSubAnimations: %d", numberOfSubAnimations);
// begin data of animations:
int value1 = READ_UINT32(&_data[offset + 28]); //size of BAS - first anim Nr
debug("firstAnimNr: %d", value1);
int value2 = READ_UINT32(&_data[offset + 28 + 8]); // + size of BASA - next anim Nr
debug("secondAnimNr: %d", value2);
void Script::installBackAnims(Common::Array<Anim> &_backanimList, int offset) {
for (uint i = 0; i < 64; i++) {
int animOffset = READ_UINT32(&_data[offset]);
int animNumber = READ_UINT16(&_data[animOffset + 28]);
Anim newAnim;
if (animOffset != 0) {
const Common::String animName = Common::String::format("AN%02d", animNumber);
const Common::String shadowName = Common::String::format("AN%02dS", animNumber, false);
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() {

View file

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