[Scummvm-git-logs] scummvm master -> 614ae2c8c922b46e3ea5d6c101a67b60f5eb6a60
bluegr
noreply at scummvm.org
Sun Jun 30 10:05:05 UTC 2024
This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
478cd8925a SCI: (SCI0) - add support for CGA and Hercules render modes
a1e6ac6811 SCI: fix undithering option and disable it for CGA/Hercules
614ae2c8c9 SCI: formatting
Commit: 478cd8925a76a7373d663e85602219c9e577a0d8
https://github.com/scummvm/scummvm/commit/478cd8925a76a7373d663e85602219c9e577a0d8
Author: athrxx (athrxx at scummvm.org)
Date: 2024-06-30T13:05:01+03:00
Commit Message:
SCI: (SCI0) - add support for CGA and Hercules render modes
(as per usual, each target has to be run once to upgrade the launcher
options, so that the new render modes can actually be selected)
Changed paths:
A engines/sci/detection_internal.h
A engines/sci/graphics/gfxdrivers.cpp
A engines/sci/graphics/gfxdrivers.h
engines/sci/detection.cpp
engines/sci/engine/kgraphics.cpp
engines/sci/event.cpp
engines/sci/graphics/cursor.cpp
engines/sci/graphics/palette.cpp
engines/sci/graphics/palette.h
engines/sci/graphics/screen.cpp
engines/sci/graphics/screen.h
engines/sci/metaengine.cpp
engines/sci/module.mk
engines/sci/sci.cpp
diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp
index b9934fe026d..47abac3944f 100644
--- a/engines/sci/detection.cpp
+++ b/engines/sci/detection.cpp
@@ -30,6 +30,7 @@
#include "gui/widgets/popup.h"
#include "sci/detection.h"
+#include "sci/detection_internal.h"
#include "sci/dialogs.h"
#include "sci/graphics/helpers_detection_enums.h"
#include "sci/sci.h"
@@ -213,12 +214,30 @@ public:
return "Sierra's Creative Interpreter (C) Sierra Online";
}
+ DetectedGames detectGames(const Common::FSList &fslist, uint32 skipADFlags, bool skipIncomplete) override;
+
ADDetectedGame fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist, ADDetectedGameExtraInfo **extra) const override;
private:
void addFileToDetectedGame(const Common::Path &name, const FileMap &allFiles, MD5Properties md5Prop, ADDetectedGame &game) const;
};
+DetectedGames SciMetaEngineDetection::detectGames(const Common::FSList &fslist, uint32 skipADFlags, bool skipIncomplete) {
+ DetectedGames games = AdvancedMetaEngineDetection::detectGames(fslist, skipADFlags, skipIncomplete);
+
+ for (DetectedGame &game : games) {
+ const GameIdStrToEnum *g = s_gameIdStrToEnum;
+ for (; g->gameidStr; ++g) {
+ if (game.gameId.equals(g->gameidStr))
+ break;
+ }
+ game.setGUIOptions(customizeGuiOptions(fslist.begin()->getParent().getPath(), parseGameGUIOptions(game.getGUIOptions()), g->version));
+ game.appendGUIOptions(getGameGUIOptionsDescriptionLanguage(game.language));
+ }
+
+ return games;
+}
+
ADDetectedGame SciMetaEngineDetection::fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist, ADDetectedGameExtraInfo **extra) const {
/**
* Fallback detection for Sci heavily depends on engine resources, so it's not possible
diff --git a/engines/sci/detection_internal.h b/engines/sci/detection_internal.h
new file mode 100644
index 00000000000..7061c2c653b
--- /dev/null
+++ b/engines/sci/detection_internal.h
@@ -0,0 +1,157 @@
+/* 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/>.
+ *
+ */
+
+#ifndef SCI_DETECTION_INTERNAL_H
+#define SCI_DETECTION_INTERNAL_H
+
+#include "common/fs.h"
+#include "common/path.h"
+
+#include "sci/detection.h"
+#include "sci/version.h"
+
+namespace Sci {
+
+struct GameIdStrToEnum {
+ const char *gameidStr;
+ const char *sierraIdStr;
+ SciGameId gameidEnum;
+ bool isSci32;
+ SciVersion version;
+};
+
+static const GameIdStrToEnum s_gameIdStrToEnum[] = {
+ {"astrochicken", "", GID_ASTROCHICKEN, false, SCI_VERSION_NONE}, // Sierra ID is "sq3", distinguished by resource count
+ {"camelot", "arthur", GID_CAMELOT, false, SCI_VERSION_NONE},
+ {"castlebrain", "brain", GID_CASTLEBRAIN, false, SCI_VERSION_1_LATE}, // Amiga is SCI1 middle, PC SCI1 late
+ {"chest", "archive", GID_CHEST, true, SCI_VERSION_NONE},
+ {"christmas1988", "demo", GID_CHRISTMAS1988, false, SCI_VERSION_0_EARLY},
+ {"christmas1990", "card", GID_CHRISTMAS1990, false, SCI_VERSION_1_EARLY},
+ {"christmas1992", "card", GID_CHRISTMAS1992, false, SCI_VERSION_1_1},
+ {"cnick-kq", "", GID_CNICK_KQ, false, SCI_VERSION_NONE}, // Sierra ID is "hoyle3", distinguished by resource count
+ {"cnick-laurabow", "", GID_CNICK_LAURABOW, false, SCI_VERSION_NONE},
+ {"cnick-longbow", "RH Budget", GID_CNICK_LONGBOW, false, SCI_VERSION_NONE},
+ {"cnick-lsl", "", GID_CNICK_LSL, false, SCI_VERSION_NONE}, // Sierra ID is "lsl1", distinguished by resource count
+ {"cnick-sq", "", GID_CNICK_SQ, false, SCI_VERSION_NONE}, // Sierra ID is "sq4", distinguished by resource count
+ {"ecoquest", "eco", GID_ECOQUEST, false, SCI_VERSION_NONE},
+ {"ecoquest2", "rain", GID_ECOQUEST2, false, SCI_VERSION_NONE},
+ {"fairytales", "tales", GID_FAIRYTALES, false, SCI_VERSION_NONE},
+ {"freddypharkas", "fp", GID_FREDDYPHARKAS, false, SCI_VERSION_NONE},
+ {"funseeker", "emc", GID_FUNSEEKER, false, SCI_VERSION_NONE},
+ {"gk1demo", "", GID_GK1DEMO, false, SCI_VERSION_NONE},
+ {"gk1", "gk", GID_GK1, true, SCI_VERSION_NONE},
+ {"gk2", "gk2", GID_GK2, true, SCI_VERSION_NONE},
+ {"hoyle1", "cardgames", GID_HOYLE1, false, SCI_VERSION_NONE},
+ {"hoyle2", "solitaire", GID_HOYLE2, false, SCI_VERSION_NONE},
+ {"hoyle3", "hoyle3", GID_HOYLE3, false, SCI_VERSION_NONE},
+ {"hoyle4", "hoyle4", GID_HOYLE4, false, SCI_VERSION_1_1},
+ {"hoyle5", "hoyle4", GID_HOYLE5, true, SCI_VERSION_2_1_MIDDLE},
+ {"hoyle5bridge", "", GID_HOYLE5, true, SCI_VERSION_2_1_MIDDLE},
+ {"hoyle5children", "", GID_HOYLE5, true, SCI_VERSION_2_1_MIDDLE},
+ {"hoyle5school", "", GID_HOYLE5, true, SCI_VERSION_2_1_MIDDLE},
+ {"hoyle5solitaire", "", GID_HOYLE5, true, SCI_VERSION_2_1_MIDDLE},
+ {"iceman", "iceman", GID_ICEMAN, false, SCI_VERSION_NONE},
+ {"inndemo", "", GID_INNDEMO, false, SCI_VERSION_NONE},
+ {"islandbrain", "brain", GID_ISLANDBRAIN, false, SCI_VERSION_1_1},
+ {"jones", "jones", GID_JONES, false, SCI_VERSION_1_1},
+ {"kq1sci", "kq1", GID_KQ1, false, SCI_VERSION_NONE},
+ {"kq4sci", "kq4", GID_KQ4, false, SCI_VERSION_NONE},
+ {"kq5", "kq5", GID_KQ5, false, SCI_VERSION_NONE},
+ {"kq6", "kq6", GID_KQ6, false, SCI_VERSION_NONE},
+ {"kq7", "kq7cd", GID_KQ7, true, SCI_VERSION_NONE},
+ {"kquestions", "quizgame-demo", GID_KQUESTIONS, true, SCI_VERSION_NONE},
+ {"laurabow", "cb1", GID_LAURABOW, false, SCI_VERSION_NONE},
+ {"laurabow2", "lb2", GID_LAURABOW2, false, SCI_VERSION_NONE},
+ {"lighthouse", "lite", GID_LIGHTHOUSE, true, SCI_VERSION_NONE},
+ {"longbow", "longbow", GID_LONGBOW, false, SCI_VERSION_NONE},
+ {"lsl1sci", "lsl1", GID_LSL1, false, SCI_VERSION_NONE},
+ {"lsl2", "lsl2", GID_LSL2, false, SCI_VERSION_NONE},
+ {"lsl3", "lsl3", GID_LSL3, false, SCI_VERSION_NONE},
+ {"lsl5", "lsl5", GID_LSL5, false, SCI_VERSION_NONE},
+ {"lsl6", "lsl6", GID_LSL6, false, SCI_VERSION_NONE},
+ {"lsl6hires", "", GID_LSL6HIRES, true, SCI_VERSION_NONE},
+ {"lsl7", "l7", GID_LSL7, true, SCI_VERSION_NONE},
+ {"mothergoose", "mg", GID_MOTHERGOOSE, false, SCI_VERSION_NONE},
+ {"mothergoose256", "", GID_MOTHERGOOSE256, false, SCI_VERSION_NONE},
+ {"mothergoosehires", "", GID_MOTHERGOOSEHIRES, true, SCI_VERSION_NONE},
+ {"msastrochicken", "", GID_MSASTROCHICKEN, false, SCI_VERSION_NONE}, // Sierra ID is "sq4", distinguished by resource count
+ {"pepper", "twisty", GID_PEPPER, false, SCI_VERSION_NONE},
+ {"phantasmagoria", "scary", GID_PHANTASMAGORIA, true, SCI_VERSION_NONE},
+ {"phantasmagoria2", "p2", GID_PHANTASMAGORIA2, true, SCI_VERSION_NONE},
+ {"pq1sci", "pq1", GID_PQ1, false, SCI_VERSION_NONE},
+ {"pq2", "pq", GID_PQ2, false, SCI_VERSION_NONE},
+ {"pq3", "pq3", GID_PQ3, false, SCI_VERSION_NONE},
+ {"pq4", "pq4", GID_PQ4, true, SCI_VERSION_NONE},
+ {"pq4demo", "", GID_PQ4DEMO, false, SCI_VERSION_NONE},
+ {"pqswat", "swat", GID_PQSWAT, true, SCI_VERSION_NONE},
+ {"qfg1", "gfg1", GID_QFG1, false, SCI_VERSION_NONE},
+ {"qfg1vga", "", GID_QFG1VGA, false, SCI_VERSION_NONE}, // Sierra ID is "glory", distinguished by resources
+ {"qfg2", "trial", GID_QFG2, false, SCI_VERSION_NONE},
+ {"qfg3", "", GID_QFG3, false, SCI_VERSION_NONE}, // Sierra ID is "glory", distinguished by resources
+ {"qfg4", "", GID_QFG4, true, SCI_VERSION_NONE}, // Sierra ID is "glory", distinguished by resources
+ {"qfg4demo", "", GID_QFG4DEMO, false, SCI_VERSION_NONE}, // Sierra ID is "glory", distinguished by resources
+ {"rama", "rama", GID_RAMA, true, SCI_VERSION_NONE},
+ {"sci-fanmade", "", GID_FANMADE, false, SCI_VERSION_NONE},
+ {"shivers", "", GID_SHIVERS, true, SCI_VERSION_NONE},
+ //{ "shivers2", "shivers2", GID_SHIVERS2, true, SCI_VERSION_NONE }, // Not SCI
+ {"slater", "thegame", GID_SLATER, false, SCI_VERSION_NONE},
+ {"sq1sci", "sq1", GID_SQ1, false, SCI_VERSION_NONE},
+ {"sq3", "sq3", GID_SQ3, false, SCI_VERSION_NONE},
+ {"sq4", "sq4", GID_SQ4, false, SCI_VERSION_NONE},
+ {"sq5", "sq5", GID_SQ5, false, SCI_VERSION_NONE},
+ {"sq6", "sq6", GID_SQ6, true, SCI_VERSION_NONE},
+ {"torin", "torin", GID_TORIN, true, SCI_VERSION_NONE},
+ {nullptr, nullptr, GID_ALL, false, SCI_VERSION_NONE}
+};
+
+static Common::String customizeGuiOptions(Common::Path gamePath, Common::String guiOptions, SciVersion version) {
+ struct RMode {
+ SciVersion min;
+ SciVersion max;
+ const char gfxDriverName[13];
+ const char *guio;
+ } rmodes[] = {
+ { SCI_VERSION_0_EARLY, SCI_VERSION_1_EGA_ONLY, "EGA320.DRV", GUIO_RENDEREGA },
+ { SCI_VERSION_0_EARLY, SCI_VERSION_1_EGA_ONLY, "CGA320C.DRV", GUIO_RENDERCGA },
+ { SCI_VERSION_0_EARLY, SCI_VERSION_1_EGA_ONLY, "CGA320BW.DRV", GUIO_RENDERCGABW },
+ { SCI_VERSION_0_EARLY, SCI_VERSION_1_EGA_ONLY, "CGA320M.DRV", GUIO_RENDERCGABW },
+ { SCI_VERSION_0_EARLY, SCI_VERSION_1_EGA_ONLY, "HERCMONO.DRV", GUIO_RENDERHERCAMBER },
+ { SCI_VERSION_0_EARLY, SCI_VERSION_1_EGA_ONLY, "HERCMONO.DRV", GUIO_RENDERHERCGREEN }
+ };
+
+ Common::FSNode node(gamePath);
+
+ if (!node.exists()) {
+ warning("Game path '%s' could not be accessed", gamePath.toString().c_str());
+ return guiOptions;
+ }
+
+ for (int i = 0; i < ARRAYSIZE(rmodes); i++) {
+ if ((version == SCI_VERSION_NONE || (version >= rmodes[i].min && version <= rmodes[i].max)) && node.getChild(rmodes[i].gfxDriverName).exists())
+ guiOptions += rmodes[i].guio;
+ }
+
+ return guiOptions;
+}
+
+} // End of namespace Sci
+
+#endif
diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp
index 0ee704e8c46..a975e17a6d5 100644
--- a/engines/sci/engine/kgraphics.cpp
+++ b/engines/sci/engine/kgraphics.cpp
@@ -43,6 +43,7 @@
#include "sci/graphics/compare.h"
#include "sci/graphics/controls16.h"
#include "sci/graphics/cursor.h"
+#include "sci/graphics/gfxdrivers.h"
#include "sci/graphics/palette.h"
#include "sci/graphics/paint16.h"
#include "sci/graphics/picture.h"
@@ -257,7 +258,7 @@ reg_t kGraph(EngineState *s, int argc, reg_t *argv) {
}
reg_t kGraphGetColorCount(EngineState *s, int argc, reg_t *argv) {
- return make_reg(0, g_sci->_gfxPalette16->getTotalColorCount());
+ return make_reg(0, g_sci->_gfxScreen->gfxDriver()->numColors());
}
reg_t kGraphDrawLine(EngineState *s, int argc, reg_t *argv) {
@@ -614,7 +615,7 @@ reg_t kPaletteSetFromResource(EngineState *s, int argc, reg_t *argv) {
// Non-VGA games don't use palette resources.
// This has been changed to 64 colors because Longbow Amiga does have
// one palette (palette 999).
- if (g_sci->_gfxPalette16->getTotalColorCount() < 64)
+ if (g_sci->_gfxScreen->gfxDriver()->numColors() < 64)
return s->r_acc;
g_sci->_gfxPalette16->kernelSetFromResource(resourceId, force);
@@ -644,7 +645,7 @@ reg_t kPaletteSetIntensity(EngineState *s, int argc, reg_t *argv) {
bool setPalette = (argc < 4) ? true : (argv[3].isNull()) ? true : false;
// Palette intensity in non-VGA SCI1 games has been removed
- if (g_sci->_gfxPalette16->getTotalColorCount() < 256)
+ if (g_sci->_gfxScreen->gfxDriver()->numColors() < 256)
return s->r_acc;
if (setPalette) {
@@ -678,7 +679,7 @@ reg_t kPaletteAnimate(EngineState *s, int argc, reg_t *argv) {
bool paletteChanged = false;
// Palette animation in non-VGA SCI1 games has been removed
- if (g_sci->_gfxPalette16->getTotalColorCount() == 256) {
+ if (g_sci->_gfxScreen->gfxDriver()->numColors() == 256) {
for (int argNr = 0; argNr < argc; argNr += 3) {
uint16 fromColor = argv[argNr].toUint16();
uint16 toColor = argv[argNr + 1].toUint16();
diff --git a/engines/sci/event.cpp b/engines/sci/event.cpp
index cbd0f425398..f8f7b041447 100644
--- a/engines/sci/event.cpp
+++ b/engines/sci/event.cpp
@@ -28,6 +28,7 @@
#include "sci/console.h"
#include "sci/engine/state.h"
#include "sci/engine/kernel.h"
+#include "sci/graphics/gfxdrivers.h"
#ifdef ENABLE_SCI32
#include "sci/graphics/cursor32.h"
#include "sci/graphics/frameout.h"
@@ -205,7 +206,7 @@ SciEvent EventManager::getScummVMEvent() {
found = em->pollEvent(ev);
} while (found && ev.type == Common::EVENT_MOUSEMOVE);
- Common::Point mousePos = em->getMousePos();
+ Common::Point mousePos = g_sci->_gfxScreen->gfxDriver()->getMousePos();
#if ENABLE_SCI32
if (getSciVersion() >= SCI_VERSION_2) {
diff --git a/engines/sci/graphics/cursor.cpp b/engines/sci/graphics/cursor.cpp
index c5e3e7c58cf..c8e20412d3b 100644
--- a/engines/sci/graphics/cursor.cpp
+++ b/engines/sci/graphics/cursor.cpp
@@ -30,6 +30,7 @@
#include "sci/sci.h"
#include "sci/event.h"
#include "sci/engine/state.h"
+#include "sci/graphics/gfxdrivers.h"
#include "sci/graphics/palette.h"
#include "sci/graphics/screen.h"
#include "sci/graphics/coordadjuster.h"
@@ -175,7 +176,8 @@ void GfxCursor::kernelSetShape(GuiResourceId resourceId) {
resourceId, hotspot.x, hotspot.y, heightWidth, heightWidth);
}
- CursorMan.replaceCursor(rawBitmap->getUnsafeDataAt(0, heightWidth * heightWidth), heightWidth, heightWidth, hotspot.x, hotspot.y, SCI_CURSOR_SCI0_TRANSPARENCYCOLOR);
+ _screen->gfxDriver()->replaceCursor(rawBitmap->getUnsafeDataAt(0, heightWidth * heightWidth), heightWidth, heightWidth, hotspot.x, hotspot.y, SCI_CURSOR_SCI0_TRANSPARENCYCOLOR);
+
if (g_system->getScreenFormat().bytesPerPixel != 1) {
byte buf[3*256];
_screen->grabPalette(buf, 0, 256);
@@ -251,7 +253,7 @@ void GfxCursor::kernelSetView(GuiResourceId viewNum, int loopNum, int celNum, Co
_screen->scale2x(rawBitmap, *cursorBitmap, celInfo->width, celInfo->height);
CursorMan.replaceCursor(cursorBitmap->getUnsafeDataAt(0, width * height), width, height, cursorHotspot->x, cursorHotspot->y, clearKey);
} else {
- CursorMan.replaceCursor(rawBitmap.getUnsafeDataAt(0, width * height), width, height, cursorHotspot->x, cursorHotspot->y, clearKey);
+ _screen->gfxDriver()->replaceCursor(rawBitmap.getUnsafeDataAt(0, width * height), width, height, cursorHotspot->x, cursorHotspot->y, clearKey);
}
if (g_system->getScreenFormat().bytesPerPixel != 1) {
byte buf[3*256];
@@ -331,7 +333,7 @@ void GfxCursor::setPosition(Common::Point pos) {
}
Common::Point GfxCursor::getPosition() {
- Common::Point mousePos = g_system->getEventManager()->getMousePos();
+ Common::Point mousePos = g_sci->_gfxScreen->gfxDriver()->getMousePos();
if (_upscaledHires)
_screen->adjustBackUpscaledCoordinates(mousePos.y, mousePos.x);
@@ -409,7 +411,7 @@ void GfxCursor::refreshPosition() {
}
}
- CursorMan.replaceCursor(_cursorSurface->getUnsafeDataAt(0, cursorCelInfo->width * cursorCelInfo->height), cursorCelInfo->width, cursorCelInfo->height, cursorHotspot.x, cursorHotspot.y, cursorCelInfo->clearKey);
+ _screen->gfxDriver()->replaceCursor(_cursorSurface->getUnsafeDataAt(0, cursorCelInfo->width * cursorCelInfo->height), cursorCelInfo->width, cursorCelInfo->height, cursorHotspot.x, cursorHotspot.y, cursorCelInfo->clearKey);
if (g_system->getScreenFormat().bytesPerPixel != 1) {
byte buf[3*256];
_screen->grabPalette(buf, 0, 256);
diff --git a/engines/sci/graphics/gfxdrivers.cpp b/engines/sci/graphics/gfxdrivers.cpp
new file mode 100644
index 00000000000..d83fc9e1bd3
--- /dev/null
+++ b/engines/sci/graphics/gfxdrivers.cpp
@@ -0,0 +1,508 @@
+/* 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/events.h"
+#include "common/system.h"
+
+#include "graphics/cursorman.h"
+#include "graphics/paletteman.h"
+
+#include "sci/graphics/gfxdrivers.h"
+#include "sci/resource/resource.h"
+#include "sci/sci.h"
+#include "sci/version.h"
+
+namespace Sci {
+
+Common::Point GfxDriver::getMousePos() const {
+ return g_system->getEventManager()->getMousePos();
+}
+
+GfxDefaultDriver::GfxDefaultDriver(uint16 screenWidth, uint16 screenHeight) : GfxDriver(screenWidth, screenHeight, 0, 1) {
+ switch (g_sci->getResMan()->getViewType()) {
+ case kViewEga:
+ _numColors = 16; // QFG PC-98 with 8 colors also reports 16 here
+ break;
+ case kViewAmiga:
+ _numColors = 32;
+ break;
+ case kViewAmiga64:
+ _numColors = 64;
+ break;
+ case kViewVga:
+ case kViewVga11:
+ _numColors = 256;
+ break;
+ default:
+ break;
+ }
+
+ if (_numColors == 0)
+ error("GfxDefaultDriver: Unknown view type");
+}
+
+void GfxDefaultDriver::setPalette(const byte *colors, uint start, uint num) {
+ g_system->getPaletteManager()->setPalette(colors, start, num);
+}
+
+void GfxDefaultDriver::copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h) {
+ g_system->copyRectToScreen(src, pitch, x, y, w, h);
+}
+
+void GfxDefaultDriver::replaceCursor(const void *cursor, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor) {
+ CursorMan.replaceCursor(cursor, w, h, hotspotX, hotspotY, keycolor);
+}
+
+SCI0_DOSPreVGADriver::SCI0_DOSPreVGADriver(int numColors, int screenW, int screenH, int horizontalAlignment) : GfxDriver(screenW, screenH, numColors, horizontalAlignment), _palNeedUpdate(true), _colors(nullptr), _compositeBuffer(nullptr) {
+ _compositeBuffer = new byte[screenW * screenH]();
+}
+
+SCI0_DOSPreVGADriver::~SCI0_DOSPreVGADriver() {
+ delete[] _compositeBuffer;
+}
+
+bool SCI0_DOSPreVGADriver::checkDriver(const char *const *driverNames, int listSize) {
+ Common::String missing;
+ while (listSize-- && *driverNames) {
+ if (Common::File::exists(*driverNames))
+ return true;
+ if (!missing.empty())
+ missing += " or ";
+ missing += "'" + Common::String(*driverNames) + "'";
+ ++driverNames;
+ }
+ warning("Driver file %s not found. Starting game in EGA mode", missing.c_str());
+ return false;
+}
+
+void SCI0_DOSPreVGADriver::assignPalette(const byte *colors) {
+ _colors = colors;
+}
+
+void SCI0_DOSPreVGADriver::setPalette(const byte*, uint, uint) {
+ if (!_palNeedUpdate || !_colors)
+ return;
+ _palNeedUpdate = false;
+ byte *tmp = new byte[768]();
+ memcpy(tmp, _colors, _numColors * 3);
+ g_system->getPaletteManager()->setPalette(tmp, 0, 256);
+ delete[]tmp;
+}
+
+SCI0_EGADriver::SCI0_EGADriver() : SCI0_DOSPreVGADriver(16, 320, 200, 1) {
+ static const uint8 egaColors[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0x00, 0xAA, 0xAA,
+ 0xAA, 0x00, 0x00, 0xAA, 0x00, 0xAA, 0xAA, 0x55, 0x00, 0xAA, 0xAA, 0xAA,
+ 0x55, 0x55, 0x55, 0x55, 0x55, 0xFF, 0x55, 0xFF, 0x55, 0x55, 0xFF, 0xFF,
+ 0xFF, 0x55, 0x55, 0xFF, 0x55, 0xFF, 0xFF, 0xFF, 0x55, 0xFF, 0xFF, 0xFF
+ };
+ assignPalette(egaColors);
+}
+
+void SCI0_EGADriver::copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h) {
+ byte *dst = _compositeBuffer;
+ pitch -= w;
+ for (int i = 0; i < h; ++i) {
+ for (int ii = 0; ii < w; ++ii)
+ *dst++ = *src++;
+ src += pitch;
+ }
+
+ g_system->copyRectToScreen(_compositeBuffer, w, x, y, w, h);
+}
+
+void SCI0_EGADriver::replaceCursor(const void *cursor, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor) {
+ CursorMan.replaceCursor(cursor, w, h, hotspotX, hotspotY, keycolor);
+}
+
+SCI0_CGADriver::SCI0_CGADriver(bool emulateCGAModeOnEGACard) : SCI0_DOSPreVGADriver(4, 320, 200, 1), _cgaPatterns(nullptr), _disableMode5(emulateCGAModeOnEGACard) {
+ static const uint8 cgaColors[48] = {
+ /*
+ // Canonical CGA palette
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0x00, 0xAA, 0xAA,
+ 0xAA, 0x00, 0x00, 0xAA, 0x00, 0xAA, 0xAA, 0x55, 0x00, 0xAA, 0xAA, 0xAA,
+ 0x55, 0x55, 0x55, 0x55, 0x55, 0xFF, 0x55, 0xFF, 0x55, 0x55, 0xFF, 0xFF,
+ 0xFF, 0x55, 0x55, 0xFF, 0x55, 0xFF, 0xFF, 0xFF, 0x55, 0xFF, 0xFF, 0xFF
+ */
+ // Improved palette model taken from https://int10h.org/blog/2022/06/ibm-5153-color-true-cga-palette/
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4, 0x00, 0xC4, 0x00, 0x00, 0xC4, 0xC4,
+ 0xC4, 0x00, 0x00, 0xC4, 0x00, 0xC4, 0xC4, 0x7E, 0x00, 0xC4, 0xC4, 0xC4,
+ 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0xDC, 0x4E, 0xDC, 0x4E, 0x4E, 0xF3, 0xF3,
+ 0xDC, 0x4E, 0x4E, 0xF3, 0x4E, 0xF3, 0xF3, 0xF3, 0x4E, 0xFF, 0xFF, 0xFF
+ };
+
+ static const uint8 modeColorMap[3][4] = {
+ { 0, 2, 4, 6 },
+ { 0, 3, 5, 7 },
+ { 0, 3, 4, 7 }
+ };
+
+ Common::File drv;
+ if (!drv.open(_driverFile))
+ error("Failed to open '%s'", _driverFile);
+
+ byte palIndex = 1;
+ byte palIntensity = 1;
+ byte mode = 4;
+
+ uint8 colMap[4];
+ memset(colMap, 0, sizeof(colMap));
+
+ uint16 eprcOffs = 0;
+
+ uint32 cmd = drv.readUint32LE();
+ if ((cmd & 0xFF) == 0xE9)
+ eprcOffs = ((cmd >> 8) & 0xFFFF) + 3;
+
+ if (!eprcOffs || drv.readUint32LE() != 0x87654321 || !drv.skip(1) || !drv.seek(drv.readByte(), SEEK_CUR) || !drv.seek(drv.readByte(), SEEK_CUR))
+ error("Driver file '%s' unknown version", _driverFile);
+
+ drv.skip(drv.readByte() == 0x90 ? 2 : 1);
+
+ uint16 op1st = drv.readUint16LE();
+ int op1len = drv.readUint16LE() - op1st;
+
+ // sanity check
+ assert(op1len > 0 && op1len < 0x100);
+
+ drv.seek(op1st, SEEK_SET);
+ byte *buf = new byte[op1len]();
+ drv.read(buf, op1len);
+
+ // Try figuring out the correct settings...
+ for (int i = 0; i < op1len - 7; ++i) {
+ uint32 cfg = READ_BE_UINT32(buf + i);
+ cmd = READ_BE_UINT32(buf + 4 + i);
+ if ((cmd >> 16) == 0xCD10 && (cfg & 0xff00ff) == 0xB80000) {
+ mode = (cfg >> 8) & 0xff;
+ } else if (cmd == 0xB40BCD10) {
+ if (cfg >> 8 == 0x00B701B3) {
+ palIndex = cfg & 1;
+ palIntensity = (cfg >> 4) & 1;
+ } else if (cfg >> 8 == 0x00B700B3) {
+ colMap[0] = (cfg & 0x0f) + ((cfg & 0x10) >> 1);
+ }
+ }
+ }
+
+ delete[] buf;
+
+ assert(palIndex <= 1);
+ assert(palIntensity <= 1);
+
+ for (int i = 1; i < 4; ++i)
+ colMap[i] = modeColorMap[(!_disableMode5 && mode == 5) ? 2 : palIndex][i] + (palIntensity << 3);
+
+ memset (_palette, 0, sizeof(_palette));
+ for (int i = 0; i < 4; ++i) {
+ for (int ii = 0; ii < 3; ++ii)
+ _palette[i * 3 + ii] = cgaColors[colMap[i] * 3 + ii];
+ }
+
+ assignPalette(_palette);
+
+ _cgaPatterns = new uint16[256]();
+ // The pattern map is always located right before the driver entry point proc.
+ drv.seek(eprcOffs - 512, SEEK_SET);
+ for (int i = 0; i < 256; ++i)
+ _cgaPatterns[i] = drv.readUint16LE();
+
+ drv.close();
+}
+
+SCI0_CGADriver::~SCI0_CGADriver() {
+ delete[] _cgaPatterns;
+}
+
+void SCI0_CGADriver::copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h) {
+ // We can't really properly fix the boundaries here, we have to do that before calling this function.
+ assert(!(w & _hAlign));
+ assert(!(x & _hAlign));
+
+ byte *dst = _compositeBuffer;
+ pitch -= w;
+ int ty = y;
+
+ for (int i = 0; i < h; ++i) {
+ int tx = x & 3;
+ ++ty;
+ for (int ii = 0; ii < (w >> 1); ++ii) {
+ uint16 pattern = _cgaPatterns[((src[0] & 0x0f) << 4) | (src[1] & 0x0f)];
+ src += 2;
+ uint8 sh = (ty & 3) << 1;
+ uint8 lo = ((pattern & 0xff) >> sh) | ((pattern & 0xff) << (8 - sh));
+ uint8 hi = (pattern >> (8 + sh)) | ((pattern >> 8) << (8 - sh));
+ *dst++ = (lo >> (6 - (tx << 1))) & 3;
+ *dst++ = (hi >> (4 - (tx << 1))) & 3;
+ tx ^= 2;
+ }
+ src += pitch;
+ }
+
+ g_system->copyRectToScreen(_compositeBuffer, w, x, y, w, h);
+}
+
+void SCI0_CGADriver::replaceCursor(const void *cursor, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor) {
+ // Instead of implementing the original cursor rendering code, we rely on the 8 bit cursor that
+ // has already been generated by the engine. Of course, that code could be moved to the EGA
+ // driver class and implemented again for each mode, but I don't see the benefit. Instead,
+ // we simply convert the colors as needed...
+ assert(keycolor == 1);
+ const byte *s = reinterpret_cast<const uint8 *>(cursor);
+ byte *d = _compositeBuffer;
+ for (uint i = w * h; i; --i)
+ *d++ = *s++ & 3;
+
+ CursorMan.replaceCursor(_compositeBuffer, w, h, hotspotX, hotspotY, keycolor);
+}
+
+const char *SCI0_CGADriver::_driverFile = "CGA320C.DRV";
+
+const byte *monochrInit(const char *drvFile, bool &earlyVersion) {
+ Common::File drv;
+ if (!drv.open(drvFile))
+ return nullptr;
+
+ uint16 eprcOffs = 0;
+
+ uint32 cmd = drv.readUint32LE();
+ if ((cmd & 0xFF) == 0xE9)
+ eprcOffs = ((cmd >> 8) & 0xFFFF) + 3;
+
+ if (!eprcOffs || drv.readUint32LE() != 0x87654321 || !drv.skip(1) || !drv.seek(drv.readByte(), SEEK_CUR) || !drv.seek(drv.readByte(), SEEK_CUR))
+ error("Driver file '%s' unknown version", drv.getName());
+
+ // This is a safe assumption, as the early version pattern map is 4 times the size of the later one.
+ earlyVersion = (eprcOffs > 0x500);
+ uint16 size = earlyVersion ? 512 : 128;
+
+ byte *result = new byte[size];
+ // For CGA, the pattern map is always located before the entry point dispatcher proc.
+ drv.seek(eprcOffs - size, SEEK_SET);
+ drv.read(result, size);
+
+ // For Hercules there are some extra vars in between, all with initial values
+ // of zero. The last entry of the pattern map is definitely never zero...
+ int xtraOffs = 0;
+ while (result[size - 1 - xtraOffs] == 0)
+ ++xtraOffs;
+ if (xtraOffs != 0) {
+ drv.seek(eprcOffs - size - xtraOffs, SEEK_SET);
+ drv.read(result, size);
+ }
+
+ drv.close();
+
+ if (earlyVersion) {
+ uint16 *r = reinterpret_cast<uint16*>(result);
+ for (int i = 0; i < 256; ++i)
+ r[i] = FROM_LE_16(r[i]);
+ }
+
+ return result;
+}
+
+SCI0_CGABWDriver::SCI0_CGABWDriver() : SCI0_DOSPreVGADriver(2, 640, 400, 1), _monochromePatterns(nullptr), _earlyVersion(false) {
+ static const uint8 monochromePalette[6] = {
+ 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF
+ };
+ assignPalette(monochromePalette);
+
+ if (!(_monochromePatterns = monochrInit(_driverFiles[0], _earlyVersion)) && !(_monochromePatterns = monochrInit(_driverFiles[1], _earlyVersion)))
+ error("Failed to open '%s' or '%s'", _driverFiles[0], _driverFiles[1]);
+}
+
+SCI0_CGABWDriver::~SCI0_CGABWDriver() {
+ delete[] _monochromePatterns;
+}
+
+void SCI0_CGABWDriver::copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h) {
+ // We can't really properly fix the boundaries here, we have to do that before calling this function.
+ assert(!(w & _hAlign));
+ assert(!(x & _hAlign));
+
+ byte *dst1 = _compositeBuffer;
+ byte *dst2 = _compositeBuffer + (w << 1);
+ int ty = y & 7;
+ pitch -= w;
+
+ for (int i = 0; i < h; ++i) {
+ int tx = x & 3;
+ if (_earlyVersion) {
+ ++ty;
+ for (int ii = 0; ii < (w >> 1); ++ii) {
+ uint16 p16 = reinterpret_cast<const uint16*>(_monochromePatterns)[((src[0] & 0x0f) << 4) | (src[1] & 0x0f)];
+ src += 2;
+ uint8 sh = (ty & 3) << 1;
+ uint8 lo = ((p16 & 0xff) >> sh) | ((p16 & 0xff) << (8 - sh));
+ uint8 hi = (p16 >> (8 + sh)) | ((p16 >> 8) << (8 - sh));
+ *dst1++ = *dst2++ = ((lo >> (6 - (tx << 1))) >> 1) & 1;
+ *dst1++ = *dst2++ = (lo >> (6 - (tx << 1))) & 1;
+ *dst1++ = *dst2++ = ((hi >> (4 - (tx << 1))) >> 1) & 1;
+ *dst1++ = *dst2++ = (hi >> (4 - (tx << 1))) & 1;
+ tx ^= 2;
+ }
+ } else {
+ for (int ii = 0; ii < w; ++ii) {
+ uint8 p = _monochromePatterns[((*src++ & 0x0f) << 3) + ty] >> (6 - (tx << 1));
+ *dst1++ = *dst2++ = (p >> 1) & 1;
+ *dst1++ = *dst2++ = p & 1;
+ tx = (tx + 1) & 3;
+ }
+ ty = (ty + 1) & 7;
+ }
+ src += pitch;
+ dst1 += (w << 1);
+ dst2 += (w << 1);
+ }
+
+ g_system->copyRectToScreen(_compositeBuffer, w << 1, x << 1, y << 1, w << 1, h << 1);
+}
+
+void SCI0_CGABWDriver::replaceCursor(const void *cursor, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor) {
+ // Instead of implementing the original cursor rendering code, we rely on the 8 bit cursor that
+ // has already been generated by the engine. Of course, that code could be moved to the EGA
+ // driver class and implemented again for each mode, but I don't see the benefit. Instead,
+ // we simply convert the colors as needed and scale the cursor...
+ assert(keycolor == 1);
+ keycolor = 0x0f;
+ w <<= 1;
+ const byte *s = reinterpret_cast<const uint8*>(cursor);
+ byte *d0 = _compositeBuffer;
+ byte *d1 = _compositeBuffer + w;
+
+ for (uint i = 0; i < h; ++i) {
+ for (uint ii = 0; ii < w; ++ii) {
+ *d0++ = *d1++ = *s ? (*s ^ 0x0e) : 0;
+ if (ii & 1)
+ ++s;
+ }
+ d0 += w;
+ d1 += w;
+ }
+
+ CursorMan.replaceCursor(_compositeBuffer, w, h << 1, hotspotX << 1, hotspotY << 1, keycolor);
+}
+
+Common::Point SCI0_CGABWDriver::getMousePos() const {
+ Common::Point res = GfxDriver::getMousePos();
+ res.x >>= 1;
+ res.y >>= 1;
+ return res;
+}
+
+const char *SCI0_CGABWDriver::_driverFiles[2] = { "CGA320BW.DRV", "CGA320M.DRV" };
+
+SCI0_HerculesDriver::SCI0_HerculesDriver(int palIndex) : SCI0_DOSPreVGADriver(2, 720, 350, 0), _monochromePatterns(nullptr) {
+ static const uint8 monochromePalettes[3][6] = {
+ { 0x00, 0x00, 0x00, 0xFF, 0xBF, 0x66 }, // Amber
+ { 0x00, 0x00, 0x00, 0x66, 0xFF, 0x66 }, // Green
+ { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF } // B/W
+ };
+ assert(palIndex >= 0 && palIndex <= 2);
+ assignPalette(monochromePalettes[palIndex]);
+ bool unused = false;
+
+ if (!(_monochromePatterns = monochrInit(_driverFile, unused)))
+ error("Failed to open '%s'", _driverFile);
+}
+
+SCI0_HerculesDriver::~SCI0_HerculesDriver() {
+ delete[] _monochromePatterns;
+}
+
+void SCI0_HerculesDriver::copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h) {
+ // We can't really properly fix the boundaries here, we have to do that before calling this function.
+ assert(!(w & _hAlign));
+ assert(!(x & _hAlign));
+
+ byte *dst = _compositeBuffer;
+ byte sw = y & 1;
+ y = (y & ~1) * 3 / 2 + (y & 1);
+ int ty = y & 7;
+ int rh = 0;
+
+ for (int i = 0; i < h; ++i) {
+ const byte *src2 = src;
+ int tx = x & 3;
+ for (int ii = 0; ii < w; ++ii) {
+ uint8 p = _monochromePatterns[((*src2++ & 0x0f) << 3) + ty] >> (6 - (tx << 1));
+ *dst++ = (p >> 1) & 1;
+ *dst++ = p & 1;
+ tx = (tx + 1) & 3;
+ }
+
+ ty = (ty + 1) & 7;
+ ++rh;
+
+ if (sw & 1)
+ sw ^= 2;
+
+ if (sw != 3) {
+ src += pitch;
+ sw ^= 1;
+ } else {
+ --i;
+ }
+ }
+
+ g_system->copyRectToScreen(_compositeBuffer, w << 1, (x << 1) + 40, y + 25, w << 1, rh);
+}
+
+void SCI0_HerculesDriver::replaceCursor(const void *cursor, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor) {
+ // Instead of implementing the original cursor rendering code, we rely on the 8 bit cursor that
+ // has already been generated by the engine. Of course, that code could be moved to the EGA
+ // driver class and implemented again for each mode, but I don't see the benefit. Instead,
+ // we simply convert the colors as needed and scale the cursor...
+ assert(keycolor == 1);
+ keycolor = 0x0f;
+ int alt = 0;
+ const byte *s = reinterpret_cast<const uint8 *>(cursor);
+ byte *d = _compositeBuffer;
+
+ for (uint i = 0; i < h; ++i) {
+ for (uint ii = 0; ii < (w << 1); ++ii) {
+ *d++ = *s ? (*s ^ 0x0e) : 0;
+ if (ii & 1)
+ ++s;
+ }
+ if (i & 1) {
+ alt ^= 1;
+ if (alt) {
+ s -= w;
+ --i;
+ }
+ }
+ }
+
+ CursorMan.replaceCursor(_compositeBuffer, w << 1, h * 3 / 2, hotspotX << 1, hotspotY * 3 / 2, keycolor);
+}
+
+Common::Point SCI0_HerculesDriver::getMousePos() const {
+ Common::Point res = GfxDriver::getMousePos();
+ res.x = CLIP<int>(res.x - 40, 0, 639) >> 1;
+ res.y = CLIP<int>(res.y - 25, 0, 299) * 2 / 3;
+ return res;
+}
+
+const char *SCI0_HerculesDriver::_driverFile = "HERCMONO.DRV";
+
+} // End of namespace Sci
diff --git a/engines/sci/graphics/gfxdrivers.h b/engines/sci/graphics/gfxdrivers.h
new file mode 100644
index 00000000000..8e1a111c5ca
--- /dev/null
+++ b/engines/sci/graphics/gfxdrivers.h
@@ -0,0 +1,125 @@
+/* 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/>.
+ *
+ */
+
+#ifndef SCI_GRAPHICS_GFXDRIVERS_H
+#define SCI_GRAPHICS_GFXDRIVERS_H
+
+#include "common/rect.h"
+
+namespace Sci {
+
+class GfxDriver {
+public:
+ GfxDriver(uint16 screenWidth, uint16 screenHeight, int numColors, int horizontalAlignment) : _screenW(screenWidth), _screenH(screenHeight), _numColors(numColors), _hAlign(horizontalAlignment) {}
+ virtual ~GfxDriver() {}
+
+ uint16 screenWidth() const { return _screenW; }
+ uint16 screenHeight() const { return _screenH; }
+ uint16 numColors() const { return _numColors; }
+ uint8 hAlignment() const { return _hAlign; }
+
+ virtual void setPalette(const byte *colors, uint start, uint num) = 0;
+ virtual void copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h) = 0;
+ virtual void replaceCursor(const void *cursor, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor) = 0;
+ virtual Common::Point getMousePos() const;
+
+protected:
+ const uint16 _screenW;
+ const uint16 _screenH;
+ uint16 _numColors;
+ const uint8 _hAlign;
+};
+
+class GfxDefaultDriver final : public GfxDriver {
+public:
+ GfxDefaultDriver(uint16 screenWidth, uint16 screenHeight);
+ ~GfxDefaultDriver() override {}
+ void setPalette(const byte *colors, uint start, uint num) override;
+ void copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h) override;
+ void replaceCursor(const void *cursor, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor) override;
+};
+
+class SCI0_DOSPreVGADriver : public GfxDriver {
+public:
+ SCI0_DOSPreVGADriver(int numColors, int screenW, int screenH, int horizontalAlignment);
+ ~SCI0_DOSPreVGADriver() override;
+ void setPalette(const byte*, uint, uint) override;
+protected:
+ static bool checkDriver(const char *const *driverNames, int listSize);
+ void assignPalette(const byte *colors);
+ byte *_compositeBuffer;
+private:
+ bool _palNeedUpdate;
+ const byte *_colors;
+};
+
+class SCI0_EGADriver final : public SCI0_DOSPreVGADriver {
+public:
+ SCI0_EGADriver();
+ ~SCI0_EGADriver() override {}
+ void copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h) override;
+ void replaceCursor(const void *cursor, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor) override;
+};
+
+class SCI0_CGADriver final : public SCI0_DOSPreVGADriver {
+public:
+ SCI0_CGADriver(bool emulateCGAModeOnEGACard);
+ ~SCI0_CGADriver() override;
+ void copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h) override;
+ void replaceCursor(const void *cursor, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor) override;
+ static bool validateMode() { return checkDriver(&_driverFile, 1); }
+private:
+ uint16 *_cgaPatterns;
+ byte _palette[12];
+ const bool _disableMode5;
+ static const char *_driverFile;
+};
+
+class SCI0_CGABWDriver final : public SCI0_DOSPreVGADriver {
+public:
+ SCI0_CGABWDriver();
+ ~SCI0_CGABWDriver() override;
+ void copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h) override;
+ void replaceCursor(const void *cursor, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor) override;
+ Common::Point getMousePos() const override;
+ static bool validateMode() { return checkDriver(_driverFiles, 2); }
+private:
+ const byte *_monochromePatterns;
+ bool _earlyVersion;
+ static const char *_driverFiles[2];
+};
+
+class SCI0_HerculesDriver final : public SCI0_DOSPreVGADriver {
+public:
+ SCI0_HerculesDriver(int palIndex);
+ ~SCI0_HerculesDriver() override;
+ void copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h) override;
+ void replaceCursor(const void *cursor, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor) override;
+ Common::Point getMousePos() const override;
+ static bool validateMode() { return checkDriver(&_driverFile, 1); }
+private:
+ const byte *_monochromePatterns;
+ static const char *_driverFile;
+};
+
+} // End of namespace Sci
+
+#endif // SCI_GRAPHICS_GFXDRIVERS_H
diff --git a/engines/sci/graphics/palette.cpp b/engines/sci/graphics/palette.cpp
index 754cb81da50..995c6ea8fd0 100644
--- a/engines/sci/graphics/palette.cpp
+++ b/engines/sci/graphics/palette.cpp
@@ -27,6 +27,7 @@
#include "sci/sci.h"
#include "sci/engine/state.h"
#include "sci/graphics/cache.h"
+#include "sci/graphics/gfxdrivers.h"
#include "sci/graphics/maciconbar.h"
#include "sci/graphics/palette.h"
#include "sci/graphics/remap.h"
@@ -84,23 +85,7 @@ GfxPalette::GfxPalette(ResourceManager *resMan, GfxScreen *screen)
_macClut = nullptr;
loadMacIconBarPalette();
- switch (_resMan->getViewType()) {
- case kViewEga:
- _totalScreenColors = 16;
- break;
- case kViewAmiga:
- _totalScreenColors = 32;
- break;
- case kViewAmiga64:
- _totalScreenColors = 64;
- break;
- case kViewVga:
- case kViewVga11:
- _totalScreenColors = 256;
- break;
- default:
- error("GfxPalette: Unknown view type");
- }
+ _totalScreenColors = _screen->gfxDriver()->numColors();
}
GfxPalette::~GfxPalette() {
diff --git a/engines/sci/graphics/palette.h b/engines/sci/graphics/palette.h
index cbf35626e7d..c1147fa3860 100644
--- a/engines/sci/graphics/palette.h
+++ b/engines/sci/graphics/palette.h
@@ -55,7 +55,6 @@ public:
bool insert(Palette *newPalette, Palette *destPalette, bool includeFirstColor = false);
bool merge(Palette *pFrom, bool force, bool forceRealMerge);
uint16 matchColor(byte r, byte g, byte b, bool force16BitColorMatch = false);
- uint16 getTotalColorCount() const { return _totalScreenColors; }
// Set palette on screen. If update is false, try not to change the palette
// on already painted areas, but this may be impossible.
diff --git a/engines/sci/graphics/screen.cpp b/engines/sci/graphics/screen.cpp
index 81faa11e824..f141640e2d7 100644
--- a/engines/sci/graphics/screen.cpp
+++ b/engines/sci/graphics/screen.cpp
@@ -34,10 +34,11 @@
#include "sci/graphics/view.h"
#include "sci/graphics/palette.h"
#include "sci/graphics/scifx.h"
+#include "sci/graphics/gfxdrivers.h"
namespace Sci {
-GfxScreen::GfxScreen(ResourceManager *resMan) : _resMan(resMan) {
+GfxScreen::GfxScreen(ResourceManager *resMan, Common::RenderMode renderMode) : _resMan(resMan) {
// Scale the screen, if needed
_upscaledHires = GFX_SCREEN_UPSCALED_DISABLED;
@@ -147,6 +148,29 @@ GfxScreen::GfxScreen(ResourceManager *resMan) : _resMan(resMan) {
break;
}
+ _gfxDrv = nullptr;
+ if (getSciVersion() <= SCI_VERSION_0_LATE || getSciVersion() == SCI_VERSION_1_EGA_ONLY) {
+ switch (renderMode) {
+ case Common::kRenderCGA:
+ _gfxDrv = new SCI0_CGADriver(false);
+ break;
+ case Common::kRenderCGA_BW:
+ _gfxDrv = new SCI0_CGABWDriver();
+ break;
+ case Common::kRenderHercA:
+ case Common::kRenderHercG:
+ _gfxDrv = new SCI0_HerculesDriver(renderMode == Common::kRenderHercG ? 1 : 0);
+ break;
+ case Common::kRenderEGA:
+ default:
+ _gfxDrv = new SCI0_EGADriver();
+ break;
+ }
+ } else {
+ _gfxDrv = new GfxDefaultDriver(_displayWidth, _displayHeight);
+ }
+ assert(_gfxDrv);
+
_displayPixels = _displayWidth * _displayHeight;
// Allocate visual, priority, control and display screen
@@ -218,7 +242,7 @@ GfxScreen::GfxScreen(ResourceManager *resMan) : _resMan(resMan) {
initGraphics(_displayWidth, _displayHeight + macIconBarBuffer, format);
} else
- initGraphics(_displayWidth, _displayHeight, format);
+ initGraphics(_gfxDrv->screenWidth(), _gfxDrv->screenHeight(), format);
_format = g_system->getScreenFormat();
@@ -253,6 +277,7 @@ GfxScreen::~GfxScreen() {
free(_rgbScreen);
delete[] _palette;
delete[] _backupScreen;
+ delete _gfxDrv;
}
void GfxScreen::convertToRGB(const Common::Rect &rect) {
@@ -368,7 +393,7 @@ void GfxScreen::displayRect(const Common::Rect &rect, int x, int y) {
// Clipping is assumed to be done already.
if (_format.bytesPerPixel == 1) {
- g_system->copyRectToScreen(_activeScreen + rect.top * _displayWidth + rect.left, _displayWidth, x, y, rect.width(), rect.height());
+ _gfxDrv->copyRectToScreen(_activeScreen + rect.top * _displayWidth + rect.left, _displayWidth, x, y, rect.width(), rect.height());
} else {
displayRectRGB(rect, x, y);
}
@@ -426,7 +451,9 @@ void GfxScreen::kernelSyncWithFramebuffer() {
void GfxScreen::copyRectToScreen(const Common::Rect &rect) {
if (!_upscaledHires) {
- displayRect(rect, rect.left, rect.top);
+ uint8 align = _gfxDrv->hAlignment();
+ Common::Rect r(rect.left & ~align, rect.top, (rect.right + align) & ~align, rect.bottom);
+ displayRect(r, r.left, r.top);
} else {
int rectHeight = _upscaledHeightMapping[rect.bottom] - _upscaledHeightMapping[rect.top];
int rectWidth = _upscaledWidthMapping[rect.right] - _upscaledWidthMapping[rect.left];
@@ -1047,7 +1074,6 @@ int16 GfxScreen::kernelPicNotValid(int16 newPicNotValid) {
return oldPicNotValid;
}
-
void GfxScreen::grabPalette(byte *buffer, uint start, uint num) const {
assert(start + num <= 256);
if (_format.bytesPerPixel == 1) {
@@ -1060,7 +1086,7 @@ void GfxScreen::grabPalette(byte *buffer, uint start, uint num) const {
void GfxScreen::setPalette(const byte *buffer, uint start, uint num, bool update) {
assert(start + num <= 256);
if (_format.bytesPerPixel == 1) {
- g_system->getPaletteManager()->setPalette(buffer, start, num);
+ _gfxDrv->setPalette(buffer, start, num);
} else {
memcpy(_palette + 3*start, buffer, 3*num);
if (update) {
@@ -1109,6 +1135,4 @@ void GfxScreen::setPaletteMods(const PaletteMod *mods, unsigned int count) {
_paletteModsEnabled = true;
}
-
-
} // End of namespace Sci
diff --git a/engines/sci/graphics/screen.h b/engines/sci/graphics/screen.h
index d72a6c39245..4c7a38c7bf7 100644
--- a/engines/sci/graphics/screen.h
+++ b/engines/sci/graphics/screen.h
@@ -31,6 +31,8 @@
#include "graphics/korfont.h"
#include "graphics/pixelformat.h"
+#include "common/rendermode.h"
+
namespace Sci {
enum {
@@ -57,6 +59,8 @@ enum {
DITHERED_BG_COLORS_SIZE = 256
};
+class GfxDriver;
+
/**
* Screen class, actually creates 3 (4) screens internally:
* - visual/display (for the user),
@@ -67,7 +71,7 @@ enum {
*/
class GfxScreen {
public:
- GfxScreen(ResourceManager *resMan);
+ GfxScreen(ResourceManager *resMan, Common::RenderMode renderMode);
~GfxScreen();
uint16 getWidth() { return _width; }
@@ -157,6 +161,8 @@ public:
void setPaletteMods(const PaletteMod *mods, unsigned int count);
bool paletteModsEnabled() const { return _paletteModsEnabled; }
+ GfxDriver *gfxDriver() const { return _gfxDrv; }
+
private:
uint16 _width;
uint16 _height;
@@ -200,6 +206,11 @@ private:
byte *_displayScreen;
Graphics::Surface _displayScreenSurface;
+ /**
+ * CGA and Hercules support
+ */
+ GfxDriver *_gfxDrv;
+
// Screens for RGB mode support
byte *_displayedScreen;
byte *_rgbScreen;
diff --git a/engines/sci/metaengine.cpp b/engines/sci/metaengine.cpp
index 4072aade131..dc4d0b0cc26 100644
--- a/engines/sci/metaengine.cpp
+++ b/engines/sci/metaengine.cpp
@@ -31,6 +31,7 @@
#include "graphics/surface.h"
#include "sci/sci.h"
+#include "sci/detection_internal.h"
#include "sci/dialogs.h"
#include "sci/engine/features.h"
#include "sci/engine/guest_additions.h"
@@ -42,98 +43,6 @@
namespace Sci {
-struct GameIdStrToEnum {
- const char *gameidStr;
- const char *sierraIdStr;
- SciGameId gameidEnum;
- bool isSci32;
- SciVersion version;
-};
-
-static const GameIdStrToEnum s_gameIdStrToEnum[] = {
- { "astrochicken", "", GID_ASTROCHICKEN, false, SCI_VERSION_NONE }, // Sierra ID is "sq3", distinguished by resource count
- { "camelot", "arthur", GID_CAMELOT, false, SCI_VERSION_NONE },
- { "castlebrain", "brain", GID_CASTLEBRAIN, false, SCI_VERSION_1_LATE }, // Amiga is SCI1 middle, PC SCI1 late
- { "chest", "archive", GID_CHEST, true, SCI_VERSION_NONE },
- { "christmas1988", "demo", GID_CHRISTMAS1988, false, SCI_VERSION_0_EARLY },
- { "christmas1990", "card", GID_CHRISTMAS1990, false, SCI_VERSION_1_EARLY },
- { "christmas1992", "card", GID_CHRISTMAS1992, false, SCI_VERSION_1_1 },
- { "cnick-kq", "", GID_CNICK_KQ, false, SCI_VERSION_NONE }, // Sierra ID is "hoyle3", distinguished by resource count
- { "cnick-laurabow", "", GID_CNICK_LAURABOW, false, SCI_VERSION_NONE },
- { "cnick-longbow", "RH Budget", GID_CNICK_LONGBOW, false, SCI_VERSION_NONE },
- { "cnick-lsl", "", GID_CNICK_LSL, false, SCI_VERSION_NONE }, // Sierra ID is "lsl1", distinguished by resource count
- { "cnick-sq", "", GID_CNICK_SQ, false, SCI_VERSION_NONE }, // Sierra ID is "sq4", distinguished by resource count
- { "ecoquest", "eco", GID_ECOQUEST, false, SCI_VERSION_NONE },
- { "ecoquest2", "rain", GID_ECOQUEST2, false, SCI_VERSION_NONE },
- { "fairytales", "tales", GID_FAIRYTALES, false, SCI_VERSION_NONE },
- { "freddypharkas", "fp", GID_FREDDYPHARKAS, false, SCI_VERSION_NONE },
- { "funseeker", "emc", GID_FUNSEEKER, false, SCI_VERSION_NONE },
- { "gk1demo", "", GID_GK1DEMO, false, SCI_VERSION_NONE },
- { "gk1", "gk", GID_GK1, true, SCI_VERSION_NONE },
- { "gk2", "gk2", GID_GK2, true, SCI_VERSION_NONE },
- { "hoyle1", "cardgames", GID_HOYLE1, false, SCI_VERSION_NONE },
- { "hoyle2", "solitaire", GID_HOYLE2, false, SCI_VERSION_NONE },
- { "hoyle3", "hoyle3", GID_HOYLE3, false, SCI_VERSION_NONE },
- { "hoyle4", "hoyle4", GID_HOYLE4, false, SCI_VERSION_1_1 },
- { "hoyle5", "hoyle4", GID_HOYLE5, true, SCI_VERSION_2_1_MIDDLE },
- { "hoyle5bridge", "", GID_HOYLE5, true, SCI_VERSION_2_1_MIDDLE },
- { "hoyle5children", "", GID_HOYLE5, true, SCI_VERSION_2_1_MIDDLE },
- { "hoyle5school", "", GID_HOYLE5, true, SCI_VERSION_2_1_MIDDLE },
- { "hoyle5solitaire", "", GID_HOYLE5, true, SCI_VERSION_2_1_MIDDLE },
- { "iceman", "iceman", GID_ICEMAN, false, SCI_VERSION_NONE },
- { "inndemo", "", GID_INNDEMO, false, SCI_VERSION_NONE },
- { "islandbrain", "brain", GID_ISLANDBRAIN, false, SCI_VERSION_1_1 },
- { "jones", "jones", GID_JONES, false, SCI_VERSION_1_1 },
- { "kq1sci", "kq1", GID_KQ1, false, SCI_VERSION_NONE },
- { "kq4sci", "kq4", GID_KQ4, false, SCI_VERSION_NONE },
- { "kq5", "kq5", GID_KQ5, false, SCI_VERSION_NONE },
- { "kq6", "kq6", GID_KQ6, false, SCI_VERSION_NONE },
- { "kq7", "kq7cd", GID_KQ7, true, SCI_VERSION_NONE },
- { "kquestions", "quizgame-demo", GID_KQUESTIONS, true, SCI_VERSION_NONE },
- { "laurabow", "cb1", GID_LAURABOW, false, SCI_VERSION_NONE },
- { "laurabow2", "lb2", GID_LAURABOW2, false, SCI_VERSION_NONE },
- { "lighthouse", "lite", GID_LIGHTHOUSE, true, SCI_VERSION_NONE },
- { "longbow", "longbow", GID_LONGBOW, false, SCI_VERSION_NONE },
- { "lsl1sci", "lsl1", GID_LSL1, false, SCI_VERSION_NONE },
- { "lsl2", "lsl2", GID_LSL2, false, SCI_VERSION_NONE },
- { "lsl3", "lsl3", GID_LSL3, false, SCI_VERSION_NONE },
- { "lsl5", "lsl5", GID_LSL5, false, SCI_VERSION_NONE },
- { "lsl6", "lsl6", GID_LSL6, false, SCI_VERSION_NONE },
- { "lsl6hires", "", GID_LSL6HIRES, true, SCI_VERSION_NONE },
- { "lsl7", "l7", GID_LSL7, true, SCI_VERSION_NONE },
- { "mothergoose", "mg", GID_MOTHERGOOSE, false, SCI_VERSION_NONE },
- { "mothergoose256", "", GID_MOTHERGOOSE256, false, SCI_VERSION_NONE },
- { "mothergoosehires","", GID_MOTHERGOOSEHIRES, true, SCI_VERSION_NONE },
- { "msastrochicken", "", GID_MSASTROCHICKEN, false, SCI_VERSION_NONE }, // Sierra ID is "sq4", distinguished by resource count
- { "pepper", "twisty", GID_PEPPER, false, SCI_VERSION_NONE },
- { "phantasmagoria", "scary", GID_PHANTASMAGORIA, true, SCI_VERSION_NONE },
- { "phantasmagoria2", "p2", GID_PHANTASMAGORIA2, true, SCI_VERSION_NONE },
- { "pq1sci", "pq1", GID_PQ1, false, SCI_VERSION_NONE },
- { "pq2", "pq", GID_PQ2, false, SCI_VERSION_NONE },
- { "pq3", "pq3", GID_PQ3, false, SCI_VERSION_NONE },
- { "pq4", "pq4", GID_PQ4, true, SCI_VERSION_NONE },
- { "pq4demo", "", GID_PQ4DEMO, false, SCI_VERSION_NONE },
- { "pqswat", "swat", GID_PQSWAT, true, SCI_VERSION_NONE },
- { "qfg1", "gfg1", GID_QFG1, false, SCI_VERSION_NONE },
- { "qfg1vga", "", GID_QFG1VGA, false, SCI_VERSION_NONE }, // Sierra ID is "glory", distinguished by resources
- { "qfg2", "trial", GID_QFG2, false, SCI_VERSION_NONE },
- { "qfg3", "", GID_QFG3, false, SCI_VERSION_NONE }, // Sierra ID is "glory", distinguished by resources
- { "qfg4", "", GID_QFG4, true, SCI_VERSION_NONE }, // Sierra ID is "glory", distinguished by resources
- { "qfg4demo", "", GID_QFG4DEMO, false, SCI_VERSION_NONE }, // Sierra ID is "glory", distinguished by resources
- { "rama", "rama", GID_RAMA, true, SCI_VERSION_NONE },
- { "sci-fanmade", "", GID_FANMADE, false, SCI_VERSION_NONE },
- { "shivers", "", GID_SHIVERS, true, SCI_VERSION_NONE },
- //{ "shivers2", "shivers2", GID_SHIVERS2, true, SCI_VERSION_NONE }, // Not SCI
- { "slater", "thegame", GID_SLATER, false, SCI_VERSION_NONE },
- { "sq1sci", "sq1", GID_SQ1, false, SCI_VERSION_NONE },
- { "sq3", "sq3", GID_SQ3, false, SCI_VERSION_NONE },
- { "sq4", "sq4", GID_SQ4, false, SCI_VERSION_NONE },
- { "sq5", "sq5", GID_SQ5, false, SCI_VERSION_NONE },
- { "sq6", "sq6", GID_SQ6, true, SCI_VERSION_NONE },
- { "torin", "torin", GID_TORIN, true, SCI_VERSION_NONE },
- { nullptr, nullptr, GID_ALL, false, SCI_VERSION_NONE }
-};
-
struct DemoIdEntry {
const char *demoId;
const char *scummVMId;
@@ -303,8 +212,11 @@ Common::Error SciMetaEngine::createInstance(OSystem *syst, Engine **engine, cons
return Common::Error(Common::kUnsupportedGameidError, _s("SCI32 support not compiled in"));
}
#endif
-
*engine = new SciEngine(syst, desc, g->gameidEnum);
+
+ // If the GUI options were updated, we catch this here and update them in the users config file transparently.
+ Common::updateGameGUIOptions(customizeGuiOptions(ConfMan.getPath("path"), desc->guiOptions, g->version), getGameGUIOptionsDescriptionLanguage(desc->language));
+
return Common::kNoError;
}
}
diff --git a/engines/sci/module.mk b/engines/sci/module.mk
index 9898f653b64..ec1109a3a74 100644
--- a/engines/sci/module.mk
+++ b/engines/sci/module.mk
@@ -49,6 +49,7 @@ MODULE_OBJS := \
graphics/cursor.o \
graphics/fontkorean.o \
graphics/fontsjis.o \
+ graphics/gfxdrivers.o \
graphics/macfont.o \
graphics/maciconbar.o \
graphics/menu.o \
diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp
index 52e4664b4a8..986cf85fa4a 100644
--- a/engines/sci/sci.cpp
+++ b/engines/sci/sci.cpp
@@ -54,6 +54,7 @@
#include "sci/graphics/controls16.h"
#include "sci/graphics/coordadjuster.h"
#include "sci/graphics/cursor.h"
+#include "sci/graphics/gfxdrivers.h"
#include "sci/graphics/macfont.h"
#include "sci/graphics/maciconbar.h"
#include "sci/graphics/menu.h"
@@ -318,8 +319,22 @@ Common::Error SciEngine::run() {
}
if (getSciVersion() < SCI_VERSION_2) {
+ Common::RenderMode renderMode = Common::kRenderDefault;
+
+ if (getSciVersion() <= SCI_VERSION_0_LATE || getSciVersion() == SCI_VERSION_1_EGA_ONLY) {
+ if (ConfMan.hasKey("render_mode"))
+ renderMode = Common::parseRenderMode(ConfMan.get("render_mode"));
+
+ // Check if the selected render mode is available for the game. This is quite specific for
+ // each SCI0 game. Sometime it is only EGA, sometimes only CGA b/w without CGA 4 colors, etc.
+ if ((renderMode == Common::kRenderCGA && !SCI0_CGADriver::validateMode()) ||
+ (renderMode == Common::kRenderCGA_BW && !SCI0_CGABWDriver::validateMode()) ||
+ ((renderMode == Common::kRenderHercA || renderMode == Common::kRenderHercG) && !SCI0_HerculesDriver::validateMode()))
+ renderMode = Common::kRenderDefault;
+ }
+
// Initialize the game screen
- _gfxScreen = new GfxScreen(_resMan);
+ _gfxScreen = new GfxScreen(_resMan, renderMode);
_gfxScreen->enableUndithering(ConfMan.getBool("disable_dithering"));
}
Commit: a1e6ac68110f5a38c32e83fd05db70ee8f8fb48e
https://github.com/scummvm/scummvm/commit/a1e6ac68110f5a38c32e83fd05db70ee8f8fb48e
Author: athrxx (athrxx at scummvm.org)
Date: 2024-06-30T13:05:01+03:00
Commit Message:
SCI: fix undithering option and disable it for CGA/Hercules
Changed paths:
engines/sci/graphics/screen.cpp
engines/sci/sci.cpp
diff --git a/engines/sci/graphics/screen.cpp b/engines/sci/graphics/screen.cpp
index f141640e2d7..78b78805948 100644
--- a/engines/sci/graphics/screen.cpp
+++ b/engines/sci/graphics/screen.cpp
@@ -162,13 +162,15 @@ GfxScreen::GfxScreen(ResourceManager *resMan, Common::RenderMode renderMode) : _
_gfxDrv = new SCI0_HerculesDriver(renderMode == Common::kRenderHercG ? 1 : 0);
break;
case Common::kRenderEGA:
- default:
_gfxDrv = new SCI0_EGADriver();
break;
+ default:
+ break;
}
- } else {
- _gfxDrv = new GfxDefaultDriver(_displayWidth, _displayHeight);
}
+
+ if (_gfxDrv == nullptr)
+ _gfxDrv = new GfxDefaultDriver(_displayWidth, _displayHeight);
assert(_gfxDrv);
_displayPixels = _displayWidth * _displayHeight;
diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp
index 986cf85fa4a..dffba4b481f 100644
--- a/engines/sci/sci.cpp
+++ b/engines/sci/sci.cpp
@@ -321,21 +321,29 @@ Common::Error SciEngine::run() {
if (getSciVersion() < SCI_VERSION_2) {
Common::RenderMode renderMode = Common::kRenderDefault;
+ bool undither = ConfMan.getBool("disable_dithering");
+
if (getSciVersion() <= SCI_VERSION_0_LATE || getSciVersion() == SCI_VERSION_1_EGA_ONLY) {
if (ConfMan.hasKey("render_mode"))
renderMode = Common::parseRenderMode(ConfMan.get("render_mode"));
// Check if the selected render mode is available for the game. This is quite specific for
// each SCI0 game. Sometime it is only EGA, sometimes only CGA b/w without CGA 4 colors, etc.
- if ((renderMode == Common::kRenderCGA && !SCI0_CGADriver::validateMode()) ||
+ // Also set default mode if undithering is enabled.
+ if ((renderMode == Common::kRenderEGA && undither) ||
+ (renderMode == Common::kRenderCGA && !SCI0_CGADriver::validateMode()) ||
(renderMode == Common::kRenderCGA_BW && !SCI0_CGABWDriver::validateMode()) ||
((renderMode == Common::kRenderHercA || renderMode == Common::kRenderHercG) && !SCI0_HerculesDriver::validateMode()))
renderMode = Common::kRenderDefault;
+
+ // Disable undithering for CGA and Hercules modes
+ if (renderMode != Common::kRenderDefault)
+ undither = false;
}
// Initialize the game screen
_gfxScreen = new GfxScreen(_resMan, renderMode);
- _gfxScreen->enableUndithering(ConfMan.getBool("disable_dithering"));
+ _gfxScreen->enableUndithering(undither);
}
_kernel = new Kernel(_resMan, segMan);
Commit: 614ae2c8c922b46e3ea5d6c101a67b60f5eb6a60
https://github.com/scummvm/scummvm/commit/614ae2c8c922b46e3ea5d6c101a67b60f5eb6a60
Author: athrxx (athrxx at scummvm.org)
Date: 2024-06-30T13:05:01+03:00
Commit Message:
SCI: formatting
Changed paths:
engines/sci/detection_internal.h
diff --git a/engines/sci/detection_internal.h b/engines/sci/detection_internal.h
index 7061c2c653b..2c9fdee58ab 100644
--- a/engines/sci/detection_internal.h
+++ b/engines/sci/detection_internal.h
@@ -39,87 +39,87 @@ struct GameIdStrToEnum {
};
static const GameIdStrToEnum s_gameIdStrToEnum[] = {
- {"astrochicken", "", GID_ASTROCHICKEN, false, SCI_VERSION_NONE}, // Sierra ID is "sq3", distinguished by resource count
- {"camelot", "arthur", GID_CAMELOT, false, SCI_VERSION_NONE},
- {"castlebrain", "brain", GID_CASTLEBRAIN, false, SCI_VERSION_1_LATE}, // Amiga is SCI1 middle, PC SCI1 late
- {"chest", "archive", GID_CHEST, true, SCI_VERSION_NONE},
- {"christmas1988", "demo", GID_CHRISTMAS1988, false, SCI_VERSION_0_EARLY},
- {"christmas1990", "card", GID_CHRISTMAS1990, false, SCI_VERSION_1_EARLY},
- {"christmas1992", "card", GID_CHRISTMAS1992, false, SCI_VERSION_1_1},
- {"cnick-kq", "", GID_CNICK_KQ, false, SCI_VERSION_NONE}, // Sierra ID is "hoyle3", distinguished by resource count
- {"cnick-laurabow", "", GID_CNICK_LAURABOW, false, SCI_VERSION_NONE},
- {"cnick-longbow", "RH Budget", GID_CNICK_LONGBOW, false, SCI_VERSION_NONE},
- {"cnick-lsl", "", GID_CNICK_LSL, false, SCI_VERSION_NONE}, // Sierra ID is "lsl1", distinguished by resource count
- {"cnick-sq", "", GID_CNICK_SQ, false, SCI_VERSION_NONE}, // Sierra ID is "sq4", distinguished by resource count
- {"ecoquest", "eco", GID_ECOQUEST, false, SCI_VERSION_NONE},
- {"ecoquest2", "rain", GID_ECOQUEST2, false, SCI_VERSION_NONE},
- {"fairytales", "tales", GID_FAIRYTALES, false, SCI_VERSION_NONE},
- {"freddypharkas", "fp", GID_FREDDYPHARKAS, false, SCI_VERSION_NONE},
- {"funseeker", "emc", GID_FUNSEEKER, false, SCI_VERSION_NONE},
- {"gk1demo", "", GID_GK1DEMO, false, SCI_VERSION_NONE},
- {"gk1", "gk", GID_GK1, true, SCI_VERSION_NONE},
- {"gk2", "gk2", GID_GK2, true, SCI_VERSION_NONE},
- {"hoyle1", "cardgames", GID_HOYLE1, false, SCI_VERSION_NONE},
- {"hoyle2", "solitaire", GID_HOYLE2, false, SCI_VERSION_NONE},
- {"hoyle3", "hoyle3", GID_HOYLE3, false, SCI_VERSION_NONE},
- {"hoyle4", "hoyle4", GID_HOYLE4, false, SCI_VERSION_1_1},
- {"hoyle5", "hoyle4", GID_HOYLE5, true, SCI_VERSION_2_1_MIDDLE},
- {"hoyle5bridge", "", GID_HOYLE5, true, SCI_VERSION_2_1_MIDDLE},
- {"hoyle5children", "", GID_HOYLE5, true, SCI_VERSION_2_1_MIDDLE},
- {"hoyle5school", "", GID_HOYLE5, true, SCI_VERSION_2_1_MIDDLE},
- {"hoyle5solitaire", "", GID_HOYLE5, true, SCI_VERSION_2_1_MIDDLE},
- {"iceman", "iceman", GID_ICEMAN, false, SCI_VERSION_NONE},
- {"inndemo", "", GID_INNDEMO, false, SCI_VERSION_NONE},
- {"islandbrain", "brain", GID_ISLANDBRAIN, false, SCI_VERSION_1_1},
- {"jones", "jones", GID_JONES, false, SCI_VERSION_1_1},
- {"kq1sci", "kq1", GID_KQ1, false, SCI_VERSION_NONE},
- {"kq4sci", "kq4", GID_KQ4, false, SCI_VERSION_NONE},
- {"kq5", "kq5", GID_KQ5, false, SCI_VERSION_NONE},
- {"kq6", "kq6", GID_KQ6, false, SCI_VERSION_NONE},
- {"kq7", "kq7cd", GID_KQ7, true, SCI_VERSION_NONE},
- {"kquestions", "quizgame-demo", GID_KQUESTIONS, true, SCI_VERSION_NONE},
- {"laurabow", "cb1", GID_LAURABOW, false, SCI_VERSION_NONE},
- {"laurabow2", "lb2", GID_LAURABOW2, false, SCI_VERSION_NONE},
- {"lighthouse", "lite", GID_LIGHTHOUSE, true, SCI_VERSION_NONE},
- {"longbow", "longbow", GID_LONGBOW, false, SCI_VERSION_NONE},
- {"lsl1sci", "lsl1", GID_LSL1, false, SCI_VERSION_NONE},
- {"lsl2", "lsl2", GID_LSL2, false, SCI_VERSION_NONE},
- {"lsl3", "lsl3", GID_LSL3, false, SCI_VERSION_NONE},
- {"lsl5", "lsl5", GID_LSL5, false, SCI_VERSION_NONE},
- {"lsl6", "lsl6", GID_LSL6, false, SCI_VERSION_NONE},
- {"lsl6hires", "", GID_LSL6HIRES, true, SCI_VERSION_NONE},
- {"lsl7", "l7", GID_LSL7, true, SCI_VERSION_NONE},
- {"mothergoose", "mg", GID_MOTHERGOOSE, false, SCI_VERSION_NONE},
- {"mothergoose256", "", GID_MOTHERGOOSE256, false, SCI_VERSION_NONE},
- {"mothergoosehires", "", GID_MOTHERGOOSEHIRES, true, SCI_VERSION_NONE},
- {"msastrochicken", "", GID_MSASTROCHICKEN, false, SCI_VERSION_NONE}, // Sierra ID is "sq4", distinguished by resource count
- {"pepper", "twisty", GID_PEPPER, false, SCI_VERSION_NONE},
- {"phantasmagoria", "scary", GID_PHANTASMAGORIA, true, SCI_VERSION_NONE},
- {"phantasmagoria2", "p2", GID_PHANTASMAGORIA2, true, SCI_VERSION_NONE},
- {"pq1sci", "pq1", GID_PQ1, false, SCI_VERSION_NONE},
- {"pq2", "pq", GID_PQ2, false, SCI_VERSION_NONE},
- {"pq3", "pq3", GID_PQ3, false, SCI_VERSION_NONE},
- {"pq4", "pq4", GID_PQ4, true, SCI_VERSION_NONE},
- {"pq4demo", "", GID_PQ4DEMO, false, SCI_VERSION_NONE},
- {"pqswat", "swat", GID_PQSWAT, true, SCI_VERSION_NONE},
- {"qfg1", "gfg1", GID_QFG1, false, SCI_VERSION_NONE},
- {"qfg1vga", "", GID_QFG1VGA, false, SCI_VERSION_NONE}, // Sierra ID is "glory", distinguished by resources
- {"qfg2", "trial", GID_QFG2, false, SCI_VERSION_NONE},
- {"qfg3", "", GID_QFG3, false, SCI_VERSION_NONE}, // Sierra ID is "glory", distinguished by resources
- {"qfg4", "", GID_QFG4, true, SCI_VERSION_NONE}, // Sierra ID is "glory", distinguished by resources
- {"qfg4demo", "", GID_QFG4DEMO, false, SCI_VERSION_NONE}, // Sierra ID is "glory", distinguished by resources
- {"rama", "rama", GID_RAMA, true, SCI_VERSION_NONE},
- {"sci-fanmade", "", GID_FANMADE, false, SCI_VERSION_NONE},
- {"shivers", "", GID_SHIVERS, true, SCI_VERSION_NONE},
+ { "astrochicken", "", GID_ASTROCHICKEN, false, SCI_VERSION_NONE }, // Sierra ID is "sq3", distinguished by resource count
+ { "camelot", "arthur", GID_CAMELOT, false, SCI_VERSION_NONE },
+ { "castlebrain", "brain", GID_CASTLEBRAIN, false, SCI_VERSION_1_LATE }, // Amiga is SCI1 middle, PC SCI1 late
+ { "chest", "archive", GID_CHEST, true, SCI_VERSION_NONE },
+ { "christmas1988", "demo", GID_CHRISTMAS1988, false, SCI_VERSION_0_EARLY },
+ { "christmas1990", "card", GID_CHRISTMAS1990, false, SCI_VERSION_1_EARLY },
+ { "christmas1992", "card", GID_CHRISTMAS1992, false, SCI_VERSION_1_1 },
+ { "cnick-kq", "", GID_CNICK_KQ, false, SCI_VERSION_NONE }, // Sierra ID is "hoyle3", distinguished by resource count
+ { "cnick-laurabow", "", GID_CNICK_LAURABOW, false, SCI_VERSION_NONE },
+ { "cnick-longbow", "RH Budget", GID_CNICK_LONGBOW, false, SCI_VERSION_NONE },
+ { "cnick-lsl", "", GID_CNICK_LSL, false, SCI_VERSION_NONE }, // Sierra ID is "lsl1", distinguished by resource count
+ { "cnick-sq", "", GID_CNICK_SQ, false, SCI_VERSION_NONE }, // Sierra ID is "sq4", distinguished by resource count
+ { "ecoquest", "eco", GID_ECOQUEST, false, SCI_VERSION_NONE },
+ { "ecoquest2", "rain", GID_ECOQUEST2, false, SCI_VERSION_NONE },
+ { "fairytales", "tales", GID_FAIRYTALES, false, SCI_VERSION_NONE },
+ { "freddypharkas", "fp", GID_FREDDYPHARKAS, false, SCI_VERSION_NONE },
+ { "funseeker", "emc", GID_FUNSEEKER, false, SCI_VERSION_NONE },
+ { "gk1demo", "", GID_GK1DEMO, false, SCI_VERSION_NONE },
+ { "gk1", "gk", GID_GK1, true, SCI_VERSION_NONE },
+ { "gk2", "gk2", GID_GK2, true, SCI_VERSION_NONE },
+ { "hoyle1", "cardgames", GID_HOYLE1, false, SCI_VERSION_NONE },
+ { "hoyle2", "solitaire", GID_HOYLE2, false, SCI_VERSION_NONE },
+ { "hoyle3", "hoyle3", GID_HOYLE3, false, SCI_VERSION_NONE },
+ { "hoyle4", "hoyle4", GID_HOYLE4, false, SCI_VERSION_1_1 },
+ { "hoyle5", "hoyle4", GID_HOYLE5, true, SCI_VERSION_2_1_MIDDLE },
+ { "hoyle5bridge", "", GID_HOYLE5, true, SCI_VERSION_2_1_MIDDLE },
+ { "hoyle5children", "", GID_HOYLE5, true, SCI_VERSION_2_1_MIDDLE },
+ { "hoyle5school", "", GID_HOYLE5, true, SCI_VERSION_2_1_MIDDLE },
+ { "hoyle5solitaire", "", GID_HOYLE5, true, SCI_VERSION_2_1_MIDDLE },
+ { "iceman", "iceman", GID_ICEMAN, false, SCI_VERSION_NONE },
+ { "inndemo", "", GID_INNDEMO, false, SCI_VERSION_NONE },
+ { "islandbrain", "brain", GID_ISLANDBRAIN, false, SCI_VERSION_1_1 },
+ { "jones", "jones", GID_JONES, false, SCI_VERSION_1_1 },
+ { "kq1sci", "kq1", GID_KQ1, false, SCI_VERSION_NONE },
+ { "kq4sci", "kq4", GID_KQ4, false, SCI_VERSION_NONE },
+ { "kq5", "kq5", GID_KQ5, false, SCI_VERSION_NONE },
+ { "kq6", "kq6", GID_KQ6, false, SCI_VERSION_NONE },
+ { "kq7", "kq7cd", GID_KQ7, true, SCI_VERSION_NONE },
+ { "kquestions", "quizgame-demo", GID_KQUESTIONS, true, SCI_VERSION_NONE },
+ { "laurabow", "cb1", GID_LAURABOW, false, SCI_VERSION_NONE },
+ { "laurabow2", "lb2", GID_LAURABOW2, false, SCI_VERSION_NONE },
+ { "lighthouse", "lite", GID_LIGHTHOUSE, true, SCI_VERSION_NONE },
+ { "longbow", "longbow", GID_LONGBOW, false, SCI_VERSION_NONE },
+ { "lsl1sci", "lsl1", GID_LSL1, false, SCI_VERSION_NONE },
+ { "lsl2", "lsl2", GID_LSL2, false, SCI_VERSION_NONE },
+ { "lsl3", "lsl3", GID_LSL3, false, SCI_VERSION_NONE },
+ { "lsl5", "lsl5", GID_LSL5, false, SCI_VERSION_NONE },
+ { "lsl6", "lsl6", GID_LSL6, false, SCI_VERSION_NONE },
+ { "lsl6hires", "", GID_LSL6HIRES, true, SCI_VERSION_NONE },
+ { "lsl7", "l7", GID_LSL7, true, SCI_VERSION_NONE },
+ { "mothergoose", "mg", GID_MOTHERGOOSE, false, SCI_VERSION_NONE },
+ { "mothergoose256", "", GID_MOTHERGOOSE256, false, SCI_VERSION_NONE },
+ { "mothergoosehires","", GID_MOTHERGOOSEHIRES, true, SCI_VERSION_NONE },
+ { "msastrochicken", "", GID_MSASTROCHICKEN, false, SCI_VERSION_NONE }, // Sierra ID is "sq4", distinguished by resource count
+ { "pepper", "twisty", GID_PEPPER, false, SCI_VERSION_NONE },
+ { "phantasmagoria", "scary", GID_PHANTASMAGORIA, true, SCI_VERSION_NONE },
+ { "phantasmagoria2", "p2", GID_PHANTASMAGORIA2, true, SCI_VERSION_NONE },
+ { "pq1sci", "pq1", GID_PQ1, false, SCI_VERSION_NONE },
+ { "pq2", "pq", GID_PQ2, false, SCI_VERSION_NONE },
+ { "pq3", "pq3", GID_PQ3, false, SCI_VERSION_NONE },
+ { "pq4", "pq4", GID_PQ4, true, SCI_VERSION_NONE },
+ { "pq4demo", "", GID_PQ4DEMO, false, SCI_VERSION_NONE },
+ { "pqswat", "swat", GID_PQSWAT, true, SCI_VERSION_NONE },
+ { "qfg1", "gfg1", GID_QFG1, false, SCI_VERSION_NONE },
+ { "qfg1vga", "", GID_QFG1VGA, false, SCI_VERSION_NONE }, // Sierra ID is "glory", distinguished by resources
+ { "qfg2", "trial", GID_QFG2, false, SCI_VERSION_NONE },
+ { "qfg3", "", GID_QFG3, false, SCI_VERSION_NONE }, // Sierra ID is "glory", distinguished by resources
+ { "qfg4", "", GID_QFG4, true, SCI_VERSION_NONE }, // Sierra ID is "glory", distinguished by resources
+ { "qfg4demo", "", GID_QFG4DEMO, false, SCI_VERSION_NONE }, // Sierra ID is "glory", distinguished by resources
+ { "rama", "rama", GID_RAMA, true, SCI_VERSION_NONE },
+ { "sci-fanmade", "", GID_FANMADE, false, SCI_VERSION_NONE },
+ { "shivers", "", GID_SHIVERS, true, SCI_VERSION_NONE },
//{ "shivers2", "shivers2", GID_SHIVERS2, true, SCI_VERSION_NONE }, // Not SCI
- {"slater", "thegame", GID_SLATER, false, SCI_VERSION_NONE},
- {"sq1sci", "sq1", GID_SQ1, false, SCI_VERSION_NONE},
- {"sq3", "sq3", GID_SQ3, false, SCI_VERSION_NONE},
- {"sq4", "sq4", GID_SQ4, false, SCI_VERSION_NONE},
- {"sq5", "sq5", GID_SQ5, false, SCI_VERSION_NONE},
- {"sq6", "sq6", GID_SQ6, true, SCI_VERSION_NONE},
- {"torin", "torin", GID_TORIN, true, SCI_VERSION_NONE},
- {nullptr, nullptr, GID_ALL, false, SCI_VERSION_NONE}
+ { "slater", "thegame", GID_SLATER, false, SCI_VERSION_NONE },
+ { "sq1sci", "sq1", GID_SQ1, false, SCI_VERSION_NONE },
+ { "sq3", "sq3", GID_SQ3, false, SCI_VERSION_NONE },
+ { "sq4", "sq4", GID_SQ4, false, SCI_VERSION_NONE },
+ { "sq5", "sq5", GID_SQ5, false, SCI_VERSION_NONE },
+ { "sq6", "sq6", GID_SQ6, true, SCI_VERSION_NONE },
+ { "torin", "torin", GID_TORIN, true, SCI_VERSION_NONE },
+ { nullptr, nullptr, GID_ALL, false, SCI_VERSION_NONE }
};
static Common::String customizeGuiOptions(Common::Path gamePath, Common::String guiOptions, SciVersion version) {
More information about the Scummvm-git-logs
mailing list