aboutsummaryrefslogtreecommitdiff
path: root/graphics
diff options
context:
space:
mode:
Diffstat (limited to 'graphics')
-rw-r--r--graphics/VectorRenderer.h11
-rw-r--r--graphics/cursorman.cpp6
-rw-r--r--graphics/cursorman.h27
-rw-r--r--graphics/iff.cpp258
-rw-r--r--graphics/iff.h101
5 files changed, 222 insertions, 181 deletions
diff --git a/graphics/VectorRenderer.h b/graphics/VectorRenderer.h
index acc2f77357..136a8d55b3 100644
--- a/graphics/VectorRenderer.h
+++ b/graphics/VectorRenderer.h
@@ -37,6 +37,10 @@
namespace Graphics {
class VectorRenderer;
+
+typedef void (VectorRenderer::*DrawingFunctionCallback)(const Common::Rect &, const Graphics::DrawStep &);
+
+
struct DrawStep {
struct Color {
uint8 r, g, b;
@@ -59,7 +63,10 @@ struct DrawStep {
kVectorAlignBottom,
kVectorAlignTop,
kVectorAlignCenter
- } xAlign, yAlign;
+ };
+
+ VectorAlignment xAlign;
+ VectorAlignment yAlign;
uint8 shadow, stroke, factor, radius, bevel; /**< Misc options... */
@@ -68,7 +75,7 @@ struct DrawStep {
uint32 scale; /**< scale of all the coordinates in FIXED POINT with 16 bits mantissa */
- void (VectorRenderer::*drawingCall)(const Common::Rect &, const DrawStep &); /** Pointer to drawing function */
+ DrawingFunctionCallback drawingCall; /**< Pointer to drawing function */
Graphics::Surface *blitSrc;
};
diff --git a/graphics/cursorman.cpp b/graphics/cursorman.cpp
index fe5f653b94..2e71b548bc 100644
--- a/graphics/cursorman.cpp
+++ b/graphics/cursorman.cpp
@@ -129,6 +129,10 @@ void CursorManager::replaceCursor(const byte *buf, uint w, uint h, int hotspotX,
g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, targetScale);
}
+bool CursorManager::supportsCursorPalettes() {
+ return g_system->hasFeature(OSystem::kFeatureCursorHasPalette);
+}
+
void CursorManager::disableCursorPalette(bool disable) {
if (!g_system->hasFeature(OSystem::kFeatureCursorHasPalette))
return;
@@ -139,7 +143,7 @@ void CursorManager::disableCursorPalette(bool disable) {
Palette *pal = _cursorPaletteStack.top();
pal->_disabled = disable;
- g_system->disableCursorPalette(true);
+ g_system->disableCursorPalette(disable);
}
void CursorManager::pushCursorPalette(const byte *colors, uint start, uint num) {
diff --git a/graphics/cursorman.h b/graphics/cursorman.h
index bc38466eda..f019e37b04 100644
--- a/graphics/cursorman.h
+++ b/graphics/cursorman.h
@@ -36,7 +36,21 @@ public:
/** Query whether the mouse cursor is visible. */
bool isVisible();
- /** Show or hide the mouse cursor. */
+ /**
+ * Show or hide the mouse cursor.
+ *
+ * This function does not call OSystem::updateScreen, when visible is true.
+ * This fact might result in a non visible mouse cursor if the caller does
+ * not call OSystem::updateScreen itself after a showMouse(true) call.
+ *
+ * TODO: We might want to reconsider this behavior, it might be confusing
+ * for the user to call OSystem::updateScreen separately, on the other
+ * hand OSystem::updateScreen might as well display unwanted changes on
+ * the screen. Another alternative would be to let the backend worry
+ * about this on OSystem::showMouse call.
+ *
+ * @see OSystem::showMouse.
+ */
bool showMouse(bool visible);
/**
@@ -88,6 +102,17 @@ public:
void popAllCursors();
/**
+ * Test whether cursor palettes are supported.
+ *
+ * This is just an convenience wrapper for checking for
+ * OSystem::kFeatureCursorHasPalette to be supported by OSystem.
+ *
+ * @see OSystem::kFeatureCursorHasPalette
+ * @see OSystem::hasFeature
+ */
+ bool supportsCursorPalettes();
+
+ /**
* Enable/Disable the current cursor palette.
*
* @param disable
diff --git a/graphics/iff.cpp b/graphics/iff.cpp
index ea6447ac01..902f97499a 100644
--- a/graphics/iff.cpp
+++ b/graphics/iff.cpp
@@ -48,194 +48,179 @@ char *ID2string(Common::IFF_ID id) {
namespace Graphics {
-
-void fillBMHD(BMHD &bitmapHeader, Common::ReadStream &stream) {
-
- bitmapHeader.width = stream.readUint16BE();
- bitmapHeader.height = stream.readUint16BE();
- bitmapHeader.x = stream.readUint16BE();
- bitmapHeader.y = stream.readUint16BE();
- bitmapHeader.depth = stream.readByte();
- bitmapHeader.masking = stream.readByte();
- bitmapHeader.pack = stream.readByte();
- bitmapHeader.flags = stream.readByte();
- bitmapHeader.transparentColor = stream.readUint16BE();
- bitmapHeader.xAspect = stream.readByte();
- bitmapHeader.yAspect = stream.readByte();
- bitmapHeader.pageWidth = stream.readUint16BE();
- bitmapHeader.pageHeight = stream.readUint16BE();
-
+void BMHD::load(Common::ReadStream *stream) {
+ assert(stream);
+ stream->read(this, sizeof(BMHD));
+ width = FROM_BE_16(width);
+ height = FROM_BE_16(height);
+ x = FROM_BE_16(x);
+ y = FROM_BE_16(y);
+ transparentColor = FROM_BE_16(transparentColor);
+ pageWidth = FROM_BE_16(pageWidth);
+ pageHeight = FROM_BE_16(pageHeight);
}
-ILBMDecoder::ILBMDecoder(Common::ReadStream &input, Surface &surface, byte *&colors) : IFFParser(input), _surface(&surface), _colors(&colors) {
- if (_typeId != ID_ILBM)
- error("unsupported IFF subtype '%s'", Common::ID2string(_typeId));
+void ILBMDecoder::loadHeader(Common::ReadStream *stream) {
+ _header.load(stream);
}
-void ILBMDecoder::decode() {
-
- Common::IFFChunk *chunk;
- while ((chunk = nextChunk()) != 0) {
- switch (chunk->id) {
- case ID_BMHD:
- readBMHD(*chunk);
- break;
+void ILBMDecoder::loadBitmap(uint32 mode, byte *buffer, Common::ReadStream *stream) {
+ assert(stream);
+ uint32 numPlanes = MIN(mode & ILBM_UNPACK_PLANES, (uint32)_header.depth);
+ assert(numPlanes == 1 || numPlanes == 2 || numPlanes == 3 || numPlanes == 4 || numPlanes == 5 || numPlanes == 8);
- case ID_CMAP:
- readCMAP(*chunk);
- break;
-
- case ID_BODY:
- readBODY(*chunk);
- break;
- }
+ bool packPixels = (mode & ILBM_PACK_PLANES) != 0;
+ if (numPlanes != 1 && numPlanes != 2 && numPlanes != 4) {
+ packPixels = false;
}
- return;
-}
+ uint32 outPitch = _header.width;
+ if (packPixels) {
+ outPitch /= (8 / numPlanes);
+ }
+ byte *out = buffer;
-void ILBMDecoder::readBMHD(Common::IFFChunk &chunk) {
+ switch (_header.pack) {
+ case 1: { // PackBits compressed bitmap
+ Graphics::PackBitsReadStream packStream(*stream);
- fillBMHD(_bitmapHeader, chunk);
+ // setup a buffer to hold enough data to build a line in the output
+ uint32 scanlineWidth = ((_header.width + 15)/16) << 1;
+ byte *scanline = new byte[scanlineWidth * _header.depth];
- _colorCount = 1 << _bitmapHeader.depth;
- *_colors = (byte*)malloc(sizeof(**_colors) * _colorCount * 3);
- _surface->create(_bitmapHeader.width, _bitmapHeader.height, 1);
+ for (uint i = 0; i < _header.height; ++i) {
+ byte *s = scanline;
+ for (uint32 j = 0; j < _header.depth; ++j) {
+ packStream.read(s, scanlineWidth);
+ s += scanlineWidth;
+ }
-}
+ planarToChunky(out, outPitch, scanline, scanlineWidth, numPlanes, packPixels);
+ out += outPitch;
+ }
-void ILBMDecoder::readCMAP(Common::IFFChunk &chunk) {
- if (*_colors == NULL) {
- error("wrong input chunk sequence");
+ delete []scanline;
+ break;
}
- for (uint32 i = 0; i < _colorCount; i++) {
- (*_colors)[i * 3 + 0] = chunk.readByte();
- (*_colors)[i * 3 + 1] = chunk.readByte();
- (*_colors)[i * 3 + 2] = chunk.readByte();
+
+ default:
+ // implement other compression types here!
+ error("only RLE compressed ILBM files are supported");
+ break;
}
}
-void ILBMDecoder::readBODY(Common::IFFChunk& chunk) {
+void ILBMDecoder::planarToChunky(byte *out, uint32 outPitch, byte *in, uint32 inWidth, uint32 nPlanes, bool packPlanes) {
+ byte pix, ofs, bit;
+ byte *s;
- switch (_bitmapHeader.pack) {
- case 0:
- error("unpacked ILBM files are not supported");
- break;
+ uint32 pixels = outPitch;
+ if (packPlanes) {
+ pixels *= (8 / nPlanes);
+ }
- case 1: {
- uint32 scanWidth = (_bitmapHeader.width + 7) >> 3;
- byte *scan = (byte*)malloc(scanWidth);
- byte *out = (byte*)_surface->pixels;
+ for (uint32 x = 0; x < pixels; ++x) {
- PackBitsReadStream stream(chunk);
+ pix = 0;
+ ofs = x >> 3;
+ bit = 0x80 >> (x & 7);
- for (uint32 i = 0; i < _bitmapHeader.height; i++) {
- for (uint32 j = 0; j < _bitmapHeader.depth; j++) {
- stream.read(scan, scanWidth);
- fillPlane(out, scan, scanWidth, j);
+ // first build a pixel by scanning all the usable planes in the input
+ s = in;
+ for (uint32 plane = 0; plane < nPlanes; ++plane) {
+ if (s[ofs] & bit) {
+ pix |= (1 << plane);
}
-
- out += _bitmapHeader.width;
+ s += inWidth;
}
- free(scan);
- break;
- }
-
- }
-}
-void ILBMDecoder::fillPlane(byte *out, byte* buf, uint32 width, uint32 plane) {
- byte src, idx, set;
- byte mask = 1 << plane;
-
- for (uint32 j = 0; j < _bitmapHeader.width; j++) {
- src = buf[j >> 3];
- idx = 7 - (j & 7);
- set = src & (1 << idx);
-
- if (set)
- out[j] |= mask;
+ // then output the pixel according to the requested packing
+ if (!packPlanes) {
+ out[x] = pix;
+ } else
+ if (nPlanes == 1) {
+ out[x/8] |= (pix << (x & 7));
+ } else
+ if (nPlanes == 2) {
+ out[x/4] |= (pix << ((x & 3) << 1));
+ } else
+ if (nPlanes == 4) {
+ out[x/2] |= (pix << ((x & 1) << 2));
+ }
}
}
-
-
-PBMDecoder::PBMDecoder(Common::ReadStream &input, Surface &surface, byte *&colors) : IFFParser(input), _surface(&surface), _colors(&colors) {
- if (_typeId != ID_PBM)
- error("unsupported IFF subtype '%s'", Common::ID2string(_typeId));
+void PBMDecoder::loadHeader(Common::ReadStream *stream) {
+ _header.load(stream);
}
-void PBMDecoder::decode() {
- Common::IFFChunk *chunk;
- while ((chunk = nextChunk()) != 0) {
- switch (chunk->id) {
- case ID_BMHD:
- readBMHD(*chunk);
- break;
+void PBMDecoder::loadBitmap(byte *buffer, Common::ReadStream *stream) {
+ uint32 outSize = _header.width * _header.height;
- case ID_CMAP:
- readCMAP(*chunk);
- break;
+ switch (_header.pack) {
+ case 0:
+ stream->read(buffer, outSize);
+ break;
- case ID_BODY:
- readBODY(*chunk);
- break;
+ case 1: {
+ PackBitsReadStream packStream(*stream);
+ packStream.read(buffer, outSize);
+ break;
}
}
-
- return;
}
-void PBMDecoder::readBMHD(Common::IFFChunk &chunk) {
- fillBMHD(_bitmapHeader, chunk);
+struct PBMLoader {
+ PBMDecoder _decoder;
+ Surface *_surface;
+ byte *_colors;
- _colorCount = 1 << _bitmapHeader.depth;
- *_colors = (byte*)malloc(sizeof(**_colors) * _colorCount * 3);
- _surface->create(_bitmapHeader.width, _bitmapHeader.height, 1);
-
-}
-
-void PBMDecoder::readCMAP(Common::IFFChunk &chunk) {
- if (*_colors == NULL) {
- error("wrong input chunk sequence");
- }
- for (uint32 i = 0; i < _colorCount; i++) {
- (*_colors)[i * 3 + 0] = chunk.readByte();
- (*_colors)[i * 3 + 1] = chunk.readByte();
- (*_colors)[i * 3 + 2] = chunk.readByte();
+ void load(Common::ReadStream &input, Surface &surface, byte *&colors) {
+ _surface = &surface;
+ _colors = colors;
+ Common::IFFParser parser(&input);
+ Common::Functor1Mem< Common::IFFChunk&, bool, PBMLoader > c(this, &PBMLoader::callback);
+ parser.parse(c);
}
-}
-void PBMDecoder::readBODY(Common::IFFChunk& chunk) {
+ bool callback(Common::IFFChunk &chunk) {
+ switch (chunk._type) {
+ case ID_BMHD:
+ _decoder.loadHeader(chunk._stream);
+ break;
- uint si = 0;
+ case ID_CMAP:
+ if (_colors) {
+ chunk._stream->read(_colors, chunk._size);
+ }
+ break;
- switch (_bitmapHeader.pack) {
- case 0:
- while (!chunk.hasReadAll()) {
- ((byte*)_surface->pixels)[si++] = chunk.readByte();
+ case ID_BODY:
+ if (_surface) {
+ _surface->create(_decoder._header.width, _decoder._header.height, 1);
+ _decoder.loadBitmap((byte*)_surface->pixels, chunk._stream);
+ }
+ return true; // stop the parser
}
- break;
- case 1: {
- PackBitsReadStream stream(chunk);
- stream.read((byte*)_surface->pixels, _surface->w * _surface->h);
- break;
+ return false;
}
+};
- }
+void decodePBM(Common::ReadStream &input, Surface &surface, byte *colors) {
+ PBMLoader loader;
+ loader.load(input, surface, colors);
}
-
PackBitsReadStream::PackBitsReadStream(Common::ReadStream &input) : _input(&input) {
}
@@ -282,9 +267,4 @@ uint32 PackBitsReadStream::read(void *dataPtr, uint32 dataSize) {
}
-void decodePBM(Common::ReadStream &input, Surface &surface, byte *&colors) {
- PBMDecoder decoder(input, surface, colors);
- decoder.decode();
-}
-
}
diff --git a/graphics/iff.h b/graphics/iff.h
index 13b82a673c..fc1b6ceefa 100644
--- a/graphics/iff.h
+++ b/graphics/iff.h
@@ -52,55 +52,80 @@ struct BMHD {
BMHD() {
memset(this, 0, sizeof(*this));
}
-};
-
-// handles ILBM subtype of IFF FORM files
-//
-class ILBMDecoder : public Common::IFFParser {
+ void load(Common::ReadStream *stream);
+};
-protected:
- void readBMHD(Common::IFFChunk &chunk);
- void readCMAP(Common::IFFChunk &chunk);
- void readBODY(Common::IFFChunk &chunk);
- BMHD _bitmapHeader;
- uint32 _colorCount;
+struct ILBMDecoder {
+ /**
+ * ILBM header data, necessary for loadBitmap()
+ */
+ Graphics::BMHD _header;
+
+ /**
+ * Available decoding modes for loadBitmap().
+ */
+ enum {
+ ILBM_UNPACK_PLANES = 0xFF, //!< Decode all bitplanes, and map 1 pixel to 1 byte.
+ ILBM_PACK_PLANES = 0x100, //!< Request unpacking, used as a mask with below options.
+
+ ILBM_1_PLANES = 1, //!< Decode only the first bitplane, don't pack.
+ ILBM_1_PACK_PLANES = ILBM_1_PLANES | ILBM_PACK_PLANES, //!< Decode only the first bitplane, pack 8 pixels in 1 byte.
+ ILBM_2_PLANES = 2, //!< Decode first 2 bitplanes, don't pack.
+ ILBM_2_PACK_PLANES = ILBM_2_PLANES | ILBM_PACK_PLANES, //!< Decode first 2 bitplanes, pack 4 pixels in 1 byte.
+ ILBM_3_PLANES = 3, //!< Decode first 3 bitplanes, don't pack.
+ ILBM_4_PLANES = 4, //!< Decode first 4 bitplanes, don't pack.
+ ILBM_4_PACK_PLANES = ILBM_4_PLANES | ILBM_PACK_PLANES, //!< Decode first 4 bitplanes, pack 2 pixels in 1 byte.
+ ILBM_5_PLANES = 5, //!< Decode first 5 bitplanes, don't pack.
+ ILBM_8_PLANES = 8 //!< Decode all 8 bitplanes.
+ };
+
+ /**
+ * Fills the _header member from the given stream.
+ */
+ void loadHeader(Common::ReadStream *stream);
+
+ /**
+ * Loads and unpacks the ILBM bitmap data from the stream into the buffer.
+ * The functions assumes the buffer is large enough to contain all data.
+ * The caller controls how data should be packed by choosing mode from
+ * the enum above.
+ */
+ void loadBitmap(uint32 mode, byte *buffer, Common::ReadStream *stream);
+
+ /**
+ * Converts from bitplanar to chunky representation. Intended for internal
+ * usage, but you can be (ab)use it from client code if you know what you
+ * are doing.
+ */
+ void planarToChunky(byte *out, uint32 width, byte *in, uint32 planeWidth, uint32 nPlanes, bool packPlanes);
+};
- Surface *_surface;
- byte **_colors;
- void fillPlane(byte *out, byte* buf, uint32 width, uint32 plane);
-
-public:
- ILBMDecoder(Common::ReadStream &input, Surface &surface, byte *&colors);
- virtual ~ILBMDecoder() { }
- void decode();
-};
// handles PBM subtype of IFF FORM files
//
-class PBMDecoder : public Common::IFFParser {
-
-protected:
- void readBMHD(Common::IFFChunk &chunk);
- void readCMAP(Common::IFFChunk &chunk);
- void readBODY(Common::IFFChunk &chunk);
-
- BMHD _bitmapHeader;
- uint32 _colorCount;
-
- Surface *_surface;
- byte **_colors;
-
-public:
- PBMDecoder(Common::ReadStream &input, Surface &surface, byte *&colors);
- virtual ~PBMDecoder() { }
- void decode();
+struct PBMDecoder {
+ /**
+ * PBM header data, necessary for loadBitmap()
+ */
+ Graphics::BMHD _header;
+
+ /**
+ * Fills the _header member from the given stream.
+ */
+ void loadHeader(Common::ReadStream *stream);
+
+ /**
+ * Loads and unpacks the PBM bitmap data from the stream into the buffer.
+ * The functions assumes the buffer is large enough to contain all data.
+ */
+ void loadBitmap(byte *buffer, Common::ReadStream *stream);
};
-void decodePBM(Common::ReadStream &input, Surface &surface, byte *&colors);
+void decodePBM(Common::ReadStream &input, Surface &surface, byte *colors);
/*