diff --git a/README.md b/README.md index 1f4478df3..e0608b673 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 2038. +This is the source code for early-access 2039. ## Legal Notice diff --git a/src/common/settings.cpp b/src/common/settings.cpp index 0d2df80a8..e50c4b343 100755 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -72,6 +72,9 @@ void LogSettings() { log_setting("Debugging_ProgramArgs", values.program_args.GetValue()); log_setting("Services_BCATBackend", values.bcat_backend.GetValue()); log_setting("Services_BCATBoxcatLocal", values.bcat_boxcat_local.GetValue()); + log_setting("Input_EnableMotion", values.motion_enabled.GetValue()); + log_setting("Input_EnableVibrations", values.vibration_enabled.GetValue()); + log_setting("Input_EnableRawInput", values.enable_raw_input.GetValue()); } bool IsConfiguringGlobal() { diff --git a/src/common/settings.h b/src/common/settings.h index 9c0da8d33..f02232ccb 100755 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -16,7 +16,6 @@ #include "common/common_types.h" #include "common/settings_input.h" -#include "input_common/udp/client.h" namespace Settings { @@ -504,14 +503,15 @@ struct Values { Setting use_docked_mode{true, "use_docked_mode"}; + BasicSetting enable_raw_input{false, "enable_raw_input"}; + Setting vibration_enabled{true, "vibration_enabled"}; Setting enable_accurate_vibrations{false, "enable_accurate_vibrations"}; Setting motion_enabled{true, "motion_enabled"}; BasicSetting motion_device{"engine:motion_emu,update_period:100,sensitivity:0.01", "motion_device"}; - BasicSetting udp_input_servers{InputCommon::CemuhookUDP::DEFAULT_SRV, - "udp_input_servers"}; + BasicSetting udp_input_servers{"127.0.0.1:26760", "udp_input_servers"}; BasicSetting pause_tas_on_load{true, "pause_tas_on_load"}; BasicSetting tas_enable{false, "tas_enable"}; diff --git a/src/input_common/sdl/sdl_impl.cpp b/src/input_common/sdl/sdl_impl.cpp index f102410d1..ab6211b29 100755 --- a/src/input_common/sdl/sdl_impl.cpp +++ b/src/input_common/sdl/sdl_impl.cpp @@ -21,7 +21,7 @@ #include "common/logging/log.h" #include "common/math_util.h" #include "common/param_package.h" -#include "common/settings_input.h" +#include "common/settings.h" #include "common/threadsafe_queue.h" #include "core/frontend/input.h" #include "input_common/motion_input.h" @@ -254,11 +254,25 @@ public: } bool IsJoyconLeft() const { - return std::strstr(GetControllerName().c_str(), "Joy-Con Left") != nullptr; + const std::string controller_name = GetControllerName(); + if (std::strstr(controller_name.c_str(), "Joy-Con Left") != nullptr) { + return true; + } + if (std::strstr(controller_name.c_str(), "Joy-Con (L)") != nullptr) { + return true; + } + return false; } bool IsJoyconRight() const { - return std::strstr(GetControllerName().c_str(), "Joy-Con Right") != nullptr; + const std::string controller_name = GetControllerName(); + if (std::strstr(controller_name.c_str(), "Joy-Con Right") != nullptr) { + return true; + } + if (std::strstr(controller_name.c_str(), "Joy-Con (R)") != nullptr) { + return true; + } + return false; } std::string GetControllerName() const { @@ -889,8 +903,10 @@ SDLState::SDLState() { RegisterFactory("sdl", vibration_factory); RegisterFactory("sdl", motion_factory); - // Disable raw input. When enabled this setting causes SDL to die when a web applet opens - SDL_SetHint(SDL_HINT_JOYSTICK_RAWINPUT, "0"); + if (!Settings::values.enable_raw_input) { + // Disable raw input. When enabled this setting causes SDL to die when a web applet opens + SDL_SetHint(SDL_HINT_JOYSTICK_RAWINPUT, "0"); + } // Enable HIDAPI rumble. This prevents SDL from disabling motion on PS4 and PS5 controllers SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, "1"); @@ -898,10 +914,10 @@ SDLState::SDLState() { // Tell SDL2 to use the hidapi driver. This will allow joycons to be detected as a // GameController and not a generic one - SDL_SetHint("SDL_JOYSTICK_HIDAPI_JOY_CONS", "1"); + SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, "1"); // Turn off Pro controller home led - SDL_SetHint("SDL_JOYSTICK_HIDAPI_SWITCH_HOME_LED", "0"); + SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_HOME_LED, "0"); // If the frontend is going to manage the event loop, then we don't start one here start_thread = SDL_WasInit(SDL_INIT_JOYSTICK) == 0; diff --git a/src/input_common/udp/client.h b/src/input_common/udp/client.h index a11ea3068..380f9bb76 100755 --- a/src/input_common/udp/client.h +++ b/src/input_common/udp/client.h @@ -21,8 +21,6 @@ namespace InputCommon::CemuhookUDP { -constexpr char DEFAULT_SRV[] = "127.0.0.1:26760"; - class Socket; namespace Response { diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp index 2d29d8c14..2885e6799 100755 --- a/src/shader_recompiler/backend/spirv/emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/emit_context.cpp @@ -15,6 +15,8 @@ namespace Shader::Backend::SPIRV { namespace { +constexpr size_t NUM_FIXEDFNCTEXTURE = 10; + enum class Operation { Increment, Decrement, @@ -427,6 +429,16 @@ Id DescType(EmitContext& ctx, Id sampled_type, Id pointer_type, u32 count) { return pointer_type; } } + +size_t FindNextUnusedLocation(const std::bitset& used_locations, + size_t start_offset) { + for (size_t location = start_offset; location < used_locations.size(); ++location) { + if (!used_locations.test(location)) { + return location; + } + } + throw RuntimeError("Unable to get an unused location for legacy attribute"); +} } // Anonymous namespace void VectorTypes::Define(Sirit::Module& sirit_ctx, Id base_type, std::string_view name) { @@ -1227,6 +1239,7 @@ void EmitContext::DefineInputs(const IR::Program& program) { loads[IR::Attribute::TessellationEvaluationPointV]) { tess_coord = DefineInput(*this, F32[3], false, spv::BuiltIn::TessCoord); } + std::bitset used_locations{}; for (size_t index = 0; index < IR::NUM_GENERICS; ++index) { const AttributeType input_type{runtime_info.generic_input_types[index]}; if (!runtime_info.previous_stage_stores.Generic(index)) { @@ -1238,6 +1251,7 @@ void EmitContext::DefineInputs(const IR::Program& program) { if (input_type == AttributeType::Disabled) { continue; } + used_locations.set(index); const Id type{GetAttributeType(*this, input_type)}; const Id id{DefineInput(*this, type, true)}; Decorate(id, spv::Decoration::Location, static_cast(index)); @@ -1263,6 +1277,26 @@ void EmitContext::DefineInputs(const IR::Program& program) { break; } } + size_t previous_unused_location = 0; + if (loads.AnyComponent(IR::Attribute::ColorFrontDiffuseR)) { + const size_t location = FindNextUnusedLocation(used_locations, previous_unused_location); + previous_unused_location = location; + used_locations.set(location); + const Id id{DefineInput(*this, F32[4], true)}; + Decorate(id, spv::Decoration::Location, location); + input_front_color = id; + } + for (size_t index = 0; index < NUM_FIXEDFNCTEXTURE; ++index) { + if (loads.AnyComponent(IR::Attribute::FixedFncTexture0S + index * 4)) { + const size_t location = + FindNextUnusedLocation(used_locations, previous_unused_location); + previous_unused_location = location; + used_locations.set(location); + const Id id{DefineInput(*this, F32[4], true)}; + Decorate(id, spv::Decoration::Location, location); + input_fixed_fnc_textures[index] = id; + } + } if (stage == Stage::TessellationEval) { for (size_t index = 0; index < info.uses_patches.size(); ++index) { if (!info.uses_patches[index]) { @@ -1313,9 +1347,31 @@ void EmitContext::DefineOutputs(const IR::Program& program) { viewport_mask = DefineOutput(*this, TypeArray(U32[1], Const(1u)), std::nullopt, spv::BuiltIn::ViewportMaskNV); } + std::bitset used_locations{}; for (size_t index = 0; index < IR::NUM_GENERICS; ++index) { if (info.stores.Generic(index)) { DefineGenericOutput(*this, index, invocations); + used_locations.set(index); + } + } + size_t previous_unused_location = 0; + if (info.stores.AnyComponent(IR::Attribute::ColorFrontDiffuseR)) { + const size_t location = FindNextUnusedLocation(used_locations, previous_unused_location); + previous_unused_location = location; + used_locations.set(location); + const Id id{DefineOutput(*this, F32[4], invocations)}; + Decorate(id, spv::Decoration::Location, static_cast(location)); + output_front_color = id; + } + for (size_t index = 0; index < NUM_FIXEDFNCTEXTURE; ++index) { + if (info.stores.AnyComponent(IR::Attribute::FixedFncTexture0S + index * 4)) { + const size_t location = + FindNextUnusedLocation(used_locations, previous_unused_location); + previous_unused_location = location; + used_locations.set(location); + const Id id{DefineOutput(*this, F32[4], invocations)}; + Decorate(id, spv::Decoration::Location, location); + output_fixed_fnc_textures[index] = id; } } switch (stage) { diff --git a/src/shader_recompiler/backend/spirv/emit_context.h b/src/shader_recompiler/backend/spirv/emit_context.h index e277bc358..847d0c0e6 100755 --- a/src/shader_recompiler/backend/spirv/emit_context.h +++ b/src/shader_recompiler/backend/spirv/emit_context.h @@ -268,10 +268,14 @@ public: Id write_global_func_u32x4{}; Id input_position{}; + Id input_front_color{}; + std::array input_fixed_fnc_textures{}; std::array input_generics{}; Id output_point_size{}; Id output_position{}; + Id output_front_color{}; + std::array output_fixed_fnc_textures{}; std::array, 32> output_generics{}; Id output_tess_level_outer{}; diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp index 9e54a17ee..68f360b3c 100755 --- a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp @@ -43,6 +43,25 @@ Id AttrPointer(EmitContext& ctx, Id pointer_type, Id vertex, Id base, Args&&... } } +bool IsFixedFncTexture(IR::Attribute attribute) { + return attribute >= IR::Attribute::FixedFncTexture0S && + attribute <= IR::Attribute::FixedFncTexture9Q; +} + +u32 FixedFncTextureAttributeIndex(IR::Attribute attribute) { + if (!IsFixedFncTexture(attribute)) { + throw InvalidArgument("Attribute {} is not a FixedFncTexture", attribute); + } + return (static_cast(attribute) - static_cast(IR::Attribute::FixedFncTexture0S)) / 4u; +} + +u32 FixedFncTextureAttributeElement(IR::Attribute attribute) { + if (!IsFixedFncTexture(attribute)) { + throw InvalidArgument("Attribute {} is not a FixedFncTexture", attribute); + } + return static_cast(attribute) % 4u; +} + template Id OutputAccessChain(EmitContext& ctx, Id result_type, Id base, Args&&... args) { if (ctx.stage == Stage::TessellationControl) { @@ -74,6 +93,13 @@ std::optional OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) { return OutputAccessChain(ctx, ctx.output_f32, info.id, index_id); } } + if (IsFixedFncTexture(attr)) { + const u32 index{FixedFncTextureAttributeIndex(attr)}; + const u32 element{FixedFncTextureAttributeElement(attr)}; + const Id element_id{ctx.Const(element)}; + return OutputAccessChain(ctx, ctx.output_f32, ctx.output_fixed_fnc_textures[index], + element_id); + } switch (attr) { case IR::Attribute::PointSize: return ctx.output_point_size; @@ -85,6 +111,14 @@ std::optional OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) { const Id element_id{ctx.Const(element)}; return OutputAccessChain(ctx, ctx.output_f32, ctx.output_position, element_id); } + case IR::Attribute::ColorFrontDiffuseR: + case IR::Attribute::ColorFrontDiffuseG: + case IR::Attribute::ColorFrontDiffuseB: + case IR::Attribute::ColorFrontDiffuseA: { + const u32 element{static_cast(attr) % 4}; + const Id element_id{ctx.Const(element)}; + return OutputAccessChain(ctx, ctx.output_f32, ctx.output_front_color, element_id); + } case IR::Attribute::ClipDistance0: case IR::Attribute::ClipDistance1: case IR::Attribute::ClipDistance2: @@ -307,6 +341,12 @@ Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, Id vertex) { const Id value{ctx.OpLoad(type->id, pointer)}; return type->needs_cast ? ctx.OpBitcast(ctx.F32[1], value) : value; } + if (IsFixedFncTexture(attr)) { + const u32 index{FixedFncTextureAttributeIndex(attr)}; + const Id attr_id{ctx.input_fixed_fnc_textures[index]}; + const Id attr_ptr{AttrPointer(ctx, ctx.input_f32, vertex, attr_id, ctx.Const(element))}; + return ctx.OpLoad(ctx.F32[1], attr_ptr); + } switch (attr) { case IR::Attribute::PrimitiveId: return ctx.OpBitcast(ctx.F32[1], ctx.OpLoad(ctx.U32[1], ctx.primitive_id)); @@ -316,6 +356,13 @@ Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, Id vertex) { case IR::Attribute::PositionW: return ctx.OpLoad(ctx.F32[1], AttrPointer(ctx, ctx.input_f32, vertex, ctx.input_position, ctx.Const(element))); + case IR::Attribute::ColorFrontDiffuseR: + case IR::Attribute::ColorFrontDiffuseG: + case IR::Attribute::ColorFrontDiffuseB: + case IR::Attribute::ColorFrontDiffuseA: { + return ctx.OpLoad(ctx.F32[1], AttrPointer(ctx, ctx.input_f32, vertex, ctx.input_front_color, + ctx.Const(element))); + } case IR::Attribute::InstanceId: if (ctx.profile.support_vertex_instance_id) { return ctx.OpBitcast(ctx.F32[1], ctx.OpLoad(ctx.U32[1], ctx.instance_id)); diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 1ae14926f..31b5e45a6 100755 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -563,6 +563,7 @@ void Config::ReadControlValues() { ReadTouchscreenValues(); ReadMotionTouchValues(); + ReadBasicSetting(Settings::values.enable_raw_input); ReadBasicSetting(Settings::values.emulate_analog_keyboard); Settings::values.mouse_panning = false; ReadBasicSetting(Settings::values.mouse_panning_sensitivity); @@ -1199,6 +1200,7 @@ void Config::SaveControlValues() { WriteGlobalSetting(Settings::values.vibration_enabled); WriteGlobalSetting(Settings::values.enable_accurate_vibrations); WriteGlobalSetting(Settings::values.motion_enabled); + WriteBasicSetting(Settings::values.enable_raw_input); WriteBasicSetting(Settings::values.keyboard_enabled); WriteBasicSetting(Settings::values.emulate_analog_keyboard); WriteBasicSetting(Settings::values.mouse_panning_sensitivity); diff --git a/src/yuzu/configuration/configure_input_advanced.cpp b/src/yuzu/configuration/configure_input_advanced.cpp index 2f1419b5b..d20fd86b6 100755 --- a/src/yuzu/configuration/configure_input_advanced.cpp +++ b/src/yuzu/configuration/configure_input_advanced.cpp @@ -126,6 +126,7 @@ void ConfigureInputAdvanced::ApplyConfiguration() { Settings::values.mouse_panning_sensitivity = static_cast(ui->mouse_panning_sensitivity->value()); Settings::values.touchscreen.enabled = ui->touchscreen_enabled->isChecked(); + Settings::values.enable_raw_input = ui->enable_raw_input->isChecked(); } void ConfigureInputAdvanced::LoadConfiguration() { @@ -155,6 +156,7 @@ void ConfigureInputAdvanced::LoadConfiguration() { ui->mouse_panning->setChecked(Settings::values.mouse_panning.GetValue()); ui->mouse_panning_sensitivity->setValue(Settings::values.mouse_panning_sensitivity.GetValue()); ui->touchscreen_enabled->setChecked(Settings::values.touchscreen.enabled); + ui->enable_raw_input->setChecked(Settings::values.enable_raw_input.GetValue()); UpdateUIEnabled(); } diff --git a/src/yuzu/configuration/configure_input_advanced.ui b/src/yuzu/configuration/configure_input_advanced.ui index d3ef5bd06..d1b4bd2f2 100755 --- a/src/yuzu/configuration/configure_input_advanced.ui +++ b/src/yuzu/configuration/configure_input_advanced.ui @@ -2672,6 +2672,22 @@ + + + + Requires restarting yuzu + + + + 0 + 23 + + + + Enable Xinput 8 player support (disables web applet) + + + diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index b21ec37ef..35c3de8e9 100755 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -559,7 +559,8 @@ void GMainWindow::WebBrowserOpenWebPage(const std::string& main_url, const std::string& additional_args, bool is_local) { #ifdef YUZU_USE_QT_WEB_ENGINE - if (disable_web_applet) { + // Raw input breaks with the web applet, Disable web applets if enabled + if (disable_web_applet || Settings::values.enable_raw_input) { emit WebBrowserClosed(Service::AM::Applets::WebExitReason::WindowClosed, "http://localhost/"); return;