WIP manual logical size

This commit is contained in:
Romain Vimont 2019-10-19 15:17:28 +02:00
parent c33a147fd0
commit ee3908da64
6 changed files with 82 additions and 34 deletions

View file

@ -176,19 +176,30 @@ convert_mouse_action(SDL_EventType from, enum android_motionevent_action *to) {
}
}
static inline void
map_coords(int32_t *x, int32_t *y, const SDL_Rect *rect,
struct size frame_size) {
*x = (*x - rect->x) * frame_size.width / rect->w;
*y = (*y - rect->y) * frame_size.height / rect->h;
}
bool
convert_mouse_button(const SDL_MouseButtonEvent *from, struct size screen_size,
struct control_msg *to) {
convert_mouse_button(const SDL_MouseButtonEvent *from, const SDL_Rect *rect,
struct size frame_size, struct control_msg *to) {
to->type = CONTROL_MSG_TYPE_INJECT_TOUCH_EVENT;
if (!convert_mouse_action(from->type, &to->inject_touch_event.action)) {
return false;
}
int32_t x = from->x;
int32_t y = from->y;
map_coords(&x, &y, rect, frame_size);
to->inject_touch_event.pointer_id = POINTER_ID_MOUSE;
to->inject_touch_event.position.screen_size = screen_size;
to->inject_touch_event.position.point.x = from->x;
to->inject_touch_event.position.point.y = from->y;
to->inject_touch_event.position.screen_size = frame_size;
to->inject_touch_event.position.point.x = x;
to->inject_touch_event.position.point.y = y;
to->inject_touch_event.pressure = 1.f;
to->inject_touch_event.buttons =
convert_mouse_buttons(SDL_BUTTON(from->button));
@ -197,14 +208,18 @@ convert_mouse_button(const SDL_MouseButtonEvent *from, struct size screen_size,
}
bool
convert_mouse_motion(const SDL_MouseMotionEvent *from, struct size screen_size,
struct control_msg *to) {
convert_mouse_motion(const SDL_MouseMotionEvent *from, const SDL_Rect *rect,
struct size frame_size, struct control_msg *to) {
int32_t x = from->x;
int32_t y = from->y;
map_coords(&x, &y, rect, frame_size);
to->type = CONTROL_MSG_TYPE_INJECT_TOUCH_EVENT;
to->inject_touch_event.action = AMOTION_EVENT_ACTION_MOVE;
to->inject_touch_event.pointer_id = POINTER_ID_MOUSE;
to->inject_touch_event.position.screen_size = screen_size;
to->inject_touch_event.position.point.x = from->x;
to->inject_touch_event.position.point.y = from->y;
to->inject_touch_event.position.screen_size = frame_size;
to->inject_touch_event.position.point.x = x;
to->inject_touch_event.position.point.y = y;
to->inject_touch_event.pressure = 1.f;
to->inject_touch_event.buttons = convert_mouse_buttons(from->state);
@ -245,6 +260,7 @@ convert_mouse_wheel(const SDL_MouseWheelEvent *from, struct position position,
struct control_msg *to) {
to->type = CONTROL_MSG_TYPE_INJECT_SCROLL_EVENT;
// TODO map coords
to->inject_scroll_event.position = position;
int mul = from->direction == SDL_MOUSEWHEEL_NORMAL ? 1 : -1;

View file

@ -21,14 +21,14 @@ bool
convert_input_key(const SDL_KeyboardEvent *from, struct control_msg *to);
bool
convert_mouse_button(const SDL_MouseButtonEvent *from, struct size screen_size,
struct control_msg *to);
convert_mouse_button(const SDL_MouseButtonEvent *from, const SDL_Rect *rect,
struct size frame_size, struct control_msg *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
bool
convert_mouse_motion(const SDL_MouseMotionEvent *from, struct size screen_size,
struct control_msg *to);
convert_mouse_motion(const SDL_MouseMotionEvent *from, const SDL_Rect *rect,
struct size frame_size, struct control_msg *to);
bool
convert_touch(const SDL_TouchFingerEvent *from, struct size screen_size,

View file

@ -394,7 +394,7 @@ input_manager_process_mouse_motion(struct input_manager *input_manager,
return;
}
struct control_msg msg;
if (convert_mouse_motion(event, input_manager->screen->frame_size, &msg)) {
if (convert_mouse_motion(event, &input_manager->screen->rect, input_manager->screen->frame_size, &msg)) {
if (!controller_push_msg(input_manager->controller, &msg)) {
LOGW("Could not request 'inject mouse motion event'");
}
@ -453,7 +453,7 @@ input_manager_process_mouse_button(struct input_manager *input_manager,
}
struct control_msg msg;
if (convert_mouse_button(event, input_manager->screen->frame_size, &msg)) {
if (convert_mouse_button(event, &input_manager->screen->rect, input_manager->screen->frame_size, &msg)) {
if (!controller_push_msg(input_manager->controller, &msg)) {
LOGW("Could not request 'inject mouse button event'");
}

View file

@ -145,9 +145,11 @@ handle_event(SDL_Event *event, bool control) {
case SDL_WINDOWEVENT:
switch (event->window.event) {
case SDL_WINDOWEVENT_EXPOSED:
case SDL_WINDOWEVENT_SIZE_CHANGED:
screen_render(&screen);
break;
case SDL_WINDOWEVENT_SIZE_CHANGED:
screen_resized(&screen);
break;
}
break;
case SDL_TEXTINPUT:

View file

@ -122,6 +122,32 @@ get_initial_optimal_size(struct size frame_size) {
return get_optimal_size(frame_size, frame_size);
}
static void
update_frame_rect(struct screen *screen) {
struct size window_size = get_window_size(screen);
// 32 bits because we need to multiply two 16 bits values
uint32_t ww = window_size.width;
uint32_t wh = window_size.height;
uint32_t fw = screen->frame_size.width;
uint32_t fh = screen->frame_size.height;
SDL_Rect *rect = &screen->rect;
bool keep_width = fw * wh > fh * ww;
if (keep_width) {
rect->x = 0;
rect->w = ww;
rect->h = ww * fh / fw;
rect->y = (wh - rect->h) / 2;
} else {
rect->y = 0;
rect->h = wh;
rect->w = wh * fw / fh;
rect->x = (ww - rect->w) / 2;
}
}
void
screen_init(struct screen *screen) {
*screen = (struct screen) SCREEN_INITIALIZER;
@ -170,13 +196,6 @@ screen_init_rendering(struct screen *screen, const char *window_title,
return false;
}
if (SDL_RenderSetLogicalSize(screen->renderer, frame_size.width,
frame_size.height)) {
LOGE("Could not set renderer logical size: %s", SDL_GetError());
screen_destroy(screen);
return false;
}
SDL_Surface *icon = read_xpm(icon_xpm);
if (icon) {
SDL_SetWindowIcon(screen->window, icon);
@ -220,12 +239,6 @@ static bool
prepare_for_frame(struct screen *screen, struct size new_frame_size) {
if (screen->frame_size.width != new_frame_size.width
|| screen->frame_size.height != new_frame_size.height) {
if (SDL_RenderSetLogicalSize(screen->renderer, new_frame_size.width,
new_frame_size.height)) {
LOGE("Could not set renderer logical size: %s", SDL_GetError());
return false;
}
// frame dimension changed, destroy texture
SDL_DestroyTexture(screen->texture);
@ -271,6 +284,7 @@ screen_update_frame(struct screen *screen, struct video_buffer *vb) {
mutex_unlock(vb->mutex);
return false;
}
update_frame_rect(screen);
update_texture(screen, frame);
mutex_unlock(vb->mutex);
@ -278,10 +292,16 @@ screen_update_frame(struct screen *screen, struct video_buffer *vb) {
return true;
}
void
screen_resized(struct screen *screen) {
update_frame_rect(screen);
screen_render(screen);
}
void
screen_render(struct screen *screen) {
SDL_RenderClear(screen->renderer);
SDL_RenderCopy(screen->renderer, screen->texture, NULL, NULL);
SDL_RenderCopy(screen->renderer, screen->texture, NULL, &screen->rect);
SDL_RenderPresent(screen->renderer);
}

View file

@ -17,6 +17,7 @@ struct screen {
struct size frame_size;
//used only in fullscreen mode to know the windowed window size
struct size windowed_window_size;
struct SDL_Rect rect; // frame location and size inside the window
bool has_frame;
bool fullscreen;
bool no_window;
@ -34,9 +35,15 @@ struct screen {
.width = 0, \
.height = 0, \
}, \
.has_frame = false, \
.fullscreen = false, \
.no_window = false, \
.rect = { \
.x = 0, \
.y = 0, \
.w = 0, \
.h = 0, \
}, \
.has_frame = false, \
.fullscreen = false, \
.no_window = false, \
}
// initialize default values
@ -60,6 +67,9 @@ screen_destroy(struct screen *screen);
bool
screen_update_frame(struct screen *screen, struct video_buffer *vb);
void
screen_resized(struct screen *screen);
// render the texture to the renderer
void
screen_render(struct screen *screen);