mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-19 08:25:47 -04:00
libretro: Implement disk control interface
This commit is contained in:
@ -27,6 +27,7 @@ Log_SetChannel(LibretroHostInterface);
|
||||
#endif
|
||||
|
||||
LibretroHostInterface g_libretro_host_interface;
|
||||
#define P_THIS (&g_libretro_host_interface)
|
||||
|
||||
retro_environment_t g_retro_environment_callback;
|
||||
retro_video_refresh_t g_retro_video_refresh_callback;
|
||||
@ -232,6 +233,7 @@ bool LibretroHostInterface::retro_load_game(const struct retro_game_info* game)
|
||||
{
|
||||
SystemBootParameters bp;
|
||||
bp.filename = game->path;
|
||||
bp.media_playlist_index = m_next_disc_index.value_or(0);
|
||||
bp.force_software_renderer = !m_hw_render_callback_valid;
|
||||
|
||||
if (!BootSystem(bp))
|
||||
@ -907,3 +909,180 @@ void LibretroHostInterface::SwitchToSoftwareRenderer()
|
||||
m_display = std::make_unique<LibretroHostDisplay>();
|
||||
m_system->RecreateGPU(GPURenderer::Software);
|
||||
}
|
||||
|
||||
bool LibretroHostInterface::DiskControlSetEjectState(bool ejected)
|
||||
{
|
||||
System* system = P_THIS->GetSystem();
|
||||
if (!system)
|
||||
{
|
||||
Log_ErrorPrintf("DiskControlSetEjectState() - no system");
|
||||
return false;
|
||||
}
|
||||
|
||||
Log_DevPrintf("DiskControlSetEjectState(%u)", static_cast<unsigned>(ejected));
|
||||
|
||||
if (ejected)
|
||||
{
|
||||
if (!system->HasMedia())
|
||||
return false;
|
||||
|
||||
system->RemoveMedia();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
const u32 image_to_insert = P_THIS->m_next_disc_index.value_or(0);
|
||||
Log_DevPrintf("Inserting image %u", image_to_insert);
|
||||
return system->SwitchMediaFromPlaylist(image_to_insert);
|
||||
}
|
||||
}
|
||||
|
||||
bool LibretroHostInterface::DiskControlGetEjectState()
|
||||
{
|
||||
System* system = P_THIS->GetSystem();
|
||||
if (!system)
|
||||
{
|
||||
Log_ErrorPrintf("DiskControlGetEjectState() - no system");
|
||||
return false;
|
||||
}
|
||||
|
||||
Log_DevPrintf("DiskControlGetEjectState() -> %u", static_cast<unsigned>(system->HasMedia()));
|
||||
return system->HasMedia();
|
||||
}
|
||||
|
||||
unsigned LibretroHostInterface::DiskControlGetImageIndex()
|
||||
{
|
||||
System* system = P_THIS->GetSystem();
|
||||
if (!system)
|
||||
{
|
||||
Log_ErrorPrintf("DiskControlGetImageIndex() - no system");
|
||||
return false;
|
||||
}
|
||||
|
||||
const u32 index = P_THIS->m_next_disc_index.value_or(system->GetMediaPlaylistIndex());
|
||||
Log_DevPrintf("DiskControlGetImageIndex() -> %u", index);
|
||||
return index;
|
||||
}
|
||||
|
||||
bool LibretroHostInterface::DiskControlSetImageIndex(unsigned index)
|
||||
{
|
||||
System* system = P_THIS->GetSystem();
|
||||
if (!system)
|
||||
{
|
||||
Log_ErrorPrintf("DiskControlSetImageIndex() - no system");
|
||||
return false;
|
||||
}
|
||||
|
||||
Log_DevPrintf("DiskControlSetImageIndex(%u)", index);
|
||||
|
||||
if (index >= system->GetMediaPlaylistCount())
|
||||
return false;
|
||||
|
||||
P_THIS->m_next_disc_index = index;
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned LibretroHostInterface::DiskControlGetNumImages()
|
||||
{
|
||||
System* system = P_THIS->GetSystem();
|
||||
if (!system)
|
||||
{
|
||||
Log_ErrorPrintf("DiskControlGetNumImages() - no system");
|
||||
return false;
|
||||
}
|
||||
|
||||
Log_DevPrintf("DiskControlGetNumImages() -> %u", system->GetMediaPlaylistCount());
|
||||
return static_cast<unsigned>(system->GetMediaPlaylistCount());
|
||||
}
|
||||
|
||||
bool LibretroHostInterface::DiskControlReplaceImageIndex(unsigned index, const retro_game_info* info)
|
||||
{
|
||||
System* system = P_THIS->GetSystem();
|
||||
if (!system)
|
||||
{
|
||||
Log_ErrorPrintf("DiskControlReplaceImageIndex() - no system");
|
||||
return false;
|
||||
}
|
||||
|
||||
Log_DevPrintf("DiskControlReplaceImageIndex(%u, %s)", index, info ? info->path : "null");
|
||||
if (info && info->path)
|
||||
return system->ReplaceMediaPathFromPlaylist(index, info->path);
|
||||
else
|
||||
return system->RemoveMediaPathFromPlaylist(index);
|
||||
}
|
||||
|
||||
bool LibretroHostInterface::DiskControlAddImageIndex()
|
||||
{
|
||||
System* system = P_THIS->GetSystem();
|
||||
if (!system)
|
||||
{
|
||||
Log_ErrorPrintf("DiskControlAddImageIndex() - no system");
|
||||
return false;
|
||||
}
|
||||
|
||||
Log_DevPrintf("DiskControlAddImageIndex() -> %zu", system->GetMediaPlaylistCount());
|
||||
system->AddMediaPathToPlaylist({});
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LibretroHostInterface::DiskControlSetInitialImage(unsigned index, const char* path)
|
||||
{
|
||||
Log_DevPrintf("DiskControlSetInitialImage(%u, %s)", index, path);
|
||||
P_THIS->m_next_disc_index = index;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LibretroHostInterface::DiskControlGetImagePath(unsigned index, char* path, size_t len)
|
||||
{
|
||||
System* system = P_THIS->GetSystem();
|
||||
if (!system || index >= system->GetMediaPlaylistCount())
|
||||
return false;
|
||||
|
||||
const std::string& image_path = system->GetMediaPlaylistPath(index);
|
||||
Log_DevPrintf("DiskControlGetImagePath(%u) -> %s", index, image_path.c_str());
|
||||
if (image_path.empty())
|
||||
return false;
|
||||
|
||||
StringUtil::Strlcpy(path, image_path.c_str(), len);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LibretroHostInterface::DiskControlGetImageLabel(unsigned index, char* label, size_t len)
|
||||
{
|
||||
System* system = P_THIS->GetSystem();
|
||||
if (!system || index >= system->GetMediaPlaylistCount())
|
||||
return false;
|
||||
|
||||
const std::string& image_path = system->GetMediaPlaylistPath(index);
|
||||
if (image_path.empty())
|
||||
return false;
|
||||
|
||||
const std::string_view title = GameList::GetTitleForPath(label);
|
||||
StringUtil::Strlcpy(label, title, len);
|
||||
Log_DevPrintf("DiskControlGetImagePath(%u) -> %s", index, label);
|
||||
return true;
|
||||
}
|
||||
|
||||
void LibretroHostInterface::InitDiskControlInterface()
|
||||
{
|
||||
unsigned version = 0;
|
||||
if (g_retro_environment_callback(RETRO_ENVIRONMENT_GET_DISK_CONTROL_INTERFACE_VERSION, &version) && version >= 1)
|
||||
{
|
||||
retro_disk_control_ext_callback ext_cb = {
|
||||
&LibretroHostInterface::DiskControlSetEjectState, &LibretroHostInterface::DiskControlGetEjectState,
|
||||
&LibretroHostInterface::DiskControlGetImageIndex, &LibretroHostInterface::DiskControlSetImageIndex,
|
||||
&LibretroHostInterface::DiskControlGetNumImages, &LibretroHostInterface::DiskControlReplaceImageIndex,
|
||||
&LibretroHostInterface::DiskControlAddImageIndex, &LibretroHostInterface::DiskControlSetInitialImage,
|
||||
&LibretroHostInterface::DiskControlGetImagePath, &LibretroHostInterface::DiskControlGetImageLabel};
|
||||
if (g_retro_environment_callback(RETRO_ENVIRONMENT_SET_DISK_CONTROL_EXT_INTERFACE, &ext_cb))
|
||||
return;
|
||||
}
|
||||
|
||||
retro_disk_control_callback cb = {
|
||||
&LibretroHostInterface::DiskControlSetEjectState, &LibretroHostInterface::DiskControlGetEjectState,
|
||||
&LibretroHostInterface::DiskControlGetImageIndex, &LibretroHostInterface::DiskControlSetImageIndex,
|
||||
&LibretroHostInterface::DiskControlGetNumImages, &LibretroHostInterface::DiskControlReplaceImageIndex,
|
||||
&LibretroHostInterface::DiskControlAddImageIndex};
|
||||
if (!g_retro_environment_callback(RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE, &cb))
|
||||
Log_WarningPrint("Failed to set disk control interface");
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
#include "core/host_interface.h"
|
||||
#include "core/system.h"
|
||||
#include "libretro.h"
|
||||
#include <limits>
|
||||
#include <optional>
|
||||
|
||||
class LibretroHostInterface : public HostInterface
|
||||
{
|
||||
@ -12,6 +14,7 @@ public:
|
||||
static void InitLogging();
|
||||
static bool SetCoreOptions();
|
||||
static bool HasCoreVariablesChanged();
|
||||
static void InitDiskControlInterface();
|
||||
|
||||
ALWAYS_INLINE u32 GetResolutionScale() const { return m_settings.gpu_resolution_scale; }
|
||||
|
||||
@ -66,10 +69,23 @@ private:
|
||||
static void HardwareRendererContextReset();
|
||||
static void HardwareRendererContextDestroy();
|
||||
|
||||
// Disk control callbacks
|
||||
static bool RETRO_CALLCONV DiskControlSetEjectState(bool ejected);
|
||||
static bool RETRO_CALLCONV DiskControlGetEjectState();
|
||||
static unsigned RETRO_CALLCONV DiskControlGetImageIndex();
|
||||
static bool RETRO_CALLCONV DiskControlSetImageIndex(unsigned index);
|
||||
static unsigned RETRO_CALLCONV DiskControlGetNumImages();
|
||||
static bool RETRO_CALLCONV DiskControlReplaceImageIndex(unsigned index, const retro_game_info* info);
|
||||
static bool RETRO_CALLCONV DiskControlAddImageIndex();
|
||||
static bool RETRO_CALLCONV DiskControlSetInitialImage(unsigned index, const char* path);
|
||||
static bool RETRO_CALLCONV DiskControlGetImagePath(unsigned index, char* path, size_t len);
|
||||
static bool RETRO_CALLCONV DiskControlGetImageLabel(unsigned index, char* label, size_t len);
|
||||
|
||||
retro_hw_render_callback m_hw_render_callback = {};
|
||||
std::unique_ptr<HostDisplay> m_hw_render_display;
|
||||
bool m_hw_render_callback_valid = false;
|
||||
bool m_using_hardware_renderer = false;
|
||||
std::optional<u32> m_next_disc_index;
|
||||
};
|
||||
|
||||
extern LibretroHostInterface g_libretro_host_interface;
|
||||
|
@ -127,6 +127,7 @@ RETRO_API void retro_set_environment(retro_environment_t f)
|
||||
Log_WarningPrintf("Failed to set core options, settings will not be changeable.");
|
||||
|
||||
g_libretro_host_interface.InitLogging();
|
||||
g_libretro_host_interface.InitDiskControlInterface();
|
||||
}
|
||||
|
||||
RETRO_API void retro_set_video_refresh(retro_video_refresh_t f)
|
||||
|
Reference in New Issue
Block a user