aboutsummaryrefslogtreecommitdiff
path: root/saga
diff options
context:
space:
mode:
authorAndrew Kurushin2005-02-22 20:18:55 +0000
committerAndrew Kurushin2005-02-22 20:18:55 +0000
commitbe2049a338e68097e334547340af033f4a820358 (patch)
tree66252203403b463231b123dbf6be2de1f3134e2f /saga
parente7b8a1eada84dc51e68bafbbf4f89903003d3c3f (diff)
downloadscummvm-rg350-be2049a338e68097e334547340af033f4a820358.tar.gz
scummvm-rg350-be2049a338e68097e334547340af033f4a820358.tar.bz2
scummvm-rg350-be2049a338e68097e334547340af033f4a820358.zip
3 stage iso drawing implemented:
1)iso scene 2)figure 3)tiles above figure svn-id: r16864
Diffstat (limited to 'saga')
-rw-r--r--saga/isomap.cpp180
-rw-r--r--saga/isomap.h7
2 files changed, 180 insertions, 7 deletions
diff --git a/saga/isomap.cpp b/saga/isomap.cpp
index f6b2123bd2..bbbfc62d9c 100644
--- a/saga/isomap.cpp
+++ b/saga/isomap.cpp
@@ -33,6 +33,24 @@
namespace Saga {
+enum MaskRules {
+ kMaskRuleNever = 0,
+ kMaskRuleAlways,
+ kMaskRuleUMIN,
+ kMaskRuleUMID,
+ kMaskRuleUMAX,
+ kMaskRuleVMIN,
+ kMaskRuleVMID,
+ kMaskRuleVMAX,
+ kMaskRuleYMIN,
+ kMaskRuleYMID,
+ kMaskRuleYMAX,
+ kMaskRuleUVMAX,
+ kMaskRuleUVMIN,
+ kMaskRuleUorV,
+ kMaskRuleUandV
+};
+
IsoMap::IsoMap(SagaEngine *vm) : _vm(vm) {
_tileData = NULL;
_tilesCount = 0;
@@ -42,6 +60,8 @@ IsoMap::IsoMap(SagaEngine *vm) : _vm(vm) {
_metaTilesCount = 0;
_multiTable = NULL;
_multiCount = 0;
+ _multiTableData = NULL;
+ _multiDataCount = 0;
_viewScroll.x = (128 - 8) * 16;
_viewScroll.x = (128 - 8) * 16 - 64;
_viewDiff = 1;
@@ -188,6 +208,16 @@ void IsoMap::loadMulti(const byte * resourcePointer, size_t resourceLength) {
multiTileEntryData->currentState = readS.readByte();
readS.readByte();//skip
}
+ for (i = 0; i < _multiCount; i++) {
+ _multiTable[i].offset -= readS.pos();
+ }
+
+ _multiDataCount = (readS.size() - readS.pos()) / 2;
+
+ _multiTableData = (int16 *)malloc(_multiDataCount * sizeof(*_multiTableData));
+ for (i = 0; i < _multiDataCount; i++) {
+ _multiTableData[i] = readS.readSint16();
+ }
}
void IsoMap::freeMem() {
@@ -199,6 +229,8 @@ void IsoMap::freeMem() {
_metaTilesCount = 0;
free(_multiTable);
_multiCount = 0;
+ free(_multiTableData);
+ _multiDataCount = 0;
}
void IsoMap::adjustScroll(bool jump) {
@@ -258,6 +290,48 @@ void IsoMap::adjustScroll(bool jump) {
}
}
+int16 IsoMap::findMulti(int16 tileIndex, int16 absU, int16 absV, int16 absH) {
+ MultiTileEntryData *multiTileEntryData;
+ int16 ru;
+ int16 rv;
+ int16 mu;
+ int16 mv;
+ int16 state;
+ uint16 i, offset;
+
+ ru = (tileIndex >> 13) & 0x03;
+ rv = (tileIndex >> 11) & 0x03;
+ mu = absU - ru;
+ mv = absV - rv;
+
+ tileIndex = 0;
+ for (i = 0; i < _multiCount; i++) {
+ multiTileEntryData = &_multiTable[i];
+
+ if ((multiTileEntryData->u == mu) &&
+ (multiTileEntryData->v == mv) &&
+ (multiTileEntryData->h == absH)) {
+ state = multiTileEntryData->currentState;
+
+ offset = (ru + state * multiTileEntryData->uSize) * multiTileEntryData->vSize + rv;
+ offset += multiTileEntryData->offset;
+ if (offset >= _multiDataCount * sizeof(*_multiTableData)) {
+ error("wrong multiTileEntryData->offset");
+ }
+ tileIndex = _multiTableData[offset];
+ if (tileIndex >= 256) {
+ warning("something terrible happened");
+ return 1;
+ }
+
+ return tileIndex;
+ }
+ }
+
+ warning("something terrible happened");
+ return 1;
+}
+
int IsoMap::draw(SURFACE *ds) {
Rect isoRect(_vm->getDisplayWidth(), _vm->getDisplayInfo().sceneHeight);
@@ -282,10 +356,10 @@ void IsoMap::drawSprite(SURFACE *ds, SpriteList &spriteList, int spriteNumber, c
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;
+ _tileClip.left = spritePointer.x;
+ _tileClip.top = spritePointer.y;
+ _tileClip.right = spritePointer.x + width;
+ _tileClip.bottom = spritePointer.y + height;
if (_tileClip.left < 0) {
_tileClip.left = 0;
@@ -526,7 +600,7 @@ void IsoMap::drawSpritePlatform(SURFACE *ds, uint16 platformIndex, const Point &
tileIndex = tilePlatform->tiles[u][v];
if (tileIndex != 0) {
if (tileIndex & SAGA_MULTI_TILE) {
- warning("SAGA_MULTI_TILE"); //TODO: do it !
+ tileIndex = findMulti(tileIndex, absU + u, absU + v, absH);
}
drawSpriteTile(ds, tileIndex, location, s);
@@ -578,7 +652,7 @@ void IsoMap::drawPlatform(SURFACE *ds, uint16 platformIndex, const Point &point,
tileIndex = tilePlatform->tiles[u][v];
if (tileIndex > 1) {
if (tileIndex & SAGA_MULTI_TILE) {
- warning("SAGA_MULTI_TILE"); //TODO: do it !
+ tileIndex = findMulti(tileIndex, absU + u, absU + v, absH);
}
drawTile(ds, tileIndex, s);
@@ -681,6 +755,10 @@ void IsoMap::drawTile(SURFACE *ds, uint16 tileIndex, const Point &point) {
}
+#define THRESH0 0
+#define THRESH8 8
+#define THRESH16 16
+
void IsoMap::drawSpriteTile(SURFACE *ds, uint16 tileIndex, const Location &location, const Point &point) {
const byte *tilePointer;
const byte *readPointer;
@@ -692,7 +770,6 @@ void IsoMap::drawSpriteTile(SURFACE *ds, uint16 tileIndex, const Location &locat
int bgRunCount;
int fgRunCount;
-
if (tileIndex >= _tilesCount) {
error("IsoMap::drawTile wrong tileIndex");
}
@@ -722,6 +799,95 @@ void IsoMap::drawSpriteTile(SURFACE *ds, uint16 tileIndex, const Location &locat
return;
}
+ if (location.z <= -16) {
+ if (location.z <= -48) {
+ if (location.u() < -THRESH8 || location.v() < -THRESH8) {
+ return;
+ }
+ } else {
+ if (location.u() < THRESH0 || location.v() < THRESH0) {
+ return;
+ }
+ }
+ } else {
+ if (location.z >= 16) {
+ return;
+ } else {
+ switch (_tilesTable[tileIndex].GetMaskRule()) {
+ case kMaskRuleNever:
+ return;
+ case kMaskRuleAlways:
+ break;
+ case kMaskRuleUMIN:
+ if (location.u() < THRESH0) {
+ return;
+ }
+ break;
+ case kMaskRuleUMID:
+ if (location.u() < THRESH8) {
+ return;
+ }
+ break;
+ case kMaskRuleUMAX:
+ if (location.u() < THRESH16) {
+ return;
+ }
+ break;
+ case kMaskRuleVMIN:
+ if (location.v() < THRESH0) {
+ return;
+ }
+ break;
+ case kMaskRuleVMID:
+ if (location.v() < THRESH8) {
+ return;
+ }
+ break;
+ case kMaskRuleVMAX:
+ if (location.v() < THRESH16) {
+ return;
+ }
+ break;
+ case kMaskRuleYMIN:
+ if (location.u() + location.v() < THRESH0 * 2) {
+ return;
+ }
+ break;
+ case kMaskRuleYMID:
+ if (location.u() + location.v() < THRESH8 * 2) {
+ return;
+ }
+ break;
+ case kMaskRuleYMAX:
+ if (location.u() + location.v() < THRESH16 * 2) {
+ return;
+ }
+ break;
+ case kMaskRuleUVMAX:
+ if (location.u() < THRESH16 && location.v() < THRESH16) {
+ return;
+ }
+ break;
+ case kMaskRuleUVMIN:
+ if (location.u() < THRESH0 || location.v() < THRESH0) {
+ return;
+ }
+ break;
+ case kMaskRuleUorV:
+ if (location.u() < THRESH8 && location.v() < THRESH8) {
+ return;
+ }
+ break;
+ case kMaskRuleUandV:
+ if (location.u() < THRESH8 || location.v() < THRESH8) {
+ return;
+ }
+ break;
+ }
+ }
+ }
+
+///
readPointer = tilePointer;
lowBound = MIN((int)(drawPoint.y + height), (int)_tileClip.bottom);
for (row = drawPoint.y; row < lowBound; row++) {
diff --git a/saga/isomap.h b/saga/isomap.h
index 1d937ea8de..a19cf24653 100644
--- a/saga/isomap.h
+++ b/saga/isomap.h
@@ -67,6 +67,9 @@ struct IsoTileData {
size_t offset;
uint16 terrainMask;
byte FGBGAttr;
+ int8 GetMaskRule() {
+ return attributes & 0x0F;
+ }
};
struct TilePlatformData {
@@ -146,6 +149,8 @@ private:
}
return value;
}
+ int16 findMulti(int16 tileIndex, int16 absU, int16 absV, int16 absH );
+
byte *_tileData;
size_t _tileDataLength;
@@ -159,6 +164,8 @@ private:
uint16 _multiCount;
MultiTileEntryData *_multiTable;
+ uint16 _multiDataCount;
+ int16 *_multiTableData;
TileMapData _tileMap;