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 bool
convert_mouse_button(const SDL_MouseButtonEvent *from, struct size screen_size, convert_mouse_button(const SDL_MouseButtonEvent *from, const SDL_Rect *rect,
struct control_msg *to) { struct size frame_size, struct control_msg *to) {
to->type = CONTROL_MSG_TYPE_INJECT_TOUCH_EVENT; to->type = CONTROL_MSG_TYPE_INJECT_TOUCH_EVENT;
if (!convert_mouse_action(from->type, &to->inject_touch_event.action)) { if (!convert_mouse_action(from->type, &to->inject_touch_event.action)) {
return false; 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.pointer_id = POINTER_ID_MOUSE;
to->inject_touch_event.position.screen_size = screen_size; to->inject_touch_event.position.screen_size = frame_size;
to->inject_touch_event.position.point.x = from->x; to->inject_touch_event.position.point.x = x;
to->inject_touch_event.position.point.y = from->y; to->inject_touch_event.position.point.y = y;
to->inject_touch_event.pressure = 1.f; to->inject_touch_event.pressure = 1.f;
to->inject_touch_event.buttons = to->inject_touch_event.buttons =
convert_mouse_buttons(SDL_BUTTON(from->button)); convert_mouse_buttons(SDL_BUTTON(from->button));
@ -197,14 +208,18 @@ convert_mouse_button(const SDL_MouseButtonEvent *from, struct size screen_size,
} }
bool bool
convert_mouse_motion(const SDL_MouseMotionEvent *from, struct size screen_size, convert_mouse_motion(const SDL_MouseMotionEvent *from, const SDL_Rect *rect,
struct control_msg *to) { 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->type = CONTROL_MSG_TYPE_INJECT_TOUCH_EVENT;
to->inject_touch_event.action = AMOTION_EVENT_ACTION_MOVE; to->inject_touch_event.action = AMOTION_EVENT_ACTION_MOVE;
to->inject_touch_event.pointer_id = POINTER_ID_MOUSE; to->inject_touch_event.pointer_id = POINTER_ID_MOUSE;
to->inject_touch_event.position.screen_size = screen_size; to->inject_touch_event.position.screen_size = frame_size;
to->inject_touch_event.position.point.x = from->x; to->inject_touch_event.position.point.x = x;
to->inject_touch_event.position.point.y = from->y; to->inject_touch_event.position.point.y = y;
to->inject_touch_event.pressure = 1.f; to->inject_touch_event.pressure = 1.f;
to->inject_touch_event.buttons = convert_mouse_buttons(from->state); 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) { struct control_msg *to) {
to->type = CONTROL_MSG_TYPE_INJECT_SCROLL_EVENT; to->type = CONTROL_MSG_TYPE_INJECT_SCROLL_EVENT;
// TODO map coords
to->inject_scroll_event.position = position; to->inject_scroll_event.position = position;
int mul = from->direction == SDL_MOUSEWHEEL_NORMAL ? 1 : -1; 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); convert_input_key(const SDL_KeyboardEvent *from, struct control_msg *to);
bool bool
convert_mouse_button(const SDL_MouseButtonEvent *from, struct size screen_size, convert_mouse_button(const SDL_MouseButtonEvent *from, const SDL_Rect *rect,
struct control_msg *to); struct size frame_size, struct control_msg *to);
// the video size may be different from the real device size, so we need the // 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 // size to which the absolute position apply, to scale it accordingly
bool bool
convert_mouse_motion(const SDL_MouseMotionEvent *from, struct size screen_size, convert_mouse_motion(const SDL_MouseMotionEvent *from, const SDL_Rect *rect,
struct control_msg *to); struct size frame_size, struct control_msg *to);
bool bool
convert_touch(const SDL_TouchFingerEvent *from, struct size screen_size, 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; return;
} }
struct control_msg msg; 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)) { if (!controller_push_msg(input_manager->controller, &msg)) {
LOGW("Could not request 'inject mouse motion event'"); 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; 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)) { if (!controller_push_msg(input_manager->controller, &msg)) {
LOGW("Could not request 'inject mouse button event'"); LOGW("Could not request 'inject mouse button event'");
} }

View File

@ -145,9 +145,11 @@ handle_event(SDL_Event *event, bool control) {
case SDL_WINDOWEVENT: case SDL_WINDOWEVENT:
switch (event->window.event) { switch (event->window.event) {
case SDL_WINDOWEVENT_EXPOSED: case SDL_WINDOWEVENT_EXPOSED:
case SDL_WINDOWEVENT_SIZE_CHANGED:
screen_render(&screen); screen_render(&screen);
break; break;
case SDL_WINDOWEVENT_SIZE_CHANGED:
screen_resized(&screen);
break;
} }
break; break;
case SDL_TEXTINPUT: 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); 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 void
screen_init(struct screen *screen) { screen_init(struct screen *screen) {
*screen = (struct screen) SCREEN_INITIALIZER; *screen = (struct screen) SCREEN_INITIALIZER;
@ -170,13 +196,6 @@ screen_init_rendering(struct screen *screen, const char *window_title,
return false; 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); SDL_Surface *icon = read_xpm(icon_xpm);
if (icon) { if (icon) {
SDL_SetWindowIcon(screen->window, icon); SDL_SetWindowIcon(screen->window, icon);
@ -220,12 +239,6 @@ static bool
prepare_for_frame(struct screen *screen, struct size new_frame_size) { prepare_for_frame(struct screen *screen, struct size new_frame_size) {
if (screen->frame_size.width != new_frame_size.width if (screen->frame_size.width != new_frame_size.width
|| screen->frame_size.height != new_frame_size.height) { || 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 // frame dimension changed, destroy texture
SDL_DestroyTexture(screen->texture); SDL_DestroyTexture(screen->texture);
@ -271,6 +284,7 @@ screen_update_frame(struct screen *screen, struct video_buffer *vb) {
mutex_unlock(vb->mutex); mutex_unlock(vb->mutex);
return false; return false;
} }
update_frame_rect(screen);
update_texture(screen, frame); update_texture(screen, frame);
mutex_unlock(vb->mutex); mutex_unlock(vb->mutex);
@ -278,10 +292,16 @@ screen_update_frame(struct screen *screen, struct video_buffer *vb) {
return true; return true;
} }
void
screen_resized(struct screen *screen) {
update_frame_rect(screen);
screen_render(screen);
}
void void
screen_render(struct screen *screen) { screen_render(struct screen *screen) {
SDL_RenderClear(screen->renderer); 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); SDL_RenderPresent(screen->renderer);
} }

View File

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