aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWalter van Niftrik2016-03-03 19:17:49 +0100
committerWalter van Niftrik2016-03-09 10:03:13 +0100
commitd5cc42f1c233a45abb879818af503ec7b91c6f34 (patch)
tree42d0c47862aad4c2b919ae4d81b3b2cbaef06dc8
parentb30fb417acb29dee415a784f15f63772a010b4d3 (diff)
downloadscummvm-rg350-d5cc42f1c233a45abb879818af503ec7b91c6f34.tar.gz
scummvm-rg350-d5cc42f1c233a45abb879818af503ec7b91c6f34.tar.bz2
scummvm-rg350-d5cc42f1c233a45abb879818af503ec7b91c6f34.zip
ADL: Make frame buffer linear
-rw-r--r--engines/adl/adl.cpp48
-rw-r--r--engines/adl/adl.h2
-rw-r--r--engines/adl/display.cpp241
-rw-r--r--engines/adl/display.h10
-rw-r--r--engines/adl/hires1.cpp40
-rw-r--r--engines/adl/hires1.h1
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);
};