Implement SDL driver video poke interface

This commit is contained in:
Higor Eurípedes 2014-08-07 23:34:50 -03:00
parent e087072f7d
commit 081347929c
5 changed files with 182 additions and 1 deletions

View File

@ -310,6 +310,34 @@ void conv_rgb565_argb8888(void *output_, const void *input_,
}
#endif
void conv_rgba4444_argb8888(void *output_, const void *input_,
int width, int height,
int out_stride, int in_stride)
{
int h, w;
const uint16_t *input = (const uint16_t*)input_;
uint32_t *output = (uint32_t*)output_;
for (h = 0; h < height; h++, output += out_stride >> 2, input += in_stride >> 1)
{
for (w = 0; w < width; w++)
{
uint32_t col = input[w];
uint32_t r = (col >> 12) & 0xf;
uint32_t g = (col >> 8) & 0xf;
uint32_t b = (col >> 4) & 0xf;
uint32_t a = (col >> 0) & 0xf;
r = (r << 4) | r;
g = (g << 4) | g;
b = (b << 4) | b;
a = (a << 4) | a;
//output[w] = (0xffu << 24) | (r << 16) | (g << 8) | (b << 0);
output[w] = (a << 24) | (r << 16) | (g << 8) | (b << 0);
}
}
}
#if defined(__SSE2__)
// :( TODO: Make this saner.
static inline void store_bgr24_sse2(void *output, __m128i a, __m128i b, __m128i c, __m128i d)

View File

@ -34,6 +34,10 @@ void conv_rgb565_argb8888(void *output, const void *input,
int width, int height,
int out_stride, int in_stride);
void conv_rgba4444_argb8888(void *output, const void *input,
int width, int height,
int out_stride, int in_stride);
void conv_bgr24_argb8888(void *output, const void *input,
int width, int height,
int out_stride, int in_stride);

View File

@ -115,6 +115,10 @@ static bool set_pix_conv(struct scaler_ctx *ctx)
ctx->in_pixconv = conv_bgr24_argb8888;
break;
case SCALER_FMT_RGBA4444:
ctx->in_pixconv = conv_rgba4444_argb8888;
break;
default:
return false;
}

View File

@ -30,7 +30,8 @@ enum scaler_pix_fmt
SCALER_FMT_0RGB1555,
SCALER_FMT_RGB565,
SCALER_FMT_BGR24,
SCALER_FMT_YUYV
SCALER_FMT_YUYV,
SCALER_FMT_RGBA4444
};
enum scaler_type

View File

@ -33,6 +33,14 @@
#include "SDL/SDL_syswm.h"
typedef struct sdl_menu_frame
{
bool active;
SDL_Surface *frame;
struct scaler_ctx scaler;
} sdl_menu_frame_t;
typedef struct sdl_video
{
SDL_Surface *screen;
@ -47,6 +55,8 @@ typedef struct sdl_video
struct scaler_ctx scaler;
unsigned last_width;
unsigned last_height;
sdl_menu_frame_t menu;
} sdl_video_t;
static void sdl_gfx_free(void *data)
@ -55,6 +65,9 @@ static void sdl_gfx_free(void *data)
if (!vid)
return;
if (vid->menu.frame)
SDL_FreeSurface(vid->menu.frame);
SDL_QuitSubSystem(SDL_INIT_VIDEO);
if (vid->font)
@ -265,6 +278,17 @@ static void *sdl_gfx_init(const video_info_t *video, const input_driver_t **inpu
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)
{
RARCH_ERR("Failed to init menu surface: %s\n", SDL_GetError());
goto error;
}
return vid;
error:
@ -320,6 +344,9 @@ static bool sdl_gfx_frame(void *data, const void *frame, unsigned width, unsigne
scaler_ctx_scale(&vid->scaler, vid->screen->pixels, frame);
RARCH_PERFORMANCE_STOP(sdl_scale);
if (vid->menu.active)
SDL_BlitSurface(vid->menu.frame, NULL, vid->screen, NULL);
if (msg)
sdl_render_msg(vid, vid->screen, msg, vid->screen->w, vid->screen->h, vid->screen->format);
@ -363,6 +390,118 @@ static void sdl_gfx_viewport_info(void *data, struct rarch_viewport *vp)
vp->height = vp->full_height = vid->screen->h;
}
static void sdl_set_filtering(void *data, unsigned index, bool smooth)
{
sdl_video_t *vid = (sdl_video_t*)data;
vid->scaler.scaler_type = smooth ? SCALER_TYPE_BILINEAR : SCALER_TYPE_POINT;
}
static void sdl_set_aspect_ratio(void *data, unsigned aspectratio_index)
{
sdl_video_t *vid = (sdl_video_t*)data;
switch (aspectratio_index)
{
case ASPECT_RATIO_SQUARE:
gfx_set_square_pixel_viewport(g_extern.system.av_info.geometry.base_width, g_extern.system.av_info.geometry.base_height);
break;
case ASPECT_RATIO_CORE:
gfx_set_core_viewport();
break;
case ASPECT_RATIO_CONFIG:
gfx_set_config_viewport();
break;
default:
break;
}
g_extern.system.aspect_ratio = aspectratio_lut[aspectratio_index].value;
}
static void sdl_apply_state_changes(void *data)
{
(void)data;
}
static void sdl_set_texture_frame(void *data, const void *frame, bool rgb32,
unsigned width, unsigned height, float alpha)
{
(void) alpha;
sdl_video_t *vid = (sdl_video_t*)data;
enum scaler_pix_fmt format = rgb32 ? SCALER_FMT_ARGB8888 : SCALER_FMT_RGBA4444;
vid->menu.scaler.in_stride = width * (rgb32 ? sizeof(uint32_t) : sizeof(uint16_t));
if (
width != vid->menu.scaler.in_width
|| height != vid->menu.scaler.in_height
|| format != vid->menu.scaler.in_fmt
)
{
vid->menu.scaler.in_fmt = format;
vid->menu.scaler.in_width = width;
vid->menu.scaler.in_height = height;
vid->menu.scaler.out_width = vid->screen->w;
vid->menu.scaler.out_height = vid->screen->h;
vid->menu.scaler.out_stride = vid->screen->pitch;
scaler_ctx_gen_filter(&vid->menu.scaler);
}
scaler_ctx_scale(&vid->menu.scaler, vid->menu.frame->pixels, frame);
SDL_SetAlpha(vid->menu.frame, SDL_SRCALPHA, 255.0 * alpha);
}
static void sdl_set_texture_enable(void *data, bool state, bool full_screen)
{
(void) full_screen;
sdl_video_t *vid = (sdl_video_t*)data;
vid->menu.active = state;
}
static void sdl_show_mouse(void *data, bool state)
{
(void)data;
SDL_ShowCursor(state);
}
static void sdl_grab_mouse_toggle(void *data)
{
(void)data;
const SDL_GrabMode mode = SDL_WM_GrabInput(SDL_GRAB_QUERY);
SDL_WM_GrabInput(mode == SDL_GRAB_ON ? SDL_GRAB_OFF : SDL_GRAB_ON);
}
static const video_poke_interface_t sdl_poke_interface = {
sdl_set_filtering,
#ifdef HAVE_FBO
NULL,
NULL,
#endif
sdl_set_aspect_ratio,
sdl_apply_state_changes,
#ifdef HAVE_MENU
sdl_set_texture_frame,
sdl_set_texture_enable,
#endif
NULL,
sdl_show_mouse,
sdl_grab_mouse_toggle,
NULL
};
static void sdl_get_poke_interface(void *data, const video_poke_interface_t **iface)
{
(void)data;
*iface = &sdl_poke_interface;
}
const video_driver_t video_sdl = {
sdl_gfx_init,
sdl_gfx_frame,
@ -375,5 +514,10 @@ const video_driver_t video_sdl = {
NULL,
sdl_gfx_viewport_info,
NULL,
#ifdef HAVE_OVERLAY
NULL,
#endif
sdl_get_poke_interface
};