mirror of
https://github.com/scummvm/scummvm.git
synced 2025-04-02 10:52:32 -04:00
There is version of MM1 in the wild which have some differences with floppy version of vanilla. Support resources from it too.
148 lines
3.9 KiB
C++
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
|