1654: Try working on colors a bit r=def- a=Learath2

There were color functions everywhere, I tried cleaning it up a little. I still couldn't get the roundtrip from Hsl to Rgb to be exactly the same, but I think this is the best possible.

1685: Work on compound binds r=def- a=Learath2

Closes #1417 

Co-authored-by: Learath <learath2@gmail.com>
This commit is contained in:
bors[bot] 2019-04-29 15:56:16 +00:00
commit d8964ceedb
25 changed files with 538 additions and 342 deletions

View file

@ -1195,6 +1195,7 @@ add_custom_target(everything DEPENDS ${TARGETS_OWN})
if(GTEST_FOUND OR DOWNLOAD_GTEST)
set_glob(TESTS GLOB src/test
aio.cpp
color.cpp
datafile.cpp
fs.cpp
git_revision.cpp

View file

@ -25,24 +25,22 @@ inline float HueToRgb(float v1, float v2, float h)
inline float RgbToHue(vec3 rgb)
{
float h_min = min(min(rgb.r, rgb.g), rgb.b);
float h_max = max(max(rgb.r, rgb.g), rgb.b);
float h_min = min(rgb.r, rgb.g, rgb.b);
float h_max = max(rgb.r, rgb.g, rgb.b);
float hue = 0.0f;
if(h_max != h_min)
{
float c = h_max - h_min;
if(h_max == rgb.r)
hue = (rgb.g - rgb.b) / c + (rgb.g < rgb.b ? 6 : 0);
else if(h_max == rgb.g)
hue = (rgb.b - rgb.r) / c + 2;
else
hue = (rgb.r - rgb.g) / c + 4;
}
if(h_max == rgb.r)
hue = (rgb.g-rgb.b) / (h_max-h_min);
else if(h_max == rgb.g)
hue = 2.0f + (rgb.b-rgb.r) / (h_max-h_min);
else
hue = 4.0f + (rgb.r-rgb.g) / (h_max-h_min);
hue /= 6.0f;
if(hue < 0.0f)
hue += 1.0f;
return hue;
return hue / 6.0f;
}
/*
@ -51,15 +49,35 @@ inline float RgbToHue(vec3 rgb)
*/
inline vec3 HslToRgb(vec3 HSL)
{
if(HSL.s == 0.0f)
return vec3(HSL.l, HSL.l, HSL.l);
else
{
float v2 = HSL.l < 0.5f ? HSL.l * (1.0f + HSL.s) : (HSL.l+HSL.s) - (HSL.s*HSL.l);
float v1 = 2.0f * HSL.l - v2;
vec3 rgb = vec3(0, 0, 0);
return vec3(HueToRgb(v1, v2, HSL.h + (1.0f/3.0f)), HueToRgb(v1, v2, HSL.h), HueToRgb(v1, v2, HSL.h - (1.0f/3.0f)));
float h1 = HSL.h * 6;
float c = (1 - absolute(2 * HSL.l - 1)) * HSL.s;
float x = c * (1 - absolute(fmod(h1, 2) - 1));
switch(round_truncate(h1)) {
case 0:
rgb.r = c, rgb.g = x;
break;
case 1:
rgb.r = x, rgb.g = c;
break;
case 2:
rgb.g = c, rgb.b = x;
break;
case 3:
rgb.g = x, rgb.b = c;
break;
case 4:
rgb.r = x, rgb.b = c;
break;
case 5:
rgb.r = c, rgb.b = x;
break;
}
float m = HSL.l - (c/2);
return vec3(rgb.r + m, rgb.g + m, rgb.b + m);
}
inline vec3 HsvToRgb(vec3 hsv)
@ -147,6 +165,19 @@ inline vec3 RgbToHsv(vec3 rgb)
return vec3(hue, s, l);
}
inline vec3 RgbToHsl(vec3 rgb)
{
float Min = min(rgb.r, rgb.g, rgb.b);
float Max = max(rgb.r, rgb.g, rgb.b);
float c = Max - Min;
float h = RgbToHue(rgb);
float l = 0.5f * (Max + Min);
float s = (Max != 0.0f && Min != 1.0f) ? (c/(1 - (absolute(2 * l - 1)))) : 0;
return vec3(h, s, l);
}
/*
Function: HexToRgba
Converts Hex to Rgba
@ -164,4 +195,14 @@ inline vec4 HexToRgba(int hex)
return c;
}
inline vec3 UnpackColor(int v)
{
return vec3(fmod(((v>>16)&0xff)/255.0f, 1.0f), ((v>>8)&0xff)/255.0f, 0.5f+(v&0xff)/255.0f*0.5f);
}
inline vec4 Color3to4(vec3 col)
{
return vec4(col[0], col[1], col[2], 1.0f);
}
#endif

View file

@ -27,6 +27,11 @@ inline int round_to_int(float f)
return (int)(f-0.5f);
}
inline int round_truncate(float f)
{
return (int)f;
}
template<typename T, typename TB>
inline T mix(const T a, const T b, TB amount)
{
@ -64,7 +69,9 @@ public:
const float pi = 3.1415926535897932384626433f;
template <typename T> inline T min(T a, T b) { return a<b?a:b; }
template <typename T> inline T min(T a, T b, T c) { return min(min(a, b), c); }
template <typename T> inline T max(T a, T b) { return a>b?a:b; }
template <typename T> inline T max(T a, T b, T c) { return max(max(a, b), c); }
template <typename T> inline T absolute(T a) { return a<T(0)?-a:a; }
template <typename T> inline T in_range(T a, T lower, T upper) { return lower <= a && a <= upper; }

View file

@ -1072,11 +1072,6 @@ void CClient::Render()
}
}
vec3 CClient::GetColorV3(int v)
{
return HslToRgb(vec3(((v>>16)&0xff)/255.0f, ((v>>8)&0xff)/255.0f, 0.5f+(v&0xff)/255.0f*0.5f));
}
const char *CClient::LoadMap(const char *pName, const char *pFilename, SHA256_DIGEST *pWantedSha256, unsigned WantedCrc)
{
static char s_aErrorMsg[128];

View file

@ -209,7 +209,6 @@ class CClient : public IClient, public CDemoPlayer::IListener
volatile int m_GfxState;
static void GraphicsThreadProxy(void *pThis) { ((CClient*)pThis)->GraphicsThread(); }
void GraphicsThread();
vec3 GetColorV3(int v);
#if defined(CONF_FAMILY_UNIX)
CFifo m_Fifo;
@ -361,7 +360,7 @@ public:
static void ConchainWindowVSync(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
static void ConchainTimeoutSeed(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
static void ConchainPassword(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
static void Con_DemoSlice(IConsole::IResult *pResult, void *pUserData);
static void Con_DemoSliceBegin(IConsole::IResult *pResult, void *pUserData);
static void Con_DemoSliceEnd(IConsole::IResult *pResult, void *pUserData);

View file

@ -6,15 +6,19 @@
bool CBinds::CBindsSpecial::OnInput(IInput::CEvent Event)
{
// don't handle invalid events and keys that aren't set to anything
if(((Event.m_Key >= KEY_F1 && Event.m_Key <= KEY_F12) || (Event.m_Key >= KEY_F13 && Event.m_Key <= KEY_F24)) && m_pBinds->m_apKeyBindings[Event.m_Key])
// only handle F and composed F binds
if((Event.m_Key >= KEY_F1 && Event.m_Key <= KEY_F12) || (Event.m_Key >= KEY_F13 && Event.m_Key <= KEY_F24))
{
int Stroke = 0;
if(Event.m_Flags&IInput::FLAG_PRESS)
Stroke = 1;
int Mask = m_pBinds->GetModifierMask(Input());
m_pBinds->GetConsole()->ExecuteLineStroked(Stroke, m_pBinds->m_apKeyBindings[Event.m_Key]);
return true;
bool ret = false;
for(int Mod = 0; Mod < MODIFIER_COUNT; Mod++)
{
if(Mask&(1 << Mod) && m_pBinds->m_aapKeyBindings[Mod][Event.m_Key])
m_pBinds->GetConsole()->ExecuteLineStroked(Event.m_Flags&IInput::FLAG_PRESS, m_pBinds->m_aapKeyBindings[Mod][Event.m_Key]);
ret = true;
}
return ret;
}
return false;
@ -22,31 +26,36 @@ bool CBinds::CBindsSpecial::OnInput(IInput::CEvent Event)
CBinds::CBinds()
{
mem_zero(m_apKeyBindings, sizeof(m_apKeyBindings));
mem_zero(m_aapKeyBindings, sizeof(m_aapKeyBindings));
m_SpecialBinds.m_pBinds = this;
}
CBinds::~CBinds()
{
for(int i = 0; i < KEY_LAST; i++)
if(m_apKeyBindings[i])
free(m_apKeyBindings[i]);
for(int j = 0; j < MODIFIER_COUNT; j++)
if(m_aapKeyBindings[j][i])
free(m_aapKeyBindings[j][i]);
}
void CBinds::Bind(int KeyID, const char *pStr, bool FreeOnly)
void CBinds::Bind(int KeyID, const char *pStr, bool FreeOnly, int Modifier)
{
if(KeyID < 0 || KeyID >= KEY_LAST)
return;
if(FreeOnly && Get(KeyID)[0])
if(FreeOnly && Get(KeyID, Modifier)[0])
return;
if(m_apKeyBindings[KeyID])
if(m_aapKeyBindings[Modifier][KeyID])
{
free(m_apKeyBindings[KeyID]);
m_apKeyBindings[KeyID] = 0;
free(m_aapKeyBindings[Modifier][KeyID]);
m_aapKeyBindings[Modifier][KeyID] = 0;
}
// skip modifiers for +xxx binds
if(pStr[0] == '+')
Modifier = 0;
char aBuf[256];
if(!pStr[0])
{
@ -55,56 +64,134 @@ void CBinds::Bind(int KeyID, const char *pStr, bool FreeOnly)
else
{
int Size = str_length(pStr) + 1;
m_apKeyBindings[KeyID] = (char *)malloc(Size);
str_copy(m_apKeyBindings[KeyID], pStr, Size);
str_format(aBuf, sizeof(aBuf), "bound %s (%d) = %s", Input()->KeyName(KeyID), KeyID, m_apKeyBindings[KeyID]);
m_aapKeyBindings[Modifier][KeyID] = (char *)malloc(Size);
str_copy(m_aapKeyBindings[Modifier][KeyID], pStr, Size);
if(Modifier)
str_format(aBuf, sizeof(aBuf), "bound %s+%s (%d) = %s", GetModifierName(Modifier), Input()->KeyName(KeyID), KeyID, m_aapKeyBindings[Modifier][KeyID]);
else
str_format(aBuf, sizeof(aBuf), "bound %s (%d) = %s", Input()->KeyName(KeyID), KeyID, m_aapKeyBindings[Modifier][KeyID]);
}
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "binds", aBuf);
}
int CBinds::GetModifierMask(IInput *i)
{
int Mask = 0;
Mask |= i->KeyIsPressed(KEY_LSHIFT) << CBinds::MODIFIER_SHIFT;
Mask |= i->KeyIsPressed(KEY_RSHIFT) << CBinds::MODIFIER_SHIFT;
Mask |= i->KeyIsPressed(KEY_LCTRL) << CBinds::MODIFIER_CTRL;
Mask |= i->KeyIsPressed(KEY_RCTRL) << CBinds::MODIFIER_CTRL;
Mask |= i->KeyIsPressed(KEY_LALT) << CBinds::MODIFIER_ALT;
if(!Mask)
return 1 << CBinds::MODIFIER_NONE;
return Mask;
}
int CBinds::GetModifierMaskOfKey(int Key)
{
switch(Key)
{
case KEY_LSHIFT:
case KEY_RSHIFT:
return 1 << CBinds::MODIFIER_SHIFT;
case KEY_LCTRL:
case KEY_RCTRL:
return 1 << CBinds::MODIFIER_CTRL;
case KEY_LALT:
return 1 << CBinds::MODIFIER_ALT;
default:
return 0;
}
}
bool CBinds::ModifierMatchesKey(int Modifier, int Key)
{
switch(Modifier)
{
case MODIFIER_SHIFT:
return Key == KEY_LSHIFT || Key == KEY_RSHIFT;
case MODIFIER_CTRL:
return Key == KEY_LCTRL || Key == KEY_RCTRL;
case MODIFIER_ALT:
return Key == KEY_LALT;
case MODIFIER_NONE:
default:
return false;
}
}
bool CBinds::OnInput(IInput::CEvent e)
{
// don't handle invalid events and keys that aren't set to anything
if(e.m_Key <= 0 || e.m_Key >= KEY_LAST || !m_apKeyBindings[e.m_Key])
// don't handle invalid events
if(e.m_Key <= 0 || e.m_Key >= KEY_LAST)
return false;
if(e.m_Flags&IInput::FLAG_PRESS)
Console()->ExecuteLineStroked(1, m_apKeyBindings[e.m_Key]);
if(e.m_Flags&IInput::FLAG_RELEASE)
Console()->ExecuteLineStroked(0, m_apKeyBindings[e.m_Key]);
return true;
int Mask = GetModifierMask(Input());
int KeyModifierMask = GetModifierMaskOfKey(e.m_Key);
Mask &= ~KeyModifierMask;
if(!Mask)
Mask = 1 << MODIFIER_NONE;
if(Mask == ((1 << MODIFIER_CTRL) | (1 << MODIFIER_SHIFT)))
return true;
bool ret = false;
for(int Mod = 0; Mod < MODIFIER_COUNT; Mod++)
{
if(m_aapKeyBindings[Mod][e.m_Key] && (((Mask&(1 << Mod)) || (Mod == 0 && m_aapKeyBindings[0][e.m_Key][0] == '+')))) // always trigger +xxx binds despite any modifier
{
if(e.m_Flags&IInput::FLAG_PRESS)
Console()->ExecuteLineStroked(1, m_aapKeyBindings[Mod][e.m_Key]);
if(e.m_Flags&IInput::FLAG_RELEASE)
Console()->ExecuteLineStroked(0, m_aapKeyBindings[Mod][e.m_Key]);
ret = true;
}
}
return ret;
}
void CBinds::UnbindAll()
{
for(int i = 0; i < KEY_LAST; i++)
for(int i = 0; i < MODIFIER_COUNT; i++)
{
if(m_apKeyBindings[i])
free(m_apKeyBindings[i]);
m_apKeyBindings[i] = 0;
for(int j = 0; j < KEY_LAST; j++)
{
if(m_aapKeyBindings[i][j])
free(m_aapKeyBindings[i][j]);
m_aapKeyBindings[i][j] = 0;
}
}
}
const char *CBinds::Get(int KeyID)
const char *CBinds::Get(int KeyID, int Modifier)
{
if(KeyID > 0 && KeyID < KEY_LAST && m_apKeyBindings[KeyID])
return m_apKeyBindings[KeyID];
if(KeyID > 0 && KeyID < KEY_LAST && m_aapKeyBindings[Modifier][KeyID])
return m_aapKeyBindings[Modifier][KeyID];
return "";
}
const char *CBinds::GetKey(const char *pBindStr)
void CBinds::GetKey(const char *pBindStr, char *aBuf, unsigned BufSize)
{
for(int KeyId = 0; KeyId < KEY_LAST; KeyId++)
aBuf[0] = 0;
for(int Mod = 0; Mod < MODIFIER_COUNT; Mod++)
{
const char *pBind = Get(KeyId);
if(!pBind[0])
continue;
for(int KeyId = 0; KeyId < KEY_LAST; KeyId++)
{
const char *pBind = Get(KeyId, Mod);
if(!pBind[0])
continue;
if(str_comp(pBind, pBindStr) == 0)
return Input()->KeyName(KeyId);
if(str_comp(pBind, pBindStr) == 0){
if(Mod)
str_format(aBuf, BufSize, "%s+%s", GetModifierName(Mod), Input()->KeyName(KeyId));
else
str_format(aBuf, BufSize, "%s", Input()->KeyName(KeyId));
return;
}
}
}
return "";
}
void CBinds::SetDefaults()
@ -175,18 +262,19 @@ void CBinds::OnConsoleInit()
void CBinds::ConBind(IConsole::IResult *pResult, void *pUserData)
{
CBinds *pBinds = (CBinds *)pUserData;
const char *pKeyName = pResult->GetString(0);
int id = pBinds->GetKeyID(pKeyName);
const char *pBindStr = pResult->GetString(0);
int Modifier;
int KeyID = pBinds->GetBindSlot(pBindStr, &Modifier);
if(!id)
if(!KeyID)
{
char aBuf[256];
str_format(aBuf, sizeof(aBuf), "key %s not found", pKeyName);
str_format(aBuf, sizeof(aBuf), "key %s not found", pBindStr);
pBinds->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "binds", aBuf);
return;
}
pBinds->Bind(id, pResult->GetString(1));
pBinds->Bind(KeyID, pResult->GetString(1), false, Modifier);
}
void CBinds::ConDumpBinds(IConsole::IResult *pResult, void *pUserData)
@ -197,7 +285,8 @@ void CBinds::ConDumpBinds(IConsole::IResult *pResult, void *pUserData)
char aBuf[256];
const char *pKeyName = pResult->GetString(0);
int id = pBinds->GetKeyID(pKeyName);
int Modifier;
int id = pBinds->GetBindSlot(pKeyName, &Modifier);
if (!id)
{
str_format(aBuf, sizeof(aBuf), "key '%s' not found", pKeyName);
@ -205,10 +294,10 @@ void CBinds::ConDumpBinds(IConsole::IResult *pResult, void *pUserData)
}
else
{
if (!pBinds->m_apKeyBindings[id])
if (!pBinds->m_aapKeyBindings[Modifier][id])
str_format(aBuf, sizeof(aBuf), "%s (%d) is not bound", pKeyName, id);
else
str_format(aBuf, sizeof(aBuf), "%s (%d) = %s", pKeyName, id, pBinds->m_apKeyBindings[id]);
str_format(aBuf, sizeof(aBuf), "%s (%d) = %s", pKeyName, id, pBinds->m_aapKeyBindings[Modifier][id]);
pBinds->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "binds", aBuf);
}
@ -216,12 +305,18 @@ void CBinds::ConDumpBinds(IConsole::IResult *pResult, void *pUserData)
else if(pResult->NumArguments() == 0)
{
char aBuf[1024];
for(int i = 0; i < KEY_LAST; i++)
for(int i = 0; i < MODIFIER_COUNT; i++)
{
if(!pBinds->m_apKeyBindings[i])
continue;
str_format(aBuf, sizeof(aBuf), "%s (%d) = %s", pBinds->Input()->KeyName(i), i, pBinds->m_apKeyBindings[i]);
pBinds->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "binds", aBuf);
for(int j = 0; j < KEY_LAST; j++)
{
if(!pBinds->m_aapKeyBindings[i][j])
continue;
if(i)
str_format(aBuf, sizeof(aBuf), "%s+%s (%d) = %s", pBinds->GetModifierName(i), pBinds->Input()->KeyName(j), j, pBinds->m_aapKeyBindings[i][j]);
else
str_format(aBuf, sizeof(aBuf), "%s (%d) = %s", pBinds->Input()->KeyName(j), j, pBinds->m_aapKeyBindings[i][j]);
pBinds->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "binds", aBuf);
}
}
}
}
@ -230,7 +325,8 @@ void CBinds::ConUnbind(IConsole::IResult *pResult, void *pUserData)
{
CBinds *pBinds = (CBinds *)pUserData;
const char *pKeyName = pResult->GetString(0);
int id = pBinds->GetKeyID(pKeyName);
int Modifier;
int id = pBinds->GetBindSlot(pKeyName, &Modifier);
if(!id)
{
@ -240,7 +336,7 @@ void CBinds::ConUnbind(IConsole::IResult *pResult, void *pUserData)
return;
}
pBinds->Bind(id, "");
pBinds->Bind(id, "", false, Modifier);
}
void CBinds::ConUnbindAll(IConsole::IResult *pResult, void *pUserData)
@ -269,6 +365,42 @@ int CBinds::GetKeyID(const char *pKeyName)
return 0;
}
int CBinds::GetBindSlot(const char *pBindString, int *Mod)
{
*Mod = MODIFIER_NONE;
char aMod[32] = { 0 };
const char *pKey = str_next_token(pBindString, "+", aMod, sizeof(aMod));
if(aMod[0] && *(pKey))
{
if(!str_comp(aMod, "shift"))
*Mod = MODIFIER_SHIFT;
else if(!str_comp(aMod, "ctrl"))
*Mod = MODIFIER_CTRL;
else if(!str_comp(aMod, "alt"))
*Mod = MODIFIER_ALT;
else
return 0;
}
return GetKeyID(*Mod == MODIFIER_NONE ? aMod : pKey + 1);
}
const char *CBinds::GetModifierName(int Modifier)
{
switch(Modifier)
{
case MODIFIER_SHIFT:
return "shift";
case MODIFIER_CTRL:
return "ctrl";
case MODIFIER_ALT:
return "alt";
case MODIFIER_NONE:
default:
return "";
}
}
void CBinds::ConfigSaveCallback(IConfig *pConfig, void *pUserData)
{
CBinds *pSelf = (CBinds *)pUserData;
@ -276,18 +408,24 @@ void CBinds::ConfigSaveCallback(IConfig *pConfig, void *pUserData)
char aBuffer[256];
char *pEnd = aBuffer+sizeof(aBuffer);
pConfig->WriteLine("unbindall");
for(int i = 0; i < KEY_LAST; i++)
for(int i = 0; i < MODIFIER_COUNT; i++)
{
if(!pSelf->m_apKeyBindings[i])
continue;
str_format(aBuffer, sizeof(aBuffer), "bind %s \"", pSelf->Input()->KeyName(i));
for(int j = 0; j < KEY_LAST; j++)
{
if(!pSelf->m_aapKeyBindings[i][j])
continue;
if(i)
str_format(aBuffer, sizeof(aBuffer), "bind %s+%s \"", pSelf->GetModifierName(i), pSelf->Input()->KeyName(j));
else
str_format(aBuffer, sizeof(aBuffer), "bind %s \"", pSelf->Input()->KeyName(j));
// process the string. we need to escape some characters
char *pDst = aBuffer + str_length(aBuffer);
str_escape(&pDst, pSelf->m_apKeyBindings[i], pEnd);
str_append(aBuffer, "\"", sizeof(aBuffer));
// process the string. we need to escape some characters
char *pDst = aBuffer + str_length(aBuffer);
str_escape(&pDst, pSelf->m_aapKeyBindings[i][j], pEnd);
str_append(aBuffer, "\"", sizeof(aBuffer));
pConfig->WriteLine(aBuffer);
pConfig->WriteLine(aBuffer);
}
}
}

View file

@ -7,8 +7,6 @@
class CBinds : public CComponent
{
char *m_apKeyBindings[KEY_LAST];
int GetKeyID(const char *pKeyName);
static void ConBind(IConsole::IResult *pResult, void *pUserData);
@ -30,13 +28,26 @@ public:
virtual bool OnInput(IInput::CEvent Event);
};
enum {
MODIFIER_NONE=0,
MODIFIER_SHIFT,
MODIFIER_CTRL,
MODIFIER_ALT,
MODIFIER_COUNT
};
CBindsSpecial m_SpecialBinds;
void Bind(int KeyID, const char *pStr, bool FreeOnly = false);
void Bind(int KeyID, const char *pStr, bool FreeOnly = false, int Modifier = MODIFIER_NONE);
void SetDefaults();
void UnbindAll();
const char *Get(int KeyID);
const char *GetKey(const char *pBindStr);
const char *Get(int KeyID, int Modifier);
void GetKey(const char *pBindStr, char *aBuf, unsigned BufSize);
int GetBindSlot(const char *pBindString, int *Modifier);
static int GetModifierMask(IInput *i);
static int GetModifierMaskOfKey(int Key);
static bool ModifierMatchesKey(int Modifier, int Key);
static const char *GetModifierName(int Modifier);
virtual void OnConsoleInit();
virtual bool OnInput(IInput::CEvent Event);
@ -44,5 +55,8 @@ public:
// DDRace
void SetDDRaceBinds(bool FreeOnly);
private:
char *m_aapKeyBindings[MODIFIER_COUNT][KEY_LAST];
};
#endif

View file

@ -167,7 +167,7 @@ void CEffects::PlayerDeath(vec2 Pos, int ClientID)
if(ClientID >= 0)
{
if(m_pClient->m_aClients[ClientID].m_UseCustomColor)
BloodColor = m_pClient->m_pSkins->GetColorV3(m_pClient->m_aClients[ClientID].m_ColorBody);
BloodColor = HslToRgb(UnpackColor(m_pClient->m_aClients[ClientID].m_ColorBody));
else
{
const CSkins::CSkin *s = m_pClient->m_pSkins->Get(m_pClient->m_aClients[ClientID].m_SkinID);

View file

@ -361,18 +361,16 @@ void CGhost::InitRenderInfos(CGhostItem *pGhost)
if(pGhost->m_Skin.m_UseCustomColor)
{
pRenderInfo->m_Texture = m_pClient->m_pSkins->Get(SkinId)->m_ColorTexture;
pRenderInfo->m_ColorBody = m_pClient->m_pSkins->GetColorV4(pGhost->m_Skin.m_ColorBody);
pRenderInfo->m_ColorFeet = m_pClient->m_pSkins->GetColorV4(pGhost->m_Skin.m_ColorFeet);
pRenderInfo->m_ColorBody = HslToRgb(UnpackColor(pGhost->m_Skin.m_ColorBody));
pRenderInfo->m_ColorFeet = HslToRgb(UnpackColor(pGhost->m_Skin.m_ColorFeet));
}
else
{
pRenderInfo->m_Texture = m_pClient->m_pSkins->Get(SkinId)->m_OrgTexture;
pRenderInfo->m_ColorBody = vec4(1, 1, 1, 1);
pRenderInfo->m_ColorFeet = vec4(1, 1, 1, 1);
pRenderInfo->m_ColorBody = vec3(1, 1, 1);
pRenderInfo->m_ColorFeet = vec3(1, 1, 1);
}
pRenderInfo->m_ColorBody.a = 0.5f;
pRenderInfo->m_ColorFeet.a = 0.5f;
pRenderInfo->m_Size = 64;
}

View file

@ -640,14 +640,16 @@ void CHud::RenderVoting()
CUIRect Base = {5, 88, 100, 4};
m_pClient->m_pVoting->RenderBars(Base, false);
const char *pYesKey = m_pClient->m_pBinds->GetKey("vote yes");
const char *pNoKey = m_pClient->m_pBinds->GetKey("vote no");
str_format(aBuf, sizeof(aBuf), "%s - %s", pYesKey, Localize("Vote yes"));
char aKey[64];
m_pClient->m_pBinds->GetKey("vote yes", aKey, sizeof(aKey));
str_format(aBuf, sizeof(aBuf), "%s - %s", aKey, Localize("Vote yes"));
Base.y += Base.h;
Base.h = 11.f;
UI()->DoLabel(&Base, aBuf, 6.0f, -1);
str_format(aBuf, sizeof(aBuf), "%s - %s", Localize("Vote no"), pNoKey);
m_pClient->m_pBinds->GetKey("vote no", aKey, sizeof(aKey));
str_format(aBuf, sizeof(aBuf), "%s - %s", Localize("Vote no"), aKey);
UI()->DoLabel(&Base, aBuf, 6.0f, 1);
}

View file

@ -26,6 +26,7 @@
#include <game/generated/protocol.h>
#include <game/generated/client_data.h>
#include <game/client/components/binds.h>
#include <game/client/components/sounds.h>
#include <game/client/gameclient.h>
#include <game/client/lineinput.h>
@ -579,7 +580,7 @@ float CMenus::DoScrollbarH(const void *pID, const CUIRect *pRect, float Current)
return ReturnValue;
}
int CMenus::DoKeyReader(void *pID, const CUIRect *pRect, int Key)
int CMenus::DoKeyReader(void *pID, const CUIRect *pRect, int Key, int Modifier, int *NewModifier)
{
// process
static void *pGrabbedID = 0;
@ -587,6 +588,7 @@ int CMenus::DoKeyReader(void *pID, const CUIRect *pRect, int Key)
static int ButtonUsed = 0;
int Inside = UI()->MouseInside(pRect);
int NewKey = Key;
*NewModifier = Modifier;
if(!UI()->MouseButton(0) && !UI()->MouseButton(1) && pGrabbedID == pID)
MouseReleased = true;
@ -597,7 +599,10 @@ int CMenus::DoKeyReader(void *pID, const CUIRect *pRect, int Key)
{
// abort with escape key
if(m_Binder.m_Key.m_Key != KEY_ESCAPE)
{
NewKey = m_Binder.m_Key.m_Key;
*NewModifier = m_Binder.m_Modifier;
}
m_Binder.m_GotKey = false;
UI()->SetActiveItem(0);
MouseReleased = false;
@ -639,10 +644,18 @@ int CMenus::DoKeyReader(void *pID, const CUIRect *pRect, int Key)
DoButton_KeySelect(pID, "???", 0, pRect);
else
{
if(Key == 0)
DoButton_KeySelect(pID, "", 0, pRect);
if(Key)
{
char aBuf[64];
if(*NewModifier)
str_format(aBuf, sizeof(aBuf), "%s+%s", CBinds::GetModifierName(*NewModifier), Input()->KeyName(Key));
else
str_format(aBuf, sizeof(aBuf), "%s", Input()->KeyName(Key));
DoButton_KeySelect(pID, aBuf, 0, pRect);
}
else
DoButton_KeySelect(pID, Input()->KeyName(Key), 0, pRect);
DoButton_KeySelect(pID, "", 0, pRect);
}
return NewKey;
}
@ -799,7 +812,7 @@ int CMenus::RenderMenubar(CUIRect r)
Box.VSplitRight(10.0f, &Box, &Button);
Box.VSplitRight(33.0f, &Box, &Button);
static int s_SettingsButton=0;
if(DoButton_MenuTab(&s_SettingsButton, "\xEE\xA2\xB8", m_ActivePage==PAGE_SETTINGS, &Button, CUI::CORNER_T))
NewPage = PAGE_SETTINGS;
@ -1909,7 +1922,7 @@ void CMenus::RenderUpdating(const char *pCaption, int current, int total)
CUIRect Screen = *UI()->Screen();
Graphics()->MapScreen(Screen.x, Screen.y, Screen.w, Screen.h);
Graphics()->BlendNormal();
RenderBackground();

View file

@ -21,6 +21,7 @@ public:
bool m_TakeKey;
bool m_GotKey;
IInput::CEvent m_Key;
int m_Modifier;
CMenusKeyBinder();
virtual bool OnInput(IInput::CEvent Event);
};
@ -71,7 +72,7 @@ class CMenus : public CComponent
float DoScrollbarV(const void *pID, const CUIRect *pRect, float Current);
float DoScrollbarH(const void *pID, const CUIRect *pRect, float Current);
void DoButton_KeySelect(const void *pID, const char *pText, int Checked, const CUIRect *pRect);
int DoKeyReader(void *pID, const CUIRect *pRect, int Key);
int DoKeyReader(void *pID, const CUIRect *pRect, int Key, int Modifier, int *NewModifier);
//static int ui_do_key_reader(void *id, const CUIRect *rect, int key);
void UiDoGetButtons(int Start, int Stop, CUIRect View, CUIRect ScopeView);
@ -366,7 +367,7 @@ public:
CGhostItem() : m_Slot(-1), m_Own(false) { m_aFilename[0] = 0; }
bool operator<(const CGhostItem &Other) { return m_Time < Other.m_Time; }
bool Active() const { return m_Slot != -1; }
bool HasFile() const { return m_aFilename[0]; }
};

View file

@ -36,17 +36,29 @@ CMenusKeyBinder::CMenusKeyBinder()
{
m_TakeKey = false;
m_GotKey = false;
m_Modifier = 0;
}
bool CMenusKeyBinder::OnInput(IInput::CEvent Event)
{
if(m_TakeKey)
{
if(Event.m_Flags&IInput::FLAG_PRESS)
int TriggeringEvent = (Event.m_Key == KEY_MOUSE_1) ? IInput::FLAG_PRESS : IInput::FLAG_RELEASE;
if(Event.m_Flags&TriggeringEvent)
{
m_Key = Event;
m_GotKey = true;
m_TakeKey = false;
int Mask = CBinds::GetModifierMask(Input());
m_Modifier = 0;
while(!(Mask&1))
{
Mask >>= 1;
m_Modifier++;
}
if(CBinds::ModifierMatchesKey(m_Modifier, Event.m_Key))
m_Modifier = 0;
}
return true;
}
@ -391,14 +403,14 @@ void CMenus::RenderSettingsTee(CUIRect MainView)
if(*UseCustomColor)
{
OwnSkinInfo.m_Texture = pOwnSkin->m_ColorTexture;
OwnSkinInfo.m_ColorBody = m_pClient->m_pSkins->GetColorV4(*ColorBody);
OwnSkinInfo.m_ColorFeet = m_pClient->m_pSkins->GetColorV4(*ColorFeet);
OwnSkinInfo.m_ColorBody = HslToRgb(UnpackColor(*ColorBody));
OwnSkinInfo.m_ColorFeet = HslToRgb(UnpackColor(*ColorFeet));
}
else
{
OwnSkinInfo.m_Texture = pOwnSkin->m_OrgTexture;
OwnSkinInfo.m_ColorBody = vec4(1.0f, 1.0f, 1.0f, 1.0f);
OwnSkinInfo.m_ColorFeet = vec4(1.0f, 1.0f, 1.0f, 1.0f);
OwnSkinInfo.m_ColorBody = vec3(1.0f, 1.0f, 1.0f);
OwnSkinInfo.m_ColorFeet = vec3(1.0f, 1.0f, 1.0f);
}
OwnSkinInfo.m_Size = 50.0f*UI()->Scale();
@ -584,14 +596,14 @@ void CMenus::RenderSettingsTee(CUIRect MainView)
if(*UseCustomColor)
{
Info.m_Texture = s->m_ColorTexture;
Info.m_ColorBody = m_pClient->m_pSkins->GetColorV4(*ColorBody);
Info.m_ColorFeet = m_pClient->m_pSkins->GetColorV4(*ColorFeet);
Info.m_ColorBody = HslToRgb(UnpackColor(*ColorBody));
Info.m_ColorFeet = HslToRgb(UnpackColor(*ColorFeet));
}
else
{
Info.m_Texture = s->m_OrgTexture;
Info.m_ColorBody = vec4(1.0f, 1.0f, 1.0f, 1.0f);
Info.m_ColorFeet = vec4(1.0f, 1.0f, 1.0f, 1.0f);
Info.m_ColorBody = vec3(1.0f, 1.0f, 1.0f);
Info.m_ColorFeet = vec3(1.0f, 1.0f, 1.0f);
}
Info.m_Size = UI()->Scale()*50.0f;
@ -604,7 +616,7 @@ void CMenus::RenderSettingsTee(CUIRect MainView)
RenderTools()->UI()->DoLabelScaled(&Item.m_Rect, aBuf, 12.0f, -1,Item.m_Rect.w);
if(g_Config.m_Debug)
{
vec3 BloodColor = *UseCustomColor ? m_pClient->m_pSkins->GetColorV3(*ColorBody) : s->m_BloodColor;
vec3 BloodColor = *UseCustomColor ? HslToRgb(UnpackColor(*ColorBody)) : s->m_BloodColor;
Graphics()->TextureSet(-1);
Graphics()->QuadsBegin();
Graphics()->SetColor(BloodColor.r, BloodColor.g, BloodColor.b, 1.0f);
@ -657,57 +669,58 @@ typedef struct
CLocConstString m_Name;
const char *m_pCommand;
int m_KeyId;
int m_Modifier;
} CKeyInfo;
static CKeyInfo gs_aKeys[] =
{
{ "Move left", "+left", 0}, // Localize - these strings are localized within CLocConstString
{ "Move right", "+right", 0 },
{ "Jump", "+jump", 0 },
{ "Fire", "+fire", 0 },
{ "Hook", "+hook", 0 },
{ "Hook collisions", "+showhookcoll", 0 },
{ "Pause", "say /pause", 0 },
{ "Kill", "kill", 0 },
{ "Zoom in", "zoom+", 0 },
{ "Zoom out", "zoom-", 0 },
{ "Default zoom", "zoom", 0 },
{ "Show others", "say /showothers", 0 },
{ "Show all", "say /showall", 0 },
{ "Toggle dyncam", "toggle cl_dyncam 0 1", 0 },
{ "Toggle dummy", "toggle cl_dummy 0 1", 0 },
{ "Toggle ghost", "toggle cl_race_show_ghost 0 1", 0 },
{ "Dummy copy", "toggle cl_dummy_copy_moves 0 1", 0 },
{ "Hammerfly dummy", "toggle cl_dummy_hammer 0 1", 0 },
{ "Move left", "+left", 0, 0 }, // Localize - these strings are localized within CLocConstString
{ "Move right", "+right", 0, 0 },
{ "Jump", "+jump", 0, 0 },
{ "Fire", "+fire", 0, 0 },
{ "Hook", "+hook", 0, 0 },
{ "Hook collisions", "+showhookcoll", 0, 0 },
{ "Pause", "say /pause", 0, 0 },
{ "Kill", "kill", 0, 0 },
{ "Zoom in", "zoom+", 0, 0 },
{ "Zoom out", "zoom-", 0, 0 },
{ "Default zoom", "zoom", 0, 0 },
{ "Show others", "say /showothers", 0, 0 },
{ "Show all", "say /showall", 0, 0 },
{ "Toggle dyncam", "toggle cl_dyncam 0 1", 0, 0 },
{ "Toggle dummy", "toggle cl_dummy 0 1", 0, 0 },
{ "Toggle ghost", "toggle cl_race_show_ghost 0 1", 0, 0 },
{ "Dummy copy", "toggle cl_dummy_copy_moves 0 1", 0, 0 },
{ "Hammerfly dummy", "toggle cl_dummy_hammer 0 1", 0, 0 },
{ "Hammer", "+weapon1", 0 },
{ "Pistol", "+weapon2", 0 },
{ "Shotgun", "+weapon3", 0 },
{ "Grenade", "+weapon4", 0 },
{ "Rifle", "+weapon5", 0 },
{ "Next weapon", "+nextweapon", 0 },
{ "Prev. weapon", "+prevweapon", 0 },
{ "Hammer", "+weapon1", 0, 0 },
{ "Pistol", "+weapon2", 0, 0 },
{ "Shotgun", "+weapon3", 0, 0 },
{ "Grenade", "+weapon4", 0, 0 },
{ "Rifle", "+weapon5", 0, 0 },
{ "Next weapon", "+nextweapon", 0, 0 },
{ "Prev. weapon", "+prevweapon", 0, 0 },
{ "Vote yes", "vote yes", 0 },
{ "Vote no", "vote no", 0 },
{ "Vote yes", "vote yes", 0, 0 },
{ "Vote no", "vote no", 0, 0 },
{ "Chat", "+show_chat; chat all", 0 },
{ "Team chat", "+show_chat; chat team", 0 },
{ "Converse", "+show_chat; chat all /c ", 0 },
{ "Show chat", "+show_chat", 0 },
{ "Chat", "+show_chat; chat all", 0, 0 },
{ "Team chat", "+show_chat; chat team", 0, 0 },
{ "Converse", "+show_chat; chat all /c ", 0, 0 },
{ "Show chat", "+show_chat", 0, 0 },
{ "Emoticon", "+emote", 0 },
{ "Spectator mode", "+spectate", 0 },
{ "Spectate next", "spectate_next", 0 },
{ "Spectate previous", "spectate_previous", 0 },
{ "Console", "toggle_local_console", 0 },
{ "Remote console", "toggle_remote_console", 0 },
{ "Screenshot", "screenshot", 0 },
{ "Scoreboard", "+scoreboard", 0 },
{ "Statboard", "+statboard", 0 },
{ "Lock team", "say /lock", 0 },
{ "Show entities", "toggle cl_overlay_entities 0 100", 0 },
{ "Show HUD", "toggle cl_showhud 0 1", 0 },
{ "Emoticon", "+emote", 0, 0 },
{ "Spectator mode", "+spectate", 0, 0 },
{ "Spectate next", "spectate_next", 0, 0 },
{ "Spectate previous", "spectate_previous", 0, 0 },
{ "Console", "toggle_local_console", 0, 0 },
{ "Remote console", "toggle_remote_console", 0, 0 },
{ "Screenshot", "screenshot", 0, 0 },
{ "Scoreboard", "+scoreboard", 0, 0 },
{ "Statboard", "+statboard", 0, 0 },
{ "Lock team", "say /lock", 0, 0 },
{ "Show entities", "toggle cl_overlay_entities 0 100", 0, 0 },
{ "Show HUD", "toggle cl_showhud 0 1", 0, 0 },
};
/* This is for scripts/update_localization.py to work, don't remove!
@ -734,14 +747,14 @@ void CMenus::UiDoGetButtons(int Start, int Stop, CUIRect View, CUIRect ScopeView
str_format(aBuf, sizeof(aBuf), "%s:", (const char *)Key.m_Name);
UI()->DoLabelScaled(&Label, aBuf, 13.0f, -1);
int OldId = Key.m_KeyId;
int NewId = DoKeyReader((void *)&gs_aKeys[i].m_Name, &Button, OldId);
if(NewId != OldId)
int OldId = Key.m_KeyId, OldModifier = Key.m_Modifier, NewModifier;
int NewId = DoKeyReader((void *)&gs_aKeys[i].m_Name, &Button, OldId, OldModifier, &NewModifier);
if(NewId != OldId || NewModifier != OldModifier)
{
if(OldId != 0 || NewId == 0)
m_pClient->m_pBinds->Bind(OldId, "");
m_pClient->m_pBinds->Bind(OldId, "", false, OldModifier);
if(NewId != 0)
m_pClient->m_pBinds->Bind(NewId, gs_aKeys[i].m_pCommand);
m_pClient->m_pBinds->Bind(NewId, gs_aKeys[i].m_pCommand, false, NewModifier);
}
}
@ -755,20 +768,24 @@ void CMenus::RenderSettingsControls(CUIRect MainView)
// this is kinda slow, but whatever
for(int i = 0; i < g_KeyCount; i++)
gs_aKeys[i].m_KeyId = 0;
gs_aKeys[i].m_KeyId = gs_aKeys[i].m_Modifier = 0;
for(int KeyId = 0; KeyId < KEY_LAST; KeyId++)
for(int Mod = 0; Mod < CBinds::MODIFIER_COUNT; Mod++)
{
const char *pBind = m_pClient->m_pBinds->Get(KeyId);
if(!pBind[0])
continue;
for(int KeyId = 0; KeyId < KEY_LAST; KeyId++)
{
const char *pBind = m_pClient->m_pBinds->Get(KeyId, Mod);
if(!pBind[0])
continue;
for(int i = 0; i < g_KeyCount; i++)
if(str_comp(pBind, gs_aKeys[i].m_pCommand) == 0)
{
gs_aKeys[i].m_KeyId = KeyId;
break;
}
for(int i = 0; i < g_KeyCount; i++)
if(str_comp(pBind, gs_aKeys[i].m_pCommand) == 0)
{
gs_aKeys[i].m_KeyId = KeyId;
gs_aKeys[i].m_Modifier = Mod;
break;
}
}
}
// controls in a scrollable listbox
@ -1055,7 +1072,7 @@ void CMenus::RenderSettingsGraphics(CUIRect MainView)
g_Config.m_GfxEnableTextureUnitOptimization ^= 1;
}
}
// check if the new settings require a restart
if(CheckSettings)
{
@ -1513,7 +1530,7 @@ void CMenus::RenderSettingsHUD(CUIRect MainView)
static int s_DefaultButton = 0;
if(DoButton_Menu(&s_DefaultButton, Localize("Reset"), 0, &Button))
{
vec3 HSL = RgbToHsl(vec3(1.0f, 1.0f, 0.5f)); // default values
vec3 HSL = RgbToHsl(vec3(1.0f, 1.0f, 0.5f)) * 255.0f; // default values
g_Config.m_ClMessageSystemHue = HSL.h;
g_Config.m_ClMessageSystemSat = HSL.s;
g_Config.m_ClMessageSystemLht = HSL.l;
@ -1565,7 +1582,7 @@ void CMenus::RenderSettingsHUD(CUIRect MainView)
static int s_DefaultButton = 0;
if(DoButton_Menu(&s_DefaultButton, Localize("Reset"), 0, &Button))
{
vec3 HSL = RgbToHsl(vec3(1.0f, 0.5f, 0.5f)); // default values
vec3 HSL = RgbToHsl(vec3(1.0f, 0.5f, 0.5f)) * 255.0f; // default values
g_Config.m_ClMessageHighlightHue = HSL.h;
g_Config.m_ClMessageHighlightSat = HSL.s;
g_Config.m_ClMessageHighlightLht = HSL.l;
@ -1623,7 +1640,7 @@ void CMenus::RenderSettingsHUD(CUIRect MainView)
static int s_DefaultButton = 0;
if(DoButton_Menu(&s_DefaultButton, Localize("Reset"), 0, &Button))
{
vec3 HSL = RgbToHsl(vec3(0.65f, 1.0f, 0.65f)); // default values
vec3 HSL = RgbToHsl(vec3(0.65f, 1.0f, 0.65f)) * 255.0f; // default values
g_Config.m_ClMessageTeamHue = HSL.h;
g_Config.m_ClMessageTeamSat = HSL.s;
g_Config.m_ClMessageTeamLht = HSL.l;
@ -1738,7 +1755,7 @@ void CMenus::RenderSettingsHUD(CUIRect MainView)
static int s_DefaultButton = 0;
if(DoButton_Menu(&s_DefaultButton, Localize("Reset"), 0, &Button))
{
vec3 HSL = RgbToHsl(vec3(1.0f, 1.0f, 1.0f)); // default values
vec3 HSL = RgbToHsl(vec3(1.0f, 1.0f, 1.0f)) * 255.0f; // default values
g_Config.m_ClMessageHue = HSL.h;
g_Config.m_ClMessageSat = HSL.s;
g_Config.m_ClMessageLht = HSL.l;
@ -1795,7 +1812,7 @@ void CMenus::RenderSettingsHUD(CUIRect MainView)
static int s_DefaultButton = 0;
if(DoButton_Menu(&s_DefaultButton, Localize("Reset"), 0, &Button))
{
vec3 HSL = RgbToHsl(vec3(0.5f, 0.5f, 1.0f)); // default values
vec3 HSL = RgbToHsl(vec3(0.5f, 0.5f, 1.0f)) * 255.0f; // default values
g_Config.m_ClLaserInnerHue = HSL.h;
g_Config.m_ClLaserInnerSat = HSL.s;
g_Config.m_ClLaserInnerLht = HSL.l;
@ -1831,7 +1848,7 @@ void CMenus::RenderSettingsHUD(CUIRect MainView)
static int s_DefaultButton = 0;
if(DoButton_Menu(&s_DefaultButton, Localize("Reset"), 0, &Button))
{
vec3 HSL = RgbToHsl(vec3(0.075f, 0.075f, 0.25f)); // default values
vec3 HSL = RgbToHsl(vec3(0.075f, 0.075f, 0.25f)) * 255.0f; // default values
g_Config.m_ClLaserOutlineHue = HSL.h;
g_Config.m_ClLaserOutlineSat = HSL.s;
g_Config.m_ClLaserOutlineLht = HSL.l;

View file

@ -28,7 +28,7 @@
#include "players.h"
#include <stdio.h>
void CPlayers::RenderHand(CTeeRenderInfo *pInfo, vec2 CenterPos, vec2 Dir, float AngleOffset, vec2 PostRotOffset)
void CPlayers::RenderHand(CTeeRenderInfo *pInfo, vec2 CenterPos, vec2 Dir, float AngleOffset, vec2 PostRotOffset, float Alpha)
{
vec2 HandPos = CenterPos + Dir;
float Angle = GetAngle(Dir);
@ -48,7 +48,7 @@ void CPlayers::RenderHand(CTeeRenderInfo *pInfo, vec2 CenterPos, vec2 Dir, float
//Graphics()->TextureSet(data->m_aImages[IMAGE_CHAR_DEFAULT].id);
Graphics()->TextureSet(pInfo->m_Texture);
Graphics()->SetColor(pInfo->m_ColorBody.r, pInfo->m_ColorBody.g, pInfo->m_ColorBody.b, pInfo->m_ColorBody.a);
Graphics()->SetColor(pInfo->m_ColorBody.r, pInfo->m_ColorBody.g, pInfo->m_ColorBody.b, Alpha);
// two passes
for(int i = 0; i < 2; i++)
@ -113,11 +113,11 @@ void CPlayers::RenderHook(
else
OtherTeam = m_pClient->m_Teams.Team(ClientID) != m_pClient->m_Teams.Team(m_pClient->m_Snap.m_LocalClientID);
if(OtherTeam)
{
RenderInfo.m_ColorBody.a = g_Config.m_ClShowOthersAlpha / 100.0f;
RenderInfo.m_ColorFeet.a = g_Config.m_ClShowOthersAlpha / 100.0f;
}
if(m_pClient->m_aClients[m_pClient->m_Snap.m_LocalClientID].m_Solo && !Local)
OtherTeam = true;
if(!Local && m_pClient->m_aClients[ClientID].m_Solo)
OtherTeam = true;
RenderInfo.m_Size = 64.0f;
@ -131,7 +131,7 @@ void CPlayers::RenderHook(
if(Prev.m_HookState>0 && Player.m_HookState>0)
{
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
Graphics()->SetColor(1.0f, 1.0f, 1.0f, 1.0f);
if(ClientID < 0)
Graphics()->SetColor(1.0f, 1.0f, 1.0f, 0.5f);
@ -173,7 +173,7 @@ void CPlayers::RenderHook(
Graphics()->QuadsSetRotation(0);
Graphics()->SetColor(1.0f, 1.0f, 1.0f, 1.0f);
RenderHand(&RenderInfo, Position, normalize(HookPos-Pos), -pi/2, vec2(20, 0));
RenderHand(&RenderInfo, Position, normalize(HookPos-Pos), -pi/2, vec2(20, 0), g_Config.m_ClShowOthersAlpha / 100.0f);
}
}
@ -518,17 +518,11 @@ void CPlayers::RenderPlayer(
Graphics()->SetColor(1.0f, 1.0f, 1.0f, 1.0f);
Graphics()->QuadsSetRotation(0);
if(OtherTeam)
{
RenderInfo.m_ColorBody.a = g_Config.m_ClShowOthersAlpha / 100.0f;
RenderInfo.m_ColorFeet.a = g_Config.m_ClShowOthersAlpha / 100.0f;
}
switch (Player.m_Weapon)
{
case WEAPON_GUN: RenderHand(&RenderInfo, p, Direction, -3*pi/4, vec2(-15, 4)); break;
case WEAPON_SHOTGUN: RenderHand(&RenderInfo, p, Direction, -pi/2, vec2(-5, 4)); break;
case WEAPON_GRENADE: RenderHand(&RenderInfo, p, Direction, -pi/2, vec2(-4, 7)); break;
case WEAPON_GUN: RenderHand(&RenderInfo, p, Direction, -3*pi/4, vec2(-15, 4), g_Config.m_ClShowOthersAlpha / 100.0f); break;
case WEAPON_SHOTGUN: RenderHand(&RenderInfo, p, Direction, -pi/2, vec2(-5, 4), g_Config.m_ClShowOthersAlpha / 100.0f); break;
case WEAPON_GRENADE: RenderHand(&RenderInfo, p, Direction, -pi/2, vec2(-4, 7), g_Config.m_ClShowOthersAlpha / 100.0f); break;
}
}
@ -544,19 +538,11 @@ void CPlayers::RenderPlayer(
Client()->IntraGameTick());
CTeeRenderInfo Ghost = RenderInfo;
Ghost.m_ColorBody.a = 0.5f;
Ghost.m_ColorFeet.a = 0.5f;
RenderTools()->RenderTee(&State, &Ghost, Player.m_Emote, Direction, GhostPosition, true); // render ghost
RenderTools()->RenderTee(&State, &Ghost, Player.m_Emote, Direction, GhostPosition, 0.5f); // render ghost
}
RenderInfo.m_Size = 64.0f; // force some settings
if(OtherTeam)
{
RenderInfo.m_ColorBody.a = g_Config.m_ClShowOthersAlpha / 100.0f;
RenderInfo.m_ColorFeet.a = g_Config.m_ClShowOthersAlpha / 100.0f;
}
Graphics()->SetColor(1.0f, 1.0f, 1.0f, 1.0f);
Graphics()->QuadsSetRotation(0);
if(g_Config.m_ClShowDirection && ClientID >= 0 && (!Local || DemoPlayer()->IsPlaying()))
@ -588,8 +574,11 @@ void CPlayers::RenderPlayer(
Graphics()->QuadsSetRotation(0);
}
RenderTools()->RenderTee(&State, &RenderInfo, Player.m_Emote, Direction, Position, OtherTeam || ClientID < 0);
if(OtherTeam || ClientID < 0)
RenderTools()->RenderTee(&State, &RenderInfo, Player.m_Emote, Direction, Position, g_Config.m_ClShowOthersAlpha / 100.0f);
else
RenderTools()->RenderTee(&State, &RenderInfo, Player.m_Emote, Direction, Position);
int QuadOffsetToEmoticon = NUM_WEAPONS * 2 + 2 + 2;
if(Player.m_PlayerFlags&PLAYERFLAG_CHATTING)
{
@ -662,8 +651,8 @@ void CPlayers::OnRender()
else
{
m_aRenderInfo[i].m_Texture = m_pClient->m_pSkins->Get(Skin)->m_OrgTexture;
m_aRenderInfo[i].m_ColorBody = vec4(1,1,1,1);
m_aRenderInfo[i].m_ColorFeet = vec4(1,1,1,1);
m_aRenderInfo[i].m_ColorBody = vec3(1,1,1);
m_aRenderInfo[i].m_ColorFeet = vec3(1,1,1);
}
}
}
@ -744,7 +733,7 @@ void CPlayers::OnInit()
RenderTools()->SelectSprite(SPRITE_OOP + i);
RenderTools()->QuadContainerAddSprite(m_WeaponEmoteQuadContainerIndex, 64.f, false);
}
for(int i = 0; i < NUM_WEAPONS; ++i)
{
m_WeaponSpriteMuzzleQuadContainerIndex[i] = Graphics()->CreateQuadContainer();

View file

@ -9,7 +9,7 @@ class CPlayers : public CComponent
friend class CGhost;
CTeeRenderInfo m_aRenderInfo[MAX_CLIENTS];
void RenderHand(class CTeeRenderInfo *pInfo, vec2 CenterPos, vec2 Dir, float AngleOffset, vec2 PostRotOffset);
void RenderHand(class CTeeRenderInfo *pInfo, vec2 CenterPos, vec2 Dir, float AngleOffset, vec2 PostRotOffset, float Alpha = 1.0f);
void RenderPlayer(
const CNetObj_Character *pPrevChar,
const CNetObj_Character *pPlayerChar,

View file

@ -135,8 +135,8 @@ void CScoreboard::RenderSpectators(float x, float y, float w)
if(m_pClient->m_aClients[pInfo->m_ClientID].m_AuthLevel)
{
vec4 Color = m_pClient->m_pSkins->GetColorV4(g_Config.m_ClAuthedPlayerColor);
TextRender()->TextColor(Color.r, Color.g, Color.b, Color.a);
vec3 Color = HslToRgb(UnpackColor(g_Config.m_ClAuthedPlayerColor));
TextRender()->TextColor(Color.r, Color.g, Color.b, 1.0f);
}
if(g_Config.m_ClShowIDs)
@ -456,8 +456,8 @@ void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const ch
TextRender()->SetCursor(&Cursor, NameOffset, y + (LineHeight - FontSize) / 2.f, FontSize, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END);
if(m_pClient->m_aClients[pInfo->m_ClientID].m_AuthLevel)
{
vec4 Color = m_pClient->m_pSkins->GetColorV4(g_Config.m_ClAuthedPlayerColor);
TextRender()->TextColor(Color.r, Color.g, Color.b, Color.a);
vec3 Color = HslToRgb(UnpackColor(g_Config.m_ClAuthedPlayerColor));
TextRender()->TextColor(Color.r, Color.g, Color.b, 1.0f);
}
if(g_Config.m_ClShowIDs)
@ -478,8 +478,8 @@ void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const ch
if(str_comp(m_pClient->m_aClients[pInfo->m_ClientID].m_aClan,
m_pClient->m_aClients[GameClient()->m_LocalIDs[g_Config.m_ClDummy]].m_aClan) == 0)
{
vec4 Color = m_pClient->m_pSkins->GetColorV4(g_Config.m_ClSameClanColor);
TextRender()->TextColor(Color.r, Color.g, Color.b, Color.a);
vec3 Color = HslToRgb(UnpackColor(g_Config.m_ClSameClanColor));
TextRender()->TextColor(Color.r, Color.g, Color.b, 1.0f);
}
else
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);

View file

@ -229,14 +229,3 @@ int CSkins::FindImpl(const char *pName) const
}
return -1;
}
vec3 CSkins::GetColorV3(int v)
{
return HslToRgb(vec3(((v>>16)&0xff)/255.0f, ((v>>8)&0xff)/255.0f, 0.5f+(v&0xff)/255.0f*0.5f));
}
vec4 CSkins::GetColorV4(int v)
{
vec3 r = GetColorV3(v);
return vec4(r.r, r.g, r.b, 1.0f);
}

View file

@ -23,8 +23,6 @@ public:
void OnInit();
vec3 GetColorV3(int v);
vec4 GetColorV4(int v);
int Num();
const CSkin *Get(int Index);
int Find(const char *pName) const;

View file

@ -393,10 +393,8 @@ void CSpectator::OnRender()
}
CTeeRenderInfo TeeInfo = m_pClient->m_aClients[m_pClient->m_Snap.m_paInfoByDDTeam[i]->m_ClientID].m_RenderInfo;
TeeInfo.m_ColorBody.a = TeeAlpha;
TeeInfo.m_ColorFeet.a = TeeAlpha;
TeeInfo.m_Size *= TeeSizeMod;
RenderTools()->RenderTee(CAnimState::GetIdle(), &TeeInfo, EMOTE_NORMAL, vec2(1.0f, 0.0f), vec2(Width/2.0f+x+20.0f, Height/2.0f+y+20.0f), true);
RenderTools()->RenderTee(CAnimState::GetIdle(), &TeeInfo, EMOTE_NORMAL, vec2(1.0f, 0.0f), vec2(Width/2.0f+x+20.0f, Height/2.0f+y+20.0f), TeeAlpha);
y += LineHeight;
}

View file

@ -171,6 +171,7 @@ void CGameClient::OnConsoleInit()
m_All.Add(m_pEffects); // doesn't render anything, just updates effects
m_All.Add(m_pParticles);
m_All.Add(m_pBinds);
m_All.Add(&m_pBinds->m_SpecialBinds);
m_All.Add(m_pControls);
m_All.Add(m_pCamera);
m_All.Add(m_pSounds);
@ -201,6 +202,7 @@ void CGameClient::OnConsoleInit()
m_All.Add(&gs_Statboard);
m_All.Add(m_pMotd);
m_All.Add(m_pMenus);
m_All.Add(&m_pMenus->m_Binder);
m_All.Add(m_pGameConsole);
// build the input stack
@ -1028,8 +1030,8 @@ void CGameClient::OnNewSnapshot()
if(m_aClients[ClientID].m_aSkinName[0] == 'x' || m_aClients[ClientID].m_aSkinName[1] == '_')
str_copy(m_aClients[ClientID].m_aSkinName, "default", 64);
m_aClients[ClientID].m_SkinInfo.m_ColorBody = m_pSkins->GetColorV4(m_aClients[ClientID].m_ColorBody);
m_aClients[ClientID].m_SkinInfo.m_ColorFeet = m_pSkins->GetColorV4(m_aClients[ClientID].m_ColorFeet);
m_aClients[ClientID].m_SkinInfo.m_ColorBody = HslToRgb(UnpackColor(m_aClients[ClientID].m_ColorBody));
m_aClients[ClientID].m_SkinInfo.m_ColorFeet = HslToRgb(UnpackColor(m_aClients[ClientID].m_ColorFeet));
m_aClients[ClientID].m_SkinInfo.m_Size = 64;
// find new skin
@ -1040,8 +1042,8 @@ void CGameClient::OnNewSnapshot()
else
{
m_aClients[ClientID].m_SkinInfo.m_Texture = g_GameClient.m_pSkins->Get(m_aClients[ClientID].m_SkinID)->m_OrgTexture;
m_aClients[ClientID].m_SkinInfo.m_ColorBody = vec4(1,1,1,1);
m_aClients[ClientID].m_SkinInfo.m_ColorFeet = vec4(1,1,1,1);
m_aClients[ClientID].m_SkinInfo.m_ColorBody = vec3(1,1,1);
m_aClients[ClientID].m_SkinInfo.m_ColorFeet = vec3(1,1,1);
}
m_aClients[ClientID].UpdateRenderInfo();
@ -1615,13 +1617,13 @@ void CGameClient::CClientData::UpdateRenderInfo()
const int TeamColors[2] = {65387, 10223467};
if(m_Team >= TEAM_RED && m_Team <= TEAM_BLUE)
{
m_RenderInfo.m_ColorBody = g_GameClient.m_pSkins->GetColorV4(TeamColors[m_Team]);
m_RenderInfo.m_ColorFeet = g_GameClient.m_pSkins->GetColorV4(TeamColors[m_Team]);
m_RenderInfo.m_ColorBody = HslToRgb(UnpackColor(TeamColors[m_Team]));
m_RenderInfo.m_ColorFeet = HslToRgb(UnpackColor(TeamColors[m_Team]));
}
else
{
m_RenderInfo.m_ColorBody = g_GameClient.m_pSkins->GetColorV4(12895054);
m_RenderInfo.m_ColorFeet = g_GameClient.m_pSkins->GetColorV4(12895054);
m_RenderInfo.m_ColorBody = HslToRgb(UnpackColor(12895054));
m_RenderInfo.m_ColorFeet = HslToRgb(UnpackColor(12895054));
}
}
}
@ -1642,10 +1644,9 @@ void CGameClient::CClientData::Reset()
m_Foe = false;
m_AuthLevel = AUTHED_NO;
m_SkinInfo.m_Texture = g_GameClient.m_pSkins->Get(0)->m_ColorTexture;
m_SkinInfo.m_ColorBody = vec4(1,1,1,1);
m_SkinInfo.m_ColorFeet = vec4(1,1,1,1);
m_SkinInfo.m_ColorBody = vec3(1,1,1);
m_SkinInfo.m_ColorFeet = vec3(1,1,1);
// DDNet Character
m_Solo = false;
m_Jetpack = false;
m_NoCollision = false;
@ -1795,7 +1796,7 @@ void CGameClient::ConColorFromRgb(IConsole::IResult *pResult, void *pUserData)
}
char aBuf[32];
Hsl = RgbToHsl(Rgb);
Hsl = RgbToHsl(Rgb) * 255.0f;
// full lightness range for GUI colors
str_format(aBuf, sizeof(aBuf), "Hue: %d, Sat: %d, Lht: %d", (int)Hsl.h, (int)Hsl.s, (int)Hsl.l);
pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "color", aBuf);

View file

@ -3,6 +3,7 @@
#ifndef GAME_CLIENT_GAMECLIENT_H
#define GAME_CLIENT_GAMECLIENT_H
#include <base/color.h>
#include <base/vmath.h>
#include <engine/client.h>
#include <engine/console.h>
@ -18,15 +19,45 @@
#include <game/client/prediction/entities/laser.h>
#include <game/client/prediction/entities/pickup.h>
#define MIN3(x,y,z) ((y) <= (z) ? \
((x) <= (y) ? (x) : (y)) \
: \
((x) <= (z) ? (x) : (z)))
class CGameClient;
#define MAX3(x,y,z) ((y) >= (z) ? \
((x) >= (y) ? (x) : (y)) \
: \
((x) >= (z) ? (x) : (z)))
class CWeaponData
{
public:
int m_Tick;
vec2 m_Pos;
vec2 m_Direction;
vec2 StartPos() { return m_Pos + m_Direction * 28.0f * 0.75f; }
};
class CLocalProjectile
{
public:
int m_Active;
CGameClient *m_pGameClient;
CWorldCore *m_pWorld;
CCollision *m_pCollision;
vec2 m_Direction;
vec2 m_Pos;
int m_StartTick;
int m_Type;
int m_Owner;
int m_Weapon;
bool m_Explosive;
int m_Bouncing;
bool m_Freeze;
bool m_ExtraInfo;
vec2 GetPos(float Time);
void CreateExplosion(vec2 Pos, int LocalClientID);
void Tick(int CurrentTick, int GameTickSpeed, int LocalClientID);
void Init(CGameClient *pGameClient, CWorldCore *pWorld, CCollision *pCollision, const CNetObj_Projectile *pProj);
void Init(CGameClient *pGameClient, CWorldCore *pWorld, CCollision *pCollision, vec2 Vel, vec2 Pos, int StartTick, int Type, int Owner, int Weapon, bool Explosive, int Bouncing, bool Freeze, bool ExtraInfo);
bool GameLayerClipped(vec2 CheckPos);
void Deactivate() { m_Active = 0; }
};
class CGameClient : public IGameClient
{
@ -401,63 +432,6 @@ private:
class CTeamsCore m_TeamsPredicted;
};
inline float HueToRgb(float v1, float v2, float h)
{
if(h < 0.0f) h += 1;
if(h > 1.0f) h -= 1;
if((6.0f * h) < 1.0f) return v1 + (v2 - v1) * 6.0f * h;
if((2.0f * h) < 1.0f) return v2;
if((3.0f * h) < 2.0f) return v1 + (v2 - v1) * ((2.0f/3.0f) - h) * 6.0f;
return v1;
}
inline vec3 HslToRgb(vec3 HSL)
{
if(HSL.s == 0.0f)
return vec3(HSL.l, HSL.l, HSL.l);
else
{
float v2 = HSL.l < 0.5f ? HSL.l * (1.0f + HSL.s) : (HSL.l+HSL.s) - (HSL.s*HSL.l);
float v1 = 2.0f * HSL.l - v2;
return vec3(HueToRgb(v1, v2, HSL.h + (1.0f/3.0f)), HueToRgb(v1, v2, HSL.h), HueToRgb(v1, v2, HSL.h - (1.0f/3.0f)));
}
}
inline vec3 RgbToHsl(vec3 RGB)
{
vec3 HSL;
float MaxColor = MAX3(RGB.r, RGB.g, RGB.b);
float MinColor = MIN3(RGB.r, RGB.g, RGB.b);
if (MinColor == MaxColor)
return vec3(0.0f, 0.0f, RGB.g * 255.0f);
else
{
HSL.l = (MinColor + MaxColor) / 2;
if (HSL.l < 0.5)
HSL.s = (MaxColor - MinColor) / (MaxColor + MinColor);
else
HSL.s = (MaxColor - MinColor) / (2.0 - MaxColor - MinColor);
if (RGB.r == MaxColor)
HSL.h = (RGB.g - RGB.b) / (MaxColor - MinColor);
else if (RGB.g == MaxColor)
HSL.h = 2.0 + (RGB.b - RGB.r) / (MaxColor - MinColor);
else
HSL.h = 4.0 + (RGB.r - RGB.g) / (MaxColor - MinColor);
HSL.h /= 6; //to bring it to a number between 0 and 1
if (HSL.h < 0) HSL.h++;
}
HSL.h = int(HSL.h * 255.0);
HSL.s = int(HSL.s * 255.0);
HSL.l = int(HSL.l * 255.0);
return HSL;
}
vec3 CalculateNameColor(vec3 TextColorHSL);
#endif

View file

@ -327,7 +327,7 @@ void CRenderTools::DrawCircle(float x, float y, float r, int Segments)
Graphics()->QuadsDrawFreeform(Array, NumItems);
}
void CRenderTools::RenderTee(CAnimState *pAnim, CTeeRenderInfo *pInfo, int Emote, vec2 Dir, vec2 Pos, bool Alpha)
void CRenderTools::RenderTee(CAnimState *pAnim, CTeeRenderInfo *pInfo, int Emote, vec2 Dir, vec2 Pos, float Alpha)
{
vec2 Direction = Dir;
vec2 Position = Pos;
@ -350,11 +350,7 @@ void CRenderTools::RenderTee(CAnimState *pAnim, CTeeRenderInfo *pInfo, int Emote
Graphics()->QuadsSetRotation(pAnim->GetBody()->m_Angle*pi*2);
// draw body
if(Alpha)
Graphics()->SetColor(pInfo->m_ColorBody.r, pInfo->m_ColorBody.g, pInfo->m_ColorBody.b, pInfo->m_ColorBody.a);
else
Graphics()->SetColor(pInfo->m_ColorBody.r, pInfo->m_ColorBody.g, pInfo->m_ColorBody.b, 1.0f);
Graphics()->SetColor(pInfo->m_ColorBody.r, pInfo->m_ColorBody.g, pInfo->m_ColorBody.b, Alpha);
vec2 BodyPos = Position + vec2(pAnim->GetBody()->m_X, pAnim->GetBody()->m_Y)*AnimScale;
float BodySize = g_Config.m_ClFatSkins ? BaseSize * 1.3 : BaseSize;
Graphics()->RenderQuadContainerAsSprite(m_TeeQuadContainerIndex, OutLine, BodyPos.x, BodyPos.y, BodySize / 64.f, BodySize / 64.f);
@ -413,11 +409,7 @@ void CRenderTools::RenderTee(CAnimState *pAnim, CTeeRenderInfo *pInfo, int Emote
cs = 0.5f;
}
if(Alpha)
Graphics()->SetColor(pInfo->m_ColorFeet.r*cs, pInfo->m_ColorFeet.g*cs, pInfo->m_ColorFeet.b*cs, pInfo->m_ColorFeet.a*cs);
else
Graphics()->SetColor(pInfo->m_ColorFeet.r*cs, pInfo->m_ColorFeet.g*cs, pInfo->m_ColorFeet.b*cs, 1.0f);
Graphics()->SetColor(pInfo->m_ColorFeet.r*cs, pInfo->m_ColorFeet.g*cs, pInfo->m_ColorFeet.b*cs, Alpha*cs);
Graphics()->RenderQuadContainerAsSprite(m_TeeQuadContainerIndex, QuadOffset, Position.x + pFoot->m_X*AnimScale, Position.y + pFoot->m_Y*AnimScale, w / 64.f, h / 32.f);
}

View file

@ -14,15 +14,15 @@ public:
CTeeRenderInfo()
{
m_Texture = -1;
m_ColorBody = vec4(1,1,1,1);
m_ColorFeet = vec4(1,1,1,1);
m_ColorBody = vec3(1,1,1);
m_ColorFeet = vec3(1,1,1);
m_Size = 1.0f;
m_GotAirJump = 1;
};
int m_Texture;
vec4 m_ColorBody;
vec4 m_ColorFeet;
vec3 m_ColorBody;
vec3 m_ColorFeet;
float m_Size;
int m_GotAirJump;
};
@ -77,7 +77,7 @@ public:
void RenderTilemapGenerateSkip(class CLayers *pLayers);
// object render methods (gc_render_obj.cpp)
void RenderTee(class CAnimState *pAnim, CTeeRenderInfo *pInfo, int Emote, vec2 Dir, vec2 Pos, bool Alpha = false);
void RenderTee(class CAnimState *pAnim, CTeeRenderInfo *pInfo, int Emote, vec2 Dir, vec2 Pos, float Alpha = 1.0f);
// map render methods (gc_render_map.cpp)
static void RenderEvalEnvelope(CEnvPoint *pPoints, int NumPoints, int Channels, float Time, float *pResult);

25
src/test/color.cpp Normal file
View file

@ -0,0 +1,25 @@
#include "test.h"
#include <gtest/gtest.h>
#include <iostream>
#include <base/system.h>
#include <base/color.h>
TEST(Color, HRHConv)
{
for(int i = 0; i < 0xFFFFFF; i++){
vec3 hsl = UnpackColor(i);
vec3 rgb = HslToRgb(hsl);
vec3 hsl2 = RgbToHsl(rgb);
if(hsl.s == 0.0f || hsl.s == 1.0f)
EXPECT_FLOAT_EQ(hsl.l, hsl2.l);
else if(hsl.l == 1.0f)
SUCCEED();
else {
EXPECT_NEAR(hsl.h, hsl2.h, 0.001f);
EXPECT_NEAR(hsl.s, hsl2.s, 0.0001f);
EXPECT_FLOAT_EQ(hsl.l, hsl2.l);
}
}
}

View file

@ -150,6 +150,10 @@ TEST(Str, Tokenize)
char aTest2[] = "";
EXPECT_EQ(str_next_token(aTest2, ",", aBuf, sizeof(aBuf)), nullptr);
char aTest3[] = "+b";
str_next_token(aTest3, "+", aBuf, sizeof(aBuf));
EXPECT_STREQ(aBuf, "b");
}
TEST(Str, InList)