144 lines
3.7 KiB
C
144 lines
3.7 KiB
C
|
#include "version.h"
|
||
|
|
||
|
#ifdef USE_SHADING
|
||
|
#include "wl_def.h"
|
||
|
#include "wl_shade.h"
|
||
|
|
||
|
typedef struct {
|
||
|
uint8_t destRed, destGreen, destBlue; // values between 0 and 255
|
||
|
uint8_t fogStrength;
|
||
|
} shadedef_t;
|
||
|
|
||
|
shadedef_t shadeDefs[] = {
|
||
|
{ 0, 0, 0, LSHADE_NOSHADING },
|
||
|
{ 0, 0, 0, LSHADE_NORMAL },
|
||
|
{ 0, 0, 0, LSHADE_FOG },
|
||
|
{ 40, 40, 40, LSHADE_NORMAL },
|
||
|
{ 60, 60, 60, LSHADE_FOG }
|
||
|
};
|
||
|
|
||
|
uint8_t shadetable[SHADE_COUNT][256];
|
||
|
int LSHADE_flag;
|
||
|
|
||
|
#ifdef USE_FEATUREFLAGS
|
||
|
|
||
|
// The lower 8-bit of the upper left tile of every map determine
|
||
|
// the used shading definition of shadeDefs.
|
||
|
static int GetShadeDefID()
|
||
|
{
|
||
|
int shadeID = ffDataTopLeft & 0x00ff;
|
||
|
assert(shadeID >= 0 && shadeID < lengthof(shadeDefs));
|
||
|
return shadeID;
|
||
|
}
|
||
|
|
||
|
#else
|
||
|
|
||
|
static int GetShadeDefID()
|
||
|
{
|
||
|
int shadeID;
|
||
|
switch(gamestate.episode * 10 + mapon)
|
||
|
{
|
||
|
case 0: shadeID = 4; break;
|
||
|
case 1:
|
||
|
case 2:
|
||
|
case 6: shadeID = 1; break;
|
||
|
case 3: shadeID = 0; break;
|
||
|
case 5: shadeID = 2; break;
|
||
|
default: shadeID = 3; break;
|
||
|
}
|
||
|
assert(shadeID >= 0 && shadeID < lengthof(shadeDefs));
|
||
|
return shadeID;
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
|
||
|
// Returns the palette index of the nearest matching color of the
|
||
|
// given RGB color in given palette
|
||
|
byte GetColor(byte red, byte green, byte blue, SDL_Color *palette)
|
||
|
{
|
||
|
byte mincol = 0;
|
||
|
double mindist = 200000.F, curdist, DRed, DGreen, DBlue;
|
||
|
|
||
|
SDL_Color *palPtr = palette;
|
||
|
|
||
|
for(int col = 0; col < 256; col++, palPtr++)
|
||
|
{
|
||
|
DRed = (double) (red - palPtr->r);
|
||
|
DGreen = (double) (green - palPtr->g);
|
||
|
DBlue = (double) (blue - palPtr->b);
|
||
|
curdist = DRed * DRed + DGreen * DGreen + DBlue * DBlue;
|
||
|
if(curdist < mindist)
|
||
|
{
|
||
|
mindist = curdist;
|
||
|
mincol = (byte) col;
|
||
|
}
|
||
|
}
|
||
|
return mincol;
|
||
|
}
|
||
|
|
||
|
// Fade all colors in 32 steps down to the destination-RGB
|
||
|
// (use gray for fogging, black for standard shading)
|
||
|
void GenerateShadeTable(byte destRed, byte destGreen, byte destBlue,
|
||
|
SDL_Color *palette, int fog)
|
||
|
{
|
||
|
double curRed, curGreen, curBlue, redStep, greenStep, blueStep;
|
||
|
SDL_Color *palPtr = palette;
|
||
|
|
||
|
// Set the fog-flag
|
||
|
LSHADE_flag=fog;
|
||
|
|
||
|
// Color loop
|
||
|
for(int i = 0; i < 256; i++, palPtr++)
|
||
|
{
|
||
|
// Get original palette color
|
||
|
curRed = palPtr->r;
|
||
|
curGreen = palPtr->g;
|
||
|
curBlue = palPtr->b;
|
||
|
|
||
|
// Calculate increment per step
|
||
|
redStep = ((double) destRed - curRed) / (SHADE_COUNT + 8);
|
||
|
greenStep = ((double) destGreen - curGreen) / (SHADE_COUNT + 8);
|
||
|
blueStep = ((double) destBlue - curBlue) / (SHADE_COUNT + 8);
|
||
|
|
||
|
// Calc color for each shade of the current color
|
||
|
for (int shade = 0; shade < SHADE_COUNT; shade++)
|
||
|
{
|
||
|
shadetable[shade][i] = GetColor((byte) curRed, (byte) curGreen, (byte) curBlue, palette);
|
||
|
|
||
|
// Inc to next shade
|
||
|
curRed += redStep;
|
||
|
curGreen += greenStep;
|
||
|
curBlue += blueStep;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void NoShading()
|
||
|
{
|
||
|
for(int shade = 0; shade < SHADE_COUNT; shade++)
|
||
|
for(int i = 0; i < 256; i++)
|
||
|
shadetable[shade][i] = i;
|
||
|
}
|
||
|
|
||
|
void InitLevelShadeTable()
|
||
|
{
|
||
|
shadedef_t *shadeDef = &shadeDefs[GetShadeDefID()];
|
||
|
if(shadeDef->fogStrength == LSHADE_NOSHADING)
|
||
|
NoShading();
|
||
|
else
|
||
|
GenerateShadeTable(shadeDef->destRed, shadeDef->destGreen, shadeDef->destBlue, gamepal, shadeDef->fogStrength);
|
||
|
}
|
||
|
|
||
|
int GetShade(int scale)
|
||
|
{
|
||
|
int shade = (scale >> 1) / (((viewwidth * 3) >> 8) + 1 + LSHADE_flag); // TODO: reconsider this...
|
||
|
if(shade > 32) shade = 32;
|
||
|
else if(shade < 1) shade = 1;
|
||
|
shade = 32 - shade;
|
||
|
|
||
|
return shade;
|
||
|
}
|
||
|
|
||
|
#endif
|