diff --git a/src/interface/viewport.h b/src/interface/viewport.h index e53019738f..22956f7974 100644 --- a/src/interface/viewport.h +++ b/src/interface/viewport.h @@ -105,5 +105,6 @@ int viewport_interaction_left_click(int x, int y); int viewport_interaction_get_item_right(int x, int y, viewport_interaction_info *info); int viewport_interaction_right_over(int x, int y); int viewport_interaction_right_click(int x, int y); +void sub_68A15E(int screenX, int screenY, short *x, short *y, int *direction, rct_map_element **mapElement); #endif diff --git a/src/interface/viewport_interaction.c b/src/interface/viewport_interaction.c index 8d84dfb308..fa32dd9055 100644 --- a/src/interface/viewport_interaction.c +++ b/src/interface/viewport_interaction.c @@ -557,4 +557,73 @@ static rct_peep *viewport_interaction_get_closest_peep(int x, int y, int maxDist } return closestPeep; +} + +/** + * + * rct2: 0x0068A15E + */ +void sub_68A15E(int screenX, int screenY, short *x, short *y, int *direction, rct_map_element **mapElement) +{ + int my_x, my_y, z; + rct_map_element *myMapElement; + rct_viewport *viewport; + get_map_coordinates_from_pos(screenX, screenY, 0xFFF6, &my_x, &my_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, 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(viewport, screenX, screenY); + rct_xy16 map_pos = { my_x + 16, my_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, sint16), map_pos.x, RCT2_GLOBAL(0x00F1AD38, sint16)); + map_pos.y = clamp(RCT2_GLOBAL(0x00F1AD36, sint16), map_pos.y, RCT2_GLOBAL(0x00F1AD3A, sint16)); + } + + // 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; } \ No newline at end of file diff --git a/src/windows/top_toolbar.c b/src/windows/top_toolbar.c index 88062296f6..4970629a45 100644 --- a/src/windows/top_toolbar.c +++ b/src/windows/top_toolbar.c @@ -752,6 +752,26 @@ void sub_68964B(sint16 x, sint16 y, sint16 z, sint16* grid_x, sint16* grid_y, ui *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; +} + void sub_6894D4(sint16 x, sint16 y, sint16 z, sint16* grid_x, sint16* grid_y){ int eax = x, ebx = y, ecx = 0, edx = 0, esi = 0, edi = 0, ebp = z; @@ -905,7 +925,7 @@ void sub_6E1F34(sint16 x, sint16 y, uint16 selected_scenery, sint16* grid_x, sin if (!(scenery->small_scenery.flags & SMALL_SCENERY_FLAG4)){ rotation = scenario_rand() & 0xFF; } - + rotation -= RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint8); rotation &= 0x3; @@ -915,7 +935,7 @@ void sub_6E1F34(sint16 x, sint16 y, uint16 selected_scenery, sint16* grid_x, sin *parameter_3 = rotation | (window_scenery_secondary_colour << 16); return; } - + // If CTRL not pressed if (RCT2_GLOBAL(0x00F64F12, uint8) == 0){ uint16 flags = 0xFFF6; @@ -989,26 +1009,191 @@ void sub_6E1F34(sint16 x, sint16 y, uint16 selected_scenery, sint16* grid_x, sin *parameter_1 = (selected_scenery & 0xFF) << 8; *parameter_2 = 0 | (window_scenery_primary_colour << 8); *parameter_3 = rotation | (window_scenery_secondary_colour << 16); - return; break; } case 1: + { // Path bits - // 6e23dd + + uint16 flags = 0xFF9F; + int interaction_type = 0; + rct_map_element* map_element; + + get_map_coordinates_from_pos(x, y, flags, grid_x, grid_y, &interaction_type, &map_element, NULL); + + if (interaction_type == VIEWPORT_INTERACTION_ITEM_NONE) + { + *grid_x = 0x8000; + return; + } + + *parameter_1 = 0 | map_element->properties.path.type & 0x7; + *parameter_2 = map_element->base_height | ((map_element->properties.path.type >> 4) << 8); + if (map_element->type & 1){ + *parameter_2 |= 0x8000; + } + *parameter_3 = (selected_scenery & 0xFF) + 1; break; + } case 2: + { // Walls - // 6e2415 + uint8 cl; + // If CTRL not pressed + if (RCT2_GLOBAL(0x00F64F12, uint8) == 0){ + sub_689692(x, y, grid_x, grid_y, &cl); + + if (*grid_x == 0x8000) + return; + + RCT2_GLOBAL(0x00F64ED4, sint16) = 0; + + // If SHIFT pressed + if (RCT2_GLOBAL(0x00F64F13, uint8) != 0){ + rct_map_element* map_element = map_get_surface_element_at(*grid_x / 32, *grid_y / 32); + + if (map_element == NULL){ + *grid_x = 0x8000; + return; + } + + sint16 z = (map_element->base_height * 8) & 0xFFF0; + z += RCT2_GLOBAL(0x00F64ED2, sint16); + + if (z < 16){ + z = 16; + } + + RCT2_GLOBAL(0x00F64ED4, sint16) = z; + } + } + else{ + sint16 z = RCT2_GLOBAL(0x00F64ECC, sint16); + sub_6896DC(x, y, z, grid_x, grid_y, &cl); + + // If SHIFT pressed + if (RCT2_GLOBAL(0x00F64F13, uint8) != 0){ + z += RCT2_GLOBAL(0x00F64ED2, sint16); + } + + if (z < 16){ + z = 16; + } + + RCT2_GLOBAL(0x00F64ED4, sint16) = z; + } + + if (*grid_x == 0x8000) + return; + + RCT2_GLOBAL(0x00F64F15, uint8) = window_scenery_secondary_colour; + RCT2_GLOBAL(0x00F64F16, uint8) = window_scenery_tertiary_colour; + // Also places it in lower but think thats for clobering + *parameter_1 = (selected_scenery & 0xFF) << 8; + *parameter_2 = cl | (window_scenery_primary_colour << 8); + *parameter_3 = 0; break; + } case 3: + { // Large scenery - // 6e22a4 + + // If CTRL not pressed + if (RCT2_GLOBAL(0x00F64F12, uint8) == 0){ + sub_68A15E(x, y, grid_x, grid_y, NULL, NULL); + + if (*grid_x == 0x8000) + return; + + RCT2_GLOBAL(0x00F64ED4, sint16) = 0; + + // If SHIFT pressed + if (RCT2_GLOBAL(0x00F64F13, uint8) != 0){ + rct_map_element* map_element = map_get_surface_element_at(*grid_x / 32, *grid_y / 32); + + if (map_element == NULL){ + *grid_x = 0x8000; + return; + } + + sint16 z = (map_element->base_height * 8) & 0xFFF0; + z += RCT2_GLOBAL(0x00F64ED2, sint16); + + if (z < 16){ + z = 16; + } + + RCT2_GLOBAL(0x00F64ED4, sint16) = z; + } + } + else{ + sint16 z = RCT2_GLOBAL(0x00F64ECC, sint16); + sub_6894D4(x, y, z, grid_x, grid_y); + + // If SHIFT pressed + if (RCT2_GLOBAL(0x00F64F13, uint8) != 0){ + z += RCT2_GLOBAL(0x00F64ED2, sint16); + } + + if (z < 16){ + z = 16; + } + + RCT2_GLOBAL(0x00F64ED4, sint16) = z; + } + + if (*grid_x == 0x8000) + return; + + *grid_x &= 0xFFE0; + *grid_y &= 0xFFE0; + + uint8 rotation = window_scenery_rotation; + rotation -= RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint8); + rotation &= 0x3; + + *parameter_1 = (rotation << 8); + *parameter_2 = window_scenery_primary_colour | (window_scenery_secondary_colour << 8); + *parameter_3 = selected_scenery & 0xFF; break; + } case 4: + { // Banner - // 6e2385 + + uint16 flags = 0xFF9F; + int interaction_type = 0; + rct_map_element* map_element; + + get_map_coordinates_from_pos(x, y, flags, grid_x, grid_y, &interaction_type, &map_element, NULL); + + if (interaction_type == VIEWPORT_INTERACTION_ITEM_NONE) + { + *grid_x = 0x8000; + return; + } + + uint8 rotation = window_scenery_rotation; + rotation -= RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint8); + rotation &= 0x3; + + sint16 z = map_element->base_height; + + if (map_element->properties.path.type & (1 << 2)){ + if (rotation != ((map_element->properties.path.type & 3) ^ 2)){ + z += 2; + } + } + + z /= 2; + + // Also places it in lower but think thats for clobering + *parameter_1 = (selected_scenery & 0xFF) << 8; + *parameter_2 = z | (rotation << 8); + *parameter_3 = window_scenery_primary_colour; break; } + } } /** diff --git a/src/windows/track_place.c b/src/windows/track_place.c index 001c4ff014..9b8d777689 100644 --- a/src/windows/track_place.c +++ b/src/windows/track_place.c @@ -300,75 +300,6 @@ static void window_track_place_draw_mini_preview() } } -/** - * - * rct2: 0x0068A15E - */ -static void sub_68A15E(int screenX, int screenY, short *x, short *y, int *direction, rct_map_element **mapElement) -{ - int my_x, my_y, z; - rct_map_element *myMapElement; - rct_viewport *viewport; - get_map_coordinates_from_pos(screenX, screenY, 0xFFF6, &my_x, &my_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, 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(viewport, screenX, screenY); - rct_xy16 map_pos = { my_x + 16, my_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, sint16), map_pos.x, RCT2_GLOBAL(0x00F1AD38, sint16)); - map_pos.y = clamp(RCT2_GLOBAL(0x00F1AD36, sint16), map_pos.y, RCT2_GLOBAL(0x00F1AD3A, sint16)); - } - - // 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; -} - /** * * rct2: 0x006D017F