[Scummvm-git-logs] scummvm master -> 8a460765a95a148e63590329d6f43dacd288b271
mduggan
noreply at scummvm.org
Sat Jun 25 23:43:29 UTC 2022
This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
b1bb9aa6e5 ULTIMA8: JANITORIAL: whitespace
b23fd8c334 ULTIMA8: Expand comments on a couple of U8 script fixes.
b92c9f981b ULTIMA8: Fix Crusader crash if splash item destroyed before damage happens
8a460765a9 ULTIMA8: Terminate more processes on Crusader level change
Commit: b1bb9aa6e54dbd435f8a23dbc50684f696539b97
https://github.com/scummvm/scummvm/commit/b1bb9aa6e54dbd435f8a23dbc50684f696539b97
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2022-06-26T08:36:11+09:00
Commit Message:
ULTIMA8: JANITORIAL: whitespace
Changed paths:
engines/ultima/ultima8/ultima8.cpp
diff --git a/engines/ultima/ultima8/ultima8.cpp b/engines/ultima/ultima8/ultima8.cpp
index f9d9538d954..9886c46fe17 100644
--- a/engines/ultima/ultima8/ultima8.cpp
+++ b/engines/ultima/ultima8/ultima8.cpp
@@ -1508,7 +1508,7 @@ bool Ultima8Engine::load(Common::ReadStream *rs, uint32 version) {
_avatarInStasis = (rs->readByte() != 0);
if (GAME_IS_CRUSADER) {
- _crusaderTeleporting = (rs->readByte() != 0);
+ _crusaderTeleporting = (rs->readByte() != 0);
_cruStasis = false;
}
Commit: b23fd8c3345009e8b107695128ea29f7feaed783
https://github.com/scummvm/scummvm/commit/b23fd8c3345009e8b107695128ea29f7feaed783
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2022-06-26T08:36:11+09:00
Commit Message:
ULTIMA8: Expand comments on a couple of U8 script fixes.
Not sure how long sourceforge bugtracker for Pentagram will exist so nice to
document the reason for the workaround in the code.
Changed paths:
engines/ultima/ultima8/usecode/uc_machine.cpp
diff --git a/engines/ultima/ultima8/usecode/uc_machine.cpp b/engines/ultima/ultima8/usecode/uc_machine.cpp
index 40e6929cf4a..97ffd9bf525 100644
--- a/engines/ultima/ultima8/usecode/uc_machine.cpp
+++ b/engines/ultima/ultima8/usecode/uc_machine.cpp
@@ -317,9 +317,9 @@ void UCMachine::execProcess(UCProcess *p) {
cs->read(str, ui16a);
str[ui16a] = 0;
- // REALLY MAJOR HACK:
- // see docs/u8bugs.txt and
- // https://sourceforge.net/p/pentagram/bugs/196/
+ // WORKAROUND: German U8: When the candles are not in the right positions
+ // for a sorcery spell, the string does not match, causing a crash.
+ // Original bug: https://sourceforge.net/p/pentagram/bugs/196/
if (GAME_IS_U8 && p->_classId == 0x7C) {
if (!strcmp(str, " Irgendetwas stimmt nicht!")) {
str[25] = '.'; // ! to .
@@ -410,9 +410,12 @@ void UCMachine::execProcess(UCProcess *p) {
delete[] argbuf;
}
- // REALLY MAJOR HACK:
- // see docs/u8bugs.txt and
- // https://sourceforge.net/p/pentagram/feature-requests/6/
+ // WORKAROUND: In U8, the flag 'startedConvo' [0000 01] which acts
+ // as a mutex is set too late in the script, allowing two copies of
+ // of the Ancient Ones script (each spawned by a different egg) to
+ // run simultaneously. Set the flag when the avatar is put in stasis
+ // to avoid this.
+ // Original bug: https://sourceforge.net/p/pentagram/feature-requests/6/
if (GAME_IS_U8 && p->_classId == 0x48B && func == 0xD0) {
// 0xD0 = setAvatarInStasis
_globals->setEntries(0, 1, 1);
Commit: b92c9f981b9794fcb8da6aabbdaa5e1b93a97f9f
https://github.com/scummvm/scummvm/commit/b92c9f981b9794fcb8da6aabbdaa5e1b93a97f9f
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2022-06-26T08:36:11+09:00
Commit Message:
ULTIMA8: Fix Crusader crash if splash item destroyed before damage happens
Changed paths:
engines/ultima/ultima8/world/fire_type.cpp
diff --git a/engines/ultima/ultima8/world/fire_type.cpp b/engines/ultima/ultima8/world/fire_type.cpp
index 25859e11c9b..8ff9aeb3112 100644
--- a/engines/ultima/ultima8/world/fire_type.cpp
+++ b/engines/ultima/ultima8/world/fire_type.cpp
@@ -268,7 +268,11 @@ void FireType::applySplashDamageAround(const Point3 &pt, int damage, int rangedi
if (!splashitemdamage)
continue;
- Direction splashdir = src->getDirToItemCentre(pt);
+ Direction splashdir;
+ if (src)
+ splashdir = src->getDirToItemCentre(pt);
+ else
+ splashdir = dir_north;
splashitem->receiveHit(0, splashdir, splashitemdamage, _typeNo);
}
}
Commit: 8a460765a95a148e63590329d6f43dacd288b271
https://github.com/scummvm/scummvm/commit/8a460765a95a148e63590329d6f43dacd288b271
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2022-06-26T08:42:55+09:00
Commit Message:
ULTIMA8: Terminate more processes on Crusader level change
Previously we used the Ultima 8 behavior of not terminating any obj id 0
processes on level change, but that occasionally left never ending "alarm has
been activated" background audio and similar problems.
This changes so that all but the "persistent" processes are terminated.
At the same time, also correctly clean up the snap egg and target lists when
changing maps - previously these were left sitting around.
Changed paths:
engines/ultima/ultima8/graphics/cycle_process.cpp
engines/ultima/ultima8/kernel/kernel.cpp
engines/ultima/ultima8/kernel/kernel.h
engines/ultima/ultima8/world/crosshair_process.cpp
engines/ultima/ultima8/world/current_map.cpp
engines/ultima/ultima8/world/item_selection_process.cpp
engines/ultima/ultima8/world/snap_process.cpp
engines/ultima/ultima8/world/snap_process.h
engines/ultima/ultima8/world/target_reticle_process.cpp
engines/ultima/ultima8/world/world.cpp
diff --git a/engines/ultima/ultima8/graphics/cycle_process.cpp b/engines/ultima/ultima8/graphics/cycle_process.cpp
index e3d01fa10ad..e3e4a828532 100644
--- a/engines/ultima/ultima8/graphics/cycle_process.cpp
+++ b/engines/ultima/ultima8/graphics/cycle_process.cpp
@@ -134,6 +134,8 @@ bool CycleProcess::loadData(Common::ReadStream *rs, uint32 version) {
_running = rs->readByte();
_instance = this; //static
+
+ _type = 1; // should be persistant but older savegames may not know that.
return true;
}
diff --git a/engines/ultima/ultima8/kernel/kernel.cpp b/engines/ultima/ultima8/kernel/kernel.cpp
index 51da4447063..16930c87895 100644
--- a/engines/ultima/ultima8/kernel/kernel.cpp
+++ b/engines/ultima/ultima8/kernel/kernel.cpp
@@ -323,6 +323,8 @@ void Kernel::killProcessesNotOfType(ObjId objid, uint16 processtype, bool fail)
for (ProcessIterator it = _processes.begin(); it != _processes.end(); ++it) {
Process *p = *it;
+ // * If objid is 0, terminate procs for all objects.
+ // * Never terminate procs with objid 0
if (p->_itemNum != 0 && (objid == 0 || objid == p->_itemNum) &&
(p->_type != processtype) &&
!(p->_flags & Process::PROC_TERMINATED) &&
@@ -335,6 +337,26 @@ void Kernel::killProcessesNotOfType(ObjId objid, uint16 processtype, bool fail)
}
}
+void Kernel::killAllProcessesNotOfTypeExcludeCurrent(uint16 processtype, bool fail) {
+ for (ProcessIterator it = _processes.begin(); it != _processes.end(); ++it) {
+ Process *p = *it;
+
+ // Don't kill the running process
+ if (p == _runningProcess)
+ continue;
+
+ if ((p->_type != processtype) &&
+ !(p->_flags & Process::PROC_TERMINATED) &&
+ !(p->_flags & Process::PROC_TERM_DEFERRED)) {
+ if (fail)
+ p->fail();
+ else
+ p->terminate();
+ }
+ }
+}
+
+
void Kernel::save(Common::WriteStream *ws) {
ws->writeUint32LE(_tickNum);
_pIDs->save(ws);
diff --git a/engines/ultima/ultima8/kernel/kernel.h b/engines/ultima/ultima8/kernel/kernel.h
index e6a9315b11b..c2f384cda6a 100644
--- a/engines/ultima/ultima8/kernel/kernel.h
+++ b/engines/ultima/ultima8/kernel/kernel.h
@@ -83,6 +83,12 @@ public:
//! \param fail if true, fail the processes instead of terminating them
void killProcessesNotOfType(ObjId objid, uint16 processtype, bool fail);
+ //! kill (fail) processes not of a certain type, regardless of object ID
+ //! except for the current running process (for switching levels in Crusader)
+ //! \param type the type not to kill
+ //! \param fail if true, fail the processes instead of terminating them
+ void killAllProcessesNotOfTypeExcludeCurrent(uint16 processtype, bool fail);
+
//! get an iterator of the process list.
ProcessIter getProcessBeginIterator() {
return _processes.begin();
diff --git a/engines/ultima/ultima8/world/crosshair_process.cpp b/engines/ultima/ultima8/world/crosshair_process.cpp
index 97c562139ea..a101626b6f6 100644
--- a/engines/ultima/ultima8/world/crosshair_process.cpp
+++ b/engines/ultima/ultima8/world/crosshair_process.cpp
@@ -108,7 +108,9 @@ void CrosshairProcess::saveData(Common::WriteStream *ws) {
}
bool CrosshairProcess::loadData(Common::ReadStream *rs, uint32 version) {
- return Process::loadData(rs, version);
+ if (!Process::loadData(rs, version)) return false;
+ _type = 1; // should be persistant but older savegames may not know that.
+ return true;
}
} // End of namespace Ultima8
diff --git a/engines/ultima/ultima8/world/current_map.cpp b/engines/ultima/ultima8/world/current_map.cpp
index 82fe1f38b26..09b49011810 100644
--- a/engines/ultima/ultima8/world/current_map.cpp
+++ b/engines/ultima/ultima8/world/current_map.cpp
@@ -194,6 +194,11 @@ void CurrentMap::loadMap(Map *map) {
_fastXMax = -1;
_fastYMax = -1;
+ // Clear target items
+ for (unsigned int i = 0; i < MAP_NUM_TARGET_ITEMS; i++) {
+ _targets[i] = 0;
+ }
+
loadItems(map->_fixedItems, callCacheIn);
loadItems(map->_dynamicItems, callCacheIn);
@@ -1378,11 +1383,16 @@ uint32 CurrentMap::I_canExistAt(const uint8 *args, unsigned int argsize) {
}
uint32 CurrentMap::I_canExistAtPoint(const uint8 *args, unsigned int /*argsize*/) {
- ARG_NULL16(); // unknown
- ARG_NULL16(); // unknown
+ ARG_ITEM_FROM_PTR(other);
ARG_UINT16(shape);
ARG_WORLDPOINT(pt);
+ if (other) {
+ debug("I_canExistAtPoint other object: ");
+ other->dumpInfo();
+ } else {
+ debug("I_canExistAtPoint other object null.");
+ }
if (shape > 0x800)
return 0;
diff --git a/engines/ultima/ultima8/world/item_selection_process.cpp b/engines/ultima/ultima8/world/item_selection_process.cpp
index fa6648c5b51..4969b2fdc53 100644
--- a/engines/ultima/ultima8/world/item_selection_process.cpp
+++ b/engines/ultima/ultima8/world/item_selection_process.cpp
@@ -220,6 +220,7 @@ bool ItemSelectionProcess::loadData(Common::ReadStream *rs, uint32 version) {
_ax = rs->readSint32LE();
_ay = rs->readSint32LE();
_az = rs->readSint32LE();
+ _type = 1; // should be persistant but older savegames may not know that.
return true;
}
diff --git a/engines/ultima/ultima8/world/snap_process.cpp b/engines/ultima/ultima8/world/snap_process.cpp
index cd1fc0232cd..697ae6fbab8 100644
--- a/engines/ultima/ultima8/world/snap_process.cpp
+++ b/engines/ultima/ultima8/world/snap_process.cpp
@@ -128,6 +128,13 @@ void SnapProcess::removeEgg(Item *item) {
}
}
+void SnapProcess::clearEggs() {
+ _snapEggs.clear();
+ _currentSnapEgg = 0;
+ _currentSnapEggRange = Rect();
+}
+
+
bool SnapProcess::isNpcInRangeOfCurrentEgg() const {
if (!_currentSnapEgg)
return false;
@@ -191,6 +198,8 @@ bool SnapProcess::loadData(Common::ReadStream *rs, uint32 version) {
_snapEggs.push_back(rs->readUint16LE());
}
+ _type = 1; // should be persistant but older savegames may not know that.
+
return true;
}
diff --git a/engines/ultima/ultima8/world/snap_process.h b/engines/ultima/ultima8/world/snap_process.h
index cf13cb1251f..6b44fc4116b 100644
--- a/engines/ultima/ultima8/world/snap_process.h
+++ b/engines/ultima/ultima8/world/snap_process.h
@@ -44,6 +44,7 @@ public:
void addEgg(Item *item);
void removeEgg(Item *item);
+ void clearEggs();
static SnapProcess *get_instance();
diff --git a/engines/ultima/ultima8/world/target_reticle_process.cpp b/engines/ultima/ultima8/world/target_reticle_process.cpp
index 48fa5e4a7e5..a1de56cc530 100644
--- a/engines/ultima/ultima8/world/target_reticle_process.cpp
+++ b/engines/ultima/ultima8/world/target_reticle_process.cpp
@@ -238,6 +238,8 @@ bool TargetReticleProcess::loadData(Common::ReadStream *rs, uint32 version) {
if (GAME_IS_REGRET)
_reticleStyle = rs->readUint16LE();
+ _type = 1; // should be persistant but older savegames may not know that.
+
return true;
}
diff --git a/engines/ultima/ultima8/world/world.cpp b/engines/ultima/ultima8/world/world.cpp
index d1d90c0f220..432c5556fc3 100644
--- a/engines/ultima/ultima8/world/world.cpp
+++ b/engines/ultima/ultima8/world/world.cpp
@@ -27,6 +27,7 @@
#include "ultima/ultima8/filesys/raw_archive.h"
#include "ultima/ultima8/world/item_factory.h"
#include "ultima/ultima8/world/actors/main_actor.h"
+#include "ultima/ultima8/world/actors/scheduler_process.h"
#include "ultima/ultima8/world/loop_script.h"
#include "ultima/ultima8/usecode/uc_list.h"
#include "ultima/ultima8/misc/direction_util.h"
@@ -167,8 +168,17 @@ bool World::switchMap(uint32 newmap) {
_maps[oldmap]->unloadFixed();
}
- // Kill any processes that need killing (those with type != 1 && item != 0)
- Kernel::get_instance()->killProcessesNotOfType(0, 1, true);
+ // Kill any processes that need killing
+ if (GAME_IS_U8) {
+ // U8 doesn't kill processes of object 0 *or* type 1 when changing map.
+ Kernel::get_instance()->killProcessesNotOfType(0, 1, true);
+ } else {
+ // Crusader kills processes even for object 0 when switching.
+ SnapProcess::get_instance()->clearEggs();
+ CameraProcess::ResetCameraProcess();
+ Kernel::get_instance()->killAllProcessesNotOfTypeExcludeCurrent(1, true);
+ Kernel::get_instance()->addProcess(new SchedulerProcess());
+ }
pout << "Loading Fixed items in map " << newmap << Std::endl;
Common::SeekableReadStream *items = GameData::get_instance()->getFixed()
@@ -178,15 +188,19 @@ bool World::switchMap(uint32 newmap) {
_currentMap->loadMap(_maps[newmap]);
- // update camera if needed (u8 only)
- // TODO: This may not even be needed, but do it just in case the
- // camera was looking at something else during teleport.
+ // Update camera
if (GAME_IS_U8) {
+ // TODO: This may not even be needed for U8, but reset in case camera
+ // was looking at something other than the avatar during teleport.
CameraProcess *camera = CameraProcess::GetCameraProcess();
if (camera && camera->getItemNum() != 1) {
CameraProcess::SetCameraProcess(new CameraProcess(1));
}
CameraProcess::SetEarthquake(0);
+ } else {
+ // In Crusader, snap the camera to the avatar. The snap process will
+ // then find the right snap egg in the next frame.
+ CameraProcess::SetCameraProcess(new CameraProcess(1));
}
return true;
More information about the Scummvm-git-logs
mailing list