diff --git a/config_spec.yml b/config_spec.yml index b858606e685..b8090035d18 100644 --- a/config_spec.yml +++ b/config_spec.yml @@ -253,3 +253,9 @@ perf: cache_shaders: type: bool default: true + override_clockspeed: + type: bool + default: false + cpu_clockspeed_scale: + type: number + default: 1 diff --git a/hw/i386/x86.c b/hw/i386/x86.c index 018fbb8b0ae..6c5e27dc02a 100644 --- a/hw/i386/x86.c +++ b/hw/i386/x86.c @@ -59,6 +59,10 @@ #include CONFIG_DEVICES #include "kvm/kvm_i386.h" +#ifdef XBOX +#include "ui/xemu-settings.h" +#endif + /* Physical Address of PVH entry point read from kernel ELF NOTE */ static size_t pvh_start_addr; @@ -532,8 +536,12 @@ static long get_file_size(FILE *f) uint64_t cpu_get_tsc(CPUX86State *env) { #ifdef XBOX - return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 733333333, - NANOSECONDS_PER_SECOND); + int cpu_clock_hz = 733333333; + + if (g_config.perf.override_clockspeed) { + cpu_clock_hz *= g_config.perf.cpu_clockspeed_scale; + } + return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), cpu_clock_hz, NANOSECONDS_PER_SECOND); #else return cpus_get_elapsed_ticks(); #endif diff --git a/ui/xui/compat.cc b/ui/xui/compat.cc index d0405389f53..34f5ac965b5 100644 --- a/ui/xui/compat.cc +++ b/ui/xui/compat.cc @@ -203,6 +203,14 @@ void CompatibilityReporter::Draw() ImGui::SameLine(); } + if (g_config.perf.override_clockspeed) { + ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); + ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f); + + ImGui::Text("Reports cannot be made while using altered CPU clock speeds"); + ImGui::SameLine(); + } + ImGui::SetCursorPosX(ImGui::GetWindowWidth()-(120+10)*g_viewport_mgr.m_scale); ImGui::SetItemDefaultFocus(); @@ -213,7 +221,10 @@ void CompatibilityReporter::Draw() is_open = false; } } - + if (g_config.perf.override_clockspeed) { + ImGui::PopItemFlag(); + ImGui::PopStyleVar(); + } ImGui::End(); } diff --git a/ui/xui/main-menu.cc b/ui/xui/main-menu.cc index 75b88cafb6e..5c6f9dde42b 100644 --- a/ui/xui/main-menu.cc +++ b/ui/xui/main-menu.cc @@ -66,6 +66,17 @@ void MainMenuGeneralView::Draw() Toggle("Cache shaders to disk", &g_config.perf.cache_shaders, "Reduce stutter in games by caching previously generated shaders"); + Toggle("Emulated CPU clock override", &g_config.perf.override_clockspeed, + "Enables to override default CPU clock speed"); + + char buf[32]; + snprintf(buf, sizeof(buf), "Clock Speed %d%% (%.2f MHz)", (int)(g_config.perf.cpu_clockspeed_scale * 100), (733333333 * g_config.perf.cpu_clockspeed_scale) / 1000000); + Slider("Virtual CPU clock", &g_config.perf.cpu_clockspeed_scale, buf, 0.01f, 2.f, 0.01f); + + if (fabs(g_config.perf.cpu_clockspeed_scale - 1.f) <= 0.0099f) { + g_config.perf.cpu_clockspeed_scale = 1; + } + SectionTitle("Miscellaneous"); Toggle("Skip startup animation", &g_config.general.skip_boot_anim, "Skip the full Xbox boot animation sequence"); diff --git a/ui/xui/widgets.cc b/ui/xui/widgets.cc index 67430ecda8a..3809a4a227f 100644 --- a/ui/xui/widgets.cc +++ b/ui/xui/widgets.cc @@ -22,6 +22,7 @@ #include "viewport-manager.hh" #include "ui/xemu-os-utils.h" #include "gl-helpers.hh" +#include void Separator() { @@ -222,8 +223,9 @@ bool Toggle(const char *str_id, bool *v, const char *description) return status; } -void Slider(const char *str_id, float *v, const char *description) +void Slider(const char *str_id, float *v, const char *description, float min, float max, float increment) { + float x = (*v - min) / (max - min); ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32_BLACK_TRANS); ImGuiStyle &style = ImGui::GetStyle(); @@ -261,13 +263,13 @@ void Slider(const char *str_id, float *v, const char *description) ImGui::IsKeyPressed(ImGuiKey_GamepadDpadLeft) || ImGui::IsKeyPressed(ImGuiKey_GamepadLStickLeft) || ImGui::IsKeyPressed(ImGuiKey_GamepadRStickLeft)) { - *v -= 0.05; + x -= increment / max; } if (ImGui::IsKeyPressed(ImGuiKey_RightArrow) || ImGui::IsKeyPressed(ImGuiKey_GamepadDpadRight) || ImGui::IsKeyPressed(ImGuiKey_GamepadLStickRight) || ImGui::IsKeyPressed(ImGuiKey_GamepadRStickRight)) { - *v += 0.05; + x += increment / max; } if ( @@ -286,10 +288,11 @@ void Slider(const char *str_id, float *v, const char *description) if (ImGui::IsItemActive()) { ImVec2 mouse = ImGui::GetMousePos(); - *v = GetSliderValueForMousePos(mouse, slider_pos, slider_size); + x = GetSliderValueForMousePos(mouse, slider_pos, slider_size); } - *v = fmax(0, fmin(*v, 1)); - DrawSlider(*v, ImGui::IsItemHovered() || ImGui::IsItemActive(), slider_pos, + x = std::clamp(x, 0.f, 1.f); + *v = x * (max - min) + min; + DrawSlider(x, ImGui::IsItemHovered() || ImGui::IsItemActive(), slider_pos, slider_size); ImVec2 slider_max = ImVec2(slider_pos.x + slider_size.x, slider_pos.y + slider_size.y); diff --git a/ui/xui/widgets.hh b/ui/xui/widgets.hh index 168878bb9fc..f698d437887 100644 --- a/ui/xui/widgets.hh +++ b/ui/xui/widgets.hh @@ -34,7 +34,7 @@ float GetSliderValueForMousePos(ImVec2 mouse, ImVec2 pos, ImVec2 size); void DrawSlider(float v, bool hovered, ImVec2 pos, ImVec2 size); void DrawToggle(bool enabled, bool hovered, ImVec2 pos, ImVec2 size); bool Toggle(const char *str_id, bool *v, const char *description = nullptr); -void Slider(const char *str_id, float *v, const char *description = nullptr); +void Slider(const char *str_id, float *v, const char *description = nullptr, float min = 0, float max = 1, float increment = 0.05); bool FilePicker(const char *str_id, const char **buf, const char *filters, bool dir = false); void DrawComboChevron();