diff options
Diffstat (limited to 'engines')
| -rw-r--r-- | engines/adl/display.cpp | 22 | ||||
| -rw-r--r-- | engines/adl/display.h | 2 | ||||
| -rw-r--r-- | engines/adl/hires2.cpp | 14 | ||||
| -rw-r--r-- | engines/adl/module.mk | 3 | ||||
| -rw-r--r-- | engines/adl/picture.cpp | 298 | ||||
| -rw-r--r-- | engines/adl/picture.h | 56 | 
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  | 
