diff --git a/libultraship/GameSettings.cpp b/libultraship/GameSettings.cpp index c2d876ab099..d9353a58a8c 100644 --- a/libultraship/GameSettings.cpp +++ b/libultraship/GameSettings.cpp @@ -10,13 +10,12 @@ #include "Cvar.h" #include "GlobalCtx2.h" #include "SohImGuiImpl.h" -#include "stox.h" #include "../../soh/include/z64audio.h" -#include #include "SohHooks.h" #include "../../soh/soh/Enhancements/debugconsole.h" #include "Window.h" +#include "Lib/Fast3D/gfx_rendering_api.h" #define ABS(var) var < 0 ? -(var) : var @@ -25,14 +24,6 @@ using namespace Ship; namespace Game { bool DeSyncAudio = false; - SoHConfigType Settings; - const std::string ConfSection = DEBUG_SECTION; - const std::string AudioSection = AUDIO_SECTION; - const std::string ControllerSection = CONTROLLER_SECTION; - const std::string EnhancementSection = ENHANCEMENTS_SECTION; - const std::string CosmeticsSection = COSMETICS_SECTION; - const std::string CheatSection = CHEATS_SECTION; - const std::string LanguagesSection = LANGUAGES_SECTION; void UpdateAudio() { Audio_SetGameVolume(SEQ_BGM_MAIN, CVar_GetFloat("gMainMusicVolume", 1)); @@ -41,18 +32,6 @@ namespace Game { Audio_SetGameVolume(SEQ_SFX, CVar_GetFloat("gFanfareVolume", 1)); } - void LoadSettings() { - const std::shared_ptr pConf = GlobalCtx2::GetInstance()->GetConfig(); - ConfigFile& Conf = *pConf; - - // Debug - SohImGui::console->opened = stob(Conf[ConfSection]["console"]); - Settings.debug.menu_bar = stob(Conf[ConfSection]["menu_bar"]); - Settings.debug.soh = stob(Conf[ConfSection]["soh_debug"]); - - UpdateAudio(); - } - void LoadPadSettings() { const std::shared_ptr pConf = GlobalCtx2::GetInstance()->GetConfig(); ConfigFile& Conf = *pConf; @@ -65,16 +44,11 @@ namespace Game { } } - void SaveSettings() { - const std::shared_ptr pConf = GlobalCtx2::GetInstance()->GetConfig(); - ConfigFile& Conf = *pConf; - - // Debug - Conf[ConfSection]["console"] = std::to_string(SohImGui::console->opened); - Conf[ConfSection]["menu_bar"] = std::to_string(Settings.debug.menu_bar); - Conf[ConfSection]["soh_debug"] = std::to_string(Settings.debug.soh); + void LoadSettings() { + DebugConsole_LoadCVars(); + } - Conf.Save(); + void SaveSettings() { DebugConsole_SaveCVars(); } @@ -82,6 +56,11 @@ namespace Game { ModInternal::registerHookListener({ AUDIO_INIT, [](HookEvent ev) { UpdateAudio(); }}); + ModInternal::registerHookListener({ GFX_INIT, [](HookEvent ev) { + gfx_get_current_rendering_api()->set_texture_filter((FilteringMode) CVar_GetS32("gTextureFilter", THREE_POINT)); + SohImGui::console->opened = CVar_GetS32("gConsoleEnabled", 0); + UpdateAudio(); + }}); } void SetSeqPlayerVolume(SeqPlayers playerId, float volume) { diff --git a/libultraship/GameSettings.h b/libultraship/GameSettings.h index 9d4e3e7763c..0a9aa0ee64d 100644 --- a/libultraship/GameSettings.h +++ b/libultraship/GameSettings.h @@ -1,19 +1,5 @@ #pragma once -struct SoHConfigType { - // Debug - struct { - bool soh = false; - bool menu_bar = false; - bool soh_sink = true; - } debug; - - // Graphics - struct { - bool show = false; - } graphics; -}; - enum SeqPlayers { /* 0 */ SEQ_BGM_MAIN, /* 1 */ SEQ_FANFARE, @@ -22,16 +8,7 @@ enum SeqPlayers { /* 4 */ SEQ_MAX }; -#define DEBUG_SECTION "DEBUG SETTINGS" -#define AUDIO_SECTION "AUDIO SETTINGS" -#define CONTROLLER_SECTION "CONTROLLER SECTION" -#define ENHANCEMENTS_SECTION "ENHANCEMENT SETTINGS" -#define COSMETICS_SECTION "COSMETIC SETTINGS" -#define CHEATS_SECTION "CHEATS SETTINGS" -#define LANGUAGES_SECTION "LANGUAGES SETTINGS" - namespace Game { - extern SoHConfigType Settings; void InitSettings(); void LoadSettings(); void LoadPadSettings(); diff --git a/libultraship/Lib/Fast3D/gfx_direct3d11.cpp b/libultraship/Lib/Fast3D/gfx_direct3d11.cpp index cea82e09ebe..8671c3df4bc 100644 --- a/libultraship/Lib/Fast3D/gfx_direct3d11.cpp +++ b/libultraship/Lib/Fast3D/gfx_direct3d11.cpp @@ -15,11 +15,9 @@ #ifndef _LANGUAGE_C #define _LANGUAGE_C #endif -#include +#include "PR/ultra64/gbi.h" -#include "gfx_cc.h" #include "gfx_window_manager_api.h" -#include "gfx_rendering_api.h" #include "gfx_direct3d_common.h" #define DECLARE_GFX_DXGI_FUNCTIONS @@ -28,7 +26,9 @@ #include "gfx_screen_config.h" #include "../../SohImGuiImpl.h" -#define THREE_POINT_FILTERING 0 +#include "gfx_cc.h" +#include "gfx_rendering_api.h" +#include "gfx_pc.h" #define DEBUG_D3D 0 using namespace Microsoft::WRL; // For ComPtr @@ -135,6 +135,7 @@ static struct { //uint32_t current_width, current_height; uint32_t render_target_height; int current_framebuffer; + FilteringMode current_filter_mode = NONE; int8_t depth_test; int8_t depth_mask; @@ -397,7 +398,7 @@ static struct ShaderProgram *gfx_d3d11_create_and_load_new_shader(uint64_t shade char buf[4096]; size_t len, num_floats; - gfx_direct3d_common_build_shader(buf, len, num_floats, cc_features, false, THREE_POINT_FILTERING); + gfx_direct3d_common_build_shader(buf, len, num_floats, cc_features, false, d3d.current_filter_mode == THREE_POINT); ComPtr vs, ps; ComPtr error_blob; @@ -564,11 +565,8 @@ static void gfx_d3d11_set_sampler_parameters(int tile, bool linear_filter, uint3 D3D11_SAMPLER_DESC sampler_desc; ZeroMemory(&sampler_desc, sizeof(D3D11_SAMPLER_DESC)); -#if THREE_POINT_FILTERING - sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; -#else - sampler_desc.Filter = linear_filter ? D3D11_FILTER_MIN_MAG_MIP_LINEAR : D3D11_FILTER_MIN_MAG_MIP_POINT; -#endif + sampler_desc.Filter = linear_filter && d3d.current_filter_mode == LINEAR ? D3D11_FILTER_MIN_MAG_MIP_LINEAR : D3D11_FILTER_MIN_MAG_MIP_POINT; + sampler_desc.AddressU = gfx_cm_to_d3d11(cms); sampler_desc.AddressV = gfx_cm_to_d3d11(cmt); sampler_desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; @@ -672,12 +670,12 @@ static void gfx_d3d11_draw_triangles(float buf_vbo[], size_t buf_vbo_len, size_t d3d.last_resource_views[i] = d3d.textures[d3d.current_texture_ids[i]].resource_view.Get(); d3d.context->PSSetShaderResources(i, 1, d3d.textures[d3d.current_texture_ids[i]].resource_view.GetAddressOf()); -#if THREE_POINT_FILTERING - d3d.per_draw_cb_data.textures[i].width = d3d.textures[d3d.current_texture_ids[i]].width; - d3d.per_draw_cb_data.textures[i].height = d3d.textures[d3d.current_texture_ids[i]].height; - d3d.per_draw_cb_data.textures[i].linear_filtering = d3d.textures[d3d.current_texture_ids[i]].linear_filtering; - textures_changed = true; -#endif + if (d3d.current_filter_mode == THREE_POINT) { + d3d.per_draw_cb_data.textures[i].width = d3d.textures[d3d.current_texture_ids[i]].width; + d3d.per_draw_cb_data.textures[i].height = d3d.textures[d3d.current_texture_ids[i]].height; + d3d.per_draw_cb_data.textures[i].linear_filtering = d3d.textures[d3d.current_texture_ids[i]].linear_filtering; + textures_changed = true; + } if (d3d.last_sampler_states[i].Get() != d3d.textures[d3d.current_texture_ids[i]].sampler_state.Get()) { d3d.last_sampler_states[i] = d3d.textures[d3d.current_texture_ids[i]].sampler_state.Get(); @@ -880,6 +878,15 @@ void gfx_d3d11_select_texture_fb(int fbID) { gfx_d3d11_select_texture(tile, d3d.framebuffers[fbID].texture_id); } +void gfx_d3d11_set_texture_filter(FilteringMode mode) { + d3d.current_filter_mode = mode; + gfx_texture_cache_clear(); +} + +FilteringMode gfx_d3d11_get_texture_filter(void) { + return d3d.current_filter_mode; +} + std::map, uint16_t> gfx_d3d11_get_pixel_depth(int fb_id, const std::set>& coordinates) { Framebuffer& fb = d3d.framebuffers[fb_id]; TextureData& td = d3d.textures[fb.texture_id]; @@ -1019,7 +1026,9 @@ struct GfxRenderingAPI gfx_direct3d11_api = { gfx_d3d11_get_pixel_depth, gfx_d3d11_get_framebuffer_texture_id, gfx_d3d11_select_texture_fb, - gfx_d3d11_delete_texture + gfx_d3d11_delete_texture, + gfx_d3d11_set_texture_filter, + gfx_d3d11_get_texture_filter }; #endif diff --git a/libultraship/Lib/Fast3D/gfx_opengl.cpp b/libultraship/Lib/Fast3D/gfx_opengl.cpp index 6c5f475775b..0c649d56292 100644 --- a/libultraship/Lib/Fast3D/gfx_opengl.cpp +++ b/libultraship/Lib/Fast3D/gfx_opengl.cpp @@ -73,6 +73,7 @@ static uint32_t frame_count; static vector framebuffers; static size_t current_framebuffer; static float current_noise_scale; +static FilteringMode current_filter_mode = THREE_POINT; GLuint pixel_depth_rb, pixel_depth_fb; size_t pixel_depth_rb_size; @@ -211,7 +212,7 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad gfx_cc_get_features(shader_id0, shader_id1, &cc_features); char vs_buf[1024]; - char fs_buf[1024]; + char fs_buf[3000]; size_t vs_len = 0; size_t fs_len = 0; size_t num_floats = 4; @@ -312,21 +313,42 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad append_line(fs_buf, &fs_len, "}"); } + if (current_filter_mode == THREE_POINT) { + append_line(fs_buf, &fs_len, "#define TEX_OFFSET(off) texture2D(tex, texCoord - (off)/texSize)"); + append_line(fs_buf, &fs_len, "vec4 filter3point(in sampler2D tex, in vec2 texCoord, in vec2 texSize) {"); + append_line(fs_buf, &fs_len, " vec2 offset = fract(texCoord*texSize - vec2(0.5));"); + append_line(fs_buf, &fs_len, " offset -= step(1.0, offset.x + offset.y);"); + append_line(fs_buf, &fs_len, " vec4 c0 = TEX_OFFSET(offset);"); + append_line(fs_buf, &fs_len, " vec4 c1 = TEX_OFFSET(vec2(offset.x - sign(offset.x), offset.y));"); + append_line(fs_buf, &fs_len, " vec4 c2 = TEX_OFFSET(vec2(offset.x, offset.y - sign(offset.y)));"); + append_line(fs_buf, &fs_len, " return c0 + abs(offset.x)*(c1-c0) + abs(offset.y)*(c2-c0);"); + append_line(fs_buf, &fs_len, "}"); + append_line(fs_buf, &fs_len, "vec4 hookTexture2D(in sampler2D tex, in vec2 uv, in vec2 texSize) {"); + append_line(fs_buf, &fs_len, " return filter3point(tex, uv, texSize);"); + append_line(fs_buf, &fs_len, "}"); + } else { + append_line(fs_buf, &fs_len, "vec4 hookTexture2D(in sampler2D tex, in vec2 uv, in vec2 texSize) {"); + append_line(fs_buf, &fs_len, " return texture2D(tex, uv);"); + append_line(fs_buf, &fs_len, "}"); + } + append_line(fs_buf, &fs_len, "void main() {"); for (int i = 0; i < 2; i++) { if (cc_features.used_textures[i]) { bool s = cc_features.clamp[i][0], t = cc_features.clamp[i][1]; + + fs_len += sprintf(fs_buf + fs_len, "vec2 texSize%d = textureSize(uTex%d, 0);\n", i, i); + if (!s && !t) { - fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = texture2D(uTex%d, vTexCoord%d);\n", i, i, i); + fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = hookTexture2D(uTex%d, vTexCoord%d, texSize%d);\n", i, i, i, i); } else { - fs_len += sprintf(fs_buf + fs_len, "vec2 texSize%d = textureSize(uTex%d, 0);\n", i, i); if (s && t) { - fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = texture2D(uTex%d, clamp(vTexCoord%d, 0.5 / texSize%d, vec2(vTexClampS%d, vTexClampT%d)));\n", i, i, i, i, i, i); + fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = hookTexture2D(uTex%d, clamp(vTexCoord%d, 0.5 / texSize%d, vec2(vTexClampS%d, vTexClampT%d)), texSize%d);\n", i, i, i, i, i, i, i); } else if (s) { - fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = texture2D(uTex%d, vec2(clamp(vTexCoord%d.s, 0.5 / texSize%d.s, vTexClampS%d), vTexCoord%d.t));\n", i, i, i, i, i, i); + fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = hookTexture2D(uTex%d, vec2(clamp(vTexCoord%d.s, 0.5 / texSize%d.s, vTexClampS%d), vTexCoord%d.t), texSize%d);\n", i, i, i, i, i, i, i); } else { - fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = texture2D(uTex%d, vec2(vTexCoord%d.s, clamp(vTexCoord%d.t, 0.5 / texSize%d.t, vTexClampT%d)));\n", i, i, i, i, i, i); + fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = hookTexture2D(uTex%d, vec2(vTexCoord%d.s, clamp(vTexCoord%d.t, 0.5 / texSize%d.t, vTexClampT%d)), texSize%d);\n", i, i, i, i, i, i, i); } } } @@ -422,9 +444,9 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad GLint max_length = 0; glGetShaderiv(fragment_shader, GL_INFO_LOG_LENGTH, &max_length); char error_log[1024]; - //fprintf(stderr, "Fragment shader compilation failed\n"); + fprintf(stderr, "Fragment shader compilation failed\n"); glGetShaderInfoLog(fragment_shader, max_length, &max_length, &error_log[0]); - //fprintf(stderr, "%s\n", &error_log[0]); + fprintf(stderr, "%s\n", &error_log[0]); abort(); } @@ -552,9 +574,10 @@ static uint32_t gfx_cm_to_opengl(uint32_t val) { } static void gfx_opengl_set_sampler_parameters(int tile, bool linear_filter, uint32_t cms, uint32_t cmt) { + const GLint filter = linear_filter && current_filter_mode == LINEAR ? GL_LINEAR : GL_NEAREST; glActiveTexture(GL_TEXTURE0 + tile); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, linear_filter ? GL_LINEAR : GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, linear_filter ? GL_LINEAR : GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, gfx_cm_to_opengl(cms)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gfx_cm_to_opengl(cmt)); } @@ -823,6 +846,15 @@ static std::map, uint16_t> gfx_opengl_get_pixel_depth(in return res; } +void gfx_opengl_set_texture_filter(FilteringMode mode) { + current_filter_mode = mode; + gfx_texture_cache_clear(); +} + +FilteringMode gfx_opengl_get_texture_filter(void) { + return current_filter_mode; +} + struct GfxRenderingAPI gfx_opengl_api = { gfx_opengl_get_clip_parameters, gfx_opengl_unload_shader, @@ -853,7 +885,9 @@ struct GfxRenderingAPI gfx_opengl_api = { gfx_opengl_get_pixel_depth, gfx_opengl_get_framebuffer_texture_id, gfx_opengl_select_texture_fb, - gfx_opengl_delete_texture + gfx_opengl_delete_texture, + gfx_opengl_set_texture_filter, + gfx_opengl_get_texture_filter }; #endif diff --git a/libultraship/Lib/Fast3D/gfx_rendering_api.h b/libultraship/Lib/Fast3D/gfx_rendering_api.h index 84247fe606f..6318be492a3 100644 --- a/libultraship/Lib/Fast3D/gfx_rendering_api.h +++ b/libultraship/Lib/Fast3D/gfx_rendering_api.h @@ -15,6 +15,12 @@ struct GfxClipParameters { bool invert_y; }; +enum FilteringMode { + THREE_POINT, + LINEAR, + NONE +}; + struct GfxRenderingAPI { struct GfxClipParameters (*get_clip_parameters)(void); void (*unload_shader)(struct ShaderProgram *old_prg); @@ -46,6 +52,8 @@ struct GfxRenderingAPI { void *(*get_framebuffer_texture_id)(int fb_id); void (*select_texture_fb)(int fb_id); void (*delete_texture)(uint32_t texID); + void (*set_texture_filter)(FilteringMode mode); + FilteringMode(*get_texture_filter)(void); }; #endif diff --git a/libultraship/Lib/spdlog/include/spdlog/sinks/sohconsole_sink.h b/libultraship/Lib/spdlog/include/spdlog/sinks/sohconsole_sink.h index 08729f4dcc6..c674495a6f7 100644 --- a/libultraship/Lib/spdlog/include/spdlog/sinks/sohconsole_sink.h +++ b/libultraship/Lib/spdlog/include/spdlog/sinks/sohconsole_sink.h @@ -10,6 +10,7 @@ #include #include "SohImGuiImpl.h" #include "GameSettings.h" +#include "Cvar.h" #include #include #include @@ -45,7 +46,7 @@ class sohconsole_sink final : public base_sink } formatted.push_back('\0'); const char *msg_output = formatted.data(); - if (Game::Settings.debug.soh_sink && SohImGui::console->opened) + if (CVar_GetS32("gSinkEnabled", 0) && SohImGui::console->opened) SohImGui::console->Append("SoH Logging", priority, msg_output); } diff --git a/libultraship/SohConsole.cpp b/libultraship/SohConsole.cpp index 618cd1e1d7b..c360ea968aa 100644 --- a/libultraship/SohConsole.cpp +++ b/libultraship/SohConsole.cpp @@ -106,7 +106,7 @@ void Console::Draw() { if (!this->opened) return; ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver); - ImGui::Begin("Console", &this->opened); + ImGui::Begin("Console", nullptr); const ImVec2 pos = ImGui::GetWindowPos(); const ImVec2 size = ImGui::GetWindowSize(); diff --git a/libultraship/SohImGuiImpl.cpp b/libultraship/SohImGuiImpl.cpp index af506615936..ccb3b4a7578 100644 --- a/libultraship/SohImGuiImpl.cpp +++ b/libultraship/SohImGuiImpl.cpp @@ -43,6 +43,11 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPAR using namespace Ship; bool oldCursorState = true; +#define EXPERIMENTAL() \ + ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 50, 50, 255)); \ + ImGui::Text("Experimental"); \ + ImGui::PopStyleColor(); \ + ImGui::Separator(); #define TOGGLE_BTN ImGuiKey_F1 #define HOOK(b) if(b) needs_save = true; OSContPad* pads; @@ -73,6 +78,12 @@ namespace SohImGui { float navi_prop_i_col[3] = { 0.0f, 0.0f, 0.0f }; float navi_prop_o_col[3] = { 0.0f, 0.0f, 0.0f }; + const char* filters[3] = { + "Three-Point", + "Linear", + "None" + }; + std::map> windowCategories; std::map customWindows; @@ -85,7 +96,7 @@ namespace SohImGui { ImGui_ImplWin32_Init(impl.dx11.window); break; } - + // OTRTODO: This gameplay specific stuff should not be in libultraship. This needs to be moved to soh and use sTunicColors kokiri_col[0] = 30 / 255.0f; kokiri_col[1] = 105 / 255.0f; @@ -94,7 +105,7 @@ namespace SohImGui { goron_col[0] = 100 / 255.0f; goron_col[1] = 20 / 255.0f; goron_col[2] = 0; - + zora_col[0] = 0; zora_col[1] = 60 / 255.0f; zora_col[2] = 100 / 255.0f; @@ -201,7 +212,7 @@ namespace SohImGui { return; } - if (d == Dialogues::dConsole && Game::Settings.debug.menu_bar) { + if (d == Dialogues::dConsole && CVar_GetS32("gOpenMenuBar", 0)) { return; } if (!GlobalCtx2::GetInstance()->GetWindow()->IsFullscreen()) { @@ -280,8 +291,8 @@ namespace SohImGui { } void Init(WindowImpl window_impl) { - impl = window_impl; Game::LoadSettings(); + impl = window_impl; ImGuiContext* ctx = ImGui::CreateContext(); ImGui::SetCurrentContext(ctx); io = &ImGui::GetIO(); @@ -296,7 +307,7 @@ namespace SohImGui { ModInternal::registerHookListener({ GFX_INIT, [](const HookEvent ev) { if (GlobalCtx2::GetInstance()->GetWindow()->IsFullscreen()) - ShowCursor(Game::Settings.debug.menu_bar, Dialogues::dLoadSettings); + ShowCursor(CVar_GetS32("gOpenMenuBar", 0), Dialogues::dLoadSettings); LoadTexture("Game_Icon", "assets/ship_of_harkinian/icons/gSohIcon.png"); LoadTexture("A-Btn", "assets/ship_of_harkinian/buttons/ABtn.png"); @@ -320,7 +331,7 @@ namespace SohImGui { ModInternal::registerHookListener({ CONTROLLER_READ, [](const HookEvent ev) { pads = static_cast(ev->baseArgs["cont_pad"]); - } }); + }}); Game::InitSettings(); } @@ -334,7 +345,7 @@ namespace SohImGui { #define BindButton(btn, status) ImGui::Image(GetTextureByID(DefaultAssets[btn]->textureId), ImVec2(16.0f * scale, 16.0f * scale), ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, (status) ? 255 : 0)); - void BindAudioSlider(const char* name, const char* key, float defaultValue, SeqPlayers playerId) + void BindAudioSlider(const char* name, const char* key, float defaultValue, SeqPlayers playerId) { float value = CVar_GetFloat(key, defaultValue); @@ -380,7 +391,7 @@ namespace SohImGui { ImGui::Text(text.c_str(), val); - if (ImGui::SliderInt(id.c_str(), &val, min, max, format.c_str())) + if (ImGui::SliderInt(id.c_str(), &val, min, max, format.c_str())) { CVar_SetS32(cvarName.c_str(), val); needs_save = true; @@ -443,7 +454,7 @@ namespace SohImGui { colors[2] = b / 255.0f; { - if (ImGui::ColorEdit3(text.c_str(), colors)) + if (ImGui::ColorEdit3(text.c_str(), colors)) { CVar_SetS32((cvarName + "_Red").c_str(), (int)(colors[0] * 255)); CVar_SetS32((cvarName + "_Green").c_str(), (int)(colors[1] * 255)); @@ -463,7 +474,7 @@ namespace SohImGui { ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus | ImGuiWindowFlags_NoResize; - if (Game::Settings.debug.menu_bar) window_flags |= ImGuiWindowFlags_MenuBar; + if (CVar_GetS32("gOpenMenuBar", 0)) window_flags |= ImGuiWindowFlags_MenuBar; const ImGuiViewport* viewport = ImGui::GetMainViewport(); ImGui::SetNextWindowPos(viewport->WorkPos); @@ -491,10 +502,11 @@ namespace SohImGui { ImGui::DockSpace(dockId, ImVec2(0.0f, 0.0f), ImGuiDockNodeFlags_None); if (ImGui::IsKeyPressed(TOGGLE_BTN)) { - Game::Settings.debug.menu_bar = !Game::Settings.debug.menu_bar; + bool menu_bar = CVar_GetS32("gOpenMenuBar", 0); + CVar_SetS32("gOpenMenuBar", !menu_bar); needs_save = true; - GlobalCtx2::GetInstance()->GetWindow()->dwMenubar = Game::Settings.debug.menu_bar; - ShowCursor(Game::Settings.debug.menu_bar, Dialogues::dMenubar); + GlobalCtx2::GetInstance()->GetWindow()->dwMenubar = menu_bar; + ShowCursor(menu_bar, Dialogues::dMenubar); } if (ImGui::BeginMenuBar()) { @@ -563,9 +575,41 @@ namespace SohImGui { ImGui::EndMenu(); } - if (ImGui::BeginMenu("Enhancements")) + if (ImGui::BeginMenu("Graphics")) { + EnhancementSliderInt("Internal Resolution: %dx", "##IMul", "gInternalResolution", 1, 8, ""); + gfx_current_dimensions.internal_mul = CVar_GetS32("gInternalResolution", 1); + EnhancementSliderInt("MSAA: %d", "##IMSAA", "gMSAAValue", 1, 8, ""); + gfx_msaa_level = CVar_GetS32("gMSAAValue", 1); + + EXPERIMENTAL(); + ImGui::Text("Texture Filter (Needs reload)"); + GfxRenderingAPI* gapi = gfx_get_current_rendering_api(); + if (ImGui::BeginCombo("##filters", filters[gapi->get_texture_filter()])) { + for (int fId = 0; fId <= FilteringMode::NONE; fId++) { + if (ImGui::Selectable(filters[fId], fId == gapi->get_texture_filter())) { + INFO("New Filter: %s", filters[fId]); + gapi->set_texture_filter((FilteringMode)fId); + + CVar_SetS32("gTextureFilter", (int) fId); + needs_save = true; + } + } + ImGui::EndCombo(); + } + ImGui::EndMenu(); + } + + if (ImGui::BeginMenu("Languages")) { + EnhancementRadioButton("English", "gLanguages", 0); + EnhancementRadioButton("German", "gLanguages", 1); + EnhancementRadioButton("French", "gLanguages", 2); + ImGui::EndMenu(); + } + + if (ImGui::BeginMenu("Enhancements")) + { ImGui::Text("Gameplay"); ImGui::Separator(); @@ -583,35 +627,43 @@ namespace SohImGui { EnhancementCheckbox("N64 Mode", "gN64Mode"); EnhancementCheckbox("Animated Link in Pause Menu", "gPauseLiveLink"); - EnhancementCheckbox("Disable LOD", "gDisableLOD"); EnhancementCheckbox("Enable 3D Dropped items", "gNewDrops"); EnhancementCheckbox("Dynamic Wallet Icon", "gDynamicWalletIcon"); EnhancementCheckbox("Always show dungeon entrances", "gAlwaysShowDungeonMinimapIcon"); - - if (ImGui::BeginMenu("Fixes")) { - EnhancementCheckbox("Fix L&R Pause menu", "gUniformLR"); - EnhancementCheckbox("Fix Dungeon entrances", "gFixDungeonMinimapIcon"); - ImGui::EndMenu(); - } - ImGui::EndMenu(); - } - if (ImGui::BeginMenu("Developer Tools")) - { - HOOK(ImGui::MenuItem("Stats", nullptr, &Game::Settings.debug.soh)); - HOOK(ImGui::MenuItem("Console", nullptr, &console->opened)); - - ImGui::Text("Debug"); + ImGui::Text("Fixes"); ImGui::Separator(); + EnhancementCheckbox("Fix L&R Pause menu", "gUniformLR"); + EnhancementCheckbox("Fix Dungeon entrances", "gFixDungeonMinimapIcon"); - EnhancementCheckbox("Debug Mode", "gDebugEnabled"); + EXPERIMENTAL(); + + EnhancementCheckbox("Disable LOD", "gDisableLOD"); ImGui::EndMenu(); } - if (ImGui::BeginMenu("Graphics")) + if (ImGui::BeginMenu("Cosmetics")) { - HOOK(ImGui::MenuItem("Anti-aliasing", nullptr, &Game::Settings.graphics.show)); + ImGui::Text("Tunics"); + ImGui::Separator(); + + EnhancementColor3("Kokiri Tunic", "gTunic_Kokiri", kokiri_col); + EnhancementColor3("Goron Tunic", "gTunic_Goron", goron_col); + EnhancementColor3("Zora Tunic", "gTunic_Zora", zora_col); + + ImGui::Text("Navi"); + ImGui::Separator(); + + EnhancementColor3("Navi Idle Inner", "gNavi_Idle_Inner", navi_idle_i_col); + EnhancementColor3("Navi Idle Outer", "gNavi_Idle_Outer", navi_idle_o_col); + EnhancementColor3("Navi NPC Inner", "gNavi_NPC_Inner", navi_npc_i_col); + EnhancementColor3("Navi NPC Outer", "gNavi_NPC_Outer", navi_npc_o_col); + EnhancementColor3("Navi Enemy Inner", "gNavi_Enemy_Inner", navi_enemy_i_col); + EnhancementColor3("Navi Enemy Outer", "gNavi_Enemy_Outer", navi_enemy_o_col); + EnhancementColor3("Navi Prop Inner", "gNavi_Prop_Inner", navi_prop_i_col); + EnhancementColor3("Navi Prop Outer", "gNavi_Prop_Outer", navi_prop_o_col); + ImGui::EndMenu(); } @@ -636,51 +688,27 @@ namespace SohImGui { EnhancementCheckbox("Freeze Time", "gFreezeTime"); ImGui::EndMenu(); - } - if (ImGui::BeginMenu("Cosmetics")) + if (ImGui::BeginMenu("Developer Tools")) { - ImGui::Text("Tunics"); - ImGui::Separator(); - - EnhancementColor3("Kokiri Tunic", "gTunic_Kokiri", kokiri_col); - EnhancementColor3("Goron Tunic", "gTunic_Goron", goron_col); - EnhancementColor3("Zora Tunic", "gTunic_Zora", zora_col); - - ImGui::Text("Navi"); - ImGui::Separator(); - - EnhancementColor3("Navi Idle Inner", "gNavi_Idle_Inner", navi_idle_i_col); - EnhancementColor3("Navi Idle Outer", "gNavi_Idle_Outer", navi_idle_o_col); - EnhancementColor3("Navi NPC Inner", "gNavi_NPC_Inner", navi_npc_i_col); - EnhancementColor3("Navi NPC Outer", "gNavi_NPC_Outer", navi_npc_o_col); - EnhancementColor3("Navi Enemy Inner", "gNavi_Enemy_Inner", navi_enemy_i_col); - EnhancementColor3("Navi Enemy Outer", "gNavi_Enemy_Outer", navi_enemy_o_col); - EnhancementColor3("Navi Prop Inner", "gNavi_Prop_Inner", navi_prop_i_col); - EnhancementColor3("Navi Prop Outer", "gNavi_Prop_Outer", navi_prop_o_col); - - ImGui::EndMenu(); - } + EnhancementCheckbox("Stats", "gStatsEnabled"); + EnhancementCheckbox("Console", "gConsoleEnabled"); + console->opened = CVar_GetS32("gConsoleEnabled", 0); + EnhancementCheckbox("OoT Debug Mode", "gDebugEnabled"); - if (CVar_GetS32("gLanguages", 0) == 0) { - SelectedLanguage = 0; - } else if (CVar_GetS32("gLanguages", 0) == 1) { - SelectedLanguage = 1; - } else if (CVar_GetS32("gLanguages", 0) == 2) { - SelectedLanguage = 2; - } - if (ImGui::BeginMenu("Languages")) { - EnhancementRadioButton("English", "gLanguages", 0); - EnhancementRadioButton("German", "gLanguages", 1); - EnhancementRadioButton("French", "gLanguages", 2); ImGui::EndMenu(); } for (const auto& category : windowCategories) { if (ImGui::BeginMenu(category.first.c_str())) { for (const std::string& name : category.second) { - HOOK(ImGui::MenuItem(name.c_str(), nullptr, &customWindows[name].enabled)); + std::string varName(name); + varName.erase(std::ranges::remove_if(varName, isspace).begin(), varName.end()); + std::string toggleName = "g" + varName + "Enabled"; + + EnhancementCheckbox(name, toggleName); + customWindows[name].enabled = CVar_GetS32(toggleName.c_str(), 0); } ImGui::EndMenu(); } @@ -691,7 +719,7 @@ namespace SohImGui { ImGui::End(); - if (Game::Settings.debug.soh) { + if (CVar_GetS32("gStatsEnabled", 0)) { const float framerate = ImGui::GetIO().Framerate; ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0)); ImGui::Begin("Debug Stats", nullptr, ImGuiWindowFlags_None); @@ -702,17 +730,6 @@ namespace SohImGui { ImGui::PopStyleColor(); } - if (Game::Settings.graphics.show) { - ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0)); - ImGui::Begin("Anti-aliasing settings", nullptr, ImGuiWindowFlags_None); - ImGui::Text("Internal Resolution:"); - ImGui::SliderInt("Mul", reinterpret_cast(&gfx_current_dimensions.internal_mul), 1, 8); - ImGui::Text("MSAA:"); - ImGui::SliderInt("MSAA", reinterpret_cast(&gfx_msaa_level), 1, 8); - ImGui::End(); - ImGui::PopStyleColor(); - } - console->Draw(); for (auto& windowIter : customWindows) {