[Scummvm-git-logs] scummvm master -> 85a191de2bae669cf7b23d47165baa892a27bc4d
athrxx
noreply at scummvm.org
Sun Jul 31 22:09:46 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:
85a191de2b SCUMM: (v6/EGA) - improved mouse cursor handling and some other fixes
Commit: 85a191de2bae669cf7b23d47165baa892a27bc4d
https://github.com/scummvm/scummvm/commit/85a191de2bae669cf7b23d47165baa892a27bc4d
Author: athrxx (athrxx at scummvm.org)
Date: 2022-07-31T23:57:15+02:00
Commit Message:
SCUMM: (v6/EGA) - improved mouse cursor handling and some other fixes
The mouse cursors get dithered correctly now and due to earlier fixes SAMNMAX seems to be in as good a state as DOTT regarding EGA dithering mode, so I enable it. Also added a post-load fix for the palette and the mouse cursors.
Changed paths:
engines/scumm/cursor.cpp
engines/scumm/palette.cpp
engines/scumm/saveload.cpp
engines/scumm/scumm.cpp
engines/scumm/scumm.h
engines/scumm/scumm_v6.h
diff --git a/engines/scumm/cursor.cpp b/engines/scumm/cursor.cpp
index d404e560ade..ce2cb4f9682 100644
--- a/engines/scumm/cursor.cpp
+++ b/engines/scumm/cursor.cpp
@@ -113,9 +113,17 @@ void ScummEngine_v6::setCursorTransparency(int a) {
size = _cursor.width * _cursor.height;
- for (i = 0; i < size; i++)
- if (_grabbedCursor[i] == (byte)a)
- _grabbedCursor[i] = 0xFF;
+ if (_enableEGADithering) {
+ for (i = 0; i < size; i += 2) {
+ int st = 1 ^ ((i / (_cursor.width << 1)) & 1);
+ if (_grabbedCursor[i] == _egaColorMap[st][a] && _grabbedCursor[i + 1] == _egaColorMap[st ^ 1][a])
+ _grabbedCursor[i] = _grabbedCursor[i + 1] = 0xFF;
+ }
+ } else {
+ for (i = 0; i < size; i++)
+ if (_grabbedCursor[i] == (byte)a)
+ _grabbedCursor[i] = 0xFF;
+ }
updateCursor();
}
@@ -153,43 +161,51 @@ void ScummEngine_v6::setDefaultCursor() {
setCursorFromBuffer(default_v6_cursor, 16, 13, 16);
}
-void ScummEngine::setCursorFromBuffer(const byte *ptr, int width, int height, int pitch) {
+void ScummEngine_v6::setCursorFromBuffer(const byte *ptr, int width, int height, int pitch) {
uint size;
byte *dst;
- int sclW = _enableEGADithering ? 2 : 1;
- int sclH = _enableEGADithering ? 2 : 1;
-
- size = width * sclW * height * sclH * _bytesPerPixel;
+ size = width * height * _bytesPerPixel;
+ if (_enableEGADithering)
+ size <<= 2;
if (size > sizeof(_grabbedCursor))
error("grabCursor: grabbed cursor too big");
- _cursor.width = width * sclW;
- _cursor.height = height * sclH;
+ _cursor.width = width;
+ _cursor.height = height;
_cursor.animate = 0;
- dst = _grabbedCursor;
+ dst = _enableEGADithering ? _compositeBuf : _grabbedCursor;
for (; height; height--) {
- for (int h2 = sclH; h2; --h2) {
- const byte *s1 = ptr;
- const byte *s2 = 0;
- byte *d = dst;
- for (int w = width; w; --w) {
- for (int w2 = sclW; w2; --w2) {
- s2 = s1;
- for (int w3 = _bytesPerPixel; w3; --w3)
- *d++ = *s2++;
- }
- s1 = s2;
- }
- dst += width * sclW * _bytesPerPixel;
- }
+ memcpy(dst, ptr, width * _bytesPerPixel);
+ dst += width * _bytesPerPixel;
ptr += pitch;
}
+ if (_enableEGADithering)
+ ditherCursor();
+
updateCursor();
}
+void ScummEngine_v6::ditherCursor() {
+ int x = 0;
+ int y = 0;
+ int pitch = _cursor.width;
+
+ // We temporarily put the transparency color in the EGA color tables.
+ uint8 backupEGA0 = _egaColorMap[0][255];
+ uint8 backupEGA1 = _egaColorMap[1][255];
+ _egaColorMap[0][255] = _egaColorMap[1][255] = 0xFF;
+
+ ditherVGAtoEGA(pitch, x, y, _cursor.width, _cursor.height);
+
+ _egaColorMap[0][255] = backupEGA0;
+ _egaColorMap[1][255] = backupEGA1;
+
+ memcpy(_grabbedCursor, _hercCGAScaleBuf, _cursor.width * _cursor.height);
+}
+
void ScummEngine_v70he::setCursorFromImg(uint img, uint room, uint imgindex) {
_resExtractor->setCursor(img);
}
@@ -391,6 +407,8 @@ void ScummEngine_v6::useBompCursor(const byte *im, int width, int height) {
height *= 8;
size = width * height;
+ if (_enableEGADithering)
+ size <<= 2;
if (size > sizeof(_grabbedCursor))
error("useBompCursor: cursor too big (%d)", size);
@@ -404,7 +422,10 @@ void ScummEngine_v6::useBompCursor(const byte *im, int width, int height) {
} else {
im += 18;
}
- decompressBomp(_grabbedCursor, im, width, height);
+ decompressBomp(_enableEGADithering ? _compositeBuf : _grabbedCursor, im, width, height);
+
+ if (_enableEGADithering)
+ ditherCursor();
updateCursor();
}
diff --git a/engines/scumm/palette.cpp b/engines/scumm/palette.cpp
index 99d8dc6a8bd..76f431ba98c 100644
--- a/engines/scumm/palette.cpp
+++ b/engines/scumm/palette.cpp
@@ -252,6 +252,12 @@ void ScummEngine::resetPalette() {
} else if (_renderMode == Common::kRenderEGA && _supportsEGADithering) {
setPaletteFromTable(tableEGAPalette, sizeof(tableEGAPalette) / 3);
_enableEGADithering = true;
+ // Set the color tables to sane values (for games that dither the mouse cursor
+ // right at the beginning, before these tables get filled normally.
+ if (_currentRoom == 0) {
+ for (uint16 i = 0; i < 256; ++i)
+ _egaColorMap[0][i] = _egaColorMap[1][i] = i & 0x0F;
+ }
#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
} else if (_game.platform == Common::kPlatformFMTowns) {
if (_game.id == GID_INDY4 || _game.id == GID_MONKEY2)
diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp
index bce0c2ff4a8..47bd5f5d887 100644
--- a/engines/scumm/saveload.cpp
+++ b/engines/scumm/saveload.cpp
@@ -1172,7 +1172,7 @@ void ScummEngine::saveLoadWithSerializer(Common::Serializer &s) {
x *= 2;
x += (kHercWidth - _screenWidth * 2) / 2;
y = y * 7 / 4;
- } else if (_macScreen || (_useCJKMode && _textSurfaceMultiplier == 2)) {
+ } else if (_macScreen || (_useCJKMode && _textSurfaceMultiplier == 2) || _renderMode == Common::kRenderCGA_BW || _enableEGADithering) {
x *= 2;
y *= 2;
}
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 353ed881468..2f0f0444f95 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -243,8 +243,8 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
// VGA games which support an EGA dithering mode
static const byte egaModeIDs[] = {
- /*GID_SAMNMAX,*/ // Not supported in the original interpreter. It works, but is too glitchy to have it enabled without further fine tuning...
- GID_TENTACLE, // Not supported in the original interpreter. Less glitchy than SAM, so I leave it enabled. I guess, people who actually select this will know what they're doing.
+ GID_SAMNMAX, // Not supported in the original interpreter. Glitches might occur.
+ GID_TENTACLE, // Not supported in the original interpreter. Glitches might occur.
GID_LOOM, // Supported in the original interpreter.
GID_MONKEY,
GID_MONKEY_VGA,
@@ -2691,13 +2691,13 @@ void ScummEngine_v3::scummLoop_handleSaveLoad() {
_townsPlayer->restoreAfterLoad();
}
}
+
void ScummEngine_v5::scummLoop_handleSaveLoad() {
bool processIQPoints = (_game.id == GID_INDY4) && (_saveLoadFlag == 2 || _loadFromLauncher);
_loadFromLauncher = false;
ScummEngine::scummLoop_handleSaveLoad();
-
if (_videoModeChanged) {
_videoModeChanged = false;
warning("Loading savegame with a different render mode setting. Glitches might occur");
@@ -2734,6 +2734,33 @@ void ScummEngine_v5::scummLoop_handleSaveLoad() {
runScript(145, 0, 0, nullptr);
}
+void ScummEngine_v6::scummLoop_handleSaveLoad() {
+ ScummEngine::scummLoop_handleSaveLoad();
+
+ if (_videoModeChanged) {
+ _videoModeChanged = false;
+ warning("Loading savegame with a different render mode setting. Glitches might occur");
+ if (_supportsEGADithering) {
+ // Reconstruct the screen palette.
+ setCurrentPalette(_curPalIndex);
+ // Reconstruct mouse cursor (crosshair for DOTT, verb cursor for SAM).
+ if (_game.id == GID_SAMNMAX) {
+ setCursorFromImg(VAR(177), VAR(177) > 890 ? 94 : 93, 1);
+ if (VAR(177) > 890) {
+ // The inventory item cursors require some extra treatment...
+ setCursorTransparency(180);
+ setCursorTransparency(178);
+ setCursorTransparency(176);
+ setCursorTransparency(6);
+ setCursorTransparency(0);
+ }
+ } else {
+ setDefaultCursor();
+ }
+ }
+ }
+}
+
#ifdef ENABLE_SCUMM_7_8
void ScummEngine_v8::scummLoop_handleSaveLoad() {
ScummEngine::scummLoop_handleSaveLoad();
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index 2435580ab5f..671f5a8b217 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -1054,8 +1054,6 @@ protected:
void setShadowPalette(int redScale, int greenScale, int blueScale, int startColor, int endColor, int start, int end);
virtual void darkenPalette(int redScale, int greenScale, int blueScale, int startColor, int endColor);
- void setCursorFromBuffer(const byte *ptr, int width, int height, int pitch);
-
public:
void markRectAsDirty(VirtScreenNumber virt, int left, int right, int top, int bottom, int dirtybit = 0);
void markRectAsDirty(VirtScreenNumber virt, const Common::Rect& rect, int dirtybit = 0) {
diff --git a/engines/scumm/scumm_v6.h b/engines/scumm/scumm_v6.h
index d1ccd9435ee..f4dd5b811a0 100644
--- a/engines/scumm/scumm_v6.h
+++ b/engines/scumm/scumm_v6.h
@@ -108,6 +108,7 @@ public:
protected:
void setupOpcodes() override;
+ void scummLoop_handleSaveLoad() override;
void scummLoop_handleActors() override;
void processKeyboard(Common::KeyState lastKeyHit) override;
@@ -143,6 +144,8 @@ protected:
void useIm01Cursor(const byte *im, int w, int h);
void useBompCursor(const byte *im, int w, int h);
void grabCursor(int x, int y, int w, int h);
+ void setCursorFromBuffer(const byte *ptr, int width, int height, int pitch);
+ void ditherCursor();
virtual void drawBlastTexts() {}
virtual void removeBlastTexts() {}
More information about the Scummvm-git-logs
mailing list