From ea78766c46041f9252e6b058f736503e6458f03d Mon Sep 17 00:00:00 2001 From: Andrew Kurushin Date: Wed, 9 Feb 2005 20:30:45 +0000 Subject: first step in ISO mode implementation - trying to draw iso scene svn-id: r16763 --- saga/actor.cpp | 45 +++++++---- saga/actor.h | 6 ++ saga/isomap.cpp | 229 ++++++++++++++++++++++++++++++++++++++++++++++++++------ saga/isomap.h | 37 +++++++-- saga/scene.cpp | 7 +- 5 files changed, 278 insertions(+), 46 deletions(-) (limited to 'saga') diff --git a/saga/actor.cpp b/saga/actor.cpp index 6474dd82a3..9809d1e2fb 100644 --- a/saga/actor.cpp +++ b/saga/actor.cpp @@ -410,10 +410,14 @@ void Actor::realLocation(Location &location, uint16 objectId, uint16 walkFlags) int angle; int distance; ActorData *actor; + ObjectData *obj; if (walkFlags & kWalkUseAngle) { - // tiled stuff if (_vm->_scene->getFlags() & kSceneFlagISO) { - //todo: it + angle = (location.x + 2) & 15; + distance = location.y; + + location.u() = (angleLUT[angle][0] * distance) >> 8; + location.v() = (angleLUT[angle][1] * distance) >> 8; } else { angle = location.x & 15; distance = location.y; @@ -426,9 +430,12 @@ void Actor::realLocation(Location &location, uint16 objectId, uint16 walkFlags) if (objectId != ID_NOTHING) { if (validActorId(objectId)) { actor = getActor(objectId); - location.add( actor->location); + location.add(actor->location); } else { - warning("ObjectId unsupported"); //todo: do it + if (validObjId(objectId)) { + obj = getObj(objectId); + location.add(obj->location); + } } } @@ -439,12 +446,16 @@ void Actor::actorFaceTowardsPoint(uint16 actorId, const Location &toLocation) { Location delta; actor = getActor(actorId); + + toLocation.delta(actor->location, delta); - // tiled stuff if (_vm->_scene->getFlags() & kSceneFlagISO) { - //todo: it + if (delta.u() > 0) { + actor->facingDirection = (delta.v() > 0) ? kDirUp : kDirRight; + } else { + actor->facingDirection = (delta.v() > 0) ? kDirLeft : kDirDown; + } } else { - toLocation.delta(actor->location, delta); if (ABS(delta.y) > ABS(delta.x * 2)) { actor->facingDirection = (delta.y > 0) ? kDirDown : kDirUp; @@ -456,12 +467,16 @@ void Actor::actorFaceTowardsPoint(uint16 actorId, const Location &toLocation) { void Actor::actorFaceTowardsObject(uint16 actorId, uint16 objectId) { ActorData *actor; + ObjectData *obj; if (validActorId(objectId)) { actor = getActor(objectId); actorFaceTowardsPoint(actorId, actor->location); } else { - warning("ObjectId unsupported"); //todo: do it + if (validObjId(objectId)) { + obj = getObj(objectId); + actorFaceTowardsPoint(actorId, obj->location); + } } } @@ -545,23 +560,22 @@ void Actor::updateActorsScene(int actorsEntrance) { if (actorsEntrance >= 0) { sceneEntry = _vm->_scene->_entryList.getEntry(actorsEntrance); - // tiled stuff if (_vm->_scene->getFlags() & kSceneFlagISO) { - //todo: it + _protagonist->location = sceneEntry->location; } else { _protagonist->location.x = sceneEntry->location.x * ACTOR_LMULT; _protagonist->location.y = sceneEntry->location.y * ACTOR_LMULT; _protagonist->location.z = sceneEntry->location.z * ACTOR_LMULT; - _protagonist->facingDirection = _protagonist->actionDirection = sceneEntry->facing; } + _protagonist->facingDirection = _protagonist->actionDirection = sceneEntry->facing; } _protagonist->currentAction = kActionWait; if (_vm->_scene->getFlags() & kSceneFlagISO) { - //todo: it + //nothing? } else { - _vm->_scene->initDoorsState(); + _vm->_scene->initDoorsState(); //TODO: move to _scene } followerDirection = _protagonist->facingDirection + 3; @@ -1114,6 +1128,9 @@ bool Actor::getSpriteParams(CommonObjectData *commonObjectData, int &frameNumber } if ((frameNumber < 0) || (spriteList->spriteCount <= frameNumber)) { + if (_vm->_scene->getFlags() & kSceneFlagISO) { // TODO: remove it + return false; + } warning("Actor::getSpriteParams frameNumber invalid for object id 0x%X", commonObjectData->id); return false; } @@ -1131,9 +1148,11 @@ int Actor::drawActors() { back_buf = _vm->_gfx->getBackBuffer(); createDrawOrderList(); + for (drawOrderIterator = _drawOrderList.begin(); drawOrderIterator != _drawOrderList.end(); ++drawOrderIterator) { drawObject = drawOrderIterator.operator*(); + if (!getSpriteParams(drawObject, frameNumber, spriteList)) { continue; } diff --git a/saga/actor.h b/saga/actor.h index 32ea2812a0..5d43efd137 100644 --- a/saga/actor.h +++ b/saga/actor.h @@ -140,6 +140,12 @@ struct Location { int distance(const Location &location) const { return MAX(ABS(x - location.x), ABS(y - location.y)); } + int &u() { + return x; + } + int &v() { + 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 76ec5bfe7e..df43d76af3 100644 --- a/saga/isomap.cpp +++ b/saga/isomap.cpp @@ -40,6 +40,8 @@ IsoMap::IsoMap(SagaEngine *vm) : _vm(vm) { _metaTilesCount = 0; _multiTable = NULL; _multiCount = 0; + _viewScroll.x = (128 - 8) * 16; + _viewScroll.x = (128 - 8) * 16 - 64; } void IsoMap::loadImages(const byte *resourcePointer, size_t resourceLength) { @@ -169,10 +171,10 @@ void IsoMap::loadMulti(const byte * resourcePointer, size_t resourceLength) { if (_multiTable == NULL) { memoryError("IsoMap::loadMulti"); } - debug(0,"resourceLength=%d but should be %d",resourceLength, 12*_multiCount + 2); + debug(0,"resourceLength=%d but should be %d",resourceLength, 14*_multiCount + 2); for (i = 0; i < _multiCount; i++) { multiTileEntryData = &_multiTable[i]; - readS.readUint16();//skip + readS.readUint32();//skip multiTileEntryData->offset = readS.readSint16(); multiTileEntryData->u = readS.readByte(); multiTileEntryData->v = readS.readByte(); @@ -196,17 +198,195 @@ void IsoMap::freeMem() { _multiCount = 0; } -int IsoMap::draw(SURFACE *dst_s) { +int IsoMap::draw(SURFACE *ds) { -/* Rect iso_rect(disp_info.logical_w, disp_info.scene_h); - drawRect(dst_s, &iso_rect, 0); - drawMetamap(dst_s, -1000, -500); -*/ + Rect iso_rect(_vm->getDisplayWidth(), _vm->getDisplayInfo().sceneHeight); + drawRect(ds, &iso_rect, 0); + drawTiles(ds); + return SUCCESS; } -int IsoMap::drawMetamap(SURFACE *dst_s, int map_x, int map_y) { -/* int meta_base_x = map_x; +void IsoMap::drawTiles(SURFACE *ds) { + Point view1; + Point meta; + int16 u0, v0, + u1, v1, + u2, v2, + uc, vc; + int16 work_area_w; + int16 work_area_h; + int16 tx; + uint16 metaTileIndex; + + _tileScroll.x = _viewScroll.x >> 4; + _tileScroll.y = _viewScroll.y >> 4; + + 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; + + meta.x = (u0 - v0) * 128 - view1.x * 16; + meta.y = view1.y * 16 - (u0 + v0) * 64; + + work_area_w = _vm->getDisplayWidth(); + work_area_h = _vm->getDisplayInfo().sceneHeight; + setTileClip(0, work_area_w, 0, work_area_h); + + + for (u1 = u0, v1 = v0; meta.y < work_area_h + 128 + 80; u1--, v1-- ) { + tx = meta.x; + + for (u2 = u1, v2 = v1; tx < work_area_w + 128; u2++, v2--, tx += 256) { + + uc = u2 & (SAGA_TILEMAP_W - 1); + vc = v2 & (SAGA_TILEMAP_W - 1); + + if (uc != u2 || vc != v2) { + metaTileIndex = 0; + switch ( _tileMap.edgeType) { + case kEdgeTypeBlack: + continue; + case kEdgeTypeFill0: + metaTileIndex = 0; //TODO:remove + break; + case kEdgeTypeFill1: + metaTileIndex = 1; + break; + case kEdgeTypeRpt: + uc = clamp( 0, u2, SAGA_TILEMAP_W - 1); + vc = clamp( 0, v2, SAGA_TILEMAP_W - 1); + metaTileIndex = _tileMap.tilePlatforms[uc][vc]; + break; + case kEdgeTypeWrap: + metaTileIndex = _tileMap.tilePlatforms[uc][vc]; + break; + } + } else { + metaTileIndex = _tileMap.tilePlatforms[uc][vc]; + } + + drawMetaTile(ds, metaTileIndex, tx, meta.y, u2 << 3, v2 << 3); + } + + meta.y += 64; + + tx = meta.x - 128; + + for (u2 = u1 - 1, v2 = v1; tx < work_area_w + 128; u2++, v2--, tx += 256) { + + uc = u2 & (SAGA_TILEMAP_W - 1); + vc = v2 & (SAGA_TILEMAP_W - 1); + + if (uc != u2 || vc != v2) { + metaTileIndex = 0; + switch ( _tileMap.edgeType) { + case kEdgeTypeBlack: + continue; + case kEdgeTypeFill0: + metaTileIndex = 0; //TODO:remove + break; + case kEdgeTypeFill1: + metaTileIndex = 1; + break; + case kEdgeTypeRpt: + uc = clamp( 0, u2, SAGA_TILEMAP_W - 1); + vc = clamp( 0, v2, SAGA_TILEMAP_W - 1); + metaTileIndex = _tileMap.tilePlatforms[uc][vc]; + break; + case kEdgeTypeWrap: + metaTileIndex = _tileMap.tilePlatforms[uc][vc]; + break; + } + } else { + metaTileIndex = _tileMap.tilePlatforms[uc][vc]; + } + + drawMetaTile(ds, metaTileIndex, tx, meta.y, u2 << 3, v2 << 3); + } + meta.y += 64; + } + +} + +void IsoMap::drawMetaTile(SURFACE *ds, uint16 metaTileIndex, int16 x, int16 y, int16 absU, int16 absV) { + MetaTileData * metaTile; + uint16 high; + int16 platformIndex; + + 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++, y -= 8) { + assert(SAGA_MAX_PLATFORM_H > high); + platformIndex = metaTile->stack[high]; + + if (platformIndex >= 0) { + drawPlatform( ds, platformIndex, x, y, absU, absV, high ); + } + } +} + +void IsoMap::drawPlatform(SURFACE *ds, uint16 platformIndex, int16 x, int16 y, int16 absU, int16 absV, int16 absH) { + TilePlatformData *tilePlatform; + int16 u, v; + int16 sx0, sy0; + Point s; + int16 tileIndex; + + if (_tilePlatformsCount <= platformIndex) { + error("IsoMap::drawPlatform wrong platformIndex"); + } + + tilePlatform = &_tilePlatformList[platformIndex]; + + if ((y <= _tileClipTop) || (y - SAGA_MAX_TILE_H - SAGA_PLATFORM_W * SAGA_TILE_NOMINAL_H >= _tileClipBottom)) { + return; + } + + sx0 = x; + sy0 = y - (((SAGA_PLATFORM_W - 1) + (SAGA_PLATFORM_W - 1)) * 8); + + for (v = SAGA_PLATFORM_W - 1; v >= 0 && sy0 - SAGA_MAX_TILE_H < _tileClipBottom && sx0 - 128 < _tileClipRight; v--, sx0 += 16, sy0 += 8) { + + if ((tilePlatform->vBits & (1 << v)) == 0) { + continue; + } + + if (sx0 + 128 + 32 < _tileClipLeft) { + continue; + } + + s.x = sx0; + s.y = sy0; + + for (u = SAGA_PLATFORM_W - 1; u >= 0 && s.x + 32 > _tileClipLeft && s.y - SAGA_MAX_TILE_H < _tileClipBottom; u--, s.x -= 16, s.y += 8 ) { + if (s.x < _tileClipRight && s.y > _tileClipTop) { + + tileIndex = tilePlatform->tiles[u][v]; + if (tileIndex > 1) { + if (tileIndex & SAGA_MULTI_TILE) { + warning("SAGA_MULTI_TILE"); //TODO: do it ! + } + + drawTile(ds, tileIndex, s); + } + } + } + } +} + +/*int IsoMap::drawMetamap(SURFACE *dst_s, int map_x, int map_y) { + int meta_base_x = map_x; int meta_base_y = map_y; int meta_xi; int meta_yi; @@ -226,7 +406,6 @@ int IsoMap::drawMetamap(SURFACE *dst_s, int map_x, int map_y) { meta_base_x -= 128; meta_base_y += 64; } -*/ return SUCCESS; } @@ -259,8 +438,8 @@ int IsoMap::drawMetaTile(SURFACE *ds, uint16 platformNumber, const Point &point) return SUCCESS; } - -int IsoMap::drawTile(SURFACE *ds, uint16 tileNumber, const Point &point) { +*/ +void IsoMap::drawTile(SURFACE *ds, uint16 tileIndex, const Point &point) { const byte *tilePointer; const byte *readPointer; byte *drawPointer; @@ -273,35 +452,40 @@ int IsoMap::drawTile(SURFACE *ds, uint16 tileNumber, const Point &point) { int ct; - if (tileNumber >= _tilesCount) { - return FAILURE; + if (tileIndex >= _tilesCount) { + error("IsoMap::drawTile wrong tileIndex"); } + /* temporary x clip */ if (point.x < 0) { - return SUCCESS; + return; } /* temporary x clip */ - if (point.x >= ds->w - 32) { - return SUCCESS; + if (point.x >= _tileClipRight - 32) { + return; } - tilePointer = _tileData + _tilesTable[tileNumber].offset; - height = _tilesTable[tileNumber].height; + tilePointer = _tileData + _tilesTable[tileIndex].offset; + height = _tilesTable[tileIndex].height; readPointer = tilePointer; drawPointer = (byte *)ds->pixels + point.x + (point.y * ds->pitch); drawPoint = point; + if (point.y - height >= _tileClipBottom) { + return; + } + if (height > SAGA_ISOTILE_BASEHEIGHT) { drawPoint.y -= (height - SAGA_ISOTILE_BASEHEIGHT); } // temporary y clip if (drawPoint.y < 0) { - return SUCCESS; + return; } for (row = 0; row < height; row++) { @@ -309,8 +493,8 @@ int IsoMap::drawTile(SURFACE *ds, uint16 tileNumber, const Point &point) { widthCount = 0; // temporary y clip - if ((drawPoint.y + row) >= _vm->getDisplayInfo().sceneHeight) { - return SUCCESS; + if ((drawPoint.y + row) >= _tileClipBottom) { + return; } for (;;) { @@ -330,7 +514,6 @@ int IsoMap::drawTile(SURFACE *ds, uint16 tileNumber, const Point &point) { } } - return SUCCESS; } } // End of namespace Saga diff --git a/saga/isomap.h b/saga/isomap.h index 72d04e3751..28f4794433 100644 --- a/saga/isomap.h +++ b/saga/isomap.h @@ -31,6 +31,8 @@ namespace Saga { #define SAGA_ISOTILEDATA_LEN 8 #define SAGA_ISOTILE_WIDTH 32 #define SAGA_ISOTILE_BASEHEIGHT 15 +#define SAGA_TILE_NOMINAL_H 16 +#define SAGA_MAX_TILE_H 64 #define SAGA_TILEPLATFORMDATA_LEN 136 #define SAGA_PLATFORM_W 8 @@ -42,6 +44,16 @@ namespace Saga { #define SAGA_METATILEDATA_LEN 36 +#define SAGA_MULTI_TILE (1 << 15) + +enum TileMapEdgeType { + kEdgeTypeBlack = 0, + kEdgeTypeFill0 = 1, + kEdgeTypeFill1 = 2, + kEdgeTypeRpt = 3, + kEdgeTypeWrap = 4 +}; + struct IsoTileData { byte height; int8 attributes; @@ -50,7 +62,6 @@ struct IsoTileData { byte FGBGAttr; }; - struct TilePlatformData { int16 metaTile; int16 height; @@ -94,12 +105,24 @@ public: void loadMetaTiles(const byte * resourcePointer, size_t resourceLength); void loadMulti(const byte * resourcePointer, size_t resourceLength); void freeMem(); - int draw(SURFACE *dst_s); + int draw(SURFACE *ds); private: - int drawTile(SURFACE *ds, uint16 tileNumber, const Point &point); - int drawMetaTile(SURFACE *ds, uint16 platformNumber, const Point &point); - int drawMetamap(SURFACE *dst_s, int map_x, int map_y); + void drawTiles(SURFACE *ds); + void drawMetaTile(SURFACE *ds, uint16 metaTileIndex, int16 x, int16 y, int16 absU, int16 absV); + void drawPlatform(SURFACE *ds, uint16 platformIndex, int16 x, int16 y, int16 absU, int16 absV, int16 absH); + void setTileClip(int16 left, int16 right, int16 top, int16 bottom) { + _tileClipLeft = left; + _tileClipRight = right; + _tileClipTop = top; + _tileClipBottom = bottom; + } + + void drawTile(SURFACE *ds, uint16 tileIndex, const Point &point); + //int drawMetaTile(SURFACE *ds, uint16 platformNumber, const Point &point); + //int drawMetamap(SURFACE *dst_s, int map_x, int map_y); + + byte *_tileData; size_t _tileDataLength; uint16 _tilesCount; @@ -114,6 +137,10 @@ private: MultiTileEntryData *_multiTable; TileMapData _tileMap; + + Point _tileScroll; + Point _viewScroll; + int16 _tileClipLeft, _tileClipRight, _tileClipTop, _tileClipBottom; SagaEngine *_vm; }; diff --git a/saga/scene.cpp b/saga/scene.cpp index 131460697e..6e0d1c2740 100644 --- a/saga/scene.cpp +++ b/saga/scene.cpp @@ -898,20 +898,17 @@ int Scene::processSceneResources() { int Scene::draw(SURFACE *dst_s) { BUFFER_INFO buf_info; - Point bg_pt; + Point bgPoint(0, 0); assert(_initialized); _vm->_render->getBufferInfo(&buf_info); - bg_pt.x = 0; - bg_pt.y = 0; - if (_vm->_scene->getFlags() & kSceneFlagISO) { _vm->_isoMap->draw(dst_s); } else { bufToSurface(dst_s, buf_info.bg_buf, _vm->getDisplayWidth(), - MAX(_vm->getSceneHeight(), _bg.h), NULL, &bg_pt); + MAX(_vm->getSceneHeight(), _bg.h), NULL, &bgPoint); } return SUCCESS; -- cgit v1.2.3