From 8e772f936c43a68e4ae7c68b178bd9fa3a3e4f1f Mon Sep 17 00:00:00 2001 From: Kamil Zbróg Date: Thu, 5 Dec 2013 00:02:31 +0000 Subject: PRINCE: animation added --- engines/prince/animation.cpp | 67 ++++++++++ engines/prince/animation.h | 20 ++- engines/prince/detail/animation.cpp | 102 +++++++++++++++ engines/prince/detail/animation.h | 51 ++++++++ engines/prince/graphics.cpp | 2 +- engines/prince/graphics.h | 2 +- engines/prince/hero.cpp | 44 ++++++- engines/prince/hero.h | 27 +++- engines/prince/hero_set.cpp | 243 ++++++++++++++++++++++++++++++++++++ engines/prince/hero_set.h | 30 +++++ engines/prince/mhwanh.h | 14 +++ engines/prince/module.mk | 3 + engines/prince/prince.cpp | 139 +++++++++------------ engines/prince/prince.h | 20 ++- engines/prince/resource.h | 101 +++++++++++++++ engines/prince/script.cpp | 10 +- 16 files changed, 777 insertions(+), 98 deletions(-) create mode 100644 engines/prince/detail/animation.cpp create mode 100644 engines/prince/detail/animation.h create mode 100644 engines/prince/hero_set.cpp create mode 100644 engines/prince/hero_set.h create mode 100644 engines/prince/resource.h (limited to 'engines/prince') diff --git a/engines/prince/animation.cpp b/engines/prince/animation.cpp index e69de29bb2..f4db81ec4d 100644 --- a/engines/prince/animation.cpp +++ b/engines/prince/animation.cpp @@ -0,0 +1,67 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "prince/animation.h" +#include "prince/detail/animation.h" + + +namespace Prince { + +Animation::Animation() : _helper(NULL) { +} + +Animation::~Animation() { + delete _helper; +} + +bool Animation::loadFromStream(Common::SeekableReadStream &stream) { + + uint32 dataSize = stream.size(); + + byte *data = (byte*)malloc(dataSize); + + if(stream.read(data, dataSize) != dataSize) { + free(data); + return false; + } + + delete _helper; + + _helper = new Detail::Animation(data, dataSize); + + return true; +} + +const Graphics::Surface * Animation::getSurface(uint16 frameIndex) { + // bida kaszing + if (frameIndex >= _frameList.size()) { + _frameList.resize(frameIndex); + _frameList.push_back(_helper->getFrame(frameIndex)); + + } + return _frameList[frameIndex]; +} + +} + + +/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/animation.h b/engines/prince/animation.h index e6a76d33d2..b0ef25d493 100644 --- a/engines/prince/animation.h +++ b/engines/prince/animation.h @@ -23,13 +23,29 @@ #ifndef PRINCE_ANIMATION_H #define PRINCE_ANIMATION_H +#include "common/array.h" +#include "common/stream.h" + +#include "graphics/surface.h" + namespace Prince { -class Animation { +// FIXME: temp hack !!! +namespace Detail { + class Animation; +} +class Animation { +public: + Animation(); + ~Animation(); bool loadFromStream(Common::SeekableReadStream &stream); - const Graphics::Surface *getSurface(uint16 frameIndex) const; + const Graphics::Surface *getSurface(uint16 frameIndex); + +private: + Common::Array _frameList; + Detail::Animation *_helper; }; } diff --git a/engines/prince/detail/animation.cpp b/engines/prince/detail/animation.cpp new file mode 100644 index 0000000000..8b4a72b2f8 --- /dev/null +++ b/engines/prince/detail/animation.cpp @@ -0,0 +1,102 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "prince/detail/animation.h" +#include "prince/decompress.h" + +#include "common/debug.h" +#include "common/endian.h" + +namespace Prince { namespace Detail { + +Animation::Animation(byte *data, uint32 dataSize) + : _data(data), _dataSize(dataSize) { +} + +Animation::~Animation() { + free(_data); +} + +int16 Animation::getLoopCount() const { + return READ_LE_UINT16(_data + 2); +} + +int16 Animation::getBaseX() const { + return READ_LE_UINT16(_data + 8); +} + +int16 Animation::getBaseY() const { + return READ_LE_UINT16(_data + 10); +} + +uint Animation::getPhaseCount() const { + return READ_LE_UINT16(_data + 4); +} + +uint Animation::getFrameCount() const { + return READ_LE_UINT16(_data + 6); +} + +int16 Animation::getPhaseOffsetX(uint phaseIndex) const { + return READ_LE_UINT16(getPhaseEntry(phaseIndex) + 0); +} + +int16 Animation::getPhaseOffsetY(uint phaseIndex) const { + return READ_LE_UINT16(getPhaseEntry(phaseIndex) + 2); +} + +int16 Animation::getPhaseFrameIndex(uint phaseIndex) const { + return READ_LE_UINT16(getPhaseEntry(phaseIndex) + 4); +} + +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); + Graphics::Surface *surf = new Graphics::Surface(); + surf->create(width, height, Graphics::PixelFormat::createFormatCLUT8()); + debug("frameData %p", frameData); + if (READ_BE_UINT32(frameData + 4) == 0x6D61736D) { + // Compressed + Decompressor dec; + uint32 ddataSize = READ_LE_UINT32(frameData + 8); + byte *ddata = new byte[ddataSize]; + dec.decompress(frameData + 12, ddata, ddataSize); + for (uint16 i = 0; i < height; ++i) { + memcpy(surf->getBasePtr(0, i), ddata + width * i, width); + } + delete[] ddata; + } else { + // Uncompressed + for (uint16 i = 0; i < height; ++i) { + memcpy(surf->getBasePtr(0, i), frameData + 4 + width * i, width); + } + } + return surf; +} + +byte *Animation::getPhaseEntry(uint phaseIndex) const { + return _data + READ_LE_UINT32(_data + 12) + phaseIndex * 8; +} + +} } diff --git a/engines/prince/detail/animation.h b/engines/prince/detail/animation.h new file mode 100644 index 0000000000..f9f289dc71 --- /dev/null +++ b/engines/prince/detail/animation.h @@ -0,0 +1,51 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef PRINCE_DETAIL_ANIMATION_H +#define PRINCE_DETAIL_ANIMATION_H + +#include "graphics/surface.h" + +namespace Prince { namespace Detail { + +class Animation { +public: + Animation(byte *data, uint32 dataSize); + ~Animation(); + int16 getLoopCount() const; + int16 getBaseX() const; + int16 getBaseY() const; + uint getPhaseCount() const; + uint getFrameCount() const; + int16 getPhaseOffsetX(uint phaseIndex) const; + int16 getPhaseOffsetY(uint phaseIndex) const; + int16 getPhaseFrameIndex(uint phaseIndex) const; + Graphics::Surface *getFrame(uint frameIndex); +protected: + byte *_data; + uint32 _dataSize; + byte *getPhaseEntry(uint phaseIndex) const; +}; + +} } + +#endif diff --git a/engines/prince/graphics.cpp b/engines/prince/graphics.cpp index 025fa70003..97e2686f54 100644 --- a/engines/prince/graphics.cpp +++ b/engines/prince/graphics.cpp @@ -68,7 +68,7 @@ void GraphicsMan::draw(uint16 posX, uint16 posY, const Graphics::Surface *s) change(); } -void GraphicsMan::drawTransparent(const Graphics::Surface *s) +void GraphicsMan::drawTransparent(uint16 posX, uint16 posY, const Graphics::Surface *s) { for (uint y = 0; y < s->h; ++y) { for (uint x = 0; x < s->w; ++x) { diff --git a/engines/prince/graphics.h b/engines/prince/graphics.h index 884aac2c84..1766e2a04e 100644 --- a/engines/prince/graphics.h +++ b/engines/prince/graphics.h @@ -43,7 +43,7 @@ public: void setPalette(const byte *palette); void draw(uint16 x, uint16 y, const Graphics::Surface *s); - void drawTransparent(const Graphics::Surface *s); + void drawTransparent(uint16 x, uint16 y, const Graphics::Surface *s); Graphics::Surface *_frontScreen; Graphics::Surface *_backScreen; diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp index 277e521bee..621a9b8ee1 100644 --- a/engines/prince/hero.cpp +++ b/engines/prince/hero.cpp @@ -19,16 +19,56 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ +#include "common/debug.h" #include "prince/hero.h" +#include "prince/hero_set.h" +#include "prince/animation.h" +#include "prince/resource.h" + namespace Prince { +static const uint32 kMoveSetSize = 26; + Hero::Hero() : _number(0), _visible(false), _state(STAY), _middleX(0), _middleY(0) - , _boreNum(0), _currHeight(0), _moveDelay(0), _shadMinus(1) -{ + , _boreNum(0), _currHeight(0), _moveDelay(0), _shadMinus(1) { } +bool Hero::loadAnimSet(uint32 animSetNr) { + animSetNr = 6; + if (animSetNr > sizeof(heroSetTable)) { + return false; + } + + for (uint32 i = 0; i < _moveSet.size(); ++i) { + delete _moveSet[i]; + } + + const HeroSetAnimNames &animSet = *heroSetTable[animSetNr]; + + _moveSet.resize(kMoveSetSize); + for (uint32 i = 0; i < kMoveSetSize; ++i) { + debug("Anim set item %d %s", i, animSet[i]); + Animation *anim = NULL; + if (animSet[i] != NULL) { + anim = new Animation(); + Resource::loadResource(anim, animSet[i]); + } + _moveSet[i] = anim; + } + + + return true; +} + +const Graphics::Surface * Hero::getSurface() { + if (_moveSet[3]) { + return _moveSet[3]->getSurface(0); + } + return NULL; +} + } /* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/hero.h b/engines/prince/hero.h index e11a0f7395..77333d3643 100644 --- a/engines/prince/hero.h +++ b/engines/prince/hero.h @@ -24,9 +24,14 @@ #define PRINCE_HERO_H #include "common/scummsys.h" +#include "common/array.h" + +#include "graphics/surface.h" namespace Prince { +class Animation; + class Hero { public: enum State { @@ -42,14 +47,28 @@ public: DMOVE = 9 }; + enum Direction { + LEFT = 1, + RIGHT = 2, + UP = 3, + DOWN = 4 + }; + Hero(); -private: + bool loadAnimSet(uint32 heroAnimNumber); + + const Graphics::Surface * getSurface(); + + void setPos(int16 x, int16 y) { _middleX = x; _middleX = y; } + void setVisible(bool flag) { _visible = flag; } + +//private: uint16 _number; uint16 _visible; State _state; - uint16 _middleX; - uint16 _middleY; + int16 _middleX; + int16 _middleY; // Coords array of coordinates // DirTab array of directions @@ -74,7 +93,7 @@ private: // Font subtitiles font // Color subtitiles color // AnimSet number of animation set - // MoveAnims MoveSet + Common::Array _moveSet; // MoveAnims MoveSet // TurnAnim ?? uint32 _moveDelay; diff --git a/engines/prince/hero_set.cpp b/engines/prince/hero_set.cpp new file mode 100644 index 0000000000..a8c05de724 --- /dev/null +++ b/engines/prince/hero_set.cpp @@ -0,0 +1,243 @@ + +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "prince/hero_set.h" +#include "common/scummsys.h" + +namespace Prince { + +static HeroSetAnimNames heroSet5= { + "SL_DIAB.ANI", + "SR_DIAB.ANI", + "SU_DIAB.ANI", + "SD_DIAB.ANI", + NULL, + NULL, + "MU_DIAB.ANI", + "MD_DIAB.ANI", + "TL_DIAB.ANI", + "TR_DIAB.ANI", + "TU_DIAB.ANI", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +static HeroSetAnimNames heroSet1= { + "SL_HERO1.ANI", + "SR_HERO1.ANI", + "SU_HERO1.ANI", + "SD_HERO1.ANI", + "ML_HERO1.ANI", + "MR_HERO1.ANI", + "MU_HERO1.ANI", + "MD_HERO1.ANI", + "TL_HERO1.ANI", + "TR_HERO1.ANI", + "TU_HERO1.ANI", + "TD_HERO1.ANI", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "KSI_KURZ.ANI", + "KS_WLOSY.ANI" +}; + +static HeroSetAnimNames heroSet2= { + "SL_HERO2.ANI", + "SR_HERO2.ANI", + "SU_HERO2.ANI", + "SD_HERO2.ANI", + "ML_HERO2.ANI", + "MR_HERO2.ANI", + "MU_HERO2.ANI", + "MD_HERO2.ANI", + "TL_HERO2.ANI", + "TR_HERO2.ANI", + "TU_HERO2.ANI", + "TD_HERO2.ANI", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "KSI_KU_S.ANI", + "KS_WLO_S.ANI" +}; + +static HeroSetAnimNames heroSet3= { + "SL_BEAR.ANI", + "SR_BEAR.ANI", + "SU_BEAR.ANI", + "SD_BEAR.ANI", + "NIED-LEW.ANI", + "NIED-PRW.ANI", + "NIED-TYL.ANI", + "NIED-PRZ.ANI", + "SL_BEAR.ANI", + "SR_BEAR.ANI", + "SU_BEAR.ANI", + "SD_BEAR.ANI", + "N_LW-TYL.ANI", + "N_LW-PRZ.ANI", + "N_LW-PR.ANI", + "N_PR-TYL.ANI", + "N_PR-PRZ.ANI", + "N_PR-LW.ANI", + "N_TYL-LW.ANI", + "N_TYL-PR.ANI", + "N_TL-PRZ.ANI", + "N_PRZ-LW.ANI", + "N_PRZ-PR.ANI", + "N_PRZ-TL.ANI", + NULL, + NULL, +}; + +static HeroSetAnimNames shanSet1= { + "SL_SHAN.ANI", + "SR_SHAN.ANI", + "SU_SHAN.ANI", + "SD_SHAN.ANI", + "ML_SHAN.ANI", + "MR_SHAN.ANI", + "MU_SHAN.ANI", + "MD_SHAN.ANI", + "TL_SHAN.ANI", + "TR_SHAN.ANI", + "TU_SHAN.ANI", + "TD_SHAN.ANI", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "B1_SHAN.ANI", + "B2_SHAN.ANI", +}; + +static HeroSetAnimNames shanSet2= { + "SL_SHAN2.ANI", + "SR_SHAN2.ANI", + "SU_SHAN.ANI", + "SD_SHAN2.ANI", + "ML_SHAN2.ANI", + "MR_SHAN2.ANI", + "MU_SHAN.ANI", + "MD_SHAN2.ANI", + "TL_SHAN2.ANI", + "TR_SHAN2.ANI", + "TU_SHAN.ANI", + "TD_SHAN2.ANI", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "B1_SHAN2.ANI", + "B2_SHAN2.ANI" +}; + +static HeroSetAnimNames arivSet1= { + "SL_ARIV.ANI", + "SR_ARIV.ANI", + "SU_ARIV.ANI", + "SD_ARIV.ANI", + "ML_ARIV.ANI", + "MR_ARIV.ANI", + "MU_ARIV.ANI", + "MD_ARIV.ANI", + "TL_ARIV.ANI", + "TR_ARIV.ANI", + "TU_ARIV.ANI", + "TD_ARIV.ANI", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +const HeroSetAnimNames *heroSetTable[7] = { + &heroSet1, + &heroSet2, + &heroSet3, + &shanSet1, + &arivSet1, + &heroSet5, + &shanSet2, +}; + +} +/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/hero_set.h b/engines/prince/hero_set.h new file mode 100644 index 0000000000..335f70a6ab --- /dev/null +++ b/engines/prince/hero_set.h @@ -0,0 +1,30 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +namespace Prince { + +typedef const char *HeroSetAnimNames[26]; + +extern const HeroSetAnimNames *heroSetTable[7]; + +} +/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/mhwanh.h b/engines/prince/mhwanh.h index b11ecd08e6..9344312cce 100644 --- a/engines/prince/mhwanh.h +++ b/engines/prince/mhwanh.h @@ -24,7 +24,9 @@ #define PRINCE_MHWANH_H #include "graphics/decoders/image_decoder.h" +#include "graphics/decoders/bmp.h" #include "graphics/surface.h" +#include "resource.h" namespace Prince { @@ -46,6 +48,18 @@ private: uint16 _paletteColorCount; }; +namespace Resource { + template <> inline + bool loadFromStream(MhwanhDecoder &image, Common::SeekableReadStream &stream) { + return image.loadStream(stream); + } + + template <> inline + bool loadFromStream(Graphics::BitmapDecoder &image, Common::SeekableReadStream &stream) { + return image.loadStream(stream); + } +} + } #endif diff --git a/engines/prince/module.mk b/engines/prince/module.mk index 2e5f0592b1..e5319f8fe8 100644 --- a/engines/prince/module.mk +++ b/engines/prince/module.mk @@ -1,6 +1,7 @@ MODULE := engines/prince MODULE_OBJS = \ + animation.o \ debugger.o \ script.o \ graphics.o \ @@ -16,6 +17,8 @@ MODULE_OBJS = \ archive.o \ decompress.o \ hero.o \ + hero_set.o \ + detail/animation.o \ cursor.o # This module can be built as a plugin diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index f82f9e0e0c..207c601810 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -58,6 +58,7 @@ #include "prince/cursor.h" #include "prince/archive.h" #include "prince/hero.h" +#include "prince/resource.h" namespace Prince { @@ -104,6 +105,8 @@ PrinceEngine::~PrinceEngine() { delete _variaTxt; delete[] _talkTxt; delete _graph; + delete _mainHero; + delete _secondHero; for (uint32 i = 0; i < _objList.size(); ++i) { delete _objList[i]; @@ -115,77 +118,6 @@ GUI::Debugger *PrinceEngine::getDebugger() { return _debugger; } -template -bool loadFromStream(T &resource, Common::SeekableReadStream &stream) { - return resource.loadFromStream(stream); -} - -template <> -bool loadFromStream(MhwanhDecoder &image, Common::SeekableReadStream &stream) { - return image.loadStream(stream); -} - -template <> -bool loadFromStream(Graphics::BitmapDecoder &image, Common::SeekableReadStream &stream) { - return image.loadStream(stream); -} - -template -bool loadResource(T *resource, const char *resourceName, bool required = true) { - Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName); - if (!stream) { - if (required) - error("Can't load %s", resourceName); - return false; - } - - bool ret = loadFromStream(*resource, *stream); - - delete stream; - - return ret; -} - -template -bool loadResource(Common::Array &array, const char *resourceName, bool required = true) { - Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName); - if (!stream) { - if (required) - error("Can't load %s", resourceName); - return false; - } - - T t; - while (t.loadFromStream(*stream)) - array.push_back(t); - - delete stream; - return true; -} - -template -bool loadResource(Common::Array &array, const char *resourceName, bool required = true) { - Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName); - if (!stream) { - if (required) - error("Can't load %s", resourceName); - return false; - } - - // FIXME: This is stupid. Maybe loadFromStream should be helper method that returns initiailzed object - while (true) { - T* t = new T(); - if (!t->loadFromStream(*stream)) { - delete t; - break; - } - array.push_back(t); - } - - delete stream; - return true; -} - void PrinceEngine::init() { const Common::FSNode gameDataDir(ConfMan.get("path")); @@ -216,22 +148,22 @@ void PrinceEngine::init() { _midiPlayer = new MusicPlayer(this); _font = new Font(); - loadResource(_font, "all/font1.raw"); + Resource::loadResource(_font, "all/font1.raw"); _walizkaBmp = new MhwanhDecoder(); - loadResource(_walizkaBmp, "all/walizka"); + Resource::loadResource(_walizkaBmp, "all/walizka"); _script = new Script(this); - loadResource(_script, "all/skrypt.dat"); + Resource::loadResource(_script, "all/skrypt.dat"); _variaTxt = new VariaTxt(); - loadResource(_variaTxt, "all/variatxt.dat"); + Resource::loadResource(_variaTxt, "all/variatxt.dat"); _cursor1 = new Cursor(); - loadResource(_cursor1, "all/mouse1.cur"); + Resource::loadResource(_cursor1, "all/mouse1.cur"); _cursor2 = new Cursor(); - loadResource(_cursor2, "all/mouse2.cur"); + Resource::loadResource(_cursor2, "all/mouse2.cur"); Common::SeekableReadStream *talkTxtStream = SearchMan.createReadStreamForMember("all/talktxt.dat"); if (!talkTxtStream) { @@ -245,11 +177,16 @@ void PrinceEngine::init() { delete talkTxtStream; _roomBmp = new Graphics::BitmapDecoder(); + + _mainHero = new Hero(); + _secondHero = new Hero(); + + _mainHero->loadAnimSet(0); } void PrinceEngine::showLogo() { MhwanhDecoder logo; - if (loadResource(&logo, "logo.raw")) { + if (Resource::loadResource(&logo, "logo.raw")) { _graph->setPalette(logo.getPalette()); _graph->draw(0, 0, logo.getSurface()); _graph->update(); @@ -268,6 +205,33 @@ Common::Error PrinceEngine::run() { return Common::kNoError; } +bool AnimListItem::loadFromStream(Common::SeekableReadStream &stream) { + int32 pos = stream.pos(); + + uint16 type = stream.readUint16LE(); + if (type == 0xFFFF) { + return false; + } + _type = type; + _fileNumber = stream.readUint16LE(); + _startPhase = stream.readUint16LE(); + _endPhase = stream.readUint16LE(); + _loopPhase = stream.readUint16LE(); + _x = stream.readSint16LE(); + _y = stream.readSint16LE(); + _loopType = stream.readUint16LE(); + _nextAnim = stream.readUint16LE(); + _flags = stream.readUint16LE(); + + debug("AnimListItem type %d, fileNumber %d, x %d, y %d, flags %d", _type, _fileNumber, _x, _y, _flags); + + + // 32 byte aligment + stream.seek(pos + 32); + + return true; +} + bool PrinceEngine::loadLocation(uint16 locationNr) { _flicPlayer.close(); @@ -303,19 +267,22 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { _midiPlayer->loadMidi(musName); // load location background, replace old one - loadResource(_roomBmp, "room"); + Resource::loadResource(_roomBmp, "room"); if (_roomBmp->getSurface()) { _sceneWidth = _roomBmp->getSurface()->w; } _mobList.clear(); - loadResource(_mobList, "mob.lst", false); + Resource::loadResource(_mobList, "mob.lst", false); for (uint32 i = 0; i < _objList.size(); ++i) { delete _objList[i]; } _objList.clear(); - loadResource(_objList, "obj.lst", false); + Resource::loadResource(_objList, "obj.lst", false); + + _animList.clear(); + Resource::loadResource(_animList, "anim.lst", false); return true; } @@ -359,7 +326,7 @@ bool PrinceEngine::playNextFrame() { const Graphics::Surface *s = _flicPlayer.decodeNextFrame(); if (s) { - _graph->drawTransparent(s); + _graph->drawTransparent(0, 0, s); _graph->change(); } else if (_flicLooped) { _flicPlayer.rewind(); @@ -597,6 +564,13 @@ void PrinceEngine::drawScreen() { _graph->draw(0, 0, &visiblePart); } + if (_mainHero->_visible) { + const Graphics::Surface *mainHeroSurface = _mainHero->getSurface(); + + if (mainHeroSurface) + _graph->drawTransparent(_mainHero->_middleX, _mainHero->_middleY, mainHeroSurface); + } + playNextFrame(); //if (_objectList) @@ -649,6 +623,7 @@ void PrinceEngine::mainLoop() { // TODO: Update all structures, animations, naks, heros etc. _script->step(); + drawScreen(); // Calculate the frame delay based off a desired frame time diff --git a/engines/prince/prince.h b/engines/prince/prince.h index d2c75e76cb..edb4f1999f 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -71,6 +71,21 @@ struct Text { } }; +struct AnimListItem { + uint16 _type; + uint16 _fileNumber; + uint16 _startPhase; + uint16 _endPhase; + uint16 _loopPhase; + int16 _x; + int16 _y; + uint16 _loopType; + uint16 _nextAnim; + uint16 _flags; + + bool loadFromStream(Common::SeekableReadStream &stream); +}; + struct DebugChannel { enum Type { @@ -119,6 +134,8 @@ public: Text _textSlots[MAXTEXTS]; uint64 _frameNr; + Hero* _mainHero; + Hero* _secondHero; private: bool playNextFrame(); @@ -155,13 +172,12 @@ private: Common::Array _mobList; Common::Array _objList; + Common::Array _animList; uint16 _cameraX; uint16 _newCameraX; uint16 _sceneWidth; - Hero* _mainHero; - bool _flicLooped; void mainLoop(); diff --git a/engines/prince/resource.h b/engines/prince/resource.h new file mode 100644 index 0000000000..a5e389a37d --- /dev/null +++ b/engines/prince/resource.h @@ -0,0 +1,101 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef PRINCE_RESOURCE_H +#define PRINCE_RESOURCE_H + +#include "common/stream.h" +#include "common/archive.h" +#include "common/debug-channels.h" + +namespace Prince { + +namespace Resource { + + template + bool loadFromStream(T &resource, Common::SeekableReadStream &stream) { + return resource.loadFromStream(stream); + } + + + template + bool loadResource(T *resource, const char *resourceName, bool required = true) { + Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName); + if (!stream) { + if (required) + error("Can't load %s", resourceName); + return false; + } + + bool ret = loadFromStream(*resource, *stream); + + delete stream; + + return ret; + } + + template + bool loadResource(Common::Array &array, const char *resourceName, bool required = true) { + Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName); + if (!stream) { + if (required) + error("Can't load %s", resourceName); + return false; + } + + T t; + while (t.loadFromStream(*stream)) + array.push_back(t); + + delete stream; + return true; + } + + template + bool loadResource(Common::Array &array, const char *resourceName, bool required = true) { + Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(resourceName); + if (!stream) { + if (required) + error("Can't load %s", resourceName); + return false; + } + + // FIXME: This is stupid. Maybe loadFromStream should be helper method that returns initiailzed object + while (true) { + T* t = new T(); + if (!t->loadFromStream(*stream)) { + delete t; + break; + } + array.push_back(t); + } + + delete stream; + return true; + } +} + +} + +#endif + +/* vim: set tabstop=4 noexpandtab: */ diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp index 9daf3048ab..3011bc78ee 100644 --- a/engines/prince/script.cpp +++ b/engines/prince/script.cpp @@ -25,6 +25,7 @@ #include "prince/flags.h" #include "prince/variatxt.h" #include "prince/font.h" +#include "prince/hero.h" #include "common/debug.h" #include "common/debug-channels.h" @@ -543,22 +544,23 @@ void Script::O_WALKHERO() { void Script::O_SETHERO() { uint16 hero = readScriptValue(); - uint16 x = readScriptValue(); - uint16 y = readScriptValue(); + int16 x = readScriptValue(); + int16 y = readScriptValue(); uint16 dir = readScriptValue(); debugScript("O_SETHERO hero %d, x %d, y %d, dir %d", hero, x, y, dir); + _vm->_mainHero->setPos(x, y); } void Script::O_HEROOFF() { uint16 heroId = readScriptValue(); debugScript("O_HEROOFF %d", heroId); - // sets hero visible flag to false + _vm->_mainHero->setVisible(false); } void Script::O_HEROON() { uint16 heroId = readScriptValue(); debugScript("O_HEROON %d", heroId); - // sets hero visible flag to true + _vm->_mainHero->setVisible(true); } void Script::O_CLSTEXT() { -- cgit v1.2.3