NEVERHOOD: Fix subtitle outline color

This commit is contained in:
Vladimir Serbinenko 2023-01-10 21:17:37 +01:00
parent de56f3f6be
commit 3d3a02483b
4 changed files with 29 additions and 16 deletions

View File

@ -46,7 +46,7 @@ void SmackerSurface::draw() {
subDrawRect.y = _drawRect.y + _drawRect.height - 17;
subDrawRect.width = _drawRect.width;
subDrawRect.height = 16;
_vm->_screen->drawSurface2(bottom, subDrawRect, _clipRect, true, ++_version, nullptr, _subtitles->kSubtitleAlpha);
_vm->_screen->drawSurface2(bottom, subDrawRect, _clipRect, true, ++_version, nullptr, _subtitles->getSubtitleAlpha());
}
const Graphics::Surface *top = _subtitles->getTopSubs();
if (top) {
@ -55,7 +55,7 @@ void SmackerSurface::draw() {
subDrawRect.y = _drawRect.y + 1;
subDrawRect.width = _drawRect.width;
subDrawRect.height = 16;
_vm->_screen->drawSurface2(top, subDrawRect, _clipRect, true, ++_version, nullptr, _subtitles->kSubtitleAlpha);
_vm->_screen->drawSurface2(top, subDrawRect, _clipRect, true, ++_version, nullptr, _subtitles->getSubtitleAlpha());
}
}
}
@ -103,7 +103,7 @@ void SmackerDoubleSurface::draw() {
subDrawRect.y = _drawRect.y + _drawRect.height * 2 - 34;
subDrawRect.width = _drawRect.width;
subDrawRect.height = 16;
_vm->_screen->drawDoubleSurface2Alpha(bottom, subDrawRect, _subtitles->kSubtitleAlpha);
_vm->_screen->drawDoubleSurface2Alpha(bottom, subDrawRect, _subtitles->getSubtitleAlpha());
}
const Graphics::Surface *top = _subtitles->getTopSubs();
if (top) {
@ -112,7 +112,7 @@ void SmackerDoubleSurface::draw() {
subDrawRect.y = _drawRect.y + 2;
subDrawRect.width = _drawRect.width;
subDrawRect.height = 16;
_vm->_screen->drawDoubleSurface2Alpha(top, subDrawRect, _subtitles->kSubtitleAlpha);
_vm->_screen->drawDoubleSurface2Alpha(top, subDrawRect, _subtitles->getSubtitleAlpha());
}
}
}

View File

@ -418,7 +418,7 @@ void AnimatedSprite::AnimatedSpriteSubtitles::draw() {
_backref->_subtitles->renderFrame(_backref->_currFrameIndex, subCenterX - getDrawRect().x);
const Graphics::Surface *bottom = _backref->_subtitles->getBottomSubs();
if (bottom) {
_vm->_screen->drawSurface2(bottom, _drawRect, _clipRect, true, ++_version, nullptr, _backref->_subtitles->kSubtitleAlpha);
_vm->_screen->drawSurface2(bottom, _drawRect, _clipRect, true, ++_version, nullptr, _backref->_subtitles->getSubtitleAlpha());
}
if (_backref->_subtitles->getTopSubs())
warning("Top subs are unsupported");

View File

@ -19,14 +19,18 @@
*
*/
#include "graphics/palette.h"
#include "neverhood/resource.h"
#include "neverhood/resourceman.h"
#include "neverhood/screen.h"
#include "neverhood/subtitles.h"
namespace Neverhood {
namespace {
void drawSubtitles(Graphics::Surface *surf, const Common::String &str, const SubtitleGlyph *subfont, int x0) {
void drawSubtitles(Graphics::Surface *surf, const Common::String &str, const SubtitleGlyph *subfont,
int x0, byte outlineColor, byte alphaColor) {
if (!surf || surf->h < SubtitlePlayer::kSubtitleCharHeight || !subfont)
return;
@ -35,8 +39,8 @@ void drawSubtitles(Graphics::Surface *surf, const Common::String &str, const Sub
int lastx = MIN<int>(str.size() * SubtitlePlayer::kSubtitleCharWidth + x0 + 1, surf->w);
for (int16 yc = 0; yc < SubtitlePlayer::kSubtitleCharHeight; yc++) {
byte *dest = dest0 + yc * surf->pitch;
memset(dest, SubtitlePlayer::kSubtitleAlpha, x0 + 2);
memset(dest + lastx, SubtitlePlayer::kSubtitleAlpha, surf->w - lastx);
memset(dest, alphaColor, x0 + 2);
memset(dest + lastx, alphaColor, surf->w - lastx);
}
for (int i = 0; i < (int)str.size() && i * SubtitlePlayer::kSubtitleCharWidth < surf->w; i++) {
@ -46,19 +50,19 @@ void drawSubtitles(Graphics::Surface *surf, const Common::String &str, const Sub
byte *row = dest;
// Outline of leftmost pixel
if (*row == SubtitlePlayer::kSubtitleAlpha && (subfont[c].bitmap[yc] & 0x80))
*row = 0x00;
if (*row == alphaColor && (subfont[c].bitmap[yc] & 0x80))
*row = outlineColor;
row++;
for (int16 xc = 0; xc < SubtitlePlayer::kSubtitleCharWidth; xc++, row++) {
if ((subfont[c].bitmap[yc] << xc) & 0x80)
*row = 0xff;
else if ((subfont[c].outline[yc] << xc) & 0x80)
*row = 0x00;
*row = outlineColor;
else if (xc != 0)
*row = SubtitlePlayer::kSubtitleAlpha;
*row = alphaColor;
}
// Outline of rightmost pixel
*row = (subfont[c].bitmap[yc] & 0x1) ? 0x00 : SubtitlePlayer::kSubtitleAlpha;
*row = (subfont[c].bitmap[yc] & 0x1) ? outlineColor : alphaColor;
dest += surf->pitch;
}
}
@ -104,6 +108,14 @@ void SubtitlePlayer::renderFrame(uint frameNumber, int centerX) {
_haveBottomSubs = false;
_haveTopSubs = false;
Graphics::PaletteLookup palLookup(_vm->_screen->getPaletteData(), 256);
byte outlineColor = palLookup.findBestColor(0, 0, 0);
_alphaColor = 0x77;
if (_alphaColor == outlineColor)
_alphaColor++;
// TODO: Optimize this
for (uint i = 0; i < _subtitles.size(); i++) {
if (frameNumber < _subtitles[i].fromFrame || frameNumber > _subtitles[i].toFrame)
@ -115,10 +127,10 @@ void SubtitlePlayer::renderFrame(uint frameNumber, int centerX) {
int startX = MAX(MIN(centerX - width / 2, screenWidth - width), 0);
if (_subtitles[i].isTop) {
drawSubtitles(&_topSubs, curStr, subFont, startX);
drawSubtitles(&_topSubs, curStr, subFont, startX, outlineColor, _alphaColor);
_haveTopSubs = true;
} else {
drawSubtitles(&_bottomSubs, curStr, subFont, startX);
drawSubtitles(&_bottomSubs, curStr, subFont, startX, outlineColor, _alphaColor);
_haveBottomSubs = true;
}
}

View File

@ -43,8 +43,8 @@ public:
const Graphics::Surface *getBottomSubs() const { return _haveBottomSubs ? &_bottomSubs : nullptr; }
const Graphics::Surface *getTopSubs() const { return _haveTopSubs ? &_topSubs : nullptr; }
bool isValid() const { return _isValid && !_subtitles.empty(); }
byte getSubtitleAlpha() const { return _alphaColor; }
static const byte kSubtitleAlpha = 0x77;
static const int kSubtitleCharHeight = 16;
static const int kSubtitleCharWidth = 8;
@ -57,6 +57,7 @@ private:
bool _haveBottomSubs;
bool _haveTopSubs;
int64 _currentFrame;
byte _alphaColor;
};
} // End of namespace Neverhood