Reduced code duplication when manipulating Animations, and cleanup.

svn-id: r35408
This commit is contained in:
Nicola Mettifogo
2008-12-17 11:15:47 +00:00
parent 3591f8859e
commit 774773b7cd
10 changed files with 94 additions and 111 deletions
+3 -1
View File
@@ -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");
+8 -5
View File
@@ -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++;
+31 -26
View File
@@ -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() {
+15 -15
View File
@@ -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; }
+26 -40
View File
@@ -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;
+2
View File
@@ -164,6 +164,8 @@ public:
ZonePtr findZone(const char *name);
void cleanup(bool removeAll);
int getScale(int z) const;
};
+1 -1
View File
@@ -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]));
}
}
+1 -1
View File
@@ -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]));
}
+7 -21
View File
@@ -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;
-1
View File
@@ -51,7 +51,6 @@ public:
class PathBuilder_NS : public PathBuilder {
PointList *_list;
PointList _subPath;
void correctPathPoint(Common::Point &to);