iw4x-client/src/Components/Modules/Colors.cpp

242 lines
5.5 KiB
C++
Raw Normal View History

#include "STDInclude.hpp"
2015-12-23 08:45:53 -05:00
namespace Components
{
2015-12-23 10:56:02 -05:00
Dvar::Var Colors::NewColors;
2016-02-06 13:09:41 -05:00
std::vector<DWORD> Colors::ColorTable;
2015-12-23 10:56:02 -05:00
2016-02-07 08:19:55 -05:00
DWORD Colors::HsvToRgb(Colors::HsvColor hsv)
{
DWORD rgb;
unsigned char region, p, q, t;
unsigned int h, s, v, remainder;
if (hsv.s == 0)
{
rgb = RGB(hsv.v, hsv.v, hsv.v);
return rgb;
}
// converting to 16 bit to prevent overflow
h = hsv.h;
s = hsv.s;
v = hsv.v;
region = static_cast<uint8_t>(h / 43);
remainder = (h - (region * 43)) * 6;
p = static_cast<uint8_t>((v * (255 - s)) >> 8);
q = static_cast<uint8_t>((v * (255 - ((s * remainder) >> 8))) >> 8);
t = static_cast<uint8_t>((v * (255 - ((s * (255 - remainder)) >> 8))) >> 8);
switch (region)
{
case 0:
rgb = RGB(v, t, p);
break;
case 1:
rgb = RGB(q, v, p);
break;
case 2:
rgb = RGB(p, v, t);
break;
case 3:
rgb = RGB(p, q, v);
break;
case 4:
rgb = RGB(t, p, v);
break;
default:
rgb = RGB(v, p, q);
break;
}
return rgb;
}
2015-12-23 08:45:53 -05:00
void Colors::Strip(const char* in, char* out, int max)
{
2015-12-30 16:22:24 -05:00
if (!in || !out) return;
2015-12-23 08:45:53 -05:00
max--;
int current = 0;
while (*in != 0 && current < max)
{
2016-02-06 13:09:41 -05:00
char index = *(in + 1);
if (*in == '^' && (Colors::ColorIndex(index) != 7 || index == '7')) // Add 1 new color for now
2015-12-23 08:45:53 -05:00
{
2016-02-06 13:09:41 -05:00
in++;
2015-12-23 08:45:53 -05:00
}
else
{
2016-02-06 13:09:41 -05:00
*out = *in;
out++;
current++;
2015-12-23 08:45:53 -05:00
}
2015-12-30 16:22:24 -05:00
in++;
2015-12-23 08:45:53 -05:00
}
*out = '\0';
}
2016-01-02 09:19:34 -05:00
std::string Colors::Strip(std::string in)
{
char buffer[1000] = { 0 }; // Should be more than enough
Colors::Strip(in.data(), buffer, sizeof(buffer));
return std::string(buffer);
}
2016-02-06 13:09:41 -05:00
void __declspec(naked) Colors::ClientUserinfoChanged()
2015-12-23 08:45:53 -05:00
{
__asm
{
mov eax, [esp + 4h] // length
sub eax, 1
push eax
push ecx // name
push edx // buffer
call strncpy
add esp, 0Ch
retn
}
}
2016-01-01 11:36:47 -05:00
char* Colors::GetClientName(int localClientNum, int index, char *buf, size_t size)
2015-12-23 08:45:53 -05:00
{
2016-01-01 11:36:47 -05:00
Game::CL_GetClientName(localClientNum, index, buf, size);
2015-12-23 08:45:53 -05:00
// Remove the colors
strncpy(buf, Colors::Strip(buf).data(), size);
2015-12-23 08:45:53 -05:00
2016-01-01 11:36:47 -05:00
return buf;
2015-12-23 08:45:53 -05:00
}
2016-02-06 13:09:41 -05:00
void Colors::PatchColorLimit(char limit)
2015-12-23 08:45:53 -05:00
{
2016-02-06 13:09:41 -05:00
Utils::Hook::Set<char>(0x535629, limit); // DrawText2d
Utils::Hook::Set<char>(0x4C1BE4, limit); // No idea :P
Utils::Hook::Set<char>(0x4863DD, limit); // No idea :P
Utils::Hook::Set<char>(0x486429, limit); // No idea :P
Utils::Hook::Set<char>(0x49A5A8, limit); // No idea :P
Utils::Hook::Set<char>(0x505721, limit); // R_TextWidth
Utils::Hook::Set<char>(0x505801, limit); // No idea :P
Utils::Hook::Set<char>(0x50597F, limit); // No idea :P
Utils::Hook::Set<char>(0x5815DB, limit); // No idea :P
Utils::Hook::Set<char>(0x592ED0, limit); // No idea :P
Utils::Hook::Set<char>(0x5A2E2E, limit); // No idea :P
Utils::Hook::Set<char>(0x5A2733, limit - '0'); // No idea :P
}
2015-12-23 10:56:02 -05:00
2016-02-06 13:09:41 -05:00
char Colors::Add(uint8_t r, uint8_t g, uint8_t b)
{
char index = '0' + static_cast<char>(Colors::ColorTable.size());
Colors::ColorTable.push_back(RGB(r, g, b));
Colors::PatchColorLimit(index);
return index;
}
unsigned int Colors::ColorIndex(unsigned char index)
{
unsigned int result = index - '0';
if (result >= Colors::ColorTable.size() || result < 0) result = 7;
return result;
}
void Colors::LookupColor(DWORD* color, char index)
{
if (index == '8') // Color 8
2015-12-23 10:56:02 -05:00
{
2016-02-06 13:09:41 -05:00
*color = *reinterpret_cast<DWORD*>(0x66E5F70);
2015-12-23 10:56:02 -05:00
}
2016-02-06 13:09:41 -05:00
else if (index == '9') // Color 9
2015-12-23 10:56:02 -05:00
{
2016-02-06 13:09:41 -05:00
*color = *reinterpret_cast<DWORD*>(0x66E5F74);
2015-12-23 10:56:02 -05:00
}
2016-02-07 08:19:55 -05:00
else if (index == ':')
{
*color = Colors::HsvToRgb({ static_cast<uint8_t>((Game::Com_Milliseconds() / 200) % 256), 255,255 });
}
2016-02-06 13:09:41 -05:00
else
2015-12-23 10:56:02 -05:00
{
2016-02-06 13:09:41 -05:00
int clrIndex = Colors::ColorIndex(index);
// Use native colors
if (clrIndex <= 7 && !Colors::NewColors.Get<bool>())
{
*color = reinterpret_cast<DWORD*>(0x78DC70)[index - 48];
}
else
{
*color = Colors::ColorTable[clrIndex];
}
}
}
2015-12-23 08:45:53 -05:00
2016-02-06 13:09:41 -05:00
char* Colors::CleanStrStub(char* string)
{
Colors::Strip(string, string, strlen(string));
return string;
}
void __declspec(naked) Colors::LookupColorStub()
{
__asm
{
push ebx
push [esp + 8h] // Index
push esi // Color ref
call Colors::LookupColor
add esp, 8h
pop ebx
retn
2015-12-23 10:56:02 -05:00
}
}
2015-12-23 08:45:53 -05:00
2015-12-23 10:56:02 -05:00
Colors::Colors()
{
2015-12-23 08:45:53 -05:00
// Allow colored names ingame
Utils::Hook(0x5D8B40, Colors::ClientUserinfoChanged, HOOK_JUMP).Install()->Quick();
// Though, don't apply that to overhead names.
2016-01-01 11:36:47 -05:00
Utils::Hook(0x581932, Colors::GetClientName, HOOK_CALL).Install()->Quick();
2015-12-23 10:56:02 -05:00
2016-02-06 13:09:41 -05:00
// Patch RB_LookupColor
Utils::Hook(0x534CD0, Colors::LookupColorStub, HOOK_JUMP).Install()->Quick();
// Patch ColorIndex
Utils::Hook(0x417770, Colors::ColorIndex, HOOK_JUMP).Install()->Quick();
// Patch I_CleanStr
Utils::Hook(0x4AD470, Colors::CleanStrStub, HOOK_JUMP).Install()->Quick();
2015-12-23 10:56:02 -05:00
// Register dvar
2015-12-26 21:56:00 -05:00
Colors::NewColors = Dvar::Register<bool>("cg_newColors", true, Game::dvar_flag::DVAR_FLAG_SAVED, "Use Warfare<72> color code style.");
2016-02-06 13:09:41 -05:00
// Add our colors
Colors::Add(0, 0, 0); // 0 - Black
Colors::Add(255, 49, 49); // 1 - Red
Colors::Add(134, 192, 0); // 2 - Green
Colors::Add(255, 173, 34); // 3 - Yellow
Colors::Add(0, 135, 193); // 4 - Blue
Colors::Add(32, 197, 255); // 5 - Light Blue
Colors::Add(151, 80, 221); // 6 - Pink
Colors::Add(255, 255, 255); // 7 - White
Colors::Add(0, 0, 0); // 8 - Team color (axis?)
Colors::Add(0, 0, 0); // 9 - Team color (allies?)
// Custom colors
2016-02-07 08:19:55 -05:00
Colors::Add(0, 0, 0); // 10 - Rainbow (:)
//Colors::Add(0, 255, 200); // 11 - Turqoise (;) - using that color in infostrings (e.g. your name) fails, ';' is an illegal character!
2016-02-06 13:09:41 -05:00
}
Colors::~Colors()
{
Colors::ColorTable.clear();
2015-12-23 08:45:53 -05:00
}
}