aboutsummaryrefslogtreecommitdiff
path: root/saga
diff options
context:
space:
mode:
authorAndrew Kurushin2005-02-18 00:00:00 +0000
committerAndrew Kurushin2005-02-18 00:00:00 +0000
commitbbbd3b5fbf1230e681fad01e80717bc1785e0d09 (patch)
treee6ece1dcf27eef28d85915deed0b1e592f326648 /saga
parentdef8641e1f748a193db6afe060729ef242883409 (diff)
downloadscummvm-rg350-bbbd3b5fbf1230e681fad01e80717bc1785e0d09.tar.gz
scummvm-rg350-bbbd3b5fbf1230e681fad01e80717bc1785e0d09.tar.bz2
scummvm-rg350-bbbd3b5fbf1230e681fad01e80717bc1785e0d09.zip
iso mode drawing work in progress
svn-id: r16802
Diffstat (limited to 'saga')
-rw-r--r--saga/actor.cpp10
-rw-r--r--saga/actor.h6
-rw-r--r--saga/isomap.cpp315
-rw-r--r--saga/isomap.h40
-rw-r--r--saga/resnames.h3
-rw-r--r--saga/scene.cpp1
-rw-r--r--saga/sprite.cpp72
-rw-r--r--saga/sprite.h5
8 files changed, 405 insertions, 47 deletions
diff --git a/saga/actor.cpp b/saga/actor.cpp
index 9809d1e2fb..365d4e74ad 100644
--- a/saga/actor.cpp
+++ b/saga/actor.cpp
@@ -34,6 +34,7 @@
#include "saga/sound.h"
#include "saga/scene.h"
+#include "saga/isomap.h"
#include "saga/actor.h"
#include "saga/itedata.h"
#include "saga/stream.h"
@@ -634,6 +635,9 @@ void Actor::updateActorsScene(int actorsEntrance) {
}
handleActions(0, true);
+ if (_vm->_scene->getFlags() & kSceneFlagISO) {
+ _vm->_isoMap->adjustScroll(true);
+ }
}
ActorFrameRange *Actor::getActorFrameRange(uint16 actorId, int frameType) {
@@ -1041,10 +1045,12 @@ int Actor::direct(int msec) {
return SUCCESS;
}
+
void Actor::calcScreenPosition(CommonObjectData *commonObjectData) {
int beginSlope, endSlope, middle;
if (_vm->_scene->getFlags() & kSceneFlagISO) {
- //todo: it
+ _vm->_isoMap->tileCoordsToScreenPoint(commonObjectData->location, commonObjectData->screenPosition);
+ commonObjectData->screenScale = 256;
} else {
middle = _vm->getSceneHeight() - commonObjectData->location.y / ACTOR_LMULT;
@@ -1159,7 +1165,7 @@ int Actor::drawActors() {
if (_vm->_scene->getFlags() & kSceneFlagISO) {
- //todo: it
+ _vm->_isoMap->drawSprite(back_buf,*spriteList, frameNumber, drawObject->location, drawObject->screenPosition, drawObject->screenScale);
} else {
_vm->_sprite->drawOccluded(back_buf, *spriteList, frameNumber, drawObject->screenPosition, drawObject->screenScale, drawObject->screenDepth);
}
diff --git a/saga/actor.h b/saga/actor.h
index 5d43efd137..4bfe878a71 100644
--- a/saga/actor.h
+++ b/saga/actor.h
@@ -146,6 +146,12 @@ struct Location {
int &v() {
return y;
}
+ int u() const {
+ return x;
+ }
+ int v() const {
+ return y;
+ }
void delta(const Location &location, Location &result) const {
result.x = x - location.x;
result.y = y - location.y;
diff --git a/saga/isomap.cpp b/saga/isomap.cpp
index 7d6ba62281..f6b2123bd2 100644
--- a/saga/isomap.cpp
+++ b/saga/isomap.cpp
@@ -26,6 +26,8 @@
#include "saga/gfx.h"
+#include "saga/resnames.h"
+#include "saga/scene.h"
#include "saga/isomap.h"
#include "saga/stream.h"
@@ -199,37 +201,133 @@ void IsoMap::freeMem() {
_multiCount = 0;
}
+void IsoMap::adjustScroll(bool jump) {
+ Point playerPoint;
+ Point minScrollPos;
+ Point maxScrollPos;
+
+
+ tileCoordsToScreenPoint(_vm->_actor->_centerActor->location, playerPoint);
+
+ if (_vm->_scene->currentSceneNumber() == RID_ITE_OVERMAP_SCENE) {
+ _mapPosition.x = (playerPoint.x + _viewScroll.x) * 30 / 100 - (381);
+ _mapPosition.y = (playerPoint.y + _viewScroll.y) * 30 / 100 - (342);
+ }
+
+ if (_vm->_actor->_centerActor != _vm->_actor->_protagonist) {
+ playerPoint.y -= 24;
+ }
+ playerPoint.y -= 28;
+
+ playerPoint.x += _viewScroll.x - _vm->getDisplayWidth()/2;
+ playerPoint.y += _viewScroll.y - _vm->getSceneHeight()/2;
+
+ minScrollPos.x = playerPoint.x - SAGA_SCROLL_LIMIT_X1;
+ minScrollPos.y = playerPoint.y - SAGA_SCROLL_LIMIT_Y1;
+
+ maxScrollPos.x = playerPoint.x + SAGA_SCROLL_LIMIT_X1;
+ maxScrollPos.y = playerPoint.y + SAGA_SCROLL_LIMIT_Y2;
+
+ if (jump) {
+ if (_viewScroll.y < minScrollPos.y) {
+ _viewScroll.y = minScrollPos.y;
+ }
+ if (_viewScroll.y > maxScrollPos.y) {
+ _viewScroll.y = maxScrollPos.y;
+ }
+ if (_viewScroll.x < minScrollPos.x) {
+ _viewScroll.x = minScrollPos.x;
+ }
+ if (_viewScroll.x > maxScrollPos.x) {
+ _viewScroll.x = maxScrollPos.x;
+ }
+ } else {
+ _viewScroll.y = smoothSlide( _viewScroll.y, minScrollPos.y, maxScrollPos.y );
+ _viewScroll.x = smoothSlide( _viewScroll.x, minScrollPos.x, maxScrollPos.x );
+ }
+
+ if (_vm->_scene->currentSceneNumber() == RID_ITE_OVERMAP_SCENE) {
+ ObjectData *obj;
+ uint16 objectId;
+ objectId = _vm->_actor->objIndexToId(ITE_OBJ_MAP);
+ obj = _vm->_actor->getObj(objectId);
+ if (obj->sceneNumber != ITE_SCENE_INV) {
+ _viewScroll.x = 1552 + 8;
+ _viewScroll.y = 1456 + 8;
+ }
+ }
+}
+
int IsoMap::draw(SURFACE *ds) {
Rect isoRect(_vm->getDisplayWidth(), _vm->getDisplayInfo().sceneHeight);
drawRect(ds, &isoRect, 0);
_tileClip = isoRect;
- drawTiles(ds);
+ drawTiles(ds, NULL);
return SUCCESS;
}
-void IsoMap::drawTiles(SURFACE *ds) {
+void IsoMap::drawSprite(SURFACE *ds, SpriteList &spriteList, int spriteNumber, const Location &location, const Point &screenPosition, int scale) {
+ int width;
+ int height;
+ int xAlign;
+ int yAlign;
+ const byte *spriteBuffer;
+ Point spritePointer;
+ Rect clip(_vm->getDisplayWidth(),_vm->getSceneHeight());
+
+ _vm->_sprite->getScaledSpriteBuffer(spriteList,spriteNumber,scale, width, height, xAlign, yAlign, spriteBuffer);
+
+ spritePointer.x = screenPosition.x + xAlign;
+ spritePointer.y = screenPosition.y + yAlign;
+
+ _tileClip.left = screenPosition.x;
+ _tileClip.top = screenPosition.y;
+ _tileClip.right = screenPosition.x + width;
+ _tileClip.bottom = screenPosition.y + height;
+
+ if (_tileClip.left < 0) {
+ _tileClip.left = 0;
+ }
+ if (_tileClip.right > _vm->getDisplayWidth()) {
+ _tileClip.right = _vm->getDisplayWidth();
+ }
+ if (_tileClip.top < 0) {
+ _tileClip.top = 0;
+ }
+ if (_tileClip.bottom > _vm->getSceneHeight()) {
+ _tileClip.bottom = _vm->getSceneHeight();
+ }
+
+ _vm->_sprite->drawClip(ds, clip, spritePointer, width, height, spriteBuffer);
+ drawTiles(ds, &location);
+}
+
+
+void IsoMap::drawTiles(SURFACE *ds, const Location *location) {
Point view1;
Point fineScroll;
+ Point tileScroll;
Point metaTileY;
Point metaTileX;
int16 u0, v0,
u1, v1,
u2, v2,
uc, vc;
+ uint16 metaTileIndex;
+ Location rLocation;
int16 workAreaWidth;
int16 workAreaHeight;
- uint16 metaTileIndex;
- _tileScroll.x = _viewScroll.x >> 4;
- _tileScroll.y = _viewScroll.y >> 4;
+ tileScroll.x = _viewScroll.x >> 4;
+ tileScroll.y = _viewScroll.y >> 4;
fineScroll.x = _viewScroll.x & 0xf;
fineScroll.y = _viewScroll.y & 0xf;
- view1.x = _tileScroll.x - (8 * SAGA_TILEMAP_W);
- view1.y = (8 * SAGA_TILEMAP_W) - _tileScroll.y;
+ view1.x = tileScroll.x - (8 * SAGA_TILEMAP_W);
+ view1.y = (8 * SAGA_TILEMAP_W) - tileScroll.y;
u0 = ((view1.y + 64) * 2 + view1.x) >> 4;
v0 = ((view1.y + 64) * 2 - view1.x) >> 4;
@@ -271,7 +369,14 @@ void IsoMap::drawTiles(SURFACE *ds) {
metaTileIndex = _tileMap.tilePlatforms[uc][vc];
}
- drawMetaTile(ds, metaTileIndex, metaTileX, u2 << 3, v2 << 3);
+ if (location != NULL) {
+ rLocation.u() = location->u() - (u2 << 7);
+ rLocation.v() = location->v() - (v2 << 7);
+ rLocation.z = location->z;
+ drawSpriteMetaTile(ds, metaTileIndex, metaTileX, rLocation, u2 << 3, v2 << 3);
+ } else {
+ drawMetaTile(ds, metaTileIndex, metaTileX, u2 << 3, v2 << 3);
+ }
}
metaTileY.y += 64;
@@ -308,13 +413,47 @@ void IsoMap::drawTiles(SURFACE *ds) {
metaTileIndex = _tileMap.tilePlatforms[uc][vc];
}
- drawMetaTile(ds, metaTileIndex, metaTileX, u2 << 3, v2 << 3);
+ if (location != NULL) {
+ rLocation.u() = location->u() - (u2 << 7);
+ rLocation.v() = location->v() - (v2 << 7);
+ rLocation.z = location->z;
+ drawSpriteMetaTile(ds, metaTileIndex, metaTileX, rLocation, u2 << 3, v2 << 3);
+ } else {
+ drawMetaTile(ds, metaTileIndex, metaTileX, u2 << 3, v2 << 3);
+ }
}
metaTileY.y += 64;
}
}
+void IsoMap::drawSpriteMetaTile(SURFACE *ds, uint16 metaTileIndex, const Point &point, Location &location, int16 absU, int16 absV) {
+ MetaTileData * metaTile;
+ uint16 high;
+ int16 platformIndex;
+ Point platformPoint;
+ platformPoint = point;
+
+ if (_metaTilesCount <= metaTileIndex) {
+ error("IsoMap::drawMetaTile wrong metaTileIndex");
+ }
+
+ metaTile = &_metaTileList[metaTileIndex];
+
+ if (metaTile->highestPlatform > 18) {
+ metaTile->highestPlatform = 0;
+ }
+
+ for (high = 0; high <= metaTile->highestPlatform; high++, platformPoint.y -= 8, location.z -= 8) {
+ assert(SAGA_MAX_PLATFORM_H > high);
+ platformIndex = metaTile->stack[high];
+
+ if (platformIndex >= 0) {
+ drawSpritePlatform( ds, platformIndex, platformPoint, location, absU, absV, high );
+ }
+ }
+}
+
void IsoMap::drawMetaTile(SURFACE *ds, uint16 metaTileIndex, const Point &point, int16 absU, int16 absV) {
MetaTileData * metaTile;
uint16 high;
@@ -342,6 +481,61 @@ void IsoMap::drawMetaTile(SURFACE *ds, uint16 metaTileIndex, const Point &point,
}
}
+void IsoMap::drawSpritePlatform(SURFACE *ds, uint16 platformIndex, const Point &point, const Location &location, int16 absU, int16 absV, int16 absH) {
+ TilePlatformData *tilePlatform;
+ int16 u, v;
+ Point s;
+ Point s0;
+ int16 tileIndex;
+ Location copyLocation(location);
+
+ if (_tilePlatformsCount <= platformIndex) {
+ error("IsoMap::drawPlatform wrong platformIndex");
+ }
+
+ tilePlatform = &_tilePlatformList[platformIndex];
+
+ if ((point.y <= _tileClip.top) || (point.y - SAGA_MAX_TILE_H - SAGA_PLATFORM_W * SAGA_TILE_NOMINAL_H >= _tileClip.bottom)) {
+ return;
+ }
+
+ s0 = point;
+ s0.y -= (((SAGA_PLATFORM_W - 1) + (SAGA_PLATFORM_W - 1)) * 8);
+
+ for (v = SAGA_PLATFORM_W - 1,
+ copyLocation.v() = location.v() - ((SAGA_PLATFORM_W - 1) << 4);
+ v >= 0 && s0.y - SAGA_MAX_TILE_H < _tileClip.bottom && s0.x - 128 < _tileClip.right;
+ v--, copyLocation.v() += 16, s0.x += 16, s0.y += 8) {
+
+ if ((tilePlatform->vBits & (1 << v)) == 0) {
+ continue;
+ }
+
+ if (s0.x + 128 + 32 < _tileClip.left) {
+ continue;
+ }
+
+ s = s0;
+
+ for (u = SAGA_PLATFORM_W - 1,
+ copyLocation.u() = location.u() - ((SAGA_PLATFORM_W - 1) << 4);
+ u >= 0 && s.x + 32 > _tileClip.left && s.y - SAGA_MAX_TILE_H < _tileClip.bottom;
+ u--, copyLocation.u() += 16, s.x -= 16, s.y += 8 ) {
+ if (s.x < _tileClip.right && s.y > _tileClip.top) {
+
+ tileIndex = tilePlatform->tiles[u][v];
+ if (tileIndex != 0) {
+ if (tileIndex & SAGA_MULTI_TILE) {
+ warning("SAGA_MULTI_TILE"); //TODO: do it !
+ }
+
+ drawSpriteTile(ds, tileIndex, location, s);
+ }
+ }
+ }
+ }
+}
+
void IsoMap::drawPlatform(SURFACE *ds, uint16 platformIndex, const Point &point, int16 absU, int16 absV, int16 absH) {
TilePlatformData *tilePlatform;
int16 u, v;
@@ -362,7 +556,9 @@ void IsoMap::drawPlatform(SURFACE *ds, uint16 platformIndex, const Point &point,
s0 = point;
s0.y -= (((SAGA_PLATFORM_W - 1) + (SAGA_PLATFORM_W - 1)) * 8);
- for (v = SAGA_PLATFORM_W - 1; v >= 0 && s0.y - SAGA_MAX_TILE_H < _tileClip.bottom && s0.x - 128 < _tileClip.right; v--, s0.x += 16, s0.y += 8) {
+ for (v = SAGA_PLATFORM_W - 1;
+ v >= 0 && s0.y - SAGA_MAX_TILE_H < _tileClip.bottom && s0.x - 128 < _tileClip.right;
+ v--, s0.x += 16, s0.y += 8) {
if ((tilePlatform->vBits & (1 << v)) == 0) {
continue;
@@ -374,7 +570,9 @@ void IsoMap::drawPlatform(SURFACE *ds, uint16 platformIndex, const Point &point,
s = s0;
- for (u = SAGA_PLATFORM_W - 1; u >= 0 && s.x + 32 > _tileClip.left && s.y - SAGA_MAX_TILE_H < _tileClip.bottom; u--, s.x -= 16, s.y += 8 ) {
+ for (u = SAGA_PLATFORM_W - 1;
+ u >= 0 && s.x + 32 > _tileClip.left && s.y - SAGA_MAX_TILE_H < _tileClip.bottom;
+ u--, s.x -= 16, s.y += 8 ) {
if (s.x < _tileClip.right && s.y > _tileClip.top) {
tileIndex = tilePlatform->tiles[u][v];
@@ -457,7 +655,7 @@ void IsoMap::drawTile(SURFACE *ds, uint16 tileIndex, const Point &point) {
}
while ((col < _tileClip.right) && (count < fgRunCount)) {
assert((uint)ds->pixels <= (uint)(drawPointer + count));
- assert(((uint)ds->pixels + (ds->pitch * _vm->getDisplayWidth())) > (uint)(drawPointer + count));
+ assert(((uint)ds->pixels + (_vm->getDisplayWidth() * _vm->getDisplayHeight())) > (uint)(drawPointer + count));
drawPointer[count] = readPointer[count];
count++;
col++;
@@ -483,4 +681,97 @@ void IsoMap::drawTile(SURFACE *ds, uint16 tileIndex, const Point &point) {
}
+void IsoMap::drawSpriteTile(SURFACE *ds, uint16 tileIndex, const Location &location, const Point &point) {
+ const byte *tilePointer;
+ const byte *readPointer;
+ byte *drawPointer;
+ Point drawPoint;
+ int height;
+ int widthCount = 0;
+ int row, col, count, lowBound;
+ int bgRunCount;
+ int fgRunCount;
+
+
+ if (tileIndex >= _tilesCount) {
+ error("IsoMap::drawTile wrong tileIndex");
+ }
+
+
+ if (point.x + SAGA_ISOTILE_WIDTH < _tileClip.left) {
+ return;
+ }
+
+ if (point.x - SAGA_ISOTILE_WIDTH >= _tileClip.right) {
+ return;
+ }
+
+ tilePointer = _tileData + _tilesTable[tileIndex].offset;
+ height = _tilesTable[tileIndex].height;
+
+
+
+ if ((height <= 8) || (height > 64)) {
+ return;
+ }
+
+ drawPoint = point;
+ drawPoint.y -= height;
+
+ if (drawPoint.y >= _tileClip.bottom) {
+ return;
+ }
+
+ readPointer = tilePointer;
+ lowBound = MIN((int)(drawPoint.y + height), (int)_tileClip.bottom);
+ for (row = drawPoint.y; row < lowBound; row++) {
+ widthCount = 0;
+ if (row >= _tileClip.top) {
+ drawPointer = (byte *)ds->pixels + drawPoint.x + (row * ds->pitch);
+ col = drawPoint.x;
+ for (;;) {
+ bgRunCount = *readPointer++;
+ widthCount += bgRunCount;
+ if (widthCount >= SAGA_ISOTILE_WIDTH) {
+ break;
+ }
+
+ drawPointer += bgRunCount;
+ col += bgRunCount;
+ fgRunCount = *readPointer++;
+ widthCount += fgRunCount;
+
+ count = 0;
+ while ((col < _tileClip.left) && (count < fgRunCount)) {
+ count++;
+ col++;
+ }
+ while ((col < _tileClip.right) && (count < fgRunCount)) {
+ assert((uint)ds->pixels <= (uint)(drawPointer + count));
+ assert(((uint)ds->pixels + (_vm->getDisplayWidth() * _vm->getDisplayHeight())) > (uint)(drawPointer + count));
+ drawPointer[count] = readPointer[count];
+ count++;
+ col++;
+ }
+ readPointer += fgRunCount;
+ drawPointer += fgRunCount;
+ }
+ } else {
+ for (;;) {
+ bgRunCount = *readPointer++;
+ widthCount += bgRunCount;
+ if (widthCount >= SAGA_ISOTILE_WIDTH) {
+ break;
+ }
+
+ fgRunCount = *readPointer++;
+ widthCount += fgRunCount;
+
+ readPointer += fgRunCount;
+ }
+ }
+ }
+
+}
+
} // End of namespace Saga
diff --git a/saga/isomap.h b/saga/isomap.h
index 4e31487725..1d937ea8de 100644
--- a/saga/isomap.h
+++ b/saga/isomap.h
@@ -26,6 +26,8 @@
#ifndef SAGA_ISOMAP_H_
#define SAGA_ISOMAP_H_
+#include "saga/actor.h"
+
namespace Saga {
#define SAGA_ISOTILEDATA_LEN 8
@@ -46,6 +48,11 @@ namespace Saga {
#define SAGA_MULTI_TILE (1 << 15)
+#define SAGA_SCROLL_LIMIT_X1 32
+#define SAGA_SCROLL_LIMIT_X2 64
+#define SAGA_SCROLL_LIMIT_Y1 8
+#define SAGA_SCROLL_LIMIT_Y2 32
+
enum TileMapEdgeType {
kEdgeTypeBlack = 0,
kEdgeTypeFill0 = 1,
@@ -106,12 +113,39 @@ public:
void loadMulti(const byte * resourcePointer, size_t resourceLength);
void freeMem();
int draw(SURFACE *ds);
+ void drawSprite(SURFACE *ds, SpriteList &spriteList, int spriteNumber, const Location &location, const Point &screenPosition, int scale);
+ void adjustScroll(bool jump);
+ void tileCoordsToScreenPoint(const Location &location, Point &position) {
+ position.x = location.u() - location.v() + (128 * SAGA_TILEMAP_W) - _viewScroll.x + 16;
+ position.y = -((location.u() + location.v()) >> 1) + (128 * SAGA_TILEMAP_W) - _viewScroll.y - location.z;
+ }
+
private:
- void drawTiles(SURFACE *ds);
+ void drawTiles(SURFACE *ds, const Location *location);
void drawMetaTile(SURFACE *ds, uint16 metaTileIndex, const Point &point, int16 absU, int16 absV);
+ void drawSpriteMetaTile(SURFACE *ds, uint16 metaTileIndex, const Point &point, Location &location, int16 absU, int16 absV);
void drawPlatform(SURFACE *ds, uint16 platformIndex, const Point &point, int16 absU, int16 absV, int16 absH);
+ void drawSpritePlatform(SURFACE *ds, uint16 platformIndex, const Point &point, const Location &location, int16 absU, int16 absV, int16 absH);
void drawTile(SURFACE *ds, uint16 tileIndex, const Point &point);
-
+ void drawSpriteTile(SURFACE *ds, uint16 tileIndex, const Location &location, const Point &point);
+ int16 smoothSlide(int16 value, int16 min, int16 max) {
+ if (value < min) {
+ if (value < min - 100 || value > min - 4) {
+ value = min;
+ } else {
+ value += 4;
+ }
+ } else {
+ if (value > max) {
+ if (value > max + 100 || value < max + 4) {
+ value = max;
+ } else {
+ value -= 4;
+ }
+ }
+ }
+ return value;
+ }
byte *_tileData;
size_t _tileDataLength;
@@ -128,7 +162,7 @@ private:
TileMapData _tileMap;
- Point _tileScroll;
+ Point _mapPosition;
public:
int _viewDiff;
Point _viewScroll;
diff --git a/saga/resnames.h b/saga/resnames.h
index 1d0e3aeec9..caf4199942 100644
--- a/saga/resnames.h
+++ b/saga/resnames.h
@@ -40,6 +40,9 @@ namespace Saga {
#define RID_IHNMDEMO_SCENE_LUT 286
#define RID_IHNMDEMO_SCRIPT_LUT 18
+//obj names
+#define ITE_OBJ_MAP 14
+
// SCENES
#define ITE_SCENE_INV -1
diff --git a/saga/scene.cpp b/saga/scene.cpp
index 6e0d1c2740..51b264b107 100644
--- a/saga/scene.cpp
+++ b/saga/scene.cpp
@@ -905,6 +905,7 @@ int Scene::draw(SURFACE *dst_s) {
_vm->_render->getBufferInfo(&buf_info);
if (_vm->_scene->getFlags() & kSceneFlagISO) {
+ _vm->_isoMap->adjustScroll(false);
_vm->_isoMap->draw(dst_s);
} else {
bufToSurface(dst_s, buf_info.bg_buf, _vm->getDisplayWidth(),
diff --git a/saga/sprite.cpp b/saga/sprite.cpp
index 906565102f..23f6a8e66c 100644
--- a/saga/sprite.cpp
+++ b/saga/sprite.cpp
@@ -170,48 +170,44 @@ 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 *bufRowPointer;
- const byte *srcRowPointer;
+void Sprite::drawClip(SURFACE *ds, Rect clip, const Point &spritePointer, int width, int height, const byte *spriteBuffer) {
int clipWidth;
int clipHeight;
- int width;
- int height;
- int xAlign;
- int yAlign;
- Point spritePointer;
- assert(_initialized);
-
- getScaledSpriteBuffer(spriteList, spriteNumber, scale, width, height, xAlign, yAlign, spriteBuffer);
-
- spritePointer.x = screenCoord.x + xAlign;
- spritePointer.y = screenCoord.y + yAlign;
-
- if (spritePointer.x < 0) {
- return 0;
- }
- if (spritePointer.y < 0) {
- return 0;
- }
+ int i, j, jo, io;
+ byte *bufRowPointer;
+ const byte *srcRowPointer;
bufRowPointer = (byte *)ds->pixels + ds->pitch * spritePointer.y;
srcRowPointer = spriteBuffer;
clipWidth = width;
- if (width > (ds->w - spritePointer.x)) {
- clipWidth = (ds->w - spritePointer.x);
+ if (width > (clip.right - spritePointer.x)) {
+ clipWidth = (clip.right - spritePointer.x);
}
clipHeight = height;
- if (height > (ds->h - spritePointer.y)) {
- clipHeight = (ds->h - spritePointer.y);
+ if (height > (clip.bottom - spritePointer.y)) {
+ clipHeight = (clip.bottom - spritePointer.y);
+ }
+
+ jo = 0;
+ io = 0;
+ if (spritePointer.x < clip.left) {
+ jo = clip.left - spritePointer.x;
+ }
+ if (spritePointer.y < clip.top) {
+ io = clip.top - spritePointer.y;
+ bufRowPointer += ds->pitch * io;
+ srcRowPointer += width * io;
}
+ for (i = io; i < clipHeight; i++) {
+ for (j = jo; j < clipWidth; j++) {
+ assert((uint)ds->pixels <= (uint)(bufRowPointer + j + spritePointer.x));
+ assert(((uint)ds->pixels + (_vm->getDisplayWidth() * _vm->getDisplayHeight())) > (uint)(bufRowPointer + j + spritePointer.x));
+ assert((uint)spriteBuffer <= (uint)(srcRowPointer + j));
+ assert(((uint)spriteBuffer + (width * height)) > (uint)(srcRowPointer + j));
- for (i = 0; i < clipHeight; i++) {
- for (j = 0; j < clipWidth; j++) {
if (*(srcRowPointer + j) != 0) {
*(bufRowPointer + j + spritePointer.x) = *(srcRowPointer + j);
}
@@ -219,6 +215,24 @@ int Sprite::draw(SURFACE *ds, SpriteList &spriteList, int spriteNumber, const Po
bufRowPointer += ds->pitch;
srcRowPointer += width;
}
+}
+
+int Sprite::draw(SURFACE *ds, SpriteList &spriteList, int spriteNumber, const Point &screenCoord, int scale) {
+ const byte *spriteBuffer;
+ int width;
+ int height;
+ int xAlign;
+ int yAlign;
+ Point spritePointer;
+ Rect clip(_vm->getDisplayWidth(),_vm->getDisplayHeight());
+
+ assert(_initialized);
+
+ getScaledSpriteBuffer(spriteList, spriteNumber, scale, width, height, xAlign, yAlign, spriteBuffer);
+
+ spritePointer.x = screenCoord.x + xAlign;
+ spritePointer.y = screenCoord.y + yAlign;
+ drawClip(ds, clip, spritePointer, width, height, spriteBuffer);
return SUCCESS;
}
diff --git a/saga/sprite.h b/saga/sprite.h
index 48abf5a52d..4907754c8b 100644
--- a/saga/sprite.h
+++ b/saga/sprite.h
@@ -65,16 +65,19 @@ class Sprite {
public:
SpriteList _mainSprites;
+
+
Sprite(SagaEngine *vm);
~Sprite(void);
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);
+ void getScaledSpriteBuffer(SpriteList &spriteList, int spriteNumber, int scale, int &width, int &height, int &xAlign, int &yAlign, const byte *&buffer);
+ void drawClip(SURFACE *ds, Rect clip, const Point &spritePointer, int width, int height, const byte *spriteBuffer);
private:
void decodeRLEBuffer(const byte *inputBuffer, size_t inLength, size_t outLength);
void scaleBuffer(const byte *src, int width, int height, int scale);
- void getScaledSpriteBuffer(SpriteList &spriteList, int spriteNumber, int scale, int &width, int &height, int &xAlign, int &yAlign, const byte *&buffer);
SagaEngine *_vm;
bool _initialized;