aboutsummaryrefslogtreecommitdiff
path: root/queen/grid.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'queen/grid.cpp')
-rw-r--r--queen/grid.cpp244
1 files changed, 244 insertions, 0 deletions
diff --git a/queen/grid.cpp b/queen/grid.cpp
new file mode 100644
index 0000000000..46d26c553c
--- /dev/null
+++ b/queen/grid.cpp
@@ -0,0 +1,244 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2003-2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#include "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));
+}
+
+
+void Grid::readDataFrom(uint16 numObjects, uint16 numRooms, byte *&ptr) {
+
+ uint16 i, j;
+
+ _objMax = new int16[numRooms + 1];
+ _areaMax = new int16[numRooms + 1];
+ _area = new Area[numRooms + 1][MAX_AREAS];
+
+ _objMax[0] = 0;
+ _areaMax[0] = 0;
+ memset(&_area[0], 0, sizeof(Area) * MAX_AREAS);
+ for (i = 1; i <= numRooms; i++) {
+ _objMax[i] = (int16)READ_BE_UINT16(ptr); ptr += 2;
+ _areaMax[i] = (int16)READ_BE_UINT16(ptr); ptr += 2;
+ memset(&_area[i][0], 0, sizeof(Area));
+ for (j = 1; j <= _areaMax[i]; j++) {
+ assert(j < MAX_AREAS);
+ _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; ++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; ++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; ++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;
+}
+
+
+} // End of namespace Queen