[Scummvm-git-logs] scummvm master -> c489eb2e50408c35fd6d604165c3a81d8de47b5a
elasota
noreply at scummvm.org
Tue Jul 19 23:18:33 UTC 2022
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:
c489eb2e50 MTROPOLIS: Use pre-menu screenshot for savegame thumbnail in Obsidian
Commit: c489eb2e50408c35fd6d604165c3a81d8de47b5a
https://github.com/scummvm/scummvm/commit/c489eb2e50408c35fd6d604165c3a81d8de47b5a
Author: elasota (ejlasota at gmail.com)
Date: 2022-07-19T19:17:53-04:00
Commit Message:
MTROPOLIS: Use pre-menu screenshot for savegame thumbnail in Obsidian
Changed paths:
engines/mtropolis/hacks.cpp
engines/mtropolis/hacks.h
engines/mtropolis/metaengine.cpp
engines/mtropolis/modifiers.cpp
engines/mtropolis/mtropolis.cpp
engines/mtropolis/mtropolis.h
engines/mtropolis/runtime.cpp
engines/mtropolis/runtime.h
engines/mtropolis/saveload.cpp
engines/mtropolis/saveload.h
diff --git a/engines/mtropolis/hacks.cpp b/engines/mtropolis/hacks.cpp
index d263bac2b61..2ab5807dcbf 100644
--- a/engines/mtropolis/hacks.cpp
+++ b/engines/mtropolis/hacks.cpp
@@ -22,6 +22,7 @@
#include "common/system.h"
#include "common/hashmap.h"
+#include "graphics/managed_surface.h"
#include "graphics/surface.h"
#include "mtropolis/assets.h"
@@ -364,6 +365,35 @@ void ObsidianRSGLogoWidescreenHooks::onCreate(Structural *structural) {
movie->setResizeFilter(Common::SharedPtr<MovieResizeFilter>(new ObsidianRSGLogoAnamorphicFilter()));
}
+class ObsidianSaveScreenshotHooks : public SceneTransitionHooks {
+public:
+ void onSceneTransitionSetup(Runtime *runtime, const Common::WeakPtr<Structural> &oldScene, const Common::WeakPtr<Structural> &newScene) override;
+};
+
+void ObsidianSaveScreenshotHooks::onSceneTransitionSetup(Runtime *runtime, const Common::WeakPtr<Structural> &oldScene, const Common::WeakPtr<Structural> &newScene) {
+ Structural *newScenePtr = newScene.lock().get();
+
+ if (!newScenePtr)
+ return;
+
+ if (newScenePtr->getName() == "Game_Screen") {
+ Window *mainWindow = runtime->getMainWindow().lock().get();
+ if (mainWindow) {
+ Common::SharedPtr<Graphics::ManagedSurface> mainWindowSurface = mainWindow->getSurface();
+ Common::SharedPtr<Graphics::Surface> screenshot(new Graphics::Surface());
+ screenshot->copyFrom(*mainWindowSurface);
+
+ runtime->setSaveScreenshotOverride(screenshot);
+ }
+ } else {
+ runtime->setSaveScreenshotOverride(Common::SharedPtr<Graphics::Surface>());
+ }
+}
+
+void addObsidianQuirks(const MTropolisGameDescription &desc, Hacks &hacks) {
+ hacks.addSceneTransitionHooks(Common::SharedPtr<SceneTransitionHooks>(new ObsidianSaveScreenshotHooks()));
+}
+
void addObsidianBugFixes(const MTropolisGameDescription &desc, Hacks &hacks) {
// Workaround for bug in Obsidian:
// When opening the journal in the intro, a script checks if cGSt.cfst.binjournal is false and if so,
diff --git a/engines/mtropolis/hacks.h b/engines/mtropolis/hacks.h
index 804e204ce60..8df373e9a99 100644
--- a/engines/mtropolis/hacks.h
+++ b/engines/mtropolis/hacks.h
@@ -63,6 +63,7 @@ struct Hacks {
namespace HackSuites {
+void addObsidianQuirks(const MTropolisGameDescription &desc, Hacks &hacks);
void addObsidianBugFixes(const MTropolisGameDescription &desc, Hacks &hacks);
void addObsidianAutoSaves(const MTropolisGameDescription &desc, Hacks &hacks, IAutoSaveProvider *autoSaveProvider);
void addObsidianImprovedWidescreen(const MTropolisGameDescription &desc, Hacks &hacks);
diff --git a/engines/mtropolis/metaengine.cpp b/engines/mtropolis/metaengine.cpp
index 11d99973d3f..107b787d609 100644
--- a/engines/mtropolis/metaengine.cpp
+++ b/engines/mtropolis/metaengine.cpp
@@ -19,19 +19,29 @@
*
*/
+#include "common/translation.h"
+
#include "engines/advancedDetector.h"
#include "backends/keymapper/action.h"
#include "backends/keymapper/keymap.h"
-#include "common/translation.h"
+#include "graphics/scaler.h"
+#include "graphics/surface.h"
#include "mtropolis/actions.h"
#include "mtropolis/debug.h"
#include "mtropolis/detection.h"
+#include "mtropolis/mtropolis.h"
#include "mtropolis/mtropolis.h"
+namespace Graphics {
+
+struct Surface;
+
+} // End of namespace Graphics
+
namespace MTropolis {
uint32 MTropolisEngine::getGameID() const {
@@ -58,6 +68,8 @@ public:
Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override;
Common::Array<Common::Keymap *> initKeymaps(const char *target) const override;
+
+ void getSavegameThumbnail(Graphics::Surface &thumb) override;
};
bool MTropolisMetaEngine::hasFeature(MetaEngineFeature f) const {
@@ -86,7 +98,7 @@ bool MTropolis::MTropolisEngine::hasFeature(EngineFeature f) const {
}
Common::Error MTropolisMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
- *engine = new MTropolis::MTropolisEngine(syst, (const MTropolis::MTropolisGameDescription *)desc);
+ *engine = new MTropolis::MTropolisEngine(syst, reinterpret_cast<const MTropolis::MTropolisGameDescription *>(desc));
return Common::kNoError;
}
@@ -103,6 +115,96 @@ Common::Array<Common::Keymap *> MTropolisMetaEngine::initKeymaps(const char *tar
return Common::Keymap::arrayOf(keymap);
}
+void MTropolisMetaEngine::getSavegameThumbnail(Graphics::Surface &thumb) {
+ const Graphics::Surface *savegameScreenshot = static_cast<MTropolis::MTropolisEngine *>(g_engine)->getSavegameScreenshot();
+
+ if (savegameScreenshot) {
+ int thumbnailWidth = kThumbnailWidth;
+ int thumbnailHeight = thumbnailWidth * savegameScreenshot->h / savegameScreenshot->w;
+ if (thumbnailHeight > kThumbnailHeight2) {
+ thumbnailHeight = kThumbnailHeight2;
+ thumbnailWidth = thumbnailHeight * savegameScreenshot->w / savegameScreenshot->h;
+ }
+
+ Common::SharedPtr<Graphics::Surface> outSurface(new Graphics::Surface());
+ outSurface->create(savegameScreenshot->w, savegameScreenshot->h, Graphics::createPixelFormat<888>());
+
+ for (int y = 0; y < savegameScreenshot->h; y++) {
+ for (int x = 0; x < savegameScreenshot->w; x++) {
+ uint8 r, g, b;
+ savegameScreenshot->format.colorToRGB(savegameScreenshot->getPixel(x, y), r, g, b);
+ outSurface->setPixel(x, y, outSurface->format.RGBToColor(r, g, b));
+ }
+ }
+
+ while (outSurface->w >= thumbnailWidth * 2) {
+ Common::SharedPtr<Graphics::Surface> temp(new Graphics::Surface());
+ temp->create(outSurface->w / 2, outSurface->h, Graphics::createPixelFormat<888>());
+
+ for (int y = 0; y < temp->h; y++) {
+ for (int x = 0; x < temp->w; x++) {
+ uint32 px1 = outSurface->getPixel(x * 2, y);
+ uint32 px2 = outSurface->getPixel(x * 2 + 1, y);
+
+ uint8 r1, g1, b1;
+ outSurface->format.colorToRGB(px1, r1, g1, b1);
+
+ uint8 r2, g2, b2;
+ outSurface->format.colorToRGB(px2, r2, g2, b2);
+
+ temp->setPixel(x, y, temp->format.RGBToColor((r1 + r2) >> 1, (g1 + g2) >> 1, (b1 + b2) >> 1));
+ }
+ }
+
+ outSurface = temp;
+ }
+
+ while (outSurface->h >= thumbnailHeight * 2) {
+ Common::SharedPtr<Graphics::Surface> temp(new Graphics::Surface());
+ temp->create(outSurface->w, outSurface->h / 2, Graphics::createPixelFormat<888>());
+
+ for (int y = 0; y < temp->h; y++) {
+ for (int x = 0; x < temp->w; x++) {
+ uint32 px1 = outSurface->getPixel(x, y * 2);
+ uint32 px2 = outSurface->getPixel(x, y * 2 + 1);
+
+ uint8 r1, g1, b1;
+ outSurface->format.colorToRGB(px1, r1, g1, b1);
+
+ uint8 r2, g2, b2;
+ outSurface->format.colorToRGB(px2, r2, g2, b2);
+
+ temp->setPixel(x, y, temp->format.RGBToColor((r1 + r2) >> 1, (g1 + g2) >> 1, (b1 + b2) >> 1));
+ }
+ }
+
+ outSurface = temp;
+ }
+
+ // TODO: Fix this for weird sizes
+ Common::SharedPtr<Graphics::Surface> changeTo16Temp = outSurface;
+ outSurface.reset(new Graphics::Surface());
+ outSurface->create(changeTo16Temp->w, changeTo16Temp->h, Graphics::createPixelFormat<565>());
+
+ for (int y = 0; y < outSurface->h; y++) {
+ for (int x = 0; x < outSurface->w; x++) {
+ uint32 px = changeTo16Temp->getPixel(x, y);
+
+ uint8 r, g, b;
+ changeTo16Temp->format.colorToRGB(px, r, g, b);
+
+ outSurface->setPixel(x, y, outSurface->format.RGBToColor(r, g, b));
+ }
+ }
+
+ changeTo16Temp.reset();
+
+ thumb.copyFrom(*outSurface);
+ } else {
+ AdvancedMetaEngine::getSavegameThumbnail(thumb);
+ }
+}
+
#if PLUGIN_ENABLED_DYNAMIC(MTROPOLIS)
REGISTER_PLUGIN_DYNAMIC(MTROPOLIS, PLUGIN_TYPE_ENGINE, MTropolisMetaEngine);
#else
diff --git a/engines/mtropolis/modifiers.cpp b/engines/mtropolis/modifiers.cpp
index 845ffe04ef6..10291c26020 100644
--- a/engines/mtropolis/modifiers.cpp
+++ b/engines/mtropolis/modifiers.cpp
@@ -277,7 +277,7 @@ VThreadState SaveAndRestoreModifier::consumeMessage(Runtime *runtime, const Comm
if (_saveWhen.respondsTo(msg->getEvent())) {
CompoundVarSaver saver(obj);
- if (runtime->getSaveProvider()->promptSave(&saver)) {
+ if (runtime->getSaveProvider()->promptSave(&saver, runtime->getSaveScreenshotOverride().get())) {
for (const Common::SharedPtr<SaveLoadHooks> &hooks : runtime->getHacks().saveLoadHooks)
hooks->onSave(runtime, this, static_cast<Modifier *>(obj));
}
diff --git a/engines/mtropolis/mtropolis.cpp b/engines/mtropolis/mtropolis.cpp
index 70d318f6b86..0b9e8e0f5de 100644
--- a/engines/mtropolis/mtropolis.cpp
+++ b/engines/mtropolis/mtropolis.cpp
@@ -119,6 +119,7 @@ Common::Error MTropolisEngine::run() {
preferredColorDepthMode = kColorDepthMode16Bit;
enhancedColorDepthMode = kColorDepthMode32Bit;
+ HackSuites::addObsidianQuirks(*_gameDescription, _runtime->getHacks());
HackSuites::addObsidianBugFixes(*_gameDescription, _runtime->getHacks());
if (ConfMan.getBool("mtropolis_mod_auto_save"))
diff --git a/engines/mtropolis/mtropolis.h b/engines/mtropolis/mtropolis.h
index 73dfac59ba3..c014eb939de 100644
--- a/engines/mtropolis/mtropolis.h
+++ b/engines/mtropolis/mtropolis.h
@@ -59,10 +59,12 @@ public:
uint16 getVersion() const;
Common::Platform getPlatform() const;
- bool promptSave(ISaveWriter *writer) override;
+ bool promptSave(ISaveWriter *writer, const Graphics::Surface *screenshotOverride) override;
bool autoSave(ISaveWriter *writer) override;
bool promptLoad(ISaveReader *reader) override;
+ const Graphics::Surface *getSavegameScreenshot() const;
+
public:
void handleEvents();
diff --git a/engines/mtropolis/runtime.cpp b/engines/mtropolis/runtime.cpp
index d994cba6973..c3503483e32 100644
--- a/engines/mtropolis/runtime.cpp
+++ b/engines/mtropolis/runtime.cpp
@@ -3728,6 +3728,10 @@ Runtime::SceneStackEntry::SceneStackEntry() {
SceneTransitionHooks::~SceneTransitionHooks() {
}
+
+void SceneTransitionHooks::onSceneTransitionSetup(Runtime *runtime, const Common::WeakPtr<Structural> &oldScene, const Common::WeakPtr<Structural> &newScene) {
+}
+
void SceneTransitionHooks::onSceneTransitionEnded(Runtime *runtime, const Common::WeakPtr<Structural> &newScene) {
}
@@ -4258,6 +4262,9 @@ void Runtime::executeCompleteTransitionToScene(const Common::SharedPtr<Structura
Common::SharedPtr<Structural> targetSharedScene = findDefaultSharedSceneForScene(targetScene.get());
+ for (const Common::SharedPtr<SceneTransitionHooks> &hooks : _hacks.sceneTransitionHooks)
+ hooks->onSceneTransitionSetup(this, _activeMainScene, targetScene);
+
if (targetScene == targetSharedScene)
error("Transitioned into a default shared scene, this is not supported");
@@ -5673,6 +5680,18 @@ const Common::String *Runtime::resolveAttributeIDName(uint32 attribID) const {
return &it->_value;
}
+const Common::WeakPtr<Window> &Runtime::getMainWindow() const {
+ return _mainWindow;
+}
+
+const Common::SharedPtr<Graphics::Surface> &Runtime::getSaveScreenshotOverride() const {
+ return _saveScreenshotOverride;
+}
+
+void Runtime::setSaveScreenshotOverride(const Common::SharedPtr<Graphics::Surface> &screenshot) {
+ _saveScreenshotOverride = screenshot;
+}
+
void Runtime::ensureMainWindowExists() {
// Maybe there's a better spot for this
if (_mainWindow.expired() && _project) {
diff --git a/engines/mtropolis/runtime.h b/engines/mtropolis/runtime.h
index 684fcc599b8..1cfcb235d73 100644
--- a/engines/mtropolis/runtime.h
+++ b/engines/mtropolis/runtime.h
@@ -1472,6 +1472,7 @@ class SceneTransitionHooks {
public:
virtual ~SceneTransitionHooks();
+ virtual void onSceneTransitionSetup(Runtime *runtime, const Common::WeakPtr<Structural> &oldScene, const Common::WeakPtr<Structural> &newScene);
virtual void onSceneTransitionEnded(Runtime *runtime, const Common::WeakPtr<Structural> &newScene);
};
@@ -1595,6 +1596,11 @@ public:
const Common::String *resolveAttributeIDName(uint32 attribID) const;
+ const Common::WeakPtr<Window> &getMainWindow() const;
+
+ const Common::SharedPtr<Graphics::Surface> &getSaveScreenshotOverride() const;
+ void setSaveScreenshotOverride(const Common::SharedPtr<Graphics::Surface> &screenshot);
+
#ifdef MTROPOLIS_DEBUG_ENABLE
void debugSetEnabled(bool enabled);
void debugBreak();
@@ -1758,8 +1764,10 @@ private:
Scheduler _scheduler;
OSystem *_system;
Audio::Mixer *_mixer;
+
ISaveUIProvider *_saveProvider;
ILoadUIProvider *_loadProvider;
+ Common::SharedPtr<Graphics::Surface> _saveScreenshotOverride;
Common::SharedPtr<CursorGraphic> _lastFrameCursor;
Common::SharedPtr<CursorGraphic> _defaultCursor;
diff --git a/engines/mtropolis/saveload.cpp b/engines/mtropolis/saveload.cpp
index 0ae46092663..52ba0d41897 100644
--- a/engines/mtropolis/saveload.cpp
+++ b/engines/mtropolis/saveload.cpp
@@ -27,6 +27,7 @@
#include "gui/saveload.h"
#include "mtropolis/mtropolis.h"
+#include "mtropolis/render.h"
#include "mtropolis/runtime.h"
namespace MTropolis {
@@ -57,7 +58,7 @@ void SaveLoadHooks::onLoad(Runtime *runtime, Modifier *saveLoadModifier, Modifie
void SaveLoadHooks::onSave(Runtime *runtime, Modifier *saveLoadModifier, Modifier *varModifier) {
}
-bool MTropolisEngine::promptSave(ISaveWriter *writer) {
+bool MTropolisEngine::promptSave(ISaveWriter *writer, const Graphics::Surface *screenshotOverride) {
Common::String desc;
int slot;
@@ -159,4 +160,16 @@ bool MTropolisEngine::autoSave(ISaveWriter *writer) {
return true;
}
+const Graphics::Surface *MTropolisEngine::getSavegameScreenshot() const {
+ const Graphics::Surface *screenshotOverride = _runtime->getSaveScreenshotOverride().get();
+ if (screenshotOverride)
+ return screenshotOverride;
+ else {
+ Window *mainWindow = _runtime->getMainWindow().lock().get();
+ if (!mainWindow)
+ return nullptr;
+ return mainWindow->getSurface().get()->surfacePtr();
+ }
+}
+
} // End of namespace MTropolis
diff --git a/engines/mtropolis/saveload.h b/engines/mtropolis/saveload.h
index 6ef2e173799..ea9bed54f48 100644
--- a/engines/mtropolis/saveload.h
+++ b/engines/mtropolis/saveload.h
@@ -31,6 +31,12 @@ class WriteStream;
} // End of namespace Common
+namespace Graphics {
+
+struct Surface;
+
+} // End of namespace Graphics
+
namespace MTropolis {
class Modifier;
@@ -46,7 +52,7 @@ struct ISaveReader : public IInterfaceBase {
};
struct ISaveUIProvider : public IInterfaceBase {
- virtual bool promptSave(ISaveWriter *writer) = 0;
+ virtual bool promptSave(ISaveWriter *writer, const Graphics::Surface *screenshotOverride) = 0;
};
struct ILoadUIProvider : public IInterfaceBase {
More information about the Scummvm-git-logs
mailing list