diff --git a/README.md b/README.md index 8b7f59993..35802a335 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 3560. +This is the source code for early-access 3561. ## Legal Notice diff --git a/src/audio_core/sink/sdl2_sink.cpp b/src/audio_core/sink/sdl2_sink.cpp index 3c0d98209..2bfd53a0d 100755 --- a/src/audio_core/sink/sdl2_sink.cpp +++ b/src/audio_core/sink/sdl2_sink.cpp @@ -3,6 +3,7 @@ #include #include +#include #include "audio_core/common/common.h" #include "audio_core/sink/sdl2_sink.h" @@ -10,16 +11,6 @@ #include "common/logging/log.h" #include "core/core.h" -// Ignore -Wimplicit-fallthrough due to https://github.com/libsdl-org/SDL/issues/4307 -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wimplicit-fallthrough" -#endif -#include -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - namespace AudioCore::Sink { /** * SDL sink stream, responsible for sinking samples to hardware. diff --git a/src/common/input.h b/src/common/input.h index 24f5a4328..e5c928aea 100755 --- a/src/common/input.h +++ b/src/common/input.h @@ -111,6 +111,8 @@ struct AnalogProperties { float offset{}; // Invert direction of the sensor data bool inverted{}; + // Invert the state if it's converted to a button + bool inverted_button{}; // Press once to activate, press again to release bool toggle{}; }; diff --git a/src/common/vector_math.h b/src/common/vector_math.h index 95029615e..bf6194827 100755 --- a/src/common/vector_math.h +++ b/src/common/vector_math.h @@ -259,6 +259,20 @@ public: return *this; } + void RotateFromOrigin(float roll, float pitch, float yaw) { + float temp = y; + y = std::cos(roll) * y - std::sin(roll) * z; + z = std::sin(roll) * temp + std::cos(roll) * z; + + temp = x; + x = std::cos(pitch) * x + std::sin(pitch) * z; + z = -std::sin(pitch) * temp + std::cos(pitch) * z; + + temp = x; + x = std::cos(yaw) * x - std::sin(yaw) * y; + y = std::sin(yaw) * temp + std::cos(yaw) * y; + } + [[nodiscard]] constexpr T Length2() const { return x * x + y * y + z * z; } diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp index 559780fff..d6d29a4d4 100755 --- a/src/core/hid/emulated_controller.cpp +++ b/src/core/hid/emulated_controller.cpp @@ -376,6 +376,7 @@ void EmulatedController::ReloadInput() { motion.accel = emulated_motion.GetAcceleration(); motion.gyro = emulated_motion.GetGyroscope(); motion.rotation = emulated_motion.GetRotations(); + motion.euler = emulated_motion.GetEulerAngles(); motion.orientation = emulated_motion.GetOrientation(); motion.is_at_rest = !emulated_motion.IsMoving(motion_sensitivity); } @@ -980,14 +981,11 @@ void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback emulated.UpdateOrientation(raw_status.delta_timestamp); force_update_motion = raw_status.force_update; - if (is_configuring) { - return; - } - auto& motion = controller.motion_state[index]; motion.accel = emulated.GetAcceleration(); motion.gyro = emulated.GetGyroscope(); motion.rotation = emulated.GetRotations(); + motion.euler = emulated.GetEulerAngles(); motion.orientation = emulated.GetOrientation(); motion.is_at_rest = !emulated.IsMoving(motion_sensitivity); } diff --git a/src/core/hid/emulated_controller.h b/src/core/hid/emulated_controller.h index f3ef4e231..41993f846 100755 --- a/src/core/hid/emulated_controller.h +++ b/src/core/hid/emulated_controller.h @@ -106,6 +106,7 @@ struct ControllerMotion { Common::Vec3f accel{}; Common::Vec3f gyro{}; Common::Vec3f rotation{}; + Common::Vec3f euler{}; std::array orientation{}; bool is_at_rest{}; }; diff --git a/src/core/hid/input_converter.cpp b/src/core/hid/input_converter.cpp index b855c3a98..53ed1d8a1 100755 --- a/src/core/hid/input_converter.cpp +++ b/src/core/hid/input_converter.cpp @@ -54,6 +54,7 @@ Common::Input::ButtonStatus TransformToButton(const Common::Input::CallbackStatu case Common::Input::InputType::Analog: status.value = TransformToTrigger(callback).pressed.value; status.toggle = callback.analog_status.properties.toggle; + status.inverted = callback.analog_status.properties.inverted_button; break; case Common::Input::InputType::Trigger: status.value = TransformToTrigger(callback).pressed.value; diff --git a/src/core/hid/motion_input.cpp b/src/core/hid/motion_input.cpp index a9a518e11..db60a6e8b 100755 --- a/src/core/hid/motion_input.cpp +++ b/src/core/hid/motion_input.cpp @@ -1,6 +1,8 @@ // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include + #include "common/math_util.h" #include "core/hid/motion_input.h" @@ -51,6 +53,20 @@ void MotionInput::SetQuaternion(const Common::Quaternion& quaternion) { quat = quaternion; } +void MotionInput::SetEulerAngles(const Common::Vec3f& euler_angles) { + const float cr = std::cos(euler_angles.x * 0.5f); + const float sr = std::sin(euler_angles.x * 0.5f); + const float cp = std::cos(euler_angles.y * 0.5f); + const float sp = std::sin(euler_angles.y * 0.5f); + const float cy = std::cos(euler_angles.z * 0.5f); + const float sy = std::sin(euler_angles.z * 0.5f); + + quat.w = cr * cp * cy + sr * sp * sy; + quat.xyz.x = sr * cp * cy - cr * sp * sy; + quat.xyz.y = cr * sp * cy + sr * cp * sy; + quat.xyz.z = cr * cp * sy - sr * sp * cy; +} + void MotionInput::SetGyroBias(const Common::Vec3f& bias) { gyro_bias = bias; } @@ -222,6 +238,26 @@ Common::Vec3f MotionInput::GetRotations() const { return rotations; } +Common::Vec3f MotionInput::GetEulerAngles() const { + // roll (x-axis rotation) + const float sinr_cosp = 2 * (quat.w * quat.xyz.x + quat.xyz.y * quat.xyz.z); + const float cosr_cosp = 1 - 2 * (quat.xyz.x * quat.xyz.x + quat.xyz.y * quat.xyz.y); + + // pitch (y-axis rotation) + const float sinp = std::sqrt(1 + 2 * (quat.w * quat.xyz.y - quat.xyz.x * quat.xyz.z)); + const float cosp = std::sqrt(1 - 2 * (quat.w * quat.xyz.y - quat.xyz.x * quat.xyz.z)); + + // yaw (z-axis rotation) + const float siny_cosp = 2 * (quat.w * quat.xyz.z + quat.xyz.x * quat.xyz.y); + const float cosy_cosp = 1 - 2 * (quat.xyz.y * quat.xyz.y + quat.xyz.z * quat.xyz.z); + + return { + std::atan2(sinr_cosp, cosr_cosp), + 2 * std::atan2(sinp, cosp) - Common::PI / 2, + std::atan2(siny_cosp, cosy_cosp), + }; +} + void MotionInput::ResetOrientation() { if (!reset_enabled || only_accelerometer) { return; diff --git a/src/core/hid/motion_input.h b/src/core/hid/motion_input.h index 6e1e536b1..86acbadbd 100755 --- a/src/core/hid/motion_input.h +++ b/src/core/hid/motion_input.h @@ -35,6 +35,7 @@ public: void SetAcceleration(const Common::Vec3f& acceleration); void SetGyroscope(const Common::Vec3f& gyroscope); void SetQuaternion(const Common::Quaternion& quaternion); + void SetEulerAngles(const Common::Vec3f& euler_angles); void SetGyroBias(const Common::Vec3f& bias); void SetGyroThreshold(f32 threshold); @@ -54,6 +55,7 @@ public: [[nodiscard]] Common::Vec3f GetGyroBias() const; [[nodiscard]] Common::Vec3f GetRotations() const; [[nodiscard]] Common::Quaternion GetQuaternion() const; + [[nodiscard]] Common::Vec3f GetEulerAngles() const; [[nodiscard]] bool IsMoving(f32 sensitivity) const; [[nodiscard]] bool IsCalibrated(f32 sensitivity) const; diff --git a/src/input_common/input_engine.cpp b/src/input_common/input_engine.cpp index 16f76573b..aa3db353b 100755 --- a/src/input_common/input_engine.cpp +++ b/src/input_common/input_engine.cpp @@ -58,6 +58,8 @@ void InputEngine::SetHatButton(const PadIdentifier& identifier, int button, u8 v } void InputEngine::SetAxis(const PadIdentifier& identifier, int axis, f32 value) { + value /= 2.0f; + value -= 0.5f; { std::scoped_lock lock{mutex}; ControllerData& controller = controller_list.at(identifier); diff --git a/src/input_common/input_poller.cpp b/src/input_common/input_poller.cpp index 1f880e2ce..ce6993be5 100755 --- a/src/input_common/input_poller.cpp +++ b/src/input_common/input_poller.cpp @@ -939,6 +939,7 @@ std::unique_ptr InputFactory::CreateAnalogDevice( .threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f), .offset = std::clamp(params.Get("offset", 0.0f), -1.0f, 1.0f), .inverted = params.Get("invert", "+") == "-", + .inverted_button = params.Get("inverted", false) != 0, .toggle = params.Get("toggle", false) != 0, }; input_engine->PreSetController(identifier); diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp index e20ea0739..3887d4b2f 100755 --- a/src/video_core/renderer_opengl/gl_device.cpp +++ b/src/video_core/renderer_opengl/gl_device.cpp @@ -108,7 +108,8 @@ bool IsASTCSupported() { [[nodiscard]] bool IsDebugToolAttached(std::span extensions) { const bool nsight = std::getenv("NVTX_INJECTION64_PATH") || std::getenv("NSIGHT_LAUNCHED"); - return nsight || HasExtension(extensions, "GL_EXT_debug_tool"); + return nsight || HasExtension(extensions, "GL_EXT_debug_tool") || + Settings::values.renderer_debug.GetValue(); } } // Anonymous namespace diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index 97e6abcaa..8866c1282 100755 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp @@ -1126,7 +1126,8 @@ bool Image::ScaleDown(bool ignore) { ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info, ImageId image_id_, Image& image, const SlotVector&) - : VideoCommon::ImageViewBase{info, image.info, image_id_}, views{runtime.null_image_views} { + : VideoCommon::ImageViewBase{info, image.info, image_id_, image.gpu_addr}, + views{runtime.null_image_views} { const Device& device = runtime.device; if (True(image.flags & ImageFlagBits::Converted)) { internal_format = IsPixelFormatSRGB(info.format) ? GL_SRGB8_ALPHA8 : GL_RGBA8; @@ -1217,12 +1218,12 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI ImageView::ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo& info, const VideoCommon::ImageViewInfo& view_info, GPUVAddr gpu_addr_) - : VideoCommon::ImageViewBase{info, view_info}, gpu_addr{gpu_addr_}, + : VideoCommon::ImageViewBase{info, view_info, gpu_addr_}, buffer_size{VideoCommon::CalculateGuestSizeInBytes(info)} {} ImageView::ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo& info, const VideoCommon::ImageViewInfo& view_info) - : VideoCommon::ImageViewBase{info, view_info} {} + : VideoCommon::ImageViewBase{info, view_info, 0} {} ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::NullImageViewParams& params) : VideoCommon::ImageViewBase{params}, views{runtime.null_image_views} {} @@ -1282,7 +1283,7 @@ GLuint ImageView::MakeView(Shader::TextureType view_type, GLenum view_format) { ApplySwizzle(view.handle, format, casted_swizzle); } if (set_object_label) { - const std::string name = VideoCommon::Name(*this); + const std::string name = VideoCommon::Name(*this, gpu_addr); glObjectLabel(GL_TEXTURE, view.handle, static_cast(name.size()), name.data()); } return view.handle; diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h index 96bba4caf..74522f029 100755 --- a/src/video_core/renderer_opengl/gl_texture_cache.h +++ b/src/video_core/renderer_opengl/gl_texture_cache.h @@ -314,7 +314,6 @@ private: std::unique_ptr storage_views; GLenum internal_format = GL_NONE; GLuint default_handle = 0; - GPUVAddr gpu_addr = 0; u32 buffer_size = 0; GLuint original_texture = 0; int num_samples = 0; diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index f0733edb2..42c1370a7 100755 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -1584,8 +1584,9 @@ bool Image::NeedsScaleHelper() const { ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info, ImageId image_id_, Image& image) - : VideoCommon::ImageViewBase{info, image.info, image_id_}, device{&runtime.device}, - image_handle{image.Handle()}, samples(ConvertSampleCount(image.info.num_samples)) { + : VideoCommon::ImageViewBase{info, image.info, image_id_, image.gpu_addr}, + device{&runtime.device}, image_handle{image.Handle()}, + samples(ConvertSampleCount(image.info.num_samples)) { using Shader::TextureType; const VkImageAspectFlags aspect_mask = ImageViewAspectMask(info); @@ -1631,7 +1632,7 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI } vk::ImageView handle = device->GetLogical().CreateImageView(ci); if (device->HasDebuggingToolAttached()) { - handle.SetObjectNameEXT(VideoCommon::Name(*this).c_str()); + handle.SetObjectNameEXT(VideoCommon::Name(*this, gpu_addr).c_str()); } image_views[static_cast(tex_type)] = std::move(handle); }; @@ -1672,7 +1673,7 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI ImageView::ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo& info, const VideoCommon::ImageViewInfo& view_info, GPUVAddr gpu_addr_) - : VideoCommon::ImageViewBase{info, view_info}, gpu_addr{gpu_addr_}, + : VideoCommon::ImageViewBase{info, view_info, gpu_addr_}, buffer_size{VideoCommon::CalculateGuestSizeInBytes(info)} {} ImageView::ImageView(TextureCacheRuntime&, const VideoCommon::NullImageViewParams& params) diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index d72277e36..fc1380671 100755 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h @@ -265,7 +265,6 @@ private: VkImage image_handle = VK_NULL_HANDLE; VkImageView render_target = VK_NULL_HANDLE; VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT; - GPUVAddr gpu_addr = 0; u32 buffer_size = 0; }; diff --git a/src/video_core/texture_cache/formatter.cpp b/src/video_core/texture_cache/formatter.cpp index aa27a312d..e6994454b 100755 --- a/src/video_core/texture_cache/formatter.cpp +++ b/src/video_core/texture_cache/formatter.cpp @@ -46,7 +46,7 @@ std::string Name(const ImageBase& image) { return "Invalid"; } -std::string Name(const ImageViewBase& image_view) { +std::string Name(const ImageViewBase& image_view, GPUVAddr addr) { const u32 width = image_view.size.width; const u32 height = image_view.size.height; const u32 depth = image_view.size.depth; @@ -56,23 +56,25 @@ std::string Name(const ImageViewBase& image_view) { const std::string level = num_levels > 1 ? fmt::format(":{}", num_levels) : ""; switch (image_view.type) { case ImageViewType::e1D: - return fmt::format("ImageView 1D {}{}", width, level); + return fmt::format("ImageView 1D 0x{:X} {}{}", addr, width, level); case ImageViewType::e2D: - return fmt::format("ImageView 2D {}x{}{}", width, height, level); + return fmt::format("ImageView 2D 0x{:X} {}x{}{}", addr, width, height, level); case ImageViewType::Cube: - return fmt::format("ImageView Cube {}x{}{}", width, height, level); + return fmt::format("ImageView Cube 0x{:X} {}x{}{}", addr, width, height, level); case ImageViewType::e3D: - return fmt::format("ImageView 3D {}x{}x{}{}", width, height, depth, level); + return fmt::format("ImageView 3D 0x{:X} {}x{}x{}{}", addr, width, height, depth, level); case ImageViewType::e1DArray: - return fmt::format("ImageView 1DArray {}{}|{}", width, level, num_layers); + return fmt::format("ImageView 1DArray 0x{:X} {}{}|{}", addr, width, level, num_layers); case ImageViewType::e2DArray: - return fmt::format("ImageView 2DArray {}x{}{}|{}", width, height, level, num_layers); + return fmt::format("ImageView 2DArray 0x{:X} {}x{}{}|{}", addr, width, height, level, + num_layers); case ImageViewType::CubeArray: - return fmt::format("ImageView CubeArray {}x{}{}|{}", width, height, level, num_layers); + return fmt::format("ImageView CubeArray 0x{:X} {}x{}{}|{}", addr, width, height, level, + num_layers); case ImageViewType::Rect: - return fmt::format("ImageView Rect {}x{}{}", width, height, level); + return fmt::format("ImageView Rect 0x{:X} {}x{}{}", addr, width, height, level); case ImageViewType::Buffer: - return fmt::format("BufferView {}", width); + return fmt::format("BufferView 0x{:X} {}", addr, width); } return "Invalid"; } diff --git a/src/video_core/texture_cache/formatter.h b/src/video_core/texture_cache/formatter.h index 3ce7cecee..745b3c1fd 100755 --- a/src/video_core/texture_cache/formatter.h +++ b/src/video_core/texture_cache/formatter.h @@ -274,7 +274,7 @@ struct RenderTargets; [[nodiscard]] std::string Name(const ImageBase& image); -[[nodiscard]] std::string Name(const ImageViewBase& image_view); +[[nodiscard]] std::string Name(const ImageViewBase& image_view, GPUVAddr addr); [[nodiscard]] std::string Name(const RenderTargets& render_targets); diff --git a/src/video_core/texture_cache/image_view_base.cpp b/src/video_core/texture_cache/image_view_base.cpp index 32f682ae5..9157e74b8 100755 --- a/src/video_core/texture_cache/image_view_base.cpp +++ b/src/video_core/texture_cache/image_view_base.cpp @@ -15,8 +15,8 @@ namespace VideoCommon { ImageViewBase::ImageViewBase(const ImageViewInfo& info, const ImageInfo& image_info, - ImageId image_id_) - : image_id{image_id_}, format{info.format}, type{info.type}, range{info.range}, + ImageId image_id_, GPUVAddr addr) + : image_id{image_id_}, gpu_addr{addr}, format{info.format}, type{info.type}, range{info.range}, size{ .width = std::max(image_info.size.width >> range.base.level, 1u), .height = std::max(image_info.size.height >> range.base.level, 1u), @@ -33,8 +33,8 @@ ImageViewBase::ImageViewBase(const ImageViewInfo& info, const ImageInfo& image_i } } -ImageViewBase::ImageViewBase(const ImageInfo& info, const ImageViewInfo& view_info) - : image_id{NULL_IMAGE_ID}, format{info.format}, type{ImageViewType::Buffer}, +ImageViewBase::ImageViewBase(const ImageInfo& info, const ImageViewInfo& view_info, GPUVAddr addr) + : image_id{NULL_IMAGE_ID}, gpu_addr{addr}, format{info.format}, type{ImageViewType::Buffer}, size{ .width = info.size.width, .height = 1, diff --git a/src/video_core/texture_cache/image_view_base.h b/src/video_core/texture_cache/image_view_base.h index 82f288d06..bb2fec858 100755 --- a/src/video_core/texture_cache/image_view_base.h +++ b/src/video_core/texture_cache/image_view_base.h @@ -24,9 +24,9 @@ enum class ImageViewFlagBits : u16 { DECLARE_ENUM_FLAG_OPERATORS(ImageViewFlagBits) struct ImageViewBase { - explicit ImageViewBase(const ImageViewInfo& info, const ImageInfo& image_info, - ImageId image_id); - explicit ImageViewBase(const ImageInfo& info, const ImageViewInfo& view_info); + explicit ImageViewBase(const ImageViewInfo& info, const ImageInfo& image_info, ImageId image_id, + GPUVAddr addr); + explicit ImageViewBase(const ImageInfo& info, const ImageViewInfo& view_info, GPUVAddr addr); explicit ImageViewBase(const NullImageViewParams&); [[nodiscard]] bool IsBuffer() const noexcept { @@ -34,6 +34,7 @@ struct ImageViewBase { } ImageId image_id{}; + GPUVAddr gpu_addr = 0; PixelFormat format{}; ImageViewType type{}; SubresourceRange range; diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index e3cd01a14..da0aa5a85 100755 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -10,6 +10,7 @@ #include #include "common/common_types.h" +#include "common/settings.h" #include "video_core/vulkan_common/vulkan_wrapper.h" // Define all features which may be used by the implementation here. @@ -510,7 +511,7 @@ public: /// Returns true when a known debugging tool is attached. bool HasDebuggingToolAttached() const { - return has_renderdoc || has_nsight_graphics; + return has_renderdoc || has_nsight_graphics || Settings::values.renderer_debug.GetValue(); } /// Returns true when the device does not properly support cube compatibility. diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index 2fff66ef2..3c39b5204 100755 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp @@ -206,7 +206,7 @@ QString ConfigureInputPlayer::ButtonToText(const Common::ParamPackage& param) { } if (param.Has("axis")) { const QString axis = QString::fromStdString(param.Get("axis", "")); - return QObject::tr("%1%2Axis %3").arg(toggle, invert, axis); + return QObject::tr("%1%2%3Axis %4").arg(toggle, inverted, invert, axis); } if (param.Has("axis_x") && param.Has("axis_y") && param.Has("axis_z")) { const QString axis_x = QString::fromStdString(param.Get("axis_x", "")); @@ -229,7 +229,7 @@ QString ConfigureInputPlayer::ButtonToText(const Common::ParamPackage& param) { return QObject::tr("%1%2%3Hat %4").arg(turbo, toggle, inverted, button_name); } if (param.Has("axis")) { - return QObject::tr("%1%2Axis %3").arg(toggle, inverted, button_name); + return QObject::tr("%1%2%3Axis %4").arg(toggle, inverted, invert, button_name); } if (param.Has("motion")) { return QObject::tr("%1%2Axis %3").arg(toggle, inverted, button_name); @@ -410,6 +410,12 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i button_map[button_id]->setText(ButtonToText(param)); emulated_controller->SetButtonParam(button_id, param); }); + context_menu.addAction(tr("Invert button"), [&] { + const bool invert_value = !param.Get("inverted", false); + param.Set("inverted", invert_value); + button_map[button_id]->setText(ButtonToText(param)); + emulated_controller->SetButtonParam(button_id, param); + }); context_menu.addAction(tr("Set threshold"), [&] { const int button_threshold = static_cast(param.Get("threshold", 0.5f) * 100.0f); diff --git a/src/yuzu/configuration/configure_input_player_widget.cpp b/src/yuzu/configuration/configure_input_player_widget.cpp index e93921650..0b66912f5 100755 --- a/src/yuzu/configuration/configure_input_player_widget.cpp +++ b/src/yuzu/configuration/configure_input_player_widget.cpp @@ -180,6 +180,10 @@ void PlayerControlPreview::ControllerUpdate(Core::HID::ControllerTriggerType typ battery_values = controller->GetBatteryValues(); needs_redraw = true; break; + case Core::HID::ControllerTriggerType::Motion: + motion_values = controller->GetMotions(); + needs_redraw = true; + break; default: break; } @@ -313,6 +317,15 @@ void PlayerControlPreview::DrawLeftController(QPainter& p, const QPointF center) DrawRawJoystick(p, center + QPointF(-140, 90), QPointF(0, 0)); } + { + // Draw motion cubes + using namespace Settings::NativeMotion; + p.setPen(colors.outline); + p.setBrush(colors.transparent); + Draw3dCube(p, center + QPointF(-140, 90), + motion_values[Settings::NativeMotion::MotionLeft].euler, 20.0f); + } + using namespace Settings::NativeButton; // D-pad constants @@ -435,6 +448,15 @@ void PlayerControlPreview::DrawRightController(QPainter& p, const QPointF center DrawRawJoystick(p, QPointF(0, 0), center + QPointF(140, 90)); } + { + // Draw motion cubes + using namespace Settings::NativeMotion; + p.setPen(colors.outline); + p.setBrush(colors.transparent); + Draw3dCube(p, center + QPointF(140, 90), + motion_values[Settings::NativeMotion::MotionRight].euler, 20.0f); + } + using namespace Settings::NativeButton; // Face buttons constants @@ -555,6 +577,17 @@ void PlayerControlPreview::DrawDualController(QPainter& p, const QPointF center) DrawRawJoystick(p, center + QPointF(-180, 90), center + QPointF(180, 90)); } + { + // Draw motion cubes + using namespace Settings::NativeMotion; + p.setPen(colors.outline); + p.setBrush(colors.transparent); + Draw3dCube(p, center + QPointF(-180, -5), + motion_values[Settings::NativeMotion::MotionLeft].euler, 20.0f); + Draw3dCube(p, center + QPointF(180, -5), + motion_values[Settings::NativeMotion::MotionRight].euler, 20.0f); + } + using namespace Settings::NativeButton; // Face buttons constants @@ -647,6 +680,15 @@ void PlayerControlPreview::DrawHandheldController(QPainter& p, const QPointF cen DrawRawJoystick(p, center + QPointF(-50, 0), center + QPointF(50, 0)); } + { + // Draw motion cubes + using namespace Settings::NativeMotion; + p.setPen(colors.outline); + p.setBrush(colors.transparent); + Draw3dCube(p, center + QPointF(0, -115), + motion_values[Settings::NativeMotion::MotionLeft].euler, 15.0f); + } + using namespace Settings::NativeButton; // Face buttons constants @@ -750,6 +792,15 @@ void PlayerControlPreview::DrawProController(QPainter& p, const QPointF center) DrawRawJoystick(p, center + QPointF(-50, 105), center + QPointF(50, 105)); } + { + // Draw motion cubes + using namespace Settings::NativeMotion; + p.setPen(colors.button); + p.setBrush(colors.transparent); + Draw3dCube(p, center + QPointF(0, -100), + motion_values[Settings::NativeMotion::MotionLeft].euler, 15.0f); + } + using namespace Settings::NativeButton; // Face buttons constants @@ -2871,6 +2922,46 @@ void PlayerControlPreview::DrawArrow(QPainter& p, const QPointF center, const Di DrawPolygon(p, arrow_symbol); } +// Draw motion functions +void PlayerControlPreview::Draw3dCube(QPainter& p, QPointF center, const Common::Vec3f& euler, + float size) { + std::array cube{ + Common::Vec3f{-1, -1, -1}, + {-1, 1, -1}, + {1, 1, -1}, + {1, -1, -1}, + {-1, -1, 1}, + {-1, 1, 1}, + {1, 1, 1}, + {1, -1, 1}, + }; + + for (Common::Vec3f& point : cube) { + point.RotateFromOrigin(euler.x, euler.y, euler.z); + point *= size; + } + + const std::array front_face{ + center + QPointF{cube[0].x, cube[0].y}, + center + QPointF{cube[1].x, cube[1].y}, + center + QPointF{cube[2].x, cube[2].y}, + center + QPointF{cube[3].x, cube[3].y}, + }; + const std::array back_face{ + center + QPointF{cube[4].x, cube[4].y}, + center + QPointF{cube[5].x, cube[5].y}, + center + QPointF{cube[6].x, cube[6].y}, + center + QPointF{cube[7].x, cube[7].y}, + }; + + DrawPolygon(p, front_face); + DrawPolygon(p, back_face); + p.drawLine(center + QPointF{cube[0].x, cube[0].y}, center + QPointF{cube[4].x, cube[4].y}); + p.drawLine(center + QPointF{cube[1].x, cube[1].y}, center + QPointF{cube[5].x, cube[5].y}); + p.drawLine(center + QPointF{cube[2].x, cube[2].y}, center + QPointF{cube[6].x, cube[6].y}); + p.drawLine(center + QPointF{cube[3].x, cube[3].y}, center + QPointF{cube[7].x, cube[7].y}); +} + template void PlayerControlPreview::DrawPolygon(QPainter& p, const std::array& polygon) { p.drawPolygon(polygon.data(), static_cast(polygon.size())); diff --git a/src/yuzu/configuration/configure_input_player_widget.h b/src/yuzu/configuration/configure_input_player_widget.h index 2b4f73481..dc6a193ef 100755 --- a/src/yuzu/configuration/configure_input_player_widget.h +++ b/src/yuzu/configuration/configure_input_player_widget.h @@ -9,6 +9,7 @@ #include "common/input.h" #include "common/settings_input.h" +#include "common/vector_math.h" #include "core/hid/emulated_controller.h" #include "core/hid/hid_types.h" @@ -193,6 +194,9 @@ private: void DrawSymbol(QPainter& p, QPointF center, Symbol symbol, float icon_size); void DrawArrow(QPainter& p, QPointF center, Direction direction, float size); + // Draw motion functions + void Draw3dCube(QPainter& p, QPointF center, const Common::Vec3f& euler, float size); + // Draw primitive types template void DrawPolygon(QPainter& p, const std::array& polygon); @@ -222,4 +226,5 @@ private: Core::HID::SticksValues stick_values{}; Core::HID::TriggerValues trigger_values{}; Core::HID::BatteryValues battery_values{}; + Core::HID::MotionState motion_values{}; }; diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp index ee38fdcb6..d421f0c2a 100755 --- a/src/yuzu_cmd/config.cpp +++ b/src/yuzu_cmd/config.cpp @@ -4,18 +4,8 @@ #include #include #include - -// Ignore -Wimplicit-fallthrough due to https://github.com/libsdl-org/SDL/issues/4307 -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wimplicit-fallthrough" -#endif -#include -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - #include +#include #include "common/fs/file.h" #include "common/fs/fs.h" #include "common/fs/path_util.h"