Slow fix of libretro interface

This commit is contained in:
Zach Bacon 2016-11-10 00:40:22 -05:00
parent 9e0c8cec8b
commit 0d6b94afb7
5 changed files with 1712 additions and 1514 deletions

View File

@ -1466,7 +1466,7 @@ void CPUCleanUp()
emulating = 0;
}
#ifndef __LIBRETRO__
void SetMapMasks()
{
map[0].mask = 0x3FFF;
@ -1501,7 +1501,7 @@ void SetMapMasks()
}
clearBreakRegList();
}
#endif
int CPULoadRom(const char* szFile)
{
romSize = 0x2000000;
@ -3662,8 +3662,9 @@ void CPUReset()
map[12].address = rom;
map[14].address = flashSaveMemory;
#ifndef __LIBRETRO__
SetMapMasks();
#endif
soundReset();
CPUUpdateWindow0();

View File

@ -15,6 +15,7 @@
// along with this program; if not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "../common/cstdint.h"
#include "SoundRetro.h"
#include "libretro.h"
unsigned g_audio_frames;

View File

@ -127,10 +127,12 @@ uint8_t* utilLoad(const char* file, bool (*accept)(const char*), uint8_t* data,
rewind(fp);
uint8_t *image = data;
if (image == NULL) {
if(image == NULL)
{
//allocate buffer memory if none was passed to the function
image = (uint8_t *)malloc(utilGetSize(size));
if (image == NULL) {
if(image == NULL)
{
systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
"data");
return NULL;

View File

@ -60,7 +60,7 @@ int systemFrameSkip = 0;
int systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
int systemSpeed = 0;
u64 startTime = 0;
uint64_t startTime = 0;
uint32_t renderedFrames = 0;
void (*dbgOutput)(const char* s, uint32_t addr);
@ -70,6 +70,10 @@ void* retro_get_memory_data(unsigned id)
{
if (id == RETRO_MEMORY_SAVE_RAM)
return libretro_save_buf;
if (id == RETRO_MEMORY_SYSTEM_RAM)
return workRAM;
if (id == RETRO_MEMORY_VIDEO_RAM)
return vram;
return NULL;
}
@ -78,6 +82,10 @@ size_t retro_get_memory_size(unsigned id)
{
if (id == RETRO_MEMORY_SAVE_RAM)
return libretro_save_size;
if (id == RETRO_MEMORY_SYSTEM_RAM)
return 0x40000;
if (id == RETRO_MEMORY_VIDEO_RAM)
return 0x20000;
return 0;
}
@ -176,7 +184,14 @@ void retro_set_environment(retro_environment_t cb)
environ_cb = cb;
struct retro_variable variables[] = {
{ "vbam_layer_1", "Show layer 1; Yes|No" },
{ "vbam_layer_2", "Show layer 2; Yes|No" },
{ "vbam_layer_3", "Show layer 3; Yes|No" },
{ "vbam_layer_4", "Show layer 4; Yes|No" },
{ "vbam_layer_5", "Show sprite layer; Yes|No" },
{ "vbam_layer_6", "Show window layer 1; Yes|No" },
{ "vbam_layer_7", "Show window layer 2; Yes|No" },
{ "vbam_layer_8", "Show sprite window layer; Yes|No" },
{ NULL, NULL },
};
@ -186,7 +201,9 @@ void retro_set_environment(retro_environment_t cb)
{ "Alt Joypad AB", RETRO_DEVICE_GBA_ALT2 },
};
static const struct retro_controller_info ports[] = { { port_1, 4 }, { 0, 0 } };
static const struct retro_controller_info ports[] = {{ port_1, 3 },{ NULL,0 }};
cb(RETRO_ENVIRONMENT_SET_VARIABLES, variables);
cb(RETRO_ENVIRONMENT_SET_CONTROLLER_INFO, (void*)ports);
@ -196,7 +213,7 @@ void retro_get_system_info(struct retro_system_info* info)
{
info->need_fullpath = false;
info->valid_extensions = "gba";
info->library_version = "svn";
info->library_version = "git";
info->library_name = "VBA-M";
info->block_extract = false;
}
@ -207,6 +224,7 @@ void retro_get_system_av_info(struct retro_system_av_info* info)
info->geometry.base_height = 160;
info->geometry.max_width = 240;
info->geometry.max_height = 160;
info->geometry.aspect_ratio = 3.0 / 2.0;
info->timing.fps = 16777216.0 / 280896.0;
info->timing.sample_rate = 32000.0;
}
@ -302,6 +320,8 @@ static const ini_t gbaover[256] = {
{"Game Boy Wars Advance 1+2 (Japan)", "BGWJ", 131072, 0, 0, 0, 0},
{"Golden Sun - The Lost Age (USA)", "AGFE", 65536, 0, 0, 1, 0},
{"Golden Sun (USA)", "AGSE", 65536, 0, 0, 1, 0},
{"Iridion II (Europe) (En,Fr,De)", "AI2P", 0, 5, 0, 0, 0},
{"Iridion II (USA)", "AI2E", 0, 5, 0, 0, 0},
{"Koro Koro Puzzle - Happy Panechu! (Japan)", "KHPJ", 0, 4, 0, 0, 0},
{"Mario vs. Donkey Kong (Europe)", "BM5P", 0, 3, 0, 0, 0},
{"Pocket Monsters - Emerald (Japan)", "BPEJ", 131072, 0, 1, 0, 0},
@ -418,12 +438,8 @@ static void gba_init(void)
systemBlueShift = 3;
#endif
utilUpdateSystemColorMaps(false);
if (cpuSaveType == 0)
utilGBAFindSave(size);
else
saveType = cpuSaveType;
utilUpdateSystemColorMaps(false);
load_image_preferences();
@ -505,6 +521,25 @@ static unsigned has_frame;
static void update_variables(void)
{
char key[256];
struct retro_variable var;
var.key=key;
int disabled_layers=0;
strcpy(key, "vbam_layer_x");
for (int i=0;i<8;i++)
{
key[strlen("vbam_layer_")]='1'+i;
var.value=NULL;
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value && var.value[0]=='N')
{
disabled_layers|=0x100<<i;
}
}
layerSettings = 0xFF00 ^ disabled_layers;
layerEnable = DISPCNT & layerSettings;
CPUUpdateRenderBuffers(false);
}
#ifdef FINAL_VERSION
@ -611,63 +646,45 @@ bool retro_load_game(const struct retro_game_info* game)
environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, input_desc);
bool ret = CPULoadRomData((const char*)game->data, game->size);
int romSize = CPULoadRomData((const char*)game->data, game->size);
if (!romSize)
return false;
gba_init();
struct retro_memory_descriptor desc[9];
struct retro_memory_descriptor desc[11];
memset(desc, 0, sizeof(desc));
desc[0].start = 0x03000000;
desc[0].select = 0xFF000000;
desc[0].len = 0x8000;
desc[0].ptr = internalRAM; //fast WRAM
desc[1].start = 0x02000000;
desc[1].select = 0xFF000000;
desc[1].len = 0x40000;
desc[1].ptr = workRAM; //slow WRAM
desc[2].start = 0x0E000000;
desc[2].select = 0xFF000000;
desc[2].len = libretro_save_size;
desc[2].ptr = flashSaveMemory; //SRAM
desc[3].start = 0x08000000;
desc[3].select = 0xFC000000;
desc[3].len = 0x2000000;
desc[3].ptr = rom; //ROM, parts 1 and 2
desc[3].flags = RETRO_MEMDESC_CONST; //we need two mappings since its size is not a power of 2
desc[4].start = 0x0C000000;
desc[4].select = 0xFE000000;
desc[4].len = 0x2000000;
desc[4].ptr = rom; //ROM part 3
desc[0].start=0x03000000; desc[0].select=0xFF000000; desc[0].len=0x8000; desc[0].ptr=internalRAM;//fast WRAM
desc[1].start=0x02000000; desc[1].select=0xFF000000; desc[1].len=0x40000; desc[1].ptr=workRAM;//slow WRAM
/* TODO: if SRAM is flash, use start=0 addrspace="S" instead */
desc[2].start=0x0E000000; desc[2].select=0; desc[2].len=libretro_save_size; desc[2].ptr=flashSaveMemory;//SRAM
desc[3].start=0x08000000; desc[3].select=0; desc[3].len=romSize; desc[3].ptr=rom;//ROM
desc[3].flags=RETRO_MEMDESC_CONST;
desc[4].start=0x0A000000; desc[4].select=0; desc[4].len=romSize; desc[4].ptr=rom;//ROM mirror 1
desc[4].flags=RETRO_MEMDESC_CONST;
desc[5].start = 0x00000000;
desc[5].select = 0xFF000000;
desc[5].len = 0x4000;
desc[5].ptr = bios; //BIOS
desc[5].start=0x0C000000; desc[5].select=0; desc[5].len=romSize; desc[5].ptr=rom;//ROM mirror 2
desc[5].flags=RETRO_MEMDESC_CONST;
desc[6].start = 0x06000000;
desc[6].select = 0xFF000000;
desc[6].len = 0x18000;
desc[6].ptr = vram; //VRAM
desc[7].start = 0x07000000;
desc[7].select = 0xFF000000;
desc[7].len = 0x400;
desc[7].ptr = paletteRAM; //palettes
desc[8].start = 0x05000000;
desc[8].select = 0xFF000000;
desc[8].len = 0x400;
desc[8].ptr = oam; //OAM
desc[6].start=0x00000000; desc[6].select=0; desc[6].len=0x4000; desc[6].ptr=bios;//BIOS
desc[6].flags=RETRO_MEMDESC_CONST;
desc[7].start=0x06000000; desc[7].select=0xFF000000; desc[7].len=0x18000; desc[7].ptr=vram;//VRAM
desc[8].start=0x05000000; desc[8].select=0xFF000000; desc[8].len=0x400; desc[8].ptr=paletteRAM;//palettes
desc[9].start=0x07000000; desc[9].select=0xFF000000; desc[9].len=0x400; desc[9].ptr=oam;//OAM
desc[10].start=0x04000000;desc[10].select=0; desc[10].len=0x400; desc[10].ptr=ioMem;//bunch of registers
struct retro_memory_map retromap={ desc, sizeof(desc)/sizeof(*desc) };
if (ret)
environ_cb(RETRO_ENVIRONMENT_SET_MEMORY_MAPS, &retromap);
return ret;
bool yes = true;
environ_cb(RETRO_ENVIRONMENT_SET_SUPPORT_ACHIEVEMENTS, &yes);
return true;
}
bool retro_load_game_special(
unsigned game_type,
const struct retro_game_info* info, size_t num_info)
{
return false;
}
const struct retro_game_info *info, size_t num_info
)
{ return false; }
extern unsigned g_audio_frames;
static unsigned g_video_frames;

View File

@ -1,25 +1,21 @@
/* Copyright (C) 2010-2014 The RetroArch team
/* Copyright (C) 2010-2016 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this libretro API header (libretro.h).
* ---------------------------------------------------------------------------------------
*
* Permission is hereby granted, free of charge,
* to any person obtaining a copy of this software and associated documentation files (the
* "Software"),
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY,
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
@ -27,9 +23,9 @@
#ifndef LIBRETRO_H__
#define LIBRETRO_H__
#include <limits.h>
#include <stddef.h>
#include <stdint.h>
#include <stddef.h>
#include <limits.h>
#ifdef __cplusplus
extern "C" {
@ -47,6 +43,40 @@ extern "C" {
#endif
#endif
#ifndef RETRO_CALLCONV
# if defined(__GNUC__) && defined(__i386__) && !defined(__x86_64__)
# define RETRO_CALLCONV __attribute__((cdecl))
# elif defined(_MSC_VER) && defined(_M_X86) && !defined(_M_X64)
# define RETRO_CALLCONV __cdecl
# else
# define RETRO_CALLCONV /* all other platforms only have one calling convention each */
# endif
#endif
#ifndef RETRO_API
# if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
# ifdef RETRO_IMPORT_SYMBOLS
# ifdef __GNUC__
# define RETRO_API RETRO_CALLCONV __attribute__((__dllimport__))
# else
# define RETRO_API RETRO_CALLCONV __declspec(dllimport)
# endif
# else
# ifdef __GNUC__
# define RETRO_API RETRO_CALLCONV __attribute__((__dllexport__))
# else
# define RETRO_API RETRO_CALLCONV __declspec(dllexport)
# endif
# endif
# else
# if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__CELLOS_LV2__)
# define RETRO_API RETRO_CALLCONV __attribute__((__visibility__("default")))
# else
# define RETRO_API RETRO_CALLCONV
# endif
# endif
#endif
/* Used for checking API/ABI mismatches that can break libretro
* implementations.
* It is not incremented for compatible changes to the API.
@ -176,6 +206,8 @@ extern "C" {
#define RETRO_DEVICE_ID_MOUSE_WHEELUP 4
#define RETRO_DEVICE_ID_MOUSE_WHEELDOWN 5
#define RETRO_DEVICE_ID_MOUSE_MIDDLE 6
#define RETRO_DEVICE_ID_MOUSE_HORIZ_WHEELUP 7
#define RETRO_DEVICE_ID_MOUSE_HORIZ_WHEELDOWN 8
/* Id values for LIGHTGUN types. */
#define RETRO_DEVICE_ID_LIGHTGUN_X 0
@ -196,7 +228,8 @@ extern "C" {
#define RETRO_REGION_PAL 1
/* Id values for LANGUAGE */
enum retro_language {
enum retro_language
{
RETRO_LANGUAGE_ENGLISH = 0,
RETRO_LANGUAGE_JAPANESE = 1,
RETRO_LANGUAGE_FRENCH = 2,
@ -209,6 +242,8 @@ enum retro_language {
RETRO_LANGUAGE_KOREAN = 9,
RETRO_LANGUAGE_CHINESE_TRADITIONAL = 10,
RETRO_LANGUAGE_CHINESE_SIMPLIFIED = 11,
RETRO_LANGUAGE_ESPERANTO = 12,
RETRO_LANGUAGE_POLISH = 13,
RETRO_LANGUAGE_LAST,
/* Ensure sizeof(enum) == sizeof(int) */
@ -240,7 +275,8 @@ enum retro_language {
#define RETRO_MEMORY_VIDEO_RAM 3
/* Keysyms used for ID in input state callback when polling RETRO_KEYBOARD. */
enum retro_key {
enum retro_key
{
RETROK_UNKNOWN = 0,
RETROK_FIRST = 0,
RETROK_BACKSPACE = 8,
@ -389,7 +425,8 @@ enum retro_key {
RETROK_DUMMY = INT_MAX /* Ensure sizeof(enum) == sizeof(int) */
};
enum retro_mod {
enum retro_mod
{
RETROKMOD_NONE = 0x0000,
RETROKMOD_SHIFT = 0x01,
@ -411,41 +448,36 @@ enum retro_mod {
#define RETRO_ENVIRONMENT_PRIVATE 0x20000
/* Environment commands. */
#define RETRO_ENVIRONMENT_SET_ROTATION \
1 /* const unsigned * -- \
* Sets screen rotation of graphics. \
* Is only implemented if rotation can be accelerated by hardware. \
* Valid values are 0, 1, 2, 3, which rotates screen by 0, 90, 180, \
* 270 degrees counter-clockwise respectively. \
#define RETRO_ENVIRONMENT_SET_ROTATION 1 /* const unsigned * --
* Sets screen rotation of graphics.
* Is only implemented if rotation can be accelerated by hardware.
* Valid values are 0, 1, 2, 3, which rotates screen by 0, 90, 180,
* 270 degrees counter-clockwise respectively.
*/
#define RETRO_ENVIRONMENT_GET_OVERSCAN \
2 /* bool * -- \
* Boolean value whether or not the implementation should use overscan, \
* or crop away overscan. \
#define RETRO_ENVIRONMENT_GET_OVERSCAN 2 /* bool * --
* Boolean value whether or not the implementation should use overscan,
* or crop away overscan.
*/
#define RETRO_ENVIRONMENT_GET_CAN_DUPE \
3 /* bool * -- \
* Boolean value whether or not frontend supports frame duping, \
* passing NULL to video frame callback. \
#define RETRO_ENVIRONMENT_GET_CAN_DUPE 3 /* bool * --
* Boolean value whether or not frontend supports frame duping,
* passing NULL to video frame callback.
*/
/* 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 via RETRO_ENVIRONMENT_GET_LOG_INTERFACE (or as a \
* fallback, stderr). \
#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 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 \
* way to shutdown the game from a menu item or similar. \
#define RETRO_ENVIRONMENT_SHUTDOWN 7 /* N/A (NULL) --
* Requests the frontend to shutdown.
* Should only be used if game has a specific
* way to shutdown the game from a menu item or similar.
*/
#define RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL 8
/* const unsigned * --
@ -699,9 +731,10 @@ enum retro_mod {
* location-based information from the host device,
* such as current latitude / longitude.
*/
#define RETRO_ENVIRONMENT_GET_CONTENT_DIRECTORY 30
#define RETRO_ENVIRONMENT_GET_CONTENT_DIRECTORY 30 /* Old name, kept for compatibility. */
#define RETRO_ENVIRONMENT_GET_CORE_ASSETS_DIRECTORY 30
/* const char ** --
* Returns the "content" directory of the frontend.
* Returns the "core assets" 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.
@ -857,22 +890,81 @@ enum retro_mod {
* Returns the specified language of the frontend, if specified by the user.
* It can be used by the core for localization purposes.
*/
#define RETRO_ENVIRONMENT_GET_CURRENT_SOFTWARE_FRAMEBUFFER (40 | RETRO_ENVIRONMENT_EXPERIMENTAL)
/* struct retro_framebuffer * --
* Returns a preallocated framebuffer which the core can use for rendering
* the frame into when not using SET_HW_RENDER.
* The framebuffer returned from this call must not be used
* after the current call to retro_run() returns.
*
* The goal of this call is to allow zero-copy behavior where a core
* can render directly into video memory, avoiding extra bandwidth cost by copying
* memory from core to video memory.
*
* If this call succeeds and the core renders into it,
* the framebuffer pointer and pitch can be passed to retro_video_refresh_t.
* If the buffer from GET_CURRENT_SOFTWARE_FRAMEBUFFER is to be used,
* the core must pass the exact
* same pointer as returned by GET_CURRENT_SOFTWARE_FRAMEBUFFER;
* i.e. passing a pointer which is offset from the
* buffer is undefined. The width, height and pitch parameters
* must also match exactly to the values obtained from GET_CURRENT_SOFTWARE_FRAMEBUFFER.
*
* It is possible for a frontend to return a different pixel format
* than the one used in SET_PIXEL_FORMAT. This can happen if the frontend
* needs to perform conversion.
*
* It is still valid for a core to render to a different buffer
* even if GET_CURRENT_SOFTWARE_FRAMEBUFFER succeeds.
*
* A frontend must make sure that the pointer obtained from this function is
* writeable (and readable).
*/
#define RETRO_MEMDESC_CONST \
(1 << 0) /* The frontend will never change this memory area once retro_load_game has \
returned. */
#define RETRO_MEMDESC_BIGENDIAN \
(1 << 1) /* The memory area contains big endian data. Default is little endian. */
#define RETRO_MEMDESC_ALIGN_2 \
(1 << 16) /* All memory access in this area is aligned to their own size, or 2, \
whichever is smaller. */
enum retro_hw_render_interface_type
{
RETRO_HW_RENDER_INTERFACE_VULKAN = 0,
RETRO_HW_RENDER_INTERFACE_DUMMY = INT_MAX
};
/* Base struct. All retro_hw_render_interface_* types
* contain at least these fields. */
struct retro_hw_render_interface
{
enum retro_hw_render_interface_type interface_type;
unsigned interface_version;
};
#define RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE (41 | RETRO_ENVIRONMENT_EXPERIMENTAL)
/* const struct retro_hw_render_interface ** --
* Returns an API specific rendering interface for accessing API specific data.
* Not all HW rendering APIs support or need this.
* The contents of the returned pointer is specific to the rendering API
* being used. See the various headers like libretro_vulkan.h, etc.
*
* GET_HW_RENDER_INTERFACE cannot be called before context_reset has been called.
* Similarly, after context_destroyed callback returns,
* the contents of the HW_RENDER_INTERFACE are invalidated.
*/
#define RETRO_ENVIRONMENT_SET_SUPPORT_ACHIEVEMENTS (42 | RETRO_ENVIRONMENT_EXPERIMENTAL)
/* const bool * --
* If true, the libretro implementation supports achievements
* either via memory descriptors set with RETRO_ENVIRONMENT_SET_MEMORY_MAPS
* or via retro_get_memory_data/retro_get_memory_size.
*
* This must be called before the first call to retro_run.
*/
#define RETRO_MEMDESC_CONST (1 << 0) /* The frontend will never change this memory area once retro_load_game has returned. */
#define RETRO_MEMDESC_BIGENDIAN (1 << 1) /* The memory area contains big endian data. Default is little endian. */
#define RETRO_MEMDESC_ALIGN_2 (1 << 16) /* All memory access in this area is aligned to their own size, or 2, whichever is smaller. */
#define RETRO_MEMDESC_ALIGN_4 (2 << 16)
#define RETRO_MEMDESC_ALIGN_8 (3 << 16)
#define RETRO_MEMDESC_MINSIZE_2 \
(1 << 24) /* All memory in this region is accessed at least 2 bytes at the time. */
#define RETRO_MEMDESC_MINSIZE_2 (1 << 24) /* All memory in this region is accessed at least 2 bytes at the time. */
#define RETRO_MEMDESC_MINSIZE_4 (2 << 24)
#define RETRO_MEMDESC_MINSIZE_8 (3 << 24)
struct retro_memory_descriptor {
struct retro_memory_descriptor
{
uint64_t flags;
/* Pointer to the start of the relevant ROM or RAM chip.
@ -986,12 +1078,14 @@ struct retro_memory_descriptor {
* .len can be implied by .select in many of them, but was included for clarity.
*/
struct retro_memory_map {
struct retro_memory_map
{
const struct retro_memory_descriptor *descriptors;
unsigned num_descriptors;
};
struct retro_controller_description {
struct retro_controller_description
{
/* Human-readable description of the controller. Even if using a generic
* input device type, this can be set to the particular device type the
* core uses. */
@ -1005,12 +1099,14 @@ struct retro_controller_description {
unsigned id;
};
struct retro_controller_info {
struct retro_controller_info
{
const struct retro_controller_description *types;
unsigned num_types;
};
struct retro_subsystem_memory_info {
struct retro_subsystem_memory_info
{
/* The extension associated with a memory type, e.g. "psram". */
const char *extension;
@ -1020,7 +1116,8 @@ struct retro_subsystem_memory_info {
unsigned type;
};
struct retro_subsystem_rom_info {
struct retro_subsystem_rom_info
{
/* Describes what the content is (SGB BIOS, GB ROM, etc). */
const char *desc;
@ -1043,7 +1140,8 @@ struct retro_subsystem_rom_info {
unsigned num_memory;
};
struct retro_subsystem_info {
struct retro_subsystem_info
{
/* Human-readable string of the subsystem type, e.g. "Super GameBoy" */
const char *desc;
@ -1087,11 +1185,13 @@ typedef void (*retro_proc_address_t)(void);
*/
typedef retro_proc_address_t (*retro_get_proc_address_t)(const char *sym);
struct retro_get_proc_address_interface {
struct retro_get_proc_address_interface
{
retro_get_proc_address_t get_proc_address;
};
enum retro_log_level {
enum retro_log_level
{
RETRO_LOG_DEBUG = 0,
RETRO_LOG_INFO,
RETRO_LOG_WARN,
@ -1101,9 +1201,11 @@ enum retro_log_level {
};
/* Logging function. Takes log level argument as well. */
typedef void (*retro_log_printf_t)(enum retro_log_level level, const char *fmt, ...);
typedef void (*retro_log_printf_t)(enum retro_log_level level,
const char *fmt, ...);
struct retro_log_callback {
struct retro_log_callback
{
retro_log_printf_t log;
};
@ -1126,11 +1228,16 @@ struct retro_log_callback {
#define RETRO_SIMD_VFPU (1 << 13)
#define RETRO_SIMD_PS (1 << 14)
#define RETRO_SIMD_AES (1 << 15)
#define RETRO_SIMD_VFPV3 (1 << 16)
#define RETRO_SIMD_VFPV4 (1 << 17)
#define RETRO_SIMD_POPCNT (1 << 18)
#define RETRO_SIMD_MOVBE (1 << 19)
typedef uint64_t retro_perf_tick_t;
typedef int64_t retro_time_t;
struct retro_perf_counter {
struct retro_perf_counter
{
const char *ident;
retro_perf_tick_t start;
retro_perf_tick_t total;
@ -1174,8 +1281,7 @@ 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_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
@ -1205,7 +1311,8 @@ typedef void (*retro_perf_stop_t)(struct retro_perf_counter *counter);
* }
*/
struct retro_perf_callback {
struct retro_perf_callback
{
retro_perf_get_time_usec_t get_time_usec;
retro_get_cpu_features_t get_cpu_features;
@ -1219,7 +1326,8 @@ struct retro_perf_callback {
/* FIXME: Document the sensor API and work out behavior.
* It will be marked as experimental until then.
*/
enum retro_sensor_action {
enum retro_sensor_action
{
RETRO_SENSOR_ACCELEROMETER_ENABLE = 0,
RETRO_SENSOR_ACCELEROMETER_DISABLE,
@ -1231,17 +1339,19 @@ enum retro_sensor_action {
#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 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 {
struct retro_sensor_interface
{
retro_set_sensor_state_t set_sensor_state;
retro_sensor_get_input_t get_sensor_input;
};
enum retro_camera_buffer {
enum retro_camera_buffer
{
RETRO_CAMERA_BUFFER_OPENGL_TEXTURE = 0,
RETRO_CAMERA_BUFFER_RAW_FRAMEBUFFER,
@ -1264,8 +1374,8 @@ typedef void (*retro_camera_lifetime_status_t)(void);
* Width, height and pitch are similar to retro_video_refresh_t.
* First pixel is top-left origin.
*/
typedef void (*retro_camera_frame_raw_framebuffer_t)(const uint32_t *buffer, unsigned width,
unsigned height, size_t pitch);
typedef void (*retro_camera_frame_raw_framebuffer_t)(const uint32_t *buffer,
unsigned width, unsigned height, size_t pitch);
/* A callback for when OpenGL textures are used.
*
@ -1285,23 +1395,27 @@ typedef void (*retro_camera_frame_raw_framebuffer_t)(const uint32_t *buffer, uns
* GL-specific typedefs are avoided here to avoid relying on gl.h in
* the API definition.
*/
typedef void (*retro_camera_frame_opengl_texture_t)(unsigned texture_id, unsigned texture_target,
const float *affine);
typedef void (*retro_camera_frame_opengl_texture_t)(unsigned texture_id,
unsigned texture_target, const float *affine);
struct retro_camera_callback {
struct retro_camera_callback
{
/* Set by libretro core.
* Example bitmask: caps = (1 << RETRO_CAMERA_BUFFER_OPENGL_TEXTURE) | (1 <<
* RETRO_CAMERA_BUFFER_RAW_FRAMEBUFFER).
* Example bitmask: caps = (1 << RETRO_CAMERA_BUFFER_OPENGL_TEXTURE) | (1 << RETRO_CAMERA_BUFFER_RAW_FRAMEBUFFER).
*/
uint64_t caps;
unsigned width; /* Desired resolution for camera. Is only used as a hint. */
/* Desired resolution for camera. Is only used as a hint. */
unsigned width;
unsigned height;
retro_camera_start_t start; /* Set by frontend. */
retro_camera_stop_t stop; /* Set by frontend. */
/* Set by frontend. */
retro_camera_start_t start;
retro_camera_stop_t stop;
/* Set by libretro core if raw framebuffer callbacks will be used. */
retro_camera_frame_raw_framebuffer_t frame_raw_framebuffer;
/* Set by libretro core if OpenGL texture callbacks will be used. */
retro_camera_frame_opengl_texture_t frame_opengl_texture;
@ -1327,7 +1441,8 @@ struct retro_camera_callback {
* 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);
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
@ -1340,8 +1455,8 @@ 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);
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.
@ -1349,7 +1464,8 @@ typedef bool (*retro_location_get_position_t)(double *lat, double *lon, double *
*/
typedef void (*retro_location_lifetime_status_t)(void);
struct retro_location_callback {
struct retro_location_callback
{
retro_location_start_t start;
retro_location_stop_t stop;
retro_location_get_position_t get_position;
@ -1359,7 +1475,8 @@ struct retro_location_callback {
retro_location_lifetime_status_t deinitialized;
};
enum retro_rumble_effect {
enum retro_rumble_effect
{
RETRO_RUMBLE_STRONG = 0,
RETRO_RUMBLE_WEAK = 1,
@ -1373,10 +1490,11 @@ enum retro_rumble_effect {
*
* Returns true if rumble state request was honored.
* Calling this before first retro_run() is likely to return false. */
typedef bool (*retro_set_rumble_state_t)(unsigned port, enum retro_rumble_effect effect,
uint16_t strength);
typedef bool (*retro_set_rumble_state_t)(unsigned port,
enum retro_rumble_effect effect, uint16_t strength);
struct retro_rumble_interface {
struct retro_rumble_interface
{
retro_set_rumble_state_t set_rumble_state;
};
@ -1392,7 +1510,8 @@ typedef void (*retro_audio_callback_t)(void);
*/
typedef void (*retro_audio_set_state_callback_t)(bool enabled);
struct retro_audio_callback {
struct retro_audio_callback
{
retro_audio_callback_t callback;
retro_audio_set_state_callback_t set_state;
};
@ -1407,7 +1526,8 @@ struct retro_audio_callback {
* In those scenarios the reference frame time value will be used. */
typedef int64_t retro_usec_t;
typedef void (*retro_frame_time_callback_t)(retro_usec_t usec);
struct retro_frame_time_callback {
struct retro_frame_time_callback
{
retro_frame_time_callback_t callback;
/* Represents the time of one frame. It is computed as
* 1000000 / fps, but the implementation will resolve the
@ -1439,7 +1559,8 @@ typedef uintptr_t (*retro_hw_get_current_framebuffer_t)(void);
/* Get a symbol from HW context. */
typedef retro_proc_address_t (*retro_hw_get_proc_address_t)(const char *sym);
enum retro_hw_context_type {
enum retro_hw_context_type
{
RETRO_HW_CONTEXT_NONE = 0,
/* OpenGL 2.x. Driver can choose to use latest compatibility context. */
RETRO_HW_CONTEXT_OPENGL = 1,
@ -1454,10 +1575,14 @@ enum retro_hw_context_type {
* use the corresponding enums directly. */
RETRO_HW_CONTEXT_OPENGLES_VERSION = 5,
/* Vulkan, see RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE. */
RETRO_HW_CONTEXT_VULKAN = 6,
RETRO_HW_CONTEXT_DUMMY = INT_MAX
};
struct retro_hw_render_callback {
struct retro_hw_render_callback
{
/* Which API to use. Set by libretro core. */
enum retro_hw_context_type context_type;
@ -1475,23 +1600,28 @@ struct retro_hw_render_callback {
*/
retro_hw_context_reset_t context_reset;
/* Set by frontend. */
/* Set by frontend.
* TODO: This is rather obsolete. The frontend should not
* be providing preallocated framebuffers. */
retro_hw_get_current_framebuffer_t get_current_framebuffer;
/* Set by frontend. */
retro_hw_get_proc_address_t get_proc_address;
/* Set if render buffers should have depth component attached. */
/* Set if render buffers should have depth component attached.
* TODO: Obsolete. */
bool depth;
/* Set if stencil buffers should be attached. */
/* Set if stencil buffers should be attached.
* TODO: Obsolete. */
bool stencil;
/* If depth and stencil are true, a packed 24/8 buffer will be added.
* Only attaching stencil is invalid and will be ignored. */
/* Use conventional bottom-left origin convention. If false,
* standard libretro top-left origin semantics are used. */
* standard libretro top-left origin semantics are used.
* TODO: Move to GL specific interface. */
bool bottom_left_origin;
/* Major version number for core GL context or GLES 3.1+. */
@ -1502,6 +1632,7 @@ struct retro_hw_render_callback {
/* If this is true, the frontend will go very far to avoid
* resetting context in scenarios like toggling fullscreen, etc.
* TODO: Obsolete? Maybe frontend should just always assume this ...
*/
bool cache_context;
@ -1551,10 +1682,11 @@ struct retro_hw_render_callback {
* Similarily if only a keycode event is generated with no corresponding
* character, character should be 0.
*/
typedef void (*retro_keyboard_event_t)(bool down, unsigned keycode, uint32_t character,
uint16_t key_modifiers);
typedef void (*retro_keyboard_event_t)(bool down, unsigned keycode,
uint32_t character, uint16_t key_modifiers);
struct retro_keyboard_callback {
struct retro_keyboard_callback
{
retro_keyboard_event_t callback;
};
@ -1607,7 +1739,8 @@ struct retro_game_info;
* returned 4 before.
* Index 1 will be removed, and the new index is 3.
*/
typedef bool (*retro_replace_image_index_t)(unsigned index, const struct retro_game_info *info);
typedef bool (*retro_replace_image_index_t)(unsigned index,
const struct retro_game_info *info);
/* Adds a new valid index (get_num_images()) to the internal disk list.
* This will increment subsequent return values from get_num_images() by 1.
@ -1615,7 +1748,8 @@ typedef bool (*retro_replace_image_index_t)(unsigned index, const struct retro_g
* with replace_image_index. */
typedef bool (*retro_add_image_index_t)(void);
struct retro_disk_control_callback {
struct retro_disk_control_callback
{
retro_set_eject_state_t set_eject_state;
retro_get_eject_state_t get_eject_state;
@ -1627,7 +1761,8 @@ struct retro_disk_control_callback {
retro_add_image_index_t add_image_index;
};
enum retro_pixel_format {
enum retro_pixel_format
{
/* 0RGB1555, native endian.
* 0 bit must be set to 0.
* This pixel format is default for compatibility concerns only.
@ -1650,7 +1785,8 @@ enum retro_pixel_format {
RETRO_PIXEL_FORMAT_UNKNOWN = INT_MAX
};
struct retro_message {
struct retro_message
{
const char *msg; /* Message to be displayed. */
unsigned frames; /* Duration in frames of message. */
};
@ -1658,7 +1794,8 @@ struct retro_message {
/* Describes how the libretro implementation maps a libretro input bind
* to its internal input system through a human readable string.
* This string can be used to better let a user configure input. */
struct retro_input_descriptor {
struct retro_input_descriptor
{
/* Associates given parameters with a description. */
unsigned port;
unsigned device;
@ -1671,7 +1808,8 @@ struct retro_input_descriptor {
const char *description;
};
struct retro_system_info {
struct retro_system_info
{
/* All pointers are owned by libretro implementation, and pointers must
* remain valid until retro_deinit() is called. */
@ -1706,7 +1844,8 @@ struct retro_system_info {
bool block_extract;
};
struct retro_game_geometry {
struct retro_game_geometry
{
unsigned base_width; /* Nominal video width of game. */
unsigned base_height; /* Nominal video height of game. */
unsigned max_width; /* Maximum possible width of game. */
@ -1719,17 +1858,20 @@ struct retro_game_geometry {
* if desired. */
};
struct retro_system_timing {
struct retro_system_timing
{
double fps; /* FPS of video content. */
double sample_rate; /* Sampling rate of audio. */
};
struct retro_system_av_info {
struct retro_system_av_info
{
struct retro_game_geometry geometry;
struct retro_system_timing timing;
};
struct retro_variable {
struct retro_variable
{
/* Variable to query in RETRO_ENVIRONMENT_GET_VARIABLE.
* If NULL, obtains the complete environment string if more
* complex parsing is necessary.
@ -1743,7 +1885,8 @@ struct retro_variable {
const char *value;
};
struct retro_game_info {
struct retro_game_info
{
const char *path; /* Path to game, UTF-8 encoded.
* Usually used as a reference.
* May be NULL if rom was loaded from stdin
@ -1756,6 +1899,36 @@ struct retro_game_info {
const char *meta; /* String of implementation specific meta-data. */
};
#define RETRO_MEMORY_ACCESS_WRITE (1 << 0)
/* The core will write to the buffer provided by retro_framebuffer::data. */
#define RETRO_MEMORY_ACCESS_READ (1 << 1)
/* The core will read from retro_framebuffer::data. */
#define RETRO_MEMORY_TYPE_CACHED (1 << 0)
/* The memory in data is cached.
* If not cached, random writes and/or reading from the buffer is expected to be very slow. */
struct retro_framebuffer
{
void *data; /* The framebuffer which the core can render into.
Set by frontend in GET_CURRENT_SOFTWARE_FRAMEBUFFER.
The initial contents of data are unspecified. */
unsigned width; /* The framebuffer width used by the core. Set by core. */
unsigned height; /* The framebuffer height used by the core. Set by core. */
size_t pitch; /* The number of bytes between the beginning of a scanline,
and beginning of the next scanline.
Set by frontend in GET_CURRENT_SOFTWARE_FRAMEBUFFER. */
enum retro_pixel_format format; /* The pixel format the core must use to render into data.
This format could differ from the format used in
SET_PIXEL_FORMAT.
Set by frontend in GET_CURRENT_SOFTWARE_FRAMEBUFFER. */
unsigned access_flags; /* How the core will access the memory in the framebuffer.
RETRO_MEMORY_ACCESS_* flags.
Set by core. */
unsigned memory_flags; /* Flags telling core how the memory has been mapped.
RETRO_MEMORY_TYPE_* flags.
Set by frontend in GET_CURRENT_SOFTWARE_FRAMEBUFFER. */
};
/* Callbacks */
/* Environment callback. Gives implementations a way of performing
@ -1773,8 +1946,8 @@ typedef bool (*retro_environment_t)(unsigned cmd, void *data);
* Certain graphic APIs, such as OpenGL ES, do not like textures
* that are not packed in memory.
*/
typedef void (*retro_video_refresh_t)(const void *data, unsigned width, unsigned height,
size_t pitch);
typedef void (*retro_video_refresh_t)(const void *data, unsigned width,
unsigned height, size_t pitch);
/* Renders a single audio frame. Should only be used if implementation
* generates a single sample at a time.
@ -1788,7 +1961,8 @@ typedef void (*retro_audio_sample_t)(int16_t left, int16_t right);
* I.e. int16_t buf[4] = { l, r, l, r }; would be 2 frames.
* Only one of the audio callbacks must ever be used.
*/
typedef size_t (*retro_audio_sample_batch_t)(const int16_t *data, size_t frames);
typedef size_t (*retro_audio_sample_batch_t)(const int16_t *data,
size_t frames);
/* Polls input. */
typedef void (*retro_input_poll_t)(void);
@ -1800,32 +1974,33 @@ typedef void (*retro_input_poll_t)(void);
* have been set with retro_set_controller_port_device()
* will still use the higher level RETRO_DEVICE_JOYPAD to request input.
*/
typedef int16_t (*retro_input_state_t)(unsigned port, unsigned device, unsigned index, unsigned id);
typedef int16_t (*retro_input_state_t)(unsigned port, unsigned device,
unsigned index, unsigned id);
/* Sets callbacks. retro_set_environment() is guaranteed to be called
* before retro_init().
*
* The rest of the set_* functions are guaranteed to have been called
* before the first call to retro_run() is made. */
void retro_set_environment(retro_environment_t);
void retro_set_video_refresh(retro_video_refresh_t);
void retro_set_audio_sample(retro_audio_sample_t);
void retro_set_audio_sample_batch(retro_audio_sample_batch_t);
void retro_set_input_poll(retro_input_poll_t);
void retro_set_input_state(retro_input_state_t);
RETRO_API void retro_set_environment(retro_environment_t);
RETRO_API void retro_set_video_refresh(retro_video_refresh_t);
RETRO_API void retro_set_audio_sample(retro_audio_sample_t);
RETRO_API void retro_set_audio_sample_batch(retro_audio_sample_batch_t);
RETRO_API void retro_set_input_poll(retro_input_poll_t);
RETRO_API void retro_set_input_state(retro_input_state_t);
/* Library global initialization/deinitialization. */
void retro_init(void);
void retro_deinit(void);
RETRO_API void retro_init(void);
RETRO_API void retro_deinit(void);
/* Must return RETRO_API_VERSION. Used to validate ABI compatibility
* when the API is revised. */
unsigned retro_api_version(void);
RETRO_API unsigned retro_api_version(void);
/* Gets statically known system info. Pointers provided in *info
* must be statically allocated.
* Can be called at any time, even before retro_init(). */
void retro_get_system_info(struct retro_system_info *info);
RETRO_API void retro_get_system_info(struct retro_system_info *info);
/* Gets information about system audio/video timings and geometry.
* Can be called only after retro_load_game() has successfully completed.
@ -1833,7 +2008,7 @@ void retro_get_system_info(struct retro_system_info *info);
* variable if needed.
* E.g. geom.aspect_ratio might not be initialized if core doesn't
* desire a particular aspect ratio. */
void retro_get_system_av_info(struct retro_system_av_info *info);
RETRO_API void retro_get_system_av_info(struct retro_system_av_info *info);
/* Sets device to be used for player 'port'.
* By default, RETRO_DEVICE_JOYPAD is assumed to be plugged into all
@ -1843,10 +2018,10 @@ void retro_get_system_av_info(struct retro_system_av_info *info);
* hint to the libretro core when a core cannot automatically detect the
* appropriate input device type on its own. It is also relevant when a
* core can change its behavior depending on device type. */
void retro_set_controller_port_device(unsigned port, unsigned device);
RETRO_API void retro_set_controller_port_device(unsigned port, unsigned device);
/* Resets the current game. */
void retro_reset(void);
RETRO_API void retro_reset(void);
/* Runs the game for one video frame.
* During retro_run(), input_poll callback must be called at least once.
@ -1856,7 +2031,7 @@ void retro_reset(void);
* a frame if GET_CAN_DUPE returns true.
* In this case, the video callback can take a NULL argument for data.
*/
void retro_run(void);
RETRO_API void retro_run(void);
/* Returns the amount of data the implementation requires to serialize
* internal state (save states).
@ -1864,33 +2039,35 @@ void retro_run(void);
* returned size is never allowed to be larger than a previous returned
* value, to ensure that the frontend can allocate a save state buffer once.
*/
size_t retro_serialize_size(void);
RETRO_API size_t retro_serialize_size(void);
/* Serializes internal state. If failed, or size is lower than
* retro_serialize_size(), it should return false, true otherwise. */
bool retro_serialize(void *data, size_t size);
bool retro_unserialize(const void *data, size_t size);
RETRO_API bool retro_serialize(void *data, size_t size);
RETRO_API bool retro_unserialize(const void *data, size_t size);
void retro_cheat_reset(void);
void retro_cheat_set(unsigned index, bool enabled, const char *code);
RETRO_API void retro_cheat_reset(void);
RETRO_API void retro_cheat_set(unsigned index, bool enabled, const char *code);
/* Loads a game. */
bool retro_load_game(const struct retro_game_info *game);
RETRO_API bool retro_load_game(const struct retro_game_info *game);
/* Loads a "special" kind of game. Should not be used,
* except in extreme cases. */
bool retro_load_game_special(unsigned game_type, const struct retro_game_info *info,
size_t num_info);
RETRO_API bool retro_load_game_special(
unsigned game_type,
const struct retro_game_info *info, size_t num_info
);
/* Unloads a currently loaded game. */
void retro_unload_game(void);
RETRO_API void retro_unload_game(void);
/* Gets region of game. */
unsigned retro_get_region(void);
RETRO_API unsigned retro_get_region(void);
/* Gets region of memory. */
void *retro_get_memory_data(unsigned id);
size_t retro_get_memory_size(unsigned id);
RETRO_API void *retro_get_memory_data(unsigned id);
RETRO_API size_t retro_get_memory_size(unsigned id);
#ifdef __cplusplus
}