aboutsummaryrefslogtreecommitdiff
path: root/engines/parallaction
diff options
context:
space:
mode:
authorNicola Mettifogo2008-12-17 11:15:47 +0000
committerNicola Mettifogo2008-12-17 11:15:47 +0000
commit774773b7cd02e3c6932095af4905a25eb1862392 (patch)
treefd2bc1c6ee9ccaa47372639a7dfdda207335e3fd /engines/parallaction
parent3591f8859ed5fe6ad4cc94671d7d43a52b9f01b6 (diff)
downloadscummvm-rg350-774773b7cd02e3c6932095af4905a25eb1862392.tar.gz
scummvm-rg350-774773b7cd02e3c6932095af4905a25eb1862392.tar.bz2
scummvm-rg350-774773b7cd02e3c6932095af4905a25eb1862392.zip
Reduced code duplication when manipulating Animations, and cleanup.
svn-id: r35408
Diffstat (limited to 'engines/parallaction')
-rw-r--r--engines/parallaction/debug.cpp4
-rw-r--r--engines/parallaction/exec_ns.cpp13
-rw-r--r--engines/parallaction/objects.cpp57
-rw-r--r--engines/parallaction/objects.h30
-rw-r--r--engines/parallaction/parallaction.cpp66
-rw-r--r--engines/parallaction/parallaction.h2
-rw-r--r--engines/parallaction/parser_br.cpp2
-rw-r--r--engines/parallaction/parser_ns.cpp2
-rw-r--r--engines/parallaction/walk.cpp28
-rw-r--r--engines/parallaction/walk.h1
10 files changed, 94 insertions, 111 deletions
diff --git a/engines/parallaction/debug.cpp b/engines/parallaction/debug.cpp
index 22b2ac6bec..df74c08f5a 100644
--- a/engines/parallaction/debug.cpp
+++ b/engines/parallaction/debug.cpp
@@ -150,13 +150,15 @@ bool Debugger::Cmd_Zones(int argc, const char **argv) {
ZoneList::iterator b = _vm->_location._zones.begin();
ZoneList::iterator e = _vm->_location._zones.end();
+ Common::Rect r;
DebugPrintf("+--------------------+---+---+---+---+--------+--------+\n"
"| name | l | t | r | b | type | flag |\n"
"+--------------------+---+---+---+---+--------+--------+\n");
for ( ; b != e; b++) {
ZonePtr z = *b;
- DebugPrintf("|%-20s|%3i|%3i|%3i|%3i|%8x|%8x|\n", z->_name, z->getX(), z->getY(), z->getX() + z->width(), z->getY() + z->height(), z->_type, z->_flags );
+ z->getRect(r);
+ DebugPrintf("|%-20s|%3i|%3i|%3i|%3i|%8x|%8x|\n", z->_name, r.left, r.top, r.right, r.bottom, z->_type, z->_flags );
}
DebugPrintf("+--------------------+---+---+---+---+--------+--------+\n");
diff --git a/engines/parallaction/exec_ns.cpp b/engines/parallaction/exec_ns.cpp
index b60f5d3779..9bfbd81705 100644
--- a/engines/parallaction/exec_ns.cpp
+++ b/engines/parallaction/exec_ns.cpp
@@ -123,10 +123,13 @@ DECLARE_INSTRUCTION_OPCODE(set) {
DECLARE_INSTRUCTION_OPCODE(put) {
InstructionPtr inst = *_ctxt.inst;
+ Common::Rect r;
+ inst->_a->getFrameRect(r);
+
Graphics::Surface v18;
- v18.w = inst->_a->width();
- v18.h = inst->_a->height();
- v18.pixels = inst->_a->getFrameData(inst->_a->getF());
+ v18.w = r.width();
+ v18.h = r.height();
+ v18.pixels = inst->_a->getFrameData();
int16 x = inst->_opA.getValue();
int16 y = inst->_opB.getValue();
@@ -332,7 +335,7 @@ void ProgramExec::runScripts(ProgramList::iterator first, ProgramList::iterator
AnimationPtr a = (*it)->_anim;
if (a->_flags & kFlagsCharacter)
- a->setZ(a->getFrameY() + a->height());
+ a->resetZ();
if ((a->_flags & kFlagsActing) == 0)
continue;
@@ -340,7 +343,7 @@ void ProgramExec::runScripts(ProgramList::iterator first, ProgramList::iterator
runScript(*it, a);
if (a->_flags & kFlagsCharacter)
- a->setZ(a->getFrameY() + a->height());
+ a->resetZ();
}
_modCounter++;
diff --git a/engines/parallaction/objects.cpp b/engines/parallaction/objects.cpp
index 59e2fb0868..8cbcb293ce 100644
--- a/engines/parallaction/objects.cpp
+++ b/engines/parallaction/objects.cpp
@@ -57,32 +57,36 @@ Animation::~Animation() {
gfxobj->release();
}
-uint16 Animation::width() const {
- if (!gfxobj) return 0;
- Common::Rect r;
+void Animation::getFrameRect(Common::Rect &r) const {
+ r.setWidth(0); r.setHeight(0);
+ if (!gfxobj) {
+ return;
+ }
gfxobj->getRect(_frame, r);
- return r.width();
+ r.translate(_left, _top);
}
-uint16 Animation::height() const {
- if (!gfxobj) return 0;
+bool Animation::hitFrameRect(int x, int y) const {
+ if (!gfxobj) {
+ return false;
+ }
Common::Rect r;
- gfxobj->getRect(_frame, r);
- return r.height();
+ getFrameRect(r);
+ return r.contains(x, y);
}
-int16 Animation::getFrameX() const {
- if (!gfxobj) return _left;
- Common::Rect r;
- gfxobj->getRect(_frame, r);
- return r.left + _left;
+int16 Animation::getBottom() const {
+ int bottom = _top;
+ if (gfxobj) {
+ Common::Rect r;
+ getFrameRect(r);
+ bottom = r.bottom;
+ }
+ return bottom;
}
-int16 Animation::getFrameY() const {
- if (!gfxobj) return _top;
- Common::Rect r;
- gfxobj->getRect(_frame, r);
- return r.top + _top;
+void Animation::resetZ() {
+ setZ(getBottom());
}
uint16 Animation::getFrameNum() const {
@@ -90,9 +94,9 @@ uint16 Animation::getFrameNum() const {
return gfxobj->getNum();
}
-byte* Animation::getFrameData(uint32 index) const {
+byte* Animation::getFrameData() const {
if (!gfxobj) return NULL;
- return gfxobj->getData(index);
+ return gfxobj->getData(_frame);
}
void Animation::validateScriptVars() {
@@ -221,12 +225,13 @@ void Zone::translate(int16 x, int16 y) {
_bottom += y;
}
-uint16 Zone::width() const {
- return _right - _left;
-}
-
-uint16 Zone::height() const {
- return _bottom - _top;
+bool Zone::hitRect(int x, int y) const {
+ // The scripts of Nippon Safes are full of invalid rectangles, used to
+ // provide 'special' features.
+ if (_right < _left || _bottom < _top) {
+ return false;
+ }
+ return Common::Rect(_left, _top, _right, _bottom).contains(x, y);
}
Dialogue::Dialogue() {
diff --git a/engines/parallaction/objects.h b/engines/parallaction/objects.h
index 1ed52dd9d0..77be772adc 100644
--- a/engines/parallaction/objects.h
+++ b/engines/parallaction/objects.h
@@ -288,11 +288,13 @@ struct TypeData {
#define ZONENAME_LENGTH 32
struct Zone {
+private:
+ int16 _right;
+ int16 _bottom;
+
protected:
int16 _left;
int16 _top;
- int16 _right;
- int16 _bottom;
public:
char _name[ZONENAME_LENGTH];
@@ -314,21 +316,19 @@ public:
virtual ~Zone();
void translate(int16 x, int16 y);
- virtual uint16 width() const;
- virtual uint16 height() const;
- void setBox(int16 left, int16 top, int16 right, int16 bottom) {
+ bool hitRect(int x, int y) const;
+
+ void setRect(int16 left, int16 top, int16 right, int16 bottom) {
setX(left);
setY(top);
_right = right;
_bottom = bottom;
}
- void getBox(Common::Rect& r) {
- r.left = getX();
- r.right = getX() + width();
- r.top = getY();
- r.bottom = getY() + height();
+ void getRect(Common::Rect& r) {
+ r.left = _left; r.right = _right;
+ r.top = _top; r.bottom = _bottom;
}
@@ -504,15 +504,15 @@ public:
Animation();
virtual ~Animation();
- virtual uint16 width() const;
- virtual uint16 height() const;
uint16 getFrameNum() const;
- byte* getFrameData(uint32 index) const;
+ byte* getFrameData() const;
void validateScriptVars();
- int16 getFrameX() const;
- int16 getFrameY() const;
+ void resetZ();
+ bool hitFrameRect(int x, int y) const;
+ void getFrameRect(Common::Rect &r) const;
+ int16 getBottom() const;
// getters/setters used by scripts
int16 getX() { return _left; }
diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp
index 6db48f7846..d26ba3fe5a 100644
--- a/engines/parallaction/parallaction.cpp
+++ b/engines/parallaction/parallaction.cpp
@@ -284,6 +284,16 @@ void Location::cleanup(bool removeAll) {
_escapeCommands.clear();
}
+int Location::getScale(int z) const {
+ int scale = 100;
+ if (z <= _zeta0) {
+ scale = _zeta2;
+ if (z >= _zeta1) {
+ scale += ((z - _zeta1) * (100 - _zeta2)) / (_zeta0 - _zeta1);
+ }
+ }
+ return scale;
+}
void Parallaction::showSlide(const char *name, int x, int y) {
@@ -334,10 +344,10 @@ void Parallaction::runGameFrame(int event) {
}
_programExec->runScripts(_location._programs.begin(), _location._programs.end());
- _char._ani->setZ(_char._ani->height() + _char._ani->getFrameY());
- if (_char._ani->gfxobj) {
- _char._ani->gfxobj->z = _char._ani->getZ();
- }
+ _char._ani->resetZ();
+// if (_char._ani->gfxobj) {
+// _char._ani->gfxobj->z = _char._ani->getZ();
+// }
_char._walker->walk();
drawAnimations();
@@ -446,12 +456,12 @@ void Parallaction::drawAnimations() {
if ((anim->_flags & kFlagsActive) && ((anim->_flags & kFlagsRemove) == 0)) {
- if (anim->_flags & kFlagsNoMasked)
+ if (anim->_flags & kFlagsNoMasked) {
layer = LAYER_FOREGROUND;
- else {
+ } else {
if (getGameType() == GType_Nippon) {
// Layer in NS depends on where the animation is on the screen, for each animation.
- layer = _gfx->_backgroundInfo->getLayer(anim->getFrameY() + anim->height());
+ layer = _gfx->_backgroundInfo->getLayer(anim->getBottom());
} else {
// Layer in BRA is calculated from Z value. For characters it is the same as NS,
// but other animations can have Z set from scripts independently from their
@@ -460,15 +470,10 @@ void Parallaction::drawAnimations() {
}
}
+ scale = 100;
if (getGameType() == GType_BRA) {
if (anim->_flags & (kFlagsScaled | kFlagsCharacter)) {
- if (anim->getZ() <= _location._zeta0) {
- if (anim->getZ() >= _location._zeta1) {
- scale = ((anim->getZ() - _location._zeta1) * (100 - _location._zeta2)) / (_location._zeta0 - _location._zeta1) + _location._zeta2;
- } else {
- scale = _location._zeta2;
- }
- }
+ scale = _location.getScale(anim->getZ());
}
}
@@ -701,14 +706,7 @@ bool Parallaction::checkZoneBox(ZonePtr z, uint32 type, uint x, uint y) {
debugC(5, kDebugExec, "checkZoneBox for %s (type = %x, x = %i, y = %i)", z->_name, type, x, y);
- Common::Rect r;
- z->getBox(r);
- r.right++; // adjust border because Common::Rect doesn't include bottom-right edge
- r.bottom++;
-
- r.grow(-1); // allows some tolerance for mouse click
-
- if (!r.contains(x, y)) {
+ if (!z->hitRect(x, y)) {
// check for special zones (items defined in common.loc)
if (checkSpecialZoneBox(z, type, x, y))
@@ -716,13 +714,7 @@ bool Parallaction::checkZoneBox(ZonePtr z, uint32 type, uint x, uint y) {
if (z->getX() != -1)
return false;
- if ((int)x < _char._ani->getFrameX())
- return false;
- if ((int)x > (_char._ani->getFrameX() + _char._ani->width()))
- return false;
- if ((int)y < _char._ani->getFrameY())
- return false;
- if ((int)y > (_char._ani->getFrameY() + _char._ani->height()))
+ if (!_char._ani->hitFrameRect(x, y))
return false;
}
@@ -747,10 +739,7 @@ bool Parallaction::checkLinkedAnimBox(ZonePtr z, uint32 type, uint x, uint y) {
debugC(5, kDebugExec, "checkLinkedAnimBox for %s (type = %x, x = %i, y = %i)", z->_name, type, x, y);
- AnimationPtr anim = z->_linkedAnim;
- Common::Rect r(anim->getFrameX(), anim->getFrameY(), anim->getFrameX() + anim->width() + 1, anim->getFrameY() + anim->height() + 1);
-
- if (!r.contains(x, y)) {
+ if (!z->_linkedAnim->hitFrameRect(x, y)) {
return false;
}
@@ -780,25 +769,22 @@ ZonePtr Parallaction::hitZone(uint32 type, uint16 x, uint16 y) {
}
- int16 _a, _b, _c, _d, _e, _f;
+ int16 _a, _b, _c, _d;
+ bool _ef;
for (AnimationList::iterator ait = _location._animations.begin(); ait != _location._animations.end(); ait++) {
AnimationPtr a = *ait;
_a = (a->_flags & kFlagsActive) ? 1 : 0; // _a: active Animation
- _e = ((_si >= a->getFrameX() + a->width()) || (_si <= a->getFrameX())) ? 0 : 1; // _e: horizontal range
- _f = ((_di >= a->getFrameY() + a->height()) || (_di <= a->getFrameY())) ? 0 : 1; // _f: vertical range
+ _ef = a->hitFrameRect(_si, _di);
_b = ((type != 0) || (a->_type == kZoneYou)) ? 0 : 1; // _b: (no type specified) AND (Animation is not the character)
_c = (a->_type & 0xFFFF0000) ? 0 : 1; // _c: Animation is not an object
_d = ((a->_type & 0xFFFF0000) != type) ? 0 : 1; // _d: Animation is an object of the same type
- if ((_a != 0 && _e != 0 && _f != 0) && ((_b != 0 && _c != 0) || (a->_type == type) || (_d != 0))) {
-
+ if ((_a != 0 && _ef) && ((_b != 0 && _c != 0) || (a->_type == type) || (_d != 0))) {
return a;
-
}
-
}
return nullZonePtr;
diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h
index bcdbdaeb2e..bffd8b2940 100644
--- a/engines/parallaction/parallaction.h
+++ b/engines/parallaction/parallaction.h
@@ -164,6 +164,8 @@ public:
ZonePtr findZone(const char *name);
void cleanup(bool removeAll);
+
+ int getScale(int z) const;
};
diff --git a/engines/parallaction/parser_br.cpp b/engines/parallaction/parser_br.cpp
index 6fbd1232f0..6b05f5018a 100644
--- a/engines/parallaction/parser_br.cpp
+++ b/engines/parallaction/parser_br.cpp
@@ -720,7 +720,7 @@ DECLARE_ZONE_PARSER(limits) {
ctxt.z->_linkedAnim = _vm->_location.findAnimation(_tokens[1]);
ctxt.z->_linkedName = strdup(_tokens[1]);
} else {
- ctxt.z->setBox(atoi(_tokens[1]), atoi(_tokens[2]), atoi(_tokens[3]), atoi(_tokens[4]));
+ ctxt.z->setRect(atoi(_tokens[1]), atoi(_tokens[2]), atoi(_tokens[3]), atoi(_tokens[4]));
}
}
diff --git a/engines/parallaction/parser_ns.cpp b/engines/parallaction/parser_ns.cpp
index 2a1b40f010..f244ab2687 100644
--- a/engines/parallaction/parser_ns.cpp
+++ b/engines/parallaction/parser_ns.cpp
@@ -1298,7 +1298,7 @@ DECLARE_ZONE_PARSER(endzone) {
DECLARE_ZONE_PARSER(limits) {
debugC(7, kDebugParser, "ZONE_PARSER(limits) ");
- ctxt.z->setBox(atoi(_tokens[1]), atoi(_tokens[2]), atoi(_tokens[3]), atoi(_tokens[4]));
+ ctxt.z->setRect(atoi(_tokens[1]), atoi(_tokens[2]), atoi(_tokens[3]), atoi(_tokens[4]));
}
diff --git a/engines/parallaction/walk.cpp b/engines/parallaction/walk.cpp
index ec24a29979..acd5daa8d5 100644
--- a/engines/parallaction/walk.cpp
+++ b/engines/parallaction/walk.cpp
@@ -360,7 +360,7 @@ void PathWalker_NS::walk() {
-PathBuilder_NS::PathBuilder_NS(Character *ch) : PathBuilder(ch), _list(0) {
+PathBuilder_NS::PathBuilder_NS(Character *ch) : PathBuilder(ch) {
}
@@ -515,25 +515,6 @@ void PathWalker_BR::walk() {
}
#endif
- GfxObj *obj = _ch->_ani->gfxobj;
-
- Common::Rect rect;
- obj->getRect(_ch->_ani->getF(), rect);
-
- uint scale;
- if (rect.bottom > _vm->_location._zeta0) {
- scale = 100;
- } else
- if (rect.bottom < _vm->_location._zeta1) {
- scale = _vm->_location._zeta2;
- } else {
- scale = _vm->_location._zeta2 + ((rect.bottom - _vm->_location._zeta1) * (100 - _vm->_location._zeta2)) / (_vm->_location._zeta0 - _vm->_location._zeta1);
- }
- int xStep = (scale * 16) / 100 + 1;
- int yStep = (scale * 10) / 100 + 1;
-
- debugC(9, kDebugWalk, "calculated step: (%i, %i)\n", xStep, yStep);
-
if (_fieldC == 0) {
_ch->_walkPath.erase(_ch->_walkPath.begin());
@@ -548,11 +529,16 @@ void PathWalker_BR::walk() {
_ch->getFoot(_startFoot);
+ uint scale = _vm->_location.getScale(_startFoot.y);
+ int xStep = (scale * 16) / 100 + 1;
+ int yStep = (scale * 10) / 100 + 1;
+
+ debugC(9, kDebugWalk, "calculated step: (%i, %i)\n", xStep, yStep);
+
_fieldC = 0;
_step++;
_step %= 8;
-
int maxX = _vm->_gfx->_backgroundInfo->width;
int minX = 0;
int maxY = _vm->_gfx->_backgroundInfo->height;
diff --git a/engines/parallaction/walk.h b/engines/parallaction/walk.h
index 8d21e5ebbd..1ffd538bab 100644
--- a/engines/parallaction/walk.h
+++ b/engines/parallaction/walk.h
@@ -51,7 +51,6 @@ public:
class PathBuilder_NS : public PathBuilder {
- PointList *_list;
PointList _subPath;
void correctPathPoint(Common::Point &to);