mirror of
https://github.com/yuzu-emu/yuzu-mainline.git
synced 2025-09-09 11:47:05 +00:00
Compare commits
4 commits
master
...
mainline-0
Author | SHA1 | Date | |
---|---|---|---|
|
cc7b11f0c7 | ||
|
a9f6bd2777 | ||
|
ce83d961f1 | ||
|
e3324fbfaa |
|
@ -6,10 +6,11 @@
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
namespace NativeButton {
|
namespace NativeButton {
|
||||||
const std::array<const char*, NumButtons> mapping = {{
|
const std::array<const char*, NumButtons> mapping = {{
|
||||||
"button_a", "button_b", "button_x", "button_y", "button_lstick",
|
"button_a", "button_b", "button_x", "button_y", "button_lstick",
|
||||||
"button_rstick", "button_l", "button_r", "button_zl", "button_zr",
|
"button_rstick", "button_l", "button_r", "button_zl", "button_zr",
|
||||||
"button_plus", "button_minus", "button_dleft", "button_dup", "button_dright",
|
"button_plus", "button_minus", "button_dleft", "button_dup", "button_dright",
|
||||||
"button_ddown", "button_sl", "button_sr", "button_home", "button_screenshot",
|
"button_ddown", "button_slleft", "button_srleft", "button_home", "button_screenshot",
|
||||||
|
"button_slright", "button_srright",
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,12 +29,15 @@ enum Values : int {
|
||||||
DRight,
|
DRight,
|
||||||
DDown,
|
DDown,
|
||||||
|
|
||||||
SL,
|
SLLeft,
|
||||||
SR,
|
SRLeft,
|
||||||
|
|
||||||
Home,
|
Home,
|
||||||
Screenshot,
|
Screenshot,
|
||||||
|
|
||||||
|
SLRight,
|
||||||
|
SRRight,
|
||||||
|
|
||||||
NumButtons,
|
NumButtons,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -715,6 +715,7 @@ add_library(core STATIC
|
||||||
hle/service/nvnflinger/producer_listener.h
|
hle/service/nvnflinger/producer_listener.h
|
||||||
hle/service/nvnflinger/status.h
|
hle/service/nvnflinger/status.h
|
||||||
hle/service/nvnflinger/ui/fence.h
|
hle/service/nvnflinger/ui/fence.h
|
||||||
|
hle/service/nvnflinger/ui/graphic_buffer.cpp
|
||||||
hle/service/nvnflinger/ui/graphic_buffer.h
|
hle/service/nvnflinger/ui/graphic_buffer.h
|
||||||
hle/service/nvnflinger/window.h
|
hle/service/nvnflinger/window.h
|
||||||
hle/service/olsc/olsc.cpp
|
hle/service/olsc/olsc.cpp
|
||||||
|
|
|
@ -243,10 +243,12 @@ void EmulatedController::LoadTASParams() {
|
||||||
tas_button_params[Settings::NativeButton::DUp].Set("button", 13);
|
tas_button_params[Settings::NativeButton::DUp].Set("button", 13);
|
||||||
tas_button_params[Settings::NativeButton::DRight].Set("button", 14);
|
tas_button_params[Settings::NativeButton::DRight].Set("button", 14);
|
||||||
tas_button_params[Settings::NativeButton::DDown].Set("button", 15);
|
tas_button_params[Settings::NativeButton::DDown].Set("button", 15);
|
||||||
tas_button_params[Settings::NativeButton::SL].Set("button", 16);
|
tas_button_params[Settings::NativeButton::SLLeft].Set("button", 16);
|
||||||
tas_button_params[Settings::NativeButton::SR].Set("button", 17);
|
tas_button_params[Settings::NativeButton::SRLeft].Set("button", 17);
|
||||||
tas_button_params[Settings::NativeButton::Home].Set("button", 18);
|
tas_button_params[Settings::NativeButton::Home].Set("button", 18);
|
||||||
tas_button_params[Settings::NativeButton::Screenshot].Set("button", 19);
|
tas_button_params[Settings::NativeButton::Screenshot].Set("button", 19);
|
||||||
|
tas_button_params[Settings::NativeButton::SLRight].Set("button", 20);
|
||||||
|
tas_button_params[Settings::NativeButton::SRRight].Set("button", 21);
|
||||||
|
|
||||||
tas_stick_params[Settings::NativeAnalog::LStick].Set("axis_x", 0);
|
tas_stick_params[Settings::NativeAnalog::LStick].Set("axis_x", 0);
|
||||||
tas_stick_params[Settings::NativeAnalog::LStick].Set("axis_y", 1);
|
tas_stick_params[Settings::NativeAnalog::LStick].Set("axis_y", 1);
|
||||||
|
@ -296,10 +298,12 @@ void EmulatedController::LoadVirtualGamepadParams() {
|
||||||
virtual_button_params[Settings::NativeButton::DUp].Set("button", 13);
|
virtual_button_params[Settings::NativeButton::DUp].Set("button", 13);
|
||||||
virtual_button_params[Settings::NativeButton::DRight].Set("button", 14);
|
virtual_button_params[Settings::NativeButton::DRight].Set("button", 14);
|
||||||
virtual_button_params[Settings::NativeButton::DDown].Set("button", 15);
|
virtual_button_params[Settings::NativeButton::DDown].Set("button", 15);
|
||||||
virtual_button_params[Settings::NativeButton::SL].Set("button", 16);
|
virtual_button_params[Settings::NativeButton::SLLeft].Set("button", 16);
|
||||||
virtual_button_params[Settings::NativeButton::SR].Set("button", 17);
|
virtual_button_params[Settings::NativeButton::SRLeft].Set("button", 17);
|
||||||
virtual_button_params[Settings::NativeButton::Home].Set("button", 18);
|
virtual_button_params[Settings::NativeButton::Home].Set("button", 18);
|
||||||
virtual_button_params[Settings::NativeButton::Screenshot].Set("button", 19);
|
virtual_button_params[Settings::NativeButton::Screenshot].Set("button", 19);
|
||||||
|
virtual_button_params[Settings::NativeButton::SLRight].Set("button", 20);
|
||||||
|
virtual_button_params[Settings::NativeButton::SRRight].Set("button", 21);
|
||||||
|
|
||||||
virtual_stick_params[Settings::NativeAnalog::LStick].Set("axis_x", 0);
|
virtual_stick_params[Settings::NativeAnalog::LStick].Set("axis_x", 0);
|
||||||
virtual_stick_params[Settings::NativeAnalog::LStick].Set("axis_y", 1);
|
virtual_stick_params[Settings::NativeAnalog::LStick].Set("axis_y", 1);
|
||||||
|
@ -867,12 +871,16 @@ void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback
|
||||||
controller.npad_button_state.down.Assign(current_status.value);
|
controller.npad_button_state.down.Assign(current_status.value);
|
||||||
controller.debug_pad_button_state.d_down.Assign(current_status.value);
|
controller.debug_pad_button_state.d_down.Assign(current_status.value);
|
||||||
break;
|
break;
|
||||||
case Settings::NativeButton::SL:
|
case Settings::NativeButton::SLLeft:
|
||||||
controller.npad_button_state.left_sl.Assign(current_status.value);
|
controller.npad_button_state.left_sl.Assign(current_status.value);
|
||||||
|
break;
|
||||||
|
case Settings::NativeButton::SLRight:
|
||||||
controller.npad_button_state.right_sl.Assign(current_status.value);
|
controller.npad_button_state.right_sl.Assign(current_status.value);
|
||||||
break;
|
break;
|
||||||
case Settings::NativeButton::SR:
|
case Settings::NativeButton::SRLeft:
|
||||||
controller.npad_button_state.left_sr.Assign(current_status.value);
|
controller.npad_button_state.left_sr.Assign(current_status.value);
|
||||||
|
break;
|
||||||
|
case Settings::NativeButton::SRRight:
|
||||||
controller.npad_button_state.right_sr.Assign(current_status.value);
|
controller.npad_button_state.right_sr.Assign(current_status.value);
|
||||||
break;
|
break;
|
||||||
case Settings::NativeButton::Home:
|
case Settings::NativeButton::Home:
|
||||||
|
@ -1890,12 +1898,16 @@ NpadButton EmulatedController::GetTurboButtonMask() const {
|
||||||
case Settings::NativeButton::DDown:
|
case Settings::NativeButton::DDown:
|
||||||
button_mask.down.Assign(1);
|
button_mask.down.Assign(1);
|
||||||
break;
|
break;
|
||||||
case Settings::NativeButton::SL:
|
case Settings::NativeButton::SLLeft:
|
||||||
button_mask.left_sl.Assign(1);
|
button_mask.left_sl.Assign(1);
|
||||||
|
break;
|
||||||
|
case Settings::NativeButton::SLRight:
|
||||||
button_mask.right_sl.Assign(1);
|
button_mask.right_sl.Assign(1);
|
||||||
break;
|
break;
|
||||||
case Settings::NativeButton::SR:
|
case Settings::NativeButton::SRLeft:
|
||||||
button_mask.left_sr.Assign(1);
|
button_mask.left_sr.Assign(1);
|
||||||
|
break;
|
||||||
|
case Settings::NativeButton::SRRight:
|
||||||
button_mask.right_sr.Assign(1);
|
button_mask.right_sr.Assign(1);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -457,12 +457,14 @@ void Controller_NPad::RequestPadStateUpdate(Core::HID::NpadIdType npad_id) {
|
||||||
pad_entry.l_stick = stick_state.left;
|
pad_entry.l_stick = stick_state.left;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (controller_type == Core::HID::NpadStyleIndex::JoyconLeft) {
|
if (controller_type == Core::HID::NpadStyleIndex::JoyconLeft ||
|
||||||
|
controller_type == Core::HID::NpadStyleIndex::JoyconDual) {
|
||||||
pad_entry.npad_buttons.left_sl.Assign(button_state.left_sl);
|
pad_entry.npad_buttons.left_sl.Assign(button_state.left_sl);
|
||||||
pad_entry.npad_buttons.left_sr.Assign(button_state.left_sr);
|
pad_entry.npad_buttons.left_sr.Assign(button_state.left_sr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (controller_type == Core::HID::NpadStyleIndex::JoyconRight) {
|
if (controller_type == Core::HID::NpadStyleIndex::JoyconRight ||
|
||||||
|
controller_type == Core::HID::NpadStyleIndex::JoyconDual) {
|
||||||
pad_entry.npad_buttons.right_sl.Assign(button_state.right_sl);
|
pad_entry.npad_buttons.right_sl.Assign(button_state.right_sl);
|
||||||
pad_entry.npad_buttons.right_sr.Assign(button_state.right_sr);
|
pad_entry.npad_buttons.right_sr.Assign(button_state.right_sr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
namespace Service::android {
|
namespace Service::android {
|
||||||
|
|
||||||
struct GraphicBuffer;
|
class GraphicBuffer;
|
||||||
|
|
||||||
class BufferItem final {
|
class BufferItem final {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
// https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/libs/gui/BufferQueueConsumer.cpp
|
// https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/libs/gui/BufferQueueConsumer.cpp
|
||||||
|
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/hle/service/nvdrv/core/nvmap.h"
|
|
||||||
#include "core/hle/service/nvnflinger/buffer_item.h"
|
#include "core/hle/service/nvnflinger/buffer_item.h"
|
||||||
#include "core/hle/service/nvnflinger/buffer_queue_consumer.h"
|
#include "core/hle/service/nvnflinger/buffer_queue_consumer.h"
|
||||||
#include "core/hle/service/nvnflinger/buffer_queue_core.h"
|
#include "core/hle/service/nvnflinger/buffer_queue_core.h"
|
||||||
|
@ -14,9 +13,8 @@
|
||||||
|
|
||||||
namespace Service::android {
|
namespace Service::android {
|
||||||
|
|
||||||
BufferQueueConsumer::BufferQueueConsumer(std::shared_ptr<BufferQueueCore> core_,
|
BufferQueueConsumer::BufferQueueConsumer(std::shared_ptr<BufferQueueCore> core_)
|
||||||
Service::Nvidia::NvCore::NvMap& nvmap_)
|
: core{std::move(core_)}, slots{core->slots} {}
|
||||||
: core{std::move(core_)}, slots{core->slots}, nvmap(nvmap_) {}
|
|
||||||
|
|
||||||
BufferQueueConsumer::~BufferQueueConsumer() = default;
|
BufferQueueConsumer::~BufferQueueConsumer() = default;
|
||||||
|
|
||||||
|
@ -136,8 +134,6 @@ Status BufferQueueConsumer::ReleaseBuffer(s32 slot, u64 frame_number, const Fenc
|
||||||
|
|
||||||
slots[slot].buffer_state = BufferState::Free;
|
slots[slot].buffer_state = BufferState::Free;
|
||||||
|
|
||||||
nvmap.FreeHandle(slots[slot].graphic_buffer->BufferId(), true);
|
|
||||||
|
|
||||||
listener = core->connected_producer_listener;
|
listener = core->connected_producer_listener;
|
||||||
|
|
||||||
LOG_DEBUG(Service_Nvnflinger, "releasing slot {}", slot);
|
LOG_DEBUG(Service_Nvnflinger, "releasing slot {}", slot);
|
||||||
|
@ -175,6 +171,25 @@ Status BufferQueueConsumer::Connect(std::shared_ptr<IConsumerListener> consumer_
|
||||||
return Status::NoError;
|
return Status::NoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Status BufferQueueConsumer::Disconnect() {
|
||||||
|
LOG_DEBUG(Service_Nvnflinger, "called");
|
||||||
|
|
||||||
|
std::scoped_lock lock{core->mutex};
|
||||||
|
|
||||||
|
if (core->consumer_listener == nullptr) {
|
||||||
|
LOG_ERROR(Service_Nvnflinger, "no consumer is connected");
|
||||||
|
return Status::BadValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
core->is_abandoned = true;
|
||||||
|
core->consumer_listener = nullptr;
|
||||||
|
core->queue.clear();
|
||||||
|
core->FreeAllBuffersLocked();
|
||||||
|
core->SignalDequeueCondition();
|
||||||
|
|
||||||
|
return Status::NoError;
|
||||||
|
}
|
||||||
|
|
||||||
Status BufferQueueConsumer::GetReleasedBuffers(u64* out_slot_mask) {
|
Status BufferQueueConsumer::GetReleasedBuffers(u64* out_slot_mask) {
|
||||||
if (out_slot_mask == nullptr) {
|
if (out_slot_mask == nullptr) {
|
||||||
LOG_ERROR(Service_Nvnflinger, "out_slot_mask may not be nullptr");
|
LOG_ERROR(Service_Nvnflinger, "out_slot_mask may not be nullptr");
|
||||||
|
|
|
@ -13,10 +13,6 @@
|
||||||
#include "core/hle/service/nvnflinger/buffer_queue_defs.h"
|
#include "core/hle/service/nvnflinger/buffer_queue_defs.h"
|
||||||
#include "core/hle/service/nvnflinger/status.h"
|
#include "core/hle/service/nvnflinger/status.h"
|
||||||
|
|
||||||
namespace Service::Nvidia::NvCore {
|
|
||||||
class NvMap;
|
|
||||||
} // namespace Service::Nvidia::NvCore
|
|
||||||
|
|
||||||
namespace Service::android {
|
namespace Service::android {
|
||||||
|
|
||||||
class BufferItem;
|
class BufferItem;
|
||||||
|
@ -25,19 +21,18 @@ class IConsumerListener;
|
||||||
|
|
||||||
class BufferQueueConsumer final {
|
class BufferQueueConsumer final {
|
||||||
public:
|
public:
|
||||||
explicit BufferQueueConsumer(std::shared_ptr<BufferQueueCore> core_,
|
explicit BufferQueueConsumer(std::shared_ptr<BufferQueueCore> core_);
|
||||||
Service::Nvidia::NvCore::NvMap& nvmap_);
|
|
||||||
~BufferQueueConsumer();
|
~BufferQueueConsumer();
|
||||||
|
|
||||||
Status AcquireBuffer(BufferItem* out_buffer, std::chrono::nanoseconds expected_present);
|
Status AcquireBuffer(BufferItem* out_buffer, std::chrono::nanoseconds expected_present);
|
||||||
Status ReleaseBuffer(s32 slot, u64 frame_number, const Fence& release_fence);
|
Status ReleaseBuffer(s32 slot, u64 frame_number, const Fence& release_fence);
|
||||||
Status Connect(std::shared_ptr<IConsumerListener> consumer_listener, bool controlled_by_app);
|
Status Connect(std::shared_ptr<IConsumerListener> consumer_listener, bool controlled_by_app);
|
||||||
|
Status Disconnect();
|
||||||
Status GetReleasedBuffers(u64* out_slot_mask);
|
Status GetReleasedBuffers(u64* out_slot_mask);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<BufferQueueCore> core;
|
std::shared_ptr<BufferQueueCore> core;
|
||||||
BufferQueueDefs::SlotsType& slots;
|
BufferQueueDefs::SlotsType& slots;
|
||||||
Service::Nvidia::NvCore::NvMap& nvmap;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Service::android
|
} // namespace Service::android
|
||||||
|
|
|
@ -14,24 +14,12 @@ BufferQueueCore::BufferQueueCore() = default;
|
||||||
|
|
||||||
BufferQueueCore::~BufferQueueCore() = default;
|
BufferQueueCore::~BufferQueueCore() = default;
|
||||||
|
|
||||||
void BufferQueueCore::NotifyShutdown() {
|
|
||||||
std::scoped_lock lock{mutex};
|
|
||||||
|
|
||||||
is_shutting_down = true;
|
|
||||||
|
|
||||||
SignalDequeueCondition();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BufferQueueCore::SignalDequeueCondition() {
|
void BufferQueueCore::SignalDequeueCondition() {
|
||||||
dequeue_possible.store(true);
|
dequeue_possible.store(true);
|
||||||
dequeue_condition.notify_all();
|
dequeue_condition.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BufferQueueCore::WaitForDequeueCondition(std::unique_lock<std::mutex>& lk) {
|
bool BufferQueueCore::WaitForDequeueCondition(std::unique_lock<std::mutex>& lk) {
|
||||||
if (is_shutting_down) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
dequeue_condition.wait(lk, [&] { return dequeue_possible.load(); });
|
dequeue_condition.wait(lk, [&] { return dequeue_possible.load(); });
|
||||||
dequeue_possible.store(false);
|
dequeue_possible.store(false);
|
||||||
|
|
||||||
|
|
|
@ -34,8 +34,6 @@ public:
|
||||||
BufferQueueCore();
|
BufferQueueCore();
|
||||||
~BufferQueueCore();
|
~BufferQueueCore();
|
||||||
|
|
||||||
void NotifyShutdown();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SignalDequeueCondition();
|
void SignalDequeueCondition();
|
||||||
bool WaitForDequeueCondition(std::unique_lock<std::mutex>& lk);
|
bool WaitForDequeueCondition(std::unique_lock<std::mutex>& lk);
|
||||||
|
@ -74,7 +72,6 @@ private:
|
||||||
u32 transform_hint{};
|
u32 transform_hint{};
|
||||||
bool is_allocating{};
|
bool is_allocating{};
|
||||||
mutable std::condition_variable_any is_allocating_condition;
|
mutable std::condition_variable_any is_allocating_condition;
|
||||||
bool is_shutting_down{};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Service::android
|
} // namespace Service::android
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
#include "core/hle/kernel/kernel.h"
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/hle/service/hle_ipc.h"
|
#include "core/hle/service/hle_ipc.h"
|
||||||
#include "core/hle/service/kernel_helpers.h"
|
#include "core/hle/service/kernel_helpers.h"
|
||||||
#include "core/hle/service/nvdrv/core/nvmap.h"
|
|
||||||
#include "core/hle/service/nvnflinger/buffer_queue_core.h"
|
#include "core/hle/service/nvnflinger/buffer_queue_core.h"
|
||||||
#include "core/hle/service/nvnflinger/buffer_queue_producer.h"
|
#include "core/hle/service/nvnflinger/buffer_queue_producer.h"
|
||||||
#include "core/hle/service/nvnflinger/consumer_listener.h"
|
#include "core/hle/service/nvnflinger/consumer_listener.h"
|
||||||
|
@ -533,8 +532,6 @@ Status BufferQueueProducer::QueueBuffer(s32 slot, const QueueBufferInput& input,
|
||||||
item.is_droppable = core->dequeue_buffer_cannot_block || async;
|
item.is_droppable = core->dequeue_buffer_cannot_block || async;
|
||||||
item.swap_interval = swap_interval;
|
item.swap_interval = swap_interval;
|
||||||
|
|
||||||
nvmap.DuplicateHandle(item.graphic_buffer->BufferId(), true);
|
|
||||||
|
|
||||||
sticky_transform = sticky_transform_;
|
sticky_transform = sticky_transform_;
|
||||||
|
|
||||||
if (core->queue.empty()) {
|
if (core->queue.empty()) {
|
||||||
|
@ -744,19 +741,13 @@ Status BufferQueueProducer::Disconnect(NativeWindowApi api) {
|
||||||
return Status::NoError;
|
return Status::NoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
// HACK: We are not Android. Remove handle for items in queue, and clear queue.
|
|
||||||
// Allows synchronous destruction of nvmap handles.
|
|
||||||
for (auto& item : core->queue) {
|
|
||||||
nvmap.FreeHandle(item.graphic_buffer->BufferId(), true);
|
|
||||||
}
|
|
||||||
core->queue.clear();
|
|
||||||
|
|
||||||
switch (api) {
|
switch (api) {
|
||||||
case NativeWindowApi::Egl:
|
case NativeWindowApi::Egl:
|
||||||
case NativeWindowApi::Cpu:
|
case NativeWindowApi::Cpu:
|
||||||
case NativeWindowApi::Media:
|
case NativeWindowApi::Media:
|
||||||
case NativeWindowApi::Camera:
|
case NativeWindowApi::Camera:
|
||||||
if (core->connected_api == api) {
|
if (core->connected_api == api) {
|
||||||
|
core->queue.clear();
|
||||||
core->FreeAllBuffersLocked();
|
core->FreeAllBuffersLocked();
|
||||||
core->connected_producer_listener = nullptr;
|
core->connected_producer_listener = nullptr;
|
||||||
core->connected_api = NativeWindowApi::NoConnectedApi;
|
core->connected_api = NativeWindowApi::NoConnectedApi;
|
||||||
|
@ -785,7 +776,7 @@ Status BufferQueueProducer::Disconnect(NativeWindowApi api) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Status BufferQueueProducer::SetPreallocatedBuffer(s32 slot,
|
Status BufferQueueProducer::SetPreallocatedBuffer(s32 slot,
|
||||||
const std::shared_ptr<GraphicBuffer>& buffer) {
|
const std::shared_ptr<NvGraphicBuffer>& buffer) {
|
||||||
LOG_DEBUG(Service_Nvnflinger, "slot {}", slot);
|
LOG_DEBUG(Service_Nvnflinger, "slot {}", slot);
|
||||||
|
|
||||||
if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
|
if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
|
||||||
|
@ -796,7 +787,7 @@ Status BufferQueueProducer::SetPreallocatedBuffer(s32 slot,
|
||||||
|
|
||||||
slots[slot] = {};
|
slots[slot] = {};
|
||||||
slots[slot].fence = Fence::NoFence();
|
slots[slot].fence = Fence::NoFence();
|
||||||
slots[slot].graphic_buffer = buffer;
|
slots[slot].graphic_buffer = std::make_shared<GraphicBuffer>(nvmap, buffer);
|
||||||
slots[slot].frame_number = 0;
|
slots[slot].frame_number = 0;
|
||||||
|
|
||||||
// Most games preallocate a buffer and pass a valid buffer here. However, it is possible for
|
// Most games preallocate a buffer and pass a valid buffer here. However, it is possible for
|
||||||
|
@ -839,7 +830,7 @@ void BufferQueueProducer::Transact(HLERequestContext& ctx, TransactionId code, u
|
||||||
}
|
}
|
||||||
case TransactionId::SetPreallocatedBuffer: {
|
case TransactionId::SetPreallocatedBuffer: {
|
||||||
const auto slot = parcel_in.Read<s32>();
|
const auto slot = parcel_in.Read<s32>();
|
||||||
const auto buffer = parcel_in.ReadObject<GraphicBuffer>();
|
const auto buffer = parcel_in.ReadObject<NvGraphicBuffer>();
|
||||||
|
|
||||||
status = SetPreallocatedBuffer(slot, buffer);
|
status = SetPreallocatedBuffer(slot, buffer);
|
||||||
break;
|
break;
|
||||||
|
@ -867,7 +858,7 @@ void BufferQueueProducer::Transact(HLERequestContext& ctx, TransactionId code, u
|
||||||
|
|
||||||
status = RequestBuffer(slot, &buf);
|
status = RequestBuffer(slot, &buf);
|
||||||
|
|
||||||
parcel_out.WriteFlattenedObject(buf);
|
parcel_out.WriteFlattenedObject<NvGraphicBuffer>(buf.get());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TransactionId::QueueBuffer: {
|
case TransactionId::QueueBuffer: {
|
||||||
|
|
|
@ -38,6 +38,7 @@ namespace Service::android {
|
||||||
|
|
||||||
class BufferQueueCore;
|
class BufferQueueCore;
|
||||||
class IProducerListener;
|
class IProducerListener;
|
||||||
|
struct NvGraphicBuffer;
|
||||||
|
|
||||||
class BufferQueueProducer final : public IBinder {
|
class BufferQueueProducer final : public IBinder {
|
||||||
public:
|
public:
|
||||||
|
@ -65,7 +66,7 @@ public:
|
||||||
bool producer_controlled_by_app, QueueBufferOutput* output);
|
bool producer_controlled_by_app, QueueBufferOutput* output);
|
||||||
|
|
||||||
Status Disconnect(NativeWindowApi api);
|
Status Disconnect(NativeWindowApi api);
|
||||||
Status SetPreallocatedBuffer(s32 slot, const std::shared_ptr<GraphicBuffer>& buffer);
|
Status SetPreallocatedBuffer(s32 slot, const std::shared_ptr<NvGraphicBuffer>& buffer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BufferQueueProducer(const BufferQueueProducer&) = delete;
|
BufferQueueProducer(const BufferQueueProducer&) = delete;
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
namespace Service::android {
|
namespace Service::android {
|
||||||
|
|
||||||
struct GraphicBuffer;
|
class GraphicBuffer;
|
||||||
|
|
||||||
enum class BufferState : u32 {
|
enum class BufferState : u32 {
|
||||||
Free = 0,
|
Free = 0,
|
||||||
|
|
|
@ -27,6 +27,26 @@ void ConsumerBase::Connect(bool controlled_by_app) {
|
||||||
consumer->Connect(shared_from_this(), controlled_by_app);
|
consumer->Connect(shared_from_this(), controlled_by_app);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConsumerBase::Abandon() {
|
||||||
|
LOG_DEBUG(Service_Nvnflinger, "called");
|
||||||
|
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
|
|
||||||
|
if (!is_abandoned) {
|
||||||
|
this->AbandonLocked();
|
||||||
|
is_abandoned = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsumerBase::AbandonLocked() {
|
||||||
|
for (int i = 0; i < BufferQueueDefs::NUM_BUFFER_SLOTS; i++) {
|
||||||
|
this->FreeBufferLocked(i);
|
||||||
|
}
|
||||||
|
// disconnect from the BufferQueue
|
||||||
|
consumer->Disconnect();
|
||||||
|
consumer = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void ConsumerBase::FreeBufferLocked(s32 slot_index) {
|
void ConsumerBase::FreeBufferLocked(s32 slot_index) {
|
||||||
LOG_DEBUG(Service_Nvnflinger, "slot_index={}", slot_index);
|
LOG_DEBUG(Service_Nvnflinger, "slot_index={}", slot_index);
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ class BufferQueueConsumer;
|
||||||
class ConsumerBase : public IConsumerListener, public std::enable_shared_from_this<ConsumerBase> {
|
class ConsumerBase : public IConsumerListener, public std::enable_shared_from_this<ConsumerBase> {
|
||||||
public:
|
public:
|
||||||
void Connect(bool controlled_by_app);
|
void Connect(bool controlled_by_app);
|
||||||
|
void Abandon();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit ConsumerBase(std::unique_ptr<BufferQueueConsumer> consumer_);
|
explicit ConsumerBase(std::unique_ptr<BufferQueueConsumer> consumer_);
|
||||||
|
@ -34,6 +35,7 @@ protected:
|
||||||
void OnBuffersReleased() override;
|
void OnBuffersReleased() override;
|
||||||
void OnSidebandStreamChanged() override;
|
void OnSidebandStreamChanged() override;
|
||||||
|
|
||||||
|
void AbandonLocked();
|
||||||
void FreeBufferLocked(s32 slot_index);
|
void FreeBufferLocked(s32 slot_index);
|
||||||
Status AcquireBufferLocked(BufferItem* item, std::chrono::nanoseconds present_when);
|
Status AcquireBufferLocked(BufferItem* item, std::chrono::nanoseconds present_when);
|
||||||
Status ReleaseBufferLocked(s32 slot, const std::shared_ptr<GraphicBuffer>& graphic_buffer);
|
Status ReleaseBufferLocked(s32 slot, const std::shared_ptr<GraphicBuffer>& graphic_buffer);
|
||||||
|
|
|
@ -166,7 +166,7 @@ constexpr SharedMemoryPoolLayout SharedBufferPoolLayout = [] {
|
||||||
}();
|
}();
|
||||||
|
|
||||||
void MakeGraphicBuffer(android::BufferQueueProducer& producer, u32 slot, u32 handle) {
|
void MakeGraphicBuffer(android::BufferQueueProducer& producer, u32 slot, u32 handle) {
|
||||||
auto buffer = std::make_shared<android::GraphicBuffer>();
|
auto buffer = std::make_shared<android::NvGraphicBuffer>();
|
||||||
buffer->width = SharedBufferWidth;
|
buffer->width = SharedBufferWidth;
|
||||||
buffer->height = SharedBufferHeight;
|
buffer->height = SharedBufferHeight;
|
||||||
buffer->stride = SharedBufferBlockLinearStride;
|
buffer->stride = SharedBufferBlockLinearStride;
|
||||||
|
|
|
@ -47,7 +47,10 @@ void Nvnflinger::SplitVSync(std::stop_token stop_token) {
|
||||||
vsync_signal.Wait();
|
vsync_signal.Wait();
|
||||||
|
|
||||||
const auto lock_guard = Lock();
|
const auto lock_guard = Lock();
|
||||||
Compose();
|
|
||||||
|
if (!is_abandoned) {
|
||||||
|
Compose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +101,6 @@ Nvnflinger::~Nvnflinger() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ShutdownLayers();
|
ShutdownLayers();
|
||||||
vsync_thread = {};
|
|
||||||
|
|
||||||
if (nvdrv) {
|
if (nvdrv) {
|
||||||
nvdrv->Close(disp_fd);
|
nvdrv->Close(disp_fd);
|
||||||
|
@ -106,12 +108,20 @@ Nvnflinger::~Nvnflinger() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Nvnflinger::ShutdownLayers() {
|
void Nvnflinger::ShutdownLayers() {
|
||||||
const auto lock_guard = Lock();
|
// Abandon consumers.
|
||||||
for (auto& display : displays) {
|
{
|
||||||
for (size_t layer = 0; layer < display.GetNumLayers(); ++layer) {
|
const auto lock_guard = Lock();
|
||||||
display.GetLayer(layer).Core().NotifyShutdown();
|
for (auto& display : displays) {
|
||||||
|
for (size_t layer = 0; layer < display.GetNumLayers(); ++layer) {
|
||||||
|
display.GetLayer(layer).GetConsumer().Abandon();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is_abandoned = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Join the vsync thread, if it exists.
|
||||||
|
vsync_thread = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Nvnflinger::SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance) {
|
void Nvnflinger::SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance) {
|
||||||
|
|
|
@ -140,6 +140,8 @@ private:
|
||||||
|
|
||||||
s32 swap_interval = 1;
|
s32 swap_interval = 1;
|
||||||
|
|
||||||
|
bool is_abandoned = false;
|
||||||
|
|
||||||
/// Event that handles screen composition.
|
/// Event that handles screen composition.
|
||||||
std::shared_ptr<Core::Timing::EventType> multi_composition_event;
|
std::shared_ptr<Core::Timing::EventType> multi_composition_event;
|
||||||
std::shared_ptr<Core::Timing::EventType> single_composition_event;
|
std::shared_ptr<Core::Timing::EventType> single_composition_event;
|
||||||
|
|
|
@ -19,7 +19,7 @@ enum class Status : s32 {
|
||||||
Busy = -16,
|
Busy = -16,
|
||||||
NoInit = -19,
|
NoInit = -19,
|
||||||
BadValue = -22,
|
BadValue = -22,
|
||||||
InvalidOperation = -37,
|
InvalidOperation = -38,
|
||||||
BufferNeedsReallocation = 1,
|
BufferNeedsReallocation = 1,
|
||||||
ReleaseAllBuffers = 2,
|
ReleaseAllBuffers = 2,
|
||||||
};
|
};
|
||||||
|
|
34
src/core/hle/service/nvnflinger/ui/graphic_buffer.cpp
Normal file
34
src/core/hle/service/nvnflinger/ui/graphic_buffer.cpp
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#include "core/hle/service/nvdrv/core/nvmap.h"
|
||||||
|
#include "core/hle/service/nvnflinger/ui/graphic_buffer.h"
|
||||||
|
|
||||||
|
namespace Service::android {
|
||||||
|
|
||||||
|
static NvGraphicBuffer GetBuffer(std::shared_ptr<NvGraphicBuffer>& buffer) {
|
||||||
|
if (buffer) {
|
||||||
|
return *buffer;
|
||||||
|
} else {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GraphicBuffer::GraphicBuffer(u32 width_, u32 height_, PixelFormat format_, u32 usage_)
|
||||||
|
: NvGraphicBuffer(width_, height_, format_, usage_), m_nvmap(nullptr) {}
|
||||||
|
|
||||||
|
GraphicBuffer::GraphicBuffer(Service::Nvidia::NvCore::NvMap& nvmap,
|
||||||
|
std::shared_ptr<NvGraphicBuffer> buffer)
|
||||||
|
: NvGraphicBuffer(GetBuffer(buffer)), m_nvmap(std::addressof(nvmap)) {
|
||||||
|
if (this->BufferId() > 0) {
|
||||||
|
m_nvmap->DuplicateHandle(this->BufferId(), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GraphicBuffer::~GraphicBuffer() {
|
||||||
|
if (m_nvmap != nullptr && this->BufferId() > 0) {
|
||||||
|
m_nvmap->FreeHandle(this->BufferId(), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Service::android
|
|
@ -6,16 +6,22 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "common/common_funcs.h"
|
#include "common/common_funcs.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/hle/service/nvnflinger/pixel_format.h"
|
#include "core/hle/service/nvnflinger/pixel_format.h"
|
||||||
|
|
||||||
|
namespace Service::Nvidia::NvCore {
|
||||||
|
class NvMap;
|
||||||
|
} // namespace Service::Nvidia::NvCore
|
||||||
|
|
||||||
namespace Service::android {
|
namespace Service::android {
|
||||||
|
|
||||||
struct GraphicBuffer final {
|
struct NvGraphicBuffer {
|
||||||
constexpr GraphicBuffer() = default;
|
constexpr NvGraphicBuffer() = default;
|
||||||
|
|
||||||
constexpr GraphicBuffer(u32 width_, u32 height_, PixelFormat format_, u32 usage_)
|
constexpr NvGraphicBuffer(u32 width_, u32 height_, PixelFormat format_, u32 usage_)
|
||||||
: width{static_cast<s32>(width_)}, height{static_cast<s32>(height_)}, format{format_},
|
: width{static_cast<s32>(width_)}, height{static_cast<s32>(height_)}, format{format_},
|
||||||
usage{static_cast<s32>(usage_)} {}
|
usage{static_cast<s32>(usage_)} {}
|
||||||
|
|
||||||
|
@ -93,6 +99,17 @@ struct GraphicBuffer final {
|
||||||
u32 offset{};
|
u32 offset{};
|
||||||
INSERT_PADDING_WORDS(60);
|
INSERT_PADDING_WORDS(60);
|
||||||
};
|
};
|
||||||
static_assert(sizeof(GraphicBuffer) == 0x16C, "GraphicBuffer has wrong size");
|
static_assert(sizeof(NvGraphicBuffer) == 0x16C, "NvGraphicBuffer has wrong size");
|
||||||
|
|
||||||
|
class GraphicBuffer final : public NvGraphicBuffer {
|
||||||
|
public:
|
||||||
|
explicit GraphicBuffer(u32 width, u32 height, PixelFormat format, u32 usage);
|
||||||
|
explicit GraphicBuffer(Service::Nvidia::NvCore::NvMap& nvmap,
|
||||||
|
std::shared_ptr<NvGraphicBuffer> buffer);
|
||||||
|
~GraphicBuffer();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Service::Nvidia::NvCore::NvMap* m_nvmap{};
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace Service::android
|
} // namespace Service::android
|
||||||
|
|
|
@ -35,7 +35,7 @@ static BufferQueue CreateBufferQueue(KernelHelpers::ServiceContext& service_cont
|
||||||
return {
|
return {
|
||||||
buffer_queue_core,
|
buffer_queue_core,
|
||||||
std::make_unique<android::BufferQueueProducer>(service_context, buffer_queue_core, nvmap),
|
std::make_unique<android::BufferQueueProducer>(service_context, buffer_queue_core, nvmap),
|
||||||
std::make_unique<android::BufferQueueConsumer>(buffer_queue_core, nvmap)};
|
std::make_unique<android::BufferQueueConsumer>(buffer_queue_core)};
|
||||||
}
|
}
|
||||||
|
|
||||||
Display::Display(u64 id, std::string name_,
|
Display::Display(u64 id, std::string name_,
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
// SPDX-FileCopyrightText: 2015 Citra Emulator Project
|
// SPDX-FileCopyrightText: 2015 Citra Emulator Project
|
||||||
|
// SPDX-FileCopyrightText: 2018 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <mutex>
|
||||||
#include <span>
|
#include <span>
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
|
@ -10,6 +12,7 @@
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/page_table.h"
|
#include "common/page_table.h"
|
||||||
|
#include "common/scope_exit.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "common/swap.h"
|
#include "common/swap.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
@ -318,7 +321,7 @@ struct Memory::Impl {
|
||||||
[&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount,
|
[&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount,
|
||||||
u8* const host_ptr) {
|
u8* const host_ptr) {
|
||||||
if constexpr (!UNSAFE) {
|
if constexpr (!UNSAFE) {
|
||||||
system.GPU().InvalidateRegion(GetInteger(current_vaddr), copy_amount);
|
HandleRasterizerWrite(GetInteger(current_vaddr), copy_amount);
|
||||||
}
|
}
|
||||||
std::memcpy(host_ptr, src_buffer, copy_amount);
|
std::memcpy(host_ptr, src_buffer, copy_amount);
|
||||||
},
|
},
|
||||||
|
@ -351,7 +354,7 @@ struct Memory::Impl {
|
||||||
},
|
},
|
||||||
[&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount,
|
[&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount,
|
||||||
u8* const host_ptr) {
|
u8* const host_ptr) {
|
||||||
system.GPU().InvalidateRegion(GetInteger(current_vaddr), copy_amount);
|
HandleRasterizerWrite(GetInteger(current_vaddr), copy_amount);
|
||||||
std::memset(host_ptr, 0, copy_amount);
|
std::memset(host_ptr, 0, copy_amount);
|
||||||
},
|
},
|
||||||
[](const std::size_t copy_amount) {});
|
[](const std::size_t copy_amount) {});
|
||||||
|
@ -420,7 +423,7 @@ struct Memory::Impl {
|
||||||
const std::size_t block_size) {
|
const std::size_t block_size) {
|
||||||
// dc cvac: Store to point of coherency
|
// dc cvac: Store to point of coherency
|
||||||
// CPU flush -> GPU invalidate
|
// CPU flush -> GPU invalidate
|
||||||
system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size);
|
HandleRasterizerWrite(GetInteger(current_vaddr), block_size);
|
||||||
};
|
};
|
||||||
return PerformCacheOperation(dest_addr, size, on_rasterizer);
|
return PerformCacheOperation(dest_addr, size, on_rasterizer);
|
||||||
}
|
}
|
||||||
|
@ -430,7 +433,7 @@ struct Memory::Impl {
|
||||||
const std::size_t block_size) {
|
const std::size_t block_size) {
|
||||||
// dc civac: Store to point of coherency, and invalidate from cache
|
// dc civac: Store to point of coherency, and invalidate from cache
|
||||||
// CPU flush -> GPU invalidate
|
// CPU flush -> GPU invalidate
|
||||||
system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size);
|
HandleRasterizerWrite(GetInteger(current_vaddr), block_size);
|
||||||
};
|
};
|
||||||
return PerformCacheOperation(dest_addr, size, on_rasterizer);
|
return PerformCacheOperation(dest_addr, size, on_rasterizer);
|
||||||
}
|
}
|
||||||
|
@ -767,7 +770,18 @@ struct Memory::Impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleRasterizerWrite(VAddr address, size_t size) {
|
void HandleRasterizerWrite(VAddr address, size_t size) {
|
||||||
const size_t core = system.GetCurrentHostThreadID();
|
constexpr size_t sys_core = Core::Hardware::NUM_CPU_CORES - 1;
|
||||||
|
const size_t core = std::min(system.GetCurrentHostThreadID(),
|
||||||
|
sys_core); // any other calls threads go to syscore.
|
||||||
|
// Guard on sys_core;
|
||||||
|
if (core == sys_core) [[unlikely]] {
|
||||||
|
sys_core_guard.lock();
|
||||||
|
}
|
||||||
|
SCOPE_EXIT({
|
||||||
|
if (core == sys_core) [[unlikely]] {
|
||||||
|
sys_core_guard.unlock();
|
||||||
|
}
|
||||||
|
});
|
||||||
auto& current_area = rasterizer_write_areas[core];
|
auto& current_area = rasterizer_write_areas[core];
|
||||||
VAddr subaddress = address >> YUZU_PAGEBITS;
|
VAddr subaddress = address >> YUZU_PAGEBITS;
|
||||||
bool do_collection = current_area.last_address == subaddress;
|
bool do_collection = current_area.last_address == subaddress;
|
||||||
|
@ -799,6 +813,7 @@ struct Memory::Impl {
|
||||||
rasterizer_read_areas{};
|
rasterizer_read_areas{};
|
||||||
std::array<GPUDirtyState, Core::Hardware::NUM_CPU_CORES> rasterizer_write_areas{};
|
std::array<GPUDirtyState, Core::Hardware::NUM_CPU_CORES> rasterizer_write_areas{};
|
||||||
std::span<Core::GPUDirtyMemoryManager> gpu_dirty_managers;
|
std::span<Core::GPUDirtyMemoryManager> gpu_dirty_managers;
|
||||||
|
std::mutex sys_core_guard;
|
||||||
};
|
};
|
||||||
|
|
||||||
Memory::Memory(Core::System& system_) : system{system_} {
|
Memory::Memory(Core::System& system_) : system{system_} {
|
||||||
|
|
|
@ -415,7 +415,7 @@ ButtonMapping GCAdapter::GetButtonMappingForDevice(const Common::ParamPackage& p
|
||||||
// This list is missing ZL/ZR since those are not considered buttons.
|
// This list is missing ZL/ZR since those are not considered buttons.
|
||||||
// We will add those afterwards
|
// We will add those afterwards
|
||||||
// This list also excludes any button that can't be really mapped
|
// This list also excludes any button that can't be really mapped
|
||||||
static constexpr std::array<std::pair<Settings::NativeButton::Values, PadButton>, 12>
|
static constexpr std::array<std::pair<Settings::NativeButton::Values, PadButton>, 14>
|
||||||
switch_to_gcadapter_button = {
|
switch_to_gcadapter_button = {
|
||||||
std::pair{Settings::NativeButton::A, PadButton::ButtonA},
|
std::pair{Settings::NativeButton::A, PadButton::ButtonA},
|
||||||
{Settings::NativeButton::B, PadButton::ButtonB},
|
{Settings::NativeButton::B, PadButton::ButtonB},
|
||||||
|
@ -426,8 +426,10 @@ ButtonMapping GCAdapter::GetButtonMappingForDevice(const Common::ParamPackage& p
|
||||||
{Settings::NativeButton::DUp, PadButton::ButtonUp},
|
{Settings::NativeButton::DUp, PadButton::ButtonUp},
|
||||||
{Settings::NativeButton::DRight, PadButton::ButtonRight},
|
{Settings::NativeButton::DRight, PadButton::ButtonRight},
|
||||||
{Settings::NativeButton::DDown, PadButton::ButtonDown},
|
{Settings::NativeButton::DDown, PadButton::ButtonDown},
|
||||||
{Settings::NativeButton::SL, PadButton::TriggerL},
|
{Settings::NativeButton::SLLeft, PadButton::TriggerL},
|
||||||
{Settings::NativeButton::SR, PadButton::TriggerR},
|
{Settings::NativeButton::SRLeft, PadButton::TriggerR},
|
||||||
|
{Settings::NativeButton::SLRight, PadButton::TriggerL},
|
||||||
|
{Settings::NativeButton::SRRight, PadButton::TriggerR},
|
||||||
{Settings::NativeButton::R, PadButton::TriggerZ},
|
{Settings::NativeButton::R, PadButton::TriggerZ},
|
||||||
};
|
};
|
||||||
if (!params.Has("port")) {
|
if (!params.Has("port")) {
|
||||||
|
|
|
@ -680,8 +680,8 @@ ButtonMapping Joycons::GetButtonMappingForDevice(const Common::ParamPackage& par
|
||||||
Common::ParamPackage sr_button_params = button_params;
|
Common::ParamPackage sr_button_params = button_params;
|
||||||
sl_button_params.Set("button", static_cast<int>(Joycon::PadButton::LeftSL));
|
sl_button_params.Set("button", static_cast<int>(Joycon::PadButton::LeftSL));
|
||||||
sr_button_params.Set("button", static_cast<int>(Joycon::PadButton::LeftSR));
|
sr_button_params.Set("button", static_cast<int>(Joycon::PadButton::LeftSR));
|
||||||
mapping.insert_or_assign(Settings::NativeButton::SL, std::move(sl_button_params));
|
mapping.insert_or_assign(Settings::NativeButton::SLLeft, std::move(sl_button_params));
|
||||||
mapping.insert_or_assign(Settings::NativeButton::SR, std::move(sr_button_params));
|
mapping.insert_or_assign(Settings::NativeButton::SRLeft, std::move(sr_button_params));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map SL and SR buttons for right joycons
|
// Map SL and SR buttons for right joycons
|
||||||
|
@ -693,8 +693,8 @@ ButtonMapping Joycons::GetButtonMappingForDevice(const Common::ParamPackage& par
|
||||||
Common::ParamPackage sr_button_params = button_params;
|
Common::ParamPackage sr_button_params = button_params;
|
||||||
sl_button_params.Set("button", static_cast<int>(Joycon::PadButton::RightSL));
|
sl_button_params.Set("button", static_cast<int>(Joycon::PadButton::RightSL));
|
||||||
sr_button_params.Set("button", static_cast<int>(Joycon::PadButton::RightSR));
|
sr_button_params.Set("button", static_cast<int>(Joycon::PadButton::RightSR));
|
||||||
mapping.insert_or_assign(Settings::NativeButton::SL, std::move(sl_button_params));
|
mapping.insert_or_assign(Settings::NativeButton::SLRight, std::move(sl_button_params));
|
||||||
mapping.insert_or_assign(Settings::NativeButton::SR, std::move(sr_button_params));
|
mapping.insert_or_assign(Settings::NativeButton::SRRight, std::move(sr_button_params));
|
||||||
}
|
}
|
||||||
|
|
||||||
return mapping;
|
return mapping;
|
||||||
|
|
|
@ -828,16 +828,18 @@ ButtonMapping SDLDriver::GetButtonMappingForDevice(const Common::ParamPackage& p
|
||||||
ButtonBindings SDLDriver::GetDefaultButtonBinding(
|
ButtonBindings SDLDriver::GetDefaultButtonBinding(
|
||||||
const std::shared_ptr<SDLJoystick>& joystick) const {
|
const std::shared_ptr<SDLJoystick>& joystick) const {
|
||||||
// Default SL/SR mapping for other controllers
|
// Default SL/SR mapping for other controllers
|
||||||
auto sl_button = SDL_CONTROLLER_BUTTON_LEFTSHOULDER;
|
auto sll_button = SDL_CONTROLLER_BUTTON_LEFTSHOULDER;
|
||||||
auto sr_button = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER;
|
auto srl_button = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER;
|
||||||
|
auto slr_button = SDL_CONTROLLER_BUTTON_LEFTSHOULDER;
|
||||||
|
auto srr_button = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER;
|
||||||
|
|
||||||
if (joystick->IsJoyconLeft()) {
|
if (joystick->IsJoyconLeft()) {
|
||||||
sl_button = SDL_CONTROLLER_BUTTON_PADDLE2;
|
sll_button = SDL_CONTROLLER_BUTTON_PADDLE2;
|
||||||
sr_button = SDL_CONTROLLER_BUTTON_PADDLE4;
|
srl_button = SDL_CONTROLLER_BUTTON_PADDLE4;
|
||||||
}
|
}
|
||||||
if (joystick->IsJoyconRight()) {
|
if (joystick->IsJoyconRight()) {
|
||||||
sl_button = SDL_CONTROLLER_BUTTON_PADDLE3;
|
slr_button = SDL_CONTROLLER_BUTTON_PADDLE3;
|
||||||
sr_button = SDL_CONTROLLER_BUTTON_PADDLE1;
|
srr_button = SDL_CONTROLLER_BUTTON_PADDLE1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -855,8 +857,10 @@ ButtonBindings SDLDriver::GetDefaultButtonBinding(
|
||||||
{Settings::NativeButton::DUp, SDL_CONTROLLER_BUTTON_DPAD_UP},
|
{Settings::NativeButton::DUp, SDL_CONTROLLER_BUTTON_DPAD_UP},
|
||||||
{Settings::NativeButton::DRight, SDL_CONTROLLER_BUTTON_DPAD_RIGHT},
|
{Settings::NativeButton::DRight, SDL_CONTROLLER_BUTTON_DPAD_RIGHT},
|
||||||
{Settings::NativeButton::DDown, SDL_CONTROLLER_BUTTON_DPAD_DOWN},
|
{Settings::NativeButton::DDown, SDL_CONTROLLER_BUTTON_DPAD_DOWN},
|
||||||
{Settings::NativeButton::SL, sl_button},
|
{Settings::NativeButton::SLLeft, sll_button},
|
||||||
{Settings::NativeButton::SR, sr_button},
|
{Settings::NativeButton::SRLeft, srl_button},
|
||||||
|
{Settings::NativeButton::SLRight, slr_button},
|
||||||
|
{Settings::NativeButton::SRRight, srr_button},
|
||||||
{Settings::NativeButton::Home, SDL_CONTROLLER_BUTTON_GUIDE},
|
{Settings::NativeButton::Home, SDL_CONTROLLER_BUTTON_GUIDE},
|
||||||
{Settings::NativeButton::Screenshot, SDL_CONTROLLER_BUTTON_MISC1},
|
{Settings::NativeButton::Screenshot, SDL_CONTROLLER_BUTTON_MISC1},
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace InputCommon {
|
||||||
class SDLJoystick;
|
class SDLJoystick;
|
||||||
|
|
||||||
using ButtonBindings =
|
using ButtonBindings =
|
||||||
std::array<std::pair<Settings::NativeButton::Values, SDL_GameControllerButton>, 18>;
|
std::array<std::pair<Settings::NativeButton::Values, SDL_GameControllerButton>, 20>;
|
||||||
using ZButtonBindings =
|
using ZButtonBindings =
|
||||||
std::array<std::pair<Settings::NativeButton::Values, SDL_GameControllerAxis>, 2>;
|
std::array<std::pair<Settings::NativeButton::Values, SDL_GameControllerAxis>, 2>;
|
||||||
|
|
||||||
|
|
|
@ -396,7 +396,7 @@ std::vector<Common::ParamPackage> UDPClient::GetInputDevices() const {
|
||||||
|
|
||||||
ButtonMapping UDPClient::GetButtonMappingForDevice(const Common::ParamPackage& params) {
|
ButtonMapping UDPClient::GetButtonMappingForDevice(const Common::ParamPackage& params) {
|
||||||
// This list excludes any button that can't be really mapped
|
// This list excludes any button that can't be really mapped
|
||||||
static constexpr std::array<std::pair<Settings::NativeButton::Values, PadButton>, 20>
|
static constexpr std::array<std::pair<Settings::NativeButton::Values, PadButton>, 22>
|
||||||
switch_to_dsu_button = {
|
switch_to_dsu_button = {
|
||||||
std::pair{Settings::NativeButton::A, PadButton::Circle},
|
std::pair{Settings::NativeButton::A, PadButton::Circle},
|
||||||
{Settings::NativeButton::B, PadButton::Cross},
|
{Settings::NativeButton::B, PadButton::Cross},
|
||||||
|
@ -412,8 +412,10 @@ ButtonMapping UDPClient::GetButtonMappingForDevice(const Common::ParamPackage& p
|
||||||
{Settings::NativeButton::R, PadButton::R1},
|
{Settings::NativeButton::R, PadButton::R1},
|
||||||
{Settings::NativeButton::ZL, PadButton::L2},
|
{Settings::NativeButton::ZL, PadButton::L2},
|
||||||
{Settings::NativeButton::ZR, PadButton::R2},
|
{Settings::NativeButton::ZR, PadButton::R2},
|
||||||
{Settings::NativeButton::SL, PadButton::L2},
|
{Settings::NativeButton::SLLeft, PadButton::L2},
|
||||||
{Settings::NativeButton::SR, PadButton::R2},
|
{Settings::NativeButton::SRLeft, PadButton::R2},
|
||||||
|
{Settings::NativeButton::SLRight, PadButton::L2},
|
||||||
|
{Settings::NativeButton::SRRight, PadButton::R2},
|
||||||
{Settings::NativeButton::LStick, PadButton::L3},
|
{Settings::NativeButton::LStick, PadButton::L3},
|
||||||
{Settings::NativeButton::RStick, PadButton::R3},
|
{Settings::NativeButton::RStick, PadButton::R3},
|
||||||
{Settings::NativeButton::Home, PadButton::Home},
|
{Settings::NativeButton::Home, PadButton::Home},
|
||||||
|
|
|
@ -86,10 +86,7 @@ public:
|
||||||
uncommitted_operations.emplace_back(std::move(func));
|
uncommitted_operations.emplace_back(std::move(func));
|
||||||
}
|
}
|
||||||
pending_operations.emplace_back(std::move(uncommitted_operations));
|
pending_operations.emplace_back(std::move(uncommitted_operations));
|
||||||
{
|
QueueFence(new_fence);
|
||||||
std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
|
|
||||||
QueueFence(new_fence);
|
|
||||||
}
|
|
||||||
if (!delay_fence) {
|
if (!delay_fence) {
|
||||||
func();
|
func();
|
||||||
}
|
}
|
||||||
|
|
|
@ -555,7 +555,7 @@ void RasterizerOpenGL::OnCacheInvalidation(VAddr addr, u64 size) {
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::scoped_lock lock{buffer_cache.mutex};
|
std::scoped_lock lock{buffer_cache.mutex};
|
||||||
buffer_cache.CachedWriteMemory(addr, size);
|
buffer_cache.WriteMemory(addr, size);
|
||||||
}
|
}
|
||||||
shader_cache.InvalidateRegion(addr, size);
|
shader_cache.InvalidateRegion(addr, size);
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,16 +132,12 @@ void RendererVulkan::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
|
||||||
const bool use_accelerated =
|
const bool use_accelerated =
|
||||||
rasterizer.AccelerateDisplay(*framebuffer, framebuffer_addr, framebuffer->stride);
|
rasterizer.AccelerateDisplay(*framebuffer, framebuffer_addr, framebuffer->stride);
|
||||||
const bool is_srgb = use_accelerated && screen_info.is_srgb;
|
const bool is_srgb = use_accelerated && screen_info.is_srgb;
|
||||||
|
RenderScreenshot(*framebuffer, use_accelerated);
|
||||||
|
|
||||||
{
|
Frame* frame = present_manager.GetRenderFrame();
|
||||||
std::scoped_lock lock{rasterizer.LockCaches()};
|
blit_screen.DrawToSwapchain(frame, *framebuffer, use_accelerated, is_srgb);
|
||||||
RenderScreenshot(*framebuffer, use_accelerated);
|
scheduler.Flush(*frame->render_ready);
|
||||||
|
present_manager.Present(frame);
|
||||||
Frame* frame = present_manager.GetRenderFrame();
|
|
||||||
blit_screen.DrawToSwapchain(frame, *framebuffer, use_accelerated, is_srgb);
|
|
||||||
scheduler.Flush(*frame->render_ready);
|
|
||||||
present_manager.Present(frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
gpu.RendererFrameEndNotify();
|
gpu.RendererFrameEndNotify();
|
||||||
rasterizer.TickFrame();
|
rasterizer.TickFrame();
|
||||||
|
|
|
@ -199,7 +199,7 @@ void RasterizerVulkan::PrepareDraw(bool is_indexed, Func&& draw_func) {
|
||||||
if (!pipeline) {
|
if (!pipeline) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::scoped_lock lock{LockCaches()};
|
std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
|
||||||
// update engine as channel may be different.
|
// update engine as channel may be different.
|
||||||
pipeline->SetEngine(maxwell3d, gpu_memory);
|
pipeline->SetEngine(maxwell3d, gpu_memory);
|
||||||
pipeline->Configure(is_indexed);
|
pipeline->Configure(is_indexed);
|
||||||
|
@ -621,7 +621,7 @@ void RasterizerVulkan::OnCacheInvalidation(VAddr addr, u64 size) {
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::scoped_lock lock{buffer_cache.mutex};
|
std::scoped_lock lock{buffer_cache.mutex};
|
||||||
buffer_cache.CachedWriteMemory(addr, size);
|
buffer_cache.WriteMemory(addr, size);
|
||||||
}
|
}
|
||||||
pipeline_cache.InvalidateRegion(addr, size);
|
pipeline_cache.InvalidateRegion(addr, size);
|
||||||
}
|
}
|
||||||
|
@ -710,7 +710,6 @@ void RasterizerVulkan::TiledCacheBarrier() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerVulkan::FlushCommands() {
|
void RasterizerVulkan::FlushCommands() {
|
||||||
std::scoped_lock lock{LockCaches()};
|
|
||||||
if (draw_counter == 0) {
|
if (draw_counter == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -808,7 +807,6 @@ void RasterizerVulkan::FlushWork() {
|
||||||
if ((++draw_counter & 7) != 7) {
|
if ((++draw_counter & 7) != 7) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::scoped_lock lock{LockCaches()};
|
|
||||||
if (draw_counter < DRAWS_TO_DISPATCH) {
|
if (draw_counter < DRAWS_TO_DISPATCH) {
|
||||||
// Send recorded tasks to the worker thread
|
// Send recorded tasks to the worker thread
|
||||||
scheduler.DispatchWork();
|
scheduler.DispatchWork();
|
||||||
|
@ -1507,7 +1505,7 @@ void RasterizerVulkan::UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs)
|
||||||
void RasterizerVulkan::InitializeChannel(Tegra::Control::ChannelState& channel) {
|
void RasterizerVulkan::InitializeChannel(Tegra::Control::ChannelState& channel) {
|
||||||
CreateChannel(channel);
|
CreateChannel(channel);
|
||||||
{
|
{
|
||||||
std::scoped_lock lock{LockCaches()};
|
std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
|
||||||
texture_cache.CreateChannel(channel);
|
texture_cache.CreateChannel(channel);
|
||||||
buffer_cache.CreateChannel(channel);
|
buffer_cache.CreateChannel(channel);
|
||||||
}
|
}
|
||||||
|
@ -1520,7 +1518,7 @@ void RasterizerVulkan::BindChannel(Tegra::Control::ChannelState& channel) {
|
||||||
const s32 channel_id = channel.bind_id;
|
const s32 channel_id = channel.bind_id;
|
||||||
BindToChannel(channel_id);
|
BindToChannel(channel_id);
|
||||||
{
|
{
|
||||||
std::scoped_lock lock{LockCaches()};
|
std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
|
||||||
texture_cache.BindToChannel(channel_id);
|
texture_cache.BindToChannel(channel_id);
|
||||||
buffer_cache.BindToChannel(channel_id);
|
buffer_cache.BindToChannel(channel_id);
|
||||||
}
|
}
|
||||||
|
@ -1533,7 +1531,7 @@ void RasterizerVulkan::BindChannel(Tegra::Control::ChannelState& channel) {
|
||||||
void RasterizerVulkan::ReleaseChannel(s32 channel_id) {
|
void RasterizerVulkan::ReleaseChannel(s32 channel_id) {
|
||||||
EraseChannel(channel_id);
|
EraseChannel(channel_id);
|
||||||
{
|
{
|
||||||
std::scoped_lock lock{LockCaches()};
|
std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
|
||||||
texture_cache.EraseChannel(channel_id);
|
texture_cache.EraseChannel(channel_id);
|
||||||
buffer_cache.EraseChannel(channel_id);
|
buffer_cache.EraseChannel(channel_id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,10 +133,6 @@ public:
|
||||||
|
|
||||||
void ReleaseChannel(s32 channel_id) override;
|
void ReleaseChannel(s32 channel_id) override;
|
||||||
|
|
||||||
std::scoped_lock<std::recursive_mutex, std::recursive_mutex> LockCaches() {
|
|
||||||
return std::scoped_lock{buffer_cache.mutex, texture_cache.mutex};
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr size_t MAX_TEXTURES = 192;
|
static constexpr size_t MAX_TEXTURES = 192;
|
||||||
static constexpr size_t MAX_IMAGES = 48;
|
static constexpr size_t MAX_IMAGES = 48;
|
||||||
|
|
|
@ -35,6 +35,7 @@ const std::array<int, Settings::NativeButton::NumButtons> Config::default_button
|
||||||
Qt::Key_G, Qt::Key_Q, Qt::Key_E, Qt::Key_R, Qt::Key_T,
|
Qt::Key_G, Qt::Key_Q, Qt::Key_E, Qt::Key_R, Qt::Key_T,
|
||||||
Qt::Key_M, Qt::Key_N, Qt::Key_Left, Qt::Key_Up, Qt::Key_Right,
|
Qt::Key_M, Qt::Key_N, Qt::Key_Left, Qt::Key_Up, Qt::Key_Right,
|
||||||
Qt::Key_Down, Qt::Key_Q, Qt::Key_E, 0, 0,
|
Qt::Key_Down, Qt::Key_Q, Qt::Key_E, 0, 0,
|
||||||
|
Qt::Key_Q, Qt::Key_E,
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::array<int, Settings::NativeMotion::NumMotions> Config::default_motions = {
|
const std::array<int, Settings::NativeMotion::NumMotions> Config::default_motions = {
|
||||||
|
|
|
@ -322,11 +322,12 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
|
||||||
setFocusPolicy(Qt::ClickFocus);
|
setFocusPolicy(Qt::ClickFocus);
|
||||||
|
|
||||||
button_map = {
|
button_map = {
|
||||||
ui->buttonA, ui->buttonB, ui->buttonX, ui->buttonY,
|
ui->buttonA, ui->buttonB, ui->buttonX, ui->buttonY,
|
||||||
ui->buttonLStick, ui->buttonRStick, ui->buttonL, ui->buttonR,
|
ui->buttonLStick, ui->buttonRStick, ui->buttonL, ui->buttonR,
|
||||||
ui->buttonZL, ui->buttonZR, ui->buttonPlus, ui->buttonMinus,
|
ui->buttonZL, ui->buttonZR, ui->buttonPlus, ui->buttonMinus,
|
||||||
ui->buttonDpadLeft, ui->buttonDpadUp, ui->buttonDpadRight, ui->buttonDpadDown,
|
ui->buttonDpadLeft, ui->buttonDpadUp, ui->buttonDpadRight, ui->buttonDpadDown,
|
||||||
ui->buttonSL, ui->buttonSR, ui->buttonHome, ui->buttonScreenshot,
|
ui->buttonSLLeft, ui->buttonSRLeft, ui->buttonHome, ui->buttonScreenshot,
|
||||||
|
ui->buttonSLRight, ui->buttonSRRight,
|
||||||
};
|
};
|
||||||
|
|
||||||
analog_map_buttons = {{
|
analog_map_buttons = {{
|
||||||
|
@ -1181,10 +1182,13 @@ void ConfigureInputPlayer::UpdateControllerAvailableButtons() {
|
||||||
|
|
||||||
// List of all the widgets that will be hidden by any of the following layouts that need
|
// List of all the widgets that will be hidden by any of the following layouts that need
|
||||||
// "unhidden" after the controller type changes
|
// "unhidden" after the controller type changes
|
||||||
const std::array<QWidget*, 11> layout_show = {
|
const std::array<QWidget*, 14> layout_show = {
|
||||||
ui->buttonShoulderButtonsSLSR,
|
ui->buttonShoulderButtonsSLSRLeft,
|
||||||
|
ui->buttonShoulderButtonsSLSRRight,
|
||||||
ui->horizontalSpacerShoulderButtonsWidget,
|
ui->horizontalSpacerShoulderButtonsWidget,
|
||||||
ui->horizontalSpacerShoulderButtonsWidget2,
|
ui->horizontalSpacerShoulderButtonsWidget2,
|
||||||
|
ui->horizontalSpacerShoulderButtonsWidget3,
|
||||||
|
ui->horizontalSpacerShoulderButtonsWidget4,
|
||||||
ui->buttonShoulderButtonsLeft,
|
ui->buttonShoulderButtonsLeft,
|
||||||
ui->buttonMiscButtonsMinusScreenshot,
|
ui->buttonMiscButtonsMinusScreenshot,
|
||||||
ui->bottomLeft,
|
ui->bottomLeft,
|
||||||
|
@ -1202,16 +1206,19 @@ void ConfigureInputPlayer::UpdateControllerAvailableButtons() {
|
||||||
std::vector<QWidget*> layout_hidden;
|
std::vector<QWidget*> layout_hidden;
|
||||||
switch (layout) {
|
switch (layout) {
|
||||||
case Core::HID::NpadStyleIndex::ProController:
|
case Core::HID::NpadStyleIndex::ProController:
|
||||||
case Core::HID::NpadStyleIndex::JoyconDual:
|
|
||||||
case Core::HID::NpadStyleIndex::Handheld:
|
case Core::HID::NpadStyleIndex::Handheld:
|
||||||
layout_hidden = {
|
layout_hidden = {
|
||||||
ui->buttonShoulderButtonsSLSR,
|
ui->buttonShoulderButtonsSLSRLeft,
|
||||||
|
ui->buttonShoulderButtonsSLSRRight,
|
||||||
ui->horizontalSpacerShoulderButtonsWidget2,
|
ui->horizontalSpacerShoulderButtonsWidget2,
|
||||||
|
ui->horizontalSpacerShoulderButtonsWidget4,
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case Core::HID::NpadStyleIndex::JoyconLeft:
|
case Core::HID::NpadStyleIndex::JoyconLeft:
|
||||||
layout_hidden = {
|
layout_hidden = {
|
||||||
|
ui->buttonShoulderButtonsSLSRRight,
|
||||||
ui->horizontalSpacerShoulderButtonsWidget2,
|
ui->horizontalSpacerShoulderButtonsWidget2,
|
||||||
|
ui->horizontalSpacerShoulderButtonsWidget3,
|
||||||
ui->buttonShoulderButtonsRight,
|
ui->buttonShoulderButtonsRight,
|
||||||
ui->buttonMiscButtonsPlusHome,
|
ui->buttonMiscButtonsPlusHome,
|
||||||
ui->bottomRight,
|
ui->bottomRight,
|
||||||
|
@ -1219,16 +1226,17 @@ void ConfigureInputPlayer::UpdateControllerAvailableButtons() {
|
||||||
break;
|
break;
|
||||||
case Core::HID::NpadStyleIndex::JoyconRight:
|
case Core::HID::NpadStyleIndex::JoyconRight:
|
||||||
layout_hidden = {
|
layout_hidden = {
|
||||||
ui->horizontalSpacerShoulderButtonsWidget,
|
ui->buttonShoulderButtonsSLSRLeft, ui->horizontalSpacerShoulderButtonsWidget,
|
||||||
ui->buttonShoulderButtonsLeft,
|
ui->horizontalSpacerShoulderButtonsWidget4, ui->buttonShoulderButtonsLeft,
|
||||||
ui->buttonMiscButtonsMinusScreenshot,
|
ui->buttonMiscButtonsMinusScreenshot, ui->bottomLeft,
|
||||||
ui->bottomLeft,
|
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case Core::HID::NpadStyleIndex::GameCube:
|
case Core::HID::NpadStyleIndex::GameCube:
|
||||||
layout_hidden = {
|
layout_hidden = {
|
||||||
ui->buttonShoulderButtonsSLSR,
|
ui->buttonShoulderButtonsSLSRLeft,
|
||||||
|
ui->buttonShoulderButtonsSLSRRight,
|
||||||
ui->horizontalSpacerShoulderButtonsWidget2,
|
ui->horizontalSpacerShoulderButtonsWidget2,
|
||||||
|
ui->horizontalSpacerShoulderButtonsWidget4,
|
||||||
ui->buttonMiscButtonsMinusGroup,
|
ui->buttonMiscButtonsMinusGroup,
|
||||||
ui->buttonMiscButtonsScreenshotGroup,
|
ui->buttonMiscButtonsScreenshotGroup,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1208,6 +1208,159 @@
|
||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>3</number>
|
<number>3</number>
|
||||||
</property>
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="buttonShoulderButtonsSLSRLeft" native="true">
|
||||||
|
<layout class="QVBoxLayout" name="buttonShoulderButtonsSLSRLeftVerticalLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item alignment="Qt::AlignHCenter">
|
||||||
|
<widget class="QGroupBox" name="buttonShoulderButtonsSLLeftGroup">
|
||||||
|
<property name="title">
|
||||||
|
<string>SL</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="buttonShoulderButtonsSLLeftVerticalLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="buttonSLLeft">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>68</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>68</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">min-width: 68px;</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>SL</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item alignment="Qt::AlignHCenter">
|
||||||
|
<widget class="QGroupBox" name="buttonShoulderButtonsSRLeftGroup">
|
||||||
|
<property name="title">
|
||||||
|
<string>SR</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="buttonShoulderButtonsSRLeftVerticalLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="buttonSRLeft">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>68</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>68</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">min-width: 68px;</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>SR</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="horizontalSpacerShoulderButtonsWidget4" native="true">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalSpacerShoulderButtonsWidget4Layout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacerShoulderButtons5">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QWidget" name="buttonShoulderButtonsLeft" native="true">
|
<widget class="QWidget" name="buttonShoulderButtonsLeft" native="true">
|
||||||
<layout class="QVBoxLayout" name="buttonShoulderButtonsLeftVerticalLayout">
|
<layout class="QVBoxLayout" name="buttonShoulderButtonsLeftVerticalLayout">
|
||||||
|
@ -1830,125 +1983,125 @@
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QWidget" name="buttonShoulderButtonsSLSR" native="true">
|
<widget class="QWidget" name="buttonShoulderButtonsSLSRRight" native="true">
|
||||||
<layout class="QVBoxLayout" name="buttonShoulderButtonsSLSRVerticalLayout">
|
<layout class="QVBoxLayout" name="buttonShoulderButtonsSLSRRightVerticalLayout">
|
||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="topMargin">
|
<property name="topMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="rightMargin">
|
<property name="rightMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item alignment="Qt::AlignHCenter">
|
<item alignment="Qt::AlignHCenter">
|
||||||
<widget class="QGroupBox" name="buttonShoulderButtonsSLGroup">
|
<widget class="QGroupBox" name="buttonShoulderButtonsSLRightGroup">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>SL</string>
|
<string>SL</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment">
|
<property name="alignment">
|
||||||
<set>Qt::AlignCenter</set>
|
<set>Qt::AlignCenter</set>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="buttonShoulderButtonsSLVerticalLayout">
|
<layout class="QVBoxLayout" name="buttonShoulderButtonsSLRightVerticalLayout">
|
||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>3</number>
|
<number>3</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>3</number>
|
<number>3</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="topMargin">
|
<property name="topMargin">
|
||||||
<number>3</number>
|
<number>3</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="rightMargin">
|
<property name="rightMargin">
|
||||||
<number>3</number>
|
<number>3</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>3</number>
|
<number>3</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="buttonSL">
|
<widget class="QPushButton" name="buttonSLRight">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>68</width>
|
<width>68</width>
|
||||||
<height>0</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="maximumSize">
|
<property name="maximumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>68</width>
|
<width>68</width>
|
||||||
<height>16777215</height>
|
<height>16777215</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
<string notr="true">min-width: 68px;</string>
|
<string notr="true">min-width: 68px;</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>SL</string>
|
<string>SL</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item alignment="Qt::AlignHCenter">
|
||||||
|
<widget class="QGroupBox" name="buttonShoulderButtonsSRRightGroup">
|
||||||
|
<property name="title">
|
||||||
|
<string>SR</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="buttonShoulderButtonsSRRightVerticalLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="buttonSRRight">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>68</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>68</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">min-width: 68px;</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>SR</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item alignment="Qt::AlignHCenter">
|
|
||||||
<widget class="QGroupBox" name="buttonShoulderButtonsSRGroup">
|
|
||||||
<property name="title">
|
|
||||||
<string>SR</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignCenter</set>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="buttonShoulderButtonsSRVerticalLayout">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>3</number>
|
|
||||||
</property>
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>3</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>3</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>3</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>3</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="buttonSR">
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>68</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>68</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="styleSheet">
|
|
||||||
<string notr="true">min-width: 68px;</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>SR</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
|
|
@ -297,8 +297,8 @@ void PlayerControlPreview::DrawLeftController(QPainter& p, const QPointF center)
|
||||||
|
|
||||||
// Sideview SL and SR buttons
|
// Sideview SL and SR buttons
|
||||||
button_color = colors.slider_button;
|
button_color = colors.slider_button;
|
||||||
DrawRoundButton(p, center + QPoint(59, 52), button_values[SR], 5, 12, Direction::Left);
|
DrawRoundButton(p, center + QPoint(59, 52), button_values[SRLeft], 5, 12, Direction::Left);
|
||||||
DrawRoundButton(p, center + QPoint(59, -69), button_values[SL], 5, 12, Direction::Left);
|
DrawRoundButton(p, center + QPoint(59, -69), button_values[SLLeft], 5, 12, Direction::Left);
|
||||||
|
|
||||||
DrawLeftBody(p, center);
|
DrawLeftBody(p, center);
|
||||||
|
|
||||||
|
@ -353,8 +353,10 @@ void PlayerControlPreview::DrawLeftController(QPainter& p, const QPointF center)
|
||||||
// SR and SL buttons
|
// SR and SL buttons
|
||||||
p.setPen(colors.outline);
|
p.setPen(colors.outline);
|
||||||
button_color = colors.slider_button;
|
button_color = colors.slider_button;
|
||||||
DrawRoundButton(p, center + QPoint(155, 52), button_values[SR], 5.2f, 12, Direction::None, 4);
|
DrawRoundButton(p, center + QPoint(155, 52), button_values[SRLeft], 5.2f, 12, Direction::None,
|
||||||
DrawRoundButton(p, center + QPoint(155, -69), button_values[SL], 5.2f, 12, Direction::None, 4);
|
4);
|
||||||
|
DrawRoundButton(p, center + QPoint(155, -69), button_values[SLLeft], 5.2f, 12, Direction::None,
|
||||||
|
4);
|
||||||
|
|
||||||
// SR and SL text
|
// SR and SL text
|
||||||
p.setPen(colors.transparent);
|
p.setPen(colors.transparent);
|
||||||
|
@ -428,8 +430,10 @@ void PlayerControlPreview::DrawRightController(QPainter& p, const QPointF center
|
||||||
|
|
||||||
// Sideview SL and SR buttons
|
// Sideview SL and SR buttons
|
||||||
button_color = colors.slider_button;
|
button_color = colors.slider_button;
|
||||||
DrawRoundButton(p, center + QPoint(-59, 52), button_values[SL], 5, 11, Direction::Right);
|
DrawRoundButton(p, center + QPoint(-59, 52), button_values[SLRight], 5, 11,
|
||||||
DrawRoundButton(p, center + QPoint(-59, -69), button_values[SR], 5, 11, Direction::Right);
|
Direction::Right);
|
||||||
|
DrawRoundButton(p, center + QPoint(-59, -69), button_values[SRRight], 5, 11,
|
||||||
|
Direction::Right);
|
||||||
|
|
||||||
DrawRightBody(p, center);
|
DrawRightBody(p, center);
|
||||||
|
|
||||||
|
@ -484,8 +488,10 @@ void PlayerControlPreview::DrawRightController(QPainter& p, const QPointF center
|
||||||
// SR and SL buttons
|
// SR and SL buttons
|
||||||
p.setPen(colors.outline);
|
p.setPen(colors.outline);
|
||||||
button_color = colors.slider_button;
|
button_color = colors.slider_button;
|
||||||
DrawRoundButton(p, center + QPoint(-155, 52), button_values[SL], 5, 12, Direction::None, 4.0f);
|
DrawRoundButton(p, center + QPoint(-155, 52), button_values[SLRight], 5, 12, Direction::None,
|
||||||
DrawRoundButton(p, center + QPoint(-155, -69), button_values[SR], 5, 12, Direction::None, 4.0f);
|
4.0f);
|
||||||
|
DrawRoundButton(p, center + QPoint(-155, -69), button_values[SRRight], 5, 12, Direction::None,
|
||||||
|
4.0f);
|
||||||
|
|
||||||
// SR and SL text
|
// SR and SL text
|
||||||
p.setPen(colors.transparent);
|
p.setPen(colors.transparent);
|
||||||
|
@ -557,6 +563,19 @@ void PlayerControlPreview::DrawDualController(QPainter& p, const QPointF center)
|
||||||
DrawRoundButton(p, center + QPoint(-154, -72), button_values[Minus], 7, 4, Direction::Up,
|
DrawRoundButton(p, center + QPoint(-154, -72), button_values[Minus], 7, 4, Direction::Up,
|
||||||
1);
|
1);
|
||||||
|
|
||||||
|
// Left SR and SL sideview buttons
|
||||||
|
button_color = colors.slider_button;
|
||||||
|
DrawRoundButton(p, center + QPoint(-20, -62), button_values[SLLeft], 4, 11,
|
||||||
|
Direction::Left);
|
||||||
|
DrawRoundButton(p, center + QPoint(-20, 47), button_values[SRLeft], 4, 11, Direction::Left);
|
||||||
|
|
||||||
|
// Right SR and SL sideview buttons
|
||||||
|
button_color = colors.slider_button;
|
||||||
|
DrawRoundButton(p, center + QPoint(20, 47), button_values[SLRight], 4, 11,
|
||||||
|
Direction::Right);
|
||||||
|
DrawRoundButton(p, center + QPoint(20, -62), button_values[SRRight], 4, 11,
|
||||||
|
Direction::Right);
|
||||||
|
|
||||||
DrawDualBody(p, center);
|
DrawDualBody(p, center);
|
||||||
|
|
||||||
// Right trigger top view
|
// Right trigger top view
|
||||||
|
@ -1792,16 +1811,6 @@ void PlayerControlPreview::DrawDualBody(QPainter& p, const QPointF center) {
|
||||||
p.setBrush(colors.right);
|
p.setBrush(colors.right);
|
||||||
DrawPolygon(p, qright_joycon_topview);
|
DrawPolygon(p, qright_joycon_topview);
|
||||||
|
|
||||||
// Right SR and SL sideview buttons
|
|
||||||
p.setPen(colors.outline);
|
|
||||||
p.setBrush(colors.slider_button);
|
|
||||||
DrawRoundRectangle(p, center + QPoint(19, 47), 7, 22, 1);
|
|
||||||
DrawRoundRectangle(p, center + QPoint(19, -62), 7, 22, 1);
|
|
||||||
|
|
||||||
// Left SR and SL sideview buttons
|
|
||||||
DrawRoundRectangle(p, center + QPoint(-19, 47), 7, 22, 1);
|
|
||||||
DrawRoundRectangle(p, center + QPoint(-19, -62), 7, 22, 1);
|
|
||||||
|
|
||||||
// Right Sideview body
|
// Right Sideview body
|
||||||
p.setBrush(colors.slider);
|
p.setBrush(colors.slider);
|
||||||
DrawPolygon(p, qright_joycon_slider);
|
DrawPolygon(p, qright_joycon_slider);
|
||||||
|
|
Loading…
Reference in a new issue