aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorathrxx2011-12-05 07:39:16 +0100
committerJohannes Schickel2011-12-26 16:18:16 +0100
commit4c6302943b1122703241686a66c1f90b2ee4a209 (patch)
treeb97189a2561a68dbba0d4729f05adee57ed00879
parent6c8fb30cbd80660bc3882ca0c0895dec8cbc4108 (diff)
downloadscummvm-rg350-4c6302943b1122703241686a66c1f90b2ee4a209.tar.gz
scummvm-rg350-4c6302943b1122703241686a66c1f90b2ee4a209.tar.bz2
scummvm-rg350-4c6302943b1122703241686a66c1f90b2ee4a209.zip
KYRA: implement Screen::decodeFrame1()
(required for decoding some EGA bitmaps in EOB1)
-rw-r--r--engines/kyra/screen.cpp84
-rw-r--r--engines/kyra/screen.h3
2 files changed, 87 insertions, 0 deletions
diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp
index c0d05dc851..e4613e2634 100644
--- a/engines/kyra/screen.cpp
+++ b/engines/kyra/screen.cpp
@@ -2052,6 +2052,87 @@ void Screen::drawShapePlotType52(uint8 *dst, uint8 cmd) {
*dst = cmd;
}
+void Screen::decodeFrame1(const uint8 *src, uint8 *dst, uint32 size) {
+ const uint8 *dstEnd = dst + size;
+
+ struct Pattern {
+ const uint8 *pos;
+ uint16 len;
+ };
+
+ Pattern *patterns = new Pattern[3840];
+ uint16 numPatterns = 0;
+ uint8 nib = 0;
+
+ uint16 code = decodeEGAGetCode(src, nib);
+ uint8 last = code & 0xff;
+
+ uint8 *dstPrev = dst;
+ uint16 count = 1;
+ uint16 countPrev = 1;
+
+ *dst++ = last;
+
+ while (dst < dstEnd) {
+ code = decodeEGAGetCode(src, nib);
+ last = code & 0xff;
+ uint8 cmd = code >> 8;
+
+ if (cmd--) {
+ code = (cmd << 8) | last;
+ uint8 *tmpDst = dst;
+ last = *dst;
+
+ if (code < numPatterns) {
+ const uint8 *tmpSrc = patterns[code].pos;
+ countPrev = patterns[code].len;
+ for (int i = 0; i < countPrev; i++)
+ *dst++ = *tmpSrc++;
+
+ } else {
+ const uint8 *tmpSrc = dstPrev;
+ count = countPrev;
+ for (int i = 0; i < countPrev; i++)
+ *dst++ = *tmpSrc++;
+ *dst++ = last;
+ countPrev++;
+ }
+
+ if (numPatterns < 3840) {
+ patterns[numPatterns].pos = dstPrev;
+ patterns[numPatterns++].len = ++count;
+ }
+
+ dstPrev = tmpDst;
+ count = countPrev;
+
+ } else {
+ *dst++ = last;
+
+ if (numPatterns < 3840) {
+ patterns[numPatterns].pos = dstPrev;
+ patterns[numPatterns++].len = ++count;
+ }
+
+ dstPrev = dst - 1;
+ count = 1;
+ countPrev = 1;
+ }
+ }
+ delete[] patterns;
+}
+
+uint16 Screen::decodeEGAGetCode(const uint8 *&pos, uint8 &nib) {
+ uint16 res = READ_BE_UINT16(pos++);
+ if ((++nib) & 1) {
+ res >>= 4;
+ } else {
+ pos++;
+ res &= 0xfff;
+ }
+ return res;
+}
+
void Screen::decodeFrame3(const uint8 *src, uint8 *dst, uint32 size) {
const uint8 *dstEnd = dst + size;
while (dst < dstEnd) {
@@ -2933,6 +3014,9 @@ void Screen::loadBitmap(const char *filename, int tempPage, int dstPage, Palette
case 0:
memcpy(dstData, srcPtr, imgSize);
break;
+ case 1:
+ Screen::decodeFrame1(srcPtr, dstData, imgSize);
+ break;
case 3:
Screen::decodeFrame3(srcPtr, dstData, imgSize);
break;
diff --git a/engines/kyra/screen.h b/engines/kyra/screen.h
index d4f0dc97da..192e267014 100644
--- a/engines/kyra/screen.h
+++ b/engines/kyra/screen.h
@@ -515,6 +515,9 @@ public:
FontId _currentFont;
// decoding functions
+ static void decodeFrame1(const uint8 *src, uint8 *dst, uint32 size);
+ static uint16 decodeEGAGetCode(const uint8 *&pos, uint8 &nib);
+
static void decodeFrame3(const uint8 *src, uint8 *dst, uint32 size);
static uint decodeFrame4(const uint8 *src, uint8 *dst, uint32 dstSize);
static void decodeFrameDelta(uint8 *dst, const uint8 *src, bool noXor = false);