Skip to content

Commit

Permalink
Sync some color and skin code with DDNet
Browse files Browse the repository at this point in the history
  • Loading branch information
Kaffeine committed Dec 2, 2024
1 parent 51f40ab commit febebaf
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 54 deletions.
13 changes: 12 additions & 1 deletion src/base/color.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,16 @@ class color4_base
return col;
}

DerivedT Multiply(const DerivedT &Other) const
{
DerivedT Color(static_cast<const DerivedT &>(*this));
Color.x *= Other.x;
Color.y *= Other.y;
Color.z *= Other.z;
Color.a *= Other.a;
return Color;
}

template<typename UnpackT>
static UnpackT UnpackAlphaLast(unsigned Color, bool Alpha = true)
{
Expand Down Expand Up @@ -166,8 +176,9 @@ class ColorHSLA : public color4_base<ColorHSLA>
ColorHSLA(){};

constexpr static const float DARKEST_LGT = 0.5f;
constexpr static const float DARKEST_LGT7 = 61.0f / 255.0f;

ColorHSLA UnclampLighting(float Darkest = DARKEST_LGT) const
ColorHSLA UnclampLighting(float Darkest) const
{
ColorHSLA col = *this;
col.l = Darkest + col.l * (1.0f - Darkest);
Expand Down
2 changes: 1 addition & 1 deletion src/engine/console.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class IConsole : public IInterface
virtual int GetInteger(unsigned Index) const = 0;
virtual float GetFloat(unsigned Index) const = 0;
virtual const char *GetString(unsigned Index) const = 0;
virtual ColorHSLA GetColor(unsigned Index, bool Light) const = 0;
virtual ColorHSLA GetColor(unsigned Index, float DarkestLighting) const = 0;

int GetClientId() { return m_ClientId; }

Expand Down
2 changes: 1 addition & 1 deletion src/engine/server/mapconverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ void MakeGrayScale(CImageInfo *pImg)

void SetQuadColor(CQuad *Quad, int Color)
{
ColorRGBA BodyColor = color_cast<ColorRGBA>(ColorHSLA(Color).UnclampLighting());
ColorRGBA BodyColor = color_cast<ColorRGBA>(ColorHSLA(Color).UnclampLighting(ColorHSLA::DARKEST_LGT));
CColor TypedColor;
TypedColor.r = BodyColor.r * 255;
TypedColor.g = BodyColor.g * 255;
Expand Down
29 changes: 13 additions & 16 deletions src/engine/shared/console.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ float CConsole::CResult::GetFloat(unsigned Index) const
return str_tofloat(m_apArgs[Index]);
}

ColorHSLA CConsole::CResult::GetColor(unsigned Index, bool Light) const
ColorHSLA CConsole::CResult::GetColor(unsigned Index, float DarkestLighting) const
{
ColorHSLA Hsla = ColorHSLA(0, 0, 0);
if(Index >= m_NumArgs)
Expand All @@ -49,8 +49,8 @@ ColorHSLA CConsole::CResult::GetColor(unsigned Index, bool Light) const
if(str_isallnum(pStr) || ((pStr[0] == '-' || pStr[0] == '+') && str_isallnum(pStr + 1))) // Teeworlds Color (Packed HSL)
{
Hsla = ColorHSLA(str_toulong_base(pStr, 10), true);
if(Light)
Hsla = Hsla.UnclampLighting();
if(DarkestLighting)
Hsla = Hsla.UnclampLighting(DarkestLighting);
}
else if(*pStr == '$') // Hex RGB
{
Expand Down Expand Up @@ -762,7 +762,7 @@ struct CColVariableData
{
IConsole *m_pConsole;
unsigned *m_pVariable;
bool m_Light;
float m_DarkestLighting;
bool m_Alpha;
unsigned m_OldValue;
};
Expand Down Expand Up @@ -841,12 +841,12 @@ static void ColVariableCommand(IConsole::IResult *pResult, void *pUserData)

if(pResult->NumArguments())
{
ColorHSLA Col = pResult->GetColor(0, pData->m_Light);
int Val = Col.Pack(pData->m_Light ? 0.5f : 0.0f, pData->m_Alpha);
const ColorHSLA Color = pResult->GetColor(0, pData->m_DarkestLighting);
const unsigned Value = Color.Pack(pData->m_DarkestLighting, pData->m_Alpha);

*(pData->m_pVariable) = Val;
*(pData->m_pVariable) = Value;
if(pResult->m_ClientId != IConsole::CLIENT_ID_GAME)
pData->m_OldValue = Val;
pData->m_OldValue = Value;
}
else
{
Expand All @@ -855,13 +855,11 @@ static void ColVariableCommand(IConsole::IResult *pResult, void *pUserData)
pData->m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "console", aBuf);
pResult->m_Value = *(pData->m_pVariable);

ColorHSLA Hsla(*(pData->m_pVariable), true);
if(pData->m_Light)
Hsla = Hsla.UnclampLighting();
const ColorHSLA Hsla = ColorHSLA(*pData->m_pVariable, true).UnclampLighting(pData->m_DarkestLighting);
str_format(aBuf, sizeof(aBuf), "H: %d°, S: %d%%, L: %d%%", round_truncate(Hsla.h * 360), round_truncate(Hsla.s * 100), round_truncate(Hsla.l * 100));
pData->m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "console", aBuf);

ColorRGBA Rgba = color_cast<ColorRGBA>(Hsla);
const ColorRGBA Rgba = color_cast<ColorRGBA>(Hsla);
str_format(aBuf, sizeof(aBuf), "R: %d, G: %d, B: %d, #%06X", round_truncate(Rgba.r * 255), round_truncate(Rgba.g * 255), round_truncate(Rgba.b * 255), Rgba.Pack(false));
pData->m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "console", aBuf);

Expand Down Expand Up @@ -996,13 +994,12 @@ void CConsole::ConToggle(IConsole::IResult *pResult, void *pUser)
else if(pfnCallback == ColVariableCommand)
{
CColVariableData *pData = static_cast<CColVariableData *>(pUserData);
bool Light = pData->m_Light;
float Darkest = Light ? 0.5f : 0.0f;
float DarkestLighting = pData->m_DarkestLighting;
bool Alpha = pData->m_Alpha;
unsigned Cur = *pData->m_pVariable;
ColorHSLA Val = Cur == pResult->GetColor(1, Light).Pack(Darkest, Alpha) ? pResult->GetColor(2, Light) : pResult->GetColor(1, Light);
ColorHSLA Val = Cur == pResult->GetColor(1, DarkestLighting).Pack(DarkestLighting, Alpha) ? pResult->GetColor(2, DarkestLighting) : pResult->GetColor(1, DarkestLighting);

str_format(aBuf, sizeof(aBuf), "%s %u", pResult->GetString(0), Val.Pack(Darkest, Alpha));
str_format(aBuf, sizeof(aBuf), "%s %u", pResult->GetString(0), Val.Pack(DarkestLighting, Alpha));
pConsole->ExecuteLine(aBuf);
aBuf[0] = 0;
}
Expand Down
2 changes: 1 addition & 1 deletion src/engine/shared/console.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ class CConsole : public IConsole
const char *GetString(unsigned Index) const override;
int GetInteger(unsigned Index) const override;
float GetFloat(unsigned Index) const override;
ColorHSLA GetColor(unsigned Index, bool Light) const override;
ColorHSLA GetColor(unsigned Index, float DarkestLighting) const override;

void RemoveArgument(unsigned Index) override
{
Expand Down
1 change: 1 addition & 0 deletions src/engine/shared/protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ enum

MAX_NAME_LENGTH = 16,
MAX_CLAN_LENGTH = 12,
MAX_SKIN_LENGTH = 24,

// message packing
MSGFLAG_VITAL = 1,
Expand Down
67 changes: 36 additions & 31 deletions src/game/server/teeinfo.cpp
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
#include <base/color.h>
#include <base/system.h>
#include <game/generated/protocol7.h>

#include "teeinfo.h"

struct StdSkin
{
char m_aSkinName[64];
char m_aSkinName[24];
// body, marking, decoration, hands, feet, eyes
char m_apSkinPartNames[6][24];
bool m_aUseCustomColors[6];
int m_aSkinPartColors[6];
char m_apSkinPartNames[protocol7::NUM_SKINPARTS][24];
bool m_aUseCustomColors[protocol7::NUM_SKINPARTS];
int m_aSkinPartColors[protocol7::NUM_SKINPARTS];
};

static StdSkin g_aStdSkins[] = {
{"default", {"standard", "", "", "standard", "standard", "standard"}, {true, false, false, true, true, false}, {1798004, 0, 0, 1799582, 1869630, 0}},
{"bluekitty", {"kitty", "whisker", "", "standard", "standard", "standard"}, {true, true, false, true, true, false}, {8681144, -8229413, 0, 7885547, 7885547, 0}},
{"bluekitty", {"kitty", "whisker", "", "standard", "standard", "negative"}, {true, true, false, true, true, true}, {8681144, -8229413, 0, 7885547, 8868585, 9043712}},
{"bluestripe", {"standard", "stripes", "", "standard", "standard", "standard"}, {true, false, false, true, true, false}, {10187898, 0, 0, 750848, 1944919, 0}},
{"brownbear", {"bear", "bear", "hair", "standard", "standard", "standard"}, {true, true, false, true, true, false}, {1082745, -15634776, 0, 1082745, 1147174, 0}},
{"cammo", {"standard", "cammo2", "", "standard", "standard", "standard"}, {true, true, false, true, true, false}, {5334342, -11771603, 0, 750848, 1944919, 0}},
{"cammostripes", {"standard", "cammostripes", "", "standard", "standard", "standard"}, {true, true, false, true, true, false}, {5334342, -14840320, 0, 750848, 1944919, 0}},
{"coala", {"koala", "twinbelly", "", "standard", "standard", "standard"}, {true, true, false, true, true, false}, {184, -15397662, 0, 184, 9765959, 0}},
{"limekitty", {"kitty", "whisker", "", "standard", "standard", "standard"}, {true, true, false, true, true, false}, {4612803, -12229920, 0, 3827951, 3827951, 0}},
{"limekitty", {"kitty", "whisker", "", "standard", "standard", "negative"}, {true, true, false, true, true, true}, {4612803, -12229920, 0, 3827951, 3827951, 8256000}},
{"pinky", {"standard", "whisker", "", "standard", "standard", "standard"}, {true, true, false, true, true, false}, {15911355, -801066, 0, 15043034, 15043034, 0}},
{"redbopp", {"standard", "donny", "unibop", "standard", "standard", "standard"}, {true, true, true, true, true, false}, {16177260, -16590390, 16177260, 16177260, 7624169, 0}},
{"redstripe", {"standard", "stripe", "", "standard", "standard", "standard"}, {true, false, false, true, true, false}, {16307835, 0, 0, 184, 9765959, 0}},
Expand All @@ -38,9 +39,9 @@ CTeeInfo::CTeeInfo(const char *pSkinName, int UseCustomColor, int ColorBody, int
m_ColorFeet = ColorFeet;
}

CTeeInfo::CTeeInfo(const char *apSkinPartNames[6], const int *pUseCustomColors, const int *pSkinPartColors)
CTeeInfo::CTeeInfo(const char *apSkinPartNames[protocol7::NUM_SKINPARTS], const int *pUseCustomColors, const int *pSkinPartColors)
{
for(int i = 0; i < 6; i++)
for(int i = 0; i < protocol7::NUM_SKINPARTS; i++)
{
str_copy(m_apSkinPartNames[i], apSkinPartNames[i], sizeof(m_apSkinPartNames[i]));
m_aUseCustomColors[i] = pUseCustomColors[i];
Expand All @@ -51,7 +52,7 @@ CTeeInfo::CTeeInfo(const char *apSkinPartNames[6], const int *pUseCustomColors,
void CTeeInfo::ToSixup()
{
// reset to default skin
for(int p = 0; p < 6; p++)
for(int p = 0; p < protocol7::NUM_SKINPARTS; p++)
{
str_copy(m_apSkinPartNames[p], g_aStdSkins[0].m_apSkinPartNames[p], 24);
m_aUseCustomColors[p] = g_aStdSkins[0].m_aUseCustomColors[p];
Expand All @@ -63,7 +64,7 @@ void CTeeInfo::ToSixup()
{
if(!str_comp(m_aSkinName, StdSkin.m_aSkinName))
{
for(int p = 0; p < 6; p++)
for(int p = 0; p < protocol7::NUM_SKINPARTS; p++)
{
str_copy(m_apSkinPartNames[p], StdSkin.m_apSkinPartNames[p], 24);
m_aUseCustomColors[p] = StdSkin.m_aUseCustomColors[p];
Expand All @@ -75,18 +76,18 @@ void CTeeInfo::ToSixup()

if(m_UseCustomColor)
{
int ColorBody = ColorHSLA(m_ColorBody).UnclampLighting().Pack(ms_DarkestLGT7);
int ColorFeet = ColorHSLA(m_ColorFeet).UnclampLighting().Pack(ms_DarkestLGT7);
m_aUseCustomColors[0] = true;
m_aUseCustomColors[1] = true;
m_aUseCustomColors[2] = true;
m_aUseCustomColors[3] = true;
m_aUseCustomColors[4] = true;
m_aSkinPartColors[0] = ColorBody;
m_aSkinPartColors[1] = 0x22FFFFFF;
m_aSkinPartColors[2] = ColorBody;
m_aSkinPartColors[3] = ColorBody;
m_aSkinPartColors[4] = ColorFeet;
int ColorBody = ColorHSLA(m_ColorBody).UnclampLighting(ColorHSLA::DARKEST_LGT).Pack(ColorHSLA::DARKEST_LGT7);
int ColorFeet = ColorHSLA(m_ColorFeet).UnclampLighting(ColorHSLA::DARKEST_LGT).Pack(ColorHSLA::DARKEST_LGT7);
m_aUseCustomColors[protocol7::SKINPART_BODY] = true;
m_aUseCustomColors[protocol7::SKINPART_MARKING] = true;
m_aUseCustomColors[protocol7::SKINPART_DECORATION] = true;
m_aUseCustomColors[protocol7::SKINPART_HANDS] = true;
m_aUseCustomColors[protocol7::SKINPART_FEET] = true;
m_aSkinPartColors[protocol7::SKINPART_BODY] = ColorBody;
m_aSkinPartColors[protocol7::SKINPART_MARKING] = 0x22FFFFFF;
m_aSkinPartColors[protocol7::SKINPART_DECORATION] = ColorBody;
m_aSkinPartColors[protocol7::SKINPART_HANDS] = ColorBody;
m_aSkinPartColors[protocol7::SKINPART_FEET] = ColorFeet;
}
}

Expand All @@ -102,7 +103,7 @@ void CTeeInfo::FromSixup()
for(auto &StdSkin : g_aStdSkins)
{
bool match = true;
for(int p = 0; p < 6; p++)
for(int p = 0; p < protocol7::NUM_SKINPARTS; p++)
{
if(str_comp(m_apSkinPartNames[p], StdSkin.m_apSkinPartNames[p]) || m_aUseCustomColors[p] != StdSkin.m_aUseCustomColors[p] || (m_aUseCustomColors[p] && m_aSkinPartColors[p] != StdSkin.m_aSkinPartColors[p]))
{
Expand All @@ -118,24 +119,28 @@ void CTeeInfo::FromSixup()
}

// find closest match
int best_skin = 0;
int best_matches = -1;
int BestSkin = 0;
int BestMatches = -1;
for(int s = 0; s < 16; s++)
{
int matches = 0;
for(int p = 0; p < 3; p++)
if(str_comp(m_apSkinPartNames[p], g_aStdSkins[s].m_apSkinPartNames[p]) == 0)
matches++;

if(matches > best_matches)
if(matches > BestMatches)
{
best_matches = matches;
best_skin = s;
BestMatches = matches;
BestSkin = s;
}
}

str_copy(m_aSkinName, g_aStdSkins[best_skin].m_aSkinName, sizeof(m_aSkinName));
str_copy(m_aSkinName, g_aStdSkins[BestSkin].m_aSkinName, sizeof(m_aSkinName));
m_UseCustomColor = true;
m_ColorBody = ColorHSLA(m_aUseCustomColors[0] ? m_aSkinPartColors[0] : 255).UnclampLighting(ms_DarkestLGT7).Pack(ColorHSLA::DARKEST_LGT);
m_ColorFeet = ColorHSLA(m_aUseCustomColors[4] ? m_aSkinPartColors[4] : 255).UnclampLighting(ms_DarkestLGT7).Pack(ColorHSLA::DARKEST_LGT);
m_ColorBody = ColorHSLA(m_aUseCustomColors[protocol7::SKINPART_BODY] ? m_aSkinPartColors[protocol7::SKINPART_BODY] : 255)
.UnclampLighting(ColorHSLA::DARKEST_LGT7)
.Pack(ColorHSLA::DARKEST_LGT);
m_ColorFeet = ColorHSLA(m_aUseCustomColors[protocol7::SKINPART_FEET] ? m_aSkinPartColors[protocol7::SKINPART_FEET] : 255)
.UnclampLighting(ColorHSLA::DARKEST_LGT7)
.Pack(ColorHSLA::DARKEST_LGT);
}
6 changes: 3 additions & 3 deletions src/game/server/teeinfo.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
#ifndef GAME_SERVER_TEEINFO_H
#define GAME_SERVER_TEEINFO_H

#include <engine/shared/protocol.h>

class CTeeInfo
{
public:
constexpr static const float ms_DarkestLGT7 = 61 / 255.0f;

char m_aSkinName[64] = {'\0'};
char m_aSkinName[MAX_SKIN_LENGTH] = "";
int m_UseCustomColor = 0;
int m_ColorBody = 0;
int m_ColorFeet = 0;
Expand Down

0 comments on commit febebaf

Please sign in to comment.