From ecdc76d697599634b354c597cd3396f6ffa84756 Mon Sep 17 00:00:00 2001 From: Timmy Weerwag Date: Sun, 22 Mar 2015 21:50:16 +0100 Subject: [PATCH 1/7] Replaced call with existing decompiled function --- src/windows/footpath.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/windows/footpath.c b/src/windows/footpath.c index 15b3e08683..ceaa17f7c0 100644 --- a/src/windows/footpath.c +++ b/src/windows/footpath.c @@ -424,7 +424,7 @@ static void window_footpath_tooldrag() window_tool_get_registers(w, widgetIndex, x, y); if (widgetIndex == WIDX_CONSTRUCT_ON_LAND) { - RCT2_CALLPROC_X(0x006A82C5, x, y, 0, 0, (int)w, 0, 0); + window_footpath_place_path_at_point(x, y); } } From ba8066c7197dacbefdad156534e457d44979316c Mon Sep 17 00:00:00 2001 From: Timmy Weerwag Date: Sun, 22 Mar 2015 22:02:21 +0100 Subject: [PATCH 2/7] Decompiled 0x006A8380 --- src/windows/footpath.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/windows/footpath.c b/src/windows/footpath.c index ceaa17f7c0..ea3567b425 100644 --- a/src/windows/footpath.c +++ b/src/windows/footpath.c @@ -441,7 +441,8 @@ static void window_footpath_toolup() window_tool_get_registers(w, widgetIndex, x, y); if (widgetIndex == WIDX_CONSTRUCT_ON_LAND) { - RCT2_CALLPROC_X(0x006A8380, x, y, 0, 0, (int)w, 0, 0); + // Below is a 'function chunk' at 0x006A8380 in rct2 + RCT2_GLOBAL(RCT2_ADDRESS_PATH_ERROR_OCCURED, uint8) = 0; } } From d4f495cc0e623a09564b7bc48813839a99f021fd Mon Sep 17 00:00:00 2001 From: Timmy Weerwag Date: Sun, 22 Mar 2015 22:18:36 +0100 Subject: [PATCH 3/7] Renamed sub_6A7831 to footpath_provisional_update --- src/interface/viewport_interaction.c | 2 +- src/windows/footpath.c | 20 ++++++++++---------- src/world/footpath.c | 2 +- src/world/footpath.h | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/interface/viewport_interaction.c b/src/interface/viewport_interaction.c index 39f1d3bf42..7222302603 100644 --- a/src/interface/viewport_interaction.c +++ b/src/interface/viewport_interaction.c @@ -399,7 +399,7 @@ static void viewport_interaction_remove_footpath(rct_map_element *mapElement, in w = window_find_by_class(WC_FOOTPATH); if (w != NULL) - sub_6A7831(); + footpath_provisional_update(); mapElement2 = map_get_first_element_at(x / 32, y / 32); do { diff --git a/src/windows/footpath.c b/src/windows/footpath.c index ea3567b425..d60ab4d6ed 100644 --- a/src/windows/footpath.c +++ b/src/windows/footpath.c @@ -223,7 +223,7 @@ static void window_footpath_close() window_get_register(w); - sub_6A7831(); + footpath_provisional_update(); viewport_set_visibility(0); map_invalidate_map_selection_tiles(); RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~2; @@ -258,7 +258,7 @@ static void window_footpath_mouseup() _window_footpath_cost = MONEY32_UNDEFINED; tool_cancel(); - sub_6A7831(); + footpath_provisional_update(); map_invalidate_map_selection_tiles(); RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~2; RCT2_GLOBAL(RCT2_ADDRESS_PATH_CONSTRUCTION_MODE, uint8) = PATH_CONSTRUCTION_MODE_LAND; @@ -273,7 +273,7 @@ static void window_footpath_mouseup() _window_footpath_cost = MONEY32_UNDEFINED; tool_cancel(); - sub_6A7831(); + footpath_provisional_update(); map_invalidate_map_selection_tiles(); RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~2; RCT2_GLOBAL(RCT2_ADDRESS_PATH_CONSTRUCTION_MODE, uint8) = PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL_TOOL; @@ -369,7 +369,7 @@ static void window_footpath_dropdown() // Set selected path id RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_PATH_ID, sint16) = pathId; - sub_6A7831(); + footpath_provisional_update(); _window_footpath_cost = MONEY32_UNDEFINED; window_invalidate(w); } @@ -642,7 +642,7 @@ static void window_footpath_show_footpath_types_dialog(rct_window *w, rct_widget */ static void window_footpath_mousedown_direction(int direction) { - sub_6A7831(); + footpath_provisional_update(); RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_DIRECTION, uint8) = (direction - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)) & 3; _window_footpath_cost = MONEY32_UNDEFINED; window_footpath_set_enabled_and_pressed_widgets(); @@ -654,7 +654,7 @@ static void window_footpath_mousedown_direction(int direction) */ static void window_footpath_mousedown_slope(int slope) { - sub_6A7831(); + footpath_provisional_update(); RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_SLOPE, uint8) = slope; _window_footpath_cost = MONEY32_UNDEFINED; window_footpath_set_enabled_and_pressed_widgets(); @@ -676,7 +676,7 @@ static void window_footpath_set_provisional_path_at_point(int x, int y) if (z == 0) { RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~(1 << 0); - sub_6A7831(); + footpath_provisional_update(); } else { // Check for change if ((RCT2_GLOBAL(RCT2_ADDRESS_PROVISIONAL_PATH_FLAGS, uint8) & (1 << 1)) && RCT2_GLOBAL(RCT2_ADDRESS_PROVISIONAL_PATH_X, uint16) == x && RCT2_GLOBAL(RCT2_ADDRESS_PROVISIONAL_PATH_Y, uint16) == y && RCT2_GLOBAL(RCT2_ADDRESS_PROVISIONAL_PATH_Z, uint8) == mapElement->base_height) @@ -690,7 +690,7 @@ static void window_footpath_set_provisional_path_at_point(int x, int y) RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16) = x; RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16) = y; - sub_6A7831(); + footpath_provisional_update(); // Set provisional path slope = RCT2_ADDRESS(0x0098D8B4, uint8)[mapElement->properties.surface.slope & 0x1F]; @@ -715,7 +715,7 @@ static void window_footpath_place_path_at_point(int x, int y) if (RCT2_GLOBAL(RCT2_ADDRESS_PATH_ERROR_OCCURED, uint8) != 0) return; - sub_6A7831(); + footpath_provisional_update(); get_map_coordinates_from_pos(x, y, 0xFFDE, &x, &y, &z, &mapElement); if (z == 0) @@ -895,7 +895,7 @@ static void window_footpath_remove() rct_map_element *mapElement; _window_footpath_cost = MONEY32_UNDEFINED; - sub_6A7831(); + footpath_provisional_update(); mapElement = footpath_get_map_element_to_remove(); if (mapElement != NULL) diff --git a/src/world/footpath.c b/src/world/footpath.c index 869cfe5513..4a6ce75530 100644 --- a/src/world/footpath.c +++ b/src/world/footpath.c @@ -459,7 +459,7 @@ void footpath_provisional_remove() * * rct2: 0x006A7831 */ -void sub_6A7831() +void footpath_provisional_update() { if (RCT2_GLOBAL(RCT2_ADDRESS_PROVISIONAL_PATH_FLAGS, uint8) & PROVISIONAL_PATH_FLAG_SHOW_ARROW) { RCT2_GLOBAL(RCT2_ADDRESS_PROVISIONAL_PATH_FLAGS, uint8) &= ~PROVISIONAL_PATH_FLAG_SHOW_ARROW; diff --git a/src/world/footpath.h b/src/world/footpath.h index 8205b91c47..957c0c7f93 100644 --- a/src/world/footpath.h +++ b/src/world/footpath.h @@ -45,7 +45,7 @@ money32 footpath_place(int type, int x, int y, int z, int slope, int flags); void footpath_remove(int x, int y, int z, int flags); money32 footpath_provisional_set(int type, int x, int y, int z, int slope); void footpath_provisional_remove(); -void sub_6A7831(); +void footpath_provisional_update(); void sub_68A0C9(int screenX, int screenY, int *x, int *y, int *direction, rct_map_element **mapElement); #endif From 071ef2c88fbcfc9d1c9db111ec0ff628efc4002a Mon Sep 17 00:00:00 2001 From: Timmy Weerwag Date: Mon, 23 Mar 2015 00:34:00 +0100 Subject: [PATCH 4/7] Fixed an original bug in bridge footpath building Affects starting to build a footpath bridge on a sloped tile. The original code was horribly broken. I think this is the most intuitive solution considering the height of the arrow when selecting the tile. --- src/windows/footpath.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/windows/footpath.c b/src/windows/footpath.c index d60ab4d6ed..5bf53d8c8c 100644 --- a/src/windows/footpath.c +++ b/src/windows/footpath.c @@ -756,14 +756,18 @@ static void window_footpath_start_bridge_at_point(int screenX, int screenY) return; if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_SURFACE) { - // ? - uint8 dl = ((mapElement->properties.surface.slope & 0x0F) << direction) & 0xFF; - uint8 dh = dl; - dl = (dl >> 4) & 0x0F; - dh = (dh & 0x0F) | dl; + // If we start the path on a slope, the arrow is slightly raised, so we + // expect the path to be slightly raised as well. + uint8_t slope = mapElement->properties.surface.slope; z = mapElement->base_height; - if ((dh & 0x0C) == 0x0C) + if (slope & 0x10) { + // Steep diagonal slope + z += 4; + } + else if (slope & 0x0f) { + // Normal slope z += 2; + } } else { z = mapElement->base_height; if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_PATH) { From 2298a32d895ce8d7ffd687de1aff1d5a65a1b036 Mon Sep 17 00:00:00 2001 From: Timmy Weerwag Date: Mon, 23 Mar 2015 02:59:46 +0100 Subject: [PATCH 5/7] Decompiled 6A79B7 (window_footpath_construct) --- src/windows/footpath.c | 49 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/src/windows/footpath.c b/src/windows/footpath.c index 5bf53d8c8c..77f58f050c 100644 --- a/src/windows/footpath.c +++ b/src/windows/footpath.c @@ -797,7 +797,54 @@ static void window_footpath_start_bridge_at_point(int screenX, int screenY) */ static void window_footpath_construct() { - RCT2_CALLPROC_EBPSAFE(0x006A79B7); + _window_footpath_cost = MONEY32_UNDEFINED; + footpath_provisional_update(); + + int type, x, y, z, slope; + footpath_get_next_path_info(&type, &x, &y, &z, &slope); + + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, uint16) = 0x498; + money32 cost = footpath_place(type, x, y, z, slope, 0); + + if (cost != MONEY32_UNDEFINED) { + uint8 direction = RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_DIRECTION, uint8); + map_remove_intersecting_walls(x, y, z, z + 4 + (slope & 0xf ? 2 : 0), direction ^ 2); + map_remove_intersecting_walls( + x - TileDirectionDelta[direction].x, + y - TileDirectionDelta[direction].y, + z, z + 4, direction); + } + + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, uint16) = 0x498; + cost = footpath_place(type, x, y, z, slope, GAME_COMMAND_FLAG_APPLY); + if (cost != MONEY32_UNDEFINED) { + sound_play_panned(SOUND_PLACE_ITEM, 0x8001, + RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_X, uint16), + RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_Y, uint16), + RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_Z, uint16)); + + if (RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_SLOPE, uint8) == 0) { + RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_VALID_DIRECTIONS, uint8) = 0xff; + } else { + RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_VALID_DIRECTIONS, uint8) + = RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_DIRECTION, uint8); + } + + if (RCT2_GLOBAL(0x00F3EFA4, uint8) & 2) + viewport_set_visibility(1); + + if (RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_SLOPE, uint8) != 0) { + z += 2; + if (RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_SLOPE, uint8) != 2) + z -= 4; + } + + RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_X, uint16) = x; + RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_Y, uint16) = y; + RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_Z, uint16) = z << 3; + } + + window_footpath_set_enabled_and_pressed_widgets(); } /** From 945f60c297d40dcf6a170ee2925c593b523a4995 Mon Sep 17 00:00:00 2001 From: Timmy Weerwag Date: Mon, 23 Mar 2015 12:47:16 +0100 Subject: [PATCH 6/7] Made a wrong assumption z is not always the same as the construct_path_slope global --- src/windows/footpath.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/windows/footpath.c b/src/windows/footpath.c index 77f58f050c..7e78fadf1a 100644 --- a/src/windows/footpath.c +++ b/src/windows/footpath.c @@ -833,11 +833,11 @@ static void window_footpath_construct() if (RCT2_GLOBAL(0x00F3EFA4, uint8) & 2) viewport_set_visibility(1); - if (RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_SLOPE, uint8) != 0) { + // If we have just built an upwards slope, the next path to construct is + // a bit higher. Note that the z returned by footpath_get_next_path_info + // already is lowered if we are building a downwards slope. + if (RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_SLOPE, uint8) == 2) z += 2; - if (RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_SLOPE, uint8) != 2) - z -= 4; - } RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_X, uint16) = x; RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_Y, uint16) = y; From cf8034a29ee48416b6bd59713459cd837077b3cb Mon Sep 17 00:00:00 2001 From: Timmy Weerwag Date: Mon, 23 Mar 2015 15:32:03 +0100 Subject: [PATCH 7/7] Better comments and coding style --- src/windows/footpath.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/windows/footpath.c b/src/windows/footpath.c index 7e78fadf1a..260bc289a1 100644 --- a/src/windows/footpath.c +++ b/src/windows/footpath.c @@ -441,7 +441,7 @@ static void window_footpath_toolup() window_tool_get_registers(w, widgetIndex, x, y); if (widgetIndex == WIDX_CONSTRUCT_ON_LAND) { - // Below is a 'function chunk' at 0x006A8380 in rct2 + // The function at 0x006A8380 in rct2 is just the following: RCT2_GLOBAL(RCT2_ADDRESS_PATH_ERROR_OCCURED, uint8) = 0; } } @@ -763,8 +763,7 @@ static void window_footpath_start_bridge_at_point(int screenX, int screenY) if (slope & 0x10) { // Steep diagonal slope z += 4; - } - else if (slope & 0x0f) { + } else if (slope & 0x0f) { // Normal slope z += 2; } @@ -792,7 +791,7 @@ static void window_footpath_start_bridge_at_point(int screenX, int screenY) } /** - * + * Construct a piece of footpath while in bridge building mode. * rct2: 0x006A79B7 */ static void window_footpath_construct() @@ -803,31 +802,38 @@ static void window_footpath_construct() int type, x, y, z, slope; footpath_get_next_path_info(&type, &x, &y, &z, &slope); + // Try to place the path at the desired location RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, uint16) = 0x498; money32 cost = footpath_place(type, x, y, z, slope, 0); if (cost != MONEY32_UNDEFINED) { + // It is possible, let's remove walls between the old and new piece of path uint8 direction = RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_DIRECTION, uint8); map_remove_intersecting_walls(x, y, z, z + 4 + (slope & 0xf ? 2 : 0), direction ^ 2); map_remove_intersecting_walls( x - TileDirectionDelta[direction].x, y - TileDirectionDelta[direction].y, - z, z + 4, direction); + z, z + 4, direction + ); } + // Actually place the path now RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, uint16) = 0x498; cost = footpath_place(type, x, y, z, slope, GAME_COMMAND_FLAG_APPLY); + if (cost != MONEY32_UNDEFINED) { - sound_play_panned(SOUND_PLACE_ITEM, 0x8001, + sound_play_panned( + SOUND_PLACE_ITEM, + 0x8001, RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_X, uint16), RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_Y, uint16), - RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_Z, uint16)); + RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_FROM_Z, uint16) + ); if (RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_SLOPE, uint8) == 0) { RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_VALID_DIRECTIONS, uint8) = 0xff; } else { - RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_VALID_DIRECTIONS, uint8) - = RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_DIRECTION, uint8); + RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_VALID_DIRECTIONS, uint8) = RCT2_GLOBAL(RCT2_ADDRESS_CONSTRUCT_PATH_DIRECTION, uint8); } if (RCT2_GLOBAL(0x00F3EFA4, uint8) & 2)