diff --git a/src/interface/viewport.c b/src/interface/viewport.c index bfd2850113..6bbe12d1f8 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -2075,56 +2075,13 @@ void viewport_paint(rct_viewport* viewport, rct_drawpixelinfo* dpi, int left, in } } -/** - * - * rct2: 0x00688972 - * In: - * screen_x: eax - * screen_y: ebx - * Out: - * x: ax - * y: bx - * map_element: edx ? - * viewport: edi - */ -void sub_688972(int screenX, int screenY, sint16 *x, sint16 *y, rct_viewport **viewport) { - sint16 my_x, my_y; - int z, interactionType; - rct_viewport *myViewport; - get_map_coordinates_from_pos(screenX, screenY, VIEWPORT_INTERACTION_MASK_TERRAIN, &my_x, &my_y, &interactionType, NULL, &myViewport); - if (interactionType == VIEWPORT_INTERACTION_ITEM_NONE) { - *x = 0x8000; - return; - } - - RCT2_GLOBAL(0x00F1AD34, sint16) = my_x; - RCT2_GLOBAL(0x00F1AD36, sint16) = my_y; - RCT2_GLOBAL(0x00F1AD38, sint16) = my_x + 31; - RCT2_GLOBAL(0x00F1AD3A, sint16) = my_y + 31; - - rct_xy16 start_vp_pos = screen_coord_to_viewport_coord(myViewport, screenX, screenY); - rct_xy16 map_pos = { my_x + 16, my_y + 16 }; - - for (int i = 0; i < 5; i++) { - z = map_element_height(map_pos.x, map_pos.y); - map_pos = viewport_coord_to_map_coord(start_vp_pos.x, start_vp_pos.y, z); - map_pos.x = clamp(RCT2_GLOBAL(0x00F1AD34, sint16), map_pos.x, RCT2_GLOBAL(0x00F1AD38, sint16)); - map_pos.y = clamp(RCT2_GLOBAL(0x00F1AD36, sint16), map_pos.y, RCT2_GLOBAL(0x00F1AD3A, sint16)); - } - - *x = map_pos.x; - *y = map_pos.y; - - if (viewport != NULL) *viewport = myViewport; -} - /** * * rct2: 0x0068958D */ void screen_pos_to_map_pos(sint16 *x, sint16 *y, int *direction) { - sub_688972(*x, *y, x, y, NULL); + screen_get_map_xy(*x, *y, x, y, NULL); if (*x == (sint16)0x8000) return; @@ -2532,11 +2489,54 @@ rct_viewport *viewport_find_from_point(int screenX, int screenY) return viewport; } +/** + * + * rct2: 0x00688972 + * In: + * screen_x: eax + * screen_y: ebx + * Out: + * x: ax + * y: bx + * map_element: edx ? + * viewport: edi + */ +void screen_get_map_xy(int screenX, int screenY, sint16 *x, sint16 *y, rct_viewport **viewport) { + sint16 my_x, my_y; + int z, interactionType; + rct_viewport *myViewport; + get_map_coordinates_from_pos(screenX, screenY, VIEWPORT_INTERACTION_MASK_TERRAIN, &my_x, &my_y, &interactionType, NULL, &myViewport); + if (interactionType == VIEWPORT_INTERACTION_ITEM_NONE) { + *x = 0x8000; + return; + } + + RCT2_GLOBAL(0x00F1AD34, sint16) = my_x; + RCT2_GLOBAL(0x00F1AD36, sint16) = my_y; + RCT2_GLOBAL(0x00F1AD38, sint16) = my_x + 31; + RCT2_GLOBAL(0x00F1AD3A, sint16) = my_y + 31; + + rct_xy16 start_vp_pos = screen_coord_to_viewport_coord(myViewport, screenX, screenY); + rct_xy16 map_pos = { my_x + 16, my_y + 16 }; + + for (int i = 0; i < 5; i++) { + z = map_element_height(map_pos.x, map_pos.y); + map_pos = viewport_coord_to_map_coord(start_vp_pos.x, start_vp_pos.y, z); + map_pos.x = clamp(RCT2_GLOBAL(0x00F1AD34, sint16), map_pos.x, RCT2_GLOBAL(0x00F1AD38, sint16)); + map_pos.y = clamp(RCT2_GLOBAL(0x00F1AD36, sint16), map_pos.y, RCT2_GLOBAL(0x00F1AD3A, sint16)); + } + + *x = map_pos.x; + *y = map_pos.y; + + if (viewport != NULL) *viewport = myViewport; +} + /** * * rct2: 0x006894D4 */ -void sub_6894D4(sint16 screenX, sint16 screenY, sint16 z, sint16 *mapX, sint16 *mapY) +void screen_get_map_xy_with_z(sint16 screenX, sint16 screenY, sint16 z, sint16 *mapX, sint16 *mapY) { rct_viewport *viewport = viewport_find_from_point(screenX, screenY); if (viewport == NULL) { @@ -2556,3 +2556,67 @@ void sub_6894D4(sint16 screenX, sint16 screenY, sint16 z, sint16 *mapX, sint16 * *mapX = mapPosition.x; *mapY = mapPosition.y; } + +/** + * + * rct2: 0x00689604 + */ +void screen_get_map_xy_quadrant(sint16 screenX, sint16 screenY, sint16 *mapX, sint16 *mapY, uint8 *quadrant) +{ + rct_viewport *viewport; + + screen_get_map_xy(screenX, screenY, mapX, mapY, &viewport); + if (*mapX == (sint16)0x8000) + return; + + *quadrant = map_get_tile_quadrant(*mapX, *mapY); + *mapX = floor2(*mapX, 32); + *mapY = floor2(*mapY, 32); +} + +/** + * + * rct2: 0x0068964B + */ +void screen_get_map_xy_quadrant_with_z(sint16 screenX, sint16 screenY, sint16 z, sint16 *mapX, sint16 *mapY, uint8 *quadrant) +{ + screen_get_map_xy_with_z(screenX, screenY, z, mapX, mapY); + if (*mapX == (sint16)0x8000) + return; + + *quadrant = map_get_tile_quadrant(*mapX, *mapY); + *mapX = floor2(*mapX, 32); + *mapY = floor2(*mapY, 32); +} + +/** + * + * rct2: 0x00689692 + */ +void screen_get_map_xy_side(sint16 screenX, sint16 screenY, sint16 *mapX, sint16 *mapY, uint8 *side) +{ + rct_viewport *viewport; + + screen_get_map_xy(screenX, screenY, mapX, mapY, &viewport); + if (*mapX == (sint16)0x8000) + return; + + *side = map_get_tile_side(*mapX, *mapY); + *mapX = floor2(*mapX, 32); + *mapY = floor2(*mapY, 32); +} + +/** + * + * rct2: 0x006896DC + */ +void screen_get_map_xy_side_with_z(sint16 screenX, sint16 screenY, sint16 z, sint16 *mapX, sint16 *mapY, uint8 *side) +{ + screen_get_map_xy_with_z(screenX, screenY, z, mapX, mapY); + if (*mapX == (sint16)0x8000) + return; + + *side = map_get_tile_side(*mapX, *mapY); + *mapX = floor2(*mapX, 32); + *mapY = floor2(*mapY, 32); +} diff --git a/src/interface/viewport.h b/src/interface/viewport.h index 529822f742..2d3abbd5a3 100644 --- a/src/interface/viewport.h +++ b/src/interface/viewport.h @@ -104,7 +104,6 @@ void sub_689174(sint16* x, sint16* y, sint16 *z); rct_xy16 screen_coord_to_viewport_coord(rct_viewport *viewport, uint16 x, uint16 y); rct_xy16 viewport_coord_to_map_coord(int x, int y, int z); -void sub_688972(int screenX, int screenY, sint16 *x, sint16 *y, rct_viewport **viewport); void screen_pos_to_map_pos(sint16 *x, sint16 *y, int *direction); void show_gridlines(); @@ -133,6 +132,11 @@ void sub_688217(); void viewport_invalidate(rct_viewport *viewport, int left, int top, int right, int bottom); -void sub_6894D4(sint16 screenX, sint16 screenY, sint16 z, sint16 *mapX, sint16 *mapY); +void screen_get_map_xy(int screenX, int screenY, sint16 *x, sint16 *y, rct_viewport **viewport); +void screen_get_map_xy_with_z(sint16 screenX, sint16 screenY, sint16 z, sint16 *mapX, sint16 *mapY); +void screen_get_map_xy_quadrant(sint16 screenX, sint16 screenY, sint16 *mapX, sint16 *mapY, uint8 *quadrant); +void screen_get_map_xy_quadrant_with_z(sint16 screenX, sint16 screenY, sint16 z, sint16 *mapX, sint16 *mapY, uint8 *quadrant); +void screen_get_map_xy_side(sint16 screenX, sint16 screenY, sint16 *mapX, sint16 *mapY, uint8 *side); +void screen_get_map_xy_side_with_z(sint16 screenX, sint16 screenY, sint16 z, sint16 *mapX, sint16 *mapY, uint8 *side); #endif diff --git a/src/interface/window.c b/src/interface/window.c index 6f6221de8f..66b34b756c 100644 --- a/src/interface/window.c +++ b/src/interface/window.c @@ -1374,7 +1374,7 @@ void window_rotate_camera(rct_window *w, int direction) //has something to do with checking if middle of the viewport is obstructed rct_viewport *other; - sub_688972(x, y, &x, &y, &other); + screen_get_map_xy(x, y, &x, &y, &other); // other != viewport probably triggers on viewports in ride or guest window? // x is 0x8000 if middle of viewport is obstructed by another window? diff --git a/src/ride/ride.c b/src/ride/ride.c index 2e83c14e4f..ef1a305386 100644 --- a/src/ride/ride.c +++ b/src/ride/ride.c @@ -5121,7 +5121,7 @@ void ride_get_entrance_or_exit_position_from_screen_position(int screenX, int sc ride = GET_RIDE(RCT2_GLOBAL(0x00F44192, uint8)); stationHeight = ride->station_heights[RCT2_GLOBAL(0x00F44193, uint8)]; - sub_6894D4(screenX, screenY, stationHeight * 8, &mapX, &mapY); + screen_get_map_xy_with_z(screenX, screenY, stationHeight * 8, &mapX, &mapY); if (mapX == (short)0x8000) { *outX = 0x8000; return; diff --git a/src/windows/map.c b/src/windows/map.c index d19a11a47a..d8d39826bd 100644 --- a/src/windows/map.c +++ b/src/windows/map.c @@ -1140,7 +1140,7 @@ static void window_map_set_land_rights_tool_update(int x, int y) map_invalidate_selection_rect(); RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~(1 << 0); - sub_688972(x, y, &mapX, &mapY, &viewport); + screen_get_map_xy(x, y, &mapX, &mapY, &viewport); if (mapX == (sint16)0x8000) return; diff --git a/src/windows/park.c b/src/windows/park.c index 6eb5fe929e..c078d91c10 100644 --- a/src/windows/park.c +++ b/src/windows/park.c @@ -734,7 +734,7 @@ void window_park_entrance_tool_update_land_rights(sint16 x, sint16 y){ RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~(1 << 0); rct_xy16 mapTile = { 0 }; - sub_688972(x, y, &mapTile.x, &mapTile.y, NULL); + screen_get_map_xy(x, y, &mapTile.x, &mapTile.y, NULL); if (mapTile.x == (sint16)0x8000){ if (RCT2_GLOBAL(0x00F1AD62, money32) != MONEY32_UNDEFINED){ diff --git a/src/windows/ride_construction.c b/src/windows/ride_construction.c index e6bb6e2ad8..80a45d4668 100644 --- a/src/windows/ride_construction.c +++ b/src/windows/ride_construction.c @@ -1956,7 +1956,7 @@ static bool ride_get_place_position_from_screen_position(int screenX, int screen } } else { mapZ = _trackPlaceCtrlZ; - sub_6894D4(screenX, screenY, mapZ, &mapX, &mapY); + screen_get_map_xy_with_z(screenX, screenY, mapZ, &mapX, &mapY); if (_trackPlaceShiftState != 0) { mapZ += _trackPlaceShiftZ; } diff --git a/src/windows/top_toolbar.c b/src/windows/top_toolbar.c index 0f2f0114cc..5694318419 100644 --- a/src/windows/top_toolbar.c +++ b/src/windows/top_toolbar.c @@ -894,46 +894,6 @@ static void repaint_scenery_tool_down(sint16 x, sint16 y, sint16 widgetIndex){ } } -void sub_689604(sint16 x, sint16 y, sint16* grid_x, sint16* grid_y, uint8* cl){ - int eax = x, ebx = y, ecx = 0, edx = 0, esi = 0, edi = 0, ebp = 0; - - RCT2_CALLFUNC_X(0x00689604, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - - *grid_x = eax; - *grid_y = ebx; - *cl = ecx; -} - -void sub_68964B(sint16 x, sint16 y, sint16 z, sint16* grid_x, sint16* grid_y, uint8* cl){ - int eax = x, ebx = y, ecx = 0, edx = 0, esi = 0, edi = 0, ebp = z; - - RCT2_CALLFUNC_X(0x0068964B, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - - *grid_x = eax; - *grid_y = ebx; - *cl = ecx; -} - -void sub_689692(sint16 x, sint16 y, sint16* grid_x, sint16* grid_y, uint8* cl){ - int eax = x, ebx = y, ecx = 0, edx = 0, esi = 0, edi = 0, ebp = 0; - - RCT2_CALLFUNC_X(0x00689692, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - - *grid_x = eax; - *grid_y = ebx; - *cl = ecx; -} - -void sub_6896DC(sint16 x, sint16 y, sint16 z, sint16* grid_x, sint16* grid_y, uint8* cl){ - int eax = x, ebx = y, ecx = 0, edx = 0, esi = 0, edi = 0, ebp = z; - - RCT2_CALLFUNC_X(0x006896DC, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - - *grid_x = eax; - *grid_y = ebx; - *cl = ecx; -} - /* rct2: 0x006E1F34 * Outputs * eax : grid_x @@ -1033,7 +993,7 @@ void sub_6E1F34(sint16 x, sint16 y, uint16 selected_scenery, sint16* grid_x, sin // If CTRL not pressed if (RCT2_GLOBAL(RCT2_ADDRESS_SCENERY_TOOL_CTRL_PRESSED, uint8) == 0){ - sub_689604(x, y, grid_x, grid_y, &cl); + screen_get_map_xy_quadrant(x, y, grid_x, grid_y, &cl); if (*grid_x == (sint16)0x8000) return; @@ -1063,7 +1023,7 @@ void sub_6E1F34(sint16 x, sint16 y, uint16 selected_scenery, sint16* grid_x, sin else{ sint16 z = RCT2_GLOBAL(RCT2_ADDRESS_CTRL_PRESS_Z_COORDINATE, sint16); - sub_68964B(x, y, z, grid_x, grid_y, &cl); + screen_get_map_xy_quadrant_with_z(x, y, z, grid_x, grid_y, &cl); // If SHIFT pressed if (RCT2_GLOBAL(RCT2_ADDRESS_SCENERY_TOOL_SHIFT_PRESSED, uint8) != 0){ @@ -1139,7 +1099,7 @@ void sub_6E1F34(sint16 x, sint16 y, uint16 selected_scenery, sint16* grid_x, sin } else{ sint16 z = RCT2_GLOBAL(RCT2_ADDRESS_CTRL_PRESS_Z_COORDINATE, sint16); - sub_6894D4(x, y, z, grid_x, grid_y); + screen_get_map_xy_with_z(x, y, z, grid_x, grid_y); // If SHIFT pressed if (RCT2_GLOBAL(RCT2_ADDRESS_SCENERY_TOOL_SHIFT_PRESSED, uint8) != 0){ @@ -1205,7 +1165,7 @@ void sub_6E1F34(sint16 x, sint16 y, uint16 selected_scenery, sint16* grid_x, sin uint8 cl; // If CTRL not pressed if (RCT2_GLOBAL(RCT2_ADDRESS_SCENERY_TOOL_CTRL_PRESSED, uint8) == 0){ - sub_689692(x, y, grid_x, grid_y, &cl); + screen_get_map_xy_side(x, y, grid_x, grid_y, &cl); if (*grid_x == (sint16)0x8000) return; @@ -1233,7 +1193,7 @@ void sub_6E1F34(sint16 x, sint16 y, uint16 selected_scenery, sint16* grid_x, sin } else{ sint16 z = RCT2_GLOBAL(RCT2_ADDRESS_CTRL_PRESS_Z_COORDINATE, sint16); - sub_6896DC(x, y, z, grid_x, grid_y, &cl); + screen_get_map_xy_side_with_z(x, y, z, grid_x, grid_y, &cl); // If SHIFT pressed if (RCT2_GLOBAL(RCT2_ADDRESS_SCENERY_TOOL_SHIFT_PRESSED, uint8) != 0){ @@ -1292,7 +1252,7 @@ void sub_6E1F34(sint16 x, sint16 y, uint16 selected_scenery, sint16* grid_x, sin } else{ sint16 z = RCT2_GLOBAL(RCT2_ADDRESS_CTRL_PRESS_Z_COORDINATE, sint16); - sub_6894D4(x, y, z, grid_x, grid_y); + screen_get_map_xy_with_z(x, y, z, grid_x, grid_y); // If SHIFT pressed if (RCT2_GLOBAL(RCT2_ADDRESS_SCENERY_TOOL_SHIFT_PRESSED, uint8) != 0){ @@ -1593,7 +1553,7 @@ void top_toolbar_tool_update_scenery_clear(sint16 x, sint16 y){ RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~(1 << 0); rct_xy16 mapTile = { 0 }; - sub_688972(x, y, &mapTile.x, &mapTile.y, NULL); + screen_get_map_xy(x, y, &mapTile.x, &mapTile.y, NULL); if (mapTile.x == (sint16)0x8000){ if (RCT2_GLOBAL(0x00F1AD62, money32) != MONEY32_UNDEFINED){ @@ -1674,7 +1634,7 @@ void top_toolbar_tool_update_land_paint(sint16 x, sint16 y){ RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~(1 << 0); rct_xy16 mapTile = { 0 }; - sub_688972(x, y, &mapTile.x, &mapTile.y, NULL); + screen_get_map_xy(x, y, &mapTile.x, &mapTile.y, NULL); if (mapTile.x == (sint16)0x8000){ if (RCT2_GLOBAL(0x00F1AD62, money32) != MONEY32_UNDEFINED){ @@ -1829,7 +1789,7 @@ void top_toolbar_tool_update_land(sint16 x, sint16 y){ return; } - sub_688972(x, y, &mapTile.x, &mapTile.y, NULL); + screen_get_map_xy(x, y, &mapTile.x, &mapTile.y, NULL); if (mapTile.x == (sint16)0x8000){ money32 lower_cost = MONEY32_UNDEFINED; diff --git a/src/world/map.c b/src/world/map.c index f445517151..b65e8968bb 100644 --- a/src/world/map.c +++ b/src/world/map.c @@ -3577,3 +3577,22 @@ void map_invalidate_element(int x, int y, rct_map_element *mapElement) { map_invalidate_tile(x, y, mapElement->base_height, mapElement->clearance_height); } + +int map_get_tile_side(int mapX, int mapY) +{ + int subMapX = mapX & (32 - 1); + int subMapY = mapY & (32 - 1); + return (subMapX < subMapY) ? + ((subMapX + subMapY) < 32 ? 0 : 1): + ((subMapX + subMapY) < 32 ? 3 : 2); +} + +int map_get_tile_quadrant(int mapX, int mapY) +{ + int subMapX = mapX & (32 - 1); + int subMapY = mapY & (32 - 1); + return (subMapX > 16) ? + (subMapY < 16 ? 1 : 0): + (subMapY < 16 ? 2 : 3); +} + diff --git a/src/world/map.h b/src/world/map.h index dd76ad8174..78aec14373 100644 --- a/src/world/map.h +++ b/src/world/map.h @@ -351,4 +351,7 @@ void map_invalidate_tile_zoom0(int x, int y, int z0, int z1); void map_invalidate_tile_full(int x, int y); void map_invalidate_element(int x, int y, rct_map_element *mapElement); +int map_get_tile_side(int mapX, int mapY); +int map_get_tile_quadrant(int mapX, int mapY); + #endif