From 4b26606b045982ee76f3504fb6e828e99c782eda Mon Sep 17 00:00:00 2001 From: azaka Date: Thu, 11 Jun 2026 20:36:30 +0800 Subject: [PATCH 1/5] add libretro --- CMakeLists.txt | 46 +- src/libretro/libretro.c | 598 +++ src/libretro/libretro.h | 7978 +++++++++++++++++++++++++++++++++++++++ src/libretro/link.T | 5 + 4 files changed, 8626 insertions(+), 1 deletion(-) create mode 100644 src/libretro/libretro.c create mode 100644 src/libretro/libretro.h create mode 100644 src/libretro/link.T diff --git a/CMakeLists.txt b/CMakeLists.txt index 978502b04..93d3c56d9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,8 @@ if(AUDIO_BACKEND STREQUAL "") set(AUDIO_BACKEND "openal") elseif(PLATFORM STREQUAL "ps2") set(AUDIO_BACKEND "ps2") + elseif(PLATFORM STREQUAL "libretro") + set(AUDIO_BACKEND "none") else() set(AUDIO_BACKEND "miniaudio") endif() @@ -99,7 +101,11 @@ if (ENABLE_GLES AND ENABLE_LEGACY_GL) set(ENABLE_LEGACY_GL OFF) endif() -add_executable(butterscotch ${SOURCES} ${PLATFORM_SOURCES} ${AUDIO_SOURCES}) +if(PLATFORM STREQUAL "libretro") + add_library(butterscotch MODULE ${SOURCES} ${PLATFORM_SOURCES} ${AUDIO_SOURCES}) +else() + add_executable(butterscotch ${SOURCES} ${PLATFORM_SOURCES} ${AUDIO_SOURCES}) +endif() target_include_directories(butterscotch PRIVATE ${CMAKE_SOURCE_DIR}/src) if(AUDIO_BACKEND STREQUAL "openal") @@ -618,6 +624,44 @@ elseif(PLATFORM STREQUAL "ps3") # mojoal calls SDL atomics/threads, so SDL2 must link after it (static link order) target_link_libraries(mojoal PUBLIC ${SDL2_LIBRARIES}) target_link_libraries(butterscotch PRIVATE ${SDL2_LIBRARIES} m gcm_sys rsx sysutil io audio rt lv2 io audio bzip2 stb_ds sha1 ps3gl mojoal stb_vorbis) +elseif(PLATFORM STREQUAL "libretro") + # bzip2 needs -fPIC for linking into shared library + set_target_properties(bzip2 PROPERTIES POSITION_INDEPENDENT_CODE ON) + + # SW renderer, image decoder, stb image loader + target_sources(butterscotch PRIVATE + src/sw/sw_renderer.c + src/image/image_decoder.c + src/desktop/stb_impl.c + ) + target_include_directories(butterscotch PRIVATE + ${CMAKE_SOURCE_DIR}/src/sw + ${CMAKE_SOURCE_DIR}/src/image + ${CMAKE_SOURCE_DIR}/src/desktop + ${CMAKE_SOURCE_DIR}/src/libretro + vendor/stb/image + ) + + # Rename output to butterscotch_libretro.so + set_target_properties(butterscotch PROPERTIES + PREFIX "" + OUTPUT_NAME "butterscotch_libretro" + ) + + # Version script for symbol visibility + target_link_options(butterscotch PRIVATE + -Wl,--version-script=${CMAKE_SOURCE_DIR}/src/libretro/link.T + -Wl,--no-undefined + ) + + # Libraries + find_library(DL_LIB dl) + target_link_libraries(butterscotch PRIVATE bzip2 m ${DL_LIB}) + + target_compile_definitions(butterscotch PRIVATE + _GNU_SOURCE + _FILE_OFFSET_BITS=64 + ) else() message(FATAL_ERROR "Unknown platform! ${PLATFORM}") endif() diff --git a/src/libretro/libretro.c b/src/libretro/libretro.c new file mode 100644 index 000000000..9ada052bc --- /dev/null +++ b/src/libretro/libretro.c @@ -0,0 +1,598 @@ +#include +#include +#include +#include +#include +#include "libretro.h" + +#include "data_win.h" +#include "vm.h" +#include "runner.h" +#include "runner_keyboard.h" +#include "runner_mouse.h" +#include "runner_gamepad.h" +#include "sw_renderer.h" +#include "noop_audio_system.h" +#include "overlay_file_system.h" +#include "desktop/platformdefs.h" +#include "utils.h" + +static retro_log_printf_t log_cb; +static retro_video_refresh_t video_cb; +static retro_input_poll_t input_poll_cb; +static retro_input_state_t input_state_cb; +static retro_audio_sample_batch_t audio_batch_cb; +static retro_environment_t environ_cb; + +static const char fallback_log_fmt[] = "libretro: "; + +static void fallback_log(enum retro_log_level level, const char *fmt, ...) +{ + (void)level; + va_list va; + fprintf(stderr, "%s", fallback_log_fmt); + va_start(va, fmt); + vfprintf(stderr, fmt, va); + va_end(va); +} + +static Runner* g_runner = nullptr; +static Renderer* g_renderer = nullptr; +static OverlayFileSystem* g_overlayFs = nullptr; +static VMContext* g_vm = nullptr; +static DataWin* g_dataWin = nullptr; +static Gen8* g_gen8 = nullptr; + +static int32_t fbWidth = 640; +static int32_t fbHeight = 480; +static double lastFrameStartTime = 0.0; + +enum GraphicsAPI gfx = SOFTWARE; +InputRecording* globalInputRecording = nullptr; + +static uint32_t* nextFb = nullptr; +static int nextFbW = 0; +static int nextFbH = 0; + +void Runner_setNextFrame(uint32_t* framebuffer, int width, int height) +{ + nextFb = framebuffer; + nextFbW = width; + nextFbH = height; +} + +bool platformInit(int32_t reqW, int32_t reqH, const char* title, bool headless) +{ + (void)title; (void)headless; + fbWidth = reqW; + fbHeight = reqH; + return true; +} + +static bool always_true(void) { return true; } + +void platformInitFunctions(Runner* runner) +{ + g_runner = runner; + runner->windowHasFocus = always_true; +} + +void platformExit(void) {} + +void platformSwapBuffers(void) {} + +void* platformGetProcAddress(const char* name) { (void)name; return nullptr; } + +double platformGetTime(void) +{ + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (double)ts.tv_sec + (double)ts.tv_nsec / 1000000000.0; +} + +bool platformHandleEvents(void) { return false; } + +void platformGetMousePos(double* xPos, double* yPos) +{ + if (xPos) *xPos = 0; + if (yPos) *yPos = 0; +} + +bool platformGetWindowSize(int32_t* outW, int32_t* outH) +{ + if (outW) *outW = fbWidth; + if (outH) *outH = fbHeight; + return true; +} + +bool platformGetScaledWindowSize(int32_t* outW, int32_t* outH) +{ + return platformGetWindowSize(outW, outH); +} + +void platformSetWindowSize(int32_t width, int32_t height) +{ + if (width <= 0 || height <= 0) return; + fbWidth = width; + fbHeight = height; +} + +void platformSetWindowTitle(const char* title) { (void)title; } + +void platformSleepUntil(uint64_t time) { (void)time; } + +static int retroKeyToGml(unsigned key) +{ + if (key >= RETROK_a && key <= RETROK_z) return key - 32; + if (key >= RETROK_0 && key <= RETROK_9) return key; + switch (key) + { + case RETROK_ESCAPE: return VK_ESCAPE; + case RETROK_RETURN: return VK_ENTER; + case RETROK_TAB: return VK_TAB; + case RETROK_BACKSPACE: return VK_BACKSPACE; + case RETROK_SPACE: return VK_SPACE; + case RETROK_LSHIFT: + case RETROK_RSHIFT: return VK_SHIFT; + case RETROK_LCTRL: + case RETROK_RCTRL: return VK_CONTROL; + case RETROK_LALT: + case RETROK_RALT: return VK_ALT; + case RETROK_UP: return VK_UP; + case RETROK_DOWN: return VK_DOWN; + case RETROK_LEFT: return VK_LEFT; + case RETROK_RIGHT: return VK_RIGHT; + case RETROK_F1: return VK_F1; + case RETROK_F2: return VK_F2; + case RETROK_F3: return VK_F3; + case RETROK_F4: return VK_F4; + case RETROK_F5: return VK_F5; + case RETROK_F6: return VK_F6; + case RETROK_F7: return VK_F7; + case RETROK_F8: return VK_F8; + case RETROK_F9: return VK_F9; + case RETROK_F10: return VK_F10; + case RETROK_F11: return VK_F11; + case RETROK_F12: return VK_F12; + case RETROK_INSERT: return VK_INSERT; + case RETROK_DELETE: return VK_DELETE; + case RETROK_HOME: return VK_HOME; + case RETROK_END: return VK_END; + case RETROK_PAGEUP: return VK_PAGEUP; + case RETROK_PAGEDOWN: return VK_PAGEDOWN; + default: return -1; + } +} + +static void keyboard_cb(bool down, unsigned keycode, uint32_t character, uint16_t key_modifiers) +{ + (void)key_modifiers; + if (!g_runner) return; + int gml = retroKeyToGml(keycode); + if (gml < 0) return; + if (down) + RunnerKeyboard_onKeyDown(g_runner->keyboard, gml); + else + RunnerKeyboard_onKeyUp(g_runner->keyboard, gml); + if (down && character != 0) + RunnerKeyboard_onCharacter(g_runner->keyboard, character); +} + +static int prev_mouse_buttons[3] = {0}; +static int16_t prev_mouse_x = 0; +static int16_t prev_mouse_y = 0; + +// RetroArch button ID → GamepadSlot::buttonDown index +static const int retro_id_to_gp_idx[] = { + [RETRO_DEVICE_ID_JOYPAD_B] = 0, // GP_FACE1 + [RETRO_DEVICE_ID_JOYPAD_A] = 1, // GP_FACE2 + [RETRO_DEVICE_ID_JOYPAD_X] = 2, // GP_FACE3 + [RETRO_DEVICE_ID_JOYPAD_Y] = 3, // GP_FACE4 + [RETRO_DEVICE_ID_JOYPAD_L] = 4, // GP_SHOULDERL + [RETRO_DEVICE_ID_JOYPAD_R] = 5, // GP_SHOULDERR + [RETRO_DEVICE_ID_JOYPAD_L2] = 6, // GP_SHOULDERLB + [RETRO_DEVICE_ID_JOYPAD_R2] = 7, // GP_SHOULDERRB + [RETRO_DEVICE_ID_JOYPAD_SELECT] = 8, // GP_SELECT + [RETRO_DEVICE_ID_JOYPAD_START] = 9, // GP_START + [RETRO_DEVICE_ID_JOYPAD_L3] = 10, // GP_STICKL + [RETRO_DEVICE_ID_JOYPAD_R3] = 11, // GP_STICKR + [RETRO_DEVICE_ID_JOYPAD_UP] = 12, // GP_PADU + [RETRO_DEVICE_ID_JOYPAD_DOWN] = 13, // GP_PADD + [RETRO_DEVICE_ID_JOYPAD_LEFT] = 14, // GP_PADL + [RETRO_DEVICE_ID_JOYPAD_RIGHT] = 15, // GP_PADR +}; +static bool prev_gp_down[GP_BUTTON_COUNT] = {0}; + +static void pump_mouse(void) +{ + // Absolute pointer (touch / mouse emulation) + int16_t px = input_state_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X); + int16_t py = input_state_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_Y); + if (px != prev_mouse_x || py != prev_mouse_y) + { + prev_mouse_x = px; + prev_mouse_y = py; + } + + // Mouse buttons via pointer pressed + int ptr_btn = 0; + while (input_state_cb(0, RETRO_DEVICE_POINTER, ptr_btn, RETRO_DEVICE_ID_POINTER_PRESSED)) + ptr_btn++; + + // Mouse buttons via RETRO_DEVICE_MOUSE + int16_t mb_left = input_state_cb(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_LEFT); + int16_t mb_right = input_state_cb(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_RIGHT); + int16_t mb_middle = input_state_cb(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_MIDDLE); + int pressed = mb_left ? 1 : (mb_right ? 2 : (mb_middle ? 3 : ptr_btn)); + + if (pressed != prev_mouse_buttons[0]) + { + prev_mouse_buttons[0] = pressed; + if (pressed) + RunnerMouse_onButtonDown(g_runner->mouse, pressed); + else + RunnerMouse_onButtonUp(g_runner->mouse, prev_mouse_buttons[0] ? prev_mouse_buttons[0] : 1); + } +} + +static void pump_gamepad(void) +{ + GamepadSlot* slot = &g_runner->gamepads->slots[0]; + GamepadSlot prev; + memcpy(&prev, slot, sizeof(prev)); + + slot->connected = true; + g_runner->gamepads->connectedCount++; + slot->deadzone = 0.15f; + slot->triggerThreshold = 0.5f; + strcpy(slot->description, "RetroPad"); + strcpy(slot->guid, "retroarch"); + + // Buttons + for (int i = 0; i < 16; i++) + { + int idx = retro_id_to_gp_idx[i]; + bool down = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, i); + slot->buttonDown[idx] = down; + slot->buttonValue[idx] = down ? 1.0f : 0.0f; + } + + // Analog sticks + slot->axisValue[0] = (float)input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X) / 32767.0f; + slot->axisValue[1] = (float)input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y) / 32767.0f; + slot->axisValue[2] = (float)input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X) / 32767.0f; + slot->axisValue[3] = (float)input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y) / 32767.0f; + + // Pressed / Released from diff with previous + for (int i = 0; i < GP_BUTTON_COUNT; i++) + { + slot->buttonPressed[i] = slot->buttonDown[i] && !prev_gp_down[i]; + slot->buttonReleased[i] = !slot->buttonDown[i] && prev_gp_down[i]; + prev_gp_down[i] = slot->buttonDown[i]; + } +} + +// === libretro entry points === + +unsigned retro_api_version(void) +{ + return RETRO_API_VERSION; +} + +void retro_set_environment(retro_environment_t cb) +{ + environ_cb = cb; + struct retro_log_callback log; + if (environ_cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &log)) + log_cb = log.log; +} + +void retro_set_video_refresh(retro_video_refresh_t cb) +{ + video_cb = cb; +} + +void retro_set_audio_sample(retro_audio_sample_t cb) { (void)cb; } + +void retro_set_audio_sample_batch(retro_audio_sample_batch_t cb) +{ + audio_batch_cb = cb; +} + +void retro_set_input_poll(retro_input_poll_t cb) +{ + input_poll_cb = cb; +} + +void retro_set_input_state(retro_input_state_t cb) +{ + input_state_cb = cb; +} + +void retro_get_system_info(struct retro_system_info *info) +{ + info->need_fullpath = true; + info->valid_extensions = "win|exe|unx|game"; + info->library_version = "0.1"; + info->library_name = "butterscotch"; + info->block_extract = false; +} + +void retro_get_system_av_info(struct retro_system_av_info *info) +{ + info->geometry.base_width = 640; + info->geometry.base_height = 480; + info->geometry.max_width = 1920; + info->geometry.max_height = 1080; + info->geometry.aspect_ratio = 0.0f; + info->timing.fps = 60.0; + info->timing.sample_rate = 44100.0; +} + +void retro_init(void) +{ + enum retro_pixel_format pixfmt = RETRO_PIXEL_FORMAT_XRGB8888; + environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &pixfmt); +} + +void retro_deinit(void) +{ +} + +bool retro_load_game(const struct retro_game_info *game) +{ + if (!game) return false; + + // --- Parse data.win --- + DataWinParserOptions opts = {0}; + opts.parseGen8 = true; + opts.parseOptn = true; + opts.parseLang = true; + opts.parseExtn = true; + opts.parseSond = true; + opts.parseAgrp = true; + opts.parseSprt = true; + opts.parseBgnd = true; + opts.parsePath = true; + opts.parseScpt = true; + opts.parseGlob = true; + opts.parseShdr = true; + opts.parseFont = true; + opts.parseTmln = true; + opts.parseObjt = true; + opts.parseRoom = true; + opts.parseTpag = true; + opts.parseCode = true; + opts.parseVari = true; + opts.parseFunc = true; + opts.parseStrg = true; + opts.parseTxtr = true; + opts.parseAudo = true; + opts.skipLoadingPreciseMasksForNonPreciseSprites = true; + opts.loadType = DATAWINLOADTYPE_LOAD_IN_MEMORY_AHEAD_OF_TIME; + + g_dataWin = DataWin_parse(game->path, opts); + if (!g_dataWin) + { + log_cb(RETRO_LOG_ERROR, "Failed to parse data.win from %s\n", game->path); + return false; + } + + g_gen8 = &g_dataWin->gen8; + log_cb(RETRO_LOG_INFO, "Loaded \"%s\" (%d) [WAD %u / GM %u.%u.%u.%u]\n", + g_gen8->name, g_gen8->gameID, g_gen8->wadVersion, + g_dataWin->detectedFormat.major, g_dataWin->detectedFormat.minor, + g_dataWin->detectedFormat.release, g_dataWin->detectedFormat.build); + + g_vm = VM_create(g_dataWin); + + const char* lastSlash = strrchr(game->path, '/'); + const char* lastBackslash = strrchr(game->path, '\\'); + if (lastBackslash && (!lastSlash || lastBackslash > lastSlash)) + lastSlash = lastBackslash; + + char* dataWinDir; + if (lastSlash) + { + size_t len = (size_t)(lastSlash - game->path + 1); + dataWinDir = (char*)safeMalloc(len + 1); + memcpy(dataWinDir, game->path, len); + dataWinDir[len] = '\0'; + } + else + { + dataWinDir = safeStrdup("./"); + } + + g_overlayFs = OverlayFileSystem_create(dataWinDir, dataWinDir); + free(dataWinDir); + + fbWidth = g_gen8->defaultWindowWidth > 0 ? (int32_t)g_gen8->defaultWindowWidth : 640; + fbHeight = g_gen8->defaultWindowHeight > 0 ? (int32_t)g_gen8->defaultWindowHeight : 480; + + g_renderer = SWRenderer_create(); + if (!g_renderer) + { + log_cb(RETRO_LOG_ERROR, "Failed to create software renderer\n"); + return false; + } + + AudioSystem* audio = (AudioSystem*)NoopAudioSystem_create(); + + g_runner = Runner_create(g_dataWin, g_vm, g_renderer, (FileSystem*)g_overlayFs, audio); + g_runner->osType = OS_WINDOWS; + g_runner->setWindowSize = platformSetWindowSize; + g_runner->getWindowSize = platformGetWindowSize; + g_runner->setWindowTitle = platformSetWindowTitle; + platformInitFunctions(g_runner); + + Runner_initFirstRoom(g_runner); + + lastFrameStartTime = platformGetTime(); + + Dl_info dl; + if (dladdr((void*)retro_init, &dl) && dl.dli_fname) + { + char core_path[4096]; + strncpy(core_path, dl.dli_fname, sizeof(core_path) - 1); + core_path[sizeof(core_path) - 1] = '\0'; + char* p = strrchr(core_path, '/'); + if (p) + { + *p = '\0'; + chdir(core_path); + } + } + + struct retro_keyboard_callback kbcb = { .callback = keyboard_cb }; + environ_cb(RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK, &kbcb); + + return true; +} + +bool retro_load_game_special(unsigned game_type, const struct retro_game_info *info, size_t num_info) +{ + (void)game_type; (void)info; (void)num_info; + return false; +} + +void retro_unload_game(void) +{ + if (g_runner) + { + g_runner->audioSystem->vtable->destroy(g_runner->audioSystem); + g_renderer->vtable->destroy(g_renderer); + Runner_free(g_runner); + g_runner = nullptr; + } + if (g_overlayFs) + { + OverlayFileSystem_destroy(g_overlayFs); + g_overlayFs = nullptr; + } + if (g_vm) + { + VM_free(g_vm); + g_vm = nullptr; + } + if (g_dataWin) + { + DataWin_free(g_dataWin); + g_dataWin = nullptr; + } + g_renderer = nullptr; + g_gen8 = nullptr; + nextFb = nullptr; +} + +void retro_reset(void) +{ + Runner_reset(g_runner); +} + +void retro_run(void) +{ + if (!g_runner) return; + + double now = platformGetTime(); + g_runner->deltaTime = (now - lastFrameStartTime) * 1000000.0; + lastFrameStartTime = now; + + RunnerKeyboard_beginFrame(g_runner->keyboard); + RunnerGamepad_beginFrame(g_runner->gamepads); + RunnerMouse_beginFrame(g_runner->mouse); + + input_poll_cb(); + pump_gamepad(); + pump_mouse(); + + Runner_step(g_runner); + + float dt = (float)(g_runner->deltaTime / 1000000.0); + if (dt < 0.0f) dt = 0.0f; + if (dt > 0.1f) dt = 0.1f; + g_runner->audioSystem->vtable->update(g_runner->audioSystem, dt); + + int32_t gameW, gameH; + if (g_runner->appSurfaceEnabled) + { + if (g_runner->applicationWidth <= 0 || g_runner->applicationHeight <= 0) + { + g_runner->applicationWidth = (int32_t)g_gen8->defaultWindowWidth; + g_runner->applicationHeight = (int32_t)g_gen8->defaultWindowHeight; + } + gameW = g_runner->applicationWidth; + gameH = g_runner->applicationHeight; + } + else + { + g_runner->applicationWidth = fbWidth; + g_runner->applicationHeight = fbHeight; + gameW = fbWidth; + gameH = fbHeight; + } + + g_runner->renderGameW = gameW; + g_runner->renderGameH = gameH; + + int32_t winW, winH; + platformGetScaledWindowSize(&winW, &winH); + int32_t scaledW, scaledH; + if ((gameW * winH) / gameH < winW) + { + scaledW = (gameW * winH) / gameH; + scaledH = winH; + } + else + { + scaledW = winW; + scaledH = (gameH * winW) / gameW; + } + g_runner->viewportX = (winW - scaledW) / 2; + g_runner->viewportY = (winH - scaledH) / 2; + g_runner->viewportW = scaledW; + g_runner->viewportH = scaledH; + + int mx = 0, my = 0; + int16_t rx = input_state_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X); + int16_t ry = input_state_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_Y); + mx = (int)((int64_t)(rx + 0x7fff) * fbWidth / 0xFFFF); + my = (int)((int64_t)(ry + 0x7fff) * fbHeight / 0xFFFF); + Runner_updateMousePosition(g_runner, winW, winH, (double)mx, (double)my); + + + float displayScaleX, displayScaleY; + Runner_computeViewDisplayScale(g_runner, gameW, gameH, &displayScaleX, &displayScaleY); + + Runner_drawPre(g_runner, fbWidth, fbHeight); + Runner_beginFrame(g_runner, gameW, gameH, fbWidth, fbHeight); + if (g_runner->drawBackgroundColor) + SWRenderer_clearFrameBuffer(g_renderer, g_runner->backgroundColor); + else + SWRenderer_clearFrameBuffer(g_renderer, 0); + + Runner_drawViews(g_runner, gameW, gameH, displayScaleX, displayScaleY, false); + g_renderer->vtable->endFrameInit(g_renderer); + Runner_drawPost(g_runner, fbWidth, fbHeight); + g_renderer->vtable->endFrameEnd(g_renderer); + Runner_drawGUI(g_runner, fbWidth, fbHeight, gameW, gameH); + + if (nextFb) + video_cb(nextFb, nextFbW, nextFbH, nextFbW * (int)sizeof(uint32_t)); + + Runner_handlePendingRoomChange(g_runner); +} + +void retro_set_controller_port_device(unsigned port, unsigned device) +{ + (void)port; (void)device; +} + +size_t retro_serialize_size(void) { return 0; } +bool retro_serialize(void *data, size_t size) { (void)data; (void)size; return false; } +bool retro_unserialize(const void *data, size_t size) { (void)data; (void)size; return false; } +void retro_cheat_reset(void) {} +void retro_cheat_set(unsigned index, bool enabled, const char *code) { (void)index; (void)enabled; (void)code; } +unsigned retro_get_region(void) { return RETRO_REGION_NTSC; } +void *retro_get_memory_data(unsigned id) { (void)id; return nullptr; } +size_t retro_get_memory_size(unsigned id) { (void)id; return 0; } diff --git a/src/libretro/libretro.h b/src/libretro/libretro.h new file mode 100644 index 000000000..b0948cdeb --- /dev/null +++ b/src/libretro/libretro.h @@ -0,0 +1,7978 @@ +/*! + * libretro.h is a simple API that allows for the creation of games and emulators. + * + * @file libretro.h + * @version 1 + * @author libretro + * @copyright Copyright (C) 2010-2024 The RetroArch team + * + * @paragraph LICENSE + * The following license statement only applies to this libretro API header (libretro.h). + * + * Copyright (C) 2010-2024 The RetroArch team + * + * Permission is hereby granted, free of charge, + * 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: + * + * 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, + * 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. + */ + +#ifndef LIBRETRO_H__ +#define LIBRETRO_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __cplusplus +#if defined(_MSC_VER) && _MSC_VER < 1800 && !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 +#else +#include +#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 +# define RETRO_API RETRO_CALLCONV __attribute__((__visibility__("default"))) +# else +# define RETRO_API RETRO_CALLCONV +# endif +# endif +#endif + +/** + * The major version of the libretro API and ABI. + * Cores may support multiple versions, + * or they may reject cores with unsupported versions. + * It is only incremented for incompatible API/ABI changes; + * this generally implies a function was removed or changed, + * or that a \c struct had fields removed or changed. + * @note A design goal of libretro is to avoid having to increase this value at all costs. + * This is why there are APIs that are "extended" or "V2". + */ +#define RETRO_API_VERSION 1 + +/** + * @defgroup RETRO_DEVICE Input Devices + * @brief Libretro's fundamental device abstractions. + * + * Libretro's input system consists of abstractions over standard device types, + * such as a joypad (with or without analog), mouse, keyboard, light gun, or an abstract pointer. + * Instead of managing input devices themselves, + * cores need only to map their own concept of a controller to libretro's abstractions. + * This makes it possible for frontends to map the abstract types to a real input device + * without having to worry about the correct use of arbitrary (real) controller layouts. + * @{ + */ + +#define RETRO_DEVICE_TYPE_SHIFT 8 +#define RETRO_DEVICE_MASK ((1 << RETRO_DEVICE_TYPE_SHIFT) - 1) + +/** + * Defines an ID for a subclass of a known device type. + * + * To define a subclass ID, use this macro like so: + * @code{c} + * #define RETRO_DEVICE_SUPER_SCOPE RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_LIGHTGUN, 1) + * #define RETRO_DEVICE_JUSTIFIER RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_LIGHTGUN, 2) + * @endcode + * + * Correct use of this macro allows a frontend to select a suitable physical device + * to map to the emulated device. + * + * @note Cores must use the base ID when polling for input, + * and frontends must only accept the base ID for this purpose. + * Polling for input using subclass IDs is reserved for future definition. + * + * @param base One of the \ref RETRO_DEVICE "base device types". + * @param id A unique ID, with respect to \c base. + * Must be a non-negative integer. + * @return A unique subclass ID. + * @see retro_controller_description + * @see retro_set_controller_port_device + */ +#define RETRO_DEVICE_SUBCLASS(base, id) (((id + 1) << RETRO_DEVICE_TYPE_SHIFT) | base) + +/** + * @defgroup RETRO_DEVICE Input Device Classes + * @{ + */ + +/** + * Indicates no input. + * + * When provided as the \c device argument to \c retro_input_state_t, + * all other arguments are ignored and zero is returned. + * + * @see retro_input_state_t + */ +#define RETRO_DEVICE_NONE 0 + +/** + * An abstraction around a game controller, known as a "RetroPad". + * + * The RetroPad is modelled after a SNES controller, + * but with additional L2/R2/L3/R3 buttons + * (similar to a PlayStation controller). + * + * When provided as the \c device argument to \c retro_input_state_t, + * the \c id argument denotes the button (including D-Pad directions) to query. + * The result of said query will be 1 if the button is down, 0 if not. + * + * There is one exception; if \c RETRO_DEVICE_ID_JOYPAD_MASK is queried + * (and the frontend supports this query), + * the result will be a bitmask of all pressed buttons. + * + * @see retro_input_state_t + * @see RETRO_DEVICE_ANALOG + * @see RETRO_DEVICE_ID_JOYPAD + * @see RETRO_DEVICE_ID_JOYPAD_MASK + * @see RETRO_ENVIRONMENT_GET_INPUT_BITMASKS + */ +#define RETRO_DEVICE_JOYPAD 1 + +/** + * An abstraction around a mouse, similar to the SNES Mouse but with more buttons. + * + * When provided as the \c device argument to \c retro_input_state_t, + * the \c id argument denotes the button or axis to query. + * For buttons, the result of said query + * will be 1 if the button is down or 0 if not. + * For mouse wheel axes, the result + * will be 1 if the wheel was rotated in that direction and 0 if not. + * For the mouse pointer axis, the result will be thee mouse's movement + * relative to the last poll. + * The core is responsible for tracking the mouse's position, + * and the frontend is responsible for preventing interference + * by the real hardware pointer (if applicable). + * + * @note This should only be used for cores that emulate mouse input, + * such as for home computers + * or consoles with mouse attachments. + * Cores that emulate light guns should use \c RETRO_DEVICE_LIGHTGUN, + * and cores that emulate touch screens should use \c RETRO_DEVICE_POINTER. + * + * @see RETRO_DEVICE_POINTER + * @see RETRO_DEVICE_LIGHTGUN + */ +#define RETRO_DEVICE_MOUSE 2 + +/** + * An abstraction around a keyboard. + * + * When provided as the \c device argument to \c retro_input_state_t, + * the \c id argument denotes the key to poll. + * + * @note This should only be used for cores that emulate keyboard input, + * such as for home computers + * or consoles with keyboard attachments. + * Cores that emulate gamepads should use \c RETRO_DEVICE_JOYPAD or \c RETRO_DEVICE_ANALOG, + * and leave keyboard compatibility to the frontend. + * + * @see RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK + * @see retro_key + */ +#define RETRO_DEVICE_KEYBOARD 3 + +/** + * An abstraction around a light gun, similar to the PlayStation's Guncon. + * + * When provided as the \c device argument to \c retro_input_state_t, + * the \c id argument denotes one of several possible inputs. + * + * The gun's coordinates are reported in screen space (similar to the pointer) + * in the range of [-0x8000, 0x7fff]. + * Zero is the center of the game's screen + * and -0x8000 represents out-of-bounds. + * The trigger and various auxiliary buttons are also reported. + * + * @note A forced off-screen shot can be requested for auto-reloading + * function in some games. + * + * @see RETRO_DEVICE_POINTER + */ +#define RETRO_DEVICE_LIGHTGUN 4 + +/** + * An extension of the RetroPad that supports analog input. + * + * The analog RetroPad provides two virtual analog sticks (similar to DualShock controllers) + * and allows any button to be treated as analog (similar to Xbox shoulder triggers). + * + * When provided as the \c device argument to \c retro_input_state_t, + * the \c id argument denotes an analog axis or an analog button. + * + * Analog axes are reported in the range of [-0x8000, 0x7fff], + * with the X axis being positive towards the right + * and the Y axis being positive towards the bottom. + * + * Analog buttons are reported in the range of [0, 0x7fff], + * where 0 is unpressed and 0x7fff is fully pressed. + * + * @note Cores should only use this type if they need analog input. + * Otherwise, \c RETRO_DEVICE_JOYPAD should be used. + * @see RETRO_DEVICE_JOYPAD + */ +#define RETRO_DEVICE_ANALOG 5 + +/** + * Input Device: Pointer. + * + * Abstracts the concept of a pointing mechanism, e.g. touch. + * This allows libretro to query in absolute coordinates where on the + * screen a mouse (or something similar) is being placed. + * For a touch centric device, coordinates reported are the coordinates + * of the press. + * + * Coordinates in X and Y are reported as: + * [-0x7fff, 0x7fff]: -0x7fff corresponds to the far left/top of the screen, + * and 0x7fff corresponds to the far right/bottom of the screen. + * The "screen" is here defined as area that is passed to the frontend and + * later displayed on the monitor. If the pointer is outside this screen, + * such as in the black surrounding areas when actual display is larger, + * edge position is reported. An explicit edge detection is also provided, + * that will return 1 if the pointer is near the screen edge or actually outside it. + * + * The frontend is free to scale/resize this screen as it sees fit, however, + * (X, Y) = (-0x7fff, -0x7fff) will correspond to the top-left pixel of the + * game image, etc. + * + * To check if the pointer coordinates are valid (e.g. a touch display + * actually being touched), \c RETRO_DEVICE_ID_POINTER_PRESSED returns 1 or 0. + * + * If using a mouse on a desktop, \c RETRO_DEVICE_ID_POINTER_PRESSED will + * usually correspond to the left mouse button, but this is a frontend decision. + * \c RETRO_DEVICE_ID_POINTER_PRESSED will only return 1 if the pointer is + * inside the game screen. + * + * For multi-touch, the index variable can be used to successively query + * more presses. + * If index = 0 returns true for \c _PRESSED, coordinates can be extracted + * with \c _X, \c _Y for index = 0. One can then query \c _PRESSED, \c _X, \c _Y with + * index = 1, and so on. + * Eventually \c _PRESSED will return false for an index. No further presses + * are registered at this point. + * + * @see RETRO_DEVICE_MOUSE + * @see RETRO_DEVICE_ID_POINTER_X + * @see RETRO_DEVICE_ID_POINTER_Y + * @see RETRO_DEVICE_ID_POINTER_PRESSED + */ +#define RETRO_DEVICE_POINTER 6 + +/** @} */ + +/** @defgroup RETRO_DEVICE_ID_JOYPAD RetroPad Input + * @brief Digital buttons for the RetroPad. + * + * Button placement is comparable to that of a SNES controller, + * combined with the shoulder buttons of a PlayStation controller. + * These values can also be used for the \c id field of \c RETRO_DEVICE_INDEX_ANALOG_BUTTON + * to represent analog buttons (usually shoulder triggers). + * @{ + */ + +/** The equivalent of the SNES controller's south face button. */ +#define RETRO_DEVICE_ID_JOYPAD_B 0 + +/** The equivalent of the SNES controller's west face button. */ +#define RETRO_DEVICE_ID_JOYPAD_Y 1 + +/** The equivalent of the SNES controller's left-center button. */ +#define RETRO_DEVICE_ID_JOYPAD_SELECT 2 + +/** The equivalent of the SNES controller's right-center button. */ +#define RETRO_DEVICE_ID_JOYPAD_START 3 + +/** Up on the RetroPad's D-pad. */ +#define RETRO_DEVICE_ID_JOYPAD_UP 4 + +/** Down on the RetroPad's D-pad. */ +#define RETRO_DEVICE_ID_JOYPAD_DOWN 5 + +/** Left on the RetroPad's D-pad. */ +#define RETRO_DEVICE_ID_JOYPAD_LEFT 6 + +/** Right on the RetroPad's D-pad. */ +#define RETRO_DEVICE_ID_JOYPAD_RIGHT 7 + +/** The equivalent of the SNES controller's east face button. */ +#define RETRO_DEVICE_ID_JOYPAD_A 8 + +/** The equivalent of the SNES controller's north face button. */ +#define RETRO_DEVICE_ID_JOYPAD_X 9 + +/** The equivalent of the SNES controller's left shoulder button. */ +#define RETRO_DEVICE_ID_JOYPAD_L 10 + +/** The equivalent of the SNES controller's right shoulder button. */ +#define RETRO_DEVICE_ID_JOYPAD_R 11 + +/** The equivalent of the PlayStation's rear left shoulder button. */ +#define RETRO_DEVICE_ID_JOYPAD_L2 12 + +/** The equivalent of the PlayStation's rear right shoulder button. */ +#define RETRO_DEVICE_ID_JOYPAD_R2 13 + +/** + * The equivalent of the PlayStation's left analog stick button, + * although the actual button need not be in this position. + */ +#define RETRO_DEVICE_ID_JOYPAD_L3 14 + +/** + * The equivalent of the PlayStation's right analog stick button, + * although the actual button need not be in this position. + */ +#define RETRO_DEVICE_ID_JOYPAD_R3 15 + +/** + * Represents a bitmask that describes the state of all \c RETRO_DEVICE_ID_JOYPAD button constants, + * rather than the state of a single button. + * + * @see RETRO_ENVIRONMENT_GET_INPUT_BITMASKS + * @see RETRO_DEVICE_JOYPAD + */ +#define RETRO_DEVICE_ID_JOYPAD_MASK 256 + +/** @} */ + +/** @defgroup RETRO_DEVICE_ID_ANALOG Analog RetroPad Input + * @{ + */ + +/* Index / Id values for ANALOG device. */ +#define RETRO_DEVICE_INDEX_ANALOG_LEFT 0 +#define RETRO_DEVICE_INDEX_ANALOG_RIGHT 1 +#define RETRO_DEVICE_INDEX_ANALOG_BUTTON 2 +#define RETRO_DEVICE_ID_ANALOG_X 0 +#define RETRO_DEVICE_ID_ANALOG_Y 1 + +/** @} */ + +/* Id values for MOUSE. */ +#define RETRO_DEVICE_ID_MOUSE_X 0 +#define RETRO_DEVICE_ID_MOUSE_Y 1 +#define RETRO_DEVICE_ID_MOUSE_LEFT 2 +#define RETRO_DEVICE_ID_MOUSE_RIGHT 3 +#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 +#define RETRO_DEVICE_ID_MOUSE_BUTTON_4 9 +#define RETRO_DEVICE_ID_MOUSE_BUTTON_5 10 + +/* Id values for LIGHTGUN. */ +#define RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X 13 /*Absolute Position*/ +#define RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y 14 /*Absolute Position*/ +/** Indicates if lightgun points off the screen or near the edge */ +#define RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN 15 /*Status Check*/ +#define RETRO_DEVICE_ID_LIGHTGUN_TRIGGER 2 +#define RETRO_DEVICE_ID_LIGHTGUN_RELOAD 16 /*Forced off-screen shot*/ +#define RETRO_DEVICE_ID_LIGHTGUN_AUX_A 3 +#define RETRO_DEVICE_ID_LIGHTGUN_AUX_B 4 +#define RETRO_DEVICE_ID_LIGHTGUN_START 6 +#define RETRO_DEVICE_ID_LIGHTGUN_SELECT 7 +#define RETRO_DEVICE_ID_LIGHTGUN_AUX_C 8 +#define RETRO_DEVICE_ID_LIGHTGUN_DPAD_UP 9 +#define RETRO_DEVICE_ID_LIGHTGUN_DPAD_DOWN 10 +#define RETRO_DEVICE_ID_LIGHTGUN_DPAD_LEFT 11 +#define RETRO_DEVICE_ID_LIGHTGUN_DPAD_RIGHT 12 +/* deprecated */ +#define RETRO_DEVICE_ID_LIGHTGUN_X 0 /*Relative Position*/ +#define RETRO_DEVICE_ID_LIGHTGUN_Y 1 /*Relative Position*/ +#define RETRO_DEVICE_ID_LIGHTGUN_CURSOR 3 /*Use Aux:A instead*/ +#define RETRO_DEVICE_ID_LIGHTGUN_TURBO 4 /*Use Aux:B instead*/ +#define RETRO_DEVICE_ID_LIGHTGUN_PAUSE 5 /*Use Start instead*/ + +/* Id values for POINTER. */ +#define RETRO_DEVICE_ID_POINTER_X 0 +#define RETRO_DEVICE_ID_POINTER_Y 1 +#define RETRO_DEVICE_ID_POINTER_PRESSED 2 +#define RETRO_DEVICE_ID_POINTER_COUNT 3 +/** Indicates if pointer is off the screen or near the edge */ +#define RETRO_DEVICE_ID_POINTER_IS_OFFSCREEN 15 +/** @} */ + +/* Returned from retro_get_region(). */ +#define RETRO_REGION_NTSC 0 +#define RETRO_REGION_PAL 1 + +/** + * Identifiers for supported languages. + * @see RETRO_ENVIRONMENT_GET_LANGUAGE + */ +enum retro_language +{ + RETRO_LANGUAGE_ENGLISH = 0, + RETRO_LANGUAGE_JAPANESE = 1, + RETRO_LANGUAGE_FRENCH = 2, + RETRO_LANGUAGE_SPANISH = 3, + RETRO_LANGUAGE_GERMAN = 4, + RETRO_LANGUAGE_ITALIAN = 5, + RETRO_LANGUAGE_DUTCH = 6, + RETRO_LANGUAGE_PORTUGUESE_BRAZIL = 7, + RETRO_LANGUAGE_PORTUGUESE_PORTUGAL = 8, + RETRO_LANGUAGE_RUSSIAN = 9, + RETRO_LANGUAGE_KOREAN = 10, + RETRO_LANGUAGE_CHINESE_TRADITIONAL = 11, + RETRO_LANGUAGE_CHINESE_SIMPLIFIED = 12, + RETRO_LANGUAGE_ESPERANTO = 13, + RETRO_LANGUAGE_POLISH = 14, + RETRO_LANGUAGE_VIETNAMESE = 15, + RETRO_LANGUAGE_ARABIC = 16, + RETRO_LANGUAGE_GREEK = 17, + RETRO_LANGUAGE_TURKISH = 18, + RETRO_LANGUAGE_SLOVAK = 19, + RETRO_LANGUAGE_PERSIAN = 20, + RETRO_LANGUAGE_HEBREW = 21, + RETRO_LANGUAGE_ASTURIAN = 22, + RETRO_LANGUAGE_FINNISH = 23, + RETRO_LANGUAGE_INDONESIAN = 24, + RETRO_LANGUAGE_SWEDISH = 25, + RETRO_LANGUAGE_UKRAINIAN = 26, + RETRO_LANGUAGE_CZECH = 27, + RETRO_LANGUAGE_CATALAN_VALENCIA = 28, + RETRO_LANGUAGE_CATALAN = 29, + RETRO_LANGUAGE_BRITISH_ENGLISH = 30, + RETRO_LANGUAGE_HUNGARIAN = 31, + RETRO_LANGUAGE_BELARUSIAN = 32, + RETRO_LANGUAGE_GALICIAN = 33, + RETRO_LANGUAGE_NORWEGIAN = 34, + RETRO_LANGUAGE_IRISH = 35, + RETRO_LANGUAGE_THAI = 36, + RETRO_LANGUAGE_LAST, + + /** Defined to ensure that sizeof(retro_language) == sizeof(int). Do not use. */ + RETRO_LANGUAGE_DUMMY = INT_MAX +}; + +/** @defgroup RETRO_MEMORY Memory Types + * @{ + */ + +/* Passed to retro_get_memory_data/size(). + * If the memory type doesn't apply to the + * implementation NULL/0 can be returned. + */ +#define RETRO_MEMORY_MASK 0xff + +/* Regular save RAM. This RAM is usually found on a game cartridge, + * backed up by a battery. + * If save game data is too complex for a single memory buffer, + * the SAVE_DIRECTORY (preferably) or SYSTEM_DIRECTORY environment + * callback can be used. */ +#define RETRO_MEMORY_SAVE_RAM 0 + +/* Some games have a built-in clock to keep track of time. + * This memory is usually just a couple of bytes to keep track of time. + */ +#define RETRO_MEMORY_RTC 1 + +/* System ram lets a frontend peek into a game systems main RAM. */ +#define RETRO_MEMORY_SYSTEM_RAM 2 + +/* Video ram lets a frontend peek into a game systems video RAM (VRAM). */ +#define RETRO_MEMORY_VIDEO_RAM 3 + +/* ROM lets a frontend peek into a game systems ROM. */ +#define RETRO_MEMORY_ROM 4 + +/** @} */ + +/* Keysyms used for ID in input state callback when polling RETRO_KEYBOARD. */ +enum retro_key +{ + RETROK_UNKNOWN = 0, + RETROK_FIRST = 0, + RETROK_BACKSPACE = 8, + RETROK_TAB = 9, + RETROK_CLEAR = 12, + RETROK_RETURN = 13, + RETROK_PAUSE = 19, + RETROK_ESCAPE = 27, + RETROK_SPACE = 32, + RETROK_EXCLAIM = 33, + RETROK_QUOTEDBL = 34, + RETROK_HASH = 35, + RETROK_DOLLAR = 36, + RETROK_AMPERSAND = 38, + RETROK_QUOTE = 39, + RETROK_LEFTPAREN = 40, + RETROK_RIGHTPAREN = 41, + RETROK_ASTERISK = 42, + RETROK_PLUS = 43, + RETROK_COMMA = 44, + RETROK_MINUS = 45, + RETROK_PERIOD = 46, + RETROK_SLASH = 47, + RETROK_0 = 48, + RETROK_1 = 49, + RETROK_2 = 50, + RETROK_3 = 51, + RETROK_4 = 52, + RETROK_5 = 53, + RETROK_6 = 54, + RETROK_7 = 55, + RETROK_8 = 56, + RETROK_9 = 57, + RETROK_COLON = 58, + RETROK_SEMICOLON = 59, + RETROK_LESS = 60, + RETROK_EQUALS = 61, + RETROK_GREATER = 62, + RETROK_QUESTION = 63, + RETROK_AT = 64, + RETROK_LEFTBRACKET = 91, + RETROK_BACKSLASH = 92, + RETROK_RIGHTBRACKET = 93, + RETROK_CARET = 94, + RETROK_UNDERSCORE = 95, + RETROK_BACKQUOTE = 96, + RETROK_a = 97, + RETROK_b = 98, + RETROK_c = 99, + RETROK_d = 100, + RETROK_e = 101, + RETROK_f = 102, + RETROK_g = 103, + RETROK_h = 104, + RETROK_i = 105, + RETROK_j = 106, + RETROK_k = 107, + RETROK_l = 108, + RETROK_m = 109, + RETROK_n = 110, + RETROK_o = 111, + RETROK_p = 112, + RETROK_q = 113, + RETROK_r = 114, + RETROK_s = 115, + RETROK_t = 116, + RETROK_u = 117, + RETROK_v = 118, + RETROK_w = 119, + RETROK_x = 120, + RETROK_y = 121, + RETROK_z = 122, + RETROK_LEFTBRACE = 123, + RETROK_BAR = 124, + RETROK_RIGHTBRACE = 125, + RETROK_TILDE = 126, + RETROK_DELETE = 127, + + RETROK_KP0 = 256, + RETROK_KP1 = 257, + RETROK_KP2 = 258, + RETROK_KP3 = 259, + RETROK_KP4 = 260, + RETROK_KP5 = 261, + RETROK_KP6 = 262, + RETROK_KP7 = 263, + RETROK_KP8 = 264, + RETROK_KP9 = 265, + RETROK_KP_PERIOD = 266, + RETROK_KP_DIVIDE = 267, + RETROK_KP_MULTIPLY = 268, + RETROK_KP_MINUS = 269, + RETROK_KP_PLUS = 270, + RETROK_KP_ENTER = 271, + RETROK_KP_EQUALS = 272, + + RETROK_UP = 273, + RETROK_DOWN = 274, + RETROK_RIGHT = 275, + RETROK_LEFT = 276, + RETROK_INSERT = 277, + RETROK_HOME = 278, + RETROK_END = 279, + RETROK_PAGEUP = 280, + RETROK_PAGEDOWN = 281, + + RETROK_F1 = 282, + RETROK_F2 = 283, + RETROK_F3 = 284, + RETROK_F4 = 285, + RETROK_F5 = 286, + RETROK_F6 = 287, + RETROK_F7 = 288, + RETROK_F8 = 289, + RETROK_F9 = 290, + RETROK_F10 = 291, + RETROK_F11 = 292, + RETROK_F12 = 293, + RETROK_F13 = 294, + RETROK_F14 = 295, + RETROK_F15 = 296, + + RETROK_NUMLOCK = 300, + RETROK_CAPSLOCK = 301, + RETROK_SCROLLOCK = 302, + RETROK_RSHIFT = 303, + RETROK_LSHIFT = 304, + RETROK_RCTRL = 305, + RETROK_LCTRL = 306, + RETROK_RALT = 307, + RETROK_LALT = 308, + RETROK_RMETA = 309, + RETROK_LMETA = 310, + RETROK_LSUPER = 311, + RETROK_RSUPER = 312, + RETROK_MODE = 313, + RETROK_COMPOSE = 314, + + RETROK_HELP = 315, + RETROK_PRINT = 316, + RETROK_SYSREQ = 317, + RETROK_BREAK = 318, + RETROK_MENU = 319, + RETROK_POWER = 320, + RETROK_EURO = 321, + RETROK_UNDO = 322, + RETROK_OEM_102 = 323, + + RETROK_BROWSER_BACK = 324, + RETROK_BROWSER_FORWARD = 325, + RETROK_BROWSER_REFRESH = 326, + RETROK_BROWSER_STOP = 327, + RETROK_BROWSER_SEARCH = 328, + RETROK_BROWSER_FAVORITES = 329, + RETROK_BROWSER_HOME = 330, + RETROK_VOLUME_MUTE = 331, + RETROK_VOLUME_DOWN = 332, + RETROK_VOLUME_UP = 333, + RETROK_MEDIA_NEXT = 334, + RETROK_MEDIA_PREV = 335, + RETROK_MEDIA_STOP = 336, + RETROK_MEDIA_PLAY_PAUSE = 337, + RETROK_LAUNCH_MAIL = 338, + RETROK_LAUNCH_MEDIA = 339, + RETROK_LAUNCH_APP1 = 340, + RETROK_LAUNCH_APP2 = 341, + + RETROK_LAST, + + RETROK_DUMMY = INT_MAX /* Ensure sizeof(enum) == sizeof(int) */ +}; + +enum retro_mod +{ + RETROKMOD_NONE = 0x0000, + + RETROKMOD_SHIFT = 0x01, + RETROKMOD_CTRL = 0x02, + RETROKMOD_ALT = 0x04, + RETROKMOD_META = 0x08, + + RETROKMOD_NUMLOCK = 0x10, + RETROKMOD_CAPSLOCK = 0x20, + RETROKMOD_SCROLLOCK = 0x40, + + RETROKMOD_DUMMY = INT_MAX /* Ensure sizeof(enum) == sizeof(int) */ +}; + +/** + * @defgroup RETRO_ENVIRONMENT Environment Callbacks + * @{ + */ + +/** + * This bit indicates that the associated environment call is experimental, + * and may be changed or removed in the future. + * Frontends should mask out this bit before handling the environment call. + */ +#define RETRO_ENVIRONMENT_EXPERIMENTAL 0x10000 + +/** Frontend-internal environment callbacks should include this bit. */ +#define RETRO_ENVIRONMENT_PRIVATE 0x20000 + +/* Environment commands. */ +/** + * Requests the frontend to set the screen rotation. + * + * @param[in] data const unsigned*. + * Valid values are 0, 1, 2, and 3. + * These numbers respectively set the screen rotation to 0, 90, 180, and 270 degrees counter-clockwise. + * @returns \c true if the screen rotation was set successfully. + */ +#define RETRO_ENVIRONMENT_SET_ROTATION 1 + +/** + * Queries whether the core should use overscan or not. + * + * @param[out] data bool*. + * Set to \c true if the core should use overscan, + * \c false if it should be cropped away. + * @returns \c true if the environment call is available. + * Does \em not indicate whether overscan should be used. + * @deprecated As of 2019 this callback is considered deprecated in favor of + * using core options to manage overscan in a more nuanced, core-specific way. + */ +#define RETRO_ENVIRONMENT_GET_OVERSCAN 2 + +/** + * Queries whether the frontend supports frame duping, + * in the form of passing \c NULL to the video frame callback. + * + * @param[out] data bool*. + * Set to \c true if the frontend supports frame duping. + * @returns \c true if the environment call is available. + * @see retro_video_refresh_t + */ +#define RETRO_ENVIRONMENT_GET_CAN_DUPE 3 + +/* + * Environ 4, 5 are no longer supported (GET_VARIABLE / SET_VARIABLES), + * and reserved to avoid possible ABI clash. + */ + +/** + * @brief Displays a user-facing message for a short time. + * + * Use this callback to convey important status messages, + * such as errors or the result of long-running operations. + * For trivial messages or logging, use \c RETRO_ENVIRONMENT_GET_LOG_INTERFACE or \c stderr. + * + * \code{.c} + * void set_message_example(void) + * { + * struct retro_message msg; + * msg.frames = 60 * 5; // 5 seconds + * msg.msg = "Hello world!"; + * + * environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, &msg); + * } + * \endcode + * + * @deprecated Prefer using \c RETRO_ENVIRONMENT_SET_MESSAGE_EXT for new code, + * as it offers more features. + * Only use this environment call for compatibility with older cores or frontends. + * + * @param[in] data const struct retro_message*. + * Details about the message to show to the user. + * Behavior is undefined if NULL. + * @returns \c true if the environment call is available. + * @see retro_message + * @see RETRO_ENVIRONMENT_GET_LOG_INTERFACE + * @see RETRO_ENVIRONMENT_SET_MESSAGE_EXT + * @see RETRO_ENVIRONMENT_SET_MESSAGE + * @see RETRO_ENVIRONMENT_GET_MESSAGE_INTERFACE_VERSION + * @note The frontend must make its own copy of the message and the underlying string. + */ +#define RETRO_ENVIRONMENT_SET_MESSAGE 6 + +/** + * Requests the frontend to shutdown the core. + * Should only be used if the core can exit on its own, + * such as from a menu item in a game + * or an emulated power-off in an emulator. + * + * @param data Ignored. + * @returns \c true if the environment call is available. + */ +#define RETRO_ENVIRONMENT_SHUTDOWN 7 + +/** + * Gives a hint to the frontend of how demanding this core is on the system. + * For example, reporting a level of 2 means that + * this implementation should run decently on frontends + * of level 2 and above. + * + * It can be used by the frontend to potentially warn + * about too demanding implementations. + * + * The levels are "floating". + * + * This function can be called on a per-game basis, + * as a core may have different demands for different games or settings. + * If called, it should be called in retro_load_game(). + * @param[in] data const unsigned*. +*/ +#define RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL 8 + +/** + * Returns the path to the frontend's system directory, + * which can be used to store system-specific configuration + * such as BIOS files or cached data. + * + * @param[out] data const char**. + * Pointer to the \c char* in which the system directory will be saved. + * The string is managed by the frontend and must not be modified or freed by the core. + * May be \c NULL if no system directory is defined, + * in which case the core should find an alternative directory. + * @return \c true if the environment call is available, + * even if the value returned in \c data is NULL. + * @note Historically, some cores would use this folder for save data such as memory cards or SRAM. + * This is now discouraged in favor of \c RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY. + * @see RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY + */ +#define RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY 9 + +/** + * Sets the internal pixel format used by the frontend for rendering. + * The default pixel format is \c RETRO_PIXEL_FORMAT_0RGB1555 for compatibility reasons, + * although it's considered deprecated and shouldn't be used by new code. + * + * @param[in] data const enum retro_pixel_format *. + * Pointer to the pixel format to use. + * @returns \c true if the pixel format was set successfully, + * \c false if it's not supported or this callback is unavailable. + * @note This function should be called inside \c retro_load_game() + * or retro_get_system_av_info(). + * @see retro_pixel_format + */ +#define RETRO_ENVIRONMENT_SET_PIXEL_FORMAT 10 + +/** + * Sets an array of input descriptors for the frontend + * to present to the user for configuring the core's controls. + * + * This function can be called at any time, + * preferably early in the core's life cycle. + * Ideally, no later than \c retro_load_game(). + * + * @param[in] data const struct retro_input_descriptor *. + * An array of input descriptors terminated by one whose + * \c retro_input_descriptor::description field is set to \c NULL. + * Behavior is undefined if \c NULL. + * @return \c true if the environment call is recognized. + * @see retro_input_descriptor + */ +#define RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS 11 + +/** + * Sets a callback function used to notify the core about keyboard events. + * This should only be used for cores that specifically need keyboard input, + * such as for home computer emulators or games with text entry. + * + * @param[in] data const struct retro_keyboard_callback *. + * Pointer to the callback function. + * Behavior is undefined if NULL. + * @return \c true if the environment call is recognized. + * @see retro_keyboard_callback + * @see retro_key + */ +#define RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK 12 + +/** + * Sets an interface that the frontend can use to insert and remove disks + * from the emulated console's disk drive. + * Can be used for optical disks, floppy disks, or any other game storage medium + * that can be swapped at runtime. + * + * This is intended for multi-disk games that expect the player + * to manually swap disks at certain points in the game. + * + * @deprecated Prefer using \c RETRO_ENVIRONMENT_SET_DISK_CONTROL_EXT_INTERFACE + * over this environment call, as it supports additional features. + * Only use this callback to maintain compatibility + * with older cores or frontends. + * + * @param[in] data const struct retro_disk_control_callback *. + * Pointer to the callback functions to use. + * May be \c NULL, in which case the existing disk callback is deregistered. + * @return \c true if this environment call is available, + * even if \c data is \c NULL. + * @see retro_disk_control_callback + * @see RETRO_ENVIRONMENT_SET_DISK_CONTROL_EXT_INTERFACE + */ +#define RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE 13 + +/** + * Requests that a frontend enable a particular hardware rendering API. + * + * If successful, the frontend will create a context (and other related resources) + * that the core can use for rendering. + * The framebuffer will be at least as large as + * the maximum dimensions provided in retro_get_system_av_info. + * + * @param[in, out] data struct retro_hw_render_callback *. + * Pointer to the hardware render callback struct. + * Used to define callbacks for the hardware-rendering life cycle, + * as well as to request a particular rendering API. + * @return \c true if the environment call is recognized + * and the requested rendering API is supported. + * \c false if \c data is \c NULL + * or the frontend can't provide the requested rendering API. + * @see retro_hw_render_callback + * @see retro_video_refresh_t + * @see RETRO_ENVIRONMENT_GET_PREFERRED_HW_RENDER + * @note Should be called in retro_load_game(). + * @note If HW rendering is used, pass only \c RETRO_HW_FRAME_BUFFER_VALID or + * \c NULL to retro_video_refresh_t. + */ +#define RETRO_ENVIRONMENT_SET_HW_RENDER 14 + +/** + * Retrieves a core option's value from the frontend. + * \c retro_variable::key should be set to an option key + * that was previously set in \c RETRO_ENVIRONMENT_SET_VARIABLES + * (or a similar environment call). + * + * @param[in,out] data struct retro_variable *. + * Pointer to a single \c retro_variable struct. + * See the documentation for \c retro_variable for details + * on which fields are set by the frontend or core. + * May be \c NULL. + * @returns \c true if the environment call is available, + * even if \c data is \c NULL or the key it specifies is not found. + * @note Passing \c NULL in to \c data can be useful to + * test for support of this environment call without looking up any variables. + * @see retro_variable + * @see RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2 + * @see RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE + */ +#define RETRO_ENVIRONMENT_GET_VARIABLE 15 + +/** + * Notifies the frontend of the core's available options. + * + * The core may check these options later using \c RETRO_ENVIRONMENT_GET_VARIABLE. + * The frontend may also present these options to the user + * in its own configuration UI. + * + * This should be called the first time as early as possible, + * ideally in \c retro_set_environment. + * The core may later call this function again + * to communicate updated options to the frontend, + * but the number of core options must not change. + * + * Here's an example that sets two options. + * + * @code + * void set_variables_example(void) + * { + * struct retro_variable options[] = { + * { "foo_speedhack", "Speed hack; false|true" }, // false by default + * { "foo_displayscale", "Display scale factor; 1|2|3|4" }, // 1 by default + * { NULL, NULL }, + * }; + * + * environ_cb(RETRO_ENVIRONMENT_SET_VARIABLES, &options); + * } + * @endcode + * + * The possible values will generally be displayed and stored as-is by the frontend. + * + * @deprecated Prefer using \c RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2 for new code, + * as it offers more features such as categories and translation. + * Only use this environment call to maintain compatibility + * with older frontends or cores. + * @note Keep the available options (and their possible values) as low as possible; + * it should be feasible to cycle through them without a keyboard. + * @param[in] data const struct retro_variable *. + * Pointer to an array of \c retro_variable structs that define available core options, + * terminated by a { NULL, NULL } element. + * The frontend must maintain its own copy of this array. + * + * @returns \c true if the environment call is available, + * even if \c data is NULL. + * @see retro_variable + * @see RETRO_ENVIRONMENT_GET_VARIABLE + * @see RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE + * @see RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2 + */ +#define RETRO_ENVIRONMENT_SET_VARIABLES 16 + +/** + * Queries whether at least one core option was updated by the frontend + * since the last call to \ref RETRO_ENVIRONMENT_GET_VARIABLE. + * This typically means that the user opened the core options menu and made some changes. + * + * Cores usually call this each frame before the core's main emulation logic. + * Specific options can then be queried with \ref RETRO_ENVIRONMENT_GET_VARIABLE. + * + * @param[out] data bool *. + * Set to \c true if at least one core option was updated + * since the last call to \ref RETRO_ENVIRONMENT_GET_VARIABLE. + * Behavior is undefined if this pointer is \c NULL. + * @returns \c true if the environment call is available. + * @see RETRO_ENVIRONMENT_GET_VARIABLE + * @see RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2 + */ +#define RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE 17 + +/** + * Notifies the frontend that this core can run without loading any content, + * such as when emulating a console that has built-in software. + * When a core is loaded without content, + * \c retro_load_game receives an argument of NULL. + * This should be called within \c retro_set_environment() only. + * + * @param[in] data const bool *. + * Pointer to a single \c bool that indicates whether this frontend can run without content. + * Can point to a value of \c false but this isn't necessary, + * as contentless support is opt-in. + * The behavior is undefined if \c data is NULL. + * @returns \c true if the environment call is available. + * @see retro_load_game + */ +#define RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME 18 + +/** + * Retrieves the absolute path from which this core was loaded. + * Useful when loading assets from paths relative to the core, + * as is sometimes the case when using RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME. + * + * @param[out] data const char **. + * Pointer to a string in which the core's path will be saved. + * The string is managed by the frontend and must not be modified or freed by the core. + * May be \c NULL if the core is statically linked to the frontend + * or if the core's path otherwise cannot be determined. + * Behavior is undefined if \c data is NULL. + * @returns \c true if the environment call is available. + */ +#define RETRO_ENVIRONMENT_GET_LIBRETRO_PATH 19 + +/* Environment call 20 was an obsolete version of SET_AUDIO_CALLBACK. + * It was not used by any known core at the time, and was removed from the API. + * The number 20 is reserved to prevent ABI clashes. + */ + +/** + * Sets a callback that notifies the core of how much time has passed + * since the last iteration of retro_run. + * If the frontend is not running the core in real time + * (e.g. it's frame-stepping or running in slow motion), + * then the reference value will be provided to the callback instead. + * + * @param[in] data const struct retro_frame_time_callback *. + * Pointer to a single \c retro_frame_time_callback struct. + * Behavior is undefined if \c data is NULL. + * @returns \c true if the environment call is available. + * @note Frontends may disable this environment call in certain situations. + * It will return \c false in those cases. + * @see retro_frame_time_callback + */ +#define RETRO_ENVIRONMENT_SET_FRAME_TIME_CALLBACK 21 + +/** + * Registers a set of functions that the frontend can use + * to tell the core it's ready for audio output. + * + * It is intended for games that feature asynchronous audio. + * It should not be used for emulators unless their audio is asynchronous. + * + * + * The callback only notifies about writability; the libretro core still + * has to call the normal audio callbacks + * to write audio. The audio callbacks must be called from within the + * notification callback. + * The amount of audio data to write is up to the core. + * Generally, the audio callback will be called continuously in a loop. + * + * A frontend may disable this callback in certain situations. + * The core must be able to render audio with the "normal" interface. + * + * @param[in] data const struct retro_audio_callback *. + * Pointer to a set of functions that the frontend will call to notify the core + * when it's ready to receive audio data. + * May be \c NULL, in which case the frontend will return + * whether this environment callback is available. + * @return \c true if this environment call is available, + * even if \c data is \c NULL. + * @warning The provided callbacks can be invoked from any thread, + * so their implementations \em must be thread-safe. + * @note If a core uses this callback, + * it should also use RETRO_ENVIRONMENT_SET_FRAME_TIME_CALLBACK. + * @see retro_audio_callback + * @see retro_audio_sample_t + * @see retro_audio_sample_batch_t + * @see RETRO_ENVIRONMENT_SET_FRAME_TIME_CALLBACK + */ +#define RETRO_ENVIRONMENT_SET_AUDIO_CALLBACK 22 + +/** + * Gets an interface that a core can use to access a controller's rumble motors. + * + * The interface supports two independently-controlled motors, + * one strong and one weak. + * + * Should be called from either \c retro_init() or \c retro_load_game(), + * but not from \c retro_set_environment(). + * + * @param[out] data struct retro_rumble_interface *. + * Pointer to the interface struct. + * Behavior is undefined if \c NULL. + * @returns \c true if the environment call is available, + * even if the current device doesn't support vibration. + * @see retro_rumble_interface + * @defgroup GET_RUMBLE_INTERFACE Rumble Interface + */ +#define RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE 23 + +/** + * Returns the frontend's supported input device types. + * + * The supported device types are returned as a bitmask, + * with each value of \ref RETRO_DEVICE corresponding to a bit. + * + * Should only be called in \c retro_run(). + * + * @code + * #define REQUIRED_DEVICES ((1 << RETRO_DEVICE_JOYPAD) | (1 << RETRO_DEVICE_ANALOG)) + * void get_input_device_capabilities_example(void) + * { + * uint64_t capabilities; + * environ_cb(RETRO_ENVIRONMENT_GET_INPUT_DEVICE_CAPABILITIES, &capabilities); + * if ((capabilities & REQUIRED_DEVICES) == REQUIRED_DEVICES) + * printf("Joypad and analog device types are supported"); + * } + * @endcode + * + * @param[out] data uint64_t *. + * Pointer to a bitmask of supported input device types. + * If the frontend supports a particular \c RETRO_DEVICE_* type, + * then the bit (1 << RETRO_DEVICE_*) will be set. + * + * Each bit represents a \c RETRO_DEVICE constant, + * e.g. bit 1 represents \c RETRO_DEVICE_JOYPAD, + * bit 2 represents \c RETRO_DEVICE_MOUSE, and so on. + * + * Bits that do not correspond to known device types will be set to zero + * and are reserved for future use. + * + * Behavior is undefined if \c NULL. + * @returns \c true if the environment call is available. + * @note If the frontend supports multiple input drivers, + * availability of this environment call (and the reported capabilities) + * may depend on the active driver. + * @see RETRO_DEVICE + */ +#define RETRO_ENVIRONMENT_GET_INPUT_DEVICE_CAPABILITIES 24 + +/** + * Returns an interface that the core can use to access and configure available sensors, + * such as an accelerometer or gyroscope. + * + * @param[out] data struct retro_sensor_interface *. + * Pointer to the sensor interface that the frontend will populate. + * Behavior is undefined if is \c NULL. + * @returns \c true if the environment call is available, + * even if the device doesn't have any supported sensors. + * @see retro_sensor_interface + * @see retro_sensor_action + * @see RETRO_SENSOR + * @addtogroup RETRO_SENSOR + */ +#define RETRO_ENVIRONMENT_GET_SENSOR_INTERFACE (25 | RETRO_ENVIRONMENT_EXPERIMENTAL) + +/** + * Gets an interface to the device's video camera. + * + * The frontend delivers new video frames via a user-defined callback + * that runs in the same thread as \c retro_run(). + * Should be called in \c retro_load_game(). + * + * @param[in,out] data struct retro_camera_callback *. + * Pointer to the camera driver interface. + * Some fields in the struct must be filled in by the core, + * others are provided by the frontend. + * Behavior is undefined if \c NULL. + * @returns \c true if this environment call is available, + * even if an actual camera isn't. + * @note This API only supports one video camera at a time. + * If the device provides multiple cameras (e.g. inner/outer cameras on a phone), + * the frontend will choose one to use. + * @see retro_camera_callback + * @see RETRO_ENVIRONMENT_SET_HW_RENDER + */ +#define RETRO_ENVIRONMENT_GET_CAMERA_INTERFACE (26 | RETRO_ENVIRONMENT_EXPERIMENTAL) + +/** + * Gets an interface that the core can use for cross-platform logging. + * Certain platforms don't have a console or stderr, + * or they have their own preferred logging methods. + * The frontend itself may also display log output. + * + * @attention This should not be used for information that the player must immediately see, + * such as major errors or warnings. + * In most cases, this is best for information that will help you (the developer) + * identify problems when debugging or providing support. + * Unless a core or frontend is intended for advanced users, + * the player might not check (or even know about) their logs. + * + * @param[out] data struct retro_log_callback *. + * Pointer to the callback where the function pointer will be saved. + * Behavior is undefined if \c data is NULL. + * @returns \c true if the environment call is available. + * @see retro_log_callback + * @note Cores can fall back to \c stderr if this interface is not available. + */ +#define RETRO_ENVIRONMENT_GET_LOG_INTERFACE 27 + +/** + * Returns an interface that the core can use for profiling code + * and to access performance-related information. + * + * This callback supports performance counters, a high-resolution timer, + * and listing available CPU features (mostly SIMD instructions). + * + * @param[out] data struct retro_perf_callback *. + * Pointer to the callback interface. + * Behavior is undefined if \c NULL. + * @returns \c true if the environment call is available. + * @see retro_perf_callback + */ +#define RETRO_ENVIRONMENT_GET_PERF_INTERFACE 28 + +/** + * Returns an interface that the core can use to retrieve the device's location, + * including its current latitude and longitude. + * + * @param[out] data struct retro_location_callback *. + * Pointer to the callback interface. + * Behavior is undefined if \c NULL. + * @return \c true if the environment call is available, + * even if there's no location information available. + * @see retro_location_callback + */ +#define RETRO_ENVIRONMENT_GET_LOCATION_INTERFACE 29 + +/** + * @deprecated An obsolete alias to \c RETRO_ENVIRONMENT_GET_CORE_ASSETS_DIRECTORY kept for compatibility. + * @see RETRO_ENVIRONMENT_GET_CORE_ASSETS_DIRECTORY + **/ +#define RETRO_ENVIRONMENT_GET_CONTENT_DIRECTORY 30 + +/** + * Returns the frontend's "core assets" directory, + * which can be used to store assets that the core needs + * such as art assets or level data. + * + * @param[out] data const char **. + * Pointer to a string in which the core assets directory will be saved. + * This string is managed by the frontend and must not be modified or freed by the core. + * May be \c NULL if no core assets directory is defined, + * in which case the core should find an alternative directory. + * Behavior is undefined if \c data is NULL. + * @returns \c true if the environment call is available, + * even if the value returned in \c data is NULL. + */ +#define RETRO_ENVIRONMENT_GET_CORE_ASSETS_DIRECTORY 30 + +/** + * Returns the frontend's save data directory, if available. + * This directory should be used to store game-specific save data, + * including memory card images. + * + * Although libretro provides an interface for cores to expose SRAM to the frontend, + * not all cores can support it correctly. + * In this case, cores should use this environment callback + * to save their game data to disk manually. + * + * Cores that use this environment callback + * should flush their save data to disk periodically and when unloading. + * + * @param[out] data const char **. + * Pointer to the string in which the save data directory will be saved. + * This string is managed by the frontend and must not be modified or freed by the core. + * May return \c NULL if no save data directory is defined. + * Behavior is undefined if \c data is NULL. + * @returns \c true if the environment call is available, + * even if the value returned in \c data is NULL. + * @note Early libretro cores used \c RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY for save data. + * This is still supported for backwards compatibility, + * but new cores should use this environment call instead. + * \c RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY should be used for game-agnostic data + * such as BIOS files or core-specific configuration. + * @note The returned directory may or may not be the same + * as the one used for \c retro_get_memory_data. + * + * @see retro_get_memory_data + * @see RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY + */ +#define RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY 31 + +/** + * Sets new video and audio parameters for the core. + * This can only be called from within retro_run. + * + * This environment call may entail a full reinitialization of the frontend's audio/video drivers, + * hence it should \em only be used if the core needs to make drastic changes + * to audio/video parameters. + * + * This environment call should \em not be used when: + *
    + *
  • Changing the emulated system's internal resolution, + * within the limits defined by the existing values of \c max_width and \c max_height. + * Use \c RETRO_ENVIRONMENT_SET_GEOMETRY instead, + * and adjust \c retro_get_system_av_info to account for + * supported scale factors and screen layouts + * when computing \c max_width and \c max_height. + * Only use this environment call if \c max_width or \c max_height needs to increase. + *
  • Adjusting the screen's aspect ratio, + * e.g. when changing the layout of the screen(s). + * Use \c RETRO_ENVIRONMENT_SET_GEOMETRY or \c RETRO_ENVIRONMENT_SET_ROTATION instead. + *
+ * + * The frontend will reinitialize its audio and video drivers within this callback; + * after that happens, audio and video callbacks will target the newly-initialized driver, + * even within the same \c retro_run call. + * + * This callback makes it possible to support configurable resolutions + * while avoiding the need to compute the "worst case" values of \c max_width and \c max_height. + * + * @param[in] data const struct retro_system_av_info *. + * Pointer to the new video and audio parameters that the frontend should adopt. + * @returns \c true if the environment call is available + * and the new av_info struct was accepted. + * \c false if the environment call is unavailable or \c data is NULL. + * @see retro_system_av_info + * @see RETRO_ENVIRONMENT_SET_GEOMETRY + */ +#define RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO 32 + +/** + * Provides an interface that a frontend can use + * to get function pointers from the core. + * + * This allows cores to define their own extensions to the libretro API, + * or to expose implementations of a frontend's libretro extensions. + * + * @param[in] data const struct retro_get_proc_address_interface *. + * Pointer to the interface that the frontend can use to get function pointers from the core. + * The frontend must maintain its own copy of this interface. + * @returns \c true if the environment call is available + * and the returned interface was accepted. + * @note The provided interface may be called at any time, + * even before this environment call returns. + * @note Extensions should be prefixed with the name of the frontend or core that defines them. + * For example, a frontend named "foo" that defines a debugging extension + * should expect the core to define functions prefixed with "foo_debug_". + * @warning If a core wants to use this environment call, + * it \em must do so from within \c retro_set_environment(). + * @see retro_get_proc_address_interface + */ +#define RETRO_ENVIRONMENT_SET_PROC_ADDRESS_CALLBACK 33 + +/** + * Registers a core's ability to handle "subsystems", + * which are secondary platforms that augment a core's primary emulated hardware. + * + * A core doesn't need to emulate a secondary platform + * in order to use it as a subsystem; + * as long as it can load a secondary file for some practical use, + * then this environment call is most likely suitable. + * + * Possible use cases of a subsystem include: + * + * \li Installing software onto an emulated console's internal storage, + * such as the Nintendo DSi. + * \li Emulating accessories that are used to support another console's games, + * such as the Super Game Boy or the N64 Transfer Pak. + * \li Inserting a secondary ROM into a console + * that features multiple cartridge ports, + * such as the Nintendo DS's Slot-2. + * \li Loading a save data file created and used by another core. + * + * Cores should \em not use subsystems for: + * + * \li Emulators that support multiple "primary" platforms, + * such as a Game Boy/Game Boy Advance core + * or a Sega Genesis/Sega CD/32X core. + * Use \c retro_system_content_info_override, \c retro_system_info, + * and/or runtime detection instead. + * \li Selecting different memory card images. + * Use dynamically-populated core options instead. + * \li Different variants of a single console, + * such the Game Boy vs. the Game Boy Color. + * Use core options or runtime detection instead. + * \li Games that span multiple disks. + * Use \c RETRO_ENVIRONMENT_SET_DISK_CONTROL_EXT_INTERFACE + * and m3u-formatted playlists instead. + * \li Console system files (BIOS, firmware, etc.). + * Use \c RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY + * and a common naming convention instead. + * + * When the frontend loads a game via a subsystem, + * it must call \c retro_load_game_special() instead of \c retro_load_game(). + * + * @param[in] data const struct retro_subsystem_info *. + * Pointer to an array of subsystem descriptors, + * terminated by a zeroed-out \c retro_subsystem_info struct. + * The frontend should maintain its own copy + * of this array and the strings within it. + * Behavior is undefined if \c NULL. + * @returns \c true if this environment call is available. + * @note This environment call \em must be called from within \c retro_set_environment(), + * as frontends may need the registered information before loading a game. + * @see retro_subsystem_info + * @see retro_load_game_special + */ +#define RETRO_ENVIRONMENT_SET_SUBSYSTEM_INFO 34 + +/** + * Declares one or more types of controllers supported by this core. + * The frontend may then allow the player to select one of these controllers in its menu. + * + * Many consoles had controllers that came in different versions, + * were extensible with peripherals, + * or could be held in multiple ways; + * this environment call can be used to represent these differences + * and adjust the core's behavior to match. + * + * Possible use cases include: + * + * \li Supporting different classes of a single controller that supported their own sets of games. + * For example, the SNES had two different lightguns (the Super Scope and the Justifier) + * whose games were incompatible with each other. + * \li Representing a platform's alternative controllers. + * For example, several platforms had music/rhythm games that included controllers + * shaped like musical instruments. + * \li Representing variants of a standard controller with additional inputs. + * For example, numerous consoles in the 90's introduced 6-button controllers for fighting games, + * steering wheels for racing games, + * or analog sticks for 3D platformers. + * \li Representing add-ons for consoles or standard controllers. + * For example, the 3DS had a Circle Pad Pro attachment that added a second analog stick. + * \li Selecting different configurations for a single controller. + * For example, the Wii Remote could be held sideways like a traditional game pad + * or in one hand like a wand. + * \li Providing multiple ways to simulate the experience of using a particular controller. + * For example, the Game Boy Advance featured several games + * with motion or light sensors in their cartridges; + * a core could provide controller configurations + * that allow emulating the sensors with either analog axes + * or with their host device's sensors. + * + * Should be called in retro_load_game. + * The frontend must maintain its own copy of the provided array, + * including all strings and subobjects. + * A core may exclude certain controllers for known incompatible games. + * + * When the frontend changes the active device for a particular port, + * it must call \c retro_set_controller_port_device() with that port's index + * and one of the IDs defined in its retro_controller_info::types field. + * + * Input ports are generally associated with different players + * (and the frontend's UI may reflect this with "Player 1" labels), + * but this is not required. + * Some games use multiple controllers for a single player, + * or some cores may use port indexes to represent an emulated console's + * alternative input peripherals. + * + * @param[in] data const struct retro_controller_info *. + * Pointer to an array of controller types defined by this core, + * terminated by a zeroed-out \c retro_controller_info. + * Each element of this array represents a controller port on the emulated device. + * Behavior is undefined if \c NULL. + * @returns \c true if this environment call is available. + * @see retro_controller_info + * @see retro_set_controller_port_device + * @see RETRO_DEVICE_SUBCLASS + */ +#define RETRO_ENVIRONMENT_SET_CONTROLLER_INFO 35 + +/** + * Notifies the frontend of the address spaces used by the core's emulated hardware, + * and of the memory maps within these spaces. + * This can be used by the frontend to provide cheats, achievements, or debugging capabilities. + * Should only be used by emulators, as it makes little sense for game engines. + * + * @note Cores should also expose these address spaces + * through retro_get_memory_data and \c retro_get_memory_size if applicable; + * this environment call is not intended to replace those two functions, + * as the emulated hardware may feature memory regions outside of its own address space + * that are nevertheless useful for the frontend. + * + * @param[in] data const struct retro_memory_map *. + * Pointer to a single memory-map listing. + * The frontend must maintain its own copy of this object and its contents, + * including strings and nested objects. + * Behavior is undefined if \c NULL. + * @returns \c true if this environment call is available. + * @see retro_memory_map + * @see retro_get_memory_data + * @see retro_memory_descriptor + */ +#define RETRO_ENVIRONMENT_SET_MEMORY_MAPS (36 | RETRO_ENVIRONMENT_EXPERIMENTAL) + +/** + * Resizes the viewport without reinitializing the video driver. + * + * Similar to \c RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO, + * but any changes that would require video reinitialization will not be performed. + * Can only be called from within \c retro_run(). + * + * This environment call allows a core to revise the size of the viewport at will, + * which can be useful for emulated platforms that support dynamic resolution changes + * or for cores that support multiple screen layouts. + * + * A frontend must guarantee that this environment call completes in + * constant time. + * + * @param[in] data const struct retro_game_geometry *. + * Pointer to the new video parameters that the frontend should adopt. + * \c retro_game_geometry::max_width and \c retro_game_geometry::max_height + * will be ignored. + * Behavior is undefined if \c data is NULL. + * @return \c true if the environment call is available. + * @see RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO + */ +#define RETRO_ENVIRONMENT_SET_GEOMETRY 37 + +/** + * Returns the name of the user, if possible. + * This callback is suitable for cores that offer personalization, + * such as online facilities or user profiles on the emulated system. + * @param[out] data const char **. + * Pointer to the user name string. + * May be \c NULL, in which case the core should use a default name. + * The returned pointer is owned by the frontend and must not be modified or freed by the core. + * Behavior is undefined if \c NULL. + * @returns \c true if the environment call is available, + * even if the frontend couldn't provide a name. + */ +#define RETRO_ENVIRONMENT_GET_USERNAME 38 + +/** + * Returns the frontend's configured language. + * It can be used to localize the core's UI, + * or to customize the emulated firmware if applicable. + * + * @param[out] data retro_language *. + * Pointer to the language identifier. + * Behavior is undefined if \c NULL. + * @returns \c true if the environment call is available. + * @note The returned language may not be the same as the operating system's language. + * Cores should fall back to the operating system's language (or to English) + * if the environment call is unavailable or the returned language is unsupported. + * @see retro_language + * @see RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2_INTL + */ +#define RETRO_ENVIRONMENT_GET_LANGUAGE 39 + +/** + * Returns a frontend-managed framebuffer + * that the core may render directly into + * + * This environment call is provided as an optimization + * for cores that use software rendering + * (i.e. that don't use \refitem RETRO_ENVIRONMENT_SET_HW_RENDER "a graphics hardware API"); + * specifically, the intended use case is to allow a core + * to render directly into frontend-managed video memory, + * avoiding the bandwidth use that copying a whole framebuffer from core to video memory entails. + * + * Must be called every frame if used, + * as this may return a different framebuffer each frame + * (e.g. for swap chains). + * However, a core may render to a different buffer even if this call succeeds. + * + * @param[in,out] data struct retro_framebuffer *. + * Pointer to a frontend's frame buffer and accompanying data. + * Some fields are set by the core, others are set by the frontend. + * Only guaranteed to be valid for the duration of the current \c retro_run call, + * and must not be used afterwards. + * Behavior is undefined if \c NULL. + * @return \c true if the environment call was recognized + * and the framebuffer was successfully returned. + * @see retro_framebuffer + */ +#define RETRO_ENVIRONMENT_GET_CURRENT_SOFTWARE_FRAMEBUFFER (40 | RETRO_ENVIRONMENT_EXPERIMENTAL) + +/** + * Returns an interface for accessing the data of specific rendering APIs. + * Not all hardware rendering APIs support or need this. + * + * The details of these interfaces are specific to each rendering API. + * + * @note \c retro_hw_render_callback::context_reset must be called by the frontend + * before this environment call can be used. + * Additionally, the contents of the returned interface are invalidated + * after \c retro_hw_render_callback::context_destroyed has been called. + * @param[out] data const struct retro_hw_render_interface **. + * The render interface for the currently-enabled hardware rendering API, if any. + * The frontend will store a pointer to the interface at the address provided here. + * The returned interface is owned by the frontend and must not be modified or freed by the core. + * Behavior is undefined if \c NULL. + * @return \c true if this environment call is available, + * the active graphics API has a libretro rendering interface, + * and the frontend is able to return said interface. + * \c false otherwise. + * @see RETRO_ENVIRONMENT_SET_HW_RENDER + * @see retro_hw_render_interface + * @note Since not every libretro-supported hardware rendering API + * has a \c retro_hw_render_interface implementation, + * a result of \c false is not necessarily an error. + */ +#define RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE (41 | RETRO_ENVIRONMENT_EXPERIMENTAL) + +/** + * Explicitly notifies the frontend of whether this core supports achievements. + * The core must expose its emulated address space via + * \c retro_get_memory_data or \c RETRO_ENVIRONMENT_GET_MEMORY_MAPS. + * Must be called before the first call to retro_run. + * + * If \ref retro_get_memory_data returns a valid address + * but this environment call is not used, + * the frontend (at its discretion) may or may not opt in the core to its achievements support. + * whether this core is opted in to the frontend's achievement support + * is left to the frontend's discretion. + * @param[in] data const bool *. + * Pointer to a single \c bool that indicates whether this core supports achievements. + * Behavior is undefined if \c data is NULL. + * @returns \c true if the environment call is available. + * @see RETRO_ENVIRONMENT_SET_MEMORY_MAPS + * @see retro_get_memory_data + */ +#define RETRO_ENVIRONMENT_SET_SUPPORT_ACHIEVEMENTS (42 | RETRO_ENVIRONMENT_EXPERIMENTAL) + +/** + * Defines an interface that the frontend can use + * to ask the core for the parameters it needs for a hardware rendering context. + * The exact semantics depend on \ref RETRO_ENVIRONMENT_SET_HW_RENDER "the active rendering API". + * Will be used some time after \c RETRO_ENVIRONMENT_SET_HW_RENDER is called, + * but before \c retro_hw_render_callback::context_reset is called. + * + * @param[in] data const struct retro_hw_render_context_negotiation_interface *. + * Pointer to the context negotiation interface. + * Will be populated by the frontend. + * Behavior is undefined if \c NULL. + * @return \c true if this environment call is supported, + * even if the current graphics API doesn't use + * a context negotiation interface (in which case the argument is ignored). + * @see retro_hw_render_context_negotiation_interface + * @see RETRO_ENVIRONMENT_GET_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE_SUPPORT + * @see RETRO_ENVIRONMENT_SET_HW_RENDER + */ +#define RETRO_ENVIRONMENT_SET_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE (43 | RETRO_ENVIRONMENT_EXPERIMENTAL) + +/** + * Notifies the frontend of any quirks associated with serialization. + * + * Should be set in either \c retro_init or \c retro_load_game, but not both. + * @param[in, out] data uint64_t *. + * Pointer to the core's serialization quirks. + * The frontend will set the flags of the quirks it supports + * and clear the flags of those it doesn't. + * Behavior is undefined if \c NULL. + * @return \c true if this environment call is supported. + * @see retro_serialize + * @see retro_unserialize + * @see RETRO_SERIALIZATION_QUIRK + */ +#define RETRO_ENVIRONMENT_SET_SERIALIZATION_QUIRKS 44 + +/** + * The frontend will try to use a "shared" context when setting up a hardware context. + * Mostly applicable to OpenGL. + * + * In order for this to have any effect, + * the core must call \c RETRO_ENVIRONMENT_SET_HW_RENDER at some point + * if it hasn't already. + * + * @param data Ignored. + * @returns \c true if the environment call is available + * and the frontend supports shared hardware contexts. + */ +#define RETRO_ENVIRONMENT_SET_HW_SHARED_CONTEXT (44 | RETRO_ENVIRONMENT_EXPERIMENTAL) + +/** + * Returns an interface that the core can use to access the file system. + * Should be called as early as possible. + * + * @param[in,out] data struct retro_vfs_interface_info *. + * Information about the desired VFS interface, + * as well as the interface itself. + * Behavior is undefined if \c NULL. + * @return \c true if this environment call is available + * and the frontend can provide a VFS interface of the requested version or newer. + * @see retro_vfs_interface_info + * @see file_path + * @see retro_dirent + * @see file_stream + */ +#define RETRO_ENVIRONMENT_GET_VFS_INTERFACE (45 | RETRO_ENVIRONMENT_EXPERIMENTAL) + +/** + * Returns an interface that the core can use + * to set the state of any accessible device LEDs. + * + * @param[out] data struct retro_led_interface *. + * Pointer to the LED interface that the frontend will populate. + * May be \c NULL, in which case the frontend will only return + * whether this environment callback is available. + * @returns \c true if the environment call is available, + * even if \c data is \c NULL + * or no LEDs are accessible. + * @see retro_led_interface + */ +#define RETRO_ENVIRONMENT_GET_LED_INTERFACE (46 | RETRO_ENVIRONMENT_EXPERIMENTAL) + +/** + * Returns hints about certain steps that the core may skip for this frame. + * + * A frontend may not need a core to generate audio or video in certain situations; + * this environment call sets a bitmask that indicates + * which steps the core may skip for this frame. + * + * This can be used to increase performance for some frontend features. + * + * @note Emulation accuracy should not be compromised; + * for example, if a core emulates a platform that supports display capture + * (i.e. looking at its own VRAM), then it should perform its rendering as normal + * unless it can prove that the emulated game is not using display capture. + * + * @param[out] data retro_av_enable_flags *. + * Pointer to the bitmask of steps that the frontend will skip. + * Other bits are set to zero and are reserved for future use. + * If \c NULL, the frontend will only return whether this environment callback is available. + * @returns \c true if the environment call is available, + * regardless of the value output to \c data. + * If \c false, the core should assume that the frontend will not skip any steps. + * @see retro_av_enable_flags + */ +#define RETRO_ENVIRONMENT_GET_AUDIO_VIDEO_ENABLE (47 | RETRO_ENVIRONMENT_EXPERIMENTAL) + +/** + * Gets an interface that the core can use for raw MIDI I/O. + * + * @param[out] data struct retro_midi_interface *. + * Pointer to the MIDI interface. + * May be \c NULL. + * @return \c true if the environment call is available, + * even if \c data is \c NULL. + * @see retro_midi_interface + */ +#define RETRO_ENVIRONMENT_GET_MIDI_INTERFACE (48 | RETRO_ENVIRONMENT_EXPERIMENTAL) + +/** + * Asks the frontend if it's currently in fast-forward mode. + * @param[out] data bool *. + * Set to \c true if the frontend is currently fast-forwarding its main loop. + * Behavior is undefined if \c data is NULL. + * @returns \c true if this environment call is available, + * regardless of the value returned in \c data. + * + * @see RETRO_ENVIRONMENT_SET_FASTFORWARDING_OVERRIDE + */ +#define RETRO_ENVIRONMENT_GET_FASTFORWARDING (49 | RETRO_ENVIRONMENT_EXPERIMENTAL) + +/** + * Returns the refresh rate the frontend is targeting, in Hz. + * The intended use case is for the core to use the result to select an ideal refresh rate. + * + * @param[out] data float *. + * Pointer to the \c float in which the frontend will store its target refresh rate. + * Behavior is undefined if \c data is NULL. + * @return \c true if this environment call is available, + * regardless of the value returned in \c data. +*/ +#define RETRO_ENVIRONMENT_GET_TARGET_REFRESH_RATE (50 | RETRO_ENVIRONMENT_EXPERIMENTAL) + +/** + * Returns whether the frontend can return the state of all buttons at once as a bitmask, + * rather than requiring a series of individual calls to \c retro_input_state_t. + * + * If this callback returns \c true, + * you can get the state of all buttons by passing \c RETRO_DEVICE_ID_JOYPAD_MASK + * as the \c id parameter to \c retro_input_state_t. + * Bit #N represents the RETRO_DEVICE_ID_JOYPAD constant of value N, + * e.g. (1 << RETRO_DEVICE_ID_JOYPAD_A) represents the A button. + * + * @param data Ignored. + * @returns \c true if the frontend can report the complete digital joypad state as a bitmask. + * @see retro_input_state_t + * @see RETRO_DEVICE_JOYPAD + * @see RETRO_DEVICE_ID_JOYPAD_MASK + */ +#define RETRO_ENVIRONMENT_GET_INPUT_BITMASKS (51 | RETRO_ENVIRONMENT_EXPERIMENTAL) + +/** + * Returns the version of the core options API supported by the frontend. + * + * Over the years, libretro has used several interfaces + * for allowing cores to define customizable options. + * \ref SET_CORE_OPTIONS_V2 "Version 2 of the interface" + * is currently preferred due to its extra features, + * but cores and frontends should strive to support + * versions \ref RETRO_ENVIRONMENT_SET_CORE_OPTIONS "1" + * and \ref RETRO_ENVIRONMENT_SET_VARIABLES "0" as well. + * This environment call provides the information that cores need for that purpose. + * + * If this environment call returns \c false, + * then the core should assume version 0 of the core options API. + * + * @param[out] data unsigned *. + * Pointer to the integer that will store the frontend's + * supported core options API version. + * Behavior is undefined if \c NULL. + * @returns \c true if the environment call is available, + * \c false otherwise. + * @see RETRO_ENVIRONMENT_SET_VARIABLES + * @see RETRO_ENVIRONMENT_SET_CORE_OPTIONS + * @see RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2 + */ +#define RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION 52 + +/** + * @copybrief RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2 + * + * @deprecated This environment call has been superseded + * by RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2, + * which supports categorizing options into groups. + * This environment call should only be used to maintain compatibility + * with older cores and frontends. + * + * This environment call is intended to replace \c RETRO_ENVIRONMENT_SET_VARIABLES, + * and should only be called if \c RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION + * returns an API version of at least 1. + * + * This should be called the first time as early as possible, + * ideally in \c retro_set_environment (but \c retro_load_game is acceptable). + * It may then be called again later to update + * the core's options and their associated values, + * as long as the number of options doesn't change + * from the number given in the first call. + * + * The core can retrieve option values at any time with \c RETRO_ENVIRONMENT_GET_VARIABLE. + * If a saved value for a core option doesn't match the option definition's values, + * the frontend may treat it as incorrect and revert to the default. + * + * Core options and their values are usually defined in a large static array, + * but they may be generated at runtime based on the loaded game or system state. + * Here are some use cases for that: + * + * @li Selecting a particular file from one of the + * \ref RETRO_ENVIRONMENT_GET_ASSET_DIRECTORY "frontend's" + * \ref RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY "content" + * \ref RETRO_ENVIRONMENT_GET_CORE_ASSETS_DIRECTORY "directories", + * such as a memory card image or figurine data file. + * @li Excluding options that are not relevant to the current game, + * for cores that define a large number of possible options. + * @li Choosing a default value at runtime for a specific game, + * such as a BIOS file whose region matches that of the loaded content. + * + * @note A guiding principle of libretro's API design is that + * all common interactions (gameplay, menu navigation, etc.) + * should be possible without a keyboard. + * This implies that cores should keep the number of options and values + * as low as possible. + * + * Example entry: + * @code + * { + * "foo_option", + * "Speed hack coprocessor X", + * "Provides increased performance at the expense of reduced accuracy", + * { + * { "false", NULL }, + * { "true", NULL }, + * { "unstable", "Turbo (Unstable)" }, + * { NULL, NULL }, + * }, + * "false" + * } + * @endcode + * + * @param[in] data const struct retro_core_option_definition *. + * Pointer to one or more core option definitions, + * terminated by a \ref retro_core_option_definition whose values are all zero. + * May be \c NULL, in which case the frontend will remove all existing core options. + * The frontend must maintain its own copy of this object, + * including all strings and subobjects. + * @return \c true if this environment call is available. + * + * @see retro_core_option_definition + * @see RETRO_ENVIRONMENT_GET_VARIABLE + * @see RETRO_ENVIRONMENT_SET_CORE_OPTIONS_INTL + */ +#define RETRO_ENVIRONMENT_SET_CORE_OPTIONS 53 + +/** + * A variant of \ref RETRO_ENVIRONMENT_SET_CORE_OPTIONS + * that supports internationalization. + * + * @deprecated This environment call has been superseded + * by \ref RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2_INTL, + * which supports categorizing options into groups + * (plus translating the groups themselves). + * Only use this environment call to maintain compatibility + * with older cores and frontends. + * + * This should be called instead of \c RETRO_ENVIRONMENT_SET_CORE_OPTIONS + * if the core provides translations for its options. + * General use is largely the same, + * but see \ref retro_core_options_intl for some important details. + * + * @param[in] data const struct retro_core_options_intl *. + * Pointer to a core's option values and their translations. + * @see retro_core_options_intl + * @see RETRO_ENVIRONMENT_SET_CORE_OPTIONS + */ +#define RETRO_ENVIRONMENT_SET_CORE_OPTIONS_INTL 54 + +/** + * Notifies the frontend that it should show or hide the named core option. + * + * Some core options aren't relevant in all scenarios, + * such as a submenu for hardware rendering flags + * when the software renderer is configured. + * This environment call asks the frontend to stop (or start) + * showing the named core option to the player. + * This is only a hint, not a requirement; + * the frontend may ignore this environment call. + * By default, all core options are visible. + * + * @note This environment call must \em only affect a core option's visibility, + * not its functionality or availability. + * \ref RETRO_ENVIRONMENT_GET_VARIABLE "Getting an invisible core option" + * must behave normally. + * + * @param[in] data const struct retro_core_option_display *. + * Pointer to a descriptor for the option that the frontend should show or hide. + * May be \c NULL, in which case the frontend will only return + * whether this environment callback is available. + * @return \c true if this environment call is available, + * even if \c data is \c NULL + * or the specified option doesn't exist. + * @see retro_core_option_display + * @see RETRO_ENVIRONMENT_SET_CORE_OPTIONS_UPDATE_DISPLAY_CALLBACK + */ +#define RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY 55 + +/** + * Returns the frontend's preferred hardware rendering API. + * Cores should use this information to decide which API to use with \c RETRO_ENVIRONMENT_SET_HW_RENDER. + * @param[out] data retro_hw_context_type *. + * Pointer to the hardware context type. + * Behavior is undefined if \c data is NULL. + * This value will be set even if the environment call returns false, + * unless the frontend doesn't implement it. + * @returns \c true if the environment call is available + * and the frontend is able to use a hardware rendering API besides the one returned. + * If \c false is returned and the core cannot use the preferred rendering API, + * then it should exit or fall back to software rendering. + * @note The returned value does not indicate which API is currently in use. + * For example, the frontend may return \c RETRO_HW_CONTEXT_OPENGL + * while a Direct3D context from a previous session is active; + * this would signal that the frontend's current preference is for OpenGL, + * possibly because the user changed their frontend's video driver while a game is running. + * @see retro_hw_context_type + * @see RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE + * @see RETRO_ENVIRONMENT_SET_HW_RENDER + */ +#define RETRO_ENVIRONMENT_GET_PREFERRED_HW_RENDER 56 + +/** + * Returns the minimum version of the disk control interface supported by the frontend. + * + * If this environment call returns \c false or \c data is 0 or greater, + * then cores may use disk control callbacks + * with \c RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE. + * If the reported version is 1 or greater, + * then cores should use \c RETRO_ENVIRONMENT_SET_DISK_CONTROL_EXT_INTERFACE instead. + * + * @param[out] data unsigned *. + * Pointer to the unsigned integer that the frontend's supported disk control interface version will be stored in. + * Behavior is undefined if \c NULL. + * @return \c true if this environment call is available. + * @see RETRO_ENVIRONMENT_SET_DISK_CONTROL_EXT_INTERFACE + */ +#define RETRO_ENVIRONMENT_GET_DISK_CONTROL_INTERFACE_VERSION 57 + +/** + * @copybrief RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE + * + * This is intended for multi-disk games that expect the player + * to manually swap disks at certain points in the game. + * This version of the disk control interface provides + * more information about disk images. + * Should be called in \c retro_init. + * + * @param[in] data const struct retro_disk_control_ext_callback *. + * Pointer to the callback functions to use. + * May be \c NULL, in which case the existing disk callback is deregistered. + * @return \c true if this environment call is available, + * even if \c data is \c NULL. + * @see retro_disk_control_ext_callback + */ +#define RETRO_ENVIRONMENT_SET_DISK_CONTROL_EXT_INTERFACE 58 + +/** + * Returns the version of the message interface supported by the frontend. + * + * A version of 0 indicates that the frontend + * only supports the legacy \c RETRO_ENVIRONMENT_SET_MESSAGE interface. + * A version of 1 indicates that the frontend + * supports \c RETRO_ENVIRONMENT_SET_MESSAGE_EXT as well. + * If this environment call returns \c false, + * the core should behave as if it had returned 0. + * + * @param[out] data unsigned *. + * Pointer to the result returned by the frontend. + * Behavior is undefined if \c NULL. + * @return \c true if this environment call is available. + * @see RETRO_ENVIRONMENT_SET_MESSAGE_EXT + * @see RETRO_ENVIRONMENT_SET_MESSAGE + */ +#define RETRO_ENVIRONMENT_GET_MESSAGE_INTERFACE_VERSION 59 + +/** + * Displays a user-facing message for a short time. + * + * Use this callback to convey important status messages, + * such as errors or the result of long-running operations. + * For trivial messages or logging, use \c RETRO_ENVIRONMENT_GET_LOG_INTERFACE or \c stderr. + * + * This environment call supersedes \c RETRO_ENVIRONMENT_SET_MESSAGE, + * as it provides many more ways to customize + * how a message is presented to the player. + * However, a frontend that supports this environment call + * must still support \c RETRO_ENVIRONMENT_SET_MESSAGE. + * + * @param[in] data const struct retro_message_ext *. + * Pointer to the message to display to the player. + * Behavior is undefined if \c NULL. + * @returns \c true if this environment call is available. + * @see retro_message_ext + * @see RETRO_ENVIRONMENT_GET_MESSAGE_INTERFACE_VERSION + */ +#define RETRO_ENVIRONMENT_SET_MESSAGE_EXT 60 + +/** + * Returns the number of active input devices currently provided by the frontend. + * + * This may change between frames, + * but will remain constant for the duration of each frame. + * + * If this callback returns \c true, + * a core need not poll any input device + * with an index greater than or equal to the returned value. + * + * If callback returns \c false, + * the number of active input devices is unknown. + * In this case, all input devices should be considered active. + * + * @param[out] data unsigned *. + * Pointer to the result returned by the frontend. + * Behavior is undefined if \c NULL. + * @return \c true if this environment call is available. + */ +#define RETRO_ENVIRONMENT_GET_INPUT_MAX_USERS 61 + +/** + * Registers a callback that the frontend can use to notify the core + * of the audio output buffer's occupancy. + * Can be used by a core to attempt frame-skipping to avoid buffer under-runs + * (i.e. "crackling" sounds). + * + * @param[in] data const struct retro_audio_buffer_status_callback *. + * Pointer to the the buffer status callback, + * or \c NULL to unregister any existing callback. + * @return \c true if this environment call is available, + * even if \c data is \c NULL. + * + * @see retro_audio_buffer_status_callback + */ +#define RETRO_ENVIRONMENT_SET_AUDIO_BUFFER_STATUS_CALLBACK 62 + +/** + * Requests a minimum frontend audio latency in milliseconds. + * + * This is a hint; the frontend may assign a different audio latency + * to accommodate hardware limits, + * although it should try to honor requests up to 512ms. + * + * This callback has no effect if the requested latency + * is less than the frontend's current audio latency. + * If value is zero or \c data is \c NULL, + * the frontend should set its default audio latency. + * + * May be used by a core to increase audio latency and + * reduce the risk of buffer under-runs (crackling) + * when performing 'intensive' operations. + * + * A core using RETRO_ENVIRONMENT_SET_AUDIO_BUFFER_STATUS_CALLBACK + * to implement audio-buffer-based frame skipping can get good results + * by setting the audio latency to a high (typically 6x or 8x) + * integer multiple of the expected frame time. + * + * This can only be called from within \c retro_run(). + * + * @warning This environment call may require the frontend to reinitialize its audio system. + * This environment call should be used sparingly. + * If the driver is reinitialized, + * \ref retro_audio_callback_t "all audio callbacks" will be updated + * to target the newly-initialized driver. + * + * @param[in] data const unsigned *. + * Minimum audio latency, in milliseconds. + * @return \c true if this environment call is available, + * even if \c data is \c NULL. + * + * @see RETRO_ENVIRONMENT_SET_AUDIO_BUFFER_STATUS_CALLBACK + */ +#define RETRO_ENVIRONMENT_SET_MINIMUM_AUDIO_LATENCY 63 + +/** + * Allows the core to tell the frontend when it should enable fast-forwarding, + * rather than relying solely on the frontend and user interaction. + * + * Possible use cases include: + * + * \li Temporarily disabling a core's fastforward support + * while investigating a related bug. + * \li Disabling fastforward during netplay sessions, + * or when using an emulated console's network features. + * \li Automatically speeding up the game when in a loading screen + * that cannot be shortened with high-level emulation. + * + * @param[in] data const struct retro_fastforwarding_override *. + * Pointer to the parameters that decide when and how + * the frontend is allowed to enable fast-forward mode. + * May be \c NULL, in which case the frontend will return \c true + * without updating the fastforward state, + * which can be used to detect support for this environment call. + * @return \c true if this environment call is available, + * even if \c data is \c NULL. + * + * @see retro_fastforwarding_override + * @see RETRO_ENVIRONMENT_GET_FASTFORWARDING + */ +#define RETRO_ENVIRONMENT_SET_FASTFORWARDING_OVERRIDE 64 + +#define RETRO_ENVIRONMENT_SET_CONTENT_INFO_OVERRIDE 65 + /* const struct retro_system_content_info_override * -- + * Allows an implementation to override 'global' content + * info parameters reported by retro_get_system_info(). + * Overrides also affect subsystem content info parameters + * set via RETRO_ENVIRONMENT_SET_SUBSYSTEM_INFO. + * This function must be called inside retro_set_environment(). + * If callback returns false, content info overrides + * are unsupported by the frontend, and will be ignored. + * If callback returns true, extended game info may be + * retrieved by calling RETRO_ENVIRONMENT_GET_GAME_INFO_EXT + * in retro_load_game() or retro_load_game_special(). + * + * 'data' points to an array of retro_system_content_info_override + * structs terminated by a { NULL, false, false } element. + * If 'data' is NULL, no changes will be made to the frontend; + * a core may therefore pass NULL in order to test whether + * the RETRO_ENVIRONMENT_SET_CONTENT_INFO_OVERRIDE and + * RETRO_ENVIRONMENT_GET_GAME_INFO_EXT callbacks are supported + * by the frontend. + * + * For struct member descriptions, see the definition of + * struct retro_system_content_info_override. + * + * Example: + * + * - struct retro_system_info: + * { + * "My Core", // library_name + * "v1.0", // library_version + * "m3u|md|cue|iso|chd|sms|gg|sg", // valid_extensions + * true, // need_fullpath + * false // block_extract + * } + * + * - Array of struct retro_system_content_info_override: + * { + * { + * "md|sms|gg", // extensions + * false, // need_fullpath + * true // persistent_data + * }, + * { + * "sg", // extensions + * false, // need_fullpath + * false // persistent_data + * }, + * { NULL, false, false } + * } + * + * Result: + * - Files of type m3u, cue, iso, chd will not be + * loaded by the frontend. Frontend will pass a + * valid path to the core, and core will handle + * loading internally + * - Files of type md, sms, gg will be loaded by + * the frontend. A valid memory buffer will be + * passed to the core. This memory buffer will + * remain valid until retro_deinit() returns + * - Files of type sg will be loaded by the frontend. + * A valid memory buffer will be passed to the core. + * This memory buffer will remain valid until + * retro_load_game() (or retro_load_game_special()) + * returns + * + * NOTE: If an extension is listed multiple times in + * an array of retro_system_content_info_override + * structs, only the first instance will be registered + */ + +#define RETRO_ENVIRONMENT_GET_GAME_INFO_EXT 66 + /* const struct retro_game_info_ext ** -- + * Allows an implementation to fetch extended game + * information, providing additional content path + * and memory buffer status details. + * This function may only be called inside + * retro_load_game() or retro_load_game_special(). + * If callback returns false, extended game information + * is unsupported by the frontend. In this case, only + * regular retro_game_info will be available. + * RETRO_ENVIRONMENT_GET_GAME_INFO_EXT is guaranteed + * to return true if RETRO_ENVIRONMENT_SET_CONTENT_INFO_OVERRIDE + * returns true. + * + * 'data' points to an array of retro_game_info_ext structs. + * + * For struct member descriptions, see the definition of + * struct retro_game_info_ext. + * + * - If function is called inside retro_load_game(), + * the retro_game_info_ext array is guaranteed to + * have a size of 1 - i.e. the returned pointer may + * be used to access directly the members of the + * first retro_game_info_ext struct, for example: + * + * struct retro_game_info_ext *game_info_ext; + * if (environ_cb(RETRO_ENVIRONMENT_GET_GAME_INFO_EXT, &game_info_ext)) + * printf("Content Directory: %s\n", game_info_ext->dir); + * + * - If the function is called inside retro_load_game_special(), + * the retro_game_info_ext array is guaranteed to have a + * size equal to the num_info argument passed to + * retro_load_game_special() + */ + +/** + * Defines a set of core options that can be shown and configured by the frontend, + * so that the player may customize their gameplay experience to their liking. + * + * @note This environment call is intended to replace + * \c RETRO_ENVIRONMENT_SET_VARIABLES and \c RETRO_ENVIRONMENT_SET_CORE_OPTIONS, + * and should only be called if \c RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION + * returns an API version of at least 2. + * + * This should be called the first time as early as possible, + * ideally in \c retro_set_environment (but \c retro_load_game is acceptable). + * It may then be called again later to update + * the core's options and their associated values, + * as long as the number of options doesn't change + * from the number given in the first call. + * + * The core can retrieve option values at any time with \c RETRO_ENVIRONMENT_GET_VARIABLE. + * If a saved value for a core option doesn't match the option definition's values, + * the frontend may treat it as incorrect and revert to the default. + * + * Core options and their values are usually defined in a large static array, + * but they may be generated at runtime based on the loaded game or system state. + * Here are some use cases for that: + * + * @li Selecting a particular file from one of the + * \ref RETRO_ENVIRONMENT_GET_ASSET_DIRECTORY "frontend's" + * \ref RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY "content" + * \ref RETRO_ENVIRONMENT_GET_CORE_ASSETS_DIRECTORY "directories", + * such as a memory card image or figurine data file. + * @li Excluding options that are not relevant to the current game, + * for cores that define a large number of possible options. + * @li Choosing a default value at runtime for a specific game, + * such as a BIOS file whose region matches that of the loaded content. + * + * @note A guiding principle of libretro's API design is that + * all common interactions (gameplay, menu navigation, etc.) + * should be possible without a keyboard. + * This implies that cores should keep the number of options and values + * as low as possible. + * + * @param[in] data const struct retro_core_options_v2 *. + * Pointer to a core's options and their associated categories. + * May be \c NULL, in which case the frontend will remove all existing core options. + * The frontend must maintain its own copy of this object, + * including all strings and subobjects. + * @return \c true if this environment call is available + * and the frontend supports categories. + * Note that this environment call is guaranteed to successfully register + * the provided core options, + * so the return value does not indicate success or failure. + * + * @see retro_core_options_v2 + * @see retro_core_option_v2_category + * @see retro_core_option_v2_definition + * @see RETRO_ENVIRONMENT_GET_VARIABLE + * @see RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2_INTL + */ +#define RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2 67 + +/** + * A variant of \ref RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2 + * that supports internationalization. + * + * This should be called instead of \c RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2 + * if the core provides translations for its options. + * General use is largely the same, + * but see \ref retro_core_options_v2_intl for some important details. + * + * @param[in] data const struct retro_core_options_v2_intl *. + * Pointer to a core's option values and categories, + * plus a translation for each option and category. + * @see retro_core_options_v2_intl + * @see RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2 + */ +#define RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2_INTL 68 + +/** + * Registers a callback that the frontend can use + * to notify the core that at least one core option + * should be made hidden or visible. + * Allows a frontend to signal that a core must update + * the visibility of any dynamically hidden core options, + * and enables the frontend to detect visibility changes. + * Used by the frontend to update the menu display status + * of core options without requiring a call of retro_run(). + * Must be called in retro_set_environment(). + * + * @param[in] data const struct retro_core_options_update_display_callback *. + * The callback that the frontend should use. + * May be \c NULL, in which case the frontend will unset any existing callback. + * Can be used to query visibility support. + * @return \c true if this environment call is available, + * even if \c data is \c NULL. + * @see retro_core_options_update_display_callback + */ +#define RETRO_ENVIRONMENT_SET_CORE_OPTIONS_UPDATE_DISPLAY_CALLBACK 69 + +/** + * Forcibly sets a core option's value. + * + * After changing a core option value with this callback, + * it will be reflected in the frontend + * and \ref RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE will return \c true. + * \ref retro_variable::key must match + * a \ref RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2 "previously-set core option", + * and \ref retro_variable::value must match one of its defined values. + * + * Possible use cases include: + * + * @li Allowing the player to set certain core options + * without entering the frontend's option menu, + * using an in-core hotkey. + * @li Adjusting invalid combinations of settings. + * @li Migrating settings from older releases of a core. + * + * @param[in] data const struct retro_variable *. + * Pointer to a single option that the core is changing. + * May be \c NULL, in which case the frontend will return \c true + * to indicate that this environment call is available. + * @return \c true if this environment call is available + * and the option named by \c key was successfully + * set to the given \c value. + * \c false if the \c key or \c value fields are \c NULL, empty, + * or don't match a previously set option. + * + * @see RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2 + * @see RETRO_ENVIRONMENT_GET_VARIABLE + * @see RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE + */ +#define RETRO_ENVIRONMENT_SET_VARIABLE 70 + +#define RETRO_ENVIRONMENT_GET_THROTTLE_STATE (71 | RETRO_ENVIRONMENT_EXPERIMENTAL) + /* struct retro_throttle_state * -- + * Allows an implementation to get details on the actual rate + * the frontend is attempting to call retro_run(). + */ + +/** + * Returns information about how the frontend will use savestates. + * + * @param[out] data retro_savestate_context *. + * Pointer to the current savestate context. + * May be \c NULL, in which case the environment call + * will return \c true to indicate its availability. + * @returns \c true if the environment call is available, + * even if \c data is \c NULL. + * @see retro_savestate_context + */ +#define RETRO_ENVIRONMENT_GET_SAVESTATE_CONTEXT (72 | RETRO_ENVIRONMENT_EXPERIMENTAL) + +/** + * Before calling \c SET_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE, will query which interface is supported. + * + * Frontend looks at \c retro_hw_render_interface_type and returns the maximum supported + * context negotiation interface version. If the \c retro_hw_render_interface_type is not + * supported or recognized by the frontend, a version of 0 must be returned in + * \c retro_hw_render_interface's \c interface_version and \c true is returned by frontend. + * + * If this environment call returns true with a \c interface_version greater than 0, + * a core can always use a negotiation interface version larger than what the frontend returns, + * but only earlier versions of the interface will be used by the frontend. + * + * A frontend must not reject a negotiation interface version that is larger than what the + * frontend supports. Instead, the frontend will use the older entry points that it recognizes. + * If this is incompatible with a particular core's requirements, it can error out early. + * + * @note Regarding backwards compatibility, this environment call was introduced after Vulkan v1 + * context negotiation. If this environment call is not supported by frontend, i.e. the environment + * call returns \c false , only Vulkan v1 context negotiation is supported (if Vulkan HW rendering + * is supported at all). If a core uses Vulkan negotiation interface with version > 1, negotiation + * may fail unexpectedly. All future updates to the context negotiation interface implies that + * frontend must support this environment call to query support. + * + * @param[out] data struct retro_hw_render_context_negotiation_interface *. + * @return \c true if the environment call is available. + * @see SET_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE + * @see retro_hw_render_interface_type + * @see retro_hw_render_context_negotiation_interface + */ +#define RETRO_ENVIRONMENT_GET_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE_SUPPORT (73 | RETRO_ENVIRONMENT_EXPERIMENTAL) + +/** + * Asks the frontend whether JIT compilation can be used. + * Primarily used by iOS and tvOS. + * @param[out] data bool *. + * Set to \c true if the frontend has verified that JIT compilation is possible. + * @return \c true if the environment call is available. + */ +#define RETRO_ENVIRONMENT_GET_JIT_CAPABLE 74 + +/** + * Returns an interface that the core can use to receive microphone input. + * + * @param[out] data retro_microphone_interface *. + * Pointer to the microphone interface. + * @return \true if microphone support is available, + * even if no microphones are plugged in. + * \c false if microphone support is disabled unavailable, + * or if \c data is \c NULL. + * @see retro_microphone_interface + */ +#define RETRO_ENVIRONMENT_GET_MICROPHONE_INTERFACE (75 | RETRO_ENVIRONMENT_EXPERIMENTAL) + +/* Environment 76 was an obsolete version of RETRO_ENVIRONMENT_SET_NETPACKET_INTERFACE. +* It was not used by any known core at the time, and was removed from the API. */ + +/** + * Returns the device's current power state as reported by the frontend. + * + * This is useful for emulating the battery level in handheld consoles, + * or for reducing power consumption when on battery power. + * + * @note This environment call describes the power state for the entire device, + * not for individual peripherals like controllers. + * + * @param[out] data . + * Indicates whether the frontend can provide this information, even if the parameter + * is \c NULL. If the frontend does not support this functionality, then the provided + * argument will remain unchanged. + * @return \c true if the environment call is available. + * @see retro_device_power + */ +#define RETRO_ENVIRONMENT_GET_DEVICE_POWER (77 | RETRO_ENVIRONMENT_EXPERIMENTAL) + +#define RETRO_ENVIRONMENT_SET_NETPACKET_INTERFACE 78 + /* const struct retro_netpacket_callback * -- + * When set, a core gains control over network packets sent and + * received during a multiplayer session. This can be used to + * emulate multiplayer games that were originally played on two + * or more separate consoles or computers connected together. + * + * The frontend will take care of connecting players together, + * and the core only needs to send the actual data as needed for + * the emulation, while handshake and connection management happen + * in the background. + * + * When two or more players are connected and this interface has + * been set, time manipulation features (such as pausing, slow motion, + * fast forward, rewinding, save state loading, etc.) are disabled to + * avoid interrupting communication. + * + * Should be set in either retro_init or retro_load_game, but not both. + * + * When not set, a frontend may use state serialization-based + * multiplayer, where a deterministic core supporting multiple + * input devices does not need to take any action on its own. + */ + +/** + * Returns the device's current power state as reported by the frontend. + * This is useful for emulating the battery level in handheld consoles, + * or for reducing power consumption when on battery power. + * + * The return value indicates whether the frontend can provide this information, + * even if the parameter is \c NULL. + * + * If the frontend does not support this functionality, + * then the provided argument will remain unchanged. + * @param[out] data retro_device_power *. + * Pointer to the information that the frontend returns about its power state. + * May be \c NULL. + * @return \c true if the environment call is available, + * even if \c data is \c NULL. + * @see retro_device_power + * @note This environment call describes the power state for the entire device, + * not for individual peripherals like controllers. +*/ +#define RETRO_ENVIRONMENT_GET_DEVICE_POWER (77 | RETRO_ENVIRONMENT_EXPERIMENTAL) + +/** + * Returns the "playlist" directory of the frontend. + * + * This directory can be used to store core generated playlists, in case + * this internal functionality is available (e.g. internal core game detection + * engine). + * + * @param[out] data const char **. + * May be \c NULL. If so, no such directory is defined, and it's up to the + * implementation to find a suitable directory. + * @return \c true if the environment call is available. + */ +#define RETRO_ENVIRONMENT_GET_PLAYLIST_DIRECTORY 79 + +/** + * Returns the "file browser" start directory of the frontend. + * + * This directory can serve as a start directory for the core in case it + * provides an internal way of loading content. + * + * @param[out] data const char **. + * May be \c NULL. If so, no such directory is defined, and it's up to the + * implementation to find a suitable directory. + * @return \c true if the environment call is available. + */ +#define RETRO_ENVIRONMENT_GET_FILE_BROWSER_START_DIRECTORY 80 + +/** + * Returns the audio sample rate the frontend is targeting, in Hz. + * The intended use case is for the core to use the result to select an ideal sample rate. + * + * @param[out] data unsigned *. + * Pointer to the \c unsigned integer in which the frontend will store its target sample rate. + * Behavior is undefined if \c data is NULL. + * @return \c true if this environment call is available, + * regardless of the value returned in \c data. +*/ +#define RETRO_ENVIRONMENT_GET_TARGET_SAMPLE_RATE (81 | RETRO_ENVIRONMENT_EXPERIMENTAL) + +/** + * Returns the local player's netplay client index when using frontend-managed + * multiplayer/rollback netplay. + * + * @param[out] data unsigned *. + * Pointer to an unsigned integer where the frontend stores the local client index. + * 0 indicates host. Values > 0 indicate connected clients. + * @return \\c true if the environment call is available and value was written, + * \\c false otherwise. +*/ +#define RETRO_ENVIRONMENT_GET_NETPLAY_CLIENT_INDEX (82 | RETRO_ENVIRONMENT_EXPERIMENTAL) + +/** + * Allocates a region of executable memory, optionally dual-mapped. + * + * The frontend allocates memory suitable for JIT code generation and returns + * it to the core. The returned mode tells the core how to use the memory: + * + * - \c RETRO_EXEC_MEM_MODE_UNRESTRICTED: The platform has no restrictions + * on executable memory. The core should self-allocate. Do not call + * this environment with a non-zero size in this mode. + * - \c RETRO_EXEC_MEM_MODE_RWX: Single mapping, read-write-execute. + * \c rx and \c rw point to the same region. + * - \c RETRO_EXEC_MEM_MODE_WX_TOGGLE: Single mapping, write XOR execute. + * \c rx and \c rw point to the same region; the core must toggle + * protections itself (e.g. mprotect) before writing or executing. + * - \c RETRO_EXEC_MEM_MODE_DUAL_MAP: Separate read-execute and read-write + * mappings of the same physical pages. The core writes through \c rw + * and executes from \c rx. + * + * Returned memory is page-aligned. The frontend tracks all allocations + * and frees any outstanding ones when the core is unloaded. + * + * The core sets \c version and \c size before calling. The frontend fills + * in \c mode, \c rx, and \c rw on success. + * + * If \c size is 0, this is a probe: the frontend returns \c true and sets + * \c mode to indicate what kind of memory it would provide, but does not + * allocate. \c rx and \c rw will be NULL. Cores can use this to decide + * whether to take a JIT code path before committing to an allocation. + * + * @param[in,out] data struct retro_exec_mem_alloc *. + * @return \c true if the allocation succeeded, \c false otherwise. + * If the frontend does not support this call, returns \c false + * and the core should fall back to managing its own executable memory. + * @see retro_exec_mem_alloc + * @see RETRO_ENVIRONMENT_EXEC_MEM_FREE + */ +#define RETRO_ENVIRONMENT_EXEC_MEM_ALLOC 83 + +/** + * Frees a region of executable memory previously allocated with + * \c RETRO_ENVIRONMENT_EXEC_MEM_ALLOC. + * + * This is optional; the frontend will free all outstanding allocations + * when the core is unloaded. Cores that never need to release memory + * mid-session need not call this. + * + * @param[in] data struct retro_exec_mem_free *. + * @return \c true if the memory was freed, \c false otherwise. + * @see retro_exec_mem_free + * @see RETRO_ENVIRONMENT_EXEC_MEM_ALLOC + */ +#define RETRO_ENVIRONMENT_EXEC_MEM_FREE 84 + +/**@}*/ + +/** + * @defgroup GET_VFS_INTERFACE File System Interface + * @brief File system functionality. + * + * @section File Paths + * File paths passed to all libretro filesystem APIs shall be well formed UNIX-style, + * using "/" (unquoted forward slash) as the directory separator + * regardless of the platform's native separator. + * + * Paths shall also include at least one forward slash + * (e.g. use "./game.bin" instead of "game.bin"). + * + * Other than the directory separator, cores shall not make assumptions about path format. + * The following paths are all valid: + * @li \c C:/path/game.bin + * @li \c http://example.com/game.bin + * @li \c #game/game.bin + * @li \c ./game.bin + * + * Cores may replace the basename or remove path components from the end, and/or add new components; + * however, cores shall not append "./", "../" or multiple consecutive forward slashes ("//") to paths they request from the front end. + * + * The frontend is encouraged to do the best it can when given an ill-formed path, + * but it is allowed to give up. + * + * Frontends are encouraged, but not required, to support native file system paths + * (including replacing the directory separator, if applicable). + * + * Cores are allowed to try using them, but must remain functional if the frontend rejects such requests. + * + * Cores are encouraged to use the libretro-common filestream functions for file I/O, + * as they seamlessly integrate with VFS, + * deal with directory separator replacement as appropriate + * and provide platform-specific fallbacks + * in cases where front ends do not provide their own VFS interface. + * + * @see RETRO_ENVIRONMENT_GET_VFS_INTERFACE + * @see retro_vfs_interface_info + * @see file_path + * @see retro_dirent + * @see file_stream + * + * @{ + */ + +/** + * Opaque file handle. + * @since VFS API v1 + */ +struct retro_vfs_file_handle; + +/** + * Opaque directory handle. + * @since VFS API v3 + */ +struct retro_vfs_dir_handle; + +/** @defgroup RETRO_VFS_FILE_ACCESS File Access Flags + * File access flags. + * @since VFS API v1 + * @{ + */ + +/** Opens a file for read-only access. */ +#define RETRO_VFS_FILE_ACCESS_READ (1 << 0) + +/** + * Opens a file for write-only access. + * Any existing file at this path will be discarded and overwritten + * unless \c RETRO_VFS_FILE_ACCESS_UPDATE_EXISTING is also specified. + */ +#define RETRO_VFS_FILE_ACCESS_WRITE (1 << 1) + +/** + * Opens a file for reading and writing. + * Any existing file at this path will be discarded and overwritten + * unless \c RETRO_VFS_FILE_ACCESS_UPDATE_EXISTING is also specified. + */ +#define RETRO_VFS_FILE_ACCESS_READ_WRITE (RETRO_VFS_FILE_ACCESS_READ | RETRO_VFS_FILE_ACCESS_WRITE) + +/** + * Opens a file without discarding its existing contents. + * Only meaningful if \c RETRO_VFS_FILE_ACCESS_WRITE is specified. + */ +#define RETRO_VFS_FILE_ACCESS_UPDATE_EXISTING (1 << 2) /* Prevents discarding content of existing files opened for writing */ + +/** @} */ + +/** @defgroup RETRO_VFS_FILE_ACCESS_HINT File Access Hints + * + * Hints to the frontend for how a file will be accessed. + * The VFS implementation may use these to optimize performance, + * react to external interference (such as concurrent writes), + * or it may ignore them entirely. + * + * Hint flags do not change the behavior of each VFS function + * unless otherwise noted. + * @{ + */ + +/** No particular hints are given. */ +#define RETRO_VFS_FILE_ACCESS_HINT_NONE (0) + +/** + * Indicates that the file will be accessed frequently. + * + * The frontend should cache it or map it into memory. + */ +#define RETRO_VFS_FILE_ACCESS_HINT_FREQUENT_ACCESS (1 << 0) + +/** @} */ + +/** @defgroup RETRO_VFS_SEEK_POSITION File Seek Positions + * File access flags and hints. + * @{ + */ + +/** + * Indicates a seek relative to the start of the file. + */ +#define RETRO_VFS_SEEK_POSITION_START 0 + +/** + * Indicates a seek relative to the current stream position. + */ +#define RETRO_VFS_SEEK_POSITION_CURRENT 1 + +/** + * Indicates a seek relative to the end of the file. + * @note The offset passed to \c retro_vfs_seek_t should be negative. + */ +#define RETRO_VFS_SEEK_POSITION_END 2 + +/** @} */ + +/** @defgroup RETRO_VFS_STAT File Status Flags + * File stat flags. + * @see retro_vfs_stat_t + * @since VFS API v3 + * @{ + */ + +/** Indicates that the given path refers to a valid file. */ +#define RETRO_VFS_STAT_IS_VALID (1 << 0) + +/** Indicates that the given path refers to a directory. */ +#define RETRO_VFS_STAT_IS_DIRECTORY (1 << 1) + +/** + * Indicates that the given path refers to a character special file, + * such as \c /dev/null. + */ +#define RETRO_VFS_STAT_IS_CHARACTER_SPECIAL (1 << 2) + +/** @} */ + +/** + * Returns the path that was used to open this file. + * + * @param stream The opened file handle to get the path of. + * Behavior is undefined if \c NULL or closed. + * @return The path that was used to open \c stream. + * The string is owned by \c stream and must not be modified. + * @since VFS API v1 + * @see filestream_get_path + */ +typedef const char *(RETRO_CALLCONV *retro_vfs_get_path_t)(struct retro_vfs_file_handle *stream); + +/** + * Open a file for reading or writing. + * + * @param path The path to open. + * @param mode A bitwise combination of \c RETRO_VFS_FILE_ACCESS flags. + * At a minimum, one of \c RETRO_VFS_FILE_ACCESS_READ or \c RETRO_VFS_FILE_ACCESS_WRITE must be specified. + * @param hints A bitwise combination of \c RETRO_VFS_FILE_ACCESS_HINT flags. + * @return A handle to the opened file, + * or \c NULL upon failure. + * Note that this will return \c NULL if \c path names a directory. + * The returned file handle must be closed with \c retro_vfs_close_t. + * @since VFS API v1 + * @see File Paths + * @see RETRO_VFS_FILE_ACCESS + * @see RETRO_VFS_FILE_ACCESS_HINT + * @see retro_vfs_close_t + * @see filestream_open + */ +typedef struct retro_vfs_file_handle *(RETRO_CALLCONV *retro_vfs_open_t)(const char *path, unsigned mode, unsigned hints); + +/** + * Close the file and release its resources. + * All files returned by \c retro_vfs_open_t must be closed with this function. + * + * @param stream The file handle to close. + * Behavior is undefined if already closed. + * Upon completion of this function, \c stream is no longer valid + * (even if it returns failure). + * @return 0 on success, -1 on failure or if \c stream is \c NULL. + * @see retro_vfs_open_t + * @see filestream_close + * @since VFS API v1 + */ +typedef int (RETRO_CALLCONV *retro_vfs_close_t)(struct retro_vfs_file_handle *stream); + +/** + * Return the size of the file in bytes. + * + * @param stream The file to query the size of. + * @return Size of the file in bytes, or -1 if there was an error. + * @see filestream_get_size + * @since VFS API v1 + */ +typedef int64_t (RETRO_CALLCONV *retro_vfs_size_t)(struct retro_vfs_file_handle *stream); + +/** + * Set the file's length. + * + * @param stream The file whose length will be adjusted. + * @param length The new length of the file, in bytes. + * If shorter than the original length, the extra bytes will be discarded. + * If longer, the file's padding is unspecified (and likely platform-dependent). + * @return 0 on success, + * -1 on failure. + * @see filestream_truncate + * @since VFS API v2 + */ +typedef int64_t (RETRO_CALLCONV *retro_vfs_truncate_t)(struct retro_vfs_file_handle *stream, int64_t length); + +/** + * Gets the given file's current read/write position. + * This position is advanced with each call to \c retro_vfs_read_t or \c retro_vfs_write_t. + * + * @param stream The file to query the position of. + * @return The current stream position in bytes + * or -1 if there was an error. + * @see filestream_tell + * @since VFS API v1 + */ +typedef int64_t (RETRO_CALLCONV *retro_vfs_tell_t)(struct retro_vfs_file_handle *stream); + +/** + * Sets the given file handle's current read/write position. + * + * @param stream The file to set the position of. + * @param offset The new position, in bytes. + * @param seek_position The position to seek from. + * @return The new position, + * or -1 if there was an error. + * @since VFS API v1 + * @see File Seek Positions + * @see filestream_seek + */ +typedef int64_t (RETRO_CALLCONV *retro_vfs_seek_t)(struct retro_vfs_file_handle *stream, int64_t offset, int seek_position); + +/** + * Read data from a file, if it was opened for reading. + * + * @param stream The file to read from. + * @param s The buffer to read into. + * @param len The number of bytes to read. + * The buffer pointed to by \c s must be this large. + * @return The number of bytes read, + * or -1 if there was an error. + * @since VFS API v1 + * @see filestream_read + */ +typedef int64_t (RETRO_CALLCONV *retro_vfs_read_t)(struct retro_vfs_file_handle *stream, void *s, uint64_t len); + +/** + * Write data to a file, if it was opened for writing. + * + * @param stream The file handle to write to. + * @param s The buffer to write from. + * @param len The number of bytes to write. + * The buffer pointed to by \c s must be this large. + * @return The number of bytes written, + * or -1 if there was an error. + * @since VFS API v1 + * @see filestream_write + */ +typedef int64_t (RETRO_CALLCONV *retro_vfs_write_t)(struct retro_vfs_file_handle *stream, const void *s, uint64_t len); + +/** + * Flush pending writes to the file, if applicable. + * + * This does not mean that the changes will be immediately persisted to disk; + * that may be scheduled for later, depending on the platform. + * + * @param stream The file handle to flush. + * @return 0 on success, -1 on failure. + * @since VFS API v1 + * @see filestream_flush + */ +typedef int (RETRO_CALLCONV *retro_vfs_flush_t)(struct retro_vfs_file_handle *stream); + +/** + * Deletes the file at the given path. + * + * @param path The path to the file that will be deleted. + * @return 0 on success, -1 on failure. + * @see filestream_delete + * @since VFS API v1 + */ +typedef int (RETRO_CALLCONV *retro_vfs_remove_t)(const char *path); + +/** + * Rename the specified file. + * + * @param old_path Path to an existing file. + * @param new_path The destination path. + * Must not name an existing file. + * @return 0 on success, -1 on failure + * @see filestream_rename + * @since VFS API v1 + */ +typedef int (RETRO_CALLCONV *retro_vfs_rename_t)(const char *old_path, const char *new_path); + +/** + * Gets information about the given file. + * + * @param path The path to the file to query. + * @param[out] size The reported size of the file in bytes. + * May be \c NULL, in which case this value is ignored. + * @return A bitmask of \c RETRO_VFS_STAT flags, + * or 0 if \c path doesn't refer to a valid file. + * @see path_stat + * @see path_get_size + * @see RETRO_VFS_STAT + * @since VFS API v3 + */ +typedef int (RETRO_CALLCONV *retro_vfs_stat_t)(const char *path, int32_t *size); + +/** + * Gets information about the given file (64-bit size). + * + * @param path The path to the file to query. + * @param[out] size The reported size of the file in bytes. + * May be \c NULL, in which case this value is ignored. + * @return A bitmask of \c RETRO_VFS_STAT flags, + * or 0 if \c path doesn't refer to a valid file. + * @see RETRO_VFS_STAT + * @since VFS API v4 + */ +typedef int (RETRO_CALLCONV *retro_vfs_stat_64_t)(const char *path, int64_t *size); + +/** + * Creates a directory at the given path. + * + * @param dir The desired location of the new directory. + * @return 0 if the directory was created, + * -2 if the directory already exists, + * or -1 if some other error occurred. + * @see path_mkdir + * @since VFS API v3 + */ +typedef int (RETRO_CALLCONV *retro_vfs_mkdir_t)(const char *dir); + +/** + * Opens a handle to a directory so its contents can be inspected. + * + * @param dir The path to the directory to open. + * Must be an existing directory. + * @param include_hidden Whether to include hidden files in the directory listing. + * The exact semantics of this flag will depend on the platform. + * @return A handle to the opened directory, + * or \c NULL if there was an error. + * @see retro_opendir + * @since VFS API v3 + */ +typedef struct retro_vfs_dir_handle *(RETRO_CALLCONV *retro_vfs_opendir_t)(const char *dir, bool include_hidden); + +/** + * Gets the next dirent ("directory entry") + * within the given directory. + * + * @param[in,out] dirstream The directory to read from. + * Updated to point to the next file, directory, or other path. + * @return \c true when the next dirent was retrieved, + * \c false if there are no more dirents to read. + * @note This API iterates over all files and directories within \c dirstream. + * Remember to check what the type of the current dirent is. + * @note This function does not recurse, + * i.e. it does not return the contents of subdirectories. + * @note This may include "." and ".." on Unix-like platforms. + * @see retro_readdir + * @see retro_vfs_dirent_is_dir_t + * @since VFS API v3 + */ +typedef bool (RETRO_CALLCONV *retro_vfs_readdir_t)(struct retro_vfs_dir_handle *dirstream); + +/** + * Gets the filename of the current dirent. + * + * The returned string pointer is valid + * until the next call to \c retro_vfs_readdir_t or \c retro_vfs_closedir_t. + * + * @param dirstream The directory to read from. + * @return The current dirent's name, + * or \c NULL if there was an error. + * @note This function only returns the file's \em name, + * not a complete path to it. + * @see retro_dirent_get_name + * @since VFS API v3 + */ +typedef const char *(RETRO_CALLCONV *retro_vfs_dirent_get_name_t)(struct retro_vfs_dir_handle *dirstream); + +/** + * Checks whether the current dirent names a directory. + * + * @param dirstream The directory to read from. + * @return \c true if \c dirstream's current dirent points to a directory, + * \c false if not or if there was an error. + * @see retro_dirent_is_dir + * @since VFS API v3 + */ +typedef bool (RETRO_CALLCONV *retro_vfs_dirent_is_dir_t)(struct retro_vfs_dir_handle *dirstream); + +/** + * Closes the given directory and release its resources. + * + * Must be called on any \c retro_vfs_dir_handle returned by \c retro_vfs_open_t. + * + * @param dirstream The directory to close. + * When this function returns (even failure), + * \c dirstream will no longer be valid and must not be used. + * @return 0 on success, -1 on failure. + * @see retro_closedir + * @since VFS API v3 + */ +typedef int (RETRO_CALLCONV *retro_vfs_closedir_t)(struct retro_vfs_dir_handle *dirstream); + +/** + * File system interface exposed by the frontend. + * + * @see dirent_vfs_init + * @see filestream_vfs_init + * @see path_vfs_init + * @see RETRO_ENVIRONMENT_GET_VFS_INTERFACE + */ +struct retro_vfs_interface +{ + /* VFS API v1 */ + /** @copydoc retro_vfs_get_path_t */ + retro_vfs_get_path_t get_path; + + /** @copydoc retro_vfs_open_t */ + retro_vfs_open_t open; + + /** @copydoc retro_vfs_close_t */ + retro_vfs_close_t close; + + /** @copydoc retro_vfs_size_t */ + retro_vfs_size_t size; + + /** @copydoc retro_vfs_tell_t */ + retro_vfs_tell_t tell; + + /** @copydoc retro_vfs_seek_t */ + retro_vfs_seek_t seek; + + /** @copydoc retro_vfs_read_t */ + retro_vfs_read_t read; + + /** @copydoc retro_vfs_write_t */ + retro_vfs_write_t write; + + /** @copydoc retro_vfs_flush_t */ + retro_vfs_flush_t flush; + + /** @copydoc retro_vfs_remove_t */ + retro_vfs_remove_t remove; + + /** @copydoc retro_vfs_rename_t */ + retro_vfs_rename_t rename; + /* VFS API v2 */ + + /** @copydoc retro_vfs_truncate_t */ + retro_vfs_truncate_t truncate; + /* VFS API v3 */ + + /** @copydoc retro_vfs_stat_t */ + retro_vfs_stat_t stat; + + /** @copydoc retro_vfs_mkdir_t */ + retro_vfs_mkdir_t mkdir; + + /** @copydoc retro_vfs_opendir_t */ + retro_vfs_opendir_t opendir; + + /** @copydoc retro_vfs_readdir_t */ + retro_vfs_readdir_t readdir; + + /** @copydoc retro_vfs_dirent_get_name_t */ + retro_vfs_dirent_get_name_t dirent_get_name; + + /** @copydoc retro_vfs_dirent_is_dir_t */ + retro_vfs_dirent_is_dir_t dirent_is_dir; + + /** @copydoc retro_vfs_closedir_t */ + retro_vfs_closedir_t closedir; + + /* VFS API v4 */ + /** @copydoc retro_vfs_stat_64_t */ + retro_vfs_stat_64_t stat_64; +}; + +/** + * Represents a request by the core for the frontend's file system interface, + * as well as the interface itself returned by the frontend. + * + * You do not need to use these functions directly; + * you may pass this struct to \c dirent_vfs_init, + * \c filestream_vfs_init, or \c path_vfs_init + * so that you can use the wrappers provided by these modules. + * + * @see dirent_vfs_init + * @see filestream_vfs_init + * @see path_vfs_init + * @see RETRO_ENVIRONMENT_GET_VFS_INTERFACE + */ +struct retro_vfs_interface_info +{ + /** + * The minimum version of the VFS API that the core requires. + * libretro-common's wrapper API initializers will check this value as well. + * + * Set to the core's desired VFS version when requesting an interface, + * and set by the frontend to indicate its actual API version. + * + * If the core asks for a newer VFS API version than the frontend supports, + * the frontend must return \c false within the \c RETRO_ENVIRONMENT_GET_VFS_INTERFACE call. + * @since VFS API v1 + */ + uint32_t required_interface_version; + + /** + * Set by the frontend. + * The frontend will set this to the VFS interface it provides. + * + * The interface is owned by the frontend + * and must not be modified or freed by the core. + * @since VFS API v1 */ + struct retro_vfs_interface *iface; +}; + +/** @} */ + +/** @defgroup GET_HW_RENDER_INTERFACE Hardware Rendering Interface + * @{ + */ + +/** + * Describes the hardware rendering API supported by + * a particular subtype of \c retro_hw_render_interface. + * + * Not every rendering API supported by libretro has its own interface, + * or even needs one. + * + * @see RETRO_ENVIRONMENT_SET_HW_RENDER + * @see RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE + */ +enum retro_hw_render_interface_type +{ + /** + * Indicates a \c retro_hw_render_interface for Vulkan. + * @see retro_hw_render_interface_vulkan + */ + RETRO_HW_RENDER_INTERFACE_VULKAN = 0, + + /** Indicates a \c retro_hw_render_interface for Direct3D 9. */ + RETRO_HW_RENDER_INTERFACE_D3D9 = 1, + + /** Indicates a \c retro_hw_render_interface for Direct3D 10. */ + RETRO_HW_RENDER_INTERFACE_D3D10 = 2, + + /** + * Indicates a \c retro_hw_render_interface for Direct3D 11. + * @see retro_hw_render_interface_d3d11 + */ + RETRO_HW_RENDER_INTERFACE_D3D11 = 3, + + /** + * Indicates a \c retro_hw_render_interface for Direct3D 12. + * @see retro_hw_render_interface_d3d12 + */ + RETRO_HW_RENDER_INTERFACE_D3D12 = 4, + + /** + * Indicates a \c retro_hw_render_interface for + * the PlayStation's 2 PSKit API. + * @see retro_hw_render_interface_gskit_ps2 + */ + RETRO_HW_RENDER_INTERFACE_GSKIT_PS2 = 5, + + /** @private Defined to ensure sizeof(retro_hw_render_interface_type) == sizeof(int). + * Do not use. */ + RETRO_HW_RENDER_INTERFACE_DUMMY = INT_MAX +}; + +/** + * Base render interface type. + * All \c retro_hw_render_interface implementations + * will start with these two fields set to particular values. + * + * @see retro_hw_render_interface_type + * @see RETRO_ENVIRONMENT_SET_HW_RENDER + * @see RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE + */ +struct retro_hw_render_interface +{ + /** + * Denotes the particular rendering API that this interface is for. + * Each interface requires this field to be set to a particular value. + * Use it to cast this interface to the appropriate pointer. + */ + enum retro_hw_render_interface_type interface_type; + + /** + * The version of this rendering interface. + * @note This is not related to the version of the API itself. + */ + unsigned interface_version; +}; + +/** @} */ + +/** + * @defgroup GET_LED_INTERFACE LED Interface + * @{ + */ + +/** @copydoc retro_led_interface::set_led_state */ +typedef void (RETRO_CALLCONV *retro_set_led_state_t)(int led, int state); + +/** + * Interface that the core can use to set the state of available LEDs. + * @see RETRO_ENVIRONMENT_GET_LED_INTERFACE + */ +struct retro_led_interface +{ + /** + * Sets the state of an LED. + * + * @param led The LED to set the state of. + * @param state The state to set the LED to. + * \c true to enable, \c false to disable. + */ + retro_set_led_state_t set_led_state; +}; + +/** @} */ + +/** @defgroup GET_AUDIO_VIDEO_ENABLE Skipped A/V Steps + * @{ + */ + +/** + * Flags that define A/V steps that the core may skip for this frame. + * + * @see RETRO_ENVIRONMENT_GET_AUDIO_VIDEO_ENABLE + */ +enum retro_av_enable_flags +{ + /** + * If set, the core should render video output with \c retro_video_refresh_t as normal. + * + * Otherwise, the frontend will discard any video data received this frame, + * including frames presented via hardware acceleration. + * \c retro_video_refresh_t will do nothing. + * + * @note After running the frame, the video output of the next frame + * should be no different than if video was enabled, + * and saving and loading state should have no issues. + * This implies that the emulated console's graphics pipeline state + * should not be affected by this flag. + * + * @note If emulating a platform that supports display capture + * (i.e. reading its own VRAM), + * the core may not be able to completely skip rendering, + * as the VRAM is part of the graphics pipeline's state. + */ + RETRO_AV_ENABLE_VIDEO = (1 << 0), + + /** + * If set, the core should render audio output + * with \c retro_audio_sample_t or \c retro_audio_sample_batch_t as normal. + * + * Otherwise, the frontend will discard any audio data received this frame. + * The core should skip audio rendering if possible. + * + * @note After running the frame, the audio output of the next frame + * should be no different than if audio was enabled, + * and saving and loading state should have no issues. + * This implies that the emulated console's audio pipeline state + * should not be affected by this flag. + */ + RETRO_AV_ENABLE_AUDIO = (1 << 1), + + /** + * If set, indicates that any savestates taken this frame + * are guaranteed to be created by the same binary that will load them, + * and will not be written to or read from the disk. + * + * The core may use these guarantees to: + * + * @li Assume that loading state will succeed. + * @li Update its memory buffers in-place if possible. + * @li Skip clearing memory. + * @li Skip resetting the system. + * @li Skip validation steps. + * + * @deprecated Use \c RETRO_ENVIRONMENT_GET_SAVESTATE_CONTEXT instead, + * except for compatibility purposes. + */ + RETRO_AV_ENABLE_FAST_SAVESTATES = (1 << 2), + + /** + * If set, indicates that the frontend will never need audio from the core. + * Used by a frontend for implementing runahead via a secondary core instance. + * + * The core may stop synthesizing audio if it can do so + * without compromising emulation accuracy. + * + * Audio output for the next frame does not matter, + * and the frontend will never need an accurate audio state in the future. + * + * State will never be saved while this flag is set. + */ + RETRO_AV_ENABLE_HARD_DISABLE_AUDIO = (1 << 3), + + /** + * @private Defined to ensure sizeof(retro_av_enable_flags) == sizeof(int). + * Do not use. + */ + RETRO_AV_ENABLE_DUMMY = INT_MAX +}; + +/** @} */ + +/** + * @defgroup GET_MIDI_INTERFACE MIDI Interface + * @{ + */ + +/** @copydoc retro_midi_interface::input_enabled */ +typedef bool (RETRO_CALLCONV *retro_midi_input_enabled_t)(void); + +/** @copydoc retro_midi_interface::output_enabled */ +typedef bool (RETRO_CALLCONV *retro_midi_output_enabled_t)(void); + +/** @copydoc retro_midi_interface::read */ +typedef bool (RETRO_CALLCONV *retro_midi_read_t)(uint8_t *byte); + +/** @copydoc retro_midi_interface::write */ +typedef bool (RETRO_CALLCONV *retro_midi_write_t)(uint8_t byte, uint32_t delta_time); + +/** @copydoc retro_midi_interface::flush */ +typedef bool (RETRO_CALLCONV *retro_midi_flush_t)(void); + +/** + * Interface that the core can use for raw MIDI I/O. + */ +struct retro_midi_interface +{ + /** + * Retrieves the current state of MIDI input. + * + * @return \c true if MIDI input is enabled. + */ + retro_midi_input_enabled_t input_enabled; + + /** + * Retrieves the current state of MIDI output. + * @return \c true if MIDI output is enabled. + */ + retro_midi_output_enabled_t output_enabled; + + /** + * Reads a byte from the MIDI input stream. + * + * @param[out] byte The byte received from the input stream. + * @return \c true if a byte was read, + * \c false if MIDI input is disabled or \c byte is \c NULL. + */ + retro_midi_read_t read; + + /** + * Writes a byte to the output stream. + * + * @param byte The byte to write to the output stream. + * @param delta_time Time since the previous write, in microseconds. + * @return \c true if c\ byte was written, false otherwise. + */ + retro_midi_write_t write; + + /** + * Flushes previously-written data. + * + * @return \c true if successful. + */ + retro_midi_flush_t flush; +}; + +/** @} */ + +/** @defgroup SET_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE Render Context Negotiation + * @{ + */ + +/** + * Describes the hardware rendering API used by + * a particular subtype of \c retro_hw_render_context_negotiation_interface. + * + * Not every rendering API supported by libretro has a context negotiation interface, + * or even needs one. + * + * @see RETRO_ENVIRONMENT_SET_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE + * @see RETRO_ENVIRONMENT_SET_HW_RENDER + * @see RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE + */ +enum retro_hw_render_context_negotiation_interface_type +{ + /** + * Denotes a context negotiation interface for Vulkan. + * @see retro_hw_render_context_negotiation_interface_vulkan + */ + RETRO_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE_VULKAN = 0, + + /** + * @private Defined to ensure sizeof(retro_hw_render_context_negotiation_interface_type) == sizeof(int). + * Do not use. + */ + RETRO_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE_DUMMY = INT_MAX +}; + +/** + * Base context negotiation interface type. + * All \c retro_hw_render_context_negotiation_interface implementations + * will start with these two fields set to particular values. + * + * @see retro_hw_render_interface_type + * @see RETRO_ENVIRONMENT_SET_HW_RENDER + * @see RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE + * @see RETRO_ENVIRONMENT_SET_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE + */ +struct retro_hw_render_context_negotiation_interface +{ + /** + * Denotes the particular rendering API that this interface is for. + * Each interface requires this field to be set to a particular value. + * Use it to cast this interface to the appropriate pointer. + */ + enum retro_hw_render_context_negotiation_interface_type interface_type; + + /** + * The version of this negotiation interface. + * @note This is not related to the version of the API itself. + */ + unsigned interface_version; +}; + +/** @} */ + +/** @defgroup RETRO_SERIALIZATION_QUIRK Serialization Quirks + * @{ + */ + +/** + * Indicates that serialized state is incomplete in some way. + * + * Set if serialization is usable for the common case of saving and loading game state, + * but should not be relied upon for frame-sensitive frontend features + * such as netplay or rerecording. + */ +#define RETRO_SERIALIZATION_QUIRK_INCOMPLETE (1 << 0) + +/** + * Indicates that core must spend some time initializing before serialization can be done. + * + * \c retro_serialize(), \c retro_unserialize(), and \c retro_serialize_size() will initially fail. + */ +#define RETRO_SERIALIZATION_QUIRK_MUST_INITIALIZE (1 << 1) + +/** Set by the core to indicate that serialization size may change within a session. */ +#define RETRO_SERIALIZATION_QUIRK_CORE_VARIABLE_SIZE (1 << 2) + +/** Set by the frontend to acknowledge that it supports variable-sized states. */ +#define RETRO_SERIALIZATION_QUIRK_FRONT_VARIABLE_SIZE (1 << 3) + +/** Serialized state can only be loaded during the same session. */ +#define RETRO_SERIALIZATION_QUIRK_SINGLE_SESSION (1 << 4) + +/** + * Serialized state cannot be loaded on an architecture + * with a different endianness from the one it was saved on. + */ +#define RETRO_SERIALIZATION_QUIRK_ENDIAN_DEPENDENT (1 << 5) + +/** + * Serialized state cannot be loaded on a different platform + * from the one it was saved on for reasons other than endianness, + * such as word size dependence. + */ +#define RETRO_SERIALIZATION_QUIRK_PLATFORM_DEPENDENT (1 << 6) + +/** @} */ + +/** @defgroup SET_MEMORY_MAPS Memory Descriptors + * @{ + */ + +/** @defgroup RETRO_MEMDESC Memory Descriptor Flags + * Information about how the emulated hardware uses this portion of its address space. + * @{ + */ + +/** + * Indicates that this memory area won't be modified + * once \c retro_load_game has returned. + */ +#define RETRO_MEMDESC_CONST (1 << 0) + +/** + * Indicates a memory area with big-endian byte ordering, + * as opposed to the default of little-endian. + */ +#define RETRO_MEMDESC_BIGENDIAN (1 << 1) + +/** + * Indicates a memory area that is used for the emulated system's main RAM. + */ +#define RETRO_MEMDESC_SYSTEM_RAM (1 << 2) + +/** + * Indicates a memory area that is used for the emulated system's save RAM, + * usually found on a game cartridge as battery-backed RAM or flash memory. + */ +#define RETRO_MEMDESC_SAVE_RAM (1 << 3) + +/** + * Indicates a memory area that is used for the emulated system's video RAM, + * usually found on a console's GPU (or local equivalent). + */ +#define RETRO_MEMDESC_VIDEO_RAM (1 << 4) + +/** + * Indicates a memory area that requires all accesses + * to be aligned to 2 bytes or their own size + * (whichever is smaller). + */ +#define RETRO_MEMDESC_ALIGN_2 (1 << 16) + +/** + * Indicates a memory area that requires all accesses + * to be aligned to 4 bytes or their own size + * (whichever is smaller). + */ +#define RETRO_MEMDESC_ALIGN_4 (2 << 16) + +/** + * Indicates a memory area that requires all accesses + * to be aligned to 8 bytes or their own size + * (whichever is smaller). + */ +#define RETRO_MEMDESC_ALIGN_8 (3 << 16) + +/** + * Indicates a memory area that requires all accesses + * to be at least 2 bytes long. + */ +#define RETRO_MEMDESC_MINSIZE_2 (1 << 24) + +/** + * Indicates a memory area that requires all accesses + * to be at least 4 bytes long. + */ +#define RETRO_MEMDESC_MINSIZE_4 (2 << 24) + +/** + * Indicates a memory area that requires all accesses + * to be at least 8 bytes long. + */ +#define RETRO_MEMDESC_MINSIZE_8 (3 << 24) + +/** @} */ + +/** + * A mapping from a region of the emulated console's address space + * to the host's address space. + * + * Can be used to map an address in the console's address space + * to the host's address space, like so: + * + * @code + * void* emu_to_host(void* addr, struct retro_memory_descriptor* descriptor) + * { + * return descriptor->ptr + (addr & ~descriptor->disconnect) - descriptor->start; + * } + * @endcode + * + * @see RETRO_ENVIRONMENT_SET_MEMORY_MAPS + */ +struct retro_memory_descriptor +{ + /** + * A bitwise \c OR of one or more \ref RETRO_MEMDESC "flags" + * that describe how the emulated system uses this descriptor's address range. + * + * @note If \c ptr is \c NULL, + * then no flags should be set. + * @see RETRO_MEMDESC + */ + uint64_t flags; + + /** + * Pointer to the start of this memory region's buffer + * within the \em host's address space. + * The address listed here must be valid for the duration of the session; + * it must not be freed or modified by the frontend + * and it must not be moved by the core. + * + * May be \c NULL to indicate a lack of accessible memory + * at the emulated address given in \c start. + * + * @note Overlapping descriptors that include the same byte + * must have the same \c ptr value. + */ + void *ptr; + + /** + * The offset of this memory region, + * relative to the address given by \c ptr. + * + * @note It is recommended to use this field for address calculations + * instead of performing arithmetic on \c ptr. + */ + size_t offset; + + /** + * The starting address of this memory region + * within the emulated hardware's address space. + * + * @note Not represented as a pointer + * because it's unlikely to be valid on the host device. + */ + size_t start; + + /** + * A bitmask that specifies which bits of an address must match + * the bits of the \ref start address. + * + * Combines with \c disconnect to map an address to a memory block. + * + * If multiple memory descriptors can claim a particular byte, + * the first one defined in the \ref retro_memory_descriptor array applies. + * A bit which is set in \c start must also be set in this. + * + * Can be zero, in which case \c start and \c len represent + * the complete mapping for this region of memory + * (i.e. each byte is mapped exactly once). + * In this case, \c len must be a power of two. + */ + size_t select; + + /** + * A bitmask of bits that are \em not used for addressing. + * + * Any set bits are assumed to be disconnected from + * the emulated memory chip's address pins, + * and are therefore ignored when memory-mapping. + */ + size_t disconnect; + + /** + * The length of this memory region, in bytes. + * + * If applying \ref start and \ref disconnect to an address + * results in a value higher than this, + * the highest bit of the address is cleared. + * + * If the address is still too high, the next highest bit is cleared. + * Can be zero, in which case it's assumed to be + * bounded only by \ref select and \ref disconnect. + */ + size_t len; + + /** + * A short name for this address space. + * + * Names must meet the following requirements: + * + * \li Characters must be in the set [a-zA-Z0-9_-]. + * \li No more than 8 characters, plus a \c NULL terminator. + * \li Names are case-sensitive, but lowercase characters are discouraged. + * \li A name must not be the same as another name plus a character in the set \c [A-F0-9] + * (i.e. if an address space named "RAM" exists, + * then the names "RAM0", "RAM1", ..., "RAMF" are forbidden). + * This is to allow addresses to be named by each descriptor unambiguously, + * even if the areas overlap. + * \li May be \c NULL or empty (both are considered equivalent). + * + * Here are some examples of pairs of address space names: + * + * \li \em blank + \em blank: valid (multiple things may be mapped in the same namespace) + * \li \c Sp + \c Sp: valid (multiple things may be mapped in the same namespace) + * \li \c SRAM + \c VRAM: valid (neither is a prefix of the other) + * \li \c V + \em blank: valid (\c V is not in \c [A-F0-9]) + * \li \c a + \em blank: valid but discouraged (\c a is not in \c [A-F0-9]) + * \li \c a + \c A: valid but discouraged (neither is a prefix of the other) + * \li \c AR + \em blank: valid (\c R is not in \c [A-F0-9]) + * \li \c ARB + \em blank: valid (there's no \c AR namespace, + * so the \c B doesn't cause ambiguity). + * \li \em blank + \c B: invalid, because it's ambiguous which address space \c B1234 would refer to. + * + * The length of the address space's name can't be used to disambugiate, + * as extra information may be appended to it without a separator. + */ + const char *addrspace; + + /* TODO: When finalizing this one, add a description field, which should be + * "WRAM" or something roughly equally long. */ + + /* TODO: When finalizing this one, replace 'select' with 'limit', which tells + * which bits can vary and still refer to the same address (limit = ~select). + * TODO: limit? range? vary? something else? */ + + /* TODO: When finalizing this one, if 'len' is above what 'select' (or + * 'limit') allows, it's bankswitched. Bankswitched data must have both 'len' + * and 'select' != 0, and the mappings don't tell how the system switches the + * banks. */ + + /* TODO: When finalizing this one, fix the 'len' bit removal order. + * For len=0x1800, pointer 0x1C00 should go to 0x1400, not 0x0C00. + * Algorithm: Take bits highest to lowest, but if it goes above len, clear + * the most recent addition and continue on the next bit. + * TODO: Can the above be optimized? Is "remove the lowest bit set in both + * pointer and 'len'" equivalent? */ + + /* TODO: Some emulators (MAME?) emulate big endian systems by only accessing + * the emulated memory in 32-bit chunks, native endian. But that's nothing + * compared to Darek Mihocka + * (section Emulation 103 - Nearly Free Byte Reversal) - he flips the ENTIRE + * RAM backwards! I'll want to represent both of those, via some flags. + * + * I suspect MAME either didn't think of that idea, or don't want the #ifdef. + * Not sure which, nor do I really care. */ + + /* TODO: Some of those flags are unused and/or don't really make sense. Clean + * them up. */ +}; + +/** + * A list of regions within the emulated console's address space. + * + * The frontend may use the largest value of + * \ref retro_memory_descriptor::start + \ref retro_memory_descriptor::select + * in a certain namespace to infer the overall size of the address space. + * If the address space is larger than that, + * the last mapping in \ref descriptors should have \ref retro_memory_descriptor::ptr set to \c NULL + * and \ref retro_memory_descriptor::select should have all bits used in the address space set to 1. + * + * Here's an example set of descriptors for the SNES. + * + * @code{.c} + * struct retro_memory_map snes_descriptors = retro_memory_map + * { + * .descriptors = (struct retro_memory_descriptor[]) + * { + * // WRAM; must usually be mapped before the ROM, + * // as some SNES ROM mappers try to claim 0x7E0000 + * { .addrspace="WRAM", .start=0x7E0000, .len=0x20000 }, + * + * // SPC700 RAM + * { .addrspace="SPC700", .len=0x10000 }, + * + * // WRAM mirrors + * { .addrspace="WRAM", .start=0x000000, .select=0xC0E000, .len=0x2000 }, + * { .addrspace="WRAM", .start=0x800000, .select=0xC0E000, .len=0x2000 }, + * + * // WRAM mirror, alternate equivalent descriptor + * // (Various similar constructions can be created by combining parts of the above two.) + * { .addrspace="WRAM", .select=0x40E000, .disconnect=~0x1FFF }, + * + * // LoROM (512KB, mirrored a couple of times) + * { .addrspace="LoROM", .start=0x008000, .select=0x408000, .disconnect=0x8000, .len=512*1024, .flags=RETRO_MEMDESC_CONST }, + * { .addrspace="LoROM", .start=0x400000, .select=0x400000, .disconnect=0x8000, .len=512*1024, .flags=RETRO_MEMDESC_CONST }, + * + * // HiROM (4MB) + * { .addrspace="HiROM", .start=0x400000, .select=0x400000, .len=4*1024*1024, .flags=RETRO_MEMDESC_CONST }, + * { .addrspace="HiROM", .start=0x008000, .select=0x408000, .len=4*1024*1024, .offset=0x8000, .flags=RETRO_MEMDESC_CONST }, + * + * // ExHiROM (8MB) + * { .addrspace="ExHiROM", .start=0xC00000, .select=0xC00000, .len=4*1024*1024, .offset=0, .flags=RETRO_MEMDESC_CONST }, + * { .addrspace="ExHiROM", .start=0x400000, .select=0xC00000, .len=4*1024*1024, .offset=4*1024*1024, .flags=RETRO_MEMDESC_CONST }, + * { .addrspace="ExHiROM", .start=0x808000, .select=0xC08000, .len=4*1024*1024, .offset=0x8000, .flags=RETRO_MEMDESC_CONST }, + * { .addrspace="ExHiROM", .start=0x008000, .select=0xC08000, .len=4*1024*1024, .offset=4*1024*1024+0x8000, .flags=RETRO_MEMDESC_CONST }, + * + * // Clarifying the full size of the address space + * { .select=0xFFFFFF, .ptr=NULL }, + * }, + * .num_descriptors = 14, + * }; + * @endcode + * + * @see RETRO_ENVIRONMENT_SET_MEMORY_MAPS + */ +struct retro_memory_map +{ + /** + * Pointer to an array of memory descriptors, + * each of which describes part of the emulated console's address space. + */ + const struct retro_memory_descriptor *descriptors; + + /** The number of descriptors in \c descriptors. */ + unsigned num_descriptors; +}; + +/** @} */ + +/** @defgroup SET_CONTROLLER_INFO Controller Info + * @{ + */ + +/** + * Details about a controller (or controller configuration) + * supported by one of a core's emulated input ports. + * + * @see RETRO_ENVIRONMENT_SET_CONTROLLER_INFO + */ +struct retro_controller_description +{ + /** + * A human-readable label for the controller or configuration + * represented by this device type. + * Most likely the device's original brand name. + */ + const char *desc; + + /** + * A unique identifier that will be passed to \c retro_set_controller_port_device()'s \c device parameter. + * May be the ID of one of \ref RETRO_DEVICE "the generic controller types", + * or a subclass ID defined with \c RETRO_DEVICE_SUBCLASS. + * + * @see RETRO_DEVICE_SUBCLASS + */ + unsigned id; +}; + +/** + * Lists the types of controllers supported by + * one of core's emulated input ports. + * + * @see RETRO_ENVIRONMENT_SET_CONTROLLER_INFO + */ +struct retro_controller_info +{ + + /** + * A pointer to an array of device types supported by this controller port. + * + * @note Ports that support the same devices + * may share the same underlying array. + */ + const struct retro_controller_description *types; + + /** The number of elements in \c types. */ + unsigned num_types; +}; + +/** @} */ + +/** @defgroup SET_SUBSYSTEM_INFO Subsystems + * @{ + */ + +/** + * Information about a type of memory associated with a subsystem. + * Usually used for SRAM (save RAM). + * + * @see RETRO_ENVIRONMENT_SET_SUBSYSTEM_INFO + * @see retro_get_memory_data + * @see retro_get_memory_size + */ +struct retro_subsystem_memory_info +{ + /** + * The file extension the frontend should use + * to save this memory region to disk, e.g. "srm" or "sav". + */ + const char *extension; + + /** + * A constant that identifies this type of memory. + * Should be at least 0x100 (256) to avoid conflict + * with the standard libretro memory types, + * unless a subsystem uses the main platform's memory region. + * @see RETRO_MEMORY + */ + unsigned type; +}; + +/** + * Information about a type of ROM that a subsystem may use. + * Subsystems may use one or more ROMs at once, + * possibly of different types. + * + * @see RETRO_ENVIRONMENT_SET_SUBSYSTEM_INFO + * @see retro_subsystem_info + */ +struct retro_subsystem_rom_info +{ + /** + * Human-readable description of what the content represents, + * e.g. "Game Boy ROM". + */ + const char *desc; + + /** @copydoc retro_system_info::valid_extensions */ + const char *valid_extensions; + + /** @copydoc retro_system_info::need_fullpath */ + bool need_fullpath; + + /** @copydoc retro_system_info::block_extract */ + bool block_extract; + + /** + * Indicates whether this particular subsystem ROM is required. + * If \c true and the user doesn't provide a ROM, + * the frontend should not load the core. + * If \c false and the user doesn't provide a ROM, + * the frontend should pass a zeroed-out \c retro_game_info + * to the corresponding entry in \c retro_load_game_special(). + */ + bool required; + + /** + * Pointer to an array of memory descriptors that this subsystem ROM type uses. + * Useful for secondary cartridges that have their own save data. + * May be \c NULL, in which case this subsystem ROM's memory is not persisted by the frontend + * and \c num_memory should be zero. + */ + const struct retro_subsystem_memory_info *memory; + + /** The number of elements in the array pointed to by \c memory. */ + unsigned num_memory; +}; + +/** + * Information about a secondary platform that a core supports. + * @see RETRO_ENVIRONMENT_SET_SUBSYSTEM_INFO + */ +struct retro_subsystem_info +{ + /** + * A human-readable description of the subsystem type, + * usually the brand name of the original platform + * (e.g. "Super Game Boy"). + */ + const char *desc; + + /** + * A short machine-friendly identifier for the subsystem, + * usually an abbreviation of the platform name. + * For example, a Super Game Boy subsystem for a SNES core + * might use an identifier of "sgb". + * This identifier can be used for command-line interfaces, + * configuration, or other purposes. + * Must use lower-case alphabetical characters only (i.e. from a-z). + */ + const char *ident; + + /** + * The list of ROM types that this subsystem may use. + * + * The first entry is considered to be the "most significant" content, + * for the purposes of the frontend's categorization. + * E.g. with Super GameBoy, the first content should be the GameBoy ROM, + * as it is the most "significant" content to a user. + * + * If a frontend creates new files based on the content used (e.g. for savestates), + * it should derive the filenames from the name of the first ROM in this list. + * + * @note \c roms can have a single element, + * but this is usually a sign that the core should broaden its + * primary system info instead. + * + * @see \c retro_system_info + */ + const struct retro_subsystem_rom_info *roms; + + /** The length of the array given in \c roms. */ + unsigned num_roms; + + /** A unique identifier passed to retro_load_game_special(). */ + unsigned id; +}; + +/** @} */ + +/** @defgroup SET_PROC_ADDRESS_CALLBACK Core Function Pointers + * @{ */ + +/** + * The function pointer type that \c retro_get_proc_address_t returns. + * + * Despite the signature shown here, the original function may include any parameters and return type + * that respects the calling convention and C ABI. + * + * The frontend is expected to cast the function pointer to the correct type. + */ +typedef void (RETRO_CALLCONV *retro_proc_address_t)(void); + +/** + * Get a symbol from a libretro core. + * + * Cores should only return symbols that serve as libretro extensions. + * Frontends should not use this to obtain symbols to standard libretro entry points; + * instead, they should link to the core statically or use \c dlsym (or local equivalent). + * + * The symbol name must be equal to the function name. + * e.g. if void retro_foo(void); exists, the symbol in the compiled library must be called \c retro_foo. + * The returned function pointer must be cast to the corresponding type. + * + * @param \c sym The name of the symbol to look up. + * @return Pointer to the exposed function with the name given in \c sym, + * or \c NULL if one couldn't be found. + * @note The frontend is expected to know the returned pointer's type in advance + * so that it can be cast correctly. + * @note The core doesn't need to expose every possible function through this interface. + * It's enough to only expose the ones that it expects the frontend to use. + * @note The functions exposed through this interface + * don't need to be publicly exposed in the compiled library + * (e.g. via \c __declspec(dllexport)). + * @see RETRO_ENVIRONMENT_SET_PROC_ADDRESS_CALLBACK + */ +typedef retro_proc_address_t (RETRO_CALLCONV *retro_get_proc_address_t)(const char *sym); + +/** + * An interface that the frontend can use to get function pointers from the core. + * + * @note The returned function pointer will be invalidated once the core is unloaded. + * How and when that happens is up to the frontend. + * + * @see retro_get_proc_address_t + * @see RETRO_ENVIRONMENT_SET_PROC_ADDRESS_CALLBACK + */ +struct retro_get_proc_address_interface +{ + /** Set by the core. */ + retro_get_proc_address_t get_proc_address; +}; + +/** @} */ + +/** @defgroup GET_LOG_INTERFACE Logging + * @{ + */ + +/** + * The severity of a given message. + * The frontend may log messages differently depending on the level. + * It may also ignore log messages of a certain level. + * @see retro_log_callback + */ +enum retro_log_level +{ + /** The logged message is most likely not interesting to the user. */ + RETRO_LOG_DEBUG = 0, + + /** Information about the core operating normally. */ + RETRO_LOG_INFO, + + /** Indicates a potential problem, possibly one that the core can recover from. */ + RETRO_LOG_WARN, + + /** Indicates a degraded experience, if not failure. */ + RETRO_LOG_ERROR, + + /** Defined to ensure that sizeof(enum retro_log_level) == sizeof(int). Do not use. */ + RETRO_LOG_DUMMY = INT_MAX +}; + +/** + * Logs a message to the frontend. + * + * @param level The log level of the message. + * @param fmt The format string to log. + * Same format as \c printf. + * Behavior is undefined if this is \c NULL. + * @param ... Zero or more arguments used by the format string. + * Behavior is undefined if these don't match the ones expected by \c fmt. + * @see retro_log_level + * @see retro_log_callback + * @see RETRO_ENVIRONMENT_GET_LOG_INTERFACE + * @see printf + */ +typedef void (RETRO_CALLCONV *retro_log_printf_t)(enum retro_log_level level, + const char *fmt, ...); + +/** + * Details about how to make log messages. + * + * @see retro_log_printf_t + * @see RETRO_ENVIRONMENT_GET_LOG_INTERFACE + */ +struct retro_log_callback +{ + /** + * Called when logging a message. + * + * @note Set by the frontend. + */ + retro_log_printf_t log; +}; + +/** @} */ + +/** @defgroup GET_PERF_INTERFACE Performance Interface + * @{ + */ + +/** @defgroup RETRO_SIMD CPU Features + * @{ + */ + +/** + * Indicates CPU support for the SSE instruction set. + * + * @see https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#ssetechs=SSE + */ +#define RETRO_SIMD_SSE (1 << 0) + +/** + * Indicates CPU support for the SSE2 instruction set. + * + * @see https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#ssetechs=SSE2 + */ +#define RETRO_SIMD_SSE2 (1 << 1) + +/** Indicates CPU support for the AltiVec (aka VMX or Velocity Engine) instruction set. */ +#define RETRO_SIMD_VMX (1 << 2) + +/** Indicates CPU support for the VMX128 instruction set. Xbox 360 only. */ +#define RETRO_SIMD_VMX128 (1 << 3) + +/** + * Indicates CPU support for the AVX instruction set. + * + * @see https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#avxnewtechs=AVX + */ +#define RETRO_SIMD_AVX (1 << 4) + +/** + * Indicates CPU support for the NEON instruction set. + * @see https://developer.arm.com/architectures/instruction-sets/intrinsics/#f:@navigationhierarchiessimdisa=[Neon] + */ +#define RETRO_SIMD_NEON (1 << 5) + +/** + * Indicates CPU support for the SSE3 instruction set. + * + * @see https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#ssetechs=SSE3 + */ +#define RETRO_SIMD_SSE3 (1 << 6) + +/** + * Indicates CPU support for the SSSE3 instruction set. + * + * @see https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#ssetechs=SSSE3 + */ +#define RETRO_SIMD_SSSE3 (1 << 7) + +/** + * Indicates CPU support for the MMX instruction set. + * @see https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#techs=MMX + */ +#define RETRO_SIMD_MMX (1 << 8) + +/** Indicates CPU support for the MMXEXT instruction set. */ +#define RETRO_SIMD_MMXEXT (1 << 9) + +/** + * Indicates CPU support for the SSE4 instruction set. + * + * @see https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#ssetechs=SSE4_1 + */ +#define RETRO_SIMD_SSE4 (1 << 10) + +/** + * Indicates CPU support for the SSE4.2 instruction set. + * + * @see https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#ssetechs=SSE4_2 + */ +#define RETRO_SIMD_SSE42 (1 << 11) + +/** + * Indicates CPU support for the AVX2 instruction set. + * + * @see https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#avxnewtechs=AVX2 + */ +#define RETRO_SIMD_AVX2 (1 << 12) + +/** Indicates CPU support for the VFPU instruction set. PS2 and PSP only. + * + * @see https://pspdev.github.io/vfpu-docs + */ +#define RETRO_SIMD_VFPU (1 << 13) + +/** + * Indicates CPU support for Gekko SIMD extensions. GameCube only. + */ +#define RETRO_SIMD_PS (1 << 14) + +/** + * Indicates CPU support for AES instructions. + * + * @see https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#aestechs=AES&othertechs=AES + */ +#define RETRO_SIMD_AES (1 << 15) + +/** + * Indicates CPU support for the VFPv3 instruction set. + */ +#define RETRO_SIMD_VFPV3 (1 << 16) + +/** + * Indicates CPU support for the VFPv4 instruction set. + */ +#define RETRO_SIMD_VFPV4 (1 << 17) + +/** Indicates CPU support for the POPCNT instruction. */ +#define RETRO_SIMD_POPCNT (1 << 18) + +/** Indicates CPU support for the MOVBE instruction. */ +#define RETRO_SIMD_MOVBE (1 << 19) + +/** Indicates CPU support for the CMOV instruction. */ +#define RETRO_SIMD_CMOV (1 << 20) + +/** Indicates CPU support for the ASIMD instruction set. */ +#define RETRO_SIMD_ASIMD (1 << 21) + +/** Indicates CPU support for the AVX512 instruction set. */ +#define RETRO_SIMD_AVX512 (1 << 22) + +/** @} */ + +/** + * An abstract unit of ticks. + * + * Usually nanoseconds or CPU cycles, + * but it depends on the platform and the frontend. + */ +typedef uint64_t retro_perf_tick_t; + +/** Time in microseconds. */ +typedef int64_t retro_time_t; + +/** + * A performance counter. + * + * Use this to measure the execution time of a region of code. + * @see retro_perf_callback + */ +struct retro_perf_counter +{ + /** + * A human-readable identifier for the counter. + * + * May be displayed by the frontend. + * Behavior is undefined if this is \c NULL. + */ + const char *ident; + + /** + * The time of the most recent call to \c retro_perf_callback::perf_start + * on this performance counter. + * + * @see retro_perf_start_t + */ + retro_perf_tick_t start; + + /** + * The total time spent within this performance counter's measured code, + * i.e. between calls to \c retro_perf_callback::perf_start and \c retro_perf_callback::perf_stop. + * + * Updated after each call to \c retro_perf_callback::perf_stop. + * @see retro_perf_stop_t + */ + retro_perf_tick_t total; + + /** + * The number of times this performance counter has been started. + * + * Updated after each call to \c retro_perf_callback::perf_start. + * @see retro_perf_start_t + */ + retro_perf_tick_t call_cnt; + + /** + * \c true if this performance counter has been registered by the frontend. + * Must be initialized to \c false by the core before registering it. + * @see retro_perf_register_t + */ + bool registered; +}; + +/** + * @returns The current system time in microseconds. + * @note Accuracy may vary by platform. + * The frontend should use the most accurate timer possible. + * @see RETRO_ENVIRONMENT_GET_PERF_INTERFACE + */ +typedef retro_time_t (RETRO_CALLCONV *retro_perf_get_time_usec_t)(void); + +/** + * @returns The number of ticks since some unspecified epoch. + * The exact meaning of a "tick" depends on the platform, + * but it usually refers to nanoseconds or CPU cycles. + * @see RETRO_ENVIRONMENT_GET_PERF_INTERFACE + */ +typedef retro_perf_tick_t (RETRO_CALLCONV *retro_perf_get_counter_t)(void); + +/** + * Returns a bitmask of detected CPU features. + * + * Use this for runtime dispatching of CPU-specific code. + * + * @returns A bitmask of detected CPU features. + * @see RETRO_ENVIRONMENT_GET_PERF_INTERFACE + * @see RETRO_SIMD + */ +typedef uint64_t (RETRO_CALLCONV *retro_get_cpu_features_t)(void); + +/** + * Asks the frontend to log or display the state of performance counters. + * How this is done depends on the frontend. + * Performance counters can be reviewed manually as well. + * + * @see RETRO_ENVIRONMENT_GET_PERF_INTERFACE + * @see retro_perf_counter + */ +typedef void (RETRO_CALLCONV *retro_perf_log_t)(void); + +/** + * Registers a new performance counter. + * + * If \c counter has already been registered beforehand, + * this function does nothing. + * + * @param counter The counter to register. + * \c counter::ident must be set to a unique identifier, + * and all other values in \c counter must be set to zero or \c false. + * Behavior is undefined if \c NULL. + * @post If \c counter is successfully registered, + * then \c counter::registered will be set to \c true. + * Otherwise, it will be set to \c false. + * Registration may fail if the frontend's maximum number of counters (if any) has been reached. + * @note The counter is owned by the core and must not be freed by the frontend. + * The frontend must also clean up any references to a core's performance counters + * before unloading it, otherwise undefined behavior may occur. + * @see retro_perf_start_t + * @see retro_perf_stop_t + */ +typedef void (RETRO_CALLCONV *retro_perf_register_t)(struct retro_perf_counter *counter); + +/** + * Starts a registered performance counter. + * + * Call this just before the code you want to measure. + * + * @param counter The counter to start. + * Behavior is undefined if \c NULL. + * @see retro_perf_stop_t + */ +typedef void (RETRO_CALLCONV *retro_perf_start_t)(struct retro_perf_counter *counter); + +/** + * Stops a registered performance counter. + * + * Call this just after the code you want to measure. + * + * @param counter The counter to stop. + * Behavior is undefined if \c NULL. + * @see retro_perf_start_t + * @see retro_perf_stop_t + */ +typedef void (RETRO_CALLCONV *retro_perf_stop_t)(struct retro_perf_counter *counter); + +/** + * An interface that the core can use to get performance information. + * + * Here's a usage example: + * + * @code{.c} + * #ifdef PROFILING + * // Wrapper macros to simplify using performance counters. + * // Optional; tailor these to your project's needs. + * #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 + * // Exclude the performance counters if profiling is disabled. + * #define RETRO_PERFORMANCE_INIT(perf_cb, name) ((void)0) + * #define RETRO_PERFORMANCE_START(perf_cb, name) ((void)0) + * #define RETRO_PERFORMANCE_STOP(perf_cb, name) ((void)0) + * #endif + * + * // Defined somewhere else in the core. + * extern struct retro_perf_callback perf_cb; + * + * void retro_run(void) + * { + * RETRO_PERFORMANCE_INIT(cb, interesting); + * RETRO_PERFORMANCE_START(cb, interesting); + * interesting_work(); + * RETRO_PERFORMANCE_STOP(cb, interesting); + * + * RETRO_PERFORMANCE_INIT(cb, maybe_slow); + * RETRO_PERFORMANCE_START(cb, maybe_slow); + * more_interesting_work(); + * RETRO_PERFORMANCE_STOP(cb, maybe_slow); + * } + * + * void retro_deinit(void) + * { + * // Asks the frontend to log the results of all performance counters. + * perf_cb.perf_log(); + * } + * @endcode + * + * All functions are set by the frontend. + * + * @see RETRO_ENVIRONMENT_GET_PERF_INTERFACE + */ +struct retro_perf_callback +{ + /** @copydoc retro_perf_get_time_usec_t */ + retro_perf_get_time_usec_t get_time_usec; + + /** @copydoc retro_perf_get_counter_t */ + retro_get_cpu_features_t get_cpu_features; + + /** @copydoc retro_perf_get_counter_t */ + retro_perf_get_counter_t get_perf_counter; + + /** @copydoc retro_perf_register_t */ + retro_perf_register_t perf_register; + + /** @copydoc retro_perf_start_t */ + retro_perf_start_t perf_start; + + /** @copydoc retro_perf_stop_t */ + retro_perf_stop_t perf_stop; + + /** @copydoc retro_perf_log_t */ + retro_perf_log_t perf_log; +}; + +/** @} */ + +/** + * @defgroup RETRO_SENSOR Sensor Interface + * @{ + */ + +/** + * Defines actions that can be performed on sensors. + * @note Cores should only enable sensors while they're actively being used; + * depending on the frontend and platform, + * enabling these sensors may impact battery life. + * + * @see RETRO_ENVIRONMENT_GET_SENSOR_INTERFACE + * @see retro_sensor_interface + * @see retro_set_sensor_state_t + */ +enum retro_sensor_action +{ + /** Enables accelerometer input, if one exists. */ + RETRO_SENSOR_ACCELEROMETER_ENABLE = 0, + + /** Disables accelerometer input, if one exists. */ + RETRO_SENSOR_ACCELEROMETER_DISABLE, + + /** Enables gyroscope input, if one exists. */ + RETRO_SENSOR_GYROSCOPE_ENABLE, + + /** Disables gyroscope input, if one exists. */ + RETRO_SENSOR_GYROSCOPE_DISABLE, + + /** Enables ambient light input, if a luminance sensor exists. */ + RETRO_SENSOR_ILLUMINANCE_ENABLE, + + /** Disables ambient light input, if a luminance sensor exists. */ + RETRO_SENSOR_ILLUMINANCE_DISABLE, + + /** @private Defined to ensure sizeof(enum retro_sensor_action) == sizeof(int). Do not use. */ + RETRO_SENSOR_DUMMY = INT_MAX +}; + +/** @defgroup RETRO_SENSOR_ID Sensor Value IDs + * @{ + */ +/* Id values for SENSOR types. */ + +/** + * Returns the device's acceleration along its local X axis, in g (standard gravity, 9.80665 m/s^2). + * Includes the effect of gravity; + * a device at rest on a table will have values close to 0, 0, 1. + * + * Positive values mean that the device is accelerating to the right, + * assuming the user is looking at it head-on. + */ +#define RETRO_SENSOR_ACCELEROMETER_X 0 + +/** + * Returns the device's acceleration along its local Y axis, in g (standard gravity, 9.80665 m/s^2). + * Includes the effect of gravity. + * + * Positive values mean that the device is accelerating upwards, + * assuming the user is looking at it head-on. + */ +#define RETRO_SENSOR_ACCELEROMETER_Y 1 + +/** + * Returns the device's acceleration along its local Z axis, in g (standard gravity, 9.80665 m/s^2). + * Includes the effect of gravity. + * + * Positive values indicate forward acceleration towards the user, + * assuming the user is looking at the device head-on. + */ +#define RETRO_SENSOR_ACCELEROMETER_Z 2 + +/** + * Returns the angular velocity of the device around its local X axis, in radians per second. + * + * Positive values indicate counter-clockwise rotation. + * + * @note A radian is about 57 degrees, and a full 360-degree rotation is 2*pi radians. + * @see https://developer.android.com/reference/android/hardware/SensorEvent#sensor.type_gyroscope + * for guidance on using this value to derive a device's orientation. + */ +#define RETRO_SENSOR_GYROSCOPE_X 3 + +/** + * Returns the angular velocity of the device around its local Z axis, in radians per second. + * + * Positive values indicate counter-clockwise rotation. + * + * @note A radian is about 57 degrees, and a full 360-degree rotation is 2*pi radians. + * @see https://developer.android.com/reference/android/hardware/SensorEvent#sensor.type_gyroscope + * for guidance on using this value to derive a device's orientation. + */ +#define RETRO_SENSOR_GYROSCOPE_Y 4 + +/** + * Returns the angular velocity of the device around its local Z axis, in radians per second. + * + * Positive values indicate counter-clockwise rotation. + * + * @note A radian is about 57 degrees, and a full 360-degree rotation is 2*pi radians. + * @see https://developer.android.com/reference/android/hardware/SensorEvent#sensor.type_gyroscope + * for guidance on using this value to derive a device's orientation. + */ +#define RETRO_SENSOR_GYROSCOPE_Z 5 + +/** + * Returns the ambient illuminance (light intensity) of the device's environment, in lux. + * + * @see https://en.wikipedia.org/wiki/Lux for a table of common lux values. + */ +#define RETRO_SENSOR_ILLUMINANCE 6 +/** @} */ + +/** + * Adjusts the state of a sensor. + * + * @param port The device port of the controller that owns the sensor given in \c action. + * @param action The action to perform on the sensor. + * Different devices support different sensors. + * @param rate The rate at which the underlying sensor should be updated, in Hz. + * This should be treated as a hint, + * as some device sensors may not support the requested rate + * (if it's configurable at all). + * @returns \c true if the sensor state was successfully adjusted, \c false otherwise. + * @note If one of the \c RETRO_SENSOR_*_ENABLE actions fails, + * this likely means that the given sensor is not available + * on the provided \c port. + * @see retro_sensor_action + */ +typedef bool (RETRO_CALLCONV *retro_set_sensor_state_t)(unsigned port, + enum retro_sensor_action action, unsigned rate); + +/** + * Retrieves the current value reported by sensor. + * @param port The device port of the controller that owns the sensor given in \c id. + * @param id The sensor value to query. + * @returns The current sensor value. + * Exact semantics depend on the value given in \c id, + * but will return 0 for invalid arguments. + * + * @see RETRO_SENSOR_ID + */ +typedef float (RETRO_CALLCONV *retro_sensor_get_input_t)(unsigned port, unsigned id); + +/** + * An interface that cores can use to access device sensors. + * + * All function pointers are set by the frontend. + */ +struct retro_sensor_interface +{ + /** @copydoc retro_set_sensor_state_t */ + retro_set_sensor_state_t set_sensor_state; + + /** @copydoc retro_sensor_get_input_t */ + retro_sensor_get_input_t get_sensor_input; +}; + +/** @} */ + +/** @defgroup GET_CAMERA_INTERFACE Camera Interface + * @{ + */ + +/** + * Denotes the type of buffer in which the camera will store its input. + * + * Different camera drivers may support different buffer types. + * + * @see RETRO_ENVIRONMENT_GET_CAMERA_INTERFACE + * @see retro_camera_callback + */ +enum retro_camera_buffer +{ + /** + * Indicates that camera frames should be delivered to the core as an OpenGL texture. + * + * Requires that the core is using an OpenGL context via \c RETRO_ENVIRONMENT_SET_HW_RENDER. + * + * @see retro_camera_frame_opengl_texture_t + */ + RETRO_CAMERA_BUFFER_OPENGL_TEXTURE = 0, + + /** + * Indicates that camera frames should be delivered to the core as a raw buffer in memory. + * + * @see retro_camera_frame_raw_framebuffer_t + */ + RETRO_CAMERA_BUFFER_RAW_FRAMEBUFFER, + + /** + * @private Defined to ensure sizeof(enum retro_camera_buffer) == sizeof(int). + * Do not use. + */ + RETRO_CAMERA_BUFFER_DUMMY = INT_MAX +}; + +/** + * Starts an initialized camera. + * The camera is disabled by default, + * and must be enabled with this function before being used. + * + * Set by the frontend. + * + * @returns \c true if the camera was successfully started, \c false otherwise. + * Failure may occur if no actual camera is available, + * or if the frontend doesn't have permission to access it. + * @note Must be called in \c retro_run(). + * @see retro_camera_callback + */ +typedef bool (RETRO_CALLCONV *retro_camera_start_t)(void); + +/** + * Stops the running camera. + * + * Set by the frontend. + * + * @note Must be called in \c retro_run(). + * @warning The frontend may close the camera on its own when unloading the core, + * but this behavior is not guaranteed. + * Cores should clean up the camera before exiting. + * @see retro_camera_callback + */ +typedef void (RETRO_CALLCONV *retro_camera_stop_t)(void); + +/** + * Called by the frontend to report the state of the camera driver. + * + * @see retro_camera_callback + */ +typedef void (RETRO_CALLCONV *retro_camera_lifetime_status_t)(void); + +/** + * Called by the frontend to report a new camera frame, + * delivered as a raw buffer in memory. + * + * Set by the core. + * + * @param buffer Pointer to the camera's most recent video frame. + * Each pixel is in XRGB8888 format. + * The first pixel represents the top-left corner of the image + * (i.e. the Y axis goes downward). + * @param width The width of the frame given in \c buffer, in pixels. + * @param height The height of the frame given in \c buffer, in pixels. + * @param pitch The width of the frame given in \c buffer, in bytes. + * @warning \c buffer may be invalidated when this function returns, + * so the core should make its own copy of \c buffer if necessary. + * @see RETRO_CAMERA_BUFFER_RAW_FRAMEBUFFER + */ +typedef void (RETRO_CALLCONV *retro_camera_frame_raw_framebuffer_t)(const uint32_t *buffer, + unsigned width, unsigned height, size_t pitch); + +/** + * Called by the frontend to report a new camera frame, + * delivered as an OpenGL texture. + * + * @param texture_id The ID of the OpenGL texture that represents the camera's most recent frame. + * Owned by the frontend, and must not be modified by the core. + * @param texture_target The type of the texture given in \c texture_id. + * Usually either \c GL_TEXTURE_2D or \c GL_TEXTURE_RECTANGLE, + * but other types are allowed. + * @param affine A pointer to a 3x3 column-major affine matrix + * that can be used to transform pixel coordinates to texture coordinates. + * After transformation, the bottom-left corner should have coordinates of (0, 0) + * and the top-right corner should have coordinates of (1, 1) + * (or (width, height) for \c GL_TEXTURE_RECTANGLE). + * + * @note GL-specific typedefs (e.g. \c GLfloat and \c GLuint) are avoided here + * so that the API doesn't rely on gl.h. + * @warning \c texture_id and \c affine may be invalidated when this function returns, + * so the core should make its own copy of them if necessary. + */ +typedef void (RETRO_CALLCONV *retro_camera_frame_opengl_texture_t)(unsigned texture_id, + unsigned texture_target, const float *affine); + +/** + * An interface that the core can use to access a device's camera. + * + * @see RETRO_ENVIRONMENT_GET_CAMERA_INTERFACE + */ +struct retro_camera_callback +{ + /** + * Requested camera capabilities, + * given as a bitmask of \c retro_camera_buffer values. + * Set by the core. + * + * Here's a usage example: + * @code + * // Requesting support for camera data delivered as both an OpenGL texture and a pixel buffer: + * struct retro_camera_callback callback; + * callback.caps = (1 << RETRO_CAMERA_BUFFER_OPENGL_TEXTURE) | (1 << RETRO_CAMERA_BUFFER_RAW_FRAMEBUFFER); + * @endcode + */ + uint64_t caps; + + /** + * The desired width of the camera frame, in pixels. + * This is only a hint; the frontend may provide a different size. + * Set by the core. + * Use zero to let the frontend decide. + */ + unsigned width; + + /** + * The desired height of the camera frame, in pixels. + * This is only a hint; the frontend may provide a different size. + * Set by the core. + * Use zero to let the frontend decide. + */ + unsigned height; + + /** + * @copydoc retro_camera_start_t + * @see retro_camera_callback + */ + retro_camera_start_t start; + + /** + * @copydoc retro_camera_stop_t + * @see retro_camera_callback + */ + retro_camera_stop_t stop; + + /** + * @copydoc retro_camera_frame_raw_framebuffer_t + * @note If \c NULL, this function will not be called. + */ + retro_camera_frame_raw_framebuffer_t frame_raw_framebuffer; + + /** + * @copydoc retro_camera_frame_opengl_texture_t + * @note If \c NULL, this function will not be called. + */ + retro_camera_frame_opengl_texture_t frame_opengl_texture; + + /** + * Core-defined callback invoked by the frontend right after the camera driver is initialized + * (\em not when calling \c start). + * May be \c NULL, in which case this function is skipped. + */ + retro_camera_lifetime_status_t initialized; + + /** + * Core-defined callback invoked by the frontend + * right before the video camera driver is deinitialized + * (\em not when calling \c stop). + * May be \c NULL, in which case this function is skipped. + */ + retro_camera_lifetime_status_t deinitialized; +}; + +/** @} */ + +/** @defgroup GET_LOCATION_INTERFACE Location Interface + * @{ + */ + +/** @copydoc retro_location_callback::set_interval */ +typedef void (RETRO_CALLCONV *retro_location_set_interval_t)(unsigned interval_ms, + unsigned interval_distance); + +/** @copydoc retro_location_callback::start */ +typedef bool (RETRO_CALLCONV *retro_location_start_t)(void); + +/** @copydoc retro_location_callback::stop */ +typedef void (RETRO_CALLCONV *retro_location_stop_t)(void); + +/** @copydoc retro_location_callback::get_position */ +typedef bool (RETRO_CALLCONV *retro_location_get_position_t)(double *lat, double *lon, + double *horiz_accuracy, double *vert_accuracy); + +/** Function type that reports the status of the location service. */ +typedef void (RETRO_CALLCONV *retro_location_lifetime_status_t)(void); + +/** + * An interface that the core can use to access a device's location. + * + * @note It is the frontend's responsibility to request the necessary permissions + * from the operating system. + * @see RETRO_ENVIRONMENT_GET_LOCATION_INTERFACE + */ +struct retro_location_callback +{ + /** + * Starts listening the device's location service. + * + * The frontend will report changes to the device's location + * at the interval defined by \c set_interval. + * Set by the frontend. + * + * @return true if location services were successfully started, false otherwise. + * Note that this will return \c false if location services are disabled + * or the frontend doesn't have permission to use them. + * @note The device's location service may or may not have been enabled + * before the core calls this function. + */ + retro_location_start_t start; + + /** + * Stop listening to the device's location service. + * + * Set by the frontend. + * + * @note The location service itself may or may not + * be turned off by this function, + * depending on the platform and the frontend. + * @post The core will stop receiving location service updates. + */ + retro_location_stop_t stop; + + /** + * Returns the device's current coordinates. + * + * Set by the frontend. + * + * @param[out] lat Pointer to latitude, in degrees. + * Will be set to 0 if no change has occurred since the last call. + * Behavior is undefined if \c NULL. + * @param[out] lon Pointer to longitude, in degrees. + * Will be set to 0 if no change has occurred since the last call. + * Behavior is undefined if \c NULL. + * @param[out] horiz_accuracy Pointer to horizontal accuracy. + * Will be set to 0 if no change has occurred since the last call. + * Behavior is undefined if \c NULL. + * @param[out] vert_accuracy Pointer to vertical accuracy. + * Will be set to 0 if no change has occurred since the last call. + * Behavior is undefined if \c NULL. + */ + retro_location_get_position_t get_position; + + /** + * Sets the rate at which the location service should report updates. + * + * This is only a hint; the actual rate may differ. + * Sets the interval of time and/or distance at which to update/poll + * location-based data. + * + * Some platforms may only support one of the two parameters; + * cores should provide both to ensure compatibility. + * + * Set by the frontend. + * + * @param interval_ms The desired period of time between location updates, in milliseconds. + * @param interval_distance The desired distance between location updates, in meters. + */ + retro_location_set_interval_t set_interval; + + /** Called when the location service is initialized. Set by the core. Optional. */ + retro_location_lifetime_status_t initialized; + + /** Called when the location service is deinitialized. Set by the core. Optional. */ + retro_location_lifetime_status_t deinitialized; +}; + +/** @} */ + +/** @addtogroup GET_RUMBLE_INTERFACE + * @{ */ + +/** + * The type of rumble motor in a controller. + * + * Both motors can be controlled independently, + * and the strong motor does not override the weak motor. + * @see RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE + */ +enum retro_rumble_effect +{ + RETRO_RUMBLE_STRONG = 0, + RETRO_RUMBLE_WEAK = 1, + + /** @private Defined to ensure sizeof(enum retro_rumble_effect) == sizeof(int). Do not use. */ + RETRO_RUMBLE_DUMMY = INT_MAX +}; + +/** + * Requests a rumble state change for a controller. + * Set by the frontend. + * + * @param port The controller port to set the rumble state for. + * @param effect The rumble motor to set the strength of. + * @param strength The desired intensity of the rumble motor, ranging from \c 0 to \c 0xffff (inclusive). + * @return \c true if the requested rumble state was honored. + * If the controller doesn't support rumble, will return \c false. + * @note Calling this before the first \c retro_run() may return \c false. + * @see RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE + */ +typedef bool (RETRO_CALLCONV *retro_set_rumble_state_t)(unsigned port, + enum retro_rumble_effect effect, uint16_t strength); + +/** + * An interface that the core can use to set the rumble state of a controller. + * @see RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE + */ +struct retro_rumble_interface +{ + /** @copydoc retro_set_rumble_state_t */ + retro_set_rumble_state_t set_rumble_state; +}; + +/** @} */ + +/** + * Called by the frontend to request audio samples. + * The core should render audio within this function + * using the callback provided by \c retro_set_audio_sample or \c retro_set_audio_sample_batch. + * + * @warning This function may be called by any thread, + * therefore it must be thread-safe. + * @see RETRO_ENVIRONMENT_SET_AUDIO_CALLBACK + * @see retro_audio_callback + * @see retro_audio_sample_batch_t + * @see retro_audio_sample_t + */ +typedef void (RETRO_CALLCONV *retro_audio_callback_t)(void); + +/** + * Called by the frontend to notify the core that it should pause or resume audio rendering. + * The initial state of the audio driver after registering this callback is \c false (inactive). + * + * @param enabled \c true if the frontend's audio driver is active. + * If so, the registered audio callback will be called regularly. + * If not, the audio callback will not be invoked until the next time + * the frontend calls this function with \c true. + * @warning This function may be called by any thread, + * therefore it must be thread-safe. + * @note Even if no audio samples are rendered, + * the core should continue to update its emulated platform's audio engine if necessary. + * @see RETRO_ENVIRONMENT_SET_AUDIO_CALLBACK + * @see retro_audio_callback + * @see retro_audio_callback_t + */ +typedef void (RETRO_CALLCONV *retro_audio_set_state_callback_t)(bool enabled); + +/** + * An interface that the frontend uses to request audio samples from the core. + * @note To unregister a callback, pass a \c retro_audio_callback_t + * with both fields set to NULL. + * @see RETRO_ENVIRONMENT_SET_AUDIO_CALLBACK + */ +struct retro_audio_callback +{ + /** @see retro_audio_callback_t */ + retro_audio_callback_t callback; + + /** @see retro_audio_set_state_callback_t */ + retro_audio_set_state_callback_t set_state; +}; + +typedef int64_t retro_usec_t; + +/** + * Called right before each iteration of \c retro_run + * if registered via RETRO_ENVIRONMENT_SET_FRAME_TIME_CALLBACK. + * + * @param usec Time since the last call to retro_run, in microseconds. + * If the frontend is manipulating the frame time + * (e.g. via fast-forward or slow motion), + * this value will be the reference value initially provided to the environment call. + * @see RETRO_ENVIRONMENT_SET_FRAME_TIME_CALLBACK + * @see retro_frame_time_callback + */ +typedef void (RETRO_CALLCONV *retro_frame_time_callback_t)(retro_usec_t usec); + +/** + * @see RETRO_ENVIRONMENT_SET_FRAME_TIME_CALLBACK + */ +struct retro_frame_time_callback +{ + /** + * Called to notify the core of the current frame time. + * If NULL, the frontend will clear its registered callback. + */ + retro_frame_time_callback_t callback; + + /** + * The ideal duration of one frame, in microseconds. + * Compute it as 1000000 / fps. + * The frontend will resolve rounding to ensure that framestepping, etc is exact. + */ + retro_usec_t reference; +}; + +/** @defgroup SET_AUDIO_BUFFER_STATUS_CALLBACK Audio Buffer Occupancy + * @{ + */ + +/** + * Notifies a libretro core of how full the frontend's audio buffer is. + * Set by the core, called by the frontend. + * It will be called right before \c retro_run() every frame. + * + * @param active \c true if the frontend's audio buffer is currently in use, + * \c false if audio is disabled in the frontend. + * @param occupancy A value between 0 and 100 (inclusive), + * corresponding to the frontend's audio buffer occupancy percentage. + * @param underrun_likely \c true if the frontend expects an audio buffer underrun + * during the next frame, which indicates that a core should attempt frame-skipping. + */ +typedef void (RETRO_CALLCONV *retro_audio_buffer_status_callback_t)( + bool active, unsigned occupancy, bool underrun_likely); + +/** + * A callback to register with the frontend to receive audio buffer occupancy information. + */ +struct retro_audio_buffer_status_callback +{ + /** @copydoc retro_audio_buffer_status_callback_t */ + retro_audio_buffer_status_callback_t callback; +}; + +/** @} */ + +/* 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. + * */ +#define RETRO_HW_FRAME_BUFFER_VALID ((void*)-1) + +/* Invalidates the current HW context. + * Any GL state is lost, and must not be deinitialized explicitly. + * If explicit deinitialization is desired by the libretro core, + * it should implement context_destroy callback. + * If called, all GPU resources must be reinitialized. + * Usually called when frontend reinits video driver. + * Also called first time video driver is initialized, + * allowing libretro core to initialize resources. + */ +typedef void (RETRO_CALLCONV *retro_hw_context_reset_t)(void); + +/* Gets current framebuffer which is to be rendered to. + * Could change every frame potentially. + */ +typedef uintptr_t (RETRO_CALLCONV *retro_hw_get_current_framebuffer_t)(void); + +/* Get a symbol from HW context. */ +typedef retro_proc_address_t (RETRO_CALLCONV *retro_hw_get_proc_address_t)(const char *sym); + +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, + /* OpenGL ES 2.0. */ + RETRO_HW_CONTEXT_OPENGLES2 = 2, + /* Modern desktop core GL context. Use version_major/ + * version_minor fields to set GL version. */ + RETRO_HW_CONTEXT_OPENGL_CORE = 3, + /* OpenGL ES 3.0 */ + RETRO_HW_CONTEXT_OPENGLES3 = 4, + /* OpenGL ES 3.1+. Set version_major/version_minor. For GLES2 and GLES3, + * use the corresponding enums directly. */ + RETRO_HW_CONTEXT_OPENGLES_VERSION = 5, + + /* Vulkan, see RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE. */ + RETRO_HW_CONTEXT_VULKAN = 6, + + /* Direct3D11, see RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE */ + RETRO_HW_CONTEXT_D3D11 = 7, + + /* Direct3D10, see RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE */ + RETRO_HW_CONTEXT_D3D10 = 8, + + /* Direct3D12, see RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE */ + RETRO_HW_CONTEXT_D3D12 = 9, + + /* Direct3D9, see RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE */ + RETRO_HW_CONTEXT_D3D9 = 10, + + /** Dummy value to ensure sizeof(enum retro_hw_context_type) == sizeof(int). Do not use. */ + RETRO_HW_CONTEXT_DUMMY = INT_MAX +}; + +struct retro_hw_render_callback +{ + /* Which API to use. Set by libretro core. */ + enum retro_hw_context_type context_type; + + /* Called when a context has been created or when it has been reset. + * An OpenGL context is only valid after context_reset() has been called. + * + * When context_reset is called, OpenGL resources in the libretro + * implementation are guaranteed to be invalid. + * + * It is possible that context_reset is called multiple times during an + * application lifecycle. + * If context_reset is called without any notification (context_destroy), + * the OpenGL context was lost and resources should just be recreated + * without any attempt to "free" old resources. + */ + retro_hw_context_reset_t context_reset; + + /* 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. + * Can return all relevant functions, including glClear on Windows. */ + retro_hw_get_proc_address_t get_proc_address; + + /* Set if render buffers should have depth component attached. + * TODO: Obsolete. */ + bool depth; + + /* 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. + * TODO: Move to GL specific interface. */ + bool bottom_left_origin; + + /* Major version number for core GL context or GLES 3.1+. */ + unsigned version_major; + + /* Minor version number for core GL context or GLES 3.1+. */ + unsigned version_minor; + + /* 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; + + /* The reset callback might still be called in extreme situations + * such as if the context is lost beyond recovery. + * + * For optimal stability, set this to false, and allow context to be + * reset at any time. + */ + + /* A callback to be called before the context is destroyed in a + * controlled way by the frontend. */ + retro_hw_context_reset_t context_destroy; + + /* OpenGL resources can be deinitialized cleanly at this step. + * context_destroy can be set to NULL, in which resources will + * just be destroyed without any notification. + * + * Even when context_destroy is non-NULL, it is possible that + * context_reset is called without any destroy notification. + * This happens if context is lost by external factors (such as + * notified by GL_ARB_robustness). + * + * In this case, the context is assumed to be already dead, + * and the libretro implementation must not try to free any OpenGL + * resources in the subsequent context_reset. + */ + + /* Creates a debug context. */ + bool debug_context; +}; + +/* Callback type passed in RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK. + * Called by the frontend in response to keyboard events. + * down is set if the key is being pressed, or false if it is being released. + * keycode is the RETROK value of the char. + * character is the text character of the pressed key. (UTF-32). + * key_modifiers is a set of RETROKMOD values or'ed together. + * + * The pressed/keycode state can be independent of the character. + * It is also possible that multiple characters are generated from a + * single keypress. + * Keycode events should be treated separately from character events. + * However, when possible, the frontend should try to synchronize these. + * If only a character is posted, keycode should be RETROK_UNKNOWN. + * + * Similarly if only a keycode event is generated with no corresponding + * character, character should be 0. + */ +typedef void (RETRO_CALLCONV *retro_keyboard_event_t)(bool down, unsigned keycode, + uint32_t character, uint16_t key_modifiers); + +struct retro_keyboard_callback +{ + retro_keyboard_event_t callback; +}; + +/** @defgroup SET_DISK_CONTROL_INTERFACE Disk Control + * + * Callbacks for inserting and removing disks from the emulated console at runtime. + * Should be provided by cores that support doing so. + * Cores should automate this process if possible, + * but some cases require the player's manual input. + * + * The steps for swapping disk images are generally as follows: + * + * \li Eject the emulated console's disk drive with \c set_eject_state(true). + * \li Insert the new disk image with \c set_image_index(index). + * \li Close the virtual disk tray with \c set_eject_state(false). + * + * @{ + */ + +/** + * Called by the frontend to open or close the emulated console's virtual disk tray. + * + * The frontend may only set the disk image index + * while the emulated tray is opened. + * + * If the emulated console's disk tray is already in the state given by \c ejected, + * then this function should return \c true without doing anything. + * The core should return \c false if it couldn't change the disk tray's state; + * this may happen if the console itself limits when the disk tray can be open or closed + * (e.g. to wait for the disc to stop spinning). + * + * @param ejected \c true if the virtual disk tray should be "ejected", + * \c false if it should be "closed". + * @return \c true if the virtual disk tray's state has been set to the given state, + * false if there was an error. + * @see retro_get_eject_state_t + */ +typedef bool (RETRO_CALLCONV *retro_set_eject_state_t)(bool ejected); + +/** + * Gets the current ejected state of the disk drive. + * The initial state is closed, i.e. \c false. + * + * @return \c true if the virtual disk tray is "ejected", + * i.e. it's open and a disk can be inserted. + * @see retro_set_eject_state_t + */ +typedef bool (RETRO_CALLCONV *retro_get_eject_state_t)(void); + +/** + * Gets the index of the current disk image, + * as determined by however the frontend orders disk images + * (such as m3u-formatted playlists or special directories). + * + * @return The index of the current disk image + * (starting with 0 for the first disk), + * or a value greater than or equal to \c get_num_images() if no disk is inserted. + * @see retro_get_num_images_t + */ +typedef unsigned (RETRO_CALLCONV *retro_get_image_index_t)(void); + +/** + * Inserts the disk image at the given index into the emulated console's drive. + * Can only be called while the disk tray is ejected + * (i.e. \c retro_get_eject_state_t returns \c true). + * + * If the emulated disk tray is ejected + * and already contains the disk image named by \c index, + * then this function should do nothing and return \c true. + * + * @param index The index of the disk image to insert, + * starting from 0 for the first disk. + * A value greater than or equal to \c get_num_images() + * represents the frontend removing the disk without inserting a new one. + * @return \c true if the disk image was successfully set. + * \c false if the disk tray isn't ejected or there was another error + * inserting a new disk image. + */ +typedef bool (RETRO_CALLCONV *retro_set_image_index_t)(unsigned index); + +/** + * @return The number of disk images which are available to use. + * These are most likely defined in a playlist file. + */ +typedef unsigned (RETRO_CALLCONV *retro_get_num_images_t)(void); + +struct retro_game_info; + +/** + * Replaces the disk image at the given index with a new disk. + * + * Replaces the disk image associated with index. + * Arguments to pass in info have same requirements as retro_load_game(). + * Virtual disk tray must be ejected when calling this. + * + * Passing \c NULL to this function indicates + * that the frontend has removed this disk image from its internal list. + * As a result, calls to this function can change the number of available disk indexes. + * + * For example, calling replace_image_index(1, NULL) + * will remove the disk image at index 1, + * and the disk image at index 2 (if any) + * will be moved to the newly-available index 1. + * + * @param index The index of the disk image to replace. + * @param info Details about the new disk image, + * or \c NULL if the disk image at the given index should be discarded. + * The semantics of each field are the same as in \c retro_load_game. + * @return \c true if the disk image was successfully replaced + * or removed from the playlist, + * \c false if the tray is not ejected + * or if there was an error. + */ +typedef bool (RETRO_CALLCONV *retro_replace_image_index_t)(unsigned index, + const struct retro_game_info *info); + +/** + * Adds a new index to the core's internal disk list. + * This will increment the return value from \c get_num_images() by 1. + * This image index cannot be used until a disk image has been set + * with \c replace_image_index. + * + * @return \c true if the core has added space for a new disk image + * and is ready to receive one. + */ +typedef bool (RETRO_CALLCONV *retro_add_image_index_t)(void); + +/** + * Sets the disk image that will be inserted into the emulated disk drive + * before \c retro_load_game is called. + * + * \c retro_load_game does not provide a way to ensure + * that a particular disk image in a playlist is inserted into the console; + * this function makes up for that. + * Frontends should call it immediately before \c retro_load_game, + * and the core should use the arguments + * to validate the disk image in \c retro_load_game. + * + * When content is loaded, the core should verify that the + * disk specified by \c index can be found at \c 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 + * \c 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 \c index is invalid (i.e. index >= get_num_images()) + * or the disk image doesn't match the value given in \c path, + * the core should ignore the arguments + * and insert the disk at index 0 into the virtual disk tray. + * + * @warning If \c RETRO_ENVIRONMENT_SET_DISK_CONTROL_EXT_INTERFACE is called within \c retro_load_game, + * then this function may not be executed. + * Set the disk control interface in \c retro_init if possible. + * + * @param index The index of the disk image within the playlist to set. + * @param path The path of the disk image to set as the first. + * The core should not load this path immediately; + * instead, it should use it within \c retro_load_game + * to verify that the correct disk image was loaded. + * @return \c true if the initial disk index was set, + * \c false if the arguments are invalid + * or the core doesn't support this function. + */ +typedef bool (RETRO_CALLCONV *retro_set_initial_image_t)(unsigned index, const char *path); + +/** + * Returns the path of the disk image at the given index + * on the host's file system. + * + * @param index The index of the disk image to get the path of. + * @param s A buffer to store the path in. + * @param len The size of \c s, in bytes. + * @return \c true if the disk image's location was successfully + * queried and copied into \c s, + * \c false if the index is invalid + * or the core couldn't locate the disk image. + */ +typedef bool (RETRO_CALLCONV *retro_get_image_path_t)(unsigned index, char *s, size_t len); + +/** + * Returns a friendly label for the given disk image. + * + * In the simplest case, this may be the disk image's file name + * with the extension omitted. + * For cores or games with more complex content requirements, + * the label can be used to provide information to help the player + * select a disk image to insert; + * for example, a core may label different kinds of disks + * (save data, level disk, installation disk, bonus content, etc.). + * with names that correspond to in-game prompts, + * so that the frontend can provide better guidance to the player. + * + * @param index The index of the disk image to return a label for. + * @param s A buffer to store the resulting label in. + * @param len The length of \c s, in bytes. + * @return \c true if the disk image at \c index is valid + * and a label was copied into \c s. + */ +typedef bool (RETRO_CALLCONV *retro_get_image_label_t)(unsigned index, char *s, size_t len); + +/** + * An interface that the frontend can use to exchange disks + * within the emulated console's disk drive. + * + * All function pointers are required. + * + * @deprecated This struct is superseded by \ref retro_disk_control_ext_callback. + * Only use this one to maintain compatibility + * with older cores and frontends. + * + * @see RETRO_ENVIRONMENT_SET_DISK_CONTROL_EXT_INTERFACE + * @see retro_disk_control_ext_callback + */ +struct retro_disk_control_callback +{ + /** @copydoc retro_set_eject_state_t */ + retro_set_eject_state_t set_eject_state; + + /** @copydoc retro_get_eject_state_t */ + retro_get_eject_state_t get_eject_state; + + /** @copydoc retro_get_image_index_t */ + retro_get_image_index_t get_image_index; + + /** @copydoc retro_set_image_index_t */ + retro_set_image_index_t set_image_index; + + /** @copydoc retro_get_num_images_t */ + retro_get_num_images_t get_num_images; + + /** @copydoc retro_replace_image_index_t */ + retro_replace_image_index_t replace_image_index; + + /** @copydoc retro_add_image_index_t */ + retro_add_image_index_t add_image_index; +}; + +/** + * @copybrief retro_disk_control_callback + * + * All function pointers are required unless otherwise noted. + * + * @see RETRO_ENVIRONMENT_SET_DISK_CONTROL_EXT_INTERFACE + */ +struct retro_disk_control_ext_callback +{ + /** @copydoc retro_set_eject_state_t */ + retro_set_eject_state_t set_eject_state; + + /** @copydoc retro_get_eject_state_t */ + retro_get_eject_state_t get_eject_state; + + /** @copydoc retro_get_image_index_t */ + retro_get_image_index_t get_image_index; + + /** @copydoc retro_set_image_index_t */ + retro_set_image_index_t set_image_index; + + /** @copydoc retro_get_num_images_t */ + retro_get_num_images_t get_num_images; + + /** @copydoc retro_replace_image_index_t */ + retro_replace_image_index_t replace_image_index; + + /** @copydoc retro_add_image_index_t */ + retro_add_image_index_t add_image_index; + + /** @copydoc retro_set_initial_image_t + * + * Optional; not called if \c NULL. + * + * @note The frontend will only try to record/restore the last-used disk index + * if both \c set_initial_image and \c get_image_path are implemented. + */ + retro_set_initial_image_t set_initial_image; + + /** + * @copydoc retro_get_image_path_t + * + * Optional; not called if \c NULL. + */ + retro_get_image_path_t get_image_path; + + /** + * @copydoc retro_get_image_label_t + * + * Optional; not called if \c NULL. + */ + retro_get_image_label_t get_image_label; +}; + +/** @} */ + +/* Definitions for RETRO_ENVIRONMENT_SET_NETPACKET_INTERFACE. + * A core can set it if sending and receiving custom network packets + * during a multiplayer session is desired. + */ + +/* Netpacket flags for retro_netpacket_send_t */ +#define RETRO_NETPACKET_UNRELIABLE 0 /* Packet to be sent unreliable, depending on network quality it might not arrive. */ +#define RETRO_NETPACKET_RELIABLE (1 << 0) /* Reliable packets are guaranteed to arrive at the target in the order they were sent. */ +#define RETRO_NETPACKET_UNSEQUENCED (1 << 1) /* Packet will not be sequenced with other packets and may arrive out of order. Cannot be set on reliable packets. */ +#define RETRO_NETPACKET_FLUSH_HINT (1 << 2) /* Request the packet and any previously buffered ones to be sent immediately */ + +/* Broadcast client_id for retro_netpacket_send_t */ +#define RETRO_NETPACKET_BROADCAST 0xFFFF + +/* Used by the core to send a packet to one or all connected players. + * A single packet sent via this interface can contain up to 64 KB of data. + * + * The client_id RETRO_NETPACKET_BROADCAST sends the packet as a broadcast to + * all connected players. This is supported from the host as well as clients. +* Otherwise, the argument indicates the player to send the packet to. + * + * A frontend must support sending reliable packets (RETRO_NETPACKET_RELIABLE). + * Unreliable packets might not be supported by the frontend, but the flags can + * still be specified. Reliable transmission will be used instead. + * + * Calling this with the flag RETRO_NETPACKET_FLUSH_HINT will send off the + * packet and any previously buffered ones immediately and without blocking. + * To only flush previously queued packets, buf or len can be passed as NULL/0. + * + * This function is not guaranteed to be thread-safe and must be called during + * retro_run or any of the netpacket callbacks passed with this interface. + */ +typedef void (RETRO_CALLCONV *retro_netpacket_send_t)(int flags, const void* buf, size_t len, uint16_t client_id); + +/* Optionally read any incoming packets without waiting for the end of the + * frame. While polling, retro_netpacket_receive_t and retro_netpacket_stop_t + * can be called. The core can perform this in a loop to do a blocking read, + * i.e., wait for incoming data, but needs to handle stop getting called and + * also give up after a short while to avoid freezing on a connection problem. + * It is a good idea to manually flush outgoing packets before calling this. + * + * This function is not guaranteed to be thread-safe and must be called during + * retro_run or any of the netpacket callbacks passed with this interface. + */ +typedef void (RETRO_CALLCONV *retro_netpacket_poll_receive_t)(void); + +/* Called by the frontend to signify that a multiplayer session has started. + * If client_id is 0 the local player is the host of the session and at this + * point no other player has connected yet. + * + * If client_id is > 0 the local player is a client connected to a host and + * at this point is already fully connected to the host. + * + * The core must store the function pointer send_fn and use it whenever it + * wants to send a packet. Optionally poll_receive_fn can be stored and used + * when regular receiving between frames is not enough. These function pointers + * remain valid until the frontend calls retro_netpacket_stop_t. + */ +typedef void (RETRO_CALLCONV *retro_netpacket_start_t)(uint16_t client_id, retro_netpacket_send_t send_fn, retro_netpacket_poll_receive_t poll_receive_fn); + +/* Called by the frontend when a new packet arrives which has been sent from + * another player with retro_netpacket_send_t. The client_id argument indicates + * who has sent the packet. + */ +typedef void (RETRO_CALLCONV *retro_netpacket_receive_t)(const void* buf, size_t len, uint16_t client_id); + +/* Called by the frontend when the multiplayer session has ended. + * Once this gets called the function pointers passed to + * retro_netpacket_start_t will not be valid anymore. + */ +typedef void (RETRO_CALLCONV *retro_netpacket_stop_t)(void); + +/* Called by the frontend every frame (between calls to retro_run while + * updating the state of the multiplayer session. + * This is a good place for the core to call retro_netpacket_send_t from. + */ +typedef void (RETRO_CALLCONV *retro_netpacket_poll_t)(void); + +/* Called by the frontend when a new player connects to the hosted session. + * This is only called on the host side, not for clients connected to the host. + * If this function returns false, the newly connected player gets dropped. + * This can be used for example to limit the number of players. + */ +typedef bool (RETRO_CALLCONV *retro_netpacket_connected_t)(uint16_t client_id); + +/* Called by the frontend when a player leaves or disconnects from the hosted session. + * This is only called on the host side, not for clients connected to the host. + */ +typedef void (RETRO_CALLCONV *retro_netpacket_disconnected_t)(uint16_t client_id); + +/** + * A callback interface for giving a core the ability to send and receive custom + * network packets during a multiplayer session between two or more instances + * of a libretro frontend. + * + * Normally during connection handshake the frontend will compare library_version + * used by both parties and show a warning if there is a difference. When the core + * supplies protocol_version, the frontend will check against this instead. + * + * @see RETRO_ENVIRONMENT_SET_NETPACKET_INTERFACE + */ +struct retro_netpacket_callback +{ + retro_netpacket_start_t start; + retro_netpacket_receive_t receive; + retro_netpacket_stop_t stop; /* Optional - may be NULL */ + retro_netpacket_poll_t poll; /* Optional - may be NULL */ + retro_netpacket_connected_t connected; /* Optional - may be NULL */ + retro_netpacket_disconnected_t disconnected; /* Optional - may be NULL */ + const char* protocol_version; /* Optional - if not NULL will be used instead of core version to decide if communication is compatible */ +}; + +/** + * The pixel format used for rendering. + * @see RETRO_ENVIRONMENT_SET_PIXEL_FORMAT + */ +enum retro_pixel_format +{ + /** + * 0RGB1555, native endian. + * Used as the default if \c RETRO_ENVIRONMENT_SET_PIXEL_FORMAT is not called. + * The most significant bit must be set to 0. + * @deprecated This format remains supported to maintain compatibility. + * New code should use RETRO_PIXEL_FORMAT_RGB565 instead. + * @see RETRO_PIXEL_FORMAT_RGB565 + */ + RETRO_PIXEL_FORMAT_0RGB1555 = 0, + + /** + * XRGB8888, native endian. + * The most significant byte (the X) is ignored. + */ + RETRO_PIXEL_FORMAT_XRGB8888 = 1, + + /** + * RGB565, native endian. + * This format is recommended if 16-bit pixels are desired, + * as it is available on a variety of devices and APIs. + */ + RETRO_PIXEL_FORMAT_RGB565 = 2, + + /** Defined to ensure that sizeof(retro_pixel_format) == sizeof(int). Do not use. */ + RETRO_PIXEL_FORMAT_UNKNOWN = INT_MAX +}; + +/** @defgroup GET_SAVESTATE_CONTEXT Savestate Context + * @{ + */ + +/** + * Details about how the frontend will use savestates. + * + * @see RETRO_ENVIRONMENT_GET_SAVESTATE_CONTEXT + * @see retro_serialize + */ +enum retro_savestate_context +{ + /** + * Standard savestate written to disk. + * May be loaded at any time, + * even in a separate session or on another device. + * + * Should not contain any pointers to code or data. + */ + RETRO_SAVESTATE_CONTEXT_NORMAL = 0, + + /** + * The savestate is guaranteed to be loaded + * within the same session, address space, and binary. + * Will not be written to disk or sent over the network; + * therefore, internal pointers to code or data are acceptable. + * May still be loaded or saved at any time. + * + * @note This context generally implies the use of runahead or rewinding, + * which may work by taking savestates multiple times per second. + * Savestate code that runs in this context should be fast. + */ + RETRO_SAVESTATE_CONTEXT_RUNAHEAD_SAME_INSTANCE = 1, + + /** + * The savestate is guaranteed to be loaded + * in the same session and by the same binary, + * but possibly by a different address space + * (e.g. for "second instance" runahead) + * + * Will not be written to disk or sent over the network, + * but may be loaded in a different address space. + * Therefore, the savestate must not contain pointers. + */ + RETRO_SAVESTATE_CONTEXT_RUNAHEAD_SAME_BINARY = 2, + + /** + * The savestate will not be written to disk, + * but no other guarantees are made. + * The savestate will almost certainly be loaded + * by a separate binary, device, and address space. + * + * This context is intended for use with frontends that support rollback netplay. + * Serialized state should omit any data that would unnecessarily increase bandwidth usage. + * Must not contain pointers, and integers must be saved in big-endian format. + * @see retro_endianness.h + * @see network_stream + */ + RETRO_SAVESTATE_CONTEXT_ROLLBACK_NETPLAY = 3, + + /** + * @private Defined to ensure sizeof(retro_savestate_context) == sizeof(int). + * Do not use. + */ + RETRO_SAVESTATE_CONTEXT_UNKNOWN = INT_MAX +}; + +/** @} */ + +/** @defgroup SET_MESSAGE User-Visible Messages + * + * @{ + */ + +/** + * Defines a message that the frontend will display to the user, + * as determined by RETRO_ENVIRONMENT_SET_MESSAGE. + * + * @deprecated This struct is superseded by \ref retro_message_ext, + * which provides more control over how a message is presented. + * Only use it for compatibility with older cores and frontends. + * + * @see RETRO_ENVIRONMENT_SET_MESSAGE + * @see retro_message_ext + */ +struct retro_message +{ + /** + * Null-terminated message to be displayed. + * If \c NULL or empty, the message will be ignored. + */ + const char *msg; + + /** Duration to display \c msg in frames. */ + unsigned frames; +}; + +/** + * The method that the frontend will use to display a message to the player. + * @see retro_message_ext + */ +enum retro_message_target +{ + /** + * Indicates that the frontend should display the given message + * using all other targets defined by \c retro_message_target at once. + */ + RETRO_MESSAGE_TARGET_ALL = 0, + + /** + * Indicates that the frontend should display the given message + * using the frontend's on-screen display, if available. + * + * @attention If the frontend allows players to customize or disable notifications, + * then they may not see messages sent to this target. + */ + RETRO_MESSAGE_TARGET_OSD, + + /** + * Indicates that the frontend should log the message + * via its usual logging mechanism, if available. + * + * This is not intended to be a substitute for \c RETRO_ENVIRONMENT_SET_LOG_INTERFACE. + * It is intended for the common use case of + * logging a player-facing message. + * + * This target should not be used for messages + * of type \c RETRO_MESSAGE_TYPE_STATUS or \c RETRO_MESSAGE_TYPE_PROGRESS, + * as it may add unnecessary noise to a log file. + * + * @see RETRO_ENVIRONMENT_SET_LOG_INTERFACE + */ + RETRO_MESSAGE_TARGET_LOG +}; + +/** + * A broad category for the type of message that the frontend will display. + * + * Each message type has its own use case, + * therefore the frontend should present each one differently. + * + * @note This is a hint that the frontend may ignore. + * The frontend should fall back to \c RETRO_MESSAGE_TYPE_NOTIFICATION + * for message types that it doesn't support. + */ +enum retro_message_type +{ + /** + * A standard on-screen message. + * + * Suitable for a variety of use cases, + * such as messages about errors + * or other important events. + * + * Frontends that display their own messages + * should display this type of core-generated message the same way. + */ + RETRO_MESSAGE_TYPE_NOTIFICATION = 0, + + /** + * An on-screen message that should be visually distinct + * from \c RETRO_MESSAGE_TYPE_NOTIFICATION messages. + * + * The exact meaning of "visually distinct" is left to the frontend, + * but this usually implies that the frontend shows the message + * in a way that it doesn't typically use for its own notices. + */ + RETRO_MESSAGE_TYPE_NOTIFICATION_ALT, + + /** + * Indicates a frequently-updated status display, + * rather than a standard notification. + * Status messages are intended to be displayed permanently while a core is running + * in a way that doesn't suggest user action is required. + * + * Here are some possible use cases for status messages: + * + * @li An internal framerate counter. + * @li Debugging information. + * Remember to let the player disable it in the core options. + * @li Core-specific state, such as when a microphone is active. + * + * The status message is displayed for the given duration, + * unless another status message of equal or greater priority is shown. + */ + RETRO_MESSAGE_TYPE_STATUS, + + /** + * Denotes a message that reports the progress + * of a long-running asynchronous task, + * such as when a core loads large files from disk or the network. + * + * The frontend should display messages of this type as a progress bar + * (or a progress spinner for indefinite tasks), + * where \c retro_message_ext::msg is the progress bar's title + * and \c retro_message_ext::progress sets the progress bar's length. + * + * This message type shouldn't be used for tasks that are expected to complete quickly. + */ + RETRO_MESSAGE_TYPE_PROGRESS +}; + +/** + * A core-provided message that the frontend will display to the player. + * + * @note The frontend is encouraged store these messages in a queue. + * However, it should not empty the queue of core-submitted messages upon exit; + * if a core exits with an error, it may want to use this API + * to show an error message to the player. + * + * The frontend should maintain its own copy of the submitted message + * and all subobjects, including strings. + * + * @see RETRO_ENVIRONMENT_SET_MESSAGE_EXT + */ +struct retro_message_ext +{ + /** + * The \c NULL-terminated text of a message to show to the player. + * Must not be \c NULL. + * + * @note The frontend must honor newlines in this string + * when rendering text to \c RETRO_MESSAGE_TARGET_OSD. + */ + const char *msg; + + /** + * The duration that \c msg will be displayed on-screen, in milliseconds. + * + * Ignored for \c RETRO_MESSAGE_TARGET_LOG. + */ + unsigned duration; + + /** + * The relative importance of this message + * when targeting \c RETRO_MESSAGE_TARGET_OSD. + * Higher values indicate higher priority. + * + * The frontend should use this to prioritize messages + * when it can't show all active messages at once, + * or to remove messages from its queue if it's full. + * + * The relative display order of messages with the same priority + * is left to the frontend's discretion, + * although we suggest breaking ties + * in favor of the most recently-submitted message. + * + * Frontends may handle deprioritized messages at their discretion; + * such messages may have their \c duration altered, + * be hidden without being delayed, + * or even be discarded entirely. + * + * @note In the reference frontend (RetroArch), + * the same priority values are used for frontend-generated notifications, + * which are typically between 0 and 3 depending upon importance. + * + * Ignored for \c RETRO_MESSAGE_TARGET_LOG. + */ + unsigned priority; + + /** + * The severity level of this message. + * + * The frontend may use this to filter or customize messages + * depending on the player's preferences. + * Here are some ideas: + * + * @li Use this to prioritize errors and warnings + * over higher-ranking info and debug messages. + * @li Render warnings or errors with extra visual feedback, + * e.g. with brighter colors or accompanying sound effects. + * + * @see RETRO_ENVIRONMENT_SET_LOG_INTERFACE + */ + enum retro_log_level level; + + /** + * The intended destination of this message. + * + * @see retro_message_target + */ + enum retro_message_target target; + + /** + * The intended semantics of this message. + * + * Ignored for \c RETRO_MESSAGE_TARGET_LOG. + * + * @see retro_message_type + */ + enum retro_message_type type; + + /** + * The progress of an asynchronous task. + * + * A value between 0 and 100 (inclusive) indicates the task's percentage, + * and a value of -1 indicates a task of unknown completion. + * + * @note Since message type is a hint, a frontend may ignore progress values. + * Where relevant, a core should include progress percentage within the message string, + * such that the message intent remains clear when displayed + * as a standard frontend-generated notification. + * + * Ignored for \c RETRO_MESSAGE_TARGET_LOG and for + * message types other than \c RETRO_MESSAGE_TYPE_PROGRESS. + */ + int8_t progress; +}; + +/** @} */ + +/* 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 +{ + /* Associates given parameters with a description. */ + unsigned port; + unsigned device; + unsigned index; + unsigned id; + + /* Human readable description for parameters. + * The pointer must remain valid until + * retro_unload_game() is called. */ + const char *description; +}; + +/** + * Contains basic information about the core. + * + * @see retro_get_system_info + * @warning All pointers are owned by the core + * and must remain valid throughout its lifetime. + */ +struct retro_system_info +{ + /** + * Descriptive name of the library. + * + * @note Should not contain any version numbers, etc. + */ + const char *library_name; + + /** + * Descriptive version of the core. + */ + const char *library_version; + + /** + * A pipe-delimited string list of file extensions that this core can load, e.g. "bin|rom|iso". + * Typically used by a frontend for filtering or core selection. + */ + const char *valid_extensions; + + /* Libretro cores that need to have direct access to their content + * files, including cores which use the path of the content files to + * determine the paths of other files, should set need_fullpath to true. + * + * Cores should strive for setting need_fullpath to false, + * as it allows the frontend to perform patching, etc. + * + * If need_fullpath is true and retro_load_game() is called: + * - retro_game_info::path is guaranteed to have a valid path + * - retro_game_info::data and retro_game_info::size are invalid + * + * If need_fullpath is false and retro_load_game() is called: + * - retro_game_info::path may be NULL + * - retro_game_info::data and retro_game_info::size are guaranteed + * to be valid + * + * See also: + * - RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY + * - RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY + */ + bool need_fullpath; + + /* If true, the frontend is not allowed to extract any archives before + * loading the real content. + * Necessary for certain libretro implementations that load games + * from zipped archives. */ + bool block_extract; +}; + +/* Defines overrides which modify frontend handling of + * specific content file types. + * An array of retro_system_content_info_override is + * passed to RETRO_ENVIRONMENT_SET_CONTENT_INFO_OVERRIDE + * NOTE: In the following descriptions, references to + * retro_load_game() may be replaced with + * retro_load_game_special() */ +struct retro_system_content_info_override +{ + /* A list of file extensions for which the override + * should apply, delimited by a 'pipe' character + * (e.g. "md|sms|gg") + * Permitted file extensions are limited to those + * included in retro_system_info::valid_extensions + * and/or retro_subsystem_rom_info::valid_extensions */ + const char *extensions; + + /* Overrides the need_fullpath value set in + * retro_system_info and/or retro_subsystem_rom_info. + * To reiterate: + * + * If need_fullpath is true and retro_load_game() is called: + * - retro_game_info::path is guaranteed to contain a valid + * path to an existent file + * - retro_game_info::data and retro_game_info::size are invalid + * + * If need_fullpath is false and retro_load_game() is called: + * - retro_game_info::path may be NULL + * - retro_game_info::data and retro_game_info::size are guaranteed + * to be valid + * + * In addition: + * + * If need_fullpath is true and retro_load_game() is called: + * - retro_game_info_ext::full_path is guaranteed to contain a valid + * path to an existent file + * - retro_game_info_ext::archive_path may be NULL + * - retro_game_info_ext::archive_file may be NULL + * - retro_game_info_ext::dir is guaranteed to contain a valid path + * to the directory in which the content file exists + * - retro_game_info_ext::name is guaranteed to contain the + * basename of the content file, without extension + * - retro_game_info_ext::ext is guaranteed to contain the + * extension of the content file in lower case format + * - retro_game_info_ext::data and retro_game_info_ext::size + * are invalid + * + * If need_fullpath is false and retro_load_game() is called: + * - If retro_game_info_ext::file_in_archive is false: + * - retro_game_info_ext::full_path is guaranteed to contain + * a valid path to an existent file + * - retro_game_info_ext::archive_path may be NULL + * - retro_game_info_ext::archive_file may be NULL + * - retro_game_info_ext::dir is guaranteed to contain a + * valid path to the directory in which the content file exists + * - retro_game_info_ext::name is guaranteed to contain the + * basename of the content file, without extension + * - retro_game_info_ext::ext is guaranteed to contain the + * extension of the content file in lower case format + * - If retro_game_info_ext::file_in_archive is true: + * - retro_game_info_ext::full_path may be NULL + * - retro_game_info_ext::archive_path is guaranteed to + * contain a valid path to an existent compressed file + * inside which the content file is located + * - retro_game_info_ext::archive_file is guaranteed to + * contain a valid path to an existent content file + * inside the compressed file referred to by + * retro_game_info_ext::archive_path + * e.g. for a compressed file '/path/to/foo.zip' + * containing 'bar.sfc' + * > retro_game_info_ext::archive_path will be '/path/to/foo.zip' + * > retro_game_info_ext::archive_file will be 'bar.sfc' + * - retro_game_info_ext::dir is guaranteed to contain a + * valid path to the directory in which the compressed file + * (containing the content file) exists + * - retro_game_info_ext::name is guaranteed to contain + * EITHER + * 1) the basename of the compressed file (containing + * the content file), without extension + * OR + * 2) the basename of the content file inside the + * compressed file, without extension + * In either case, a core should consider 'name' to + * be the canonical name/ID of the the content file + * - retro_game_info_ext::ext is guaranteed to contain the + * extension of the content file inside the compressed file, + * in lower case format + * - retro_game_info_ext::data and retro_game_info_ext::size are + * guaranteed to be valid */ + bool need_fullpath; + + /* If need_fullpath is false, specifies whether the content + * data buffer available in retro_load_game() is 'persistent' + * + * If persistent_data is false and retro_load_game() is called: + * - retro_game_info::data and retro_game_info::size + * are valid only until retro_load_game() returns + * - retro_game_info_ext::data and retro_game_info_ext::size + * are valid only until retro_load_game() returns + * + * If persistent_data is true and retro_load_game() is called: + * - retro_game_info::data and retro_game_info::size + * are valid until retro_deinit() returns + * - retro_game_info_ext::data and retro_game_info_ext::size + * are valid until retro_deinit() returns */ + bool persistent_data; +}; + +/* Similar to retro_game_info, but provides extended + * information about the source content file and + * game memory buffer status. + * And array of retro_game_info_ext is returned by + * RETRO_ENVIRONMENT_GET_GAME_INFO_EXT + * NOTE: In the following descriptions, references to + * retro_load_game() may be replaced with + * retro_load_game_special() */ +struct retro_game_info_ext +{ + /* - If file_in_archive is false, contains a valid + * path to an existent content file (UTF-8 encoded) + * - If file_in_archive is true, may be NULL */ + const char *full_path; + + /* - If file_in_archive is false, may be NULL + * - If file_in_archive is true, contains a valid path + * to an existent compressed file inside which the + * content file is located (UTF-8 encoded) */ + const char *archive_path; + + /* - If file_in_archive is false, may be NULL + * - If file_in_archive is true, contain a valid path + * to an existent content file inside the compressed + * file referred to by archive_path (UTF-8 encoded) + * e.g. for a compressed file '/path/to/foo.zip' + * containing 'bar.sfc' + * > archive_path will be '/path/to/foo.zip' + * > archive_file will be 'bar.sfc' */ + const char *archive_file; + + /* - If file_in_archive is false, contains a valid path + * to the directory in which the content file exists + * (UTF-8 encoded) + * - If file_in_archive is true, contains a valid path + * to the directory in which the compressed file + * (containing the content file) exists (UTF-8 encoded) */ + const char *dir; + + /* Contains the canonical name/ID of the content file + * (UTF-8 encoded). Intended for use when identifying + * 'complementary' content named after the loaded file - + * i.e. companion data of a different format (a CD image + * required by a ROM), texture packs, internally handled + * save files, etc. + * - If file_in_archive is false, contains the basename + * of the content file, without extension + * - If file_in_archive is true, then string is + * implementation specific. A frontend may choose to + * set a name value of: + * EITHER + * 1) the basename of the compressed file (containing + * the content file), without extension + * OR + * 2) the basename of the content file inside the + * compressed file, without extension + * RetroArch sets the 'name' value according to (1). + * A frontend that supports routine loading of + * content from archives containing multiple unrelated + * content files may set the 'name' value according + * to (2). */ + const char *name; + + /* - If file_in_archive is false, contains the extension + * of the content file in lower case format + * - If file_in_archive is true, contains the extension + * of the content file inside the compressed file, + * in lower case format */ + const char *ext; + + /* String of implementation specific meta-data. */ + const char *meta; + + /* Memory buffer of loaded game content. Will be NULL: + * IF + * - retro_system_info::need_fullpath is true and + * retro_system_content_info_override::need_fullpath + * is unset + * OR + * - retro_system_content_info_override::need_fullpath + * is true */ + const void *data; + + /* Size of game content memory buffer, in bytes */ + size_t size; + + /* True if loaded content file is inside a compressed + * archive */ + bool file_in_archive; + + /* - If data is NULL, value is unset/ignored + * - If data is non-NULL: + * - If persistent_data is false, data and size are + * valid only until retro_load_game() returns + * - If persistent_data is true, data and size are + * are valid until retro_deinit() returns */ + bool persistent_data; +}; + +/** + * Parameters describing the size and shape of the video frame. + * @see retro_system_av_info + * @see RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO + * @see RETRO_ENVIRONMENT_SET_GEOMETRY + * @see retro_get_system_av_info + */ +struct retro_game_geometry +{ + /** + * Nominal video width of game, in pixels. + * This will typically be the emulated platform's native video width + * (or its smallest, if the original hardware supports multiple resolutions). + */ + unsigned base_width; + + /** + * Nominal video height of game, in pixels. + * This will typically be the emulated platform's native video height + * (or its smallest, if the original hardware supports multiple resolutions). + */ + unsigned base_height; + + /** + * Maximum possible width of the game screen, in pixels. + * This will typically be the emulated platform's maximum video width. + * For cores that emulate platforms with multiple screens (such as the Nintendo DS), + * this should assume the core's widest possible screen layout (e.g. side-by-side). + * For cores that support upscaling the resolution, + * this should assume the highest supported scale factor is active. + */ + unsigned max_width; + + /** + * Maximum possible height of the game screen, in pixels. + * This will typically be the emulated platform's maximum video height. + * For cores that emulate platforms with multiple screens (such as the Nintendo DS), + * this should assume the core's tallest possible screen layout (e.g. vertical). + * For cores that support upscaling the resolution, + * this should assume the highest supported scale factor is active. + */ + unsigned max_height; /* Maximum possible height of game. */ + + /** + * Nominal aspect ratio of game. + * If zero or less, + * an aspect ratio of base_width / base_height is assumed. + * + * @note A frontend may ignore this setting. + */ + float aspect_ratio; +}; + +/** + * Parameters describing the timing of the video and audio. + * @see retro_system_av_info + * @see RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO + * @see retro_get_system_av_info + */ +struct retro_system_timing +{ + /** Video output refresh rate, in frames per second. */ + double fps; + + /** The audio output sample rate, in Hz. */ + double sample_rate; +}; + +/** + * Configures how the core's audio and video should be updated. + * @see RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO + * @see retro_get_system_av_info + */ +struct retro_system_av_info +{ + /** Parameters describing the size and shape of the video frame. */ + struct retro_game_geometry geometry; + + /** Parameters describing the timing of the video and audio. */ + struct retro_system_timing timing; +}; + +/** @defgroup SET_CORE_OPTIONS Core Options + * @{ + */ + +/** + * Represents \ref RETRO_ENVIRONMENT_GET_VARIABLE "a core option query". + * + * @note In \ref RETRO_ENVIRONMENT_SET_VARIABLES + * (which is a deprecated API), + * this \c struct serves as an option definition. + * + * @see RETRO_ENVIRONMENT_GET_VARIABLE + */ +struct retro_variable +{ + /** + * A unique key identifying this option. + * + * Should be a key for an option that was previously defined + * with \ref RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2 or similar. + * + * Should be prefixed with the core's name + * to minimize the risk of collisions with another core's options, + * as frontends are not required to use a namespacing scheme for storing options. + * For example, a core named "foo" might define an option named "foo_option". + * + * @note In \ref RETRO_ENVIRONMENT_SET_VARIABLES + * (which is a deprecated API), + * this field is used to define an option + * named by this key. + */ + const char *key; + + /** + * Value to be obtained. + * + * Set by the frontend to \c NULL if + * the option named by \ref key does not exist. + * + * @note In \ref RETRO_ENVIRONMENT_SET_VARIABLES + * (which is a deprecated API), + * this field is set by the core to define the possible values + * for an option named by \ref key. + * When used this way, it must be formatted as follows: + * @li The text before the first ';' is the option's human-readable title. + * @li A single space follows the ';'. + * @li The rest of the string is a '|'-delimited list of possible values, + * with the first one being the default. + */ + const char *value; +}; + +/** + * An argument that's used to show or hide a core option in the frontend. + * + * @see RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY + */ +struct retro_core_option_display +{ + /** + * The key for a core option that was defined with \ref RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2, + * \ref RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2_INTL, + * or their legacy equivalents. + */ + const char *key; + + /** + * Whether the option named by \c key + * should be displayed to the player in the frontend's core options menu. + * + * @note This value is a hint, \em not a requirement; + * the frontend is free to ignore this field. + */ + bool visible; +}; + +/** + * The maximum number of choices that can be defined for a given core option. + * + * This limit was chosen as a compromise between + * a core's flexibility and a streamlined user experience. + * + * @note A guiding principle of libretro's API design is that + * all common interactions (gameplay, menu navigation, etc.) + * should be possible without a keyboard. + * + * If you need more than 128 choices for a core option, + * consider simplifying your option structure. + * Here are some ideas: + * + * \li If a core option represents a numeric value, + * consider reducing the option's granularity + * (e.g. define time limits in increments of 5 seconds instead of 1 second). + * Providing a fixed set of values based on experimentation + * is also a good idea. + * \li If a core option represents a dynamically-built list of files, + * consider leaving out files that won't be useful. + * For example, if a core allows the player to choose a specific BIOS file, + * it can omit files of the wrong length or without a valid header. + * + * @see retro_core_option_definition + * @see retro_core_option_v2_definition + */ +#define RETRO_NUM_CORE_OPTION_VALUES_MAX 128 + +/** + * A descriptor for a particular choice within a core option. + * + * @note All option values are represented as strings. + * If you need to represent any other type, + * parse the string in \ref value. + * + * @see retro_core_option_v2_category + */ +struct retro_core_option_value +{ + /** + * The option value that the frontend will serialize. + * + * Must not be \c NULL or empty. + * No other hard limits are placed on this value's contents, + * but here are some suggestions: + * + * \li If the value represents a number, + * don't include any non-digit characters (units, separators, etc.). + * Instead, include that information in \c label. + * This will simplify parsing. + * \li If the value represents a file path, + * store it as a relative path with respect to one of the common libretro directories + * (e.g. \ref RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY "the system directory" + * or \ref RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY "the save directory"), + * and use forward slashes (\c "/") as directory separators. + * This will simplify cloud storage if supported by the frontend, + * as the same file may be used on multiple devices. + */ + const char *value; + + /** + * Human-readable name for \c value that the frontend should show to players. + * + * May be \c NULL, in which case the frontend + * should display \c value itself. + * + * Here are some guidelines for writing a good label: + * + * \li Make the option labels obvious + * so that they don't need to be explained in the description. + * \li Keep labels short, and don't use unnecessary words. + * For example, "OpenGL" is a better label than "OpenGL Mode". + * \li If the option represents a number, + * consider adding units, separators, or other punctuation + * into the label itself. + * For example, "5 seconds" is a better label than "5". + * \li If the option represents a number, use intuitive units + * that don't take a lot of digits to express. + * For example, prefer "1 minute" over "60 seconds" or "60,000 milliseconds". + */ + const char *label; +}; + +/** + * @copybrief retro_core_option_v2_definition + * + * @deprecated Use \ref retro_core_option_v2_definition instead, + * as it supports categorizing options into groups. + * Only use this \c struct to support older frontends or cores. + * + * @see RETRO_ENVIRONMENT_SET_CORE_OPTIONS + * @see RETRO_ENVIRONMENT_SET_CORE_OPTIONS_INTL + */ +struct retro_core_option_definition +{ + /** @copydoc retro_core_option_v2_definition::key */ + const char *key; + + /** @copydoc retro_core_option_v2_definition::desc */ + const char *desc; + + /** @copydoc retro_core_option_v2_definition::info */ + const char *info; + + /** @copydoc retro_core_option_v2_definition::values */ + struct retro_core_option_value values[RETRO_NUM_CORE_OPTION_VALUES_MAX]; + + /** @copydoc retro_core_option_v2_definition::default_value */ + const char *default_value; +}; + +#ifdef __PS3__ +#undef local +#endif + +/** + * A variant of \ref retro_core_options that supports internationalization. + * + * @deprecated Use \ref retro_core_options_v2_intl instead, + * as it supports categorizing options into groups. + * Only use this \c struct to support older frontends or cores. + * + * @see retro_core_options + * @see RETRO_ENVIRONMENT_SET_CORE_OPTIONS_INTL + * @see RETRO_ENVIRONMENT_GET_LANGUAGE + * @see retro_language + */ +struct retro_core_options_intl +{ + /** @copydoc retro_core_options_v2_intl::us */ + struct retro_core_option_definition *us; + + /** @copydoc retro_core_options_v2_intl::local */ + struct retro_core_option_definition *local; +}; + +/** + * A descriptor for a group of related core options. + * + * Here's an example category: + * + * @code + * { + * "cpu", + * "CPU Emulation", + * "Settings for CPU quirks." + * } + * @endcode + * + * @see retro_core_options_v2 + * @see RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2 + * @see RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2_INTL + */ +struct retro_core_option_v2_category +{ + /** + * A string that uniquely identifies this category within the core's options. + * Any \c retro_core_option_v2_definition whose \c category_key matches this + * is considered to be within this category. + * Different cores may use the same category keys, + * so namespacing them is not necessary. + * Valid characters are [a-zA-Z0-9_-]. + * + * Frontends should use this category to organize core options, + * but may customize this category's presentation in other ways. + * For example, a frontend may use common keys like "audio" or "gfx" + * to select an appropriate icon in its UI. + * + * Required; must not be \c NULL. + */ + const char *key; + + /** + * A brief human-readable name for this category, + * intended for the frontend to display to the player. + * This should be a name that's concise and descriptive, such as "Audio" or "Video". + * + * Required; must not be \c NULL. + */ + const char *desc; + + /** + * A human-readable description for this category, + * intended for the frontend to display to the player + * as secondary help text (e.g. a sublabel or a tooltip). + * Optional; may be \c NULL or an empty string. + */ + const char *info; +}; + +/** + * A descriptor for a particular core option and the values it may take. + * + * Supports categorizing options into groups, + * so as not to overwhelm the player. + * + * @see retro_core_option_v2_category + * @see RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2 + * @see RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2_INTL + */ +struct retro_core_option_v2_definition +{ + /** + * A unique identifier for this option that cores may use + * \ref RETRO_ENVIRONMENT_GET_VARIABLE "to query its value from the frontend". + * Must be unique within this core. + * + * Should be unique globally; + * the recommended method for doing so + * is to prefix each option with the core's name. + * For example, an option that controls the resolution for a core named "foo" + * should be named \c "foo_resolution". + * + * Valid key characters are in the set [a-zA-Z0-9_-]. + */ + const char *key; + + /** + * A human-readable name for this option, + * intended to be displayed by frontends that don't support + * categorizing core options. + * + * Required; must not be \c NULL or empty. + */ + const char *desc; + + /** + * A human-readable name for this option, + * intended to be displayed by frontends that support + * categorizing core options. + * + * This version may be slightly more concise than \ref desc, + * as it can rely on the structure of the options menu. + * For example, "Interface" is a good \c desc_categorized, + * as it can be displayed as a sublabel for a "Network" category. + * For \c desc, "Network Interface" would be more suitable. + * + * Optional; if this field or \c category_key is empty or \c NULL, + * \c desc will be used instead. + */ + const char *desc_categorized; + + /** + * A human-readable description of this option and its effects, + * intended to be displayed by frontends that don't support + * categorizing core options. + * + * @details Intended to be displayed as secondary help text, + * such as a tooltip or a sublabel. + * + * Here are some suggestions for writing a good description: + * + * \li Avoid technical jargon unless this option is meant for advanced users. + * If unavoidable, suggest one of the default options for those unsure. + * \li Don't repeat the option name in the description; + * instead, describe what the option name means. + * \li If an option requires a core restart or game reset to take effect, + * be sure to say so. + * \li Try to make the option labels obvious + * so that they don't need to be explained in the description. + * + * Optional; may be \c NULL. + */ + const char *info; + + /** + * @brief A human-readable description of this option and its effects, + * intended to be displayed by frontends that support + * categorizing core options. + * + * This version is provided to accommodate descriptions + * that reference other options by name, + * as options may have different user-facing names + * depending on whether the frontend supports categorization. + * + * @copydetails info + * + * If empty or \c NULL, \c info will be used instead. + * Will be ignored if \c category_key is empty or \c NULL. + */ + const char *info_categorized; + + /** + * The key of the category that this option belongs to. + * + * Optional; if equal to \ref retro_core_option_v2_category::key "a defined category", + * then this option shall be displayed by the frontend + * next to other options in this same category, + * assuming it supports doing so. + * Option categories are intended to be displayed in a submenu, + * but this isn't a hard requirement. + * + * If \c NULL, empty, or not equal to a defined category, + * then this option is considered uncategorized + * and the frontend shall display it outside of any category + * (most likely at a top-level menu). + * + * @see retro_core_option_v2_category + */ + const char *category_key; + + /** + * One or more possible values for this option, + * up to the limit of \ref RETRO_NUM_CORE_OPTION_VALUES_MAX. + * + * Terminated by a \c { NULL, NULL } element, + * although frontends should work even if all elements are used. + */ + struct retro_core_option_value values[RETRO_NUM_CORE_OPTION_VALUES_MAX]; + + /** + * The default value for this core option. + * Used if it hasn't been set, e.g. for new cores. + * Must equal one of the \ref value members in the \c values array, + * or else this option will be ignored. + */ + const char *default_value; +}; + +/** + * A set of core option descriptors and the categories that group them, + * suitable for enabling a core to be customized. + * + * @see RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2 + */ +struct retro_core_options_v2 +{ + /** + * An array of \ref retro_core_option_v2_category "option categories", + * terminated by a zeroed-out category \c struct. + * + * Will be ignored if the frontend doesn't support core option categories. + * + * If \c NULL or ignored, all options will be treated as uncategorized. + * This most likely means that a frontend will display them at a top-level menu + * without any kind of hierarchy or grouping. + */ + struct retro_core_option_v2_category *categories; + + /** + * An array of \ref retro_core_option_v2_definition "core option descriptors", + * terminated by a zeroed-out definition \c struct. + * + * Required; must not be \c NULL. + */ + struct retro_core_option_v2_definition *definitions; +}; + +/** + * A variant of \ref retro_core_options_v2 that supports internationalization. + * + * @see retro_core_options_v2 + * @see RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2_INTL + * @see RETRO_ENVIRONMENT_GET_LANGUAGE + * @see retro_language + */ +struct retro_core_options_v2_intl +{ + /** + * Pointer to a core options set + * whose text is written in American English. + * + * This may be passed to \c RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2 as-is + * if not using \c RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2_INTL. + * + * Required; must not be \c NULL. + */ + struct retro_core_options_v2 *us; + + /** + * Pointer to a core options set + * whose text is written in one of libretro's \ref retro_language "supported languages", + * most likely the one returned by \ref RETRO_ENVIRONMENT_GET_LANGUAGE. + * + * Structure is the same, but usage is slightly different: + * + * \li All text (except for keys and option values) + * should be written in whichever language + * is returned by \c RETRO_ENVIRONMENT_GET_LANGUAGE. + * \li All fields besides keys and option values may be \c NULL, + * in which case the corresponding string in \c us + * is used instead. + * \li All \ref retro_core_option_v2_definition::default_value "default option values" + * are taken from \c us. + * The defaults in this field are ignored. + * + * May be \c NULL, in which case \c us is used instead. + */ + struct retro_core_options_v2 *local; +}; + +/** + * Called by the frontend to determine if any core option's visibility has changed. + * + * Each time a frontend sets a core option, + * it should call this function to see if + * any core option should be made visible or invisible. + * + * May also be called after \ref retro_load_game "loading a game", + * to determine what the initial visibility of each option should be. + * + * Within this function, the core must update the visibility + * of any dynamically-hidden options + * using \ref RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY. + * + * @note All core options are visible by default, + * even during this function's first call. + * + * @return \c true if any core option's visibility was adjusted + * since the last call to this function. + * @see RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY + * @see retro_core_option_display + */ +typedef bool (RETRO_CALLCONV *retro_core_options_update_display_callback_t)(void); + +/** + * Callback registered by the core for the frontend to use + * when setting the visibility of each core option. + * + * @see RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY + * @see retro_core_option_display + */ +struct retro_core_options_update_display_callback +{ + /** + * @copydoc retro_core_options_update_display_callback_t + * + * Set by the core. + */ + retro_core_options_update_display_callback_t callback; +}; + +/** @} */ + +struct retro_game_info +{ + const char *path; /* Path to game, UTF-8 encoded. + * Sometimes used as a reference for building other paths. + * May be NULL if game was loaded from stdin or similar, + * but in this case some cores will be unable to load `data`. + * So, it is preferable to fabricate something here instead + * of passing NULL, which will help more cores to succeed. + * retro_system_info::need_fullpath requires + * that this path is valid. */ + const void *data; /* Memory buffer of loaded game. Will be NULL + * if need_fullpath was set. */ + size_t size; /* Size of memory buffer. */ + const char *meta; /* String of implementation specific meta-data. */ +}; + +/** @defgroup GET_CURRENT_SOFTWARE_FRAMEBUFFER Frontend-Owned Framebuffers + * @{ + */ + +/** @defgroup RETRO_MEMORY_ACCESS Framebuffer Memory Access Types + * @{ + */ + +/** Indicates that core will write to the framebuffer returned by the frontend. */ +#define RETRO_MEMORY_ACCESS_WRITE (1 << 0) + +/** Indicates that the core will read from the framebuffer returned by the frontend. */ +#define RETRO_MEMORY_ACCESS_READ (1 << 1) + +/** @} */ + +/** @defgroup RETRO_MEMORY_TYPE Framebuffer Memory Types + * @{ + */ + +/** + * Indicates that the returned framebuffer's memory is cached. + * If not set, random access to the buffer may be very slow. + */ +#define RETRO_MEMORY_TYPE_CACHED (1 << 0) + +/** @} */ + +/** + * A frame buffer owned by the frontend that a core may use for rendering. + * + * @see GET_CURRENT_SOFTWARE_FRAMEBUFFER + * @see retro_video_refresh_t + */ +struct retro_framebuffer +{ + /** + * Pointer to the beginning of the framebuffer provided by the frontend. + * The initial contents of this buffer are unspecified, + * as is the means used to map the memory; + * this may be defined in software, + * or it may be GPU memory mapped to RAM. + * + * If the framebuffer is used, + * this pointer must be passed to \c retro_video_refresh_t as-is. + * It is undefined behavior to pass an offset to this pointer. + * + * @warning This pointer is only guaranteed to be valid + * for the duration of the same \c retro_run iteration + * \ref GET_CURRENT_SOFTWARE_FRAMEBUFFER "that requested the framebuffer". + * Reuse of this pointer is undefined. + */ + void *data; + + /** + * The width of the framebuffer given in \c data, in pixels. + * Set by the core. + * + * @warning If the framebuffer is used, + * this value must be passed to \c retro_video_refresh_t as-is. + * It is undefined behavior to try to render \c data with any other width. + */ + unsigned width; + + /** + * The height of the framebuffer given in \c data, in pixels. + * Set by the core. + * + * @warning If the framebuffer is used, + * this value must be passed to \c retro_video_refresh_t as-is. + * It is undefined behavior to try to render \c data with any other height. + */ + unsigned height; + + /** + * The distance between the start of one scanline and the beginning of the next, in bytes. + * In practice this is usually equal to \c width times the pixel size, + * but that's not guaranteed. + * Sometimes called the "stride". + * + * @setby{frontend} + * @warning If the framebuffer is used, + * this value must be passed to \c retro_video_refresh_t as-is. + * It is undefined to try to render \c data with any other pitch. + */ + size_t pitch; + + /** + * The pixel format of the returned framebuffer. + * May be different than the format specified by the core in \c RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, + * e.g. due to conversions. + * Set by the frontend. + * + * @see RETRO_ENVIRONMENT_SET_PIXEL_FORMAT + */ + enum retro_pixel_format format; + + /** + * One or more \ref RETRO_MEMORY_ACCESS "memory access flags" + * that specify how the core will access the memory in \c data. + * + * @setby{core} + */ + unsigned access_flags; + + /** + * Zero or more \ref RETRO_MEMORY_TYPE "memory type flags" + * that describe how the framebuffer's memory has been mapped. + * + * @setby{frontend} + */ + unsigned memory_flags; +}; + +/** @} */ + +/** @defgroup SET_FASTFORWARDING_OVERRIDE Fast-Forward Override + * @{ + */ + +/** + * Parameters that govern when and how the core takes control + * of fast-forwarding mode. + */ +struct retro_fastforwarding_override +{ + /** + * The factor by which the core will be sped up + * when \c fastforward is \c true. + * This value is used as follows: + * + * @li A value greater than 1.0 will run the core at + * the specified multiple of normal speed. + * For example, a value of 5.0 + * combined with a normal target rate of 60 FPS + * will result in a target rate of 300 FPS. + * The actual rate may be lower if the host's hardware can't keep up. + * @li A value of 1.0 will run the core at normal speed. + * @li A value between 0.0 (inclusive) and 1.0 (exclusive) + * will run the core as fast as the host system can manage. + * @li A negative value will let the frontend choose a factor. + * @li An infinite value or \c NaN results in undefined behavior. + * + * @attention Setting this value to less than 1.0 will \em not + * slow down the core. + */ + float ratio; + + /** + * If \c true, the frontend should activate fast-forwarding + * until this field is set to \c false or the core is unloaded. + */ + bool fastforward; + + /** + * If \c true, the frontend should display an on-screen notification or icon + * while \c fastforward is \c true (where supported). + * Otherwise, the frontend should not display any such notification. + */ + bool notification; + + /** + * If \c true, the core has exclusive control + * over enabling and disabling fast-forwarding + * via the \c fastforward field. + * The frontend will not be able to start or stop fast-forwarding + * until this field is set to \c false or the core is unloaded. + */ + bool inhibit_toggle; +}; + +/** @} */ + +/** + * During normal operation. + * + * @note Rate will be equal to the core's internal FPS. + */ +#define RETRO_THROTTLE_NONE 0 + +/** + * While paused or stepping single frames. + * + * @note Rate will be 0. + */ +#define RETRO_THROTTLE_FRAME_STEPPING 1 + +/** + * During fast forwarding. + * + * @note Rate will be 0 if not specifically limited to a maximum speed. + */ +#define RETRO_THROTTLE_FAST_FORWARD 2 + +/** + * During slow motion. + * + * @note Rate will be less than the core's internal FPS. + */ +#define RETRO_THROTTLE_SLOW_MOTION 3 + +/** + * While rewinding recorded save states. + * + * @note Rate can vary depending on the rewind speed or be 0 if the frontend + * is not aiming for a specific rate. + */ +#define RETRO_THROTTLE_REWINDING 4 + +/** + * While vsync is active in the video driver, and the target refresh rate is lower than the core's internal FPS. + * + * @note Rate is the target refresh rate. + */ +#define RETRO_THROTTLE_VSYNC 5 + +/** + * When the frontend does not throttle in any way. + * + * @note Rate will be 0. An example could be if no vsync or audio output is active. + */ +#define RETRO_THROTTLE_UNBLOCKED 6 + +/** + * Details about the actual rate an implementation is calling \c retro_run() at. + * + * @see RETRO_ENVIRONMENT_GET_THROTTLE_STATE + */ +struct retro_throttle_state +{ + /** + * The current throttling mode. + * + * @note Should be one of the \c RETRO_THROTTLE_* values. + * @see RETRO_THROTTLE_NONE + * @see RETRO_THROTTLE_FRAME_STEPPING + * @see RETRO_THROTTLE_FAST_FORWARD + * @see RETRO_THROTTLE_SLOW_MOTION + * @see RETRO_THROTTLE_REWINDING + * @see RETRO_THROTTLE_VSYNC + * @see RETRO_THROTTLE_UNBLOCKED + */ + unsigned mode; + + /** + * How many times per second the frontend aims to call retro_run. + * + * @note Depending on the mode, it can be 0 if there is no known fixed rate. + * This won't be accurate if the total processing time of the core and + * the frontend is longer than what is available for one frame. + */ + float rate; +}; + +/** @defgroup GET_MICROPHONE_INTERFACE Microphone Interface + * @{ + */ + +/** + * Opaque handle to a microphone that's been opened for use. + * The underlying object is accessed or created with \c retro_microphone_interface_t. + */ +typedef struct retro_microphone retro_microphone_t; + +/** + * Parameters for configuring a microphone. + * Some of these might not be honored, + * depending on the available hardware and driver configuration. + */ +typedef struct retro_microphone_params +{ + /** + * The desired sample rate of the microphone's input, in Hz. + * The microphone's input will be resampled, + * so cores can ask for whichever frequency they need. + * + * If zero, some reasonable default will be provided by the frontend + * (usually from its config file). + * + * @see retro_get_mic_rate_t + */ + unsigned rate; +} retro_microphone_params_t; + +/** + * @copydoc retro_microphone_interface::open_mic + */ +typedef retro_microphone_t *(RETRO_CALLCONV *retro_open_mic_t)(const retro_microphone_params_t *params); + +/** + * @copydoc retro_microphone_interface::close_mic + */ +typedef void (RETRO_CALLCONV *retro_close_mic_t)(retro_microphone_t *microphone); + +/** + * @copydoc retro_microphone_interface::get_params + */ +typedef bool (RETRO_CALLCONV *retro_get_mic_params_t)(const retro_microphone_t *microphone, retro_microphone_params_t *params); + +/** + * @copydoc retro_microphone_interface::set_mic_state + */ +typedef bool (RETRO_CALLCONV *retro_set_mic_state_t)(retro_microphone_t *microphone, bool state); + +/** + * @copydoc retro_microphone_interface::get_mic_state + */ +typedef bool (RETRO_CALLCONV *retro_get_mic_state_t)(const retro_microphone_t *microphone); + +/** + * @copydoc retro_microphone_interface::read_mic + */ +typedef int (RETRO_CALLCONV *retro_read_mic_t)(retro_microphone_t *microphone, int16_t* samples, size_t num_samples); + +/** + * The current version of the microphone interface. + * Will be incremented whenever \c retro_microphone_interface or \c retro_microphone_params_t + * receive new fields. + * + * Frontends using cores built against older mic interface versions + * should not access fields introduced in newer versions. + */ +#define RETRO_MICROPHONE_INTERFACE_VERSION 1 + +/** + * An interface for querying the microphone and accessing data read from it. + * + * @see RETRO_ENVIRONMENT_GET_MICROPHONE_INTERFACE + */ +struct retro_microphone_interface +{ + /** + * The version of this microphone interface. + * Set by the core to request a particular version, + * and set by the frontend to indicate the returned version. + * 0 indicates that the interface is invalid or uninitialized. + */ + unsigned interface_version; + + /** + * Initializes a new microphone. + * Assuming that microphone support is enabled and provided by the frontend, + * cores may call this function whenever necessary. + * A microphone could be opened throughout a core's lifetime, + * or it could wait until a microphone is plugged in to the emulated device. + * + * The returned handle will be valid until it's freed, + * even if the audio driver is reinitialized. + * + * This function is not guaranteed to be thread-safe. + * + * @param[in] args Parameters used to create the microphone. + * May be \c NULL, in which case the default value of each parameter will be used. + * + * @returns Pointer to the newly-opened microphone, + * or \c NULL if one couldn't be opened. + * This likely means that no microphone is plugged in and recognized, + * or the maximum number of supported microphones has been reached. + * + * @note Microphones are \em inactive by default; + * to begin capturing audio, call \c set_mic_state. + * @see retro_microphone_params_t + */ + retro_open_mic_t open_mic; + + /** + * Closes a microphone that was initialized with \c open_mic. + * Calling this function will stop all microphone activity + * and free up the resources that it allocated. + * Afterwards, the handle is invalid and must not be used. + * + * A frontend may close opened microphones when unloading content, + * but this behavior is not guaranteed. + * Cores should close their microphones when exiting, just to be safe. + * + * @param microphone Pointer to the microphone that was allocated by \c open_mic. + * If \c NULL, this function does nothing. + * + * @note The handle might be reused if another microphone is opened later. + */ + retro_close_mic_t close_mic; + + /** + * Returns the configured parameters of this microphone. + * These may differ from what was requested depending on + * the driver and device configuration. + * + * Cores should check these values before they start fetching samples. + * + * Will not change after the mic was opened. + * + * @param[in] microphone Opaque handle to the microphone + * whose parameters will be retrieved. + * @param[out] params The parameters object that the + * microphone's parameters will be copied to. + * + * @return \c true if the parameters were retrieved, + * \c false if there was an error. + */ + retro_get_mic_params_t get_params; + + /** + * Enables or disables the given microphone. + * Microphones are disabled by default + * and must be explicitly enabled before they can be used. + * Disabled microphones will not process incoming audio samples, + * and will therefore have minimal impact on overall performance. + * Cores may enable microphones throughout their lifetime, + * or only for periods where they're needed. + * + * Cores that accept microphone input should be able to operate without it; + * we suggest substituting silence in this case. + * + * @param microphone Opaque handle to the microphone + * whose state will be adjusted. + * This will have been provided by \c open_mic. + * @param state \c true if the microphone should receive audio input, + * \c false if it should be idle. + * @returns \c true if the microphone's state was successfully set, + * \c false if \c microphone is invalid + * or if there was an error. + */ + retro_set_mic_state_t set_mic_state; + + /** + * Queries the active state of a microphone at the given index. + * Will return whether the microphone is enabled, + * even if the driver is paused. + * + * @param microphone Opaque handle to the microphone + * whose state will be queried. + * @return \c true if the provided \c microphone is valid and active, + * \c false if not or if there was an error. + */ + retro_get_mic_state_t get_mic_state; + + /** + * Retrieves the input processed by the microphone since the last call. + * \em Must be called every frame unless \c microphone is disabled, + * similar to how \c retro_audio_sample_batch_t works. + * + * @param[in] microphone Opaque handle to the microphone + * whose recent input will be retrieved. + * @param[out] samples The buffer that will be used to store the microphone's data. + * Microphone input is in mono (i.e. one number per sample). + * Should be large enough to accommodate the expected number of samples per frame; + * for example, a 44.1kHz sample rate at 60 FPS would require space for 735 samples. + * @param[in] num_samples The size of the data buffer in samples (\em not bytes). + * Microphone input is in mono, so a "frame" and a "sample" are equivalent in length here. + * + * @return The number of samples that were copied into \c samples. + * If \c microphone is pending driver initialization, + * this function will copy silence of the requested length into \c samples. + * + * Will return -1 if the microphone is disabled, + * the audio driver is paused, + * or there was an error. + */ + retro_read_mic_t read_mic; +}; + +/** @} */ + +/** @defgroup GET_DEVICE_POWER Device Power + * @{ + */ + +/** + * Describes how a device is being powered. + * @see RETRO_ENVIRONMENT_GET_DEVICE_POWER + */ +enum retro_power_state +{ + /** + * Indicates that the frontend cannot report its power state at this time, + * most likely due to a lack of support. + * + * \c RETRO_ENVIRONMENT_GET_DEVICE_POWER will not return this value; + * instead, the environment callback will return \c false. + */ + RETRO_POWERSTATE_UNKNOWN = 0, + + /** + * Indicates that the device is running on its battery. + * Usually applies to portable devices such as handhelds, laptops, and smartphones. + */ + RETRO_POWERSTATE_DISCHARGING, + + /** + * Indicates that the device's battery is currently charging. + */ + RETRO_POWERSTATE_CHARGING, + + /** + * Indicates that the device is connected to a power source + * and that its battery has finished charging. + */ + RETRO_POWERSTATE_CHARGED, + + /** + * Indicates that the device is connected to a power source + * and that it does not have a battery. + * This usually suggests a desktop computer or a non-portable game console. + */ + RETRO_POWERSTATE_PLUGGED_IN +}; + +/** + * Indicates that an estimate is not available for the battery level or time remaining, + * even if the actual power state is known. + */ +#define RETRO_POWERSTATE_NO_ESTIMATE (-1) + +/** + * Describes the power state of the device running the frontend. + * @see RETRO_ENVIRONMENT_GET_DEVICE_POWER + */ +struct retro_device_power +{ + /** + * The current state of the frontend's power usage. + */ + enum retro_power_state state; + + /** + * A rough estimate of the amount of time remaining (in seconds) + * before the device powers off. + * This value depends on a variety of factors, + * so it is not guaranteed to be accurate. + * + * Will be set to \c RETRO_POWERSTATE_NO_ESTIMATE if \c state does not equal \c RETRO_POWERSTATE_DISCHARGING. + * May still be set to \c RETRO_POWERSTATE_NO_ESTIMATE if the frontend is unable to provide an estimate. + */ + int seconds; + + /** + * The approximate percentage of battery charge, + * ranging from 0 to 100 (inclusive). + * The device may power off before this reaches 0. + * + * The user might have configured their device + * to stop charging before the battery is full, + * so do not assume that this will be 100 in the \c RETRO_POWERSTATE_CHARGED state. + */ + int8_t percent; +}; + +/** @} */ + +/** @defgroup Executable Memory Modes + * Describes how the frontend provisions executable memory. + * @{ + */ + +#define RETRO_EXEC_MEM_MODE_UNAVAILABLE 0 /**< No executable memory available */ +#define RETRO_EXEC_MEM_MODE_UNRESTRICTED 1 /**< No restrictions; core should self-allocate */ +#define RETRO_EXEC_MEM_MODE_RWX 2 /**< Single mapping, read-write-execute */ +#define RETRO_EXEC_MEM_MODE_WX_TOGGLE 3 /**< Single mapping, write XOR execute (core toggles) */ +#define RETRO_EXEC_MEM_MODE_DUAL_MAP 4 /**< Separate R-X and R-W mappings of same pages */ + +/** + * Parameters for \c RETRO_ENVIRONMENT_EXEC_MEM_ALLOC. + * + * The core fills in \c version and \c size before calling. + * The frontend fills in \c mode, \c rx, and \c rw on success. + * @see RETRO_ENVIRONMENT_EXEC_MEM_ALLOC + */ +struct retro_exec_mem_alloc +{ + unsigned version; /**< Set by core (currently 1). */ + size_t size; /**< Set by core: requested bytes. */ + unsigned mode; /**< Set by frontend: one of \c RETRO_EXEC_MEM_MODE_*. */ + void *rx; /**< Set by frontend: execute from this pointer. */ + void *rw; /**< Set by frontend: write through this pointer. + Equal to \c rx when mode is RWX or WX_TOGGLE. */ +}; + +/** + * Parameters for \c RETRO_ENVIRONMENT_EXEC_MEM_FREE. + * @see RETRO_ENVIRONMENT_EXEC_MEM_FREE + */ +struct retro_exec_mem_free +{ + void *rx; /**< The \c rx pointer returned by a previous alloc call. */ +}; + +/** @} */ + +/** + * @defgroup Callbacks + * @{ + */ + +/** + * Environment callback to give implementations a way of performing uncommon tasks. + * + * @note Extensible. + * + * @param cmd The command to run. + * @param data A pointer to the data associated with the command. + * + * @return Varies by callback, + * but will always return \c false if the command is not recognized. + * + * @see RETRO_ENVIRONMENT_SET_ROTATION + * @see retro_set_environment() + */ +typedef bool (RETRO_CALLCONV *retro_environment_t)(unsigned cmd, void *data); + +/** + * Render a frame. + * + * @note For performance reasons, it is highly recommended to have a frame + * that is packed in memory, i.e. pitch == width * byte_per_pixel. + * Certain graphic APIs, such as OpenGL ES, do not like textures + * that are not packed in memory. + * + * @param data A pointer to the frame buffer data with a pixel format of 15-bit \c 0RGB1555 native endian, unless changed with \c RETRO_ENVIRONMENT_SET_PIXEL_FORMAT. + * @param width The width of the frame buffer, in pixels. + * @param height The height frame buffer, in pixels. + * @param pitch The width of the frame buffer, in bytes. + * + * @see retro_set_video_refresh() + * @see RETRO_ENVIRONMENT_SET_PIXEL_FORMAT + * @see retro_pixel_format + */ +typedef void (RETRO_CALLCONV *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. + * + * @param left The left audio sample represented as a signed 16-bit native endian. + * @param right The right audio sample represented as a signed 16-bit native endian. + * + * @see retro_set_audio_sample() + * @see retro_set_audio_sample_batch() + */ +typedef void (RETRO_CALLCONV *retro_audio_sample_t)(int16_t left, int16_t right); + +/** + * Renders multiple audio frames in one go. + * + * @note Only one of the audio callbacks must ever be used. + * + * @param data A pointer to the audio sample data pairs to render. + * @param frames The number of frames that are represented in the data. One frame + * is defined as a sample of left and right channels, interleaved. + * For example: int16_t buf[4] = { l, r, l, r }; would be 2 frames. + * + * @return The number of frames that were processed. + * + * @see retro_set_audio_sample_batch() + * @see retro_set_audio_sample() + */ +typedef size_t (RETRO_CALLCONV *retro_audio_sample_batch_t)(const int16_t *data, + size_t frames); + +/** + * Polls input. + * + * @see retro_set_input_poll() + */ +typedef void (RETRO_CALLCONV *retro_input_poll_t)(void); + +/** + * Queries for input for player 'port'. + * + * @param port Which player 'port' to query. + * @param device Which device to query for. Will be masked with \c RETRO_DEVICE_MASK. + * @param index The input index to retrieve. + * The exact semantics depend on the device type given in \c device. + * @param id The ID of which value to query, like \c RETRO_DEVICE_ID_JOYPAD_B. + * @returns Depends on the provided arguments, + * but will return 0 if their values are unsupported + * by the frontend or the backing physical device. + * @note Specialization of devices such as \c RETRO_DEVICE_JOYPAD_MULTITAP that + * have been set with \c retro_set_controller_port_device() will still use the + * higher level \c RETRO_DEVICE_JOYPAD to request input. + * + * @see retro_set_input_state() + * @see RETRO_DEVICE_NONE + * @see RETRO_DEVICE_JOYPAD + * @see RETRO_DEVICE_MOUSE + * @see RETRO_DEVICE_KEYBOARD + * @see RETRO_DEVICE_LIGHTGUN + * @see RETRO_DEVICE_ANALOG + * @see RETRO_DEVICE_POINTER + */ +typedef int16_t (RETRO_CALLCONV *retro_input_state_t)(unsigned port, unsigned device, + unsigned index, unsigned id); + +/** + * Sets the environment callback. + * + * @param cb The function which is used when making environment calls. + * + * @note Guaranteed to be called before \c retro_init(). + * + * @see RETRO_ENVIRONMENT + */ +RETRO_API void retro_set_environment(retro_environment_t cb); + +/** + * Sets the video refresh callback. + * + * @param cb The function which is used when rendering a frame. + * + * @note Guaranteed to have been called before the first call to \c retro_run() is made. + */ +RETRO_API void retro_set_video_refresh(retro_video_refresh_t cb); + +/** + * Sets the audio sample callback. + * + * @param cb The function which is used when rendering a single audio frame. + * + * @note Guaranteed to have been called before the first call to \c retro_run() is made. + */ +RETRO_API void retro_set_audio_sample(retro_audio_sample_t cb); + +/** + * Sets the audio sample batch callback. + * + * @param cb The function which is used when rendering multiple audio frames in one go. + * + * @note Guaranteed to have been called before the first call to \c retro_run() is made. + */ +RETRO_API void retro_set_audio_sample_batch(retro_audio_sample_batch_t cb); + +/** + * Sets the input poll callback. + * + * @param cb The function which is used to poll the active input. + * + * @note Guaranteed to have been called before the first call to \c retro_run() is made. + */ +RETRO_API void retro_set_input_poll(retro_input_poll_t cb); + +/** + * Sets the input state callback. + * + * @param cb The function which is used to query the input state. + * + *@note Guaranteed to have been called before the first call to \c retro_run() is made. + */ +RETRO_API void retro_set_input_state(retro_input_state_t cb); + +/** + * @} + */ + +/** + * Called by the frontend when initializing a libretro core. + * + * @warning There are many possible "gotchas" with global state in dynamic libraries. + * Here are some to keep in mind: + *
    + *
  • Do not assume that the core was loaded by the operating system + * for the first time within this call. + * It may have been statically linked or retained from a previous session. + * Consequently, cores must not rely on global variables being initialized + * to their default values before this function is called; + * this also goes for object constructors in C++. + *
  • Although C++ requires that constructors be called for global variables, + * it does not require that their destructors be called + * if stored within a dynamic library's global scope. + *
  • If the core is statically linked to the frontend, + * global variables may be initialized when the frontend itself is initially executed. + *
+ * @see retro_deinit + */ +RETRO_API void retro_init(void); + +/** + * Called by the frontend when deinitializing a libretro core. + * The core must release all of its allocated resources before this function returns. + * + * @warning There are many possible "gotchas" with global state in dynamic libraries. + * Here are some to keep in mind: + *
    + *
  • Do not assume that the operating system will unload the core after this function returns, + * as the core may be linked statically or retained in memory. + * Cores should use this function to clean up all allocated resources + * and reset all global variables to their default states. + *
  • Do not assume that this core won't be loaded again after this function returns. + * It may be kept in memory by the frontend for later use, + * or it may be statically linked. + * Therefore, all global variables should be reset to their default states within this function. + *
  • C++ does not require that destructors be called + * for variables within a dynamic library's global scope. + * Therefore, global objects that own dynamically-managed resources + * (such as \c std::string or std::vector) + * should be kept behind pointers that are explicitly deallocated within this function. + *
+ * @see retro_init + */ +RETRO_API void retro_deinit(void); + +/** + * Retrieves which version of the libretro API is being used. + * + * @note This is used to validate ABI compatibility when the API is revised. + * + * @return Must return \c RETRO_API_VERSION. + * + * @see RETRO_API_VERSION + */ +RETRO_API unsigned retro_api_version(void); + +/** + * Gets statically known system info. + * + * @note Can be called at any time, even before retro_init(). + * + * @param info A pointer to a \c retro_system_info where the info is to be loaded into. This must be statically allocated. + */ +RETRO_API void retro_get_system_info(struct retro_system_info *info); + +/** + * Gets information about system audio/video timings and geometry. + * + * @note Can be called only after \c retro_load_game() has successfully completed. + * + * @note The implementation of this function might not initialize every variable + * if needed. For example, \c geom.aspect_ratio might not be initialized if + * the core doesn't desire a particular aspect ratio. + * + * @param info A pointer to a \c retro_system_av_info where the audio/video information should be loaded into. + * + * @see retro_system_av_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, \c RETRO_DEVICE_JOYPAD is assumed to be plugged into all + * available ports. + * + * @note Setting a particular device type is not a guarantee that libretro cores + * will only poll input based on that particular device type. It is only a + * 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. + * + * @note As part of the core's implementation of retro_set_controller_port_device, + * the core should call \c RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS to notify the + * frontend if the descriptions for any controls have changed as a + * result of changing the device type. + * + * @param port Which port to set the device for, usually indicates the player number. + * @param device Which device the given port is using. By default, \c RETRO_DEVICE_JOYPAD is assumed for all ports. + * + * @see RETRO_DEVICE_NONE + * @see RETRO_DEVICE_JOYPAD + * @see RETRO_DEVICE_MOUSE + * @see RETRO_DEVICE_KEYBOARD + * @see RETRO_DEVICE_LIGHTGUN + * @see RETRO_DEVICE_ANALOG + * @see RETRO_DEVICE_POINTER + * @see RETRO_ENVIRONMENT_SET_CONTROLLER_INFO + */ +RETRO_API void retro_set_controller_port_device(unsigned port, unsigned device); + +/** + * Resets the currently-loaded game. + * Cores should treat this as a soft reset (i.e. an emulated reset button) if possible, + * but hard resets are acceptable. + */ +RETRO_API void retro_reset(void); + +/** + * Runs the game for one video frame. + * + * During \c retro_run(), the \c retro_input_poll_t callback must be called at least once. + * + * @note If a frame is not rendered for reasons where a game "dropped" a frame, + * this still counts as a frame, and \c retro_run() should explicitly dupe + * a frame if \c RETRO_ENVIRONMENT_GET_CAN_DUPE returns true. In this case, + * the video callback can take a NULL argument for data. + * + * @see retro_input_poll_t + */ +RETRO_API void retro_run(void); + +/** + * Returns the amount of data the implementation requires to serialize internal state (save states). + * + * @note Between calls to \c retro_load_game() and \c retro_unload_game(), the + * 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. + * + * @return The amount of data the implementation requires to serialize the internal state. + * + * @see retro_serialize() + */ +RETRO_API size_t retro_serialize_size(void); + +/** + * Serializes the internal state. + * + * @param data A pointer to where the serialized data should be saved to. + * @param size The size of the memory. + * + * @return If failed, or size is lower than \c retro_serialize_size(), it + * should return false. On success, it will return true. + * + * @see retro_serialize_size() + * @see retro_unserialize() + */ +RETRO_API bool retro_serialize(void *data, size_t len); + +/** + * Unserialize the given state data, and load it into the internal state. + * + * @return Returns true if loading the state was successful, false otherwise. + * + * @see retro_serialize() + */ +RETRO_API bool retro_unserialize(const void *data, size_t len); + +/** + * Reset all the active cheats to their default disabled state. + * + * @see retro_cheat_set() + */ +RETRO_API void retro_cheat_reset(void); + +/** + * Enable or disable a cheat. + * + * @param index The index of the cheat to act upon. + * @param enabled Whether to enable or disable the cheat. + * @param code A string of the code used for the cheat. + * + * @see retro_cheat_reset() + */ +RETRO_API void retro_cheat_set(unsigned index, bool enabled, const char *code); + +/** + * Loads a game. + * + * @param game A pointer to a \c retro_game_info detailing information about the game to load. + * May be \c NULL if the core is loaded without content. + * + * @return Will return true when the game was loaded successfully, or false otherwise. + * + * @see retro_game_info + * @see RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME + */ +RETRO_API bool retro_load_game(const struct retro_game_info *game); + +/** + * Called when the frontend has loaded one or more "special" content files, + * typically through subsystems. + * + * @note Only necessary for cores that support subsystems. + * Others may return \c false or delegate to retro_load_game. + * + * @param game_type The type of game to load, + * as determined by \c retro_subsystem_info. + * @param info A pointer to an array of \c retro_game_info objects + * providing information about the loaded content. + * @param num_info The number of \c retro_game_info objects passed into the info parameter. + * @return \c true if loading is successful, false otherwise. + * If the core returns \c false, + * the frontend should abort the core + * and return to its main menu (if applicable). + * + * @see RETRO_ENVIRONMENT_GET_GAME_INFO_EXT + * @see RETRO_ENVIRONMENT_SET_SUBSYSTEM_INFO + * @see retro_load_game() + * @see retro_subsystem_info + */ +RETRO_API bool retro_load_game_special( + unsigned game_type, + const struct retro_game_info *info, size_t num_info +); + +/** + * Unloads the currently loaded game. + * + * @note This is called before \c retro_deinit(void). + * + * @see retro_load_game() + * @see retro_deinit() + */ +RETRO_API void retro_unload_game(void); + +/** + * Gets the region of the actively loaded content as either \c RETRO_REGION_NTSC or \c RETRO_REGION_PAL. + * @note This refers to the region of the content's intended television standard, + * not necessarily the region of the content's origin. + * For emulated consoles that don't use either standard + * (e.g. handhelds or post-HD platforms), + * the core should return \c RETRO_REGION_NTSC. + * @return The region of the actively loaded content. + * + * @see RETRO_REGION_NTSC + * @see RETRO_REGION_PAL + */ +RETRO_API unsigned retro_get_region(void); + +/** + * Get a region of memory. + * + * @param id The ID for the memory block that's desired to retrieve. Can be \c RETRO_MEMORY_SAVE_RAM, \c RETRO_MEMORY_RTC, \c RETRO_MEMORY_SYSTEM_RAM, or \c RETRO_MEMORY_VIDEO_RAM. + * + * @return A pointer to the desired region of memory, or NULL when not available. + * + * @see RETRO_MEMORY_SAVE_RAM + * @see RETRO_MEMORY_RTC + * @see RETRO_MEMORY_SYSTEM_RAM + * @see RETRO_MEMORY_VIDEO_RAM + */ +RETRO_API void *retro_get_memory_data(unsigned id); + +/** + * Gets the size of the given region of memory. + * + * @param id The ID for the memory block to check the size of. Can be RETRO_MEMORY_SAVE_RAM, RETRO_MEMORY_RTC, RETRO_MEMORY_SYSTEM_RAM, or RETRO_MEMORY_VIDEO_RAM. + * + * @return The size of the region in memory, or 0 when not available. + * + * @see RETRO_MEMORY_SAVE_RAM + * @see RETRO_MEMORY_RTC + * @see RETRO_MEMORY_SYSTEM_RAM + * @see RETRO_MEMORY_VIDEO_RAM + */ +RETRO_API size_t retro_get_memory_size(unsigned id); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libretro/link.T b/src/libretro/link.T new file mode 100644 index 000000000..b0c262db9 --- /dev/null +++ b/src/libretro/link.T @@ -0,0 +1,5 @@ +{ + global: retro_*; + local: *; +}; + From 946b68777b1c134c9afaf2c022c6a0059a313c35 Mon Sep 17 00:00:00 2001 From: azaka Date: Sat, 13 Jun 2026 13:17:26 +0800 Subject: [PATCH 2/5] audio support --- CMakeLists.txt | 6 ++++-- src/audio/miniaudio/ma_audio_system.c | 5 +++++ src/libretro/libretro.c | 30 +++++++++++++++++++++++++-- 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 93d3c56d9..ad57068bf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,7 +37,7 @@ if(AUDIO_BACKEND STREQUAL "") elseif(PLATFORM STREQUAL "ps2") set(AUDIO_BACKEND "ps2") elseif(PLATFORM STREQUAL "libretro") - set(AUDIO_BACKEND "none") + set(AUDIO_BACKEND "miniaudio") else() set(AUDIO_BACKEND "miniaudio") endif() @@ -640,6 +640,7 @@ elseif(PLATFORM STREQUAL "libretro") ${CMAKE_SOURCE_DIR}/src/desktop ${CMAKE_SOURCE_DIR}/src/libretro vendor/stb/image + vendor/stb/vorbis ) # Rename output to butterscotch_libretro.so @@ -656,11 +657,12 @@ elseif(PLATFORM STREQUAL "libretro") # Libraries find_library(DL_LIB dl) - target_link_libraries(butterscotch PRIVATE bzip2 m ${DL_LIB}) + target_link_libraries(butterscotch PRIVATE bzip2 m ${DL_LIB} ${AUDIO_LIBRARIES}) target_compile_definitions(butterscotch PRIVATE _GNU_SOURCE _FILE_OFFSET_BITS=64 + HAVE_LIBRETRO ) else() message(FATAL_ERROR "Unknown platform! ${PLATFORM}") diff --git a/src/audio/miniaudio/ma_audio_system.c b/src/audio/miniaudio/ma_audio_system.c index d6e9ec87d..95078145b 100644 --- a/src/audio/miniaudio/ma_audio_system.c +++ b/src/audio/miniaudio/ma_audio_system.c @@ -97,6 +97,11 @@ static void maInit(AudioSystem* audio, DataWin* dataWin, FileSystem* fileSystem) ma->fileSystem = fileSystem; ma_engine_config config = ma_engine_config_init(); +#ifdef HAVE_LIBRETRO + config.noDevice = MA_TRUE; + config.channels = 2; + config.sampleRate = 44100; +#endif ma_result result = ma_engine_init(&config, &ma->engine); if (result != MA_SUCCESS) { fprintf(stderr, "Audio: Failed to initialize miniaudio engine (error %d)\n", result); diff --git a/src/libretro/libretro.c b/src/libretro/libretro.c index 9ada052bc..0d203df7a 100644 --- a/src/libretro/libretro.c +++ b/src/libretro/libretro.c @@ -12,7 +12,7 @@ #include "runner_mouse.h" #include "runner_gamepad.h" #include "sw_renderer.h" -#include "noop_audio_system.h" +#include "ma_audio_system.h" #include "overlay_file_system.h" #include "desktop/platformdefs.h" #include "utils.h" @@ -417,7 +417,8 @@ bool retro_load_game(const struct retro_game_info *game) return false; } - AudioSystem* audio = (AudioSystem*)NoopAudioSystem_create(); + MaAudioSystem* maAudio = MaAudioSystem_create(); + AudioSystem* audio = (AudioSystem*)maAudio; g_runner = Runner_create(g_dataWin, g_vm, g_renderer, (FileSystem*)g_overlayFs, audio); g_runner->osType = OS_WINDOWS; @@ -513,6 +514,31 @@ void retro_run(void) if (dt > 0.1f) dt = 0.1f; g_runner->audioSystem->vtable->update(g_runner->audioSystem, dt); + // Read mixed PCM frames from miniaudio engine and push to libretro + static float mixFloat[8192 * 2]; + static int16_t mixInt16[8192 * 2]; + ma_engine* engine = &((MaAudioSystem*)g_runner->audioSystem)->engine; + if (engine) + { + ma_uint64 frames = (ma_uint64)(44100.0f * dt); + if (frames == 0) frames = 1; + if (frames > 8192) frames = 8192; + ma_uint64 read = 0; + ma_engine_read_pcm_frames(engine, mixFloat, frames, &read); + if (read > 0) + { + ma_uint64 total = read * 2; + for (ma_uint64 s = 0; s < total; s++) + { + float f = mixFloat[s]; + if (f < -1.0f) f = -1.0f; + if (f > 1.0f) f = 1.0f; + mixInt16[s] = (int16_t)(f * 32767.0f); + } + audio_batch_cb(mixInt16, (size_t)read); + } + } + int32_t gameW, gameH; if (g_runner->appSurfaceEnabled) { From d6c0b5bcbfb32fa56399f5c7b0680a0838712d62 Mon Sep 17 00:00:00 2001 From: azaka Date: Mon, 22 Jun 2026 21:30:58 +0800 Subject: [PATCH 3/5] update & add missing libs --- CMakeLists.txt | 2 +- src/libretro/libretro.c | 18 +++--------------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ad57068bf..4ccc0953a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -657,7 +657,7 @@ elseif(PLATFORM STREQUAL "libretro") # Libraries find_library(DL_LIB dl) - target_link_libraries(butterscotch PRIVATE bzip2 m ${DL_LIB} ${AUDIO_LIBRARIES}) + target_link_libraries(butterscotch PRIVATE bzip2 stb_ds sha1 m ${DL_LIB} ${AUDIO_LIBRARIES}) target_compile_definitions(butterscotch PRIVATE _GNU_SOURCE diff --git a/src/libretro/libretro.c b/src/libretro/libretro.c index 0d203df7a..ccf28e99d 100644 --- a/src/libretro/libretro.c +++ b/src/libretro/libretro.c @@ -24,18 +24,6 @@ static retro_input_state_t input_state_cb; static retro_audio_sample_batch_t audio_batch_cb; static retro_environment_t environ_cb; -static const char fallback_log_fmt[] = "libretro: "; - -static void fallback_log(enum retro_log_level level, const char *fmt, ...) -{ - (void)level; - va_list va; - fprintf(stderr, "%s", fallback_log_fmt); - va_start(va, fmt); - vfprintf(stderr, fmt, va); - va_end(va); -} - static Runner* g_runner = nullptr; static Renderer* g_renderer = nullptr; static OverlayFileSystem* g_overlayFs = nullptr; @@ -417,7 +405,7 @@ bool retro_load_game(const struct retro_game_info *game) return false; } - MaAudioSystem* maAudio = MaAudioSystem_create(); + MaAudioSystem* maAudio = MaAudioSystem_create(g_dataWin); AudioSystem* audio = (AudioSystem*)maAudio; g_runner = Runner_create(g_dataWin, g_vm, g_renderer, (FileSystem*)g_overlayFs, audio); @@ -591,13 +579,13 @@ void retro_run(void) Runner_computeViewDisplayScale(g_runner, gameW, gameH, &displayScaleX, &displayScaleY); Runner_drawPre(g_runner, fbWidth, fbHeight); - Runner_beginFrame(g_runner, gameW, gameH, fbWidth, fbHeight); + Runner_beginFrame(g_runner, gameW, gameH, fbWidth, fbHeight, fbWidth, fbHeight); if (g_runner->drawBackgroundColor) SWRenderer_clearFrameBuffer(g_renderer, g_runner->backgroundColor); else SWRenderer_clearFrameBuffer(g_renderer, 0); - Runner_drawViews(g_runner, gameW, gameH, displayScaleX, displayScaleY, false); + Runner_drawViews(g_runner, gameW, gameH, false); g_renderer->vtable->endFrameInit(g_renderer); Runner_drawPost(g_runner, fbWidth, fbHeight); g_renderer->vtable->endFrameEnd(g_renderer); From cafb47218978e283c56753981ab1b60c625ffb29 Mon Sep 17 00:00:00 2001 From: azaka Date: Wed, 24 Jun 2026 19:26:15 +0800 Subject: [PATCH 4/5] use opengl for rendering --- CMakeLists.txt | 38 +- src/libretro/glad/glad.h | 1 + src/libretro/libretro-common/glsm/glsm.c | 2897 +++++++++++ src/libretro/libretro-common/glsym/README.md | 11 + src/libretro/libretro-common/glsym/glgen.py | 155 + .../libretro-common/glsym/glsym_es2.c | 409 ++ .../libretro-common/glsym/glsym_es3.c | 413 ++ src/libretro/libretro-common/glsym/glsym_gl.c | 2541 ++++++++++ src/libretro/libretro-common/glsym/rglgen.c | 45 + src/libretro/libretro-common/glsym/rglgen.py | 147 + src/libretro/libretro-common/glsym/xglgen.py | 156 + .../libretro-common/include/array/rbuf.h | 120 + .../libretro-common/include/array/rhmap.h | 285 ++ .../libretro-common/include/audio/audio_mix.h | 94 + .../include/audio/audio_mixer.h | 90 + .../include/audio/audio_resampler.h | 223 + .../include/audio/conversion/dual_mono.h | 69 + .../include/audio/conversion/float_to_s16.h | 55 + .../include/audio/conversion/s16_to_float.h | 55 + .../include/audio/dsp_filter.h | 55 + .../libretro-common/include/boolean.h | 39 + .../libretro-common/include/cdrom/cdrom.h | 125 + .../libretro-common/include/clamping.h | 65 + .../include/compat/apple_compat.h | 84 + .../libretro-common/include/compat/fnmatch.h | 30 + .../include/compat/fopen_utf8.h | 34 + .../libretro-common/include/compat/getopt.h | 74 + .../libretro-common/include/compat/ifaddrs.h | 53 + .../include/compat/intrinsics.h | 99 + .../libretro-common/include/compat/msvc.h | 126 + .../include/compat/msvc/stdint.h | 255 + .../include/compat/posix_string.h | 60 + .../include/compat/strcasestr.h | 48 + .../libretro-common/include/compat/strl.h | 59 + .../libretro-common/include/compat/zconf.h | 483 ++ .../libretro-common/include/compat/zconf.h.in | 483 ++ .../libretro-common/include/compat/zlib.h | 1772 +++++++ .../include/compat/zlib/zconf.h | 483 ++ .../include/compat/zlib/zconf.h.in | 483 ++ .../include/compat/zlib/zlib.h | 1761 +++++++ .../include/compat/zlib/zutil.h | 253 + .../libretro-common/include/compat/zutil.h | 253 + .../include/defines/cocoa_defines.h | 76 + .../include/defines/d3d_defines.h | 92 + .../include/defines/gx_defines.h | 96 + .../include/defines/ps3_defines.h | 952 ++++ .../include/defines/ps4_defines.h | 46 + .../include/defines/psp_defines.h | 145 + .../libretro-common/include/dynamic/dylib.h | 71 + .../include/encodings/base64.h | 16 + .../libretro-common/include/encodings/crc32.h | 37 + .../libretro-common/include/encodings/utf.h | 137 + .../libretro-common/include/encodings/win32.h | 63 + .../libretro-common/include/fastcpy.h | 93 + .../include/features/features_cpu.h | 75 + .../include/file/archive_file.h | 210 + .../include/file/config_file.h | 323 ++ .../include/file/config_file_userdata.h | 64 + .../libretro-common/include/file/file_path.h | 682 +++ .../libretro-common/include/file/nbio.h | 124 + .../libretro-common/include/filters.h | 103 + .../libretro-common/include/formats/cdfs.h | 113 + .../libretro-common/include/formats/image.h | 102 + .../include/formats/logiqx_dat.h | 107 + .../include/formats/m3u_file.h | 122 + .../libretro-common/include/formats/rbmp.h | 66 + .../libretro-common/include/formats/rjpeg.h | 48 + .../libretro-common/include/formats/rjson.h | 242 + .../include/formats/rjson_helpers.h | 78 + .../libretro-common/include/formats/rpng.h | 64 + .../libretro-common/include/formats/rtga.h | 48 + .../libretro-common/include/formats/rwav.h | 87 + .../libretro-common/include/formats/rxml.h | 69 + .../include/gfx/gl_capabilities.h | 68 + .../include/gfx/math/matrix_3x3.h | 253 + .../include/gfx/math/matrix_4x4.h | 395 ++ .../include/gfx/math/vector_2.h | 138 + .../include/gfx/math/vector_3.h | 68 + .../include/gfx/math/vector_4.h | 61 + .../include/gfx/scaler/filter.h | 37 + .../include/gfx/scaler/pixconv.h | 110 + .../include/gfx/scaler/scaler.h | 128 + .../include/gfx/scaler/scaler_int.h | 46 + .../libretro-common/include/gfx/video_frame.h | 220 + .../libretro-common/include/glsm/glsm.h | 158 + .../libretro-common/include/glsm/glsmsym.h | 483 ++ .../libretro-common/include/glsym/glsym.h | 45 + .../libretro-common/include/glsym/glsym_es2.h | 639 +++ .../libretro-common/include/glsym/glsym_es3.h | 653 +++ .../libretro-common/include/glsym/glsym_gl.h | 3140 ++++++++++++ .../libretro-common/include/glsym/rglgen.h | 46 + .../include/glsym/rglgen_headers.h | 53 + .../include/glsym/rglgen_private_headers.h | 76 + .../include/glsym/switch/nx_gl.h | 848 ++++ .../include/glsym/switch/nx_glsym.h | 928 ++++ .../include/libchdr/bitstream.h | 42 + .../libretro-common/include/libchdr/cdrom.h | 69 + .../libretro-common/include/libchdr/chd.h | 397 ++ .../include/libchdr/coretypes.h | 22 + .../libretro-common/include/libchdr/flac.h | 70 + .../libretro-common/include/libchdr/huffman.h | 89 + .../include/libchdr/libchdr_zlib.h | 69 + .../libretro-common/include/libchdr/lzma.h | 73 + .../libretro-common/include/libchdr/minmax.h | 21 + src/libretro/libretro-common/include/libco.h | 79 + .../libretro-common/include/libretro.h | 4308 +++++++++++++++++ .../libretro-common/include/libretro_d3d.h | 87 + .../include/libretro_dspfilter.h | 187 + .../include/libretro_gskit_ps2.h | 66 + .../libretro-common/include/libretro_vulkan.h | 494 ++ .../libretro-common/include/lists/dir_list.h | 100 + .../libretro-common/include/lists/file_list.h | 117 + .../include/lists/linked_list.h | 298 ++ .../include/lists/nested_list.h | 242 + .../include/lists/string_list.h | 205 + .../libretro-common/include/lrc_hash.h | 95 + .../libretro-common/include/math/complex.h | 77 + .../include/math/float_minmax.h | 61 + .../libretro-common/include/math/fxp.h | 61 + .../include/media/media_detect_cd.h | 61 + .../libretro-common/include/memalign.h | 40 + src/libretro/libretro-common/include/memmap.h | 52 + .../libretro-common/include/net/net_compat.h | 421 ++ .../libretro-common/include/net/net_http.h | 131 + .../include/net/net_http_parse.h | 53 + .../libretro-common/include/net/net_ifinfo.h | 54 + .../libretro-common/include/net/net_socket.h | 118 + .../include/net/net_socket_ssl.h | 50 + .../include/playlists/label_sanitization.h | 42 + .../include/queues/fifo_queue.h | 75 + .../include/queues/generic_queue.h | 208 + .../include/queues/message_queue.h | 156 + .../include/queues/task_queue.h | 262 + .../libretro-common/include/retro_assert.h | 35 + .../libretro-common/include/retro_common.h | 36 + .../include/retro_common_api.h | 139 + .../libretro-common/include/retro_dirent.h | 77 + .../include/retro_endianness.h | 580 +++ .../include/retro_environment.h | 114 + .../libretro-common/include/retro_inline.h | 39 + .../libretro-common/include/retro_math.h | 190 + .../include/retro_miscellaneous.h | 222 + .../libretro-common/include/retro_stat.h | 63 + .../libretro-common/include/retro_timers.h | 116 + .../include/rthreads/async_job.h | 35 + .../include/rthreads/rthreads.h | 269 + .../libretro-common/include/rthreads/tpool.h | 96 + .../include/streams/chd_stream.h | 68 + .../include/streams/file_stream.h | 142 + .../include/streams/file_stream_transforms.h | 101 + .../include/streams/interface_stream.h | 132 + .../include/streams/memory_stream.h | 63 + .../include/streams/network_stream.h | 267 + .../include/streams/rzip_stream.h | 188 + .../include/streams/stdin_stream.h | 39 + .../include/streams/trans_stream.h | 106 + .../include/string/stdstring.h | 387 ++ .../libretro-common/include/time/rtime.h | 48 + .../libretro-common/include/utils/md5.h | 51 + .../libretro-common/include/vfs/vfs.h | 111 + .../include/vfs/vfs_implementation.h | 82 + .../include/vfs/vfs_implementation_cdrom.h | 52 + .../include/vulkan/vulkan_symbol_wrapper.h | 347 ++ src/libretro/libretro.c | 151 +- 164 files changed, 41505 insertions(+), 18 deletions(-) create mode 100644 src/libretro/glad/glad.h create mode 100644 src/libretro/libretro-common/glsm/glsm.c create mode 100644 src/libretro/libretro-common/glsym/README.md create mode 100755 src/libretro/libretro-common/glsym/glgen.py create mode 100644 src/libretro/libretro-common/glsym/glsym_es2.c create mode 100644 src/libretro/libretro-common/glsym/glsym_es3.c create mode 100644 src/libretro/libretro-common/glsym/glsym_gl.c create mode 100644 src/libretro/libretro-common/glsym/rglgen.c create mode 100755 src/libretro/libretro-common/glsym/rglgen.py create mode 100644 src/libretro/libretro-common/glsym/xglgen.py create mode 100644 src/libretro/libretro-common/include/array/rbuf.h create mode 100644 src/libretro/libretro-common/include/array/rhmap.h create mode 100644 src/libretro/libretro-common/include/audio/audio_mix.h create mode 100644 src/libretro/libretro-common/include/audio/audio_mixer.h create mode 100644 src/libretro/libretro-common/include/audio/audio_resampler.h create mode 100644 src/libretro/libretro-common/include/audio/conversion/dual_mono.h create mode 100644 src/libretro/libretro-common/include/audio/conversion/float_to_s16.h create mode 100644 src/libretro/libretro-common/include/audio/conversion/s16_to_float.h create mode 100644 src/libretro/libretro-common/include/audio/dsp_filter.h create mode 100644 src/libretro/libretro-common/include/boolean.h create mode 100644 src/libretro/libretro-common/include/cdrom/cdrom.h create mode 100644 src/libretro/libretro-common/include/clamping.h create mode 100644 src/libretro/libretro-common/include/compat/apple_compat.h create mode 100644 src/libretro/libretro-common/include/compat/fnmatch.h create mode 100644 src/libretro/libretro-common/include/compat/fopen_utf8.h create mode 100644 src/libretro/libretro-common/include/compat/getopt.h create mode 100644 src/libretro/libretro-common/include/compat/ifaddrs.h create mode 100644 src/libretro/libretro-common/include/compat/intrinsics.h create mode 100644 src/libretro/libretro-common/include/compat/msvc.h create mode 100644 src/libretro/libretro-common/include/compat/msvc/stdint.h create mode 100644 src/libretro/libretro-common/include/compat/posix_string.h create mode 100644 src/libretro/libretro-common/include/compat/strcasestr.h create mode 100644 src/libretro/libretro-common/include/compat/strl.h create mode 100644 src/libretro/libretro-common/include/compat/zconf.h create mode 100644 src/libretro/libretro-common/include/compat/zconf.h.in create mode 100644 src/libretro/libretro-common/include/compat/zlib.h create mode 100644 src/libretro/libretro-common/include/compat/zlib/zconf.h create mode 100644 src/libretro/libretro-common/include/compat/zlib/zconf.h.in create mode 100644 src/libretro/libretro-common/include/compat/zlib/zlib.h create mode 100644 src/libretro/libretro-common/include/compat/zlib/zutil.h create mode 100644 src/libretro/libretro-common/include/compat/zutil.h create mode 100644 src/libretro/libretro-common/include/defines/cocoa_defines.h create mode 100644 src/libretro/libretro-common/include/defines/d3d_defines.h create mode 100644 src/libretro/libretro-common/include/defines/gx_defines.h create mode 100644 src/libretro/libretro-common/include/defines/ps3_defines.h create mode 100644 src/libretro/libretro-common/include/defines/ps4_defines.h create mode 100644 src/libretro/libretro-common/include/defines/psp_defines.h create mode 100644 src/libretro/libretro-common/include/dynamic/dylib.h create mode 100644 src/libretro/libretro-common/include/encodings/base64.h create mode 100644 src/libretro/libretro-common/include/encodings/crc32.h create mode 100644 src/libretro/libretro-common/include/encodings/utf.h create mode 100644 src/libretro/libretro-common/include/encodings/win32.h create mode 100644 src/libretro/libretro-common/include/fastcpy.h create mode 100644 src/libretro/libretro-common/include/features/features_cpu.h create mode 100644 src/libretro/libretro-common/include/file/archive_file.h create mode 100644 src/libretro/libretro-common/include/file/config_file.h create mode 100644 src/libretro/libretro-common/include/file/config_file_userdata.h create mode 100644 src/libretro/libretro-common/include/file/file_path.h create mode 100644 src/libretro/libretro-common/include/file/nbio.h create mode 100644 src/libretro/libretro-common/include/filters.h create mode 100644 src/libretro/libretro-common/include/formats/cdfs.h create mode 100644 src/libretro/libretro-common/include/formats/image.h create mode 100644 src/libretro/libretro-common/include/formats/logiqx_dat.h create mode 100644 src/libretro/libretro-common/include/formats/m3u_file.h create mode 100644 src/libretro/libretro-common/include/formats/rbmp.h create mode 100644 src/libretro/libretro-common/include/formats/rjpeg.h create mode 100644 src/libretro/libretro-common/include/formats/rjson.h create mode 100644 src/libretro/libretro-common/include/formats/rjson_helpers.h create mode 100644 src/libretro/libretro-common/include/formats/rpng.h create mode 100644 src/libretro/libretro-common/include/formats/rtga.h create mode 100644 src/libretro/libretro-common/include/formats/rwav.h create mode 100644 src/libretro/libretro-common/include/formats/rxml.h create mode 100644 src/libretro/libretro-common/include/gfx/gl_capabilities.h create mode 100644 src/libretro/libretro-common/include/gfx/math/matrix_3x3.h create mode 100644 src/libretro/libretro-common/include/gfx/math/matrix_4x4.h create mode 100644 src/libretro/libretro-common/include/gfx/math/vector_2.h create mode 100644 src/libretro/libretro-common/include/gfx/math/vector_3.h create mode 100644 src/libretro/libretro-common/include/gfx/math/vector_4.h create mode 100644 src/libretro/libretro-common/include/gfx/scaler/filter.h create mode 100644 src/libretro/libretro-common/include/gfx/scaler/pixconv.h create mode 100644 src/libretro/libretro-common/include/gfx/scaler/scaler.h create mode 100644 src/libretro/libretro-common/include/gfx/scaler/scaler_int.h create mode 100644 src/libretro/libretro-common/include/gfx/video_frame.h create mode 100644 src/libretro/libretro-common/include/glsm/glsm.h create mode 100644 src/libretro/libretro-common/include/glsm/glsmsym.h create mode 100644 src/libretro/libretro-common/include/glsym/glsym.h create mode 100644 src/libretro/libretro-common/include/glsym/glsym_es2.h create mode 100644 src/libretro/libretro-common/include/glsym/glsym_es3.h create mode 100644 src/libretro/libretro-common/include/glsym/glsym_gl.h create mode 100644 src/libretro/libretro-common/include/glsym/rglgen.h create mode 100644 src/libretro/libretro-common/include/glsym/rglgen_headers.h create mode 100644 src/libretro/libretro-common/include/glsym/rglgen_private_headers.h create mode 100644 src/libretro/libretro-common/include/glsym/switch/nx_gl.h create mode 100644 src/libretro/libretro-common/include/glsym/switch/nx_glsym.h create mode 100644 src/libretro/libretro-common/include/libchdr/bitstream.h create mode 100644 src/libretro/libretro-common/include/libchdr/cdrom.h create mode 100644 src/libretro/libretro-common/include/libchdr/chd.h create mode 100644 src/libretro/libretro-common/include/libchdr/coretypes.h create mode 100644 src/libretro/libretro-common/include/libchdr/flac.h create mode 100644 src/libretro/libretro-common/include/libchdr/huffman.h create mode 100644 src/libretro/libretro-common/include/libchdr/libchdr_zlib.h create mode 100644 src/libretro/libretro-common/include/libchdr/lzma.h create mode 100644 src/libretro/libretro-common/include/libchdr/minmax.h create mode 100644 src/libretro/libretro-common/include/libco.h create mode 100644 src/libretro/libretro-common/include/libretro.h create mode 100644 src/libretro/libretro-common/include/libretro_d3d.h create mode 100644 src/libretro/libretro-common/include/libretro_dspfilter.h create mode 100644 src/libretro/libretro-common/include/libretro_gskit_ps2.h create mode 100644 src/libretro/libretro-common/include/libretro_vulkan.h create mode 100644 src/libretro/libretro-common/include/lists/dir_list.h create mode 100644 src/libretro/libretro-common/include/lists/file_list.h create mode 100644 src/libretro/libretro-common/include/lists/linked_list.h create mode 100644 src/libretro/libretro-common/include/lists/nested_list.h create mode 100644 src/libretro/libretro-common/include/lists/string_list.h create mode 100644 src/libretro/libretro-common/include/lrc_hash.h create mode 100644 src/libretro/libretro-common/include/math/complex.h create mode 100644 src/libretro/libretro-common/include/math/float_minmax.h create mode 100644 src/libretro/libretro-common/include/math/fxp.h create mode 100644 src/libretro/libretro-common/include/media/media_detect_cd.h create mode 100644 src/libretro/libretro-common/include/memalign.h create mode 100644 src/libretro/libretro-common/include/memmap.h create mode 100644 src/libretro/libretro-common/include/net/net_compat.h create mode 100644 src/libretro/libretro-common/include/net/net_http.h create mode 100644 src/libretro/libretro-common/include/net/net_http_parse.h create mode 100644 src/libretro/libretro-common/include/net/net_ifinfo.h create mode 100644 src/libretro/libretro-common/include/net/net_socket.h create mode 100644 src/libretro/libretro-common/include/net/net_socket_ssl.h create mode 100644 src/libretro/libretro-common/include/playlists/label_sanitization.h create mode 100644 src/libretro/libretro-common/include/queues/fifo_queue.h create mode 100644 src/libretro/libretro-common/include/queues/generic_queue.h create mode 100644 src/libretro/libretro-common/include/queues/message_queue.h create mode 100644 src/libretro/libretro-common/include/queues/task_queue.h create mode 100644 src/libretro/libretro-common/include/retro_assert.h create mode 100644 src/libretro/libretro-common/include/retro_common.h create mode 100644 src/libretro/libretro-common/include/retro_common_api.h create mode 100644 src/libretro/libretro-common/include/retro_dirent.h create mode 100644 src/libretro/libretro-common/include/retro_endianness.h create mode 100644 src/libretro/libretro-common/include/retro_environment.h create mode 100644 src/libretro/libretro-common/include/retro_inline.h create mode 100644 src/libretro/libretro-common/include/retro_math.h create mode 100644 src/libretro/libretro-common/include/retro_miscellaneous.h create mode 100644 src/libretro/libretro-common/include/retro_stat.h create mode 100644 src/libretro/libretro-common/include/retro_timers.h create mode 100644 src/libretro/libretro-common/include/rthreads/async_job.h create mode 100644 src/libretro/libretro-common/include/rthreads/rthreads.h create mode 100644 src/libretro/libretro-common/include/rthreads/tpool.h create mode 100644 src/libretro/libretro-common/include/streams/chd_stream.h create mode 100644 src/libretro/libretro-common/include/streams/file_stream.h create mode 100644 src/libretro/libretro-common/include/streams/file_stream_transforms.h create mode 100644 src/libretro/libretro-common/include/streams/interface_stream.h create mode 100644 src/libretro/libretro-common/include/streams/memory_stream.h create mode 100644 src/libretro/libretro-common/include/streams/network_stream.h create mode 100644 src/libretro/libretro-common/include/streams/rzip_stream.h create mode 100644 src/libretro/libretro-common/include/streams/stdin_stream.h create mode 100644 src/libretro/libretro-common/include/streams/trans_stream.h create mode 100644 src/libretro/libretro-common/include/string/stdstring.h create mode 100644 src/libretro/libretro-common/include/time/rtime.h create mode 100644 src/libretro/libretro-common/include/utils/md5.h create mode 100644 src/libretro/libretro-common/include/vfs/vfs.h create mode 100644 src/libretro/libretro-common/include/vfs/vfs_implementation.h create mode 100644 src/libretro/libretro-common/include/vfs/vfs_implementation_cdrom.h create mode 100644 src/libretro/libretro-common/include/vulkan/vulkan_symbol_wrapper.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ccc0953a..e02f6d496 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -628,17 +628,44 @@ elseif(PLATFORM STREQUAL "libretro") # bzip2 needs -fPIC for linking into shared library set_target_properties(bzip2 PROPERTIES POSITION_INDEPENDENT_CODE ON) - # SW renderer, image decoder, stb image loader + if(ENABLE_SW_RENDERER) + target_sources(butterscotch PRIVATE + src/sw/sw_renderer.c + src/desktop/stb_impl.c + ) + target_include_directories(butterscotch PRIVATE + ${CMAKE_SOURCE_DIR}/src/sw + ) + else() + target_sources(butterscotch PRIVATE + src/gl/gl_renderer.c + src/gl_common/gl_common.c + src/libretro/libretro-common/glsym/glsym_es3.c + src/libretro/libretro-common/glsm/glsm.c + src/libretro/libretro-common/glsym/rglgen.c + ) + target_include_directories(butterscotch PRIVATE + ${CMAKE_SOURCE_DIR}/src/gl + ${CMAKE_SOURCE_DIR}/src/gl_common + ) + target_compile_definitions(butterscotch PRIVATE HAVE_OPENGLES HAVE_OPENGLES3) + add_compile_definitions(ENABLE_GLES) + + find_library(GLES2_LIB GLESv2) + target_link_libraries(butterscotch PRIVATE ${GLES2_LIB}) + + target_compile_definitions(butterscotch PRIVATE GLclampd=GLclampf) + endif() target_sources(butterscotch PRIVATE - src/sw/sw_renderer.c src/image/image_decoder.c src/desktop/stb_impl.c ) + target_include_directories(butterscotch PRIVATE - ${CMAKE_SOURCE_DIR}/src/sw ${CMAKE_SOURCE_DIR}/src/image ${CMAKE_SOURCE_DIR}/src/desktop ${CMAKE_SOURCE_DIR}/src/libretro + ${CMAKE_SOURCE_DIR}/src/libretro/libretro-common/include vendor/stb/image vendor/stb/vorbis ) @@ -657,7 +684,12 @@ elseif(PLATFORM STREQUAL "libretro") # Libraries find_library(DL_LIB dl) + find_library(ATOMIC_LIB atomic) + target_link_libraries(butterscotch PRIVATE bzip2 stb_ds sha1 m ${DL_LIB} ${AUDIO_LIBRARIES}) + if(ATOMIC_LIB) + target_link_libraries(butterscotch PRIVATE ${ATOMIC_LIB}) + endif() target_compile_definitions(butterscotch PRIVATE _GNU_SOURCE diff --git a/src/libretro/glad/glad.h b/src/libretro/glad/glad.h new file mode 100644 index 000000000..ec2485b44 --- /dev/null +++ b/src/libretro/glad/glad.h @@ -0,0 +1 @@ +#include diff --git a/src/libretro/libretro-common/glsm/glsm.c b/src/libretro/libretro-common/glsm/glsm.c new file mode 100644 index 000000000..388914508 --- /dev/null +++ b/src/libretro/libretro-common/glsm/glsm.c @@ -0,0 +1,2897 @@ +/* Copyright (C) 2010-2018 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this libretro SDK code part (glsm). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * 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: + * + * 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, + * 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. + */ + +#include +#include +#include +#include + +#ifndef GL_DEPTH_CLAMP +#define GL_DEPTH_CLAMP 0x864F +#define GL_RASTERIZER_DISCARD 0x8C89 +#define GL_SAMPLE_MASK 0x8E51 +#endif + +#if 0 +extern retro_log_printf_t log_cb; +#define GLSM_DEBUG +#endif + +struct gl_cached_state +{ + struct + { + GLuint *ids; + } bind_textures; + + struct + { + bool used[MAX_ATTRIB]; + GLint size[MAX_ATTRIB]; + GLenum type[MAX_ATTRIB]; + GLboolean normalized[MAX_ATTRIB]; + GLsizei stride[MAX_ATTRIB]; + const GLvoid *pointer[MAX_ATTRIB]; + GLuint buffer[MAX_ATTRIB]; + } attrib_pointer; + +#ifndef HAVE_OPENGLES + GLenum colorlogicop; +#endif + + struct + { + bool enabled[MAX_ATTRIB]; + } vertex_attrib_pointer; + + struct + { + GLenum pname; + GLint param; + } pixelstore_i; + + struct + { + GLuint r; + GLuint g; + GLuint b; + GLuint a; + } clear_color; + + struct + { + bool used; + GLint x; + GLint y; + GLsizei w; + GLsizei h; + } scissor; + + struct + { + GLint x; + GLint y; + GLsizei w; + GLsizei h; + } viewport; + + struct + { + bool used; + GLenum sfactor; + GLenum dfactor; + } blendfunc; + + struct + { + bool used; + GLenum srcRGB; + GLenum dstRGB; + GLenum srcAlpha; + GLenum dstAlpha; + } blendfunc_separate; + + struct + { + bool used; + GLboolean red; + GLboolean green; + GLboolean blue; + GLboolean alpha; + } colormask; + + struct + { + bool used; + GLdouble depth; + } cleardepth; + + struct + { + bool used; + GLenum func; + } depthfunc; + + struct + { + bool used; + GLclampd zNear; + GLclampd zFar; + } depthrange; + + struct + { + bool used; + GLfloat factor; + GLfloat units; + } polygonoffset; + + struct + { + bool used; + GLenum func; + GLint ref; + GLuint mask; + } stencilfunc; + + struct + { + bool used; + GLenum sfail; + GLenum dpfail; + GLenum dppass; + } stencilop; + + struct + { + bool used; + GLenum mode; + } frontface; + + struct + { + bool used; + GLenum mode; + } cullface; + + struct + { + bool used; + GLuint mask; + } stencilmask; + + struct + { + bool used; + GLboolean mask; + } depthmask; + + struct + { + GLenum mode; + } readbuffer; + + GLuint vao; + GLuint framebuf; + GLuint array_buffer; + GLuint program; + GLenum active_texture; + int cap_state[SGL_CAP_MAX]; + int cap_translate[SGL_CAP_MAX]; +}; + +static GLuint default_framebuffer; +static GLint glsm_max_textures; +struct retro_hw_render_callback hw_render; +static struct gl_cached_state gl_state; + +/* GL wrapper-side */ + +/* + * + * Core in: + * OpenGL : 1.0 + */ +GLenum rglGetError(void) +{ + return glGetError(); +} + +/* + * + * Core in: + * OpenGL : 3.2 + * OpenGLES : N/A + */ + +void rglProvokingVertex( GLenum provokeMode) +{ +#if defined(HAVE_OPENGL) + glProvokingVertex(provokeMode); +#endif +} + +/* + * + * Core in: + * OpenGL : 3.2 + * OpenGLES : 3.0 + */ +void rglGetInteger64v( GLenum pname, int64_t *data) +{ +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glGetInteger64v(pname, (GLint64*)data); +#endif +} + +/* + * + * Core in: + * OpenGL : 3.2 + * OpenGLES : 3.0 + */ +void rglSamplerParameteri( GLuint sampler, + GLenum pname, + GLint param) +{ +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glSamplerParameteri(sampler, pname, param); +#endif +} + +void rglGenSamplers( GLsizei n, + GLuint *samplers) +{ +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glGenSamplers(n, samplers); +#endif +} + +void rglBindSampler( GLuint unit, + GLuint sampler) +{ +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glBindSampler(unit, sampler); +#endif +} + +/* + * + * Core in: + * OpenGL : 1.0 + */ +void rglClear(GLbitfield mask) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glClear.\n"); +#endif + glClear(mask); +} + +/* + * + * Core in: + * OpenGL : 2.0 + */ +void rglValidateProgram(GLuint program) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glValidateProgram.\n"); +#endif + glValidateProgram(program); +} + +/* + * + * Core in: + * OpenGL : 1.0 + * OpenGLES : N/A + */ +void rglPolygonMode(GLenum face, GLenum mode) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glPolygonMode.\n"); +#endif +#ifndef HAVE_OPENGLES + glPolygonMode(face, mode); +#endif +} + +void rglTexSubImage2D( + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const GLvoid * pixels) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glTexSubImage2D.\n"); +#endif + glTexSubImage2D(target, level, xoffset, yoffset, + width, height, format, type, pixels); +} + +void rglGetBufferSubData( GLenum target, + GLintptr offset, + GLsizeiptr size, + GLvoid * data) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGetBufferSubData.\n"); +#endif +#if defined(HAVE_OPENGL) + glGetBufferSubData(target, offset, size, data); +#endif +} + +/* + * + * Core in: + * OpenGL : 1.0 + */ +void rglLineWidth(GLfloat width) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glLineWidth.\n"); +#endif + glLineWidth(width); +} + +/* + * Category: FBO + * + * Core in: + * OpenGL : 3.0 + * OpenGLES : 3.0 + */ +void rglBlitFramebuffer( + GLint srcX0, GLint srcY0, + GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, + GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBlitFramebuffer.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1, + mask, filter); +#endif +} + +/* + * + * Core in: + * OpenGLES : 3.0 + */ +void rglReadBuffer(GLenum mode) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glReadBuffer.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glReadBuffer(mode); + gl_state.readbuffer.mode = mode; +#endif +} + +/* + * + * Core in: + * OpenGLES : 2.0 + */ +void rglClearDepth(GLdouble depth) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glClearDepth.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); +#ifdef HAVE_OPENGLES + glClearDepthf(depth); +#else + glClearDepth(depth); +#endif + gl_state.cleardepth.used = true; + gl_state.cleardepth.depth = depth; +} + +/* + * + * Core in: + * OpenGLES : 2.0 + */ +void rglPixelStorei(GLenum pname, GLint param) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glPixelStorei.\n"); +#endif + glPixelStorei(pname, param); + gl_state.pixelstore_i.pname = pname; + gl_state.pixelstore_i.param = param; +} + +/* + * + * Core in: + * OpenGLES : 2.0 + */ +void rglDepthRange(GLclampd zNear, GLclampd zFar) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDepthRange.\n"); +#endif +#ifdef HAVE_OPENGLES + glDepthRangef(zNear, zFar); +#else + glDepthRange(zNear, zFar); +#endif + gl_state.depthrange.used = true; + gl_state.depthrange.zNear = zNear; + gl_state.depthrange.zFar = zFar; +} + +/* + * + * Core in: + * OpenGLES : 2.0 + */ +void rglFrontFace(GLenum mode) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glFrontFace.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + glFrontFace(mode); + gl_state.frontface.used = true; + gl_state.frontface.mode = mode; +} + +/* + * + * Core in: + * OpenGLES : 2.0 + */ +void rglDepthFunc(GLenum func) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDepthFunc.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + gl_state.depthfunc.used = true; + gl_state.depthfunc.func = func; + glDepthFunc(func); +} + +/* + * + * Core in: + * OpenGLES : 2.0 + */ +void rglColorMask(GLboolean red, GLboolean green, + GLboolean blue, GLboolean alpha) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glColorMask.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + glColorMask(red, green, blue, alpha); + gl_state.colormask.red = red; + gl_state.colormask.green = green; + gl_state.colormask.blue = blue; + gl_state.colormask.alpha = alpha; + gl_state.colormask.used = true; +} + +/* + * + * Core in: + * OpenGLES : 2.0 + */ +void rglCullFace(GLenum mode) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glCullFace.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + glCullFace(mode); + gl_state.cullface.used = true; + gl_state.cullface.mode = mode; +} + +/* + * + * Core in: + * OpenGLES : 2.0 + */ +void rglStencilOp(GLenum sfail, GLenum dpfail, GLenum dppass) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glStencilOp.\n"); +#endif + glStencilOp(sfail, dpfail, dppass); + gl_state.stencilop.used = true; + gl_state.stencilop.sfail = sfail; + gl_state.stencilop.dpfail = dpfail; + gl_state.stencilop.dppass = dppass; +} + +/* + * + * Core in: + * OpenGLES : 2.0 + */ +void rglStencilFunc(GLenum func, GLint ref, GLuint mask) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glStencilFunc.\n"); +#endif + glStencilFunc(func, ref, mask); + gl_state.stencilfunc.used = true; + gl_state.stencilfunc.func = func; + gl_state.stencilfunc.ref = ref; + gl_state.stencilfunc.mask = mask; +} + +/* + * + * Core in: + * OpenGL : 1.0 + */ +GLboolean rglIsEnabled(GLenum cap) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glIsEnabled.\n"); +#endif + return gl_state.cap_state[cap] ? GL_TRUE : GL_FALSE; +} + +/* + * + * Core in: + * OpenGL : 1.0 + */ +void rglClearColor(GLclampf red, GLclampf green, + GLclampf blue, GLclampf alpha) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glClearColor.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + glClearColor(red, green, blue, alpha); + gl_state.clear_color.r = red; + gl_state.clear_color.g = green; + gl_state.clear_color.b = blue; + gl_state.clear_color.a = alpha; +} + +/* + * + * Core in: + * OpenGLES : 2.0 (maybe earlier?) + */ +void rglScissor(GLint x, GLint y, GLsizei width, GLsizei height) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glScissor.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + glScissor(x, y, width, height); + gl_state.scissor.used = true; + gl_state.scissor.x = x; + gl_state.scissor.y = y; + gl_state.scissor.w = width; + gl_state.scissor.h = height; +} + +/* + * + * Core in: + * OpenGL : 1.0 + */ +void rglViewport(GLint x, GLint y, GLsizei width, GLsizei height) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glViewport.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + glViewport(x, y, width, height); + gl_state.viewport.x = x; + gl_state.viewport.y = y; + gl_state.viewport.w = width; + gl_state.viewport.h = height; +} + +void rglBlendFunc(GLenum sfactor, GLenum dfactor) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBlendFunc.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + gl_state.blendfunc.used = true; + gl_state.blendfunc.sfactor = sfactor; + gl_state.blendfunc.dfactor = dfactor; + glBlendFunc(sfactor, dfactor); +} + +/* + * Category: Blending + * + * Core in: + * OpenGL : 1.4 + */ +void rglBlendFuncSeparate(GLenum sfactor, GLenum dfactor) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBlendFuncSeparate.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + gl_state.blendfunc_separate.used = true; + gl_state.blendfunc_separate.srcRGB = sfactor; + gl_state.blendfunc_separate.dstRGB = dfactor; + gl_state.blendfunc_separate.srcAlpha = sfactor; + gl_state.blendfunc_separate.dstAlpha = dfactor; + glBlendFunc(sfactor, dfactor); +} + +/* + * Category: Textures + * + * Core in: + * OpenGL : 1.3 + */ +void rglActiveTexture(GLenum texture) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glActiveTexture.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + glActiveTexture(texture); + gl_state.active_texture = texture - GL_TEXTURE0; +} + +/* + * + * Core in: + * OpenGL : 1.1 + */ +void rglBindTexture(GLenum target, GLuint texture) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBindTexture.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + glBindTexture(target, texture); + gl_state.bind_textures.ids[gl_state.active_texture] = texture; +} + +/* + * + * Core in: + * OpenGL : 1.0 + */ +void rglDisable(GLenum cap) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDisable.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + glDisable(gl_state.cap_translate[cap]); + gl_state.cap_state[cap] = 0; +} + +/* + * + * Core in: + * OpenGL : 1.0 + */ +void rglEnable(GLenum cap) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glEnable.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + glEnable(gl_state.cap_translate[cap]); + gl_state.cap_state[cap] = 1; +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglUseProgram(GLuint program) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUseProgram.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + gl_state.program = program; + glUseProgram(program); +} + +/* + * + * Core in: + * OpenGL : 1.0 + */ +void rglDepthMask(GLboolean flag) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDepthMask.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + glDepthMask(flag); + gl_state.depthmask.used = true; + gl_state.depthmask.mask = flag; +} + +/* + * + * Core in: + * OpenGL : 1.0 + */ +void rglStencilMask(GLenum mask) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glStencilMask.\n"); +#endif + glStencilMask(mask); + gl_state.stencilmask.used = true; + gl_state.stencilmask.mask = mask; +} + +/* + * + * Core in: + * OpenGL : 1.5 + */ +void rglBufferData(GLenum target, GLsizeiptr size, + const GLvoid *data, GLenum usage) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBufferData.\n"); +#endif + glBufferData(target, size, data, usage); +} + +/* + * + * Core in: + * OpenGL : 1.5 + */ +void rglBufferSubData(GLenum target, GLintptr offset, + GLsizeiptr size, const GLvoid *data) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBufferSubData.\n"); +#endif + glBufferSubData(target, offset, size, data); +} + +/* + * + * Core in: + * OpenGL : 1.5 + */ +void rglBindBuffer(GLenum target, GLuint buffer) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBindBuffer.\n"); +#endif + if (target == GL_ARRAY_BUFFER) + gl_state.array_buffer = buffer; + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + glBindBuffer(target, buffer); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglLinkProgram(GLuint program) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glLinkProgram.\n"); +#endif + glLinkProgram(program); +} + +/* + * Category: FBO + * + * Core in: + * OpenGL : 3.0 + * OpenGLES : 2.0 + */ +void rglFramebufferTexture2D(GLenum target, GLenum attachment, + GLenum textarget, GLuint texture, GLint level) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glFramebufferTexture2D.\n"); +#endif + glFramebufferTexture2D(target, attachment, textarget, texture, level); +} + +/* + * Category: FBO + * + * Core in: + * OpenGL : 3.0 + * OpenGLES : 3.2 + */ +void rglFramebufferTexture(GLenum target, GLenum attachment, + GLuint texture, GLint level) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glFramebufferTexture.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3_2) + glFramebufferTexture(target, attachment, texture, level); +#endif +} + +/* + * + * Core in: + * OpenGL : 1.1 + */ +void rglDrawArrays(GLenum mode, GLint first, GLsizei count) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDrawArrays.\n"); +#endif + glDrawArrays(mode, first, count); +} + +/* + * + * Core in: + * OpenGL : 1.1 + */ +void rglDrawElements(GLenum mode, GLsizei count, GLenum type, + const GLvoid * indices) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDrawElements.\n"); +#endif + glDrawElements(mode, count, type, indices); +} + +void rglCompressedTexImage2D(GLenum target, GLint level, + GLenum internalformat, GLsizei width, GLsizei height, + GLint border, GLsizei imageSize, const GLvoid *data) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glCompressedTexImage2D.\n"); +#endif + glCompressedTexImage2D(target, level, internalformat, + width, height, border, imageSize, data); +} + +void rglDeleteFramebuffers(GLsizei n, const GLuint *framebuffers) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDeleteFramebuffers.\n"); +#endif + glDeleteFramebuffers(n, framebuffers); +} + +void rglDeleteTextures(GLsizei n, const GLuint *textures) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDeleteTextures.\n"); +#endif + glDeleteTextures(n, textures); +} + +/* + * + * Core in: + * OpenGLES : 2.0 + */ +void rglRenderbufferStorage(GLenum target, GLenum internalFormat, + GLsizei width, GLsizei height) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glRenderbufferStorage.\n"); +#endif + glRenderbufferStorage(target, internalFormat, width, height); +} + +/* + * + * Core in: + * + * OpenGL : 3.0 + * OpenGLES : 2.0 + */ +void rglBindRenderbuffer(GLenum target, GLuint renderbuffer) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBindRenderbuffer.\n"); +#endif + glBindRenderbuffer(target, renderbuffer); +} + +/* + * + * Core in: + * + * OpenGLES : 2.0 + */ +void rglDeleteRenderbuffers(GLsizei n, GLuint *renderbuffers) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDeleteRenderbuffers.\n"); +#endif + glDeleteRenderbuffers(n, renderbuffers); +} + +/* + * + * Core in: + * + * OpenGL : 3.0 + * OpenGLES : 2.0 + */ +void rglGenRenderbuffers(GLsizei n, GLuint *renderbuffers) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGenRenderbuffers.\n"); +#endif + glGenRenderbuffers(n, renderbuffers); +} + +/* + * + * Core in: + * + * OpenGL : 3.0 + * OpenGLES : 2.0 + */ +void rglGenerateMipmap(GLenum target) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGenerateMipmap.\n"); +#endif + glGenerateMipmap(target); +} + +/* + * Category: FBO + * + * Core in: + * OpenGL : 3.0 + */ +GLenum rglCheckFramebufferStatus(GLenum target) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glCheckFramebufferStatus.\n"); +#endif + return glCheckFramebufferStatus(target); +} + +/* + * Category: FBO + * + * Core in: + * OpenGL : 3.0 + * OpenGLES : 2.0 + */ +void rglFramebufferRenderbuffer(GLenum target, GLenum attachment, + GLenum renderbuffertarget, GLuint renderbuffer) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glFramebufferRenderbuffer.\n"); +#endif + glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 3.0 + */ +void rglBindFragDataLocation(GLuint program, GLuint colorNumber, + const char * name) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBindFragDataLocation.\n"); +#endif +#if !defined(HAVE_OPENGLES2) && !defined(HAVE_OPENGLES3) + glBindFragDataLocation(program, colorNumber, name); +#endif +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglGetProgramiv(GLuint shader, GLenum pname, GLint *params) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGetProgramiv.\n"); +#endif + glGetProgramiv(shader, pname, params); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 4.1 + * OpenGLES : 3.0 + */ +void rglProgramParameteri( GLuint program, + GLenum pname, + GLint value) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glProgramParameteri.\n"); +#endif +#if !defined(HAVE_OPENGLES) || defined(HAVE_OPENGLES) && (defined(HAVE_OPENGLES3) || defined(HAVE_OPENGLES_3_1)) + glProgramParameteri(program, pname, value); +#else + printf("WARNING! Not implemented.\n"); +#endif +} + +/* + * + * Core in: + * OpenGL : 2.0 + */ +void rglGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, + GLsizei *length, GLint *size, GLenum *type, GLchar *name) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGetActiveUniform.\n"); +#endif + glGetActiveUniform(program, index, bufsize, length, size, type, name); +} + +void rglGenQueries( GLsizei n, + GLuint * ids) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGenQueries.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glGenQueries(n, ids); +#endif +} + +void rglGetQueryObjectuiv( GLuint id, + GLenum pname, + GLuint * params) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGetQueryObjectuiv.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glGetQueryObjectuiv(id, pname, params); +#endif +} + +void rglDeleteQueries( GLsizei n, + const GLuint * ids) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDeleteQueries.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glDeleteQueries(n, ids); +#endif +} + +void rglBeginQuery( GLenum target, + GLuint id) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBeginQuery.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glBeginQuery(target, id); +#endif +} + +void rglEndQuery( GLenum target) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glEndQuery.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glEndQuery(target); +#endif +} + +/* + * Category: UBO + * + * Core in: + * + * OpenGL : 2.0 + * OpenGLES : 3.0 + */ +void rglGetActiveUniformBlockiv(GLuint program, + GLuint uniformBlockIndex, + GLenum pname, + GLint *params) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGetActiveUniformBlockiv.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glGetActiveUniformBlockiv(program, uniformBlockIndex, + pname, params); +#else + printf("WARNING! Not implemented.\n"); +#endif +} + +/* + * + * Core in: + * + * OpenGLES : 3.0 + */ +void rglGetActiveUniformsiv( GLuint program, + GLsizei uniformCount, + const GLuint *uniformIndices, + GLenum pname, + GLint *params) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGetActiveUniformsiv.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glGetActiveUniformsiv(program, uniformCount, + uniformIndices, pname, params); +#else + printf("WARNING! Not implemented.\n"); +#endif +} + +/* + * + * Core in: + * + * OpenGLES : 3.0 + */ +void rglGetUniformIndices(GLuint program, + GLsizei uniformCount, + const GLchar **uniformNames, + GLuint *uniformIndices) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGetUniformIndices.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glGetUniformIndices(program, uniformCount, + uniformNames, uniformIndices); +#else + printf("WARNING! Not implemented.\n"); +#endif +} + +/* + * Category: UBO + * + * Core in: + * + * OpenGLES : 3.0 + */ +void rglBindBufferBase( GLenum target, + GLuint index, + GLuint buffer) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBindBufferBase.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glBindBufferBase(target, index, buffer); +#else + printf("WARNING! Not implemented.\n"); +#endif +} + +/* + * + * Category: UBO + * + * Core in: + * + * OpenGLES : 3.0 + */ +GLuint rglGetUniformBlockIndex( GLuint program, + const GLchar *uniformBlockName) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGetUniformBlockIndex.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + return glGetUniformBlockIndex(program, uniformBlockName); +#else + printf("WARNING! Not implemented.\n"); + return 0; +#endif +} + +/* + * Category: UBO + * + * Core in: + * + * OpenGLES : 3.0 + */ +void rglUniformBlockBinding( GLuint program, + GLuint uniformBlockIndex, + GLuint uniformBlockBinding) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniformBlockBinding.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glUniformBlockBinding(program, uniformBlockIndex, + uniformBlockBinding); +#else + printf("WARNING! Not implemented.\n"); +#endif +} + +/* + * + * Core in: + * OpenGL : 2.0 + * OpenGLES : 3.0 + */ +void rglUniform1ui(GLint location, GLuint v) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform1ui.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glUniform1ui(location ,v); +#endif +} + +/* + * + * Core in: + * OpenGL : 2.0 + * OpenGLES : 3.0 + */ +void rglUniform2ui(GLint location, GLuint v0, GLuint v1) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform2ui.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glUniform2ui(location, v0, v1); +#endif +} + +/* + * + * Core in: + * OpenGL : 2.0 + * OpenGLES : 3.0 + */ +void rglUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform3ui.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glUniform3ui(location, v0, v1, v2); +#endif +} + +/* + * + * Core in: + * OpenGL : 2.0 + * OpenGLES : 3.0 + */ +void rglUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform4ui.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glUniform4ui(location, v0, v1, v2, v3); +#endif +} + +/* + * + * Core in: + * OpenGL : 2.0 + */ +void rglUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniformMatrix4fv.\n"); +#endif + glUniformMatrix4fv(location, count, transpose, value); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglDetachShader(GLuint program, GLuint shader) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDetachShader.\n"); +#endif + glDetachShader(program, shader); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglGetShaderiv(GLuint shader, GLenum pname, GLint *params) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGetShaderiv.\n"); +#endif + glGetShaderiv(shader, pname, params); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglAttachShader(GLuint program, GLuint shader) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glAttachShader.\n"); +#endif + glAttachShader(program, shader); +} + +/* + * + * Core in: + * OpenGL : 2.0 + */ +GLint rglGetAttribLocation(GLuint program, const GLchar *name) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGetAttribLocation.\n"); +#endif + return glGetAttribLocation(program, name); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglShaderSource(GLuint shader, GLsizei count, + const GLchar **string, const GLint *length) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glShaderSource.\n"); +#endif + return glShaderSource(shader, count, string, length); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglCompileShader(GLuint shader) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glCompileShader.\n"); +#endif + glCompileShader(shader); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +GLuint rglCreateProgram(void) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glCreateProgram.\n"); +#endif + return glCreateProgram(); +} + +/* + * + * Core in: + * OpenGL : 1.1 + */ +void rglGenTextures(GLsizei n, GLuint *textures) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGenTextures.\n"); +#endif + glGenTextures(n, textures); +} + +/* + * + * Core in: + * OpenGL : 2.0 + */ +void rglGetShaderInfoLog(GLuint shader, GLsizei maxLength, + GLsizei *length, GLchar *infoLog) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGetShaderInfoLog.\n"); +#endif + glGetShaderInfoLog(shader, maxLength, length, infoLog); +} + +/* + * + * Core in: + * OpenGL : 2.0 + */ +void rglGetProgramInfoLog(GLuint shader, GLsizei maxLength, + GLsizei *length, GLchar *infoLog) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGetProgramInfoLog.\n"); +#endif + glGetProgramInfoLog(shader, maxLength, length, infoLog); +} + +/* + * + * Core in: + * OpenGL : 2.0 + */ +GLboolean rglIsProgram(GLuint program) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glIsProgram.\n"); +#endif + return glIsProgram(program); +} + +void rglTexCoord2f(GLfloat s, GLfloat t) +{ +#ifdef HAVE_LEGACY_GL +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glTexCoord2f.\n"); +#endif + glTexCoord2f(s, t); +#endif +} + +/* + * Category: Generic vertex attributes + * + * Core in: + * OpenGL : 2.0 + * + */ +void rglDisableVertexAttribArray(GLuint index) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDisableVertexAttribArray.\n"); +#endif + gl_state.vertex_attrib_pointer.enabled[index] = 0; + glDisableVertexAttribArray(index); +} + +/* + * Category: Generic vertex attributes + * + * Core in: + * OpenGL : 2.0 + */ +void rglEnableVertexAttribArray(GLuint index) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glEnableVertexAttribArray.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + gl_state.vertex_attrib_pointer.enabled[index] = 1; + glEnableVertexAttribArray(index); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglVertexAttribIPointer( + GLuint index, + GLint size, + GLenum type, + GLsizei stride, + const GLvoid * pointer) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glVertexAttribIPointer.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glVertexAttribIPointer(index, size, type, stride, pointer); +#endif +} + +void rglVertexAttribLPointer( + GLuint index, + GLint size, + GLenum type, + GLsizei stride, + const GLvoid * pointer) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glVertexAttribLPointer.\n"); +#endif +#if defined(HAVE_OPENGL) + glVertexAttribLPointer(index, size, type, stride, pointer); +#endif +} + +/* + * Category: Generic vertex attributes + * + * Core in: + * OpenGL : 2.0 + */ +void rglVertexAttribPointer(GLuint name, GLint size, + GLenum type, GLboolean normalized, GLsizei stride, + const GLvoid* pointer) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glVertexAttribPointer.\n"); +#endif + gl_state.attrib_pointer.used[name] = 1; + gl_state.attrib_pointer.size[name] = size; + gl_state.attrib_pointer.type[name] = type; + gl_state.attrib_pointer.normalized[name] = normalized; + gl_state.attrib_pointer.stride[name] = stride; + gl_state.attrib_pointer.pointer[name] = pointer; + gl_state.attrib_pointer.buffer[name] = gl_state.array_buffer; + glVertexAttribPointer(name, size, type, normalized, stride, pointer); +} + +/* + * Category: Generic vertex attributes + * + * Core in: + * OpenGL : 2.0 + */ +void rglBindAttribLocation(GLuint program, GLuint index, const GLchar *name) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBindAttribLocation.\n"); +#endif + glBindAttribLocation(program, index, name); +} + +/* + * + * Core in: + * OpenGL : 2.0 + */ +void rglVertexAttrib4f(GLuint name, GLfloat x, GLfloat y, + GLfloat z, GLfloat w) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glVertexAttrib4f.\n"); +#endif + glVertexAttrib4f(name, x, y, z, w); +} + +/* + * + * Core in: + * OpenGL : 2.0 + */ +void rglVertexAttrib4fv(GLuint name, GLfloat* v) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glVertexAttrib4fv.\n"); +#endif + glVertexAttrib4fv(name, v); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +GLuint rglCreateShader(GLenum shaderType) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glCreateShader.\n"); +#endif + return glCreateShader(shaderType); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglDeleteProgram(GLuint program) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDeleteProgram.\n"); +#endif + glDeleteProgram(program); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglDeleteShader(GLuint shader) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDeleteShader.\n"); +#endif + glDeleteShader(shader); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +GLint rglGetUniformLocation(GLuint program, const GLchar *name) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGetUniformLocation.\n"); +#endif + return glGetUniformLocation(program, name); +} + +/* + * Category: VBO and PBO + * + * Core in: + * OpenGL : 1.5 + */ +void rglDeleteBuffers(GLsizei n, const GLuint *buffers) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDeleteBuffers.\n"); +#endif + glDeleteBuffers(n, buffers); +} + +/* + * Category: VBO and PBO + * + * Core in: + * OpenGL : 1.5 + */ +void rglGenBuffers(GLsizei n, GLuint *buffers) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGenBuffers.\n"); +#endif + glGenBuffers(n, buffers); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglUniform1f(GLint location, GLfloat v0) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform1f.\n"); +#endif + glUniform1f(location, v0); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglUniform1fv(GLint location, GLsizei count, const GLfloat *value) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform1fv.\n"); +#endif + glUniform1fv(location, count, value); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglUniform1iv(GLint location, GLsizei count, const GLint *value) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform1iv.\n"); +#endif + glUniform1iv(location, count, value); +} + +void rglClearBufferfv( GLenum buffer, + GLint drawBuffer, + const GLfloat * value) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glClearBufferfv.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3) + glClearBufferfv(buffer, drawBuffer, value); +#endif +} + +void rglTexBuffer(GLenum target, GLenum internalFormat, GLuint buffer) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glTexBuffer.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3_2) + glTexBuffer(target, internalFormat, buffer); +#endif +} + +/* + * + * Core in: + * OpenGL : 2.0 + * OpenGLES : 3.0 + */ +const GLubyte* rglGetStringi(GLenum name, GLuint index) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGetString.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3) + return glGetStringi(name, index); +#else + return NULL; +#endif +} + +void rglClearBufferfi( GLenum buffer, + GLint drawBuffer, + GLfloat depth, + GLint stencil) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glClearBufferfi.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3) + glClearBufferfi(buffer, drawBuffer, depth, stencil); +#endif +} + +/* + * + * Core in: + * OpenGL : 3.0 + * OpenGLES : 3.0 + */ +void rglRenderbufferStorageMultisample( GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glRenderbufferStorageMultisample.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3) + glRenderbufferStorageMultisample(target, samples, internalformat, width, height); +#endif +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglUniform1i(GLint location, GLint v0) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform1i.\n"); +#endif + glUniform1i(location, v0); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglUniform2f(GLint location, GLfloat v0, GLfloat v1) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform2f.\n"); +#endif + glUniform2f(location, v0, v1); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglUniform2i(GLint location, GLint v0, GLint v1) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform2i.\n"); +#endif + glUniform2i(location, v0, v1); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglUniform2fv(GLint location, GLsizei count, const GLfloat *value) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform2fv.\n"); +#endif + glUniform2fv(location, count, value); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform3f.\n"); +#endif + glUniform3f(location, v0, v1, v2); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglUniform3fv(GLint location, GLsizei count, const GLfloat *value) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform3fv.\n"); +#endif + glUniform3fv(location, count, value); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglUniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform4i.\n"); +#endif + glUniform4i(location, v0, v1, v2, v3); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform4f.\n"); +#endif + glUniform4f(location, v0, v1, v2, v3); +} + +/* + * Category: Shaders + * + * Core in: + * OpenGL : 2.0 + */ +void rglUniform4fv(GLint location, GLsizei count, const GLfloat *value) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform4fv.\n"); +#endif + glUniform4fv(location, count, value); +} + +/* + * + * Core in: + * OpenGL : 1.0 + */ +void rglPolygonOffset(GLfloat factor, GLfloat units) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glPolygonOffset.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + glPolygonOffset(factor, units); + gl_state.polygonoffset.used = true; + gl_state.polygonoffset.factor = factor; + gl_state.polygonoffset.units = units; +} + +/* + * Category: FBO + * + * Core in: + * OpenGL : 3.0 + */ +void rglGenFramebuffers(GLsizei n, GLuint *ids) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGenFramebuffers.\n"); +#endif + glGenFramebuffers(n, ids); +} + +/* + * Category: FBO + * + * Core in: + * OpenGL : 3.0 + */ +void rglBindFramebuffer(GLenum target, GLuint framebuffer) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBindFramebuffer.\n"); +#endif + glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL); + glBindFramebuffer(target, framebuffer); + gl_state.framebuf = framebuffer; +} + +/* + * Category: FBO + * + * Core in: + * OpenGL : 2.0 + * OpenGLES : 3.0 + */ +void rglDrawBuffers(GLsizei n, const GLenum *bufs) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDrawBuffers.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glDrawBuffers(n, bufs); +#endif +} + +/* + * Category: FBO + * + * Core in: + * OpenGL : 2.0 + * OpenGLES : 3.0 + */ +void *rglMapBufferRange( GLenum target, + GLintptr offset, + GLsizeiptr length, + GLbitfield access) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glMapBufferRange.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + return glMapBufferRange(target, offset, length, access); +#else + printf("WARNING! Not implemented.\n"); + return NULL; +#endif +} + +/* + * + * Core in: + * OpenGL : 4.3 + * OpenGLES : 3.1 + */ +void rglTexStorage2DMultisample(GLenum target, GLsizei samples, + GLenum internalformat, GLsizei width, GLsizei height, + GLboolean fixedsamplelocations) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glTexStorage2DMultisample.\n"); +#endif +#if defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3_1) + glTexStorage2DMultisample(target, samples, internalformat, + width, height, fixedsamplelocations); +#endif +} + +/* + * + * Core in: + * OpenGLES : 3.0 + */ +void rglTexStorage2D(GLenum target, GLsizei levels, GLenum internalFormat, + GLsizei width, GLsizei height) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glTexStorage2D.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glTexStorage2D(target, levels, internalFormat, width, height); +#endif +} +/* + * + * Core in: + * OpenGL : 3.2 + * OpenGLES : 3.2 + */ +void rglDrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, GLvoid *indices, GLint basevertex) +{ +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3_2) + glDrawRangeElementsBaseVertex(mode, start, end, count, type, indices, basevertex); +#endif +} + +/* + * + * Core in: + * OpenGL : 4.2 + * OpenGLES : 3.1 + */ +void rglMemoryBarrier( GLbitfield barriers) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glMemoryBarrier.\n"); +#endif +#if !defined(HAVE_OPENGLES) || defined(HAVE_OPENGLES3) && defined(HAVE_OPENGLES_3_1) + glMemoryBarrier(barriers); +#else + printf("WARNING! Not implemented.\n"); +#endif +} + +/* + * + * Core in: + * OpenGL : 4.2 + * OpenGLES : 3.1 + */ +void rglBindImageTexture( GLuint unit, + GLuint texture, + GLint level, + GLboolean layered, + GLint layer, + GLenum access, + GLenum format) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBindImageTexture.\n"); +#endif +#if !defined(HAVE_OPENGLES) || defined(HAVE_OPENGLES3) && defined(HAVE_OPENGLES_3_1) + glBindImageTexture(unit, texture, level, layered, layer, access, format); +#else + printf("WARNING! Not implemented.\n"); +#endif +} + +/* + * + * Core in: + * OpenGL : 4.1 + * OpenGLES : 3.1 + */ +void rglGetProgramBinary( GLuint program, + GLsizei bufsize, + GLsizei *length, + GLenum *binaryFormat, + void *binary) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGetProgramBinary.\n"); +#endif +#if !defined(HAVE_OPENGLES) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glGetProgramBinary(program, bufsize, length, binaryFormat, binary); +#else + printf("WARNING! Not implemented.\n"); +#endif +} + +/* + * + * Core in: + * OpenGL : 4.1 + * OpenGLES : 3.1 + */ +void rglProgramBinary(GLuint program, + GLenum binaryFormat, + const void *binary, + GLsizei length) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glProgramBinary.\n"); +#endif +#if !defined(HAVE_OPENGLES) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3_1) + glProgramBinary(program, binaryFormat, binary, length); +#else + printf("WARNING! Not implemented.\n"); +#endif +} + +void rglTexImage2DMultisample( GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glTexImage2DMultisample.\n"); +#endif +#ifndef HAVE_OPENGLES + glTexImage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations); +#endif +} + +void rglTexImage3D( GLenum target, + GLint level, + GLint internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const GLvoid * data) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glTexImage3D.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glTexImage3D(target, level, internalFormat, width, height, depth, border, format, type, data); +#endif +} + +/* + * + * Core in: + * OpenGL : 1.5 + */ +void * rglMapBuffer( GLenum target, GLenum access) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glMapBuffer.\n"); +#endif +#if defined(HAVE_OPENGLES) + return glMapBufferOES(target, access); +#else + return glMapBuffer(target, access); +#endif +} + +/* + * + * Core in: + * OpenGL : 1.5 + */ +GLboolean rglUnmapBuffer( GLenum target) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUnmapBuffer.\n"); +#endif +#if defined(HAVE_OPENGLES) + return glUnmapBufferOES(target); +#else + return glUnmapBuffer(target); +#endif +} + +void rglBlendEquation(GLenum mode) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBlendEquation.\n"); +#endif + glBlendEquation(mode); +} + +void rglBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBlendColor.\n"); +#endif + glBlendColor(red, green, blue, alpha); +} + +/* + * Category: Blending + * + * Core in: + * OpenGL : 2.0 + */ +void rglBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBlendEquationSeparate.\n"); +#endif + glBlendEquationSeparate(modeRGB, modeAlpha); +} + +/* + * + * Core in: + * OpenGL : 2.0 + * OpenGLES : 3.2 + */ +void rglCopyImageSubData( GLuint srcName, + GLenum srcTarget, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + GLuint dstName, + GLenum dstTarget, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei srcWidth, + GLsizei srcHeight, + GLsizei srcDepth) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glCopyImageSubData.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES_3_2) + glCopyImageSubData(srcName, + srcTarget, + srcLevel, + srcX, + srcY, + srcZ, + dstName, + dstTarget, + dstLevel, + dstX, + dstY, + dstZ, + srcWidth, + srcHeight, + srcDepth); +#endif +} + +/* + * Category: VAO + * + * Core in: + * OpenGL : 3.0 + * OpenGLES : 3.0 + */ +void rglBindVertexArray(GLuint array) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBindVertexArray.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glBindVertexArray(array); +#endif +} + +/* + * Category: VAO + * + * Core in: + * OpenGL : 3.0 + * OpenGLES : 3.0 + */ +void rglGenVertexArrays(GLsizei n, GLuint *arrays) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glGenVertexArrays.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glGenVertexArrays(n, arrays); +#endif +} + +/* + * Category: VAO + * + * Core in: + * OpenGL : 3.0 + * OpenGLES : 3.0 + */ +void rglDeleteVertexArrays(GLsizei n, const GLuint *arrays) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDeleteVertexArrays.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glDeleteVertexArrays(n, arrays); +#endif +} + +/* + * + * Core in: + * OpenGL : 3.2 + * OpenGLES : 3.0 + */ +void *rglFenceSync(GLenum condition, GLbitfield flags) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glFenceSync.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + return (GLsync)glFenceSync(condition, flags); +#else + return NULL; +#endif +} + +/* + * + * Core in: + * OpenGL : 3.2 + * OpenGLES : 3.0 + */ +void rglDeleteSync(void * sync) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDeleteSync.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glDeleteSync((GLsync)sync); +#endif +} + +/* + * + * Core in: + * OpenGL : 3.2 + * OpenGLES : 3.0 + */ +void rglWaitSync(void *sync, GLbitfield flags, uint64_t timeout) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glWaitSync.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glWaitSync((GLsync)sync, flags, (GLuint64)timeout); +#endif +} + +/* + * + * Core in: + * OpenGL : 4.4 + * OpenGLES : Not available + */ +void rglBufferStorage(GLenum target, GLsizeiptr size, const GLvoid *data, GLbitfield flags) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glBufferStorage.\n"); +#endif +#if defined(HAVE_OPENGL) + glBufferStorage(target, size, data, flags); +#endif +} + +/* + * + * Core in: + * OpenGL : 2.0 + * OpenGLES : 2.0 + */ + +void rglUniform2iv( GLint location, + GLsizei count, + const GLint *value) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform2iv.\n"); +#endif + glUniform2iv(location, count, value); +} + +/* + * + * Core in: + * OpenGL : 3.0 + * OpenGLES : ?.? + */ + +void rglUniform2uiv( GLint location, + GLsizei count, + const GLuint *value) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glUniform2uiv.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glUniform2uiv(location, count, value); +#endif +} + +/* + * + * Core in: + * OpenGL : 4.3 + * OpenGLES : ?.? + */ +void rglTextureView( GLuint texture, + GLenum target, + GLuint origtexture, + GLenum internalformat, + GLuint minlevel, + GLuint numlevels, + GLuint minlayer, + GLuint numlayers) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glTextureView.\n"); +#endif +#if defined(HAVE_OPENGL) + glTextureView(texture, target, origtexture, internalformat, minlevel, numlevels, minlayer, numlayers); +#endif +} + +/* + * + * Core in: + * OpenGL : 3.0 + * OpenGLES : 3.0 + */ +void rglFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glFlushMappedBufferRange.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + glFlushMappedBufferRange(target, offset, length); +#endif +} + +#ifndef GL_WAIT_FAILED +#define GL_WAIT_FAILED 0x911D +#endif + +/* + * + * Core in: + * OpenGL : 3.2 + * OpenGLES : 3.0 + */ +GLenum rglClientWaitSync(void *sync, GLbitfield flags, uint64_t timeout) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glClientWaitSync.\n"); +#endif +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) && defined(HAVE_OPENGLES3) + return glClientWaitSync((GLsync)sync, flags, (GLuint64)timeout); +#else + return GL_WAIT_FAILED; +#endif +} + +/* + * + * Core in: + * OpenGL : 3.2 + * OpenGLES : Not available + */ +void rglDrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, + GLvoid *indices, GLint basevertex) +{ +#ifdef GLSM_DEBUG + log_cb(RETRO_LOG_INFO, "glDrawElementsBaseVertex.\n"); +#endif +#if defined(HAVE_OPENGL) + glDrawElementsBaseVertex(mode, count, type, indices, basevertex); +#endif +} + +/* GLSM-side */ + +static void glsm_state_setup(void) +{ + unsigned i; + + gl_state.cap_translate[SGL_DEPTH_TEST] = GL_DEPTH_TEST; + gl_state.cap_translate[SGL_BLEND] = GL_BLEND; + gl_state.cap_translate[SGL_POLYGON_OFFSET_FILL] = GL_POLYGON_OFFSET_FILL; + gl_state.cap_translate[SGL_FOG] = GL_FOG; + gl_state.cap_translate[SGL_CULL_FACE] = GL_CULL_FACE; + gl_state.cap_translate[SGL_ALPHA_TEST] = GL_ALPHA_TEST; + gl_state.cap_translate[SGL_SCISSOR_TEST] = GL_SCISSOR_TEST; + gl_state.cap_translate[SGL_STENCIL_TEST] = GL_STENCIL_TEST; + +#ifndef HAVE_OPENGLES + gl_state.cap_translate[SGL_COLOR_LOGIC_OP] = GL_COLOR_LOGIC_OP; + gl_state.cap_translate[SGL_CLIP_DISTANCE0] = GL_CLIP_DISTANCE0; + gl_state.cap_translate[SGL_DEPTH_CLAMP] = GL_DEPTH_CLAMP; +#endif + + for (i = 0; i < MAX_ATTRIB; i++) + { + gl_state.vertex_attrib_pointer.enabled[i] = 0; + gl_state.attrib_pointer.used[i] = 0; + } + + glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &glsm_max_textures); + + gl_state.bind_textures.ids = (GLuint*)calloc(glsm_max_textures, sizeof(GLuint)); + + default_framebuffer = glsm_get_current_framebuffer(); + gl_state.framebuf = default_framebuffer; + gl_state.cullface.mode = GL_BACK; + gl_state.frontface.mode = GL_CCW; + + gl_state.blendfunc_separate.used = false; + gl_state.blendfunc_separate.srcRGB = GL_ONE; + gl_state.blendfunc_separate.dstRGB = GL_ZERO; + gl_state.blendfunc_separate.srcAlpha = GL_ONE; + gl_state.blendfunc_separate.dstAlpha = GL_ZERO; + + gl_state.depthfunc.used = false; + + gl_state.colormask.used = false; + gl_state.colormask.red = GL_TRUE; + gl_state.colormask.green = GL_TRUE; + gl_state.colormask.blue = GL_TRUE; + gl_state.colormask.alpha = GL_TRUE; + + gl_state.polygonoffset.used = false; + + gl_state.depthfunc.func = GL_LESS; + +#ifndef HAVE_OPENGLES + gl_state.colorlogicop = GL_COPY; +#endif + +#ifdef CORE + glGenVertexArrays(1, &gl_state.vao); +#endif +} + +static void glsm_state_bind(void) +{ + unsigned i; +#ifdef CORE + glBindVertexArray(gl_state.vao); +#endif + glBindBuffer(GL_ARRAY_BUFFER, gl_state.array_buffer); + + for (i = 0; i < MAX_ATTRIB; i++) + { + if (gl_state.vertex_attrib_pointer.enabled[i]) + glEnableVertexAttribArray(i); + else + glDisableVertexAttribArray(i); + + if (gl_state.attrib_pointer.used[i] && gl_state.attrib_pointer.buffer[i] == gl_state.array_buffer) + { + glVertexAttribPointer( + i, + gl_state.attrib_pointer.size[i], + gl_state.attrib_pointer.type[i], + gl_state.attrib_pointer.normalized[i], + gl_state.attrib_pointer.stride[i], + gl_state.attrib_pointer.pointer[i]); + } + } + + glBindFramebuffer(RARCH_GL_FRAMEBUFFER, default_framebuffer); + + if (gl_state.blendfunc.used) + glBlendFunc( + gl_state.blendfunc.sfactor, + gl_state.blendfunc.dfactor); + + if (gl_state.blendfunc_separate.used) + glBlendFuncSeparate( + gl_state.blendfunc_separate.srcRGB, + gl_state.blendfunc_separate.dstRGB, + gl_state.blendfunc_separate.srcAlpha, + gl_state.blendfunc_separate.dstAlpha + ); + + glClearColor( + gl_state.clear_color.r, + gl_state.clear_color.g, + gl_state.clear_color.b, + gl_state.clear_color.a); + + if (gl_state.depthfunc.used) + glDepthFunc(gl_state.depthfunc.func); + + if (gl_state.colormask.used) + glColorMask( + gl_state.colormask.red, + gl_state.colormask.green, + gl_state.colormask.blue, + gl_state.colormask.alpha); + + if (gl_state.cullface.used) + glCullFace(gl_state.cullface.mode); + + if (gl_state.depthmask.used) + glDepthMask(gl_state.depthmask.mask); + + if (gl_state.polygonoffset.used) + glPolygonOffset( + gl_state.polygonoffset.factor, + gl_state.polygonoffset.units); + + if (gl_state.scissor.used) + glScissor( + gl_state.scissor.x, + gl_state.scissor.y, + gl_state.scissor.w, + gl_state.scissor.h); + + glUseProgram(gl_state.program); + + glViewport( + gl_state.viewport.x, + gl_state.viewport.y, + gl_state.viewport.w, + gl_state.viewport.h); + + for(i = 0; i < SGL_CAP_MAX; i ++) + { + if (gl_state.cap_state[i]) + glEnable(gl_state.cap_translate[i]); + } + + if (gl_state.frontface.used) + glFrontFace(gl_state.frontface.mode); + + if (gl_state.stencilmask.used) + glStencilMask(gl_state.stencilmask.mask); + + if (gl_state.stencilop.used) + glStencilOp(gl_state.stencilop.sfail, + gl_state.stencilop.dpfail, + gl_state.stencilop.dppass); + + if (gl_state.stencilfunc.used) + glStencilFunc( + gl_state.stencilfunc.func, + gl_state.stencilfunc.ref, + gl_state.stencilfunc.mask); + + for (i = 0; i < glsm_max_textures; i ++) + { + glActiveTexture(GL_TEXTURE0 + i); + glBindTexture(GL_TEXTURE_2D, gl_state.bind_textures.ids[i]); + } + + glActiveTexture(GL_TEXTURE0 + gl_state.active_texture); +} + +static void glsm_state_unbind(void) +{ + unsigned i; +#ifdef CORE + glBindVertexArray(0); +#endif + for (i = 0; i < SGL_CAP_MAX; i ++) + { + if (gl_state.cap_state[i]) + glDisable(gl_state.cap_translate[i]); + } + + glBlendFunc(GL_ONE, GL_ZERO); + + if (gl_state.colormask.used) + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + if (gl_state.blendfunc_separate.used) + glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ONE, GL_ZERO); + + if (gl_state.cullface.used) + glCullFace(GL_BACK); + + if (gl_state.depthmask.used) + glDepthMask(GL_TRUE); + + if (gl_state.polygonoffset.used) + glPolygonOffset(0, 0); + + glUseProgram(0); + glClearColor(0,0,0,0.0f); + + if (gl_state.depthrange.used) + rglDepthRange(0, 1); + + glStencilMask(1); + glFrontFace(GL_CCW); + if (gl_state.depthfunc.used) + glDepthFunc(GL_LESS); + + if (gl_state.stencilop.used) + glStencilOp(GL_KEEP,GL_KEEP, GL_KEEP); + + if (gl_state.stencilfunc.used) + glStencilFunc(GL_ALWAYS,0,1); + + /* Clear textures */ + for (i = 0; i < glsm_max_textures; i ++) + { + glActiveTexture(GL_TEXTURE0 + i); + glBindTexture(GL_TEXTURE_2D, 0); + } + glActiveTexture(GL_TEXTURE0); + + for (i = 0; i < MAX_ATTRIB; i ++) + glDisableVertexAttribArray(i); + + glBindFramebuffer(RARCH_GL_FRAMEBUFFER, 0); +} + +static bool glsm_state_ctx_destroy(void *data) +{ + if (gl_state.bind_textures.ids) + free(gl_state.bind_textures.ids); + gl_state.bind_textures.ids = NULL; + + return true; +} + +static bool glsm_state_ctx_init(glsm_ctx_params_t *params) +{ + if (!params || !params->environ_cb) + return false; + +#ifdef HAVE_OPENGLES +#if defined(HAVE_OPENGLES_3_1) + hw_render.context_type = RETRO_HW_CONTEXT_OPENGLES_VERSION; + hw_render.version_major = 3; + hw_render.version_minor = 1; +#elif defined(HAVE_OPENGLES3) + hw_render.context_type = RETRO_HW_CONTEXT_OPENGLES3; +#else + hw_render.context_type = RETRO_HW_CONTEXT_OPENGLES2; +#endif +#else + hw_render.context_type = RETRO_HW_CONTEXT_OPENGL; + if (params->context_type != RETRO_HW_CONTEXT_NONE) + hw_render.context_type = params->context_type; + if (params->major != 0) + hw_render.version_major = params->major; + if (params->minor != 0) + hw_render.version_minor = params->minor; +#endif + + hw_render.context_reset = params->context_reset; + hw_render.context_destroy = params->context_destroy; + hw_render.stencil = params->stencil; + hw_render.depth = true; + hw_render.bottom_left_origin = true; + hw_render.cache_context = false; + + if (!params->environ_cb(RETRO_ENVIRONMENT_SET_HW_RENDER, &hw_render)) + return false; + + return true; +} + +GLuint glsm_get_current_framebuffer(void) +{ + return hw_render.get_current_framebuffer(); +} + +bool glsm_ctl(enum glsm_state_ctl state, void *data) +{ + switch (state) + { + case GLSM_CTL_IMM_VBO_DRAW: + return false; + case GLSM_CTL_IMM_VBO_DISABLE: + return false; + case GLSM_CTL_IS_IMM_VBO: + return false; + case GLSM_CTL_SET_IMM_VBO: + break; + case GLSM_CTL_UNSET_IMM_VBO: + break; + case GLSM_CTL_PROC_ADDRESS_GET: + { + glsm_ctx_proc_address_t *proc = (glsm_ctx_proc_address_t*)data; + if (!hw_render.get_proc_address) + return false; + proc->addr = hw_render.get_proc_address; + } + break; + case GLSM_CTL_STATE_CONTEXT_RESET: + rglgen_resolve_symbols(hw_render.get_proc_address); + break; + case GLSM_CTL_STATE_CONTEXT_DESTROY: + glsm_state_ctx_destroy(data); + break; + case GLSM_CTL_STATE_CONTEXT_INIT: + return glsm_state_ctx_init((glsm_ctx_params_t*)data); + case GLSM_CTL_STATE_SETUP: + glsm_state_setup(); + break; + case GLSM_CTL_STATE_UNBIND: + glsm_state_unbind(); + break; + case GLSM_CTL_STATE_BIND: + glsm_state_bind(); + break; + case GLSM_CTL_NONE: + default: + break; + } + + return true; +} diff --git a/src/libretro/libretro-common/glsym/README.md b/src/libretro/libretro-common/glsym/README.md new file mode 100644 index 000000000..5130194fc --- /dev/null +++ b/src/libretro/libretro-common/glsym/README.md @@ -0,0 +1,11 @@ +# Autogenerate GL extension loaders + +## OpenGL desktop + +Use Khronos' recent [header](www.opengl.org/registry/api/glext.h). + + ./glgen.py /usr/include/GL/glext.h glsym_gl.h glsym_gl.c + +## OpenGL ES + + ./glgen.py /usr/include/GLES2/gl2ext.h glsym_es2.h glsym_es2.c diff --git a/src/libretro/libretro-common/glsym/glgen.py b/src/libretro/libretro-common/glsym/glgen.py new file mode 100755 index 000000000..8d82357fc --- /dev/null +++ b/src/libretro/libretro-common/glsym/glgen.py @@ -0,0 +1,155 @@ +#!/usr/bin/env python3 + +""" + License statement applies to this file (glgen.py) only. + + Permission is hereby granted, free of charge, + 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: + + 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, + 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. +""" + +import sys +import os +import re + +banned_ext = [ 'AMD', 'APPLE', 'NV', 'NVX', 'ATI', '3DLABS', 'SUN', 'SGI', 'SGIX', 'SGIS', 'INTEL', '3DFX', 'IBM', 'MESA', 'GREMEDY', 'OML', 'PGI', 'I3D', 'INGL', 'MTX', 'QCOM', 'IMG', 'ANGLE', 'SUNX', 'INGR' ] + +def noext(sym): + for ext in banned_ext: + if sym.endswith(ext): + return False + return True + +def fix_multiline_functions(lines): + fixed_lines = [] + temp_lines = [] + for line in lines: + if line.count('(') > line.count(')'): + temp_lines.append(line) + else: + if len(temp_lines) > 0: + if line.count(')') > line.count('('): + temp_lines.append(line) + fixed_line = re.sub(' +',' ', ''.join(temp_lines).replace('\n','').replace('\t','')) + fixed_lines.append(fixed_line) + temp_lines = [] + else: + temp_lines.append(line) + else: + fixed_lines.append(line) + return fixed_lines + +def find_gl_symbols(lines): + typedefs = [] + syms = [] + for line in lines: + m = re.search(r'^typedef.+PFN(\S+)PROC.+$', line) + g = re.search(r'^.+(gl\S+)\W*\(.+\).*$', line) + if m and noext(m.group(1)): + typedefs.append(m.group(0).replace('PFN', 'RGLSYM').replace('GLDEBUGPROC', 'RGLGENGLDEBUGPROC')) + if g and noext(g.group(1)): + syms.append(g.group(1)) + return (typedefs, syms) + +def generate_defines(gl_syms): + res = [] + for line in gl_syms: + res.append('#define {} __rglgen_{}'.format(line, line)) + return res + +def generate_declarations(gl_syms): + return ['RGLSYM' + x.upper() + 'PROC ' + '__rglgen_' + x + ';' for x in gl_syms] + +def generate_macros(gl_syms): + return [' SYM(' + x.replace('gl', '') + '),' for x in gl_syms] + +def dump(f, lines): + f.write('\n'.join(lines)) + f.write('\n\n') + +if __name__ == '__main__': + + if len(sys.argv) > 4: + for banned in sys.argv[4:]: + banned_ext.append(banned) + + with open(sys.argv[1], 'r') as f: + lines = fix_multiline_functions(f.readlines()) + typedefs, syms = find_gl_symbols(lines) + + overrides = generate_defines(syms) + declarations = generate_declarations(syms) + externs = ['extern ' + x for x in declarations] + + macros = generate_macros(syms) + + with open(sys.argv[2], 'w') as f: + f.write('#ifndef RGLGEN_DECL_H__\n') + f.write('#define RGLGEN_DECL_H__\n') + + f.write('#ifdef __cplusplus\n') + f.write('extern "C" {\n') + f.write('#endif\n') + + f.write('#ifdef GL_APIENTRY\n') + f.write('typedef void (GL_APIENTRY *RGLGENGLDEBUGPROC)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*);\n') + f.write('typedef void (GL_APIENTRY *RGLGENGLDEBUGPROCKHR)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*);\n') + f.write('#else\n') + f.write('#ifndef APIENTRY\n') + f.write('#define APIENTRY\n') + f.write('#endif\n') + f.write('#ifndef APIENTRYP\n') + f.write('#define APIENTRYP APIENTRY *\n') + f.write('#endif\n') + f.write('typedef void (APIENTRY *RGLGENGLDEBUGPROCARB)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*);\n') + f.write('typedef void (APIENTRY *RGLGENGLDEBUGPROC)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*);\n') + f.write('#endif\n') + + f.write('#ifndef GL_OES_EGL_image\n') + f.write('typedef void *GLeglImageOES;\n') + f.write('#endif\n') + + f.write('#if !defined(GL_OES_fixed_point) && !defined(HAVE_OPENGLES2)\n') + f.write('typedef GLint GLfixed;\n') + f.write('#endif\n') + + f.write('#if defined(OSX) && !defined(MAC_OS_X_VERSION_10_7)\n') + f.write('typedef long long int GLint64;\n') + f.write('typedef unsigned long long int GLuint64;\n') + f.write('typedef unsigned long long int GLuint64EXT;\n') + f.write('typedef struct __GLsync *GLsync;\n') + f.write('#endif\n') + + dump(f, typedefs) + dump(f, overrides) + dump(f, externs) + + f.write('struct rglgen_sym_map { const char *sym; void *ptr; };\n') + f.write('extern const struct rglgen_sym_map rglgen_symbol_map[];\n') + + f.write('#ifdef __cplusplus\n') + f.write('}\n') + f.write('#endif\n') + + f.write('#endif\n') + + with open(sys.argv[3], 'w') as f: + f.write('#include "glsym/glsym.h"\n') + f.write('#include \n') + f.write('#define SYM(x) { "gl" #x, &(gl##x) }\n') + f.write('const struct rglgen_sym_map rglgen_symbol_map[] = {\n') + dump(f, macros) + f.write(' { NULL, NULL },\n') + f.write('};\n') + dump(f, declarations) diff --git a/src/libretro/libretro-common/glsym/glsym_es2.c b/src/libretro/libretro-common/glsym/glsym_es2.c new file mode 100644 index 000000000..b9c070648 --- /dev/null +++ b/src/libretro/libretro-common/glsym/glsym_es2.c @@ -0,0 +1,409 @@ +#include "glsym/glsym.h" +#include +#define SYM(x) { "gl" #x, &(gl##x) } +const struct rglgen_sym_map rglgen_symbol_map[] = { + SYM(BlendBarrierKHR), + SYM(DebugMessageControlKHR), + SYM(DebugMessageInsertKHR), + SYM(DebugMessageCallbackKHR), + SYM(GetDebugMessageLogKHR), + SYM(PushDebugGroupKHR), + SYM(PopDebugGroupKHR), + SYM(ObjectLabelKHR), + SYM(GetObjectLabelKHR), + SYM(ObjectPtrLabelKHR), + SYM(GetObjectPtrLabelKHR), + SYM(GetPointervKHR), + SYM(GetGraphicsResetStatusKHR), + SYM(ReadnPixelsKHR), + SYM(GetnUniformfvKHR), + SYM(GetnUniformivKHR), + SYM(GetnUniformuivKHR), + SYM(EGLImageTargetTexture2DOES), + SYM(EGLImageTargetRenderbufferStorageOES), + SYM(CopyImageSubDataOES), + SYM(EnableiOES), + SYM(DisableiOES), + SYM(BlendEquationiOES), + SYM(BlendEquationSeparateiOES), + SYM(BlendFunciOES), + SYM(BlendFuncSeparateiOES), + SYM(ColorMaskiOES), + SYM(IsEnablediOES), + SYM(DrawElementsBaseVertexOES), + SYM(DrawRangeElementsBaseVertexOES), + SYM(DrawElementsInstancedBaseVertexOES), + SYM(MultiDrawElementsBaseVertexOES), + SYM(FramebufferTextureOES), + SYM(GetProgramBinaryOES), + SYM(ProgramBinaryOES), + SYM(MapBufferOES), + SYM(UnmapBufferOES), + SYM(GetBufferPointervOES), + SYM(PrimitiveBoundingBoxOES), + SYM(MinSampleShadingOES), + SYM(PatchParameteriOES), + SYM(TexImage3DOES), + SYM(TexSubImage3DOES), + SYM(CopyTexSubImage3DOES), + SYM(CompressedTexImage3DOES), + SYM(CompressedTexSubImage3DOES), + SYM(FramebufferTexture3DOES), + SYM(TexParameterIivOES), + SYM(TexParameterIuivOES), + SYM(GetTexParameterIivOES), + SYM(GetTexParameterIuivOES), + SYM(SamplerParameterIivOES), + SYM(SamplerParameterIuivOES), + SYM(GetSamplerParameterIivOES), + SYM(GetSamplerParameterIuivOES), + SYM(TexBufferOES), + SYM(TexBufferRangeOES), + SYM(TexStorage3DMultisampleOES), + SYM(TextureViewOES), + SYM(BindVertexArrayOES), + SYM(DeleteVertexArraysOES), + SYM(GenVertexArraysOES), + SYM(IsVertexArrayOES), + SYM(ViewportArrayvOES), + SYM(ViewportIndexedfOES), + SYM(ViewportIndexedfvOES), + SYM(ScissorArrayvOES), + SYM(ScissorIndexedOES), + SYM(ScissorIndexedvOES), + SYM(DepthRangeArrayfvOES), + SYM(DepthRangeIndexedfOES), + SYM(GetFloati_vOES), + SYM(DrawArraysInstancedBaseInstanceEXT), + SYM(DrawElementsInstancedBaseInstanceEXT), + SYM(DrawElementsInstancedBaseVertexBaseInstanceEXT), + SYM(BindFragDataLocationIndexedEXT), + SYM(BindFragDataLocationEXT), + SYM(GetProgramResourceLocationIndexEXT), + SYM(GetFragDataIndexEXT), + SYM(BufferStorageEXT), + SYM(ClearTexImageEXT), + SYM(ClearTexSubImageEXT), + SYM(CopyImageSubDataEXT), + SYM(LabelObjectEXT), + SYM(GetObjectLabelEXT), + SYM(InsertEventMarkerEXT), + SYM(PushGroupMarkerEXT), + SYM(PopGroupMarkerEXT), + SYM(DiscardFramebufferEXT), + SYM(GenQueriesEXT), + SYM(DeleteQueriesEXT), + SYM(IsQueryEXT), + SYM(BeginQueryEXT), + SYM(EndQueryEXT), + SYM(QueryCounterEXT), + SYM(GetQueryivEXT), + SYM(GetQueryObjectivEXT), + SYM(GetQueryObjectuivEXT), + SYM(DrawBuffersEXT), + SYM(EnableiEXT), + SYM(DisableiEXT), + SYM(BlendEquationiEXT), + SYM(BlendEquationSeparateiEXT), + SYM(BlendFunciEXT), + SYM(BlendFuncSeparateiEXT), + SYM(ColorMaskiEXT), + SYM(IsEnablediEXT), + SYM(DrawElementsBaseVertexEXT), + SYM(DrawRangeElementsBaseVertexEXT), + SYM(DrawElementsInstancedBaseVertexEXT), + SYM(MultiDrawElementsBaseVertexEXT), + SYM(DrawArraysInstancedEXT), + SYM(DrawElementsInstancedEXT), + SYM(FramebufferTextureEXT), + SYM(VertexAttribDivisorEXT), + SYM(MapBufferRangeEXT), + SYM(FlushMappedBufferRangeEXT), + SYM(MultiDrawArraysEXT), + SYM(MultiDrawElementsEXT), + SYM(MultiDrawArraysIndirectEXT), + SYM(MultiDrawElementsIndirectEXT), + SYM(RenderbufferStorageMultisampleEXT), + SYM(FramebufferTexture2DMultisampleEXT), + SYM(ReadBufferIndexedEXT), + SYM(DrawBuffersIndexedEXT), + SYM(GetIntegeri_vEXT), + SYM(PolygonOffsetClampEXT), + SYM(PrimitiveBoundingBoxEXT), + SYM(RasterSamplesEXT), + SYM(GetGraphicsResetStatusEXT), + SYM(ReadnPixelsEXT), + SYM(GetnUniformfvEXT), + SYM(GetnUniformivEXT), + SYM(ActiveShaderProgramEXT), + SYM(BindProgramPipelineEXT), + SYM(CreateShaderProgramvEXT), + SYM(DeleteProgramPipelinesEXT), + SYM(GenProgramPipelinesEXT), + SYM(GetProgramPipelineInfoLogEXT), + SYM(GetProgramPipelineivEXT), + SYM(IsProgramPipelineEXT), + SYM(ProgramParameteriEXT), + SYM(ProgramUniform1fEXT), + SYM(ProgramUniform1fvEXT), + SYM(ProgramUniform1iEXT), + SYM(ProgramUniform1ivEXT), + SYM(ProgramUniform2fEXT), + SYM(ProgramUniform2fvEXT), + SYM(ProgramUniform2iEXT), + SYM(ProgramUniform2ivEXT), + SYM(ProgramUniform3fEXT), + SYM(ProgramUniform3fvEXT), + SYM(ProgramUniform3iEXT), + SYM(ProgramUniform3ivEXT), + SYM(ProgramUniform4fEXT), + SYM(ProgramUniform4fvEXT), + SYM(ProgramUniform4iEXT), + SYM(ProgramUniform4ivEXT), + SYM(ProgramUniformMatrix2fvEXT), + SYM(ProgramUniformMatrix3fvEXT), + SYM(ProgramUniformMatrix4fvEXT), + SYM(UseProgramStagesEXT), + SYM(ValidateProgramPipelineEXT), + SYM(ProgramUniform1uiEXT), + SYM(ProgramUniform2uiEXT), + SYM(ProgramUniform3uiEXT), + SYM(ProgramUniform4uiEXT), + SYM(ProgramUniform1uivEXT), + SYM(ProgramUniform2uivEXT), + SYM(ProgramUniform3uivEXT), + SYM(ProgramUniform4uivEXT), + SYM(ProgramUniformMatrix2x3fvEXT), + SYM(ProgramUniformMatrix3x2fvEXT), + SYM(ProgramUniformMatrix2x4fvEXT), + SYM(ProgramUniformMatrix4x2fvEXT), + SYM(ProgramUniformMatrix3x4fvEXT), + SYM(ProgramUniformMatrix4x3fvEXT), + SYM(FramebufferPixelLocalStorageSizeEXT), + SYM(GetFramebufferPixelLocalStorageSizeEXT), + SYM(ClearPixelLocalStorageuiEXT), + SYM(TexPageCommitmentEXT), + SYM(PatchParameteriEXT), + SYM(TexParameterIivEXT), + SYM(TexParameterIuivEXT), + SYM(GetTexParameterIivEXT), + SYM(GetTexParameterIuivEXT), + SYM(SamplerParameterIivEXT), + SYM(SamplerParameterIuivEXT), + SYM(GetSamplerParameterIivEXT), + SYM(GetSamplerParameterIuivEXT), + SYM(TexBufferEXT), + SYM(TexBufferRangeEXT), + SYM(TexStorage1DEXT), + SYM(TexStorage2DEXT), + SYM(TexStorage3DEXT), + SYM(TextureStorage1DEXT), + SYM(TextureStorage2DEXT), + SYM(TextureStorage3DEXT), + SYM(TextureViewEXT), + SYM(FramebufferTextureMultiviewOVR), + SYM(FramebufferTextureMultisampleMultiviewOVR), + + { NULL, NULL }, +}; +RGLSYMGLBLENDBARRIERKHRPROC __rglgen_glBlendBarrierKHR; +RGLSYMGLDEBUGMESSAGECONTROLKHRPROC __rglgen_glDebugMessageControlKHR; +RGLSYMGLDEBUGMESSAGEINSERTKHRPROC __rglgen_glDebugMessageInsertKHR; +RGLSYMGLDEBUGMESSAGECALLBACKKHRPROC __rglgen_glDebugMessageCallbackKHR; +RGLSYMGLGETDEBUGMESSAGELOGKHRPROC __rglgen_glGetDebugMessageLogKHR; +RGLSYMGLPUSHDEBUGGROUPKHRPROC __rglgen_glPushDebugGroupKHR; +RGLSYMGLPOPDEBUGGROUPKHRPROC __rglgen_glPopDebugGroupKHR; +RGLSYMGLOBJECTLABELKHRPROC __rglgen_glObjectLabelKHR; +RGLSYMGLGETOBJECTLABELKHRPROC __rglgen_glGetObjectLabelKHR; +RGLSYMGLOBJECTPTRLABELKHRPROC __rglgen_glObjectPtrLabelKHR; +RGLSYMGLGETOBJECTPTRLABELKHRPROC __rglgen_glGetObjectPtrLabelKHR; +RGLSYMGLGETPOINTERVKHRPROC __rglgen_glGetPointervKHR; +RGLSYMGLGETGRAPHICSRESETSTATUSKHRPROC __rglgen_glGetGraphicsResetStatusKHR; +RGLSYMGLREADNPIXELSKHRPROC __rglgen_glReadnPixelsKHR; +RGLSYMGLGETNUNIFORMFVKHRPROC __rglgen_glGetnUniformfvKHR; +RGLSYMGLGETNUNIFORMIVKHRPROC __rglgen_glGetnUniformivKHR; +RGLSYMGLGETNUNIFORMUIVKHRPROC __rglgen_glGetnUniformuivKHR; +RGLSYMGLEGLIMAGETARGETTEXTURE2DOESPROC __rglgen_glEGLImageTargetTexture2DOES; +RGLSYMGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC __rglgen_glEGLImageTargetRenderbufferStorageOES; +RGLSYMGLCOPYIMAGESUBDATAOESPROC __rglgen_glCopyImageSubDataOES; +RGLSYMGLENABLEIOESPROC __rglgen_glEnableiOES; +RGLSYMGLDISABLEIOESPROC __rglgen_glDisableiOES; +RGLSYMGLBLENDEQUATIONIOESPROC __rglgen_glBlendEquationiOES; +RGLSYMGLBLENDEQUATIONSEPARATEIOESPROC __rglgen_glBlendEquationSeparateiOES; +RGLSYMGLBLENDFUNCIOESPROC __rglgen_glBlendFunciOES; +RGLSYMGLBLENDFUNCSEPARATEIOESPROC __rglgen_glBlendFuncSeparateiOES; +RGLSYMGLCOLORMASKIOESPROC __rglgen_glColorMaskiOES; +RGLSYMGLISENABLEDIOESPROC __rglgen_glIsEnablediOES; +RGLSYMGLDRAWELEMENTSBASEVERTEXOESPROC __rglgen_glDrawElementsBaseVertexOES; +RGLSYMGLDRAWRANGEELEMENTSBASEVERTEXOESPROC __rglgen_glDrawRangeElementsBaseVertexOES; +RGLSYMGLDRAWELEMENTSINSTANCEDBASEVERTEXOESPROC __rglgen_glDrawElementsInstancedBaseVertexOES; +RGLSYMGLMULTIDRAWELEMENTSBASEVERTEXOESPROC __rglgen_glMultiDrawElementsBaseVertexOES; +RGLSYMGLFRAMEBUFFERTEXTUREOESPROC __rglgen_glFramebufferTextureOES; +RGLSYMGLGETPROGRAMBINARYOESPROC __rglgen_glGetProgramBinaryOES; +RGLSYMGLPROGRAMBINARYOESPROC __rglgen_glProgramBinaryOES; +RGLSYMGLMAPBUFFEROESPROC __rglgen_glMapBufferOES; +RGLSYMGLUNMAPBUFFEROESPROC __rglgen_glUnmapBufferOES; +RGLSYMGLGETBUFFERPOINTERVOESPROC __rglgen_glGetBufferPointervOES; +RGLSYMGLPRIMITIVEBOUNDINGBOXOESPROC __rglgen_glPrimitiveBoundingBoxOES; +RGLSYMGLMINSAMPLESHADINGOESPROC __rglgen_glMinSampleShadingOES; +RGLSYMGLPATCHPARAMETERIOESPROC __rglgen_glPatchParameteriOES; +RGLSYMGLTEXIMAGE3DOESPROC __rglgen_glTexImage3DOES; +RGLSYMGLTEXSUBIMAGE3DOESPROC __rglgen_glTexSubImage3DOES; +RGLSYMGLCOPYTEXSUBIMAGE3DOESPROC __rglgen_glCopyTexSubImage3DOES; +RGLSYMGLCOMPRESSEDTEXIMAGE3DOESPROC __rglgen_glCompressedTexImage3DOES; +RGLSYMGLCOMPRESSEDTEXSUBIMAGE3DOESPROC __rglgen_glCompressedTexSubImage3DOES; +RGLSYMGLFRAMEBUFFERTEXTURE3DOESPROC __rglgen_glFramebufferTexture3DOES; +RGLSYMGLTEXPARAMETERIIVOESPROC __rglgen_glTexParameterIivOES; +RGLSYMGLTEXPARAMETERIUIVOESPROC __rglgen_glTexParameterIuivOES; +RGLSYMGLGETTEXPARAMETERIIVOESPROC __rglgen_glGetTexParameterIivOES; +RGLSYMGLGETTEXPARAMETERIUIVOESPROC __rglgen_glGetTexParameterIuivOES; +RGLSYMGLSAMPLERPARAMETERIIVOESPROC __rglgen_glSamplerParameterIivOES; +RGLSYMGLSAMPLERPARAMETERIUIVOESPROC __rglgen_glSamplerParameterIuivOES; +RGLSYMGLGETSAMPLERPARAMETERIIVOESPROC __rglgen_glGetSamplerParameterIivOES; +RGLSYMGLGETSAMPLERPARAMETERIUIVOESPROC __rglgen_glGetSamplerParameterIuivOES; +RGLSYMGLTEXBUFFEROESPROC __rglgen_glTexBufferOES; +RGLSYMGLTEXBUFFERRANGEOESPROC __rglgen_glTexBufferRangeOES; +RGLSYMGLTEXSTORAGE3DMULTISAMPLEOESPROC __rglgen_glTexStorage3DMultisampleOES; +RGLSYMGLTEXTUREVIEWOESPROC __rglgen_glTextureViewOES; +RGLSYMGLBINDVERTEXARRAYOESPROC __rglgen_glBindVertexArrayOES; +RGLSYMGLDELETEVERTEXARRAYSOESPROC __rglgen_glDeleteVertexArraysOES; +RGLSYMGLGENVERTEXARRAYSOESPROC __rglgen_glGenVertexArraysOES; +RGLSYMGLISVERTEXARRAYOESPROC __rglgen_glIsVertexArrayOES; +RGLSYMGLVIEWPORTARRAYVOESPROC __rglgen_glViewportArrayvOES; +RGLSYMGLVIEWPORTINDEXEDFOESPROC __rglgen_glViewportIndexedfOES; +RGLSYMGLVIEWPORTINDEXEDFVOESPROC __rglgen_glViewportIndexedfvOES; +RGLSYMGLSCISSORARRAYVOESPROC __rglgen_glScissorArrayvOES; +RGLSYMGLSCISSORINDEXEDOESPROC __rglgen_glScissorIndexedOES; +RGLSYMGLSCISSORINDEXEDVOESPROC __rglgen_glScissorIndexedvOES; +RGLSYMGLDEPTHRANGEARRAYFVOESPROC __rglgen_glDepthRangeArrayfvOES; +RGLSYMGLDEPTHRANGEINDEXEDFOESPROC __rglgen_glDepthRangeIndexedfOES; +RGLSYMGLGETFLOATI_VOESPROC __rglgen_glGetFloati_vOES; +RGLSYMGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC __rglgen_glDrawArraysInstancedBaseInstanceEXT; +RGLSYMGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC __rglgen_glDrawElementsInstancedBaseInstanceEXT; +RGLSYMGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC __rglgen_glDrawElementsInstancedBaseVertexBaseInstanceEXT; +RGLSYMGLBINDFRAGDATALOCATIONINDEXEDEXTPROC __rglgen_glBindFragDataLocationIndexedEXT; +RGLSYMGLBINDFRAGDATALOCATIONEXTPROC __rglgen_glBindFragDataLocationEXT; +RGLSYMGLGETPROGRAMRESOURCELOCATIONINDEXEXTPROC __rglgen_glGetProgramResourceLocationIndexEXT; +RGLSYMGLGETFRAGDATAINDEXEXTPROC __rglgen_glGetFragDataIndexEXT; +RGLSYMGLBUFFERSTORAGEEXTPROC __rglgen_glBufferStorageEXT; +RGLSYMGLCLEARTEXIMAGEEXTPROC __rglgen_glClearTexImageEXT; +RGLSYMGLCLEARTEXSUBIMAGEEXTPROC __rglgen_glClearTexSubImageEXT; +RGLSYMGLCOPYIMAGESUBDATAEXTPROC __rglgen_glCopyImageSubDataEXT; +RGLSYMGLLABELOBJECTEXTPROC __rglgen_glLabelObjectEXT; +RGLSYMGLGETOBJECTLABELEXTPROC __rglgen_glGetObjectLabelEXT; +RGLSYMGLINSERTEVENTMARKEREXTPROC __rglgen_glInsertEventMarkerEXT; +RGLSYMGLPUSHGROUPMARKEREXTPROC __rglgen_glPushGroupMarkerEXT; +RGLSYMGLPOPGROUPMARKEREXTPROC __rglgen_glPopGroupMarkerEXT; +RGLSYMGLDISCARDFRAMEBUFFEREXTPROC __rglgen_glDiscardFramebufferEXT; +RGLSYMGLGENQUERIESEXTPROC __rglgen_glGenQueriesEXT; +RGLSYMGLDELETEQUERIESEXTPROC __rglgen_glDeleteQueriesEXT; +RGLSYMGLISQUERYEXTPROC __rglgen_glIsQueryEXT; +RGLSYMGLBEGINQUERYEXTPROC __rglgen_glBeginQueryEXT; +RGLSYMGLENDQUERYEXTPROC __rglgen_glEndQueryEXT; +RGLSYMGLQUERYCOUNTEREXTPROC __rglgen_glQueryCounterEXT; +RGLSYMGLGETQUERYIVEXTPROC __rglgen_glGetQueryivEXT; +RGLSYMGLGETQUERYOBJECTIVEXTPROC __rglgen_glGetQueryObjectivEXT; +RGLSYMGLGETQUERYOBJECTUIVEXTPROC __rglgen_glGetQueryObjectuivEXT; +RGLSYMGLDRAWBUFFERSEXTPROC __rglgen_glDrawBuffersEXT; +RGLSYMGLENABLEIEXTPROC __rglgen_glEnableiEXT; +RGLSYMGLDISABLEIEXTPROC __rglgen_glDisableiEXT; +RGLSYMGLBLENDEQUATIONIEXTPROC __rglgen_glBlendEquationiEXT; +RGLSYMGLBLENDEQUATIONSEPARATEIEXTPROC __rglgen_glBlendEquationSeparateiEXT; +RGLSYMGLBLENDFUNCIEXTPROC __rglgen_glBlendFunciEXT; +RGLSYMGLBLENDFUNCSEPARATEIEXTPROC __rglgen_glBlendFuncSeparateiEXT; +RGLSYMGLCOLORMASKIEXTPROC __rglgen_glColorMaskiEXT; +RGLSYMGLISENABLEDIEXTPROC __rglgen_glIsEnablediEXT; +RGLSYMGLDRAWELEMENTSBASEVERTEXEXTPROC __rglgen_glDrawElementsBaseVertexEXT; +RGLSYMGLDRAWRANGEELEMENTSBASEVERTEXEXTPROC __rglgen_glDrawRangeElementsBaseVertexEXT; +RGLSYMGLDRAWELEMENTSINSTANCEDBASEVERTEXEXTPROC __rglgen_glDrawElementsInstancedBaseVertexEXT; +RGLSYMGLMULTIDRAWELEMENTSBASEVERTEXEXTPROC __rglgen_glMultiDrawElementsBaseVertexEXT; +RGLSYMGLDRAWARRAYSINSTANCEDEXTPROC __rglgen_glDrawArraysInstancedEXT; +RGLSYMGLDRAWELEMENTSINSTANCEDEXTPROC __rglgen_glDrawElementsInstancedEXT; +RGLSYMGLFRAMEBUFFERTEXTUREEXTPROC __rglgen_glFramebufferTextureEXT; +RGLSYMGLVERTEXATTRIBDIVISOREXTPROC __rglgen_glVertexAttribDivisorEXT; +RGLSYMGLMAPBUFFERRANGEEXTPROC __rglgen_glMapBufferRangeEXT; +RGLSYMGLFLUSHMAPPEDBUFFERRANGEEXTPROC __rglgen_glFlushMappedBufferRangeEXT; +RGLSYMGLMULTIDRAWARRAYSEXTPROC __rglgen_glMultiDrawArraysEXT; +RGLSYMGLMULTIDRAWELEMENTSEXTPROC __rglgen_glMultiDrawElementsEXT; +RGLSYMGLMULTIDRAWARRAYSINDIRECTEXTPROC __rglgen_glMultiDrawArraysIndirectEXT; +RGLSYMGLMULTIDRAWELEMENTSINDIRECTEXTPROC __rglgen_glMultiDrawElementsIndirectEXT; +RGLSYMGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __rglgen_glRenderbufferStorageMultisampleEXT; +RGLSYMGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC __rglgen_glFramebufferTexture2DMultisampleEXT; +RGLSYMGLREADBUFFERINDEXEDEXTPROC __rglgen_glReadBufferIndexedEXT; +RGLSYMGLDRAWBUFFERSINDEXEDEXTPROC __rglgen_glDrawBuffersIndexedEXT; +RGLSYMGLGETINTEGERI_VEXTPROC __rglgen_glGetIntegeri_vEXT; +RGLSYMGLPOLYGONOFFSETCLAMPEXTPROC __rglgen_glPolygonOffsetClampEXT; +RGLSYMGLPRIMITIVEBOUNDINGBOXEXTPROC __rglgen_glPrimitiveBoundingBoxEXT; +RGLSYMGLRASTERSAMPLESEXTPROC __rglgen_glRasterSamplesEXT; +RGLSYMGLGETGRAPHICSRESETSTATUSEXTPROC __rglgen_glGetGraphicsResetStatusEXT; +RGLSYMGLREADNPIXELSEXTPROC __rglgen_glReadnPixelsEXT; +RGLSYMGLGETNUNIFORMFVEXTPROC __rglgen_glGetnUniformfvEXT; +RGLSYMGLGETNUNIFORMIVEXTPROC __rglgen_glGetnUniformivEXT; +RGLSYMGLACTIVESHADERPROGRAMEXTPROC __rglgen_glActiveShaderProgramEXT; +RGLSYMGLBINDPROGRAMPIPELINEEXTPROC __rglgen_glBindProgramPipelineEXT; +RGLSYMGLCREATESHADERPROGRAMVEXTPROC __rglgen_glCreateShaderProgramvEXT; +RGLSYMGLDELETEPROGRAMPIPELINESEXTPROC __rglgen_glDeleteProgramPipelinesEXT; +RGLSYMGLGENPROGRAMPIPELINESEXTPROC __rglgen_glGenProgramPipelinesEXT; +RGLSYMGLGETPROGRAMPIPELINEINFOLOGEXTPROC __rglgen_glGetProgramPipelineInfoLogEXT; +RGLSYMGLGETPROGRAMPIPELINEIVEXTPROC __rglgen_glGetProgramPipelineivEXT; +RGLSYMGLISPROGRAMPIPELINEEXTPROC __rglgen_glIsProgramPipelineEXT; +RGLSYMGLPROGRAMPARAMETERIEXTPROC __rglgen_glProgramParameteriEXT; +RGLSYMGLPROGRAMUNIFORM1FEXTPROC __rglgen_glProgramUniform1fEXT; +RGLSYMGLPROGRAMUNIFORM1FVEXTPROC __rglgen_glProgramUniform1fvEXT; +RGLSYMGLPROGRAMUNIFORM1IEXTPROC __rglgen_glProgramUniform1iEXT; +RGLSYMGLPROGRAMUNIFORM1IVEXTPROC __rglgen_glProgramUniform1ivEXT; +RGLSYMGLPROGRAMUNIFORM2FEXTPROC __rglgen_glProgramUniform2fEXT; +RGLSYMGLPROGRAMUNIFORM2FVEXTPROC __rglgen_glProgramUniform2fvEXT; +RGLSYMGLPROGRAMUNIFORM2IEXTPROC __rglgen_glProgramUniform2iEXT; +RGLSYMGLPROGRAMUNIFORM2IVEXTPROC __rglgen_glProgramUniform2ivEXT; +RGLSYMGLPROGRAMUNIFORM3FEXTPROC __rglgen_glProgramUniform3fEXT; +RGLSYMGLPROGRAMUNIFORM3FVEXTPROC __rglgen_glProgramUniform3fvEXT; +RGLSYMGLPROGRAMUNIFORM3IEXTPROC __rglgen_glProgramUniform3iEXT; +RGLSYMGLPROGRAMUNIFORM3IVEXTPROC __rglgen_glProgramUniform3ivEXT; +RGLSYMGLPROGRAMUNIFORM4FEXTPROC __rglgen_glProgramUniform4fEXT; +RGLSYMGLPROGRAMUNIFORM4FVEXTPROC __rglgen_glProgramUniform4fvEXT; +RGLSYMGLPROGRAMUNIFORM4IEXTPROC __rglgen_glProgramUniform4iEXT; +RGLSYMGLPROGRAMUNIFORM4IVEXTPROC __rglgen_glProgramUniform4ivEXT; +RGLSYMGLPROGRAMUNIFORMMATRIX2FVEXTPROC __rglgen_glProgramUniformMatrix2fvEXT; +RGLSYMGLPROGRAMUNIFORMMATRIX3FVEXTPROC __rglgen_glProgramUniformMatrix3fvEXT; +RGLSYMGLPROGRAMUNIFORMMATRIX4FVEXTPROC __rglgen_glProgramUniformMatrix4fvEXT; +RGLSYMGLUSEPROGRAMSTAGESEXTPROC __rglgen_glUseProgramStagesEXT; +RGLSYMGLVALIDATEPROGRAMPIPELINEEXTPROC __rglgen_glValidateProgramPipelineEXT; +RGLSYMGLPROGRAMUNIFORM1UIEXTPROC __rglgen_glProgramUniform1uiEXT; +RGLSYMGLPROGRAMUNIFORM2UIEXTPROC __rglgen_glProgramUniform2uiEXT; +RGLSYMGLPROGRAMUNIFORM3UIEXTPROC __rglgen_glProgramUniform3uiEXT; +RGLSYMGLPROGRAMUNIFORM4UIEXTPROC __rglgen_glProgramUniform4uiEXT; +RGLSYMGLPROGRAMUNIFORM1UIVEXTPROC __rglgen_glProgramUniform1uivEXT; +RGLSYMGLPROGRAMUNIFORM2UIVEXTPROC __rglgen_glProgramUniform2uivEXT; +RGLSYMGLPROGRAMUNIFORM3UIVEXTPROC __rglgen_glProgramUniform3uivEXT; +RGLSYMGLPROGRAMUNIFORM4UIVEXTPROC __rglgen_glProgramUniform4uivEXT; +RGLSYMGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC __rglgen_glProgramUniformMatrix2x3fvEXT; +RGLSYMGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC __rglgen_glProgramUniformMatrix3x2fvEXT; +RGLSYMGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC __rglgen_glProgramUniformMatrix2x4fvEXT; +RGLSYMGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC __rglgen_glProgramUniformMatrix4x2fvEXT; +RGLSYMGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC __rglgen_glProgramUniformMatrix3x4fvEXT; +RGLSYMGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC __rglgen_glProgramUniformMatrix4x3fvEXT; +RGLSYMGLFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC __rglgen_glFramebufferPixelLocalStorageSizeEXT; +RGLSYMGLGETFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC __rglgen_glGetFramebufferPixelLocalStorageSizeEXT; +RGLSYMGLCLEARPIXELLOCALSTORAGEUIEXTPROC __rglgen_glClearPixelLocalStorageuiEXT; +RGLSYMGLTEXPAGECOMMITMENTEXTPROC __rglgen_glTexPageCommitmentEXT; +RGLSYMGLPATCHPARAMETERIEXTPROC __rglgen_glPatchParameteriEXT; +RGLSYMGLTEXPARAMETERIIVEXTPROC __rglgen_glTexParameterIivEXT; +RGLSYMGLTEXPARAMETERIUIVEXTPROC __rglgen_glTexParameterIuivEXT; +RGLSYMGLGETTEXPARAMETERIIVEXTPROC __rglgen_glGetTexParameterIivEXT; +RGLSYMGLGETTEXPARAMETERIUIVEXTPROC __rglgen_glGetTexParameterIuivEXT; +RGLSYMGLSAMPLERPARAMETERIIVEXTPROC __rglgen_glSamplerParameterIivEXT; +RGLSYMGLSAMPLERPARAMETERIUIVEXTPROC __rglgen_glSamplerParameterIuivEXT; +RGLSYMGLGETSAMPLERPARAMETERIIVEXTPROC __rglgen_glGetSamplerParameterIivEXT; +RGLSYMGLGETSAMPLERPARAMETERIUIVEXTPROC __rglgen_glGetSamplerParameterIuivEXT; +RGLSYMGLTEXBUFFEREXTPROC __rglgen_glTexBufferEXT; +RGLSYMGLTEXBUFFERRANGEEXTPROC __rglgen_glTexBufferRangeEXT; +RGLSYMGLTEXSTORAGE1DEXTPROC __rglgen_glTexStorage1DEXT; +RGLSYMGLTEXSTORAGE2DEXTPROC __rglgen_glTexStorage2DEXT; +RGLSYMGLTEXSTORAGE3DEXTPROC __rglgen_glTexStorage3DEXT; +RGLSYMGLTEXTURESTORAGE1DEXTPROC __rglgen_glTextureStorage1DEXT; +RGLSYMGLTEXTURESTORAGE2DEXTPROC __rglgen_glTextureStorage2DEXT; +RGLSYMGLTEXTURESTORAGE3DEXTPROC __rglgen_glTextureStorage3DEXT; +RGLSYMGLTEXTUREVIEWEXTPROC __rglgen_glTextureViewEXT; +RGLSYMGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC __rglgen_glFramebufferTextureMultiviewOVR; +RGLSYMGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC __rglgen_glFramebufferTextureMultisampleMultiviewOVR; diff --git a/src/libretro/libretro-common/glsym/glsym_es3.c b/src/libretro/libretro-common/glsym/glsym_es3.c new file mode 100644 index 000000000..86d46d9e7 --- /dev/null +++ b/src/libretro/libretro-common/glsym/glsym_es3.c @@ -0,0 +1,413 @@ +#include "glsym/glsym.h" +#include +#define SYM(x) { "gl" #x, &(gl##x) } +const struct rglgen_sym_map rglgen_symbol_map[] = { + SYM(BlendBarrierKHR), + SYM(DebugMessageControlKHR), + SYM(DebugMessageInsertKHR), + SYM(DebugMessageCallbackKHR), + SYM(GetDebugMessageLogKHR), + SYM(PushDebugGroupKHR), + SYM(PopDebugGroupKHR), + SYM(ObjectLabelKHR), + SYM(GetObjectLabelKHR), + SYM(ObjectPtrLabelKHR), + SYM(GetObjectPtrLabelKHR), + SYM(GetPointervKHR), + SYM(GetGraphicsResetStatusKHR), + SYM(ReadnPixelsKHR), + SYM(GetnUniformfvKHR), + SYM(GetnUniformivKHR), + SYM(GetnUniformuivKHR), + SYM(EGLImageTargetTexture2DOES), + SYM(EGLImageTargetRenderbufferStorageOES), + SYM(CopyImageSubDataOES), + SYM(EnableiOES), + SYM(DisableiOES), + SYM(BlendEquationiOES), + SYM(BlendEquationSeparateiOES), + SYM(BlendFunciOES), + SYM(BlendFuncSeparateiOES), + SYM(ColorMaskiOES), + SYM(IsEnablediOES), + SYM(DrawElementsBaseVertexOES), + SYM(DrawRangeElementsBaseVertexOES), + SYM(DrawElementsInstancedBaseVertexOES), + SYM(MultiDrawElementsBaseVertexOES), + SYM(FramebufferTextureOES), + SYM(GetProgramBinaryOES), + SYM(ProgramBinaryOES), + SYM(MapBufferOES), + SYM(UnmapBufferOES), + SYM(GetBufferPointervOES), + SYM(PrimitiveBoundingBoxOES), + SYM(MinSampleShadingOES), + SYM(PatchParameteriOES), + SYM(TexImage3DOES), + SYM(TexSubImage3DOES), + SYM(CopyTexSubImage3DOES), + SYM(CompressedTexImage3DOES), + SYM(CompressedTexSubImage3DOES), + SYM(FramebufferTexture3DOES), + SYM(TexParameterIivOES), + SYM(TexParameterIuivOES), + SYM(GetTexParameterIivOES), + SYM(GetTexParameterIuivOES), + SYM(SamplerParameterIivOES), + SYM(SamplerParameterIuivOES), + SYM(GetSamplerParameterIivOES), + SYM(GetSamplerParameterIuivOES), + SYM(TexBufferOES), + SYM(TexBufferRangeOES), + SYM(TexStorage3DMultisampleOES), + SYM(TextureViewOES), + SYM(BindVertexArrayOES), + SYM(DeleteVertexArraysOES), + SYM(GenVertexArraysOES), + SYM(IsVertexArrayOES), + SYM(ViewportArrayvOES), + SYM(ViewportIndexedfOES), + SYM(ViewportIndexedfvOES), + SYM(ScissorArrayvOES), + SYM(ScissorIndexedOES), + SYM(ScissorIndexedvOES), + SYM(DepthRangeArrayfvOES), + SYM(DepthRangeIndexedfOES), + SYM(GetFloati_vOES), + SYM(DrawArraysInstancedBaseInstanceEXT), + SYM(DrawElementsInstancedBaseInstanceEXT), + SYM(DrawElementsInstancedBaseVertexBaseInstanceEXT), + SYM(BindFragDataLocationIndexedEXT), + SYM(BindFragDataLocationEXT), + SYM(GetProgramResourceLocationIndexEXT), + SYM(GetFragDataIndexEXT), + SYM(BufferStorageEXT), + SYM(ClearTexImageEXT), + SYM(ClearTexSubImageEXT), + SYM(CopyImageSubDataEXT), + SYM(LabelObjectEXT), + SYM(GetObjectLabelEXT), + SYM(InsertEventMarkerEXT), + SYM(PushGroupMarkerEXT), + SYM(PopGroupMarkerEXT), + SYM(DiscardFramebufferEXT), + SYM(GenQueriesEXT), + SYM(DeleteQueriesEXT), + SYM(IsQueryEXT), + SYM(BeginQueryEXT), + SYM(EndQueryEXT), + SYM(QueryCounterEXT), + SYM(GetQueryivEXT), + SYM(GetQueryObjectivEXT), + SYM(GetQueryObjectuivEXT), + SYM(GetQueryObjecti64vEXT), + SYM(GetQueryObjectui64vEXT), + SYM(DrawBuffersEXT), + SYM(EnableiEXT), + SYM(DisableiEXT), + SYM(BlendEquationiEXT), + SYM(BlendEquationSeparateiEXT), + SYM(BlendFunciEXT), + SYM(BlendFuncSeparateiEXT), + SYM(ColorMaskiEXT), + SYM(IsEnablediEXT), + SYM(DrawElementsBaseVertexEXT), + SYM(DrawRangeElementsBaseVertexEXT), + SYM(DrawElementsInstancedBaseVertexEXT), + SYM(MultiDrawElementsBaseVertexEXT), + SYM(DrawArraysInstancedEXT), + SYM(DrawElementsInstancedEXT), + SYM(FramebufferTextureEXT), + SYM(VertexAttribDivisorEXT), + SYM(MapBufferRangeEXT), + SYM(FlushMappedBufferRangeEXT), + SYM(MultiDrawArraysEXT), + SYM(MultiDrawElementsEXT), + SYM(MultiDrawArraysIndirectEXT), + SYM(MultiDrawElementsIndirectEXT), + SYM(RenderbufferStorageMultisampleEXT), + SYM(FramebufferTexture2DMultisampleEXT), + SYM(ReadBufferIndexedEXT), + SYM(DrawBuffersIndexedEXT), + SYM(GetIntegeri_vEXT), + SYM(PolygonOffsetClampEXT), + SYM(PrimitiveBoundingBoxEXT), + SYM(RasterSamplesEXT), + SYM(GetGraphicsResetStatusEXT), + SYM(ReadnPixelsEXT), + SYM(GetnUniformfvEXT), + SYM(GetnUniformivEXT), + SYM(ActiveShaderProgramEXT), + SYM(BindProgramPipelineEXT), + SYM(CreateShaderProgramvEXT), + SYM(DeleteProgramPipelinesEXT), + SYM(GenProgramPipelinesEXT), + SYM(GetProgramPipelineInfoLogEXT), + SYM(GetProgramPipelineivEXT), + SYM(IsProgramPipelineEXT), + SYM(ProgramParameteriEXT), + SYM(ProgramUniform1fEXT), + SYM(ProgramUniform1fvEXT), + SYM(ProgramUniform1iEXT), + SYM(ProgramUniform1ivEXT), + SYM(ProgramUniform2fEXT), + SYM(ProgramUniform2fvEXT), + SYM(ProgramUniform2iEXT), + SYM(ProgramUniform2ivEXT), + SYM(ProgramUniform3fEXT), + SYM(ProgramUniform3fvEXT), + SYM(ProgramUniform3iEXT), + SYM(ProgramUniform3ivEXT), + SYM(ProgramUniform4fEXT), + SYM(ProgramUniform4fvEXT), + SYM(ProgramUniform4iEXT), + SYM(ProgramUniform4ivEXT), + SYM(ProgramUniformMatrix2fvEXT), + SYM(ProgramUniformMatrix3fvEXT), + SYM(ProgramUniformMatrix4fvEXT), + SYM(UseProgramStagesEXT), + SYM(ValidateProgramPipelineEXT), + SYM(ProgramUniform1uiEXT), + SYM(ProgramUniform2uiEXT), + SYM(ProgramUniform3uiEXT), + SYM(ProgramUniform4uiEXT), + SYM(ProgramUniform1uivEXT), + SYM(ProgramUniform2uivEXT), + SYM(ProgramUniform3uivEXT), + SYM(ProgramUniform4uivEXT), + SYM(ProgramUniformMatrix2x3fvEXT), + SYM(ProgramUniformMatrix3x2fvEXT), + SYM(ProgramUniformMatrix2x4fvEXT), + SYM(ProgramUniformMatrix4x2fvEXT), + SYM(ProgramUniformMatrix3x4fvEXT), + SYM(ProgramUniformMatrix4x3fvEXT), + SYM(FramebufferPixelLocalStorageSizeEXT), + SYM(GetFramebufferPixelLocalStorageSizeEXT), + SYM(ClearPixelLocalStorageuiEXT), + SYM(TexPageCommitmentEXT), + SYM(PatchParameteriEXT), + SYM(TexParameterIivEXT), + SYM(TexParameterIuivEXT), + SYM(GetTexParameterIivEXT), + SYM(GetTexParameterIuivEXT), + SYM(SamplerParameterIivEXT), + SYM(SamplerParameterIuivEXT), + SYM(GetSamplerParameterIivEXT), + SYM(GetSamplerParameterIuivEXT), + SYM(TexBufferEXT), + SYM(TexBufferRangeEXT), + SYM(TexStorage1DEXT), + SYM(TexStorage2DEXT), + SYM(TexStorage3DEXT), + SYM(TextureStorage1DEXT), + SYM(TextureStorage2DEXT), + SYM(TextureStorage3DEXT), + SYM(TextureViewEXT), + SYM(FramebufferTextureMultiviewOVR), + SYM(FramebufferTextureMultisampleMultiviewOVR), + + { NULL, NULL }, +}; +RGLSYMGLBLENDBARRIERKHRPROC __rglgen_glBlendBarrierKHR; +RGLSYMGLDEBUGMESSAGECONTROLKHRPROC __rglgen_glDebugMessageControlKHR; +RGLSYMGLDEBUGMESSAGEINSERTKHRPROC __rglgen_glDebugMessageInsertKHR; +RGLSYMGLDEBUGMESSAGECALLBACKKHRPROC __rglgen_glDebugMessageCallbackKHR; +RGLSYMGLGETDEBUGMESSAGELOGKHRPROC __rglgen_glGetDebugMessageLogKHR; +RGLSYMGLPUSHDEBUGGROUPKHRPROC __rglgen_glPushDebugGroupKHR; +RGLSYMGLPOPDEBUGGROUPKHRPROC __rglgen_glPopDebugGroupKHR; +RGLSYMGLOBJECTLABELKHRPROC __rglgen_glObjectLabelKHR; +RGLSYMGLGETOBJECTLABELKHRPROC __rglgen_glGetObjectLabelKHR; +RGLSYMGLOBJECTPTRLABELKHRPROC __rglgen_glObjectPtrLabelKHR; +RGLSYMGLGETOBJECTPTRLABELKHRPROC __rglgen_glGetObjectPtrLabelKHR; +RGLSYMGLGETPOINTERVKHRPROC __rglgen_glGetPointervKHR; +RGLSYMGLGETGRAPHICSRESETSTATUSKHRPROC __rglgen_glGetGraphicsResetStatusKHR; +RGLSYMGLREADNPIXELSKHRPROC __rglgen_glReadnPixelsKHR; +RGLSYMGLGETNUNIFORMFVKHRPROC __rglgen_glGetnUniformfvKHR; +RGLSYMGLGETNUNIFORMIVKHRPROC __rglgen_glGetnUniformivKHR; +RGLSYMGLGETNUNIFORMUIVKHRPROC __rglgen_glGetnUniformuivKHR; +RGLSYMGLEGLIMAGETARGETTEXTURE2DOESPROC __rglgen_glEGLImageTargetTexture2DOES; +RGLSYMGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC __rglgen_glEGLImageTargetRenderbufferStorageOES; +RGLSYMGLCOPYIMAGESUBDATAOESPROC __rglgen_glCopyImageSubDataOES; +RGLSYMGLENABLEIOESPROC __rglgen_glEnableiOES; +RGLSYMGLDISABLEIOESPROC __rglgen_glDisableiOES; +RGLSYMGLBLENDEQUATIONIOESPROC __rglgen_glBlendEquationiOES; +RGLSYMGLBLENDEQUATIONSEPARATEIOESPROC __rglgen_glBlendEquationSeparateiOES; +RGLSYMGLBLENDFUNCIOESPROC __rglgen_glBlendFunciOES; +RGLSYMGLBLENDFUNCSEPARATEIOESPROC __rglgen_glBlendFuncSeparateiOES; +RGLSYMGLCOLORMASKIOESPROC __rglgen_glColorMaskiOES; +RGLSYMGLISENABLEDIOESPROC __rglgen_glIsEnablediOES; +RGLSYMGLDRAWELEMENTSBASEVERTEXOESPROC __rglgen_glDrawElementsBaseVertexOES; +RGLSYMGLDRAWRANGEELEMENTSBASEVERTEXOESPROC __rglgen_glDrawRangeElementsBaseVertexOES; +RGLSYMGLDRAWELEMENTSINSTANCEDBASEVERTEXOESPROC __rglgen_glDrawElementsInstancedBaseVertexOES; +RGLSYMGLMULTIDRAWELEMENTSBASEVERTEXOESPROC __rglgen_glMultiDrawElementsBaseVertexOES; +RGLSYMGLFRAMEBUFFERTEXTUREOESPROC __rglgen_glFramebufferTextureOES; +RGLSYMGLGETPROGRAMBINARYOESPROC __rglgen_glGetProgramBinaryOES; +RGLSYMGLPROGRAMBINARYOESPROC __rglgen_glProgramBinaryOES; +RGLSYMGLMAPBUFFEROESPROC __rglgen_glMapBufferOES; +RGLSYMGLUNMAPBUFFEROESPROC __rglgen_glUnmapBufferOES; +RGLSYMGLGETBUFFERPOINTERVOESPROC __rglgen_glGetBufferPointervOES; +RGLSYMGLPRIMITIVEBOUNDINGBOXOESPROC __rglgen_glPrimitiveBoundingBoxOES; +RGLSYMGLMINSAMPLESHADINGOESPROC __rglgen_glMinSampleShadingOES; +RGLSYMGLPATCHPARAMETERIOESPROC __rglgen_glPatchParameteriOES; +RGLSYMGLTEXIMAGE3DOESPROC __rglgen_glTexImage3DOES; +RGLSYMGLTEXSUBIMAGE3DOESPROC __rglgen_glTexSubImage3DOES; +RGLSYMGLCOPYTEXSUBIMAGE3DOESPROC __rglgen_glCopyTexSubImage3DOES; +RGLSYMGLCOMPRESSEDTEXIMAGE3DOESPROC __rglgen_glCompressedTexImage3DOES; +RGLSYMGLCOMPRESSEDTEXSUBIMAGE3DOESPROC __rglgen_glCompressedTexSubImage3DOES; +RGLSYMGLFRAMEBUFFERTEXTURE3DOESPROC __rglgen_glFramebufferTexture3DOES; +RGLSYMGLTEXPARAMETERIIVOESPROC __rglgen_glTexParameterIivOES; +RGLSYMGLTEXPARAMETERIUIVOESPROC __rglgen_glTexParameterIuivOES; +RGLSYMGLGETTEXPARAMETERIIVOESPROC __rglgen_glGetTexParameterIivOES; +RGLSYMGLGETTEXPARAMETERIUIVOESPROC __rglgen_glGetTexParameterIuivOES; +RGLSYMGLSAMPLERPARAMETERIIVOESPROC __rglgen_glSamplerParameterIivOES; +RGLSYMGLSAMPLERPARAMETERIUIVOESPROC __rglgen_glSamplerParameterIuivOES; +RGLSYMGLGETSAMPLERPARAMETERIIVOESPROC __rglgen_glGetSamplerParameterIivOES; +RGLSYMGLGETSAMPLERPARAMETERIUIVOESPROC __rglgen_glGetSamplerParameterIuivOES; +RGLSYMGLTEXBUFFEROESPROC __rglgen_glTexBufferOES; +RGLSYMGLTEXBUFFERRANGEOESPROC __rglgen_glTexBufferRangeOES; +RGLSYMGLTEXSTORAGE3DMULTISAMPLEOESPROC __rglgen_glTexStorage3DMultisampleOES; +RGLSYMGLTEXTUREVIEWOESPROC __rglgen_glTextureViewOES; +RGLSYMGLBINDVERTEXARRAYOESPROC __rglgen_glBindVertexArrayOES; +RGLSYMGLDELETEVERTEXARRAYSOESPROC __rglgen_glDeleteVertexArraysOES; +RGLSYMGLGENVERTEXARRAYSOESPROC __rglgen_glGenVertexArraysOES; +RGLSYMGLISVERTEXARRAYOESPROC __rglgen_glIsVertexArrayOES; +RGLSYMGLVIEWPORTARRAYVOESPROC __rglgen_glViewportArrayvOES; +RGLSYMGLVIEWPORTINDEXEDFOESPROC __rglgen_glViewportIndexedfOES; +RGLSYMGLVIEWPORTINDEXEDFVOESPROC __rglgen_glViewportIndexedfvOES; +RGLSYMGLSCISSORARRAYVOESPROC __rglgen_glScissorArrayvOES; +RGLSYMGLSCISSORINDEXEDOESPROC __rglgen_glScissorIndexedOES; +RGLSYMGLSCISSORINDEXEDVOESPROC __rglgen_glScissorIndexedvOES; +RGLSYMGLDEPTHRANGEARRAYFVOESPROC __rglgen_glDepthRangeArrayfvOES; +RGLSYMGLDEPTHRANGEINDEXEDFOESPROC __rglgen_glDepthRangeIndexedfOES; +RGLSYMGLGETFLOATI_VOESPROC __rglgen_glGetFloati_vOES; +RGLSYMGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC __rglgen_glDrawArraysInstancedBaseInstanceEXT; +RGLSYMGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC __rglgen_glDrawElementsInstancedBaseInstanceEXT; +RGLSYMGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC __rglgen_glDrawElementsInstancedBaseVertexBaseInstanceEXT; +RGLSYMGLBINDFRAGDATALOCATIONINDEXEDEXTPROC __rglgen_glBindFragDataLocationIndexedEXT; +RGLSYMGLBINDFRAGDATALOCATIONEXTPROC __rglgen_glBindFragDataLocationEXT; +RGLSYMGLGETPROGRAMRESOURCELOCATIONINDEXEXTPROC __rglgen_glGetProgramResourceLocationIndexEXT; +RGLSYMGLGETFRAGDATAINDEXEXTPROC __rglgen_glGetFragDataIndexEXT; +RGLSYMGLBUFFERSTORAGEEXTPROC __rglgen_glBufferStorageEXT; +RGLSYMGLCLEARTEXIMAGEEXTPROC __rglgen_glClearTexImageEXT; +RGLSYMGLCLEARTEXSUBIMAGEEXTPROC __rglgen_glClearTexSubImageEXT; +RGLSYMGLCOPYIMAGESUBDATAEXTPROC __rglgen_glCopyImageSubDataEXT; +RGLSYMGLLABELOBJECTEXTPROC __rglgen_glLabelObjectEXT; +RGLSYMGLGETOBJECTLABELEXTPROC __rglgen_glGetObjectLabelEXT; +RGLSYMGLINSERTEVENTMARKEREXTPROC __rglgen_glInsertEventMarkerEXT; +RGLSYMGLPUSHGROUPMARKEREXTPROC __rglgen_glPushGroupMarkerEXT; +RGLSYMGLPOPGROUPMARKEREXTPROC __rglgen_glPopGroupMarkerEXT; +RGLSYMGLDISCARDFRAMEBUFFEREXTPROC __rglgen_glDiscardFramebufferEXT; +RGLSYMGLGENQUERIESEXTPROC __rglgen_glGenQueriesEXT; +RGLSYMGLDELETEQUERIESEXTPROC __rglgen_glDeleteQueriesEXT; +RGLSYMGLISQUERYEXTPROC __rglgen_glIsQueryEXT; +RGLSYMGLBEGINQUERYEXTPROC __rglgen_glBeginQueryEXT; +RGLSYMGLENDQUERYEXTPROC __rglgen_glEndQueryEXT; +RGLSYMGLQUERYCOUNTEREXTPROC __rglgen_glQueryCounterEXT; +RGLSYMGLGETQUERYIVEXTPROC __rglgen_glGetQueryivEXT; +RGLSYMGLGETQUERYOBJECTIVEXTPROC __rglgen_glGetQueryObjectivEXT; +RGLSYMGLGETQUERYOBJECTUIVEXTPROC __rglgen_glGetQueryObjectuivEXT; +RGLSYMGLGETQUERYOBJECTI64VEXTPROC __rglgen_glGetQueryObjecti64vEXT; +RGLSYMGLGETQUERYOBJECTUI64VEXTPROC __rglgen_glGetQueryObjectui64vEXT; +RGLSYMGLDRAWBUFFERSEXTPROC __rglgen_glDrawBuffersEXT; +RGLSYMGLENABLEIEXTPROC __rglgen_glEnableiEXT; +RGLSYMGLDISABLEIEXTPROC __rglgen_glDisableiEXT; +RGLSYMGLBLENDEQUATIONIEXTPROC __rglgen_glBlendEquationiEXT; +RGLSYMGLBLENDEQUATIONSEPARATEIEXTPROC __rglgen_glBlendEquationSeparateiEXT; +RGLSYMGLBLENDFUNCIEXTPROC __rglgen_glBlendFunciEXT; +RGLSYMGLBLENDFUNCSEPARATEIEXTPROC __rglgen_glBlendFuncSeparateiEXT; +RGLSYMGLCOLORMASKIEXTPROC __rglgen_glColorMaskiEXT; +RGLSYMGLISENABLEDIEXTPROC __rglgen_glIsEnablediEXT; +RGLSYMGLDRAWELEMENTSBASEVERTEXEXTPROC __rglgen_glDrawElementsBaseVertexEXT; +RGLSYMGLDRAWRANGEELEMENTSBASEVERTEXEXTPROC __rglgen_glDrawRangeElementsBaseVertexEXT; +RGLSYMGLDRAWELEMENTSINSTANCEDBASEVERTEXEXTPROC __rglgen_glDrawElementsInstancedBaseVertexEXT; +RGLSYMGLMULTIDRAWELEMENTSBASEVERTEXEXTPROC __rglgen_glMultiDrawElementsBaseVertexEXT; +RGLSYMGLDRAWARRAYSINSTANCEDEXTPROC __rglgen_glDrawArraysInstancedEXT; +RGLSYMGLDRAWELEMENTSINSTANCEDEXTPROC __rglgen_glDrawElementsInstancedEXT; +RGLSYMGLFRAMEBUFFERTEXTUREEXTPROC __rglgen_glFramebufferTextureEXT; +RGLSYMGLVERTEXATTRIBDIVISOREXTPROC __rglgen_glVertexAttribDivisorEXT; +RGLSYMGLMAPBUFFERRANGEEXTPROC __rglgen_glMapBufferRangeEXT; +RGLSYMGLFLUSHMAPPEDBUFFERRANGEEXTPROC __rglgen_glFlushMappedBufferRangeEXT; +RGLSYMGLMULTIDRAWARRAYSEXTPROC __rglgen_glMultiDrawArraysEXT; +RGLSYMGLMULTIDRAWELEMENTSEXTPROC __rglgen_glMultiDrawElementsEXT; +RGLSYMGLMULTIDRAWARRAYSINDIRECTEXTPROC __rglgen_glMultiDrawArraysIndirectEXT; +RGLSYMGLMULTIDRAWELEMENTSINDIRECTEXTPROC __rglgen_glMultiDrawElementsIndirectEXT; +RGLSYMGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __rglgen_glRenderbufferStorageMultisampleEXT; +RGLSYMGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC __rglgen_glFramebufferTexture2DMultisampleEXT; +RGLSYMGLREADBUFFERINDEXEDEXTPROC __rglgen_glReadBufferIndexedEXT; +RGLSYMGLDRAWBUFFERSINDEXEDEXTPROC __rglgen_glDrawBuffersIndexedEXT; +RGLSYMGLGETINTEGERI_VEXTPROC __rglgen_glGetIntegeri_vEXT; +RGLSYMGLPOLYGONOFFSETCLAMPEXTPROC __rglgen_glPolygonOffsetClampEXT; +RGLSYMGLPRIMITIVEBOUNDINGBOXEXTPROC __rglgen_glPrimitiveBoundingBoxEXT; +RGLSYMGLRASTERSAMPLESEXTPROC __rglgen_glRasterSamplesEXT; +RGLSYMGLGETGRAPHICSRESETSTATUSEXTPROC __rglgen_glGetGraphicsResetStatusEXT; +RGLSYMGLREADNPIXELSEXTPROC __rglgen_glReadnPixelsEXT; +RGLSYMGLGETNUNIFORMFVEXTPROC __rglgen_glGetnUniformfvEXT; +RGLSYMGLGETNUNIFORMIVEXTPROC __rglgen_glGetnUniformivEXT; +RGLSYMGLACTIVESHADERPROGRAMEXTPROC __rglgen_glActiveShaderProgramEXT; +RGLSYMGLBINDPROGRAMPIPELINEEXTPROC __rglgen_glBindProgramPipelineEXT; +RGLSYMGLCREATESHADERPROGRAMVEXTPROC __rglgen_glCreateShaderProgramvEXT; +RGLSYMGLDELETEPROGRAMPIPELINESEXTPROC __rglgen_glDeleteProgramPipelinesEXT; +RGLSYMGLGENPROGRAMPIPELINESEXTPROC __rglgen_glGenProgramPipelinesEXT; +RGLSYMGLGETPROGRAMPIPELINEINFOLOGEXTPROC __rglgen_glGetProgramPipelineInfoLogEXT; +RGLSYMGLGETPROGRAMPIPELINEIVEXTPROC __rglgen_glGetProgramPipelineivEXT; +RGLSYMGLISPROGRAMPIPELINEEXTPROC __rglgen_glIsProgramPipelineEXT; +RGLSYMGLPROGRAMPARAMETERIEXTPROC __rglgen_glProgramParameteriEXT; +RGLSYMGLPROGRAMUNIFORM1FEXTPROC __rglgen_glProgramUniform1fEXT; +RGLSYMGLPROGRAMUNIFORM1FVEXTPROC __rglgen_glProgramUniform1fvEXT; +RGLSYMGLPROGRAMUNIFORM1IEXTPROC __rglgen_glProgramUniform1iEXT; +RGLSYMGLPROGRAMUNIFORM1IVEXTPROC __rglgen_glProgramUniform1ivEXT; +RGLSYMGLPROGRAMUNIFORM2FEXTPROC __rglgen_glProgramUniform2fEXT; +RGLSYMGLPROGRAMUNIFORM2FVEXTPROC __rglgen_glProgramUniform2fvEXT; +RGLSYMGLPROGRAMUNIFORM2IEXTPROC __rglgen_glProgramUniform2iEXT; +RGLSYMGLPROGRAMUNIFORM2IVEXTPROC __rglgen_glProgramUniform2ivEXT; +RGLSYMGLPROGRAMUNIFORM3FEXTPROC __rglgen_glProgramUniform3fEXT; +RGLSYMGLPROGRAMUNIFORM3FVEXTPROC __rglgen_glProgramUniform3fvEXT; +RGLSYMGLPROGRAMUNIFORM3IEXTPROC __rglgen_glProgramUniform3iEXT; +RGLSYMGLPROGRAMUNIFORM3IVEXTPROC __rglgen_glProgramUniform3ivEXT; +RGLSYMGLPROGRAMUNIFORM4FEXTPROC __rglgen_glProgramUniform4fEXT; +RGLSYMGLPROGRAMUNIFORM4FVEXTPROC __rglgen_glProgramUniform4fvEXT; +RGLSYMGLPROGRAMUNIFORM4IEXTPROC __rglgen_glProgramUniform4iEXT; +RGLSYMGLPROGRAMUNIFORM4IVEXTPROC __rglgen_glProgramUniform4ivEXT; +RGLSYMGLPROGRAMUNIFORMMATRIX2FVEXTPROC __rglgen_glProgramUniformMatrix2fvEXT; +RGLSYMGLPROGRAMUNIFORMMATRIX3FVEXTPROC __rglgen_glProgramUniformMatrix3fvEXT; +RGLSYMGLPROGRAMUNIFORMMATRIX4FVEXTPROC __rglgen_glProgramUniformMatrix4fvEXT; +RGLSYMGLUSEPROGRAMSTAGESEXTPROC __rglgen_glUseProgramStagesEXT; +RGLSYMGLVALIDATEPROGRAMPIPELINEEXTPROC __rglgen_glValidateProgramPipelineEXT; +RGLSYMGLPROGRAMUNIFORM1UIEXTPROC __rglgen_glProgramUniform1uiEXT; +RGLSYMGLPROGRAMUNIFORM2UIEXTPROC __rglgen_glProgramUniform2uiEXT; +RGLSYMGLPROGRAMUNIFORM3UIEXTPROC __rglgen_glProgramUniform3uiEXT; +RGLSYMGLPROGRAMUNIFORM4UIEXTPROC __rglgen_glProgramUniform4uiEXT; +RGLSYMGLPROGRAMUNIFORM1UIVEXTPROC __rglgen_glProgramUniform1uivEXT; +RGLSYMGLPROGRAMUNIFORM2UIVEXTPROC __rglgen_glProgramUniform2uivEXT; +RGLSYMGLPROGRAMUNIFORM3UIVEXTPROC __rglgen_glProgramUniform3uivEXT; +RGLSYMGLPROGRAMUNIFORM4UIVEXTPROC __rglgen_glProgramUniform4uivEXT; +RGLSYMGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC __rglgen_glProgramUniformMatrix2x3fvEXT; +RGLSYMGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC __rglgen_glProgramUniformMatrix3x2fvEXT; +RGLSYMGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC __rglgen_glProgramUniformMatrix2x4fvEXT; +RGLSYMGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC __rglgen_glProgramUniformMatrix4x2fvEXT; +RGLSYMGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC __rglgen_glProgramUniformMatrix3x4fvEXT; +RGLSYMGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC __rglgen_glProgramUniformMatrix4x3fvEXT; +RGLSYMGLFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC __rglgen_glFramebufferPixelLocalStorageSizeEXT; +RGLSYMGLGETFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC __rglgen_glGetFramebufferPixelLocalStorageSizeEXT; +RGLSYMGLCLEARPIXELLOCALSTORAGEUIEXTPROC __rglgen_glClearPixelLocalStorageuiEXT; +RGLSYMGLTEXPAGECOMMITMENTEXTPROC __rglgen_glTexPageCommitmentEXT; +RGLSYMGLPATCHPARAMETERIEXTPROC __rglgen_glPatchParameteriEXT; +RGLSYMGLTEXPARAMETERIIVEXTPROC __rglgen_glTexParameterIivEXT; +RGLSYMGLTEXPARAMETERIUIVEXTPROC __rglgen_glTexParameterIuivEXT; +RGLSYMGLGETTEXPARAMETERIIVEXTPROC __rglgen_glGetTexParameterIivEXT; +RGLSYMGLGETTEXPARAMETERIUIVEXTPROC __rglgen_glGetTexParameterIuivEXT; +RGLSYMGLSAMPLERPARAMETERIIVEXTPROC __rglgen_glSamplerParameterIivEXT; +RGLSYMGLSAMPLERPARAMETERIUIVEXTPROC __rglgen_glSamplerParameterIuivEXT; +RGLSYMGLGETSAMPLERPARAMETERIIVEXTPROC __rglgen_glGetSamplerParameterIivEXT; +RGLSYMGLGETSAMPLERPARAMETERIUIVEXTPROC __rglgen_glGetSamplerParameterIuivEXT; +RGLSYMGLTEXBUFFEREXTPROC __rglgen_glTexBufferEXT; +RGLSYMGLTEXBUFFERRANGEEXTPROC __rglgen_glTexBufferRangeEXT; +RGLSYMGLTEXSTORAGE1DEXTPROC __rglgen_glTexStorage1DEXT; +RGLSYMGLTEXSTORAGE2DEXTPROC __rglgen_glTexStorage2DEXT; +RGLSYMGLTEXSTORAGE3DEXTPROC __rglgen_glTexStorage3DEXT; +RGLSYMGLTEXTURESTORAGE1DEXTPROC __rglgen_glTextureStorage1DEXT; +RGLSYMGLTEXTURESTORAGE2DEXTPROC __rglgen_glTextureStorage2DEXT; +RGLSYMGLTEXTURESTORAGE3DEXTPROC __rglgen_glTextureStorage3DEXT; +RGLSYMGLTEXTUREVIEWEXTPROC __rglgen_glTextureViewEXT; +RGLSYMGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC __rglgen_glFramebufferTextureMultiviewOVR; +RGLSYMGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC __rglgen_glFramebufferTextureMultisampleMultiviewOVR; diff --git a/src/libretro/libretro-common/glsym/glsym_gl.c b/src/libretro/libretro-common/glsym/glsym_gl.c new file mode 100644 index 000000000..a5ce04e8e --- /dev/null +++ b/src/libretro/libretro-common/glsym/glsym_gl.c @@ -0,0 +1,2541 @@ +/* Copyright (C) 2010-2020 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this libretro SDK code part (glsym). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * 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: + * + * 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, + * 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. + */ + +#include + +#include + +#define SYM(x) { "gl" #x, (void*)&(gl##x) } + +const struct rglgen_sym_map rglgen_symbol_map[] = { +#ifdef HAVE_LIBNX + SYM(ClearIndex), + SYM(ClearColor), + SYM(Clear), + SYM(IndexMask), + SYM(ColorMask), + SYM(AlphaFunc), + SYM(BlendFunc), + SYM(LogicOp), + SYM(CullFace), + SYM(FrontFace), + SYM(PointSize), + SYM(LineWidth), + SYM(LineStipple), + SYM(PolygonMode), + SYM(PolygonOffset), + SYM(PolygonStipple), + SYM(GetPolygonStipple), + SYM(EdgeFlag), + SYM(EdgeFlagv), + SYM(Scissor), + SYM(ClipPlane), + SYM(GetClipPlane), + SYM(DrawBuffer), + SYM(ReadBuffer), + SYM(Enable), + SYM(Disable), + SYM(IsEnabled), + SYM(EnableClientState), + SYM(DisableClientState), + SYM(GetBooleanv), + SYM(GetDoublev), + SYM(GetFloatv), + SYM(GetIntegerv), + SYM(PushAttrib), + SYM(PopAttrib), + SYM(PushClientAttrib), + SYM(PopClientAttrib), + SYM(RenderMode), + SYM(GetError), + SYM(GetString), + SYM(Finish), + SYM(Flush), + SYM(Hint), + SYM(ClearDepth), + SYM(DepthFunc), + SYM(DepthMask), + SYM(DepthRange), + SYM(ClearAccum), + SYM(Accum), + SYM(MatrixMode), + SYM(Ortho), + SYM(Frustum), + SYM(Viewport), + SYM(PushMatrix), + SYM(PopMatrix), + SYM(LoadIdentity), + SYM(LoadMatrixd), + SYM(LoadMatrixf), + SYM(MultMatrixd), + SYM(MultMatrixf), + SYM(Rotated), + SYM(Rotatef), + SYM(Scaled), + SYM(Scalef), + SYM(Translated), + SYM(Translatef), + SYM(IsList), + SYM(DeleteLists), + SYM(GenLists), + SYM(NewList), + SYM(EndList), + SYM(CallList), + SYM(CallLists), + SYM(ListBase), + SYM(Begin), + SYM(End), + SYM(Vertex2d), + SYM(Vertex2f), + SYM(Vertex2i), + SYM(Vertex2s), + SYM(Vertex3d), + SYM(Vertex3f), + SYM(Vertex3i), + SYM(Vertex3s), + SYM(Vertex4d), + SYM(Vertex4f), + SYM(Vertex4i), + SYM(Vertex4s), + SYM(Vertex2dv), + SYM(Vertex2fv), + SYM(Vertex2iv), + SYM(Vertex2sv), + SYM(Vertex3dv), + SYM(Vertex3fv), + SYM(Vertex3iv), + SYM(Vertex3sv), + SYM(Vertex4dv), + SYM(Vertex4fv), + SYM(Vertex4iv), + SYM(Vertex4sv), + SYM(Normal3b), + SYM(Normal3d), + SYM(Normal3f), + SYM(Normal3i), + SYM(Normal3s), + SYM(Normal3bv), + SYM(Normal3dv), + SYM(Normal3fv), + SYM(Normal3iv), + SYM(Normal3sv), + SYM(Indexd), + SYM(Indexf), + SYM(Indexi), + SYM(Indexs), + SYM(Indexub), + SYM(Indexdv), + SYM(Indexfv), + SYM(Indexiv), + SYM(Indexsv), + SYM(Indexubv), + SYM(Color3b), + SYM(Color3d), + SYM(Color3f), + SYM(Color3i), + SYM(Color3s), + SYM(Color3ub), + SYM(Color3ui), + SYM(Color3us), + SYM(Color4b), + SYM(Color4d), + SYM(Color4f), + SYM(Color4i), + SYM(Color4s), + SYM(Color4ub), + SYM(Color4ui), + SYM(Color4us), + SYM(Color3bv), + SYM(Color3dv), + SYM(Color3fv), + SYM(Color3iv), + SYM(Color3sv), + SYM(Color3ubv), + SYM(Color3uiv), + SYM(Color3usv), + SYM(Color4bv), + SYM(Color4dv), + SYM(Color4fv), + SYM(Color4iv), + SYM(Color4sv), + SYM(Color4ubv), + SYM(Color4uiv), + SYM(Color4usv), + SYM(TexCoord1d), + SYM(TexCoord1f), + SYM(TexCoord1i), + SYM(TexCoord1s), + SYM(TexCoord2d), + SYM(TexCoord2f), + SYM(TexCoord2i), + SYM(TexCoord2s), + SYM(TexCoord3d), + SYM(TexCoord3f), + SYM(TexCoord3i), + SYM(TexCoord3s), + SYM(TexCoord4d), + SYM(TexCoord4f), + SYM(TexCoord4i), + SYM(TexCoord4s), + SYM(TexCoord1dv), + SYM(TexCoord1fv), + SYM(TexCoord1iv), + SYM(TexCoord1sv), + SYM(TexCoord2dv), + SYM(TexCoord2fv), + SYM(TexCoord2iv), + SYM(TexCoord2sv), + SYM(TexCoord3dv), + SYM(TexCoord3fv), + SYM(TexCoord3iv), + SYM(TexCoord3sv), + SYM(TexCoord4dv), + SYM(TexCoord4fv), + SYM(TexCoord4iv), + SYM(TexCoord4sv), + SYM(RasterPos2d), + SYM(RasterPos2f), + SYM(RasterPos2i), + SYM(RasterPos2s), + SYM(RasterPos3d), + SYM(RasterPos3f), + SYM(RasterPos3i), + SYM(RasterPos3s), + SYM(RasterPos4d), + SYM(RasterPos4f), + SYM(RasterPos4i), + SYM(RasterPos4s), + SYM(RasterPos2dv), + SYM(RasterPos2fv), + SYM(RasterPos2iv), + SYM(RasterPos2sv), + SYM(RasterPos3dv), + SYM(RasterPos3fv), + SYM(RasterPos3iv), + SYM(RasterPos3sv), + SYM(RasterPos4dv), + SYM(RasterPos4fv), + SYM(RasterPos4iv), + SYM(RasterPos4sv), + SYM(Rectd), + SYM(Rectf), + SYM(Recti), + SYM(Rects), + SYM(Rectdv), + SYM(Rectfv), + SYM(Rectiv), + SYM(Rectsv), + SYM(VertexPointer), + SYM(NormalPointer), + SYM(ColorPointer), + SYM(IndexPointer), + SYM(TexCoordPointer), + SYM(EdgeFlagPointer), + SYM(GetPointerv), + SYM(ArrayElement), + SYM(DrawArrays), + SYM(DrawElements), + SYM(InterleavedArrays), + SYM(ShadeModel), + SYM(Lightf), + SYM(Lighti), + SYM(Lightfv), + SYM(Lightiv), + SYM(GetLightfv), + SYM(GetLightiv), + SYM(LightModelf), + SYM(LightModeli), + SYM(LightModelfv), + SYM(LightModeliv), + SYM(Materialf), + SYM(Materiali), + SYM(Materialfv), + SYM(Materialiv), + SYM(GetMaterialfv), + SYM(GetMaterialiv), + SYM(ColorMaterial), + SYM(PixelZoom), + SYM(PixelStoref), + SYM(PixelStorei), + SYM(PixelTransferf), + SYM(PixelTransferi), + SYM(PixelMapfv), + SYM(PixelMapuiv), + SYM(PixelMapusv), + SYM(GetPixelMapfv), + SYM(GetPixelMapuiv), + SYM(GetPixelMapusv), + SYM(Bitmap), + SYM(ReadPixels), + SYM(DrawPixels), + SYM(CopyPixels), + SYM(StencilFunc), + SYM(StencilMask), + SYM(StencilOp), + SYM(ClearStencil), + SYM(TexGend), + SYM(TexGenf), + SYM(TexGeni), + SYM(TexGendv), + SYM(TexGenfv), + SYM(TexGeniv), + SYM(GetTexGendv), + SYM(GetTexGenfv), + SYM(GetTexGeniv), + SYM(TexEnvf), + SYM(TexEnvi), + SYM(TexEnvfv), + SYM(TexEnviv), + SYM(GetTexEnvfv), + SYM(GetTexEnviv), + SYM(TexParameterf), + SYM(TexParameteri), + SYM(TexParameterfv), + SYM(TexParameteriv), + SYM(GetTexParameterfv), + SYM(GetTexParameteriv), + SYM(GetTexLevelParameterfv), + SYM(GetTexLevelParameteriv), + SYM(TexImage1D), + SYM(TexImage2D), + SYM(GetTexImage), + SYM(GenTextures), + SYM(DeleteTextures), + SYM(BindTexture), + SYM(PrioritizeTextures), + SYM(AreTexturesResident), + SYM(IsTexture), + SYM(TexSubImage1D), + SYM(TexSubImage2D), + SYM(CopyTexImage1D), + SYM(CopyTexImage2D), + SYM(CopyTexSubImage1D), + SYM(CopyTexSubImage2D), + SYM(Map1d), + SYM(Map1f), + SYM(Map2d), + SYM(Map2f), + SYM(GetMapdv), + SYM(GetMapfv), + SYM(GetMapiv), + SYM(EvalCoord1d), + SYM(EvalCoord1f), + SYM(EvalCoord1dv), + SYM(EvalCoord1fv), + SYM(EvalCoord2d), + SYM(EvalCoord2f), + SYM(EvalCoord2dv), + SYM(EvalCoord2fv), + SYM(MapGrid1d), + SYM(MapGrid1f), + SYM(MapGrid2d), + SYM(MapGrid2f), + SYM(EvalPoint1), + SYM(EvalPoint2), + SYM(EvalMesh1), + SYM(EvalMesh2), + SYM(Fogf), + SYM(Fogi), + SYM(Fogfv), + SYM(Fogiv), + SYM(FeedbackBuffer), + SYM(PassThrough), + SYM(SelectBuffer), + SYM(InitNames), + SYM(LoadName), + SYM(PushName), + SYM(PopName), + SYM(DrawRangeElements), + SYM(TexImage3D), + SYM(TexSubImage3D), + SYM(CopyTexSubImage3D), + SYM(ColorTable), + SYM(ColorSubTable), + SYM(ColorTableParameteriv), + SYM(ColorTableParameterfv), + SYM(CopyColorSubTable), + SYM(CopyColorTable), + SYM(GetColorTable), + SYM(GetColorTableParameterfv), + SYM(GetColorTableParameteriv), + SYM(BlendEquation), + SYM(BlendColor), + SYM(Histogram), + SYM(ResetHistogram), + SYM(GetHistogram), + SYM(GetHistogramParameterfv), + SYM(GetHistogramParameteriv), + SYM(Minmax), + SYM(ResetMinmax), + SYM(GetMinmax), + SYM(GetMinmaxParameterfv), + SYM(GetMinmaxParameteriv), + SYM(ConvolutionFilter1D), + SYM(ConvolutionFilter2D), + SYM(ConvolutionParameterf), + SYM(ConvolutionParameterfv), + SYM(ConvolutionParameteri), + SYM(ConvolutionParameteriv), + SYM(CopyConvolutionFilter1D), + SYM(CopyConvolutionFilter2D), + SYM(GetConvolutionFilter), + SYM(GetConvolutionParameterfv), + SYM(GetConvolutionParameteriv), + SYM(SeparableFilter2D), + SYM(GetSeparableFilter), + SYM(ActiveTexture), + SYM(ClientActiveTexture), + SYM(CompressedTexImage1D), + SYM(CompressedTexImage2D), + SYM(CompressedTexImage3D), + SYM(CompressedTexSubImage1D), + SYM(CompressedTexSubImage2D), + SYM(CompressedTexSubImage3D), + SYM(GetCompressedTexImage), + SYM(MultiTexCoord1d), + SYM(MultiTexCoord1dv), + SYM(MultiTexCoord1f), + SYM(MultiTexCoord1fv), + SYM(MultiTexCoord1i), + SYM(MultiTexCoord1iv), + SYM(MultiTexCoord1s), + SYM(MultiTexCoord1sv), + SYM(MultiTexCoord2d), + SYM(MultiTexCoord2dv), + SYM(MultiTexCoord2f), + SYM(MultiTexCoord2fv), + SYM(MultiTexCoord2i), + SYM(MultiTexCoord2iv), + SYM(MultiTexCoord2s), + SYM(MultiTexCoord2sv), + SYM(MultiTexCoord3d), + SYM(MultiTexCoord3dv), + SYM(MultiTexCoord3f), + SYM(MultiTexCoord3fv), + SYM(MultiTexCoord3i), + SYM(MultiTexCoord3iv), + SYM(MultiTexCoord3s), + SYM(MultiTexCoord3sv), + SYM(MultiTexCoord4d), + SYM(MultiTexCoord4dv), + SYM(MultiTexCoord4f), + SYM(MultiTexCoord4fv), + SYM(MultiTexCoord4i), + SYM(MultiTexCoord4iv), + SYM(MultiTexCoord4s), + SYM(MultiTexCoord4sv), + SYM(LoadTransposeMatrixd), + SYM(LoadTransposeMatrixf), + SYM(MultTransposeMatrixd), + SYM(MultTransposeMatrixf), + SYM(SampleCoverage), + SYM(ActiveTextureARB), + SYM(ClientActiveTextureARB), + SYM(MultiTexCoord1dARB), + SYM(MultiTexCoord1dvARB), + SYM(MultiTexCoord1fARB), + SYM(MultiTexCoord1fvARB), + SYM(MultiTexCoord1iARB), + SYM(MultiTexCoord1ivARB), + SYM(MultiTexCoord1sARB), + SYM(MultiTexCoord1svARB), + SYM(MultiTexCoord2dARB), + SYM(MultiTexCoord2dvARB), + SYM(MultiTexCoord2fARB), + SYM(MultiTexCoord2fvARB), + SYM(MultiTexCoord2iARB), + SYM(MultiTexCoord2ivARB), + SYM(MultiTexCoord2sARB), + SYM(MultiTexCoord2svARB), + SYM(MultiTexCoord3dARB), + SYM(MultiTexCoord3dvARB), + SYM(MultiTexCoord3fARB), + SYM(MultiTexCoord3fvARB), + SYM(MultiTexCoord3iARB), + SYM(MultiTexCoord3ivARB), + SYM(MultiTexCoord3sARB), + SYM(MultiTexCoord3svARB), + SYM(MultiTexCoord4dARB), + SYM(MultiTexCoord4dvARB), + SYM(MultiTexCoord4fARB), + SYM(MultiTexCoord4fvARB), + SYM(MultiTexCoord4iARB), + SYM(MultiTexCoord4ivARB), + SYM(MultiTexCoord4sARB), + SYM(MultiTexCoord4svARB), + SYM(EGLImageTargetTexture2DOES), + SYM(EGLImageTargetRenderbufferStorageOES), +#endif + + SYM(DrawRangeElements), + SYM(TexImage3D), + SYM(TexSubImage3D), + SYM(CopyTexSubImage3D), + SYM(ActiveTexture), + SYM(SampleCoverage), + SYM(CompressedTexImage3D), + SYM(CompressedTexImage2D), + SYM(CompressedTexImage1D), + SYM(CompressedTexSubImage3D), + SYM(CompressedTexSubImage2D), + SYM(CompressedTexSubImage1D), + SYM(GetCompressedTexImage), + SYM(ClientActiveTexture), + SYM(MultiTexCoord1d), + SYM(MultiTexCoord1dv), + SYM(MultiTexCoord1f), + SYM(MultiTexCoord1fv), + SYM(MultiTexCoord1i), + SYM(MultiTexCoord1iv), + SYM(MultiTexCoord1s), + SYM(MultiTexCoord1sv), + SYM(MultiTexCoord2d), + SYM(MultiTexCoord2dv), + SYM(MultiTexCoord2f), + SYM(MultiTexCoord2fv), + SYM(MultiTexCoord2i), + SYM(MultiTexCoord2iv), + SYM(MultiTexCoord2s), + SYM(MultiTexCoord2sv), + SYM(MultiTexCoord3d), + SYM(MultiTexCoord3dv), + SYM(MultiTexCoord3f), + SYM(MultiTexCoord3fv), + SYM(MultiTexCoord3i), + SYM(MultiTexCoord3iv), + SYM(MultiTexCoord3s), + SYM(MultiTexCoord3sv), + SYM(MultiTexCoord4d), + SYM(MultiTexCoord4dv), + SYM(MultiTexCoord4f), + SYM(MultiTexCoord4fv), + SYM(MultiTexCoord4i), + SYM(MultiTexCoord4iv), + SYM(MultiTexCoord4s), + SYM(MultiTexCoord4sv), + SYM(LoadTransposeMatrixf), + SYM(LoadTransposeMatrixd), + SYM(MultTransposeMatrixf), + SYM(MultTransposeMatrixd), + SYM(BlendFuncSeparate), + SYM(MultiDrawArrays), + SYM(MultiDrawElements), + SYM(PointParameterf), + SYM(PointParameterfv), + SYM(PointParameteri), + SYM(PointParameteriv), + SYM(FogCoordf), + SYM(FogCoordfv), + SYM(FogCoordd), + SYM(FogCoorddv), + SYM(FogCoordPointer), + SYM(SecondaryColor3b), + SYM(SecondaryColor3bv), + SYM(SecondaryColor3d), + SYM(SecondaryColor3dv), + SYM(SecondaryColor3f), + SYM(SecondaryColor3fv), + SYM(SecondaryColor3i), + SYM(SecondaryColor3iv), + SYM(SecondaryColor3s), + SYM(SecondaryColor3sv), + SYM(SecondaryColor3ub), + SYM(SecondaryColor3ubv), + SYM(SecondaryColor3ui), + SYM(SecondaryColor3uiv), + SYM(SecondaryColor3us), + SYM(SecondaryColor3usv), + SYM(SecondaryColorPointer), + SYM(WindowPos2d), + SYM(WindowPos2dv), + SYM(WindowPos2f), + SYM(WindowPos2fv), + SYM(WindowPos2i), + SYM(WindowPos2iv), + SYM(WindowPos2s), + SYM(WindowPos2sv), + SYM(WindowPos3d), + SYM(WindowPos3dv), + SYM(WindowPos3f), + SYM(WindowPos3fv), + SYM(WindowPos3i), + SYM(WindowPos3iv), + SYM(WindowPos3s), + SYM(WindowPos3sv), + SYM(BlendColor), + SYM(BlendEquation), + SYM(GenQueries), + SYM(DeleteQueries), + SYM(IsQuery), + SYM(BeginQuery), + SYM(EndQuery), + SYM(GetQueryiv), + SYM(GetQueryObjectiv), + SYM(GetQueryObjectuiv), + SYM(BindBuffer), + SYM(DeleteBuffers), + SYM(GenBuffers), + SYM(IsBuffer), + SYM(BufferData), + SYM(BufferSubData), + SYM(GetBufferSubData), + SYM(MapBuffer), + SYM(UnmapBuffer), + SYM(GetBufferParameteriv), + SYM(GetBufferPointerv), + SYM(BlendEquationSeparate), + SYM(DrawBuffers), + SYM(StencilOpSeparate), + SYM(StencilFuncSeparate), + SYM(StencilMaskSeparate), + SYM(AttachShader), + SYM(BindAttribLocation), + SYM(CompileShader), + SYM(CreateProgram), + SYM(CreateShader), + SYM(DeleteProgram), + SYM(DeleteShader), + SYM(DetachShader), + SYM(DisableVertexAttribArray), + SYM(EnableVertexAttribArray), + SYM(GetActiveAttrib), + SYM(GetActiveUniform), + SYM(GetAttachedShaders), + SYM(GetAttribLocation), + SYM(GetProgramiv), + SYM(GetProgramInfoLog), + SYM(GetShaderiv), + SYM(GetShaderInfoLog), + SYM(GetShaderSource), + SYM(GetUniformLocation), + SYM(GetUniformfv), + SYM(GetUniformiv), + SYM(GetVertexAttribdv), + SYM(GetVertexAttribfv), + SYM(GetVertexAttribiv), + SYM(GetVertexAttribPointerv), + SYM(IsProgram), + SYM(IsShader), + SYM(LinkProgram), + SYM(ShaderSource), + SYM(UseProgram), + SYM(Uniform1f), + SYM(Uniform2f), + SYM(Uniform3f), + SYM(Uniform4f), + SYM(Uniform1i), + SYM(Uniform2i), + SYM(Uniform3i), + SYM(Uniform4i), + SYM(Uniform1fv), + SYM(Uniform2fv), + SYM(Uniform3fv), + SYM(Uniform4fv), + SYM(Uniform1iv), + SYM(Uniform2iv), + SYM(Uniform3iv), + SYM(Uniform4iv), + SYM(UniformMatrix2fv), + SYM(UniformMatrix3fv), + SYM(UniformMatrix4fv), + SYM(ValidateProgram), + SYM(VertexAttrib1d), + SYM(VertexAttrib1dv), + SYM(VertexAttrib1f), + SYM(VertexAttrib1fv), + SYM(VertexAttrib1s), + SYM(VertexAttrib1sv), + SYM(VertexAttrib2d), + SYM(VertexAttrib2dv), + SYM(VertexAttrib2f), + SYM(VertexAttrib2fv), + SYM(VertexAttrib2s), + SYM(VertexAttrib2sv), + SYM(VertexAttrib3d), + SYM(VertexAttrib3dv), + SYM(VertexAttrib3f), + SYM(VertexAttrib3fv), + SYM(VertexAttrib3s), + SYM(VertexAttrib3sv), + SYM(VertexAttrib4Nbv), + SYM(VertexAttrib4Niv), + SYM(VertexAttrib4Nsv), + SYM(VertexAttrib4Nub), + SYM(VertexAttrib4Nubv), + SYM(VertexAttrib4Nuiv), + SYM(VertexAttrib4Nusv), + SYM(VertexAttrib4bv), + SYM(VertexAttrib4d), + SYM(VertexAttrib4dv), + SYM(VertexAttrib4f), + SYM(VertexAttrib4fv), + SYM(VertexAttrib4iv), + SYM(VertexAttrib4s), + SYM(VertexAttrib4sv), + SYM(VertexAttrib4ubv), + SYM(VertexAttrib4uiv), + SYM(VertexAttrib4usv), + SYM(VertexAttribPointer), + SYM(UniformMatrix2x3fv), + SYM(UniformMatrix3x2fv), + SYM(UniformMatrix2x4fv), + SYM(UniformMatrix4x2fv), + SYM(UniformMatrix3x4fv), + SYM(UniformMatrix4x3fv), + SYM(ColorMaski), + SYM(GetBooleani_v), + SYM(GetIntegeri_v), + SYM(Enablei), + SYM(Disablei), + SYM(IsEnabledi), + SYM(BeginTransformFeedback), + SYM(EndTransformFeedback), + SYM(BindBufferRange), + SYM(BindBufferBase), + SYM(TransformFeedbackVaryings), + SYM(GetTransformFeedbackVarying), + SYM(ClampColor), + SYM(BeginConditionalRender), + SYM(EndConditionalRender), + SYM(VertexAttribIPointer), + SYM(GetVertexAttribIiv), + SYM(GetVertexAttribIuiv), + SYM(VertexAttribI1i), + SYM(VertexAttribI2i), + SYM(VertexAttribI3i), + SYM(VertexAttribI4i), + SYM(VertexAttribI1ui), + SYM(VertexAttribI2ui), + SYM(VertexAttribI3ui), + SYM(VertexAttribI4ui), + SYM(VertexAttribI1iv), + SYM(VertexAttribI2iv), + SYM(VertexAttribI3iv), + SYM(VertexAttribI4iv), + SYM(VertexAttribI1uiv), + SYM(VertexAttribI2uiv), + SYM(VertexAttribI3uiv), + SYM(VertexAttribI4uiv), + SYM(VertexAttribI4bv), + SYM(VertexAttribI4sv), + SYM(VertexAttribI4ubv), + SYM(VertexAttribI4usv), + SYM(GetUniformuiv), + SYM(BindFragDataLocation), + SYM(GetFragDataLocation), + SYM(Uniform1ui), + SYM(Uniform2ui), + SYM(Uniform3ui), + SYM(Uniform4ui), + SYM(Uniform1uiv), + SYM(Uniform2uiv), + SYM(Uniform3uiv), + SYM(Uniform4uiv), + SYM(TexParameterIiv), + SYM(TexParameterIuiv), + SYM(GetTexParameterIiv), + SYM(GetTexParameterIuiv), + SYM(ClearBufferiv), + SYM(ClearBufferuiv), + SYM(ClearBufferfv), + SYM(ClearBufferfi), + SYM(GetStringi), + SYM(IsRenderbuffer), + SYM(BindRenderbuffer), + SYM(DeleteRenderbuffers), + SYM(GenRenderbuffers), + SYM(RenderbufferStorage), + SYM(GetRenderbufferParameteriv), + SYM(IsFramebuffer), + SYM(BindFramebuffer), + SYM(DeleteFramebuffers), + SYM(GenFramebuffers), + SYM(CheckFramebufferStatus), + SYM(FramebufferTexture1D), + SYM(FramebufferTexture2D), + SYM(FramebufferTexture3D), + SYM(FramebufferRenderbuffer), + SYM(GetFramebufferAttachmentParameteriv), + SYM(GenerateMipmap), + SYM(BlitFramebuffer), + SYM(RenderbufferStorageMultisample), + SYM(FramebufferTextureLayer), + SYM(MapBufferRange), + SYM(FlushMappedBufferRange), + SYM(BindVertexArray), + SYM(DeleteVertexArrays), + SYM(GenVertexArrays), + SYM(IsVertexArray), + SYM(DrawArraysInstanced), + SYM(DrawElementsInstanced), + SYM(TexBuffer), + SYM(PrimitiveRestartIndex), + SYM(CopyBufferSubData), + SYM(GetUniformIndices), + SYM(GetActiveUniformsiv), + SYM(GetActiveUniformName), + SYM(GetUniformBlockIndex), + SYM(GetActiveUniformBlockiv), + SYM(GetActiveUniformBlockName), + SYM(UniformBlockBinding), + SYM(DrawElementsBaseVertex), + SYM(DrawRangeElementsBaseVertex), + SYM(DrawElementsInstancedBaseVertex), + SYM(MultiDrawElementsBaseVertex), + SYM(ProvokingVertex), + SYM(FenceSync), + SYM(IsSync), + SYM(DeleteSync), + SYM(ClientWaitSync), + SYM(WaitSync), + SYM(GetInteger64v), + SYM(GetSynciv), + SYM(GetInteger64i_v), + SYM(GetBufferParameteri64v), + SYM(FramebufferTexture), + SYM(TexImage2DMultisample), + SYM(TexImage3DMultisample), + SYM(GetMultisamplefv), + SYM(SampleMaski), + SYM(BindFragDataLocationIndexed), + SYM(GetFragDataIndex), + SYM(GenSamplers), + SYM(DeleteSamplers), + SYM(IsSampler), + SYM(BindSampler), + SYM(SamplerParameteri), + SYM(SamplerParameteriv), + SYM(SamplerParameterf), + SYM(SamplerParameterfv), + SYM(SamplerParameterIiv), + SYM(SamplerParameterIuiv), + SYM(GetSamplerParameteriv), + SYM(GetSamplerParameterIiv), + SYM(GetSamplerParameterfv), + SYM(GetSamplerParameterIuiv), + SYM(QueryCounter), + SYM(GetQueryObjecti64v), + SYM(GetQueryObjectui64v), + SYM(VertexAttribDivisor), + SYM(VertexAttribP1ui), + SYM(VertexAttribP1uiv), + SYM(VertexAttribP2ui), + SYM(VertexAttribP2uiv), + SYM(VertexAttribP3ui), + SYM(VertexAttribP3uiv), + SYM(VertexAttribP4ui), + SYM(VertexAttribP4uiv), + SYM(VertexP2ui), + SYM(VertexP2uiv), + SYM(VertexP3ui), + SYM(VertexP3uiv), + SYM(VertexP4ui), + SYM(VertexP4uiv), + SYM(TexCoordP1ui), + SYM(TexCoordP1uiv), + SYM(TexCoordP2ui), + SYM(TexCoordP2uiv), + SYM(TexCoordP3ui), + SYM(TexCoordP3uiv), + SYM(TexCoordP4ui), + SYM(TexCoordP4uiv), + SYM(MultiTexCoordP1ui), + SYM(MultiTexCoordP1uiv), + SYM(MultiTexCoordP2ui), + SYM(MultiTexCoordP2uiv), + SYM(MultiTexCoordP3ui), + SYM(MultiTexCoordP3uiv), + SYM(MultiTexCoordP4ui), + SYM(MultiTexCoordP4uiv), + SYM(NormalP3ui), + SYM(NormalP3uiv), + SYM(ColorP3ui), + SYM(ColorP3uiv), + SYM(ColorP4ui), + SYM(ColorP4uiv), + SYM(SecondaryColorP3ui), + SYM(SecondaryColorP3uiv), + SYM(MinSampleShading), + SYM(BlendEquationi), + SYM(BlendEquationSeparatei), + SYM(BlendFunci), + SYM(BlendFuncSeparatei), + SYM(DrawArraysIndirect), + SYM(DrawElementsIndirect), + SYM(Uniform1d), + SYM(Uniform2d), + SYM(Uniform3d), + SYM(Uniform4d), + SYM(Uniform1dv), + SYM(Uniform2dv), + SYM(Uniform3dv), + SYM(Uniform4dv), + SYM(UniformMatrix2dv), + SYM(UniformMatrix3dv), + SYM(UniformMatrix4dv), + SYM(UniformMatrix2x3dv), + SYM(UniformMatrix2x4dv), + SYM(UniformMatrix3x2dv), + SYM(UniformMatrix3x4dv), + SYM(UniformMatrix4x2dv), + SYM(UniformMatrix4x3dv), + SYM(GetUniformdv), + SYM(GetSubroutineUniformLocation), + SYM(GetSubroutineIndex), + SYM(GetActiveSubroutineUniformiv), + SYM(GetActiveSubroutineUniformName), + SYM(GetActiveSubroutineName), + SYM(UniformSubroutinesuiv), + SYM(GetUniformSubroutineuiv), + SYM(GetProgramStageiv), + SYM(PatchParameteri), + SYM(PatchParameterfv), + SYM(BindTransformFeedback), + SYM(DeleteTransformFeedbacks), + SYM(GenTransformFeedbacks), + SYM(IsTransformFeedback), + SYM(PauseTransformFeedback), + SYM(ResumeTransformFeedback), + SYM(DrawTransformFeedback), + SYM(DrawTransformFeedbackStream), + SYM(BeginQueryIndexed), + SYM(EndQueryIndexed), + SYM(GetQueryIndexediv), + SYM(ReleaseShaderCompiler), + SYM(ShaderBinary), + SYM(GetShaderPrecisionFormat), + SYM(DepthRangef), + SYM(ClearDepthf), + SYM(GetProgramBinary), + SYM(ProgramBinary), + SYM(ProgramParameteri), + SYM(UseProgramStages), + SYM(ActiveShaderProgram), + SYM(CreateShaderProgramv), + SYM(BindProgramPipeline), + SYM(DeleteProgramPipelines), + SYM(GenProgramPipelines), + SYM(IsProgramPipeline), + SYM(GetProgramPipelineiv), + SYM(ProgramUniform1i), + SYM(ProgramUniform1iv), + SYM(ProgramUniform1f), + SYM(ProgramUniform1fv), + SYM(ProgramUniform1d), + SYM(ProgramUniform1dv), + SYM(ProgramUniform1ui), + SYM(ProgramUniform1uiv), + SYM(ProgramUniform2i), + SYM(ProgramUniform2iv), + SYM(ProgramUniform2f), + SYM(ProgramUniform2fv), + SYM(ProgramUniform2d), + SYM(ProgramUniform2dv), + SYM(ProgramUniform2ui), + SYM(ProgramUniform2uiv), + SYM(ProgramUniform3i), + SYM(ProgramUniform3iv), + SYM(ProgramUniform3f), + SYM(ProgramUniform3fv), + SYM(ProgramUniform3d), + SYM(ProgramUniform3dv), + SYM(ProgramUniform3ui), + SYM(ProgramUniform3uiv), + SYM(ProgramUniform4i), + SYM(ProgramUniform4iv), + SYM(ProgramUniform4f), + SYM(ProgramUniform4fv), + SYM(ProgramUniform4d), + SYM(ProgramUniform4dv), + SYM(ProgramUniform4ui), + SYM(ProgramUniform4uiv), + SYM(ProgramUniformMatrix2fv), + SYM(ProgramUniformMatrix3fv), + SYM(ProgramUniformMatrix4fv), + SYM(ProgramUniformMatrix2dv), + SYM(ProgramUniformMatrix3dv), + SYM(ProgramUniformMatrix4dv), + SYM(ProgramUniformMatrix2x3fv), + SYM(ProgramUniformMatrix3x2fv), + SYM(ProgramUniformMatrix2x4fv), + SYM(ProgramUniformMatrix4x2fv), + SYM(ProgramUniformMatrix3x4fv), + SYM(ProgramUniformMatrix4x3fv), + SYM(ProgramUniformMatrix2x3dv), + SYM(ProgramUniformMatrix3x2dv), + SYM(ProgramUniformMatrix2x4dv), + SYM(ProgramUniformMatrix4x2dv), + SYM(ProgramUniformMatrix3x4dv), + SYM(ProgramUniformMatrix4x3dv), + SYM(ValidateProgramPipeline), + SYM(GetProgramPipelineInfoLog), + SYM(VertexAttribL1d), + SYM(VertexAttribL2d), + SYM(VertexAttribL3d), + SYM(VertexAttribL4d), + SYM(VertexAttribL1dv), + SYM(VertexAttribL2dv), + SYM(VertexAttribL3dv), + SYM(VertexAttribL4dv), + SYM(VertexAttribLPointer), + SYM(GetVertexAttribLdv), + SYM(ViewportArrayv), + SYM(ViewportIndexedf), + SYM(ViewportIndexedfv), + SYM(ScissorArrayv), + SYM(ScissorIndexed), + SYM(ScissorIndexedv), + SYM(DepthRangeArrayv), + SYM(DepthRangeIndexed), + SYM(GetFloati_v), + SYM(GetDoublei_v), + SYM(DrawArraysInstancedBaseInstance), + SYM(DrawElementsInstancedBaseInstance), + SYM(DrawElementsInstancedBaseVertexBaseInstance), + SYM(GetInternalformativ), + SYM(GetActiveAtomicCounterBufferiv), + SYM(BindImageTexture), + SYM(MemoryBarrier), + SYM(TexStorage1D), + SYM(TexStorage2D), + SYM(TexStorage3D), + SYM(DrawTransformFeedbackInstanced), + SYM(DrawTransformFeedbackStreamInstanced), + SYM(ClearBufferData), + SYM(ClearBufferSubData), + SYM(DispatchCompute), + SYM(DispatchComputeIndirect), + SYM(CopyImageSubData), + SYM(FramebufferParameteri), + SYM(GetFramebufferParameteriv), + SYM(GetInternalformati64v), + SYM(InvalidateTexSubImage), + SYM(InvalidateTexImage), + SYM(InvalidateBufferSubData), + SYM(InvalidateBufferData), + SYM(InvalidateFramebuffer), + SYM(InvalidateSubFramebuffer), + SYM(MultiDrawArraysIndirect), + SYM(MultiDrawElementsIndirect), + SYM(GetProgramInterfaceiv), + SYM(GetProgramResourceIndex), + SYM(GetProgramResourceName), + SYM(GetProgramResourceiv), + SYM(GetProgramResourceLocation), + SYM(GetProgramResourceLocationIndex), + SYM(ShaderStorageBlockBinding), + SYM(TexBufferRange), + SYM(TexStorage2DMultisample), + SYM(TexStorage3DMultisample), + SYM(TextureView), + SYM(BindVertexBuffer), + SYM(VertexAttribFormat), + SYM(VertexAttribIFormat), + SYM(VertexAttribLFormat), + SYM(VertexAttribBinding), + SYM(VertexBindingDivisor), + SYM(DebugMessageControl), + SYM(DebugMessageInsert), + SYM(DebugMessageCallback), + SYM(GetDebugMessageLog), + SYM(PushDebugGroup), + SYM(PopDebugGroup), + SYM(ObjectLabel), + SYM(GetObjectLabel), + SYM(ObjectPtrLabel), + SYM(GetObjectPtrLabel), + SYM(BufferStorage), + SYM(ClearTexImage), + SYM(ClearTexSubImage), + SYM(BindBuffersBase), + SYM(BindBuffersRange), + SYM(BindTextures), + SYM(BindSamplers), + SYM(BindImageTextures), + SYM(BindVertexBuffers), + SYM(GetTextureHandleARB), + SYM(GetTextureSamplerHandleARB), + SYM(MakeTextureHandleResidentARB), + SYM(MakeTextureHandleNonResidentARB), + SYM(GetImageHandleARB), + SYM(MakeImageHandleResidentARB), + SYM(MakeImageHandleNonResidentARB), + SYM(UniformHandleui64ARB), + SYM(UniformHandleui64vARB), + SYM(ProgramUniformHandleui64ARB), + SYM(ProgramUniformHandleui64vARB), + SYM(IsTextureHandleResidentARB), + SYM(IsImageHandleResidentARB), + SYM(VertexAttribL1ui64ARB), + SYM(VertexAttribL1ui64vARB), + SYM(GetVertexAttribLui64vARB), + SYM(CreateSyncFromCLeventARB), + SYM(ClampColorARB), + SYM(DispatchComputeGroupSizeARB), + SYM(DebugMessageControlARB), + SYM(DebugMessageInsertARB), + SYM(DebugMessageCallbackARB), + SYM(GetDebugMessageLogARB), + SYM(DrawBuffersARB), + SYM(BlendEquationiARB), + SYM(BlendEquationSeparateiARB), + SYM(BlendFunciARB), + SYM(BlendFuncSeparateiARB), + SYM(DrawArraysInstancedARB), + SYM(DrawElementsInstancedARB), + SYM(ProgramStringARB), + SYM(BindProgramARB), + SYM(DeleteProgramsARB), + SYM(GenProgramsARB), + SYM(ProgramEnvParameter4dARB), + SYM(ProgramEnvParameter4dvARB), + SYM(ProgramEnvParameter4fARB), + SYM(ProgramEnvParameter4fvARB), + SYM(ProgramLocalParameter4dARB), + SYM(ProgramLocalParameter4dvARB), + SYM(ProgramLocalParameter4fARB), + SYM(ProgramLocalParameter4fvARB), + SYM(GetProgramEnvParameterdvARB), + SYM(GetProgramEnvParameterfvARB), + SYM(GetProgramLocalParameterdvARB), + SYM(GetProgramLocalParameterfvARB), + SYM(GetProgramivARB), + SYM(GetProgramStringARB), + SYM(IsProgramARB), + SYM(ProgramParameteriARB), + SYM(FramebufferTextureARB), + SYM(FramebufferTextureLayerARB), + SYM(FramebufferTextureFaceARB), + SYM(ColorTable), + SYM(ColorTableParameterfv), + SYM(ColorTableParameteriv), + SYM(CopyColorTable), + SYM(GetColorTable), + SYM(GetColorTableParameterfv), + SYM(GetColorTableParameteriv), + SYM(ColorSubTable), + SYM(CopyColorSubTable), + SYM(ConvolutionFilter1D), + SYM(ConvolutionFilter2D), + SYM(ConvolutionParameterf), + SYM(ConvolutionParameterfv), + SYM(ConvolutionParameteri), + SYM(ConvolutionParameteriv), + SYM(CopyConvolutionFilter1D), + SYM(CopyConvolutionFilter2D), + SYM(GetConvolutionFilter), + SYM(GetConvolutionParameterfv), + SYM(GetConvolutionParameteriv), + SYM(GetSeparableFilter), + SYM(SeparableFilter2D), + SYM(GetHistogram), + SYM(GetHistogramParameterfv), + SYM(GetHistogramParameteriv), + SYM(GetMinmax), + SYM(GetMinmaxParameterfv), + SYM(GetMinmaxParameteriv), + SYM(Histogram), + SYM(Minmax), + SYM(ResetHistogram), + SYM(ResetMinmax), + SYM(MultiDrawArraysIndirectCountARB), + SYM(MultiDrawElementsIndirectCountARB), + SYM(VertexAttribDivisorARB), + SYM(CurrentPaletteMatrixARB), + SYM(MatrixIndexubvARB), + SYM(MatrixIndexusvARB), + SYM(MatrixIndexuivARB), + SYM(MatrixIndexPointerARB), + SYM(SampleCoverageARB), + SYM(ActiveTextureARB), + SYM(ClientActiveTextureARB), + SYM(MultiTexCoord1dARB), + SYM(MultiTexCoord1dvARB), + SYM(MultiTexCoord1fARB), + SYM(MultiTexCoord1fvARB), + SYM(MultiTexCoord1iARB), + SYM(MultiTexCoord1ivARB), + SYM(MultiTexCoord1sARB), + SYM(MultiTexCoord1svARB), + SYM(MultiTexCoord2dARB), + SYM(MultiTexCoord2dvARB), + SYM(MultiTexCoord2fARB), + SYM(MultiTexCoord2fvARB), + SYM(MultiTexCoord2iARB), + SYM(MultiTexCoord2ivARB), + SYM(MultiTexCoord2sARB), + SYM(MultiTexCoord2svARB), + SYM(MultiTexCoord3dARB), + SYM(MultiTexCoord3dvARB), + SYM(MultiTexCoord3fARB), + SYM(MultiTexCoord3fvARB), + SYM(MultiTexCoord3iARB), + SYM(MultiTexCoord3ivARB), + SYM(MultiTexCoord3sARB), + SYM(MultiTexCoord3svARB), + SYM(MultiTexCoord4dARB), + SYM(MultiTexCoord4dvARB), + SYM(MultiTexCoord4fARB), + SYM(MultiTexCoord4fvARB), + SYM(MultiTexCoord4iARB), + SYM(MultiTexCoord4ivARB), + SYM(MultiTexCoord4sARB), + SYM(MultiTexCoord4svARB), + SYM(GenQueriesARB), + SYM(DeleteQueriesARB), + SYM(IsQueryARB), + SYM(BeginQueryARB), + SYM(EndQueryARB), + SYM(GetQueryivARB), + SYM(GetQueryObjectivARB), + SYM(GetQueryObjectuivARB), + SYM(PointParameterfARB), + SYM(PointParameterfvARB), + SYM(GetGraphicsResetStatusARB), + SYM(GetnTexImageARB), + SYM(ReadnPixelsARB), + SYM(GetnCompressedTexImageARB), + SYM(GetnUniformfvARB), + SYM(GetnUniformivARB), + SYM(GetnUniformuivARB), + SYM(GetnUniformdvARB), + SYM(GetnMapdvARB), + SYM(GetnMapfvARB), + SYM(GetnMapivARB), + SYM(GetnPixelMapfvARB), + SYM(GetnPixelMapuivARB), + SYM(GetnPixelMapusvARB), + SYM(GetnPolygonStippleARB), + SYM(GetnColorTableARB), + SYM(GetnConvolutionFilterARB), + SYM(GetnSeparableFilterARB), + SYM(GetnHistogramARB), + SYM(GetnMinmaxARB), + SYM(MinSampleShadingARB), + SYM(DeleteObjectARB), + SYM(GetHandleARB), + SYM(DetachObjectARB), + SYM(CreateShaderObjectARB), + SYM(ShaderSourceARB), + SYM(CompileShaderARB), + SYM(CreateProgramObjectARB), + SYM(AttachObjectARB), + SYM(LinkProgramARB), + SYM(UseProgramObjectARB), + SYM(ValidateProgramARB), + SYM(Uniform1fARB), + SYM(Uniform2fARB), + SYM(Uniform3fARB), + SYM(Uniform4fARB), + SYM(Uniform1iARB), + SYM(Uniform2iARB), + SYM(Uniform3iARB), + SYM(Uniform4iARB), + SYM(Uniform1fvARB), + SYM(Uniform2fvARB), + SYM(Uniform3fvARB), + SYM(Uniform4fvARB), + SYM(Uniform1ivARB), + SYM(Uniform2ivARB), + SYM(Uniform3ivARB), + SYM(Uniform4ivARB), + SYM(UniformMatrix2fvARB), + SYM(UniformMatrix3fvARB), + SYM(UniformMatrix4fvARB), + SYM(GetObjectParameterfvARB), + SYM(GetObjectParameterivARB), + SYM(GetInfoLogARB), + SYM(GetAttachedObjectsARB), + SYM(GetUniformLocationARB), + SYM(GetActiveUniformARB), + SYM(GetUniformfvARB), + SYM(GetUniformivARB), + SYM(GetShaderSourceARB), + SYM(NamedStringARB), + SYM(DeleteNamedStringARB), + SYM(CompileShaderIncludeARB), + SYM(IsNamedStringARB), + SYM(GetNamedStringARB), + SYM(GetNamedStringivARB), + SYM(TexPageCommitmentARB), + SYM(TexBufferARB), + SYM(CompressedTexImage3DARB), + SYM(CompressedTexImage2DARB), + SYM(CompressedTexImage1DARB), + SYM(CompressedTexSubImage3DARB), + SYM(CompressedTexSubImage2DARB), + SYM(CompressedTexSubImage1DARB), + SYM(GetCompressedTexImageARB), + SYM(LoadTransposeMatrixfARB), + SYM(LoadTransposeMatrixdARB), + SYM(MultTransposeMatrixfARB), + SYM(MultTransposeMatrixdARB), + SYM(WeightbvARB), + SYM(WeightsvARB), + SYM(WeightivARB), + SYM(WeightfvARB), + SYM(WeightdvARB), + SYM(WeightubvARB), + SYM(WeightusvARB), + SYM(WeightuivARB), + SYM(WeightPointerARB), + SYM(VertexBlendARB), + SYM(BindBufferARB), + SYM(DeleteBuffersARB), + SYM(GenBuffersARB), + SYM(IsBufferARB), + SYM(BufferDataARB), + SYM(BufferSubDataARB), + SYM(GetBufferSubDataARB), + SYM(MapBufferARB), + SYM(UnmapBufferARB), + SYM(GetBufferParameterivARB), + SYM(GetBufferPointervARB), + SYM(VertexAttrib1dARB), + SYM(VertexAttrib1dvARB), + SYM(VertexAttrib1fARB), + SYM(VertexAttrib1fvARB), + SYM(VertexAttrib1sARB), + SYM(VertexAttrib1svARB), + SYM(VertexAttrib2dARB), + SYM(VertexAttrib2dvARB), + SYM(VertexAttrib2fARB), + SYM(VertexAttrib2fvARB), + SYM(VertexAttrib2sARB), + SYM(VertexAttrib2svARB), + SYM(VertexAttrib3dARB), + SYM(VertexAttrib3dvARB), + SYM(VertexAttrib3fARB), + SYM(VertexAttrib3fvARB), + SYM(VertexAttrib3sARB), + SYM(VertexAttrib3svARB), + SYM(VertexAttrib4NbvARB), + SYM(VertexAttrib4NivARB), + SYM(VertexAttrib4NsvARB), + SYM(VertexAttrib4NubARB), + SYM(VertexAttrib4NubvARB), + SYM(VertexAttrib4NuivARB), + SYM(VertexAttrib4NusvARB), + SYM(VertexAttrib4bvARB), + SYM(VertexAttrib4dARB), + SYM(VertexAttrib4dvARB), + SYM(VertexAttrib4fARB), + SYM(VertexAttrib4fvARB), + SYM(VertexAttrib4ivARB), + SYM(VertexAttrib4sARB), + SYM(VertexAttrib4svARB), + SYM(VertexAttrib4ubvARB), + SYM(VertexAttrib4uivARB), + SYM(VertexAttrib4usvARB), + SYM(VertexAttribPointerARB), + SYM(EnableVertexAttribArrayARB), + SYM(DisableVertexAttribArrayARB), + SYM(GetVertexAttribdvARB), + SYM(GetVertexAttribfvARB), + SYM(GetVertexAttribivARB), + SYM(GetVertexAttribPointervARB), + SYM(BindAttribLocationARB), + SYM(GetActiveAttribARB), + SYM(GetAttribLocationARB), + SYM(WindowPos2dARB), + SYM(WindowPos2dvARB), + SYM(WindowPos2fARB), + SYM(WindowPos2fvARB), + SYM(WindowPos2iARB), + SYM(WindowPos2ivARB), + SYM(WindowPos2sARB), + SYM(WindowPos2svARB), + SYM(WindowPos3dARB), + SYM(WindowPos3dvARB), + SYM(WindowPos3fARB), + SYM(WindowPos3fvARB), + SYM(WindowPos3iARB), + SYM(WindowPos3ivARB), + SYM(WindowPos3sARB), + SYM(WindowPos3svARB), + SYM(MultiTexCoord1bOES), + SYM(MultiTexCoord1bvOES), + SYM(MultiTexCoord2bOES), + SYM(MultiTexCoord2bvOES), + SYM(MultiTexCoord3bOES), + SYM(MultiTexCoord3bvOES), + SYM(MultiTexCoord4bOES), + SYM(MultiTexCoord4bvOES), + SYM(TexCoord1bOES), + SYM(TexCoord1bvOES), + SYM(TexCoord2bOES), + SYM(TexCoord2bvOES), + SYM(TexCoord3bOES), + SYM(TexCoord3bvOES), + SYM(TexCoord4bOES), + SYM(TexCoord4bvOES), + SYM(Vertex2bOES), + SYM(Vertex2bvOES), + SYM(Vertex3bOES), + SYM(Vertex3bvOES), + SYM(Vertex4bOES), + SYM(Vertex4bvOES), + SYM(AlphaFuncxOES), + SYM(ClearColorxOES), + SYM(ClearDepthxOES), + SYM(ClipPlanexOES), + SYM(Color4xOES), + SYM(DepthRangexOES), + SYM(FogxOES), + SYM(FogxvOES), + SYM(FrustumxOES), + SYM(GetClipPlanexOES), + SYM(GetFixedvOES), + SYM(GetTexEnvxvOES), + SYM(GetTexParameterxvOES), + SYM(LightModelxOES), + SYM(LightModelxvOES), + SYM(LightxOES), + SYM(LightxvOES), + SYM(LineWidthxOES), + SYM(LoadMatrixxOES), + SYM(MaterialxOES), + SYM(MaterialxvOES), + SYM(MultMatrixxOES), + SYM(MultiTexCoord4xOES), + SYM(Normal3xOES), + SYM(OrthoxOES), + SYM(PointParameterxvOES), + SYM(PointSizexOES), + SYM(PolygonOffsetxOES), + SYM(RotatexOES), + SYM(SampleCoverageOES), + SYM(ScalexOES), + SYM(TexEnvxOES), + SYM(TexEnvxvOES), + SYM(TexParameterxOES), + SYM(TexParameterxvOES), + SYM(TranslatexOES), + SYM(AccumxOES), + SYM(BitmapxOES), + SYM(BlendColorxOES), + SYM(ClearAccumxOES), + SYM(Color3xOES), + SYM(Color3xvOES), + SYM(Color4xvOES), + SYM(ConvolutionParameterxOES), + SYM(ConvolutionParameterxvOES), + SYM(EvalCoord1xOES), + SYM(EvalCoord1xvOES), + SYM(EvalCoord2xOES), + SYM(EvalCoord2xvOES), + SYM(FeedbackBufferxOES), + SYM(GetConvolutionParameterxvOES), + SYM(GetHistogramParameterxvOES), + SYM(GetLightxOES), + SYM(GetMapxvOES), + SYM(GetMaterialxOES), + SYM(GetPixelMapxv), + SYM(GetTexGenxvOES), + SYM(GetTexLevelParameterxvOES), + SYM(IndexxOES), + SYM(IndexxvOES), + SYM(LoadTransposeMatrixxOES), + SYM(Map1xOES), + SYM(Map2xOES), + SYM(MapGrid1xOES), + SYM(MapGrid2xOES), + SYM(MultTransposeMatrixxOES), + SYM(MultiTexCoord1xOES), + SYM(MultiTexCoord1xvOES), + SYM(MultiTexCoord2xOES), + SYM(MultiTexCoord2xvOES), + SYM(MultiTexCoord3xOES), + SYM(MultiTexCoord3xvOES), + SYM(MultiTexCoord4xvOES), + SYM(Normal3xvOES), + SYM(PassThroughxOES), + SYM(PixelMapx), + SYM(PixelStorex), + SYM(PixelTransferxOES), + SYM(PixelZoomxOES), + SYM(PrioritizeTexturesxOES), + SYM(RasterPos2xOES), + SYM(RasterPos2xvOES), + SYM(RasterPos3xOES), + SYM(RasterPos3xvOES), + SYM(RasterPos4xOES), + SYM(RasterPos4xvOES), + SYM(RectxOES), + SYM(RectxvOES), + SYM(TexCoord1xOES), + SYM(TexCoord1xvOES), + SYM(TexCoord2xOES), + SYM(TexCoord2xvOES), + SYM(TexCoord3xOES), + SYM(TexCoord3xvOES), + SYM(TexCoord4xOES), + SYM(TexCoord4xvOES), + SYM(TexGenxOES), + SYM(TexGenxvOES), + SYM(Vertex2xOES), + SYM(Vertex2xvOES), + SYM(Vertex3xOES), + SYM(Vertex3xvOES), + SYM(Vertex4xOES), + SYM(Vertex4xvOES), + SYM(QueryMatrixxOES), + SYM(ClearDepthfOES), + SYM(ClipPlanefOES), + SYM(DepthRangefOES), + SYM(FrustumfOES), + SYM(GetClipPlanefOES), + SYM(OrthofOES), + SYM(ImageTransformParameteriHP), + SYM(ImageTransformParameterfHP), + SYM(ImageTransformParameterivHP), + SYM(ImageTransformParameterfvHP), + SYM(GetImageTransformParameterivHP), + SYM(GetImageTransformParameterfvHP), + + { NULL, NULL }, +}; +RGLSYMGLDRAWRANGEELEMENTSPROC __rglgen_glDrawRangeElements; +RGLSYMGLTEXIMAGE3DPROC __rglgen_glTexImage3D; +RGLSYMGLTEXSUBIMAGE3DPROC __rglgen_glTexSubImage3D; +RGLSYMGLCOPYTEXSUBIMAGE3DPROC __rglgen_glCopyTexSubImage3D; +RGLSYMGLACTIVETEXTUREPROC __rglgen_glActiveTexture; +RGLSYMGLSAMPLECOVERAGEPROC __rglgen_glSampleCoverage; +RGLSYMGLCOMPRESSEDTEXIMAGE3DPROC __rglgen_glCompressedTexImage3D; +RGLSYMGLCOMPRESSEDTEXIMAGE2DPROC __rglgen_glCompressedTexImage2D; +RGLSYMGLCOMPRESSEDTEXIMAGE1DPROC __rglgen_glCompressedTexImage1D; +RGLSYMGLCOMPRESSEDTEXSUBIMAGE3DPROC __rglgen_glCompressedTexSubImage3D; +RGLSYMGLCOMPRESSEDTEXSUBIMAGE2DPROC __rglgen_glCompressedTexSubImage2D; +RGLSYMGLCOMPRESSEDTEXSUBIMAGE1DPROC __rglgen_glCompressedTexSubImage1D; +RGLSYMGLGETCOMPRESSEDTEXIMAGEPROC __rglgen_glGetCompressedTexImage; +RGLSYMGLCLIENTACTIVETEXTUREPROC __rglgen_glClientActiveTexture; +RGLSYMGLMULTITEXCOORD1DPROC __rglgen_glMultiTexCoord1d; +RGLSYMGLMULTITEXCOORD1DVPROC __rglgen_glMultiTexCoord1dv; +RGLSYMGLMULTITEXCOORD1FPROC __rglgen_glMultiTexCoord1f; +RGLSYMGLMULTITEXCOORD1FVPROC __rglgen_glMultiTexCoord1fv; +RGLSYMGLMULTITEXCOORD1IPROC __rglgen_glMultiTexCoord1i; +RGLSYMGLMULTITEXCOORD1IVPROC __rglgen_glMultiTexCoord1iv; +RGLSYMGLMULTITEXCOORD1SPROC __rglgen_glMultiTexCoord1s; +RGLSYMGLMULTITEXCOORD1SVPROC __rglgen_glMultiTexCoord1sv; +RGLSYMGLMULTITEXCOORD2DPROC __rglgen_glMultiTexCoord2d; +RGLSYMGLMULTITEXCOORD2DVPROC __rglgen_glMultiTexCoord2dv; +RGLSYMGLMULTITEXCOORD2FPROC __rglgen_glMultiTexCoord2f; +RGLSYMGLMULTITEXCOORD2FVPROC __rglgen_glMultiTexCoord2fv; +RGLSYMGLMULTITEXCOORD2IPROC __rglgen_glMultiTexCoord2i; +RGLSYMGLMULTITEXCOORD2IVPROC __rglgen_glMultiTexCoord2iv; +RGLSYMGLMULTITEXCOORD2SPROC __rglgen_glMultiTexCoord2s; +RGLSYMGLMULTITEXCOORD2SVPROC __rglgen_glMultiTexCoord2sv; +RGLSYMGLMULTITEXCOORD3DPROC __rglgen_glMultiTexCoord3d; +RGLSYMGLMULTITEXCOORD3DVPROC __rglgen_glMultiTexCoord3dv; +RGLSYMGLMULTITEXCOORD3FPROC __rglgen_glMultiTexCoord3f; +RGLSYMGLMULTITEXCOORD3FVPROC __rglgen_glMultiTexCoord3fv; +RGLSYMGLMULTITEXCOORD3IPROC __rglgen_glMultiTexCoord3i; +RGLSYMGLMULTITEXCOORD3IVPROC __rglgen_glMultiTexCoord3iv; +RGLSYMGLMULTITEXCOORD3SPROC __rglgen_glMultiTexCoord3s; +RGLSYMGLMULTITEXCOORD3SVPROC __rglgen_glMultiTexCoord3sv; +RGLSYMGLMULTITEXCOORD4DPROC __rglgen_glMultiTexCoord4d; +RGLSYMGLMULTITEXCOORD4DVPROC __rglgen_glMultiTexCoord4dv; +RGLSYMGLMULTITEXCOORD4FPROC __rglgen_glMultiTexCoord4f; +RGLSYMGLMULTITEXCOORD4FVPROC __rglgen_glMultiTexCoord4fv; +RGLSYMGLMULTITEXCOORD4IPROC __rglgen_glMultiTexCoord4i; +RGLSYMGLMULTITEXCOORD4IVPROC __rglgen_glMultiTexCoord4iv; +RGLSYMGLMULTITEXCOORD4SPROC __rglgen_glMultiTexCoord4s; +RGLSYMGLMULTITEXCOORD4SVPROC __rglgen_glMultiTexCoord4sv; +RGLSYMGLLOADTRANSPOSEMATRIXFPROC __rglgen_glLoadTransposeMatrixf; +RGLSYMGLLOADTRANSPOSEMATRIXDPROC __rglgen_glLoadTransposeMatrixd; +RGLSYMGLMULTTRANSPOSEMATRIXFPROC __rglgen_glMultTransposeMatrixf; +RGLSYMGLMULTTRANSPOSEMATRIXDPROC __rglgen_glMultTransposeMatrixd; +RGLSYMGLBLENDFUNCSEPARATEPROC __rglgen_glBlendFuncSeparate; +RGLSYMGLMULTIDRAWARRAYSPROC __rglgen_glMultiDrawArrays; +RGLSYMGLMULTIDRAWELEMENTSPROC __rglgen_glMultiDrawElements; +RGLSYMGLPOINTPARAMETERFPROC __rglgen_glPointParameterf; +RGLSYMGLPOINTPARAMETERFVPROC __rglgen_glPointParameterfv; +RGLSYMGLPOINTPARAMETERIPROC __rglgen_glPointParameteri; +RGLSYMGLPOINTPARAMETERIVPROC __rglgen_glPointParameteriv; +RGLSYMGLFOGCOORDFPROC __rglgen_glFogCoordf; +RGLSYMGLFOGCOORDFVPROC __rglgen_glFogCoordfv; +RGLSYMGLFOGCOORDDPROC __rglgen_glFogCoordd; +RGLSYMGLFOGCOORDDVPROC __rglgen_glFogCoorddv; +RGLSYMGLFOGCOORDPOINTERPROC __rglgen_glFogCoordPointer; +RGLSYMGLSECONDARYCOLOR3BPROC __rglgen_glSecondaryColor3b; +RGLSYMGLSECONDARYCOLOR3BVPROC __rglgen_glSecondaryColor3bv; +RGLSYMGLSECONDARYCOLOR3DPROC __rglgen_glSecondaryColor3d; +RGLSYMGLSECONDARYCOLOR3DVPROC __rglgen_glSecondaryColor3dv; +RGLSYMGLSECONDARYCOLOR3FPROC __rglgen_glSecondaryColor3f; +RGLSYMGLSECONDARYCOLOR3FVPROC __rglgen_glSecondaryColor3fv; +RGLSYMGLSECONDARYCOLOR3IPROC __rglgen_glSecondaryColor3i; +RGLSYMGLSECONDARYCOLOR3IVPROC __rglgen_glSecondaryColor3iv; +RGLSYMGLSECONDARYCOLOR3SPROC __rglgen_glSecondaryColor3s; +RGLSYMGLSECONDARYCOLOR3SVPROC __rglgen_glSecondaryColor3sv; +RGLSYMGLSECONDARYCOLOR3UBPROC __rglgen_glSecondaryColor3ub; +RGLSYMGLSECONDARYCOLOR3UBVPROC __rglgen_glSecondaryColor3ubv; +RGLSYMGLSECONDARYCOLOR3UIPROC __rglgen_glSecondaryColor3ui; +RGLSYMGLSECONDARYCOLOR3UIVPROC __rglgen_glSecondaryColor3uiv; +RGLSYMGLSECONDARYCOLOR3USPROC __rglgen_glSecondaryColor3us; +RGLSYMGLSECONDARYCOLOR3USVPROC __rglgen_glSecondaryColor3usv; +RGLSYMGLSECONDARYCOLORPOINTERPROC __rglgen_glSecondaryColorPointer; +RGLSYMGLWINDOWPOS2DPROC __rglgen_glWindowPos2d; +RGLSYMGLWINDOWPOS2DVPROC __rglgen_glWindowPos2dv; +RGLSYMGLWINDOWPOS2FPROC __rglgen_glWindowPos2f; +RGLSYMGLWINDOWPOS2FVPROC __rglgen_glWindowPos2fv; +RGLSYMGLWINDOWPOS2IPROC __rglgen_glWindowPos2i; +RGLSYMGLWINDOWPOS2IVPROC __rglgen_glWindowPos2iv; +RGLSYMGLWINDOWPOS2SPROC __rglgen_glWindowPos2s; +RGLSYMGLWINDOWPOS2SVPROC __rglgen_glWindowPos2sv; +RGLSYMGLWINDOWPOS3DPROC __rglgen_glWindowPos3d; +RGLSYMGLWINDOWPOS3DVPROC __rglgen_glWindowPos3dv; +RGLSYMGLWINDOWPOS3FPROC __rglgen_glWindowPos3f; +RGLSYMGLWINDOWPOS3FVPROC __rglgen_glWindowPos3fv; +RGLSYMGLWINDOWPOS3IPROC __rglgen_glWindowPos3i; +RGLSYMGLWINDOWPOS3IVPROC __rglgen_glWindowPos3iv; +RGLSYMGLWINDOWPOS3SPROC __rglgen_glWindowPos3s; +RGLSYMGLWINDOWPOS3SVPROC __rglgen_glWindowPos3sv; +RGLSYMGLBLENDCOLORPROC __rglgen_glBlendColor; +RGLSYMGLBLENDEQUATIONPROC __rglgen_glBlendEquation; +RGLSYMGLGENQUERIESPROC __rglgen_glGenQueries; +RGLSYMGLDELETEQUERIESPROC __rglgen_glDeleteQueries; +RGLSYMGLISQUERYPROC __rglgen_glIsQuery; +RGLSYMGLBEGINQUERYPROC __rglgen_glBeginQuery; +RGLSYMGLENDQUERYPROC __rglgen_glEndQuery; +RGLSYMGLGETQUERYIVPROC __rglgen_glGetQueryiv; +RGLSYMGLGETQUERYOBJECTIVPROC __rglgen_glGetQueryObjectiv; +RGLSYMGLGETQUERYOBJECTUIVPROC __rglgen_glGetQueryObjectuiv; +RGLSYMGLBINDBUFFERPROC __rglgen_glBindBuffer; +RGLSYMGLDELETEBUFFERSPROC __rglgen_glDeleteBuffers; +RGLSYMGLGENBUFFERSPROC __rglgen_glGenBuffers; +RGLSYMGLISBUFFERPROC __rglgen_glIsBuffer; +RGLSYMGLBUFFERDATAPROC __rglgen_glBufferData; +RGLSYMGLBUFFERSUBDATAPROC __rglgen_glBufferSubData; +RGLSYMGLGETBUFFERSUBDATAPROC __rglgen_glGetBufferSubData; +RGLSYMGLMAPBUFFERPROC __rglgen_glMapBuffer; +RGLSYMGLUNMAPBUFFERPROC __rglgen_glUnmapBuffer; +RGLSYMGLGETBUFFERPARAMETERIVPROC __rglgen_glGetBufferParameteriv; +RGLSYMGLGETBUFFERPOINTERVPROC __rglgen_glGetBufferPointerv; +RGLSYMGLBLENDEQUATIONSEPARATEPROC __rglgen_glBlendEquationSeparate; +RGLSYMGLDRAWBUFFERSPROC __rglgen_glDrawBuffers; +RGLSYMGLSTENCILOPSEPARATEPROC __rglgen_glStencilOpSeparate; +RGLSYMGLSTENCILFUNCSEPARATEPROC __rglgen_glStencilFuncSeparate; +RGLSYMGLSTENCILMASKSEPARATEPROC __rglgen_glStencilMaskSeparate; +RGLSYMGLATTACHSHADERPROC __rglgen_glAttachShader; +RGLSYMGLBINDATTRIBLOCATIONPROC __rglgen_glBindAttribLocation; +RGLSYMGLCOMPILESHADERPROC __rglgen_glCompileShader; +RGLSYMGLCREATEPROGRAMPROC __rglgen_glCreateProgram; +RGLSYMGLCREATESHADERPROC __rglgen_glCreateShader; +RGLSYMGLDELETEPROGRAMPROC __rglgen_glDeleteProgram; +RGLSYMGLDELETESHADERPROC __rglgen_glDeleteShader; +RGLSYMGLDETACHSHADERPROC __rglgen_glDetachShader; +RGLSYMGLDISABLEVERTEXATTRIBARRAYPROC __rglgen_glDisableVertexAttribArray; +RGLSYMGLENABLEVERTEXATTRIBARRAYPROC __rglgen_glEnableVertexAttribArray; +RGLSYMGLGETACTIVEATTRIBPROC __rglgen_glGetActiveAttrib; +RGLSYMGLGETACTIVEUNIFORMPROC __rglgen_glGetActiveUniform; +RGLSYMGLGETATTACHEDSHADERSPROC __rglgen_glGetAttachedShaders; +RGLSYMGLGETATTRIBLOCATIONPROC __rglgen_glGetAttribLocation; +RGLSYMGLGETPROGRAMIVPROC __rglgen_glGetProgramiv; +RGLSYMGLGETPROGRAMINFOLOGPROC __rglgen_glGetProgramInfoLog; +RGLSYMGLGETSHADERIVPROC __rglgen_glGetShaderiv; +RGLSYMGLGETSHADERINFOLOGPROC __rglgen_glGetShaderInfoLog; +RGLSYMGLGETSHADERSOURCEPROC __rglgen_glGetShaderSource; +RGLSYMGLGETUNIFORMLOCATIONPROC __rglgen_glGetUniformLocation; +RGLSYMGLGETUNIFORMFVPROC __rglgen_glGetUniformfv; +RGLSYMGLGETUNIFORMIVPROC __rglgen_glGetUniformiv; +RGLSYMGLGETVERTEXATTRIBDVPROC __rglgen_glGetVertexAttribdv; +RGLSYMGLGETVERTEXATTRIBFVPROC __rglgen_glGetVertexAttribfv; +RGLSYMGLGETVERTEXATTRIBIVPROC __rglgen_glGetVertexAttribiv; +RGLSYMGLGETVERTEXATTRIBPOINTERVPROC __rglgen_glGetVertexAttribPointerv; +RGLSYMGLISPROGRAMPROC __rglgen_glIsProgram; +RGLSYMGLISSHADERPROC __rglgen_glIsShader; +RGLSYMGLLINKPROGRAMPROC __rglgen_glLinkProgram; +RGLSYMGLSHADERSOURCEPROC __rglgen_glShaderSource; +RGLSYMGLUSEPROGRAMPROC __rglgen_glUseProgram; +RGLSYMGLUNIFORM1FPROC __rglgen_glUniform1f; +RGLSYMGLUNIFORM2FPROC __rglgen_glUniform2f; +RGLSYMGLUNIFORM3FPROC __rglgen_glUniform3f; +RGLSYMGLUNIFORM4FPROC __rglgen_glUniform4f; +RGLSYMGLUNIFORM1IPROC __rglgen_glUniform1i; +RGLSYMGLUNIFORM2IPROC __rglgen_glUniform2i; +RGLSYMGLUNIFORM3IPROC __rglgen_glUniform3i; +RGLSYMGLUNIFORM4IPROC __rglgen_glUniform4i; +RGLSYMGLUNIFORM1FVPROC __rglgen_glUniform1fv; +RGLSYMGLUNIFORM2FVPROC __rglgen_glUniform2fv; +RGLSYMGLUNIFORM3FVPROC __rglgen_glUniform3fv; +RGLSYMGLUNIFORM4FVPROC __rglgen_glUniform4fv; +RGLSYMGLUNIFORM1IVPROC __rglgen_glUniform1iv; +RGLSYMGLUNIFORM2IVPROC __rglgen_glUniform2iv; +RGLSYMGLUNIFORM3IVPROC __rglgen_glUniform3iv; +RGLSYMGLUNIFORM4IVPROC __rglgen_glUniform4iv; +RGLSYMGLUNIFORMMATRIX2FVPROC __rglgen_glUniformMatrix2fv; +RGLSYMGLUNIFORMMATRIX3FVPROC __rglgen_glUniformMatrix3fv; +RGLSYMGLUNIFORMMATRIX4FVPROC __rglgen_glUniformMatrix4fv; +RGLSYMGLVALIDATEPROGRAMPROC __rglgen_glValidateProgram; +RGLSYMGLVERTEXATTRIB1DPROC __rglgen_glVertexAttrib1d; +RGLSYMGLVERTEXATTRIB1DVPROC __rglgen_glVertexAttrib1dv; +RGLSYMGLVERTEXATTRIB1FPROC __rglgen_glVertexAttrib1f; +RGLSYMGLVERTEXATTRIB1FVPROC __rglgen_glVertexAttrib1fv; +RGLSYMGLVERTEXATTRIB1SPROC __rglgen_glVertexAttrib1s; +RGLSYMGLVERTEXATTRIB1SVPROC __rglgen_glVertexAttrib1sv; +RGLSYMGLVERTEXATTRIB2DPROC __rglgen_glVertexAttrib2d; +RGLSYMGLVERTEXATTRIB2DVPROC __rglgen_glVertexAttrib2dv; +RGLSYMGLVERTEXATTRIB2FPROC __rglgen_glVertexAttrib2f; +RGLSYMGLVERTEXATTRIB2FVPROC __rglgen_glVertexAttrib2fv; +RGLSYMGLVERTEXATTRIB2SPROC __rglgen_glVertexAttrib2s; +RGLSYMGLVERTEXATTRIB2SVPROC __rglgen_glVertexAttrib2sv; +RGLSYMGLVERTEXATTRIB3DPROC __rglgen_glVertexAttrib3d; +RGLSYMGLVERTEXATTRIB3DVPROC __rglgen_glVertexAttrib3dv; +RGLSYMGLVERTEXATTRIB3FPROC __rglgen_glVertexAttrib3f; +RGLSYMGLVERTEXATTRIB3FVPROC __rglgen_glVertexAttrib3fv; +RGLSYMGLVERTEXATTRIB3SPROC __rglgen_glVertexAttrib3s; +RGLSYMGLVERTEXATTRIB3SVPROC __rglgen_glVertexAttrib3sv; +RGLSYMGLVERTEXATTRIB4NBVPROC __rglgen_glVertexAttrib4Nbv; +RGLSYMGLVERTEXATTRIB4NIVPROC __rglgen_glVertexAttrib4Niv; +RGLSYMGLVERTEXATTRIB4NSVPROC __rglgen_glVertexAttrib4Nsv; +RGLSYMGLVERTEXATTRIB4NUBPROC __rglgen_glVertexAttrib4Nub; +RGLSYMGLVERTEXATTRIB4NUBVPROC __rglgen_glVertexAttrib4Nubv; +RGLSYMGLVERTEXATTRIB4NUIVPROC __rglgen_glVertexAttrib4Nuiv; +RGLSYMGLVERTEXATTRIB4NUSVPROC __rglgen_glVertexAttrib4Nusv; +RGLSYMGLVERTEXATTRIB4BVPROC __rglgen_glVertexAttrib4bv; +RGLSYMGLVERTEXATTRIB4DPROC __rglgen_glVertexAttrib4d; +RGLSYMGLVERTEXATTRIB4DVPROC __rglgen_glVertexAttrib4dv; +RGLSYMGLVERTEXATTRIB4FPROC __rglgen_glVertexAttrib4f; +RGLSYMGLVERTEXATTRIB4FVPROC __rglgen_glVertexAttrib4fv; +RGLSYMGLVERTEXATTRIB4IVPROC __rglgen_glVertexAttrib4iv; +RGLSYMGLVERTEXATTRIB4SPROC __rglgen_glVertexAttrib4s; +RGLSYMGLVERTEXATTRIB4SVPROC __rglgen_glVertexAttrib4sv; +RGLSYMGLVERTEXATTRIB4UBVPROC __rglgen_glVertexAttrib4ubv; +RGLSYMGLVERTEXATTRIB4UIVPROC __rglgen_glVertexAttrib4uiv; +RGLSYMGLVERTEXATTRIB4USVPROC __rglgen_glVertexAttrib4usv; +RGLSYMGLVERTEXATTRIBPOINTERPROC __rglgen_glVertexAttribPointer; +RGLSYMGLUNIFORMMATRIX2X3FVPROC __rglgen_glUniformMatrix2x3fv; +RGLSYMGLUNIFORMMATRIX3X2FVPROC __rglgen_glUniformMatrix3x2fv; +RGLSYMGLUNIFORMMATRIX2X4FVPROC __rglgen_glUniformMatrix2x4fv; +RGLSYMGLUNIFORMMATRIX4X2FVPROC __rglgen_glUniformMatrix4x2fv; +RGLSYMGLUNIFORMMATRIX3X4FVPROC __rglgen_glUniformMatrix3x4fv; +RGLSYMGLUNIFORMMATRIX4X3FVPROC __rglgen_glUniformMatrix4x3fv; +RGLSYMGLCOLORMASKIPROC __rglgen_glColorMaski; +RGLSYMGLGETBOOLEANI_VPROC __rglgen_glGetBooleani_v; +RGLSYMGLGETINTEGERI_VPROC __rglgen_glGetIntegeri_v; +RGLSYMGLENABLEIPROC __rglgen_glEnablei; +RGLSYMGLDISABLEIPROC __rglgen_glDisablei; +RGLSYMGLISENABLEDIPROC __rglgen_glIsEnabledi; +RGLSYMGLBEGINTRANSFORMFEEDBACKPROC __rglgen_glBeginTransformFeedback; +RGLSYMGLENDTRANSFORMFEEDBACKPROC __rglgen_glEndTransformFeedback; +RGLSYMGLBINDBUFFERRANGEPROC __rglgen_glBindBufferRange; +RGLSYMGLBINDBUFFERBASEPROC __rglgen_glBindBufferBase; +RGLSYMGLTRANSFORMFEEDBACKVARYINGSPROC __rglgen_glTransformFeedbackVaryings; +RGLSYMGLGETTRANSFORMFEEDBACKVARYINGPROC __rglgen_glGetTransformFeedbackVarying; +RGLSYMGLCLAMPCOLORPROC __rglgen_glClampColor; +RGLSYMGLBEGINCONDITIONALRENDERPROC __rglgen_glBeginConditionalRender; +RGLSYMGLENDCONDITIONALRENDERPROC __rglgen_glEndConditionalRender; +RGLSYMGLVERTEXATTRIBIPOINTERPROC __rglgen_glVertexAttribIPointer; +RGLSYMGLGETVERTEXATTRIBIIVPROC __rglgen_glGetVertexAttribIiv; +RGLSYMGLGETVERTEXATTRIBIUIVPROC __rglgen_glGetVertexAttribIuiv; +RGLSYMGLVERTEXATTRIBI1IPROC __rglgen_glVertexAttribI1i; +RGLSYMGLVERTEXATTRIBI2IPROC __rglgen_glVertexAttribI2i; +RGLSYMGLVERTEXATTRIBI3IPROC __rglgen_glVertexAttribI3i; +RGLSYMGLVERTEXATTRIBI4IPROC __rglgen_glVertexAttribI4i; +RGLSYMGLVERTEXATTRIBI1UIPROC __rglgen_glVertexAttribI1ui; +RGLSYMGLVERTEXATTRIBI2UIPROC __rglgen_glVertexAttribI2ui; +RGLSYMGLVERTEXATTRIBI3UIPROC __rglgen_glVertexAttribI3ui; +RGLSYMGLVERTEXATTRIBI4UIPROC __rglgen_glVertexAttribI4ui; +RGLSYMGLVERTEXATTRIBI1IVPROC __rglgen_glVertexAttribI1iv; +RGLSYMGLVERTEXATTRIBI2IVPROC __rglgen_glVertexAttribI2iv; +RGLSYMGLVERTEXATTRIBI3IVPROC __rglgen_glVertexAttribI3iv; +RGLSYMGLVERTEXATTRIBI4IVPROC __rglgen_glVertexAttribI4iv; +RGLSYMGLVERTEXATTRIBI1UIVPROC __rglgen_glVertexAttribI1uiv; +RGLSYMGLVERTEXATTRIBI2UIVPROC __rglgen_glVertexAttribI2uiv; +RGLSYMGLVERTEXATTRIBI3UIVPROC __rglgen_glVertexAttribI3uiv; +RGLSYMGLVERTEXATTRIBI4UIVPROC __rglgen_glVertexAttribI4uiv; +RGLSYMGLVERTEXATTRIBI4BVPROC __rglgen_glVertexAttribI4bv; +RGLSYMGLVERTEXATTRIBI4SVPROC __rglgen_glVertexAttribI4sv; +RGLSYMGLVERTEXATTRIBI4UBVPROC __rglgen_glVertexAttribI4ubv; +RGLSYMGLVERTEXATTRIBI4USVPROC __rglgen_glVertexAttribI4usv; +RGLSYMGLGETUNIFORMUIVPROC __rglgen_glGetUniformuiv; +RGLSYMGLBINDFRAGDATALOCATIONPROC __rglgen_glBindFragDataLocation; +RGLSYMGLGETFRAGDATALOCATIONPROC __rglgen_glGetFragDataLocation; +RGLSYMGLUNIFORM1UIPROC __rglgen_glUniform1ui; +RGLSYMGLUNIFORM2UIPROC __rglgen_glUniform2ui; +RGLSYMGLUNIFORM3UIPROC __rglgen_glUniform3ui; +RGLSYMGLUNIFORM4UIPROC __rglgen_glUniform4ui; +RGLSYMGLUNIFORM1UIVPROC __rglgen_glUniform1uiv; +RGLSYMGLUNIFORM2UIVPROC __rglgen_glUniform2uiv; +RGLSYMGLUNIFORM3UIVPROC __rglgen_glUniform3uiv; +RGLSYMGLUNIFORM4UIVPROC __rglgen_glUniform4uiv; +RGLSYMGLTEXPARAMETERIIVPROC __rglgen_glTexParameterIiv; +RGLSYMGLTEXPARAMETERIUIVPROC __rglgen_glTexParameterIuiv; +RGLSYMGLGETTEXPARAMETERIIVPROC __rglgen_glGetTexParameterIiv; +RGLSYMGLGETTEXPARAMETERIUIVPROC __rglgen_glGetTexParameterIuiv; +RGLSYMGLCLEARBUFFERIVPROC __rglgen_glClearBufferiv; +RGLSYMGLCLEARBUFFERUIVPROC __rglgen_glClearBufferuiv; +RGLSYMGLCLEARBUFFERFVPROC __rglgen_glClearBufferfv; +RGLSYMGLCLEARBUFFERFIPROC __rglgen_glClearBufferfi; +RGLSYMGLGETSTRINGIPROC __rglgen_glGetStringi; +RGLSYMGLISRENDERBUFFERPROC __rglgen_glIsRenderbuffer; +RGLSYMGLBINDRENDERBUFFERPROC __rglgen_glBindRenderbuffer; +RGLSYMGLDELETERENDERBUFFERSPROC __rglgen_glDeleteRenderbuffers; +RGLSYMGLGENRENDERBUFFERSPROC __rglgen_glGenRenderbuffers; +RGLSYMGLRENDERBUFFERSTORAGEPROC __rglgen_glRenderbufferStorage; +RGLSYMGLGETRENDERBUFFERPARAMETERIVPROC __rglgen_glGetRenderbufferParameteriv; +RGLSYMGLISFRAMEBUFFERPROC __rglgen_glIsFramebuffer; +RGLSYMGLBINDFRAMEBUFFERPROC __rglgen_glBindFramebuffer; +RGLSYMGLDELETEFRAMEBUFFERSPROC __rglgen_glDeleteFramebuffers; +RGLSYMGLGENFRAMEBUFFERSPROC __rglgen_glGenFramebuffers; +RGLSYMGLCHECKFRAMEBUFFERSTATUSPROC __rglgen_glCheckFramebufferStatus; +RGLSYMGLFRAMEBUFFERTEXTURE1DPROC __rglgen_glFramebufferTexture1D; +RGLSYMGLFRAMEBUFFERTEXTURE2DPROC __rglgen_glFramebufferTexture2D; +RGLSYMGLFRAMEBUFFERTEXTURE3DPROC __rglgen_glFramebufferTexture3D; +RGLSYMGLFRAMEBUFFERRENDERBUFFERPROC __rglgen_glFramebufferRenderbuffer; +RGLSYMGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC __rglgen_glGetFramebufferAttachmentParameteriv; +RGLSYMGLGENERATEMIPMAPPROC __rglgen_glGenerateMipmap; +RGLSYMGLBLITFRAMEBUFFERPROC __rglgen_glBlitFramebuffer; +RGLSYMGLRENDERBUFFERSTORAGEMULTISAMPLEPROC __rglgen_glRenderbufferStorageMultisample; +RGLSYMGLFRAMEBUFFERTEXTURELAYERPROC __rglgen_glFramebufferTextureLayer; +RGLSYMGLMAPBUFFERRANGEPROC __rglgen_glMapBufferRange; +RGLSYMGLFLUSHMAPPEDBUFFERRANGEPROC __rglgen_glFlushMappedBufferRange; +RGLSYMGLBINDVERTEXARRAYPROC __rglgen_glBindVertexArray; +RGLSYMGLDELETEVERTEXARRAYSPROC __rglgen_glDeleteVertexArrays; +RGLSYMGLGENVERTEXARRAYSPROC __rglgen_glGenVertexArrays; +RGLSYMGLISVERTEXARRAYPROC __rglgen_glIsVertexArray; +RGLSYMGLDRAWARRAYSINSTANCEDPROC __rglgen_glDrawArraysInstanced; +RGLSYMGLDRAWELEMENTSINSTANCEDPROC __rglgen_glDrawElementsInstanced; +RGLSYMGLTEXBUFFERPROC __rglgen_glTexBuffer; +RGLSYMGLPRIMITIVERESTARTINDEXPROC __rglgen_glPrimitiveRestartIndex; +RGLSYMGLCOPYBUFFERSUBDATAPROC __rglgen_glCopyBufferSubData; +RGLSYMGLGETUNIFORMINDICESPROC __rglgen_glGetUniformIndices; +RGLSYMGLGETACTIVEUNIFORMSIVPROC __rglgen_glGetActiveUniformsiv; +RGLSYMGLGETACTIVEUNIFORMNAMEPROC __rglgen_glGetActiveUniformName; +RGLSYMGLGETUNIFORMBLOCKINDEXPROC __rglgen_glGetUniformBlockIndex; +RGLSYMGLGETACTIVEUNIFORMBLOCKIVPROC __rglgen_glGetActiveUniformBlockiv; +RGLSYMGLGETACTIVEUNIFORMBLOCKNAMEPROC __rglgen_glGetActiveUniformBlockName; +RGLSYMGLUNIFORMBLOCKBINDINGPROC __rglgen_glUniformBlockBinding; +RGLSYMGLDRAWELEMENTSBASEVERTEXPROC __rglgen_glDrawElementsBaseVertex; +RGLSYMGLDRAWRANGEELEMENTSBASEVERTEXPROC __rglgen_glDrawRangeElementsBaseVertex; +RGLSYMGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC __rglgen_glDrawElementsInstancedBaseVertex; +RGLSYMGLMULTIDRAWELEMENTSBASEVERTEXPROC __rglgen_glMultiDrawElementsBaseVertex; +RGLSYMGLPROVOKINGVERTEXPROC __rglgen_glProvokingVertex; +RGLSYMGLFENCESYNCPROC __rglgen_glFenceSync; +RGLSYMGLISSYNCPROC __rglgen_glIsSync; +RGLSYMGLDELETESYNCPROC __rglgen_glDeleteSync; +RGLSYMGLCLIENTWAITSYNCPROC __rglgen_glClientWaitSync; +RGLSYMGLWAITSYNCPROC __rglgen_glWaitSync; +RGLSYMGLGETINTEGER64VPROC __rglgen_glGetInteger64v; +RGLSYMGLGETSYNCIVPROC __rglgen_glGetSynciv; +RGLSYMGLGETINTEGER64I_VPROC __rglgen_glGetInteger64i_v; +RGLSYMGLGETBUFFERPARAMETERI64VPROC __rglgen_glGetBufferParameteri64v; +RGLSYMGLFRAMEBUFFERTEXTUREPROC __rglgen_glFramebufferTexture; +RGLSYMGLTEXIMAGE2DMULTISAMPLEPROC __rglgen_glTexImage2DMultisample; +RGLSYMGLTEXIMAGE3DMULTISAMPLEPROC __rglgen_glTexImage3DMultisample; +RGLSYMGLGETMULTISAMPLEFVPROC __rglgen_glGetMultisamplefv; +RGLSYMGLSAMPLEMASKIPROC __rglgen_glSampleMaski; +RGLSYMGLBINDFRAGDATALOCATIONINDEXEDPROC __rglgen_glBindFragDataLocationIndexed; +RGLSYMGLGETFRAGDATAINDEXPROC __rglgen_glGetFragDataIndex; +RGLSYMGLGENSAMPLERSPROC __rglgen_glGenSamplers; +RGLSYMGLDELETESAMPLERSPROC __rglgen_glDeleteSamplers; +RGLSYMGLISSAMPLERPROC __rglgen_glIsSampler; +RGLSYMGLBINDSAMPLERPROC __rglgen_glBindSampler; +RGLSYMGLSAMPLERPARAMETERIPROC __rglgen_glSamplerParameteri; +RGLSYMGLSAMPLERPARAMETERIVPROC __rglgen_glSamplerParameteriv; +RGLSYMGLSAMPLERPARAMETERFPROC __rglgen_glSamplerParameterf; +RGLSYMGLSAMPLERPARAMETERFVPROC __rglgen_glSamplerParameterfv; +RGLSYMGLSAMPLERPARAMETERIIVPROC __rglgen_glSamplerParameterIiv; +RGLSYMGLSAMPLERPARAMETERIUIVPROC __rglgen_glSamplerParameterIuiv; +RGLSYMGLGETSAMPLERPARAMETERIVPROC __rglgen_glGetSamplerParameteriv; +RGLSYMGLGETSAMPLERPARAMETERIIVPROC __rglgen_glGetSamplerParameterIiv; +RGLSYMGLGETSAMPLERPARAMETERFVPROC __rglgen_glGetSamplerParameterfv; +RGLSYMGLGETSAMPLERPARAMETERIUIVPROC __rglgen_glGetSamplerParameterIuiv; +RGLSYMGLQUERYCOUNTERPROC __rglgen_glQueryCounter; +RGLSYMGLGETQUERYOBJECTI64VPROC __rglgen_glGetQueryObjecti64v; +RGLSYMGLGETQUERYOBJECTUI64VPROC __rglgen_glGetQueryObjectui64v; +RGLSYMGLVERTEXATTRIBDIVISORPROC __rglgen_glVertexAttribDivisor; +RGLSYMGLVERTEXATTRIBP1UIPROC __rglgen_glVertexAttribP1ui; +RGLSYMGLVERTEXATTRIBP1UIVPROC __rglgen_glVertexAttribP1uiv; +RGLSYMGLVERTEXATTRIBP2UIPROC __rglgen_glVertexAttribP2ui; +RGLSYMGLVERTEXATTRIBP2UIVPROC __rglgen_glVertexAttribP2uiv; +RGLSYMGLVERTEXATTRIBP3UIPROC __rglgen_glVertexAttribP3ui; +RGLSYMGLVERTEXATTRIBP3UIVPROC __rglgen_glVertexAttribP3uiv; +RGLSYMGLVERTEXATTRIBP4UIPROC __rglgen_glVertexAttribP4ui; +RGLSYMGLVERTEXATTRIBP4UIVPROC __rglgen_glVertexAttribP4uiv; +RGLSYMGLVERTEXP2UIPROC __rglgen_glVertexP2ui; +RGLSYMGLVERTEXP2UIVPROC __rglgen_glVertexP2uiv; +RGLSYMGLVERTEXP3UIPROC __rglgen_glVertexP3ui; +RGLSYMGLVERTEXP3UIVPROC __rglgen_glVertexP3uiv; +RGLSYMGLVERTEXP4UIPROC __rglgen_glVertexP4ui; +RGLSYMGLVERTEXP4UIVPROC __rglgen_glVertexP4uiv; +RGLSYMGLTEXCOORDP1UIPROC __rglgen_glTexCoordP1ui; +RGLSYMGLTEXCOORDP1UIVPROC __rglgen_glTexCoordP1uiv; +RGLSYMGLTEXCOORDP2UIPROC __rglgen_glTexCoordP2ui; +RGLSYMGLTEXCOORDP2UIVPROC __rglgen_glTexCoordP2uiv; +RGLSYMGLTEXCOORDP3UIPROC __rglgen_glTexCoordP3ui; +RGLSYMGLTEXCOORDP3UIVPROC __rglgen_glTexCoordP3uiv; +RGLSYMGLTEXCOORDP4UIPROC __rglgen_glTexCoordP4ui; +RGLSYMGLTEXCOORDP4UIVPROC __rglgen_glTexCoordP4uiv; +RGLSYMGLMULTITEXCOORDP1UIPROC __rglgen_glMultiTexCoordP1ui; +RGLSYMGLMULTITEXCOORDP1UIVPROC __rglgen_glMultiTexCoordP1uiv; +RGLSYMGLMULTITEXCOORDP2UIPROC __rglgen_glMultiTexCoordP2ui; +RGLSYMGLMULTITEXCOORDP2UIVPROC __rglgen_glMultiTexCoordP2uiv; +RGLSYMGLMULTITEXCOORDP3UIPROC __rglgen_glMultiTexCoordP3ui; +RGLSYMGLMULTITEXCOORDP3UIVPROC __rglgen_glMultiTexCoordP3uiv; +RGLSYMGLMULTITEXCOORDP4UIPROC __rglgen_glMultiTexCoordP4ui; +RGLSYMGLMULTITEXCOORDP4UIVPROC __rglgen_glMultiTexCoordP4uiv; +RGLSYMGLNORMALP3UIPROC __rglgen_glNormalP3ui; +RGLSYMGLNORMALP3UIVPROC __rglgen_glNormalP3uiv; +RGLSYMGLCOLORP3UIPROC __rglgen_glColorP3ui; +RGLSYMGLCOLORP3UIVPROC __rglgen_glColorP3uiv; +RGLSYMGLCOLORP4UIPROC __rglgen_glColorP4ui; +RGLSYMGLCOLORP4UIVPROC __rglgen_glColorP4uiv; +RGLSYMGLSECONDARYCOLORP3UIPROC __rglgen_glSecondaryColorP3ui; +RGLSYMGLSECONDARYCOLORP3UIVPROC __rglgen_glSecondaryColorP3uiv; +RGLSYMGLMINSAMPLESHADINGPROC __rglgen_glMinSampleShading; +RGLSYMGLBLENDEQUATIONIPROC __rglgen_glBlendEquationi; +RGLSYMGLBLENDEQUATIONSEPARATEIPROC __rglgen_glBlendEquationSeparatei; +RGLSYMGLBLENDFUNCIPROC __rglgen_glBlendFunci; +RGLSYMGLBLENDFUNCSEPARATEIPROC __rglgen_glBlendFuncSeparatei; +RGLSYMGLDRAWARRAYSINDIRECTPROC __rglgen_glDrawArraysIndirect; +RGLSYMGLDRAWELEMENTSINDIRECTPROC __rglgen_glDrawElementsIndirect; +RGLSYMGLUNIFORM1DPROC __rglgen_glUniform1d; +RGLSYMGLUNIFORM2DPROC __rglgen_glUniform2d; +RGLSYMGLUNIFORM3DPROC __rglgen_glUniform3d; +RGLSYMGLUNIFORM4DPROC __rglgen_glUniform4d; +RGLSYMGLUNIFORM1DVPROC __rglgen_glUniform1dv; +RGLSYMGLUNIFORM2DVPROC __rglgen_glUniform2dv; +RGLSYMGLUNIFORM3DVPROC __rglgen_glUniform3dv; +RGLSYMGLUNIFORM4DVPROC __rglgen_glUniform4dv; +RGLSYMGLUNIFORMMATRIX2DVPROC __rglgen_glUniformMatrix2dv; +RGLSYMGLUNIFORMMATRIX3DVPROC __rglgen_glUniformMatrix3dv; +RGLSYMGLUNIFORMMATRIX4DVPROC __rglgen_glUniformMatrix4dv; +RGLSYMGLUNIFORMMATRIX2X3DVPROC __rglgen_glUniformMatrix2x3dv; +RGLSYMGLUNIFORMMATRIX2X4DVPROC __rglgen_glUniformMatrix2x4dv; +RGLSYMGLUNIFORMMATRIX3X2DVPROC __rglgen_glUniformMatrix3x2dv; +RGLSYMGLUNIFORMMATRIX3X4DVPROC __rglgen_glUniformMatrix3x4dv; +RGLSYMGLUNIFORMMATRIX4X2DVPROC __rglgen_glUniformMatrix4x2dv; +RGLSYMGLUNIFORMMATRIX4X3DVPROC __rglgen_glUniformMatrix4x3dv; +RGLSYMGLGETUNIFORMDVPROC __rglgen_glGetUniformdv; +RGLSYMGLGETSUBROUTINEUNIFORMLOCATIONPROC __rglgen_glGetSubroutineUniformLocation; +RGLSYMGLGETSUBROUTINEINDEXPROC __rglgen_glGetSubroutineIndex; +RGLSYMGLGETACTIVESUBROUTINEUNIFORMIVPROC __rglgen_glGetActiveSubroutineUniformiv; +RGLSYMGLGETACTIVESUBROUTINEUNIFORMNAMEPROC __rglgen_glGetActiveSubroutineUniformName; +RGLSYMGLGETACTIVESUBROUTINENAMEPROC __rglgen_glGetActiveSubroutineName; +RGLSYMGLUNIFORMSUBROUTINESUIVPROC __rglgen_glUniformSubroutinesuiv; +RGLSYMGLGETUNIFORMSUBROUTINEUIVPROC __rglgen_glGetUniformSubroutineuiv; +RGLSYMGLGETPROGRAMSTAGEIVPROC __rglgen_glGetProgramStageiv; +RGLSYMGLPATCHPARAMETERIPROC __rglgen_glPatchParameteri; +RGLSYMGLPATCHPARAMETERFVPROC __rglgen_glPatchParameterfv; +RGLSYMGLBINDTRANSFORMFEEDBACKPROC __rglgen_glBindTransformFeedback; +RGLSYMGLDELETETRANSFORMFEEDBACKSPROC __rglgen_glDeleteTransformFeedbacks; +RGLSYMGLGENTRANSFORMFEEDBACKSPROC __rglgen_glGenTransformFeedbacks; +RGLSYMGLISTRANSFORMFEEDBACKPROC __rglgen_glIsTransformFeedback; +RGLSYMGLPAUSETRANSFORMFEEDBACKPROC __rglgen_glPauseTransformFeedback; +RGLSYMGLRESUMETRANSFORMFEEDBACKPROC __rglgen_glResumeTransformFeedback; +RGLSYMGLDRAWTRANSFORMFEEDBACKPROC __rglgen_glDrawTransformFeedback; +RGLSYMGLDRAWTRANSFORMFEEDBACKSTREAMPROC __rglgen_glDrawTransformFeedbackStream; +RGLSYMGLBEGINQUERYINDEXEDPROC __rglgen_glBeginQueryIndexed; +RGLSYMGLENDQUERYINDEXEDPROC __rglgen_glEndQueryIndexed; +RGLSYMGLGETQUERYINDEXEDIVPROC __rglgen_glGetQueryIndexediv; +RGLSYMGLRELEASESHADERCOMPILERPROC __rglgen_glReleaseShaderCompiler; +RGLSYMGLSHADERBINARYPROC __rglgen_glShaderBinary; +RGLSYMGLGETSHADERPRECISIONFORMATPROC __rglgen_glGetShaderPrecisionFormat; +RGLSYMGLDEPTHRANGEFPROC __rglgen_glDepthRangef; +RGLSYMGLCLEARDEPTHFPROC __rglgen_glClearDepthf; +RGLSYMGLGETPROGRAMBINARYPROC __rglgen_glGetProgramBinary; +RGLSYMGLPROGRAMBINARYPROC __rglgen_glProgramBinary; +RGLSYMGLPROGRAMPARAMETERIPROC __rglgen_glProgramParameteri; +RGLSYMGLUSEPROGRAMSTAGESPROC __rglgen_glUseProgramStages; +RGLSYMGLACTIVESHADERPROGRAMPROC __rglgen_glActiveShaderProgram; +RGLSYMGLCREATESHADERPROGRAMVPROC __rglgen_glCreateShaderProgramv; +RGLSYMGLBINDPROGRAMPIPELINEPROC __rglgen_glBindProgramPipeline; +RGLSYMGLDELETEPROGRAMPIPELINESPROC __rglgen_glDeleteProgramPipelines; +RGLSYMGLGENPROGRAMPIPELINESPROC __rglgen_glGenProgramPipelines; +RGLSYMGLISPROGRAMPIPELINEPROC __rglgen_glIsProgramPipeline; +RGLSYMGLGETPROGRAMPIPELINEIVPROC __rglgen_glGetProgramPipelineiv; +RGLSYMGLPROGRAMUNIFORM1IPROC __rglgen_glProgramUniform1i; +RGLSYMGLPROGRAMUNIFORM1IVPROC __rglgen_glProgramUniform1iv; +RGLSYMGLPROGRAMUNIFORM1FPROC __rglgen_glProgramUniform1f; +RGLSYMGLPROGRAMUNIFORM1FVPROC __rglgen_glProgramUniform1fv; +RGLSYMGLPROGRAMUNIFORM1DPROC __rglgen_glProgramUniform1d; +RGLSYMGLPROGRAMUNIFORM1DVPROC __rglgen_glProgramUniform1dv; +RGLSYMGLPROGRAMUNIFORM1UIPROC __rglgen_glProgramUniform1ui; +RGLSYMGLPROGRAMUNIFORM1UIVPROC __rglgen_glProgramUniform1uiv; +RGLSYMGLPROGRAMUNIFORM2IPROC __rglgen_glProgramUniform2i; +RGLSYMGLPROGRAMUNIFORM2IVPROC __rglgen_glProgramUniform2iv; +RGLSYMGLPROGRAMUNIFORM2FPROC __rglgen_glProgramUniform2f; +RGLSYMGLPROGRAMUNIFORM2FVPROC __rglgen_glProgramUniform2fv; +RGLSYMGLPROGRAMUNIFORM2DPROC __rglgen_glProgramUniform2d; +RGLSYMGLPROGRAMUNIFORM2DVPROC __rglgen_glProgramUniform2dv; +RGLSYMGLPROGRAMUNIFORM2UIPROC __rglgen_glProgramUniform2ui; +RGLSYMGLPROGRAMUNIFORM2UIVPROC __rglgen_glProgramUniform2uiv; +RGLSYMGLPROGRAMUNIFORM3IPROC __rglgen_glProgramUniform3i; +RGLSYMGLPROGRAMUNIFORM3IVPROC __rglgen_glProgramUniform3iv; +RGLSYMGLPROGRAMUNIFORM3FPROC __rglgen_glProgramUniform3f; +RGLSYMGLPROGRAMUNIFORM3FVPROC __rglgen_glProgramUniform3fv; +RGLSYMGLPROGRAMUNIFORM3DPROC __rglgen_glProgramUniform3d; +RGLSYMGLPROGRAMUNIFORM3DVPROC __rglgen_glProgramUniform3dv; +RGLSYMGLPROGRAMUNIFORM3UIPROC __rglgen_glProgramUniform3ui; +RGLSYMGLPROGRAMUNIFORM3UIVPROC __rglgen_glProgramUniform3uiv; +RGLSYMGLPROGRAMUNIFORM4IPROC __rglgen_glProgramUniform4i; +RGLSYMGLPROGRAMUNIFORM4IVPROC __rglgen_glProgramUniform4iv; +RGLSYMGLPROGRAMUNIFORM4FPROC __rglgen_glProgramUniform4f; +RGLSYMGLPROGRAMUNIFORM4FVPROC __rglgen_glProgramUniform4fv; +RGLSYMGLPROGRAMUNIFORM4DPROC __rglgen_glProgramUniform4d; +RGLSYMGLPROGRAMUNIFORM4DVPROC __rglgen_glProgramUniform4dv; +RGLSYMGLPROGRAMUNIFORM4UIPROC __rglgen_glProgramUniform4ui; +RGLSYMGLPROGRAMUNIFORM4UIVPROC __rglgen_glProgramUniform4uiv; +RGLSYMGLPROGRAMUNIFORMMATRIX2FVPROC __rglgen_glProgramUniformMatrix2fv; +RGLSYMGLPROGRAMUNIFORMMATRIX3FVPROC __rglgen_glProgramUniformMatrix3fv; +RGLSYMGLPROGRAMUNIFORMMATRIX4FVPROC __rglgen_glProgramUniformMatrix4fv; +RGLSYMGLPROGRAMUNIFORMMATRIX2DVPROC __rglgen_glProgramUniformMatrix2dv; +RGLSYMGLPROGRAMUNIFORMMATRIX3DVPROC __rglgen_glProgramUniformMatrix3dv; +RGLSYMGLPROGRAMUNIFORMMATRIX4DVPROC __rglgen_glProgramUniformMatrix4dv; +RGLSYMGLPROGRAMUNIFORMMATRIX2X3FVPROC __rglgen_glProgramUniformMatrix2x3fv; +RGLSYMGLPROGRAMUNIFORMMATRIX3X2FVPROC __rglgen_glProgramUniformMatrix3x2fv; +RGLSYMGLPROGRAMUNIFORMMATRIX2X4FVPROC __rglgen_glProgramUniformMatrix2x4fv; +RGLSYMGLPROGRAMUNIFORMMATRIX4X2FVPROC __rglgen_glProgramUniformMatrix4x2fv; +RGLSYMGLPROGRAMUNIFORMMATRIX3X4FVPROC __rglgen_glProgramUniformMatrix3x4fv; +RGLSYMGLPROGRAMUNIFORMMATRIX4X3FVPROC __rglgen_glProgramUniformMatrix4x3fv; +RGLSYMGLPROGRAMUNIFORMMATRIX2X3DVPROC __rglgen_glProgramUniformMatrix2x3dv; +RGLSYMGLPROGRAMUNIFORMMATRIX3X2DVPROC __rglgen_glProgramUniformMatrix3x2dv; +RGLSYMGLPROGRAMUNIFORMMATRIX2X4DVPROC __rglgen_glProgramUniformMatrix2x4dv; +RGLSYMGLPROGRAMUNIFORMMATRIX4X2DVPROC __rglgen_glProgramUniformMatrix4x2dv; +RGLSYMGLPROGRAMUNIFORMMATRIX3X4DVPROC __rglgen_glProgramUniformMatrix3x4dv; +RGLSYMGLPROGRAMUNIFORMMATRIX4X3DVPROC __rglgen_glProgramUniformMatrix4x3dv; +RGLSYMGLVALIDATEPROGRAMPIPELINEPROC __rglgen_glValidateProgramPipeline; +RGLSYMGLGETPROGRAMPIPELINEINFOLOGPROC __rglgen_glGetProgramPipelineInfoLog; +RGLSYMGLVERTEXATTRIBL1DPROC __rglgen_glVertexAttribL1d; +RGLSYMGLVERTEXATTRIBL2DPROC __rglgen_glVertexAttribL2d; +RGLSYMGLVERTEXATTRIBL3DPROC __rglgen_glVertexAttribL3d; +RGLSYMGLVERTEXATTRIBL4DPROC __rglgen_glVertexAttribL4d; +RGLSYMGLVERTEXATTRIBL1DVPROC __rglgen_glVertexAttribL1dv; +RGLSYMGLVERTEXATTRIBL2DVPROC __rglgen_glVertexAttribL2dv; +RGLSYMGLVERTEXATTRIBL3DVPROC __rglgen_glVertexAttribL3dv; +RGLSYMGLVERTEXATTRIBL4DVPROC __rglgen_glVertexAttribL4dv; +RGLSYMGLVERTEXATTRIBLPOINTERPROC __rglgen_glVertexAttribLPointer; +RGLSYMGLGETVERTEXATTRIBLDVPROC __rglgen_glGetVertexAttribLdv; +RGLSYMGLVIEWPORTARRAYVPROC __rglgen_glViewportArrayv; +RGLSYMGLVIEWPORTINDEXEDFPROC __rglgen_glViewportIndexedf; +RGLSYMGLVIEWPORTINDEXEDFVPROC __rglgen_glViewportIndexedfv; +RGLSYMGLSCISSORARRAYVPROC __rglgen_glScissorArrayv; +RGLSYMGLSCISSORINDEXEDPROC __rglgen_glScissorIndexed; +RGLSYMGLSCISSORINDEXEDVPROC __rglgen_glScissorIndexedv; +RGLSYMGLDEPTHRANGEARRAYVPROC __rglgen_glDepthRangeArrayv; +RGLSYMGLDEPTHRANGEINDEXEDPROC __rglgen_glDepthRangeIndexed; +RGLSYMGLGETFLOATI_VPROC __rglgen_glGetFloati_v; +RGLSYMGLGETDOUBLEI_VPROC __rglgen_glGetDoublei_v; +RGLSYMGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC __rglgen_glDrawArraysInstancedBaseInstance; +RGLSYMGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC __rglgen_glDrawElementsInstancedBaseInstance; +RGLSYMGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC __rglgen_glDrawElementsInstancedBaseVertexBaseInstance; +RGLSYMGLGETINTERNALFORMATIVPROC __rglgen_glGetInternalformativ; +RGLSYMGLGETACTIVEATOMICCOUNTERBUFFERIVPROC __rglgen_glGetActiveAtomicCounterBufferiv; +RGLSYMGLBINDIMAGETEXTUREPROC __rglgen_glBindImageTexture; +RGLSYMGLMEMORYBARRIERPROC __rglgen_glMemoryBarrier; +RGLSYMGLTEXSTORAGE1DPROC __rglgen_glTexStorage1D; +RGLSYMGLTEXSTORAGE2DPROC __rglgen_glTexStorage2D; +RGLSYMGLTEXSTORAGE3DPROC __rglgen_glTexStorage3D; +RGLSYMGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC __rglgen_glDrawTransformFeedbackInstanced; +RGLSYMGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC __rglgen_glDrawTransformFeedbackStreamInstanced; +RGLSYMGLCLEARBUFFERDATAPROC __rglgen_glClearBufferData; +RGLSYMGLCLEARBUFFERSUBDATAPROC __rglgen_glClearBufferSubData; +RGLSYMGLDISPATCHCOMPUTEPROC __rglgen_glDispatchCompute; +RGLSYMGLDISPATCHCOMPUTEINDIRECTPROC __rglgen_glDispatchComputeIndirect; +RGLSYMGLCOPYIMAGESUBDATAPROC __rglgen_glCopyImageSubData; +RGLSYMGLFRAMEBUFFERPARAMETERIPROC __rglgen_glFramebufferParameteri; +RGLSYMGLGETFRAMEBUFFERPARAMETERIVPROC __rglgen_glGetFramebufferParameteriv; +RGLSYMGLGETINTERNALFORMATI64VPROC __rglgen_glGetInternalformati64v; +RGLSYMGLINVALIDATETEXSUBIMAGEPROC __rglgen_glInvalidateTexSubImage; +RGLSYMGLINVALIDATETEXIMAGEPROC __rglgen_glInvalidateTexImage; +RGLSYMGLINVALIDATEBUFFERSUBDATAPROC __rglgen_glInvalidateBufferSubData; +RGLSYMGLINVALIDATEBUFFERDATAPROC __rglgen_glInvalidateBufferData; +RGLSYMGLINVALIDATEFRAMEBUFFERPROC __rglgen_glInvalidateFramebuffer; +RGLSYMGLINVALIDATESUBFRAMEBUFFERPROC __rglgen_glInvalidateSubFramebuffer; +RGLSYMGLMULTIDRAWARRAYSINDIRECTPROC __rglgen_glMultiDrawArraysIndirect; +RGLSYMGLMULTIDRAWELEMENTSINDIRECTPROC __rglgen_glMultiDrawElementsIndirect; +RGLSYMGLGETPROGRAMINTERFACEIVPROC __rglgen_glGetProgramInterfaceiv; +RGLSYMGLGETPROGRAMRESOURCEINDEXPROC __rglgen_glGetProgramResourceIndex; +RGLSYMGLGETPROGRAMRESOURCENAMEPROC __rglgen_glGetProgramResourceName; +RGLSYMGLGETPROGRAMRESOURCEIVPROC __rglgen_glGetProgramResourceiv; +RGLSYMGLGETPROGRAMRESOURCELOCATIONPROC __rglgen_glGetProgramResourceLocation; +RGLSYMGLGETPROGRAMRESOURCELOCATIONINDEXPROC __rglgen_glGetProgramResourceLocationIndex; +RGLSYMGLSHADERSTORAGEBLOCKBINDINGPROC __rglgen_glShaderStorageBlockBinding; +RGLSYMGLTEXBUFFERRANGEPROC __rglgen_glTexBufferRange; +RGLSYMGLTEXSTORAGE2DMULTISAMPLEPROC __rglgen_glTexStorage2DMultisample; +RGLSYMGLTEXSTORAGE3DMULTISAMPLEPROC __rglgen_glTexStorage3DMultisample; +RGLSYMGLTEXTUREVIEWPROC __rglgen_glTextureView; +RGLSYMGLBINDVERTEXBUFFERPROC __rglgen_glBindVertexBuffer; +RGLSYMGLVERTEXATTRIBFORMATPROC __rglgen_glVertexAttribFormat; +RGLSYMGLVERTEXATTRIBIFORMATPROC __rglgen_glVertexAttribIFormat; +RGLSYMGLVERTEXATTRIBLFORMATPROC __rglgen_glVertexAttribLFormat; +RGLSYMGLVERTEXATTRIBBINDINGPROC __rglgen_glVertexAttribBinding; +RGLSYMGLVERTEXBINDINGDIVISORPROC __rglgen_glVertexBindingDivisor; +RGLSYMGLDEBUGMESSAGECONTROLPROC __rglgen_glDebugMessageControl; +RGLSYMGLDEBUGMESSAGEINSERTPROC __rglgen_glDebugMessageInsert; +RGLSYMGLDEBUGMESSAGECALLBACKPROC __rglgen_glDebugMessageCallback; +RGLSYMGLGETDEBUGMESSAGELOGPROC __rglgen_glGetDebugMessageLog; +RGLSYMGLPUSHDEBUGGROUPPROC __rglgen_glPushDebugGroup; +RGLSYMGLPOPDEBUGGROUPPROC __rglgen_glPopDebugGroup; +RGLSYMGLOBJECTLABELPROC __rglgen_glObjectLabel; +RGLSYMGLGETOBJECTLABELPROC __rglgen_glGetObjectLabel; +RGLSYMGLOBJECTPTRLABELPROC __rglgen_glObjectPtrLabel; +RGLSYMGLGETOBJECTPTRLABELPROC __rglgen_glGetObjectPtrLabel; +RGLSYMGLBUFFERSTORAGEPROC __rglgen_glBufferStorage; +RGLSYMGLCLEARTEXIMAGEPROC __rglgen_glClearTexImage; +RGLSYMGLCLEARTEXSUBIMAGEPROC __rglgen_glClearTexSubImage; +RGLSYMGLBINDBUFFERSBASEPROC __rglgen_glBindBuffersBase; +RGLSYMGLBINDBUFFERSRANGEPROC __rglgen_glBindBuffersRange; +RGLSYMGLBINDTEXTURESPROC __rglgen_glBindTextures; +RGLSYMGLBINDSAMPLERSPROC __rglgen_glBindSamplers; +RGLSYMGLBINDIMAGETEXTURESPROC __rglgen_glBindImageTextures; +RGLSYMGLBINDVERTEXBUFFERSPROC __rglgen_glBindVertexBuffers; +RGLSYMGLGETTEXTUREHANDLEARBPROC __rglgen_glGetTextureHandleARB; +RGLSYMGLGETTEXTURESAMPLERHANDLEARBPROC __rglgen_glGetTextureSamplerHandleARB; +RGLSYMGLMAKETEXTUREHANDLERESIDENTARBPROC __rglgen_glMakeTextureHandleResidentARB; +RGLSYMGLMAKETEXTUREHANDLENONRESIDENTARBPROC __rglgen_glMakeTextureHandleNonResidentARB; +RGLSYMGLGETIMAGEHANDLEARBPROC __rglgen_glGetImageHandleARB; +RGLSYMGLMAKEIMAGEHANDLERESIDENTARBPROC __rglgen_glMakeImageHandleResidentARB; +RGLSYMGLMAKEIMAGEHANDLENONRESIDENTARBPROC __rglgen_glMakeImageHandleNonResidentARB; +RGLSYMGLUNIFORMHANDLEUI64ARBPROC __rglgen_glUniformHandleui64ARB; +RGLSYMGLUNIFORMHANDLEUI64VARBPROC __rglgen_glUniformHandleui64vARB; +RGLSYMGLPROGRAMUNIFORMHANDLEUI64ARBPROC __rglgen_glProgramUniformHandleui64ARB; +RGLSYMGLPROGRAMUNIFORMHANDLEUI64VARBPROC __rglgen_glProgramUniformHandleui64vARB; +RGLSYMGLISTEXTUREHANDLERESIDENTARBPROC __rglgen_glIsTextureHandleResidentARB; +RGLSYMGLISIMAGEHANDLERESIDENTARBPROC __rglgen_glIsImageHandleResidentARB; +RGLSYMGLVERTEXATTRIBL1UI64ARBPROC __rglgen_glVertexAttribL1ui64ARB; +RGLSYMGLVERTEXATTRIBL1UI64VARBPROC __rglgen_glVertexAttribL1ui64vARB; +RGLSYMGLGETVERTEXATTRIBLUI64VARBPROC __rglgen_glGetVertexAttribLui64vARB; +RGLSYMGLCREATESYNCFROMCLEVENTARBPROC __rglgen_glCreateSyncFromCLeventARB; +RGLSYMGLCLAMPCOLORARBPROC __rglgen_glClampColorARB; +RGLSYMGLDISPATCHCOMPUTEGROUPSIZEARBPROC __rglgen_glDispatchComputeGroupSizeARB; +RGLSYMGLDEBUGMESSAGECONTROLARBPROC __rglgen_glDebugMessageControlARB; +RGLSYMGLDEBUGMESSAGEINSERTARBPROC __rglgen_glDebugMessageInsertARB; +RGLSYMGLDEBUGMESSAGECALLBACKARBPROC __rglgen_glDebugMessageCallbackARB; +RGLSYMGLGETDEBUGMESSAGELOGARBPROC __rglgen_glGetDebugMessageLogARB; +RGLSYMGLDRAWBUFFERSARBPROC __rglgen_glDrawBuffersARB; +RGLSYMGLBLENDEQUATIONIARBPROC __rglgen_glBlendEquationiARB; +RGLSYMGLBLENDEQUATIONSEPARATEIARBPROC __rglgen_glBlendEquationSeparateiARB; +RGLSYMGLBLENDFUNCIARBPROC __rglgen_glBlendFunciARB; +RGLSYMGLBLENDFUNCSEPARATEIARBPROC __rglgen_glBlendFuncSeparateiARB; +RGLSYMGLDRAWARRAYSINSTANCEDARBPROC __rglgen_glDrawArraysInstancedARB; +RGLSYMGLDRAWELEMENTSINSTANCEDARBPROC __rglgen_glDrawElementsInstancedARB; +RGLSYMGLPROGRAMSTRINGARBPROC __rglgen_glProgramStringARB; +RGLSYMGLBINDPROGRAMARBPROC __rglgen_glBindProgramARB; +RGLSYMGLDELETEPROGRAMSARBPROC __rglgen_glDeleteProgramsARB; +RGLSYMGLGENPROGRAMSARBPROC __rglgen_glGenProgramsARB; +RGLSYMGLPROGRAMENVPARAMETER4DARBPROC __rglgen_glProgramEnvParameter4dARB; +RGLSYMGLPROGRAMENVPARAMETER4DVARBPROC __rglgen_glProgramEnvParameter4dvARB; +RGLSYMGLPROGRAMENVPARAMETER4FARBPROC __rglgen_glProgramEnvParameter4fARB; +RGLSYMGLPROGRAMENVPARAMETER4FVARBPROC __rglgen_glProgramEnvParameter4fvARB; +RGLSYMGLPROGRAMLOCALPARAMETER4DARBPROC __rglgen_glProgramLocalParameter4dARB; +RGLSYMGLPROGRAMLOCALPARAMETER4DVARBPROC __rglgen_glProgramLocalParameter4dvARB; +RGLSYMGLPROGRAMLOCALPARAMETER4FARBPROC __rglgen_glProgramLocalParameter4fARB; +RGLSYMGLPROGRAMLOCALPARAMETER4FVARBPROC __rglgen_glProgramLocalParameter4fvARB; +RGLSYMGLGETPROGRAMENVPARAMETERDVARBPROC __rglgen_glGetProgramEnvParameterdvARB; +RGLSYMGLGETPROGRAMENVPARAMETERFVARBPROC __rglgen_glGetProgramEnvParameterfvARB; +RGLSYMGLGETPROGRAMLOCALPARAMETERDVARBPROC __rglgen_glGetProgramLocalParameterdvARB; +RGLSYMGLGETPROGRAMLOCALPARAMETERFVARBPROC __rglgen_glGetProgramLocalParameterfvARB; +RGLSYMGLGETPROGRAMIVARBPROC __rglgen_glGetProgramivARB; +RGLSYMGLGETPROGRAMSTRINGARBPROC __rglgen_glGetProgramStringARB; +RGLSYMGLISPROGRAMARBPROC __rglgen_glIsProgramARB; +RGLSYMGLPROGRAMPARAMETERIARBPROC __rglgen_glProgramParameteriARB; +RGLSYMGLFRAMEBUFFERTEXTUREARBPROC __rglgen_glFramebufferTextureARB; +RGLSYMGLFRAMEBUFFERTEXTURELAYERARBPROC __rglgen_glFramebufferTextureLayerARB; +RGLSYMGLFRAMEBUFFERTEXTUREFACEARBPROC __rglgen_glFramebufferTextureFaceARB; +RGLSYMGLCOLORTABLEPROC __rglgen_glColorTable; +RGLSYMGLCOLORTABLEPARAMETERFVPROC __rglgen_glColorTableParameterfv; +RGLSYMGLCOLORTABLEPARAMETERIVPROC __rglgen_glColorTableParameteriv; +RGLSYMGLCOPYCOLORTABLEPROC __rglgen_glCopyColorTable; +RGLSYMGLGETCOLORTABLEPROC __rglgen_glGetColorTable; +RGLSYMGLGETCOLORTABLEPARAMETERFVPROC __rglgen_glGetColorTableParameterfv; +RGLSYMGLGETCOLORTABLEPARAMETERIVPROC __rglgen_glGetColorTableParameteriv; +RGLSYMGLCOLORSUBTABLEPROC __rglgen_glColorSubTable; +RGLSYMGLCOPYCOLORSUBTABLEPROC __rglgen_glCopyColorSubTable; +RGLSYMGLCONVOLUTIONFILTER1DPROC __rglgen_glConvolutionFilter1D; +RGLSYMGLCONVOLUTIONFILTER2DPROC __rglgen_glConvolutionFilter2D; +RGLSYMGLCONVOLUTIONPARAMETERFPROC __rglgen_glConvolutionParameterf; +RGLSYMGLCONVOLUTIONPARAMETERFVPROC __rglgen_glConvolutionParameterfv; +RGLSYMGLCONVOLUTIONPARAMETERIPROC __rglgen_glConvolutionParameteri; +RGLSYMGLCONVOLUTIONPARAMETERIVPROC __rglgen_glConvolutionParameteriv; +RGLSYMGLCOPYCONVOLUTIONFILTER1DPROC __rglgen_glCopyConvolutionFilter1D; +RGLSYMGLCOPYCONVOLUTIONFILTER2DPROC __rglgen_glCopyConvolutionFilter2D; +RGLSYMGLGETCONVOLUTIONFILTERPROC __rglgen_glGetConvolutionFilter; +RGLSYMGLGETCONVOLUTIONPARAMETERFVPROC __rglgen_glGetConvolutionParameterfv; +RGLSYMGLGETCONVOLUTIONPARAMETERIVPROC __rglgen_glGetConvolutionParameteriv; +RGLSYMGLGETSEPARABLEFILTERPROC __rglgen_glGetSeparableFilter; +RGLSYMGLSEPARABLEFILTER2DPROC __rglgen_glSeparableFilter2D; +RGLSYMGLGETHISTOGRAMPROC __rglgen_glGetHistogram; +RGLSYMGLGETHISTOGRAMPARAMETERFVPROC __rglgen_glGetHistogramParameterfv; +RGLSYMGLGETHISTOGRAMPARAMETERIVPROC __rglgen_glGetHistogramParameteriv; +RGLSYMGLGETMINMAXPROC __rglgen_glGetMinmax; +RGLSYMGLGETMINMAXPARAMETERFVPROC __rglgen_glGetMinmaxParameterfv; +RGLSYMGLGETMINMAXPARAMETERIVPROC __rglgen_glGetMinmaxParameteriv; +RGLSYMGLHISTOGRAMPROC __rglgen_glHistogram; +RGLSYMGLMINMAXPROC __rglgen_glMinmax; +RGLSYMGLRESETHISTOGRAMPROC __rglgen_glResetHistogram; +RGLSYMGLRESETMINMAXPROC __rglgen_glResetMinmax; +RGLSYMGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC __rglgen_glMultiDrawArraysIndirectCountARB; +RGLSYMGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC __rglgen_glMultiDrawElementsIndirectCountARB; +RGLSYMGLVERTEXATTRIBDIVISORARBPROC __rglgen_glVertexAttribDivisorARB; +RGLSYMGLCURRENTPALETTEMATRIXARBPROC __rglgen_glCurrentPaletteMatrixARB; +RGLSYMGLMATRIXINDEXUBVARBPROC __rglgen_glMatrixIndexubvARB; +RGLSYMGLMATRIXINDEXUSVARBPROC __rglgen_glMatrixIndexusvARB; +RGLSYMGLMATRIXINDEXUIVARBPROC __rglgen_glMatrixIndexuivARB; +RGLSYMGLMATRIXINDEXPOINTERARBPROC __rglgen_glMatrixIndexPointerARB; +RGLSYMGLSAMPLECOVERAGEARBPROC __rglgen_glSampleCoverageARB; +RGLSYMGLACTIVETEXTUREARBPROC __rglgen_glActiveTextureARB; +RGLSYMGLCLIENTACTIVETEXTUREARBPROC __rglgen_glClientActiveTextureARB; +RGLSYMGLMULTITEXCOORD1DARBPROC __rglgen_glMultiTexCoord1dARB; +RGLSYMGLMULTITEXCOORD1DVARBPROC __rglgen_glMultiTexCoord1dvARB; +RGLSYMGLMULTITEXCOORD1FARBPROC __rglgen_glMultiTexCoord1fARB; +RGLSYMGLMULTITEXCOORD1FVARBPROC __rglgen_glMultiTexCoord1fvARB; +RGLSYMGLMULTITEXCOORD1IARBPROC __rglgen_glMultiTexCoord1iARB; +RGLSYMGLMULTITEXCOORD1IVARBPROC __rglgen_glMultiTexCoord1ivARB; +RGLSYMGLMULTITEXCOORD1SARBPROC __rglgen_glMultiTexCoord1sARB; +RGLSYMGLMULTITEXCOORD1SVARBPROC __rglgen_glMultiTexCoord1svARB; +RGLSYMGLMULTITEXCOORD2DARBPROC __rglgen_glMultiTexCoord2dARB; +RGLSYMGLMULTITEXCOORD2DVARBPROC __rglgen_glMultiTexCoord2dvARB; +RGLSYMGLMULTITEXCOORD2FARBPROC __rglgen_glMultiTexCoord2fARB; +RGLSYMGLMULTITEXCOORD2FVARBPROC __rglgen_glMultiTexCoord2fvARB; +RGLSYMGLMULTITEXCOORD2IARBPROC __rglgen_glMultiTexCoord2iARB; +RGLSYMGLMULTITEXCOORD2IVARBPROC __rglgen_glMultiTexCoord2ivARB; +RGLSYMGLMULTITEXCOORD2SARBPROC __rglgen_glMultiTexCoord2sARB; +RGLSYMGLMULTITEXCOORD2SVARBPROC __rglgen_glMultiTexCoord2svARB; +RGLSYMGLMULTITEXCOORD3DARBPROC __rglgen_glMultiTexCoord3dARB; +RGLSYMGLMULTITEXCOORD3DVARBPROC __rglgen_glMultiTexCoord3dvARB; +RGLSYMGLMULTITEXCOORD3FARBPROC __rglgen_glMultiTexCoord3fARB; +RGLSYMGLMULTITEXCOORD3FVARBPROC __rglgen_glMultiTexCoord3fvARB; +RGLSYMGLMULTITEXCOORD3IARBPROC __rglgen_glMultiTexCoord3iARB; +RGLSYMGLMULTITEXCOORD3IVARBPROC __rglgen_glMultiTexCoord3ivARB; +RGLSYMGLMULTITEXCOORD3SARBPROC __rglgen_glMultiTexCoord3sARB; +RGLSYMGLMULTITEXCOORD3SVARBPROC __rglgen_glMultiTexCoord3svARB; +RGLSYMGLMULTITEXCOORD4DARBPROC __rglgen_glMultiTexCoord4dARB; +RGLSYMGLMULTITEXCOORD4DVARBPROC __rglgen_glMultiTexCoord4dvARB; +RGLSYMGLMULTITEXCOORD4FARBPROC __rglgen_glMultiTexCoord4fARB; +RGLSYMGLMULTITEXCOORD4FVARBPROC __rglgen_glMultiTexCoord4fvARB; +RGLSYMGLMULTITEXCOORD4IARBPROC __rglgen_glMultiTexCoord4iARB; +RGLSYMGLMULTITEXCOORD4IVARBPROC __rglgen_glMultiTexCoord4ivARB; +RGLSYMGLMULTITEXCOORD4SARBPROC __rglgen_glMultiTexCoord4sARB; +RGLSYMGLMULTITEXCOORD4SVARBPROC __rglgen_glMultiTexCoord4svARB; +RGLSYMGLGENQUERIESARBPROC __rglgen_glGenQueriesARB; +RGLSYMGLDELETEQUERIESARBPROC __rglgen_glDeleteQueriesARB; +RGLSYMGLISQUERYARBPROC __rglgen_glIsQueryARB; +RGLSYMGLBEGINQUERYARBPROC __rglgen_glBeginQueryARB; +RGLSYMGLENDQUERYARBPROC __rglgen_glEndQueryARB; +RGLSYMGLGETQUERYIVARBPROC __rglgen_glGetQueryivARB; +RGLSYMGLGETQUERYOBJECTIVARBPROC __rglgen_glGetQueryObjectivARB; +RGLSYMGLGETQUERYOBJECTUIVARBPROC __rglgen_glGetQueryObjectuivARB; +RGLSYMGLPOINTPARAMETERFARBPROC __rglgen_glPointParameterfARB; +RGLSYMGLPOINTPARAMETERFVARBPROC __rglgen_glPointParameterfvARB; +RGLSYMGLGETGRAPHICSRESETSTATUSARBPROC __rglgen_glGetGraphicsResetStatusARB; +RGLSYMGLGETNTEXIMAGEARBPROC __rglgen_glGetnTexImageARB; +RGLSYMGLREADNPIXELSARBPROC __rglgen_glReadnPixelsARB; +RGLSYMGLGETNCOMPRESSEDTEXIMAGEARBPROC __rglgen_glGetnCompressedTexImageARB; +RGLSYMGLGETNUNIFORMFVARBPROC __rglgen_glGetnUniformfvARB; +RGLSYMGLGETNUNIFORMIVARBPROC __rglgen_glGetnUniformivARB; +RGLSYMGLGETNUNIFORMUIVARBPROC __rglgen_glGetnUniformuivARB; +RGLSYMGLGETNUNIFORMDVARBPROC __rglgen_glGetnUniformdvARB; +RGLSYMGLGETNMAPDVARBPROC __rglgen_glGetnMapdvARB; +RGLSYMGLGETNMAPFVARBPROC __rglgen_glGetnMapfvARB; +RGLSYMGLGETNMAPIVARBPROC __rglgen_glGetnMapivARB; +RGLSYMGLGETNPIXELMAPFVARBPROC __rglgen_glGetnPixelMapfvARB; +RGLSYMGLGETNPIXELMAPUIVARBPROC __rglgen_glGetnPixelMapuivARB; +RGLSYMGLGETNPIXELMAPUSVARBPROC __rglgen_glGetnPixelMapusvARB; +RGLSYMGLGETNPOLYGONSTIPPLEARBPROC __rglgen_glGetnPolygonStippleARB; +RGLSYMGLGETNCOLORTABLEARBPROC __rglgen_glGetnColorTableARB; +RGLSYMGLGETNCONVOLUTIONFILTERARBPROC __rglgen_glGetnConvolutionFilterARB; +RGLSYMGLGETNSEPARABLEFILTERARBPROC __rglgen_glGetnSeparableFilterARB; +RGLSYMGLGETNHISTOGRAMARBPROC __rglgen_glGetnHistogramARB; +RGLSYMGLGETNMINMAXARBPROC __rglgen_glGetnMinmaxARB; +RGLSYMGLMINSAMPLESHADINGARBPROC __rglgen_glMinSampleShadingARB; +RGLSYMGLDELETEOBJECTARBPROC __rglgen_glDeleteObjectARB; +RGLSYMGLGETHANDLEARBPROC __rglgen_glGetHandleARB; +RGLSYMGLDETACHOBJECTARBPROC __rglgen_glDetachObjectARB; +RGLSYMGLCREATESHADEROBJECTARBPROC __rglgen_glCreateShaderObjectARB; +RGLSYMGLSHADERSOURCEARBPROC __rglgen_glShaderSourceARB; +RGLSYMGLCOMPILESHADERARBPROC __rglgen_glCompileShaderARB; +RGLSYMGLCREATEPROGRAMOBJECTARBPROC __rglgen_glCreateProgramObjectARB; +RGLSYMGLATTACHOBJECTARBPROC __rglgen_glAttachObjectARB; +RGLSYMGLLINKPROGRAMARBPROC __rglgen_glLinkProgramARB; +RGLSYMGLUSEPROGRAMOBJECTARBPROC __rglgen_glUseProgramObjectARB; +RGLSYMGLVALIDATEPROGRAMARBPROC __rglgen_glValidateProgramARB; +RGLSYMGLUNIFORM1FARBPROC __rglgen_glUniform1fARB; +RGLSYMGLUNIFORM2FARBPROC __rglgen_glUniform2fARB; +RGLSYMGLUNIFORM3FARBPROC __rglgen_glUniform3fARB; +RGLSYMGLUNIFORM4FARBPROC __rglgen_glUniform4fARB; +RGLSYMGLUNIFORM1IARBPROC __rglgen_glUniform1iARB; +RGLSYMGLUNIFORM2IARBPROC __rglgen_glUniform2iARB; +RGLSYMGLUNIFORM3IARBPROC __rglgen_glUniform3iARB; +RGLSYMGLUNIFORM4IARBPROC __rglgen_glUniform4iARB; +RGLSYMGLUNIFORM1FVARBPROC __rglgen_glUniform1fvARB; +RGLSYMGLUNIFORM2FVARBPROC __rglgen_glUniform2fvARB; +RGLSYMGLUNIFORM3FVARBPROC __rglgen_glUniform3fvARB; +RGLSYMGLUNIFORM4FVARBPROC __rglgen_glUniform4fvARB; +RGLSYMGLUNIFORM1IVARBPROC __rglgen_glUniform1ivARB; +RGLSYMGLUNIFORM2IVARBPROC __rglgen_glUniform2ivARB; +RGLSYMGLUNIFORM3IVARBPROC __rglgen_glUniform3ivARB; +RGLSYMGLUNIFORM4IVARBPROC __rglgen_glUniform4ivARB; +RGLSYMGLUNIFORMMATRIX2FVARBPROC __rglgen_glUniformMatrix2fvARB; +RGLSYMGLUNIFORMMATRIX3FVARBPROC __rglgen_glUniformMatrix3fvARB; +RGLSYMGLUNIFORMMATRIX4FVARBPROC __rglgen_glUniformMatrix4fvARB; +RGLSYMGLGETOBJECTPARAMETERFVARBPROC __rglgen_glGetObjectParameterfvARB; +RGLSYMGLGETOBJECTPARAMETERIVARBPROC __rglgen_glGetObjectParameterivARB; +RGLSYMGLGETINFOLOGARBPROC __rglgen_glGetInfoLogARB; +RGLSYMGLGETATTACHEDOBJECTSARBPROC __rglgen_glGetAttachedObjectsARB; +RGLSYMGLGETUNIFORMLOCATIONARBPROC __rglgen_glGetUniformLocationARB; +RGLSYMGLGETACTIVEUNIFORMARBPROC __rglgen_glGetActiveUniformARB; +RGLSYMGLGETUNIFORMFVARBPROC __rglgen_glGetUniformfvARB; +RGLSYMGLGETUNIFORMIVARBPROC __rglgen_glGetUniformivARB; +RGLSYMGLGETSHADERSOURCEARBPROC __rglgen_glGetShaderSourceARB; +RGLSYMGLNAMEDSTRINGARBPROC __rglgen_glNamedStringARB; +RGLSYMGLDELETENAMEDSTRINGARBPROC __rglgen_glDeleteNamedStringARB; +RGLSYMGLCOMPILESHADERINCLUDEARBPROC __rglgen_glCompileShaderIncludeARB; +RGLSYMGLISNAMEDSTRINGARBPROC __rglgen_glIsNamedStringARB; +RGLSYMGLGETNAMEDSTRINGARBPROC __rglgen_glGetNamedStringARB; +RGLSYMGLGETNAMEDSTRINGIVARBPROC __rglgen_glGetNamedStringivARB; +RGLSYMGLTEXPAGECOMMITMENTARBPROC __rglgen_glTexPageCommitmentARB; +RGLSYMGLTEXBUFFERARBPROC __rglgen_glTexBufferARB; +RGLSYMGLCOMPRESSEDTEXIMAGE3DARBPROC __rglgen_glCompressedTexImage3DARB; +RGLSYMGLCOMPRESSEDTEXIMAGE2DARBPROC __rglgen_glCompressedTexImage2DARB; +RGLSYMGLCOMPRESSEDTEXIMAGE1DARBPROC __rglgen_glCompressedTexImage1DARB; +RGLSYMGLCOMPRESSEDTEXSUBIMAGE3DARBPROC __rglgen_glCompressedTexSubImage3DARB; +RGLSYMGLCOMPRESSEDTEXSUBIMAGE2DARBPROC __rglgen_glCompressedTexSubImage2DARB; +RGLSYMGLCOMPRESSEDTEXSUBIMAGE1DARBPROC __rglgen_glCompressedTexSubImage1DARB; +RGLSYMGLGETCOMPRESSEDTEXIMAGEARBPROC __rglgen_glGetCompressedTexImageARB; +RGLSYMGLLOADTRANSPOSEMATRIXFARBPROC __rglgen_glLoadTransposeMatrixfARB; +RGLSYMGLLOADTRANSPOSEMATRIXDARBPROC __rglgen_glLoadTransposeMatrixdARB; +RGLSYMGLMULTTRANSPOSEMATRIXFARBPROC __rglgen_glMultTransposeMatrixfARB; +RGLSYMGLMULTTRANSPOSEMATRIXDARBPROC __rglgen_glMultTransposeMatrixdARB; +RGLSYMGLWEIGHTBVARBPROC __rglgen_glWeightbvARB; +RGLSYMGLWEIGHTSVARBPROC __rglgen_glWeightsvARB; +RGLSYMGLWEIGHTIVARBPROC __rglgen_glWeightivARB; +RGLSYMGLWEIGHTFVARBPROC __rglgen_glWeightfvARB; +RGLSYMGLWEIGHTDVARBPROC __rglgen_glWeightdvARB; +RGLSYMGLWEIGHTUBVARBPROC __rglgen_glWeightubvARB; +RGLSYMGLWEIGHTUSVARBPROC __rglgen_glWeightusvARB; +RGLSYMGLWEIGHTUIVARBPROC __rglgen_glWeightuivARB; +RGLSYMGLWEIGHTPOINTERARBPROC __rglgen_glWeightPointerARB; +RGLSYMGLVERTEXBLENDARBPROC __rglgen_glVertexBlendARB; +RGLSYMGLBINDBUFFERARBPROC __rglgen_glBindBufferARB; +RGLSYMGLDELETEBUFFERSARBPROC __rglgen_glDeleteBuffersARB; +RGLSYMGLGENBUFFERSARBPROC __rglgen_glGenBuffersARB; +RGLSYMGLISBUFFERARBPROC __rglgen_glIsBufferARB; +RGLSYMGLBUFFERDATAARBPROC __rglgen_glBufferDataARB; +RGLSYMGLBUFFERSUBDATAARBPROC __rglgen_glBufferSubDataARB; +RGLSYMGLGETBUFFERSUBDATAARBPROC __rglgen_glGetBufferSubDataARB; +RGLSYMGLMAPBUFFERARBPROC __rglgen_glMapBufferARB; +RGLSYMGLUNMAPBUFFERARBPROC __rglgen_glUnmapBufferARB; +RGLSYMGLGETBUFFERPARAMETERIVARBPROC __rglgen_glGetBufferParameterivARB; +RGLSYMGLGETBUFFERPOINTERVARBPROC __rglgen_glGetBufferPointervARB; +RGLSYMGLVERTEXATTRIB1DARBPROC __rglgen_glVertexAttrib1dARB; +RGLSYMGLVERTEXATTRIB1DVARBPROC __rglgen_glVertexAttrib1dvARB; +RGLSYMGLVERTEXATTRIB1FARBPROC __rglgen_glVertexAttrib1fARB; +RGLSYMGLVERTEXATTRIB1FVARBPROC __rglgen_glVertexAttrib1fvARB; +RGLSYMGLVERTEXATTRIB1SARBPROC __rglgen_glVertexAttrib1sARB; +RGLSYMGLVERTEXATTRIB1SVARBPROC __rglgen_glVertexAttrib1svARB; +RGLSYMGLVERTEXATTRIB2DARBPROC __rglgen_glVertexAttrib2dARB; +RGLSYMGLVERTEXATTRIB2DVARBPROC __rglgen_glVertexAttrib2dvARB; +RGLSYMGLVERTEXATTRIB2FARBPROC __rglgen_glVertexAttrib2fARB; +RGLSYMGLVERTEXATTRIB2FVARBPROC __rglgen_glVertexAttrib2fvARB; +RGLSYMGLVERTEXATTRIB2SARBPROC __rglgen_glVertexAttrib2sARB; +RGLSYMGLVERTEXATTRIB2SVARBPROC __rglgen_glVertexAttrib2svARB; +RGLSYMGLVERTEXATTRIB3DARBPROC __rglgen_glVertexAttrib3dARB; +RGLSYMGLVERTEXATTRIB3DVARBPROC __rglgen_glVertexAttrib3dvARB; +RGLSYMGLVERTEXATTRIB3FARBPROC __rglgen_glVertexAttrib3fARB; +RGLSYMGLVERTEXATTRIB3FVARBPROC __rglgen_glVertexAttrib3fvARB; +RGLSYMGLVERTEXATTRIB3SARBPROC __rglgen_glVertexAttrib3sARB; +RGLSYMGLVERTEXATTRIB3SVARBPROC __rglgen_glVertexAttrib3svARB; +RGLSYMGLVERTEXATTRIB4NBVARBPROC __rglgen_glVertexAttrib4NbvARB; +RGLSYMGLVERTEXATTRIB4NIVARBPROC __rglgen_glVertexAttrib4NivARB; +RGLSYMGLVERTEXATTRIB4NSVARBPROC __rglgen_glVertexAttrib4NsvARB; +RGLSYMGLVERTEXATTRIB4NUBARBPROC __rglgen_glVertexAttrib4NubARB; +RGLSYMGLVERTEXATTRIB4NUBVARBPROC __rglgen_glVertexAttrib4NubvARB; +RGLSYMGLVERTEXATTRIB4NUIVARBPROC __rglgen_glVertexAttrib4NuivARB; +RGLSYMGLVERTEXATTRIB4NUSVARBPROC __rglgen_glVertexAttrib4NusvARB; +RGLSYMGLVERTEXATTRIB4BVARBPROC __rglgen_glVertexAttrib4bvARB; +RGLSYMGLVERTEXATTRIB4DARBPROC __rglgen_glVertexAttrib4dARB; +RGLSYMGLVERTEXATTRIB4DVARBPROC __rglgen_glVertexAttrib4dvARB; +RGLSYMGLVERTEXATTRIB4FARBPROC __rglgen_glVertexAttrib4fARB; +RGLSYMGLVERTEXATTRIB4FVARBPROC __rglgen_glVertexAttrib4fvARB; +RGLSYMGLVERTEXATTRIB4IVARBPROC __rglgen_glVertexAttrib4ivARB; +RGLSYMGLVERTEXATTRIB4SARBPROC __rglgen_glVertexAttrib4sARB; +RGLSYMGLVERTEXATTRIB4SVARBPROC __rglgen_glVertexAttrib4svARB; +RGLSYMGLVERTEXATTRIB4UBVARBPROC __rglgen_glVertexAttrib4ubvARB; +RGLSYMGLVERTEXATTRIB4UIVARBPROC __rglgen_glVertexAttrib4uivARB; +RGLSYMGLVERTEXATTRIB4USVARBPROC __rglgen_glVertexAttrib4usvARB; +RGLSYMGLVERTEXATTRIBPOINTERARBPROC __rglgen_glVertexAttribPointerARB; +RGLSYMGLENABLEVERTEXATTRIBARRAYARBPROC __rglgen_glEnableVertexAttribArrayARB; +RGLSYMGLDISABLEVERTEXATTRIBARRAYARBPROC __rglgen_glDisableVertexAttribArrayARB; +RGLSYMGLGETVERTEXATTRIBDVARBPROC __rglgen_glGetVertexAttribdvARB; +RGLSYMGLGETVERTEXATTRIBFVARBPROC __rglgen_glGetVertexAttribfvARB; +RGLSYMGLGETVERTEXATTRIBIVARBPROC __rglgen_glGetVertexAttribivARB; +RGLSYMGLGETVERTEXATTRIBPOINTERVARBPROC __rglgen_glGetVertexAttribPointervARB; +RGLSYMGLBINDATTRIBLOCATIONARBPROC __rglgen_glBindAttribLocationARB; +RGLSYMGLGETACTIVEATTRIBARBPROC __rglgen_glGetActiveAttribARB; +RGLSYMGLGETATTRIBLOCATIONARBPROC __rglgen_glGetAttribLocationARB; +RGLSYMGLWINDOWPOS2DARBPROC __rglgen_glWindowPos2dARB; +RGLSYMGLWINDOWPOS2DVARBPROC __rglgen_glWindowPos2dvARB; +RGLSYMGLWINDOWPOS2FARBPROC __rglgen_glWindowPos2fARB; +RGLSYMGLWINDOWPOS2FVARBPROC __rglgen_glWindowPos2fvARB; +RGLSYMGLWINDOWPOS2IARBPROC __rglgen_glWindowPos2iARB; +RGLSYMGLWINDOWPOS2IVARBPROC __rglgen_glWindowPos2ivARB; +RGLSYMGLWINDOWPOS2SARBPROC __rglgen_glWindowPos2sARB; +RGLSYMGLWINDOWPOS2SVARBPROC __rglgen_glWindowPos2svARB; +RGLSYMGLWINDOWPOS3DARBPROC __rglgen_glWindowPos3dARB; +RGLSYMGLWINDOWPOS3DVARBPROC __rglgen_glWindowPos3dvARB; +RGLSYMGLWINDOWPOS3FARBPROC __rglgen_glWindowPos3fARB; +RGLSYMGLWINDOWPOS3FVARBPROC __rglgen_glWindowPos3fvARB; +RGLSYMGLWINDOWPOS3IARBPROC __rglgen_glWindowPos3iARB; +RGLSYMGLWINDOWPOS3IVARBPROC __rglgen_glWindowPos3ivARB; +RGLSYMGLWINDOWPOS3SARBPROC __rglgen_glWindowPos3sARB; +RGLSYMGLWINDOWPOS3SVARBPROC __rglgen_glWindowPos3svARB; +RGLSYMGLMULTITEXCOORD1BOESPROC __rglgen_glMultiTexCoord1bOES; +RGLSYMGLMULTITEXCOORD1BVOESPROC __rglgen_glMultiTexCoord1bvOES; +RGLSYMGLMULTITEXCOORD2BOESPROC __rglgen_glMultiTexCoord2bOES; +RGLSYMGLMULTITEXCOORD2BVOESPROC __rglgen_glMultiTexCoord2bvOES; +RGLSYMGLMULTITEXCOORD3BOESPROC __rglgen_glMultiTexCoord3bOES; +RGLSYMGLMULTITEXCOORD3BVOESPROC __rglgen_glMultiTexCoord3bvOES; +RGLSYMGLMULTITEXCOORD4BOESPROC __rglgen_glMultiTexCoord4bOES; +RGLSYMGLMULTITEXCOORD4BVOESPROC __rglgen_glMultiTexCoord4bvOES; +RGLSYMGLTEXCOORD1BOESPROC __rglgen_glTexCoord1bOES; +RGLSYMGLTEXCOORD1BVOESPROC __rglgen_glTexCoord1bvOES; +RGLSYMGLTEXCOORD2BOESPROC __rglgen_glTexCoord2bOES; +RGLSYMGLTEXCOORD2BVOESPROC __rglgen_glTexCoord2bvOES; +RGLSYMGLTEXCOORD3BOESPROC __rglgen_glTexCoord3bOES; +RGLSYMGLTEXCOORD3BVOESPROC __rglgen_glTexCoord3bvOES; +RGLSYMGLTEXCOORD4BOESPROC __rglgen_glTexCoord4bOES; +RGLSYMGLTEXCOORD4BVOESPROC __rglgen_glTexCoord4bvOES; +RGLSYMGLVERTEX2BOESPROC __rglgen_glVertex2bOES; +RGLSYMGLVERTEX2BVOESPROC __rglgen_glVertex2bvOES; +RGLSYMGLVERTEX3BOESPROC __rglgen_glVertex3bOES; +RGLSYMGLVERTEX3BVOESPROC __rglgen_glVertex3bvOES; +RGLSYMGLVERTEX4BOESPROC __rglgen_glVertex4bOES; +RGLSYMGLVERTEX4BVOESPROC __rglgen_glVertex4bvOES; +RGLSYMGLALPHAFUNCXOESPROC __rglgen_glAlphaFuncxOES; +RGLSYMGLCLEARCOLORXOESPROC __rglgen_glClearColorxOES; +RGLSYMGLCLEARDEPTHXOESPROC __rglgen_glClearDepthxOES; +RGLSYMGLCLIPPLANEXOESPROC __rglgen_glClipPlanexOES; +RGLSYMGLCOLOR4XOESPROC __rglgen_glColor4xOES; +RGLSYMGLDEPTHRANGEXOESPROC __rglgen_glDepthRangexOES; +RGLSYMGLFOGXOESPROC __rglgen_glFogxOES; +RGLSYMGLFOGXVOESPROC __rglgen_glFogxvOES; +RGLSYMGLFRUSTUMXOESPROC __rglgen_glFrustumxOES; +RGLSYMGLGETCLIPPLANEXOESPROC __rglgen_glGetClipPlanexOES; +RGLSYMGLGETFIXEDVOESPROC __rglgen_glGetFixedvOES; +RGLSYMGLGETTEXENVXVOESPROC __rglgen_glGetTexEnvxvOES; +RGLSYMGLGETTEXPARAMETERXVOESPROC __rglgen_glGetTexParameterxvOES; +RGLSYMGLLIGHTMODELXOESPROC __rglgen_glLightModelxOES; +RGLSYMGLLIGHTMODELXVOESPROC __rglgen_glLightModelxvOES; +RGLSYMGLLIGHTXOESPROC __rglgen_glLightxOES; +RGLSYMGLLIGHTXVOESPROC __rglgen_glLightxvOES; +RGLSYMGLLINEWIDTHXOESPROC __rglgen_glLineWidthxOES; +RGLSYMGLLOADMATRIXXOESPROC __rglgen_glLoadMatrixxOES; +RGLSYMGLMATERIALXOESPROC __rglgen_glMaterialxOES; +RGLSYMGLMATERIALXVOESPROC __rglgen_glMaterialxvOES; +RGLSYMGLMULTMATRIXXOESPROC __rglgen_glMultMatrixxOES; +RGLSYMGLMULTITEXCOORD4XOESPROC __rglgen_glMultiTexCoord4xOES; +RGLSYMGLNORMAL3XOESPROC __rglgen_glNormal3xOES; +RGLSYMGLORTHOXOESPROC __rglgen_glOrthoxOES; +RGLSYMGLPOINTPARAMETERXVOESPROC __rglgen_glPointParameterxvOES; +RGLSYMGLPOINTSIZEXOESPROC __rglgen_glPointSizexOES; +RGLSYMGLPOLYGONOFFSETXOESPROC __rglgen_glPolygonOffsetxOES; +RGLSYMGLROTATEXOESPROC __rglgen_glRotatexOES; +RGLSYMGLSAMPLECOVERAGEOESPROC __rglgen_glSampleCoverageOES; +RGLSYMGLSCALEXOESPROC __rglgen_glScalexOES; +RGLSYMGLTEXENVXOESPROC __rglgen_glTexEnvxOES; +RGLSYMGLTEXENVXVOESPROC __rglgen_glTexEnvxvOES; +RGLSYMGLTEXPARAMETERXOESPROC __rglgen_glTexParameterxOES; +RGLSYMGLTEXPARAMETERXVOESPROC __rglgen_glTexParameterxvOES; +RGLSYMGLTRANSLATEXOESPROC __rglgen_glTranslatexOES; +RGLSYMGLACCUMXOESPROC __rglgen_glAccumxOES; +RGLSYMGLBITMAPXOESPROC __rglgen_glBitmapxOES; +RGLSYMGLBLENDCOLORXOESPROC __rglgen_glBlendColorxOES; +RGLSYMGLCLEARACCUMXOESPROC __rglgen_glClearAccumxOES; +RGLSYMGLCOLOR3XOESPROC __rglgen_glColor3xOES; +RGLSYMGLCOLOR3XVOESPROC __rglgen_glColor3xvOES; +RGLSYMGLCOLOR4XVOESPROC __rglgen_glColor4xvOES; +RGLSYMGLCONVOLUTIONPARAMETERXOESPROC __rglgen_glConvolutionParameterxOES; +RGLSYMGLCONVOLUTIONPARAMETERXVOESPROC __rglgen_glConvolutionParameterxvOES; +RGLSYMGLEVALCOORD1XOESPROC __rglgen_glEvalCoord1xOES; +RGLSYMGLEVALCOORD1XVOESPROC __rglgen_glEvalCoord1xvOES; +RGLSYMGLEVALCOORD2XOESPROC __rglgen_glEvalCoord2xOES; +RGLSYMGLEVALCOORD2XVOESPROC __rglgen_glEvalCoord2xvOES; +RGLSYMGLFEEDBACKBUFFERXOESPROC __rglgen_glFeedbackBufferxOES; +RGLSYMGLGETCONVOLUTIONPARAMETERXVOESPROC __rglgen_glGetConvolutionParameterxvOES; +RGLSYMGLGETHISTOGRAMPARAMETERXVOESPROC __rglgen_glGetHistogramParameterxvOES; +RGLSYMGLGETLIGHTXOESPROC __rglgen_glGetLightxOES; +RGLSYMGLGETMAPXVOESPROC __rglgen_glGetMapxvOES; +RGLSYMGLGETMATERIALXOESPROC __rglgen_glGetMaterialxOES; +RGLSYMGLGETPIXELMAPXVPROC __rglgen_glGetPixelMapxv; +RGLSYMGLGETTEXGENXVOESPROC __rglgen_glGetTexGenxvOES; +RGLSYMGLGETTEXLEVELPARAMETERXVOESPROC __rglgen_glGetTexLevelParameterxvOES; +RGLSYMGLINDEXXOESPROC __rglgen_glIndexxOES; +RGLSYMGLINDEXXVOESPROC __rglgen_glIndexxvOES; +RGLSYMGLLOADTRANSPOSEMATRIXXOESPROC __rglgen_glLoadTransposeMatrixxOES; +RGLSYMGLMAP1XOESPROC __rglgen_glMap1xOES; +RGLSYMGLMAP2XOESPROC __rglgen_glMap2xOES; +RGLSYMGLMAPGRID1XOESPROC __rglgen_glMapGrid1xOES; +RGLSYMGLMAPGRID2XOESPROC __rglgen_glMapGrid2xOES; +RGLSYMGLMULTTRANSPOSEMATRIXXOESPROC __rglgen_glMultTransposeMatrixxOES; +RGLSYMGLMULTITEXCOORD1XOESPROC __rglgen_glMultiTexCoord1xOES; +RGLSYMGLMULTITEXCOORD1XVOESPROC __rglgen_glMultiTexCoord1xvOES; +RGLSYMGLMULTITEXCOORD2XOESPROC __rglgen_glMultiTexCoord2xOES; +RGLSYMGLMULTITEXCOORD2XVOESPROC __rglgen_glMultiTexCoord2xvOES; +RGLSYMGLMULTITEXCOORD3XOESPROC __rglgen_glMultiTexCoord3xOES; +RGLSYMGLMULTITEXCOORD3XVOESPROC __rglgen_glMultiTexCoord3xvOES; +RGLSYMGLMULTITEXCOORD4XVOESPROC __rglgen_glMultiTexCoord4xvOES; +RGLSYMGLNORMAL3XVOESPROC __rglgen_glNormal3xvOES; +RGLSYMGLPASSTHROUGHXOESPROC __rglgen_glPassThroughxOES; +RGLSYMGLPIXELMAPXPROC __rglgen_glPixelMapx; +RGLSYMGLPIXELSTOREXPROC __rglgen_glPixelStorex; +RGLSYMGLPIXELTRANSFERXOESPROC __rglgen_glPixelTransferxOES; +RGLSYMGLPIXELZOOMXOESPROC __rglgen_glPixelZoomxOES; +RGLSYMGLPRIORITIZETEXTURESXOESPROC __rglgen_glPrioritizeTexturesxOES; +RGLSYMGLRASTERPOS2XOESPROC __rglgen_glRasterPos2xOES; +RGLSYMGLRASTERPOS2XVOESPROC __rglgen_glRasterPos2xvOES; +RGLSYMGLRASTERPOS3XOESPROC __rglgen_glRasterPos3xOES; +RGLSYMGLRASTERPOS3XVOESPROC __rglgen_glRasterPos3xvOES; +RGLSYMGLRASTERPOS4XOESPROC __rglgen_glRasterPos4xOES; +RGLSYMGLRASTERPOS4XVOESPROC __rglgen_glRasterPos4xvOES; +RGLSYMGLRECTXOESPROC __rglgen_glRectxOES; +RGLSYMGLRECTXVOESPROC __rglgen_glRectxvOES; +RGLSYMGLTEXCOORD1XOESPROC __rglgen_glTexCoord1xOES; +RGLSYMGLTEXCOORD1XVOESPROC __rglgen_glTexCoord1xvOES; +RGLSYMGLTEXCOORD2XOESPROC __rglgen_glTexCoord2xOES; +RGLSYMGLTEXCOORD2XVOESPROC __rglgen_glTexCoord2xvOES; +RGLSYMGLTEXCOORD3XOESPROC __rglgen_glTexCoord3xOES; +RGLSYMGLTEXCOORD3XVOESPROC __rglgen_glTexCoord3xvOES; +RGLSYMGLTEXCOORD4XOESPROC __rglgen_glTexCoord4xOES; +RGLSYMGLTEXCOORD4XVOESPROC __rglgen_glTexCoord4xvOES; +RGLSYMGLTEXGENXOESPROC __rglgen_glTexGenxOES; +RGLSYMGLTEXGENXVOESPROC __rglgen_glTexGenxvOES; +RGLSYMGLVERTEX2XOESPROC __rglgen_glVertex2xOES; +RGLSYMGLVERTEX2XVOESPROC __rglgen_glVertex2xvOES; +RGLSYMGLVERTEX3XOESPROC __rglgen_glVertex3xOES; +RGLSYMGLVERTEX3XVOESPROC __rglgen_glVertex3xvOES; +RGLSYMGLVERTEX4XOESPROC __rglgen_glVertex4xOES; +RGLSYMGLVERTEX4XVOESPROC __rglgen_glVertex4xvOES; +RGLSYMGLQUERYMATRIXXOESPROC __rglgen_glQueryMatrixxOES; +RGLSYMGLCLEARDEPTHFOESPROC __rglgen_glClearDepthfOES; +RGLSYMGLCLIPPLANEFOESPROC __rglgen_glClipPlanefOES; +RGLSYMGLDEPTHRANGEFOESPROC __rglgen_glDepthRangefOES; +RGLSYMGLFRUSTUMFOESPROC __rglgen_glFrustumfOES; +RGLSYMGLGETCLIPPLANEFOESPROC __rglgen_glGetClipPlanefOES; +RGLSYMGLORTHOFOESPROC __rglgen_glOrthofOES; +RGLSYMGLIMAGETRANSFORMPARAMETERIHPPROC __rglgen_glImageTransformParameteriHP; +RGLSYMGLIMAGETRANSFORMPARAMETERFHPPROC __rglgen_glImageTransformParameterfHP; +RGLSYMGLIMAGETRANSFORMPARAMETERIVHPPROC __rglgen_glImageTransformParameterivHP; +RGLSYMGLIMAGETRANSFORMPARAMETERFVHPPROC __rglgen_glImageTransformParameterfvHP; +RGLSYMGLGETIMAGETRANSFORMPARAMETERIVHPPROC __rglgen_glGetImageTransformParameterivHP; +RGLSYMGLGETIMAGETRANSFORMPARAMETERFVHPPROC __rglgen_glGetImageTransformParameterfvHP; diff --git a/src/libretro/libretro-common/glsym/rglgen.c b/src/libretro/libretro-common/glsym/rglgen.c new file mode 100644 index 000000000..d1c4119db --- /dev/null +++ b/src/libretro/libretro-common/glsym/rglgen.c @@ -0,0 +1,45 @@ +/* Copyright (C) 2010-2020 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this libretro SDK code part (glsym). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * 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: + * + * 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, + * 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. + */ + +#include +#include + +#include +#include + +void rglgen_resolve_symbols_custom(rglgen_proc_address_t proc, + const struct rglgen_sym_map *map) +{ + for (; map->sym; map++) + { + rglgen_func_t func = proc(map->sym); + memcpy(map->ptr, &func, sizeof(func)); + } +} + +void rglgen_resolve_symbols(rglgen_proc_address_t proc) +{ + if (!proc) + return; + + rglgen_resolve_symbols_custom(proc, rglgen_symbol_map); +} diff --git a/src/libretro/libretro-common/glsym/rglgen.py b/src/libretro/libretro-common/glsym/rglgen.py new file mode 100755 index 000000000..ee43be2c8 --- /dev/null +++ b/src/libretro/libretro-common/glsym/rglgen.py @@ -0,0 +1,147 @@ +#!/usr/bin/env python3 + +""" + License statement applies to this file (glgen.py) only. + + Permission is hereby granted, free of charge, + 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: + + 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, + 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. +""" + +import sys +import os +import re + +banned_ext = [ 'AMD', 'APPLE', 'NV', 'NVX', 'ATI', '3DLABS', 'SUN', 'SGI', 'SGIX', 'SGIS', 'INTEL', '3DFX', 'IBM', 'MESA', 'GREMEDY', 'OML', 'PGI', 'I3D', 'INGL', 'MTX', 'QCOM', 'IMG', 'ANGLE', 'SUNX', 'INGR' ] + +def noext(sym): + for ext in banned_ext: + if sym.endswith(ext): + return False + return True + +def fix_multiline_functions(lines): + fixed_lines = [] + temp_lines = [] + for line in lines: + if line.count('(') > line.count(')'): + temp_lines.append(line) + else: + if len(temp_lines) > 0: + if line.count(')') > line.count('('): + temp_lines.append(line) + fixed_line = re.sub(' +',' ', ''.join(temp_lines).replace('\n','').replace('\t','')) + fixed_lines.append(fixed_line) + temp_lines = [] + else: + temp_lines.append(line) + else: + fixed_lines.append(line) + return fixed_lines + +def find_gl_symbols(lines): + typedefs = [] + syms = [] + for line in lines: + m = re.search(r'^typedef.+PFN(\S+)PROC.+$', line) + g = re.search(r'^.+(gl\S+)\W*\(.+\).*$', line) + if m and noext(m.group(1)): + typedefs.append(m.group(0).replace('PFN', 'RGLSYM').replace('GLDEBUGPROC', 'RGLGENGLDEBUGPROC')) + if g and noext(g.group(1)): + syms.append(g.group(1)) + return (typedefs, syms) + +def generate_defines(gl_syms): + res = [] + for line in gl_syms: + res.append('#define {} __rglgen_{}'.format(line, line)) + return res + +def generate_declarations(gl_syms): + return ['RGLSYM' + x.upper() + 'PROC ' + '__rglgen_' + x + ';' for x in gl_syms] + +def generate_macros(gl_syms): + return [' SYM(' + x.replace('gl', '') + '),' for x in gl_syms] + +def dump(f, lines): + f.write('\n'.join(lines)) + f.write('\n\n') + +if __name__ == '__main__': + + if len(sys.argv) > 4: + for banned in sys.argv[4:]: + banned_ext.append(banned) + + with open(sys.argv[1], 'r') as f: + lines = fix_multiline_functions(f.readlines()) + typedefs, syms = find_gl_symbols(lines) + + overrides = generate_defines(syms) + declarations = generate_declarations(syms) + externs = ['extern ' + x for x in declarations] + + macros = generate_macros(syms) + + with open(sys.argv[2], 'w') as f: + f.write('#ifndef RGLGEN_DECL_H__\n') + f.write('#define RGLGEN_DECL_H__\n') + + f.write('#ifdef __cplusplus\n') + f.write('extern "C" {\n') + f.write('#endif\n') + + f.write('#ifdef GL_APIENTRY\n') + f.write('typedef void (GL_APIENTRY *RGLGENGLDEBUGPROC)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*);\n') + f.write('#else\n') + f.write('#ifndef APIENTRY\n') + f.write('#define APIENTRY\n') + f.write('#endif\n') + f.write('#ifndef APIENTRYP\n') + f.write('#define APIENTRYP APIENTRY *\n') + f.write('#endif\n') + f.write('typedef void (APIENTRY *RGLGENGLDEBUGPROCARB)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*);\n') + f.write('typedef void (APIENTRY *RGLGENGLDEBUGPROC)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*);\n') + f.write('#endif\n') + + f.write('#ifndef GL_OES_EGL_image\n') + f.write('typedef void *GLeglImageOES;\n') + f.write('#endif\n') + + f.write('#if !defined(GL_OES_fixed_point) && !defined(HAVE_OPENGLES2)\n') + f.write('typedef GLint GLfixed;\n') + f.write('#endif\n') + + dump(f, typedefs) + dump(f, overrides) + dump(f, externs) + + f.write('struct rglgen_sym_map { const char *sym; void *ptr; };\n') + f.write('extern const struct rglgen_sym_map rglgen_symbol_map[];\n') + + f.write('#ifdef __cplusplus\n') + f.write('}\n') + f.write('#endif\n') + + f.write('#endif\n') + + with open(sys.argv[3], 'w') as f: + f.write('#include "glsym/glsym.h"\n') + f.write('#include \n') + f.write('#define SYM(x) { "gl" #x, &(gl##x) }\n') + f.write('const struct rglgen_sym_map rglgen_symbol_map[] = {\n') + dump(f, macros) + f.write(' { NULL, NULL },\n') + f.write('};\n') + dump(f, declarations) diff --git a/src/libretro/libretro-common/glsym/xglgen.py b/src/libretro/libretro-common/glsym/xglgen.py new file mode 100644 index 000000000..215ffff3b --- /dev/null +++ b/src/libretro/libretro-common/glsym/xglgen.py @@ -0,0 +1,156 @@ +#!/usr/bin/env python3 + +""" + License statement applies to this file (xglgen.py) only. + + Permission is hereby granted, free of charge, + 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: + + 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, + 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. +""" + +import sys +import os +import re + +banned_ext = [ 'AMD', 'APPLE', 'NV', 'NVX', 'ATI', '3DLABS', 'SUN', 'SGI', 'SGIX', 'SGIS', 'INTEL', '3DFX', 'IBM', 'MESA', 'GREMEDY', 'OML', 'PGI', 'I3D', 'INGL', 'MTX', 'QCOM', 'IMG', 'ANGLE', 'SUNX', 'INGR' ] + +def noext(sym): + for ext in banned_ext: + if sym.endswith(ext): + return False + return True + +def fix_multiline_functions(lines): + fixed_lines = [] + temp_lines = [] + for line in lines: + if line.count('(') > line.count(')'): + temp_lines.append(line) + else: + if len(temp_lines) > 0: + if line.count(')') > line.count('('): + temp_lines.append(line) + fixed_line = re.sub(' +',' ', ''.join(temp_lines).replace('\n','').replace('\t','')) + fixed_lines.append(fixed_line) + temp_lines = [] + else: + temp_lines.append(line) + else: + fixed_lines.append(line) + return fixed_lines + +def find_gl_symbols(lines): + typedefs = [] + syms = [] + for line in lines: + # Note this doesn't work automated; this script is designed as a helper + m = re.search(r'^typedef.+PFN(\S+)PROC.+$', line) + g = re.search(r'^GLAPI\s(.+)\s(.+)\s(gl\S+)\W*\((.+)\).*', line) + if g and noext(g.group(3)): + typedefs.append('typedef ' + g.group(1) + ' (APIENTRYP RGLSYM' + g.group(3).upper() + 'PROC) (' + g.group(4) + ');') + syms.append(g.group(3)) + + return (typedefs, syms) + +def generate_defines(gl_syms): + res = [] + for line in gl_syms: + res.append('#define {} __rglgen_{}'.format(line, line)) + return res + +def generate_declarations(gl_syms): + return ['RGLSYM' + x.upper() + 'PROC ' + x + ';' for x in gl_syms] + +def generate_macros(gl_syms): + return [' SYM(' + x.replace('gl', '') + '),' for x in gl_syms] + +def dump(f, lines): + f.write('\n'.join(lines)) + f.write('\n\n') + +if __name__ == '__main__': + + if len(sys.argv) > 4: + for banned in sys.argv[4:]: + banned_ext.append(banned) + + with open(sys.argv[1], 'r') as f: + lines = fix_multiline_functions(f.readlines()) + typedefs, syms = find_gl_symbols(lines) + + overrides = generate_defines(syms) + declarations = generate_declarations(syms) + externs = ['extern ' + x for x in declarations] + + macros = generate_macros(syms) + + with open(sys.argv[2], 'w') as f: + f.write('#ifndef RGLGEN_DECL_H__\n') + f.write('#define RGLGEN_DECL_H__\n') + + f.write('#ifdef __cplusplus\n') + f.write('extern "C" {\n') + f.write('#endif\n') + + f.write('#ifdef GL_APIENTRY\n') + f.write('typedef void (GL_APIENTRY *RGLGENGLDEBUGPROC)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*);\n') + f.write('typedef void (GL_APIENTRY *RGLGENGLDEBUGPROCKHR)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*);\n') + f.write('#else\n') + f.write('#ifndef APIENTRY\n') + f.write('#define APIENTRY\n') + f.write('#endif\n') + f.write('#ifndef APIENTRYP\n') + f.write('#define APIENTRYP APIENTRY *\n') + f.write('#endif\n') + f.write('typedef void (APIENTRY *RGLGENGLDEBUGPROCARB)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*);\n') + f.write('typedef void (APIENTRY *RGLGENGLDEBUGPROC)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*);\n') + f.write('#endif\n') + + f.write('#ifndef GL_OES_EGL_image\n') + f.write('typedef void *GLeglImageOES;\n') + f.write('#endif\n') + + f.write('#if !defined(GL_OES_fixed_point) && !defined(HAVE_OPENGLES2)\n') + f.write('typedef GLint GLfixed;\n') + f.write('#endif\n') + + f.write('#if defined(OSX) && !defined(MAC_OS_X_VERSION_10_7)\n') + f.write('typedef long long int GLint64;\n') + f.write('typedef unsigned long long int GLuint64;\n') + f.write('typedef unsigned long long int GLuint64EXT;\n') + f.write('typedef struct __GLsync *GLsync;\n') + f.write('#endif\n') + + dump(f, typedefs) + dump(f, overrides) + dump(f, externs) + + f.write('struct rglgen_sym_map { const char *sym; void *ptr; };\n') + f.write('extern const struct rglgen_sym_map rglgen_symbol_map[];\n') + + f.write('#ifdef __cplusplus\n') + f.write('}\n') + f.write('#endif\n') + + f.write('#endif\n') + + with open(sys.argv[3], 'w') as f: + f.write('#include "glsym/glsym.h"\n') + f.write('#include \n') + f.write('#define SYM(x) { "gl" #x, &(gl##x) }\n') + f.write('const struct rglgen_sym_map rglgen_symbol_map[] = {\n') + dump(f, macros) + f.write(' { NULL, NULL },\n') + f.write('};\n') + dump(f, declarations) diff --git a/src/libretro/libretro-common/include/array/rbuf.h b/src/libretro/libretro-common/include/array/rbuf.h new file mode 100644 index 000000000..deb045fbb --- /dev/null +++ b/src/libretro/libretro-common/include/array/rbuf.h @@ -0,0 +1,120 @@ +/* Copyright (C) 2010-2020 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (rbuf.h). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * 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: + * + * 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, + * 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. + */ + +#ifndef __LIBRETRO_SDK_ARRAY_RBUF_H__ +#define __LIBRETRO_SDK_ARRAY_RBUF_H__ + +/* + * This file implements stretchy buffers as invented (?) by Sean Barrett. + * Based on the implementation from the public domain Bitwise project + * by Per Vognsen - https://github.com/pervognsen/bitwise + * + * It's a super simple type safe dynamic array for C with no need + * to predeclare any type or anything. + * The first time an element is added, memory for 16 elements are allocated. + * Then every time length is about to exceed capacity, capacity is doubled. + * + * Be careful not to supply modifying statements to the macro arguments. + * Something like RBUF_REMOVE(buf, i--); would have unintended results. + * + * Sample usage: + * + * mytype_t* buf = NULL; + * RBUF_PUSH(buf, some_element); + * RBUF_PUSH(buf, other_element); + * -- now RBUF_LEN(buf) == 2, buf[0] == some_element, buf[1] == other_element + * + * -- Free allocated memory: + * RBUF_FREE(buf); + * -- now buf == NULL, RBUF_LEN(buf) == 0, RBUF_CAP(buf) == 0 + * + * -- Explicitly increase allocated memory and set capacity: + * RBUF_FIT(buf, 100); + * -- now RBUF_LEN(buf) == 0, RBUF_CAP(buf) == 100 + * + * -- Resize buffer (does not initialize or zero memory!) + * RBUF_RESIZE(buf, 200); + * -- now RBUF_LEN(buf) == 200, RBUF_CAP(buf) == 200 + * + * -- To handle running out of memory: + * bool ran_out_of_memory = !RBUF_TRYFIT(buf, 1000); + * -- before RESIZE or PUSH. When out of memory, buf will stay unmodified. + */ + +#include /* for MAX */ +#include /* for malloc, realloc */ + +#define RBUF__HDR(b) (((struct rbuf__hdr *)(b))-1) + +#define RBUF_LEN(b) ((b) ? RBUF__HDR(b)->len : 0) +#define RBUF_CAP(b) ((b) ? RBUF__HDR(b)->cap : 0) +#define RBUF_END(b) ((b) + RBUF_LEN(b)) +#define RBUF_SIZEOF(b) ((b) ? RBUF_LEN(b)*sizeof(*b) : 0) + +#define RBUF_FREE(b) ((b) ? (free(RBUF__HDR(b)), (b) = NULL) : 0) +#define RBUF_FIT(b, n) ((size_t)(n) <= RBUF_CAP(b) ? 0 : (*(void**)(&(b)) = rbuf__grow((b), (n), sizeof(*(b))))) +#define RBUF_PUSH(b, val) (RBUF_FIT((b), 1 + RBUF_LEN(b)), (b)[RBUF__HDR(b)->len++] = (val)) +#define RBUF_POP(b) (b)[--RBUF__HDR(b)->len] +#define RBUF_RESIZE(b, sz) (RBUF_FIT((b), (sz)), ((b) ? RBUF__HDR(b)->len = (sz) : 0)) +#define RBUF_CLEAR(b) ((b) ? RBUF__HDR(b)->len = 0 : 0) +#define RBUF_TRYFIT(b, n) (RBUF_FIT((b), (n)), (((b) && RBUF_CAP(b) >= (size_t)(n)) || !(n))) +#define RBUF_REMOVE(b, idx) memmove((b) + (idx), (b) + (idx) + 1, (--RBUF__HDR(b)->len - (idx)) * sizeof(*(b))) + +struct rbuf__hdr +{ + size_t len; + size_t cap; +}; + +#ifdef __GNUC__ +__attribute__((__unused__)) +#elif defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4505) //unreferenced local function has been removed +#endif +static void *rbuf__grow(void *buf, + size_t new_len, size_t elem_size) +{ + struct rbuf__hdr *new_hdr; + size_t new_cap = MAX(2 * RBUF_CAP(buf), MAX(new_len, 16)); + size_t new_size = sizeof(struct rbuf__hdr) + new_cap*elem_size; + if (buf) + { + new_hdr = (struct rbuf__hdr *)realloc(RBUF__HDR(buf), new_size); + if (!new_hdr) + return buf; /* out of memory, return unchanged */ + } + else + { + new_hdr = (struct rbuf__hdr *)malloc(new_size); + if (!new_hdr) + return NULL; /* out of memory */ + new_hdr->len = 0; + } + new_hdr->cap = new_cap; + return new_hdr + 1; +} +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +#endif diff --git a/src/libretro/libretro-common/include/array/rhmap.h b/src/libretro/libretro-common/include/array/rhmap.h new file mode 100644 index 000000000..d6aec9014 --- /dev/null +++ b/src/libretro/libretro-common/include/array/rhmap.h @@ -0,0 +1,285 @@ +/* Copyright (C) 2010-2020 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (rhmap.h). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * 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: + * + * 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, + * 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. + */ + +#ifndef __LIBRETRO_SDK_ARRAY_RHMAP_H__ +#define __LIBRETRO_SDK_ARRAY_RHMAP_H__ + +/* + * This file implements a hash map with 32-bit keys. + * Based on the implementation from the public domain Bitwise project + * by Per Vognsen - https://github.com/pervognsen/bitwise + * + * It's a super simple type safe hash map for C with no need + * to predeclare any type or anything. + * Will always allocate memory for twice the amount of max elements + * so larger structs should be stored as pointers or indices to an array. + * Can be used in C++ with POD types (without any constructor/destructor). + * + * Be careful not to supply modifying statements to the macro arguments. + * Something like RHMAP_FIT(map, i++); would have unintended results. + * + * Sample usage: + * + * -- Set 2 elements with string keys and mytype_t values: + * mytype_t* map = NULL; + * RHMAP_SET_STR(map, "foo", foo_element); + * RHMAP_SET_STR(map, "bar", bar_element); + * -- now RHMAP_LEN(map) == 2, RHMAP_GET_STR(map, "foo") == foo_element + * + * -- Check if keys exist: + * bool has_foo = RHMAP_HAS_STR(map, "foo"); + * bool has_baz = RHMAP_HAS_STR(map, "baz"); + * -- now has_foo == true, has_baz == false + * + * -- Removing a key: + * bool removed = RHMAP_DEL_STR(map, "bar"); + * bool removed_again = RHMAP_DEL_STR(map, "bar"); + * -- now RHMAP_LEN(map) == 1, removed == true, removed_again == false + * + * -- Add/modify via pointer: + * mytype_t* p_elem = RHMAP_PTR_STR(map, "qux"); + * p_elem->a = 123; + * -- New keys initially have memory uninitialized + * -- Pointers can get invalidated when a key is added/removed + * + * -- Looking up the index for a given key: + * ptrdiff_t idx_foo = RHMAP_IDX_STR(map, "foo"); + * ptrdiff_t idx_invalid = RHMAP_IDX_STR(map, "invalid"); + * -- now idx_foo >= 0, idx_invalid == -1, map[idx_foo] == foo_element + * -- Indices can change when a key is added/removed + * + * -- Clear all elements (keep memory allocated): + * RHMAP_CLEAR(map); + * -- now RHMAP_LEN(map) == 0, RHMAP_CAP(map) == 16 + * + * -- Reserve memory for at least N elements: + * RHMAP_FIT(map, 30); + * -- now RHMAP_LEN(map) == 0, RHMAP_CAP(map) == 64 + * + * -- Add elements with custom hash keys: + * RHMAP_SET(map, my_uint32_hash(key1), some_element); + * RHMAP_SET(map, my_uint32_hash(key2), other_element); + * -- now RHMAP_LEN(map) == 2, _GET/_HAS/_DEL/_PTR/_IDX also exist + * + * -- Iterate elements (random order, order can change on insert): + * for (size_t i = 0, cap = RHMAP_CAP(map); i != cap, i++) + * if (RHMAP_KEY(map, i)) + * ------ here map[i] is the value of key RHMAP_KEY(map, i) + * + * -- Set a custom null value (is zeroed by default): + * RHMAP_SETNULLVAL(map, map_null); + * -- now RHMAP_GET_STR(map, "invalid") == map_null + * + * -- Free allocated memory: + * RHMAP_FREE(map); + * -- now map == NULL, RHMAP_LEN(map) == 0, RHMAP_CAP(map) == 0 + * + * -- To handle running out of memory: + * bool ran_out_of_memory = !RHMAP_TRYFIT(map, 1000); + * -- before setting an element (with SET, PTR or NULLVAL). + * -- When out of memory, map will stay unmodified. + * + */ + +#include /* for malloc, realloc */ +#include /* for memcpy, memset */ +#include /* for ptrdiff_t, size_t */ +#include /* for uint32_t */ + +#define RHMAP_LEN(b) ((b) ? RHMAP__HDR(b)->len : 0) +#define RHMAP_MAX(b) ((b) ? RHMAP__HDR(b)->maxlen : 0) +#define RHMAP_CAP(b) ((b) ? RHMAP__HDR(b)->maxlen + 1 : 0) +#define RHMAP_KEY(b, idx) (RHMAP__HDR(b)->keys[idx]) +#define RHMAP_KEY_STR(b, idx) (RHMAP__HDR(b)->key_strs[idx]) +#define RHMAP_SETNULLVAL(b, val) (RHMAP__FIT1(b), b[-1] = (val)) +#define RHMAP_CLEAR(b) ((b) ? (memset(RHMAP__HDR(b)->keys, 0, RHMAP_CAP(b) * sizeof(uint32_t)), RHMAP__HDR(b)->len = 0) : 0) +#define RHMAP_FREE(b) ((b) ? (rhmap__free(RHMAP__HDR(b)), (b) = NULL) : 0) +#define RHMAP_FIT(b, n) ((!(n) || ((b) && (size_t)(n) * 2 <= RHMAP_MAX(b))) ? 0 : RHMAP__GROW(b, n)) +#define RHMAP_TRYFIT(b, n) (RHMAP_FIT((b), (n)), (!(n) || ((b) && (size_t)(n) * 2 <= RHMAP_MAX(b)))) + +#define RHMAP_SET(b, key, val) RHMAP_SET_FULL(b, key, NULL, val) +#define RHMAP_GET(b, key) RHMAP_GET_FULL(b, key, NULL) +#define RHMAP_HAS(b, key) RHMAP_HAS_FULL(b, key, NULL) +#define RHMAP_DEL(b, key) RHMAP_DEL_FULL(b, key, NULL) +#define RHMAP_PTR(b, key) RHMAP_PTR_FULL(b, key, NULL) +#define RHMAP_IDX(b, key) RHMAP_IDX_FULL(b, key, NULL) + +#ifdef __GNUC__ +#define RHMAP__UNUSED __attribute__((__unused__)) +#else +#define RHMAP__UNUSED +#endif + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4505) //unreferenced local function has been removed +#endif + +#define RHMAP_SET_FULL(b, key, str, val) (RHMAP__FIT1(b), b[rhmap__idx(RHMAP__HDR(b), (key), (str), 1, 0)] = (val)) +#define RHMAP_GET_FULL(b, key, str) (RHMAP__FIT1(b), b[rhmap__idx(RHMAP__HDR(b), (key), (str), 0, 0)]) +#define RHMAP_HAS_FULL(b, key, str) ((b) ? rhmap__idx(RHMAP__HDR(b), (key), (str), 0, 0) != -1 : 0) +#define RHMAP_DEL_FULL(b, key, str) ((b) ? rhmap__idx(RHMAP__HDR(b), (key), (str), 0, sizeof(*(b))) != -1 : 0) +#define RHMAP_PTR_FULL(b, key, str) (RHMAP__FIT1(b), &b[rhmap__idx(RHMAP__HDR(b), (key), (str), 1, 0)]) +#define RHMAP_IDX_FULL(b, key, str) ((b) ? rhmap__idx(RHMAP__HDR(b), (key), (str), 0, 0) : -1) + +#define RHMAP_SET_STR(b, string_key, val) RHMAP_SET_FULL(b, rhmap_hash_string(string_key), string_key, val) +#define RHMAP_GET_STR(b, string_key) RHMAP_GET_FULL(b, rhmap_hash_string(string_key), string_key) +#define RHMAP_HAS_STR(b, string_key) RHMAP_HAS_FULL(b, rhmap_hash_string(string_key), string_key) +#define RHMAP_DEL_STR(b, string_key) RHMAP_DEL_FULL(b, rhmap_hash_string(string_key), string_key) +#define RHMAP_PTR_STR(b, string_key) RHMAP_PTR_FULL(b, rhmap_hash_string(string_key), string_key) +#define RHMAP_IDX_STR(b, string_key) RHMAP_IDX_FULL(b, rhmap_hash_string(string_key), string_key) + +RHMAP__UNUSED static uint32_t rhmap_hash_string(const char* str) +{ + unsigned char c; + uint32_t hash = (uint32_t)0x811c9dc5; + while ((c = (unsigned char)*(str++)) != '\0') + hash = ((hash * (uint32_t)0x01000193) ^ (uint32_t)c); + return (hash ? hash : 1); +} + +struct rhmap__hdr { size_t len, maxlen; uint32_t *keys; char** key_strs; }; +#define RHMAP__HDR(b) (((struct rhmap__hdr *)&(b)[-1])-1) +#define RHMAP__GROW(b, n) (*(void**)(&(b)) = rhmap__grow((void*)(b), sizeof(*(b)), (size_t)(n))) +#define RHMAP__FIT1(b) ((b) && RHMAP_LEN(b) * 2 <= RHMAP_MAX(b) ? 0 : RHMAP__GROW(b, 0)) + +RHMAP__UNUSED static void* rhmap__grow(void* old_ptr, size_t elem_size, size_t reserve) +{ + struct rhmap__hdr *old_hdr = (old_ptr ? ((struct rhmap__hdr *)((char*)old_ptr-elem_size))-1 : NULL); + struct rhmap__hdr *new_hdr; + char *new_vals; + size_t new_max = (old_ptr ? old_hdr->maxlen * 2 + 1 : 15); + for (; new_max / 2 <= reserve; new_max = new_max * 2 + 1) + if (new_max == (size_t)-1) + return old_ptr; /* overflow */ + + new_hdr = (struct rhmap__hdr *)malloc(sizeof(struct rhmap__hdr) + (new_max + 2) * elem_size); + if (!new_hdr) + return old_ptr; /* out of memory */ + + new_hdr->maxlen = new_max; + new_hdr->keys = (uint32_t *)calloc(new_max + 1, sizeof(uint32_t)); + if (!new_hdr->keys) + { + /* out of memory */ + free(new_hdr); + return old_ptr; + } + new_hdr->key_strs = (char**)calloc(new_max + 1, sizeof(char*)); + if (!new_hdr->key_strs) + { + /* out of memory */ + free(new_hdr->keys); + free(new_hdr); + return old_ptr; + } + + new_vals = ((char*)(new_hdr + 1)) + elem_size; + if (old_ptr) + { + size_t i; + char* old_vals = ((char*)(old_hdr + 1)) + elem_size; + for (i = 0; i <= old_hdr->maxlen; i++) + { + uint32_t key, j; + if (!old_hdr->keys[i]) + continue; + for (key = old_hdr->keys[i], j = key;; j++) + { + if (!new_hdr->keys[j &= new_hdr->maxlen]) + { + new_hdr->keys[j] = key; + new_hdr->key_strs[j] = old_hdr->key_strs[i]; + memcpy(new_vals + j * elem_size, old_vals + i * elem_size, elem_size); + break; + } + } + } + memcpy(new_vals - elem_size, old_vals - elem_size, elem_size); + new_hdr->len = old_hdr->len; + free(old_hdr->keys); + free(old_hdr->key_strs); + free(old_hdr); + } + else + { + memset(new_vals - elem_size, 0, elem_size); + new_hdr->len = 0; + } + return new_vals; +} + +RHMAP__UNUSED static ptrdiff_t rhmap__idx(struct rhmap__hdr* hdr, uint32_t key, const char * str, int add, size_t del) +{ + uint32_t i; + + if (!key) + return (ptrdiff_t)-1; + + for (i = key;; i++) + { + if (hdr->keys[i &= hdr->maxlen] == key && (!hdr->key_strs[i] || !str || !strcmp(hdr->key_strs[i], str))) + { + if (del) + { + hdr->len--; + hdr->keys[i] = 0; + free(hdr->key_strs[i]); + hdr->key_strs[i] = NULL; + while ((key = hdr->keys[i = (i + 1) & hdr->maxlen]) != 0) + { + if ((key = (uint32_t)rhmap__idx(hdr, key, hdr->key_strs[i], 1, 0)) == i) continue; + hdr->len--; + hdr->keys[i] = 0; + free(hdr->key_strs[i]); + hdr->key_strs[i] = NULL; + memcpy(((char*)(hdr + 1)) + (key + 1) * del, + ((char*)(hdr + 1)) + (i + 1) * del, del); + } + } + return (ptrdiff_t)i; + } + if (!hdr->keys[i]) + { + if (add) { hdr->len++; hdr->keys[i] = key; if (str) hdr->key_strs[i] = strdup(str); return (ptrdiff_t)i; } + return (ptrdiff_t)-1; + } + } +} + +RHMAP__UNUSED static void rhmap__free(struct rhmap__hdr* hdr) +{ + size_t i; + for (i=0;imaxlen+1;i++) + { + free(hdr->key_strs[i]); + } + free(hdr->key_strs); + free(hdr->keys); + free(hdr); +} + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +#endif diff --git a/src/libretro/libretro-common/include/audio/audio_mix.h b/src/libretro/libretro-common/include/audio/audio_mix.h new file mode 100644 index 000000000..6a2adac17 --- /dev/null +++ b/src/libretro/libretro-common/include/audio/audio_mix.h @@ -0,0 +1,94 @@ +/* Copyright (C) 2010-2020 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (audio_mix.h). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * 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: + * + * 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, + * 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. + */ + +#ifndef __LIBRETRO_SDK_AUDIO_MIX_H__ +#define __LIBRETRO_SDK_AUDIO_MIX_H__ + +#include + +#include +#include +#ifdef _WIN32 +#include +#else +#include +#endif + +#include +#include