Added light mask support (in the demo this is most visible when walking

under the shack), plus some other cleanups. The s->blend & 0x02 case looks
bogus to me, but I don't know where it's used and I can't see that the
original did it differently.

svn-id: r9819
This commit is contained in:
Torbjörn Andersson 2003-08-22 07:04:50 +00:00
parent 812f42ce8e
commit 641d164e21
2 changed files with 59 additions and 17 deletions

View File

@ -305,11 +305,11 @@ int32 UpdatePaletteMatchTable(uint8 *data)
} }
// FIXME: This used to be inlined - probably a good idea - but the
// linker complained when I tried to use it in sprite.cpp.
__inline uint8 QuickMatch(uint8 r, uint8 g, uint8 b) uint8 QuickMatch(uint8 r, uint8 g, uint8 b) {
return paletteMatch[((int32) (r >> 2) << 12) + ((int32) (g >> 2) << 6) + (b >> 2)];
{
return(paletteMatch[((int32) (r >> 2) << 12) + ((int32) (g >> 2) << 6) + (b >> 2)]);
} }

View File

@ -1466,7 +1466,7 @@ uint16 yScale[SCALE_MAXHEIGHT];
int32 DrawSprite(_spriteInfo *s) { int32 DrawSprite(_spriteInfo *s) {
uint8 *src, *dst; uint8 *src, *dst;
uint8 *sprite, *newSprite; uint8 *sprite, *newSprite;
uint8 pixel, red, green, blue; uint8 red, green, blue;
uint16 scale; uint16 scale;
int16 i, j; int16 i, j;
uint16 srcPitch; uint16 srcPitch;
@ -1477,8 +1477,6 @@ int32 DrawSprite(_spriteInfo *s) {
// original did: // original did:
// //
// * Anti-aliasing sprites when upscaling them. // * Anti-aliasing sprites when upscaling them.
// * The light mask. If a room has one the sprite should be colored
// by it, simulating light sources in the room.
// * We don't implement the various graphics quality settings at all. // * We don't implement the various graphics quality settings at all.
// //
// But it should be good enough for now. // But it should be good enough for now.
@ -1614,12 +1612,46 @@ int32 DrawSprite(_spriteInfo *s) {
freeSprite = true; freeSprite = true;
} }
// -----------------------------------------------------------------
// Light masking
// -----------------------------------------------------------------
// 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))) {
uint8 *lightMap;
if (!freeSprite) {
newSprite = (uint8 *) malloc(s->w * s->h);
memcpy(newSprite, sprite, s->w * s->h);
sprite = newSprite;
freeSprite = true;
}
src = sprite + rs.top * srcPitch + rs.left;
lightMap = lightMask + (rd.top + scrolly - 40) * locationWide + rd.left + scrollx;
for (i = 0; i < rs.bottom - rs.top; i++) {
for (j = 0; j < rs.right - rs.left; j++) {
if (src[j] && lightMap[j]) {
uint8 r = ((32 - lightMap[j]) * palCopy[src[j]][0]) >> 5;
uint8 g = ((32 - lightMap[j]) * palCopy[src[j]][1]) >> 5;
uint8 b = ((32 - lightMap[j]) * palCopy[src[j]][2]) >> 5;
src[j] = QuickMatch(r, g, b);
}
}
src += srcPitch;
lightMap += locationWide;
}
}
// ----------------------------------------------------------------- // -----------------------------------------------------------------
// Drawing // Drawing
// ----------------------------------------------------------------- // -----------------------------------------------------------------
src = sprite + rs.top * s->w + rs.left; src = sprite + rs.top * srcPitch + rs.left;
dst = (uint8 *) lpBackBuffer->_pixels + lpBackBuffer->_width * rd.top + rd.left; dst = lpBackBuffer->_pixels + lpBackBuffer->_width * rd.top + rd.left;
if (s->type & RDSPR_BLEND) { if (s->type & RDSPR_BLEND) {
if (s->blend & 0x01) { if (s->blend & 0x01) {
@ -1627,26 +1659,36 @@ int32 DrawSprite(_spriteInfo *s) {
for (i = 0; i < rs.bottom - rs.top; i++) { for (i = 0; i < rs.bottom - rs.top; i++) {
for (j = 0; j < rs.right - rs.left; j++) { for (j = 0; j < rs.right - rs.left; j++) {
if (src[j]) { if (src[j]) {
pixel = dst[j]; uint8 r = (palCopy[src[j]][0] * red + palCopy[dst[j]][0] * (8 - red)) >> 3;
dst[j] = paletteMatch[(((palCopy[src[j]][0] * red + palCopy[pixel][0] * (8 - red)) >> 5) << 12) + uint8 g = (palCopy[src[j]][1] * red + palCopy[dst[j]][1] * (8 - red)) >> 3;
(((palCopy[src[j]][1] * red + palCopy[pixel][1] * (8 - red)) >> 5) << 6) + uint8 b = (palCopy[src[j]][2] * red + palCopy[dst[j]][2] * (8 - red)) >> 3;
(((palCopy[src[j]][2] * red + palCopy[pixel][2] * (8 - red)) >> 5))]; dst[j] = QuickMatch(r, g, b);
} }
} }
src += srcPitch; src += srcPitch;
dst += lpBackBuffer->_width; dst += lpBackBuffer->_width;
} }
} else if (s->blend & 0x02) { } 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]; red = palCopy[s->blend >> 8][0];
green = palCopy[s->blend >> 8][0]; green = palCopy[s->blend >> 8][0];
blue = palCopy[s->blend >> 8][0]; blue = palCopy[s->blend >> 8][0];
for (i = 0; i < rs.bottom - rs.top; i++) { for (i = 0; i < rs.bottom - rs.top; i++) {
for (j = 0; j < rs.right - rs.left; j++) { for (j = 0; j < rs.right - rs.left; j++) {
if (src[j]) { if (src[j]) {
pixel = dst[j]; uint8 r = (src[j] * red + (16 - src[j]) * palCopy[dst[j]][0]) >> 4;
dst[j] = paletteMatch[((((src[j] * red + (16 - src[j]) * palCopy[pixel][0]) >> 4) >> 2) << 12) + uint8 g = (src[j] * green + (16 - src[j]) * palCopy[dst[j]][1]) >> 4;
((((src[j] * green + (16 - src[j]) * palCopy[pixel][1]) >> 4) >> 2) << 6) + uint8 b = (src[j] * blue + (16 - src[j]) * palCopy[dst[j]][2]) >> 4;
(((src[j] * blue + (16 - src[j]) * palCopy[pixel][2]) >> 4) >> 2)]; dst[j] = QuickMatch(r, g, b);
} }
} }
src += srcPitch; src += srcPitch;