diff options
Diffstat (limited to 'engines/gob')
-rw-r--r-- | engines/gob/coktelvideo.cpp | 8 | ||||
-rw-r--r-- | engines/gob/coktelvideo.h | 7 | ||||
-rw-r--r-- | engines/gob/indeo3.cpp | 274 | ||||
-rw-r--r-- | engines/gob/indeo3.h | 85 | ||||
-rw-r--r-- | engines/gob/inter_v6.cpp | 3 | ||||
-rw-r--r-- | engines/gob/video.cpp | 3 | ||||
-rw-r--r-- | engines/gob/video.h | 8 | ||||
-rw-r--r-- | engines/gob/video_v6.cpp | 9 |
8 files changed, 36 insertions, 361 deletions
diff --git a/engines/gob/coktelvideo.cpp b/engines/gob/coktelvideo.cpp index 8ea13946d7..cab1072d94 100644 --- a/engines/gob/coktelvideo.cpp +++ b/engines/gob/coktelvideo.cpp @@ -25,6 +25,7 @@ #include "common/endian.h" #include "common/system.h" +#include "graphics/dither.h" #include "gob/coktelvideo.h" #include "gob/indeo3.h" @@ -863,7 +864,7 @@ const uint16 Vmd::_tableADPCM[128] = { 0x0F00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000 }; -Vmd::Vmd(PaletteLUT *palLUT) : _palLUT(palLUT) { +Vmd::Vmd(Graphics::PaletteLUT *palLUT) : _palLUT(palLUT) { clear(false); } @@ -1540,7 +1541,8 @@ void Vmd::blit16(byte *dest, uint16 *src, int16 width, int16 height) { assert(_palLUT); - SierraLight *dither = new SierraLight(width, height, _palLUT); + Graphics::SierraLight *dither = + new Graphics::SierraLight(width, height, _palLUT); for (int i = 0; i < height; i++) { byte *d = dest; @@ -1552,7 +1554,7 @@ void Vmd::blit16(byte *dest, uint16 *src, int16 width, int16 height) { byte b = ((*s & 0x001F) >> 0) << 1; byte dY, dU, dV; - PaletteLUT::RGB2YUV(r << 2, g << 2, b << 2, dY, dU, dV); + Graphics::PaletteLUT::RGB2YUV(r << 2, g << 2, b << 2, dY, dU, dV); byte p = dither->dither(dY, dU, dV, j); diff --git a/engines/gob/coktelvideo.h b/engines/gob/coktelvideo.h index 9d7dc93b3f..7ed90ed073 100644 --- a/engines/gob/coktelvideo.h +++ b/engines/gob/coktelvideo.h @@ -28,12 +28,13 @@ #include "common/stream.h" #include "common/array.h" +#include "graphics/dither.h" #include "sound/mixer.h" #include "sound/audiostream.h" namespace Gob { -class PaletteLUT; +class Graphics::PaletteLUT; class Indeo3; /** Common interface for handling Coktel Vision videos and derivated formats. */ @@ -303,7 +304,7 @@ protected: class Vmd : public Imd { public: - Vmd(PaletteLUT *palLUT = 0); + Vmd(Graphics::PaletteLUT *palLUT = 0); ~Vmd(); bool getAnchor(int16 frame, uint16 partType, @@ -373,7 +374,7 @@ protected: byte _scaleExternalX; byte *_vidMemBuffer; - PaletteLUT *_palLUT; + Graphics::PaletteLUT *_palLUT; Indeo3 *_codecIndeo3; void clear(bool del = true); diff --git a/engines/gob/indeo3.cpp b/engines/gob/indeo3.cpp index 6182983fe3..951bc2d3e8 100644 --- a/engines/gob/indeo3.cpp +++ b/engines/gob/indeo3.cpp @@ -33,282 +33,14 @@ #include "common/endian.h" #include "common/frac.h" #include "common/file.h" +#include "graphics/dither.h" #include "gob/indeo3.h" #include "gob/indeo3data.h" namespace Gob { -#define SQR(x) ((x) * (x)) -PaletteLUT::PaletteLUT(byte depth, PaletteFormat format) { - assert((depth > 1) && (depth < 9)); - - // For adjusting depth - _depth1 = depth; - _depth2 = 2 * _depth1; - _shift = 8 - _depth1; - - // The table's dimensions - _dim1 = (1 << _depth1); - _dim2 = _dim1 * _dim1; - _dim3 = _dim1 * _dim1 * _dim1; - - _format = format; - - // What's already built - _got = _dim1; - _gots = new byte[_dim1]; - - // The lookup table - _lut = new byte[_dim3]; - - memset(_lutPal, 0, 768); - memset(_realPal, 0, 768); - memset(_gots, 1, _dim1); -} - -void PaletteLUT::setPalette(const byte *palette, PaletteFormat format, byte depth) { - assert((depth > 1) && (depth < 9)); - - warning("Building new palette LUT"); - - int shift = 8 - depth; - - // Checking for the table's and the palette's pixel format - if ((_format == kPaletteRGB) && (format == kPaletteYUV)) { - byte *newPal = _realPal; - const byte *oldPal = palette; - for (int i = 0; i < 256; i++, newPal += 3, oldPal += 3) - YUV2RGB(oldPal[0] << shift, oldPal[1] << shift, oldPal[2] << shift, - newPal[0], newPal[1], newPal[2]); - } else if ((_format == kPaletteYUV) && (format == kPaletteRGB)) { - byte *newPal = _realPal; - const byte *oldPal = palette; - for (int i = 0; i < 256; i++, newPal += 3, oldPal += 3) - RGB2YUV(oldPal[0] << shift, oldPal[1] << shift, oldPal[2] << shift, - newPal[0], newPal[1], newPal[2]); - } else - memcpy(_realPal, palette, 768); - - // Using the specified depth for the lookup - byte *newPal = _lutPal, *oldPal = _realPal; - for (int i = 0; i < 768; i++) - *newPal++ = (*oldPal++) >> _shift; - - // Everything has to be rebuilt - _got = 0; - memset(_gots, 0, _dim1); -} - -PaletteLUT::~PaletteLUT() { - delete[] _lut; - delete[] _gots; -} - -void PaletteLUT::buildNext() { - if (_got >= _dim1) - return; - - build(_got++); -} - -// Building one "slice" -void PaletteLUT::build(int d1) { - // First dimension - byte *lut = _lut + d1 * _dim2; - - // Second dimension - for (uint32 j = 0; j < _dim1; j++) { - // Third dimension - for (uint32 k = 0; k < _dim1; k++) { - const byte *p = _lutPal; - uint32 d = 0xFFFFFFFF; - byte n = 0; - - // Going over every palette entry, searching for the closest - for (int c = 0; c < 256; c++, p += 3) { - uint32 di = SQR(d1 - p[0]) + SQR(j - p[1]) + SQR(k - p[2]); - if (di < d) { - d = di; - n = c; - if (d == 0) - break; - } - } - - *lut++ = n; - } - } - - // Got this slice now - _gots[d1] = 1; -} - -inline int PaletteLUT::getIndex(byte c1, byte c2, byte c3) const { - return ((c1 >> _shift) << _depth2) | ((c2 >> _shift) << _depth1) | (c3 >> _shift); -} - -void PaletteLUT::getEntry(byte index, byte &c1, byte &c2, byte &c3) const { - c1 = _realPal[index * 3 + 0]; - c2 = _realPal[index * 3 + 1]; - c3 = _realPal[index * 3 + 2]; -} - -byte PaletteLUT::findNearest(byte c1, byte c2, byte c3) { - return _lut[getIndex(c1, c2, c3)]; -} - -byte PaletteLUT::findNearest(byte c1, byte c2, byte c3, byte &nC1, byte &nC2, byte &nC3) { - // If we don't have the required "slice" yet, build it - if (!_gots[c1 >> _shift]) - build(c1 >> _shift); - - int palIndex = _lut[getIndex(c1, c2, c3)]; - int i = palIndex * 3; - - nC1 = _realPal[i + 0]; - nC2 = _realPal[i + 1]; - nC3 = _realPal[i + 2]; - - return palIndex; -} - -bool PaletteLUT::save(Common::WriteStream &stream) { - // The table has to be completely built before we can save - while (_got < _dim1) - buildNext(); - - stream.writeByte(_depth1); - if (stream.write(_realPal, 768) != 768) - return false; - if (stream.write(_lutPal, 768) != 768) - return false; - if (stream.write(_lut, _dim3) != _dim3) - return false; - if (!stream.flush()) - return false; - - if (stream.err()) - return false; - - return true; -} - -bool PaletteLUT::load(Common::SeekableReadStream &stream) { - // _realPal + _lutPal + _lut + _depth1 - int32 needSize = 768 + 768 + _dim3 + 1; - - if ((stream.size() - stream.pos()) < needSize) - return false; - - byte depth1 = stream.readByte(); - - if (depth1 != _depth1) - return false; - - if (stream.read(_realPal, 768) != 768) - return false; - if (stream.read(_lutPal, 768) != 768) - return false; - if (stream.read(_lut, _dim3) != _dim3) - return false; - - _got = _dim1; - memset(_gots, 1, _dim1); - - return true; -} - -SierraLight::SierraLight(int16 width, int16 height, PaletteLUT *palLUT) { - assert((width > 0) && (height > 0)); - - _width = width; - _height = height; - _palLUT = palLUT; - - // Big buffer for the errors of the current and next line - _errorBuf = new int32[3 * (2 * (_width + 2*1))]; - memset(_errorBuf, 0, (3 * (2 * (_width + 2*1))) * sizeof(int32)); - - _curLine = 0; - _errors[0] = _errorBuf + 3; - _errors[1] = _errors[0] + 3 * (_width + 2*1); -} - -SierraLight::~SierraLight() { - delete[] _errorBuf; -} - -void SierraLight::newFrame() { - _curLine = 0; - memset(_errors[0], 0, 3 * _width * sizeof(int32)); - memset(_errors[1], 0, 3 * _width * sizeof(int32)); -} - -void SierraLight::nextLine() { - // Clear the finished line, it will become the last line in the buffer - memset(_errors[_curLine], 0, 3 * _width * sizeof(int32)); - - _curLine = (_curLine + 1) % 2; -} - -byte SierraLight::dither(byte c1, byte c2, byte c3, uint32 x) { - assert(_palLUT); - - int32 eC1, eC2, eC3; - - getErrors(x, eC1, eC2, eC3); - - // Apply error on values - c1 = CLIP<int>(c1 + eC1, 0, 255); - c2 = CLIP<int>(c2 + eC2, 0, 255); - c3 = CLIP<int>(c3 + eC3, 0, 255); - - // Find color - byte newC1, newC2, newC3; - byte newPixel = _palLUT->findNearest(c1, c2, c3, newC1, newC2, newC3); - - // Calculate new error - eC1 = c1 - newC1; - eC2 = c2 - newC2; - eC3 = c3 - newC3; - - // Add them - addErrors(x, eC1, eC2, eC3); - - return newPixel; -} - -inline void SierraLight::getErrors(uint32 x, int32 &eC1, int32 &eC2, int32 &eC3) { - int32 *errCur = _errors[_curLine]; - - x *= 3; - eC1 = errCur[x + 0] >> 2; - eC2 = errCur[x + 1] >> 2; - eC3 = errCur[x + 2] >> 2; -} - -inline void SierraLight::addErrors(uint32 x, int32 eC1, int32 eC2, int32 eC3) { - int32 *errCur = _errors[_curLine]; - int32 *errNext = _errors[(_curLine + 1) % 2]; - - // Indices for current error - int x0 = 3 * (x + 1); - int x1 = 3 * (x + 0); - int x2 = 3 * (x - 1); - - errCur [x0 + 0] += eC1 << 1; - errCur [x0 + 1] += eC2 << 1; - errCur [x0 + 2] += eC3 << 1; - errNext[x1 + 0] += eC1; - errNext[x1 + 1] += eC2; - errNext[x1 + 2] += eC3; - errNext[x2 + 0] += eC1; - errNext[x2 + 1] += eC2; - errNext[x2 + 2] += eC3; -} - -Indeo3::Indeo3(int16 width, int16 height, PaletteLUT *palLUT) { +Indeo3::Indeo3(int16 width, int16 height, Graphics::PaletteLUT *palLUT) { assert((width > 0) && (height > 0)); _width = width; @@ -363,7 +95,7 @@ void Indeo3::setDither(DitherAlgorithm dither) { switch(dither) { case kDitherSierraLight: - _ditherSL = new SierraLight(_width, _height, _palLUT); + _ditherSL = new Graphics::SierraLight(_width, _height, _palLUT); break; default: diff --git a/engines/gob/indeo3.h b/engines/gob/indeo3.h index 28eba336e5..f30b47806a 100644 --- a/engines/gob/indeo3.h +++ b/engines/gob/indeo3.h @@ -35,81 +35,12 @@ #include "common/stream.h" -namespace Gob { - -class PaletteLUT { -public: - enum PaletteFormat { - kPaletteRGB, - kPaletteYUV - }; - - inline static void YUV2RGB(byte y, byte u, byte v, byte &r, byte &g, byte &b) { - r = CLIP<int>(y + ((1357 * (v - 128)) >> 10), 0, 255); - g = CLIP<int>(y - (( 691 * (v - 128)) >> 10) - ((333 * (u - 128)) >> 10), 0, 255); - b = CLIP<int>(y + ((1715 * (u - 128)) >> 10), 0, 255); - } - inline static void RGB2YUV(byte r, byte g, byte b, byte &y, byte &u, byte &v) { - y = CLIP<int>( ((r * 306) >> 10) + ((g * 601) >> 10) + ((b * 117) >> 10) , 0, 255); - u = CLIP<int>(-((r * 172) >> 10) - ((g * 340) >> 10) + ((b * 512) >> 10) + 128, 0, 255); - v = CLIP<int>( ((r * 512) >> 10) - ((g * 429) >> 10) - ((b * 83) >> 10) + 128, 0, 255); - } - - PaletteLUT(byte depth, PaletteFormat format); - ~PaletteLUT(); - - void setPalette(const byte *palette, PaletteFormat format, byte depth); - - void buildNext(); - - void getEntry(byte index, byte &c1, byte &c2, byte &c3) const; - byte findNearest(byte c1, byte c2, byte c3); - byte findNearest(byte c1, byte c2, byte c3, byte &nC1, byte &nC2, byte &nC3); - - bool save(Common::WriteStream &stream); - bool load(Common::SeekableReadStream &stream); - -private: - byte _depth1, _depth2; - byte _shift; - - uint32 _dim1, _dim2, _dim3; +namespace Graphics { + class PaletteLUT; + class SierraLight; +} - PaletteFormat _format; - byte _lutPal[768]; - byte _realPal[768]; - - uint32 _got; - byte *_gots; - byte *_lut; - - void build(int d1); - inline int getIndex(byte c1, byte c2, byte c3) const; - inline void plotEntry(int x, int y, int z, byte e, byte *filled, int &free); -}; - -// The Sierra-2-4A ("Filter Light") dithering algorithm -class SierraLight { -public: - SierraLight(int16 width, int16 height, PaletteLUT *palLUT); - ~SierraLight(); - - void newFrame(); - void nextLine(); - byte dither(byte c1, byte c2, byte c3, uint32 x); - -protected: - int16 _width, _height; - - PaletteLUT *_palLUT; - - int32 *_errorBuf; - int32 *_errors[2]; - int _curLine; - - inline void getErrors(uint32 x, int32 &eC1, int32 &eC2, int32 &eC3); - inline void addErrors(uint32 x, int32 eC1, int32 eC2, int32 eC3); -}; +namespace Gob { class Indeo3 { public: @@ -118,7 +49,7 @@ public: kDitherSierraLight }; - Indeo3(int16 width, int16 height, PaletteLUT *palLUT); + Indeo3(int16 width, int16 height, Graphics::PaletteLUT *palLUT); ~Indeo3(); static bool isIndeo3(byte *data, uint32 dataLen); @@ -154,10 +85,10 @@ private: byte *_ModPred; uint16 *_corrector_type; - PaletteLUT *_palLUT; + Graphics::PaletteLUT *_palLUT; DitherAlgorithm _dither; - SierraLight *_ditherSL; + Graphics::SierraLight *_ditherSL; struct BlitState { uint32 curX, curY; diff --git a/engines/gob/inter_v6.cpp b/engines/gob/inter_v6.cpp index 8e16337827..65022ab539 100644 --- a/engines/gob/inter_v6.cpp +++ b/engines/gob/inter_v6.cpp @@ -25,6 +25,7 @@ #include "common/endian.h" #include "common/file.h" +#include "graphics/dither.h" #include "gob/gob.h" #include "gob/inter.h" @@ -926,7 +927,7 @@ bool Inter_v6::o6_palLoad(OpFuncParams ¶ms) { if (_gotFirstPalette) _vm->_video->_palLUT->setPalette((const byte *) _vm->_global->_pPaletteDesc->vgaPal, - PaletteLUT::kPaletteRGB, 6); + Graphics::PaletteLUT::kPaletteRGB, 6); _gotFirstPalette = true; return false; diff --git a/engines/gob/video.cpp b/engines/gob/video.cpp index fd256096ce..3c26ea4ee7 100644 --- a/engines/gob/video.cpp +++ b/engines/gob/video.cpp @@ -27,6 +27,7 @@ #include "graphics/cursorman.h" #include "graphics/fontman.h" #include "graphics/surface.h" +#include "graphics/dither.h" #include "gob/gob.h" #include "gob/video.h" @@ -109,7 +110,7 @@ Video::Video(GobEngine *vm) : _vm(vm) { _dirtyAll = false; - _palLUT = new PaletteLUT(6, PaletteLUT::kPaletteYUV); + _palLUT = new Graphics::PaletteLUT(6, Graphics::PaletteLUT::kPaletteYUV); } char Video::initDriver(int16 vidMode) { diff --git a/engines/gob/video.h b/engines/gob/video.h index 42eafae5de..50653bd26c 100644 --- a/engines/gob/video.h +++ b/engines/gob/video.h @@ -31,9 +31,13 @@ #include "gob/gob.h" +namespace Graphics { + class PaletteLUT; +} + namespace Gob { -class PaletteLUT; +class Graphics::PaletteLUT; // Some Surfaces are simultaneous in Draw::spritesArray and discrete // variables, so it's a references counting class that cleans @@ -122,7 +126,7 @@ public: int16 _screenDeltaX; int16 _screenDeltaY; - PaletteLUT *_palLUT; + Graphics::PaletteLUT *_palLUT; void freeDriver(); void initPrimary(int16 mode); diff --git a/engines/gob/video_v6.cpp b/engines/gob/video_v6.cpp index 6746715de9..a3ba8cb340 100644 --- a/engines/gob/video_v6.cpp +++ b/engines/gob/video_v6.cpp @@ -25,6 +25,7 @@ #include "common/endian.h" #include "common/savefile.h" +#include "graphics/dither.h" #include "gob/gob.h" #include "gob/video.h" @@ -104,7 +105,7 @@ bool Video_v6::savePalLUT(const char *target) { void Video_v6::buildPalLUT() { char text[30]; - _palLUT->setPalette(_ditherPalette, PaletteLUT::kPaletteYUV, 8); + _palLUT->setPalette(_ditherPalette, Graphics::PaletteLUT::kPaletteYUV, 8); for (int i = 0; (i < 64) && !_vm->shouldQuit(); i++) { sprintf(text, "Building palette table: %02d/63", i); @@ -175,7 +176,8 @@ void Video_v6::shadeRect(SurfaceDesc *dest, _palLUT->getEntry(color, sY, sU, sV); - SierraLight *dither = new SierraLight(width, height, _palLUT); + Graphics::SierraLight *dither = + new Graphics::SierraLight(width, height, _palLUT); for (int i = 0; i < height; i++) { byte *d = vidMem; @@ -253,7 +255,8 @@ void Video_v6::drawYUV(SurfaceDesc *destDesc, int16 x, int16 y, if ((y + height - 1) >= destDesc->getHeight()) height = destDesc->getHeight() - y; - SierraLight *dither = new SierraLight(width, height, _palLUT); + Graphics::SierraLight *dither = + new Graphics::SierraLight(width, height, _palLUT); for (int i = 0; i < height; i++) { byte *dest = vidMem; |