diff options
Diffstat (limited to 'engines/xeen/dialogs/dialogs_map.cpp')
-rw-r--r-- | engines/xeen/dialogs/dialogs_map.cpp | 461 |
1 files changed, 461 insertions, 0 deletions
diff --git a/engines/xeen/dialogs/dialogs_map.cpp b/engines/xeen/dialogs/dialogs_map.cpp new file mode 100644 index 0000000000..b822c71472 --- /dev/null +++ b/engines/xeen/dialogs/dialogs_map.cpp @@ -0,0 +1,461 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "xeen/dialogs/dialogs_map.h" +#include "xeen/resources.h" +#include "xeen/xeen.h" + +namespace Xeen { + +#define MAP_SIZE 16 +#define MAP_DIFF (MAP_SIZE / 2) +#define MAP_XSTART 80 +#define MAP_YSTART 38 +#define TILE_WIDTH 10 +#define TILE_HEIGHT 8 + +void MapDialog::show(XeenEngine *vm) { + MapDialog *dlg = new MapDialog(vm); + dlg->execute(); + delete dlg; +} + +void MapDialog::execute() { + EventsManager &events = *_vm->_events; + Interface &intf = *_vm->_interface; + Map &map = *_vm->_map; + Party &party = *_vm->_party; + Windows &windows = *_vm->_windows; + + _pt = party._mazePosition; + _globalSprites.load("global.icn"); + + if (_pt.x < 8 && map.mazeData()._surroundingMazes._west == 0) { + _arrowPt.x = _pt.x * 10 + 4; + _pt.x = 7; + } else if (_pt.x > 23) { + _arrowPt.x = (byte)(_pt.x * 10 + 100); + _pt.x = 23; + } else if (_pt.x > 8 && map.mazeData()._surroundingMazes._east == 0) { + _arrowPt.x = (byte)(_pt.x * 10 + 4); + _pt.x = 7; + } else { + _arrowPt.x = 74; + } + + if (_pt.y < 8 && map.mazeData()._surroundingMazes._south == 0) { + _arrowPt.y = ((15 - _pt.y) << 3) + 13; + _pt.y = 8; + } else if (_pt.y > 24) { + _arrowPt.y = ((15 - (_pt.y - 16)) << 3) + 13; + _pt.y = 24; + } else if (_pt.y >= 8 && map.mazeData()._surroundingMazes._north == 0) { + _arrowPt.y = ((15 - _pt.y) << 3) + 13; + _pt.y = 8; + } else { + _arrowPt.y = 69; + } + + windows[5].open(); + bool drawFlag = true; + + events.updateGameCounter(); + do { + if (drawFlag) + intf.draw3d(false, false); + windows[5].writeString("\r"); + + if (map._isOutdoors) + drawOutdoors(); + else + drawIndoors(); + + windows[5].frame(); + if (!map._isOutdoors) { + map._tileSprites.draw(0, 52, Common::Point(76, 30)); + } else if (_frameEndFlag) { + _globalSprites.draw(0, party._mazeDirection + 1, + Common::Point(_arrowPt.x + 76, _arrowPt.y + 25)); + } + + if (events.timeElapsed() > 5) { + // Set the flag to make the basic arrow blinking effect + _frameEndFlag = !_frameEndFlag; + events.updateGameCounter(); + } + + windows[5].writeString(Common::String::format(Res.MAP_TEXT, + map._mazeName.c_str(), party._mazePosition.x, + party._mazePosition.y, Res.DIRECTION_TEXT[party._mazeDirection])); + windows[5].update(); + windows[3].update(); + + events.ipause5(2); + drawFlag = false; + } while (!_vm->shouldExit() && !events.isKeyMousePressed()); + + events.clearEvents(); + windows[5].close(); +} + +void MapDialog::drawOutdoors() { + Map &map = *g_vm->_map; + int v, frame; + + // Draw outdoors map + for (int yp = MAP_YSTART, mazeY = _pt.y + MAP_DIFF - 1; mazeY >= (_pt.y - MAP_DIFF); + --mazeY, yp += TILE_HEIGHT) { + for (int xp = MAP_XSTART, mazeX = _pt.x - (MAP_DIFF - 1); mazeX <= (_pt.x + MAP_DIFF); + xp += TILE_WIDTH, ++mazeX) { + v = map.mazeLookup(Common::Point(mazeX, mazeY), 0); + assert(v != INVALID_CELL); + frame = map.mazeDataCurrent()._surfaceTypes[v]; + + if (map._currentSteppedOn) { + map._tileSprites.draw(0, frame, Common::Point(xp, yp)); + } + } + } + + for (int yp = MAP_YSTART, mazeY = _pt.y + MAP_DIFF - 1; mazeY >= (_pt.y - MAP_DIFF); + --mazeY, yp += TILE_HEIGHT) { + for (int xp = MAP_XSTART, mazeX = _pt.x - (MAP_DIFF - 1); mazeX <= (_pt.x + MAP_DIFF); + xp += TILE_WIDTH, ++mazeX) { + v = map.mazeLookup(Common::Point(mazeX, mazeY), 4); + assert(v != INVALID_CELL); + frame = map.mazeDataCurrent()._wallTypes[v]; + + if (frame && map._currentSteppedOn) + map._tileSprites.draw(0, frame + 16, Common::Point(xp, yp)); + } + } + + for (int yp = MAP_YSTART, mazeY = _pt.y + MAP_DIFF - 1; mazeY >= (_pt.y - MAP_DIFF); + --mazeY, yp += TILE_HEIGHT) { + for (int xp = MAP_XSTART, mazeX = _pt.x - (MAP_DIFF - 1); mazeX <= (_pt.x + MAP_DIFF); + xp += TILE_WIDTH, ++mazeX) { + frame = map.mazeLookup(Common::Point(mazeX, mazeY), 8, 0xff); + + if (frame && map._currentSteppedOn) + map._tileSprites.draw(0, frame + 32, Common::Point(xp, yp)); + } + } +} + +void MapDialog::drawIndoors() { + Map &map = *g_vm->_map; + Party &party = *g_vm->_party; + int v, frame; + int frame2 = _animFrame; + _animFrame = (_animFrame + 2) % 8; + + // Draw indoors map + frame2 = (frame2 + 2) % 8; + + // Draw default ground for all the valid explored areas + for (int yp = MAP_YSTART, mazeY = _pt.y + MAP_DIFF - 1; mazeY >= (_pt.y - MAP_DIFF); + yp += TILE_HEIGHT, --mazeY) { + for (int xp = MAP_XSTART, mazeX = _pt.x - (MAP_DIFF - 1); mazeX <= (_pt.x + MAP_DIFF); + xp += TILE_WIDTH, ++mazeX) { + v = map.mazeLookup(Common::Point(mazeX, mazeY), 0, 0xffff); + + if (v != INVALID_CELL && map._currentSteppedOn) + map._tileSprites.draw(0, 0, Common::Point(xp, yp)); + } + } + + // Draw thinner ground tiles on the left edge of the map + for (int yp = MAP_YSTART + 5, mazeY = _pt.y + MAP_DIFF - 1; mazeY >= (_pt.y - MAP_DIFF); + yp += TILE_HEIGHT, --mazeY) { + v = map.mazeLookup(Common::Point(_pt.x - 8, mazeY), 0, 0xffff); + + if (v != INVALID_CELL && map._currentSurfaceId != 0 && map._currentSteppedOn) + map._tileSprites.draw(0, 36 + map.mazeData()._surfaceTypes[ + map._currentSurfaceId], Common::Point(75, yp)); + } + + // Draw thin tile portion on top-left corner of map + v = map.mazeLookup(Common::Point(_pt.x - 8, _pt.y + 8), 0, 0xffff); + if (v != INVALID_CELL && map._currentSurfaceId != 0 && map._currentSteppedOn) + map._tileSprites.draw(0, 36 + map.mazeData()._surfaceTypes[ + map._currentSurfaceId], Common::Point(75, 35)); + + // Draw any thin tiles at the very top of the map + for (int xp = MAP_XSTART + 5, mazeX = _pt.x - (MAP_DIFF - 1); mazeX <= (_pt.x + MAP_DIFF); + xp += TILE_WIDTH, ++mazeX) { + v = map.mazeLookup(Common::Point(mazeX, _pt.y + 8), 0, 0xffff); + + if (v != INVALID_CELL && map._currentSurfaceId != 0 && map._currentSteppedOn) + map._tileSprites.draw(0, 36 + map.mazeData()._surfaceTypes[ + map._currentSurfaceId], Common::Point(xp, 35)); + } + + // Draw the default ground tiles + for (int yp = MAP_YSTART + 5, mazeY = _pt.y + MAP_DIFF - 1; mazeY >= (_pt.y - MAP_DIFF); + yp += TILE_HEIGHT, --mazeY) { + for (int xp = MAP_XSTART + 5, mazeX = _pt.x - (MAP_DIFF - 1); mazeX <= (_pt.x + MAP_DIFF); + xp += TILE_WIDTH, ++mazeX) { + v = map.mazeLookup(Common::Point(mazeX, mazeY), 0, 0xffff); + + if (v != INVALID_CELL && map._currentSurfaceId && map._currentSteppedOn) + map._tileSprites.draw(0, 36 + map.mazeData()._surfaceTypes[ + map._currentSurfaceId], Common::Point(xp, yp)); + } + } + + // Draw walls on left and top edges of map + for (int xp = MAP_XSTART, yp = MAP_YSTART + (MAP_SIZE - 1) * TILE_HEIGHT, + mazeX = _pt.x - (MAP_DIFF - 1), mazeY = _pt.y - MAP_DIFF; + mazeX < (_pt.x + MAP_DIFF); xp += TILE_WIDTH, yp -= TILE_HEIGHT, ++mazeX, ++mazeY) { + // Draw walls on left edge of map + v = map.mazeLookup(Common::Point(_pt.x - 8, mazeY), 12); + + switch (v) { + case SURFTYPE_DIRT: + frame = 18; + break; + case SURFTYPE_SNOW: + frame = 22; + break; + case SURFTYPE_SWAMP: + case SURFTYPE_CLOUD: + frame = 16; + break; + case SURFTYPE_LAVA: + case SURFTYPE_DWATER: + frame = 2; + break; + case SURFTYPE_DESERT: + frame = 30; + break; + case SURFTYPE_ROAD: + frame = 32; + break; + case SURFTYPE_TFLR: + frame = 20; + break; + case SURFTYPE_SKY: + frame = 28; + break; + case SURFTYPE_CROAD: + frame = 14; + break; + case SURFTYPE_SEWER: + frame = frame2 + 4; + break; + case SURFTYPE_SCORCH: + frame = 24; + break; + case SURFTYPE_SPACE: + frame = 26; + break; + default: + frame = -1; + break; + } + + if (frame != -1 && map._currentSteppedOn) + map._tileSprites.draw(0, frame, Common::Point(70, yp)); + + // Draw walls on top edge of map + v = map.mazeLookup(Common::Point(mazeX, _pt.y + 8), 0); + + switch (v) { + case SURFTYPE_DIRT: + frame = 19; + break; + case SURFTYPE_GRASS: + frame = 35; + break; + case SURFTYPE_SNOW: + frame = 23; + break; + case SURFTYPE_SWAMP: + case SURFTYPE_CLOUD: + frame = 17; + break; + case SURFTYPE_LAVA: + case SURFTYPE_DWATER: + frame = 3; + break; + case SURFTYPE_DESERT: + frame = 31; + break; + case SURFTYPE_ROAD: + frame = 33; + break; + case SURFTYPE_TFLR: + frame = 21; + break; + case SURFTYPE_SKY: + frame = 29; + break; + case SURFTYPE_CROAD: + frame = 15; + break; + case SURFTYPE_SEWER: + frame = frame2 + 5; + break; + case SURFTYPE_SCORCH: + frame = 25; + break; + case SURFTYPE_SPACE: + frame = 27; + break; + default: + frame = -1; + break; + } + + if (frame != -1 && map._currentSteppedOn) + map._tileSprites.draw(0, frame, Common::Point(xp, 30)); + } + + // Draw the walls for the remaining cells of the minimap + for (int yp = MAP_YSTART, mazeY = _pt.y + MAP_DIFF - 1, yCtr = 0; yCtr < MAP_SIZE; + yp += TILE_HEIGHT, --mazeY, ++yCtr) { + for (int xp = MAP_XSTART, mazeX = _pt.x - (MAP_DIFF - 1), xCtr = 0; xCtr < MAP_SIZE; + xp += TILE_WIDTH, ++mazeX, ++xCtr) { + // Draw the arrow if at the correct position + if ((_arrowPt.x / 10) == xCtr && (14 - (_arrowPt.y / 10)) == yCtr && _frameEndFlag) { + _globalSprites.draw(0, party._mazeDirection + 1, + Common::Point(_arrowPt.x + 81, _arrowPt.y + 29)); + } + + v = map.mazeLookup(Common::Point(mazeX, mazeY), 12); + switch (v) { + case 1: + frame = 18; + break; + case 2: + frame = 34; + 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) + map._tileSprites.draw(0, frame, Common::Point(xp, yp)); + + v = map.mazeLookup(Common::Point(mazeX, mazeY), 0); + 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 (frame != -1 && map._currentSteppedOn) + map._tileSprites.draw(0, frame, Common::Point(xp, yp)); + } + } + + // Draw overlay on cells that haven't been stepped on yet + for (int yp = MAP_YSTART, mazeY = _pt.y + MAP_DIFF - 1; mazeY >= (_pt.y - MAP_DIFF); + yp += TILE_HEIGHT, --mazeY) { + for (int xp = MAP_XSTART, mazeX = _pt.x - (MAP_DIFF - 1); mazeX <= (_pt.x + MAP_DIFF); + xp += TILE_WIDTH, ++mazeX) { + v = map.mazeLookup(Common::Point(mazeX, mazeY), 0, 0xffff); + + if (v == INVALID_CELL || !map._currentSteppedOn) + map._tileSprites.draw(0, 1, Common::Point(xp, yp)); + } + } +} + +} // End of namespace Xeen |