hidpiscale

hidpiscale
Romain Vimont 6 years ago
parent 65021416b3
commit ae87885ffa

@ -8,6 +8,7 @@ src = [
'src/device.c',
'src/fpscounter.c',
'src/frames.c',
'src/hidpi.c',
'src/inputmanager.c',
'src/lockutil.c',
'src/net.c',

@ -136,6 +136,7 @@ SDL_bool input_key_from_sdl_to_android(const SDL_KeyboardEvent *from,
SDL_bool mouse_button_from_sdl_to_android(const SDL_MouseButtonEvent *from,
struct size screen_size,
struct hidpi_scale *hidpi_scale,
struct control_event *to) {
to->type = CONTROL_EVENT_TYPE_MOUSE;
@ -145,21 +146,30 @@ SDL_bool mouse_button_from_sdl_to_android(const SDL_MouseButtonEvent *from,
to->mouse_event.buttons = convert_mouse_buttons(SDL_BUTTON(from->button));
to->mouse_event.position.screen_size = screen_size;
to->mouse_event.position.point.x = (Uint16) from->x;
to->mouse_event.position.point.y = (Uint16) from->y;
Sint32 x = from->x;
Sint32 y = from->y;
hidpi_unscale_coordinates(hidpi_scale, &x, &y);
to->mouse_event.position.point.x = (Uint16) x;
to->mouse_event.position.point.y = (Uint16) y;
return SDL_TRUE;
}
SDL_bool mouse_motion_from_sdl_to_android(const SDL_MouseMotionEvent *from,
struct size screen_size,
struct hidpi_scale *hidpi_scale,
struct control_event *to) {
to->type = CONTROL_EVENT_TYPE_MOUSE;
to->mouse_event.action = AMOTION_EVENT_ACTION_MOVE;
to->mouse_event.buttons = convert_mouse_buttons(from->state);
to->mouse_event.position.screen_size = screen_size;
to->mouse_event.position.point.x = from->x;
to->mouse_event.position.point.y = from->y;
Sint32 x = from->x;
Sint32 y = from->y;
hidpi_unscale_coordinates(hidpi_scale, &x, &y);
to->mouse_event.position.point.x = (Uint16) x;
to->mouse_event.position.point.y = (Uint16) y;
return SDL_TRUE;
}

@ -3,7 +3,10 @@
#include <SDL2/SDL_stdinc.h>
#include <SDL2/SDL_events.h>
#include "common.h"
#include "controlevent.h"
#include "hidpi.h"
struct complete_mouse_motion_event {
SDL_MouseMotionEvent *mouse_motion_event;
@ -19,12 +22,14 @@ SDL_bool input_key_from_sdl_to_android(const SDL_KeyboardEvent *from,
struct control_event *to);
SDL_bool mouse_button_from_sdl_to_android(const SDL_MouseButtonEvent *from,
struct size screen_size,
struct hidpi_scale *hidpi_scale,
struct control_event *to);
// the video size may be different from the real device size, so we need the size
// to which the absolute position apply, to scale it accordingly
SDL_bool mouse_motion_from_sdl_to_android(const SDL_MouseMotionEvent *from,
struct size screen_size,
struct hidpi_scale *hidpi_scale,
struct control_event *to);
// on Android, a scroll event requires the current mouse position

@ -0,0 +1,16 @@
#include "hidpi.h"
void hidpi_get_scale(struct screen *screen, struct hidpi_scale *scale) {
SDL_GL_GetDrawableSize(screen->window, &scale->horizontal.num, &scale->vertical.num);
SDL_GetWindowSize(screen->window, &scale->horizontal.div, &scale->vertical.div);
}
void hidpi_unscale_coordinates(struct hidpi_scale *scale, Sint32 *x, Sint32 *y) {
// to unscale, we devide by the ratio (so num and div are reversed)
if (scale->horizontal.num) {
*x = ((Sint64) *x) * scale->horizontal.div / scale->horizontal.num;
}
if (scale->vertical.num) {
*y = ((Sint64) *y) * scale->vertical.div / scale->vertical.num;
}
}

@ -0,0 +1,24 @@
#ifndef HIDPI_H
#define HIDPI_H
#include "common.h"
#include "screen.h"
// rational number p/q
struct rational {
int num;
int div;
};
struct hidpi_scale {
struct rational horizontal; // drawable.width / window.width
struct rational vertical; // drawable.height / window.height
};
void hidpi_get_scale(struct screen *screen, struct hidpi_scale *hidpi_scale);
// mouse location need to be "unscaled" if hidpi is enabled
// <https://nlguillemot.wordpress.com/2016/12/11/high-dpi-rendering/>
void hidpi_unscale_coordinates(struct hidpi_scale *hidpi_scale, Sint32 *x, Sint32 *y);
#endif

@ -1,6 +1,7 @@
#include "inputmanager.h"
#include "convert.h"
#include "hidpi.h"
#include "lockutil.h"
#include "log.h"
@ -18,10 +19,19 @@ static void convert_to_renderer_coordinates(SDL_Renderer *renderer, int *x, int
}
static struct point get_mouse_point(struct screen *screen) {
int x;
int y;
SDL_GetMouseState(&x, &y);
convert_to_renderer_coordinates(screen->renderer, &x, &y);
int mx;
int my;
SDL_GetMouseState(&mx, &my);
convert_to_renderer_coordinates(screen->renderer, &mx, &my);
struct hidpi_scale hidpi_scale;
hidpi_get_scale(screen, &hidpi_scale);
// SDL sometimes uses "int", sometimes "Sint32"
Sint32 x = mx;
Sint32 y = my;
hidpi_unscale_coordinates(&hidpi_scale, &x, &y);
SDL_assert_release(x >= 0 && x < 0x10000 && y >= 0 && y < 0x10000);
return (struct point) {
.x = (Uint16) x,
@ -192,8 +202,12 @@ void input_manager_process_mouse_motion(struct input_manager *input_manager,
// do not send motion events when no button is pressed
return;
}
struct hidpi_scale hidpi_scale;
hidpi_get_scale(input_manager->screen, &hidpi_scale);
struct control_event control_event;
if (mouse_motion_from_sdl_to_android(event, input_manager->screen->frame_size, &control_event)) {
if (mouse_motion_from_sdl_to_android(event, input_manager->screen->frame_size, &hidpi_scale, &control_event)) {
if (!controller_push_event(input_manager->controller, &control_event)) {
LOGW("Cannot send mouse motion event");
}
@ -206,8 +220,12 @@ void input_manager_process_mouse_button(struct input_manager *input_manager,
turn_screen_on(input_manager->controller);
return;
};
struct hidpi_scale hidpi_scale;
hidpi_get_scale(input_manager->screen, &hidpi_scale);
struct control_event control_event;
if (mouse_button_from_sdl_to_android(event, input_manager->screen->frame_size, &control_event)) {
if (mouse_button_from_sdl_to_android(event, input_manager->screen->frame_size, &hidpi_scale, &control_event)) {
if (!controller_push_event(input_manager->controller, &control_event)) {
LOGW("Cannot send mouse button event");
}

@ -141,7 +141,8 @@ SDL_bool screen_init_rendering(struct screen *screen, const char *device_name, s
struct size window_size = get_initial_optimal_size(frame_size);
screen->window = SDL_CreateWindow(device_name, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
window_size.width, window_size.height, SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE);
window_size.width, window_size.height,
SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
if (!screen->window) {
LOGC("Could not create window: %s", SDL_GetError());
return SDL_FALSE;

Loading…
Cancel
Save