1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
#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
|