[Scummvm-git-logs] scummvm master -> a955865002ffcec4036fa1757554d391fe65866c
mduggan
mgithub at guarana.org
Tue Jul 20 10:02:39 UTC 2021
This automated email contains information about 5 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
718ed5280a ULTIMA8: Improvements to map dumping
b5f1222a24 ULTIMA8: Fix Crusader keypad gump cheat
09bb79b145 ULTIMA8: Use MKTAG on IFF fourCCs for nicer code.
5df976a6d0 ULTIMA8: Target reticle process updates for No Regret
a955865002 ULTIMA8: Document some Crusader setActivity magic numbers
Commit: 718ed5280a5970d78086467f20b747e1686dee3f
https://github.com/scummvm/scummvm/commit/718ed5280a5970d78086467f20b747e1686dee3f
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-07-20T18:55:52+09:00
Commit Message:
ULTIMA8: Improvements to map dumping
* Make it work in Crusader
* Add a debugger command to dump all maps at once
Changed paths:
engines/ultima/ultima8/misc/debugger.cpp
engines/ultima/ultima8/misc/debugger.h
diff --git a/engines/ultima/ultima8/misc/debugger.cpp b/engines/ultima/ultima8/misc/debugger.cpp
index b9275c95d1..aa7dc837f4 100644
--- a/engines/ultima/ultima8/misc/debugger.cpp
+++ b/engines/ultima/ultima8/misc/debugger.cpp
@@ -132,6 +132,7 @@ Debugger::Debugger() : Shared::Debugger() {
registerCmd("GameMapGump::stopHighlightItems", WRAP_METHOD(Debugger, cmdStopHighlightItems));
registerCmd("GameMapGump::toggleHighlightItems", WRAP_METHOD(Debugger, cmdToggleHighlightItems));
registerCmd("GameMapGump::dumpMap", WRAP_METHOD(Debugger, cmdDumpMap));
+ registerCmd("GameMapGump::dumpAllMaps", WRAP_METHOD(Debugger, cmdDumpAllMaps));
registerCmd("GameMapGump::incrementSortOrder", WRAP_METHOD(Debugger, cmdIncrementSortOrder));
registerCmd("GameMapGump::decrementSortOrder", WRAP_METHOD(Debugger, cmdDecrementSortOrder));
@@ -654,46 +655,33 @@ bool Debugger::cmdToggleHighlightItems(int argc, const char **argv) {
return false;
}
-bool Debugger::cmdDumpMap(int argc, const char **argv) {
- // Save because we're going to potentially break the game by enlarging
- // the fast area and available object IDs.
- int slot = Ultima8Engine::get_instance()->getAutosaveSlot();
- if (!Ultima8Engine::get_instance()->saveGame(slot, "Pre-dumpMap save")) {
- debugPrintf("Could not dump map: pre-dumpMap save failed\n");
- return false;
- }
-
+void Debugger::dumpCurrentMap() {
// Increase number of available object IDs.
ObjectManager::get_instance()->allow64kObjects();
- // Actual size
- int32 awidth = 8192;
- int32 aheight = 8192;
-
- int32 xpos = 0;
- int32 ypos = 0;
-
+ // top/bottom/left/right render coordinates
int32 left = 16384;
int32 right = -16384;
int32 top = 16384;
int32 bot = -16384;
- int32 camheight = 256;
+ const int32 camheight = 256;
+ const CurrentMap *curmap = World::get_instance()->getCurrentMap();
+ const int32 chunksize = curmap->getChunkSize();
- // Work out the map limit we do this very coarsly
- // Now render the map
- for (int32 y = 0; y < 64; y++) {
- for (int32 x = 0; x < 64; x++) {
- const Std::list<Item *> *list =
- World::get_instance()->getCurrentMap()->getItemList(x, y);
+ // Work out the map limits in chunks
+ for (int32 y = 0; y < MAP_NUM_CHUNKS; y++) {
+ for (int32 x = 0; x < MAP_NUM_CHUNKS; x++) {
+ const Std::list<Item *> *list = curmap->getItemList(x, y);
// Should iterate the items!
// (items could extend outside of this chunk and they have height)
if (list && list->size() != 0) {
- int32 l = (x * 512 - y * 512) / 4 - 128;
- int32 r = (x * 512 - y * 512) / 4 + 128;
- int32 t = (x * 512 + y * 512) / 8 - 256;
- int32 b = (x * 512 + y * 512) / 8;
+ // Bounds of render coordinates for items in this chunk
+ int32 l = (x * chunksize - y * chunksize) / 4 - (chunksize / 4);
+ int32 r = (x * chunksize - y * chunksize) / 4 + (chunksize / 4);
+ int32 t = (x * chunksize + y * chunksize) / 8 - (chunksize / 2);
+ int32 b = (x * chunksize + y * chunksize) / 8;
t -= 256; // approx. adjustment for height of items in chunk
@@ -706,32 +694,34 @@ bool Debugger::cmdDumpMap(int argc, const char **argv) {
}
if (right == -16384) {
- return false;
+ debugPrintf("Map seems empty, nothing to dump.\n");
+ // No objects?
+ return;
}
// camera height
bot += camheight;
top += camheight;
- awidth = right - left;
- aheight = bot - top;
-
- ypos = top;
- xpos = left;
-
- // Buffer Size
- int32 bwidth = awidth;
- //int32 bheight = 256;
-
- // Original version of this command wrote the image out in rows to save memory
- // This version can only write out a full texture
- int32 bheight = aheight;
-
- // Tile size
- int32 twidth = bwidth / 8;
- int32 theight = 256;
+ const int32 awidth = right - left;
+ const int32 aheight = bot - top;
+
+ //
+ // If you are doing a once-off dump and get this error, try building ScummVM
+ // with int32 size for Surfaces. It breaks other engines but this is just a
+ // once-off type debugging feature anyway.
+ //
+ // Most U8 maps can be dumped without needing int32, but most Crusader maps
+ // need a patch to work.
+ //
+ Graphics::Surface nullsurface;
+ if ((sizeof(nullsurface.pitch) == 2 && awidth > 8191) ||
+ (sizeof(nullsurface.h) == 2 && aheight > 32767 )) {
+ warning("WARN: Can't dump map, image will not fit into 16 bit dimensions.");
+ return;
+ }
- GameMapGump *g = new GameMapGump(0, 0, twidth, theight);
+ GameMapGump *g = new GameMapGump(0, 0, awidth, aheight);
// HACK: Setting both INVISIBLE and TRANSPARENT flags on the Avatar
// will make him completely invisible.
@@ -741,50 +731,28 @@ bool Debugger::cmdDumpMap(int argc, const char **argv) {
CurrentMap *currentMap = World::get_instance()->getCurrentMap();
currentMap->setWholeMapFast();
- RenderSurface *s = RenderSurface::CreateSecondaryRenderSurface(bwidth,
- bheight);
+ RenderSurface *s = RenderSurface::CreateSecondaryRenderSurface(awidth,
+ aheight);
debugPrintf("Rendering map...\n");
- // Now render the map
- for (int32 y = 0; y < aheight; y += theight) {
- for (int32 x = 0; x < awidth; x += twidth) {
- // Work out 'effective' and world coords
- int32 ex = xpos + x + twidth / 2;
- int32 ey = ypos + y + theight / 2;
- int32 wx = ex * 2 + ey * 4;
- int32 wy = ey * 4 - ex * 2;
-
- s->SetOrigin(x, y % bheight);
- CameraProcess::SetCameraProcess(new CameraProcess(wx + 4 * camheight, wy + 4 * camheight, camheight));
- g->Paint(s, 256, false);
-
- }
+ // Camera coordinates in world-coords (in the middle of the map)
+ int32 midx = left + (right - left) / 2;
+ int32 midy = top + (bot - top) / 2;
+ int32 cx = midx * 2 + midy * 4;
+ int32 cy = midy * 4 - midx * 2;
- // Write out the current buffer
- //if (((y + theight) % bheight) == 0) {
- // for (int i = 0; i < bwidth * bheight; ++i) {
- // // Convert to correct pixel format
- // uint8 r, g, b;
- // UNPACK_RGB8(t->buffer[i], r, g, b);
- // uint8 *buf = reinterpret_cast<uint8 *>(&t->buffer[i]);
- // buf[0] = b;
- // buf[1] = g;
- // buf[2] = r;
- // buf[3] = 0xFF;
- // }
-
- // pngw->writeRows(bheight, t);
-
- // // clear buffer for next set
- // t->clear();
- //}
- }
+ // Now render the map
+ s->BeginPainting();
+ s->SetOrigin(0, 0);
+ CameraProcess::SetCameraProcess(new CameraProcess(cx + camheight * 4, cy + camheight * 4, camheight));
+ g->Paint(s, 256, false);
+ s->EndPainting();
#ifdef USE_PNG
- Std::string filename = Common::String::format("map_%02d.png", currentMap->getNum());
+ Std::string filename = Common::String::format("map_%03d.png", currentMap->getNum());
#else
- Std::string filename = Common::String::format("map_%02d.bmp", currentMap->getNum());
+ Std::string filename = Common::String::format("map_%03d.bmp", currentMap->getNum());
#endif
Common::DumpFile dumpFile;
@@ -806,11 +774,56 @@ bool Debugger::cmdDumpMap(int argc, const char **argv) {
delete g;
delete s;
+}
+
+bool Debugger::cmdDumpMap(int argc, const char **argv) {
+ // Save because we're going to potentially break the game by enlarging
+ // the fast area and available object IDs.
+ int slot = Ultima8Engine::get_instance()->getAutosaveSlot();
+ if (!Ultima8Engine::get_instance()->saveGame(slot, "Pre-dumpMap save")) {
+ debugPrintf("Could not dump map: pre-dumpMap save failed\n");
+ return false;
+ }
+
+ if (argc > 1) {
+ int mapno = atoi(argv[1]);
+ debugPrintf("Switching to map %d\n", mapno);
+ bool success = World::get_instance()->switchMap(mapno);
+ if (!success) {
+ debugPrintf("Dump failed: switch to map %d FAILED\n", mapno);
+ return false;
+ }
+ }
+ dumpCurrentMap();
+
// Reload
Ultima8Engine::get_instance()->loadGameState(slot);
return false;
}
+
+bool Debugger::cmdDumpAllMaps(int argc, const char **argv) {
+ // Save because we're going to potentially break the game by enlarging
+ // the fast area and available object IDs and changing maps
+ int slot = Ultima8Engine::get_instance()->getAutosaveSlot();
+ if (!Ultima8Engine::get_instance()->saveGame(slot, "Pre-dumpMap save")) {
+ debugPrintf("Could not dump map: pre-dumpMap save failed\n");
+ return false;
+ }
+
+ for (int i = 0; i < 256; i++) {
+ if (World::get_instance()->switchMap(i)) {
+ debugPrintf("Dumping map %d...\n", i);
+ dumpCurrentMap();
+ }
+ }
+
+ // Reload
+ Ultima8Engine::get_instance()->loadGameState(slot);
+ return false;
+}
+
+
bool Debugger::cmdIncrementSortOrder(int argc, const char **argv) {
int32 count = argc > 1 ? strtol(argv[1], 0, 0) : 1;
GameMapGump *gump = Ultima8Engine::get_instance()->getGameMapGump();
diff --git a/engines/ultima/ultima8/misc/debugger.h b/engines/ultima/ultima8/misc/debugger.h
index 66cde2d39c..a3fa63ee11 100644
--- a/engines/ultima/ultima8/misc/debugger.h
+++ b/engines/ultima/ultima8/misc/debugger.h
@@ -197,6 +197,7 @@ private:
bool cmdStopHighlightItems(int argc, const char **argv);
bool cmdToggleHighlightItems(int argc, const char **argv);
bool cmdDumpMap(int argc, const char **argvv);
+ bool cmdDumpAllMaps(int argc, const char **argv);
bool cmdIncrementSortOrder(int argc, const char **argv);
bool cmdDecrementSortOrder(int argc, const char **argv);
@@ -276,6 +277,8 @@ private:
bool cmdVisualDebugPathfinder(int argc, const char **argv);
#endif
+ void dumpCurrentMap(); // helper function
+
public:
Debugger();
~Debugger() override;
Commit: b5f1222a24722fbfdbee797d6c200ec85cf73e4d
https://github.com/scummvm/scummvm/commit/b5f1222a24722fbfdbee797d6c200ec85cf73e4d
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-07-20T18:55:52+09:00
Commit Message:
ULTIMA8: Fix Crusader keypad gump cheat
Changed paths:
engines/ultima/ultima8/gumps/keypad_gump.cpp
diff --git a/engines/ultima/ultima8/gumps/keypad_gump.cpp b/engines/ultima/ultima8/gumps/keypad_gump.cpp
index 187243bb33..99c2332734 100644
--- a/engines/ultima/ultima8/gumps/keypad_gump.cpp
+++ b/engines/ultima/ultima8/gumps/keypad_gump.cpp
@@ -166,7 +166,7 @@ void KeypadGump::ChildNotify(Gump *child, uint32 message) {
update = false;
if (_value == _targetValue || _value == CHEAT_CODE_VAL) {
sfxno = SFXNO_CORRECT;
- SetResult(_value);
+ SetResult(_targetValue);
} else {
// wrong.
sfxno = SFXNO_WRONG;
Commit: 09bb79b145d2bb10da31cdbb85edd75448060e15
https://github.com/scummvm/scummvm/commit/09bb79b145d2bb10da31cdbb85edd75448060e15
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-07-20T18:55:52+09:00
Commit Message:
ULTIMA8: Use MKTAG on IFF fourCCs for nicer code.
Changed paths:
engines/ultima/ultima8/gumps/movie_gump.cpp
diff --git a/engines/ultima/ultima8/gumps/movie_gump.cpp b/engines/ultima/ultima8/gumps/movie_gump.cpp
index 89f4916eed..7377901505 100644
--- a/engines/ultima/ultima8/gumps/movie_gump.cpp
+++ b/engines/ultima/ultima8/gumps/movie_gump.cpp
@@ -287,11 +287,11 @@ void MovieGump::loadTXTSubs(Common::SeekableReadStream *rs) {
}
// Some fourCCs used in IFF files
-static const uint32 IFF_MAGIC = 0x464F524D; // 'FORM'
-static const uint32 IFF_LANG = 0x4C414E47; // 'LANG'
-static const uint32 IFF_LANG_FR = 0x4652454E; // 'FREN'
-static const uint32 IFF_LANG_EN = 0x454E474C; // 'ENGL'
-static const uint32 IFF_LANG_DE = 0x4745524D; // 'GERM'
+static const uint32 IFF_MAGIC = MKTAG('F', 'O', 'R', 'M');
+static const uint32 IFF_LANG = MKTAG('L', 'A', 'N', 'G');
+static const uint32 IFF_LANG_FR = MKTAG('F', 'R', 'E', 'N');
+static const uint32 IFF_LANG_EN = MKTAG('E', 'N', 'G', 'L');
+static const uint32 IFF_LANG_DE = MKTAG('G', 'E', 'R', 'M');
void MovieGump::loadIFFSubs(Common::SeekableReadStream *rs) {
uint32 magic = rs->readUint32BE();
Commit: 5df976a6d0f3f6e5f351c7dca7da013db9467af1
https://github.com/scummvm/scummvm/commit/5df976a6d0f3f6e5f351c7dca7da013db9467af1
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-07-20T18:55:52+09:00
Commit Message:
ULTIMA8: Target reticle process updates for No Regret
Add the ability to use the 4 different reticle styles, which original game
controlled with CTRL-R (not yet wired up).
This breaks No Regret save compatibility, but it is still marked unstable and
currently the first mission can't be finished without cheating, so it should
not affect anyone.
Changed paths:
engines/ultima/ultima8/world/target_reticle_process.cpp
engines/ultima/ultima8/world/target_reticle_process.h
diff --git a/engines/ultima/ultima8/world/target_reticle_process.cpp b/engines/ultima/ultima8/world/target_reticle_process.cpp
index 21a4150798..35b1bfd8c6 100644
--- a/engines/ultima/ultima8/world/target_reticle_process.cpp
+++ b/engines/ultima/ultima8/world/target_reticle_process.cpp
@@ -21,6 +21,7 @@
*/
+#include "ultima/ultima8/ultima8.h"
#include "ultima/ultima8/gumps/message_box_gump.h"
#include "ultima/ultima8/games/game_data.h"
#include "ultima/ultima8/kernel/kernel.h"
@@ -39,9 +40,12 @@ TargetReticleProcess *TargetReticleProcess::_instance = nullptr;
DEFINE_RUNTIME_CLASSTYPE_CODE(TargetReticleProcess)
TargetReticleProcess::TargetReticleProcess() : Process(), _reticleEnabled(true),
- _lastUpdate(0), _reticleSpriteProcess(0), _lastTargetDir(dir_current), _lastTargetItem(0) {
+ _lastUpdate(0), _reticleSpriteProcess(0), _lastTargetDir(dir_current), _lastTargetItem(0),
+ _reticleStyle(0) {
_instance = this;
_type = 1; // persistent
+ if (GAME_IS_REGRET)
+ _reticleStyle = 3;
}
TargetReticleProcess::~TargetReticleProcess() {
@@ -128,7 +132,7 @@ void TargetReticleProcess::avatarMoved() {
_lastUpdate = 0;
}
-void TargetReticleProcess::putTargetReticleOnItem(Item *item, bool last_frame) {
+void TargetReticleProcess::putTargetReticleOnItem(Item *item, bool only_last_frame) {
int32 x, y, z;
// TODO: the game does a bunch of other maths here to pick the right location.
@@ -138,10 +142,12 @@ void TargetReticleProcess::putTargetReticleOnItem(Item *item, bool last_frame) {
z -= 8;
Process *p;
- if (!last_frame)
- p = new SpriteProcess(0x59a, 0, 5, 1, 10, x, y, z, false);
+ const int first_frame = _reticleStyle * 6;
+ const int last_frame = first_frame + 5;
+ if (!only_last_frame)
+ p = new SpriteProcess(0x59a, first_frame, last_frame, 1, 10, x, y, z, false);
else
- p = new SpriteProcess(0x59a, 5, 5, 1, 1000, x, y, z, false);
+ p = new SpriteProcess(0x59a, last_frame, last_frame, 1, 1000, x, y, z, false);
_reticleSpriteProcess = Kernel::get_instance()->addProcess(p);
_lastTargetItem = item->getObjId();
@@ -199,6 +205,17 @@ void TargetReticleProcess::toggle() {
setEnabled(newstate);
}
+void TargetReticleProcess::toggleReticleStyle() {
+ if (GAME_IS_REMORSE) {
+ _reticleStyle = 0;
+ return;
+ }
+
+ _reticleStyle++;
+ if (_reticleStyle >= 4)
+ _reticleStyle = 0;
+}
+
void TargetReticleProcess::saveData(Common::WriteStream *ws) {
Process::saveData(ws);
@@ -207,6 +224,8 @@ void TargetReticleProcess::saveData(Common::WriteStream *ws) {
ws->writeUint16LE(_reticleSpriteProcess);
ws->writeByte(_lastTargetDir);
ws->writeUint16LE(_lastTargetItem);
+ if (GAME_IS_REGRET)
+ ws->writeUint16LE(_reticleStyle);
}
bool TargetReticleProcess::loadData(Common::ReadStream *rs, uint32 version) {
@@ -217,6 +236,8 @@ bool TargetReticleProcess::loadData(Common::ReadStream *rs, uint32 version) {
_reticleSpriteProcess = rs->readUint16LE();
_lastTargetDir = static_cast<Direction>(rs->readByte());
_lastTargetItem = rs->readUint16LE();
+ if (GAME_IS_REGRET)
+ _reticleStyle = rs->readUint16LE();
return true;
}
diff --git a/engines/ultima/ultima8/world/target_reticle_process.h b/engines/ultima/ultima8/world/target_reticle_process.h
index f151b95051..59ee9950c8 100644
--- a/engines/ultima/ultima8/world/target_reticle_process.h
+++ b/engines/ultima/ultima8/world/target_reticle_process.h
@@ -66,6 +66,8 @@ public:
return _instance;
}
+ void toggleReticleStyle();
+
private:
bool findTargetItem();
void putTargetReticleOnItem(Item *, bool last_frame);
@@ -77,6 +79,9 @@ private:
Direction _lastTargetDir;
uint16 _lastTargetItem;
+ // Only used in No Regret.
+ uint16 _reticleStyle;
+
static TargetReticleProcess *_instance;
};
Commit: a955865002ffcec4036fa1757554d391fe65866c
https://github.com/scummvm/scummvm/commit/a955865002ffcec4036fa1757554d391fe65866c
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-07-20T18:55:52+09:00
Commit Message:
ULTIMA8: Document some Crusader setActivity magic numbers
Changed paths:
engines/ultima/ultima8/world/actors/actor.cpp
diff --git a/engines/ultima/ultima8/world/actors/actor.cpp b/engines/ultima/ultima8/world/actors/actor.cpp
index 524a262a21..541c9ed008 100644
--- a/engines/ultima/ultima8/world/actors/actor.cpp
+++ b/engines/ultima/ultima8/world/actors/actor.cpp
@@ -788,7 +788,16 @@ uint16 Actor::setActivityCru(int activity) {
Kernel *kernel = Kernel::get_instance();
- static const uint16 PROCSTYPES_TO_KILL[] = { 0x204, 0x258, 0xf0, 0x255, 0x257, 0x259, 0x25f, 0x25e };
+ static const uint16 PROCSTYPES_TO_KILL[] = {
+ ActorAnimProcess::ACTOR_ANIM_PROC_TYPE,
+ PathfinderProcess::PATHFINDER_PROC_TYPE,
+ 0x255, // PaceProcess
+ 0x257, // LoiterProcess
+ // 0x258, // Stand Process (we don't have a process for this)
+ AttackProcess::ATTACK_PROCESS_TYPE,
+ 0x25e, // GuardProcess
+ 0x25f // SurrenderProcess
+ };
for (int i = 0; i < ARRAYSIZE(PROCSTYPES_TO_KILL); i++) {
kernel->killProcesses(_objId, PROCSTYPES_TO_KILL[i], true);
}
More information about the Scummvm-git-logs
mailing list