From e559a99c2794c727d04adf4602f0aac1112af765 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 19 Jan 2015 15:29:57 -0500 Subject: XEEN: Initial implementation of drawMiniMap --- engines/xeen/interface.cpp | 502 +++++++++++++++++++++++++++++++++++++++------ engines/xeen/interface.h | 4 +- engines/xeen/map.cpp | 4 +- engines/xeen/map.h | 6 +- 4 files changed, 446 insertions(+), 70 deletions(-) (limited to 'engines/xeen') diff --git a/engines/xeen/interface.cpp b/engines/xeen/interface.cpp index 8ff0b92d13..bcb406dcbe 100644 --- a/engines/xeen/interface.cpp +++ b/engines/xeen/interface.cpp @@ -722,7 +722,7 @@ void Interface::draw3d(bool updateFlag) { } animate3d(); - updateAutoMap(); + drawMiniMap(); if (_vm->_falling == 1) { error("TODO: Indoor falling"); @@ -808,7 +808,7 @@ void Interface::setMainButtons() { addButton(Common::Rect(235, 169, 259, 189), 176, &_iconSprites); addButton(Common::Rect(260, 169, 284, 189), 243, &_iconSprites); addButton(Common::Rect(286, 169, 310, 189), 177, &_iconSprites); - addButton(Common::Rect(236, 11, 308, 69), 61, &_iconSprites, false); + addButton(Common::Rect(236, 11, 308, 69), Common::KEYCODE_EQUALS, &_iconSprites, false); addButton(Common::Rect(239, 27, 312, 37), 49, &_iconSprites, false); addButton(Common::Rect(239, 37, 312, 47), 50, &_iconSprites, false); addButton(Common::Rect(239, 47, 312, 57), 51, &_iconSprites, false); @@ -2309,96 +2309,468 @@ void Interface::setMazeBits() { } } -void Interface::updateAutoMap() { - // TODO -} - -/** - * Waits for a keypress or click, whilst still allowing the game scene to - * be animated. - */ -void Interface::perform() { - EventsManager &events = *_vm->_events; +void Interface::drawMiniMap() { Map &map = *_vm->_map; Party &party = *_vm->_party; - Scripts &scripts = *_vm->_scripts; - const Common::Rect waitBounds(8, 8, 224, 140); + Screen &screen = *_vm->_screen; + Window &window1 = screen._windows[1]; - while (!_vm->shouldQuit()) { - events.updateGameCounter(); - draw3d(true); + if (screen._windows[2]._enabled || screen._windows[10]._enabled || + (!party._automapOn && !party._wizardEyeActive)) + return; - // Wait for a frame - do { - events.pollEventsAndWait(); - checkEvents(_vm); - } while (!_buttonValue && events.timeElapsed() < 1 && !_vm->_party->_partyDead); + int v, frame; + int frame2 = _overallFrame * 2; + bool eyeActive = party._wizardEyeActive; + if (party._automapOn) + party._wizardEyeActive = false; - if (!_buttonValue && !_vm->_party->_partyDead) - continue; + if (map._isOutdoors) { + _globalSprites.draw(window1, 15, Common::Point(237, 12)); - if (_buttonValue == Common::KEYCODE_SPACE || - (events._leftButton && waitBounds.contains(events._mousePos))) { - int lookupId = map.mazeLookup(party._mazePosition, - WALL_NUMBERS[party._mazeDirection][2]); + for (int rowNum = 0, yp = 12, yDiff = 3; rowNum < MINIMAP_SIZE; ++rowNum, yp += 8, --yDiff) { + for (int colNum = 0, xp = 237, xDiff = -3; colNum < MINIMAP_SIZE; ++colNum, xp += 10, ++xDiff) { + v = map.mazeLookup( + Common::Point(party._mazePosition.x + xDiff, party._mazePosition.y + yDiff), + 4); + frame = map.mazeDataCurrent()._surfaceTypes[v]; - bool eventsFlag = true; - switch (lookupId) { - case 1: - if (!map._isOutdoors) { - scripts.openGrate(13, 1); - eventsFlag = _buttonValue != 0; + if (frame != -1 && (map._currentSteppedOn || party._wizardEyeActive)) { + map._tileSprites.draw(window1, frame, Common::Point(xp, yp)); } + } + } - case 6: - if (!map._isOutdoors) { - scripts.openGrate(9, 0); - eventsFlag = _buttonValue != 0; + for (int rowNum = 0, yp = 12, yDiff = 3; rowNum < MINIMAP_SIZE; ++rowNum, yp += 8, --yDiff) { + for (int colNum = 0, xp = 237, xDiff = -3; colNum < MINIMAP_SIZE; ++colNum, xp += 10, ++xDiff) { + v = map.mazeLookup( + Common::Point(party._mazePosition.x + xDiff, party._mazePosition.y + yDiff), + 4); + frame = map.mazeData()._wallTypes[v]; + + if (frame != -1 && (map._currentSteppedOn || party._wizardEyeActive)) { + map._tileSprites.draw(window1, frame + 16, Common::Point(xp, yp)); } + } + } + + for (int rowNum = 0, yp = 12, yDiff = 3; rowNum < MINIMAP_SIZE; ++rowNum, yp += 8, --yDiff) { + for (int colNum = 0, xp = 237, xDiff = -3; colNum < MINIMAP_SIZE; ++colNum, xp += 10, ++xDiff) { + v = map.mazeLookup( + Common::Point(party._mazePosition.x + xDiff, party._mazePosition.y + yDiff), + 4); + + if (v != -1 && (map._currentSteppedOn || party._wizardEyeActive)) { + map._tileSprites.draw(window1, v + 32, Common::Point(xp, yp)); + } + } + } + } else { + frame2 = (frame2 + 2) % 8; + + // First draw cell back for positions in the map that have been revealed + for (int rowNum = 0, yp = 12, yDiff = 3; rowNum < MINIMAP_SIZE; ++rowNum, yp += 8, --yDiff) { + for (int colNum = 0, xp = 237, xDiff = -3; colNum < MINIMAP_SIZE; ++colNum, xp += 10, ++xDiff) { + v = map.mazeLookup( + Common::Point(party._mazePosition.x + xDiff, party._mazePosition.y + yDiff), + 0, 0xffff); + + if (v != 0xffff && (map._currentSteppedOn || party._wizardEyeActive)) { + map._tileSprites.draw(window1, 0, Common::Point(xp, yp)); + } + } + } + + // Draw tiles based on the surface for each revelaed tile + for (int rowNum = 0, yp = 17, yDiff = 3; rowNum < MINIMAP_SIZE; ++rowNum, yp += 8, --yDiff) { + for (int colNum = 0, xp = 242, xDiff = -3; colNum < MINIMAP_SIZE; ++colNum, xp += 10, ++xDiff) { + v = map.mazeLookup( + Common::Point(party._mazePosition.x + xDiff, party._mazePosition.y + yDiff), + 0, 0xffff); + + if (v != 0xffff && !map._currentSurfaceId && + (map._currentSteppedOn || party._wizardEyeActive)) { + map._tileSprites.draw(window1, + map.mazeData()._surfaceTypes[map._currentSurfaceId] + 36, + Common::Point(xp, yp)); + } + } + } + + v = map.mazeLookup(Common::Point(party._mazePosition.x - 4, party._mazePosition.y + 4), 0xffff, 0); + if (v != 0xffff && !map._currentSurfaceId && + (map._currentSteppedOn || party._wizardEyeActive)) { + map._tileSprites.draw(window1, + map.mazeData()._surfaceTypes[map._currentSurfaceId] + 36, + Common::Point(232, 9)); + } + + // Right edge + for (int rowNum = 0, yp = 242, yDiff = -3; rowNum < MINIMAP_SIZE; ++rowNum, --yDiff, yp += 8) { + v = map.mazeLookup( + Common::Point(party._mazePosition.x - 4, party._mazePosition.y + yDiff), + 0, 0xffff); + + if (v != 0xffff && !map._currentSurfaceId && + (map._currentSteppedOn || party._wizardEyeActive)) { + map._tileSprites.draw(window1, + map.mazeData()._surfaceTypes[map._currentSurfaceId] + 36, + Common::Point(232, yp)); + } + } + + // Top edge + for (int colNum = 0, xp = 242, xDiff = -3; colNum < MINIMAP_SIZE; ++colNum, --xDiff, xp += 8) { + v = map.mazeLookup( + Common::Point(party._mazePosition.x + xDiff, party._mazePosition.y + 4), + 0, 0xffff); + + if (v != 0xffff && !map._currentSurfaceId && + (map._currentSteppedOn || party._wizardEyeActive)) { + map._tileSprites.draw(window1, + map.mazeData()._surfaceTypes[map._currentSurfaceId] + 36, + Common::Point(xp, 9)); + } + } + + // + for (int idx = 0, xp = 237, yp = 60, xDiff = -3; idx < MINIMAP_SIZE; + ++idx, --xDiff, xp += 10, yp -= 8) { + v = map.mazeLookup( + Common::Point(party._mazePosition.x - 4, party._mazePosition.y - 3 + idx), + 12, 0xffff); + + switch (v) { + case 1: + frame = 18; + break; + case 3: + frame = 22; + break; + case 4: + case 13: + frame = 16; + break; + case 5: + case 8: + frame = 2; + break; + case 6: + frame = 30; + break; + case 7: + frame = 32; break; case 9: - if (!map._isOutdoors) { - scripts.openGrate(6, 0); - eventsFlag = _buttonValue != 0; - } + frame = 24; + break; + case 10: + frame = 28; + break; + case 11: + frame = 14; + break; + case 12: + frame = frame2 + 4; + break; + case 14: + frame = 24; + break; + case 15: + frame = 26; + break; + default: + frame = -1; break; + } + + if (frame != -1 && (map._currentSteppedOn || party._wizardEyeActive)) + map._tileSprites.draw(window1, frame, Common::Point(222, yp)); + + v = map.mazeLookup( + Common::Point(party._mazePosition.x - 3 + idx, party._mazePosition.y + 4), + 0); + + switch (v) { + case 1: + frame = 19; + break; + case 2: + frame = 35; + break; + case 3: + frame = 23; + break; + case 4: case 13: - if (!map._isOutdoors) { - scripts.openGrate(1, 1); - eventsFlag = _buttonValue != 0; - } + frame = 17; + break; + case 5: + case 8: + frame = 3; + break; + case 6: + frame = 31; + break; + case 7: + frame = 33; + break; + case 9: + frame = 21; + break; + case 10: + frame = 29; + break; + case 11: + frame = 15; + break; + case 12: + frame = frame2 + 5; + break; + case 14: + frame = 25; + break; + case 15: + frame = 27; break; default: + frame = -1; break; } - if (eventsFlag) { - scripts.checkEvents(); - if (_vm->shouldQuit()) - return; + + if (frame != -1 && (map._currentSteppedOn || party._wizardEyeActive)) + map._tileSprites.draw(window1, frame, Common::Point(xp, 4)); + } + + // + for (int rowNum = 0, yp = 12, yDiff = 3; rowNum < MINIMAP_SIZE; + ++rowNum, --yDiff, yp -= 8) { + for (int colNum = 0, xp = 237, xDiff = -3; colNum < MINIMAP_SIZE; + ++colNum, ++xDiff, xp += 10) { + if (colNum == 4 && rowNum == 4) { + // Center of the minimap + _globalSprites.draw(window1, party._mazeDirection + 1, + Common::Point(272, 40)); + } + + v = map.mazeLookup(Common::Point(party._mazePosition.x + xDiff, + party._mazePosition.y + yDiff), 12, 0xffff); + switch (v) { + case 1: + frame = 18; + break; + case 3: + frame = 22; + break; + case 4: + case 13: + frame = 16; + break; + case 5: + case 8: + frame = 2; + break; + case 6: + frame = 30; + break; + case 7: + frame = 32; + break; + case 9: + frame = 20; + break; + case 10: + frame = 28; + break; + case 11: + frame = 14; + break; + case 12: + frame = frame2 + 4; + break; + case 14: + frame = 24; + break; + case 15: + frame = 26; + break; + default: + frame = -1; + break; + } + + if (frame != -1 && (map._currentSteppedOn || party._wizardEyeActive)) { + map._tileSprites.draw(window1, frame, Common::Point(xp, yp)); + } + + v = map.mazeLookup(Common::Point(party._mazePosition.x + xDiff, + party._mazePosition.y + yDiff), 12, 0xffff); + switch (v) { + case 1: + frame = 19; + break; + case 2: + frame = 35; + break; + case 3: + frame = 23; + break; + case 4: + case 13: + frame = 17; + break; + case 5: + case 8: + frame = 3; + break; + case 6: + frame = 31; + break; + case 7: + frame = 33; + break; + case 9: + frame = 21; + break; + case 10: + frame = 29; + break; + case 11: + frame = 15; + break; + case 12: + frame = frame2 + 5; + break; + case 14: + frame = 25; + break; + case 15: + frame = 27; + break; + default: + frame = -1; + break; + } + + if (v == -1 && (map._currentSteppedOn || party._wizardEyeActive)) { + map._tileSprites.draw(window1, frame, Common::Point(xp, yp)); + } } } - switch (_buttonValue) { - case Common::KEYCODE_TAB: - // Stop mosters doing any movement - _vm->_moveMonsters = false; - warning("TODO: showControlPanel"); - break; + // Final loop + for (int rowNum = 0, yp = 12, yDiff = 3; rowNum < MINIMAP_SIZE; ++rowNum, yp += 8, --yDiff) { + for (int colNum = 0, xp = 237, xDiff = -3; colNum < MINIMAP_SIZE; ++colNum, xp += 10, ++xDiff) { + v = map.mazeLookup( + Common::Point(party._mazePosition.x + xDiff, party._mazePosition.y + yDiff), + 0, 0xffff); - case Common::KEYCODE_SPACE: - case Common::KEYCODE_w: - // Wait one turn - chargeStep(); - moveMonsters(); - _upDoorText = false; - _flipDefaultGround = !_flipDefaultGround; - _flipGround = !_flipGround; + if (v != 0xffff && !map._currentSurfaceId && + (map._currentSteppedOn || party._wizardEyeActive)) { + map._tileSprites.draw(window1, 1, Common::Point(xp, yp)); + } + } + } + } + + if (map._isOutdoors) { + _globalSprites.draw(window1, party._mazeDirection + 1, + Common::Point(267, 36)); + } + + _globalSprites.draw(window1, 6, Common::Point(223, 3)); + party._wizardEyeActive = eyeActive; +} + +/** + * Waits for a keypress or click, whilst still allowing the game scene to + * be animated. + */ +void Interface::perform() { + EventsManager &events = *_vm->_events; + Map &map = *_vm->_map; + Party &party = *_vm->_party; + Scripts &scripts = *_vm->_scripts; + const Common::Rect waitBounds(8, 8, 224, 140); + + events.updateGameCounter(); + draw3d(true); + + // Wait for a frame + do { + events.pollEventsAndWait(); + checkEvents(_vm); + } while (!_buttonValue && events.timeElapsed() < 1 && !_vm->_party->_partyDead); - stepTime(); + if (!_buttonValue && !_vm->_party->_partyDead) + return; + + if (_buttonValue == Common::KEYCODE_SPACE || + (events._leftButton && waitBounds.contains(events._mousePos))) { + int lookupId = map.mazeLookup(party._mazePosition, + WALL_NUMBERS[party._mazeDirection][2]); + + bool eventsFlag = true; + switch (lookupId) { + case 1: + if (!map._isOutdoors) { + scripts.openGrate(13, 1); + eventsFlag = _buttonValue != 0; + } + + case 6: + if (!map._isOutdoors) { + scripts.openGrate(9, 0); + eventsFlag = _buttonValue != 0; + } + break; + case 9: + if (!map._isOutdoors) { + scripts.openGrate(6, 0); + eventsFlag = _buttonValue != 0; + } + break; + case 13: + if (!map._isOutdoors) { + scripts.openGrate(1, 1); + eventsFlag = _buttonValue != 0; + } break; default: break; } + if (eventsFlag) { + scripts.checkEvents(); + if (_vm->shouldQuit()) + return; + } + } + + switch (_buttonValue) { + case Common::KEYCODE_TAB: + // Stop mosters doing any movement + _vm->_moveMonsters = false; + warning("TODO: showControlPanel"); + break; + + case Common::KEYCODE_SPACE: + case Common::KEYCODE_w: + // Wait one turn + chargeStep(); + moveMonsters(); + _upDoorText = false; + _flipDefaultGround = !_flipDefaultGround; + _flipGround = !_flipGround; + + stepTime(); + break; + case Common::KEYCODE_EQUALS: + case Common::KEYCODE_KP_EQUALS: + // Toggle minimap + party._automapOn = !party._automapOn; + break; + default: + break; } } diff --git a/engines/xeen/interface.h b/engines/xeen/interface.h index af26611e6d..2e19d2230f 100644 --- a/engines/xeen/interface.h +++ b/engines/xeen/interface.h @@ -33,6 +33,8 @@ namespace Xeen { class XeenEngine; +#define MINIMAP_SIZE 7 + class Interface: public ButtonContainer, public InterfaceMap { private: XeenEngine *_vm; @@ -98,7 +100,7 @@ private: void setMazeBits(); - void updateAutoMap(); + void drawMiniMap(); void chargeStep(); diff --git a/engines/xeen/map.cpp b/engines/xeen/map.cpp index bef0511c81..17c49bef80 100644 --- a/engines/xeen/map.cpp +++ b/engines/xeen/map.cpp @@ -1195,7 +1195,7 @@ void Map::load(int mapId) { loadSky(); } -int Map::mazeLookup(const Common::Point &pt, int layerShift) { +int Map::mazeLookup(const Common::Point &pt, int layerShift, int wallMask) { Common::Point pos = pt; int mapId = _vm->_party->_mazeId; @@ -1259,7 +1259,7 @@ int Map::mazeLookup(const Common::Point &pt, int layerShift) { _currentSteppedOn = _mazeData[_mazeDataIndex]._steppedOnTiles[pos.y][pos.x]; } - return (_mazeData[_mazeDataIndex]._wallData[pos.y][pos.x]._data >> layerShift) & 0xF; + return (_mazeData[_mazeDataIndex]._wallData[pos.y][pos.x]._data >> layerShift) & wallMask; } else { _currentSteppedOn = _isOutdoors; diff --git a/engines/xeen/map.h b/engines/xeen/map.h index ae8ad28efd..16ef15cbdb 100644 --- a/engines/xeen/map.h +++ b/engines/xeen/map.h @@ -362,7 +362,6 @@ private: int _sideMonsters; bool _stepped; int _mazeDataIndex; - bool _currentSteppedOn; void loadEvents(int mapId); public: @@ -387,12 +386,13 @@ public: MazeWallLayers _currentWall; int _currentTile; int _currentSurfaceId; + bool _currentSteppedOn; public: Map(XeenEngine *vm); void load(int mapId); - int mazeLookup(const Common::Point &pt, int layerShift); + int mazeLookup(const Common::Point &pt, int layerShift, int wallMask = 0xf); void cellFlagLookup(const Common::Point &pt); @@ -404,6 +404,8 @@ public: MazeData mazeData() { return _mazeData[0]; } + MazeData mazeDataCurrent() { return _mazeData[_mazeDataIndex]; } + void loadSky(); }; -- cgit v1.2.3