Compare commits

...

36 Commits

Author SHA1 Message Date
Lioncash
c883666045 dmnt_cheat_vm: Make use of designated initializers
Allows for more compact code.
2020-08-03 08:50:51 -04:00
bunnei
05781ce8c4 Merge pull request #4437 from lioncash/ptr
core_timing: Make use of uintptr_t to represent user_data
2020-07-27 19:29:22 -07:00
bunnei
312c3788df Merge pull request #4420 from lat9nq/fix-themed-label-bg
qt_themes: Set QLabel background color to transparent for Dark and Midnight Blue themes
2020-07-27 18:29:06 -07:00
Lioncash
a7af349dae core_timing: Make use of uintptr_t to represent user_data
Makes the interface future-proofed for supporting other platforms in the event we ever support platforms with differing pointer sizes. This way, we have a type in place that is always guaranteed to be able to represent a pointer exactly.
2020-07-27 21:21:01 -04:00
bunnei
6b35317ff3 Merge pull request #4419 from lioncash/initializer
vulkan: Resolve -Wmissing-field-initializer warnings
2020-07-27 15:52:03 -07:00
bunnei
f97c2cdd0b Merge pull request #4434 from CrazyMax/lang_unused_var
AM: GetDesiredLanguage: remove unused variable
2020-07-27 12:37:52 -07:00
Rodrigo Locatti
d51afc4efb Merge pull request #4432 from bylaws/patch-1
video_core/gpu: Correct the size of the puller registers
2020-07-27 05:25:49 -03:00
CrazyMax
1ffff4dab2 remove unused variable; 2020-07-27 10:36:26 +03:00
bunnei
99d191d80d Merge pull request #4431 from kelnos/fix-exit-crash
GCAdapter: only join worker thread if running & joinable
2020-07-26 18:03:37 -07:00
Brian J. Tarricone
d840ed90e1 GCAdapter: only join worker thread if running & joinable 2020-07-26 14:54:02 -07:00
Billy Laws
f490b4545d video_core/gpu: Correct the size of the puller registers
The puller register array is made up of u32s however the `NUM_REGS` value is the size in bytes, so switch it to avoid making the struct unnecessary large. Also fix a small typo in a comment.
2020-07-26 22:26:29 +01:00
bunnei
08f02836d8 Merge pull request #4426 from lioncash/lock
nvflinger: Use return value of Lock()
2020-07-26 09:19:24 -07:00
bunnei
4524e1bd54 Merge pull request #4418 from lioncash/udp-warn
udp/client: Remove unused boost include
2020-07-25 21:50:37 -07:00
bunnei
45cf48bd0a Merge pull request #4415 from lioncash/maybe
virtual_buffer: Mark size parameter of FreeMemoryPages() as [[maybe_unused]]
2020-07-25 21:35:09 -07:00
bunnei
b69f902b18 Merge pull request #4417 from lioncash/poll
gc_adapter/gc_poller: Resolve compiler warnings
2020-07-25 19:42:09 -07:00
LC
dd92bd644d Merge pull request #4429 from FearlessTobi/remove-duplicated-options
yuzu/configure_debug: Remove duplicated checkboxes
2020-07-25 21:20:39 -04:00
FearlessTobi
35b96a28d7 yuzu/configure_debug: Remove duplicated checkboxes
Those are already found in the Filesystem tab.
They were added back to the Debug tab by mistake in the Vulkan PR.
2020-07-26 02:45:19 +02:00
Lioncash
7b070bbf62 nvflinger: Mark interface functions with return values as [[nodiscard]]
Not using the return value of these functions are undeniably the source
of a bug. This way we allow compilers to loudly make any future misuses
evident.
2020-07-25 19:42:45 -04:00
Lioncash
5dab23e017 nvflinger: Use return value of Lock()
comex reported in #4424 that we were incorrectly discarding the return
value of Lock() which is correct.
2020-07-25 19:04:53 -04:00
bunnei
a2e1810287 Merge pull request #4350 from ogniK5377/hid-update-connected
hid: Only update keyboard & debug pad inputs if enabled
2020-07-25 11:57:24 -07:00
LC
e3503de588 common/string_util: Remove unimplemented function prototype (#4414)
This function was relocated to log.h as a constexpr function, so this
can be removed.
2020-07-25 15:37:51 +02:00
lat9nq
5f075bb490 qt_themes: Set background color to transparent for Dark and Midnight Blue themes
Fixes the override highlights in per-game settings from looking weird when viewed on the Dark or Midnight Blue themes by setting QLabels to have transparent backgrounds by default.

Also apparently adds a newline to the end of the Dark theme's qss file.
2020-07-25 04:23:48 -04:00
Lioncash
80eedff9e1 vulkan: Resolve -Wmissing-field-initializer warnings 2020-07-25 03:50:18 -04:00
Lioncash
1a7cf26884 udp/client: Remove unused boost include
Also silences a deprecation warning from boost on Clang/GCC.
2020-07-25 03:42:03 -04:00
Lioncash
ac7e4e2cab gc_adapter: Resolve C++20 deprecation warning 2020-07-25 03:38:22 -04:00
Lioncash
04699c366b gc_poller: Resolve -Wsign-compare warning 2020-07-25 03:37:22 -04:00
Lioncash
e19972dfc4 gc_poller: Resolve -Wredundant-move warning 2020-07-25 03:35:40 -04:00
Lioncash
ca6ff01333 virtual_buffer: Mark size parameter of FreeMemoryPages() as [[maybe_unused]]
This isn't used on Windows, but is used on non-Windows operating
systems.
2020-07-25 03:04:27 -04:00
bunnei
d046e9b458 Merge pull request #4380 from ogniK5377/swkbd-inline-1
swkbd: Return result for Calc request for inlined swkbd
2020-07-24 22:31:24 -07:00
bunnei
e96cf13ebc Merge pull request #4383 from ogniK5377/dark-checkbox
frontend: Match indeterminate checkbox state with light theme
2020-07-24 21:14:50 -07:00
bunnei
dc2d31b1b2 Merge pull request #4393 from lioncash/unused5
vk_rasterizer: Remove unused variable in Clear()
2020-07-24 20:33:58 -07:00
Lioncash
4b369126c4 vk_rasterizer: Remove unused variable in Clear()
The relevant values are already assigned further down in the lambda, so
this can be removed entirely.
2020-07-21 00:49:10 -04:00
David Marcec
92d879e5f6 frontend: Match indeterminate checkbox state with light theme
Keeps consistency between the two themes
2020-07-20 13:21:53 +10:00
David Marcec
8248d76964 Address issues 2020-07-20 11:52:07 +10:00
David Marcec
d7d2c27b48 swkbd: Return result for Calc request for inlined swkbd
Fixes random swkbd popups in monster hunter
2020-07-19 18:56:16 +10:00
David Marcec
0319cc1c37 hid: Only update keyboard & debug pad inputs if enabled
Previously we would ignore this setting and would update the states regardless of the user setting
2020-07-16 22:28:49 +10:00
41 changed files with 296 additions and 264 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 492 B

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 491 B

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 252 B

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 493 B

After

Width:  |  Height:  |  Size: 492 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 492 B

After

Width:  |  Height:  |  Size: 491 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 249 B

After

Width:  |  Height:  |  Size: 252 B

View File

@@ -654,7 +654,11 @@ QAbstractSpinBox::down-arrow:hover {
image: url(:/qss_icons/rc/down_arrow.png);
}
QLabel,
QLabel {
border: 0;
background: transparent;
}
QTabWidget {
border: 0;
}
@@ -1269,4 +1273,4 @@ QPushButton#RendererStatusBarButton:checked {
QPushButton#RendererStatusBarButton:!checked{
color: #00ccdd;
}
}

View File

@@ -875,7 +875,7 @@ https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qframe
--------------------------------------------------------------------------- */
QLabel {
background-color: #19232D;
background: transparent;
border: 0px solid #32414B;
padding: 2px;
margin: 0px;
@@ -883,7 +883,6 @@ QLabel {
}
QLabel:disabled {
background-color: #19232D;
border: 0px solid #32414B;
color: #787878;
}

View File

@@ -36,9 +36,10 @@ Stream::Stream(Core::Timing::CoreTiming& core_timing, u32 sample_rate, Format fo
ReleaseCallback&& release_callback, SinkStream& sink_stream, std::string&& name_)
: sample_rate{sample_rate}, format{format}, release_callback{std::move(release_callback)},
sink_stream{sink_stream}, core_timing{core_timing}, name{std::move(name_)} {
release_event = Core::Timing::CreateEvent(
name, [this](u64, std::chrono::nanoseconds ns_late) { ReleaseActiveBuffer(ns_late); });
release_event =
Core::Timing::CreateEvent(name, [this](std::uintptr_t, std::chrono::nanoseconds ns_late) {
ReleaseActiveBuffer(ns_late);
});
}
void Stream::Play() {

View File

@@ -74,16 +74,4 @@ std::string StringFromFixedZeroTerminatedBuffer(const char* buffer, std::size_t
std::u16string UTF16StringFromFixedZeroTerminatedBuffer(std::u16string_view buffer,
std::size_t max_len);
/**
* Attempts to trim an arbitrary prefix from `path`, leaving only the part starting at `root`. It's
* intended to be used to strip a system-specific build directory from the `__FILE__` macro,
* leaving only the path relative to the sources root.
*
* @param path The input file path as a null-terminated string
* @param root The name of the root source directory as a null-terminated string. Path up to and
* including the last occurrence of this name will be stripped
* @return A pointer to the same string passed as `path`, but starting at the trimmed portion
*/
const char* TrimSourcePath(const char* path, const char* root = "src");
} // namespace Common

View File

@@ -38,7 +38,7 @@ void* AllocateMemoryPages(std::size_t size) {
return base;
}
void FreeMemoryPages(void* base, std::size_t size) {
void FreeMemoryPages(void* base, [[maybe_unused]] std::size_t size) {
if (!base) {
return;
}

View File

@@ -23,7 +23,7 @@ std::shared_ptr<EventType> CreateEvent(std::string name, TimedCallback&& callbac
struct CoreTiming::Event {
u64 time;
u64 fifo_order;
u64 userdata;
std::uintptr_t user_data;
std::weak_ptr<EventType> type;
// Sort by time, unless the times are the same, in which case sort by
@@ -58,7 +58,7 @@ void CoreTiming::Initialize(std::function<void()>&& on_thread_init_) {
event_fifo_id = 0;
shutting_down = false;
ticks = 0;
const auto empty_timed_callback = [](u64, std::chrono::nanoseconds) {};
const auto empty_timed_callback = [](std::uintptr_t, std::chrono::nanoseconds) {};
ev_lost = CreateEvent("_lost_event", empty_timed_callback);
if (is_multicore) {
timer_thread = std::make_unique<std::thread>(ThreadEntry, std::ref(*this));
@@ -107,22 +107,24 @@ bool CoreTiming::HasPendingEvents() const {
}
void CoreTiming::ScheduleEvent(std::chrono::nanoseconds ns_into_future,
const std::shared_ptr<EventType>& event_type, u64 userdata) {
const std::shared_ptr<EventType>& event_type,
std::uintptr_t user_data) {
{
std::scoped_lock scope{basic_lock};
const u64 timeout = static_cast<u64>((GetGlobalTimeNs() + ns_into_future).count());
event_queue.emplace_back(Event{timeout, event_fifo_id++, userdata, event_type});
event_queue.emplace_back(Event{timeout, event_fifo_id++, user_data, event_type});
std::push_heap(event_queue.begin(), event_queue.end(), std::greater<>());
}
event.Set();
}
void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type, u64 userdata) {
void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type,
std::uintptr_t user_data) {
std::scoped_lock scope{basic_lock};
const auto itr = std::remove_if(event_queue.begin(), event_queue.end(), [&](const Event& e) {
return e.type.lock().get() == event_type.get() && e.userdata == userdata;
return e.type.lock().get() == event_type.get() && e.user_data == user_data;
});
// Removing random items breaks the invariant so we have to re-establish it.
@@ -197,7 +199,7 @@ std::optional<s64> CoreTiming::Advance() {
if (const auto event_type{evt.type.lock()}) {
event_type->callback(
evt.userdata, std::chrono::nanoseconds{static_cast<s64>(global_timer - evt.time)});
evt.user_data, std::chrono::nanoseconds{static_cast<s64>(global_timer - evt.time)});
}
basic_lock.lock();

View File

@@ -22,7 +22,8 @@
namespace Core::Timing {
/// A callback that may be scheduled for a particular core timing event.
using TimedCallback = std::function<void(u64 userdata, std::chrono::nanoseconds ns_late)>;
using TimedCallback =
std::function<void(std::uintptr_t user_data, std::chrono::nanoseconds ns_late)>;
/// Contains the characteristics of a particular event.
struct EventType {
@@ -94,9 +95,9 @@ public:
/// Schedules an event in core timing
void ScheduleEvent(std::chrono::nanoseconds ns_into_future,
const std::shared_ptr<EventType>& event_type, u64 userdata = 0);
const std::shared_ptr<EventType>& event_type, std::uintptr_t user_data = 0);
void UnscheduleEvent(const std::shared_ptr<EventType>& event_type, u64 userdata);
void UnscheduleEvent(const std::shared_ptr<EventType>& event_type, std::uintptr_t user_data);
/// We only permit one event of each type in the queue at a time.
void RemoveEvent(const std::shared_ptr<EventType>& event_type);

View File

@@ -11,8 +11,8 @@
namespace Core::Hardware {
InterruptManager::InterruptManager(Core::System& system_in) : system(system_in) {
gpu_interrupt_event =
Core::Timing::CreateEvent("GPUInterrupt", [this](u64 message, std::chrono::nanoseconds) {
gpu_interrupt_event = Core::Timing::CreateEvent(
"GPUInterrupt", [this](std::uintptr_t message, std::chrono::nanoseconds) {
auto nvdrv = system.ServiceManager().GetService<Service::Nvidia::NVDRV>("nvdrv");
const u32 syncpt = static_cast<u32>(message >> 32);
const u32 value = static_cast<u32>(message);

View File

@@ -145,7 +145,7 @@ struct KernelCore::Impl {
void InitializePreemption(KernelCore& kernel) {
preemption_event = Core::Timing::CreateEvent(
"PreemptionCallback", [this, &kernel](u64, std::chrono::nanoseconds) {
"PreemptionCallback", [this, &kernel](std::uintptr_t, std::chrono::nanoseconds) {
{
SchedulerLock lock(kernel);
global_scheduler.PreemptThreads();

View File

@@ -33,8 +33,10 @@ ResultVal<std::shared_ptr<ServerSession>> ServerSession::Create(KernelCore& kern
std::string name) {
std::shared_ptr<ServerSession> session{std::make_shared<ServerSession>(kernel)};
session->request_event = Core::Timing::CreateEvent(
name, [session](u64, std::chrono::nanoseconds) { session->CompleteSyncRequest(); });
session->request_event =
Core::Timing::CreateEvent(name, [session](std::uintptr_t, std::chrono::nanoseconds) {
session->CompleteSyncRequest();
});
session->name = std::move(name);
session->parent = std::move(parent);

View File

@@ -16,14 +16,14 @@ namespace Kernel {
TimeManager::TimeManager(Core::System& system_) : system{system_} {
time_manager_event_type = Core::Timing::CreateEvent(
"Kernel::TimeManagerCallback", [this](u64 thread_handle, std::chrono::nanoseconds) {
SchedulerLock lock(system.Kernel());
Handle proper_handle = static_cast<Handle>(thread_handle);
"Kernel::TimeManagerCallback",
[this](std::uintptr_t thread_handle, std::chrono::nanoseconds) {
const SchedulerLock lock(system.Kernel());
const auto proper_handle = static_cast<Handle>(thread_handle);
if (cancelled_events[proper_handle]) {
return;
}
std::shared_ptr<Thread> thread =
this->system.Kernel().RetrieveThreadFromGlobalHandleTable(proper_handle);
auto thread = this->system.Kernel().RetrieveThreadFromGlobalHandleTable(proper_handle);
thread->OnWakeUp();
});
}

View File

@@ -1405,7 +1405,6 @@ void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) {
// Get supported languages from NACP, if possible
// Default to 0 (all languages supported)
u32 supported_languages = 0;
FileSys::PatchManager pm{system.CurrentProcess()->GetTitleID()};
const auto res = [this] {
const auto title_id = system.CurrentProcess()->GetTitleID();

View File

@@ -13,11 +13,23 @@
namespace Service::AM::Applets {
namespace {
enum class Request : u32 {
Finalize = 0x4,
SetUserWordInfo = 0x6,
SetCustomizeDic = 0x7,
Calc = 0xa,
SetCustomizedDictionaries = 0xb,
UnsetCustomizedDictionaries = 0xc,
UnknownD = 0xd,
UnknownE = 0xe,
};
constexpr std::size_t SWKBD_INLINE_INIT_SIZE = 0x8;
constexpr std::size_t SWKBD_OUTPUT_BUFFER_SIZE = 0x7D8;
constexpr std::size_t SWKBD_OUTPUT_INTERACTIVE_BUFFER_SIZE = 0x7D4;
constexpr std::size_t DEFAULT_MAX_LENGTH = 500;
constexpr bool INTERACTIVE_STATUS_OK = false;
} // Anonymous namespace
static Core::Frontend::SoftwareKeyboardParameters ConvertToFrontendParameters(
KeyboardConfig config, std::u16string initial_text) {
Core::Frontend::SoftwareKeyboardParameters params{};
@@ -47,6 +59,7 @@ SoftwareKeyboard::~SoftwareKeyboard() = default;
void SoftwareKeyboard::Initialize() {
complete = false;
is_inline = false;
initial_text.clear();
final_data.clear();
@@ -56,6 +69,11 @@ void SoftwareKeyboard::Initialize() {
ASSERT(keyboard_config_storage != nullptr);
const auto& keyboard_config = keyboard_config_storage->GetData();
if (keyboard_config.size() == SWKBD_INLINE_INIT_SIZE) {
is_inline = true;
return;
}
ASSERT(keyboard_config.size() >= sizeof(KeyboardConfig));
std::memcpy(&config, keyboard_config.data(), sizeof(KeyboardConfig));
@@ -87,16 +105,32 @@ void SoftwareKeyboard::ExecuteInteractive() {
const auto storage = broker.PopInteractiveDataToApplet();
ASSERT(storage != nullptr);
const auto data = storage->GetData();
const auto status = static_cast<bool>(data[0]);
if (status == INTERACTIVE_STATUS_OK) {
complete = true;
if (!is_inline) {
const auto status = static_cast<bool>(data[0]);
if (status == INTERACTIVE_STATUS_OK) {
complete = true;
} else {
std::array<char16_t, SWKBD_OUTPUT_INTERACTIVE_BUFFER_SIZE / 2 - 2> string;
std::memcpy(string.data(), data.data() + 4, string.size() * 2);
frontend.SendTextCheckDialog(
Common::UTF16StringFromFixedZeroTerminatedBuffer(string.data(), string.size()),
[this] { broker.SignalStateChanged(); });
}
} else {
std::array<char16_t, SWKBD_OUTPUT_INTERACTIVE_BUFFER_SIZE / 2 - 2> string;
std::memcpy(string.data(), data.data() + 4, string.size() * 2);
frontend.SendTextCheckDialog(
Common::UTF16StringFromFixedZeroTerminatedBuffer(string.data(), string.size()),
[this] { broker.SignalStateChanged(); });
Request request{};
std::memcpy(&request, data.data(), sizeof(Request));
switch (request) {
case Request::Calc: {
broker.PushNormalDataFromApplet(
std::make_shared<IStorage>(std::move(std::vector<u8>{1})));
broker.SignalStateChanged();
break;
}
default:
UNIMPLEMENTED_MSG("Request {:X} is not implemented", request);
break;
}
}
}
@@ -108,9 +142,10 @@ void SoftwareKeyboard::Execute() {
}
const auto parameters = ConvertToFrontendParameters(config, initial_text);
frontend.RequestText([this](std::optional<std::u16string> text) { WriteText(std::move(text)); },
parameters);
if (!is_inline) {
frontend.RequestText(
[this](std::optional<std::u16string> text) { WriteText(std::move(text)); }, parameters);
}
}
void SoftwareKeyboard::WriteText(std::optional<std::u16string> text) {

View File

@@ -78,6 +78,7 @@ private:
KeyboardConfig config;
std::u16string initial_text;
bool complete = false;
bool is_inline = false;
std::vector<u8> final_data;
};

View File

@@ -39,33 +39,36 @@ void Controller_DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing,
cur_entry.sampling_number = last_entry.sampling_number + 1;
cur_entry.sampling_number2 = cur_entry.sampling_number;
cur_entry.attribute.connected.Assign(1);
auto& pad = cur_entry.pad_state;
using namespace Settings::NativeButton;
pad.a.Assign(buttons[A - BUTTON_HID_BEGIN]->GetStatus());
pad.b.Assign(buttons[B - BUTTON_HID_BEGIN]->GetStatus());
pad.x.Assign(buttons[X - BUTTON_HID_BEGIN]->GetStatus());
pad.y.Assign(buttons[Y - BUTTON_HID_BEGIN]->GetStatus());
pad.l.Assign(buttons[L - BUTTON_HID_BEGIN]->GetStatus());
pad.r.Assign(buttons[R - BUTTON_HID_BEGIN]->GetStatus());
pad.zl.Assign(buttons[ZL - BUTTON_HID_BEGIN]->GetStatus());
pad.zr.Assign(buttons[ZR - BUTTON_HID_BEGIN]->GetStatus());
pad.plus.Assign(buttons[Plus - BUTTON_HID_BEGIN]->GetStatus());
pad.minus.Assign(buttons[Minus - BUTTON_HID_BEGIN]->GetStatus());
pad.d_left.Assign(buttons[DLeft - BUTTON_HID_BEGIN]->GetStatus());
pad.d_up.Assign(buttons[DUp - BUTTON_HID_BEGIN]->GetStatus());
pad.d_right.Assign(buttons[DRight - BUTTON_HID_BEGIN]->GetStatus());
pad.d_down.Assign(buttons[DDown - BUTTON_HID_BEGIN]->GetStatus());
if (Settings::values.debug_pad_enabled) {
cur_entry.attribute.connected.Assign(1);
auto& pad = cur_entry.pad_state;
const auto [stick_l_x_f, stick_l_y_f] =
analogs[static_cast<std::size_t>(JoystickId::Joystick_Left)]->GetStatus();
const auto [stick_r_x_f, stick_r_y_f] =
analogs[static_cast<std::size_t>(JoystickId::Joystick_Right)]->GetStatus();
cur_entry.l_stick.x = static_cast<s32>(stick_l_x_f * HID_JOYSTICK_MAX);
cur_entry.l_stick.y = static_cast<s32>(stick_l_y_f * HID_JOYSTICK_MAX);
cur_entry.r_stick.x = static_cast<s32>(stick_r_x_f * HID_JOYSTICK_MAX);
cur_entry.r_stick.y = static_cast<s32>(stick_r_y_f * HID_JOYSTICK_MAX);
using namespace Settings::NativeButton;
pad.a.Assign(buttons[A - BUTTON_HID_BEGIN]->GetStatus());
pad.b.Assign(buttons[B - BUTTON_HID_BEGIN]->GetStatus());
pad.x.Assign(buttons[X - BUTTON_HID_BEGIN]->GetStatus());
pad.y.Assign(buttons[Y - BUTTON_HID_BEGIN]->GetStatus());
pad.l.Assign(buttons[L - BUTTON_HID_BEGIN]->GetStatus());
pad.r.Assign(buttons[R - BUTTON_HID_BEGIN]->GetStatus());
pad.zl.Assign(buttons[ZL - BUTTON_HID_BEGIN]->GetStatus());
pad.zr.Assign(buttons[ZR - BUTTON_HID_BEGIN]->GetStatus());
pad.plus.Assign(buttons[Plus - BUTTON_HID_BEGIN]->GetStatus());
pad.minus.Assign(buttons[Minus - BUTTON_HID_BEGIN]->GetStatus());
pad.d_left.Assign(buttons[DLeft - BUTTON_HID_BEGIN]->GetStatus());
pad.d_up.Assign(buttons[DUp - BUTTON_HID_BEGIN]->GetStatus());
pad.d_right.Assign(buttons[DRight - BUTTON_HID_BEGIN]->GetStatus());
pad.d_down.Assign(buttons[DDown - BUTTON_HID_BEGIN]->GetStatus());
const auto [stick_l_x_f, stick_l_y_f] =
analogs[static_cast<std::size_t>(JoystickId::Joystick_Left)]->GetStatus();
const auto [stick_r_x_f, stick_r_y_f] =
analogs[static_cast<std::size_t>(JoystickId::Joystick_Right)]->GetStatus();
cur_entry.l_stick.x = static_cast<s32>(stick_l_x_f * HID_JOYSTICK_MAX);
cur_entry.l_stick.y = static_cast<s32>(stick_l_y_f * HID_JOYSTICK_MAX);
cur_entry.r_stick.x = static_cast<s32>(stick_r_x_f * HID_JOYSTICK_MAX);
cur_entry.r_stick.y = static_cast<s32>(stick_r_y_f * HID_JOYSTICK_MAX);
}
std::memcpy(data, &shared_memory, sizeof(SharedMemory));
}

View File

@@ -40,15 +40,16 @@ void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing,
cur_entry.key.fill(0);
cur_entry.modifier = 0;
if (Settings::values.keyboard_enabled) {
for (std::size_t i = 0; i < keyboard_keys.size(); ++i) {
cur_entry.key[i / KEYS_PER_BYTE] |=
(keyboard_keys[i]->GetStatus() << (i % KEYS_PER_BYTE));
}
for (std::size_t i = 0; i < keyboard_keys.size(); ++i) {
cur_entry.key[i / KEYS_PER_BYTE] |= (keyboard_keys[i]->GetStatus() << (i % KEYS_PER_BYTE));
for (std::size_t i = 0; i < keyboard_mods.size(); ++i) {
cur_entry.modifier |= (keyboard_mods[i]->GetStatus() << i);
}
}
for (std::size_t i = 0; i < keyboard_mods.size(); ++i) {
cur_entry.modifier |= (keyboard_mods[i]->GetStatus() << i);
}
std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory));
}

View File

@@ -77,8 +77,9 @@ IAppletResource::IAppletResource(Core::System& system)
// Register update callbacks
pad_update_event = Core::Timing::CreateEvent(
"HID::UpdatePadCallback", [this](u64 userdata, std::chrono::nanoseconds ns_late) {
UpdateControllers(userdata, ns_late);
"HID::UpdatePadCallback",
[this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
UpdateControllers(user_data, ns_late);
});
// TODO(shinyquagsire23): Other update callbacks? (accel, gyro?)
@@ -108,7 +109,8 @@ void IAppletResource::GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) {
rb.PushCopyObjects(shared_mem);
}
void IAppletResource::UpdateControllers(u64 userdata, std::chrono::nanoseconds ns_late) {
void IAppletResource::UpdateControllers(std::uintptr_t user_data,
std::chrono::nanoseconds ns_late) {
auto& core_timing = system.CoreTiming();
const bool should_reload = Settings::values.is_device_reload_pending.exchange(false);

View File

@@ -64,7 +64,7 @@ private:
}
void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx);
void UpdateControllers(u64 userdata, std::chrono::nanoseconds ns_late);
void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
std::shared_ptr<Kernel::SharedMemory> shared_mem;

View File

@@ -67,8 +67,8 @@ NVFlinger::NVFlinger(Core::System& system) : system(system) {
// Schedule the screen composition events
composition_event = Core::Timing::CreateEvent(
"ScreenComposition", [this](u64, std::chrono::nanoseconds ns_late) {
Lock();
"ScreenComposition", [this](std::uintptr_t, std::chrono::nanoseconds ns_late) {
const auto guard = Lock();
Compose();
const auto ticks = std::chrono::nanoseconds{GetNextTicks()};

View File

@@ -54,12 +54,12 @@ public:
/// Opens the specified display and returns the ID.
///
/// If an invalid display name is provided, then an empty optional is returned.
std::optional<u64> OpenDisplay(std::string_view name);
[[nodiscard]] std::optional<u64> OpenDisplay(std::string_view name);
/// Creates a layer on the specified display and returns the layer ID.
///
/// If an invalid display ID is specified, then an empty optional is returned.
std::optional<u64> CreateLayer(u64 display_id);
[[nodiscard]] std::optional<u64> CreateLayer(u64 display_id);
/// Closes a layer on all displays for the given layer ID.
void CloseLayer(u64 layer_id);
@@ -67,41 +67,39 @@ public:
/// Finds the buffer queue ID of the specified layer in the specified display.
///
/// If an invalid display ID or layer ID is provided, then an empty optional is returned.
std::optional<u32> FindBufferQueueId(u64 display_id, u64 layer_id) const;
[[nodiscard]] std::optional<u32> FindBufferQueueId(u64 display_id, u64 layer_id) const;
/// Gets the vsync event for the specified display.
///
/// If an invalid display ID is provided, then nullptr is returned.
std::shared_ptr<Kernel::ReadableEvent> FindVsyncEvent(u64 display_id) const;
[[nodiscard]] std::shared_ptr<Kernel::ReadableEvent> FindVsyncEvent(u64 display_id) const;
/// Obtains a buffer queue identified by the ID.
BufferQueue& FindBufferQueue(u32 id);
[[nodiscard]] BufferQueue& FindBufferQueue(u32 id);
/// Obtains a buffer queue identified by the ID.
const BufferQueue& FindBufferQueue(u32 id) const;
[[nodiscard]] const BufferQueue& FindBufferQueue(u32 id) const;
/// Performs a composition request to the emulated nvidia GPU and triggers the vsync events when
/// finished.
void Compose();
s64 GetNextTicks() const;
[[nodiscard]] s64 GetNextTicks() const;
std::unique_lock<std::mutex> Lock() {
return std::unique_lock{*guard};
}
[[nodiscard]] std::unique_lock<std::mutex> Lock() const { return std::unique_lock{*guard}; }
private:
/// Finds the display identified by the specified ID.
VI::Display* FindDisplay(u64 display_id);
private :
/// Finds the display identified by the specified ID.
[[nodiscard]] VI::Display* FindDisplay(u64 display_id);
/// Finds the display identified by the specified ID.
const VI::Display* FindDisplay(u64 display_id) const;
[[nodiscard]] const VI::Display* FindDisplay(u64 display_id) const;
/// Finds the layer identified by the specified ID in the desired display.
VI::Layer* FindLayer(u64 display_id, u64 layer_id);
[[nodiscard]] VI::Layer* FindLayer(u64 display_id, u64 layer_id);
/// Finds the layer identified by the specified ID in the desired display.
const VI::Layer* FindLayer(u64 display_id, u64 layer_id) const;
[[nodiscard]] const VI::Layer* FindLayer(u64 display_id, u64 layer_id) const;
static void VSyncThread(NVFlinger& nv_flinger);

View File

@@ -511,7 +511,7 @@ private:
LOG_DEBUG(Service_VI, "called. id=0x{:08X} transaction={:X}, flags=0x{:08X}", id,
static_cast<u32>(transaction), flags);
nv_flinger->Lock();
const auto guard = nv_flinger->Lock();
auto& buffer_queue = nv_flinger->FindBufferQueue(id);
switch (transaction) {
@@ -551,7 +551,7 @@ private:
[=](std::shared_ptr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx,
Kernel::ThreadWakeupReason reason) {
// Repeat TransactParcel DequeueBuffer when a buffer is available
nv_flinger->Lock();
const auto guard = nv_flinger->Lock();
auto& buffer_queue = nv_flinger->FindBufferQueue(id);
auto result = buffer_queue.DequeueBuffer(width, height);
ASSERT_MSG(result != std::nullopt, "Could not dequeue buffer.");

View File

@@ -188,11 +188,11 @@ CheatEngine::~CheatEngine() {
}
void CheatEngine::Initialize() {
event = Core::Timing::CreateEvent("CheatEngine::FrameCallback::" +
Common::HexToString(metadata.main_nso_build_id),
[this](u64 userdata, std::chrono::nanoseconds ns_late) {
FrameCallback(userdata, ns_late);
});
event = Core::Timing::CreateEvent(
"CheatEngine::FrameCallback::" + Common::HexToString(metadata.main_nso_build_id),
[this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
FrameCallback(user_data, ns_late);
});
core_timing.ScheduleEvent(CHEAT_ENGINE_NS, event);
metadata.process_id = system.CurrentProcess()->GetProcessID();
@@ -219,7 +219,7 @@ void CheatEngine::Reload(std::vector<CheatEntry> cheats) {
MICROPROFILE_DEFINE(Cheat_Engine, "Add-Ons", "Cheat Engine", MP_RGB(70, 200, 70));
void CheatEngine::FrameCallback(u64, std::chrono::nanoseconds ns_late) {
void CheatEngine::FrameCallback(std::uintptr_t, std::chrono::nanoseconds ns_late) {
if (is_pending_reload.exchange(false)) {
vm.LoadProgram(cheats);
}

View File

@@ -72,7 +72,7 @@ public:
void Reload(std::vector<CheatEntry> cheats);
private:
void FrameCallback(u64 userdata, std::chrono::nanoseconds ns_late);
void FrameCallback(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
DmntCheatVm vm;
CheatProcessMetadata metadata;

View File

@@ -313,30 +313,32 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) {
switch (opcode_type) {
case CheatVmOpcodeType::StoreStatic: {
StoreStaticOpcode store_static{};
// 0TMR00AA AAAAAAAA YYYYYYYY (YYYYYYYY)
// Read additional words.
const u32 second_dword = GetNextDword();
store_static.bit_width = (first_dword >> 24) & 0xF;
store_static.mem_type = static_cast<MemoryAccessType>((first_dword >> 20) & 0xF);
store_static.offset_register = ((first_dword >> 16) & 0xF);
store_static.rel_address =
(static_cast<u64>(first_dword & 0xFF) << 32ul) | static_cast<u64>(second_dword);
store_static.value = GetNextVmInt(store_static.bit_width);
opcode.opcode = store_static;
const u32 bit_width = (first_dword >> 24) & 0xF;
opcode.opcode = StoreStaticOpcode{
.bit_width = bit_width,
.mem_type = static_cast<MemoryAccessType>((first_dword >> 20) & 0xF),
.offset_register = (first_dword >> 16) & 0xF,
.rel_address = (static_cast<u64>(first_dword & 0xFF) << 32) | second_dword,
.value = GetNextVmInt(bit_width),
};
} break;
case CheatVmOpcodeType::BeginConditionalBlock: {
BeginConditionalOpcode begin_cond{};
// 1TMC00AA AAAAAAAA YYYYYYYY (YYYYYYYY)
// Read additional words.
const u32 second_dword = GetNextDword();
begin_cond.bit_width = (first_dword >> 24) & 0xF;
begin_cond.mem_type = static_cast<MemoryAccessType>((first_dword >> 20) & 0xF);
begin_cond.cond_type = static_cast<ConditionalComparisonType>((first_dword >> 16) & 0xF);
begin_cond.rel_address =
(static_cast<u64>(first_dword & 0xFF) << 32ul) | static_cast<u64>(second_dword);
begin_cond.value = GetNextVmInt(begin_cond.bit_width);
opcode.opcode = begin_cond;
const u32 bit_width = (first_dword >> 24) & 0xF;
opcode.opcode = BeginConditionalOpcode{
.bit_width = bit_width,
.mem_type = static_cast<MemoryAccessType>((first_dword >> 20) & 0xF),
.cond_type = static_cast<ConditionalComparisonType>((first_dword >> 16) & 0xF),
.rel_address = (static_cast<u64>(first_dword & 0xFF) << 32) | second_dword,
.value = GetNextVmInt(bit_width),
};
} break;
case CheatVmOpcodeType::EndConditionalBlock: {
// 20000000
@@ -344,12 +346,14 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) {
opcode.opcode = EndConditionalOpcode{};
} break;
case CheatVmOpcodeType::ControlLoop: {
ControlLoopOpcode ctrl_loop{};
// 300R0000 VVVVVVVV
// 310R0000
// Parse register, whether loop start or loop end.
ctrl_loop.start_loop = ((first_dword >> 24) & 0xF) == 0;
ctrl_loop.reg_index = ((first_dword >> 20) & 0xF);
ControlLoopOpcode ctrl_loop{
.start_loop = ((first_dword >> 24) & 0xF) == 0,
.reg_index = (first_dword >> 20) & 0xF,
.num_iters = 0,
};
// Read number of iters if loop start.
if (ctrl_loop.start_loop) {
@@ -358,66 +362,65 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) {
opcode.opcode = ctrl_loop;
} break;
case CheatVmOpcodeType::LoadRegisterStatic: {
LoadRegisterStaticOpcode ldr_static{};
// 400R0000 VVVVVVVV VVVVVVVV
// Read additional words.
ldr_static.reg_index = ((first_dword >> 16) & 0xF);
ldr_static.value =
(static_cast<u64>(GetNextDword()) << 32ul) | static_cast<u64>(GetNextDword());
opcode.opcode = ldr_static;
opcode.opcode = LoadRegisterStaticOpcode{
.reg_index = (first_dword >> 16) & 0xF,
.value = (static_cast<u64>(GetNextDword()) << 32) | GetNextDword(),
};
} break;
case CheatVmOpcodeType::LoadRegisterMemory: {
LoadRegisterMemoryOpcode ldr_memory{};
// 5TMRI0AA AAAAAAAA
// Read additional words.
const u32 second_dword = GetNextDword();
ldr_memory.bit_width = (first_dword >> 24) & 0xF;
ldr_memory.mem_type = static_cast<MemoryAccessType>((first_dword >> 20) & 0xF);
ldr_memory.reg_index = ((first_dword >> 16) & 0xF);
ldr_memory.load_from_reg = ((first_dword >> 12) & 0xF) != 0;
ldr_memory.rel_address =
(static_cast<u64>(first_dword & 0xFF) << 32ul) | static_cast<u64>(second_dword);
opcode.opcode = ldr_memory;
opcode.opcode = LoadRegisterMemoryOpcode{
.bit_width = (first_dword >> 24) & 0xF,
.mem_type = static_cast<MemoryAccessType>((first_dword >> 20) & 0xF),
.reg_index = ((first_dword >> 16) & 0xF),
.load_from_reg = ((first_dword >> 12) & 0xF) != 0,
.rel_address = (static_cast<u64>(first_dword & 0xFF) << 32) | second_dword,
};
} break;
case CheatVmOpcodeType::StoreStaticToAddress: {
StoreStaticToAddressOpcode str_static{};
// 6T0RIor0 VVVVVVVV VVVVVVVV
// Read additional words.
str_static.bit_width = (first_dword >> 24) & 0xF;
str_static.reg_index = ((first_dword >> 16) & 0xF);
str_static.increment_reg = ((first_dword >> 12) & 0xF) != 0;
str_static.add_offset_reg = ((first_dword >> 8) & 0xF) != 0;
str_static.offset_reg_index = ((first_dword >> 4) & 0xF);
str_static.value =
(static_cast<u64>(GetNextDword()) << 32ul) | static_cast<u64>(GetNextDword());
opcode.opcode = str_static;
opcode.opcode = StoreStaticToAddressOpcode{
.bit_width = (first_dword >> 24) & 0xF,
.reg_index = (first_dword >> 16) & 0xF,
.increment_reg = ((first_dword >> 12) & 0xF) != 0,
.add_offset_reg = ((first_dword >> 8) & 0xF) != 0,
.offset_reg_index = (first_dword >> 4) & 0xF,
.value = (static_cast<u64>(GetNextDword()) << 32) | GetNextDword(),
};
} break;
case CheatVmOpcodeType::PerformArithmeticStatic: {
PerformArithmeticStaticOpcode perform_math_static{};
// 7T0RC000 VVVVVVVV
// Read additional words.
perform_math_static.bit_width = (first_dword >> 24) & 0xF;
perform_math_static.reg_index = ((first_dword >> 16) & 0xF);
perform_math_static.math_type =
static_cast<RegisterArithmeticType>((first_dword >> 12) & 0xF);
perform_math_static.value = GetNextDword();
opcode.opcode = perform_math_static;
opcode.opcode = PerformArithmeticStaticOpcode{
.bit_width = (first_dword >> 24) & 0xF,
.reg_index = ((first_dword >> 16) & 0xF),
.math_type = static_cast<RegisterArithmeticType>((first_dword >> 12) & 0xF),
.value = GetNextDword(),
};
} break;
case CheatVmOpcodeType::BeginKeypressConditionalBlock: {
BeginKeypressConditionalOpcode begin_keypress_cond{};
// 8kkkkkkk
// Just parse the mask.
begin_keypress_cond.key_mask = first_dword & 0x0FFFFFFF;
opcode.opcode = begin_keypress_cond;
opcode.opcode = BeginKeypressConditionalOpcode{
.key_mask = first_dword & 0x0FFFFFFF,
};
} break;
case CheatVmOpcodeType::PerformArithmeticRegister: {
PerformArithmeticRegisterOpcode perform_math_reg{};
// 9TCRSIs0 (VVVVVVVV (VVVVVVVV))
perform_math_reg.bit_width = (first_dword >> 24) & 0xF;
perform_math_reg.math_type = static_cast<RegisterArithmeticType>((first_dword >> 20) & 0xF);
perform_math_reg.dst_reg_index = ((first_dword >> 16) & 0xF);
perform_math_reg.src_reg_1_index = ((first_dword >> 12) & 0xF);
perform_math_reg.has_immediate = ((first_dword >> 8) & 0xF) != 0;
PerformArithmeticRegisterOpcode perform_math_reg{
.bit_width = (first_dword >> 24) & 0xF,
.math_type = static_cast<RegisterArithmeticType>((first_dword >> 20) & 0xF),
.dst_reg_index = (first_dword >> 16) & 0xF,
.src_reg_1_index = (first_dword >> 12) & 0xF,
.src_reg_2_index = 0,
.has_immediate = ((first_dword >> 8) & 0xF) != 0,
.value = {},
};
if (perform_math_reg.has_immediate) {
perform_math_reg.src_reg_2_index = 0;
perform_math_reg.value = GetNextVmInt(perform_math_reg.bit_width);
@@ -427,7 +430,6 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) {
opcode.opcode = perform_math_reg;
} break;
case CheatVmOpcodeType::StoreRegisterToAddress: {
StoreRegisterToAddressOpcode str_register{};
// ATSRIOxa (aaaaaaaa)
// A = opcode 10
// T = bit width
@@ -439,20 +441,23 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) {
// Relative Address
// x = offset register (for offset type 1), memory type (for offset type 3)
// a = relative address (for offset type 2+3)
str_register.bit_width = (first_dword >> 24) & 0xF;
str_register.str_reg_index = ((first_dword >> 20) & 0xF);
str_register.addr_reg_index = ((first_dword >> 16) & 0xF);
str_register.increment_reg = ((first_dword >> 12) & 0xF) != 0;
str_register.ofs_type = static_cast<StoreRegisterOffsetType>(((first_dword >> 8) & 0xF));
str_register.ofs_reg_index = ((first_dword >> 4) & 0xF);
StoreRegisterToAddressOpcode str_register{
.bit_width = (first_dword >> 24) & 0xF,
.str_reg_index = (first_dword >> 20) & 0xF,
.addr_reg_index = (first_dword >> 16) & 0xF,
.increment_reg = ((first_dword >> 12) & 0xF) != 0,
.ofs_type = static_cast<StoreRegisterOffsetType>(((first_dword >> 8) & 0xF)),
.mem_type = MemoryAccessType::MainNso,
.ofs_reg_index = (first_dword >> 4) & 0xF,
.rel_address = 0,
};
switch (str_register.ofs_type) {
case StoreRegisterOffsetType::None:
case StoreRegisterOffsetType::Reg:
// Nothing more to do
break;
case StoreRegisterOffsetType::Imm:
str_register.rel_address =
((static_cast<u64>(first_dword & 0xF) << 32ul) | static_cast<u64>(GetNextDword()));
str_register.rel_address = (static_cast<u64>(first_dword & 0xF) << 32) | GetNextDword();
break;
case StoreRegisterOffsetType::MemReg:
str_register.mem_type = static_cast<MemoryAccessType>((first_dword >> 4) & 0xF);
@@ -460,8 +465,7 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) {
case StoreRegisterOffsetType::MemImm:
case StoreRegisterOffsetType::MemImmReg:
str_register.mem_type = static_cast<MemoryAccessType>((first_dword >> 4) & 0xF);
str_register.rel_address =
((static_cast<u64>(first_dword & 0xF) << 32ul) | static_cast<u64>(GetNextDword()));
str_register.rel_address = (static_cast<u64>(first_dword & 0xF) << 32) | GetNextDword();
break;
default:
str_register.ofs_type = StoreRegisterOffsetType::None;
@@ -470,7 +474,6 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) {
opcode.opcode = str_register;
} break;
case CheatVmOpcodeType::BeginRegisterConditionalBlock: {
BeginRegisterConditionalOpcode begin_reg_cond{};
// C0TcSX##
// C0TcS0Ma aaaaaaaa
// C0TcS1Mr
@@ -492,11 +495,19 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) {
// r = offset register.
// X = other register.
// V = value.
begin_reg_cond.bit_width = (first_dword >> 20) & 0xF;
begin_reg_cond.cond_type =
static_cast<ConditionalComparisonType>((first_dword >> 16) & 0xF);
begin_reg_cond.val_reg_index = ((first_dword >> 12) & 0xF);
begin_reg_cond.comp_type = static_cast<CompareRegisterValueType>((first_dword >> 8) & 0xF);
BeginRegisterConditionalOpcode begin_reg_cond{
.bit_width = (first_dword >> 20) & 0xF,
.cond_type = static_cast<ConditionalComparisonType>((first_dword >> 16) & 0xF),
.val_reg_index = (first_dword >> 12) & 0xF,
.comp_type = static_cast<CompareRegisterValueType>((first_dword >> 8) & 0xF),
.mem_type = MemoryAccessType::MainNso,
.addr_reg_index = 0,
.other_reg_index = 0,
.ofs_reg_index = 0,
.rel_address = 0,
.value = {},
};
switch (begin_reg_cond.comp_type) {
case CompareRegisterValueType::StaticValue:
@@ -508,26 +519,25 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) {
case CompareRegisterValueType::MemoryRelAddr:
begin_reg_cond.mem_type = static_cast<MemoryAccessType>((first_dword >> 4) & 0xF);
begin_reg_cond.rel_address =
((static_cast<u64>(first_dword & 0xF) << 32ul) | static_cast<u64>(GetNextDword()));
(static_cast<u64>(first_dword & 0xF) << 32) | GetNextDword();
break;
case CompareRegisterValueType::MemoryOfsReg:
begin_reg_cond.mem_type = static_cast<MemoryAccessType>((first_dword >> 4) & 0xF);
begin_reg_cond.ofs_reg_index = (first_dword & 0xF);
break;
case CompareRegisterValueType::RegisterRelAddr:
begin_reg_cond.addr_reg_index = ((first_dword >> 4) & 0xF);
begin_reg_cond.addr_reg_index = (first_dword >> 4) & 0xF;
begin_reg_cond.rel_address =
((static_cast<u64>(first_dword & 0xF) << 32ul) | static_cast<u64>(GetNextDword()));
(static_cast<u64>(first_dword & 0xF) << 32) | GetNextDword();
break;
case CompareRegisterValueType::RegisterOfsReg:
begin_reg_cond.addr_reg_index = ((first_dword >> 4) & 0xF);
begin_reg_cond.ofs_reg_index = (first_dword & 0xF);
begin_reg_cond.addr_reg_index = (first_dword >> 4) & 0xF;
begin_reg_cond.ofs_reg_index = first_dword & 0xF;
break;
}
opcode.opcode = begin_reg_cond;
} break;
case CheatVmOpcodeType::SaveRestoreRegister: {
SaveRestoreRegisterOpcode save_restore_reg{};
// C10D0Sx0
// C1 = opcode 0xC1
// D = destination index.
@@ -535,36 +545,37 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) {
// x = 3 if clearing reg, 2 if clearing saved value, 1 if saving a register, 0 if restoring
// a register.
// NOTE: If we add more save slots later, current encoding is backwards compatible.
save_restore_reg.dst_index = (first_dword >> 16) & 0xF;
save_restore_reg.src_index = (first_dword >> 8) & 0xF;
save_restore_reg.op_type = static_cast<SaveRestoreRegisterOpType>((first_dword >> 4) & 0xF);
opcode.opcode = save_restore_reg;
opcode.opcode = SaveRestoreRegisterOpcode{
.dst_index = (first_dword >> 16) & 0xF,
.src_index = (first_dword >> 8) & 0xF,
.op_type = static_cast<SaveRestoreRegisterOpType>((first_dword >> 4) & 0xF),
};
} break;
case CheatVmOpcodeType::SaveRestoreRegisterMask: {
SaveRestoreRegisterMaskOpcode save_restore_regmask{};
// C2x0XXXX
// C2 = opcode 0xC2
// x = 3 if clearing reg, 2 if clearing saved value, 1 if saving, 0 if restoring.
// X = 16-bit bitmask, bit i --> save or restore register i.
save_restore_regmask.op_type =
static_cast<SaveRestoreRegisterOpType>((first_dword >> 20) & 0xF);
SaveRestoreRegisterMaskOpcode save_restore_regmask{
.op_type = static_cast<SaveRestoreRegisterOpType>((first_dword >> 20) & 0xF),
.should_operate = {},
};
for (std::size_t i = 0; i < NumRegisters; i++) {
save_restore_regmask.should_operate[i] = (first_dword & (1u << i)) != 0;
save_restore_regmask.should_operate[i] = (first_dword & (1U << i)) != 0;
}
opcode.opcode = save_restore_regmask;
} break;
case CheatVmOpcodeType::ReadWriteStaticRegister: {
ReadWriteStaticRegisterOpcode rw_static_reg{};
// C3000XXx
// C3 = opcode 0xC3.
// XX = static register index.
// x = register index.
rw_static_reg.static_idx = ((first_dword >> 4) & 0xFF);
rw_static_reg.idx = (first_dword & 0xF);
opcode.opcode = rw_static_reg;
opcode.opcode = ReadWriteStaticRegisterOpcode{
.static_idx = (first_dword >> 4) & 0xFF,
.idx = first_dword & 0xF,
};
} break;
case CheatVmOpcodeType::DebugLog: {
DebugLogOpcode debug_log{};
// FFFTIX##
// FFFTI0Ma aaaaaaaa
// FFFTI1Mr
@@ -583,31 +594,36 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) {
// a = relative address.
// r = offset register.
// X = value register.
debug_log.bit_width = (first_dword >> 16) & 0xF;
debug_log.log_id = ((first_dword >> 12) & 0xF);
debug_log.val_type = static_cast<DebugLogValueType>((first_dword >> 8) & 0xF);
DebugLogOpcode debug_log{
.bit_width = (first_dword >> 16) & 0xF,
.log_id = (first_dword >> 12) & 0xF,
.val_type = static_cast<DebugLogValueType>((first_dword >> 8) & 0xF),
.mem_type = MemoryAccessType::MainNso,
.addr_reg_index = 0,
.val_reg_index = 0,
.ofs_reg_index = 0,
.rel_address = 0,
};
switch (debug_log.val_type) {
case DebugLogValueType::RegisterValue:
debug_log.val_reg_index = ((first_dword >> 4) & 0xF);
debug_log.val_reg_index = (first_dword >> 4) & 0xF;
break;
case DebugLogValueType::MemoryRelAddr:
debug_log.mem_type = static_cast<MemoryAccessType>((first_dword >> 4) & 0xF);
debug_log.rel_address =
((static_cast<u64>(first_dword & 0xF) << 32ul) | static_cast<u64>(GetNextDword()));
debug_log.rel_address = (static_cast<u64>(first_dword & 0xF) << 32) | GetNextDword();
break;
case DebugLogValueType::MemoryOfsReg:
debug_log.mem_type = static_cast<MemoryAccessType>((first_dword >> 4) & 0xF);
debug_log.ofs_reg_index = (first_dword & 0xF);
debug_log.ofs_reg_index = first_dword & 0xF;
break;
case DebugLogValueType::RegisterRelAddr:
debug_log.addr_reg_index = ((first_dword >> 4) & 0xF);
debug_log.rel_address =
((static_cast<u64>(first_dword & 0xF) << 32ul) | static_cast<u64>(GetNextDword()));
debug_log.addr_reg_index = (first_dword >> 4) & 0xF;
debug_log.rel_address = (static_cast<u64>(first_dword & 0xF) << 32) | GetNextDword();
break;
case DebugLogValueType::RegisterOfsReg:
debug_log.addr_reg_index = ((first_dword >> 4) & 0xF);
debug_log.ofs_reg_index = (first_dword & 0xF);
debug_log.addr_reg_index = (first_dword >> 4) & 0xF;
debug_log.ofs_reg_index = first_dword & 0xF;
break;
}
opcode.opcode = debug_log;

View File

@@ -55,10 +55,11 @@ void MemoryWriteWidth(Core::Memory::Memory& memory, u32 width, VAddr addr, u64 v
Freezer::Freezer(Core::Timing::CoreTiming& core_timing_, Core::Memory::Memory& memory_)
: core_timing{core_timing_}, memory{memory_} {
event = Core::Timing::CreateEvent("MemoryFreezer::FrameCallback",
[this](u64 userdata, std::chrono::nanoseconds ns_late) {
FrameCallback(userdata, ns_late);
});
event = Core::Timing::CreateEvent(
"MemoryFreezer::FrameCallback",
[this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
FrameCallback(user_data, ns_late);
});
core_timing.ScheduleEvent(memory_freezer_ns, event);
}
@@ -159,7 +160,7 @@ std::vector<Freezer::Entry> Freezer::GetEntries() const {
return entries;
}
void Freezer::FrameCallback(u64, std::chrono::nanoseconds ns_late) {
void Freezer::FrameCallback(std::uintptr_t, std::chrono::nanoseconds ns_late) {
if (!IsActive()) {
LOG_DEBUG(Common_Memory, "Memory freezer has been deactivated, ending callback events.");
return;

View File

@@ -73,7 +73,7 @@ public:
std::vector<Entry> GetEntries() const;
private:
void FrameCallback(u64 userdata, std::chrono::nanoseconds ns_late);
void FrameCallback(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
void FillEntryReads();
std::atomic_bool active{false};

View File

@@ -254,7 +254,7 @@ void Adapter::GetGCEndpoint(libusb_device* device) {
sizeof(clear_payload), nullptr, 16);
adapter_thread_running = true;
adapter_input_thread = std::thread([=] { Read(); }); // Read input
adapter_input_thread = std::thread(&Adapter::Read, this);
}
Adapter::~Adapter() {
@@ -265,7 +265,9 @@ void Adapter::Reset() {
if (adapter_thread_running) {
adapter_thread_running = false;
}
adapter_input_thread.join();
if (adapter_input_thread.joinable()) {
adapter_input_thread.join();
}
adapter_controllers_status.fill(ControllerTypes::None);
get_origin.fill(true);

View File

@@ -76,8 +76,7 @@ std::unique_ptr<Input::ButtonDevice> GCButtonFactory::Create(const Common::Param
// button is not an axis/stick button
if (button_id != PAD_STICK_ID) {
auto button = std::make_unique<GCButton>(port, button_id, adapter.get());
return std::move(button);
return std::make_unique<GCButton>(port, button_id, adapter.get());
}
// For Axis buttons, used by the binary sticks.
@@ -264,7 +263,8 @@ Common::ParamPackage GCAnalogFactory::GetNextInput() {
if (analog_x_axis == -1) {
analog_x_axis = axis;
controller_number = static_cast<int>(port);
} else if (analog_y_axis == -1 && analog_x_axis != axis && controller_number == port) {
} else if (analog_y_axis == -1 && analog_x_axis != axis &&
controller_number == static_cast<int>(port)) {
analog_y_axis = axis;
}
}

View File

@@ -9,7 +9,6 @@
#include <functional>
#include <thread>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include "common/logging/log.h"
#include "input_common/udp/client.h"
#include "input_common/udp/protocol.h"

View File

@@ -25,10 +25,10 @@ std::bitset<CB_IDS.size()> callbacks_ran_flags;
u64 expected_callback = 0;
template <unsigned int IDX>
void HostCallbackTemplate(u64 userdata, std::chrono::nanoseconds ns_late) {
void HostCallbackTemplate(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
static_assert(IDX < CB_IDS.size(), "IDX out of range");
callbacks_ran_flags.set(IDX);
REQUIRE(CB_IDS[IDX] == userdata);
REQUIRE(CB_IDS[IDX] == user_data);
REQUIRE(CB_IDS[IDX] == CB_IDS[calls_order[expected_callback]]);
delays[IDX] = ns_late.count();
++expected_callback;

View File

@@ -252,7 +252,7 @@ public:
const Tegra::DmaPusher& DmaPusher() const;
struct Regs {
static constexpr size_t NUM_REGS = 0x100;
static constexpr size_t NUM_REGS = 0x40;
union {
struct {
@@ -271,7 +271,7 @@ public:
u32 semaphore_trigger;
INSERT_UNION_PADDING_WORDS(0xC);
// The puser and the puller share the reference counter, the pusher only has read
// The pusher and the puller share the reference counter, the pusher only has read
// access
u32 reference_count;
INSERT_UNION_PADDING_WORDS(0x5);

View File

@@ -532,10 +532,6 @@ void RasterizerVulkan::Clear() {
scheduler.Record([clear_depth = regs.clear_depth, clear_stencil = regs.clear_stencil,
clear_rect, aspect_flags](vk::CommandBuffer cmdbuf) {
VkClearValue clear_value;
clear_value.depthStencil.depth = clear_depth;
clear_value.depthStencil.stencil = clear_stencil;
VkClearAttachment attachment;
attachment.aspectMask = aspect_flags;
attachment.colorAttachment = 0;

View File

@@ -156,6 +156,7 @@ void VKSwapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities,
.minImageCount = requested_image_count,
.imageFormat = surface_format.format,
.imageColorSpace = surface_format.colorSpace,
.imageExtent = {},
.imageArrayLayers = 1,
.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
@@ -204,6 +205,7 @@ void VKSwapchain::CreateImageViews() {
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.image = {},
.viewType = VK_IMAGE_VIEW_TYPE_2D,
.format = image_format,
.components =

View File

@@ -138,6 +138,7 @@ VkImageCreateInfo GenerateImageCreateInfo(const VKDevice& device, const SurfaceP
.flags = 0,
.imageType = SurfaceTargetToImage(params.target),
.format = format,
.extent = {},
.mipLevels = params.num_levels,
.arrayLayers = static_cast<u32>(params.GetNumLayers()),
.samples = VK_SAMPLE_COUNT_1_BIT,
@@ -458,6 +459,7 @@ VkImageView CachedSurfaceView::GetAttachment() {
.pNext = nullptr,
.flags = 0,
.image = surface.GetImageHandle(),
.viewType = VK_IMAGE_VIEW_TYPE_1D,
.format = surface.GetImage().GetFormat(),
.components =
{

View File

@@ -170,26 +170,6 @@
<string>Dump</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QCheckBox" name="dump_decompressed_nso">
<property name="whatsThis">
<string>When checked, any NSO yuzu tries to load or patch will be copied decompressed to the yuzu/dump directory.</string>
</property>
<property name="text">
<string>Dump Decompressed NSOs</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="dump_exefs">
<property name="whatsThis">
<string>When checked, any game that yuzu loads will have its ExeFS dumped to the yuzu/dump directory.</string>
</property>
<property name="text">
<string>Dump ExeFS</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="reporting_services">
<property name="text">
@@ -257,8 +237,6 @@
<tabstop>open_log_button</tabstop>
<tabstop>homebrew_args_edit</tabstop>
<tabstop>enable_graphics_debugging</tabstop>
<tabstop>dump_decompressed_nso</tabstop>
<tabstop>dump_exefs</tabstop>
<tabstop>reporting_services</tabstop>
<tabstop>quest_flag</tabstop>
</tabstops>