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];
// 0x6738D0
unsigned char _colorMixAddTable[65536];
Color colorMixAddTable[256][256];
// 0x6838D0
unsigned char _intensityColorTable[65536];
Color intensityColorTable[256][256];
// 0x6938D0
unsigned char _colorMixMulTable[65536];
Color colorMixMulTable[256][256];
// 0x6A38D0
unsigned char _colorTable[32768];
@ -172,10 +172,9 @@ static void colorPaletteFreeDefaultImpl(void* ptr)
}
// 0x4C72B4
int _calculateColor(int a1, int a2)
int _calculateColor(int intensity, Color color)
{
int v1 = (a1 >> 9) + ((a2 & 0xFF) << 8);
return _intensityColorTable[v1];
return intensityColorTable[color][intensity / 512];
}
// 0x4C72E0
@ -266,27 +265,26 @@ void _setSystemPaletteEntries(unsigned char* palette, int start, int end)
}
// 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;
v10 = a1 << 8;
for (int index = 0; index < 128; index++) {
v1 = (_Color2RGB_(a1) & 0x7C00) >> 10;
v2 = (_Color2RGB_(a1) & 0x3E0) >> 5;
v3 = (_Color2RGB_(a1) & 0x1F);
v1 = (_Color2RGB_(cc) & 0x7C00) >> 10;
v2 = (_Color2RGB_(cc) & 0x3E0) >> 5;
v3 = (_Color2RGB_(cc) & 0x1F);
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);
v7 = v2 + (((0x1F - v2) * v5) >> 16);
v8 = v3 + (((0x1F - v3) * v5) >> 16);
v9 = (v6 << 10) | (v7 << 5) | v8;
_intensityColorTable[0x7F + index + 1 + v10] = _colorTable[v9];
intensityColorTable[cc][128 + index] = _colorTable[v9];
v5 += 0x200;
}
@ -299,7 +297,7 @@ static void _setIntensityTables()
if (_mappedColor[index] != 0) {
_setIntensityTableColor(index);
} else {
memset(_intensityColorTable + index * 256, 0, 256);
memset(intensityColorTable[index], 0, 256);
}
}
}
@ -308,11 +306,9 @@ static void _setIntensityTables()
static void _setMixTableColor(int a1)
{
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;
v1 = a1 << 8;
for (i = 0; i < 256; i++) {
if (_mappedColor[a1] && _mappedColor[i]) {
v2 = (_Color2RGB_(a1) & 0x7C00) >> 10;
@ -366,7 +362,7 @@ static void _setMixTableColor(int a1)
v12 = _calculateColor(v19, v18);
}
_colorMixAddTable[v1 + i] = v12;
colorMixAddTable[a1][i] = v12;
v20 = (_Color2RGB_(a1) & 0x7C00) >> 10;
v21 = (_Color2RGB_(a1) & 0x3E0) >> 5;
@ -381,14 +377,14 @@ static void _setMixTableColor(int a1)
v28 = (v22 * v25) >> 5;
v29 = (v26 << 10) | (v27 << 5) | v28;
_colorMixMulTable[v1 + i] = _colorTable[v29];
colorMixMulTable[a1][i] = _colorTable[v29];
} else {
if (_mappedColor[i]) {
_colorMixAddTable[v1 + i] = i;
_colorMixMulTable[v1 + i] = i;
colorMixAddTable[a1][i] = i;
colorMixMulTable[a1][i] = i;
} else {
_colorMixAddTable[v1 + i] = a1;
_colorMixMulTable[v1 + i] = a1;
colorMixAddTable[a1][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,
// or comparing characters one-by-one.
if (type == 0x4E455743) {
if (type == 'NEWC') {
// NOTE: Uninline.
colorPaletteFileRead(fd, _intensityColorTable, 0x10000);
colorPaletteFileRead(fd, intensityColorTable, sizeof(intensityColorTable));
// NOTE: Uninline.
colorPaletteFileRead(fd, _colorMixAddTable, 0x10000);
colorPaletteFileRead(fd, colorMixAddTable, sizeof(colorMixAddTable));
// NOTE: Uninline.
colorPaletteFileRead(fd, _colorMixMulTable, 0x10000);
colorPaletteFileRead(fd, colorMixMulTable, sizeof(colorMixMulTable));
} else {
_setIntensityTables();

View File

@ -5,6 +5,7 @@
namespace fallout {
typedef unsigned char Color;
typedef const char*(ColorFileNameManger)(const char*);
typedef void(ColorTransitionCallback)();
@ -18,13 +19,13 @@ extern unsigned char _systemCmap[256 * 3];
extern unsigned char _currentGammaTable[64];
extern unsigned char* _blendTable[256];
extern unsigned char _mappedColor[256];
extern unsigned char _colorMixAddTable[65536];
extern unsigned char _intensityColorTable[65536];
extern unsigned char _colorMixMulTable[65536];
extern Color colorMixAddTable[256][256];
extern Color intensityColorTable[256][256];
extern Color colorMixMulTable[256][256];
extern unsigned char _colorTable[32768];
void colorPaletteSetFileIO(ColorPaletteFileOpenProc* openProc, ColorPaletteFileReadProc* readProc, ColorPaletteCloseProc* closeProc);
int _calculateColor(int a1, int a2);
int _calculateColor(int intensity, Color color);
int _Color2RGB_(int a1);
void colorPaletteFadeBetween(unsigned char* oldPalette, unsigned char* newPalette, int steps);
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 x = 0; x < width; x++) {
unsigned char p = *buf;
*buf++ = _intensityColorTable[(p << 8) + 147];
unsigned char color = *buf;
*buf++ = intensityColorTable[color][147];
}
buf += skip;
}

View File

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

View File

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

View File

@ -627,39 +627,39 @@ void _setButtonGFX(int width, int height, unsigned char* normal, unsigned char*
{
if (normal != NULL) {
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, 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, 2, height - 3, width - 3, height - 3, _intensityColorTable[(_colorTable[32767] << 8) + 44]);
bufferDrawLine(normal, width, width - 2, 1, width - 3, 2, _intensityColorTable[(_colorTable[32767] << 8) + 89]);
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]][44]);
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, 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 - 3, 3, width - 3, height - 4, _intensityColorTable[(_colorTable[32767] << 8) + 44]);
bufferDrawLine(normal, width, 1, height - 2, 2, height - 3, _intensityColorTable[(_colorTable[32767] << 8) + 89]);
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]][44]);
bufferDrawLine(normal, width, 1, height - 2, 2, height - 3, intensityColorTable[_colorTable[32767]][89]);
}
if (pressed != NULL) {
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, 1, height - 2, _colorTable[32767] + 44);
}
if (a5 != NULL) {
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, 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, 2, height - 3, width - 3, height - 3, _intensityColorTable[(_colorTable[32767] << 8) + 44]);
bufferDrawLine(a5, width, width - 2, 1, width - 3, 2, _intensityColorTable[(_colorTable[32767] << 8) + 89]);
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]][44]);
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, 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 - 3, 3, width - 3, height - 4, _intensityColorTable[(_colorTable[32767] << 8) + 44]);
bufferDrawLine(a5, width, 1, height - 2, 2, height - 3, _intensityColorTable[(_colorTable[32767] << 8) + 89]);
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]][44]);
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 x = 0; x < width; x++) {
unsigned char byte = *dest;
unsigned int index = (byte << 8) + 75;
*dest++ = _intensityColorTable[index];
unsigned char color = *dest;
*dest++ = intensityColorTable[color][75];
}
dest += skipY;
}