RetroArch/gfx/drivers/sdl_gfx.c

596 lines
15 KiB
C
Raw Normal View History

2012-04-21 23:13:50 +02:00
/* RetroArch - A frontend for libretro.
2014-01-01 01:50:59 +01:00
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
2017-01-22 13:40:32 +01:00
* Copyright (C) 2011-2017 - Daniel De Matteis
* Copyright (C) 2011-2017 - Higor Euripedes
2011-04-21 03:23:44 +02:00
*
2012-04-21 23:13:50 +02:00
* RetroArch is free software: you can redistribute it and/or modify it under the terms
2011-04-21 03:23:44 +02:00
* 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.
*
2012-04-21 23:13:50 +02:00
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
2011-04-21 03:23:44 +02:00
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
2012-04-21 23:31:57 +02:00
* You should have received a copy of the GNU General Public License along with RetroArch.
2011-04-21 03:23:44 +02:00
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
2015-11-22 13:32:46 +01:00
2016-02-13 04:49:42 +01:00
#include <retro_assert.h>
2015-11-22 13:32:46 +01:00
#include <gfx/scaler/scaler.h>
2016-11-08 15:35:24 +01:00
#include <gfx/video_frame.h>
2016-02-16 20:24:00 +01:00
#include <retro_assert.h>
2016-09-11 16:10:41 +02:00
#include "../../verbosity.h"
2015-11-22 13:32:46 +01:00
2016-09-11 14:46:53 +02:00
#ifdef HAVE_CONFIG_H
#include "../../config.h"
#endif
#ifdef HAVE_MENU
#include "../../menu/menu_driver.h"
#endif
2016-09-11 14:46:53 +02:00
#ifdef HAVE_X11
#include "../common/x11_common.h"
#endif
2015-11-22 13:32:46 +01:00
#include "SDL.h"
2016-09-11 14:46:53 +02:00
#include "SDL_syswm.h"
2015-11-22 13:32:46 +01:00
2017-01-19 17:20:42 +01:00
#include "../font_driver.h"
2016-09-05 18:31:32 +02:00
#include "../../configuration.h"
#include "../../retroarch.h"
2016-05-04 16:56:16 +02:00
typedef struct sdl_menu_frame
{
bool active;
struct scaler_ctx scaler;
2020-03-07 19:54:58 +01:00
SDL_Surface *frame;
} sdl_menu_frame_t;
2011-12-24 13:46:12 +01:00
typedef struct sdl_video
2011-04-21 03:23:44 +02:00
{
bool quitting;
2011-09-06 18:32:40 +02:00
uint8_t font_r;
uint8_t font_g;
uint8_t font_b;
struct scaler_ctx scaler;
sdl_menu_frame_t menu;
2020-03-07 18:05:50 +01:00
SDL_Surface *screen;
void *font;
const font_renderer_driver_t *font_driver;
2011-12-24 13:46:12 +01:00
} sdl_video_t;
2011-04-21 03:23:44 +02:00
static void sdl_gfx_free(void *data)
{
2011-12-24 13:46:12 +01:00
sdl_video_t *vid = (sdl_video_t*)data;
2011-04-21 03:23:44 +02:00
if (!vid)
return;
if (vid->menu.frame)
SDL_FreeSurface(vid->menu.frame);
2011-04-22 03:13:09 +02:00
if (vid->font)
vid->font_driver->free(vid->font);
2011-04-22 03:13:09 +02:00
scaler_ctx_gen_reset(&vid->scaler);
2014-08-26 23:57:29 -03:00
scaler_ctx_gen_reset(&vid->menu.scaler);
2011-04-21 03:23:44 +02:00
free(vid);
}
static void sdl_init_font(sdl_video_t *vid,
bool video_font_enable,
const char *path_font,
float video_font_size,
float msg_color_r,
float msg_color_g,
float msg_color_b
)
2011-04-22 03:13:09 +02:00
{
2015-01-22 00:32:24 +01:00
int r, g, b;
2015-03-20 22:08:36 +01:00
if (!video_font_enable)
2011-11-10 00:15:41 +01:00
return;
2018-07-14 00:54:14 +02:00
if (!font_renderer_create_default(
&vid->font_driver, &vid->font,
*path_font ? path_font : NULL,
video_font_size))
2011-04-22 03:13:09 +02:00
{
2015-01-22 00:32:24 +01:00
RARCH_LOG("[SDL]: Could not initialize fonts.\n");
return;
}
2011-09-06 18:32:40 +02:00
r = msg_color_r * 255;
g = msg_color_g * 255;
b = msg_color_b * 255;
2011-09-06 18:32:40 +02:00
2015-01-22 00:32:24 +01:00
r = (r < 0) ? 0 : (r > 255 ? 255 : r);
g = (g < 0) ? 0 : (g > 255 ? 255 : g);
b = (b < 0) ? 0 : (b > 255 ? 255 : b);
vid->font_r = r;
vid->font_g = g;
vid->font_b = b;
2011-04-22 03:13:09 +02:00
}
static void sdl_render_msg(
sdl_video_t *vid,
SDL_Surface *buffer,
const char *msg,
unsigned width,
unsigned height,
const SDL_PixelFormat *fmt,
float msg_pos_x,
float msg_pos_y
)
2011-04-22 03:13:09 +02:00
{
2014-09-05 19:27:46 -04:00
int x, y, msg_base_x, msg_base_y;
2014-04-30 04:04:59 +02:00
unsigned rshift, gshift, bshift;
2015-03-20 22:08:36 +01:00
const struct font_atlas *atlas = NULL;
2014-04-30 04:04:59 +02:00
if (!vid->font)
return;
atlas = vid->font_driver->get_atlas(vid->font);
2011-04-22 03:13:09 +02:00
msg_base_x = msg_pos_x * width;
msg_base_y = (1.0f - msg_pos_y) * height;
2011-04-22 03:13:09 +02:00
rshift = fmt->Rshift;
gshift = fmt->Gshift;
bshift = fmt->Bshift;
2014-06-08 13:01:55 +02:00
for (; *msg; msg++)
2011-04-22 03:13:09 +02:00
{
2016-03-20 05:24:05 +01:00
int glyph_width, glyph_height;
int base_x, base_y, max_width, max_height;
uint32_t *out = NULL;
const uint8_t *src = NULL;
2014-06-08 13:01:55 +02:00
const struct font_glyph *glyph = vid->font_driver->get_glyph(vid->font, (uint8_t)*msg);
if (!glyph)
continue;
2014-04-30 04:04:59 +02:00
2016-03-20 05:24:05 +01:00
glyph_width = glyph->width;
glyph_height = glyph->height;
base_x = msg_base_x + glyph->draw_offset_x;
base_y = msg_base_y + glyph->draw_offset_y;
src = atlas->buffer + glyph->atlas_offset_x
2016-03-20 05:24:05 +01:00
+ glyph->atlas_offset_y * atlas->width;
if (base_x < 0)
{
src -= base_x;
glyph_width += base_x;
base_x = 0;
}
if (base_y < 0)
{
src -= base_y * (int)atlas->width;
glyph_height += base_y;
base_y = 0;
}
2016-03-20 05:24:05 +01:00
max_width = width - base_x;
max_height = height - base_y;
if (max_width <= 0 || max_height <= 0)
continue;
if (glyph_width > max_width)
glyph_width = max_width;
if (glyph_height > max_height)
glyph_height = max_height;
out = (uint32_t*)buffer->pixels + base_y
* (buffer->pitch >> 2) + base_x;
2014-06-08 13:01:55 +02:00
for (y = 0; y < glyph_height; y++, src += atlas->width, out += buffer->pitch >> 2)
2011-04-22 03:13:09 +02:00
{
2013-10-22 21:26:33 +02:00
for (x = 0; x < glyph_width; x++)
2011-04-22 03:13:09 +02:00
{
unsigned blend = src[x];
unsigned out_pix = out[x];
unsigned r = (out_pix >> rshift) & 0xff;
unsigned g = (out_pix >> gshift) & 0xff;
unsigned b = (out_pix >> bshift) & 0xff;
unsigned out_r = (r * (256 - blend) + vid->font_r * blend) >> 8;
unsigned out_g = (g * (256 - blend) + vid->font_g * blend) >> 8;
unsigned out_b = (b * (256 - blend) + vid->font_b * blend) >> 8;
out[x] = (out_r << rshift) |
(out_g << gshift) |
(out_b << bshift);
2011-04-22 03:13:09 +02:00
}
}
2014-06-08 13:01:55 +02:00
msg_base_x += glyph->advance_x;
msg_base_y += glyph->advance_y;
}
2011-04-22 03:13:09 +02:00
}
2012-09-28 22:38:42 +02:00
static void sdl_gfx_set_handles(void)
{
2015-01-22 00:32:24 +01:00
/* SysWMinfo headers are broken on OSX. */
#if defined(_WIN32) || defined(HAVE_X11)
2012-09-28 22:38:42 +02:00
SDL_SysWMinfo info;
SDL_VERSION(&info.version);
2015-01-22 00:32:24 +01:00
if (SDL_GetWMInfo(&info) != 1)
return;
#if defined(_WIN32)
video_driver_display_type_set(RARCH_DISPLAY_WIN32);
video_driver_display_set(0);
video_driver_window_set((uintptr_t)info.window);
2012-09-28 22:38:42 +02:00
#elif defined(HAVE_X11)
video_driver_display_type_set(RARCH_DISPLAY_X11);
video_driver_display_set((uintptr_t)info.info.x11.display);
video_driver_window_set((uintptr_t)info.info.x11.window);
#endif
2012-09-28 22:38:42 +02:00
#endif
}
static void *sdl_gfx_init(const video_info_t *video,
input_driver_t **input, void **input_data)
2011-04-21 03:23:44 +02:00
{
2015-01-22 00:32:24 +01:00
unsigned full_x, full_y;
const SDL_VideoInfo *video_info = NULL;
sdl_video_t *vid = NULL;
settings_t *settings = config_get_ptr();
2021-03-23 12:46:25 +00:00
uint32_t sdl_subsystem_flags = SDL_WasInit(0);
const char *path_font = settings->paths.path_font;
float video_font_size = settings->floats.video_font_size;
2020-02-21 07:34:53 +01:00
bool video_font_enable = settings->bools.video_font_enable;
float msg_color_r = settings->floats.video_msg_color_r;
float msg_color_g = settings->floats.video_msg_color_g;
float msg_color_b = settings->floats.video_msg_color_b;
2015-03-20 22:08:36 +01:00
#ifdef HAVE_X11
XInitThreads();
#endif
2021-03-23 12:46:25 +00:00
/* Initialise graphics subsystem, if required */
if (sdl_subsystem_flags == 0)
2014-08-26 23:53:22 -03:00
{
if (SDL_Init(SDL_INIT_VIDEO) < 0)
return NULL;
}
2021-03-23 12:46:25 +00:00
else if ((sdl_subsystem_flags & SDL_INIT_VIDEO) == 0)
{
if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
return NULL;
}
2011-04-21 03:23:44 +02:00
2015-01-22 00:32:24 +01:00
vid = (sdl_video_t*)calloc(1, sizeof(*vid));
2011-04-21 03:23:44 +02:00
if (!vid)
return NULL;
video_info = SDL_GetVideoInfo();
retro_assert(video_info);
2015-01-22 00:32:24 +01:00
full_x = video_info->current_w;
full_y = video_info->current_h;
2014-08-26 23:53:22 -03:00
RARCH_LOG("[SDL]: Detecting desktop resolution %ux%u.\n", full_x, full_y);
2011-12-24 13:46:12 +01:00
if (!video->fullscreen)
2014-08-26 23:53:22 -03:00
RARCH_LOG("[SDL]: Creating window @ %ux%u\n", video->width, video->height);
vid->screen = SDL_SetVideoMode(video->width, video->height, 32,
SDL_HWSURFACE | SDL_HWACCEL | SDL_DOUBLEBUF | (video->fullscreen ? SDL_FULLSCREEN : 0));
2011-04-23 18:06:48 +02:00
2015-01-22 00:32:24 +01:00
/* We assume that SDL chooses ARGB8888.
* Assuming this simplifies the driver *a ton*.
*/
2012-11-20 23:35:40 +01:00
2011-04-21 03:23:44 +02:00
if (!vid->screen)
{
2017-03-24 01:33:22 +01:00
RARCH_ERR("[SDL1]: Failed to init SDL surface: %s\n", SDL_GetError());
2011-04-21 03:23:44 +02:00
goto error;
}
if (video->fullscreen)
SDL_ShowCursor(SDL_DISABLE);
2012-09-28 22:38:42 +02:00
sdl_gfx_set_handles();
if (input && input_data)
2011-04-21 03:23:44 +02:00
{
2020-08-30 05:29:32 +02:00
void *sdl_input = input_driver_init_wrap(&input_sdl,
settings->arrays.input_joypad_driver);
2015-01-22 00:32:24 +01:00
if (sdl_input)
{
*input = &input_sdl;
*input_data = sdl_input;
}
else
{
*input = NULL;
*input_data = NULL;
}
2011-12-14 16:37:31 +01:00
}
2011-04-21 03:23:44 +02:00
sdl_init_font(vid,
2020-02-21 07:34:53 +01:00
video_font_enable,
path_font, video_font_size,
2020-02-21 07:34:53 +01:00
msg_color_r,
msg_color_g,
msg_color_b);
2011-04-22 03:13:09 +02:00
vid->scaler.scaler_type = video->smooth ? SCALER_TYPE_BILINEAR : SCALER_TYPE_POINT;
vid->scaler.in_fmt = video->rgb32 ? SCALER_FMT_ARGB8888 : SCALER_FMT_RGB565;
vid->scaler.out_fmt = SCALER_FMT_ARGB8888;
vid->menu.scaler = vid->scaler;
vid->menu.scaler.scaler_type = SCALER_TYPE_BILINEAR;
vid->menu.frame = SDL_ConvertSurface(
vid->screen, vid->screen->format, vid->screen->flags | SDL_SRCALPHA);
if (!vid->menu.frame)
{
2017-03-24 01:33:22 +01:00
RARCH_ERR("[SDL1]: Failed to init menu surface: %s\n", SDL_GetError());
goto error;
}
2011-04-21 03:23:44 +02:00
return vid;
error:
sdl_gfx_free(vid);
return NULL;
}
2015-04-03 04:20:50 +02:00
static void sdl_gfx_check_window(sdl_video_t *vid)
{
SDL_Event event;
SDL_PumpEvents();
while (SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_QUITMASK))
{
2015-01-22 00:32:24 +01:00
if (event.type != SDL_QUIT)
continue;
vid->quitting = true;
break;
}
}
2014-08-26 23:53:22 -03:00
static bool sdl_gfx_frame(void *data, const void *frame, unsigned width,
2015-08-03 23:01:07 +02:00
unsigned height, uint64_t frame_count,
2017-01-18 17:41:27 +01:00
unsigned pitch, const char *msg, video_frame_info_t *video_info)
2011-04-21 03:23:44 +02:00
{
2017-01-19 17:51:22 +00:00
char title[128];
2020-05-19 16:20:43 +02:00
sdl_video_t *vid = (sdl_video_t*)data;
2020-08-03 16:33:54 +02:00
#ifdef HAVE_MENU
2020-05-19 16:20:43 +02:00
bool menu_is_alive = video_info->menu_is_alive;
2020-08-03 16:33:54 +02:00
#endif
if (!vid)
return true;
2017-01-19 17:51:22 +00:00
title[0] = '\0';
video_driver_get_window_title(title, sizeof(title));
2022-11-26 21:06:55 +01:00
if (vid->menu.active)
{
#ifdef HAVE_MENU
menu_driver_frame(menu_is_alive, video_info);
#endif
SDL_BlitSurface(vid->menu.frame, NULL, vid->screen, NULL);
2022-11-26 21:06:55 +01:00
}
else
{
if (SDL_MUSTLOCK(vid->screen))
2022-11-26 21:06:55 +01:00
SDL_LockSurface(vid->screen);
video_frame_scale(
&vid->scaler,
vid->screen->pixels,
frame,
vid->scaler.in_fmt,
vid->screen->w,
vid->screen->h,
vid->screen->pitch,
width,
height,
pitch);
if (SDL_MUSTLOCK(vid->screen))
SDL_UnlockSurface(vid->screen);
}
2011-04-21 03:23:44 +02:00
2017-01-19 17:51:22 +00:00
if (title[0])
SDL_WM_SetCaption(title, NULL);
2011-04-21 03:39:03 +02:00
SDL_Flip(vid->screen);
2011-04-21 03:23:44 +02:00
return true;
}
static void sdl_gfx_set_nonblock_state(void *a, bool b, bool c, unsigned d) { }
2011-04-21 03:23:44 +02:00
static bool sdl_gfx_alive(void *data)
{
2011-12-24 13:46:12 +01:00
sdl_video_t *vid = (sdl_video_t*)data;
2015-04-03 04:20:50 +02:00
sdl_gfx_check_window(vid);
2011-04-21 03:23:44 +02:00
return !vid->quitting;
}
static bool sdl_gfx_focus(void *data)
{
return (SDL_GetAppState() & (SDL_APPINPUTFOCUS | SDL_APPACTIVE)) == (SDL_APPINPUTFOCUS | SDL_APPACTIVE);
}
2015-01-18 22:32:14 +01:00
static bool sdl_gfx_suppress_screensaver(void *data, bool enable)
{
2015-09-29 17:35:28 +02:00
#ifdef HAVE_X11
if (video_driver_display_type_get() == RARCH_DISPLAY_X11)
2015-01-18 22:32:14 +01:00
{
x11_suspend_screensaver(video_driver_window_get(), enable);
2015-01-18 22:32:14 +01:00
return true;
}
#endif
return false;
}
2020-07-27 13:16:14 +02:00
/* TODO/FIXME - implement */
static bool sdl_gfx_has_windowed(void *data) { return true; }
2015-02-14 05:52:05 +01:00
static void sdl_gfx_viewport_info(void *data, struct video_viewport *vp)
{
sdl_video_t *vid = (sdl_video_t*)data;
vp->x = 0;
vp->y = 0;
2013-01-11 16:23:04 +01:00
vp->width = vp->full_width = vid->screen->w;
vp->height = vp->full_height = vid->screen->h;
}
static void sdl_set_filtering(void *data, unsigned index, bool smooth, bool ctx_scaling)
{
sdl_video_t *vid = (sdl_video_t*)data;
vid->scaler.scaler_type = smooth ? SCALER_TYPE_BILINEAR : SCALER_TYPE_POINT;
}
static void sdl_apply_state_changes(void *data)
{
(void)data;
}
static void sdl_set_texture_frame(void *data, const void *frame, bool rgb32,
2015-04-03 04:20:50 +02:00
unsigned width, unsigned height, float alpha)
{
enum scaler_pix_fmt format = rgb32
2016-05-04 16:56:16 +02:00
? SCALER_FMT_ARGB8888 : SCALER_FMT_RGBA4444;
sdl_video_t *vid = (sdl_video_t*)data;
video_frame_scale(
&vid->menu.scaler,
vid->menu.frame->pixels,
frame,
format,
vid->menu.frame->w,
vid->menu.frame->h,
vid->menu.frame->pitch,
width,
height,
width * (rgb32 ? sizeof(uint32_t) : sizeof(uint16_t))
);
SDL_SetAlpha(vid->menu.frame, SDL_SRCALPHA, 255.0 * alpha);
}
static void sdl_set_texture_enable(void *data, bool state, bool full_screen)
{
sdl_video_t *vid = (sdl_video_t*)data;
2015-04-03 04:20:50 +02:00
(void)full_screen;
vid->menu.active = state;
}
static void sdl_show_mouse(void *data, bool state)
{
(void)data;
2015-04-03 04:20:50 +02:00
SDL_ShowCursor(state);
}
static void sdl_grab_mouse_toggle(void *data)
{
const SDL_GrabMode mode = SDL_WM_GrabInput(SDL_GRAB_QUERY);
2015-04-03 04:20:50 +02:00
(void)data;
SDL_WM_GrabInput(mode == SDL_GRAB_ON ? SDL_GRAB_OFF : SDL_GRAB_ON);
}
static uint32_t sdl_get_flags(void *data)
{
uint32_t flags = 0;
BIT32_SET(flags, GFX_CTX_FLAGS_SCREENSHOTS_SUPPORTED);
return flags;
}
static const video_poke_interface_t sdl_poke_interface = {
sdl_get_flags,
NULL,
NULL,
NULL,
NULL, /* get_refresh_rate */
sdl_set_filtering,
NULL, /* get_video_output_size */
NULL, /* get_video_output_prev */
NULL, /* get_video_output_next */
2015-04-25 02:35:06 +02:00
NULL, /* get_current_framebuffer */
NULL, /* get_proc_address */
NULL,
sdl_apply_state_changes,
sdl_set_texture_frame,
2016-05-17 08:02:13 +02:00
sdl_set_texture_enable,
NULL,
sdl_show_mouse,
sdl_grab_mouse_toggle,
2018-01-30 22:29:57 +01:00
NULL, /* get_current_shader */
NULL, /* get_current_software_framebuffer */
Add HDR support for D3D12 (rebased PR from MajorPainTheCactus) (#12917) * Add HDR support * Attempt to fix Mingw build and Metal builds * (D3D12) Fix relative header includes * Add missing hdr_sm5.hlsl.h * (d3d12_common.c) Some C89 build fixes * Fix MSVC build * - Attempt to fix build on mingw/msys unix with dirty hack - Fix shader compilation of hdr_sm5.hlsl.h on MSVC/Visual Studio - the define was seen as an error and was causing the first pipeline to error out - Make sure we manually set handle of backBuffer to NULL * Moving the release of the texture above the freeing of desc.srv_heap and desc.rtv_heap solves the hard crashes on teardown/setup in RA - it was crashing hard in d3d12_release_texture before * Add HAVE_D3D12_HDR ifdef - needs to be disabled for WinRT for now because of several things that are Windows desktop-specific right now (GetWindowRect) * Add dirty GUID hack - should work for both mingw/msys on Windows/Linux as well as MSVC/Visual Studio (hopefully) * Change HAVE_D3D12_HDR to HAVE_DXGI_HDR * Move away from camelcase named variables * Fix RARCH_ERR logs - they need a newline at the end * d3d12_check_display_hdr_support - make it return a bool on return and set d3d12->hdr.support and d3d12->hdr.enable outside of the function * (DXGI) Remove D3D12 dependencies from dxgi_check_display_hdr_support and move it to dxgi_common.c instead * (DXGI) move d3d12_swapchain_color_space over to dxgi_common.c and rename it dxgi_swapchain_color_space * (DXGI) move d3d12_set_hdr_metadata to dxgi_common.c and rename it dxgi_set_hdr_metadata * (DXGI) dxgi_check_display_hdr_support - better error handling? * Fix typo * Remove video_force_resolution * (D3D12) Address TODO/FIXME * (D3D12) Backport https://github.com/libretro/RetroArch/pull/12916/commits/c1b6c0bff2aa33cde035b43cb31ac7e78ff2a07a - Fixed resource transition for present when HDR is off Fixed cel shader displaying all black as blending was enabled when the hdr shader was being applied - turned off blending during this shader * Move d3d12_hdr_uniform_t to dxgi_common.h and rename it dxgi_hdr_uniform_t * (D3D11) Add HDR support * Add TODO/FIXME notes * Cache hdr_enable in video_frame_info_t * Update comment
2021-09-03 06:15:25 +02:00
NULL, /* get_hw_render_interface */
NULL, /* set_hdr_max_nits */
NULL, /* set_hdr_paper_white_nits */
NULL, /* set_hdr_contrast */
NULL /* set_hdr_expand_gamut */
};
static void sdl_get_poke_interface(void *data, const video_poke_interface_t **iface)
{
(void)data;
2015-04-03 04:20:50 +02:00
*iface = &sdl_poke_interface;
}
static bool sdl_gfx_set_shader(void *data,
enum rarch_shader_type type, const char *path)
{
(void)data;
(void)type;
(void)path;
return false;
}
2014-09-11 07:06:20 +02:00
video_driver_t video_sdl = {
2011-12-24 13:46:12 +01:00
sdl_gfx_init,
sdl_gfx_frame,
sdl_gfx_set_nonblock_state,
sdl_gfx_alive,
sdl_gfx_focus,
2015-01-18 22:32:14 +01:00
sdl_gfx_suppress_screensaver,
sdl_gfx_has_windowed,
sdl_gfx_set_shader,
2011-12-24 13:46:12 +01:00
sdl_gfx_free,
"sdl",
NULL,
NULL, /* set_rotation */
sdl_gfx_viewport_info,
NULL, /* read_viewport */
NULL, /* read_frame_raw */
#ifdef HAVE_OVERLAY
NULL,
2019-04-01 04:00:58 +01:00
#endif
#ifdef HAVE_VIDEO_LAYOUT
NULL,
#endif
sdl_get_poke_interface
2011-04-21 03:23:44 +02:00
};