From f3b2c8748ade06935c825b0288296a61c6fb67b4 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sun, 28 Oct 2012 11:04:07 +0100 Subject: [PATCH] Add RETRO_DEVICE_POINTER support to SDL/Xv. --- gfx/sdl_gfx.c | 16 ++++++++++++++-- gfx/xvideo.c | 37 ++++++++++++++++++++++++++++--------- input/sdl_input.c | 40 ++++++++++++++++++++++++++++++++++------ 3 files changed, 76 insertions(+), 17 deletions(-) diff --git a/gfx/sdl_gfx.c b/gfx/sdl_gfx.c index 88abe57cc5..b947743c93 100644 --- a/gfx/sdl_gfx.c +++ b/gfx/sdl_gfx.c @@ -364,7 +364,8 @@ static void *sdl_gfx_init(const video_info_t *video, const input_driver_t **inpu if (!video->rgb32 && vid->render32) vid->upsample = true; - SDL_ShowCursor(SDL_DISABLE); + if (video->fullscreen) + SDL_ShowCursor(SDL_DISABLE); fmt = vid->screen->format; if (vid->render32) @@ -658,6 +659,14 @@ static bool sdl_gfx_focus(void *data) return (SDL_GetAppState() & (SDL_APPINPUTFOCUS | SDL_APPACTIVE)) == (SDL_APPINPUTFOCUS | SDL_APPACTIVE); } +static void sdl_gfx_viewport_info(void *data, struct rarch_viewport *vp) +{ + sdl_video_t *vid = (sdl_video_t*)data; + vp->x = vp->y = 0; + vp->width = vid->screen->w; + vp->height = vid->screen->h; +} + const video_driver_t video_sdl = { sdl_gfx_init, sdl_gfx_frame, @@ -666,6 +675,9 @@ const video_driver_t video_sdl = { sdl_gfx_focus, NULL, sdl_gfx_free, - "sdl" + "sdl", + + NULL, + sdl_gfx_viewport_info, }; diff --git a/gfx/xvideo.c b/gfx/xvideo.c index fe7b7a9ff9..b67aed8417 100644 --- a/gfx/xvideo.c +++ b/gfx/xvideo.c @@ -59,6 +59,7 @@ typedef struct xv unsigned width; unsigned height; bool keep_aspect; + struct rarch_viewport vp; uint8_t *ytable; uint8_t *utable; @@ -545,11 +546,13 @@ static bool check_resize(xv_t *xv, unsigned width, unsigned height) return true; } -static void calc_out_rect(bool keep_aspect, unsigned *x, unsigned *y, unsigned *width, unsigned *height, unsigned vp_width, unsigned vp_height) +static void calc_out_rect(bool keep_aspect, struct rarch_viewport *vp, unsigned vp_width, unsigned vp_height) { if (!keep_aspect) { - *x = 0; *y = 0; *width = vp_width; *height = vp_height; + vp->x = 0; vp->y = 0; + vp->width = vp_width; + vp->height = vp_height; } else { @@ -560,17 +563,25 @@ static void calc_out_rect(bool keep_aspect, unsigned *x, unsigned *y, unsigned * // assume they are actually equal. if (fabs(device_aspect - desired_aspect) < 0.0001) { - *x = 0; *y = 0; *width = vp_width; *height = vp_height; + vp->x = 0; vp->y = 0; + vp->width = vp_width; + vp->height = vp_height; } else if (device_aspect > desired_aspect) { float delta = (desired_aspect / device_aspect - 1.0) / 2.0 + 0.5; - *x = vp_width * (0.5 - delta); *y = 0; *width = 2.0 * vp_width * delta; *height = vp_height; + vp->x = vp_width * (0.5 - delta); + vp->y = 0; + vp->width = 2.0 * vp_width * delta; + vp->height = vp_height; } else { float delta = (device_aspect / desired_aspect - 1.0) / 2.0 + 0.5; - *x = 0; *y = vp_height * (0.5 - delta); *width = vp_width; *height = 2.0 * vp_height * delta; + vp->x = 0; + vp->y = vp_height * (0.5 - delta); + vp->width = vp_width; + vp->height = 2.0 * vp_height * delta; } } } @@ -689,15 +700,14 @@ static bool xv_frame(void *data, const void *frame, unsigned width, unsigned hei XGetWindowAttributes(xv->display, xv->window, &target); xv->render_func(xv, frame, width, height, pitch); - unsigned x, y, owidth, oheight; - calc_out_rect(xv->keep_aspect, &x, &y, &owidth, &oheight, target.width, target.height); + calc_out_rect(xv->keep_aspect, &xv->vp, target.width, target.height); if (msg) xv_render_msg(xv, msg, width << 1, height << 1); XvShmPutImage(xv->display, xv->port, xv->window, xv->gc, xv->image, 0, 0, width << 1, height << 1, - x, y, owidth, oheight, + xv->vp.x, xv->vp.y, xv->vp.width, xv->vp.height, true); XSync(xv->display, False); @@ -772,6 +782,12 @@ static void xv_free(void *data) free(xv); } +static void xv_viewport_info(void *data, struct rarch_viewport *vp) +{ + xv_t *xv = (xv_t*)data; + *vp = xv->vp; +} + const video_driver_t video_xvideo = { xv_init, xv_frame, @@ -780,6 +796,9 @@ const video_driver_t video_xvideo = { xv_focus, NULL, xv_free, - "xvideo" + "xvideo", + + NULL, + xv_viewport_info, }; diff --git a/input/sdl_input.c b/input/sdl_input.c index 992d7ec335..20bb02c897 100644 --- a/input/sdl_input.c +++ b/input/sdl_input.c @@ -28,8 +28,9 @@ typedef struct sdl_input { const rarch_joypad_driver_t *joypad; - int16_t mouse_x, mouse_y; - int16_t mouse_l, mouse_r, mouse_m; + int mouse_x, mouse_y; + int mouse_abs_x, mouse_abs_y; + int mouse_l, mouse_r, mouse_m; } sdl_input_t; struct key_bind @@ -218,6 +219,33 @@ static int16_t sdl_mouse_device_state(sdl_input_t *sdl, unsigned id) } } +static int16_t sdl_pointer_device_state(sdl_input_t *sdl, unsigned id) +{ + int16_t res_x = 0, res_y = 0; + bool valid = input_translate_coord_viewport(sdl->mouse_abs_x, sdl->mouse_abs_y, &res_x, &res_y); + + if (!valid) + return 0; + + bool inside = (res_x >= -0x7fff) && (res_x <= 0x7fff) && + (res_y >= -0x7fff) && (res_y <= 0x7fff); + + if (!inside) + return 0; + + switch (id) + { + case RETRO_DEVICE_ID_POINTER_X: + return res_x; + case RETRO_DEVICE_ID_POINTER_Y: + return res_y; + case RETRO_DEVICE_ID_POINTER_PRESSED: + return sdl->mouse_l; + default: + return 0; + } +} + static int16_t sdl_lightgun_device_state(sdl_input_t *sdl, unsigned id) { switch (id) @@ -252,6 +280,8 @@ static int16_t sdl_input_state(void *data_, const struct retro_keybind **binds, return sdl_analog_device_state(data, binds, port, index, id); case RETRO_DEVICE_MOUSE: return sdl_mouse_device_state(data, id); + case RETRO_DEVICE_POINTER: + return sdl_pointer_device_state(data, id); case RETRO_DEVICE_KEYBOARD: return sdl_keyboard_device_state(data, id); case RETRO_DEVICE_LIGHTGUN: @@ -281,10 +311,8 @@ static void sdl_input_free(void *data) static void sdl_poll_mouse(sdl_input_t *sdl) { - int _x, _y; - Uint8 btn = SDL_GetRelativeMouseState(&_x, &_y); - sdl->mouse_x = _x; - sdl->mouse_y = _y; + Uint8 btn = SDL_GetRelativeMouseState(&sdl->mouse_x, &sdl->mouse_y); + SDL_GetMouseState(&sdl->mouse_abs_x, &sdl->mouse_abs_y); sdl->mouse_l = SDL_BUTTON(SDL_BUTTON_LEFT) & btn ? 1 : 0; sdl->mouse_r = SDL_BUTTON(SDL_BUTTON_RIGHT) & btn ? 1 : 0; sdl->mouse_m = SDL_BUTTON(SDL_BUTTON_MIDDLE) & btn ? 1 : 0;