diff options
author | Walter van Niftrik | 2016-03-03 19:17:49 +0100 |
---|---|---|
committer | Walter van Niftrik | 2016-03-09 10:03:13 +0100 |
commit | d5cc42f1c233a45abb879818af503ec7b91c6f34 (patch) | |
tree | 42d0c47862aad4c2b919ae4d81b3b2cbaef06dc8 | |
parent | b30fb417acb29dee415a784f15f63772a010b4d3 (diff) | |
download | scummvm-rg350-d5cc42f1c233a45abb879818af503ec7b91c6f34.tar.gz scummvm-rg350-d5cc42f1c233a45abb879818af503ec7b91c6f34.tar.bz2 scummvm-rg350-d5cc42f1c233a45abb879818af503ec7b91c6f34.zip |
ADL: Make frame buffer linear
-rw-r--r-- | engines/adl/adl.cpp | 48 | ||||
-rw-r--r-- | engines/adl/adl.h | 2 | ||||
-rw-r--r-- | engines/adl/display.cpp | 241 | ||||
-rw-r--r-- | engines/adl/display.h | 10 | ||||
-rw-r--r-- | engines/adl/hires1.cpp | 40 | ||||
-rw-r--r-- | engines/adl/hires1.h | 1 |
6 files changed, 125 insertions, 217 deletions
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp index 083fde9690..90a9a0db06 100644 --- a/engines/adl/adl.cpp +++ b/engines/adl/adl.cpp @@ -484,7 +484,7 @@ void AdlEngine::drawItems() { if (curRoom().picture == curRoom().curPicture) { const Common::Point &p = _itemOffsets[dropped]; if (item->isLineArt) - _display->drawLineArt(_lineArt[item->picture - 1], p); + drawLineArt(_lineArt[item->picture - 1], p); else drawPic(item->picture, p); ++dropped; @@ -497,7 +497,7 @@ void AdlEngine::drawItems() { for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) { if (*pic == curRoom().curPicture) { if (item->isLineArt) - _display->drawLineArt(_lineArt[item->picture - 1], item->position); + drawLineArt(_lineArt[item->picture - 1], item->position); else drawPic(item->picture, item->position); continue; @@ -942,6 +942,50 @@ void AdlEngine::delay(uint32 ms) { } } +void AdlEngine::drawNextPixel(Common::Point &p, byte color, byte bits, byte quadrant) { + if (bits & 4) { + _display->putPixel(p, color); + } + + bits += quadrant; + + if (bits & 1) + p.x += (bits & 2 ? -1 : 1); + else + p.y += (bits & 2 ? 1 : -1); +} + +void AdlEngine::drawLineArt(const Common::Array<byte> &lineArt, Common::Point p, byte rotation, byte scaling, byte color) { + const byte stepping[] = { + 0xff, 0xfe, 0xfa, 0xf4, 0xec, 0xe1, 0xd4, 0xc5, + 0xb4, 0xa1, 0x8d, 0x78, 0x61, 0x49, 0x31, 0x18, + 0xff + }; + + byte quadrant = rotation >> 4; + rotation &= 0xf; + byte xStep = stepping[rotation]; + byte yStep = stepping[(rotation ^ 0xf) + 1] + 1; + + for (uint i = 0; i < lineArt.size(); ++i) { + byte b = lineArt[i]; + + do { + byte xFrac = 0x80; + byte yFrac = 0x80; + for (uint j = 0; j < scaling; ++j) { + if (xFrac + xStep + 1 > 255) + drawNextPixel(p, color, b, quadrant); + xFrac += xStep + 1; + if (yFrac + yStep > 255) + drawNextPixel(p, color, b, quadrant + 1); + yFrac += yStep; + } + b >>= 3; + } while (b != 0); + } +} + AdlEngine *AdlEngine::create(GameType type, OSystem *syst, const AdlGameDescription *gd) { switch(type) { case kGameTypeHires1: diff --git a/engines/adl/adl.h b/engines/adl/adl.h index f8b2dca1b7..84b9214161 100644 --- a/engines/adl/adl.h +++ b/engines/adl/adl.h @@ -198,6 +198,8 @@ protected: void clearScreen(); virtual void drawPic(byte pic, Common::Point pos = Common::Point()) = 0; void drawItems(); + void drawNextPixel(Common::Point &p, byte color, byte bits, byte quadrant); + void drawLineArt(const Common::Array<byte> &lineArt, Common::Point p, byte rotation = 0, byte scaling = 1, byte color = 0x7f); void showRoom(); void takeItem(byte noun); void dropItem(byte noun); diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp index 6a7cc6900b..90ca1b60db 100644 --- a/engines/adl/display.cpp +++ b/engines/adl/display.cpp @@ -89,7 +89,7 @@ Display::Display() : enableScanlines(_scanlines); - _frameBuf = new byte[kFrameBufSize]; + _frameBuf = new byte[kWidth * kHeight / 7]; _frameBufSurface = new Graphics::Surface; _frameBufSurface->create(kWidth * 2, kHeight * 2, Graphics::PixelFormat::createFormatCLUT8()); @@ -164,7 +164,19 @@ void Display::setMonoPalette() { } void Display::loadFrameBuffer(Common::ReadStream &stream) { - stream.read(_frameBuf, kFrameBufSize); + 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::decodeScanlineColor(byte *dst, int pitch, byte *src) { @@ -236,224 +248,45 @@ void Display::decodeScanline(byte *dst, int pitch, byte *src) { decodeScanlineColor(dst, pitch, src); } -Display::PixelPos Display::getPixelPos(byte x, byte y) { - PixelPos pixelPos; - - // FIXME: check X, Y range - - byte offsetL = y & 0xc0; - offsetL |= offsetL >> 2; - byte offsetH = y; - y <<= 2; - offsetH <<= 1; - offsetH |= y >> 7; - y <<= 1; - offsetH <<= 1; - offsetH |= y >> 7; - y <<= 1; - offsetL >>= 1; - offsetL |= y & 0x80; - y <<= 1; - offsetH = offsetH & 0x1f; - pixelPos.rowAddr = (offsetH << 8) | offsetL; - pixelPos.byteOffset = x / 7; - pixelPos.bitMask = 0x80 | (1 << x % 7); - - return pixelPos; -} - -byte Display::getPixelColor(byte offset, byte color) { - if (offset & 1) { - byte c = color << 1; - if (c >= 0x40 && c < 0xc0) - return color ^ 0x7f; - } - - return color; -} - void Display::decodeFrameBuffer() { byte *src = _frameBuf; - int pitch = _frameBufSurface->pitch; - for (int j = 0; j < 8; ++j) { - for (int i = 0; i < 8; ++i) { - byte *dst = (byte *)_frameBufSurface->getPixels() + pitch * 2 * (i * 8 + j); - decodeScanline(dst, pitch, src); - src += 40; - dst += pitch * 2 * 64; - decodeScanline(dst, pitch, src); - src += 40; - dst += pitch * 2 * 64; - decodeScanline(dst, pitch, src); - src += 48; - dst += pitch * 2 * 64; - } - } -} - -void Display::drawPixel(byte x, byte y, byte color) { - PixelPos p = getPixelPos(x, y); - byte c = getPixelColor(p.byteOffset, color); - byte *b = _frameBuf + p.rowAddr + p.byteOffset; - c ^= *b; - c &= p.bitMask; - c ^= *b; - *b = c; -} + byte *dst = (byte *)_frameBufSurface->getPixels(); -void Display::moveX(PixelPos &p, byte &color, bool left) { - if (left) { - byte bit = p.bitMask; - bool b = bit & 1; - bit >>= 1; - if (!b) { - bit ^= 0xc0; - p.bitMask = bit; - return; - } - --p.byteOffset; - if (p.byteOffset & 0x80) - p.byteOffset = 39; - p.bitMask = 0xc0; - } else { - byte bit = p.bitMask; - bit <<= 1; - bit ^= 0x80; - if (bit & 0x80) { - p.bitMask = bit; - return; - } - p.bitMask = 0x81; - ++p.byteOffset; - if (p.byteOffset == 40) - p.byteOffset = 0; + for (uint i = 0; i < kHeight; ++i) { + decodeScanline(dst, _frameBufSurface->pitch, src); + src += kWidth / 7; + dst += _frameBufSurface->pitch * 2; } - - color = getPixelColor(p.byteOffset, color); } -void Display::moveY(PixelPos &p, bool down) { - if (!down) { - if (p.rowAddr & 0x1c00) - p.rowAddr -= 0x400; - else if (p.rowAddr & 0x380) - p.rowAddr += 0x1b80; - else { - p.rowAddr += 0x1f58; - if (!(p.rowAddr & 0x80)) - p.rowAddr += 0x78; // Wrap around - } - } else { - p.rowAddr += 0x400; - if (p.rowAddr & 0x1c00) - return; - else if ((p.rowAddr & 0x380) != 0x380) - p.rowAddr -= 0x1f80; - else { - p.rowAddr -= 0x2358; - if ((p.rowAddr & 0x78) == 0x78) - p.rowAddr -= 0x78; // Wrap around - } - } -} +void Display::putPixel(Common::Point p, byte color) { + byte offset = p.x / 7; -void Display::drawNextPixel(Display::PixelPos &p, byte &color, byte bits, byte quadrant) { - if (bits & 4) { - byte b = (_frameBuf[p.rowAddr + p.byteOffset] ^ color) & p.bitMask; - _frameBuf[p.rowAddr + p.byteOffset] ^= b; + if (offset & 1) { + byte c = color << 1; + if (c >= 0x40 && c < 0xc0) + color ^= 0x7f; } - bits += quadrant; - - if (bits & 1) - moveX(p, color, bits & 2); - else - moveY(p, bits & 2); -} - -void Display::drawLineArt(const Common::Array<byte> &lineArt, Common::Point p, byte rotation, byte scaling, byte color) { - const byte stepping[] = { - 0xff, 0xfe, 0xfa, 0xf4, 0xec, 0xe1, 0xd4, 0xc5, - 0xb4, 0xa1, 0x8d, 0x78, 0x61, 0x49, 0x31, 0x18, - 0xff - }; - - PixelPos pos = getPixelPos(p.x, p.y); - byte c = getPixelColor(pos.byteOffset, color); - - byte quadrant = rotation >> 4; - rotation &= 0xf; - byte xStep = stepping[rotation]; - byte yStep = stepping[(rotation ^ 0xf) + 1] + 1; - - for (uint i = 0; i < lineArt.size(); ++i) { - byte b = lineArt[i]; - - do { - byte xFrac = 0x80; - byte yFrac = 0x80; - for (uint j = 0; j < scaling; ++j) { - if (xFrac + xStep + 1 > 255) - drawNextPixel(pos, c, b, quadrant); - xFrac += xStep + 1; - if (yFrac + yStep > 255) - drawNextPixel(pos, c, b, quadrant + 1); - yFrac += yStep; - } - b >>= 3; - } while (b != 0); - } + byte *b = _frameBuf + p.y * kWidth / 7 + offset; + color ^= *b; + color &= 1 << (p.x % 7); + *b ^= color; } -void Display::drawLine(Common::Point p1, Common::Point p2, byte color) { - PixelPos p = getPixelPos(p1.x, p1.y); - byte c = getPixelColor(p.byteOffset, color); - - int16 deltaX = p2.x - p1.x; - byte dir = deltaX >> 8; - - if (deltaX < 0) - deltaX = -deltaX; - - int16 err = deltaX; - - int16 deltaY = p2.y - p1.y - 1; - dir >>= 1; - if (deltaY >= 0) { - deltaY = -deltaY - 2; - dir |= 0x80; - } - - int16 steps = deltaY - deltaX; - - err += deltaY + 1; - - while (1) { - byte *b = _frameBuf + p.rowAddr + p.byteOffset; - byte d = *b; - d ^= c; - d &= p.bitMask; - d ^= *b; - *b = d; +void Display::clear(byte color) { + byte val = 0; - if (++steps == 0) - return; + byte c = color << 1; + if (c >= 0x40 && c < 0xc0) + val = 0x7f; - if (err < 0) { - moveY(p, dir & 0x80); - err += deltaX; - } else { - moveX(p, c, dir & 0x40); - err += deltaY + 1; - } + for (uint i = 0; i < kWidth / 7 * kHeight; ++i) { + _frameBuf[i] = color; + color ^= val; } } -void Display::clear(byte color) { - for (uint i = 0; i < kFrameBufSize; ++i) - _frameBuf[i] = getPixelColor(i & 1, color); -} - void Display::updateTextSurface() { for (uint row = 0; row < 24; ++row) for (uint col = 0; col < 40; ++col) { diff --git a/engines/adl/display.h b/engines/adl/display.h index 12e3ab90b9..0452b2768f 100644 --- a/engines/adl/display.h +++ b/engines/adl/display.h @@ -58,10 +58,8 @@ public: void decodeFrameBuffer(); void updateScreen(); void setMode(Mode mode) { _mode = mode; } - void drawPixel(byte x, byte y, byte color); - void drawLine(Common::Point p1, Common::Point p2, byte color); + void putPixel(Common::Point p1, byte color); void clear(byte color); - void drawLineArt(const Common::Array<byte> &lineArt, Common::Point p, byte rotation = 0, byte scaling = 1, byte color = 0x7f); void setCursorPos(Common::Point pos); void home(); @@ -78,7 +76,6 @@ private: enum { kWidth = 280, kHeight = 192, - kFrameBufSize = 0x2000, kTextBufSize = 40 * 24 }; @@ -91,13 +88,8 @@ private: void decodeScanline(byte *dst, int pitch, byte *src); void decodeScanlineColor(byte *dst, int pitch, byte *src); void decodeScanlineMono(byte *dst, int pitch, byte *src); - PixelPos getPixelPos(byte x, byte y); - byte getPixelColor(byte x, byte color); void drawChar(byte c, int x, int y); void createFont(); - void moveX(PixelPos &p, byte &color, bool left); - void moveY(PixelPos &p, bool down); - void drawNextPixel(Display::PixelPos &p, byte &color, byte bits, byte quadrant); void scrollUp(); diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp index 54351911fc..04df01ecd4 100644 --- a/engines/adl/hires1.cpp +++ b/engines/adl/hires1.cpp @@ -216,10 +216,10 @@ void HiRes1Engine::drawPic(Common::ReadStream &stream, Common::Point pos) { y = 160; if (bNewLine) { - _display->drawPixel(x, y, 0x7f); + _display->putPixel(Common::Point(x, y), 0x7f); bNewLine = false; } else { - _display->drawLine(Common::Point(oldX, oldY), Common::Point(x, y), 0x7f); + drawLine(Common::Point(oldX, oldY), Common::Point(x, y), 0x7f); } oldX = x; @@ -455,6 +455,42 @@ uint HiRes1Engine::getEngineMessage(EngineMessage msg) { } } +void HiRes1Engine::drawLine(Common::Point p1, Common::Point p2, byte color) { + int16 deltaX = p2.x - p1.x; + byte dir = deltaX >> 8; + + if (deltaX < 0) + deltaX = -deltaX; + + int16 err = deltaX; + + int16 deltaY = p2.y - p1.y - 1; + dir >>= 1; + if (deltaY >= 0) { + deltaY = -deltaY - 2; + dir |= 0x80; + } + + int16 steps = deltaY - deltaX; + + err += deltaY + 1; + + while (1) { + _display->putPixel(p1, color); + + if (++steps == 0) + return; + + if (err < 0) { + p1.y += (dir & 0x80 ? 1 : -1); + err += deltaX; + } else { + p1.x += (dir & 0x40 ? -1 : 1); + err += deltaY + 1; + } + } +} + AdlEngine *HiRes1Engine__create(OSystem *syst, const AdlGameDescription *gd) { return new HiRes1Engine(syst, gd); } diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h index 897327cdbf..cae5980102 100644 --- a/engines/adl/hires1.h +++ b/engines/adl/hires1.h @@ -57,6 +57,7 @@ private: void runIntro(); void drawPic(Common::ReadStream &stream, Common::Point pos); void drawItems(); + void drawLine(Common::Point p1, Common::Point p2, byte color); void drawPic(byte pic, Common::Point pos); }; |