Compare commits

...

25 Commits

Author SHA1 Message Date
Markus Wick d2d7a5060f externals: Update dynarmic.
The new version supports fastmem on a64.
2021-05-29 08:53:01 +02:00
bunnei 420b1f89d3 Merge pull request #6371 from degasus/drop_ExceptionalExit
core/arm_interface: Call SVC after end of dynarmic block.
2021-05-28 17:45:05 -07:00
bunnei 945effcc75 Merge pull request #6356 from ogniK5377/ApplyNpadSystemCommonPolicy
hid: ApplyNpadSystemCommonPolicy
2021-05-28 10:05:20 -07:00
Morph d25648cb6c Merge pull request #6375 from lioncash/iofs
common/fs/file: Default initialize IOFile members
2021-05-28 02:43:33 -04:00
Lioncash 210c2c9a56 common/fs/file: Explicitly delete copy constructors
Relocates them to the same place the move equivalents are at for
consistent viewing.
2021-05-28 01:49:40 -04:00
Lioncash 6806a893bd common/fs/file: Devirtualize destructor
IOFile is a final class, so there's no need for a virtual destructor.
2021-05-28 01:47:52 -04:00
Lioncash 019bc9f6b2 common/fs/file: Default initialize IOFile members
Prevents a potential uninitialized read vector in the move constructor.
2021-05-28 01:46:30 -04:00
bunnei 3289abe1cc Merge pull request #6372 from bunnei/raster-cache-fix
video_core: rasterizer_cache: Use u16 for cached page count.
2021-05-27 15:48:21 -07:00
bunnei 4b95b0df97 video_core: rasterizer_cache: Use u16 for cached page count.
- Greatly reduces the risk of overflow, at the cost of doubling the size of this array.
2021-05-27 14:47:24 -07:00
Markus Wick 3d2e80daed core/arm_interface: Call SVC after end of dynarmic block.
So we can modify all of dynarmic states within SVC without ExceptionalExit.

Especially as the ExceptionalExit hack is dropped on upstream dynarmic.
2021-05-27 23:23:23 +02:00
Mai M d825dff259 Merge pull request #6369 from lat9nq/cmake-fix-dep-opt
cmake: Fix usage of CMAKE_DEPENDENT_OPTION
2021-05-27 17:14:18 -04:00
Ameer J 9110cfdefb Merge pull request #6346 from lat9nq/apply-config-pgc
yuzu qt: Add an Apply button to configuration dialogs
2021-05-27 13:07:53 -04:00
lat9nq f94cb0bdb2 cmake: Fix usage of CMAKE_DEPENDENT_OPTION
CMAKE_DEPENDENT_OPTION takes a value argument, but as a macro function
it will read a variable name as the name and not the value. For
YUZU_USE_BUNDLED_QT, ensure that we are reading the value of MSVC. For
YUZU_ALLOW_SYSTEM_SDL2, CMAKE_DEPENDENT_OPTION is redundant here anyway
as we don't use that path on any toolchain by default.
2021-05-27 12:51:52 -04:00
Mai M 116989be8e Merge pull request #6366 from lat9nq/bundled-qt-linux
cmake: Download Qt binaries on Linux if needed
2021-05-26 18:19:02 -04:00
Mai M 2c791b38e6 Merge pull request #6365 from degasus/drop_ChangeProcessorID
core/arm: Drop ChangeProcessorID.
2021-05-26 18:16:54 -04:00
Markus Wick 993dbe49fc core/arm: Drop ChangeProcessorID.
This code was used to switch the CPU ID on thread switches.
However since "hle: kernel: multicore: Replace n-JITs impl. with 4 JITs.", the CPU ID is not a constant.
This has been dead code since this rewrite, and dropped in dynarmic as well. So there is no need to keep it.
2021-05-26 19:48:24 +02:00
Morph 02169406be Merge pull request #6331 from lioncash/gesture
hid/gesture: Simplify point related code
2021-05-26 09:19:00 -04:00
lat9nq c1bad4357a yuzu qt: Add an Apply button to configuration dialogs
Most of the code already exists to do this, but the Apply button itself
was never added. This adds a button and boolean that tells yuzu to save
the configuration after applying settings, even if close/Cancel is
pressed on the dialog. Changes after applying will not be saved when
Cancel is pressed, though.
2021-05-25 02:25:39 -04:00
Chloe Marcec db7abfecdd hid: ApplyNpadSystemCommonPolicy
We already do this specifically for homebrew, so we can keep it stubbed out for the time being
2021-05-24 15:07:47 +10:00
Lioncash 44556dc21a hid/gesture: Factor out last gesture retrieval into its own function
Deduplicates a commonly repeated expression.
2021-05-18 03:59:44 -04:00
Lioncash a9d8e24e47 hid/gesture: Ensure all ID arrays are initialized
Makes for deterministic initial state.
2021-05-18 03:39:21 -04:00
Lioncash 74f30c0223 hid/gesture: Make Point a template
We can now use this in a generic context to reuse it with the finger
position.
2021-05-18 03:39:18 -04:00
Lioncash 20699e90fa hid/gesture: Replace x,y members of GestureState with a Point
Simplifies assignments.
2021-05-18 03:32:42 -04:00
Lioncash 2f1ef3910b hid/gesture: Add default comparators to Point
Simplifies some comparisons.
2021-05-18 03:32:42 -04:00
Lioncash 60831eabd9 hid/gesture: Rename Points to Point
This only represents a single point
2021-05-18 03:32:38 -04:00
22 changed files with 220 additions and 145 deletions
+2 -2
View File
@@ -13,11 +13,11 @@ project(yuzu)
option(ENABLE_SDL2 "Enable the SDL2 frontend" ON)
CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 binaries" ON "ENABLE_SDL2;MSVC" OFF)
# On Linux system SDL2 is likely to be lacking HIDAPI support which have drawbacks but is needed for SDL motion
CMAKE_DEPENDENT_OPTION(YUZU_ALLOW_SYSTEM_SDL2 "Try using system SDL2 before fallling back to one from externals" NOT UNIX "ENABLE_SDL2" OFF)
option(YUZU_ALLOW_SYSTEM_SDL2 "Try using system SDL2 before fallling back to one from externals" OFF)
option(ENABLE_QT "Enable the Qt frontend" ON)
option(ENABLE_QT_TRANSLATION "Enable translations for the Qt frontend" OFF)
CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" MSVC "ENABLE_QT" OFF)
CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" "${MSVC}" "ENABLE_QT" OFF)
option(ENABLE_WEB_SERVICE "Enable web services (telemetry, etc.)" ON)
+7 -4
View File
@@ -117,7 +117,7 @@ template <typename Path>
}
#endif
class IOFile final : NonCopyable {
class IOFile final {
public:
IOFile();
@@ -142,7 +142,10 @@ public:
FileType type = FileType::BinaryFile,
FileShareFlag flag = FileShareFlag::ShareReadOnly);
virtual ~IOFile();
~IOFile();
IOFile(const IOFile&) = delete;
IOFile& operator=(const IOFile&) = delete;
IOFile(IOFile&& other) noexcept;
IOFile& operator=(IOFile&& other) noexcept;
@@ -441,8 +444,8 @@ public:
private:
std::filesystem::path file_path;
FileAccessMode file_access_mode;
FileType file_type;
FileAccessMode file_access_mode{};
FileType file_type{};
std::FILE* file = nullptr;
};
-5
View File
@@ -65,9 +65,6 @@ public:
/// Step CPU by one instruction
virtual void Step() = 0;
/// Exits execution from a callback, the callback must rewind the stack
virtual void ExceptionalExit() = 0;
/// Clear all instruction cache
virtual void ClearInstructionCache() = 0;
@@ -159,8 +156,6 @@ public:
*/
virtual void SetTPIDR_EL0(u64 value) = 0;
virtual void ChangeProcessorID(std::size_t new_core_id) = 0;
virtual void SaveContext(ThreadContext32& ctx) = 0;
virtual void SaveContext(ThreadContext64& ctx) = 0;
virtual void LoadContext(const ThreadContext32& ctx) = 0;
+18 -13
View File
@@ -4,9 +4,9 @@
#include <cinttypes>
#include <memory>
#include <dynarmic/A32/a32.h>
#include <dynarmic/A32/config.h>
#include <dynarmic/A32/context.h>
#include <dynarmic/interface/A32/a32.h>
#include <dynarmic/interface/A32/config.h>
#include <dynarmic/interface/A32/context.h>
#include "common/assert.h"
#include "common/logging/log.h"
#include "common/page_table.h"
@@ -78,7 +78,9 @@ public:
}
void CallSVC(u32 swi) override {
Kernel::Svc::Call(parent.system, swi);
parent.svc_called = true;
parent.svc_swi = swi;
parent.jit->HaltExecution();
}
void AddTicks(u64 ticks) override {
@@ -187,11 +189,17 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
}
void ARM_Dynarmic_32::Run() {
jit->Run();
}
void ARM_Dynarmic_32::ExceptionalExit() {
jit->ExceptionalExit();
while (true) {
jit->Run();
if (!svc_called) {
break;
}
svc_called = false;
Kernel::Svc::Call(system, svc_swi);
if (shutdown) {
break;
}
}
}
void ARM_Dynarmic_32::Step() {
@@ -255,10 +263,6 @@ void ARM_Dynarmic_32::SetTPIDR_EL0(u64 value) {
cp15->uprw = static_cast<u32>(value);
}
void ARM_Dynarmic_32::ChangeProcessorID(std::size_t new_core_id) {
jit->ChangeProcessorID(new_core_id);
}
void ARM_Dynarmic_32::SaveContext(ThreadContext32& ctx) {
Dynarmic::A32::Context context;
jit->SaveContext(context);
@@ -279,6 +283,7 @@ void ARM_Dynarmic_32::LoadContext(const ThreadContext32& ctx) {
void ARM_Dynarmic_32::PrepareReschedule() {
jit->HaltExecution();
shutdown = true;
}
void ARM_Dynarmic_32::ClearInstructionCache() {
+9 -5
View File
@@ -7,9 +7,9 @@
#include <memory>
#include <unordered_map>
#include <dynarmic/A32/a32.h>
#include <dynarmic/A64/a64.h>
#include <dynarmic/exclusive_monitor.h>
#include <dynarmic/interface/A32/a32.h>
#include <dynarmic/interface/A64/a64.h>
#include <dynarmic/interface/exclusive_monitor.h>
#include "common/common_types.h"
#include "common/hash.h"
#include "core/arm/arm_interface.h"
@@ -42,13 +42,11 @@ public:
u32 GetPSTATE() const override;
void SetPSTATE(u32 pstate) override;
void Run() override;
void ExceptionalExit() override;
void Step() override;
VAddr GetTlsAddress() const override;
void SetTlsAddress(VAddr address) override;
void SetTPIDR_EL0(u64 value) override;
u64 GetTPIDR_EL0() const override;
void ChangeProcessorID(std::size_t new_core_id) override;
bool IsInThumbMode() const {
return (GetPSTATE() & 0x20) != 0;
@@ -83,6 +81,12 @@ private:
std::size_t core_index;
DynarmicExclusiveMonitor& exclusive_monitor;
std::shared_ptr<Dynarmic::A32::Jit> jit;
// SVC callback
u32 svc_swi{};
bool svc_called{};
bool shutdown{};
};
} // namespace Core
+17 -12
View File
@@ -4,8 +4,8 @@
#include <cinttypes>
#include <memory>
#include <dynarmic/A64/a64.h>
#include <dynarmic/A64/config.h>
#include <dynarmic/interface/A64/a64.h>
#include <dynarmic/interface/A64/config.h>
#include "common/assert.h"
#include "common/logging/log.h"
#include "common/page_table.h"
@@ -102,7 +102,9 @@ public:
}
void CallSVC(u32 swi) override {
Kernel::Svc::Call(parent.system, swi);
parent.svc_called = true;
parent.svc_swi = swi;
parent.jit->HaltExecution();
}
void AddTicks(u64 ticks) override {
@@ -227,11 +229,17 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
}
void ARM_Dynarmic_64::Run() {
jit->Run();
}
void ARM_Dynarmic_64::ExceptionalExit() {
jit->ExceptionalExit();
while (true) {
jit->Run();
if (!svc_called) {
break;
}
svc_called = false;
Kernel::Svc::Call(system, svc_swi);
if (shutdown) {
break;
}
}
}
void ARM_Dynarmic_64::Step() {
@@ -296,10 +304,6 @@ void ARM_Dynarmic_64::SetTPIDR_EL0(u64 value) {
cb->tpidr_el0 = value;
}
void ARM_Dynarmic_64::ChangeProcessorID(std::size_t new_core_id) {
jit->ChangeProcessorID(new_core_id);
}
void ARM_Dynarmic_64::SaveContext(ThreadContext64& ctx) {
ctx.cpu_registers = jit->GetRegisters();
ctx.sp = jit->GetSP();
@@ -324,6 +328,7 @@ void ARM_Dynarmic_64::LoadContext(const ThreadContext64& ctx) {
void ARM_Dynarmic_64::PrepareReschedule() {
jit->HaltExecution();
shutdown = true;
}
void ARM_Dynarmic_64::ClearInstructionCache() {
+7 -3
View File
@@ -7,7 +7,7 @@
#include <memory>
#include <unordered_map>
#include <dynarmic/A64/a64.h>
#include <dynarmic/interface/A64/a64.h>
#include "common/common_types.h"
#include "common/hash.h"
#include "core/arm/arm_interface.h"
@@ -40,12 +40,10 @@ public:
void SetPSTATE(u32 pstate) override;
void Run() override;
void Step() override;
void ExceptionalExit() override;
VAddr GetTlsAddress() const override;
void SetTlsAddress(VAddr address) override;
void SetTPIDR_EL0(u64 value) override;
u64 GetTPIDR_EL0() const override;
void ChangeProcessorID(std::size_t new_core_id) override;
void SaveContext(ThreadContext32& ctx) override {}
void SaveContext(ThreadContext64& ctx) override;
@@ -76,6 +74,12 @@ private:
DynarmicExclusiveMonitor& exclusive_monitor;
std::shared_ptr<Dynarmic::A64::Jit> jit;
// SVC callback
u32 svc_swi{};
bool svc_called{};
bool shutdown{};
};
} // namespace Core
+1 -1
View File
@@ -7,7 +7,7 @@
#include <memory>
#include <optional>
#include <dynarmic/A32/coprocessor.h>
#include <dynarmic/interface/A32/coprocessor.h>
#include "common/common_types.h"
namespace Core {
@@ -7,7 +7,7 @@
#include <memory>
#include <unordered_map>
#include <dynarmic/exclusive_monitor.h>
#include <dynarmic/interface/exclusive_monitor.h>
#include "common/common_types.h"
#include "core/arm/dynarmic/arm_dynarmic_32.h"
-1
View File
@@ -659,7 +659,6 @@ void KScheduler::Unload(KThread* thread) {
if (thread) {
if (thread->IsCallingSvc()) {
system.ArmInterface(core_id).ExceptionalExit();
thread->ClearIsCallingSvc();
}
if (!thread->IsTerminationRequested()) {
@@ -91,8 +91,7 @@ bool Controller_Gesture::ShouldUpdateGesture(const GestureProperties& gesture,
// Update if coordinates change
for (size_t id = 0; id < MAX_POINTS; id++) {
if (gesture.points[id].x != last_gesture.points[id].x ||
gesture.points[id].y != last_gesture.points[id].y) {
if (gesture.points[id] != last_gesture.points[id]) {
return true;
}
}
@@ -124,8 +123,7 @@ void Controller_Gesture::UpdateGestureSharedMemory(u8* data, std::size_t size,
cur_entry.sampling_number2 = cur_entry.sampling_number;
// Reset values to default
cur_entry.delta_x = 0;
cur_entry.delta_y = 0;
cur_entry.delta = {};
cur_entry.vel_x = 0;
cur_entry.vel_y = 0;
cur_entry.direction = Direction::None;
@@ -146,13 +144,9 @@ void Controller_Gesture::UpdateGestureSharedMemory(u8* data, std::size_t size,
cur_entry.detection_count = gesture.detection_count;
cur_entry.type = type;
cur_entry.attributes = attributes;
cur_entry.x = gesture.mid_point.x;
cur_entry.y = gesture.mid_point.y;
cur_entry.pos = gesture.mid_point;
cur_entry.point_count = static_cast<s32>(gesture.active_points);
for (size_t id = 0; id < MAX_POINTS; id++) {
cur_entry.points[id].x = gesture.points[id].x;
cur_entry.points[id].y = gesture.points[id].y;
}
cur_entry.points = gesture.points;
last_gesture = gesture;
std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory));
@@ -160,8 +154,8 @@ void Controller_Gesture::UpdateGestureSharedMemory(u8* data, std::size_t size,
void Controller_Gesture::NewGesture(GestureProperties& gesture, TouchType& type,
Attribute& attributes) {
const auto& last_entry =
shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17];
const auto& last_entry = GetLastGestureEntry();
gesture.detection_count++;
type = TouchType::Touch;
@@ -174,13 +168,11 @@ void Controller_Gesture::NewGesture(GestureProperties& gesture, TouchType& type,
void Controller_Gesture::UpdateExistingGesture(GestureProperties& gesture, TouchType& type,
f32 time_difference) {
const auto& last_entry =
shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17];
const auto& last_entry = GetLastGestureEntry();
// Promote to pan type if touch moved
for (size_t id = 0; id < MAX_POINTS; id++) {
if (gesture.points[id].x != last_gesture.points[id].x ||
gesture.points[id].y != last_gesture.points[id].y) {
if (gesture.points[id] != last_gesture.points[id]) {
type = TouchType::Pan;
break;
}
@@ -192,10 +184,7 @@ void Controller_Gesture::UpdateExistingGesture(GestureProperties& gesture, Touch
enable_press_and_tap = false;
gesture.active_points = 0;
gesture.mid_point = {};
for (size_t id = 0; id < MAX_POINTS; id++) {
gesture.points[id].x = 0;
gesture.points[id].y = 0;
}
gesture.points.fill({});
return;
}
@@ -214,8 +203,8 @@ void Controller_Gesture::UpdateExistingGesture(GestureProperties& gesture, Touch
void Controller_Gesture::EndGesture(GestureProperties& gesture,
GestureProperties& last_gesture_props, TouchType& type,
Attribute& attributes, f32 time_difference) {
const auto& last_entry =
shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17];
const auto& last_entry = GetLastGestureEntry();
if (last_gesture_props.active_points != 0) {
switch (last_entry.type) {
case TouchType::Touch:
@@ -265,13 +254,11 @@ void Controller_Gesture::UpdatePanEvent(GestureProperties& gesture,
GestureProperties& last_gesture_props, TouchType& type,
f32 time_difference) {
auto& cur_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index];
const auto& last_entry =
shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17];
cur_entry.delta_x = gesture.mid_point.x - last_entry.x;
cur_entry.delta_y = gesture.mid_point.y - last_entry.y;
const auto& last_entry = GetLastGestureEntry();
cur_entry.vel_x = static_cast<f32>(cur_entry.delta_x) / time_difference;
cur_entry.vel_y = static_cast<f32>(cur_entry.delta_y) / time_difference;
cur_entry.delta = gesture.mid_point - last_entry.pos;
cur_entry.vel_x = static_cast<f32>(cur_entry.delta.x) / time_difference;
cur_entry.vel_y = static_cast<f32>(cur_entry.delta.y) / time_difference;
last_pan_time_difference = time_difference;
// Promote to pinch type
@@ -295,12 +282,11 @@ void Controller_Gesture::EndPanEvent(GestureProperties& gesture,
GestureProperties& last_gesture_props, TouchType& type,
f32 time_difference) {
auto& cur_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index];
const auto& last_entry =
shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17];
const auto& last_entry = GetLastGestureEntry();
cur_entry.vel_x =
static_cast<f32>(last_entry.delta_x) / (last_pan_time_difference + time_difference);
static_cast<f32>(last_entry.delta.x) / (last_pan_time_difference + time_difference);
cur_entry.vel_y =
static_cast<f32>(last_entry.delta_y) / (last_pan_time_difference + time_difference);
static_cast<f32>(last_entry.delta.y) / (last_pan_time_difference + time_difference);
const f32 curr_vel =
std::sqrt((cur_entry.vel_x * cur_entry.vel_x) + (cur_entry.vel_y * cur_entry.vel_y));
@@ -320,22 +306,22 @@ void Controller_Gesture::EndPanEvent(GestureProperties& gesture,
void Controller_Gesture::SetSwipeEvent(GestureProperties& gesture,
GestureProperties& last_gesture_props, TouchType& type) {
auto& cur_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index];
const auto& last_entry =
shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17];
const auto& last_entry = GetLastGestureEntry();
type = TouchType::Swipe;
gesture = last_gesture_props;
force_update = true;
cur_entry.delta_x = last_entry.delta_x;
cur_entry.delta_y = last_entry.delta_y;
if (std::abs(cur_entry.delta_x) > std::abs(cur_entry.delta_y)) {
if (cur_entry.delta_x > 0) {
cur_entry.delta = last_entry.delta;
if (std::abs(cur_entry.delta.x) > std::abs(cur_entry.delta.y)) {
if (cur_entry.delta.x > 0) {
cur_entry.direction = Direction::Right;
return;
}
cur_entry.direction = Direction::Left;
return;
}
if (cur_entry.delta_y > 0) {
if (cur_entry.delta.y > 0) {
cur_entry.direction = Direction::Down;
return;
}
@@ -364,6 +350,14 @@ std::optional<std::size_t> Controller_Gesture::GetUnusedFingerID() const {
return std::nullopt;
}
Controller_Gesture::GestureState& Controller_Gesture::GetLastGestureEntry() {
return shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17];
}
const Controller_Gesture::GestureState& Controller_Gesture::GetLastGestureEntry() const {
return shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17];
}
std::size_t Controller_Gesture::UpdateTouchInputEvent(
const std::tuple<float, float, bool>& touch_input, std::size_t finger_id) {
const auto& [x, y, pressed] = touch_input;
@@ -381,8 +375,7 @@ std::size_t Controller_Gesture::UpdateTouchInputEvent(
finger_id = first_free_id.value();
fingers[finger_id].pressed = true;
}
fingers[finger_id].x = x;
fingers[finger_id].y = y;
fingers[finger_id].pos = {x, y};
return finger_id;
}
@@ -402,17 +395,18 @@ Controller_Gesture::GestureProperties Controller_Gesture::GetGestureProperties()
static_cast<std::size_t>(std::distance(active_fingers.begin(), end_iter));
for (size_t id = 0; id < gesture.active_points; ++id) {
gesture.points[id].x =
static_cast<s32>(active_fingers[id].x * Layout::ScreenUndocked::Width);
gesture.points[id].y =
static_cast<s32>(active_fingers[id].y * Layout::ScreenUndocked::Height);
const auto& [active_x, active_y] = active_fingers[id].pos;
gesture.points[id] = {
.x = static_cast<s32>(active_x * Layout::ScreenUndocked::Width),
.y = static_cast<s32>(active_y * Layout::ScreenUndocked::Height),
};
// Hack: There is no touch in docked but games still allow it
if (Settings::values.use_docked_mode.GetValue()) {
gesture.points[id].x =
static_cast<s32>(active_fingers[id].x * Layout::ScreenDocked::Width);
gesture.points[id].y =
static_cast<s32>(active_fingers[id].y * Layout::ScreenDocked::Height);
gesture.points[id] = {
.x = static_cast<s32>(active_x * Layout::ScreenDocked::Width),
.y = static_cast<s32>(active_y * Layout::ScreenDocked::Height),
};
}
gesture.mid_point.x += static_cast<s32>(gesture.points[id].x / gesture.active_points);
+36 -18
View File
@@ -63,11 +63,28 @@ private:
};
static_assert(sizeof(Attribute) == 4, "Attribute is an invalid size");
struct Points {
s32_le x;
s32_le y;
template <typename T>
struct Point {
T x{};
T y{};
friend Point operator+(const Point& lhs, const Point& rhs) {
return {
.x = lhs.x + rhs.x,
.y = lhs.y + rhs.y,
};
}
friend Point operator-(const Point& lhs, const Point& rhs) {
return {
.x = lhs.x - rhs.x,
.y = lhs.y - rhs.y,
};
}
friend bool operator==(const Point&, const Point&) = default;
};
static_assert(sizeof(Points) == 8, "Points is an invalid size");
static_assert(sizeof(Point<s32_le>) == 8, "Point is an invalid size");
struct GestureState {
s64_le sampling_number;
@@ -75,17 +92,15 @@ private:
s64_le detection_count;
TouchType type;
Direction direction;
s32_le x;
s32_le y;
s32_le delta_x;
s32_le delta_y;
Point<s32_le> pos;
Point<s32_le> delta;
f32 vel_x;
f32 vel_y;
Attribute attributes;
f32 scale;
f32 rotation_angle;
s32_le point_count;
std::array<Points, 4> points;
std::array<Point<s32_le>, 4> points;
};
static_assert(sizeof(GestureState) == 0x68, "GestureState is an invalid size");
@@ -96,15 +111,14 @@ private:
static_assert(sizeof(SharedMemory) == 0x708, "SharedMemory is an invalid size");
struct Finger {
f32 x{};
f32 y{};
Point<f32> pos{};
bool pressed{};
};
struct GestureProperties {
std::array<Points, MAX_POINTS> points{};
std::array<Point<s32_le>, MAX_POINTS> points{};
std::size_t active_points{};
Points mid_point{};
Point<s32_le> mid_point{};
s64_le detection_count{};
u64_le delta_time{};
f32 average_distance{};
@@ -148,7 +162,11 @@ private:
TouchType& type);
// Returns an unused finger id, if there is no fingers available std::nullopt is returned.
std::optional<size_t> GetUnusedFingerID() const;
[[nodiscard]] std::optional<size_t> GetUnusedFingerID() const;
// Retrieves the last gesture entry, as indicated by shared memory indices.
[[nodiscard]] GestureState& GetLastGestureEntry();
[[nodiscard]] const GestureState& GetLastGestureEntry() const;
/**
* If the touch is new it tries to assign a new finger id, if there is no fingers available no
@@ -166,10 +184,10 @@ private:
std::unique_ptr<Input::TouchDevice> touch_mouse_device;
std::unique_ptr<Input::TouchDevice> touch_udp_device;
std::unique_ptr<Input::TouchDevice> touch_btn_device;
std::array<size_t, MAX_FINGERS> mouse_finger_id;
std::array<size_t, MAX_FINGERS> keyboard_finger_id;
std::array<size_t, MAX_FINGERS> udp_finger_id;
std::array<Finger, MAX_POINTS> fingers;
std::array<size_t, MAX_FINGERS> mouse_finger_id{};
std::array<size_t, MAX_FINGERS> keyboard_finger_id{};
std::array<size_t, MAX_FINGERS> udp_finger_id{};
std::array<Finger, MAX_POINTS> fingers{};
GestureProperties last_gesture{};
s64_le last_update_timestamp{};
s64_le last_tap_timestamp{};
+10 -1
View File
@@ -1770,7 +1770,7 @@ public:
{232, nullptr, "GetIrSensorState"},
{233, nullptr, "GetXcdHandleForNpadWithIrSensor"},
{301, nullptr, "ActivateNpadSystem"},
{303, nullptr, "ApplyNpadSystemCommonPolicy"},
{303, &HidSys::ApplyNpadSystemCommonPolicy, "ApplyNpadSystemCommonPolicy"},
{304, nullptr, "EnableAssigningSingleOnSlSrPress"},
{305, nullptr, "DisableAssigningSingleOnSlSrPress"},
{306, nullptr, "GetLastActiveNpad"},
@@ -1949,6 +1949,15 @@ public:
RegisterHandlers(functions);
}
private:
void ApplyNpadSystemCommonPolicy(Kernel::HLERequestContext& ctx) {
// We already do this for homebrew so we can just stub it out
LOG_WARNING(Service_HID, "called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
};
class HidTmp final : public ServiceFramework<HidTmp> {
+3 -3
View File
@@ -18,10 +18,10 @@ RasterizerAccelerated::~RasterizerAccelerated() = default;
void RasterizerAccelerated::UpdatePagesCachedCount(VAddr addr, u64 size, int delta) {
const auto page_end = Common::DivCeil(addr + size, Core::Memory::PAGE_SIZE);
for (auto page = addr >> Core::Memory::PAGE_BITS; page != page_end; ++page) {
auto& count = cached_pages.at(page >> 3).Count(page);
auto& count = cached_pages.at(page >> 2).Count(page);
if (delta > 0) {
ASSERT_MSG(count < UINT8_MAX, "Count may overflow!");
ASSERT_MSG(count < UINT16_MAX, "Count may overflow!");
} else if (delta < 0) {
ASSERT_MSG(count > 0, "Count may underflow!");
} else {
@@ -29,7 +29,7 @@ void RasterizerAccelerated::UpdatePagesCachedCount(VAddr addr, u64 size, int del
}
// Adds or subtracts 1, as count is a unsigned 8-bit value
count += static_cast<u8>(delta);
count += static_cast<u16>(delta);
// Assume delta is either -1 or 1
if (count == 0) {
+6 -6
View File
@@ -29,20 +29,20 @@ private:
public:
CacheEntry() = default;
std::atomic_uint8_t& Count(std::size_t page) {
return values[page & 7];
std::atomic_uint16_t& Count(std::size_t page) {
return values[page & 3];
}
const std::atomic_uint8_t& Count(std::size_t page) const {
return values[page & 7];
const std::atomic_uint16_t& Count(std::size_t page) const {
return values[page & 3];
}
private:
std::array<std::atomic_uint8_t, 8> values{};
std::array<std::atomic_uint16_t, 4> values{};
};
static_assert(sizeof(CacheEntry) == 8, "CacheEntry should be 8 bytes!");
std::array<CacheEntry, 0x800000> cached_pages;
std::array<CacheEntry, 0x1000000> cached_pages;
Core::Memory::Memory& cpu_memory;
};
@@ -2,8 +2,11 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <QAbstractButton>
#include <QDialogButtonBox>
#include <QHash>
#include <QListWidgetItem>
#include <QPushButton>
#include <QSignalBlocker>
#include "common/settings.h"
#include "core/core.h"
@@ -31,6 +34,12 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry,
connect(ui->selectorList, &QListWidget::itemSelectionChanged, this,
&ConfigureDialog::UpdateVisibleTabs);
if (Core::System::GetInstance().IsPoweredOn()) {
QPushButton* apply_button = ui->buttonBox->addButton(QDialogButtonBox::Apply);
connect(apply_button, &QAbstractButton::clicked, this,
&ConfigureDialog::HandleApplyButtonClicked);
}
adjustSize();
ui->selectorList->setCurrentRow(0);
}
@@ -80,6 +89,11 @@ void ConfigureDialog::RetranslateUI() {
ui->tabWidget->setCurrentIndex(old_index);
}
void ConfigureDialog::HandleApplyButtonClicked() {
UISettings::values.configuration_applied = true;
ApplyConfiguration();
}
Q_DECLARE_METATYPE(QList<QWidget*>);
void ConfigureDialog::PopulateSelectionList() {
+2 -1
View File
@@ -35,9 +35,10 @@ signals:
private:
void changeEvent(QEvent* event) override;
void RetranslateUI();
void HandleApplyButtonClicked();
void SetConfiguration();
void UpdateVisibleTabs();
void PopulateSelectionList();
@@ -6,9 +6,12 @@
#include <memory>
#include <utility>
#include <QAbstractButton>
#include <QCheckBox>
#include <QDialogButtonBox>
#include <QHeaderView>
#include <QMenu>
#include <QPushButton>
#include <QStandardItemModel>
#include <QString>
#include <QTimer>
@@ -42,6 +45,12 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id)
scene = new QGraphicsScene;
ui->icon_view->setScene(scene);
if (Core::System::GetInstance().IsPoweredOn()) {
QPushButton* apply_button = ui->buttonBox->addButton(QDialogButtonBox::Apply);
connect(apply_button, &QAbstractButton::clicked, this,
&ConfigurePerGame::HandleApplyButtonClicked);
}
LoadConfiguration();
}
@@ -74,6 +83,11 @@ void ConfigurePerGame::RetranslateUI() {
ui->retranslateUi(this);
}
void ConfigurePerGame::HandleApplyButtonClicked() {
UISettings::values.configuration_applied = true;
ApplyConfiguration();
}
void ConfigurePerGame::LoadFromFile(FileSys::VirtualFile file) {
this->file = std::move(file);
LoadConfiguration();
@@ -39,6 +39,8 @@ private:
void changeEvent(QEvent* event) override;
void RetranslateUI();
void HandleApplyButtonClicked();
void LoadConfiguration();
std::unique_ptr<Ui::ConfigurePerGame> ui;
+25 -19
View File
@@ -2587,12 +2587,12 @@ void GMainWindow::OnConfigure() {
&GMainWindow::OnLanguageChanged);
const auto result = configure_dialog.exec();
if (result != QDialog::Accepted) {
if (result != QDialog::Accepted && !UISettings::values.configuration_applied) {
return;
} else if (result == QDialog::Accepted) {
configure_dialog.ApplyConfiguration();
controller_dialog->refreshConfiguration();
}
configure_dialog.ApplyConfiguration();
controller_dialog->refreshConfiguration();
InitializeHotkeys();
if (UISettings::values.theme != old_theme) {
UpdateUITheme();
@@ -2607,6 +2607,8 @@ void GMainWindow::OnConfigure() {
game_list->PopulateAsync(UISettings::values.game_dirs);
}
UISettings::values.configuration_applied = false;
config->Save();
if ((UISettings::values.hide_mouse || Settings::values.mouse_panning) && emulation_running) {
@@ -2636,23 +2638,27 @@ void GMainWindow::OpenPerGameConfiguration(u64 title_id, const std::string& file
ConfigurePerGame dialog(this, title_id);
dialog.LoadFromFile(v_file);
const auto result = dialog.exec();
if (result == QDialog::Accepted) {
dialog.ApplyConfiguration();
const auto reload = UISettings::values.is_game_list_reload_pending.exchange(false);
if (reload) {
game_list->PopulateAsync(UISettings::values.game_dirs);
}
// Do not cause the global config to write local settings into the config file
const bool is_powered_on = system.IsPoweredOn();
Settings::RestoreGlobalState(is_powered_on);
if (!is_powered_on) {
config->Save();
}
} else {
if (result != QDialog::Accepted && !UISettings::values.configuration_applied) {
Settings::RestoreGlobalState(system.IsPoweredOn());
return;
} else if (result == QDialog::Accepted) {
dialog.ApplyConfiguration();
}
const auto reload = UISettings::values.is_game_list_reload_pending.exchange(false);
if (reload) {
game_list->PopulateAsync(UISettings::values.game_dirs);
}
// Do not cause the global config to write local settings into the config file
const bool is_powered_on = system.IsPoweredOn();
Settings::RestoreGlobalState(is_powered_on);
UISettings::values.configuration_applied = false;
if (!is_powered_on) {
config->Save();
}
}
+2
View File
@@ -95,6 +95,8 @@ struct Values {
uint8_t row_2_text_id;
std::atomic_bool is_game_list_reload_pending{false};
bool cache_game_list;
bool configuration_applied;
};
extern Values values;