diff options
Diffstat (limited to 'queen')
-rw-r--r-- | queen/bankman.cpp | 146 | ||||
-rw-r--r-- | queen/bankman.h | 72 | ||||
-rw-r--r-- | queen/command.cpp | 19 | ||||
-rw-r--r-- | queen/cutaway.cpp | 17 | ||||
-rw-r--r-- | queen/graphics.cpp | 119 | ||||
-rw-r--r-- | queen/graphics.h | 50 | ||||
-rw-r--r-- | queen/grid.cpp | 244 | ||||
-rw-r--r-- | queen/grid.h | 93 | ||||
-rw-r--r-- | queen/journal.cpp | 26 | ||||
-rw-r--r-- | queen/logic.cpp | 229 | ||||
-rw-r--r-- | queen/logic.h | 46 | ||||
-rw-r--r-- | queen/module.mk | 2 | ||||
-rw-r--r-- | queen/queen.cpp | 4 | ||||
-rw-r--r-- | queen/queen.h | 3 | ||||
-rw-r--r-- | queen/structs.h | 7 | ||||
-rw-r--r-- | queen/talk.cpp | 24 | ||||
-rw-r--r-- | queen/walk.cpp | 40 | ||||
-rw-r--r-- | queen/walk.h | 5 | ||||
-rw-r--r-- | queen/xref.txt | 24 |
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) |