Add the ability to Randomize Music and Sound Effects and Cosmetrics based on Rando File Seed. (#5970)
Add the ability to Randomize All Music and sfx based on file Rando seed. Add the ability to Randomize All cosmetics based on file rando seed. Add combobox for selection: - Disabled: No music or sound effects are randomized. - On New Scene: Randomizes when you enter a new scene. - On Rando Gen Only: Randomizes only when you generate a new randomizer - On File Load: Randomizes on File Load. - On File Load (Seeded): Randomizes on file load based on the current randomizer seed/file. Removed checkboxes.
This commit is contained in:
@@ -33,8 +33,7 @@ static WidgetInfo leadingMusic;
|
||||
static WidgetInfo displaySeqName;
|
||||
static WidgetInfo ovlDuration;
|
||||
static WidgetInfo voicePitch;
|
||||
static WidgetInfo randoMusicOnSceneChange;
|
||||
static WidgetInfo randomAudioOnSeedGen;
|
||||
static WidgetInfo randomAudioGenModes;
|
||||
static WidgetInfo lowerOctaves;
|
||||
|
||||
namespace SohGui {
|
||||
@@ -78,6 +77,14 @@ size_t AuthenticCountBySequenceType(SeqType type) {
|
||||
}
|
||||
}
|
||||
|
||||
static const std::unordered_map<int32_t, const char*> audioRandomizerModes = {
|
||||
{ RANDOMIZE_OFF, "Manual" },
|
||||
{ RANDOMIZE_ON_NEW_SCENE, "On New Scene" },
|
||||
{ RANDOMIZE_ON_RANDO_GEN_ONLY, "On Rando Gen Only" },
|
||||
{ RANDOMIZE_ON_FILE_LOAD, "On File Load" },
|
||||
{ RANDOMIZE_ON_FILE_LOAD_SEEDED, "On File Load (Seeded)" },
|
||||
};
|
||||
|
||||
// Grabs the current BGM sequence ID and replays it
|
||||
// which will lookup the proper override, or reset back to vanilla
|
||||
void ReplayCurrentBGM() {
|
||||
@@ -100,9 +107,19 @@ void UpdateCurrentBGM(u16 seqKey, SeqType seqType) {
|
||||
}
|
||||
}
|
||||
|
||||
void RandomizeGroup(SeqType type) {
|
||||
void RandomizeGroup(SeqType type, bool manual = true) {
|
||||
std::vector<u16> values;
|
||||
|
||||
if (!manual) {
|
||||
if (CVarGetInteger(CVAR_AUDIO("RandomizeAudioGenModes"), 0) == RANDOMIZE_ON_FILE_LOAD_SEEDED ||
|
||||
CVarGetInteger(CVAR_AUDIO("RandomizeAudioGenModes"), 0) == RANDOMIZE_ON_RANDO_GEN_ONLY) {
|
||||
|
||||
uint32_t finalSeed = type + (IS_RANDO ? Rando::Context::GetInstance()->GetSeed()
|
||||
: static_cast<uint32_t>(gSaveContext.ship.stats.fileCreatedAt));
|
||||
Random_Init(finalSeed);
|
||||
}
|
||||
}
|
||||
|
||||
// An empty IncludedSequences set means that the AudioEditor window has never been drawn
|
||||
if (AudioCollection::Instance->GetIncludedSequences().empty()) {
|
||||
AudioCollection::Instance->InitializeShufflePool();
|
||||
@@ -478,16 +495,29 @@ void DrawTypeChip(SeqType type, std::string sequenceName) {
|
||||
|
||||
void AudioEditorRegisterOnSceneInitHook() {
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneInit>([](int16_t sceneNum) {
|
||||
if (gSaveContext.gameMode != GAMEMODE_END_CREDITS && CVarGetInteger(CVAR_AUDIO("RandomizeAllOnNewScene"), 0)) {
|
||||
AudioEditor_RandomizeAll();
|
||||
if (gSaveContext.gameMode != GAMEMODE_END_CREDITS &&
|
||||
CVarGetInteger(CVAR_AUDIO("RandomizeAudioGenModes"), 0) == RANDOMIZE_ON_NEW_SCENE) {
|
||||
|
||||
AudioEditor_AutoRandomizeAll();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void AudioEditorRegisterOnGenerationCompletionHook() {
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGenerationCompletion>([]() {
|
||||
if (CVarGetInteger(CVAR_AUDIO("RandomizeAllOnRandoGen"), 0)) {
|
||||
AudioEditor_RandomizeAll();
|
||||
if (CVarGetInteger(CVAR_AUDIO("RandomizeAudioGenModes"), 0) == RANDOMIZE_ON_RANDO_GEN_ONLY) {
|
||||
|
||||
AudioEditor_AutoRandomizeAll();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void AudioEditorRegisterOnLoadGameHook() {
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnLoadGame>([](int32_t fileNum) {
|
||||
if (CVarGetInteger(CVAR_AUDIO("RandomizeAudioGenModes"), 0) == RANDOMIZE_ON_FILE_LOAD ||
|
||||
CVarGetInteger(CVAR_AUDIO("RandomizeAudioGenModes"), 0) == RANDOMIZE_ON_FILE_LOAD_SEEDED) {
|
||||
|
||||
AudioEditor_AutoRandomizeAll();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -495,6 +525,7 @@ void AudioEditorRegisterOnGenerationCompletionHook() {
|
||||
void AudioEditor::InitElement() {
|
||||
AudioEditorRegisterOnSceneInitHook();
|
||||
AudioEditorRegisterOnGenerationCompletionHook();
|
||||
AudioEditorRegisterOnLoadGameHook();
|
||||
}
|
||||
|
||||
void AudioEditor::DrawElement() {
|
||||
@@ -556,8 +587,7 @@ void AudioEditor::DrawElement() {
|
||||
UIWidgets::ButtonOptions().Size(ImVec2(80, 36)).Padding(ImVec2(5.0f, 0.0f)))) {
|
||||
CVarSetFloat(CVAR_AUDIO("LinkVoiceFreqMultiplier"), 1.0f);
|
||||
}
|
||||
SohGui::mSohMenu->MenuDrawItem(randoMusicOnSceneChange, ImGui::GetContentRegionAvail().x, THEME_COLOR);
|
||||
SohGui::mSohMenu->MenuDrawItem(randomAudioOnSeedGen, ImGui::GetContentRegionAvail().x, THEME_COLOR);
|
||||
SohGui::mSohMenu->MenuDrawItem(randomAudioGenModes, ImGui::GetContentRegionAvail().x, THEME_COLOR);
|
||||
SohGui::mSohMenu->MenuDrawItem(lowerOctaves, ImGui::GetContentRegionAvail().x, THEME_COLOR);
|
||||
}
|
||||
ImGui::EndChild();
|
||||
@@ -774,6 +804,15 @@ void AudioEditor_RandomizeAll() {
|
||||
ReplayCurrentBGM();
|
||||
}
|
||||
|
||||
void AudioEditor_AutoRandomizeAll() {
|
||||
for (auto type : allTypes) {
|
||||
RandomizeGroup(type, false);
|
||||
}
|
||||
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
|
||||
ReplayCurrentBGM();
|
||||
}
|
||||
|
||||
void AudioEditor_RandomizeGroup(SeqType group) {
|
||||
RandomizeGroup(group);
|
||||
|
||||
@@ -865,22 +904,22 @@ void RegisterAudioWidgets() {
|
||||
.Size(ImVec2(300.0f, 0.0f)));
|
||||
SohGui::mSohMenu->AddSearchWidget({ voicePitch, "Enhancements", "Audio Editor", "Audio Options" });
|
||||
|
||||
randoMusicOnSceneChange = { .name = "Randomize All Music and Sound Effects on New Scene",
|
||||
.type = WidgetType::WIDGET_CVAR_CHECKBOX };
|
||||
randoMusicOnSceneChange.CVar(CVAR_AUDIO("RandomizeAllOnNewScene"))
|
||||
.Options(CheckboxOptions()
|
||||
.Color(THEME_COLOR)
|
||||
.Tooltip("Enables randomizing all unlocked music and sound effects when you enter a new scene."));
|
||||
SohGui::mSohMenu->AddSearchWidget({ randoMusicOnSceneChange, "Enhancements", "Audio Editor", "Audio Options" });
|
||||
|
||||
randomAudioOnSeedGen = { .name = "Randomize All Music and Sound Effects on Randomizer Generation",
|
||||
.type = WidgetType::WIDGET_CVAR_CHECKBOX };
|
||||
randomAudioOnSeedGen.CVar(CVAR_AUDIO("RandomizeAllOnRandoGen"))
|
||||
.Options(CheckboxOptions()
|
||||
.Color(THEME_COLOR)
|
||||
.Tooltip("Enables randomizing all unlocked music and sound effects when you generate a new "
|
||||
"randomizer. Respects locks already in place."));
|
||||
SohGui::mSohMenu->AddSearchWidget({ randomAudioOnSeedGen, "Enhancements", "Audio Editor", "Audio Options" });
|
||||
randomAudioGenModes = { .name = "Automatically Randomize All Music and Sound Effects",
|
||||
.type = WidgetType::WIDGET_CVAR_COMBOBOX };
|
||||
randomAudioGenModes.CVar(CVAR_AUDIO("RandomizeAudioGenModes"))
|
||||
.Options(
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(RANDOMIZE_OFF)
|
||||
.ComboMap(audioRandomizerModes)
|
||||
.Tooltip(
|
||||
"Set when the music and sound effects is automaticly randomized:\n"
|
||||
"- Manual: Manually randomize music or sound effects by pressing the 'Randomize all Groups' "
|
||||
"button\n"
|
||||
"- On New Scene : Randomizes when you enter a new scene.\n"
|
||||
"- On Rando Gen Only: Randomizes only when you generate a new randomizer.\n"
|
||||
"- On File Load: Randomizes on File Load.\n"
|
||||
"- On File Load (Seeded): Randomizes on file load based on the current randomizer seed/file.\n"));
|
||||
SohGui::mSohMenu->AddSearchWidget({ randomAudioGenModes, "Enhancements", "Audio Editor", "Audio Options" });
|
||||
|
||||
lowerOctaves = { .name = "Lower Octaves of Unplayable High Notes", .type = WidgetType::WIDGET_CVAR_CHECKBOX };
|
||||
lowerOctaves.CVar(CVAR_AUDIO("ExperimentalOctaveDrop"))
|
||||
|
||||
@@ -18,6 +18,7 @@ class AudioEditor final : public Ship::GuiWindow {
|
||||
};
|
||||
|
||||
void AudioEditor_RandomizeAll();
|
||||
void AudioEditor_AutoRandomizeAll();
|
||||
void AudioEditor_RandomizeGroup(SeqType group);
|
||||
void AudioEditor_ResetAll();
|
||||
void AudioEditor_ResetGroup(SeqType group);
|
||||
|
||||
@@ -13,9 +13,11 @@
|
||||
#include "soh/SohGui/SohGui.hpp"
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "soh/ResourceManagerHelpers.h"
|
||||
#include "soh/Enhancements/enhancementTypes.h"
|
||||
|
||||
extern "C" {
|
||||
#include "z64.h"
|
||||
#include "z64save.h"
|
||||
#include "macros.h"
|
||||
#include "soh/cvar_prefixes.h"
|
||||
#include "objects/object_link_boy/object_link_boy.h"
|
||||
@@ -47,6 +49,7 @@ extern "C" {
|
||||
#include "objects/object_gi_rabit_mask/object_gi_rabit_mask.h"
|
||||
#include "overlays/ovl_Magic_Wind/ovl_Magic_Wind.h"
|
||||
|
||||
extern SaveContext gSaveContext;
|
||||
extern PlayState* gPlayState;
|
||||
void ResourceMgr_PatchGfxByName(const char* path, const char* patchName, int index, Gfx instruction);
|
||||
void ResourceMgr_PatchGfxCopyCommandByName(const char* path, const char* patchName, int destinationIndex,
|
||||
@@ -96,6 +99,14 @@ std::map<CosmeticGroup, const char*> groupLabels = {
|
||||
{ COSMETICS_GROUP_MESSAGE, "Message" },
|
||||
};
|
||||
|
||||
static const std::unordered_map<int32_t, const char*> cosmeticsRandomizerModes = {
|
||||
{ RANDOMIZE_OFF, "Manual" },
|
||||
{ RANDOMIZE_ON_NEW_SCENE, "On New Scene" },
|
||||
{ RANDOMIZE_ON_RANDO_GEN_ONLY, "On Rando Gen Only" },
|
||||
{ RANDOMIZE_ON_FILE_LOAD, "On File Load" },
|
||||
{ RANDOMIZE_ON_FILE_LOAD_SEEDED, "On File Load (Seeded)" },
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const char* cvar;
|
||||
const char* valuesCvar;
|
||||
@@ -2093,8 +2104,22 @@ void ApplySideEffects(CosmeticOption& cosmeticOption) {
|
||||
}
|
||||
}
|
||||
|
||||
void RandomizeColor(CosmeticOption& cosmeticOption) {
|
||||
ImVec4 randomColor = GetRandomValue();
|
||||
void RandomizeColor(CosmeticOption& cosmeticOption, bool manual = true) {
|
||||
ImVec4 randomColor;
|
||||
|
||||
if (!manual && CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), 0) == RANDOMIZE_ON_FILE_LOAD_SEEDED ||
|
||||
!manual && CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), 0) == RANDOMIZE_ON_RANDO_GEN_ONLY) {
|
||||
|
||||
uint32_t finalSeed = cosmeticOption.defaultColor.r + cosmeticOption.defaultColor.g +
|
||||
cosmeticOption.defaultColor.b + cosmeticOption.defaultColor.a +
|
||||
(IS_RANDO ? Rando::Context::GetInstance()->GetSeed()
|
||||
: static_cast<uint32_t>(gSaveContext.ship.stats.fileCreatedAt));
|
||||
|
||||
randomColor = GetRandomValue(finalSeed);
|
||||
} else {
|
||||
randomColor = GetRandomValue();
|
||||
}
|
||||
|
||||
Color_RGBA8 newColor;
|
||||
newColor.r = static_cast<uint8_t>(randomColor.x * 255.0f);
|
||||
newColor.g = static_cast<uint8_t>(randomColor.y * 255.0f);
|
||||
@@ -2372,17 +2397,17 @@ void CosmeticsEditorWindow::DrawElement() {
|
||||
.Step(0.01f)
|
||||
.Size(ImVec2(300.0f, 0.0f))
|
||||
.Color(THEME_COLOR));
|
||||
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
|
||||
UIWidgets::CVarCheckbox("Randomize All on New Scene", CVAR_COSMETIC("RandomizeAllOnNewScene"),
|
||||
UIWidgets::CheckboxOptions()
|
||||
.Color(THEME_COLOR)
|
||||
.Tooltip("Enables randomizing all unlocked cosmetics when you enter a new scene."));
|
||||
ImGui::EndDisabled();
|
||||
UIWidgets::CVarCheckbox(
|
||||
"Randomize All on Randomizer Generation", CVAR_COSMETIC("RandomizeAllOnRandoGen"),
|
||||
UIWidgets::CheckboxOptions()
|
||||
UIWidgets::CVarCombobox(
|
||||
"Automatically Randomize All Cosmetics", CVAR_COSMETIC("RandomizeCosmeticsGenModes"), cosmeticsRandomizerModes,
|
||||
UIWidgets::ComboboxOptions()
|
||||
.DefaultIndex(RANDOMIZE_OFF)
|
||||
.Color(THEME_COLOR)
|
||||
.Tooltip("Enables randomizing all unlocked cosmetics when you generate a new randomizer."));
|
||||
.Tooltip("Set when the cosmetics is automaticly randomized:\n"
|
||||
"- Manual: Manually randomize cosmetics by pressing the 'Randomize all' button\n"
|
||||
"- On New Scene : Randomizes when you enter a new scene.\n"
|
||||
"- On Rando Gen Only: Randomizes only when you generate a new randomizer.\n"
|
||||
"- On File Load: Randomizes on File Load.\n"
|
||||
"- On File Load (Seeded): Randomizes on file load based on the current randomizer seed/file.\n"));
|
||||
UIWidgets::CVarCheckbox(
|
||||
"Advanced Mode", CVAR_COSMETIC("AdvancedMode"),
|
||||
UIWidgets::CheckboxOptions()
|
||||
@@ -2573,6 +2598,10 @@ void CosmeticsEditorWindow::DrawElement() {
|
||||
UIWidgets::PopStyleTabs();
|
||||
}
|
||||
|
||||
void RegisterOnGameFrameUpdateHook() {
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameFrameUpdate>([]() { CosmeticsUpdateTick(); });
|
||||
}
|
||||
|
||||
void CosmeticsEditorWindow::InitElement() {
|
||||
// Convert the `current color` into the format that the ImGui color picker expects
|
||||
for (auto& [id, cosmeticOption] : cosmeticOptions) {
|
||||
@@ -2602,6 +2631,18 @@ void CosmeticsEditor_RandomizeAll() {
|
||||
ApplyOrResetCustomGfxPatches();
|
||||
}
|
||||
|
||||
void CosmeticsEditor_AutoRandomizeAll() {
|
||||
for (auto& [id, cosmeticOption] : cosmeticOptions) {
|
||||
if (!CVarGetInteger(cosmeticOption.lockedCvar, 0) &&
|
||||
(!cosmeticOption.advancedOption || CVarGetInteger(CVAR_COSMETIC("AdvancedMode"), 0))) {
|
||||
RandomizeColor(cosmeticOption, false);
|
||||
}
|
||||
}
|
||||
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
|
||||
ApplyOrResetCustomGfxPatches();
|
||||
}
|
||||
|
||||
void CosmeticsEditor_RandomizeGroup(CosmeticGroup group) {
|
||||
for (auto& [id, cosmeticOption] : cosmeticOptions) {
|
||||
if (!CVarGetInteger(cosmeticOption.lockedCvar, 0) &&
|
||||
@@ -2638,13 +2679,25 @@ void CosmeticsEditor_ResetGroup(CosmeticGroup group) {
|
||||
}
|
||||
|
||||
void RegisterCosmeticHooks() {
|
||||
COND_HOOK(OnSceneInit, CVarGetInteger(CVAR_COSMETIC("RandomizeAllOnNewScene"), 0),
|
||||
[](s16 sceneNum) { CosmeticsEditor_RandomizeAll(); });
|
||||
COND_HOOK(OnGenerationCompletion,
|
||||
CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), RANDOMIZE_OFF) == RANDOMIZE_ON_RANDO_GEN_ONLY,
|
||||
[]() { CosmeticsEditor_AutoRandomizeAll(); });
|
||||
|
||||
COND_HOOK(OnGenerationCompletion, CVarGetInteger(CVAR_COSMETIC("RandomizeAllOnRandoGen"), 0),
|
||||
[]() { CosmeticsEditor_RandomizeAll(); });
|
||||
COND_HOOK(OnLoadGame, CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), RANDOMIZE_OFF) == RANDOMIZE_OFF,
|
||||
[](s32 fileNum) { ApplyOrResetCustomGfxPatches(); });
|
||||
|
||||
COND_HOOK(OnLoadGame, true, [](int32_t fileNum) { ApplyOrResetCustomGfxPatches(); });
|
||||
COND_HOOK(OnLoadGame,
|
||||
CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), RANDOMIZE_OFF) == RANDOMIZE_ON_FILE_LOAD,
|
||||
[](s32 fileNum) { CosmeticsEditor_AutoRandomizeAll(); });
|
||||
|
||||
COND_HOOK(OnLoadGame,
|
||||
CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), RANDOMIZE_OFF) ==
|
||||
RANDOMIZE_ON_FILE_LOAD_SEEDED,
|
||||
[](s32 fileNum) { CosmeticsEditor_AutoRandomizeAll(); });
|
||||
|
||||
COND_HOOK(OnSceneInit,
|
||||
CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), RANDOMIZE_OFF) == RANDOMIZE_ON_NEW_SCENE,
|
||||
[](s16 sceneNum) { CosmeticsEditor_AutoRandomizeAll(); });
|
||||
|
||||
COND_HOOK(OnGameFrameUpdate, true, CosmeticsUpdateTick);
|
||||
}
|
||||
@@ -2664,7 +2717,6 @@ void RegisterCosmeticWidgets() {
|
||||
}
|
||||
|
||||
static RegisterShipInitFunc initFunc(RegisterCosmeticHooks, {
|
||||
CVAR_COSMETIC("RandomizeAllOnNewScene"),
|
||||
CVAR_COSMETIC("RandomizeAllOnRandoGen"),
|
||||
CVAR_COSMETIC("RandomizeCosmeticsGenModes"),
|
||||
});
|
||||
static RegisterMenuInitFunc menuInitFunc(RegisterCosmeticWidgets);
|
||||
|
||||
@@ -55,6 +55,7 @@ static ImGuiTableColumnFlags FlagsCell =
|
||||
ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_IndentEnable | ImGuiTableColumnFlags_NoSort;
|
||||
|
||||
void CosmeticsEditor_RandomizeAll();
|
||||
void CosmeticsEditor_AutoRandomizeAll();
|
||||
void CosmeticsEditor_RandomizeGroup(CosmeticGroup group);
|
||||
void CosmeticsEditor_ResetAll();
|
||||
void CosmeticsEditor_ResetGroup(CosmeticGroup group);
|
||||
|
||||
@@ -123,4 +123,12 @@ typedef enum {
|
||||
WATERFALL_NEVER,
|
||||
} SleepingWaterfallType;
|
||||
|
||||
typedef enum {
|
||||
RANDOMIZE_OFF,
|
||||
RANDOMIZE_ON_NEW_SCENE,
|
||||
RANDOMIZE_ON_RANDO_GEN_ONLY,
|
||||
RANDOMIZE_ON_FILE_LOAD,
|
||||
RANDOMIZE_ON_FILE_LOAD_SEEDED,
|
||||
} RandomizeOnMode;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1170,6 +1170,21 @@ ImVec4 GetRandomValue() {
|
||||
return NewColor;
|
||||
}
|
||||
|
||||
ImVec4 GetRandomValue(uint32_t seed) {
|
||||
#if !defined(__SWITCH__) && !defined(__WIIU__)
|
||||
std::mt19937 rng(seed);
|
||||
#else
|
||||
std::mt19937_64 rng(seed);
|
||||
#endif
|
||||
std::uniform_int_distribution<int> dist(0, 255 - 1);
|
||||
|
||||
ImVec4 NewColor;
|
||||
NewColor.x = (float)(dist(rng)) / 255.0f;
|
||||
NewColor.y = (float)(dist(rng)) / 255.0f;
|
||||
NewColor.z = (float)(dist(rng)) / 255.0f;
|
||||
return NewColor;
|
||||
}
|
||||
|
||||
Color_RGBA8 RGBA8FromVec(ImVec4 vec) {
|
||||
Color_RGBA8 color = { vec.x * 255, vec.y * 255, vec.z * 255, vec.w * 255 };
|
||||
return color;
|
||||
|
||||
@@ -1051,7 +1051,9 @@ void DrawFlagArray8Mask(const std::string& name, uint8_t& flags, Colors color =
|
||||
void InsertHelpHoverText(const std::string& text);
|
||||
void InsertHelpHoverText(const char* text);
|
||||
} // namespace UIWidgets
|
||||
|
||||
ImVec4 GetRandomValue();
|
||||
ImVec4 GetRandomValue(uint32_t seed);
|
||||
|
||||
Color_RGBA8 RGBA8FromVec(ImVec4 vec);
|
||||
ImVec4 VecFromRGBA8(Color_RGBA8 color);
|
||||
|
||||
Reference in New Issue
Block a user