mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-20 17:36:10 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9fac15716d | |||
| 565f9a3005 | |||
| 01f149ddfd | |||
| 4bcc2a2319 | |||
| 8b03a1ba01 | |||
| 652ab5c25c |
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -35,7 +38,7 @@ void CircularBufferSinkInfo::Update(BehaviorInfo::ErrorInfo& error_info, OutStat
|
|||||||
auto current_params{reinterpret_cast<CircularBufferInParameter*>(parameter.data())};
|
auto current_params{reinterpret_cast<CircularBufferInParameter*>(parameter.data())};
|
||||||
auto current_state{reinterpret_cast<CircularBufferState*>(state.data())};
|
auto current_state{reinterpret_cast<CircularBufferState*>(state.data())};
|
||||||
|
|
||||||
if (in_use == buffer_params->in_use && !buffer_unmapped) {
|
if (in_use == bool(buffer_params->in_use) && !buffer_unmapped) {
|
||||||
error_info.error_code = ResultSuccess;
|
error_info.error_code = ResultSuccess;
|
||||||
error_info.address = CpuAddr(0);
|
error_info.address = CpuAddr(0);
|
||||||
out_status.writeOffset = current_state->last_pos2;
|
out_status.writeOffset = current_state->last_pos2;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
@@ -31,10 +31,10 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct DeviceInParameter {
|
struct DeviceInParameter {
|
||||||
/* 0x000 */ char name[0x100];
|
/* 0x000 */ u8 name[0x100];
|
||||||
/* 0x100 */ u32 input_count;
|
/* 0x100 */ u32 input_count;
|
||||||
/* 0x104 */ std::array<s8, MaxChannels> inputs;
|
/* 0x104 */ std::array<s8, MaxChannels> inputs;
|
||||||
/* 0x10A */ char unk10A[0x1];
|
/* 0x10A */ u8 unk10A[0x1];
|
||||||
/* 0x10B */ bool downmix_enabled;
|
/* 0x10B */ bool downmix_enabled;
|
||||||
/* 0x10C */ std::array<f32, 4> downmix_coeff;
|
/* 0x10C */ std::array<f32, 4> downmix_coeff;
|
||||||
};
|
};
|
||||||
@@ -43,7 +43,7 @@ public:
|
|||||||
struct DeviceState {
|
struct DeviceState {
|
||||||
/* 0x00 */ UpsamplerInfo* upsampler_info;
|
/* 0x00 */ UpsamplerInfo* upsampler_info;
|
||||||
/* 0x08 */ std::array<Common::FixedPoint<16, 16>, 4> downmix_coeff;
|
/* 0x08 */ std::array<Common::FixedPoint<16, 16>, 4> downmix_coeff;
|
||||||
/* 0x18 */ char unk18[0x18];
|
/* 0x18 */ u8 unk18[0x18];
|
||||||
};
|
};
|
||||||
static_assert(sizeof(DeviceState) == 0x30, "DeviceState has the wrong size!");
|
static_assert(sizeof(DeviceState) == 0x30, "DeviceState has the wrong size!");
|
||||||
|
|
||||||
@@ -55,8 +55,8 @@ public:
|
|||||||
/* 0x14 */ u32 previous_pos;
|
/* 0x14 */ u32 previous_pos;
|
||||||
/* 0x18 */ SampleFormat format;
|
/* 0x18 */ SampleFormat format;
|
||||||
/* 0x1C */ std::array<s8, MaxChannels> inputs;
|
/* 0x1C */ std::array<s8, MaxChannels> inputs;
|
||||||
/* 0x22 */ bool in_use;
|
/* 0x22 */ u8 in_use;
|
||||||
/* 0x23 */ char unk23[0x5];
|
/* 0x23 */ u8 unk23[0x5];
|
||||||
};
|
};
|
||||||
static_assert(sizeof(CircularBufferInParameter) == 0x28,
|
static_assert(sizeof(CircularBufferInParameter) == 0x28,
|
||||||
"CircularBufferInParameter has the wrong size!");
|
"CircularBufferInParameter has the wrong size!");
|
||||||
@@ -65,16 +65,16 @@ public:
|
|||||||
/* 0x00 */ u32 last_pos2;
|
/* 0x00 */ u32 last_pos2;
|
||||||
/* 0x04 */ s32 current_pos;
|
/* 0x04 */ s32 current_pos;
|
||||||
/* 0x08 */ u32 last_pos;
|
/* 0x08 */ u32 last_pos;
|
||||||
/* 0x0C */ char unk0C[0x4];
|
/* 0x0C */ u8 unk0C[0x4];
|
||||||
/* 0x10 */ AddressInfo address_info;
|
/* 0x10 */ AddressInfo address_info;
|
||||||
};
|
};
|
||||||
static_assert(sizeof(CircularBufferState) == 0x30, "CircularBufferState has the wrong size!");
|
static_assert(sizeof(CircularBufferState) == 0x30, "CircularBufferState has the wrong size!");
|
||||||
|
|
||||||
struct InParameter {
|
struct InParameter {
|
||||||
/* 0x000 */ Type type;
|
/* 0x000 */ Type type;
|
||||||
/* 0x001 */ bool in_use;
|
/* 0x001 */ u8 in_use;
|
||||||
/* 0x004 */ u32 node_id;
|
/* 0x004 */ u32 node_id;
|
||||||
/* 0x008 */ char unk08[0x18];
|
/* 0x008 */ u8 unk08[0x18];
|
||||||
union {
|
union {
|
||||||
/* 0x020 */ DeviceInParameter device;
|
/* 0x020 */ DeviceInParameter device;
|
||||||
/* 0x020 */ CircularBufferInParameter circular_buffer;
|
/* 0x020 */ CircularBufferInParameter circular_buffer;
|
||||||
@@ -84,7 +84,7 @@ public:
|
|||||||
|
|
||||||
struct OutStatus {
|
struct OutStatus {
|
||||||
/* 0x00 */ u32 writeOffset;
|
/* 0x00 */ u32 writeOffset;
|
||||||
/* 0x04 */ char unk04[0x1C];
|
/* 0x04 */ u8 unk04[0x1C];
|
||||||
}; // size == 0x20
|
}; // size == 0x20
|
||||||
static_assert(sizeof(OutStatus) == 0x20, "SinkInfoBase::OutStatus has the wrong size!");
|
static_assert(sizeof(OutStatus) == 0x20, "SinkInfoBase::OutStatus has the wrong size!");
|
||||||
|
|
||||||
@@ -162,19 +162,18 @@ public:
|
|||||||
u8* GetParameter();
|
u8* GetParameter();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// Type of this sink
|
|
||||||
Type type{Type::Invalid};
|
|
||||||
/// Is this sink in use?
|
|
||||||
bool in_use{};
|
|
||||||
/// Is this sink's buffer unmapped? Circular only
|
|
||||||
bool buffer_unmapped{};
|
|
||||||
/// Node id for this sink
|
|
||||||
u32 node_id{};
|
|
||||||
/// State buffer for this sink
|
/// State buffer for this sink
|
||||||
std::array<u8, (std::max)(sizeof(DeviceState), sizeof(CircularBufferState))> state{};
|
std::array<u8, (std::max)(sizeof(DeviceState), sizeof(CircularBufferState))> state{};
|
||||||
/// Parameter buffer for this sink
|
/// Parameter buffer for this sink
|
||||||
std::array<u8, (std::max)(sizeof(DeviceInParameter), sizeof(CircularBufferInParameter))>
|
std::array<u8, (std::max)(sizeof(DeviceInParameter), sizeof(CircularBufferInParameter))> parameter{};
|
||||||
parameter{};
|
/// Type of this sink
|
||||||
|
Type type{Type::Invalid};
|
||||||
|
/// Node id for this sink
|
||||||
|
u32 node_id{};
|
||||||
|
/// Is this sink in use?
|
||||||
|
bool in_use : 1 = false;
|
||||||
|
/// Is this sink's buffer unmapped? Circular only
|
||||||
|
bool buffer_unmapped : 1 = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::Renderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|||||||
+1
-1
@@ -428,8 +428,8 @@ struct System::Impl {
|
|||||||
core_timing.SyncPause(false);
|
core_timing.SyncPause(false);
|
||||||
Network::CancelPendingSocketOperations();
|
Network::CancelPendingSocketOperations();
|
||||||
kernel.SuspendEmulation(true);
|
kernel.SuspendEmulation(true);
|
||||||
kernel.CloseServices();
|
|
||||||
kernel.ShutdownCores();
|
kernel.ShutdownCores();
|
||||||
|
kernel.CloseServices();
|
||||||
services.reset();
|
services.reset();
|
||||||
service_manager.reset();
|
service_manager.reset();
|
||||||
fs_controller.Reset();
|
fs_controller.Reset();
|
||||||
|
|||||||
@@ -72,11 +72,9 @@ void GlobalSchedulerContext::UnregisterDummyThreadForWakeup(KThread* thread) noe
|
|||||||
|
|
||||||
void GlobalSchedulerContext::WakeupWaitingDummyThreads(KernelCore& kernel) noexcept {
|
void GlobalSchedulerContext::WakeupWaitingDummyThreads(KernelCore& kernel) noexcept {
|
||||||
ASSERT(this->IsLocked());
|
ASSERT(this->IsLocked());
|
||||||
if (m_woken_dummy_threads.size() > 0) {
|
for (auto* thread : m_woken_dummy_threads)
|
||||||
for (auto* thread : m_woken_dummy_threads)
|
thread->DummyThreadEndWait(kernel);
|
||||||
thread->DummyThreadEndWait(kernel);
|
m_woken_dummy_threads.clear();
|
||||||
m_woken_dummy_threads.clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|||||||
@@ -1236,14 +1236,10 @@ namespace Kernel {
|
|||||||
KScopedSchedulerLock sl{kernel};
|
KScopedSchedulerLock sl{kernel};
|
||||||
|
|
||||||
// Determine if this is the first termination request.
|
// Determine if this is the first termination request.
|
||||||
const bool first_request = [&]() -> bool {
|
// Perform an atomic compare-and-swap from false to true.
|
||||||
// Perform an atomic compare-and-swap from false to true.
|
bool expected = false;
|
||||||
bool expected = false;
|
|
||||||
return m_termination_requested.compare_exchange_strong(expected, true);
|
|
||||||
}();
|
|
||||||
|
|
||||||
// If this is the first request, start termination procedure.
|
// If this is the first request, start termination procedure.
|
||||||
if (first_request) {
|
if (m_termination_requested.compare_exchange_strong(expected, true)) {
|
||||||
// If the thread is in initialized state, just change state to terminated.
|
// If the thread is in initialized state, just change state to terminated.
|
||||||
if (this->GetState() == ThreadState::Initialized) {
|
if (this->GetState() == ThreadState::Initialized) {
|
||||||
m_thread_state = ThreadState::Terminated;
|
m_thread_state = ThreadState::Terminated;
|
||||||
|
|||||||
@@ -967,12 +967,16 @@ Kernel::KHardwareTimer& KernelCore::HardwareTimer() {
|
|||||||
return *impl->hardware_timer;
|
return *impl->hardware_timer;
|
||||||
}
|
}
|
||||||
|
|
||||||
KAutoObjectWithListContainer& KernelCore::ObjectListContainer() {
|
KAutoObjectWithListContainer* KernelCore::ObjectListContainer() {
|
||||||
return *impl->global_object_list_container;
|
if (!impl->global_object_list_container)
|
||||||
|
return nullptr;
|
||||||
|
return std::addressof(*impl->global_object_list_container);
|
||||||
}
|
}
|
||||||
|
|
||||||
const KAutoObjectWithListContainer& KernelCore::ObjectListContainer() const {
|
const KAutoObjectWithListContainer* KernelCore::ObjectListContainer() const {
|
||||||
return *impl->global_object_list_container;
|
if (!impl->global_object_list_container)
|
||||||
|
return nullptr;
|
||||||
|
return std::addressof(*impl->global_object_list_container);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KernelCore::PrepareReschedule(std::size_t id) {
|
void KernelCore::PrepareReschedule(std::size_t id) {
|
||||||
@@ -1001,16 +1005,10 @@ void KernelCore::UnregisterInUseObject(KAutoObject* object) {
|
|||||||
|
|
||||||
void KernelCore::RunServer(std::unique_ptr<Service::ServerManager>&& server_manager) {
|
void KernelCore::RunServer(std::unique_ptr<Service::ServerManager>&& server_manager) {
|
||||||
auto* manager = server_manager.get();
|
auto* manager = server_manager.get();
|
||||||
|
if (!impl->is_shutting_down) {
|
||||||
{
|
|
||||||
std::scoped_lock lk{impl->server_lock};
|
std::scoped_lock lk{impl->server_lock};
|
||||||
if (impl->is_shutting_down) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl->server_managers.emplace_back(std::move(server_manager));
|
impl->server_managers.emplace_back(std::move(server_manager));
|
||||||
}
|
}
|
||||||
|
|
||||||
manager->LoopProcess();
|
manager->LoopProcess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -175,9 +175,8 @@ public:
|
|||||||
/// Stops execution of 'id' core, in order to reschedule a new thread.
|
/// Stops execution of 'id' core, in order to reschedule a new thread.
|
||||||
void PrepareReschedule(std::size_t id);
|
void PrepareReschedule(std::size_t id);
|
||||||
|
|
||||||
KAutoObjectWithListContainer& ObjectListContainer();
|
KAutoObjectWithListContainer* ObjectListContainer();
|
||||||
|
const KAutoObjectWithListContainer* ObjectListContainer() const;
|
||||||
const KAutoObjectWithListContainer& ObjectListContainer() const;
|
|
||||||
|
|
||||||
/// Registers all kernel objects with the global emulation state, this is purely for tracking
|
/// Registers all kernel objects with the global emulation state, this is purely for tracking
|
||||||
/// leaks after emulation has been shutdown.
|
/// leaks after emulation has been shutdown.
|
||||||
|
|||||||
@@ -151,7 +151,8 @@ public:
|
|||||||
const bool is_initialized = this->IsInitialized();
|
const bool is_initialized = this->IsInitialized();
|
||||||
uintptr_t arg = 0;
|
uintptr_t arg = 0;
|
||||||
if (is_initialized) {
|
if (is_initialized) {
|
||||||
kernel.ObjectListContainer().Unregister(this);
|
if (auto const olc = kernel.ObjectListContainer(); olc)
|
||||||
|
olc->Unregister(this);
|
||||||
arg = this->GetPostDestroyArgument();
|
arg = this->GetPostDestroyArgument();
|
||||||
this->Finalize(kernel);
|
this->Finalize(kernel);
|
||||||
}
|
}
|
||||||
@@ -175,7 +176,7 @@ public:
|
|||||||
public:
|
public:
|
||||||
static void InitializeSlabHeap(KernelCore& kernel, void* memory, size_t memory_size) {
|
static void InitializeSlabHeap(KernelCore& kernel, void* memory, size_t memory_size) {
|
||||||
kernel.SlabHeap<Derived>().Initialize(memory, memory_size);
|
kernel.SlabHeap<Derived>().Initialize(memory, memory_size);
|
||||||
kernel.ObjectListContainer().Initialize();
|
kernel.ObjectListContainer()->Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
static Derived* Create(KernelCore& kernel) {
|
static Derived* Create(KernelCore& kernel) {
|
||||||
@@ -186,7 +187,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void Register(KernelCore& kernel, Derived* obj) {
|
static void Register(KernelCore& kernel, Derived* obj) {
|
||||||
return kernel.ObjectListContainer().Register(obj);
|
return kernel.ObjectListContainer()->Register(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t GetObjectSize(KernelCore& kernel) {
|
static size_t GetObjectSize(KernelCore& kernel) {
|
||||||
|
|||||||
@@ -1,6 +1,15 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
// gcc14 bug
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/scope_exit.h"
|
#include "common/scope_exit.h"
|
||||||
#include "core/memory/dmnt_cheat_types.h"
|
#include "core/memory/dmnt_cheat_types.h"
|
||||||
@@ -223,7 +232,10 @@ DmntCheatVm::Callbacks::~Callbacks() = default;
|
|||||||
bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) {
|
bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) {
|
||||||
// If we've ever seen a decode failure, return false.
|
// If we've ever seen a decode failure, return false.
|
||||||
bool valid = decode_success;
|
bool valid = decode_success;
|
||||||
CheatVmOpcode opcode = {};
|
CheatVmOpcode opcode = {
|
||||||
|
.begin_conditional_block = false,
|
||||||
|
.opcode = {}
|
||||||
|
};
|
||||||
SCOPE_EXIT {
|
SCOPE_EXIT {
|
||||||
decode_success &= valid;
|
decode_success &= valid;
|
||||||
if (valid) {
|
if (valid) {
|
||||||
@@ -1266,3 +1278,8 @@ void DmntCheatVm::Execute(const CheatProcessMetadata& metadata) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Core::Memory
|
} // namespace Core::Memory
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
||||||
@@ -254,14 +254,16 @@ struct UnrecognizedInstruction {
|
|||||||
|
|
||||||
struct CheatVmOpcode {
|
struct CheatVmOpcode {
|
||||||
bool begin_conditional_block{};
|
bool begin_conditional_block{};
|
||||||
std::variant<StoreStaticOpcode, BeginConditionalOpcode, EndConditionalOpcode, ControlLoopOpcode,
|
std::variant<
|
||||||
LoadRegisterStaticOpcode, LoadRegisterMemoryOpcode, StoreStaticToAddressOpcode,
|
std::monostate,
|
||||||
PerformArithmeticStaticOpcode, BeginKeypressConditionalOpcode,
|
StoreStaticOpcode, BeginConditionalOpcode, EndConditionalOpcode, ControlLoopOpcode,
|
||||||
PerformArithmeticRegisterOpcode, StoreRegisterToAddressOpcode,
|
LoadRegisterStaticOpcode, LoadRegisterMemoryOpcode, StoreStaticToAddressOpcode,
|
||||||
BeginRegisterConditionalOpcode, SaveRestoreRegisterOpcode,
|
PerformArithmeticStaticOpcode, BeginKeypressConditionalOpcode,
|
||||||
SaveRestoreRegisterMaskOpcode, ReadWriteStaticRegisterOpcode, PauseProcessOpcode,
|
PerformArithmeticRegisterOpcode, StoreRegisterToAddressOpcode,
|
||||||
ResumeProcessOpcode, DebugLogOpcode, UnrecognizedInstruction>
|
BeginRegisterConditionalOpcode, SaveRestoreRegisterOpcode,
|
||||||
opcode{};
|
SaveRestoreRegisterMaskOpcode, ReadWriteStaticRegisterOpcode, PauseProcessOpcode,
|
||||||
|
ResumeProcessOpcode, DebugLogOpcode, UnrecognizedInstruction
|
||||||
|
> opcode{};
|
||||||
};
|
};
|
||||||
|
|
||||||
class DmntCheatVm {
|
class DmntCheatVm {
|
||||||
|
|||||||
@@ -170,13 +170,19 @@ template<>
|
|||||||
|
|
||||||
// check for marked bit, use as unmapped if marked
|
// check for marked bit, use as unmapped if marked
|
||||||
if (ctx.conf.page_table_marked_bit) {
|
if (ctx.conf.page_table_marked_bit) {
|
||||||
code.bt(page, *ctx.conf.page_table_marked_bit);
|
auto const marked_bit = *ctx.conf.page_table_marked_bit;
|
||||||
code.jc(abort, code.T_NEAR);
|
if (s64(s32(1 << marked_bit)) == s64(1 << marked_bit)) {
|
||||||
|
code.test(page, s32(1 << marked_bit));
|
||||||
|
code.jnz(abort, code.T_NEAR);
|
||||||
|
} else {
|
||||||
|
code.bt(page, marked_bit);
|
||||||
|
code.jc(abort, code.T_NEAR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// mask away attributes
|
// mask away attributes
|
||||||
if (ctx.conf.page_table_pointer_mask == 0) {
|
if (ctx.conf.page_table_pointer_mask == 0) {
|
||||||
code.test(page, page);
|
code.test(page, page);
|
||||||
} else if (std::in_range<s32>(ctx.conf.page_table_pointer_mask)) {
|
} else if (s64(s32(ctx.conf.page_table_pointer_mask)) == s64(ctx.conf.page_table_pointer_mask)) {
|
||||||
code.and_(page, ctx.conf.page_table_pointer_mask);
|
code.and_(page, ctx.conf.page_table_pointer_mask);
|
||||||
} else {
|
} else {
|
||||||
code.mov(tmp, ctx.conf.page_table_pointer_mask);
|
code.mov(tmp, ctx.conf.page_table_pointer_mask);
|
||||||
|
|||||||
@@ -79,8 +79,10 @@ void NpadAbstractButtonHandler::UpdateAllButtonLifo() {
|
|||||||
Core::HID::NpadIdType npad_id = properties_handler->GetNpadId();
|
Core::HID::NpadIdType npad_id = properties_handler->GetNpadId();
|
||||||
for (std::size_t i = 0; i < AruidIndexMax; i++) {
|
for (std::size_t i = 0; i < AruidIndexMax; i++) {
|
||||||
auto* data = applet_resource_holder->applet_resource->GetAruidDataByIndex(i);
|
auto* data = applet_resource_holder->applet_resource->GetAruidDataByIndex(i);
|
||||||
auto& npad_entry = data->shared_memory_format->npad.npad_entry[NpadIdTypeToIndex(npad_id)];
|
if (auto const shfmt = data->shared_memory_format; shfmt) {
|
||||||
UpdateButtonLifo(npad_entry, data->aruid);
|
auto& npad_entry = shfmt->npad.npad_entry[NpadIdTypeToIndex(npad_id)];
|
||||||
|
UpdateButtonLifo(npad_entry, data->aruid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,19 +90,19 @@ void NpadAbstractButtonHandler::UpdateCoreBatteryState() {
|
|||||||
Core::HID::NpadIdType npad_id = properties_handler->GetNpadId();
|
Core::HID::NpadIdType npad_id = properties_handler->GetNpadId();
|
||||||
for (std::size_t i = 0; i < AruidIndexMax; i++) {
|
for (std::size_t i = 0; i < AruidIndexMax; i++) {
|
||||||
auto* data = applet_resource_holder->applet_resource->GetAruidDataByIndex(i);
|
auto* data = applet_resource_holder->applet_resource->GetAruidDataByIndex(i);
|
||||||
auto& npad_entry = data->shared_memory_format->npad.npad_entry[NpadIdTypeToIndex(npad_id)];
|
if (auto const shfmt = data->shared_memory_format; shfmt) {
|
||||||
UpdateButtonLifo(npad_entry, data->aruid);
|
auto& npad_entry = shfmt->npad.npad_entry[NpadIdTypeToIndex(npad_id)];
|
||||||
|
UpdateButtonLifo(npad_entry, data->aruid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NpadAbstractButtonHandler::UpdateButtonState(u64 aruid) {
|
void NpadAbstractButtonHandler::UpdateButtonState(u64 aruid) {
|
||||||
Core::HID::NpadIdType npad_id = properties_handler->GetNpadId();
|
Core::HID::NpadIdType npad_id = properties_handler->GetNpadId();
|
||||||
auto* data = applet_resource_holder->applet_resource->GetAruidData(aruid);
|
if (auto data = applet_resource_holder->applet_resource->GetAruidData(aruid); data) {
|
||||||
if (data == nullptr) {
|
auto& npad_entry = data->shared_memory_format->npad.npad_entry[NpadIdTypeToIndex(npad_id)];
|
||||||
return;
|
UpdateButtonLifo(npad_entry, aruid);
|
||||||
}
|
}
|
||||||
auto& npad_entry = data->shared_memory_format->npad.npad_entry[NpadIdTypeToIndex(npad_id)];
|
|
||||||
UpdateButtonLifo(npad_entry, aruid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result NpadAbstractButtonHandler::SetHomeProtection(bool is_enabled, u64 aruid) {
|
Result NpadAbstractButtonHandler::SetHomeProtection(bool is_enabled, u64 aruid) {
|
||||||
|
|||||||
@@ -496,31 +496,30 @@ void SetupCapabilities(const Profile& profile, const Info& info, EmitContext& ct
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PatchPhiNodes(IR::Program& program, EmitContext& ctx) {
|
void PatchPhiNodes(IR::Program& program, EmitContext& ctx) {
|
||||||
// Flatten all leading PHIs from each block into a vector
|
// Flatten all leading PHIs from each block into a vector
|
||||||
std::vector<IR::Inst*> phi_instructions;
|
std::vector<IR::Inst*> phi_instructions;
|
||||||
for (IR::Block* block : program.blocks) {
|
for (IR::Block* block : program.blocks) {
|
||||||
for (auto it = block->begin(); it != block->end(); ++it) {
|
for (auto it = block->begin(); it != block->end(); ++it) {
|
||||||
if (it->GetOpcode() != IR::Opcode::Phi)
|
if (it->GetOpcode() != IR::Opcode::Phi)
|
||||||
break;
|
break;
|
||||||
phi_instructions.push_back(&*it);
|
phi_instructions.push_back(&*it);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (phi_instructions.empty()) {
|
|
||||||
return; // nothing to patch
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start "before" first PHI; advance on phi_arg == 0
|
|
||||||
size_t phi_index = static_cast<size_t>(-1);
|
|
||||||
|
|
||||||
ctx.PatchDeferredPhi([&](size_t phi_arg, Id parent) -> std::pair<Id, Id> {
|
|
||||||
if (phi_arg == 0) {
|
|
||||||
++phi_index;
|
|
||||||
}
|
|
||||||
IR::Inst* phi = phi_instructions[phi_index];
|
|
||||||
return { ctx.Def(phi->Arg(phi_arg)), parent };
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (phi_instructions.empty()) {
|
||||||
|
return; // nothing to patch
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start "before" first PHI; advance on phi_arg == 0
|
||||||
|
size_t phi_index = size_t(-1);
|
||||||
|
ctx.PatchDeferredPhi([&ctx, &phi_index, phi_insts = std::move(phi_instructions)](size_t phi_arg, Id parent) -> std::pair<Id, Id> {
|
||||||
|
if (phi_arg == 0) {
|
||||||
|
++phi_index;
|
||||||
|
}
|
||||||
|
IR::Inst* phi = phi_insts[phi_index];
|
||||||
|
return { ctx.Def(phi->Arg(phi_arg)), parent };
|
||||||
|
});
|
||||||
|
}
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
std::vector<u32> EmitSPIRV(const Profile& profile, const RuntimeInfo& runtime_info, IR::Program& program, Bindings& bindings) {
|
std::vector<u32> EmitSPIRV(const Profile& profile, const RuntimeInfo& runtime_info, IR::Program& program, Bindings& bindings) {
|
||||||
|
|||||||
Reference in New Issue
Block a user