[Scummvm-git-logs] scummvm master -> 97fbe867cb9121863e4ba07443c3852651b7fced
athrxx
noreply at scummvm.org
Sat Jul 9 23:04:56 UTC 2022
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
bd1f3ff984 COMMON: add CGA Composite render mode
97fbe867cb SCUMM: (MMv1/ZAKv1) - add support for CGA, CGA Composite and Hercules modes
Commit: bd1f3ff9845eb42c0df98d8d6d5da9460a6accd7
https://github.com/scummvm/scummvm/commit/bd1f3ff9845eb42c0df98d8d6d5da9460a6accd7
Author: athrxx (athrxx at scummvm.org)
Date: 2022-07-10T01:04:38+02:00
Commit Message:
COMMON: add CGA Composite render mode
(for SCUMM v1)
Changed paths:
common/gui_options.cpp
common/gui_options.h
common/rendermode.cpp
common/rendermode.h
diff --git a/common/gui_options.cpp b/common/gui_options.cpp
index 23a1253f660..39d41275776 100644
--- a/common/gui_options.cpp
+++ b/common/gui_options.cpp
@@ -63,12 +63,13 @@ const struct GameOpt {
{ GUIO_RENDERHERCGREEN, "hercGreen" },
{ GUIO_RENDERHERCAMBER, "hercAmber" },
{ GUIO_RENDERCGA, "cga" },
+ { GUIO_RENDERCGACOMP, "cgacomp" },
{ GUIO_RENDEREGA, "ega" },
{ GUIO_RENDERVGA, "vga" },
{ GUIO_RENDERAMIGA, "amiga" },
{ GUIO_RENDERFMTOWNS, "fmtowns" },
{ GUIO_RENDERPC9821, "pc9821" },
- { GUIO_RENDERPC9801, "pc9801" },
+ { GUIO_RENDERPC9801, "pc9801" },
{ GUIO_RENDERAPPLE2GS, "2gs" },
{ GUIO_RENDERATARIST, "atari" },
{ GUIO_RENDERMACINTOSH, "macintosh" },
@@ -145,7 +146,7 @@ const String getGameGUIOptionsDescription(const String &options) {
String res;
for (int i = 0; g_gameOptions[i].desc; i++)
- if (options.contains(g_gameOptions[i].option[0]))
+ if (options.contains(g_gameOptions[i].option[0]))
res += String(g_gameOptions[i].desc) + " ";
res.trim();
diff --git a/common/gui_options.h b/common/gui_options.h
index 8c531084cec..c56a5439bd4 100644
--- a/common/gui_options.h
+++ b/common/gui_options.h
@@ -59,6 +59,7 @@
#define GUIO_RENDERATARIST "\x22"
#define GUIO_RENDERMACINTOSH "\x23"
#define GUIO_RENDERMACINTOSHBW "\x28" // Setting this to 0x28 is not ideal, but there is no free slot left. Maybe we need to migrate to 3-digit numbers...
+#define GUIO_RENDERCGACOMP "\x29"
#define GUIO_LINKSPEECHTOSFX "\x24"
#define GUIO_LINKMUSICTOSFX "\x25"
diff --git a/common/rendermode.cpp b/common/rendermode.cpp
index a9815459664..630e0b78e95 100644
--- a/common/rendermode.cpp
+++ b/common/rendermode.cpp
@@ -34,6 +34,7 @@ const RenderModeDescription g_renderModes[] = {
{ "hercGreen", _s("Hercules Green"), kRenderHercG },
{ "hercAmber", _s("Hercules Amber"), kRenderHercA },
{ "cga", "CGA", kRenderCGA },
+ { "cgaComp", "CGA Composite", kRenderCGAComp },
{ "ega", "EGA", kRenderEGA },
{ "vga", "VGA", kRenderVGA },
{ "amiga", "Amiga", kRenderAmiga },
@@ -69,7 +70,8 @@ static const RenderGUIOMapping s_renderGUIOMapping[] = {
{ kRenderApple2GS, GUIO_RENDERAPPLE2GS },
{ kRenderAtariST, GUIO_RENDERATARIST },
{ kRenderMacintosh, GUIO_RENDERMACINTOSH },
- { kRenderMacintoshBW, GUIO_RENDERMACINTOSHBW }
+ { kRenderMacintoshBW, GUIO_RENDERMACINTOSHBW },
+ { kRenderCGAComp, GUIO_RENDERCGACOMP },
};
DECLARE_TRANSLATION_ADDITIONAL_CONTEXT("Hercules Green", "lowres")
diff --git a/common/rendermode.h b/common/rendermode.h
index 4fad2b40f87..145e0ffe48e 100644
--- a/common/rendermode.h
+++ b/common/rendermode.h
@@ -57,7 +57,8 @@ enum RenderMode {
kRenderApple2GS = 10,
kRenderAtariST = 11,
kRenderMacintosh = 12,
- kRenderMacintoshBW = 13
+ kRenderMacintoshBW = 13,
+ kRenderCGAComp = 14
};
struct RenderModeDescription {
Commit: 97fbe867cb9121863e4ba07443c3852651b7fced
https://github.com/scummvm/scummvm/commit/97fbe867cb9121863e4ba07443c3852651b7fced
Author: athrxx (athrxx at scummvm.org)
Date: 2022-07-10T01:04:38+02:00
Commit Message:
SCUMM: (MMv1/ZAKv1) - add support for CGA, CGA Composite and Hercules modes
This does not improve anything about these modes for v2 and v3, except:
- brighter CGA colors
- v2 will also get the more accurate Hercules mouse cursor
I will do improve v2/v3 as separate tasks. v3 seems to be mostly fine, anyway, except for the actors (we dither them just like the backgrounds, but that looks different in DOSBox).
Changed paths:
NEWS.md
engines/scumm/charset.cpp
engines/scumm/costume.cpp
engines/scumm/cursor.cpp
engines/scumm/gfx.cpp
engines/scumm/gfx.h
engines/scumm/input.cpp
engines/scumm/palette.cpp
engines/scumm/saveload.cpp
engines/scumm/script_v2.cpp
engines/scumm/scumm.cpp
engines/scumm/scumm.h
engines/scumm/scumm_v2.h
engines/scumm/vars.cpp
engines/scumm/verbs.cpp
diff --git a/NEWS.md b/NEWS.md
index 5735674ad36..60f3965c641 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -20,6 +20,10 @@ For a more comprehensive changelog of the latest experimental code, see:
- Added support for the Korean version of Legend of Kyrandia 1.
- Added support for the Hebrew version of Legend of Kyrandia 3.
+ SCUMM:
+ - Add support for CGA, CGA Composite and Hercules modes for SCUMM 1
+ versions of Zak McKracken and Maniac Mansion.
+
Toon:
- Made game menus behave like in the original.
diff --git a/engines/scumm/charset.cpp b/engines/scumm/charset.cpp
index b313e807728..ab505f8c295 100644
--- a/engines/scumm/charset.cpp
+++ b/engines/scumm/charset.cpp
@@ -943,6 +943,10 @@ void CharsetRendererV3::drawChar(int chr, Graphics::Surface &s, int x, int y) {
}
void CharsetRenderer::translateColor() {
+ // Don't do anything for v1 here.
+ if (_vm->_game.version == 1)
+ return;
+
// Based on disassembly
if (_vm->_renderMode == Common::kRenderCGA) {
static const byte CGAtextColorMap[16] = {0, 3, 3, 3, 5, 5, 5, 15,
diff --git a/engines/scumm/costume.cpp b/engines/scumm/costume.cpp
index 5bbacde979a..44c242a4849 100644
--- a/engines/scumm/costume.cpp
+++ b/engines/scumm/costume.cpp
@@ -319,9 +319,11 @@ byte ClassicCostumeRenderer::mainRoutine(int xmoveCur, int ymoveCur) {
return drawFlag;
}
+// Skin colors
static const int v1MMActorPalatte1[25] = {
8, 8, 8, 8, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
};
+// Suit colors
static const int v1MMActorPalatte2[25] = {
0, 7, 2, 6, 9, 1, 3, 7, 7, 1, 1, 9, 1, 4, 5, 5, 4, 1, 0, 5, 4, 2, 2, 7, 7
};
@@ -359,16 +361,16 @@ void ClassicCostumeRenderer::procC64(Codec1 &v1, int actor) {
byte palette[4] = { 0, 0, 0, 0 };
if (_vm->getCurrentLights() & LIGHTMODE_actor_use_colors) {
if (_vm->_game.id == GID_MANIAC) {
- palette[1] = v1MMActorPalatte1[actor];
- palette[2] = v1MMActorPalatte2[actor];
+ palette[1] = _vm->_gdi->remapColorToRenderMode(v1MMActorPalatte1[actor]);
+ palette[2] = _vm->_gdi->remapColorToRenderMode(v1MMActorPalatte2[actor]);
} else {
// Adjust for C64 version of Zak McKracken
- palette[1] = (_vm->_game.platform == Common::kPlatformC64) ? 10 : 8;
- palette[2] = _palette[actor];
+ palette[1] = _vm->_gdi->remapColorToRenderMode(_vm->_game.platform == Common::kPlatformC64 ? 10 : 8);
+ palette[2] = _vm->_gdi->remapColorToRenderMode(_palette[actor]);
}
} else {
- palette[2] = 11;
- palette[3] = 11;
+ palette[2] = _vm->_gdi->remapColorToRenderMode(11);
+ palette[3] = _vm->_gdi->remapColorToRenderMode(11);
}
mask = v1.mask_ptr;
diff --git a/engines/scumm/cursor.cpp b/engines/scumm/cursor.cpp
index d0de41ab8ad..34e72766718 100644
--- a/engines/scumm/cursor.cpp
+++ b/engines/scumm/cursor.cpp
@@ -41,7 +41,7 @@ namespace Scumm {
/*
* Mouse cursor cycle colors (for the default crosshair).
*/
-static const byte default_v1_cursor_colors[4] = {
+static const byte default_v0_cursor_colors[4] = {
1, 1, 12, 11
};
@@ -465,10 +465,14 @@ void ScummEngine_v2::setBuiltinCursor(int idx) {
memset(_grabbedCursor, 0xFF, sizeof(_grabbedCursor));
- if (_game.version <= 1)
- color = default_v1_cursor_colors[idx];
+ if (_game.version == 0)
+ color = default_v0_cursor_colors[idx];
+ else if (_renderMode == Common::kRenderCGA || _renderMode == Common::kRenderCGAComp)
+ color = (idx & 1) * 3;
+ else if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG)
+ color = idx & 1;
else
- color = default_cursor_colors[idx];
+ color = default_cursor_colors[idx];
if (_game.platform == Common::kPlatformNES) {
_cursor.width = 8;
@@ -561,6 +565,29 @@ void ScummEngine_v2::setBuiltinCursor(int idx) {
*(hotspot - (_cursor.width * 5) + 1) = color;
*(hotspot + (_cursor.width * 5) - 1) = color;
*(hotspot + (_cursor.width * 5) + 1) = color;
+
+ if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
+ const byte *src = &_grabbedCursor[_cursor.width * _cursor.height - 1];
+
+ _cursor.width <<= 1;
+ _cursor.height <<= 1;
+ _cursor.hotspotX <<= 1;
+ _cursor.hotspotY <<= 1;
+
+ byte *dst1 = &_grabbedCursor[_cursor.width * _cursor.height - 1];
+ byte *dst2 = dst1 - _cursor.width;
+
+ while (dst2 >= _grabbedCursor) {
+ for (i = _cursor.width >> 1; i; --i) {
+ *dst2-- = *src;
+ *dst2-- = *src--;
+ *dst1-- = 0xFF;
+ *dst1-- = 0xFF;
+ }
+ dst1 -= _cursor.width;
+ dst2 -= _cursor.width;
+ }
+ }
}
updateCursor();
diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp
index d033d1f3d5f..93d7006a3fa 100644
--- a/engines/scumm/gfx.cpp
+++ b/engines/scumm/gfx.cpp
@@ -246,6 +246,15 @@ GdiV1::GdiV1(ScummEngine *vm) : Gdi(vm) {
memset(&_V1, 0, sizeof(_V1));
}
+void GdiV1::setRenderModeColorMap(const byte *map) {
+ _colorMap = map;
+}
+
+byte GdiV1::remapColorToRenderMode(byte col) const {
+ assert(_colorMap);
+ return _colorMap[col];
+}
+
GdiV2::GdiV2(ScummEngine *vm) : Gdi(vm) {
_roomStrips = nullptr;
}
@@ -736,29 +745,12 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i
src = _compositeBuf;
pitch = width * vs->format.bytesPerPixel;
- if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
- ditherHerc(_compositeBuf, _herculesBuf, width, &x, &y, &width, &height);
-
- src = _herculesBuf + x + y * kHercWidth;
- pitch = kHercWidth;
-
- // center image on the screen
- x += (kHercWidth - _screenWidth * 2) / 2; // (720 - 320*2)/2 = 40
- } else if (_useCJKMode && m == 2) {
- pitch *= m;
- x *= m;
- y *= m;
- width *= m;
- height *= m;
- } else {
- if (_renderMode == Common::kRenderCGA)
- ditherCGA(_compositeBuf, width, x, y, width, height);
-
+ if (_game.platform == Common::kPlatformNES) {
// HACK: This is dirty hack which renders narrow NES rooms centered
// NES can address negative number strips and that poses problem for
// our code. So instead of adding zillions of fixes and potentially
// breaking other games, we shift it right at the rendering stage.
- if ((_game.platform == Common::kPlatformNES) && (((_NESStartStrip > 0) && (vs->number == kMainVirtScreen)) || (vs->number == kTextVirtScreen))) {
+ if (((_NESStartStrip > 0) && (vs->number == kMainVirtScreen)) || (vs->number == kTextVirtScreen)) {
x += 16;
while (x + width >= _screenWidth)
width -= 16;
@@ -775,7 +767,27 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i
_system->copyRectToScreen(blackbuf, 16, 0, 0, 16, 240); // Fix left strip
}
}
+ } else if (_game.version == 1) {
+ src = postProcessV1Graphics(vs, x, y, width, height);
+ if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG)
+ pitch = kHercWidth;
+ } else if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
+ ditherHerc(_compositeBuf, _herculesBuf, width, &x, &y, &width, &height);
+
+ src = _herculesBuf + x + y * kHercWidth;
+ pitch = kHercWidth;
+
+ // center image on the screen
+ x += (kHercWidth - _screenWidth * 2) / 2; // (720 - 320*2)/2 = 40
+ } else if (_useCJKMode && m == 2) {
+ pitch *= m;
+ x *= m;
+ y *= m;
+ width *= m;
+ height *= m;
+ } else if (_renderMode == Common::kRenderCGA) {
+ ditherCGA(_compositeBuf, width, x, y, width, height);
}
}
@@ -783,6 +795,94 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i
_system->copyRectToScreen(src, pitch, x, y, width, height);
}
+const byte *ScummEngine::postProcessV1Graphics(VirtScreen *vs, int &x, int &y, int &width, int &height) const {
+ static const byte zakVrbColMap[] = { 0x0, 0x5, 0x5, 0x5, 0xA, 0xA, 0xA, 0xF, 0xF, 0x5, 0x5, 0x5, 0xA, 0xA, 0xF, 0xF };
+ static const byte zakTxtColMap[] = { 0x0, 0xF, 0xA, 0x5, 0xA, 0x5, 0x5, 0xF, 0xA, 0xA, 0xA, 0xA, 0xA, 0x5, 0x5, 0xF };
+ static const byte mmVrbColMap[] = { 0x0, 0x5, 0x5, 0x5, 0xA, 0xA, 0xA, 0xF, 0xA, 0x5, 0x5, 0x5, 0xA, 0xA, 0xA, 0xF };
+
+ byte mmTxtColMap[16];
+ for (uint8 i = 0; i < ARRAYSIZE(mmTxtColMap); ++i)
+ mmTxtColMap[i] = mmVrbColMap[_gdi->remapColorToRenderMode(i)];
+
+ byte *res = _compositeBuf;
+ byte *dst = _compositeBuf;
+ const byte *src = res;
+
+ if (_renderMode == Common::kRenderCGA || _renderMode == Common::kRenderCGAComp) {
+ const byte *colMap = (_game.id == GID_ZAK) ? (vs->number == kVerbVirtScreen ? zakVrbColMap : zakTxtColMap) : (vs->number == kVerbVirtScreen ? mmVrbColMap : mmTxtColMap);
+
+ if (vs->number == kMainVirtScreen) {
+ for (int h = height; h; --h) {
+ for (int w = width >> 1; w; --w) {
+ *dst++ = (*src++ >> 2) & 3;
+ *dst++ = *src++ & 3;
+ }
+ }
+ } else {
+ for (int h = height; h; --h) {
+ for (int w = width >> 1; w; --w) {
+ *dst++ = (colMap[*src++] >> 2) & 3;
+ *dst++ = colMap[*src++] & 3;
+ }
+ }
+ }
+
+ } else if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
+ const byte *colMap = (_game.id == GID_ZAK) ? zakVrbColMap : (vs->number == kVerbVirtScreen ? mmVrbColMap : mmTxtColMap);
+ dst = res = _herculesBuf;
+
+ if (vs->number == kMainVirtScreen) {
+ uint32 *dst2 = (uint32*)(dst + kHercWidth);
+ int pitch = (kHercWidth - width) << 1;
+ int pitch2 = pitch >> 2;
+ y = (y - vs->topline) * 2 + vs->topline;
+ height = MIN<int>(height << 1, kHercHeight - y);
+
+ for (int h = height >> 1; h; --h) {
+ for (int w = width >> 1; w; --w) {
+ *dst++ = (*src >> 3) & 1;
+ *dst++ = (*src >> 2) & 1;
+ *dst++ = (*src >> 1) & 1;
+ *dst++ = *src & 1;
+ *dst2++ = 0;
+ src += 2;
+ }
+ dst += pitch;
+ dst2 += pitch2;
+ }
+
+ } else {
+ int pitch = kHercWidth - (width << 1);
+ y -= vs->topline;
+ if (vs->number == kVerbVirtScreen) {
+ y += vs->topline * 2 - 16;
+ height = MIN<int>(height, kHercHeight - y);
+ }
+
+ for (int h = height; h; --h) {
+ for (int w = width; w; --w) {
+ uint8 col = colMap[*src++];
+ *dst++ = (col >> 1) & 1;
+ *dst++ = col & 1;
+ }
+ dst += pitch;
+ }
+ }
+
+ x = x * 2 + 40;
+ width *= 2;
+
+ } else if (vs->number == kTextVirtScreen) {
+ // For EGA, the omly colors that need remapping are for the kTextVirtScreen.
+ for (int h = height; h; --h) {
+ for (int w = width; w; --w)
+ *dst++ = _gdi->remapColorToRenderMode(*src++);
+ }
+ }
+
+ return res;
+}
+
// CGA
// indy3 loom maniac monkey1 zak
//
@@ -798,17 +898,16 @@ static const byte cgaDither[2][2][16] = {
{{0, 0, 1, 1, 0, 2, 2, 3, 0, 3, 1, 1, 3, 3, 1, 3},
{0, 1, 0, 1, 2, 2, 0, 0, 3, 1, 1, 1, 3, 2, 1, 3}}};
-// CGA dithers 4x4 square with direct substitutes
-// Odd lines have colors swapped, so there will be checkered patterns.
-// But apparently there is a mistake for 10th color.
void ScummEngine::ditherCGA(byte *dst, int dstPitch, int x, int y, int width, int height) const {
byte *ptr;
int idx1, idx2;
-
+ // CGA dithers 4x4 square with direct substitutes
+ // Odd lines have colors swapped, so there will be checkered patterns.
+ // But apparently there is a mistake for 10th color.
for (int y1 = 0; y1 < height; y1++) {
ptr = dst + y1 * dstPitch;
- if (_game.version == 2)
+ if (_game.version <= 2)
idx1 = 0;
else
idx1 = (y + y1) % 2;
@@ -3172,10 +3271,10 @@ void GdiV1::drawStripV1Background(byte *dst, int dstPitch, int stripnr, int heig
charIdx = _V1.picMap[y + stripnr * height] * 8;
for (int i = 0; i < 8; i++) {
byte c = _V1.charMap[charIdx + i];
- dst[0] = dst[1] = _V1.colors[(c >> 6) & 3];
- dst[2] = dst[3] = _V1.colors[(c >> 4) & 3];
- dst[4] = dst[5] = _V1.colors[(c >> 2) & 3];
- dst[6] = dst[7] = _V1.colors[(c >> 0) & 3];
+ dst[0] = dst[1] = _colorMap[_V1.colors[(c >> 6) & 3]];
+ dst[2] = dst[3] = _colorMap[_V1.colors[(c >> 4) & 3]];
+ dst[4] = dst[5] = _colorMap[_V1.colors[(c >> 2) & 3]];
+ dst[6] = dst[7] = _colorMap[_V1.colors[(c >> 0) & 3]];
dst += dstPitch;
}
}
@@ -3190,10 +3289,10 @@ void GdiV1::drawStripV1Object(byte *dst, int dstPitch, int stripnr, int width, i
charIdx = _V1.objectMap[y * width + stripnr] * 8;
for (int i = 0; i < 8; i++) {
byte c = _V1.charMap[charIdx + i];
- dst[0] = dst[1] = _V1.colors[(c >> 6) & 3];
- dst[2] = dst[3] = _V1.colors[(c >> 4) & 3];
- dst[4] = dst[5] = _V1.colors[(c >> 2) & 3];
- dst[6] = dst[7] = _V1.colors[(c >> 0) & 3];
+ dst[0] = dst[1] = _colorMap[_V1.colors[(c >> 6) & 3]];
+ dst[2] = dst[3] = _colorMap[_V1.colors[(c >> 4) & 3]];
+ dst[4] = dst[5] = _colorMap[_V1.colors[(c >> 2) & 3]];
+ dst[6] = dst[7] = _colorMap[_V1.colors[(c >> 0) & 3]];
dst += dstPitch;
}
}
diff --git a/engines/scumm/gfx.h b/engines/scumm/gfx.h
index e3754a152c8..79e92564f95 100644
--- a/engines/scumm/gfx.h
+++ b/engines/scumm/gfx.h
@@ -270,6 +270,9 @@ public:
Gdi(ScummEngine *vm);
virtual ~Gdi();
+ virtual void setRenderModeColorMap(const byte *map) {}
+ virtual byte remapColorToRenderMode(byte col) const { return col; }
+
virtual void init();
virtual void roomChanged(byte *roomptr);
virtual void loadTiles(byte *roomptr);
@@ -404,6 +407,8 @@ protected:
byte maskMap[4096], maskChar[4096];
} _V1;
+ const byte *_colorMap;
+
protected:
void decodeV1Gfx(const byte *src, byte *dst, int size) const;
@@ -426,6 +431,9 @@ protected:
public:
GdiV1(ScummEngine *vm);
+ void setRenderModeColorMap(const byte *map) override;
+ byte remapColorToRenderMode(byte col) const override;
+
void roomChanged(byte *roomptr) override;
};
diff --git a/engines/scumm/input.cpp b/engines/scumm/input.cpp
index 9d478908150..1ff06dd54f9 100644
--- a/engines/scumm/input.cpp
+++ b/engines/scumm/input.cpp
@@ -199,7 +199,16 @@ void ScummEngine::parseEvent(Common::Event event) {
if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
_mouse.x -= (kHercWidth - _screenWidth * 2) / 2;
_mouse.x >>= 1;
- _mouse.y = _mouse.y * 4 / 7;
+ if (_game.version == 1) {
+ if (_mouse.y >= _virtscr[kMainVirtScreen].topline)
+ _mouse.y = _mouse.y / 2 + _virtscr[kMainVirtScreen].topline / 2;
+ if (_mouse.y > _virtscr[kVerbVirtScreen].topline)
+ _mouse.y += (_mouse.y - _virtscr[kVerbVirtScreen].topline);
+
+ } else {
+ _mouse.y = _mouse.y * 4 / 7;
+ }
+
} else if (_macScreen || (_useCJKMode && _textSurfaceMultiplier == 2)) {
_mouse.x >>= 1;
_mouse.y >>= 1;
diff --git a/engines/scumm/palette.cpp b/engines/scumm/palette.cpp
index 474b692e91c..0534127cc5f 100644
--- a/engines/scumm/palette.cpp
+++ b/engines/scumm/palette.cpp
@@ -144,17 +144,11 @@ void ScummEngine::resetPalette() {
0xFF, 0x55, 0x55, 0xFF, 0x55, 0xFF, 0xFF, 0xFF, 0x55, 0xFF, 0xFF, 0xFF
};
- static const byte tableV1Palette[] = {
- 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xAA, 0x00, 0x00, 0x00, 0xAA, 0xAA,
- 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0x00, 0x00, 0xAA, 0xFF, 0xFF, 0x55,
- 0xFF, 0x55, 0x55, 0xAA, 0x55, 0x00, 0xFF, 0x55, 0x55, 0x55, 0x55, 0x55,
- 0xAA, 0xAA, 0xAA, 0x55, 0xFF, 0x55, 0x55, 0x55, 0xFF, 0x55, 0x55, 0x55,
-
- 0xFF, 0x55, 0xFF
- };
-
- static const byte tableCGAPalette[] = {
- 0x00, 0x00, 0x00, 0x00, 0xA8, 0xA8, 0xA8, 0x00, 0xA8, 0xA8, 0xA8, 0xA8
+ static const byte _cgaColors[4][12] = {
+ { 0x00, 0x00, 0x00, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0x00, 0xAA, 0x55, 0x00 },
+ { 0x00, 0x00, 0x00, 0x55, 0xFF, 0x55, 0xFF, 0x55, 0x55, 0xFF, 0xFF, 0x55 },
+ { 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0x00, 0xAA, 0xAA, 0xAA, 0xAA },
+ { 0x00, 0x00, 0x00, 0x55, 0xFF, 0xFF, 0xFF, 0x55, 0xFF, 0xFF, 0xFF, 0xFF }
};
static const byte tableHercAPalette[] = {
@@ -194,6 +188,9 @@ void ScummEngine::resetPalette() {
#endif
#endif
+ int cgaPalIndex = 1;
+ int cgaPalIntensity = 1;
+
if (_game.version <= 1) {
if (_game.platform == Common::kPlatformApple2GS) {
setPaletteFromTable(tableApple2gsPalette, sizeof(tableApple2gsPalette) / 3);
@@ -204,10 +201,14 @@ void ScummEngine::resetPalette() {
setPaletteFromTable(tableNESClassicPalette, sizeof(tableNESClassicPalette) / 3);
else
setPaletteFromTable(tableNESNTSCPalette, sizeof(tableNESNTSCPalette) / 3);
+ } else if (_renderMode == Common::kRenderHercA) {
+ setPaletteFromTable(tableHercAPalette, sizeof(tableHercAPalette) / 3);
+ } else if (_renderMode == Common::kRenderHercG) {
+ setPaletteFromTable(tableHercGPalette, sizeof(tableHercGPalette) / 3);
+ } else if (_renderMode == Common::kRenderCGA || _renderMode == Common::kRenderCGAComp) {
+ setPaletteFromTable(_cgaColors[cgaPalIndex * 2 + cgaPalIntensity], sizeof(_cgaColors[0]) / 3);
} else {
- setPaletteFromTable(tableV1Palette, sizeof(tableV1Palette) / 3);
- if (_game.id == GID_ZAK)
- setPalColor(15, 170, 170, 170);
+ setPaletteFromTable(tableEGAPalette, sizeof(tableEGAPalette) / 3);
}
} else if (_game.features & GF_16COLOR) {
bool setupCursor = false;
@@ -226,7 +227,7 @@ void ScummEngine::resetPalette() {
break;
case Common::kRenderCGA:
- setPaletteFromTable(tableCGAPalette, sizeof(tableCGAPalette) / 3);
+ setPaletteFromTable(_cgaColors[cgaPalIndex * 2 + cgaPalIntensity], sizeof(_cgaColors[0]) / 3);
setupCursor = true;
break;
@@ -463,6 +464,28 @@ void ScummEngine::setAmigaPaletteFromPtr(const byte *ptr) {
setDirtyColors(0, 255);
}
+void ScummEngine::updateColorTableV1(int renderMode) {
+ static const byte v1ColorMaps[5][16] = {
+ // C-64: Just leave everything the way it is
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F },
+ // ZAK: EGA, Tandy, MCGA, CGA Composite
+ { 0x00, 0x0F, 0x04, 0x03, 0x05, 0x02, 0x01, 0x0E, 0x0C, 0x06, 0x0D, 0x08, 0x07, 0x0A, 0x09, 0x07 },
+ // ZAK: CGA, CGA B&W, Hercules
+ { 0x00, 0x0F, 0x08, 0x05, 0x0A, 0x05, 0x01, 0x0D, 0x0A, 0x02, 0x0A, 0x0C, 0x0F, 0x0A, 0x05, 0x0C },
+ // MM: EGA, Tandy, MCGA, CGA Composite
+ { 0x00, 0x0F, 0x04, 0x03, 0x05, 0x02, 0x01, 0x0E, 0x0C, 0x06, 0x0C, 0x08, 0x07, 0x0A, 0x09, 0x08 },
+ // MM: CGA, CGA B&W, Hercules
+ { 0x00, 0x0F, 0x08, 0x05, 0x0A, 0x05, 0x01, 0x0D, 0x0A, 0x02, 0x0A, 0x0C, 0x0F, 0x0A, 0x05, 0x0C }
+ };
+
+ int tbl = (_game.platform == Common::kPlatformC64) ? 0 : (_game.id == GID_ZAK ? 1 : 3);
+ if (renderMode == Common::kRenderHercA || renderMode == Common::kRenderHercG || renderMode == Common::kRenderCGA)
+ ++tbl;
+
+ assert(_gdi);
+ _gdi->setRenderModeColorMap(v1ColorMaps[tbl]);
+}
+
void ScummEngine::amigaPaletteFindFirstUsedColor() {
for (_amigaFirstUsedColor = 80; _amigaFirstUsedColor < 256; ++_amigaFirstUsedColor) {
// We look for the first used color here. If all color components are
diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp
index 72d2b35f43e..07b574620a2 100644
--- a/engines/scumm/saveload.cpp
+++ b/engines/scumm/saveload.cpp
@@ -67,7 +67,7 @@ struct SaveInfoSection {
#define SaveInfoSectionSize (4+4+4 + 4+4 + 4+2)
-#define CURRENT_VER 105
+#define CURRENT_VER 106
#define INFOSECTION_VERSION 2
#pragma mark -
@@ -1567,6 +1567,19 @@ void ScummEngine_v2::saveLoadWithSerializer(Common::Serializer &s) {
s.syncAsByte(_flashlight.xStrips, VER(99));
s.syncAsByte(_flashlight.yStrips, VER(99));
+
+ // Old saves are based on a diffenrent color mapping, so the verb
+ // colors need to be adjusted.
+ if (s.getVersion() < VER(106) && s.isLoading()) {
+ initV2MouseOver();
+ for (int i = 0; i < _numVerbs; ++i) {
+ if (!_verbs[i].verbid)
+ continue;
+ _verbs[i].color = 2;
+ _verbs[i].hicolor = _hiLiteColorVerbArrow;
+ _verbs[i].dimcolor = 8;
+ }
+ }
}
void ScummEngine_v5::saveLoadWithSerializer(Common::Serializer &s) {
diff --git a/engines/scumm/script_v2.cpp b/engines/scumm/script_v2.cpp
index ba5d347578e..61d1f3a4ed0 100644
--- a/engines/scumm/script_v2.cpp
+++ b/engines/scumm/script_v2.cpp
@@ -849,13 +849,13 @@ void ScummEngine_v2::o2_verbOps() {
vs->color = 1;
vs->hicolor = 1;
vs->dimcolor = 1;
- } else if (_game.version == 1) {
- vs->color = (_game.id == GID_MANIAC && (_game.features & GF_DEMO)) ? 16 : 5;
+ } else if (_game.platform == Common::kPlatformC64) {
+ vs->color = 5;
vs->hicolor = 7;
vs->dimcolor = 11;
} else {
vs->color = (_game.id == GID_MANIAC && (_game.features & GF_DEMO)) ? 13 : 2;
- vs->hicolor = 14;
+ vs->hicolor = _hiLiteColorVerbArrow;
vs->dimcolor = 8;
}
vs->type = kTextVerbType;
@@ -1088,10 +1088,11 @@ void ScummEngine_v2::o2_drawSentence() {
if (_game.platform == Common::kPlatformNES) {
_string[2].xpos = 16;
_string[2].color = 0;
- } else if (_game.version == 1)
+ } else if (_game.platform == Common::kPlatformC64) {
_string[2].color = 16;
- else
+ } else {
_string[2].color = 13;
+ }
byte string[80];
const char *ptr = _sentenceBuf.c_str();
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 0ce1f69eab5..9e5d6d94ab3 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -247,10 +247,6 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
dialog.runModal();
}
- // Check some render mode restrictions
- if (_game.version <= 1)
- _renderMode = Common::kRenderDefault;
-
switch (_renderMode) {
case Common::kRenderHercA:
case Common::kRenderHercG:
@@ -258,6 +254,7 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
_renderMode = Common::kRenderDefault;
break;
+ case Common::kRenderCGAComp:
case Common::kRenderCGA:
case Common::kRenderEGA:
case Common::kRenderAmiga:
@@ -323,6 +320,7 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
_herculesBuf = (byte *)malloc(kHercWidth * kHercHeight);
}
+ updateColorTableV1(_renderMode);
_isRTL = (_language == Common::HE_ISR && _game.heversion == 0)
&& (_game.id == GID_MANIAC || (_game.version >= 4 && _game.version < 7));
@@ -390,6 +388,7 @@ ScummEngine::~ScummEngine() {
free(_compositeBuf);
free(_herculesBuf);
+ delete[] _ditheringTableV1;
free(_16BitPalette);
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index 052e0082d61..e99fc357e17 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -1025,6 +1025,7 @@ protected:
void setPCEPaletteFromPtr(const byte *ptr);
void setAmigaPaletteFromPtr(const byte *ptr);
virtual void setPaletteFromPtr(const byte *ptr, int numcolor = -1);
+ void updateColorTableV1(int renderMode);
virtual void setPalColor(int index, int r, int g, int b);
void setDirtyColors(int min, int max);
@@ -1059,6 +1060,7 @@ protected:
// Screen rendering
byte *_compositeBuf;
byte *_herculesBuf = nullptr;
+ const uint16 *_ditheringTableV1 = nullptr;
virtual void drawDirtyScreenParts();
void updateDirtyScreen(VirtScreenNumber slot);
@@ -1070,6 +1072,7 @@ protected:
void mac_undrawIndy3TextBox();
void mac_undrawIndy3CreditsText();
+ const byte *postProcessV1Graphics(VirtScreen *vs, int &x, int &y, int &width, int &height) const;
void ditherCGA(byte *dst, int dstPitch, int x, int y, int width, int height) const;
public:
diff --git a/engines/scumm/scumm_v2.h b/engines/scumm/scumm_v2.h
index 75f162a3499..37e3048739e 100644
--- a/engines/scumm/scumm_v2.h
+++ b/engines/scumm/scumm_v2.h
@@ -52,6 +52,10 @@ public:
int checkV2Inventory(int x, int y);
void redrawV2Inventory();
+protected:
+ byte _hiLiteColorVerbArrow = 0x0E;
+ byte _hiLiteColorInvSentence = 0x0E;
+
protected:
void setupOpcodes() override;
diff --git a/engines/scumm/vars.cpp b/engines/scumm/vars.cpp
index 78aaa55e917..9f445349e66 100644
--- a/engines/scumm/vars.cpp
+++ b/engines/scumm/vars.cpp
@@ -791,7 +791,7 @@ void ScummEngine::resetScummVars() {
// Value only used by the Amiga version of Monkey Island 2
else if (_game.platform == Common::kPlatformAmiga)
VAR(VAR_VIDEOMODE) = 82;
- else if (_renderMode == Common::kRenderCGA)
+ else if (_renderMode == Common::kRenderCGA || _renderMode == Common::kRenderCGAComp)
VAR(VAR_VIDEOMODE) = 4;
else if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG)
VAR(VAR_VIDEOMODE) = 30;
diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp
index 309ee8e78e1..66c3e3c7d25 100644
--- a/engines/scumm/verbs.cpp
+++ b/engines/scumm/verbs.cpp
@@ -194,16 +194,20 @@ void ScummEngine_v0::switchActor(int slot) {
void ScummEngine_v2::initV2MouseOver() {
int i;
- int arrow_color, color, hi_color;
-
- if (_game.version == 2) {
- color = 13;
- hi_color = 14;
- arrow_color = 1;
- } else {
+ int arrow_color, color;
+ _hiLiteColorVerbArrow = _hiLiteColorInvSentence = 14;
+ if (_renderMode == Common::kRenderCGA || _renderMode == Common::kRenderCGAComp)
+ _hiLiteColorInvSentence = 15;
+ else if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG)
+ _hiLiteColorVerbArrow = _hiLiteColorInvSentence = 15;
+
+ if (_game.platform == Common::kPlatformC64) {
color = 16;
- hi_color = 7;
+ _hiLiteColorVerbArrow = _hiLiteColorInvSentence = 7;
arrow_color = 6;
+ } else {
+ color = 13;
+ arrow_color = 1;
}
_mouseOverBoxV2 = -1;
@@ -217,7 +221,7 @@ void ScummEngine_v2::initV2MouseOver() {
_mouseOverBoxesV2[2 * i].rect.bottom = _mouseOverBoxesV2[2 * i].rect.top + 8;
_mouseOverBoxesV2[2 * i].color = color;
- _mouseOverBoxesV2[2 * i].hicolor = hi_color;
+ _mouseOverBoxesV2[2 * i].hicolor = _hiLiteColorInvSentence;
_mouseOverBoxesV2[2 * i + 1].rect.left = 176;
_mouseOverBoxesV2[2 * i + 1].rect.right = 320;
@@ -225,7 +229,7 @@ void ScummEngine_v2::initV2MouseOver() {
_mouseOverBoxesV2[2 * i + 1].rect.bottom = _mouseOverBoxesV2[2 * i].rect.bottom;
_mouseOverBoxesV2[2 * i + 1].color = color;
- _mouseOverBoxesV2[2 * i + 1].hicolor = hi_color;
+ _mouseOverBoxesV2[2 * i + 1].hicolor = _hiLiteColorInvSentence;
}
// Inventory arrows
@@ -236,7 +240,7 @@ void ScummEngine_v2::initV2MouseOver() {
_mouseOverBoxesV2[kInventoryUpArrow].rect.bottom = 40;
_mouseOverBoxesV2[kInventoryUpArrow].color = arrow_color;
- _mouseOverBoxesV2[kInventoryUpArrow].hicolor = hi_color;
+ _mouseOverBoxesV2[kInventoryUpArrow].hicolor = _hiLiteColorVerbArrow;
_mouseOverBoxesV2[kInventoryDownArrow].rect.left = 144;
_mouseOverBoxesV2[kInventoryDownArrow].rect.right = 176;
@@ -244,7 +248,7 @@ void ScummEngine_v2::initV2MouseOver() {
_mouseOverBoxesV2[kInventoryDownArrow].rect.bottom = 48;
_mouseOverBoxesV2[kInventoryDownArrow].color = arrow_color;
- _mouseOverBoxesV2[kInventoryDownArrow].hicolor = hi_color;
+ _mouseOverBoxesV2[kInventoryDownArrow].hicolor = _hiLiteColorVerbArrow;
// Sentence line
@@ -254,7 +258,7 @@ void ScummEngine_v2::initV2MouseOver() {
_mouseOverBoxesV2[kSentenceLine].rect.bottom = 8;
_mouseOverBoxesV2[kSentenceLine].color = color;
- _mouseOverBoxesV2[kSentenceLine].hicolor = hi_color;
+ _mouseOverBoxesV2[kSentenceLine].hicolor = _hiLiteColorInvSentence;
}
void ScummEngine_v2::initNESMouseOver() {
More information about the Scummvm-git-logs
mailing list