aboutsummaryrefslogtreecommitdiff
path: root/engines/agos
diff options
context:
space:
mode:
authorTravis Howell2007-02-09 00:35:57 +0000
committerTravis Howell2007-02-09 00:35:57 +0000
commiteaeada78acef36750c89a653df4a38b7f4aaf4cc (patch)
treeeed052f34f85f8154a2b48e9f2ad411378cdedc7 /engines/agos
parentdda1431e7c6b223a5686fe6d06d5268adbbb5e33 (diff)
downloadscummvm-rg350-eaeada78acef36750c89a653df4a38b7f4aaf4cc.tar.gz
scummvm-rg350-eaeada78acef36750c89a653df4a38b7f4aaf4cc.tar.bz2
scummvm-rg350-eaeada78acef36750c89a653df4a38b7f4aaf4cc.zip
Add cyx's patch for cleanup for planar conversion code, and support for 32 color planar graphics of Amiga ECS version of Simon the Sorcerer 1.
svn-id: r25436
Diffstat (limited to 'engines/agos')
-rw-r--r--engines/agos/agos.h3
-rw-r--r--engines/agos/gfx.cpp103
-rw-r--r--engines/agos/res_ami.cpp246
-rw-r--r--engines/agos/vga.cpp72
4 files changed, 202 insertions, 222 deletions
diff --git a/engines/agos/agos.h b/engines/agos/agos.h
index ad46fe572d..51d4f4b77a 100644
--- a/engines/agos/agos.h
+++ b/engines/agos/agos.h
@@ -1278,6 +1278,7 @@ protected:
bool drawImages_clip(VC10_state *state);
void drawImages(VC10_state *state);
+ void drawImages_Amiga(VC10_state *state);
void drawImages_Simon(VC10_state *state);
void drawImages_Feeble(VC10_state *state);
@@ -1336,7 +1337,7 @@ protected:
byte *getBackGround();
byte *getScaleBuf();
- byte *convertclip(const byte *src, uint height, uint width, byte flags);
+ byte *convertclip(const byte *src, bool is32Colors, uint height, uint width, byte flags);
bool decrunchFile(byte *src, byte *dst, uint32 size);
void loadVGABeardFile(uint id);
diff --git a/engines/agos/gfx.cpp b/engines/agos/gfx.cpp
index 644747012a..f5727b5b90 100644
--- a/engines/agos/gfx.cpp
+++ b/engines/agos/gfx.cpp
@@ -425,36 +425,30 @@ void AGOSEngine::drawImages_Simon(VC10_state *state) {
dst = state->surf_addr + w * 2; /* edi */
h = state->draw_height;
- if ((getGameType() == GType_SIMON1) && getBitFlag(88)) {
- /* transparency */
- do {
- if (mask[0] & 0xF0) {
- if ((dst[0] & 0x0F0) == 0x20)
+ do {
+ if ((getGameType() == GType_SIMON1) && getBitFlag(88)) {
+ /* transparency */
+ if (mask[0] & 0xF0) {
+ if ((dst[0] & 0x0F0) == 0x20)
+ dst[0] = src[0];
+ }
+ if (mask[0] & 0x0F) {
+ if ((dst[1] & 0x0F0) == 0x20)
+ dst[1] = src[1];
+ }
+ } else {
+ /* no transparency */
+ if (mask[0] & 0xF0)
dst[0] = src[0];
- }
- if (mask[0] & 0x0F) {
- if ((dst[1] & 0x0F0) == 0x20)
+ if (mask[0] & 0x0F)
dst[1] = src[1];
- }
- mask++;
- dst += state->surf_pitch;
- src += state->surf2_pitch;
- } while (--h);
- } else {
- /* no transparency */
- do {
- if (mask[0] & 0xF0)
- dst[0] = src[0];
- if (mask[0] & 0x0F)
- dst[1] = src[1];
- mask++;
- dst += state->surf_pitch;
- src += state->surf2_pitch;
- } while (--h);
- }
+ }
+ mask++;
+ dst += state->surf_pitch;
+ src += state->surf2_pitch;
+ } while (--h);
} while (++w != state->draw_width);
- } else if ((((_lockWord & 0x20) && state->palette == 0) || state->palette == 0xC0) &&
- getPlatform() != Common::kPlatformAmiga) {
+ } else if ((((_lockWord & 0x20) && state->palette == 0) || state->palette == 0xC0)) {
const byte *src;
byte *dst;
uint h, i;
@@ -589,6 +583,61 @@ void AGOSEngine::drawImages_Simon(VC10_state *state) {
}
}
+void AGOSEngine::drawImages_Amiga(VC10_state *state) {
+ uint8 *dst;
+ const byte *src;
+ const uint16 *vlut = &_videoWindows[_windowNum * 4];
+
+ if (drawImages_clip(state) == 0)
+ return;
+
+ uint xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
+ uint yoffs = (vlut[1] - _videoWindows[17] + state->y);
+
+ state->surf2_addr += xoffs + yoffs * state->surf_pitch;
+ state->surf_addr += xoffs + yoffs * state->surf2_pitch;
+
+ if (state->flags & kDFMasked) {
+ const byte *mask = state->depack_src + (state->width * state->y_skip * 16) + (state->x_skip * 8);
+ src = state->surf2_addr;
+ dst = state->surf_addr;
+
+ state->draw_width *= 2;
+
+ uint h = state->draw_height;
+ do {
+ for (uint i = 0; i != state->draw_width; i++) {
+ if ((getGameType() == GType_SIMON1) && getBitFlag(88)) {
+ /* transparency */
+ if (mask[i] & 1 && (dst[i] & 1) == 0x20)
+ dst[i] = src[i];
+ } else {
+ /* no transparency */
+ if (mask[i] & 1)
+ dst[i] = src[i];
+ }
+ }
+ dst += state->surf_pitch;
+ src += state->surf2_pitch;
+ mask += state->width * 16;
+ } while (--h);
+ } else {
+ src = state->depack_src + (state->width * state->y_skip * 16) + (state->x_skip * 8);
+ dst = state->surf_addr;
+
+ state->draw_width *= 2;
+
+ uint h = state->draw_height;
+ do {
+ for (uint i = 0; i != state->draw_width; i++)
+ if ((state->flags & kDFNonTrans) || src[i])
+ dst[i] = src[i];
+ dst += _screenWidth;
+ src += state->width * 16;
+ } while (--h);
+ }
+}
+
void AGOSEngine::drawImages(VC10_state *state) {
const uint16 *vlut = &_videoWindows[_windowNum * 4];
diff --git a/engines/agos/res_ami.cpp b/engines/agos/res_ami.cpp
index 6afe08e61e..c16b907f01 100644
--- a/engines/agos/res_ami.cpp
+++ b/engines/agos/res_ami.cpp
@@ -29,29 +29,29 @@
namespace AGOS {
+enum {
+ kMaxColorDepth = 5
+};
+
static void uncompressplane(const byte *plane, byte *outptr, uint16 length) {
- char x;
- byte y, z;
- while (length) {
- x = *plane++;
+ while (length != 0) {
+ char x = *plane++;
if (x >= 0) {
- x += 1;
- y = *plane++;
- z = *plane++;
- while (x) {
+ x++;
+ byte y = *plane++;
+ byte z = *plane++;
+ while (x != 0) {
*outptr++ = y;
*outptr++ = z;
- length--;
- if (length == 0)
+ if (--length == 0)
break;
x--;
}
} else {
- while (x) {
+ while (x != 0) {
*outptr++ = *plane++;
*outptr++ = *plane++;
- length--;
- if (length == 0)
+ if (--length == 0)
break;
x++;
}
@@ -59,183 +59,87 @@ static void uncompressplane(const byte *plane, byte *outptr, uint16 length) {
}
}
-static void convertcompressedclip(const byte *src, byte *dst, uint16 height, uint16 width) {
- const byte *plane0, *plane1, *plane2, *plane3;
- byte *uncbuffer;
- byte *uncptr0, *uncptr1, *uncptr2, *uncptr3;
- byte *uncbfrout;
- byte *uncbfroutptr;
- uint16 length, i, j, k, word1, word2, word3, word4, cliplength;
- byte outbyte, outbyte1, x, y;
- char n;
- uncbuffer = (byte *)malloc(height * width * 4);
- uncbfrout = (byte *)malloc(height * width * 4);
-
- byte *free_uncbuffer = uncbuffer;
- byte *free_uncbfrout = uncbfrout;
-
- length = width / 16;
- length *= height;
- plane0 = READ_BE_UINT16(src) + READ_BE_UINT16(src + 2) + src; src += 4; plane0 += 4;
- plane1 = READ_BE_UINT16(src) + READ_BE_UINT16(src + 2) + src; src += 4; plane1 += 4;
- plane2 = READ_BE_UINT16(src) + READ_BE_UINT16(src + 2) + src; src += 4; plane2 += 4;
- plane3 = READ_BE_UINT16(src) + READ_BE_UINT16(src + 2) + src; src += 4; plane3 += 4;
- plane0 -= 4;
- plane1 -= 8;
- plane2 -= 12;
- plane3 -= 16;
- uncptr0 = uncbuffer;
- uncptr1 = uncptr0+(length * 2);
- uncptr2 = uncptr1+(length * 2);
- uncptr3 = uncptr2+(length * 2);
- uncompressplane(plane0, uncptr0, length);
- uncompressplane(plane1, uncptr1, length);
- uncompressplane(plane2, uncptr2, length);
- uncompressplane(plane3, uncptr3, length);
- uncbfroutptr = uncbfrout;
- for (i = 0; i < length; i++) {
- word1=READ_BE_UINT16(uncptr0); uncptr0 += 2;
- word2=READ_BE_UINT16(uncptr1); uncptr1 += 2;
- word3=READ_BE_UINT16(uncptr2); uncptr2 += 2;
- word4=READ_BE_UINT16(uncptr3); uncptr3 += 2;
- for (j = 0; j < 8; j++) {
- outbyte = ((word1 / 32768) + ((word2 / 32768) * 2) + ((word3 / 32768) * 4) + ((word4 / 32768) * 8));
- word1 <<= 1;
- word2 <<= 1;
- word3 <<= 1;
- word4 <<= 1;
- outbyte1 = ((word1 / 32768) + ((word2 / 32768) * 2) + ((word3 / 32768) * 4) + ((word4 / 32768) * 8));
- word1 <<= 1;
- word2 <<= 1;
- word3 <<= 1;
- word4 <<= 1;
- *uncbfroutptr++ = (outbyte * 16 + outbyte1);
- }
- }
- uncptr0 = uncbuffer;
- uncptr1 = uncbfrout;
- uncptr2 = uncbfrout;
- uncptr3 = uncbfrout;
- for (i = 0; i < (width / 16); i++) {
- for (k = 0; k < 8; k++) {
- for (j = 0; j < height; j++) {
- *uncptr0++ = *uncptr1;
- uncptr1 += 8;
+static void bitplanetochunky(uint16 *w, uint8 colorDepth, uint8 *&dst) {
+ for (int j = 0; j < 8; j++) {
+ byte color1 = 0;
+ byte color2 = 0;
+ for (int p = 0; p < 5; ++p) {
+ if (w[p] & 0x8000) {
+ color1 |= 1 << p;
}
- uncptr2++;
- uncptr1 = uncptr2;
+ if (w[p] & 0x4000) {
+ color2 |= 1 << p;
+ }
+ w[p] <<= 2;
+ }
+ if (colorDepth > 4) {
+ *dst++ = color1;
+ *dst++ = color2;
+ } else {
+ *dst++ = (color1 << 4) | color2;
}
- uncptr3 += (height * 8);
- uncptr2 = uncptr3;
- uncptr1 = uncptr2;
}
- length *= 8;
- cliplength = 0;
- while(1) {
- if (length == 1) {
- *dst++ = 0xFF;
- *dst++ = *uncbuffer;
- cliplength += 2;
- break;
+}
+
+static void convertcompressedclip(const byte *src, byte *dst, uint8 colorDepth, uint16 height, uint16 width) {
+ const byte *plane[kMaxColorDepth];
+ byte *uncptr[kMaxColorDepth];
+ uint32 length, i, j;
+ uint16 w[kMaxColorDepth];
+
+ byte *uncbfrout = (byte *)malloc(width * height);
+
+ length = (width + 15) / 16 * height;
+
+ for (i = 0; i < colorDepth; ++i) {
+ plane[i] = src + READ_BE_UINT16(src + i * 4) + READ_BE_UINT16(src + i * 4 + 2);
+ uncptr[i] = (uint8 *)malloc(length * 2);
+ uncompressplane(plane[i], uncptr[i], length);
+ plane[i] = uncptr[i];
+ }
+
+ byte *uncbfroutptr = uncbfrout;
+ for (i = 0; i < length; ++i) {
+ for (j = 0; j < colorDepth; ++j) {
+ w[j] = READ_BE_UINT16(plane[j]); plane[j] += 2;
}
- x = *uncbuffer++;
- y = *uncbuffer++;
- length -= 2;
- if (x == y) {
- n = 1;
- y = *uncbuffer++;
- if (length == 0) {
- *dst++ = n;
- *dst++ = x;
- cliplength += 2;
- break;
- }
- length--;
- while (x == y) {
- n++;
- y = *uncbuffer++;
- if (length == 0)
- break;
- length--;
- if(n == 127)
- break;
- }
- *dst++ = n;
- *dst++ = x;
- cliplength += 2;
- uncbuffer--;
- if (length == 0)
- break;
- length++;
- } else {
- n =- 1;
- uncptr0 = dst;
- dst++;
- *dst++ = x;
- cliplength += 2;
- x = y;
- y = *uncbuffer++;
- if (length == 0) {
- *uncptr0 = n;
- break;
- }
- length--;
- while (x != y) {
- if (n == -127)
- break;
- n--;
- *dst++ = x;
- cliplength++;
- x = y;
- y = *uncbuffer++;
- if (length == 0)
- break;
- length--;
- }
- *uncptr0 = n;
- if (length == 0)
- break;
- uncbuffer -= 2;
- length += 2;
+ bitplanetochunky(w, colorDepth, uncbfroutptr);
+ }
+
+ uncbfroutptr = uncbfrout;
+ const int chunkSize = colorDepth > 4 ? 16 : 8;
+ for (i = 0; i < width / 16; ++i) {
+ for (j = 0; j < height; ++j) {
+ memcpy(dst + width * chunkSize / 16 * j + chunkSize * i, uncbfroutptr, chunkSize);
+ uncbfroutptr += chunkSize;
}
}
- free(free_uncbuffer);
- free(free_uncbfrout);
+ free(uncbfrout);
+ for (i = 0; i < colorDepth; ++i) {
+ free(uncptr[i]);
+ }
}
-byte *AGOSEngine::convertclip(const byte *src, uint height, uint width, byte flags) {
+byte *AGOSEngine::convertclip(const byte *src, bool is32Colors, uint height, uint width, byte flags) {
+ uint8 colorDepth = is32Colors ? 5 : 4;
+
uint32 length, i, j;
- uint16 word1, word2, word3, word4;
- byte outbyte, outbyte1;
free(_planarBuf);
_planarBuf = (byte *)malloc(width * height);
byte *dst = _planarBuf;
if (flags & 0x80) {
- convertcompressedclip(src, dst, height, width);
+ convertcompressedclip(src, dst, colorDepth, height, width);
} else {
- width /= 16;
- length = height * width;
+ length = (width + 15) / 16 * height;
for (i = 0; i < length; i++) {
- word1 = READ_BE_UINT16(src); src += 2;
- word2 = READ_BE_UINT16(src); src += 2;
- word3 = READ_BE_UINT16(src); src += 2;
- word4 = READ_BE_UINT16(src); src += 2;
- for (j = 0; j < 8; j++) {
- outbyte = ((word1 / 32768) + ((word2 / 32768) * 2) + ((word3 / 32768) * 4) + ((word4 / 32768) * 8));
- word1 <<= 1;
- word2 <<= 1;
- word3 <<= 1;
- word4 <<= 1;
- outbyte1 = ((word1 / 32768) + ((word2 / 32768) * 2) + ((word3 / 32768) * 4) + ((word4 / 32768) * 8));
- word1 <<= 1;
- word2 <<= 1;
- word3 <<= 1;
- word4 <<= 1;
- *dst++ = (outbyte * 16 + outbyte1);
+ uint16 w[kMaxColorDepth];
+ for (j = 0; j < colorDepth; ++j) {
+ w[j] = READ_BE_UINT16(src); src += 2;
}
+ bitplanetochunky(w, colorDepth, dst);
}
}
diff --git a/engines/agos/vga.cpp b/engines/agos/vga.cpp
index 93aeda6c5e..0ec2c5004f 100644
--- a/engines/agos/vga.cpp
+++ b/engines/agos/vga.cpp
@@ -541,24 +541,38 @@ byte *AGOSEngine::vc10_uncompressFlip(const byte *src, uint w, uint h) {
}
byte *AGOSEngine::vc10_flip(const byte *src, uint w, uint h) {
- w *= 8;
-
byte *dstPtr;
uint i;
- dstPtr = _videoBuf1 + w;
+ if (getFeatures() & GF_32COLOR) {
+ w *= 16;
+ dstPtr = _videoBuf1 + w;
- do {
- byte *dst = dstPtr;
- for (i = 0; i != w; ++i) {
- byte b = src[i];
- b = (b >> 4) | (b << 4);
- *--dst = b;
- }
+ do {
+ byte *dst = dstPtr;
+ for (i = 0; i != w; ++i) {
+ *--dst = src[i];
+ }
- src += w;
- dstPtr += w;
- } while (--h);
+ src += w;
+ dstPtr += w;
+ } while (--h);
+ } else {
+ w *= 8;
+ dstPtr = _videoBuf1 + w;
+
+ do {
+ byte *dst = dstPtr;
+ for (i = 0; i != w; ++i) {
+ byte b = src[i];
+ b = (b >> 4) | (b << 4);
+ *--dst = b;
+ }
+
+ src += w;
+ dstPtr += w;
+ } while (--h);
+ }
return _videoBuf1;
}
@@ -583,10 +597,6 @@ void AGOSEngine::vc10_draw() {
state.palette = 0;
}
- if (getFeatures() & GF_32COLOR) {
- state.palette = 0;
- }
-
state.x = (int16)vcReadNextWord();
state.x -= _scrollX;
@@ -617,15 +627,29 @@ void AGOSEngine::vc10_draw() {
if (height == 0 || width == 0)
return;
- if (getFeatures() & GF_PLANAR) {
- state.depack_src = convertclip(state.depack_src, height, width * 16, flags);
- }
-
if (_dumpImages)
dumpSingleBitmap(_vgaCurZoneNum, state.image, state.depack_src, width, height,
state.palette);
- // Check if image is compressed
- if (getGameType() == GType_FF || getGameType() == GType_PP) {
+ if (getFeatures() & GF_PLANAR) {
+ bool is32Colors = false;
+ if (getGameType() == GType_SIMON1) {
+ if (((_lockWord & 0x20) && !state.palette) || state.palette == 0xC0 ||
+ (getFeatures() & GF_32COLOR)) {
+ is32Colors = true;
+ }
+ }
+
+ state.depack_src = convertclip(state.depack_src, is32Colors, height, width * 16, flags);
+
+ // converted planar clip is already uncompressed
+ if (state.flags & kDFCompressedFlip) {
+ state.flags &= ~kDFCompressedFlip;
+ state.flags |= kDFFlip;
+ }
+ if (state.flags & kDFCompressed) {
+ state.flags &= ~kDFCompressed;
+ }
+ } else if (getGameType() == GType_FF || getGameType() == GType_PP) {
if (flags & 0x80) {
state.flags |= kDFCompressed;
}
@@ -674,6 +698,8 @@ void AGOSEngine::vc10_draw() {
if (getGameType() == GType_FF || getGameType() == GType_PP) {
drawImages_Feeble(&state);
+ } else if (getFeatures() & GF_32COLOR) {
+ drawImages_Amiga(&state);
} else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
drawImages_Simon(&state);
} else {