aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorNicola Mettifogo2009-02-27 08:56:19 +0000
committerNicola Mettifogo2009-02-27 08:56:19 +0000
commit44906f574fa46f1f02d8e9f9d5113ab1b35cf759 (patch)
tree36458f56be6242c027662f9b0664cbf6455e9ea3 /engines
parente17a14001997552dd51c99275b623f5fa6b1b9ca (diff)
downloadscummvm-rg350-44906f574fa46f1f02d8e9f9d5113ab1b35cf759.tar.gz
scummvm-rg350-44906f574fa46f1f02d8e9f9d5113ab1b35cf759.tar.bz2
scummvm-rg350-44906f574fa46f1f02d8e9f9d5113ab1b35cf759.zip
The engine has now to build the drawing list for the graphic department, instead of setting visibility flags; the new field _prog has been added to GfxObj to help sorting the list.
The outcome is that cleaning up unused resources on location switches is now easier to manage, and less error prone. svn-id: r38928
Diffstat (limited to 'engines')
-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;