Compare commits
22 Commits
__refs_pul
...
__refs_pul
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
739a81055f | ||
|
|
673accd630 | ||
|
|
8f3e2a1b48 | ||
|
|
d482ec32a4 | ||
|
|
11f6bb1532 | ||
|
|
ba05301e1b | ||
|
|
5a657488e1 | ||
|
|
c9678bda24 | ||
|
|
83afc12475 | ||
|
|
d746cfc018 | ||
|
|
89221ca7d5 | ||
|
|
165ebbb63c | ||
|
|
898c5d35a5 | ||
|
|
a4d0663158 | ||
|
|
e531d1fae9 | ||
|
|
41183b622f | ||
|
|
1773a1039f | ||
|
|
17207939e5 | ||
|
|
57aaf00a0c | ||
|
|
5e746da981 | ||
|
|
505923f0f3 | ||
|
|
57a4388e2d |
@@ -241,7 +241,7 @@ endif()
|
||||
|
||||
if (ENABLE_WEB_SERVICE)
|
||||
find_package(cpp-jwt 1.4 CONFIG)
|
||||
find_package(httplib 0.11 MODULE)
|
||||
find_package(httplib 0.12 MODULE)
|
||||
endif()
|
||||
|
||||
if (YUZU_TESTS)
|
||||
|
||||
2
externals/cpp-httplib
vendored
2
externals/cpp-httplib
vendored
Submodule externals/cpp-httplib updated: 305a7abcb9...6d963fbe8d
@@ -225,6 +225,8 @@ add_library(core STATIC
|
||||
hle/kernel/k_memory_manager.h
|
||||
hle/kernel/k_memory_region.h
|
||||
hle/kernel/k_memory_region_type.h
|
||||
hle/kernel/k_object_name.cpp
|
||||
hle/kernel/k_object_name.h
|
||||
hle/kernel/k_page_bitmap.h
|
||||
hle/kernel/k_page_buffer.cpp
|
||||
hle/kernel/k_page_buffer.h
|
||||
|
||||
@@ -23,7 +23,8 @@ void EmulatedConsole::SetTouchParams() {
|
||||
|
||||
// We can't use mouse as touch if native mouse is enabled
|
||||
if (!Settings::values.mouse_enabled) {
|
||||
touch_params[index++] = Common::ParamPackage{"engine:mouse,axis_x:10,axis_y:11,button:0"};
|
||||
touch_params[index++] =
|
||||
Common::ParamPackage{"engine:mouse,axis_x:0,axis_y:1,button:0,port:2"};
|
||||
}
|
||||
|
||||
touch_params[index++] =
|
||||
|
||||
@@ -363,7 +363,17 @@ void EmulatedController::ReloadInput() {
|
||||
SetMotion(callback, index);
|
||||
},
|
||||
});
|
||||
motion_devices[index]->ForceUpdate();
|
||||
|
||||
// Restore motion state
|
||||
auto& emulated_motion = controller.motion_values[index].emulated;
|
||||
auto& motion = controller.motion_state[index];
|
||||
emulated_motion.ResetRotations();
|
||||
emulated_motion.ResetQuaternion();
|
||||
motion.accel = emulated_motion.GetAcceleration();
|
||||
motion.gyro = emulated_motion.GetGyroscope();
|
||||
motion.rotation = emulated_motion.GetRotations();
|
||||
motion.orientation = emulated_motion.GetOrientation();
|
||||
motion.is_at_rest = !emulated_motion.IsMoving(motion_sensitivity);
|
||||
}
|
||||
|
||||
for (std::size_t index = 0; index < camera_devices.size(); ++index) {
|
||||
|
||||
@@ -34,9 +34,12 @@ void EmulatedDevices::ReloadInput() {
|
||||
// First two axis are reserved for mouse position
|
||||
key_index = 2;
|
||||
for (auto& mouse_device : mouse_analog_devices) {
|
||||
// Mouse axis are only mapped on port 1, pad 0
|
||||
Common::ParamPackage mouse_params;
|
||||
mouse_params.Set("engine", "mouse");
|
||||
mouse_params.Set("axis", static_cast<int>(key_index));
|
||||
mouse_params.Set("port", 1);
|
||||
mouse_params.Set("pad", 0);
|
||||
mouse_device = Common::Input::CreateInputDevice(mouse_params);
|
||||
key_index++;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ MotionInput::MotionInput() {
|
||||
// Initialize PID constants with default values
|
||||
SetPID(0.3f, 0.005f, 0.0f);
|
||||
SetGyroThreshold(ThresholdStandard);
|
||||
ResetQuaternion();
|
||||
ResetRotations();
|
||||
}
|
||||
|
||||
void MotionInput::SetPID(f32 new_kp, f32 new_ki, f32 new_kd) {
|
||||
@@ -20,11 +22,19 @@ void MotionInput::SetPID(f32 new_kp, f32 new_ki, f32 new_kd) {
|
||||
|
||||
void MotionInput::SetAcceleration(const Common::Vec3f& acceleration) {
|
||||
accel = acceleration;
|
||||
|
||||
accel.x = std::clamp(accel.x, -AccelMaxValue, AccelMaxValue);
|
||||
accel.y = std::clamp(accel.y, -AccelMaxValue, AccelMaxValue);
|
||||
accel.z = std::clamp(accel.z, -AccelMaxValue, AccelMaxValue);
|
||||
}
|
||||
|
||||
void MotionInput::SetGyroscope(const Common::Vec3f& gyroscope) {
|
||||
gyro = gyroscope - gyro_bias;
|
||||
|
||||
gyro.x = std::clamp(gyro.x, -GyroMaxValue, GyroMaxValue);
|
||||
gyro.y = std::clamp(gyro.y, -GyroMaxValue, GyroMaxValue);
|
||||
gyro.z = std::clamp(gyro.z, -GyroMaxValue, GyroMaxValue);
|
||||
|
||||
// Auto adjust drift to minimize drift
|
||||
if (!IsMoving(IsAtRestRelaxed)) {
|
||||
gyro_bias = (gyro_bias * 0.9999f) + (gyroscope * 0.0001f);
|
||||
@@ -61,6 +71,10 @@ void MotionInput::ResetRotations() {
|
||||
rotations = {};
|
||||
}
|
||||
|
||||
void MotionInput::ResetQuaternion() {
|
||||
quat = {{0.0f, 0.0f, -1.0f}, 0.0f};
|
||||
}
|
||||
|
||||
bool MotionInput::IsMoving(f32 sensitivity) const {
|
||||
return gyro.Length() >= sensitivity || accel.Length() <= 0.9f || accel.Length() >= 1.1f;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,9 @@ public:
|
||||
static constexpr float IsAtRestStandard = 0.01f;
|
||||
static constexpr float IsAtRestThight = 0.005f;
|
||||
|
||||
static constexpr float GyroMaxValue = 5.0f;
|
||||
static constexpr float AccelMaxValue = 7.0f;
|
||||
|
||||
explicit MotionInput();
|
||||
|
||||
MotionInput(const MotionInput&) = default;
|
||||
@@ -40,6 +43,7 @@ public:
|
||||
|
||||
void EnableReset(bool reset);
|
||||
void ResetRotations();
|
||||
void ResetQuaternion();
|
||||
|
||||
void UpdateRotation(u64 elapsed_time);
|
||||
void UpdateOrientation(u64 elapsed_time);
|
||||
@@ -69,7 +73,7 @@ private:
|
||||
Common::Vec3f derivative_error;
|
||||
|
||||
// Quaternion containing the device orientation
|
||||
Common::Quaternion<f32> quat{{0.0f, 0.0f, -1.0f}, 0.0f};
|
||||
Common::Quaternion<f32> quat;
|
||||
|
||||
// Number of full rotations in each axis
|
||||
Common::Vec3f rotations;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "core/hle/kernel/k_event_info.h"
|
||||
#include "core/hle/kernel/k_memory_layout.h"
|
||||
#include "core/hle/kernel/k_memory_manager.h"
|
||||
#include "core/hle/kernel/k_object_name.h"
|
||||
#include "core/hle/kernel/k_page_buffer.h"
|
||||
#include "core/hle/kernel/k_port.h"
|
||||
#include "core/hle/kernel/k_process.h"
|
||||
@@ -49,6 +50,7 @@ namespace Kernel::Init {
|
||||
HANDLER(KThreadLocalPage, \
|
||||
(SLAB_COUNT(KProcess) + (SLAB_COUNT(KProcess) + SLAB_COUNT(KThread)) / 8), \
|
||||
##__VA_ARGS__) \
|
||||
HANDLER(KObjectName, (SLAB_COUNT(KObjectName)), ##__VA_ARGS__) \
|
||||
HANDLER(KResourceLimit, (SLAB_COUNT(KResourceLimit)), ##__VA_ARGS__) \
|
||||
HANDLER(KEventInfo, (SLAB_COUNT(KThread) + SLAB_COUNT(KDebug)), ##__VA_ARGS__) \
|
||||
HANDLER(KDebug, (SLAB_COUNT(KDebug)), ##__VA_ARGS__) \
|
||||
|
||||
102
src/core/hle/kernel/k_object_name.cpp
Normal file
102
src/core/hle/kernel/k_object_name.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "core/hle/kernel/k_object_name.h"
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
KObjectNameGlobalData::KObjectNameGlobalData(KernelCore& kernel) : m_object_list_lock{kernel} {}
|
||||
KObjectNameGlobalData::~KObjectNameGlobalData() = default;
|
||||
|
||||
void KObjectName::Initialize(KAutoObject* obj, const char* name) {
|
||||
// Set member variables.
|
||||
m_object = obj;
|
||||
std::strncpy(m_name.data(), name, sizeof(m_name) - 1);
|
||||
m_name[sizeof(m_name) - 1] = '\x00';
|
||||
|
||||
// Open a reference to the object we hold.
|
||||
m_object->Open();
|
||||
}
|
||||
|
||||
bool KObjectName::MatchesName(const char* name) const {
|
||||
return std::strncmp(m_name.data(), name, sizeof(m_name)) == 0;
|
||||
}
|
||||
|
||||
Result KObjectName::NewFromName(KernelCore& kernel, KAutoObject* obj, const char* name) {
|
||||
// Create a new object name.
|
||||
KObjectName* new_name = KObjectName::Allocate(kernel);
|
||||
R_UNLESS(new_name != nullptr, ResultOutOfResource);
|
||||
|
||||
// Initialize the new name.
|
||||
new_name->Initialize(obj, name);
|
||||
|
||||
// Check if there's an existing name.
|
||||
{
|
||||
// Get the global data.
|
||||
KObjectNameGlobalData& gd{kernel.ObjectNameGlobalData()};
|
||||
|
||||
// Ensure we have exclusive access to the global list.
|
||||
KScopedLightLock lk{gd.GetObjectListLock()};
|
||||
|
||||
// If the object doesn't exist, put it into the list.
|
||||
KScopedAutoObject existing_object = FindImpl(kernel, name);
|
||||
if (existing_object.IsNull()) {
|
||||
gd.GetObjectList().push_back(*new_name);
|
||||
R_SUCCEED();
|
||||
}
|
||||
}
|
||||
|
||||
// The object already exists, which is an error condition. Perform cleanup.
|
||||
obj->Close();
|
||||
KObjectName::Free(kernel, new_name);
|
||||
R_THROW(ResultInvalidState);
|
||||
}
|
||||
|
||||
Result KObjectName::Delete(KernelCore& kernel, KAutoObject* obj, const char* compare_name) {
|
||||
// Get the global data.
|
||||
KObjectNameGlobalData& gd{kernel.ObjectNameGlobalData()};
|
||||
|
||||
// Ensure we have exclusive access to the global list.
|
||||
KScopedLightLock lk{gd.GetObjectListLock()};
|
||||
|
||||
// Find a matching entry in the list, and delete it.
|
||||
for (auto& name : gd.GetObjectList()) {
|
||||
if (name.MatchesName(compare_name) && obj == name.GetObject()) {
|
||||
// We found a match, clean up its resources.
|
||||
obj->Close();
|
||||
gd.GetObjectList().erase(gd.GetObjectList().iterator_to(name));
|
||||
KObjectName::Free(kernel, std::addressof(name));
|
||||
R_SUCCEED();
|
||||
}
|
||||
}
|
||||
|
||||
// We didn't find the object in the list.
|
||||
R_THROW(ResultNotFound);
|
||||
}
|
||||
|
||||
KScopedAutoObject<KAutoObject> KObjectName::Find(KernelCore& kernel, const char* name) {
|
||||
// Get the global data.
|
||||
KObjectNameGlobalData& gd{kernel.ObjectNameGlobalData()};
|
||||
|
||||
// Ensure we have exclusive access to the global list.
|
||||
KScopedLightLock lk{gd.GetObjectListLock()};
|
||||
|
||||
return FindImpl(kernel, name);
|
||||
}
|
||||
|
||||
KScopedAutoObject<KAutoObject> KObjectName::FindImpl(KernelCore& kernel, const char* compare_name) {
|
||||
// Get the global data.
|
||||
KObjectNameGlobalData& gd{kernel.ObjectNameGlobalData()};
|
||||
|
||||
// Try to find a matching object in the global list.
|
||||
for (const auto& name : gd.GetObjectList()) {
|
||||
if (name.MatchesName(compare_name)) {
|
||||
return name.GetObject();
|
||||
}
|
||||
}
|
||||
|
||||
// There's no matching entry in the list.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace Kernel
|
||||
86
src/core/hle/kernel/k_object_name.h
Normal file
86
src/core/hle/kernel/k_object_name.h
Normal file
@@ -0,0 +1,86 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <boost/intrusive/list.hpp>
|
||||
|
||||
#include "core/hle/kernel/k_light_lock.h"
|
||||
#include "core/hle/kernel/slab_helpers.h"
|
||||
#include "core/hle/kernel/svc_results.h"
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
class KObjectNameGlobalData;
|
||||
|
||||
class KObjectName : public KSlabAllocated<KObjectName>, public boost::intrusive::list_base_hook<> {
|
||||
public:
|
||||
explicit KObjectName(KernelCore&) {}
|
||||
virtual ~KObjectName() = default;
|
||||
|
||||
static constexpr size_t NameLengthMax = 12;
|
||||
using List = boost::intrusive::list<KObjectName>;
|
||||
|
||||
static Result NewFromName(KernelCore& kernel, KAutoObject* obj, const char* name);
|
||||
static Result Delete(KernelCore& kernel, KAutoObject* obj, const char* name);
|
||||
|
||||
static KScopedAutoObject<KAutoObject> Find(KernelCore& kernel, const char* name);
|
||||
|
||||
template <typename Derived>
|
||||
static Result Delete(KernelCore& kernel, const char* name) {
|
||||
// Find the object.
|
||||
KScopedAutoObject obj = Find(kernel, name);
|
||||
R_UNLESS(obj.IsNotNull(), ResultNotFound);
|
||||
|
||||
// Cast the object to the desired type.
|
||||
Derived* derived = obj->DynamicCast<Derived*>();
|
||||
R_UNLESS(derived != nullptr, ResultNotFound);
|
||||
|
||||
// Check that the object is closed.
|
||||
R_UNLESS(derived->IsServerClosed(), ResultInvalidState);
|
||||
|
||||
return Delete(kernel, obj.GetPointerUnsafe(), name);
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
requires(std::derived_from<Derived, KAutoObject>)
|
||||
static KScopedAutoObject<Derived> Find(KernelCore& kernel, const char* name) {
|
||||
return Find(kernel, name);
|
||||
}
|
||||
|
||||
private:
|
||||
static KScopedAutoObject<KAutoObject> FindImpl(KernelCore& kernel, const char* name);
|
||||
|
||||
void Initialize(KAutoObject* obj, const char* name);
|
||||
|
||||
bool MatchesName(const char* name) const;
|
||||
KAutoObject* GetObject() const {
|
||||
return m_object;
|
||||
}
|
||||
|
||||
private:
|
||||
std::array<char, NameLengthMax> m_name{};
|
||||
KAutoObject* m_object{};
|
||||
};
|
||||
|
||||
class KObjectNameGlobalData {
|
||||
public:
|
||||
explicit KObjectNameGlobalData(KernelCore& kernel);
|
||||
~KObjectNameGlobalData();
|
||||
|
||||
KLightLock& GetObjectListLock() {
|
||||
return m_object_list_lock;
|
||||
}
|
||||
|
||||
KObjectName::List& GetObjectList() {
|
||||
return m_object_list;
|
||||
}
|
||||
|
||||
private:
|
||||
KLightLock m_object_list_lock;
|
||||
KObjectName::List m_object_list;
|
||||
};
|
||||
|
||||
} // namespace Kernel
|
||||
@@ -29,6 +29,7 @@
|
||||
#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_object_name.h"
|
||||
#include "core/hle/kernel/k_page_buffer.h"
|
||||
#include "core/hle/kernel/k_process.h"
|
||||
#include "core/hle/kernel/k_resource_limit.h"
|
||||
@@ -84,6 +85,7 @@ struct KernelCore::Impl {
|
||||
InitializeShutdownThreads();
|
||||
InitializePhysicalCores();
|
||||
InitializePreemption(kernel);
|
||||
InitializeGlobalData(kernel);
|
||||
|
||||
// Initialize the Dynamic Slab Heaps.
|
||||
{
|
||||
@@ -194,6 +196,8 @@ struct KernelCore::Impl {
|
||||
}
|
||||
}
|
||||
|
||||
object_name_global_data.reset();
|
||||
|
||||
// Ensure that the object list container is finalized and properly shutdown.
|
||||
global_object_list_container->Finalize();
|
||||
global_object_list_container.reset();
|
||||
@@ -363,27 +367,29 @@ struct KernelCore::Impl {
|
||||
}
|
||||
}
|
||||
|
||||
void InitializeGlobalData(KernelCore& kernel) {
|
||||
object_name_global_data = std::make_unique<KObjectNameGlobalData>(kernel);
|
||||
}
|
||||
|
||||
void MakeApplicationProcess(KProcess* process) {
|
||||
application_process = process;
|
||||
}
|
||||
|
||||
static inline thread_local u32 host_thread_id = UINT32_MAX;
|
||||
static inline thread_local u8 host_thread_id = UINT8_MAX;
|
||||
|
||||
/// Gets the host thread ID for the caller, allocating a new one if this is the first time
|
||||
u32 GetHostThreadId(std::size_t core_id) {
|
||||
if (host_thread_id == UINT32_MAX) {
|
||||
// The first four slots are reserved for CPU core threads
|
||||
ASSERT(core_id < Core::Hardware::NUM_CPU_CORES);
|
||||
host_thread_id = static_cast<u32>(core_id);
|
||||
}
|
||||
/// Sets the host thread ID for the caller.
|
||||
u32 SetHostThreadId(std::size_t core_id) {
|
||||
// This should only be called during core init.
|
||||
ASSERT(host_thread_id == UINT8_MAX);
|
||||
|
||||
// The first four slots are reserved for CPU core threads
|
||||
ASSERT(core_id < Core::Hardware::NUM_CPU_CORES);
|
||||
host_thread_id = static_cast<u8>(core_id);
|
||||
return host_thread_id;
|
||||
}
|
||||
|
||||
/// Gets the host thread ID for the caller, allocating a new one if this is the first time
|
||||
u32 GetHostThreadId() {
|
||||
if (host_thread_id == UINT32_MAX) {
|
||||
host_thread_id = next_host_thread_id++;
|
||||
}
|
||||
/// Gets the host thread ID for the caller
|
||||
u32 GetHostThreadId() const {
|
||||
return host_thread_id;
|
||||
}
|
||||
|
||||
@@ -391,23 +397,19 @@ struct KernelCore::Impl {
|
||||
KThread* GetHostDummyThread(KThread* existing_thread) {
|
||||
auto initialize = [this](KThread* thread) {
|
||||
ASSERT(KThread::InitializeDummyThread(thread, nullptr).IsSuccess());
|
||||
thread->SetName(fmt::format("DummyThread:{}", GetHostThreadId()));
|
||||
thread->SetName(fmt::format("DummyThread:{}", next_host_thread_id++));
|
||||
return thread;
|
||||
};
|
||||
|
||||
thread_local KThread raw_thread{system.Kernel()};
|
||||
thread_local KThread* thread = nullptr;
|
||||
if (thread == nullptr) {
|
||||
thread = (existing_thread == nullptr) ? initialize(&raw_thread) : existing_thread;
|
||||
}
|
||||
|
||||
thread_local KThread* thread = existing_thread ? existing_thread : initialize(&raw_thread);
|
||||
return thread;
|
||||
}
|
||||
|
||||
/// Registers a CPU core thread by allocating a host thread ID for it
|
||||
void RegisterCoreThread(std::size_t core_id) {
|
||||
ASSERT(core_id < Core::Hardware::NUM_CPU_CORES);
|
||||
const auto this_id = GetHostThreadId(core_id);
|
||||
const auto this_id = SetHostThreadId(core_id);
|
||||
if (!is_multicore) {
|
||||
single_core_thread_id = this_id;
|
||||
}
|
||||
@@ -415,7 +417,6 @@ struct KernelCore::Impl {
|
||||
|
||||
/// Registers a new host thread by allocating a host thread ID for it
|
||||
void RegisterHostThread(KThread* existing_thread) {
|
||||
[[maybe_unused]] const auto this_id = GetHostThreadId();
|
||||
[[maybe_unused]] const auto dummy_thread = GetHostDummyThread(existing_thread);
|
||||
}
|
||||
|
||||
@@ -445,11 +446,9 @@ struct KernelCore::Impl {
|
||||
static inline thread_local KThread* current_thread{nullptr};
|
||||
|
||||
KThread* GetCurrentEmuThread() {
|
||||
const auto thread_id = GetCurrentHostThreadID();
|
||||
if (thread_id >= Core::Hardware::NUM_CPU_CORES) {
|
||||
return GetHostDummyThread(nullptr);
|
||||
if (!current_thread) {
|
||||
current_thread = GetHostDummyThread(nullptr);
|
||||
}
|
||||
|
||||
return current_thread;
|
||||
}
|
||||
|
||||
@@ -838,6 +837,8 @@ struct KernelCore::Impl {
|
||||
|
||||
std::unique_ptr<KAutoObjectWithListContainer> global_object_list_container;
|
||||
|
||||
std::unique_ptr<KObjectNameGlobalData> object_name_global_data;
|
||||
|
||||
/// Map of named ports managed by the kernel, which can be retrieved using
|
||||
/// the ConnectToPort SVC.
|
||||
std::unordered_map<std::string, ServiceInterfaceFactory> service_interface_factory;
|
||||
@@ -1002,7 +1003,7 @@ const Kernel::PhysicalCore& KernelCore::CurrentPhysicalCore() const {
|
||||
}
|
||||
|
||||
Kernel::KScheduler* KernelCore::CurrentScheduler() {
|
||||
u32 core_id = impl->GetCurrentHostThreadID();
|
||||
const u32 core_id = impl->GetCurrentHostThreadID();
|
||||
if (core_id >= Core::Hardware::NUM_CPU_CORES) {
|
||||
// This is expected when called from not a guest thread
|
||||
return {};
|
||||
@@ -1138,6 +1139,10 @@ void KernelCore::SetCurrentEmuThread(KThread* thread) {
|
||||
impl->SetCurrentEmuThread(thread);
|
||||
}
|
||||
|
||||
KObjectNameGlobalData& KernelCore::ObjectNameGlobalData() {
|
||||
return *impl->object_name_global_data;
|
||||
}
|
||||
|
||||
KMemoryManager& KernelCore::MemoryManager() {
|
||||
return *impl->memory_manager;
|
||||
}
|
||||
|
||||
@@ -44,6 +44,8 @@ class KHardwareTimer;
|
||||
class KLinkedListNode;
|
||||
class KMemoryLayout;
|
||||
class KMemoryManager;
|
||||
class KObjectName;
|
||||
class KObjectNameGlobalData;
|
||||
class KPageBuffer;
|
||||
class KPageBufferSlabHeap;
|
||||
class KPort;
|
||||
@@ -240,6 +242,9 @@ public:
|
||||
/// Register the current thread as a non CPU core thread.
|
||||
void RegisterHostThread(KThread* existing_thread = nullptr);
|
||||
|
||||
/// Gets global data for KObjectName.
|
||||
KObjectNameGlobalData& ObjectNameGlobalData();
|
||||
|
||||
/// Gets the virtual memory manager for the kernel.
|
||||
KMemoryManager& MemoryManager();
|
||||
|
||||
@@ -372,6 +377,8 @@ public:
|
||||
return slab_heap_container->page_buffer;
|
||||
} else if constexpr (std::is_same_v<T, KThreadLocalPage>) {
|
||||
return slab_heap_container->thread_local_page;
|
||||
} else if constexpr (std::is_same_v<T, KObjectName>) {
|
||||
return slab_heap_container->object_name;
|
||||
} else if constexpr (std::is_same_v<T, KSessionRequest>) {
|
||||
return slab_heap_container->session_request;
|
||||
} else if constexpr (std::is_same_v<T, KSecureSystemResource>) {
|
||||
@@ -443,6 +450,7 @@ private:
|
||||
KSlabHeap<KDeviceAddressSpace> device_address_space;
|
||||
KSlabHeap<KPageBuffer> page_buffer;
|
||||
KSlabHeap<KThreadLocalPage> thread_local_page;
|
||||
KSlabHeap<KObjectName> object_name;
|
||||
KSlabHeap<KSessionRequest> session_request;
|
||||
KSlabHeap<KSecureSystemResource> secure_system_resource;
|
||||
KSlabHeap<KEventInfo> event_info;
|
||||
|
||||
@@ -82,7 +82,7 @@ static_assert(sizeof(uint64_t) == 8);
|
||||
static void SvcWrap_SetHeapSize64From32(Core::System& system) {
|
||||
Result ret{};
|
||||
|
||||
uintptr_t out_address{};
|
||||
uint64_t out_address{};
|
||||
uint32_t size{};
|
||||
|
||||
size = Convert<uint32_t>(GetReg32(system, 1));
|
||||
@@ -729,7 +729,7 @@ static void SvcWrap_GetLastThreadInfo64From32(Core::System& system) {
|
||||
Result ret{};
|
||||
|
||||
ilp32::LastThreadContext out_context{};
|
||||
uintptr_t out_tls_address{};
|
||||
uint64_t out_tls_address{};
|
||||
uint32_t out_flags{};
|
||||
|
||||
ret = GetLastThreadInfo64From32(system, &out_context, &out_tls_address, &out_flags);
|
||||
@@ -1278,8 +1278,8 @@ static void SvcWrap_QueryPhysicalAddress64From32(Core::System& system) {
|
||||
static void SvcWrap_QueryIoMapping64From32(Core::System& system) {
|
||||
Result ret{};
|
||||
|
||||
uintptr_t out_address{};
|
||||
uintptr_t out_size{};
|
||||
uint64_t out_address{};
|
||||
uint64_t out_size{};
|
||||
uint64_t physical_address{};
|
||||
uint32_t size{};
|
||||
|
||||
@@ -2088,7 +2088,7 @@ static void SvcWrap_UnmapInsecureMemory64From32(Core::System& system) {
|
||||
static void SvcWrap_SetHeapSize64(Core::System& system) {
|
||||
Result ret{};
|
||||
|
||||
uintptr_t out_address{};
|
||||
uint64_t out_address{};
|
||||
uint64_t size{};
|
||||
|
||||
size = Convert<uint64_t>(GetReg64(system, 1));
|
||||
@@ -2705,7 +2705,7 @@ static void SvcWrap_GetLastThreadInfo64(Core::System& system) {
|
||||
Result ret{};
|
||||
|
||||
lp64::LastThreadContext out_context{};
|
||||
uintptr_t out_tls_address{};
|
||||
uint64_t out_tls_address{};
|
||||
uint32_t out_flags{};
|
||||
|
||||
ret = GetLastThreadInfo64(system, &out_context, &out_tls_address, &out_flags);
|
||||
@@ -3217,8 +3217,8 @@ static void SvcWrap_QueryPhysicalAddress64(Core::System& system) {
|
||||
static void SvcWrap_QueryIoMapping64(Core::System& system) {
|
||||
Result ret{};
|
||||
|
||||
uintptr_t out_address{};
|
||||
uintptr_t out_size{};
|
||||
uint64_t out_address{};
|
||||
uint64_t out_size{};
|
||||
uint64_t physical_address{};
|
||||
uint64_t size{};
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ class System;
|
||||
namespace Kernel::Svc {
|
||||
|
||||
// clang-format off
|
||||
Result SetHeapSize(Core::System& system, uintptr_t* out_address, uint64_t size);
|
||||
Result SetHeapSize(Core::System& system, uint64_t* out_address, uint64_t size);
|
||||
Result SetMemoryPermission(Core::System& system, uint64_t address, uint64_t size, MemoryPermission perm);
|
||||
Result SetMemoryAttribute(Core::System& system, uint64_t address, uint64_t size, uint32_t mask, uint32_t attr);
|
||||
Result MapMemory(Core::System& system, uint64_t dst_address, uint64_t src_address, uint64_t size);
|
||||
@@ -61,7 +61,7 @@ Result FlushDataCache(Core::System& system, uint64_t address, uint64_t size);
|
||||
Result MapPhysicalMemory(Core::System& system, uint64_t address, uint64_t size);
|
||||
Result UnmapPhysicalMemory(Core::System& system, uint64_t address, uint64_t size);
|
||||
Result GetDebugFutureThreadInfo(Core::System& system, lp64::LastThreadContext* out_context, uint64_t* out_thread_id, Handle debug_handle, int64_t ns);
|
||||
Result GetLastThreadInfo(Core::System& system, lp64::LastThreadContext* out_context, uintptr_t* out_tls_address, uint32_t* out_flags);
|
||||
Result GetLastThreadInfo(Core::System& system, lp64::LastThreadContext* out_context, uint64_t* out_tls_address, uint32_t* out_flags);
|
||||
Result GetResourceLimitLimitValue(Core::System& system, int64_t* out_limit_value, Handle resource_limit_handle, LimitableResource which);
|
||||
Result GetResourceLimitCurrentValue(Core::System& system, int64_t* out_current_value, Handle resource_limit_handle, LimitableResource which);
|
||||
Result SetThreadActivity(Core::System& system, Handle thread_handle, ThreadActivity thread_activity);
|
||||
@@ -94,7 +94,7 @@ Result MapTransferMemory(Core::System& system, Handle trmem_handle, uint64_t add
|
||||
Result UnmapTransferMemory(Core::System& system, Handle trmem_handle, uint64_t address, uint64_t size);
|
||||
Result CreateInterruptEvent(Core::System& system, Handle* out_read_handle, int32_t interrupt_id, InterruptType interrupt_type);
|
||||
Result QueryPhysicalAddress(Core::System& system, lp64::PhysicalMemoryInfo* out_info, uint64_t address);
|
||||
Result QueryIoMapping(Core::System& system, uintptr_t* out_address, uintptr_t* out_size, uint64_t physical_address, uint64_t size);
|
||||
Result QueryIoMapping(Core::System& system, uint64_t* out_address, uint64_t* out_size, uint64_t physical_address, uint64_t size);
|
||||
Result CreateDeviceAddressSpace(Core::System& system, Handle* out_handle, uint64_t das_address, uint64_t das_size);
|
||||
Result AttachDeviceAddressSpace(Core::System& system, DeviceName device_name, Handle das_handle);
|
||||
Result DetachDeviceAddressSpace(Core::System& system, DeviceName device_name, Handle das_handle);
|
||||
@@ -137,7 +137,7 @@ Result SetResourceLimitLimitValue(Core::System& system, Handle resource_limit_ha
|
||||
Result MapInsecureMemory(Core::System& system, uint64_t address, uint64_t size);
|
||||
Result UnmapInsecureMemory(Core::System& system, uint64_t address, uint64_t size);
|
||||
|
||||
Result SetHeapSize64From32(Core::System& system, uintptr_t* out_address, uint32_t size);
|
||||
Result SetHeapSize64From32(Core::System& system, uint64_t* out_address, uint32_t size);
|
||||
Result SetMemoryPermission64From32(Core::System& system, uint32_t address, uint32_t size, MemoryPermission perm);
|
||||
Result SetMemoryAttribute64From32(Core::System& system, uint32_t address, uint32_t size, uint32_t mask, uint32_t attr);
|
||||
Result MapMemory64From32(Core::System& system, uint32_t dst_address, uint32_t src_address, uint32_t size);
|
||||
@@ -182,7 +182,7 @@ Result FlushDataCache64From32(Core::System& system, uint32_t address, uint32_t s
|
||||
Result MapPhysicalMemory64From32(Core::System& system, uint32_t address, uint32_t size);
|
||||
Result UnmapPhysicalMemory64From32(Core::System& system, uint32_t address, uint32_t size);
|
||||
Result GetDebugFutureThreadInfo64From32(Core::System& system, ilp32::LastThreadContext* out_context, uint64_t* out_thread_id, Handle debug_handle, int64_t ns);
|
||||
Result GetLastThreadInfo64From32(Core::System& system, ilp32::LastThreadContext* out_context, uintptr_t* out_tls_address, uint32_t* out_flags);
|
||||
Result GetLastThreadInfo64From32(Core::System& system, ilp32::LastThreadContext* out_context, uint64_t* out_tls_address, uint32_t* out_flags);
|
||||
Result GetResourceLimitLimitValue64From32(Core::System& system, int64_t* out_limit_value, Handle resource_limit_handle, LimitableResource which);
|
||||
Result GetResourceLimitCurrentValue64From32(Core::System& system, int64_t* out_current_value, Handle resource_limit_handle, LimitableResource which);
|
||||
Result SetThreadActivity64From32(Core::System& system, Handle thread_handle, ThreadActivity thread_activity);
|
||||
@@ -215,7 +215,7 @@ Result MapTransferMemory64From32(Core::System& system, Handle trmem_handle, uint
|
||||
Result UnmapTransferMemory64From32(Core::System& system, Handle trmem_handle, uint32_t address, uint32_t size);
|
||||
Result CreateInterruptEvent64From32(Core::System& system, Handle* out_read_handle, int32_t interrupt_id, InterruptType interrupt_type);
|
||||
Result QueryPhysicalAddress64From32(Core::System& system, ilp32::PhysicalMemoryInfo* out_info, uint32_t address);
|
||||
Result QueryIoMapping64From32(Core::System& system, uintptr_t* out_address, uintptr_t* out_size, uint64_t physical_address, uint32_t size);
|
||||
Result QueryIoMapping64From32(Core::System& system, uint64_t* out_address, uint64_t* out_size, uint64_t physical_address, uint32_t size);
|
||||
Result CreateDeviceAddressSpace64From32(Core::System& system, Handle* out_handle, uint64_t das_address, uint64_t das_size);
|
||||
Result AttachDeviceAddressSpace64From32(Core::System& system, DeviceName device_name, Handle das_handle);
|
||||
Result DetachDeviceAddressSpace64From32(Core::System& system, DeviceName device_name, Handle das_handle);
|
||||
@@ -258,7 +258,7 @@ Result SetResourceLimitLimitValue64From32(Core::System& system, Handle resource_
|
||||
Result MapInsecureMemory64From32(Core::System& system, uint32_t address, uint32_t size);
|
||||
Result UnmapInsecureMemory64From32(Core::System& system, uint32_t address, uint32_t size);
|
||||
|
||||
Result SetHeapSize64(Core::System& system, uintptr_t* out_address, uint64_t size);
|
||||
Result SetHeapSize64(Core::System& system, uint64_t* out_address, uint64_t size);
|
||||
Result SetMemoryPermission64(Core::System& system, uint64_t address, uint64_t size, MemoryPermission perm);
|
||||
Result SetMemoryAttribute64(Core::System& system, uint64_t address, uint64_t size, uint32_t mask, uint32_t attr);
|
||||
Result MapMemory64(Core::System& system, uint64_t dst_address, uint64_t src_address, uint64_t size);
|
||||
@@ -303,7 +303,7 @@ Result FlushDataCache64(Core::System& system, uint64_t address, uint64_t size);
|
||||
Result MapPhysicalMemory64(Core::System& system, uint64_t address, uint64_t size);
|
||||
Result UnmapPhysicalMemory64(Core::System& system, uint64_t address, uint64_t size);
|
||||
Result GetDebugFutureThreadInfo64(Core::System& system, lp64::LastThreadContext* out_context, uint64_t* out_thread_id, Handle debug_handle, int64_t ns);
|
||||
Result GetLastThreadInfo64(Core::System& system, lp64::LastThreadContext* out_context, uintptr_t* out_tls_address, uint32_t* out_flags);
|
||||
Result GetLastThreadInfo64(Core::System& system, lp64::LastThreadContext* out_context, uint64_t* out_tls_address, uint32_t* out_flags);
|
||||
Result GetResourceLimitLimitValue64(Core::System& system, int64_t* out_limit_value, Handle resource_limit_handle, LimitableResource which);
|
||||
Result GetResourceLimitCurrentValue64(Core::System& system, int64_t* out_current_value, Handle resource_limit_handle, LimitableResource which);
|
||||
Result SetThreadActivity64(Core::System& system, Handle thread_handle, ThreadActivity thread_activity);
|
||||
@@ -336,7 +336,7 @@ Result MapTransferMemory64(Core::System& system, Handle trmem_handle, uint64_t a
|
||||
Result UnmapTransferMemory64(Core::System& system, Handle trmem_handle, uint64_t address, uint64_t size);
|
||||
Result CreateInterruptEvent64(Core::System& system, Handle* out_read_handle, int32_t interrupt_id, InterruptType interrupt_type);
|
||||
Result QueryPhysicalAddress64(Core::System& system, lp64::PhysicalMemoryInfo* out_info, uint64_t address);
|
||||
Result QueryIoMapping64(Core::System& system, uintptr_t* out_address, uintptr_t* out_size, uint64_t physical_address, uint64_t size);
|
||||
Result QueryIoMapping64(Core::System& system, uint64_t* out_address, uint64_t* out_size, uint64_t physical_address, uint64_t size);
|
||||
Result CreateDeviceAddressSpace64(Core::System& system, Handle* out_handle, uint64_t das_address, uint64_t das_size);
|
||||
Result AttachDeviceAddressSpace64(Core::System& system, DeviceName device_name, Handle das_handle);
|
||||
Result DetachDeviceAddressSpace64(Core::System& system, DeviceName device_name, Handle das_handle);
|
||||
|
||||
@@ -12,7 +12,7 @@ Result QueryPhysicalAddress(Core::System& system, lp64::PhysicalMemoryInfo* out_
|
||||
R_THROW(ResultNotImplemented);
|
||||
}
|
||||
|
||||
Result QueryIoMapping(Core::System& system, uintptr_t* out_address, uintptr_t* out_size,
|
||||
Result QueryIoMapping(Core::System& system, uint64_t* out_address, uint64_t* out_size,
|
||||
uint64_t physical_address, uint64_t size) {
|
||||
UNIMPLEMENTED();
|
||||
R_THROW(ResultNotImplemented);
|
||||
@@ -23,7 +23,7 @@ Result QueryPhysicalAddress64(Core::System& system, lp64::PhysicalMemoryInfo* ou
|
||||
R_RETURN(QueryPhysicalAddress(system, out_info, address));
|
||||
}
|
||||
|
||||
Result QueryIoMapping64(Core::System& system, uintptr_t* out_address, uintptr_t* out_size,
|
||||
Result QueryIoMapping64(Core::System& system, uint64_t* out_address, uint64_t* out_size,
|
||||
uint64_t physical_address, uint64_t size) {
|
||||
R_RETURN(QueryIoMapping(system, out_address, out_size, physical_address, size));
|
||||
}
|
||||
@@ -41,10 +41,10 @@ Result QueryPhysicalAddress64From32(Core::System& system, ilp32::PhysicalMemoryI
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result QueryIoMapping64From32(Core::System& system, uintptr_t* out_address, uintptr_t* out_size,
|
||||
Result QueryIoMapping64From32(Core::System& system, uint64_t* out_address, uint64_t* out_size,
|
||||
uint64_t physical_address, uint32_t size) {
|
||||
R_RETURN(QueryIoMapping(system, reinterpret_cast<uintptr_t*>(out_address),
|
||||
reinterpret_cast<uintptr_t*>(out_size), physical_address, size));
|
||||
R_RETURN(QueryIoMapping(system, reinterpret_cast<uint64_t*>(out_address),
|
||||
reinterpret_cast<uint64_t*>(out_size), physical_address, size));
|
||||
}
|
||||
|
||||
} // namespace Kernel::Svc
|
||||
|
||||
@@ -13,7 +13,7 @@ void FlushEntireDataCache(Core::System& system) {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
Result FlushDataCache(Core::System& system, VAddr address, size_t size) {
|
||||
Result FlushDataCache(Core::System& system, uint64_t address, uint64_t size) {
|
||||
UNIMPLEMENTED();
|
||||
R_THROW(ResultNotImplemented);
|
||||
}
|
||||
@@ -33,8 +33,8 @@ Result StoreProcessDataCache(Core::System& system, Handle process_handle, uint64
|
||||
Result FlushProcessDataCache(Core::System& system, Handle process_handle, u64 address, u64 size) {
|
||||
// Validate address/size.
|
||||
R_UNLESS(size > 0, ResultInvalidSize);
|
||||
R_UNLESS(address == static_cast<uintptr_t>(address), ResultInvalidCurrentMemory);
|
||||
R_UNLESS(size == static_cast<size_t>(size), ResultInvalidCurrentMemory);
|
||||
R_UNLESS(address == static_cast<uint64_t>(address), ResultInvalidCurrentMemory);
|
||||
R_UNLESS(size == static_cast<uint64_t>(size), ResultInvalidCurrentMemory);
|
||||
|
||||
// Get the process from its handle.
|
||||
KScopedAutoObject process =
|
||||
@@ -53,7 +53,7 @@ void FlushEntireDataCache64(Core::System& system) {
|
||||
FlushEntireDataCache(system);
|
||||
}
|
||||
|
||||
Result FlushDataCache64(Core::System& system, VAddr address, size_t size) {
|
||||
Result FlushDataCache64(Core::System& system, uint64_t address, uint64_t size) {
|
||||
R_RETURN(FlushDataCache(system, address, size));
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ constexpr bool IsValidUnmapFromOwnerCodeMemoryPermission(MemoryPermission perm)
|
||||
|
||||
} // namespace
|
||||
|
||||
Result CreateCodeMemory(Core::System& system, Handle* out, VAddr address, size_t size) {
|
||||
Result CreateCodeMemory(Core::System& system, Handle* out, VAddr address, uint64_t size) {
|
||||
LOG_TRACE(Kernel_SVC, "called, address=0x{:X}, size=0x{:X}", address, size);
|
||||
|
||||
// Get kernel instance.
|
||||
@@ -64,7 +64,7 @@ Result CreateCodeMemory(Core::System& system, Handle* out, VAddr address, size_t
|
||||
}
|
||||
|
||||
Result ControlCodeMemory(Core::System& system, Handle code_memory_handle,
|
||||
CodeMemoryOperation operation, VAddr address, size_t size,
|
||||
CodeMemoryOperation operation, VAddr address, uint64_t size,
|
||||
MemoryPermission perm) {
|
||||
|
||||
LOG_TRACE(Kernel_SVC,
|
||||
|
||||
@@ -45,19 +45,19 @@ Result SetDebugThreadContext(Core::System& system, Handle debug_handle, uint64_t
|
||||
}
|
||||
|
||||
Result QueryDebugProcessMemory(Core::System& system, uint64_t out_memory_info,
|
||||
PageInfo* out_page_info, Handle debug_handle, uintptr_t address) {
|
||||
PageInfo* out_page_info, Handle process_handle, uint64_t address) {
|
||||
UNIMPLEMENTED();
|
||||
R_THROW(ResultNotImplemented);
|
||||
}
|
||||
|
||||
Result ReadDebugProcessMemory(Core::System& system, uintptr_t buffer, Handle debug_handle,
|
||||
uintptr_t address, size_t size) {
|
||||
Result ReadDebugProcessMemory(Core::System& system, uint64_t buffer, Handle debug_handle,
|
||||
uint64_t address, uint64_t size) {
|
||||
UNIMPLEMENTED();
|
||||
R_THROW(ResultNotImplemented);
|
||||
}
|
||||
|
||||
Result WriteDebugProcessMemory(Core::System& system, Handle debug_handle, uintptr_t buffer,
|
||||
uintptr_t address, size_t size) {
|
||||
Result WriteDebugProcessMemory(Core::System& system, Handle debug_handle, uint64_t buffer,
|
||||
uint64_t address, uint64_t size) {
|
||||
UNIMPLEMENTED();
|
||||
R_THROW(ResultNotImplemented);
|
||||
}
|
||||
|
||||
@@ -76,8 +76,8 @@ constexpr bool IsValidDeviceMemoryPermission(MemoryPermission device_perm) {
|
||||
}
|
||||
|
||||
Result MapDeviceAddressSpaceByForce(Core::System& system, Handle das_handle, Handle process_handle,
|
||||
uint64_t process_address, size_t size, uint64_t device_address,
|
||||
u32 option) {
|
||||
uint64_t process_address, uint64_t size,
|
||||
uint64_t device_address, u32 option) {
|
||||
// Decode the option.
|
||||
const MapDeviceAddressSpaceOption option_pack{option};
|
||||
const auto device_perm = option_pack.permission;
|
||||
@@ -90,7 +90,7 @@ Result MapDeviceAddressSpaceByForce(Core::System& system, Handle das_handle, Han
|
||||
R_UNLESS(size > 0, ResultInvalidSize);
|
||||
R_UNLESS((process_address < process_address + size), ResultInvalidCurrentMemory);
|
||||
R_UNLESS((device_address < device_address + size), ResultInvalidMemoryRegion);
|
||||
R_UNLESS((process_address == static_cast<uintptr_t>(process_address)),
|
||||
R_UNLESS((process_address == static_cast<uint64_t>(process_address)),
|
||||
ResultInvalidCurrentMemory);
|
||||
R_UNLESS(IsValidDeviceMemoryPermission(device_perm), ResultInvalidNewMemoryPermission);
|
||||
R_UNLESS(reserved == 0, ResultInvalidEnumValue);
|
||||
@@ -116,8 +116,8 @@ Result MapDeviceAddressSpaceByForce(Core::System& system, Handle das_handle, Han
|
||||
}
|
||||
|
||||
Result MapDeviceAddressSpaceAligned(Core::System& system, Handle das_handle, Handle process_handle,
|
||||
uint64_t process_address, size_t size, uint64_t device_address,
|
||||
u32 option) {
|
||||
uint64_t process_address, uint64_t size,
|
||||
uint64_t device_address, u32 option) {
|
||||
// Decode the option.
|
||||
const MapDeviceAddressSpaceOption option_pack{option};
|
||||
const auto device_perm = option_pack.permission;
|
||||
@@ -131,7 +131,7 @@ Result MapDeviceAddressSpaceAligned(Core::System& system, Handle das_handle, Han
|
||||
R_UNLESS(size > 0, ResultInvalidSize);
|
||||
R_UNLESS((process_address < process_address + size), ResultInvalidCurrentMemory);
|
||||
R_UNLESS((device_address < device_address + size), ResultInvalidMemoryRegion);
|
||||
R_UNLESS((process_address == static_cast<uintptr_t>(process_address)),
|
||||
R_UNLESS((process_address == static_cast<uint64_t>(process_address)),
|
||||
ResultInvalidCurrentMemory);
|
||||
R_UNLESS(IsValidDeviceMemoryPermission(device_perm), ResultInvalidNewMemoryPermission);
|
||||
R_UNLESS(reserved == 0, ResultInvalidEnumValue);
|
||||
@@ -157,7 +157,7 @@ Result MapDeviceAddressSpaceAligned(Core::System& system, Handle das_handle, Han
|
||||
}
|
||||
|
||||
Result UnmapDeviceAddressSpace(Core::System& system, Handle das_handle, Handle process_handle,
|
||||
uint64_t process_address, size_t size, uint64_t device_address) {
|
||||
uint64_t process_address, uint64_t size, uint64_t device_address) {
|
||||
// Validate input.
|
||||
R_UNLESS(Common::IsAligned(process_address, PageSize), ResultInvalidAddress);
|
||||
R_UNLESS(Common::IsAligned(device_address, PageSize), ResultInvalidAddress);
|
||||
@@ -165,7 +165,7 @@ Result UnmapDeviceAddressSpace(Core::System& system, Handle das_handle, Handle p
|
||||
R_UNLESS(size > 0, ResultInvalidSize);
|
||||
R_UNLESS((process_address < process_address + size), ResultInvalidCurrentMemory);
|
||||
R_UNLESS((device_address < device_address + size), ResultInvalidMemoryRegion);
|
||||
R_UNLESS((process_address == static_cast<uintptr_t>(process_address)),
|
||||
R_UNLESS((process_address == static_cast<uint64_t>(process_address)),
|
||||
ResultInvalidCurrentMemory);
|
||||
|
||||
// Get the device address space.
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
|
||||
namespace Kernel::Svc {
|
||||
|
||||
Result MapInsecureMemory(Core::System& system, uintptr_t address, size_t size) {
|
||||
Result MapInsecureMemory(Core::System& system, uint64_t address, uint64_t size) {
|
||||
UNIMPLEMENTED();
|
||||
R_THROW(ResultNotImplemented);
|
||||
}
|
||||
|
||||
Result UnmapInsecureMemory(Core::System& system, uintptr_t address, size_t size) {
|
||||
Result UnmapInsecureMemory(Core::System& system, uint64_t address, uint64_t size) {
|
||||
UNIMPLEMENTED();
|
||||
R_THROW(ResultNotImplemented);
|
||||
}
|
||||
|
||||
@@ -12,19 +12,19 @@ Result CreateIoPool(Core::System& system, Handle* out, IoPoolType pool_type) {
|
||||
}
|
||||
|
||||
Result CreateIoRegion(Core::System& system, Handle* out, Handle io_pool_handle, uint64_t phys_addr,
|
||||
size_t size, MemoryMapping mapping, MemoryPermission perm) {
|
||||
uint64_t size, MemoryMapping mapping, MemoryPermission perm) {
|
||||
UNIMPLEMENTED();
|
||||
R_THROW(ResultNotImplemented);
|
||||
}
|
||||
|
||||
Result MapIoRegion(Core::System& system, Handle io_region_handle, uintptr_t address, size_t size,
|
||||
Result MapIoRegion(Core::System& system, Handle io_region_handle, uint64_t address, uint64_t size,
|
||||
MemoryPermission map_perm) {
|
||||
UNIMPLEMENTED();
|
||||
R_THROW(ResultNotImplemented);
|
||||
}
|
||||
|
||||
Result UnmapIoRegion(Core::System& system, Handle io_region_handle, uintptr_t address,
|
||||
size_t size) {
|
||||
Result UnmapIoRegion(Core::System& system, Handle io_region_handle, uint64_t address,
|
||||
uint64_t size) {
|
||||
UNIMPLEMENTED();
|
||||
R_THROW(ResultNotImplemented);
|
||||
}
|
||||
|
||||
@@ -158,7 +158,7 @@ Result SetUnsafeLimit64(Core::System& system, uint64_t limit) {
|
||||
R_RETURN(SetUnsafeLimit(system, limit));
|
||||
}
|
||||
|
||||
Result SetHeapSize64From32(Core::System& system, uintptr_t* out_address, uint32_t size) {
|
||||
Result SetHeapSize64From32(Core::System& system, uint64_t* out_address, uint32_t size) {
|
||||
R_RETURN(SetHeapSize(system, out_address, size));
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "core/core.h"
|
||||
#include "core/hle/kernel/k_client_port.h"
|
||||
#include "core/hle/kernel/k_client_session.h"
|
||||
#include "core/hle/kernel/k_object_name.h"
|
||||
#include "core/hle/kernel/k_port.h"
|
||||
#include "core/hle/kernel/k_process.h"
|
||||
#include "core/hle/kernel/svc.h"
|
||||
@@ -64,7 +65,7 @@ Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr port_name_add
|
||||
}
|
||||
|
||||
Result CreatePort(Core::System& system, Handle* out_server, Handle* out_client,
|
||||
int32_t max_sessions, bool is_light, uintptr_t name) {
|
||||
int32_t max_sessions, bool is_light, uint64_t name) {
|
||||
UNIMPLEMENTED();
|
||||
R_THROW(ResultNotImplemented);
|
||||
}
|
||||
@@ -74,10 +75,57 @@ Result ConnectToPort(Core::System& system, Handle* out_handle, Handle port) {
|
||||
R_THROW(ResultNotImplemented);
|
||||
}
|
||||
|
||||
Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t name,
|
||||
Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t user_name,
|
||||
int32_t max_sessions) {
|
||||
UNIMPLEMENTED();
|
||||
R_THROW(ResultNotImplemented);
|
||||
// Copy the provided name from user memory to kernel memory.
|
||||
std::array<char, KObjectName::NameLengthMax> name{};
|
||||
system.Memory().ReadBlock(user_name, name.data(), sizeof(name));
|
||||
|
||||
// Validate that sessions and name are valid.
|
||||
R_UNLESS(max_sessions >= 0, ResultOutOfRange);
|
||||
R_UNLESS(name[sizeof(name) - 1] == '\x00', ResultOutOfRange);
|
||||
|
||||
if (max_sessions > 0) {
|
||||
// Get the current handle table.
|
||||
auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
|
||||
|
||||
// Create a new port.
|
||||
KPort* port = KPort::Create(system.Kernel());
|
||||
R_UNLESS(port != nullptr, ResultOutOfResource);
|
||||
|
||||
// Initialize the new port.
|
||||
port->Initialize(max_sessions, false, "");
|
||||
|
||||
// Register the port.
|
||||
KPort::Register(system.Kernel(), port);
|
||||
|
||||
// Ensure that our only reference to the port is in the handle table when we're done.
|
||||
SCOPE_EXIT({
|
||||
port->GetClientPort().Close();
|
||||
port->GetServerPort().Close();
|
||||
});
|
||||
|
||||
// Register the handle in the table.
|
||||
R_TRY(handle_table.Add(out_server_handle, std::addressof(port->GetServerPort())));
|
||||
ON_RESULT_FAILURE {
|
||||
handle_table.Remove(*out_server_handle);
|
||||
};
|
||||
|
||||
// Create a new object name.
|
||||
R_TRY(KObjectName::NewFromName(system.Kernel(), std::addressof(port->GetClientPort()),
|
||||
name.data()));
|
||||
} else /* if (max_sessions == 0) */ {
|
||||
// Ensure that this else case is correct.
|
||||
ASSERT(max_sessions == 0);
|
||||
|
||||
// If we're closing, there's no server handle.
|
||||
*out_server_handle = InvalidHandle;
|
||||
|
||||
// Delete the object.
|
||||
R_TRY(KObjectName::Delete<KClientPort>(system.Kernel(), name.data()));
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ConnectToNamedPort64(Core::System& system, Handle* out_handle, uint64_t name) {
|
||||
|
||||
@@ -37,8 +37,8 @@ Result SetProcessMemoryPermission(Core::System& system, Handle process_handle, V
|
||||
R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize);
|
||||
R_UNLESS(size > 0, ResultInvalidSize);
|
||||
R_UNLESS((address < address + size), ResultInvalidCurrentMemory);
|
||||
R_UNLESS(address == static_cast<uintptr_t>(address), ResultInvalidCurrentMemory);
|
||||
R_UNLESS(size == static_cast<size_t>(size), ResultInvalidCurrentMemory);
|
||||
R_UNLESS(address == static_cast<uint64_t>(address), ResultInvalidCurrentMemory);
|
||||
R_UNLESS(size == static_cast<uint64_t>(size), ResultInvalidCurrentMemory);
|
||||
|
||||
// Validate the memory permission.
|
||||
R_UNLESS(IsValidProcessMemoryPermission(perm), ResultInvalidNewMemoryPermission);
|
||||
|
||||
@@ -443,7 +443,7 @@ def emit_wrapper(wrapped_fn, suffix, register_info, arguments, byte_size):
|
||||
lines.append("")
|
||||
|
||||
for output_type, var_name, _, is_address in output_writes:
|
||||
output_type = "uintptr_t" if is_address else output_type
|
||||
output_type = "uint64_t" if is_address else output_type
|
||||
lines.append(f"{output_type} {var_name}{{}};")
|
||||
for input_type, var_name, _ in input_reads:
|
||||
lines.append(f"{input_type} {var_name}{{}};")
|
||||
@@ -630,7 +630,7 @@ def emit_call(bitness, names, suffix):
|
||||
def build_fn_declaration(return_type, name, arguments):
|
||||
arg_list = ["Core::System& system"]
|
||||
for arg in arguments:
|
||||
type_name = "uintptr_t" if arg.is_address else arg.type_name
|
||||
type_name = "uint64_t" if arg.is_address else arg.type_name
|
||||
pointer = "*" if arg.is_output and not arg.is_outptr else ""
|
||||
arg_list.append(f"{type_name}{pointer} {arg.var_name}")
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ enum class Errno : u32 {
|
||||
INVAL = 22,
|
||||
MFILE = 24,
|
||||
MSGSIZE = 90,
|
||||
CONNRESET = 104,
|
||||
NOTCONN = 107,
|
||||
TIMEDOUT = 110,
|
||||
};
|
||||
|
||||
@@ -27,6 +27,8 @@ Errno Translate(Network::Errno value) {
|
||||
return Errno::NOTCONN;
|
||||
case Network::Errno::TIMEDOUT:
|
||||
return Errno::TIMEDOUT;
|
||||
case Network::Errno::CONNRESET:
|
||||
return Errno::CONNRESET;
|
||||
default:
|
||||
UNIMPLEMENTED_MSG("Unimplemented errno={}", value);
|
||||
return Errno::SUCCESS;
|
||||
|
||||
@@ -109,6 +109,8 @@ Errno TranslateNativeError(int e) {
|
||||
return Errno::AGAIN;
|
||||
case WSAECONNREFUSED:
|
||||
return Errno::CONNREFUSED;
|
||||
case WSAECONNRESET:
|
||||
return Errno::CONNRESET;
|
||||
case WSAEHOSTUNREACH:
|
||||
return Errno::HOSTUNREACH;
|
||||
case WSAENETDOWN:
|
||||
@@ -205,6 +207,8 @@ Errno TranslateNativeError(int e) {
|
||||
return Errno::AGAIN;
|
||||
case ECONNREFUSED:
|
||||
return Errno::CONNREFUSED;
|
||||
case ECONNRESET:
|
||||
return Errno::CONNRESET;
|
||||
case EHOSTUNREACH:
|
||||
return Errno::HOSTUNREACH;
|
||||
case ENETDOWN:
|
||||
|
||||
@@ -30,6 +30,7 @@ enum class Errno {
|
||||
NOTCONN,
|
||||
AGAIN,
|
||||
CONNREFUSED,
|
||||
CONNRESET,
|
||||
HOSTUNREACH,
|
||||
NETDOWN,
|
||||
NETUNREACH,
|
||||
|
||||
@@ -10,68 +10,122 @@
|
||||
#include "input_common/drivers/mouse.h"
|
||||
|
||||
namespace InputCommon {
|
||||
constexpr int update_time = 10;
|
||||
constexpr float default_stick_sensitivity = 0.022f;
|
||||
constexpr float default_motion_sensitivity = 0.008f;
|
||||
constexpr int mouse_axis_x = 0;
|
||||
constexpr int mouse_axis_y = 1;
|
||||
constexpr int wheel_axis_x = 2;
|
||||
constexpr int wheel_axis_y = 3;
|
||||
constexpr int motion_wheel_y = 4;
|
||||
constexpr int touch_axis_x = 10;
|
||||
constexpr int touch_axis_y = 11;
|
||||
constexpr PadIdentifier identifier = {
|
||||
.guid = Common::UUID{},
|
||||
.port = 0,
|
||||
.pad = 0,
|
||||
};
|
||||
|
||||
constexpr PadIdentifier motion_identifier = {
|
||||
.guid = Common::UUID{},
|
||||
.port = 0,
|
||||
.pad = 1,
|
||||
};
|
||||
|
||||
constexpr PadIdentifier real_mouse_identifier = {
|
||||
.guid = Common::UUID{},
|
||||
.port = 1,
|
||||
.pad = 0,
|
||||
};
|
||||
|
||||
constexpr PadIdentifier touch_identifier = {
|
||||
.guid = Common::UUID{},
|
||||
.port = 2,
|
||||
.pad = 0,
|
||||
};
|
||||
|
||||
Mouse::Mouse(std::string input_engine_) : InputEngine(std::move(input_engine_)) {
|
||||
PreSetController(identifier);
|
||||
PreSetController(real_mouse_identifier);
|
||||
PreSetController(touch_identifier);
|
||||
PreSetController(motion_identifier);
|
||||
|
||||
// Initialize all mouse axis
|
||||
PreSetAxis(identifier, mouse_axis_x);
|
||||
PreSetAxis(identifier, mouse_axis_y);
|
||||
PreSetAxis(identifier, wheel_axis_x);
|
||||
PreSetAxis(identifier, wheel_axis_y);
|
||||
PreSetAxis(identifier, motion_wheel_y);
|
||||
PreSetAxis(identifier, touch_axis_x);
|
||||
PreSetAxis(identifier, touch_axis_y);
|
||||
PreSetAxis(real_mouse_identifier, mouse_axis_x);
|
||||
PreSetAxis(real_mouse_identifier, mouse_axis_y);
|
||||
PreSetAxis(touch_identifier, mouse_axis_x);
|
||||
PreSetAxis(touch_identifier, mouse_axis_y);
|
||||
|
||||
// Initialize variables
|
||||
mouse_origin = {};
|
||||
last_mouse_position = {};
|
||||
wheel_position = {};
|
||||
last_mouse_change = {};
|
||||
last_motion_change = {};
|
||||
|
||||
update_thread = std::jthread([this](std::stop_token stop_token) { UpdateThread(stop_token); });
|
||||
}
|
||||
|
||||
void Mouse::UpdateThread(std::stop_token stop_token) {
|
||||
Common::SetCurrentThreadName("Mouse");
|
||||
constexpr int update_time = 10;
|
||||
|
||||
while (!stop_token.stop_requested()) {
|
||||
if (Settings::values.mouse_panning && !Settings::values.mouse_enabled) {
|
||||
// Slow movement by 4%
|
||||
last_mouse_change *= 0.96f;
|
||||
const float sensitivity =
|
||||
Settings::values.mouse_panning_sensitivity.GetValue() * 0.022f;
|
||||
SetAxis(identifier, mouse_axis_x, last_mouse_change.x * sensitivity);
|
||||
SetAxis(identifier, mouse_axis_y, -last_mouse_change.y * sensitivity);
|
||||
}
|
||||
UpdateStickInput();
|
||||
UpdateMotionInput();
|
||||
|
||||
SetAxis(identifier, motion_wheel_y, 0.0f);
|
||||
|
||||
if (mouse_panning_timout++ > 20) {
|
||||
if (mouse_panning_timeout++ > 20) {
|
||||
StopPanning();
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(update_time));
|
||||
}
|
||||
}
|
||||
|
||||
void Mouse::MouseMove(int x, int y, f32 touch_x, f32 touch_y, int center_x, int center_y) {
|
||||
// If native mouse is enabled just set the screen coordinates
|
||||
if (Settings::values.mouse_enabled) {
|
||||
SetAxis(identifier, mouse_axis_x, touch_x);
|
||||
SetAxis(identifier, mouse_axis_y, touch_y);
|
||||
void Mouse::UpdateStickInput() {
|
||||
if (!Settings::values.mouse_panning) {
|
||||
return;
|
||||
}
|
||||
|
||||
SetAxis(identifier, touch_axis_x, touch_x);
|
||||
SetAxis(identifier, touch_axis_y, touch_y);
|
||||
const float sensitivity =
|
||||
Settings::values.mouse_panning_sensitivity.GetValue() * default_stick_sensitivity;
|
||||
|
||||
// Slow movement by 4%
|
||||
last_mouse_change *= 0.96f;
|
||||
SetAxis(identifier, mouse_axis_x, last_mouse_change.x * sensitivity);
|
||||
SetAxis(identifier, mouse_axis_y, -last_mouse_change.y * sensitivity);
|
||||
}
|
||||
|
||||
void Mouse::UpdateMotionInput() {
|
||||
const float sensitivity =
|
||||
Settings::values.mouse_panning_sensitivity.GetValue() * default_motion_sensitivity;
|
||||
|
||||
// Slow movement by 7%
|
||||
if (Settings::values.mouse_panning) {
|
||||
last_motion_change *= 0.93f;
|
||||
} else {
|
||||
last_motion_change.z *= 0.93f;
|
||||
}
|
||||
|
||||
const BasicMotion motion_data{
|
||||
.gyro_x = last_motion_change.x * sensitivity,
|
||||
.gyro_y = last_motion_change.y * sensitivity,
|
||||
.gyro_z = last_motion_change.z * sensitivity,
|
||||
.accel_x = 0,
|
||||
.accel_y = 0,
|
||||
.accel_z = 0,
|
||||
.delta_timestamp = update_time * 1000,
|
||||
};
|
||||
|
||||
SetMotion(motion_identifier, 0, motion_data);
|
||||
}
|
||||
|
||||
void Mouse::Move(int x, int y, int center_x, int center_y) {
|
||||
if (Settings::values.mouse_panning) {
|
||||
mouse_panning_timeout = 0;
|
||||
|
||||
auto mouse_change =
|
||||
(Common::MakeVec(x, y) - Common::MakeVec(center_x, center_y)).Cast<float>();
|
||||
mouse_panning_timout = 0;
|
||||
Common::Vec3<float> motion_change{-mouse_change.y, -mouse_change.x, last_motion_change.z};
|
||||
|
||||
const auto move_distance = mouse_change.Length();
|
||||
if (move_distance == 0) {
|
||||
@@ -87,6 +141,7 @@ void Mouse::MouseMove(int x, int y, f32 touch_x, f32 touch_y, int center_x, int
|
||||
|
||||
// Average mouse movements
|
||||
last_mouse_change = (last_mouse_change * 0.91f) + (mouse_change * 0.09f);
|
||||
last_motion_change = (last_motion_change * 0.69f) + (motion_change * 0.31f);
|
||||
|
||||
const auto last_move_distance = last_mouse_change.Length();
|
||||
|
||||
@@ -110,35 +165,66 @@ void Mouse::MouseMove(int x, int y, f32 touch_x, f32 touch_y, int center_x, int
|
||||
const float sensitivity = Settings::values.mouse_panning_sensitivity.GetValue() * 0.0012f;
|
||||
SetAxis(identifier, mouse_axis_x, static_cast<float>(mouse_move.x) * sensitivity);
|
||||
SetAxis(identifier, mouse_axis_y, static_cast<float>(-mouse_move.y) * sensitivity);
|
||||
|
||||
last_motion_change = {
|
||||
static_cast<float>(-mouse_move.y) / 50.0f,
|
||||
static_cast<float>(-mouse_move.x) / 50.0f,
|
||||
last_motion_change.z,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
void Mouse::PressButton(int x, int y, f32 touch_x, f32 touch_y, MouseButton button) {
|
||||
SetAxis(identifier, touch_axis_x, touch_x);
|
||||
SetAxis(identifier, touch_axis_y, touch_y);
|
||||
void Mouse::MouseMove(f32 touch_x, f32 touch_y) {
|
||||
SetAxis(real_mouse_identifier, mouse_axis_x, touch_x);
|
||||
SetAxis(real_mouse_identifier, mouse_axis_y, touch_y);
|
||||
}
|
||||
|
||||
void Mouse::TouchMove(f32 touch_x, f32 touch_y) {
|
||||
SetAxis(touch_identifier, mouse_axis_x, touch_x);
|
||||
SetAxis(touch_identifier, mouse_axis_y, touch_y);
|
||||
}
|
||||
|
||||
void Mouse::PressButton(int x, int y, MouseButton button) {
|
||||
SetButton(identifier, static_cast<int>(button), true);
|
||||
|
||||
// Set initial analog parameters
|
||||
mouse_origin = {x, y};
|
||||
last_mouse_position = {x, y};
|
||||
button_pressed = true;
|
||||
}
|
||||
|
||||
void Mouse::PressMouseButton(MouseButton button) {
|
||||
SetButton(real_mouse_identifier, static_cast<int>(button), true);
|
||||
}
|
||||
|
||||
void Mouse::PressTouchButton(f32 touch_x, f32 touch_y, MouseButton button) {
|
||||
SetAxis(touch_identifier, mouse_axis_x, touch_x);
|
||||
SetAxis(touch_identifier, mouse_axis_y, touch_y);
|
||||
SetButton(touch_identifier, static_cast<int>(button), true);
|
||||
}
|
||||
|
||||
void Mouse::ReleaseButton(MouseButton button) {
|
||||
SetButton(identifier, static_cast<int>(button), false);
|
||||
SetButton(real_mouse_identifier, static_cast<int>(button), false);
|
||||
SetButton(touch_identifier, static_cast<int>(button), false);
|
||||
|
||||
if (!Settings::values.mouse_panning && !Settings::values.mouse_enabled) {
|
||||
if (!Settings::values.mouse_panning) {
|
||||
SetAxis(identifier, mouse_axis_x, 0);
|
||||
SetAxis(identifier, mouse_axis_y, 0);
|
||||
}
|
||||
|
||||
last_motion_change.x = 0;
|
||||
last_motion_change.y = 0;
|
||||
|
||||
button_pressed = false;
|
||||
}
|
||||
|
||||
void Mouse::MouseWheelChange(int x, int y) {
|
||||
wheel_position.x += x;
|
||||
wheel_position.y += y;
|
||||
last_motion_change.z += static_cast<f32>(y) / 100.0f;
|
||||
SetAxis(identifier, wheel_axis_x, static_cast<f32>(wheel_position.x));
|
||||
SetAxis(identifier, wheel_axis_y, static_cast<f32>(wheel_position.y));
|
||||
SetAxis(identifier, motion_wheel_y, static_cast<f32>(y) / 100.0f);
|
||||
}
|
||||
|
||||
void Mouse::ReleaseAllButtons() {
|
||||
@@ -207,6 +293,9 @@ Common::Input::ButtonNames Mouse::GetUIName(const Common::ParamPackage& params)
|
||||
if (params.Has("axis_x") && params.Has("axis_y") && params.Has("axis_z")) {
|
||||
return Common::Input::ButtonNames::Engine;
|
||||
}
|
||||
if (params.Has("motion")) {
|
||||
return Common::Input::ButtonNames::Engine;
|
||||
}
|
||||
|
||||
return Common::Input::ButtonNames::Invalid;
|
||||
}
|
||||
|
||||
@@ -37,13 +37,43 @@ public:
|
||||
* @param center_x the x-coordinate of the middle of the screen
|
||||
* @param center_y the y-coordinate of the middle of the screen
|
||||
*/
|
||||
void MouseMove(int x, int y, f32 touch_x, f32 touch_y, int center_x, int center_y);
|
||||
void Move(int x, int y, int center_x, int center_y);
|
||||
|
||||
/**
|
||||
* Sets the status of all buttons bound with the key to pressed
|
||||
* @param key_code the code of the key to press
|
||||
* Signals that real mouse has moved.
|
||||
* @param x the absolute position on the touchscreen of the cursor
|
||||
* @param y the absolute position on the touchscreen of the cursor
|
||||
*/
|
||||
void PressButton(int x, int y, f32 touch_x, f32 touch_y, MouseButton button);
|
||||
void MouseMove(f32 touch_x, f32 touch_y);
|
||||
|
||||
/**
|
||||
* Signals that touch finger has moved.
|
||||
* @param x the absolute position on the touchscreen of the cursor
|
||||
* @param y the absolute position on the touchscreen of the cursor
|
||||
*/
|
||||
void TouchMove(f32 touch_x, f32 touch_y);
|
||||
|
||||
/**
|
||||
* Sets the status of a button to pressed
|
||||
* @param x the x-coordinate of the cursor
|
||||
* @param y the y-coordinate of the cursor
|
||||
* @param button the id of the button to press
|
||||
*/
|
||||
void PressButton(int x, int y, MouseButton button);
|
||||
|
||||
/**
|
||||
* Sets the status of a mouse button to pressed
|
||||
* @param button the id of the button to press
|
||||
*/
|
||||
void PressMouseButton(MouseButton button);
|
||||
|
||||
/**
|
||||
* Sets the status of touch finger to pressed
|
||||
* @param x the absolute position on the touchscreen of the cursor
|
||||
* @param y the absolute position on the touchscreen of the cursor
|
||||
* @param button the id of the button to press
|
||||
*/
|
||||
void PressTouchButton(f32 touch_x, f32 touch_y, MouseButton button);
|
||||
|
||||
/**
|
||||
* Sets the status of all buttons bound with the key to released
|
||||
@@ -66,6 +96,8 @@ public:
|
||||
|
||||
private:
|
||||
void UpdateThread(std::stop_token stop_token);
|
||||
void UpdateStickInput();
|
||||
void UpdateMotionInput();
|
||||
void StopPanning();
|
||||
|
||||
Common::Input::ButtonNames GetUIButtonName(const Common::ParamPackage& params) const;
|
||||
@@ -73,9 +105,10 @@ private:
|
||||
Common::Vec2<int> mouse_origin;
|
||||
Common::Vec2<int> last_mouse_position;
|
||||
Common::Vec2<float> last_mouse_change;
|
||||
Common::Vec3<float> last_motion_change;
|
||||
Common::Vec2<int> wheel_position;
|
||||
bool button_pressed;
|
||||
int mouse_panning_timout{};
|
||||
int mouse_panning_timeout{};
|
||||
std::jthread update_thread;
|
||||
};
|
||||
|
||||
|
||||
@@ -142,14 +142,10 @@ void MappingFactory::RegisterMotion(const MappingData& data) {
|
||||
new_input.Set("port", static_cast<int>(data.pad.port));
|
||||
new_input.Set("pad", static_cast<int>(data.pad.pad));
|
||||
|
||||
// If engine is mouse map the mouse position as 3 axis motion
|
||||
// If engine is mouse map it automatically to mouse motion
|
||||
if (data.engine == "mouse") {
|
||||
new_input.Set("axis_x", 1);
|
||||
new_input.Set("invert_x", "-");
|
||||
new_input.Set("axis_y", 0);
|
||||
new_input.Set("axis_z", 4);
|
||||
new_input.Set("range", 1.0f);
|
||||
new_input.Set("deadzone", 0.0f);
|
||||
new_input.Set("motion", 0);
|
||||
new_input.Set("pad", 1);
|
||||
input_queue.Push(new_input);
|
||||
return;
|
||||
}
|
||||
@@ -194,6 +190,10 @@ bool MappingFactory::IsDriverValid(const MappingData& data) const {
|
||||
if (data.engine == "keyboard" && data.pad.port != 0) {
|
||||
return false;
|
||||
}
|
||||
// Only port 0 can be mapped on the mouse
|
||||
if (data.engine == "mouse" && data.pad.port != 0) {
|
||||
return false;
|
||||
}
|
||||
// To prevent mapping with two devices we disable any UDP except motion
|
||||
if (!Settings::values.enable_udp_controller && data.engine == "cemuhookudp" &&
|
||||
data.type != EngineInputType::Motion) {
|
||||
|
||||
@@ -292,7 +292,7 @@ IR::Program TranslateProgram(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Blo
|
||||
|
||||
Optimization::PositionPass(env, program);
|
||||
|
||||
Optimization::GlobalMemoryToStorageBufferPass(program, host_info);
|
||||
Optimization::GlobalMemoryToStorageBufferPass(program);
|
||||
Optimization::TexturePass(env, program, host_info);
|
||||
|
||||
if (Settings::values.resolution_info.active) {
|
||||
|
||||
@@ -15,7 +15,6 @@ struct HostTranslateInfo {
|
||||
bool needs_demote_reorder{}; ///< True when the device needs DemoteToHelperInvocation reordered
|
||||
bool support_snorm_render_buffer{}; ///< True when the device supports SNORM render buffers
|
||||
bool support_viewport_index_layer{}; ///< True when the device supports gl_Layer in VS
|
||||
u32 min_ssbo_alignment{}; ///< Minimum alignment supported by the device for SSBOs
|
||||
bool support_geometry_shader_passthrough{}; ///< True when the device supports geometry
|
||||
///< passthrough shaders
|
||||
};
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "shader_recompiler/frontend/ir/breadth_first_search.h"
|
||||
#include "shader_recompiler/frontend/ir/ir_emitter.h"
|
||||
#include "shader_recompiler/frontend/ir/value.h"
|
||||
#include "shader_recompiler/host_translate_info.h"
|
||||
#include "shader_recompiler/ir_opt/passes.h"
|
||||
|
||||
namespace Shader::Optimization {
|
||||
@@ -403,7 +402,7 @@ void CollectStorageBuffers(IR::Block& block, IR::Inst& inst, StorageInfo& info)
|
||||
}
|
||||
|
||||
/// Returns the offset in indices (not bytes) for an equivalent storage instruction
|
||||
IR::U32 StorageOffset(IR::Block& block, IR::Inst& inst, StorageBufferAddr buffer, u32 alignment) {
|
||||
IR::U32 StorageOffset(IR::Block& block, IR::Inst& inst, StorageBufferAddr buffer) {
|
||||
IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
|
||||
IR::U32 offset;
|
||||
if (const std::optional<LowAddrInfo> low_addr{TrackLowAddress(&inst)}) {
|
||||
@@ -416,10 +415,7 @@ IR::U32 StorageOffset(IR::Block& block, IR::Inst& inst, StorageBufferAddr buffer
|
||||
}
|
||||
// Subtract the least significant 32 bits from the guest offset. The result is the storage
|
||||
// buffer offset in bytes.
|
||||
IR::U32 low_cbuf{ir.GetCbuf(ir.Imm32(buffer.index), ir.Imm32(buffer.offset))};
|
||||
|
||||
// Align the offset base to match the host alignment requirements
|
||||
low_cbuf = ir.BitwiseAnd(low_cbuf, ir.Imm32(~(alignment - 1U)));
|
||||
const IR::U32 low_cbuf{ir.GetCbuf(ir.Imm32(buffer.index), ir.Imm32(buffer.offset))};
|
||||
return ir.ISub(offset, low_cbuf);
|
||||
}
|
||||
|
||||
@@ -514,7 +510,7 @@ void Replace(IR::Block& block, IR::Inst& inst, const IR::U32& storage_index,
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
void GlobalMemoryToStorageBufferPass(IR::Program& program, const HostTranslateInfo& host_info) {
|
||||
void GlobalMemoryToStorageBufferPass(IR::Program& program) {
|
||||
StorageInfo info;
|
||||
for (IR::Block* const block : program.post_order_blocks) {
|
||||
for (IR::Inst& inst : block->Instructions()) {
|
||||
@@ -538,8 +534,7 @@ void GlobalMemoryToStorageBufferPass(IR::Program& program, const HostTranslateIn
|
||||
const IR::U32 index{IR::Value{static_cast<u32>(info.set.index_of(it))}};
|
||||
IR::Block* const block{storage_inst.block};
|
||||
IR::Inst* const inst{storage_inst.inst};
|
||||
const IR::U32 offset{
|
||||
StorageOffset(*block, *inst, storage_buffer, host_info.min_ssbo_alignment)};
|
||||
const IR::U32 offset{StorageOffset(*block, *inst, storage_buffer)};
|
||||
Replace(*block, *inst, index, offset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Shader::Optimization {
|
||||
void CollectShaderInfoPass(Environment& env, IR::Program& program);
|
||||
void ConstantPropagationPass(Environment& env, IR::Program& program);
|
||||
void DeadCodeEliminationPass(IR::Program& program);
|
||||
void GlobalMemoryToStorageBufferPass(IR::Program& program, const HostTranslateInfo& host_info);
|
||||
void GlobalMemoryToStorageBufferPass(IR::Program& program);
|
||||
void IdentityRemovalPass(IR::Program& program);
|
||||
void LowerFp16ToFp32(IR::Program& program);
|
||||
void LowerInt64ToInt32(IR::Program& program);
|
||||
|
||||
@@ -568,7 +568,7 @@ private:
|
||||
const u64* const state_words = Array<type>();
|
||||
const u64 num_query_words = size / BYTES_PER_WORD + 1;
|
||||
const u64 word_begin = offset / BYTES_PER_WORD;
|
||||
const u64 word_end = std::min(word_begin + num_query_words, NumWords());
|
||||
const u64 word_end = std::min<u64>(word_begin + num_query_words, NumWords());
|
||||
const u64 page_base = offset / BYTES_PER_PAGE;
|
||||
const u64 page_limit = Common::DivCeil(offset + size, BYTES_PER_PAGE);
|
||||
u64 begin = std::numeric_limits<u64>::max();
|
||||
|
||||
@@ -1938,21 +1938,14 @@ typename BufferCache<P>::Binding BufferCache<P>::StorageBufferBinding(GPUVAddr s
|
||||
bool is_written) const {
|
||||
const GPUVAddr gpu_addr = gpu_memory->Read<u64>(ssbo_addr);
|
||||
const u32 size = gpu_memory->Read<u32>(ssbo_addr + 8);
|
||||
const u32 alignment = runtime.GetStorageBufferAlignment();
|
||||
|
||||
const GPUVAddr aligned_gpu_addr = Common::AlignDown(gpu_addr, alignment);
|
||||
const u32 aligned_size =
|
||||
Common::AlignUp(static_cast<u32>(gpu_addr - aligned_gpu_addr) + size, alignment);
|
||||
|
||||
const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(aligned_gpu_addr);
|
||||
const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr);
|
||||
if (!cpu_addr || size == 0) {
|
||||
return NULL_BINDING;
|
||||
}
|
||||
|
||||
const VAddr cpu_end = Common::AlignUp(*cpu_addr + aligned_size, Core::Memory::YUZU_PAGESIZE);
|
||||
const VAddr cpu_end = Common::AlignUp(*cpu_addr + size, Core::Memory::YUZU_PAGESIZE);
|
||||
const Binding binding{
|
||||
.cpu_addr = *cpu_addr,
|
||||
.size = is_written ? aligned_size : static_cast<u32>(cpu_end - *cpu_addr),
|
||||
.size = is_written ? size : static_cast<u32>(cpu_end - *cpu_addr),
|
||||
.buffer_id = BufferId{},
|
||||
};
|
||||
return binding;
|
||||
|
||||
@@ -160,10 +160,6 @@ public:
|
||||
return device.CanReportMemoryUsage();
|
||||
}
|
||||
|
||||
u32 GetStorageBufferAlignment() const {
|
||||
return static_cast<u32>(device.GetShaderStorageBufferAlignment());
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr std::array PABO_LUT{
|
||||
GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV, GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV,
|
||||
|
||||
@@ -236,7 +236,6 @@ ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindo
|
||||
.needs_demote_reorder = device.IsAmd(),
|
||||
.support_snorm_render_buffer = false,
|
||||
.support_viewport_index_layer = device.HasVertexViewportLayer(),
|
||||
.min_ssbo_alignment = static_cast<u32>(device.GetShaderStorageBufferAlignment()),
|
||||
.support_geometry_shader_passthrough = device.HasGeometryShaderPassthrough(),
|
||||
} {
|
||||
if (use_asynchronous_shaders) {
|
||||
|
||||
@@ -330,10 +330,6 @@ bool BufferCacheRuntime::CanReportMemoryUsage() const {
|
||||
return device.CanReportMemoryUsage();
|
||||
}
|
||||
|
||||
u32 BufferCacheRuntime::GetStorageBufferAlignment() const {
|
||||
return static_cast<u32>(device.GetStorageBufferAlignment());
|
||||
}
|
||||
|
||||
void BufferCacheRuntime::Finish() {
|
||||
scheduler.Finish();
|
||||
}
|
||||
|
||||
@@ -73,8 +73,6 @@ public:
|
||||
|
||||
bool CanReportMemoryUsage() const;
|
||||
|
||||
u32 GetStorageBufferAlignment() const;
|
||||
|
||||
[[nodiscard]] StagingBufferRef UploadStagingBuffer(size_t size);
|
||||
|
||||
[[nodiscard]] StagingBufferRef DownloadStagingBuffer(size_t size);
|
||||
|
||||
@@ -344,7 +344,6 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device
|
||||
driver_id == VK_DRIVER_ID_AMD_PROPRIETARY || driver_id == VK_DRIVER_ID_AMD_OPEN_SOURCE,
|
||||
.support_snorm_render_buffer = true,
|
||||
.support_viewport_index_layer = device.IsExtShaderViewportIndexLayerSupported(),
|
||||
.min_ssbo_alignment = static_cast<u32>(device.GetStorageBufferAlignment()),
|
||||
.support_geometry_shader_passthrough = device.IsNvGeometryShaderPassthroughSupported(),
|
||||
};
|
||||
|
||||
|
||||
@@ -36,23 +36,18 @@ VkSurfaceFormatKHR ChooseSwapSurfaceFormat(vk::Span<VkSurfaceFormatKHR> formats)
|
||||
VkPresentModeKHR ChooseSwapPresentMode(vk::Span<VkPresentModeKHR> modes) {
|
||||
// Mailbox (triple buffering) doesn't lock the application like fifo (vsync),
|
||||
// prefer it if vsync option is not selected
|
||||
// AMD proprietary drivers can't render past the screen's refresh rate
|
||||
const auto found_mailbox = std::find(modes.begin(), modes.end(), VK_PRESENT_MODE_MAILBOX_KHR);
|
||||
const auto found_imm = std::find(modes.begin(), modes.end(), VK_PRESENT_MODE_IMMEDIATE_KHR);
|
||||
if (!Settings::values.use_speed_limit.GetValue() && found_imm != modes.end()) {
|
||||
return VK_PRESENT_MODE_IMMEDIATE_KHR;
|
||||
if (Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Borderless &&
|
||||
found_mailbox != modes.end() && !Settings::values.use_vsync.GetValue()) {
|
||||
return VK_PRESENT_MODE_MAILBOX_KHR;
|
||||
}
|
||||
if (Settings::values.use_vsync.GetValue()) {
|
||||
if (found_mailbox != modes.end()) {
|
||||
return VK_PRESENT_MODE_MAILBOX_KHR;
|
||||
}
|
||||
} else {
|
||||
if (!Settings::values.use_speed_limit.GetValue()) {
|
||||
// FIFO present mode locks the framerate to the monitor's refresh rate,
|
||||
// Find an alternative to surpass this limitation if FPS is unlocked.
|
||||
const auto found_imm = std::find(modes.begin(), modes.end(), VK_PRESENT_MODE_IMMEDIATE_KHR);
|
||||
if (found_imm != modes.end()) {
|
||||
return VK_PRESENT_MODE_IMMEDIATE_KHR;
|
||||
}
|
||||
if (found_mailbox != modes.end()) {
|
||||
return VK_PRESENT_MODE_MAILBOX_KHR;
|
||||
}
|
||||
}
|
||||
return VK_PRESENT_MODE_FIFO_KHR;
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ struct Client::Impl {
|
||||
const std::string& jwt_ = "", const std::string& username_ = "",
|
||||
const std::string& token_ = "") {
|
||||
if (cli == nullptr) {
|
||||
cli = std::make_unique<httplib::Client>(host.c_str());
|
||||
cli = std::make_unique<httplib::Client>(host);
|
||||
}
|
||||
|
||||
if (!cli->is_valid()) {
|
||||
|
||||
@@ -652,7 +652,10 @@ void GRenderWindow::mousePressEvent(QMouseEvent* event) {
|
||||
const auto [x, y] = ScaleTouch(pos);
|
||||
const auto [touch_x, touch_y] = MapToTouchScreen(x, y);
|
||||
const auto button = QtButtonToMouseButton(event->button());
|
||||
input_subsystem->GetMouse()->PressButton(x, y, touch_x, touch_y, button);
|
||||
|
||||
input_subsystem->GetMouse()->PressMouseButton(button);
|
||||
input_subsystem->GetMouse()->PressButton(pos.x(), pos.y(), button);
|
||||
input_subsystem->GetMouse()->PressTouchButton(touch_x, touch_y, button);
|
||||
|
||||
emit MouseActivity();
|
||||
}
|
||||
@@ -669,7 +672,10 @@ void GRenderWindow::mouseMoveEvent(QMouseEvent* event) {
|
||||
const auto [touch_x, touch_y] = MapToTouchScreen(x, y);
|
||||
const int center_x = width() / 2;
|
||||
const int center_y = height() / 2;
|
||||
input_subsystem->GetMouse()->MouseMove(x, y, touch_x, touch_y, center_x, center_y);
|
||||
|
||||
input_subsystem->GetMouse()->MouseMove(touch_x, touch_y);
|
||||
input_subsystem->GetMouse()->TouchMove(touch_x, touch_y);
|
||||
input_subsystem->GetMouse()->Move(pos.x(), pos.y(), center_x, center_y);
|
||||
|
||||
if (Settings::values.mouse_panning && !Settings::values.mouse_enabled) {
|
||||
QCursor::setPos(mapToGlobal(QPoint{center_x, center_y}));
|
||||
|
||||
@@ -147,6 +147,8 @@ public:
|
||||
|
||||
qreal windowPixelRatio() const;
|
||||
|
||||
std::pair<u32, u32> ScaleTouch(const QPointF& pos) const;
|
||||
|
||||
void closeEvent(QCloseEvent* event) override;
|
||||
|
||||
void resizeEvent(QResizeEvent* event) override;
|
||||
@@ -184,8 +186,6 @@ public:
|
||||
|
||||
void CaptureScreenshot(const QString& screenshot_path);
|
||||
|
||||
std::pair<u32, u32> ScaleTouch(const QPointF& pos) const;
|
||||
|
||||
/**
|
||||
* Instructs the window to re-launch the application using the specified program_index.
|
||||
* @param program_index Specifies the index within the application of the program to launch.
|
||||
|
||||
@@ -1490,7 +1490,7 @@ void ConfigureInputPlayer::mousePressEvent(QMouseEvent* event) {
|
||||
}
|
||||
|
||||
const auto button = GRenderWindow::QtButtonToMouseButton(event->button());
|
||||
input_subsystem->GetMouse()->PressButton(0, 0, 0, 0, button);
|
||||
input_subsystem->GetMouse()->PressButton(0, 0, button);
|
||||
}
|
||||
|
||||
void ConfigureInputPlayer::wheelEvent(QWheelEvent* event) {
|
||||
|
||||
@@ -371,7 +371,7 @@ void ConfigureRingController::mousePressEvent(QMouseEvent* event) {
|
||||
}
|
||||
|
||||
const auto button = GRenderWindow::QtButtonToMouseButton(event->button());
|
||||
input_subsystem->GetMouse()->PressButton(0, 0, 0, 0, button);
|
||||
input_subsystem->GetMouse()->PressButton(0, 0, button);
|
||||
}
|
||||
|
||||
void ConfigureRingController::keyPressEvent(QKeyEvent* event) {
|
||||
|
||||
@@ -75,8 +75,10 @@ void DiscordImpl::Update() {
|
||||
|
||||
// New Check for game cover
|
||||
httplib::Client cli(game_cover_url);
|
||||
cli.set_connection_timeout(std::chrono::seconds(3));
|
||||
cli.set_read_timeout(std::chrono::seconds(3));
|
||||
|
||||
if (auto res = cli.Head(fmt::format("/images/game/boxart/{}.png", icon_name).c_str())) {
|
||||
if (auto res = cli.Head(fmt::format("/images/game/boxart/{}.png", icon_name))) {
|
||||
if (res->status == 200) {
|
||||
game_cover_url += fmt::format("/images/game/boxart/{}.png", icon_name);
|
||||
} else {
|
||||
|
||||
@@ -1165,6 +1165,14 @@ void GMainWindow::InitializeHotkeys() {
|
||||
Settings::values.use_speed_limit.SetValue(!Settings::values.use_speed_limit.GetValue());
|
||||
});
|
||||
connect_shortcut(QStringLiteral("Toggle Mouse Panning"), [&] {
|
||||
if (Settings::values.mouse_enabled) {
|
||||
Settings::values.mouse_panning = false;
|
||||
QMessageBox::warning(
|
||||
this, tr("Emulated mouse is enabled"),
|
||||
tr("Real mouse input and mouse panning are incompatible. Please disable the "
|
||||
"emulated mouse in input advanced settings to allow mouse panning."));
|
||||
return;
|
||||
}
|
||||
Settings::values.mouse_panning = !Settings::values.mouse_panning;
|
||||
if (Settings::values.mouse_panning) {
|
||||
render_window->installEventFilter(render_window);
|
||||
|
||||
@@ -62,7 +62,9 @@ void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) {
|
||||
const auto mouse_button = SDLButtonToMouseButton(button);
|
||||
if (state == SDL_PRESSED) {
|
||||
const auto [touch_x, touch_y] = MouseToTouchPos(x, y);
|
||||
input_subsystem->GetMouse()->PressButton(x, y, touch_x, touch_y, mouse_button);
|
||||
input_subsystem->GetMouse()->PressButton(x, y, mouse_button);
|
||||
input_subsystem->GetMouse()->PressMouseButton(mouse_button);
|
||||
input_subsystem->GetMouse()->PressTouchButton(touch_x, touch_y, mouse_button);
|
||||
} else {
|
||||
input_subsystem->GetMouse()->ReleaseButton(mouse_button);
|
||||
}
|
||||
@@ -70,7 +72,9 @@ void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) {
|
||||
|
||||
void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) {
|
||||
const auto [touch_x, touch_y] = MouseToTouchPos(x, y);
|
||||
input_subsystem->GetMouse()->MouseMove(x, y, touch_x, touch_y, 0, 0);
|
||||
input_subsystem->GetMouse()->Move(x, y, 0, 0);
|
||||
input_subsystem->GetMouse()->MouseMove(touch_x, touch_y);
|
||||
input_subsystem->GetMouse()->TouchMove(touch_x, touch_y);
|
||||
}
|
||||
|
||||
void EmuWindow_SDL2::OnFingerDown(float x, float y, std::size_t id) {
|
||||
|
||||
Reference in New Issue
Block a user