mirror of
https://github.com/jmarshall23/CnC_Remastered_Collection.git
synced 2026-08-12 08:00:55 +02:00
Remaster palettes now work correctly.
This commit is contained in:
+1
-1
@@ -1,4 +1,4 @@
|
||||
# CMakeList.txt : CMake project for Red Alert
|
||||
# CMakeList.txt : CMake project for Red Alert
|
||||
cmake_minimum_required (VERSION 3.8)
|
||||
|
||||
project(RedAlert ASM CXX C)
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// HOUSECOLOR.H
|
||||
//
|
||||
|
||||
#include "vectormath.h"
|
||||
|
||||
struct HouseColorHD {
|
||||
HouseColorHD(float3 lowerbounds,
|
||||
float3 upperbounds,
|
||||
float fudge,
|
||||
float3 hsvshift,
|
||||
float3 inputlevels,
|
||||
float2 outputlevels,
|
||||
float3 overallinputlevels,
|
||||
float2 overalloutputlevels,
|
||||
float3 radarmapcolor)
|
||||
{
|
||||
this->LowerBounds = lowerbounds;
|
||||
this->UpperBounds = upperbounds;
|
||||
this->Fudge = fudge;
|
||||
this->HSVShift = hsvshift;
|
||||
this->InputLevels = inputlevels;
|
||||
this->OutputLevels = outputlevels;
|
||||
this->OverallInputLevels = overallinputlevels;
|
||||
this->OverallOutputLevels = overalloutputlevels;
|
||||
this->RadarMapColor = radarmapcolor;
|
||||
}
|
||||
|
||||
float3 LowerBounds;
|
||||
float3 UpperBounds;
|
||||
float Fudge;
|
||||
float3 HSVShift;
|
||||
float3 InputLevels;
|
||||
float2 OutputLevels;
|
||||
float3 OverallInputLevels;
|
||||
float2 OverallOutputLevels;
|
||||
float3 RadarMapColor;
|
||||
};
|
||||
|
||||
// This data has been sourced from the TD Original Skirmish Color mod by Pokey
|
||||
//
|
||||
static HouseColorHD *houseColors[8] = {
|
||||
// Spain
|
||||
new HouseColorHD(float3(0.26f, 1.0f, 1.0f), float3(0.0f, 1.0f, 0.22f), 0, float3(0.777f,-0.196, -0.0f), float3(0.0f, 1.0f, 1.0f), float2(0.0f, 1.0f), float3(0.0f, 1.0f, 1.0f), float2(0.0f, 1.0f), float3(0.737255, 0.627451, 0.239216) ),
|
||||
// Greece
|
||||
new HouseColorHD(float3(0.264706f, 1.0f, 0.0f), float3(0.0f, 1.0f, 0.22f), 0, float3(0.310000f,-0.211000, 0.005000), float3(0.0f, 1.0f, 1.0f), float2(0.0f, 1.0f), float3(0.0f, 1.0f, 1.0f), float2(0.0f, 1.0f), float3(0.0980f, 0.3922, 0.9216)),
|
||||
// USSR
|
||||
new HouseColorHD(float3(0.264706f, 1.0f, 0.0f), float3(0.0f, 1.0f, 0.22f), 0, float3(0.689000f,0.382000, 0.000000), float3(0.0f, 1.0f, 1.0f), float2(0.0f, 1.0f), float3(0.0f, 1.0f, 1.0f), float2(0.0f, 1.0f), float3(0.756863f, 0.0, 0.015686)),
|
||||
// England
|
||||
new HouseColorHD(float3(0.26, 1.0f, 0.0f), float3(0.0f, 1.0f, 0.22f), 0, float3(0.911f,-0.381, 0.000000), float3(0.0f, 1.0f, 1.0f), float2(0.0f, 1.0f), float3(0.0f, 1.0f, 1.0f), float2(0.0f, 1.0f), float3(0.184314, 0.67451, 0.141176)),
|
||||
// Ukraine
|
||||
new HouseColorHD(float3(0.26, 1.0f, 0.0f), float3(0.0f, 1.0f, 0.22f), 0, float3(0.726,0.119, 0.000000), float3(0.0f, 1.0f, 1.0f), float2(0.0f, 1.0f), float3(0.0f, 1.0f, 1.0f), float2(0.0f, 1.0f), float3(0.772549, 0.380392, 0.07451)),
|
||||
// Germany
|
||||
new HouseColorHD(float3(0.26, 1.0f, 0.0f), float3(0.0f, 1.0f, 0.22f), 0, float3(0.713,-0.621, 0.000000), float3(0.0f, 1.0f, 1.0f), float2(0.0f, 1.0f), float3(0.0f, 1.0f, 1.0f), float2(0.0f, 1.0f), float3(0.6421568, 0.4784698, 0.4784698)),
|
||||
// France
|
||||
new HouseColorHD(float3(0.26, 1.0f, 0.0f), float3(0.0f, 1.0f, 0.22f), 0, float3(0.119,-0.233, 0.000000), float3(0.0f, 1.0f, 1.0f), float2(0.0f, 1.0f), float3(0.0f, 1.0f, 1.0f), float2(0.0f, 1.0f), float3(0.1151961, 0.6911765, 0.4031861)),
|
||||
// Turkey
|
||||
new HouseColorHD(float3(0.26, 1.0f, 0.0f), float3(0.0f, 1.0f, 0.22f), 0, float3(0.685,-0.151, 0.000000), float3(0.0f, 1.0f, 1.0f), float2(0.0f, 1.0f), float3(0.0f, 1.0f, 1.0f), float2(0.0f, 1.0f), float3(0.5784314, 0.1155861, 0.05387352)),
|
||||
};
|
||||
@@ -0,0 +1,206 @@
|
||||
// IMGUTIL.H
|
||||
//
|
||||
|
||||
#ifdef _DEBUG
|
||||
#pragma optimize( "", on )
|
||||
#endif
|
||||
|
||||
// SRGB -> Linear color space conversion.
|
||||
inline float ByteToLinear(byte p) {
|
||||
float v;
|
||||
v = ((float)p) / 255.0f;
|
||||
v = (double)v >= 0.0404499992728233 ? (float)pow((200.0 * (double)v + 11.0) / 211.0, 2.40000009536743) : (float)((double)v * 25.0 / 323.0);
|
||||
return v;
|
||||
}
|
||||
|
||||
inline float ToSRGB(float v)
|
||||
{
|
||||
return (double)v >= 0.0031308 ? (float)((pow((double)v, 0.416666656732559) * 211.0 - 11.0) / 200.0) : (float)((double)v * 323.0 / 25.0);
|
||||
}
|
||||
|
||||
inline float PixelToHue(float R, float G, float B) {
|
||||
if (R == G && G == B)
|
||||
return 0; // 0 makes as good an UNDEFINED value as any
|
||||
|
||||
float r = (float)R / 255.0f;
|
||||
float g = (float)G / 255.0f;
|
||||
float b = (float)B / 255.0f;
|
||||
|
||||
float max, min;
|
||||
float delta;
|
||||
float hue = 0.0f;
|
||||
|
||||
max = r; min = r;
|
||||
|
||||
if (g > max) max = g;
|
||||
if (b > max) max = b;
|
||||
|
||||
if (g < min) min = g;
|
||||
if (b < min) min = b;
|
||||
|
||||
delta = max - min;
|
||||
|
||||
if (r == max) {
|
||||
hue = (g - b) / delta;
|
||||
}
|
||||
else if (g == max) {
|
||||
hue = 2 + (b - r) / delta;
|
||||
}
|
||||
else if (b == max) {
|
||||
hue = 4 + (r - g) / delta;
|
||||
}
|
||||
hue *= 60;
|
||||
|
||||
if (hue < 0.0f) {
|
||||
hue += 360.0f;
|
||||
}
|
||||
return hue;
|
||||
}
|
||||
|
||||
struct Turple {
|
||||
Turple() {
|
||||
memset(this, 0, sizeof(Turple));
|
||||
}
|
||||
Turple(float Item1, float Item2, float Item3) {
|
||||
this->Item1 = Item1;
|
||||
this->Item2 = Item2;
|
||||
this->Item3 = Item3;
|
||||
this->Item4 = -1;
|
||||
}
|
||||
Turple(float Item1, float Item2, float Item3, float Item4) {
|
||||
this->Item1 = Item1;
|
||||
this->Item2 = Item2;
|
||||
this->Item3 = Item3;
|
||||
this->Item4 = Item4;
|
||||
}
|
||||
float Item1;
|
||||
float Item2;
|
||||
float Item3;
|
||||
float Item4;
|
||||
};
|
||||
|
||||
|
||||
float step(float a, float x)
|
||||
{
|
||||
return x >= a;
|
||||
}
|
||||
|
||||
inline float4 lerp(float4 a, float4 b, float w)
|
||||
{
|
||||
float4 l;
|
||||
l.x = a.x + w * (b.x - a.x);
|
||||
l.y = a.y + w * (b.y - a.y);
|
||||
l.z = a.z + w * (b.z - a.z);
|
||||
l.w = a.w + w * (b.w - a.w);
|
||||
return l;
|
||||
}
|
||||
|
||||
inline float3 lerp(float3 a, float3 b, float w)
|
||||
{
|
||||
float3 l;
|
||||
l.x = a.x + w * (b.x - a.x);
|
||||
l.y = a.y + w * (b.y - a.y);
|
||||
l.z = a.z + w * (b.z - a.z);
|
||||
return l;
|
||||
}
|
||||
|
||||
inline float3 frac(float3 v)
|
||||
{
|
||||
float3 f;
|
||||
f.x = v.x - floor(v.x);
|
||||
f.y = v.y - floor(v.y);
|
||||
f.z = v.z - floor(v.z);
|
||||
return f;
|
||||
}
|
||||
|
||||
inline float frac(float v)
|
||||
{
|
||||
return v - floor(v);
|
||||
}
|
||||
|
||||
inline float lerp(float a, float b, float w)
|
||||
{
|
||||
return a + w * (b - a);
|
||||
}
|
||||
|
||||
|
||||
inline float3 clamp(float3 x, float a, float b)
|
||||
{
|
||||
float3 r;
|
||||
r.x = max(a, min(b, x.x));
|
||||
r.y = max(a, min(b, x.y));
|
||||
r.z = max(a, min(b, x.z));
|
||||
return r;
|
||||
}
|
||||
|
||||
inline float saturate(float x)
|
||||
{
|
||||
return max(0, min(1, x));
|
||||
}
|
||||
|
||||
inline void RenderTeamPalette(byte* pixel, HouseColorHD &teamColor) {
|
||||
float linear1 = ByteToLinear(pixel[2]);
|
||||
float linear2 = ByteToLinear(pixel[1]);
|
||||
float linear3 = ByteToLinear(pixel[0]);
|
||||
float num1 = linear1;
|
||||
float num2 = linear2;
|
||||
float num3 = (float)linear3;
|
||||
Turple valueTuple1 = Turple(0.0f, -0.3333333, 0.6666667, -1 );
|
||||
Turple valueTuple2;
|
||||
|
||||
if ((double)num2 >= (double)num3)
|
||||
valueTuple2 = Turple( num2, num3, valueTuple1.Item1, valueTuple1.Item2 );
|
||||
else
|
||||
valueTuple2 = Turple( num3, num2, valueTuple1.Item4, valueTuple1.Item3 );
|
||||
|
||||
Turple valueTuple3;
|
||||
if ((double)num1 >= (double)valueTuple2.Item1)
|
||||
valueTuple3 = Turple(num1, valueTuple2.Item2, valueTuple2.Item3, valueTuple2.Item1);
|
||||
else
|
||||
valueTuple3 = Turple(valueTuple2.Item1, valueTuple2.Item2, valueTuple2.Item4, num1);
|
||||
double num4 = (double)valueTuple3.Item1 - (double)min(valueTuple3.Item4, valueTuple3.Item2);
|
||||
float num5 = 1E-10f;
|
||||
float num6 = (float)num4;
|
||||
float num7 = num5;
|
||||
float num8 = abs(valueTuple3.Item3 + (float)(((double)valueTuple3.Item4 - (double)valueTuple3.Item2) / (6.0 * (double)num6 + (double)num7)));
|
||||
float num9 = num6 / (valueTuple3.Item1 + num7);
|
||||
double num10 = (double)valueTuple3.Item1;
|
||||
float num11 = num8;
|
||||
float num12 = num9;
|
||||
float num13 = (float)num10;
|
||||
float num14 = PixelToHue(teamColor.LowerBounds.x, teamColor.LowerBounds.y, teamColor.LowerBounds.z) / 360;
|
||||
float num15 = PixelToHue(teamColor.UpperBounds.x, teamColor.UpperBounds.y, teamColor.UpperBounds.z) / 360;
|
||||
|
||||
if ((double)num11 >= (double)num14 && (double)num15 >= (double)num11)
|
||||
{
|
||||
float num16 = (float)((double)num11 / ((double)num15 - (double)num14) * ((double)num15 + (double)teamColor.Fudge - ((double)num14 - (double)teamColor.Fudge))) + teamColor.HSVShift.x;
|
||||
float t = num12 + teamColor.HSVShift.y;
|
||||
float num17 = num13 + teamColor.HSVShift.z;
|
||||
Turple valueTuple4 = Turple(1.0f, 0.6666667, 0.3333333, 3);
|
||||
Turple valueTuple5 = Turple(abs(frac(num16 + valueTuple4.Item1) * 6 - valueTuple4.Item4), abs(frac(num16 + valueTuple4.Item2) * 6 - valueTuple4.Item4), abs(frac(num16 + valueTuple4.Item3) * 6 - valueTuple4.Item4));
|
||||
float num18 = num17 * lerp(valueTuple4.Item1, saturate(valueTuple5.Item1 - valueTuple4.Item1), t);
|
||||
float num19 = num17 * lerp(valueTuple4.Item1, saturate(valueTuple5.Item2 - valueTuple4.Item1), t);
|
||||
float num20 = num17 * lerp(valueTuple4.Item1, saturate(valueTuple5.Item3 - valueTuple4.Item1), t);
|
||||
Turple valueTuple6 = Turple(min(1, max(0.0f, num18 - teamColor.InputLevels.x) / (teamColor.InputLevels.z - teamColor.InputLevels.x)), min(1, max(0.0f, num19 - teamColor.InputLevels.x) / (teamColor.InputLevels.z - teamColor.InputLevels.x)), min(1, max(0.0f, num20 - teamColor.InputLevels.x) / (teamColor.InputLevels.z - teamColor.InputLevels.x)));
|
||||
valueTuple6.Item1 = (float)pow((double)valueTuple6.Item1, (double)teamColor.InputLevels.y);
|
||||
valueTuple6.Item2 = (float)pow((double)valueTuple6.Item2, (double)teamColor.InputLevels.y);
|
||||
valueTuple6.Item3 = (float)pow((double)valueTuple6.Item3, (double)teamColor.InputLevels.y);
|
||||
num1 = lerp(teamColor.OutputLevels.x, teamColor.OutputLevels.y, valueTuple6.Item1);
|
||||
num2 = lerp(teamColor.OutputLevels.x, teamColor.OutputLevels.y, valueTuple6.Item2);
|
||||
num3 = lerp(teamColor.OutputLevels.x, teamColor.OutputLevels.y, valueTuple6.Item3);
|
||||
}
|
||||
|
||||
Turple valueTuple7 = Turple(min(1, max(0.0f, num1 - teamColor.OverallInputLevels.x) / (teamColor.OverallInputLevels.z - teamColor.OverallInputLevels.x)), min(1, max(0.0f, num2 - teamColor.OverallInputLevels.x) / (teamColor.OverallInputLevels.z - teamColor.OverallInputLevels.x)), min(1, max(0.0f, num3 - teamColor.OverallInputLevels.x) / (teamColor.OverallInputLevels.z - teamColor.OverallInputLevels.x)));
|
||||
valueTuple7.Item1 = (float)pow((double)valueTuple7.Item1, (double)teamColor.OverallInputLevels.y);
|
||||
valueTuple7.Item2 = (float)pow((double)valueTuple7.Item2, (double)teamColor.OverallInputLevels.y);
|
||||
valueTuple7.Item3 = (float)pow((double)valueTuple7.Item3, (double)teamColor.OverallInputLevels.y);
|
||||
float v1 = lerp(teamColor.OverallOutputLevels.x, teamColor.OverallOutputLevels.y, valueTuple7.Item1);
|
||||
float v2 = lerp(teamColor.OverallOutputLevels.x, teamColor.OverallOutputLevels.y, valueTuple7.Item2);
|
||||
float v3 = lerp(teamColor.OverallOutputLevels.x, teamColor.OverallOutputLevels.y, valueTuple7.Item3);
|
||||
pixel[2] = (byte)((double)ToSRGB(v1) * (double)255.0f);
|
||||
pixel[1] = (byte)((double)ToSRGB(v2) * (double)255.0f);
|
||||
pixel[0] = (byte)((double)ToSRGB(v3) * (double)255.0f);
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
#pragma optimize( "", off )
|
||||
#endif
|
||||
@@ -63,6 +63,8 @@
|
||||
#include <examples/imgui_impl_opengl3.h>
|
||||
|
||||
#include <vector>
|
||||
#include "HOUSECOLOR.H"
|
||||
#include "IMGUTIL.H"
|
||||
|
||||
GLuint backbuffer_texture = -1;
|
||||
//byte* backbuffer_data;
|
||||
@@ -109,28 +111,7 @@ static int64_t generateHashValue(const char* fname, const int size) {
|
||||
return hash;
|
||||
}
|
||||
|
||||
static void OffsetRemap(unsigned char remap[3]) {
|
||||
int r = remap[0] << 2;
|
||||
int g = remap[1] << 2;
|
||||
int b = remap[2] << 2;
|
||||
|
||||
// normalize by color instead of saturating to white
|
||||
//if ((r | g | b) > 255) {
|
||||
// int max;
|
||||
//
|
||||
// max = r > g ? r : g;
|
||||
// max = max > b ? max : b;
|
||||
// r = r * 255 / max;
|
||||
// g = g * 255 / max;
|
||||
// b = b * 255 / max;
|
||||
//}
|
||||
|
||||
remap[0] = r;
|
||||
remap[1] = g;
|
||||
remap[2] = b;
|
||||
}
|
||||
|
||||
static bool Image_loadHDImage(Image_t *image, const char* name, int houseid, int animid, int64_t hash, unsigned char remap[3]) {
|
||||
static bool Image_loadHDImage(Image_t *image, const char* name, int houseid, int animid, int64_t hash, int houseId) {
|
||||
ILuint ImageName;
|
||||
ilGenImages(1, &ImageName);
|
||||
ilBindImage(ImageName);
|
||||
@@ -151,18 +132,9 @@ static bool Image_loadHDImage(Image_t *image, const char* name, int houseid, int
|
||||
Bpp = ilGetInteger(IL_IMAGE_BPP);
|
||||
ILubyte* Data = ilGetData();
|
||||
|
||||
if (Bpp == 4 && (remap[0] + remap[1] + remap[2]) > 0) {
|
||||
OffsetRemap(remap);
|
||||
|
||||
if (Bpp == 4 && houseId != -1) {
|
||||
for (int i = 0; i < Width * Height; i++) {
|
||||
if (Data[(i * 4) + 1] > Data[(i * 4) + 0] && Data[(i * 4) + 1] > Data[(i * 4) + 2]) {
|
||||
float g = (Data[(i * 4) + 1] / 255.0f);
|
||||
for (int c = 0; c < 3; c++) {
|
||||
float f = ((remap[2 - c]) / 255.0f) * min(g, 1);
|
||||
f = f * 255.0f;
|
||||
Data[(i * 4) + c] = ((unsigned int) f); //((unsigned char)(f * 255.0f)) << 2; //((unsigned char)f) << 2;
|
||||
}
|
||||
}
|
||||
RenderTeamPalette(&Data[i * 4], *houseColors[houseId]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,7 +198,7 @@ Image_t* Image_LoadImage(const char* name, bool loadAnims, bool loadHouseColor)
|
||||
|
||||
if (!loadAnims) {
|
||||
unsigned char remap[3] = { 0, 0, 0 };
|
||||
if (!Image_loadHDImage(image, name, 0, 0, hash, remap)) {
|
||||
if (!Image_loadHDImage(image, name, 0, 0, hash, -1)) {
|
||||
delete image;
|
||||
return NULL;
|
||||
}
|
||||
@@ -240,7 +212,7 @@ Image_t* Image_LoadImage(const char* name, bool loadAnims, bool loadHouseColor)
|
||||
remap[0] = palette[(p * 3) + 0];
|
||||
remap[1] = palette[(p * 3) + 1];
|
||||
remap[2] = palette[(p * 3) + 2];
|
||||
if (!Image_loadHDImage(image, name, i, 0, hash, remap)) {
|
||||
if (!Image_loadHDImage(image, name, i, 0, hash, i)) {
|
||||
delete image;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user