experiment

This commit is contained in:
Crunch (Chaz9) 2024-09-29 22:31:12 +01:00
parent a7822c2ddb
commit f8802b232b
2 changed files with 117 additions and 0 deletions

View file

@ -14,6 +14,7 @@
#include "common/common_types.h"
#include "core/file_sys/vfs/vfs_types.h"
#include "libretro.h"
namespace Core::Frontend {
class EmuWindow;
@ -140,6 +141,25 @@ enum class SystemResultStatus : u32 {
ErrorLoader, ///< The base for loader errors (too many to repeat)
};
class LibretroWrapper {
public:
LibretroWrapper();
~LibretroWrapper();
bool LoadCore(const std::string& core_path);
bool LoadGame(const std::string& game_path);
void Run();
void Reset();
void Unload();
// Implement other libretro API functions as needed
private:
void* core_handle;
retro_game_info game_info;
// Add other necessary libretro-related members
};
class System {
public:
using CurrentBuildProcessID = std::array<u8, 0x20>;
@ -456,9 +476,17 @@ public:
/// Applies any changes to settings to this core instance.
void ApplySettings();
// New methods for libretro support
bool LoadLibretroCore(const std::string& core_path);
bool LoadLibretroGame(const std::string& game_path);
void RunLibretroCore();
void ResetLibretroCore();
void UnloadLibretroCore();
private:
struct Impl;
std::unique_ptr<Impl> impl;
std::unique_ptr<LibretroWrapper> libretro_wrapper;
};
} // namespace Core

View file

@ -0,0 +1,89 @@
#include "core/libretro_wrapper.h"
#include <dlfcn.h>
#include <stdexcept>
#include <cstring>
namespace Core {
LibretroWrapper::LibretroWrapper() : core_handle(nullptr) {}
LibretroWrapper::~LibretroWrapper() {
Unload();
}
bool LibretroWrapper::LoadCore(const std::string& core_path) {
core_handle = dlopen(core_path.c_str(), RTLD_LAZY);
if (!core_handle) {
return false;
}
// Load libretro core functions
retro_init = reinterpret_cast<void (*)()>(dlsym(core_handle, "retro_init"));
retro_deinit = reinterpret_cast<void (*)()>(dlsym(core_handle, "retro_deinit"));
retro_api_version = reinterpret_cast<unsigned (*)()>(dlsym(core_handle, "retro_api_version"));
retro_get_system_info = reinterpret_cast<void (*)(struct retro_system_info*)>(dlsym(core_handle, "retro_get_system_info"));
retro_get_system_av_info = reinterpret_cast<void (*)(struct retro_system_av_info*)>(dlsym(core_handle, "retro_get_system_av_info"));
retro_set_environment = reinterpret_cast<void (*)(retro_environment_t)>(dlsym(core_handle, "retro_set_environment"));
retro_set_video_refresh = reinterpret_cast<void (*)(retro_video_refresh_t)>(dlsym(core_handle, "retro_set_video_refresh"));
retro_set_audio_sample = reinterpret_cast<void (*)(retro_audio_sample_t)>(dlsym(core_handle, "retro_set_audio_sample"));
retro_set_audio_sample_batch = reinterpret_cast<void (*)(retro_audio_sample_batch_t)>(dlsym(core_handle, "retro_set_audio_sample_batch"));
retro_set_input_poll = reinterpret_cast<void (*)(retro_input_poll_t)>(dlsym(core_handle, "retro_set_input_poll"));
retro_set_input_state = reinterpret_cast<void (*)(retro_input_state_t)>(dlsym(core_handle, "retro_set_input_state"));
retro_set_controller_port_device = reinterpret_cast<void (*)(unsigned, unsigned)>(dlsym(core_handle, "retro_set_controller_port_device"));
retro_reset = reinterpret_cast<void (*)()>(dlsym(core_handle, "retro_reset"));
retro_run = reinterpret_cast<void (*)()>(dlsym(core_handle, "retro_run"));
retro_serialize_size = reinterpret_cast<size_t (*)()>(dlsym(core_handle, "retro_serialize_size"));
retro_serialize = reinterpret_cast<bool (*)(void*, size_t)>(dlsym(core_handle, "retro_serialize"));
retro_unserialize = reinterpret_cast<bool (*)(const void*, size_t)>(dlsym(core_handle, "retro_unserialize"));
retro_load_game = reinterpret_cast<bool (*)(const struct retro_game_info*)>(dlsym(core_handle, "retro_load_game"));
retro_unload_game = reinterpret_cast<void (*)()>(dlsym(core_handle, "retro_unload_game"));
if (!retro_init || !retro_deinit || !retro_api_version || !retro_get_system_info ||
!retro_get_system_av_info || !retro_set_environment || !retro_set_video_refresh ||
!retro_set_audio_sample || !retro_set_audio_sample_batch || !retro_set_input_poll ||
!retro_set_input_state || !retro_set_controller_port_device || !retro_reset ||
!retro_run || !retro_serialize_size || !retro_serialize || !retro_unserialize ||
!retro_load_game || !retro_unload_game) {
Unload();
return false;
}
retro_init();
return true;
}
bool LibretroWrapper::LoadGame(const std::string& game_path) {
if (!core_handle) {
return false;
}
game_info.path = game_path.c_str();
game_info.data = nullptr;
game_info.size = 0;
game_info.meta = nullptr;
return retro_load_game(&game_info);
}
void LibretroWrapper::Run() {
if (core_handle) {
retro_run();
}
}
void LibretroWrapper::Reset() {
if (core_handle) {
retro_reset();
}
}
void LibretroWrapper::Unload() {
if (core_handle) {
retro_unload_game();
retro_deinit();
dlclose(core_handle);
core_handle = nullptr;
}
}
} // namespace Core