early-access version 3561
This commit is contained in:
parent
9f7d9cd3f1
commit
4fa09f2af9
25 changed files with 203 additions and 58 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <span>
|
||||
#include <vector>
|
||||
#include <SDL.h>
|
||||
|
||||
#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 <SDL.h>
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
namespace AudioCore::Sink {
|
||||
/**
|
||||
* SDL sink stream, responsible for sinking samples to hardware.
|
||||
|
|
|
@ -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{};
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -106,6 +106,7 @@ struct ControllerMotion {
|
|||
Common::Vec3f accel{};
|
||||
Common::Vec3f gyro{};
|
||||
Common::Vec3f rotation{};
|
||||
Common::Vec3f euler{};
|
||||
std::array<Common::Vec3f, 3> orientation{};
|
||||
bool is_at_rest{};
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "common/math_util.h"
|
||||
#include "core/hid/motion_input.h"
|
||||
|
||||
|
@ -51,6 +53,20 @@ void MotionInput::SetQuaternion(const Common::Quaternion<f32>& 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;
|
||||
|
|
|
@ -35,6 +35,7 @@ public:
|
|||
void SetAcceleration(const Common::Vec3f& acceleration);
|
||||
void SetGyroscope(const Common::Vec3f& gyroscope);
|
||||
void SetQuaternion(const Common::Quaternion<f32>& 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<f32> GetQuaternion() const;
|
||||
[[nodiscard]] Common::Vec3f GetEulerAngles() const;
|
||||
|
||||
[[nodiscard]] bool IsMoving(f32 sensitivity) const;
|
||||
[[nodiscard]] bool IsCalibrated(f32 sensitivity) const;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -939,6 +939,7 @@ std::unique_ptr<Common::Input::InputDevice> 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);
|
||||
|
|
|
@ -108,7 +108,8 @@ bool IsASTCSupported() {
|
|||
|
||||
[[nodiscard]] bool IsDebugToolAttached(std::span<const std::string_view> 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
|
||||
|
||||
|
|
|
@ -1126,7 +1126,8 @@ bool Image::ScaleDown(bool ignore) {
|
|||
|
||||
ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info,
|
||||
ImageId image_id_, Image& image, const SlotVector<Image>&)
|
||||
: 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<GLsizei>(name.size()), name.data());
|
||||
}
|
||||
return view.handle;
|
||||
|
|
|
@ -314,7 +314,6 @@ private:
|
|||
std::unique_ptr<StorageViews> 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;
|
||||
|
|
|
@ -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<size_t>(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)
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <vector>
|
||||
|
||||
#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.
|
||||
|
|
|
@ -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<int>(param.Get("threshold", 0.5f) * 100.0f);
|
||||
|
|
|
@ -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<Common::Vec3f, 8> 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<QPointF, 4> 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<QPointF, 4> 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 <size_t N>
|
||||
void PlayerControlPreview::DrawPolygon(QPainter& p, const std::array<QPointF, N>& polygon) {
|
||||
p.drawPolygon(polygon.data(), static_cast<int>(polygon.size()));
|
||||
|
|
|
@ -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 <size_t N>
|
||||
void DrawPolygon(QPainter& p, const std::array<QPointF, N>& 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{};
|
||||
};
|
||||
|
|
|
@ -4,18 +4,8 @@
|
|||
#include <memory>
|
||||
#include <optional>
|
||||
#include <sstream>
|
||||
|
||||
// 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 <SDL.h>
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#include <INIReader.h>
|
||||
#include <SDL.h>
|
||||
#include "common/fs/file.h"
|
||||
#include "common/fs/fs.h"
|
||||
#include "common/fs/path_util.h"
|
||||
|
|
Loading…
Reference in a new issue