early-access version 3975

main
pineappleEA 2023-11-14 20:38:42 +01:00
parent bddead2fb2
commit 5304174e08
20 changed files with 431 additions and 221 deletions

View File

@ -1,7 +1,7 @@
yuzu emulator early access yuzu emulator early access
============= =============
This is the source code for early-access 3974. This is the source code for early-access 3975.
## Legal Notice ## Legal Notice

View File

@ -22,12 +22,16 @@ import androidx.core.graphics.drawable.toBitmap
import androidx.core.graphics.drawable.toDrawable import androidx.core.graphics.drawable.toDrawable
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.navigation.findNavController import androidx.navigation.findNavController
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.AsyncDifferConfig import androidx.recyclerview.widget.AsyncDifferConfig
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.yuzu.yuzu_emu.HomeNavigationDirections import org.yuzu.yuzu_emu.HomeNavigationDirections
import org.yuzu.yuzu_emu.R import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.YuzuApplication import org.yuzu.yuzu_emu.YuzuApplication
@ -92,28 +96,34 @@ class GameAdapter(private val activity: AppCompatActivity) :
data = Uri.parse(holder.game.path) data = Uri.parse(holder.game.path)
} }
val layerDrawable = ResourcesCompat.getDrawable( activity.lifecycleScope.launch {
YuzuApplication.appContext.resources, withContext(Dispatchers.IO) {
R.drawable.shortcut, val layerDrawable = ResourcesCompat.getDrawable(
null YuzuApplication.appContext.resources,
) as LayerDrawable R.drawable.shortcut,
layerDrawable.setDrawableByLayerId( null
R.id.shortcut_foreground, ) as LayerDrawable
GameIconUtils.getGameIcon(holder.game).toDrawable(YuzuApplication.appContext.resources) layerDrawable.setDrawableByLayerId(
) R.id.shortcut_foreground,
val inset = YuzuApplication.appContext.resources GameIconUtils.getGameIcon(activity, holder.game)
.getDimensionPixelSize(R.dimen.icon_inset) .toDrawable(YuzuApplication.appContext.resources)
layerDrawable.setLayerInset(1, inset, inset, inset, inset)
val shortcut = ShortcutInfoCompat.Builder(YuzuApplication.appContext, holder.game.path)
.setShortLabel(holder.game.title)
.setIcon(
IconCompat.createWithAdaptiveBitmap(
layerDrawable.toBitmap(config = Bitmap.Config.ARGB_8888)
) )
) val inset = YuzuApplication.appContext.resources
.setIntent(openIntent) .getDimensionPixelSize(R.dimen.icon_inset)
.build() layerDrawable.setLayerInset(1, inset, inset, inset, inset)
ShortcutManagerCompat.pushDynamicShortcut(YuzuApplication.appContext, shortcut) val shortcut =
ShortcutInfoCompat.Builder(YuzuApplication.appContext, holder.game.path)
.setShortLabel(holder.game.title)
.setIcon(
IconCompat.createWithAdaptiveBitmap(
layerDrawable.toBitmap(config = Bitmap.Config.ARGB_8888)
)
)
.setIntent(openIntent)
.build()
ShortcutManagerCompat.pushDynamicShortcut(YuzuApplication.appContext, shortcut)
}
}
val action = HomeNavigationDirections.actionGlobalEmulationActivity(holder.game) val action = HomeNavigationDirections.actionGlobalEmulationActivity(holder.game)
view.findNavController().navigate(action) view.findNavController().navigate(action)

View File

@ -8,9 +8,9 @@ import android.graphics.BitmapFactory
import android.widget.ImageView import android.widget.ImageView
import androidx.core.graphics.drawable.toBitmap import androidx.core.graphics.drawable.toBitmap
import androidx.core.graphics.drawable.toDrawable import androidx.core.graphics.drawable.toDrawable
import androidx.lifecycle.LifecycleOwner
import coil.ImageLoader import coil.ImageLoader
import coil.decode.DataSource import coil.decode.DataSource
import coil.executeBlocking
import coil.fetch.DrawableResult import coil.fetch.DrawableResult
import coil.fetch.FetchResult import coil.fetch.FetchResult
import coil.fetch.Fetcher import coil.fetch.Fetcher
@ -76,12 +76,13 @@ object GameIconUtils {
imageLoader.enqueue(request) imageLoader.enqueue(request)
} }
fun getGameIcon(game: Game): Bitmap { suspend fun getGameIcon(lifecycleOwner: LifecycleOwner, game: Game): Bitmap {
val request = ImageRequest.Builder(YuzuApplication.appContext) val request = ImageRequest.Builder(YuzuApplication.appContext)
.data(game) .data(game)
.lifecycle(lifecycleOwner)
.error(R.drawable.default_icon) .error(R.drawable.default_icon)
.build() .build()
return imageLoader.executeBlocking(request) return imageLoader.execute(request)
.drawable!!.toBitmap(config = Bitmap.Config.ARGB_8888) .drawable!!.toBitmap(config = Bitmap.Config.ARGB_8888)
} }
} }

View File

@ -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",
}}; }};
} }

View File

@ -29,12 +29,15 @@ enum Values : int {
DRight, DRight,
DDown, DDown,
SL, SLLeft,
SR, SRLeft,
Home, Home,
Screenshot, Screenshot,
SLRight,
SRRight,
NumButtons, NumButtons,
}; };

View File

@ -153,6 +153,14 @@ void ARM_Interface::Run() {
Kernel::KThread* current_thread{Kernel::GetCurrentThreadPointer(system.Kernel())}; Kernel::KThread* current_thread{Kernel::GetCurrentThreadPointer(system.Kernel())};
HaltReason hr{}; HaltReason hr{};
// If the thread is scheduled for termination, exit the thread.
if (current_thread->HasDpc()) {
if (current_thread->IsTerminationRequested()) {
current_thread->Exit();
UNREACHABLE();
}
}
// Notify the debugger and go to sleep if a step was performed // Notify the debugger and go to sleep if a step was performed
// and this thread has been scheduled again. // and this thread has been scheduled again.
if (current_thread->GetStepState() == StepState::StepPerformed) { if (current_thread->GetStepState() == StepState::StepPerformed) {
@ -174,14 +182,6 @@ void ARM_Interface::Run() {
} }
system.ExitCPUProfile(); system.ExitCPUProfile();
// If the thread is scheduled for termination, exit the thread.
if (current_thread->HasDpc()) {
if (current_thread->IsTerminationRequested()) {
current_thread->Exit();
UNREACHABLE();
}
}
// Notify the debugger and go to sleep if a breakpoint was hit, // Notify the debugger and go to sleep if a breakpoint was hit,
// or if the thread is unable to continue for any reason. // or if the thread is unable to continue for any reason.
if (True(hr & HaltReason::InstructionBreakpoint) || True(hr & HaltReason::PrefetchAbort)) { if (True(hr & HaltReason::InstructionBreakpoint) || True(hr & HaltReason::PrefetchAbort)) {

View File

@ -76,6 +76,7 @@ void CoreTiming::Initialize(std::function<void()>&& on_thread_init_) {
} }
void CoreTiming::ClearPendingEvents() { void CoreTiming::ClearPendingEvents() {
std::scoped_lock lock{basic_lock};
event_queue.clear(); event_queue.clear();
} }
@ -113,6 +114,7 @@ bool CoreTiming::IsRunning() const {
} }
bool CoreTiming::HasPendingEvents() const { bool CoreTiming::HasPendingEvents() const {
std::scoped_lock lock{basic_lock};
return !(wait_set && event_queue.empty()); return !(wait_set && event_queue.empty());
} }

View File

@ -161,7 +161,7 @@ private:
std::shared_ptr<EventType> ev_lost; std::shared_ptr<EventType> ev_lost;
Common::Event event{}; Common::Event event{};
Common::Event pause_event{}; Common::Event pause_event{};
std::mutex basic_lock; mutable std::mutex basic_lock;
std::mutex advance_lock; std::mutex advance_lock;
std::unique_ptr<std::jthread> timer_thread; std::unique_ptr<std::jthread> timer_thread;
std::atomic<bool> paused{}; std::atomic<bool> paused{};

View File

@ -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:

View File

@ -1617,9 +1617,9 @@ void KPageTableBase::RemapPageGroup(PageLinkedList* page_list, KProcessAddress a
const KMemoryInfo info = it->GetMemoryInfo(); const KMemoryInfo info = it->GetMemoryInfo();
// Determine the range to map. // Determine the range to map.
KProcessAddress map_address = std::max(info.GetAddress(), GetInteger(start_address)); KProcessAddress map_address = std::max<u64>(info.GetAddress(), GetInteger(start_address));
const KProcessAddress map_end_address = const KProcessAddress map_end_address =
std::min(info.GetEndAddress(), GetInteger(end_address)); std::min<u64>(info.GetEndAddress(), GetInteger(end_address));
ASSERT(map_end_address != map_address); ASSERT(map_end_address != map_address);
// Determine if we should disable head merge. // Determine if we should disable head merge.

View File

@ -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);
} }

View File

@ -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")) {

View File

@ -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;

View File

@ -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},
}; };

View File

@ -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>;

View File

@ -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},

View File

@ -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 = {

View File

@ -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,
}; };

View File

@ -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>

View File

@ -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);