aboutsummaryrefslogtreecommitdiff
path: root/queen
diff options
context:
space:
mode:
Diffstat (limited to 'queen')
-rw-r--r--queen/bankman.cpp146
-rw-r--r--queen/bankman.h72
-rw-r--r--queen/command.cpp19
-rw-r--r--queen/cutaway.cpp17
-rw-r--r--queen/graphics.cpp119
-rw-r--r--queen/graphics.h50
-rw-r--r--queen/grid.cpp244
-rw-r--r--queen/grid.h93
-rw-r--r--queen/journal.cpp26
-rw-r--r--queen/logic.cpp229
-rw-r--r--queen/logic.h46
-rw-r--r--queen/module.mk2
-rw-r--r--queen/queen.cpp4
-rw-r--r--queen/queen.h3
-rw-r--r--queen/structs.h7
-rw-r--r--queen/talk.cpp24
-rw-r--r--queen/walk.cpp40
-rw-r--r--queen/walk.h5
-rw-r--r--queen/xref.txt24
19 files changed, 675 insertions, 495 deletions
diff --git a/queen/bankman.cpp b/queen/bankman.cpp
new file mode 100644
index 0000000000..6e77307498
--- /dev/null
+++ b/queen/bankman.cpp
@@ -0,0 +1,146 @@
+/* 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/bankman.h"
+
+#include "queen/resource.h"
+
+namespace Queen {
+
+
+BankManager::BankManager(Resource *res)
+ : _res(res) {
+ memset(_frames, 0, sizeof(_frames));
+ memset(_banks, 0, sizeof(_banks));
+}
+
+
+BankManager::~BankManager() {
+ for(uint32 i = 0; i < MAX_BANKS_NUMBER; ++i) {
+ close(i);
+ }
+ eraseAllFrames(true);
+}
+
+
+void BankManager::load(const char *bankname, uint32 bankslot) {
+ close(bankslot);
+
+ _banks[bankslot].data = _res->loadFile(bankname);
+ if (!_banks[bankslot].data) {
+ error("Unable to open bank '%s'", bankname);
+ }
+
+ int16 entries = (int16)READ_LE_UINT16(_banks[bankslot].data);
+ if (entries < 0 || entries >= MAX_BANK_SIZE) {
+ error("Maximum bank size exceeded or negative bank size : %d", entries);
+ }
+
+ debug(9, "BankManager::load(%s, %d) - entries = %d", bankname, bankslot, entries);
+
+ uint32 offset = 2;
+ uint8 *p = _banks[bankslot].data;
+ for (int16 i = 1; i <= entries; ++i) {
+ _banks[bankslot].indexes[i] = offset;
+ uint16 w = READ_LE_UINT16(p + offset + 0);
+ uint16 h = READ_LE_UINT16(p + offset + 2);
+ // jump to next entry, skipping data & header
+ offset += w * h + 8;
+ }
+}
+
+
+void BankManager::unpack(uint32 srcframe, uint32 dstframe, uint32 bankslot) {
+ debug(9, "BankManager::unpack(%d, %d, %d)", srcframe, dstframe, bankslot);
+ if (!_banks[bankslot].data)
+ error("BankManager::unpack() _banks[bankslot].data is NULL!");
+
+ BobFrame *pbf = &_frames[dstframe];
+ uint8 *p = _banks[bankslot].data + _banks[bankslot].indexes[srcframe];
+ pbf->width = READ_LE_UINT16(p + 0);
+ pbf->height = READ_LE_UINT16(p + 2);
+ pbf->xhotspot = READ_LE_UINT16(p + 4);
+ pbf->yhotspot = READ_LE_UINT16(p + 6);
+
+ uint32 size = pbf->width * pbf->height;
+ delete[] pbf->data;
+ pbf->data = new uint8[ size ];
+ memcpy(pbf->data, p + 8, size);
+}
+
+
+void BankManager::overpack(uint32 srcframe, uint32 dstframe, uint32 bankslot) {
+ debug(9, "BankManager::overpack(%d, %d, %d)", srcframe, dstframe, bankslot);
+ if (!_banks[bankslot].data)
+ error("BankManager::overpack() _banks[bankslot].data is NULL!");
+
+ uint8 *p = _banks[bankslot].data + _banks[bankslot].indexes[srcframe];
+ uint16 src_w = READ_LE_UINT16(p + 0);
+ uint16 src_h = READ_LE_UINT16(p + 2);
+
+ // unpack if destination frame is smaller than source one
+ if (_frames[dstframe].width < src_w || _frames[dstframe].height < src_h) {
+ unpack(srcframe, dstframe, bankslot);
+ } else {
+ // copy data 'over' destination frame (without changing frame header)
+ memcpy(_frames[dstframe].data, p + 8, src_w * src_h);
+ }
+}
+
+
+void BankManager::close(uint32 bankslot) {
+ debug(9, "BankManager::close(%d)", bankslot);
+ delete[] _banks[bankslot].data;
+ memset(&_banks[bankslot], 0, sizeof(_banks[bankslot]));
+}
+
+
+BobFrame *BankManager::fetchFrame(uint32 index) {
+ debug(9, "BankManager::fetchFrame(%d)", index);
+ if (index >= MAX_FRAMES_NUMBER) {
+ error("BankManager::fetchFrame() invalid frame index = %d", index);
+ }
+ return &_frames[index];
+}
+
+
+void BankManager::eraseFrame(uint32 index) {
+ debug(9, "BankManager::eraseFrame(%d)", index);
+ BobFrame *pbf = &_frames[index];
+ delete[] pbf->data;
+ memset(pbf, 0, sizeof(BobFrame));
+}
+
+
+void BankManager::eraseAllFrames(bool joe) {
+ uint32 i = 0;
+ if (!joe) {
+ i = FRAMES_JOE + FRAMES_JOE_XTRA;
+ }
+ while (i < 256) {
+ eraseFrame(i);
+ ++i;
+ }
+}
+
+
+} // End of namespace Queen
diff --git a/queen/bankman.h b/queen/bankman.h
new file mode 100644
index 0000000000..55c78eb4fa
--- /dev/null
+++ b/queen/bankman.h
@@ -0,0 +1,72 @@
+/* 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$
+ *
+ */
+
+#ifndef QUEENBANKMAN_H
+#define QUEENBANKMAN_H
+
+#include "common/util.h"
+#include "queen/structs.h"
+
+namespace Queen {
+
+class Resource;
+
+class BankManager {
+public:
+
+ BankManager(Resource *res);
+ ~BankManager();
+
+ void load(const char *bankname, uint32 bankslot);
+ void unpack(uint32 srcframe, uint32 dstframe, uint32 bankslot);
+ void overpack(uint32 srcframe, uint32 dstframe, uint32 bankslot);
+ void close(uint32 bankslot);
+
+ BobFrame *fetchFrame(uint32 index);
+ void eraseFrame(uint32 index);
+ void eraseAllFrames(bool joe);
+
+ enum {
+ MAX_BANK_SIZE = 110,
+ MAX_FRAMES_NUMBER = 256,
+ MAX_BANKS_NUMBER = 18
+ };
+
+
+private:
+
+ struct PackedBank {
+ uint32 indexes[MAX_BANK_SIZE];
+ uint8 *data;
+ };
+
+ //! unbanked bob frames
+ BobFrame _frames[MAX_FRAMES_NUMBER];
+
+ //! banked bob frames
+ PackedBank _banks[MAX_BANKS_NUMBER];
+
+ Resource *_res;
+};
+
+} // End of namespace Queen
+
+#endif
diff --git a/queen/command.cpp b/queen/command.cpp
index 33e4459a04..8d2dc663a7 100644
--- a/queen/command.cpp
+++ b/queen/command.cpp
@@ -25,6 +25,7 @@
#include "queen/display.h"
#include "queen/input.h"
#include "queen/graphics.h"
+#include "queen/grid.h"
#include "queen/logic.h"
#include "queen/queen.h"
#include "queen/sound.h"
@@ -506,9 +507,9 @@ void Command::grabCurrentSelection() {
_selPosX = _vm->input()->mousePosX();
_selPosY = _vm->input()->mousePosY();
- uint16 zone = _vm->logic()->findObjectUnderCursor(_selPosX, _selPosY);
- _state.noun = _vm->logic()->findObjectNumber(zone);
- _state.verb = _vm->logic()->findVerbUnderCursor(_selPosX, _selPosY);
+ uint16 zone = _vm->grid()->findObjectUnderCursor(_selPosX, _selPosY);
+ _state.noun = _vm->grid()->findObjectNumber(zone);
+ _state.verb = _vm->grid()->findVerbUnderCursor(_selPosX, _selPosY);
_selPosX += _vm->display()->horizontalScroll();
@@ -772,7 +773,7 @@ bool Command::executeIfDialog(const char *description) {
bool Command::handleWrongAction() {
// l.96-141 execute.c
- uint16 objMax = _vm->logic()->currentRoomObjMax();
+ uint16 objMax = _vm->grid()->objMax(_vm->logic()->currentRoom());
uint16 roomData = _vm->logic()->currentRoomData();
// select without a command or WALK TO ; do a WALK
@@ -1074,7 +1075,7 @@ void Command::setAreas(uint16 command) {
for (i = 1; i <= _numCmdArea; ++i, ++cmdArea) {
if (cmdArea->id == command) {
uint16 areaNum = ABS(cmdArea->area);
- Area *area = _vm->logic()->area(cmdArea->room, areaNum);
+ Area *area = _vm->grid()->area(cmdArea->room, areaNum);
if (cmdArea->area > 0) {
// turn on area
area->mapNeighbours = ABS(area->mapNeighbours);
@@ -1123,7 +1124,7 @@ void Command::setObjects(uint16 command) {
}
// invalidate object area
uint16 objZone = dstObj - _vm->logic()->currentRoomData();
- _vm->logic()->zoneSet(ZONE_ROOM, objZone, 0, 0, 1, 1);
+ _vm->grid()->setZone(GS_ROOM, objZone, 0, 0, 1, 1);
}
}
@@ -1296,8 +1297,8 @@ void Command::lookAtSelectedObject() {
void Command::lookForCurrentObject(int16 cx, int16 cy) {
- uint16 obj = _vm->logic()->findObjectUnderCursor(cx, cy);
- _state.noun = _vm->logic()->findObjectNumber(obj);
+ uint16 obj = _vm->grid()->findObjectUnderCursor(cx, cy);
+ _state.noun = _vm->grid()->findObjectNumber(obj);
if (_state.oldNoun == _state.noun) {
return;
@@ -1351,7 +1352,7 @@ void Command::lookForCurrentObject(int16 cx, int16 cy) {
void Command::lookForCurrentIcon(int16 cx, int16 cy) {
- _state.verb = _vm->logic()->findVerbUnderCursor(cx, cy);
+ _state.verb = _vm->grid()->findVerbUnderCursor(cx, cy);
if (_state.oldVerb != _state.verb) {
if (_state.action == VERB_NONE) {
diff --git a/queen/cutaway.cpp b/queen/cutaway.cpp
index 939baa2130..661380441e 100644
--- a/queen/cutaway.cpp
+++ b/queen/cutaway.cpp
@@ -22,9 +22,10 @@
#include "stdafx.h"
#include "queen/cutaway.h"
-#include "queen/credits.h"
+#include "queen/bankman.h"
#include "queen/display.h"
#include "queen/graphics.h"
+#include "queen/grid.h"
#include "queen/input.h"
#include "queen/logic.h"
#include "queen/queen.h"
@@ -337,7 +338,7 @@ void Cutaway::changeRooms(CutawayObject &object) {
if (_finalRoom != object.room) {
int firstObjectInRoom = _vm->logic()->roomData(object.room) + 1;
- int lastObjectInRoom = _vm->logic()->roomData(object.room) + _vm->logic()->objMax(object.room);
+ int lastObjectInRoom = _vm->logic()->roomData(object.room) + _vm->grid()->objMax(object.room);
for (int i = firstObjectInRoom; i <= lastObjectInRoom; i++) {
ObjectData *objectData = _vm->logic()->objectData(i);
@@ -1137,7 +1138,7 @@ void Cutaway::stop() {
pbs->x = x;
pbs->y = y;
if (inRange(object->image, -4, -3))
- pbs->scale = _vm->logic()->findScale(x, y);
+ pbs->scale = _vm->grid()->findScale(x, y);
}
if (frame) {
@@ -1185,7 +1186,7 @@ void Cutaway::stop() {
joeBob->x = joeX;
joeBob->y = joeY;
- _vm->logic()->joeScale(_vm->logic()->findScale(joeX, joeY));
+ _vm->logic()->joeScale(_vm->grid()->findScale(joeX, joeY));
_vm->logic()->joeFace();
}
}
@@ -1238,11 +1239,11 @@ void Cutaway::updateGameState() {
// Turn area on or off
if (areaSubIndex > 0) {
- Area *area = _vm->logic()->area(areaIndex, areaSubIndex);
+ Area *area = _vm->grid()->area(areaIndex, areaSubIndex);
area->mapNeighbours = ABS(area->mapNeighbours);
}
else {
- Area *area = _vm->logic()->area(areaIndex, ABS(areaSubIndex));
+ Area *area = _vm->grid()->area(areaIndex, ABS(areaSubIndex));
area->mapNeighbours = -ABS(area->mapNeighbours);
}
}
@@ -1416,9 +1417,9 @@ int Cutaway::scale(CutawayObject &object) {
y = bob->y;
}
- int zone = _vm->logic()->zoneInArea(0, x, y);
+ int zone = _vm->grid()->findAreaForPos(GS_ROOM, x, y);
if (zone > 0) {
- Area *area = _vm->logic()->area(_vm->logic()->currentRoom(), zone);
+ Area *area = _vm->grid()->area(_vm->logic()->currentRoom(), zone);
scaling = area->calcScale(y);
}
}
diff --git a/queen/graphics.cpp b/queen/graphics.cpp
index 10b5c0dee2..3d4f8c45bb 100644
--- a/queen/graphics.cpp
+++ b/queen/graphics.cpp
@@ -22,6 +22,7 @@
#include "stdafx.h"
#include "queen/graphics.h"
+#include "queen/bankman.h"
#include "queen/display.h"
#include "queen/logic.h"
#include "queen/queen.h"
@@ -180,124 +181,6 @@ void BobSlot::clear() {
}
-
-BankManager::BankManager(Resource *res)
- : _res(res) {
- memset(_frames, 0, sizeof(_frames));
- memset(_banks, 0, sizeof(_banks));
-}
-
-
-BankManager::~BankManager() {
- for(uint32 i = 0; i < MAX_BANKS_NUMBER; ++i) {
- close(i);
- }
- eraseAllFrames(true);
-}
-
-
-void BankManager::load(const char *bankname, uint32 bankslot) {
- close(bankslot);
-
- _banks[bankslot].data = _res->loadFile(bankname);
- if (!_banks[bankslot].data) {
- error("Unable to open bank '%s'", bankname);
- }
-
- int16 entries = (int16)READ_LE_UINT16(_banks[bankslot].data);
- if (entries < 0 || entries >= MAX_BANK_SIZE) {
- error("Maximum bank size exceeded or negative bank size : %d", entries);
- }
-
- debug(9, "BankManager::load(%s, %d) - entries = %d", bankname, bankslot, entries);
-
- uint32 offset = 2;
- uint8 *p = _banks[bankslot].data;
- for (int16 i = 1; i <= entries; ++i) {
- _banks[bankslot].indexes[i] = offset;
- uint16 w = READ_LE_UINT16(p + offset + 0);
- uint16 h = READ_LE_UINT16(p + offset + 2);
- // jump to next entry, skipping data & header
- offset += w * h + 8;
- }
-}
-
-
-void BankManager::unpack(uint32 srcframe, uint32 dstframe, uint32 bankslot) {
- debug(9, "BankManager::unpack(%d, %d, %d)", srcframe, dstframe, bankslot);
- if (!_banks[bankslot].data)
- error("BankManager::unpack() _banks[bankslot].data is NULL!");
-
- BobFrame *pbf = &_frames[dstframe];
- uint8 *p = _banks[bankslot].data + _banks[bankslot].indexes[srcframe];
- pbf->width = READ_LE_UINT16(p + 0);
- pbf->height = READ_LE_UINT16(p + 2);
- pbf->xhotspot = READ_LE_UINT16(p + 4);
- pbf->yhotspot = READ_LE_UINT16(p + 6);
-
- uint32 size = pbf->width * pbf->height;
- delete[] pbf->data;
- pbf->data = new uint8[ size ];
- memcpy(pbf->data, p + 8, size);
-}
-
-
-void BankManager::overpack(uint32 srcframe, uint32 dstframe, uint32 bankslot) {
- debug(9, "BankManager::overpack(%d, %d, %d)", srcframe, dstframe, bankslot);
- if (!_banks[bankslot].data)
- error("BankManager::overpack() _banks[bankslot].data is NULL!");
-
- uint8 *p = _banks[bankslot].data + _banks[bankslot].indexes[srcframe];
- uint16 src_w = READ_LE_UINT16(p + 0);
- uint16 src_h = READ_LE_UINT16(p + 2);
-
- // unpack if destination frame is smaller than source one
- if (_frames[dstframe].width < src_w || _frames[dstframe].height < src_h) {
- unpack(srcframe, dstframe, bankslot);
- } else {
- // copy data 'over' destination frame (without changing frame header)
- memcpy(_frames[dstframe].data, p + 8, src_w * src_h);
- }
-}
-
-
-void BankManager::close(uint32 bankslot) {
- debug(9, "BankManager::close(%d)", bankslot);
- delete[] _banks[bankslot].data;
- memset(&_banks[bankslot], 0, sizeof(_banks[bankslot]));
-}
-
-
-BobFrame *BankManager::fetchFrame(uint32 index) {
- debug(9, "BankManager::fetchFrame(%d)", index);
- if (index >= MAX_FRAMES_NUMBER) {
- error("BankManager::fetchFrame() invalid frame index = %d", index);
- }
- return &_frames[index];
-}
-
-
-void BankManager::eraseFrame(uint32 index) {
- debug(9, "BankManager::eraseFrame(%d)", index);
- BobFrame *pbf = &_frames[index];
- delete[] pbf->data;
- memset(pbf, 0, sizeof(BobFrame));
-}
-
-
-void BankManager::eraseAllFrames(bool joe) {
- uint32 i = 0;
- if (!joe) {
- i = FRAMES_JOE + FRAMES_JOE_XTRA;
- }
- while (i < 256) {
- eraseFrame(i);
- ++i;
- }
-}
-
-
-
Graphics::Graphics(QueenEngine *vm)
: _cameraBob(0), _vm(vm) {
memset(_bobs, 0, sizeof(_bobs));
diff --git a/queen/graphics.h b/queen/graphics.h
index c374bd7cfc..b0c8369119 100644
--- a/queen/graphics.h
+++ b/queen/graphics.h
@@ -29,14 +29,6 @@
namespace Queen {
-
-struct BobFrame {
- uint16 width, height;
- uint16 xhotspot, yhotspot;
- uint8 *data;
-};
-
-
struct BobSlot {
bool active;
//! current position
@@ -93,7 +85,6 @@ struct BobSlot {
void clear();
};
-
struct TextSlot {
uint16 x;
uint8 color;
@@ -101,47 +92,6 @@ struct TextSlot {
bool outlined;
};
-class Resource;
-
-class BankManager {
-public:
-
- BankManager(Resource *res);
- ~BankManager();
-
- void load(const char *bankname, uint32 bankslot);
- void unpack(uint32 srcframe, uint32 dstframe, uint32 bankslot);
- void overpack(uint32 srcframe, uint32 dstframe, uint32 bankslot);
- void close(uint32 bankslot);
-
- BobFrame *fetchFrame(uint32 index);
- void eraseFrame(uint32 index);
- void eraseAllFrames(bool joe);
-
- enum {
- MAX_BANK_SIZE = 110,
- MAX_FRAMES_NUMBER = 256,
- MAX_BANKS_NUMBER = 18
- };
-
-
-private:
-
- struct PackedBank {
- uint32 indexes[MAX_BANK_SIZE];
- uint8 *data;
- };
-
- //! unbanked bob frames
- BobFrame _frames[MAX_FRAMES_NUMBER];
-
- //! banked bob frames
- PackedBank _banks[MAX_BANKS_NUMBER];
-
- Resource *_res;
-};
-
-
class QueenEngine;
class Graphics {
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
diff --git a/queen/grid.h b/queen/grid.h
new file mode 100644
index 0000000000..b81e5b5148
--- /dev/null
+++ b/queen/grid.h
@@ -0,0 +1,93 @@
+/* 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$
+ *
+ */
+
+#ifndef QUEENGRID_H
+#define QUEENGRID_H
+
+#include "common/util.h"
+#include "queen/structs.h"
+
+namespace Queen {
+
+enum GridScreen {
+ GS_ROOM = 0,
+ GS_PANEL = 1,
+ GS_COUNT = 2
+};
+
+class QueenEngine;
+
+class Grid {
+public:
+
+ Grid(QueenEngine *vm);
+
+ void readDataFrom(uint16 numObjects, uint16 numRooms, byte *&ptr);
+
+ void setZone(GridScreen screen, uint16 zoneNum, uint16 x1, uint16 y1, uint16 x2, uint16 y2);
+ void setZone(GridScreen screen, uint16 zoneNum, const Box &box);
+ uint16 findZoneForPos(GridScreen screen, uint16 x, uint16 y) const;
+ uint16 findAreaForPos(GridScreen screen, uint16 x, uint16 y) const;
+ void clear(GridScreen screen);
+ void setupNewRoom(uint16 room, uint16 firstRoomObjNum);
+ void setupPanel();
+ void drawZones();
+ const Box *zone(GridScreen screen, uint16 index) const;
+
+ Verb findVerbUnderCursor(int16 cursorx, int16 cursory) const;
+ uint16 findObjectUnderCursor(int16 cursorx, int16 cursory) const;
+ uint16 findObjectNumber(uint16 zoneNum) const;
+ uint16 findScale(uint16 x, uint16 y) const;
+
+ Area *area(int room, int num) const { return &_area[room][num]; }
+ uint16 areaMax(int room) const { return _areaMax[room]; }
+ uint16 objMax(int room) const { return _objMax[room]; }
+
+ enum {
+ MAX_ZONES = 32,
+ MAX_AREAS = 11
+ };
+
+
+private:
+
+ struct ZoneSlot {
+ bool valid;
+ Box box;
+ };
+
+ ZoneSlot _zones[GS_COUNT][MAX_ZONES];
+
+ int16 *_objMax;
+
+ int16 *_areaMax;
+
+ Area (*_area)[MAX_AREAS];
+
+ Box *_objectBox;
+
+ QueenEngine *_vm;
+};
+
+
+} // End of namespace Queen
+
+#endif
diff --git a/queen/journal.cpp b/queen/journal.cpp
index 74c7f30558..0537645e21 100644
--- a/queen/journal.cpp
+++ b/queen/journal.cpp
@@ -22,8 +22,10 @@
#include "stdafx.h"
#include "queen/journal.h"
+#include "queen/bankman.h"
#include "queen/display.h"
#include "queen/graphics.h"
+#include "queen/grid.h"
#include "queen/logic.h"
#include "queen/queen.h"
#include "queen/resource.h"
@@ -106,21 +108,21 @@ void Journal::prepare() {
_vm->graphics()->textCurrentColor(INK_JOURNAL);
int i;
- _vm->logic()->zoneClearAll(ZONE_ROOM);
+ _vm->grid()->clear(GS_ROOM);
for (i = 0; i < 4; ++i) { // left panel
- _vm->logic()->zoneSet(ZONE_ROOM, i + 1, 32, 8 + i * 48, 96, 40 + i * 48);
+ _vm->grid()->setZone(GS_ROOM, i + 1, 32, 8 + i * 48, 96, 40 + i * 48);
}
- _vm->logic()->zoneSet(ZONE_ROOM, ZN_TEXT_SPEED, 136, 169, 265, 176);
- _vm->logic()->zoneSet(ZONE_ROOM, ZN_SFX_TOGGLE, 221 - 24, 155, 231, 164);
- _vm->logic()->zoneSet(ZONE_ROOM, ZN_MUSIC_VOLUME, 136, 182, 265, 189);
+ _vm->grid()->setZone(GS_ROOM, ZN_TEXT_SPEED, 136, 169, 265, 176);
+ _vm->grid()->setZone(GS_ROOM, ZN_SFX_TOGGLE, 221 - 24, 155, 231, 164);
+ _vm->grid()->setZone(GS_ROOM, ZN_MUSIC_VOLUME, 136, 182, 265, 189);
for (i = 0; i < 10; ++i) { // right panel
- _vm->logic()->zoneSet(ZONE_ROOM, ZN_DESC_FIRST + i, 131, 7 + i * 13, 290, 18 + i * 13);
- _vm->logic()->zoneSet(ZONE_ROOM, ZN_PAGE_FIRST + i, 300, 4 + i * 15, 319, 17 + i * 15);
+ _vm->grid()->setZone(GS_ROOM, ZN_DESC_FIRST + i, 131, 7 + i * 13, 290, 18 + i * 13);
+ _vm->grid()->setZone(GS_ROOM, ZN_PAGE_FIRST + i, 300, 4 + i * 15, 319, 17 + i * 15);
}
- _vm->logic()->zoneSet(ZONE_ROOM, ZN_INFO_BOX, 273, 146, 295, 189);
- _vm->logic()->zoneSet(ZONE_ROOM, ZN_MUSIC_TOGGLE, 125 - 16, 181, 135, 190);
- _vm->logic()->zoneSet(ZONE_ROOM, ZN_VOICE_TOGGLE, 158 - 24, 155, 168, 164);
- _vm->logic()->zoneSet(ZONE_ROOM, ZN_TEXT_TOGGLE, 125 - 16, 168, 135, 177);
+ _vm->grid()->setZone(GS_ROOM, ZN_INFO_BOX, 273, 146, 295, 189);
+ _vm->grid()->setZone(GS_ROOM, ZN_MUSIC_TOGGLE, 125 - 16, 181, 135, 190);
+ _vm->grid()->setZone(GS_ROOM, ZN_VOICE_TOGGLE, 158 - 24, 155, 168, 164);
+ _vm->grid()->setZone(GS_ROOM, ZN_TEXT_TOGGLE, 125 - 16, 168, 135, 177);
_vm->display()->setupNewRoom("journal", JOURNAL_ROOM);
_vm->bankMan()->load("journal.BBK", JOURNAL_BANK);
@@ -348,7 +350,7 @@ void Journal::handleMouseWheel(int inc) {
void Journal::handleMouseDown(int x, int y) {
- int16 zone = _vm->logic()->zoneIn(ZONE_ROOM, x, y);
+ int16 zone = _vm->grid()->findZoneForPos(GS_ROOM, x, y);
if (_mode == M_INFO_BOX) {
handleInfoBoxMode(_mode);
} else if (_mode == M_YES_NO) {
diff --git a/queen/logic.cpp b/queen/logic.cpp
index c93c033b9c..32f080d55b 100644
--- a/queen/logic.cpp
+++ b/queen/logic.cpp
@@ -23,6 +23,7 @@
#include "queen/logic.h"
#include "common/config-manager.h"
+#include "queen/bankman.h"
#include "queen/command.h"
#include "queen/credits.h"
#include "queen/cutaway.h"
@@ -30,6 +31,7 @@
#include "queen/defs.h"
#include "queen/display.h"
#include "queen/graphics.h"
+#include "queen/grid.h"
#include "queen/input.h"
#include "queen/journal.h"
#include "queen/queen.h"
@@ -60,7 +62,7 @@ Logic::~Logic() {
}
void Logic::initialise() {
- int16 i, j;
+ int16 i;
// Step 1 : read queen.jas file and 'unserialize' some arrays
@@ -117,28 +119,7 @@ void Logic::initialise() {
_graphicData[i].readFromBE(ptr);
}
- _objMax = new int16[_numRooms + 1];
- _areaMax = new int16[_numRooms + 1];
- _area = new Area[_numRooms + 1][MAX_AREAS_NUMBER];
-
- _objMax[0] = 0;
- _areaMax[0] = 0;
- memset(&_area[0], 0, sizeof(Area) * MAX_AREAS_NUMBER);
- 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_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);
- }
+ _vm->grid()->readDataFrom(_numObjects, _numRooms, ptr);
// Walk OFF Data
_numWalkOffs = READ_BE_UINT16(ptr); ptr += 2;
@@ -263,7 +244,7 @@ void Logic::initialise() {
_vm->display()->setupPanel();
_vm->graphics()->bobSetupControl();
setupJoe();
- zoneSetupPanel();
+ _vm->grid()->setupPanel();
_oldRoom = 0;
}
@@ -277,14 +258,6 @@ ObjectData* Logic::objectData(int index) const {
}
-Area *Logic::currentRoomArea(int num) const {
- if (num == 0 || num > _areaMax[_currentRoom]) {
- error("Logic::currentRoomArea() - Bad area number = %d (max = %d), currentRoom = %d", num, _areaMax[_currentRoom], _currentRoom);
- }
- return &_area[_currentRoom][num];
-}
-
-
uint16 Logic::findBob(uint16 obj) {
uint16 i;
uint16 bobnum = 0;
@@ -495,107 +468,6 @@ void Logic::gameState(int index, int16 newValue) {
}
-void Logic::zoneSet(uint16 screen, uint16 zone, uint16 x1, uint16 y1, uint16 x2, uint16 y2) {
- debug(9, "Logic::zoneSet(%d, %d, (%d,%d), (%d,%d))", screen, zone, x1, y1, x2, y2);
- ZoneSlot *pzs = &_zones[screen][zone];
- pzs->valid = true;
- pzs->box.x1 = x1;
- pzs->box.y1 = y1;
- pzs->box.x2 = x2;
- pzs->box.y2 = y2;
-}
-
-
-void Logic::zoneSet(uint16 screen, uint16 zone, const Box& box) {
- debug(9, "Logic::zoneSet(%d, %d, (%d,%d), (%d,%d))", screen, zone, box.x1, box.y1, box.x2, box.y2);
- ZoneSlot *pzs = &_zones[screen][zone];
- pzs->valid = true;
- pzs->box = box;
-}
-
-
-uint16 Logic::zoneIn(uint16 screen, uint16 x, uint16 y) const {
- debug(9, "Logic::zoneIn(%d, (%d,%d))", screen, x, y);
- int i;
- if (screen == ZONE_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 Logic::zoneInArea(uint16 screen, uint16 x, uint16 y) const {
- uint16 zone = zoneIn(screen, x, y);
- if (zone <= currentRoomObjMax()) {
- zone = 0;
- } else {
- zone -= currentRoomObjMax();
- }
- return zone;
-}
-
-
-void Logic::zoneClearAll(uint16 screen) {
- debug(9, "Logic::zoneClearAll(%d)", screen);
- int i;
- for(i = 1; i < MAX_ZONES_NUMBER; ++i) {
- _zones[screen][i].valid = false;
- }
-}
-
-
-void Logic::zoneSetup() {
- debug(9, "Logic::zoneSetup()");
- zoneClearAll(ZONE_ROOM);
-
- int i;
- int zoneNum;
-
- // setup objects zones
- uint16 maxObjRoom = currentRoomObjMax();
- uint16 objRoomNum = currentRoomData();
- zoneNum = 1;
- for (i = objRoomNum + 1; i <= objRoomNum + maxObjRoom; ++i) {
- if (_objectData[i].name != 0) {
- zoneSet(ZONE_ROOM, zoneNum, _objectBox[i]);
- }
- ++zoneNum;
- }
-
- // setup room zones (areas)
- uint16 maxAreaRoom = currentRoomAreaMax();
- for (zoneNum = 1; zoneNum <= maxAreaRoom; ++zoneNum) {
- zoneSet(ZONE_ROOM, maxObjRoom + zoneNum, currentRoomArea(zoneNum)->box);
- }
-}
-
-
-void Logic::zoneSetupPanel() {
- // verbs
- int i;
- for (i = 0; i <= 7; ++i) {
- int x = i * 20;
- zoneSet(ZONE_PANEL, i + 1, x, 10, x + 19, 49);
- }
-
- // inventory scrolls
- zoneSet(ZONE_PANEL, 9, 160, 10, 179, 29);
- zoneSet(ZONE_PANEL, 10, 160, 30, 179, 49);
-
- // inventory items
- zoneSet(ZONE_PANEL, 11, 180, 10, 213, 49);
- zoneSet(ZONE_PANEL, 12, 214, 10, 249, 49);
- zoneSet(ZONE_PANEL, 13, 250, 10, 284, 49);
- zoneSet(ZONE_PANEL, 14, 285, 10, 320, 49);
-}
-
-
void Logic::roomErase() {
_vm->bankMan()->eraseAllFrames(false);
_vm->bankMan()->close(15);
@@ -949,7 +821,7 @@ void Logic::roomSetup(const char *room, int comPanel, bool inCutaway) {
sprintf(filename, "%s.BBK", room);
_vm->bankMan()->load(filename, 15);
- zoneSetup();
+ _vm->grid()->setupNewRoom(_currentRoom, _roomData[_currentRoom]);
_numFrames = 37 + FRAMES_JOE_XTRA;
roomSetupFurniture();
roomSetupObjects();
@@ -990,16 +862,6 @@ void Logic::roomDisplay(uint16 room, RoomDisplayMode mode, uint16 scale, int com
}
-uint16 Logic::findScale(uint16 x, uint16 y) {
- uint16 scale = 100;
- uint16 areaNum = zoneInArea(ZONE_ROOM, x, y);
- if(areaNum != 0) {
- scale = currentRoomArea(areaNum)->calcScale(y);
- }
- return scale;
-}
-
-
ActorData *Logic::findActor(uint16 noun, const char *name) {
uint16 obj = currentRoomData() + noun;
int16 img = _objectData[obj].image;
@@ -1067,10 +929,10 @@ uint16 Logic::setupPersonInRoom(uint16 noun, uint16 curImage) {
const ActorData *pad = p.actor;
uint16 scale = 100;
- uint16 a = zoneInArea(ZONE_ROOM, pad->x, pad->y);
+ uint16 a = _vm->grid()->findAreaForPos(GS_ROOM, pad->x, pad->y);
if (a > 0) {
// person is not standing in the area box, scale it accordingly
- scale = currentRoomArea(a)->calcScale(pad->y);
+ scale = _vm->grid()->area(_currentRoom, a)->calcScale(pad->y);
}
_vm->bankMan()->unpack(pad->bobFrameStanding, p.bobFrame, p.actor->bankNum);
@@ -1158,9 +1020,9 @@ ObjectData *Logic::setupJoeInRoom(bool autoPosition, uint16 scale) {
if (scale > 0 && scale < 100) {
joeScale(scale);
} else {
- uint16 a = zoneInArea(ZONE_ROOM, oldx, oldy);
+ uint16 a = _vm->grid()->findAreaForPos(GS_ROOM, oldx, oldy);
if (a > 0) {
- joeScale(currentRoomArea(a)->calcScale(oldy));
+ joeScale(_vm->grid()->area(_currentRoom, a)->calcScale(oldy));
} else {
joeScale(100);
}
@@ -1402,55 +1264,6 @@ void Logic::makeJoeSpeak(uint16 descNum, bool objectType) {
}
-Verb Logic::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[zoneIn(ZONE_PANEL, cursorx, cursory)];
-}
-
-
-uint16 Logic::findObjectUnderCursor(int16 cursorx, int16 cursory) const {
- uint16 roomObj = 0;
- if (cursory < ROOM_ZONE_HEIGHT) {
- int16 x = cursorx + _vm->display()->horizontalScroll();
- roomObj = zoneIn(ZONE_ROOM, x, cursory);
- }
- return roomObj;
-}
-
-
-uint16 Logic::findObjectNumber(uint16 zoneNum) const {
- // l.316-327 select.c
- uint16 obj = zoneNum;
- uint16 objectMax = currentRoomObjMax();
- debug(9, "Logic::findObjectNumber(%X, %X)", zoneNum, objectMax);
- if (zoneNum > objectMax) {
- // this is an area box, check for associated object
- obj = currentRoomArea(zoneNum - objectMax)->object;
- if (obj != 0) {
- // there is an object, get its number
- obj -= currentRoomData();
- }
- }
- return obj;
-}
-
-
uint16 Logic::findInventoryItem(int invSlot) const {
// queen.c l.3894-3898
if (invSlot >= 0 && invSlot < 4) {
@@ -1814,7 +1627,7 @@ void Logic::handlePinnacleRoom() {
_vm->graphics()->textClear(5, 5);
- uint16 curObj = findObjectUnderCursor(mx, my);
+ uint16 curObj = _vm->grid()->findObjectUnderCursor(mx, my);
if (curObj != 0 && curObj != prevObj) {
_entryObj = 0;
curObj += currentRoomData(); // global object number
@@ -1876,13 +1689,7 @@ void Logic::update() {
_credits->update();
if (_vm->debugger()->_drawAreas) {
- for(int i = 1; i < MAX_ZONES_NUMBER; ++i) {
- const ZoneSlot *pzs = &_zones[ZONE_ROOM][i];
- if (pzs->valid) {
- const Box *b = &pzs->box;
- _vm->display()->drawBox(b->x1, b->y1, b->x2, b->y2, 3);
- }
- }
+ _vm->grid()->drawZones();
}
}
@@ -1929,8 +1736,8 @@ bool Logic::gameSave(uint16 slot, const char *desc) {
}
for (i = 1; i <= _numRooms; i++)
- for (j = 1; j <= _areaMax[i]; j++)
- _area[i][j].writeToBE(ptr);
+ for (j = 1; j <= _vm->grid()->areaMax(i); j++)
+ _vm->grid()->area(i, j)->writeToBE(ptr);
for (i = 0; i < TALK_SELECTED_COUNT; i++)
_talkSelected[i].writeToBE(ptr);
@@ -2000,8 +1807,8 @@ bool Logic::gameLoad(uint16 slot) {
}
for (i = 1; i <= _numRooms; i++)
- for (j = 1; j <= _areaMax[i]; j++)
- _area[i][j].readFromBE(ptr);
+ for (j = 1; j <= _vm->grid()->areaMax(i); j++)
+ _vm->grid()->area(i, j)->readFromBE(ptr);
for (i = 0; i < TALK_SELECTED_COUNT; i++)
_talkSelected[i].readFromBE(ptr);
@@ -2076,7 +1883,7 @@ void Logic::sceneStop() {
_vm->display()->palSetAllDirty();
_vm->display()->showMouseCursor(true);
- zoneSetupPanel();
+ _vm->grid()->setupPanel();
}
@@ -2308,7 +2115,7 @@ void Logic::asmSetLightsOn() {
void Logic::asmSetManequinAreaOn() {
- Area *a = area(ROOM_FLODA_FRONTDESK, 7);
+ Area *a = _vm->grid()->area(ROOM_FLODA_FRONTDESK, 7);
a->mapNeighbours = ABS(a->mapNeighbours);
}
diff --git a/queen/logic.h b/queen/logic.h
index 55344f5a34..14f3cfc869 100644
--- a/queen/logic.h
+++ b/queen/logic.h
@@ -36,11 +36,6 @@ enum RoomDisplayMode {
RDM_FADE_JOE_XY = 3 // display Joe at the current X, Y coords
};
-enum {
- ZONE_ROOM = 0,
- ZONE_PANEL = 1
-};
-
enum JoeWalkMode {
JWM_NORMAL = 0,
JWM_MOVE = 1,
@@ -48,12 +43,6 @@ enum JoeWalkMode {
JWM_SPEAK = 3
};
-struct ZoneSlot {
- bool valid;
- Box box;
-};
-
-
class Credits;
class Journal;
class QueenEngine;
@@ -90,7 +79,6 @@ public:
ObjectData *objectData(int index) const;
uint16 roomData(int room) const { return _roomData[room]; }
- uint16 objMax(int room) const { return _objMax[room]; }
GraphicData *graphicData(int index) const { return &_graphicData[index]; }
ItemData *itemData(int index) const { return &_itemData[index]; }
uint16 itemDataCount() const { return _numItems; }
@@ -100,13 +88,8 @@ public:
uint16 objectForPerson(uint16 bobnum) const;
WalkOffData *walkOffPointForObject(uint16 obj) const;
- Area *area(int room, int num) const { return &_area[room][num]; }
- Area *currentRoomArea(int num) const;
- uint16 areaMax(int room) const { return _areaMax[room]; }
- uint16 currentRoomAreaMax() const { return _areaMax[_currentRoom]; }
uint16 walkOffCount() const { return _numWalkOffs; }
WalkOffData *walkOffData(int index) const { return &_walkOffData[index]; }
- uint16 currentRoomObjMax() const { return _objMax[_currentRoom]; }
uint16 currentRoomData() const { return _roomData[_currentRoom]; }
GraphicAnim *graphicAnim(int index) const { return &_graphicAnim[index]; }
uint16 graphicAnimCount() const { return _numGraphicAnim; }
@@ -147,15 +130,6 @@ public:
const char *objectName(uint16 objNum) const { return _objName[objNum]; }
const char *objectTextualDescription(uint16 objNum) const { return _objDescription[objNum]; }
- void zoneSet(uint16 screen, uint16 zone, uint16 x1, uint16 y1, uint16 x2, uint16 y2);
- void zoneSet(uint16 screen, uint16 zone, const Box& box);
- uint16 zoneIn(uint16 screen, uint16 x, uint16 y) const;
- uint16 zoneInArea(uint16 screen, uint16 x, uint16 y) const;
- void zoneClearAll(uint16 screen);
- void zoneSetup();
- void zoneSetupPanel();
- Box &zoneBox(uint16 screen, uint16 index) { return _zones[screen][index].box; }
-
void roomErase();
void roomSetupFurniture();
void roomSetupObjects();
@@ -163,8 +137,6 @@ public:
void roomSetup(const char *room, int comPanel, bool inCutaway);
void roomDisplay(uint16 room, RoomDisplayMode mode, uint16 joeScale, int comPanel, bool inCutaway);
- uint16 findScale(uint16 x, uint16 y);
-
int16 entryObj() const { return _entryObj; }
void entryObj(int16 obj) { _entryObj = obj; }
@@ -196,10 +168,6 @@ public:
void startDialogue(const char *dlgFile, int personInRoom, char *cutaway);
void playCutaway(const char *cutFile, char *next = NULL);
- Verb findVerbUnderCursor(int16 cursorx, int16 cursory) const;
- uint16 findObjectUnderCursor(int16 cursorx, int16 cursory) const;
- uint16 findObjectNumber(uint16 zoneNum) const;
-
void inventorySetup();
uint16 findInventoryItem(int invSlot) const;
void inventoryRefresh();
@@ -284,8 +252,6 @@ public:
void stopCredits();
enum {
- MAX_ZONES_NUMBER = 32,
- MAX_AREAS_NUMBER = 11,
JOE_RESPONSE_MAX = 40,
DEFAULT_TALK_SPEED = 7 * 3,
GAME_STATE_COUNT = 211,
@@ -315,9 +281,6 @@ protected:
//! Background music to play in room
uint16 *_sfxName;
- //! Number of objects in room
- int16 *_objMax;
-
//! Bounding box of object
Box *_objectBox;
@@ -337,12 +300,6 @@ protected:
ActorData *_actorData;
uint16 _numActors;
- //! Areas in room
- Area (*_area)[MAX_AREAS_NUMBER];
-
- //! Number of areas in room
- int16 *_areaMax;
-
//! Walk off point for an object
WalkOffData *_walkOffData;
uint16 _numWalkOffs;
@@ -353,9 +310,6 @@ protected:
GraphicAnim *_graphicAnim;
uint16 _numGraphicAnim;
- //! Current areas in room
- ZoneSlot _zones[2][MAX_ZONES_NUMBER];
-
//! Actor position in room is _walkOffData[_entryObj]
int16 _entryObj;
diff --git a/queen/module.mk b/queen/module.mk
index ba2eba5e75..eaa678e5bf 100644
--- a/queen/module.mk
+++ b/queen/module.mk
@@ -1,12 +1,14 @@
MODULE := queen
MODULE_OBJS = \
+ queen/bankman.o \
queen/command.o \
queen/credits.o \
queen/cutaway.o \
queen/debug.o \
queen/display.o \
queen/graphics.o \
+ queen/grid.o \
queen/input.o \
queen/journal.o \
queen/logic.o \
diff --git a/queen/queen.cpp b/queen/queen.cpp
index f9bf8fc407..5d98730ae3 100644
--- a/queen/queen.cpp
+++ b/queen/queen.cpp
@@ -31,11 +31,13 @@
#include "common/timer.h"
#include "queen/queen.h"
+#include "queen/bankman.h"
#include "queen/command.h"
#include "queen/cutaway.h"
#include "queen/debug.h"
#include "queen/display.h"
#include "queen/graphics.h"
+#include "queen/grid.h"
#include "queen/input.h"
#include "queen/logic.h"
#include "queen/music.h"
@@ -108,6 +110,7 @@ QueenEngine::~QueenEngine() {
delete _debugger;
delete _display;
delete _graphics;
+ delete _grid;
delete _input;
delete _logic;
delete _music;
@@ -263,6 +266,7 @@ void QueenEngine::initialise(void) {
_debugger = new Debugger(this);
_display = new Display(this, _system);
_graphics = new Graphics(this);
+ _grid = new Grid(this);
_input = new Input(_resource->getLanguage(), _system);
if (_resource->isDemo()) {
diff --git a/queen/queen.h b/queen/queen.h
index a2f659940b..25d85fdf17 100644
--- a/queen/queen.h
+++ b/queen/queen.h
@@ -34,6 +34,7 @@ class Command;
class Debugger;
class Display;
class Graphics;
+class Grid;
class Input;
class Logic;
class Music;
@@ -53,6 +54,7 @@ public:
Debugger *debugger() const { return _debugger; }
Display *display() const { return _display; }
Graphics *graphics() const { return _graphics; }
+ Grid *grid() const { return _grid; }
Input *input() const { return _input; }
Logic *logic() const { return _logic; }
Music *music() const { return _music; }
@@ -95,6 +97,7 @@ protected:
Debugger *_debugger;
Display *_display;
Graphics *_graphics;
+ Grid *_grid;
Input *_input;
Logic *_logic;
Music *_music;
diff --git a/queen/structs.h b/queen/structs.h
index 70d787d6c7..5b90bec5d6 100644
--- a/queen/structs.h
+++ b/queen/structs.h
@@ -595,6 +595,13 @@ struct TalkSelected {
};
+struct BobFrame {
+ uint16 width, height;
+ uint16 xhotspot, yhotspot;
+ uint8 *data;
+};
+
+
} // End of namespace Queen
#endif
diff --git a/queen/talk.cpp b/queen/talk.cpp
index b80612c908..33b2b0bec9 100644
--- a/queen/talk.cpp
+++ b/queen/talk.cpp
@@ -22,8 +22,10 @@
#include "stdafx.h"
#include "queen/talk.h"
+#include "queen/bankman.h"
#include "queen/display.h"
#include "queen/graphics.h"
+#include "queen/grid.h"
#include "queen/input.h"
#include "queen/logic.h"
#include "queen/queen.h"
@@ -301,7 +303,7 @@ void Talk::talk(const char *filename, int personInRoom, char *cutawayFilename) {
}
}
- _vm->logic()->zoneSetupPanel();
+ _vm->grid()->setupPanel();
uint8 *ptr = _cutawayPtr;
@@ -1003,7 +1005,7 @@ void Talk::speakSegment(
textY = bob->y;
}
- //int SF = _vm->logic()->findScale(textX, textY);
+ //int SF = _vm->grid()->findScale(textX, textY);
const SpeechParameters *parameters = NULL;
int startFrame = 0;
@@ -1266,11 +1268,11 @@ int16 Talk::selectSentence() {
// Set zones for UP/DOWN text arrows when not English version
- _vm->logic()->zoneClearAll(ZONE_PANEL);
+ _vm->grid()->clear(GS_PANEL);
if (_vm->resource()->getLanguage() != ENGLISH) {
- _vm->logic()->zoneSet(ZONE_PANEL, ARROW_ZONE_UP, MAX_TEXT_WIDTH + 1, 0, 319, 24);
- _vm->logic()->zoneSet(ZONE_PANEL, ARROW_ZONE_DOWN, MAX_TEXT_WIDTH + 1, 25, 319, 49);
+ _vm->grid()->setZone(GS_PANEL, ARROW_ZONE_UP, MAX_TEXT_WIDTH + 1, 0, 319, 24);
+ _vm->grid()->setZone(GS_PANEL, ARROW_ZONE_DOWN, MAX_TEXT_WIDTH + 1, 25, 319, 49);
}
_vm->graphics()->textClear(151,199);
@@ -1289,8 +1291,8 @@ int16 Talk::selectSentence() {
optionLines = splitOption(removeStar(temp), optionText);
if (yOffset < 5) {
- _vm->logic()->zoneSet(
- ZONE_PANEL,
+ _vm->grid()->setZone(
+ GS_PANEL,
i,
0,
yOffset * LINE_HEIGHT - PUSHUP,
@@ -1336,7 +1338,7 @@ int16 Talk::selectSentence() {
_vm->update();
- zone = _vm->logic()->zoneIn(ZONE_PANEL, _vm->input()->mousePosX(), _vm->input()->mousePosY());
+ zone = _vm->grid()->findZoneForPos(GS_PANEL, _vm->input()->mousePosX(), _vm->input()->mousePosY());
if (5 == zone || 6 == zone) {
// XXX Arrow zones
@@ -1351,12 +1353,14 @@ int16 Talk::selectSentence() {
oldZone, zone);*/
if (zone > 0) {
- for (y = _vm->logic()->zoneBox(ZONE_PANEL, zone).y1; y < _vm->logic()->zoneBox(ZONE_PANEL, zone).y2; y += 10)
+ const Box *b = _vm->grid()->zone(GS_PANEL, zone);
+ for (y = b->y1; y < b->y2; y += 10)
_vm->graphics()->textColor(150 + y, INK_JOE);
}
if (oldZone > 0) {
- for (y = _vm->logic()->zoneBox(ZONE_PANEL, oldZone).y1; y < _vm->logic()->zoneBox(ZONE_PANEL, oldZone).y2; y += 10)
+ const Box *b = _vm->grid()->zone(GS_PANEL, oldZone);
+ for (y = b->y1; y < b->y2; y += 10)
_vm->graphics()->textColor(150 + y, INK_TALK_NORMAL);
}
diff --git a/queen/walk.cpp b/queen/walk.cpp
index 4ff4bd44fd..6bcd0e5146 100644
--- a/queen/walk.cpp
+++ b/queen/walk.cpp
@@ -22,9 +22,10 @@
#include "stdafx.h"
#include "queen/walk.h"
-#include "queen/defs.h"
+#include "queen/bankman.h"
#include "queen/logic.h"
#include "queen/graphics.h"
+#include "queen/grid.h"
#include "queen/queen.h"
namespace Queen {
@@ -122,7 +123,7 @@ void Walk::animateJoe() {
pbs->animNormal(pwd->anim.firstFrame, pwd->anim.lastFrame, 1, false, false);
}
- uint16 moveSpeed = _vm->logic()->findScale(pbs->x, pbs->y) * 6 / 100;
+ uint16 moveSpeed = _vm->grid()->findScale(pbs->x, pbs->y) * 6 / 100;
pbs->move(pbs->x + pwd->dx, pbs->y + pwd->dy, moveSpeed);
pbs->xflip = (pbs->xdir < 0);
while (pbs->moving) {
@@ -250,7 +251,7 @@ void Walk::animatePerson(const MovePersonData *mpd, uint16 image, uint16 bobNum,
}
// move other actors at correct speed relative to scale
- uint16 moveSpeed = _vm->logic()->findScale(pbs->x, pbs->y) * mpd->moveSpeed / 100;
+ uint16 moveSpeed = _vm->grid()->findScale(pbs->x, pbs->y) * mpd->moveSpeed / 100;
pbs->move(pbs->x + pwd->dx, pbs->y + pwd->dy, moveSpeed);
// flip if one set of frames for actor
@@ -287,8 +288,8 @@ int16 Walk::moveJoe(int direction, int16 endx, int16 endy, bool inCutaway) {
_vm->logic()->joeWalk(JWM_MOVE);
- uint16 oldPos = _vm->logic()->zoneInArea(ZONE_ROOM, oldx, oldy);
- uint16 newPos = _vm->logic()->zoneInArea(ZONE_ROOM, endx, endy);
+ uint16 oldPos = _vm->grid()->findAreaForPos(GS_ROOM, oldx, oldy);
+ uint16 newPos = _vm->grid()->findAreaForPos(GS_ROOM, endx, endy);
debug(9, "Walk::moveJoe(%d, %d, %d, %d, %d) - old = %d, new = %d", direction, oldx, oldy, endx, endy, oldPos, newPos);
@@ -342,8 +343,8 @@ int16 Walk::movePerson(const Person *pp, int16 endx, int16 endy, uint16 curImage
uint16 oldx = _vm->graphics()->bob(bobNum)->x;
uint16 oldy = _vm->graphics()->bob(bobNum)->y;
- uint16 oldPos = _vm->logic()->zoneInArea(ZONE_ROOM, oldx, oldy);
- uint16 newPos = _vm->logic()->zoneInArea(ZONE_ROOM, endx, endy);
+ uint16 oldPos = _vm->grid()->findAreaForPos(GS_ROOM, oldx, oldy);
+ uint16 newPos = _vm->grid()->findAreaForPos(GS_ROOM, endx, endy);
debug(9, "Walk::movePerson(%d, %d, %d, %d, %d) - old = %d, new = %d", direction, oldx, oldy, endx, endy, oldPos, newPos);
@@ -419,8 +420,8 @@ bool Walk::calc(uint16 oldPos, uint16 newPos, int16 oldx, int16 oldy, int16 x, i
for (i = 2; i <= _areaListCount; ++i) {
uint16 a1 = _areaList[i - 1];
uint16 a2 = _areaList[i];
- const Area *pa1 = _vm->logic()->currentRoomArea(a1);
- const Area *pa2 = _vm->logic()->currentRoomArea(a2);
+ const Area *pa1 = &_roomArea[a1];
+ const Area *pa2 = &_roomArea[a2];
uint16 x1 = calcC(pa1->box.x1, pa1->box.x2, pa2->box.x1, pa2->box.x2, px);
uint16 y1 = calcC(pa1->box.y1, pa1->box.y2, pa2->box.y1, pa2->box.y2, py);
incWalkData(px, py, x1, y1, a1);
@@ -458,10 +459,10 @@ int16 Walk::findAreaPosition(int16 *x, int16 *y, bool recalibrate) {
uint16 i;
uint16 pos = 1;
uint32 minDist = ~0;
- const Box *b = &_vm->logic()->currentRoomArea(1)->box;
- for (i = 1; i <= _vm->logic()->currentRoomAreaMax(); ++i) {
+ const Box *b = &_roomArea[1].box;
+ for (i = 1; i <= _roomAreaCount; ++i) {
- b = &_vm->logic()->currentRoomArea(i)->box;
+ b = &_roomArea[i].box;
uint16 dx1 = ABS(b->x1 - *x);
uint16 dx2 = ABS(b->x2 - *x);
@@ -490,7 +491,7 @@ int16 Walk::findAreaPosition(int16 *x, int16 *y, bool recalibrate) {
// we now have the closest area near X,Y, so we can recalibrate
// the X,Y coord to be in this area
if (recalibrate) {
- b = &_vm->logic()->currentRoomArea(pos)->box;
+ b = &_roomArea[pos].box;
if(*x < b->x1) *x = b->x1;
if(*x > b->x2) *x = b->x2;
if(*y < b->y1) *y = b->y1;
@@ -503,9 +504,9 @@ int16 Walk::findAreaPosition(int16 *x, int16 *y, bool recalibrate) {
uint16 Walk::findFreeArea(uint16 area) const {
uint16 testArea;
uint16 freeArea = 0;
- uint16 map = ABS(_vm->logic()->currentRoomArea(area)->mapNeighbours);
- for (testArea = 1; testArea <= _vm->logic()->currentRoomAreaMax(); ++testArea) {
- int b = _vm->logic()->currentRoomAreaMax() - testArea;
+ uint16 map = ABS(_roomArea[area].mapNeighbours);
+ for (testArea = 1; testArea <= _roomAreaCount; ++testArea) {
+ int b = _roomAreaCount - testArea;
if (map & (1 << b)) {
// connecting area, check if it's been struck off
if(!isAreaStruck(testArea)) {
@@ -558,6 +559,10 @@ bool Walk::calcPath(uint16 oldArea, uint16 newArea) {
void Walk::initWalkData() {
+ uint16 curRoom = _vm->logic()->currentRoom();
+ _roomArea = _vm->grid()->area(curRoom, 0);
+ _roomAreaCount = _vm->grid()->areaMax(curRoom);
+
_walkDataCount = 0;
memset(_walkData, 0, sizeof(_walkData));
_areaStrikeCount = 0;
@@ -569,13 +574,12 @@ void Walk::initWalkData() {
void Walk::incWalkData(int16 px, int16 py, int16 x, int16 y, uint16 areaNum) {
debug(9, "Walk::incWalkData(%d, %d, %d)", (x - px), (y - py), areaNum);
-
if (px != x || py != y) {
++_walkDataCount;
WalkData *pwd = &_walkData[_walkDataCount];
pwd->dx = x - px;
pwd->dy = y - py;
- pwd->area = _vm->logic()->currentRoomArea(areaNum);
+ pwd->area = &_roomArea[areaNum];
pwd->areaNum = areaNum;
}
}
diff --git a/queen/walk.h b/queen/walk.h
index 16c64e1b67..54238a6250 100644
--- a/queen/walk.h
+++ b/queen/walk.h
@@ -113,7 +113,10 @@ private:
bool calc(uint16 oldPos, uint16 newPos, int16 oldx, int16 oldy, int16 x, int16 y);
- WalkData _walkData[MAX_WALK_DATA];
+ const Area *_roomArea;
+ uint16 _roomAreaCount;
+
+ WalkData _walkData[MAX_WALK_DATA];
uint16 _walkDataCount;
uint16 _areaStrike[MAX_WALK_DATA];
diff --git a/queen/xref.txt b/queen/xref.txt
index 48c287d614..3e5e746456 100644
--- a/queen/xref.txt
+++ b/queen/xref.txt
@@ -211,8 +211,6 @@ DISP_ROOM() Logic::roomDisplay
FIND_BOB() Logic::findBob
FIND_FRAME() Logic::findFrame
FIND_GRAPHIC() Logic::graphicData
-FIND_SCALE() Logic::findScale
-FIND_VERB() Logic::findVerb
P3_COPY_FROM() Logic::objectCopy
R_MAP() Logic::handlePinnacleRoom
REDISP_OBJECT() Logic::roomRefreshObject
@@ -231,8 +229,6 @@ A_NAME_MAX Logic::_numAName
A_FILEstr Logic::_aFile
A_FILE_MAX Logic::_numAFile
ACTOR_DATA_MAX Logic::_numActors
-AREA Logic::_area
-AREAMAX Logic::_areaMax
bamflag BamScene::_flag
bamindex BamScene::_index
DESCTOT Logic::_numDescriptions
@@ -251,11 +247,11 @@ ITEM_DATA Logic::_itemData
NAMETOT Logic::_numNames
OBJ_DESC_DATA Logic::_objectDescription
OBJ_DESC_MAX Logic::_numObjDesc
-OBJECT_BOX Logic::_objectBox
+OBJECT_BOX Grid::_objectBox
OBJECT_DATA Logic::_objectData
OBJECT_DESCRstr Logic::_objDescription
OBJECT_NAMEstr Logic::_objName
-OBJMAX Logic::_objMax
+OBJMAX Grid::_objMax
OBJTOT Logic::_numObjects
OLDROOM,ROOM,NEW_ROOM Logic::_*oom
ROOMTOT Logic::_numRooms
@@ -416,13 +412,17 @@ WALKI Walk::_walkDataCount
ZONES
=====
-ClearZones() Logic::zoneClearAll
-SETUP_PANEL_ZONES() Logic::zoneSetupPanel
-SETUP_ZONES() Logic::zoneSetup
-SetZone() Logic::zoneSet
-zone() Logic::zoneIn / Logic::zoneInArea
+ClearZones() Grid::clear
+FIND_SCALE() Grid::findScale
+FIND_VERB() Grid::findVerbUnderCursor
+SETUP_PANEL_ZONES() Grid::setupPanel
+SETUP_ZONES() Grid::setupNewRoom
+SetZone() Grid::setZone
+zone() Grid:findZoneForPos / Logic::findAreaForPos
-
-zones Logic::_zones
+AREA Grid::_area
+AREAMAX Grid::_areaMax
+zones Grid::_zones
(UNSORTED)