diff options
author | Andrew Kurushin | 2005-01-18 23:15:41 +0000 |
---|---|---|
committer | Andrew Kurushin | 2005-01-18 23:15:41 +0000 |
commit | 9353d54f95baf1e0838850a181bbad8b43761d66 (patch) | |
tree | 756e85bd06c7409b62726900da4cf2fdf6ccffb8 | |
parent | 0ccf59faee053f4ea6c349d25bf39bb83e537686 (diff) | |
download | scummvm-rg350-9353d54f95baf1e0838850a181bbad8b43761d66.tar.gz scummvm-rg350-9353d54f95baf1e0838850a181bbad8b43761d66.tar.bz2 scummvm-rg350-9353d54f95baf1e0838850a181bbad8b43761d66.zip |
implemented Sprite::hitTest
Actors & Objects can be hited
svn-id: r16596
-rw-r--r-- | saga/actor.cpp | 55 | ||||
-rw-r--r-- | saga/actor.h | 3 | ||||
-rw-r--r-- | saga/script.cpp | 2 | ||||
-rw-r--r-- | saga/sprite.cpp | 81 | ||||
-rw-r--r-- | saga/sprite.h | 2 |
5 files changed, 107 insertions, 36 deletions
diff --git a/saga/actor.cpp b/saga/actor.cpp index 97844e02de..5130c6c104 100644 --- a/saga/actor.cpp +++ b/saga/actor.cpp @@ -1055,6 +1055,24 @@ void Actor::calcScreenPosition(CommonObjectData *commonObjectData) { } +uint16 Actor::hitTest(const Point &testPoint) { + CommonObjectOrderList::iterator drawOrderIterator; + CommonObjectDataPointer drawObject; + int frameNumber; + SpriteList *spriteList; + createDrawOrderList(); + for (drawOrderIterator = _drawOrderList.begin(); drawOrderIterator != _drawOrderList.end(); ++drawOrderIterator) { + drawObject = drawOrderIterator.operator*(); + if (!getSpriteParams(drawObject, frameNumber, spriteList)) { + continue; + } + + if (_vm->_sprite->hitTest(*spriteList, frameNumber, drawObject->screenPosition, drawObject->screenScale, testPoint)) { + return drawObject->id; + } + } + return ID_NOTHING; +} void Actor::createDrawOrderList() { int i; @@ -1082,6 +1100,26 @@ void Actor::createDrawOrderList() { } } +bool Actor::getSpriteParams(CommonObjectData *commonObjectData, int &frameNumber, SpriteList *&spriteList) { + if (_vm->_scene->currentSceneNumber() == RID_ITE_OVERMAP_SCENE) { + if (!(commonObjectData->flags & kProtagonist)){ + warning("not protagonist"); + return false; + } + frameNumber = 8; + spriteList = &_vm->_sprite->_mainSprites; + } else { + frameNumber = commonObjectData->frameNumber; + spriteList = &commonObjectData->spriteList; + } + + if ((frameNumber < 0) || (spriteList->spriteCount <= frameNumber)) { + warning("Actor::getSpriteParams frameNumber invalid for object id 0x%X", commonObjectData->id); + return false; + } + return true; +} + int Actor::drawActors() { CommonObjectOrderList::iterator drawOrderIterator; CommonObjectDataPointer drawObject; @@ -1096,24 +1134,11 @@ int Actor::drawActors() { for (drawOrderIterator = _drawOrderList.begin(); drawOrderIterator != _drawOrderList.end(); ++drawOrderIterator) { drawObject = drawOrderIterator.operator*(); - - if (_vm->_scene->currentSceneNumber() == RID_ITE_OVERMAP_SCENE) { - if (!(drawObject->flags & kProtagonist)){ - warning("not protagonist"); - continue; - } - frameNumber = 8; - spriteList = &_vm->_sprite->_mainSprites; - } else { - frameNumber = drawObject->frameNumber; - spriteList = &drawObject->spriteList; - } - - if ((frameNumber < 0) || (spriteList->spriteCount <= frameNumber)) { - warning("Actor::drawActors frameNumber invalid for object id 0x%X", drawObject->id); + if (!getSpriteParams(drawObject, frameNumber, spriteList)) { continue; } + if (_vm->_scene->getFlags() & kSceneFlagISO) { //todo: it } else { diff --git a/saga/actor.h b/saga/actor.h index 024f3c791c..572e0bb19c 100644 --- a/saga/actor.h +++ b/saga/actor.h @@ -327,7 +327,7 @@ public: void drawPathTest(); - uint16 testHit(const Point& mousePointer){ return ID_NOTHING;}; //TODO: do it + uint16 hitTest(const Point &testPoint); void takeExit(uint16 actorId, const HitZone *hitZone); bool actorEndWalk(uint16 actorId, bool recurse); bool actorWalkTo(uint16 actorId, const Location &toLocation); @@ -357,6 +357,7 @@ private: void createDrawOrderList(); void calcScreenPosition(CommonObjectData *commonObjectData); + bool getSpriteParams(CommonObjectData *commonObjectData, int &frameNumber, SpriteList *&spriteList); bool followProtagonist(ActorData *actor); void findActorPath(ActorData *actor, const Point &fromPoint, const Point &toPoint); diff --git a/saga/script.cpp b/saga/script.cpp index 66ac013815..e587456852 100644 --- a/saga/script.cpp +++ b/saga/script.cpp @@ -904,7 +904,7 @@ void Script::whichObject(const Point& mousePoint) { if (_vm->_actor->_protagonist->currentAction == kActionWalkDir) { } else { - newObjectId = _vm->_actor->testHit(mousePoint); + newObjectId = _vm->_actor->hitTest(mousePoint); if (newObjectId != ID_NOTHING) { if (objectTypeId(newObjectId) == kGameObjectObject) { diff --git a/saga/sprite.cpp b/saga/sprite.cpp index 7801eb5904..36d2f0f9b4 100644 --- a/saga/sprite.cpp +++ b/saga/sprite.cpp @@ -173,10 +173,10 @@ void Sprite::getScaledSpriteBuffer(SpriteList &spriteList, int spriteNumber, int int Sprite::draw(SURFACE *ds, SpriteList &spriteList, int spriteNumber, const Point &screenCoord, int scale) { const byte *spriteBuffer; int i, j; - byte *buf_row_p; - const byte *src_row_p; - int clip_width; - int clip_height; + byte *bufRowPointer; + const byte *srcRowPointer; + int clipWidth; + int clipHeight; int width; int height; int xAlign; @@ -197,34 +197,79 @@ int Sprite::draw(SURFACE *ds, SpriteList &spriteList, int spriteNumber, const Po return 0; } - buf_row_p = (byte *)ds->pixels + ds->pitch * spritePointer.y; - src_row_p = spriteBuffer; + bufRowPointer = (byte *)ds->pixels + ds->pitch * spritePointer.y; + srcRowPointer = spriteBuffer; - // Clip to right side of surface - clip_width = width; + clipWidth = width; if (width > (ds->w - spritePointer.x)) { - clip_width = (ds->w - spritePointer.x); + clipWidth = (ds->w - spritePointer.x); } - // Clip to bottom side of surface - clip_height = height; + clipHeight = height; if (height > (ds->h - spritePointer.y)) { - clip_height = (ds->h - spritePointer.y); + clipHeight = (ds->h - spritePointer.y); } - for (i = 0; i < clip_height; i++) { - for (j = 0; j < clip_width; j++) { - if (*(src_row_p + j) != 0) { - *(buf_row_p + j + spritePointer.x) = *(src_row_p + j); + for (i = 0; i < clipHeight; i++) { + for (j = 0; j < clipWidth; j++) { + if (*(srcRowPointer + j) != 0) { + *(bufRowPointer + j + spritePointer.x) = *(srcRowPointer + j); } } - buf_row_p += ds->pitch; - src_row_p += width; + bufRowPointer += ds->pitch; + srcRowPointer += width; } return SUCCESS; } +bool Sprite::hitTest(SpriteList &spriteList, int spriteNumber, const Point &screenCoord, int scale, const Point &testPoint) { + const byte *spriteBuffer; + int i, j; + const byte *srcRowPointer; + int clipWidth; + int clipHeight; + int width; + int height; + int xAlign; + int yAlign; + Point spritePointer; + + + getScaledSpriteBuffer(spriteList, spriteNumber, scale, width, height, xAlign, yAlign, spriteBuffer); + + spritePointer.x = screenCoord.x + xAlign; + spritePointer.y = screenCoord.y + yAlign; + + if (spritePointer.x < 0) { + return false; + } + if (spritePointer.y < 0) { + return false; + } + + clipWidth = width; + if (width > (_vm->getDisplayWidth() - spritePointer.x)) { + clipWidth = (_vm->getDisplayWidth() - spritePointer.x); + } + + clipHeight = height; + if (height > (_vm->getDisplayHeight() - spritePointer.y)) { + clipHeight = (_vm->getDisplayHeight() - spritePointer.y); + } + + if ((testPoint.y < spritePointer.y) || (testPoint.y >= spritePointer.y + clipHeight)) { + return false; + } + if ((testPoint.x < spritePointer.x) || (testPoint.x >= spritePointer.x + clipWidth)) { + return false; + } + i = testPoint.y - spritePointer.y; + j = testPoint.x - spritePointer.x; + srcRowPointer = spriteBuffer + j + i * width; + return *srcRowPointer != 0; +} + int Sprite::drawOccluded(SURFACE *ds, SpriteList &spriteList, int spriteNumber, const Point &screenCoord, int scale, int depth) { const byte *spriteBuffer; int x, y; diff --git a/saga/sprite.h b/saga/sprite.h index 9f229891fb..48abf5a52d 100644 --- a/saga/sprite.h +++ b/saga/sprite.h @@ -70,7 +70,7 @@ public: int loadList(int resourceId, SpriteList &spriteList); // load or append spriteList int draw(SURFACE *ds, SpriteList &spriteList, int spriteNumber, const Point &screenCoord, int scale); int drawOccluded(SURFACE *ds, SpriteList &spriteList, int spriteNumber, const Point &screenCoord, int scale, int depth); - + bool hitTest(SpriteList &spriteList, int spriteNumber, const Point &screenCoord, int scale, const Point &testPoint); private: void decodeRLEBuffer(const byte *inputBuffer, size_t inLength, size_t outLength); void scaleBuffer(const byte *src, int width, int height, int scale); |