aboutsummaryrefslogtreecommitdiff
path: root/scumm/gfx.cpp
diff options
context:
space:
mode:
authorJames Brown2002-09-16 15:53:52 +0000
committerJames Brown2002-09-16 15:53:52 +0000
commit66757f4d4d6d3c7a99d4bb3b24977186c0ebc76e (patch)
treecb96a6b47015664108724e4c6c6df36b4bfc8d6f /scumm/gfx.cpp
parent1e236d4c350b6951abdedf426d15a5fa03f1024f (diff)
downloadscummvm-rg350-66757f4d4d6d3c7a99d4bb3b24977186c0ebc76e.tar.gz
scummvm-rg350-66757f4d4d6d3c7a99d4bb3b24977186c0ebc76e.tar.bz2
scummvm-rg350-66757f4d4d6d3c7a99d4bb3b24977186c0ebc76e.zip
Patch 609563: eriktorbjorns drawBomp() rewrite.
Scaling + Alpha. Fixes Sam and Max and Dig bugs. svn-id: r4953
Diffstat (limited to 'scumm/gfx.cpp')
-rw-r--r--scumm/gfx.cpp234
1 files changed, 159 insertions, 75 deletions
diff --git a/scumm/gfx.cpp b/scumm/gfx.cpp
index aa74fa30bd..daa73af4fe 100644
--- a/scumm/gfx.cpp
+++ b/scumm/gfx.cpp
@@ -25,6 +25,7 @@
#include "gui/gui.h"
#include "gui/newgui.h"
#include "resource.h"
+#include "util.h"
enum {
kScrolltime = 500, // ms scrolling is supposed to take
@@ -3054,6 +3055,66 @@ int Scumm::remapPaletteColor(int r, int g, int b, uint threshold)
return bestitem;
}
+static int blend_cache[3][256];
+
+static void clear_blend_cache()
+{
+ int i, j;
+
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 256; j++)
+ blend_cache[i][j] = -1;
+}
+
+static byte blend(byte *pal, byte method, int dest_color)
+{
+ double val = 1.0;
+ int cache = 0;
+
+ switch (method) {
+ case 1:
+ cache = 0;
+ val = 0.5;
+ break;
+
+ case 2:
+ cache = 1;
+ val = 0.4;
+ break;
+
+ case 3:
+ cache = 2;
+ val = 1.1;
+ break;
+
+ case 255:
+ return dest_color;
+
+ default:
+ return method;
+ }
+
+ if (blend_cache[cache][dest_color] == -1) {
+ byte r = *(pal + 3 * dest_color + 0);
+ byte g = *(pal + 3 * dest_color + 1);
+ byte b = *(pal + 3 * dest_color + 2);
+
+ int new_r = (int) (val * r + 0.5);
+ int new_g = (int) (val * g + 0.5);
+ int new_b = (int) (val * b + 0.5);
+
+ if (new_r > 255)
+ new_r = 255;
+ if (new_g > 255)
+ new_g = 255;
+ if (new_b > 255)
+ new_g = 255;
+
+ blend_cache[cache][dest_color] = RGBMatch(pal, new_r, new_g, new_b);
+ }
+
+ return blend_cache[cache][dest_color];
+}
// param3= clipping
@@ -3062,95 +3123,118 @@ int Scumm::remapPaletteColor(int r, int g, int b, uint threshold)
// 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;
- bool inside;
+ uint i;
if (h == 0 || bd->srcwidth == 0)
return;
- inside = (bd->x >= 0) && (bd->y >= 0) &&
- (bd->x <= bd->outwidth - bd->srcwidth) && (bd->y <= bd->outheight - bd->srcheight);
+ if (bd->scale_x != 255) {
+ scale_rows = (byte *) calloc(bd->srcheight, 1);
+ if (scale_rows == NULL) {
+ warning("drawBomp: out of memory");
+ return;
+ }
+ }
- if (1 || bd->scale_x == 255 && bd->scale_y == 255) {
- /* Routine used when no scaling is needed */
- if (inside) {
- dest += bd->x;
- src = bd->dataptr;
- do {
- byte code, color;
- uint len = bd->srcwidth, num, i;
- byte *d = dest;
- src += 2;
- do {
- code = *src++;
- num = (code >> 1) + 1;
- if (num > len)
- num = len;
- len -= num;
- if (code & 1) {
- color = *src++;
- if (color != 255) {
- do
- *d++ = color;
- while (--num);
- } else {
- d += num;
- }
- } else {
- for (i = 0; i < num; i++)
- if ((color = src[i]) != 255)
- d[i] = color;
- d += num;
- src += num;
- }
- } while (len);
- dest += bd->outwidth;
- } while (--h);
- } else {
- uint y = bd->y;
- src = bd->dataptr;
+ if (bd->scale_y != 255) {
+ scale_cols = (byte *) calloc(bd->srcwidth, 1);
+ if (scale_cols == NULL) {
+ warning("drawBomp: out of memory");
+ return;
+ }
+ }
- do {
- byte color;
- uint len, num;
- uint x;
- if ((uint) y >= (uint) bd->outheight) {
- src += READ_LE_UINT16(src) + 2;
- continue;
- }
- len = bd->srcwidth;
- x = bd->x;
+ // 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.
- src += 2;
- do {
- byte code = *src++;
- num = (code >> 1) + 1;
- if (num > len)
- num = len;
- len -= num;
- if (code & 1) {
- if ((color = *src++) != 255) {
- do {
- if ((uint) x < (uint) bd->outwidth)
- dest[x] = color;
- } while (++x, --num);
- } else {
- x += num;
+ 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;
+ }
+
+ 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;
+ }
+
+ clear_blend_cache();
+
+ dest += bd->x;
+ src = bd->dataptr;
+ for (src_y = 0, dst_y = bd->y; src_y < bd->srcheight; src_y++) {
+ byte code, color;
+ uint len, num;
+ byte *d = dest;
+
+ if (dst_y < 0 || dst_y >= bd->outheight) {
+ src += READ_LE_UINT16(src) + 2;
+ continue;
+ }
+
+ 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++;
+ if (bd->scale_y == 255 || scale_rows[src_y]) {
+ do {
+ if (dst_x >= 0 && dst_x < bd->outwidth && (bd->scale_x || scale_cols[src_x]))
+ *d = blend(_currentPalette, color, *d);
+ if (bd->scale_x == 255 || scale_cols[src_x]) {
+ d++;
+ dst_x++;
}
- } else {
- do {
- if ((color = *src++) != 255 && (uint) x < (uint) bd->outwidth)
- dest[x] = color;
- } while (++x, --num);
+ src_x++;
+ } while (--num);
+ } else {
+ src_x += num;
+ dst_x += num;
+ }
+ } else {
+ if (bd->scale_y == 255 || scale_rows[src_y]) {
+ for (i = 0; i < num; i++) {
+ if (dst_x >= 0 && dst_x < bd->outwidth && (bd->scale_x || scale_cols[src_x]))
+ *d = blend(_currentPalette, src[i], *d);
+ if (bd->scale_x == 255 || scale_cols[src_x]) {
+ d++;
+ dst_x++;
+ }
+ src_x++;
}
- } while (len);
- } while (dest += bd->outwidth, y++, --h);
+ } else {
+ dst_x += num;
+ src_x += num;
+ }
+ src += num;
+ }
+ }
+ if (bd->scale_y == 255 || scale_rows[src_y]) {
+ dest += bd->outwidth;
+ dst_y++;
}
- } else {
- /* scaling of bomp images not supported yet */
}
+ if (scale_rows)
+ free(scale_rows);
+ if (scale_cols)
+ free(scale_cols);
CHECK_HEAP;
}