mirror of https://github.com/mgba-emu/mgba.git
Libretro: Fix sensors
This commit is contained in:
parent
983a482527
commit
ff6218fe1e
|
@ -52,6 +52,10 @@ static void _updateCamera(const uint32_t* buffer, unsigned width, unsigned heigh
|
||||||
static void _startImage(struct mImageSource*, unsigned w, unsigned h, int colorFormats);
|
static void _startImage(struct mImageSource*, unsigned w, unsigned h, int colorFormats);
|
||||||
static void _stopImage(struct mImageSource*);
|
static void _stopImage(struct mImageSource*);
|
||||||
static void _requestImage(struct mImageSource*, const void** buffer, size_t* stride, enum mColorFormat* colorFormat);
|
static void _requestImage(struct mImageSource*, const void** buffer, size_t* stride, enum mColorFormat* colorFormat);
|
||||||
|
static void _updateRotation(struct mRotationSource* source);
|
||||||
|
static int32_t _readTiltX(struct mRotationSource* source);
|
||||||
|
static int32_t _readTiltY(struct mRotationSource* source);
|
||||||
|
static int32_t _readGyroZ(struct mRotationSource* source);
|
||||||
|
|
||||||
static struct mCore* core;
|
static struct mCore* core;
|
||||||
static color_t* outputBuffer = NULL;
|
static color_t* outputBuffer = NULL;
|
||||||
|
@ -81,9 +85,12 @@ static unsigned imcapHeight;
|
||||||
static size_t camStride;
|
static size_t camStride;
|
||||||
static bool deferredSetup = false;
|
static bool deferredSetup = false;
|
||||||
static bool envVarsUpdated;
|
static bool envVarsUpdated;
|
||||||
|
static int32_t tiltX = 0;
|
||||||
|
static int32_t tiltY = 0;
|
||||||
|
static int32_t gyroZ = 0;
|
||||||
|
|
||||||
static void _initSensors(void) {
|
static void _initSensors(void) {
|
||||||
if(sensorsInitDone) {
|
if (sensorsInitDone) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,13 +99,15 @@ static void _initSensors(void) {
|
||||||
sensorGetCallback = sensorInterface.get_sensor_input;
|
sensorGetCallback = sensorInterface.get_sensor_input;
|
||||||
sensorStateCallback = sensorInterface.set_sensor_state;
|
sensorStateCallback = sensorInterface.set_sensor_state;
|
||||||
|
|
||||||
if(sensorStateCallback(0, RETRO_SENSOR_ACCELEROMETER_ENABLE, EVENT_RATE)
|
if (sensorStateCallback && sensorGetCallback) {
|
||||||
&& sensorStateCallback(0, RETRO_SENSOR_GYROSCOPE_ENABLE, EVENT_RATE)) {
|
if (sensorStateCallback(0, RETRO_SENSOR_ACCELEROMETER_ENABLE, EVENT_RATE)
|
||||||
rotationEnabled = true;
|
&& sensorStateCallback(0, RETRO_SENSOR_GYROSCOPE_ENABLE, EVENT_RATE)) {
|
||||||
}
|
rotationEnabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
if(sensorStateCallback(0, RETRO_SENSOR_ILLUMINANCE_ENABLE, EVENT_RATE)) {
|
if (sensorStateCallback(0, RETRO_SENSOR_ILLUMINANCE_ENABLE, EVENT_RATE)) {
|
||||||
luxSensorEnabled = true;
|
luxSensorEnabled = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,6 +319,7 @@ void retro_init(void) {
|
||||||
sensorStateCallback = 0;
|
sensorStateCallback = 0;
|
||||||
|
|
||||||
rotationEnabled = false;
|
rotationEnabled = false;
|
||||||
|
rotation.sample = _updateRotation;
|
||||||
rotation.readTiltX = _readTiltX;
|
rotation.readTiltX = _readTiltX;
|
||||||
rotation.readTiltY = _readTiltY;
|
rotation.readTiltY = _readTiltY;
|
||||||
rotation.readGyroZ = _readGyroZ;
|
rotation.readGyroZ = _readGyroZ;
|
||||||
|
@ -345,14 +355,17 @@ void retro_init(void) {
|
||||||
void retro_deinit(void) {
|
void retro_deinit(void) {
|
||||||
free(outputBuffer);
|
free(outputBuffer);
|
||||||
|
|
||||||
if(sensorStateCallback) {
|
if (sensorStateCallback) {
|
||||||
sensorStateCallback(0, RETRO_SENSOR_ACCELEROMETER_DISABLE, EVENT_RATE);
|
sensorStateCallback(0, RETRO_SENSOR_ACCELEROMETER_DISABLE, EVENT_RATE);
|
||||||
sensorStateCallback(0, RETRO_SENSOR_GYROSCOPE_DISABLE, EVENT_RATE);
|
sensorStateCallback(0, RETRO_SENSOR_GYROSCOPE_DISABLE, EVENT_RATE);
|
||||||
sensorStateCallback(0, RETRO_SENSOR_ILLUMINANCE_DISABLE, EVENT_RATE);
|
sensorStateCallback(0, RETRO_SENSOR_ILLUMINANCE_DISABLE, EVENT_RATE);
|
||||||
|
sensorGetCallback = NULL;
|
||||||
|
sensorStateCallback = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
rotationEnabled = false;
|
rotationEnabled = false;
|
||||||
luxSensorEnabled = false;
|
luxSensorEnabled = false;
|
||||||
|
sensorsInitDone = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void retro_run(void) {
|
void retro_run(void) {
|
||||||
|
@ -398,7 +411,7 @@ void retro_run(void) {
|
||||||
keys |= (!!inputCallback(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L)) << 9;
|
keys |= (!!inputCallback(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L)) << 9;
|
||||||
core->setKeys(core, keys);
|
core->setKeys(core, keys);
|
||||||
|
|
||||||
if(!luxSensorUsed) {
|
if (!luxSensorUsed) {
|
||||||
static bool wasAdjustingLux = false;
|
static bool wasAdjustingLux = false;
|
||||||
if (wasAdjustingLux) {
|
if (wasAdjustingLux) {
|
||||||
wasAdjustingLux = inputCallback(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3) ||
|
wasAdjustingLux = inputCallback(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3) ||
|
||||||
|
@ -1005,15 +1018,15 @@ static void _updateLux(struct GBALuminanceSource* lux) {
|
||||||
luxVarUpdated = false;
|
luxVarUpdated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(luxVarUpdated) {
|
if (luxVarUpdated) {
|
||||||
luxSensorUsed = strcmp(var.value, "sensor") == 0;
|
luxSensorUsed = strcmp(var.value, "sensor") == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(luxSensorUsed) {
|
if (luxSensorUsed) {
|
||||||
float fLux = luxSensorEnabled ? sensorGetCallback(0, RETRO_SENSOR_ILLUMINANCE) : 0.0f;
|
float fLux = luxSensorEnabled ? sensorGetCallback(0, RETRO_SENSOR_ILLUMINANCE) : 0.0f;
|
||||||
luxLevel = cbrtf(fLux) * 8;
|
luxLevel = cbrtf(fLux) * 8;
|
||||||
} else {
|
} else {
|
||||||
if(luxVarUpdated) {
|
if (luxVarUpdated) {
|
||||||
char* end;
|
char* end;
|
||||||
int newLuxLevelIndex = strtol(var.value, &end, 10);
|
int newLuxLevelIndex = strtol(var.value, &end, 10);
|
||||||
|
|
||||||
|
@ -1106,35 +1119,29 @@ static void _requestImage(struct mImageSource* image, const void** buffer, size_
|
||||||
*colorFormat = mCOLOR_XRGB8;
|
*colorFormat = mCOLOR_XRGB8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _updateRotation(struct mRotationSource* source) {
|
||||||
|
UNUSED(source);
|
||||||
|
tiltX = 0;
|
||||||
|
tiltY = 0;
|
||||||
|
gyroZ = 0;
|
||||||
|
if (rotationEnabled) {
|
||||||
|
tiltX = sensorGetCallback(0, RETRO_SENSOR_ACCELEROMETER_X) * 3e8f;
|
||||||
|
tiltY = sensorGetCallback(0, RETRO_SENSOR_ACCELEROMETER_Y) * -3e8f;
|
||||||
|
gyroZ = sensorGetCallback(0, RETRO_SENSOR_GYROSCOPE_Z) * -1.1e9f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t _readTiltX(struct mRotationSource* source) {
|
static int32_t _readTiltX(struct mRotationSource* source) {
|
||||||
UNUSED(source);
|
UNUSED(source);
|
||||||
int32_t tiltX = 0;
|
|
||||||
|
|
||||||
if(rotationEnabled) {
|
|
||||||
tiltX = sensorGetCallback(0, RETRO_SENSOR_ACCELEROMETER_X) * 3e8f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return tiltX;
|
return tiltX;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t _readTiltY(struct mRotationSource* source) {
|
static int32_t _readTiltY(struct mRotationSource* source) {
|
||||||
UNUSED(source);
|
UNUSED(source);
|
||||||
int32_t tiltY = 0;
|
|
||||||
|
|
||||||
if(rotationEnabled) {
|
|
||||||
tiltY = sensorGetCallback(0, RETRO_SENSOR_ACCELEROMETER_Y) * -3e8f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return tiltY;
|
return tiltY;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t _readGyroZ(struct mRotationSource* source) {
|
static int32_t _readGyroZ(struct mRotationSource* source) {
|
||||||
UNUSED(source);
|
UNUSED(source);
|
||||||
int32_t gyroZ = 0;
|
|
||||||
|
|
||||||
if(rotationEnabled) {
|
|
||||||
gyroZ = sensorGetCallback(0, RETRO_SENSOR_GYROSCOPE_Z) * -1.1e9f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return gyroZ;
|
return gyroZ;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright (C) 2010-2018 The RetroArch team
|
/* Copyright (C) 2010-2020 The RetroArch team
|
||||||
*
|
*
|
||||||
* ---------------------------------------------------------------------------------------
|
* ---------------------------------------------------------------------------------------
|
||||||
* The following license statement only applies to this libretro API header (libretro.h).
|
* The following license statement only applies to this libretro API header (libretro.h).
|
||||||
|
@ -278,6 +278,10 @@ enum retro_language
|
||||||
RETRO_LANGUAGE_ARABIC = 16,
|
RETRO_LANGUAGE_ARABIC = 16,
|
||||||
RETRO_LANGUAGE_GREEK = 17,
|
RETRO_LANGUAGE_GREEK = 17,
|
||||||
RETRO_LANGUAGE_TURKISH = 18,
|
RETRO_LANGUAGE_TURKISH = 18,
|
||||||
|
RETRO_LANGUAGE_SLOVAK = 19,
|
||||||
|
RETRO_LANGUAGE_PERSIAN = 20,
|
||||||
|
RETRO_LANGUAGE_HEBREW = 21,
|
||||||
|
RETRO_LANGUAGE_ASTURIAN = 22,
|
||||||
RETRO_LANGUAGE_LAST,
|
RETRO_LANGUAGE_LAST,
|
||||||
|
|
||||||
/* Ensure sizeof(enum) == sizeof(int) */
|
/* Ensure sizeof(enum) == sizeof(int) */
|
||||||
|
@ -1246,6 +1250,130 @@ enum retro_mod
|
||||||
* default when calling SET_VARIABLES/SET_CORE_OPTIONS.
|
* default when calling SET_VARIABLES/SET_CORE_OPTIONS.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define RETRO_ENVIRONMENT_GET_PREFERRED_HW_RENDER 56
|
||||||
|
/* unsigned * --
|
||||||
|
*
|
||||||
|
* Allows an implementation to ask frontend preferred hardware
|
||||||
|
* context to use. Core should use this information to deal
|
||||||
|
* with what specific context to request with SET_HW_RENDER.
|
||||||
|
*
|
||||||
|
* 'data' points to an unsigned variable
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define RETRO_ENVIRONMENT_GET_DISK_CONTROL_INTERFACE_VERSION 57
|
||||||
|
/* unsigned * --
|
||||||
|
* Unsigned value is the API version number of the disk control
|
||||||
|
* interface supported by the frontend. If callback return false,
|
||||||
|
* API version is assumed to be 0.
|
||||||
|
*
|
||||||
|
* In legacy code, the disk control interface is defined by passing
|
||||||
|
* a struct of type retro_disk_control_callback to
|
||||||
|
* RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE.
|
||||||
|
* This may be still be done regardless of the disk control
|
||||||
|
* interface version.
|
||||||
|
*
|
||||||
|
* If version is >= 1 however, the disk control interface may
|
||||||
|
* instead be defined by passing a struct of type
|
||||||
|
* retro_disk_control_ext_callback to
|
||||||
|
* RETRO_ENVIRONMENT_SET_DISK_CONTROL_EXT_INTERFACE.
|
||||||
|
* This allows the core to provide additional information about
|
||||||
|
* disk images to the frontend and/or enables extra
|
||||||
|
* disk control functionality by the frontend.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define RETRO_ENVIRONMENT_SET_DISK_CONTROL_EXT_INTERFACE 58
|
||||||
|
/* const struct retro_disk_control_ext_callback * --
|
||||||
|
* Sets an interface which frontend can use to eject and insert
|
||||||
|
* disk images, and also obtain information about individual
|
||||||
|
* disk image files registered by the core.
|
||||||
|
* This is used for games which consist of multiple images and
|
||||||
|
* must be manually swapped out by the user (e.g. PSX, floppy disk
|
||||||
|
* based systems).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define RETRO_ENVIRONMENT_GET_MESSAGE_INTERFACE_VERSION 59
|
||||||
|
/* unsigned * --
|
||||||
|
* Unsigned value is the API version number of the message
|
||||||
|
* interface supported by the frontend. If callback returns
|
||||||
|
* false, API version is assumed to be 0.
|
||||||
|
*
|
||||||
|
* In legacy code, messages may be displayed in an
|
||||||
|
* implementation-specific manner by passing a struct
|
||||||
|
* of type retro_message to RETRO_ENVIRONMENT_SET_MESSAGE.
|
||||||
|
* This may be still be done regardless of the message
|
||||||
|
* interface version.
|
||||||
|
*
|
||||||
|
* If version is >= 1 however, messages may instead be
|
||||||
|
* displayed by passing a struct of type retro_message_ext
|
||||||
|
* to RETRO_ENVIRONMENT_SET_MESSAGE_EXT. This allows the
|
||||||
|
* core to specify message logging level, priority and
|
||||||
|
* destination (OSD, logging interface or both).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define RETRO_ENVIRONMENT_SET_MESSAGE_EXT 60
|
||||||
|
/* const struct retro_message_ext * --
|
||||||
|
* Sets a message to be displayed in an implementation-specific
|
||||||
|
* manner for a certain amount of 'frames'. Additionally allows
|
||||||
|
* the core to specify message logging level, priority and
|
||||||
|
* destination (OSD, logging interface or both).
|
||||||
|
* Should not be used for trivial messages, which should simply be
|
||||||
|
* logged via RETRO_ENVIRONMENT_GET_LOG_INTERFACE (or as a
|
||||||
|
* fallback, stderr).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define RETRO_ENVIRONMENT_GET_INPUT_MAX_USERS 61
|
||||||
|
/* unsigned * --
|
||||||
|
* Unsigned value is the number of active input devices
|
||||||
|
* provided by the frontend. This may change between
|
||||||
|
* frames, but will remain constant for the duration
|
||||||
|
* of each frame.
|
||||||
|
* If callback returns true, a core need not poll any
|
||||||
|
* input device with an index greater than or equal to
|
||||||
|
* the number of active devices.
|
||||||
|
* If callback returns false, the number of active input
|
||||||
|
* devices is unknown. In this case, all input devices
|
||||||
|
* should be considered active.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define RETRO_ENVIRONMENT_SET_AUDIO_BUFFER_STATUS_CALLBACK 62
|
||||||
|
/* const struct retro_audio_buffer_status_callback * --
|
||||||
|
* Lets the core know the occupancy level of the frontend
|
||||||
|
* audio buffer. Can be used by a core to attempt frame
|
||||||
|
* skipping in order to avoid buffer under-runs.
|
||||||
|
* A core may pass NULL to disable buffer status reporting
|
||||||
|
* in the frontend.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define RETRO_ENVIRONMENT_SET_MINIMUM_AUDIO_LATENCY 63
|
||||||
|
/* const unsigned * --
|
||||||
|
* Sets minimum frontend audio latency in milliseconds.
|
||||||
|
* Resultant audio latency may be larger than set value,
|
||||||
|
* or smaller if a hardware limit is encountered. A frontend
|
||||||
|
* is expected to honour requests up to 512 ms.
|
||||||
|
*
|
||||||
|
* - If value is less than current frontend
|
||||||
|
* audio latency, callback has no effect
|
||||||
|
* - If value is zero, default frontend audio
|
||||||
|
* latency is set
|
||||||
|
*
|
||||||
|
* May be used by a core to increase audio latency and
|
||||||
|
* therefore decrease the probability of buffer under-runs
|
||||||
|
* (crackling) when performing 'intensive' operations.
|
||||||
|
* A core utilising RETRO_ENVIRONMENT_SET_AUDIO_BUFFER_STATUS_CALLBACK
|
||||||
|
* to implement audio-buffer-based frame skipping may achieve
|
||||||
|
* optimal results by setting the audio latency to a 'high'
|
||||||
|
* (typically 6x or 8x) integer multiple of the expected
|
||||||
|
* frame time.
|
||||||
|
*
|
||||||
|
* WARNING: This can only be called from within retro_run().
|
||||||
|
* Calling this can require a full reinitialization of audio
|
||||||
|
* drivers in the frontend, so it is important to call it very
|
||||||
|
* sparingly, and usually only with the users explicit consent.
|
||||||
|
* An eventual driver reinitialize will happen so that audio
|
||||||
|
* callbacks happening after this call within the same retro_run()
|
||||||
|
* call will target the newly initialized driver.
|
||||||
|
*/
|
||||||
|
|
||||||
/* VFS functionality */
|
/* VFS functionality */
|
||||||
|
|
||||||
/* File paths:
|
/* File paths:
|
||||||
|
@ -1922,6 +2050,10 @@ enum retro_sensor_action
|
||||||
{
|
{
|
||||||
RETRO_SENSOR_ACCELEROMETER_ENABLE = 0,
|
RETRO_SENSOR_ACCELEROMETER_ENABLE = 0,
|
||||||
RETRO_SENSOR_ACCELEROMETER_DISABLE,
|
RETRO_SENSOR_ACCELEROMETER_DISABLE,
|
||||||
|
RETRO_SENSOR_GYROSCOPE_ENABLE,
|
||||||
|
RETRO_SENSOR_GYROSCOPE_DISABLE,
|
||||||
|
RETRO_SENSOR_ILLUMINANCE_ENABLE,
|
||||||
|
RETRO_SENSOR_ILLUMINANCE_DISABLE,
|
||||||
|
|
||||||
RETRO_SENSOR_DUMMY = INT_MAX
|
RETRO_SENSOR_DUMMY = INT_MAX
|
||||||
};
|
};
|
||||||
|
@ -1930,6 +2062,10 @@ enum retro_sensor_action
|
||||||
#define RETRO_SENSOR_ACCELEROMETER_X 0
|
#define RETRO_SENSOR_ACCELEROMETER_X 0
|
||||||
#define RETRO_SENSOR_ACCELEROMETER_Y 1
|
#define RETRO_SENSOR_ACCELEROMETER_Y 1
|
||||||
#define RETRO_SENSOR_ACCELEROMETER_Z 2
|
#define RETRO_SENSOR_ACCELEROMETER_Z 2
|
||||||
|
#define RETRO_SENSOR_GYROSCOPE_X 3
|
||||||
|
#define RETRO_SENSOR_GYROSCOPE_Y 4
|
||||||
|
#define RETRO_SENSOR_GYROSCOPE_Z 5
|
||||||
|
#define RETRO_SENSOR_ILLUMINANCE 6
|
||||||
|
|
||||||
typedef bool (RETRO_CALLCONV *retro_set_sensor_state_t)(unsigned port,
|
typedef bool (RETRO_CALLCONV *retro_set_sensor_state_t)(unsigned port,
|
||||||
enum retro_sensor_action action, unsigned rate);
|
enum retro_sensor_action action, unsigned rate);
|
||||||
|
@ -2127,6 +2263,30 @@ struct retro_frame_time_callback
|
||||||
retro_usec_t reference;
|
retro_usec_t reference;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Notifies a libretro core of the current occupancy
|
||||||
|
* level of the frontend audio buffer.
|
||||||
|
*
|
||||||
|
* - active: 'true' if audio buffer is currently
|
||||||
|
* in use. Will be 'false' if audio is
|
||||||
|
* disabled in the frontend
|
||||||
|
*
|
||||||
|
* - occupancy: Given as a value in the range [0,100],
|
||||||
|
* corresponding to the occupancy percentage
|
||||||
|
* of the audio buffer
|
||||||
|
*
|
||||||
|
* - underrun_likely: 'true' if the frontend expects an
|
||||||
|
* audio buffer underrun during the
|
||||||
|
* next frame (indicates that a core
|
||||||
|
* should attempt frame skipping)
|
||||||
|
*
|
||||||
|
* It will be called right before retro_run() every frame. */
|
||||||
|
typedef void (RETRO_CALLCONV *retro_audio_buffer_status_callback_t)(
|
||||||
|
bool active, unsigned occupancy, bool underrun_likely);
|
||||||
|
struct retro_audio_buffer_status_callback
|
||||||
|
{
|
||||||
|
retro_audio_buffer_status_callback_t callback;
|
||||||
|
};
|
||||||
|
|
||||||
/* Pass this to retro_video_refresh_t if rendering to hardware.
|
/* Pass this to retro_video_refresh_t if rendering to hardware.
|
||||||
* Passing NULL to retro_video_refresh_t is still a frame dupe as normal.
|
* Passing NULL to retro_video_refresh_t is still a frame dupe as normal.
|
||||||
* */
|
* */
|
||||||
|
@ -2287,7 +2447,8 @@ struct retro_keyboard_callback
|
||||||
retro_keyboard_event_t callback;
|
retro_keyboard_event_t callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Callbacks for RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE.
|
/* Callbacks for RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE &
|
||||||
|
* RETRO_ENVIRONMENT_SET_DISK_CONTROL_EXT_INTERFACE.
|
||||||
* Should be set for implementations which can swap out multiple disk
|
* Should be set for implementations which can swap out multiple disk
|
||||||
* images in runtime.
|
* images in runtime.
|
||||||
*
|
*
|
||||||
|
@ -2345,6 +2506,53 @@ typedef bool (RETRO_CALLCONV *retro_replace_image_index_t)(unsigned index,
|
||||||
* with replace_image_index. */
|
* with replace_image_index. */
|
||||||
typedef bool (RETRO_CALLCONV *retro_add_image_index_t)(void);
|
typedef bool (RETRO_CALLCONV *retro_add_image_index_t)(void);
|
||||||
|
|
||||||
|
/* Sets initial image to insert in drive when calling
|
||||||
|
* core_load_game().
|
||||||
|
* Since we cannot pass the initial index when loading
|
||||||
|
* content (this would require a major API change), this
|
||||||
|
* is set by the frontend *before* calling the core's
|
||||||
|
* retro_load_game()/retro_load_game_special() implementation.
|
||||||
|
* A core should therefore cache the index/path values and handle
|
||||||
|
* them inside retro_load_game()/retro_load_game_special().
|
||||||
|
* - If 'index' is invalid (index >= get_num_images()), the
|
||||||
|
* core should ignore the set value and instead use 0
|
||||||
|
* - 'path' is used purely for error checking - i.e. when
|
||||||
|
* content is loaded, the core should verify that the
|
||||||
|
* disk specified by 'index' has the specified file path.
|
||||||
|
* This is to guard against auto selecting the wrong image
|
||||||
|
* if (for example) the user should modify an existing M3U
|
||||||
|
* playlist. We have to let the core handle this because
|
||||||
|
* set_initial_image() must be called before loading content,
|
||||||
|
* i.e. the frontend cannot access image paths in advance
|
||||||
|
* and thus cannot perform the error check itself.
|
||||||
|
* If set path and content path do not match, the core should
|
||||||
|
* ignore the set 'index' value and instead use 0
|
||||||
|
* Returns 'false' if index or 'path' are invalid, or core
|
||||||
|
* does not support this functionality
|
||||||
|
*/
|
||||||
|
typedef bool (RETRO_CALLCONV *retro_set_initial_image_t)(unsigned index, const char *path);
|
||||||
|
|
||||||
|
/* Fetches the path of the specified disk image file.
|
||||||
|
* Returns 'false' if index is invalid (index >= get_num_images())
|
||||||
|
* or path is otherwise unavailable.
|
||||||
|
*/
|
||||||
|
typedef bool (RETRO_CALLCONV *retro_get_image_path_t)(unsigned index, char *path, size_t len);
|
||||||
|
|
||||||
|
/* Fetches a core-provided 'label' for the specified disk
|
||||||
|
* image file. In the simplest case this may be a file name
|
||||||
|
* (without extension), but for cores with more complex
|
||||||
|
* content requirements information may be provided to
|
||||||
|
* facilitate user disk swapping - for example, a core
|
||||||
|
* running floppy-disk-based content may uniquely label
|
||||||
|
* save disks, data disks, level disks, etc. with names
|
||||||
|
* corresponding to in-game disk change prompts (so the
|
||||||
|
* frontend can provide better user guidance than a 'dumb'
|
||||||
|
* disk index value).
|
||||||
|
* Returns 'false' if index is invalid (index >= get_num_images())
|
||||||
|
* or label is otherwise unavailable.
|
||||||
|
*/
|
||||||
|
typedef bool (RETRO_CALLCONV *retro_get_image_label_t)(unsigned index, char *label, size_t len);
|
||||||
|
|
||||||
struct retro_disk_control_callback
|
struct retro_disk_control_callback
|
||||||
{
|
{
|
||||||
retro_set_eject_state_t set_eject_state;
|
retro_set_eject_state_t set_eject_state;
|
||||||
|
@ -2358,6 +2566,27 @@ struct retro_disk_control_callback
|
||||||
retro_add_image_index_t add_image_index;
|
retro_add_image_index_t add_image_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct retro_disk_control_ext_callback
|
||||||
|
{
|
||||||
|
retro_set_eject_state_t set_eject_state;
|
||||||
|
retro_get_eject_state_t get_eject_state;
|
||||||
|
|
||||||
|
retro_get_image_index_t get_image_index;
|
||||||
|
retro_set_image_index_t set_image_index;
|
||||||
|
retro_get_num_images_t get_num_images;
|
||||||
|
|
||||||
|
retro_replace_image_index_t replace_image_index;
|
||||||
|
retro_add_image_index_t add_image_index;
|
||||||
|
|
||||||
|
/* NOTE: Frontend will only attempt to record/restore
|
||||||
|
* last used disk index if both set_initial_image()
|
||||||
|
* and get_image_path() are implemented */
|
||||||
|
retro_set_initial_image_t set_initial_image; /* Optional - may be NULL */
|
||||||
|
|
||||||
|
retro_get_image_path_t get_image_path; /* Optional - may be NULL */
|
||||||
|
retro_get_image_label_t get_image_label; /* Optional - may be NULL */
|
||||||
|
};
|
||||||
|
|
||||||
enum retro_pixel_format
|
enum retro_pixel_format
|
||||||
{
|
{
|
||||||
/* 0RGB1555, native endian.
|
/* 0RGB1555, native endian.
|
||||||
|
@ -2388,6 +2617,104 @@ struct retro_message
|
||||||
unsigned frames; /* Duration in frames of message. */
|
unsigned frames; /* Duration in frames of message. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum retro_message_target
|
||||||
|
{
|
||||||
|
RETRO_MESSAGE_TARGET_ALL = 0,
|
||||||
|
RETRO_MESSAGE_TARGET_OSD,
|
||||||
|
RETRO_MESSAGE_TARGET_LOG
|
||||||
|
};
|
||||||
|
|
||||||
|
enum retro_message_type
|
||||||
|
{
|
||||||
|
RETRO_MESSAGE_TYPE_NOTIFICATION = 0,
|
||||||
|
RETRO_MESSAGE_TYPE_NOTIFICATION_ALT,
|
||||||
|
RETRO_MESSAGE_TYPE_STATUS,
|
||||||
|
RETRO_MESSAGE_TYPE_PROGRESS
|
||||||
|
};
|
||||||
|
|
||||||
|
struct retro_message_ext
|
||||||
|
{
|
||||||
|
/* Message string to be displayed/logged */
|
||||||
|
const char *msg;
|
||||||
|
/* Duration (in ms) of message when targeting the OSD */
|
||||||
|
unsigned duration;
|
||||||
|
/* Message priority when targeting the OSD
|
||||||
|
* > When multiple concurrent messages are sent to
|
||||||
|
* the frontend and the frontend does not have the
|
||||||
|
* capacity to display them all, messages with the
|
||||||
|
* *highest* priority value should be shown
|
||||||
|
* > There is no upper limit to a message priority
|
||||||
|
* value (within the bounds of the unsigned data type)
|
||||||
|
* > In the reference frontend (RetroArch), the same
|
||||||
|
* priority values are used for frontend-generated
|
||||||
|
* notifications, which are typically assigned values
|
||||||
|
* between 0 and 3 depending upon importance */
|
||||||
|
unsigned priority;
|
||||||
|
/* Message logging level (info, warn, error, etc.) */
|
||||||
|
enum retro_log_level level;
|
||||||
|
/* Message destination: OSD, logging interface or both */
|
||||||
|
enum retro_message_target target;
|
||||||
|
/* Message 'type' when targeting the OSD
|
||||||
|
* > RETRO_MESSAGE_TYPE_NOTIFICATION: Specifies that a
|
||||||
|
* message should be handled in identical fashion to
|
||||||
|
* a standard frontend-generated notification
|
||||||
|
* > RETRO_MESSAGE_TYPE_NOTIFICATION_ALT: Specifies that
|
||||||
|
* message is a notification that requires user attention
|
||||||
|
* or action, but that it should be displayed in a manner
|
||||||
|
* that differs from standard frontend-generated notifications.
|
||||||
|
* This would typically correspond to messages that should be
|
||||||
|
* displayed immediately (independently from any internal
|
||||||
|
* frontend message queue), and/or which should be visually
|
||||||
|
* distinguishable from frontend-generated notifications.
|
||||||
|
* For example, a core may wish to inform the user of
|
||||||
|
* information related to a disk-change event. It is
|
||||||
|
* expected that the frontend itself may provide a
|
||||||
|
* notification in this case; if the core sends a
|
||||||
|
* message of type RETRO_MESSAGE_TYPE_NOTIFICATION, an
|
||||||
|
* uncomfortable 'double-notification' may occur. A message
|
||||||
|
* of RETRO_MESSAGE_TYPE_NOTIFICATION_ALT should therefore
|
||||||
|
* be presented such that visual conflict with regular
|
||||||
|
* notifications does not occur
|
||||||
|
* > RETRO_MESSAGE_TYPE_STATUS: Indicates that message
|
||||||
|
* is not a standard notification. This typically
|
||||||
|
* corresponds to 'status' indicators, such as a core's
|
||||||
|
* internal FPS, which are intended to be displayed
|
||||||
|
* either permanently while a core is running, or in
|
||||||
|
* a manner that does not suggest user attention or action
|
||||||
|
* is required. 'Status' type messages should therefore be
|
||||||
|
* displayed in a different on-screen location and in a manner
|
||||||
|
* easily distinguishable from both standard frontend-generated
|
||||||
|
* notifications and messages of type RETRO_MESSAGE_TYPE_NOTIFICATION_ALT
|
||||||
|
* > RETRO_MESSAGE_TYPE_PROGRESS: Indicates that message reports
|
||||||
|
* the progress of an internal core task. For example, in cases
|
||||||
|
* where a core itself handles the loading of content from a file,
|
||||||
|
* this may correspond to the percentage of the file that has been
|
||||||
|
* read. Alternatively, an audio/video playback core may use a
|
||||||
|
* message of type RETRO_MESSAGE_TYPE_PROGRESS to display the current
|
||||||
|
* playback position as a percentage of the runtime. 'Progress' type
|
||||||
|
* messages should therefore be displayed as a literal progress bar,
|
||||||
|
* where:
|
||||||
|
* - 'retro_message_ext.msg' is the progress bar title/label
|
||||||
|
* - 'retro_message_ext.progress' determines the length of
|
||||||
|
* the progress bar
|
||||||
|
* NOTE: Message type is a *hint*, and may be ignored
|
||||||
|
* by the frontend. If a frontend lacks support for
|
||||||
|
* displaying messages via alternate means than standard
|
||||||
|
* frontend-generated notifications, it will treat *all*
|
||||||
|
* messages as having the type RETRO_MESSAGE_TYPE_NOTIFICATION */
|
||||||
|
enum retro_message_type type;
|
||||||
|
/* Task progress when targeting the OSD and message is
|
||||||
|
* of type RETRO_MESSAGE_TYPE_PROGRESS
|
||||||
|
* > -1: Unmetered/indeterminate
|
||||||
|
* > 0-100: Current progress percentage
|
||||||
|
* NOTE: Since message type is a hint, a frontend may ignore
|
||||||
|
* progress values. Where relevant, a core should therefore
|
||||||
|
* include progress percentage within the message string,
|
||||||
|
* such that the message intent remains clear when displayed
|
||||||
|
* as a standard frontend-generated notification */
|
||||||
|
int8_t progress;
|
||||||
|
};
|
||||||
|
|
||||||
/* Describes how the libretro implementation maps a libretro input bind
|
/* Describes how the libretro implementation maps a libretro input bind
|
||||||
* to its internal input system through a human readable string.
|
* to its internal input system through a human readable string.
|
||||||
* This string can be used to better let a user configure input. */
|
* This string can be used to better let a user configure input. */
|
||||||
|
@ -2408,7 +2735,7 @@ struct retro_input_descriptor
|
||||||
struct retro_system_info
|
struct retro_system_info
|
||||||
{
|
{
|
||||||
/* All pointers are owned by libretro implementation, and pointers must
|
/* All pointers are owned by libretro implementation, and pointers must
|
||||||
* remain valid until retro_deinit() is called. */
|
* remain valid until it is unloaded. */
|
||||||
|
|
||||||
const char *library_name; /* Descriptive name of library. Should not
|
const char *library_name; /* Descriptive name of library. Should not
|
||||||
* contain any version numbers, etc. */
|
* contain any version numbers, etc. */
|
||||||
|
|
Loading…
Reference in New Issue