From 6de7a38f53623da573cefda7b2ab0955c22f30aa Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Thu, 2 Jul 2015 00:37:55 +0100 Subject: [PATCH] implement finish-map-window part 4 --- src/localisation/string_ids.h | 3 ++ src/windows/map.c | 85 +++++++++++++++++++++++++++++++-- src/world/map.c | 88 +++++++++++++++++++++++++++++++++-- src/world/map.h | 3 ++ 4 files changed, 171 insertions(+), 8 deletions(-) diff --git a/src/localisation/string_ids.h b/src/localisation/string_ids.h index a8800fa2be..6d3e064515 100644 --- a/src/localisation/string_ids.h +++ b/src/localisation/string_ids.h @@ -1551,6 +1551,9 @@ enum { STR_MAP_SIZE = 3211, + STR_CANT_DECREASE_MAP_SIZE_ANY_FURTHER = 3213, + STR_CANT_INCREASE_MAP_SIZE_ANY_FURTHER = 3214, + STR_SELECT_PARK_OWNED_LAND_TIP = 3216, STR_LAND_OWNED = 3217, diff --git a/src/windows/map.c b/src/windows/map.c index 2fb826867e..4edd547bec 100644 --- a/src/windows/map.c +++ b/src/windows/map.c @@ -31,6 +31,7 @@ #include "../sprites.h" #include "../world/footpath.h" #include "../world/scenery.h" +#include "error.h" enum { PAGE_PEEPS, @@ -161,6 +162,9 @@ static void window_map_place_park_entrance_tool_update(int x, int y); static void window_map_set_peep_spawn_tool_update(int x, int y); static void window_map_place_park_entrance_tool_down(int x, int y); static void window_map_set_peep_spawn_tool_down(int x, int y); +static void map_window_increase_map_size(); +static void map_window_decrease_map_size(); +static void map_window_set_pixels(rct_window *w); /** * @@ -389,10 +393,10 @@ static void window_map_mousedown(int widgetIndex, rct_window *w, rct_widget *wid { switch (widgetIndex) { case WIDX_MAP_SIZE_SPINNER_UP: - RCT2_CALLPROC_X(0x0068D641, 0, 0, 0, widgetIndex, (int)w, 0, 0); + map_window_increase_map_size(); break; case WIDX_MAP_SIZE_SPINNER_DOWN: - RCT2_CALLPROC_X(0x0068D6B4, 0, 0, 0, widgetIndex, (int)w, 0, 0); + map_window_decrease_map_size(); break; case WIDX_SET_LAND_RIGHTS: // When unselecting the land rights tool, reset the size so the number doesn't @@ -408,7 +412,31 @@ static void window_map_mousedown(int widgetIndex, rct_window *w, rct_widget *wid */ static void window_map_update(rct_window *w) { - RCT2_CALLPROC_X(0x0068D7FB, 0, 0, 0, 0, (int)w, 0, 0); + if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint8) != w->map.rotation) { + w->map.rotation = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint8); + window_map_init_map(); + window_map_center_on_view_point(); + } + + for (int i = 0; i < 16; i++) + map_window_set_pixels(w); + + window_invalidate(w); + + // Update tab animations + w->list_information_type++; + switch (w->selected_tab) { + case PAGE_PEEPS: + if (w->list_information_type >= 32) { + w->list_information_type = 0; + } + break; + case PAGE_RIDES: + if (w->list_information_type >= 64) { + w->list_information_type = 0; + } + break; + } } @@ -583,11 +611,11 @@ static void window_map_textinput() if (size > 256) size = 256; int currentSize = RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, uint16); while (size < currentSize) { - RCT2_CALLPROC_X(0x0068D6B4, 0, 0, 0, widgetIndex, (int)w, 0, 0); + map_window_decrease_map_size(); currentSize--; } while (size > currentSize) { - RCT2_CALLPROC_X(0x0068D641, 0, 0, 0, widgetIndex, (int)w, 0, 0); + map_window_increase_map_size(); currentSize++; } window_invalidate(w); @@ -1306,3 +1334,50 @@ static void window_map_set_peep_spawn_tool_down(int x, int y) gfx_invalidate_screen(); RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, uint16) = peepSpawnIndex; } + +/** + * + * rct2: 0x0068D641 + */ +static void map_window_increase_map_size() +{ + if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, uint16) >= 256) { + window_error_open(STR_CANT_INCREASE_MAP_SIZE_ANY_FURTHER, STR_NONE); + return; + } + + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, uint16)++; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE_UNITS, uint16) = (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, uint16) - 1) * 32; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE_MINUS_2, uint16) = (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, uint16) * 32) + 254; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAX_XY, uint16) = ((RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, uint16) - 1) * 32) - 1; + map_extend_boundary_surface(); + window_map_init_map(); + window_map_center_on_view_point(); + gfx_invalidate_screen(); +} + +/** + * + * rct2: 0x0068D6B4 + */ +static void map_window_decrease_map_size() +{ + if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, uint16) < 16) { + window_error_open(STR_CANT_DECREASE_MAP_SIZE_ANY_FURTHER, STR_NONE); + return; + } + + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, uint16)--; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE_UNITS, uint16) = (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, uint16) - 1) * 32; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE_MINUS_2, uint16) = (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, uint16) * 32) + 254; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAX_XY, uint16) = ((RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, uint16) - 1) * 32) - 1; + map_remove_out_of_range_elements(); + window_map_init_map(); + window_map_center_on_view_point(); + gfx_invalidate_screen(); +} + +static void map_window_set_pixels(rct_window *w) +{ + RCT2_CALLPROC_X(0x0068DC71, 0, 0, 0, 0, (int)w, 0, 0); +} diff --git a/src/world/map.c b/src/world/map.c index 00127a07fc..0ebe546dfd 100644 --- a/src/world/map.c +++ b/src/world/map.c @@ -64,7 +64,6 @@ static void tiles_init(); static void sub_6A87BB(int x, int y); static void map_update_grass_length(int x, int y, rct_map_element *mapElement); static void map_set_grass_length(int x, int y, rct_map_element *mapElement, int length); -static void sub_68ADBC(); static void sub_68AE2A(int x, int y); void rotate_map_coordinates(sint16* x, sint16* y, int rotation){ @@ -302,7 +301,7 @@ void map_init(int size) RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAX_XY, sint16) = size * 32 - 33; RCT2_GLOBAL(0x01359208, sint16) = 7; map_update_tile_pointers(); - sub_68ADBC(); + map_remove_out_of_range_elements(); climate_reset(CLIMATE_WARM); } @@ -3134,7 +3133,11 @@ void map_element_remove_banner_entry(rct_map_element *mapElement) } } -static void sub_68ADBC() +/** + * Removes elements that are out of the map size range and crops the park perimeter. + * rct2: 0x0068ADBC + */ +void map_remove_out_of_range_elements() { int mapMaxXY = RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAX_XY, uint16); @@ -3151,6 +3154,85 @@ static void sub_68ADBC() } } +/** + * Copies the terrain and slope from the edge of the map to the new tiles. Used when increasing the size of the map. + * rct2: 0x0068AC15 + */ +void map_extend_boundary_surface() +{ + rct_map_element *existingMapElement, *newMapElement; + int x, y, z, slope; + + y = RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, uint16) - 2; + for (x = 0; x < 256; x++) { + existingMapElement = map_get_surface_element_at(x, y - 1); + newMapElement = map_get_surface_element_at(x, y); + + newMapElement->type = (newMapElement->type & 0x7C) | (existingMapElement->type & 0x83); + newMapElement->properties.surface.slope = existingMapElement->properties.surface.slope & 0xE0; + newMapElement->properties.surface.terrain = existingMapElement->properties.surface.terrain; + newMapElement->properties.surface.grass_length = existingMapElement->properties.surface.grass_length; + newMapElement->properties.surface.ownership = 0; + + z = existingMapElement->base_height; + slope = existingMapElement->properties.surface.slope & 9; + if (slope == 9) { + z += 2; + slope = 0; + if (existingMapElement->properties.surface.slope & 0x10) { + slope = 1; + if (existingMapElement->properties.surface.slope & 0x04) { + slope = 8; + if (existingMapElement->properties.surface.slope & 0x02) { + slope = 0; + } + } + } + } + if (slope & 1) slope |= 2; + if (slope & 8) slope |= 4; + + newMapElement->properties.surface.slope |= slope; + newMapElement->base_height = z; + newMapElement->clearance_height = z; + } + + x = RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, uint16) - 2; + for (y = 0; y < 256; y++) { + existingMapElement = map_get_surface_element_at(x - 1, y); + newMapElement = map_get_surface_element_at(x, y); + + newMapElement->type = (newMapElement->type & 0x7C) | (existingMapElement->type & 0x83); + newMapElement->properties.surface.slope = existingMapElement->properties.surface.slope & 0xE0; + newMapElement->properties.surface.terrain = existingMapElement->properties.surface.terrain; + newMapElement->properties.surface.grass_length = existingMapElement->properties.surface.grass_length; + newMapElement->properties.surface.ownership = 0; + + z = existingMapElement->base_height; + slope = existingMapElement->properties.surface.slope & 3; + if (slope == 3) { + z += 2; + slope = 0; + if (existingMapElement->properties.surface.slope & 0x10) { + slope = 1; + if (existingMapElement->properties.surface.slope & 0x04) { + slope = 2; + if (existingMapElement->properties.surface.slope & 0x08) { + slope = 0; + } + } + } + } + if (slope & 1) slope |= 8; + if (slope & 2) slope |= 4; + + newMapElement->properties.surface.slope |= slope; + newMapElement->base_height = z; + newMapElement->clearance_height = z; + } + +} + static void sub_68AE2A(int x, int y) { for (;;) { diff --git a/src/world/map.h b/src/world/map.h index 0c58cd9e3f..7fbd9991e2 100644 --- a/src/world/map.h +++ b/src/world/map.h @@ -338,4 +338,7 @@ void map_element_remove_banner_entry(rct_map_element *mapElement); bool map_element_is_underground(rct_map_element *mapElement); +void map_remove_out_of_range_elements(); +void map_extend_boundary_surface(); + #endif