aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/adl/display.cpp22
-rw-r--r--engines/adl/display.h2
-rw-r--r--engines/adl/hires2.cpp14
-rw-r--r--engines/adl/module.mk3
-rw-r--r--engines/adl/picture.cpp298
-rw-r--r--engines/adl/picture.h56
6 files changed, 393 insertions, 2 deletions
diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp
index 6342504bc3..37959735fd 100644
--- a/engines/adl/display.cpp
+++ b/engines/adl/display.cpp
@@ -219,9 +219,24 @@ void Display::loadFrameBuffer(Common::ReadStream &stream) {
error("Failed to read frame buffer");
}
+void Display::putPixelRaw(const Common::Point &p, byte color) {
+ byte *b = _frameBuf + p.y * DISPLAY_PITCH + (p.x / 7);
+ color ^= *b;
+ color &= 0x80 | (1 << (p.x % 7));
+ *b ^= color;
+}
+
void Display::putPixel(const Common::Point &p, byte color) {
byte offset = p.x / 7;
+ byte mask = 0x80 | (1 << (p.x % 7));
+ // Since white and black are in both palettes, we leave
+ // the palette bit alone
+ if ((color & 0x7f) == 0x7f || (color & 0x7f) == 0)
+ mask &= 0x7f;
+
+ // Adjust colors starting with bits '01' or '10' for
+ // odd offsets
if (offset & 1) {
byte c = color << 1;
if (c >= 0x40 && c < 0xc0)
@@ -230,10 +245,15 @@ void Display::putPixel(const Common::Point &p, byte color) {
byte *b = _frameBuf + p.y * DISPLAY_PITCH + offset;
color ^= *b;
- color &= 1 << (p.x % 7);
+ color &= mask;
*b ^= color;
}
+bool Display::getPixelBit(const Common::Point &p) const {
+ byte *b = _frameBuf + p.y * DISPLAY_PITCH + (p.x / 7);
+ return *b & (1 << (p.x % 7));
+}
+
void Display::clear(byte color) {
byte val = 0;
diff --git a/engines/adl/display.h b/engines/adl/display.h
index ff01e3faf2..67d8bf4392 100644
--- a/engines/adl/display.h
+++ b/engines/adl/display.h
@@ -61,7 +61,9 @@ public:
// Graphics
void loadFrameBuffer(Common::ReadStream &stream);
+ void putPixelRaw(const Common::Point &p, byte color);
void putPixel(const Common::Point &p, byte color);
+ bool getPixelBit(const Common::Point &p) const;
void clear(byte color);
// Text
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 1c4377180d..c36e151969 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -28,6 +28,7 @@
#include "adl/hires2.h"
#include "adl/display.h"
+#include "adl/picture.h"
namespace Adl {
@@ -121,9 +122,22 @@ void HiRes2Engine::restartGame() {
}
void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
+ // Temp hack
+ PictureD test(*_display);
+
+ Common::File f;
+
+ if (!f.open(IDS_HR2_DISK_IMAGE))
+ error("Failed to open file '" IDS_HR2_DISK_IMAGE "'");
+
+ f.seek(0x1000);
+
+ test.draw(f);
}
void HiRes2Engine::showRoom() const {
+ drawPic(0, Common::Point());
+ _display->updateHiResScreen();
}
Engine *HiRes2Engine_create(OSystem *syst, const AdlGameDescription *gd) {
diff --git a/engines/adl/module.mk b/engines/adl/module.mk
index de69b52621..8162e51665 100644
--- a/engines/adl/module.mk
+++ b/engines/adl/module.mk
@@ -5,7 +5,8 @@ MODULE_OBJS := \
detection.o \
display.o \
hires1.o \
- hires2.o
+ hires2.o \
+ picture.o
MODULE_DIRS += \
engines/adl
diff --git a/engines/adl/picture.cpp b/engines/adl/picture.cpp
new file mode 100644
index 0000000000..567165af62
--- /dev/null
+++ b/engines/adl/picture.cpp
@@ -0,0 +1,298 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/stream.h"
+#include "common/rect.h"
+#include "common/textconsole.h"
+
+#include "adl/display.h"
+#include "adl/picture.h"
+
+#define MIN_COMMAND 0xe0
+
+namespace Adl {
+
+#define NUM_PATTERNS 22
+#define PATTERN_LEN 4
+static const byte fillPatterns[NUM_PATTERNS][PATTERN_LEN] = {
+ { 0x00, 0x00, 0x00, 0x00 },
+ { 0x80, 0x80, 0x80, 0x80 },
+ { 0xff, 0xff, 0xff, 0xff },
+ { 0x7f, 0x7f, 0x7f, 0x7f },
+ { 0x2a, 0x55, 0x2a, 0x55 },
+ { 0xaa, 0xd5, 0xaa, 0xd5 },
+ { 0x55, 0x2a, 0x55, 0x2a },
+ { 0xd5, 0xaa, 0xd5, 0xaa },
+ { 0x33, 0x66, 0x4c, 0x19 },
+ { 0xb3, 0xe6, 0xcc, 0x99 },
+ { 0x22, 0x44, 0x08, 0x11 },
+ { 0xa2, 0xc4, 0x88, 0x91 },
+ { 0x11, 0x22, 0x44, 0x08 },
+ { 0x91, 0xa2, 0xc4, 0x88 },
+ { 0x6e, 0x5d, 0x3b, 0x77 },
+ { 0xee, 0xdd, 0xbb, 0xf7 },
+ { 0x5d, 0x3b, 0x77, 0x6e },
+ { 0xdd, 0xbb, 0xf7, 0xee },
+ { 0x66, 0x4c, 0x19, 0x33 },
+ { 0xe6, 0xcc, 0x99, 0xb3 },
+ { 0x33, 0x66, 0x4c, 0x19 },
+ { 0xb3, 0xe6, 0xcc, 0x99 }
+};
+
+#define CHECK_COMMAND(X) \
+ do { \
+ if ((X) >= MIN_COMMAND) { \
+ pic.seek(-1, SEEK_CUR); \
+ return; \
+ } \
+ } while (0)
+
+#define READ_BYTE(b) \
+ do { \
+ b = pic.readByte(); \
+ if (pic.eos() || pic.err()) \
+ return; \
+ CHECK_COMMAND(b); \
+ } while (0)
+
+#define READ_POINT(p) \
+ do { \
+ READ_BYTE(p.x); \
+ p.x <<= 1; \
+ READ_BYTE(p.y); \
+ } while (0)
+
+// Draws a four-connected line
+void PictureD::drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const {
+ int16 deltaX = p2.x - p1.x;
+ int8 xStep = 1;
+
+ if (deltaX < 0) {
+ deltaX = -deltaX;
+ xStep = -1;
+ }
+
+ int16 deltaY = p2.y - p1.y;
+ int8 yStep = -1;
+
+ if (deltaY > 0) {
+ deltaY = -deltaY;
+ yStep = 1;
+ }
+
+ Common::Point p(p1);
+ int16 steps = deltaX - deltaY + 1;
+ int16 err = deltaX + deltaY;
+
+ while (true) {
+ _display.putPixel(p, color);
+
+ if (--steps == 0)
+ return;
+
+ if (err < 0) {
+ p.y += yStep;
+ err += deltaX;
+ } else {
+ p.x += xStep;
+ err += deltaY;
+ }
+ }
+}
+
+void PictureD::clear() {
+ _display.clear(0xff);
+ _color = 0;
+}
+
+void PictureD::drawCorners(Common::SeekableReadStream &pic, bool yFirst) {
+ Common::Point p;
+
+ READ_POINT(p);
+
+ if (yFirst)
+ goto doYStep;
+
+ while (true) {
+ int16 n;
+
+ READ_BYTE(n);
+
+ _display.putPixel(p, _color);
+
+ n <<= 1;
+ drawLine(p, Common::Point(n, p.y), _color);
+ p.x = n;
+
+doYStep:
+ READ_BYTE(n);
+
+ _display.putPixel(p, _color);
+ drawLine(p, Common::Point(p.x, n), _color);
+
+ _display.putPixel(Common::Point(p.x + 1, p.y), _color);
+ drawLine(Common::Point(p.x + 1, p.y), Common::Point(p.x + 1, n), _color);
+
+ p.y = n;
+ }
+}
+
+void PictureD::drawRelativeLines(Common::SeekableReadStream &pic) {
+ Common::Point p1;
+
+ READ_POINT(p1);
+ _display.putPixel(p1, _color);
+
+ while (true) {
+ Common::Point p2(p1);
+
+ byte n;
+ READ_BYTE(n);
+
+ byte h = (n & 0x70) >> 4;
+ byte l = n & 7;
+
+ if (n & 0x80)
+ p2.x -= (h << 1);
+ else
+ p2.x += (h << 1);
+
+ if (n & 8)
+ p2.y -= l;
+ else
+ p2.y += l;
+
+ drawLine(p1, p2, _color);
+ p1 = p2;
+ }
+}
+
+void PictureD::drawAbsoluteLines(Common::SeekableReadStream &pic) {
+ Common::Point p1;
+
+ READ_POINT(p1);
+ _display.putPixel(p1, _color);
+
+ while (true) {
+ Common::Point p2;
+
+ READ_POINT(p2);
+ drawLine(p1, p2, _color);
+ p1 = p2;
+ }
+}
+
+static byte getPatternColor(const Common::Point &p, byte pattern) {
+ if (pattern >= NUM_PATTERNS)
+ error("Invalid fill pattern %i encountered", pattern);
+
+ byte offset = (p.y & 1) << 1;
+ offset += (p.x / 7) & 3;
+
+ return fillPatterns[pattern][offset % PATTERN_LEN];
+}
+
+void PictureD::fillRow(const Common::Point &p, bool stopBit, byte pattern) {
+ const byte color = getPatternColor(p, pattern);
+ _display.putPixelRaw(p, color);
+
+ Common::Point q(p);
+ byte c = color;
+
+ while (++q.x < DISPLAY_WIDTH && _display.getPixelBit(q) != stopBit) {
+ if ((q.x % 7) == 0)
+ c = getPatternColor(q, pattern);
+ _display.putPixelRaw(q, c);
+ }
+
+ q = p;
+ c = color;
+ while (--q.x >= 0 && _display.getPixelBit(q) != stopBit) {
+ if ((q.x % 7) == 6)
+ c = getPatternColor(q, pattern);
+ _display.putPixelRaw(q, c);
+ }
+}
+
+// Basic flood fill
+void PictureD::fill(Common::SeekableReadStream &pic) {
+ byte pattern;
+ READ_BYTE(pattern);
+
+ while (true) {
+ Common::Point p;
+ READ_POINT(p);
+
+ bool stopBit = !_display.getPixelBit(p);
+
+ while (--p.y >= 0) {
+ if (_display.getPixelBit(p) == stopBit)
+ break;
+ if (_display.getPixelBit(Common::Point(p.x + 1, p.y)) == stopBit)
+ break;
+ }
+
+ while (++p.y < DISPLAY_HEIGHT) {
+ if (_display.getPixelBit(p) == stopBit)
+ break;
+ if (_display.getPixelBit(Common::Point(p.x + 1, p.y)) == stopBit)
+ break;
+ fillRow(p, stopBit, pattern);
+ }
+ }
+}
+
+void PictureD::draw(Common::SeekableReadStream &pic) {
+ while (true) {
+ byte opcode = pic.readByte();
+
+ if (pic.eos() || pic.err())
+ error("Error reading picture");
+
+ switch (opcode) {
+ case 0xe0:
+ drawCorners(pic, false);
+ break;
+ case 0xe1:
+ drawCorners(pic, true);
+ break;
+ case 0xe2:
+ drawRelativeLines(pic);
+ break;
+ case 0xe3:
+ drawAbsoluteLines(pic);
+ break;
+ case 0xe4:
+ fill(pic);
+ break;
+ case 0xe5:
+ clear();
+ break;
+ case 0xff:
+ return;
+ default:
+ error("Invalid pic opcode %02x", opcode);
+ }
+ }
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/picture.h b/engines/adl/picture.h
new file mode 100644
index 0000000000..990c8561d9
--- /dev/null
+++ b/engines/adl/picture.h
@@ -0,0 +1,56 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ADL_PICTURE_H
+#define ADL_PICTURE_H
+
+namespace Common{
+class SeekableReadStream;
+class Point;
+}
+
+namespace Adl {
+
+class Display;
+
+class PictureD {
+public:
+ PictureD(Display &display) : _display(display) { }
+
+ void drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const;
+ void draw(Common::SeekableReadStream &pic);
+
+private:
+ void clear();
+ void drawCorners(Common::SeekableReadStream &pic, bool yFirst);
+ void drawRelativeLines(Common::SeekableReadStream &pic);
+ void drawAbsoluteLines(Common::SeekableReadStream &pic);
+ void fillRow(const Common::Point &p, bool fillBit, byte pattern);
+ void fill(Common::SeekableReadStream &pic);
+
+ Display &_display;
+ byte _color;
+};
+
+} // End of namespace Adl
+
+#endif