aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/graphics
diff options
context:
space:
mode:
authorColin Snover2016-07-02 20:56:29 -0500
committerColin Snover2016-07-10 09:36:10 -0500
commitb6dbc79021be137367372faa3b53081e7a332efd (patch)
tree5ef02afbaed1bb762cd4c55ad7f3739eeaee45bb /engines/sci/graphics
parent4d91b458e53ebda8726055d338da12c05a7879ea (diff)
downloadscummvm-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.cpp24
-rw-r--r--engines/sci/graphics/celobj32.h12
-rw-r--r--engines/sci/graphics/screen_item32.cpp16
-rw-r--r--engines/sci/graphics/screen_item32.h10
-rw-r--r--engines/sci/graphics/video32.cpp50
-rw-r--r--engines/sci/graphics/video32.h9
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