mirror of
https://github.com/scummvm/scummvm.git
synced 2026-06-20 05:45:29 +00:00
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).
This commit is contained in:
@@ -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.
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
+131
-32
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
+10
-1
@@ -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;
|
||||
|
||||
+38
-15
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -52,6 +52,10 @@ public:
|
||||
int checkV2Inventory(int x, int y);
|
||||
void redrawV2Inventory();
|
||||
|
||||
protected:
|
||||
byte _hiLiteColorVerbArrow = 0x0E;
|
||||
byte _hiLiteColorInvSentence = 0x0E;
|
||||
|
||||
protected:
|
||||
void setupOpcodes() override;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
+16
-12
@@ -194,16 +194,20 @@ void ScummEngine_v0::switchActor(int slot) {
|
||||
|
||||
void ScummEngine_v2::initV2MouseOver() {
|
||||
int i;
|
||||
int arrow_color, color, hi_color;
|
||||
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.version == 2) {
|
||||
color = 13;
|
||||
hi_color = 14;
|
||||
arrow_color = 1;
|
||||
} else {
|
||||
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() {
|
||||
|
||||
Reference in New Issue
Block a user