aboutsummaryrefslogtreecommitdiff
path: root/engines/sherlock/map.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sherlock/map.cpp')
-rw-r--r--engines/sherlock/map.cpp529
1 files changed, 4 insertions, 525 deletions
diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp
index 3f9c9f5e75..fbccaf244f 100644
--- a/engines/sherlock/map.cpp
+++ b/engines/sherlock/map.cpp
@@ -28,31 +28,6 @@
namespace Sherlock {
-MapPaths::MapPaths() {
- _numLocations = 0;
-}
-
-void MapPaths::load(int numLocations, Common::SeekableReadStream &s) {
- _numLocations = numLocations;
- _paths.resize(_numLocations * _numLocations);
-
- for (int idx = 0; idx < (numLocations * numLocations); ++idx) {
- Common::Array<byte> &path = _paths[idx];
- int v;
-
- do {
- v = s.readByte();
- path.push_back(v);
- } while (v && v < 254);
- }
-}
-
-const byte *MapPaths::getPath(int srcLocation, int destLocation) {
- return &_paths[srcLocation * _numLocations + destLocation][0];
-}
-
-/*----------------------------------------------------------------*/
-
Map *Map::init(SherlockEngine *vm) {
if (vm->getGameID() == GType_SerratedScalpel)
return new Scalpel::ScalpelMap(vm);
@@ -60,506 +35,9 @@ Map *Map::init(SherlockEngine *vm) {
return new Tattoo::TattooMap(vm);
}
-Map::Map(SherlockEngine *vm): _vm(vm), _topLine(g_system->getWidth(), 12, vm->getPlatform()) {
- _active = false;
- _mapCursors = nullptr;
- _shapes = nullptr;
- _iconShapes = nullptr;
- _point = 0;
- _placesShown = false;
- _cursorIndex = -1;
- _drawMap = false;
- _overPos = Point32(130 * FIXED_INT_MULTIPLIER, 126 * FIXED_INT_MULTIPLIER);
- _charPoint = 0;
- _oldCharPoint = 0;
- _frameChangeFlag = false;
-
- // Initialise the initial walk sequence set
- _walkSequences.resize(MAX_HOLMES_SEQUENCE);
- for (int idx = 0; idx < MAX_HOLMES_SEQUENCE; ++idx) {
- _walkSequences[idx]._sequences.resize(MAX_FRAME);
- Common::fill(&_walkSequences[idx]._sequences[0], &_walkSequences[idx]._sequences[0] + MAX_FRAME, 0);
- }
-
- if (!_vm->isDemo())
- loadData();
-}
-
-void Map::loadPoints(int count, const int *xList, const int *yList, const int *transList) {
- for (int idx = 0; idx < count; ++idx, ++xList, ++yList, ++transList) {
- _points.push_back(MapEntry(*xList, *yList, *transList));
- }
-}
-
-void Map::loadSequences(int count, const byte *seq) {
- for (int idx = 0; idx < count; ++idx, seq += MAX_FRAME)
- Common::copy(seq, seq + MAX_FRAME, &_walkSequences[idx]._sequences[0]);
-}
-
-void Map::loadData() {
- // TODO: Remove this
- if (_vm->getGameID() == GType_RoseTattoo)
- return;
-
- // Load the list of location names
- Common::SeekableReadStream *txtStream = _vm->_res->load(
- _vm->getGameID() == GType_SerratedScalpel ? "chess.txt" : "map.txt");
-
- int streamSize = txtStream->size();
- while (txtStream->pos() < streamSize) {
- Common::String line;
- char c;
- while ((c = txtStream->readByte()) != '\0')
- line += c;
-
- _locationNames.push_back(line);
- }
-
- delete txtStream;
-
- // Load the path data
- Common::SeekableReadStream *pathStream = _vm->_res->load("chess.pth");
-
- // Get routes between different locations on the map
- _paths.load(31, *pathStream);
-
- // Load in the co-ordinates that the paths refer to
- _pathPoints.resize(208);
- for (uint idx = 0; idx < _pathPoints.size(); ++idx) {
- _pathPoints[idx].x = pathStream->readSint16LE();
- _pathPoints[idx].y = pathStream->readSint16LE();
- }
-
- delete pathStream;
-}
-
-int Map::show() {
- Events &events = *_vm->_events;
- People &people = *_vm->_people;
- Screen &screen = *_vm->_screen;
- bool changed = false, exitFlag = false;
- _active = true;
-
- // Set font and custom cursor for the map
- int oldFont = screen.fontNumber();
- screen.setFont(0);
-
- // Initial screen clear
- screen._backBuffer1.clear();
- screen.clear();
-
- // Load the entire map
- ImageFile bigMap("bigmap.vgs");
- screen.setPalette(bigMap._palette);
-
- // Load need sprites
- setupSprites();
-
- screen._backBuffer1.blitFrom(bigMap[0], Common::Point(-_bigPos.x, -_bigPos.y));
- screen._backBuffer1.blitFrom(bigMap[1], Common::Point(-_bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y));
- screen._backBuffer1.blitFrom(bigMap[2], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, -_bigPos.y));
- screen._backBuffer1.blitFrom(bigMap[3], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y));
-
- _drawMap = true;
- _charPoint = -1;
- _point = -1;
- people[AL]._position = _lDrawnPos = _overPos;
-
- // Show place icons
- showPlaces();
- saveTopLine();
- _placesShown = true;
-
- // Keep looping until either a location is picked, or the game is ended
- while (!_vm->shouldQuit() && !exitFlag) {
- events.pollEventsAndWait();
- events.setButtonState();
-
- // Keyboard handling
- if (events.kbHit()) {
- Common::KeyState keyState = events.getKey();
-
- if (keyState.keycode == Common::KEYCODE_RETURN || keyState.keycode == Common::KEYCODE_SPACE) {
- // Both space and enter simulate a mouse release
- events._pressed = false;
- events._released = true;
- events._oldButtons = 0;
- }
- }
-
- // Ignore scrolling attempts until the screen is drawn
- if (!_drawMap) {
- Common::Point pt = events.mousePos();
-
- // Check for vertical map scrolling
- if ((pt.y > (SHERLOCK_SCREEN_HEIGHT - 10) && _bigPos.y < 200) || (pt.y < 10 && _bigPos.y > 0)) {
- if (pt.y > (SHERLOCK_SCREEN_HEIGHT - 10))
- _bigPos.y += 10;
- else
- _bigPos.y -= 10;
-
- changed = true;
- }
-
- // Check for horizontal map scrolling
- if ((pt.x > (SHERLOCK_SCREEN_WIDTH - 10) && _bigPos.x < 315) || (pt.x < 10 && _bigPos.x > 0)) {
- if (pt.x > (SHERLOCK_SCREEN_WIDTH - 10))
- _bigPos.x += 15;
- else
- _bigPos.x -= 15;
-
- changed = true;
- }
- }
-
- if (changed) {
- // Map has scrolled, so redraw new map view
- changed = false;
-
- screen._backBuffer1.blitFrom(bigMap[0], Common::Point(-_bigPos.x, -_bigPos.y));
- screen._backBuffer1.blitFrom(bigMap[1], Common::Point(-_bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y));
- screen._backBuffer1.blitFrom(bigMap[2], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, -_bigPos.y));
- screen._backBuffer1.blitFrom(bigMap[3], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y));
-
- showPlaces();
- _placesShown = false;
-
- saveTopLine();
- _savedPos.x = -1;
- updateMap(true);
- } else if (!_drawMap) {
- if (!_placesShown) {
- showPlaces();
- _placesShown = true;
- }
-
- if (_cursorIndex == 0) {
- Common::Point pt = events.mousePos();
- highlightIcon(Common::Point(pt.x - 4 + _bigPos.x, pt.y + _bigPos.y));
- }
- updateMap(false);
- }
-
- if ((events._released || events._rightReleased) && _point != -1) {
- if (people[AL]._walkCount == 0) {
- people._walkDest = _points[_point] + Common::Point(4, 9);
- _charPoint = _point;
-
- // Start walking to selected location
- walkTheStreets();
-
- // Show wait cursor
- _cursorIndex = 1;
- events.setCursor((*_mapCursors)[_cursorIndex]._frame);
- }
- }
-
- // Check if a scene has beeen selected and we've finished "moving" to it
- if (people[AL]._walkCount == 0) {
- if (_charPoint >= 1 && _charPoint < (int)_points.size())
- exitFlag = true;
- }
-
- if (_drawMap) {
- _drawMap = false;
-
- if (screen._fadeStyle)
- screen.randomTransition();
- else
- screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
- }
-
- // Wait for a frame
- events.wait(1);
- }
-
- freeSprites();
- _overPos = people[AL]._position;
-
- // Reset font
- screen.setFont(oldFont);
-
- _active = false;
- return _charPoint;
-}
-
-void Map::setupSprites() {
- Events &events = *_vm->_events;
- People &people = *_vm->_people;
- Scene &scene = *_vm->_scene;
- _savedPos.x = -1;
-
- _mapCursors = new ImageFile("omouse.vgs");
- _cursorIndex = 0;
- events.setCursor((*_mapCursors)[_cursorIndex]._frame);
-
- _shapes = new ImageFile("mapicon.vgs");
- _iconShapes = new ImageFile("overicon.vgs");
- _iconSave.create((*_shapes)[4]._width, (*_shapes)[4]._height, _vm->getPlatform());
- Person &p = people[AL];
- p._description = " ";
- p._type = CHARACTER;
- p._position = Common::Point(12400, 5000);
- p._sequenceNumber = 0;
- p._images = _shapes;
- p._imageFrame = nullptr;
- p._frameNumber = 0;
- p._delta = Common::Point(0, 0);
- p._oldSize = Common::Point(0, 0);
- p._oldSize = Common::Point(0, 0);
- p._misc = 0;
- p._walkCount = 0;
- p._allow = 0;
- p._noShapeSize = Common::Point(0, 0);
- p._goto = Common::Point(28000, 15000);
- p._status = 0;
- p._walkSequences = _walkSequences;
- p.setImageFrame();
- scene._bgShapes.clear();
-}
-
-void Map::freeSprites() {
- delete _mapCursors;
- delete _shapes;
- delete _iconShapes;
- _iconSave.free();
-}
-
-void Map::showPlaces() {
- Screen &screen = *_vm->_screen;
-
- for (uint idx = 0; idx < _points.size(); ++idx) {
- const MapEntry &pt = _points[idx];
-
- if (pt.x != 0 && pt.y != 0) {
- if (pt.x >= _bigPos.x && (pt.x - _bigPos.x) < SHERLOCK_SCREEN_WIDTH
- && pt.y >= _bigPos.y && (pt.y - _bigPos.y) < SHERLOCK_SCREEN_HEIGHT) {
- if (_vm->readFlags(idx)) {
- screen._backBuffer1.transBlitFrom((*_iconShapes)[pt._translate],
- Common::Point(pt.x - _bigPos.x - 6, pt.y - _bigPos.y - 12));
- }
- }
- }
- }
-}
-
-void Map::saveTopLine() {
- _topLine.blitFrom(_vm->_screen->_backBuffer1, Common::Point(0, 0), Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, 12));
-}
-
-void Map::eraseTopLine() {
- Screen &screen = *_vm->_screen;
- screen._backBuffer1.blitFrom(_topLine, Common::Point(0, 0));
- screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, _topLine.h());
-}
-
-void Map::showPlaceName(int idx, bool highlighted) {
- People &people = *_vm->_people;
- Screen &screen = *_vm->_screen;
-
- Common::String name = _locationNames[idx];
- int width = screen.stringWidth(name);
-
- if (!_cursorIndex) {
- saveIcon(people[AL]._imageFrame, _lDrawnPos);
-
- bool flipped = people[AL]._sequenceNumber == MAP_DOWNLEFT || people[AL]._sequenceNumber == MAP_LEFT
- || people[AL]._sequenceNumber == MAP_UPLEFT;
- screen._backBuffer1.transBlitFrom(*people[AL]._imageFrame, _lDrawnPos, flipped);
- }
-
- if (highlighted) {
- int xp = (SHERLOCK_SCREEN_WIDTH - screen.stringWidth(name)) / 2;
- screen.gPrint(Common::Point(xp + 2, 2), 0, "%s", name.c_str());
- screen.gPrint(Common::Point(xp + 1, 1), 0, "%s", name.c_str());
- screen.gPrint(Common::Point(xp, 0), 12, "%s", name.c_str());
-
- screen.slamArea(xp, 0, width + 2, 15);
- }
-}
-
-void Map::updateMap(bool flushScreen) {
- Events &events = *_vm->_events;
- People &people = *_vm->_people;
- Screen &screen = *_vm->_screen;
- Common::Point osPos = _savedPos;
- Common::Point osSize = _savedSize;
- Common::Point hPos;
-
- if (_cursorIndex >= 1) {
- if (++_cursorIndex > (1 + 8))
- _cursorIndex = 1;
-
- events.setCursor((*_mapCursors)[(_cursorIndex + 1) / 2]._frame);
- }
-
- if (!_drawMap && !flushScreen)
- restoreIcon();
- else
- _savedPos.x = -1;
-
- people[AL].adjustSprite();
-
- _lDrawnPos.x = hPos.x = people[AL]._position.x / FIXED_INT_MULTIPLIER - _bigPos.x;
- _lDrawnPos.y = hPos.y = people[AL]._position.y / FIXED_INT_MULTIPLIER - people[AL].frameHeight() - _bigPos.y;
-
- // Draw the person icon
- saveIcon(people[AL]._imageFrame, hPos);
- if (people[AL]._sequenceNumber == MAP_DOWNLEFT || people[AL]._sequenceNumber == MAP_LEFT
- || people[AL]._sequenceNumber == MAP_UPLEFT)
- screen._backBuffer1.transBlitFrom(*people[AL]._imageFrame, hPos, true);
- else
- screen._backBuffer1.transBlitFrom(*people[AL]._imageFrame, hPos, false);
-
- if (flushScreen) {
- screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
- } else if (!_drawMap) {
- if (hPos.x > 0 && hPos.y >= 0 && hPos.x < SHERLOCK_SCREEN_WIDTH && hPos.y < SHERLOCK_SCREEN_HEIGHT)
- screen.flushImage(people[AL]._imageFrame, Common::Point(people[AL]._position.x / FIXED_INT_MULTIPLIER - _bigPos.x,
- people[AL]._position.y / FIXED_INT_MULTIPLIER - people[AL].frameHeight() - _bigPos.y),
- &people[AL]._oldPosition.x, &people[AL]._oldPosition.y, &people[AL]._oldSize.x, &people[AL]._oldSize.y);
-
- if (osPos.x != -1)
- screen.slamArea(osPos.x, osPos.y, osSize.x, osSize.y);
- }
-}
-
-void Map::walkTheStreets() {
- People &people = *_vm->_people;
- Common::Array<Common::Point> tempPath;
-
- // Get indexes into the path lists for the start and destination scenes
- int start = _points[_oldCharPoint]._translate;
- int dest = _points[_charPoint]._translate;
-
- // Get pointer to start of path
- const byte *path = _paths.getPath(start, dest);
-
- // Add in destination position
- people._walkTo.clear();
- Common::Point destPos = people._walkDest;
-
- // Check for any intermediate points between the two locations
- if (path[0] || _charPoint > 50 || _oldCharPoint > 50) {
- people[AL]._sequenceNumber = -1;
-
- if (_charPoint == 51 || _oldCharPoint == 51) {
- people.setWalking();
- } else {
- bool reversePath = false;
-
- // Check for moving the path backwards or forwards
- if (path[0] == 255) {
- reversePath = true;
- SWAP(start, dest);
- path = _paths.getPath(start, dest);
- }
-
- do {
- int idx = *path++;
- tempPath.push_back(_pathPoints[idx - 1] + Common::Point(4, 4));
- } while (*path != 254);
-
- // Load up the path to use
- people._walkTo.clear();
-
- if (reversePath) {
- for (int idx = (int)tempPath.size() - 1; idx >= 0; --idx)
- people._walkTo.push(tempPath[idx]);
- } else {
- for (int idx = 0; idx < (int)tempPath.size(); ++idx)
- people._walkTo.push(tempPath[idx]);
- }
-
- people._walkDest = people._walkTo.pop() + Common::Point(12, 6);
- people.setWalking();
- }
- } else {
- people[AL]._walkCount = 0;
- }
-
- // Store the final destination icon position
- people._walkTo.push(destPos);
-}
-
-void Map::saveIcon(ImageFrame *src, const Common::Point &pt) {
- Screen &screen = *_vm->_screen;
- Common::Point size(src->_width, src->_height);
- Common::Point pos = pt;
-
- if (pos.x < 0) {
- size.x += pos.x;
- pos.x = 0;
- }
-
- if (pos.y < 0) {
- size.y += pos.y;
- pos.y = 0;
- }
-
- if ((pos.x + size.x) > SHERLOCK_SCREEN_WIDTH)
- size.x -= (pos.x + size.x) - SHERLOCK_SCREEN_WIDTH;
-
- if ((pos.y + size.y) > SHERLOCK_SCREEN_HEIGHT)
- size.y -= (pos.y + size.y) - SHERLOCK_SCREEN_HEIGHT;
-
- if (size.x < 1 || size.y < 1 || pos.x >= SHERLOCK_SCREEN_WIDTH || pos.y >= SHERLOCK_SCREEN_HEIGHT || _drawMap) {
- // Flag as the area not needing to be saved
- _savedPos.x = -1;
- return;
- }
-
- assert(size.x <= _iconSave.w() && size.y <= _iconSave.h());
- _iconSave.blitFrom(screen._backBuffer1, Common::Point(0, 0),
- Common::Rect(pos.x, pos.y, pos.x + size.x, pos.y + size.y));
- _savedPos = pos;
- _savedSize = size;
-}
-
-void Map::restoreIcon() {
- Screen &screen = *_vm->_screen;
-
- if (_savedPos.x >= 0 && _savedPos.y >= 0 && _savedPos.x <= SHERLOCK_SCREEN_WIDTH
- && _savedPos.y < SHERLOCK_SCREEN_HEIGHT)
- screen._backBuffer1.blitFrom(_iconSave, _savedPos, Common::Rect(0, 0, _savedSize.x, _savedSize.y));
-}
-
-void Map::highlightIcon(const Common::Point &pt) {
- int oldPoint = _point;
-
- // Iterate through the icon list
- bool done = false;
- for (int idx = 0; idx < (int)_points.size(); ++idx) {
- const MapEntry &entry = _points[idx];
-
- // Check whether the mouse is over a given icon
- if (entry.x != 0 && entry.y != 0) {
- if (Common::Rect(entry.x - 8, entry.y - 8, entry.x + 9, entry.y + 9).contains(pt)) {
- done = true;
-
- if (_point != idx && _vm->readFlags(idx)) {
- // Changed to a new valid (visible) location
- eraseTopLine();
- showPlaceName(idx, true);
- _point = idx;
- }
- }
- }
- }
-
- if (!done) {
- // No icon was highlighted
- if (_point != -1) {
- // No longer highlighting previously highlighted icon, so erase it
- showPlaceName(_point, false);
- eraseTopLine();
- }
-
- _point = -1;
- } else if (oldPoint != -1 && oldPoint != _point) {
- showPlaceName(oldPoint, false);
- eraseTopLine();
- }
+Map::Map(SherlockEngine *vm) : _vm(vm) {
+ _charPoint = _oldCharPoint = 0;
+ _active = _frameChangeFlag = false;
}
void Map::synchronize(Serializer &s) {
@@ -570,4 +48,5 @@ void Map::synchronize(Serializer &s) {
s.syncAsSint16LE(_oldCharPoint);
}
+
} // End of namespace Sherlock