[Scummvm-cvs-logs] SF.net SVN: scummvm:[54913] scummvm/trunk/engines/mohawk
mthreepwood at users.sourceforge.net
mthreepwood at users.sourceforge.net
Tue Dec 14 23:59:40 CET 2010
Revision: 54913
http://scummvm.svn.sourceforge.net/scummvm/?rev=54913&view=rev
Author: mthreepwood
Date: 2010-12-14 22:59:39 +0000 (Tue, 14 Dec 2010)
Log Message:
-----------
MOHAWK: Add support for DOS bitmaps (thanks to fuzzie for the EGA planar code)
Modified Paths:
--------------
scummvm/trunk/engines/mohawk/bitmap.cpp
scummvm/trunk/engines/mohawk/bitmap.h
Modified: scummvm/trunk/engines/mohawk/bitmap.cpp
===================================================================
--- scummvm/trunk/engines/mohawk/bitmap.cpp 2010-12-14 22:58:51 UTC (rev 54912)
+++ scummvm/trunk/engines/mohawk/bitmap.cpp 2010-12-14 22:59:39 UTC (rev 54913)
@@ -759,4 +759,122 @@
return mhkSurface;
}
+// Partially based on the Prince of Persia Format Specifications
+// See http://sdfg.com.ar/git/?p=fp-git.git;a=blob;f=FP/doc/FormatSpecifications
+
+MohawkSurface *DOSBitmap::decodeImage(Common::SeekableReadStream *stream) {
+ _header.height = stream->readUint16LE();
+ _header.width = stream->readUint16LE();
+ stream->readByte(); // Always 0
+ _header.format = stream->readByte();
+
+ debug(2, "Decoding DOS Bitmap (%dx%d, %dbpp, Compression %d)", _header.width, _header.height, getBitsPerPixel(), _header.format & 0xf);
+
+ // All the PoP games seem to have this flag, but at least CSWorld Deluxe doesn't...
+ // Perhaps this differentiates between normal bitmap mode and planar mode?
+ if (_header.format & 0x80)
+ error("Unknown EGA flag?");
+
+ // Calculate the bytes per row
+ byte pixelsPerByte = 8 / getBitsPerPixel();
+ _header.bytesPerRow = (_header.width + pixelsPerByte - 1) / pixelsPerByte;
+
+ // Only Raw and LZ L/R are supported currently
+ // Notice how Broderbund used their same LZ compression for every PC game possibly ever?
+ switch (_header.format & 0xf) {
+ case 0: // Raw
+ _data = stream;
+ break;
+ case 3: // LZ Left/Right
+ _data = decompressLZ(stream, _header.bytesPerRow * _header.height);
+ delete stream;
+ break;
+ case 1: // RLE Left/Right (Used by PoP, haven't seen in a CS game)
+ case 2: // RLE Up/Down (Used by PoP, haven't seen in a CS game)
+ case 4: // LZ Up/Down (Used by CS America's Past and CS Space)
+ error("Unhandled DOS bitmap compression %d", _header.format & 0xf);
+ break;
+ default:
+ error("Unknown DOS bitmap compression %d", _header.format & 0xf);
+ }
+
+ Graphics::Surface *surface = createSurface(_header.width, _header.height);
+ memset(surface->pixels, 0, _header.width * _header.height);
+
+ // Expand the <8bpp data to one byte per pixel
+ switch (getBitsPerPixel()) {
+ case 1:
+ expandMonochromePlane(surface, _data);
+ break;
+ case 4:
+ expandEGAPlanes(surface, _data);
+ break;
+ default:
+ error("Unhandled %dbpp", getBitsPerPixel());
+ }
+
+ delete _data;
+
+ return new MohawkSurface(surface);
+}
+
+void DOSBitmap::expandMonochromePlane(Graphics::Surface *surface, Common::SeekableReadStream *rawStream) {
+ assert(surface->bytesPerPixel == 1);
+
+ byte *dst = (byte *)surface->pixels;
+
+ // Expand the 8 pixels in a byte into a full byte per pixel
+
+ for (uint32 i = 0; i < surface->h; i++) {
+ for (uint x = 0; x < surface->w;) {
+ byte temp = rawStream->readByte();
+
+ for (int j = 7; j >= 0 && x < surface->w; j--) {
+ if (temp & (1 << j))
+ *dst++ = 0xf;
+ else
+ *dst++ = 0;
+
+ x++;
+ }
+ }
+ }
+}
+
+#define ADD_BIT(dstPixel, srcBit) \
+ *(dst + j * 4 + dstPixel) = (*(dst + j * 4 + dstPixel) >> 1) | (((temp >> srcBit) & 1) << 3)
+
+void DOSBitmap::expandEGAPlanes(Graphics::Surface *surface, Common::SeekableReadStream *rawStream) {
+ assert(surface->bytesPerPixel == 1);
+
+ // Note that the image is in EGA planar form and not just standard 4bpp
+ // This seems to contradict the PoP specs which seem to do
+
+ byte *dst = (byte *)surface->pixels;
+
+ for (uint32 i = 0; i < surface->h; i++) {
+ uint x = 0;
+
+ for (int32 j = 0; j < surface->w / 4; j++) {
+ byte temp = rawStream->readByte();
+ ADD_BIT(3, 4);
+ ADD_BIT(2, 5);
+ ADD_BIT(1, 6);
+ ADD_BIT(0, 7);
+ j++;
+ ADD_BIT(3, 0);
+ ADD_BIT(2, 1);
+ ADD_BIT(1, 2);
+ ADD_BIT(0, 3);
+
+ if (x < 3 && j + 1 >= surface->w / 4) {
+ j = -1;
+ x++;
+ }
+ }
+
+ dst += surface->w;
+ }
+}
+
} // End of namespace Mohawk
Modified: scummvm/trunk/engines/mohawk/bitmap.h
===================================================================
--- scummvm/trunk/engines/mohawk/bitmap.h 2010-12-14 22:58:51 UTC (rev 54912)
+++ scummvm/trunk/engines/mohawk/bitmap.h 2010-12-14 22:59:39 UTC (rev 54913)
@@ -188,6 +188,21 @@
byte getBitsPerPixel() { return 8; }
};
+class DOSBitmap : public MohawkBitmap {
+public:
+ DOSBitmap() : MohawkBitmap() {}
+ ~DOSBitmap() {}
+
+ MohawkSurface *decodeImage(Common::SeekableReadStream *stream);
+
+protected:
+ byte getBitsPerPixel() { return ((_header.format & 0x30) >> 4) + 1; }
+
+private:
+ void expandMonochromePlane(Graphics::Surface *surface, Common::SeekableReadStream *rawStream);
+ void expandEGAPlanes(Graphics::Surface *surface, Common::SeekableReadStream *rawStream);
+};
+
} // End of namespace Mohawk
#endif
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list