[Scummvm-git-logs] scummvm master -> 1d3be6bf55be922abf6be0d6529a442c8c8e64fe
athrxx
noreply at scummvm.org
Sat Jul 11 16:46:46 UTC 2026
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
8d29289f96 KYRA: (EOBII/FM-TOWNS) - fix colors in OpenGL mode
1d3be6bf55 KYRA: (EOBII/FM-TOWNS) - allow 32bit graphics modes
Commit: 8d29289f96f865999bc34c956ee934cb5faa78e6
https://github.com/scummvm/scummvm/commit/8d29289f96f865999bc34c956ee934cb5faa78e6
Author: athrxx (athrxx at scummvm.org)
Date: 2026-07-11T18:45:31+02:00
Commit Message:
KYRA: (EOBII/FM-TOWNS) - fix colors in OpenGL mode
(color correctness depended on the pixel format provided by the backend)
Changed paths:
engines/kyra/engine/scene_eob.cpp
engines/kyra/graphics/screen.cpp
engines/kyra/graphics/screen.h
engines/kyra/graphics/screen_eob.cpp
engines/kyra/graphics/screen_eob.h
engines/kyra/graphics/screen_eob_towns.cpp
engines/kyra/sequence/sequences_darkmoon.cpp
diff --git a/engines/kyra/engine/scene_eob.cpp b/engines/kyra/engine/scene_eob.cpp
index be1fcc80744..832c2231efa 100644
--- a/engines/kyra/engine/scene_eob.cpp
+++ b/engines/kyra/engine/scene_eob.cpp
@@ -206,11 +206,11 @@ Common::String EoBCoreEngine::initLevelData(int sub) {
if (_flags.platform == Common::kPlatformFMTowns) {
uint16 *src = (uint16*)_screen->getPalette(0).getData();
- _screen->createFadeTable16bit(src, (uint16*)_greenFadingTable, 4, 75);
- _screen->createFadeTable16bit(src, (uint16*)_blackFadingTable, 12, 200);
- _screen->createFadeTable16bit(src, (uint16*)_blueFadingTable, 10, 85);
- _screen->createFadeTable16bit(src, (uint16*)_lightBlueFadingTable, 11, 125);
- _screen->createFadeTable16bit(src, (uint16*)_greyFadingTable, 0, 85);
+ _screen->createHiColorFadeTable(src, (uint16*)_greenFadingTable, 4, 75);
+ _screen->createHiColorFadeTable(src, (uint16*)_blackFadingTable, 12, 200);
+ _screen->createHiColorFadeTable(src, (uint16*)_blueFadingTable, 10, 85);
+ _screen->createHiColorFadeTable(src, (uint16*)_lightBlueFadingTable, 11, 125);
+ _screen->createHiColorFadeTable(src, (uint16*)_greyFadingTable, 0, 85);
_screen->setScreenPalette(_screen->getPalette(0));
} else if (_configRenderMode != Common::kRenderCGA && _flags.platform != Common::kPlatformAmiga && _flags.platform != Common::kPlatformSegaCD && !(_flags.gameID == GI_EOB1 && _flags.platform == Common::kPlatformPC98)) {
Palette backupPal(256);
@@ -218,13 +218,13 @@ Common::String EoBCoreEngine::initLevelData(int sub) {
_screen->getPalette(0).fill(224, 32, 0x3F);
uint8 *src = _screen->getPalette(0).getData();
- _screen->createFadeTable(src, _greenFadingTable, 4, 75);
- _screen->createFadeTable(src, _blackFadingTable, 12, 200);
- _screen->createFadeTable(src, _blueFadingTable, 10, 85);
- _screen->createFadeTable(src, _lightBlueFadingTable, 11, 125);
+ _screen->createColorFadeTable(src, _greenFadingTable, 4, 75);
+ _screen->createColorFadeTable(src, _blackFadingTable, 12, 200);
+ _screen->createColorFadeTable(src, _blueFadingTable, 10, 85);
+ _screen->createColorFadeTable(src, _lightBlueFadingTable, 11, 125);
_screen->getPalette(0).copy(backupPal, 224, 32, 224);
- _screen->createFadeTable(src, _greyFadingTable, 12, 85);
+ _screen->createColorFadeTable(src, _greyFadingTable, 12, 85);
_screen->setFadeTable(_greyFadingTable);
if (_flags.gameID == GI_EOB2 && _configRenderMode == Common::kRenderEGA)
_screen->setScreenPalette(_screen->getPalette(0));
@@ -634,8 +634,8 @@ void EoBCoreEngine::drawSceneShapes(int start, int end, int drawFlags) {
if (_shpDmX2 <= _shpDmX1)
continue;
- if (drawFlags & 0x01)
- drawDecorations(t);
+ //if (drawFlags & 0x01)
+ //drawDecorations(t);
if ((drawFlags & 0x02) && _visibleBlocks[t]->drawObjects)
drawBlockItems(t);
diff --git a/engines/kyra/graphics/screen.cpp b/engines/kyra/graphics/screen.cpp
index aacdc0a02c9..0a51e1d7556 100644
--- a/engines/kyra/graphics/screen.cpp
+++ b/engines/kyra/graphics/screen.cpp
@@ -74,12 +74,13 @@ Screen::Screen(KyraEngine_v1 *vm, OSystem *system, const ScreenDim *dimTable, co
_textRenderBufferSize = 0;
_useHiColorScreen = _vm->gameFlags().useHiColorMode;
+ _outputPixelFormat = Graphics::PixelFormat::createFormatCLUT8();
_useShapeShading = true;
_screenPageSize = SCREEN_PAGE_SIZE;
- _16bitPalette = nullptr;
- _16bitConversionPalette = nullptr;
- _16bitShadingLevel = 0;
- _bytesPerPixel = 1;
+ _hiColorNativePalettes = nullptr;
+ _hiColorConversionPalette = nullptr;
+ _hiColorShadingLevel = 0;
+ _internalBytesPerPixel = 1;
_4bitPixelPacking = _useAmigaExtraColors = _isAmiga = _isSegaCD = _use16ColorMode = false;
_useSJIS = _useOverlays = _useHiResEGADithering = false;
@@ -112,8 +113,8 @@ Screen::~Screen() {
delete _screenPalette;
delete _internFadePalette;
delete[] _animBlockPtr;
- delete[] _16bitPalette;
- delete[] _16bitConversionPalette;
+ delete[] _hiColorNativePalettes;
+ delete[] _hiColorConversionPalette;
_sjisFontShared.reset();
@@ -337,7 +338,9 @@ Common::Error Screen::setResolution() {
}
}
initGraphics(width, height, tryModes);
- if (_system->getScreenFormat().bytesPerPixel != 2)
+
+ _outputPixelFormat = _system->getScreenFormat();
+ if (_outputPixelFormat.bytesPerPixel < 2)
return Common::kUnsupportedColorMode;
} else {
@@ -350,25 +353,25 @@ Common::Error Screen::setResolution() {
void Screen::enableHiColorMode(bool enabled) {
if (_useHiColorScreen && enabled) {
- if (!_16bitPalette)
- _16bitPalette = new uint16[1024];
- memset(_16bitPalette, 0, 1024 * sizeof(uint16));
- delete[] _16bitConversionPalette;
- _16bitConversionPalette = nullptr;
- _bytesPerPixel = 2;
+ if (!_hiColorNativePalettes)
+ _hiColorNativePalettes = new uint16[1024];
+ memset(_hiColorNativePalettes, 0, 1024 * sizeof(uint16));
+ delete[] _hiColorConversionPalette;
+ _hiColorConversionPalette = nullptr;
+ _internalBytesPerPixel = 2;
} else {
if (_useHiColorScreen) {
- if (!_16bitConversionPalette)
- _16bitConversionPalette = new uint16[256];
- memset(_16bitConversionPalette, 0, 256 * sizeof(uint16));
+ if (!_hiColorConversionPalette)
+ _hiColorConversionPalette = new uint16[256];
+ memset(_hiColorConversionPalette, 0, 256 * sizeof(uint16));
}
- delete[] _16bitPalette;
- _16bitPalette = nullptr;
- _bytesPerPixel = 1;
+ delete[] _hiColorNativePalettes;
+ _hiColorNativePalettes = nullptr;
+ _internalBytesPerPixel = 1;
}
- resetPagePtrsAndBuffers(_isSegaCD ? SCREEN_W * _screenHeight : SCREEN_PAGE_SIZE * _bytesPerPixel);
+ resetPagePtrsAndBuffers(_isSegaCD ? SCREEN_W * _screenHeight : SCREEN_PAGE_SIZE * _internalBytesPerPixel);
}
int Screen::updateScreen() {
@@ -468,7 +471,7 @@ void Screen::updateDirtyRectsAmiga() {
#define mScale2x(dst, dstPitch, src, srcPitch, w, h) \
if (!_useHiColorScreen) \
scale2x<uint8, uint16>(dst, dstPitch, src, srcPitch, w, h); \
- else if (_bytesPerPixel == 2) \
+ else if (_internalBytesPerPixel == 2) \
scale2x<uint16, uint32>(dst, dstPitch, src, srcPitch, w, h); \
else \
scale2x<uint8, uint32>(dst, dstPitch, src, srcPitch, w, h)
@@ -488,7 +491,7 @@ void Screen::updateDirtyRectsOvl() {
Common::List<Common::Rect>::iterator it;
for (it = _dirtyRects.begin(); it != _dirtyRects.end(); ++it) {
byte *dst = ovl0 + it->top * 1280 * dstBpp + (it->left << dstBpp);
- const byte *src = page0 + it->top * SCREEN_W * _bytesPerPixel + it->left * _bytesPerPixel;
+ const byte *src = page0 + it->top * SCREEN_W * _internalBytesPerPixel + it->left * _internalBytesPerPixel;
mScale2x(dst, 640, src, SCREEN_W, it->width(), it->height());
mergeOverlay(it->left<<1, it->top<<1, it->width()<<1, it->height()<<1);
_system->copyRectToScreen(dst, _useHiColorScreen ? 1280 : 640, it->left << 1, it->top << 1, it->width() << 1, it->height() << 1);
@@ -511,7 +514,7 @@ void Screen::scale2x(uint8 *dst, int dstPitch, const uint8 *src, int srcPitch, i
while (h--) {
for (int x = 0; x < w; x++) {
- scaleToType col = (sizeof(srcType) == 1 && sizeof(scaleToType) == 4) ? _16bitConversionPalette[*src1++] : *src1++;
+ scaleToType col = (sizeof(srcType) == 1 && sizeof(scaleToType) == 4) ? _hiColorConversionPalette[*src1++] : *src1++;
*dstL1++ = *dstL2++ = col | (col << (sizeof(scaleToType) << 2));
}
dstL1 += dstAdd; dstL2 += dstAdd;
@@ -526,7 +529,7 @@ template void Screen::scale2x<uint8, uint32>(uint8 *dst, int dstPitch, const uin
template<typename pixelType>
void Screen::mergeOverlayImpl(int x, int y, int w, int h) {
const uint8 *src = _sjisOverlayPtrs[1] + y * 640 + x;
- uint16 *p16 = _16bitPalette ? _16bitPalette : _16bitConversionPalette;
+ uint16 *p16 = _hiColorNativePalettes ? _hiColorNativePalettes : _hiColorConversionPalette;
pixelType *dst = (pixelType*)(_sjisOverlayPtrs[0] + y * 640 * sizeof(pixelType) + x * sizeof(pixelType));
int add = 640 - w;
@@ -784,7 +787,7 @@ void Screen::copyWsaRect(int x, int y, int w, int h, int dimState, int plotFunc,
int Screen::getPagePixel(int pageNum, int x, int y) {
assert(pageNum < SCREEN_PAGE_NUM);
assert(x >= 0 && x < SCREEN_W && y >= 0 && y < _screenHeight);
- if (_bytesPerPixel == 1)
+ if (_internalBytesPerPixel == 1)
return _pagePtrs[pageNum][y * SCREEN_W + x];
else
return ((uint16*)_pagePtrs[pageNum])[y * SCREEN_W + x];
@@ -806,8 +809,8 @@ void Screen::setPagePixel(int pageNum, int x, int y, uint8 color) {
color &= 0x0F;
}
- if (_bytesPerPixel == 2) {
- ((uint16*)_pagePtrs[pageNum])[y * SCREEN_W + x] = _16bitPalette[color];
+ if (_internalBytesPerPixel == 2) {
+ ((uint16*)_pagePtrs[pageNum])[y * SCREEN_W + x] = _hiColorNativePalettes[color];
} else {
_pagePtrs[pageNum][y * SCREEN_W + x] = color;
}
@@ -826,12 +829,12 @@ void Screen::fadeToBlack(int delay, const UpdateFunctor *upFunc) {
}
void Screen::fadePalette(const Palette &pal, int delay, const UpdateFunctor *upFunc) {
- if (_renderMode == Common::kRenderEGA || _bytesPerPixel == 2)
+ if (_renderMode == Common::kRenderEGA || _internalBytesPerPixel == 2)
setScreenPalette(pal);
updateScreen();
- if (_renderMode == Common::kRenderCGA || _renderMode == Common::kRenderEGA || _bytesPerPixel == 2)
+ if (_renderMode == Common::kRenderCGA || _renderMode == Common::kRenderEGA || _internalBytesPerPixel == 2)
return;
int diff = 0, delayInc = 0;
@@ -961,22 +964,6 @@ void Screen::setScreenPalette(const Palette &pal) {
}
_paletteChanged = true;
-
- if (_useHiColorScreen) {
- if (_16bitPalette)
- memcpy(_16bitPalette, pal.getData(), 512);
-
- // Generate 16bit palette for the 8bit/16 bit conversion in scale2x()
- if (_16bitConversionPalette) {
- Graphics::PixelFormat pixelFormat = _system->getScreenFormat();
- for (int i = 0; i < 256; ++i)
- _16bitConversionPalette[i] = pixelFormat.RGBToColor(screenPal[i * 3], screenPal[i * 3 + 1], screenPal[i * 3 + 2]);
- // The whole Surface has to be converted again after each palette change
- _forceFullUpdate = true;
- }
- return;
- }
-
_system->getPaletteManager()->setPalette(screenPal, 0, pal.getNumColors());
}
@@ -1050,8 +1037,8 @@ void Screen::copyRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPag
h = _screenHeight - y2;
}
- const uint8 *src = getPagePtr(srcPage) + y1 * SCREEN_W * _bytesPerPixel + x1 * _bytesPerPixel;
- uint8 *dst = getPagePtr(dstPage) + y2 * SCREEN_W * _bytesPerPixel + x2 * _bytesPerPixel;
+ const uint8 *src = getPagePtr(srcPage) + y1 * SCREEN_W * _internalBytesPerPixel + x1 * _internalBytesPerPixel;
+ uint8 *dst = getPagePtr(dstPage) + y2 * SCREEN_W * _internalBytesPerPixel + x2 * _internalBytesPerPixel;
if (src == dst)
return;
@@ -1063,14 +1050,14 @@ void Screen::copyRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPag
if (flags & CR_NO_P_CHECK) {
while (h--) {
- memmove(dst, src, w * _bytesPerPixel);
- src += SCREEN_W * _bytesPerPixel;
- dst += SCREEN_W * _bytesPerPixel;
+ memmove(dst, src, w * _internalBytesPerPixel);
+ src += SCREEN_W * _internalBytesPerPixel;
+ dst += SCREEN_W * _internalBytesPerPixel;
}
} else {
while (h--) {
for (int i = 0; i < w; ++i) {
- if (_bytesPerPixel == 2) {
+ if (_internalBytesPerPixel == 2) {
uint px = *(const uint16*)&src[i << 1];
if (px)
*(uint16*)&dst[i << 1] = px;
@@ -1079,15 +1066,15 @@ void Screen::copyRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPag
dst[i] = src[i];
}
}
- src += SCREEN_W * _bytesPerPixel;
- dst += SCREEN_W * _bytesPerPixel;
+ src += SCREEN_W * _internalBytesPerPixel;
+ dst += SCREEN_W * _internalBytesPerPixel;
}
}
}
void Screen::copyRegionToBuffer(int pageNum, int x, int y, int w, int h, uint8 *dest) {
if (y < 0) {
- dest += (-y) * w * _bytesPerPixel;
+ dest += (-y) * w * _internalBytesPerPixel;
h += y;
y = 0;
} else if (y + h > _screenHeight) {
@@ -1096,7 +1083,7 @@ void Screen::copyRegionToBuffer(int pageNum, int x, int y, int w, int h, uint8 *
int pitch = w;
if (x < 0) {
- dest += -x * _bytesPerPixel;
+ dest += -x * _internalBytesPerPixel;
w += x;
x = 0;
} else if (x + w > SCREEN_W) {
@@ -1109,14 +1096,14 @@ void Screen::copyRegionToBuffer(int pageNum, int x, int y, int w, int h, uint8 *
uint8 *pagePtr = getPagePtr(pageNum);
for (int i = y; i < y + h; ++i)
- memcpy(dest + (i - y) * pitch * _bytesPerPixel, pagePtr + i * SCREEN_W * _bytesPerPixel + x * _bytesPerPixel, w * _bytesPerPixel);
+ memcpy(dest + (i - y) * pitch * _internalBytesPerPixel, pagePtr + i * SCREEN_W * _internalBytesPerPixel + x * _internalBytesPerPixel, w * _internalBytesPerPixel);
}
void Screen::copyPage(uint8 srcPage, uint8 dstPage) {
uint8 *src = getPagePtr(srcPage);
uint8 *dst = getPagePtr(dstPage);
if (src != dst)
- memcpy(dst, src, SCREEN_W * _screenHeight * _bytesPerPixel);
+ memcpy(dst, src, SCREEN_W * _screenHeight * _internalBytesPerPixel);
copyOverlayRegion(0, 0, 0, 0, SCREEN_W, _screenHeight, srcPage, dstPage);
if (dstPage == 0 || dstPage == 1)
@@ -1125,7 +1112,7 @@ void Screen::copyPage(uint8 srcPage, uint8 dstPage) {
void Screen::copyBlockToPage(int pageNum, int x, int y, int w, int h, const uint8 *src) {
if (y < 0) {
- src += (-y) * w * _bytesPerPixel;
+ src += (-y) * w * _internalBytesPerPixel;
h += y;
y = 0;
} else if (y + h > _screenHeight) {
@@ -1134,7 +1121,7 @@ void Screen::copyBlockToPage(int pageNum, int x, int y, int w, int h, const uint
int pitch = w;
if (x < 0) {
- src += -x * _bytesPerPixel;
+ src += -x * _internalBytesPerPixel;
w += x;
x = 0;
} else if (x + w > SCREEN_W) {
@@ -1144,7 +1131,7 @@ void Screen::copyBlockToPage(int pageNum, int x, int y, int w, int h, const uint
if (w < 0 || h < 0)
return;
- uint8 *dst = getPagePtr(pageNum) + y * SCREEN_W * _bytesPerPixel + x * _bytesPerPixel;
+ uint8 *dst = getPagePtr(pageNum) + y * SCREEN_W * _internalBytesPerPixel + x * _internalBytesPerPixel;
if (pageNum == 0 || pageNum == 1)
addDirtyRect(x, y, w, h);
@@ -1152,9 +1139,9 @@ void Screen::copyBlockToPage(int pageNum, int x, int y, int w, int h, const uint
clearOverlayRect(pageNum, x, y, w, h);
while (h--) {
- memcpy(dst, src, w * _bytesPerPixel);
- dst += SCREEN_W * _bytesPerPixel;
- src += pitch * _bytesPerPixel;
+ memcpy(dst, src, w * _internalBytesPerPixel);
+ dst += SCREEN_W * _internalBytesPerPixel;
+ src += pitch * _internalBytesPerPixel;
}
}
@@ -1220,7 +1207,7 @@ void Screen::fillRect(int x1, int y1, int x2, int y2, uint8 color, int pageNum,
if (pageNum == -1)
pageNum = _curPage;
- uint8 *dst = getPagePtr(pageNum) + y1 * SCREEN_W * _bytesPerPixel + x1 * _bytesPerPixel;
+ uint8 *dst = getPagePtr(pageNum) + y1 * SCREEN_W * _internalBytesPerPixel + x1 * _internalBytesPerPixel;
if (pageNum == 0 || pageNum == 1)
addDirtyRect(x1, y1, x2-x1+1, y2-y1+1);
@@ -1234,8 +1221,8 @@ void Screen::fillRect(int x1, int y1, int x2, int y2, uint8 color, int pageNum,
color &= 0x03;
} else if (_use16ColorMode || (_renderMode == Common::kRenderEGA && !_useHiResEGADithering)) {
color &= 0x0F;
- } else if (_bytesPerPixel == 2)
- color16 = shade16bitColor(_16bitPalette[color]);
+ } else if (_internalBytesPerPixel == 2)
+ color16 = shadeRGBColor(_hiColorNativePalettes[color]);
if (xored) {
// no 16 bit support for this (unneeded)
@@ -1246,14 +1233,14 @@ void Screen::fillRect(int x1, int y1, int x2, int y2, uint8 color, int pageNum,
}
} else {
for (; y1 <= y2; ++y1) {
- if (_bytesPerPixel == 2) {
+ if (_internalBytesPerPixel == 2) {
uint16 *ptr = (uint16*)dst;
for (int i = 0; i < x2 - x1 + 1; i++)
*ptr++ = color16;
} else {
memset(dst, color, x2 - x1 + 1);
}
- dst += SCREEN_W * _bytesPerPixel;
+ dst += SCREEN_W * _internalBytesPerPixel;
}
}
}
@@ -1310,7 +1297,7 @@ void Screen::drawClippedLine(int x1, int y1, int x2, int y2, int color) {
}
void Screen::drawLine(bool vertical, int x, int y, int length, int color) {
- uint8 *ptr = getPagePtr(_curPage) + y * SCREEN_W * _bytesPerPixel + x * _bytesPerPixel;
+ uint8 *ptr = getPagePtr(_curPage) + y * SCREEN_W * _internalBytesPerPixel + x * _internalBytesPerPixel;
if (_4bitPixelPacking) {
color &= 0x0F;
@@ -1319,23 +1306,23 @@ void Screen::drawLine(bool vertical, int x, int y, int length, int color) {
color &= 0x03;
} else if (_use16ColorMode || (_renderMode == Common::kRenderEGA && !_useHiResEGADithering)) {
color &= 0x0F;
- } else if (_bytesPerPixel == 2)
- color = shade16bitColor(_16bitPalette[color]);
+ } else if (_internalBytesPerPixel == 2)
+ color = shadeRGBColor(_hiColorNativePalettes[color]);
if (vertical) {
assert((y + length) <= SCREEN_H);
int currLine = 0;
while (currLine < length) {
- if (_bytesPerPixel == 2)
+ if (_internalBytesPerPixel == 2)
*(uint16*)ptr = color;
else
*ptr = color;
- ptr += SCREEN_W * _bytesPerPixel;
+ ptr += SCREEN_W * _internalBytesPerPixel;
currLine++;
}
} else {
assert((x + length) <= SCREEN_W);
- if (_bytesPerPixel == 2) {
+ if (_internalBytesPerPixel == 2) {
for (int i = 0; i < length; i++) {
*(uint16*)ptr = color;
ptr += 2;
@@ -1530,9 +1517,9 @@ int Screen::getNumberOfCharacters(const char *str) {
void Screen::printText(const char *str, int x, int y, uint8 color1, uint8 color2, int pitch) {
uint16 cmap16[2];
- if (_16bitPalette) {
- cmap16[0] = color2 ? shade16bitColor(_16bitPalette[color2]) : 0xFFFF;
- cmap16[1] = _16bitPalette[color1];
+ if (_hiColorNativePalettes) {
+ cmap16[0] = color2 ? shadeRGBColor(_hiColorNativePalettes[color2]) : 0xFFFF;
+ cmap16[1] = _hiColorNativePalettes[color1];
setTextColor16bit(cmap16);
}
@@ -1644,7 +1631,7 @@ void Screen::drawChar(uint16 c, int x, int y, int pitch) {
fnt->drawChar(c, destPage, 640, bpp);
} else {
- fnt->drawChar(c, getPagePtr(_curPage) + y * SCREEN_W * _bytesPerPixel + x * _bytesPerPixel, SCREEN_W, _bytesPerPixel);
+ fnt->drawChar(c, getPagePtr(_curPage) + y * SCREEN_W * _internalBytesPerPixel + x * _internalBytesPerPixel, SCREEN_W, _internalBytesPerPixel);
}
if (!_isSegaCD && (_curPage == 0 || _curPage == 1))
@@ -3126,16 +3113,15 @@ int16 Screen::encodeShapeAndCalculateSize(uint8 *from, uint8 *to, int size_to) {
return (to - toPtr);
}
-uint16 Screen::shade16bitColor(uint16 col) {
- uint8 r = (col & 0x1f);
- uint8 g = (col & 0x3E0) >> 5;
- uint8 b = (col & 0x7C00) >> 10;
+uint16 Screen::shadeRGBColor(uint16 col) {
+ uint8 r = 0, g = 0, b = 0;
+ _outputPixelFormat.colorToRGB(col, r, g, b);
- r = (r > _16bitShadingLevel) ? r - _16bitShadingLevel : 0;
- g = (g > _16bitShadingLevel) ? g - _16bitShadingLevel : 0;
- b = (b > _16bitShadingLevel) ? b - _16bitShadingLevel : 0;
+ r = (r > _hiColorShadingLevel) ? r - _hiColorShadingLevel : 0;
+ g = (g > _hiColorShadingLevel) ? g - _hiColorShadingLevel : 0;
+ b = (b > _hiColorShadingLevel) ? b - _hiColorShadingLevel : 0;
- return (b << 10) | (g << 5) | r;
+ return _outputPixelFormat.RGBToColor(r, g, b);
}
void Screen::hideMouse() {
@@ -3433,7 +3419,7 @@ bool Screen::loadPalette(const char *filename, Palette &pal) {
debugC(3, kDebugLevelScreen, "Screen::loadPalette('%s', %p)", filename, (const void *)&pal);
- const int maxCols = _16bitPalette ? 256 : pal.getNumColors();
+ const int maxCols = _hiColorNativePalettes ? 256 : pal.getNumColors();
int numCols = 0;
if (_isAmiga) {
@@ -3449,10 +3435,10 @@ bool Screen::loadPalette(const char *filename, Palette &pal) {
numCols /= Palette::kVGABytesPerColor;
pal.loadVGAPalette(*stream, 0, numCols);
} else {
- if (_bytesPerPixel == 2) {
+ if (_internalBytesPerPixel == 2) {
numCols = stream->size() / 2;
pal.loadHiColorPalette(*stream, 0, numCols);
- } else if (!_16bitPalette) {
+ } else if (!_hiColorNativePalettes) {
numCols = stream->size() / Palette::kVGABytesPerColor;
pal.loadVGAPalette(*stream, 0, MIN(maxCols, numCols));
} else {
@@ -3636,7 +3622,7 @@ void Screen::crossFadeRegion(int x1, int y1, int x2, int y2, int w, int h, int s
hideMouse();
uint16 *wB = (uint16 *)_pagePtrs[14];
- uint8 *hB = _pagePtrs[14] + 640 * _bytesPerPixel;
+ uint8 *hB = _pagePtrs[14] + 640 * _internalBytesPerPixel;
for (int i = 0; i < w; i++)
wB[i] = i;
@@ -3665,7 +3651,7 @@ void Screen::crossFadeRegion(int x1, int y1, int x2, int y2, int w, int h, int s
if (++iH >= h)
iH = 0;
- if (_bytesPerPixel == 2)
+ if (_internalBytesPerPixel == 2)
((uint16*)d)[dY * 320 + dX] = ((uint16*)s)[sY * 320 + sX];
else
d[dY * 320 + dX] = s[sY * 320 + sX];
@@ -4110,15 +4096,8 @@ void Palette::loadVGAPalette(Common::ReadStream &stream, int startIndex, int col
void Palette::loadHiColorPalette(Common::ReadStream &stream, int startIndex, int colors) {
uint16 *pos = (uint16*)(_palData + startIndex * 2);
-
- Graphics::PixelFormat currentFormat = g_system->getScreenFormat();
- Graphics::PixelFormat originalFormat(2, 5, 5, 5, 0, 5, 10, 0, 0);
-
- for (int i = 0; i < colors; i++) {
- uint8 r, g, b;
- originalFormat.colorToRGB(stream.readUint16LE(), r, g, b);
- *pos++ = currentFormat.RGBToColor(r, g, b);
- }
+ for (int i = 0; i < colors; i++)
+ *pos++ = stream.readUint16LE();
}
void Palette::loadEGAPalette(Common::ReadStream &stream, int startIndex, int colors) {
diff --git a/engines/kyra/graphics/screen.h b/engines/kyra/graphics/screen.h
index 083d8b328bf..3e9dc38a2bd 100644
--- a/engines/kyra/graphics/screen.h
+++ b/engines/kyra/graphics/screen.h
@@ -31,6 +31,7 @@
#include "common/stream.h"
#include "common/ptr.h"
#include "common/error.h"
+#include "graphics/pixelformat.h"
class OSystem;
@@ -813,8 +814,8 @@ public:
// can well afford the 20 lines of extra code.
void crossFadeRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPage, int dstPage);
- uint16 *get16bitPalette() { return _16bitPalette; }
- void set16bitShadingLevel(int lvl) { _16bitShadingLevel = lvl; }
+ uint16 *get16bitPalette() { return _hiColorNativePalettes; }
+ void set16bitShadingLevel(int lvl) { _hiColorShadingLevel = lvl; }
protected:
void resetPagePtrsAndBuffers(int pageSize);
@@ -872,12 +873,13 @@ protected:
bool _useShapeShading;
bool _4bitPixelPacking;
bool _useHiResEGADithering;
+ Graphics::PixelFormat _outputPixelFormat;
bool _useHiColorScreen;
bool _isAmiga;
bool _useAmigaExtraColors;
bool _isSegaCD;
Common::RenderMode _renderMode;
- int _bytesPerPixel;
+ int _internalBytesPerPixel;
int _screenPageSize;
const int _screenHeight;
int _yTransOffs;
@@ -886,11 +888,11 @@ protected:
Common::Array<Palette *> _palettes;
Palette *_internFadePalette;
- uint16 shade16bitColor(uint16 col);
+ uint16 shadeRGBColor(uint16 col);
- uint16 *_16bitPalette;
- uint16 *_16bitConversionPalette;
- uint8 _16bitShadingLevel;
+ uint16 *_hiColorNativePalettes;
+ uint16 *_hiColorConversionPalette;
+ uint8 _hiColorShadingLevel;
uint8 *_animBlockPtr;
int _animBlockSize;
diff --git a/engines/kyra/graphics/screen_eob.cpp b/engines/kyra/graphics/screen_eob.cpp
index c3a8c194db8..61784b1e638 100644
--- a/engines/kyra/graphics/screen_eob.cpp
+++ b/engines/kyra/graphics/screen_eob.cpp
@@ -86,7 +86,7 @@ Screen_EoB::Screen_EoB(EoBCoreEngine *vm, OSystem *system) : Screen(vm, system,
_gfxX = _gfxY = 0;
_gfxCol = 0;
_dsTempPage = 0;
- _shpBuffer = _convertHiColorBuffer = 0;
+ _shpBuffer = _hiColorConvertBuffer = 0;
_dsDiv = 0;
_dsRem = 0;
_dsScaleTrans = 0;
@@ -113,7 +113,7 @@ Screen_EoB::Screen_EoB(EoBCoreEngine *vm, OSystem *system) : Screen(vm, system,
Screen_EoB::~Screen_EoB() {
delete[] _dsTempPage;
delete[] _shpBuffer;
- delete[] _convertHiColorBuffer;
+ delete[] _hiColorConvertBuffer;
delete[] _cgaScaleTable;
delete[] _egaDitheringTable;
delete[] _egaDitheringTempPage;
@@ -135,7 +135,7 @@ bool Screen_EoB::init() {
if (_vm->gameFlags().platform == Common::kPlatformFMTowns) {
_shpBuffer = new uint8[SCREEN_H * SCREEN_W];
- _convertHiColorBuffer = new uint8[SCREEN_H * SCREEN_W];
+ _hiColorConvertBuffer = new uint8[SCREEN_H * SCREEN_W];
enableHiColorMode(true);
setFontStyles(FID_SJIS_FNT, Font::kStyleFat);
_fonts[FID_SJIS_LARGE_FNT] = new SJISFontLarge(_sjisFontShared);
@@ -172,7 +172,7 @@ bool Screen_EoB::init() {
sega_setTextBuffer(0, 0);
}
- _useShapeShading = (_bytesPerPixel != 2 && !_isAmiga && !_isSegaCD && !_use16ColorMode && _renderMode != Common::kRenderCGA && _renderMode != Common::kRenderEGA) || _useHiResEGADithering;
+ _useShapeShading = (_internalBytesPerPixel != 2 && !_isAmiga && !_isSegaCD && !_use16ColorMode && _renderMode != Common::kRenderCGA && _renderMode != Common::kRenderEGA) || _useHiResEGADithering;
static const char *cpsExt[] = { "CPS", "EGA", "SHP", "BIN" };
int ci = 0;
@@ -229,14 +229,14 @@ void Screen_EoB::setMouseCursor(int x, int y, const byte *shape, const uint8 *ov
int mouseW = (shape[2] << 3);
int mouseH = (shape[3]);
- int colorKey = (_renderMode == Common::kRenderCGA) ? 0 : (_bytesPerPixel == 2 ? _cursorColorKey16Bit : _cursorColorKey);
+ int colorKey = (_renderMode == Common::kRenderCGA) ? 0 : (_internalBytesPerPixel == 2 ? _cursorColorKey16Bit : _cursorColorKey);
int scaleFactor = _vm->gameFlags().useHiRes ? 2 : 1;
int bpp = _useHiColorScreen ? 2 : 1;
uint8 *cursor = new uint8[mouseW * scaleFactor * bpp * mouseH * scaleFactor];
- if (_bytesPerPixel == 2) {
+ if (_internalBytesPerPixel == 2) {
for (int s = mouseW * scaleFactor * bpp * mouseH * scaleFactor; s; s -= 2)
*(uint16*)(cursor + s - 2) = colorKey;
} else {
@@ -289,7 +289,7 @@ void Screen_EoB::setMouseCursor(int x, int y, const byte *shape, const uint8 *ov
// Convert color key to 16 bit after drawing the mouse cursor.
// The cursor has been converted to 16 bit in scale2x().
- colorKey = _16bitConversionPalette ? _16bitConversionPalette[colorKey] : colorKey;
+ colorKey = _hiColorConversionPalette ? _hiColorConversionPalette[colorKey] : colorKey;
Graphics::PixelFormat pixelFormat = _system->getScreenFormat();
CursorMan.replaceCursor(cursor, mouseW * scaleFactor, mouseH * scaleFactor, x * scaleFactor, y * scaleFactor, colorKey, &pixelFormat);
@@ -505,7 +505,7 @@ void Screen_EoB::loadEoBBitmap(const char *file, const uint8 *cgaMapping, int te
if (convertToPage == -1)
return;
- if (_16bitPalette)
+ if (_hiColorNativePalettes)
convertToHiColor(destPage);
if (convertToPage == 2 && _renderMode == Common::kRenderCGA) {
@@ -551,9 +551,17 @@ void Screen_EoB::convertPage(int srcPage, int dstPage, const uint8 *cgaMapping)
}
void Screen_EoB::setScreenPalette(const Palette &pal) {
- if (_bytesPerPixel == 2) {
+ if (_internalBytesPerPixel == 2) {
+ assert(_hiColorNativePalettes);
for (int i = 0; i < 4; i++)
- createFadeTable16bit((const uint16*)(pal.getData()), &_16bitPalette[i * 256], 0, i * 85);
+ createHiColorFadeTable((const uint16 *)(pal.getData()), &_hiColorNativePalettes[i << 8], 0, i * 85);
+ } else if (_outputPixelFormat.bytesPerPixel > 1) {
+ assert(_hiColorConversionPalette);
+ _screenPalette->copy(pal);
+ for (int i = 0; i < pal.getNumColors(); ++i)
+ _hiColorConversionPalette[i] = _outputPixelFormat.RGBToColor(pal[i * 3] * 0xFF / 0x3F, pal[i * 3 + 1] * 0xFF / 0x3F, pal[i * 3 + 2] * 0xFF / 0x3F);
+ // The whole Surface has to be converted again after each palette change
+ _forceFullUpdate = true;
} else if (_useHiResEGADithering && pal.getNumColors() != 16) {
generateEGADitheringTable(pal);
} else if (_isSegaCD || (_renderMode == Common::kRenderEGA && pal.getNumColors() == 16)) {
@@ -590,7 +598,7 @@ uint8 *Screen_EoB::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool enco
if (_use16ColorMode || (_renderMode == Common::kRenderEGA && !_useHiResEGADithering))
encode8bit = false;
- if (_bytesPerPixel == 2 && encode8bit) {
+ if (_internalBytesPerPixel == 2 && encode8bit) {
shapesize = h * (w << 3) + 4;
shp = new uint8[shapesize]();
uint8 *dst = shp;
@@ -812,18 +820,18 @@ void Screen_EoB::drawT1Shape(uint8 pageNum, const byte *t1data, int x, int y, in
addDirtyRect(rX, rY, rW, rH);
int dH = rH;
- uint8 *dstL = getPagePtr(pageNum) + rY * _bytesPerPixel * SCREEN_W;
+ uint8 *dstL = getPagePtr(pageNum) + rY * _internalBytesPerPixel * SCREEN_W;
src += dY * width;
while (dH--) {
const uint8 *src2 = src + dX;
- uint8 *dst = dstL + rX * _bytesPerPixel;
+ uint8 *dst = dstL + rX * _internalBytesPerPixel;
- for (int i = 0; i < rW; i++, src2++, dst += _bytesPerPixel)
+ for (int i = 0; i < rW; i++, src2++, dst += _internalBytesPerPixel)
if (*src2)
drawShapeSetPixel(dst, *src2);
- dstL += SCREEN_W * _bytesPerPixel;
+ dstL += SCREEN_W * _internalBytesPerPixel;
src += width;
}
}
@@ -852,7 +860,7 @@ void Screen_EoB::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y,
}
va_end(args);
- dst += (_dsX1 << (2 + _bytesPerPixel));
+ dst += (_dsX1 << (2 + _internalBytesPerPixel));
int16 dX = x - (_dsX1 << 3);
int16 dY = y;
int16 dW = _dsX2 - _dsX1;
@@ -924,7 +932,7 @@ void Screen_EoB::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y,
marginRight = w2 - marginLeft - width;
}
- dst += (dY * SCREEN_W * _bytesPerPixel + dX * _bytesPerPixel);
+ dst += (dY * SCREEN_W * _internalBytesPerPixel + dX * _internalBytesPerPixel);
uint8 *dstL = dst;
if (pageNum == 0 || pageNum == 1)
@@ -972,7 +980,7 @@ void Screen_EoB::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y,
}
}
- dst -= xpos * _bytesPerPixel;
+ dst -= xpos * _internalBytesPerPixel;
xpos += width;
while (xpos > 0) {
@@ -982,15 +990,15 @@ void Screen_EoB::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y,
if (m) {
drawShapeSetPixel(dst, c);
- dst += _bytesPerPixel;
+ dst += _internalBytesPerPixel;
xpos--;
} else if (pixelsPerByte) {
uint8 len = (flags & 1) ? src[1] : src[0];
- dst += len * _bytesPerPixel;
+ dst += len * _internalBytesPerPixel;
xpos -= len;
src += pixelStep;
} else {
- dst += _bytesPerPixel;
+ dst += _internalBytesPerPixel;
xpos--;
}
}
@@ -1020,7 +1028,7 @@ void Screen_EoB::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y,
} while (xpos > 0);
}
- dstL += SCREEN_W * _bytesPerPixel;
+ dstL += SCREEN_W * _internalBytesPerPixel;
dst = dstL;
if (flags & 1)
src = src2 + 1;
@@ -1088,7 +1096,7 @@ void Screen_EoB::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y,
if (d < width)
width = d;
- dst += (dY * SCREEN_W * _bytesPerPixel + dX * _bytesPerPixel);
+ dst += (dY * SCREEN_W * _internalBytesPerPixel + dX * _internalBytesPerPixel);
if (pageNum == 0 || pageNum == 1)
addDirtyRect(rX, rY, rW, rH);
@@ -1137,11 +1145,11 @@ void Screen_EoB::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y,
uint8 col = (pixelsPerByte == 2) ? pal[(in >> shift) & pixelPackingMask] : (*dst & ((trans >> shift) & (pixelPackingMask))) | pal[(in >> shift) & pixelPackingMask];
if (col || pixelsPerByte == 4)
drawShapeSetPixel(dst, col);
- dst += _bytesPerPixel;
+ dst += _internalBytesPerPixel;
shift = ((shift - (pixelStep * pixelPacking)) & 7);
}
src += lineSrcStep;
- dst += (pitch * _bytesPerPixel);
+ dst += (pitch * _internalBytesPerPixel);
}
}
}
@@ -1220,7 +1228,7 @@ const uint8 *Screen_EoB::generateShapeOverlay(const uint8 *shp, const uint8 *fad
if (*shp != 2)
return 0;
- if (_bytesPerPixel == 2) {
+ if (_internalBytesPerPixel == 2) {
setFadeTable(fadingTable);
setShapeFadingLevel(1);
return 0;
@@ -1307,7 +1315,7 @@ void Screen_EoB::drawExplosion(int scale, int radius, int numElements, int stepS
if (py > ymax)
py = ymax;
if (posWithinRect(px, py, rX1, rY1, rX2, rY2)) {
- if (_bytesPerPixel == 2)
+ if (_internalBytesPerPixel == 2)
setPagePixel16bit(0, px, py, ptr6[i]);
else
setPagePixel(0, px, py, ptr6[i]);
@@ -1464,7 +1472,7 @@ void Screen_EoB::drawVortex(int numElements, int radius, int stepSize, int, int
for (int ii = numElements - 1; ii >= 0; ii--) {
int16 px = CLIP((xCoords[ii] >> 6) + cx, 0, SCREEN_W - 1);
int16 py = CLIP((yCoords[ii] >> 6) + cy, 0, SCREEN_H - 1);
- if (_bytesPerPixel == 2)
+ if (_internalBytesPerPixel == 2)
setPagePixel16bit(0, px, py, pixBackup[ii]);
else
setPagePixel(0, px, py, pixBackup[ii]);
@@ -1609,11 +1617,11 @@ int Screen_EoB::getRectSize(int w, int h) {
void Screen_EoB::setFadeTable(const uint8 *table) {
_dsShapeFadingTable = table;
- if (_bytesPerPixel == 2)
- memcpy(&_16bitPalette[0x100], table, 512);
+ if (_internalBytesPerPixel == 2)
+ memcpy(&_hiColorNativePalettes[0x100], table, 512);
}
-void Screen_EoB::createFadeTable(const uint8 *palData, uint8 *dst, uint8 rootColor, uint8 weight) {
+void Screen_EoB::createColorFadeTable(const uint8 *palData, uint8 *dst, uint8 rootColor, uint8 weight) {
if (!palData)
return;
@@ -1627,7 +1635,7 @@ void Screen_EoB::createFadeTable(const uint8 *palData, uint8 *dst, uint8 rootCol
*dst++ = 0;
weight >>= 1;
- for (uint8 i = 1; i; i++) {
+ for (int i = 1; i < 256; ++i) {
uint16 tmp = (uint16)((*src - r) * weight) << 1;
tr = *src++ - ((tmp >> 8) & 0xFF);
tmp = (uint16)((*src - g) * weight) << 1;
@@ -1639,7 +1647,7 @@ void Screen_EoB::createFadeTable(const uint8 *palData, uint8 *dst, uint8 rootCol
uint16 v = 0xFFFF;
uint8 col = rootColor;
- for (uint8 ii = 1; ii; ii++) {
+ for (int ii = 1; ii < 256; ++ii) {
int a = *d++ - tr;
int t = a * a;
a = *d++ - tg;
@@ -1656,26 +1664,24 @@ void Screen_EoB::createFadeTable(const uint8 *palData, uint8 *dst, uint8 rootCol
}
}
-void Screen_EoB::createFadeTable16bit(const uint16 *palData, uint16 *dst, uint16 rootColor, uint8 weight) {
- rootColor = palData[rootColor];
- uint8 r8 = (rootColor & 0x1f);
- uint8 g8 = (rootColor & 0x3E0) >> 5;
- uint8 b8 = (rootColor & 0x7C00) >> 10;
+void Screen_EoB::createHiColorFadeTable(const uint16 *palData, uint16 *dst, uint8 rootColor, uint8 weight) {
+ const Graphics::PixelFormat originalFormat(2, 5, 5, 5, 0, 5, 10, 0, 0);
+ uint8 r = 0, b = 0, g = 0;
+ originalFormat.colorToRGB(palData[rootColor], r, g, b);
- int root_r = r8 << 4;
- int root_g = g8 << 4;
- int root_b = b8 << 4;
+ int root_r = r << 1;
+ int root_g = g << 1;
+ int root_b = b << 1;
- *dst++ = palData[0];
+ originalFormat.colorToRGB(palData[0], r, g, b);
+ *dst++ = _outputPixelFormat.RGBToColor(r, g, b);
- for (uint8 i = 1; i; i++) {
- r8 = (palData[i] & 0x1f);
- g8 = (palData[i] & 0x3E0) >> 5;
- b8 = (palData[i] & 0x7C00) >> 10;
+ for (int i = 1; i < 256; ++i) {
+ originalFormat.colorToRGB(palData[i], r, g, b);
- int red = r8 << 4;
- int green = g8 << 4;
- int blue = b8 << 4;
+ int red = r << 1;
+ int green = g << 1;
+ int blue = b << 1;
if (red > root_r) {
red -= weight;
@@ -1707,11 +1713,11 @@ void Screen_EoB::createFadeTable16bit(const uint16 *palData, uint16 *dst, uint16
blue = root_b;
}
- r8 = red >> 4;
- g8 = green >> 4;
- b8 = blue >> 4;
+ r = red >> 1;
+ g = green >> 1;
+ b = blue >> 1;
- *dst++ = (b8 << 10) | (g8 << 5) | r8;
+ *dst++ = _outputPixelFormat.RGBToColor(r, g, b);
}
}
@@ -1824,8 +1830,8 @@ void Screen_EoB::ditherRect(const uint8 *src, uint8 *dst, int dstPitch, int srcW
}
void Screen_EoB::drawShapeSetPixel(uint8 *dst, uint8 col) {
- if (_bytesPerPixel == 2) {
- *(uint16*)dst = _16bitPalette[(_dsShapeFadingLevel << 8) + col];
+ if (_internalBytesPerPixel == 2) {
+ *(uint16*)dst = _hiColorNativePalettes[(_dsShapeFadingLevel << 8) + col];
return;
} else if (_useShapeShading) {
if (_dsBackgroundFading) {
@@ -1904,7 +1910,7 @@ bool Screen_EoB::posWithinRect(int posX, int posY, int x1, int y1, int x2, int y
void Screen_EoB::setPagePixel16bit(int pageNum, int x, int y, uint16 color) {
assert(pageNum < SCREEN_PAGE_NUM);
assert(x >= 0 && x < SCREEN_W && y >= 0 && y < SCREEN_H);
- assert(_bytesPerPixel == 2);
+ assert(_internalBytesPerPixel == 2);
if (pageNum == 0 || pageNum == 1)
addDirtyRect(x, y, 1, 1);
diff --git a/engines/kyra/graphics/screen_eob.h b/engines/kyra/graphics/screen_eob.h
index d5f242b0d96..149fa3b50c1 100644
--- a/engines/kyra/graphics/screen_eob.h
+++ b/engines/kyra/graphics/screen_eob.h
@@ -102,8 +102,8 @@ public:
int getRectSize(int w, int h) override;
void setFadeTable(const uint8 *table);
- void createFadeTable(const uint8 *palData, uint8 *dst, uint8 rootColor, uint8 weight);
- void createFadeTable16bit(const uint16 *palData, uint16 *dst, uint16 rootColor, uint8 weight);
+ void createColorFadeTable(const uint8 *palData, uint8 *dst, uint8 rootColor, uint8 weight);
+ void createHiColorFadeTable(const uint16 *palData, uint16 *dst, uint8 rootColor, uint8 weight);
const uint16 *getCGADitheringTable(int index);
const uint8 *getEGADitheringTable();
@@ -189,7 +189,7 @@ private:
uint8 *_dsTempPage;
uint8 *_shpBuffer;
- uint8 *_convertHiColorBuffer;
+ uint8 *_hiColorConvertBuffer;
uint16 *_cgaDitheringTables[2];
const uint8 *_cgaMappingDefault;
diff --git a/engines/kyra/graphics/screen_eob_towns.cpp b/engines/kyra/graphics/screen_eob_towns.cpp
index a69616c1b93..56cd06e00df 100644
--- a/engines/kyra/graphics/screen_eob_towns.cpp
+++ b/engines/kyra/graphics/screen_eob_towns.cpp
@@ -62,37 +62,37 @@ void Screen_EoB::decodeSHP(const uint8 *data, int dstPage) {
}
void Screen_EoB::convertToHiColor(int page) {
- if (!_16bitPalette)
+ if (!_hiColorNativePalettes)
return;
uint16 *dst = (uint16 *)getPagePtr(page);
- memcpy(_convertHiColorBuffer, dst, SCREEN_H * SCREEN_W);
- uint8 *src = _convertHiColorBuffer;
+ memcpy(_hiColorConvertBuffer, dst, SCREEN_H * SCREEN_W);
+ const uint8 *src = _hiColorConvertBuffer;
for (int s = SCREEN_H * SCREEN_W; s; --s)
- *dst++ = _16bitPalette[*src++];
+ *dst++ = _hiColorNativePalettes[*src++];
}
void Screen_EoB::shadeRect(int x1, int y1, int x2, int y2, int shadingLevel) {
- if (!_16bitPalette)
+ if (!_hiColorNativePalettes)
return;
- int l = _16bitShadingLevel;
- _16bitShadingLevel = shadingLevel;
+ int l = _hiColorShadingLevel;
+ _hiColorShadingLevel = shadingLevel;
if (_curPage == 0 || _curPage == 1)
addDirtyRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
- uint16 *dst = (uint16*)(getPagePtr(_curPage) + y1 * SCREEN_W * _bytesPerPixel + x1 * _bytesPerPixel);
+ uint16 *dst = (uint16*)(getPagePtr(_curPage) + y1 * SCREEN_W * _internalBytesPerPixel + x1 * _internalBytesPerPixel);
for (; y1 < y2; ++y1) {
uint16 *ptr = dst;
for (int i = 0; i < x2 - x1; i++) {
- *ptr = shade16bitColor(*ptr);
+ *ptr = shadeRGBColor(*ptr);
ptr++;
}
dst += SCREEN_W;
}
- _16bitShadingLevel = l;
+ _hiColorShadingLevel = l;
}
SJISFontLarge::SJISFontLarge(Common::SharedPtr<Graphics::FontSJIS> &font) : SJISFont(font, 0, false, false, 0) {
diff --git a/engines/kyra/sequence/sequences_darkmoon.cpp b/engines/kyra/sequence/sequences_darkmoon.cpp
index 7690bd9f92c..64a2b7975e2 100644
--- a/engines/kyra/sequence/sequences_darkmoon.cpp
+++ b/engines/kyra/sequence/sequences_darkmoon.cpp
@@ -1844,7 +1844,7 @@ void DarkmoonSequenceHelper::init(DarkmoonSequenceHelper::Mode mode) {
if (_vm->_flags.platform != Common::kPlatformAmiga && _vm->_configRenderMode != Common::kRenderCGA && _vm->_configRenderMode != Common::kRenderEGA) {
uint8 *pal = _vm->resource()->fileData("PALETTE1.PAL", 0);
for (int i = 0; i < 7; i++)
- _screen->createFadeTable(pal, _fadingTables[i], 18, (i + 1) * 36);
+ _screen->createColorFadeTable(pal, _fadingTables[i], 18, (i + 1) * 36);
delete[] pal;
}
}
Commit: 1d3be6bf55be922abf6be0d6529a442c8c8e64fe
https://github.com/scummvm/scummvm/commit/1d3be6bf55be922abf6be0d6529a442c8c8e64fe
Author: athrxx (athrxx at scummvm.org)
Date: 2026-07-11T18:45:32+02:00
Commit Message:
KYRA: (EOBII/FM-TOWNS) - allow 32bit graphics modes
Instead of trying to enforce a 16 bit mode the game will now run in the
backend's default mode, as long as this is either a 16 or a 32 bit mode.
Changed paths:
engines/kyra/engine/darkmoon.cpp
engines/kyra/engine/eobcommon.cpp
engines/kyra/engine/items_eob.cpp
engines/kyra/engine/kyra_rpg.cpp
engines/kyra/engine/kyra_rpg.h
engines/kyra/engine/scene_eob.cpp
engines/kyra/engine/scene_rpg.cpp
engines/kyra/graphics/screen.cpp
engines/kyra/graphics/screen.h
engines/kyra/graphics/screen_eob.cpp
engines/kyra/graphics/screen_eob.h
engines/kyra/graphics/screen_eob_towns.cpp
diff --git a/engines/kyra/engine/darkmoon.cpp b/engines/kyra/engine/darkmoon.cpp
index 77db9472b8e..89f7bb13583 100644
--- a/engines/kyra/engine/darkmoon.cpp
+++ b/engines/kyra/engine/darkmoon.cpp
@@ -258,6 +258,8 @@ uint8 *DarkMoonEngine::loadFMTownsShape(Common::SeekableReadStream *stream) {
void DarkMoonEngine::generateMonsterPalettes(const char *file, int16 monsterIndex) {
if (_flags.platform == Common::kPlatformAmiga)
return;
+ // EOB II FM-TOWNS version will also never arrive here, see DarkMoonEngine::loadMonsterShapes().
+ // So there is no need to worry about how the following code could ever work in hicolor mode.
int cp = _screen->setCurPage(2);
_screen->loadShapeSetBitmap(file, 3, 3);
diff --git a/engines/kyra/engine/eobcommon.cpp b/engines/kyra/engine/eobcommon.cpp
index fd7386a17ec..cff470ec13f 100644
--- a/engines/kyra/engine/eobcommon.cpp
+++ b/engines/kyra/engine/eobcommon.cpp
@@ -523,13 +523,14 @@ Common::Error EoBCoreEngine::init() {
memset(&_wllShapeMap[13], -1, 5);
_wllVcnOffset = (_flags.platform == Common::kPlatformFMTowns) ? 0 : 16;
- int bpp = (_flags.platform == Common::kPlatformFMTowns) ? 2 : 1;
-
- _greenFadingTable = new uint8[256 * bpp];
- _blueFadingTable = new uint8[256 * bpp];
- _lightBlueFadingTable = new uint8[256 * bpp];
- _blackFadingTable = new uint8[256 * bpp];
- _greyFadingTable = new uint8[256 * bpp];
+ int bpp = _screen->bytesPerPixel();
+ setVcnFormat(bpp);
+
+ _greenFadingTable = new uint8[256 * bpp]();
+ _blueFadingTable = new uint8[256 * bpp]();
+ _lightBlueFadingTable = new uint8[256 * bpp]();
+ _blackFadingTable = new uint8[256 * bpp]();
+ _greyFadingTable = new uint8[256 * bpp]();
_monsters = new EoBMonsterInPlay[30]();
diff --git a/engines/kyra/engine/items_eob.cpp b/engines/kyra/engine/items_eob.cpp
index 9795558822c..65c2f6bc019 100644
--- a/engines/kyra/engine/items_eob.cpp
+++ b/engines/kyra/engine/items_eob.cpp
@@ -773,7 +773,7 @@ void EoBCoreEngine::explodeObject(EoBFlyingObject *fo, int block, Item item) {
fo->enable = 2;
_screen->fillRect(0, 0, 176, 120, 0, 2);
- uint8 col = _screen->getPagePixel(2, 0, 0);
+ int col = _screen->getPagePixel(2, 0, 0);
drawSceneShapes(_expObjectShpStart[dm]);
setLevelShapesDim(tl, x1, x2, 5);
diff --git a/engines/kyra/engine/kyra_rpg.cpp b/engines/kyra/engine/kyra_rpg.cpp
index 785822ddd6b..7d2f5ea4d02 100644
--- a/engines/kyra/engine/kyra_rpg.cpp
+++ b/engines/kyra/engine/kyra_rpg.cpp
@@ -50,9 +50,9 @@ KyraRpgEngine::KyraRpgEngine(OSystem *system, const GameFlags &flags) : KyraEngi
_vcnShift = 0;
_vcnColTable = 0;
_vcnShiftVal = 0;
- _vcnBpp = flags.useHiColorMode ? 2 : 1;
- _vcnSrcBitsPerPixel = (flags.platform == Common::kPlatformAmiga) ? 5 : (_vcnBpp == 2 ? 8 : 4);
- _vcnDrawLine = 0;
+ _vcnBpp = 1;
+ _vcnSrcBitsPerPixel = (_flags.platform == Common::kPlatformAmiga) ? 5 : (_flags.platform == Common::kPlatformFMTowns ? 8 : 4);
+ _vcnDrawLine = nullptr;
_vmpVisOffs = (flags.platform == Common::kPlatformSegaCD) ? _vmpOffsetsSegaCD : _vmpOffsetsDefault;
_vmpPtr = 0;
@@ -193,8 +193,7 @@ Common::Error KyraRpgEngine::init() {
_wllWallFlags = new uint8[256]();
_blockDrawingBuffer = new uint16[1320]();
- int windowBufferSize = _flags.useHiColorMode ? 42240 : 21120;
- _sceneWindowBuffer = new uint8[windowBufferSize]();
+ _sceneWindowBuffer = nullptr;
_lvlShapeTop = new int16[18]();
_lvlShapeBottom = new int16[18]();
@@ -204,15 +203,7 @@ Common::Error KyraRpgEngine::init() {
for (int i = 0; i < 128; i++)
_vcnColTable[i] = i & 0x0F;
- if (_vcnBpp == 2)
- _vcnDrawLine = new VcnLineDrawingMethods(new VcnDrawProc(this, &KyraRpgEngine::vcnDraw_fw_hiCol), new VcnDrawProc(this, &KyraRpgEngine::vcnDraw_bw_hiCol),
- new VcnDrawProc(this, &KyraRpgEngine::vcnDraw_fw_trans_hiCol), new VcnDrawProc(this, &KyraRpgEngine::vcnDraw_bw_trans_hiCol));
- else if (_flags.platform == Common::kPlatformAmiga || (_flags.gameID == GI_EOB1 && _flags.use16ColorMode))
- _vcnDrawLine = new VcnLineDrawingMethods(new VcnDrawProc(this, &KyraRpgEngine::vcnDraw_fw_planar), new VcnDrawProc(this, &KyraRpgEngine::vcnDraw_bw_planar),
- new VcnDrawProc(this, &KyraRpgEngine::vcnDraw_fw_trans_planar), new VcnDrawProc(this, &KyraRpgEngine::vcnDraw_bw_trans_planar));
- else
- _vcnDrawLine = new VcnLineDrawingMethods(new VcnDrawProc(this, &KyraRpgEngine::vcnDraw_fw_4bit), new VcnDrawProc(this, &KyraRpgEngine::vcnDraw_bw_4bit),
- new VcnDrawProc(this, &KyraRpgEngine::vcnDraw_fw_trans_4bit), new VcnDrawProc(this, &KyraRpgEngine::vcnDraw_bw_trans_4bit));
+ setVcnFormat(1);
_doorShapes = new uint8*[6]();
diff --git a/engines/kyra/engine/kyra_rpg.h b/engines/kyra/engine/kyra_rpg.h
index ab3bdb87dd4..b049dd6383e 100644
--- a/engines/kyra/engine/kyra_rpg.h
+++ b/engines/kyra/engine/kyra_rpg.h
@@ -315,15 +315,16 @@ protected:
bool checkSceneUpdateNeed(int block);
uint16 calcNewBlockPosition(uint16 curBlock, uint16 direction);
+ void setVcnFormat(int outputBPP);
void drawVcnBlocks();
void vcnDraw_fw_4bit(uint8 *&dst, const uint8 *&src);
void vcnDraw_bw_4bit(uint8 *&dst, const uint8 *&src);
void vcnDraw_fw_trans_4bit(uint8 *&dst, const uint8 *&src);
void vcnDraw_bw_trans_4bit(uint8 *&dst, const uint8 *&src);
- void vcnDraw_fw_hiCol(uint8 *&dst, const uint8 *&src);
- void vcnDraw_bw_hiCol(uint8 *&dst, const uint8 *&src);
- void vcnDraw_fw_trans_hiCol(uint8 *&dst, const uint8 *&src);
- void vcnDraw_bw_trans_hiCol(uint8 *&dst, const uint8 *&src);
+ template<typename T> void vcnDraw_fw_hiCol(uint8 *&dst, const uint8 *&src);
+ template<typename T> void vcnDraw_bw_hiCol(uint8 *&dst, const uint8 *&src);
+ template<typename T> void vcnDraw_fw_trans_hiCol(uint8 *&dst, const uint8 *&src);
+ template<typename T> void vcnDraw_bw_trans_hiCol(uint8 *&dst, const uint8 *&src);
void vcnDraw_fw_planar(uint8 *&dst, const uint8 *&src);
void vcnDraw_bw_planar(uint8 *&dst, const uint8 *&src);
void vcnDraw_fw_trans_planar(uint8 *&dst, const uint8 *&src);
diff --git a/engines/kyra/engine/scene_eob.cpp b/engines/kyra/engine/scene_eob.cpp
index 832c2231efa..fe87c29e5dd 100644
--- a/engines/kyra/engine/scene_eob.cpp
+++ b/engines/kyra/engine/scene_eob.cpp
@@ -205,24 +205,22 @@ Common::String EoBCoreEngine::initLevelData(int sub) {
setLevelPalettes(_currentLevel);
if (_flags.platform == Common::kPlatformFMTowns) {
- uint16 *src = (uint16*)_screen->getPalette(0).getData();
- _screen->createHiColorFadeTable(src, (uint16*)_greenFadingTable, 4, 75);
- _screen->createHiColorFadeTable(src, (uint16*)_blackFadingTable, 12, 200);
- _screen->createHiColorFadeTable(src, (uint16*)_blueFadingTable, 10, 85);
- _screen->createHiColorFadeTable(src, (uint16*)_lightBlueFadingTable, 11, 125);
- _screen->createHiColorFadeTable(src, (uint16*)_greyFadingTable, 0, 85);
+ const uint16 *src = reinterpret_cast<const uint16 *>(_screen->getPalette(0).getData());
+ _screen->createHiColorFadeTable(src, _greenFadingTable, 4, 75);
+ _screen->createHiColorFadeTable(src, _blackFadingTable, 12, 200);
+ _screen->createHiColorFadeTable(src, _blueFadingTable, 10, 85);
+ _screen->createHiColorFadeTable(src, _lightBlueFadingTable, 11, 125);
+ _screen->createHiColorFadeTable(src, _greyFadingTable, 0, 85);
_screen->setScreenPalette(_screen->getPalette(0));
} else if (_configRenderMode != Common::kRenderCGA && _flags.platform != Common::kPlatformAmiga && _flags.platform != Common::kPlatformSegaCD && !(_flags.gameID == GI_EOB1 && _flags.platform == Common::kPlatformPC98)) {
Palette backupPal(256);
backupPal.copy(_screen->getPalette(0), 224, 32, 224);
_screen->getPalette(0).fill(224, 32, 0x3F);
uint8 *src = _screen->getPalette(0).getData();
-
_screen->createColorFadeTable(src, _greenFadingTable, 4, 75);
_screen->createColorFadeTable(src, _blackFadingTable, 12, 200);
_screen->createColorFadeTable(src, _blueFadingTable, 10, 85);
_screen->createColorFadeTable(src, _lightBlueFadingTable, 11, 125);
-
_screen->getPalette(0).copy(backupPal, 224, 32, 224);
_screen->createColorFadeTable(src, _greyFadingTable, 12, 85);
_screen->setFadeTable(_greyFadingTable);
@@ -634,8 +632,8 @@ void EoBCoreEngine::drawSceneShapes(int start, int end, int drawFlags) {
if (_shpDmX2 <= _shpDmX1)
continue;
- //if (drawFlags & 0x01)
- //drawDecorations(t);
+ if (drawFlags & 0x01)
+ drawDecorations(t);
if ((drawFlags & 0x02) && _visibleBlocks[t]->drawObjects)
drawBlockItems(t);
diff --git a/engines/kyra/engine/scene_rpg.cpp b/engines/kyra/engine/scene_rpg.cpp
index 5a99bd09f04..58437e132eb 100644
--- a/engines/kyra/engine/scene_rpg.cpp
+++ b/engines/kyra/engine/scene_rpg.cpp
@@ -344,6 +344,28 @@ uint16 KyraRpgEngine::calcNewBlockPosition(uint16 curBlock, uint16 direction) {
return (curBlock + blockPosTable[direction]) & 0x3FF;
}
+void KyraRpgEngine::setVcnFormat(int outputBPP) {
+ _vcnBpp = outputBPP;
+
+ delete[] _sceneWindowBuffer;
+ _sceneWindowBuffer = new uint8[22 * 15 * 8 * 8 * _vcnBpp]();
+
+ delete _vcnDrawLine;
+
+ if (_vcnBpp == 4)
+ _vcnDrawLine = new VcnLineDrawingMethods(new VcnDrawProc(this, &KyraRpgEngine::vcnDraw_fw_hiCol<uint32>), new VcnDrawProc(this, &KyraRpgEngine::vcnDraw_bw_hiCol<uint32>),
+ new VcnDrawProc(this, &KyraRpgEngine::vcnDraw_fw_trans_hiCol<uint32>), new VcnDrawProc(this, &KyraRpgEngine::vcnDraw_bw_trans_hiCol<uint32>));
+ else if (_vcnBpp == 2)
+ _vcnDrawLine = new VcnLineDrawingMethods(new VcnDrawProc(this, &KyraRpgEngine::vcnDraw_fw_hiCol<uint16>), new VcnDrawProc(this, &KyraRpgEngine::vcnDraw_bw_hiCol<uint16>),
+ new VcnDrawProc(this, &KyraRpgEngine::vcnDraw_fw_trans_hiCol<uint16>), new VcnDrawProc(this, &KyraRpgEngine::vcnDraw_bw_trans_hiCol<uint16>));
+ else if (_flags.platform == Common::kPlatformAmiga || (_flags.gameID == GI_EOB1 && _flags.use16ColorMode))
+ _vcnDrawLine = new VcnLineDrawingMethods(new VcnDrawProc(this, &KyraRpgEngine::vcnDraw_fw_planar), new VcnDrawProc(this, &KyraRpgEngine::vcnDraw_bw_planar),
+ new VcnDrawProc(this, &KyraRpgEngine::vcnDraw_fw_trans_planar), new VcnDrawProc(this, &KyraRpgEngine::vcnDraw_bw_trans_planar));
+ else
+ _vcnDrawLine = new VcnLineDrawingMethods(new VcnDrawProc(this, &KyraRpgEngine::vcnDraw_fw_4bit), new VcnDrawProc(this, &KyraRpgEngine::vcnDraw_bw_4bit),
+ new VcnDrawProc(this, &KyraRpgEngine::vcnDraw_fw_trans_4bit), new VcnDrawProc(this, &KyraRpgEngine::vcnDraw_bw_trans_4bit));
+}
+
void KyraRpgEngine::drawVcnBlocks() {
uint8 *d = _sceneWindowBuffer;
uint16 *bdb = _blockDrawingBuffer;
@@ -433,7 +455,7 @@ void KyraRpgEngine::vcnDraw_fw_4bit(uint8 *&dst, const uint8 *&src) {
void KyraRpgEngine::vcnDraw_bw_4bit(uint8 *&dst, const uint8 *&src) {
src += 3;
- for (int blockX = 0; blockX < 4 * _vcnBpp; blockX++) {
+ for (int blockX = 0; blockX < 4; blockX++) {
uint8 bl = *src--;
*dst++ = _vcnColTable[((bl & 0x0F) + _wllVcnOffset2) | _vcnShiftVal];
*dst++ = _vcnColTable[((bl >> 4) + _wllVcnOffset2) | _vcnShiftVal];
@@ -442,7 +464,7 @@ void KyraRpgEngine::vcnDraw_bw_4bit(uint8 *&dst, const uint8 *&src) {
}
void KyraRpgEngine::vcnDraw_fw_trans_4bit(uint8 *&dst, const uint8 *&src) {
- for (int blockX = 0; blockX < _vcnSrcBitsPerPixel; blockX++) {
+ for (int blockX = 0; blockX < 4; blockX++) {
uint8 bl = *src++;
uint8 mask = _vcnTransitionMask ? *_vcnMaskTbl++ : 0;
uint8 h = _vcnColTable[((bl >> 4) + _wllVcnRmdOffset) | _vcnShiftVal];
@@ -465,7 +487,7 @@ void KyraRpgEngine::vcnDraw_fw_trans_4bit(uint8 *&dst, const uint8 *&src) {
void KyraRpgEngine::vcnDraw_bw_trans_4bit(uint8 *&dst, const uint8 *&src) {
src += 3;
_vcnMaskTbl += 3;
- for (int blockX = 0; blockX < _vcnSrcBitsPerPixel; blockX++) {
+ for (int blockX = 0; blockX < 4; blockX++) {
uint8 bl = *src--;
uint8 mask = _vcnTransitionMask ? *_vcnMaskTbl-- : 0;
uint8 h = _vcnColTable[((bl & 0x0F) + _wllVcnRmdOffset) | _vcnShiftVal];
@@ -487,46 +509,59 @@ void KyraRpgEngine::vcnDraw_bw_trans_4bit(uint8 *&dst, const uint8 *&src) {
_vcnMaskTbl += 5;
}
-void KyraRpgEngine::vcnDraw_fw_hiCol(uint8 *&dst, const uint8 *&src) {
- const uint16 *hiColorPal = screen()->get16bitPalette();
- for (int blockX = 0; blockX < 8; blockX++) {
- *(uint16*)dst = hiColorPal[*src++];
- dst += 2;
- }
+template<typename T> void KyraRpgEngine::vcnDraw_fw_hiCol(uint8 *&dst, const uint8 *&src) {
+ const T *hiColorPal = reinterpret_cast<const T*>(screen()->getHiColorPalette());
+ T *d = reinterpret_cast<T*>(dst);
+ for (int blockX = 0; blockX < _vcnSrcBitsPerPixel; blockX++)
+ *d++ = hiColorPal[*src++];
+ dst = reinterpret_cast<uint8*>(d);
}
-void KyraRpgEngine::vcnDraw_bw_hiCol(uint8 *&dst, const uint8 *&src) {
+template<typename T> void KyraRpgEngine::vcnDraw_bw_hiCol(uint8 *&dst, const uint8 *&src) {
src += 7;
- const uint16 *hiColorPal = screen()->get16bitPalette();
- for (int blockX = 0; blockX < 4 * _vcnBpp; blockX++) {
- *(uint16*)dst = hiColorPal[*src--];
- dst += 2;
- }
+ const T *hiColorPal = reinterpret_cast<const T*>(screen()->getHiColorPalette());
+ T *d = reinterpret_cast<T*>(dst);
+ for (int blockX = 0; blockX < _vcnSrcBitsPerPixel; blockX++)
+ *d++ = hiColorPal[*src--];
src += 9;
+ dst = reinterpret_cast<uint8*>(d);
}
-void KyraRpgEngine::vcnDraw_fw_trans_hiCol(uint8 *&dst, const uint8 *&src) {
- const uint16 *hiColorPal = screen()->get16bitPalette();
+template<typename T> void KyraRpgEngine::vcnDraw_fw_trans_hiCol(uint8 *&dst, const uint8 *&src) {
+ const T *hiColorPal = reinterpret_cast<const T*>(screen()->getHiColorPalette());
+ T *d = reinterpret_cast<T*>(dst);
for (int blockX = 0; blockX < _vcnSrcBitsPerPixel; blockX++) {
uint8 bl = *src++;
if (bl)
- *(uint16*)dst = hiColorPal[bl];
- dst += 2;
+ *d = hiColorPal[bl];
+ d++;
}
+ dst = reinterpret_cast<uint8*>(d);
}
-void KyraRpgEngine::vcnDraw_bw_trans_hiCol(uint8 *&dst, const uint8 *&src) {
+template<typename T> void KyraRpgEngine::vcnDraw_bw_trans_hiCol(uint8 *&dst, const uint8 *&src) {
src += 7;
- const uint16 *hiColorPal = screen()->get16bitPalette();
+ const T *hiColorPal = reinterpret_cast<const T*>(screen()->getHiColorPalette());
+ T *d = reinterpret_cast<T*>(dst);
for (int blockX = 0; blockX < _vcnSrcBitsPerPixel; blockX++) {
uint8 bl = *src--;
if (bl)
- *(uint16*)dst = hiColorPal[bl];
- dst += 2;
+ *d = hiColorPal[bl];
+ d++;
}
src += 9;
+ dst = reinterpret_cast<uint8*>(d);
}
+template void KyraRpgEngine::vcnDraw_fw_hiCol<uint16>(uint8 *&dst, const uint8 *&src);
+template void KyraRpgEngine::vcnDraw_fw_hiCol<uint32>(uint8 *&dst, const uint8 *&src);
+template void KyraRpgEngine::vcnDraw_bw_hiCol<uint16>(uint8 *&dst, const uint8 *&src);
+template void KyraRpgEngine::vcnDraw_bw_hiCol<uint32>(uint8 *&dst, const uint8 *&src);
+template void KyraRpgEngine::vcnDraw_fw_trans_hiCol<uint16>(uint8 *&dst, const uint8 *&src);
+template void KyraRpgEngine::vcnDraw_fw_trans_hiCol<uint32>(uint8 *&dst, const uint8 *&src);
+template void KyraRpgEngine::vcnDraw_bw_trans_hiCol<uint16>(uint8 *&dst, const uint8 *&src);
+template void KyraRpgEngine::vcnDraw_bw_trans_hiCol<uint32>(uint8 *&dst, const uint8 *&src);
+
void KyraRpgEngine::vcnDraw_fw_planar(uint8 *&dst, const uint8 *&src) {
for (int blockX = 0; blockX < 8; blockX++) {
uint8 col = 0;
diff --git a/engines/kyra/graphics/screen.cpp b/engines/kyra/graphics/screen.cpp
index 0a51e1d7556..fcc1315c813 100644
--- a/engines/kyra/graphics/screen.cpp
+++ b/engines/kyra/graphics/screen.cpp
@@ -23,6 +23,7 @@
#include "kyra/kyra_v1.h"
#include "kyra/resource/resource.h"
+#include "common/algorithm.h"
#include "common/endian.h"
#include "common/memstream.h"
#include "common/system.h"
@@ -66,6 +67,11 @@ Screen::Screen(KyraEngine_v1 *vm, OSystem *system, const ScreenDim *dimTable, co
memset(_pageMapping, 0, sizeof(_pageMapping));
memset(_sjisOverlayPtrs, 0, sizeof(_sjisOverlayPtrs));
+ _mergeOverlayProc = nullptr;
+ _scale2xProc = nullptr;
+ _getPagePixelProc = nullptr;
+ _setPagePixelProc = nullptr;
+
_renderMode = Common::kRenderDefault;
_sjisMixedFontMode = false;
@@ -73,7 +79,6 @@ Screen::Screen(KyraEngine_v1 *vm, OSystem *system, const ScreenDim *dimTable, co
_animBlockPtr = _textRenderBuffer = nullptr;
_textRenderBufferSize = 0;
- _useHiColorScreen = _vm->gameFlags().useHiColorMode;
_outputPixelFormat = Graphics::PixelFormat::createFormatCLUT8();
_useShapeShading = true;
_screenPageSize = SCREEN_PAGE_SIZE;
@@ -113,8 +118,8 @@ Screen::~Screen() {
delete _screenPalette;
delete _internFadePalette;
delete[] _animBlockPtr;
- delete[] _hiColorNativePalettes;
- delete[] _hiColorConversionPalette;
+ delete[] reinterpret_cast<uint8*>(_hiColorNativePalettes);
+ delete[] reinterpret_cast<uint8*>(_hiColorConversionPalette);
_sjisFontShared.reset();
@@ -128,6 +133,48 @@ Screen::~Screen() {
}
}
+template void Screen::mergeOverlayImpl<uint8>(int x, int y, int w, int h);
+template void Screen::mergeOverlayImpl<uint16>(int x, int y, int w, int h);
+template void Screen::mergeOverlayImpl<uint32>(int x, int y, int w, int h);
+template void Screen::setPagePixelImpl<uint8>(int pageNum, int x, int y, uint8 color);
+template void Screen::setPagePixelImpl<uint16>(int pageNum, int x, int y, uint8 color);
+template void Screen::setPagePixelImpl<uint32>(int pageNum, int x, int y, uint8 color);
+template int Screen::getPagePixelImpl<uint8>(int pageNum, int x, int y);
+template int Screen::getPagePixelImpl<uint16>(int pageNum, int x, int y);
+template int Screen::getPagePixelImpl<uint32>(int pageNum, int x, int y);
+template void Screen::scale2x<uint8, uint8>(uint8 *dst, int dstPitch, const uint8 *src, int srcPitch, int w, int h);
+template void Screen::scale2x<uint16, uint16>(uint8 *dst, int dstPitch, const uint8 *src, int srcPitch, int w, int h);
+template void Screen::scale2x<uint32, uint32>(uint8 *dst, int dstPitch, const uint8 *src, int srcPitch, int w, int h);
+template void Screen::scale2x<uint8, uint16>(uint8 *dst, int dstPitch, const uint8 *src, int srcPitch, int w, int h);
+template void Screen::scale2x<uint8, uint32>(uint8 *dst, int dstPitch, const uint8 *src, int srcPitch, int w, int h);
+
+const Screen::MergeOverlayFunc Screen::_mergeOverlayProcs[] = {
+ &Screen::mergeOverlayImpl<uint8>,
+ &Screen::mergeOverlayImpl<uint16>,
+ &Screen::mergeOverlayImpl<uint32>};
+
+const Screen::Scale2xFunc Screen::_scale2xProcs[] = {
+ &Screen::scale2x<uint8, uint8>,
+ &Screen::scale2x<uint8, uint16>,
+ &Screen::scale2x<uint8, uint32>,
+ &Screen::scale2x<uint16, uint16>,
+ nullptr,
+ nullptr,
+ &Screen::scale2x<uint32, uint32>,
+};
+
+const Screen::GetPagePixelProc Screen::_getPagePixelProcs[] = {
+ &Screen::getPagePixelImpl<uint8>,
+ &Screen::getPagePixelImpl<uint16>,
+ &Screen::getPagePixelImpl<uint32>
+};
+
+const Screen::SetPagePixelProc Screen::_setPagePixelProcs[] = {
+ &Screen::setPagePixelImpl<uint8>,
+ &Screen::setPagePixelImpl<uint16>,
+ &Screen::setPagePixelImpl<uint32>
+};
+
bool Screen::init() {
_debugEnabled = false;
_useOverlays = false;
@@ -180,13 +227,13 @@ bool Screen::init() {
_sjisMixedFontMode = !_use16ColorMode;
if (!_sjisOverlayPtrs[0]) {
- // We alway assume 2 bytes per pixel here when the backend is in hicolor mode, since this is the surface that is passed to the backend.
+ // We use the number of bytes per pixel here when the backend is in hicolor mode, since this is the surface that is passed to the backend.
// We do this regardsless of the paramater sent to enableHiColorMode() so as not to have to change the backend color mode.
- // Conversions from 8bit to 16bit have to take place when copying data to this surface here.
- int bpp = _useHiColorScreen ? 2 : 1;
- _sjisOverlayPtrs[0] = new uint8[SCREEN_OVL_SJIS_SIZE * bpp];
+ // Conversions from 8bit to the actual bpp have to take place when copying data to this surface here.
+ assert(_outputPixelFormat.bytesPerPixel > 0);
+ _sjisOverlayPtrs[0] = new uint8[SCREEN_OVL_SJIS_SIZE * _outputPixelFormat.bytesPerPixel];
assert(_sjisOverlayPtrs[0]);
- memset(_sjisOverlayPtrs[0], _sjisInvisibleColor, SCREEN_OVL_SJIS_SIZE * bpp);
+ memset(_sjisOverlayPtrs[0], _sjisInvisibleColor, SCREEN_OVL_SJIS_SIZE * _outputPixelFormat.bytesPerPixel);
}
for (int i = 1; i < SCREEN_OVLS_NUM; ++i) {
@@ -209,6 +256,9 @@ bool Screen::init() {
else if (_vm->gameFlags().platform != Common::kPlatformPC98 || _vm->game() != GI_EOB2)
_fonts[FID_SJIS_FNT] = new SJISFont(_sjisFontShared, _sjisInvisibleColor, false, _vm->game() != GI_LOL && _vm->game() != GI_EOB2, _vm->game() == GI_LOL ? 1 : 0);
}
+
+ assert((_outputPixelFormat.bytesPerPixel >> 1) < ARRAYSIZE(_mergeOverlayProcs));
+ _mergeOverlayProc = _mergeOverlayProcs[_outputPixelFormat.bytesPerPixel >> 1];
}
_curPage = 0;
@@ -272,7 +322,7 @@ bool Screen::init() {
_overdrawMargin = (_vm->game() == GI_EOB2 && _vm->gameFlags().lang == Common::ZH_TWN);
for (int i = 0; i < ARRAYSIZE(_textColorsMap); ++i)
_textColorsMap[i] = i;
- _textColorsMap16bit[0] = _textColorsMap16bit[1] = 0;
+ _textColorsMapHiCol[0] = _textColorsMapHiCol[1] = 0;
_animBlockPtr = nullptr;
_animBlockSize = 0;
_mouseLockCount = 1;
@@ -303,7 +353,7 @@ bool Screen::enableScreenDebug(bool enable) {
Common::Error Screen::setResolution() {
byte palette[3 * 256];
- if (!_useHiColorScreen)
+ if (!_vm->gameFlags().useHiColorMode)
_system->getPaletteManager()->grabPalette(palette, 0, 256);
int width = 320, height = 200;
@@ -325,22 +375,10 @@ Common::Error Screen::setResolution() {
if (_vm->gameFlags().platform == Common::kPlatformSegaCD)
height = 224;
- if (_useHiColorScreen) {
- Graphics::PixelFormat px(2, 5, 5, 5, 0, 10, 5, 0, 0);
- Common::List<Graphics::PixelFormat> tryModes = _system->getSupportedFormats();
- for (Common::List<Graphics::PixelFormat>::iterator g = tryModes.begin(); g != tryModes.end(); ++g) {
- if (g->bytesPerPixel != 2 || g->aBits()) {
- g = tryModes.reverse_erase(g);
- } else if (*g == px) {
- tryModes.clear();
- tryModes.push_back(px);
- break;
- }
- }
- initGraphics(width, height, tryModes);
-
+ if (_vm->gameFlags().useHiColorMode) {
+ initGraphics(width, height, nullptr);
_outputPixelFormat = _system->getScreenFormat();
- if (_outputPixelFormat.bytesPerPixel < 2)
+ if (_outputPixelFormat.bytesPerPixel != 2 && _outputPixelFormat.bytesPerPixel != 4)
return Common::kUnsupportedColorMode;
} else {
@@ -352,26 +390,32 @@ Common::Error Screen::setResolution() {
}
void Screen::enableHiColorMode(bool enabled) {
- if (_useHiColorScreen && enabled) {
+ if (_outputPixelFormat.bytesPerPixel > 1 && enabled) {
if (!_hiColorNativePalettes)
- _hiColorNativePalettes = new uint16[1024];
- memset(_hiColorNativePalettes, 0, 1024 * sizeof(uint16));
- delete[] _hiColorConversionPalette;
+ _hiColorNativePalettes = new uint8[_outputPixelFormat.bytesPerPixel * 1024]();
+ delete[] reinterpret_cast<uint8*>(_hiColorConversionPalette);
_hiColorConversionPalette = nullptr;
- _internalBytesPerPixel = 2;
+ _internalBytesPerPixel = _outputPixelFormat.bytesPerPixel;
} else {
- if (_useHiColorScreen) {
+ if (_outputPixelFormat.bytesPerPixel > 1) {
if (!_hiColorConversionPalette)
- _hiColorConversionPalette = new uint16[256];
- memset(_hiColorConversionPalette, 0, 256 * sizeof(uint16));
+ _hiColorConversionPalette = new uint8[_outputPixelFormat.bytesPerPixel * 256]();
}
- delete[] _hiColorNativePalettes;
+ delete[] reinterpret_cast<uint8*>(_hiColorNativePalettes);
_hiColorNativePalettes = nullptr;
_internalBytesPerPixel = 1;
}
resetPagePtrsAndBuffers(_isSegaCD ? SCREEN_W * _screenHeight : SCREEN_PAGE_SIZE * _internalBytesPerPixel);
+
+ int num = _outputPixelFormat.bytesPerPixel >> 1;
+ assert((_internalBytesPerPixel & ~1) + num < ARRAYSIZE(_scale2xProcs));
+ _scale2xProc = _scale2xProcs[(_internalBytesPerPixel & ~1) + num];
+ assert(num < ARRAYSIZE(_getPagePixelProcs));
+ _getPagePixelProc = _getPagePixelProcs[num];
+ assert(num < ARRAYSIZE(_setPagePixelProcs));
+ _setPagePixelProc = _setPagePixelProcs[num];
}
int Screen::updateScreen() {
@@ -468,33 +512,25 @@ void Screen::updateDirtyRectsAmiga() {
_dirtyRects.clear();
}
-#define mScale2x(dst, dstPitch, src, srcPitch, w, h) \
- if (!_useHiColorScreen) \
- scale2x<uint8, uint16>(dst, dstPitch, src, srcPitch, w, h); \
- else if (_internalBytesPerPixel == 2) \
- scale2x<uint16, uint32>(dst, dstPitch, src, srcPitch, w, h); \
- else \
- scale2x<uint8, uint32>(dst, dstPitch, src, srcPitch, w, h)
-
void Screen::updateDirtyRectsOvl() {
+ assert(_scale2xProc);
if (_forceFullUpdate) {
const byte *src = getCPagePtr(0);
- byte *dst = _sjisOverlayPtrs[0];
- mScale2x(dst, 640, src, SCREEN_W, SCREEN_W, SCREEN_H);
+ uint8 *dst = _sjisOverlayPtrs[0];
+ (this->*_scale2xProc)(dst, 640, src, SCREEN_W, SCREEN_W, SCREEN_H);
mergeOverlay(0, 0, 640, 400);
- _system->copyRectToScreen(dst, _useHiColorScreen ? 1280 : 640, 0, 0, 640, 400);
+ _system->copyRectToScreen(dst, 640 * _outputPixelFormat.bytesPerPixel, 0, 0, 640, 400);
} else {
- const byte *page0 = getCPagePtr(0);
- byte *ovl0 = _sjisOverlayPtrs[0];
- int dstBpp = _useHiColorScreen ? 2 : 1;
+ const uint8 *page0 = getCPagePtr(0);
+ uint8 *ovl0 = _sjisOverlayPtrs[0];
Common::List<Common::Rect>::iterator it;
for (it = _dirtyRects.begin(); it != _dirtyRects.end(); ++it) {
- byte *dst = ovl0 + it->top * 1280 * dstBpp + (it->left << dstBpp);
- const byte *src = page0 + it->top * SCREEN_W * _internalBytesPerPixel + it->left * _internalBytesPerPixel;
- mScale2x(dst, 640, src, SCREEN_W, it->width(), it->height());
+ uint8 *dst = ovl0 + it->top * 2 * 640 * _outputPixelFormat.bytesPerPixel + it->left * 2 * _outputPixelFormat.bytesPerPixel;
+ const uint8 *src = page0 + it->top * SCREEN_W * _internalBytesPerPixel + it->left * _internalBytesPerPixel;
+ (this->*_scale2xProc)(dst, 640, src, SCREEN_W, it->width(), it->height());
mergeOverlay(it->left<<1, it->top<<1, it->width()<<1, it->height()<<1);
- _system->copyRectToScreen(dst, _useHiColorScreen ? 1280 : 640, it->left << 1, it->top << 1, it->width() << 1, it->height() << 1);
+ _system->copyRectToScreen(dst, 640 * _outputPixelFormat.bytesPerPixel, it->left << 1, it->top << 1, it->width() << 1, it->height() << 1);
}
}
@@ -502,42 +538,39 @@ void Screen::updateDirtyRectsOvl() {
_dirtyRects.clear();
}
-#undef mScale2x
-
-template<typename srcType, typename scaleToType>
+template<typename srcPixelType, typename dstPixelType>
void Screen::scale2x(uint8 *dst, int dstPitch, const uint8 *src, int srcPitch, int w, int h) {
- int dstAdd = dstPitch - w;
+ int dstAdd = (dstPitch - w) << 1;
int srcAdd = srcPitch - w;
- scaleToType *dstL1 = (scaleToType*)dst;
- scaleToType *dstL2 = (scaleToType*)(dst + dstPitch * (sizeof(scaleToType) >> 1));
- const srcType *src1 = (const srcType*)src;
+ dstPixelType *dstL11= reinterpret_cast<dstPixelType*>(dst);
+ dstPixelType *dstL12 = dstL11 + 1;
+ dstPixelType *dstL21 = dstL11 + dstPitch;
+ dstPixelType *dstL22 = dstL12 + dstPitch;
+ const dstPixelType *p = reinterpret_cast<const dstPixelType *>(_hiColorNativePalettes ? _hiColorNativePalettes : _hiColorConversionPalette);
+ const srcPixelType *src1 = reinterpret_cast<const srcPixelType*>(src);
while (h--) {
for (int x = 0; x < w; x++) {
- scaleToType col = (sizeof(srcType) == 1 && sizeof(scaleToType) == 4) ? _hiColorConversionPalette[*src1++] : *src1++;
- *dstL1++ = *dstL2++ = col | (col << (sizeof(scaleToType) << 2));
+ *dstL11 = *dstL12 = *dstL21 = *dstL22 = (sizeof(srcPixelType) == sizeof(dstPixelType)) ? *src1++ : p[*src1++];
+ dstL11 += 2; dstL12 += 2; dstL21 += 2; dstL22 += 2;
}
- dstL1 += dstAdd; dstL2 += dstAdd;
+ dstL11 += dstAdd; dstL12 += dstAdd; dstL21 += dstAdd; dstL22 += dstAdd;
src1 += srcAdd;
}
}
-template void Screen::scale2x<uint8, uint16>(uint8 *dst, int dstPitch, const uint8 *src, int srcPitch, int w, int h);
-template void Screen::scale2x<uint16, uint32>(uint8 *dst, int dstPitch, const uint8 *src, int srcPitch, int w, int h);
-template void Screen::scale2x<uint8, uint32>(uint8 *dst, int dstPitch, const uint8 *src, int srcPitch, int w, int h);
-
template<typename pixelType>
void Screen::mergeOverlayImpl(int x, int y, int w, int h) {
const uint8 *src = _sjisOverlayPtrs[1] + y * 640 + x;
- uint16 *p16 = _hiColorNativePalettes ? _hiColorNativePalettes : _hiColorConversionPalette;
- pixelType *dst = (pixelType*)(_sjisOverlayPtrs[0] + y * 640 * sizeof(pixelType) + x * sizeof(pixelType));
+ const pixelType *p = reinterpret_cast<const pixelType*>(_hiColorNativePalettes ? _hiColorNativePalettes : _hiColorConversionPalette);
+ pixelType *dst = reinterpret_cast<pixelType*>(_sjisOverlayPtrs[0] + y * 640 * sizeof(pixelType) + x * sizeof(pixelType));
int add = 640 - w;
while (h--) {
for (x = 0; x < w; ++x) {
uint8 col = *src++;
if (col != _sjisInvisibleColor)
- *dst = (sizeof(pixelType) == 2) ? p16[col] : col;
+ *dst = (sizeof(pixelType) == 1) ? col : p[col];
dst++;
}
dst += add;
@@ -545,9 +578,6 @@ void Screen::mergeOverlayImpl(int x, int y, int w, int h) {
}
}
-template void Screen::mergeOverlayImpl<uint8>(int x, int y, int w, int h);
-template void Screen::mergeOverlayImpl<uint16>(int x, int y, int w, int h);
-
const ScreenDim *Screen::getScreenDim(int dim) const {
assert(dim < _dimTableCount);
return _customDimTable[dim] ? _customDimTable[dim] : &_dimTable[dim];
@@ -784,35 +814,35 @@ void Screen::copyWsaRect(int x, int y, int w, int h, int dimState, int plotFunc,
}
}
-int Screen::getPagePixel(int pageNum, int x, int y) {
+template <typename T> int Screen::getPagePixelImpl(int pageNum, int x, int y) {
assert(pageNum < SCREEN_PAGE_NUM);
assert(x >= 0 && x < SCREEN_W && y >= 0 && y < _screenHeight);
- if (_internalBytesPerPixel == 1)
+ if (sizeof(T) == 1)
return _pagePtrs[pageNum][y * SCREEN_W + x];
else
- return ((uint16*)_pagePtrs[pageNum])[y * SCREEN_W + x];
+ return static_cast<int>(reinterpret_cast<T*>(_pagePtrs[pageNum])[y * SCREEN_W + x]);
}
-void Screen::setPagePixel(int pageNum, int x, int y, uint8 color) {
+template<typename T>
+void Screen::setPagePixelImpl(int pageNum, int x, int y, uint8 color) {
assert(pageNum < SCREEN_PAGE_NUM);
assert(x >= 0 && x < SCREEN_W && y >= 0 && y < _screenHeight);
if (pageNum == 0 || pageNum == 1)
addDirtyRect(x, y, 1, 1);
- if (_4bitPixelPacking) {
- color &= 0x0F;
- color |= (color << 4);
- } else if (_renderMode == Common::kRenderCGA) {
- color &= 0x03;
- } else if (_use16ColorMode || (_renderMode == Common::kRenderEGA && !_useHiResEGADithering)) {
- color &= 0x0F;
- }
-
- if (_internalBytesPerPixel == 2) {
- ((uint16*)_pagePtrs[pageNum])[y * SCREEN_W + x] = _hiColorNativePalettes[color];
- } else {
+ if (sizeof(T) == 1) {
+ if (_4bitPixelPacking) {
+ color &= 0x0F;
+ color |= (color << 4);
+ } else if (_renderMode == Common::kRenderCGA) {
+ color &= 0x03;
+ } else if (_use16ColorMode || (_renderMode == Common::kRenderEGA && !_useHiResEGADithering)) {
+ color &= 0x0F;
+ }
_pagePtrs[pageNum][y * SCREEN_W + x] = color;
+ } else {
+ reinterpret_cast<T*>(_pagePtrs[pageNum])[y * SCREEN_W + x] = reinterpret_cast<T*>(_hiColorNativePalettes)[color];
}
}
@@ -829,12 +859,12 @@ void Screen::fadeToBlack(int delay, const UpdateFunctor *upFunc) {
}
void Screen::fadePalette(const Palette &pal, int delay, const UpdateFunctor *upFunc) {
- if (_renderMode == Common::kRenderEGA || _internalBytesPerPixel == 2)
+ if (_renderMode == Common::kRenderEGA || _internalBytesPerPixel > 1)
setScreenPalette(pal);
updateScreen();
- if (_renderMode == Common::kRenderCGA || _renderMode == Common::kRenderEGA || _internalBytesPerPixel == 2)
+ if (_renderMode == Common::kRenderCGA || _renderMode == Common::kRenderEGA || _internalBytesPerPixel > 1)
return;
int diff = 0, delayInc = 0;
@@ -848,7 +878,7 @@ void Screen::fadePalette(const Palette &pal, int delay, const UpdateFunctor *upF
if (upFunc && upFunc->isValid())
(*upFunc)();
- else if (_useHiColorScreen)
+ else if (_outputPixelFormat.bytesPerPixel > 1)
updateScreen();
else
updateBackendScreen(true);
@@ -1055,19 +1085,35 @@ void Screen::copyRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPag
dst += SCREEN_W * _internalBytesPerPixel;
}
} else {
- while (h--) {
- for (int i = 0; i < w; ++i) {
- if (_internalBytesPerPixel == 2) {
- uint px = *(const uint16*)&src[i << 1];
+ if (_internalBytesPerPixel == 4) {
+ while (h--) {
+ for (int i = 0; i < w; ++i) {
+ uint32 px = reinterpret_cast<const uint32*>(src)[i];
if (px)
- *(uint16*)&dst[i << 1] = px;
- } else {
+ reinterpret_cast<uint32*>(dst)[i] = px;
+ }
+ src += SCREEN_W * _internalBytesPerPixel;
+ dst += SCREEN_W * _internalBytesPerPixel;
+ }
+ } else if (_internalBytesPerPixel == 2) {
+ while (h--) {
+ for (int i = 0; i < w; ++i) {
+ uint16 px = reinterpret_cast<const uint16*>(src)[i];
+ if (px)
+ reinterpret_cast<uint16*>(dst)[i] = px;
+ }
+ src += SCREEN_W * _internalBytesPerPixel;
+ dst += SCREEN_W * _internalBytesPerPixel;
+ }
+ } else {
+ while (h--) {
+ for (int i = 0; i < w; ++i) {
if (src[i])
dst[i] = src[i];
}
+ src += SCREEN_W * _internalBytesPerPixel;
+ dst += SCREEN_W * _internalBytesPerPixel;
}
- src += SCREEN_W * _internalBytesPerPixel;
- dst += SCREEN_W * _internalBytesPerPixel;
}
}
}
@@ -1203,7 +1249,7 @@ void Screen::shuffleScreen(int sx, int sy, int w, int h, int srcPage, int dstPag
void Screen::fillRect(int x1, int y1, int x2, int y2, uint8 color, int pageNum, bool xored) {
assert(x2 < SCREEN_W && y2 < _screenHeight);
- uint16 color16 = 0;
+ uint32 hcolor = 0;
if (pageNum == -1)
pageNum = _curPage;
@@ -1221,8 +1267,8 @@ void Screen::fillRect(int x1, int y1, int x2, int y2, uint8 color, int pageNum,
color &= 0x03;
} else if (_use16ColorMode || (_renderMode == Common::kRenderEGA && !_useHiResEGADithering)) {
color &= 0x0F;
- } else if (_internalBytesPerPixel == 2)
- color16 = shadeRGBColor(_hiColorNativePalettes[color]);
+ } else if (_internalBytesPerPixel > 1)
+ hcolor = shadeRGBColor(_internalBytesPerPixel == 4 ? reinterpret_cast<const uint32*>(_hiColorNativePalettes)[color] : reinterpret_cast<const uint16*>(_hiColorNativePalettes)[color]);
if (xored) {
// no 16 bit support for this (unneeded)
@@ -1233,10 +1279,14 @@ void Screen::fillRect(int x1, int y1, int x2, int y2, uint8 color, int pageNum,
}
} else {
for (; y1 <= y2; ++y1) {
- if (_internalBytesPerPixel == 2) {
- uint16 *ptr = (uint16*)dst;
+ if (_internalBytesPerPixel == 4) {
+ uint32 *ptr = reinterpret_cast<uint32*>(dst);
for (int i = 0; i < x2 - x1 + 1; i++)
- *ptr++ = color16;
+ *ptr++ = hcolor;
+ } else if (_internalBytesPerPixel == 2) {
+ uint16 *ptr = reinterpret_cast<uint16*>(dst);
+ for (int i = 0; i < x2 - x1 + 1; i++)
+ *ptr++ = static_cast<uint16>(hcolor);
} else {
memset(dst, color, x2 - x1 + 1);
}
@@ -1306,27 +1356,41 @@ void Screen::drawLine(bool vertical, int x, int y, int length, int color) {
color &= 0x03;
} else if (_use16ColorMode || (_renderMode == Common::kRenderEGA && !_useHiResEGADithering)) {
color &= 0x0F;
- } else if (_internalBytesPerPixel == 2)
- color = shadeRGBColor(_hiColorNativePalettes[color]);
+ } else if (_internalBytesPerPixel > 1)
+ color = static_cast<int>(shadeRGBColor(_internalBytesPerPixel == 4 ? reinterpret_cast<const uint32*>(_hiColorNativePalettes)[color] : reinterpret_cast<const uint16*>(_hiColorNativePalettes)[color]));
if (vertical) {
assert((y + length) <= SCREEN_H);
int currLine = 0;
- while (currLine < length) {
- if (_internalBytesPerPixel == 2)
- *(uint16*)ptr = color;
- else
+ if (_internalBytesPerPixel == 4) {
+ uint32 *p = reinterpret_cast<uint32*>(ptr);
+ while (currLine < length) {
+ *p = color;
+ p += SCREEN_W;
+ currLine++;
+ }
+ } else if (_internalBytesPerPixel == 2) {
+ uint16 *p = reinterpret_cast<uint16*>(ptr);
+ while (currLine < length) {
+ *p = static_cast<uint16>(color);
+ p += SCREEN_W;
+ currLine++;
+ }
+ } else {
+ while (currLine < length) {
*ptr = color;
- ptr += SCREEN_W * _internalBytesPerPixel;
- currLine++;
+ ptr += SCREEN_W;
+ currLine++;
+ }
}
} else {
assert((x + length) <= SCREEN_W);
- if (_internalBytesPerPixel == 2) {
- for (int i = 0; i < length; i++) {
- *(uint16*)ptr = color;
- ptr += 2;
- }
+ if (_internalBytesPerPixel == 4) {
+ uint32 *p = reinterpret_cast<uint32*>(ptr);
+ Common::fill<uint32*, uint32>(p, &p[length], color);
+ } else if (_internalBytesPerPixel == 2) {
+ uint16 *p = reinterpret_cast<uint16*>(ptr);
+ Common::fill<uint16*, uint32>(p, &p[length], color);
} else {
memset(ptr, color, length);
}
@@ -1355,15 +1419,15 @@ void Screen::setTextColor(const uint8 *cmap8, int a, int b) {
}
}
-void Screen::setTextColor16bit(const uint16 *cmap16) {
- assert(cmap16);
- _textColorsMap16bit[0] = cmap16[0];
- _textColorsMap16bit[1] = cmap16[1];
+void Screen::setTextColorHiCol(const uint32 *cmap) {
+ assert(cmap);
+ _textColorsMapHiCol[0] = cmap[0];
+ _textColorsMapHiCol[1] = cmap[1];
// We need to update the color tables of all fonts, we
// setup so far here.
for (int i = 0; i < FID_NUM; ++i) {
if (_fonts[i])
- _fonts[i]->set16bitColorMap(_textColorsMap16bit);
+ _fonts[i]->setHiColorMap(_textColorsMapHiCol);
}
}
@@ -1516,11 +1580,16 @@ int Screen::getNumberOfCharacters(const char *str) {
}
void Screen::printText(const char *str, int x, int y, uint8 color1, uint8 color2, int pitch) {
- uint16 cmap16[2];
+ uint32 cmapHiCol[2];
if (_hiColorNativePalettes) {
- cmap16[0] = color2 ? shadeRGBColor(_hiColorNativePalettes[color2]) : 0xFFFF;
- cmap16[1] = _hiColorNativePalettes[color1];
- setTextColor16bit(cmap16);
+ if (_internalBytesPerPixel == 4) {
+ cmapHiCol[0] = color2 ? shadeRGBColor(reinterpret_cast<uint32*>(_hiColorNativePalettes)[color2]) : 0xFFFFFFFF;
+ cmapHiCol[1] = reinterpret_cast<uint32*>(_hiColorNativePalettes)[color1];
+ } else {
+ cmapHiCol[0] = color2 ? shadeRGBColor(reinterpret_cast<uint16*>(_hiColorNativePalettes)[color2]) : 0xFFFF;
+ cmapHiCol[1] = reinterpret_cast<uint16*>(_hiColorNativePalettes)[color1];
+ }
+ setTextColorHiCol(cmapHiCol);
}
uint8 cmap8[2];
@@ -1626,7 +1695,7 @@ void Screen::drawChar(uint16 c, int x, int y, int pitch) {
return;
}
- int bpp = (_currentFont == Screen::FID_SJIS_LARGE_FNT) ? 2 : 1;
+ int bpp = (_currentFont == Screen::FID_SJIS_LARGE_FNT) ? _outputPixelFormat.bytesPerPixel : 1;
destPage += (y * 2) * 640 * bpp + (x * 2 * bpp);
fnt->drawChar(c, destPage, 640, bpp);
@@ -3113,7 +3182,7 @@ int16 Screen::encodeShapeAndCalculateSize(uint8 *from, uint8 *to, int size_to) {
return (to - toPtr);
}
-uint16 Screen::shadeRGBColor(uint16 col) {
+uint32 Screen::shadeRGBColor(uint32 col) {
uint8 r = 0, g = 0, b = 0;
_outputPixelFormat.colorToRGB(col, r, g, b);
@@ -3182,7 +3251,7 @@ void Screen::setMouseCursor(int x, int y, const byte *shape) {
if (_vm->gameFlags().useHiRes) {
xOffset = mouseWidth;
- scale2x<uint8, uint16>(getPagePtr(8) + mouseWidth, SCREEN_W, getPagePtr(8), SCREEN_W, mouseWidth, mouseHeight);
+ scale2x<uint8, uint8>(getPagePtr(8) + mouseWidth, SCREEN_W, getPagePtr(8), SCREEN_W, mouseWidth, mouseHeight);
postProcessCursor(getPagePtr(8) + mouseWidth, mouseWidth, mouseHeight, SCREEN_W);
} else {
postProcessCursor(getPagePtr(8), mouseWidth, mouseHeight, SCREEN_W);
@@ -3435,7 +3504,7 @@ bool Screen::loadPalette(const char *filename, Palette &pal) {
numCols /= Palette::kVGABytesPerColor;
pal.loadVGAPalette(*stream, 0, numCols);
} else {
- if (_internalBytesPerPixel == 2) {
+ if (_internalBytesPerPixel > 1) {
numCols = stream->size() / 2;
pal.loadHiColorPalette(*stream, 0, numCols);
} else if (!_hiColorNativePalettes) {
@@ -3541,20 +3610,22 @@ void Screen::addDirtyRect(int x, int y, int w, int h) {
// overlay functions
byte *Screen::getOverlayPtr(int page) {
- if (page == 0 || page == 1)
+ page &= ~1;
+
+ if (page == 0)
return _sjisOverlayPtrs[1];
- else if (page == 2 || page == 3)
+ else if (page == 2)
return _sjisOverlayPtrs[2];
if (_vm->game() == GI_KYRA2) {
- if (page == 12 || page == 13)
+ if (page == 12)
return _sjisOverlayPtrs[3];
} else if (_vm->game() == GI_LOL) {
- if (page == 4 || page == 5)
+ if (page == 4)
return _sjisOverlayPtrs[3];
- if (page == 6 || page == 7)
+ if (page == 6)
return _sjisOverlayPtrs[4];
- if (page == 12 || page == 13)
+ if (page == 12)
return _sjisOverlayPtrs[5];
}
@@ -3651,8 +3722,10 @@ void Screen::crossFadeRegion(int x1, int y1, int x2, int y2, int w, int h, int s
if (++iH >= h)
iH = 0;
- if (_internalBytesPerPixel == 2)
- ((uint16*)d)[dY * 320 + dX] = ((uint16*)s)[sY * 320 + sX];
+ if (_internalBytesPerPixel == 4)
+ reinterpret_cast<uint32*>(d)[dY * 320 + dX] = reinterpret_cast<uint32*>(s)[sY * 320 + sX];
+ else if (_internalBytesPerPixel == 2)
+ reinterpret_cast<uint16*>(d)[dY * 320 + dX] = reinterpret_cast<uint16*>(s)[sY * 320 + sX];
else
d[dY * 320 + dX] = s[sY * 320 + sX];
addDirtyRect(dX, dY, 1, 1);
diff --git a/engines/kyra/graphics/screen.h b/engines/kyra/graphics/screen.h
index 3e9dc38a2bd..27b0f12cca7 100644
--- a/engines/kyra/graphics/screen.h
+++ b/engines/kyra/graphics/screen.h
@@ -122,7 +122,7 @@ public:
/**
* Sets a text 16bit palette map. Only used in in EOB II FM-Towns. The map contains 2 entries.
*/
- virtual void set16bitColorMap(const uint16 *src) {}
+ virtual void setHiColorMap(const uint32 *src) {}
enum FontStyle {
kStyleNone = 0,
@@ -678,8 +678,14 @@ public:
void clearPage(int pageNum);
- int getPagePixel(int pageNum, int x, int y);
- void setPagePixel(int pageNum, int x, int y, uint8 color);
+ int getPagePixel(int pageNum, int x, int y) {
+ assert(_getPagePixelProc);
+ return (this->*_getPagePixelProc)(pageNum, x, y);
+ }
+ void setPagePixel(int pageNum, int x, int y, uint8 color) {
+ assert(_setPagePixelProc);
+ (this->*_setPagePixelProc)(pageNum, x, y, color);
+ }
const uint8 *getCPagePtr(int pageNum) const;
uint8 *getPageRect(int pageNum, int x, int y, int w, int h);
@@ -731,7 +737,7 @@ public:
virtual void setTextColorMap(const uint8 *cmap) = 0;
void setTextColor(const uint8 *cmap, int a, int b);
- void setTextColor16bit(const uint16 *cmap16);
+ void setTextColorHiCol(const uint32 *cmap);
int setFontStyles(FontId fontId, int styles);
const ScreenDim *getScreenDim(int dim) const;
@@ -814,7 +820,7 @@ public:
// can well afford the 20 lines of extra code.
void crossFadeRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPage, int dstPage);
- uint16 *get16bitPalette() { return _hiColorNativePalettes; }
+ const void *getHiColorPalette() const { return _hiColorNativePalettes; }
void set16bitShadingLevel(int lvl) { _hiColorShadingLevel = lvl; }
protected:
@@ -824,13 +830,11 @@ protected:
void updateDirtyRectsAmiga();
void updateDirtyRectsOvl();
- template<typename srcType, typename scaleToType> void scale2x(uint8 *dst, int dstPitch, const uint8 *src, int srcPitch, int w, int h);
+ template<typename srcPixelType, typename dstPixelType> void scale2x(uint8 *dst, int dstPitch, const uint8 *src, int srcPitch, int w, int h);
template<typename pixelType> void mergeOverlayImpl(int x, int y, int w, int h);
virtual void mergeOverlay(int x, int y, int w, int h) {
- if (_useHiColorScreen)
- mergeOverlayImpl<uint16>(x, y, w, h);
- else
- mergeOverlayImpl<uint8>(x, y, w, h);
+ assert(_mergeOverlayProc);
+ (this->*_mergeOverlayProc)(x, y, w, h);
}
// overlay specific
@@ -848,6 +852,23 @@ protected:
template<bool noXor> static void wrapped_decodeFrameDelta(uint8 *dst, const uint8 *src);
template<bool noXor> static void wrapped_decodeFrameDeltaPage(uint8 *dst, const uint8 *src, const int pitch);
+ typedef void (Screen::*MergeOverlayFunc)(int, int, int, int);
+ MergeOverlayFunc _mergeOverlayProc;
+ static const MergeOverlayFunc _mergeOverlayProcs[];
+ typedef void (Screen::*Scale2xFunc)(uint8*, int, const uint8*, int, int, int);
+ Scale2xFunc _scale2xProc;
+ static const Scale2xFunc _scale2xProcs[];
+
+ template<typename T> int getPagePixelImpl(int pageNum, int x, int y);
+ template<typename T> void setPagePixelImpl(int pageNum, int x, int y, uint8 color);
+
+ typedef int (Screen::*GetPagePixelProc)(int, int, int);
+ GetPagePixelProc _getPagePixelProc;
+ static const GetPagePixelProc _getPagePixelProcs[];
+ typedef void (Screen::*SetPagePixelProc)(int, int, int, uint8);
+ SetPagePixelProc _setPagePixelProc;
+ static const SetPagePixelProc _setPagePixelProcs[];
+
uint8 *_pagePtrs[16];
const uint8 *_pagePtrsBuff;
uint8 *_sjisOverlayPtrs[SCREEN_OVLS_NUM];
@@ -859,7 +880,7 @@ protected:
Font *_fonts[FID_NUM];
uint8 _textColorsMap[16];
- uint16 _textColorsMap16bit[2];
+ uint32 _textColorsMapHiCol[2];
uint8 *_textRenderBuffer;
int _textRenderBufferSize;
@@ -874,7 +895,6 @@ protected:
bool _4bitPixelPacking;
bool _useHiResEGADithering;
Graphics::PixelFormat _outputPixelFormat;
- bool _useHiColorScreen;
bool _isAmiga;
bool _useAmigaExtraColors;
bool _isSegaCD;
@@ -888,10 +908,10 @@ protected:
Common::Array<Palette *> _palettes;
Palette *_internFadePalette;
- uint16 shadeRGBColor(uint16 col);
+ uint32 shadeRGBColor(uint32 col);
- uint16 *_hiColorNativePalettes;
- uint16 *_hiColorConversionPalette;
+ void *_hiColorNativePalettes;
+ void *_hiColorConversionPalette;
uint8 _hiColorShadingLevel;
uint8 *_animBlockPtr;
diff --git a/engines/kyra/graphics/screen_eob.cpp b/engines/kyra/graphics/screen_eob.cpp
index 61784b1e638..78824c9e5b4 100644
--- a/engines/kyra/graphics/screen_eob.cpp
+++ b/engines/kyra/graphics/screen_eob.cpp
@@ -77,7 +77,7 @@ struct eob2ChineseLZInStream {
};
}
-Screen_EoB::Screen_EoB(EoBCoreEngine *vm, OSystem *system) : Screen(vm, system, vm->gameFlags().lang == Common::Language::ZH_TWN ? _screenDimTableZH : _screenDimTableIntl, _screenDimTableCount), _cursorColorKey16Bit(0x8000) {
+Screen_EoB::Screen_EoB(EoBCoreEngine *vm, OSystem *system) : Screen(vm, system, vm->gameFlags().lang == Common::Language::ZH_TWN ? _screenDimTableZH : _screenDimTableIntl, _screenDimTableCount), _hiColorCursorColorKey(0x8000) {
_dsBackgroundFading = false;
_dsShapeFadingLevel = 0;
_dsBackgroundFadingXOffs = 0;
@@ -172,7 +172,7 @@ bool Screen_EoB::init() {
sega_setTextBuffer(0, 0);
}
- _useShapeShading = (_internalBytesPerPixel != 2 && !_isAmiga && !_isSegaCD && !_use16ColorMode && _renderMode != Common::kRenderCGA && _renderMode != Common::kRenderEGA) || _useHiResEGADithering;
+ _useShapeShading = (_internalBytesPerPixel == 1 && !_isAmiga && !_isSegaCD && !_use16ColorMode && _renderMode != Common::kRenderCGA && _renderMode != Common::kRenderEGA) || _useHiResEGADithering;
static const char *cpsExt[] = { "CPS", "EGA", "SHP", "BIN" };
int ci = 0;
@@ -229,19 +229,22 @@ void Screen_EoB::setMouseCursor(int x, int y, const byte *shape, const uint8 *ov
int mouseW = (shape[2] << 3);
int mouseH = (shape[3]);
- int colorKey = (_renderMode == Common::kRenderCGA) ? 0 : (_internalBytesPerPixel == 2 ? _cursorColorKey16Bit : _cursorColorKey);
+ int colorKey = (_renderMode == Common::kRenderCGA) ? 0 : (_internalBytesPerPixel > 1 ? _hiColorCursorColorKey : _cursorColorKey);
+ if (_internalBytesPerPixel == 4)
+ colorKey <<= 16;
int scaleFactor = _vm->gameFlags().useHiRes ? 2 : 1;
- int bpp = _useHiColorScreen ? 2 : 1;
-
- uint8 *cursor = new uint8[mouseW * scaleFactor * bpp * mouseH * scaleFactor];
-
- if (_internalBytesPerPixel == 2) {
- for (int s = mouseW * scaleFactor * bpp * mouseH * scaleFactor; s; s -= 2)
- *(uint16*)(cursor + s - 2) = colorKey;
+ uint8 *cursor = new uint8[mouseW * scaleFactor * _outputPixelFormat.bytesPerPixel * mouseH * scaleFactor];
+
+ if (_internalBytesPerPixel == 4) {
+ uint32 *c = reinterpret_cast<uint32*>(cursor);
+ Common::fill<uint32*, uint32>(c, c + mouseW * scaleFactor * mouseH * scaleFactor, colorKey);
+ } else if (_internalBytesPerPixel == 2) {
+ uint16 *c = reinterpret_cast<uint16*>(cursor);
+ Common::fill<uint16*, uint16>(c, c + mouseW * scaleFactor * mouseH * scaleFactor, colorKey);
} else {
// We don't use fillRect here to make sure that the color key 0xFF doesn't get converted into EGA color
- memset(cursor, colorKey, mouseW * scaleFactor * bpp * mouseH * scaleFactor);
+ memset(cursor, colorKey, mouseW * scaleFactor * _outputPixelFormat.bytesPerPixel * mouseH * scaleFactor);
}
copyBlockToPage(6, 0, 0, mouseW * scaleFactor, mouseH * scaleFactor, cursor);
@@ -250,10 +253,12 @@ void Screen_EoB::setMouseCursor(int x, int y, const byte *shape, const uint8 *ov
if (_useHiResEGADithering)
ditherRect(getCPagePtr(6), cursor, mouseW * scaleFactor, mouseW, mouseH, colorKey);
- else if (_useHiColorScreen)
- scale2x<uint16, uint32>(cursor, mouseW * scaleFactor, getCPagePtr(6), SCREEN_W, mouseW, mouseH);
+ else if (_outputPixelFormat.bytesPerPixel == 4)
+ scale2x<uint32, uint32>(cursor, mouseW * scaleFactor, getCPagePtr(6), SCREEN_W, mouseW, mouseH);
+ else if (_outputPixelFormat.bytesPerPixel == 2)
+ scale2x<uint16, uint16>(cursor, mouseW * scaleFactor, getCPagePtr(6), SCREEN_W, mouseW, mouseH);
else if (_vm->gameFlags().useHiRes)
- scale2x<uint8, uint16>(cursor, mouseW * scaleFactor, getCPagePtr(6), SCREEN_W, mouseW, mouseH);
+ scale2x<uint8, uint8>(cursor, mouseW * scaleFactor, getCPagePtr(6), SCREEN_W, mouseW, mouseH);
else
copyRegionToBuffer(6, 0, 0, mouseW, mouseH, cursor);
@@ -289,7 +294,12 @@ void Screen_EoB::setMouseCursor(int x, int y, const byte *shape, const uint8 *ov
// Convert color key to 16 bit after drawing the mouse cursor.
// The cursor has been converted to 16 bit in scale2x().
- colorKey = _hiColorConversionPalette ? _hiColorConversionPalette[colorKey] : colorKey;
+ if (_hiColorConversionPalette) {
+ if (_outputPixelFormat.bytesPerPixel == 4)
+ colorKey = reinterpret_cast<uint32 *>(_hiColorConversionPalette)[colorKey];
+ else
+ colorKey = reinterpret_cast<uint16 *>(_hiColorConversionPalette)[colorKey];
+ }
Graphics::PixelFormat pixelFormat = _system->getScreenFormat();
CursorMan.replaceCursor(cursor, mouseW * scaleFactor, mouseH * scaleFactor, x * scaleFactor, y * scaleFactor, colorKey, &pixelFormat);
@@ -311,7 +321,7 @@ void Screen_EoB::loadFileDataToPage(Common::SeekableReadStream *s, int pageNum,
void Screen_EoB::printShadedText(const char *string, int x, int y, int col1, int col2, int shadowCol, int pitch) {
if (_isSegaCD && shadowCol) {
printText(string, x + 1, y + 1, shadowCol, 0, pitch);
- } else if (!_isSegaCD && !_use16ColorMode && !_useHiColorScreen && (_fonts[_currentFont]->getType() == Font::kASCII || _fonts[_currentFont]->getType() == Font::kBIG5)) {
+ } else if (!_isSegaCD && !_use16ColorMode && _outputPixelFormat.bytesPerPixel == 1 && (_fonts[_currentFont]->getType() == Font::kASCII || _fonts[_currentFont]->getType() == Font::kBIG5)) {
printText(string, x - 1, y, shadowCol, col2);
printText(string, x, y + 1, shadowCol, 0);
printText(string, x - 1, y + 1, shadowCol, 0);
@@ -551,15 +561,22 @@ void Screen_EoB::convertPage(int srcPage, int dstPage, const uint8 *cgaMapping)
}
void Screen_EoB::setScreenPalette(const Palette &pal) {
- if (_internalBytesPerPixel == 2) {
+ if (_internalBytesPerPixel > 1) {
assert(_hiColorNativePalettes);
for (int i = 0; i < 4; i++)
- createHiColorFadeTable((const uint16 *)(pal.getData()), &_hiColorNativePalettes[i << 8], 0, i * 85);
+ createHiColorFadeTable(reinterpret_cast<const uint16*>(pal.getData()), reinterpret_cast<uint8*>(_hiColorNativePalettes) + (i << 8) * _internalBytesPerPixel, 0, i * 85);
} else if (_outputPixelFormat.bytesPerPixel > 1) {
assert(_hiColorConversionPalette);
_screenPalette->copy(pal);
- for (int i = 0; i < pal.getNumColors(); ++i)
- _hiColorConversionPalette[i] = _outputPixelFormat.RGBToColor(pal[i * 3] * 0xFF / 0x3F, pal[i * 3 + 1] * 0xFF / 0x3F, pal[i * 3 + 2] * 0xFF / 0x3F);
+ if (_outputPixelFormat.bytesPerPixel == 4) {
+ uint32 *p = reinterpret_cast<uint32*>(_hiColorConversionPalette);
+ for (int i = 0; i < pal.getNumColors(); ++i)
+ p[i] = _outputPixelFormat.RGBToColor(pal[i * 3] * 0xFF / 0x3F, pal[i * 3 + 1] * 0xFF / 0x3F, pal[i * 3 + 2] * 0xFF / 0x3F);
+ } else {
+ uint16 *p = reinterpret_cast<uint16*>(_hiColorConversionPalette);
+ for (int i = 0; i < pal.getNumColors(); ++i)
+ p[i] = _outputPixelFormat.RGBToColor(pal[i * 3] * 0xFF / 0x3F, pal[i * 3 + 1] * 0xFF / 0x3F, pal[i * 3 + 2] * 0xFF / 0x3F);
+ }
// The whole Surface has to be converted again after each palette change
_forceFullUpdate = true;
} else if (_useHiResEGADithering && pal.getNumColors() != 16) {
@@ -598,7 +615,7 @@ uint8 *Screen_EoB::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool enco
if (_use16ColorMode || (_renderMode == Common::kRenderEGA && !_useHiResEGADithering))
encode8bit = false;
- if (_internalBytesPerPixel == 2 && encode8bit) {
+ if (_internalBytesPerPixel > 1 && encode8bit) {
shapesize = h * (w << 3) + 4;
shp = new uint8[shapesize]();
uint8 *dst = shp;
@@ -860,7 +877,7 @@ void Screen_EoB::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y,
}
va_end(args);
- dst += (_dsX1 << (2 + _internalBytesPerPixel));
+ dst += ((_dsX1 << 3) * _internalBytesPerPixel);
int16 dX = x - (_dsX1 << 3);
int16 dY = y;
int16 dW = _dsX2 - _dsX1;
@@ -1228,7 +1245,7 @@ const uint8 *Screen_EoB::generateShapeOverlay(const uint8 *shp, const uint8 *fad
if (*shp != 2)
return 0;
- if (_internalBytesPerPixel == 2) {
+ if (_internalBytesPerPixel > 1) {
setFadeTable(fadingTable);
setShapeFadingLevel(1);
return 0;
@@ -1285,9 +1302,9 @@ void Screen_EoB::drawExplosion(int scale, int radius, int numElements, int stepS
int16 *ptr3 = (int16 *)&_dsTempPage[300];
int16 *ptr4 = (int16 *)&_dsTempPage[600];
int16 *ptr5 = (int16 *)&_dsTempPage[900];
- int16 *ptr6 = (int16 *)&_dsTempPage[1200];
- int16 *ptr7 = (int16 *)&_dsTempPage[1500];
- int16 *ptr8 = (int16 *)&_dsTempPage[1800];
+ int32 *ptr6 = (int32 *)&_dsTempPage[1200];
+ int16 *ptr7 = (int16 *)&_dsTempPage[1800];
+ int16 *ptr8 = (int16 *)&_dsTempPage[2100];
if (numElements > 150)
numElements = 150;
@@ -1315,8 +1332,8 @@ void Screen_EoB::drawExplosion(int scale, int radius, int numElements, int stepS
if (py > ymax)
py = ymax;
if (posWithinRect(px, py, rX1, rY1, rX2, rY2)) {
- if (_internalBytesPerPixel == 2)
- setPagePixel16bit(0, px, py, ptr6[i]);
+ if (_internalBytesPerPixel > 1)
+ setPagePixelHiCol(0, px, py, ptr6[i]);
else
setPagePixel(0, px, py, ptr6[i]);
}
@@ -1364,7 +1381,7 @@ void Screen_EoB::drawExplosion(int scale, int radius, int numElements, int stepS
}
assert((ptr8[i] >> 8) < colorTableSize);
- int pxVal2 = colorTable[ptr8[i] >> 8];
+ uint8 pxVal2 = colorTable[ptr8[i] >> 8];
if (pxVal2) {
l = 1;
if (pxVal1 == _gfxCol && posWithinRect(px, py, rX1, rY1, rX2, rY2))
@@ -1396,10 +1413,10 @@ void Screen_EoB::drawVortex(int numElements, int radius, int stepSize, int, int
int16 *yCoords = (int16 *)&_dsTempPage[300];
int16 *xMod = (int16 *)&_dsTempPage[600];
int16 *yMod = (int16 *)&_dsTempPage[900];
- int16 *pixBackup = (int16 *)&_dsTempPage[1200];
- int16 *colTableStep = (int16 *)&_dsTempPage[1500];
- int16 *colTableIndex = (int16 *)&_dsTempPage[1800];
- int16 *pixDelay = (int16 *)&_dsTempPage[2100];
+ int32 *pixBackup = (int32 *)&_dsTempPage[1200];
+ int16 *colTableStep = (int16 *)&_dsTempPage[1800];
+ int16 *colTableIndex = (int16 *)&_dsTempPage[2100];
+ int16 *pixDelay = (int16 *)&_dsTempPage[2400];
hideMouse();
int cp = _curPage;
@@ -1472,8 +1489,8 @@ void Screen_EoB::drawVortex(int numElements, int radius, int stepSize, int, int
for (int ii = numElements - 1; ii >= 0; ii--) {
int16 px = CLIP((xCoords[ii] >> 6) + cx, 0, SCREEN_W - 1);
int16 py = CLIP((yCoords[ii] >> 6) + cy, 0, SCREEN_H - 1);
- if (_internalBytesPerPixel == 2)
- setPagePixel16bit(0, px, py, pixBackup[ii]);
+ if (_internalBytesPerPixel > 1)
+ setPagePixelHiCol(0, px, py, pixBackup[ii]);
else
setPagePixel(0, px, py, pixBackup[ii]);
@@ -1519,7 +1536,7 @@ void Screen_EoB::drawVortex(int numElements, int radius, int stepSize, int, int
int16 px = CLIP((xCoords[ii] >> 6) + cx, 0, SCREEN_W - 1);
int16 py = CLIP((yCoords[ii] >> 6) + cy, 0, SCREEN_H - 1);
- uint8 tc1 = ((disorder >> 2) <= d) ? getPagePixel(2, px, py) : 0;
+ int tc1 = ((disorder >> 2) <= d) ? getPagePixel(2, px, py) : 0;
pixBackup[ii] = getPagePixel(0, px, py);
uint8 tblIndex = CLIP(colTableIndex[ii] >> 8, 0, colorTableSize - 1);
uint8 tc2 = colorTable[tblIndex];
@@ -1617,8 +1634,8 @@ int Screen_EoB::getRectSize(int w, int h) {
void Screen_EoB::setFadeTable(const uint8 *table) {
_dsShapeFadingTable = table;
- if (_internalBytesPerPixel == 2)
- memcpy(&_hiColorNativePalettes[0x100], table, 512);
+ if (_internalBytesPerPixel > 1)
+ memcpy(reinterpret_cast<uint8 *>(_hiColorNativePalettes) + (_internalBytesPerPixel << 8), table, _internalBytesPerPixel << 8);
}
void Screen_EoB::createColorFadeTable(const uint8 *palData, uint8 *dst, uint8 rootColor, uint8 weight) {
@@ -1664,7 +1681,7 @@ void Screen_EoB::createColorFadeTable(const uint8 *palData, uint8 *dst, uint8 ro
}
}
-void Screen_EoB::createHiColorFadeTable(const uint16 *palData, uint16 *dst, uint8 rootColor, uint8 weight) {
+void Screen_EoB::createHiColorFadeTable(const uint16 *palData, void *dst, uint8 rootColor, uint8 weight) {
const Graphics::PixelFormat originalFormat(2, 5, 5, 5, 0, 5, 10, 0, 0);
uint8 r = 0, b = 0, g = 0;
originalFormat.colorToRGB(palData[rootColor], r, g, b);
@@ -1673,8 +1690,15 @@ void Screen_EoB::createHiColorFadeTable(const uint16 *palData, uint16 *dst, uint
int root_g = g << 1;
int root_b = b << 1;
+ uint32 *d32 = reinterpret_cast<uint32*>(dst);
+ uint16 *d16 = reinterpret_cast<uint16*>(dst);
+
originalFormat.colorToRGB(palData[0], r, g, b);
- *dst++ = _outputPixelFormat.RGBToColor(r, g, b);
+
+ if (_outputPixelFormat.bytesPerPixel == 2)
+ *d16++ = _outputPixelFormat.RGBToColor(r, g, b);
+ else
+ *d32++ = _outputPixelFormat.RGBToColor(r, g, b);
for (int i = 1; i < 256; ++i) {
originalFormat.colorToRGB(palData[i], r, g, b);
@@ -1717,18 +1741,25 @@ void Screen_EoB::createHiColorFadeTable(const uint16 *palData, uint16 *dst, uint
g = green >> 1;
b = blue >> 1;
- *dst++ = _outputPixelFormat.RGBToColor(r, g, b);
+ if (_outputPixelFormat.bytesPerPixel == 2)
+ *d16++ = _outputPixelFormat.RGBToColor(r, g, b);
+ else
+ *d32++ = _outputPixelFormat.RGBToColor(r, g, b);
}
}
-const uint16 *Screen_EoB::getCGADitheringTable(int index) {
+const uint16 *Screen_EoB::getCGADitheringTable(int index) const {
return !(index & ~1) ? _cgaDitheringTables[index] : 0;
}
-const uint8 *Screen_EoB::getEGADitheringTable() {
+const uint8 *Screen_EoB::getEGADitheringTable() const {
return _egaDitheringTable;
}
+int Screen_EoB::bytesPerPixel() const {
+ return _outputPixelFormat.bytesPerPixel;
+}
+
bool Screen_EoB::loadFont(FontId fontId, const char *filename) {
Font *&fnt = _fonts[fontId];
int temp = 0;
@@ -1830,8 +1861,11 @@ void Screen_EoB::ditherRect(const uint8 *src, uint8 *dst, int dstPitch, int srcW
}
void Screen_EoB::drawShapeSetPixel(uint8 *dst, uint8 col) {
- if (_internalBytesPerPixel == 2) {
- *(uint16*)dst = _hiColorNativePalettes[(_dsShapeFadingLevel << 8) + col];
+ if (_internalBytesPerPixel == 4) {
+ *reinterpret_cast<uint32*>(dst) = reinterpret_cast<const uint32*>(_hiColorNativePalettes)[(_dsShapeFadingLevel << 8) + col];
+ return;
+ } else if (_internalBytesPerPixel == 2) {
+ *reinterpret_cast<uint16*>(dst) = reinterpret_cast<const uint16*>(_hiColorNativePalettes)[(_dsShapeFadingLevel << 8) + col];
return;
} else if (_useShapeShading) {
if (_dsBackgroundFading) {
@@ -1907,15 +1941,18 @@ bool Screen_EoB::posWithinRect(int posX, int posY, int x1, int y1, int x2, int y
return true;
}
-void Screen_EoB::setPagePixel16bit(int pageNum, int x, int y, uint16 color) {
+void Screen_EoB::setPagePixelHiCol(int pageNum, int x, int y, int color) {
assert(pageNum < SCREEN_PAGE_NUM);
assert(x >= 0 && x < SCREEN_W && y >= 0 && y < SCREEN_H);
- assert(_internalBytesPerPixel == 2);
+ assert(_internalBytesPerPixel > 1);
if (pageNum == 0 || pageNum == 1)
addDirtyRect(x, y, 1, 1);
- ((uint16*)_pagePtrs[pageNum])[y * SCREEN_W + x] = color;
+ if (_internalBytesPerPixel == 4)
+ reinterpret_cast<uint32*>(_pagePtrs[pageNum])[y * SCREEN_W + x] = color;
+ else
+ reinterpret_cast<uint16*>(_pagePtrs[pageNum])[y * SCREEN_W + x] = color;
}
void Screen_EoB::generateEGADitheringTable(const Palette &pal) {
@@ -2015,7 +2052,7 @@ const uint8 Screen_EoB::_egaMatchTable[] = {
uint16 *OldDOSFont::_cgaDitheringTable = 0;
int OldDOSFont::_numRef = 0;
-OldDOSFont::OldDOSFont(Common::RenderMode mode, uint8 shadowColor, bool remapCharacters) : _renderMode(mode), _shadowColor(shadowColor), _remapCharacters(remapCharacters), _numGlyphsMax(128), _useOverlay(false), _scaleV(1), _colorMap8bit(0), _colorMap16bit(0) {
+OldDOSFont::OldDOSFont(Common::RenderMode mode, uint8 shadowColor, bool remapCharacters) : _renderMode(mode), _shadowColor(shadowColor), _remapCharacters(remapCharacters), _numGlyphsMax(128), _useOverlay(false), _scaleV(1), _colorMap8bit(nullptr), _hiColorMap(nullptr) {
_data = 0;
_width = _height = _numGlyphs = 0;
_bitmapOffsets = 0;
@@ -2108,8 +2145,8 @@ void OldDOSFont::setColorMap(const uint8 *src) {
}
void OldDOSFont::drawChar(uint16 c, byte *dst, int pitch, int bpp) const {
- uint16 color1 = _colorMap8bit[1];
- uint16 color2 = _colorMap8bit[0];
+ uint32 color1 = _colorMap8bit[1];
+ uint32 color2 = _colorMap8bit[0];
if (_style == kStyleLeftShadow) {
byte *dst2 = dst;
@@ -2121,9 +2158,9 @@ void OldDOSFont::drawChar(uint16 c, byte *dst, int pitch, int bpp) const {
}
}
- if (bpp == 2) {
- color1 = _colorMap16bit[1];
- color2 = _colorMap16bit[0];
+ if (bpp > 1) {
+ color1 = _hiColorMap[1];
+ color2 = _hiColorMap[0];
}
for (int i = 0; i < _scaleV; ++i) {
@@ -2208,14 +2245,19 @@ void OldDOSFont::drawCharIntern(uint16 c, byte *dst, int pitch, int bpp, int col
}
if (s & i) {
- if (bpp == 2)
- *(uint16*)dst = col1;
+ if (bpp == 4)
+ *reinterpret_cast<uint32*>(dst) = col1;
+ else if (bpp == 2)
+ *reinterpret_cast<uint16*>(dst) = col1;
else if (col1)
*dst = col1;
} else {
- if (bpp == 2) {
- if (col2 != 0xFFFF)
- *(uint16*)dst = col2;
+ if (bpp == 4) {
+ if (col2)
+ *reinterpret_cast<uint32*>(dst) = col2;
+ } else if (bpp == 2) {
+ if (col2)
+ *reinterpret_cast<uint16*>(dst) = col2;
} else if (col2) {
*dst = col2;
}
diff --git a/engines/kyra/graphics/screen_eob.h b/engines/kyra/graphics/screen_eob.h
index 149fa3b50c1..5bd95090a7e 100644
--- a/engines/kyra/graphics/screen_eob.h
+++ b/engines/kyra/graphics/screen_eob.h
@@ -103,10 +103,11 @@ public:
void setFadeTable(const uint8 *table);
void createColorFadeTable(const uint8 *palData, uint8 *dst, uint8 rootColor, uint8 weight);
- void createHiColorFadeTable(const uint16 *palData, uint16 *dst, uint8 rootColor, uint8 weight);
+ void createHiColorFadeTable(const uint16 *palData, void *dst, uint8 rootColor, uint8 weight);
- const uint16 *getCGADitheringTable(int index);
- const uint8 *getEGADitheringTable();
+ const uint16 *getCGADitheringTable(int index) const;
+ const uint8 *getEGADitheringTable() const;
+ int bytesPerPixel() const;
bool loadFont(FontId fontId, const char *filename) override;
@@ -170,7 +171,7 @@ private:
void scaleShapeProcessLine4Bit(uint8 *&dst, const uint8 *&src);
bool posWithinRect(int posX, int posY, int x1, int y1, int x2, int y2);
- void setPagePixel16bit(int pageNum, int x, int y, uint16 color);
+ void setPagePixelHiCol(int pageNum, int x, int y, int color);
void generateEGADitheringTable(const Palette &pal);
void generateCGADitheringTables(const uint8 *mappingData);
@@ -178,7 +179,7 @@ private:
int _dsDiv, _dsRem, _dsScaleTrans;
uint8 *_cgaScaleTable;
int16 _gfxX, _gfxY;
- uint16 _gfxCol;
+ int _gfxCol;
const uint8 *_gfxMaxY;
int16 _dsX1, _dsX2, _dsY1, _dsY2;
@@ -199,7 +200,7 @@ private:
Common::String _cpsFilePattern;
- const uint16 _cursorColorKey16Bit;
+ const uint16 _hiColorCursorColorKey;
static const uint8 _egaMatchTable[];
static const ScreenDim _screenDimTableIntl[];
@@ -273,7 +274,7 @@ public:
bool usesOverlay() const override { return _useOverlay; }
int getCharWidth(uint16 c) const override;
void setColorMap(const uint8 *src) override;
- void set16bitColorMap(const uint16 *src) override { _colorMap16bit = src; }
+ void setHiColorMap(const uint32 *src) override { _hiColorMap = src; }
void setStyles(int styles) override { _style = styles; }
void drawChar(uint16 c, byte *dst, int pitch, int bpp) const override;
@@ -296,7 +297,7 @@ private:
void drawCharIntern(uint16 c, byte *dst, int pitch, int bpp, int col1, int col2) const;
virtual uint16 convert(uint16 c) const;
Common::RenderMode _renderMode;
- const uint16 *_colorMap16bit;
+ const uint32 *_hiColorMap;
bool _remapCharacters;
static uint16 *_cgaDitheringTable;
diff --git a/engines/kyra/graphics/screen_eob_towns.cpp b/engines/kyra/graphics/screen_eob_towns.cpp
index 56cd06e00df..bdf1d142e41 100644
--- a/engines/kyra/graphics/screen_eob_towns.cpp
+++ b/engines/kyra/graphics/screen_eob_towns.cpp
@@ -64,11 +64,19 @@ void Screen_EoB::decodeSHP(const uint8 *data, int dstPage) {
void Screen_EoB::convertToHiColor(int page) {
if (!_hiColorNativePalettes)
return;
- uint16 *dst = (uint16 *)getPagePtr(page);
- memcpy(_hiColorConvertBuffer, dst, SCREEN_H * SCREEN_W);
+ memcpy(_hiColorConvertBuffer, getCPagePtr(page), SCREEN_H * SCREEN_W);
const uint8 *src = _hiColorConvertBuffer;
- for (int s = SCREEN_H * SCREEN_W; s; --s)
- *dst++ = _hiColorNativePalettes[*src++];
+ if (_internalBytesPerPixel == 4) {
+ uint32 *dst = reinterpret_cast<uint32*>(getPagePtr(page));
+ const uint32 *p = reinterpret_cast<const uint32*>(_hiColorNativePalettes);
+ for (int s = SCREEN_H * SCREEN_W; s; --s)
+ *dst++ = p[*src++];
+ } else {
+ uint16 *dst = reinterpret_cast<uint16*>(getPagePtr(page));
+ const uint16 *p = reinterpret_cast<const uint16*>(_hiColorNativePalettes);
+ for (int s = SCREEN_H * SCREEN_W; s; --s)
+ *dst++ = p[*src++];
+ }
}
void Screen_EoB::shadeRect(int x1, int y1, int x2, int y2, int shadingLevel) {
@@ -81,15 +89,26 @@ void Screen_EoB::shadeRect(int x1, int y1, int x2, int y2, int shadingLevel) {
if (_curPage == 0 || _curPage == 1)
addDirtyRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
- uint16 *dst = (uint16*)(getPagePtr(_curPage) + y1 * SCREEN_W * _internalBytesPerPixel + x1 * _internalBytesPerPixel);
-
- for (; y1 < y2; ++y1) {
- uint16 *ptr = dst;
- for (int i = 0; i < x2 - x1; i++) {
- *ptr = shadeRGBColor(*ptr);
- ptr++;
+ if (_internalBytesPerPixel == 4) {
+ uint32 *dst = &(reinterpret_cast<uint32*>(getPagePtr(_curPage))[y1 * SCREEN_W + x1]);
+ for (; y1 < y2; ++y1) {
+ uint32 *ptr = dst;
+ for (int i = 0; i < x2 - x1; i++) {
+ *ptr = shadeRGBColor(*ptr);
+ ptr++;
+ }
+ dst += SCREEN_W;
+ }
+ } else {
+ uint16 *dst = &(reinterpret_cast<uint16 *>(getPagePtr(_curPage))[y1 * SCREEN_W + x1]);
+ for (; y1 < y2; ++y1) {
+ uint16 *ptr = dst;
+ for (int i = 0; i < x2 - x1; i++) {
+ *ptr = shadeRGBColor(*ptr);
+ ptr++;
+ }
+ dst += SCREEN_W;
}
- dst += SCREEN_W;
}
_hiColorShadingLevel = l;
More information about the Scummvm-git-logs
mailing list