aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaweł Kołodziejski2003-04-30 05:48:55 +0000
committerPaweł Kołodziejski2003-04-30 05:48:55 +0000
commit39f85f7aac9493c3cc0200cad555a48cf2201af0 (patch)
tree8c420372780666c253191b166a83ff9d38b786b4
parent62aec0740245423b1c83394ba26f9d032ac1aa4c (diff)
downloadscummvm-rg350-39f85f7aac9493c3cc0200cad555a48cf2201af0.tar.gz
scummvm-rg350-39f85f7aac9493c3cc0200cad555a48cf2201af0.tar.bz2
scummvm-rg350-39f85f7aac9493c3cc0200cad555a48cf2201af0.zip
added gfx bitmap and zbuffer codec for v2 games
svn-id: r7209
-rw-r--r--scumm/gfx.cpp185
-rw-r--r--scumm/gfx.h2
-rw-r--r--scumm/scumm.h7
-rw-r--r--scumm/scummvm.cpp5
4 files changed, 188 insertions, 11 deletions
diff --git a/scumm/gfx.cpp b/scumm/gfx.cpp
index 40ec569879..c29f1912e0 100644
--- a/scumm/gfx.cpp
+++ b/scumm/gfx.cpp
@@ -848,6 +848,8 @@ void Gdi::drawBitmap(byte *ptr, VirtScreen *vs, int x, int y, const int h,
assert(smap_ptr);
+ byte *roomptr = _vm->getResourceAddress(rtRoom, _vm->_roomResource);
+
zplane_list[0] = smap_ptr;
if (_disable_zbuffer)
@@ -941,8 +943,12 @@ void Gdi::drawBitmap(byte *ptr, VirtScreen *vs, int x, int y, const int h,
_mask_ptr = _vm->getResourceAddress(rtBuffer, 9) + (y * _numStrips + x);
if (_vm->_features & GF_SMALL_HEADER) {
- if (_vm->_features & GF_16COLOR) {
- useOrDecompress = decompressBitmap(bgbak_ptr, smap_ptr + READ_LE_UINT16(smap_ptr + stripnr * 2 + 2), h);
+ if (_vm->_features & GF_AFTER_V2) {
+ decodeStripOldEGA(bgbak_ptr, roomptr + _vm->_egaStripOffsets[stripnr], h, stripnr);
+ useOrDecompress = false;
+ } else if (_vm->_features & GF_16COLOR) {
+ decodeStripEGA(bgbak_ptr, smap_ptr + READ_LE_UINT16(smap_ptr + stripnr * 2 + 2), h);
+ useOrDecompress = false;
} else {
useOrDecompress = decompressBitmap(bgbak_ptr, smap_ptr + READ_LE_UINT32(smap_ptr + stripnr * 4 + 4), h);
}
@@ -1002,7 +1008,9 @@ void Gdi::drawBitmap(byte *ptr, VirtScreen *vs, int x, int y, const int h,
if (!zplane_list[i])
continue;
- if (_vm->_features & GF_OLD_BUNDLE)
+ if (_vm->_features & GF_AFTER_V2)
+ offs = 0;
+ else if (_vm->_features & GF_OLD_BUNDLE)
offs = READ_LE_UINT16(zplane_list[i] + stripnr * 2);
else if (_vm->_features & GF_OLD256)
offs = READ_LE_UINT16(zplane_list[i] + stripnr * 2 + 4);
@@ -1018,7 +1026,9 @@ void Gdi::drawBitmap(byte *ptr, VirtScreen *vs, int x, int y, const int h,
if (offs) {
byte *z_plane_ptr = zplane_list[i] + offs;
- if (useOrDecompress && (flag & dbAllowMaskOr)) {
+ if (_vm->_features & GF_AFTER_V2)
+ decompressMaskImgOld(_mask_ptr_dest, roomptr + _vm->_egaStripZOffsets[stripnr], stripnr);
+ else if (useOrDecompress && (flag & dbAllowMaskOr)) {
decompressMaskImgOr(_mask_ptr_dest, z_plane_ptr, h);
} else {
decompressMaskImg(_mask_ptr_dest, z_plane_ptr, h);
@@ -1101,13 +1111,170 @@ void Gdi::decodeStripEGA(byte *dst, byte *src, int height) {
}
}
-bool Gdi::decompressBitmap(byte *bgbak_ptr, byte *smap_ptr, int numLinesToProcess) {
- assert(numLinesToProcess);
+void Scumm::buildStripOffsets() {
+ byte *roomptr = getResourceAddress(rtRoom, _roomResource);
+ byte *bitmap = roomptr + READ_LE_UINT16(roomptr + 10);
+ byte *zplane = roomptr + READ_LE_UINT16(roomptr + 12);
+ int room_width = READ_LE_UINT16(roomptr + 4) >> 3;
+ byte color, data;
+ int x, y, length;
+ int run = 1;
+
+ for (x = 0 ; x < room_width << 3; x++) {
+
+ if ((x % 8) == 0) {
+ _egaStripRun[x >> 3] = run;
+ _egaStripColor[x >> 3] = color;
+ _egaStripOffsets[x >> 3] = bitmap - roomptr;
+ }
+
+ for (y = 0; y < 128; y++) {
+ if (--run == 0) {
+ data = *bitmap++;
+ if (data & 0x80) {
+ run = data & 0x7f;
+ } else {
+ run = data >> 4;
+ }
+ if (run == 0) {
+ run = *bitmap++;
+ }
+ color = data & 0x0f;
+ }
+ }
+ }
- if (_vm->_features & GF_16COLOR) {
- decodeStripEGA(bgbak_ptr, smap_ptr, numLinesToProcess);
- return false;
+ x = 0;
+ y = 128;
+
+ for (;;) {
+ length = *zplane++;
+ if (length & 0x80) {
+ length &= 0x7f;
+ data = *zplane++;
+ do {
+ if (y == 128) {
+ _egaStripZOffsets[x] = zplane - roomptr - 1;
+ _egaStripZRun[x] = length | 0x80;
+ }
+ if (--y == 0) {
+ if (--room_width == 0)
+ return;
+ x++;
+ y = 128;
+ }
+ } while (--length);
+ } else {
+ do {
+ data = *zplane++;
+ if (y == 128) {
+ _egaStripZOffsets[x] = zplane - roomptr - 1;
+ _egaStripZRun[x] = length;
+ }
+ if (--y == 0) {
+ if (--room_width == 0)
+ return;
+ x++;
+ y = 128;
+ }
+ } while (--length);
+ }
}
+}
+
+void Gdi::decodeStripOldEGA(byte *dst, byte *src, int height, int stripnr) {
+ byte color = _vm->_egaStripColor[stripnr];
+ int run = _vm->_egaStripRun[stripnr];
+ bool dither = false;
+ byte dither_table[128];
+ byte data;
+ int x = 4;
+ do {
+ byte *ptr_dither_table = dither_table;
+ int y = 128;
+ do {
+ if (--run == 0) {
+ data = *src++;
+ if (data & 0x80) {
+ run = data & 0x7f;
+ dither = true;
+ } else {
+ run = data >> 4;
+ dither = false;
+ }
+ if (run == 0) {
+ run = *src++;
+ }
+ color = _vm->_shadowPalette[data & 0x0f];
+ }
+ if (!dither) {
+ *ptr_dither_table = color;
+ }
+ *dst = *ptr_dither_table++;
+ dst += _vm->_realWidth;
+ } while (--y);
+ dst -= _vm->_realWidth * 128;
+ dst++;
+
+ ptr_dither_table = dither_table;
+ y = 128;
+ do {
+ if (--run == 0) {
+ data = *src++;
+ if (data & 0x80) {
+ run = data & 0x7f;
+ dither = true;
+ } else {
+ run = data >> 4;
+ dither = false;
+ }
+ if (run == 0) {
+ run = *src++;
+ }
+ color = _vm->_shadowPalette[data & 0x0f];
+ }
+ if (!dither) {
+ *ptr_dither_table = color;
+ }
+ *dst = *ptr_dither_table++;
+
+ dst += _vm->_realWidth;
+ } while (--y);
+ dst -= _vm->_realWidth * 128;
+ dst++;
+ } while (--x);
+}
+
+void Gdi::decompressMaskImgOld(byte *dst, byte *src, int stripnr) {
+ int run = _vm->_egaStripRun[stripnr];
+ int y = 128;
+ byte data;
+
+ for (;;) {
+ if (run & 0x80) {
+ run &= 0x7f;
+ data = *src++;
+ do {
+ *dst++ = data;
+ dst += _numStrips;
+ if (--y == 0)
+ return;
+ } while (--run);
+ } else {
+ do {
+ data = *src++;
+ *dst++ = data;
+ dst += _numStrips;
+ if (--y == 0)
+ return;
+ } while (--run);
+ }
+ run = *src++;
+ }
+}
+
+bool Gdi::decompressBitmap(byte *bgbak_ptr, byte *smap_ptr, int numLinesToProcess) {
+ assert(numLinesToProcess);
byte code = *smap_ptr++;
diff --git a/scumm/gfx.h b/scumm/gfx.h
index 57205551a9..acdaa44eec 100644
--- a/scumm/gfx.h
+++ b/scumm/gfx.h
@@ -135,6 +135,8 @@ protected:
/* Bitmap decompressors */
bool decompressBitmap(byte *bgbak_ptr, byte *smap_ptr, int numLinesToProcess);
void decodeStripEGA(byte *dst, byte *src, int height);
+ void decodeStripOldEGA(byte *dst, byte *src, int height, int stripnr);
+ void decompressMaskImgOld(byte *dst, byte *src, int stripnr);
void unkDecodeA(byte *dst, byte *src, int height);
void unkDecodeA_trans(byte *dst, byte *src, int height);
void unkDecodeB(byte *dst, byte *src, int height);
diff --git a/scumm/scumm.h b/scumm/scumm.h
index 288849c9f8..bfee86cace 100644
--- a/scumm/scumm.h
+++ b/scumm/scumm.h
@@ -749,6 +749,13 @@ public:
uint32 _CLUT_offs;
uint32 _IM00_offs, _PALS_offs;
+ void buildStripOffsets();
+ int _egaStripOffsets[160];
+ int _egaStripRun[160];
+ byte _egaStripColor[160];
+ int _egaStripZOffsets[120];
+ int _egaStripZRun[120];
+
//ender: fullscreen
bool _fullRedraw, _BgNeedsRedraw, _verbRedraw;
bool _screenEffectFlag, _completeScreenRedraw;
diff --git a/scumm/scummvm.cpp b/scumm/scummvm.cpp
index d290b7e033..32844a0d01 100644
--- a/scumm/scummvm.cpp
+++ b/scumm/scummvm.cpp
@@ -912,9 +912,10 @@ void Scumm::initRoomSubBlocks() {
//
// Find the room image data
//
- if (_features & GF_OLD_BUNDLE)
+ if (_features & GF_OLD_BUNDLE) {
_IM00_offs = READ_LE_UINT16(roomptr + 0x0A);
- else if (_features & GF_SMALL_HEADER)
+ buildStripOffsets();
+ } else if (_features & GF_SMALL_HEADER)
_IM00_offs = findResourceData(MKID('IM00'), roomptr) - roomptr;
else if (_features & GF_AFTER_V8) {
ptr = findResource(MKID('IMAG'), roomptr);