KYRA: (EOB) - implement simplified EGA dithering for EOB II

This commit is contained in:
athrxx 2012-11-17 21:46:12 +01:00
parent c8a73d30cf
commit 93eb6ec64a
4 changed files with 56 additions and 10 deletions

View File

@ -1074,7 +1074,7 @@ void Screen::fillRect(int x1, int y1, int x2, int y2, uint8 color, int pageNum,
color |= (color << 4);
} else if (_renderMode == Common::kRenderCGA) {
color &= 0x03;
} else if (_renderMode == Common::kRenderEGA) {
} else if (_renderMode == Common::kRenderEGA && !_useHiResEGADithering) {
color &= 0x0F;
}
@ -1151,7 +1151,7 @@ void Screen::drawLine(bool vertical, int x, int y, int length, int color) {
color |= (color << 4);
} else if (_renderMode == Common::kRenderCGA) {
color &= 0x03;
} else if (_renderMode == Common::kRenderEGA) {
} else if (_renderMode == Common::kRenderEGA && !_useHiResEGADithering) {
color &= 0x0F;
}
@ -2862,8 +2862,6 @@ void Screen::setShapePages(int page1, int page2, int minY, int maxY) {
void Screen::setMouseCursor(int x, int y, const byte *shape) {
if (!shape)
return;
// if mouseDisabled
// return _mouseShape
if (_vm->gameFlags().useAltShapeHeader)
shape += 2;

View File

@ -547,7 +547,7 @@ public:
protected:
uint8 *getPagePtr(int pageNum);
void updateDirtyRects();
virtual void updateDirtyRects();
void updateDirtyRectsAmiga();
void updateDirtyRectsOvl();

View File

@ -52,6 +52,7 @@ Screen_EoB::Screen_EoB(EoBCoreEngine *vm, OSystem *system) : Screen(vm, system,
_cgaScaleTable = 0;
_gfxMaxY = 0;
_egaDitheringTable = 0;
_egaDitheringTempPage = 0;
_cgaMappingDefault = 0;
_cgaDitheringTables[0] = _cgaDitheringTables[1] = 0;
_useHiResEGADithering = false;
@ -62,6 +63,7 @@ Screen_EoB::~Screen_EoB() {
delete[] _dsTempPage;
delete[] _cgaScaleTable;
delete[] _egaDitheringTable;
delete[] _egaDitheringTempPage;
delete[] _cgaDitheringTables[0];
delete[] _cgaDitheringTables[1];
}
@ -90,6 +92,7 @@ bool Screen_EoB::init() {
if (_vm->gameFlags().useHiRes && _renderMode == Common::kRenderEGA) {
_useHiResEGADithering = true;
_egaDitheringTable = new uint8[256];
_egaDitheringTempPage = new uint8[SCREEN_W * 2 * SCREEN_H * 2];
for (int i = 0; i < 256; i++)
_egaDitheringTable[i] = i & 0x0f;
} else if (_renderMode == Common::kRenderCGA) {
@ -137,14 +140,14 @@ void Screen_EoB::setMouseCursor(int x, int y, const byte *shape, const uint8 *ov
// We use memset and copyBlockToPage instead of fillRect to make sure that the
// color key 0xFF doesn't get converted into EGA color
memset(cursor, colorKey, mouseW * scaleFactor * mouseH * scaleFactor);
copyBlockToPage(6, 0, 0, mouseW, mouseH, cursor);
copyBlockToPage(6, 0, 0, mouseW * scaleFactor, mouseH * scaleFactor, cursor);
drawShape(6, shape, 0, 0, 0, 2, ovl);
CursorMan.showMouse(false);
if (_useHiResEGADithering) {
}
copyRegionToBuffer(6, 0, 0, mouseW, mouseH, cursor);
if (_useHiResEGADithering)
ditherRect(getCPagePtr(6), cursor, mouseW * scaleFactor, mouseW, mouseH, colorKey);
else
copyRegionToBuffer(6, 0, 0, mouseW, mouseH, cursor);
// Mouse cursor post processing for CGA mode. Unlike the original (which uses drawShape for the mouse cursor)
// the cursor manager cannot know whether a pixel value of 0 is supposed to be black or transparent. Thus, we
@ -1229,6 +1232,47 @@ const uint8 *Screen_EoB::getEGADitheringTable() {
return _egaDitheringTable;
}
void Screen_EoB::updateDirtyRects() {
if (!_useHiResEGADithering) {
Screen::updateDirtyRects();
return;
}
if (_forceFullUpdate) {
ditherRect(getCPagePtr(0), _egaDitheringTempPage, SCREEN_W * 2, SCREEN_W, SCREEN_H);
_system->copyRectToScreen(_egaDitheringTempPage, SCREEN_W * 2, 0, 0, SCREEN_W * 2, SCREEN_H * 2);
} else {
const byte *page0 = getCPagePtr(0);
Common::List<Common::Rect>::iterator it;
for (it = _dirtyRects.begin(); it != _dirtyRects.end(); ++it) {
ditherRect(page0 + it->top * SCREEN_W + it->left, _egaDitheringTempPage, SCREEN_W * 2, it->width(), it->height());
_system->copyRectToScreen(_egaDitheringTempPage, SCREEN_W * 2, it->left * 2, it->top * 2, it->width() * 2, it->height() * 2);
}
}
_forceFullUpdate = false;
_dirtyRects.clear();
}
void Screen_EoB::ditherRect(const uint8 *src, uint8 *dst, int dstPitch, int srcW, int srcH, int colorKey) {
while (srcH--) {
uint8 *dst2 = dst + dstPitch;
for (int i = 0; i < srcW; i++) {
int in = *src++;
if (in != colorKey) {
in = _egaDitheringTable[in];
*dst++ = *dst2++ = in >> 4;
*dst++ = *dst2++ = in & 0x0f;
} else {
dst[0] = dst[1] = dst2[0] = dst2[1] = colorKey;
dst += 2;
dst2 += 2;
}
}
src += (SCREEN_W - srcW);
dst += ((dstPitch - srcW) * 2);
}
}
void Screen_EoB::drawShapeSetPixel(uint8 *dst, uint8 col) {
if ((_renderMode != Common::kRenderCGA && _renderMode != Common::kRenderEGA) || _useHiResEGADithering) {
if (_shapeFadeMode[0]) {

View File

@ -82,6 +82,9 @@ public:
const uint8 *getEGADitheringTable();
private:
void updateDirtyRects();
void ditherRect(const uint8 *src, uint8 *dst, int dstPitch, int srcW, int srcH, int colorKey = -1);
void drawShapeSetPixel(uint8 *dst, uint8 col);
void scaleShapeProcessLine2Bit(uint8 *&shpDst, const uint8 *&shpSrc, uint32 transOffsetDst, uint32 transOffsetSrc);
void scaleShapeProcessLine4Bit(uint8 *&dst, const uint8 *&src);
@ -109,6 +112,7 @@ private:
const uint8 *_cgaMappingDefault;
uint8 *_egaDitheringTable;
uint8 *_egaDitheringTempPage;
static const uint8 _egaMatchTable[];
static const ScreenDim _screenDimTable[];