From 93eb6ec64aa2ee2e276c7c2ddd57a269b539af28 Mon Sep 17 00:00:00 2001 From: athrxx Date: Sat, 17 Nov 2012 21:46:12 +0100 Subject: KYRA: (EOB) - implement simplified EGA dithering for EOB II --- engines/kyra/screen.cpp | 6 ++--- engines/kyra/screen.h | 2 +- engines/kyra/screen_eob.cpp | 54 ++++++++++++++++++++++++++++++++++++++++----- engines/kyra/screen_eob.h | 4 ++++ 4 files changed, 56 insertions(+), 10 deletions(-) (limited to 'engines') diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp index c400b330b9..6c77870210 100644 --- a/engines/kyra/screen.cpp +++ b/engines/kyra/screen.cpp @@ -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; diff --git a/engines/kyra/screen.h b/engines/kyra/screen.h index 159d415ea6..bd94e2611f 100644 --- a/engines/kyra/screen.h +++ b/engines/kyra/screen.h @@ -547,7 +547,7 @@ public: protected: uint8 *getPagePtr(int pageNum); - void updateDirtyRects(); + virtual void updateDirtyRects(); void updateDirtyRectsAmiga(); void updateDirtyRectsOvl(); diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp index eed9647069..8f18c5aa8b 100644 --- a/engines/kyra/screen_eob.cpp +++ b/engines/kyra/screen_eob.cpp @@ -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::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]) { diff --git a/engines/kyra/screen_eob.h b/engines/kyra/screen_eob.h index 2e3cbde452..9de6a58a4a 100644 --- a/engines/kyra/screen_eob.h +++ b/engines/kyra/screen_eob.h @@ -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[]; -- cgit v1.2.3