diff options
author | Andrew Kurushin | 2005-02-18 00:00:00 +0000 |
---|---|---|
committer | Andrew Kurushin | 2005-02-18 00:00:00 +0000 |
commit | bbbd3b5fbf1230e681fad01e80717bc1785e0d09 (patch) | |
tree | e6ece1dcf27eef28d85915deed0b1e592f326648 /saga | |
parent | def8641e1f748a193db6afe060729ef242883409 (diff) | |
download | scummvm-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.cpp | 10 | ||||
-rw-r--r-- | saga/actor.h | 6 | ||||
-rw-r--r-- | saga/isomap.cpp | 315 | ||||
-rw-r--r-- | saga/isomap.h | 40 | ||||
-rw-r--r-- | saga/resnames.h | 3 | ||||
-rw-r--r-- | saga/scene.cpp | 1 | ||||
-rw-r--r-- | saga/sprite.cpp | 72 | ||||
-rw-r--r-- | saga/sprite.h | 5 |
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; |