mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-20 09:26:53 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a277b62fe4 | |||
| 908b1e9a37 |
@@ -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());
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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};
|
||||||
|
|||||||
Reference in New Issue
Block a user