diff options
author | Colin Snover | 2016-07-02 20:56:29 -0500 |
---|---|---|
committer | Colin Snover | 2016-07-10 09:36:10 -0500 |
commit | b6dbc79021be137367372faa3b53081e7a332efd (patch) | |
tree | 5ef02afbaed1bb762cd4c55ad7f3739eeaee45bb /engines/sci/graphics | |
parent | 4d91b458e53ebda8726055d338da12c05a7879ea (diff) | |
download | scummvm-rg350-b6dbc79021be137367372faa3b53081e7a332efd.tar.gz scummvm-rg350-b6dbc79021be137367372faa3b53081e7a332efd.tar.bz2 scummvm-rg350-b6dbc79021be137367372faa3b53081e7a332efd.zip |
SCI32: Add support for blacklined video
Ow. My eyeballs.
Diffstat (limited to 'engines/sci/graphics')
-rw-r--r-- | engines/sci/graphics/celobj32.cpp | 24 | ||||
-rw-r--r-- | engines/sci/graphics/celobj32.h | 12 | ||||
-rw-r--r-- | engines/sci/graphics/screen_item32.cpp | 16 | ||||
-rw-r--r-- | engines/sci/graphics/screen_item32.h | 10 | ||||
-rw-r--r-- | engines/sci/graphics/video32.cpp | 50 | ||||
-rw-r--r-- | engines/sci/graphics/video32.h | 9 |
6 files changed, 90 insertions, 31 deletions
diff --git a/engines/sci/graphics/celobj32.cpp b/engines/sci/graphics/celobj32.cpp index f8cd5fd171..da41879efe 100644 --- a/engines/sci/graphics/celobj32.cpp +++ b/engines/sci/graphics/celobj32.cpp @@ -83,9 +83,11 @@ const CelScalerTable *CelScaler::getScalerTable(const Ratio &scaleX, const Ratio #pragma mark - #pragma mark CelObj +bool CelObj::_drawBlackLines = false; void CelObj::init() { CelObj::deinit(); + _drawBlackLines = false; _nextCacheId = 1; _scaler = new CelScaler(); _cache = new CelCache; @@ -407,6 +409,7 @@ void CelObj::draw(Buffer &target, const ScreenItem &screenItem, const Common::Re const Common::Point &scaledPosition = screenItem._scaledPosition; const Ratio &scaleX = screenItem._ratioX; const Ratio &scaleY = screenItem._ratioY; + _drawBlackLines = screenItem._drawBlackLines; if (_remap) { // NOTE: In the original code this check was `g_Remap_numActiveRemaps && _remap`, @@ -488,6 +491,8 @@ void CelObj::draw(Buffer &target, const ScreenItem &screenItem, const Common::Re } } } + + _drawBlackLines = false; } void CelObj::draw(Buffer &target, const ScreenItem &screenItem, const Common::Rect &targetRect, bool mirrorX) { @@ -627,7 +632,7 @@ void CelObj::putCopyInCache(const int cacheIndex) const { #pragma mark - #pragma mark CelObj - Drawing -template<typename MAPPER, typename SCALER> +template<typename MAPPER, typename SCALER, bool DRAW_BLACK_LINES> struct RENDERER { MAPPER &_mapper; SCALER &_scaler; @@ -645,6 +650,12 @@ struct RENDERER { const int16 targetWidth = targetRect.width(); const int16 targetHeight = targetRect.height(); for (int16 y = 0; y < targetHeight; ++y) { + if (DRAW_BLACK_LINES && (y % 2) == 0) { + memset(targetPixel, 0, targetWidth); + targetPixel += targetWidth + skipStride; + continue; + } + _scaler.setTarget(targetRect.left, targetRect.top + y); for (int16 x = 0; x < targetWidth; ++x) { @@ -661,7 +672,7 @@ void CelObj::render(Buffer &target, const Common::Rect &targetRect, const Common MAPPER mapper; SCALER scaler(*this, targetRect.left - scaledPosition.x + targetRect.width(), scaledPosition); - RENDERER<MAPPER, SCALER> renderer(mapper, scaler, _transparentColor); + RENDERER<MAPPER, SCALER, false> renderer(mapper, scaler, _transparentColor); renderer.draw(target, targetRect, scaledPosition); } @@ -670,8 +681,13 @@ void CelObj::render(Buffer &target, const Common::Rect &targetRect, const Common MAPPER mapper; SCALER scaler(*this, targetRect, scaledPosition, scaleX, scaleY); - RENDERER<MAPPER, SCALER> renderer(mapper, scaler, _transparentColor); - renderer.draw(target, targetRect, scaledPosition); + if (_drawBlackLines) { + RENDERER<MAPPER, SCALER, true> renderer(mapper, scaler, _transparentColor); + renderer.draw(target, targetRect, scaledPosition); + } else { + RENDERER<MAPPER, SCALER, false> renderer(mapper, scaler, _transparentColor); + renderer.draw(target, targetRect, scaledPosition); + } } void dummyFill(Buffer &target, const Common::Rect &targetRect) { diff --git a/engines/sci/graphics/celobj32.h b/engines/sci/graphics/celobj32.h index e405592b5f..eb6ce3a3c9 100644 --- a/engines/sci/graphics/celobj32.h +++ b/engines/sci/graphics/celobj32.h @@ -228,6 +228,18 @@ class ScreenItem; class CelObj { protected: /** + * When true, every second line of the cel will be + * rendered as a black line. + * + * @see ScreenItem::_drawBlackLines + * @note Using a static member because otherwise this + * would otherwise need to be copied down through + * several calls. (SSCI did similar, using a global + * variable.) + */ + static bool _drawBlackLines; + + /** * When true, this cel will be horizontally mirrored * when it is drawn. This is an internal flag that is * set by draw methods based on the combination of the diff --git a/engines/sci/graphics/screen_item32.cpp b/engines/sci/graphics/screen_item32.cpp index ebaf132890..7383dc222e 100644 --- a/engines/sci/graphics/screen_item32.cpp +++ b/engines/sci/graphics/screen_item32.cpp @@ -42,7 +42,8 @@ _pictureId(-1), _created(g_sci->_gfxFrameout->getScreenCount()), _updated(0), _deleted(0), -_mirrorX(false) { +_mirrorX(false), +_drawBlackLines(false) { SegManager *segMan = g_sci->getEngineState()->_segMan; setFromObject(segMan, object, true, true); @@ -62,7 +63,8 @@ _pictureId(-1), _created(g_sci->_gfxFrameout->getScreenCount()), _updated(0), _deleted(0), -_mirrorX(false) {} +_mirrorX(false), +_drawBlackLines(false) {} ScreenItem::ScreenItem(const reg_t plane, const CelInfo32 &celInfo, const Common::Rect &rect) : _plane(plane), @@ -77,7 +79,8 @@ _pictureId(-1), _created(g_sci->_gfxFrameout->getScreenCount()), _updated(0), _deleted(0), -_mirrorX(false) { +_mirrorX(false), +_drawBlackLines(false) { if (celInfo.type == kCelTypeColor) { _insetRect = rect; } @@ -97,7 +100,8 @@ _pictureId(-1), _created(g_sci->_gfxFrameout->getScreenCount()), _updated(0), _deleted(0), -_mirrorX(false) {} +_mirrorX(false), +_drawBlackLines(false) {} ScreenItem::ScreenItem(const ScreenItem &other) : _plane(other._plane), @@ -108,7 +112,8 @@ _celObj(nullptr), _object(other._object), _mirrorX(other._mirrorX), _scaledPosition(other._scaledPosition), -_screenRect(other._screenRect) { +_screenRect(other._screenRect), +_drawBlackLines(other._drawBlackLines) { if (other._useInsetRect) { _insetRect = other._insetRect; } @@ -134,6 +139,7 @@ void ScreenItem::operator=(const ScreenItem &other) { } _scale = other._scale; _scaledPosition = other._scaledPosition; + _drawBlackLines = other._drawBlackLines; } ScreenItem::~ScreenItem() { diff --git a/engines/sci/graphics/screen_item32.h b/engines/sci/graphics/screen_item32.h index 56f858dc74..3d9d5ef3d7 100644 --- a/engines/sci/graphics/screen_item32.h +++ b/engines/sci/graphics/screen_item32.h @@ -180,7 +180,7 @@ public: * plane is a pic type and its picture resource ID has * changed */ - int _created, _updated, _deleted; // ? + int _created, _updated, _deleted; /** * For screen items that represent picture cels, this @@ -214,6 +214,14 @@ public: Common::Rect _screenRect; /** + * Whether or not the screen item should be drawn + * with black lines drawn every second line. This is + * used when pixel doubling videos to improve apparent + * sharpness at the cost of your eyesight. + */ + bool _drawBlackLines; + + /** * Initialises static Plane members. */ static void init(); diff --git a/engines/sci/graphics/video32.cpp b/engines/sci/graphics/video32.cpp index 0f0116e41c..86ff82a8d0 100644 --- a/engines/sci/graphics/video32.cpp +++ b/engines/sci/graphics/video32.cpp @@ -21,6 +21,7 @@ */ #include "audio/mixer.h" +#include "common/config-manager.h" #include "sci/console.h" #include "sci/event.h" #include "sci/graphics/cursor.h" @@ -85,7 +86,7 @@ void VMDPlayer::init(const int16 x, const int16 y, const PlayFlags flags, const _leaveScreenBlack = flags & kPlayFlagLeaveScreenBlack; _leaveLastFrame = flags & kPlayFlagLeaveLastFrame; _doublePixels = flags & kPlayFlagDoublePixels; - _blackLines = flags & kPlayFlagBlackLines; + _blackLines = ConfMan.getBool("enable_black_lined_video") && (flags & kPlayFlagBlackLines); _boostPercent = 100 + (flags & kPlayFlagBoost ? boostPercent : 0); _blackPalette = flags & kPlayFlagBlackPalette; _stretchVertical = flags & kPlayFlagStretchVertical; @@ -209,6 +210,10 @@ VMDPlayer::EventFlags VMDPlayer::playUntilEvent(const EventFlags flags) { } } + if (_blackLines) { + _screenItem->_drawBlackLines = true; + } + // NOTE: There was code for positioning the screen item using insetRect // here, but none of the game scripts seem to use this functionality. @@ -267,11 +272,29 @@ VMDPlayer::EventFlags VMDPlayer::playUntilEvent(const EventFlags flags) { return stopFlag; } -void VMDPlayer::renderFrame() { - // TODO: This is kind of different from the original implementation - // which has access to dirty rects from the decoder; we probably do - // not need to care to limit output this way +void VMDPlayer::fillPalette(Palette &palette) const { + const byte *vmdPalette = _decoder->getPalette() + _startColor * 3; + for (uint16 i = _startColor; i <= _endColor; ++i) { + int16 r = *vmdPalette++; + int16 g = *vmdPalette++; + int16 b = *vmdPalette++; + + if (_boostPercent != 100 && i >= _boostStartColor && i <= _boostEndColor) { + r = CLIP<int16>(r * _boostPercent / 100, 0, 255); + g = CLIP<int16>(g * _boostPercent / 100, 0, 255); + b = CLIP<int16>(b * _boostPercent / 100, 0, 255); + } + palette.colors[i].r = r; + palette.colors[i].g = g; + palette.colors[i].b = b; + palette.colors[i].used = true; + } +} + +void VMDPlayer::renderFrame() const { + // This writes directly to the CelObjMem we already created, + // so no need to take its return value _decoder->decodeNextFrame(); // NOTE: Normally this would write a hunk palette at the end of the @@ -287,13 +310,7 @@ void VMDPlayer::renderFrame() { palette.colors[i].used = true; } } else { - const byte *vmdPalette = _decoder->getPalette() + _startColor * 3; - for (uint16 i = _startColor; i <= _endColor; ++i) { - palette.colors[i].r = *vmdPalette++; - palette.colors[i].g = *vmdPalette++; - palette.colors[i].b = *vmdPalette++; - palette.colors[i].used = true; - } + fillPalette(palette); } g_sci->_gfxPalette32->submit(palette); @@ -301,14 +318,7 @@ void VMDPlayer::renderFrame() { g_sci->_gfxFrameout->frameOut(true); if (_blackPalette) { - const byte *vmdPalette = _decoder->getPalette() + _startColor * 3; - for (uint16 i = _startColor; i <= _endColor; ++i) { - palette.colors[i].r = *vmdPalette++; - palette.colors[i].g = *vmdPalette++; - palette.colors[i].b = *vmdPalette++; - palette.colors[i].used = true; - } - + fillPalette(palette); g_sci->_gfxPalette32->submit(palette); g_sci->_gfxPalette32->updateForFrame(); g_sci->_gfxPalette32->updateHardware(); diff --git a/engines/sci/graphics/video32.h b/engines/sci/graphics/video32.h index 481b222f6f..d51316bfbd 100644 --- a/engines/sci/graphics/video32.h +++ b/engines/sci/graphics/video32.h @@ -120,7 +120,14 @@ private: /** * Renders a frame of video to the output bitmap. */ - void renderFrame(); + void renderFrame() const; + + /** + * Fills the given palette with RGB values from + * the VMD palette, applying brightness boost if + * it is enabled. + */ + void fillPalette(Palette &palette) const; /** * Whether or not a VMD stream has been opened with |