diff options
author | James Brown | 2002-10-07 09:20:50 +0000 |
---|---|---|
committer | James Brown | 2002-10-07 09:20:50 +0000 |
commit | e252eda7c238c263fe94bede247779260ecfb861 (patch) | |
tree | b016896c697950edd2e2b1dc450aea5263dd209e /scumm | |
parent | bbc1567526aaa538c844afd53b02913d6a31b761 (diff) | |
download | scummvm-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.cpp | 159 |
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() |