scummvm/engines/mm/mm1/maps/map.cpp
NoSFeRaTU 7c8ed5b574 MM: MM1: Support for non-vanilla version
There is version of MM1 in the wild which have some differences with floppy version of vanilla. Support resources from it too.
2024-02-17 13:16:51 -10:00

148 lines
3.9 KiB
C++

/* 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 "common/file.h"
#include "mm/mm1/maps/map.h"
#include "mm/mm1/maps/maps.h"
#include "mm/mm1/globals.h"
#include "mm/mm1/events.h"
namespace MM {
namespace MM1 {
namespace Maps {
Map::Map(uint index, const Common::String &name, uint16 id,
byte defaultSection, const char *desc) :
_mapIndex(index), _name(name), _id(id), _defaultSection(defaultSection) {
_description = desc ? Common::String(desc) : _name;
_description.setChar(toupper(_description[0]), 0);
if (_description.hasPrefix("Area")) {
_description.setChar(toupper(_description[4]), 4);
_description.insertChar(' ', 4);
}
Common::fill((byte *)&_walls[0], (byte *)&_walls[MAP_SIZE], 0);
Common::fill(&_states[0], (byte *)&_states[MAP_SIZE], 0);
Common::fill(&_visited[0], &_visited[MAP_SIZE], 0);
}
void Map::load() {
loadMazeData();
loadOverlay();
g_globals->_heardRumor = false;
}
void Map::loadMazeData() {
Common::File f;
if (!f.open("mazedata.dta"))
error("Could not open mazedata.dta");
f.seek(512 * _mapIndex);
f.read((byte *)_walls, MAP_SIZE);
f.read(_states, MAP_SIZE);
f.close();
}
void Map::loadOverlay() {
Common::File f;
if (!f.open(Common::Path(Common::String::format("%s.ovr", _name.c_str()))))
error("Could not open %s.ovr overlay", _name.c_str());
int magicId = f.readUint16LE();
int codePtr = f.readUint16LE();
int codeSize = f.readUint16LE();
f.readUint16LE(); // dataPtr
int dataSize = f.readUint16LE();
f.readUint16LE(); // extras size
f.readUint16LE(); // code entry-point
if (magicId != 0xF2 || (codePtr != 0xF48F && codePtr != 0xF47C))
error("Invalid map overlay header");
// Skip over code segment, since each map's
// code is going to be reimplemented in C++
f.skip(codeSize);
// Read in the data segment
_data.resize(dataSize);
f.read(&_data[0], dataSize);
}
bool Map::checkPartyDead() {
return g_globals->_party.checkPartyDead();
}
uint16 Map::dataWord(uint16 ofs) const {
return READ_LE_UINT16(&_data[ofs]);
}
void Map::dataWord(uint16 ofs, uint16 val) {
WRITE_LE_UINT16(&_data[ofs], val);
}
void Map::reduceHP() {
for (uint i = 0; i < g_globals->_party.size(); ++i)
g_globals->_party[i]._hpCurrent /= 2;
}
void Map::updateGame() {
g_events->send("Game", GameMessage("UPDATE"));
}
void Map::redrawGame() {
g_events->send("Game", GameMessage("REDRAW"));
}
void Map::encounter(const byte *id1, const byte *id2) {
Game::Encounter &enc = g_globals->_encounters;
g_maps->clearSpecial();
enc.clearMonsters();
for (int i = 0; i < 14 && *id1; ++i, ++id1, ++id2)
enc.addMonster(*id1, *id2);
enc._manual = true;
enc._levelIndex = 64;
enc.execute();
}
void Map::unlockDoor() {
g_maps->_currentState = _states[g_maps->_mapOffset] ^=
g_maps->_forwardMask & 0x55;
}
void Map::visitedSpecial() {
if (!_visited[g_maps->_mapOffset])
_visited[g_maps->_mapOffset] = VISITED_SPECIAL;
}
void Map::visitedExit() {
_visited[g_maps->_mapOffset] = VISITED_EXIT;
}
void Map::visitedBusiness() {
_visited[g_maps->_mapOffset] = VISITED_BUSINESS;
}
} // namespace Maps
} // namespace MM1
} // namespace MM