[Scummvm-git-logs] scummvm master -> 0add487eea42ee8ce05d271b3715fbcf52ca3b91
AndywinXp
noreply at scummvm.org
Sat Aug 31 11:30:19 UTC 2024
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:
0add487eea SCUMM: SAMNMAX: Implement original noir mode
Commit: 0add487eea42ee8ce05d271b3715fbcf52ca3b91
https://github.com/scummvm/scummvm/commit/0add487eea42ee8ce05d271b3715fbcf52ca3b91
Author: AndywinXp (andywinxp at gmail.com)
Date: 2024-08-31T13:30:15+02:00
Commit Message:
SCUMM: SAMNMAX: Implement original noir mode
At default, we still use our improved version (for which
I restored the correct accurate grayscale colors, though).
For this original noir mode we have to play without the
"minor bug fixes" enhancement class active.
Changed paths:
engines/scumm/palette.cpp
engines/scumm/script_v6.cpp
engines/scumm/scumm.h
diff --git a/engines/scumm/palette.cpp b/engines/scumm/palette.cpp
index abc47074fe1..629854164ca 100644
--- a/engines/scumm/palette.cpp
+++ b/engines/scumm/palette.cpp
@@ -419,6 +419,9 @@ void ScummEngine::setPaletteFromPtr(const byte *ptr, int numcolor) {
}
setDirtyColors(firstIndex, numcolor - 1);
+
+ if (_game.id == GID_SAMNMAX && !enhancementEnabled(kEnhMinorBugFixes))
+ VAR(77) = 0;
}
void ScummEngine::setAmigaPaletteFromPtr(const byte *ptr) {
@@ -1180,6 +1183,10 @@ void ScummEngine::darkenPalette(int redScale, int greenScale, int blueScale, int
}
if (_game.heversion != 70)
setDirtyColors(startColor, endColor);
+
+ // Original noir mode behavior
+ if (_game.id == GID_SAMNMAX && !enhancementEnabled(kEnhMinorBugFixes) && VAR(77) == 1)
+ applyGrayscaleToPaletteRange(startColor, endColor);
}
}
}
@@ -1384,6 +1391,10 @@ void ScummEngine::copyPalColor(int dst, int src) {
_16BitPalette[dst] = get16BitColor(sp[0], sp[1], sp[2]);
setDirtyColors(dst, dst);
+
+ // Original noir mode behavior
+ if (_game.id == GID_SAMNMAX && !enhancementEnabled(kEnhMinorBugFixes) && VAR(77) == 1)
+ applyGrayscaleToPaletteRange(src, src);
}
void ScummEngine::setPalColor(int idx, int r, int g, int b) {
@@ -1447,6 +1458,10 @@ void ScummEngine::setPalColor(int idx, int r, int g, int b) {
_16BitPalette[idx] = get16BitColor(r, g, b);
setDirtyColors(idx, idx);
+
+ // Original noir mode behavior
+ if (_game.id == GID_SAMNMAX && !enhancementEnabled(kEnhMinorBugFixes) && VAR(77) == 1)
+ applyGrayscaleToPaletteRange(idx, idx);
}
void ScummEngine::setCurrentPalette(int palindex) {
@@ -1583,6 +1598,37 @@ uint32 ScummEngine::findClosestPaletteColor(byte *palette, int paletteLength, by
return (uint32)_pl.findBestColor(r, g, b, true);
}
+void ScummEngine::applyGrayscaleToPaletteRange(int min, int max) {
+ assertRange(0, min, 256, "ScummEngine::applyGrayscaleToPaletteRange(): min");
+ assertRange(0, max, 256, "ScummEngine::applyGrayscaleToPaletteRange(): min");
+
+ if (min <= max) {
+ int count = max - min + 1;
+ byte *paletteEntry = &_currentPalette[3 * min];
+
+ for (int i = 0; i < count; i++) {
+ int r = paletteEntry[0];
+ int g = paletteEntry[1];
+ int b = paletteEntry[2];
+ byte average = (byte)((r + g + b) / 3);
+
+ // The original checks for colors to be < 126,
+ // but we handle things a little bit differently,
+ // so this is not needed...
+ //
+ // if (r < 126 || g < 126 || b < 126) {
+ paletteEntry[0] = average;
+ paletteEntry[1] = average;
+ paletteEntry[2] = average;
+ // }
+
+ paletteEntry += 3;
+ }
+ }
+
+ setDirtyColors(min, max);
+}
+
void ScummEngine::updatePalette() {
if (_game.features & GF_16BIT_COLOR)
return;
@@ -1623,7 +1669,7 @@ void ScummEngine::updatePalette() {
_system->getPaletteManager()->setPalette(mouseCursorPalette, 252, 3);
} else {
- bool noir_mode = (_game.id == GID_SAMNMAX && readVar(0x8000));
+ bool noirMode = (_game.id == GID_SAMNMAX && readVar(0x8000));
int i;
first = _palDirtyMin;
@@ -1637,10 +1683,9 @@ void ScummEngine::updatePalette() {
else
data = _currentPalette + i * 3;
- // Sam & Max film noir mode. Convert the colors to grayscale
- // before uploading them to the backend.
-
- if (noir_mode) {
+ // Sam & Max film noir mode - Enhanced version.
+ // Convert the colors to grayscale before uploading them to the backend.
+ if (noirMode && enhancementEnabled(kEnhMinorBugFixes)) {
int r, g, b;
byte brightness;
@@ -1648,7 +1693,7 @@ void ScummEngine::updatePalette() {
g = data[1];
b = data[2];
- brightness = (byte)((0.299 * r + 0.587 * g + 0.114 * b) + 0.5);
+ brightness = (byte)((r + g + b) / 3);
*p++ = brightness;
*p++ = brightness;
diff --git a/engines/scumm/script_v6.cpp b/engines/scumm/script_v6.cpp
index 4e4fa89e896..6cc2c449684 100644
--- a/engines/scumm/script_v6.cpp
+++ b/engines/scumm/script_v6.cpp
@@ -2180,16 +2180,17 @@ void ScummEngine_v6::o6_roomOps() {
case SO_ROOM_NEW_PALETTE:
a = pop();
- // This opcode is used when turning off noir mode in Sam & Max,
- // but since our implementation of this feature doesn't change
- // the original palette there's no need to reload it. Doing it
- // this way, we avoid some graphics glitches that the original
- // interpreter had.
-
- if (_game.id == GID_SAMNMAX && _currentScript != 0xFF && vm.slot[_currentScript].number == 64)
+ // This opcode is used when turning off noir mode in Sam & Max;
+ // the original exhibited some minor glitches during this mode,
+ // so we have two ways to perform it: the accurate one, and our
+ // improved one...
+ if (_game.id == GID_SAMNMAX && enhancementEnabled(kEnhMinorBugFixes) &&
+ _currentScript != 0xFF && vm.slot[_currentScript].number == 64) {
setDirtyColors(0, 255);
- else
+ } else {
setCurrentPalette(a);
+ }
+
break;
default:
error("o6_roomOps: default case %d", subOp);
@@ -3222,17 +3223,21 @@ void ScummEngine_v6::o6_kernelSetFunctions() {
case 114:
// Sam & Max film noir mode
if (_game.id == GID_SAMNMAX) {
- // At this point ScummVM will already have set
- // variable 0x8000 to indicate that the game is
- // in film noir mode. All we have to do here is
- // to mark the palette as "dirty", because
- // updatePalette() will desaturate the colors
- // as they are uploaded to the backend.
- //
- // This actually works better than the original
- // interpreter, where actors would sometimes
- // still be drawn in color.
- setDirtyColors(0, 255);
+ if (enhancementEnabled(kEnhMinorBugFixes)) {
+ // At this point ScummVM will already have set
+ // variable 0x8000 to indicate that the game is
+ // in film noir mode. All we have to do here is
+ // to mark the palette as "dirty", because
+ // updatePalette() will desaturate the colors
+ // as they are uploaded to the backend.
+ //
+ // This actually works better than the original
+ // interpreter, where actors would sometimes
+ // still be drawn in color.
+ setDirtyColors(0, 255);
+ } else {
+ applyGrayscaleToPaletteRange(0, 254);
+ }
} else
error("stub o6_kernelSetFunctions_114()");
break;
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index 13b92cbb3db..1b9c0d44609 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -1386,6 +1386,7 @@ protected:
virtual void palManipulateInit(int resID, int start, int end, int time);
void palManipulate();
uint32 findClosestPaletteColor(byte *palette, int paletteLength, byte r, byte g, byte b);
+ void applyGrayscaleToPaletteRange(int min, int max); // For Sam&Max original noir mode
public:
uint8 *getHEPaletteSlot(uint16 palSlot);
More information about the Scummvm-git-logs
mailing list