Compare commits

..

2 Commits

Author SHA1 Message Date
xbzk a277b62fe4 [fs] revert #4319 savedata_factory changes (#4462)
- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.

-------------------

This one reverts part of the PR 4319 which was aimed to allow child titles to inherit bundle settings.
The fix seems good so far, but by applying it to save folders caused a trap:
Now child's save folders move to bundle folder, hence saves will vanish, and the android/qt save tools are still pointing to old folders.
Since the save part was only a compliance fix, instead of fiddle in master i'd rather revert this part now, then only touch this again if any bug show up.
No worries. I'll be right here waiting.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4462
Reviewed-by: lizzie <lizzie@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-09-20 04:40:14 +02:00
lizzie 908b1e9a37 [dynarmic] fix bad arm codegen on relocations (#4458)
In an earlier version I had these as constants which were referred to via `db`, I haphazardly left the LDR and didn't notice.
Even still relocations apply to only 1 ins at a time.

Fixes regressions on #4158

Signed-off-by: lizzie <lizzie@eden-emu.dev>

- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.

-------------------

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4458
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-09-20 00:29:28 +02:00
8 changed files with 188 additions and 79 deletions
+8 -14
View File
@@ -9,7 +9,6 @@
#include "common/logging.h" #include "common/logging.h"
#include "common/uuid.h" #include "common/uuid.h"
#include "core/core.h" #include "core/core.h"
#include "core/file_sys/registered_cache.h"
#include "core/file_sys/savedata_factory.h" #include "core/file_sys/savedata_factory.h"
#include "core/file_sys/vfs/vfs.h" #include "core/file_sys/vfs/vfs.h"
@@ -62,24 +61,17 @@ SaveDataFactory::SaveDataFactory(Core::System& system_, ProgramId program_id_,
SaveDataFactory::~SaveDataFactory() = default; SaveDataFactory::~SaveDataFactory() = default;
std::string SaveDataFactory::GetSaveDataPath(SaveDataSpaceId space, SaveDataType type, u64 title_id, u128 user_id, u64 save_id) const {
if (type == SaveDataType::Account || type == SaveDataType::Device) {
const auto requested_id = title_id != 0 ? title_id : program_id;
const auto parent_id = system.GetContentProvider().GetParentApplicationId(requested_id);
title_id = parent_id.value_or(requested_id);
}
return GetFullPath(program_id, dir, space, type, title_id, user_id, save_id);
}
VirtualDir SaveDataFactory::Create(SaveDataSpaceId space, const SaveDataAttribute& meta) const { VirtualDir SaveDataFactory::Create(SaveDataSpaceId space, const SaveDataAttribute& meta) const {
const auto save_directory = GetSaveDataPath(space, meta.type, meta.program_id, meta.user_id, meta.system_save_data_id); const auto save_directory = GetFullPath(program_id, dir, space, meta.type, meta.program_id,
meta.user_id, meta.system_save_data_id);
return dir->CreateDirectoryRelative(save_directory); return dir->CreateDirectoryRelative(save_directory);
} }
VirtualDir SaveDataFactory::Open(SaveDataSpaceId space, const SaveDataAttribute& meta) const { VirtualDir SaveDataFactory::Open(SaveDataSpaceId space, const SaveDataAttribute& meta) const {
const auto save_directory = GetSaveDataPath(space, meta.type, meta.program_id, meta.user_id, meta.system_save_data_id); const auto save_directory = GetFullPath(program_id, dir, space, meta.type, meta.program_id,
meta.user_id, meta.system_save_data_id);
auto out = dir->GetDirectoryRelative(save_directory); auto out = dir->GetDirectoryRelative(save_directory);
@@ -162,7 +154,8 @@ std::string SaveDataFactory::GetUserGameSaveDataRoot(u128 user_id, bool future)
SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id, SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id,
u128 user_id) const { u128 user_id) const {
const auto path = GetSaveDataPath(SaveDataSpaceId::User, type, title_id, user_id, 0); const auto path =
GetFullPath(program_id, dir, SaveDataSpaceId::User, type, title_id, user_id, 0);
const auto relative_dir = GetOrCreateDirectoryRelative(dir, path); const auto relative_dir = GetOrCreateDirectoryRelative(dir, path);
const auto size_file = relative_dir->GetFile(GetSaveDataSizeFileName()); const auto size_file = relative_dir->GetFile(GetSaveDataSizeFileName());
@@ -180,7 +173,8 @@ SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id,
void SaveDataFactory::WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id, void SaveDataFactory::WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id,
SaveDataSize new_value) const { SaveDataSize new_value) const {
const auto path = GetSaveDataPath(SaveDataSpaceId::User, type, title_id, user_id, 0); const auto path =
GetFullPath(program_id, dir, SaveDataSpaceId::User, type, title_id, user_id, 0);
const auto relative_dir = GetOrCreateDirectoryRelative(dir, path); const auto relative_dir = GetOrCreateDirectoryRelative(dir, path);
const auto size_file = relative_dir->CreateFile(GetSaveDataSizeFileName()); const auto size_file = relative_dir->CreateFile(GetSaveDataSizeFileName());
-1
View File
@@ -50,7 +50,6 @@ public:
void SetAutoCreate(bool state); void SetAutoCreate(bool state);
private: private:
std::string GetSaveDataPath(SaveDataSpaceId space, SaveDataType type, u64 title_id, u128 user_id, u64 save_id) const;
Core::System& system; Core::System& system;
ProgramId program_id; ProgramId program_id;
VirtualDir dir; VirtualDir dir;
@@ -24,29 +24,65 @@
namespace Dynarmic::Backend::Arm64 { namespace Dynarmic::Backend::Arm64 {
template<auto mfp, typename T> template<auto mfp, typename T>
static void* EmitCallTrampoline(oaknut::CodeGenerator& code, T* this_) { static void* EmitCallReadTrampoline(oaknut::CodeGenerator& code, T* this_, size_t bitsize) {
using namespace oaknut::util; using namespace oaknut::util;
const auto info = Devirtualize<mfp>(this_); const auto info = Devirtualize<mfp>(this_);
oaknut::Label l_addr, l_this; oaknut::Label l_addr, l_this;
void* target = code.xptr<void*>(); void* target = code.xptr<void*>();
// params = { this, vaddr, bitsize }
code.LDR(X0, l_this); code.LDR(X0, l_this);
// X1 = vaddr
code.MOV(X2, bitsize);
code.LDR(Xscratch0, l_addr); code.LDR(Xscratch0, l_addr);
code.BR(Xscratch0); code.BR(Xscratch0);
code.align(8); code.align(8);
code.l(l_this); code.l(l_this);
code.dx(info.this_ptr); code.dx(info.this_ptr);
code.l(l_addr); code.l(l_addr);
code.dx(info.fn_ptr); code.dx(info.fn_ptr);
return target; return target;
} }
template<auto mfp, typename T> template<auto mfp, typename T>
static void* EmitWrappedReadCallTrampoline(oaknut::CodeGenerator& code, T* this_) { static void* EmitCallWriteTrampoline(oaknut::CodeGenerator& code, T* this_, size_t bitsize) {
using namespace oaknut::util;
const auto info = Devirtualize<mfp>(this_);
oaknut::Label l_addr, l_this;
void* target = code.xptr<void*>();
// params = { this, vaddr, value, bitsize }
code.LDR(X0, l_this);
// X1 = vaddr
// X2 = value
code.MOV(X3, bitsize);
code.LDR(Xscratch0, l_addr);
code.BR(Xscratch0);
code.align(8);
code.l(l_this);
code.dx(info.this_ptr);
code.l(l_addr);
code.dx(info.fn_ptr);
return target;
}
template<auto mfp, typename T>
static void* EmitCallTrampoline(oaknut::CodeGenerator& code, T* this_) {
using namespace oaknut::util;
const auto info = Devirtualize<mfp>(this_);
oaknut::Label l_addr, l_this;
void* target = code.xptr<void*>();
code.LDR(X0, l_this);
code.LDR(Xscratch0, l_addr);
code.BR(Xscratch0);
code.align(8);
code.l(l_this);
code.dx(info.this_ptr);
code.l(l_addr);
code.dx(info.fn_ptr);
return target;
}
template<auto mfp, typename T>
static void* EmitWrappedReadCallTrampoline(oaknut::CodeGenerator& code, T* this_, size_t bitsize) {
using namespace oaknut::util; using namespace oaknut::util;
const auto info = Devirtualize<mfp>(this_); const auto info = Devirtualize<mfp>(this_);
@@ -59,6 +95,7 @@ static void* EmitWrappedReadCallTrampoline(oaknut::CodeGenerator& code, T* this_
ABI_PushRegisters(code, save_regs, 0); ABI_PushRegisters(code, save_regs, 0);
code.LDR(X0, l_this); code.LDR(X0, l_this);
code.MOV(X1, Xscratch0); code.MOV(X1, Xscratch0);
code.MOV(X2, bitsize);
code.LDR(Xscratch0, l_addr); code.LDR(Xscratch0, l_addr);
code.BLR(Xscratch0); code.BLR(Xscratch0);
code.MOV(Xscratch0, X0); code.MOV(Xscratch0, X0);
@@ -101,7 +138,7 @@ static void* EmitExclusiveReadCallTrampoline(oaknut::CodeGenerator& code, const
} }
template<auto mfp, typename T> template<auto mfp, typename T>
static void* EmitWrappedWriteCallTrampoline(oaknut::CodeGenerator& code, T* this_) { static void* EmitWrappedWriteCallTrampoline(oaknut::CodeGenerator& code, T* this_, size_t bitsize) {
using namespace oaknut::util; using namespace oaknut::util;
const auto info = Devirtualize<mfp>(this_); const auto info = Devirtualize<mfp>(this_);
@@ -115,6 +152,7 @@ static void* EmitWrappedWriteCallTrampoline(oaknut::CodeGenerator& code, T* this
code.LDR(X0, l_this); code.LDR(X0, l_this);
code.MOV(X1, Xscratch0); code.MOV(X1, Xscratch0);
code.MOV(X2, Xscratch1); code.MOV(X2, Xscratch1);
code.MOV(X3, bitsize);
code.LDR(Xscratch0, l_addr); code.LDR(Xscratch0, l_addr);
code.BLR(Xscratch0); code.BLR(Xscratch0);
ABI_PopRegisters(code, save_regs, 0); ABI_PopRegisters(code, save_regs, 0);
@@ -176,14 +214,27 @@ void A32AddressSpace::EmitPrelude() {
UnprotectCodeMemory(); UnprotectCodeMemory();
prelude_info.read_memory = EmitCallTrampoline<&A32::UserCallbacks::MemoryRead>(code, conf.callbacks);
prelude_info.wrapped_read_memory = EmitWrappedReadCallTrampoline<&A32::UserCallbacks::MemoryRead>(code, conf.callbacks); prelude_info.read_memory_8 = EmitCallReadTrampoline<&A32::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u8));
prelude_info.read_memory_16 = EmitCallReadTrampoline<&A32::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u16));
prelude_info.read_memory_32 = EmitCallReadTrampoline<&A32::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u32));
prelude_info.read_memory_64 = EmitCallReadTrampoline<&A32::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u64));
prelude_info.wrapped_read_memory_8 = EmitWrappedReadCallTrampoline<&A32::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u8));
prelude_info.wrapped_read_memory_16 = EmitWrappedReadCallTrampoline<&A32::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u16));
prelude_info.wrapped_read_memory_32 = EmitWrappedReadCallTrampoline<&A32::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u32));
prelude_info.wrapped_read_memory_64 = EmitWrappedReadCallTrampoline<&A32::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u64));
prelude_info.exclusive_read_memory_8 = EmitExclusiveReadCallTrampoline<&A32::UserCallbacks::MemoryRead, u8>(code, conf); prelude_info.exclusive_read_memory_8 = EmitExclusiveReadCallTrampoline<&A32::UserCallbacks::MemoryRead, u8>(code, conf);
prelude_info.exclusive_read_memory_16 = EmitExclusiveReadCallTrampoline<&A32::UserCallbacks::MemoryRead, u16>(code, conf); prelude_info.exclusive_read_memory_16 = EmitExclusiveReadCallTrampoline<&A32::UserCallbacks::MemoryRead, u16>(code, conf);
prelude_info.exclusive_read_memory_32 = EmitExclusiveReadCallTrampoline<&A32::UserCallbacks::MemoryRead, u32>(code, conf); prelude_info.exclusive_read_memory_32 = EmitExclusiveReadCallTrampoline<&A32::UserCallbacks::MemoryRead, u32>(code, conf);
prelude_info.exclusive_read_memory_64 = EmitExclusiveReadCallTrampoline<&A32::UserCallbacks::MemoryRead, u64>(code, conf); prelude_info.exclusive_read_memory_64 = EmitExclusiveReadCallTrampoline<&A32::UserCallbacks::MemoryRead, u64>(code, conf);
prelude_info.write_memory = EmitCallTrampoline<&A32::UserCallbacks::MemoryWrite>(code, conf.callbacks); prelude_info.write_memory_8 = EmitCallWriteTrampoline<&A32::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u8));
prelude_info.wrapped_write_memory = EmitWrappedWriteCallTrampoline<&A32::UserCallbacks::MemoryWrite>(code, conf.callbacks); prelude_info.write_memory_16 = EmitCallWriteTrampoline<&A32::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u16));
prelude_info.write_memory_32 = EmitCallWriteTrampoline<&A32::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u32));
prelude_info.write_memory_64 = EmitCallWriteTrampoline<&A32::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u64));
prelude_info.wrapped_write_memory_8 = EmitWrappedWriteCallTrampoline<&A32::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u8));
prelude_info.wrapped_write_memory_16 = EmitWrappedWriteCallTrampoline<&A32::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u16));
prelude_info.wrapped_write_memory_32 = EmitWrappedWriteCallTrampoline<&A32::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u32));
prelude_info.wrapped_write_memory_64 = EmitWrappedWriteCallTrampoline<&A32::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u64));
prelude_info.exclusive_write_memory_8 = EmitExclusiveWriteCallTrampoline<&A32::UserCallbacks::MemoryWriteExclusive8, u8>(code, conf); prelude_info.exclusive_write_memory_8 = EmitExclusiveWriteCallTrampoline<&A32::UserCallbacks::MemoryWriteExclusive8, u8>(code, conf);
prelude_info.exclusive_write_memory_16 = EmitExclusiveWriteCallTrampoline<&A32::UserCallbacks::MemoryWriteExclusive16, u16>(code, conf); prelude_info.exclusive_write_memory_16 = EmitExclusiveWriteCallTrampoline<&A32::UserCallbacks::MemoryWriteExclusive16, u16>(code, conf);
prelude_info.exclusive_write_memory_32 = EmitExclusiveWriteCallTrampoline<&A32::UserCallbacks::MemoryWriteExclusive32, u32>(code, conf); prelude_info.exclusive_write_memory_32 = EmitExclusiveWriteCallTrampoline<&A32::UserCallbacks::MemoryWriteExclusive32, u32>(code, conf);
@@ -23,29 +23,65 @@
namespace Dynarmic::Backend::Arm64 { namespace Dynarmic::Backend::Arm64 {
template<auto mfp, typename T> template<auto mfp, typename T>
static void* EmitCallTrampoline(oaknut::CodeGenerator& code, T* this_) { static void* EmitCallReadTrampoline(oaknut::CodeGenerator& code, T* this_, size_t bitsize) {
using namespace oaknut::util; using namespace oaknut::util;
const auto info = Devirtualize<mfp>(this_); const auto info = Devirtualize<mfp>(this_);
oaknut::Label l_addr, l_this; oaknut::Label l_addr, l_this;
void* target = code.xptr<void*>(); void* target = code.xptr<void*>();
// params = { this, vaddr, bitsize }
code.LDR(X0, l_this); code.LDR(X0, l_this);
// X1 = vaddr
code.MOV(X2, bitsize);
code.LDR(Xscratch0, l_addr); code.LDR(Xscratch0, l_addr);
code.BR(Xscratch0); code.BR(Xscratch0);
code.align(8); code.align(8);
code.l(l_this); code.l(l_this);
code.dx(info.this_ptr); code.dx(info.this_ptr);
code.l(l_addr); code.l(l_addr);
code.dx(info.fn_ptr); code.dx(info.fn_ptr);
return target; return target;
} }
template<auto mfp, typename T> template<auto mfp, typename T>
static void* EmitWrappedReadCallTrampoline(oaknut::CodeGenerator& code, T* this_) { static void* EmitCallWriteTrampoline(oaknut::CodeGenerator& code, T* this_, size_t bitsize) {
using namespace oaknut::util;
const auto info = Devirtualize<mfp>(this_);
oaknut::Label l_addr, l_this;
void* target = code.xptr<void*>();
// params = { this, vaddr, value, bitsize }
code.LDR(X0, l_this);
// X1 = vaddr
// X2 = value
code.MOV(X3, bitsize);
code.LDR(Xscratch0, l_addr);
code.BR(Xscratch0);
code.align(8);
code.l(l_this);
code.dx(info.this_ptr);
code.l(l_addr);
code.dx(info.fn_ptr);
return target;
}
template<auto mfp, typename T>
static void* EmitCallTrampoline(oaknut::CodeGenerator& code, T* this_) {
using namespace oaknut::util;
const auto info = Devirtualize<mfp>(this_);
oaknut::Label l_addr, l_this;
void* target = code.xptr<void*>();
code.LDR(X0, l_this);
code.LDR(Xscratch0, l_addr);
code.BR(Xscratch0);
code.align(8);
code.l(l_this);
code.dx(info.this_ptr);
code.l(l_addr);
code.dx(info.fn_ptr);
return target;
}
template<auto mfp, typename T>
static void* EmitWrappedReadCallTrampoline(oaknut::CodeGenerator& code, T* this_, size_t bitsize) {
using namespace oaknut::util; using namespace oaknut::util;
const auto info = Devirtualize<mfp>(this_); const auto info = Devirtualize<mfp>(this_);
@@ -58,6 +94,7 @@ static void* EmitWrappedReadCallTrampoline(oaknut::CodeGenerator& code, T* this_
ABI_PushRegisters(code, save_regs, 0); ABI_PushRegisters(code, save_regs, 0);
code.LDR(X0, l_this); code.LDR(X0, l_this);
code.MOV(X1, Xscratch0); code.MOV(X1, Xscratch0);
code.MOV(X2, bitsize);
code.LDR(Xscratch0, l_addr); code.LDR(Xscratch0, l_addr);
code.BLR(Xscratch0); code.BLR(Xscratch0);
code.MOV(Xscratch0, X0); code.MOV(Xscratch0, X0);
@@ -100,7 +137,7 @@ static void* EmitExclusiveReadCallTrampoline(oaknut::CodeGenerator& code, const
} }
template<auto mfp, typename T> template<auto mfp, typename T>
static void* EmitWrappedWriteCallTrampoline(oaknut::CodeGenerator& code, T* this_) { static void* EmitWrappedWriteCallTrampoline(oaknut::CodeGenerator& code, T* this_, size_t bitsize) {
using namespace oaknut::util; using namespace oaknut::util;
const auto info = Devirtualize<mfp>(this_); const auto info = Devirtualize<mfp>(this_);
@@ -114,6 +151,7 @@ static void* EmitWrappedWriteCallTrampoline(oaknut::CodeGenerator& code, T* this
code.LDR(X0, l_this); code.LDR(X0, l_this);
code.MOV(X1, Xscratch0); code.MOV(X1, Xscratch0);
code.MOV(X2, Xscratch1); code.MOV(X2, Xscratch1);
code.MOV(X3, bitsize);
code.LDR(Xscratch0, l_addr); code.LDR(Xscratch0, l_addr);
code.BLR(Xscratch0); code.BLR(Xscratch0);
ABI_PopRegisters(code, save_regs, 0); ABI_PopRegisters(code, save_regs, 0);
@@ -342,18 +380,30 @@ void A64AddressSpace::EmitPrelude() {
UnprotectCodeMemory(); UnprotectCodeMemory();
prelude_info.read_memory = EmitCallTrampoline<&A64::UserCallbacks::MemoryRead>(code, conf.callbacks); prelude_info.read_memory_8 = EmitCallReadTrampoline<&A64::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u8));
prelude_info.read_memory_16 = EmitCallReadTrampoline<&A64::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u16));
prelude_info.read_memory_32 = EmitCallReadTrampoline<&A64::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u32));
prelude_info.read_memory_64 = EmitCallReadTrampoline<&A64::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u64));
prelude_info.read_memory_128 = EmitRead128CallTrampoline(code, conf.callbacks); prelude_info.read_memory_128 = EmitRead128CallTrampoline(code, conf.callbacks);
prelude_info.wrapped_read_memory = EmitWrappedReadCallTrampoline<&A64::UserCallbacks::MemoryRead>(code, conf.callbacks); prelude_info.wrapped_read_memory_8 = EmitWrappedReadCallTrampoline<&A64::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u8));
prelude_info.wrapped_read_memory_16 = EmitWrappedReadCallTrampoline<&A64::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u16));
prelude_info.wrapped_read_memory_32 = EmitWrappedReadCallTrampoline<&A64::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u32));
prelude_info.wrapped_read_memory_64 = EmitWrappedReadCallTrampoline<&A64::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u64));
prelude_info.wrapped_read_memory_128 = EmitWrappedRead128CallTrampoline(code, conf.callbacks); prelude_info.wrapped_read_memory_128 = EmitWrappedRead128CallTrampoline(code, conf.callbacks);
prelude_info.exclusive_read_memory_8 = EmitExclusiveReadCallTrampoline<&A64::UserCallbacks::MemoryRead, u8>(code, conf); prelude_info.exclusive_read_memory_8 = EmitExclusiveReadCallTrampoline<&A64::UserCallbacks::MemoryRead, u8>(code, conf);
prelude_info.exclusive_read_memory_16 = EmitExclusiveReadCallTrampoline<&A64::UserCallbacks::MemoryRead, u16>(code, conf); prelude_info.exclusive_read_memory_16 = EmitExclusiveReadCallTrampoline<&A64::UserCallbacks::MemoryRead, u16>(code, conf);
prelude_info.exclusive_read_memory_32 = EmitExclusiveReadCallTrampoline<&A64::UserCallbacks::MemoryRead, u32>(code, conf); prelude_info.exclusive_read_memory_32 = EmitExclusiveReadCallTrampoline<&A64::UserCallbacks::MemoryRead, u32>(code, conf);
prelude_info.exclusive_read_memory_64 = EmitExclusiveReadCallTrampoline<&A64::UserCallbacks::MemoryRead, u64>(code, conf); prelude_info.exclusive_read_memory_64 = EmitExclusiveReadCallTrampoline<&A64::UserCallbacks::MemoryRead, u64>(code, conf);
prelude_info.exclusive_read_memory_128 = EmitExclusiveRead128CallTrampoline(code, conf); prelude_info.exclusive_read_memory_128 = EmitExclusiveRead128CallTrampoline(code, conf);
prelude_info.write_memory = EmitCallTrampoline<&A64::UserCallbacks::MemoryWrite>(code, conf.callbacks); prelude_info.write_memory_8 = EmitCallWriteTrampoline<&A64::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u8));
prelude_info.write_memory_16 = EmitCallWriteTrampoline<&A64::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u16));
prelude_info.write_memory_32 = EmitCallWriteTrampoline<&A64::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u32));
prelude_info.write_memory_64 = EmitCallWriteTrampoline<&A64::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u64));
prelude_info.write_memory_128 = EmitWrite128CallTrampoline(code, conf.callbacks); prelude_info.write_memory_128 = EmitWrite128CallTrampoline(code, conf.callbacks);
prelude_info.wrapped_write_memory = EmitWrappedWriteCallTrampoline<&A64::UserCallbacks::MemoryWrite>(code, conf.callbacks); prelude_info.wrapped_write_memory_8 = EmitWrappedWriteCallTrampoline<&A64::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u8));
prelude_info.wrapped_write_memory_16 = EmitWrappedWriteCallTrampoline<&A64::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u16));
prelude_info.wrapped_write_memory_32 = EmitWrappedWriteCallTrampoline<&A64::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u32));
prelude_info.wrapped_write_memory_64 = EmitWrappedWriteCallTrampoline<&A64::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u64));
prelude_info.wrapped_write_memory_128 = EmitWrappedWrite128CallTrampoline(code, conf.callbacks); prelude_info.wrapped_write_memory_128 = EmitWrappedWrite128CallTrampoline(code, conf.callbacks);
prelude_info.exclusive_write_memory_8 = EmitExclusiveWriteCallTrampoline<&A64::UserCallbacks::MemoryWriteExclusive8, u8>(code, conf); prelude_info.exclusive_write_memory_8 = EmitExclusiveWriteCallTrampoline<&A64::UserCallbacks::MemoryWriteExclusive8, u8>(code, conf);
prelude_info.exclusive_write_memory_16 = EmitExclusiveWriteCallTrampoline<&A64::UserCallbacks::MemoryWriteExclusive16, u16>(code, conf); prelude_info.exclusive_write_memory_16 = EmitExclusiveWriteCallTrampoline<&A64::UserCallbacks::MemoryWriteExclusive16, u16>(code, conf);
@@ -147,44 +147,37 @@ void AddressSpace::Link(EmittedBlockInfo& block_info) {
break; break;
// { this, vaddr, size } // { this, vaddr, size }
case LinkTarget::ReadMemory8: case LinkTarget::ReadMemory8:
c.LDR(X2, 1); c.BL(prelude_info.read_memory_8);
c.BL(prelude_info.read_memory);
break; break;
case LinkTarget::ReadMemory16: case LinkTarget::ReadMemory16:
c.LDR(X2, 2); c.BL(prelude_info.read_memory_16);
c.BL(prelude_info.read_memory);
break; break;
case LinkTarget::ReadMemory32: case LinkTarget::ReadMemory32:
c.LDR(X2, 4); c.BL(prelude_info.read_memory_32);
c.BL(prelude_info.read_memory);
break; break;
case LinkTarget::ReadMemory64: case LinkTarget::ReadMemory64:
c.LDR(X2, 8); c.BL(prelude_info.read_memory_64);
c.BL(prelude_info.read_memory);
break; break;
case LinkTarget::ReadMemory128: case LinkTarget::ReadMemory128:
c.BL(prelude_info.read_memory_128); c.BL(prelude_info.read_memory_128);
break; break;
// { this, vaddr, size } // { this, vaddr, size }
case LinkTarget::WrappedReadMemory8: case LinkTarget::WrappedReadMemory8:
c.LDR(X2, 1); c.BL(prelude_info.wrapped_read_memory_8);
c.BL(prelude_info.wrapped_read_memory);
break; break;
case LinkTarget::WrappedReadMemory16: case LinkTarget::WrappedReadMemory16:
c.LDR(X2, 2); c.BL(prelude_info.wrapped_read_memory_16);
c.BL(prelude_info.wrapped_read_memory);
break; break;
case LinkTarget::WrappedReadMemory32: case LinkTarget::WrappedReadMemory32:
c.LDR(X2, 4); c.BL(prelude_info.wrapped_read_memory_32);
c.BL(prelude_info.wrapped_read_memory);
break; break;
case LinkTarget::WrappedReadMemory64: case LinkTarget::WrappedReadMemory64:
c.LDR(X2, 8); c.BL(prelude_info.wrapped_read_memory_64);
c.BL(prelude_info.wrapped_read_memory);
break; break;
case LinkTarget::WrappedReadMemory128: case LinkTarget::WrappedReadMemory128:
c.BL(prelude_info.wrapped_read_memory_128); c.BL(prelude_info.wrapped_read_memory_128);
break; break;
//
case LinkTarget::ExclusiveReadMemory8: case LinkTarget::ExclusiveReadMemory8:
c.BL(prelude_info.exclusive_read_memory_8); c.BL(prelude_info.exclusive_read_memory_8);
break; break;
@@ -202,43 +195,37 @@ void AddressSpace::Link(EmittedBlockInfo& block_info) {
break; break;
// { this, vaddr, value, size } // { this, vaddr, value, size }
case LinkTarget::WriteMemory8: case LinkTarget::WriteMemory8:
c.LDR(X3, 1); c.BL(prelude_info.write_memory_8);
c.BL(prelude_info.write_memory);
break; break;
case LinkTarget::WriteMemory16: case LinkTarget::WriteMemory16:
c.LDR(X3, 2); c.BL(prelude_info.write_memory_16);
c.BL(prelude_info.write_memory);
break; break;
case LinkTarget::WriteMemory32: case LinkTarget::WriteMemory32:
c.LDR(X3, 4); c.BL(prelude_info.write_memory_32);
c.BL(prelude_info.write_memory);
break; break;
case LinkTarget::WriteMemory64: case LinkTarget::WriteMemory64:
c.LDR(X3, 8); c.BL(prelude_info.write_memory_64);
c.BL(prelude_info.write_memory);
break; break;
case LinkTarget::WriteMemory128: case LinkTarget::WriteMemory128:
c.BL(prelude_info.write_memory_128); c.BL(prelude_info.write_memory_128);
break; break;
//
case LinkTarget::WrappedWriteMemory8: case LinkTarget::WrappedWriteMemory8:
c.LDR(X3, 1); c.BL(prelude_info.wrapped_write_memory_8);
c.BL(prelude_info.wrapped_write_memory);
break; break;
case LinkTarget::WrappedWriteMemory16: case LinkTarget::WrappedWriteMemory16:
c.LDR(X3, 2); c.BL(prelude_info.wrapped_write_memory_16);
c.BL(prelude_info.wrapped_write_memory);
break; break;
case LinkTarget::WrappedWriteMemory32: case LinkTarget::WrappedWriteMemory32:
c.LDR(X3, 4); c.BL(prelude_info.wrapped_write_memory_32);
c.BL(prelude_info.wrapped_write_memory);
break; break;
case LinkTarget::WrappedWriteMemory64: case LinkTarget::WrappedWriteMemory64:
c.LDR(X3, 8); c.BL(prelude_info.wrapped_write_memory_64);
c.BL(prelude_info.wrapped_write_memory);
break; break;
case LinkTarget::WrappedWriteMemory128: case LinkTarget::WrappedWriteMemory128:
c.BL(prelude_info.wrapped_write_memory_128); c.BL(prelude_info.wrapped_write_memory_128);
break; break;
//
case LinkTarget::ExclusiveWriteMemory8: case LinkTarget::ExclusiveWriteMemory8:
c.BL(prelude_info.exclusive_write_memory_8); c.BL(prelude_info.exclusive_write_memory_8);
break; break;
@@ -93,18 +93,30 @@ protected:
void* return_to_dispatcher; void* return_to_dispatcher;
void* return_from_run_code; void* return_from_run_code;
void* read_memory; void* read_memory_8;
void* read_memory_16;
void* read_memory_32;
void* read_memory_64;
void* read_memory_128; void* read_memory_128;
void* wrapped_read_memory; void* wrapped_read_memory_8;
void* wrapped_read_memory_16;
void* wrapped_read_memory_32;
void* wrapped_read_memory_64;
void* wrapped_read_memory_128; void* wrapped_read_memory_128;
void* exclusive_read_memory_8; void* exclusive_read_memory_8;
void* exclusive_read_memory_16; void* exclusive_read_memory_16;
void* exclusive_read_memory_32; void* exclusive_read_memory_32;
void* exclusive_read_memory_64; void* exclusive_read_memory_64;
void* exclusive_read_memory_128; void* exclusive_read_memory_128;
void* write_memory; void* write_memory_8;
void* write_memory_16;
void* write_memory_32;
void* write_memory_64;
void* write_memory_128; void* write_memory_128;
void* wrapped_write_memory; void* wrapped_write_memory_8;
void* wrapped_write_memory_16;
void* wrapped_write_memory_32;
void* wrapped_write_memory_64;
void* wrapped_write_memory_128; void* wrapped_write_memory_128;
void* exclusive_write_memory_8; void* exclusive_write_memory_8;
void* exclusive_write_memory_16; void* exclusive_write_memory_16;
+17 -3
View File
@@ -761,6 +761,9 @@ void EmulatedController::StartMotionCalibration() {
} }
void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback, std::size_t index, Common::UUID uuid) { void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback, std::size_t index, Common::UUID uuid) {
const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
const auto& player = Settings::values.players.GetValue()[player_index];
if (index >= controller.button_values.size()) { if (index >= controller.button_values.size()) {
return; return;
} }
@@ -913,10 +916,21 @@ void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback
break; break;
} }
const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type); if (!is_connected) {
const auto& player = Settings::values.players.GetValue()[player_index]; if (npad_type == NpadStyleIndex::Handheld) {
if (player.connected) { if (npad_id_type == NpadIdType::Handheld) {
Connect(); Connect();
controller_connected[player_index] = true;
}
} else if (npad_type != NpadStyleIndex::Handheld) {
if (npad_id_type == NpadIdType::Player1) {
Connect();
controller_connected[player_index] = true;
} else if (player.connected && !controller_connected[player_index]) {
Connect();
controller_connected[player_index] = true;
}
}
} }
TriggerOnChange(ControllerTriggerType::Button, true); TriggerOnChange(ControllerTriggerType::Button, true);
@@ -22,6 +22,7 @@
#include "common/settings.h" #include "common/settings.h"
#include "common/vector_math.h" #include "common/vector_math.h"
#include "hid_core/frontend/motion_input.h" #include "hid_core/frontend/motion_input.h"
#include "hid_core/hid_core.h"
#include "hid_core/hid_types.h" #include "hid_core/hid_types.h"
#include "hid_core/irsensor/irs_types.h" #include "hid_core/irsensor/irs_types.h"
@@ -584,6 +585,7 @@ private:
std::array<VibrationValue, 2> last_vibration_value{DEFAULT_VIBRATION_VALUE, std::array<VibrationValue, 2> last_vibration_value{DEFAULT_VIBRATION_VALUE,
DEFAULT_VIBRATION_VALUE}; DEFAULT_VIBRATION_VALUE};
std::array<std::chrono::steady_clock::time_point, 2> last_vibration_timepoint{}; std::array<std::chrono::steady_clock::time_point, 2> last_vibration_timepoint{};
std::array<bool, HIDCore::available_controllers> controller_connected{};
// Atomically synched values // Atomically synched values
std::atomic<HID::NpadStyleIndex> npad_type{HID::NpadStyleIndex::None}; std::atomic<HID::NpadStyleIndex> npad_type{HID::NpadStyleIndex::None};