#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers /***************************************************************************** * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. * * OpenRCT2 is the work of many authors, a full list can be found in contributors.md * For more information, visit https://github.com/OpenRCT2/OpenRCT2 * * OpenRCT2 is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * A full copy of the GNU General Public License can be found in licence.txt *****************************************************************************/ #pragma endregion #include "../addresses.h" #include "../localisation/localisation.h" #include "../input.h" #include "../interface/widget.h" #include "../interface/viewport.h" #include "../interface/window.h" #include "../sprites.h" #include "../util/util.h" #include "../world/mapgen.h" #include "../world/scenery.h" #include "dropdown.h" #include "../interface/themes.h" enum { WINDOW_MAPGEN_PAGE_BASE, WINDOW_MAPGEN_PAGE_RANDOM, WINDOW_MAPGEN_PAGE_SIMPLEX, WINDOW_MAPGEN_PAGE_COUNT }; enum { WIDX_BACKGROUND, WIDX_TITLE, WIDX_CLOSE, WIDX_PAGE_BACKGROUND, WIDX_TAB_1, WIDX_TAB_2, WIDX_TAB_3, WIDX_GENERATE, WIDX_MAP_SIZE = 8, WIDX_MAP_SIZE_UP, WIDX_MAP_SIZE_DOWN, WIDX_BASE_HEIGHT, WIDX_BASE_HEIGHT_UP, WIDX_BASE_HEIGHT_DOWN, WIDX_WATER_LEVEL, WIDX_WATER_LEVEL_UP, WIDX_WATER_LEVEL_DOWN, WIDX_FLOOR_TEXTURE, WIDX_WALL_TEXTURE, WIDX_RANDOM_TERRAIN = 8, WIDX_PLACE_TREES, WIDX_SIMPLEX_LABEL = 8, WIDX_SIMPLEX_LOW, WIDX_SIMPLEX_LOW_UP, WIDX_SIMPLEX_LOW_DOWN, WIDX_SIMPLEX_HIGH, WIDX_SIMPLEX_HIGH_UP, WIDX_SIMPLEX_HIGH_DOWN, WIDX_SIMPLEX_BASE_FREQ, WIDX_SIMPLEX_BASE_FREQ_UP, WIDX_SIMPLEX_BASE_FREQ_DOWN, WIDX_SIMPLEX_OCTAVES, WIDX_SIMPLEX_OCTAVES_UP, WIDX_SIMPLEX_OCTAVES_DOWN, WIDX_SIMPLEX_MAP_SIZE, WIDX_SIMPLEX_MAP_SIZE_UP, WIDX_SIMPLEX_MAP_SIZE_DOWN, WIDX_SIMPLEX_WATER_LEVEL, WIDX_SIMPLEX_WATER_LEVEL_UP, WIDX_SIMPLEX_WATER_LEVEL_DOWN, WIDX_SIMPLEX_FLOOR_TEXTURE, WIDX_SIMPLEX_WALL_TEXTURE, }; #pragma region Widgets static rct_widget window_mapgen_base_widgets[] = { { WWT_FRAME, 0, 0, 299, 0, 195, 0xFFFFFFFF, STR_NONE }, { WWT_CAPTION, 0, 1, 298, 1, 14, 2690, STR_WINDOW_TITLE_TIP }, { WWT_CLOSEBOX, 0, 287, 297, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, { WWT_RESIZE, 1, 0, 299, 43, 195, 0xFFFFFFFF, STR_NONE }, { WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, STR_NONE }, { WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, STR_NONE }, { WWT_TAB, 1, 65, 95, 17, 43, 0x2000144E, STR_NONE }, { WWT_DROPDOWN_BUTTON, 1, 104, 198, 52, 63, 2694, STR_NONE }, { WWT_SPINNER, 1, 104, 198, 52, 63, STR_NONE, STR_NONE }, { WWT_DROPDOWN_BUTTON, 1, 187, 197, 53, 57, STR_NUMERIC_UP, STR_NONE }, { WWT_DROPDOWN_BUTTON, 1, 187, 197, 58, 62, STR_NUMERIC_DOWN, STR_NONE }, { WWT_SPINNER, 1, 104, 198, 70, 81, STR_NONE, STR_NONE }, { WWT_DROPDOWN_BUTTON, 1, 187, 197, 71, 75, STR_NUMERIC_UP, STR_NONE }, { WWT_DROPDOWN_BUTTON, 1, 187, 197, 76, 80, STR_NUMERIC_DOWN, STR_NONE }, { WWT_SPINNER, 1, 104, 198, 88, 99, STR_NONE, STR_NONE }, { WWT_DROPDOWN_BUTTON, 1, 187, 197, 89, 93, STR_NUMERIC_UP, STR_NONE }, { WWT_DROPDOWN_BUTTON, 1, 187, 197, 94, 98, STR_NUMERIC_DOWN, STR_NONE }, { WWT_FLATBTN, 1, 104, 150, 106, 141, 0xFFFFFFFF, STR_CHANGE_BASE_LAND_TIP }, { WWT_FLATBTN, 1, 151, 197, 106, 141, 0xFFFFFFFF, STR_CHANGE_VERTICAL_LAND_TIP }, { WIDGETS_END }, }; static rct_widget window_mapgen_random_widgets[] = { { WWT_FRAME, 0, 0, 299, 0, 195, 0xFFFFFFFF, STR_NONE }, { WWT_CAPTION, 0, 1, 298, 1, 14, 2690, STR_WINDOW_TITLE_TIP }, { WWT_CLOSEBOX, 0, 287, 297, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, { WWT_RESIZE, 1, 0, 299, 43, 195, 0xFFFFFFFF, STR_NONE }, { WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, STR_NONE }, { WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, STR_NONE }, { WWT_TAB, 1, 65, 95, 17, 43, 0x2000144E, STR_NONE }, { WWT_DROPDOWN_BUTTON, 1, 104, 198, 52, 63, 2694, STR_NONE }, { WWT_CHECKBOX, 1, 4, 198, 52, 63, 2695, STR_NONE }, { WWT_CHECKBOX, 1, 4, 198, 70, 81, 2696, STR_NONE }, { WIDGETS_END }, }; static rct_widget window_mapgen_simplex_widgets[] = { { WWT_FRAME, 0, 0, 299, 0, 195, 0xFFFFFFFF, STR_NONE }, { WWT_CAPTION, 0, 1, 298, 1, 14, 2690, STR_WINDOW_TITLE_TIP }, { WWT_CLOSEBOX, 0, 287, 297, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, { WWT_RESIZE, 1, 0, 299, 43, 195, 0xFFFFFFFF, STR_NONE }, { WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, STR_NONE }, { WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, STR_NONE }, { WWT_TAB, 1, 65, 95, 17, 43, 0x2000144E, STR_NONE }, { WWT_DROPDOWN_BUTTON, 1, 104, 198, 52, 63, 2694, STR_NONE }, { WWT_12, 1, 4, 198, 52, 63, 2685, STR_NONE }, { WWT_SPINNER, 1, 104, 198, 70, 81, STR_NONE, STR_NONE }, { WWT_DROPDOWN_BUTTON, 1, 187, 197, 71, 75, STR_NUMERIC_UP, STR_NONE }, { WWT_DROPDOWN_BUTTON, 1, 187, 197, 76, 80, STR_NUMERIC_DOWN, STR_NONE }, { WWT_SPINNER, 1, 104, 198, 88, 99, STR_NONE, STR_NONE }, { WWT_DROPDOWN_BUTTON, 1, 187, 197, 89, 93, STR_NUMERIC_UP, STR_NONE }, { WWT_DROPDOWN_BUTTON, 1, 187, 197, 94, 98, STR_NUMERIC_DOWN, STR_NONE }, { WWT_SPINNER, 1, 104, 198, 106, 117, STR_NONE, STR_NONE }, { WWT_DROPDOWN_BUTTON, 1, 187, 197, 107, 111, STR_NUMERIC_UP, STR_NONE }, { WWT_DROPDOWN_BUTTON, 1, 187, 197, 112, 116, STR_NUMERIC_DOWN, STR_NONE }, { WWT_SPINNER, 1, 104, 198, 124, 135, STR_NONE, STR_NONE }, { WWT_DROPDOWN_BUTTON, 1, 187, 197, 125, 129, STR_NUMERIC_UP, STR_NONE }, { WWT_DROPDOWN_BUTTON, 1, 187, 197, 130, 134, STR_NUMERIC_DOWN, STR_NONE }, { WWT_SPINNER, 1, 104, 198, 148, 159, STR_NONE, STR_NONE }, { WWT_DROPDOWN_BUTTON, 1, 187, 197, 149, 153, STR_NUMERIC_UP, STR_NONE }, { WWT_DROPDOWN_BUTTON, 1, 187, 197, 154, 158, STR_NUMERIC_DOWN, STR_NONE }, { WWT_SPINNER, 1, 104, 198, 166, 177, STR_NONE, STR_NONE }, { WWT_DROPDOWN_BUTTON, 1, 187, 197, 167, 171, STR_NUMERIC_UP, STR_NONE }, { WWT_DROPDOWN_BUTTON, 1, 187, 197, 172, 176, STR_NUMERIC_DOWN, STR_NONE }, { WWT_FLATBTN, 1, 225, 271, 68, 103, 0xFFFFFFFF, STR_CHANGE_BASE_LAND_TIP }, { WWT_FLATBTN, 1, 225, 271, 104, 139, 0xFFFFFFFF, STR_CHANGE_VERTICAL_LAND_TIP }, { WIDGETS_END }, }; const int window_mapgen_tab_animation_divisor[] = { 1, 1, 1 }; const int window_mapgen_tab_animation_frames[] = { 1, 1, 1 }; static rct_widget *window_mapgen_page_widgets[] = { window_mapgen_base_widgets, window_mapgen_random_widgets, window_mapgen_simplex_widgets }; #pragma endregion #pragma region Events static void window_mapgen_base_mouseup(rct_window *w, int widgetIndex); static void window_mapgen_base_mousedown(int widgetIndex, rct_window *w, rct_widget* widget); static void window_mapgen_base_dropdown(rct_window *w, int widgetIndex, int dropdownIndex); static void window_mapgen_base_update(rct_window *w); static void window_mapgen_textinput(rct_window *w, int widgetIndex, char *text); static void window_mapgen_base_invalidate(rct_window *w); static void window_mapgen_base_paint(rct_window *w, rct_drawpixelinfo *dpi); static void window_mapgen_random_mouseup(rct_window *w, int widgetIndex); static void window_mapgen_random_mousedown(int widgetIndex, rct_window*w, rct_widget* widget); static void window_mapgen_random_update(rct_window *w); static void window_mapgen_random_invalidate(rct_window *w); static void window_mapgen_random_paint(rct_window *w, rct_drawpixelinfo *dpi); static void window_mapgen_simplex_mouseup(rct_window *w, int widgetIndex); static void window_mapgen_simplex_mousedown(int widgetIndex, rct_window *w, rct_widget* widget); static void window_mapgen_simplex_dropdown(rct_window *w, int widgetIndex, int dropdownIndex); static void window_mapgen_simplex_update(rct_window *w); static void window_mapgen_simplex_invalidate(rct_window *w); static void window_mapgen_simplex_paint(rct_window *w, rct_drawpixelinfo *dpi); static rct_window_event_list window_mapgen_base_events = { NULL, window_mapgen_base_mouseup, NULL, window_mapgen_base_mousedown, window_mapgen_base_dropdown, NULL, window_mapgen_base_update, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, window_mapgen_textinput, NULL, NULL, NULL, NULL, NULL, window_mapgen_base_invalidate, window_mapgen_base_paint, NULL }; static rct_window_event_list window_mapgen_random_events = { NULL, window_mapgen_random_mouseup, NULL, window_mapgen_random_mousedown, NULL, NULL, window_mapgen_random_update, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, window_mapgen_random_invalidate, window_mapgen_random_paint, NULL }; static rct_window_event_list window_mapgen_simplex_events = { NULL, window_mapgen_simplex_mouseup, NULL, window_mapgen_simplex_mousedown, window_mapgen_simplex_dropdown, NULL, window_mapgen_simplex_update, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, window_mapgen_textinput, NULL, NULL, NULL, NULL, NULL, window_mapgen_simplex_invalidate, window_mapgen_simplex_paint, NULL }; static rct_window_event_list *window_mapgen_page_events[] = { &window_mapgen_base_events, &window_mapgen_random_events, &window_mapgen_simplex_events }; #pragma endregion #pragma region Enabled widgets static uint32 window_mapgen_page_enabled_widgets[] = { (1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | (1 << WIDX_TAB_2) | (1 << WIDX_TAB_3) | (1 << WIDX_GENERATE) | (1 << WIDX_MAP_SIZE) | (1 << WIDX_MAP_SIZE_UP) | (1 << WIDX_MAP_SIZE_DOWN) | (1 << WIDX_BASE_HEIGHT) | (1 << WIDX_BASE_HEIGHT_UP) | (1 << WIDX_BASE_HEIGHT_DOWN) | (1 << WIDX_WATER_LEVEL) | (1 << WIDX_WATER_LEVEL_UP) | (1 << WIDX_WATER_LEVEL_DOWN) | (1 << WIDX_FLOOR_TEXTURE) | (1 << WIDX_WALL_TEXTURE), (1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | (1 << WIDX_TAB_2) | (1 << WIDX_TAB_3) | (1 << WIDX_GENERATE) | (1 << WIDX_RANDOM_TERRAIN) | (1 << WIDX_PLACE_TREES), (1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | (1 << WIDX_TAB_2) | (1 << WIDX_TAB_3) | (1 << WIDX_GENERATE) | (1 << WIDX_SIMPLEX_LABEL) | (1 << WIDX_SIMPLEX_LOW) | (1 << WIDX_SIMPLEX_LOW_UP) | (1 << WIDX_SIMPLEX_LOW_DOWN) | (1 << WIDX_SIMPLEX_HIGH) | (1 << WIDX_SIMPLEX_HIGH_UP) | (1 << WIDX_SIMPLEX_HIGH_DOWN) | (1 << WIDX_SIMPLEX_BASE_FREQ) | (1 << WIDX_SIMPLEX_BASE_FREQ_UP) | (1 << WIDX_SIMPLEX_BASE_FREQ_DOWN) | (1 << WIDX_SIMPLEX_OCTAVES) | (1 << WIDX_SIMPLEX_OCTAVES_UP) | (1 << WIDX_SIMPLEX_OCTAVES_DOWN) | (1 << WIDX_SIMPLEX_MAP_SIZE) | (1 << WIDX_SIMPLEX_MAP_SIZE_UP) | (1 << WIDX_SIMPLEX_MAP_SIZE_DOWN) | (1 << WIDX_SIMPLEX_WATER_LEVEL) | (1 << WIDX_SIMPLEX_WATER_LEVEL_UP) | (1 << WIDX_SIMPLEX_WATER_LEVEL_DOWN) | (1 << WIDX_SIMPLEX_FLOOR_TEXTURE) | (1 << WIDX_SIMPLEX_WALL_TEXTURE) }; static uint32 window_mapgen_page_hold_down_widgets[] = { (1 << WIDX_MAP_SIZE_UP) | (1 << WIDX_MAP_SIZE_DOWN) | (1 << WIDX_BASE_HEIGHT_UP) | (1 << WIDX_BASE_HEIGHT_DOWN) | (1 << WIDX_WATER_LEVEL_UP) | (1 << WIDX_WATER_LEVEL_DOWN), 0, (1 << WIDX_SIMPLEX_LOW_UP) | (1 << WIDX_SIMPLEX_LOW_DOWN) | (1 << WIDX_SIMPLEX_HIGH_UP) | (1 << WIDX_SIMPLEX_HIGH_DOWN) | (1 << WIDX_SIMPLEX_BASE_FREQ_UP) | (1 << WIDX_SIMPLEX_BASE_FREQ_DOWN) | (1 << WIDX_SIMPLEX_OCTAVES_UP) | (1 << WIDX_SIMPLEX_OCTAVES_DOWN) | (1 << WIDX_SIMPLEX_MAP_SIZE_UP) | (1 << WIDX_SIMPLEX_MAP_SIZE_DOWN) | (1 << WIDX_SIMPLEX_WATER_LEVEL_UP) | (1 << WIDX_SIMPLEX_WATER_LEVEL_DOWN) }; #pragma endregion const int window_mapgen_tab_animation_loops[] = { 16, 16, 16 }; #define MINIMUM_MAP_SIZE_TECHNICAL 15 #define MAXIMUM_MAP_SIZE_TECHNICAL 256 #define MINIMUM_MAP_SIZE_PRACTICAL MINIMUM_MAP_SIZE_TECHNICAL-2 #define MAXIMUM_MAP_SIZE_PRACTICAL MAXIMUM_MAP_SIZE_TECHNICAL-2 #define BASESIZE_MIN 0 #define BASESIZE_MAX 60 #define WATERLEVEL_MIN 0 #define WATERLEVEL_MAX 54 static void window_mapgen_set_page(rct_window *w, int page); static void window_mapgen_set_pressed_tab(rct_window *w); static void window_mapgen_anchor_border_widgets(rct_window *w); static void window_mapgen_draw_tab_images(rct_drawpixelinfo *dpi, rct_window *w); static char window_land_floor_texture_order[] = { TERRAIN_SAND_DARK, TERRAIN_SAND_LIGHT, TERRAIN_DIRT, TERRAIN_GRASS_CLUMPS, TERRAIN_GRASS, TERRAIN_ROCK, TERRAIN_SAND, TERRAIN_MARTIAN, TERRAIN_CHECKERBOARD, TERRAIN_ICE, TERRAIN_GRID_RED, TERRAIN_GRID_YELLOW, TERRAIN_GRID_BLUE, TERRAIN_GRID_GREEN }; static char window_land_wall_texture_order[] = { TERRAIN_EDGE_ROCK, TERRAIN_EDGE_WOOD_RED, TERRAIN_EDGE_WOOD_BLACK, TERRAIN_EDGE_ICE, 0, 0 }; static int _mapSize = 150; static int _baseHeight = 12; static int _waterLevel = 16; static int _floorTexture = TERRAIN_GRASS; static int _wallTexture = TERRAIN_EDGE_ROCK; static int _randomTerrrain = 1; static int _placeTrees = 1; static int _simplex_low = 6; static int _simplex_high = 10; static sint32 _simplex_base_freq = 60; static int _simplex_octaves = 4; rct_window *window_mapgen_open() { rct_window *w; w = window_bring_to_front_by_class(WC_MAPGEN); if (w == NULL) { w = window_create_centred( 300, 200, window_mapgen_page_events[0], WC_MAPGEN, WF_10 ); w->number = 0; w->frame_no = 0; } w->page = WINDOW_MAPGEN_PAGE_BASE; window_invalidate(w); w->widgets = window_mapgen_page_widgets[WINDOW_MAPGEN_PAGE_BASE]; w->enabled_widgets = window_mapgen_page_enabled_widgets[WINDOW_MAPGEN_PAGE_BASE]; w->hold_down_widgets = window_mapgen_page_hold_down_widgets[WINDOW_MAPGEN_PAGE_BASE]; w->event_handlers = window_mapgen_page_events[WINDOW_MAPGEN_PAGE_BASE]; w->pressed_widgets = 0; w->disabled_widgets = 0; window_init_scroll_widgets(w); return w; } #pragma region Base page static void window_mapgen_base_mouseup(rct_window *w, int widgetIndex) { mapgen_settings mapgenSettings; switch (widgetIndex) { case WIDX_CLOSE: window_close(w); break; case WIDX_TAB_1: case WIDX_TAB_2: case WIDX_TAB_3: window_mapgen_set_page(w, widgetIndex - WIDX_TAB_1); break; case WIDX_GENERATE: mapgenSettings.mapSize = _mapSize; mapgenSettings.height = _baseHeight + 2; mapgenSettings.waterLevel = _waterLevel + 2; mapgenSettings.floor = _floorTexture; mapgenSettings.wall = _wallTexture; mapgen_generate_blank(&mapgenSettings); gfx_invalidate_screen(); break; case WIDX_MAP_SIZE: TextInputDescriptionArgs[0] = MINIMUM_MAP_SIZE_PRACTICAL; TextInputDescriptionArgs[1] = MAXIMUM_MAP_SIZE_PRACTICAL; // Practical map size is 2 lower than the technical map size window_text_input_open(w, WIDX_MAP_SIZE, STR_MAP_SIZE_2, STR_ENTER_MAP_SIZE, 5182, _mapSize - 2, 4); break; case WIDX_BASE_HEIGHT: TextInputDescriptionArgs[0] = (BASESIZE_MIN - 12) / 2; TextInputDescriptionArgs[1] = (BASESIZE_MAX - 12) / 2; window_text_input_open(w, WIDX_BASE_HEIGHT, STR_BASE_HEIGHT, STR_ENTER_BASE_HEIGHT, 5182, (_baseHeight - 12) / 2, 3); break; case WIDX_WATER_LEVEL: TextInputDescriptionArgs[0] = (WATERLEVEL_MIN - 12) / 2; TextInputDescriptionArgs[1] = (WATERLEVEL_MAX - 12) / 2; window_text_input_open(w, WIDX_WATER_LEVEL, STR_WATER_LEVEL, STR_ENTER_WATER_LEVEL, 5182, (_waterLevel - 12) / 2, 3); break; } } static void window_mapgen_base_mousedown(int widgetIndex, rct_window *w, rct_widget* widget) { int i; int defaultIndex = -1; switch (widgetIndex) { case WIDX_MAP_SIZE_UP: _mapSize = min(_mapSize + 1, MAXIMUM_MAP_SIZE_TECHNICAL); window_invalidate(w); break; case WIDX_MAP_SIZE_DOWN: _mapSize = max(_mapSize - 1, MINIMUM_MAP_SIZE_TECHNICAL); window_invalidate(w); break; case WIDX_BASE_HEIGHT_UP: _baseHeight = min(_baseHeight + 2, BASESIZE_MAX); window_invalidate(w); break; case WIDX_BASE_HEIGHT_DOWN: _baseHeight = max(_baseHeight - 2, BASESIZE_MIN); window_invalidate(w); break; case WIDX_WATER_LEVEL_UP: _waterLevel = min(_waterLevel + 2, WATERLEVEL_MAX); window_invalidate(w); break; case WIDX_WATER_LEVEL_DOWN: _waterLevel = max(_waterLevel - 2, WATERLEVEL_MIN); window_invalidate(w); break; case WIDX_FLOOR_TEXTURE: for (i = 0; i < 14; i++) { gDropdownItemsFormat[i] = -1; gDropdownItemsArgs[i] = SPR_FLOOR_TEXTURE_GRASS + window_land_floor_texture_order[i]; if (window_land_floor_texture_order[i] == _floorTexture) defaultIndex = i; } window_dropdown_show_image( w->x + widget->left, w->y + widget->top, widget->bottom - widget->top, w->colours[2], 0, 14, 47, 36, gAppropriateImageDropdownItemsPerRow[14] ); gDropdownDefaultIndex = defaultIndex; break; case WIDX_WALL_TEXTURE: for (i = 0; i < 4; i++) { gDropdownItemsFormat[i] = -1; gDropdownItemsArgs[i] = SPR_WALL_TEXTURE_ROCK + window_land_wall_texture_order[i]; if (window_land_wall_texture_order[i] == _wallTexture) defaultIndex = i; } window_dropdown_show_image( w->x + widget->left, w->y + widget->top, widget->bottom - widget->top, w->colours[2], 0, 4, 47, 36, gAppropriateImageDropdownItemsPerRow[4] ); gDropdownDefaultIndex = defaultIndex; break; } } static void window_mapgen_base_dropdown(rct_window *w, int widgetIndex, int dropdownIndex) { int type; switch (widgetIndex) { case WIDX_FLOOR_TEXTURE: if (dropdownIndex == -1) dropdownIndex = gDropdownHighlightedIndex; type = (dropdownIndex == -1) ? _floorTexture : (uint32)gDropdownItemsArgs[dropdownIndex] - SPR_FLOOR_TEXTURE_GRASS; if (gLandToolTerrainSurface == type) { gLandToolTerrainSurface = 255; } else { gLandToolTerrainSurface = type; _floorTexture = type; } window_invalidate(w); break; case WIDX_WALL_TEXTURE: if (dropdownIndex == -1) dropdownIndex = gDropdownHighlightedIndex; type = (dropdownIndex == -1) ? _wallTexture : (uint32)gDropdownItemsArgs[dropdownIndex] - SPR_WALL_TEXTURE_ROCK; if (gLandToolTerrainEdge == type) { gLandToolTerrainEdge = 255; } else { gLandToolTerrainEdge = type; _wallTexture = type; } window_invalidate(w); break; } } static void window_mapgen_base_update(rct_window *w) { // Tab animation if (++w->frame_no >= window_mapgen_tab_animation_loops[w->page]) w->frame_no = 0; widget_invalidate(w, WIDX_TAB_1); } static void window_mapgen_textinput(rct_window *w, int widgetIndex, char *text) { int value; char* end; if (text == NULL) return; value = strtol(text, &end, 10); if (*end != '\0') { return; } switch (widgetIndex) { case WIDX_MAP_SIZE: case WIDX_SIMPLEX_MAP_SIZE: // The practical size is 2 lower than the technical size value += 2; _mapSize = clamp(MINIMUM_MAP_SIZE_TECHNICAL, value, MAXIMUM_MAP_SIZE_TECHNICAL); break; case WIDX_BASE_HEIGHT: _baseHeight = clamp(BASESIZE_MIN, (value * 2) + 12, BASESIZE_MAX); break; case WIDX_WATER_LEVEL: _waterLevel = clamp(WATERLEVEL_MIN, (value * 2) + 12, WATERLEVEL_MAX); break; } window_invalidate(w); } static void window_mapgen_base_invalidate(rct_window *w) { colour_scheme_update(w); if (w->widgets != window_mapgen_page_widgets[WINDOW_MAPGEN_PAGE_BASE]) { w->widgets = window_mapgen_page_widgets[WINDOW_MAPGEN_PAGE_BASE]; window_init_scroll_widgets(w); } w->widgets[WIDX_FLOOR_TEXTURE].image = SPR_FLOOR_TEXTURE_GRASS + _floorTexture; w->widgets[WIDX_WALL_TEXTURE].image = SPR_WALL_TEXTURE_ROCK + _wallTexture; window_mapgen_set_pressed_tab(w); window_mapgen_anchor_border_widgets(w); } static void window_mapgen_base_paint(rct_window *w, rct_drawpixelinfo *dpi) { uint16 arg; window_draw_widgets(w, dpi); window_mapgen_draw_tab_images(dpi, w); gfx_draw_string_left(dpi, STR_MAP_SIZE, 0, 0, w->x + 4, w->y + w->widgets[WIDX_MAP_SIZE].top + 1); gfx_draw_string_left(dpi, STR_BASE_HEIGHT_LABEL, 0, 0, w->x + 4, w->y + w->widgets[WIDX_BASE_HEIGHT].top + 1); gfx_draw_string_left(dpi, STR_WATER_LEVEL_LABEL, 0, 0, w->x + 4, w->y + w->widgets[WIDX_WATER_LEVEL].top + 1); gfx_draw_string_left(dpi, STR_TERRAIN_LABEL, 0, 0, w->x + 4, w->y + w->widgets[WIDX_FLOOR_TEXTURE].top + 1); // The practical map size is 2 lower than the technical map size uint16 mapSizeArgs[2] = { _mapSize - 2, _mapSize -2 }; gfx_draw_string_left(dpi, 839, mapSizeArgs, w->colours[1], w->x + w->widgets[WIDX_MAP_SIZE].left + 1, w->y + w->widgets[WIDX_MAP_SIZE].top + 1); arg = (_baseHeight - 12) / 2; gfx_draw_string_left(dpi, 1737, &arg, w->colours[1], w->x + w->widgets[WIDX_BASE_HEIGHT].left + 1, w->y + w->widgets[WIDX_BASE_HEIGHT].top + 1); arg = (_waterLevel - 12) / 2; gfx_draw_string_left(dpi, 1737, &arg, w->colours[1], w->x + w->widgets[WIDX_WATER_LEVEL].left + 1, w->y + w->widgets[WIDX_WATER_LEVEL].top + 1); } #pragma endregion #pragma region Random page static void window_mapgen_random_mouseup(rct_window *w, int widgetIndex) { mapgen_settings mapgenSettings; switch (widgetIndex) { case WIDX_CLOSE: window_close(w); break; case WIDX_TAB_1: case WIDX_TAB_2: case WIDX_TAB_3: window_mapgen_set_page(w, widgetIndex - WIDX_TAB_1); break; case WIDX_GENERATE: mapgenSettings.mapSize = _mapSize; mapgenSettings.height = _baseHeight + 2; mapgenSettings.waterLevel = _waterLevel + 2; mapgenSettings.floor = _randomTerrrain ? -1 : _floorTexture; mapgenSettings.wall = _randomTerrrain ? -1 : _wallTexture; mapgenSettings.trees = _placeTrees; mapgenSettings.simplex_low = util_rand() % 4; mapgenSettings.simplex_high = 12 + (util_rand() % (32 - 12)); mapgenSettings.simplex_base_freq = 1.75f; mapgenSettings.simplex_octaves = 6; mapgen_generate(&mapgenSettings); gfx_invalidate_screen(); break; case WIDX_RANDOM_TERRAIN: _randomTerrrain ^= 1; break; case WIDX_PLACE_TREES: _placeTrees ^= 1; break; } } static void window_mapgen_random_mousedown(int widgetIndex, rct_window *w, rct_widget* widget) { } static void window_mapgen_random_update(rct_window *w) { // Tab animation if (++w->frame_no >= window_mapgen_tab_animation_loops[w->page]) w->frame_no = 0; widget_invalidate(w, WIDX_TAB_2); } static void window_mapgen_random_invalidate(rct_window *w) { colour_scheme_update(w); if (w->widgets != window_mapgen_page_widgets[WINDOW_MAPGEN_PAGE_RANDOM]) { w->widgets = window_mapgen_page_widgets[WINDOW_MAPGEN_PAGE_RANDOM]; window_init_scroll_widgets(w); } w->pressed_widgets = 0; if (_randomTerrrain) w->pressed_widgets |= 1 << WIDX_RANDOM_TERRAIN; if (_placeTrees) w->pressed_widgets |= 1 << WIDX_PLACE_TREES; window_mapgen_set_pressed_tab(w); window_mapgen_anchor_border_widgets(w); } static void window_mapgen_random_paint(rct_window *w, rct_drawpixelinfo *dpi) { window_draw_widgets(w, dpi); window_mapgen_draw_tab_images(dpi, w); } #pragma endregion #pragma region Simplex page static void window_mapgen_simplex_mouseup(rct_window *w, int widgetIndex) { mapgen_settings mapgenSettings; switch (widgetIndex) { case WIDX_CLOSE: window_close(w); break; case WIDX_TAB_1: case WIDX_TAB_2: case WIDX_TAB_3: window_mapgen_set_page(w, widgetIndex - WIDX_TAB_1); break; case WIDX_SIMPLEX_MAP_SIZE: TextInputDescriptionArgs[0] = MINIMUM_MAP_SIZE_PRACTICAL; TextInputDescriptionArgs[1] = MAXIMUM_MAP_SIZE_PRACTICAL; // Practical map size is 2 lower than the technical map size window_text_input_open(w, WIDX_SIMPLEX_MAP_SIZE, STR_MAP_SIZE_2, STR_ENTER_MAP_SIZE, 5182, _mapSize - 2, 4); break; case WIDX_GENERATE: mapgenSettings.mapSize = _mapSize; mapgenSettings.height = _baseHeight; mapgenSettings.waterLevel = _waterLevel + 2; mapgenSettings.floor = _floorTexture; mapgenSettings.wall = _wallTexture; mapgenSettings.trees = 0; mapgenSettings.simplex_low = _simplex_low; mapgenSettings.simplex_high = _simplex_high; mapgenSettings.simplex_base_freq = ((float)_simplex_base_freq) / 100.00f; mapgenSettings.simplex_octaves = _simplex_octaves; mapgen_generate(&mapgenSettings); gfx_invalidate_screen(); break; } } static void window_mapgen_simplex_mousedown(int widgetIndex, rct_window *w, rct_widget* widget) { int i; int defaultIndex = -1; switch (widgetIndex) { case WIDX_SIMPLEX_LOW_UP: _simplex_low = min(_simplex_low + 1, 24); window_invalidate(w); break; case WIDX_SIMPLEX_LOW_DOWN: _simplex_low = max(_simplex_low - 1, 0); window_invalidate(w); break; case WIDX_SIMPLEX_HIGH_UP: _simplex_high = min(_simplex_high + 1, 36); window_invalidate(w); break; case WIDX_SIMPLEX_HIGH_DOWN: _simplex_high = max(_simplex_high - 1, 0); window_invalidate(w); break; case WIDX_SIMPLEX_BASE_FREQ_UP: _simplex_base_freq = min(_simplex_base_freq + 5, 1000); window_invalidate(w); break; case WIDX_SIMPLEX_BASE_FREQ_DOWN: _simplex_base_freq = max(_simplex_base_freq - 5, 0); window_invalidate(w); break; case WIDX_SIMPLEX_OCTAVES_UP: _simplex_octaves = min(_simplex_octaves + 1, 10); window_invalidate(w); break; case WIDX_SIMPLEX_OCTAVES_DOWN: _simplex_octaves = max(_simplex_octaves - 1, 1); window_invalidate(w); break; case WIDX_SIMPLEX_MAP_SIZE_UP: _mapSize = min(_mapSize + 1, MAXIMUM_MAP_SIZE_TECHNICAL); window_invalidate(w); break; case WIDX_SIMPLEX_MAP_SIZE_DOWN: _mapSize = max(_mapSize - 1, MINIMUM_MAP_SIZE_TECHNICAL); window_invalidate(w); break; case WIDX_SIMPLEX_WATER_LEVEL_UP: _waterLevel = min(_waterLevel + 2, 54); window_invalidate(w); break; case WIDX_SIMPLEX_WATER_LEVEL_DOWN: _waterLevel = max(_waterLevel - 2, 0); window_invalidate(w); break; case WIDX_SIMPLEX_FLOOR_TEXTURE: for (i = 0; i < 14; i++) { gDropdownItemsFormat[i] = -1; gDropdownItemsArgs[i] = SPR_FLOOR_TEXTURE_GRASS + window_land_floor_texture_order[i]; if (window_land_floor_texture_order[i] == _floorTexture) defaultIndex = i; } window_dropdown_show_image( w->x + widget->left, w->y + widget->top, widget->bottom - widget->top, w->colours[2], 0, 14, 47, 36, gAppropriateImageDropdownItemsPerRow[14] ); gDropdownDefaultIndex = defaultIndex; break; case WIDX_SIMPLEX_WALL_TEXTURE: for (i = 0; i < 4; i++) { gDropdownItemsFormat[i] = -1; gDropdownItemsArgs[i] = SPR_WALL_TEXTURE_ROCK + window_land_wall_texture_order[i]; if (window_land_wall_texture_order[i] == _wallTexture) defaultIndex = i; } window_dropdown_show_image( w->x + widget->left, w->y + widget->top, widget->bottom - widget->top, w->colours[2], 0, 4, 47, 36, gAppropriateImageDropdownItemsPerRow[4] ); gDropdownDefaultIndex = defaultIndex; break; } } static void window_mapgen_simplex_dropdown(rct_window *w, int widgetIndex, int dropdownIndex) { int type; switch (widgetIndex) { case WIDX_SIMPLEX_FLOOR_TEXTURE: if (dropdownIndex == -1) dropdownIndex = gDropdownHighlightedIndex; type = (dropdownIndex == -1) ? _floorTexture : (uint32)gDropdownItemsArgs[dropdownIndex] - SPR_FLOOR_TEXTURE_GRASS; if (gLandToolTerrainSurface == type) { gLandToolTerrainSurface = 255; } else { gLandToolTerrainSurface = type; _floorTexture = type; } window_invalidate(w); break; case WIDX_SIMPLEX_WALL_TEXTURE: if (dropdownIndex == -1) dropdownIndex = gDropdownHighlightedIndex; type = (dropdownIndex == -1) ? _wallTexture : (uint32)gDropdownItemsArgs[dropdownIndex] - SPR_WALL_TEXTURE_ROCK; if (gLandToolTerrainEdge == type) { gLandToolTerrainEdge = 255; } else { gLandToolTerrainEdge = type; _wallTexture = type; } window_invalidate(w); break; } } static void window_mapgen_simplex_update(rct_window *w) { // Tab animation if (++w->frame_no >= window_mapgen_tab_animation_loops[w->page]) w->frame_no = 0; widget_invalidate(w, WIDX_TAB_3); } static void window_mapgen_simplex_invalidate(rct_window *w) { colour_scheme_update(w); if (w->widgets != window_mapgen_page_widgets[WINDOW_MAPGEN_PAGE_SIMPLEX]) { w->widgets = window_mapgen_page_widgets[WINDOW_MAPGEN_PAGE_SIMPLEX]; window_init_scroll_widgets(w); } w->widgets[WIDX_SIMPLEX_FLOOR_TEXTURE].image = SPR_FLOOR_TEXTURE_GRASS + _floorTexture; w->widgets[WIDX_SIMPLEX_WALL_TEXTURE].image = SPR_WALL_TEXTURE_ROCK + _wallTexture; window_mapgen_set_pressed_tab(w); window_mapgen_anchor_border_widgets(w); } static void window_mapgen_simplex_paint(rct_window *w, rct_drawpixelinfo *dpi) { uint16 arg; window_draw_widgets(w, dpi); window_mapgen_draw_tab_images(dpi, w); gfx_draw_string_left(dpi, 2686, 0, 0, w->x + 5, w->y + w->widgets[WIDX_SIMPLEX_LOW].top + 1); gfx_draw_string_left(dpi, 2687, 0, 0, w->x + 5, w->y + w->widgets[WIDX_SIMPLEX_HIGH].top + 1); gfx_draw_string_left(dpi, 2688, 0, 0, w->x + 5, w->y + w->widgets[WIDX_SIMPLEX_BASE_FREQ].top + 1); gfx_draw_string_left(dpi, 2689, 0, 0, w->x + 5, w->y + w->widgets[WIDX_SIMPLEX_OCTAVES].top + 1); gfx_draw_string_left(dpi, STR_MAP_SIZE, 0, 0, w->x + 5, w->y + w->widgets[WIDX_SIMPLEX_MAP_SIZE].top + 1); gfx_draw_string_left(dpi, 2692, 0, 0, w->x + 5, w->y + w->widgets[WIDX_SIMPLEX_WATER_LEVEL].top + 1); gfx_draw_string_left(dpi, 1737, &_simplex_low, w->colours[1], w->x + w->widgets[WIDX_SIMPLEX_LOW].left + 1, w->y + w->widgets[WIDX_SIMPLEX_LOW].top + 1); gfx_draw_string_left(dpi, 1737, &_simplex_high, w->colours[1], w->x + w->widgets[WIDX_SIMPLEX_HIGH].left + 1, w->y + w->widgets[WIDX_SIMPLEX_HIGH].top + 1); gfx_draw_string_left(dpi, 3311, &_simplex_base_freq, w->colours[1], w->x + w->widgets[WIDX_SIMPLEX_BASE_FREQ].left + 1, w->y + w->widgets[WIDX_SIMPLEX_BASE_FREQ].top + 1); gfx_draw_string_left(dpi, 1737, &_simplex_octaves, w->colours[1], w->x + w->widgets[WIDX_SIMPLEX_OCTAVES].left + 1, w->y + w->widgets[WIDX_SIMPLEX_OCTAVES].top + 1); // The practical map size is 2 lower than the technical map size uint16 mapSizeArgs[2] = { _mapSize - 2, _mapSize - 2 }; gfx_draw_string_left(dpi, 839, mapSizeArgs, w->colours[1], w->x + w->widgets[WIDX_SIMPLEX_MAP_SIZE].left + 1, w->y + w->widgets[WIDX_SIMPLEX_MAP_SIZE].top + 1); arg = (_waterLevel - 12) / 2; gfx_draw_string_left(dpi, 1737, &arg, w->colours[1], w->x + w->widgets[WIDX_SIMPLEX_WATER_LEVEL].left + 1, w->y + w->widgets[WIDX_SIMPLEX_WATER_LEVEL].top + 1); } #pragma endregion #pragma region Common static void window_mapgen_set_page(rct_window *w, int page) { w->page = page; w->frame_no = 0; if (w->viewport != NULL) { w->viewport->width = 0; w->viewport = NULL; } w->enabled_widgets = window_mapgen_page_enabled_widgets[page]; w->hold_down_widgets = window_mapgen_page_hold_down_widgets[page]; w->event_handlers = window_mapgen_page_events[page]; w->widgets = window_mapgen_page_widgets[page]; w->disabled_widgets = 0; w->pressed_widgets = 0; window_init_scroll_widgets(w); window_invalidate(w); } static void window_mapgen_set_pressed_tab(rct_window *w) { int i; for (i = 0; i < WINDOW_MAPGEN_PAGE_COUNT; i++) w->pressed_widgets &= ~(1 << (WIDX_TAB_1 + i)); w->pressed_widgets |= 1LL << (WIDX_TAB_1 + w->page); } static void window_mapgen_anchor_border_widgets(rct_window *w) { int width = w->widgets[WIDX_GENERATE].right - w->widgets[WIDX_GENERATE].left; int height = w->widgets[WIDX_GENERATE].bottom - w->widgets[WIDX_GENERATE].top; w->widgets[WIDX_GENERATE].left = w->width - 3 - width; w->widgets[WIDX_GENERATE].right = w->width - 3; w->widgets[WIDX_GENERATE].bottom = w->height - 3; w->widgets[WIDX_GENERATE].top = w->height - 3 - height; w->widgets[WIDX_BACKGROUND].right = w->width - 1; w->widgets[WIDX_BACKGROUND].bottom = w->height - 1; w->widgets[WIDX_PAGE_BACKGROUND].right = w->width - 1; w->widgets[WIDX_PAGE_BACKGROUND].bottom = w->height - 1; w->widgets[WIDX_TITLE].right = w->width - 2; w->widgets[WIDX_CLOSE].left = w->width - 13; w->widgets[WIDX_CLOSE].right = w->width - 3; } static void window_mapgen_draw_tab_image(rct_drawpixelinfo *dpi, rct_window *w, int page, int spriteIndex) { int widgetIndex = WIDX_TAB_1 + page; if (!(w->disabled_widgets & (1LL << widgetIndex))) { if (w->page == page) { int frame = w->frame_no / window_mapgen_tab_animation_divisor[w->page]; spriteIndex += (frame % window_mapgen_tab_animation_frames[w->page]); } gfx_draw_sprite(dpi, spriteIndex, w->x + w->widgets[widgetIndex].left, w->y + w->widgets[widgetIndex].top, 0); } } static void window_mapgen_draw_tab_images(rct_drawpixelinfo *dpi, rct_window *w) { window_mapgen_draw_tab_image(dpi, w, WINDOW_MAPGEN_PAGE_BASE, SPR_G2_TAB_LAND); window_mapgen_draw_tab_image(dpi, w, WINDOW_MAPGEN_PAGE_RANDOM, SPR_G2_TAB_TREE); window_mapgen_draw_tab_image(dpi, w, WINDOW_MAPGEN_PAGE_SIMPLEX, SPR_G2_TAB_PENCIL); } #pragma endregion