Ticket #8049: drawbomp.diff

File drawbomp.diff, 6.1 KB (added by eriktorbjorn, 17 years ago)

Patch against a September 14 CVS snapshot

  • scummvm/scumm/gfx.cpp

    diff -ur ScummVM-cvs20020914/scummvm/scumm/gfx.cpp ScummVM-cvs20020914+hack/scummvm/scumm/gfx.cpp
    old new  
    2525#include "gui/gui.h"
    2626#include "gui/newgui.h"
    2727#include "resource.h"
     28#include "util.h"
    2829
    2930enum {
    3031        kScrolltime = 500,  // ms scrolling is supposed to take
     
    30543055        return bestitem;
    30553056}
    30563057
     3058static int blend_cache[3][256];
     3059
     3060static void clear_blend_cache()
     3061{
     3062        int i, j;
     3063
     3064        for (i = 0; i < 3; i++)
     3065                for (j = 0; j < 256; j++)
     3066                        blend_cache[i][j] = -1;
     3067}
     3068
     3069static byte blend(byte *pal, byte method, int dest_color)
     3070{
     3071        double val = 1.0;
     3072        int cache = 0;
     3073
     3074        switch (method) {
     3075                case 1:
     3076                        cache = 0;
     3077                        val = 0.5;
     3078                        break;
     3079
     3080                case 2:
     3081                        cache = 1;
     3082                        val = 0.4;
     3083                        break;
     3084
     3085                case 3:
     3086                        cache = 2;
     3087                        val = 1.1;
     3088                        break;
     3089
     3090                case 255:
     3091                        return dest_color;
     3092
     3093                default:
     3094                        return method;
     3095        }
     3096
     3097        if (blend_cache[cache][dest_color] == -1) {
     3098                byte r = *(pal + 3 * dest_color + 0);
     3099                byte g = *(pal + 3 * dest_color + 1);
     3100                byte b = *(pal + 3 * dest_color + 2);
     3101
     3102                int new_r = (int) (val * r + 0.5);
     3103                int new_g = (int) (val * g + 0.5);
     3104                int new_b = (int) (val * b + 0.5);
     3105
     3106                if (new_r > 255)
     3107                        new_r = 255;
     3108                if (new_g > 255)
     3109                        new_g = 255;
     3110                if (new_b > 255)
     3111                        new_g = 255;
     3112
     3113                blend_cache[cache][dest_color] = RGBMatch(pal, new_r, new_g, new_b);
     3114        }
     3115
     3116        return blend_cache[cache][dest_color];
     3117}
    30573118
    30583119// param3= clipping
    30593120
     
    30623123// param1= never used ?
    30633124void Scumm::drawBomp(BompDrawData *bd, int param1, byte *dataPtr, int param2, int param3)
    30643125{
     3126        byte *scale_rows = NULL;
     3127        byte *scale_cols = NULL;
    30653128        byte *dest = bd->out + bd->y * bd->outwidth, *src;
     3129        int src_x, src_y, dst_x, dst_y;
     3130        uint scaled_width, scaled_height;
    30663131        int h = bd->srcheight;
    3067         bool inside;
     3132        uint i;
    30683133
    30693134        if (h == 0 || bd->srcwidth == 0)
    30703135                return;
    30713136
    3072         inside = (bd->x >= 0) && (bd->y >= 0) &&
    3073                 (bd->x <= bd->outwidth - bd->srcwidth) && (bd->y <= bd->outheight - bd->srcheight);
     3137        if (bd->scale_x != 255) {
     3138                scale_rows = (byte *) calloc(bd->srcheight, 1);
     3139                if (scale_rows == NULL) {
     3140                        warning("drawBomp: out of memory");
     3141                        return;
     3142                }
     3143        }
    30743144
    3075         if (1 || bd->scale_x == 255 && bd->scale_y == 255) {
    3076                 /* Routine used when no scaling is needed */
    3077                 if (inside) {
    3078                         dest += bd->x;
    3079                         src = bd->dataptr;
    3080                         do {
    3081                                 byte code, color;
    3082                                 uint len = bd->srcwidth, num, i;
    3083                                 byte *d = dest;
    3084                                 src += 2;
    3085                                 do {
    3086                                         code = *src++;
    3087                                         num = (code >> 1) + 1;
    3088                                         if (num > len)
    3089                                                 num = len;
    3090                                         len -= num;
    3091                                         if (code & 1) {
    3092                                                 color = *src++;
    3093                                                 if (color != 255) {
    3094                                                         do
    3095                                                                 *d++ = color;
    3096                                                         while (--num);
    3097                                                 } else {
    3098                                                         d += num;
    3099                                                 }
    3100                                         } else {
    3101                                                 for (i = 0; i < num; i++)
    3102                                                         if ((color = src[i]) != 255)
    3103                                                                 d[i] = color;
    3104                                                 d += num;
    3105                                                 src += num;
    3106                                         }
    3107                                 } while (len);
    3108                                 dest += bd->outwidth;
    3109                         } while (--h);
    3110                 } else {
    3111                         uint y = bd->y;
    3112                         src = bd->dataptr;
     3145        if (bd->scale_y != 255) {       
     3146                scale_cols = (byte *) calloc(bd->srcwidth, 1);
     3147                if (scale_cols == NULL) {
     3148                        warning("drawBomp: out of memory");
     3149                        return;
     3150                }
     3151        }
    31133152
    3114                         do {
    3115                                 byte color;
    3116                                 uint len, num;
    3117                                 uint x;
    3118                                 if ((uint) y >= (uint) bd->outheight) {
    3119                                         src += READ_LE_UINT16(src) + 2;
    3120                                         continue;
    3121                                 }
    3122                                 len = bd->srcwidth;
    3123                                 x = bd->x;
     3153        // Select which rows and columns from the original to show in the
     3154        // scaled version of the image. This is a pretty stupid way of scaling
     3155        // images, but it will have to do for now.
    31243156
    3125                                 src += 2;
    3126                                 do {
    3127                                         byte code = *src++;
    3128                                         num = (code >> 1) + 1;
    3129                                         if (num > len)
    3130                                                 num = len;
    3131                                         len -= num;
    3132                                         if (code & 1) {
    3133                                                 if ((color = *src++) != 255) {
    3134                                                         do {
    3135                                                                 if ((uint) x < (uint) bd->outwidth)
    3136                                                                         dest[x] = color;
    3137                                                         } while (++x, --num);
    3138                                                 } else {
    3139                                                         x += num;
     3157        if (bd->scale_x < 255) {
     3158                scaled_width = (bd->srcwidth * bd->scale_x) / 255;
     3159                for (i = 0; i < scaled_width; i++)
     3160                        scale_cols[(i * 255) / bd->scale_x] = 1;
     3161        }
     3162
     3163        if (bd->scale_y < 255) {
     3164                scaled_height = (bd->srcheight * bd->scale_y) / 255;
     3165                for (i = 0; i < scaled_height; i++)
     3166                        scale_rows[(i * 255) / bd->scale_y] = 1;
     3167        }
     3168
     3169        clear_blend_cache();
     3170
     3171        dest += bd->x;
     3172        src = bd->dataptr;
     3173        for (src_y = 0, dst_y = bd->y; src_y < bd->srcheight; src_y++) {
     3174                byte code, color;
     3175                uint len, num;
     3176                byte *d = dest;
     3177
     3178                if (dst_y < 0 || dst_y >= bd->outheight) {
     3179                        src += READ_LE_UINT16(src) + 2;
     3180                        continue;
     3181                }
     3182
     3183                len = bd->srcwidth;
     3184                src_x = 0;
     3185                dst_x = bd->x;
     3186                src += 2;
     3187               
     3188                while (src_x < bd->srcwidth) {
     3189                        code = *src++;
     3190                        num = (code >> 1) + 1;
     3191                        if (num > len)
     3192                                num = len;
     3193                        len -= num;
     3194                        if (code & 1) {
     3195                                color = *src++;
     3196                                if (bd->scale_y == 255 || scale_rows[src_y]) {
     3197                                        do {
     3198                                                if (dst_x >= 0 && dst_x < bd->outwidth && (bd->scale_x || scale_cols[src_x]))
     3199                                                        *d = blend(_currentPalette, color, *d);
     3200                                                if (bd->scale_x == 255 || scale_cols[src_x]) {
     3201                                                        d++;
     3202                                                        dst_x++;
    31403203                                                }
    3141                                         } else {
    3142                                                 do {
    3143                                                         if ((color = *src++) != 255 && (uint) x < (uint) bd->outwidth)
    3144                                                                 dest[x] = color;
    3145                                                 } while (++x, --num);
     3204                                                src_x++;
     3205                                        } while (--num);
     3206                                } else {
     3207                                        src_x += num;
     3208                                        dst_x += num;
     3209                                }
     3210                        } else {
     3211                                if (bd->scale_y == 255 || scale_rows[src_y]) {
     3212                                        for (i = 0; i < num; i++) {
     3213                                                if (dst_x >= 0 && dst_x < bd->outwidth && (bd->scale_x || scale_cols[src_x]))
     3214                                                        *d = blend(_currentPalette, src[i], *d);
     3215                                                if (bd->scale_x == 255 || scale_cols[src_x]) {
     3216                                                        d++;
     3217                                                        dst_x++;
     3218                                                }
     3219                                                src_x++;
    31463220                                        }
    3147                                 } while (len);
    3148                         } while (dest += bd->outwidth, y++, --h);
     3221                                } else {
     3222                                        dst_x += num;
     3223                                        src_x += num;
     3224                                }
     3225                                src += num;
     3226                        }
     3227                }
     3228                if (bd->scale_y == 255 || scale_rows[src_y]) {
     3229                        dest += bd->outwidth;
     3230                        dst_y++;
    31493231                }
    3150         } else {
    3151                 /* scaling of bomp images not supported yet */
    31523232        }
    31533233
     3234        if (scale_rows)
     3235                free(scale_rows);
     3236        if (scale_cols)
     3237                free(scale_cols);
    31543238        CHECK_HEAP;
    31553239}
    31563240