mirror of
https://github.com/libretro/RetroArch
synced 2025-02-06 00:39:53 +00:00
cdrom: add function to get list of available drives (initial linux implementation), show list in "Dump Drive" menu entry
This commit is contained in:
parent
36c2fc847d
commit
9a52595ce3
@ -34,16 +34,19 @@
|
||||
#include <retro_endianness.h>
|
||||
#include <retro_miscellaneous.h>
|
||||
#include <vfs/vfs_implementation.h>
|
||||
#include <lists/string_list.h>
|
||||
#include <lists/dir_list.h>
|
||||
#include <string/stdstring.h>
|
||||
|
||||
#include <math.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __linux__
|
||||
#if defined(__linux__) && !defined(ANDROID)
|
||||
#include <stropts.h>
|
||||
#include <scsi/sg.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
#include <winioctl.h>
|
||||
#include <ntddscsi.h>
|
||||
#endif
|
||||
@ -86,7 +89,7 @@ void increment_msf(unsigned char *min, unsigned char *sec, unsigned char *frame)
|
||||
*frame = (*frame < 74) ? (*frame + 1) : 0;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
static int cdrom_send_command_win32(HANDLE fh, CDROM_CMD_Direction dir, void *buf, size_t len, unsigned char *cmd, size_t cmd_len, unsigned char *sense, size_t sense_len)
|
||||
{
|
||||
DWORD ioctl_bytes;
|
||||
@ -134,7 +137,7 @@ static int cdrom_send_command_win32(HANDLE fh, CDROM_CMD_Direction dir, void *bu
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
#if defined(__linux__) && !defined(ANDROID)
|
||||
static int cdrom_send_command_linux(int fd, CDROM_CMD_Direction dir, void *buf, size_t len, unsigned char *cmd, size_t cmd_len, unsigned char *sense, size_t sense_len)
|
||||
{
|
||||
sg_io_hdr_t sgio = {0};
|
||||
@ -172,7 +175,7 @@ static int cdrom_send_command_linux(int fd, CDROM_CMD_Direction dir, void *buf,
|
||||
}
|
||||
#endif
|
||||
|
||||
static int cdrom_send_command(libretro_vfs_implementation_file *stream, CDROM_CMD_Direction dir, void *buf, size_t len, unsigned char *cmd, size_t cmd_len, size_t skip)
|
||||
static int cdrom_send_command(const libretro_vfs_implementation_file *stream, CDROM_CMD_Direction dir, void *buf, size_t len, unsigned char *cmd, size_t cmd_len, size_t skip)
|
||||
{
|
||||
unsigned char *xfer_buf;
|
||||
unsigned char sense[CDROM_MAX_SENSE_BYTES] = {0};
|
||||
@ -204,10 +207,10 @@ static int cdrom_send_command(libretro_vfs_implementation_file *stream, CDROM_CM
|
||||
#endif
|
||||
|
||||
retry:
|
||||
#ifdef __linux__
|
||||
#if defined(__linux__) && !defined(ANDROID)
|
||||
if (!cdrom_send_command_linux(fileno(stream->fp), dir, xfer_buf, len + skip, cmd, cmd_len, sense, sizeof(sense)))
|
||||
#else
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
if (!cdrom_send_command_win32(stream->fh, dir, xfer_buf, len + skip, cmd, cmd_len, sense, sizeof(sense)))
|
||||
#endif
|
||||
#endif
|
||||
@ -554,7 +557,7 @@ int cdrom_write_cue(libretro_vfs_implementation_file *stream, char **out_buf, si
|
||||
|
||||
cdrom_read_track_info(stream, point, toc);
|
||||
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
pos += snprintf(*out_buf + pos, len - pos, "FILE \"cdrom://%c://drive-track%02d.bin\" BINARY\n", cdrom_drive, point);
|
||||
#else
|
||||
pos += snprintf(*out_buf + pos, len - pos, "FILE \"cdrom://drive%c-track%02d.bin\" BINARY\n", cdrom_drive, point);
|
||||
@ -585,7 +588,7 @@ int cdrom_write_cue(libretro_vfs_implementation_file *stream, char **out_buf, si
|
||||
}
|
||||
|
||||
/* needs 32 bytes for full vendor, product and version */
|
||||
int cdrom_get_inquiry(libretro_vfs_implementation_file *stream, char *model, int len)
|
||||
int cdrom_get_inquiry(const libretro_vfs_implementation_file *stream, char *model, int len, bool *is_cdrom)
|
||||
{
|
||||
/* MMC Command: INQUIRY */
|
||||
unsigned char cdb[] = {0x12, 0, 0, 0, 0xff, 0};
|
||||
@ -613,6 +616,9 @@ int cdrom_get_inquiry(libretro_vfs_implementation_file *stream, char *model, int
|
||||
memcpy(model + 26, buf + 32, 4);
|
||||
}
|
||||
|
||||
if (is_cdrom && buf[0] == 5)
|
||||
*is_cdrom = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -747,3 +753,61 @@ int cdrom_close_tray(libretro_vfs_implementation_file *stream)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct string_list* cdrom_get_available_drives(void)
|
||||
{
|
||||
struct string_list *list = string_list_new();
|
||||
int drive_index = 0;
|
||||
|
||||
#if defined(__linux__) && !defined(ANDROID)
|
||||
struct string_list *dir_list = dir_list_new("/dev", NULL, false, false, false, false);
|
||||
int i;
|
||||
|
||||
if (!dir_list)
|
||||
return list;
|
||||
|
||||
for (i = 0; i < dir_list->size; i++)
|
||||
{
|
||||
if (strstr(dir_list->elems[i].data, "/dev/sg"))
|
||||
{
|
||||
char drive_model[32] = {0};
|
||||
char drive_string[64] = {0};
|
||||
union string_list_elem_attr attr = {0};
|
||||
int dev_index = 0;
|
||||
RFILE *file = filestream_open(dir_list->elems[i].data, RETRO_VFS_FILE_ACCESS_READ, 0);
|
||||
const libretro_vfs_implementation_file *stream;
|
||||
bool is_cdrom = false;
|
||||
|
||||
if (!file)
|
||||
continue;
|
||||
|
||||
stream = filestream_get_vfs_handle(file);
|
||||
cdrom_get_inquiry(stream, drive_model, sizeof(drive_model), &is_cdrom);
|
||||
filestream_close(file);
|
||||
|
||||
if (!is_cdrom)
|
||||
continue;
|
||||
|
||||
sscanf(dir_list->elems[i].data + strlen("/dev/sg"), "%d", &dev_index);
|
||||
|
||||
attr.i = dev_index;
|
||||
|
||||
snprintf(drive_string, sizeof(drive_string), "Drive %d: ", drive_index + 1);
|
||||
|
||||
if (!string_is_empty(drive_model))
|
||||
strlcat(drive_string, drive_model, sizeof(drive_string));
|
||||
else
|
||||
strlcat(drive_string, "Unknown Drive", sizeof(drive_string));
|
||||
|
||||
string_list_append(list, drive_string, attr);
|
||||
drive_index++;
|
||||
}
|
||||
}
|
||||
|
||||
string_list_free(dir_list);
|
||||
#else
|
||||
string_list_append(list, "Drive 1", attr);
|
||||
#endif
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,8 @@ typedef struct retro_vfs_file_handle libretro_vfs_implementation_file;
|
||||
typedef struct libretro_vfs_implementation_file libretro_vfs_implementation_file;
|
||||
#endif
|
||||
|
||||
struct string_list;
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
typedef struct
|
||||
@ -73,7 +75,7 @@ int cdrom_read_subq(libretro_vfs_implementation_file *stream, unsigned char *buf
|
||||
int cdrom_write_cue(libretro_vfs_implementation_file *stream, char **out_buf, size_t *out_len, char cdrom_drive, unsigned char *num_tracks, cdrom_toc_t *toc);
|
||||
|
||||
/* needs 32 bytes for full vendor, product and version */
|
||||
int cdrom_get_inquiry(libretro_vfs_implementation_file *stream, char *model, int len);
|
||||
int cdrom_get_inquiry(const libretro_vfs_implementation_file *stream, char *model, int len, bool *is_cdrom);
|
||||
|
||||
int cdrom_read(libretro_vfs_implementation_file *stream, unsigned char min, unsigned char sec, unsigned char frame, void *s, size_t len, size_t skip);
|
||||
|
||||
@ -87,6 +89,9 @@ int cdrom_open_tray(libretro_vfs_implementation_file *stream);
|
||||
|
||||
int cdrom_close_tray(libretro_vfs_implementation_file *stream);
|
||||
|
||||
/* must be freed by the caller */
|
||||
struct string_list* cdrom_get_available_drives(void);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
||||
|
@ -53,7 +53,7 @@ void string_list_free(struct string_list *list)
|
||||
free(list->elems);
|
||||
}
|
||||
|
||||
list->elems = NULL;
|
||||
list->elems = NULL;
|
||||
free(list);
|
||||
}
|
||||
|
||||
|
@ -410,7 +410,7 @@ libretro_vfs_implementation_file *retro_vfs_file_open_impl(
|
||||
if (stream->scheme == VFS_SCHEME_CDROM)
|
||||
{
|
||||
retro_vfs_file_open_cdrom(stream, path, mode, hints);
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
if (!stream->fh)
|
||||
goto error;
|
||||
#else
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include <string/stdstring.h>
|
||||
#include <cdrom/cdrom.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
@ -127,7 +127,7 @@ void retro_vfs_file_open_cdrom(
|
||||
libretro_vfs_implementation_file *stream,
|
||||
const char *path, unsigned mode, unsigned hints)
|
||||
{
|
||||
#ifdef __linux__
|
||||
#if defined(__linux__) && !defined(ANDROID)
|
||||
char model[32] = {0};
|
||||
char cdrom_path[] = "/dev/sg1";
|
||||
size_t path_len = strlen(path);
|
||||
@ -176,7 +176,7 @@ void retro_vfs_file_open_cdrom(
|
||||
|
||||
if (stream->fp)
|
||||
{
|
||||
if (!cdrom_get_inquiry(stream, model, sizeof(model)))
|
||||
if (!cdrom_get_inquiry(stream, model, sizeof(model), NULL))
|
||||
{
|
||||
#ifdef CDROM_DEBUG
|
||||
printf("CDROM Model: %s\n", model);
|
||||
@ -211,7 +211,7 @@ void retro_vfs_file_open_cdrom(
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
char model[32] = {0};
|
||||
char cdrom_path[] = "\\\\.\\D:";
|
||||
size_t path_len = strlen(path);
|
||||
@ -313,7 +313,7 @@ int retro_vfs_file_close_cdrom(libretro_vfs_implementation_file *stream)
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
if (!stream->fh || !CloseHandle(stream->fh))
|
||||
return -1;
|
||||
#else
|
||||
|
@ -60,6 +60,10 @@
|
||||
#include "../frontend/drivers/platform_unix.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CDROM
|
||||
#include <cdrom/cdrom.h>
|
||||
#endif
|
||||
|
||||
#include "menu_cbs.h"
|
||||
#include "menu_content.h"
|
||||
#include "menu_driver.h"
|
||||
@ -4890,23 +4894,40 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type,
|
||||
|
||||
switch (type)
|
||||
{
|
||||
#ifdef HAVE_CDROM
|
||||
case DISPLAYLIST_DUMP_DISC:
|
||||
{
|
||||
int i;
|
||||
struct string_list *list = cdrom_get_available_drives();
|
||||
|
||||
menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list);
|
||||
count = 0;
|
||||
|
||||
/* TODO/FIXME - remove 'count = 0;' and implement disk list */
|
||||
|
||||
if (count == 0)
|
||||
for (i = 0; list && i < list->size; i++)
|
||||
{
|
||||
menu_entries_append_enum(info->list,
|
||||
list->elems[i].data,
|
||||
"",
|
||||
0,
|
||||
MENU_SET_CDROM_LIST,
|
||||
0, i);
|
||||
}
|
||||
|
||||
if (list->size == 0)
|
||||
menu_entries_append_enum(info->list,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_ENTRIES_TO_DISPLAY),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_NO_ENTRIES_TO_DISPLAY),
|
||||
MENU_ENUM_LABEL_NO_ENTRIES_TO_DISPLAY,
|
||||
FILE_TYPE_NONE, 0, 0);
|
||||
|
||||
string_list_free(list);
|
||||
|
||||
info->need_push = true;
|
||||
info->need_refresh = true;
|
||||
info->need_clear = true;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if defined(HAVE_LAKKA_SWITCH) || defined(HAVE_LIBNX)
|
||||
case DISPLAYLIST_SWITCH_CPU_PROFILE:
|
||||
{
|
||||
|
@ -194,6 +194,8 @@ enum menu_settings_type
|
||||
MENU_SET_SWITCH_CPU_PROFILE,
|
||||
#endif
|
||||
|
||||
MENU_SET_CDROM_LIST,
|
||||
|
||||
MENU_SETTINGS_LAST
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user