diff --git a/vita3k/app/include/app/functions.h b/vita3k/app/include/app/functions.h index ef016dee62..c275b96d73 100644 --- a/vita3k/app/include/app/functions.h +++ b/vita3k/app/include/app/functions.h @@ -39,7 +39,7 @@ enum class AppRunType { }; void init_paths(Root &root_paths); -bool init(EmuEnvState &state, Config &cfg, const Root &root_paths); +bool init(EmuEnvState &state, const Root &root_paths); bool late_init(EmuEnvState &state); void destroy(EmuEnvState &emuenv, ImGui_State *imgui); void update_viewport(EmuEnvState &state); diff --git a/vita3k/app/src/app.cpp b/vita3k/app/src/app.cpp index abad95d335..c84b369bde 100644 --- a/vita3k/app/src/app.cpp +++ b/vita3k/app/src/app.cpp @@ -68,7 +68,7 @@ void set_window_title(EmuEnvState &emuenv) { const std::string title_to_set = fmt::format("{} | {} ({}) | {} | {} FPS ({} ms) | {}x{}{} | {}", window_title, emuenv.current_app_title, emuenv.io.title_id, - emuenv.cfg.backend_renderer, + emuenv.cfg.current_config.backend_renderer, emuenv.fps, emuenv.ms_per_frame, x, y, af, emuenv.cfg.current_config.screen_filter); diff --git a/vita3k/app/src/app_init.cpp b/vita3k/app/src/app_init.cpp index 473ae403c6..1ea4101d95 100644 --- a/vita3k/app/src/app_init.cpp +++ b/vita3k/app/src/app_init.cpp @@ -229,9 +229,7 @@ void init_paths(Root &root_paths) { fs::create_directories(root_paths.get_log_path() / "texturelog"); } -bool init(EmuEnvState &state, Config &cfg, const Root &root_paths) { - state.cfg = std::move(cfg); - +bool init(EmuEnvState &state, const Root &root_paths) { state.base_path = root_paths.get_base_path(); state.default_path = root_paths.get_pref_path(); state.log_path = root_paths.get_log_path(); @@ -268,7 +266,7 @@ bool init(EmuEnvState &state, Config &cfg, const Root &root_paths) { state.backend_renderer = renderer::Backend::Vulkan; - if (string_utils::toupper(state.cfg.backend_renderer) == "OPENGL") { + if (string_utils::toupper(state.cfg.current_config.backend_renderer) == "OPENGL") { #ifndef __APPLE__ state.backend_renderer = renderer::Backend::OpenGL; #else diff --git a/vita3k/config/include/config/state.h b/vita3k/config/include/config/state.h index 4ce3e4c10f..3257a4c5be 100644 --- a/vita3k/config/include/config/state.h +++ b/vita3k/config/include/config/state.h @@ -129,6 +129,7 @@ struct Config : YamlLoader { int audio_volume = 100; bool ngs_enable = true; bool pstv_mode = false; + std::string backend_renderer = "OpenGL"; bool high_accuracy = false; float resolution_multiplier = 1.0f; bool disable_surface_sync = false; diff --git a/vita3k/gui/include/gui/functions.h b/vita3k/gui/include/gui/functions.h index e055471010..90176d3378 100644 --- a/vita3k/gui/include/gui/functions.h +++ b/vita3k/gui/include/gui/functions.h @@ -101,7 +101,7 @@ void pre_run_app(GuiState &gui, EmuEnvState &emuenv, const std::string &app_path void reset_controller_binding(EmuEnvState &emuenv); void save_apps_cache(GuiState &gui, EmuEnvState &emuenv); void save_user(GuiState &gui, EmuEnvState &emuenv, const std::string &user_id); -void set_config(GuiState &gui, EmuEnvState &emuenv, const std::string &app_path); +void set_config(EmuEnvState &emuenv, const std::string &app_path, bool custom = true); void set_shaders_compiled_display(GuiState &gui, EmuEnvState &emuenv); void update_app(GuiState &gui, EmuEnvState &emuenv, const std::string &app_path); void update_last_time_app_used(GuiState &gui, EmuEnvState &emuenv, const std::string &app); diff --git a/vita3k/gui/src/settings_dialog.cpp b/vita3k/gui/src/settings_dialog.cpp index ffa5d0131d..175d5ba651 100644 --- a/vita3k/gui/src/settings_dialog.cpp +++ b/vita3k/gui/src/settings_dialog.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include @@ -138,7 +139,7 @@ static CPUBackend config_cpu_backend; * @return false A custom config for the application has not been found or a custom config has been found * but it's corrupted or invalid. */ -static bool get_custom_config(GuiState &gui, EmuEnvState &emuenv, const std::string &app_path) { +static bool get_custom_config(EmuEnvState &emuenv, const std::string &app_path) { const auto CUSTOM_CONFIG_PATH{ emuenv.config_path / "config" / fmt::format("config_{}.xml", app_path) }; if (fs::exists(CUSTOM_CONFIG_PATH)) { @@ -166,6 +167,7 @@ static bool get_custom_config(GuiState &gui, EmuEnvState &emuenv, const std::str // Load GPU Config if (!config_child.child("gpu").empty()) { const auto gpu_child = config_child.child("gpu"); + config.backend_renderer = gpu_child.attribute("backend-renderer").as_string(); config.high_accuracy = gpu_child.attribute("high-accuracy").as_bool(); config.resolution_multiplier = gpu_child.attribute("resolution-multiplier").as_float(); config.disable_surface_sync = gpu_child.attribute("disable-surface-sync").as_bool(); @@ -231,11 +233,12 @@ static std::vector list_user_lang; void init_config(GuiState &gui, EmuEnvState &emuenv, const std::string &app_path) { // If no app-specific config file is being used for the initialized application, // set up `config` with the values set in the global emulator configuration - if (!get_custom_config(gui, emuenv, app_path)) { + if (!get_custom_config(emuenv, app_path)) { config.cpu_backend = emuenv.cfg.cpu_backend; config.cpu_opt = emuenv.cfg.cpu_opt; config.modules_mode = emuenv.cfg.modules_mode; config.lle_modules = emuenv.cfg.lle_modules; + config.backend_renderer = emuenv.cfg.backend_renderer; config.high_accuracy = emuenv.cfg.high_accuracy; config.resolution_multiplier = emuenv.cfg.resolution_multiplier; config.disable_surface_sync = emuenv.cfg.disable_surface_sync; @@ -276,6 +279,14 @@ void init_config(GuiState &gui, EmuEnvState &emuenv, const std::string &app_path current_aniso_filter_log = static_cast(log2f(static_cast(config.anisotropic_filtering))); max_aniso_filter_log = static_cast(log2f(static_cast(emuenv.renderer->get_max_anisotropic_filtering()))); audio_backend_idx = (emuenv.cfg.audio_backend == "SDL") ? 0 : 1; +#ifndef __APPLE__ + if (string_utils::toupper(config.backend_renderer) == "OPENGL") + emuenv.backend_renderer = renderer::Backend::OpenGL; + else + emuenv.backend_renderer = renderer::Backend::Vulkan; +#else + emuenv.backend_renderer = renderer::Backend::Vulkan; +#endif emuenv.app_path = app_path; emuenv.display.imgui_render = true; } @@ -319,6 +330,7 @@ static void save_config(GuiState &gui, EmuEnvState &emuenv) { // GPU auto gpu_child = config_child.append_child("gpu"); + gpu_child.append_attribute("backend-renderer") = config.backend_renderer.c_str(); gpu_child.append_attribute("high-accuracy") = config.high_accuracy; gpu_child.append_attribute("resolution-multiplier") = config.resolution_multiplier; gpu_child.append_attribute("disable-surface-sync") = config.disable_surface_sync; @@ -357,6 +369,7 @@ static void save_config(GuiState &gui, EmuEnvState &emuenv) { emuenv.cfg.modules_mode = config.modules_mode; emuenv.cfg.lle_modules = config.lle_modules; emuenv.cfg.high_accuracy = config.high_accuracy; + emuenv.cfg.backend_renderer = config.backend_renderer; emuenv.cfg.resolution_multiplier = config.resolution_multiplier; emuenv.cfg.disable_surface_sync = config.disable_surface_sync; emuenv.cfg.screen_filter = config.screen_filter; @@ -383,7 +396,7 @@ static void save_config(GuiState &gui, EmuEnvState &emuenv) { } std::string get_cpu_backend(GuiState &gui, EmuEnvState &emuenv, const std::string &app_path) { - if (!get_custom_config(gui, emuenv, app_path)) + if (!get_custom_config(emuenv, app_path)) return emuenv.cfg.cpu_backend; return config.cpu_backend; @@ -410,17 +423,19 @@ static void set_vsync_state(const bool &state) { * @param emuenv State of the emulated PlayStation Vita environment * @param app_path Path to the app or game to get the custom config for */ -void set_config(GuiState &gui, EmuEnvState &emuenv, const std::string &app_path) { +void set_config(EmuEnvState &emuenv, const std::string &app_path, bool custom) { // If a config file is in use, call `get_custom_config()` and set the config // parameters with the values stored in the app-specific custom config file - if (get_custom_config(gui, emuenv, app_path)) + if (custom && get_custom_config(emuenv, app_path)) { emuenv.cfg.current_config = config; - else { + LOG_INFO("Using custom config for app path: {}", app_path); + } else { // Else inherit the values from the global emulator config emuenv.cfg.current_config.cpu_backend = emuenv.cfg.cpu_backend; emuenv.cfg.current_config.cpu_opt = emuenv.cfg.cpu_opt; emuenv.cfg.current_config.modules_mode = emuenv.cfg.modules_mode; emuenv.cfg.current_config.lle_modules = emuenv.cfg.lle_modules; + emuenv.cfg.current_config.backend_renderer = emuenv.cfg.backend_renderer; emuenv.cfg.current_config.high_accuracy = emuenv.cfg.high_accuracy; emuenv.cfg.current_config.resolution_multiplier = emuenv.cfg.resolution_multiplier; emuenv.cfg.current_config.disable_surface_sync = emuenv.cfg.disable_surface_sync; @@ -439,6 +454,19 @@ void set_config(GuiState &gui, EmuEnvState &emuenv, const std::string &app_path) emuenv.cfg.current_config.psn_signed_in = emuenv.cfg.psn_signed_in; } + // can happen when launching directly into a game, the renderer is not even initialized yet + if (!emuenv.renderer) + return; + +#ifndef __APPLE__ + if (string_utils::toupper(emuenv.cfg.current_config.backend_renderer) == "OPENGL") + emuenv.backend_renderer = renderer::Backend::OpenGL; + else + emuenv.backend_renderer = renderer::Backend::Vulkan; +#else + emuenv.backend_renderer = renderer::Backend::Vulkan; +#endif + // If backend render or resolution multiplier is changed when app run, reboot emu and app if (!emuenv.io.title_id.empty() && ((emuenv.renderer->current_backend != emuenv.backend_renderer) || (emuenv.renderer->res_multiplier != emuenv.cfg.current_config.resolution_multiplier))) { emuenv.load_exec = true; @@ -582,15 +610,15 @@ void draw_settings_dialog(GuiState &gui, EmuEnvState &emuenv) { ImGui::PopStyleColor(); ImGui::Spacing(); -#ifdef __APPLE__ +#if defined(__APPLE__) ImGui::BeginDisabled(); #endif static const char *LIST_BACKEND_RENDERER[] = { "OpenGL", "Vulkan" }; if (ImGui::Combo(lang.gpu["backend_renderer"].c_str(), reinterpret_cast(&emuenv.backend_renderer), LIST_BACKEND_RENDERER, IM_ARRAYSIZE(LIST_BACKEND_RENDERER))) - emuenv.cfg.backend_renderer = LIST_BACKEND_RENDERER[int(emuenv.backend_renderer)]; + config.backend_renderer = LIST_BACKEND_RENDERER[int(emuenv.backend_renderer)]; if (ImGui::IsItemHovered()) ImGui::SetTooltip("%s", lang.gpu["select_backend_renderer"].c_str()); -#ifdef __APPLE__ +#if defined(__APPLE__) ImGui::EndDisabled(); #else ImGui::Spacing(); @@ -598,7 +626,8 @@ void draw_settings_dialog(GuiState &gui, EmuEnvState &emuenv) { const bool is_vulkan = (emuenv.backend_renderer == renderer::Backend::Vulkan); const bool is_ingame = !emuenv.io.title_id.empty(); - if (is_vulkan) { + const bool is_renderer_changed = (emuenv.backend_renderer != emuenv.renderer->current_backend); + if (is_vulkan && !is_renderer_changed) { const std::vector gpu_list_str = emuenv.renderer->get_gpu_list(); // must convert to a vector of char* std::vector gpu_list; @@ -618,7 +647,7 @@ void draw_settings_dialog(GuiState &gui, EmuEnvState &emuenv) { if (is_ingame) ImGui::EndDisabled(); - } else { + } else if (!is_vulkan) { ImGui::Checkbox(lang.gpu["v_sync"].c_str(), &config.v_sync); if (ImGui::IsItemHovered()) ImGui::SetTooltip("%s", lang.gpu["v_sync_description"].c_str()); @@ -1296,7 +1325,7 @@ void draw_settings_dialog(GuiState &gui, EmuEnvState &emuenv) { if (ImGui::Button(is_apply ? (is_reboot ? lang.main_window["save_reboot"].c_str() : lang.main_window["save_apply"].c_str()) : lang.main_window["save"].c_str(), BUTTON_SIZE)) { save_config(gui, emuenv); if (is_apply) - set_config(gui, emuenv, emuenv.io.app_path); + set_config(emuenv, emuenv.io.app_path); } if (ImGui::IsItemHovered()) ImGui::SetTooltip("%s", lang.main_window["keep_changes"].c_str()); diff --git a/vita3k/main.cpp b/vita3k/main.cpp index 86c0ffb755..e9fb059e29 100644 --- a/vita3k/main.cpp +++ b/vita3k/main.cpp @@ -124,10 +124,14 @@ int main(int argc, char *argv[]) { LOG_CRITICAL("PLEASE. DO NOT RUN VITA3K AS ADMIN OR WITH ADMIN PRIVILEGES."); } - Config cfg{}; - EmuEnvState emuenv; + EmuEnvState emuenv{}; + Config &cfg = emuenv.cfg; + const auto config_err = config::init_config(cfg, argc, argv, root_paths); + // to make sure config.current_config is properly initialized... + gui::set_config(emuenv, "", false); + fs::create_directories(cfg.get_pref_path()); if (config_err != Success) { @@ -197,10 +201,13 @@ int main(int argc, char *argv[]) { LOG_INFO("Available ram memory: {} MiB", SDL_GetSystemRAM()); app::AppRunType run_type = app::AppRunType::Unknown; - if (cfg.run_app_path) + if (cfg.run_app_path) { run_type = app::AppRunType::Extracted; + emuenv.config_path = root_paths.get_config_path(); + gui::set_config(emuenv, *cfg.run_app_path); + } - if (!app::init(emuenv, cfg, root_paths)) { + if (!app::init(emuenv, root_paths)) { app::error_dialog("Emulated environment initialization failed.", emuenv.window.get()); return 1; } @@ -319,6 +326,8 @@ int main(int argc, char *argv[]) { } } + gui::set_config(emuenv, emuenv.io.app_path); + // When backend render is changed before boot app, reboot emu in new backend render and run app if (emuenv.renderer->current_backend != emuenv.backend_renderer) { emuenv.load_app_path = emuenv.io.app_path; @@ -326,8 +335,6 @@ int main(int argc, char *argv[]) { return Success; } - gui::set_config(gui, emuenv, emuenv.io.app_path); - const auto APP_INDEX = gui::get_app_index(gui, emuenv.io.app_path); emuenv.app_info.app_version = APP_INDEX->app_ver; emuenv.app_info.app_category = APP_INDEX->category;