Initial commit
This commit is contained in:
471
engines/mm/xeen/dialogs/dialogs_map.cpp
Normal file
471
engines/mm/xeen/dialogs/dialogs_map.cpp
Normal file
@@ -0,0 +1,471 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mm/xeen/dialogs/dialogs_map.h"
|
||||
#include "mm/xeen/resources.h"
|
||||
#include "mm/xeen/xeen.h"
|
||||
|
||||
namespace MM {
|
||||
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;
|
||||
|
||||
#ifdef USE_TTS
|
||||
_vm->stopTextToSpeech();
|
||||
#endif
|
||||
bool ttsVoiceText = 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]), ttsVoiceText);
|
||||
ttsVoiceText = false;
|
||||
windows[5].update();
|
||||
windows[3].update();
|
||||
|
||||
events.ipause5(2);
|
||||
drawFlag = false;
|
||||
} while (!_vm->shouldExit() && !events.isKeyMousePressed());
|
||||
|
||||
#ifdef USE_TTS
|
||||
_vm->stopTextToSpeech();
|
||||
#endif
|
||||
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
|
||||
} // End of namespace MM
|
||||
Reference in New Issue
Block a user