kolibrios/contrib/games/wolf3d/wl_shade.cpp

144 lines
3.7 KiB
C++
Raw Permalink Normal View History

#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 inline 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