Backport jdgleaver's 'add disk control interface V1 support' PR

This commit is contained in:
libretroadmin 2022-05-27 00:55:09 +02:00
parent aeca338aa4
commit f53fcc5866
4 changed files with 173 additions and 47 deletions

3
.gitignore vendored
View File

@ -1,6 +1,7 @@
*.o
*.so
*.dll
*.pdb
*.lib
*.exp
*.manifest
*.manifest

176
disc.cpp
View File

@ -20,8 +20,14 @@ static bool g_eject_state;
static int g_current_disc;
static unsigned g_initial_disc;
static std::string g_initial_disc_path;
static std::vector<CDIF *> CDInterfaces;
static std::vector<std::string> disk_image_paths;
static std::vector<std::string> disk_image_labels;
//
// Remember to rebuild region database in db.cpp if changing the order of
// entries in this table(and be careful about game id collisions,
@ -152,11 +158,6 @@ static bool disk_get_eject_state(void)
return g_eject_state;
}
static unsigned disk_get_image_index(void)
{
return g_current_disc;
}
static bool disk_set_image_index(unsigned index)
{
// only listen if the tray is open
@ -229,6 +230,9 @@ static bool disk_replace_image_index(unsigned index, const struct retro_game_inf
if (index < CD_SelectedDisc)
CD_SelectedDisc--;
disk_image_paths.erase(disk_image_paths.begin() + index);
disk_image_labels.erase(disk_image_labels.begin() + index);
// Poke into psx.cpp
CalcDiscSCEx();
return true;
@ -248,6 +252,11 @@ static bool disk_replace_image_index(unsigned index, const struct retro_game_inf
extract_basename(retro_cd_base_name, info->path, sizeof(retro_cd_base_name));
/* Ugly, but needed to get proper disk swapping effect. */
update_md5_checksum(iface);
/* Update disk path/label vectors */
disk_image_paths[index] = info->path;
disk_image_labels[index] = retro_cd_base_name;
return true;
#endif
}
@ -257,14 +266,70 @@ static bool disk_add_image_index(void)
log_cb(RETRO_LOG_INFO, "disk_add_image_index called.\n");
CDInterfaces.push_back(NULL);
disk_image_paths.push_back("");
disk_image_labels.push_back("");
return true;
}
static bool disk_set_initial_image(unsigned index, const char *path)
{
if (string_is_empty(path))
return false;
g_initial_disc = index;
g_initial_disc_path = path;
return true;
}
static bool disk_get_image_path(unsigned index, char *path, size_t len)
{
if (len < 1)
return false;
if ((index < CDInterfaces.size()) &&
(index < disk_image_paths.size()))
{
if (!string_is_empty(disk_image_paths[index].c_str()))
{
strlcpy(path, disk_image_paths[index].c_str(), len);
return true;
}
}
return false;
}
static bool disk_get_image_label(unsigned index, char *label, size_t len)
{
if (len < 1)
return false;
if ((index < CDInterfaces.size()) &&
(index < disk_image_labels.size()))
{
if (!string_is_empty(disk_image_labels[index].c_str()))
{
strlcpy(label, disk_image_labels[index].c_str(), len);
return true;
}
}
return false;
}
//------------------------------------------------------------------------------
// Global Functions
//------------------------------------------------------------------------------
/* This has to be 'global', since we need to
* access the current disk index inside
* libretro.cpp */
unsigned disk_get_image_index(void)
{
return g_current_disc;
}
static struct retro_disk_control_callback disk_interface =
{
disk_set_eject_state,
@ -276,13 +341,69 @@ static struct retro_disk_control_callback disk_interface =
disk_add_image_index,
};
static struct retro_disk_control_ext_callback disk_interface_ext =
{
disk_set_eject_state,
disk_get_eject_state,
disk_get_image_index,
disk_set_image_index,
disk_get_num_images,
disk_replace_image_index,
disk_add_image_index,
disk_set_initial_image,
disk_get_image_path,
disk_get_image_label,
};
void extract_basename(char *buf, const char *path, size_t size)
{
const char *base = strrchr(path, '/');
if (!base)
base = strrchr(path, '\\');
if (!base)
base = path;
if (*base == '\\' || *base == '/')
base++;
strncpy(buf, base, size - 1);
buf[size - 1] = '\0';
char *ext = strrchr(buf, '.');
if (ext)
*ext = '\0';
}
void extract_directory(char *buf, const char *path, size_t size)
{
strncpy(buf, path, size - 1);
buf[size - 1] = '\0';
char *base = strrchr(buf, '/');
if (!base)
base = strrchr(buf, '\\');
if (base)
*base = '\0';
else
buf[0] = '\0';
}
void disc_init( retro_environment_t environ_cb )
{
unsigned dci_version = 0;
// start closed
g_eject_state = false;
g_initial_disc = 0;
g_initial_disc_path.clear();
// register vtable with environment
environ_cb( RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE, &disk_interface );
if (environ_cb(RETRO_ENVIRONMENT_GET_DISK_CONTROL_INTERFACE_VERSION, &dci_version) && (dci_version >= 1))
environ_cb(RETRO_ENVIRONMENT_SET_DISK_CONTROL_EXT_INTERFACE, &disk_interface_ext);
else
environ_cb(RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE, &disk_interface);
}
static INLINE bool MDFN_isspace(const char c) { return c == ' ' || c == '\f' || c == '\r' || c == '\n' || c == '\t' || c == '\v'; }
@ -427,6 +548,9 @@ void disc_cleanup(void)
}
CDInterfaces.clear();
disk_image_paths.clear();
disk_image_labels.clear();
g_current_disc = 0;
}
@ -589,23 +713,53 @@ bool disc_load_content( MDFNGI* game_interface, const char* content_name, uint8*
if ( !strcasecmp( content_ext, ".m3u" ) )
{
// multiple discs
std::vector<std::string> file_list;
ReadM3U(file_list, content_name);
for(unsigned i = 0; i < file_list.size(); i++)
ReadM3U(disk_image_paths, content_name);
for(unsigned i = 0; i < disk_image_paths.size(); i++)
{
char image_label[4096];
bool success = true;
log_cb(RETRO_LOG_INFO, "Adding CD: \"%s\".\n", file_list[i].c_str());
CDIF *image = CDIF_Open(file_list[i].c_str(), image_memcache);
image_label[0] = '\0';
log_cb(RETRO_LOG_INFO, "Adding CD: \"%s\".\n", disk_image_paths[i].c_str());
CDIF *image = CDIF_Open(disk_image_paths[i].c_str(), image_memcache);
CDInterfaces.push_back(image);
extract_basename(
image_label,
disk_image_paths[i].c_str(),
sizeof(image_label));
disk_image_labels.push_back(image_label);
}
}
else
{
// single disc
char image_label[4096];
bool success = true;
image_label[0] = '\0';
disk_image_paths.push_back(content_name);
CDIF *image = CDIF_Open(content_name, image_memcache);
CDInterfaces.push_back(image);
extract_basename(
image_label,
content_name,
sizeof(image_label));
disk_image_labels.push_back(image_label);
}
/* Attempt to set initial disk index */
if ((g_initial_disc > 0) &&
(g_initial_disc
< CDInterfaces.size()))
if (g_initial_disc
< disk_image_paths.size())
if (string_is_equal(
disk_image_paths[
g_initial_disc].c_str(),
g_initial_disc_path.c_str()))
g_current_disc = (int)
g_initial_disc;
}
}
catch( std::exception &e )

5
disc.h
View File

@ -5,8 +5,13 @@
#include "mednafen/git.h"
#include "mednafen/mednafen-types.h"
extern void extract_basename(char *buf, const char *path, size_t size);
extern void extract_directory(char *buf, const char *path, size_t size);
// These routines handle disc drive front-end.
extern unsigned disk_get_image_index(void);
void disc_init( retro_environment_t environ_cb );
void disc_cleanup(void);

View File

@ -96,40 +96,6 @@ extern MDFNGI EmulatedSS;
MDFN_COLD void CloseGame(void);
void Emulate(EmulateSpecStruct* espec_arg);
static void extract_basename(char *buf, const char *path, size_t size)
{
const char *base = strrchr(path, '/');
if (!base)
base = strrchr(path, '\\');
if (!base)
base = path;
if (*base == '\\' || *base == '/')
base++;
strncpy(buf, base, size - 1);
buf[size - 1] = '\0';
char *ext = strrchr(buf, '.');
if (ext)
*ext = '\0';
}
static void extract_directory(char *buf, const char *path, size_t size)
{
strncpy(buf, path, size - 1);
buf[size - 1] = '\0';
char *base = strrchr(buf, '/');
if (!base)
base = strrchr(buf, '\\');
if (base)
*base = '\0';
else
buf[0] = '\0';
}
//forward decls
static bool overscan;
static double last_sound_rate;
@ -674,7 +640,7 @@ bool retro_load_game(const struct retro_game_info *info)
boot = false;
disc_select(0);
disc_select(disk_get_image_index());
frame_count = 0;
internal_frame_count = 0;