Improve graphlib accuracy

This commit is contained in:
Alexander Batalov 2022-12-27 18:59:24 +03:00
parent 1f6d5ebbc9
commit 4b137dac5f
9 changed files with 58 additions and 104 deletions

View File

@ -107,8 +107,6 @@ target_sources(${EXECUTABLE_NAME} PUBLIC
"src/game_mouse.h" "src/game_mouse.h"
"src/game_movie.cc" "src/game_movie.cc"
"src/game_movie.h" "src/game_movie.h"
"src/game_palette.cc"
"src/game_palette.h"
"src/game_sound.cc" "src/game_sound.cc"
"src/game_sound.h" "src/game_sound.h"
"src/game_vars.h" "src/game_vars.h"
@ -118,8 +116,6 @@ target_sources(${EXECUTABLE_NAME} PUBLIC
"src/geometry.h" "src/geometry.h"
"src/graph_lib.cc" "src/graph_lib.cc"
"src/graph_lib.h" "src/graph_lib.h"
"src/grayscale.cc"
"src/grayscale.h"
"src/heap.cc" "src/heap.cc"
"src/heap.h" "src/heap.h"
"src/input.cc" "src/input.cc"

View File

@ -18,9 +18,9 @@
#include "draw.h" #include "draw.h"
#include "game.h" #include "game.h"
#include "game_mouse.h" #include "game_mouse.h"
#include "game_palette.h"
#include "game_sound.h" #include "game_sound.h"
#include "geometry.h" #include "geometry.h"
#include "graph_lib.h"
#include "input.h" #include "input.h"
#include "interface.h" #include "interface.h"
#include "item.h" #include "item.h"
@ -4961,7 +4961,7 @@ static int characterEditorDrawCardWithOptions(int graphicId, const char* name, c
ptr = frmImage.getData(); ptr = frmImage.getData();
for (y = 0; y < frmImage.getHeight(); y++) { for (y = 0; y < frmImage.getHeight(); y++) {
for (x = 0; x < frmImage.getWidth(); x++) { for (x = 0; x < frmImage.getWidth(); x++) {
if (_HighRGB_(*ptr) < 2 && v9 >= x) { if (HighRGB(*ptr) < 2 && v9 >= x) {
v9 = x; v9 = x;
} }
ptr++; ptr++;
@ -6659,7 +6659,7 @@ static int perkDialogDrawCard(int frmId, const char* name, const char* rank, cha
for (int y = 0; y < frmImage.getHeight(); y++) { for (int y = 0; y < frmImage.getHeight(); y++) {
unsigned char* stride = data; unsigned char* stride = data;
for (int x = 0; x < frmImage.getWidth(); x++) { for (int x = 0; x < frmImage.getWidth(); x++) {
if (_HighRGB_(*stride) < 2) { if (HighRGB(*stride) < 2) {
if (extraDescriptionWidth > x) { if (extraDescriptionWidth > x) {
extraDescriptionWidth = x; extraDescriptionWidth = x;
} }

View File

@ -1,29 +0,0 @@
#include "game_palette.h"
#include "color.h"
namespace fallout {
// 0x44EBC0
int _HighRGB_(int a1)
{
// TODO: Some strange bit arithmetic.
int v1 = Color2RGB(a1);
int r = (v1 & 0x7C00) >> 10;
int g = (v1 & 0x3E0) >> 5;
int b = (v1 & 0x1F);
int result = g;
if (r > result) {
result = r;
}
result = result & 0xFF;
if (result <= b) {
result = b;
}
return result;
}
} // namespace fallout

View File

@ -1,10 +0,0 @@
#ifndef GAME_PALETTE_H
#define GAME_PALETTE_H
namespace fallout {
int _HighRGB_(int a1);
} // namespace fallout
#endif /* GAME_PALETTE_H */

View File

@ -2,6 +2,9 @@
#include <string.h> #include <string.h>
#include <algorithm>
#include "color.h"
#include "debug.h" #include "debug.h"
#include "memory.h" #include "memory.h"
@ -11,6 +14,9 @@ static void _InitTree();
static void _InsertNode(int a1); static void _InsertNode(int a1);
static void _DeleteNode(int a1); static void _DeleteNode(int a1);
// 0x596D90
static unsigned char _GreyTable[256];
// 0x596E90 // 0x596E90
static int* _dad_2; static int* _dad_2;
@ -35,6 +41,17 @@ static int _codesize;
// 0x596EAC // 0x596EAC
static int _match_position; static int _match_position;
// 0x44EBC0
unsigned char HighRGB(unsigned char color)
{
int rgb = Color2RGB(color);
int r = (rgb & 0x7C00) >> 10;
int g = (rgb & 0x3E0) >> 5;
int b = (rgb & 0x1F);
return std::max(std::max(r, g), b);
}
// 0x44F250 // 0x44F250
int graphCompress(unsigned char* a1, unsigned char* a2, int a3) int graphCompress(unsigned char* a1, unsigned char* a2, int a3)
{ {
@ -385,4 +402,38 @@ int graphDecompress(unsigned char* src, unsigned char* dest, int length)
return 0; return 0;
} }
// 0x44FA78
void grayscalePaletteUpdate(int a1, int a2)
{
if (a1 >= 0 && a2 <= 255) {
for (int index = a1; index <= a2; index++) {
// NOTE: The only way to explain so much calls to `Color2RGB` with
// the same repeated pattern is by the use of min/max macros.
int v1 = std::max((Color2RGB(index) & 0x7C00) >> 10, std::max((Color2RGB(index) & 0x3E0) >> 5, Color2RGB(index) & 0x1F));
int v2 = std::min((Color2RGB(index) & 0x7C00) >> 10, std::min((Color2RGB(index) & 0x3E0) >> 5, Color2RGB(index) & 0x1F));
int v3 = v1 + v2;
int v4 = (int)((double)v3 * 240.0 / 510.0);
int paletteIndex = ((v4 & 0xFF) << 10) | ((v4 & 0xFF) << 5) | (v4 & 0xFF);
_GreyTable[index] = _colorTable[paletteIndex];
}
}
}
// 0x44FC40
void grayscalePaletteApply(unsigned char* buffer, int width, int height, int pitch)
{
unsigned char* ptr = buffer;
int skip = pitch - width;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
unsigned char c = *ptr;
*ptr++ = _GreyTable[c];
}
ptr += skip;
}
}
} // namespace fallout } // namespace fallout

View File

@ -3,8 +3,11 @@
namespace fallout { namespace fallout {
unsigned char HighRGB(unsigned char color);
int graphCompress(unsigned char* a1, unsigned char* a2, int a3); int graphCompress(unsigned char* a1, unsigned char* a2, int a3);
int graphDecompress(unsigned char* a1, unsigned char* a2, int a3); int graphDecompress(unsigned char* a1, unsigned char* a2, int a3);
void grayscalePaletteUpdate(int a1, int a2);
void grayscalePaletteApply(unsigned char* surface, int width, int height, int pitch);
} // namespace fallout } // namespace fallout

View File

@ -1,46 +0,0 @@
#include "grayscale.h"
#include <algorithm>
#include "color.h"
namespace fallout {
// 0x596D90
static unsigned char _GreyTable[256];
// 0x44FA78
void grayscalePaletteUpdate(int a1, int a2)
{
if (a1 >= 0 && a2 <= 255) {
for (int index = a1; index <= a2; index++) {
// NOTE: The only way to explain so much calls to `Color2RGB` with
// the same repeated pattern is by the use of min/max macros.
int v1 = std::max((Color2RGB(index) & 0x7C00) >> 10, std::max((Color2RGB(index) & 0x3E0) >> 5, Color2RGB(index) & 0x1F));
int v2 = std::min((Color2RGB(index) & 0x7C00) >> 10, std::min((Color2RGB(index) & 0x3E0) >> 5, Color2RGB(index) & 0x1F));
int v3 = v1 + v2;
int v4 = (int)((double)v3 * 240.0 / 510.0);
int paletteIndex = ((v4 & 0xFF) << 10) | ((v4 & 0xFF) << 5) | (v4 & 0xFF);
_GreyTable[index] = _colorTable[paletteIndex];
}
}
}
// 0x44FC40
void grayscalePaletteApply(unsigned char* buffer, int width, int height, int pitch)
{
unsigned char* ptr = buffer;
int skip = pitch - width;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
unsigned char c = *ptr;
*ptr++ = _GreyTable[c];
}
ptr += skip;
}
}
} // namespace fallout

View File

@ -1,11 +0,0 @@
#ifndef GRAYSCALE_H
#define GRAYSCALE_H
namespace fallout {
void grayscalePaletteUpdate(int a1, int a2);
void grayscalePaletteApply(unsigned char* surface, int width, int height, int pitch);
} // namespace fallout
#endif /* GRAYSCALE_H */

View File

@ -17,7 +17,7 @@
#include "game_mouse.h" #include "game_mouse.h"
#include "game_sound.h" #include "game_sound.h"
#include "geometry.h" #include "geometry.h"
#include "grayscale.h" #include "graph_lib.h"
#include "input.h" #include "input.h"
#include "kb.h" #include "kb.h"
#include "loadsave.h" #include "loadsave.h"