From b13b00deb3b604f6ece5e63c3824100b9ae7cb32 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 9 Apr 2018 19:33:31 -0400 Subject: XEEN: Add Patcher class for doing on-the-fly map patches The first patch is a script patch for Ellinger's Tower Level 2 on the Dark Side. It fixes an incorrect index for a wall item of a curtain that's meant to be removed --- engines/xeen/map.cpp | 2 ++ engines/xeen/module.mk | 1 + engines/xeen/patcher.cpp | 84 ++++++++++++++++++++++++++++++++++++++++++++++++ engines/xeen/patcher.h | 48 +++++++++++++++++++++++++++ engines/xeen/scripts.cpp | 4 +-- engines/xeen/xeen.cpp | 3 ++ engines/xeen/xeen.h | 2 ++ 7 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 engines/xeen/patcher.cpp create mode 100644 engines/xeen/patcher.h diff --git a/engines/xeen/map.cpp b/engines/xeen/map.cpp index 1fb5a9f73e..6e859e17ba 100644 --- a/engines/xeen/map.cpp +++ b/engines/xeen/map.cpp @@ -628,6 +628,7 @@ void Map::load(int mapId) { FileManager &files = *g_vm->_files; Interface &intf = *g_vm->_interface; Party &party = *g_vm->_party; + Patcher &patcher = *g_vm->_patcher; Sound &sound = *g_vm->_sound; IndoorDrawList &indoorList = intf._indoorList; OutdoorDrawList &outdoorList = intf._outdoorList; @@ -982,6 +983,7 @@ void Map::load(int mapId) { } } + patcher.patch(); loadSky(); files.setGameCc(ccNum); diff --git a/engines/xeen/module.mk b/engines/xeen/module.mk index 9f6075b5f6..66091681b2 100644 --- a/engines/xeen/module.mk +++ b/engines/xeen/module.mk @@ -47,6 +47,7 @@ MODULE_OBJS := \ locations.o \ map.o \ party.o \ + patcher.o \ resources.o \ saves.o \ screen.o \ diff --git a/engines/xeen/patcher.cpp b/engines/xeen/patcher.cpp new file mode 100644 index 0000000000..384b90ee9a --- /dev/null +++ b/engines/xeen/patcher.cpp @@ -0,0 +1,84 @@ +/* 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/patcher.h" +#include "xeen/xeen.h" +#include "xeen/map.h" +#include "xeen/party.h" +#include "common/memstream.h" +#include "common/serializer.h" + +namespace Xeen { + +struct ScriptEntry { + uint _gameId; + int _mapId; + const byte *_data; +}; + +const byte MAP54_LINE8[] = { 8, 10, 10, DIR_EAST, 8, OP_MoveWallObj, 20, 100, 100 }; + +#define SCRIPT_PATCHES_COUNT 1 +static const ScriptEntry SCRIPT_PATCHES[] = { + { GType_DarkSide, 54, MAP54_LINE8 } +}; + +/*------------------------------------------------------------------------*/ + +void Patcher::patch() { + patchScripts(); +} + +void Patcher::patchScripts() { + FileManager &files = *g_vm->_files; + Map &map = *g_vm->_map; + Party &party = *g_vm->_party; + + uint gameId = g_vm->getGameID(); + if (gameId == GType_WorldOfXeen) + gameId = files._ccNum ? GType_DarkSide : GType_Clouds; + + for (int patchIdx = 0; patchIdx < SCRIPT_PATCHES_COUNT; ++patchIdx) { + const ScriptEntry &se = SCRIPT_PATCHES[patchIdx]; + if (se._gameId != gameId || se._mapId != party._mazeId) + continue; + + MazeEvent evt; + Common::MemoryReadStream memStream(se._data, se._data[0] + 1); + Common::Serializer s(&memStream, nullptr); + evt.synchronize(s); + + // Scan through the events to find a matching line + int idx = 0; + while (idx < (int)map._events.size() && (evt._position != map._events[idx]._position + || evt._direction != map._events[idx]._direction || evt._line != map._events[idx]._line)) + ++idx; + + // Set the event + if (idx == (int)map._events.size()) + map._events.push_back(evt); + else + map._events[idx] = evt; + } +} + +} // End of namespace Xeen diff --git a/engines/xeen/patcher.h b/engines/xeen/patcher.h new file mode 100644 index 0000000000..f0d4267320 --- /dev/null +++ b/engines/xeen/patcher.h @@ -0,0 +1,48 @@ +/* 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_PATCHER_H +#define XEEN_PATCHER_H + +namespace Xeen { + +class Patcher { +private: + /** + * Patches incorrect script lines + */ + void patchScripts(); +public: + /** + * Constructor + */ + Patcher() {} + + /** + * Called after a map is loaded to patch any problems + */ + void patch(); +}; + +} // End of namespace Xeen + +#endif /* XEEN_PATCHER_H */ diff --git a/engines/xeen/scripts.cpp b/engines/xeen/scripts.cpp index 464130be69..298dead111 100644 --- a/engines/xeen/scripts.cpp +++ b/engines/xeen/scripts.cpp @@ -1130,11 +1130,11 @@ bool Scripts::cmdRndDamage(ParamsIterator ¶ms) { bool Scripts::cmdMoveWallObj(ParamsIterator ¶ms) { Map &map = *_vm->_map; - int itemNum = params.readByte(); + int index = params.readByte(); int x = params.readShort(); int y = params.readShort(); - map._mobData._wallItems[itemNum]._position = Common::Point(x, y); + map._mobData._wallItems[index]._position = Common::Point(x, y); return true; } diff --git a/engines/xeen/xeen.cpp b/engines/xeen/xeen.cpp index f495f48a49..41de1d8565 100644 --- a/engines/xeen/xeen.cpp +++ b/engines/xeen/xeen.cpp @@ -49,6 +49,7 @@ XeenEngine::XeenEngine(OSystem *syst, const XeenGameDescription *gameDesc) _locations = nullptr; _map = nullptr; _party = nullptr; + _patcher = nullptr; _resources = nullptr; _saves = nullptr; _screen = nullptr; @@ -75,6 +76,7 @@ XeenEngine::~XeenEngine() { delete _locations; delete _map; delete _party; + delete _patcher; delete _saves; delete _screen; delete _scripts; @@ -100,6 +102,7 @@ bool XeenEngine::initialize() { _locations = new LocationManager(); _map = new Map(this); _party = new Party(this); + _patcher = new Patcher(); _saves = new SavesManager(_targetName); _screen = new Screen(this); _scripts = new Scripts(this); diff --git a/engines/xeen/xeen.h b/engines/xeen/xeen.h index 2cd42fdb0a..93be6d202f 100644 --- a/engines/xeen/xeen.h +++ b/engines/xeen/xeen.h @@ -39,6 +39,7 @@ #include "xeen/locations.h" #include "xeen/map.h" #include "xeen/party.h" +#include "xeen/patcher.h" #include "xeen/resources.h" #include "xeen/saves.h" #include "xeen/screen.h" @@ -183,6 +184,7 @@ public: LocationManager *_locations; Map *_map; Party *_party; + Patcher *_patcher; Resources *_resources; SavesManager *_saves; Screen *_screen; -- cgit v1.2.3