diff --git a/src/windows/track_place.c b/src/windows/track_place.c index 1023196bae..eb1b933d26 100644 --- a/src/windows/track_place.c +++ b/src/windows/track_place.c @@ -304,14 +304,69 @@ static void window_track_place_draw_mini_preview() * * rct2: 0x0068A15E */ -static void sub_68A15E(int x, int y, short *ax, short *bx) +static void sub_68A15E(int screenX, int screenY, int *x, int *y, int *direction, rct_map_element **mapElement) { - int eax, ebx, ecx, edx, esi, edi, ebp; - eax = x; - ebx = y; - RCT2_CALLFUNC_X(0x0068A15E, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - *ax = *((short*)&eax); - *bx = *((short*)&ebx); + int z; + rct_map_element *myMapElement; + rct_viewport *viewport; + get_map_coordinates_from_pos(screenX, screenY, 0xFFF6, x, y, &z, &myMapElement, &viewport); + + if (z == 0) { + *x = 0x8000; + return; + } + + RCT2_GLOBAL(0x00F1AD3E, uint8) = z; + RCT2_GLOBAL(0x00F1AD30, rct_map_element*) = myMapElement; + + if (z == 4) { + // myMapElement appears to be water + z = myMapElement->properties.surface.terrain; + z = (z & MAP_ELEMENT_WATER_HEIGHT_MASK) << 4; + } + + RCT2_GLOBAL(0x00F1AD3C, uint16) = z; + RCT2_GLOBAL(0x00F1AD34, uint16) = *x; + RCT2_GLOBAL(0x00F1AD36, uint16) = *y; + RCT2_GLOBAL(0x00F1AD38, uint16) = *x + 31; + RCT2_GLOBAL(0x00F1AD3A, uint16) = *y + 31; + + rct_xy16 start_vp_pos = screen_coord_to_viewport_coord(viewport, screenX, screenY); + rct_xy16 map_pos = { *x + 16, *y + 16 }; + + for (int i = 0; i < 5; i++) { + if (RCT2_GLOBAL(0x00F1AD3E, uint8) != 4) { + z = map_element_height(map_pos.x, map_pos.y); + } else { + z = RCT2_GLOBAL(0x00F1AD3C, uint16); + } + map_pos = viewport_coord_to_map_coord(start_vp_pos.x, start_vp_pos.y, z); + map_pos.x = clamp(RCT2_GLOBAL(0x00F1AD34, uint16), map_pos.x, RCT2_GLOBAL(0x00F1AD38, uint16)); + map_pos.y = clamp(RCT2_GLOBAL(0x00F1AD36, uint16), map_pos.y, RCT2_GLOBAL(0x00F1AD3A, uint16)); + } + + // Determine to which edge the cursor is closest + int myDirection; + int mod_x = map_pos.x & 0x1F; + int mod_y = map_pos.y & 0x1F; + if (mod_x < mod_y) { + if (mod_x + mod_y < 32) { + myDirection = 0; + } else { + myDirection = 1; + } + } else { + if (mod_x + mod_y < 32) { + myDirection = 3; + } else { + myDirection = 2; + } + } + + *x = map_pos.x & ~0x1F; + *y = map_pos.y & ~0x1F; + if (direction != NULL) *direction = myDirection; + if (mapElement != NULL) *mapElement = myMapElement; } /** @@ -483,7 +538,7 @@ static void window_track_place_toolupdate() RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~7; // Get the tool map position - sub_68A15E(x, y, &x, &y); + sub_68A15E(x, y, &x, &y, NULL, NULL); if (x == (short)0x8000) { window_track_place_clear_provisional(); return; @@ -545,7 +600,7 @@ static void window_track_place_tooldown() map_invalidate_map_selection_tiles(); RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~7; - sub_68A15E(x, y, &x, &y); + sub_68A15E(x, y, &x, &y, NULL, NULL); if (x == (short)0x8000) return;