[libretro]

- fixed framebuffer size for PAL interlaced mode
- added support for in-game resolution changes through RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO
This commit is contained in:
EkeEke 2014-03-02 17:51:00 +01:00
parent 9352c3414f
commit 7dbeddece1
2 changed files with 204 additions and 26 deletions

View File

@ -53,7 +53,7 @@ static uint8_t brm_format[0x40] =
static uint8_t temp[0x10000];
static int16 soundbuffer[3068];
static uint16_t bitmap_data_[1024 * 512];
static uint16_t bitmap_data_[720 * 576];
static const double pal_fps = 53203424.0 / (3420.0 * 313.0);
static const double ntsc_fps = 53693175.0 / (3420.0 * 262.0);
@ -210,14 +210,10 @@ void osd_input_update(void)
static void init_bitmap(void)
{
memset(&bitmap, 0, sizeof(bitmap));
bitmap.width = 1024;
bitmap.height = 512;
bitmap.pitch = 1024 * 2;
bitmap.width = 720;
bitmap.height = 576;
bitmap.pitch = 720 * 2;
bitmap.data = (uint8_t *)bitmap_data_;
bitmap.viewport.w = 0;
bitmap.viewport.h = 0;
bitmap.viewport.x = 0;
bitmap.viewport.y = 0;
}
static void config_default(void)
@ -474,6 +470,8 @@ static void check_variables(void)
orig_value = config.system;
if (!strcmp(var.value, "sg-1000"))
config.system = SYSTEM_SG;
else if (!strcmp(var.value, "sg-1000 II"))
config.system = SYSTEM_SGII;
else if (!strcmp(var.value, "mark-III"))
config.system = SYSTEM_MARKIII;
else if (!strcmp(var.value, "master system"))
@ -760,7 +758,7 @@ unsigned retro_api_version(void) { return RETRO_API_VERSION; }
void retro_set_environment(retro_environment_t cb)
{
static const struct retro_variable vars[] = {
{ "system_hw", "System hardware; auto|sg-1000|mark-III|master system|master system II|game gear|mega drive / genesis" },
{ "system_hw", "System hardware; auto|sg-1000|sg-1000 II|mark-III|master system|master system II|game gear|mega drive / genesis" },
{ "region_detect", "System region; auto|ntsc-u|pal|ntsc-j" },
{ "force_dtack", "System lockups; enabled|disabled" },
{ "addr_error", "68k address error; enabled|disabled" },
@ -773,7 +771,7 @@ void retro_set_environment(retro_environment_t cb)
{ "blargg_ntsc_filter", "Blargg NTSC filter; disabled|monochrome|composite|svideo|rgb" },
{ "overscan", "Borders; disabled|top/bottom|left/right|full" },
{ "gg_extra", "Game Gear extended screen; disabled|enabled" },
{ "render", "Interlaced mode resolution; normal|double" },
{ "render", "Interlaced mode 2 output; single field|double field" },
{ NULL, NULL },
};
@ -800,8 +798,8 @@ void retro_get_system_av_info(struct retro_system_av_info *info)
{
info->geometry.base_width = vwidth;
info->geometry.base_height = vheight;
info->geometry.max_width = 1024;
info->geometry.max_height = 512;
info->geometry.max_width = 720;
info->geometry.max_height = 576;
info->geometry.aspect_ratio = 4.0 / 3.0;
info->timing.fps = snd.frame_rate;
info->timing.sample_rate = 44100;
@ -1000,11 +998,14 @@ void retro_run(void)
if (bitmap.viewport.changed & 1)
{
struct retro_system_av_info info;
bitmap.viewport.changed &= ~1;
update_viewport();
retro_get_system_av_info(&info);
environ_cb(RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO, &info);
}
video_cb(bitmap.data, vwidth, vheight, 1024 * 2);
video_cb(bitmap.data, vwidth, vheight, 720 * 2);
audio_cb(soundbuffer, audio_update(soundbuffer));
environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated);

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2010-2013 The RetroArch team
/* Copyright (C) 2010-2014 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this libretro API header (libretro.h).
@ -27,11 +27,13 @@
#include <stddef.h>
#include <limits.h>
// Hack applied for MSVC when compiling in C89 mode as it isn't C99 compliant.
#ifdef __cplusplus
extern "C" {
#else
#if defined(_MSC_VER) && !defined(SN_TARGET_PS3) && !defined(__cplusplus)
#endif
#ifndef __cplusplus
#if defined(_MSC_VER) && !defined(SN_TARGET_PS3)
/* Hack applied for MSVC when compiling in C89 mode as it isn't C99 compliant. */
#define bool unsigned char
#define true 1
#define false 0
@ -94,9 +96,6 @@ extern "C" {
// Eventually _PRESSED will return false for an index. No further presses are registered at this point.
#define RETRO_DEVICE_POINTER 6
// FIXME: Document this.
#define RETRO_DEVICE_SENSOR_ACCELEROMETER 7
// These device types are specializations of the base types above.
// They should only be used in retro_set_controller_type() to inform libretro implementations
// about use of a very specific device type.
@ -153,11 +152,6 @@ extern "C" {
#define RETRO_DEVICE_ID_POINTER_Y 1
#define RETRO_DEVICE_ID_POINTER_PRESSED 2
// Id values for SENSOR types.
#define RETRO_DEVICE_ID_SENSOR_ACCELEROMETER_X 0
#define RETRO_DEVICE_ID_SENSOR_ACCELEROMETER_Y 1
#define RETRO_DEVICE_ID_SENSOR_ACCELEROMETER_Z 2
// Returned from retro_get_region().
#define RETRO_REGION_NTSC 0
#define RETRO_REGION_PAL 1
@ -385,7 +379,7 @@ enum retro_mod
// Environ 4, 5 are no longer supported (GET_VARIABLE / SET_VARIABLES), and reserved to avoid possible ABI clash.
#define RETRO_ENVIRONMENT_SET_MESSAGE 6 // const struct retro_message * --
// Sets a message to be displayed in implementation-specific manner for a certain amount of 'frames'.
// Should not be used for trivial messages, which should simply be logged to stderr.
// 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_SHUTDOWN 7 // N/A (NULL) --
// Requests the frontend to shutdown.
// Should only be used if game has a specific
@ -421,6 +415,9 @@ enum retro_mod
// If so, no such directory is defined,
// and it's up to the implementation to find a suitable directory.
//
// NOTE: Some cores used this folder also for "save" data such as memory cards, etc, for lack of a better place to put it.
// This is now discouraged, and if possible, cores should try to use the new GET_SAVE_DIRECTORY.
//
#define RETRO_ENVIRONMENT_SET_PIXEL_FORMAT 10
// const enum retro_pixel_format * --
// Sets the internal pixel format used by the implementation.
@ -564,6 +561,52 @@ enum retro_mod
// as certain platforms cannot use use stderr for logging. It also allows the frontend to
// show logging information in a more suitable way.
// If this interface is not used, libretro cores should log to stderr as desired.
#define RETRO_ENVIRONMENT_GET_PERF_INTERFACE 28
// struct retro_perf_callback * --
// Gets an interface for performance counters. This is useful for performance logging in a
// cross-platform way and for detecting architecture-specific features, such as SIMD support.
#define RETRO_ENVIRONMENT_GET_LOCATION_INTERFACE 29
// struct retro_location_callback * --
// Gets access to the location interface.
// The purpose of this interface is to be able to retrieve location-based information from the host device,
// such as current latitude / longitude.
//
#define RETRO_ENVIRONMENT_GET_CONTENT_DIRECTORY 30
// const char ** --
// Returns the "content" directory of the frontend.
// This directory can be used to store specific assets that the core relies upon, such as art assets,
// input data, etc etc.
// The returned value can be NULL.
// If so, no such directory is defined,
// and it's up to the implementation to find a suitable directory.
//
#define RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY 31
// const char ** --
// Returns the "save" directory of the frontend.
// This directory can be used to store SRAM, memory cards, high scores, etc, if the libretro core
// cannot use the regular memory interface (retro_get_memory_data()).
//
// NOTE: libretro cores used to check GET_SYSTEM_DIRECTORY for similar things before.
// They should still check GET_SYSTEM_DIRECTORY if they want to be backwards compatible.
// The path here can be NULL. It should only be non-NULL if the frontend user has set a specific save path.
//
#define RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO 32
// const struct retro_system_av_info * --
// Sets a new av_info structure. This can only be called from within retro_run().
// This should *only* be used if the core is completely altering the internal resolutions, aspect ratios, timings, sampling rate, etc.
// Calling this can require a full reinitialization of video/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 reinit will happen so that video and audio callbacks
// happening after this call within the same retro_run() call will target the newly initialized driver.
//
// This callback makes it possible to support configurable resolutions in games, which can be useful to
// avoid setting the "worst case" in max_width/max_height.
//
// ***HIGHLY RECOMMENDED*** Do not call this callback every time resolution changes in an emulator core if it's
// expected to be a temporary change, for the reasons of possible driver reinit.
// This call is not a free pass for not trying to provide correct values in retro_get_system_av_info().
//
// If this returns false, the frontend does not acknowledge a changed av_info struct.
enum retro_log_level
{
@ -583,6 +626,98 @@ struct retro_log_callback
retro_log_printf_t log;
};
// Performance related functions
//
// ID values for SIMD CPU features
#define RETRO_SIMD_SSE (1 << 0)
#define RETRO_SIMD_SSE2 (1 << 1)
#define RETRO_SIMD_VMX (1 << 2)
#define RETRO_SIMD_VMX128 (1 << 3)
#define RETRO_SIMD_AVX (1 << 4)
#define RETRO_SIMD_NEON (1 << 5)
#define RETRO_SIMD_SSE3 (1 << 6)
#define RETRO_SIMD_SSSE3 (1 << 7)
#define RETRO_SIMD_MMX (1 << 8)
#define RETRO_SIMD_MMXEXT (1 << 9)
#define RETRO_SIMD_SSE4 (1 << 10)
#define RETRO_SIMD_SSE42 (1 << 11)
#define RETRO_SIMD_AVX2 (1 << 12)
#define RETRO_SIMD_VFPU (1 << 13)
typedef uint64_t retro_perf_tick_t;
typedef int64_t retro_time_t;
struct retro_perf_counter
{
const char *ident;
retro_perf_tick_t start;
retro_perf_tick_t total;
retro_perf_tick_t call_cnt;
bool registered;
};
// Returns current time in microseconds. Tries to use the most accurate timer available.
typedef retro_time_t (*retro_perf_get_time_usec_t)(void);
// A simple counter. Usually nanoseconds, but can also be CPU cycles.
// Can be used directly if desired (when creating a more sophisticated performance counter system).
typedef retro_perf_tick_t (*retro_perf_get_counter_t)(void);
// Returns a bit-mask of detected CPU features (RETRO_SIMD_*).
typedef uint64_t (*retro_get_cpu_features_t)(void);
// Asks frontend to log and/or display the state of performance counters.
// Performance counters can always be poked into manually as well.
typedef void (*retro_perf_log_t)(void);
// Register a performance counter.
// ident field must be set with a discrete value and other values in retro_perf_counter must be 0.
// Registering can be called multiple times. To avoid calling to frontend redundantly, you can check registered field first.
typedef void (*retro_perf_register_t)(struct retro_perf_counter *counter);
// Starts and stops a registered counter.
typedef void (*retro_perf_start_t)(struct retro_perf_counter *counter);
typedef void (*retro_perf_stop_t)(struct retro_perf_counter *counter);
// For convenience it can be useful to wrap register, start and stop in macros.
// E.g.:
// #ifdef LOG_PERFORMANCE
// #define RETRO_PERFORMANCE_INIT(perf_cb, name) static struct retro_perf_counter name = {#name}; if (!name.registered) perf_cb.perf_register(&(name))
// #define RETRO_PERFORMANCE_START(perf_cb, name) perf_cb.perf_start(&(name))
// #define RETRO_PERFORMANCE_STOP(perf_cb, name) perf_cb.perf_stop(&(name))
// #else
// ... Blank macros ...
// #endif
// These can then be used mid-functions around code snippets.
//
// extern struct retro_perf_callback perf_cb; // Somewhere in the core.
//
// void do_some_heavy_work(void)
// {
// RETRO_PERFORMANCE_INIT(cb, work_1);
// RETRO_PERFORMANCE_START(cb, work_1);
// heavy_work_1();
// RETRO_PERFORMANCE_STOP(cb, work_1);
//
// RETRO_PERFORMANCE_INIT(cb, work_2);
// RETRO_PERFORMANCE_START(cb, work_2);
// heavy_work_2();
// RETRO_PERFORMANCE_STOP(cb, work_2);
// }
//
// void retro_deinit(void)
// {
// perf_cb.perf_log(); // Log all perf counters here for example.
// }
struct retro_perf_callback
{
retro_perf_get_time_usec_t get_time_usec;
retro_get_cpu_features_t get_cpu_features;
retro_perf_get_counter_t get_perf_counter;
retro_perf_register_t perf_register;
retro_perf_start_t perf_start;
retro_perf_stop_t perf_stop;
retro_perf_log_t perf_log;
};
// FIXME: Document the sensor API and work out behavior.
// It will be marked as experimental until then.
enum retro_sensor_action
@ -593,10 +728,17 @@ enum retro_sensor_action
RETRO_SENSOR_DUMMY = INT_MAX
};
// Id values for SENSOR types.
#define RETRO_SENSOR_ACCELEROMETER_X 0
#define RETRO_SENSOR_ACCELEROMETER_Y 1
#define RETRO_SENSOR_ACCELEROMETER_Z 2
typedef bool (*retro_set_sensor_state_t)(unsigned port, enum retro_sensor_action action, unsigned rate);
typedef float (*retro_sensor_get_input_t)(unsigned port, unsigned id);
struct retro_sensor_interface
{
retro_set_sensor_state_t set_sensor_state;
retro_sensor_get_input_t get_sensor_input;
};
////
@ -653,6 +795,41 @@ struct retro_camera_callback
retro_camera_lifetime_status_t deinitialized;
};
// Sets the interval of time and/or distance at which to update/poll location-based data.
// To ensure compatibility with all location-based implementations, values for both
// interval_ms and interval_distance should be provided.
// interval_ms is the interval expressed in milliseconds.
// interval_distance is the distance interval expressed in meters.
typedef void (*retro_location_set_interval_t)(unsigned interval_ms, unsigned interval_distance);
// Start location services. The device will start listening for changes to the
// current location at regular intervals (which are defined with retro_location_set_interval_t).
typedef bool (*retro_location_start_t)(void);
// Stop location services. The device will stop listening for changes to the current
// location.
typedef void (*retro_location_stop_t)(void);
// Get the position of the current location. Will set parameters to 0 if no new
// location update has happened since the last time.
typedef bool (*retro_location_get_position_t)(double *lat, double *lon, double *horiz_accuracy,
double *vert_accuracy);
// Callback which signals when the location driver is initialized and/or deinitialized.
// retro_location_start_t can be called in initialized callback.
typedef void (*retro_location_lifetime_status_t)(void);
struct retro_location_callback
{
retro_location_start_t start;
retro_location_stop_t stop;
retro_location_get_position_t get_position;
retro_location_set_interval_t set_interval;
retro_location_lifetime_status_t initialized;
retro_location_lifetime_status_t deinitialized;
};
enum retro_rumble_effect
{
RETRO_RUMBLE_STRONG = 0,