mirror of
https://git.suyu.dev/suyu/suyu.git
synced 2024-11-25 16:22:47 +01: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 "common/common_types.h"
|
||||||
#include "core/file_sys/vfs/vfs_types.h"
|
#include "core/file_sys/vfs/vfs_types.h"
|
||||||
|
#include "libretro.h"
|
||||||
|
|
||||||
namespace Core::Frontend {
|
namespace Core::Frontend {
|
||||||
class EmuWindow;
|
class EmuWindow;
|
||||||
|
@ -140,6 +141,25 @@ enum class SystemResultStatus : u32 {
|
||||||
ErrorLoader, ///< The base for loader errors (too many to repeat)
|
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 {
|
class System {
|
||||||
public:
|
public:
|
||||||
using CurrentBuildProcessID = std::array<u8, 0x20>;
|
using CurrentBuildProcessID = std::array<u8, 0x20>;
|
||||||
|
@ -456,9 +476,17 @@ public:
|
||||||
/// Applies any changes to settings to this core instance.
|
/// Applies any changes to settings to this core instance.
|
||||||
void ApplySettings();
|
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:
|
private:
|
||||||
struct Impl;
|
struct Impl;
|
||||||
std::unique_ptr<Impl> impl;
|
std::unique_ptr<Impl> impl;
|
||||||
|
std::unique_ptr<LibretroWrapper> libretro_wrapper;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Core
|
} // 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