Browse Source

Handle color cyceling when using blended transparancy

pull/1036/head
Anders Jenbo 5 years ago
parent
commit
732d070b75
  1. 147
      Source/palette.cpp

147
Source/palette.cpp

@ -81,14 +81,19 @@ void palette_init()
}
/**
* Generate lookup table for transparency
* @brief Generate lookup table for transparency
*
* This is based of the same technique found in Quake2.
*
* To mimic 50% transparency we figure out what colours in the existing palette are the best match for the combination of any 2 colours.
* We save this into a lookup table for use during rendering.
*
* @param palette The colors to operate on
* @param skipFrom Do not use colors between this index and skipTo
* @param skipTo Do not use colors between skipFrom and this index
* @param toUpdate Only update the first n colors
*/
void GenerateBlendedLookupTable()
static void GenerateBlendedLookupTable(SDL_Color *palette, int skipFrom, int skipTo, int toUpdate = 256)
{
for (int i = 0; i < 256; i++) {
for (int j = 0; j < 256; j++) {
@ -100,16 +105,21 @@ void GenerateBlendedLookupTable()
paletteTransparencyLookup[i][j] = paletteTransparencyLookup[j][i];
continue;
}
if (i > toUpdate && j > toUpdate) {
continue;
}
Uint8 r = ((int)orig_palette[i].r + (int)orig_palette[j].r) / 2;
Uint8 g = ((int)orig_palette[i].g + (int)orig_palette[j].g) / 2;
Uint8 b = ((int)orig_palette[i].b + (int)orig_palette[j].b) / 2;
Uint8 r = ((int)palette[i].r + (int)palette[j].r) / 2;
Uint8 g = ((int)palette[i].g + (int)palette[j].g) / 2;
Uint8 b = ((int)palette[i].b + (int)palette[j].b) / 2;
Uint8 best;
Uint32 bestDiff = SDL_MAX_UINT32;
for (int k = 0; k < 256; k++) {
int diffr = orig_palette[k].r - r;
int diffg = orig_palette[k].g - g;
int diffb = orig_palette[k].b - b;
if (k >= skipFrom && k <= skipTo)
continue;
int diffr = palette[k].r - r;
int diffg = palette[k].g - g;
int diffb = palette[k].b - b;
int diff = diffr * diffr + diffg * diffg + diffb * diffb;
if (bestDiff > diff) {
@ -144,7 +154,13 @@ void LoadPalette(const char *pszFileName)
}
if (sgOptions.blendedTransparancy) {
GenerateBlendedLookupTable();
if (leveltype == DTYPE_CAVES || leveltype == DTYPE_CRYPT) {
GenerateBlendedLookupTable(orig_palette, 1, 31);
} else if (leveltype == DTYPE_NEST) {
GenerateBlendedLookupTable(orig_palette, 1, 15);
} else {
GenerateBlendedLookupTable(orig_palette, -1, -1);
}
}
}
@ -259,17 +275,73 @@ void PaletteFadeOut(int fr)
}
}
void palette_update_caves()
/**
* @brief Cycle the given range of colors in the palette
* @param from First color index of the range
* @param to First color index of the range
*/
static void CycleColors(int from, int to)
{
int i;
SDL_Color col;
col = system_palette[1];
for (i = 1; i < 31; i++) {
SDL_Color col = system_palette[from];
for (int i = from; i < to; i++) {
system_palette[i] = system_palette[i + 1];
}
system_palette[i] = col;
system_palette[to] = col;
if (!sgOptions.blendedTransparancy)
return;
for (int i = 0; i < 256; i++) {
Uint8 col = paletteTransparencyLookup[i][from];
for (int j = from; j < to; j++) {
paletteTransparencyLookup[i][j] = paletteTransparencyLookup[i][j + 1];
}
paletteTransparencyLookup[i][to] = col;
}
Uint8 colRow[256];
memcpy(colRow, &paletteTransparencyLookup[from], sizeof(*paletteTransparencyLookup));
for (int i = from; i < to; i++) {
memcpy(&paletteTransparencyLookup[i], &paletteTransparencyLookup[i + 1], sizeof(*paletteTransparencyLookup));
}
memcpy(&paletteTransparencyLookup[to], colRow, sizeof(colRow));
}
/**
* @brief Cycle the given range of colors in the palette in reverse direction
* @param from First color index of the range
* @param to First color index of the range
*/
static void CycleColorsReverse(int from, int to)
{
SDL_Color col = system_palette[to];
for (int i = to; i > from; i--) {
system_palette[i] = system_palette[i - 1];
}
system_palette[from] = col;
if (!sgOptions.blendedTransparancy)
return;
for (int i = 0; i < 256; i++) {
Uint8 col = paletteTransparencyLookup[i][to];
for (int j = to; j > from; j--) {
paletteTransparencyLookup[i][j] = paletteTransparencyLookup[i][j - 1];
}
paletteTransparencyLookup[i][from] = col;
}
Uint8 colRow[256];
memcpy(colRow, &paletteTransparencyLookup[to], sizeof(*paletteTransparencyLookup));
for (int i = to; i > from; i--) {
memcpy(&paletteTransparencyLookup[i], &paletteTransparencyLookup[i - 1], sizeof(*paletteTransparencyLookup));
}
memcpy(&paletteTransparencyLookup[from], colRow, sizeof(colRow));
}
void palette_update_caves()
{
CycleColors(1, 31);
palette_update();
}
@ -281,30 +353,13 @@ void palette_update_crypt()
SDL_Color col;
if (dword_6E2D58 > 1) {
col = system_palette[15];
for (i = 15; i > 1; i--) {
system_palette[i].r = system_palette[i - 1].r;
system_palette[i].g = system_palette[i - 1].g;
system_palette[i].b = system_palette[i - 1].b;
}
system_palette[i].r = col.r;
system_palette[i].g = col.g;
system_palette[i].b = col.b;
CycleColorsReverse(1, 15);
dword_6E2D58 = 0;
} else {
dword_6E2D58++;
}
if (dword_6E2D54 > 0) {
col = system_palette[31];
for (i = 31; i > 16; i--) {
system_palette[i].r = system_palette[i - 1].r;
system_palette[i].g = system_palette[i - 1].g;
system_palette[i].b = system_palette[i - 1].b;
}
system_palette[i].r = col.r;
system_palette[i].g = col.g;
system_palette[i].b = col.b;
CycleColorsReverse(16, 31);
palette_update();
dword_6E2D54++;
} else {
@ -320,29 +375,13 @@ void palette_update_hive()
SDL_Color col;
if (dword_6E2D60 == 2) {
col = system_palette[8];
for (i = 8; i > 1; i--) {
system_palette[i].r = system_palette[i - 1].r;
system_palette[i].g = system_palette[i - 1].g;
system_palette[i].b = system_palette[i - 1].b;
}
system_palette[i].r = col.r;
system_palette[i].g = col.g;
system_palette[i].b = col.b;
CycleColorsReverse(1, 8);
dword_6E2D60 = 0;
} else {
dword_6E2D60++;
}
if (dword_6E2D5C == 2) {
col = system_palette[15];
for (i = 15; i > 9; i--) {
system_palette[i].r = system_palette[i - 1].r;
system_palette[i].g = system_palette[i - 1].g;
system_palette[i].b = system_palette[i - 1].b;
}
system_palette[i].r = col.r;
system_palette[i].g = col.g;
system_palette[i].b = col.b;
CycleColorsReverse(9, 15);
palette_update();
dword_6E2D5C = 0;
} else {
@ -359,6 +398,8 @@ void palette_update_quest_palette(int n)
}
ApplyGamma(system_palette, logical_palette, 32);
palette_update();
GenerateBlendedLookupTable(logical_palette, 1, 31, 32 - n); // Possible optimization would be to only update color 0 as only the UI can overlap with transparency in this quest
}
BOOL palette_get_color_cycling()

Loading…
Cancel
Save