Merge branch 'master' into cheevos_loaded

This commit is contained in:
leiradel 2017-12-04 20:23:02 +00:00
commit d27e6746a1
51 changed files with 1625 additions and 669 deletions

28
.vscode/launch.json vendored Normal file
View 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
View 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
View 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"
]
}
}
}
]
}

View File

@ -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)

View File

@ -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),)

View File

@ -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);

View File

@ -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
{

View File

@ -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);

View File

@ -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);

View File

@ -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)
{

View File

@ -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;

View File

@ -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)

View File

@ -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);
}

View 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));
}
);

View File

@ -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

View File

@ -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",
};

View File

@ -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",
};

View File

@ -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);

View File

@ -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"

View File

@ -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;

View File

@ -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"
/*============================================================

View File

@ -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))
{

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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},

View File

@ -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
};

View File

@ -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 );

View File

@ -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")

View File

@ -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,

View 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

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View 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

View File

@ -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 &.

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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;
}

View File

@ -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";

View File

@ -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),

View File

@ -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
};

View File

@ -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,

View File

@ -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),

View File

@ -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,

View File

@ -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
View 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.

View File

@ -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;
}

View File

@ -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)

View File

@ -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) {