From 2472cc0917e3e1a56f61e270e55c76af1152cb05 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 31 Jan 2015 07:22:25 -0500 Subject: XEEN: Initial implementation of map dialog --- engines/xeen/dialogs_automap.cpp | 413 +++++++++++++++++++++++++++++++++++++++ engines/xeen/dialogs_automap.h | 45 +++++ engines/xeen/interface.cpp | 7 + engines/xeen/interface_map.cpp | 2 +- engines/xeen/map.h | 2 +- engines/xeen/module.mk | 2 + engines/xeen/resources.cpp | 28 +-- engines/xeen/resources.h | 4 + 8 files changed, 490 insertions(+), 13 deletions(-) create mode 100644 engines/xeen/dialogs_automap.cpp create mode 100644 engines/xeen/dialogs_automap.h diff --git a/engines/xeen/dialogs_automap.cpp b/engines/xeen/dialogs_automap.cpp new file mode 100644 index 0000000000..08cf593f7b --- /dev/null +++ b/engines/xeen/dialogs_automap.cpp @@ -0,0 +1,413 @@ +/* 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_automap.h" +#include "xeen/resources.h" +#include "xeen/xeen.h" + +namespace Xeen { + + +void AutoMapDialog::show(XeenEngine *vm) { + AutoMapDialog *dlg = new AutoMapDialog(vm); + dlg->execute(); + delete dlg; +} + +void AutoMapDialog::execute() { + Screen &screen = *_vm->_screen; + EventsManager &events = *_vm->_events; + Interface &intf = *_vm->_interface; + Map &map = *_vm->_map; + Party &party = *_vm->_party; + int frame2 = intf._overallFrame * 2; + int varSI = 1; + bool frameEndFlag; + + int yDiffStart = 8; + int xDiffStart = 248; + Common::Point pt = party._mazePosition; + Common::Point arrowPt; + SpriteResource globalSprites; + globalSprites.load("global.icn"); + + if (pt.x < 8 && map.mazeData()._surroundingMazes._west == 0) { + arrowPt.x = pt.x * 10 + 4; + } else if (pt.x > 23) { + arrowPt.x = pt.x * 10 + 100; + pt.x = 23; + } else if (pt.x > 8 && map.mazeData()._surroundingMazes._east == 0) { + arrowPt.x = 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 - 24)) << 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; + } + + screen._windows[5].open(); + MazeData &mazeData = map.mazeDataCurrent(); + bool drawFlag = true; + int v; + + events.updateGameCounter(); + do { + if (drawFlag) + intf.draw3d(false); + screen._windows[5].writeString("\n"); + + if (map._isOutdoors) { + // Draw outdoors map + for (int yCtr = 0, yDiff = yDiffStart - 1, yp = 38; yCtr < 16; + ++yCtr, --yDiff, yp += 8) { + for (int xp = 80, xDiff = xDiffStart + 1; xp < 240; xp += 10, ++xDiff) { + v = map.mazeLookup(Common::Point(xDiff, yDiff), 0); + + if (map._currentSteppedOn) { + map._tileSprites.draw(screen, map.mazeDataCurrent()._surfaceTypes[v], + Common::Point(xp, yp)); + } + } + } + + for (int yCtr = 0, yDiff = yDiffStart - 1, yp = 38; yCtr < 16; + ++yCtr, --yDiff, yp += 8) { + for (int xp = 80, xDiff = xDiffStart + 1; xp < 240; xp += 10, ++xDiff) { + v = map.mazeLookup(Common::Point(xDiff, yDiff), 4); + int wallType = map.mazeDataCurrent()._wallTypes[v]; + + if (wallType && map._currentSteppedOn) + map._tileSprites.draw(screen, wallType, Common::Point(xp, yp)); + } + } + + for (int yCtr = 0, yDiff = yDiffStart - 1, yp = 38; yCtr < 16; + ++yCtr, --yDiff, yp += 8) { + for (int xCtr = 0, xp = 80, xDiff = xDiffStart + 1; xp < 240; + ++xCtr, ++xDiff, xp += 10) { + if (xCtr == (arrowPt.x / 10) && yCtr == (14 - (arrowPt.y)) && frameEndFlag) + map._tileSprites.draw(screen, party._mazeDirection + 1, + Common::Point(arrowPt.x + 81, arrowPt.y + 29)); + + v = map.mazeLookup(Common::Point(xDiff, yDiff), 12); + int frame; + switch (v) { + case SURFTYPE_WATER: + frame = 18; + break; + case SURFTYPE_DIRT: + frame = 34; + break; + case SURFTYPE_GRASS: + frame = 22; + break; + case SURFTYPE_SNOW: + case SURFTYPE_SEWER: + frame = 16; + break; + case SURFTYPE_SWAMP: + case SURFTYPE_ROAD: + frame = 2; + case SURFTYPE_LAVA: + frame = 30; + break; + case SURFTYPE_DESERT: + frame = 32; + break; + case SURFTYPE_DWATER: + frame = 20; + break; + case SURFTYPE_TFLR: + frame = 28; + break; + case SURFTYPE_SKY: + frame = 14; + break; + case SURFTYPE_CROAD: + frame = frame2 + 4; + break; + case SURFTYPE_CLOUD: + frame = 24; + break; + case SURFTYPE_SCORCH: + frame = 26; + break; + default: + frame = -1; + break; + } + + if (frame != -1 && map._currentSteppedOn) + map._tileSprites.draw(screen, frame, Common::Point(xp, yp)); + + v = map.mazeLookup(Common::Point(xDiff, yDiff), 0); + switch (v) { + case SURFTYPE_WATER: + frame = 19; + break; + case SURFTYPE_DIRT: + frame = 35; + break; + case SURFTYPE_GRASS: + frame = 23; + break; + case SURFTYPE_SNOW: + case SURFTYPE_SEWER: + frame = 17; + break; + case SURFTYPE_SWAMP: + case SURFTYPE_ROAD: + frame = 3; + break; + case SURFTYPE_LAVA: + frame = 31; + break; + case SURFTYPE_DESERT: + frame = 33; + break; + case SURFTYPE_DWATER: + frame = 21; + break; + case SURFTYPE_TFLR: + frame = 29; + break; + case SURFTYPE_SKY: + frame = 15; + break; + case SURFTYPE_CROAD: + frame = frame2 + 5; + break; + case SURFTYPE_CLOUD: + frame = 25; + break; + case SURFTYPE_SCORCH: + frame = 27; + break; + default: + frame = -1; + break; + } + + if (frame != -1 && map._currentSteppedOn) + map._tileSprites.draw(screen, frame, Common::Point(xp, yp)); + } + } + + for (int yCtr = 0, yDiff = yDiffStart - 1, yp = 38; yCtr < 16; + ++yCtr, --yDiff, yp += 8) { + for (int xp = 80, xDiff = xDiffStart + 1; xp < 240; xp += 10, ++xDiff) { + v = map.mazeLookup(Common::Point(xDiff, yDiff), 0, 0xffff); + + if (v != INVALID_CELL && map._currentSteppedOn) + map._tileSprites.draw(screen, 1, Common::Point(xp, yp)); + } + } + } else { + // Draw indoors map + frame2 = (frame2 + 2) % 8; + + for (int yCtr = 0, yDiff = yDiffStart - 1, yp = 38; yCtr < 16; + ++yCtr, --yDiff, yp += 8) { + for (int xp = 80, xDiff = xDiffStart + 1; xp < 240; xp += 10, ++xDiff) { + v = map.mazeLookup(Common::Point(xDiff, yDiff), 0, 0xffff); + + if (v != INVALID_CELL && map._currentSteppedOn) + map._tileSprites.draw(screen, 0, Common::Point(xp, yp)); + } + } + + for (int yDiff = yDiffStart - 1, yp = 38; yp < 171; --yDiff, yp += 8) { + v = map.mazeLookup(Common::Point(pt.x - 8, yDiff), 0, 0xffff); + + if (v != INVALID_CELL && map._currentSurfaceId != 0 && map._currentSteppedOn) + map._tileSprites.draw(screen, 36 + map.mazeData()._surfaceTypes[v], + Common::Point(75, yp)); + } + + 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(screen, 36 + map.mazeData()._surfaceTypes[v], + Common::Point(75, 35)); + + for (int xp = 85, xDiff = xDiffStart + 1; xp < 245; xp += 10, ++xDiff) { + v = map.mazeLookup(Common::Point(xDiff, pt.y + 8), 0, 0xffff); + + if (v != INVALID_CELL && map._currentSurfaceId != 0 && map._currentSteppedOn) + map._tileSprites.draw(screen, 36 + map.mazeData()._surfaceTypes[v], + Common::Point(xp, 35)); + } + + for (int xp = 80, yp = 158, xDiff = pt.x - 7, yDiff = pt.y - 8; xp < 250; + xp += 10, yp += 8, ++xDiff, ++yDiff) { + v = map.mazeLookup(Common::Point(pt.x - 8, yDiff), 12); + + int frame; + switch (v) { + case SURFTYPE_WATER: + frame = 18; + break; + case SURFTYPE_GRASS: + frame = 24; + break; + case SURFTYPE_SNOW: + case SURFTYPE_SEWER: + frame = 16; + break; + case SURFTYPE_SWAMP: + case SURFTYPE_ROAD: + frame = 2; + break; + case SURFTYPE_LAVA: + frame = 30; + break; + case SURFTYPE_DESERT: + frame = 32; + break; + case SURFTYPE_DWATER: + frame = 20; + break; + case SURFTYPE_TFLR: + frame = 28; + break; + case SURFTYPE_SKY: + frame = 14; + break; + case SURFTYPE_CROAD: + frame = frame2 + 4; + break; + case SURFTYPE_CLOUD: + frame = 24; + break; + case SURFTYPE_SCORCH: + frame = 26; + break; + default: + frame = -1; + break; + } + + if (frame != -1 && map._currentSteppedOn) + map._tileSprites.draw(screen, frame, Common::Point(70, yp)); + + v = map.mazeLookup(Common::Point(xDiff, pt.y + 8), 0); + + switch (v) { + case SURFTYPE_WATER: + frame = 19; + break; + case SURFTYPE_DIRT: + frame = 35; + break; + case SURFTYPE_GRASS: + frame = 23; + break; + case SURFTYPE_SNOW: + case SURFTYPE_SEWER: + frame = 17; + break; + case SURFTYPE_SWAMP: + case SURFTYPE_ROAD: + frame = 3; + break; + case SURFTYPE_LAVA: + frame = 31; + break; + case SURFTYPE_DESERT: + frame = 33; + break; + case SURFTYPE_DWATER: + frame = 21; + break; + case SURFTYPE_TFLR: + frame = 29; + break; + case SURFTYPE_SKY: + frame = 15; + break; + case SURFTYPE_CROAD: + frame = frame2 + 5; + break; + case SURFTYPE_CLOUD: + frame = 25; + break; + case SURFTYPE_SCORCH: + frame = 27; + break; + default: + frame = -1; + break; + } + + if (frame != -1 && map._currentSteppedOn) + map._tileSprites.draw(screen, frame, Common::Point(xp, 30)); + } + + for (int yCtr = 0, yDiff = yDiffStart - 1, yp = 38; yCtr < 16; + ++yCtr, --yDiff, yp += 8) { + for (int xp = 80, xDiff = xDiffStart + 1; xp < 240; xp += 10, ++xDiff) { + v = map.mazeLookup(Common::Point(xDiff, yDiff), 0, 0xffff); + + if (v != INVALID_CELL && map._currentSteppedOn) + map._tileSprites.draw(screen, 0, Common::Point(xp, yp)); + } + } + } + + screen._windows[5].frame(); + if (!map._isOutdoors) { + map._tileSprites.draw(screen, 52, Common::Point(76, 30)); + } else if (frameEndFlag) { + globalSprites.draw(screen, 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 = true; + events.updateGameCounter(); + } + + screen._windows[5].writeString(Common::String::format(MAP_TEXT, + map._mazeName.c_str(), party._mazePosition.x, + party._mazePosition.y, DIRECTION_TEXT[party._mazeDirection])); + screen._windows[5].update(); + screen._windows[3].update(); + + events.pollEvents(); + } while (!_vm->shouldQuit() && !events.isKeyMousePressed()); + + events.clearEvents(); + screen._windows[5].close(); +} + +} // End of namespace Xeen diff --git a/engines/xeen/dialogs_automap.h b/engines/xeen/dialogs_automap.h new file mode 100644 index 0000000000..f20f9b0104 --- /dev/null +++ b/engines/xeen/dialogs_automap.h @@ -0,0 +1,45 @@ +/* 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. + * + */ + +#ifndef XEEN_DIALOGS_AUTOMAP_H +#define XEEN_DIALOGS_AUTOMAP_H + +#include "xeen/dialogs.h" + +namespace Xeen { + +class XeenEngine; + +class AutoMapDialog: public ButtonContainer { +private: + XeenEngine *_vm; + + AutoMapDialog(XeenEngine *vm) : ButtonContainer(), _vm(vm) {} + + void execute(); +public: + static void show(XeenEngine *vm); +}; + +} // End of namespace Xeen + +#endif /* XEEN_DIALOGS_AUTOMAP_H */ diff --git a/engines/xeen/interface.cpp b/engines/xeen/interface.cpp index ece8ff3054..d3fe234017 100644 --- a/engines/xeen/interface.cpp +++ b/engines/xeen/interface.cpp @@ -22,6 +22,7 @@ #include "xeen/interface.h" #include "xeen/dialogs_error.h" +#include "xeen/dialogs_automap.h" #include "xeen/resources.h" #include "xeen/xeen.h" @@ -672,6 +673,12 @@ void Interface::perform() { // Toggle minimap party._automapOn = !party._automapOn; break; + + case Common::KEYCODE_m: + // Show map dialog + AutoMapDialog::show(_vm); + break; + default: break; } diff --git a/engines/xeen/interface_map.cpp b/engines/xeen/interface_map.cpp index dcae6cc406..46f52729e7 100644 --- a/engines/xeen/interface_map.cpp +++ b/engines/xeen/interface_map.cpp @@ -4580,7 +4580,7 @@ void InterfaceMap::assembleBorder() { // Draw direction character if direction sense is active if (_vm->_party->checkSkill(DIRECTION_SENSE) && !_vm->_noDirectionSense) { - const char *dirText = DIRECTION_TEXT[_vm->_party->_mazeDirection]; + const char *dirText = DIRECTION_TEXT_UPPER[_vm->_party->_mazeDirection]; Common::String msg = Common::String::format( "\002""08\003""c\013""139\011""116%c\014""d\001", *dirText); screen._windows[0].writeString(msg); diff --git a/engines/xeen/map.h b/engines/xeen/map.h index 7d268efb8e..abc36411ee 100644 --- a/engines/xeen/map.h +++ b/engines/xeen/map.h @@ -347,7 +347,6 @@ class Map { private: XeenEngine *_vm; MazeData _mazeData[9]; - Common::String _mazeName; SpriteResource _wallPicSprites; int _sideTownPortal; int _sidePictures; @@ -357,6 +356,7 @@ private: void loadEvents(int mapId); public: + Common::String _mazeName; bool _isOutdoors; MonsterObjectData _mobData; MonsterData _monsterData; diff --git a/engines/xeen/module.mk b/engines/xeen/module.mk index be951239d3..50a8947afa 100644 --- a/engines/xeen/module.mk +++ b/engines/xeen/module.mk @@ -8,6 +8,8 @@ MODULE_OBJS := \ debugger.o \ detection.o \ dialogs.o \ + automap.o \ + dialogs_automap.o \ dialogs_confirm.o \ dialogs_error.o \ dialogs_options.o \ diff --git a/engines/xeen/resources.cpp b/engines/xeen/resources.cpp index ed304dc9e1..05eff2d580 100644 --- a/engines/xeen/resources.cpp +++ b/engines/xeen/resources.cpp @@ -271,7 +271,9 @@ const byte TEXT_COLORS[40][4] = { { 0x00, 0xDB, 0xDB, 0xDB }, }; -const char *const DIRECTION_TEXT[4] = { "NORTH", "EAST", "SOUTH", "WEST" }; +const char *const DIRECTION_TEXT_UPPER[4] = { "NORTH", "EAST", "SOUTH", "WEST" }; + +const char *const DIRECTION_TEXT[4] = { "North", "East", "South", "West" }; const char *const RACE_NAMES[5] = { "Human", "Elf", "Dwarf", "Gnome", "H-Orc" }; @@ -815,15 +817,19 @@ const char *const SPELLS_PURCHASE = "\xC""09%s\xC""d for %u?"; const char *const SPELL_DETAILS = -"\xD\x2\x3""c\xB""122\x9""013\xC""37C\xC""dast" -"\x9""040\xC""37N\xC""dew\x9""067ESC\x1""000\xB""000\x3""cCast Spell\n" -"\n" -"%s\x3l\n" -"\n" -"Spell Ready:\x3""c\n" -"\n" -"\xC""09%s\xC""d\x2\x3l\n" -"\xB""082Cost\x3r\x9""000%u/%u\x3l\n" -"Cur SP\x3r\x9""000%u\x1"; + "\xD\x2\x3""c\xB""122\x9""013\xC""37C\xC""dast" + "\x9""040\xC""37N\xC""dew\x9""067ESC\x1""000\xB""000\x3""cCast Spell\n" + "\n" + "%s\x3l\n" + "\n" + "Spell Ready:\x3""c\n" + "\n" + "\xC""09%s\xC""d\x2\x3l\n" + "\xB""082Cost\x3r\x9""000%u/%u\x3l\n" + "Cur SP\x3r\x9""000%u\x1"; + +const char *const MAP_TEXT = + "\x3""c\xB""000\x9""000%s\x3l\xB""139" + "\x9""000X = %d\x3r\x9""000Y = %d\x3""c\x9""000%s"; } // End of namespace Xeen diff --git a/engines/xeen/resources.h b/engines/xeen/resources.h index 37afb2cc76..70fdcf65b1 100644 --- a/engines/xeen/resources.h +++ b/engines/xeen/resources.h @@ -56,6 +56,8 @@ extern const byte SYMBOLS[20][64]; extern const byte TEXT_COLORS[40][4]; +extern const char *const DIRECTION_TEXT_UPPER[4]; + extern const char *const DIRECTION_TEXT[4]; extern const char *const RACE_NAMES[5]; @@ -244,6 +246,8 @@ extern const char *const SPELLS_PURCHASE; extern const char *const SPELL_DETAILS; +extern const char *const MAP_TEXT; + } // End of namespace Xeen #endif /* XEEN_RESOURCES_H */ -- cgit v1.2.3