mirror of
https://git.suyu.dev/suyu/suyu
synced 2024-12-23 09:53:10 -06:00
experiment
This commit is contained in:
parent
a7822c2ddb
commit
f8802b232b
2 changed files with 117 additions and 0 deletions
|
@ -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
|
||||
|
|
89
src/core/libretro_wrapper.cpp
Normal file
89
src/core/libretro_wrapper.cpp
Normal 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
|
Loading…
Reference in a new issue