summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/common/fiber.cpp2
-rw-r--r--src/core/file_sys/system_archive/ng_word.cpp4
-rw-r--r--src/core/file_sys/system_archive/system_version.cpp10
-rw-r--r--src/core/hle/service/sockets/bsd.cpp8
-rw-r--r--src/core/hle/service/time/time.cpp14
-rw-r--r--src/input_common/keyboard.cpp31
-rw-r--r--src/input_common/mouse/mouse_input.cpp36
-rw-r--r--src/input_common/mouse/mouse_input.h5
-rw-r--r--src/input_common/mouse/mouse_poller.cpp20
-rw-r--r--src/video_core/rasterizer_accelerated.cpp62
-rw-r--r--src/video_core/rasterizer_accelerated.h25
-rw-r--r--src/yuzu/bootmanager.cpp8
-rw-r--r--src/yuzu/configuration/configure_input_player.cpp21
-rw-r--r--src/yuzu/main.cpp9
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 @@
namespace Common {
-constexpr std::size_t default_stack_size = 256 * 1024;
+constexpr std::size_t default_stack_size = 512 * 1024;
struct Fiber::FiberImpl {
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 {
constexpr std::size_t NUMBER_WORD_TXT_FILES = 0x10;
// Should this archive replacement mysteriously not work on a future game, consider updating.
-constexpr std::array<u8, 4> VERSION_DAT{0x0, 0x0, 0x0, 0x19}; // 5.1.0 System Version
+constexpr std::array<u8, 4> VERSION_DAT{0x0, 0x0, 0x0, 0x20}; // 11.0.1 System Version
constexpr std::array<u8, 30> WORD_TXT{
0xFE, 0xFF, 0x00, 0x5E, 0x00, 0x76, 0x00, 0x65, 0x00, 0x72, 0x00, 0x79, 0x00, 0x62, 0x00,
@@ -43,7 +43,7 @@ namespace NgWord2Data {
constexpr std::size_t NUMBER_AC_NX_FILES = 0x10;
// Should this archive replacement mysteriously not work on a future game, consider updating.
-constexpr std::array<u8, 4> VERSION_DAT{0x0, 0x0, 0x0, 0x15}; // 5.1.0 System Version
+constexpr std::array<u8, 4> VERSION_DAT{0x0, 0x0, 0x0, 0x1A}; // 11.0.1 System Version
constexpr std::array<u8, 0x2C> AC_NX_DATA{
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 {
constexpr u8 VERSION_MAJOR = 11;
constexpr u8 VERSION_MINOR = 0;
-constexpr u8 VERSION_MICRO = 0;
+constexpr u8 VERSION_MICRO = 1;
-constexpr u8 REVISION_MAJOR = 5;
+constexpr u8 REVISION_MAJOR = 1;
constexpr u8 REVISION_MINOR = 0;
constexpr char PLATFORM_STRING[] = "NX";
-constexpr char VERSION_HASH[] = "34197eba8810e2edd5e9dfcfbde7b340882e856d";
-constexpr char DISPLAY_VERSION[] = "11.0.0";
-constexpr char DISPLAY_TITLE[] = "NintendoSDK Firmware for NX 11.0.0-5.0";
+constexpr char VERSION_HASH[] = "69103fcb2004dace877094c2f8c29e6113be5dbf";
+constexpr char DISPLAY_VERSION[] = "11.0.1";
+constexpr char DISPLAY_TITLE[] = "NintendoSDK Firmware for NX 11.0.1-1.0";
} // namespace SystemVersionData
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) {
}
void BSD::PollWork::Response(Kernel::HLERequestContext& ctx) {
- ctx.WriteBuffer(write_buffer);
+ if (write_buffer.size() > 0) {
+ ctx.WriteBuffer(write_buffer);
+ }
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
@@ -55,7 +57,9 @@ void BSD::AcceptWork::Execute(BSD* bsd) {
}
void BSD::AcceptWork::Response(Kernel::HLERequestContext& ctx) {
- ctx.WriteBuffer(write_buffer);
+ if (write_buffer.size() > 0) {
+ ctx.WriteBuffer(write_buffer);
+ }
IPC::ResponseBuilder rb{ctx, 5};
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(
const auto current_time_point{
time_manager.GetStandardSteadyClockCore().GetCurrentTimePoint(system)};
+ clock_snapshot.steady_clock_time_point = current_time_point;
+
if (const ResultCode result{Clock::ClockSnapshot::GetCurrentTime(
clock_snapshot.user_time, current_time_point, clock_snapshot.user_context)};
result != RESULT_SUCCESS) {
@@ -341,12 +343,18 @@ void Module::Interface::CalculateStandardUserSystemClockDifferenceByUser(
void Module::Interface::CalculateSpanBetween(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_Time, "called");
- IPC::RequestParser rp{ctx};
- const auto snapshot_a = rp.PopRaw<Clock::ClockSnapshot>();
- const auto snapshot_b = rp.PopRaw<Clock::ClockSnapshot>();
+ Clock::ClockSnapshot snapshot_a;
+ Clock::ClockSnapshot snapshot_b;
+
+ const auto snapshot_a_data = ctx.ReadBuffer(0);
+ const auto snapshot_b_data = ctx.ReadBuffer(1);
+
+ std::memcpy(&snapshot_a, snapshot_a_data.data(), sizeof(Clock::ClockSnapshot));
+ std::memcpy(&snapshot_b, snapshot_b_data.data(), sizeof(Clock::ClockSnapshot));
Clock::TimeSpanType time_span_type{};
s64 span{};
+
if (const ResultCode result{snapshot_a.steady_clock_time_point.GetSpanBetween(
snapshot_b.steady_clock_time_point, span)};
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 {
class KeyButton final : public Input::ButtonDevice {
public:
- explicit KeyButton(std::shared_ptr<KeyButtonList> key_button_list_)
- : key_button_list(std::move(key_button_list_)) {}
+ explicit KeyButton(std::shared_ptr<KeyButtonList> key_button_list_, bool toggle_)
+ : key_button_list(std::move(key_button_list_)), toggle(toggle_) {}
~KeyButton() override;
bool GetStatus() const override {
+ if (toggle) {
+ return toggled_status.load(std::memory_order_relaxed);
+ }
return status.load();
}
+ void ToggleButton() {
+ if (lock) {
+ return;
+ }
+ lock = true;
+ const bool old_toggle_status = toggled_status.load();
+ toggled_status.store(!old_toggle_status);
+ }
+
+ void UnlockButton() {
+ lock = false;
+ }
+
friend class KeyButtonList;
private:
std::shared_ptr<KeyButtonList> key_button_list;
std::atomic<bool> status{false};
+ std::atomic<bool> toggled_status{false};
+ bool lock{false};
+ const bool toggle;
};
struct KeyButtonPair {
@@ -51,6 +70,11 @@ public:
for (const KeyButtonPair& pair : list) {
if (pair.key_code == key_code) {
pair.key_button->status.store(pressed);
+ if (pressed) {
+ pair.key_button->ToggleButton();
+ } else {
+ pair.key_button->UnlockButton();
+ }
}
}
}
@@ -75,7 +99,8 @@ KeyButton::~KeyButton() {
std::unique_ptr<Input::ButtonDevice> Keyboard::Create(const Common::ParamPackage& params) {
const int key_code = params.Get("code", 0);
- std::unique_ptr<KeyButton> button = std::make_unique<KeyButton>(key_button_list);
+ const bool toggle = params.Get("toggle", false);
+ std::unique_ptr<KeyButton> button = std::make_unique<KeyButton>(key_button_list, toggle);
key_button_list->AddKeyButton(key_code, button.get());
return button;
}
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() {
configuring = false;
}
+bool Mouse::ToggleButton(std::size_t button_) {
+ if (button_ >= mouse_info.size()) {
+ return false;
+ }
+ const auto button = 1U << button_;
+ const bool button_state = (toggle_buttons & button) != 0;
+ const bool button_lock = (lock_buttons & button) != 0;
+
+ if (button_lock) {
+ return button_state;
+ }
+
+ lock_buttons |= static_cast<u16>(button);
+
+ if (button_state) {
+ toggle_buttons &= static_cast<u16>(0xFF - button);
+ } else {
+ toggle_buttons |= static_cast<u16>(button);
+ }
+
+ return !button_state;
+}
+
+bool Mouse::UnlockButton(std::size_t button_) {
+ if (button_ >= mouse_info.size()) {
+ return false;
+ }
+
+ const auto button = 1U << button_;
+ const bool button_state = (toggle_buttons & button) != 0;
+
+ lock_buttons &= static_cast<u16>(0xFF - button);
+
+ return button_state;
+}
+
Common::SPSCQueue<MouseStatus>& Mouse::GetMouseQueue() {
return mouse_queue;
}
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:
*/
void ReleaseButton(MouseButton button_);
+ [[nodiscard]] bool ToggleButton(std::size_t button_);
+ [[nodiscard]] bool UnlockButton(std::size_t button_);
+
[[nodiscard]] Common::SPSCQueue<MouseStatus>& GetMouseQueue();
[[nodiscard]] const Common::SPSCQueue<MouseStatus>& GetMouseQueue() const;
@@ -94,6 +97,8 @@ private:
};
u16 buttons{};
+ u16 toggle_buttons{};
+ u16 lock_buttons{};
std::thread update_thread;
MouseButton last_button{MouseButton::Undefined};
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 {
class MouseButton final : public Input::ButtonDevice {
public:
- explicit MouseButton(u32 button_, const MouseInput::Mouse* mouse_input_)
- : button(button_), mouse_input(mouse_input_) {}
+ explicit MouseButton(u32 button_, bool toggle_, MouseInput::Mouse* mouse_input_)
+ : button(button_), toggle(toggle_), mouse_input(mouse_input_) {}
bool GetStatus() const override {
- return mouse_input->GetMouseState(button).pressed;
+ const bool button_state = mouse_input->GetMouseState(button).pressed;
+ if (!toggle) {
+ return button_state;
+ }
+
+ if (button_state) {
+ return mouse_input->ToggleButton(button);
+ }
+ return mouse_input->UnlockButton(button);
}
private:
const u32 button;
- const MouseInput::Mouse* mouse_input;
+ const bool toggle;
+ MouseInput::Mouse* mouse_input;
};
MouseButtonFactory::MouseButtonFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_)
@@ -32,8 +41,9 @@ MouseButtonFactory::MouseButtonFactory(std::shared_ptr<MouseInput::Mouse> mouse_
std::unique_ptr<Input::ButtonDevice> MouseButtonFactory::Create(
const Common::ParamPackage& params) {
const auto button_id = params.Get("button", 0);
+ const auto toggle = params.Get("toggle", false);
- return std::make_unique<MouseButton>(button_id, mouse_input.get());
+ return std::make_unique<MouseButton>(button_id, toggle, mouse_input.get());
}
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 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-#include <mutex>
-
-#include <boost/icl/interval_map.hpp>
-#include <boost/range/iterator_range.hpp>
-
#include "common/assert.h"
#include "common/common_types.h"
+#include "common/div_ceil.h"
#include "core/memory.h"
#include "video_core/rasterizer_accelerated.h"
namespace VideoCore {
-namespace {
-
-template <typename Map, typename Interval>
-constexpr auto RangeFromInterval(Map& map, const Interval& interval) {
- return boost::make_iterator_range(map.equal_range(interval));
-}
-
-} // Anonymous namespace
-
RasterizerAccelerated::RasterizerAccelerated(Core::Memory::Memory& cpu_memory_)
: cpu_memory{cpu_memory_} {}
RasterizerAccelerated::~RasterizerAccelerated() = default;
void RasterizerAccelerated::UpdatePagesCachedCount(VAddr addr, u64 size, int delta) {
- std::lock_guard lock{pages_mutex};
- const u64 page_start{addr >> Core::Memory::PAGE_BITS};
- const u64 page_end{(addr + size + Core::Memory::PAGE_SIZE - 1) >> Core::Memory::PAGE_BITS};
-
- // Interval maps will erase segments if count reaches 0, so if delta is negative we have to
- // subtract after iterating
- const auto pages_interval = CachedPageMap::interval_type::right_open(page_start, page_end);
- if (delta > 0) {
- cached_pages.add({pages_interval, delta});
- }
-
- for (const auto& pair : RangeFromInterval(cached_pages, pages_interval)) {
- const auto interval = pair.first & pages_interval;
- const int count = pair.second;
-
- const VAddr interval_start_addr = boost::icl::first(interval) << Core::Memory::PAGE_BITS;
- const VAddr interval_end_addr = boost::icl::last_next(interval) << Core::Memory::PAGE_BITS;
- const u64 interval_size = interval_end_addr - interval_start_addr;
-
- if (delta > 0 && count == delta) {
- cpu_memory.RasterizerMarkRegionCached(interval_start_addr, interval_size, true);
- } else if (delta < 0 && count == -delta) {
- cpu_memory.RasterizerMarkRegionCached(interval_start_addr, interval_size, false);
+ 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);
+
+ if (delta > 0) {
+ ASSERT_MSG(count < UINT8_MAX, "Count may overflow!");
+ } else if (delta < 0) {
+ ASSERT_MSG(count > 0, "Count may underflow!");
} else {
- ASSERT(count >= 0);
+ ASSERT_MSG(true, "Delta must be non-zero!");
}
- }
- if (delta < 0) {
- cached_pages.add({pages_interval, delta});
+ // Adds or subtracts 1, as count is a unsigned 8-bit value
+ count += static_cast<u8>(delta);
+
+ // Assume delta is either -1 or 1
+ if (count == 0) {
+ cpu_memory.RasterizerMarkRegionCached(page << Core::Memory::PAGE_BITS,
+ Core::Memory::PAGE_SIZE, false);
+ } else if (count == 1 && delta > 0) {
+ cpu_memory.RasterizerMarkRegionCached(page << Core::Memory::PAGE_BITS,
+ Core::Memory::PAGE_SIZE, true);
+ }
}
}
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 @@
#pragma once
-#include <mutex>
-
-#include <boost/icl/interval_map.hpp>
+#include <array>
+#include <atomic>
#include "common/common_types.h"
#include "video_core/rasterizer_interface.h"
@@ -26,10 +25,24 @@ public:
void UpdatePagesCachedCount(VAddr addr, u64 size, int delta) override;
private:
- using CachedPageMap = boost::icl::interval_map<u64, int>;
- CachedPageMap cached_pages;
- std::mutex pages_mutex;
+ class CacheEntry final {
+ public:
+ CacheEntry() = default;
+
+ std::atomic_uint8_t& Count(std::size_t page) {
+ return values[page & 7];
+ }
+
+ const std::atomic_uint8_t& Count(std::size_t page) const {
+ return values[page & 7];
+ }
+
+ private:
+ std::array<std::atomic_uint8_t, 8> values{};
+ };
+ static_assert(sizeof(CacheEntry) == 8, "CacheEntry should be 8 bytes!");
+ std::array<CacheEntry, 0x800000> cached_pages;
Core::Memory::Memory& cpu_memory;
};
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) {
}
void GRenderWindow::keyPressEvent(QKeyEvent* event) {
- input_subsystem->GetKeyboard()->PressKey(event->key());
+ if (!event->isAutoRepeat()) {
+ input_subsystem->GetKeyboard()->PressKey(event->key());
+ }
}
void GRenderWindow::keyReleaseEvent(QKeyEvent* event) {
- input_subsystem->GetKeyboard()->ReleaseKey(event->key());
+ if (!event->isAutoRepeat()) {
+ input_subsystem->GetKeyboard()->ReleaseKey(event->key());
+ }
}
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) {
}
if (param.Get("engine", "") == "keyboard") {
- return GetKeyName(param.Get("code", 0));
+ const QString button_str = GetKeyName(param.Get("code", 0));
+ const QString toggle = QString::fromStdString(param.Get("toggle", false) ? "~" : "");
+ return QObject::tr("%1%2").arg(toggle, button_str);
}
if (param.Get("engine", "") == "gcpad") {
@@ -157,7 +159,8 @@ QString ButtonToText(const Common::ParamPackage& param) {
if (param.Get("engine", "") == "mouse") {
if (param.Has("button")) {
const QString button_str = QString::number(int(param.Get("button", 0)));
- return QObject::tr("Click %1").arg(button_str);
+ const QString toggle = QString::fromStdString(param.Get("toggle", false) ? "~" : "");
+ return QObject::tr("%1Click %2").arg(toggle, button_str);
}
return GetKeyName(param.Get("code", 0));
}
@@ -301,6 +304,11 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
buttons_param[button_id].Clear();
button_map[button_id]->setText(tr("[not set]"));
});
+ context_menu.addAction(tr("Toggle button"), [&] {
+ const bool toggle_value = !buttons_param[button_id].Get("toggle", false);
+ buttons_param[button_id].Set("toggle", toggle_value);
+ button_map[button_id]->setText(ButtonToText(buttons_param[button_id]));
+ });
context_menu.exec(button_map[button_id]->mapToGlobal(menu_location));
ui->controllerFrame->SetPlayerInput(player_index, buttons_param, analogs_param);
});
@@ -413,6 +421,15 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
analogs_param[analog_id].Set("modifier", "");
analog_map_modifier_button[analog_id]->setText(tr("[not set]"));
});
+ context_menu.addAction(tr("Toggle button"), [&] {
+ Common::ParamPackage modifier_param =
+ Common::ParamPackage{analogs_param[analog_id].Get("modifier", "")};
+ const bool toggle_value = !modifier_param.Get("toggle", false);
+ modifier_param.Set("toggle", toggle_value);
+ analogs_param[analog_id].Set("modifier", modifier_param.Serialize());
+ analog_map_modifier_button[analog_id]->setText(
+ ButtonToText(modifier_param));
+ });
context_menu.exec(
analog_map_modifier_button[analog_id]->mapToGlobal(menu_location));
});
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
#include <QPushButton>
#include <QShortcut>
#include <QStatusBar>
+#include <QString>
#include <QSysInfo>
#include <QUrl>
#include <QtConcurrent/QtConcurrent>
@@ -3061,6 +3062,14 @@ int main(int argc, char* argv[]) {
chdir(bin_path.c_str());
#endif
+#ifdef __linux__
+ // Set the DISPLAY variable in order to open web browsers
+ // TODO (lat9nq): Find a better solution for AppImages to start external applications
+ if (QString::fromLocal8Bit(qgetenv("DISPLAY")).isEmpty()) {
+ qputenv("DISPLAY", ":0");
+ }
+#endif
+
// Enables the core to make the qt created contexts current on std::threads
QCoreApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity);
QApplication app(argc, argv);