diff --git a/libultraship/libultraship/Cvar.cpp b/libultraship/libultraship/Cvar.cpp index 98d4ee9b0..eb6147baf 100644 --- a/libultraship/libultraship/Cvar.cpp +++ b/libultraship/libultraship/Cvar.cpp @@ -18,7 +18,7 @@ extern "C" int32_t CVar_GetS32(const char* name, int32_t defaultValue) { CVar* cvar = CVar_Get(name); if (cvar) { - if (cvar->type == CVAR_TYPE_S32) + if (cvar->type == CVarType::S32) return cvar->value.valueS32; } @@ -29,7 +29,7 @@ extern "C" float CVar_GetFloat(const char* name, float defaultValue) { CVar* cvar = CVar_Get(name); if (cvar) { - if (cvar->type == CVAR_TYPE_FLOAT) + if (cvar->type == CVarType::Float) return cvar->value.valueFloat; } @@ -40,13 +40,53 @@ extern "C" const char* CVar_GetString(const char* name, const char* defaultValue CVar* cvar = CVar_Get(name); if (cvar) { - if (cvar->type == CVAR_TYPE_STRING) + if (cvar->type == CVarType::String) return cvar->value.valueStr; } return defaultValue; } +extern "C" Color_RGB8 CVar_GetRGB(const char* name, Color_RGB8 defaultValue) +{ + Color_RGBA8 defaultValueRGBA; + defaultValueRGBA.r = defaultValue.r; + defaultValueRGBA.g = defaultValue.g; + defaultValueRGBA.b = defaultValue.b; + defaultValueRGBA.a = 255; + + Color_RGBA8 cvarGet = CVar_GetRGBA(name, defaultValueRGBA); + Color_RGB8 result; + + result.r = cvarGet.r; + result.g = cvarGet.g; + result.b = cvarGet.b; + + return result; +} + +extern "C" Color_RGBA8 CVar_GetRGBA(const char* name, Color_RGBA8 defaultValue) { + CVar* cvar = CVar_Get(name); + + if (cvar != nullptr) { + if (cvar->type == CVarType::RGBA) + return cvar->value.valueRGBA; + } + + return defaultValue; +} + +extern "C" void CVar_SetRGBA(const char* name, Color_RGBA8 value) +{ + auto& cvar = cvars[name]; + if (!cvar) { + cvar = std::make_unique(); + } + + cvar->type = CVarType::RGBA; + cvar->value.valueRGBA = value; +} + extern "C" void CVar_SetS32(const char* name, int32_t value) { auto& cvar = cvars[name]; if (!cvar) { @@ -74,6 +114,11 @@ extern "C" void CVar_SetString(const char* name, const char* value) { cvar->value.valueStr = value; } +extern "C" void CVar_RegisterRGBA(const char* name, Color_RGBA8 defaultValue) { + if (!CVar_Get(name)) + CVar_SetRGBA(name, defaultValue); +} + extern "C" void CVar_RegisterS32(const char* name, int32_t defaultValue) { if (!CVar_Get(name)) CVar_SetS32(name, defaultValue); diff --git a/libultraship/libultraship/Cvar.h b/libultraship/libultraship/Cvar.h index c0568da41..759d7f895 100644 --- a/libultraship/libultraship/Cvar.h +++ b/libultraship/libultraship/Cvar.h @@ -1,6 +1,7 @@ #ifndef _CVAR_H #define _CVAR_H +#include "color.h" #include #ifdef __cplusplus @@ -20,6 +21,7 @@ typedef struct CVar { int32_t valueS32; float valueFloat; const char* valueStr; + Color_RGBA8 valueRGBA; } value; } CVar; @@ -39,9 +41,14 @@ const char* CVar_GetString(const char* name, const char* defaultValue); void CVar_SetS32(const char* name, int32_t value); void CVar_SetString(const char* name, const char* value); +Color_RGB8 CVar_GetRGB(const char* name, Color_RGB8 defaultValue); +Color_RGBA8 CVar_GetRGBA(const char* name, Color_RGBA8 defaultValue); +void CVar_SetRGBA(const char* name, Color_RGBA8 value); + void CVar_RegisterS32(const char* name, int32_t defaultValue); void CVar_RegisterFloat(const char* name, float defaultValue); void CVar_RegisterString(const char* name, const char* defaultValue); +void CVar_RegisterRGBA(const char* name, Color_RGBA8 defaultValue); #ifdef __cplusplus }; @@ -53,6 +60,7 @@ void CVar_RegisterString(const char* name, const char* defaultValue); #include #include +extern "C" CVar * CVar_Get(const char* name); extern std::map, std::less<>> cvars; void CVar_SetFloat(const char* name, float value); #endif diff --git a/libultraship/libultraship/GameOverlay.cpp b/libultraship/libultraship/GameOverlay.cpp index 5f98a3104..ab6dfb33c 100644 --- a/libultraship/libultraship/GameOverlay.cpp +++ b/libultraship/libultraship/GameOverlay.cpp @@ -162,13 +162,13 @@ void Ship::GameOverlay::Draw() { ImVec4 color = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); switch (var->type) { - case CVAR_TYPE_FLOAT: + case CVarType::Float: this->TextDraw(30, textY, true, color, "%s %.2f", text, var->value.valueFloat); break; - case CVAR_TYPE_S32: + case CVarType::S32: this->TextDraw(30, textY, true, color, "%s %d", text, var->value.valueS32); break; - case CVAR_TYPE_STRING: + case CVarType::String: this->TextDraw(30, textY, true, color, "%s %s", text, var->value.valueStr); break; } diff --git a/libultraship/libultraship/color.h b/libultraship/libultraship/color.h index 6c8e4c1ce..a260869a7 100644 --- a/libultraship/libultraship/color.h +++ b/libultraship/libultraship/color.h @@ -37,4 +37,8 @@ typedef union { u16 rgba; } Color_RGBA16; +#ifdef __cplusplus +}; +#endif + #endif diff --git a/soh/soh/Enhancements/debugconsole.cpp b/soh/soh/Enhancements/debugconsole.cpp index 5ea885723..bdae7754e 100644 --- a/soh/soh/Enhancements/debugconsole.cpp +++ b/soh/soh/Enhancements/debugconsole.cpp @@ -375,11 +375,16 @@ static bool StateSlotSelectHandler(const std::vector& args) { #define VARTYPE_INTEGER 0 #define VARTYPE_FLOAT 1 #define VARTYPE_STRING 2 +#define VARTYPE_RGBA 3 static int CheckVarType(const std::string& input) { int result = VARTYPE_STRING; + if (input[0] == '#') { + return VARTYPE_RGBA; + } + for (size_t i = 0; i < input.size(); i++) { if (!(std::isdigit(input[i]) || input[i] == '.')) @@ -407,7 +412,17 @@ static bool SetCVarHandler(const std::vector& args) { if (vType == VARTYPE_STRING) CVar_SetString(args[1].c_str(), args[2].c_str()); else if (vType == VARTYPE_FLOAT) - CVar_SetFloat(args[1].c_str(), std::stof(args[2])); + CVar_SetFloat((char*)args[1].c_str(), std::stof(args[2])); + else if (vType == VARTYPE_RGBA) + { + uint32_t val = std::stoul(&args[2].c_str()[1], nullptr, 16); + Color_RGBA8 clr; + clr.r = val >> 24; + clr.g = val >> 16; + clr.b = val >> 8; + clr.a = val & 0xFF; + CVar_SetRGBA((char*)args[1].c_str(), clr); + } else CVar_SetS32(args[1].c_str(), std::stoi(args[2])); @@ -432,6 +447,8 @@ static bool GetCVarHandler(const std::vector& args) { INFO("[SOH] Variable %s is %f", args[1].c_str(), cvar->value.valueFloat); else if (cvar->type == CVarType::String) INFO("[SOH] Variable %s is %s", args[1].c_str(), cvar->value.valueStr); + else if (cvar->type == CVarType::RGBA) + INFO("[SOH] Variable %s is %08X", args[1].c_str(), cvar->value.valueRGBA); } else { @@ -508,6 +525,22 @@ void DebugConsole_LoadLegacyCVars() { std::vector cfg = StringHelper::Split(line, " = "); if (line.empty()) continue; if (cfg.size() < 2) continue; + + if (cfg[1].find("\"") == std::string::npos && (cfg[1].find("#") != std::string::npos)) + { + std::string value(cfg[1]); + value.erase(std::ranges::remove(value, '#').begin(), value.end()); + auto splitTest = StringHelper::Split(value, "\r")[0]; + + uint32_t val = std::stoul(splitTest, nullptr, 16); + Color_RGBA8 clr; + clr.r = val >> 24; + clr.g = val >> 16; + clr.b = val >> 8; + clr.a = val & 0xFF; + CVar_SetRGBA(cfg[0].c_str(), clr); + } + if (cfg[1].find("\"") != std::string::npos) { std::string value(cfg[1]); value.erase(std::remove(value.begin(), value.end(), '\"'), value.end()); @@ -565,12 +598,19 @@ void DebugConsole_SaveCVars() for (const auto &cvar : cvars) { const std::string key = StringHelper::Sprintf("CVars.%s", cvar.first.c_str()); - if (cvar.second->type == CVAR_TYPE_STRING && cvar.second->value.valueStr != nullptr) + if (cvar.second->type == CVarType::String && cvar.second->value.valueStr != nullptr) pConf->setString(key, std::string(cvar.second->value.valueStr)); - else if (cvar.second->type == CVAR_TYPE_S32) + else if (cvar.second->type == CVarType::S32) pConf->setInt(key, cvar.second->value.valueS32); - else if (cvar.second->type == CVAR_TYPE_FLOAT) + else if (cvar.second->type == CVarType::Float) pConf->setFloat(key, cvar.second->value.valueFloat); + else if (cvar.second->type == CVarType::RGBA) + { + Color_RGBA8 clr = cvar.second->value.valueRGBA; + uint32_t val = (clr.r << 24) + (clr.g << 16) + (clr.b << 8) + clr.a; + Conf->setRGBA(clr); + //output += StringHelper::Sprintf("%s = #%08X\n", cvar.first.c_str(), val); + } } pConf->save(); diff --git a/soh/src/code/z_actor.c b/soh/src/code/z_actor.c index 70771880c..fff93a560 100644 --- a/soh/src/code/z_actor.c +++ b/soh/src/code/z_actor.c @@ -355,36 +355,20 @@ void func_8002BF60(TargetContext* targetCtx, Actor* actor, s32 actorCategory, Gl } } else { if (actorCategory == ACTORCAT_PLAYER) { - naviColor->inner.r = CVar_GetS32("gNavi_Idle_Inner_R", naviColor->inner.r); - naviColor->inner.g = CVar_GetS32("gNavi_Idle_Inner_G", naviColor->inner.g); - naviColor->inner.b = CVar_GetS32("gNavi_Idle_Inner_B", naviColor->inner.b); - naviColor->outer.r = CVar_GetS32("gNavi_Idle_Outer_R", naviColor->outer.r); - naviColor->outer.g = CVar_GetS32("gNavi_Idle_Outer_G", naviColor->outer.g); - naviColor->outer.b = CVar_GetS32("gNavi_Idle_Outer_B", naviColor->outer.b); + naviColor->inner = CVar_GetRGBA("gNavi_Idle_Inner", naviColor->inner); + naviColor->outer = CVar_GetRGBA("gNavi_Idle_Outer", naviColor->outer); } if (actorCategory == ACTORCAT_NPC) { - naviColor->inner.r = CVar_GetS32("gNavi_NPC_Inner_R", naviColor->inner.r); - naviColor->inner.g = CVar_GetS32("gNavi_NPC_Inner_G", naviColor->inner.g); - naviColor->inner.b = CVar_GetS32("gNavi_NPC_Inner_B", naviColor->inner.b); - naviColor->outer.r = CVar_GetS32("gNavi_NPC_Outer_R", naviColor->outer.r); - naviColor->outer.g = CVar_GetS32("gNavi_NPC_Outer_G", naviColor->outer.g); - naviColor->outer.b = CVar_GetS32("gNavi_NPC_Outer_B", naviColor->outer.b); + naviColor->inner = CVar_GetRGBA("gNavi_NPC_Inner", naviColor->inner); + naviColor->outer = CVar_GetRGBA("gNavi_NPC_Outer", naviColor->outer); } if (actorCategory == ACTORCAT_BOSS || actorCategory == ACTORCAT_ENEMY) { - naviColor->inner.r = CVar_GetS32("gNavi_Enemy_Inner_R", naviColor->inner.r); - naviColor->inner.g = CVar_GetS32("gNavi_Enemy_Inner_G", naviColor->inner.g); - naviColor->inner.b = CVar_GetS32("gNavi_Enemy_Inner_B", naviColor->inner.b); - naviColor->outer.r = CVar_GetS32("gNavi_Enemy_Outer_R", naviColor->outer.r); - naviColor->outer.g = CVar_GetS32("gNavi_Enemy_Outer_G", naviColor->outer.g); - naviColor->outer.b = CVar_GetS32("gNavi_Enemy_Outer_B", naviColor->outer.b); + naviColor->inner = CVar_GetRGBA("gNavi_Enemy_Inner", naviColor->inner); + naviColor->outer = CVar_GetRGBA("gNavi_Enemy_Outer", naviColor->outer); } if (actorCategory == ACTORCAT_PROP) { - naviColor->inner.r = CVar_GetS32("gNavi_Prop_Inner_R", naviColor->inner.r); - naviColor->inner.g = CVar_GetS32("gNavi_Prop_Inner_G", naviColor->inner.g); - naviColor->inner.b = CVar_GetS32("gNavi_Prop_Inner_B", naviColor->inner.b); - naviColor->outer.r = CVar_GetS32("gNavi_Prop_Outer_R", naviColor->outer.r); - naviColor->outer.g = CVar_GetS32("gNavi_Prop_Outer_G", naviColor->outer.g); - naviColor->outer.b = CVar_GetS32("gNavi_Prop_Outer_B", naviColor->outer.b); + naviColor->inner = CVar_GetRGBA("gNavi_Prop_Inner", naviColor->inner); + naviColor->outer = CVar_GetRGBA("gNavi_Prop_Outer", naviColor->outer); } } diff --git a/soh/src/code/z_player_lib.c b/soh/src/code/z_player_lib.c index 470cec354..2db533821 100644 --- a/soh/src/code/z_player_lib.c +++ b/soh/src/code/z_player_lib.c @@ -752,18 +752,12 @@ void func_8008F470(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, }; color = &sTemp; if (tunic == PLAYER_TUNIC_KOKIRI && CVar_GetS32("gUseTunicsCol",0)) { - color->r = CVar_GetS32("gTunic_Kokiri_R", sTunicColors[PLAYER_TUNIC_KOKIRI].r); - color->g = CVar_GetS32("gTunic_Kokiri_G", sTunicColors[PLAYER_TUNIC_KOKIRI].g); - color->b = CVar_GetS32("gTunic_Kokiri_B", sTunicColors[PLAYER_TUNIC_KOKIRI].b); + *color = CVar_GetRGB("gTunic_Kokiri", sTunicColors[PLAYER_TUNIC_KOKIRI]); } else if (tunic == PLAYER_TUNIC_GORON && CVar_GetS32("gUseTunicsCol",0)) { - color->r = CVar_GetS32("gTunic_Goron_R", sTunicColors[PLAYER_TUNIC_GORON].r); - color->g = CVar_GetS32("gTunic_Goron_G", sTunicColors[PLAYER_TUNIC_GORON].g); - color->b = CVar_GetS32("gTunic_Goron_B", sTunicColors[PLAYER_TUNIC_GORON].b); + *color = CVar_GetRGB("gTunic_Goron", sTunicColors[PLAYER_TUNIC_GORON]); } else if (tunic == PLAYER_TUNIC_ZORA && CVar_GetS32("gUseTunicsCol",0)) { - color->r = CVar_GetS32("gTunic_Zora_R", sTunicColors[PLAYER_TUNIC_ZORA].r); - color->g = CVar_GetS32("gTunic_Zora_G", sTunicColors[PLAYER_TUNIC_ZORA].g); - color->b = CVar_GetS32("gTunic_Zora_B", sTunicColors[PLAYER_TUNIC_ZORA].b); - } else if (!CVar_GetS32("gUseTunicsCol",0)) { + *color = CVar_GetRGB("gTunic_Zora", sTunicColors[PLAYER_TUNIC_ZORA]); + } else if (!CVar_GetS32("gUseTunicsCol",0)){ if (tunic >= 3) { color->r = sOriginalTunicColors[0].r; color->g = sOriginalTunicColors[0].g;