From 462baa0a04723c342c90ced1ee694267df30f677 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Tue, 27 Dec 2022 15:51:43 +0300 Subject: [PATCH] Improve color tables accuracy --- src/color.cc | 52 +++++++++++++++++++++++-------------------------- src/color.h | 9 +++++---- src/draw.cc | 4 ++-- src/object.cc | 52 +++++++++++++++++++------------------------------ src/tile.cc | 3 +-- src/window.cc | 30 ++++++++++++++-------------- src/worldmap.cc | 5 ++--- 7 files changed, 69 insertions(+), 86 deletions(-) diff --git a/src/color.cc b/src/color.cc index 7841ada..a7a616e 100644 --- a/src/color.cc +++ b/src/color.cc @@ -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(); diff --git a/src/color.h b/src/color.h index d673720..dc36220 100644 --- a/src/color.h +++ b/src/color.h @@ -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); diff --git a/src/draw.cc b/src/draw.cc index a96bfab..592273f 100644 --- a/src/draw.cc +++ b/src/draw.cc @@ -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; } diff --git a/src/object.cc b/src/object.cc index 5d264f3..01ec907 100644 --- a/src/object.cc +++ b/src/object.cc @@ -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++; diff --git a/src/tile.cc b/src/tile.cc index 0e81070..0eb5ebc 100644 --- a/src/tile.cc +++ b/src/tile.cc @@ -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++; diff --git a/src/window.cc b/src/window.cc index e657d98..fd9e9d8 100644 --- a/src/window.cc +++ b/src/window.cc @@ -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]); } } diff --git a/src/worldmap.cc b/src/worldmap.cc index ed8e828..6d3662e 100644 --- a/src/worldmap.cc +++ b/src/worldmap.cc @@ -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; }