mirror of
https://github.com/CTCaer/RetroArch.git
synced 2025-03-06 18:37:11 +00:00
Merge branch 'master' into cheevos_loaded
This commit is contained in:
commit
d27e6746a1
28
.vscode/launch.json
vendored
Normal file
28
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "MINGW64 (MSYS2) debug",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/retroarch.exe",
|
||||
"args": [],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
"miDebuggerPath": "c:\\msys64\\mingw64\\bin\\gdb.exe",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
12
.vscode/settings.json
vendored
Normal file
12
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"terminal.integrated.shell.windows": "C:\\msys64\\usr\\bin\\bash.exe",
|
||||
"terminal.integrated.env.windows": {
|
||||
"PATH": "/mingw64/lib/ccache/bin:/mingw64/lib/ccache/bin:/mingw64/lib/ccache/bin:/mingw64/bin:/usr/local/bin:/usr/bin:/bin:$PATH",
|
||||
"MSYSTEM": "MINGW64",
|
||||
},
|
||||
"terminal.integrated.cursorBlinking": true,
|
||||
|
||||
"editor.tabSize": 3,
|
||||
"editor.renderWhitespace": "all",
|
||||
"editor.insertSpaces": true,
|
||||
}
|
91
.vscode/tasks.json
vendored
Normal file
91
.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"taskName": "Build",
|
||||
"type": "shell",
|
||||
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true },
|
||||
|
||||
"command": "./configure; make -j2",
|
||||
"options": {
|
||||
"shell": {
|
||||
"executable": "C:\\msys64\\usr\\bin\\bash.exe",
|
||||
"args": [
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
"taskName": "Build with debugging symbols",
|
||||
"type": "shell",
|
||||
|
||||
"group": "build",
|
||||
|
||||
"command": "./configure; DEBUG=1 make -j2",
|
||||
"options": {
|
||||
"shell": {
|
||||
"executable": "C:\\msys64\\usr\\bin\\bash.exe",
|
||||
"args": [
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
"taskName": "Build without reconfiguring",
|
||||
"type": "shell",
|
||||
|
||||
"group": "build",
|
||||
|
||||
"command": "make -j2",
|
||||
"options": {
|
||||
"shell": {
|
||||
"executable": "C:\\msys64\\usr\\bin\\bash.exe",
|
||||
"args": [
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
"taskName": "Clean",
|
||||
"type": "shell",
|
||||
|
||||
"group": "build",
|
||||
|
||||
"command": "make clean",
|
||||
"options": {
|
||||
"shell": {
|
||||
"executable": "C:\\msys64\\usr\\bin\\bash.exe",
|
||||
"args": [
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
"taskName": "Start",
|
||||
"type": "shell",
|
||||
|
||||
"group": {
|
||||
"kind": "test",
|
||||
"isDefault": true },
|
||||
|
||||
"command": "./retroarch -v",
|
||||
"options": {
|
||||
"shell": {
|
||||
"executable": "C:\\msys64\\usr\\bin\\bash.exe",
|
||||
"args": [
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -170,6 +170,7 @@ OBJ += frontend/frontend.o \
|
||||
tasks/task_audio_mixer.o \
|
||||
$(LIBRETRO_COMM_DIR)/encodings/encoding_utf.o \
|
||||
$(LIBRETRO_COMM_DIR)/encodings/encoding_crc32.o \
|
||||
$(LIBRETRO_COMM_DIR)/compat/fopen_utf8.o \
|
||||
$(LIBRETRO_COMM_DIR)/lists/file_list.o \
|
||||
$(LIBRETRO_COMM_DIR)/lists/dir_list.o \
|
||||
$(LIBRETRO_COMM_DIR)/file/retro_dirent.o \
|
||||
@ -1531,7 +1532,7 @@ ifneq ($(findstring Win32,$(OS)),)
|
||||
gfx/drivers_font/gdi_font.o \
|
||||
menu/drivers_display/menu_display_gdi.o
|
||||
|
||||
LIBS += -lmsimg32
|
||||
LIBS += -lmsimg32 -lhid -lsetupapi
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_AVFOUNDATION), 1)
|
||||
|
@ -18,24 +18,27 @@ OBJ += wiiu/system/exception_handler.o
|
||||
OBJ += wiiu/system/missing_libc_functions.o
|
||||
OBJ += wiiu/fs/sd_fat_devoptab.o
|
||||
OBJ += wiiu/fs/fs_utils.o
|
||||
OBJ += wiiu/controller_patcher/ControllerPatcher.o
|
||||
OBJ += wiiu/controller_patcher/ControllerPatcherWrapper.o
|
||||
OBJ += wiiu/controller_patcher/ConfigReader.o
|
||||
OBJ += wiiu/controller_patcher/config/ConfigParser.o
|
||||
OBJ += wiiu/controller_patcher/config/ConfigValues.o
|
||||
OBJ += wiiu/controller_patcher/network/ControllerPatcherNet.o
|
||||
OBJ += wiiu/controller_patcher/network/TCPServer.o
|
||||
OBJ += wiiu/controller_patcher/network/UDPClient.o
|
||||
OBJ += wiiu/controller_patcher/network/UDPServer.o
|
||||
OBJ += wiiu/controller_patcher/patcher/ControllerPatcherUtils.o
|
||||
OBJ += wiiu/controller_patcher/patcher/ControllerPatcherHID.o
|
||||
OBJ += wiiu/controller_patcher/utils/CPRetainVars.o
|
||||
OBJ += wiiu/controller_patcher/utils/CPStringTools.o
|
||||
OBJ += wiiu/controller_patcher/utils/PadConst.o
|
||||
OBJ += wiiu/controller_patcher/utils/FSHelper.o
|
||||
OBJ += wiiu/tex_shader.o
|
||||
OBJ += wiiu/hbl.o
|
||||
|
||||
ifeq ($(ENABLE_CONTROLLER_PATCHER), 1)
|
||||
OBJ += wiiu/controller_patcher/ControllerPatcher.o
|
||||
OBJ += wiiu/controller_patcher/ControllerPatcherWrapper.o
|
||||
OBJ += wiiu/controller_patcher/ConfigReader.o
|
||||
OBJ += wiiu/controller_patcher/config/ConfigParser.o
|
||||
OBJ += wiiu/controller_patcher/config/ConfigValues.o
|
||||
OBJ += wiiu/controller_patcher/network/ControllerPatcherNet.o
|
||||
OBJ += wiiu/controller_patcher/network/TCPServer.o
|
||||
OBJ += wiiu/controller_patcher/network/UDPClient.o
|
||||
OBJ += wiiu/controller_patcher/network/UDPServer.o
|
||||
OBJ += wiiu/controller_patcher/patcher/ControllerPatcherUtils.o
|
||||
OBJ += wiiu/controller_patcher/patcher/ControllerPatcherHID.o
|
||||
OBJ += wiiu/controller_patcher/utils/CPRetainVars.o
|
||||
OBJ += wiiu/controller_patcher/utils/CPStringTools.o
|
||||
OBJ += wiiu/controller_patcher/utils/PadConst.o
|
||||
OBJ += wiiu/controller_patcher/utils/FSHelper.o
|
||||
endif
|
||||
|
||||
DEFINES :=
|
||||
|
||||
ifeq ($(GRIFFIN_BUILD), 1)
|
||||
@ -158,6 +161,9 @@ CFLAGS += -DWIIU -DMSB_FIRST
|
||||
CFLAGS += -DHAVE_MAIN
|
||||
CFLAGS += -DHAVE_UPDATE_ASSETS
|
||||
CFLAGS += -DRARCH_INTERNAL -DRARCH_CONSOLE
|
||||
ifeq ($(ENABLE_CONTROLLER_PATCHER), 1)
|
||||
CFLAGS += -DENABLE_CONTROLLER_PATCHER
|
||||
endif
|
||||
CFLAGS += -DHAVE_FILTERS_BUILTIN $(DEFINES)
|
||||
|
||||
ifneq ($(PC_DEVELOPMENT_IP_ADDRESS),)
|
||||
|
@ -2723,9 +2723,8 @@ static bool config_load_file(const char *path, bool set_defaults,
|
||||
/* Sanitize fastforward_ratio value - previously range was -1
|
||||
* and up (with 0 being skipped) */
|
||||
if (settings->floats.fastforward_ratio < 0.0f)
|
||||
{
|
||||
configuration_set_float(settings, settings->floats.fastforward_ratio, 0.0f);
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_LAKKA
|
||||
settings->bools.ssh_enable = path_file_exists(LAKKA_SSH_PATH);
|
||||
|
@ -29,21 +29,28 @@
|
||||
#include "input/input_defines.h"
|
||||
|
||||
#define configuration_set_float(settings, var, newvar) \
|
||||
{ \
|
||||
settings->modified = true; \
|
||||
var = newvar
|
||||
var = newvar; \
|
||||
}
|
||||
|
||||
#define configuration_set_bool(settings, var, newvar) \
|
||||
{ \
|
||||
settings->modified = true; \
|
||||
var = newvar
|
||||
var = newvar; \
|
||||
}
|
||||
|
||||
#define configuration_set_uint(settings, var, newvar) \
|
||||
{ \
|
||||
settings->modified = true; \
|
||||
var = newvar
|
||||
var = newvar; \
|
||||
}
|
||||
|
||||
#define configuration_set_int(settings, var, newvar) \
|
||||
{ \
|
||||
settings->modified = true; \
|
||||
var = newvar
|
||||
|
||||
var = newvar; \
|
||||
}
|
||||
|
||||
enum override_type
|
||||
{
|
||||
|
@ -58,7 +58,9 @@
|
||||
#include <wiiu/vpad.h>
|
||||
#include <wiiu/kpad.h>
|
||||
|
||||
#include "wiiu/controller_patcher/ControllerPatcherWrapper.h"
|
||||
#if defined(ENABLE_CONTROLLER_PATCHER)
|
||||
#include "wiiu/controller_patcher/ControllerPatcherWrapper.h"
|
||||
#endif
|
||||
|
||||
#include <fat.h>
|
||||
#include <iosuhax.h>
|
||||
@ -430,7 +432,7 @@ int main(int argc, char **argv)
|
||||
KPADInit();
|
||||
#endif
|
||||
verbosity_enable();
|
||||
#ifndef IS_SALAMANDER
|
||||
#if !defined(IS_SALAMANDER) && defined(ENABLE_CONTROLLER_PATCHER)
|
||||
ControllerPatcherInit();
|
||||
#endif
|
||||
fflush(stdout);
|
||||
@ -492,7 +494,7 @@ int main(int argc, char **argv)
|
||||
|
||||
}
|
||||
while (1);
|
||||
#ifndef IS_SALAMANDER
|
||||
#if !defined(IS_SALAMANDER) && defined(ENABLE_CONTROLLER_PATCHER)
|
||||
ControllerPatcherDeInit();
|
||||
#endif
|
||||
main_exit(NULL);
|
||||
@ -523,22 +525,25 @@ void __eabi()
|
||||
__attribute__((weak))
|
||||
void __init(void)
|
||||
{
|
||||
extern void(*__CTOR_LIST__[])(void);
|
||||
void(**ctor)(void) = __CTOR_LIST__;
|
||||
extern void (*const __CTOR_LIST__)(void);
|
||||
extern void (*const __CTOR_END__)(void);
|
||||
|
||||
while (*ctor)
|
||||
void (*const *ctor)(void) = &__CTOR_LIST__;
|
||||
while (ctor < &__CTOR_END__) {
|
||||
(*ctor++)();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
__attribute__((weak))
|
||||
void __fini(void)
|
||||
{
|
||||
extern void(*__DTOR_LIST__[])(void);
|
||||
void(**ctor)(void) = __DTOR_LIST__;
|
||||
extern void (*const __DTOR_LIST__)(void);
|
||||
extern void (*const __DTOR_END__)(void);
|
||||
|
||||
while (*ctor)
|
||||
(*ctor++)();
|
||||
void (*const *dtor)(void) = &__DTOR_LIST__;
|
||||
while (dtor < &__DTOR_END__) {
|
||||
(*dtor++)();
|
||||
}
|
||||
}
|
||||
|
||||
/* libiosuhax related */
|
||||
@ -633,7 +638,7 @@ int __entry_menu(int argc, char **argv)
|
||||
int ret = main(argc, argv);
|
||||
|
||||
fsdev_exit();
|
||||
// __fini();
|
||||
__fini();
|
||||
memoryRelease();
|
||||
return ret;
|
||||
}
|
||||
@ -648,7 +653,10 @@ void _start(int argc, char **argv)
|
||||
main(argc, argv);
|
||||
|
||||
fsdev_exit();
|
||||
// __fini();
|
||||
|
||||
/* TODO: fix elf2rpl so it doesn't error with "Could not find matching symbol
|
||||
for relocation" then uncomment this */
|
||||
// __fini();
|
||||
memoryRelease();
|
||||
SYSRelaunchTitle(0, 0);
|
||||
exit(0);
|
||||
|
@ -340,7 +340,7 @@ static uint64_t frontend_win32_get_mem_total(void)
|
||||
{
|
||||
/* OSes below 2000 don't have the Ex version,
|
||||
* and non-Ex cannot work with >4GB RAM */
|
||||
#if _WIN32_WINNT > 0x0400
|
||||
#if _WIN32_WINNT >= 0x0500
|
||||
MEMORYSTATUSEX mem_info;
|
||||
mem_info.dwLength = sizeof(MEMORYSTATUSEX);
|
||||
GlobalMemoryStatusEx(&mem_info);
|
||||
@ -357,7 +357,7 @@ static uint64_t frontend_win32_get_mem_used(void)
|
||||
{
|
||||
/* OSes below 2000 don't have the Ex version,
|
||||
* and non-Ex cannot work with >4GB RAM */
|
||||
#if _WIN32_WINNT > 0x0400
|
||||
#if _WIN32_WINNT >= 0x0500
|
||||
MEMORYSTATUSEX mem_info;
|
||||
mem_info.dwLength = sizeof(MEMORYSTATUSEX);
|
||||
GlobalMemoryStatusEx(&mem_info);
|
||||
|
@ -14,16 +14,13 @@
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <gfx/math/matrix_4x4.h>
|
||||
#include <gfx/gl_capabilities.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../../config.h"
|
||||
#endif
|
||||
|
||||
#include "../drivers/gl_symlinks.h"
|
||||
#include "../video_coord_array.h"
|
||||
|
||||
#include "gl_common.h"
|
||||
|
||||
static void gl_size_format(GLint* internalFormat)
|
||||
{
|
||||
|
@ -17,7 +17,9 @@
|
||||
#ifndef __GL_COMMON_H
|
||||
#define __GL_COMMON_H
|
||||
|
||||
#include <boolean.h>
|
||||
#include <string.h>
|
||||
#include <retro_common_api.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../../config.h"
|
||||
@ -32,14 +34,124 @@
|
||||
#include "../font_driver.h"
|
||||
#include "../video_coord_array.h"
|
||||
#include "../video_driver.h"
|
||||
#include "../drivers/gl_symlinks.h"
|
||||
#include <glsym/glsym.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
#define MAX_FENCES 4
|
||||
#if defined(HAVE_PSGL)
|
||||
#define RARCH_GL_FRAMEBUFFER GL_FRAMEBUFFER_OES
|
||||
#define RARCH_GL_FRAMEBUFFER_COMPLETE GL_FRAMEBUFFER_COMPLETE_OES
|
||||
#define RARCH_GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_EXT
|
||||
#elif (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__)))
|
||||
#define RARCH_GL_FRAMEBUFFER GL_FRAMEBUFFER_EXT
|
||||
#define RARCH_GL_FRAMEBUFFER_COMPLETE GL_FRAMEBUFFER_COMPLETE_EXT
|
||||
#define RARCH_GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_EXT
|
||||
#else
|
||||
#define RARCH_GL_FRAMEBUFFER GL_FRAMEBUFFER
|
||||
#define RARCH_GL_FRAMEBUFFER_COMPLETE GL_FRAMEBUFFER_COMPLETE
|
||||
#define RARCH_GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0
|
||||
#endif
|
||||
|
||||
#ifndef ARB_sync
|
||||
typedef struct __GLsync *GLsync;
|
||||
#if defined(HAVE_OPENGLES2) || defined(HAVE_OPENGLES3) || defined(HAVE_OPENGLES_3_1) || defined(HAVE_OPENGLES_3_2)
|
||||
#define RARCH_GL_RENDERBUFFER GL_RENDERBUFFER
|
||||
#if defined(HAVE_OPENGLES2)
|
||||
#define RARCH_GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_OES
|
||||
#else
|
||||
#define RARCH_GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8
|
||||
#endif
|
||||
#define RARCH_GL_DEPTH_ATTACHMENT GL_DEPTH_ATTACHMENT
|
||||
#define RARCH_GL_STENCIL_ATTACHMENT GL_STENCIL_ATTACHMENT
|
||||
#elif (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__)))
|
||||
#define RARCH_GL_RENDERBUFFER GL_RENDERBUFFER_EXT
|
||||
#define RARCH_GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_EXT
|
||||
#define RARCH_GL_DEPTH_ATTACHMENT GL_DEPTH_ATTACHMENT_EXT
|
||||
#define RARCH_GL_STENCIL_ATTACHMENT GL_STENCIL_ATTACHMENT_EXT
|
||||
#elif defined(HAVE_PSGL)
|
||||
#define RARCH_GL_RENDERBUFFER GL_RENDERBUFFER_OES
|
||||
#define RARCH_GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_SCE
|
||||
#define RARCH_GL_DEPTH_ATTACHMENT GL_DEPTH_ATTACHMENT_OES
|
||||
#define RARCH_GL_STENCIL_ATTACHMENT GL_STENCIL_ATTACHMENT_OES
|
||||
#else
|
||||
#define RARCH_GL_RENDERBUFFER GL_RENDERBUFFER
|
||||
#define RARCH_GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8
|
||||
#define RARCH_GL_DEPTH_ATTACHMENT GL_DEPTH_ATTACHMENT
|
||||
#define RARCH_GL_STENCIL_ATTACHMENT GL_STENCIL_ATTACHMENT
|
||||
#endif
|
||||
|
||||
#if (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__)))
|
||||
#define RARCH_GL_MAX_RENDERBUFFER_SIZE GL_MAX_RENDERBUFFER_SIZE_EXT
|
||||
#elif defined(HAVE_PSGL)
|
||||
#define RARCH_GL_MAX_RENDERBUFFER_SIZE GL_MAX_RENDERBUFFER_SIZE_OES
|
||||
#else
|
||||
#define RARCH_GL_MAX_RENDERBUFFER_SIZE GL_MAX_RENDERBUFFER_SIZE
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_PSGL)
|
||||
#define glGenerateMipmap glGenerateMipmapOES
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) || defined(HAVE_PSGL)
|
||||
#define GL_RGBA32F GL_RGBA32F_ARB
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_PSGL)
|
||||
#define RARCH_GL_INTERNAL_FORMAT32 GL_ARGB_SCE
|
||||
#define RARCH_GL_INTERNAL_FORMAT16 GL_RGB5 /* TODO: Verify if this is really 565 or just 555. */
|
||||
#define RARCH_GL_TEXTURE_TYPE32 GL_BGRA
|
||||
#define RARCH_GL_TEXTURE_TYPE16 GL_BGRA
|
||||
#define RARCH_GL_FORMAT32 GL_UNSIGNED_INT_8_8_8_8_REV
|
||||
#define RARCH_GL_FORMAT16 GL_RGB5
|
||||
#elif defined(HAVE_OPENGLES)
|
||||
/* Imgtec/SGX headers have this missing. */
|
||||
#ifndef GL_BGRA_EXT
|
||||
#define GL_BGRA_EXT 0x80E1
|
||||
#endif
|
||||
#ifndef GL_BGRA8_EXT
|
||||
#define GL_BGRA8_EXT 0x93A1
|
||||
#endif
|
||||
#ifdef IOS
|
||||
/* Stupid Apple */
|
||||
#define RARCH_GL_INTERNAL_FORMAT32 GL_RGBA
|
||||
#else
|
||||
#define RARCH_GL_INTERNAL_FORMAT32 GL_BGRA_EXT
|
||||
#endif
|
||||
#define RARCH_GL_INTERNAL_FORMAT16 GL_RGB
|
||||
#define RARCH_GL_TEXTURE_TYPE32 GL_BGRA_EXT
|
||||
#define RARCH_GL_TEXTURE_TYPE16 GL_RGB
|
||||
#define RARCH_GL_FORMAT32 GL_UNSIGNED_BYTE
|
||||
#define RARCH_GL_FORMAT16 GL_UNSIGNED_SHORT_5_6_5
|
||||
#else
|
||||
/* On desktop, we always use 32-bit. */
|
||||
#define RARCH_GL_INTERNAL_FORMAT32 GL_RGBA8
|
||||
#define RARCH_GL_INTERNAL_FORMAT16 GL_RGBA8
|
||||
#define RARCH_GL_TEXTURE_TYPE32 GL_BGRA
|
||||
#define RARCH_GL_TEXTURE_TYPE16 GL_BGRA
|
||||
#define RARCH_GL_FORMAT32 GL_UNSIGNED_INT_8_8_8_8_REV
|
||||
#define RARCH_GL_FORMAT16 GL_UNSIGNED_INT_8_8_8_8_REV
|
||||
|
||||
/* GL_RGB565 internal format isn't in desktop GL
|
||||
* until 4.1 core (ARB_ES2_compatibility).
|
||||
* Check for this. */
|
||||
#ifndef GL_RGB565
|
||||
#define GL_RGB565 0x8D62
|
||||
#endif
|
||||
#define RARCH_GL_INTERNAL_FORMAT16_565 GL_RGB565
|
||||
#define RARCH_GL_TEXTURE_TYPE16_565 GL_RGB
|
||||
#define RARCH_GL_FORMAT16_565 GL_UNSIGNED_SHORT_5_6_5
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_OPENGLES2) /* TODO: Figure out exactly what. */
|
||||
#define NO_GL_CLAMP_TO_BORDER
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_OPENGLES)
|
||||
#ifndef GL_UNPACK_ROW_LENGTH
|
||||
#define GL_UNPACK_ROW_LENGTH 0x0CF2
|
||||
#endif
|
||||
|
||||
#ifndef GL_SRGB_ALPHA_EXT
|
||||
#define GL_SRGB_ALPHA_EXT 0x8C42
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef struct gl
|
||||
@ -54,11 +166,7 @@ typedef struct gl
|
||||
bool fbo_inited;
|
||||
bool fbo_feedback_enable;
|
||||
bool hw_render_fbo_init;
|
||||
bool hw_render_depth_init;
|
||||
bool has_fbo;
|
||||
bool has_srgb_fbo_gles3;
|
||||
bool has_fp_fbo;
|
||||
bool has_srgb_fbo;
|
||||
bool hw_render_use;
|
||||
bool core_context_in_use;
|
||||
|
||||
@ -71,7 +179,6 @@ typedef struct gl
|
||||
bool have_full_npot_support;
|
||||
bool have_mipmap;
|
||||
|
||||
bool egl_images;
|
||||
bool overlay_enable;
|
||||
bool overlay_full_screen;
|
||||
bool menu_texture_enable;
|
||||
@ -82,7 +189,6 @@ typedef struct gl
|
||||
|
||||
int version_major;
|
||||
int version_minor;
|
||||
int fbo_pass;
|
||||
|
||||
GLuint tex_mag_filter;
|
||||
GLuint tex_min_filter;
|
||||
@ -91,13 +197,9 @@ typedef struct gl
|
||||
GLuint pbo;
|
||||
GLuint *overlay_tex;
|
||||
GLuint menu_texture;
|
||||
GLuint vao;
|
||||
GLuint pbo_readback[4];
|
||||
GLuint texture[GFX_MAX_TEXTURES];
|
||||
GLuint fbo[GFX_MAX_SHADERS];
|
||||
GLuint fbo_texture[GFX_MAX_SHADERS];
|
||||
GLuint hw_render_fbo[GFX_MAX_TEXTURES];
|
||||
GLuint hw_render_depth[GFX_MAX_TEXTURES];
|
||||
|
||||
unsigned tex_index; /* For use with PREV. */
|
||||
unsigned textures;
|
||||
@ -110,7 +212,6 @@ typedef struct gl
|
||||
unsigned base_size; /* 2 or 4 */
|
||||
unsigned overlays;
|
||||
unsigned pbo_readback_index;
|
||||
unsigned fence_count;
|
||||
unsigned last_width[GFX_MAX_TEXTURES];
|
||||
unsigned last_height[GFX_MAX_TEXTURES];
|
||||
|
||||
@ -134,9 +235,7 @@ typedef struct gl
|
||||
video_info_t video_info;
|
||||
struct video_tex_info prev_info[GFX_MAX_TEXTURES];
|
||||
struct video_fbo_rect fbo_rect[GFX_MAX_SHADERS];
|
||||
struct gfx_fbo_scale fbo_scale[GFX_MAX_SHADERS];
|
||||
|
||||
GLsync fences[MAX_FENCES];
|
||||
const gl_renderchain_driver_t *renderchain_driver;
|
||||
void *renderchain_data;
|
||||
} gl_t;
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <X11/Xatom.h>
|
||||
@ -159,19 +160,27 @@ static void x11_set_window_class(Display *dpy, Window win)
|
||||
|
||||
static void x11_set_window_pid(Display *dpy, Window win)
|
||||
{
|
||||
long scret;
|
||||
char *hostname;
|
||||
pid_t pid = getpid();
|
||||
char hostname[HOST_NAME_MAX + 1];
|
||||
|
||||
XChangeProperty(dpy, win, XInternAtom(dpy, "_NET_WM_PID", False),
|
||||
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&pid, 1);
|
||||
XChangeProperty(dpy, win, XInternAtom(dpy, "_NET_WM_PID", False),
|
||||
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&pid, 1);
|
||||
|
||||
if(gethostname(hostname, HOST_NAME_MAX + 1) == -1)
|
||||
RARCH_WARN("Failed to get hostname.\n");
|
||||
else
|
||||
{
|
||||
XChangeProperty(dpy, win, XA_WM_CLIENT_MACHINE, XA_STRING, 8,
|
||||
PropModeReplace, (unsigned char *)hostname, strlen(hostname));
|
||||
}
|
||||
errno = 0;
|
||||
if((scret = sysconf(_SC_HOST_NAME_MAX)) == -1 && errno)
|
||||
return;
|
||||
if((hostname = malloc(scret + 1)) == NULL)
|
||||
return;
|
||||
|
||||
if(gethostname(hostname, scret + 1) == -1)
|
||||
RARCH_WARN("Failed to get hostname.\n");
|
||||
else
|
||||
{
|
||||
XChangeProperty(dpy, win, XA_WM_CLIENT_MACHINE, XA_STRING, 8,
|
||||
PropModeReplace, (unsigned char *)hostname, strlen(hostname));
|
||||
}
|
||||
free(hostname);
|
||||
}
|
||||
|
||||
void x11_set_window_attr(Display *dpy, Window win)
|
||||
|
107
gfx/drivers/gl.c
107
gfx/drivers/gl.c
@ -40,6 +40,7 @@
|
||||
|
||||
#include <gfx/gl_capabilities.h>
|
||||
#include <gfx/video_frame.h>
|
||||
#include <glsym/glsym.h>
|
||||
|
||||
#include "../../configuration.h"
|
||||
#include "../../dynamic.h"
|
||||
@ -543,11 +544,9 @@ static void gl_init_textures_data(gl_t *gl)
|
||||
static void gl_init_textures(gl_t *gl, const video_info_t *video)
|
||||
{
|
||||
unsigned i;
|
||||
GLenum internal_fmt, texture_type = 0, texture_fmt = 0;
|
||||
|
||||
/* Use regular textures if we use HW render. */
|
||||
gl->egl_images = !gl->hw_render_use && gl_check_capability(GL_CAPS_EGLIMAGE) &&
|
||||
video_context_driver_init_image_buffer(video);
|
||||
GLenum internal_fmt = gl->internal_fmt;
|
||||
GLenum texture_type = gl->texture_type;
|
||||
GLenum texture_fmt = gl->texture_fmt;
|
||||
|
||||
#ifdef HAVE_PSGL
|
||||
if (!gl->pbo)
|
||||
@ -559,10 +558,6 @@ static void gl_init_textures(gl_t *gl, const video_info_t *video)
|
||||
NULL, GL_STREAM_DRAW);
|
||||
#endif
|
||||
|
||||
internal_fmt = gl->internal_fmt;
|
||||
texture_type = gl->texture_type;
|
||||
texture_fmt = gl->texture_fmt;
|
||||
|
||||
#if defined(HAVE_OPENGLES) && !defined(HAVE_PSGL)
|
||||
/* GLES is picky about which format we use here.
|
||||
* Without extensions, we can *only* render to 16-bit FBOs. */
|
||||
@ -594,7 +589,7 @@ static void gl_init_textures(gl_t *gl, const video_info_t *video)
|
||||
|
||||
if (gl->renderchain_driver->init_texture_reference)
|
||||
gl->renderchain_driver->init_texture_reference(
|
||||
gl, i, internal_fmt,
|
||||
gl, gl->renderchain_data, i, internal_fmt,
|
||||
texture_fmt, texture_type);
|
||||
}
|
||||
|
||||
@ -893,11 +888,11 @@ static void gl_pbo_async_readback(gl_t *gl)
|
||||
gl->pbo_readback_valid[gl->pbo_readback_index] = true;
|
||||
|
||||
if (gl->renderchain_driver->readback)
|
||||
gl->renderchain_driver->readback(gl,
|
||||
gl->renderchain_driver->readback(gl, gl->renderchain_data,
|
||||
video_pixel_get_alignment(gl->vp.width * sizeof(uint32_t)),
|
||||
fmt, type, NULL);
|
||||
if (gl->renderchain_driver->unbind_pbo)
|
||||
gl->renderchain_driver->unbind_pbo();
|
||||
gl->renderchain_driver->unbind_pbo(gl, gl->renderchain_data);
|
||||
}
|
||||
|
||||
static INLINE void gl_draw_texture(gl_t *gl, video_frame_info_t *video_info)
|
||||
@ -982,7 +977,7 @@ static bool gl_frame(void *data, const void *frame,
|
||||
context_bind_hw_render(false);
|
||||
|
||||
if (gl->core_context_in_use && gl->renderchain_driver->bind_vao)
|
||||
gl->renderchain_driver->bind_vao(gl);
|
||||
gl->renderchain_driver->bind_vao(gl, gl->renderchain_data);
|
||||
|
||||
video_info->cb_shader_use(gl, video_info->shader_data, 1, true);
|
||||
|
||||
@ -996,11 +991,12 @@ static bool gl_frame(void *data, const void *frame,
|
||||
{
|
||||
if (gl->renderchain_driver->recompute_pass_sizes)
|
||||
gl->renderchain_driver->recompute_pass_sizes(
|
||||
gl, frame_width, frame_height,
|
||||
gl, gl->renderchain_data, frame_width, frame_height,
|
||||
gl->vp_out_width, gl->vp_out_height);
|
||||
|
||||
if (gl->renderchain_driver->start_render)
|
||||
gl->renderchain_driver->start_render(gl, video_info);
|
||||
gl->renderchain_driver->start_render(gl, gl->renderchain_data,
|
||||
video_info);
|
||||
}
|
||||
|
||||
if (gl->should_resize)
|
||||
@ -1018,12 +1014,14 @@ static bool gl_frame(void *data, const void *frame,
|
||||
if (gl->fbo_inited)
|
||||
{
|
||||
if (gl->renderchain_driver->check_fbo_dimensions)
|
||||
gl->renderchain_driver->check_fbo_dimensions(gl);
|
||||
gl->renderchain_driver->check_fbo_dimensions(gl,
|
||||
gl->renderchain_data);
|
||||
|
||||
/* Go back to what we're supposed to do,
|
||||
* render to FBO #0. */
|
||||
if (gl->renderchain_driver->start_render)
|
||||
gl->renderchain_driver->start_render(gl, video_info);
|
||||
gl->renderchain_driver->start_render(gl, gl->renderchain_data,
|
||||
video_info);
|
||||
}
|
||||
else
|
||||
gl_set_viewport(gl, video_info, width, height, false, true);
|
||||
@ -1042,7 +1040,7 @@ static bool gl_frame(void *data, const void *frame,
|
||||
gl_update_input_size(gl, frame_width, frame_height, pitch, true);
|
||||
|
||||
if (gl->renderchain_driver->copy_frame)
|
||||
gl->renderchain_driver->copy_frame(gl,
|
||||
gl->renderchain_driver->copy_frame(gl, gl->renderchain_data,
|
||||
video_info, frame, frame_width, frame_height, pitch);
|
||||
}
|
||||
|
||||
@ -1060,12 +1058,12 @@ static bool gl_frame(void *data, const void *frame,
|
||||
if (!gl->fbo_inited)
|
||||
{
|
||||
if (gl->renderchain_driver->bind_backbuffer)
|
||||
gl->renderchain_driver->bind_backbuffer();
|
||||
gl->renderchain_driver->bind_backbuffer(gl, gl->renderchain_data);
|
||||
gl_set_viewport(gl, video_info, width, height, false, true);
|
||||
}
|
||||
|
||||
if (gl->renderchain_driver->restore_default_state)
|
||||
gl->renderchain_driver->restore_default_state(gl);
|
||||
gl->renderchain_driver->restore_default_state(gl, gl->renderchain_data);
|
||||
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
@ -1127,12 +1125,14 @@ static bool gl_frame(void *data, const void *frame,
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
if (gl->fbo_inited && gl->renderchain_driver->renderchain_render)
|
||||
gl->renderchain_driver->renderchain_render(gl, video_info,
|
||||
gl->renderchain_driver->renderchain_render(gl, gl->renderchain_data,
|
||||
video_info,
|
||||
frame_count, &gl->tex_info, &feedback_info);
|
||||
|
||||
/* Set prev textures. */
|
||||
if (gl->renderchain_driver->bind_prev_texture)
|
||||
gl->renderchain_driver->bind_prev_texture(gl, &gl->tex_info);
|
||||
gl->renderchain_driver->bind_prev_texture(gl, gl->renderchain_data,
|
||||
&gl->tex_info);
|
||||
|
||||
#if defined(HAVE_MENU)
|
||||
if (gl->menu_texture_enable)
|
||||
@ -1167,7 +1167,8 @@ static bool gl_frame(void *data, const void *frame,
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
if (gl->renderchain_driver->disable_client_arrays)
|
||||
gl->renderchain_driver->disable_client_arrays();
|
||||
gl->renderchain_driver->disable_client_arrays(gl,
|
||||
gl->renderchain_data);
|
||||
}
|
||||
|
||||
/* Screenshots. */
|
||||
@ -1175,6 +1176,7 @@ static bool gl_frame(void *data, const void *frame,
|
||||
{
|
||||
if (gl->renderchain_driver->readback)
|
||||
gl->renderchain_driver->readback(gl,
|
||||
gl->renderchain_data,
|
||||
4, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
gl->readback_buffer_screenshot);
|
||||
}
|
||||
@ -1207,12 +1209,14 @@ static bool gl_frame(void *data, const void *frame,
|
||||
|
||||
if (gl->renderchain_driver->fence_iterate)
|
||||
gl->renderchain_driver->fence_iterate(gl,
|
||||
gl->renderchain_data,
|
||||
video_info->hard_sync_frames);
|
||||
}
|
||||
|
||||
if (gl->core_context_in_use &&
|
||||
gl->renderchain_driver->unbind_vao)
|
||||
gl->renderchain_driver->unbind_vao(gl);
|
||||
gl->renderchain_driver->unbind_vao(gl,
|
||||
gl->renderchain_data);
|
||||
|
||||
context_bind_hw_render(true);
|
||||
|
||||
@ -1242,7 +1246,7 @@ static void gl_deinit_chain(gl_t *gl)
|
||||
return;
|
||||
|
||||
if (gl->renderchain_driver->chain_free)
|
||||
gl->renderchain_driver->chain_free(gl->renderchain_data);
|
||||
gl->renderchain_driver->chain_free(gl, gl->renderchain_data);
|
||||
|
||||
gl->renderchain_driver = NULL;
|
||||
gl->renderchain_data = NULL;
|
||||
@ -1259,14 +1263,14 @@ static void gl_free(void *data)
|
||||
if (gl->have_sync)
|
||||
{
|
||||
if (gl->renderchain_driver->fence_free)
|
||||
gl->renderchain_driver->fence_free(gl);
|
||||
gl->renderchain_driver->fence_free(gl, gl->renderchain_data);
|
||||
}
|
||||
|
||||
font_driver_free_osd();
|
||||
video_shader_driver_deinit();
|
||||
|
||||
if (gl->renderchain_driver->disable_client_arrays)
|
||||
gl->renderchain_driver->disable_client_arrays();
|
||||
gl->renderchain_driver->disable_client_arrays(gl, gl->renderchain_data);
|
||||
|
||||
glDeleteTextures(gl->textures, gl->texture);
|
||||
|
||||
@ -1295,13 +1299,13 @@ static void gl_free(void *data)
|
||||
if (gl->core_context_in_use)
|
||||
{
|
||||
if (gl->renderchain_driver->unbind_vao)
|
||||
gl->renderchain_driver->unbind_vao(gl);
|
||||
gl->renderchain_driver->unbind_vao(gl, gl->renderchain_data);
|
||||
if (gl->renderchain_driver->free_vao)
|
||||
gl->renderchain_driver->free_vao(gl);
|
||||
gl->renderchain_driver->free_vao(gl, gl->renderchain_data);
|
||||
}
|
||||
|
||||
if (gl->renderchain_driver->free)
|
||||
gl->renderchain_driver->free(gl);
|
||||
gl->renderchain_driver->free(gl, gl->renderchain_data);
|
||||
gl_deinit_chain(gl);
|
||||
|
||||
video_context_driver_free();
|
||||
@ -1329,7 +1333,7 @@ static void gl_set_nonblock_state(void *data, bool state)
|
||||
context_bind_hw_render(true);
|
||||
}
|
||||
|
||||
static bool resolve_extensions(gl_t *gl, const char *context_ident)
|
||||
static bool resolve_extensions(gl_t *gl, const char *context_ident, const video_info_t *video)
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
@ -1342,25 +1346,21 @@ static bool resolve_extensions(gl_t *gl, const char *context_ident)
|
||||
*
|
||||
* have_sync - Use ARB_sync to reduce latency.
|
||||
*/
|
||||
gl->has_srgb_fbo = false;
|
||||
gl->has_fbo = gl_check_capability(GL_CAPS_FBO);
|
||||
gl->have_full_npot_support = gl_check_capability(GL_CAPS_FULL_NPOT_SUPPORT);
|
||||
gl->have_mipmap = gl_check_capability(GL_CAPS_MIPMAP);
|
||||
gl->have_es2_compat = gl_check_capability(GL_CAPS_ES2_COMPAT);
|
||||
gl->has_fp_fbo = gl_check_capability(GL_CAPS_FP_FBO);
|
||||
gl->support_unpack_row_length = gl_check_capability(GL_CAPS_UNPACK_ROW_LENGTH);
|
||||
gl->have_sync = gl_check_capability(GL_CAPS_SYNC);
|
||||
/* GLES3 has unpack_subimage and sRGB in core. */
|
||||
gl->has_srgb_fbo_gles3 = gl_check_capability(GL_CAPS_SRGB_FBO_ES3);
|
||||
|
||||
if (!settings->bools.video_force_srgb_disable)
|
||||
gl->has_srgb_fbo = gl_check_capability(GL_CAPS_SRGB_FBO);
|
||||
|
||||
if (gl->have_sync && settings->bools.video_hard_sync)
|
||||
RARCH_LOG("[GL]: Using ARB_sync to reduce latency.\n");
|
||||
|
||||
video_driver_unset_rgba();
|
||||
|
||||
if (gl->renderchain_driver->resolve_extensions)
|
||||
gl->renderchain_driver->resolve_extensions(gl, gl->renderchain_data, context_ident, video);
|
||||
|
||||
#if defined(HAVE_OPENGLES) && !defined(HAVE_PSGL)
|
||||
if (!gl_check_capability(GL_CAPS_BGRA8888))
|
||||
{
|
||||
@ -1463,7 +1463,7 @@ static bool gl_init_pbo_readback(gl_t *gl)
|
||||
gl->vp.height * sizeof(uint32_t), NULL);
|
||||
}
|
||||
if (gl->renderchain_driver->unbind_pbo)
|
||||
gl->renderchain_driver->unbind_pbo();
|
||||
gl->renderchain_driver->unbind_pbo(gl, gl->renderchain_data);
|
||||
|
||||
#ifndef HAVE_OPENGLES3
|
||||
{
|
||||
@ -1775,16 +1775,16 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
|
||||
}
|
||||
|
||||
if (gl->renderchain_driver->restore_default_state)
|
||||
gl->renderchain_driver->restore_default_state(gl);
|
||||
gl->renderchain_driver->restore_default_state(gl, gl->renderchain_data);
|
||||
|
||||
if (hwr->context_type == RETRO_HW_CONTEXT_OPENGL_CORE)
|
||||
if (gl->renderchain_driver->new_vao)
|
||||
gl->renderchain_driver->new_vao(gl);
|
||||
gl->renderchain_driver->new_vao(gl, gl->renderchain_data);
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
|
||||
if (!resolve_extensions(gl, ctx_driver->ident))
|
||||
if (!resolve_extensions(gl, ctx_driver->ident, video))
|
||||
goto error;
|
||||
|
||||
#ifdef GL_DEBUG
|
||||
@ -1927,13 +1927,13 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
|
||||
gl_init_textures_data(gl);
|
||||
|
||||
if (gl->renderchain_driver->init)
|
||||
gl->renderchain_driver->init(gl, gl->tex_w, gl->tex_h);
|
||||
gl->renderchain_driver->init(gl, gl->renderchain_data, gl->tex_w, gl->tex_h);
|
||||
|
||||
if (gl->has_fbo)
|
||||
{
|
||||
if (gl->hw_render_use &&
|
||||
gl->renderchain_driver->init_hw_render &&
|
||||
!gl->renderchain_driver->init_hw_render(gl, gl->tex_w, gl->tex_h))
|
||||
!gl->renderchain_driver->init_hw_render(gl, gl->renderchain_data, gl->tex_w, gl->tex_h))
|
||||
{
|
||||
RARCH_ERR("[GL]: Hardware rendering context initialization failed.\n");
|
||||
goto error;
|
||||
@ -2111,7 +2111,7 @@ static bool gl_set_shader(void *data,
|
||||
if (gl->fbo_inited)
|
||||
{
|
||||
if (gl->renderchain_driver->deinit_fbo)
|
||||
gl->renderchain_driver->deinit_fbo(gl);
|
||||
gl->renderchain_driver->deinit_fbo(gl, gl->renderchain_data);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]);
|
||||
}
|
||||
@ -2143,7 +2143,7 @@ static bool gl_set_shader(void *data,
|
||||
{
|
||||
if (gl->hw_render_use && gl->fbo_inited &&
|
||||
gl->renderchain_driver->deinit_hw_render)
|
||||
gl->renderchain_driver->deinit_hw_render(gl);
|
||||
gl->renderchain_driver->deinit_hw_render(gl, gl->renderchain_data);
|
||||
|
||||
glDeleteTextures(gl->textures, gl->texture);
|
||||
#if defined(HAVE_PSGL)
|
||||
@ -2157,11 +2157,13 @@ static bool gl_set_shader(void *data,
|
||||
gl_init_textures_data(gl);
|
||||
|
||||
if (gl->hw_render_use && gl->renderchain_driver->init_hw_render)
|
||||
gl->renderchain_driver->init_hw_render(gl, gl->tex_w, gl->tex_h);
|
||||
gl->renderchain_driver->init_hw_render(gl, gl->renderchain_data,
|
||||
gl->tex_w, gl->tex_h);
|
||||
}
|
||||
|
||||
if (gl->renderchain_driver->init)
|
||||
gl->renderchain_driver->init(gl, gl->tex_w, gl->tex_h);
|
||||
gl->renderchain_driver->init(gl, gl->renderchain_data,
|
||||
gl->tex_w, gl->tex_h);
|
||||
|
||||
/* Apparently need to set viewport for passes when we aren't using FBOs. */
|
||||
gl_set_shader_viewports(gl);
|
||||
@ -2185,7 +2187,7 @@ static void gl_viewport_info(void *data, struct video_viewport *vp)
|
||||
gl_t *gl = (gl_t*)data;
|
||||
if (!gl->renderchain_driver || !gl->renderchain_driver->viewport_info)
|
||||
return;
|
||||
gl->renderchain_driver->viewport_info(data, vp);
|
||||
gl->renderchain_driver->viewport_info(gl, gl->renderchain_data, vp);
|
||||
}
|
||||
|
||||
static bool gl_read_viewport(void *data, uint8_t *buffer, bool is_idle)
|
||||
@ -2193,7 +2195,8 @@ static bool gl_read_viewport(void *data, uint8_t *buffer, bool is_idle)
|
||||
gl_t *gl = (gl_t*)data;
|
||||
if (!gl->renderchain_driver || !gl->renderchain_driver->read_viewport)
|
||||
return false;
|
||||
return gl->renderchain_driver->read_viewport(data, buffer, is_idle);
|
||||
return gl->renderchain_driver->read_viewport(gl, gl->renderchain_data,
|
||||
buffer, is_idle);
|
||||
}
|
||||
|
||||
#if 0
|
||||
@ -2524,7 +2527,7 @@ static void gl_set_coords(void *handle_data, void *shader_data,
|
||||
{
|
||||
gl_t *gl = (gl_t*)handle_data;
|
||||
if (gl && gl->renderchain_driver->set_coords)
|
||||
gl->renderchain_driver->set_coords(handle_data,
|
||||
gl->renderchain_driver->set_coords(gl, gl->renderchain_data,
|
||||
shader_data, coords);
|
||||
}
|
||||
|
||||
@ -2533,7 +2536,7 @@ static void gl_set_mvp(void *data, void *shader_data,
|
||||
{
|
||||
gl_t *gl = (gl_t*)data;
|
||||
if (gl && gl->renderchain_driver->set_mvp)
|
||||
gl->renderchain_driver->set_mvp(data,
|
||||
gl->renderchain_driver->set_mvp(gl, gl->renderchain_data,
|
||||
shader_data, mat_data);
|
||||
}
|
||||
|
||||
|
76
gfx/drivers/gl_shaders/pipeline_snowflake.glsl.frag.h
Normal file
76
gfx/drivers/gl_shaders/pipeline_snowflake.glsl.frag.h
Normal file
@ -0,0 +1,76 @@
|
||||
/* credits to: TheTimJames
|
||||
https://www.shadertoy.com/view/Md2GRw
|
||||
*/
|
||||
|
||||
#include "shaders_common.h"
|
||||
|
||||
static const char* stock_fragment_xmb_snowflake = GLSL(
|
||||
uniform float time;
|
||||
uniform vec2 OutputSize;
|
||||
vec2 uv;
|
||||
|
||||
float atime;
|
||||
|
||||
float rand(vec2 co)
|
||||
{
|
||||
return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453);
|
||||
}
|
||||
|
||||
float rand_float(float x)
|
||||
{
|
||||
return rand(vec2(x, 1.0));
|
||||
}
|
||||
|
||||
float snow(vec3 pos, vec2 uv, float o)
|
||||
{
|
||||
vec2 d = (pos.xy - uv);
|
||||
float a = atan(d.y,d.x) + sin(atime*1.0 + o) * 10.0;
|
||||
|
||||
float dist = d.x*d.x + d.y*d.y;
|
||||
|
||||
if(dist < pos.z/400.0)
|
||||
{
|
||||
float col = 0.0;
|
||||
if(sin(a * 8.0) < 0.0)
|
||||
{
|
||||
col=1.0;
|
||||
}
|
||||
if(dist < pos.z/800.0)
|
||||
{
|
||||
col+=1.0;
|
||||
}
|
||||
return col * pos.z;
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
float col(vec2 c)
|
||||
{
|
||||
float color = 0.0;
|
||||
for (int i = 1; i < 15; i++)
|
||||
{
|
||||
float o = rand_float(float(i) / 3.0) * 15.0;
|
||||
float z = rand_float(float(i) + 13.0);
|
||||
float x = 1.8 - (3.6) * (rand_float(floor((time*((z + 1.0) / 2.0) +o) / 2.0)) + sin(time * o /1000.0) / 10.0);
|
||||
float y = 1.0 - mod((time * ((z + 1.0)/2.0)) + o, 2.0);
|
||||
|
||||
color += snow(vec3(x,y,z), c, o);
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
uv = gl_FragCoord.xy / OutputSize.xy;
|
||||
uv = uv * 2.0 - 1.0;
|
||||
vec2 p = uv;
|
||||
p.x *= OutputSize.x / OutputSize.y;
|
||||
|
||||
atime = (time + 1.0) / 4.0;
|
||||
|
||||
gl_FragColor = vec4(col(p));
|
||||
}
|
||||
|
||||
);
|
@ -1,159 +0,0 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
* Copyright (C) 2012-2015 - Michael Lelli
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _GL_SYMLINKS_H
|
||||
#define _GL_SYMLINKS_H
|
||||
|
||||
#include <boolean.h>
|
||||
#include <retro_common_api.h>
|
||||
|
||||
#include <glsym/glsym.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_PSGL)
|
||||
#define glGenFramebuffers glGenFramebuffersOES
|
||||
#define glBindFramebuffer glBindFramebufferOES
|
||||
#define glFramebufferTexture2D glFramebufferTexture2DOES
|
||||
#define glCheckFramebufferStatus glCheckFramebufferStatusOES
|
||||
#define glDeleteFramebuffers glDeleteFramebuffersOES
|
||||
#define glGenRenderbuffers glGenRenderbuffersOES
|
||||
#define glBindRenderbuffer glBindRenderbufferOES
|
||||
#define glFramebufferRenderbuffer glFramebufferRenderbufferOES
|
||||
#define glRenderbufferStorage glRenderbufferStorageOES
|
||||
#define glDeleteRenderbuffers glDeleteRenderbuffersOES
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_PSGL)
|
||||
#define RARCH_GL_FRAMEBUFFER GL_FRAMEBUFFER_OES
|
||||
#define RARCH_GL_FRAMEBUFFER_COMPLETE GL_FRAMEBUFFER_COMPLETE_OES
|
||||
#define RARCH_GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_EXT
|
||||
#elif (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__)))
|
||||
#define RARCH_GL_FRAMEBUFFER GL_FRAMEBUFFER_EXT
|
||||
#define RARCH_GL_FRAMEBUFFER_COMPLETE GL_FRAMEBUFFER_COMPLETE_EXT
|
||||
#define RARCH_GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_EXT
|
||||
#else
|
||||
#define RARCH_GL_FRAMEBUFFER GL_FRAMEBUFFER
|
||||
#define RARCH_GL_FRAMEBUFFER_COMPLETE GL_FRAMEBUFFER_COMPLETE
|
||||
#define RARCH_GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_OPENGLES2) || defined(HAVE_OPENGLES3) || defined(HAVE_OPENGLES_3_1) || defined(HAVE_OPENGLES_3_2)
|
||||
#define RARCH_GL_RENDERBUFFER GL_RENDERBUFFER
|
||||
#if defined(HAVE_OPENGLES2)
|
||||
#define RARCH_GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_OES
|
||||
#else
|
||||
#define RARCH_GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8
|
||||
#endif
|
||||
#define RARCH_GL_DEPTH_ATTACHMENT GL_DEPTH_ATTACHMENT
|
||||
#define RARCH_GL_STENCIL_ATTACHMENT GL_STENCIL_ATTACHMENT
|
||||
#elif (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__)))
|
||||
#define RARCH_GL_RENDERBUFFER GL_RENDERBUFFER_EXT
|
||||
#define RARCH_GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_EXT
|
||||
#define RARCH_GL_DEPTH_ATTACHMENT GL_DEPTH_ATTACHMENT_EXT
|
||||
#define RARCH_GL_STENCIL_ATTACHMENT GL_STENCIL_ATTACHMENT_EXT
|
||||
#elif defined(HAVE_PSGL)
|
||||
#define RARCH_GL_RENDERBUFFER GL_RENDERBUFFER_OES
|
||||
#define RARCH_GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_SCE
|
||||
#define RARCH_GL_DEPTH_ATTACHMENT GL_DEPTH_ATTACHMENT_OES
|
||||
#define RARCH_GL_STENCIL_ATTACHMENT GL_STENCIL_ATTACHMENT_OES
|
||||
#else
|
||||
#define RARCH_GL_RENDERBUFFER GL_RENDERBUFFER
|
||||
#define RARCH_GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8
|
||||
#define RARCH_GL_DEPTH_ATTACHMENT GL_DEPTH_ATTACHMENT
|
||||
#define RARCH_GL_STENCIL_ATTACHMENT GL_STENCIL_ATTACHMENT
|
||||
#endif
|
||||
|
||||
#if (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__)))
|
||||
#define RARCH_GL_MAX_RENDERBUFFER_SIZE GL_MAX_RENDERBUFFER_SIZE_EXT
|
||||
#elif defined(HAVE_PSGL)
|
||||
#define RARCH_GL_MAX_RENDERBUFFER_SIZE GL_MAX_RENDERBUFFER_SIZE_OES
|
||||
#else
|
||||
#define RARCH_GL_MAX_RENDERBUFFER_SIZE GL_MAX_RENDERBUFFER_SIZE
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_PSGL)
|
||||
#define glGenerateMipmap glGenerateMipmapOES
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) || defined(HAVE_PSGL)
|
||||
#define GL_RGBA32F GL_RGBA32F_ARB
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_PSGL)
|
||||
#define RARCH_GL_INTERNAL_FORMAT32 GL_ARGB_SCE
|
||||
#define RARCH_GL_INTERNAL_FORMAT16 GL_RGB5 /* TODO: Verify if this is really 565 or just 555. */
|
||||
#define RARCH_GL_TEXTURE_TYPE32 GL_BGRA
|
||||
#define RARCH_GL_TEXTURE_TYPE16 GL_BGRA
|
||||
#define RARCH_GL_FORMAT32 GL_UNSIGNED_INT_8_8_8_8_REV
|
||||
#define RARCH_GL_FORMAT16 GL_RGB5
|
||||
#elif defined(HAVE_OPENGLES)
|
||||
/* Imgtec/SGX headers have this missing. */
|
||||
#ifndef GL_BGRA_EXT
|
||||
#define GL_BGRA_EXT 0x80E1
|
||||
#endif
|
||||
#ifndef GL_BGRA8_EXT
|
||||
#define GL_BGRA8_EXT 0x93A1
|
||||
#endif
|
||||
#ifdef IOS
|
||||
/* Stupid Apple */
|
||||
#define RARCH_GL_INTERNAL_FORMAT32 GL_RGBA
|
||||
#else
|
||||
#define RARCH_GL_INTERNAL_FORMAT32 GL_BGRA_EXT
|
||||
#endif
|
||||
#define RARCH_GL_INTERNAL_FORMAT16 GL_RGB
|
||||
#define RARCH_GL_TEXTURE_TYPE32 GL_BGRA_EXT
|
||||
#define RARCH_GL_TEXTURE_TYPE16 GL_RGB
|
||||
#define RARCH_GL_FORMAT32 GL_UNSIGNED_BYTE
|
||||
#define RARCH_GL_FORMAT16 GL_UNSIGNED_SHORT_5_6_5
|
||||
#else
|
||||
/* On desktop, we always use 32-bit. */
|
||||
#define RARCH_GL_INTERNAL_FORMAT32 GL_RGBA8
|
||||
#define RARCH_GL_INTERNAL_FORMAT16 GL_RGBA8
|
||||
#define RARCH_GL_TEXTURE_TYPE32 GL_BGRA
|
||||
#define RARCH_GL_TEXTURE_TYPE16 GL_BGRA
|
||||
#define RARCH_GL_FORMAT32 GL_UNSIGNED_INT_8_8_8_8_REV
|
||||
#define RARCH_GL_FORMAT16 GL_UNSIGNED_INT_8_8_8_8_REV
|
||||
|
||||
/* GL_RGB565 internal format isn't in desktop GL
|
||||
* until 4.1 core (ARB_ES2_compatibility).
|
||||
* Check for this. */
|
||||
#ifndef GL_RGB565
|
||||
#define GL_RGB565 0x8D62
|
||||
#endif
|
||||
#define RARCH_GL_INTERNAL_FORMAT16_565 GL_RGB565
|
||||
#define RARCH_GL_TEXTURE_TYPE16_565 GL_RGB
|
||||
#define RARCH_GL_FORMAT16_565 GL_UNSIGNED_SHORT_5_6_5
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_OPENGLES2) /* TODO: Figure out exactly what. */
|
||||
#define NO_GL_CLAMP_TO_BORDER
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_OPENGLES)
|
||||
#ifndef GL_UNPACK_ROW_LENGTH
|
||||
#define GL_UNPACK_ROW_LENGTH 0x0CF2
|
||||
#endif
|
||||
|
||||
#ifndef GL_SRGB_ALPHA_EXT
|
||||
#define GL_SRGB_ALPHA_EXT 0x8C42
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
@ -57,14 +57,15 @@ typedef struct gl1_renderchain
|
||||
|
||||
GLenum min_filter_to_mag(GLenum type);
|
||||
|
||||
void gl1_renderchain_free(void *data)
|
||||
void gl1_renderchain_free(void *data, void *chain_data)
|
||||
{
|
||||
gl_t *gl = (gl_t*)data;
|
||||
(void)gl;
|
||||
(void)chain_data;
|
||||
(void)data;
|
||||
}
|
||||
|
||||
static void gl1_renderchain_bind_prev_texture(
|
||||
void *data,
|
||||
void *chain_data,
|
||||
const struct video_tex_info *tex_info)
|
||||
{
|
||||
gl_t *gl = (gl_t*)data;
|
||||
@ -76,7 +77,8 @@ static void gl1_renderchain_bind_prev_texture(
|
||||
}
|
||||
|
||||
static void gl1_renderchain_viewport_info(
|
||||
void *data, struct video_viewport *vp)
|
||||
void *data, void *chain_data,
|
||||
struct video_viewport *vp)
|
||||
{
|
||||
unsigned width, height;
|
||||
unsigned top_y, top_dist;
|
||||
@ -95,7 +97,8 @@ static void gl1_renderchain_viewport_info(
|
||||
}
|
||||
|
||||
static bool gl1_renderchain_read_viewport(
|
||||
void *data, uint8_t *buffer, bool is_idle)
|
||||
void *data, void *chain_data,
|
||||
uint8_t *buffer, bool is_idle)
|
||||
{
|
||||
unsigned num_pixels = 0;
|
||||
gl_t *gl = (gl_t*)data;
|
||||
@ -108,14 +111,12 @@ static bool gl1_renderchain_read_viewport(
|
||||
/* Use slow synchronous readbacks. Use this with plain screenshots
|
||||
as we don't really care about performance in this case. */
|
||||
|
||||
/* GLES2 only guarantees GL_RGBA/GL_UNSIGNED_BYTE
|
||||
/* GL1 only guarantees GL_RGBA/GL_UNSIGNED_BYTE
|
||||
* readbacks so do just that.
|
||||
* GLES2 also doesn't support reading back data
|
||||
* GL1 also doesn't support reading back data
|
||||
* from front buffer, so render a cached frame
|
||||
* and have gl_frame() do the readback while it's
|
||||
* in the back buffer.
|
||||
*
|
||||
* Keep codepath similar for GLES and desktop GL.
|
||||
*/
|
||||
gl->readback_buffer_screenshot = malloc(num_pixels * sizeof(uint32_t));
|
||||
|
||||
@ -136,9 +137,9 @@ static bool gl1_renderchain_read_viewport(
|
||||
return true;
|
||||
}
|
||||
|
||||
void gl1_renderchain_free_internal(void *data)
|
||||
void gl1_renderchain_free_internal(void *data, void *chain_data)
|
||||
{
|
||||
gl1_renderchain_t *cg_data = (gl1_renderchain_t*)data;
|
||||
gl1_renderchain_t *cg_data = (gl1_renderchain_t*)chain_data;
|
||||
|
||||
if (!cg_data)
|
||||
return;
|
||||
@ -185,7 +186,8 @@ static void gl1_renderchain_ff_matrix(const void *data)
|
||||
glLoadMatrixf(ident.data);
|
||||
}
|
||||
|
||||
static void gl1_renderchain_disable_client_arrays(void)
|
||||
static void gl1_renderchain_disable_client_arrays(void *data,
|
||||
void *chain_data)
|
||||
{
|
||||
if (gl_query_core_context_in_use())
|
||||
return;
|
||||
@ -198,7 +200,8 @@ static void gl1_renderchain_disable_client_arrays(void)
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
|
||||
static void gl1_renderchain_restore_default_state(void *data)
|
||||
static void gl1_renderchain_restore_default_state(void *data,
|
||||
void *chain_data)
|
||||
{
|
||||
gl_t *gl = (gl_t*)data;
|
||||
if (!gl)
|
||||
@ -211,6 +214,7 @@ static void gl1_renderchain_restore_default_state(void *data)
|
||||
|
||||
static void gl1_renderchain_copy_frame(
|
||||
void *data,
|
||||
void *chain_data,
|
||||
video_frame_info_t *video_info,
|
||||
const void *frame,
|
||||
unsigned width, unsigned height, unsigned pitch)
|
||||
@ -246,6 +250,7 @@ static void gl1_renderchain_copy_frame(
|
||||
}
|
||||
|
||||
static void gl1_renderchain_readback(void *data,
|
||||
void *chain_data,
|
||||
unsigned alignment,
|
||||
unsigned fmt, unsigned type,
|
||||
void *src)
|
||||
@ -262,6 +267,7 @@ static void gl1_renderchain_readback(void *data,
|
||||
}
|
||||
|
||||
static void gl1_renderchain_set_mvp(void *data,
|
||||
void *chain_data,
|
||||
void *shader_data, const void *mat_data)
|
||||
{
|
||||
math_matrix_4x4 ident;
|
||||
@ -276,6 +282,7 @@ static void gl1_renderchain_set_mvp(void *data,
|
||||
}
|
||||
|
||||
static void gl1_renderchain_set_coords(void *handle_data,
|
||||
void *chain_data,
|
||||
void *shader_data, const struct video_coords *coords)
|
||||
{
|
||||
/* Fall back to fixed function-style if needed and possible. */
|
||||
@ -320,10 +327,11 @@ gl_renderchain_driver_t gl2_renderchain = {
|
||||
NULL, /* renderchain_init */
|
||||
NULL, /* init_hw_render */
|
||||
gl1_renderchain_free,
|
||||
NULL, /* deinit_hw_render */
|
||||
NULL, /* start_render */
|
||||
NULL, /* deinit_hw_render */
|
||||
NULL, /* start_render */
|
||||
NULL, /* check_fbo_dimensions */
|
||||
NULL, /* recompute_pass_sizes */
|
||||
NULL, /* renderchain_render */
|
||||
NULL, /* renderchain_render */
|
||||
NULL, /* resolve_extensions */
|
||||
"gl1",
|
||||
};
|
||||
|
@ -41,6 +41,7 @@
|
||||
|
||||
#include <gfx/gl_capabilities.h>
|
||||
#include <gfx/video_frame.h>
|
||||
#include <glsym/glsym.h>
|
||||
|
||||
#include "../video_driver.h"
|
||||
#include "../video_shader_parse.h"
|
||||
@ -50,9 +51,28 @@
|
||||
#include "../../configuration.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
#define MAX_FENCES 4
|
||||
|
||||
typedef struct gl2_renderchain
|
||||
{
|
||||
void *empty;
|
||||
bool egl_images;
|
||||
bool has_fp_fbo;
|
||||
bool has_srgb_fbo_gles3;
|
||||
bool has_srgb_fbo;
|
||||
bool hw_render_depth_init;
|
||||
|
||||
int fbo_pass;
|
||||
|
||||
GLuint vao;
|
||||
GLuint fbo[GFX_MAX_SHADERS];
|
||||
GLuint fbo_texture[GFX_MAX_SHADERS];
|
||||
GLuint hw_render_depth[GFX_MAX_TEXTURES];
|
||||
|
||||
unsigned fence_count;
|
||||
|
||||
GLsync fences[MAX_FENCES];
|
||||
|
||||
struct gfx_fbo_scale fbo_scale[GFX_MAX_SHADERS];
|
||||
} gl2_renderchain_t;
|
||||
|
||||
#if (!defined(HAVE_OPENGLES) || defined(HAVE_OPENGLES3))
|
||||
@ -67,7 +87,45 @@ typedef struct gl2_renderchain
|
||||
coords[5] = yamt; \
|
||||
coords[7] = yamt
|
||||
|
||||
#define gl2_bind_fb(id) glBindFramebuffer(RARCH_GL_FRAMEBUFFER, id)
|
||||
#if defined(HAVE_PSGL)
|
||||
#define gl2_fb_texture_2d(a, b, c, d, e) glFramebufferTexture2DOES(a, b, c, d, e)
|
||||
#define gl2_check_fb_status(target) glCheckFramebufferStatusOES(target)
|
||||
#define gl2_gen_fb(n, ids) glGenFramebuffersOES(n, ids)
|
||||
#define gl2_delete_fb(n, fb) glDeleteFramebuffersOES(n, fb)
|
||||
#define gl2_bind_fb(id) glBindFramebufferOES(RARCH_GL_FRAMEBUFFER, id)
|
||||
#define gl2_gen_rb glGenRenderbuffersOES
|
||||
#define gl2_bind_rb glBindRenderbufferOES
|
||||
#define gl2_fb_rb glFramebufferRenderbufferOES
|
||||
#define gl2_rb_storage glRenderbufferStorageOES
|
||||
#define gl2_delete_rb glDeleteRenderbuffersOES
|
||||
|
||||
#elif (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__)))
|
||||
#define gl2_fb_texture_2d(a, b, c, d, e) glFramebufferTexture2DEXT(a, b, c, d, e)
|
||||
#define gl2_check_fb_status(target) glCheckFramebufferStatusEXT(target)
|
||||
#define gl2_gen_fb(n, ids) glGenFramebuffersEXT(n, ids)
|
||||
#define gl2_delete_fb(n, fb) glDeleteFramebuffersEXT(n, fb)
|
||||
#define gl2_bind_fb(id) glBindFramebufferEXT(RARCH_GL_FRAMEBUFFER, id)
|
||||
#define gl2_gen_rb glGenRenderbuffersEXT
|
||||
#define gl2_bind_rb glBindRenderbufferEXT
|
||||
#define gl2_fb_rb glFramebufferRenderbufferEXT
|
||||
#define gl2_rb_storage glRenderbufferStorageEXT
|
||||
#define gl2_delete_rb glDeleteRenderbuffersEXT
|
||||
|
||||
#else
|
||||
|
||||
#define gl2_fb_texture_2d(a, b, c, d, e) glFramebufferTexture2D(a, b, c, d, e)
|
||||
#define gl2_check_fb_status(target) glCheckFramebufferStatus(target)
|
||||
#define gl2_gen_fb(n, ids) glGenFramebuffers(n, ids)
|
||||
#define gl2_delete_fb(n, fb) glDeleteFramebuffers(n, fb)
|
||||
#define gl2_bind_fb(id) glBindFramebuffer(RARCH_GL_FRAMEBUFFER, id)
|
||||
#define gl2_gen_rb glGenRenderbuffers
|
||||
#define gl2_bind_rb glBindRenderbuffer
|
||||
#define gl2_fb_rb glFramebufferRenderbuffer
|
||||
#define gl2_rb_storage glRenderbufferStorage
|
||||
#define gl2_delete_rb glDeleteRenderbuffers
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef GL_SYNC_GPU_COMMANDS_COMPLETE
|
||||
#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117
|
||||
@ -78,7 +136,8 @@ typedef struct gl2_renderchain
|
||||
#endif
|
||||
|
||||
/* Prototypes */
|
||||
static void gl2_renderchain_bind_backbuffer(void)
|
||||
static void gl2_renderchain_bind_backbuffer(void *data,
|
||||
void *chain_data)
|
||||
{
|
||||
#ifdef IOS
|
||||
/* There is no default frame buffer on iOS. */
|
||||
@ -169,11 +228,11 @@ static bool gl_recreate_fbo(
|
||||
0, RARCH_GL_TEXTURE_TYPE32,
|
||||
RARCH_GL_FORMAT32, NULL);
|
||||
|
||||
glFramebufferTexture2D(RARCH_GL_FRAMEBUFFER,
|
||||
gl2_fb_texture_2d(RARCH_GL_FRAMEBUFFER,
|
||||
RARCH_GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||
*texture, 0);
|
||||
|
||||
if (glCheckFramebufferStatus(RARCH_GL_FRAMEBUFFER)
|
||||
if (gl2_check_fb_status(RARCH_GL_FRAMEBUFFER)
|
||||
== RARCH_GL_FRAMEBUFFER_COMPLETE)
|
||||
return true;
|
||||
|
||||
@ -181,12 +240,15 @@ static bool gl_recreate_fbo(
|
||||
return false;
|
||||
}
|
||||
|
||||
static void gl_check_fbo_dimension(gl_t *gl, unsigned i,
|
||||
static void gl_check_fbo_dimension(gl_t *gl,
|
||||
void *chain_data,
|
||||
unsigned i,
|
||||
bool update_feedback)
|
||||
{
|
||||
struct video_fbo_rect *fbo_rect = &gl->fbo_rect[i];
|
||||
/* Check proactively since we might suddently
|
||||
* get sizes of tex_w width or tex_h height. */
|
||||
gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data;
|
||||
unsigned img_width = fbo_rect->max_img_width;
|
||||
unsigned img_height = fbo_rect->max_img_height;
|
||||
unsigned max = img_width > img_height ? img_width : img_height;
|
||||
@ -195,7 +257,7 @@ static void gl_check_fbo_dimension(gl_t *gl, unsigned i,
|
||||
fbo_rect->width = pow2_size;
|
||||
fbo_rect->height = pow2_size;
|
||||
|
||||
gl_recreate_fbo(fbo_rect, gl->fbo[i], &gl->fbo_texture[i]);
|
||||
gl_recreate_fbo(fbo_rect, chain->fbo[i], &chain->fbo_texture[i]);
|
||||
|
||||
/* Update feedback texture in-place so we avoid having to
|
||||
* juggle two different fbo_rect structs since they get updated here. */
|
||||
@ -218,13 +280,15 @@ static void gl_check_fbo_dimension(gl_t *gl, unsigned i,
|
||||
/* On resize, we might have to recreate our FBOs
|
||||
* due to "Viewport" scale, and set a new viewport. */
|
||||
|
||||
static void gl2_renderchain_check_fbo_dimensions(void *data)
|
||||
static void gl2_renderchain_check_fbo_dimensions(void *data,
|
||||
void *chain_data)
|
||||
{
|
||||
int i;
|
||||
gl_t *gl = (gl_t*)data;
|
||||
gl_t *gl = (gl_t*)data;
|
||||
gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data;
|
||||
|
||||
/* Check if we have to recreate our FBO textures. */
|
||||
for (i = 0; i < gl->fbo_pass; i++)
|
||||
for (i = 0; i < chain->fbo_pass; i++)
|
||||
{
|
||||
struct video_fbo_rect *fbo_rect = &gl->fbo_rect[i];
|
||||
if (fbo_rect)
|
||||
@ -234,13 +298,14 @@ static void gl2_renderchain_check_fbo_dimensions(void *data)
|
||||
|
||||
if ((fbo_rect->max_img_width > fbo_rect->width) ||
|
||||
(fbo_rect->max_img_height > fbo_rect->height))
|
||||
gl_check_fbo_dimension(gl, i, update_feedback);
|
||||
gl_check_fbo_dimension(gl, chain_data, i, update_feedback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void gl2_renderchain_render(
|
||||
void *data,
|
||||
void *chain_data,
|
||||
video_frame_info_t *video_info,
|
||||
uint64_t frame_count,
|
||||
const struct video_tex_info *tex_info,
|
||||
@ -251,6 +316,7 @@ static void gl2_renderchain_render(
|
||||
video_shader_ctx_params_t params;
|
||||
video_shader_ctx_info_t shader_info;
|
||||
gl_t *gl = (gl_t*)data;
|
||||
gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data;
|
||||
static GLfloat fbo_tex_coords[8] = {0.0f};
|
||||
struct video_tex_info fbo_tex_info[GFX_MAX_SHADERS];
|
||||
struct video_tex_info *fbo_info = NULL;
|
||||
@ -267,7 +333,7 @@ static void gl2_renderchain_render(
|
||||
|
||||
/* Calculate viewports, texture coordinates etc,
|
||||
* and render all passes from FBOs, to another FBO. */
|
||||
for (i = 1; i < gl->fbo_pass; i++)
|
||||
for (i = 1; i < chain->fbo_pass; i++)
|
||||
{
|
||||
video_shader_ctx_coords_t coords;
|
||||
video_shader_ctx_params_t params;
|
||||
@ -281,7 +347,7 @@ static void gl2_renderchain_render(
|
||||
|
||||
set_texture_coords(fbo_tex_coords, xamt, yamt);
|
||||
|
||||
fbo_info->tex = gl->fbo_texture[i - 1];
|
||||
fbo_info->tex = chain->fbo_texture[i - 1];
|
||||
fbo_info->input_size[0] = prev_rect->img_width;
|
||||
fbo_info->input_size[1] = prev_rect->img_height;
|
||||
fbo_info->tex_size[0] = prev_rect->width;
|
||||
@ -289,14 +355,14 @@ static void gl2_renderchain_render(
|
||||
memcpy(fbo_info->coord, fbo_tex_coords, sizeof(fbo_tex_coords));
|
||||
fbo_tex_info_cnt++;
|
||||
|
||||
gl2_bind_fb(gl->fbo[i]);
|
||||
gl2_bind_fb(chain->fbo[i]);
|
||||
|
||||
shader_info.data = gl;
|
||||
shader_info.idx = i + 1;
|
||||
shader_info.set_active = true;
|
||||
|
||||
video_shader_driver_use(shader_info);
|
||||
glBindTexture(GL_TEXTURE_2D, gl->fbo_texture[i - 1]);
|
||||
glBindTexture(GL_TEXTURE_2D, chain->fbo_texture[i - 1]);
|
||||
|
||||
mip_level = i + 1;
|
||||
|
||||
@ -340,21 +406,21 @@ static void gl2_renderchain_render(
|
||||
}
|
||||
|
||||
#if defined(GL_FRAMEBUFFER_SRGB) && !defined(HAVE_OPENGLES)
|
||||
if (gl->has_srgb_fbo)
|
||||
if (chain->has_srgb_fbo)
|
||||
glDisable(GL_FRAMEBUFFER_SRGB);
|
||||
#endif
|
||||
|
||||
/* Render our last FBO texture directly to screen. */
|
||||
prev_rect = &gl->fbo_rect[gl->fbo_pass - 1];
|
||||
prev_rect = &gl->fbo_rect[chain->fbo_pass - 1];
|
||||
xamt = (GLfloat)prev_rect->img_width / prev_rect->width;
|
||||
yamt = (GLfloat)prev_rect->img_height / prev_rect->height;
|
||||
|
||||
set_texture_coords(fbo_tex_coords, xamt, yamt);
|
||||
|
||||
/* Push final FBO to list. */
|
||||
fbo_info = &fbo_tex_info[gl->fbo_pass - 1];
|
||||
fbo_info = &fbo_tex_info[chain->fbo_pass - 1];
|
||||
|
||||
fbo_info->tex = gl->fbo_texture[gl->fbo_pass - 1];
|
||||
fbo_info->tex = chain->fbo_texture[chain->fbo_pass - 1];
|
||||
fbo_info->input_size[0] = prev_rect->img_width;
|
||||
fbo_info->input_size[1] = prev_rect->img_height;
|
||||
fbo_info->tex_size[0] = prev_rect->width;
|
||||
@ -363,17 +429,17 @@ static void gl2_renderchain_render(
|
||||
fbo_tex_info_cnt++;
|
||||
|
||||
/* Render our FBO texture to back buffer. */
|
||||
gl2_renderchain_bind_backbuffer();
|
||||
gl2_renderchain_bind_backbuffer(gl, chain_data);
|
||||
|
||||
shader_info.data = gl;
|
||||
shader_info.idx = gl->fbo_pass + 1;
|
||||
shader_info.idx = chain->fbo_pass + 1;
|
||||
shader_info.set_active = true;
|
||||
|
||||
video_shader_driver_use(shader_info);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, gl->fbo_texture[gl->fbo_pass - 1]);
|
||||
glBindTexture(GL_TEXTURE_2D, chain->fbo_texture[chain->fbo_pass - 1]);
|
||||
|
||||
mip_level = gl->fbo_pass + 1;
|
||||
mip_level = chain->fbo_pass + 1;
|
||||
|
||||
if (video_shader_driver_mipmap_input(&mip_level)
|
||||
&& gl->have_mipmap)
|
||||
@ -416,69 +482,80 @@ static void gl2_renderchain_render(
|
||||
gl->coords.tex_coord = gl->tex_info.coord;
|
||||
}
|
||||
|
||||
static void gl2_renderchain_deinit_fbo(void *data)
|
||||
static void gl2_renderchain_deinit_fbo(void *data,
|
||||
void *chain_data)
|
||||
{
|
||||
gl_t *gl = (gl_t*)data;
|
||||
gl_t *gl = (gl_t*)data;
|
||||
gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data;
|
||||
|
||||
glDeleteTextures(gl->fbo_pass, gl->fbo_texture);
|
||||
glDeleteFramebuffers(gl->fbo_pass, gl->fbo);
|
||||
memset(gl->fbo_texture, 0, sizeof(gl->fbo_texture));
|
||||
memset(gl->fbo, 0, sizeof(gl->fbo));
|
||||
gl->fbo_inited = false;
|
||||
gl->fbo_pass = 0;
|
||||
if (!gl)
|
||||
return;
|
||||
|
||||
glDeleteTextures(chain->fbo_pass, chain->fbo_texture);
|
||||
gl2_delete_fb(chain->fbo_pass, chain->fbo);
|
||||
|
||||
memset(chain->fbo_texture, 0, sizeof(chain->fbo_texture));
|
||||
memset(chain->fbo, 0, sizeof(chain->fbo));
|
||||
|
||||
if (gl->fbo_feedback)
|
||||
glDeleteFramebuffers(1, &gl->fbo_feedback);
|
||||
gl2_delete_fb(1, &gl->fbo_feedback);
|
||||
if (gl->fbo_feedback_texture)
|
||||
glDeleteTextures(1, &gl->fbo_feedback_texture);
|
||||
|
||||
chain->fbo_pass = 0;
|
||||
|
||||
gl->fbo_inited = false;
|
||||
gl->fbo_feedback_enable = false;
|
||||
gl->fbo_feedback_pass = 0;
|
||||
gl->fbo_feedback_texture = 0;
|
||||
gl->fbo_feedback = 0;
|
||||
}
|
||||
|
||||
static void gl2_renderchain_deinit_hw_render(void *data)
|
||||
static void gl2_renderchain_deinit_hw_render(
|
||||
void *data,
|
||||
void *chain_data)
|
||||
{
|
||||
gl_t *gl = (gl_t*)data;
|
||||
gl_t *gl = (gl_t*)data;
|
||||
gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data;
|
||||
if (!gl)
|
||||
return;
|
||||
|
||||
context_bind_hw_render(true);
|
||||
|
||||
if (gl->hw_render_fbo_init)
|
||||
glDeleteFramebuffers(gl->textures, gl->hw_render_fbo);
|
||||
if (gl->hw_render_depth_init)
|
||||
glDeleteRenderbuffers(gl->textures, gl->hw_render_depth);
|
||||
gl2_delete_fb(gl->textures, gl->hw_render_fbo);
|
||||
if (chain->hw_render_depth_init)
|
||||
gl2_delete_rb(gl->textures, chain->hw_render_depth);
|
||||
gl->hw_render_fbo_init = false;
|
||||
|
||||
context_bind_hw_render(false);
|
||||
}
|
||||
|
||||
void gl2_renderchain_free(void *data)
|
||||
static void gl2_renderchain_free(void *data, void *chain_data)
|
||||
{
|
||||
gl_t *gl = (gl_t*)data;
|
||||
|
||||
gl2_renderchain_deinit_fbo(gl);
|
||||
gl2_renderchain_deinit_hw_render(gl);
|
||||
gl2_renderchain_deinit_fbo(gl, chain_data);
|
||||
gl2_renderchain_deinit_hw_render(gl, chain_data);
|
||||
}
|
||||
|
||||
static bool gl_create_fbo_targets(gl_t *gl)
|
||||
static bool gl_create_fbo_targets(gl_t *gl, void *chain_data)
|
||||
{
|
||||
int i;
|
||||
gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glGenFramebuffers(gl->fbo_pass, gl->fbo);
|
||||
gl2_gen_fb(chain->fbo_pass, chain->fbo);
|
||||
|
||||
for (i = 0; i < gl->fbo_pass; i++)
|
||||
for (i = 0; i < chain->fbo_pass; i++)
|
||||
{
|
||||
GLenum status;
|
||||
|
||||
gl2_bind_fb(gl->fbo[i]);
|
||||
glFramebufferTexture2D(RARCH_GL_FRAMEBUFFER,
|
||||
RARCH_GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gl->fbo_texture[i], 0);
|
||||
gl2_bind_fb(chain->fbo[i]);
|
||||
gl2_fb_texture_2d(RARCH_GL_FRAMEBUFFER,
|
||||
RARCH_GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, chain->fbo_texture[i], 0);
|
||||
|
||||
status = glCheckFramebufferStatus(RARCH_GL_FRAMEBUFFER);
|
||||
status = gl2_check_fb_status(RARCH_GL_FRAMEBUFFER);
|
||||
if (status != RARCH_GL_FRAMEBUFFER_COMPLETE)
|
||||
goto error;
|
||||
}
|
||||
@ -487,13 +564,13 @@ static bool gl_create_fbo_targets(gl_t *gl)
|
||||
{
|
||||
GLenum status;
|
||||
|
||||
glGenFramebuffers(1, &gl->fbo_feedback);
|
||||
gl2_gen_fb(1, &gl->fbo_feedback);
|
||||
gl2_bind_fb(gl->fbo_feedback);
|
||||
glFramebufferTexture2D(RARCH_GL_FRAMEBUFFER,
|
||||
gl2_fb_texture_2d(RARCH_GL_FRAMEBUFFER,
|
||||
RARCH_GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||
gl->fbo_feedback_texture, 0);
|
||||
|
||||
status = glCheckFramebufferStatus(RARCH_GL_FRAMEBUFFER);
|
||||
status = gl2_check_fb_status(RARCH_GL_FRAMEBUFFER);
|
||||
if (status != RARCH_GL_FRAMEBUFFER_COMPLETE)
|
||||
goto error;
|
||||
|
||||
@ -506,20 +583,22 @@ static bool gl_create_fbo_targets(gl_t *gl)
|
||||
return true;
|
||||
|
||||
error:
|
||||
glDeleteFramebuffers(gl->fbo_pass, gl->fbo);
|
||||
gl2_delete_fb(chain->fbo_pass, chain->fbo);
|
||||
if (gl->fbo_feedback)
|
||||
glDeleteFramebuffers(1, &gl->fbo_feedback);
|
||||
gl2_delete_fb(1, &gl->fbo_feedback);
|
||||
RARCH_ERR("[GL]: Failed to set up frame buffer objects. Multi-pass shading will not work.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
static void gl_create_fbo_texture(gl_t *gl, unsigned i, GLuint texture)
|
||||
static void gl_create_fbo_texture(gl_t *gl,
|
||||
void *chain_data, unsigned i, GLuint texture)
|
||||
{
|
||||
GLenum mag_filter, wrap_enum;
|
||||
video_shader_ctx_filter_t filter_type;
|
||||
video_shader_ctx_wrap_t wrap = {0};
|
||||
bool fp_fbo = false;
|
||||
bool smooth = false;
|
||||
gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data;
|
||||
settings_t *settings = config_get_ptr();
|
||||
GLuint base_filt = settings->bools.video_smooth ? GL_LINEAR : GL_NEAREST;
|
||||
GLuint base_mip_filt = settings->bools.video_smooth ?
|
||||
@ -547,16 +626,16 @@ static void gl_create_fbo_texture(gl_t *gl, unsigned i, GLuint texture)
|
||||
|
||||
gl_bind_texture(texture, wrap_enum, mag_filter, min_filter);
|
||||
|
||||
fp_fbo = gl->fbo_scale[i].fp_fbo;
|
||||
fp_fbo = chain->fbo_scale[i].fp_fbo;
|
||||
|
||||
if (fp_fbo)
|
||||
{
|
||||
if (!gl->has_fp_fbo)
|
||||
if (!chain->has_fp_fbo)
|
||||
RARCH_ERR("[GL]: Floating-point FBO was requested, but is not supported. Falling back to UNORM. Result may band/clip/etc.!\n");
|
||||
}
|
||||
|
||||
#if !defined(HAVE_OPENGLES2)
|
||||
if (fp_fbo && gl->has_fp_fbo)
|
||||
if (fp_fbo && chain->has_fp_fbo)
|
||||
{
|
||||
RARCH_LOG("[GL]: FBO pass #%d is floating-point.\n", i);
|
||||
gl_load_texture_image(GL_TEXTURE_2D, 0, GL_RGBA32F,
|
||||
@ -567,18 +646,18 @@ static void gl_create_fbo_texture(gl_t *gl, unsigned i, GLuint texture)
|
||||
#endif
|
||||
{
|
||||
#ifndef HAVE_OPENGLES
|
||||
bool srgb_fbo = gl->fbo_scale[i].srgb_fbo;
|
||||
bool srgb_fbo = chain->fbo_scale[i].srgb_fbo;
|
||||
|
||||
if (!fp_fbo && srgb_fbo)
|
||||
{
|
||||
if (!gl->has_srgb_fbo)
|
||||
if (!chain->has_srgb_fbo)
|
||||
RARCH_ERR("[GL]: sRGB FBO was requested, but it is not supported. Falling back to UNORM. Result may have banding!\n");
|
||||
}
|
||||
|
||||
if (settings->bools.video_force_srgb_disable)
|
||||
srgb_fbo = false;
|
||||
|
||||
if (srgb_fbo && gl->has_srgb_fbo)
|
||||
if (srgb_fbo && chain->has_srgb_fbo)
|
||||
{
|
||||
RARCH_LOG("[GL]: FBO pass #%d is sRGB.\n", i);
|
||||
#ifdef HAVE_OPENGLES2
|
||||
@ -587,7 +666,7 @@ static void gl_create_fbo_texture(gl_t *gl, unsigned i, GLuint texture)
|
||||
glTexImage2D(GL_TEXTURE_2D,
|
||||
0, GL_SRGB_ALPHA_EXT,
|
||||
gl->fbo_rect[i].width, gl->fbo_rect[i].height, 0,
|
||||
gl->has_srgb_fbo_gles3 ? GL_RGBA : GL_SRGB_ALPHA_EXT,
|
||||
chain->has_srgb_fbo_gles3 ? GL_RGBA : GL_SRGB_ALPHA_EXT,
|
||||
GL_UNSIGNED_BYTE, NULL);
|
||||
#else
|
||||
gl_load_texture_image(GL_TEXTURE_2D,
|
||||
@ -616,18 +695,22 @@ static void gl_create_fbo_texture(gl_t *gl, unsigned i, GLuint texture)
|
||||
}
|
||||
}
|
||||
|
||||
static void gl_create_fbo_textures(gl_t *gl)
|
||||
static void gl_create_fbo_textures(gl_t *gl, void *chain_data)
|
||||
{
|
||||
int i;
|
||||
glGenTextures(gl->fbo_pass, gl->fbo_texture);
|
||||
gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data;
|
||||
|
||||
for (i = 0; i < gl->fbo_pass; i++)
|
||||
gl_create_fbo_texture(gl, i, gl->fbo_texture[i]);
|
||||
glGenTextures(chain->fbo_pass, chain->fbo_texture);
|
||||
|
||||
for (i = 0; i < chain->fbo_pass; i++)
|
||||
gl_create_fbo_texture(gl, gl->renderchain_data,
|
||||
i, chain->fbo_texture[i]);
|
||||
|
||||
if (gl->fbo_feedback_enable)
|
||||
{
|
||||
glGenTextures(1, &gl->fbo_feedback_texture);
|
||||
gl_create_fbo_texture(gl,
|
||||
gl->renderchain_data,
|
||||
gl->fbo_feedback_pass, gl->fbo_feedback_texture);
|
||||
}
|
||||
|
||||
@ -640,11 +723,13 @@ static void gl_create_fbo_textures(gl_t *gl)
|
||||
|
||||
static void gl2_renderchain_recompute_pass_sizes(
|
||||
void *data,
|
||||
void *chain_data,
|
||||
unsigned width, unsigned height,
|
||||
unsigned vp_width, unsigned vp_height)
|
||||
{
|
||||
int i;
|
||||
gl_t *gl = (gl_t*)data;
|
||||
gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data;
|
||||
bool size_modified = false;
|
||||
GLint max_size = 0;
|
||||
unsigned last_width = width;
|
||||
@ -655,10 +740,10 @@ static void gl2_renderchain_recompute_pass_sizes(
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_size);
|
||||
|
||||
/* Calculate viewports for FBOs. */
|
||||
for (i = 0; i < gl->fbo_pass; i++)
|
||||
for (i = 0; i < chain->fbo_pass; i++)
|
||||
{
|
||||
struct video_fbo_rect *fbo_rect = &gl->fbo_rect[i];
|
||||
struct gfx_fbo_scale *fbo_scale = &gl->fbo_scale[i];
|
||||
struct gfx_fbo_scale *fbo_scale = &chain->fbo_scale[i];
|
||||
|
||||
gl2_renderchain_convert_geometry(
|
||||
gl, fbo_rect, fbo_scale,
|
||||
@ -702,6 +787,7 @@ static void gl2_renderchain_recompute_pass_sizes(
|
||||
}
|
||||
|
||||
static void gl2_renderchain_start_render(void *data,
|
||||
void *chain_data,
|
||||
video_frame_info_t *video_info)
|
||||
{
|
||||
/* Used when rendering to an FBO.
|
||||
@ -713,10 +799,11 @@ static void gl2_renderchain_start_render(void *data,
|
||||
0, 1,
|
||||
1, 1
|
||||
};
|
||||
gl_t *gl = (gl_t*)data;
|
||||
gl_t *gl = (gl_t*)data;
|
||||
gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]);
|
||||
gl2_bind_fb(gl->fbo[0]);
|
||||
gl2_bind_fb(chain->fbo[0]);
|
||||
|
||||
gl_set_viewport(gl,
|
||||
video_info, gl->fbo_rect[0].img_width,
|
||||
@ -729,21 +816,23 @@ static void gl2_renderchain_start_render(void *data,
|
||||
gl->coords.vertex = fbo_vertexes;
|
||||
|
||||
#if defined(GL_FRAMEBUFFER_SRGB) && !defined(HAVE_OPENGLES)
|
||||
if (gl->has_srgb_fbo)
|
||||
if (chain->has_srgb_fbo)
|
||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Set up render to texture. */
|
||||
void gl2_renderchain_init(
|
||||
void *data, unsigned fbo_width, unsigned fbo_height)
|
||||
void *data, void *chain_data,
|
||||
unsigned fbo_width, unsigned fbo_height)
|
||||
{
|
||||
int i;
|
||||
unsigned width, height;
|
||||
video_shader_ctx_scale_t scaler;
|
||||
video_shader_ctx_info_t shader_info;
|
||||
struct gfx_fbo_scale scale, scale_last;
|
||||
gl_t *gl = (gl_t*)data;
|
||||
gl_t *gl = (gl_t*)data;
|
||||
gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data;
|
||||
|
||||
if (!video_shader_driver_info(&shader_info))
|
||||
return;
|
||||
@ -773,9 +862,9 @@ void gl2_renderchain_init(
|
||||
return;
|
||||
}
|
||||
|
||||
gl->fbo_pass = shader_info.num - 1;
|
||||
chain->fbo_pass = shader_info.num - 1;
|
||||
if (scale_last.valid)
|
||||
gl->fbo_pass++;
|
||||
chain->fbo_pass++;
|
||||
|
||||
if (!scale.valid)
|
||||
{
|
||||
@ -785,28 +874,29 @@ void gl2_renderchain_init(
|
||||
scale.valid = true;
|
||||
}
|
||||
|
||||
gl->fbo_scale[0] = scale;
|
||||
chain->fbo_scale[0] = scale;
|
||||
|
||||
for (i = 1; i < gl->fbo_pass; i++)
|
||||
for (i = 1; i < chain->fbo_pass; i++)
|
||||
{
|
||||
scaler.idx = i + 1;
|
||||
scaler.scale = &gl->fbo_scale[i];
|
||||
scaler.scale = &chain->fbo_scale[i];
|
||||
|
||||
video_shader_driver_scale(&scaler);
|
||||
|
||||
if (!gl->fbo_scale[i].valid)
|
||||
if (!chain->fbo_scale[i].valid)
|
||||
{
|
||||
gl->fbo_scale[i].scale_x = gl->fbo_scale[i].scale_y = 1.0f;
|
||||
gl->fbo_scale[i].type_x = gl->fbo_scale[i].type_y =
|
||||
chain->fbo_scale[i].scale_x = chain->fbo_scale[i].scale_y = 1.0f;
|
||||
chain->fbo_scale[i].type_x = chain->fbo_scale[i].type_y =
|
||||
RARCH_SCALE_INPUT;
|
||||
gl->fbo_scale[i].valid = true;
|
||||
chain->fbo_scale[i].valid = true;
|
||||
}
|
||||
}
|
||||
|
||||
gl2_renderchain_recompute_pass_sizes(gl,
|
||||
chain_data,
|
||||
fbo_width, fbo_height, width, height);
|
||||
|
||||
for (i = 0; i < gl->fbo_pass; i++)
|
||||
for (i = 0; i < chain->fbo_pass; i++)
|
||||
{
|
||||
gl->fbo_rect[i].width = next_pow2(gl->fbo_rect[i].img_width);
|
||||
gl->fbo_rect[i].height = next_pow2(gl->fbo_rect[i].img_height);
|
||||
@ -818,7 +908,7 @@ void gl2_renderchain_init(
|
||||
&gl->fbo_feedback_pass);
|
||||
|
||||
if (gl->fbo_feedback_enable && gl->fbo_feedback_pass
|
||||
< (unsigned)gl->fbo_pass)
|
||||
< (unsigned)chain->fbo_pass)
|
||||
{
|
||||
RARCH_LOG("[GL]: Creating feedback FBO %d @ %ux%u\n", i,
|
||||
gl->fbo_rect[gl->fbo_feedback_pass].width,
|
||||
@ -827,14 +917,14 @@ void gl2_renderchain_init(
|
||||
else if (gl->fbo_feedback_enable)
|
||||
{
|
||||
RARCH_WARN("[GL]: Tried to create feedback FBO of pass #%u, but there are only %d FBO passes. Will use input texture as feedback texture.\n",
|
||||
gl->fbo_feedback_pass, gl->fbo_pass);
|
||||
gl->fbo_feedback_pass, chain->fbo_pass);
|
||||
gl->fbo_feedback_enable = false;
|
||||
}
|
||||
|
||||
gl_create_fbo_textures(gl);
|
||||
if (!gl || !gl_create_fbo_targets(gl))
|
||||
gl_create_fbo_textures(gl, chain);
|
||||
if (!gl || !gl_create_fbo_targets(gl, chain))
|
||||
{
|
||||
glDeleteTextures(gl->fbo_pass, gl->fbo_texture);
|
||||
glDeleteTextures(chain->fbo_pass, chain->fbo_texture);
|
||||
RARCH_ERR("[GL]: Failed to create FBO targets. Will continue without FBO.\n");
|
||||
return;
|
||||
}
|
||||
@ -844,6 +934,7 @@ void gl2_renderchain_init(
|
||||
|
||||
static bool gl2_renderchain_init_hw_render(
|
||||
void *data,
|
||||
void *chain_data,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
GLenum status;
|
||||
@ -855,6 +946,7 @@ static bool gl2_renderchain_init_hw_render(
|
||||
struct retro_hw_render_callback *hwr =
|
||||
video_driver_get_hw_context();
|
||||
gl_t *gl = (gl_t*)data;
|
||||
gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data;
|
||||
|
||||
/* We can only share texture objects through contexts.
|
||||
* FBOs are "abstract" objects and are not shared. */
|
||||
@ -872,58 +964,62 @@ static bool gl2_renderchain_init_hw_render(
|
||||
RARCH_LOG("[GL]: Supports FBO (render-to-texture).\n");
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glGenFramebuffers(gl->textures, gl->hw_render_fbo);
|
||||
gl2_gen_fb(gl->textures, gl->hw_render_fbo);
|
||||
|
||||
depth = hwr->depth;
|
||||
stencil = hwr->stencil;
|
||||
|
||||
if (depth)
|
||||
{
|
||||
glGenRenderbuffers(gl->textures, gl->hw_render_depth);
|
||||
gl->hw_render_depth_init = true;
|
||||
gl2_gen_rb(gl->textures, chain->hw_render_depth);
|
||||
chain->hw_render_depth_init = true;
|
||||
}
|
||||
|
||||
for (i = 0; i < gl->textures; i++)
|
||||
{
|
||||
gl2_bind_fb(gl->hw_render_fbo[i]);
|
||||
glFramebufferTexture2D(RARCH_GL_FRAMEBUFFER,
|
||||
gl2_fb_texture_2d(RARCH_GL_FRAMEBUFFER,
|
||||
RARCH_GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gl->texture[i], 0);
|
||||
|
||||
if (depth)
|
||||
{
|
||||
glBindRenderbuffer(RARCH_GL_RENDERBUFFER, gl->hw_render_depth[i]);
|
||||
glRenderbufferStorage(RARCH_GL_RENDERBUFFER,
|
||||
gl2_bind_rb(RARCH_GL_RENDERBUFFER, chain->hw_render_depth[i]);
|
||||
gl2_rb_storage(RARCH_GL_RENDERBUFFER,
|
||||
stencil ? RARCH_GL_DEPTH24_STENCIL8 : GL_DEPTH_COMPONENT16,
|
||||
width, height);
|
||||
glBindRenderbuffer(RARCH_GL_RENDERBUFFER, 0);
|
||||
gl2_bind_rb(RARCH_GL_RENDERBUFFER, 0);
|
||||
|
||||
if (stencil)
|
||||
{
|
||||
#if defined(HAVE_OPENGLES2) || defined(HAVE_OPENGLES1) || ((defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__))))
|
||||
/* GLES2 is a bit weird, as always.
|
||||
* There's no GL_DEPTH_STENCIL_ATTACHMENT like in desktop GL. */
|
||||
glFramebufferRenderbuffer(RARCH_GL_FRAMEBUFFER,
|
||||
gl2_fb_rb(RARCH_GL_FRAMEBUFFER,
|
||||
RARCH_GL_DEPTH_ATTACHMENT,
|
||||
RARCH_GL_RENDERBUFFER, gl->hw_render_depth[i]);
|
||||
glFramebufferRenderbuffer(RARCH_GL_FRAMEBUFFER,
|
||||
RARCH_GL_RENDERBUFFER,
|
||||
chain->hw_render_depth[i]);
|
||||
gl2_fb_rb(RARCH_GL_FRAMEBUFFER,
|
||||
RARCH_GL_STENCIL_ATTACHMENT,
|
||||
RARCH_GL_RENDERBUFFER, gl->hw_render_depth[i]);
|
||||
RARCH_GL_RENDERBUFFER,
|
||||
chain->hw_render_depth[i]);
|
||||
#else
|
||||
/* We use ARB FBO extensions, no need to check. */
|
||||
glFramebufferRenderbuffer(RARCH_GL_FRAMEBUFFER,
|
||||
gl2_fb_rb(RARCH_GL_FRAMEBUFFER,
|
||||
GL_DEPTH_STENCIL_ATTACHMENT,
|
||||
RARCH_GL_RENDERBUFFER, gl->hw_render_depth[i]);
|
||||
RARCH_GL_RENDERBUFFER,
|
||||
chain->hw_render_depth[i]);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
glFramebufferRenderbuffer(RARCH_GL_FRAMEBUFFER,
|
||||
gl2_fb_rb(RARCH_GL_FRAMEBUFFER,
|
||||
RARCH_GL_DEPTH_ATTACHMENT,
|
||||
RARCH_GL_RENDERBUFFER, gl->hw_render_depth[i]);
|
||||
RARCH_GL_RENDERBUFFER,
|
||||
chain->hw_render_depth[i]);
|
||||
}
|
||||
}
|
||||
|
||||
status = glCheckFramebufferStatus(RARCH_GL_FRAMEBUFFER);
|
||||
status = gl2_check_fb_status(RARCH_GL_FRAMEBUFFER);
|
||||
if (status != RARCH_GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
RARCH_ERR("[GL]: Failed to create HW render FBO #%u, error: 0x%u.\n",
|
||||
@ -932,7 +1028,7 @@ static bool gl2_renderchain_init_hw_render(
|
||||
}
|
||||
}
|
||||
|
||||
gl2_renderchain_bind_backbuffer();
|
||||
gl2_renderchain_bind_backbuffer(gl, chain_data);
|
||||
gl->hw_render_fbo_init = true;
|
||||
|
||||
context_bind_hw_render(false);
|
||||
@ -941,9 +1037,11 @@ static bool gl2_renderchain_init_hw_render(
|
||||
|
||||
static void gl2_renderchain_bind_prev_texture(
|
||||
void *data,
|
||||
void *chain_data,
|
||||
const struct video_tex_info *tex_info)
|
||||
{
|
||||
gl_t *gl = (gl_t*)data;
|
||||
gl_t *gl = (gl_t*)data;
|
||||
gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data;
|
||||
|
||||
memmove(gl->prev_info + 1, gl->prev_info,
|
||||
sizeof(*tex_info) * (gl->textures - 1));
|
||||
@ -956,15 +1054,16 @@ static void gl2_renderchain_bind_prev_texture(
|
||||
{
|
||||
GLuint tmp_fbo = gl->fbo_feedback;
|
||||
GLuint tmp_tex = gl->fbo_feedback_texture;
|
||||
gl->fbo_feedback = gl->fbo[gl->fbo_feedback_pass];
|
||||
gl->fbo_feedback_texture = gl->fbo_texture[gl->fbo_feedback_pass];
|
||||
gl->fbo[gl->fbo_feedback_pass] = tmp_fbo;
|
||||
gl->fbo_texture[gl->fbo_feedback_pass] = tmp_tex;
|
||||
gl->fbo_feedback = chain->fbo[gl->fbo_feedback_pass];
|
||||
gl->fbo_feedback_texture = chain->fbo_texture[gl->fbo_feedback_pass];
|
||||
chain->fbo[gl->fbo_feedback_pass] = tmp_fbo;
|
||||
chain->fbo_texture[gl->fbo_feedback_pass] = tmp_tex;
|
||||
}
|
||||
}
|
||||
|
||||
static void gl2_renderchain_viewport_info(
|
||||
void *data, struct video_viewport *vp)
|
||||
void *data, void *chain_data,
|
||||
struct video_viewport *vp)
|
||||
{
|
||||
unsigned width, height;
|
||||
unsigned top_y, top_dist;
|
||||
@ -983,7 +1082,9 @@ static void gl2_renderchain_viewport_info(
|
||||
}
|
||||
|
||||
static bool gl2_renderchain_read_viewport(
|
||||
void *data, uint8_t *buffer, bool is_idle)
|
||||
void *data,
|
||||
void *chain_data,
|
||||
uint8_t *buffer, bool is_idle)
|
||||
{
|
||||
unsigned num_pixels = 0;
|
||||
gl_t *gl = (gl_t*)data;
|
||||
@ -1084,14 +1185,14 @@ error:
|
||||
return false;
|
||||
}
|
||||
|
||||
void gl2_renderchain_free_internal(void *data)
|
||||
void gl2_renderchain_free_internal(void *data, void *chain_data)
|
||||
{
|
||||
gl2_renderchain_t *cg_data = (gl2_renderchain_t*)data;
|
||||
gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data;
|
||||
|
||||
if (!cg_data)
|
||||
if (!chain)
|
||||
return;
|
||||
|
||||
free(cg_data);
|
||||
free(chain);
|
||||
}
|
||||
|
||||
static void *gl2_renderchain_new(void)
|
||||
@ -1104,40 +1205,43 @@ static void *gl2_renderchain_new(void)
|
||||
}
|
||||
|
||||
#ifndef HAVE_OPENGLES
|
||||
static void gl2_renderchain_bind_vao(void *data)
|
||||
static void gl2_renderchain_bind_vao(void *data,
|
||||
void *chain_data)
|
||||
{
|
||||
gl_t *gl = (gl_t*)data;
|
||||
if (!gl)
|
||||
gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data;
|
||||
if (!chain)
|
||||
return;
|
||||
glBindVertexArray(gl->vao);
|
||||
glBindVertexArray(chain->vao);
|
||||
}
|
||||
|
||||
static void gl2_renderchain_unbind_vao(void *data)
|
||||
static void gl2_renderchain_unbind_vao(void *data,
|
||||
void *chain_data)
|
||||
{
|
||||
gl_t *gl = (gl_t*)data;
|
||||
if (!gl)
|
||||
return;
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
static void gl2_renderchain_new_vao(void *data)
|
||||
static void gl2_renderchain_new_vao(void *data,
|
||||
void *chain_data)
|
||||
{
|
||||
gl_t *gl = (gl_t*)data;
|
||||
if (!gl)
|
||||
gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data;
|
||||
if (!chain)
|
||||
return;
|
||||
glGenVertexArrays(1, &gl->vao);
|
||||
glGenVertexArrays(1, &chain->vao);
|
||||
}
|
||||
|
||||
static void gl2_renderchain_free_vao(void *data)
|
||||
static void gl2_renderchain_free_vao(void *data,
|
||||
void *chain_data)
|
||||
{
|
||||
gl_t *gl = (gl_t*)data;
|
||||
if (!gl)
|
||||
gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data;
|
||||
if (!chain)
|
||||
return;
|
||||
glDeleteVertexArrays(1, &gl->vao);
|
||||
glDeleteVertexArrays(1, &chain->vao);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void gl2_renderchain_restore_default_state(void *data)
|
||||
static void gl2_renderchain_restore_default_state(
|
||||
void *data,
|
||||
void *chain_data)
|
||||
{
|
||||
gl_t *gl = (gl_t*)data;
|
||||
if (!gl)
|
||||
@ -1153,6 +1257,7 @@ static void gl2_renderchain_restore_default_state(void *data)
|
||||
|
||||
static void gl2_renderchain_copy_frame(
|
||||
void *data,
|
||||
void *chain_data,
|
||||
video_frame_info_t *video_info,
|
||||
const void *frame,
|
||||
unsigned width, unsigned height, unsigned pitch)
|
||||
@ -1176,7 +1281,7 @@ static void gl2_renderchain_copy_frame(
|
||||
}
|
||||
#elif defined(HAVE_OPENGLES)
|
||||
#if defined(HAVE_EGL)
|
||||
if (gl->egl_images)
|
||||
if (chain->egl_images)
|
||||
{
|
||||
gfx_ctx_image_t img_info;
|
||||
bool new_egl = false;
|
||||
@ -1295,7 +1400,8 @@ static void gl2_renderchain_bind_pbo(unsigned idx)
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, (GLuint)idx);
|
||||
}
|
||||
|
||||
static void gl2_renderchain_unbind_pbo(void)
|
||||
static void gl2_renderchain_unbind_pbo(void *data,
|
||||
void *chain_data)
|
||||
{
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||
}
|
||||
@ -1309,6 +1415,7 @@ static void gl2_renderchain_init_pbo(unsigned size,
|
||||
#endif
|
||||
|
||||
static void gl2_renderchain_readback(void *data,
|
||||
void *chain_data,
|
||||
unsigned alignment,
|
||||
unsigned fmt, unsigned type,
|
||||
void *src)
|
||||
@ -1327,47 +1434,51 @@ static void gl2_renderchain_readback(void *data,
|
||||
}
|
||||
|
||||
#ifndef HAVE_OPENGLES
|
||||
static void gl2_renderchain_fence_iterate(void *data, unsigned
|
||||
hard_sync_frames)
|
||||
static void gl2_renderchain_fence_iterate(
|
||||
void *data,
|
||||
void *chain_data,
|
||||
unsigned hard_sync_frames)
|
||||
{
|
||||
gl_t *gl = (gl_t*)data;
|
||||
gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data;
|
||||
|
||||
gl->fences[gl->fence_count++] =
|
||||
chain->fences[chain->fence_count++] =
|
||||
glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
|
||||
while (gl->fence_count > hard_sync_frames)
|
||||
while (chain->fence_count > hard_sync_frames)
|
||||
{
|
||||
glClientWaitSync(gl->fences[0],
|
||||
glClientWaitSync(chain->fences[0],
|
||||
GL_SYNC_FLUSH_COMMANDS_BIT, 1000000000);
|
||||
glDeleteSync(gl->fences[0]);
|
||||
glDeleteSync(chain->fences[0]);
|
||||
|
||||
gl->fence_count--;
|
||||
memmove(gl->fences, gl->fences + 1,
|
||||
gl->fence_count * sizeof(GLsync));
|
||||
chain->fence_count--;
|
||||
memmove(chain->fences, chain->fences + 1,
|
||||
chain->fence_count * sizeof(GLsync));
|
||||
}
|
||||
}
|
||||
|
||||
static void gl2_renderchain_fence_free(void *data)
|
||||
static void gl2_renderchain_fence_free(void *data,
|
||||
void *chain_data)
|
||||
{
|
||||
unsigned i;
|
||||
gl_t *gl = (gl_t*)data;
|
||||
gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data;
|
||||
|
||||
for (i = 0; i < gl->fence_count; i++)
|
||||
for (i = 0; i < chain->fence_count; i++)
|
||||
{
|
||||
glClientWaitSync(gl->fences[i],
|
||||
glClientWaitSync(chain->fences[i],
|
||||
GL_SYNC_FLUSH_COMMANDS_BIT, 1000000000);
|
||||
glDeleteSync(gl->fences[i]);
|
||||
glDeleteSync(chain->fences[i]);
|
||||
}
|
||||
gl->fence_count = 0;
|
||||
chain->fence_count = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void gl2_renderchain_init_textures_reference(
|
||||
void *data, unsigned i,
|
||||
void *data, void *chain_data, unsigned i,
|
||||
unsigned internal_fmt, unsigned texture_fmt,
|
||||
unsigned texture_type)
|
||||
{
|
||||
gl_t *gl = (gl_t*)data;
|
||||
gl_t *gl = (gl_t*)data;
|
||||
gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data;
|
||||
#ifdef HAVE_PSGL
|
||||
glTextureReferenceSCE(GL_TEXTURE_2D, 1,
|
||||
gl->tex_w, gl->tex_h, 0,
|
||||
@ -1375,7 +1486,7 @@ static void gl2_renderchain_init_textures_reference(
|
||||
gl->tex_w * gl->base_size,
|
||||
gl->tex_w * gl->tex_h * i * gl->base_size);
|
||||
#else
|
||||
if (gl->egl_images)
|
||||
if (chain->egl_images)
|
||||
return;
|
||||
|
||||
gl_load_texture_image(GL_TEXTURE_2D,
|
||||
@ -1388,6 +1499,30 @@ static void gl2_renderchain_init_textures_reference(
|
||||
#endif
|
||||
}
|
||||
|
||||
static void gl2_renderchain_resolve_extensions(void *data,
|
||||
void *chain_data, const char *context_ident,
|
||||
const video_info_t *video)
|
||||
{
|
||||
gl_t *gl = (gl_t*)data;
|
||||
gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data;
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
if (!chain)
|
||||
return;
|
||||
|
||||
chain->has_srgb_fbo = false;
|
||||
chain->has_fp_fbo = gl_check_capability(GL_CAPS_FP_FBO);
|
||||
/* GLES3 has unpack_subimage and sRGB in core. */
|
||||
chain->has_srgb_fbo_gles3 = gl_check_capability(GL_CAPS_SRGB_FBO_ES3);
|
||||
|
||||
if (!settings->bools.video_force_srgb_disable)
|
||||
chain->has_srgb_fbo = gl_check_capability(GL_CAPS_SRGB_FBO);
|
||||
|
||||
/* Use regular textures if we use HW render. */
|
||||
chain->egl_images = !gl->hw_render_use && gl_check_capability(GL_CAPS_EGLIMAGE) &&
|
||||
video_context_driver_init_image_buffer(video);
|
||||
}
|
||||
|
||||
gl_renderchain_driver_t gl2_renderchain = {
|
||||
NULL, /* set_coords */
|
||||
NULL, /* set_mvp */
|
||||
@ -1440,5 +1575,6 @@ gl_renderchain_driver_t gl2_renderchain = {
|
||||
gl2_renderchain_check_fbo_dimensions,
|
||||
gl2_renderchain_recompute_pass_sizes,
|
||||
gl2_renderchain_render,
|
||||
gl2_renderchain_resolve_extensions,
|
||||
"gl2",
|
||||
};
|
||||
|
@ -129,6 +129,7 @@ static const char *glsl_prefixes[] = {
|
||||
#include "../drivers/gl_shaders/modern_pipeline_xmb_ribbon.glsl.vert.h"
|
||||
#include "../drivers/gl_shaders/pipeline_xmb_ribbon.glsl.frag.h"
|
||||
#include "../drivers/gl_shaders/pipeline_bokeh.glsl.frag.h"
|
||||
#include "../drivers/gl_shaders/pipeline_snowflake.glsl.frag.h"
|
||||
#endif
|
||||
|
||||
typedef struct glsl_shader_data
|
||||
@ -1095,6 +1096,21 @@ static void *gl_glsl_init(void *data, const char *path)
|
||||
&shader_prog_info);
|
||||
gl_glsl_find_uniforms(glsl, 0, glsl->prg[VIDEO_SHADER_MENU_5].id,
|
||||
&glsl->uniforms[VIDEO_SHADER_MENU_5]);
|
||||
|
||||
#if defined(HAVE_OPENGLES)
|
||||
shader_prog_info.vertex = stock_vertex_xmb_snow_modern;
|
||||
#else
|
||||
shader_prog_info.vertex = glsl_core ? stock_vertex_xmb_snow_modern : stock_vertex_xmb_snow_legacy;
|
||||
#endif
|
||||
shader_prog_info.fragment = stock_fragment_xmb_snowflake;
|
||||
|
||||
gl_glsl_compile_program(
|
||||
glsl,
|
||||
VIDEO_SHADER_MENU_6,
|
||||
&glsl->prg[VIDEO_SHADER_MENU_6],
|
||||
&shader_prog_info);
|
||||
gl_glsl_find_uniforms(glsl, 0, glsl->prg[VIDEO_SHADER_MENU_6].id,
|
||||
&glsl->uniforms[VIDEO_SHADER_MENU_6]);
|
||||
#endif
|
||||
|
||||
gl_glsl_reset_attrib(glsl);
|
||||
|
@ -46,10 +46,6 @@
|
||||
#include "../menu/menu_setting.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENGL
|
||||
#include "common/gl_common.h"
|
||||
#endif
|
||||
|
||||
#include "video_thread_wrapper.h"
|
||||
#include "video_driver.h"
|
||||
|
||||
|
@ -56,6 +56,7 @@
|
||||
#define VIDEO_SHADER_MENU_3 (GFX_MAX_SHADERS - 4)
|
||||
#define VIDEO_SHADER_MENU_4 (GFX_MAX_SHADERS - 5)
|
||||
#define VIDEO_SHADER_MENU_5 (GFX_MAX_SHADERS - 6)
|
||||
#define VIDEO_SHADER_MENU_6 (GFX_MAX_SHADERS - 7)
|
||||
|
||||
#endif
|
||||
|
||||
@ -837,60 +838,77 @@ typedef struct d3d_renderchain_driver
|
||||
typedef struct gl_renderchain_driver
|
||||
{
|
||||
void (*set_coords)(void *handle_data,
|
||||
void *chain_data,
|
||||
void *shader_data, const struct video_coords *coords);
|
||||
void (*set_mvp)(void *data, void *shader_data,
|
||||
void (*set_mvp)(void *data,
|
||||
void *chain_data,
|
||||
void *shader_data,
|
||||
const void *mat_data);
|
||||
void (*init_texture_reference)(
|
||||
void *data, unsigned i,
|
||||
void *data, void *chain_data, unsigned i,
|
||||
unsigned internal_fmt, unsigned texture_fmt,
|
||||
unsigned texture_type);
|
||||
void (*fence_iterate)(void *data, unsigned hard_sync_frames);
|
||||
void (*fence_free)(void *data);
|
||||
void (*fence_iterate)(void *data, void *chain_data,
|
||||
unsigned hard_sync_frames);
|
||||
void (*fence_free)(void *data, void *chain_data);
|
||||
void (*readback)(void *data,
|
||||
void *chain_data,
|
||||
unsigned alignment,
|
||||
unsigned fmt, unsigned type,
|
||||
void *src);
|
||||
void (*init_pbo)(unsigned size, const void *data);
|
||||
void (*bind_pbo)(unsigned idx);
|
||||
void (*unbind_pbo)(void);
|
||||
void (*unbind_pbo)(void *data, void *chain_data);
|
||||
void (*copy_frame)(
|
||||
void *data,
|
||||
void *chain_data,
|
||||
video_frame_info_t *video_info,
|
||||
const void *frame,
|
||||
unsigned width, unsigned height, unsigned pitch);
|
||||
void (*restore_default_state)(void *data);
|
||||
void (*new_vao)(void *data);
|
||||
void (*free_vao)(void *data);
|
||||
void (*bind_vao)(void *data);
|
||||
void (*unbind_vao)(void *data);
|
||||
void (*disable_client_arrays)(void);
|
||||
void (*restore_default_state)(void *data, void *chain_data);
|
||||
void (*new_vao)(void *data, void *chain_data);
|
||||
void (*free_vao)(void *data, void *chain_data);
|
||||
void (*bind_vao)(void *data, void *chain_data);
|
||||
void (*unbind_vao)(void *data, void *chain_data);
|
||||
void (*disable_client_arrays)(void *data, void *chain_data);
|
||||
void (*ff_vertex)(const void *data);
|
||||
void (*ff_matrix)(const void *data);
|
||||
void (*bind_backbuffer)(void);
|
||||
void (*deinit_fbo)(void *data);
|
||||
void (*bind_backbuffer)(void *data, void *chain_data);
|
||||
void (*deinit_fbo)(void *data, void *chain_data);
|
||||
void (*viewport_info)(
|
||||
void *data, struct video_viewport *vp);
|
||||
void *data, void *chain_data, struct video_viewport *vp);
|
||||
bool (*read_viewport)(
|
||||
void *data, uint8_t *buffer, bool is_idle);
|
||||
void *data, void *chain_data, uint8_t *buffer, bool is_idle);
|
||||
void (*bind_prev_texture)(
|
||||
void *data,
|
||||
void *chain_data,
|
||||
const struct video_tex_info *tex_info);
|
||||
void (*chain_free)(void *data);
|
||||
void (*chain_free)(void *data, void *chain_data);
|
||||
void *(*chain_new)(void);
|
||||
void (*init)(void *data, unsigned fbo_width, unsigned fbo_height);
|
||||
bool (*init_hw_render)(void *data, unsigned width, unsigned height);
|
||||
void (*free)(void *data);
|
||||
void (*deinit_hw_render)(void *data);
|
||||
void (*start_render)(void *data, video_frame_info_t *video_info);
|
||||
void (*check_fbo_dimensions)(void *data);
|
||||
void (*init)(void *data, void *chain_data,
|
||||
unsigned fbo_width, unsigned fbo_height);
|
||||
bool (*init_hw_render)(void *data, void *chain_data,
|
||||
unsigned width, unsigned height);
|
||||
void (*free)(void *data, void *chain_data);
|
||||
void (*deinit_hw_render)(void *data, void *chain_data);
|
||||
void (*start_render)(void *data, void *chain_data,
|
||||
video_frame_info_t *video_info);
|
||||
void (*check_fbo_dimensions)(void *data, void *chain_data);
|
||||
void (*recompute_pass_sizes)(void *data,
|
||||
void *chain_data,
|
||||
unsigned width, unsigned height,
|
||||
unsigned vp_width, unsigned vp_height);
|
||||
void (*renderchain_render)(void *data,
|
||||
void *chain_data,
|
||||
video_frame_info_t *video_info,
|
||||
uint64_t frame_count,
|
||||
const struct video_tex_info *tex_info,
|
||||
const struct video_tex_info *feedback_info);
|
||||
void (*resolve_extensions)(
|
||||
void *data,
|
||||
void *chain_data,
|
||||
const char *context_ident,
|
||||
const video_info_t *video);
|
||||
const char *ident;
|
||||
} gl_renderchain_driver_t;
|
||||
|
||||
|
@ -58,6 +58,7 @@ COMPATIBILITY
|
||||
#endif
|
||||
|
||||
#include "../libretro-common/compat/compat_fnmatch.c"
|
||||
#include "../libretro-common/compat/fopen_utf8.c"
|
||||
#include "../libretro-common/memmap/memalign.c"
|
||||
|
||||
/*============================================================
|
||||
|
@ -14,6 +14,19 @@
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* TODO/FIXME - set this once the kqueue codepath is implemented and working properly */
|
||||
#if 1
|
||||
#define HAVE_EPOLL
|
||||
#else
|
||||
#ifdef __linux__
|
||||
#define HAVE_EPOLL 1
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined (__NetBSD__)
|
||||
#define HAVE_KQUEUE 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -25,7 +38,11 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if defined(HAVE_EPOLL)
|
||||
#include <sys/epoll.h>
|
||||
#elif defined(HAVE_KQUEUE)
|
||||
#include <sys/event.h>
|
||||
#endif
|
||||
#include <sys/poll.h>
|
||||
|
||||
#include <libudev.h>
|
||||
@ -117,7 +134,7 @@ struct udev_input
|
||||
|
||||
const input_device_driver_t *joypad;
|
||||
|
||||
int epfd;
|
||||
int fd;
|
||||
udev_input_device_t **devices;
|
||||
unsigned num_devices;
|
||||
|
||||
@ -450,7 +467,11 @@ static bool udev_input_add_device(udev_input_t *udev,
|
||||
{
|
||||
int fd;
|
||||
struct stat st;
|
||||
#if defined(HAVE_EPOLL)
|
||||
struct epoll_event event;
|
||||
#elif defined(HAVE_KQUEUE)
|
||||
struct kevent event;
|
||||
#endif
|
||||
struct input_absinfo absinfo;
|
||||
udev_input_device_t **tmp;
|
||||
udev_input_device_t *device = NULL;
|
||||
@ -518,15 +539,24 @@ static bool udev_input_add_device(udev_input_t *udev,
|
||||
tmp[udev->num_devices++] = device;
|
||||
udev->devices = tmp;
|
||||
|
||||
#if defined(HAVE_EPOLL)
|
||||
event.events = EPOLLIN;
|
||||
event.data.ptr = device;
|
||||
|
||||
/* Shouldn't happen, but just check it. */
|
||||
if (epoll_ctl(udev->epfd, EPOLL_CTL_ADD, fd, &event) < 0)
|
||||
if (epoll_ctl(udev->fd, EPOLL_CTL_ADD, fd, &event) < 0)
|
||||
{
|
||||
RARCH_ERR("Failed to add FD (%d) to epoll list (%s).\n",
|
||||
fd, strerror(errno));
|
||||
}
|
||||
#elif defined(HAVE_KQUEUE)
|
||||
EV_SET(&event, fd, EVFILT_READ, EV_ADD, 0, 0, LISTENSOCKET);
|
||||
if (kevent(udev->fd, &event, 1, NULL, 0, NULL) == -1)
|
||||
{
|
||||
RARCH_ERR("Failed to add FD (%d) to kqueue list (%s).\n",
|
||||
fd, strerror(errno));
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
|
||||
@ -639,7 +669,11 @@ static bool udev_input_poll_hotplug_available(struct udev_monitor *dev)
|
||||
static void udev_input_poll(void *data)
|
||||
{
|
||||
int i, ret;
|
||||
#if defined(HAVE_EPOLL)
|
||||
struct epoll_event events[32];
|
||||
#elif defined(HAVE_KQUEUE)
|
||||
struct kevent events[32];
|
||||
#endif
|
||||
udev_input_mouse_t *mouse = NULL;
|
||||
udev_input_t *udev = (udev_input_t*)data;
|
||||
|
||||
@ -666,15 +700,30 @@ static void udev_input_poll(void *data)
|
||||
while (udev->monitor && udev_input_poll_hotplug_available(udev->monitor))
|
||||
udev_input_handle_hotplug(udev);
|
||||
|
||||
ret = epoll_wait(udev->epfd, events, ARRAY_SIZE(events), 0);
|
||||
#if defined(HAVE_EPOLL)
|
||||
ret = epoll_wait(udev->fd, events, ARRAY_SIZE(events), 0);
|
||||
#elif defined(HAVE_KQUEUE)
|
||||
{
|
||||
struct timespec timeoutspec;
|
||||
timeoutspec.tv_sec = timeout;
|
||||
timeoutspec.tv_nsec = 0;
|
||||
ret = kevent(udev->fd, NULL, 0, events,
|
||||
ARRAY_SIZE(events), &timeoutspec);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < ret; i++)
|
||||
{
|
||||
/* TODO/FIXME - add HAVE_EPOLL/HAVE_KQUEUE codepaths here */
|
||||
if (events[i].events & EPOLLIN)
|
||||
{
|
||||
int j, len;
|
||||
struct input_event input_events[32];
|
||||
#if defined(HAVE_EPOLL)
|
||||
udev_input_device_t *device = (udev_input_device_t*)events[i].data.ptr;
|
||||
#elif defined(HAVE_KQUEUE)
|
||||
udev_input_device_t *device = (udev_input_device_t*)events[i].udata;
|
||||
#endif
|
||||
|
||||
while ((len = read(device->fd,
|
||||
input_events, sizeof(input_events))) > 0)
|
||||
@ -874,10 +923,10 @@ static void udev_input_free(void *data)
|
||||
if (udev->joypad)
|
||||
udev->joypad->destroy();
|
||||
|
||||
if (udev->epfd >= 0)
|
||||
close(udev->epfd);
|
||||
if (udev->fd >= 0)
|
||||
close(udev->fd);
|
||||
|
||||
udev->epfd = -1;
|
||||
udev->fd = -1;
|
||||
|
||||
for (i = 0; i < udev->num_devices; i++)
|
||||
{
|
||||
@ -978,14 +1027,23 @@ static void *udev_input_init(const char *joypad_driver)
|
||||
udev->xkb_handling = string_is_equal(ctx_ident.ident, "kms");
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_EPOLL)
|
||||
fd = epoll_create(32);
|
||||
if (fd < 0)
|
||||
{
|
||||
RARCH_ERR("Failed to create epoll FD.\n");
|
||||
RARCH_ERR("Failed to create poll file descriptor.\n");
|
||||
goto error;
|
||||
}
|
||||
#elif defined(HAVE_KQUEUE)
|
||||
fd = kqueue();
|
||||
if (fd == -1)
|
||||
{
|
||||
RARCH_ERR("Failed to create poll file descriptor.\n");
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
|
||||
udev->epfd = fd;
|
||||
udev->fd = fd;
|
||||
|
||||
if (!open_devices(udev, UDEV_INPUT_KEYBOARD, udev_handle_keyboard))
|
||||
{
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "../../gfx/video_driver.h"
|
||||
#include "../common/input_x11_common.h"
|
||||
|
||||
#include "../../configuration.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
typedef struct x11_input
|
||||
@ -72,6 +73,78 @@ static void *x_input_init(const char *joypad_driver)
|
||||
return x11;
|
||||
}
|
||||
|
||||
static bool x_keyboard_pressed(x11_input_t *x11, unsigned key)
|
||||
{
|
||||
int keycode = XKeysymToKeycode(x11->display, rarch_keysym_lut[(enum retro_key)key]);
|
||||
return x11->state[keycode >> 3] & (1 << (keycode & 7));
|
||||
}
|
||||
|
||||
static bool x_mbutton_pressed(x11_input_t *x11, unsigned port, unsigned key)
|
||||
{
|
||||
bool result;
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
if (port >= MAX_USERS)
|
||||
return false;
|
||||
|
||||
/* the driver only supports one mouse */
|
||||
if ( settings->uints.input_mouse_index[ port ] != 0 )
|
||||
return false;
|
||||
|
||||
switch ( key )
|
||||
{
|
||||
|
||||
case RETRO_DEVICE_ID_MOUSE_LEFT:
|
||||
return x11->mouse_l;
|
||||
case RETRO_DEVICE_ID_MOUSE_RIGHT:
|
||||
return x11->mouse_r;
|
||||
case RETRO_DEVICE_ID_MOUSE_MIDDLE:
|
||||
return x11->mouse_m;
|
||||
/* case RETRO_DEVICE_ID_MOUSE_BUTTON_4:
|
||||
return x11->mouse_b4;*/
|
||||
/* case RETRO_DEVICE_ID_MOUSE_BUTTON_5:
|
||||
return x11->mouse_b5;*/
|
||||
|
||||
case RETRO_DEVICE_ID_MOUSE_WHEELUP:
|
||||
case RETRO_DEVICE_ID_MOUSE_WHEELDOWN:
|
||||
return x_mouse_state_wheel( key );
|
||||
|
||||
/* case RETRO_DEVICE_ID_MOUSE_HORIZ_WHEELUP:
|
||||
result = x11->mouse_hwu;
|
||||
x11->mouse_hwu = false;
|
||||
return result;
|
||||
|
||||
case RETRO_DEVICE_ID_MOUSE_HORIZ_WHEELDOWN:
|
||||
result = x11->mouse_hwd;
|
||||
x11->mouse_hwd = false;
|
||||
return result;
|
||||
*/
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool x_is_pressed(x11_input_t *x11,
|
||||
rarch_joypad_info_t joypad_info,
|
||||
const struct retro_keybind *binds,
|
||||
unsigned port, unsigned id)
|
||||
{
|
||||
const struct retro_keybind *bind = &binds[id];
|
||||
|
||||
if ( (bind->key < RETROK_LAST) && x_keyboard_pressed(x11, bind->key) )
|
||||
return true;
|
||||
|
||||
if (binds && binds[id].valid)
|
||||
{
|
||||
if (x_mbutton_pressed(x11, port, bind->mbutton))
|
||||
return true;
|
||||
if (input_joypad_pressed(x11->joypad, joypad_info, port, binds, id))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int16_t x_pressed_analog(x11_input_t *x11,
|
||||
const struct retro_keybind *binds, unsigned idx, unsigned id)
|
||||
{
|
||||
@ -111,6 +184,44 @@ static bool x_input_meta_key_pressed(void *data, int key)
|
||||
return false;
|
||||
}
|
||||
|
||||
static int16_t x_lightgun_aiming_state( x11_input_t *x11, unsigned idx, unsigned id )
|
||||
{
|
||||
const int edge_detect = 32700;
|
||||
struct video_viewport vp;
|
||||
bool inside = false;
|
||||
int16_t res_x = 0;
|
||||
int16_t res_y = 0;
|
||||
int16_t res_screen_x = 0;
|
||||
int16_t res_screen_y = 0;
|
||||
|
||||
vp.x = 0;
|
||||
vp.y = 0;
|
||||
vp.width = 0;
|
||||
vp.height = 0;
|
||||
vp.full_width = 0;
|
||||
vp.full_height = 0;
|
||||
|
||||
if (!(video_driver_translate_coord_viewport_wrap(&vp, x11->mouse_x, x11->mouse_y,
|
||||
&res_x, &res_y, &res_screen_x, &res_screen_y)))
|
||||
return 0;
|
||||
|
||||
inside = (res_x >= -edge_detect) && (res_y >= -edge_detect) && (res_x <= edge_detect) && (res_y <= edge_detect);
|
||||
|
||||
switch ( id )
|
||||
{
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X:
|
||||
return inside ? res_x : 0;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y:
|
||||
return inside ? res_y : 0;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN:
|
||||
return !inside;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int16_t x_mouse_state(x11_input_t *x11, unsigned id)
|
||||
{
|
||||
switch (id)
|
||||
@ -193,29 +304,6 @@ static int16_t x_pointer_state(x11_input_t *x11,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int16_t x_lightgun_state(x11_input_t *x11, unsigned id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_X:
|
||||
return x11->mouse_x - x11->mouse_last_x;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_Y:
|
||||
return x11->mouse_y - x11->mouse_last_y;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_TRIGGER:
|
||||
return x11->mouse_l;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_CURSOR:
|
||||
return x11->mouse_m;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_TURBO:
|
||||
return x11->mouse_r;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_START:
|
||||
return x11->mouse_m && x11->mouse_r;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_PAUSE:
|
||||
return x11->mouse_m && x11->mouse_l;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int16_t x_input_state(void *data,
|
||||
rarch_joypad_info_t joypad_info,
|
||||
const struct retro_keybind **binds, unsigned port,
|
||||
@ -227,23 +315,11 @@ static int16_t x_input_state(void *data,
|
||||
switch (device)
|
||||
{
|
||||
case RETRO_DEVICE_JOYPAD:
|
||||
{
|
||||
int keycode = XKeysymToKeycode(x11->display,
|
||||
rarch_keysym_lut[(enum retro_key)binds[port][id].key]);
|
||||
ret = (binds[port][id].key < RETROK_LAST) && (x11->state[keycode >> 3] & (1 << (keycode & 7)));
|
||||
if (!ret)
|
||||
ret = input_joypad_pressed(x11->joypad,
|
||||
joypad_info, port, binds[port], id);
|
||||
}
|
||||
return ret;
|
||||
if (id < RARCH_BIND_LIST_END)
|
||||
return x_is_pressed(x11, joypad_info, binds[port], port, id);
|
||||
break;
|
||||
case RETRO_DEVICE_KEYBOARD:
|
||||
if (id < RETROK_LAST)
|
||||
{
|
||||
int keycode = XKeysymToKeycode(x11->display,
|
||||
rarch_keysym_lut[(enum retro_key)id]);
|
||||
ret = x11->state[keycode >> 3] & (1 << (keycode & 7));
|
||||
}
|
||||
return ret;
|
||||
return (id < RETROK_LAST) && x_keyboard_pressed(x11, id);
|
||||
case RETRO_DEVICE_ANALOG:
|
||||
ret = x_pressed_analog(x11, binds[port], idx, id);
|
||||
if (!ret && binds[port])
|
||||
@ -263,7 +339,48 @@ static int16_t x_input_state(void *data,
|
||||
device == RARCH_DEVICE_POINTER_SCREEN);
|
||||
break;
|
||||
case RETRO_DEVICE_LIGHTGUN:
|
||||
return x_lightgun_state(x11, id);
|
||||
switch ( id )
|
||||
{
|
||||
/*aiming*/
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X:
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y:
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN:
|
||||
return x_lightgun_aiming_state( x11, idx, id );
|
||||
|
||||
/*buttons*/
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_TRIGGER:
|
||||
return x_is_pressed(x11, joypad_info, binds[port], port, RARCH_LIGHTGUN_TRIGGER);
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_RELOAD:
|
||||
return x_is_pressed(x11, joypad_info, binds[port], port, RARCH_LIGHTGUN_RELOAD);
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_AUX_A:
|
||||
return x_is_pressed(x11, joypad_info, binds[port], port, RARCH_LIGHTGUN_AUX_A);
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_AUX_B:
|
||||
return x_is_pressed(x11, joypad_info, binds[port], port, RARCH_LIGHTGUN_AUX_B);
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_AUX_C:
|
||||
return x_is_pressed(x11, joypad_info, binds[port], port, RARCH_LIGHTGUN_AUX_C);
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_START:
|
||||
return x_is_pressed(x11, joypad_info, binds[port], port, RARCH_LIGHTGUN_START);
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_SELECT:
|
||||
return x_is_pressed(x11, joypad_info, binds[port], port, RARCH_LIGHTGUN_SELECT);
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_DPAD_UP:
|
||||
return x_is_pressed(x11, joypad_info, binds[port], port, RARCH_LIGHTGUN_DPAD_UP);
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_DPAD_DOWN:
|
||||
return x_is_pressed(x11, joypad_info, binds[port], port, RARCH_LIGHTGUN_DPAD_DOWN);
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_DPAD_LEFT:
|
||||
return x_is_pressed(x11, joypad_info, binds[port], port, RARCH_LIGHTGUN_DPAD_LEFT);
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_DPAD_RIGHT:
|
||||
return x_is_pressed(x11, joypad_info, binds[port], port, RARCH_LIGHTGUN_DPAD_RIGHT);
|
||||
|
||||
/*deprecated*/
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_X:
|
||||
return x11->mouse_x - x11->mouse_last_x;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_Y:
|
||||
return x11->mouse_y - x11->mouse_last_y;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_PAUSE:
|
||||
return x_is_pressed(x11, joypad_info, binds[port], port, RARCH_LIGHTGUN_START);
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -42,6 +42,7 @@ typedef struct libusb_hid
|
||||
libusb_context *ctx;
|
||||
joypad_connection_t *slots;
|
||||
sthread_t *poll_thread;
|
||||
int can_hotplug;
|
||||
#if defined(__FreeBSD__) && LIBUSB_API_VERSION <= 0x01000102
|
||||
libusb_hotplug_callback_handle hp;
|
||||
#else
|
||||
@ -523,7 +524,8 @@ static void libusb_hid_free(void *data)
|
||||
if (hid->slots)
|
||||
pad_connection_destroy(hid->slots);
|
||||
|
||||
libusb_hotplug_deregister_callback(hid->ctx, hid->hp);
|
||||
if (hid->can_hotplug)
|
||||
libusb_hotplug_deregister_callback(hid->ctx, hid->hp);
|
||||
|
||||
libusb_exit(hid->ctx);
|
||||
free(hid);
|
||||
@ -556,13 +558,21 @@ static void *libusb_hid_init(void)
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
#if 0
|
||||
/* Don't use this for now since it requires a newer API
|
||||
* version than FreeBSD has, and always returns false on Windows anyway.
|
||||
* https://github.com/libusb/libusb/issues/86
|
||||
#if LIBUSB_API_VERSION <= 0x01000102
|
||||
/* API is too old, so libusb_has_capability function does not exist.
|
||||
* Since we can't be sure, we assume for now there might be hot-plugging
|
||||
* capability and continue on until we're told otherwise.
|
||||
*/
|
||||
if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG))
|
||||
goto error;
|
||||
hid->can_hotplug = 1;
|
||||
#else
|
||||
/* Ask libusb if it supports hotplug and store the result.
|
||||
* Note: On Windows this will probably be false, see:
|
||||
* https://github.com/libusb/libusb/issues/86
|
||||
*/
|
||||
if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG))
|
||||
hid->can_hotplug = 1;
|
||||
else
|
||||
hid->can_hotplug = 0;
|
||||
#endif
|
||||
|
||||
hid->slots = pad_connection_init(MAX_USERS);
|
||||
@ -584,22 +594,29 @@ static void *libusb_hid_init(void)
|
||||
if (count > 0)
|
||||
libusb_free_device_list(devices, 1);
|
||||
|
||||
ret = libusb_hotplug_register_callback(
|
||||
hid->ctx,
|
||||
(libusb_hotplug_event)(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED |
|
||||
LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT),
|
||||
(libusb_hotplug_flag)LIBUSB_HOTPLUG_ENUMERATE,
|
||||
LIBUSB_HOTPLUG_MATCH_ANY,
|
||||
LIBUSB_HOTPLUG_MATCH_ANY,
|
||||
LIBUSB_HOTPLUG_MATCH_ANY,
|
||||
libusb_hid_hotplug_callback,
|
||||
hid,
|
||||
&hid->hp);
|
||||
|
||||
if (ret != LIBUSB_SUCCESS)
|
||||
if (hid->can_hotplug)
|
||||
{
|
||||
RARCH_ERR("Error creating a hotplug callback.\n");
|
||||
goto error;
|
||||
ret = libusb_hotplug_register_callback(
|
||||
hid->ctx,
|
||||
(libusb_hotplug_event)(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED |
|
||||
LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT),
|
||||
(libusb_hotplug_flag)LIBUSB_HOTPLUG_ENUMERATE,
|
||||
LIBUSB_HOTPLUG_MATCH_ANY,
|
||||
LIBUSB_HOTPLUG_MATCH_ANY,
|
||||
LIBUSB_HOTPLUG_MATCH_ANY,
|
||||
libusb_hid_hotplug_callback,
|
||||
hid,
|
||||
&hid->hp);
|
||||
|
||||
if (ret != LIBUSB_SUCCESS)
|
||||
{
|
||||
/* Creating the hotplug callback has failed. We assume libusb
|
||||
* is still okay to continue and just update our knowledge of
|
||||
* the situation accordingly.
|
||||
*/
|
||||
RARCH_WARN("[libusb] Failed to create a hotplug callback.\n");
|
||||
hid->can_hotplug = 0;
|
||||
}
|
||||
}
|
||||
|
||||
hid->poll_thread = sthread_create(poll_thread, hid);
|
||||
|
@ -21,7 +21,9 @@
|
||||
#include <wiiu/vpad.h>
|
||||
#include <wiiu/kpad.h>
|
||||
|
||||
#include "wiiu/controller_patcher/ControllerPatcherWrapper.h"
|
||||
#if defined(ENABLE_CONTROLLER_PATCHER)
|
||||
#include "wiiu/controller_patcher/ControllerPatcherWrapper.h"
|
||||
#endif
|
||||
|
||||
#include "../input_driver.h"
|
||||
|
||||
@ -33,8 +35,12 @@
|
||||
|
||||
#include "wiiu_dbg.h"
|
||||
|
||||
#ifndef MAX_PADS
|
||||
#define MAX_PADS 16
|
||||
#if !defined(MAX_PADS)
|
||||
#if defined(ENABLE_CONTROLLER_PATCHER)
|
||||
#define MAX_PADS 16
|
||||
#else
|
||||
#define MAX_PADS 5
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define WIIUINPUT_TYPE_WIIMOTE 0x00
|
||||
@ -45,22 +51,27 @@
|
||||
|
||||
#define GAMEPAD_COUNT 1
|
||||
#define KPAD_COUNT 4
|
||||
#define HID_COUNT (MAX_PADS - GAMEPAD_COUNT - KPAD_COUNT)
|
||||
#define GAMEPAD_OFFSET 0
|
||||
#define KPAD_OFFSET (GAMEPAD_OFFSET + GAMEPAD_COUNT)
|
||||
#define HID_OFFSET (KPAD_OFFSET + KPAD_COUNT)
|
||||
|
||||
#if defined(ENABLE_CONTROLLER_PATCHER)
|
||||
#define HID_COUNT (MAX_PADS - GAMEPAD_COUNT - KPAD_COUNT)
|
||||
#define HID_OFFSET (KPAD_OFFSET + KPAD_COUNT)
|
||||
#endif
|
||||
|
||||
static uint64_t pad_state[MAX_PADS];
|
||||
static uint8_t pad_type[KPAD_COUNT] = {WIIUINPUT_TYPE_NONE, WIIUINPUT_TYPE_NONE, WIIUINPUT_TYPE_NONE, WIIUINPUT_TYPE_NONE};
|
||||
|
||||
#if defined(ENABLE_CONTROLLER_PATCHER)
|
||||
static uint8_t hid_status[HID_COUNT];
|
||||
static InputData hid_data[HID_COUNT];
|
||||
static char hidName[HID_COUNT][255];
|
||||
#endif
|
||||
|
||||
/* 3 axis - one for touch/future IR support? */
|
||||
static int16_t analog_state[MAX_PADS][3][2];
|
||||
static bool wiiu_pad_inited = false;
|
||||
|
||||
static char hidName[HID_COUNT][255];
|
||||
|
||||
static const char* wiiu_joypad_name(unsigned pad)
|
||||
{
|
||||
if (pad > MAX_PADS) return "N/A";
|
||||
@ -91,12 +102,14 @@ static const char* wiiu_joypad_name(unsigned pad)
|
||||
}
|
||||
}
|
||||
|
||||
if (pad >= HID_OFFSET && pad < HID_OFFSET + HID_COUNT)
|
||||
{
|
||||
s32 hid_index = pad - HID_OFFSET;
|
||||
sprintf(hidName[hid_index], "HID %04X/%04X(%02X)", hid_data[hid_index].device_info.vidpid.vid, hid_data[hid_index].device_info.vidpid.pid, hid_data[hid_index].pad);
|
||||
return hidName[hid_index];
|
||||
}
|
||||
#if defined(ENABLE_CONTROLLER_PATCHER)
|
||||
if (pad >= HID_OFFSET && pad < HID_OFFSET + HID_COUNT)
|
||||
{
|
||||
s32 hid_index = pad - HID_OFFSET;
|
||||
sprintf(hidName[hid_index], "HID %04X/%04X(%02X)", hid_data[hid_index].device_info.vidpid.vid, hid_data[hid_index].device_info.vidpid.pid, hid_data[hid_index].pad);
|
||||
return hidName[hid_index];
|
||||
}
|
||||
#endif //defined(ENABLE_CONTROLLER_PATCHER)
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
@ -194,9 +207,12 @@ static int16_t scaleTP(int16_t oldMin, int16_t oldMax, int16_t newMin, int16_t n
|
||||
|
||||
static void wiiu_joypad_poll(void)
|
||||
{
|
||||
int i, c, result;
|
||||
int i, c;
|
||||
VPADStatus vpad;
|
||||
VPADReadError vpadError;
|
||||
#if defined(ENABLE_CONTROLLER_PATCHER)
|
||||
int result;
|
||||
#endif
|
||||
|
||||
VPADRead(0, &vpad, 1, &vpadError);
|
||||
|
||||
@ -311,41 +327,46 @@ static void wiiu_joypad_poll(void)
|
||||
}
|
||||
}
|
||||
|
||||
memset(hid_data,0,sizeof(hid_data));
|
||||
result = gettingInputAllDevices(hid_data,HID_COUNT);
|
||||
#if defined(ENABLE_CONTROLLER_PATCHER)
|
||||
memset(hid_data,0,sizeof(hid_data));
|
||||
result = gettingInputAllDevices(hid_data,HID_COUNT);
|
||||
|
||||
if (result + HID_OFFSET > MAX_PADS)
|
||||
result = MAX_PADS - HID_OFFSET;
|
||||
if (result + HID_OFFSET > MAX_PADS)
|
||||
result = MAX_PADS - HID_OFFSET;
|
||||
|
||||
for(i = HID_OFFSET;i < result + HID_OFFSET; i++)
|
||||
{
|
||||
int hid_index = i-HID_OFFSET;
|
||||
uint8_t old_status = hid_status[hid_index];
|
||||
uint8_t new_status = hid_data[hid_index].status;/* TODO: defines for the status. */
|
||||
|
||||
if (old_status == 1 || new_status == 1)
|
||||
for(i = HID_OFFSET;i < result + HID_OFFSET; i++)
|
||||
{
|
||||
hid_status[hid_index] = new_status;
|
||||
if (old_status == 0 && new_status == 1) /* Pad was attached */
|
||||
wiiu_joypad_autodetect_add(i);
|
||||
else if (old_status == 1 && new_status == 0) /* Pad was detached */
|
||||
input_autoconfigure_disconnect(i, wiiu_joypad.ident);
|
||||
else if (old_status == 1 && new_status == 1) /* Pad still connected */
|
||||
int hid_index = i-HID_OFFSET;
|
||||
uint8_t old_status = hid_status[hid_index];
|
||||
uint8_t new_status = hid_data[hid_index].status;/* TODO: defines for the status. */
|
||||
|
||||
if (old_status == 1 || new_status == 1)
|
||||
{
|
||||
pad_state[i] = hid_data[hid_index].button_data.hold & ~0x7F800000; /* clear out emulated analog sticks */
|
||||
analog_state[i][RETRO_DEVICE_INDEX_ANALOG_LEFT] [RETRO_DEVICE_ID_ANALOG_X] = hid_data[hid_index].stick_data.leftStickX * 0x7FF0;
|
||||
analog_state[i][RETRO_DEVICE_INDEX_ANALOG_LEFT] [RETRO_DEVICE_ID_ANALOG_Y] = hid_data[hid_index].stick_data.leftStickY * 0x7FF0;
|
||||
analog_state[i][RETRO_DEVICE_INDEX_ANALOG_RIGHT] [RETRO_DEVICE_ID_ANALOG_X] = hid_data[hid_index].stick_data.rightStickX * 0x7FF0;
|
||||
analog_state[i][RETRO_DEVICE_INDEX_ANALOG_RIGHT] [RETRO_DEVICE_ID_ANALOG_Y] = hid_data[hid_index].stick_data.rightStickY * 0x7FF0;
|
||||
hid_status[hid_index] = new_status;
|
||||
if (old_status == 0 && new_status == 1) /* Pad was attached */
|
||||
wiiu_joypad_autodetect_add(i);
|
||||
else if (old_status == 1 && new_status == 0) /* Pad was detached */
|
||||
input_autoconfigure_disconnect(i, wiiu_joypad.ident);
|
||||
else if (old_status == 1 && new_status == 1) /* Pad still connected */
|
||||
{
|
||||
pad_state[i] = hid_data[hid_index].button_data.hold & ~0x7F800000; /* clear out emulated analog sticks */
|
||||
analog_state[i][RETRO_DEVICE_INDEX_ANALOG_LEFT] [RETRO_DEVICE_ID_ANALOG_X] = hid_data[hid_index].stick_data.leftStickX * 0x7FF0;
|
||||
analog_state[i][RETRO_DEVICE_INDEX_ANALOG_LEFT] [RETRO_DEVICE_ID_ANALOG_Y] = hid_data[hid_index].stick_data.leftStickY * 0x7FF0;
|
||||
analog_state[i][RETRO_DEVICE_INDEX_ANALOG_RIGHT] [RETRO_DEVICE_ID_ANALOG_X] = hid_data[hid_index].stick_data.rightStickX * 0x7FF0;
|
||||
analog_state[i][RETRO_DEVICE_INDEX_ANALOG_RIGHT] [RETRO_DEVICE_ID_ANALOG_Y] = hid_data[hid_index].stick_data.rightStickY * 0x7FF0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif //defined(ENABLE_CONTROLLER_PATCHER)
|
||||
}
|
||||
|
||||
static bool wiiu_joypad_init(void* data)
|
||||
{
|
||||
wiiu_joypad_autodetect_add(0);
|
||||
memset(hid_status,0,sizeof(hid_status));
|
||||
|
||||
#if defined(ENABLE_CONTROLLER_PATCHER)
|
||||
memset(hid_status,0,sizeof(hid_status));
|
||||
#endif
|
||||
|
||||
wiiu_joypad_poll();
|
||||
wiiu_pad_inited = true;
|
||||
|
@ -42,6 +42,7 @@ const blissbox_pad_type_t blissbox_pad_types[] =
|
||||
{"A5200_TB", 50},
|
||||
{"A7800", 4},
|
||||
{"ATARI_KEYPAD", 43},
|
||||
{"ATARI", 0},
|
||||
{"ATMARK", 10},
|
||||
{"BALLY", 42},
|
||||
{"CD32", 24},
|
||||
|
@ -544,16 +544,16 @@ const char* const input_builtin_autoconfs[] =
|
||||
#endif
|
||||
#ifdef WIIU
|
||||
DECL_AUTOCONF_DEVICE("WIIU Gamepad", "wiiu", WIIUINPUT_GAMEPAD_DEFAULT_BINDS),
|
||||
DECL_AUTOCONF_DEVICE("HID Controller", "wiiu", WIIUINPUT_GAMEPAD_DEFAULT_BINDS),
|
||||
DECL_AUTOCONF_DEVICE("WIIU Pro Controller", "wiiu", WIIUINPUT_PRO_CONTROLLER_DEFAULT_BINDS),
|
||||
DECL_AUTOCONF_DEVICE("Wiimote Controller", "wiiu", WIIUINPUT_WIIMOTE_DEFAULT_BINDS),
|
||||
DECL_AUTOCONF_DEVICE("Nunchuk Controller", "wiiu", WIIUINPUT_NUNCHUK_DEFAULT_BINDS),
|
||||
DECL_AUTOCONF_DEVICE("Classic Controller", "wiiu", WIIUINPUT_CLASSIC_CONTROLLER_DEFAULT_BINDS),
|
||||
#if defined(ENABLE_CONTROLLER_PATCHER)
|
||||
DECL_AUTOCONF_DEVICE("HID Controller", "wiiu", WIIUINPUT_GAMEPAD_DEFAULT_BINDS),
|
||||
#endif
|
||||
#endif
|
||||
#ifdef __CELLOS_LV2__
|
||||
DECL_AUTOCONF_DEVICE("SixAxis Controller", "ps3", PS3INPUT_DEFAULT_BINDS),
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
|
@ -806,6 +806,9 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state)
|
||||
uint8_t port_max =
|
||||
settings->bools.input_all_users_control_menu
|
||||
? max_users : 1;
|
||||
|
||||
joypad_info.joy_idx = 0;
|
||||
joypad_info.auto_binds = NULL;
|
||||
|
||||
RARCH_INPUT_STATE_CLEAR_PTR( p_new_state );
|
||||
|
||||
|
@ -3292,8 +3292,8 @@ MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_OK,
|
||||
MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_NOK,
|
||||
"Password non corretta.")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST,
|
||||
"Automatically add content to playlist")
|
||||
"Aggiungi automaticamente il contenuto alla playlist")
|
||||
MSG_HASH(MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST,
|
||||
"Automatically scans loaded content so they appear inside playlists.")
|
||||
"Esegue automaticamente la scansione dei contenuti caricati in modo che vengano visualizzati all'interno delle playlist.")
|
||||
MSG_HASH(MSG_SCANNING_OF_FILE_FINISHED,
|
||||
"Scanning of file finished")
|
||||
"Scansione del file completata")
|
||||
|
@ -2542,6 +2542,8 @@ MSG_HASH(
|
||||
)
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_BOKEH,
|
||||
"Bokeh")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SNOWFLAKE,
|
||||
"Snowflake")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_REFRESH_ROOMS,
|
||||
"Refresh Room List")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ROOM_NICKNAME,
|
||||
|
32
libretro-common/compat/fopen_utf8.c
Normal file
32
libretro-common/compat/fopen_utf8.c
Normal file
@ -0,0 +1,32 @@
|
||||
#include <compat/fopen_utf8.h>
|
||||
#include <encodings/utf.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1400 || defined(_XBOX)
|
||||
#ifndef LEGACY_WIN32
|
||||
#define LEGACY_WIN32
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#undef fopen
|
||||
|
||||
FILE* fopen_utf8(const char * filename, const char * mode)
|
||||
{
|
||||
#if defined(_XBOX)
|
||||
return fopen(filename, mode);
|
||||
#elif defined(LEGACY_WIN32)
|
||||
char * filename_local = utf8_to_local_string_alloc(path);
|
||||
FILE* ret = fopen(filename_local, mode);
|
||||
free(filename_local);
|
||||
return ret;
|
||||
#else
|
||||
wchar_t * filename_w = utf8_to_utf16_string_alloc(filename);
|
||||
wchar_t * mode_w = utf8_to_utf16_string_alloc(mode);
|
||||
FILE* ret = _wfopen(filename_w, mode_w);
|
||||
free(filename_w);
|
||||
free(mode_w);
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
#endif
|
@ -38,6 +38,7 @@
|
||||
#include <retro_miscellaneous.h>
|
||||
#include <compat/strl.h>
|
||||
#include <compat/posix_string.h>
|
||||
#include <compat/fopen_utf8.h>
|
||||
#include <compat/msvc.h>
|
||||
#include <file/config_file.h>
|
||||
#include <file/file_path.h>
|
||||
@ -912,21 +913,26 @@ void config_set_bool(config_file_t *conf, const char *key, bool val)
|
||||
|
||||
bool config_file_write(config_file_t *conf, const char *path)
|
||||
{
|
||||
RFILE *file = NULL;
|
||||
|
||||
if (!string_is_empty(path))
|
||||
{
|
||||
file = filestream_open(path, RFILE_MODE_WRITE, 0x4000);
|
||||
void* buf = NULL;
|
||||
FILE *file = fopen_utf8(path, "wb");
|
||||
if (!file)
|
||||
return false;
|
||||
config_file_dump(conf, filestream_get_fp(file));
|
||||
|
||||
/* TODO: this is only useful for a few platforms, find which and add ifdef */
|
||||
buf = calloc(1, 0x4000);
|
||||
setvbuf(file, (char*)buf, _IOFBF, 0x4000);
|
||||
|
||||
config_file_dump(conf, file);
|
||||
|
||||
if (file != stdout)
|
||||
fclose(file);
|
||||
free(buf);
|
||||
}
|
||||
else
|
||||
config_file_dump(conf, stdout);
|
||||
|
||||
if (file)
|
||||
filestream_close(file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -20,13 +20,17 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <file/nbio.h>
|
||||
|
||||
#if defined(HAVE_MMAP) && defined(BSD)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
#else
|
||||
@ -35,6 +39,20 @@
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
#ifndef O_CLOEXEC
|
||||
#define O_CLOEXEC 0x1000000
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#ifndef O_CLOEXEC
|
||||
#define O_CLOEXEC 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
struct nbio_mmap_unix_t
|
||||
{
|
||||
int fd;
|
||||
|
@ -179,16 +179,13 @@ bool gl_check_capability(enum gl_capability_enum enum_idx)
|
||||
&& !gl_query_extension("EXT_framebuffer_object"))
|
||||
return false;
|
||||
|
||||
if (glGenFramebuffers
|
||||
&& glBindFramebuffer
|
||||
&& glFramebufferTexture2D
|
||||
&& glCheckFramebufferStatus
|
||||
&& glDeleteFramebuffers
|
||||
&& glGenRenderbuffers
|
||||
&& glBindRenderbuffer
|
||||
&& glFramebufferRenderbuffer
|
||||
&& glRenderbufferStorage
|
||||
&& glDeleteRenderbuffers)
|
||||
if (gl_query_extension("ARB_framebuffer_object"))
|
||||
return true;
|
||||
|
||||
if (gl_query_extension("EXT_framebuffer_object"))
|
||||
return true;
|
||||
|
||||
if (major >= 3)
|
||||
return true;
|
||||
break;
|
||||
#endif
|
||||
|
14
libretro-common/include/compat/fopen_utf8.h
Normal file
14
libretro-common/include/compat/fopen_utf8.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef __FOPEN_UTF8_H
|
||||
#define __FOPEN_UTF8_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
/* defined to error rather than fopen_utf8, to make it clear to everyone reading the code that not worrying about utf16 is fine */
|
||||
/* TODO: enable */
|
||||
/* #define fopen (use fopen_utf8 instead) */
|
||||
FILE* fopen_utf8(const char * filename, const char * mode);
|
||||
#else
|
||||
#define fopen_utf8 fopen
|
||||
#endif
|
||||
#endif
|
@ -80,7 +80,7 @@
|
||||
#define BIT128_SET(a, bit) ((a).data[(bit) >> 5] |= (1 << ((bit) & 31)))
|
||||
#define BIT128_CLEAR(a, bit) ((a).data[(bit) >> 5] &= ~(1 << ((bit) & 31)))
|
||||
#define BIT128_GET(a, bit) ((a).data[(bit) >> 5] & (1 << ((bit) & 31)))
|
||||
#define BIT128_CLEAR_ALL(a) memset(&(a), 0, sizeof(a));
|
||||
#define BIT128_CLEAR_ALL(a) memset(&(a), 0, sizeof(a))
|
||||
|
||||
/* Helper macros and struct to keep track of many booleans.
|
||||
* To check for multiple bits, use &&, not &.
|
||||
|
@ -63,10 +63,9 @@ const char *filestream_get_ext(RFILE *stream);
|
||||
* @bufsize : optional buffer size (-1 or 0 to use default)
|
||||
*
|
||||
* Opens a file for reading or writing, depending on the requested mode.
|
||||
* If bufsize is > 0 for unbuffered modes (like RFILE_MODE_WRITE), file will instead be fully buffered.
|
||||
* Returns a pointer to an RFILE if opened successfully, otherwise NULL.
|
||||
**/
|
||||
RFILE *filestream_open(const char *path, unsigned mode, ssize_t bufsize);
|
||||
RFILE *filestream_open(const char *path, unsigned mode, ssize_t unused);
|
||||
|
||||
ssize_t filestream_seek(RFILE *stream, ssize_t offset, int whence);
|
||||
|
||||
@ -100,9 +99,10 @@ int filestream_printf(RFILE *stream, const char* format, ...);
|
||||
|
||||
int filestream_error(RFILE *stream);
|
||||
|
||||
/* DO NOT put these functions back, unless you want to deal with
|
||||
the UNAVOIDABLE REGRESSIONS on platforms using unexpected rfile backends
|
||||
int filestream_get_fd(RFILE *stream);
|
||||
|
||||
FILE* filestream_get_fp(RFILE *stream);
|
||||
FILE* filestream_get_fp(RFILE *stream); */
|
||||
|
||||
int filestream_flush(RFILE *stream);
|
||||
|
||||
|
@ -114,24 +114,6 @@ struct RFILE
|
||||
char *buf;
|
||||
};
|
||||
|
||||
FILE* filestream_get_fp(RFILE *stream)
|
||||
{
|
||||
if (!stream)
|
||||
return NULL;
|
||||
return stream->fp;
|
||||
}
|
||||
|
||||
int filestream_get_fd(RFILE *stream)
|
||||
{
|
||||
if (!stream)
|
||||
return -1;
|
||||
#if defined(HAVE_BUFFERED_IO)
|
||||
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
|
||||
return fileno(stream->fp);
|
||||
#endif
|
||||
return stream->fd;
|
||||
}
|
||||
|
||||
const char *filestream_get_ext(RFILE *stream)
|
||||
{
|
||||
if (!stream)
|
||||
@ -166,12 +148,10 @@ void filestream_set_size(RFILE *stream)
|
||||
* @bufsize : optional buffer size (-1 or 0 to use default)
|
||||
*
|
||||
* Opens a file for reading or writing, depending on the requested mode.
|
||||
* If bufsize is > 0 for unbuffered modes (like RFILE_MODE_WRITE), file will instead be fully buffered.
|
||||
* Returns a pointer to an RFILE if opened successfully, otherwise NULL.
|
||||
**/
|
||||
RFILE *filestream_open(const char *path, unsigned mode, ssize_t unused)
|
||||
{
|
||||
ssize_t bufsize = 0x4000;
|
||||
int flags = 0;
|
||||
int mode_int = 0;
|
||||
#if defined(HAVE_BUFFERED_IO)
|
||||
@ -271,7 +251,7 @@ RFILE *filestream_open(const char *path, unsigned mode, ssize_t unused)
|
||||
#if defined(PSP)
|
||||
stream->fd = sceIoOpen(path, flags, mode_int);
|
||||
|
||||
if (stream->fd == -1)
|
||||
if (stream->fd < 0)
|
||||
goto error;
|
||||
#else
|
||||
#if defined(HAVE_BUFFERED_IO)
|
||||
@ -298,20 +278,18 @@ RFILE *filestream_open(const char *path, unsigned mode, ssize_t unused)
|
||||
if (!stream->fp)
|
||||
goto error;
|
||||
|
||||
if (bufsize > 0)
|
||||
{
|
||||
/* Regarding setvbuf:
|
||||
*
|
||||
* https://www.freebsd.org/cgi/man.cgi?query=setvbuf&apropos=0&sektion=0&manpath=FreeBSD+11.1-RELEASE&arch=default&format=html
|
||||
*
|
||||
* If the size argument is not zero but buf is NULL, a buffer of the given size will be allocated immediately, and
|
||||
* released on close. This is an extension to ANSI C.
|
||||
*
|
||||
* Since C89 does not support specifying a null buffer with a non-zero size, we create and track our own buffer for it.
|
||||
*/
|
||||
stream->buf = (char*)calloc(1, bufsize);
|
||||
setvbuf(stream->fp, stream->buf, _IOFBF, bufsize);
|
||||
}
|
||||
/* Regarding setvbuf:
|
||||
*
|
||||
* https://www.freebsd.org/cgi/man.cgi?query=setvbuf&apropos=0&sektion=0&manpath=FreeBSD+11.1-RELEASE&arch=default&format=html
|
||||
*
|
||||
* If the size argument is not zero but buf is NULL, a buffer of the given size will be allocated immediately, and
|
||||
* released on close. This is an extension to ANSI C.
|
||||
*
|
||||
* Since C89 does not support specifying a null buffer with a non-zero size, we create and track our own buffer for it.
|
||||
*/
|
||||
/* TODO: this is only useful for a few platforms, find which and add ifdef */
|
||||
stream->buf = (char*)calloc(1, 0x4000);
|
||||
setvbuf(stream->fp, stream->buf, _IOFBF, 0x4000);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
@ -247,6 +247,11 @@ static void menu_action_setting_disp_set_label_pipeline(
|
||||
msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_BOKEH), len);
|
||||
break;
|
||||
case XMB_SHADER_PIPELINE_SNOWFLAKE:
|
||||
strlcpy(s,
|
||||
msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SNOWFLAKE), len);
|
||||
break;
|
||||
}
|
||||
|
||||
strlcpy(s2, path, len2);
|
||||
|
@ -2759,6 +2759,9 @@ static void xmb_draw_bg(
|
||||
case XMB_SHADER_PIPELINE_BOKEH:
|
||||
draw.pipeline.id = VIDEO_SHADER_MENU_5;
|
||||
break;
|
||||
case XMB_SHADER_PIPELINE_SNOWFLAKE:
|
||||
draw.pipeline.id = VIDEO_SHADER_MENU_6;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -185,6 +185,7 @@ static void menu_display_gl_draw_pipeline(void *data)
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
case VIDEO_SHADER_MENU_6:
|
||||
shader_info.data = NULL;
|
||||
shader_info.idx = draw->pipeline.id;
|
||||
shader_info.set_active = true;
|
||||
@ -215,6 +216,7 @@ static void menu_display_gl_draw_pipeline(void *data)
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
case VIDEO_SHADER_MENU_6:
|
||||
#ifndef HAVE_PSGL
|
||||
uniform_param.type = UNIFORM_2F;
|
||||
uniform_param.lookup.ident = "OutputSize";
|
||||
|
@ -4273,7 +4273,7 @@ bool menu_displaylist_process(menu_displaylist_info_t *info)
|
||||
MENU_SETTING_ACTION, 0, 0);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_NETWORKING) && defined(HAVE_NETWORKGAMEPAD) && defined(HAVE_NETWORKGAMEPAD_CORE)
|
||||
#if defined(HAVE_NETWORKING) && defined(HAVE_NETWORKGAMEPAD)
|
||||
menu_entries_append_enum(info->list,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_START_NET_RETROPAD),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_START_NET_RETROPAD),
|
||||
|
@ -260,6 +260,7 @@ enum xmb_shader_pipeline
|
||||
XMB_SHADER_PIPELINE_SIMPLE_SNOW,
|
||||
XMB_SHADER_PIPELINE_SNOW,
|
||||
XMB_SHADER_PIPELINE_BOKEH,
|
||||
XMB_SHADER_PIPELINE_SNOWFLAKE,
|
||||
XMB_SHADER_PIPELINE_LAST
|
||||
};
|
||||
|
||||
|
@ -2263,7 +2263,7 @@ static bool setting_append_list(
|
||||
parent_group);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_NETWORKING) && defined(HAVE_NETWORKGAMEPAD) && defined(HAVE_NETWORKGAMEPAD_CORE)
|
||||
#if defined(HAVE_NETWORKING) && defined(HAVE_NETWORKGAMEPAD)
|
||||
CONFIG_ACTION(
|
||||
list, list_info,
|
||||
MENU_ENUM_LABEL_START_NET_RETROPAD,
|
||||
|
@ -447,6 +447,7 @@ enum msg_hash_enums
|
||||
MENU_LABEL(SHADER_PIPELINE_SIMPLE_SNOW),
|
||||
MENU_LABEL(SHADER_PIPELINE_SNOW),
|
||||
MENU_LABEL(SHADER_PIPELINE_BOKEH),
|
||||
MENU_LABEL(SHADER_PIPELINE_SNOWFLAKE),
|
||||
|
||||
MENU_LABEL(MATERIALUI_MENU_HEADER_OPACITY),
|
||||
MENU_LABEL(MATERIALUI_MENU_FOOTER_OPACITY),
|
||||
|
@ -381,7 +381,6 @@ void playlist_write_file(playlist_t *playlist)
|
||||
{
|
||||
size_t i;
|
||||
RFILE *file = NULL;
|
||||
FILE *fp = NULL;
|
||||
|
||||
if (!playlist || !playlist->modified)
|
||||
return;
|
||||
@ -394,10 +393,8 @@ void playlist_write_file(playlist_t *playlist)
|
||||
return;
|
||||
}
|
||||
|
||||
fp = filestream_get_fp(file);
|
||||
|
||||
for (i = 0; i < playlist->size; i++)
|
||||
fprintf(fp, "%s\n%s\n%s\n%s\n%s\n%s\n",
|
||||
filestream_printf(file, "%s\n%s\n%s\n%s\n%s\n%s\n",
|
||||
playlist->entries[i].path ? playlist->entries[i].path : "",
|
||||
playlist->entries[i].label ? playlist->entries[i].label : "",
|
||||
playlist->entries[i].core_path,
|
||||
|
@ -33,6 +33,26 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && !defined(_XBOX) && !defined(_MSC_VER) && _WIN32_WINNT >= 0x0500
|
||||
/* MinGW Win32 HID API */
|
||||
#include <minwindef.h>
|
||||
#include <wtypes.h>
|
||||
#include <tchar.h>
|
||||
#ifdef __NO_INLINE__
|
||||
/* Workaround MinGW issue where compiling without -O2 (which sets __NO_INLINE__) causes the strsafe functions
|
||||
* to never be defined (only declared).
|
||||
*/
|
||||
#define __CRT_STRSAFE_IMPL
|
||||
#endif
|
||||
#include <strsafe.h>
|
||||
#include <guiddef.h>
|
||||
#include <ks.h>
|
||||
#include <setupapi.h>
|
||||
#include <hidsdi.h>
|
||||
/* Why doesn't including cguid.h work to get a GUID_NULL instead? */
|
||||
const GUID GUID_NULL = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
|
||||
#endif
|
||||
|
||||
#include "../input/input_driver.h"
|
||||
#include "../input/include/blissbox.h"
|
||||
|
||||
@ -359,12 +379,258 @@ static void input_autoconfigure_params_free(autoconfig_params_t *params)
|
||||
params->autoconfig_directory = NULL;
|
||||
}
|
||||
|
||||
static const blissbox_pad_type_t* input_autoconfigure_get_blissbox_pad_type(int vid, int pid)
|
||||
#ifdef _WIN32
|
||||
static const blissbox_pad_type_t* input_autoconfigure_get_blissbox_pad_type_win32(int vid, int pid)
|
||||
{
|
||||
/* TODO: Remove the check for !defined(_MSC_VER) after making sure this builds on MSVC */
|
||||
|
||||
/* HID API is available since Windows 2000 */
|
||||
#if defined(_WIN32) && !defined(_XBOX) && !defined(_MSC_VER) && _WIN32_WINNT >= 0x0500
|
||||
HDEVINFO hDeviceInfo;
|
||||
SP_DEVINFO_DATA DeviceInfoData;
|
||||
SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
|
||||
HANDLE hDeviceHandle = INVALID_HANDLE_VALUE;
|
||||
BOOL bResult = TRUE;
|
||||
BOOL success = FALSE;
|
||||
GUID guidDeviceInterface = {0};
|
||||
PSP_DEVICE_INTERFACE_DETAIL_DATA
|
||||
pInterfaceDetailData = NULL;
|
||||
ULONG requiredLength = 0;
|
||||
LPTSTR lpDevicePath = NULL;
|
||||
char *devicePath = NULL;
|
||||
DWORD index = 0;
|
||||
DWORD intIndex = 0;
|
||||
size_t nLength = 0;
|
||||
unsigned len = 0;
|
||||
unsigned i = 0;
|
||||
char vidPidString[32] = {0};
|
||||
char vidString[5] = {0};
|
||||
char pidString[5] = {0};
|
||||
char report[USB_PACKET_CTRL_LEN + 1] = {0};
|
||||
|
||||
snprintf(vidString, sizeof(vidString), "%04x", vid);
|
||||
snprintf(pidString, sizeof(pidString), "%04x", pid);
|
||||
|
||||
strlcat(vidPidString, "vid_", sizeof(vidPidString));
|
||||
strlcat(vidPidString, vidString, sizeof(vidPidString));
|
||||
strlcat(vidPidString, "&pid_", sizeof(vidPidString));
|
||||
strlcat(vidPidString, pidString, sizeof(vidPidString));
|
||||
|
||||
HidD_GetHidGuid(&guidDeviceInterface);
|
||||
|
||||
if (!memcmp(&guidDeviceInterface, &GUID_NULL, sizeof(GUID_NULL)))
|
||||
{
|
||||
RARCH_ERR("[Autoconf]: null guid\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get information about all the installed devices for the specified
|
||||
* device interface class.
|
||||
*/
|
||||
hDeviceInfo = SetupDiGetClassDevs(
|
||||
&guidDeviceInterface,
|
||||
NULL,
|
||||
NULL,
|
||||
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
|
||||
|
||||
if (hDeviceInfo == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
RARCH_ERR("[Autoconf]: Error in SetupDiGetClassDevs: %d.\n", GetLastError());
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Enumerate all the device interfaces in the device information set. */
|
||||
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
|
||||
|
||||
while (!success)
|
||||
{
|
||||
success = SetupDiEnumDeviceInfo(hDeviceInfo, index, &DeviceInfoData);
|
||||
|
||||
/* Reset for this iteration */
|
||||
if (lpDevicePath)
|
||||
{
|
||||
LocalFree(lpDevicePath);
|
||||
lpDevicePath = NULL;
|
||||
}
|
||||
|
||||
if (pInterfaceDetailData)
|
||||
{
|
||||
LocalFree(pInterfaceDetailData);
|
||||
pInterfaceDetailData = NULL;
|
||||
}
|
||||
|
||||
/* Check if this is the last item */
|
||||
if (GetLastError() == ERROR_NO_MORE_ITEMS)
|
||||
break;
|
||||
|
||||
deviceInterfaceData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);
|
||||
|
||||
/* Get information about the device interface. */
|
||||
for (intIndex = 0; (bResult = SetupDiEnumDeviceInterfaces(
|
||||
hDeviceInfo,
|
||||
&DeviceInfoData,
|
||||
&guidDeviceInterface,
|
||||
intIndex,
|
||||
&deviceInterfaceData)); intIndex++)
|
||||
{
|
||||
/* Check if this is the last item */
|
||||
if (GetLastError() == ERROR_NO_MORE_ITEMS)
|
||||
break;
|
||||
|
||||
/* Check for some other error */
|
||||
if (!bResult)
|
||||
{
|
||||
RARCH_ERR("[Autoconf]: Error in SetupDiEnumDeviceInterfaces: %d.\n", GetLastError());
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Interface data is returned in SP_DEVICE_INTERFACE_DETAIL_DATA
|
||||
* which we need to allocate, so we have to call this function twice.
|
||||
* First to get the size so that we know how much to allocate, and
|
||||
* second to do the actual call with the allocated buffer.
|
||||
*/
|
||||
|
||||
bResult = SetupDiGetDeviceInterfaceDetail(
|
||||
hDeviceInfo,
|
||||
&deviceInterfaceData,
|
||||
NULL, 0,
|
||||
&requiredLength,
|
||||
NULL);
|
||||
|
||||
/* Check for some other error */
|
||||
if (!bResult)
|
||||
{
|
||||
if ((ERROR_INSUFFICIENT_BUFFER == GetLastError()) && (requiredLength > 0))
|
||||
{
|
||||
/* we got the size, now allocate buffer */
|
||||
pInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LPTR, requiredLength);
|
||||
|
||||
if (!pInterfaceDetailData)
|
||||
{
|
||||
RARCH_ERR("[Autoconf]: Error allocating memory for the device detail buffer.\n");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RARCH_ERR("[Autoconf]: Other error: %d.\n", GetLastError());
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* get the interface detailed data */
|
||||
pInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
|
||||
|
||||
/* Now call it with the correct size and allocated buffer */
|
||||
bResult = SetupDiGetDeviceInterfaceDetail(
|
||||
hDeviceInfo,
|
||||
&deviceInterfaceData,
|
||||
pInterfaceDetailData,
|
||||
requiredLength,
|
||||
NULL,
|
||||
&DeviceInfoData);
|
||||
|
||||
/* Check for some other error */
|
||||
if (!bResult)
|
||||
{
|
||||
RARCH_LOG("[Autoconf]: Error in SetupDiGetDeviceInterfaceDetail: %d.\n", GetLastError());
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* copy device path */
|
||||
nLength = _tcslen(pInterfaceDetailData->DevicePath) + 1;
|
||||
lpDevicePath = (TCHAR*)LocalAlloc(LPTR, nLength * sizeof(TCHAR));
|
||||
|
||||
StringCchCopy(lpDevicePath, nLength, pInterfaceDetailData->DevicePath);
|
||||
|
||||
devicePath = (char*)malloc(nLength);
|
||||
|
||||
for (len = 0; len < nLength; len++)
|
||||
devicePath[len] = lpDevicePath[len];
|
||||
|
||||
lpDevicePath[nLength - 1] = 0;
|
||||
|
||||
if (strstr(devicePath, vidPidString))
|
||||
goto found;
|
||||
}
|
||||
|
||||
success = FALSE;
|
||||
index++;
|
||||
}
|
||||
|
||||
if (!lpDevicePath)
|
||||
{
|
||||
RARCH_ERR("[Autoconf]: No devicepath. Error %d.", GetLastError());
|
||||
goto done;
|
||||
}
|
||||
|
||||
found:
|
||||
/* Open the device */
|
||||
hDeviceHandle = CreateFileA(
|
||||
devicePath,
|
||||
GENERIC_READ, /* | GENERIC_WRITE,*/
|
||||
FILE_SHARE_READ, /* | FILE_SHARE_WRITE,*/
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
0, /*FILE_FLAG_OVERLAPPED,*/
|
||||
NULL);
|
||||
|
||||
if (hDeviceHandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
RARCH_ERR("[Autoconf]: Can't open device: %d.", GetLastError());
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
free(devicePath);
|
||||
LocalFree(lpDevicePath);
|
||||
LocalFree(pInterfaceDetailData);
|
||||
bResult = SetupDiDestroyDeviceInfoList(hDeviceInfo);
|
||||
|
||||
devicePath = NULL;
|
||||
lpDevicePath = NULL;
|
||||
pInterfaceDetailData = NULL;
|
||||
|
||||
if (!bResult)
|
||||
RARCH_ERR("[Autoconf]: Could not destroy device info list.\n");
|
||||
|
||||
if (!hDeviceHandle || hDeviceHandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
/* device is not connected */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
report[0] = BLISSBOX_USB_FEATURE_REPORT_ID;
|
||||
|
||||
HidD_GetFeature(hDeviceHandle, report, sizeof(report));
|
||||
|
||||
CloseHandle(hDeviceHandle);
|
||||
|
||||
for (i = 0; i < sizeof(blissbox_pad_types) / sizeof(blissbox_pad_types[0]); i++)
|
||||
{
|
||||
const blissbox_pad_type_t *pad = &blissbox_pad_types[i];
|
||||
|
||||
if (!pad || string_is_empty(pad->name))
|
||||
continue;
|
||||
|
||||
if (pad->index == report[0])
|
||||
return pad;
|
||||
}
|
||||
|
||||
RARCH_LOG("[Autoconf]: Could not find connected pad in Bliss-Box port#%d.\n", pid - BLISSBOX_PID);
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
static const blissbox_pad_type_t* input_autoconfigure_get_blissbox_pad_type_libusb(int vid, int pid)
|
||||
{
|
||||
#ifdef HAVE_LIBUSB
|
||||
unsigned char answer[USB_PACKET_CTRL_LEN] = {0};
|
||||
unsigned i;
|
||||
int ret = libusb_init(NULL);
|
||||
unsigned char answer[USB_PACKET_CTRL_LEN] = {0};
|
||||
int ret = libusb_init(NULL);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
@ -432,9 +698,24 @@ static const blissbox_pad_type_t* input_autoconfigure_get_blissbox_pad_type(int
|
||||
error:
|
||||
libusb_close(autoconfig_libusb_handle);
|
||||
libusb_exit(NULL);
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const blissbox_pad_type_t* input_autoconfigure_get_blissbox_pad_type(int vid, int pid)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
#if defined(_MSC_VER) || defined(_XBOX)
|
||||
/* no MSVC/XBOX support */
|
||||
return NULL;
|
||||
#else
|
||||
return NULL;
|
||||
/* MinGW */
|
||||
return input_autoconfigure_get_blissbox_pad_type_win32(vid, pid);
|
||||
#endif
|
||||
#else
|
||||
return input_autoconfigure_get_blissbox_pad_type_libusb(vid, pid);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -467,7 +748,7 @@ static void input_autoconfigure_override_handler(autoconfig_params_t *params)
|
||||
free(params->name);
|
||||
|
||||
/* override name given to autoconfig so it knows what kind of pad this is */
|
||||
strlcat(name, "Bliss-Box ", sizeof(name));
|
||||
strlcat(name, "Bliss-Box 4-Play ", sizeof(name));
|
||||
strlcat(name, pad->name, sizeof(name));
|
||||
|
||||
params->name = strdup(name);
|
||||
|
19
tools/ps3/ps3py/LICENSE
Normal file
19
tools/ps3/ps3py/LICENSE
Normal file
@ -0,0 +1,19 @@
|
||||
Copyright (c) 2011 PSL1GHT Development 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.
|
@ -1,3 +1,24 @@
|
||||
/* Copyright (c) 2011 PSL1GHT Development 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.
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
static PyObject *sha1_callback = NULL;
|
||||
@ -81,10 +102,10 @@ static PyObject *register_sha1_callback(PyObject *self, PyObject *args)
|
||||
PyErr_SetString(PyExc_TypeError, "parameter must be callable");
|
||||
return NULL;
|
||||
}
|
||||
Py_XINCREF(temp); /* Add a reference to new callback */
|
||||
Py_XINCREF(temp); /* Add a reference to new callback */
|
||||
Py_XDECREF(sha1_callback); /* Dispose of previous callback */
|
||||
sha1_callback = temp; /* Remember new callback */
|
||||
/* Boilerplate to return "None" */
|
||||
/* Boilerplate to return "None" */
|
||||
Py_INCREF(Py_None);
|
||||
result = Py_None;
|
||||
}
|
||||
|
17
verbosity.c
17
verbosity.c
@ -35,6 +35,7 @@
|
||||
|
||||
#include <string/stdstring.h>
|
||||
#include <streams/file_stream.h>
|
||||
#include <compat/fopen_utf8.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
@ -49,8 +50,8 @@
|
||||
|
||||
/* If this is non-NULL. RARCH_LOG and friends
|
||||
* will write to this file. */
|
||||
static RFILE *log_file = NULL;
|
||||
static FILE *log_file_fp = NULL;
|
||||
static void* log_file_buf = NULL;
|
||||
static bool main_verbosity = false;
|
||||
static bool log_file_initialized = false;
|
||||
|
||||
@ -96,17 +97,21 @@ void retro_main_log_file_init(const char *path)
|
||||
if (path == NULL)
|
||||
return;
|
||||
|
||||
log_file = filestream_open(path, RFILE_MODE_WRITE, -1);
|
||||
log_file_fp = filestream_get_fp(log_file);
|
||||
log_file_fp = fopen_utf8(path, "wb");
|
||||
log_file_initialized = true;
|
||||
|
||||
/* TODO: this is only useful for a few platforms, find which and add ifdef */
|
||||
log_file_buf = calloc(1, 0x4000);
|
||||
setvbuf(log_file_fp, (char*)log_file_buf, _IOFBF, 0x4000);
|
||||
}
|
||||
|
||||
void retro_main_log_file_deinit(void)
|
||||
{
|
||||
if (log_file && log_file_fp != stderr)
|
||||
filestream_close(log_file);
|
||||
log_file = NULL;
|
||||
if (log_file_fp && log_file_fp != stderr)
|
||||
fclose(log_file_fp);
|
||||
if (log_file_buf) free(log_file_buf);
|
||||
log_file_fp = NULL;
|
||||
log_file_buf = NULL;
|
||||
}
|
||||
|
||||
#if !defined(HAVE_LOGGER)
|
||||
|
@ -90,8 +90,7 @@ void __attribute__((__noreturn__)) exception_cb(OSContext* ctx, OSExceptionType
|
||||
|
||||
/* First up, the pretty header that tells you wtf just happened */
|
||||
if (type == OS_EXCEPTION_TYPE_DSI) {
|
||||
/* Exception type and offending instruction location
|
||||
Also initializes exception_msgbuf, use buf_add from now on */
|
||||
/* Exception type and offending instruction location */
|
||||
buf_add("DSI: Instr at %08" PRIX32, ctx->srr0);
|
||||
/* Was this a read or a write? */
|
||||
if (ctx->dsisr & DSISR_WRITE_ATTEMPTED) {
|
||||
@ -216,6 +215,12 @@ void exception_print_symbol(uint32_t addr) {
|
||||
/* Try for a base address */
|
||||
void* libAddr;
|
||||
OSDynLoad_Acquire(symbolName, &libAddr);
|
||||
/* Special case for coreinit; which has broken handles */
|
||||
if (!strcmp(symbolName, "coreinit.rpl")) {
|
||||
void* PPCExit_addr;
|
||||
OSDynLoad_FindExport(libAddr, 0, "__PPCExit", &PPCExit_addr);
|
||||
libAddr = PPCExit_addr - 0x180;
|
||||
}
|
||||
*seperator = '|';
|
||||
/* We got one! */
|
||||
if (libAddr) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user