893 | | if (left < 0) |
894 | | left = 0; |
895 | | if (left > max_width) |
896 | | left -= left - max_width; |
897 | | |
898 | | // Yazoo: this is not correct, but fix a lots of bugs for the momment |
899 | | |
900 | | draw_top = 0; |
901 | | draw_bottom = vs->height; |
902 | | |
903 | | _vm->updateDirtyRect(0, left, right + 1, top, bottom + 1, 1 << dirty_id); |
904 | | |
905 | | bdd.dataptr = srcptr; |
906 | | bdd.out = outptr; |
907 | | bdd.outheight = outheight; |
908 | | bdd.outwidth = outwidth; |
909 | | bdd.scale_x = 0xFF; |
910 | | bdd.scale_y = 0xFF; |
911 | | bdd.srcheight = height; |
912 | | bdd.srcwidth = width; |
913 | | bdd.x = left + 1; |
914 | | bdd.y = top; |
| 895 | if (left >= _vm->_realWidth || top >= _vm->_realHeight) |
| 896 | return; |
| 897 | |
| 898 | // The actual drawing code shouldn't survive even if the image is |
| 899 | // partially outside the screen, but something before that seems to |
| 900 | // be less tolerant... |
| 901 | |
| 902 | clip_left = (left >= 0) ? left : 0; |
| 903 | clip_right = (right > _vm->_realWidth) ? _vm->_realWidth : right; |
| 904 | clip_top = (top >= 0) ? top : 0; |
| 905 | clip_bottom = (bottom > _vm->_realHeight) ? _vm->_realHeight : bottom; |
| 906 | |
| 907 | if (clip_top < draw_top) |
| 908 | draw_top = clip_top; |
| 909 | if (clip_bottom > draw_bottom) |
| 910 | draw_bottom = clip_bottom; |
| 911 | |
| 912 | _vm->updateDirtyRect(0, clip_left, clip_right, clip_top, clip_bottom, 1 << dirty_id); |
| 913 | |
| 914 | masking = false; |
| 915 | if (clipping) { |
| 916 | masking = _vm->isMaskActiveAt(clip_left, clip_top, clip_right, clip_bottom, |
| 917 | _vm->getResourceAddress(rtBuffer, 9) + |
| 918 | _vm->gdi._imgBufOffs[clipping] + |
| 919 | _vm->_screenStartStrip) != 0; |
| 920 | } |
| 921 | |
| 922 | v1.mask_ptr = NULL; |
| 923 | |
| 924 | if (masking || charsetmask) { |
| 925 | v1.mask_ptr = _vm->getResourceAddress(rtBuffer, 9) + _vm->_screenStartStrip; |
| 926 | v1.imgbufoffs = _vm->gdi._imgBufOffs[clipping]; |
| 927 | if (!charsetmask && masking) { |
| 928 | v1.mask_ptr += v1.imgbufoffs; |
| 929 | v1.imgbufoffs = 0; |
| 930 | } |
| 931 | } |
| 932 | |
| 933 | src = srcptr; |
| 934 | dest = outptr; |
916 | | _vm->drawBomp(&bdd, 0, bdd.dataptr, 0, 0); |
| 936 | for (src_y = 0, dst_y = top; src_y < height; src_y++) { |
| 937 | byte code, color; |
| 938 | uint num, i; |
| 939 | byte *d = dest + dst_y * _vm->_realWidth + left; |
| 940 | byte *s; |
| 941 | uint data_length; |
| 942 | |
| 943 | data_length = READ_LE_UINT16(src) + 2; |
| 944 | |
| 945 | if (dst_y < 0 || dst_y >= _vm->_realHeight) { |
| 946 | src += data_length; |
| 947 | dst_y++; |
| 948 | continue; |
| 949 | } |
| 950 | |
| 951 | src_x = 0; |
| 952 | dst_x = left; |
| 953 | s = src + 2; |
| 954 | |
| 955 | while (src_x < width) { |
| 956 | code = *s++; |
| 957 | num = (code >> 1) + 1; |
| 958 | if (code & 1) { |
| 959 | color = *s++; |
| 960 | for (i = 0; i < num; i++) { |
| 961 | if (dst_x >= 0 && dst_x < _vm->_realWidth) { |
| 962 | if (color != 255) { |
| 963 | if (v1.mask_ptr) |
| 964 | mask = v1.mask_ptr + 40 * dst_y + (dst_x >> 3); |
| 965 | maskbit = revBitMask[dst_x & 7]; |
| 966 | if (shadow_mode && color == 13) |
| 967 | color = shadow_table[*d]; |
| 968 | if (!mask || !((mask[0] | mask[v1.imgbufoffs]) & maskbit)) |
| 969 | *d = color; |
| 970 | } |
| 971 | } |
| 972 | d++; |
| 973 | dst_x++; |
| 974 | src_x++; |
| 975 | } |
| 976 | } else { |
| 977 | for (i = 0; i < num; i++) { |
| 978 | color = s[i]; |
| 979 | if (dst_x >= 0 && dst_x < _vm->_realWidth) { |
| 980 | if (color != 255) { |
| 981 | if (v1.mask_ptr) |
| 982 | mask = v1.mask_ptr + 40 * dst_y + (dst_x >> 3); |
| 983 | maskbit = revBitMask[dst_x & 7]; |
| 984 | if (shadow_mode && color == 13) |
| 985 | color = shadow_table[*d]; |
| 986 | if (!mask || !((mask[0] | mask[v1.imgbufoffs]) & maskbit)) |
| 987 | *d = color; |
| 988 | } |
| 989 | } |
| 990 | d++; |
| 991 | dst_x++; |
| 992 | src_x++; |
| 993 | } |
| 994 | s += num; |
| 995 | } |
| 996 | } |
| 997 | src += data_length; |
| 998 | dst_y++; |
| 999 | } |