diff options
-rw-r--r-- | engines/parallaction/callables_ns.cpp | 2 | ||||
-rw-r--r-- | engines/parallaction/gfxbase.cpp | 46 | ||||
-rw-r--r-- | engines/parallaction/graphics.cpp | 6 | ||||
-rw-r--r-- | engines/parallaction/graphics.h | 12 | ||||
-rw-r--r-- | engines/parallaction/parallaction.cpp | 37 | ||||
-rw-r--r-- | engines/parallaction/parallaction.h | 3 | ||||
-rw-r--r-- | engines/parallaction/parser.h | 1 | ||||
-rw-r--r-- | engines/parallaction/parser_br.cpp | 1 | ||||
-rw-r--r-- | engines/parallaction/parser_ns.cpp | 11 |
9 files changed, 76 insertions, 43 deletions
diff --git a/engines/parallaction/callables_ns.cpp b/engines/parallaction/callables_ns.cpp index 450e4171cc..c3e8c8e6a4 100644 --- a/engines/parallaction/callables_ns.cpp +++ b/engines/parallaction/callables_ns.cpp @@ -244,8 +244,6 @@ void Parallaction_ns::stopMovingSarcophagus() { _moveSarcGetZone->translate(_sarcophagusDeltaX, -_sarcophagusDeltaX / 20); _moveSarcExaZone->translate(_sarcophagusDeltaX, -_sarcophagusDeltaX / 20); - _zonesToUpdate.push_back(_moveSarcGetZone); - // check if the puzzle has been completed, by verifying the position of // the sarcophagi if (_moveSarcGetZones[0]->getX() == 35 && diff --git a/engines/parallaction/gfxbase.cpp b/engines/parallaction/gfxbase.cpp index 968d705a5c..c4109c41b6 100644 --- a/engines/parallaction/gfxbase.cpp +++ b/engines/parallaction/gfxbase.cpp @@ -33,7 +33,7 @@ namespace Parallaction { GfxObj::GfxObj(uint objType, Frames *frames, const char* name) : - _frames(frames), _keep(true), x(0), y(0), z(0), _flags(kGfxObjNormal), + _frames(frames), _keep(true), x(0), y(0), z(0), _flags(0), type(objType), frame(0), layer(3), scale(100), _hasMask(false), _hasPath(false) { if (name) { @@ -88,6 +88,27 @@ void GfxObj::clearFlags(uint32 flags) { _flags &= ~flags; } +void Gfx::addObjectToScene(GfxObj *obj) { + if (!obj) { + return; + } + + if (!obj->isVisible()) { + return; + } + + if (SCENE_DRAWLIST_SIZE == _sceneObjects.size()) { + warning("number of objects in the current scene is larger than the fixed drawlist size"); + } + + _sceneObjects.push_back(obj); +} + +void Gfx::resetSceneDrawList() { + _sceneObjects.clear(); + _sceneObjects.reserve(SCENE_DRAWLIST_SIZE); +} + GfxObj* Gfx::loadAnim(const char *name) { Frames* frames = _disk->loadFrames(name); assert(frames); @@ -98,15 +119,11 @@ GfxObj* Gfx::loadAnim(const char *name) { // animation Z is not set here, but controlled by game scripts and user interaction. // it is always >=0 and <screen height obj->transparentKey = 0; - _sceneObjects.push_back(obj); return obj; } GfxObj* Gfx::loadCharacterAnim(const char *name) { - GfxObj *obj = loadAnim(name); - obj->setFlags(kGfxObjCharacter); - obj->clearFlags(kGfxObjNormal); - return obj; + return loadAnim(name); } GfxObj* Gfx::loadGet(const char *name) { @@ -116,7 +133,6 @@ GfxObj* Gfx::loadGet(const char *name) { obj->z = kGfxObjGetZ; // this preset Z value ensures that get zones are drawn after doors but before animations obj->type = kGfxObjTypeGet; obj->transparentKey = 0; - _sceneObjects.push_back(obj); return obj; } @@ -129,31 +145,17 @@ GfxObj* Gfx::loadDoor(const char *name) { obj->z = kGfxObjDoorZ; // this preset Z value ensures that doors are drawn first obj->transparentKey = 0; - _sceneObjects.push_back(obj); return obj; } -void Gfx::clearGfxObjects(uint filter) { - - for (uint i = 0; i < _sceneObjects.size() ; ) { - if ((_sceneObjects[i]->_flags & filter) != 0) { - _sceneObjects.remove_at(i); - } else { - i++; - } - } - -} void Gfx::freeLocationObjects() { freeDialogueObjects(); - clearGfxObjects(kGfxObjNormal); freeLabels(); } void Gfx::freeCharacterObjects() { freeDialogueObjects(); - clearGfxObjects(kGfxObjCharacter); } void BackgroundInfo::loadGfxObjMask(const char *name, GfxObj *obj) { @@ -202,7 +204,7 @@ void Gfx::showGfxObj(GfxObj* obj, bool visible) { bool compareZ(const GfxObj* a1, const GfxObj* a2) { - return a1->z < a2->z; + return (a1->z == a2->z) ? (a1->_prog < a2->_prog) : (a1->z < a2->z); } void Gfx::sortScene() { diff --git a/engines/parallaction/graphics.cpp b/engines/parallaction/graphics.cpp index 5d2b571343..fdeba0b089 100644 --- a/engines/parallaction/graphics.cpp +++ b/engines/parallaction/graphics.cpp @@ -372,6 +372,10 @@ void Gfx::setScrollPos(int scrollX) { _scrollPos = CLIP(scrollX, _minScroll, _maxScroll); } +void Gfx::beginFrame() { + resetSceneDrawList(); +} + void Gfx::updateScreen() { // the scene is calculated in game coordinates, so no translation @@ -714,6 +718,8 @@ Gfx::Gfx(Parallaction* vm) : _backupPal.clone(paletteInfo.palette); } + resetSceneDrawList(); + return; } diff --git a/engines/parallaction/graphics.h b/engines/parallaction/graphics.h index f029d54833..007590705c 100644 --- a/engines/parallaction/graphics.h +++ b/engines/parallaction/graphics.h @@ -273,9 +273,6 @@ class Disk; enum { kGfxObjVisible = 1, - kGfxObjNormal = 2, - kGfxObjCharacter = 4, - kGfxObjTypeDoor = 0, kGfxObjTypeGet = 1, kGfxObjTypeAnim = 2, @@ -299,6 +296,7 @@ public: int16 x, y; int32 z; + uint32 _prog; // this value is used when sorting, in case that comparing z is not enough to tell which object goes on front uint32 _flags; @@ -419,26 +417,28 @@ public: typedef Common::Array<GfxObj*> GfxObjArray; - +#define SCENE_DRAWLIST_SIZE 100 class Gfx { protected: Parallaction* _vm; + void resetSceneDrawList(); public: Disk *_disk; + void beginFrame(); + void addObjectToScene(GfxObj *obj); GfxObjArray _sceneObjects; GfxObj* loadAnim(const char *name); GfxObj* loadGet(const char *name); GfxObj* loadDoor(const char *name); GfxObj* loadCharacterAnim(const char *name); + void sortScene(); void freeCharacterObjects(); void freeLocationObjects(); void showGfxObj(GfxObj* obj, bool visible); - void clearGfxObjects(uint filter); - void sortScene(); void blt(const Common::Rect& r, byte *data, Graphics::Surface *surf, uint16 z, uint scale, byte transparentColor); void unpackBlt(const Common::Rect& r, byte *data, uint size, Graphics::Surface *surf, uint16 z, uint scale, byte transparentColor); diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp index abd8249d02..38d8b8002e 100644 --- a/engines/parallaction/parallaction.cpp +++ b/engines/parallaction/parallaction.cpp @@ -338,6 +338,8 @@ void Parallaction::runGameFrame(int event) { _input->setArrowCursor(); } + _gfx->beginFrame(); + runPendingZones(); if (shouldQuit()) @@ -494,6 +496,29 @@ void Parallaction::drawAnimation(AnimationPtr anim) { obj->z = anim->getZ(); obj->layer = layer; obj->scale = scale; + _gfx->addObjectToScene(obj); +} + +void Parallaction::drawZone(ZonePtr zone) { + if (!zone) { + return; + } + + GfxObj *obj = 0; + if (ACTIONTYPE(zone) == kZoneGet) { + obj = zone->u.get->gfxobj; + } else + if (ACTIONTYPE(zone) == kZoneDoor) { + obj = zone->u.door->gfxobj; + } + + if (!obj) { + return; + } + + obj->x = zone->getX(); + obj->y = zone->getY(); + _gfx->addObjectToScene(obj); } void Parallaction::updateZones() { @@ -512,16 +537,10 @@ void Parallaction::updateZones() { } } - // examine the list of get zones to update - for (ZoneList::iterator zit = _zonesToUpdate.begin(); zit != _zonesToUpdate.end(); ++zit) { - ZonePtr z = *zit; - if (ACTIONTYPE(z) == kZoneGet) { - GfxObj *obj = z->u.get->gfxobj; - obj->x = z->getX(); - obj->y = z->getY(); - } + // go through all zones and mark/unmark each of them for display + for (ZoneList::iterator zit = _location._zones.begin(); zit != _location._zones.end(); ++zit) { + drawZone(*zit); } - _zonesToUpdate.clear(); debugC(9, kDebugExec, "Parallaction::updateZones done()\n"); } diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h index 8e7ba76648..8a6546e9b9 100644 --- a/engines/parallaction/parallaction.h +++ b/engines/parallaction/parallaction.h @@ -305,6 +305,7 @@ protected: void exitCommentMode(); void updateView(); void drawAnimation(AnimationPtr anim); + void drawZone(ZonePtr zone); void updateZones(); void doLocationEnterTransition(); void allocateLocationSlot(const char *name); @@ -312,8 +313,6 @@ protected: void showLocationComment(const Common::String &text, bool end); void setupBalloonManager(); - ZoneList _zonesToUpdate; - public: void beep(); void pauseJobs(); diff --git a/engines/parallaction/parser.h b/engines/parallaction/parser.h index 13129b0aac..eb0ee71648 100644 --- a/engines/parallaction/parser.h +++ b/engines/parallaction/parser.h @@ -106,6 +106,7 @@ protected: Table *_zoneTypeNames; Table *_zoneFlagNames; + uint _zoneProg; // location parser OpcodeSet _locationParsers; diff --git a/engines/parallaction/parser_br.cpp b/engines/parallaction/parser_br.cpp index 97db740ae7..529d87b953 100644 --- a/engines/parallaction/parser_br.cpp +++ b/engines/parallaction/parser_br.cpp @@ -786,6 +786,7 @@ void LocationParser_br::parseGetData(ZonePtr z) { obj->frame = 0; obj->x = z->getX(); obj->y = z->getY(); + obj->_prog = _zoneProg; data->gfxobj = obj; } diff --git a/engines/parallaction/parser_ns.cpp b/engines/parallaction/parser_ns.cpp index 4eef8d1370..a84c821e24 100644 --- a/engines/parallaction/parser_ns.cpp +++ b/engines/parallaction/parser_ns.cpp @@ -290,7 +290,13 @@ DECLARE_ANIM_PARSER(endanimation) { void LocationParser_ns::parseAnimation(AnimationList &list, char *name) { debugC(5, kDebugParser, "parseAnimation(name: %s)", name); + if (_vm->_location.findAnimation(name)) { + _script->skip("endanimation"); + return; + } + AnimationPtr a(new Animation); + _zoneProg++; strncpy(a->_name, name, ZONENAME_LENGTH); a->_flags |= kFlagsIsAnimation; @@ -328,7 +334,6 @@ void ProgramParser_ns::parseInstruction() { } void ProgramParser_ns::parse(Script *script, ProgramPtr program) { - _script = script; _program = program; @@ -1088,7 +1093,7 @@ DECLARE_LOCATION_PARSER(music) { } void LocationParser_ns::parse(Script *script) { - + _zoneProg = 0; _numForwardedCommands = 0; ctxt.end = false; @@ -1360,6 +1365,7 @@ void LocationParser_ns::parseZone(ZoneList &list, char *name) { } ZonePtr z(new Zone); + _zoneProg++; strncpy(z->_name, name, ZONENAME_LENGTH); @@ -1389,6 +1395,7 @@ void LocationParser_ns::parseGetData(ZonePtr z) { obj->frame = 0; obj->x = z->getX(); obj->y = z->getY(); + obj->_prog = _zoneProg; _vm->_gfx->showGfxObj(obj, visible); data->gfxobj = obj; |