Compare commits

..

1 Commits

Author SHA1 Message Date
Behunin
8832446730 Make player input configuration scrollable
Use minimumContentsLength to size the profile combo box
ZL/RL slider threshold 18 -> 20 max height
2022-12-17 14:29:12 -07:00
46 changed files with 3523 additions and 3872 deletions

View File

@@ -11,7 +11,6 @@ ccache -s
mkdir build || true && cd build
cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_FLAGS="-march=x86-64-v2" \
-DCMAKE_CXX_COMPILER=/usr/lib/ccache/clang++ \
-DCMAKE_C_COMPILER=/usr/lib/ccache/clang \
-DCMAKE_INSTALL_PREFIX="/usr" \

View File

@@ -12,7 +12,6 @@ mkdir build || true && cd build
cmake .. \
-DBoost_USE_STATIC_LIBS=ON \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_FLAGS="-march=x86-64-v2" \
-DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ \
-DCMAKE_C_COMPILER=/usr/lib/ccache/gcc \
-DCMAKE_INSTALL_PREFIX="/usr" \

View File

@@ -9,7 +9,7 @@ parameters:
steps:
- script: choco install vulkan-sdk
displayName: 'Install vulkan-sdk'
- script: refreshenv && mkdir build && cd build && cmake -E env CXXFLAGS="/Gw /GA /Gr /Ob2" cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON -DCMAKE_POLICY_DEFAULT_CMP0069=NEW -DYUZU_USE_BUNDLED_QT=1 -DYUZU_USE_BUNDLED_SDL2=1 -DYUZU_USE_QT_WEB_ENGINE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DYUZU_TESTS=OFF -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON -DDISPLAY_VERSION=${{ parameters['version'] }} -DCMAKE_BUILD_TYPE=Release -DYUZU_CRASH_DUMPS=ON .. && cd ..
- script: refreshenv && mkdir build && cd build && cmake -G "Visual Studio 17 2022" -A x64 -DYUZU_USE_BUNDLED_QT=1 -DYUZU_USE_BUNDLED_SDL2=1 -DYUZU_USE_QT_WEB_ENGINE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DYUZU_TESTS=OFF -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON -DDISPLAY_VERSION=${{ parameters['version'] }} -DCMAKE_BUILD_TYPE=Release -DYUZU_CRASH_DUMPS=ON .. && cd ..
displayName: 'Configure CMake'
- task: MSBuild@1
displayName: 'Build'

View File

@@ -208,7 +208,7 @@ find_package(libusb 1.0.24)
find_package(lz4 REQUIRED)
find_package(nlohmann_json 3.8 REQUIRED)
find_package(Opus 1.3)
find_package(Vulkan 1.3.238)
find_package(Vulkan 1.3.213)
find_package(ZLIB 1.2 REQUIRED)
find_package(zstd 1.5 REQUIRED)

View File

@@ -69,7 +69,7 @@ void assert_fail_impl();
#define ASSERT_OR_EXECUTE(_a_, _b_) \
do { \
ASSERT(_a_); \
if (!(_a_)) [[unlikely]] { \
if (!(_a_)) { \
_b_ \
} \
} while (0)
@@ -78,7 +78,7 @@ void assert_fail_impl();
#define ASSERT_OR_EXECUTE_MSG(_a_, _b_, ...) \
do { \
ASSERT_MSG(_a_, __VA_ARGS__); \
if (!(_a_)) [[unlikely]] { \
if (!(_a_)) { \
_b_ \
} \
} while (0)

View File

@@ -201,9 +201,6 @@ add_library(core STATIC
hle/kernel/k_event_info.h
hle/kernel/k_handle_table.cpp
hle/kernel/k_handle_table.h
hle/kernel/k_hardware_timer_base.h
hle/kernel/k_hardware_timer.cpp
hle/kernel/k_hardware_timer.h
hle/kernel/k_interrupt_manager.cpp
hle/kernel/k_interrupt_manager.h
hle/kernel/k_light_condition_variable.cpp
@@ -271,7 +268,6 @@ add_library(core STATIC
hle/kernel/k_thread_local_page.h
hle/kernel/k_thread_queue.cpp
hle/kernel/k_thread_queue.h
hle/kernel/k_timer_task.h
hle/kernel/k_trace.h
hle/kernel/k_transfer_memory.cpp
hle/kernel/k_transfer_memory.h
@@ -294,6 +290,8 @@ add_library(core STATIC
hle/kernel/svc_common.h
hle/kernel/svc_types.h
hle/kernel/svc_wrap.h
hle/kernel/time_manager.cpp
hle/kernel/time_manager.h
hle/result.h
hle/service/acc/acc.cpp
hle/service/acc/acc.h

View File

@@ -183,20 +183,26 @@ struct System::Impl {
Initialize(system);
}
void Run() {
SystemResultStatus Run() {
std::unique_lock<std::mutex> lk(suspend_guard);
status = SystemResultStatus::Success;
kernel.Suspend(false);
core_timing.SyncPause(false);
is_paused.store(false, std::memory_order_relaxed);
return status;
}
void Pause() {
SystemResultStatus Pause() {
std::unique_lock<std::mutex> lk(suspend_guard);
status = SystemResultStatus::Success;
core_timing.SyncPause(true);
kernel.Suspend(true);
is_paused.store(true, std::memory_order_relaxed);
return status;
}
bool IsPaused() const {
@@ -547,12 +553,12 @@ void System::Initialize() {
impl->Initialize(*this);
}
void System::Run() {
impl->Run();
SystemResultStatus System::Run() {
return impl->Run();
}
void System::Pause() {
impl->Pause();
SystemResultStatus System::Pause() {
return impl->Pause();
}
bool System::IsPaused() const {

View File

@@ -152,13 +152,13 @@ public:
* Run the OS and Application
* This function will start emulation and run the relevant devices
*/
void Run();
[[nodiscard]] SystemResultStatus Run();
/**
* Pause the OS and Application
* This function will pause emulation and stop the relevant devices
*/
void Pause();
[[nodiscard]] SystemResultStatus Pause();
/// Check if the core is currently paused.
[[nodiscard]] bool IsPaused() const;

View File

@@ -145,7 +145,6 @@ void EmulatedController::LoadDevices() {
output_params[3].Set("output", true);
LoadTASParams();
LoadVirtualGamepadParams();
std::ranges::transform(button_params, button_devices.begin(), Common::Input::CreateInputDevice);
std::ranges::transform(stick_params, stick_devices.begin(), Common::Input::CreateInputDevice);
@@ -164,12 +163,6 @@ void EmulatedController::LoadDevices() {
Common::Input::CreateInputDevice);
std::ranges::transform(tas_stick_params, tas_stick_devices.begin(),
Common::Input::CreateInputDevice);
// Initialize virtual gamepad devices
std::ranges::transform(virtual_button_params, virtual_button_devices.begin(),
Common::Input::CreateInputDevice);
std::ranges::transform(virtual_stick_params, virtual_stick_devices.begin(),
Common::Input::CreateInputDevice);
}
void EmulatedController::LoadTASParams() {
@@ -212,46 +205,6 @@ void EmulatedController::LoadTASParams() {
tas_stick_params[Settings::NativeAnalog::RStick].Set("axis_y", 3);
}
void EmulatedController::LoadVirtualGamepadParams() {
const auto player_index = NpadIdTypeToIndex(npad_id_type);
Common::ParamPackage common_params{};
common_params.Set("engine", "virtual_gamepad");
common_params.Set("port", static_cast<int>(player_index));
for (auto& param : virtual_button_params) {
param = common_params;
}
for (auto& param : virtual_stick_params) {
param = common_params;
}
// TODO(german77): Replace this with an input profile or something better
virtual_button_params[Settings::NativeButton::A].Set("button", 0);
virtual_button_params[Settings::NativeButton::B].Set("button", 1);
virtual_button_params[Settings::NativeButton::X].Set("button", 2);
virtual_button_params[Settings::NativeButton::Y].Set("button", 3);
virtual_button_params[Settings::NativeButton::LStick].Set("button", 4);
virtual_button_params[Settings::NativeButton::RStick].Set("button", 5);
virtual_button_params[Settings::NativeButton::L].Set("button", 6);
virtual_button_params[Settings::NativeButton::R].Set("button", 7);
virtual_button_params[Settings::NativeButton::ZL].Set("button", 8);
virtual_button_params[Settings::NativeButton::ZR].Set("button", 9);
virtual_button_params[Settings::NativeButton::Plus].Set("button", 10);
virtual_button_params[Settings::NativeButton::Minus].Set("button", 11);
virtual_button_params[Settings::NativeButton::DLeft].Set("button", 12);
virtual_button_params[Settings::NativeButton::DUp].Set("button", 13);
virtual_button_params[Settings::NativeButton::DRight].Set("button", 14);
virtual_button_params[Settings::NativeButton::DDown].Set("button", 15);
virtual_button_params[Settings::NativeButton::SL].Set("button", 16);
virtual_button_params[Settings::NativeButton::SR].Set("button", 17);
virtual_button_params[Settings::NativeButton::Home].Set("button", 18);
virtual_button_params[Settings::NativeButton::Screenshot].Set("button", 19);
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::RStick].Set("axis_x", 2);
virtual_stick_params[Settings::NativeAnalog::RStick].Set("axis_y", 3);
}
void EmulatedController::ReloadInput() {
// If you load any device here add the equivalent to the UnloadInput() function
LoadDevices();
@@ -369,35 +322,6 @@ void EmulatedController::ReloadInput() {
},
});
}
// Use a common UUID for Virtual Gamepad
static constexpr Common::UUID VIRTUAL_UUID = Common::UUID{
{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xFF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
// Register virtual devices. No need to force update
for (std::size_t index = 0; index < virtual_button_devices.size(); ++index) {
if (!virtual_button_devices[index]) {
continue;
}
virtual_button_devices[index]->SetCallback({
.on_change =
[this, index](const Common::Input::CallbackStatus& callback) {
SetButton(callback, index, VIRTUAL_UUID);
},
});
}
for (std::size_t index = 0; index < virtual_stick_devices.size(); ++index) {
if (!virtual_stick_devices[index]) {
continue;
}
virtual_stick_devices[index]->SetCallback({
.on_change =
[this, index](const Common::Input::CallbackStatus& callback) {
SetStick(callback, index, VIRTUAL_UUID);
},
});
}
}
void EmulatedController::UnloadInput() {
@@ -425,12 +349,6 @@ void EmulatedController::UnloadInput() {
for (auto& stick : tas_stick_devices) {
stick.reset();
}
for (auto& button : virtual_button_devices) {
button.reset();
}
for (auto& stick : virtual_stick_devices) {
stick.reset();
}
camera_devices.reset();
nfc_devices.reset();
}

View File

@@ -385,9 +385,6 @@ private:
/// Set the params for TAS devices
void LoadTASParams();
/// Set the params for virtual pad devices
void LoadVirtualGamepadParams();
/**
* @param use_temporary_value If true tmp_npad_type will be used
* @return true if the controller style is fullkey
@@ -503,12 +500,6 @@ private:
ButtonDevices tas_button_devices;
StickDevices tas_stick_devices;
// Virtual gamepad related variables
ButtonParams virtual_button_params;
StickParams virtual_stick_params;
ButtonDevices virtual_button_devices;
StickDevices virtual_stick_devices;
mutable std::mutex mutex;
mutable std::mutex callback_mutex;
std::unordered_map<int, ControllerUpdateCallback> callback_list;

View File

@@ -10,6 +10,7 @@
#include "core/hle/kernel/k_thread_queue.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/svc_results.h"
#include "core/hle/kernel/time_manager.h"
#include "core/memory.h"
namespace Kernel {

View File

@@ -1,74 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/core.h"
#include "core/core_timing.h"
#include "core/hle/kernel/k_hardware_timer.h"
#include "core/hle/kernel/k_scheduler.h"
namespace Kernel {
void KHardwareTimer::Initialize() {
// Create the timing callback to register with CoreTiming.
m_event_type = Core::Timing::CreateEvent(
"KHardwareTimer::Callback", [](std::uintptr_t timer_handle, s64, std::chrono::nanoseconds) {
reinterpret_cast<KHardwareTimer*>(timer_handle)->DoTask();
return std::nullopt;
});
}
void KHardwareTimer::Finalize() {
this->DisableInterrupt();
m_event_type.reset();
}
void KHardwareTimer::DoTask() {
// Handle the interrupt.
{
KScopedSchedulerLock slk{m_kernel};
KScopedSpinLock lk(this->GetLock());
//! Ignore this event if needed.
if (!this->GetInterruptEnabled()) {
return;
}
// Disable the timer interrupt while we handle this.
this->DisableInterrupt();
if (const s64 next_time = this->DoInterruptTaskImpl(GetTick());
0 < next_time && next_time <= m_wakeup_time) {
// We have a next time, so we should set the time to interrupt and turn the interrupt
// on.
this->EnableInterrupt(next_time);
}
}
// Clear the timer interrupt.
// Kernel::GetInterruptManager().ClearInterrupt(KInterruptName_NonSecurePhysicalTimer,
// GetCurrentCoreId());
}
void KHardwareTimer::EnableInterrupt(s64 wakeup_time) {
this->DisableInterrupt();
m_wakeup_time = wakeup_time;
m_kernel.System().CoreTiming().ScheduleEvent(std::chrono::nanoseconds{m_wakeup_time},
m_event_type, reinterpret_cast<uintptr_t>(this),
true);
}
void KHardwareTimer::DisableInterrupt() {
m_kernel.System().CoreTiming().UnscheduleEvent(m_event_type, reinterpret_cast<uintptr_t>(this));
m_wakeup_time = std::numeric_limits<s64>::max();
}
s64 KHardwareTimer::GetTick() const {
return m_kernel.System().CoreTiming().GetGlobalTimeNs().count();
}
bool KHardwareTimer::GetInterruptEnabled() {
return m_wakeup_time != std::numeric_limits<s64>::max();
}
} // namespace Kernel

View File

@@ -1,54 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "core/hle/kernel/k_hardware_timer_base.h"
namespace Core::Timing {
struct EventType;
} // namespace Core::Timing
namespace Kernel {
class KHardwareTimer : /* public KInterruptTask, */ public KHardwareTimerBase {
public:
explicit KHardwareTimer(KernelCore& kernel) : KHardwareTimerBase{kernel} {}
// Public API.
void Initialize();
void Finalize();
s64 GetCount() const {
return GetTick();
}
void RegisterTask(KTimerTask* task, s64 time_from_now) {
this->RegisterAbsoluteTask(task, GetTick() + time_from_now);
}
void RegisterAbsoluteTask(KTimerTask* task, s64 task_time) {
KScopedDisableDispatch dd{m_kernel};
KScopedSpinLock lk{this->GetLock()};
if (this->RegisterAbsoluteTaskImpl(task, task_time)) {
if (task_time <= m_wakeup_time) {
this->EnableInterrupt(task_time);
}
}
}
private:
void EnableInterrupt(s64 wakeup_time);
void DisableInterrupt();
bool GetInterruptEnabled();
s64 GetTick() const;
void DoTask();
private:
// Absolute time in nanoseconds
s64 m_wakeup_time{std::numeric_limits<s64>::max()};
std::shared_ptr<Core::Timing::EventType> m_event_type{};
};
} // namespace Kernel

View File

@@ -1,92 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "core/hle/kernel/k_spin_lock.h"
#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/k_timer_task.h"
namespace Kernel {
class KHardwareTimerBase {
public:
explicit KHardwareTimerBase(KernelCore& kernel) : m_kernel{kernel} {}
void CancelTask(KTimerTask* task) {
KScopedDisableDispatch dd{m_kernel};
KScopedSpinLock lk{m_lock};
if (const s64 task_time = task->GetTime(); task_time > 0) {
this->RemoveTaskFromTree(task);
}
}
protected:
KSpinLock& GetLock() {
return m_lock;
}
s64 DoInterruptTaskImpl(s64 cur_time) {
// We want to handle all tasks, returning the next time that a task is scheduled.
while (true) {
// Get the next task. If there isn't one, return 0.
KTimerTask* task = m_next_task;
if (task == nullptr) {
return 0;
}
// If the task needs to be done in the future, do it in the future and not now.
if (const s64 task_time = task->GetTime(); task_time > cur_time) {
return task_time;
}
// Remove the task from the tree of tasks, and update our next task.
this->RemoveTaskFromTree(task);
// Handle the task.
task->OnTimer();
}
}
bool RegisterAbsoluteTaskImpl(KTimerTask* task, s64 task_time) {
ASSERT(task_time > 0);
// Set the task's time, and insert it into our tree.
task->SetTime(task_time);
m_task_tree.insert(*task);
// Update our next task if relevant.
if (m_next_task != nullptr && m_next_task->GetTime() <= task_time) {
return false;
}
m_next_task = task;
return true;
}
private:
void RemoveTaskFromTree(KTimerTask* task) {
// Erase from the tree.
auto it = m_task_tree.erase(m_task_tree.iterator_to(*task));
// Clear the task's scheduled time.
task->SetTime(0);
// Update our next task if relevant.
if (m_next_task == task) {
m_next_task = (it != m_task_tree.end()) ? std::addressof(*it) : nullptr;
}
}
protected:
KernelCore& m_kernel;
private:
using TimerTaskTree = Common::IntrusiveRedBlackTreeBaseTraits<KTimerTask>::TreeType<KTimerTask>;
KSpinLock m_lock{};
TimerTaskTree m_task_tree{};
KTimerTask* m_next_task{};
};
} // namespace Kernel

View File

@@ -5,9 +5,9 @@
#include "common/common_types.h"
#include "core/hle/kernel/global_scheduler_context.h"
#include "core/hle/kernel/k_hardware_timer.h"
#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/time_manager.h"
namespace Kernel {
@@ -22,7 +22,7 @@ public:
~KScopedSchedulerLockAndSleep() {
// Register the sleep.
if (timeout_tick > 0) {
kernel.HardwareTimer().RegisterTask(thread, timeout_tick);
kernel.TimeManager().ScheduleTimeEvent(thread, timeout_tick);
}
// Unlock the scheduler.

View File

@@ -22,7 +22,6 @@
#include "core/hle/kernel/k_light_lock.h"
#include "core/hle/kernel/k_spin_lock.h"
#include "core/hle/kernel/k_synchronization_object.h"
#include "core/hle/kernel/k_timer_task.h"
#include "core/hle/kernel/k_worker_task.h"
#include "core/hle/kernel/slab_helpers.h"
#include "core/hle/kernel/svc_common.h"
@@ -113,8 +112,7 @@ void SetCurrentThread(KernelCore& kernel, KThread* thread);
[[nodiscard]] s32 GetCurrentCoreId(KernelCore& kernel);
class KThread final : public KAutoObjectWithSlabHeapAndContainer<KThread, KWorkerTask>,
public boost::intrusive::list_base_hook<>,
public KTimerTask {
public boost::intrusive::list_base_hook<> {
KERNEL_AUTOOBJECT_TRAITS(KThread, KSynchronizationObject);
private:
@@ -842,8 +840,4 @@ private:
KernelCore& kernel;
};
inline void KTimerTask::OnTimer() {
static_cast<KThread*>(this)->OnTimer();
}
} // namespace Kernel

View File

@@ -1,9 +1,9 @@
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/kernel/k_hardware_timer.h"
#include "core/hle/kernel/k_thread_queue.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/time_manager.h"
namespace Kernel {
@@ -22,7 +22,7 @@ void KThreadQueue::EndWait(KThread* waiting_thread, Result wait_result) {
waiting_thread->ClearWaitQueue();
// Cancel the thread task.
kernel.HardwareTimer().CancelTask(waiting_thread);
kernel.TimeManager().UnscheduleTimeEvent(waiting_thread);
}
void KThreadQueue::CancelWait(KThread* waiting_thread, Result wait_result, bool cancel_timer_task) {
@@ -37,7 +37,7 @@ void KThreadQueue::CancelWait(KThread* waiting_thread, Result wait_result, bool
// Cancel the thread task.
if (cancel_timer_task) {
kernel.HardwareTimer().CancelTask(waiting_thread);
kernel.TimeManager().UnscheduleTimeEvent(waiting_thread);
}
}

View File

@@ -1,40 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "common/intrusive_red_black_tree.h"
namespace Kernel {
class KTimerTask : public Common::IntrusiveRedBlackTreeBaseNode<KTimerTask> {
public:
static constexpr int Compare(const KTimerTask& lhs, const KTimerTask& rhs) {
if (lhs.GetTime() < rhs.GetTime()) {
return -1;
} else {
return 1;
}
}
constexpr explicit KTimerTask() = default;
constexpr void SetTime(s64 t) {
m_time = t;
}
constexpr s64 GetTime() const {
return m_time;
}
// NOTE: This is virtual in Nintendo's kernel. Prior to 13.0.0, KWaitObject was also a
// TimerTask; this is no longer the case. Since this is now KThread exclusive, we have
// devirtualized (see inline declaration for this inside k_thread.h).
void OnTimer();
private:
// Absolute time in nanoseconds
s64 m_time{};
};
} // namespace Kernel

View File

@@ -26,7 +26,6 @@
#include "core/hle/kernel/k_client_port.h"
#include "core/hle/kernel/k_dynamic_resource_manager.h"
#include "core/hle/kernel/k_handle_table.h"
#include "core/hle/kernel/k_hardware_timer.h"
#include "core/hle/kernel/k_memory_layout.h"
#include "core/hle/kernel/k_memory_manager.h"
#include "core/hle/kernel/k_page_buffer.h"
@@ -40,6 +39,7 @@
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/physical_core.h"
#include "core/hle/kernel/service_thread.h"
#include "core/hle/kernel/time_manager.h"
#include "core/hle/result.h"
#include "core/hle/service/sm/sm.h"
#include "core/memory.h"
@@ -55,7 +55,7 @@ struct KernelCore::Impl {
static constexpr size_t ReservedDynamicPageCount = 64;
explicit Impl(Core::System& system_, KernelCore& kernel_)
: service_threads_manager{1, "ServiceThreadsManager"},
: time_manager{system_}, service_threads_manager{1, "ServiceThreadsManager"},
service_thread_barrier{2}, system{system_} {}
void SetMulticore(bool is_multi) {
@@ -63,9 +63,6 @@ struct KernelCore::Impl {
}
void Initialize(KernelCore& kernel) {
hardware_timer = std::make_unique<Kernel::KHardwareTimer>(kernel);
hardware_timer->Initialize();
global_object_list_container = std::make_unique<KAutoObjectWithListContainer>(kernel);
global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel);
global_handle_table = std::make_unique<Kernel::KHandleTable>(kernel);
@@ -196,9 +193,6 @@ struct KernelCore::Impl {
// Ensure that the object list container is finalized and properly shutdown.
global_object_list_container->Finalize();
global_object_list_container.reset();
hardware_timer->Finalize();
hardware_timer.reset();
}
void CloseServices() {
@@ -838,7 +832,7 @@ struct KernelCore::Impl {
std::vector<KProcess*> process_list;
std::atomic<KProcess*> current_process{};
std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context;
std::unique_ptr<Kernel::KHardwareTimer> hardware_timer;
Kernel::TimeManager time_manager;
Init::KSlabResourceCounts slab_resource_counts{};
KResourceLimit* system_resource_limit{};
@@ -1025,8 +1019,12 @@ Kernel::KScheduler* KernelCore::CurrentScheduler() {
return impl->schedulers[core_id].get();
}
Kernel::KHardwareTimer& KernelCore::HardwareTimer() {
return *impl->hardware_timer;
Kernel::TimeManager& KernelCore::TimeManager() {
return impl->time_manager;
}
const Kernel::TimeManager& KernelCore::TimeManager() const {
return impl->time_manager;
}
Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() {

View File

@@ -39,7 +39,6 @@ class KDynamicPageManager;
class KEvent;
class KEventInfo;
class KHandleTable;
class KHardwareTimer;
class KLinkedListNode;
class KMemoryLayout;
class KMemoryManager;
@@ -64,6 +63,7 @@ class KCodeMemory;
class PhysicalCore;
class ServiceThread;
class Synchronization;
class TimeManager;
using ServiceInterfaceFactory =
std::function<KClientPort&(Service::SM::ServiceManager&, Core::System&)>;
@@ -175,8 +175,11 @@ public:
/// Gets the an instance of the current physical CPU core.
const Kernel::PhysicalCore& CurrentPhysicalCore() const;
/// Gets the an instance of the hardware timer.
Kernel::KHardwareTimer& HardwareTimer();
/// Gets the an instance of the TimeManager Interface.
Kernel::TimeManager& TimeManager();
/// Gets the an instance of the TimeManager Interface.
const Kernel::TimeManager& TimeManager() const;
/// Stops execution of 'id' core, in order to reschedule a new thread.
void PrepareReschedule(std::size_t id);

View File

@@ -0,0 +1,44 @@
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/assert.h"
#include "core/core.h"
#include "core/core_timing.h"
#include "core/hle/kernel/k_scheduler.h"
#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/time_manager.h"
namespace Kernel {
TimeManager::TimeManager(Core::System& system_) : system{system_} {
time_manager_event_type = Core::Timing::CreateEvent(
"Kernel::TimeManagerCallback",
[this](std::uintptr_t thread_handle, s64 time,
std::chrono::nanoseconds) -> std::optional<std::chrono::nanoseconds> {
KThread* thread = reinterpret_cast<KThread*>(thread_handle);
{
KScopedSchedulerLock sl(system.Kernel());
thread->OnTimer();
}
return std::nullopt;
});
}
void TimeManager::ScheduleTimeEvent(KThread* thread, s64 nanoseconds) {
std::scoped_lock lock{mutex};
if (nanoseconds > 0) {
ASSERT(thread);
ASSERT(thread->GetState() != ThreadState::Runnable);
system.CoreTiming().ScheduleEvent(std::chrono::nanoseconds{nanoseconds},
time_manager_event_type,
reinterpret_cast<uintptr_t>(thread));
}
}
void TimeManager::UnscheduleTimeEvent(KThread* thread) {
std::scoped_lock lock{mutex};
system.CoreTiming().UnscheduleEvent(time_manager_event_type,
reinterpret_cast<uintptr_t>(thread));
}
} // namespace Kernel

View File

@@ -0,0 +1,41 @@
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <memory>
#include <mutex>
namespace Core {
class System;
} // namespace Core
namespace Core::Timing {
struct EventType;
} // namespace Core::Timing
namespace Kernel {
class KThread;
/**
* The `TimeManager` takes care of scheduling time events on threads and executes their TimeUp
* method when the event is triggered.
*/
class TimeManager {
public:
explicit TimeManager(Core::System& system);
/// Schedule a time event on `timetask` thread that will expire in 'nanoseconds'
void ScheduleTimeEvent(KThread* time_task, s64 nanoseconds);
/// Unschedule an existing time event
void UnscheduleTimeEvent(KThread* thread);
private:
Core::System& system;
std::shared_ptr<Core::Timing::EventType> time_manager_event_type;
std::mutex mutex;
};
} // namespace Kernel

View File

@@ -97,7 +97,7 @@ void IUser::IsNfcEnabled(Kernel::HLERequestContext& ctx) {
}
void IUser::ListDevices(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_NFC, "called");
LOG_INFO(Service_NFC, "called");
if (state == State::NonInitialized) {
IPC::ResponseBuilder rb{ctx, 2};

View File

@@ -83,7 +83,7 @@ void IUser::Finalize(Kernel::HLERequestContext& ctx) {
}
void IUser::ListDevices(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_NFP, "called");
LOG_INFO(Service_NFP, "called");
if (state == State::NonInitialized) {
IPC::ResponseBuilder rb{ctx, 2};

View File

@@ -20,8 +20,6 @@ add_library(input_common STATIC
drivers/udp_client.h
drivers/virtual_amiibo.cpp
drivers/virtual_amiibo.h
drivers/virtual_gamepad.cpp
drivers/virtual_gamepad.h
helpers/stick_from_buttons.cpp
helpers/stick_from_buttons.h
helpers/touch_from_buttons.cpp

View File

@@ -25,7 +25,6 @@ public:
Common::Input::CameraError SetCameraFormat(const PadIdentifier& identifier_,
Common::Input::CameraFormat camera_format) override;
private:
Common::Input::CameraStatus status{};
};

View File

@@ -1,78 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "input_common/drivers/virtual_gamepad.h"
namespace InputCommon {
constexpr std::size_t PlayerIndexCount = 10;
VirtualGamepad::VirtualGamepad(std::string input_engine_) : InputEngine(std::move(input_engine_)) {
for (std::size_t i = 0; i < PlayerIndexCount; i++) {
PreSetController(GetIdentifier(i));
}
}
void VirtualGamepad::SetButtonState(std::size_t player_index, int button_id, bool value) {
if (player_index > PlayerIndexCount) {
return;
}
const auto identifier = GetIdentifier(player_index);
SetButton(identifier, button_id, value);
}
void VirtualGamepad::SetButtonState(std::size_t player_index, VirtualButton button_id, bool value) {
SetButtonState(player_index, static_cast<int>(button_id), value);
}
void VirtualGamepad::SetStickPosition(std::size_t player_index, int axis_id, float x_value,
float y_value) {
if (player_index > PlayerIndexCount) {
return;
}
const auto identifier = GetIdentifier(player_index);
SetAxis(identifier, axis_id * 2, x_value);
SetAxis(identifier, (axis_id * 2) + 1, y_value);
}
void VirtualGamepad::SetStickPosition(std::size_t player_index, VirtualStick axis_id, float x_value,
float y_value) {
SetStickPosition(player_index, static_cast<int>(axis_id), x_value, y_value);
}
void VirtualGamepad::ResetControllers() {
for (std::size_t i = 0; i < PlayerIndexCount; i++) {
SetStickPosition(i, VirtualStick::Left, 0.0f, 0.0f);
SetStickPosition(i, VirtualStick::Right, 0.0f, 0.0f);
SetButtonState(i, VirtualButton::ButtonA, false);
SetButtonState(i, VirtualButton::ButtonB, false);
SetButtonState(i, VirtualButton::ButtonX, false);
SetButtonState(i, VirtualButton::ButtonY, false);
SetButtonState(i, VirtualButton::StickL, false);
SetButtonState(i, VirtualButton::StickR, false);
SetButtonState(i, VirtualButton::TriggerL, false);
SetButtonState(i, VirtualButton::TriggerR, false);
SetButtonState(i, VirtualButton::TriggerZL, false);
SetButtonState(i, VirtualButton::TriggerZR, false);
SetButtonState(i, VirtualButton::ButtonPlus, false);
SetButtonState(i, VirtualButton::ButtonMinus, false);
SetButtonState(i, VirtualButton::ButtonLeft, false);
SetButtonState(i, VirtualButton::ButtonUp, false);
SetButtonState(i, VirtualButton::ButtonRight, false);
SetButtonState(i, VirtualButton::ButtonDown, false);
SetButtonState(i, VirtualButton::ButtonSL, false);
SetButtonState(i, VirtualButton::ButtonSR, false);
SetButtonState(i, VirtualButton::ButtonHome, false);
SetButtonState(i, VirtualButton::ButtonCapture, false);
}
}
PadIdentifier VirtualGamepad::GetIdentifier(std::size_t player_index) const {
return {
.guid = Common::UUID{},
.port = player_index,
.pad = 0,
};
}
} // namespace InputCommon

View File

@@ -1,73 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "input_common/input_engine.h"
namespace InputCommon {
/**
* A virtual controller that is always assigned to the game input
*/
class VirtualGamepad final : public InputEngine {
public:
enum class VirtualButton {
ButtonA,
ButtonB,
ButtonX,
ButtonY,
StickL,
StickR,
TriggerL,
TriggerR,
TriggerZL,
TriggerZR,
ButtonPlus,
ButtonMinus,
ButtonLeft,
ButtonUp,
ButtonRight,
ButtonDown,
ButtonSL,
ButtonSR,
ButtonHome,
ButtonCapture,
};
enum class VirtualStick {
Left = 0,
Right = 1,
};
explicit VirtualGamepad(std::string input_engine_);
/**
* Sets the status of all buttons bound with the key to pressed
* @param player_index the player number that will take this action
* @param button_id the id of the button
* @param value indicates if the button is pressed or not
*/
void SetButtonState(std::size_t player_index, int button_id, bool value);
void SetButtonState(std::size_t player_index, VirtualButton button_id, bool value);
/**
* Sets the status of all buttons bound with the key to released
* @param player_index the player number that will take this action
* @param axis_id the id of the axis to move
* @param x_value the position of the stick in the x axis
* @param y_value the position of the stick in the y axis
*/
void SetStickPosition(std::size_t player_index, int axis_id, float x_value, float y_value);
void SetStickPosition(std::size_t player_index, VirtualStick axis_id, float x_value,
float y_value);
/// Restores all inputs into the neutral position
void ResetControllers();
private:
/// Returns the correct identifier corresponding to the player index
PadIdentifier GetIdentifier(std::size_t player_index) const;
};
} // namespace InputCommon

View File

@@ -200,6 +200,12 @@ bool MappingFactory::IsDriverValid(const MappingData& data) const {
return false;
}
// The following drivers don't need to be mapped
if (data.engine == "tas") {
return false;
}
if (data.engine == "touch") {
return false;
}
if (data.engine == "touch_from_button") {
return false;
}

View File

@@ -12,7 +12,6 @@
#include "input_common/drivers/touch_screen.h"
#include "input_common/drivers/udp_client.h"
#include "input_common/drivers/virtual_amiibo.h"
#include "input_common/drivers/virtual_gamepad.h"
#include "input_common/helpers/stick_from_buttons.h"
#include "input_common/helpers/touch_from_buttons.h"
#include "input_common/input_engine.h"
@@ -26,33 +25,73 @@
namespace InputCommon {
struct InputSubsystem::Impl {
template <typename Engine>
void RegisterEngine(std::string name, std::shared_ptr<Engine>& engine) {
MappingCallback mapping_callback{[this](const MappingData& data) { RegisterInput(data); }};
engine = std::make_shared<Engine>(name);
engine->SetMappingCallback(mapping_callback);
std::shared_ptr<InputFactory> input_factory = std::make_shared<InputFactory>(engine);
std::shared_ptr<OutputFactory> output_factory = std::make_shared<OutputFactory>(engine);
Common::Input::RegisterInputFactory(engine->GetEngineName(), std::move(input_factory));
Common::Input::RegisterOutputFactory(engine->GetEngineName(), std::move(output_factory));
}
void Initialize() {
mapping_factory = std::make_shared<MappingFactory>();
MappingCallback mapping_callback{[this](const MappingData& data) { RegisterInput(data); }};
keyboard = std::make_shared<Keyboard>("keyboard");
keyboard->SetMappingCallback(mapping_callback);
keyboard_factory = std::make_shared<InputFactory>(keyboard);
keyboard_output_factory = std::make_shared<OutputFactory>(keyboard);
Common::Input::RegisterInputFactory(keyboard->GetEngineName(), keyboard_factory);
Common::Input::RegisterOutputFactory(keyboard->GetEngineName(), keyboard_output_factory);
mouse = std::make_shared<Mouse>("mouse");
mouse->SetMappingCallback(mapping_callback);
mouse_factory = std::make_shared<InputFactory>(mouse);
mouse_output_factory = std::make_shared<OutputFactory>(mouse);
Common::Input::RegisterInputFactory(mouse->GetEngineName(), mouse_factory);
Common::Input::RegisterOutputFactory(mouse->GetEngineName(), mouse_output_factory);
touch_screen = std::make_shared<TouchScreen>("touch");
touch_screen_factory = std::make_shared<InputFactory>(touch_screen);
Common::Input::RegisterInputFactory(touch_screen->GetEngineName(), touch_screen_factory);
gcadapter = std::make_shared<GCAdapter>("gcpad");
gcadapter->SetMappingCallback(mapping_callback);
gcadapter_input_factory = std::make_shared<InputFactory>(gcadapter);
gcadapter_output_factory = std::make_shared<OutputFactory>(gcadapter);
Common::Input::RegisterInputFactory(gcadapter->GetEngineName(), gcadapter_input_factory);
Common::Input::RegisterOutputFactory(gcadapter->GetEngineName(), gcadapter_output_factory);
udp_client = std::make_shared<CemuhookUDP::UDPClient>("cemuhookudp");
udp_client->SetMappingCallback(mapping_callback);
udp_client_input_factory = std::make_shared<InputFactory>(udp_client);
udp_client_output_factory = std::make_shared<OutputFactory>(udp_client);
Common::Input::RegisterInputFactory(udp_client->GetEngineName(), udp_client_input_factory);
Common::Input::RegisterOutputFactory(udp_client->GetEngineName(),
udp_client_output_factory);
tas_input = std::make_shared<TasInput::Tas>("tas");
tas_input->SetMappingCallback(mapping_callback);
tas_input_factory = std::make_shared<InputFactory>(tas_input);
tas_output_factory = std::make_shared<OutputFactory>(tas_input);
Common::Input::RegisterInputFactory(tas_input->GetEngineName(), tas_input_factory);
Common::Input::RegisterOutputFactory(tas_input->GetEngineName(), tas_output_factory);
camera = std::make_shared<Camera>("camera");
camera->SetMappingCallback(mapping_callback);
camera_input_factory = std::make_shared<InputFactory>(camera);
camera_output_factory = std::make_shared<OutputFactory>(camera);
Common::Input::RegisterInputFactory(camera->GetEngineName(), camera_input_factory);
Common::Input::RegisterOutputFactory(camera->GetEngineName(), camera_output_factory);
virtual_amiibo = std::make_shared<VirtualAmiibo>("virtual_amiibo");
virtual_amiibo->SetMappingCallback(mapping_callback);
virtual_amiibo_input_factory = std::make_shared<InputFactory>(virtual_amiibo);
virtual_amiibo_output_factory = std::make_shared<OutputFactory>(virtual_amiibo);
Common::Input::RegisterInputFactory(virtual_amiibo->GetEngineName(),
virtual_amiibo_input_factory);
Common::Input::RegisterOutputFactory(virtual_amiibo->GetEngineName(),
virtual_amiibo_output_factory);
RegisterEngine("keyboard", keyboard);
RegisterEngine("mouse", mouse);
RegisterEngine("touch", touch_screen);
RegisterEngine("gcpad", gcadapter);
RegisterEngine("cemuhookudp", udp_client);
RegisterEngine("tas", tas_input);
RegisterEngine("camera", camera);
RegisterEngine("virtual_amiibo", virtual_amiibo);
RegisterEngine("virtual_gamepad", virtual_gamepad);
#ifdef HAVE_SDL2
RegisterEngine("sdl", sdl);
sdl = std::make_shared<SDLDriver>("sdl");
sdl->SetMappingCallback(mapping_callback);
sdl_input_factory = std::make_shared<InputFactory>(sdl);
sdl_output_factory = std::make_shared<OutputFactory>(sdl);
Common::Input::RegisterInputFactory(sdl->GetEngineName(), sdl_input_factory);
Common::Input::RegisterOutputFactory(sdl->GetEngineName(), sdl_output_factory);
#endif
Common::Input::RegisterInputFactory("touch_from_button",
@@ -61,25 +100,42 @@ struct InputSubsystem::Impl {
std::make_shared<StickFromButton>());
}
template <typename Engine>
void UnregisterEngine(std::shared_ptr<Engine>& engine) {
Common::Input::UnregisterInputFactory(engine->GetEngineName());
Common::Input::UnregisterOutputFactory(engine->GetEngineName());
engine.reset();
}
void Shutdown() {
UnregisterEngine(keyboard);
UnregisterEngine(mouse);
UnregisterEngine(touch_screen);
UnregisterEngine(gcadapter);
UnregisterEngine(udp_client);
UnregisterEngine(tas_input);
UnregisterEngine(camera);
UnregisterEngine(virtual_amiibo);
UnregisterEngine(virtual_gamepad);
Common::Input::UnregisterInputFactory(keyboard->GetEngineName());
Common::Input::UnregisterOutputFactory(keyboard->GetEngineName());
keyboard.reset();
Common::Input::UnregisterInputFactory(mouse->GetEngineName());
Common::Input::UnregisterOutputFactory(mouse->GetEngineName());
mouse.reset();
Common::Input::UnregisterInputFactory(touch_screen->GetEngineName());
touch_screen.reset();
Common::Input::UnregisterInputFactory(gcadapter->GetEngineName());
Common::Input::UnregisterOutputFactory(gcadapter->GetEngineName());
gcadapter.reset();
Common::Input::UnregisterInputFactory(udp_client->GetEngineName());
Common::Input::UnregisterOutputFactory(udp_client->GetEngineName());
udp_client.reset();
Common::Input::UnregisterInputFactory(tas_input->GetEngineName());
Common::Input::UnregisterOutputFactory(tas_input->GetEngineName());
tas_input.reset();
Common::Input::UnregisterInputFactory(camera->GetEngineName());
Common::Input::UnregisterOutputFactory(camera->GetEngineName());
camera.reset();
Common::Input::UnregisterInputFactory(virtual_amiibo->GetEngineName());
Common::Input::UnregisterOutputFactory(virtual_amiibo->GetEngineName());
virtual_amiibo.reset();
#ifdef HAVE_SDL2
UnregisterEngine(sdl);
Common::Input::UnregisterInputFactory(sdl->GetEngineName());
Common::Input::UnregisterOutputFactory(sdl->GetEngineName());
sdl.reset();
#endif
Common::Input::UnregisterInputFactory("touch_from_button");
@@ -107,86 +163,117 @@ struct InputSubsystem::Impl {
return devices;
}
[[nodiscard]] std::shared_ptr<InputEngine> GetInputEngine(
[[nodiscard]] AnalogMapping GetAnalogMappingForDevice(
const Common::ParamPackage& params) const {
if (!params.Has("engine") || params.Get("engine", "") == "any") {
return nullptr;
return {};
}
const std::string engine = params.Get("engine", "");
if (engine == keyboard->GetEngineName()) {
return keyboard;
}
if (engine == mouse->GetEngineName()) {
return mouse;
return mouse->GetAnalogMappingForDevice(params);
}
if (engine == gcadapter->GetEngineName()) {
return gcadapter;
return gcadapter->GetAnalogMappingForDevice(params);
}
if (engine == udp_client->GetEngineName()) {
return udp_client;
return udp_client->GetAnalogMappingForDevice(params);
}
if (engine == tas_input->GetEngineName()) {
return tas_input->GetAnalogMappingForDevice(params);
}
#ifdef HAVE_SDL2
if (engine == sdl->GetEngineName()) {
return sdl;
return sdl->GetAnalogMappingForDevice(params);
}
#endif
return nullptr;
}
[[nodiscard]] AnalogMapping GetAnalogMappingForDevice(
const Common::ParamPackage& params) const {
const auto input_engine = GetInputEngine(params);
if (input_engine == nullptr) {
return {};
}
return input_engine->GetAnalogMappingForDevice(params);
return {};
}
[[nodiscard]] ButtonMapping GetButtonMappingForDevice(
const Common::ParamPackage& params) const {
const auto input_engine = GetInputEngine(params);
if (input_engine == nullptr) {
if (!params.Has("engine") || params.Get("engine", "") == "any") {
return {};
}
return input_engine->GetButtonMappingForDevice(params);
const std::string engine = params.Get("engine", "");
if (engine == gcadapter->GetEngineName()) {
return gcadapter->GetButtonMappingForDevice(params);
}
if (engine == udp_client->GetEngineName()) {
return udp_client->GetButtonMappingForDevice(params);
}
if (engine == tas_input->GetEngineName()) {
return tas_input->GetButtonMappingForDevice(params);
}
#ifdef HAVE_SDL2
if (engine == sdl->GetEngineName()) {
return sdl->GetButtonMappingForDevice(params);
}
#endif
return {};
}
[[nodiscard]] MotionMapping GetMotionMappingForDevice(
const Common::ParamPackage& params) const {
const auto input_engine = GetInputEngine(params);
if (input_engine == nullptr) {
if (!params.Has("engine") || params.Get("engine", "") == "any") {
return {};
}
return input_engine->GetMotionMappingForDevice(params);
const std::string engine = params.Get("engine", "");
if (engine == udp_client->GetEngineName()) {
return udp_client->GetMotionMappingForDevice(params);
}
#ifdef HAVE_SDL2
if (engine == sdl->GetEngineName()) {
return sdl->GetMotionMappingForDevice(params);
}
#endif
return {};
}
Common::Input::ButtonNames GetButtonName(const Common::ParamPackage& params) const {
if (!params.Has("engine") || params.Get("engine", "") == "any") {
return Common::Input::ButtonNames::Undefined;
}
const auto input_engine = GetInputEngine(params);
if (input_engine == nullptr) {
return Common::Input::ButtonNames::Invalid;
const std::string engine = params.Get("engine", "");
if (engine == mouse->GetEngineName()) {
return mouse->GetUIName(params);
}
return input_engine->GetUIName(params);
if (engine == gcadapter->GetEngineName()) {
return gcadapter->GetUIName(params);
}
if (engine == udp_client->GetEngineName()) {
return udp_client->GetUIName(params);
}
if (engine == tas_input->GetEngineName()) {
return tas_input->GetUIName(params);
}
#ifdef HAVE_SDL2
if (engine == sdl->GetEngineName()) {
return sdl->GetUIName(params);
}
#endif
return Common::Input::ButtonNames::Invalid;
}
bool IsStickInverted(const Common::ParamPackage& params) {
const auto input_engine = GetInputEngine(params);
if (input_engine == nullptr) {
return false;
const std::string engine = params.Get("engine", "");
if (engine == mouse->GetEngineName()) {
return mouse->IsStickInverted(params);
}
return input_engine->IsStickInverted(params);
if (engine == gcadapter->GetEngineName()) {
return gcadapter->IsStickInverted(params);
}
if (engine == udp_client->GetEngineName()) {
return udp_client->IsStickInverted(params);
}
if (engine == tas_input->GetEngineName()) {
return tas_input->IsStickInverted(params);
}
#ifdef HAVE_SDL2
if (engine == sdl->GetEngineName()) {
return sdl->IsStickInverted(params);
}
#endif
return false;
}
bool IsController(const Common::ParamPackage& params) {
@@ -203,9 +290,6 @@ struct InputSubsystem::Impl {
if (engine == tas_input->GetEngineName()) {
return true;
}
if (engine == virtual_gamepad->GetEngineName()) {
return true;
}
#ifdef HAVE_SDL2
if (engine == sdl->GetEngineName()) {
return true;
@@ -254,10 +338,28 @@ struct InputSubsystem::Impl {
std::shared_ptr<CemuhookUDP::UDPClient> udp_client;
std::shared_ptr<Camera> camera;
std::shared_ptr<VirtualAmiibo> virtual_amiibo;
std::shared_ptr<VirtualGamepad> virtual_gamepad;
std::shared_ptr<InputFactory> keyboard_factory;
std::shared_ptr<InputFactory> mouse_factory;
std::shared_ptr<InputFactory> gcadapter_input_factory;
std::shared_ptr<InputFactory> touch_screen_factory;
std::shared_ptr<InputFactory> udp_client_input_factory;
std::shared_ptr<InputFactory> tas_input_factory;
std::shared_ptr<InputFactory> camera_input_factory;
std::shared_ptr<InputFactory> virtual_amiibo_input_factory;
std::shared_ptr<OutputFactory> keyboard_output_factory;
std::shared_ptr<OutputFactory> mouse_output_factory;
std::shared_ptr<OutputFactory> gcadapter_output_factory;
std::shared_ptr<OutputFactory> udp_client_output_factory;
std::shared_ptr<OutputFactory> tas_output_factory;
std::shared_ptr<OutputFactory> camera_output_factory;
std::shared_ptr<OutputFactory> virtual_amiibo_output_factory;
#ifdef HAVE_SDL2
std::shared_ptr<SDLDriver> sdl;
std::shared_ptr<InputFactory> sdl_input_factory;
std::shared_ptr<OutputFactory> sdl_output_factory;
#endif
};
@@ -321,14 +423,6 @@ const VirtualAmiibo* InputSubsystem::GetVirtualAmiibo() const {
return impl->virtual_amiibo.get();
}
VirtualGamepad* InputSubsystem::GetVirtualGamepad() {
return impl->virtual_gamepad.get();
}
const VirtualGamepad* InputSubsystem::GetVirtualGamepad() const {
return impl->virtual_gamepad.get();
}
std::vector<Common::ParamPackage> InputSubsystem::GetInputDevices() const {
return impl->GetInputDevices();
}

View File

@@ -34,7 +34,6 @@ class Keyboard;
class Mouse;
class TouchScreen;
class VirtualAmiibo;
class VirtualGamepad;
struct MappingData;
} // namespace InputCommon
@@ -109,12 +108,6 @@ public:
/// Retrieves the underlying virtual amiibo input device.
[[nodiscard]] const VirtualAmiibo* GetVirtualAmiibo() const;
/// Retrieves the underlying virtual gamepad input device.
[[nodiscard]] VirtualGamepad* GetVirtualGamepad();
/// Retrieves the underlying virtual gamepad input device.
[[nodiscard]] const VirtualGamepad* GetVirtualGamepad() const;
/**
* Returns all available input devices that this Factory can create a new device with.
* Each returned ParamPackage should have a `display` field used for display, a `engine` field

View File

@@ -314,18 +314,6 @@ const char* ToString(VkResult result) noexcept {
return "VK_ERROR_VALIDATION_FAILED_EXT";
case VkResult::VK_ERROR_INVALID_SHADER_NV:
return "VK_ERROR_INVALID_SHADER_NV";
case VkResult::VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR:
return "VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR";
case VkResult::VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR:
return "VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR";
case VkResult::VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR:
return "VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR";
case VkResult::VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR:
return "VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR";
case VkResult::VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR:
return "VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR";
case VkResult::VK_ERROR_VIDEO_STD_VERSION_NOT_SUPPORTED_KHR:
return "VK_ERROR_VIDEO_STD_VERSION_NOT_SUPPORTED_KHR";
case VkResult::VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT:
return "VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT";
case VkResult::VK_ERROR_FRAGMENTATION_EXT:

View File

@@ -46,28 +46,30 @@
static Core::Frontend::WindowSystemType GetWindowSystemType();
EmuThread::EmuThread(Core::System& system) : m_system{system} {}
EmuThread::EmuThread(Core::System& system_) : system{system_} {}
EmuThread::~EmuThread() = default;
void EmuThread::run() {
const char* name = "EmuControlThread";
MicroProfileOnThreadCreate(name);
Common::SetCurrentThreadName(name);
std::string name = "EmuControlThread";
MicroProfileOnThreadCreate(name.c_str());
Common::SetCurrentThreadName(name.c_str());
auto& gpu = m_system.GPU();
auto stop_token = m_stop_source.get_token();
auto& gpu = system.GPU();
auto stop_token = stop_source.get_token();
bool debugger_should_start = system.DebuggerEnabled();
m_system.RegisterHostThread();
system.RegisterHostThread();
// Main process has been loaded. Make the context current to this thread and begin GPU and CPU
// execution.
gpu.ObtainContext();
emit LoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0);
if (Settings::values.use_disk_shader_cache.GetValue()) {
m_system.Renderer().ReadRasterizer()->LoadDiskResources(
m_system.GetCurrentProcessProgramID(), stop_token,
system.Renderer().ReadRasterizer()->LoadDiskResources(
system.GetCurrentProcessProgramID(), stop_token,
[this](VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total) {
emit LoadProgress(stage, value, total);
});
@@ -77,34 +79,57 @@ void EmuThread::run() {
gpu.ReleaseContext();
gpu.Start();
m_system.GetCpuManager().OnGpuReady();
system.GetCpuManager().OnGpuReady();
if (m_system.DebuggerEnabled()) {
m_system.InitializeDebugger();
}
system.RegisterExitCallback([this]() {
stop_source.request_stop();
SetRunning(false);
});
// Holds whether the cpu was running during the last iteration,
// so that the DebugModeLeft signal can be emitted before the
// next execution step
bool was_active = false;
while (!stop_token.stop_requested()) {
std::unique_lock lk{m_should_run_mutex};
if (m_should_run) {
m_system.Run();
m_is_running.store(true);
m_is_running.notify_all();
if (running) {
if (was_active) {
emit DebugModeLeft();
}
Common::CondvarWait(m_should_run_cv, lk, stop_token, [&] { return !m_should_run; });
running_guard = true;
Core::SystemResultStatus result = system.Run();
if (result != Core::SystemResultStatus::Success) {
running_guard = false;
this->SetRunning(false);
emit ErrorThrown(result, system.GetStatusDetails());
}
if (debugger_should_start) {
system.InitializeDebugger();
debugger_should_start = false;
}
running_wait.Wait();
result = system.Pause();
if (result != Core::SystemResultStatus::Success) {
running_guard = false;
this->SetRunning(false);
emit ErrorThrown(result, system.GetStatusDetails());
}
running_guard = false;
if (!stop_token.stop_requested()) {
was_active = true;
emit DebugModeEntered();
}
} else {
m_system.Pause();
m_is_running.store(false);
m_is_running.notify_all();
emit DebugModeEntered();
Common::CondvarWait(m_should_run_cv, lk, stop_token, [&] { return m_should_run; });
emit DebugModeLeft();
std::unique_lock lock{running_mutex};
Common::CondvarWait(running_cv, lock, stop_token, [&] { return IsRunning(); });
}
}
// Shutdown the main emulated process
m_system.DetachDebugger();
m_system.ShutdownMainProcess();
system.ShutdownMainProcess();
#if MICROPROFILE_ENABLED
MicroProfileOnThreadExit();
@@ -739,9 +764,7 @@ void GRenderWindow::InitializeCamera() {
return;
}
const auto camera_width = input_subsystem->GetCamera()->getImageWidth();
const auto camera_height = input_subsystem->GetCamera()->getImageHeight();
camera_data.resize(camera_width * camera_height);
camera_data.resize(CAMERA_WIDTH * CAMERA_HEIGHT);
camera_capture->setCaptureDestination(QCameraImageCapture::CaptureDestination::CaptureToBuffer);
connect(camera_capture.get(), &QCameraImageCapture::imageCaptured, this,
&GRenderWindow::OnCameraCapture);
@@ -797,22 +820,14 @@ void GRenderWindow::RequestCameraCapture() {
}
void GRenderWindow::OnCameraCapture(int requestId, const QImage& img) {
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) && YUZU_USE_QT_MULTIMEDIA
// TODO: Capture directly in the format and resolution needed
const auto camera_width = input_subsystem->GetCamera()->getImageWidth();
const auto camera_height = input_subsystem->GetCamera()->getImageHeight();
const auto converted =
img.scaled(static_cast<int>(camera_width), static_cast<int>(camera_height),
Qt::AspectRatioMode::IgnoreAspectRatio,
img.scaled(CAMERA_WIDTH, CAMERA_HEIGHT, Qt::AspectRatioMode::IgnoreAspectRatio,
Qt::TransformationMode::SmoothTransformation)
.mirrored(false, true);
if (camera_data.size() != camera_width * camera_height) {
camera_data.resize(camera_width * camera_height);
}
std::memcpy(camera_data.data(), converted.bits(), camera_width * camera_height * sizeof(u32));
input_subsystem->GetCamera()->SetCameraData(camera_width, camera_height, camera_data);
std::memcpy(camera_data.data(), converted.bits(), CAMERA_WIDTH * CAMERA_HEIGHT * sizeof(u32));
input_subsystem->GetCamera()->SetCameraData(CAMERA_WIDTH, CAMERA_HEIGHT, camera_data);
pending_camera_snapshots = 0;
#endif
}
bool GRenderWindow::event(QEvent* event) {

View File

@@ -47,7 +47,7 @@ class EmuThread final : public QThread {
Q_OBJECT
public:
explicit EmuThread(Core::System& system);
explicit EmuThread(Core::System& system_);
~EmuThread() override;
/**
@@ -57,30 +57,30 @@ public:
void run() override;
/**
* Sets whether the emulation thread should run or not
* @param should_run Boolean value, set the emulation thread to running if true
* Sets whether the emulation thread is running or not
* @param running_ Boolean value, set the emulation thread to running if true
* @note This function is thread-safe
*/
void SetRunning(bool should_run) {
// TODO: Prevent other threads from modifying the state until we finish.
{
// Notify the running thread to change state.
std::unique_lock run_lk{m_should_run_mutex};
m_should_run = should_run;
m_should_run_cv.notify_one();
}
// Wait until paused, if pausing.
if (!should_run) {
m_is_running.wait(true);
void SetRunning(bool running_) {
std::unique_lock lock{running_mutex};
running = running_;
lock.unlock();
running_cv.notify_all();
if (!running) {
running_wait.Set();
/// Wait until effectively paused
while (running_guard)
;
}
}
/**
* Check if the emulation thread is running or not
* @return True if the emulation thread is running, otherwise false
* @note This function is thread-safe
*/
bool IsRunning() const {
return m_is_running.load() || m_should_run;
return running;
}
/**
@@ -88,17 +88,18 @@ public:
*/
void ForceStop() {
LOG_WARNING(Frontend, "Force stopping EmuThread");
m_stop_source.request_stop();
stop_source.request_stop();
SetRunning(false);
}
private:
Core::System& m_system;
std::stop_source m_stop_source;
std::mutex m_should_run_mutex;
std::condition_variable_any m_should_run_cv;
std::atomic<bool> m_is_running{false};
bool m_should_run{true};
bool running = false;
std::stop_source stop_source;
std::mutex running_mutex;
std::condition_variable_any running_cv;
Common::Event running_wait{};
std::atomic_bool running_guard{false};
Core::System& system;
signals:
/**
@@ -119,6 +120,8 @@ signals:
*/
void DebugModeLeft();
void ErrorThrown(Core::SystemResultStatus, std::string);
void LoadProgress(VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total);
};
@@ -239,14 +242,16 @@ private:
bool first_frame = false;
InputCommon::TasInput::TasState last_tas_state;
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) && YUZU_USE_QT_MULTIMEDIA
bool is_virtual_camera;
int pending_camera_snapshots;
std::vector<u32> camera_data;
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) && YUZU_USE_QT_MULTIMEDIA
std::unique_ptr<QCamera> camera;
std::unique_ptr<QCameraImageCapture> camera_capture;
std::unique_ptr<QTimer> camera_timer;
static constexpr std::size_t CAMERA_WIDTH = 320;
static constexpr std::size_t CAMERA_HEIGHT = 240;
std::vector<u32> camera_data;
#endif
std::unique_ptr<QTimer> camera_timer;
Core::System& system;

View File

@@ -783,6 +783,8 @@ void Config::ReadSystemValues() {
}
}
ReadBasicSetting(Settings::values.device_name);
if (global) {
ReadBasicSetting(Settings::values.current_user);
Settings::values.current_user = std::clamp<int>(Settings::values.current_user.GetValue(), 0,
@@ -795,7 +797,6 @@ void Config::ReadSystemValues() {
} else {
Settings::values.custom_rtc = std::nullopt;
}
ReadBasicSetting(Settings::values.device_name);
}
ReadGlobalSetting(Settings::values.sound_index);
@@ -1406,6 +1407,7 @@ void Config::SaveSystemValues() {
Settings::values.rng_seed.UsingGlobal());
WriteSetting(QStringLiteral("rng_seed"), Settings::values.rng_seed.GetValue(global).value_or(0),
0, Settings::values.rng_seed.UsingGlobal());
WriteBasicSetting(Settings::values.device_name);
if (global) {
WriteBasicSetting(Settings::values.current_user);
@@ -1414,7 +1416,6 @@ void Config::SaveSystemValues() {
false);
WriteSetting(QStringLiteral("custom_rtc"),
QVariant::fromValue<long long>(Settings::values.custom_rtc.value_or(0)), 0);
WriteBasicSetting(Settings::values.device_name);
}
WriteGlobalSetting(Settings::values.sound_index);

View File

@@ -269,7 +269,7 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
InputCommon::InputSubsystem* input_subsystem_,
InputProfiles* profiles_, Core::HID::HIDCore& hid_core_,
bool is_powered_on_, bool debug_)
: QWidget(parent),
: QScrollArea(parent),
ui(std::make_unique<Ui::ConfigureInputPlayer>()), player_index{player_index_}, debug{debug_},
is_powered_on{is_powered_on_}, input_subsystem{input_subsystem_}, profiles(profiles_),
timeout_timer(std::make_unique<QTimer>()),

View File

@@ -10,7 +10,7 @@
#include <string>
#include <vector>
#include <QWidget>
#include <QScrollArea>
#include "common/param_package.h"
#include "common/settings.h"
@@ -46,7 +46,7 @@ class EmulatedController;
enum class NpadStyleIndex : u8;
} // namespace Core::HID
class ConfigureInputPlayer : public QWidget {
class ConfigureInputPlayer : public QScrollArea {
Q_OBJECT
public:

File diff suppressed because it is too large Load Diff

View File

@@ -1498,7 +1498,7 @@ void GMainWindow::SetupSigInterrupts() {
void GMainWindow::HandleSigInterrupt(int sig) {
if (sig == SIGINT) {
_exit(1);
exit(1);
}
// Calling into Qt directly from a signal handler is not safe,
@@ -1550,9 +1550,8 @@ void GMainWindow::AllowOSSleep() {
bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t program_index) {
// Shutdown previous session if the emu thread is still active...
if (emu_thread != nullptr) {
if (emu_thread != nullptr)
ShutdownGame();
}
if (!render_window->InitRenderTarget()) {
return false;
@@ -1711,11 +1710,6 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t
system->RegisterExecuteProgramCallback(
[this](std::size_t program_index_) { render_window->ExecuteProgram(program_index_); });
system->RegisterExitCallback([this] {
emu_thread->ForceStop();
render_window->Exit();
});
connect(render_window, &GRenderWindow::Closed, this, &GMainWindow::OnStopGame);
connect(render_window, &GRenderWindow::MouseActivity, this, &GMainWindow::OnMouseActivity);
// BlockingQueuedConnection is important here, it makes sure we've finished refreshing our views
@@ -1785,9 +1779,9 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t
OnStartGame();
}
bool GMainWindow::OnShutdownBegin() {
void GMainWindow::ShutdownGame() {
if (!emulation_running) {
return false;
return;
}
if (ui->action_Fullscreen->isChecked()) {
@@ -1799,55 +1793,21 @@ bool GMainWindow::OnShutdownBegin() {
// Disable unlimited frame rate
Settings::values.use_speed_limit.SetValue(true);
if (system->IsShuttingDown()) {
return false;
}
system->SetShuttingDown(true);
system->DetachDebugger();
discord_rpc->Pause();
RequestGameExit();
emu_thread->disconnect();
emu_thread->SetRunning(true);
emit EmulationStopping();
shutdown_timer.setSingleShot(true);
shutdown_timer.start(system->DebuggerEnabled() ? 0 : 5000);
connect(&shutdown_timer, &QTimer::timeout, this, &GMainWindow::OnEmulationStopTimeExpired);
connect(emu_thread.get(), &QThread::finished, this, &GMainWindow::OnEmulationStopped);
// Disable everything to prevent anything from being triggered here
ui->action_Pause->setEnabled(false);
ui->action_Restart->setEnabled(false);
ui->action_Stop->setEnabled(false);
return true;
}
void GMainWindow::OnShutdownBeginDialog() {
shutdown_dialog = new OverlayDialog(this, *system, QString{}, tr("Closing software..."),
QString{}, QString{}, Qt::AlignHCenter | Qt::AlignVCenter);
shutdown_dialog->open();
}
void GMainWindow::OnEmulationStopTimeExpired() {
if (emu_thread) {
// Wait for emulation thread to complete and delete it
if (!emu_thread->wait(5000)) {
emu_thread->ForceStop();
emu_thread->wait();
}
}
void GMainWindow::OnEmulationStopped() {
shutdown_timer.stop();
emu_thread->disconnect();
emu_thread->wait();
emu_thread = nullptr;
if (shutdown_dialog) {
shutdown_dialog->deleteLater();
shutdown_dialog = nullptr;
}
emulation_running = false;
discord_rpc->Update();
@@ -1893,20 +1853,6 @@ void GMainWindow::OnEmulationStopped() {
// When closing the game, destroy the GLWindow to clear the context after the game is closed
render_window->ReleaseRenderTarget();
Settings::RestoreGlobalState(system->IsPoweredOn());
system->HIDCore().ReloadInputDevices();
UpdateStatusButtons();
}
void GMainWindow::ShutdownGame() {
if (!emulation_running) {
return;
}
OnShutdownBegin();
OnEmulationStopTimeExpired();
OnEmulationStopped();
}
void GMainWindow::StoreRecentFile(const QString& filename) {
@@ -2715,9 +2661,6 @@ void GMainWindow::OnMenuInstallToNAND() {
return;
}
// Save folder location of the first selected file
UISettings::values.roms_path = QFileInfo(filenames[0]).path();
int remaining = filenames.size();
// This would only overflow above 2^43 bytes (8.796 TB)
@@ -2973,6 +2916,8 @@ void GMainWindow::OnStartGame() {
emu_thread->SetRunning(true);
connect(emu_thread.get(), &EmuThread::ErrorThrown, this, &GMainWindow::OnCoreError);
UpdateMenuState();
OnTasStateChanged();
@@ -3009,9 +2954,11 @@ void GMainWindow::OnStopGame() {
return;
}
if (OnShutdownBegin()) {
OnShutdownBeginDialog();
}
ShutdownGame();
Settings::RestoreGlobalState(system->IsPoweredOn());
system->HIDCore().ReloadInputDevices();
UpdateStatusButtons();
}
void GMainWindow::OnLoadComplete() {
@@ -3954,6 +3901,79 @@ void GMainWindow::OnMouseActivity() {
mouse_center_timer.stop();
}
void GMainWindow::OnCoreError(Core::SystemResultStatus result, std::string details) {
QMessageBox::StandardButton answer;
QString status_message;
const QString common_message =
tr("The game you are trying to load requires additional files from your Switch to be "
"dumped "
"before playing.<br/><br/>For more information on dumping these files, please see the "
"following wiki page: <a "
"href='https://yuzu-emu.org/wiki/"
"dumping-system-archives-and-the-shared-fonts-from-a-switch-console/'>Dumping System "
"Archives and the Shared Fonts from a Switch Console</a>.<br/><br/>Would you like to "
"quit "
"back to the game list? Continuing emulation may result in crashes, corrupted save "
"data, or other bugs.");
switch (result) {
case Core::SystemResultStatus::ErrorSystemFiles: {
QString message;
if (details.empty()) {
message =
tr("yuzu was unable to locate a Switch system archive. %1").arg(common_message);
} else {
message = tr("yuzu was unable to locate a Switch system archive: %1. %2")
.arg(QString::fromStdString(details), common_message);
}
answer = QMessageBox::question(this, tr("System Archive Not Found"), message,
QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
status_message = tr("System Archive Missing");
break;
}
case Core::SystemResultStatus::ErrorSharedFont: {
const QString message =
tr("yuzu was unable to locate the Switch shared fonts. %1").arg(common_message);
answer = QMessageBox::question(this, tr("Shared Fonts Not Found"), message,
QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
status_message = tr("Shared Font Missing");
break;
}
default:
answer = QMessageBox::question(
this, tr("Fatal Error"),
tr("yuzu has encountered a fatal error, please see the log for more details. "
"For more information on accessing the log, please see the following page: "
"<a href='https://community.citra-emu.org/t/how-to-upload-the-log-file/296'>How "
"to "
"Upload the Log File</a>.<br/><br/>Would you like to quit back to the game "
"list? "
"Continuing emulation may result in crashes, corrupted save data, or other "
"bugs."),
QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
status_message = tr("Fatal Error encountered");
break;
}
if (answer == QMessageBox::Yes) {
if (emu_thread) {
ShutdownGame();
Settings::RestoreGlobalState(system->IsPoweredOn());
system->HIDCore().ReloadInputDevices();
UpdateStatusButtons();
}
} else {
// Only show the message if the game is still running.
if (emu_thread) {
emu_thread->SetRunning(true);
message_label->setText(status_message);
}
}
}
void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) {
if (behavior == ReinitializeKeyBehavior::Warning) {
const auto res = QMessageBox::information(
@@ -4098,6 +4118,10 @@ void GMainWindow::closeEvent(QCloseEvent* event) {
// Shutdown session if the emu thread is active...
if (emu_thread != nullptr) {
ShutdownGame();
Settings::RestoreGlobalState(system->IsPoweredOn());
system->HIDCore().ReloadInputDevices();
UpdateStatusButtons();
}
render_window->close();
@@ -4190,10 +4214,6 @@ bool GMainWindow::ConfirmForceLockedExit() {
}
void GMainWindow::RequestGameExit() {
if (!system->IsPoweredOn()) {
return;
}
auto& sm{system->ServiceManager()};
auto applet_oe = sm.GetService<Service::AM::AppletOE>("appletOE");
auto applet_ae = sm.GetService<Service::AM::AppletAE>("appletAE");

View File

@@ -29,7 +29,6 @@ class GImageInfo;
class GRenderWindow;
class LoadingScreen;
class MicroProfileDialog;
class OverlayDialog;
class ProfilerWidget;
class ControllerDialog;
class QLabel;
@@ -333,13 +332,10 @@ private slots:
void ResetWindowSize900();
void ResetWindowSize1080();
void OnCaptureScreenshot();
void OnCoreError(Core::SystemResultStatus, std::string);
void OnReinitializeKeys(ReinitializeKeyBehavior behavior);
void OnLanguageChanged(const QString& locale);
void OnMouseActivity();
bool OnShutdownBegin();
void OnShutdownBeginDialog();
void OnEmulationStopped();
void OnEmulationStopTimeExpired();
private:
QString GetGameListErrorRemoving(InstalledEntryType type) const;
@@ -389,8 +385,6 @@ private:
GRenderWindow* render_window;
GameList* game_list;
LoadingScreen* loading_screen;
QTimer shutdown_timer;
OverlayDialog* shutdown_dialog{};
GameListPlaceholder* game_list_placeholder;

View File

@@ -186,7 +186,7 @@ pid_t SpawnChild(const char* arg0) {
return pid;
} else if (pid == 0) {
// child
execlp(arg0, arg0, nullptr);
execl(arg0, arg0, nullptr);
const int err = errno;
fmt::print(stderr, "execl failed with error {}\n", err);
_exit(0);

View File

@@ -3,7 +3,6 @@
#include <QKeyEvent>
#include <QScreen>
#include <QWindow>
#include "core/core.h"
#include "core/hid/hid_types.h"
@@ -43,7 +42,7 @@ OverlayDialog::OverlayDialog(QWidget* parent, Core::System& system, const QStrin
MoveAndResizeWindow();
// TODO (Morph): Remove this when InputInterpreter no longer relies on the HID backend
if (system.IsPoweredOn() && !ui->buttonsDialog->isHidden()) {
if (system.IsPoweredOn()) {
input_interpreter = std::make_unique<InputInterpreter>(system);
StartInputThread();
@@ -84,11 +83,6 @@ void OverlayDialog::InitializeRegularTextDialog(const QString& title_text, const
ui->button_ok_label->setEnabled(false);
}
if (ui->button_cancel->isHidden() && ui->button_ok_label->isHidden()) {
ui->buttonsDialog->hide();
return;
}
connect(
ui->button_cancel, &QPushButton::clicked, this,
[this](bool) {
@@ -136,11 +130,6 @@ void OverlayDialog::InitializeRichTextDialog(const QString& title_text, const QS
ui->button_ok_rich->setEnabled(false);
}
if (ui->button_cancel_rich->isHidden() && ui->button_ok_rich->isHidden()) {
ui->buttonsRichDialog->hide();
return;
}
connect(
ui->button_cancel_rich, &QPushButton::clicked, this,
[this](bool) {
@@ -163,7 +152,7 @@ void OverlayDialog::MoveAndResizeWindow() {
const auto height = static_cast<float>(parentWidget()->height());
// High DPI
const float dpi_scale = parentWidget()->windowHandle()->screen()->logicalDotsPerInch() / 96.0f;
const float dpi_scale = qApp->screenAt(pos)->logicalDotsPerInch() / 96.0f;
const auto title_text_font_size = BASE_TITLE_FONT_SIZE * (height / BASE_HEIGHT) / dpi_scale;
const auto body_text_font_size =
@@ -260,9 +249,3 @@ void OverlayDialog::InputThread() {
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
}
void OverlayDialog::keyPressEvent(QKeyEvent* e) {
if (!ui->buttonsDialog->isHidden() || e->key() != Qt::Key_Escape) {
QDialog::keyPressEvent(e);
}
}

View File

@@ -94,7 +94,6 @@ private:
/// The thread where input is being polled and processed.
void InputThread();
void keyPressEvent(QKeyEvent* e) override;
std::unique_ptr<Ui::OverlayDialog> ui;

View File

@@ -49,15 +49,6 @@ if(UNIX AND NOT APPLE)
install(TARGETS yuzu-cmd)
endif()
if(WIN32)
# compile as a win32 gui application instead of a console application
if(MSVC)
set_target_properties(yuzu-cmd PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
elseif(MINGW)
set_target_properties(yuzu-cmd PROPERTIES LINK_FLAGS_RELEASE "-Wl,--subsystem,windows")
endif()
endif()
if (MSVC)
include(CopyYuzuSDLDeps)
copy_yuzu_SDL_deps(yuzu-cmd)

View File

@@ -174,13 +174,6 @@ static void OnStatusMessageReceived(const Network::StatusMessageEntry& msg) {
/// Application entry point
int main(int argc, char** argv) {
#ifdef _WIN32
if (AttachConsole(ATTACH_PARENT_PROCESS)) {
freopen("CONOUT$", "wb", stdout);
freopen("CONOUT$", "wb", stderr);
}
#endif
Common::Log::Initialize();
Common::Log::SetColorConsoleBackendEnabled(true);
Common::Log::Start();