From 4f7e5da4dad61f11553e5f51f00d33506b9ef342 Mon Sep 17 00:00:00 2001 From: Walter van Niftrik Date: Fri, 4 Mar 2016 16:12:11 +0100 Subject: ADL: Clean up Display class --- engines/adl/display.cpp | 364 ++++++++++++++++++++++++------------------------ engines/adl/display.h | 46 +++--- 2 files changed, 204 insertions(+), 206 deletions(-) (limited to 'engines/adl') diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp index 90ca1b60db..55166f4e30 100644 --- a/engines/adl/display.cpp +++ b/engines/adl/display.cpp @@ -20,23 +20,40 @@ * */ -#include "adl/display.h" #include "common/stream.h" #include "common/rect.h" -#include "graphics/surface.h" #include "common/system.h" #include "common/str.h" -#include "common/events.h" -#include "common/rect.h" -#include "common/array.h" #include "common/config-manager.h" -#include "engines/engine.h" -#include "engines/util.h" + +#include "graphics/surface.h" #include "graphics/palette.h" #include "graphics/thumbnail.h" +#include "engines/util.h" + +#include "adl/display.h" + namespace Adl { +#define DISPLAY_PITCH (DISPLAY_WIDTH / 7) + +#define COLOR_PALETTE_SIZE 6 +const byte colorPalette[COLOR_PALETTE_SIZE * 3] = { + 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, + 0xc7, 0x34, 0xff, + 0x38, 0xcb, 0x00, + 0x0d, 0xa1, 0xff, + 0xf2, 0x5e, 0x00 +}; + +#define MONO_PALETTE_SIZE 2 +const byte monoPalette[MONO_PALETTE_SIZE * 3] = { + 0x00, 0x00, 0x00, + 0x00, 0xc0, 0x01 +}; + static const byte font[64][5] = { { 0x7c, 0x82, 0xba, 0xb2, 0x9c }, { 0xf8, 0x24, 0x22, 0x24, 0xf8 }, // @A { 0xfe, 0x92, 0x92, 0x92, 0x6c }, { 0x7c, 0x82, 0x82, 0x82, 0x44 }, // BC @@ -73,8 +90,8 @@ static const byte font[64][5] = { }; Display::Display() : - _cursorPos(0), _mode(kModeText), + _cursorPos(0), _showCursor(false) { initGraphics(560, 384, true); @@ -83,20 +100,23 @@ Display::Display() : _scanlines = ConfMan.getBool("scanlines"); if (_monochrome) - setMonoPalette(); + g_system->getPaletteManager()->setPalette(monoPalette, 0, MONO_PALETTE_SIZE); else - setColorPalette(); + g_system->getPaletteManager()->setPalette(colorPalette, 0, COLOR_PALETTE_SIZE); enableScanlines(_scanlines); - _frameBuf = new byte[kWidth * kHeight / 7]; + _frameBuf = new byte[DISPLAY_PITCH * DISPLAY_HEIGHT]; _frameBufSurface = new Graphics::Surface; - _frameBufSurface->create(kWidth * 2, kHeight * 2, Graphics::PixelFormat::createFormatCLUT8()); + // We need 2x scaling to properly render the half-pixel shift + // of the second palette + _frameBufSurface->create(DISPLAY_WIDTH * 2, DISPLAY_HEIGHT * 2, Graphics::PixelFormat::createFormatCLUT8()); _textBuf = new byte[kTextBufSize]; - memset(_textBuf, ' ' | 0x80, kTextBufSize); + memset(_textBuf, APPLECHAR(' '), kTextBufSize); _textBufSurface = new Graphics::Surface; - _textBufSurface->create(kWidth * 2, kHeight * 2, Graphics::PixelFormat::createFormatCLUT8()); + // For ease of copying, also use 2x scaling here + _textBufSurface->create(DISPLAY_WIDTH * 2, DISPLAY_HEIGHT * 2, Graphics::PixelFormat::createFormatCLUT8()); createFont(); } @@ -114,6 +134,17 @@ Display::~Display() { delete _font; } +void Display::updateScreen() { + if (_mode == kModeText) { + g_system->copyRectToScreen(_textBufSurface->getPixels(), _textBufSurface->pitch, 0, 0, _textBufSurface->w, _textBufSurface->h); + } else if (_mode == kModeHires) { + g_system->copyRectToScreen(_frameBufSurface->getPixels(), _frameBufSurface->pitch, 0, 0, _frameBufSurface->w, _frameBufSurface->h); + } else { + g_system->copyRectToScreen(_frameBufSurface->getPixels(), _frameBufSurface->pitch, 0, 0, _frameBufSurface->w, _frameBufSurface->h - 4 * 8 * 2); + g_system->copyRectToScreen(_textBufSurface->getBasePtr(0, _textBufSurface->h - 4 * 8 * 2), _textBufSurface->pitch, 0, _textBufSurface->h - 4 * 8 * 2, _textBufSurface->w, 4 * 8 * 2); + } +} + bool Display::saveThumbnail(Common::WriteStream &out) { if (_scanlines) { enableScanlines(false); @@ -130,56 +161,153 @@ bool Display::saveThumbnail(Common::WriteStream &out) { return retval; } -void Display::enableScanlines(bool enable) { - byte pal[6 * 3] = { }; +void Display::loadFrameBuffer(Common::ReadStream &stream) { + for (uint j = 0; j < 8; ++j) { + for (uint i = 0; i < 8; ++i) { + byte *dst = _frameBuf + DISPLAY_PITCH * (i * 8 + j); + stream.read(dst, DISPLAY_PITCH); + dst += DISPLAY_PITCH * 64; + stream.read(dst, DISPLAY_PITCH); + dst += DISPLAY_PITCH * 64; + stream.read(dst, DISPLAY_PITCH); + stream.readUint32LE(); + stream.readUint32LE(); + dst += DISPLAY_PITCH * 64; + } + } +} - if (enable) - g_system->getPaletteManager()->setPalette(pal, 6, 6); - else { - g_system->getPaletteManager()->grabPalette(pal, 0, 6); - g_system->getPaletteManager()->setPalette(pal, 6, 6); +void Display::decodeFrameBuffer() { + byte *src = _frameBuf; + byte *dst = (byte *)_frameBufSurface->getPixels(); + + for (uint i = 0; i < DISPLAY_HEIGHT; ++i) { + decodeScanline(dst, _frameBufSurface->pitch, src); + src += DISPLAY_PITCH; + dst += _frameBufSurface->pitch * 2; } } -void Display::setColorPalette() { - const byte colorPal[6 * 3] = { - 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, - 0xc7, 0x34, 0xff, - 0x38, 0xcb, 0x00, - 0x0d, 0xa1, 0xff, - 0xf2, 0x5e, 0x00 - }; - - g_system->getPaletteManager()->setPalette(colorPal, 0, 6); +void Display::putPixel(Common::Point p, byte color) { + byte offset = p.x / 7; + + if (offset & 1) { + byte c = color << 1; + if (c >= 0x40 && c < 0xc0) + color ^= 0x7f; + } + + byte *b = _frameBuf + p.y * DISPLAY_PITCH + offset; + color ^= *b; + color &= 1 << (p.x % 7); + *b ^= color; } -void Display::setMonoPalette() { - const byte monoPal[2 * 3] = { - 0x00, 0x00, 0x00, - 0x00, 0xc0, 0x01 - }; +void Display::clear(byte color) { + byte val = 0; + + byte c = color << 1; + if (c >= 0x40 && c < 0xc0) + val = 0x7f; - g_system->getPaletteManager()->setPalette(monoPal, 0, 2); + for (uint i = 0; i < DISPLAY_PITCH * DISPLAY_HEIGHT; ++i) { + _frameBuf[i] = color; + color ^= val; + } } -void Display::loadFrameBuffer(Common::ReadStream &stream) { - for (uint j = 0; j < 8; ++j) { - for (uint i = 0; i < 8; ++i) { - byte *dst = _frameBuf + kWidth / 7 * (i * 8 + j); - stream.read(dst, kWidth / 7); - dst += kWidth / 7 * 64; - stream.read(dst, kWidth / 7); - dst += kWidth / 7 * 64; - stream.read(dst, kWidth / 7); - stream.readUint32LE(); - stream.readUint32LE(); - dst += kWidth / 7 * 64; +void Display::updateTextSurface() { + for (uint row = 0; row < 24; ++row) + for (uint col = 0; col < 40; ++col) { + int charPos = row * 40 + col; + char c = _textBuf[row * 40 + col]; + + if (charPos == _cursorPos && _showCursor) + c = (c & 0x3f) | 0x40; + + Common::Rect r(7 * 2, 8 * 2); + r.translate(((c & 0x3f) % 16) * 7 * 2, (c & 0x3f) / 16 * 8 * 2); + + if (!(c & 0x80)) { + if (!(c & 0x40) || ((g_system->getMillis() / 270) & 1)) + r.translate(0, 4 * 8 * 2); + } + + _textBufSurface->copyRectToSurface(*_font, col * 7 * 2, row * 8 * 2, r); + } +} + + +void Display::setCursorPos(Common::Point pos) { + _cursorPos = pos.y * 40 + pos.x; +} + + +void Display::home() { + memset(_textBuf, APPLECHAR(' '), kTextBufSize); + _cursorPos = 0; +} + +void Display::moveCursorForward() { + ++_cursorPos; + + if (_cursorPos >= kTextBufSize) + scrollUp(); +} + +void Display::moveCursorBackward() { + --_cursorPos; + + if (_cursorPos < 0) + _cursorPos = 0; +} + +void Display::moveCursorTo(const Common::Point &pos) { + _cursorPos = pos.y * 40 + pos.x; + + if (_cursorPos >= kTextBufSize) + error("Cursor position (%i, %i) out of bounds", pos.x, pos.y); +} + +void Display::printString(const Common::String &str) { + Common::String::const_iterator c; + for (c = str.begin(); c != str.end(); ++c) { + byte b = *c; + + if (*c == APPLECHAR('\r')) + _cursorPos = (_cursorPos / 40 + 1) * 40; + else if (b < 0x80 || b >= 0xa0) { + setCharAtCursor(b); + ++_cursorPos; } + + if (_cursorPos == kTextBufSize) + scrollUp(); } + + updateTextSurface(); } -void Display::decodeScanlineColor(byte *dst, int pitch, byte *src) { +void Display::setCharAtCursor(byte c) { + _textBuf[_cursorPos] = c; +} + +void Display::showCursor(bool enable) { + _showCursor = enable; +} + +void Display::enableScanlines(bool enable) { + byte pal[6 * 3] = { }; + + if (enable) + g_system->getPaletteManager()->setPalette(pal, 6, 6); + else { + g_system->getPaletteManager()->grabPalette(pal, 0, 6); + g_system->getPaletteManager()->setPalette(pal, 6, 6); + } +} + +void Display::decodeScanlineColor(byte *dst, int pitch, byte *src) const { // TODO: shift secondPal by half a pixel bool prevOn = false; @@ -221,7 +349,7 @@ void Display::decodeScanlineColor(byte *dst, int pitch, byte *src) { } } -void Display::decodeScanlineMono(byte *dst, int pitch, byte *src) { +void Display::decodeScanlineMono(byte *dst, int pitch, byte *src) const { // TODO: shift secondPal by half a pixel for (uint j = 0; j < 39; ++j) { @@ -241,73 +369,13 @@ void Display::decodeScanlineMono(byte *dst, int pitch, byte *src) { } } -void Display::decodeScanline(byte *dst, int pitch, byte *src) { +void Display::decodeScanline(byte *dst, int pitch, byte *src) const { if (_monochrome) decodeScanlineMono(dst, pitch, src); else decodeScanlineColor(dst, pitch, src); } -void Display::decodeFrameBuffer() { - byte *src = _frameBuf; - byte *dst = (byte *)_frameBufSurface->getPixels(); - - for (uint i = 0; i < kHeight; ++i) { - decodeScanline(dst, _frameBufSurface->pitch, src); - src += kWidth / 7; - dst += _frameBufSurface->pitch * 2; - } -} - -void Display::putPixel(Common::Point p, byte color) { - byte offset = p.x / 7; - - if (offset & 1) { - byte c = color << 1; - if (c >= 0x40 && c < 0xc0) - color ^= 0x7f; - } - - byte *b = _frameBuf + p.y * kWidth / 7 + offset; - color ^= *b; - color &= 1 << (p.x % 7); - *b ^= color; -} - -void Display::clear(byte color) { - byte val = 0; - - byte c = color << 1; - if (c >= 0x40 && c < 0xc0) - val = 0x7f; - - for (uint i = 0; i < kWidth / 7 * kHeight; ++i) { - _frameBuf[i] = color; - color ^= val; - } -} - -void Display::updateTextSurface() { - for (uint row = 0; row < 24; ++row) - for (uint col = 0; col < 40; ++col) { - int charPos = row * 40 + col; - char c = _textBuf[row * 40 + col]; - - if (charPos == _cursorPos && _showCursor) - c = (c & 0x3f) | 0x40; - - Common::Rect r(7 * 2, 8 * 2); - r.translate(((c & 0x3f) % 16) * 7 * 2, (c & 0x3f) / 16 * 8 * 2); - - if (!(c & 0x80)) { - if (!(c & 0x40) || ((g_system->getMillis() / 270) & 1)) - r.translate(0, 4 * 8 * 2); - } - - _textBufSurface->copyRectToSurface(*_font, col * 7 * 2, row * 8 * 2, r); - } -} - void Display::drawChar(byte c, int x, int y) { byte *buf = (byte *)_font->getPixels() + y * _font->pitch + x; @@ -361,78 +429,10 @@ void Display::createFont() { } } -void Display::updateScreen() { - if (_mode == kModeText) { - g_system->copyRectToScreen(_textBufSurface->getPixels(), _textBufSurface->pitch, 0, 0, _textBufSurface->w, _textBufSurface->h); - } else if (_mode == kModeHires) { - g_system->copyRectToScreen(_frameBufSurface->getPixels(), _frameBufSurface->pitch, 0, 0, _frameBufSurface->w, _frameBufSurface->h); - } else { - g_system->copyRectToScreen(_frameBufSurface->getPixels(), _frameBufSurface->pitch, 0, 0, _frameBufSurface->w, _frameBufSurface->h - 4 * 8 * 2); - g_system->copyRectToScreen(_textBufSurface->getBasePtr(0, _textBufSurface->h - 4 * 8 * 2), _textBufSurface->pitch, 0, _textBufSurface->h - 4 * 8 * 2, _textBufSurface->w, 4 * 8 * 2); - } -} - -void Display::home() { - memset(_textBuf, APPLECHAR(' '), kTextBufSize); - _cursorPos = 0; -} - -void Display::moveCursorForward() { - ++_cursorPos; - - if (_cursorPos >= kTextBufSize) - scrollUp(); -} - -void Display::moveCursorBackward() { - --_cursorPos; - - if (_cursorPos < 0) - _cursorPos = 0; -} - -void Display::moveCursorTo(const Common::Point &pos) { - _cursorPos = pos.y * 40 + pos.x; - - if (_cursorPos >= kTextBufSize) - error("Cursor position (%i, %i) out of bounds", pos.x, pos.y); -} - -void Display::setCharAtCursor(byte c) { - _textBuf[_cursorPos] = c; -} - void Display::scrollUp() { memmove(_textBuf, _textBuf + 40, kTextBufSize - 40); - memset(_textBuf + kTextBufSize - 40, ' ' | 0x80, 40); + memset(_textBuf + kTextBufSize - 40, APPLECHAR(' '), 40); _cursorPos -= 40; } -void Display::printString(const Common::String &str) { - Common::String::const_iterator c; - for (c = str.begin(); c != str.end(); ++c) { - byte b = *c; - - if (*c == APPLECHAR('\r')) - _cursorPos = (_cursorPos / 40 + 1) * 40; - else if (b < 0x80 || b >= 0xa0) { - setCharAtCursor(b); - ++_cursorPos; - } - - if (_cursorPos == kTextBufSize) - scrollUp(); - } - - updateTextSurface(); -} - -void Display::showCursor(bool enable) { - _showCursor = enable; -} - -void Display::setCursorPos(Common::Point pos) { - _cursorPos = pos.y * 40 + pos.x; -} - } // End of namespace Adl diff --git a/engines/adl/display.h b/engines/adl/display.h index 0452b2768f..70dc42df63 100644 --- a/engines/adl/display.h +++ b/engines/adl/display.h @@ -24,7 +24,6 @@ #define ADL_DISPLAY_H #include -#include namespace Common { class ReadStream; @@ -39,6 +38,9 @@ class Surface; namespace Adl { +#define DISPLAY_WIDTH 280 +#define DISPLAY_HEIGHT 192 + #define APPLECHAR(C) ((char)((C) | 0x80)) class Display { @@ -51,17 +53,20 @@ public: Display(); ~Display(); - void enableScanlines(bool enable); - void setMonoPalette(); - void setColorPalette(); + + void setMode(Mode mode) { _mode = mode; } + void updateScreen(); + bool saveThumbnail(Common::WriteStream &out); + + // Graphics void loadFrameBuffer(Common::ReadStream &stream); void decodeFrameBuffer(); - void updateScreen(); - void setMode(Mode mode) { _mode = mode; } void putPixel(Common::Point p1, byte color); void clear(byte color); - void setCursorPos(Common::Point pos); + // Text + void updateTextSurface(); + void setCursorPos(Common::Point pos); void home(); void moveCursorTo(const Common::Point &pos); void moveCursorForward(); @@ -69,40 +74,33 @@ public: void printString(const Common::String &str); void setCharAtCursor(byte c); void showCursor(bool enable); - void updateTextSurface(); - bool saveThumbnail(Common::WriteStream &out); private: enum { - kWidth = 280, - kHeight = 192, kTextBufSize = 40 * 24 }; - struct PixelPos { - uint16 rowAddr; - byte byteOffset; - byte bitMask; - }; + void enableScanlines(bool enable); + void decodeScanlineColor(byte *dst, int pitch, byte *src) const; + void decodeScanlineMono(byte *dst, int pitch, byte *src) const; + void decodeScanline(byte *dst, int pitch, byte *src) const; - void decodeScanline(byte *dst, int pitch, byte *src); - void decodeScanlineColor(byte *dst, int pitch, byte *src); - void decodeScanlineMono(byte *dst, int pitch, byte *src); void drawChar(byte c, int x, int y); void createFont(); - void scrollUp(); - bool _scanlines; + Mode _mode; + byte *_frameBuf; - byte *_textBuf; Graphics::Surface *_frameBufSurface; + bool _scanlines; + bool _monochrome; + + byte *_textBuf; Graphics::Surface *_textBufSurface; Graphics::Surface *_font; int _cursorPos; - Mode _mode; bool _showCursor; - bool _monochrome; }; } // End of namespace Adl -- cgit v1.2.3