mirror of
https://github.com/scummvm/scummvm.git
synced 2026-06-20 05:45:29 +00:00
Reduced code duplication when manipulating Animations, and cleanup.
svn-id: r35408
This commit is contained in:
@@ -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");
|
||||
|
||||
|
||||
@@ -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++;
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -164,6 +164,8 @@ public:
|
||||
ZonePtr findZone(const char *name);
|
||||
|
||||
void cleanup(bool removeAll);
|
||||
|
||||
int getScale(int z) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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]));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -51,7 +51,6 @@ public:
|
||||
|
||||
class PathBuilder_NS : public PathBuilder {
|
||||
|
||||
PointList *_list;
|
||||
PointList _subPath;
|
||||
|
||||
void correctPathPoint(Common::Point &to);
|
||||
|
||||
Reference in New Issue
Block a user