From 20d8c6a6e69738770ed4b46f08d36b37e60edc0b Mon Sep 17 00:00:00 2001 From: KiritoDv Date: Wed, 4 Oct 2023 23:19:30 -0600 Subject: [PATCH] Added more options --- CMakeLists.txt | 3 - src/game/rendering_graph_node.c | 4 + src/game/shadow.c | 8 +- src/port/ui/ImguiUI.cpp | 283 +++++++++++++++++++++++++++----- 4 files changed, 250 insertions(+), 48 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 852cc81d..38f7267b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,9 +44,6 @@ endif() # Set game compilation version set(VERSION us) -# Add the tools subdirectory to the build -add_subdirectory(tools) - # Add compile definitions for the target add_compile_definitions( VERSION_US=1 diff --git a/src/game/rendering_graph_node.c b/src/game/rendering_graph_node.c index eea7246a..0ccccf44 100644 --- a/src/game/rendering_graph_node.c +++ b/src/game/rendering_graph_node.c @@ -277,6 +277,10 @@ static void geo_process_level_of_detail(struct GraphNodeLevelOfDetail *node) { s16 distanceFromCam = -GET_HIGH_S16_OF_32(mtx->m[1][3]); // z-component of the translation column #endif + if(CVarGetInteger("gDisableLOD", 0) == 1) { + node->minDistance = 0; + } + if (node->minDistance <= distanceFromCam && distanceFromCam < node->maxDistance) { if (node->node.children != 0) { geo_process_node_and_siblings(node->node.children); diff --git a/src/game/shadow.c b/src/game/shadow.c index 049791c3..1ca18de5 100644 --- a/src/game/shadow.c +++ b/src/game/shadow.c @@ -206,7 +206,7 @@ s8 init_shadow(struct Shadow *s, f32 xPos, f32 yPos, f32 zPos, s16 shadowScale, s->parentY = yPos; s->parentZ = zPos; - s->floorHeight = find_floor_height_and_data(s->parentX, s->parentY, s->parentZ, &floorGeometry); + s->floorHeight = find_floor_height_and_data(s->parentX, s->parentY, s->parentZ, &floorGeometry) + 0.4f; if (gEnvironmentRegions != NULL) { waterLevel = get_water_level_below_shadow(s); @@ -384,7 +384,7 @@ void calculate_vertex_xyz(s8 index, struct Shadow s, f32 *xPosVtx, f32 *yPosVtx, // Clamp this vertex's y-position to that of the floor directly // below it, which may differ from the floor below the center // vertex. - *yPosVtx = find_floor_height_and_data(*xPosVtx, s.parentY, *zPosVtx, &dummy); + *yPosVtx = find_floor_height_and_data(*xPosVtx, s.parentY, *zPosVtx, &dummy) + 0.4f; break; case SHADOW_WITH_4_VERTS: // Do not clamp. Instead, extrapolate the y-position of this @@ -700,7 +700,7 @@ Gfx *create_shadow_circle_assuming_flat_ground(f32 xPos, f32 yPos, f32 zPos, s16 Gfx *displayList; struct FloorGeometry *dummy; // only for calling find_floor_height_and_data f32 distBelowFloor; - f32 floorHeight = find_floor_height_and_data(xPos, yPos, zPos, &dummy); + f32 floorHeight = find_floor_height_and_data(xPos, yPos, zPos, &dummy) + 0.4f; f32 radius = shadowScale / 2; if (floorHeight < FLOOR_LOWER_LIMIT_SHADOW) { @@ -760,7 +760,7 @@ Gfx *create_shadow_rectangle(f32 halfWidth, f32 halfLength, f32 relY, u8 solidit s32 get_shadow_height_solidity(f32 xPos, f32 yPos, f32 zPos, f32 *shadowHeight, u8 *solidity) { struct FloorGeometry *dummy; f32 waterLevel; - *shadowHeight = find_floor_height_and_data(xPos, yPos, zPos, &dummy); + *shadowHeight = find_floor_height_and_data(xPos, yPos, zPos, &dummy) + 0.4f; if (*shadowHeight < FLOOR_LOWER_LIMIT_SHADOW) { return 1; diff --git a/src/port/ui/ImguiUI.cpp b/src/port/ui/ImguiUI.cpp index f6ff69db..d81ffc7d 100644 --- a/src/port/ui/ImguiUI.cpp +++ b/src/port/ui/ImguiUI.cpp @@ -46,57 +46,258 @@ void Destroy() { } } -void GameMenuBar::DrawElement() { - if(ImGui::BeginMenuBar()){ - if(ImGui::BeginMenu("Settings")){ - if (ImGui::BeginMenu("Audio")) { - UIWidgets::PaddedEnhancementSliderFloat("Master Volume: %d %%", "##Master_Vol", "gGameMasterVolume", 0.0f, 1.0f, "", 1.0f, true, true, false, true); - if (UIWidgets::PaddedEnhancementSliderFloat("Main Music Volume: %d %%", "##Main_Music_Vol", "gMainMusicVolume", 0.0f, 1.0f, "", 1.0f, true, true, false, true)) { - audio_set_player_volume(SEQ_PLAYER_LEVEL, CVarGetFloat("gMainMusicVolume", 1.0f)); - } - if (UIWidgets::PaddedEnhancementSliderFloat("Sound Effects Volume: %d %%", "##Sound_Effect_Vol", "gSFXMusicVolume", 0.0f, 1.0f, "", 1.0f, true, true, false, true)) { - audio_set_player_volume(SEQ_PLAYER_SFX, CVarGetFloat("gSFXMusicVolume", 1.0f)); - } - if (UIWidgets::PaddedEnhancementSliderFloat("Environment Volume: %d %%", "##Environment_Vol", "gEnvironmentVolume", 0.0f, 1.0f, "", 1.0f, true, true, false, true)) { - audio_set_player_volume(SEQ_PLAYER_ENV, CVarGetFloat("gEnvironmentVolume", 1.0f)); - } +static const char* filters[3] = { +#ifdef __WIIU__ + "", +#else + "Three-Point", +#endif + "Linear", "None" +}; - static std::unordered_map audioBackendNames = { - { LUS::AudioBackend::WASAPI, "Windows Audio Session API" }, - { LUS::AudioBackend::PULSE, "PulseAudio" }, - { LUS::AudioBackend::SDL, "SDL" }, - }; - - ImGui::Text("Audio API (Needs reload)"); - auto currentAudioBackend = LUS::Context::GetInstance()->GetAudio()->GetAudioBackend(); - - if (LUS::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->size() <= 1) { - UIWidgets::DisableComponent(ImGui::GetStyle().Alpha * 0.5f); - } - if (ImGui::BeginCombo("##AApi", audioBackendNames[currentAudioBackend])) { - for (uint8_t i = 0; i < LUS::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->size(); i++) { - auto backend = LUS::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->data()[i]; - if (ImGui::Selectable(audioBackendNames[backend], backend == currentAudioBackend)) { - LUS::Context::GetInstance()->GetAudio()->SetAudioBackend(backend); - } - } - ImGui::EndCombo(); - } - if (LUS::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->size() <= 1) { - UIWidgets::ReEnableComponent(""); - } - - ImGui::EndMenu(); +void DrawSettingsMenu(){ + if(ImGui::BeginMenu("Settings")){ + if (ImGui::BeginMenu("Audio")) { + UIWidgets::PaddedEnhancementSliderFloat("Master Volume: %d %%", "##Master_Vol", "gGameMasterVolume", 0.0f, 1.0f, "", 1.0f, true, true, false, true); + if (UIWidgets::PaddedEnhancementSliderFloat("Main Music Volume: %d %%", "##Main_Music_Vol", "gMainMusicVolume", 0.0f, 1.0f, "", 1.0f, true, true, false, true)) { + audio_set_player_volume(SEQ_PLAYER_LEVEL, CVarGetFloat("gMainMusicVolume", 1.0f)); + } + if (UIWidgets::PaddedEnhancementSliderFloat("Sound Effects Volume: %d %%", "##Sound_Effect_Vol", "gSFXMusicVolume", 0.0f, 1.0f, "", 1.0f, true, true, false, true)) { + audio_set_player_volume(SEQ_PLAYER_SFX, CVarGetFloat("gSFXMusicVolume", 1.0f)); + } + if (UIWidgets::PaddedEnhancementSliderFloat("Environment Volume: %d %%", "##Environment_Vol", "gEnvironmentVolume", 0.0f, 1.0f, "", 1.0f, true, true, false, true)) { + audio_set_player_volume(SEQ_PLAYER_ENV, CVarGetFloat("gEnvironmentVolume", 1.0f)); } + static std::unordered_map audioBackendNames = { + { LUS::AudioBackend::WASAPI, "Windows Audio Session API" }, + { LUS::AudioBackend::PULSE, "PulseAudio" }, + { LUS::AudioBackend::SDL, "SDL" }, + }; + + ImGui::Text("Audio API (Needs reload)"); + auto currentAudioBackend = LUS::Context::GetInstance()->GetAudio()->GetAudioBackend(); + + if (LUS::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->size() <= 1) { + UIWidgets::DisableComponent(ImGui::GetStyle().Alpha * 0.5f); + } + if (ImGui::BeginCombo("##AApi", audioBackendNames[currentAudioBackend])) { + for (uint8_t i = 0; i < LUS::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->size(); i++) { + auto backend = LUS::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->data()[i]; + if (ImGui::Selectable(audioBackendNames[backend], backend == currentAudioBackend)) { + LUS::Context::GetInstance()->GetAudio()->SetAudioBackend(backend); + } + } + ImGui::EndCombo(); + } + if (LUS::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->size() <= 1) { + UIWidgets::ReEnableComponent(""); + } + + ImGui::EndMenu(); + } + + UIWidgets::Spacer(0); + + if (ImGui::BeginMenu("Controller")) { + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2 (12.0f, 6.0f)); + ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0f, 0.0f)); + ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f); + ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.22f, 0.38f, 0.56f, 1.0f)); if (GameUI::mInputEditorWindow) { if (ImGui::Button("Controller Mapping", ImVec2 (-1.0f, 0.0f))) { GameUI::mInputEditorWindow->ToggleVisibility(); } } - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetGameOverlay()->DrawSettings(); + UIWidgets::PaddedSeparator(); + ImGui::PopStyleColor(1); + ImGui::PopStyleVar(3); +#ifndef __SWITCH__ + UIWidgets::EnhancementCheckbox("Menubar Controller Navigation", "gControlNav"); + UIWidgets::Tooltip("Allows controller navigation of the SOH menu bar (Settings, Enhancements,...)\nCAUTION: This will disable game inputs while the menubar is visible.\n\nD-pad to move between items, A to select, and X to grab focus on the menu bar"); +#endif + UIWidgets::PaddedEnhancementCheckbox("Show Inputs", "gInputEnabled", true, false); + UIWidgets::Tooltip("Shows currently pressed inputs on the bottom right of the screen"); + UIWidgets::PaddedEnhancementSliderFloat("Input Scale: %.1f", "##Input", "gInputScale", 1.0f, 3.0f, "", 1.0f, false, true, true, false); + UIWidgets::Tooltip("Sets the on screen size of the displayed inputs from the Show Inputs setting"); + ImGui::EndMenu(); } + + ImGui::EndMenu(); + } + + UIWidgets::Spacer(0); + + ImGui::SetCursorPosY(0.0f); + if (ImGui::BeginMenu("Graphics")) { +#ifndef __APPLE__ + UIWidgets::EnhancementSliderFloat("Internal Resolution: %d %%", "##IMul", "gInternalResolution", 0.5f, 2.0f, "", 1.0f, true); + UIWidgets::Tooltip("Multiplies your output resolution by the value inputted, as a more intensive but effective form of anti-aliasing"); + // OTRTODO: fix this + // LUS::SetResolutionMultiplier(CVarGetFloat("gInternalResolution", 1)); +#endif +#ifndef __WIIU__ + UIWidgets::PaddedEnhancementSliderInt("MSAA: %d", "##IMSAA", "gMSAAValue", 1, 8, "", 1, true, true, false); + UIWidgets::Tooltip("Activates multi-sample anti-aliasing when above 1x up to 8x for 8 samples for every pixel"); + // OTRTODO: fix this + // LUS::SetMSAALevel(CVarGetInteger("gMSAAValue", 1)); +#endif + UIWidgets::Tooltip("Matches interpolation value to the current game's window refresh rate"); + + if (LUS::Context::GetInstance()->GetWindow()->GetWindowBackend() == LUS::WindowBackend::DX11) { + UIWidgets::PaddedEnhancementSliderInt(CVarGetInteger("gExtraLatencyThreshold", 80) == 0 ? "Jitter fix: Off" : "Jitter fix: >= %d FPS", + "##ExtraLatencyThreshold", "gExtraLatencyThreshold", 0, 360, "", 80, true, true, false); + UIWidgets::Tooltip("When Interpolation FPS setting is at least this threshold, add one frame of input lag (e.g. 16.6 ms for 60 FPS) in order to avoid jitter. This setting allows the CPU to work on one frame while GPU works on the previous frame.\nThis setting should be used when your computer is too slow to do CPU + GPU work in time."); + } + + UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f); + + + static std::unordered_map windowBackendNames = { + { LUS::WindowBackend::DX11, "DirectX" }, + { LUS::WindowBackend::SDL_OPENGL, "OpenGL"}, + { LUS::WindowBackend::SDL_METAL, "Metal" }, + { LUS::WindowBackend::GX2, "GX2"} + }; + + ImGui::Text("Renderer API (Needs reload)"); + LUS::WindowBackend runningWindowBackend = LUS::Context::GetInstance()->GetWindow()->GetWindowBackend(); + LUS::WindowBackend configWindowBackend; + int configWindowBackendId = LUS::Context::GetInstance()->GetConfig()->GetInt("Window.Backend.Id", -1); + if (configWindowBackendId != -1 && configWindowBackendId < static_cast(LUS::WindowBackend::BACKEND_COUNT)) { + configWindowBackend = static_cast(configWindowBackendId); + } else { + configWindowBackend = runningWindowBackend; + } + + if (LUS::Context::GetInstance()->GetWindow()->GetAvailableWindowBackends()->size() <= 1) { + UIWidgets::DisableComponent(ImGui::GetStyle().Alpha * 0.5f); + } + if (ImGui::BeginCombo("##RApi", windowBackendNames[configWindowBackend])) { + for (size_t i = 0; i < LUS::Context::GetInstance()->GetWindow()->GetAvailableWindowBackends()->size(); i++) { + auto backend = LUS::Context::GetInstance()->GetWindow()->GetAvailableWindowBackends()->data()[i]; + if (ImGui::Selectable(windowBackendNames[backend], backend == configWindowBackend)) { + LUS::Context::GetInstance()->GetConfig()->SetInt("Window.Backend.Id", static_cast(backend)); + LUS::Context::GetInstance()->GetConfig()->SetString("Window.Backend.Name", + windowBackendNames[backend]); + LUS::Context::GetInstance()->GetConfig()->Save(); + } + } + ImGui::EndCombo(); + } + if (LUS::Context::GetInstance()->GetWindow()->GetAvailableWindowBackends()->size() <= 1) { + UIWidgets::ReEnableComponent(""); + } + + if (LUS::Context::GetInstance()->GetWindow()->CanDisableVerticalSync()) { + UIWidgets::PaddedEnhancementCheckbox("Enable Vsync", "gVsyncEnabled", true, false); + } + + if (LUS::Context::GetInstance()->GetWindow()->SupportsWindowedFullscreen()) { + UIWidgets::PaddedEnhancementCheckbox("Windowed fullscreen", "gSdlWindowedFullscreen", true, false); + } + + if (LUS::Context::GetInstance()->GetWindow()->GetGui()->SupportsViewports()) { + UIWidgets::PaddedEnhancementCheckbox("Allow multi-windows", "gEnableMultiViewports", true, false, false, "", UIWidgets::CheckboxGraphics::Cross, true); + UIWidgets::Tooltip("Allows windows to be able to be dragged off of the main game window. Requires a reload to take effect."); + } + + // If more filters are added to LUS, make sure to add them to the filters list here + ImGui::Text("Texture Filter (Needs reload)"); + + UIWidgets::EnhancementCombobox("gTextureFilter", filters, 0); + + UIWidgets::Spacer(0); + + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetGameOverlay()->DrawSettings(); + + ImGui::EndMenu(); + } +} + +void DrawMenuBarIcon() { + static bool gameIconLoaded = false; + if (!gameIconLoaded) { + LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTexture("Game_Icon", "textures/icons/gIcon.png"); + gameIconLoaded = true; + } + + if (LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Game_Icon")) { +#ifdef __SWITCH__ + ImVec2 iconSize = ImVec2(20.0f, 20.0f); + float posScale = 1.0f; +#elif defined(__WIIU__) + ImVec2 iconSize = ImVec2(16.0f * 2, 16.0f * 2); + float posScale = 2.0f; +#else + ImVec2 iconSize = ImVec2(16.0f, 16.0f); + float posScale = 1.0f; +#endif + ImGui::SetCursorPos(ImVec2(5, 2.5f) * posScale); + ImGui::Image(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Game_Icon"), iconSize); + ImGui::SameLine(); + ImGui::SetCursorPos(ImVec2(25, 0) * posScale); + } +} + +void DrawGameMenu() { + if (ImGui::BeginMenu("Ghostship")) { + if (ImGui::MenuItem("Reset", +#ifdef __APPLE__ + "Command-R" +#else + "Ctrl+R" +#endif + )) { + std::reinterpret_pointer_cast(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console"))->Dispatch("reset"); + } +#if !defined(__SWITCH__) && !defined(__WIIU__) + + if (ImGui::MenuItem("Toggle Fullscreen", "F9")) { + LUS::Context::GetInstance()->GetWindow()->ToggleFullscreen(); + } + + if (ImGui::MenuItem("Quit")) { + LUS::Context::GetInstance()->GetWindow()->Close(); + } +#endif + ImGui::EndMenu(); + } +} + +void DrawEnhancementsMenu() { + if (ImGui::BeginMenu("Enhancements")) { + + if (ImGui::BeginMenu("Gameplay")) { + UIWidgets::PaddedEnhancementCheckbox("No Level of Detail (LOD)", "gDisableLOD", true, false); + UIWidgets::Tooltip("Disable Level of Detail (LOD) to avoid models using lower poly versions at a distance"); + ImGui::EndMenu(); + } + + ImGui::EndMenu(); + } +} + +void GameMenuBar::DrawElement() { + if(ImGui::BeginMenuBar()){ + DrawMenuBarIcon(); + + static ImVec2 sWindowPadding(8.0f, 8.0f); + + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, sWindowPadding); + + DrawGameMenu(); + + ImGui::SetCursorPosY(0.0f); + + DrawSettingsMenu(); + + ImGui::SetCursorPosY(0.0f); + + DrawEnhancementsMenu(); + + ImGui::PopStyleVar(1); ImGui::EndMenuBar(); } } \ No newline at end of file