diff options
-rw-r--r-- | scumm/akos.cpp | 191 | ||||
-rw-r--r-- | scumm/gfx.cpp | 361 | ||||
-rw-r--r-- | scumm/object.cpp | 151 | ||||
-rw-r--r-- | scumm/scumm.h | 21 |
4 files changed, 496 insertions, 228 deletions
diff --git a/scumm/akos.cpp b/scumm/akos.cpp index de5bbdb9e3..9ee3b0b4f6 100644 --- a/scumm/akos.cpp +++ b/scumm/akos.cpp @@ -137,6 +137,15 @@ void AkosRenderer::setPalette(byte *new_palette) for (i = 0; i < size; i++) { palette[i] = new_palette[i] != 0xFF ? new_palette[i] : the_akpl[i]; } + + if (size == 256) { + byte color = new_palette[0]; + if (color == 255) { + palette[0] = color; + } else { + _vm->_bompActorPalletePtr = palette; + } + } } void AkosRenderer::setCostume(int costume) @@ -842,143 +851,87 @@ void AkosRenderer::codec1_ignorePakCols(int num) } while (1); } +void AkosRenderer::codec5() { + int32 clip_left, clip_right, clip_top, clip_bottom, maxw, maxh, tmp_x, tmp_y; -void AkosRenderer::codec5() -{ - int left, right, top, bottom; - int clip_left, clip_right, clip_top, clip_bottom; - - byte *src, *dest; - int src_x, src_y; - int dst_x, dst_y; + _vm->_bompShadowMode = shadow_mode; - 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. - if (!mirror) { - left = (_x - move_x_cur - _width) + 1; + clip_left = (_x - move_x_cur - _width) + 1; } else { - left = _x + move_x_cur - 1; + clip_left = _x + move_x_cur - 1; + } + + clip_right = (clip_left + _width) - 1; + clip_top = _y + move_y_cur; + clip_bottom = (clip_top + _height) - 1; + maxw = outwidth - 1; + maxh = outheight - 1; + + if (clip_left < 0) { + clip_left = 0; + } + + tmp_x = clip_right - maxw; + if (tmp_x > 0) { + clip_right -= tmp_x; + } + + tmp_y = clip_top; + if (tmp_y < 0) { + clip_top -= tmp_y; } - right = left + _width; - top = _y + move_y_cur; - bottom = top + _height; + tmp_y = clip_bottom - maxh; + if (tmp_y > 0) { + clip_bottom -= tmp_y; + } - if (left >= (int) outwidth || top >= (int) outheight) + if ((clip_right <= clip_left) || (clip_top >= clip_bottom)) 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... + _vm->updateDirtyRect(0, clip_left, clip_right + 1, clip_top, clip_bottom + 1, 1 << dirty_id); - clip_left = (left >= 0) ? left : 0; - clip_right = (right > (int) outwidth) ? (int) outwidth : right; - clip_top = (top >= 0) ? top : 0; - clip_bottom = (bottom > (int) outheight) ? (int) outheight : 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; - } + draw_bottom = clip_bottom + 1; - v1.mask_ptr = NULL; + BompDrawData bdd; - 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; - } - } + bdd.srcwidth = _width; + bdd.srcheight = _height; + bdd.out = outptr; + bdd.outwidth = outwidth; + bdd.outheight = outheight; + bdd.dataptr = srcptr; + bdd.scale_x = 255; + bdd.scale_y = 255; - src = srcptr; - dest = outptr; + _vm->_bompScallingXPtr = NULL; + _vm->_bompScallingYPtr = NULL; - for (src_y = 0, dst_y = top; src_y < _height; src_y++) { - byte code, color; - uint num, i; - byte *d = dest + dst_y * outwidth + left; - byte *s; - uint data_length; + int decode_mode; - data_length = READ_LE_UINT16(src) + 2; + if (!mirror) { + bdd.x = (_x - move_x_cur - _width) + 1; + decode_mode = 3; + } else { + bdd.x = _x + move_x_cur; + decode_mode = 1; + } - if (dst_y < 0 || dst_y >= (int) outheight) { - src += data_length; - dst_y++; - continue; - } + bdd.y = _y + move_y_cur; - 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 < (int) outwidth) { - if (color != 255) { - if (v1.mask_ptr) - mask = v1.mask_ptr + _numStrips * 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 < (int) outwidth) { - if (color != 255) { - if (v1.mask_ptr) - mask = v1.mask_ptr + _numStrips * 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++; + if (clipping != 0) { + _vm->_bompMaskPtr = _vm->getResourceAddress(rtBuffer, 9) + _vm->_screenStartStrip + _vm->gdi._imgBufOffs[clipping]; + _vm->_bompMaskPitch = _vm->_realWidth / 8; + _vm->drawBomp(&bdd, 0, bdd.dataptr, decode_mode, 1); + } else { + _vm->drawBomp(&bdd, 0, bdd.dataptr, decode_mode, 0); } + + _vm->_bompActorPalletePtr = NULL; } void AkosRenderer::akos16SetupBitReader(byte *src) { @@ -1195,7 +1148,7 @@ void AkosRenderer::akos16DecompressMask(byte * dest, int32 pitch, byte * src, in akos16SkipData(numskip_before); } - maskpitch = _numStrips + 1; + maskpitch = _numStrips ; while (t_height != 0) { akos16DecodeLine(tmp_buf, t_width, dir); @@ -1286,7 +1239,7 @@ void AkosRenderer::codec16() { if (!mirror) { dir = -1; - + int tmp_skip_x = skip_x; skip_x = _width-1-cur_x; cur_x = _width-1-tmp_skip_x; @@ -1331,7 +1284,7 @@ void AkosRenderer::codec16() { } byte * ptr = _vm->_screenStartStrip + _vm->getResourceAddress(rtBuffer, 9) + _vm->gdi._imgBufOffs[clipping]; - ptr += (_numStrips + 1) * clip_top + (clip_left / 8); + ptr += _numStrips * clip_top + (clip_left / 8); akos16DecompressMask(dest, pitch, srcptr, cur_x, out_height, dir, numskip_before, numskip_after, 255, ptr, clip_left / 8); } diff --git a/scumm/gfx.cpp b/scumm/gfx.cpp index 6fd4e44b1e..288baf279c 100644 --- a/scumm/gfx.cpp +++ b/scumm/gfx.cpp @@ -3155,137 +3155,294 @@ static byte blend(byte *pal, byte method, int dest_color) return blend_cache[cache][dest_color]; } -// param3= clipping -// param2= mirror -// param1= never used ? - -void Scumm::drawBomp(BompDrawData *bd, int param1, byte *dataPtr, int param2, int param3) -{ - byte *scale_rows = NULL; - byte *scale_cols = NULL; - byte *dest = bd->out + bd->y * bd->outwidth, *src; - int src_x, src_y, dst_x, dst_y; - uint scaled_width, scaled_height; - int h = bd->srcheight; - byte *mask = NULL; - uint i; - - if (h == 0 || bd->srcwidth == 0) - return; +int32 Scumm::bompDecodeLineMode0(byte * src, byte * line_buffer, int32 size) { + if (size <= 0) + return size; + + for (int32 l = 0; l < size; l++) { + *(line_buffer++) = *(src++); + } + return size; +} + +int32 Scumm::bompDecodeLineMode1(byte * src, byte * line_buffer, int32 size) { + int32 t_size = READ_LE_UINT16(src) + 2; + if (size <= 0) + return t_size; + + int32 len = size; + src += 2; + while (len) { + byte code = *src++; + int32 num = (code >> 1) + 1; + if (num > len) + num = len; + len -= num; + if (code & 1) { + byte color = *src++; + do + *line_buffer++ = color; + while (--num); + } else { + do + *line_buffer++ = *src++; + while (--num); + } + } + return t_size; +} + +int32 Scumm::bompDecodeLineMode3(byte * src, byte * line_buffer, int32 size) { + int32 t_size = READ_LE_UINT16(src) + 2; + line_buffer += size; + if (size <= 0) + return t_size; + + int32 len = size; + src += 2; + while (len) { + byte code = *src++; + int32 num = (code >> 1) + 1; + if (num > len) + num = len; + len -= num; + if (code & 1) { + byte color = *src++; + do + *--line_buffer = color; + while (--num); + } else { + do + *--line_buffer = *src++; + while (--num); + } + } + return t_size; +} + +void Scumm::bompApplyMask(byte * line_buffer, byte * mask_src, byte bits, int32 size) { + while(1) { + byte tmp = *(mask_src++); + do { + if (size-- == 0) + return; + if (tmp & bits) { + *(line_buffer) = 255; + } + line_buffer++; + bits >>= 1; + } while (bits != 0); + bits = 128; + } +} - if (bd->scale_x != 255) { - scale_rows = (byte *) calloc(bd->srcheight, 1); - if (scale_rows == NULL) { - warning("drawBomp: out of memory"); +void Scumm::bompApplyShadow0(byte * line_buffer, byte * dst, int32 size) { + while(1) { + if (size-- == 0) return; + byte tmp = *(line_buffer++); + if (tmp != 255) { + *(dst) = tmp; } + dst++; } +} - if (bd->scale_y != 255) { - scale_cols = (byte *) calloc(bd->srcwidth, 1); - if (scale_cols == NULL) { - warning("drawBomp: out of memory"); - if (scale_rows) - free(scale_rows); +void Scumm::bompApplyShadow1(byte * line_buffer, byte * dst, int32 size) { + while(1) { + if (size-- == 0) return; + byte tmp = *(line_buffer++); + if (tmp != 255) { + if (tmp == 13) { + tmp = _shadowPalette[*(dst)]; + } + *(dst) = tmp; } + dst++; } +} - // We take charset masking into consideration, because otherwise the - // inventory window in The Dig may overwrite text. +void Scumm::bompApplyShadow3(byte * line_buffer, byte * dst, int32 size) { + while(1) { + if (size-- == 0) + return; + byte tmp = *(line_buffer++); + if (tmp != 255) { + if (tmp < 8) { + tmp = _shadowPalette[*(dst) + (tmp << 8)]; + } + *(dst) = tmp; + } + dst++; + } +} - mask = getResourceAddress(rtBuffer, 9) + _screenStartStrip; - - // Select which rows and columns from the original to show in the - // scaled version of the image. This is a pretty stupid way of scaling - // images, but it will have to do for now. +void Scumm::bompApplyActorPalette(byte * line_buffer, int32 size) { + if (_bompActorPalletePtr != 0) { + *(_bompActorPalletePtr + 255) = 255; + while(1) { + if (size-- == 0) + break; + *(line_buffer++) = *(_bompActorPalletePtr + *(line_buffer)); + } + } +} + +void Scumm::bompScaleFuncX(byte * line_buffer, byte * scalling_x_ptr, byte skip, int32 size) { + byte * line_ptr1 = line_buffer; + byte * line_ptr2 = line_buffer; - if (bd->scale_x < 255) { - scaled_width = (bd->srcwidth * bd->scale_x) / 255; - for (i = 0; i < scaled_width; i++) - scale_cols[(i * 255) / bd->scale_x] = 1; + byte tmp = *(scalling_x_ptr++); + + while (size--) { + if ((skip & tmp) == 0) { + *(line_ptr1++) = *(line_ptr2); + } + line_ptr2++; + skip >>= 1; + if (skip == 0) { + skip = 128; + tmp = *(scalling_x_ptr++); + } } +} + +void Scumm::drawBomp(BompDrawData * bd, int param1, byte * data_ptr, int decode_mode, int mask) { + byte skip_y = 128, skip_y_new; + byte bits, tmp; + int32 clip_left, clip_right, clip_top, clip_bottom, tmp_x, tmp_y; + byte * mask_out; - if (bd->scale_y < 255) { - scaled_height = (bd->srcheight * bd->scale_y) / 255; - for (i = 0; i < scaled_height; i++) - scale_rows[(i * 255) / bd->scale_y] = 1; + if (bd->x < 0) { + clip_left = -bd->x; + } else { + clip_left = 0; } - // FIXME: Be more intelligent about clearing the blend cache. It - // should be possible to clear it only for the parts of the palette - // that have changed since the last time. + if (bd->y < 0) { + clip_top = -bd->y; + } else { + clip_top = 0; + } - clear_blend_cache(); + clip_right = bd->srcwidth - clip_left; + tmp_x = bd->x + bd->srcwidth; + if (tmp_x > bd->outwidth) { + clip_right -= tmp_x - bd->outwidth; + } - dest += bd->x; - src = bd->dataptr; + clip_bottom = bd->srcheight; + tmp_y = bd->y + bd->srcheight; + if (tmp_y > bd->outheight) { + clip_bottom -= tmp_y - bd->outheight; + } + + byte * src = bd->dataptr; + byte * dst = bd->out + bd->y * bd->outwidth + bd->x + clip_left; - for (src_y = 0, dst_y = bd->y; src_y < bd->srcheight; src_y++) { - byte code, color; - uint len, num; - byte *d = dest; + if (mask == 1) { + mask_out = _bompMaskPtr + (bd->y * _bompMaskPitch) + ((bd->x + clip_left) >> 3); + bits = 128 >> ((bd->x + clip_left) & 7); + } - if ((dst_y < 0 || dst_y >= bd->outheight) || (bd->scale_y != 255 && !scale_rows[src_y])) { - src += READ_LE_UINT16(src) + 2; - continue; + if (mask == 3) { + if (_bompScallingYPtr != NULL) { + skip_y_new = *(_bompScallingYPtr++); } - len = bd->srcwidth; - src_x = 0; - dst_x = bd->x; - src += 2; - - while (src_x < bd->srcwidth) { - code = *src++; - num = (code >> 1) + 1; - if (num > len) - num = len; - len -= num; - if (code & 1) { - color = *src++; - for (i = 0; i < num; i++) { - if (bd->scale_x == 255 || scale_cols[src_x]) { - if (dst_x >= 0 && dst_x < bd->outwidth) { - if (!(*(mask + dst_y * gdi._numStrips + (dst_x >> 3)) & revBitMask[dst_x & 7])) - - *d = blend(_currentPalette, color, *d); - } - d++; - dst_x++; - } - src_x++; - } - } else { - for (i = 0; i < num; i++) { - if (bd->scale_x == 255 || scale_cols[src_x]) { - if (dst_x >= 0 && dst_x < bd->outwidth) - if (!(*(mask + dst_y * gdi._numStrips + (dst_x >> 3)) & revBitMask[dst_x & 7])) - *d = blend(_currentPalette, src[i], *d); - d++; - dst_x++; - } - src_x++; + if ((clip_right + clip_left) > _bompScaleRight) { + clip_right = _bompScaleRight - clip_left; + } + + if (clip_bottom > _bompScaleBottom) { + clip_bottom = _bompScaleBottom; + } + } + + if ((clip_right <= 0) || (clip_bottom <= 0)) + return; + + int32 pos_y = 0; + + byte line_buffer[1024]; + + byte * line_ptr = (byte*)&line_buffer + clip_left; + + while(1) { + switch(decode_mode) { + case 0: + { + src += bompDecodeLineMode0(src, (byte*)&line_buffer, bd->srcwidth); + break; + } + case 1: + { + src += bompDecodeLineMode1(src, (byte*)&line_buffer, bd->srcwidth); + break; + } + case 3: + { + src += bompDecodeLineMode3(src, (byte*)&line_buffer, bd->srcwidth); + break; + } + } + + if (mask == 3) { + if (bd->scale_y != 255) { + tmp = skip_y_new & skip_y; + skip_y >>= 1; + if (skip_y == 0) { + skip_y = 128; + skip_y_new = *(_bompScallingYPtr++); } - src += num; + + if (tmp != 0) + continue; + } + + if (bd->scale_x != 255) { + bompScaleFuncX((byte*)&line_buffer, _bompScallingXPtr, 128, bd->srcwidth); } } - dest += bd->outwidth; - dst_y++; - - } - if (scale_rows) - free(scale_rows); - if (scale_cols) - free(scale_cols); - CHECK_HEAP; -} + if (clip_top-- > 0) + goto labelBompSkip; + if (mask == 1) { + bompApplyMask(line_ptr, mask_out, bits, clip_right); + } -/* Yazoo: This function create the specialPalette used for semi-transparency in SamnMax */ + bompApplyActorPalette(line_ptr, clip_right); + switch(_bompShadowMode) { + case 0: + { + bompApplyShadow0(line_ptr, dst, clip_right); + break; + } + case 1: + { + bompApplyShadow1(line_ptr, dst, clip_right); + break; + } + case 3: + { + bompApplyShadow3(line_ptr, dst, clip_right); + break; + } + } + +labelBompSkip: + mask_out += _bompMaskPitch; + pos_y++; + dst += bd->outwidth; + if (pos_y >= clip_bottom) + break; + } +} +/* Yazoo: This function create the specialPalette used for semi-transparency in SamnMax */ void Scumm::createSpecialPalette(int16 a, int16 b, int16 c, int16 d, int16 e, int16 colorMin, int16 colorMax) { diff --git a/scumm/object.cpp b/scumm/object.cpp index 11246ad16c..fefa9833e7 100644 --- a/scumm/object.cpp +++ b/scumm/object.cpp @@ -1248,13 +1248,154 @@ void Scumm::drawBlastObject(BlastObject *eo) bdd.dataptr = bomp + 10; bdd.x = eo->posX; bdd.y = eo->posY; - bdd.scale_x = (unsigned char)eo->scaleX; - bdd.scale_y = (unsigned char)eo->scaleY; + bdd.scale_x = (byte)eo->scaleX; + bdd.scale_y = (byte)eo->scaleY; + + byte bomp_scalling_x[64], bomp_scalling_y[64]; + + _bompShadowMode = 0; + + if ((bdd.scale_x != 255) || (bdd.scale_y != 255)) { + _bompScallingXPtr = (byte*)&bomp_scalling_x; + _bompScallingYPtr = (byte*)&bomp_scalling_y; + _bompScaleRight = setupBompScale(_bompScallingXPtr, bdd.srcwidth, bdd.scale_x); + _bompScaleBottom = setupBompScale(_bompScallingYPtr, bdd.srcheight, bdd.scale_y); + drawBomp(&bdd, 0, bdd.dataptr, 1, 3); + } else { + _bompShadowMode = eo->mode; + drawBomp(&bdd, 0, bdd.dataptr, 1, 0); + } + + _bompShadowMode = 0; + _bompScallingXPtr = NULL; + _bompScallingYPtr = NULL; + _bompScaleRight = 0; + _bompScaleBottom = 0; - drawBomp(&bdd, 0, bdd.dataptr, 1, 0); updateDirtyRect(vs->number, bdd.x, bdd.x + bdd.srcwidth, bdd.y, bdd.y + bdd.srcheight, 0); } +byte _bompScaleTable[] = { + 0, 128, 64, 192, 32, 160, 96, 224, + 16, 144, 80, 208, 48, 176, 112, 240, + 8, 136, 72, 200, 40, 168, 104, 232, + 24, 152, 88, 216, 56, 184, 120, 248, + 4, 132, 68, 196, 36, 164, 100, 228, + 20, 148, 84, 212, 52, 180, 116, 244, + 12, 140, 76, 204, 44, 172, 108, 236, + 28, 156, 92, 220, 60, 188, 124, 252, + 2, 130, 66, 194, 34, 162, 98, 226, + 18, 146, 82, 210, 50, 178, 114, 242, + 10, 138, 74, 202, 42, 170, 106, 234, + 26, 154, 90, 218, 58, 186, 122, 250, + 6, 134, 70, 198, 38, 166, 102, 230, + 22, 150, 86, 214, 54, 182, 118, 246, + 14, 142, 78, 206, 46, 174, 110, 238, + 30, 158, 94, 222, 62, 190, 126, 254, + 1, 129, 65, 193, 33, 161, 97, 225, + 17, 145, 81, 209, 49, 177, 113, 241, + 9, 137, 73, 201, 41, 169, 105, 233, + 25, 153, 89, 217, 57, 185, 121, 249, + 5, 133, 69, 197, 37, 165, 101, 229, + 21, 149, 85, 213, 53, 181, 117, 245, + 13, 141, 77, 205, 45, 173, 109, 237, + 29, 157, 93, 221, 61, 189, 125, 253, + 3, 131, 67, 195, 35, 163, 99, 227, + 19, 147, 83, 211, 51, 179, 115, 243, + 11, 139, 75, 203, 43, 171, 107, 235, + 27, 155, 91, 219, 59, 187, 123, 251, + 7, 135, 71, 199, 39, 167, 103, 231, + 23, 151, 87, 215, 55, 183, 119, 247, + 15, 143, 79, 207, 47, 175, 111, 239, + 31, 159, 95, 223, 63, 191, 127, 255, +}; + +byte _bompBitsTable[] = { + 8, 7, 7, 6, 7, 6, 6, 5, 7, 6, 6, 5, 6, 5, 5, 4, + 7, 6, 6, 5, 6, 5, 5, 4, 6, 5, 5, 4, 5, 4, 4, 3, + 7, 6, 6, 5, 6, 5, 5, 4, 6, 5, 5, 4, 5, 4, 4, 3, + 6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, + 7, 6, 6, 5, 6, 5, 5, 4, 6, 5, 5, 4, 5, 4, 4, 3, + 6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, + 6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, + 5, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1, + 7, 6, 6, 5, 6, 5, 5, 4, 6, 5, 5, 4, 5, 4, 4, 3, + 6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, + 6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, + 5, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1, + 6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, + 5, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1, + 5, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1, + 4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0, +}; + +int32 Scumm::setupBompScale(byte * scalling, int32 size, byte scale) { + uint32 tmp; + int32 count = (size + 7) >> 3; + byte * tmp_ptr = _bompScaleTable + (256 - (size >> 1)); + byte * tmp_scalling = scalling; + byte a = 0; + + while((count--) != 0) { + tmp = *(tmp_ptr + 3); + a <<= 1; + if (scale < tmp) { + a |= 1; + } + tmp = *(tmp_ptr + 2); + a <<= 1; + if (scale < tmp) { + a |= 1; + } + tmp = *(tmp_ptr + 1); + a <<= 1; + if (scale < tmp) { + a |= 1; + } + tmp = *(tmp_ptr + 0); + a <<= 1; + if (scale < tmp) { + a |= 1; + } + tmp_ptr += 4; + + tmp = *(tmp_ptr + 3); + a <<= 1; + if (scale < tmp) { + a |= 1; + } + tmp = *(tmp_ptr + 2); + a <<= 1; + if (scale < tmp) { + a |= 1; + } + tmp = *(tmp_ptr + 1); + a <<= 1; + if (scale < tmp) { + a |= 1; + } + tmp = *(tmp_ptr + 0); + a <<= 1; + if (scale < tmp) { + a |= 1; + } + tmp_ptr += 4; + + *(tmp_scalling++) = a; + } + if ((size & 7) != 0) { + *(tmp_scalling - 1) |= revBitMask[size & 7]; + } + + count = (size + 7) >> 3; + byte ret_value = 0; + while((count--) != 0) { + ret_value += *(*(scalling++) + _bompBitsTable); + } + + return ret_value; +} + void Scumm::removeBlastObjects() { BlastObject *eo; @@ -1298,8 +1439,8 @@ void Scumm::removeBlastObject(BlastObject *eo) if (left_strip < 0) left_strip = 0; - if (right_strip >= 240) - right_strip = 240; + if (right_strip >= 409) + right_strip = 409; for (i = left_strip; i <= right_strip; i++) gdi.resetBackground(top, bottom, i); diff --git a/scumm/scumm.h b/scumm/scumm.h index 6b4b3c3d5d..643633afed 100644 --- a/scumm/scumm.h +++ b/scumm/scumm.h @@ -778,7 +778,17 @@ public: void drawRoomObjects(int arg); void drawRoomObject(int i, int arg); void drawBox(int x, int y, int x2, int y2, int color); - void drawBomp(BompDrawData *bd, int param1, byte *dataPtr, int param2, int param3); + void drawBomp(BompDrawData * bd, int param1, byte *data_ptr, int decode_mode, int mask); + int32 setupBompScale(byte * scalling, int32 size, byte scale); + void bompScaleFuncX(byte * line_buffer, byte * scalling_x_ptr, byte skip, int32 size); + int32 bompDecodeLineMode0(byte * src, byte * line_buffer, int32 size); + int32 bompDecodeLineMode1(byte * src, byte * line_buffer, int32 size); + int32 bompDecodeLineMode3(byte * src, byte * line_buffer, int32 size); + void bompApplyMask(byte * line_buffer, byte * mask_out, byte bits, int32 size); + void bompApplyShadow0(byte * line_buffer, byte * dst, int32 size); + void bompApplyShadow1(byte * line_buffer, byte * dst, int32 size); + void bompApplyShadow3(byte * line_buffer, byte * dst, int32 size); + void bompApplyActorPalette(byte * line_buffer, int32 size); void restoreBG(int left, int top, int right, int bottom); void redrawBGStrip(int start, int num); @@ -865,13 +875,20 @@ public: void removeBlastObjects(); void removeBlastObject(BlastObject *eo); + uint16 _bompShadowMode; + int32 _bompScaleRight, _bompScaleBottom; + byte * _bompScallingXPtr, * _bompScallingYPtr; + byte * _bompMaskPtr; + int32 _bompMaskPitch; + byte * _bompActorPalletePtr; + int _drawObjectQueNr; byte _drawObjectQue[200]; byte _palManipStart, _palManipEnd; uint16 _palManipCounter; byte *_palManipPalette; byte *_palManipIntermediatePal; - uint32 gfxUsageBits[240]; + uint32 gfxUsageBits[409]; byte *_shadowPalette; int _shadowPaletteSize; byte _currentPalette[0x300]; |