mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-04-28 00:04:53 +00:00
Add MemoryPoker for RAIntegration
This commit is contained in:
parent
90a4be4b36
commit
fa782de15c
2 changed files with 67 additions and 6 deletions
|
@ -33,6 +33,7 @@
|
||||||
#include "Core/GeckoCode.h"
|
#include "Core/GeckoCode.h"
|
||||||
#include "Core/HW/Memmap.h"
|
#include "Core/HW/Memmap.h"
|
||||||
#include "Core/HW/VideoInterface.h"
|
#include "Core/HW/VideoInterface.h"
|
||||||
|
#include "Core/Host.h"
|
||||||
#include "Core/PatchEngine.h"
|
#include "Core/PatchEngine.h"
|
||||||
#include "Core/PowerPC/MMU.h"
|
#include "Core/PowerPC/MMU.h"
|
||||||
#include "Core/System.h"
|
#include "Core/System.h"
|
||||||
|
@ -308,15 +309,26 @@ void AchievementManager::FetchGameBadges()
|
||||||
|
|
||||||
void AchievementManager::DoFrame()
|
void AchievementManager::DoFrame()
|
||||||
{
|
{
|
||||||
if (!IsGameLoaded() || !Core::IsCPUThread())
|
if (!(IsGameLoaded() || m_dll_found) || !Core::IsCPUThread())
|
||||||
return;
|
return;
|
||||||
{
|
{
|
||||||
std::lock_guard lg{m_lock};
|
#ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION
|
||||||
rc_client_do_frame(m_client);
|
if (m_dll_found)
|
||||||
}
|
{
|
||||||
|
std::lock_guard lg{m_memory_lock};
|
||||||
Core::System* system = m_system.load(std::memory_order_acquire);
|
Core::System* system = m_system.load(std::memory_order_acquire);
|
||||||
if (!system)
|
if (!system)
|
||||||
return;
|
return;
|
||||||
|
Core::CPUThreadGuard thread_guard(*system);
|
||||||
|
u32 ram_size = system->GetMemory().GetRamSizeReal();
|
||||||
|
if (m_cloned_memory.size() != ram_size)
|
||||||
|
m_cloned_memory.resize(ram_size);
|
||||||
|
system->GetMemory().CopyFromEmu(m_cloned_memory.data(), 0, m_cloned_memory.size());
|
||||||
|
}
|
||||||
|
#endif // RC_CLIENT_SUPPORTS_RAINTEGRATION
|
||||||
|
std::lock_guard lg{m_lock};
|
||||||
|
rc_client_do_frame(m_client);
|
||||||
|
}
|
||||||
auto current_time = std::chrono::steady_clock::now();
|
auto current_time = std::chrono::steady_clock::now();
|
||||||
if (current_time - m_last_rp_time > std::chrono::seconds{10})
|
if (current_time - m_last_rp_time > std::chrono::seconds{10})
|
||||||
{
|
{
|
||||||
|
@ -1262,16 +1274,33 @@ u32 AchievementManager::MemoryPeeker(u32 address, u8* buffer, u32 num_bytes, rc_
|
||||||
{
|
{
|
||||||
if (buffer == nullptr)
|
if (buffer == nullptr)
|
||||||
return 0u;
|
return 0u;
|
||||||
|
#ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION
|
||||||
|
auto& instance = AchievementManager::GetInstance();
|
||||||
|
if (instance.m_dll_found)
|
||||||
|
{
|
||||||
|
std::lock_guard lg{instance.m_memory_lock};
|
||||||
|
if (u64(address) + num_bytes >= instance.m_cloned_memory.size())
|
||||||
|
{
|
||||||
|
ERROR_LOG_FMT(ACHIEVEMENTS,
|
||||||
|
"Attempt to read past memory size: size {} address {} write length {}",
|
||||||
|
instance.m_cloned_memory.size(), address, num_bytes);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
std::copy(instance.m_cloned_memory.begin() + address,
|
||||||
|
instance.m_cloned_memory.begin() + address + num_bytes, buffer);
|
||||||
|
return num_bytes;
|
||||||
|
}
|
||||||
|
#endif // RC_CLIENT_SUPPORTS_RAINTEGRATION
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = Core::System::GetInstance();
|
||||||
if (!(Core::IsHostThread() || Core::IsCPUThread()))
|
if (!(Core::IsHostThread() || Core::IsCPUThread()))
|
||||||
{
|
{
|
||||||
ASSERT_MSG(ACHIEVEMENTS, false, "MemoryPeeker called from wrong thread");
|
ASSERT_MSG(ACHIEVEMENTS, false, "MemoryPeeker called from wrong thread");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Core::CPUThreadGuard threadguard(system);
|
Core::CPUThreadGuard thread_guard(system);
|
||||||
for (u32 num_read = 0; num_read < num_bytes; num_read++)
|
for (u32 num_read = 0; num_read < num_bytes; num_read++)
|
||||||
{
|
{
|
||||||
auto value = system.GetMMU().HostTryReadU8(threadguard, address + num_read,
|
auto value = system.GetMMU().HostTryReadU8(thread_guard, address + num_read,
|
||||||
PowerPC::RequestedAddressSpace::Physical);
|
PowerPC::RequestedAddressSpace::Physical);
|
||||||
if (!value.has_value())
|
if (!value.has_value())
|
||||||
return num_read;
|
return num_read;
|
||||||
|
@ -1439,6 +1468,7 @@ void AchievementManager::LoadIntegrationCallback(int result, const char* error_m
|
||||||
INFO_LOG_FMT(ACHIEVEMENTS, "RAIntegration.dll found.");
|
INFO_LOG_FMT(ACHIEVEMENTS, "RAIntegration.dll found.");
|
||||||
instance.m_dll_found = true;
|
instance.m_dll_found = true;
|
||||||
rc_client_raintegration_set_event_handler(instance.m_client, RAIntegrationEventHandler);
|
rc_client_raintegration_set_event_handler(instance.m_client, RAIntegrationEventHandler);
|
||||||
|
rc_client_raintegration_set_write_memory_function(instance.m_client, MemoryPoker);
|
||||||
instance.m_dev_menu_callback();
|
instance.m_dev_menu_callback();
|
||||||
// TODO: hook up menu and dll event handlers
|
// TODO: hook up menu and dll event handlers
|
||||||
break;
|
break;
|
||||||
|
@ -1482,6 +1512,34 @@ void AchievementManager::RAIntegrationEventHandler(const rc_client_raintegration
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AchievementManager::MemoryPoker(u32 address, u8* buffer, u32 num_bytes, rc_client_t* client)
|
||||||
|
{
|
||||||
|
if (buffer == nullptr)
|
||||||
|
return;
|
||||||
|
if (!(Core::IsHostThread() || Core::IsCPUThread()))
|
||||||
|
{
|
||||||
|
Core::QueueHostJob([address, buffer, num_bytes, client](Core::System& system) {
|
||||||
|
MemoryPoker(address, buffer, num_bytes, client);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto& instance = AchievementManager::GetInstance();
|
||||||
|
if (u64(address) + num_bytes >= instance.m_cloned_memory.size())
|
||||||
|
{
|
||||||
|
ERROR_LOG_FMT(ACHIEVEMENTS,
|
||||||
|
"Attempt to write past memory size: size {} address {} write length {}",
|
||||||
|
instance.m_cloned_memory.size(), address, num_bytes);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Core::System* system = instance.m_system.load(std::memory_order_acquire);
|
||||||
|
if (!system)
|
||||||
|
return;
|
||||||
|
Core::CPUThreadGuard thread_guard(*system);
|
||||||
|
std::lock_guard lg{instance.m_memory_lock};
|
||||||
|
system->GetMemory().CopyToEmu(address, buffer, num_bytes);
|
||||||
|
std::copy(buffer, buffer + num_bytes, instance.m_cloned_memory.begin() + address);
|
||||||
|
}
|
||||||
#endif // RC_CLIENT_SUPPORTS_RAINTEGRATION
|
#endif // RC_CLIENT_SUPPORTS_RAINTEGRATION
|
||||||
|
|
||||||
#endif // USE_RETRO_ACHIEVEMENTS
|
#endif // USE_RETRO_ACHIEVEMENTS
|
||||||
|
|
|
@ -253,6 +253,7 @@ private:
|
||||||
void* userdata);
|
void* userdata);
|
||||||
static void RAIntegrationEventHandler(const rc_client_raintegration_event_t* event,
|
static void RAIntegrationEventHandler(const rc_client_raintegration_event_t* event,
|
||||||
rc_client_t* client);
|
rc_client_t* client);
|
||||||
|
static void MemoryPoker(u32 address, u8* buffer, u32 num_bytes, rc_client_t* client);
|
||||||
#endif // RC_CLIENT_SUPPORTS_RAINTEGRATION
|
#endif // RC_CLIENT_SUPPORTS_RAINTEGRATION
|
||||||
|
|
||||||
rc_runtime_t m_runtime{};
|
rc_runtime_t m_runtime{};
|
||||||
|
@ -289,6 +290,8 @@ private:
|
||||||
bool m_dll_found = false;
|
bool m_dll_found = false;
|
||||||
#ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION
|
#ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION
|
||||||
std::function<void(void)> m_dev_menu_callback;
|
std::function<void(void)> m_dev_menu_callback;
|
||||||
|
std::vector<u8> m_cloned_memory;
|
||||||
|
std::recursive_mutex m_memory_lock;
|
||||||
#endif // RC_CLIENT_SUPPORTS_RAINTEGRATION
|
#endif // RC_CLIENT_SUPPORTS_RAINTEGRATION
|
||||||
|
|
||||||
Common::WorkQueueThread<std::function<void()>> m_queue;
|
Common::WorkQueueThread<std::function<void()>> m_queue;
|
||||||
|
|
Loading…
Add table
Reference in a new issue