mirror of
https://github.com/libretro/scummvm.git
synced 2025-03-02 16:31:01 +00:00
ADL: Merge graphics code into a single file
This commit is contained in:
parent
7b0c49b2a8
commit
55f3bef837
@ -22,6 +22,7 @@
|
||||
|
||||
#include "common/stream.h"
|
||||
#include "common/rect.h"
|
||||
#include "common/textconsole.h"
|
||||
|
||||
#include "adl/display.h"
|
||||
#include "adl/graphics.h"
|
||||
@ -66,4 +67,361 @@ void GraphicsMan::drawLine(const Common::Point &p1, const Common::Point &p2, byt
|
||||
}
|
||||
}
|
||||
|
||||
void Graphics_v1::drawPic(Common::SeekableReadStream &pic, const Common::Point &pos) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
#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 += _offset.x; \
|
||||
p.x <<= 1; \
|
||||
READ_BYTE(p.y); \
|
||||
p.y += _offset.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);
|
||||
n += _offset.x;
|
||||
|
||||
_display.putPixel(p, _color);
|
||||
|
||||
n <<= 1;
|
||||
drawLine(p, Common::Point(n, p.y), _color);
|
||||
p.x = n;
|
||||
|
||||
doYStep:
|
||||
READ_BYTE(n);
|
||||
n += _offset.y;
|
||||
|
||||
_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.setPixelPalette(p, color);
|
||||
_display.setPixelBit(p, color);
|
||||
|
||||
Common::Point q(p);
|
||||
byte c = color;
|
||||
|
||||
while (++q.x < DISPLAY_WIDTH) {
|
||||
if ((q.x % 7) == 0) {
|
||||
c = getPatternColor(q, pattern);
|
||||
// Palette is set before the first bit is tested
|
||||
_display.setPixelPalette(q, c);
|
||||
}
|
||||
if (_display.getPixelBit(q) == stopBit)
|
||||
break;
|
||||
_display.setPixelBit(q, c);
|
||||
}
|
||||
|
||||
q = p;
|
||||
c = color;
|
||||
while (--q.x >= 0) {
|
||||
if ((q.x % 7) == 6) {
|
||||
c = getPatternColor(q, pattern);
|
||||
_display.setPixelPalette(q, c);
|
||||
}
|
||||
if (_display.getPixelBit(q) == stopBit)
|
||||
break;
|
||||
_display.setPixelBit(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) {
|
||||
_color = 0;
|
||||
_offset = pos;
|
||||
|
||||
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 0xf0:
|
||||
_color = 0x00;
|
||||
break;
|
||||
case 0xf1:
|
||||
_color = 0x2a;
|
||||
break;
|
||||
case 0xf2:
|
||||
_color = 0x55;
|
||||
break;
|
||||
case 0xf3:
|
||||
_color = 0x7f;
|
||||
break;
|
||||
case 0xf4:
|
||||
_color = 0x80;
|
||||
break;
|
||||
case 0xf5:
|
||||
_color = 0xaa;
|
||||
break;
|
||||
case 0xf6:
|
||||
_color = 0xd5;
|
||||
break;
|
||||
case 0xf7:
|
||||
_color = 0xff;
|
||||
break;
|
||||
case 0xff:
|
||||
return;
|
||||
default:
|
||||
error("Invalid pic opcode %02x", opcode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Adl
|
||||
|
@ -1,120 +0,0 @@
|
||||
/* 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 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
|
@ -1,304 +0,0 @@
|
||||
/* 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"
|
||||
#include "adl/adl.h"
|
||||
|
||||
namespace Adl {
|
||||
|
||||
// FIXME: Add clipping
|
||||
|
||||
#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 += _offset.x; \
|
||||
p.x <<= 1; \
|
||||
READ_BYTE(p.y); \
|
||||
p.y += _offset.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);
|
||||
n += _offset.x;
|
||||
|
||||
_display.putPixel(p, _color);
|
||||
|
||||
n <<= 1;
|
||||
drawLine(p, Common::Point(n, p.y), _color);
|
||||
p.x = n;
|
||||
|
||||
doYStep:
|
||||
READ_BYTE(n);
|
||||
n += _offset.y;
|
||||
|
||||
_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.setPixelPalette(p, color);
|
||||
_display.setPixelBit(p, color);
|
||||
|
||||
Common::Point q(p);
|
||||
byte c = color;
|
||||
|
||||
while (++q.x < DISPLAY_WIDTH) {
|
||||
if ((q.x % 7) == 0) {
|
||||
c = getPatternColor(q, pattern);
|
||||
// Palette is set before the first bit is tested
|
||||
_display.setPixelPalette(q, c);
|
||||
}
|
||||
if (_display.getPixelBit(q) == stopBit)
|
||||
break;
|
||||
_display.setPixelBit(q, c);
|
||||
}
|
||||
|
||||
q = p;
|
||||
c = color;
|
||||
while (--q.x >= 0) {
|
||||
if ((q.x % 7) == 6) {
|
||||
c = getPatternColor(q, pattern);
|
||||
_display.setPixelPalette(q, c);
|
||||
}
|
||||
if (_display.getPixelBit(q) == stopBit)
|
||||
break;
|
||||
_display.setPixelBit(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) {
|
||||
_color = 0;
|
||||
_offset = pos;
|
||||
|
||||
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 0xf0:
|
||||
_color = 0x00;
|
||||
break;
|
||||
case 0xf1:
|
||||
_color = 0x2a;
|
||||
break;
|
||||
case 0xf2:
|
||||
_color = 0x55;
|
||||
break;
|
||||
case 0xf3:
|
||||
_color = 0x7f;
|
||||
break;
|
||||
case 0xf4:
|
||||
_color = 0x80;
|
||||
break;
|
||||
case 0xf5:
|
||||
_color = 0xaa;
|
||||
break;
|
||||
case 0xf6:
|
||||
_color = 0xd5;
|
||||
break;
|
||||
case 0xf7:
|
||||
_color = 0xff;
|
||||
break;
|
||||
case 0xff:
|
||||
return;
|
||||
default:
|
||||
error("Invalid pic opcode %02x", opcode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Adl
|
@ -11,8 +11,6 @@ MODULE_OBJS := \
|
||||
disk.o \
|
||||
display.o \
|
||||
graphics.o \
|
||||
graphics_v1.o \
|
||||
graphics_v2.o \
|
||||
hires0.o \
|
||||
hires1.o \
|
||||
hires2.o \
|
||||
|
Loading…
x
Reference in New Issue
Block a user