summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitmodules2
m---------externals/dynarmic0
m---------externals/mbedtls0
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/common/common_funcs.h6
-rw-r--r--src/common/fiber.cpp23
-rw-r--r--src/common/fiber.h2
-rw-r--r--src/common/misc.cpp44
-rw-r--r--src/core/core.cpp13
-rw-r--r--src/core/cpu_manager.cpp8
-rw-r--r--src/core/crypto/aes_util.cpp2
-rw-r--r--src/core/hle/kernel/k_scheduler.cpp17
-rw-r--r--src/core/hle/kernel/k_thread.cpp50
-rw-r--r--src/core/hle/kernel/k_thread.h24
-rw-r--r--src/core/hle/kernel/kernel.cpp11
-rw-r--r--src/core/hle/kernel/process.cpp5
-rw-r--r--src/core/hle/kernel/svc.cpp5
-rw-r--r--src/core/network/network.cpp173
-rw-r--r--src/core/network/network.h6
-rw-r--r--src/input_common/mouse/mouse_input.cpp11
-rw-r--r--src/input_common/mouse/mouse_input.h12
-rw-r--r--src/input_common/udp/client.cpp26
-rw-r--r--src/input_common/udp/client.h6
-rw-r--r--src/tests/CMakeLists.txt1
-rw-r--r--src/tests/common/fibers.cpp28
-rw-r--r--src/tests/core/network/network.cpp28
-rw-r--r--src/video_core/renderer_vulkan/vk_command_pool.cpp2
-rw-r--r--src/yuzu/bootmanager.cpp25
-rw-r--r--src/yuzu/bootmanager.h7
-rw-r--r--src/yuzu/configuration/config.cpp9
-rw-r--r--src/yuzu/configuration/configure_input_player.cpp4
-rw-r--r--src/yuzu/configuration/configure_motion_touch.cpp8
-rw-r--r--src/yuzu/configuration/configure_motion_touch.h2
-rw-r--r--src/yuzu/main.cpp19
-rw-r--r--src/yuzu_cmd/config.cpp2
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2.cpp24
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2.h7
37 files changed, 367 insertions, 247 deletions
diff --git a/.gitmodules b/.gitmodules
index 93ba9b930..a0a89933d 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -27,7 +27,7 @@
url = https://github.com/ReinUsesLisp/sirit
[submodule "mbedtls"]
path = externals/mbedtls
- url = https://github.com/DarkLordZach/mbedtls
+ url = https://github.com/yuzu-emu/mbedtls
[submodule "libzip"]
path = externals/libzip/libzip
url = https://github.com/nih-at/libzip.git
diff --git a/externals/dynarmic b/externals/dynarmic
-Subproject cafa687684a3e5dbe86be7150c0f8183d2ad53c
+Subproject 646fd0592091c5c1e5899fa715bd7b7fcc977a3
diff --git a/externals/mbedtls b/externals/mbedtls
-Subproject a280e602f3a4ae001d3a83cbc3e6e04c99c2227
+Subproject eac2416b8fdb2cb9c867a538100bf95326bad75
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 1cfd3bbc9..8bd7e5f72 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -27,6 +27,7 @@ if (MSVC)
# /Zo - Enhanced debug info for optimized builds
# /permissive- - Enables stricter C++ standards conformance checks
# /EHsc - C++-only exception handling semantics
+ # /utf-8 - Set source and execution character sets to UTF-8
# /volatile:iso - Use strict standards-compliant volatile semantics.
# /Zc:externConstexpr - Allow extern constexpr variables to have external linkage, like the standard mandates
# /Zc:inline - Let codegen omit inline functions in object files
@@ -38,6 +39,7 @@ if (MSVC)
/permissive-
/EHsc
/std:c++latest
+ /utf-8
/volatile:iso
/Zc:externConstexpr
/Zc:inline
diff --git a/src/common/common_funcs.h b/src/common/common_funcs.h
index 71b64e32a..4ace2cd33 100644
--- a/src/common/common_funcs.h
+++ b/src/common/common_funcs.h
@@ -52,9 +52,13 @@ __declspec(dllimport) void __stdcall DebugBreak(void);
// Generic function to get last error message.
// Call directly after the command or use the error num.
// This function might change the error code.
-// Defined in Misc.cpp.
+// Defined in misc.cpp.
[[nodiscard]] std::string GetLastErrorMsg();
+// Like GetLastErrorMsg(), but passing an explicit error code.
+// Defined in misc.cpp.
+[[nodiscard]] std::string NativeErrorToString(int e);
+
#define DECLARE_ENUM_FLAG_OPERATORS(type) \
[[nodiscard]] constexpr type operator|(type a, type b) noexcept { \
using T = std::underlying_type_t<type>; \
diff --git a/src/common/fiber.cpp b/src/common/fiber.cpp
index 3c1eefcb7..39532ff58 100644
--- a/src/common/fiber.cpp
+++ b/src/common/fiber.cpp
@@ -116,16 +116,19 @@ void Fiber::Rewind() {
boost::context::detail::jump_fcontext(impl->rewind_context, this);
}
-void Fiber::YieldTo(std::shared_ptr<Fiber> from, std::shared_ptr<Fiber> to) {
- ASSERT_MSG(from != nullptr, "Yielding fiber is null!");
- ASSERT_MSG(to != nullptr, "Next fiber is null!");
- to->impl->guard.lock();
- to->impl->previous_fiber = from;
- auto transfer = boost::context::detail::jump_fcontext(to->impl->context, to.get());
- ASSERT(from->impl->previous_fiber != nullptr);
- from->impl->previous_fiber->impl->context = transfer.fctx;
- from->impl->previous_fiber->impl->guard.unlock();
- from->impl->previous_fiber.reset();
+void Fiber::YieldTo(std::weak_ptr<Fiber> weak_from, Fiber& to) {
+ to.impl->guard.lock();
+ to.impl->previous_fiber = weak_from.lock();
+
+ auto transfer = boost::context::detail::jump_fcontext(to.impl->context, &to);
+
+ // "from" might no longer be valid if the thread was killed
+ if (auto from = weak_from.lock()) {
+ ASSERT(from->impl->previous_fiber != nullptr);
+ from->impl->previous_fiber->impl->context = transfer.fctx;
+ from->impl->previous_fiber->impl->guard.unlock();
+ from->impl->previous_fiber.reset();
+ }
}
std::shared_ptr<Fiber> Fiber::ThreadToFiber() {
diff --git a/src/common/fiber.h b/src/common/fiber.h
index f7f587f8c..f2a8ff29a 100644
--- a/src/common/fiber.h
+++ b/src/common/fiber.h
@@ -41,7 +41,7 @@ public:
/// Yields control from Fiber 'from' to Fiber 'to'
/// Fiber 'from' must be the currently running fiber.
- static void YieldTo(std::shared_ptr<Fiber> from, std::shared_ptr<Fiber> to);
+ static void YieldTo(std::weak_ptr<Fiber> weak_from, Fiber& to);
[[nodiscard]] static std::shared_ptr<Fiber> ThreadToFiber();
void SetRewindPoint(std::function<void(void*)>&& rewind_func, void* rewind_param);
diff --git a/src/common/misc.cpp b/src/common/misc.cpp
index 1d5393597..495385b9e 100644
--- a/src/common/misc.cpp
+++ b/src/common/misc.cpp
@@ -12,27 +12,41 @@
#include "common/common_funcs.h"
-// Generic function to get last error message.
-// Call directly after the command or use the error num.
-// This function might change the error code.
-std::string GetLastErrorMsg() {
- static constexpr std::size_t buff_size = 255;
- char err_str[buff_size];
-
+std::string NativeErrorToString(int e) {
#ifdef _WIN32
- FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, GetLastError(),
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), err_str, buff_size, nullptr);
- return std::string(err_str, buff_size);
-#elif defined(__GLIBC__) && (_GNU_SOURCE || (_POSIX_C_SOURCE < 200112L && _XOPEN_SOURCE < 600))
+ LPSTR err_str;
+
+ DWORD res = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ nullptr, e, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ reinterpret_cast<LPSTR>(&err_str), 1, nullptr);
+ if (!res) {
+ return "(FormatMessageA failed to format error)";
+ }
+ std::string ret(err_str);
+ LocalFree(err_str);
+ return ret;
+#else
+ char err_str[255];
+#if defined(__GLIBC__) && (_GNU_SOURCE || (_POSIX_C_SOURCE < 200112L && _XOPEN_SOURCE < 600))
// Thread safe (GNU-specific)
- const char* str = strerror_r(errno, err_str, buff_size);
+ const char* str = strerror_r(e, err_str, sizeof(err_str));
return std::string(str);
#else
// Thread safe (XSI-compliant)
- const int success = strerror_r(errno, err_str, buff_size);
- if (success != 0) {
- return {};
+ int second_err = strerror_r(e, err_str, sizeof(err_str));
+ if (second_err != 0) {
+ return "(strerror_r failed to format error)";
}
return std::string(err_str);
+#endif // GLIBC etc.
+#endif // _WIN32
+}
+
+std::string GetLastErrorMsg() {
+#ifdef _WIN32
+ return NativeErrorToString(GetLastError());
+#else
+ return NativeErrorToString(errno);
#endif
}
diff --git a/src/core/core.cpp b/src/core/core.cpp
index de6305e2a..305f56ff1 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -299,28 +299,17 @@ struct System::Impl {
gpu_core->WaitIdle();
}
- // Shutdown emulation session
services.reset();
service_manager.reset();
cheat_engine.reset();
telemetry_session.reset();
-
- // Close all CPU/threading state
cpu_manager.Shutdown();
-
- // Release the Time Manager's resources
time_manager.Shutdown();
-
- // Shutdown kernel and core timing
core_timing.Shutdown();
- kernel.Shutdown();
-
- // Close app loader
app_loader.reset();
gpu_core.reset();
perf_stats.reset();
-
- // Clear all applets
+ kernel.Shutdown();
applet_manager.ClearAll();
LOG_DEBUG(Core, "Shutdown OK");
diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp
index 8f04fb8f5..bdb374792 100644
--- a/src/core/cpu_manager.cpp
+++ b/src/core/cpu_manager.cpp
@@ -148,7 +148,7 @@ void CpuManager::MultiCoreRunSuspendThread() {
auto core = kernel.GetCurrentHostThreadID();
auto& scheduler = *kernel.CurrentScheduler();
Kernel::KThread* current_thread = scheduler.GetCurrentThread();
- Common::Fiber::YieldTo(current_thread->GetHostContext(), core_data[core].host_context);
+ Common::Fiber::YieldTo(current_thread->GetHostContext(), *core_data[core].host_context);
ASSERT(scheduler.ContextSwitchPending());
ASSERT(core == kernel.GetCurrentHostThreadID());
scheduler.RescheduleCurrentCore();
@@ -245,7 +245,7 @@ void CpuManager::SingleCoreRunSuspendThread() {
auto core = kernel.GetCurrentHostThreadID();
auto& scheduler = *kernel.CurrentScheduler();
Kernel::KThread* current_thread = scheduler.GetCurrentThread();
- Common::Fiber::YieldTo(current_thread->GetHostContext(), core_data[0].host_context);
+ Common::Fiber::YieldTo(current_thread->GetHostContext(), *core_data[0].host_context);
ASSERT(scheduler.ContextSwitchPending());
ASSERT(core == kernel.GetCurrentHostThreadID());
scheduler.RescheduleCurrentCore();
@@ -271,7 +271,7 @@ void CpuManager::PreemptSingleCore(bool from_running_enviroment) {
scheduler.Unload(scheduler.GetCurrentThread());
auto& next_scheduler = kernel.Scheduler(current_core);
- Common::Fiber::YieldTo(current_thread->GetHostContext(), next_scheduler.ControlContext());
+ Common::Fiber::YieldTo(current_thread->GetHostContext(), *next_scheduler.ControlContext());
}
// May have changed scheduler
@@ -363,7 +363,7 @@ void CpuManager::RunThread(std::size_t core) {
auto current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread();
data.is_running = true;
- Common::Fiber::YieldTo(data.host_context, current_thread->GetHostContext());
+ Common::Fiber::YieldTo(data.host_context, *current_thread->GetHostContext());
data.is_running = false;
data.is_paused = true;
data.exit_barrier->Wait();
diff --git a/src/core/crypto/aes_util.cpp b/src/core/crypto/aes_util.cpp
index 6a9734812..cb7506241 100644
--- a/src/core/crypto/aes_util.cpp
+++ b/src/core/crypto/aes_util.cpp
@@ -105,8 +105,6 @@ void AESCipher<Key, KeySize>::Transcode(const u8* src, std::size_t size, u8* des
}
}
}
-
- mbedtls_cipher_finish(context, nullptr, nullptr);
}
template <typename Key, std::size_t KeySize>
diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp
index bb5f43b53..e7de48476 100644
--- a/src/core/hle/kernel/k_scheduler.cpp
+++ b/src/core/hle/kernel/k_scheduler.cpp
@@ -734,7 +734,7 @@ void KScheduler::ScheduleImpl() {
}
guard.unlock();
- Common::Fiber::YieldTo(*old_context, switch_fiber);
+ Common::Fiber::YieldTo(*old_context, *switch_fiber);
/// When a thread wakes up, the scheduler may have changed to other in another core.
auto& next_scheduler = *system.Kernel().CurrentScheduler();
next_scheduler.SwitchContextStep2();
@@ -769,13 +769,8 @@ void KScheduler::SwitchToCurrent() {
break;
}
}
- std::shared_ptr<Common::Fiber>* next_context;
- if (next_thread != nullptr) {
- next_context = &next_thread->GetHostContext();
- } else {
- next_context = &idle_thread->GetHostContext();
- }
- Common::Fiber::YieldTo(switch_fiber, *next_context);
+ auto thread = next_thread ? next_thread : idle_thread;
+ Common::Fiber::YieldTo(switch_fiber, *thread->GetHostContext());
} while (!is_switch_pending());
}
}
@@ -800,9 +795,9 @@ void KScheduler::Initialize() {
std::string name = "Idle Thread Id:" + std::to_string(core_id);
std::function<void(void*)> init_func = Core::CpuManager::GetIdleThreadStartFunc();
void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater();
- auto thread_res = KThread::Create(system, ThreadType::Main, name, 0,
- KThread::IdleThreadPriority, 0, static_cast<u32>(core_id), 0,
- nullptr, std::move(init_func), init_func_parameter);
+ auto thread_res = KThread::CreateThread(
+ system, ThreadType::Main, name, 0, KThread::IdleThreadPriority, 0,
+ static_cast<u32>(core_id), 0, nullptr, std::move(init_func), init_func_parameter);
idle_thread = thread_res.Unwrap().get();
}
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp
index 1661afbd9..e0f53287c 100644
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -995,22 +995,11 @@ std::shared_ptr<Common::Fiber>& KThread::GetHostContext() {
return host_context;
}
-ResultVal<std::shared_ptr<KThread>> KThread::Create(Core::System& system, ThreadType type_flags,
- std::string name, VAddr entry_point,
- u32 priority, u64 arg, s32 processor_id,
- VAddr stack_top, Process* owner_process) {
- std::function<void(void*)> init_func = Core::CpuManager::GetGuestThreadStartFunc();
- void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater();
- return Create(system, type_flags, name, entry_point, priority, arg, processor_id, stack_top,
- owner_process, std::move(init_func), init_func_parameter);
-}
-
-ResultVal<std::shared_ptr<KThread>> KThread::Create(Core::System& system, ThreadType type_flags,
- std::string name, VAddr entry_point,
- u32 priority, u64 arg, s32 processor_id,
- VAddr stack_top, Process* owner_process,
- std::function<void(void*)>&& thread_start_func,
- void* thread_start_parameter) {
+ResultVal<std::shared_ptr<KThread>> KThread::CreateThread(Core::System& system,
+ ThreadType type_flags, std::string name,
+ VAddr entry_point, u32 priority, u64 arg,
+ s32 processor_id, VAddr stack_top,
+ Process* owner_process) {
auto& kernel = system.Kernel();
std::shared_ptr<KThread> thread = std::make_shared<KThread>(kernel);
@@ -1027,12 +1016,35 @@ ResultVal<std::shared_ptr<KThread>> KThread::Create(Core::System& system, Thread
auto& scheduler = kernel.GlobalSchedulerContext();
scheduler.AddThread(thread);
- thread->host_context =
- std::make_shared<Common::Fiber>(std::move(thread_start_func), thread_start_parameter);
-
return MakeResult<std::shared_ptr<KThread>>(std::move(thread));
}
+ResultVal<std::shared_ptr<KThread>> KThread::CreateThread(
+ Core::System& system, ThreadType type_flags, std::string name, VAddr entry_point, u32 priority,
+ u64 arg, s32 processor_id, VAddr stack_top, Process* owner_process,
+ std::function<void(void*)>&& thread_start_func, void* thread_start_parameter) {
+ auto thread_result = CreateThread(system, type_flags, name, entry_point, priority, arg,
+ processor_id, stack_top, owner_process);
+
+ if (thread_result.Succeeded()) {
+ (*thread_result)->host_context =
+ std::make_shared<Common::Fiber>(std::move(thread_start_func), thread_start_parameter);
+ }
+
+ return thread_result;
+}
+
+ResultVal<std::shared_ptr<KThread>> KThread::CreateUserThread(
+ Core::System& system, ThreadType type_flags, std::string name, VAddr entry_point, u32 priority,
+ u64 arg, s32 processor_id, VAddr stack_top, Process* owner_process) {
+ std::function<void(void*)> init_func = Core::CpuManager::GetGuestThreadStartFunc();
+
+ void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater();
+
+ return CreateThread(system, type_flags, name, entry_point, priority, arg, processor_id,
+ stack_top, owner_process, std::move(init_func), init_func_parameter);
+}
+
KThread* GetCurrentThreadPointer(KernelCore& kernel) {
return kernel.GetCurrentEmuThread();
}
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h
index c8ac656a4..1c19b23dc 100644
--- a/src/core/hle/kernel/k_thread.h
+++ b/src/core/hle/kernel/k_thread.h
@@ -116,7 +116,7 @@ public:
using WaiterList = boost::intrusive::list<KThread>;
/**
- * Creates and returns a new thread. The new thread is immediately scheduled
+ * Creates and returns a new thread.
* @param system The instance of the whole system
* @param name The friendly name desired for the thread
* @param entry_point The address at which the thread should start execution
@@ -127,12 +127,12 @@ public:
* @param owner_process The parent process for the thread, if null, it's a kernel thread
* @return A shared pointer to the newly created thread
*/
- [[nodiscard]] static ResultVal<std::shared_ptr<KThread>> Create(
+ [[nodiscard]] static ResultVal<std::shared_ptr<KThread>> CreateThread(
Core::System& system, ThreadType type_flags, std::string name, VAddr entry_point,
u32 priority, u64 arg, s32 processor_id, VAddr stack_top, Process* owner_process);
/**
- * Creates and returns a new thread. The new thread is immediately scheduled
+ * Creates and returns a new thread, with a specified entry point.
* @param system The instance of the whole system
* @param name The friendly name desired for the thread
* @param entry_point The address at which the thread should start execution
@@ -145,11 +145,27 @@ public:
* @param thread_start_parameter The parameter which will passed to host context on init
* @return A shared pointer to the newly created thread
*/
- [[nodiscard]] static ResultVal<std::shared_ptr<KThread>> Create(
+ [[nodiscard]] static ResultVal<std::shared_ptr<KThread>> CreateThread(
Core::System& system, ThreadType type_flags, std::string name, VAddr entry_point,
u32 priority, u64 arg, s32 processor_id, VAddr stack_top, Process* owner_process,
std::function<void(void*)>&& thread_start_func, void* thread_start_parameter);
+ /**
+ * Creates and returns a new thread for the emulated "user" process.
+ * @param system The instance of the whole system
+ * @param name The friendly name desired for the thread
+ * @param entry_point The address at which the thread should start execution
+ * @param priority The thread's priority
+ * @param arg User data to pass to the thread
+ * @param processor_id The ID(s) of the processors on which the thread is desired to be run
+ * @param stack_top The address of the thread's stack top
+ * @param owner_process The parent process for the thread, if null, it's a kernel thread
+ * @return A shared pointer to the newly created thread
+ */
+ [[nodiscard]] static ResultVal<std::shared_ptr<KThread>> CreateUserThread(
+ Core::System& system, ThreadType type_flags, std::string name, VAddr entry_point,
+ u32 priority, u64 arg, s32 processor_id, VAddr stack_top, Process* owner_process);
+
[[nodiscard]] std::string GetName() const override {
return name;
}
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 331cf3a60..780008b08 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -181,9 +181,9 @@ struct KernelCore::Impl {
std::string name = "Suspend Thread Id:" + std::to_string(i);
std::function<void(void*)> init_func = Core::CpuManager::GetSuspendThreadStartFunc();
void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater();
- auto thread_res = KThread::Create(system, ThreadType::HighPriority, std::move(name), 0,
- 0, 0, static_cast<u32>(i), 0, nullptr,
- std::move(init_func), init_func_parameter);
+ auto thread_res = KThread::CreateThread(
+ system, ThreadType::HighPriority, std::move(name), 0, 0, 0, static_cast<u32>(i), 0,
+ nullptr, std::move(init_func), init_func_parameter);
suspend_threads[i] = std::move(thread_res).Unwrap();
}
@@ -221,10 +221,9 @@ struct KernelCore::Impl {
// Gets the dummy KThread for the caller, allocating a new one if this is the first time
KThread* GetHostDummyThread() {
const thread_local auto thread =
- KThread::Create(
+ KThread::CreateThread(
system, ThreadType::Main, fmt::format("DummyThread:{}", GetHostThreadId()), 0,
- KThread::DefaultThreadPriority, 0, static_cast<u32>(3), 0, nullptr,
- []([[maybe_unused]] void* arg) { UNREACHABLE(); }, nullptr)
+ KThread::DefaultThreadPriority, 0, static_cast<u32>(3), 0, nullptr)
.Unwrap();
return thread.get();
}
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 73b85d6f9..9d5956ead 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -40,8 +40,9 @@ namespace {
void SetupMainThread(Core::System& system, Process& owner_process, u32 priority, VAddr stack_top) {
const VAddr entry_point = owner_process.PageTable().GetCodeRegionStart();
ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::Threads, 1));
- auto thread_res = KThread::Create(system, ThreadType::User, "main", entry_point, priority, 0,
- owner_process.GetIdealCoreId(), stack_top, &owner_process);
+ auto thread_res =
+ KThread::CreateUserThread(system, ThreadType::User, "main", entry_point, priority, 0,
+ owner_process.GetIdealCoreId(), stack_top, &owner_process);
std::shared_ptr<KThread> thread = std::move(thread_res).Unwrap();
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index cc8fa6576..326d3b9ec 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -1532,8 +1532,9 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e
std::shared_ptr<KThread> thread;
{
KScopedLightLock lk{process.GetStateLock()};
- CASCADE_RESULT(thread, KThread::Create(system, ThreadType::User, "", entry_point, priority,
- arg, core_id, stack_bottom, &process));
+ CASCADE_RESULT(thread,
+ KThread::CreateUserThread(system, ThreadType::User, "", entry_point,
+ priority, arg, core_id, stack_bottom, &process));
}
const auto new_thread_handle = process.GetHandleTable().Create(thread);
diff --git a/src/core/network/network.cpp b/src/core/network/network.cpp
index 681e93468..526bfa110 100644
--- a/src/core/network/network.cpp
+++ b/src/core/network/network.cpp
@@ -7,6 +7,7 @@
#include <limits>
#include <utility>
#include <vector>
+#include "common/common_funcs.h"
#ifdef _WIN32
#define _WINSOCK_DEPRECATED_NO_WARNINGS // gethostname
@@ -90,15 +91,36 @@ LINGER MakeLinger(bool enable, u32 linger_value) {
return value;
}
-int LastError() {
- return WSAGetLastError();
-}
-
bool EnableNonBlock(SOCKET fd, bool enable) {
u_long value = enable ? 1 : 0;
return ioctlsocket(fd, FIONBIO, &value) != SOCKET_ERROR;
}
+Errno TranslateNativeError(int e) {
+ switch (e) {
+ case WSAEBADF:
+ return Errno::BADF;
+ case WSAEINVAL:
+ return Errno::INVAL;
+ case WSAEMFILE:
+ return Errno::MFILE;
+ case WSAENOTCONN:
+ return Errno::NOTCONN;
+ case WSAEWOULDBLOCK:
+ return Errno::AGAIN;
+ case WSAECONNREFUSED:
+ return Errno::CONNREFUSED;
+ case WSAEHOSTUNREACH:
+ return Errno::HOSTUNREACH;
+ case WSAENETDOWN:
+ return Errno::NETDOWN;
+ case WSAENETUNREACH:
+ return Errno::NETUNREACH;
+ default:
+ return Errno::OTHER;
+ }
+}
+
#elif YUZU_UNIX // ^ _WIN32 v YUZU_UNIX
using SOCKET = int;
@@ -108,9 +130,6 @@ using ULONG = u64;
constexpr SOCKET INVALID_SOCKET = -1;
constexpr SOCKET SOCKET_ERROR = -1;
-constexpr int WSAEWOULDBLOCK = EAGAIN;
-constexpr int WSAENOTCONN = ENOTCONN;
-
constexpr int SD_RECEIVE = SHUT_RD;
constexpr int SD_SEND = SHUT_WR;
constexpr int SD_BOTH = SHUT_RDWR;
@@ -162,10 +181,6 @@ linger MakeLinger(bool enable, u32 linger_value) {
return value;
}
-int LastError() {
- return errno;
-}
-
bool EnableNonBlock(int fd, bool enable) {
int flags = fcntl(fd, F_GETFD);
if (flags == -1) {
@@ -179,8 +194,43 @@ bool EnableNonBlock(int fd, bool enable) {
return fcntl(fd, F_SETFD, flags) == 0;
}
+Errno TranslateNativeError(int e) {
+ switch (e) {
+ case EBADF:
+ return Errno::BADF;
+ case EINVAL:
+ return Errno::INVAL;
+ case EMFILE:
+ return Errno::MFILE;
+ case ENOTCONN:
+ return Errno::NOTCONN;
+ case EAGAIN:
+ return Errno::AGAIN;
+ case ECONNREFUSED:
+ return Errno::CONNREFUSED;
+ case EHOSTUNREACH:
+ return Errno::HOSTUNREACH;
+ case ENETDOWN:
+ return Errno::NETDOWN;
+ case ENETUNREACH:
+ return Errno::NETUNREACH;
+ default:
+ return Errno::OTHER;
+ }
+}
+
#endif
+Errno GetAndLogLastError() {
+#ifdef _WIN32
+ int e = WSAGetLastError();
+#else
+ int e = errno;
+#endif
+ LOG_ERROR(Network, "Socket operation error: {}", NativeErrorToString(e));
+ return TranslateNativeError(e);
+}
+
int TranslateDomain(Domain domain) {
switch (domain) {
case Domain::INET:
@@ -290,9 +340,7 @@ Errno SetSockOpt(SOCKET fd, int option, T value) {
if (result != SOCKET_ERROR) {
return Errno::SUCCESS;
}
- const int ec = LastError();
- UNREACHABLE_MSG("Unhandled host socket error={}", ec);
- return Errno::SUCCESS;
+ return GetAndLogLastError();
}
} // Anonymous namespace
@@ -308,14 +356,12 @@ NetworkInstance::~NetworkInstance() {
std::pair<IPv4Address, Errno> GetHostIPv4Address() {
std::array<char, 256> name{};
if (gethostname(name.data(), static_cast<int>(name.size()) - 1) == SOCKET_ERROR) {
- UNIMPLEMENTED_MSG("Unhandled gethostname error");
- return {IPv4Address{}, Errno::SUCCESS};
+ return {IPv4Address{}, GetAndLogLastError()};
}
hostent* const ent = gethostbyname(name.data());
if (!ent) {
- UNIMPLEMENTED_MSG("Unhandled gethostbyname error");
- return {IPv4Address{}, Errno::SUCCESS};
+ return {IPv4Address{}, GetAndLogLastError()};
}
if (ent->h_addr_list == nullptr) {
UNIMPLEMENTED_MSG("No addr provided in hostent->h_addr_list");
@@ -359,9 +405,7 @@ std::pair<s32, Errno> Poll(std::vector<PollFD>& pollfds, s32 timeout) {
ASSERT(result == SOCKET_ERROR);
- const int ec = LastError();
- UNREACHABLE_MSG("Unhandled host socket error={}", ec);
- return {-1, Errno::SUCCESS};
+ return {-1, GetAndLogLastError()};
}
Socket::~Socket() {
@@ -380,9 +424,7 @@ Errno Socket::Initialize(Domain domain, Type type, Protocol protocol) {
return Errno::SUCCESS;
}
- const int ec = LastError();
- UNREACHABLE_MSG("Unhandled host socket error={}", ec);
- return Errno::SUCCESS;
+ return GetAndLogLastError();
}
std::pair<Socket::AcceptResult, Errno> Socket::Accept() {
@@ -391,9 +433,7 @@ std::pair<Socket::AcceptResult, Errno> Socket::Accept() {
const SOCKET new_socket = accept(fd, &addr, &addrlen);
if (new_socket == INVALID_SOCKET) {
- const int ec = LastError();
- UNREACHABLE_MSG("Unhandled host socket error={}", ec);
- return {AcceptResult{}, Errno::SUCCESS};
+ return {AcceptResult{}, GetAndLogLastError()};
}
AcceptResult result;
@@ -412,23 +452,14 @@ Errno Socket::Connect(SockAddrIn addr_in) {
return Errno::SUCCESS;
}
- switch (const int ec = LastError()) {
- case WSAEWOULDBLOCK:
- LOG_DEBUG(Service, "EAGAIN generated");
- return Errno::AGAIN;
- default:
- UNREACHABLE_MSG("Unhandled host socket error={}", ec);
- return Errno::SUCCESS;
- }
+ return GetAndLogLastError();
}
std::pair<SockAddrIn, Errno> Socket::GetPeerName() {
sockaddr addr;
socklen_t addrlen = sizeof(addr);
if (getpeername(fd, &addr, &addrlen) == SOCKET_ERROR) {
- const int ec = LastError();
- UNREACHABLE_MSG("Unhandled host socket error={}", ec);
- return {SockAddrIn{}, Errno::SUCCESS};
+ return {SockAddrIn{}, GetAndLogLastError()};
}
ASSERT(addrlen == sizeof(sockaddr_in));
@@ -439,9 +470,7 @@ std::pair<SockAddrIn, Errno> Socket::GetSockName() {
sockaddr addr;
socklen_t addrlen = sizeof(addr);
if (getsockname(fd, &addr, &addrlen) == SOCKET_ERROR) {
- const int ec = LastError();
- UNREACHABLE_MSG("Unhandled host socket error={}", ec);
- return {SockAddrIn{}, Errno::SUCCESS};
+ return {SockAddrIn{}, GetAndLogLastError()};
}
ASSERT(addrlen == sizeof(sockaddr_in));
@@ -454,9 +483,7 @@ Errno Socket::Bind(SockAddrIn addr) {
return Errno::SUCCESS;
}
- const int ec = LastError();
- UNREACHABLE_MSG("Unhandled host socket error={}", ec);
- return Errno::SUCCESS;
+ return GetAndLogLastError();
}
Errno Socket::Listen(s32 backlog) {
@@ -464,9 +491,7 @@ Errno Socket::Listen(s32 backlog) {
return Errno::SUCCESS;
}
- const int ec = LastError();
- UNREACHABLE_MSG("Unhandled host socket error={}", ec);
- return Errno::SUCCESS;
+ return GetAndLogLastError();
}
Errno Socket::Shutdown(ShutdownHow how) {
@@ -489,14 +514,7 @@ Errno Socket::Shutdown(ShutdownHow how) {
return Errno::SUCCESS;
}
- switch (const int ec = LastError()) {
- case WSAENOTCONN:
- LOG_ERROR(Service, "ENOTCONN generated");
- return Errno::NOTCONN;
- default:
- UNREACHABLE_MSG("Unhandled host socket error={}", ec);
- return Errno::SUCCESS;
- }
+ return GetAndLogLastError();
}
std::pair<s32, Errno> Socket::Recv(int flags, std::vector<u8>& message) {
@@ -509,17 +527,7 @@ std::pair<s32, Errno> Socket::Recv(int flags, std::vector<u8>& message) {
return {static_cast<s32>(result), Errno::SUCCESS};
}
- switch (const int ec = LastError()) {
- case WSAEWOULDBLOCK:
- LOG_DEBUG(Service, "EAGAIN generated");
- return {-1, Errno::AGAIN};
- case WSAENOTCONN:
- LOG_ERROR(Service, "ENOTCONN generated");
- return {-1, Errno::NOTCONN};
- default:
- UNREACHABLE_MSG("Unhandled host socket error={}", ec);
- return {0, Errno::SUCCESS};
- }
+ return {-1, GetAndLogLastError()};
}
std::pair<s32, Errno> Socket::RecvFrom(int flags, std::vector<u8>& message, SockAddrIn* addr) {
@@ -541,17 +549,7 @@ std::pair<s32, Errno> Socket::RecvFrom(int flags, std::vector<u8>& message, Sock
return {static_cast<s32>(result), Errno::SUCCESS};
}
- switch (const int ec = LastError()) {
- case WSAEWOULDBLOCK:
- LOG_DEBUG(Service, "EAGAIN generated");
- return {-1, Errno::AGAIN};
- case WSAENOTCONN:
- LOG_ERROR(Service, "ENOTCONN generated");
- return {-1, Errno::NOTCONN};
- default:
- UNREACHABLE_MSG("Unhandled host socket error={}", ec);
- return {-1, Errno::SUCCESS};
- }
+ return {-1, GetAndLogLastError()};
}
std::pair<s32, Errno> Socket::Send(const std::vector<u8>& message, int flags) {
@@ -564,18 +562,7 @@ std::pair<s32, Errno> Socket::Send(const std::vector<u8>& message, int flags) {
return {static_cast<s32>(result), Errno::SUCCESS};
}
- const int ec = LastError();
- switch (ec) {
- case WSAEWOULDBLOCK:
- LOG_DEBUG(Service, "EAGAIN generated");
- return {-1, Errno::AGAIN};
- case WSAENOTCONN:
- LOG_ERROR(Service, "ENOTCONN generated");
- return {-1, Errno::NOTCONN};
- default:
- UNREACHABLE_MSG("Unhandled host socket error={}", ec);
- return {-1, Errno::SUCCESS};
- }
+ return {-1, GetAndLogLastError()};
}
std::pair<s32, Errno> Socket::SendTo(u32 flags, const std::vector<u8>& message,
@@ -597,9 +584,7 @@ std::pair<s32, Errno> Socket::SendTo(u32 flags, const std::vector<u8>& message,
return {static_cast<s32>(result), Errno::SUCCESS};
}
- const int ec = LastError();
- UNREACHABLE_MSG("Unhandled host socket error={}", ec);
- return {-1, Errno::SUCCESS};
+ return {-1, GetAndLogLastError()};
}
Errno Socket::Close() {
@@ -642,9 +627,7 @@ Errno Socket::SetNonBlock(bool enable) {
if (EnableNonBlock(fd, enable)) {
return Errno::SUCCESS;
}
- const int ec = LastError();
- UNREACHABLE_MSG("Unhandled host socket error={}", ec);
- return Errno::SUCCESS;
+ return GetAndLogLastError();
}
bool Socket::IsOpened() const {
diff --git a/src/core/network/network.h b/src/core/network/network.h
index 76b2821f2..bd30f1899 100644
--- a/src/core/network/network.h
+++ b/src/core/network/network.h
@@ -7,6 +7,7 @@
#include <array>
#include <utility>
+#include "common/common_funcs.h"
#include "common/common_types.h"
namespace Network {
@@ -21,6 +22,11 @@ enum class Errno {
MFILE,
NOTCONN,
AGAIN,
+ CONNREFUSED,
+ HOSTUNREACH,
+ NETDOWN,
+ NETUNREACH,
+ OTHER,
};
/// Address families
diff --git a/src/input_common/mouse/mouse_input.cpp b/src/input_common/mouse/mouse_input.cpp
index b864d26f2..d81e790ee 100644
--- a/src/input_common/mouse/mouse_input.cpp
+++ b/src/input_common/mouse/mouse_input.cpp
@@ -59,7 +59,7 @@ void Mouse::UpdateYuzuSettings() {
});
}
-void Mouse::PressButton(int x, int y, int button_) {
+void Mouse::PressButton(int x, int y, MouseButton button_) {
const auto button_index = static_cast<std::size_t>(button_);
if (button_index >= mouse_info.size()) {
return;
@@ -67,7 +67,7 @@ void Mouse::PressButton(int x, int y, int button_) {
const auto button = 1U << button_index;
buttons |= static_cast<u16>(button);
- last_button = static_cast<MouseButton>(button_index);
+ last_button = button_;
mouse_info[button_index].mouse_origin = Common::MakeVec(x, y);
mouse_info[button_index].last_mouse_position = Common::MakeVec(x, y);
@@ -129,7 +129,7 @@ void Mouse::MouseMove(int x, int y, int center_x, int center_y) {
}
}
-void Mouse::ReleaseButton(int button_) {
+void Mouse::ReleaseButton(MouseButton button_) {
const auto button_index = static_cast<std::size_t>(button_);
if (button_index >= mouse_info.size()) {
return;
@@ -152,6 +152,11 @@ void Mouse::BeginConfiguration() {
void Mouse::EndConfiguration() {
buttons = 0;
+ for (MouseInfo& info : mouse_info) {
+ info.tilt_speed = 0;
+ info.data.pressed = false;
+ info.data.axis = {0, 0};
+ }
last_button = MouseButton::Undefined;
mouse_queue.Clear();
configuring = false;
diff --git a/src/input_common/mouse/mouse_input.h b/src/input_common/mouse/mouse_input.h
index 46aa676c1..3622fe080 100644
--- a/src/input_common/mouse/mouse_input.h
+++ b/src/input_common/mouse/mouse_input.h
@@ -18,10 +18,12 @@ namespace MouseInput {
enum class MouseButton {
Left,
- Wheel,
Right,
- Forward,
+ Wheel,
Backward,
+ Forward,
+ Task,
+ Extra,
Undefined,
};
@@ -51,7 +53,7 @@ public:
* @param y the y-coordinate of the cursor
* @param button_ the button pressed
*/
- void PressButton(int x, int y, int button_);
+ void PressButton(int x, int y, MouseButton button_);
/**
* Signals that mouse has moved.
@@ -65,7 +67,7 @@ public:
/**
* Signals that a motion sensor tilt has ended.
*/
- void ReleaseButton(int button_);
+ void ReleaseButton(MouseButton button_);
[[nodiscard]] Common::SPSCQueue<MouseStatus>& GetMouseQueue();
[[nodiscard]] const Common::SPSCQueue<MouseStatus>& GetMouseQueue() const;
@@ -94,7 +96,7 @@ private:
u16 buttons{};
std::thread update_thread;
MouseButton last_button{MouseButton::Undefined};
- std::array<MouseInfo, 5> mouse_info;
+ std::array<MouseInfo, 7> mouse_info;
Common::SPSCQueue<MouseStatus> mouse_queue;
bool configuring{false};
bool update_thread_running{true};
diff --git a/src/input_common/udp/client.cpp b/src/input_common/udp/client.cpp
index c4afa4174..df73f9ff7 100644
--- a/src/input_common/udp/client.cpp
+++ b/src/input_common/udp/client.cpp
@@ -5,6 +5,7 @@
#include <chrono>
#include <cstring>
#include <functional>
+#include <random>
#include <thread>
#include <boost/asio.hpp>
#include "common/logging/log.h"
@@ -26,10 +27,10 @@ class Socket {
public:
using clock = std::chrono::system_clock;
- explicit Socket(const std::string& host, u16 port, std::size_t pad_index_, u32 client_id_,
+ explicit Socket(const std::string& host, u16 port, std::size_t pad_index_,
SocketCallback callback_)
: callback(std::move(callback_)), timer(io_service),
- socket(io_service, udp::endpoint(udp::v4(), 0)), client_id(client_id_),
+ socket(io_service, udp::endpoint(udp::v4(), 0)), client_id(GenerateRandomClientId()),
pad_index(pad_index_) {
boost::system::error_code ec{};
auto ipv4 = boost::asio::ip::make_address_v4(host, ec);
@@ -63,6 +64,11 @@ public:
}
private:
+ u32 GenerateRandomClientId() const {
+ std::random_device device;
+ return device();
+ }
+
void HandleReceive(const boost::system::error_code&, std::size_t bytes_transferred) {
if (auto type = Response::Validate(receive_buffer.data(), bytes_transferred)) {
switch (*type) {
@@ -115,7 +121,7 @@ private:
boost::asio::basic_waitable_timer<clock> timer;
udp::socket socket;
- u32 client_id{};
+ const u32 client_id;
std::size_t pad_index{};
static constexpr std::size_t PORT_INFO_SIZE = sizeof(Message<Request::PortInfo>);
@@ -203,7 +209,7 @@ void Client::ReloadSockets() {
LOG_ERROR(Input, "Duplicated UDP servers found");
continue;
}
- StartCommunication(client++, udp_input_address, udp_input_port, pad, 24872);
+ StartCommunication(client++, udp_input_address, udp_input_port, pad);
}
}
}
@@ -277,7 +283,7 @@ void Client::OnPadData(Response::PadData data, std::size_t client) {
}
void Client::StartCommunication(std::size_t client, const std::string& host, u16 port,
- std::size_t pad_index, u32 client_id) {
+ std::size_t pad_index) {
SocketCallback callback{[this](Response::Version version) { OnVersion(version); },
[this](Response::PortInfo info) { OnPortInfo(info); },
[this, client](Response::PadData data) { OnPadData(data, client); }};
@@ -287,7 +293,7 @@ void Client::StartCommunication(std::size_t client, const std::string& host, u16
clients[client].port = port;
clients[client].pad_index = pad_index;
clients[client].active = 0;
- clients[client].socket = std::make_unique<Socket>(host, port, pad_index, client_id, callback);
+ clients[client].socket = std::make_unique<Socket>(host, port, pad_index, callback);
clients[client].thread = std::thread{SocketLoop, clients[client].socket.get()};
// Set motion parameters
// SetGyroThreshold value should be dependent on GyroscopeZeroDriftMode
@@ -416,7 +422,7 @@ const Common::SPSCQueue<UDPPadStatus>& Client::GetPadQueue() const {
return pad_queue;
}
-void TestCommunication(const std::string& host, u16 port, std::size_t pad_index, u32 client_id,
+void TestCommunication(const std::string& host, u16 port, std::size_t pad_index,
const std::function<void()>& success_callback,
const std::function<void()>& failure_callback) {
std::thread([=] {
@@ -426,7 +432,7 @@ void TestCommunication(const std::string& host, u16 port, std::size_t pad_index,
.port_info = [](Response::PortInfo) {},
.pad_data = [&](Response::PadData) { success_event.Set(); },
};
- Socket socket{host, port, pad_index, client_id, std::move(callback)};
+ Socket socket{host, port, pad_index, std::move(callback)};
std::thread worker_thread{SocketLoop, &socket};
const bool result = success_event.WaitFor(std::chrono::seconds(5));
socket.Stop();
@@ -440,7 +446,7 @@ void TestCommunication(const std::string& host, u16 port, std::size_t pad_index,
}
CalibrationConfigurationJob::CalibrationConfigurationJob(
- const std::string& host, u16 port, std::size_t pad_index, u32 client_id,
+ const std::string& host, u16 port, std::size_t pad_index,
std::function<void(Status)> status_callback,
std::function<void(u16, u16, u16, u16)> data_callback) {
@@ -485,7 +491,7 @@ CalibrationConfigurationJob::CalibrationConfigurationJob(
complete_event.Set();
}
}};
- Socket socket{host, port, pad_index, client_id, std::move(callback)};
+ Socket socket{host, port, pad_index, std::move(callback)};
std::thread worker_thread{SocketLoop, &socket};
complete_event.Wait();
socket.Stop();
diff --git a/src/input_common/udp/client.h b/src/input_common/udp/client.h
index a523f6124..e9e438e88 100644
--- a/src/input_common/udp/client.h
+++ b/src/input_common/udp/client.h
@@ -126,7 +126,7 @@ private:
void OnPortInfo(Response::PortInfo);
void OnPadData(Response::PadData, std::size_t client);
void StartCommunication(std::size_t client, const std::string& host, u16 port,
- std::size_t pad_index, u32 client_id);
+ std::size_t pad_index);
void UpdateYuzuSettings(std::size_t client, const Common::Vec3<float>& acc,
const Common::Vec3<float>& gyro);
@@ -165,7 +165,7 @@ public:
* @param data_callback Called when calibration data is ready
*/
explicit CalibrationConfigurationJob(const std::string& host, u16 port, std::size_t pad_index,
- u32 client_id, std::function<void(Status)> status_callback,
+ std::function<void(Status)> status_callback,
std::function<void(u16, u16, u16, u16)> data_callback);
~CalibrationConfigurationJob();
void Stop();
@@ -174,7 +174,7 @@ private:
Common::Event complete_event;
};
-void TestCommunication(const std::string& host, u16 port, std::size_t pad_index, u32 client_id,
+void TestCommunication(const std::string& host, u16 port, std::size_t pad_index,
const std::function<void()>& success_callback,
const std::function<void()>& failure_callback);
diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt
index 4ea0076e9..d875c4fee 100644
--- a/src/tests/CMakeLists.txt
+++ b/src/tests/CMakeLists.txt
@@ -5,6 +5,7 @@ add_executable(tests
common/param_package.cpp
common/ring_buffer.cpp
core/core_timing.cpp
+ core/network/network.cpp
tests.cpp
video_core/buffer_base.cpp
)
diff --git a/src/tests/common/fibers.cpp b/src/tests/common/fibers.cpp
index d94492fc6..751cbe196 100644
--- a/src/tests/common/fibers.cpp
+++ b/src/tests/common/fibers.cpp
@@ -67,7 +67,7 @@ void TestControl1::DoWork() {
value++;
}
results[id] = value;
- Fiber::YieldTo(work_fibers[id], thread_fibers[id]);
+ Fiber::YieldTo(work_fibers[id], *thread_fibers[id]);
}
void TestControl1::ExecuteThread(u32 id) {
@@ -76,7 +76,7 @@ void TestControl1::ExecuteThread(u32 id) {
thread_fibers[id] = thread_fiber;
work_fibers[id] = std::make_shared<Fiber>(std::function<void(void*)>{WorkControl1}, this);
items[id] = rand() % 256;
- Fiber::YieldTo(thread_fibers[id], work_fibers[id]);
+ Fiber::YieldTo(thread_fibers[id], *work_fibers[id]);
thread_fibers[id]->Exit();
}
@@ -117,11 +117,11 @@ public:
for (u32 i = 0; i < 12000; i++) {
value1 += i;
}
- Fiber::YieldTo(fiber1, fiber3);
+ Fiber::YieldTo(fiber1, *fiber3);
const u32 id = thread_ids.Get();
assert1 = id == 1;
value2 += 5000;
- Fiber::YieldTo(fiber1, thread_fibers[id]);
+ Fiber::YieldTo(fiber1, *thread_fibers[id]);
}
void DoWork2() {
@@ -129,7 +129,7 @@ public:
;
value2 = 2000;
trap = false;
- Fiber::YieldTo(fiber2, fiber1);
+ Fiber::YieldTo(fiber2, *fiber1);
assert3 = false;
}
@@ -137,19 +137,19 @@ public:
const u32 id = thread_ids.Get();
assert2 = id == 0;
value1 += 1000;
- Fiber::YieldTo(fiber3, thread_fibers[id]);
+ Fiber::YieldTo(fiber3, *thread_fibers[id]);
}
void ExecuteThread(u32 id);
void CallFiber1() {
const u32 id = thread_ids.Get();
- Fiber::YieldTo(thread_fibers[id], fiber1);
+ Fiber::YieldTo(thread_fibers[id], *fiber1);
}
void CallFiber2() {
const u32 id = thread_ids.Get();
- Fiber::YieldTo(thread_fibers[id], fiber2);
+ Fiber::YieldTo(thread_fibers[id], *fiber2);
}
void Exit();
@@ -241,23 +241,23 @@ public:
void DoWork1() {
value1 += 1;
- Fiber::YieldTo(fiber1, fiber2);
+ Fiber::YieldTo(fiber1, *fiber2);
const u32 id = thread_ids.Get();
value3 += 1;
- Fiber::YieldTo(fiber1, thread_fibers[id]);
+ Fiber::YieldTo(fiber1, *thread_fibers[id]);
}
void DoWork2() {
value2 += 1;
const u32 id = thread_ids.Get();
- Fiber::YieldTo(fiber2, thread_fibers[id]);
+ Fiber::YieldTo(fiber2, *thread_fibers[id]);
}
void ExecuteThread(u32 id);
void CallFiber1() {
const u32 id = thread_ids.Get();
- Fiber::YieldTo(thread_fibers[id], fiber1);
+ Fiber::YieldTo(thread_fibers[id], *fiber1);
}
void Exit();
@@ -332,7 +332,7 @@ public:
void Execute() {
thread_fiber = Fiber::ThreadToFiber();
- Fiber::YieldTo(thread_fiber, fiber1);
+ Fiber::YieldTo(thread_fiber, *fiber1);
thread_fiber->Exit();
}
@@ -340,7 +340,7 @@ public:
fiber1->SetRewindPoint(std::function<void(void*)>{WorkControl4}, this);
if (rewinded) {
goal_reached = true;
- Fiber::YieldTo(fiber1, thread_fiber);
+ Fiber::YieldTo(fiber1, *thread_fiber);
}
rewinded = true;
fiber1->Rewind();
diff --git a/src/tests/core/network/network.cpp b/src/tests/core/network/network.cpp
new file mode 100644
index 000000000..b21ad8911
--- /dev/null
+++ b/src/tests/core/network/network.cpp
@@ -0,0 +1,28 @@
+// Copyright 2021 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <catch2/catch.hpp>
+
+#include "core/network/network.h"
+#include "core/network/sockets.h"
+
+TEST_CASE("Network::Errors", "[core]") {
+ Network::NetworkInstance network_instance; // initialize network
+
+ Network::Socket socks[2];
+ for (Network::Socket& sock : socks) {
+ REQUIRE(sock.Initialize(Network::Domain::INET, Network::Type::STREAM,
+ Network::Protocol::TCP) == Network::Errno::SUCCESS);
+ }
+
+ Network::SockAddrIn addr{
+ Network::Domain::INET,
+ {127, 0, 0, 1},
+ 1, // hopefully nobody running this test has something listening on port 1
+ };
+ REQUIRE(socks[0].Connect(addr) == Network::Errno::CONNREFUSED);
+
+ std::vector<u8> message{1, 2, 3, 4};
+ REQUIRE(socks[1].Recv(0, message).second == Network::Errno::NOTCONN);
+}
diff --git a/src/video_core/renderer_vulkan/vk_command_pool.cpp b/src/video_core/renderer_vulkan/vk_command_pool.cpp
index a99df9323..d8e92ac0e 100644
--- a/src/video_core/renderer_vulkan/vk_command_pool.cpp
+++ b/src/video_core/renderer_vulkan/vk_command_pool.cpp
@@ -10,7 +10,7 @@
namespace Vulkan {
-constexpr size_t COMMAND_BUFFER_POOL_SIZE = 0x1000;
+constexpr size_t COMMAND_BUFFER_POOL_SIZE = 4;
struct CommandPool::Pool {
vk::CommandPool handle;
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index 1c61d419d..ae49cbb45 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -383,6 +383,25 @@ void GRenderWindow::keyReleaseEvent(QKeyEvent* event) {
input_subsystem->GetKeyboard()->ReleaseKey(event->key());
}
+MouseInput::MouseButton GRenderWindow::QtButtonToMouseButton(Qt::MouseButton button) {
+ switch (button) {
+ case Qt::LeftButton:
+ return MouseInput::MouseButton::Left;
+ case Qt::RightButton:
+ return MouseInput::MouseButton::Right;
+ case Qt::MiddleButton:
+ return MouseInput::MouseButton::Wheel;
+ case Qt::BackButton:
+ return MouseInput::MouseButton::Backward;
+ case Qt::ForwardButton:
+ return MouseInput::MouseButton::Forward;
+ case Qt::TaskButton:
+ return MouseInput::MouseButton::Task;
+ default:
+ return MouseInput::MouseButton::Extra;
+ }
+}
+
void GRenderWindow::mousePressEvent(QMouseEvent* event) {
// Touch input is handled in TouchBeginEvent
if (event->source() == Qt::MouseEventSynthesizedBySystem) {
@@ -391,7 +410,8 @@ void GRenderWindow::mousePressEvent(QMouseEvent* event) {
auto pos = event->pos();
const auto [x, y] = ScaleTouch(pos);
- input_subsystem->GetMouse()->PressButton(x, y, event->button());
+ const auto button = QtButtonToMouseButton(event->button());
+ input_subsystem->GetMouse()->PressButton(x, y, button);
if (event->button() == Qt::LeftButton) {
this->TouchPressed(x, y, 0);
@@ -425,7 +445,8 @@ void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) {
return;
}
- input_subsystem->GetMouse()->ReleaseButton(event->button());
+ const auto button = QtButtonToMouseButton(event->button());
+ input_subsystem->GetMouse()->ReleaseButton(button);
if (event->button() == Qt::LeftButton) {
this->TouchReleased(0);
diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h
index b5ec7de07..acfe2bc8c 100644
--- a/src/yuzu/bootmanager.h
+++ b/src/yuzu/bootmanager.h
@@ -28,6 +28,10 @@ namespace InputCommon {
class InputSubsystem;
}
+namespace MouseInput {
+enum class MouseButton;
+}
+
namespace VideoCore {
enum class LoadCallbackStage;
}
@@ -149,6 +153,9 @@ public:
void keyPressEvent(QKeyEvent* event) override;
void keyReleaseEvent(QKeyEvent* event) override;
+ /// Converts a Qt mouse button into MouseInput mouse button
+ static MouseInput::MouseButton QtButtonToMouseButton(Qt::MouseButton button);
+
void mousePressEvent(QMouseEvent* event) override;
void mouseMoveEvent(QMouseEvent* event) override;
void mouseReleaseEvent(QMouseEvent* event) override;
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 3d6f64300..1bac57bb2 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -235,7 +235,7 @@ const std::array<UISettings::Shortcut, 17> Config::default_hotkeys{{
{QStringLiteral("Restart Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F6"), Qt::WindowShortcut}},
{QStringLiteral("Stop Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F5"), Qt::WindowShortcut}},
{QStringLiteral("Toggle Filter Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F"), Qt::WindowShortcut}},
- {QStringLiteral("Toggle Mouse Panning"), QStringLiteral("Main Window"), {QStringLiteral("F9"), Qt::ApplicationShortcut}},
+ {QStringLiteral("Toggle Mouse Panning"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F9"), Qt::ApplicationShortcut}},
{QStringLiteral("Toggle Speed Limit"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+Z"), Qt::ApplicationShortcut}},
{QStringLiteral("Toggle Status Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+S"), Qt::WindowShortcut}},
}};
@@ -508,7 +508,7 @@ void Config::ReadControlValues() {
Settings::values.emulate_analog_keyboard =
ReadSetting(QStringLiteral("emulate_analog_keyboard"), false).toBool();
- Settings::values.mouse_panning = ReadSetting(QStringLiteral("mouse_panning"), false).toBool();
+ Settings::values.mouse_panning = false;
Settings::values.mouse_panning_sensitivity =
ReadSetting(QStringLiteral("mouse_panning_sensitivity"), 1).toFloat();
@@ -648,7 +648,7 @@ void Config::ReadDebuggingValues() {
void Config::ReadServiceValues() {
qt_config->beginGroup(QStringLiteral("Services"));
Settings::values.bcat_backend =
- ReadSetting(QStringLiteral("bcat_backend"), QStringLiteral("null"))
+ ReadSetting(QStringLiteral("bcat_backend"), QStringLiteral("none"))
.toString()
.toStdString();
Settings::values.bcat_boxcat_local =
@@ -1182,7 +1182,6 @@ void Config::SaveControlValues() {
WriteSetting(QStringLiteral("keyboard_enabled"), Settings::values.keyboard_enabled, false);
WriteSetting(QStringLiteral("emulate_analog_keyboard"),
Settings::values.emulate_analog_keyboard, false);
- WriteSetting(QStringLiteral("mouse_panning"), Settings::values.mouse_panning, false);
WriteSetting(QStringLiteral("mouse_panning_sensitivity"),
Settings::values.mouse_panning_sensitivity, 1.0f);
qt_config->endGroup();
@@ -1239,7 +1238,7 @@ void Config::SaveDebuggingValues() {
void Config::SaveServiceValues() {
qt_config->beginGroup(QStringLiteral("Services"));
WriteSetting(QStringLiteral("bcat_backend"),
- QString::fromStdString(Settings::values.bcat_backend), QStringLiteral("null"));
+ QString::fromStdString(Settings::values.bcat_backend), QStringLiteral("none"));
WriteSetting(QStringLiteral("bcat_boxcat_local"), Settings::values.bcat_boxcat_local, false);
qt_config->endGroup();
}
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index 21d0d3449..bc572d319 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -21,6 +21,7 @@
#include "input_common/mouse/mouse_poller.h"
#include "input_common/udp/udp.h"
#include "ui_configure_input_player.h"
+#include "yuzu/bootmanager.h"
#include "yuzu/configuration/config.h"
#include "yuzu/configuration/configure_input_player.h"
#include "yuzu/configuration/configure_input_player_widget.h"
@@ -1345,7 +1346,8 @@ void ConfigureInputPlayer::mousePressEvent(QMouseEvent* event) {
return;
}
- input_subsystem->GetMouse()->PressButton(0, 0, event->button());
+ const auto button = GRenderWindow::QtButtonToMouseButton(event->button());
+ input_subsystem->GetMouse()->PressButton(0, 0, button);
}
void ConfigureInputPlayer::keyPressEvent(QKeyEvent* event) {
diff --git a/src/yuzu/configuration/configure_motion_touch.cpp b/src/yuzu/configuration/configure_motion_touch.cpp
index 1f2b792e4..52fdf7265 100644
--- a/src/yuzu/configuration/configure_motion_touch.cpp
+++ b/src/yuzu/configuration/configure_motion_touch.cpp
@@ -24,7 +24,7 @@
CalibrationConfigurationDialog::CalibrationConfigurationDialog(QWidget* parent,
const std::string& host, u16 port,
- u8 pad_index, u16 client_id)
+ u8 pad_index)
: QDialog(parent) {
layout = new QVBoxLayout;
status_label = new QLabel(tr("Communicating with the server..."));
@@ -41,7 +41,7 @@ CalibrationConfigurationDialog::CalibrationConfigurationDialog(QWidget* parent,
using namespace InputCommon::CemuhookUDP;
job = std::make_unique<CalibrationConfigurationJob>(
- host, port, pad_index, client_id,
+ host, port, pad_index,
[this](CalibrationConfigurationJob::Status status) {
QString text;
switch (status) {
@@ -218,7 +218,6 @@ void ConfigureMotionTouch::OnCemuhookUDPTest() {
udp_test_in_progress = true;
InputCommon::CemuhookUDP::TestCommunication(
ui->udp_server->text().toStdString(), static_cast<u16>(ui->udp_port->text().toInt()), 0,
- 24872,
[this] {
LOG_INFO(Frontend, "UDP input test success");
QMetaObject::invokeMethod(this, "ShowUDPTestResult", Q_ARG(bool, true));
@@ -233,8 +232,7 @@ void ConfigureMotionTouch::OnConfigureTouchCalibration() {
ui->touch_calibration_config->setEnabled(false);
ui->touch_calibration_config->setText(tr("Configuring"));
CalibrationConfigurationDialog dialog(this, ui->udp_server->text().toStdString(),
- static_cast<u16>(ui->udp_port->text().toUInt()), 0,
- 24872);
+ static_cast<u16>(ui->udp_port->text().toUInt()), 0);
dialog.exec();
if (dialog.completed) {
min_x = dialog.min_x;
diff --git a/src/yuzu/configuration/configure_motion_touch.h b/src/yuzu/configuration/configure_motion_touch.h
index 15d61e8ba..d76bc8154 100644
--- a/src/yuzu/configuration/configure_motion_touch.h
+++ b/src/yuzu/configuration/configure_motion_touch.h
@@ -30,7 +30,7 @@ class CalibrationConfigurationDialog : public QDialog {
Q_OBJECT
public:
explicit CalibrationConfigurationDialog(QWidget* parent, const std::string& host, u16 port,
- u8 pad_index, u16 client_id);
+ u8 pad_index);
~CalibrationConfigurationDialog() override;
private:
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 0ba7c07cc..56d892a31 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -854,8 +854,7 @@ void GMainWindow::InitializeHotkeys() {
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Mouse Panning"), this),
&QShortcut::activated, this, [&] {
Settings::values.mouse_panning = !Settings::values.mouse_panning;
- if (UISettings::values.hide_mouse || Settings::values.mouse_panning) {
- mouse_hide_timer.start();
+ if (Settings::values.mouse_panning) {
render_window->installEventFilter(render_window);
render_window->setAttribute(Qt::WA_Hover, true);
}
@@ -1208,11 +1207,14 @@ void GMainWindow::BootGame(const QString& filename, std::size_t program_index) {
renderer_status_button->setDisabled(true);
if (UISettings::values.hide_mouse || Settings::values.mouse_panning) {
- mouse_hide_timer.start();
render_window->installEventFilter(render_window);
render_window->setAttribute(Qt::WA_Hover, true);
}
+ if (UISettings::values.hide_mouse) {
+ mouse_hide_timer.start();
+ }
+
std::string title_name;
std::string title_version;
const auto res = system.GetGameName(title_name);
@@ -2372,12 +2374,15 @@ void GMainWindow::OnConfigure() {
if ((UISettings::values.hide_mouse || Settings::values.mouse_panning) && emulation_running) {
render_window->installEventFilter(render_window);
render_window->setAttribute(Qt::WA_Hover, true);
- mouse_hide_timer.start();
} else {
render_window->removeEventFilter(render_window);
render_window->setAttribute(Qt::WA_Hover, false);
}
+ if (UISettings::values.hide_mouse) {
+ mouse_hide_timer.start();
+ }
+
UpdateStatusButtons();
}
@@ -2615,8 +2620,7 @@ void GMainWindow::UpdateUISettings() {
}
void GMainWindow::HideMouseCursor() {
- if (emu_thread == nullptr ||
- (!UISettings::values.hide_mouse && !Settings::values.mouse_panning)) {
+ if (emu_thread == nullptr && UISettings::values.hide_mouse) {
mouse_hide_timer.stop();
ShowMouseCursor();
return;
@@ -2626,8 +2630,7 @@ void GMainWindow::HideMouseCursor() {
void GMainWindow::ShowMouseCursor() {
render_window->unsetCursor();
- if (emu_thread != nullptr &&
- (UISettings::values.hide_mouse || Settings::values.mouse_panning)) {
+ if (emu_thread != nullptr && UISettings::values.hide_mouse) {
mouse_hide_timer.start();
}
}
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index 6d8bc5509..43877fc98 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -457,7 +457,7 @@ void Config::ReadValues() {
Settings::values.yuzu_token = sdl2_config->Get("WebService", "yuzu_token", "");
// Services
- Settings::values.bcat_backend = sdl2_config->Get("Services", "bcat_backend", "null");
+ Settings::values.bcat_backend = sdl2_config->Get("Services", "bcat_backend", "none");
Settings::values.bcat_boxcat_local =
sdl2_config->GetBoolean("Services", "bcat_boxcat_local", false);
}
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
index 7e391ab89..ce8b7c218 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
@@ -35,18 +35,36 @@ void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) {
input_subsystem->GetMouse()->MouseMove(x, y, 0, 0);
}
+MouseInput::MouseButton EmuWindow_SDL2::SDLButtonToMouseButton(u32 button) const {
+ switch (button) {
+ case SDL_BUTTON_LEFT:
+ return MouseInput::MouseButton::Left;
+ case SDL_BUTTON_RIGHT:
+ return MouseInput::MouseButton::Right;
+ case SDL_BUTTON_MIDDLE:
+ return MouseInput::MouseButton::Wheel;
+ case SDL_BUTTON_X1:
+ return MouseInput::MouseButton::Backward;
+ case SDL_BUTTON_X2:
+ return MouseInput::MouseButton::Forward;
+ default:
+ return MouseInput::MouseButton::Undefined;
+ }
+}
+
void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) {
+ const auto mouse_button = SDLButtonToMouseButton(button);
if (button == SDL_BUTTON_LEFT) {
if (state == SDL_PRESSED) {
TouchPressed((unsigned)std::max(x, 0), (unsigned)std::max(y, 0), 0);
} else {
TouchReleased(0);
}
- } else if (button == SDL_BUTTON_RIGHT) {
+ } else {
if (state == SDL_PRESSED) {
- input_subsystem->GetMouse()->PressButton(x, y, button);
+ input_subsystem->GetMouse()->PressButton(x, y, mouse_button);
} else {
- input_subsystem->GetMouse()->ReleaseButton(button);
+ input_subsystem->GetMouse()->ReleaseButton(mouse_button);
}
}
}
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.h b/src/yuzu_cmd/emu_window/emu_window_sdl2.h
index 51a12a6a9..0e17bbca7 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2.h
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.h
@@ -18,6 +18,10 @@ namespace InputCommon {
class InputSubsystem;
}
+namespace MouseInput {
+enum class MouseButton;
+}
+
class EmuWindow_SDL2 : public Core::Frontend::EmuWindow {
public:
explicit EmuWindow_SDL2(InputCommon::InputSubsystem* input_subsystem);
@@ -42,6 +46,9 @@ protected:
/// Called by WaitEvent when the mouse moves.
void OnMouseMotion(s32 x, s32 y);
+ /// Converts a SDL mouse button into MouseInput mouse button
+ MouseInput::MouseButton SDLButtonToMouseButton(u32 button) const;
+
/// Called by WaitEvent when a mouse button is pressed or released
void OnMouseButton(u32 button, u8 state, s32 x, s32 y);