Skip to content

Commit 5312260

Browse files
adyapowerof3
authored andcommitted
Added SetColorTint to GFxValue and GFxMovie. Added constructors to GColor.
1 parent 7f8e63d commit 5312260

File tree

5 files changed

+140
-0
lines changed

5 files changed

+140
-0
lines changed

include/RE/G/GColor.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,32 @@ namespace RE
2121
};
2222
static_assert(sizeof(ColorData) == 0x4);
2323

24+
constexpr GColor() noexcept :
25+
colorData{}
26+
{}
27+
28+
constexpr GColor(std::uint8_t a_red, std::uint8_t a_green, std::uint8_t a_blue, std::uint8_t a_alpha = 255) noexcept :
29+
colorData{}
30+
{
31+
colorData.channels.red = a_red;
32+
colorData.channels.green = a_green;
33+
colorData.channels.blue = a_blue;
34+
colorData.channels.alpha = a_alpha;
35+
36+
colorData.raw = (static_cast<std::uint32_t>(a_alpha) << 24) | (static_cast<std::uint32_t>(a_red) << 16) | (static_cast<std::uint32_t>(a_green) << 8) | a_blue;
37+
}
38+
39+
constexpr GColor(std::uint32_t a_raw) noexcept :
40+
colorData{}
41+
{
42+
colorData.raw = a_raw;
43+
44+
colorData.channels.alpha = (a_raw >> 24) & 0xFF;
45+
colorData.channels.red = (a_raw >> 16) & 0xFF;
46+
colorData.channels.green = (a_raw >> 8) & 0xFF;
47+
colorData.channels.blue = a_raw & 0xFF;
48+
}
49+
2450
// members
2551
ColorData colorData; // 0
2652
};

include/RE/G/GFxMovie.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include "RE/G/GFxPlayerStats.h"
44
#include "RE/G/GRefCountBase.h"
5+
#include "RE/G/GColor.h"
56

67
namespace RE
78
{
@@ -74,6 +75,24 @@ namespace RE
7475
double GetVariableDouble(const char* a_pathToVar) const;
7576
bool SetVariableArray(const char* a_pathToVar, std::uint32_t a_index, const GFxValue* a_data, std::uint32_t a_count, SetVarType a_setType = SetVarType::kSticky);
7677
bool GetVariableArray(const char* a_pathToVar, std::uint32_t a_index, GFxValue* a_data, std::uint32_t a_count);
78+
79+
/// <summary>
80+
/// Applies a color tint to a display object at the specified path.
81+
/// This is a convenience method that retrieves the display object and calls SetColorTint on it.
82+
/// The alpha channel of the color determines the intensity of the tint (0 = no tint, 255 = full tint).
83+
/// </summary>
84+
/// <param name="a_pathToVar">Path to the display object (e.g. "_root.MyObject")</param>
85+
/// <param name="a_tint">The color to tint toward. Alpha channel determines intensity (0-255)</param>
86+
/// <returns>True if the display object was found and tinted successfully, false otherwise</returns>
87+
bool SetColorTint(const char* a_pathToVar, const GColor& a_tint);
88+
89+
/// <summary>
90+
/// Removes any color tint from a display object at the specified path.
91+
/// This is a convenience method that retrieves the display object and calls RemoveColorTint on it.
92+
/// </summary>
93+
/// <param name="a_pathToVar">Path to the display object (e.g. "_root.MyObject")</param>
94+
/// <returns>True if the display object was found and the tint was removed successfully, false otherwise</returns>
95+
bool RemoveColorTint(const char* a_pathToVar);
7796
};
7897
static_assert(sizeof(GFxMovie) == 0x10);
7998
}

include/RE/G/GFxValue.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,22 @@ namespace RE
404404
bool GotoAndPlay(const char* a_frame);
405405
bool GotoAndStop(const char* a_frame);
406406

407+
/// <summary>
408+
/// Applies a color tint to this display object by modifying its color transform.
409+
/// The tint is applied by blending the object's colors toward the specified tint color.
410+
/// The alpha channel of the color determines the intensity of the tint (0 = no tint, 255 = full tint).
411+
/// </summary>
412+
/// <param name="a_tint">The color to tint toward. Alpha channel determines intensity (0-255)</param>
413+
/// <returns>True if the color transform was successfully applied, false otherwise</returns>
414+
bool SetColorTint(const GColor& a_tint);
415+
416+
/// <summary>
417+
/// Removes any color tint from this display object by resetting its color transform to identity.
418+
/// This restores the original colors of the display object.
419+
/// </summary>
420+
/// <returns>True if the color transform was successfully reset, false otherwise</returns>
421+
bool RemoveColorTint();
422+
407423
GFC_MEMORY_REDEFINE_NEW(GFxValue, GStatGroups::kGStatGroup_Default);
408424

409425
protected:

src/RE/G/GFxMovie.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "RE/G/GFxMovie.h"
22

3+
#include "RE/G/GColor.h"
34
#include "RE/G/GFxMovieDef.h"
45
#include "RE/G/GFxValue.h"
56

@@ -54,4 +55,32 @@ namespace RE
5455
{
5556
return GetVariableArray(SetArrayType::kValue, a_pathToVar, a_index, a_data, a_count);
5657
}
58+
59+
bool GFxMovie::SetColorTint(const char* a_pathToVar, const GColor& a_tint)
60+
{
61+
GFxValue object;
62+
if (!GetVariable(&object, a_pathToVar)) {
63+
return false;
64+
}
65+
66+
if (!object.IsDisplayObject()) {
67+
return false;
68+
}
69+
70+
return object.SetColorTint(a_tint);
71+
}
72+
73+
bool GFxMovie::RemoveColorTint(const char* a_pathToVar)
74+
{
75+
GFxValue object;
76+
if (!GetVariable(&object, a_pathToVar)) {
77+
return false;
78+
}
79+
80+
if (!object.IsDisplayObject()) {
81+
return false;
82+
}
83+
84+
return object.RemoveColorTint();
85+
}
5786
}

src/RE/G/GFxValue.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include "RE/G/GFxValue.h"
22

3+
#include "RE/G/GColor.h"
4+
35
namespace RE
46
{
57
GFxValue::DisplayInfo::DisplayInfo(double a_x, double a_y) :
@@ -992,6 +994,54 @@ namespace RE
992994
return _objectInterface->GotoAndPlay(_value.obj, a_frame, true);
993995
}
994996

997+
bool GFxValue::SetColorTint(const GColor& a_tint)
998+
{
999+
assert(IsDisplayObject());
1000+
1001+
using Cxform = GRenderer::Cxform;
1002+
1003+
Cxform colorTransform;
1004+
if (!GetCxform(&colorTransform)) {
1005+
return false;
1006+
}
1007+
1008+
// Normalize color values from 0-255 to 0-1
1009+
float normalizedRed = a_tint.colorData.channels.red / 255.0f;
1010+
float normalizedGreen = a_tint.colorData.channels.green / 255.0f;
1011+
float normalizedBlue = a_tint.colorData.channels.blue / 255.0f;
1012+
1013+
// Use alpha channel as intensity (0-255 -> 0-1)
1014+
float intensity = a_tint.colorData.channels.alpha / 255.0f;
1015+
1016+
// Apply color transform
1017+
// Multiply: reduce the original color channels that aren't the tint color
1018+
colorTransform.matrix[Cxform::kR][Cxform::kMult] = 1.0f - (intensity * (1.0f - normalizedRed));
1019+
colorTransform.matrix[Cxform::kG][Cxform::kMult] = 1.0f - (intensity * (1.0f - normalizedGreen));
1020+
colorTransform.matrix[Cxform::kB][Cxform::kMult] = 1.0f - (intensity * (1.0f - normalizedBlue));
1021+
colorTransform.matrix[Cxform::kA][Cxform::kMult] = 1.0f;
1022+
1023+
// Add: boost the tint color channels
1024+
colorTransform.matrix[Cxform::kR][Cxform::kAdd] = intensity * normalizedRed * 0.5f;
1025+
colorTransform.matrix[Cxform::kG][Cxform::kAdd] = intensity * normalizedGreen * 0.5f;
1026+
colorTransform.matrix[Cxform::kB][Cxform::kAdd] = intensity * normalizedBlue * 0.5f;
1027+
colorTransform.matrix[Cxform::kA][Cxform::kAdd] = 0.0f;
1028+
1029+
return SetCxform(colorTransform);
1030+
}
1031+
1032+
bool GFxValue::RemoveColorTint()
1033+
{
1034+
assert(IsDisplayObject());
1035+
1036+
GRenderer::Cxform colorTransform;
1037+
if (!GetCxform(&colorTransform)) {
1038+
return false;
1039+
}
1040+
colorTransform.SetIdentity();
1041+
1042+
return SetCxform(colorTransform);
1043+
}
1044+
9951045
bool GFxValue::IsManagedValue() const
9961046
{
9971047
return _type.all(ValueType::kManagedBit);

0 commit comments

Comments
 (0)