aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTorbjörn Andersson2003-08-26 06:53:00 +0000
committerTorbjörn Andersson2003-08-26 06:53:00 +0000
commit8277c6cb798552de5ef315311db18f91a25e42fc (patch)
tree18606d41b4db06dda28acc075af1141c750fbcff
parentf3675261a970ca1c76870f3ebbf3774771d22270 (diff)
downloadscummvm-rg350-8277c6cb798552de5ef315311db18f91a25e42fc.tar.gz
scummvm-rg350-8277c6cb798552de5ef315311db18f91a25e42fc.tar.bz2
scummvm-rg350-8277c6cb798552de5ef315311db18f91a25e42fc.zip
The graphics detail settings partially work now. They only affect how
sprites are drawn, but I think that's how it should be. 1: No bells or whistles. 2: This setting adds sprite blending, e.g. the smoke at the docks or the display cases at the Glease Gallery. 3: This setting adds light map support, e.g. when walking under the shack at the docks. 4: This setting adds better scaling algorithms. The first three settings should work fine now. In fact, the third setting is what we used to implement. The fourth setting still needs work and testing. I've added code for downscaling case, but frankly I'm not convinced the result is any better than with the simpler scaler. I usually can't even tell the difference. Of course, my translation of the original code could very well be buggy. svn-id: r9867
-rw-r--r--sword2/controls.cpp123
-rw-r--r--sword2/controls.h2
-rw-r--r--sword2/driver/d_draw.cpp33
-rw-r--r--sword2/driver/driver96.h10
-rw-r--r--sword2/driver/menu.cpp2
-rw-r--r--sword2/driver/render.cpp64
-rw-r--r--sword2/driver/render.h4
-rw-r--r--sword2/driver/sprite.cpp196
-rw-r--r--sword2/sword2.cpp4
9 files changed, 194 insertions, 244 deletions
diff --git a/sword2/controls.cpp b/sword2/controls.cpp
index 3c0233a7aa..bff471b817 100644
--- a/sword2/controls.cpp
+++ b/sword2/controls.cpp
@@ -1919,7 +1919,7 @@ int32 ReadOptionSettings(void) //pete10Jun97
g_sword2->_sound->MuteFx(buff[5]);
- UpdateGraphicsLevel(GetRenderType(), buff[6]); // (James13jun97)
+ UpdateGraphicsLevel(buff[6]); // (James13jun97)
speechSelected = !buff[4];
subtitles = buff[7];
@@ -2091,7 +2091,6 @@ void Option_control(void) //Pete6Jun97
//uint8 safe_musicVolume = musicVolume;
//uint8 safe_speechVolume = speechVolume;
//uint8 safe_fxVolume = fxVolume;
- uint8 safe_grfxLevel = grfxLevel;
// button state variables
uint8 dreverse_stereo_state = 0, dmusic_mute_state = 0, dspeech_mute_state = 0, dfx_mute_state = 0, dobject_state = 0, dsubtitle_state = 0;
@@ -2540,7 +2539,7 @@ void Option_control(void) //Pete6Jun97
lb_down = 0;
if (touching_restore_button && restore_button_state) // ok to settings
{
- UpdateGraphicsLevel(safe_grfxLevel, grfxLevel); // (James13jun97)
+ UpdateGraphicsLevel(grfxLevel); // (James13jun97)
g_sword2->_sound->MuteMusic(music_mute_state); // Ensure all the levels are recorded correctly (Pete21Aug97)
g_sword2->_sound->MuteSpeech(speech_mute_state);
@@ -2784,106 +2783,34 @@ void Option_control(void) //Pete6Jun97
return; //just return to game
}
-//-----------------------------------------------------------------------------------------------------------------------
-void UpdateGraphicsLevel(uint8 oldLevel, uint8 newLevel) // (James13jun97)
-{
-
- switch (oldLevel) // Set the graphics level
- {
- //-------------------------------
- case 0: // lowest setting: h/w only; no graphics fx
- switch(newLevel)
- {
- case 0:
- break;
-
- case 1:
- ClearBltFx();
- ClearShadowFx();
- CloseBackgroundLayer();
- break;
-
- case 2:
- ClearBltFx();
- CloseBackgroundLayer();
- break;
-
- case 3: // same as case 2 until case 2 has edge-blending inactivated
- CloseBackgroundLayer();
- break;
- }
+void UpdateGraphicsLevel(uint8 newLevel) { // (James13jun97)
+ switch (newLevel) {
+ case 0: // Lowest setting: no graphics fx
+ ClearTransFx();
+ ClearShadowFx();
+ ClearBltFx();
break;
- //-------------------------------
- case 1: // medium-low setting: s/w transparency-blending
- switch(newLevel)
- {
- case 1:
- break;
-
- case 0:
- SetUpBackgroundLayers(); // InitialiseBackgroundLayer for each layer! (see layers.cpp)
- break;
-
- case 2:
- SetShadowFx();
- break;
-
- case 3: // same as case 2 until case 2 has edge-blending inactivated
- SetBltFx();
- break;
- }
+ case 1: // Medium-low setting: transparency-blending
+ SetTransFx();
+ ClearShadowFx();
+ ClearBltFx();
break;
- //-------------------------------
- case 2: // medium-high setting: s/w transparency-blending + shading
- switch(newLevel)
- {
- case 2:
- break;
-
- case 3: // same as case 2 until case 2 has edge-blending inactivated
- SetBltFx();
- break;
-
- case 1:
- ClearShadowFx();
- break;
-
- case 0:
- SetUpBackgroundLayers(); // InitialiseBackgroundLayer for each layer! (see layers.cpp)
- break;
- }
+ case 2: // Medium-high setting: transparency-blending + shading
+ SetTransFx();
+ SetShadowFx();
+ ClearBltFx();
break;
- //-------------------------------
- case 3: // highest setting: s/w transparency-blending + shading + edge-blending (& improved stretching)
- switch(newLevel)
- {
- case 2:
- ClearBltFx();
- break;
-
- case 3: // same as case 2 until case 2 has edge-blending inactivated
- break;
-
- case 1:
- ClearBltFx();
- ClearShadowFx();
- break;
-
- case 0:
- SetUpBackgroundLayers(); // InitialiseBackgroundLayer for each layer! (see layers.cpp)
- break;
- }
+ case 3: // Highest setting: transparency-blending + shading + edge-blending + improved stretching
+ SetTransFx();
+ SetShadowFx();
+ SetBltFx();
break;
- //-------------------------------
}
- // update our global variable - which needs to be checked when dimming the palette
- // in PauseGame() in sword2.cpp (since palette-matching cannot be done with dimmed palette
- // so we turn down one notch while dimmed, if at top level)
+ // update our global variable - which needs to be checked when dimming
+ // the palette in PauseGame() in sword2.cpp (since palette-matching
+ // cannot be done with dimmed palette so we turn down one notch while
+ // dimmed, if at top level)
+
current_graphics_level = newLevel;
}
-//-----------------------------------------------------------------------------------------------------------------------
-//-----------------------------------------------------------------------------------------------------------------------
-//-----------------------------------------------------------------------------------------------------------------------
-//-----------------------------------------------------------------------------------------------------------------------
-
diff --git a/sword2/controls.h b/sword2/controls.h
index 95045e2e63..535ff1e1ea 100644
--- a/sword2/controls.h
+++ b/sword2/controls.h
@@ -29,7 +29,7 @@ void Quit_control(void); //Tony2Apr97
void Restart_control(void); //Tony4Apr97
void Option_control(void); //Pete5Jun97
int32 ReadOptionSettings(void); //Pete10Jun97
-void UpdateGraphicsLevel(uint8 oldLevel, uint8 newLevel); // (James13jun97)
+void UpdateGraphicsLevel(uint8 newLevel); // (James13jun97)
extern uint8 subtitles; // text selected
extern uint8 speechSelected;
diff --git a/sword2/driver/d_draw.cpp b/sword2/driver/d_draw.cpp
index 68dc133c0c..752a06f304 100644
--- a/sword2/driver/d_draw.cpp
+++ b/sword2/driver/d_draw.cpp
@@ -123,24 +123,35 @@ int32 InitialiseDisplay(int16 width, int16 height, int16 colourDepth, int32 wind
return(RD_OK);
}
-int32 SetBltFx(void) {
- renderCaps |= RDBLTFX_EDGEBLEND + RDBLTFX_ARITHMETICSTRETCH;
- return(RD_OK);
+// FIXME: Clean up this mess. I don't want to add any new flags, but some of
+// them should be renamed. Or maybe we should abandon the whole renderCaps
+// thing and simply check the numeric value of the graphics quality setting
+// instead.
+
+// Note that SetTransFx() actually clears a bit. That's intentional.
+
+void SetTransFx(void) {
+ renderCaps &= ~RDBLTFX_ALLHARDWARE;
}
-int32 ClearBltFx(void) {
- renderCaps &= (0xffffffff - RDBLTFX_EDGEBLEND - RDBLTFX_ARITHMETICSTRETCH);
- return(RD_OK);
+void ClearTransFx(void) {
+ renderCaps |= RDBLTFX_ALLHARDWARE;
}
-int32 ClearShadowFx(void) {
- renderCaps &= (0xffffffff - RDBLTFX_SHADOWBLEND);
- return(RD_OK);
+void SetBltFx(void) {
+ renderCaps |= (RDBLTFX_EDGEBLEND | RDBLTFX_ARITHMETICSTRETCH);
}
-int32 SetShadowFx(void) {
+void ClearBltFx(void) {
+ renderCaps &= ~(RDBLTFX_EDGEBLEND | RDBLTFX_ARITHMETICSTRETCH);
+}
+
+void SetShadowFx(void) {
renderCaps |= RDBLTFX_SHADOWBLEND;
- return RD_OK;
+}
+
+void ClearShadowFx(void) {
+ renderCaps &= ~RDBLTFX_SHADOWBLEND;
}
int32 GetRenderType(void)
diff --git a/sword2/driver/driver96.h b/sword2/driver/driver96.h
index 9255566165..8f8a304aa9 100644
--- a/sword2/driver/driver96.h
+++ b/sword2/driver/driver96.h
@@ -1476,10 +1476,12 @@ typedef struct {
extern int32 InitialiseDisplay(int16 width, int16 height, int16 colourDepth, int32 windowType);
extern int32 WaitForVbl(void);
extern int32 EraseBackBuffer(void);
-extern int32 SetBltFx(void);
-extern int32 ClearBltFx(void);
-extern int32 ClearShadowFx(void);
-extern int32 SetShadowFx(void);
+extern void SetTransFx(void);
+extern void ClearTransFx(void);
+extern void SetBltFx(void);
+extern void ClearBltFx(void);
+extern void ClearShadowFx(void);
+extern void SetShadowFx(void);
extern int32 GetRenderType(void);
extern int32 PlaySmacker(char *filename, _movieTextObject *textObjects[], uint8 *musicOut);
extern void GetDrawStatus(_drvDrawStatus *s);
diff --git a/sword2/driver/menu.cpp b/sword2/driver/menu.cpp
index 241866e8f8..2f6d1d6314 100644
--- a/sword2/driver/menu.cpp
+++ b/sword2/driver/menu.cpp
@@ -238,7 +238,7 @@ int32 ProcessMenu(void) {
if (pocketStatus[menu][i] != MAXMENUANIMS) {
SquashImage(
dst, lpBackBuffer->_width, r.right - r.left, r.bottom - r.top,
- src, RDMENU_ICONWIDE, RDMENU_ICONWIDE, RDMENU_ICONDEEP);
+ src, RDMENU_ICONWIDE, RDMENU_ICONWIDE, RDMENU_ICONDEEP, NULL);
} else {
for (int j = 0; j < RDMENU_ICONDEEP; j++) {
memcpy(dst, src, RDMENU_ICONWIDE);
diff --git a/sword2/driver/render.cpp b/sword2/driver/render.cpp
index 1d9749e3f8..3bdc306f97 100644
--- a/sword2/driver/render.cpp
+++ b/sword2/driver/render.cpp
@@ -349,15 +349,16 @@ void UploadRect(ScummVM::Rect *r) {
static uint16 xScale[SCALE_MAXWIDTH];
static uint16 yScale[SCALE_MAXHEIGHT];
-// This is based on the "line doubling" scaler in the original sprite renderer.
-// I've made it into two separate functions because there were cases from
+// I've made the scaling two separate functions because there were cases from
// DrawSprite() where it wasn't obvious if the sprite should grow or shrink,
// which caused crashes.
//
-// The functions can probably be merged later, if/when we implement a better
-// scale function for it.
+// Maybe the functions can be merged later?
+//
+// The code is based on the original DrawSprite() code, so apart from not
+// knowing if I got it right, I don't know how good the original really is.
-void SquashImage(byte *dst, uint16 dstPitch, uint16 dstWidth, uint16 dstHeight,byte *src, uint16 srcPitch, uint16 srcWidth, uint16 srcHeight) {
+void SquashImage(byte *dst, uint16 dstPitch, uint16 dstWidth, uint16 dstHeight, byte *src, uint16 srcPitch, uint16 srcWidth, uint16 srcHeight, byte *backbuf) {
int32 ince, incne, d;
int16 x, y;
@@ -403,15 +404,56 @@ void SquashImage(byte *dst, uint16 dstPitch, uint16 dstWidth, uint16 dstHeight,b
// Copy the image
- for (y = 0; y < dstHeight; y++) {
- for (x = 0; x < dstWidth; x++) {
- dst[x] = src[yScale[y] * srcPitch + xScale[x]];
+ if (backbuf) {
+ for (y = 0; y < dstHeight; y++) {
+ for (x = 0; x < dstWidth; x++) {
+ uint8 p;
+ uint8 p1 = 0;
+ int count = 0;
+ int spriteCount = 0;
+ int red = 0;
+ int green = 0;
+ int blue = 0;
+ int i, j;
+
+ for (j = yScale[y]; j < yScale[y + 1]; j++) {
+ for (i = xScale[x]; i < xScale[x + 1]; i++) {
+ p = src[j * srcPitch + i];
+ if (p) {
+ red += palCopy[p][0];
+ green += palCopy[p][1];
+ blue += palCopy[p][2];
+ p1 = p;
+ spriteCount++;
+ } else {
+ red += palCopy[backbuf[x]][0];
+ green += palCopy[backbuf[x]][1];
+ blue += palCopy[backbuf[x]][2];
+ }
+ count++;
+ }
+ }
+ if (spriteCount == 0)
+ dst[x] = 0;
+ else if (spriteCount == 1)
+ dst[x] = p1;
+ else
+ dst[x] = QuickMatch((uint8) (red / count), (uint8) (green / count), (uint8) (blue / count));
+ }
+ dst += dstPitch;
+ backbuf += lpBackBuffer->_width;
+ }
+ } else {
+ for (y = 0; y < dstHeight; y++) {
+ for (x = 0; x < dstWidth; x++) {
+ dst[x] = src[yScale[y] * srcPitch + xScale[x]];
+ }
+ dst += dstPitch;
}
- dst += dstPitch;
}
}
-void StretchImage(byte *dst, uint16 dstPitch, uint16 dstWidth, uint16 dstHeight,byte *src, uint16 srcPitch, uint16 srcWidth, uint16 srcHeight) {
+void StretchImage(byte *dst, uint16 dstPitch, uint16 dstWidth, uint16 dstHeight, byte *src, uint16 srcPitch, uint16 srcWidth, uint16 srcHeight, byte *backbuf) {
int32 ince, incne, d;
int16 x, y, i, j, k;
@@ -456,6 +498,8 @@ void StretchImage(byte *dst, uint16 dstPitch, uint16 dstWidth, uint16 dstHeight,
// Copy the image
+ // FIXME: If backbuf != NULL the image should be anti-aliased
+
for (y = 0; y < srcHeight; y++) {
for (j = yScale[y]; j < yScale[y + 1]; j++) {
k = 0;
diff --git a/sword2/driver/render.h b/sword2/driver/render.h
index d49d64ee11..afae35874d 100644
--- a/sword2/driver/render.h
+++ b/sword2/driver/render.h
@@ -88,8 +88,8 @@ extern int16 locationDeep;
// extern uint8 myScreenBuffer[RENDERWIDE * RENDERDEEP];
-void SquashImage(byte *dst, uint16 dstPitch, uint16 dstWidth, uint16 dstHeight, byte *src, uint16 srcPitch, uint16 srcWidth, uint16 srcHeight);
-void StretchImage(byte *dst, uint16 dstPitch, uint16 dstWidth, uint16 dstHeight, byte *src, uint16 srcPitch, uint16 srcWidth, uint16 srcHeight);
+void SquashImage(byte *dst, uint16 dstPitch, uint16 dstWidth, uint16 dstHeight, byte *src, uint16 srcPitch, uint16 srcWidth, uint16 srcHeight, byte *backbuf);
+void StretchImage(byte *dst, uint16 dstPitch, uint16 dstWidth, uint16 dstHeight, byte *src, uint16 srcPitch, uint16 srcWidth, uint16 srcHeight, byte *backbuf);
void UploadRect(ScummVM::Rect *r);
diff --git a/sword2/driver/sprite.cpp b/sword2/driver/sprite.cpp
index 324f7981bf..023b61f35c 100644
--- a/sword2/driver/sprite.cpp
+++ b/sword2/driver/sprite.cpp
@@ -1298,9 +1298,9 @@ int32 DrawSurface(_spriteInfo *s, uint8 *surface) {
return RDERR_OUTOFMEMORY;
if (scale < 256) {
- SquashImage(sprite, s->scaledWidth, s->scaledWidth, s->scaledHeight, surface, s->w, s->w, s->h);
+ SquashImage(sprite, s->scaledWidth, s->scaledWidth, s->scaledHeight, surface, s->w, s->w, s->h, NULL);
} else {
- StretchImage(sprite, s->scaledWidth, s->scaledWidth, s->scaledHeight, surface, s->w, s->w, s->h);
+ StretchImage(sprite, s->scaledWidth, s->scaledWidth, s->scaledHeight, surface, s->w, s->w, s->h, NULL);
}
freeSprite = true;
@@ -1348,20 +1348,19 @@ uint16 yScale[SCALE_MAXHEIGHT];
int32 DrawSprite(_spriteInfo *s) {
uint8 *src, *dst;
uint8 *sprite, *newSprite;
+ uint8 *backbuf = NULL;
uint8 red, green, blue;
uint16 scale;
int16 i, j;
uint16 srcPitch;
bool freeSprite = false;
+ bool clipped = false;
ScummVM::Rect rd, rs;
// FIXME: There are still a few minor details that I think the
- // original did:
- //
- // * Anti-aliasing sprites when upscaling them.
- // * We don't implement the various graphics quality settings at all.
- //
- // But it should be good enough for now.
+ // original did. Off-hand, I know that at the highest graphics
+ // quality setting sprites should be anti-aliased when they are
+ // upscaled.
// -----------------------------------------------------------------
// Decompression and mirroring
@@ -1445,18 +1444,22 @@ int32 DrawSprite(_spriteInfo *s) {
if (rd.top < 40) {
rs.top = (40 - rd.top) * 256 / scale;
rd.top = 40;
+ clipped = true;
}
if (rd.bottom > 440) {
rs.bottom -= ((rd.bottom - 440) * 256 / scale);
rd.bottom = 440;
+ clipped = true;
}
if (rd.left < 0) {
rs.left = (0 - rd.left) * 256 / scale;
rd.left = 0;
+ clipped = true;
}
if (rd.right > 640) {
rs.right -= ((rd.right - 640) * 256 / scale);
rd.right = 640;
+ clipped = true;
}
// -----------------------------------------------------------------
@@ -1464,6 +1467,10 @@ int32 DrawSprite(_spriteInfo *s) {
// -----------------------------------------------------------------
if (scale != 256) {
+ if ((renderCaps & RDBLTFX_ARITHMETICSTRETCH) && !clipped)
+ backbuf = lpBackBuffer->_pixels + lpBackBuffer->_width * rd.top + rd.left;
+
+
if (s->scaledWidth > SCALE_MAXWIDTH || s->scaledHeight > SCALE_MAXHEIGHT) {
if (freeSprite)
free(sprite);
@@ -1478,14 +1485,14 @@ int32 DrawSprite(_spriteInfo *s) {
}
if (scale < 256) {
- SquashImage(newSprite, s->scaledWidth, s->scaledWidth, s->scaledHeight, sprite, s->w, s->w, s->h);
+ SquashImage(newSprite, s->scaledWidth, s->scaledWidth, s->scaledHeight, sprite, s->w, s->w, s->h, backbuf);
} else {
if (s->scale > 512) {
if (freeSprite)
free(sprite);
return RDERR_INVALIDSCALING;
}
- StretchImage(newSprite, s->scaledWidth, s->scaledWidth, s->scaledHeight, sprite, s->w, s->w, s->h);
+ StretchImage(newSprite, s->scaledWidth, s->scaledWidth, s->scaledHeight, sprite, s->w, s->w, s->h, backbuf);
}
if (freeSprite)
@@ -1501,7 +1508,7 @@ int32 DrawSprite(_spriteInfo *s) {
// The light mask is an optional layer that covers the entire room
// and which is used to simulate light and shadows.
- if (lightMask && (scale != 256 || (s->type & RDSPR_SHADOW))) {
+ if ((renderCaps & RDBLTFX_SHADOWBLEND) && lightMask && (scale != 256 || (s->type & RDSPR_SHADOW))) {
uint8 *lightMap;
if (!freeSprite) {
@@ -1536,51 +1543,65 @@ int32 DrawSprite(_spriteInfo *s) {
dst = lpBackBuffer->_pixels + lpBackBuffer->_width * rd.top + rd.left;
if (s->type & RDSPR_BLEND) {
- if (s->blend & 0x01) {
- red = s->blend >> 8;
+ if (renderCaps & RDBLTFX_ALLHARDWARE) {
for (i = 0; i < rs.bottom - rs.top; i++) {
for (j = 0; j < rs.right - rs.left; j++) {
- if (src[j]) {
- uint8 r = (palCopy[src[j]][0] * red + palCopy[dst[j]][0] * (8 - red)) >> 3;
- uint8 g = (palCopy[src[j]][1] * red + palCopy[dst[j]][1] * (8 - red)) >> 3;
- uint8 b = (palCopy[src[j]][2] * red + palCopy[dst[j]][2] * (8 - red)) >> 3;
- dst[j] = QuickMatch(r, g, b);
- }
+ if (src[j] && ((i & 1) == (j & 1)))
+ dst[j] = src[j];
}
src += srcPitch;
dst += lpBackBuffer->_width;
}
- } else if (s->blend & 0x02) {
- // FIXME: This case looks bogus to me. The same value
- // for the red, green and blue parameters, and we
- // multiply with the source color's palette index
- // rather than its color component.
- //
- // But as far as I can see, that's how the original
- // code did it.
- //
- // Does anyone know where this case was used anyway?
-
- red = palCopy[s->blend >> 8][0];
- green = palCopy[s->blend >> 8][0];
- blue = palCopy[s->blend >> 8][0];
- for (i = 0; i < rs.bottom - rs.top; i++) {
- for (j = 0; j < rs.right - rs.left; j++) {
- if (src[j]) {
- uint8 r = (src[j] * red + (16 - src[j]) * palCopy[dst[j]][0]) >> 4;
- uint8 g = (src[j] * green + (16 - src[j]) * palCopy[dst[j]][1]) >> 4;
- uint8 b = (src[j] * blue + (16 - src[j]) * palCopy[dst[j]][2]) >> 4;
- dst[j] = QuickMatch(r, g, b);
+ } else {
+ if (s->blend & 0x01) {
+ red = s->blend >> 8;
+ for (i = 0; i < rs.bottom - rs.top; i++) {
+ for (j = 0; j < rs.right - rs.left; j++) {
+ if (src[j]) {
+ uint8 r = (palCopy[src[j]][0] * red + palCopy[dst[j]][0] * (8 - red)) >> 3;
+ uint8 g = (palCopy[src[j]][1] * red + palCopy[dst[j]][1] * (8 - red)) >> 3;
+ uint8 b = (palCopy[src[j]][2] * red + palCopy[dst[j]][2] * (8 - red)) >> 3;
+ dst[j] = QuickMatch(r, g, b);
+ }
}
+ src += srcPitch;
+ dst += lpBackBuffer->_width;
}
- src += srcPitch;
- dst += lpBackBuffer->_width;
+ } else if (s->blend & 0x02) {
+ // FIXME: This case looks bogus to me. The
+ // same value for the red, green and blue
+ // parameters, and we multiply with the source
+ // color's palette index rather than its color
+ // component.
+ //
+ // But as far as I can see, that's how the
+ // original
+ // code did it.
+ //
+ // Does anyone know where this case was used
+ // anyway?
+
+ red = palCopy[s->blend >> 8][0];
+ green = palCopy[s->blend >> 8][0];
+ blue = palCopy[s->blend >> 8][0];
+ for (i = 0; i < rs.bottom - rs.top; i++) {
+ for (j = 0; j < rs.right - rs.left; j++) {
+ if (src[j]) {
+ uint8 r = (src[j] * red + (16 - src[j]) * palCopy[dst[j]][0]) >> 4;
+ uint8 g = (src[j] * green + (16 - src[j]) * palCopy[dst[j]][1]) >> 4;
+ uint8 b = (src[j] * blue + (16 - src[j]) * palCopy[dst[j]][2]) >> 4;
+ dst[j] = QuickMatch(r, g, b);
+ }
+ }
+ src += srcPitch;
+ dst += lpBackBuffer->_width;
+ }
+ } else {
+ warning("DrawSprite: Invalid blended sprite");
+ if (freeSprite)
+ free(sprite);
+ return RDERR_UNKNOWNTYPE;
}
- } else {
- warning("DrawSprite: Invalid blended sprite");
- if (freeSprite)
- free(sprite);
- return RDERR_UNKNOWNTYPE;
}
} else {
if (s->type & RDSPR_TRANS) {
@@ -3266,85 +3287,30 @@ int32 DrawSprite(_spriteInfo *s) {
-int32 OpenLightMask(_spriteInfo *s)
-
-{
+int32 OpenLightMask(_spriteInfo *s) {
+ // FIXME: The light mask is only needed on higher graphics detail
+ // settings, so to save memory we could simply ignore it on lower
+ // settings. But then we need to figure out how to ensure that it
+ // is properly loaded if the user changes the settings in mid-game.
if (lightMask)
- return(RDERR_NOTCLOSED);
+ return RDERR_NOTCLOSED;
lightMask = (uint8 *) malloc(s->w * s->h);
-
- if (lightMask == NULL)
- return(RDERR_OUTOFMEMORY);
+ if (!lightMask)
+ return RDERR_OUTOFMEMORY;
if (DecompressRLE256(lightMask, s->data, s->w * s->h))
- return(RDERR_DECOMPRESSION);
-
- return(RD_OK);
+ return RDERR_DECOMPRESSION;
+ return RD_OK;
}
-int32 CloseLightMask(void)
-{
-
+int32 CloseLightMask(void) {
if (!lightMask)
- return(RDERR_NOTOPEN);
+ return RDERR_NOTOPEN;
free(lightMask);
-
lightMask = 0;
-
- return(RD_OK);
-
+ return RD_OK;
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/sword2/sword2.cpp b/sword2/sword2.cpp
index 90dd53b4ce..40edeffded 100644
--- a/sword2/sword2.cpp
+++ b/sword2/sword2.cpp
@@ -542,7 +542,7 @@ void PauseGame(void) // James17jun97
if (current_graphics_level==3) // if level at max
{
- UpdateGraphicsLevel(3,2); // turn down because palette-matching won't work when dimmed
+ UpdateGraphicsLevel(2); // turn down because palette-matching won't work when dimmed
graphics_level_fudged=1;
}
@@ -567,7 +567,7 @@ void UnpauseGame(void) // James17jun97
if (graphics_level_fudged) // if level at max
{
- UpdateGraphicsLevel(2,3); // turn up again
+ UpdateGraphicsLevel(3); // turn up again
graphics_level_fudged=0;
}