22 #ifndef ADL_GRAPHICS_H 23 #define ADL_GRAPHICS_H 25 #include "common/rect.h" 26 #include "common/stream.h" 28 #include "adl/display.h" 41 virtual void clearScreen()
const = 0;
57 void clearScreen()
const override;
64 void drawShapePixel(
Common::Point &p, byte color, byte bits, byte quadrant)
const;
65 virtual byte getClearColor()
const {
return 0x00; }
76 bool canFillAt(
const Common::Point &p,
const bool stopBit =
false);
77 void fillRow(
Common::Point p,
const byte pattern,
const bool stopBit =
false);
87 virtual void fillRowLeft(
Common::Point p,
const byte pattern,
const bool stopBit);
89 byte getClearColor()
const override {
return 0xff; }
102 void fillRowLeft(
Common::Point p,
const byte pattern,
const bool stopBit)
override;
108 _display.setMode(Display::kModeMixed);
109 _display.clear(getClearColor());
115 int16 deltaX = p2.
x - p1.
x;
123 int16 deltaY = p2.
y - p1.
y;
132 int16 steps = deltaX - deltaY + 1;
133 int16 err = deltaX + deltaY;
153 if (this->_bounds.contains(p))
154 _display.putPixel(p, color);
165 p.
x += (bits & 2 ? -1 : 1);
167 p.
y += (bits & 2 ? 1 : -1);
172 const byte stepping[] = {
173 0xff, 0xfe, 0xfa, 0xf4, 0xec, 0xe1, 0xd4, 0xc5,
174 0xb4, 0xa1, 0x8d, 0x78, 0x61, 0x49, 0x31, 0x18,
178 byte quadrant = rotation >> 4;
180 byte xStep = stepping[rotation];
181 byte yStep = stepping[(rotation ^ 0xf) + 1] + 1;
186 if (corners.
eos() || corners.
err())
187 error(
"Error reading corners");
195 for (uint j = 0; j < scaling; ++j) {
196 if (xFrac + xStep + 1 > 255)
197 drawShapePixel(pos, color, b, quadrant);
199 if (yFrac + yStep > 255)
200 drawShapePixel(pos, color, b, quadrant + 1);
211 bool bNewLine =
false;
212 byte oldX = 0, oldY = 0;
217 if (pic.
err() || pic.
eos())
218 error(
"Error reading picture");
220 if (x == 0xff && y == 0xff)
223 if (x == 0 && y == 0) {
250 if (pic.
eos() || pic.
err())
251 error(
"Error reading picture");
254 pic.
seek(-1, SEEK_CUR);
265 if (!readByte(pic, b))
271 if (!readByte(pic, b))
281 const byte fillPatterns[][4] = {
282 { 0x00, 0x00, 0x00, 0x00 },
283 { 0x80, 0x80, 0x80, 0x80 },
284 { 0xff, 0xff, 0xff, 0xff },
285 { 0x7f, 0x7f, 0x7f, 0x7f },
286 { 0x2a, 0x55, 0x2a, 0x55 },
287 { 0xaa, 0xd5, 0xaa, 0xd5 },
288 { 0x55, 0x2a, 0x55, 0x2a },
289 { 0xd5, 0xaa, 0xd5, 0xaa },
290 { 0x33, 0x66, 0x4c, 0x19 },
291 { 0xb3, 0xe6, 0xcc, 0x99 },
292 { 0x22, 0x44, 0x08, 0x11 },
293 { 0xa2, 0xc4, 0x88, 0x91 },
294 { 0x11, 0x22, 0x44, 0x08 },
295 { 0x91, 0xa2, 0xc4, 0x88 },
296 { 0x6e, 0x5d, 0x3b, 0x77 },
297 { 0xee, 0xdd, 0xbb, 0xf7 },
298 { 0x5d, 0x3b, 0x77, 0x6e },
299 { 0xdd, 0xbb, 0xf7, 0xee },
300 { 0x66, 0x4c, 0x19, 0x33 },
301 { 0xe6, 0xcc, 0x99, 0xb3 },
302 { 0x33, 0x66, 0x4c, 0x19 },
303 { 0xb3, 0xe6, 0xcc, 0x99 }
307 error(
"Invalid fill pattern %i encountered in picture", pattern);
309 byte offset = (p.
y & 1) << 1;
310 offset += (p.
x / 7) & 3;
312 return fillPatterns[pattern][offset %
sizeof(fillPatterns[0])];
319 if (!readPoint(pic, p))
329 if (!readByte(pic, b))
334 this->putPixel(p, _color);
341 if (!readByte(pic, b))
346 this->putPixel(p, _color);
360 if (!readPoint(pic, p1))
363 this->putPixel(p1, _color);
370 if (!readByte(pic, n))
373 byte h = (n & 0x70) >> 4;
386 this->drawLine(p1, p2, _color);
395 if (!readPoint(pic, p1))
398 this->putPixel(p1, _color);
403 if (!readPoint(pic, p2))
406 this->drawLine(p1, p2, _color);
413 return this->_display.getPixelBit(p) != stopBit && this->_display.getPixelBit(
Common::Point(p.
x + 1, p.
y)) != stopBit;
418 byte color = getPatternColor(p, pattern);
420 while (--p.
x >= this->_bounds.left) {
421 if ((p.
x % 7) == 6) {
422 color = getPatternColor(p, pattern);
423 this->_display.setPixelPalette(p, color);
425 if (this->_display.getPixelBit(p) == stopBit)
427 this->_display.setPixelBit(p, color);
434 byte color = getPatternColor(p, pattern);
435 this->_display.setPixelPalette(p, color);
436 this->_display.setPixelBit(p, color);
439 fillRowLeft(p, pattern, stopBit);
442 while (++p.
x < this->_bounds.right) {
443 if ((p.
x % 7) == 0) {
444 color = getPatternColor(p, pattern);
446 this->_display.setPixelPalette(p, color);
448 if (this->_display.getPixelBit(p) == stopBit)
450 this->_display.setPixelBit(p, color);
456 const bool stopBit = !this->_display.getPixelBit(p);
459 while (--p.
y >= this->_bounds.top && canFillAt(p, stopBit)) {}
462 while (++p.
y < this->_bounds.bottom && canFillAt(p, stopBit))
463 fillRow(p, pattern, stopBit);
470 if (!readByte(pic, pattern))
476 if (!readPoint(pic, p))
479 if (this->_bounds.contains(p))
496 if (pic.
eos() || pic.
err())
497 error(
"Error reading picture");
501 drawCorners(pic,
false);
504 drawCorners(pic,
true);
507 drawRelativeLines(pic);
510 drawAbsoluteLines(pic);
547 error(
"Invalid pic opcode %02x", opcode);
549 warning(
"Expected pic opcode, but found data byte %02x", opcode);
556 byte color = this->getPatternColor(p, pattern);
558 while (--p.
x >= this->_bounds.left) {
560 if (!this->_display.getPixelBit(p))
562 if ((p.
x % 7) == 6) {
563 color = this->getPatternColor(p, pattern);
564 this->_display.setPixelPalette(p, color);
566 this->_display.setPixelBit(p, color);
573 if (!this->canFillAt(p))
576 this->fillRow(p, pattern);
581 while (--q.
y >= this->_bounds.top && this->canFillAt(q))
582 this->fillRow(q, pattern);
585 while (++p.
y < this->_bounds.bottom && this->canFillAt(p))
586 this->fillRow(p, pattern);
#define ARRAYSIZE(x)
Definition: util.h:91
virtual bool err() const
Definition: stream.h:61
void warning(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
virtual bool seek(int64 offset, int whence=SEEK_SET)=0
virtual bool eos() const =0
Definition: graphics.h:32
Definition: graphics.h:70
byte readByte()
Definition: stream.h:434
Definition: graphics.h:97
Definition: graphics.h:50
void NORETURN_PRE error(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
int16 x
Definition: rect.h:46
signed char * fill(signed char *first, signed char *last, Value val)
Definition: algorithm.h:168
int16 y
Definition: rect.h:47