diff options
Diffstat (limited to 'engines/queen/grid.cpp')
-rw-r--r-- | engines/queen/grid.cpp | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/engines/queen/grid.cpp b/engines/queen/grid.cpp new file mode 100644 index 0000000000..cb8ed4696b --- /dev/null +++ b/engines/queen/grid.cpp @@ -0,0 +1,255 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003-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 "common/stdafx.h" +#include "queen/grid.h" + +#include "queen/display.h" +#include "queen/logic.h" +#include "queen/queen.h" + +namespace Queen { + +Grid::Grid(QueenEngine *vm) + : _vm(vm) { + memset(_zones, 0, sizeof(_zones)); +} + +Grid::~Grid() { + delete[] _objMax; + delete[] _areaMax; + delete[] _area; + delete[] _objectBox; +} + +void Grid::readDataFrom(uint16 numObjects, uint16 numRooms, byte *&ptr) { + uint16 i, j; + + _numRoomAreas = numRooms; + + _objMax = new int16[_numRoomAreas + 1]; + _areaMax = new int16[_numRoomAreas + 1]; + _area = new Area[_numRoomAreas + 1][MAX_AREAS_NUMBER]; + + _objMax[0] = 0; + _areaMax[0] = 0; + memset(&_area[0], 0, sizeof(Area) * MAX_AREAS_NUMBER); + for (i = 1; i <= _numRoomAreas; i++) { + _objMax[i] = (int16)READ_BE_INT16(ptr); ptr += 2; + _areaMax[i] = (int16)READ_BE_INT16(ptr); ptr += 2; + memset(&_area[i][0], 0, sizeof(Area)); + for (j = 1; j <= _areaMax[i]; j++) { + assert(j < MAX_AREAS_NUMBER); + _area[i][j].readFromBE(ptr); + } + } + + _objectBox = new Box[numObjects + 1]; + memset(&_objectBox[0], 0, sizeof(Box)); + for (i = 1; i <= numObjects; i++) { + _objectBox[i].readFromBE(ptr); + } +} + +void Grid::setZone(GridScreen screen, uint16 zoneNum, uint16 x1, uint16 y1, uint16 x2, uint16 y2) { + debug(9, "Grid::setZone(%d, %d, (%d,%d), (%d,%d))", screen, zoneNum, x1, y1, x2, y2); + ZoneSlot *pzs = &_zones[screen][zoneNum]; + pzs->valid = true; + pzs->box.x1 = x1; + pzs->box.y1 = y1; + pzs->box.x2 = x2; + pzs->box.y2 = y2; +} + +void Grid::setZone(GridScreen screen, uint16 zoneNum, const Box &box) { + debug(9, "Grid::setZone(%d, %d, (%d,%d), (%d,%d))", screen, zoneNum, box.x1, box.y1, box.x2, box.y2); + ZoneSlot *pzs = &_zones[screen][zoneNum]; + pzs->valid = true; + pzs->box = box; +} + +uint16 Grid::findZoneForPos(GridScreen screen, uint16 x, uint16 y) const { + debug(9, "Logic::findZoneForPos(%d, (%d,%d))", screen, x, y); + int i; + if (screen == GS_PANEL) { + y -= ROOM_ZONE_HEIGHT; + } + for (i = 1; i < MAX_ZONES_NUMBER; ++i) { + const ZoneSlot *pzs = &_zones[screen][i]; + if (pzs->valid && pzs->box.contains(x, y)) { + return i; + } + } + return 0; +} + +uint16 Grid::findAreaForPos(GridScreen screen, uint16 x, uint16 y) const { + uint16 room = _vm->logic()->currentRoom(); + uint16 zoneNum = findZoneForPos(screen, x, y); + if (zoneNum <= _objMax[room]) { + zoneNum = 0; + } else { + zoneNum -= _objMax[room]; + } + return zoneNum; +} + +void Grid::clear(GridScreen screen) { + debug(9, "Grid::clear(%d)", screen); + for (int i = 1; i < MAX_ZONES_NUMBER; ++i) { + _zones[screen][i].valid = false; + } +} + +void Grid::setupNewRoom(uint16 room, uint16 firstRoomObjNum) { + debug(9, "Grid::setupNewRoom()"); + clear(GS_ROOM); + + uint16 i; + uint16 zoneNum; + + // setup objects zones + uint16 maxObjRoom = _objMax[room]; + zoneNum = 1; + for (i = firstRoomObjNum + 1; i <= firstRoomObjNum + maxObjRoom; ++i) { + if (_vm->logic()->objectData(i)->name != 0) { + setZone(GS_ROOM, zoneNum, _objectBox[i]); + } + ++zoneNum; + } + + // setup room zones (areas) + uint16 maxAreaRoom = _areaMax[room]; + for (zoneNum = 1; zoneNum <= maxAreaRoom; ++zoneNum) { + setZone(GS_ROOM, maxObjRoom + zoneNum, _area[room][zoneNum].box); + } +} + +void Grid::setupPanel() { + for (int i = 0; i <= 7; ++i) { + uint16 x = i * 20; + setZone(GS_PANEL, i + 1, x, 10, x + 19, 49); + } + + // inventory scrolls + setZone(GS_PANEL, 9, 160, 10, 179, 29); + setZone(GS_PANEL, 10, 160, 30, 179, 49); + + // inventory items + setZone(GS_PANEL, 11, 180, 10, 213, 49); + setZone(GS_PANEL, 12, 214, 10, 249, 49); + setZone(GS_PANEL, 13, 250, 10, 284, 49); + setZone(GS_PANEL, 14, 285, 10, 320, 49); +} + +void Grid::drawZones() { + for (int i = 1; i < MAX_ZONES_NUMBER; ++i) { + const ZoneSlot *pzs = &_zones[GS_ROOM][i]; + if (pzs->valid) { + const Box *b = &pzs->box; + _vm->display()->drawBox(b->x1, b->y1, b->x2, b->y2, 3); + } + } +} + +const Box *Grid::zone(GridScreen screen, uint16 index) const { + const ZoneSlot *zs = &_zones[screen][index]; + assert(zs->valid); + return &zs->box; +} + +Verb Grid::findVerbUnderCursor(int16 cursorx, int16 cursory) const { + static const Verb pv[] = { + VERB_NONE, + VERB_OPEN, + VERB_CLOSE, + VERB_MOVE, + VERB_GIVE, + VERB_LOOK_AT, + VERB_PICK_UP, + VERB_TALK_TO, + VERB_USE, + VERB_SCROLL_UP, + VERB_SCROLL_DOWN, + VERB_INV_1, + VERB_INV_2, + VERB_INV_3, + VERB_INV_4, + }; + return pv[findZoneForPos(GS_PANEL, cursorx, cursory)]; +} + +uint16 Grid::findObjectUnderCursor(int16 cursorx, int16 cursory) const { + uint16 roomObj = 0; + if (cursory < ROOM_ZONE_HEIGHT) { + int16 x = cursorx + _vm->display()->horizontalScroll(); + roomObj = findZoneForPos(GS_ROOM, x, cursory); + } + return roomObj; +} + +uint16 Grid::findObjectNumber(uint16 zoneNum) const { + // l.316-327 select.c + uint16 room = _vm->logic()->currentRoom(); + uint16 obj = zoneNum; + uint16 objectMax = _objMax[room]; + debug(9, "Grid::findObjectNumber(%X, %X)", zoneNum, objectMax); + if (zoneNum > objectMax) { + // this is an area box, check for associated object + obj = _area[room][zoneNum - objectMax].object; + if (obj != 0) { + // there is an object, get its number + obj -= _vm->logic()->currentRoomData(); + } + } + return obj; +} + +uint16 Grid::findScale(uint16 x, uint16 y) const { + uint16 room = _vm->logic()->currentRoom(); + uint16 scale = 100; + uint16 areaNum = findAreaForPos(GS_ROOM, x, y); + if (areaNum != 0) { + scale = _area[room][areaNum].calcScale(y); + } + return scale; +} + +void Grid::saveState(byte *&ptr) { + uint16 i, j; + for (i = 1; i <= _numRoomAreas; ++i) { + for (j = 1; j <= _areaMax[i]; ++j) { + _area[i][j].writeToBE(ptr); + } + } +} + +void Grid::loadState(uint32 ver, byte *&ptr) { + uint16 i, j; + for (i = 1; i <= _numRoomAreas; ++i) { + for (j = 1; j <= _areaMax[i]; ++j) { + _area[i][j].readFromBE(ptr); + } + } +} + +} // End of namespace Queen |