aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorWalter van Niftrik2016-03-14 10:04:51 +0100
committerWalter van Niftrik2016-06-06 20:35:49 +0200
commit148814b2a6c3dffb53b8d902eb7fcfb68110bea3 (patch)
treef424a5964b9d8d8800bf4051685a91e88e0aeda3 /engines
parent60892c91a5455f1c490c1c1016a9149b6d3a2db2 (diff)
downloadscummvm-rg350-148814b2a6c3dffb53b8d902eb7fcfb68110bea3.tar.gz
scummvm-rg350-148814b2a6c3dffb53b8d902eb7fcfb68110bea3.tar.bz2
scummvm-rg350-148814b2a6c3dffb53b8d902eb7fcfb68110bea3.zip
ADL: Move hires1 drawing functions into class
Diffstat (limited to 'engines')
-rw-r--r--engines/adl/adl.cpp68
-rw-r--r--engines/adl/adl.h12
-rw-r--r--engines/adl/graphics.cpp231
-rw-r--r--engines/adl/graphics.h27
-rw-r--r--engines/adl/graphics_v1.cpp120
-rw-r--r--engines/adl/graphics_v2.cpp260
-rw-r--r--engines/adl/hires1.cpp111
-rw-r--r--engines/adl/hires1.h11
-rw-r--r--engines/adl/hires2.cpp9
-rw-r--r--engines/adl/hires2.h3
-rw-r--r--engines/adl/module.mk2
11 files changed, 456 insertions, 398 deletions
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 47623d45e2..a17339f8ea 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -38,16 +38,19 @@
#include "adl/adl.h"
#include "adl/display.h"
#include "adl/detection.h"
+#include "adl/graphics.h"
namespace Adl {
AdlEngine::~AdlEngine() {
delete _display;
+ delete _graphics;
}
AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) :
Engine(syst),
_display(nullptr),
+ _graphics(nullptr),
_gameDescription(gd),
_isRestarting(false),
_isRestoring(false),
@@ -82,6 +85,14 @@ Common::String AdlEngine::readStringAt(Common::SeekableReadStream &stream, uint
return readString(stream, until);
}
+Common::File *AdlEngine::openFile(const Common::String &name) const {
+ Common::File *f = new Common::File();
+ if (!f->open(name))
+ error("Error opening '%s'", name.c_str());
+
+ return f;
+}
+
void AdlEngine::printMessage(uint idx, bool wait) const {
Common::String msg = _messages[idx - 1];
wordWrap(msg);
@@ -281,10 +292,7 @@ void AdlEngine::drawItems() const {
if (item->state == IDI_ITEM_MOVED) {
if (getCurRoom().picture == getCurRoom().curPicture) {
const Common::Point &p = _itemOffsets[dropped];
- if (item->isLineArt)
- drawLineArt(_lineArt[item->picture - 1], p);
- else
- drawPic(item->picture, p);
+ drawItem(*item, p);
++dropped;
}
continue;
@@ -294,61 +302,13 @@ void AdlEngine::drawItems() const {
for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
if (*pic == getCurRoom().curPicture) {
- if (item->isLineArt)
- drawLineArt(_lineArt[item->picture - 1], item->position);
- else
- drawPic(item->picture, item->position);
+ drawItem(*item, item->position);
continue;
}
}
}
}
-void AdlEngine::drawNextPixel(Common::Point &p, byte color, byte bits, byte quadrant) const {
- 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, const Common::Point &pos, byte rotation, byte scaling, byte color) const {
- 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;
-
- Common::Point p(pos);
-
- 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);
- }
-}
-
const Room &AdlEngine::getRoom(uint i) const {
if (i < 1 || i > _state.rooms.size())
error("Room %i out of range [1, %i]", i, _state.rooms.size());
@@ -447,7 +407,7 @@ void AdlEngine::dropItem(byte noun) {
Common::Error AdlEngine::run() {
_display = new Display();
- loadData();
+ init();
int saveSlot = ConfMan.getInt("save_slot");
if (saveSlot >= 0) {
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index d0da3bfec1..d8c631ec48 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -37,6 +37,7 @@ class SeekableReadStream;
namespace Adl {
class Display;
+class GraphicsMan;
struct AdlGameDescription;
// Conditional opcodes
@@ -142,6 +143,7 @@ protected:
Common::String readString(Common::ReadStream &stream, byte until = 0) const;
Common::String readStringAt(Common::SeekableReadStream &stream, uint offset, byte until = 0) const;
+ Common::File *openFile(const Common::String &name) const;
virtual void printMessage(uint idx, bool wait = true) const;
void delay(uint32 ms) const;
@@ -155,8 +157,6 @@ protected:
// Graphics
void clearScreen() const;
void drawItems() const;
- void drawNextPixel(Common::Point &p, byte color, byte bits, byte quadrant) const;
- void drawLineArt(const Common::Array<byte> &lineArt, const Common::Point &pos, byte rotation = 0, byte scaling = 1, byte color = 0x7f) const;
// Game state functions
const Room &getRoom(uint i) const;
@@ -175,6 +175,7 @@ protected:
void doAllCommands(const Commands &commands, byte verb, byte noun);
Display *_display;
+ GraphicsMan *_graphics;
// Message strings in data file
Common::Array<Common::String> _messages;
@@ -182,9 +183,6 @@ protected:
Common::Array<Picture> _pictures;
// Dropped item screen offsets
Common::Array<Common::Point> _itemOffsets;
- // Drawings consisting of horizontal and vertical lines only, but
- // supporting scaling and rotation
- Common::Array<Common::Array<byte> > _lineArt;
// <room, verb, noun, script> lists
Commands _roomCommands;
Commands _globalCommands;
@@ -213,10 +211,10 @@ protected:
private:
virtual void runIntro() const { }
- virtual void loadData() = 0;
+ virtual void init() = 0;
virtual void initState() = 0;
virtual void restartGame() = 0;
- virtual void drawPic(byte pic, Common::Point pos = Common::Point()) const = 0;
+ virtual void drawItem(const Item &item, const Common::Point &pos) const = 0;
virtual void showRoom() const = 0;
// Engine
diff --git a/engines/adl/graphics.cpp b/engines/adl/graphics.cpp
index 8e8117dafd..f9af442a9f 100644
--- a/engines/adl/graphics.cpp
+++ b/engines/adl/graphics.cpp
@@ -22,67 +22,14 @@
#include "common/stream.h"
#include "common/rect.h"
-#include "common/textconsole.h"
#include "adl/display.h"
#include "adl/graphics.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 Graphics::drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const {
+void GraphicsMan::drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const {
int16 deltaX = p2.x - p1.x;
int8 xStep = 1;
@@ -119,180 +66,4 @@ void Graphics::drawLine(const Common::Point &p1, const Common::Point &p2, byte c
}
}
-void Graphics::clear() {
- _display.clear(0xff);
- _color = 0;
-}
-
-void Graphics::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 Graphics::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 Graphics::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 Graphics::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 Graphics::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 Graphics::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/graphics.h b/engines/adl/graphics.h
index 9c47820390..ec29ee073b 100644
--- a/engines/adl/graphics.h
+++ b/engines/adl/graphics.h
@@ -32,12 +32,32 @@ namespace Adl {
class Display;
-class Graphics {
+class GraphicsMan {
public:
- Graphics(Display &display) : _display(display) { }
+ virtual ~GraphicsMan() { }
+ virtual void drawPic(Common::SeekableReadStream &pic, const Common::Point &pos, byte color) = 0;
+protected:
+ GraphicsMan(Display &display) : _display(display) { }
void drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const;
- void draw(Common::SeekableReadStream &pic);
+
+ Display &_display;
+};
+
+class Graphics_v1 : public GraphicsMan {
+public:
+ Graphics_v1(Display &display) : GraphicsMan(display) { }
+ void drawPic(Common::SeekableReadStream &pic, const Common::Point &pos, byte color);
+ void drawCorners(Common::ReadStream &corners, const Common::Point &pos, byte rotation = 0, byte scaling = 1, byte color = 0x7f) const;
+
+private:
+ void drawCornerPixel(Common::Point &p, byte color, byte bits, byte quadrant) const;
+};
+
+class Graphics_v2 : public GraphicsMan {
+public:
+ Graphics_v2(Display &display) : GraphicsMan(display), _color(0) { }
+ void drawPic(Common::SeekableReadStream &pic, const Common::Point &pos, byte color);
private:
void clear();
@@ -47,7 +67,6 @@ private:
void fillRow(const Common::Point &p, bool fillBit, byte pattern);
void fill(Common::SeekableReadStream &pic);
- Display &_display;
byte _color;
};
diff --git a/engines/adl/graphics_v1.cpp b/engines/adl/graphics_v1.cpp
new file mode 100644
index 0000000000..edf16b8be4
--- /dev/null
+++ b/engines/adl/graphics_v1.cpp
@@ -0,0 +1,120 @@
+/* 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/graphics.h"
+
+namespace Adl {
+
+void Graphics_v1::drawPic(Common::SeekableReadStream &pic, const Common::Point &pos, byte color) {
+ byte x, y;
+ bool bNewLine = false;
+ byte oldX = 0, oldY = 0;
+ while (1) {
+ x = pic.readByte();
+ y = pic.readByte();
+
+ if (pic.err() || pic.eos())
+ error("Error reading picture");
+
+ if (x == 0xff && y == 0xff)
+ return;
+
+ if (x == 0 && y == 0) {
+ bNewLine = true;
+ continue;
+ }
+
+ x += pos.x;
+ y += pos.y;
+
+ if (y > 160)
+ y = 160;
+
+ if (bNewLine) {
+ _display.putPixel(Common::Point(x, y), 0x7f);
+ bNewLine = false;
+ } else {
+ drawLine(Common::Point(oldX, oldY), Common::Point(x, y), 0x7f);
+ }
+
+ oldX = x;
+ oldY = y;
+ }
+}
+
+void Graphics_v1::drawCornerPixel(Common::Point &p, byte color, byte bits, byte quadrant) const {
+ 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 Graphics_v1::drawCorners(Common::ReadStream &corners, const Common::Point &pos, byte rotation, byte scaling, byte color) const {
+ 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;
+
+ Common::Point p(pos);
+
+ while (true) {
+ byte b = corners.readByte();
+
+ if (corners.eos() || corners.err())
+ error("Error reading corners");
+
+ if (b == 0)
+ return;
+
+ do {
+ byte xFrac = 0x80;
+ byte yFrac = 0x80;
+ for (uint j = 0; j < scaling; ++j) {
+ if (xFrac + xStep + 1 > 255)
+ drawCornerPixel(p, color, b, quadrant);
+ xFrac += xStep + 1;
+ if (yFrac + yStep > 255)
+ drawCornerPixel(p, color, b, quadrant + 1);
+ yFrac += yStep;
+ }
+ b >>= 3;
+ } while (b != 0);
+ }
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/graphics_v2.cpp b/engines/adl/graphics_v2.cpp
new file mode 100644
index 0000000000..289f43e8de
--- /dev/null
+++ b/engines/adl/graphics_v2.cpp
@@ -0,0 +1,260 @@
+/* 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/graphics.h"
+
+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 MIN_COMMAND 0xe0
+
+#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()) \
+ error("Error reading picture"); \
+ CHECK_COMMAND(b); \
+ } while (0)
+
+#define READ_POINT(p) \
+ do { \
+ READ_BYTE(p.x); \
+ p.x <<= 1; \
+ READ_BYTE(p.y); \
+ } while (0)
+
+void Graphics_v2::clear() {
+ _display.clear(0xff);
+ _color = 0;
+}
+
+void Graphics_v2::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 Graphics_v2::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 Graphics_v2::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 in picture", pattern);
+
+ byte offset = (p.y & 1) << 1;
+ offset += (p.x / 7) & 3;
+
+ return fillPatterns[pattern][offset % PATTERN_LEN];
+}
+
+void Graphics_v2::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 Graphics_v2::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 Graphics_v2::drawPic(Common::SeekableReadStream &pic, const Common::Point &pos, byte color) {
+ 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/hires1.cpp b/engines/adl/hires1.cpp
index 98e33abbb9..735473864a 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -136,7 +136,9 @@ void HiRes1Engine::runIntro() const {
delay(2000);
}
-void HiRes1Engine::loadData() {
+void HiRes1Engine::init() {
+ _graphics = new Graphics_v1(*_display);
+
Common::File f;
if (!f.open(IDS_HR1_MESSAGES))
@@ -196,21 +198,10 @@ void HiRes1Engine::loadData() {
}
// Load right-angle line art
- f.seek(IDI_HR1_OFS_LINE_ART);
- uint16 lineArtTotal = f.readUint16LE();
- for (uint i = 0; i < lineArtTotal; ++i) {
- f.seek(IDI_HR1_OFS_LINE_ART + 2 + i * 2);
- uint16 offset = f.readUint16LE();
- f.seek(IDI_HR1_OFS_LINE_ART + offset);
-
- Common::Array<byte> lineArt;
- byte b = f.readByte();
- while (b != 0) {
- lineArt.push_back(b);
- b = f.readByte();
- }
- _lineArt.push_back(lineArt);
- }
+ f.seek(IDI_HR1_OFS_CORNERS);
+ uint16 cornersCount = f.readUint16LE();
+ for (uint i = 0; i < cornersCount; ++i)
+ _corners.push_back(IDI_HR1_OFS_CORNERS + f.readUint16LE());
if (f.eos() || f.err())
error("Failed to read game data from '" IDS_HR1_EXE_1 "'");
@@ -290,7 +281,7 @@ void HiRes1Engine::drawPic(byte pic, Common::Point pos) const {
error("Failed to open file '%s'", name.c_str());
f.seek(_pictures[pic].offset);
- drawPic(f, pos);
+ _graphics->drawPic(f, pos, 0x7f);
}
void HiRes1Engine::printMessage(uint idx, bool wait) const {
@@ -312,6 +303,16 @@ void HiRes1Engine::printMessage(uint idx, bool wait) const {
AdlEngine::printMessage(idx, wait);
}
+void HiRes1Engine::drawItem(const Item &item, const Common::Point &pos) const {
+ if (item.isLineArt) {
+ Common::File *f = openFile(IDS_HR1_EXE_1);
+ f->seek(_corners[item.picture - 1]);
+ static_cast<Graphics_v1 *>(_graphics)->drawCorners(*f, pos);
+ delete f;
+ } else
+ drawPic(item.picture, pos);
+}
+
void HiRes1Engine::showRoom() const {
if (!_state.isDark) {
drawPic(getCurRoom().curPicture);
@@ -322,82 +323,6 @@ void HiRes1Engine::showRoom() const {
printMessage(_roomDesc[_state.room - 1], false);
}
-void HiRes1Engine::drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const {
- // This draws a four-connected line
-
- 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 (1) {
- _display->putPixel(p, color);
-
- if (--steps == 0)
- return;
-
- if (err < 0) {
- p.y += yStep;
- err += deltaX;
- } else {
- p.x += xStep;
- err += deltaY;
- }
- }
-}
-
-void HiRes1Engine::drawPic(Common::ReadStream &stream, const Common::Point &pos) const {
- byte x, y;
- bool bNewLine = false;
- byte oldX = 0, oldY = 0;
- while (1) {
- x = stream.readByte();
- y = stream.readByte();
-
- if (stream.err() || stream.eos())
- error("Failed to read picture");
-
- if (x == 0xff && y == 0xff)
- return;
-
- if (x == 0 && y == 0) {
- bNewLine = true;
- continue;
- }
-
- x += pos.x;
- y += pos.y;
-
- if (y > 160)
- y = 160;
-
- if (bNewLine) {
- _display->putPixel(Common::Point(x, y), 0x7f);
- bNewLine = false;
- } else {
- drawLine(Common::Point(oldX, oldY), Common::Point(x, y), 0x7f);
- }
-
- oldX = x;
- oldY = y;
- }
-}
-
Engine *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 02cec0137a..96e2fd0122 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -26,6 +26,7 @@
#include "common/str.h"
#include "adl/adl.h"
+#include "adl/graphics.h"
namespace Common {
class ReadStream;
@@ -82,7 +83,7 @@ namespace Adl {
#define IDI_HR1_OFS_CMDS_1 0x3d00
#define IDI_HR1_OFS_ITEM_OFFSETS 0x68ff
-#define IDI_HR1_OFS_LINE_ART 0x4f00
+#define IDI_HR1_OFS_CORNERS 0x4f00
#define IDI_HR1_OFS_VERBS 0x3800
#define IDI_HR1_OFS_NOUNS 0x0f00
@@ -94,16 +95,16 @@ public:
private:
// AdlEngine
void runIntro() const;
- void loadData();
+ void init();
void initState();
void restartGame();
void drawPic(byte pic, Common::Point pos = Common::Point()) const;
void printMessage(uint idx, bool wait = true) const;
+ void drawItem(const Item &item, const Common::Point &pos) const;
void showRoom() const;
- void drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const;
- void drawPic(Common::ReadStream &stream, const Common::Point &pos) const;
-
+ Common::File _exe;
+ Common::Array<uint> _corners;
Common::Array<byte> _roomDesc;
};
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 7bdfde580c..19f447e8be 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -51,7 +51,9 @@ void HiRes2Engine::runIntro() const {
delay(2000);
}
-void HiRes2Engine::loadData() {
+void HiRes2Engine::init() {
+ _graphics = new Graphics_v2(*_display);
+
Common::File f;
if (!f.open(IDS_HR2_DISK_IMAGE))
@@ -122,8 +124,7 @@ void HiRes2Engine::restartGame() {
}
void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
- // Temp hack
- Graphics test(*_display);
+ // Temp hack to show a pic
Common::File f;
@@ -132,7 +133,7 @@ void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
f.seek(0x1000);
- test.draw(f);
+ _graphics->drawPic(f, pos, 0);
}
void HiRes2Engine::showRoom() const {
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 05926ee7b8..f09a62fdcc 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -70,10 +70,11 @@ public:
private:
// AdlEngine
void runIntro() const;
- void loadData();
+ void init();
void initState();
void restartGame();
void drawPic(byte pic, Common::Point pos) const;
+ void drawItem(const Item &item, const Common::Point &pos) const { }
void showRoom() const;
};
diff --git a/engines/adl/module.mk b/engines/adl/module.mk
index 6901279262..de4d645dbc 100644
--- a/engines/adl/module.mk
+++ b/engines/adl/module.mk
@@ -5,6 +5,8 @@ MODULE_OBJS := \
detection.o \
display.o \
graphics.o \
+ graphics_v1.o \
+ graphics_v2.o \
hires1.o \
hires2.o