aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--saga/actor.cpp55
-rw-r--r--saga/actor.h3
-rw-r--r--saga/script.cpp2
-rw-r--r--saga/sprite.cpp81
-rw-r--r--saga/sprite.h2
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);