aboutsummaryrefslogtreecommitdiff
path: root/scumm
diff options
context:
space:
mode:
authorJames Brown2002-10-07 09:20:50 +0000
committerJames Brown2002-10-07 09:20:50 +0000
commite252eda7c238c263fe94bede247779260ecfb861 (patch)
treeb016896c697950edd2e2b1dc450aea5263dd209e /scumm
parentbbc1567526aaa538c844afd53b02913d6a31b761 (diff)
downloadscummvm-rg350-e252eda7c238c263fe94bede247779260ecfb861.tar.gz
scummvm-rg350-e252eda7c238c263fe94bede247779260ecfb861.tar.bz2
scummvm-rg350-e252eda7c238c263fe94bede247779260ecfb861.zip
eriktorbjorn's Akos Codec 5 rewrite (Patch 618888 V2)
svn-id: r5102
Diffstat (limited to 'scumm')
-rw-r--r--scumm/akos.cpp159
1 files changed, 121 insertions, 38 deletions
diff --git a/scumm/akos.cpp b/scumm/akos.cpp
index ecd97b2b0f..3f97bcd7c1 100644
--- a/scumm/akos.cpp
+++ b/scumm/akos.cpp
@@ -860,60 +860,143 @@ void AkosRenderer::codec1_ignorePakCols(int num)
void AkosRenderer::codec5()
{
VirtScreen *vs;
- BompDrawData bdd;
- int moveX;
- int moveY;
- int left;
- int var_20;
- int max_width;
+ int left, right, top, bottom;
+ int clip_left, clip_right, clip_top, clip_bottom;
- int right;
- int top;
- int bottom;
+ byte *src, *dest;
+ int src_x, src_y;
+ int dst_x, dst_y;
+ bool masking;
+ byte maskbit;
+ byte *mask = NULL;
+
+ // I don't know if this is complete. It used to simply call drawBomp()
+ // to draw an unscaled image, but I don't know if that was because it
+ // will never have to scale, or if it's because until quite recently
+ // drawBomp() didn't know how to scale images.
+ //
+ // What I do know is that drawBomp() doesn't care about masking and
+ // shadows, and these are both needed for Full Throttle and The Dig.
+
vs = &_vm->virtscr[0];
- //setBlastObjectMode(shadow_mode); // not implemented yet
- moveX = move_x_cur;
- moveY = move_y_cur;
if (!mirror) {
- left = (x - moveX - width) + 1;
+ left = (x - move_x_cur - width) + 1;
} else {
- left = x + moveX - 1;
+ left = x + move_x_cur - 1;
}
- var_20 = 0;
- max_width = outwidth;
-
- right = left + width - 1;
- top = y + moveY;
+ right = left + width;
+ top = y + move_y_cur;
bottom = top + height;
- if (left < 0)
- left = 0;
- if (left > max_width)
- left -= left - max_width;
+ if (left >= _vm->_realWidth || top >= _vm->_realHeight)
+ return;
+
+ // The actual drawing code shouldn't survive even if the image is
+ // partially outside the screen, but something before that seems to
+ // be less tolerant...
+
+ clip_left = (left >= 0) ? left : 0;
+ clip_right = (right > _vm->_realWidth) ? _vm->_realWidth : right;
+ clip_top = (top >= 0) ? top : 0;
+ clip_bottom = (bottom > _vm->_realHeight) ? _vm->_realHeight : bottom;
+
+ if (clip_top < draw_top)
+ draw_top = clip_top;
+ if (clip_bottom > draw_bottom)
+ draw_bottom = clip_bottom;
+
+ _vm->updateDirtyRect(0, clip_left, clip_right, clip_top, clip_bottom, 1 << dirty_id);
+
+ masking = false;
+ if (clipping) {
+ masking = _vm->isMaskActiveAt(clip_left, clip_top, clip_right, clip_bottom,
+ _vm->getResourceAddress(rtBuffer, 9) +
+ _vm->gdi._imgBufOffs[clipping] +
+ _vm->_screenStartStrip) != 0;
+ }
+
+ v1.mask_ptr = NULL;
+
+ if (masking || charsetmask) {
+ v1.mask_ptr = _vm->getResourceAddress(rtBuffer, 9) + _vm->_screenStartStrip;
+ v1.imgbufoffs = _vm->gdi._imgBufOffs[clipping];
+ if (!charsetmask && masking) {
+ v1.mask_ptr += v1.imgbufoffs;
+ v1.imgbufoffs = 0;
+ }
+ }
- // Yazoo: this is not correct, but fix a lots of bugs for the momment
+ src = srcptr;
+ dest = outptr;
- draw_top = 0;
- draw_bottom = vs->height;
+ for (src_y = 0, dst_y = top; src_y < height; src_y++) {
+ byte code, color;
+ uint num, i;
+ byte *d = dest + dst_y * _vm->_realWidth + left;
+ byte *s;
+ uint data_length;
- _vm->updateDirtyRect(0, left, right + 1, top, bottom + 1, 1 << dirty_id);
+ data_length = READ_LE_UINT16(src) + 2;
- bdd.dataptr = srcptr;
- bdd.out = outptr;
- bdd.outheight = outheight;
- bdd.outwidth = outwidth;
- bdd.scale_x = 0xFF;
- bdd.scale_y = 0xFF;
- bdd.srcheight = height;
- bdd.srcwidth = width;
- bdd.x = left + 1;
- bdd.y = top;
+ if (dst_y < 0 || dst_y >= _vm->_realHeight) {
+ src += data_length;
+ dst_y++;
+ continue;
+ }
- _vm->drawBomp(&bdd, 0, bdd.dataptr, 0, 0);
+ src_x = 0;
+ dst_x = left;
+ s = src + 2;
+
+ while (src_x < width) {
+ code = *s++;
+ num = (code >> 1) + 1;
+ if (code & 1) {
+ color = *s++;
+ for (i = 0; i < num; i++) {
+ if (dst_x >= 0 && dst_x < _vm->_realWidth) {
+ if (color != 255) {
+ if (v1.mask_ptr)
+ mask = v1.mask_ptr + 40 * dst_y + (dst_x >> 3);
+ maskbit = revBitMask[dst_x & 7];
+ if (shadow_mode && color == 13)
+ color = shadow_table[*d];
+ if (!mask || !((mask[0] | mask[v1.imgbufoffs]) & maskbit))
+ *d = color;
+ }
+ }
+ d++;
+ dst_x++;
+ src_x++;
+ }
+ } else {
+ for (i = 0; i < num; i++) {
+ color = s[i];
+ if (dst_x >= 0 && dst_x < _vm->_realWidth) {
+ if (color != 255) {
+ if (v1.mask_ptr)
+ mask = v1.mask_ptr + 40 * dst_y + (dst_x >> 3);
+ maskbit = revBitMask[dst_x & 7];
+ if (shadow_mode && color == 13)
+ color = shadow_table[*d];
+ if (!mask || !((mask[0] | mask[v1.imgbufoffs]) & maskbit))
+ *d = color;
+ }
+ }
+ d++;
+ dst_x++;
+ src_x++;
+ }
+ s += num;
+ }
+ }
+ src += data_length;
+ dst_y++;
+ }
}
void AkosRenderer::codec16()