aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2007-10-20 22:35:23 +0000
committerPaul Gilbert2007-10-20 22:35:23 +0000
commit1aab730e6b28ee5f574c0fd91ce02b7d2fad2899 (patch)
treeec214533fe8766983d8c61aa90dd066dd3fa19ca
parentdd5be6826a081742c91ce8e9c36bf623b7754300 (diff)
downloadscummvm-rg350-1aab730e6b28ee5f574c0fd91ce02b7d2fad2899.tar.gz
scummvm-rg350-1aab730e6b28ee5f574c0fd91ce02b7d2fad2899.tar.bz2
scummvm-rg350-1aab730e6b28ee5f574c0fd91ce02b7d2fad2899.zip
Finally got the room layering to work correctly
svn-id: r29236
-rw-r--r--engines/lure/room.cpp118
-rw-r--r--engines/lure/room.h6
2 files changed, 56 insertions, 68 deletions
diff --git a/engines/lure/room.cpp b/engines/lure/room.cpp
index 947192099f..7c77ecbce7 100644
--- a/engines/lure/room.cpp
+++ b/engines/lure/room.cpp
@@ -39,10 +39,8 @@ RoomLayer::RoomLayer(uint16 screenId, bool backgroundLayer):
byte *screenData = data().data();
int cellY;
- // Reset all the cells to false
- for (cellY = 0; cellY < FULL_VERT_RECTS; ++cellY)
- for (int cellX = 0; cellX < FULL_HORIZ_RECTS; ++cellX)
- _cells[cellY][cellX] = false;
+ // Reset all the cells to unused
+ Common::set_to((bool *) _cells, (bool *) _cells + GRID_SIZE, false);
// Loop through each cell of the screen
for (cellY = 0; cellY < NUM_VERT_RECTS; ++cellY) {
@@ -55,7 +53,7 @@ RoomLayer::RoomLayer(uint16 screenId, bool backgroundLayer):
// Check the cell
for (int yP = 0; yP < RECT_SIZE; ++yP) {
if (hasPixels) break;
- byte *linePos = screenData + (cellY * RECT_SIZE + yP + 8)
+ byte *linePos = screenData + (cellY * RECT_SIZE + yP + MENUBAR_Y_SIZE)
* FULL_SCREEN_WIDTH + (cellX * RECT_SIZE);
for (int xP = 0; xP < RECT_SIZE; ++xP) {
@@ -267,27 +265,6 @@ CursorType Room::checkRoomExits() {
return CURSOR_ARROW;
}
-void Room::flagCoveredCells(Hotspot &h) {
- int16 yStart = (h.y() - MENUBAR_Y_SIZE) / RECT_SIZE;
- int16 yEnd = (h.y() + h.heightCopy() - 1 - MENUBAR_Y_SIZE) / RECT_SIZE;
- int16 numY = yEnd - yStart + 1;
- int16 xStart = h.x() / RECT_SIZE;
- int16 xEnd = (h.x() + h.width() - 1) / RECT_SIZE;
- int16 numX = xEnd - xStart + 1;
-
- int index = yStart * NUM_HORIZ_RECTS + xStart;
-
- for (int16 yP = 0; yP < numY; ++yP) {
- for (int16 xP = 0; xP < numX; ++xP) {
- int indexPos = index + xP;
- if ((indexPos < 0) || (indexPos >= NUM_HORIZ_RECTS*NUM_VERT_RECTS))
- continue;
- _cells[index+xP] = true;
- }
- index += NUM_HORIZ_RECTS;
- }
-}
-
void Room::addAnimation(Hotspot &h) {
Surface &s = _screen.screen();
char buffer[10];
@@ -303,8 +280,8 @@ void Room::addAnimation(Hotspot &h) {
}
void Room::addLayers(Hotspot &h) {
- int16 hsX = h.x() + (4 * RECT_SIZE);
- int16 hsY = h.y() + (4 * RECT_SIZE) - MENUBAR_Y_SIZE;
+ int16 hsX = h.x() + (NUM_EDGE_RECTS * RECT_SIZE);
+ int16 hsY = h.y() + (NUM_EDGE_RECTS * RECT_SIZE) - MENUBAR_Y_SIZE;
int16 xStart = hsX / RECT_SIZE;
int16 xEnd = (hsX + h.width()) / RECT_SIZE;
@@ -317,17 +294,18 @@ void Room::addLayers(Hotspot &h) {
return;
for (int16 xCtr = 0; xCtr < numX; ++xCtr, ++xStart) {
- int16 xs = xStart - 4;
+ int16 xs = xStart - NUM_EDGE_RECTS;
if (xs < 0) continue;
// Check foreground layers for an occupied one
- int layerNum = _numLayers - 1;
- while ((layerNum > 0) && !_layers[layerNum]->isOccupied(xStart, yEnd))
- --layerNum;
- if (layerNum == 0) continue;
+ int layerNum = 1;
+ while ((layerNum < 4) && (_layers[layerNum] != NULL) &&
+ !_layers[layerNum]->isOccupied(xStart, yEnd))
+ ++layerNum;
+ if ((layerNum == 4) || (_layers[layerNum] == NULL)) continue;
- int16 ye = yEnd - 4;
+ int16 ye = yEnd - NUM_EDGE_RECTS;
for (int16 yCtr = 0; yCtr < numY; ++yCtr, --ye) {
if (ye < 0) break;
addCell(xs, ye, layerNum);
@@ -338,13 +316,14 @@ void Room::addLayers(Hotspot &h) {
void Room::addCell(int16 xp, int16 yp, int layerNum) {
Surface &s = _screen.screen();
- while ((layerNum > 0) && !_layers[layerNum]->isOccupied(xp+4, yp+4))
- --layerNum;
- if (layerNum == 0) return;
+ while ((layerNum < 4) && (_layers[layerNum] != NULL) &&
+ !_layers[layerNum]->isOccupied(xp + NUM_EDGE_RECTS, yp + NUM_EDGE_RECTS))
+ ++layerNum;
+ if ((layerNum == 4) || (_layers[layerNum] == NULL)) return;
RoomLayer *layer = _layers[layerNum];
- int index = ((yp * RECT_SIZE + 8) * FULL_SCREEN_WIDTH) + (xp * RECT_SIZE);
+ int index = ((yp * RECT_SIZE + MENUBAR_Y_SIZE) * FULL_SCREEN_WIDTH) + (xp * RECT_SIZE);
byte *srcPos = layer->data().data() + index;
byte *destPos = s.data().data() + index;
@@ -360,15 +339,43 @@ void Room::addCell(int16 xp, int16 yp, int layerNum) {
}
}
+void Room::blockMerge() {
+ for (int layerNum1 = 0; layerNum1 < 3; ++layerNum1) {
+ if (_layers[layerNum1] == NULL) break;
+
+ for (int layerNum2 = layerNum1 + 1; layerNum2 < 4; ++layerNum2) {
+ if (_layers[layerNum2] == NULL) break;
+
+ for (int yp = 0; yp < NUM_VERT_RECTS; ++yp) {
+ for (int xp = 0; xp < NUM_HORIZ_RECTS; ++xp) {
+ if (_layers[layerNum1]->isOccupied(xp + NUM_EDGE_RECTS, yp + NUM_EDGE_RECTS) &&
+ _layers[layerNum2]->isOccupied(xp + NUM_EDGE_RECTS, yp + NUM_EDGE_RECTS)) {
+ // Copy the rect from the later layer onto the earlier layer
+ int offset = (yp * RECT_SIZE + MENUBAR_Y_SIZE) * FULL_SCREEN_WIDTH + (xp * RECT_SIZE);
+ byte *src = _layers[layerNum2]->data().data() + offset;
+ byte *dest = _layers[layerNum1]->data().data() + offset;
+
+ for (int y = 0; y < RECT_SIZE; ++y) {
+ for (int x = 0; x < RECT_SIZE; ++x, ++src, ++dest) {
+ if (*src != 0) *dest = *src;
+ }
+ src += FULL_SCREEN_WIDTH - RECT_SIZE;
+ dest += FULL_SCREEN_WIDTH - RECT_SIZE;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
void Room::update() {
Surface &s = _screen.screen();
Resources &res = Resources::getReference();
HotspotList &hotspots = res.activeHotspots();
HotspotList::iterator i;
- memset(_cells, false, NUM_HORIZ_RECTS*NUM_VERT_RECTS);
-
- // Copy the background to the temporary srceen surface
+ // Copy the background to the temporary screen surface
_layers[0]->copyTo(&s);
// Handle first layer (layer 3)
@@ -376,7 +383,6 @@ void Room::update() {
Hotspot &h = *i.operator*();
if ((h.roomNumber() == _roomNumber) && h.isActiveAnimation() && (h.layer() == 3)) {
- flagCoveredCells(h);
addAnimation(h);
addLayers(h);
}
@@ -401,7 +407,6 @@ void Room::update() {
}
for (iTemp = tempList.begin(); iTemp != tempList.end(); ++iTemp) {
Hotspot &h = *iTemp.operator*();
- flagCoveredCells(h);
addAnimation(h);
addLayers(h);
}
@@ -411,25 +416,10 @@ void Room::update() {
Hotspot &h = *i.operator*();
if ((h.roomNumber() == _roomNumber) && h.isActiveAnimation() && (h.layer() == 2)) {
- flagCoveredCells(h);
addAnimation(h);
}
}
- // Loop to add in any remaining cells
- for (int yp = 0; yp < NUM_VERT_RECTS; ++yp) {
- for (int xp = 0; xp < NUM_HORIZ_RECTS; ++xp) {
- if (_cells[yp*NUM_HORIZ_RECTS+xp]) continue;
-
- int layerNum = _numLayers - 1;
- while ((layerNum > 0) && !_layers[layerNum]->isOccupied(xp+4, yp+4))
- --layerNum;
- if (layerNum != 0)
- // Add in the cell
- addCell(xp, yp, layerNum);
- }
- }
-
// Show any active talk dialog
if (_talkDialog) {
// Make sure the character is still active and in the viewing room
@@ -486,7 +476,8 @@ void Room::update() {
}
Mouse &m = Mouse::getReference();
- sprintf(buffer, "Room %d Pos (%d,%d)", _roomNumber, m.x(), m.y());
+ sprintf(buffer, "Room %d Pos (%d,%d) @ (%d,%d)", _roomNumber, m.x(), m.y(),
+ m.x() / RECT_SIZE, (m.y() - MENUBAR_Y_SIZE) / RECT_SIZE);
s.writeString(FULL_SCREEN_WIDTH / 2, 0, buffer, false, DIALOG_TEXT_COLOUR);
}
}
@@ -521,12 +512,9 @@ void Room::setRoomNumber(uint16 newRoomNumber, bool showOverlay) {
for (uint8 layerNum = 0; layerNum < _numLayers; ++layerNum)
_layers[layerNum] = new RoomLayer(_roomData->layers[layerNum],
layerNum == 0);
-/*
- // Load in the game palette, which contains at it's top end general GUI element colours
- Palette mainPalette(GAME_PALETTE_RESOURCE_ID);
- _screen.setPalette(&mainPalette, RES_PALETTE_ENTRIES,
- GAME_COLOURS - RES_PALETTE_ENTRIES);
-*/
+
+ blockMerge();
+
// Generate the palette for the room that will be faded in
Palette p(MAIN_PALETTE_SIZE, NULL, RGB64);
Palette tempPalette(paletteId);
diff --git a/engines/lure/room.h b/engines/lure/room.h
index b97df2f46a..8cda59415e 100644
--- a/engines/lure/room.h
+++ b/engines/lure/room.h
@@ -43,6 +43,7 @@ namespace Lure {
#define FULL_HORIZ_RECTS 18
#define FULL_VERT_RECTS 14
#define NUM_EDGE_RECTS 4
+#define GRID_SIZE (FULL_VERT_RECTS * FULL_HORIZ_RECTS)
class RoomLayer: public Surface {
private:
@@ -72,7 +73,6 @@ private:
bool _showInfo;
uint8 _numLayers;
RoomLayer *_layers[MAX_NUM_LAYERS];
- bool _cells[NUM_HORIZ_RECTS*NUM_VERT_RECTS];
TalkDialog *_talkDialog;
int16 _talkDialogX, _talkDialogY;
CursorState _cursorState;
@@ -80,11 +80,10 @@ private:
void checkRoomHotspots();
CursorType checkRoomExits();
void loadRoomHotspots();
- bool sub_112() { return false; } // not yet implemented
- void flagCoveredCells(Hotspot &h);
void addAnimation(Hotspot &h);
void addLayers(Hotspot &h);
void addCell(int16 xp, int16 yp, int layerNum);
+ void blockMerge();
public:
RoomPathsDecompressedData tempLayer;
Room();
@@ -97,6 +96,7 @@ public:
uint16 roomNumber() { return _roomNumber; }
void setRoomNumber(uint16 newRoomNumber, bool showOverlay = false);
void leaveRoom();
+ uint8 numLayers() { return _numLayers; }
uint16 hotspotId() { return _hotspotId; }
uint16 destRoomNumber() { return _destRoomNumber; }
uint16 isExit() { return _isExit; }