Improve color tables accuracy

This commit is contained in:
Alexander Batalov 2022-12-27 15:51:43 +03:00
parent b74f3c368b
commit 462baa0a04
7 changed files with 69 additions and 86 deletions

View File

@ -86,13 +86,13 @@ unsigned char* _blendTable[256];
unsigned char _mappedColor[256]; unsigned char _mappedColor[256];
// 0x6738D0 // 0x6738D0
unsigned char _colorMixAddTable[65536]; Color colorMixAddTable[256][256];
// 0x6838D0 // 0x6838D0
unsigned char _intensityColorTable[65536]; Color intensityColorTable[256][256];
// 0x6938D0 // 0x6938D0
unsigned char _colorMixMulTable[65536]; Color colorMixMulTable[256][256];
// 0x6A38D0 // 0x6A38D0
unsigned char _colorTable[32768]; unsigned char _colorTable[32768];
@ -172,10 +172,9 @@ static void colorPaletteFreeDefaultImpl(void* ptr)
} }
// 0x4C72B4 // 0x4C72B4
int _calculateColor(int a1, int a2) int _calculateColor(int intensity, Color color)
{ {
int v1 = (a1 >> 9) + ((a2 & 0xFF) << 8); return intensityColorTable[color][intensity / 512];
return _intensityColorTable[v1];
} }
// 0x4C72E0 // 0x4C72E0
@ -266,27 +265,26 @@ void _setSystemPaletteEntries(unsigned char* palette, int start, int end)
} }
// 0x4C7550 // 0x4C7550
static void _setIntensityTableColor(int a1) static void _setIntensityTableColor(int cc)
{ {
int v1, v2, v3, v4, v5, v6, v7, v8, v9, v10; int v1, v2, v3, v4, v5, v6, v7, v8, v9;
v5 = 0; v5 = 0;
v10 = a1 << 8;
for (int index = 0; index < 128; index++) { for (int index = 0; index < 128; index++) {
v1 = (_Color2RGB_(a1) & 0x7C00) >> 10; v1 = (_Color2RGB_(cc) & 0x7C00) >> 10;
v2 = (_Color2RGB_(a1) & 0x3E0) >> 5; v2 = (_Color2RGB_(cc) & 0x3E0) >> 5;
v3 = (_Color2RGB_(a1) & 0x1F); v3 = (_Color2RGB_(cc) & 0x1F);
v4 = (((v1 * v5) >> 16) << 10) | (((v2 * v5) >> 16) << 5) | ((v3 * v5) >> 16); v4 = (((v1 * v5) >> 16) << 10) | (((v2 * v5) >> 16) << 5) | ((v3 * v5) >> 16);
_intensityColorTable[index + v10] = _colorTable[v4]; intensityColorTable[cc][index] = _colorTable[v4];
v6 = v1 + (((0x1F - v1) * v5) >> 16); v6 = v1 + (((0x1F - v1) * v5) >> 16);
v7 = v2 + (((0x1F - v2) * v5) >> 16); v7 = v2 + (((0x1F - v2) * v5) >> 16);
v8 = v3 + (((0x1F - v3) * v5) >> 16); v8 = v3 + (((0x1F - v3) * v5) >> 16);
v9 = (v6 << 10) | (v7 << 5) | v8; v9 = (v6 << 10) | (v7 << 5) | v8;
_intensityColorTable[0x7F + index + 1 + v10] = _colorTable[v9]; intensityColorTable[cc][128 + index] = _colorTable[v9];
v5 += 0x200; v5 += 0x200;
} }
@ -299,7 +297,7 @@ static void _setIntensityTables()
if (_mappedColor[index] != 0) { if (_mappedColor[index] != 0) {
_setIntensityTableColor(index); _setIntensityTableColor(index);
} else { } else {
memset(_intensityColorTable + index * 256, 0, 256); memset(intensityColorTable[index], 0, 256);
} }
} }
} }
@ -308,11 +306,9 @@ static void _setIntensityTables()
static void _setMixTableColor(int a1) static void _setMixTableColor(int a1)
{ {
int i; int i;
int v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19; int v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19;
int v20, v21, v22, v23, v24, v25, v26, v27, v28, v29; int v20, v21, v22, v23, v24, v25, v26, v27, v28, v29;
v1 = a1 << 8;
for (i = 0; i < 256; i++) { for (i = 0; i < 256; i++) {
if (_mappedColor[a1] && _mappedColor[i]) { if (_mappedColor[a1] && _mappedColor[i]) {
v2 = (_Color2RGB_(a1) & 0x7C00) >> 10; v2 = (_Color2RGB_(a1) & 0x7C00) >> 10;
@ -366,7 +362,7 @@ static void _setMixTableColor(int a1)
v12 = _calculateColor(v19, v18); v12 = _calculateColor(v19, v18);
} }
_colorMixAddTable[v1 + i] = v12; colorMixAddTable[a1][i] = v12;
v20 = (_Color2RGB_(a1) & 0x7C00) >> 10; v20 = (_Color2RGB_(a1) & 0x7C00) >> 10;
v21 = (_Color2RGB_(a1) & 0x3E0) >> 5; v21 = (_Color2RGB_(a1) & 0x3E0) >> 5;
@ -381,14 +377,14 @@ static void _setMixTableColor(int a1)
v28 = (v22 * v25) >> 5; v28 = (v22 * v25) >> 5;
v29 = (v26 << 10) | (v27 << 5) | v28; v29 = (v26 << 10) | (v27 << 5) | v28;
_colorMixMulTable[v1 + i] = _colorTable[v29]; colorMixMulTable[a1][i] = _colorTable[v29];
} else { } else {
if (_mappedColor[i]) { if (_mappedColor[i]) {
_colorMixAddTable[v1 + i] = i; colorMixAddTable[a1][i] = i;
_colorMixMulTable[v1 + i] = i; colorMixMulTable[a1][i] = i;
} else { } else {
_colorMixAddTable[v1 + i] = a1; colorMixAddTable[a1][i] = a1;
_colorMixMulTable[v1 + i] = a1; colorMixMulTable[a1][i] = a1;
} }
} }
} }
@ -445,15 +441,15 @@ bool colorPaletteLoad(const char* path)
// NOTE: The value is "NEWC". Original code uses cmp opcode, not stricmp, // NOTE: The value is "NEWC". Original code uses cmp opcode, not stricmp,
// or comparing characters one-by-one. // or comparing characters one-by-one.
if (type == 0x4E455743) { if (type == 'NEWC') {
// NOTE: Uninline. // NOTE: Uninline.
colorPaletteFileRead(fd, _intensityColorTable, 0x10000); colorPaletteFileRead(fd, intensityColorTable, sizeof(intensityColorTable));
// NOTE: Uninline. // NOTE: Uninline.
colorPaletteFileRead(fd, _colorMixAddTable, 0x10000); colorPaletteFileRead(fd, colorMixAddTable, sizeof(colorMixAddTable));
// NOTE: Uninline. // NOTE: Uninline.
colorPaletteFileRead(fd, _colorMixMulTable, 0x10000); colorPaletteFileRead(fd, colorMixMulTable, sizeof(colorMixMulTable));
} else { } else {
_setIntensityTables(); _setIntensityTables();

View File

@ -5,6 +5,7 @@
namespace fallout { namespace fallout {
typedef unsigned char Color;
typedef const char*(ColorFileNameManger)(const char*); typedef const char*(ColorFileNameManger)(const char*);
typedef void(ColorTransitionCallback)(); typedef void(ColorTransitionCallback)();
@ -18,13 +19,13 @@ extern unsigned char _systemCmap[256 * 3];
extern unsigned char _currentGammaTable[64]; extern unsigned char _currentGammaTable[64];
extern unsigned char* _blendTable[256]; extern unsigned char* _blendTable[256];
extern unsigned char _mappedColor[256]; extern unsigned char _mappedColor[256];
extern unsigned char _colorMixAddTable[65536]; extern Color colorMixAddTable[256][256];
extern unsigned char _intensityColorTable[65536]; extern Color intensityColorTable[256][256];
extern unsigned char _colorMixMulTable[65536]; extern Color colorMixMulTable[256][256];
extern unsigned char _colorTable[32768]; extern unsigned char _colorTable[32768];
void colorPaletteSetFileIO(ColorPaletteFileOpenProc* openProc, ColorPaletteFileReadProc* readProc, ColorPaletteCloseProc* closeProc); void colorPaletteSetFileIO(ColorPaletteFileOpenProc* openProc, ColorPaletteFileReadProc* readProc, ColorPaletteCloseProc* closeProc);
int _calculateColor(int a1, int a2); int _calculateColor(int intensity, Color color);
int _Color2RGB_(int a1); int _Color2RGB_(int a1);
void colorPaletteFadeBetween(unsigned char* oldPalette, unsigned char* newPalette, int steps); void colorPaletteFadeBetween(unsigned char* oldPalette, unsigned char* newPalette, int steps);
void colorPaletteSetTransitionCallback(ColorTransitionCallback* callback); void colorPaletteSetTransitionCallback(ColorTransitionCallback* callback);

View File

@ -241,8 +241,8 @@ void _lighten_buf(unsigned char* buf, int width, int height, int pitch)
for (int y = 0; y < height; y++) { for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) { for (int x = 0; x < width; x++) {
unsigned char p = *buf; unsigned char color = *buf;
*buf++ = _intensityColorTable[(p << 8) + 147]; *buf++ = intensityColorTable[color][147];
} }
buf += skip; buf += skip;
} }

View File

@ -2782,26 +2782,24 @@ void _translucent_trans_buf_to_buf(unsigned char* src, int srcWidth, int srcHeig
} }
// 0x48BEFC // 0x48BEFC
void _dark_trans_buf_to_buf(unsigned char* src, int srcWidth, int srcHeight, int srcPitch, unsigned char* dest, int destX, int destY, int destPitch, int light) void _dark_trans_buf_to_buf(unsigned char* src, int srcWidth, int srcHeight, int srcPitch, unsigned char* dest, int destX, int destY, int destPitch, int intensity)
{ {
unsigned char* sp = src; unsigned char* sp = src;
unsigned char* dp = dest + destPitch * destY + destX; unsigned char* dp = dest + destPitch * destY + destX;
int srcStep = srcPitch - srcWidth; int srcStep = srcPitch - srcWidth;
int destStep = destPitch - srcWidth; int destStep = destPitch - srcWidth;
// TODO: Name might be confusing. int intensityIndex = intensity / 512;
int lightModifier = light >> 9;
for (int y = 0; y < srcHeight; y++) { for (int y = 0; y < srcHeight; y++) {
for (int x = 0; x < srcWidth; x++) { for (int x = 0; x < srcWidth; x++) {
unsigned char b = *sp; unsigned char color = *sp;
if (b != 0) { if (color != 0) {
if (b < 0xE5) { if (color < 0xE5) {
int t = (b << 8) + lightModifier; color = intensityColorTable[color][intensityIndex];
b = _intensityColorTable[t];
} }
*dp = b; *dp = color;
} }
sp++; sp++;
@ -2814,11 +2812,11 @@ void _dark_trans_buf_to_buf(unsigned char* src, int srcWidth, int srcHeight, int
} }
// 0x48BF88 // 0x48BF88
void _dark_translucent_trans_buf_to_buf(unsigned char* src, int srcWidth, int srcHeight, int srcPitch, unsigned char* dest, int destX, int destY, int destPitch, int light, unsigned char* a10, unsigned char* a11) void _dark_translucent_trans_buf_to_buf(unsigned char* src, int srcWidth, int srcHeight, int srcPitch, unsigned char* dest, int destX, int destY, int destPitch, int intensity, unsigned char* a10, unsigned char* a11)
{ {
int srcStep = srcPitch - srcWidth; int srcStep = srcPitch - srcWidth;
int destStep = destPitch - srcWidth; int destStep = destPitch - srcWidth;
int lightModifier = light >> 9; int intensityIndex = intensity / 512;
dest += destPitch * destY + destX; dest += destPitch * destY + destX;
@ -2829,9 +2827,7 @@ void _dark_translucent_trans_buf_to_buf(unsigned char* src, int srcWidth, int sr
unsigned char destByte = *dest; unsigned char destByte = *dest;
unsigned int index = a11[srcByte] << 8; unsigned int index = a11[srcByte] << 8;
index = a10[index + destByte]; index = a10[index + destByte];
index <<= 8; *dest = intensityColorTable[index][intensityIndex];
index += lightModifier;
*dest = _intensityColorTable[index];
} }
src++; src++;
@ -2844,32 +2840,24 @@ void _dark_translucent_trans_buf_to_buf(unsigned char* src, int srcWidth, int sr
} }
// 0x48C03C // 0x48C03C
void _intensity_mask_buf_to_buf(unsigned char* src, int srcWidth, int srcHeight, int srcPitch, unsigned char* dest, int destPitch, unsigned char* mask, int maskPitch, int light) void _intensity_mask_buf_to_buf(unsigned char* src, int srcWidth, int srcHeight, int srcPitch, unsigned char* dest, int destPitch, unsigned char* mask, int maskPitch, int intensity)
{ {
int srcStep = srcPitch - srcWidth; int srcStep = srcPitch - srcWidth;
int destStep = destPitch - srcWidth; int destStep = destPitch - srcWidth;
int maskStep = maskPitch - srcWidth; int maskStep = maskPitch - srcWidth;
light >>= 9; int intensityIndex = intensity / 512;
for (int y = 0; y < srcHeight; y++) { for (int y = 0; y < srcHeight; y++) {
for (int x = 0; x < srcWidth; x++) { for (int x = 0; x < srcWidth; x++) {
unsigned char b = *src; unsigned char color = *src;
if (b != 0) { if (color != 0) {
int off = (b << 8) + light; color = intensityColorTable[color][intensityIndex];
b = _intensityColorTable[off]; if (*mask != 0) {
unsigned char m = *mask; unsigned char v1 = intensityColorTable[*dest][128 - *mask];
if (m != 0) { unsigned char v2 = intensityColorTable[color][*mask];
unsigned char d = *dest; color = colorMixAddTable[v2][v1];
int off = (d << 8) + 128 - m;
int q = _intensityColorTable[off];
off = (b << 8) + m;
m = _intensityColorTable[off];
off = (m << 8) + q;
b = _colorMixAddTable[off];
} }
*dest = b; *dest = color;
} }
src++; src++;

View File

@ -1794,8 +1794,7 @@ static void tileRenderFloor(int fid, int x, int y, Rect* rect)
while (--v76 != -1) { while (--v76 != -1) {
for (int kk = 0; kk < v77; kk++) { for (int kk = 0; kk < v77; kk++) {
if (*v67 != 0) { if (*v67 != 0) {
int t = (*v67 << 8) + (*v68 >> 9); *v66 = intensityColorTable[*v67][*v68 >> 9];
*v66 = _intensityColorTable[t];
} }
v67++; v67++;
v68++; v68++;

View File

@ -627,39 +627,39 @@ void _setButtonGFX(int width, int height, unsigned char* normal, unsigned char*
{ {
if (normal != NULL) { if (normal != NULL) {
bufferFill(normal, width, height, width, _colorTable[0]); bufferFill(normal, width, height, width, _colorTable[0]);
bufferFill(normal + width + 1, width - 2, height - 2, width, _intensityColorTable[(_colorTable[32767] << 8) + 89]); bufferFill(normal + width + 1, width - 2, height - 2, width, intensityColorTable[_colorTable[32767]][89]);
bufferDrawLine(normal, width, 1, 1, width - 2, 1, _colorTable[32767]); bufferDrawLine(normal, width, 1, 1, width - 2, 1, _colorTable[32767]);
bufferDrawLine(normal, width, 2, 2, width - 3, 2, _colorTable[32767]); bufferDrawLine(normal, width, 2, 2, width - 3, 2, _colorTable[32767]);
bufferDrawLine(normal, width, 1, height - 2, width - 2, height - 2, _intensityColorTable[(_colorTable[32767] << 8) + 44]); bufferDrawLine(normal, width, 1, height - 2, width - 2, height - 2, intensityColorTable[_colorTable[32767]][44]);
bufferDrawLine(normal, width, 2, height - 3, width - 3, height - 3, _intensityColorTable[(_colorTable[32767] << 8) + 44]); bufferDrawLine(normal, width, 2, height - 3, width - 3, height - 3, intensityColorTable[_colorTable[32767]][44]);
bufferDrawLine(normal, width, width - 2, 1, width - 3, 2, _intensityColorTable[(_colorTable[32767] << 8) + 89]); bufferDrawLine(normal, width, width - 2, 1, width - 3, 2, intensityColorTable[_colorTable[32767]][89]);
bufferDrawLine(normal, width, 1, 2, 1, height - 3, _colorTable[32767]); bufferDrawLine(normal, width, 1, 2, 1, height - 3, _colorTable[32767]);
bufferDrawLine(normal, width, 2, 3, 2, height - 4, _colorTable[32767]); bufferDrawLine(normal, width, 2, 3, 2, height - 4, _colorTable[32767]);
bufferDrawLine(normal, width, width - 2, 2, width - 2, height - 3, _intensityColorTable[(_colorTable[32767] << 8) + 44]); bufferDrawLine(normal, width, width - 2, 2, width - 2, height - 3, intensityColorTable[_colorTable[32767]][44]);
bufferDrawLine(normal, width, width - 3, 3, width - 3, height - 4, _intensityColorTable[(_colorTable[32767] << 8) + 44]); bufferDrawLine(normal, width, width - 3, 3, width - 3, height - 4, intensityColorTable[_colorTable[32767]][44]);
bufferDrawLine(normal, width, 1, height - 2, 2, height - 3, _intensityColorTable[(_colorTable[32767] << 8) + 89]); bufferDrawLine(normal, width, 1, height - 2, 2, height - 3, intensityColorTable[_colorTable[32767]][89]);
} }
if (pressed != NULL) { if (pressed != NULL) {
bufferFill(pressed, width, height, width, _colorTable[0]); bufferFill(pressed, width, height, width, _colorTable[0]);
bufferFill(pressed + width + 1, width - 2, height - 2, width, _intensityColorTable[(_colorTable[32767] << 8) + 89]); bufferFill(pressed + width + 1, width - 2, height - 2, width, intensityColorTable[_colorTable[32767]][89]);
bufferDrawLine(pressed, width, 1, 1, width - 2, 1, _colorTable[32767] + 44); bufferDrawLine(pressed, width, 1, 1, width - 2, 1, _colorTable[32767] + 44);
bufferDrawLine(pressed, width, 1, 1, 1, height - 2, _colorTable[32767] + 44); bufferDrawLine(pressed, width, 1, 1, 1, height - 2, _colorTable[32767] + 44);
} }
if (a5 != NULL) { if (a5 != NULL) {
bufferFill(a5, width, height, width, _colorTable[0]); bufferFill(a5, width, height, width, _colorTable[0]);
bufferFill(a5 + width + 1, width - 2, height - 2, width, _intensityColorTable[(_colorTable[32767] << 8) + 89]); bufferFill(a5 + width + 1, width - 2, height - 2, width, intensityColorTable[_colorTable[32767]][89]);
bufferDrawLine(a5, width, 1, 1, width - 2, 1, _colorTable[32767]); bufferDrawLine(a5, width, 1, 1, width - 2, 1, _colorTable[32767]);
bufferDrawLine(a5, width, 2, 2, width - 3, 2, _colorTable[32767]); bufferDrawLine(a5, width, 2, 2, width - 3, 2, _colorTable[32767]);
bufferDrawLine(a5, width, 1, height - 2, width - 2, height - 2, _intensityColorTable[(_colorTable[32767] << 8) + 44]); bufferDrawLine(a5, width, 1, height - 2, width - 2, height - 2, intensityColorTable[_colorTable[32767]][44]);
bufferDrawLine(a5, width, 2, height - 3, width - 3, height - 3, _intensityColorTable[(_colorTable[32767] << 8) + 44]); bufferDrawLine(a5, width, 2, height - 3, width - 3, height - 3, intensityColorTable[_colorTable[32767]][44]);
bufferDrawLine(a5, width, width - 2, 1, width - 3, 2, _intensityColorTable[(_colorTable[32767] << 8) + 89]); bufferDrawLine(a5, width, width - 2, 1, width - 3, 2, intensityColorTable[_colorTable[32767]][89]);
bufferDrawLine(a5, width, 1, 2, 1, height - 3, _colorTable[32767]); bufferDrawLine(a5, width, 1, 2, 1, height - 3, _colorTable[32767]);
bufferDrawLine(a5, width, 2, 3, 2, height - 4, _colorTable[32767]); bufferDrawLine(a5, width, 2, 3, 2, height - 4, _colorTable[32767]);
bufferDrawLine(a5, width, width - 2, 2, width - 2, height - 3, _intensityColorTable[(_colorTable[32767] << 8) + 44]); bufferDrawLine(a5, width, width - 2, 2, width - 2, height - 3, intensityColorTable[_colorTable[32767]][44]);
bufferDrawLine(a5, width, width - 3, 3, width - 3, height - 4, _intensityColorTable[(_colorTable[32767] << 8) + 44]); bufferDrawLine(a5, width, width - 3, 3, width - 3, height - 4, intensityColorTable[_colorTable[32767]][44]);
bufferDrawLine(a5, width, 1, height - 2, 2, height - 3, _intensityColorTable[(_colorTable[32767] << 8) + 89]); bufferDrawLine(a5, width, 1, height - 2, 2, height - 3, intensityColorTable[_colorTable[32767]][89]);
} }
} }

View File

@ -5429,9 +5429,8 @@ static void wmInterfaceDrawSubTileRectFogged(unsigned char* dest, int width, int
for (int y = 0; y < height; y++) { for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) { for (int x = 0; x < width; x++) {
unsigned char byte = *dest; unsigned char color = *dest;
unsigned int index = (byte << 8) + 75; *dest++ = intensityColorTable[color][75];
*dest++ = _intensityColorTable[index];
} }
dest += skipY; dest += skipY;
} }