aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/parallaction/callables_ns.cpp2
-rw-r--r--engines/parallaction/gfxbase.cpp46
-rw-r--r--engines/parallaction/graphics.cpp6
-rw-r--r--engines/parallaction/graphics.h12
-rw-r--r--engines/parallaction/parallaction.cpp37
-rw-r--r--engines/parallaction/parallaction.h3
-rw-r--r--engines/parallaction/parser.h1
-rw-r--r--engines/parallaction/parser_br.cpp1
-rw-r--r--engines/parallaction/parser_ns.cpp11
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;