mirror of
https://github.com/jmarshall23/Hellfire.git
synced 2026-08-11 23:40:51 +02:00
833 lines
24 KiB
C++
833 lines
24 KiB
C++
/*-----------------------------------------------------------------------**
|
|
** Diablo
|
|
**
|
|
** Palette file
|
|
**
|
|
** (C)1995 Condor, Inc. All rights reserved.
|
|
**-----------------------------------------------------------------------**
|
|
** $Header: /Diablo/PALETTE.CPP 2 1/23/97 12:21p Jmorin $
|
|
**-----------------------------------------------------------------------*/
|
|
|
|
#include "diablo.h"
|
|
#pragma hdrstop
|
|
#include "storm/h/storm.h"
|
|
#include "palette.h"
|
|
#include "engine.h"
|
|
#include <math.h>
|
|
#include "resource.h"
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
** extern
|
|
**-----------------------------------------------------------------------*/
|
|
extern char gszProgKey[];
|
|
void ErrorDlg(int nDlgId,DWORD dwErr,const char * pszFile,int nLine);
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
** File Variables
|
|
**-----------------------------------------------------------------------*/
|
|
static LONG sglGamma = lGAMMA_MAX;
|
|
static int sgnStaticColors2 = 0;
|
|
static PALETTEENTRY sgLoad[256]; // original loaded palette -- used as reference
|
|
// for gamma conversion
|
|
static PALETTEENTRY sgBase[256]; // palettized version of sgLoad
|
|
static PALETTEENTRY sgCurr[256]; // palette to be displayed -- includes rotations
|
|
|
|
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));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
**-----------------------------------------------------------------------*/
|
|
static void SetPaletteEntries() {
|
|
if (! lpDDPal) return;
|
|
|
|
int nStart;
|
|
int nColors;
|
|
if (! fullscreen) {
|
|
nStart = sgnStaticColors2;
|
|
nColors = 256 - sgnStaticColors2*2;
|
|
}
|
|
else {
|
|
nStart = 0;
|
|
nColors = 256;
|
|
}
|
|
|
|
// HRESULT ddrval = lpDDPal->SetEntries(0,nStart,nColors,&sgCurr[nStart]);
|
|
// ddraw_assert(ddrval);
|
|
SDrawUpdatePalette(nStart,nColors,&sgCurr[nStart]);
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
**-----------------------------------------------------------------------*/
|
|
static void GammaPalette(PALETTEENTRY * pDst, const PALETTEENTRY * pSrc, int nNum) {
|
|
double gamma = sglGamma / 100.0;
|
|
for(int i = 0; i < nNum; i++,pDst++,pSrc++) {
|
|
pDst->peRed = (BYTE)(256.0*pow(((double)pSrc->peRed)/256.0, gamma));
|
|
pDst->peGreen = (BYTE)(256.0*pow(((double)pSrc->peGreen)/256.0, gamma));
|
|
pDst->peBlue = (BYTE)(256.0*pow(((double)pSrc->peBlue)/256.0, gamma));
|
|
}
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
**-----------------------------------------------------------------------*/
|
|
void SavePaletteSettings() {
|
|
SRegSaveValue(gszProgKey,sgszGamma,0,sglGamma);
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
**-----------------------------------------------------------------------*/
|
|
static void GetPaletteSettings() {
|
|
DWORD dwTemp = (DWORD) sglGamma;
|
|
if (! SRegLoadValue(gszProgKey,sgszGamma,0,&dwTemp))
|
|
dwTemp = lGAMMA_MAX;
|
|
|
|
sglGamma = (LONG) dwTemp;
|
|
if (sglGamma < lGAMMA_MIN)
|
|
sglGamma = lGAMMA_MIN;
|
|
else if (sglGamma > lGAMMA_MAX)
|
|
sglGamma = lGAMMA_MAX;
|
|
sglGamma -= sglGamma % lGAMMA_STEP;
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
**-----------------------------------------------------------------------*/
|
|
static void FixWindowsPal() {
|
|
int i;
|
|
|
|
// reserve all colors so no mapping occurs
|
|
for (i = 0; i < 256; i++)
|
|
sgCurr[i].peFlags = PC_NOCOLLAPSE | PC_RESERVED;
|
|
|
|
if (fullscreen) return;
|
|
|
|
// get static color count
|
|
HDC hDC = GetDC(NULL);
|
|
sgnStaticColors2 = GetDeviceCaps(hDC, NUMRESERVED) / 2;
|
|
|
|
// get the lower windows color set
|
|
GetSystemPaletteEntries(hDC, 0, sgnStaticColors2, &sgCurr[0]);
|
|
for (i = 0; i < sgnStaticColors2; i++) sgCurr[i].peFlags = 0;
|
|
|
|
// get the upper windows color set
|
|
i = 256 - sgnStaticColors2;
|
|
GetSystemPaletteEntries(hDC, i, sgnStaticColors2, &sgCurr[i]);
|
|
for ( ; i < 256; i++) sgCurr[i].peFlags = 0;
|
|
|
|
ReleaseDC(NULL, hDC);
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
**-----------------------------------------------------------------------*/
|
|
void CreatePalette() {
|
|
GetPaletteSettings();
|
|
CopyMemory(sgCurr,sgLoad,sizeof(sgCurr));
|
|
FixWindowsPal();
|
|
HRESULT ddrval = lpDD->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256 | DDPCAPS_INITIALIZE,sgCurr,&lpDDPal,NULL);
|
|
if (ddrval != DD_OK) ErrorDlg(IDD_DDRAW_PAL_ERR,ddrval,__FILE__,__LINE__);
|
|
|
|
ddrval = lpDDSPrimary->SetPalette(lpDDPal);
|
|
if (ddrval != DD_OK) ErrorDlg(IDD_DDRAW_PAL_ERR,ddrval,__FILE__,__LINE__);
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
**-----------------------------------------------------------------------*/
|
|
void LoadPalette(const char * pszFileName) {
|
|
struct RGB {
|
|
BYTE red;
|
|
BYTE green;
|
|
BYTE blue;
|
|
} pal[256];
|
|
|
|
HSFILE hFile;
|
|
app_assert(pszFileName);
|
|
patSFileOpenFile(pszFileName,&hFile);
|
|
patSFileReadFile(hFile,&pal[0],sizeof(pal));
|
|
patSFileCloseFile(hFile);
|
|
|
|
for (int i = 0; i < 256; i++) {
|
|
sgLoad[i].peRed = pal[i].red;
|
|
sgLoad[i].peGreen = pal[i].green;
|
|
sgLoad[i].peBlue = pal[i].blue;
|
|
sgLoad[i].peFlags = 0;
|
|
}
|
|
// GammaPalette(sgBase, sgLoad, 256);
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
**-----------------------------------------------------------------------*/
|
|
void LoadRndLvlPal(int l) {
|
|
|
|
if (l == 0) {
|
|
LoadPalette("Levels\\TownData\\Town.pal");
|
|
}
|
|
else {
|
|
char filestr[MAX_PATH];
|
|
int palnum = random(0, 4) + 1;
|
|
sprintf(filestr, "Levels\\L%iData\\L%i_%i.PAL", l, l, palnum);
|
|
// JKE add our palettes here
|
|
if (l == 5)
|
|
sprintf(filestr, "NLevels\\L5Data\\L5Base.PAL");
|
|
if (l == 6)
|
|
{
|
|
if (!gbOurNest)
|
|
++palnum;
|
|
sprintf(filestr, "NLevels\\L%iData\\L%iBase%i.PAL", l, l, palnum);
|
|
}
|
|
LoadPalette(filestr);
|
|
}
|
|
|
|
BuildLevelTileEnhanceTables();
|
|
BuildTownWarmFlickerTables();
|
|
BuildHudAnimateTables();
|
|
BuildWorldGoldShimmerTables();
|
|
gbLevelTileEnhanceActive = TRUE;
|
|
gbTownWarmFlickerActive = (l == 0);
|
|
gbHudAnimateActive = FALSE;
|
|
gbWorldGoldShimmerActive = TRUE;
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
**-----------------------------------------------------------------------*/
|
|
void ResetPal() {
|
|
if (lpDDSPrimary && lpDDSPrimary->IsLost() == DDERR_SURFACELOST)
|
|
if (DD_OK != lpDDSPrimary->Restore()) return;
|
|
SDrawRealizePalette();
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
**-----------------------------------------------------------------------*/
|
|
void GammaUp() {
|
|
if(sglGamma < lGAMMA_MAX) {
|
|
sglGamma += lGAMMA_STEP;
|
|
if (sglGamma > lGAMMA_MAX)
|
|
sglGamma = lGAMMA_MAX;
|
|
GammaPalette(sgCurr,sgBase,256);
|
|
SetPaletteEntries();
|
|
}
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
**-----------------------------------------------------------------------*/
|
|
void GammaDown() {
|
|
if(sglGamma > lGAMMA_MIN) {
|
|
sglGamma -= lGAMMA_STEP;
|
|
if (sglGamma < lGAMMA_MIN)
|
|
sglGamma = lGAMMA_MIN;
|
|
GammaPalette(sgCurr,sgBase,256);
|
|
SetPaletteEntries();
|
|
}
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
**-----------------------------------------------------------------------*/
|
|
LONG GammaLevel(LONG lGamma) {
|
|
if (lGamma != lGAMMA_READ) {
|
|
// invert gamma hi/lo
|
|
sglGamma = lGAMMA_MAX - lGamma + lGAMMA_MIN;
|
|
GammaPalette(sgCurr,sgBase,256);
|
|
SetPaletteEntries();
|
|
}
|
|
|
|
// invert gamma hi/lo
|
|
return lGAMMA_MAX - sglGamma + lGAMMA_MIN;
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
**-----------------------------------------------------------------------*/
|
|
static void SetFadeLevel(int fadeval) {
|
|
if (! lpDD) return;
|
|
|
|
for (int i = 0; i < 255; i++) {
|
|
DWORD pv;
|
|
pv = sgBase[i].peRed * fadeval;
|
|
sgCurr[i].peRed = (BYTE) (pv/256);
|
|
pv = sgBase[i].peGreen * fadeval;
|
|
sgCurr[i].peGreen = (BYTE) (pv/256);
|
|
pv = sgBase[i].peBlue * fadeval;
|
|
sgCurr[i].peBlue = (BYTE) (pv/256);
|
|
}
|
|
|
|
// sgCurr[i].peRed = 0xff;
|
|
// sgCurr[i].peGreen = 0xff;
|
|
// sgCurr[i].peBlue = 0xff;
|
|
|
|
Sleep(3);
|
|
lpDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN,NULL);
|
|
SetPaletteEntries();
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
**-----------------------------------------------------------------------*/
|
|
void BlackPalette() {
|
|
SetFadeLevel(0);
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
**-----------------------------------------------------------------------*/
|
|
void PaletteFadeIn(int faderate) {
|
|
GammaPalette(sgBase,sgLoad,256);
|
|
for (int i = 0; i < 256; i += faderate)
|
|
SetFadeLevel(i);
|
|
SetFadeLevel(256);
|
|
|
|
// un-gamma-fy base palette
|
|
CopyMemory(sgBase,sgLoad,sizeof(sgBase));
|
|
sgbFadedIn = TRUE;
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
**-----------------------------------------------------------------------*/
|
|
void PaletteFadeOut(int faderate) {
|
|
if (! sgbFadedIn) return;
|
|
for (int i = 256; i > 0; i -= faderate)
|
|
SetFadeLevel(i);
|
|
SetFadeLevel(0);
|
|
sgbFadedIn = FALSE;
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
**-----------------------------------------------------------------------*/
|
|
void LavaCycle() {
|
|
PALETTEENTRY temp = sgCurr[1];
|
|
for (int i = 1; i < 31; i++) {
|
|
sgCurr[i].peRed = sgCurr[i + 1].peRed;
|
|
sgCurr[i].peGreen = sgCurr[i + 1].peGreen;
|
|
sgCurr[i].peBlue = sgCurr[i + 1].peBlue;
|
|
// don't copy flags
|
|
}
|
|
|
|
sgCurr[i].peRed = temp.peRed;
|
|
sgCurr[i].peGreen = temp.peGreen;
|
|
sgCurr[i].peBlue = temp.peBlue;
|
|
// don't copy flags
|
|
|
|
SetPaletteEntries();
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
**-----------------------------------------------------------------------*/
|
|
// JKE new cycle to do twin effects
|
|
void TwinCycleCrypt() {
|
|
int i;
|
|
static int toggle = 0;
|
|
static int toggle2 = 0;
|
|
PALETTEENTRY temp;
|
|
|
|
if (toggle2 > 1)
|
|
{
|
|
temp = sgCurr[15];
|
|
for (i = 15; i > 1; --i) {
|
|
sgCurr[i].peRed = sgCurr[i - 1].peRed;
|
|
sgCurr[i].peGreen = sgCurr[i - 1].peGreen;
|
|
sgCurr[i].peBlue = sgCurr[i - 1].peBlue;
|
|
// don't copy flags
|
|
}
|
|
sgCurr[i].peRed = temp.peRed;
|
|
sgCurr[i].peGreen = temp.peGreen;
|
|
sgCurr[i].peBlue = temp.peBlue;
|
|
// don't copy flags
|
|
toggle2 = 0;
|
|
}
|
|
else
|
|
++toggle2;
|
|
|
|
if (toggle > 0)
|
|
{
|
|
temp = sgCurr[31];
|
|
for (i = 31; i > 16; --i)
|
|
{
|
|
sgCurr[i].peRed = sgCurr[i - 1].peRed;
|
|
sgCurr[i].peGreen = sgCurr[i - 1].peGreen;
|
|
sgCurr[i].peBlue = sgCurr[i - 1].peBlue;
|
|
}
|
|
sgCurr[i].peRed = temp.peRed;
|
|
sgCurr[i].peGreen = temp.peGreen;
|
|
sgCurr[i].peBlue = temp.peBlue;
|
|
|
|
SetPaletteEntries();
|
|
++toggle;
|
|
}
|
|
else
|
|
toggle = 1;
|
|
}
|
|
void TwinCycleNest() {
|
|
int i;
|
|
static int toggle = 0;
|
|
static int toggle2 = 0;
|
|
PALETTEENTRY temp;
|
|
if (toggle2 == 2)
|
|
{
|
|
temp = sgCurr[8];
|
|
for (i = 8; i > 1; --i) {
|
|
sgCurr[i].peRed = sgCurr[i - 1].peRed;
|
|
sgCurr[i].peGreen = sgCurr[i - 1].peGreen;
|
|
sgCurr[i].peBlue = sgCurr[i - 1].peBlue;
|
|
// don't copy flags
|
|
}
|
|
|
|
sgCurr[i].peRed = temp.peRed;
|
|
sgCurr[i].peGreen = temp.peGreen;
|
|
sgCurr[i].peBlue = temp.peBlue;
|
|
// don't copy flags
|
|
toggle2 = 0;
|
|
}
|
|
else
|
|
++toggle2;
|
|
|
|
if (toggle == 2)
|
|
{
|
|
temp = sgCurr[15];
|
|
for (i = 15; i > 9; --i)
|
|
{
|
|
sgCurr[i].peRed = sgCurr[i - 1].peRed;
|
|
sgCurr[i].peGreen = sgCurr[i - 1].peGreen;
|
|
sgCurr[i].peBlue = sgCurr[i - 1].peBlue;
|
|
}
|
|
sgCurr[i].peRed = temp.peRed;
|
|
sgCurr[i].peGreen = temp.peGreen;
|
|
sgCurr[i].peBlue = temp.peBlue;
|
|
|
|
SetPaletteEntries();
|
|
toggle = 0;
|
|
}
|
|
else
|
|
++toggle;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
**-----------------------------------------------------------------------*/
|
|
void UpdateLavaPalette() {
|
|
for (int i = 0; i < 32; i++)
|
|
sgBase[i] = sgLoad[i];
|
|
GammaPalette(sgCurr,sgBase,32);
|
|
SetPaletteEntries();
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
**-----------------------------------------------------------------------*/
|
|
void MeshLavaPalette(int fadeval) {
|
|
int i;
|
|
|
|
for (i = 32 - fadeval; i >= 0; i--)
|
|
sgBase[i] = sgLoad[i];
|
|
GammaPalette(sgCurr, sgBase, 32);
|
|
SetPaletteEntries();
|
|
}
|