aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2018-04-09 19:33:31 -0400
committerPaul Gilbert2018-04-09 19:33:31 -0400
commitb13b00deb3b604f6ece5e63c3824100b9ae7cb32 (patch)
tree02da609f5589a5fecd31b499db798f5db9c9ec73
parentf52517449591bdc269bec7eecfffdc5439567d33 (diff)
downloadscummvm-rg350-b13b00deb3b604f6ece5e63c3824100b9ae7cb32.tar.gz
scummvm-rg350-b13b00deb3b604f6ece5e63c3824100b9ae7cb32.tar.bz2
scummvm-rg350-b13b00deb3b604f6ece5e63c3824100b9ae7cb32.zip
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
-rw-r--r--engines/xeen/map.cpp2
-rw-r--r--engines/xeen/module.mk1
-rw-r--r--engines/xeen/patcher.cpp84
-rw-r--r--engines/xeen/patcher.h48
-rw-r--r--engines/xeen/scripts.cpp4
-rw-r--r--engines/xeen/xeen.cpp3
-rw-r--r--engines/xeen/xeen.h2
7 files changed, 142 insertions, 2 deletions
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 &params) {
bool Scripts::cmdMoveWallObj(ParamsIterator &params) {
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;