diff options
Diffstat (limited to 'lure/room.cpp')
-rw-r--r-- | lure/room.cpp | 485 |
1 files changed, 0 insertions, 485 deletions
diff --git a/lure/room.cpp b/lure/room.cpp deleted file mode 100644 index 748ffccd28..0000000000 --- a/lure/room.cpp +++ /dev/null @@ -1,485 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2005-2006 The ScummVM project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "lure/room.h" -#include "lure/luredefs.h" -#include "lure/res.h" -#include "lure/screen.h" -#include "lure/events.h" -#include "lure/strings.h" -#include "lure/scripts.h" - -namespace Lure { - -static Room *int_room; - -RoomLayer::RoomLayer(uint16 screenId, bool backgroundLayer): - Surface(FULL_SCREEN_WIDTH, FULL_SCREEN_HEIGHT) { - loadScreen(screenId); - byte cellIndex = 0; - byte *screenData = data().data(); - - memset(_cells, 0xff, FULL_HORIZ_RECTS*FULL_VERT_RECTS); - - // Loop through each cell of the screen - for (int cellY = 0; cellY < NUM_VERT_RECTS; ++cellY) { - for (int cellX = 0; cellX < NUM_HORIZ_RECTS; ++cellX) { - bool hasPixels = false; - - if (backgroundLayer) { - hasPixels = true; - } else { - // Check the cell - for (int yP = 0; yP < RECT_SIZE; ++yP) { - if (hasPixels) break; - byte *linePos = screenData + (cellY * RECT_SIZE + yP + 8) - * FULL_SCREEN_WIDTH + (cellX * RECT_SIZE); - - for (int xP = 0; xP < RECT_SIZE; ++xP) { - hasPixels = *linePos++ != 0; - if (hasPixels) break; - } - } - } - - _cells[(cellY + NUM_EDGE_RECTS) * FULL_HORIZ_RECTS + NUM_EDGE_RECTS + - cellX] = !hasPixels ? 0xff : cellIndex++; - } - } -} - -Room::Room(): _screen(Screen::getReference()) { - int_room = this; - - _roomData = NULL; - _hotspotName[0] = '\0'; - for (int ctr = 0; ctr < MAX_NUM_LAYERS; ++ctr) _layers[ctr] = NULL; - _numLayers = 0; - _showInfo = false; - _currentAction = NONE; -} - -Room::~Room() { - for (int layerNum = 0; layerNum < _numLayers; ++layerNum) - if (_layers[layerNum]) - delete _layers[layerNum]; - - int_room = NULL; -} - -Room &Room::getReference() { - return *int_room; -} - -// leaveRoom -// Handles leaving the current room - -void Room::leaveRoom() { - Resources &r = Resources::getReference(); - - // Deallocate graphical layers from the room - for (int layerNum = 0; layerNum < _numLayers; ++layerNum) - if (_layers[layerNum]) { - delete _layers[layerNum]; - _layers[layerNum] = NULL; - } - - // Scan through the hotspot list and remove any uneeded entries -//r.activeHotspots().clear(); - HotspotList &list = r.activeHotspots(); - HotspotList::iterator i = list.begin(); - while (i != list.end()) { - Hotspot *h = i.operator*(); - if (!h->persistant()) { - i = list.erase(i); - } else { - ++i; - } - } -} - -void Room::loadRoomHotspots() { - Resources &r = Resources::getReference(); - HotspotDataList &list = r.hotspotData(); - - HotspotDataList::iterator i; - for (i = list.begin(); i != list.end(); ++i) { - HotspotData *rec = *i; - - if ((rec->hotspotId < 0x7530) && (rec->roomNumber == _roomNumber) && - (rec->layer != 0)) - r.activateHotspot(rec->hotspotId); - } -} - -void Room::checkRoomHotspots() { - Mouse &m = Mouse::getReference(); - Resources &r = Resources::getReference(); - HotspotDataList &list = r.hotspotData(); - HotspotData *entry = NULL; - int16 currentX = m.x(); - int16 currentY = m.y(); - - HotspotDataList::iterator i; - for (i = list.begin(); i != list.end(); ++i) { - entry = *i; - - bool skipFlag = (entry->roomNumber != _roomNumber); - if (!skipFlag) { - skipFlag = (((entry->flags & 0x80) == 0) && - ((entry->flags & 0x40) != 0)) || - ((entry->flags & 0x20) != 0); - } - - if ((!skipFlag) && (entry->hotspotId < 0x409)) - skipFlag = sub_112(); - - if (!skipFlag && (entry->hotspotId >= 0x2710) && (entry->hotspotId <= 0x27ff)) { - RoomExitJoinData *rec = r.getExitJoin(entry->hotspotId); - if ((rec) && (!rec->blocked)) - // Hotspot is over a room exit, and it's not blocked, so don't - // register it as an active hotspot - skipFlag = true; - } - - if (!skipFlag) { - // Check for a hotspot override - HotspotOverrideData *hsEntry = r.getHotspotOverride(entry->hotspotId); - - if (hsEntry) { - // Check whether cursor is in override hotspot area - if ((currentX >= hsEntry->xs) && (currentX <= hsEntry->xe) && - (currentY >= hsEntry->ys) && (currentY <= hsEntry->ye)) - // Found to be in hotspot entry - break; - } else { - // Check whether cursor is in default hospot area - if ((currentX >= entry->startX) && (currentX < entry->startX + entry->width) && - (currentY >= entry->startY) && (currentY < entry->startY + entry->height)) - // Found hotspot entry - break; - } - } - } - - if (i == list.end()) { - _hotspotId = 0; - _hotspotNameId = 0; - _hotspot = NULL; - } else { - _hotspotNameId = entry->nameId; - _hotspot = entry; - _hotspotId = entry->hotspotId; - } -} - -uint8 Room::checkRoomExits() { - Mouse &m = Mouse::getReference(); - Resources &r = Resources::getReference(); - - RoomExitHotspotList &exits = _roomData->exitHotspots; - if (exits.isEmpty()) return CURSOR_ARROW; - RoomExitJoinData *join; - bool skipFlag; - - RoomExitHotspotList::iterator i; - for (i = exits.begin(); i != exits.end(); ++i) { - RoomExitHotspotData *rec = *i; - skipFlag = false; - - if (rec->hotspotId != 0) { - join = r.getExitJoin(rec->hotspotId); - if ((join) && (join->blocked != 0)) - skipFlag = true; - } - - if (!skipFlag && (m.x() >= rec->xs) && (m.x() <= rec->xe) && - (m.y() >= rec->ys) && (m.y() <= rec->ye)) { - // Cursor is within exit area - uint8 cursorNum = rec->cursorNum; - - // If it's a hotspotted exit, change arrow to the + arrow - if (rec->hotspotId != 0) cursorNum += 7; - - return cursorNum; - } - } - - // No room exits found - return CURSOR_ARROW; -} - -void Room::flagCoveredCells(Hotspot &h) { - int16 yStart = (h.y() - MENUBAR_Y_SIZE) / RECT_SIZE; - int16 yEnd = (h.y() + h.height() - 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] |= 0x81; - _cells2[index+xP] |= 1; - } - index += NUM_HORIZ_RECTS; - } -} - -void Room::addAnimation(Hotspot &h) { - Surface &s = _screen.screen(); - char buffer[10]; - h.copyTo(&s); - - if (_showInfo) { - int16 x = h.x(); - int16 y = h.y(); - if ((x >= 0) && (x <= 319) && (y >= 0) && (y <= 200)) { - sprintf(buffer, "%x", h.resource().hotspotId); - strcat(buffer, "h"); - s.writeString(h.x(), h.y(), buffer, false); - } - } -} - -void Room::addLayers(Hotspot &h) { - int16 hsX = h.x() + (4 * RECT_SIZE); - int16 hsY = h.y() + (4 * RECT_SIZE) - MENUBAR_Y_SIZE; - - int16 xStart = hsX / RECT_SIZE; - int16 xEnd = (hsX + h.width()) / RECT_SIZE; - int16 numX = xEnd - xStart + 1; - int16 yStart = hsY / RECT_SIZE; - int16 yEnd = (hsY + h.height() - 1) / RECT_SIZE; - int16 numY = yEnd - yStart + 1; - - for (int16 xCtr = 0; xCtr < numX; ++xCtr, ++xStart) { - int16 xs = xStart - 4; - if (xs < 0) continue; - - // Check foreground layers for an occupied one -/* DEBUG - int layerNum = 1; - while ((layerNum < _numLayers) && - !_layers[layerNum]->isOccupied(xStart, yEnd)) - ++layerNum; - if (layerNum == _numLayers) continue; -*/ - int layerNum = _numLayers - 1; - while ((layerNum > 0) && - !_layers[layerNum]->isOccupied(xStart, yEnd)) - --layerNum; - if (layerNum == 0) continue; - - int16 ye = yEnd - 4; - for (int16 yCtr = 0; yCtr < numY; ++yCtr, --ye) { - if (ye < 0) break; - addCell(xs, ye, layerNum); - } - } -} - -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; -/* DEBUG - while ((layerNum < _numLayers) && !_layers[layerNum]->isOccupied(xp+4, yp+4)) - ++layerNum; - if (layerNum == _numLayers) return; -*/ - RoomLayer *layer = _layers[layerNum]; - - int index = ((yp * RECT_SIZE + 8) * FULL_SCREEN_WIDTH) + (xp * RECT_SIZE); - byte *srcPos = layer->data().data() + index; - byte *destPos = s.data().data() + index; - - for (int yCtr = 0; yCtr < RECT_SIZE; ++yCtr) { - for (int xCtr = 0; xCtr < RECT_SIZE; ++xCtr, ++destPos) { - byte pixel = *srcPos++; - if (pixel) *destPos = pixel; - } - - // Move to start of next cell line - srcPos += FULL_SCREEN_WIDTH - RECT_SIZE; - destPos += FULL_SCREEN_WIDTH - RECT_SIZE; - } - - // Note: old version of screen layers load compresses loaded layers down to - // only a set of the non-empty rects. Since modern memory allows me to load - // all the layers completely, I'm bypassing the need to use cell index values -} - -void Room::update() { - Surface &s = _screen.screen(); - Resources &r = Resources::getReference(); - HotspotList &hotspots = r.activeHotspots(); - HotspotList::iterator i; - - memset(_cells, 0x81, NUM_HORIZ_RECTS*NUM_VERT_RECTS); - memset(_cells2, 0x81, NUM_HORIZ_RECTS*NUM_VERT_RECTS); - - _layers[0]->copyTo(&s); - for (int ctr = 1; ctr < _numLayers; ++ctr) - _layers[ctr]->transparentCopyTo(&s); - - // Handle first layer (layer 3) - for (i = hotspots.begin(); i != hotspots.end(); ++i) { - Hotspot &h = *i.operator*(); - if ((h.roomNumber() == _roomNumber) && h.isActiveAnimation() && (h.layer() == 3)) { - flagCoveredCells(h); - addAnimation(h); - addLayers(h); - } - } - - // Handle second layer (layer 1) - do in order of Y axis - List<Hotspot *> tempList; - List<Hotspot *>::iterator iTemp; - for (i = hotspots.begin(); i != hotspots.end(); ++i) { - Hotspot *h = i.operator*(); - if ((h->roomNumber() != _roomNumber) || !h->isActiveAnimation() - || (h->layer() != 1)) - continue; - int16 endY = h->y() + h->height(); - - for (iTemp = tempList.begin(); iTemp != tempList.end(); ++iTemp) { - Hotspot *hTemp = iTemp.operator*(); - int16 tempY = hTemp->y() + hTemp->height(); - if (endY < tempY) { - if (iTemp != tempList.begin()) --iTemp; - break; - } - } - tempList.insert(iTemp, h); - } - for (iTemp = tempList.begin(); iTemp != tempList.end(); ++iTemp) { - Hotspot &h = *iTemp.operator*(); - flagCoveredCells(h); - addAnimation(h); - addLayers(h); - } - - // Handle third layer (layer 2) - for (i = hotspots.begin(); i != hotspots.end(); ++i) { - Hotspot &h = *i.operator*(); - if ((h.roomNumber() == _roomNumber) && h.isActiveAnimation() && (h.layer() == 2)) { - flagCoveredCells(h); - addAnimation(h); - } - } - - // Handle showing name of highlighted hotspot - if (_hotspotName[0] != '\0') { - if (_currentAction == NONE) { - s.writeString(0, 0, _hotspotName, false, DIALOG_TEXT_COLOUR); - } else { - char buffer[MAX_ACTION_NAME_SIZE + MAX_HOTSPOT_NAME_SIZE]; - strcpy(buffer, actionList[_currentAction]); - strcat(buffer, " "); - strcat(buffer, _hotspotName); - s.writeString(0, 0, buffer, false, DIALOG_WHITE_COLOUR); - } - } - - // If show information is turned on, show room and position - if (_showInfo) { - char buffer[64]; - Mouse &m = Mouse::getReference(); - sprintf(buffer, "Room %d Pos (%d,%d)", _roomNumber, m.x(), m.y()); - s.writeString(FULL_SCREEN_WIDTH / 2, 0, buffer, false, DIALOG_TEXT_COLOUR); - } - - _screen.update(); -} - -void Room::setRoomNumber(uint16 newRoomNumber, bool showOverlay) { - Resources &r = Resources::getReference(); - _roomData = r.getRoom(newRoomNumber); - if (!_roomData) - error("Tried to change to non-existant room: %d", newRoomNumber); - - _roomNumber = _roomData->roomNumber; - _descId = _roomData->descId; - - _screen.empty(); - _screen.resetPalette(); - - if (_layers[0]) leaveRoom(); - - _numLayers = _roomData->numLayers; - if (showOverlay) ++_numLayers; - - uint16 paletteId = (_roomData->layers[0] & 0xffe0) - 1; - - for (uint8 layerNum = 0; layerNum < _numLayers; ++layerNum) - _layers[layerNum] = new RoomLayer(_roomData->layers[layerNum], - layerNum == 0); - - // Load in the palette, add in the two replacements segments, and then - // set to the system palette - Palette p(228, NULL, RGB64); - Palette tempPalette(paletteId); - p.copyFrom(&tempPalette); - r.insertPaletteSubset(p); - _screen.setPalette(&p); - - if (_roomData->sequenceOffset != 0xffff) - Script::execute(_roomData->sequenceOffset); - loadRoomHotspots(); - cursorMoved(); - - update(); -} - -// cursorMoved -// Called as the cursor moves to handle any changes that must occur - -void Room::cursorMoved() { - uint16 cursorNew = CURSOR_ARROW; - uint16 oldHotspotId = _hotspotId; - - Mouse &m = Mouse::getReference(); - checkRoomHotspots(); - - if (_hotspotId != 0) { - cursorNew = CURSOR_CROSS; - - if (oldHotspotId != _hotspotId) - StringData::getReference().getString(_hotspotNameId, _hotspotName, NULL, NULL); - } else { - _hotspotName[0] = '\0'; - cursorNew = checkRoomExits(); - } - - if (m.getCursorNum() != cursorNew) - m.setCursorNum(cursorNew); -} - -} // end of namespace Lure |