libretro / libretro/libretro-common
Enhanced Drive API (RFC)
Nobody has claimed this yet.
- Dominant language
- C
- Stars
- 180
- Forks
- 98
- Avg merge
- 7h 16m
- Merged PRs (30d)
- 1
Description
Hi, this is a design/specification (and request for comments) for an enhanced drive API for LibRetro cores.
The current LibRetro API defines a single anonymous drive. While this is sufficient for consoles like the PlayStation, it is not suitable for describing the more complex and varied configurations of home computer systems such as the C64, Apple ][ and Amiga, etc.
This new API introduces a mechanism for cores to tell the front-end about an arbitrary number of independent "drives" each with additional meta-data to both identify the drive with a system specific name (e.g. "DF0") and generally describe the kind of drive (e.g. 3.5" floppy, DVD drive, etc.) to allow for correct iconography and terminology such as disk/disc, etc. Also with an API to control the state of the drive and to request content data be loaded into it.
The API is a recognisable mix of the controller API and existing disk control interface.
Drive
A drive is the generic name used to describe any media storage device that can be loaded with content stored on the host computer in a core-specific or standardised image file format.
A drive can represent a wide range of devices such as a tape cassette, floppy disk, hard disk, ROM cartridge, memory stick, etc.
A drive can accept only one content file at a time. It is the front-end's responsibility to implement "CD multi-changer" functionality for multiple disk titles.
The core provides a list of acceptable content file extensions on a per-drive basis to allow for mixed media support (e.g. .TAP files limited to just the cassette drive).
Drive States
A drive can be in one of the following 6 states.
RETRO_DRIVE_STATE_INVALID,
The drive does not exist, the index used to specify it is invalid.
RETRO_DRIVE_STATE_CLOSED,
The drive is connected but empty and also unavailable for new content to be loaded. The simulated drive mechanism (e.g. CD tray, cassette door, etc.) is considered to be closed/locked in this state. Requesting a RETRO_DRIVE_STATE_OPEN state may allow content to be loaded if the core permits it. This state allows the core to forbid media insertion on this drive. This is the recommended default state for drives on start-up.
RETRO_DRIVE_STATE_OPEN,
The drive is empty and available for new content to be loaded. The simulated drive mechanism (e.g. CD tray, cassette door, etc.) is considered to be open/unlocked in this state.
RETRO_DRIVE_STATE_LOADED,
The drive has content loaded into it and is operating correctly, able to read and/or write data as the core decides. This state is typically set by the core automatically after a call to the retro_drive_load_content function. The front-end must maintain a consistent pointer to any allocated memory for content supplied via an in-memory buffer.
RETRO_DRIVE_STATE_REMOVED,
The drive has been physically disconnected from the system. It is not available for content to be loaded and cannot be accessed by the core. It is implied that the removal of the drive has also emptied it of any media/content. This drive can be hidden by the front-end until potentially re-instated via a state change to RETRO_DRIVE_STATE_OPEN or RETRO_DRIVE_STATE_EMPTY.
RETRO_DRIVE_STATE_ERROR,
The drive has failed but is in a recoverable error state. This state is for use by the core to report when invalid data has been encountered such as a bad sector, or a host file error has occurred. This condition can be addressed by requesting a RETRO_DRIVE_STATE_OPEN or RETRO_DRIVE_STATE_REMOVED state transition.
Note that some states are not permitted for certain drive types, the core determines whether a requested state transition is permitted and has the final say on which states are used / reported to the front-end. Drive state should not be assumed by the front-end.
Drive API
struct retro_drive_description
{
const char* desc;
/* [OPTIONAL] Short core specific identifier for the drive for human presentation.
A system without a named drive (such as a PlayStation) should use NULL.
e.g. a DOS machine might use "A:" for a floppy drive. The core is required to keep this pointer valid
while loaded or until a new retro_drive_description array is submitted to the front-end.
*/
unsigned media_id;
/* Describes the kind of drive and media this drive accepts for human usage. Used to allow the front-end to describe it more accurately. For example being able to use disk or disc correctly, or to draw a suitable icon in a menu.
The value is specified as a main type in the low byte and a sub-type in the high byte. A sub-type of 0 mean generic or not-applicable. Main and sub types are given below as RETRO_MEDIA_xxx constant definitions.
For sub-types that are super-sets of lesser types, specify the maximum supported or most common media type - e.g. A PlayStation 2 would specify RETRO_MEDIA_DISK_DVD even though it can also accept CDs. */
const char* valid_extensions;
/* Same definition as retro_get_system_info(). */
}
A structure describing a single drive in the system.
Media class constants
#define RETRO_MEDIA_CLASS_SHIFT 8
#define RETRO_MEDIA_CLASS_MASK ((1 << RETRO_MEDIA_CLASS_SHIFT) - 1)
/* media classes */
#define RETRO_MEDIA_GENERIC 0
#define RETRO_MEDIA_CASSETTE 1
#define RETRO_MEDIA_FLOPPY 2
#define RETRO_MEDIA_DISC 3
#define RETRO_MEDIA_HDD 4
#define RETRO_MEDIA_CARTRIDGE 5
#define RETRO_MEDIA_CARD 6
/* media sub-classes */
#define RETRO_MEDIA_FLOPPY_8 (( 1 ) << RETRO_DEVICE_TYPE_SHIFT)
#define RETRO_MEDIA_FLOPPY_5_1_4 (( 2 ) << RETRO_DEVICE_TYPE_SHIFT)
#define RETRO_MEDIA_FLOPPY_3 (( 3 ) << RETRO_DEVICE_TYPE_SHIFT)
#define RETRO_MEDIA_FLOPPY_3_5 (( 4 ) << RETRO_DEVICE_TYPE_SHIFT)
#define RETRO_MEDIA_FLOPPY_NINTENDO_FDS (( 5 ) << RETRO_DEVICE_TYPE_SHIFT)
#define RETRO_MEDIA_DISC_LASER (( 1 ) << RETRO_DEVICE_TYPE_SHIFT)
#define RETRO_MEDIA_DISC_CD (( 2 ) << RETRO_DEVICE_TYPE_SHIFT)
#define RETRO_MEDIA_DISC_GDROM (( 3 ) << RETRO_DEVICE_TYPE_SHIFT)
#define RETRO_MEDIA_DISC_DVD (( 4 ) << RETRO_DEVICE_TYPE_SHIFT)
#define RETRO_MEDIA_DISC_MINI_DVD (( 5 ) << RETRO_DEVICE_TYPE_SHIFT)
#define RETRO_MEDIA_DISC_HD_DVD (( 6 ) << RETRO_DEVICE_TYPE_SHIFT)
#define RETRO_MEDIA_DISC_BLURAY (( 7 ) << RETRO_DEVICE_TYPE_SHIFT)
#define RETRO_MEDIA_HDD_IDE (( 1 ) << RETRO_DEVICE_TYPE_SHIFT)
#define RETRO_MEDIA_HDD_SCSI (( 2 ) << RETRO_DEVICE_TYPE_SHIFT)
#define RETRO_MEDIA_HDD_ACSI (( 3 ) << RETRO_DEVICE_TYPE_SHIFT)
#define RETRO_MEDIA_CARD_SD (( 1 ) << RETRO_DEVICE_TYPE_SHIFT)
#define RETRO_MEDIA_CARD_SEGA_MYCARD (( 2 ) << RETRO_DEVICE_TYPE_SHIFT)
#define RETRO_MEDIA_CARD_HUCARD (( 3 ) << RETRO_DEVICE_TYPE_SHIFT)
struct retro_drive_info
{
const struct retro_drive_description *drives;
unsigned num_drives;
};
A container structure similar to struct retro_controller_info
#define RETRO_ENVIRONMENT_SET_DRIVE_INFO
Used to specify a pointer to a retro_drive_info structure
typedef unsigned (RETRO_CALLCONV * retro_drive_get_state_t)(unsigned drive_index);
/* Returns a RETRO_DRIVE_STATE_xxx value for the drive.
drive_index is the logical index from the retro_drive_info array.
Invalid indices should return RETRO_DRIVE_STATE_INVALID */
typedef bool (RETRO_CALLCONV * retro_drive_request_state_t)(unsigned drive_index, unsigned state);
/* Request a state transition for this drive, returns true if successful.
The core is free to ignore any state request. */
typedef bool (RETRO_CALLCONV * retro_drive_load_content_t)(unsigned drive_index, struct retro_game_info* content);
/* Submit content for the given drive index. Returns true if successful, however the front-end should check for RETRO_DRIVE_STATE_ERROR for subsequent errors during execution.
For data buffers, the core should NOT take ownership of the given pointer. The F-E should check for a state being other than RETRO_DRIVE_STATE_LOADED before freeing this memory. */
struct retro_drive_control_callback
{
retro_drive_request_state_t request_state;
retro_drive_get_state_t get_drive_state;
retro_drive_load_content_t load_content;
};
A structure to contain the control callback function pointers.
#define RETRO_ENVIRONMENT_SET_DRIVE_CONTROL_INTERFACE
Used to specify a pointer to a retro_drive_control structure.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the proposed drive API specification in this issue, including its structures, constants, environment commands, and callbacks. Because no file or test is identified and the proposal is an unresolved RFC, confirm the design and implementation scope with maintainers before work begins; done would require an agreed API and corresponding project changes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- api, backend-api-design
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100