hidpiscale
This commit is contained in:
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
|
||||
|
16
app/src/hidpi.c
Normal file
16
app/src/hidpi.c
Normal file
@ -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;
|
||||
}
|
||||
}
|
24
app/src/hidpi.h
Normal file
24
app/src/hidpi.h
Normal file
@ -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…
x
Reference in New Issue
Block a user