From 38b59b6c312e9bf3220a781f50497fafd3278ce9 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Thu, 21 Jul 2016 16:06:43 +0200 Subject: [PATCH 01/10] WIP: zoom towards cursor rather than centre. --- src/interface/window.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/interface/window.c b/src/interface/window.c index 5e042798d8..e89c141dab 100644 --- a/src/interface/window.c +++ b/src/interface/window.c @@ -374,7 +374,7 @@ static void window_close_surplus(int cap, sint8 avoid_classification) /* * Changes the maximum amount of windows allowed */ -void window_set_window_limit(int value) +void window_set_window_limit(int value) { int prev = gConfigGeneral.window_limit; int val = clamp(value, WINDOW_LIMIT_MIN, WINDOW_LIMIT_MAX); @@ -1445,6 +1445,13 @@ void window_rotate_camera(rct_window *w, int direction) reset_all_sprite_quadrant_placements(); } +void window_viewport_get_map_coords_by_cursor(rct_window *w, sint16 *map_x, sint16 *map_y) +{ + int mouse_x, mouse_y; + platform_get_cursor_position(&mouse_x, &mouse_y); + get_map_coordinates_from_pos(mouse_x, mouse_y, VIEWPORT_INTERACTION_MASK_NONE, map_x, map_y, NULL, NULL, NULL); +} + void window_zoom_set(rct_window *w, int zoomLevel) { rct_viewport* v = w->viewport; @@ -1453,12 +1460,15 @@ void window_zoom_set(rct_window *w, int zoomLevel) if (v->zoom == zoomLevel) return; + sint16 saved_map_x, saved_map_y; + window_viewport_get_map_coords_by_cursor(w, &saved_map_x, &saved_map_y); + // Zoom in while (v->zoom > zoomLevel) { v->zoom--; w->saved_view_x += v->view_width / 4; w->saved_view_y += v->view_height / 4; - v->view_width /= 2; + v->view_width /= 2; v->view_height /= 2; } @@ -1467,10 +1477,16 @@ void window_zoom_set(rct_window *w, int zoomLevel) v->zoom++; w->saved_view_x -= v->view_width / 2; w->saved_view_y -= v->view_height / 2; - v->view_width *= 2; + v->view_width *= 2; v->view_height *= 2; } + int dest_x, dest_y; + center_2d_coordinates(saved_map_x, saved_map_y, 14, &dest_x, &dest_y, v); + + w->saved_view_x = dest_x; + w->saved_view_y = dest_y; + // HACK: Prevents the redraw from failing when there is // a window on top of the viewport. window_bring_to_front(w); From a1b8bdfa114386c5c0fbdc07bf6933df7e9e74c0 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Thu, 21 Jul 2016 21:00:29 +0200 Subject: [PATCH 02/10] Make zooming to cursor optional. This adds a checkbox to the interface settings panel to enable zooming around the cursor. If disabled, which it is by default, vanilla RCT2 behaviour is retained. --- data/language/en-GB.txt | 2 ++ src/config.c | 2 +- src/config.h | 1 + src/interface/window.c | 16 +++++++++----- src/localisation/string_ids.h | 3 ++- src/windows/options.c | 39 +++++++++++++++++++++-------------- 6 files changed, 41 insertions(+), 22 deletions(-) diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index b92add2344..38c40b2b71 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -4214,6 +4214,8 @@ STR_5902 :Show bounding boxes STR_5903 :Show paint debug window STR_5904 :Reset date STR_5905 :{SMALLFONT}{BLACK}A map generation tool that automatically creates a custom landscape +STR_5906 :Zoom to cursor position +STR_5907 :{SMALLFONT}{BLACK}When enabled, zooming in will centre around the cursor, as opposed to the screen centre. ############# # Scenarios # diff --git a/src/config.c b/src/config.c index d5ab291413..e67b39c08a 100644 --- a/src/config.c +++ b/src/config.c @@ -227,7 +227,7 @@ config_property_definition _generalDefinitions[] = { { offsetof(general_configuration, last_save_scenario_directory), "last_scenario_directory", CONFIG_VALUE_TYPE_STRING, { .value_string = NULL }, NULL }, { offsetof(general_configuration, last_save_track_directory), "last_track_directory", CONFIG_VALUE_TYPE_STRING, { .value_string = NULL }, NULL }, { offsetof(general_configuration, window_limit), "window_limit", CONFIG_VALUE_TYPE_UINT8, WINDOW_LIMIT_MAX, NULL }, - + { offsetof(general_configuration, zoom_to_cursor), "zoom_to_cursor", CONFIG_VALUE_TYPE_BOOLEAN, false, NULL }, }; config_property_definition _interfaceDefinitions[] = { diff --git a/src/config.h b/src/config.h index e211374c29..ffc28ba085 100644 --- a/src/config.h +++ b/src/config.h @@ -198,6 +198,7 @@ typedef struct general_configuration { utf8string last_save_scenario_directory; utf8string last_save_track_directory; uint8 window_limit; + uint8 zoom_to_cursor; } general_configuration; typedef struct interface_configuration { diff --git a/src/interface/window.c b/src/interface/window.c index e89c141dab..d4d4b4453f 100644 --- a/src/interface/window.c +++ b/src/interface/window.c @@ -1460,8 +1460,11 @@ void window_zoom_set(rct_window *w, int zoomLevel) if (v->zoom == zoomLevel) return; + // Zooming to cursor? Remember where we're pointing at the moment. sint16 saved_map_x, saved_map_y; - window_viewport_get_map_coords_by_cursor(w, &saved_map_x, &saved_map_y); + if (gConfigGeneral.zoom_to_cursor) { + window_viewport_get_map_coords_by_cursor(w, &saved_map_x, &saved_map_y); + } // Zoom in while (v->zoom > zoomLevel) { @@ -1481,11 +1484,14 @@ void window_zoom_set(rct_window *w, int zoomLevel) v->view_height *= 2; } - int dest_x, dest_y; - center_2d_coordinates(saved_map_x, saved_map_y, 14, &dest_x, &dest_y, v); + // Zooming to cursor? Centre around the tile we were hovering over just now. + if (gConfigGeneral.zoom_to_cursor) { + int dest_x, dest_y; + center_2d_coordinates(saved_map_x, saved_map_y, 14, &dest_x, &dest_y, v); - w->saved_view_x = dest_x; - w->saved_view_y = dest_y; + w->saved_view_x = dest_x; + w->saved_view_y = dest_y; + } // HACK: Prevents the redraw from failing when there is // a window on top of the viewport. diff --git a/src/localisation/string_ids.h b/src/localisation/string_ids.h index db725ab61a..d0613e4dfa 100644 --- a/src/localisation/string_ids.h +++ b/src/localisation/string_ids.h @@ -3336,8 +3336,9 @@ enum { STR_DEBUG_PAINT_SHOW_BOUND_BOXES = 5902, STR_DEBUG_DROPDOWN_DEBUG_PAINT = 5903, STR_CHEAT_RESET_DATE = 5904, - STR_MAP_GENERATOR_TIP = 5905, + STR_ZOOM_TO_CURSOR = 5906, + STR_ZOOM_TO_CURSOR_TIP = 5907, // Have to include resource strings (from scenarios and objects) for the time being now that language is partially working STR_COUNT = 32768 diff --git a/src/windows/options.c b/src/windows/options.c index 8d7692b71b..3a341fbb9d 100644 --- a/src/windows/options.c +++ b/src/windows/options.c @@ -129,6 +129,7 @@ enum WINDOW_OPTIONS_WIDGET_IDX { WIDX_SCREEN_EDGE_SCROLLING, WIDX_TRAP_CURSOR, WIDX_INVERT_DRAG, + WIDX_ZOOM_TO_CURSOR, WIDX_HOTKEY_DROPDOWN, WIDX_THEMES_GROUP, WIDX_THEMES, @@ -269,27 +270,28 @@ static rct_widget window_options_audio_widgets[] = { static rct_widget window_options_controls_and_interface_widgets[] = { MAIN_OPTIONS_WIDGETS, - { WWT_GROUPBOX, 1, 5, 304, 53, 129, STR_CONTROLS_GROUP, STR_NONE }, // Controls group + { WWT_GROUPBOX, 1, 5, 304, 53, 144, STR_CONTROLS_GROUP, STR_NONE }, // Controls group { WWT_CHECKBOX, 2, 10, 299, 68, 79, STR_SCREEN_EDGE_SCROLLING, STR_SCREEN_EDGE_SCROLLING_TIP }, // Edge scrolling { WWT_CHECKBOX, 2, 10, 299, 83, 94, STR_TRAP_MOUSE, STR_TRAP_MOUSE_TIP }, // Trap mouse { WWT_CHECKBOX, 2, 10, 299, 98, 109, STR_INVERT_RIGHT_MOUSE_DRAG, STR_INVERT_RIGHT_MOUSE_DRAG_TIP }, // Invert right mouse dragging - { WWT_DROPDOWN_BUTTON, 1, 26, 185, 113, 124, STR_HOTKEY, STR_HOTKEY_TIP }, // Set hotkeys buttons + { WWT_CHECKBOX, 2, 10, 299, 113, 124, STR_ZOOM_TO_CURSOR, STR_ZOOM_TO_CURSOR_TIP }, // Zoom to cursor + { WWT_DROPDOWN_BUTTON, 1, 26, 185, 128, 139, STR_HOTKEY, STR_HOTKEY_TIP }, // Set hotkeys buttons - { WWT_GROUPBOX, 1, 5, 304, 133, 179, STR_THEMES_GROUP, STR_NONE }, // Toolbar buttons group - { WWT_DROPDOWN, 1, 155, 299, 147, 158, STR_NONE, STR_NONE }, // Themes - { WWT_DROPDOWN_BUTTON, 1, 288, 298, 148, 157, STR_DROPDOWN_GLYPH, STR_CURRENT_THEME_TIP }, - { WWT_DROPDOWN_BUTTON, 1, 10, 145, 163, 174, STR_EDIT_THEMES_BUTTON, STR_EDIT_THEMES_BUTTON_TIP }, // Themes button + { WWT_GROUPBOX, 1, 5, 304, 148, 194, STR_THEMES_GROUP, STR_NONE }, // Toolbar buttons group + { WWT_DROPDOWN, 1, 155, 299, 162, 173, STR_NONE, STR_NONE }, // Themes + { WWT_DROPDOWN_BUTTON, 1, 288, 298, 163, 172, STR_DROPDOWN_GLYPH, STR_CURRENT_THEME_TIP }, + { WWT_DROPDOWN_BUTTON, 1, 10, 145, 178, 189, STR_EDIT_THEMES_BUTTON, STR_EDIT_THEMES_BUTTON_TIP }, // Themes button - { WWT_GROUPBOX, 1, 5, 304, 183, 245, STR_TOOLBAR_BUTTONS_GROUP, STR_NONE }, // Toolbar buttons group - { WWT_CHECKBOX, 2, 10, 145, 214, 225, STR_FINANCES_BUTTON_ON_TOOLBAR, STR_FINANCES_BUTTON_ON_TOOLBAR_TIP }, // Finances - { WWT_CHECKBOX, 2, 10, 145, 229, 240, STR_RESEARCH_BUTTON_ON_TOOLBAR, STR_RESEARCH_BUTTON_ON_TOOLBAR_TIP }, // Research - { WWT_CHECKBOX, 2, 155, 299, 214, 225, STR_CHEATS_BUTTON_ON_TOOLBAR, STR_CHEATS_BUTTON_ON_TOOLBAR_TIP }, // Cheats - { WWT_CHECKBOX, 2, 155, 299, 229, 240, STR_SHOW_RECENT_MESSAGES_ON_TOOLBAR, STR_SHOW_RECENT_MESSAGES_ON_TOOLBAR_TIP }, // Recent messages + { WWT_GROUPBOX, 1, 5, 304, 198, 260, STR_TOOLBAR_BUTTONS_GROUP, STR_NONE }, // Toolbar buttons group + { WWT_CHECKBOX, 2, 10, 145, 229, 240, STR_FINANCES_BUTTON_ON_TOOLBAR, STR_FINANCES_BUTTON_ON_TOOLBAR_TIP }, // Finances + { WWT_CHECKBOX, 2, 10, 145, 244, 255, STR_RESEARCH_BUTTON_ON_TOOLBAR, STR_RESEARCH_BUTTON_ON_TOOLBAR_TIP }, // Research + { WWT_CHECKBOX, 2, 155, 299, 229, 240, STR_CHEATS_BUTTON_ON_TOOLBAR, STR_CHEATS_BUTTON_ON_TOOLBAR_TIP }, // Cheats + { WWT_CHECKBOX, 2, 155, 299, 244, 255, STR_SHOW_RECENT_MESSAGES_ON_TOOLBAR, STR_SHOW_RECENT_MESSAGES_ON_TOOLBAR_TIP }, // Recent messages - { WWT_CHECKBOX, 2, 10, 299, 254, 265, STR_SELECT_BY_TRACK_TYPE, STR_SELECT_BY_TRACK_TYPE_TIP }, // Select by track type - { WWT_DROPDOWN, 2, 155, 299, 269, 280, STR_NONE, STR_NONE }, // Scenario select mode - { WWT_DROPDOWN_BUTTON, 2, 288, 298, 270, 279, STR_DROPDOWN_GLYPH, STR_SCENARIO_GROUPING_TIP }, - { WWT_CHECKBOX, 2, 18, 299, 284, 295, STR_OPTIONS_SCENARIO_UNLOCKING, STR_SCENARIO_UNLOCKING_TIP }, // Unlocking of scenarios + { WWT_CHECKBOX, 2, 10, 299, 269, 280, STR_SELECT_BY_TRACK_TYPE, STR_SELECT_BY_TRACK_TYPE_TIP }, // Select by track type + { WWT_DROPDOWN, 2, 155, 299, 284, 295, STR_NONE, STR_NONE }, // Scenario select mode + { WWT_DROPDOWN_BUTTON, 2, 288, 298, 285, 294, STR_DROPDOWN_GLYPH, STR_SCENARIO_GROUPING_TIP }, + { WWT_CHECKBOX, 2, 18, 299, 299, 310, STR_OPTIONS_SCENARIO_UNLOCKING, STR_SCENARIO_UNLOCKING_TIP }, // Unlocking of scenarios { WIDGETS_END }, }; @@ -491,6 +493,7 @@ static uint32 window_options_page_enabled_widgets[] = { (1 << WIDX_SCREEN_EDGE_SCROLLING) | (1 << WIDX_TRAP_CURSOR) | (1 << WIDX_INVERT_DRAG) | + (1 << WIDX_ZOOM_TO_CURSOR) | (1 << WIDX_HOTKEY_DROPDOWN) | (1 << WIDX_TOOLBAR_SHOW_FINANCES) | (1 << WIDX_TOOLBAR_SHOW_RESEARCH) | @@ -694,6 +697,11 @@ static void window_options_mouseup(rct_window *w, int widgetIndex) SDL_SetWindowGrab(gWindow, gConfigGeneral.trap_cursor ? SDL_TRUE : SDL_FALSE); window_invalidate(w); break; + case WIDX_ZOOM_TO_CURSOR: + gConfigGeneral.zoom_to_cursor ^= 1; + config_save_default(); + window_invalidate(w); + break; case WIDX_TOOLBAR_SHOW_FINANCES: gConfigInterface.toolbar_show_finances ^= 1; config_save_default(); @@ -1556,6 +1564,7 @@ static void window_options_invalidate(rct_window *w) widget_set_checkbox_value(w, WIDX_SCREEN_EDGE_SCROLLING, gConfigGeneral.edge_scrolling); widget_set_checkbox_value(w, WIDX_TRAP_CURSOR, gConfigGeneral.trap_cursor); widget_set_checkbox_value(w, WIDX_INVERT_DRAG, gConfigGeneral.invert_viewport_drag); + widget_set_checkbox_value(w, WIDX_ZOOM_TO_CURSOR, gConfigGeneral.zoom_to_cursor); widget_set_checkbox_value(w, WIDX_TOOLBAR_SHOW_FINANCES, gConfigInterface.toolbar_show_finances); widget_set_checkbox_value(w, WIDX_TOOLBAR_SHOW_RESEARCH, gConfigInterface.toolbar_show_research); widget_set_checkbox_value(w, WIDX_TOOLBAR_SHOW_CHEATS, gConfigInterface.toolbar_show_cheats); From 17cbdf795e6cd87e13e8792c3c67e3132c561844 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Thu, 21 Jul 2016 21:51:39 +0200 Subject: [PATCH 03/10] Missing header declaration for gcc. --- src/interface/window.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/interface/window.h b/src/interface/window.h index fa7d8a75a8..c97f68c45c 100644 --- a/src/interface/window.h +++ b/src/interface/window.h @@ -574,6 +574,7 @@ rct_window *window_get_main(); void window_scroll_to_viewport(rct_window *w); void window_scroll_to_location(rct_window *w, int x, int y, int z); void window_rotate_camera(rct_window *w, int direction); +void window_viewport_get_map_coords_by_cursor(rct_window *w, sint16 *map_x, sint16 *map_y); void window_zoom_set(rct_window *w, int zoomLevel); void window_zoom_in(rct_window *w); void window_zoom_out(rct_window *w); From f035bfdecdd3e1d9e90290e72ab9e907e38d7b5c Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Fri, 22 Jul 2016 01:01:24 +0200 Subject: [PATCH 04/10] Try to keep the current tile under the mouse cursor. This still doesn't work as well as I'd like yet, most notably when zooming out. --- src/interface/window.c | 24 +++++++++++++++++++----- src/interface/window.h | 1 + 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/interface/window.c b/src/interface/window.c index d4d4b4453f..25c1eed9dd 100644 --- a/src/interface/window.c +++ b/src/interface/window.c @@ -1452,6 +1452,24 @@ void window_viewport_get_map_coords_by_cursor(rct_window *w, sint16 *map_x, sint get_map_coordinates_from_pos(mouse_x, mouse_y, VIEWPORT_INTERACTION_MASK_NONE, map_x, map_y, NULL, NULL, NULL); } +void window_viewport_centre_tile_around_cursor(rct_window *w, sint16 map_x, sint16 map_y) +{ + // Get viewport coordinates centring around the tile. + int dest_x, dest_y; + center_2d_coordinates(map_x, map_y, 14, &dest_x, &dest_y, w->viewport); + + // Get mouse position to offset against. + int mouse_x, mouse_y; + platform_get_cursor_position(&mouse_x, &mouse_y); + + // Rebase mouse position onto centre of window. + int rebased_x = (w->width >> 1) - mouse_x, + rebased_y = (w->height >> 1) - mouse_y; + + w->saved_view_x = dest_x + rebased_x; + w->saved_view_y = dest_y + rebased_y; +} + void window_zoom_set(rct_window *w, int zoomLevel) { rct_viewport* v = w->viewport; @@ -1486,11 +1504,7 @@ void window_zoom_set(rct_window *w, int zoomLevel) // Zooming to cursor? Centre around the tile we were hovering over just now. if (gConfigGeneral.zoom_to_cursor) { - int dest_x, dest_y; - center_2d_coordinates(saved_map_x, saved_map_y, 14, &dest_x, &dest_y, v); - - w->saved_view_x = dest_x; - w->saved_view_y = dest_y; + window_viewport_centre_tile_around_cursor(w, saved_map_x, saved_map_y); } // HACK: Prevents the redraw from failing when there is diff --git a/src/interface/window.h b/src/interface/window.h index c97f68c45c..2774060d88 100644 --- a/src/interface/window.h +++ b/src/interface/window.h @@ -575,6 +575,7 @@ void window_scroll_to_viewport(rct_window *w); void window_scroll_to_location(rct_window *w, int x, int y, int z); void window_rotate_camera(rct_window *w, int direction); void window_viewport_get_map_coords_by_cursor(rct_window *w, sint16 *map_x, sint16 *map_y); +void window_viewport_centre_tile_around_cursor(rct_window *w, sint16 map_x, sint16 map_y); void window_zoom_set(rct_window *w, int zoomLevel); void window_zoom_in(rct_window *w); void window_zoom_out(rct_window *w); From ccdd7bec4fedbb991c79fdf0f8fec2b20934a346 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Fri, 22 Jul 2016 10:47:07 +0200 Subject: [PATCH 05/10] Compensate for zoom level and base height. --- src/interface/window.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/interface/window.c b/src/interface/window.c index 25c1eed9dd..c4ed8cdd92 100644 --- a/src/interface/window.c +++ b/src/interface/window.c @@ -1456,7 +1456,8 @@ void window_viewport_centre_tile_around_cursor(rct_window *w, sint16 map_x, sint { // Get viewport coordinates centring around the tile. int dest_x, dest_y; - center_2d_coordinates(map_x, map_y, 14, &dest_x, &dest_y, w->viewport); + int base_height = map_element_height(map_x, map_y); + center_2d_coordinates(map_x, map_y, base_height, &dest_x, &dest_y, w->viewport); // Get mouse position to offset against. int mouse_x, mouse_y; @@ -1466,6 +1467,11 @@ void window_viewport_centre_tile_around_cursor(rct_window *w, sint16 map_x, sint int rebased_x = (w->width >> 1) - mouse_x, rebased_y = (w->height >> 1) - mouse_y; + // Compensate for zoom level. + rebased_x <<= w->viewport->zoom; + rebased_y <<= w->viewport->zoom; + + // Apply offset to the viewport. w->saved_view_x = dest_x + rebased_x; w->saved_view_y = dest_y + rebased_y; } From 7c12c48bfd2db209d918845c4b46e70e5d9c2253 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Fri, 22 Jul 2016 10:52:57 +0200 Subject: [PATCH 06/10] Add changelog entry. [ci skip] --- distribution/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 22690aad66..0a4e9fff49 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -19,6 +19,7 @@ - Feature: Add console command to set scenario initial cash. - Feature: Objects are scanned from the user directory as well as the RCT2 directory. - Feature: Objects directory is scanned recursively. +- Feature: Optionally zoom in towards the cursor rather than the screen centre. - Improve: Performance and reliability of loading objects. - Improve: Screenshots are now saved with the name of the park and the current date and time. - Improve: More accurate frame rate calculation From 34bef11f7578b5f4158b9966784f272e033657e0 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Fri, 22 Jul 2016 12:09:38 +0200 Subject: [PATCH 07/10] Compensate mouse position for window scaling. --- src/interface/window.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/interface/window.c b/src/interface/window.c index c4ed8cdd92..716aefb020 100644 --- a/src/interface/window.c +++ b/src/interface/window.c @@ -1449,6 +1449,11 @@ void window_viewport_get_map_coords_by_cursor(rct_window *w, sint16 *map_x, sint { int mouse_x, mouse_y; platform_get_cursor_position(&mouse_x, &mouse_y); + + // Compensate for window scaling. + mouse_x = (int) ceilf(mouse_x / gConfigGeneral.window_scale); + mouse_y = (int) ceilf(mouse_y / gConfigGeneral.window_scale); + get_map_coordinates_from_pos(mouse_x, mouse_y, VIEWPORT_INTERACTION_MASK_NONE, map_x, map_y, NULL, NULL, NULL); } @@ -1463,6 +1468,10 @@ void window_viewport_centre_tile_around_cursor(rct_window *w, sint16 map_x, sint int mouse_x, mouse_y; platform_get_cursor_position(&mouse_x, &mouse_y); + // Compensate for window scaling. + mouse_x = (int) ceilf(mouse_x / gConfigGeneral.window_scale); + mouse_y = (int) ceilf(mouse_y / gConfigGeneral.window_scale); + // Rebase mouse position onto centre of window. int rebased_x = (w->width >> 1) - mouse_x, rebased_y = (w->height >> 1) - mouse_y; From 1755fa433fe8dc903556ab987826aea6e85726ee Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Fri, 22 Jul 2016 16:07:14 +0200 Subject: [PATCH 08/10] Enable zoom to cursor by default. --- src/config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.c b/src/config.c index e67b39c08a..c85c76d76d 100644 --- a/src/config.c +++ b/src/config.c @@ -227,7 +227,7 @@ config_property_definition _generalDefinitions[] = { { offsetof(general_configuration, last_save_scenario_directory), "last_scenario_directory", CONFIG_VALUE_TYPE_STRING, { .value_string = NULL }, NULL }, { offsetof(general_configuration, last_save_track_directory), "last_track_directory", CONFIG_VALUE_TYPE_STRING, { .value_string = NULL }, NULL }, { offsetof(general_configuration, window_limit), "window_limit", CONFIG_VALUE_TYPE_UINT8, WINDOW_LIMIT_MAX, NULL }, - { offsetof(general_configuration, zoom_to_cursor), "zoom_to_cursor", CONFIG_VALUE_TYPE_BOOLEAN, false, NULL }, + { offsetof(general_configuration, zoom_to_cursor), "zoom_to_cursor", CONFIG_VALUE_TYPE_BOOLEAN, true, NULL }, }; config_property_definition _interfaceDefinitions[] = { From 8ac1b79799e966e6b9089ce56109d9f4dc2383c7 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Sat, 30 Jul 2016 21:02:54 +0200 Subject: [PATCH 09/10] Remember and apply cursor position relative to tile. --- src/interface/window.c | 34 +++++++++++++++++++++++++++------- src/interface/window.h | 4 ++-- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/interface/window.c b/src/interface/window.c index 716aefb020..39267cc5a2 100644 --- a/src/interface/window.c +++ b/src/interface/window.c @@ -1445,7 +1445,7 @@ void window_rotate_camera(rct_window *w, int direction) reset_all_sprite_quadrant_placements(); } -void window_viewport_get_map_coords_by_cursor(rct_window *w, sint16 *map_x, sint16 *map_y) +void window_viewport_get_map_coords_by_cursor(rct_window *w, sint16 *map_x, sint16 *map_y, sint16 *offset_x, sint16 *offset_y) { int mouse_x, mouse_y; platform_get_cursor_position(&mouse_x, &mouse_y); @@ -1455,9 +1455,29 @@ void window_viewport_get_map_coords_by_cursor(rct_window *w, sint16 *map_x, sint mouse_y = (int) ceilf(mouse_y / gConfigGeneral.window_scale); get_map_coordinates_from_pos(mouse_x, mouse_y, VIEWPORT_INTERACTION_MASK_NONE, map_x, map_y, NULL, NULL, NULL); + + // Get viewport coordinates centring around the tile. + int base_height = map_element_height(*map_x, *map_y); + int dest_x, dest_y; + center_2d_coordinates(*map_x, *map_y, base_height, &dest_x, &dest_y, w->viewport); + + // Rebase mouse position onto centre of window. + int rebased_x = (w->width >> 1) - mouse_x, + rebased_y = (w->height >> 1) - mouse_y; + + // Compensate for zoom level. + rebased_x <<= w->viewport->zoom; + rebased_y <<= w->viewport->zoom; + + // Apply offset to the viewport. + int new_x = dest_x + rebased_x, + new_y = dest_y + rebased_y; + + *offset_x = (w->saved_view_x - new_x) << w->viewport->zoom, + *offset_y = (w->saved_view_y - new_y) << w->viewport->zoom; } -void window_viewport_centre_tile_around_cursor(rct_window *w, sint16 map_x, sint16 map_y) +void window_viewport_centre_tile_around_cursor(rct_window *w, sint16 map_x, sint16 map_y, sint16 offset_x, sint16 offset_y) { // Get viewport coordinates centring around the tile. int dest_x, dest_y; @@ -1481,8 +1501,8 @@ void window_viewport_centre_tile_around_cursor(rct_window *w, sint16 map_x, sint rebased_y <<= w->viewport->zoom; // Apply offset to the viewport. - w->saved_view_x = dest_x + rebased_x; - w->saved_view_y = dest_y + rebased_y; + w->saved_view_x = dest_x + rebased_x + (offset_x >> w->viewport->zoom); + w->saved_view_y = dest_y + rebased_y + (offset_y >> w->viewport->zoom); } void window_zoom_set(rct_window *w, int zoomLevel) @@ -1494,9 +1514,9 @@ void window_zoom_set(rct_window *w, int zoomLevel) return; // Zooming to cursor? Remember where we're pointing at the moment. - sint16 saved_map_x, saved_map_y; + sint16 saved_map_x, saved_map_y, offset_x, offset_y; if (gConfigGeneral.zoom_to_cursor) { - window_viewport_get_map_coords_by_cursor(w, &saved_map_x, &saved_map_y); + window_viewport_get_map_coords_by_cursor(w, &saved_map_x, &saved_map_y, &offset_x, &offset_y); } // Zoom in @@ -1519,7 +1539,7 @@ void window_zoom_set(rct_window *w, int zoomLevel) // Zooming to cursor? Centre around the tile we were hovering over just now. if (gConfigGeneral.zoom_to_cursor) { - window_viewport_centre_tile_around_cursor(w, saved_map_x, saved_map_y); + window_viewport_centre_tile_around_cursor(w, saved_map_x, saved_map_y, offset_x, offset_y); } // HACK: Prevents the redraw from failing when there is diff --git a/src/interface/window.h b/src/interface/window.h index 2774060d88..1802060697 100644 --- a/src/interface/window.h +++ b/src/interface/window.h @@ -574,8 +574,8 @@ rct_window *window_get_main(); void window_scroll_to_viewport(rct_window *w); void window_scroll_to_location(rct_window *w, int x, int y, int z); void window_rotate_camera(rct_window *w, int direction); -void window_viewport_get_map_coords_by_cursor(rct_window *w, sint16 *map_x, sint16 *map_y); -void window_viewport_centre_tile_around_cursor(rct_window *w, sint16 map_x, sint16 map_y); +void window_viewport_get_map_coords_by_cursor(rct_window *w, sint16 *map_x, sint16 *map_y, sint16 *offset_x, sint16 *offset_y); +void window_viewport_centre_tile_around_cursor(rct_window *w, sint16 map_x, sint16 map_y, sint16 offset_x, sint16 offset_y); void window_zoom_set(rct_window *w, int zoomLevel); void window_zoom_in(rct_window *w); void window_zoom_out(rct_window *w); From 29b0b4885ea733535a75c47bdc00cc43370f0c98 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Sat, 30 Jul 2016 21:42:21 +0200 Subject: [PATCH 10/10] Reduce code verbosity. This introduces the function `platform_get_cursor_position_scaled` as a common means of getting the cursor position compensated for window scaling. --- src/interface/window.c | 43 +++++++++++++---------------------------- src/platform/platform.h | 1 + src/platform/shared.c | 9 +++++++++ 3 files changed, 23 insertions(+), 30 deletions(-) diff --git a/src/interface/window.c b/src/interface/window.c index 39267cc5a2..2fc1a323f7 100644 --- a/src/interface/window.c +++ b/src/interface/window.c @@ -1447,13 +1447,11 @@ void window_rotate_camera(rct_window *w, int direction) void window_viewport_get_map_coords_by_cursor(rct_window *w, sint16 *map_x, sint16 *map_y, sint16 *offset_x, sint16 *offset_y) { + // Get mouse position to offset against. int mouse_x, mouse_y; - platform_get_cursor_position(&mouse_x, &mouse_y); - - // Compensate for window scaling. - mouse_x = (int) ceilf(mouse_x / gConfigGeneral.window_scale); - mouse_y = (int) ceilf(mouse_y / gConfigGeneral.window_scale); + platform_get_cursor_position_scaled(&mouse_x, &mouse_y); + // Compute map coordinate by mouse position. get_map_coordinates_from_pos(mouse_x, mouse_y, VIEWPORT_INTERACTION_MASK_NONE, map_x, map_y, NULL, NULL, NULL); // Get viewport coordinates centring around the tile. @@ -1461,20 +1459,13 @@ void window_viewport_get_map_coords_by_cursor(rct_window *w, sint16 *map_x, sint int dest_x, dest_y; center_2d_coordinates(*map_x, *map_y, base_height, &dest_x, &dest_y, w->viewport); - // Rebase mouse position onto centre of window. - int rebased_x = (w->width >> 1) - mouse_x, - rebased_y = (w->height >> 1) - mouse_y; + // Rebase mouse position onto centre of window, and compensate for zoom level. + int rebased_x = ((w->width >> 1) - mouse_x) << w->viewport->zoom, + rebased_y = ((w->height >> 1) - mouse_y) << w->viewport->zoom; - // Compensate for zoom level. - rebased_x <<= w->viewport->zoom; - rebased_y <<= w->viewport->zoom; - - // Apply offset to the viewport. - int new_x = dest_x + rebased_x, - new_y = dest_y + rebased_y; - - *offset_x = (w->saved_view_x - new_x) << w->viewport->zoom, - *offset_y = (w->saved_view_y - new_y) << w->viewport->zoom; + // Compute cursor offset relative to tile. + *offset_x = (w->saved_view_x - (dest_x + rebased_x)) << w->viewport->zoom; + *offset_y = (w->saved_view_y - (dest_y + rebased_y)) << w->viewport->zoom; } void window_viewport_centre_tile_around_cursor(rct_window *w, sint16 map_x, sint16 map_y, sint16 offset_x, sint16 offset_y) @@ -1486,19 +1477,11 @@ void window_viewport_centre_tile_around_cursor(rct_window *w, sint16 map_x, sint // Get mouse position to offset against. int mouse_x, mouse_y; - platform_get_cursor_position(&mouse_x, &mouse_y); + platform_get_cursor_position_scaled(&mouse_x, &mouse_y); - // Compensate for window scaling. - mouse_x = (int) ceilf(mouse_x / gConfigGeneral.window_scale); - mouse_y = (int) ceilf(mouse_y / gConfigGeneral.window_scale); - - // Rebase mouse position onto centre of window. - int rebased_x = (w->width >> 1) - mouse_x, - rebased_y = (w->height >> 1) - mouse_y; - - // Compensate for zoom level. - rebased_x <<= w->viewport->zoom; - rebased_y <<= w->viewport->zoom; + // Rebase mouse position onto centre of window, and compensate for zoom level. + int rebased_x = ((w->width >> 1) - mouse_x) << w->viewport->zoom, + rebased_y = ((w->height >> 1) - mouse_y) << w->viewport->zoom; // Apply offset to the viewport. w->saved_view_x = dest_x + rebased_x + (offset_x >> w->viewport->zoom); diff --git a/src/platform/platform.h b/src/platform/platform.h index c85e1ec33d..88ad8d3bf9 100644 --- a/src/platform/platform.h +++ b/src/platform/platform.h @@ -166,6 +166,7 @@ bool platform_file_delete(const utf8 *path); void platform_hide_cursor(); void platform_show_cursor(); void platform_get_cursor_position(int *x, int *y); +void platform_get_cursor_position_scaled(int *x, int *y); void platform_set_cursor_position(int x, int y); unsigned int platform_get_ticks(); void platform_resolve_user_data_path(); diff --git a/src/platform/shared.c b/src/platform/shared.c index 83f28719b4..50eccbf2e0 100644 --- a/src/platform/shared.c +++ b/src/platform/shared.c @@ -783,6 +783,15 @@ void platform_get_cursor_position(int *x, int *y) SDL_GetMouseState(x, y); } +void platform_get_cursor_position_scaled(int *x, int *y) +{ + platform_get_cursor_position(x, y); + + // Compensate for window scaling. + *x = (int) ceilf(*x / gConfigGeneral.window_scale); + *y = (int) ceilf(*y / gConfigGeneral.window_scale); +} + void platform_set_cursor_position(int x, int y) { SDL_WarpMouseInWindow(NULL, x, y);