[Scummvm-git-logs] scummvm master -> 7423e9258007491b730cc1acb1826d1c20f844b2
elasota
noreply at scummvm.org
Sat Jun 10 21:56:41 UTC 2023
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
7423e92580 MTROPOLIS: Add hack to fix black square in MTI's MPZ-1000 screen
Commit: 7423e9258007491b730cc1acb1826d1c20f844b2
https://github.com/scummvm/scummvm/commit/7423e9258007491b730cc1acb1826d1c20f844b2
Author: elasota (ejlasota at gmail.com)
Date: 2023-06-10T17:55:57-04:00
Commit Message:
MTROPOLIS: Add hack to fix black square in MTI's MPZ-1000 screen
Changed paths:
engines/mtropolis/assets.cpp
engines/mtropolis/assets.h
engines/mtropolis/elements.cpp
engines/mtropolis/hacks.cpp
engines/mtropolis/hacks.h
diff --git a/engines/mtropolis/assets.cpp b/engines/mtropolis/assets.cpp
index 658fc7513e5..02b5b61e941 100644
--- a/engines/mtropolis/assets.cpp
+++ b/engines/mtropolis/assets.cpp
@@ -143,11 +143,12 @@ MToonMetadata::MToonMetadata() : imageFormat(kImageFormatWindows), bitsPerPixel(
CachedMToon::RleFrame::RleFrame() : version(0), width(0), height(0), isKeyframe(0) {
}
-CachedMToon::CachedMToon() : _isRLETemporalCompressed(false) {
+CachedMToon::CachedMToon() : _isRLETemporalCompressed(false), _hackFlags(0) {
}
-bool CachedMToon::loadFromStream(const Common::SharedPtr<MToonMetadata> &metadata, Common::ReadStream *stream, size_t size) {
+bool CachedMToon::loadFromStream(const Common::SharedPtr<MToonMetadata> &metadata, Common::ReadStream *stream, size_t size, uint hackFlags) {
_metadata = metadata;
+ _hackFlags = hackFlags;
Common::Array<uint8> data;
data.resize(size);
@@ -207,7 +208,7 @@ void CachedMToon::decompressFrames(const Common::Array<uint8> &data) {
}
template<class TNumber, uint32 TLiteralMask, uint32 TTransparentRowSkipMask>
-bool CachedMToon::decompressMToonRLE(const RleFrame &frame, const Common::Array<TNumber> &coefsArray, Graphics::ManagedSurface &surface, bool isBottomUp) {
+bool CachedMToon::decompressMToonRLE(const RleFrame &frame, const Common::Array<TNumber> &coefsArray, Graphics::ManagedSurface &surface, bool isBottomUp, uint hackFlags) {
assert(sizeof(TNumber) == surface.format.bytesPerPixel);
size_t size = coefsArray.size();
@@ -244,7 +245,12 @@ bool CachedMToon::decompressMToonRLE(const RleFrame &frame, const Common::Array<
if (transparentCountCode & TTransparentRowSkipMask) {
// Vertical skip
- y += (transparentCountCode - TTransparentRowSkipMask);
+ uint32 skipAmount = transparentCountCode - TTransparentRowSkipMask;
+
+ if ((hackFlags & MToonHackFlags::kMTIHispaniolaMPZHack) && (transparentCountCode - TTransparentRowSkipMask) == (TTransparentRowSkipMask - 2))
+ skipAmount = 0;
+
+ y += skipAmount;
x = 0;
if (y < h) {
rowData = static_cast<TNumber *>(surface.getBasePtr(0, isBottomUp ? (h - 1 - y) : y));
@@ -303,11 +309,11 @@ void CachedMToon::decompressRLEFrameToImage(size_t frameIndex, Graphics::Managed
bool decompressedOK = false;
if (_rleOptimizedFormat.bytesPerPixel == 4) {
- decompressedOK = decompressMToonRLE<uint32, 0x80000000u, 0x80000000u>(_rleData[frameIndex], _rleData[frameIndex].data32, surface, isBottomUp);
+ decompressedOK = decompressMToonRLE<uint32, 0x80000000u, 0x80000000u>(_rleData[frameIndex], _rleData[frameIndex].data32, surface, isBottomUp, _hackFlags);
} else if (_rleOptimizedFormat.bytesPerPixel == 2) {
- decompressedOK = decompressMToonRLE<uint16, 0x8000u, 0x8000u>(_rleData[frameIndex], _rleData[frameIndex].data16, surface, isBottomUp);
+ decompressedOK = decompressMToonRLE<uint16, 0x8000u, 0x8000u>(_rleData[frameIndex], _rleData[frameIndex].data16, surface, isBottomUp, _hackFlags);
} else if (_rleOptimizedFormat.bytesPerPixel == 1) {
- decompressedOK = decompressMToonRLE<uint8, 0x80u, 0x80u>(_rleData[frameIndex], _rleData[frameIndex].data8, surface, isBottomUp);
+ decompressedOK = decompressMToonRLE<uint8, 0x80u, 0x80u>(_rleData[frameIndex], _rleData[frameIndex].data8, surface, isBottomUp, _hackFlags);
} else
error("Unknown mToon encoding");
@@ -502,7 +508,7 @@ void CachedMToon::decompressQuickTimeFrame(const Common::Array<uint8> &data, siz
}
template<class TSrcNumber, uint32 TSrcLiteralMask, uint32 TSrcTransparentSkipMask, class TDestNumber, uint32 TDestLiteralMask, uint32 TDestTransparentSkipMask>
-void CachedMToon::rleReformat(RleFrame &frame, const Common::Array<TSrcNumber> &srcData, const Graphics::PixelFormat &srcFormatRef, Common::Array<TDestNumber> &destData, const Graphics::PixelFormat &destFormatRef) {
+void CachedMToon::rleReformat(RleFrame &frame, const Common::Array<TSrcNumber> &srcData, const Graphics::PixelFormat &srcFormatRef, Common::Array<TDestNumber> &destData, const Graphics::PixelFormat &destFormatRef, uint hackFlags) {
const Graphics::PixelFormat srcFormat = srcFormatRef;
const Graphics::PixelFormat destFormat = destFormatRef;
@@ -594,14 +600,14 @@ void CachedMToon::optimizeRLE(const Graphics::PixelFormat &targetFormatRef) {
for (size_t i = 0; i < numFrames; i++) {
if (_rleInternalFormat.bytesPerPixel == 2) {
if (targetFormat.bytesPerPixel == 4)
- rleReformat<uint16, 0x8000u, 0x8000u, uint32, 0x80000000u, 0x80000000u>(_rleData[i], _rleData[i].data16, _rleInternalFormat, _rleData[i].data32, targetFormat);
+ rleReformat<uint16, 0x8000u, 0x8000u, uint32, 0x80000000u, 0x80000000u>(_rleData[i], _rleData[i].data16, _rleInternalFormat, _rleData[i].data32, targetFormat, _hackFlags);
else if (targetFormat.bytesPerPixel == 2)
- rleReformat<uint16, 0x8000u, 0x8000u, uint16, 0x8000u, 0x8000u>(_rleData[i], _rleData[i].data16, _rleInternalFormat, _rleData[i].data16, targetFormat);
+ rleReformat<uint16, 0x8000u, 0x8000u, uint16, 0x8000u, 0x8000u>(_rleData[i], _rleData[i].data16, _rleInternalFormat, _rleData[i].data16, targetFormat, _hackFlags);
} else if (_rleInternalFormat.bytesPerPixel == 4) {
if (targetFormat.bytesPerPixel == 4)
- rleReformat<uint32, 0x80000000u, 0x80000000u, uint32, 0x80000000u, 0x80000000u>(_rleData[i], _rleData[i].data32, _rleInternalFormat, _rleData[i].data32, targetFormat);
+ rleReformat<uint32, 0x80000000u, 0x80000000u, uint32, 0x80000000u, 0x80000000u>(_rleData[i], _rleData[i].data32, _rleInternalFormat, _rleData[i].data32, targetFormat, _hackFlags);
else if (targetFormat.bytesPerPixel == 2)
- rleReformat<uint32, 0x80000000u, 0x80000000u, uint16, 0x8000u, 0x8000u>(_rleData[i], _rleData[i].data32, _rleInternalFormat, _rleData[i].data16, targetFormat);
+ rleReformat<uint32, 0x80000000u, 0x80000000u, uint16, 0x8000u, 0x8000u>(_rleData[i], _rleData[i].data32, _rleInternalFormat, _rleData[i].data16, targetFormat, _hackFlags);
}
}
@@ -644,11 +650,11 @@ void CachedMToon::getOrRenderFrame(uint32 prevFrame, uint32 targetFrame, Common:
for (size_t i = firstFrameToRender; i <= targetFrame; i++) {
if (_rleOptimizedFormat.bytesPerPixel == 1)
- decompressMToonRLE<uint8, 0x80u, 0x80u>(_rleData[i], _rleData[i].data8, *surface, isBottomUp);
+ decompressMToonRLE<uint8, 0x80u, 0x80u>(_rleData[i], _rleData[i].data8, *surface, isBottomUp, _hackFlags);
else if (_rleOptimizedFormat.bytesPerPixel == 2)
- decompressMToonRLE<uint16, 0x8000u, 0x8000u>(_rleData[i], _rleData[i].data16, *surface, isBottomUp);
+ decompressMToonRLE<uint16, 0x8000u, 0x8000u>(_rleData[i], _rleData[i].data16, *surface, isBottomUp, _hackFlags);
else if (_rleOptimizedFormat.bytesPerPixel == 4)
- decompressMToonRLE<uint32, 0x80000000u, 0x80000000u>(_rleData[i], _rleData[i].data32, *surface, isBottomUp);
+ decompressMToonRLE<uint32, 0x80000000u, 0x80000000u>(_rleData[i], _rleData[i].data32, *surface, isBottomUp, _hackFlags);
}
}
}
@@ -657,8 +663,6 @@ const Common::SharedPtr<MToonMetadata>& CachedMToon::getMetadata() const {
return _metadata;
}
-
-
AudioMetadata::AudioMetadata() : encoding(kEncodingUncompressed), durationMSec(0),
sampleRate(0), channels(0), bitsPerSample(0), isBigEndian(false) {
}
@@ -1097,11 +1101,14 @@ bool MToonAsset::load(AssetLoaderContext &context, const Data::MToonAsset &data)
return true;
}
+MToonAsset::MToonAsset() : _frameDataPosition(0), _sizeOfFrameData(0), _streamIndex(0){
+}
+
AssetType MToonAsset::getAssetType() const {
return kAssetTypeMToon;
}
-const Common::SharedPtr<CachedMToon> &MToonAsset::loadAndCacheMToon(Runtime *runtime) {
+const Common::SharedPtr<CachedMToon> &MToonAsset::loadAndCacheMToon(Runtime *runtime, uint hackFlags) {
if (_cachedMToon)
return _cachedMToon;
@@ -1117,7 +1124,7 @@ const Common::SharedPtr<CachedMToon> &MToonAsset::loadAndCacheMToon(Runtime *run
return _cachedMToon;
}
- if (!cachedMToon->loadFromStream(_metadata, stream, _sizeOfFrameData)) {
+ if (!cachedMToon->loadFromStream(_metadata, stream, _sizeOfFrameData, hackFlags)) {
warning("mToon data failed to load");
return _cachedMToon;
}
diff --git a/engines/mtropolis/assets.h b/engines/mtropolis/assets.h
index 2c076cad766..1a4b7218acb 100644
--- a/engines/mtropolis/assets.h
+++ b/engines/mtropolis/assets.h
@@ -59,6 +59,14 @@ private:
Common::Array<uint8> _data;
};
+namespace MToonHackFlags {
+
+enum MToonHackFlag {
+ kMTIHispaniolaMPZHack = 1,
+};
+
+} // End of namespace MToonHackFlags
+
struct MToonMetadata {
enum ImageFormat {
kImageFormatMac,
@@ -106,7 +114,7 @@ class CachedMToon {
public:
CachedMToon();
- bool loadFromStream(const Common::SharedPtr<MToonMetadata> &metadata, Common::ReadStream *stream, size_t size);
+ bool loadFromStream(const Common::SharedPtr<MToonMetadata> &metadata, Common::ReadStream *stream, size_t size, uint hackFlags);
void optimize(Runtime *runtime);
@@ -141,10 +149,10 @@ private:
void decompressQuickTimeFrame(const Common::Array<uint8> &data, size_t frameIndex);
template<class TSrcNumber, uint32 TSrcLiteralMask, uint32 TSrcTransparentSkipMask, class TDestNumber, uint32 TDestLiteralMask, uint32 TDestTransparentSkipMask>
- void rleReformat(RleFrame &frame, const Common::Array<TSrcNumber> &srcData, const Graphics::PixelFormat &srcFormatRef, Common::Array<TDestNumber> &destData, const Graphics::PixelFormat &destFormatRef);
+ void rleReformat(RleFrame &frame, const Common::Array<TSrcNumber> &srcData, const Graphics::PixelFormat &srcFormatRef, Common::Array<TDestNumber> &destData, const Graphics::PixelFormat &destFormatRef, uint hackFlags);
template<class TNumber, uint32 TLiteralMask, uint32 TTransparentRowSkipMask>
- static bool decompressMToonRLE(const RleFrame &frame, const Common::Array<TNumber> &coefsArray, Graphics::ManagedSurface &surface, bool isBottomUp);
+ static bool decompressMToonRLE(const RleFrame &frame, const Common::Array<TNumber> &coefsArray, Graphics::ManagedSurface &surface, bool isBottomUp, uint hackFlags);
Common::Array<RleFrame> _rleData;
bool _isRLETemporalCompressed;
@@ -156,6 +164,8 @@ private:
Graphics::PixelFormat _rleOptimizedFormat;
Common::SharedPtr<MToonMetadata> _metadata;
+
+ uint _hackFlags;
};
struct AudioMetadata {
@@ -281,10 +291,12 @@ private:
struct MToonAsset : public Asset {
public:
+ MToonAsset();
+
bool load(AssetLoaderContext &context, const Data::MToonAsset &data);
AssetType getAssetType() const override;
- const Common::SharedPtr<CachedMToon> &loadAndCacheMToon(Runtime *runtime);
+ const Common::SharedPtr<CachedMToon> &loadAndCacheMToon(Runtime *runtime, uint hackFlags);
private:
uint32 _frameDataPosition;
diff --git a/engines/mtropolis/elements.cpp b/engines/mtropolis/elements.cpp
index 31a73e9b544..89110dbf9c0 100644
--- a/engines/mtropolis/elements.cpp
+++ b/engines/mtropolis/elements.cpp
@@ -1340,7 +1340,12 @@ void MToonElement::activate() {
return;
}
- _cachedMToon = static_cast<MToonAsset *>(asset.get())->loadAndCacheMToon(getRuntime());
+ uint hackFlags = 0;
+ if (getRuntime()->getHacks().mtiHispaniolaMToonHack && project->getAssetNameByID(_assetID) == "G00_HispaniolaMPZ.TUN") {
+ hackFlags |= MToonHackFlags::kMTIHispaniolaMPZHack;
+ }
+
+ _cachedMToon = static_cast<MToonAsset *>(asset.get())->loadAndCacheMToon(getRuntime(), hackFlags);
_metadata = _cachedMToon->getMetadata();
_playMediaSignaller = project->notifyOnPlayMedia(this);
diff --git a/engines/mtropolis/hacks.cpp b/engines/mtropolis/hacks.cpp
index 1bcf01908f0..751d484934f 100644
--- a/engines/mtropolis/hacks.cpp
+++ b/engines/mtropolis/hacks.cpp
@@ -44,6 +44,7 @@ Hacks::Hacks() {
allowAssetsFromOtherScenes = false;
mtiVariableReferencesHack = false;
mtiSceneReturnHack = false;
+ mtiHispaniolaMToonHack = false;
}
Hacks::~Hacks() {
@@ -1054,6 +1055,10 @@ void addMTIQuirks(const MTropolisGameDescription &desc, Hacks &hacks) {
// scene, which is supposed to activate a scene transtion modifier in the scene that transitions to itself.
// This doesn't work because the modifier is gone when the scene is unloaded.
hacks.mtiSceneReturnHack = true;
+
+ // Weird rendering bug in the MTZ-1000 Hispaniola mToon, it has a skip code that would normally skip 127 rows but
+ // doing that causes a big hole in the image.
+ hacks.mtiHispaniolaMToonHack = true;
}
} // End of namespace HackSuites
diff --git a/engines/mtropolis/hacks.h b/engines/mtropolis/hacks.h
index b1751c7a2a8..743c0a32f7d 100644
--- a/engines/mtropolis/hacks.h
+++ b/engines/mtropolis/hacks.h
@@ -54,6 +54,7 @@ struct Hacks {
bool allowAssetsFromOtherScenes;
bool mtiVariableReferencesHack;
bool mtiSceneReturnHack;
+ bool mtiHispaniolaMToonHack;
uint midiVolumeScale; // 256 = 1.0
More information about the Scummvm-git-logs
mailing list