[Scummvm-git-logs] scummvm master -> c6654065d2f268365469a0fb0d62d191d90cc455
OMGPizzaGuy
noreply at scummvm.org
Wed Dec 7 23:02:30 UTC 2022
This automated email contains information about 8 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
2183e1bb0b ULTIMA8: Store minimap data for all maps and add to savegame
b7b3a66b10 ULTIMA8: Adjust minimap save to store array size similar to world maps
147b6cea04 ULTIMA8: Reduce minimap pixel format to RGB5551
2eed148582 ULTIMA8: Update minimap storage to use HashMap
a016f1497d ULTIMA8: Split minimap generation into a separate class from the gump
c0fc6f583e ULTIMA8: Crop saved minimap surfaces to non-black area.
559e954eda ULTIMA8: Small cleanup for finding minimap bounds
c6654065d2 ULTIMA8: Fix incorrect header define for minimap.h
Commit: 2183e1bb0b23106833105c8a6757ceb219048341
https://github.com/scummvm/scummvm/commit/2183e1bb0b23106833105c8a6757ceb219048341
Author: Matthew Jimenez (matthew.jimenez at outlook.com)
Date: 2022-12-07T17:02:23-06:00
Commit Message:
ULTIMA8: Store minimap data for all maps and add to savegame
Changed paths:
engines/ultima/ultima8/filesys/savegame.cpp
engines/ultima/ultima8/gumps/minimap_gump.cpp
engines/ultima/ultima8/gumps/minimap_gump.h
diff --git a/engines/ultima/ultima8/filesys/savegame.cpp b/engines/ultima/ultima8/filesys/savegame.cpp
index 3f18ec0a641..66dc429935d 100644
--- a/engines/ultima/ultima8/filesys/savegame.cpp
+++ b/engines/ultima/ultima8/filesys/savegame.cpp
@@ -25,7 +25,7 @@ namespace Ultima {
namespace Ultima8 {
#define SAVEGAME_IDENT MKTAG('V', 'M', 'U', '8')
-#define SAVEGAME_VERSION 5
+#define SAVEGAME_VERSION 6
#define SAVEGAME_MIN_VERSION 2
SavegameReader::SavegameReader(Common::SeekableReadStream *rs, bool metadataOnly) : _file(rs), _version(0) {
diff --git a/engines/ultima/ultima8/gumps/minimap_gump.cpp b/engines/ultima/ultima8/gumps/minimap_gump.cpp
index 9548216c440..5dc8ef72fb0 100644
--- a/engines/ultima/ultima8/gumps/minimap_gump.cpp
+++ b/engines/ultima/ultima8/gumps/minimap_gump.cpp
@@ -33,22 +33,21 @@ namespace Ultima8 {
DEFINE_RUNTIME_CLASSTYPE_CODE(MiniMapGump)
-
-static const int MINMAPGUMP_SCALE = 8;
+#define MAX_NUM_MAPS 256
+#define MINMAPGUMP_SCALE 8
MiniMapGump::MiniMapGump(int x, int y) :
Gump(x, y, MAP_NUM_CHUNKS * 2 + 2, MAP_NUM_CHUNKS * 2 + 2, 0,
- FLAG_DRAGGABLE, LAYER_NORMAL), _minimap(), _lastMapNum(0), _ax(0), _ay(0) {
- _minimap.create((MAP_NUM_CHUNKS * MINMAPGUMP_SCALE), (MAP_NUM_CHUNKS * MINMAPGUMP_SCALE),
- Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
+ FLAG_DRAGGABLE, LAYER_NORMAL), _minimaps(MAX_NUM_MAPS), _format(4, 8, 8, 8, 8, 24, 16, 8, 0), _ax(0), _ay(0) {
}
-MiniMapGump::MiniMapGump() : Gump(), _minimap(), _lastMapNum(0), _ax(0), _ay(0) {
- _minimap.create((MAP_NUM_CHUNKS * MINMAPGUMP_SCALE), (MAP_NUM_CHUNKS * MINMAPGUMP_SCALE),
- Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
+MiniMapGump::MiniMapGump() : Gump(), _minimaps(MAX_NUM_MAPS), _format(4, 8, 8, 8, 8, 24, 16, 8, 0), _ax(0), _ay(0) {
}
MiniMapGump::~MiniMapGump(void) {
+ for (unsigned int i = 0; i < _minimaps.size(); ++i) {
+ _minimaps[i].free();
+ }
}
void MiniMapGump::run() {
@@ -58,11 +57,6 @@ void MiniMapGump::run() {
CurrentMap *currentmap = world->getCurrentMap();
int mapChunkSize = currentmap->getChunkSize();
- if (currentmap->getNum() != _lastMapNum) {
- _lastMapNum = currentmap->getNum();
- _minimap.clear();
- }
-
MainActor *actor = getMainActor();
if (!actor || actor->isDead())
return;
@@ -85,10 +79,15 @@ void MiniMapGump::run() {
void MiniMapGump::update(CurrentMap *currentmap) {
int mapChunkSize = currentmap->getChunkSize();
+ Graphics::Surface &minimap = _minimaps[currentmap->getNum()];
+ if (minimap.w == 0 && minimap.h == 0) {
+ minimap.create((MAP_NUM_CHUNKS * MINMAPGUMP_SCALE), (MAP_NUM_CHUNKS * MINMAPGUMP_SCALE), _format);
+ }
+
// Draw into the map surface
- for (int x = 0; x < _minimap.w; x++) {
- for (int y = 0; y < _minimap.h; y++) {
- uint32 val = _minimap.getPixel(x, y);
+ for (int x = 0; x < minimap.w; x++) {
+ for (int y = 0; y < minimap.h; y++) {
+ uint32 val = minimap.getPixel(x, y);
if (val == 0) {
int cx = x / MINMAPGUMP_SCALE;
int cy = y / MINMAPGUMP_SCALE;
@@ -101,7 +100,7 @@ void MiniMapGump::update(CurrentMap *currentmap) {
my += mapChunkSize / (MINMAPGUMP_SCALE * 2);
val = sampleAtPoint(currentmap, mx, my);
- _minimap.setPixel(x, y, val);
+ minimap.setPixel(x, y, val);
}
}
}
@@ -114,12 +113,15 @@ void MiniMapGump::generate() {
// TODO - do not leave whole map fast after generation
currentmap->setWholeMapFast();
- _minimap.clear();
+ Graphics::Surface &minimap = _minimaps[currentmap->getNum()];
+ minimap.free();
update(currentmap);
}
void MiniMapGump::clear() {
- _minimap.clear();
+ for (unsigned int i = 0; i < _minimaps.size(); ++i) {
+ _minimaps[i].free();
+ }
}
void MiniMapGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled) {
@@ -130,7 +132,7 @@ void MiniMapGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled)
surf->Fill32(0xFFFFAF00, _dims.right - 1, 1, 1, _dims.height());
// Dimensions minus border
- Rect dims = _dims;
+ Common::Rect dims(_dims.left, _dims.top, _dims.right, _dims.bottom);
dims.grow(-1);
// Fill the background
@@ -142,26 +144,29 @@ void MiniMapGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled)
int dx = 1;
int dy = 1;
+ World *world = World::get_instance();
+ CurrentMap *currentmap = world->getCurrentMap();
+ Graphics::ManagedSurface minimap(&_minimaps[currentmap->getNum()], DisposeAfterUse::NO);
Common::Rect r(sx, sy, sx + dims.width(), sy + dims.height());
if (r.left < 0) {
dx -= r.left;
r.left = 0;
}
- if (r.right > _minimap.w) {
- r.right = _minimap.w;
+ if (r.right > minimap.w) {
+ r.right = minimap.w;
}
if (r.top < 0) {
dy -= r.top;
r.top = 0;
}
- if (r.bottom > _minimap.h) {
- r.bottom = _minimap.h;
+ if (r.bottom > minimap.h) {
+ r.bottom = minimap.h;
}
- if (r.isValidRect()) {
- surf->Blit(_minimap, r, dx, dy);
+ if (!r.isEmpty()) {
+ surf->Blit(minimap, r, dx, dy);
}
int32 ax = _ax - sx;
@@ -188,14 +193,13 @@ uint32 MiniMapGump::sampleAtPoint(CurrentMap *currentmap, int x, int y) {
if (val == 0) {
// set to avoid reprocessing
- val = _minimap.format.RGBToColor(0x00, 0x00, 0x00);
+ val = _format.RGBToColor(0x00, 0x00, 0x00);
}
}
return val;
}
-uint32 MiniMapGump::sampleAtPoint(const Item *item, int x, int y)
-{
+uint32 MiniMapGump::sampleAtPoint(const Item *item, int x, int y) {
int32 ix, iy, iz, idx, idy, idz;
item->getLocation(ix, iy, iz);
item->getFootpadWorld(idx, idy, idz);
@@ -253,7 +257,7 @@ uint32 MiniMapGump::sampleAtPoint(const Item *item, int x, int y)
}
if (c > 0) {
- return _minimap.format.RGBToColor(RenderSurface::_gamma10toGamma22[r / c], RenderSurface::_gamma10toGamma22[g / c], RenderSurface::_gamma10toGamma22[b / c]);
+ return _format.RGBToColor(RenderSurface::_gamma10toGamma22[r / c], RenderSurface::_gamma10toGamma22[g / c], RenderSurface::_gamma10toGamma22[b / c]);
}
return 0;
@@ -261,15 +265,72 @@ uint32 MiniMapGump::sampleAtPoint(const Item *item, int x, int y)
void MiniMapGump::saveData(Common::WriteStream *ws) {
Gump::saveData(ws);
+
+ // Serialize the PixelFormat
+ ws->writeByte(_format.bytesPerPixel);
+ ws->writeByte(_format.rLoss);
+ ws->writeByte(_format.gLoss);
+ ws->writeByte(_format.bLoss);
+ ws->writeByte(_format.aLoss);
+ ws->writeByte(_format.rShift);
+ ws->writeByte(_format.gShift);
+ ws->writeByte(_format.bShift);
+ ws->writeByte(_format.aShift);
+
+ for (unsigned int i = 0; i < _minimaps.size(); ++i) {
+ const Graphics::Surface &minimap = _minimaps[i];
+ ws->writeByte(i);
+ ws->writeUint16LE(minimap.w);
+ ws->writeUint16LE(minimap.h);
+ for (int y = 0; y < minimap.h; ++y) {
+ const uint32 *pixels = (const uint32 *)minimap.getBasePtr(0, y);
+ for (int x = 0; x < minimap.w; ++x) {
+ ws->writeUint32LE(*pixels++);
+ }
+ }
+ }
}
bool MiniMapGump::loadData(Common::ReadStream *rs, uint32 version) {
if (!Gump::loadData(rs, version))
return false;
- _lastMapNum = 0;
- _minimap.clear();
+ _ax = 0;
+ _ay = 0;
+
+ if (version >= 6) {
+ _format.bytesPerPixel = rs->readByte();
+ _format.rLoss = rs->readByte();
+ _format.gLoss = rs->readByte();
+ _format.bLoss = rs->readByte();
+ _format.aLoss = rs->readByte();
+ _format.rShift = rs->readByte();
+ _format.gShift = rs->readByte();
+ _format.bShift = rs->readByte();
+ _format.aShift = rs->readByte();
+
+ for (unsigned int i = 0; i < _minimaps.size(); ++i) {
+ Graphics::Surface &minimap = _minimaps[i];
+ if (i != rs->readByte()) {
+ return false;
+ }
+
+ uint w = rs->readUint16LE();
+ uint h = rs->readUint16LE();
+ minimap.create(w, h, _format);
+ for (int y = 0; y < minimap.h; ++y) {
+ uint32 *pixels = (uint32 *)minimap.getBasePtr(0, y);
+ for (int x = 0; x < minimap.w; ++x) {
+ *pixels++ = rs->readUint32LE();
+ }
+ }
+ }
+ } else {
+ for (unsigned int i = 0; i < _minimaps.size(); ++i) {
+ _minimaps[i].free();
+ }
+ }
return true;
}
diff --git a/engines/ultima/ultima8/gumps/minimap_gump.h b/engines/ultima/ultima8/gumps/minimap_gump.h
index 3d9bb62395c..a8fd2c1da74 100644
--- a/engines/ultima/ultima8/gumps/minimap_gump.h
+++ b/engines/ultima/ultima8/gumps/minimap_gump.h
@@ -32,8 +32,8 @@ namespace Ultima8 {
class MiniMapGump : public Gump {
private:
- Graphics::ManagedSurface _minimap;
- unsigned int _lastMapNum;
+ Common::Array<Graphics::Surface> _minimaps;
+ Graphics::PixelFormat _format;
int32 _ax, _ay;
void update(CurrentMap *map);
Commit: b7b3a66b10dd06c7fcc67abec33c3224c8d95c4e
https://github.com/scummvm/scummvm/commit/b7b3a66b10dd06c7fcc67abec33c3224c8d95c4e
Author: Matthew Jimenez (matthew.jimenez at outlook.com)
Date: 2022-12-07T17:02:23-06:00
Commit Message:
ULTIMA8: Adjust minimap save to store array size similar to world maps
Changed paths:
engines/ultima/ultima8/gumps/minimap_gump.cpp
diff --git a/engines/ultima/ultima8/gumps/minimap_gump.cpp b/engines/ultima/ultima8/gumps/minimap_gump.cpp
index 5dc8ef72fb0..e45bf2e961a 100644
--- a/engines/ultima/ultima8/gumps/minimap_gump.cpp
+++ b/engines/ultima/ultima8/gumps/minimap_gump.cpp
@@ -277,9 +277,9 @@ void MiniMapGump::saveData(Common::WriteStream *ws) {
ws->writeByte(_format.bShift);
ws->writeByte(_format.aShift);
+ ws->writeUint32LE(static_cast<uint32>(_minimaps.size()));
for (unsigned int i = 0; i < _minimaps.size(); ++i) {
const Graphics::Surface &minimap = _minimaps[i];
- ws->writeByte(i);
ws->writeUint16LE(minimap.w);
ws->writeUint16LE(minimap.h);
for (int y = 0; y < minimap.h; ++y) {
@@ -298,6 +298,10 @@ bool MiniMapGump::loadData(Common::ReadStream *rs, uint32 version) {
_ax = 0;
_ay = 0;
+ for (unsigned int i = 0; i < _minimaps.size(); ++i) {
+ _minimaps[i].free();
+ }
+
if (version >= 6) {
_format.bytesPerPixel = rs->readByte();
_format.rLoss = rs->readByte();
@@ -309,11 +313,16 @@ bool MiniMapGump::loadData(Common::ReadStream *rs, uint32 version) {
_format.bShift = rs->readByte();
_format.aShift = rs->readByte();
- for (unsigned int i = 0; i < _minimaps.size(); ++i) {
+ uint32 mapcount = rs->readUint32LE();
+
+ // Integrity check
+ if (mapcount > _minimaps.size()) {
+ warning("Invalid minimap count in save: %d. Corrupt save?", mapcount);
+ return false;
+ }
+
+ for (unsigned int i = 0; i < mapcount; ++i) {
Graphics::Surface &minimap = _minimaps[i];
- if (i != rs->readByte()) {
- return false;
- }
uint w = rs->readUint16LE();
uint h = rs->readUint16LE();
@@ -326,10 +335,6 @@ bool MiniMapGump::loadData(Common::ReadStream *rs, uint32 version) {
}
}
}
- } else {
- for (unsigned int i = 0; i < _minimaps.size(); ++i) {
- _minimaps[i].free();
- }
}
return true;
}
Commit: 147b6cea0458dd5737bc8e59267bcede45373ebb
https://github.com/scummvm/scummvm/commit/147b6cea0458dd5737bc8e59267bcede45373ebb
Author: Matthew Jimenez (matthew.jimenez at outlook.com)
Date: 2022-12-07T17:02:23-06:00
Commit Message:
ULTIMA8: Reduce minimap pixel format to RGB5551
Changed paths:
engines/ultima/ultima8/gumps/minimap_gump.cpp
diff --git a/engines/ultima/ultima8/gumps/minimap_gump.cpp b/engines/ultima/ultima8/gumps/minimap_gump.cpp
index e45bf2e961a..de0cc1a3fa5 100644
--- a/engines/ultima/ultima8/gumps/minimap_gump.cpp
+++ b/engines/ultima/ultima8/gumps/minimap_gump.cpp
@@ -38,10 +38,10 @@ DEFINE_RUNTIME_CLASSTYPE_CODE(MiniMapGump)
MiniMapGump::MiniMapGump(int x, int y) :
Gump(x, y, MAP_NUM_CHUNKS * 2 + 2, MAP_NUM_CHUNKS * 2 + 2, 0,
- FLAG_DRAGGABLE, LAYER_NORMAL), _minimaps(MAX_NUM_MAPS), _format(4, 8, 8, 8, 8, 24, 16, 8, 0), _ax(0), _ay(0) {
+ FLAG_DRAGGABLE, LAYER_NORMAL), _minimaps(MAX_NUM_MAPS), _format(2, 5, 5, 5, 1, 11, 6, 1, 0), _ax(0), _ay(0) {
}
-MiniMapGump::MiniMapGump() : Gump(), _minimaps(MAX_NUM_MAPS), _format(4, 8, 8, 8, 8, 24, 16, 8, 0), _ax(0), _ay(0) {
+MiniMapGump::MiniMapGump() : Gump(), _minimaps(MAX_NUM_MAPS), _format(2, 5, 5, 5, 1, 11, 6, 1, 0), _ax(0), _ay(0) {
}
MiniMapGump::~MiniMapGump(void) {
@@ -283,9 +283,9 @@ void MiniMapGump::saveData(Common::WriteStream *ws) {
ws->writeUint16LE(minimap.w);
ws->writeUint16LE(minimap.h);
for (int y = 0; y < minimap.h; ++y) {
- const uint32 *pixels = (const uint32 *)minimap.getBasePtr(0, y);
+ const uint16 *pixels = (const uint16 *)minimap.getBasePtr(0, y);
for (int x = 0; x < minimap.w; ++x) {
- ws->writeUint32LE(*pixels++);
+ ws->writeUint16LE(*pixels++);
}
}
}
@@ -329,9 +329,9 @@ bool MiniMapGump::loadData(Common::ReadStream *rs, uint32 version) {
minimap.create(w, h, _format);
for (int y = 0; y < minimap.h; ++y) {
- uint32 *pixels = (uint32 *)minimap.getBasePtr(0, y);
+ uint16 *pixels = (uint16 *)minimap.getBasePtr(0, y);
for (int x = 0; x < minimap.w; ++x) {
- *pixels++ = rs->readUint32LE();
+ *pixels++ = rs->readUint16LE();
}
}
}
Commit: 2eed1485821e7133a197997615327d7030815004
https://github.com/scummvm/scummvm/commit/2eed1485821e7133a197997615327d7030815004
Author: Matthew Jimenez (matthew.jimenez at outlook.com)
Date: 2022-12-07T17:02:23-06:00
Commit Message:
ULTIMA8: Update minimap storage to use HashMap
Changed paths:
engines/ultima/ultima8/gumps/minimap_gump.cpp
engines/ultima/ultima8/gumps/minimap_gump.h
diff --git a/engines/ultima/ultima8/gumps/minimap_gump.cpp b/engines/ultima/ultima8/gumps/minimap_gump.cpp
index de0cc1a3fa5..42307565483 100644
--- a/engines/ultima/ultima8/gumps/minimap_gump.cpp
+++ b/engines/ultima/ultima8/gumps/minimap_gump.cpp
@@ -33,20 +33,20 @@ namespace Ultima8 {
DEFINE_RUNTIME_CLASSTYPE_CODE(MiniMapGump)
-#define MAX_NUM_MAPS 256
#define MINMAPGUMP_SCALE 8
MiniMapGump::MiniMapGump(int x, int y) :
Gump(x, y, MAP_NUM_CHUNKS * 2 + 2, MAP_NUM_CHUNKS * 2 + 2, 0,
- FLAG_DRAGGABLE, LAYER_NORMAL), _minimaps(MAX_NUM_MAPS), _format(2, 5, 5, 5, 1, 11, 6, 1, 0), _ax(0), _ay(0) {
+ FLAG_DRAGGABLE, LAYER_NORMAL), _minimaps(), _format(2, 5, 5, 5, 1, 11, 6, 1, 0), _ax(0), _ay(0) {
}
-MiniMapGump::MiniMapGump() : Gump(), _minimaps(MAX_NUM_MAPS), _format(2, 5, 5, 5, 1, 11, 6, 1, 0), _ax(0), _ay(0) {
+MiniMapGump::MiniMapGump() : Gump(), _minimaps(), _format(2, 5, 5, 5, 1, 11, 6, 1, 0), _ax(0), _ay(0) {
}
MiniMapGump::~MiniMapGump(void) {
- for (unsigned int i = 0; i < _minimaps.size(); ++i) {
- _minimaps[i].free();
+ Common::HashMap<uint32, Graphics::Surface>::iterator iter;
+ for (iter = _minimaps.begin(); iter != _minimaps.end(); ++iter) {
+ iter->_value.free();
}
}
@@ -119,8 +119,9 @@ void MiniMapGump::generate() {
}
void MiniMapGump::clear() {
- for (unsigned int i = 0; i < _minimaps.size(); ++i) {
- _minimaps[i].free();
+ Common::HashMap<uint32, Graphics::Surface>::iterator iter;
+ for (iter = _minimaps.begin(); iter != _minimaps.end(); ++iter) {
+ iter->_value.free();
}
}
@@ -278,8 +279,10 @@ void MiniMapGump::saveData(Common::WriteStream *ws) {
ws->writeByte(_format.aShift);
ws->writeUint32LE(static_cast<uint32>(_minimaps.size()));
- for (unsigned int i = 0; i < _minimaps.size(); ++i) {
- const Graphics::Surface &minimap = _minimaps[i];
+ Common::HashMap<uint32, Graphics::Surface>::const_iterator iter;
+ for (iter = _minimaps.begin(); iter != _minimaps.end(); ++iter) {
+ const Graphics::Surface &minimap = iter->_value;
+ ws->writeUint32LE(iter->_key);
ws->writeUint16LE(minimap.w);
ws->writeUint16LE(minimap.h);
for (int y = 0; y < minimap.h; ++y) {
@@ -298,8 +301,9 @@ bool MiniMapGump::loadData(Common::ReadStream *rs, uint32 version) {
_ax = 0;
_ay = 0;
- for (unsigned int i = 0; i < _minimaps.size(); ++i) {
- _minimaps[i].free();
+ Common::HashMap<uint32, Graphics::Surface>::iterator iter;
+ for (iter = _minimaps.begin(); iter != _minimaps.end(); ++iter) {
+ iter->_value.free();
}
if (version >= 6) {
@@ -313,16 +317,15 @@ bool MiniMapGump::loadData(Common::ReadStream *rs, uint32 version) {
_format.bShift = rs->readByte();
_format.aShift = rs->readByte();
- uint32 mapcount = rs->readUint32LE();
-
- // Integrity check
- if (mapcount > _minimaps.size()) {
- warning("Invalid minimap count in save: %d. Corrupt save?", mapcount);
+ if (_format.bytesPerPixel == 2) {
+ error("unsupported minimap texture format %d bpp", _format.bytesPerPixel);
return false;
}
- for (unsigned int i = 0; i < mapcount; ++i) {
- Graphics::Surface &minimap = _minimaps[i];
+ uint32 mapcount = rs->readUint32LE();
+ for (uint32 i = 0; i < mapcount; ++i) {
+ uint32 key = rs->readUint32LE();
+ Graphics::Surface &minimap = _minimaps[key];
uint w = rs->readUint16LE();
uint h = rs->readUint16LE();
diff --git a/engines/ultima/ultima8/gumps/minimap_gump.h b/engines/ultima/ultima8/gumps/minimap_gump.h
index a8fd2c1da74..b3b5edcf0bd 100644
--- a/engines/ultima/ultima8/gumps/minimap_gump.h
+++ b/engines/ultima/ultima8/gumps/minimap_gump.h
@@ -32,7 +32,7 @@ namespace Ultima8 {
class MiniMapGump : public Gump {
private:
- Common::Array<Graphics::Surface> _minimaps;
+ Common::HashMap<uint32, Graphics::Surface> _minimaps;
Graphics::PixelFormat _format;
int32 _ax, _ay;
Commit: a016f1497d88fa0ba49fdbffbcfa12e22d36eeb7
https://github.com/scummvm/scummvm/commit/a016f1497d88fa0ba49fdbffbcfa12e22d36eeb7
Author: Matthew Jimenez (matthew.jimenez at outlook.com)
Date: 2022-12-07T17:02:23-06:00
Commit Message:
ULTIMA8: Split minimap generation into a separate class from the gump
Changed paths:
A engines/ultima/ultima8/world/minimap.cpp
A engines/ultima/ultima8/world/minimap.h
engines/ultima/module.mk
engines/ultima/ultima8/gumps/minimap_gump.cpp
engines/ultima/ultima8/gumps/minimap_gump.h
engines/ultima/ultima8/misc/debugger.cpp
diff --git a/engines/ultima/module.mk b/engines/ultima/module.mk
index c1db87ee13b..ef4975bda08 100644
--- a/engines/ultima/module.mk
+++ b/engines/ultima/module.mk
@@ -535,6 +535,7 @@ MODULE_OBJS := \
ultima8/world/item_sorter.o \
ultima8/world/map.o \
ultima8/world/map_glob.o \
+ ultima8/world/minimap.o \
ultima8/world/missile_tracker.o \
ultima8/world/monster_egg.o \
ultima8/world/snap_process.o \
diff --git a/engines/ultima/ultima8/gumps/minimap_gump.cpp b/engines/ultima/ultima8/gumps/minimap_gump.cpp
index 42307565483..0e13b5da8d5 100644
--- a/engines/ultima/ultima8/gumps/minimap_gump.cpp
+++ b/engines/ultima/ultima8/gumps/minimap_gump.cpp
@@ -20,12 +20,11 @@
*/
#include "ultima/ultima8/gumps/minimap_gump.h"
+#include "ultima/ultima8/world/minimap.h"
+#include "ultima/ultima8/world/current_map.h"
#include "ultima/ultima8/world/world.h"
-#include "ultima/ultima8/graphics/shape.h"
-#include "ultima/ultima8/graphics/shape_frame.h"
#include "ultima/ultima8/world/actors/main_actor.h"
#include "ultima/ultima8/graphics/render_surface.h"
-#include "ultima/ultima8/graphics/palette.h"
#include "ultima/ultima8/world/get_object.h"
namespace Ultima {
@@ -33,20 +32,18 @@ namespace Ultima8 {
DEFINE_RUNTIME_CLASSTYPE_CODE(MiniMapGump)
-#define MINMAPGUMP_SCALE 8
-
MiniMapGump::MiniMapGump(int x, int y) :
Gump(x, y, MAP_NUM_CHUNKS * 2 + 2, MAP_NUM_CHUNKS * 2 + 2, 0,
- FLAG_DRAGGABLE, LAYER_NORMAL), _minimaps(), _format(2, 5, 5, 5, 1, 11, 6, 1, 0), _ax(0), _ay(0) {
+ FLAG_DRAGGABLE, LAYER_NORMAL), _minimaps(), _ax(0), _ay(0) {
}
-MiniMapGump::MiniMapGump() : Gump(), _minimaps(), _format(2, 5, 5, 5, 1, 11, 6, 1, 0), _ax(0), _ay(0) {
+MiniMapGump::MiniMapGump() : Gump(), _minimaps(), _ax(0), _ay(0) {
}
MiniMapGump::~MiniMapGump(void) {
- Common::HashMap<uint32, Graphics::Surface>::iterator iter;
+ Common::HashMap<uint32, MiniMap *>::iterator iter;
for (iter = _minimaps.begin(); iter != _minimaps.end(); ++iter) {
- iter->_value.free();
+ delete iter->_value;
}
}
@@ -74,37 +71,14 @@ void MiniMapGump::run() {
_ax = ax;
_ay = ay;
- update(currentmap);
-}
-void MiniMapGump::update(CurrentMap *currentmap) {
- int mapChunkSize = currentmap->getChunkSize();
-
- Graphics::Surface &minimap = _minimaps[currentmap->getNum()];
- if (minimap.w == 0 && minimap.h == 0) {
- minimap.create((MAP_NUM_CHUNKS * MINMAPGUMP_SCALE), (MAP_NUM_CHUNKS * MINMAPGUMP_SCALE), _format);
- }
+ uint32 mapNum = currentmap->getNum();
- // Draw into the map surface
- for (int x = 0; x < minimap.w; x++) {
- for (int y = 0; y < minimap.h; y++) {
- uint32 val = minimap.getPixel(x, y);
- if (val == 0) {
- int cx = x / MINMAPGUMP_SCALE;
- int cy = y / MINMAPGUMP_SCALE;
- if (currentmap->isChunkFast(cx, cy)) {
- int mx = (x * mapChunkSize) / MINMAPGUMP_SCALE;
- int my = (y * mapChunkSize) / MINMAPGUMP_SCALE;
-
- // Offset produces nicer samples but may need altering
- mx += mapChunkSize / (MINMAPGUMP_SCALE * 2);
- my += mapChunkSize / (MINMAPGUMP_SCALE * 2);
-
- val = sampleAtPoint(currentmap, mx, my);
- minimap.setPixel(x, y, val);
- }
- }
- }
+ MiniMap *minimap = _minimaps[mapNum];
+ if (!minimap) {
+ minimap = new MiniMap(mapNum);
+ _minimaps[mapNum] = minimap;
}
+ minimap->update(currentmap);
}
void MiniMapGump::generate() {
@@ -113,16 +87,22 @@ void MiniMapGump::generate() {
// TODO - do not leave whole map fast after generation
currentmap->setWholeMapFast();
- Graphics::Surface &minimap = _minimaps[currentmap->getNum()];
- minimap.free();
- update(currentmap);
+ uint32 mapNum = currentmap->getNum();
+
+ MiniMap *minimap = _minimaps[mapNum];
+ if (!minimap) {
+ minimap = new MiniMap(mapNum);
+ _minimaps[mapNum] = minimap;
+ }
+ minimap->update(currentmap);
}
void MiniMapGump::clear() {
- Common::HashMap<uint32, Graphics::Surface>::iterator iter;
+ Common::HashMap<uint32, MiniMap *>::iterator iter;
for (iter = _minimaps.begin(); iter != _minimaps.end(); ++iter) {
- iter->_value.free();
+ delete iter->_value;
}
+ _minimaps.clear();
}
void MiniMapGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled) {
@@ -147,27 +127,28 @@ void MiniMapGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled)
World *world = World::get_instance();
CurrentMap *currentmap = world->getCurrentMap();
- Graphics::ManagedSurface minimap(&_minimaps[currentmap->getNum()], DisposeAfterUse::NO);
+ MiniMap *minimap = _minimaps[currentmap->getNum()];
+ Graphics::ManagedSurface ms(minimap->getSurface(), DisposeAfterUse::NO);
Common::Rect r(sx, sy, sx + dims.width(), sy + dims.height());
if (r.left < 0) {
dx -= r.left;
r.left = 0;
}
- if (r.right > minimap.w) {
- r.right = minimap.w;
+ if (r.right > ms.w) {
+ r.right = ms.w;
}
if (r.top < 0) {
dy -= r.top;
r.top = 0;
}
- if (r.bottom > minimap.h) {
- r.bottom = minimap.h;
+ if (r.bottom > ms.h) {
+ r.bottom = ms.h;
}
if (!r.isEmpty()) {
- surf->Blit(minimap, r, dx, dy);
+ surf->Blit(ms, r, dx, dy);
}
int32 ax = _ax - sx;
@@ -180,117 +161,15 @@ void MiniMapGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled)
surf->Fill32(0xFFFFFF00, 1 + ax + 0, 1 + ay + 1, 1, 2);
}
-uint32 MiniMapGump::sampleAtPoint(CurrentMap *currentmap, int x, int y) {
- uint32 val = 0;
- const Item *item = currentmap->traceTopItem(x, y, 1 << 15, -1, 0, ShapeInfo::SI_ROOF | ShapeInfo::SI_OCCL | ShapeInfo::SI_LAND | ShapeInfo::SI_SEA);
- if (item) {
- val = sampleAtPoint(item, x, y);
- if (val == 0) {
- item = currentmap->traceTopItem(x, y, 1 << 15, -1, item->getObjId(), ShapeInfo::SI_ROOF | ShapeInfo::SI_OCCL | ShapeInfo::SI_LAND | ShapeInfo::SI_SEA);
- if (item) {
- val = sampleAtPoint(item, x, y);
- }
- }
-
- if (val == 0) {
- // set to avoid reprocessing
- val = _format.RGBToColor(0x00, 0x00, 0x00);
- }
- }
- return val;
-}
-
-uint32 MiniMapGump::sampleAtPoint(const Item *item, int x, int y) {
- int32 ix, iy, iz, idx, idy, idz;
- item->getLocation(ix, iy, iz);
- item->getFootpadWorld(idx, idy, idz);
-
- ix -= x;
- iy -= y;
-
- const Shape *sh = item->getShapeObject();
- if (!sh)
- return 0;
-
- const ShapeFrame *frame = sh->getFrame(item->getFrame());
- if (!frame)
- return 0;
-
- const Palette *pal = sh->getPalette();
- if (!pal)
- return 0;
-
- if (item->canDrag())
- return 0;
-
- // Screenspace bounding box bottom x_ coord (RNB x_ coord)
- int sx = (ix - iy) / 4;
- // Screenspace bounding box bottom extent (RNB y_ coord)
- int sy = (ix + iy) / 8 + idz;
-
- int w = 2;
- int h = 2;
-
- // Ensure sample is in bounds of frame
- if (frame->_xoff - sx < 0)
- sx = frame->_xoff;
- else if (frame->_xoff - sx >= frame->_width - w)
- sx = frame->_xoff - frame->_width + w;
-
- if (frame->_yoff - sy < 0)
- sy = frame->_yoff;
- else if (frame->_yoff - sy >= frame->_height - h)
- sy = frame->_yoff - frame->_height + h;
-
- uint16 r = 0, g = 0, b = 0, c = 0;
-
- for (int j = 0; j < w; j++) {
- for (int i = 0; i < h; i++) {
- if (!frame->hasPoint(i - sx, j - sy)) continue;
-
- byte r2, g2, b2;
- UNPACK_RGB8(pal->_native_untransformed[frame->getPixelAtPoint(i - sx, j - sy)], r2, g2, b2);
- r += RenderSurface::_gamma22toGamma10[r2];
- g += RenderSurface::_gamma22toGamma10[g2];
- b += RenderSurface::_gamma22toGamma10[b2];
- c++;
- }
- }
-
- if (c > 0) {
- return _format.RGBToColor(RenderSurface::_gamma10toGamma22[r / c], RenderSurface::_gamma10toGamma22[g / c], RenderSurface::_gamma10toGamma22[b / c]);
- }
-
- return 0;
-}
-
void MiniMapGump::saveData(Common::WriteStream *ws) {
Gump::saveData(ws);
- // Serialize the PixelFormat
- ws->writeByte(_format.bytesPerPixel);
- ws->writeByte(_format.rLoss);
- ws->writeByte(_format.gLoss);
- ws->writeByte(_format.bLoss);
- ws->writeByte(_format.aLoss);
- ws->writeByte(_format.rShift);
- ws->writeByte(_format.gShift);
- ws->writeByte(_format.bShift);
- ws->writeByte(_format.aShift);
-
ws->writeUint32LE(static_cast<uint32>(_minimaps.size()));
- Common::HashMap<uint32, Graphics::Surface>::const_iterator iter;
+ Common::HashMap<uint32, MiniMap *>::const_iterator iter;
for (iter = _minimaps.begin(); iter != _minimaps.end(); ++iter) {
- const Graphics::Surface &minimap = iter->_value;
+ const MiniMap *minimap = iter->_value;
ws->writeUint32LE(iter->_key);
- ws->writeUint16LE(minimap.w);
- ws->writeUint16LE(minimap.h);
- for (int y = 0; y < minimap.h; ++y) {
- const uint16 *pixels = (const uint16 *)minimap.getBasePtr(0, y);
- for (int x = 0; x < minimap.w; ++x) {
- ws->writeUint16LE(*pixels++);
- }
- }
+ minimap->save(ws);
}
}
@@ -301,42 +180,16 @@ bool MiniMapGump::loadData(Common::ReadStream *rs, uint32 version) {
_ax = 0;
_ay = 0;
- Common::HashMap<uint32, Graphics::Surface>::iterator iter;
- for (iter = _minimaps.begin(); iter != _minimaps.end(); ++iter) {
- iter->_value.free();
- }
-
- if (version >= 6) {
- _format.bytesPerPixel = rs->readByte();
- _format.rLoss = rs->readByte();
- _format.gLoss = rs->readByte();
- _format.bLoss = rs->readByte();
- _format.aLoss = rs->readByte();
- _format.rShift = rs->readByte();
- _format.gShift = rs->readByte();
- _format.bShift = rs->readByte();
- _format.aShift = rs->readByte();
-
- if (_format.bytesPerPixel == 2) {
- error("unsupported minimap texture format %d bpp", _format.bytesPerPixel);
- return false;
- }
+ clear();
+ if (version >= 6) {
uint32 mapcount = rs->readUint32LE();
for (uint32 i = 0; i < mapcount; ++i) {
- uint32 key = rs->readUint32LE();
- Graphics::Surface &minimap = _minimaps[key];
-
- uint w = rs->readUint16LE();
- uint h = rs->readUint16LE();
- minimap.create(w, h, _format);
-
- for (int y = 0; y < minimap.h; ++y) {
- uint16 *pixels = (uint16 *)minimap.getBasePtr(0, y);
- for (int x = 0; x < minimap.w; ++x) {
- *pixels++ = rs->readUint16LE();
- }
- }
+ uint32 mapNum = rs->readUint32LE();
+ MiniMap *minimap = new MiniMap(mapNum);
+ if (!minimap->load(rs, version))
+ return false;
+ _minimaps[mapNum] = minimap;
}
}
return true;
diff --git a/engines/ultima/ultima8/gumps/minimap_gump.h b/engines/ultima/ultima8/gumps/minimap_gump.h
index b3b5edcf0bd..1e70956cd29 100644
--- a/engines/ultima/ultima8/gumps/minimap_gump.h
+++ b/engines/ultima/ultima8/gumps/minimap_gump.h
@@ -23,22 +23,18 @@
#define ULTIMA8_GUMPS_MINIMAPGUMP_H
#include "ultima/ultima8/gumps/gump.h"
-#include "ultima/ultima8/world/current_map.h"
#include "ultima/ultima8/misc/classtype.h"
-#include "graphics/managed_surface.h"
namespace Ultima {
namespace Ultima8 {
+class MiniMap;
+
class MiniMapGump : public Gump {
private:
- Common::HashMap<uint32, Graphics::Surface> _minimaps;
- Graphics::PixelFormat _format;
+ Common::HashMap<uint32, MiniMap *> _minimaps;
int32 _ax, _ay;
- void update(CurrentMap *map);
- uint32 sampleAtPoint(CurrentMap *map, int x, int y);
- uint32 sampleAtPoint(const Item *item, int x, int y);
public:
ENABLE_RUNTIME_CLASSTYPE()
diff --git a/engines/ultima/ultima8/misc/debugger.cpp b/engines/ultima/ultima8/misc/debugger.cpp
index d1cf0d772d8..394c8f04790 100644
--- a/engines/ultima/ultima8/misc/debugger.cpp
+++ b/engines/ultima/ultima8/misc/debugger.cpp
@@ -42,6 +42,7 @@
#include "ultima/ultima8/misc/util.h"
#include "ultima/ultima8/usecode/uc_machine.h"
#include "ultima/ultima8/usecode/bit_set.h"
+#include "ultima/ultima8/world/current_map.h"
#include "ultima/ultima8/world/world.h"
#include "ultima/ultima8/world/camera_process.h"
#include "ultima/ultima8/world/get_object.h"
diff --git a/engines/ultima/ultima8/world/minimap.cpp b/engines/ultima/ultima8/world/minimap.cpp
new file mode 100644
index 00000000000..17b4d28e14c
--- /dev/null
+++ b/engines/ultima/ultima8/world/minimap.cpp
@@ -0,0 +1,212 @@
+/* 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/stream.h"
+
+#include "ultima/ultima8/world/minimap.h"
+#include "ultima/ultima8/world/current_map.h"
+#include "ultima/ultima8/world/item.h"
+#include "ultima/ultima8/graphics/render_surface.h"
+#include "ultima/ultima8/graphics/shape.h"
+#include "ultima/ultima8/graphics/shape_frame.h"
+#include "ultima/ultima8/graphics/palette.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+MiniMap::MiniMap(uint32 mapNum) : _mapNum(mapNum), _surface() {
+ _surface.create((MAP_NUM_CHUNKS * MINMAPGUMP_SCALE), (MAP_NUM_CHUNKS * MINMAPGUMP_SCALE),
+ Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0));
+}
+
+MiniMap::~MiniMap() {
+ _surface.free();
+}
+
+void MiniMap::update(CurrentMap *currentmap) {
+ int mapChunkSize = currentmap->getChunkSize();
+
+ // Draw into the map surface
+ for (int x = 0; x < _surface.w; x++) {
+ for (int y = 0; y < _surface.h; y++) {
+ uint32 val = _surface.getPixel(x, y);
+ if (val == 0) {
+ int cx = x / MINMAPGUMP_SCALE;
+ int cy = y / MINMAPGUMP_SCALE;
+ if (currentmap->isChunkFast(cx, cy)) {
+ int mx = (x * mapChunkSize) / MINMAPGUMP_SCALE;
+ int my = (y * mapChunkSize) / MINMAPGUMP_SCALE;
+
+ // Offset produces nicer samples but may need altering
+ mx += mapChunkSize / (MINMAPGUMP_SCALE * 2);
+ my += mapChunkSize / (MINMAPGUMP_SCALE * 2);
+
+ val = sampleAtPoint(currentmap, mx, my);
+ _surface.setPixel(x, y, val);
+ }
+ }
+ }
+ }
+}
+
+uint32 MiniMap::sampleAtPoint(CurrentMap *currentmap, int x, int y) {
+ uint32 val = 0;
+ const Item *item = currentmap->traceTopItem(x, y, 1 << 15, -1, 0, ShapeInfo::SI_ROOF | ShapeInfo::SI_OCCL | ShapeInfo::SI_LAND | ShapeInfo::SI_SEA);
+ if (item) {
+ val = sampleAtPoint(item, x, y);
+ if (val == 0) {
+ item = currentmap->traceTopItem(x, y, 1 << 15, -1, item->getObjId(), ShapeInfo::SI_ROOF | ShapeInfo::SI_OCCL | ShapeInfo::SI_LAND | ShapeInfo::SI_SEA);
+ if (item) {
+ val = sampleAtPoint(item, x, y);
+ }
+ }
+
+ if (val == 0) {
+ // set to avoid reprocessing
+ val = _surface.format.RGBToColor(0x00, 0x00, 0x00);
+ }
+ }
+ return val;
+}
+
+uint32 MiniMap::sampleAtPoint(const Item *item, int x, int y) {
+ int32 ix, iy, iz, idx, idy, idz;
+ item->getLocation(ix, iy, iz);
+ item->getFootpadWorld(idx, idy, idz);
+
+ ix -= x;
+ iy -= y;
+
+ const Shape *sh = item->getShapeObject();
+ if (!sh)
+ return 0;
+
+ const ShapeFrame *frame = sh->getFrame(item->getFrame());
+ if (!frame)
+ return 0;
+
+ const Palette *pal = sh->getPalette();
+ if (!pal)
+ return 0;
+
+ if (item->canDrag())
+ return 0;
+
+ // Screenspace bounding box bottom x_ coord (RNB x_ coord)
+ int sx = (ix - iy) / 4;
+ // Screenspace bounding box bottom extent (RNB y_ coord)
+ int sy = (ix + iy) / 8 + idz;
+
+ int w = 2;
+ int h = 2;
+
+ // Ensure sample is in bounds of frame
+ if (frame->_xoff - sx < 0)
+ sx = frame->_xoff;
+ else if (frame->_xoff - sx >= frame->_width - w)
+ sx = frame->_xoff - frame->_width + w;
+
+ if (frame->_yoff - sy < 0)
+ sy = frame->_yoff;
+ else if (frame->_yoff - sy >= frame->_height - h)
+ sy = frame->_yoff - frame->_height + h;
+
+ uint16 r = 0, g = 0, b = 0, c = 0;
+
+ for (int j = 0; j < w; j++) {
+ for (int i = 0; i < h; i++) {
+ if (!frame->hasPoint(i - sx, j - sy))
+ continue;
+
+ byte r2, g2, b2;
+ UNPACK_RGB8(pal->_native_untransformed[frame->getPixelAtPoint(i - sx, j - sy)], r2, g2, b2);
+ r += RenderSurface::_gamma22toGamma10[r2];
+ g += RenderSurface::_gamma22toGamma10[g2];
+ b += RenderSurface::_gamma22toGamma10[b2];
+ c++;
+ }
+ }
+
+ if (c > 0) {
+ return _surface.format.RGBToColor(RenderSurface::_gamma10toGamma22[r / c], RenderSurface::_gamma10toGamma22[g / c], RenderSurface::_gamma10toGamma22[b / c]);
+ }
+
+ return 0;
+}
+
+bool MiniMap::load(Common::ReadStream *rs, uint32 version) {
+ //_mapNum = rs->readUint32LE();
+ uint w = rs->readUint16LE();
+ uint h = rs->readUint16LE();
+
+ Graphics::PixelFormat format;
+ format.bytesPerPixel = rs->readByte();
+ format.rLoss = rs->readByte();
+ format.gLoss = rs->readByte();
+ format.bLoss = rs->readByte();
+ format.aLoss = rs->readByte();
+ format.rShift = rs->readByte();
+ format.gShift = rs->readByte();
+ format.bShift = rs->readByte();
+ format.aShift = rs->readByte();
+
+ if (format.bytesPerPixel != 2) {
+ error("unsupported minimap texture format %d bpp", format.bytesPerPixel);
+ return false;
+ }
+
+ _surface.create(w, h, format);
+ for (int y = 0; y < _surface.h; ++y) {
+ uint16 *pixels = (uint16 *)_surface.getBasePtr(0, y);
+ for (int x = 0; x < _surface.w; ++x) {
+ *pixels++ = rs->readUint16LE();
+ }
+ }
+ return true;
+}
+
+void MiniMap::save(Common::WriteStream *ws) const {
+ //ws->writeUint32LE(_mapNum);
+ ws->writeUint16LE(_surface.w);
+ ws->writeUint16LE(_surface.h);
+
+ // Serialize the PixelFormat
+ ws->writeByte(_surface.format.bytesPerPixel);
+ ws->writeByte(_surface.format.rLoss);
+ ws->writeByte(_surface.format.gLoss);
+ ws->writeByte(_surface.format.bLoss);
+ ws->writeByte(_surface.format.aLoss);
+ ws->writeByte(_surface.format.rShift);
+ ws->writeByte(_surface.format.gShift);
+ ws->writeByte(_surface.format.bShift);
+ ws->writeByte(_surface.format.aShift);
+
+ // Serialize the pixel data
+ for (int y = 0; y < _surface.h; ++y) {
+ const uint16 *pixels = (const uint16 *)_surface.getBasePtr(0, y);
+ for (int x = 0; x < _surface.w; ++x) {
+ ws->writeUint16LE(*pixels++);
+ }
+ }
+}
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
diff --git a/engines/ultima/ultima8/world/minimap.h b/engines/ultima/ultima8/world/minimap.h
new file mode 100644
index 00000000000..9648a665530
--- /dev/null
+++ b/engines/ultima/ultima8/world/minimap.h
@@ -0,0 +1,60 @@
+/* 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 "ultima/ultima8/misc/common_types.h"
+#include "graphics/surface.h"
+
+#ifndef ULTIMA8_WORLD_MAP_H
+#define ULTIMA8_WORLD_MAP_H
+
+namespace Ultima {
+namespace Ultima8 {
+
+class CurrentMap;
+class Item;
+
+#define MINMAPGUMP_SCALE 8
+
+class MiniMap {
+private:
+ uint32 _mapNum;
+ Graphics::Surface _surface;
+
+ uint32 sampleAtPoint(CurrentMap *map, int x, int y);
+ uint32 sampleAtPoint(const Item *item, int x, int y);
+
+public:
+ MiniMap(uint32 mapNum);
+ ~MiniMap();
+
+ void update(CurrentMap *map);
+
+ uint32 getMapNum() const { return _mapNum; }
+ Graphics::Surface *getSurface() { return &_surface; }
+
+ bool load(Common::ReadStream *rs, uint32 version);
+ void save(Common::WriteStream *ws) const;
+};
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
+
+#endif
Commit: c0fc6f583ed1487b04810f20ed6c43eefbcac554
https://github.com/scummvm/scummvm/commit/c0fc6f583ed1487b04810f20ed6c43eefbcac554
Author: Matthew Jimenez (matthew.jimenez at outlook.com)
Date: 2022-12-07T17:02:23-06:00
Commit Message:
ULTIMA8: Crop saved minimap surfaces to non-black area.
Changed paths:
engines/ultima/ultima8/gumps/minimap_gump.cpp
engines/ultima/ultima8/world/minimap.cpp
engines/ultima/ultima8/world/minimap.h
diff --git a/engines/ultima/ultima8/gumps/minimap_gump.cpp b/engines/ultima/ultima8/gumps/minimap_gump.cpp
index 0e13b5da8d5..47bba5dfecd 100644
--- a/engines/ultima/ultima8/gumps/minimap_gump.cpp
+++ b/engines/ultima/ultima8/gumps/minimap_gump.cpp
@@ -127,7 +127,14 @@ void MiniMapGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled)
World *world = World::get_instance();
CurrentMap *currentmap = world->getCurrentMap();
- MiniMap *minimap = _minimaps[currentmap->getNum()];
+ uint32 mapNum = currentmap->getNum();
+
+ MiniMap *minimap = _minimaps[mapNum];
+ if (!minimap) {
+ minimap = new MiniMap(mapNum);
+ _minimaps[mapNum] = minimap;
+ }
+
Graphics::ManagedSurface ms(minimap->getSurface(), DisposeAfterUse::NO);
Common::Rect r(sx, sy, sx + dims.width(), sy + dims.height());
diff --git a/engines/ultima/ultima8/world/minimap.cpp b/engines/ultima/ultima8/world/minimap.cpp
index 17b4d28e14c..8b2482f12fb 100644
--- a/engines/ultima/ultima8/world/minimap.cpp
+++ b/engines/ultima/ultima8/world/minimap.cpp
@@ -152,10 +152,76 @@ uint32 MiniMap::sampleAtPoint(const Item *item, int x, int y) {
return 0;
}
+const Common::Rect MiniMap::getCropBounds() const {
+ Common::Rect bounds;
+ uint32 mask = _surface.format.ARGBToColor(0x00, 0xFF, 0xFF, 0xFF);
+
+ // Get top & initial rect
+ bool found = false;
+ for (int y = 0; !found && y < _surface.h; y++) {
+ for (int x = 0; !found && x < _surface.w; x++) {
+ uint32 val = _surface.getPixel(x, y);
+ if ((val & mask) != 0) {
+ bounds.top = y;
+ bounds.bottom = y + 1;
+ bounds.left = x;
+ bounds.right = x + 1;
+ found = true;
+ }
+ }
+ }
+
+ // Get bottom & extend left / right
+ found = false;
+ for (int y = _surface.h - 1; !found && y > bounds.top; y--) {
+ for (int x = 0; !found && x < _surface.w; x++) {
+ uint32 val = _surface.getPixel(x, y);
+ if ((val & mask) != 0) {
+ bounds.bottom = y + 1;
+ if (x < bounds.left)
+ bounds.left = x;
+ if (x > bounds.right)
+ bounds.right = x + 1;
+ found = true;
+ }
+ }
+ }
+
+ // Get left
+ found = false;
+ for (int x = 0; !found && x < bounds.left; x++) {
+ for (int y = bounds.top; !found && y < bounds.bottom; y++) {
+ uint32 val = _surface.getPixel(x, y);
+ if ((val & mask) != 0) {
+ bounds.left = x;
+ found = true;
+ }
+ }
+ }
+
+ // Get right
+ found = false;
+ for (int x = _surface.w - 1; !found && x > bounds.right; x--) {
+ for (int y = bounds.top; !found && y < bounds.bottom; y++) {
+ uint32 val = _surface.getPixel(x, y);
+ if ((val & mask) != 0) {
+ bounds.right = x + 1;
+ found = true;
+ }
+ }
+ }
+
+ return bounds;
+}
+
bool MiniMap::load(Common::ReadStream *rs, uint32 version) {
//_mapNum = rs->readUint32LE();
- uint w = rs->readUint16LE();
- uint h = rs->readUint16LE();
+
+ Common::Rect bounds;
+ bounds.left = rs->readUint16LE();
+ bounds.top = rs->readUint16LE();
+ bounds.right = rs->readUint16LE();
+ bounds.bottom = rs->readUint16LE();
Graphics::PixelFormat format;
format.bytesPerPixel = rs->readByte();
@@ -173,10 +239,12 @@ bool MiniMap::load(Common::ReadStream *rs, uint32 version) {
return false;
}
+ uint16 w = _surface.w;
+ uint16 h = _surface.h;
_surface.create(w, h, format);
- for (int y = 0; y < _surface.h; ++y) {
- uint16 *pixels = (uint16 *)_surface.getBasePtr(0, y);
- for (int x = 0; x < _surface.w; ++x) {
+ for (int y = bounds.top; y < bounds.bottom; ++y) {
+ uint16 *pixels = (uint16 *)_surface.getBasePtr(bounds.left, y);
+ for (int x = bounds.left; x < bounds.right; ++x) {
*pixels++ = rs->readUint16LE();
}
}
@@ -185,8 +253,12 @@ bool MiniMap::load(Common::ReadStream *rs, uint32 version) {
void MiniMap::save(Common::WriteStream *ws) const {
//ws->writeUint32LE(_mapNum);
- ws->writeUint16LE(_surface.w);
- ws->writeUint16LE(_surface.h);
+
+ Common::Rect bounds = getCropBounds();
+ ws->writeUint16LE(bounds.left);
+ ws->writeUint16LE(bounds.top);
+ ws->writeUint16LE(bounds.right);
+ ws->writeUint16LE(bounds.bottom);
// Serialize the PixelFormat
ws->writeByte(_surface.format.bytesPerPixel);
@@ -200,9 +272,9 @@ void MiniMap::save(Common::WriteStream *ws) const {
ws->writeByte(_surface.format.aShift);
// Serialize the pixel data
- for (int y = 0; y < _surface.h; ++y) {
- const uint16 *pixels = (const uint16 *)_surface.getBasePtr(0, y);
- for (int x = 0; x < _surface.w; ++x) {
+ for (int y = bounds.top; y < bounds.bottom; ++y) {
+ const uint16 *pixels = (const uint16 *)_surface.getBasePtr(bounds.left, y);
+ for (int x = bounds.left; x < bounds.right; ++x) {
ws->writeUint16LE(*pixels++);
}
}
diff --git a/engines/ultima/ultima8/world/minimap.h b/engines/ultima/ultima8/world/minimap.h
index 9648a665530..226865992d2 100644
--- a/engines/ultima/ultima8/world/minimap.h
+++ b/engines/ultima/ultima8/world/minimap.h
@@ -41,6 +41,7 @@ private:
uint32 sampleAtPoint(CurrentMap *map, int x, int y);
uint32 sampleAtPoint(const Item *item, int x, int y);
+ const Common::Rect getCropBounds() const;
public:
MiniMap(uint32 mapNum);
~MiniMap();
Commit: 559e954eda7813f257c3b84604cc722b81bf0b2c
https://github.com/scummvm/scummvm/commit/559e954eda7813f257c3b84604cc722b81bf0b2c
Author: Matthew Jimenez (matthew.jimenez at outlook.com)
Date: 2022-12-07T17:02:23-06:00
Commit Message:
ULTIMA8: Small cleanup for finding minimap bounds
Changed paths:
engines/ultima/ultima8/world/minimap.cpp
diff --git a/engines/ultima/ultima8/world/minimap.cpp b/engines/ultima/ultima8/world/minimap.cpp
index 8b2482f12fb..6adc096cd55 100644
--- a/engines/ultima/ultima8/world/minimap.cpp
+++ b/engines/ultima/ultima8/world/minimap.cpp
@@ -153,60 +153,61 @@ uint32 MiniMap::sampleAtPoint(const Item *item, int x, int y) {
}
const Common::Rect MiniMap::getCropBounds() const {
- Common::Rect bounds;
+ Common::Rect bounds(_surface.w, _surface.h);
uint32 mask = _surface.format.ARGBToColor(0x00, 0xFF, 0xFF, 0xFF);
- // Get top & initial rect
- bool found = false;
- for (int y = 0; !found && y < _surface.h; y++) {
- for (int x = 0; !found && x < _surface.w; x++) {
+ // Get left
+ for (int x = bounds.left; x < bounds.right; x++) {
+ for (int y = bounds.top; y < bounds.bottom; y++) {
uint32 val = _surface.getPixel(x, y);
if ((val & mask) != 0) {
- bounds.top = y;
- bounds.bottom = y + 1;
bounds.left = x;
- bounds.right = x + 1;
- found = true;
+
+ // end loops
+ x = bounds.right;
+ y = bounds.bottom;
}
}
}
- // Get bottom & extend left / right
- found = false;
- for (int y = _surface.h - 1; !found && y > bounds.top; y--) {
- for (int x = 0; !found && x < _surface.w; x++) {
+ // Get top
+ for (int y = bounds.top; y < bounds.bottom; y++) {
+ for (int x = bounds.left; x < bounds.right; x++) {
uint32 val = _surface.getPixel(x, y);
if ((val & mask) != 0) {
- bounds.bottom = y + 1;
- if (x < bounds.left)
- bounds.left = x;
- if (x > bounds.right)
- bounds.right = x + 1;
- found = true;
+ bounds.top = y;
+
+ // end loops
+ x = bounds.right;
+ y = bounds.bottom;
}
}
}
- // Get left
- found = false;
- for (int x = 0; !found && x < bounds.left; x++) {
- for (int y = bounds.top; !found && y < bounds.bottom; y++) {
+ // Get right
+ for (int x = bounds.right - 1; x > bounds.left; x--) {
+ for (int y = bounds.bottom - 1; y > bounds.top; y--) {
uint32 val = _surface.getPixel(x, y);
if ((val & mask) != 0) {
- bounds.left = x;
- found = true;
+ bounds.right = x + 1;
+
+ // end loops
+ x = bounds.left;
+ y = bounds.top;
}
}
}
- // Get right
- found = false;
- for (int x = _surface.w - 1; !found && x > bounds.right; x--) {
- for (int y = bounds.top; !found && y < bounds.bottom; y++) {
+ // Get bottom
+ for (int y = bounds.bottom - 1; y > bounds.top; y--) {
+ for (int x = bounds.right - 1; x > bounds.left; x--) {
uint32 val = _surface.getPixel(x, y);
if ((val & mask) != 0) {
- bounds.right = x + 1;
- found = true;
+ bounds.bottom = y + 1;
+
+ // end loops
+ x = bounds.left;
+ y = bounds.top;
}
}
}
Commit: c6654065d2f268365469a0fb0d62d191d90cc455
https://github.com/scummvm/scummvm/commit/c6654065d2f268365469a0fb0d62d191d90cc455
Author: Matthew Jimenez (matthew.jimenez at outlook.com)
Date: 2022-12-07T17:02:23-06:00
Commit Message:
ULTIMA8: Fix incorrect header define for minimap.h
Changed paths:
engines/ultima/ultima8/world/minimap.h
diff --git a/engines/ultima/ultima8/world/minimap.h b/engines/ultima/ultima8/world/minimap.h
index 226865992d2..bfb90844d72 100644
--- a/engines/ultima/ultima8/world/minimap.h
+++ b/engines/ultima/ultima8/world/minimap.h
@@ -22,8 +22,8 @@
#include "ultima/ultima8/misc/common_types.h"
#include "graphics/surface.h"
-#ifndef ULTIMA8_WORLD_MAP_H
-#define ULTIMA8_WORLD_MAP_H
+#ifndef ULTIMA8_WORLD_MINIMAP_H
+#define ULTIMA8_WORLD_MINIMAP_H
namespace Ultima {
namespace Ultima8 {
More information about the Scummvm-git-logs
mailing list