Lots of feature upgrades.

This commit is contained in:
Justin Marshall
2026-05-30 02:50:21 -07:00
parent 7806bb8ef8
commit ea74cd9921
13 changed files with 2433 additions and 153 deletions
+408
View File
@@ -37,6 +37,405 @@ static PALETTEENTRY sgCurr[256]; // palette to be displayed -- includes rotation
static const char sgszGamma[] = "Gamma Correction";
static BYTE sgbFadedIn = TRUE;
extern "C" {
BYTE gbLevelTileEnhanceActive = FALSE;
BYTE gbLevelTileContrastTable[256];
BYTE gbLevelTileLumaTable[256];
BYTE gbLevelTileSharpenLightTable[256];
BYTE gbLevelTileAoTable[256];
BYTE gbLevelUnitContrastTable[256];
BYTE gbLevelUnitLumaTable[256];
BYTE gbLevelUnitSharpenLightTable[256];
BYTE gbLevelUnitAoTable[256];
BYTE gbTownWarmFlickerActive = FALSE;
BYTE gbTownWarmFlickerTable[4][256];
BYTE gbHudAnimateActive = FALSE;
BYTE gbHudHealthOrbTable[4][256];
BYTE gbHudManaOrbTable[4][256];
BYTE gbHudPotionHealthTable[4][256];
BYTE gbHudPotionManaTable[4][256];
BYTE gbHudPotionRejuvTable[4][256];
BYTE gbWorldGoldShimmerActive = FALSE;
BYTE gbWorldGoldShimmerTable[4][256];
int gnTownTileX = -1;
int gnTownTileY = -1;
int gnTownFlickerFrame = 0;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static int PalClamp(int value, int max)
{
if (value < 0) return 0;
if (value > max) return max;
return value;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static LONG PalDistance(const PALETTEENTRY *a, int red, int green, int blue)
{
LONG dr, dg, db;
dr = (LONG)a->peRed - red;
dg = (LONG)a->peGreen - green;
db = (LONG)a->peBlue - blue;
return dr * dr + dg * dg + db * db;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static BYTE FindNearestPaletteColor(int red, int green, int blue)
{
int i;
BYTE best;
LONG dist, bestDist;
best = 1;
bestDist = PalDistance(&sgLoad[1], red, green, blue);
for (i = 2; i < 256; i++) {
dist = PalDistance(&sgLoad[i], red, green, blue);
if (dist < bestDist) {
bestDist = dist;
best = (BYTE)i;
}
}
return best;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static void BuildLevelTileEnhanceTables()
{
int i, max, mid;
int red, green, blue, brightness;
max = 63;
for (i = 0; i < 256; i++) {
if (sgLoad[i].peRed > 63 || sgLoad[i].peGreen > 63 || sgLoad[i].peBlue > 63) {
max = 255;
break;
}
}
mid = max / 2;
gbLevelTileContrastTable[0] = 0;
gbLevelTileLumaTable[0] = 0;
gbLevelTileSharpenLightTable[0] = 0;
gbLevelTileAoTable[0] = 0;
gbLevelUnitContrastTable[0] = 0;
gbLevelUnitLumaTable[0] = 0;
gbLevelUnitSharpenLightTable[0] = 0;
gbLevelUnitAoTable[0] = 0;
for (i = 1; i < 256; i++) {
brightness = ((int)sgLoad[i].peRed * 30 + (int)sgLoad[i].peGreen * 59 + (int)sgLoad[i].peBlue * 11) / 100;
gbLevelTileLumaTable[i] = (BYTE)((brightness * 255) / max);
gbLevelUnitLumaTable[i] = gbLevelTileLumaTable[i];
red = (int)sgLoad[i].peRed + (((int)max - (int)sgLoad[i].peRed) * 6) / 100;
green = (int)sgLoad[i].peGreen + (((int)max - (int)sgLoad[i].peGreen) * 6) / 100;
blue = (int)sgLoad[i].peBlue + (((int)max - (int)sgLoad[i].peBlue) * 6) / 100;
gbLevelTileSharpenLightTable[i] = FindNearestPaletteColor(
PalClamp(red, max),
PalClamp(green, max),
PalClamp(blue, max));
red = ((int)sgLoad[i].peRed * 90) / 100;
green = ((int)sgLoad[i].peGreen * 90) / 100;
blue = ((int)sgLoad[i].peBlue * 90) / 100;
gbLevelTileAoTable[i] = FindNearestPaletteColor(
PalClamp(red, max),
PalClamp(green, max),
PalClamp(blue, max));
red = (int)sgLoad[i].peRed + (((int)max - (int)sgLoad[i].peRed) * 12) / 100;
green = (int)sgLoad[i].peGreen + (((int)max - (int)sgLoad[i].peGreen) * 12) / 100;
blue = (int)sgLoad[i].peBlue + (((int)max - (int)sgLoad[i].peBlue) * 12) / 100;
gbLevelUnitSharpenLightTable[i] = FindNearestPaletteColor(
PalClamp(red, max),
PalClamp(green, max),
PalClamp(blue, max));
red = ((int)sgLoad[i].peRed * 82) / 100;
green = ((int)sgLoad[i].peGreen * 82) / 100;
blue = ((int)sgLoad[i].peBlue * 82) / 100;
gbLevelUnitAoTable[i] = FindNearestPaletteColor(
PalClamp(red, max),
PalClamp(green, max),
PalClamp(blue, max));
if (brightness < max / 5 || brightness > (max * 4) / 5) {
gbLevelTileContrastTable[i] = (BYTE)i;
gbLevelUnitContrastTable[i] = (BYTE)i;
continue;
}
red = mid + (((int)sgLoad[i].peRed - mid) * 106) / 100;
green = mid + (((int)sgLoad[i].peGreen - mid) * 106) / 100;
blue = mid + (((int)sgLoad[i].peBlue - mid) * 106) / 100;
gbLevelTileContrastTable[i] = FindNearestPaletteColor(
PalClamp(red, max),
PalClamp(green, max),
PalClamp(blue, max));
red = mid + (((int)sgLoad[i].peRed - mid) * 108) / 100;
green = mid + (((int)sgLoad[i].peGreen - mid) * 108) / 100;
blue = mid + (((int)sgLoad[i].peBlue - mid) * 108) / 100;
gbLevelUnitContrastTable[i] = FindNearestPaletteColor(
PalClamp(red, max),
PalClamp(green, max),
PalClamp(blue, max));
}
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static int IsWarmTownLightColor(int red, int green, int blue, int brightness, int max)
{
if (brightness < max / 4)
return FALSE;
if (red < green || green < blue)
return FALSE;
if (red - blue < max / 7)
return FALSE;
if (green - blue < max / 12)
return FALSE;
return TRUE;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static void BuildTownWarmFlickerTables()
{
int i, p, max;
int red, green, blue, brightness;
static const int sPhaseRed[4] = { 6, 14, 9, -3 };
static const int sPhaseGreen[4] = { 3, 8, 5, -2 };
static const int sPhaseBlue[4] = { -3, -6, -4, 0 };
max = 63;
for (i = 0; i < 256; i++) {
if (sgLoad[i].peRed > 63 || sgLoad[i].peGreen > 63 || sgLoad[i].peBlue > 63) {
max = 255;
break;
}
}
for (i = 0; i < 256; i++) {
brightness = ((int)sgLoad[i].peRed * 30 + (int)sgLoad[i].peGreen * 59 + (int)sgLoad[i].peBlue * 11) / 100;
for (p = 0; p < 4; p++) {
if (!IsWarmTownLightColor(sgLoad[i].peRed, sgLoad[i].peGreen, sgLoad[i].peBlue, brightness, max)) {
gbTownWarmFlickerTable[p][i] = (BYTE)i;
continue;
}
red = (int)sgLoad[i].peRed + (((int)max - (int)sgLoad[i].peRed) * sPhaseRed[p]) / 100;
green = (int)sgLoad[i].peGreen + (((int)max - (int)sgLoad[i].peGreen) * sPhaseGreen[p]) / 100;
if (sPhaseBlue[p] < 0)
blue = ((int)sgLoad[i].peBlue * (100 + sPhaseBlue[p])) / 100;
else
blue = (int)sgLoad[i].peBlue + (((int)max - (int)sgLoad[i].peBlue) * sPhaseBlue[p]) / 100;
gbTownWarmFlickerTable[p][i] = FindNearestPaletteColor(
PalClamp(red, max),
PalClamp(green, max),
PalClamp(blue, max));
}
}
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static int IsHudHealthColor(int red, int green, int blue, int brightness, int max)
{
if (brightness < max / 5)
return FALSE;
if (red < green - max / 16)
return FALSE;
if (red < blue - max / 12)
return FALSE;
return TRUE;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static int IsHudManaColor(int red, int green, int blue, int brightness, int max)
{
if (brightness < max / 5)
return FALSE;
if (blue < red - max / 16)
return FALSE;
if (blue < green - max / 12)
return FALSE;
return TRUE;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static int IsHudRejuvColor(int red, int green, int blue, int brightness, int max)
{
if (brightness < max / 5)
return FALSE;
if (red < green + max / 14)
return FALSE;
if (blue < green + max / 14)
return FALSE;
return TRUE;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static int HudShiftChannel(int value, int max, int percent)
{
if (percent >= 0)
return value + ((max - value) * percent) / 100;
return (value * (100 + percent)) / 100;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static void BuildHudAnimTable(BYTE table[4][256], const int redPhase[4], const int greenPhase[4], const int bluePhase[4], int kind, int max)
{
int i, p;
int red, green, blue, brightness;
int useColor;
for (i = 0; i < 256; i++) {
red = sgLoad[i].peRed;
green = sgLoad[i].peGreen;
blue = sgLoad[i].peBlue;
brightness = (red * 30 + green * 59 + blue * 11) / 100;
useColor = FALSE;
if (kind == 0)
useColor = IsHudHealthColor(red, green, blue, brightness, max);
else if (kind == 1)
useColor = IsHudManaColor(red, green, blue, brightness, max);
else
useColor = IsHudRejuvColor(red, green, blue, brightness, max);
for (p = 0; p < 4; p++) {
if (!useColor) {
table[p][i] = (BYTE)i;
continue;
}
table[p][i] = FindNearestPaletteColor(
PalClamp(HudShiftChannel(red, max, redPhase[p]), max),
PalClamp(HudShiftChannel(green, max, greenPhase[p]), max),
PalClamp(HudShiftChannel(blue, max, bluePhase[p]), max));
}
}
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static void BuildHudAnimateTables()
{
int i, max;
static const int sHealthOrbRed[4] = { 6, 16, 9, -4 };
static const int sHealthOrbGreen[4] = { 1, 4, 2, -2 };
static const int sHealthOrbBlue[4] = { -4, -10, -6, 0 };
static const int sManaOrbRed[4] = { -4, -10, -6, 0 };
static const int sManaOrbGreen[4] = { 2, 7, 4, -2 };
static const int sManaOrbBlue[4] = { 7, 18, 10, -4 };
static const int sHealthPotionRed[4] = { 3, 8, 5, -2 };
static const int sHealthPotionGreen[4] = { 0, 2, 1, -1 };
static const int sHealthPotionBlue[4] = { -2, -5, -3, 0 };
static const int sManaPotionRed[4] = { -2, -5, -3, 0 };
static const int sManaPotionGreen[4] = { 1, 4, 2, -1 };
static const int sManaPotionBlue[4] = { 4, 11, 6, -2 };
static const int sRejuvPotionRed[4] = { 4, 11, 6, -2 };
static const int sRejuvPotionGreen[4] = { -1, 1, 0, -1 };
static const int sRejuvPotionBlue[4] = { 4, 11, 6, -2 };
max = 63;
for (i = 0; i < 256; i++) {
if (sgLoad[i].peRed > 63 || sgLoad[i].peGreen > 63 || sgLoad[i].peBlue > 63) {
max = 255;
break;
}
}
BuildHudAnimTable(gbHudHealthOrbTable, sHealthOrbRed, sHealthOrbGreen, sHealthOrbBlue, 0, max);
BuildHudAnimTable(gbHudManaOrbTable, sManaOrbRed, sManaOrbGreen, sManaOrbBlue, 1, max);
BuildHudAnimTable(gbHudPotionHealthTable, sHealthPotionRed, sHealthPotionGreen, sHealthPotionBlue, 0, max);
BuildHudAnimTable(gbHudPotionManaTable, sManaPotionRed, sManaPotionGreen, sManaPotionBlue, 1, max);
BuildHudAnimTable(gbHudPotionRejuvTable, sRejuvPotionRed, sRejuvPotionGreen, sRejuvPotionBlue, 2, max);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static int IsWorldGoldColor(int red, int green, int blue, int brightness, int max)
{
if (brightness < max / 8)
return FALSE;
if (red < green - max / 5)
return FALSE;
if (green < blue + max / 24)
return FALSE;
if (red < blue + max / 12)
return FALSE;
return TRUE;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static void BuildWorldGoldShimmerTables()
{
int i, p, max;
int red, green, blue, brightness;
static const int sGoldRed[4] = { 2, 22, 8, -8 };
static const int sGoldGreen[4] = { 1, 18, 6, -7 };
static const int sGoldBlue[4] = { -3, -16, -7, -4 };
max = 63;
for (i = 0; i < 256; i++) {
if (sgLoad[i].peRed > 63 || sgLoad[i].peGreen > 63 || sgLoad[i].peBlue > 63) {
max = 255;
break;
}
}
for (i = 0; i < 256; i++) {
red = sgLoad[i].peRed;
green = sgLoad[i].peGreen;
blue = sgLoad[i].peBlue;
brightness = (red * 30 + green * 59 + blue * 11) / 100;
for (p = 0; p < 4; p++) {
if (!IsWorldGoldColor(red, green, blue, brightness, max)) {
gbWorldGoldShimmerTable[p][i] = (BYTE)i;
continue;
}
gbWorldGoldShimmerTable[p][i] = FindNearestPaletteColor(
PalClamp(HudShiftChannel(red, max, sGoldRed[p]), max),
PalClamp(HudShiftChannel(green, max, sGoldGreen[p]), max),
PalClamp(HudShiftChannel(blue, max, sGoldBlue[p]), max));
}
}
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
@@ -184,6 +583,15 @@ void LoadRndLvlPal(int l) {
}
LoadPalette(filestr);
}
BuildLevelTileEnhanceTables();
BuildTownWarmFlickerTables();
BuildHudAnimateTables();
BuildWorldGoldShimmerTables();
gbLevelTileEnhanceActive = TRUE;
gbTownWarmFlickerActive = (l == 0);
gbHudAnimateActive = FALSE;
gbWorldGoldShimmerActive = TRUE;
}