diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/fiber.cpp | 2 | ||||
| -rw-r--r-- | src/core/file_sys/system_archive/ng_word.cpp | 4 | ||||
| -rw-r--r-- | src/core/file_sys/system_archive/system_version.cpp | 10 | ||||
| -rw-r--r-- | src/core/hle/service/sockets/bsd.cpp | 8 | ||||
| -rw-r--r-- | src/core/hle/service/time/time.cpp | 14 | ||||
| -rw-r--r-- | src/input_common/keyboard.cpp | 31 | ||||
| -rw-r--r-- | src/input_common/mouse/mouse_input.cpp | 36 | ||||
| -rw-r--r-- | src/input_common/mouse/mouse_input.h | 5 | ||||
| -rw-r--r-- | src/input_common/mouse/mouse_poller.cpp | 20 | ||||
| -rw-r--r-- | src/video_core/rasterizer_accelerated.cpp | 62 | ||||
| -rw-r--r-- | src/video_core/rasterizer_accelerated.h | 25 | ||||
| -rw-r--r-- | src/yuzu/bootmanager.cpp | 8 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_input_player.cpp | 21 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 9 |
14 files changed, 183 insertions, 72 deletions
diff --git a/src/common/fiber.cpp b/src/common/fiber.cpp index 39532ff58..62010d762 100644 --- a/src/common/fiber.cpp +++ b/src/common/fiber.cpp | |||
| @@ -11,7 +11,7 @@ | |||
| 11 | 11 | ||
| 12 | namespace Common { | 12 | namespace Common { |
| 13 | 13 | ||
| 14 | constexpr std::size_t default_stack_size = 256 * 1024; | 14 | constexpr std::size_t default_stack_size = 512 * 1024; |
| 15 | 15 | ||
| 16 | struct Fiber::FiberImpl { | 16 | struct Fiber::FiberImpl { |
| 17 | FiberImpl() : stack{default_stack_size}, rewind_stack{default_stack_size} {} | 17 | FiberImpl() : stack{default_stack_size}, rewind_stack{default_stack_size} {} |
diff --git a/src/core/file_sys/system_archive/ng_word.cpp b/src/core/file_sys/system_archive/ng_word.cpp index 100d3c5db..8d86d563a 100644 --- a/src/core/file_sys/system_archive/ng_word.cpp +++ b/src/core/file_sys/system_archive/ng_word.cpp | |||
| @@ -14,7 +14,7 @@ namespace NgWord1Data { | |||
| 14 | constexpr std::size_t NUMBER_WORD_TXT_FILES = 0x10; | 14 | constexpr std::size_t NUMBER_WORD_TXT_FILES = 0x10; |
| 15 | 15 | ||
| 16 | // Should this archive replacement mysteriously not work on a future game, consider updating. | 16 | // Should this archive replacement mysteriously not work on a future game, consider updating. |
| 17 | constexpr std::array<u8, 4> VERSION_DAT{0x0, 0x0, 0x0, 0x19}; // 5.1.0 System Version | 17 | constexpr std::array<u8, 4> VERSION_DAT{0x0, 0x0, 0x0, 0x20}; // 11.0.1 System Version |
| 18 | 18 | ||
| 19 | constexpr std::array<u8, 30> WORD_TXT{ | 19 | constexpr std::array<u8, 30> WORD_TXT{ |
| 20 | 0xFE, 0xFF, 0x00, 0x5E, 0x00, 0x76, 0x00, 0x65, 0x00, 0x72, 0x00, 0x79, 0x00, 0x62, 0x00, | 20 | 0xFE, 0xFF, 0x00, 0x5E, 0x00, 0x76, 0x00, 0x65, 0x00, 0x72, 0x00, 0x79, 0x00, 0x62, 0x00, |
| @@ -43,7 +43,7 @@ namespace NgWord2Data { | |||
| 43 | constexpr std::size_t NUMBER_AC_NX_FILES = 0x10; | 43 | constexpr std::size_t NUMBER_AC_NX_FILES = 0x10; |
| 44 | 44 | ||
| 45 | // Should this archive replacement mysteriously not work on a future game, consider updating. | 45 | // Should this archive replacement mysteriously not work on a future game, consider updating. |
| 46 | constexpr std::array<u8, 4> VERSION_DAT{0x0, 0x0, 0x0, 0x15}; // 5.1.0 System Version | 46 | constexpr std::array<u8, 4> VERSION_DAT{0x0, 0x0, 0x0, 0x1A}; // 11.0.1 System Version |
| 47 | 47 | ||
| 48 | constexpr std::array<u8, 0x2C> AC_NX_DATA{ | 48 | constexpr std::array<u8, 0x2C> AC_NX_DATA{ |
| 49 | 0x1F, 0x8B, 0x08, 0x08, 0xD5, 0x2C, 0x09, 0x5C, 0x04, 0x00, 0x61, 0x63, 0x72, 0x61, 0x77, | 49 | 0x1F, 0x8B, 0x08, 0x08, 0xD5, 0x2C, 0x09, 0x5C, 0x04, 0x00, 0x61, 0x63, 0x72, 0x61, 0x77, |
diff --git a/src/core/file_sys/system_archive/system_version.cpp b/src/core/file_sys/system_archive/system_version.cpp index 7bfbc9a67..54704105b 100644 --- a/src/core/file_sys/system_archive/system_version.cpp +++ b/src/core/file_sys/system_archive/system_version.cpp | |||
| @@ -14,15 +14,15 @@ namespace SystemVersionData { | |||
| 14 | 14 | ||
| 15 | constexpr u8 VERSION_MAJOR = 11; | 15 | constexpr u8 VERSION_MAJOR = 11; |
| 16 | constexpr u8 VERSION_MINOR = 0; | 16 | constexpr u8 VERSION_MINOR = 0; |
| 17 | constexpr u8 VERSION_MICRO = 0; | 17 | constexpr u8 VERSION_MICRO = 1; |
| 18 | 18 | ||
| 19 | constexpr u8 REVISION_MAJOR = 5; | 19 | constexpr u8 REVISION_MAJOR = 1; |
| 20 | constexpr u8 REVISION_MINOR = 0; | 20 | constexpr u8 REVISION_MINOR = 0; |
| 21 | 21 | ||
| 22 | constexpr char PLATFORM_STRING[] = "NX"; | 22 | constexpr char PLATFORM_STRING[] = "NX"; |
| 23 | constexpr char VERSION_HASH[] = "34197eba8810e2edd5e9dfcfbde7b340882e856d"; | 23 | constexpr char VERSION_HASH[] = "69103fcb2004dace877094c2f8c29e6113be5dbf"; |
| 24 | constexpr char DISPLAY_VERSION[] = "11.0.0"; | 24 | constexpr char DISPLAY_VERSION[] = "11.0.1"; |
| 25 | constexpr char DISPLAY_TITLE[] = "NintendoSDK Firmware for NX 11.0.0-5.0"; | 25 | constexpr char DISPLAY_TITLE[] = "NintendoSDK Firmware for NX 11.0.1-1.0"; |
| 26 | 26 | ||
| 27 | } // namespace SystemVersionData | 27 | } // namespace SystemVersionData |
| 28 | 28 | ||
diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp index 78e9cd708..5fcd91f68 100644 --- a/src/core/hle/service/sockets/bsd.cpp +++ b/src/core/hle/service/sockets/bsd.cpp | |||
| @@ -42,7 +42,9 @@ void BSD::PollWork::Execute(BSD* bsd) { | |||
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | void BSD::PollWork::Response(Kernel::HLERequestContext& ctx) { | 44 | void BSD::PollWork::Response(Kernel::HLERequestContext& ctx) { |
| 45 | ctx.WriteBuffer(write_buffer); | 45 | if (write_buffer.size() > 0) { |
| 46 | ctx.WriteBuffer(write_buffer); | ||
| 47 | } | ||
| 46 | 48 | ||
| 47 | IPC::ResponseBuilder rb{ctx, 4}; | 49 | IPC::ResponseBuilder rb{ctx, 4}; |
| 48 | rb.Push(RESULT_SUCCESS); | 50 | rb.Push(RESULT_SUCCESS); |
| @@ -55,7 +57,9 @@ void BSD::AcceptWork::Execute(BSD* bsd) { | |||
| 55 | } | 57 | } |
| 56 | 58 | ||
| 57 | void BSD::AcceptWork::Response(Kernel::HLERequestContext& ctx) { | 59 | void BSD::AcceptWork::Response(Kernel::HLERequestContext& ctx) { |
| 58 | ctx.WriteBuffer(write_buffer); | 60 | if (write_buffer.size() > 0) { |
| 61 | ctx.WriteBuffer(write_buffer); | ||
| 62 | } | ||
| 59 | 63 | ||
| 60 | IPC::ResponseBuilder rb{ctx, 5}; | 64 | IPC::ResponseBuilder rb{ctx, 5}; |
| 61 | rb.Push(RESULT_SUCCESS); | 65 | rb.Push(RESULT_SUCCESS); |
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index 18629dd7e..78543688f 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp | |||
| @@ -140,6 +140,8 @@ ResultCode Module::Interface::GetClockSnapshotFromSystemClockContextInternal( | |||
| 140 | 140 | ||
| 141 | const auto current_time_point{ | 141 | const auto current_time_point{ |
| 142 | time_manager.GetStandardSteadyClockCore().GetCurrentTimePoint(system)}; | 142 | time_manager.GetStandardSteadyClockCore().GetCurrentTimePoint(system)}; |
| 143 | clock_snapshot.steady_clock_time_point = current_time_point; | ||
| 144 | |||
| 143 | if (const ResultCode result{Clock::ClockSnapshot::GetCurrentTime( | 145 | if (const ResultCode result{Clock::ClockSnapshot::GetCurrentTime( |
| 144 | clock_snapshot.user_time, current_time_point, clock_snapshot.user_context)}; | 146 | clock_snapshot.user_time, current_time_point, clock_snapshot.user_context)}; |
| 145 | result != RESULT_SUCCESS) { | 147 | result != RESULT_SUCCESS) { |
| @@ -341,12 +343,18 @@ void Module::Interface::CalculateStandardUserSystemClockDifferenceByUser( | |||
| 341 | void Module::Interface::CalculateSpanBetween(Kernel::HLERequestContext& ctx) { | 343 | void Module::Interface::CalculateSpanBetween(Kernel::HLERequestContext& ctx) { |
| 342 | LOG_DEBUG(Service_Time, "called"); | 344 | LOG_DEBUG(Service_Time, "called"); |
| 343 | 345 | ||
| 344 | IPC::RequestParser rp{ctx}; | 346 | Clock::ClockSnapshot snapshot_a; |
| 345 | const auto snapshot_a = rp.PopRaw<Clock::ClockSnapshot>(); | 347 | Clock::ClockSnapshot snapshot_b; |
| 346 | const auto snapshot_b = rp.PopRaw<Clock::ClockSnapshot>(); | 348 | |
| 349 | const auto snapshot_a_data = ctx.ReadBuffer(0); | ||
| 350 | const auto snapshot_b_data = ctx.ReadBuffer(1); | ||
| 351 | |||
| 352 | std::memcpy(&snapshot_a, snapshot_a_data.data(), sizeof(Clock::ClockSnapshot)); | ||
| 353 | std::memcpy(&snapshot_b, snapshot_b_data.data(), sizeof(Clock::ClockSnapshot)); | ||
| 347 | 354 | ||
| 348 | Clock::TimeSpanType time_span_type{}; | 355 | Clock::TimeSpanType time_span_type{}; |
| 349 | s64 span{}; | 356 | s64 span{}; |
| 357 | |||
| 350 | if (const ResultCode result{snapshot_a.steady_clock_time_point.GetSpanBetween( | 358 | if (const ResultCode result{snapshot_a.steady_clock_time_point.GetSpanBetween( |
| 351 | snapshot_b.steady_clock_time_point, span)}; | 359 | snapshot_b.steady_clock_time_point, span)}; |
| 352 | result != RESULT_SUCCESS) { | 360 | result != RESULT_SUCCESS) { |
diff --git a/src/input_common/keyboard.cpp b/src/input_common/keyboard.cpp index 24a6f7a33..c467ff4c5 100644 --- a/src/input_common/keyboard.cpp +++ b/src/input_common/keyboard.cpp | |||
| @@ -12,20 +12,39 @@ namespace InputCommon { | |||
| 12 | 12 | ||
| 13 | class KeyButton final : public Input::ButtonDevice { | 13 | class KeyButton final : public Input::ButtonDevice { |
| 14 | public: | 14 | public: |
| 15 | explicit KeyButton(std::shared_ptr<KeyButtonList> key_button_list_) | 15 | explicit KeyButton(std::shared_ptr<KeyButtonList> key_button_list_, bool toggle_) |
| 16 | : key_button_list(std::move(key_button_list_)) {} | 16 | : key_button_list(std::move(key_button_list_)), toggle(toggle_) {} |
| 17 | 17 | ||
| 18 | ~KeyButton() override; | 18 | ~KeyButton() override; |
| 19 | 19 | ||
| 20 | bool GetStatus() const override { | 20 | bool GetStatus() const override { |
| 21 | if (toggle) { | ||
| 22 | return toggled_status.load(std::memory_order_relaxed); | ||
| 23 | } | ||
| 21 | return status.load(); | 24 | return status.load(); |
| 22 | } | 25 | } |
| 23 | 26 | ||
| 27 | void ToggleButton() { | ||
| 28 | if (lock) { | ||
| 29 | return; | ||
| 30 | } | ||
| 31 | lock = true; | ||
| 32 | const bool old_toggle_status = toggled_status.load(); | ||
| 33 | toggled_status.store(!old_toggle_status); | ||
| 34 | } | ||
| 35 | |||
| 36 | void UnlockButton() { | ||
| 37 | lock = false; | ||
| 38 | } | ||
| 39 | |||
| 24 | friend class KeyButtonList; | 40 | friend class KeyButtonList; |
| 25 | 41 | ||
| 26 | private: | 42 | private: |
| 27 | std::shared_ptr<KeyButtonList> key_button_list; | 43 | std::shared_ptr<KeyButtonList> key_button_list; |
| 28 | std::atomic<bool> status{false}; | 44 | std::atomic<bool> status{false}; |
| 45 | std::atomic<bool> toggled_status{false}; | ||
| 46 | bool lock{false}; | ||
| 47 | const bool toggle; | ||
| 29 | }; | 48 | }; |
| 30 | 49 | ||
| 31 | struct KeyButtonPair { | 50 | struct KeyButtonPair { |
| @@ -51,6 +70,11 @@ public: | |||
| 51 | for (const KeyButtonPair& pair : list) { | 70 | for (const KeyButtonPair& pair : list) { |
| 52 | if (pair.key_code == key_code) { | 71 | if (pair.key_code == key_code) { |
| 53 | pair.key_button->status.store(pressed); | 72 | pair.key_button->status.store(pressed); |
| 73 | if (pressed) { | ||
| 74 | pair.key_button->ToggleButton(); | ||
| 75 | } else { | ||
| 76 | pair.key_button->UnlockButton(); | ||
| 77 | } | ||
| 54 | } | 78 | } |
| 55 | } | 79 | } |
| 56 | } | 80 | } |
| @@ -75,7 +99,8 @@ KeyButton::~KeyButton() { | |||
| 75 | 99 | ||
| 76 | std::unique_ptr<Input::ButtonDevice> Keyboard::Create(const Common::ParamPackage& params) { | 100 | std::unique_ptr<Input::ButtonDevice> Keyboard::Create(const Common::ParamPackage& params) { |
| 77 | const int key_code = params.Get("code", 0); | 101 | const int key_code = params.Get("code", 0); |
| 78 | std::unique_ptr<KeyButton> button = std::make_unique<KeyButton>(key_button_list); | 102 | const bool toggle = params.Get("toggle", false); |
| 103 | std::unique_ptr<KeyButton> button = std::make_unique<KeyButton>(key_button_list, toggle); | ||
| 79 | key_button_list->AddKeyButton(key_code, button.get()); | 104 | key_button_list->AddKeyButton(key_code, button.get()); |
| 80 | return button; | 105 | return button; |
| 81 | } | 106 | } |
diff --git a/src/input_common/mouse/mouse_input.cpp b/src/input_common/mouse/mouse_input.cpp index d81e790ee..329e416c7 100644 --- a/src/input_common/mouse/mouse_input.cpp +++ b/src/input_common/mouse/mouse_input.cpp | |||
| @@ -162,6 +162,42 @@ void Mouse::EndConfiguration() { | |||
| 162 | configuring = false; | 162 | configuring = false; |
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | bool Mouse::ToggleButton(std::size_t button_) { | ||
| 166 | if (button_ >= mouse_info.size()) { | ||
| 167 | return false; | ||
| 168 | } | ||
| 169 | const auto button = 1U << button_; | ||
| 170 | const bool button_state = (toggle_buttons & button) != 0; | ||
| 171 | const bool button_lock = (lock_buttons & button) != 0; | ||
| 172 | |||
| 173 | if (button_lock) { | ||
| 174 | return button_state; | ||
| 175 | } | ||
| 176 | |||
| 177 | lock_buttons |= static_cast<u16>(button); | ||
| 178 | |||
| 179 | if (button_state) { | ||
| 180 | toggle_buttons &= static_cast<u16>(0xFF - button); | ||
| 181 | } else { | ||
| 182 | toggle_buttons |= static_cast<u16>(button); | ||
| 183 | } | ||
| 184 | |||
| 185 | return !button_state; | ||
| 186 | } | ||
| 187 | |||
| 188 | bool Mouse::UnlockButton(std::size_t button_) { | ||
| 189 | if (button_ >= mouse_info.size()) { | ||
| 190 | return false; | ||
| 191 | } | ||
| 192 | |||
| 193 | const auto button = 1U << button_; | ||
| 194 | const bool button_state = (toggle_buttons & button) != 0; | ||
| 195 | |||
| 196 | lock_buttons &= static_cast<u16>(0xFF - button); | ||
| 197 | |||
| 198 | return button_state; | ||
| 199 | } | ||
| 200 | |||
| 165 | Common::SPSCQueue<MouseStatus>& Mouse::GetMouseQueue() { | 201 | Common::SPSCQueue<MouseStatus>& Mouse::GetMouseQueue() { |
| 166 | return mouse_queue; | 202 | return mouse_queue; |
| 167 | } | 203 | } |
diff --git a/src/input_common/mouse/mouse_input.h b/src/input_common/mouse/mouse_input.h index 3622fe080..750d9b011 100644 --- a/src/input_common/mouse/mouse_input.h +++ b/src/input_common/mouse/mouse_input.h | |||
| @@ -69,6 +69,9 @@ public: | |||
| 69 | */ | 69 | */ |
| 70 | void ReleaseButton(MouseButton button_); | 70 | void ReleaseButton(MouseButton button_); |
| 71 | 71 | ||
| 72 | [[nodiscard]] bool ToggleButton(std::size_t button_); | ||
| 73 | [[nodiscard]] bool UnlockButton(std::size_t button_); | ||
| 74 | |||
| 72 | [[nodiscard]] Common::SPSCQueue<MouseStatus>& GetMouseQueue(); | 75 | [[nodiscard]] Common::SPSCQueue<MouseStatus>& GetMouseQueue(); |
| 73 | [[nodiscard]] const Common::SPSCQueue<MouseStatus>& GetMouseQueue() const; | 76 | [[nodiscard]] const Common::SPSCQueue<MouseStatus>& GetMouseQueue() const; |
| 74 | 77 | ||
| @@ -94,6 +97,8 @@ private: | |||
| 94 | }; | 97 | }; |
| 95 | 98 | ||
| 96 | u16 buttons{}; | 99 | u16 buttons{}; |
| 100 | u16 toggle_buttons{}; | ||
| 101 | u16 lock_buttons{}; | ||
| 97 | std::thread update_thread; | 102 | std::thread update_thread; |
| 98 | MouseButton last_button{MouseButton::Undefined}; | 103 | MouseButton last_button{MouseButton::Undefined}; |
| 99 | std::array<MouseInfo, 7> mouse_info; | 104 | std::array<MouseInfo, 7> mouse_info; |
diff --git a/src/input_common/mouse/mouse_poller.cpp b/src/input_common/mouse/mouse_poller.cpp index bb56787ee..0e1db54fb 100644 --- a/src/input_common/mouse/mouse_poller.cpp +++ b/src/input_common/mouse/mouse_poller.cpp | |||
| @@ -14,16 +14,25 @@ namespace InputCommon { | |||
| 14 | 14 | ||
| 15 | class MouseButton final : public Input::ButtonDevice { | 15 | class MouseButton final : public Input::ButtonDevice { |
| 16 | public: | 16 | public: |
| 17 | explicit MouseButton(u32 button_, const MouseInput::Mouse* mouse_input_) | 17 | explicit MouseButton(u32 button_, bool toggle_, MouseInput::Mouse* mouse_input_) |
| 18 | : button(button_), mouse_input(mouse_input_) {} | 18 | : button(button_), toggle(toggle_), mouse_input(mouse_input_) {} |
| 19 | 19 | ||
| 20 | bool GetStatus() const override { | 20 | bool GetStatus() const override { |
| 21 | return mouse_input->GetMouseState(button).pressed; | 21 | const bool button_state = mouse_input->GetMouseState(button).pressed; |
| 22 | if (!toggle) { | ||
| 23 | return button_state; | ||
| 24 | } | ||
| 25 | |||
| 26 | if (button_state) { | ||
| 27 | return mouse_input->ToggleButton(button); | ||
| 28 | } | ||
| 29 | return mouse_input->UnlockButton(button); | ||
| 22 | } | 30 | } |
| 23 | 31 | ||
| 24 | private: | 32 | private: |
| 25 | const u32 button; | 33 | const u32 button; |
| 26 | const MouseInput::Mouse* mouse_input; | 34 | const bool toggle; |
| 35 | MouseInput::Mouse* mouse_input; | ||
| 27 | }; | 36 | }; |
| 28 | 37 | ||
| 29 | MouseButtonFactory::MouseButtonFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_) | 38 | MouseButtonFactory::MouseButtonFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_) |
| @@ -32,8 +41,9 @@ MouseButtonFactory::MouseButtonFactory(std::shared_ptr<MouseInput::Mouse> mouse_ | |||
| 32 | std::unique_ptr<Input::ButtonDevice> MouseButtonFactory::Create( | 41 | std::unique_ptr<Input::ButtonDevice> MouseButtonFactory::Create( |
| 33 | const Common::ParamPackage& params) { | 42 | const Common::ParamPackage& params) { |
| 34 | const auto button_id = params.Get("button", 0); | 43 | const auto button_id = params.Get("button", 0); |
| 44 | const auto toggle = params.Get("toggle", false); | ||
| 35 | 45 | ||
| 36 | return std::make_unique<MouseButton>(button_id, mouse_input.get()); | 46 | return std::make_unique<MouseButton>(button_id, toggle, mouse_input.get()); |
| 37 | } | 47 | } |
| 38 | 48 | ||
| 39 | Common::ParamPackage MouseButtonFactory::GetNextInput() const { | 49 | Common::ParamPackage MouseButtonFactory::GetNextInput() const { |
diff --git a/src/video_core/rasterizer_accelerated.cpp b/src/video_core/rasterizer_accelerated.cpp index 53622ca05..62d84c0f8 100644 --- a/src/video_core/rasterizer_accelerated.cpp +++ b/src/video_core/rasterizer_accelerated.cpp | |||
| @@ -2,63 +2,43 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <mutex> | ||
| 6 | |||
| 7 | #include <boost/icl/interval_map.hpp> | ||
| 8 | #include <boost/range/iterator_range.hpp> | ||
| 9 | |||
| 10 | #include "common/assert.h" | 5 | #include "common/assert.h" |
| 11 | #include "common/common_types.h" | 6 | #include "common/common_types.h" |
| 7 | #include "common/div_ceil.h" | ||
| 12 | #include "core/memory.h" | 8 | #include "core/memory.h" |
| 13 | #include "video_core/rasterizer_accelerated.h" | 9 | #include "video_core/rasterizer_accelerated.h" |
| 14 | 10 | ||
| 15 | namespace VideoCore { | 11 | namespace VideoCore { |
| 16 | 12 | ||
| 17 | namespace { | ||
| 18 | |||
| 19 | template <typename Map, typename Interval> | ||
| 20 | constexpr auto RangeFromInterval(Map& map, const Interval& interval) { | ||
| 21 | return boost::make_iterator_range(map.equal_range(interval)); | ||
| 22 | } | ||
| 23 | |||
| 24 | } // Anonymous namespace | ||
| 25 | |||
| 26 | RasterizerAccelerated::RasterizerAccelerated(Core::Memory::Memory& cpu_memory_) | 13 | RasterizerAccelerated::RasterizerAccelerated(Core::Memory::Memory& cpu_memory_) |
| 27 | : cpu_memory{cpu_memory_} {} | 14 | : cpu_memory{cpu_memory_} {} |
| 28 | 15 | ||
| 29 | RasterizerAccelerated::~RasterizerAccelerated() = default; | 16 | RasterizerAccelerated::~RasterizerAccelerated() = default; |
| 30 | 17 | ||
| 31 | void RasterizerAccelerated::UpdatePagesCachedCount(VAddr addr, u64 size, int delta) { | 18 | void RasterizerAccelerated::UpdatePagesCachedCount(VAddr addr, u64 size, int delta) { |
| 32 | std::lock_guard lock{pages_mutex}; | 19 | const auto page_end = Common::DivCeil(addr + size, Core::Memory::PAGE_SIZE); |
| 33 | const u64 page_start{addr >> Core::Memory::PAGE_BITS}; | 20 | for (auto page = addr >> Core::Memory::PAGE_BITS; page != page_end; ++page) { |
| 34 | const u64 page_end{(addr + size + Core::Memory::PAGE_SIZE - 1) >> Core::Memory::PAGE_BITS}; | 21 | auto& count = cached_pages.at(page >> 3).Count(page); |
| 35 | 22 | ||
| 36 | // Interval maps will erase segments if count reaches 0, so if delta is negative we have to | 23 | if (delta > 0) { |
| 37 | // subtract after iterating | 24 | ASSERT_MSG(count < UINT8_MAX, "Count may overflow!"); |
| 38 | const auto pages_interval = CachedPageMap::interval_type::right_open(page_start, page_end); | 25 | } else if (delta < 0) { |
| 39 | if (delta > 0) { | 26 | ASSERT_MSG(count > 0, "Count may underflow!"); |
| 40 | cached_pages.add({pages_interval, delta}); | ||
| 41 | } | ||
| 42 | |||
| 43 | for (const auto& pair : RangeFromInterval(cached_pages, pages_interval)) { | ||
| 44 | const auto interval = pair.first & pages_interval; | ||
| 45 | const int count = pair.second; | ||
| 46 | |||
| 47 | const VAddr interval_start_addr = boost::icl::first(interval) << Core::Memory::PAGE_BITS; | ||
| 48 | const VAddr interval_end_addr = boost::icl::last_next(interval) << Core::Memory::PAGE_BITS; | ||
| 49 | const u64 interval_size = interval_end_addr - interval_start_addr; | ||
| 50 | |||
| 51 | if (delta > 0 && count == delta) { | ||
| 52 | cpu_memory.RasterizerMarkRegionCached(interval_start_addr, interval_size, true); | ||
| 53 | } else if (delta < 0 && count == -delta) { | ||
| 54 | cpu_memory.RasterizerMarkRegionCached(interval_start_addr, interval_size, false); | ||
| 55 | } else { | 27 | } else { |
| 56 | ASSERT(count >= 0); | 28 | ASSERT_MSG(true, "Delta must be non-zero!"); |
| 57 | } | 29 | } |
| 58 | } | ||
| 59 | 30 | ||
| 60 | if (delta < 0) { | 31 | // Adds or subtracts 1, as count is a unsigned 8-bit value |
| 61 | cached_pages.add({pages_interval, delta}); | 32 | count += static_cast<u8>(delta); |
| 33 | |||
| 34 | // Assume delta is either -1 or 1 | ||
| 35 | if (count == 0) { | ||
| 36 | cpu_memory.RasterizerMarkRegionCached(page << Core::Memory::PAGE_BITS, | ||
| 37 | Core::Memory::PAGE_SIZE, false); | ||
| 38 | } else if (count == 1 && delta > 0) { | ||
| 39 | cpu_memory.RasterizerMarkRegionCached(page << Core::Memory::PAGE_BITS, | ||
| 40 | Core::Memory::PAGE_SIZE, true); | ||
| 41 | } | ||
| 62 | } | 42 | } |
| 63 | } | 43 | } |
| 64 | 44 | ||
diff --git a/src/video_core/rasterizer_accelerated.h b/src/video_core/rasterizer_accelerated.h index 91866d7dd..9227a4adc 100644 --- a/src/video_core/rasterizer_accelerated.h +++ b/src/video_core/rasterizer_accelerated.h | |||
| @@ -4,9 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <mutex> | 7 | #include <array> |
| 8 | 8 | #include <atomic> | |
| 9 | #include <boost/icl/interval_map.hpp> | ||
| 10 | 9 | ||
| 11 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 12 | #include "video_core/rasterizer_interface.h" | 11 | #include "video_core/rasterizer_interface.h" |
| @@ -26,10 +25,24 @@ public: | |||
| 26 | void UpdatePagesCachedCount(VAddr addr, u64 size, int delta) override; | 25 | void UpdatePagesCachedCount(VAddr addr, u64 size, int delta) override; |
| 27 | 26 | ||
| 28 | private: | 27 | private: |
| 29 | using CachedPageMap = boost::icl::interval_map<u64, int>; | 28 | class CacheEntry final { |
| 30 | CachedPageMap cached_pages; | 29 | public: |
| 31 | std::mutex pages_mutex; | 30 | CacheEntry() = default; |
| 31 | |||
| 32 | std::atomic_uint8_t& Count(std::size_t page) { | ||
| 33 | return values[page & 7]; | ||
| 34 | } | ||
| 35 | |||
| 36 | const std::atomic_uint8_t& Count(std::size_t page) const { | ||
| 37 | return values[page & 7]; | ||
| 38 | } | ||
| 39 | |||
| 40 | private: | ||
| 41 | std::array<std::atomic_uint8_t, 8> values{}; | ||
| 42 | }; | ||
| 43 | static_assert(sizeof(CacheEntry) == 8, "CacheEntry should be 8 bytes!"); | ||
| 32 | 44 | ||
| 45 | std::array<CacheEntry, 0x800000> cached_pages; | ||
| 33 | Core::Memory::Memory& cpu_memory; | 46 | Core::Memory::Memory& cpu_memory; |
| 34 | }; | 47 | }; |
| 35 | 48 | ||
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index ae49cbb45..15c09e0ad 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp | |||
| @@ -376,11 +376,15 @@ void GRenderWindow::closeEvent(QCloseEvent* event) { | |||
| 376 | } | 376 | } |
| 377 | 377 | ||
| 378 | void GRenderWindow::keyPressEvent(QKeyEvent* event) { | 378 | void GRenderWindow::keyPressEvent(QKeyEvent* event) { |
| 379 | input_subsystem->GetKeyboard()->PressKey(event->key()); | 379 | if (!event->isAutoRepeat()) { |
| 380 | input_subsystem->GetKeyboard()->PressKey(event->key()); | ||
| 381 | } | ||
| 380 | } | 382 | } |
| 381 | 383 | ||
| 382 | void GRenderWindow::keyReleaseEvent(QKeyEvent* event) { | 384 | void GRenderWindow::keyReleaseEvent(QKeyEvent* event) { |
| 383 | input_subsystem->GetKeyboard()->ReleaseKey(event->key()); | 385 | if (!event->isAutoRepeat()) { |
| 386 | input_subsystem->GetKeyboard()->ReleaseKey(event->key()); | ||
| 387 | } | ||
| 384 | } | 388 | } |
| 385 | 389 | ||
| 386 | MouseInput::MouseButton GRenderWindow::QtButtonToMouseButton(Qt::MouseButton button) { | 390 | MouseInput::MouseButton GRenderWindow::QtButtonToMouseButton(Qt::MouseButton button) { |
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index bc572d319..c9318c562 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp | |||
| @@ -105,7 +105,9 @@ QString ButtonToText(const Common::ParamPackage& param) { | |||
| 105 | } | 105 | } |
| 106 | 106 | ||
| 107 | if (param.Get("engine", "") == "keyboard") { | 107 | if (param.Get("engine", "") == "keyboard") { |
| 108 | return GetKeyName(param.Get("code", 0)); | 108 | const QString button_str = GetKeyName(param.Get("code", 0)); |
| 109 | const QString toggle = QString::fromStdString(param.Get("toggle", false) ? "~" : ""); | ||
| 110 | return QObject::tr("%1%2").arg(toggle, button_str); | ||
| 109 | } | 111 | } |
| 110 | 112 | ||
| 111 | if (param.Get("engine", "") == "gcpad") { | 113 | if (param.Get("engine", "") == "gcpad") { |
| @@ -157,7 +159,8 @@ QString ButtonToText(const Common::ParamPackage& param) { | |||
| 157 | if (param.Get("engine", "") == "mouse") { | 159 | if (param.Get("engine", "") == "mouse") { |
| 158 | if (param.Has("button")) { | 160 | if (param.Has("button")) { |
| 159 | const QString button_str = QString::number(int(param.Get("button", 0))); | 161 | const QString button_str = QString::number(int(param.Get("button", 0))); |
| 160 | return QObject::tr("Click %1").arg(button_str); | 162 | const QString toggle = QString::fromStdString(param.Get("toggle", false) ? "~" : ""); |
| 163 | return QObject::tr("%1Click %2").arg(toggle, button_str); | ||
| 161 | } | 164 | } |
| 162 | return GetKeyName(param.Get("code", 0)); | 165 | return GetKeyName(param.Get("code", 0)); |
| 163 | } | 166 | } |
| @@ -301,6 +304,11 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i | |||
| 301 | buttons_param[button_id].Clear(); | 304 | buttons_param[button_id].Clear(); |
| 302 | button_map[button_id]->setText(tr("[not set]")); | 305 | button_map[button_id]->setText(tr("[not set]")); |
| 303 | }); | 306 | }); |
| 307 | context_menu.addAction(tr("Toggle button"), [&] { | ||
| 308 | const bool toggle_value = !buttons_param[button_id].Get("toggle", false); | ||
| 309 | buttons_param[button_id].Set("toggle", toggle_value); | ||
| 310 | button_map[button_id]->setText(ButtonToText(buttons_param[button_id])); | ||
| 311 | }); | ||
| 304 | context_menu.exec(button_map[button_id]->mapToGlobal(menu_location)); | 312 | context_menu.exec(button_map[button_id]->mapToGlobal(menu_location)); |
| 305 | ui->controllerFrame->SetPlayerInput(player_index, buttons_param, analogs_param); | 313 | ui->controllerFrame->SetPlayerInput(player_index, buttons_param, analogs_param); |
| 306 | }); | 314 | }); |
| @@ -413,6 +421,15 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i | |||
| 413 | analogs_param[analog_id].Set("modifier", ""); | 421 | analogs_param[analog_id].Set("modifier", ""); |
| 414 | analog_map_modifier_button[analog_id]->setText(tr("[not set]")); | 422 | analog_map_modifier_button[analog_id]->setText(tr("[not set]")); |
| 415 | }); | 423 | }); |
| 424 | context_menu.addAction(tr("Toggle button"), [&] { | ||
| 425 | Common::ParamPackage modifier_param = | ||
| 426 | Common::ParamPackage{analogs_param[analog_id].Get("modifier", "")}; | ||
| 427 | const bool toggle_value = !modifier_param.Get("toggle", false); | ||
| 428 | modifier_param.Set("toggle", toggle_value); | ||
| 429 | analogs_param[analog_id].Set("modifier", modifier_param.Serialize()); | ||
| 430 | analog_map_modifier_button[analog_id]->setText( | ||
| 431 | ButtonToText(modifier_param)); | ||
| 432 | }); | ||
| 416 | context_menu.exec( | 433 | context_menu.exec( |
| 417 | analog_map_modifier_button[analog_id]->mapToGlobal(menu_location)); | 434 | analog_map_modifier_button[analog_id]->mapToGlobal(menu_location)); |
| 418 | }); | 435 | }); |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 56d892a31..24bfa4d34 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -60,6 +60,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual | |||
| 60 | #include <QPushButton> | 60 | #include <QPushButton> |
| 61 | #include <QShortcut> | 61 | #include <QShortcut> |
| 62 | #include <QStatusBar> | 62 | #include <QStatusBar> |
| 63 | #include <QString> | ||
| 63 | #include <QSysInfo> | 64 | #include <QSysInfo> |
| 64 | #include <QUrl> | 65 | #include <QUrl> |
| 65 | #include <QtConcurrent/QtConcurrent> | 66 | #include <QtConcurrent/QtConcurrent> |
| @@ -3061,6 +3062,14 @@ int main(int argc, char* argv[]) { | |||
| 3061 | chdir(bin_path.c_str()); | 3062 | chdir(bin_path.c_str()); |
| 3062 | #endif | 3063 | #endif |
| 3063 | 3064 | ||
| 3065 | #ifdef __linux__ | ||
| 3066 | // Set the DISPLAY variable in order to open web browsers | ||
| 3067 | // TODO (lat9nq): Find a better solution for AppImages to start external applications | ||
| 3068 | if (QString::fromLocal8Bit(qgetenv("DISPLAY")).isEmpty()) { | ||
| 3069 | qputenv("DISPLAY", ":0"); | ||
| 3070 | } | ||
| 3071 | #endif | ||
| 3072 | |||
| 3064 | // Enables the core to make the qt created contexts current on std::threads | 3073 | // Enables the core to make the qt created contexts current on std::threads |
| 3065 | QCoreApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity); | 3074 | QCoreApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity); |
| 3066 | QApplication app(argc, argv); | 3075 | QApplication app(argc, argv); |