From d9a2ef1066ea3b11c95c321f67e1a75c6d51316e Mon Sep 17 00:00:00 2001 From: Daniel Trujillo Date: Wed, 13 Jul 2016 01:21:03 +0200 Subject: [PATCH 1/6] Rewrite function clear_elements_at() in a more readable way. Also, some code has been taken out the main loop, making calls to this function return faster. --- src/world/map.c | 139 ++++++++++++++++++++++++++---------------------- 1 file changed, 75 insertions(+), 64 deletions(-) diff --git a/src/world/map.c b/src/world/map.c index 840a43321b..ad2e92b05c 100644 --- a/src/world/map.c +++ b/src/world/map.c @@ -4502,78 +4502,89 @@ void map_extend_boundary_surface() } } +/** + * Clears the provided element properly from a certain tile. + */ +void clear_element_at(int x, int y, rct_map_element *element) +{ + switch (map_element_get_type(element)) { + case MAP_ELEMENT_TYPE_SURFACE: + break; + case MAP_ELEMENT_TYPE_ENTRANCE: + viewport_interaction_remove_park_entrance(element, x, y); + break; + case MAP_ELEMENT_TYPE_FENCE: + gGameCommandErrorTitle = STR_CANT_REMOVE_THIS; + game_do_command( + x, + GAME_COMMAND_FLAG_APPLY, + y, + (element->type & MAP_ELEMENT_DIRECTION_MASK) | (element->base_height << 8), + GAME_COMMAND_REMOVE_FENCE, + 0, + 0 + ); + break; + case MAP_ELEMENT_TYPE_SCENERY_MULTIPLE: + gGameCommandErrorTitle = STR_CANT_REMOVE_THIS; + game_do_command( + x, + (GAME_COMMAND_FLAG_APPLY) | ((element->type & MAP_ELEMENT_DIRECTION_MASK) << 8), + y, + (element->base_height) | (((element->properties.scenerymultiple.type >> 8) >> 2) << 8), + GAME_COMMAND_REMOVE_LARGE_SCENERY, + 0, + 0 + ); + break; + case MAP_ELEMENT_TYPE_BANNER: + gGameCommandErrorTitle = STR_CANT_REMOVE_THIS; + game_do_command( + x, + GAME_COMMAND_FLAG_APPLY, + y, + (element->base_height) | ((element->properties.banner.position & 3) << 8), + GAME_COMMAND_REMOVE_BANNER, + 0, + 0 + ); + break; + default: + map_element_remove(element); + break; + } +} + /** * Clears all elements properly from a certain tile. * rct2: 0x0068AE2A */ static void clear_elements_at(int x, int y) { - for (;;) { - for (int i = 0; i < 2; i++) { - rct2_peep_spawn *peepSpawn = &gPeepSpawns[i]; - if (floor2(peepSpawn->x, 32) == x && floor2(peepSpawn->y, 32) == y) { - peepSpawn->x = UINT16_MAX; - } - } - - rct_map_element *mapElement = map_get_first_element_at(x >> 5, y >> 5); - next_element: - switch (map_element_get_type(mapElement)) { - case MAP_ELEMENT_TYPE_SURFACE: - mapElement->base_height = 2; - mapElement->clearance_height = 2; - mapElement->properties.surface.slope = 0; - mapElement->properties.surface.terrain = 0; - mapElement->properties.surface.grass_length = 1; - mapElement->properties.surface.ownership = 0; - if (!map_element_is_last_for_tile(mapElement++)) - goto next_element; - - return; - case MAP_ELEMENT_TYPE_ENTRANCE: - viewport_interaction_remove_park_entrance(mapElement, x, y); - break; - case MAP_ELEMENT_TYPE_FENCE: - gGameCommandErrorTitle = STR_CANT_REMOVE_THIS; - game_do_command( - x, - GAME_COMMAND_FLAG_APPLY, - y, - (mapElement->type & MAP_ELEMENT_DIRECTION_MASK) | (mapElement->base_height << 8), - GAME_COMMAND_REMOVE_FENCE, - 0, - 0 - ); - break; - case MAP_ELEMENT_TYPE_SCENERY_MULTIPLE: - gGameCommandErrorTitle = STR_CANT_REMOVE_THIS; - game_do_command( - x, - (GAME_COMMAND_FLAG_APPLY) | ((mapElement->type & MAP_ELEMENT_DIRECTION_MASK) << 8), - y, - (mapElement->base_height) | (((mapElement->properties.scenerymultiple.type >> 8) >> 2) << 8), - GAME_COMMAND_REMOVE_LARGE_SCENERY, - 0, - 0 - ); - break; - case MAP_ELEMENT_TYPE_BANNER: - gGameCommandErrorTitle = STR_CANT_REMOVE_THIS; - game_do_command( - x, - GAME_COMMAND_FLAG_APPLY, - y, - (mapElement->base_height) | ((mapElement->properties.banner.position & 3) << 8), - GAME_COMMAND_REMOVE_BANNER, - 0, - 0 - ); - break; - default: - map_element_remove(mapElement); - break; + for (int i = 0; i < 2; i++) { + rct2_peep_spawn *peepSpawn = &gPeepSpawns[i]; + if (floor2(peepSpawn->x, 32) == x && floor2(peepSpawn->y, 32) == y) { + peepSpawn->x = UINT16_MAX; } } + + rct_map_element *mapElement = map_get_first_element_at(x >> 5, y >> 5); + + if(map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_SURFACE){ + mapElement->base_height = 2; + mapElement->clearance_height = 2; + mapElement->properties.surface.slope = 0; + mapElement->properties.surface.terrain = 0; + mapElement->properties.surface.grass_length = 1; + mapElement->properties.surface.ownership = 0; + if (map_element_is_last_for_tile(mapElement++)) + return; + } + + while(!map_element_is_last_for_tile(mapElement)) + clear_element_at(x, y, mapElement); + + clear_element_at(x, y, mapElement); } int map_get_highest_z(int tileX, int tileY) From d8e2dbe04511bf89847bcccc2c4c76a7cb8ff5dd Mon Sep 17 00:00:00 2001 From: Daniel Trujillo Date: Wed, 13 Jul 2016 18:48:40 +0200 Subject: [PATCH 2/6] Final refactor, comments & code cleaning --- src/world/map.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/world/map.c b/src/world/map.c index ad2e92b05c..e47b9a32b7 100644 --- a/src/world/map.c +++ b/src/world/map.c @@ -4503,12 +4503,23 @@ void map_extend_boundary_surface() } /** - * Clears the provided element properly from a certain tile. + * Clears the provided element properly from a certain tile, and updates the pointer passed + * to this function to point to the next element. */ -void clear_element_at(int x, int y, rct_map_element *element) +void clear_element_at(int x, int y, rct_map_element **elementPtr) { + rct_map_element *element = *elementPtr; switch (map_element_get_type(element)) { case MAP_ELEMENT_TYPE_SURFACE: + element->base_height = 2; + element->clearance_height = 2; + element->properties.surface.slope = 0; + element->properties.surface.terrain = 0; + element->properties.surface.grass_length = 1; + element->properties.surface.ownership = 0; + // Because this element is not completely removed, the pointer must be updated muanually + // The rest of the elements are removed from the array, so the pointer doesn't need to be updated. + (*elementPtr)++; break; case MAP_ELEMENT_TYPE_ENTRANCE: viewport_interaction_remove_park_entrance(element, x, y); @@ -4561,6 +4572,7 @@ void clear_element_at(int x, int y, rct_map_element *element) */ static void clear_elements_at(int x, int y) { + // Remove the spawn point (if there is one in the current tile for (int i = 0; i < 2; i++) { rct2_peep_spawn *peepSpawn = &gPeepSpawns[i]; if (floor2(peepSpawn->x, 32) == x && floor2(peepSpawn->y, 32) == y) { @@ -4570,21 +4582,12 @@ static void clear_elements_at(int x, int y) rct_map_element *mapElement = map_get_first_element_at(x >> 5, y >> 5); - if(map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_SURFACE){ - mapElement->base_height = 2; - mapElement->clearance_height = 2; - mapElement->properties.surface.slope = 0; - mapElement->properties.surface.terrain = 0; - mapElement->properties.surface.grass_length = 1; - mapElement->properties.surface.ownership = 0; - if (map_element_is_last_for_tile(mapElement++)) - return; - } - + // Remove all elements except the last one while(!map_element_is_last_for_tile(mapElement)) - clear_element_at(x, y, mapElement); + clear_element_at(x, y, &mapElement); - clear_element_at(x, y, mapElement); + // Remove the last element + clear_element_at(x, y, &mapElement); } int map_get_highest_z(int tileX, int tileY) From 00956459d87416a5d103ffec2c93e412e3cd30c5 Mon Sep 17 00:00:00 2001 From: Daniel Trujillo Date: Wed, 13 Jul 2016 18:57:55 +0200 Subject: [PATCH 3/6] Fix comments typo --- src/world/map.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/world/map.c b/src/world/map.c index e47b9a32b7..dcd225b7c0 100644 --- a/src/world/map.c +++ b/src/world/map.c @@ -4503,8 +4503,8 @@ void map_extend_boundary_surface() } /** - * Clears the provided element properly from a certain tile, and updates the pointer passed - * to this function to point to the next element. + * Clears the provided element properly from a certain tile, and updates + * the pointer (when needed) passed to this function to point to the next element. */ void clear_element_at(int x, int y, rct_map_element **elementPtr) { @@ -4572,7 +4572,7 @@ void clear_element_at(int x, int y, rct_map_element **elementPtr) */ static void clear_elements_at(int x, int y) { - // Remove the spawn point (if there is one in the current tile + // Remove the spawn point (if there is one in the current tile) for (int i = 0; i < 2; i++) { rct2_peep_spawn *peepSpawn = &gPeepSpawns[i]; if (floor2(peepSpawn->x, 32) == x && floor2(peepSpawn->y, 32) == y) { From 0a6fcce92e4bb85309d4d01c17cf04c2dbd45673 Mon Sep 17 00:00:00 2001 From: Daniel Trujillo Date: Wed, 13 Jul 2016 19:15:50 +0200 Subject: [PATCH 4/6] Make clear_element_at() static. --- src/world/map.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/map.c b/src/world/map.c index dcd225b7c0..9a6152a802 100644 --- a/src/world/map.c +++ b/src/world/map.c @@ -4506,7 +4506,7 @@ void map_extend_boundary_surface() * Clears the provided element properly from a certain tile, and updates * the pointer (when needed) passed to this function to point to the next element. */ -void clear_element_at(int x, int y, rct_map_element **elementPtr) +static void clear_element_at(int x, int y, rct_map_element **elementPtr) { rct_map_element *element = *elementPtr; switch (map_element_get_type(element)) { From f8aac831ca68ef42a788a37d7597b7343c420424 Mon Sep 17 00:00:00 2001 From: Daniel Trujillo Date: Sun, 17 Jul 2016 17:05:17 +0200 Subject: [PATCH 5/6] Comment map_element_remove() --- src/world/map.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/world/map.c b/src/world/map.c index 9a6152a802..1f1938d5d2 100644 --- a/src/world/map.c +++ b/src/world/map.c @@ -3803,11 +3803,16 @@ int map_get_station(rct_map_element *mapElement) */ void map_element_remove(rct_map_element *mapElement) { + // Replace Nth element by (N+1)th element. + // This loop will make mapElement point to the old last element position, + // befor copy it to it's new position if (!map_element_is_last_for_tile(mapElement)){ do{ *mapElement = *(mapElement + 1); } while (!map_element_is_last_for_tile(++mapElement)); } + + // Mark the latest element with the last element flag. (mapElement - 1)->flags |= MAP_ELEMENT_FLAG_LAST_TILE; mapElement->base_height = 0xFF; From 68c5f256c55cfdc8f724ed40a8a8c4e26fe9289c Mon Sep 17 00:00:00 2001 From: Daniel Trujillo Date: Sun, 17 Jul 2016 17:18:37 +0200 Subject: [PATCH 6/6] Fix a mistake in a newly added comment --- src/world/map.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/map.c b/src/world/map.c index 1f1938d5d2..223e9ce9ca 100644 --- a/src/world/map.c +++ b/src/world/map.c @@ -3805,7 +3805,7 @@ void map_element_remove(rct_map_element *mapElement) { // Replace Nth element by (N+1)th element. // This loop will make mapElement point to the old last element position, - // befor copy it to it's new position + // after copy it to it's new position if (!map_element_is_last_for_tile(mapElement)){ do{ *mapElement = *(mapElement + 1);