diff --git a/data/language/english_uk.txt b/data/language/english_uk.txt index 3f031494f6..ac2dad12af 100644 --- a/data/language/english_uk.txt +++ b/data/language/english_uk.txt @@ -2692,13 +2692,13 @@ STR_2686 :??? STR_2687 :??? STR_2688 :??? STR_2689 :??? -STR_2690 :??? -STR_2691 :??? -STR_2692 :??? -STR_2693 :??? -STR_2694 :??? -STR_2695 :??? -STR_2696 :??? +STR_2690 :Map Generation +STR_2691 :{WINDOW_COLOUR_2}Base height: +STR_2692 :{WINDOW_COLOUR_2}Water level: +STR_2693 :{WINDOW_COLOUR_2}Terrain: +STR_2694 :Generate +STR_2695 :Random terrain +STR_2696 :Place trees STR_2697 :??? STR_2698 :??? STR_2699 :??? diff --git a/data/language/english_us.txt b/data/language/english_us.txt index feb888bde1..8da74f757e 100644 --- a/data/language/english_us.txt +++ b/data/language/english_us.txt @@ -2692,13 +2692,13 @@ STR_2686 :??? STR_2687 :??? STR_2688 :??? STR_2689 :??? -STR_2690 :??? -STR_2691 :??? -STR_2692 :??? -STR_2693 :??? -STR_2694 :??? -STR_2695 :??? -STR_2696 :??? +STR_2690 :Map Generation +STR_2691 :{WINDOW_COLOUR_2}Base height: +STR_2692 :{WINDOW_COLOUR_2}Water level: +STR_2693 :{WINDOW_COLOUR_2}Terrain: +STR_2694 :Generate +STR_2695 :Random terrain +STR_2696 :Place trees STR_2697 :??? STR_2698 :??? STR_2699 :??? diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj index 328636c259..5e35558d42 100644 --- a/projects/openrct2.vcxproj +++ b/projects/openrct2.vcxproj @@ -73,7 +73,6 @@ - @@ -89,16 +88,15 @@ - - + @@ -126,6 +124,7 @@ + @@ -136,6 +135,8 @@ + + @@ -189,7 +190,6 @@ - @@ -201,6 +201,8 @@ + + diff --git a/projects/openrct2.vcxproj.filters b/projects/openrct2.vcxproj.filters index 6020eafffc..4ac5e713de 100644 --- a/projects/openrct2.vcxproj.filters +++ b/projects/openrct2.vcxproj.filters @@ -120,9 +120,6 @@ Source\Windows - - Source\Windows - Source\Windows @@ -330,8 +327,6 @@ Source\Drawing - - Source @@ -350,14 +345,14 @@ Source\Windows - + Source\Windows Source\Windows - + Source\Windows @@ -392,9 +387,6 @@ Source - - Source - Source\Windows @@ -404,9 +396,6 @@ Source\Windows - - Source\Windows - Source\Localisation @@ -422,7 +411,19 @@ Source\Windows - + + Source\World + + + Source\World + + + Source\Windows + + + Source\Windows + + Source\Ride @@ -610,12 +611,15 @@ Source - - Source - Source + + Source\World + + + Source\World + Source\Ride diff --git a/projects/openrct2.vcxproj.user b/projects/openrct2.vcxproj.user index 97b50ef56d..80981e45c6 100644 --- a/projects/openrct2.vcxproj.user +++ b/projects/openrct2.vcxproj.user @@ -7,14 +7,10 @@ $(TargetDir)\openrct2.exe WindowsLocalDebugger $(TargetDir) - - $(TargetDir)\openrct2.exe $(TargetDir) WindowsLocalDebugger - - \ No newline at end of file diff --git a/src/editor.c b/src/editor.c index 0e833d7869..493a655b18 100644 --- a/src/editor.c +++ b/src/editor.c @@ -62,7 +62,7 @@ void editor_load() pause_sounds(); unpause_sounds(); object_unload_all(); - map_init(); + map_init(150); RCT2_CALLPROC_EBPSAFE(0x006B9CB0); reset_park_entrances(); user_string_clear_all(); @@ -156,7 +156,7 @@ void editor_convert_save_to_scenario() format_string(s6Info->details, STR_NO_DETAILS_YET, NULL); s6Info->name[0] = 0; - } +} RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) = SCREEN_FLAGS_SCENARIO_EDITOR; s6Info->var_000 = 4; @@ -209,7 +209,7 @@ void trackdesigner_load() rct_window *mainWindow; object_unload_all(); - map_init(); + map_init(150); set_all_land_owned(); RCT2_CALLPROC_EBPSAFE(0x006B9CB0); reset_park_entrances(); @@ -246,7 +246,7 @@ void trackmanager_load() rct_window *mainWindow; object_unload_all(); - map_init(); + map_init(150); set_all_land_owned(); RCT2_CALLPROC_EBPSAFE(0x006B9CB0); reset_park_entrances(); diff --git a/src/game.c b/src/game.c index 309ff41940..c25f8c264c 100644 --- a/src/game.c +++ b/src/game.c @@ -71,7 +71,7 @@ void game_reduce_game_speed() void game_create_windows() { window_main_open(); - window_game_top_toolbar_open(); + window_top_toolbar_open(); window_game_bottom_toolbar_open(); RCT2_CALLPROC_EBPSAFE(0x0066B905); } diff --git a/src/input.c b/src/input.c index 896ff4596a..2714857616 100644 --- a/src/input.c +++ b/src/input.c @@ -97,7 +97,7 @@ void game_handle_input() if (RCT2_GLOBAL(0x009DEA64, uint16) & 2) { RCT2_GLOBAL(0x009DEA64, uint16) &= ~2; game_do_command(0, 1, 0, 0, GAME_COMMAND_LOAD_OR_QUIT, 2, 0); - } +} if (RCT2_GLOBAL(0x009ABDF2, uint8) != 0) { for (w = g_window_list; w < RCT2_GLOBAL(RCT2_ADDRESS_NEW_WINDOW_PTR, rct_window*); w++) @@ -112,7 +112,7 @@ void game_handle_input() break; game_handle_input_mouse(x, y, state & 0xFF); - } +} if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_5) { game_handle_input_mouse(x, y, state); @@ -123,8 +123,8 @@ void game_handle_input() game_handle_input_mouse(x, y, state); process_mouse_over(x, y); process_mouse_tool(x, y); - } - } +} +} for (w = g_window_list; w < RCT2_GLOBAL(RCT2_ADDRESS_NEW_WINDOW_PTR, rct_window*); w++) RCT2_CALLPROC_X(w->event_handlers[WE_UNKNOWN_08], 0, 0, 0, 0,(int) w, 0, 0); @@ -133,7 +133,7 @@ void game_handle_input() /** * * rct2: 0x006E83C7 - */ +*/ static void game_get_next_input(int *x, int *y, int *state) { rct_mouse_data* eax = get_mouse_input(); @@ -142,7 +142,7 @@ static void game_get_next_input(int *x, int *y, int *state) *y = gCursorState.y; *state = 0; return; - } +} *x = eax->x; *y = eax->y; @@ -172,7 +172,7 @@ static void game_get_next_input(int *x, int *y, int *state) } /** - * + * * rct2: 0x00407074 */ static rct_mouse_data* get_mouse_input() @@ -185,7 +185,7 @@ static rct_mouse_data* get_mouse_input() RCT2_GLOBAL(RCT2_ADDRESS_MOUSE_READ_INDEX, uint32) = (read_index + 1) % 64; return &mouse_buffer[read_index]; -} + } /** * @@ -253,8 +253,8 @@ static void game_handle_input_mouse(int x, int y, int state) input_viewport_drag_end(); if (RCT2_GLOBAL(0x009DE540, sint16) < 500) { viewport_interaction_right_click(x, y); - } - } + } + } break; case INPUT_STATE_DROPDOWN_ACTIVE: input_state_widget_pressed(x, y, state, widgetIndex, w, widget); @@ -305,10 +305,10 @@ static void game_handle_input_mouse(int x, int y, int state) else{ if ((RCT2_GLOBAL(0x9DE518, uint32) & (1 << 4))) break; - + viewport_interaction_left_click(x, y); - } - } + } + } break; case INPUT_STATE_SCROLL_LEFT: if (state == 0) @@ -326,14 +326,14 @@ static void game_handle_input_mouse(int x, int y, int state) if (state == 0 || state == 2) input_window_resize_continue(w, x, y); - } + } break; case 9: RCT2_CALLPROC_X(0x006E8ACB, x, y, state, widgetIndex, (int)w, (int)widget, 0); break; - } + } } - + #pragma region Window positioning / resizing void input_window_position_begin(rct_window *w, int widgetIndex, int x, int y) @@ -344,7 +344,7 @@ void input_window_position_begin(rct_window *w, int widgetIndex, int x, int y) _dragWindowClass = w->classification; _dragWindowNumber = w->number; _dragWidgetIndex = widgetIndex; -} + } static void input_window_position_continue(rct_window *w, int wdx, int wdy, int x, int y) { @@ -352,7 +352,7 @@ static void input_window_position_continue(rct_window *w, int wdx, int wdy, int snapProximity = w->flags & WF_NO_SNAPPING ? 0 : gGeneral_config.window_snap_proximity; window_move_and_snap(w, x - wdx, y - wdy, snapProximity); -} + } static void input_window_position_end(rct_window *w, int x, int y) { @@ -362,7 +362,7 @@ static void input_window_position_end(rct_window *w, int x, int y) RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WINDOW_NUMBER, rct_windownumber) = _dragWindowNumber; RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WIDGET_INDEX, uint16) = _dragWidgetIndex; RCT2_CALLPROC_X(w->event_handlers[WE_MOVED], 0, 0, x, y, (int)w, 0, 0); -} + } static void input_window_resize_begin(rct_window *w, int widgetIndex, int x, int y) { @@ -374,7 +374,7 @@ static void input_window_resize_begin(rct_window *w, int widgetIndex, int x, int _dragWidgetIndex = widgetIndex; _originalWindowWidth = w->width; _originalWindowHeight = w->height; -} + } static void input_window_resize_continue(rct_window *w, int x, int y) { @@ -391,8 +391,8 @@ static void input_window_resize_continue(rct_window *w, int x, int y) targetWidth - w->width, targetHeight - w->height ); - } -} + } + } static void input_window_resize_end() { @@ -535,77 +535,77 @@ static void input_scroll_continue(rct_window *w, int widgetIndex, int state, int rct_widget *widget; widget = &w->widgets[widgetIndex]; - if (widgetIndex != RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, uint32)){ - invalidate_scroll(); - return; - } - if (w->classification != RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, uint8)){ - invalidate_scroll(); - return; - } - if (w->number != RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWNUMBER, uint16)){ - invalidate_scroll(); - return; - } + if (widgetIndex != RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, uint32)){ + invalidate_scroll(); + return; + } + if (w->classification != RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, uint8)){ + invalidate_scroll(); + return; + } + if (w->number != RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWNUMBER, uint16)){ + invalidate_scroll(); + return; + } - if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SCROLL_AREA, uint16) == SCROLL_PART_HSCROLLBAR_THUMB){ - int temp_x = x; - x -= RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_X, uint16); - RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_X, uint16) = temp_x; - RCT2_CALLPROC_X(0x006E98F2, x, temp_x, state, w->number, (int)w, (int)widget, x); - return; - } + if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SCROLL_AREA, uint16) == SCROLL_PART_HSCROLLBAR_THUMB){ + int temp_x = x; + x -= RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_X, uint16); + RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_X, uint16) = temp_x; + RCT2_CALLPROC_X(0x006E98F2, x, temp_x, state, w->number, (int)w, (int)widget, x); + return; + } - if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SCROLL_AREA, uint16) == SCROLL_PART_VSCROLLBAR_THUMB){ - int temp_y = y; - y -= RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_Y, uint16); - RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_Y, uint16) = temp_y; - RCT2_CALLPROC_X(0x006E99A9, temp_y, y, state, w->number, (int)w, (int)widget, y); - return; - } - int scroll_part, scroll_id; - widget_scroll_get_part(w, widget, x, y, &x, &y, &scroll_part, &scroll_id); + if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SCROLL_AREA, uint16) == SCROLL_PART_VSCROLLBAR_THUMB){ + int temp_y = y; + y -= RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_Y, uint16); + RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_Y, uint16) = temp_y; + RCT2_CALLPROC_X(0x006E99A9, temp_y, y, state, w->number, (int)w, (int)widget, y); + return; + } + int scroll_part, scroll_id; + widget_scroll_get_part(w, widget, x, y, &x, &y, &scroll_part, &scroll_id); - if (scroll_part != RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SCROLL_AREA, uint16)){ - invalidate_scroll(); - return; - } + if (scroll_part != RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SCROLL_AREA, uint16)){ + invalidate_scroll(); + return; + } - switch (scroll_part){ - case SCROLL_PART_VIEW: - RCT2_CALLPROC_X(w->event_handlers[WE_TOOL_DRAG], w->number / 18, y, x, y, (int)w, (int)widget, (int)w->event_handlers); - break; - case SCROLL_PART_HSCROLLBAR_LEFT: - RCT2_CALLPROC_X(0x006E9A60, x, y, scroll_part, w->number, (int)w, (int)widget, 0); - break; - case SCROLL_PART_HSCROLLBAR_RIGHT: - RCT2_CALLPROC_X(0x006E9ABF, x, y, scroll_part, w->number, (int)w, (int)widget, 0); - break; - case SCROLL_PART_HSCROLLBAR_LEFT_TROUGH: - case SCROLL_PART_HSCROLLBAR_RIGHT_TROUGH: - return; - break; - case SCROLL_PART_HSCROLLBAR_THUMB: - case SCROLL_PART_VSCROLLBAR_TOP: - RCT2_CALLPROC_X(0x006E9C37, x, y, scroll_part, w->number, (int)w, (int)widget, 0); - break; - case SCROLL_PART_VSCROLLBAR_BOTTOM: - RCT2_CALLPROC_X(0x006E9C96, x, y, scroll_part, w->number, (int)w, (int)widget, 0); - break; - case SCROLL_PART_VSCROLLBAR_TOP_TROUGH: - case SCROLL_PART_VSCROLLBAR_BOTTOM_TROUGH: - return; - break; - default: - return; - } -} + switch (scroll_part){ + case SCROLL_PART_VIEW: + RCT2_CALLPROC_X(w->event_handlers[WE_TOOL_DRAG], w->number / 18, y, x, y, (int)w, (int)widget, (int)w->event_handlers); + break; + case SCROLL_PART_HSCROLLBAR_LEFT: + RCT2_CALLPROC_X(0x006E9A60, x, y, scroll_part, w->number, (int)w, (int)widget, 0); + break; + case SCROLL_PART_HSCROLLBAR_RIGHT: + RCT2_CALLPROC_X(0x006E9ABF, x, y, scroll_part, w->number, (int)w, (int)widget, 0); + break; + case SCROLL_PART_HSCROLLBAR_LEFT_TROUGH: + case SCROLL_PART_HSCROLLBAR_RIGHT_TROUGH: + return; + break; + case SCROLL_PART_HSCROLLBAR_THUMB: + case SCROLL_PART_VSCROLLBAR_TOP: + RCT2_CALLPROC_X(0x006E9C37, x, y, scroll_part, w->number, (int)w, (int)widget, 0); + break; + case SCROLL_PART_VSCROLLBAR_BOTTOM: + RCT2_CALLPROC_X(0x006E9C96, x, y, scroll_part, w->number, (int)w, (int)widget, 0); + break; + case SCROLL_PART_VSCROLLBAR_TOP_TROUGH: + case SCROLL_PART_VSCROLLBAR_BOTTOM_TROUGH: + return; + break; + default: + return; + } + } static void input_scroll_end() { - RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_RESET; + RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_RESET; invalidate_scroll(); -} + } #pragma endregion @@ -638,8 +638,8 @@ static void input_widget_over(int x, int y, rct_window *w, int widgetIndex) else if (ecx == 0) { RCT2_CALLPROC_X(w->event_handlers[WE_SCROLL_MOUSEOVER], edx, 0, eax, ebx, (int)w, 0, 0); input_update_tooltip(w, widgetIndex, x, y); - } - } else { + } + } else { input_update_tooltip(w, widgetIndex, x, y); } @@ -714,7 +714,7 @@ static void input_widget_left(int x, int y, rct_window *w, int widgetIndex) if (w != NULL) { windowClass = w->classification; windowNumber = w->number; - } +} window_close_by_class(WC_ERROR); window_close_by_class(WC_TOOLTIP); @@ -773,7 +773,7 @@ static void input_widget_left(int x, int y, rct_window *w, int widgetIndex) widget_invalidate_by_number(windowClass, windowNumber, widgetIndex); window_event_mouse_down_call(w, widgetIndex); - } + } break; } } @@ -781,9 +781,9 @@ static void input_widget_left(int x, int y, rct_window *w, int widgetIndex) #pragma endregion /** -* + * * rct2: 0x006ED833 -*/ + */ void process_mouse_over(int x, int y) { rct_window* window; @@ -797,7 +797,7 @@ void process_mouse_over(int x, int y) RCT2_GLOBAL(0x9A9808, sint16) = -1; window = window_find_from_point(x, y); - if (window != NULL) { + if (window != NULL) { widgetId = window_find_widget_from_point(window, x, y); RCT2_GLOBAL(0x1420046, sint16) = (widgetId & 0xFFFF); if (widgetId != -1) { @@ -807,9 +807,9 @@ void process_mouse_over(int x, int y) if (viewport_interaction_left_over(x, y)) { sub_6ED990(CURSOR_HAND_POINT); return; - } - break; - } + } + break; + } cursorId = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8); subWindow = window_find_by_number( RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass), @@ -818,8 +818,8 @@ void process_mouse_over(int x, int y) ebp = (int)subWindow; if (subWindow == NULL) { - break; - } + break; + } ebx = ebx & 0xFFFFFF00; edi = cursorId; esi = (int) subWindow; @@ -829,28 +829,28 @@ void process_mouse_over(int x, int y) { sub_6ED990(cursorId); return; - } - break; + } + break; case WWT_FRAME: case WWT_RESIZE: if (!(window->flags & 0x100)) { - break; - } + break; + } if (window->min_width == window->max_width && window->min_height == window->max_height) { - break; - } + break; + } if (x < window->x + window->width - 0x13) { - break; - } + break; + } if (y < window->y + window->height - 0x13) { - break; - } + break; + } cursorId = CURSOR_DIAGONAL_ARROWS; - break; + break; case WWT_SCROLL: RCT2_GLOBAL(0x9DE558, uint16) = x; RCT2_GLOBAL(0x9DE55A, uint16) = y; @@ -860,8 +860,8 @@ void process_mouse_over(int x, int y) if (output_scroll_area != SCROLL_PART_VIEW) { cursorId = CURSOR_ARROW; - break; - } + break; + } //Fall through to default default: ecx = x; @@ -874,17 +874,17 @@ void process_mouse_over(int x, int y) RCT2_CALLFUNC_X(window->event_handlers[WE_CURSOR], &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); if (ebx == 0xFFFFFFFF) { cursorId = CURSOR_ARROW; - break; - } - cursorId = ebx; - break; - } + break; } - } + cursorId = ebx; + break; + } + } + } viewport_interaction_right_over(x, y); sub_6ED990(cursorId); -} + } /** * @@ -904,8 +904,8 @@ void process_mouse_tool(int x, int y) else RCT2_CALLPROC_X(w->event_handlers[WE_TOOL_UPDATE], x, y, 0, RCT2_GLOBAL(0x9DE546, uint16), (int)w, 0, 0); - } -} + } + } /** * @@ -927,15 +927,15 @@ void input_state_widget_pressed( int x, int y, int state, int widgetIndex, rct_w if (cursor_w == NULL) { RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = 0; return; - } + } switch (state){ case 0: if (!w || cursor_w_class != w->classification || cursor_w_number != w->number || widgetIndex != cursor_widgetIndex) - break; + break; if (w->disabled_widgets & (1ULL << widgetIndex)) - break; + break; if (RCT2_GLOBAL(0x9DE528, uint16) != 0) RCT2_GLOBAL(0x9DE528, uint16)++; @@ -943,7 +943,7 @@ void input_state_widget_pressed( int x, int y, int state, int widgetIndex, rct_w RCT2_GLOBAL(0x9DE528, uint16) >= 0x10 && (!(RCT2_GLOBAL(0x9DE528, uint16) & 0x3))){ window_event_mouse_down_call(w, widgetIndex); - } + } if (RCT2_GLOBAL(0x9DE518, uint32) & 1) return; @@ -965,7 +965,7 @@ void input_state_widget_pressed( int x, int y, int state, int widgetIndex, rct_w // gDropdownItemsFormat[dropdown_index] will not work until all windows that use dropdown decompiled if (RCT2_ADDRESS(0x9DEBA4, uint16)[dropdown_index] == 0)goto dropdown_cleanup; - } + } else{ if (cursor_w_class != w->classification || cursor_w_number != w->number || widgetIndex != cursor_widgetIndex) goto dropdown_cleanup; @@ -974,16 +974,16 @@ void input_state_widget_pressed( int x, int y, int state, int widgetIndex, rct_w if (!(RCT2_GLOBAL(0x9DE518, uint32) & 4)){ RCT2_GLOBAL(0x9DE518, uint32) |= (1 << 2); return; - } - } - } + } + } + } window_close_by_class(WC_DROPDOWN); cursor_w = window_find_by_number(cursor_w_class, cursor_w_number); if (RCT2_GLOBAL(0x9DE518, uint32) & 1){ RCT2_GLOBAL(0x9DE518, uint32) &= 0xFFFE; widget_invalidate_by_number(cursor_w_class, cursor_w_number, cursor_widgetIndex); - } + } RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = 1; RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_TIMEOUT, uint16) = 0; @@ -1002,24 +1002,24 @@ void input_state_widget_pressed( int x, int y, int state, int widgetIndex, rct_w RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WIDGET_INDEX, uint16) = cursor_widgetIndex; if (!w) - break; + break; if (!widget) - break; + break; int mid_point_x = (widget->left + widget->right) / 2 + w->x; sound_play_panned(5, mid_point_x, 0, 0, 0); if (cursor_w_class != w->classification || cursor_w_number != w->number || widgetIndex != cursor_widgetIndex) - break; + break; if (w->disabled_widgets & (1ULL << widgetIndex)) - break; + break; widget_invalidate_by_number(cursor_w_class, cursor_w_number, widgetIndex); window_event_mouse_up_call(w, widgetIndex); default: return; - } + } RCT2_GLOBAL(0x9DE528, uint16) = 0; if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) != 5){ @@ -1027,9 +1027,9 @@ void input_state_widget_pressed( int x, int y, int state, int widgetIndex, rct_w if (RCT2_GLOBAL(0x9DE518, uint32) & 1){ RCT2_GLOBAL(0x9DE518, uint32) &= 0xFFFE; widget_invalidate_by_number(cursor_w_class, cursor_w_number, cursor_widgetIndex); - } + } return; - } + } if (!w) return; @@ -1067,7 +1067,7 @@ static void input_update_tooltip(rct_window *w, int widgetIndex, int x, int y) window_tooltip_open(w, widgetIndex, x, y); // RCT2_CALLPROC_X(0x006EA10D, x, y, 0, widgetIndex, w, widget, 0); // window_tooltip_open(); - } +} } else { if (RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WINDOW_CLASS, rct_windowclass) != w->classification || RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WINDOW_NUMBER, rct_windownumber) != w->number || @@ -1170,7 +1170,6 @@ void game_handle_keyboard_input() keyboard_shortcut_handle(key); } } - } if (RCT2_GLOBAL(RCT2_ADDRESS_ON_TUTORIAL, uint8) == 0) @@ -1208,13 +1207,13 @@ void game_handle_keyboard_input() * rct2: 0x00406CD2 */ int get_next_key() -{ + { int i; for (i = 0; i < 221; i++) { if (gKeysPressed[i]) { gKeysPressed[i] = 0; return i; - } +} } return 0; @@ -1367,4 +1366,4 @@ void game_handle_key_scroll() mainWindow->saved_view_y += scrollY * (12 << mainWindow->viewport->zoom); RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_VIEWPORT_SCROLLING; } -} \ No newline at end of file +} diff --git a/src/interface/window.h b/src/interface/window.h index f396c59145..1f89d08004 100644 --- a/src/interface/window.h +++ b/src/interface/window.h @@ -397,7 +397,8 @@ enum { WC_CHEATS = 110, WC_RESEARCH = 111, WC_VIEWPORT = 112, - WC_TEXTINPUT = 113 + WC_TEXTINPUT = 113, + WC_MAPGEN = 114 } WINDOW_CLASS; enum PROMPT_MODE { @@ -484,7 +485,7 @@ void window_main_open(); void window_relocate_windows(int width, int height); void window_resize_gui(int width, int height); void window_resize_gui_scenario_editor(int width, int height); -void window_game_top_toolbar_open(); +void window_top_toolbar_open(); void window_game_bottom_toolbar_open(); void window_about_open(); void window_footpath_open(); @@ -536,9 +537,9 @@ void window_publisher_credits_open(); void window_track_manage_open(); void window_viewport_open(); void window_text_input_open(rct_window* call_w, int call_widget, rct_string_id title, rct_string_id description, rct_string_id existing_text, uint32 existing_args, int maxLength); +rct_window *window_mapgen_open(); void window_editor_main_open(); -void window_editor_top_toolbar_open(); void window_editor_bottom_toolbar_open(); void window_editor_object_selection_open(); void window_editor_inventions_list_open(); diff --git a/src/openrct2.c b/src/openrct2.c index 6300a69c15..6c5d4f7bbc 100644 --- a/src/openrct2.c +++ b/src/openrct2.c @@ -29,6 +29,7 @@ #include "platform/platform.h" #include "platform/osinterface.h" #include "util/sawyercoding.h" +#include "world/mapgen.h" int gOpenRCT2StartupAction = STARTUP_ACTION_TITLE; char gOpenRCT2StartupActionPath[512] = { 0 }; @@ -77,10 +78,11 @@ void openrct2_launch() RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) = SCREEN_FLAGS_PLAYING; break; case STARTUP_ACTION_EDIT: - if (strlen(gOpenRCT2StartupActionPath) == 0) + if (strlen(gOpenRCT2StartupActionPath) == 0) { editor_load(); - else + } else { editor_load_landscape(gOpenRCT2StartupActionPath); + } break; } diff --git a/src/platform/osinterface.c b/src/platform/osinterface.c index cd10665c57..87c42e018d 100644 --- a/src/platform/osinterface.c +++ b/src/platform/osinterface.c @@ -189,8 +189,8 @@ static void osinterface_create_window() exit(-1); } - osinterface_load_cursors(); - RCT2_CALLPROC_EBPSAFE(0x0068371D); + osinterface_load_cursors(); + RCT2_CALLPROC_EBPSAFE(0x0068371D); // Get window size width = gGeneral_config.window_width; @@ -825,7 +825,7 @@ int osinterface_open_common_file_dialog(int type, char *title, char *filename, c // Clear filename if (type != 0) - *filename = 0; + *filename = 0; // Set open file name options memset(&openFileName, 0, sizeof(OPENFILENAME)); diff --git a/src/rct2.c b/src/rct2.c index 4bb25b8888..5b6b415fa8 100644 --- a/src/rct2.c +++ b/src/rct2.c @@ -104,7 +104,7 @@ int rct2_init() ride_init_all(); window_guest_list_init_vars_a(); sub_6BD3A4();// RCT2_CALLPROC_EBPSAFE(0x006BD3A4); //Peep? - map_init(); + map_init(150); park_init(); RCT2_CALLPROC_EBPSAFE(0x0066B5C0); // 0x0066B5C0 (part of 0x0066B3E8) screen_game_create_windows() date_reset(); @@ -135,7 +135,7 @@ int rct2_init_directories() if (!config_find_or_browse_install_directory()) { log_fatal("Invalid RCT2 installation path. Please correct in config.ini."); return 0; - } + } } strcpy(RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH, char), gGeneral_config.game_path); @@ -223,7 +223,10 @@ int rct2_open_file(const char *path) strcpy(scenarioBasic.path, path); scenario_load_and_play_from_path(scenarioBasic.path); } else if (_stricmp(extension, "td6") == 0 || _stricmp(extension, "td4") == 0) { + return 1; + } else if (!_stricmp(extension, "td6") || !_stricmp(extension, "td4")) { // TODO track design install + return 1; } return 0; @@ -234,10 +237,10 @@ int rct2_open_file(const char *path) * rct2: 0x00674C95 */ int check_file_paths() -{ + { for (int pathId = 0; pathId < PATH_ID_END; pathId++) if (!check_file_path(pathId)) - return 0; + return 0; return 1; } @@ -288,11 +291,11 @@ int check_file_path(int pathId) * rct2: 0x00674C0B */ int check_files_integrity() -{ + { int i; const char *path; HANDLE file; - WIN32_FIND_DATA find_data; + WIN32_FIND_DATA find_data; for (i = 0; files_to_check[i].pathId != PATH_ID_END; i++) { path = get_file_path(files_to_check[i].pathId); @@ -503,4 +506,4 @@ void *rct2_realloc(void *block, size_t numBytes) void rct2_free(void *block) { RCT2_CALLPROC_1(0x004068DE, void*, block); -} \ No newline at end of file +} diff --git a/src/scenario.c b/src/scenario.c index cd1399c126..3a077fe5fc 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -334,7 +334,6 @@ int scenario_load_and_play_from_path(const char *path) gfx_invalidate_screen(); RCT2_GLOBAL(0x009DEA66, uint16) = 0; RCT2_GLOBAL(0x009DEA5C, uint16) = 62000; // (doesn't appear to ever be read) - return 1; } diff --git a/src/title.c b/src/title.c index 9988f41381..87380c673b 100644 --- a/src/title.c +++ b/src/title.c @@ -103,7 +103,7 @@ void title_load() ride_init_all(); window_guest_list_init_vars_a(); sub_6BD3A4(); // RCT2_CALLPROC_EBPSAFE(0x006BD3A4); - map_init(); + map_init(150); park_init(); date_reset(); climate_reset(CLIMATE_COOL_AND_WET); diff --git a/src/toolbar.c b/src/toolbar.c deleted file mode 100644 index b04aea397d..0000000000 --- a/src/toolbar.c +++ /dev/null @@ -1,200 +0,0 @@ -/***************************************************************************** -* Copyright (c) 2014 Ted John -* OpenRCT2, an open source clone of Roller Coaster Tycoon 2. -* -* This file is part of 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. - -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. - -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "rct2.h" -#include "addresses.h" -#include "input.h" -#include "toolbar.h" -#include "localisation/string_ids.h" -#include "interface/viewport.h" -#include "interface/window.h" -#include "windows/dropdown.h" - -/** -* -* rct2: 0x0066CDE4 -*/ -void top_toolbar_init_view_menu(rct_window* w, rct_widget* widget) { - gDropdownItemsFormat[0] = 1156; - gDropdownItemsFormat[1] = 1156; - gDropdownItemsFormat[2] = 1156; - gDropdownItemsFormat[3] = 0; - gDropdownItemsFormat[4] = 1156; - gDropdownItemsFormat[5] = 1156; - gDropdownItemsFormat[6] = 1156; - gDropdownItemsFormat[7] = 1156; - gDropdownItemsFormat[8] = 0; - gDropdownItemsFormat[9] = 1156; - gDropdownItemsFormat[10] = 1156; - gDropdownItemsFormat[11] = 1156; - - gDropdownItemsArgs[0] = STR_UNDERGROUND_VIEW; - gDropdownItemsArgs[1] = STR_REMOVE_BASE_LAND; - gDropdownItemsArgs[2] = STR_REMOVE_VERTICAL_FACES; - gDropdownItemsArgs[4] = STR_SEE_THROUGH_RIDES; - gDropdownItemsArgs[5] = STR_SEE_THROUGH_SCENERY; - gDropdownItemsArgs[6] = STR_INVISIBLE_SUPPORTS; - gDropdownItemsArgs[7] = STR_INVISIBLE_PEOPLE; - gDropdownItemsArgs[9] = STR_HEIGHT_MARKS_ON_LAND; - gDropdownItemsArgs[10] = STR_HEIGHT_MARKS_ON_RIDE_TRACKS; - gDropdownItemsArgs[11] = STR_HEIGHT_MARKS_ON_PATHS; - - window_dropdown_show_text( - w->x + widget->left, - w->y + widget->top, - widget->bottom - widget->top + 1, - w->colours[1] | 0x80, - 0, - 12 - ); - - // Set checkmarks - rct_viewport* mainViewport = window_get_main()->viewport; - if (mainViewport->flags & VIEWPORT_FLAG_UNDERGROUND_INSIDE) - gDropdownItemsChecked |= (1 << 0); - if (mainViewport->flags & VIEWPORT_FLAG_HIDE_BASE) - gDropdownItemsChecked |= (1 << 1); - if (mainViewport->flags & VIEWPORT_FLAG_HIDE_VERTICAL) - gDropdownItemsChecked |= (1 << 2); - if (mainViewport->flags & VIEWPORT_FLAG_SEETHROUGH_RIDES) - gDropdownItemsChecked |= (1 << 4); - if (mainViewport->flags & VIEWPORT_FLAG_SEETHROUGH_SCENERY) - gDropdownItemsChecked |= (1 << 5); - if (mainViewport->flags & VIEWPORT_FLAG_INVISIBLE_SUPPORTS) - gDropdownItemsChecked |= (1 << 6); - if (mainViewport->flags & VIEWPORT_FLAG_INVISIBLE_PEEPS) - gDropdownItemsChecked |= (1 << 7); - if (mainViewport->flags & VIEWPORT_FLAG_LAND_HEIGHTS) - gDropdownItemsChecked |= (1 << 9); - if (mainViewport->flags & VIEWPORT_FLAG_TRACK_HEIGHTS) - gDropdownItemsChecked |= (1 << 10); - if (mainViewport->flags & VIEWPORT_FLAG_PATH_HEIGHTS) - gDropdownItemsChecked |= (1 << 11); - - RCT2_GLOBAL(0x9DEBA2, uint16) = 0; -} - -/** -* -* rct2: 0x0066CF8A -*/ -void top_toolbar_view_menu_dropdown(short dropdownIndex) { - if (dropdownIndex == -1) dropdownIndex = RCT2_GLOBAL(0x9DEBA2, uint16); - rct_window* w = window_get_main(); - if (w) { - switch (dropdownIndex) { - case DDIDX_UNDERGROUND_INSIDE: - w->viewport->flags ^= VIEWPORT_FLAG_UNDERGROUND_INSIDE; - break; - case DDIDX_HIDE_BASE: - w->viewport->flags ^= VIEWPORT_FLAG_HIDE_BASE; - break; - case DDIDX_HIDE_VERTICAL: - w->viewport->flags ^= VIEWPORT_FLAG_HIDE_VERTICAL; - break; - case DDIDX_SEETHROUGH_RIDES: - w->viewport->flags ^= VIEWPORT_FLAG_SEETHROUGH_RIDES; - break; - case DDIDX_SEETHROUGH_SCENARY: - w->viewport->flags ^= VIEWPORT_FLAG_SEETHROUGH_SCENERY; - break; - case DDIDX_INVISIBLE_SUPPORTS: - w->viewport->flags ^= VIEWPORT_FLAG_INVISIBLE_SUPPORTS; - break; - case DDIDX_INVISIBLE_PEEPS: - w->viewport->flags ^= VIEWPORT_FLAG_INVISIBLE_PEEPS; - break; - case DDIDX_LAND_HEIGHTS: - w->viewport->flags ^= VIEWPORT_FLAG_LAND_HEIGHTS; - break; - case DDIDX_TRACK_HEIGHTS: - w->viewport->flags ^= VIEWPORT_FLAG_TRACK_HEIGHTS; - break; - case DDIDX_PATH_HEIGHTS: - w->viewport->flags ^= VIEWPORT_FLAG_PATH_HEIGHTS; - break; - default: - return; - } - window_invalidate(w); - } -} - - -/** -* -* rct2: 0x0066CCE7 -*/ -void toggle_footpath_window() { - if (window_find_by_class(WC_FOOTPATH) == NULL) { - window_footpath_open(); - } else { - tool_cancel(); - window_close_by_class(WC_FOOTPATH); - } -} - -/* -* -* rct2: 0x0066CD54 -*/ -void toggle_land_window(rct_window* topToolbar, int widgetIndex) { - if ((RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE) && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, uint8) == 1 && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) == 7) { - tool_cancel(); - } else { - show_gridlines(); - tool_set(topToolbar, widgetIndex, 18); - RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6; - RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) = 1; - window_land_open(); - } -} - -/* -* -* rct2: 0x0066CD0C -*/ -void toggle_clear_scenery_window(rct_window* topToolbar, int widgetIndex) { - if ((RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE) && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, uint8) == 1 && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) == 16) { - tool_cancel(); - } else { - show_gridlines(); - tool_set(topToolbar, widgetIndex, 12); - RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6; - RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) = 2; - window_clear_scenery_open(); - } -} - -/* -* -* rct2: 0x0066CD9C -*/ -void toggle_water_window(rct_window* topToolbar, int widgetIndex) { - if ((RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE) && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, uint8) == 1 && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) == 8) { - tool_cancel(); - } else { - show_gridlines(); - tool_set(topToolbar, widgetIndex, 19); - RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6; - RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) = 1; - window_water_open(); - } -} \ No newline at end of file diff --git a/src/toolbar.h b/src/toolbar.h deleted file mode 100644 index 4c216c99a4..0000000000 --- a/src/toolbar.h +++ /dev/null @@ -1,47 +0,0 @@ -/***************************************************************************** -* Copyright (c) 2014 Ted John -* OpenRCT2, an open source clone of Roller Coaster Tycoon 2. -* -* This file is part of 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. - -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. - -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef _TOOLBAR_H_ -#define _TOOLBAR_H_ - -#include "interface/window.h" -#include "interface/widget.h" - -typedef enum { - DDIDX_UNDERGROUND_INSIDE = 0, - DDIDX_HIDE_BASE = 1, - DDIDX_HIDE_VERTICAL = 2, - DDIDX_SEETHROUGH_RIDES = 4, - DDIDX_SEETHROUGH_SCENARY = 5, - DDIDX_INVISIBLE_SUPPORTS = 6, - DDIDX_INVISIBLE_PEEPS = 7, - DDIDX_LAND_HEIGHTS = 9, - DDIDX_TRACK_HEIGHTS = 10, - DDIDX_PATH_HEIGHTS = 11, -} TOP_TOOLBAR_VIEW_MENU_DDIDX; - -void top_toolbar_init_view_menu(rct_window* window, rct_widget* widget); -void top_toolbar_view_menu_dropdown(short dropdownIndex); - -void toggle_footpath_window(); -void toggle_land_window(rct_window* topToolbar, int widgetIndex); -void toggle_clear_scenery_window(rct_window* topToolbar, int widgetIndex); -void toggle_water_window(rct_window* topToolbar, int widgetIndex); -#endif diff --git a/src/windows/editor_bottom_toolbar.c b/src/windows/editor_bottom_toolbar.c index 58911a4a1b..54a43155fa 100644 --- a/src/windows/editor_bottom_toolbar.c +++ b/src/windows/editor_bottom_toolbar.c @@ -33,7 +33,7 @@ #include "../util/util.h" #include "error.h" -enum WINDOW_EDITOR_TOP_TOOLBAR_WIDGET_IDX { +enum { WIDX_PREVIOUS_IMAGE, // 1 WIDX_PREVIOUS_STEP_BUTTON, // 2 WIDX_NEXT_IMAGE, // 4 diff --git a/src/windows/editor_main.c b/src/windows/editor_main.c index d1231efaea..a9635b4e47 100644 --- a/src/windows/editor_main.c +++ b/src/windows/editor_main.c @@ -87,7 +87,7 @@ void window_editor_main_open() RCT2_GLOBAL(0x009E32B3, uint8) = 0; RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_PATH_TYPE, uint8) = 0; - window_editor_top_toolbar_open(); + window_top_toolbar_open(); window_editor_bottom_toolbar_open(); } diff --git a/src/windows/editor_top_toolbar.c b/src/windows/editor_top_toolbar.c deleted file mode 100644 index 4c99d2e027..0000000000 --- a/src/windows/editor_top_toolbar.c +++ /dev/null @@ -1,437 +0,0 @@ -/***************************************************************************** -* Copyright (c) 2014 Dániel Tar, Ted John -* OpenRCT2, an open source clone of Roller Coaster Tycoon 2. -* -* This file is part of 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. - -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. - -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "../addresses.h" -#include "../localisation/string_ids.h" -#include "../sprites.h" -#include "../game.h" -#include "../editor.h" -#include "../toolbar.h" -#include "../interface/viewport.h" -#include "../interface/widget.h" -#include "../interface/window.h" -#include "dropdown.h" - -enum WINDOW_EDITOR_TOP_TOOLBAR_WIDGET_IDX { - WIDX_PAUSE, // 0, 1 - WIDX_FILE_MENU, // 1, 2 - WIDX_ZOOM_OUT, // 2, 4 - WIDX_ZOOM_IN, // 3, 8 - WIDX_ROTATE, // 4, 10 - WIDX_VIEW_MENU, // 5, 20 - WIDX_MAP, // 6, 40 - WIDX_LAND, // 7, 80 - WIDX_WATER, // 8, 100 - WIDX_SCENERY, // 9, 200 - WIDX_PATH, // 10, 400 - WIDX_CONSTRUCT_RIDE, // 11, 800 - WIDX_UNUSED1, // 12, 1000 - WIDX_UNUSED2, // 13, 2000 - WIDX_UNUSED3, // 14, 4000 - WIDX_UNUSED4, // 15, 8000 - WIDX_CLEAR_SCENERY, // 16, 10000 - - WIDX_SEPARATOR, -}; - -typedef enum { - DDIDX_SE_LOAD_LANDSCAPE = 0, - DDIDX_SE_SAVE_LANDSCAPE = 1, - DDIDX_SE_ABOUT = 3, - DDIDX_SE_OPTIONS = 4, - DDIDX_SE_SCREENSHOT = 5, - DDIDX_SE_QUIT_GAME = 7, -} SCENARIO_EDITOR_FILE_MENU_DDIDX; - -typedef enum { - DDIDX_TD_ABOUT = 0, - DDIDX_TD_OPTIONS = 1, - DDIDX_TD_SCREENSHOT = 2, - DDIDX_TD_QUIT_GAME = 4, -} TRACK_DESINGER_FILE_MENU_DDIDX; - -#pragma region Toolbar_widget_ordering - -// from left to right -static const int left_aligned_widgets_order[] = { - WIDX_PAUSE, WIDX_FILE_MENU, - - WIDX_SEPARATOR, - - WIDX_ZOOM_OUT, - WIDX_ZOOM_IN, - WIDX_ROTATE, - WIDX_VIEW_MENU, - WIDX_MAP, -}; - -// from right to left -static const int right_aligned_widgets_order[] = { - WIDX_CONSTRUCT_RIDE, WIDX_PATH, - WIDX_SCENERY, - WIDX_WATER, - WIDX_LAND, - WIDX_CLEAR_SCENERY, -}; - -#pragma endregion - -static rct_widget window_editor_top_toolbar_widgets[] = { - { WWT_EMPTY, 0, 0, 0, 0, 0, 0xFFFFFFFF, 0xFFFF }, // 1 0x009A9844 - { WWT_TRNBTN, 0, 0, 29, 0, 27, 0x20000000 | SPR_TOOLBAR_FILE, STR_DISC_AND_GAME_OPTIONS_TIP }, // 2 0x009A9854 - { WWT_TRNBTN, 1, 40, 69, 0, 27, 0x20000000 | SPR_TOOLBAR_ZOOM_OUT, STR_ZOOM_OUT_TIP }, // 4 0x009A9864 - { WWT_TRNBTN, 1, 70, 99, 0, 27, 0x20000000 | SPR_TOOLBAR_ZOOM_IN, STR_ZOOM_IN_TIP }, // 8 0x009A9874 - { WWT_TRNBTN, 1, 100, 129, 0, 27, 0x20000000 | SPR_TOOLBAR_ROTATE, STR_ROTATE_TIP }, // 10 0x009A9884 - { WWT_TRNBTN, 1, 130, 159, 0, 27, 0x20000000 | SPR_TOOLBAR_VIEW, STR_VIEW_OPTIONS_TIP }, // 20 0x009A9894 - { WWT_TRNBTN, 1, 160, 189, 0, 27, 0x20000000 | SPR_TOOLBAR_MAP, STR_SHOW_MAP_TIP }, // 40 0x009A98A4 - { WWT_TRNBTN, 2, 267, 296, 0, 27, 0x20000000 | SPR_TOOLBAR_LAND, STR_ADJUST_LAND_TIP }, // 80 0x009A98B4 - { WWT_TRNBTN, 2, 297, 326, 0, 27, 0x20000000 | SPR_TOOLBAR_WATER, STR_ADJUST_WATER_TIP }, // 100 0x009A98C4 - { WWT_TRNBTN, 2, 327, 356, 0, 27, 0x20000000 | SPR_TOOLBAR_SCENERY, STR_PLACE_SCENERY_TIP }, // 200 0x009A98D4 - { WWT_TRNBTN, 2, 357, 386, 0, 27, 0x20000000 | SPR_TOOLBAR_FOOTPATH, STR_BUILD_FOOTPATH_TIP }, // 400 0x009A98E4 - { WWT_TRNBTN, 2, 387, 416, 0, 27, 0x20000000 | SPR_TOOLBAR_CONSTRUCT_RIDE, STR_BUILD_RIDE_TIP }, // 800 0x009A98F4 - { WWT_EMPTY, 0, 0, 0, 0, 0, 0xFFFFFFFF, 0xFFFF }, // 1000 0x009A9904 - { WWT_EMPTY, 0, 0, 0, 0, 0, 0xFFFFFFFF, 0xFFFF }, // 2000 0x009A9914 - { WWT_EMPTY, 0, 0, 0, 0, 0, 0xFFFFFFFF, 0xFFFF }, // 4000 0x009A9924 - { WWT_EMPTY, 0, 0, 0, 0, 0, 0xFFFFFFFF, 0xFFFF }, // 8000 0x009A9934 - { WWT_TRNBTN, 2, 560, 589, 0, 27, 0x20000000 | SPR_TOOLBAR_CLEAR_SCENERY, STR_CLEAR_SCENERY_TIP }, // 10000 0x009A9944 - - { WWT_EMPTY, 0, 0, 10-1, 0, 0, 0xFFFFFFFF, 0xFFFF }, // Artificial widget separator - { WIDGETS_END }, -}; - -static void window_editor_top_toolbar_emptysub() { } - -static void window_editor_top_toolbar_mouseup(); -static void window_editor_top_toolbar_resize(); -static void window_editor_top_toolbar_mousedown(int widgetIndex, rct_window*w, rct_widget* widget); -static void window_editor_top_toolbar_dropdown(); -static void window_editor_top_toolbar_invalidate(); -static void window_editor_top_toolbar_paint(); - -static void* window_editor_top_toolbar_events[] = { - window_editor_top_toolbar_emptysub, - window_editor_top_toolbar_mouseup, //(void*)0x0066f9d7, // mouseup - window_editor_top_toolbar_resize, //(void*)0x0066fada, // resize - window_editor_top_toolbar_mousedown, //(void*)0x0066fa57, // mousedown - window_editor_top_toolbar_dropdown, //(void*)0x0066fa38, // dropdown - window_editor_top_toolbar_emptysub, - window_editor_top_toolbar_emptysub, - window_editor_top_toolbar_emptysub, - window_editor_top_toolbar_emptysub, - (void*)0x0066fb0e, - (void*)0x0066fb5c, - (void*)0x0066fb37, - (void*)0x0066fc44, - (void*)0x0066fa74, - window_editor_top_toolbar_emptysub, - window_editor_top_toolbar_emptysub, - window_editor_top_toolbar_emptysub, - window_editor_top_toolbar_emptysub, - window_editor_top_toolbar_emptysub, - window_editor_top_toolbar_emptysub, - window_editor_top_toolbar_emptysub, - window_editor_top_toolbar_emptysub, - window_editor_top_toolbar_emptysub, - window_editor_top_toolbar_emptysub, - window_editor_top_toolbar_emptysub, - window_editor_top_toolbar_invalidate, // (void*)0x0066f87d, // oninvalidate - window_editor_top_toolbar_paint, //(void*)0x0066f9d1, // onpaint - window_editor_top_toolbar_emptysub -}; - -/** -* Creates the main editor top toolbar window. -* rct2: 0x0066EFC8 (part of 0x0066EF38) -*/ -void window_editor_top_toolbar_open() -{ - rct_window* window; - - window = window_create(0, 0, RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16), 28, - (uint32*)window_editor_top_toolbar_events, - WC_TOP_TOOLBAR, WF_STICK_TO_FRONT | WF_TRANSPARENT | WF_5); - window->widgets = window_editor_top_toolbar_widgets; - - window->enabled_widgets |= - (1 << WIDX_ZOOM_IN) | - (1 << WIDX_ZOOM_OUT) | - (1 << WIDX_ROTATE) | - (1 << WIDX_FILE_MENU) | - (1 << WIDX_LAND) | - (1 << WIDX_VIEW_MENU) | - (1 << WIDX_SCENERY) | - (1 << WIDX_WATER) | - (1 << WIDX_PATH) | - (1 << WIDX_MAP) | - (1 << WIDX_CONSTRUCT_RIDE) | - (1 << WIDX_CLEAR_SCENERY); - - window_init_scroll_widgets(window); - window->colours[0] = 7; - window->colours[1] = 12; - window->colours[2] = 24; - window->colours[3] = 1; -} - -/** -* -* rct2: 0x0066C957 -*/ -static void window_editor_top_toolbar_mouseup() -{ - short widgetIndex; - rct_window *w, *mainWindow; - - window_widget_get_registers(w, widgetIndex); - - switch (widgetIndex) { - case WIDX_ZOOM_IN: - if ((mainWindow = window_get_main()) != NULL) - window_zoom_in(mainWindow); - break; - case WIDX_ZOOM_OUT: - if ((mainWindow = window_get_main()) != NULL) - window_zoom_out(mainWindow); - break; - case WIDX_ROTATE: - if ((mainWindow = window_get_main()) != NULL) - window_rotate_camera(mainWindow); - break; - case WIDX_SCENERY: - if (!tool_set(w, WIDX_SCENERY, 0)) { - RCT2_GLOBAL(0x009DE518, uint32) |= (1 << 6); - window_scenery_open(); - } - break; - case WIDX_PATH: - toggle_footpath_window(); - break; - case WIDX_LAND: - toggle_land_window(w, WIDX_LAND); - break; - case WIDX_CLEAR_SCENERY: - toggle_clear_scenery_window(w, WIDX_CLEAR_SCENERY); - break; - case WIDX_WATER: - toggle_water_window(w, WIDX_WATER); - break; - case WIDX_MAP: - window_map_open(); - break; - case WIDX_CONSTRUCT_RIDE: - window_new_ride_open(); - break; - } -} - -/** -* -* rct2: 0x0066FADA -*/ -static void window_editor_top_toolbar_resize() { - rct_window *mainWindow = window_get_main(); - rct_window *w; - - window_get_register(w); - - int eax = 0; - - if ((w->disabled_widgets & 0xFF) == 0) - eax |= (1 << 3); - - if ((w->disabled_widgets & 0xFF) == 3) - eax |= (1 << 2); - - RCT2_CALLPROC_X(0x006ECE14, 0, 0, 0, 0, (int)w, 0, 0); -} - -/** -* -* rct2: 0x0066FA57 -*/ -static void window_editor_top_toolbar_mousedown(int widgetIndex, rct_window*w, rct_widget* widget) -{ - if (widgetIndex == WIDX_FILE_MENU) { - short dropdownItemCount = 8; - gDropdownItemsFormat[0] = STR_LOAD_LANDSCAPE; - gDropdownItemsFormat[1] = STR_SAVE_LANDSCAPE; - gDropdownItemsFormat[2] = 0; - gDropdownItemsFormat[3] = STR_ABOUT; - gDropdownItemsFormat[4] = STR_OPTIONS; - gDropdownItemsFormat[5] = STR_SCREENSHOT; - gDropdownItemsFormat[6] = 0; - gDropdownItemsFormat[7] = STR_QUIT_SCENARIO_EDITOR; - - if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & (SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER)) { - dropdownItemCount = 5; - gDropdownItemsFormat[0] = STR_ABOUT; - gDropdownItemsFormat[1] = STR_OPTIONS; - gDropdownItemsFormat[2] = STR_SCREENSHOT; - gDropdownItemsFormat[3] = 0; - gDropdownItemsFormat[4] = STR_QUIT_TRACK_DESIGNS_MANAGER; - - if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_DESIGNER) { - gDropdownItemsFormat[4] = STR_QUIT_ROLLERCOASTER_DESIGNER; - } - } - - window_dropdown_show_text(w->x + widget->left, w->y + widget->top, - widget->bottom - widget->top + 1, w->colours[0] | 0x80, 0x80, dropdownItemCount); - } else if (widgetIndex == WIDX_VIEW_MENU) { - top_toolbar_init_view_menu(w, widget); - } -} - -/** -* -* rct2: 0x0066FA38 -*/ -void window_editor_top_toolbar_dropdown() { - short widgetIndex, dropdownIndex; - rct_window* w; - - window_dropdown_get_registers(w, widgetIndex, dropdownIndex); - - if (widgetIndex == WIDX_FILE_MENU) { - if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & (SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER)) { - if (dropdownIndex == DDIDX_TD_ABOUT) { - window_about_open(); - } else if (dropdownIndex == DDIDX_TD_OPTIONS) { - window_options_open(); - } else if (dropdownIndex == DDIDX_TD_SCREENSHOT) { - RCT2_GLOBAL(RCT2_ADDRESS_SCREENSHOT_COUNTDOWN, sint8) = 10; - } else if (dropdownIndex == DDIDX_TD_QUIT_GAME) { - window_close_by_number(WC_MANAGE_TRACK_DESIGN, w->number); - window_close_by_number(WC_TRACK_DELETE_PROMPT, w->number); - game_do_command(0, 1, 0, 0, GAME_COMMAND_LOAD_OR_QUIT, 1, 0); - } - } else { - if (dropdownIndex == DDIDX_SE_LOAD_LANDSCAPE) { - game_do_command(0, 1, 0, 0, GAME_COMMAND_LOAD_OR_QUIT, 0, 0); - } else if (dropdownIndex == DDIDX_SE_SAVE_LANDSCAPE) { - RCT2_CALLPROC_EBPSAFE(0x0066FE2A); - } else if (dropdownIndex == DDIDX_SE_ABOUT) { - window_about_open(); - } else if (dropdownIndex == DDIDX_SE_OPTIONS) { - window_options_open(); - } else if (dropdownIndex == DDIDX_SE_SCREENSHOT) { - RCT2_GLOBAL(RCT2_ADDRESS_SCREENSHOT_COUNTDOWN, sint8) = 10; - } else if (dropdownIndex == DDIDX_SE_QUIT_GAME) { - window_close_by_number(WC_MANAGE_TRACK_DESIGN, w->number); - window_close_by_number(WC_TRACK_DELETE_PROMPT, w->number); - game_do_command(0, 1, 0, 0, GAME_COMMAND_LOAD_OR_QUIT, 1, 0); - } - } - } else if (widgetIndex == WIDX_VIEW_MENU) { - top_toolbar_view_menu_dropdown(dropdownIndex); - } -} - -/** -* -* rct2: 0x0066F87D -*/ -void window_editor_top_toolbar_invalidate() -{ - rct_window *w; - - window_get_register(w); - - window_editor_top_toolbar_widgets[WIDX_ZOOM_OUT].type = WWT_EMPTY; - window_editor_top_toolbar_widgets[WIDX_ZOOM_IN].type = WWT_EMPTY; - window_editor_top_toolbar_widgets[WIDX_ROTATE].type = WWT_EMPTY; - window_editor_top_toolbar_widgets[WIDX_VIEW_MENU].type = WWT_EMPTY; - window_editor_top_toolbar_widgets[WIDX_MAP].type = WWT_EMPTY; - window_editor_top_toolbar_widgets[WIDX_CLEAR_SCENERY].type = WWT_EMPTY; - window_editor_top_toolbar_widgets[WIDX_LAND].type = WWT_EMPTY; - window_editor_top_toolbar_widgets[WIDX_WATER].type = WWT_EMPTY; - window_editor_top_toolbar_widgets[WIDX_SCENERY].type = WWT_EMPTY; - window_editor_top_toolbar_widgets[WIDX_PATH].type = WWT_EMPTY; - window_editor_top_toolbar_widgets[WIDX_CONSTRUCT_RIDE].type = WWT_EMPTY; - - - if (g_editor_step == EDITOR_STEP_LANDSCAPE_EDITOR) { - window_editor_top_toolbar_widgets[WIDX_ZOOM_OUT].type = WWT_TRNBTN; - window_editor_top_toolbar_widgets[WIDX_ZOOM_IN].type = WWT_TRNBTN; - window_editor_top_toolbar_widgets[WIDX_ROTATE].type = WWT_TRNBTN; - window_editor_top_toolbar_widgets[WIDX_VIEW_MENU].type = WWT_TRNBTN; - window_editor_top_toolbar_widgets[WIDX_MAP].type = WWT_TRNBTN; - window_editor_top_toolbar_widgets[WIDX_CLEAR_SCENERY].type = WWT_TRNBTN; - window_editor_top_toolbar_widgets[WIDX_LAND].type = WWT_TRNBTN; - window_editor_top_toolbar_widgets[WIDX_WATER].type = WWT_TRNBTN; - window_editor_top_toolbar_widgets[WIDX_SCENERY].type = WWT_TRNBTN; - window_editor_top_toolbar_widgets[WIDX_PATH].type = WWT_TRNBTN; - } else if (g_editor_step == EDITOR_STEP_ROLLERCOASTER_DESIGNER) { - window_editor_top_toolbar_widgets[WIDX_ZOOM_OUT].type = WWT_TRNBTN; - window_editor_top_toolbar_widgets[WIDX_ZOOM_IN].type = WWT_TRNBTN; - window_editor_top_toolbar_widgets[WIDX_ROTATE].type = WWT_TRNBTN; - window_editor_top_toolbar_widgets[WIDX_VIEW_MENU].type = WWT_TRNBTN; - window_editor_top_toolbar_widgets[WIDX_CONSTRUCT_RIDE].type = WWT_TRNBTN; - } - - if (window_find_by_class(0x94) == NULL) - w->pressed_widgets &= ~(1 << WIDX_PATH); - else - w->pressed_widgets |= (1 << WIDX_PATH); - - sint16 x = max(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16), 640); - - for (int i = 0; i < countof(right_aligned_widgets_order); ++i) { - rct_widget *current_widget = &window_editor_top_toolbar_widgets[right_aligned_widgets_order[i]]; - int widget_width = current_widget->right - current_widget->left; - - if (current_widget->type == WWT_EMPTY && right_aligned_widgets_order[i] != WIDX_SEPARATOR) - continue; - - x -= 1; - current_widget->right = x; - x -= widget_width; - current_widget->left = x; - } - - x = 0; - - for (int i = 0; i < countof(left_aligned_widgets_order); ++i) { - rct_widget *current_widget = &window_editor_top_toolbar_widgets[left_aligned_widgets_order[i]]; - int widget_width = current_widget->right - current_widget->left; - - if (current_widget->type == WWT_EMPTY && left_aligned_widgets_order[i] != WIDX_SEPARATOR) - continue; - - current_widget->left = x; - x += widget_width; - current_widget->right = x; - x += 1; - } -} - -/** -* -* rct2: 0x0066F9D1 -*/ -static void window_editor_top_toolbar_paint() -{ - rct_window *w; - rct_drawpixelinfo *dpi; - - window_paint_get_registers(w, dpi); - - window_draw_widgets(w, dpi); -} \ No newline at end of file diff --git a/src/windows/game_top_toolbar.c b/src/windows/game_top_toolbar.c deleted file mode 100644 index bfcf28cd48..0000000000 --- a/src/windows/game_top_toolbar.c +++ /dev/null @@ -1,703 +0,0 @@ -/***************************************************************************** - * Copyright (c) 2014 Ted John - * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. - * - * This file is part of 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. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *****************************************************************************/ - -#include "../addresses.h" -#include "../game.h" -#include "../input.h" -#include "../sprites.h" -#include "../toolbar.h" -#include "../audio/audio.h" -#include "../interface/widget.h" -#include "../interface/window.h" -#include "../interface/viewport.h" -#include "../localisation/localisation.h" -#include "dropdown.h" -#include "scenery.h" - -enum { - WIDX_PAUSE, - WIDX_FILE_MENU, - WIDX_ZOOM_OUT, - WIDX_ZOOM_IN, - WIDX_ROTATE, - WIDX_VIEW_MENU, - WIDX_MAP, - - WIDX_LAND, - WIDX_WATER, - WIDX_SCENERY, - WIDX_PATH, - WIDX_CONSTRUCT_RIDE, - WIDX_RIDES, - WIDX_PARK, - WIDX_STAFF, - WIDX_GUESTS, - WIDX_CLEAR_SCENERY, - - //WIDX_FASTFORWARD, - WIDX_FINANCES, - WIDX_RESEARCH, - - WIDX_SEPARATOR, -}; - -typedef enum { - DDIDX_LOAD_GAME = 0, - DDIDX_SAVE_GAME = 1, - DDIDX_ABOUT = 3, - DDIDX_OPTIONS = 4, - DDIDX_SCREENSHOT = 5, - DDIDX_QUIT_GAME = 7, -} FILE_MENU_DDIDX; - -#pragma region Toolbar_widget_ordering - -// from left to right -static const int left_aligned_widgets_order[] = { - WIDX_PAUSE, - //WIDX_FASTFORWARD, - WIDX_FILE_MENU, - - WIDX_SEPARATOR, - - WIDX_ZOOM_OUT, - WIDX_ZOOM_IN, - WIDX_ROTATE, - WIDX_VIEW_MENU, - WIDX_MAP, -}; - -// from right to left -static const int right_aligned_widgets_order[] = { - WIDX_GUESTS, - WIDX_STAFF, - WIDX_PARK, - WIDX_RIDES, - WIDX_RESEARCH, - WIDX_FINANCES, - - WIDX_SEPARATOR, - - WIDX_CONSTRUCT_RIDE, - WIDX_PATH, - WIDX_SCENERY, - WIDX_WATER, - WIDX_LAND, - WIDX_CLEAR_SCENERY, -}; - -#pragma endregion - -static rct_widget window_game_top_toolbar_widgets[] = { - { WWT_TRNBTN, 0, 0x0000, 0x001D, 0, 27, 0x20000000 | SPR_TOOLBAR_PAUSE, STR_PAUSE_GAME_TIP }, // Pause - { WWT_TRNBTN, 0, 0x001E + 30, 0x003B + 30, 0, 27, 0x20000000 | SPR_TOOLBAR_FILE, STR_DISC_AND_GAME_OPTIONS_TIP }, // File menu - { WWT_TRNBTN, 1, 0x0046 + 30, 0x0063 + 30, 0, 27, 0x20000000 | SPR_TOOLBAR_ZOOM_OUT, STR_ZOOM_OUT_TIP }, // Zoom out - { WWT_TRNBTN, 1, 0x0064 + 30, 0x0081 + 30, 0, 27, 0x20000000 | SPR_TOOLBAR_ZOOM_IN, STR_ZOOM_IN_TIP }, // Zoom in - { WWT_TRNBTN, 1, 0x0082 + 30, 0x009F + 30, 0, 27, 0x20000000 | SPR_TOOLBAR_ROTATE, STR_ROTATE_TIP }, // Rotate camera - { WWT_TRNBTN, 1, 0x00A0 + 30, 0x00BD + 30, 0, 27, 0x20000000 | SPR_TOOLBAR_VIEW, STR_VIEW_OPTIONS_TIP }, // Transparancy menu - { WWT_TRNBTN, 1, 0x00BE + 30, 0x00DB + 30, 0, 27, 0x20000000 | SPR_TOOLBAR_MAP, STR_SHOW_MAP_TIP }, // Map - - { WWT_TRNBTN, 2, 0x010B, 0x0128, 0, 27, 0x20000000 | SPR_TOOLBAR_LAND, STR_ADJUST_LAND_TIP }, // Land - { WWT_TRNBTN, 2, 0x0129, 0x0146, 0, 27, 0x20000000 | SPR_TOOLBAR_WATER, STR_ADJUST_WATER_TIP }, // Water - { WWT_TRNBTN, 2, 0x0147, 0x0164, 0, 27, 0x20000000 | SPR_TOOLBAR_SCENERY, STR_PLACE_SCENERY_TIP }, // Scenery - { WWT_TRNBTN, 2, 0x0165, 0x0182, 0, 27, 0x20000000 | SPR_TOOLBAR_FOOTPATH, STR_BUILD_FOOTPATH_TIP }, // Path - { WWT_TRNBTN, 2, 0x0183, 0x01A0, 0, 27, 0x20000000 | SPR_TOOLBAR_CONSTRUCT_RIDE, STR_BUILD_RIDE_TIP }, // Construct ride - { WWT_TRNBTN, 3, 0x01EA, 0x0207, 0, 27, 0x20000000 | SPR_TOOLBAR_RIDES, STR_RIDES_IN_PARK_TIP }, // Rides - { WWT_TRNBTN, 3, 0x0208, 0x0225, 0, 27, 0x20000000 | SPR_TOOLBAR_PARK, STR_PARK_INFORMATION_TIP }, // Park - { WWT_TRNBTN, 3, 0x0226, 0x0243, 0, 27, 0x20000000 | 0x15F9, STR_STAFF_TIP }, // Staff - { WWT_TRNBTN, 3, 0x0230, 0x024D, 0, 27, 0x20000000 | SPR_TOOLBAR_GUESTS, STR_GUESTS_TIP }, // Guests - { WWT_TRNBTN, 2, 0x0230, 0x024D, 0, 27, 0x20000000 | SPR_TOOLBAR_CLEAR_SCENERY, STR_CLEAR_SCENERY_TIP }, // Clear scenery - - //{ WWT_TRNBTN, 0, 0x001E, 0x003B, 0, 27, 0x20000000 | 0x15F9, STR_NONE }, // Fast forward - { WWT_TRNBTN, 3, 0x001E, 0x003B, 0, 27, 0x20000000 | 0x15F9, 3235 }, // Finances - { WWT_TRNBTN, 3, 0x001E, 0x003B, 0, 27, 0x20000000 | 0x15F9, 2275 }, // Research - - { WWT_EMPTY, 0, 0, 10-1, 0, 0, 0xFFFFFFFF, STR_NONE }, // Artificial widget separator - { WIDGETS_END }, -}; - -static void window_game_top_toolbar_emptysub() { } -static void window_game_top_toolbar_mouseup(); -static void window_game_top_toolbar_mousedown(int widgetIndex, rct_window*w, rct_widget* widget); -static void window_game_top_toolbar_dropdown(); -static void window_game_top_toolbar_tool_update(); -static void window_game_top_toolbar_tool_down(); -static void window_game_top_toolbar_tool_drag(); -static void window_game_top_toolbar_invalidate(); -static void window_game_top_toolbar_paint(); - -static void* window_game_top_toolbar_events[] = { - window_game_top_toolbar_emptysub, - window_game_top_toolbar_mouseup, - window_game_top_toolbar_emptysub, - window_game_top_toolbar_mousedown, - window_game_top_toolbar_dropdown, - window_game_top_toolbar_emptysub, - window_game_top_toolbar_emptysub, - window_game_top_toolbar_emptysub, - window_game_top_toolbar_emptysub, - window_game_top_toolbar_tool_update, - window_game_top_toolbar_tool_down, - window_game_top_toolbar_tool_drag, - (void*)0x0066CC5B, - (void*)0x0066CA58, - window_game_top_toolbar_emptysub, - window_game_top_toolbar_emptysub, - window_game_top_toolbar_emptysub, - window_game_top_toolbar_emptysub, - window_game_top_toolbar_emptysub, - window_game_top_toolbar_emptysub, - window_game_top_toolbar_emptysub, - window_game_top_toolbar_emptysub, - window_game_top_toolbar_emptysub, - window_game_top_toolbar_emptysub, - window_game_top_toolbar_emptysub, - window_game_top_toolbar_invalidate, - window_game_top_toolbar_paint, - window_game_top_toolbar_emptysub -}; - -/** - * Creates the main game top toolbar window. - * rct2: 0x0066B485 (part of 0x0066B3E8) - */ -void window_game_top_toolbar_open() -{ - rct_window* window; - - window = window_create( - 0, 0, - RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16), 28, - (uint32*)window_game_top_toolbar_events, - WC_TOP_TOOLBAR, - WF_STICK_TO_FRONT | WF_TRANSPARENT | WF_5 - ); - window->widgets = window_game_top_toolbar_widgets; - - window->enabled_widgets |= - (1 << WIDX_PAUSE) | - (1 << WIDX_FILE_MENU) | - (1 << WIDX_ZOOM_OUT) | - (1 << WIDX_ZOOM_IN) | - (1 << WIDX_ROTATE) | - (1 << WIDX_VIEW_MENU) | - (1 << WIDX_MAP) | - (1 << WIDX_LAND) | - (1 << WIDX_WATER) | - (1 << WIDX_SCENERY) | - (1 << WIDX_PATH) | - (1 << WIDX_CONSTRUCT_RIDE) | - (1 << WIDX_RIDES) | - (1 << WIDX_PARK) | - (1 << WIDX_STAFF) | - (1 << WIDX_GUESTS) | - (1 << WIDX_CLEAR_SCENERY) | - //(1ULL << WIDX_FASTFORWARD) | - (1ULL << WIDX_FINANCES) | - (1ULL << WIDX_RESEARCH); - - window_init_scroll_widgets(window); - window->colours[0] = 7; - window->colours[1] = 12; - window->colours[2] = 24; - window->colours[3] = 1; -} - -/** - * - * rct2: 0x0066C957 - */ -static void window_game_top_toolbar_mouseup() -{ - short widgetIndex; - rct_window *w, *mainWindow; - - window_widget_get_registers(w, widgetIndex); - - switch (widgetIndex) { - case WIDX_PAUSE: - game_do_command(0, 1, 0, 0, GAME_COMMAND_TOGGLE_PAUSE, 0, 0); - break; - // case WIDX_FASTFORWARD: - // // This is an excellent place to add in debugging statements and - // // print routines, that will be triggered when you press the - // // button in the game. Use "git update-index --skip-worktree - // // src/window_game_top_toolbar" to avoid committing these changes to - // // version control. - // window_cheats_open(); - // break; - - case WIDX_ZOOM_OUT: - if ((mainWindow = window_get_main()) != NULL) - window_zoom_out(mainWindow); - break; - case WIDX_ZOOM_IN: - if ((mainWindow = window_get_main()) != NULL) - window_zoom_in(mainWindow); - break; - case WIDX_ROTATE: - if ((mainWindow = window_get_main()) != NULL) - window_rotate_camera(mainWindow); - break; - case WIDX_CLEAR_SCENERY: - toggle_clear_scenery_window(w, WIDX_CLEAR_SCENERY); - break; - case WIDX_LAND: - toggle_land_window(w, WIDX_LAND); - break; - case WIDX_WATER: - toggle_water_window(w, WIDX_WATER); - break; - case WIDX_SCENERY: - if (!tool_set(w, WIDX_SCENERY, 0)) { - RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6; - window_scenery_open(); - } - break; - case WIDX_PATH: - toggle_footpath_window(); - break; - case WIDX_CONSTRUCT_RIDE: - window_new_ride_open(); - break; - case WIDX_RIDES: - window_ride_list_open(); - break; - case WIDX_PARK: - window_park_entrance_open(); - break; - case WIDX_STAFF: - window_staff_list_open(); - break; - case WIDX_GUESTS: - window_guest_list_open(); - break; - case WIDX_FINANCES: - window_finances_open(); - break; - case WIDX_RESEARCH: - window_research_open(); - break; - } -} - -/** - * - * rct2: 0x0066CA3B - */ -static void window_game_top_toolbar_mousedown(int widgetIndex, rct_window*w, rct_widget* widget) -{ - switch (widgetIndex) { - case WIDX_FILE_MENU: - gDropdownItemsFormat[0] = STR_LOAD_GAME; - gDropdownItemsFormat[1] = STR_SAVE_GAME; - gDropdownItemsFormat[2] = 0; - gDropdownItemsFormat[3] = STR_ABOUT; - gDropdownItemsFormat[4] = STR_OPTIONS; - gDropdownItemsFormat[5] = STR_SCREENSHOT; - gDropdownItemsFormat[6] = 0; - gDropdownItemsFormat[7] = STR_QUIT_GAME; - window_dropdown_show_text( - w->x + widget->left, - w->y + widget->top, - widget->bottom - widget->top + 1, - w->colours[0] | 0x80, - 0x80, - 8 - ); - break; - case WIDX_VIEW_MENU: - top_toolbar_init_view_menu(w, widget); - break; - case WIDX_MAP: - gDropdownItemsFormat[0] = 2523; - gDropdownItemsFormat[1] = 2780; - window_dropdown_show_text( - w->x + widget->left, - w->y + widget->top, - widget->bottom - widget->top + 1, - w->colours[1] | 0x80, - 0, - 2 - ); - RCT2_GLOBAL(0x9DEBA2, uint16) = 0; - break; - } -} - -/** - * - * rct2: 0x0066C9EA - */ -static void window_game_top_toolbar_dropdown() -{ - short widgetIndex, dropdownIndex; - rct_window* w; - - window_dropdown_get_registers(w, widgetIndex, dropdownIndex); - - switch (widgetIndex) { - case WIDX_FILE_MENU: - switch (dropdownIndex) { - case DDIDX_LOAD_GAME: // load game - game_do_command(0, 1, 0, 0, GAME_COMMAND_LOAD_OR_QUIT, 0, 0); - break; - case DDIDX_SAVE_GAME: // save game - tool_cancel(); - save_game(); - break; - case DDIDX_ABOUT: // about - window_about_open(); - break; - case DDIDX_OPTIONS: // options - window_options_open(); - break; - case DDIDX_SCREENSHOT: // screenshot - RCT2_GLOBAL(RCT2_ADDRESS_SCREENSHOT_COUNTDOWN, sint8) = 10; - break; - case DDIDX_QUIT_GAME: // quit game - game_do_command(0, 1, 0, 0, GAME_COMMAND_LOAD_OR_QUIT, 1, 0); - break; - } - break; - case WIDX_VIEW_MENU: - top_toolbar_view_menu_dropdown(dropdownIndex); - break; - case WIDX_MAP: - if (dropdownIndex == -1) - dropdownIndex = RCT2_GLOBAL(0x9DEBA2, uint16); - switch (dropdownIndex) { - case 0: - window_map_open(); - break; - case 1: - window_viewport_open(); - break; - } - break; - } -} - -/** - * - * rct2: 0x0066C810 - */ -static void window_game_top_toolbar_invalidate() -{ - int x; - rct_window *w; - - window_get_register(w); - - // Anchor the right half of the buttons to the right - x = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16); - if (x < 640) - x = 640; - - for (int i = 0; i < countof(right_aligned_widgets_order); ++i) { - rct_widget *current_widget = &window_game_top_toolbar_widgets[right_aligned_widgets_order[i]]; - int widget_width = current_widget->right - current_widget->left; - - x -= 1; - current_widget->right = x; - x -= widget_width; - current_widget->left = x; - } - - x = 0; - - for (int i = 0; i < countof(left_aligned_widgets_order); ++i) { - rct_widget *current_widget = &window_game_top_toolbar_widgets[left_aligned_widgets_order[i]]; - int widget_width = current_widget->right - current_widget->left; - - current_widget->left = x; - x += widget_width; - current_widget->right = x; - x += 1; - } - - // Footpath button pressed down - if (window_find_by_class(WC_FOOTPATH) == NULL) - w->pressed_widgets &= ~(1 << WIDX_PATH); - else - w->pressed_widgets |= (1 << WIDX_PATH); - - // Fast forward button pressed down - // if (0) - // w->pressed_widgets |= (1 << WIDX_FASTFORWARD); - // else - // w->pressed_widgets &= ~(1 << WIDX_FASTFORWARD); - - if (!(RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint32) & 1)) - w->pressed_widgets &= ~(1 << WIDX_PAUSE); - else - w->pressed_widgets |= (1 << WIDX_PAUSE); - - // Zoomed out/in disable. Not sure where this code is in the original. - if (window_get_main()->viewport->zoom == 0){ - w->disabled_widgets |= (1 << WIDX_ZOOM_IN); - } - else if (window_get_main()->viewport->zoom == 3){ - w->disabled_widgets |= (1 << WIDX_ZOOM_OUT); - } - else - { - w->disabled_widgets &= ~((1 << WIDX_ZOOM_IN) | (1 << WIDX_ZOOM_OUT)); - } - - if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY) { - window_game_top_toolbar_widgets[WIDX_FINANCES].type = WWT_EMPTY; - } - else{ - window_game_top_toolbar_widgets[WIDX_FINANCES].type = WWT_TRNBTN; - } -} - -/** - * - * rct2: 0x0066C8EC - */ -static void window_game_top_toolbar_paint() -{ - int x, y, imgId; - rct_window *w; - rct_drawpixelinfo *dpi; - - window_paint_get_registers(w, dpi); - - window_draw_widgets(w, dpi); - - // Draw staff button image (setting masks to the staff colours) - x = w->x + window_game_top_toolbar_widgets[WIDX_STAFF].left; - y = w->y + window_game_top_toolbar_widgets[WIDX_STAFF].top; - imgId = 5627; - if (widget_is_pressed(w, WIDX_STAFF)) - imgId++; - imgId |= (RCT2_GLOBAL(RCT2_ADDRESS_HANDYMAN_COLOUR, uint8) << 19) | 0xA0000000 | (RCT2_GLOBAL(RCT2_ADDRESS_MECHANIC_COLOUR, uint8) << 24); - gfx_draw_sprite(dpi, imgId, x, y, 0); - - // Draw research button - x = w->x + window_game_top_toolbar_widgets[WIDX_RESEARCH].left - 1; - y = w->y + window_game_top_toolbar_widgets[WIDX_RESEARCH].top; - imgId = SPR_TAB_FINANCES_RESEARCH_0; - gfx_draw_sprite(dpi, imgId, x, y, 0); - - // Draw finances button - if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY)){ - x = w->x + window_game_top_toolbar_widgets[WIDX_FINANCES].left + 3; - y = w->y + window_game_top_toolbar_widgets[WIDX_FINANCES].top + 1; - imgId = SPR_FINANCE; - gfx_draw_sprite(dpi, imgId, x, y, 0); - } -} - -/** - * rct2: 0x6e2cc6 - */ -static void window_game_top_toolbar_scenery_tool_down(short x, short y, rct_window* w, short widgetIndex){ - RCT2_CALLPROC_EBPSAFE(0x006E2712); - if (window_scenery_is_repaint_scenery_tool_on & 1){ - //6e3158 - RCT2_CALLPROC_X(0x6E2CC6, x, y, 0, widgetIndex, (int)w, 0, 0); - } - - int selected_tab = window_scenery_selected_scenery_by_tab[window_scenery_active_tab_index]; - if (selected_tab == -1) return; - - sint16 grid_x, grid_y, grid_z; - uint8 item_colour; - uint8 model_type; - int ebp = selected_tab; - - { - int eax = x, ebx = y, ecx = 0, edx = 0, esi = 0, edi = 0; - RCT2_CALLFUNC_X(0x6E1F34, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - item_colour = edi; - model_type = (ebx & 0xFF00) >> 8; - grid_x = eax; - grid_y = ecx; - grid_z = edx; - } - - if (grid_x == 0x8000)return; - - if (ebp >= 1024){ - RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, rct_string_id) = 1161; - - // The return value will be banner id but the input is colour - int banner_id = item_colour; - - int ebx = (model_type << 8) | 1; - - { - int esi = 0, eax = grid_x, ecx = grid_y, edx = grid_z; - game_do_command_p(GAME_COMMAND_50, &eax, &ebx, &ecx, &edx, &esi, &banner_id, &ebp); - } - - if (ebx == 0x80000000)return; - - sound_play_panned(SOUND_PLACE_ITEM, 0x8001, RCT2_GLOBAL(0x009DEA5E, uint16), RCT2_GLOBAL(0x009DEA60, uint16), RCT2_GLOBAL(0x009DEA62, uint16)); - - window_banner_open(banner_id); - } - else if (ebp >= 768){ - //6e301c - RCT2_CALLPROC_X(0x6E2CC6, x, y, 0, widgetIndex, (int)w, 0, 0); - } - else if (ebp >= 512){ - //6e2f2e - RCT2_CALLPROC_X(0x6E2CC6, x, y, 0, widgetIndex, (int)w, 0, 0); - } - else if (ebp >= 256){ - //6e2eda - RCT2_CALLPROC_X(0x6E2CC6, x, y, 0, widgetIndex, (int)w, 0, 0); - } - else{ - //6e2d2d - RCT2_CALLPROC_X(0x6E2CC6, x, y, 0, widgetIndex, (int)w, 0, 0); - } -} - -/** - * - * rct2: 0x0066CB25 - */ -static void window_game_top_toolbar_tool_update() -{ - short widgetIndex; - rct_window *w; - short x, y; - - window_tool_get_registers(w, widgetIndex, x, y); - - switch (widgetIndex){ - case WIDX_CLEAR_SCENERY: - RCT2_CALLPROC_X(0x0068E213, x, y, 0, widgetIndex, (int)w, 0, 0); - break; - case WIDX_LAND: - RCT2_CALLPROC_X(0x00664280, x, y, 0, widgetIndex, (int)w, 0, 0); - break; - case WIDX_WATER: - RCT2_CALLPROC_X(0x006E6BDC, x, y, 0, widgetIndex, (int)w, 0, 0); - break; - case WIDX_SCENERY: - RCT2_CALLPROC_X(0x006E287B, x, y, 0, widgetIndex, (int)w, 0, 0); - break; - } -} - -/** - * rct2: 0x0066CB73 - */ -static void window_game_top_toolbar_tool_down(){ - short widgetIndex; - rct_window* w; - short x, y; - - window_tool_get_registers(w, widgetIndex, x, y); - - switch (widgetIndex){ - case WIDX_CLEAR_SCENERY: - if (!RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) & (1 << 0)) - break; - - RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, rct_string_id) = 3438; - - game_do_command( - RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, uint16), - 1, - RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, uint16), - 0, - GAME_COMMAND_CLEAR_SCENERY, - RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16), - RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16) - ); - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) = 12; - break; - case WIDX_LAND: - if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16)&(1 << 0)){ - RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, rct_string_id) = 1387; - game_do_command( - RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, uint16), - 1, - RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, uint16), - RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_TERRAIN_SURFACE, uint8) | (RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_TERRAIN_EDGE, uint8) << 8), - GAME_COMMAND_CHANGE_SURFACE_STYLE, - RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16), - RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16) - ); - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) = 3; - } - break; - case WIDX_WATER: - if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16)&(1 << 0)){ - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) = 3; - } - break; - case WIDX_SCENERY: - window_game_top_toolbar_scenery_tool_down(x, y, w, widgetIndex); - break; - } -} - -/** - * - * rct2: 0x0066CB4E - */ -static void window_game_top_toolbar_tool_drag() -{ - short widgetIndex; - rct_window *w; - short x, y; - - window_tool_get_registers(w, widgetIndex, x, y); - - switch (widgetIndex){ - case WIDX_CLEAR_SCENERY: - if (window_find_by_class(WC_ERROR) != NULL) - break; - - if (!RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) & (1 << 0)) - break; - - RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, rct_string_id) = 3438; - - game_do_command( - RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, uint16), - 1, - RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, uint16), - 0, - GAME_COMMAND_CLEAR_SCENERY, - RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16), - RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16) - ); - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) = 12; - break; - case WIDX_LAND: - RCT2_CALLPROC_X(0x00664454, x, y, 0, widgetIndex, (int)w, 0, 0); - break; - case WIDX_WATER: - RCT2_CALLPROC_X(0x006E6D4B, x, y, 0, widgetIndex, (int)w, 0, 0); - break; - case WIDX_SCENERY: - RCT2_CALLPROC_X(0x006E2CBC, x, y, 0, widgetIndex, (int)w, 0, 0); - break; - } -} \ No newline at end of file diff --git a/src/windows/mapgen.c b/src/windows/mapgen.c new file mode 100644 index 0000000000..50c092fa4b --- /dev/null +++ b/src/windows/mapgen.c @@ -0,0 +1,646 @@ +/***************************************************************************** + * Copyright (c) 2014 Ted John + * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. + * + * This file is part of 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. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#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 "../windows/scenery.h" +#include "../world/mapgen.h" +#include "dropdown.h" + +enum { + WINDOW_MAPGEN_PAGE_BASE, + WINDOW_MAPGEN_PAGE_RANDOM, + WINDOW_MAPGEN_PAGE_COUNT +}; + +enum { + WIDX_BACKGROUND, + WIDX_TITLE, + WIDX_CLOSE, + WIDX_PAGE_BACKGROUND, + WIDX_TAB_1, + WIDX_TAB_2, + + WIDX_GENERATE, + + WIDX_MAP_SIZE = 7, + 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 = 7, + WIDX_PLACE_TREES, +}; + +#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_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_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_page_widgets[] = { + window_mapgen_base_widgets, + window_mapgen_random_widgets +}; + +#pragma endregion + +#pragma region Events + +static void window_mapgen_emptysub() { } + +static void window_mapgen_base_mouseup(); +static void window_mapgen_base_mousedown(int widgetIndex, rct_window *w, rct_widget* widget); +static void window_mapgen_base_dropdown(); +static void window_mapgen_base_update(rct_window *w); +static void window_mapgen_base_invalidate(); +static void window_mapgen_base_paint(); +static void window_mapgen_random_mouseup(); +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(); +static void window_mapgen_random_paint(); + +static void* window_mapgen_base_events[] = { + window_mapgen_emptysub, + window_mapgen_base_mouseup, + window_mapgen_emptysub, + window_mapgen_base_mousedown, + window_mapgen_base_dropdown, + window_mapgen_emptysub, + window_mapgen_base_update, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_base_invalidate, + window_mapgen_base_paint, + window_mapgen_emptysub +}; + +static void* window_mapgen_random_events[] = { + window_mapgen_emptysub, + window_mapgen_random_mouseup, + window_mapgen_emptysub, + window_mapgen_random_mousedown, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_random_update, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_emptysub, + window_mapgen_random_invalidate, + window_mapgen_random_paint, + window_mapgen_emptysub +}; + +static void* window_mapgen_page_events[] = { + window_mapgen_base_events, + window_mapgen_random_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_GENERATE) | + (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) | + (1 << WIDX_FLOOR_TEXTURE) | + (1 << WIDX_WALL_TEXTURE), + + (1 << WIDX_CLOSE) | + (1 << WIDX_TAB_1) | + (1 << WIDX_TAB_2) | + (1 << WIDX_GENERATE) | + (1 << WIDX_RANDOM_TERRAIN) | + (1 << WIDX_PLACE_TREES) +}; + +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 +}; + +#pragma endregion + +const int window_mapgen_tab_animation_loops[] = { 16, 16 }; + +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 = 6; +static int _floorTexture = TERRAIN_GRASS; +static int _wallTexture = TERRAIN_EDGE_ROCK; +static int _randomTerrrain = 1; +static int _placeTrees = 1; + +rct_window *window_mapgen_open() +{ + rct_window *w; + + w = window_bring_to_front_by_class(WC_MAPGEN); + if (w == NULL) { + w = window_create( + (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16) - 300) / 2, + (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16) - 200) / 2, + 300, + 200, + window_mapgen_page_events[0], + WC_MAPGEN, + WF_10 + ); + w->number = 0; + w->frame_no = 0; + w->colours[0] = 12; + w->colours[1] = 24; + w->colours[2] = 24; + } + + 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->var_020 = 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() +{ + short widgetIndex; + rct_window *w; + mapgen_settings mapgenSettings; + + window_widget_get_registers(w, widgetIndex); + + switch (widgetIndex) { + case WIDX_CLOSE: + window_close(w); + break; + case WIDX_TAB_1: + case WIDX_TAB_2: + 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; + } +} + +static void window_mapgen_base_mousedown(int widgetIndex, rct_window *w, rct_widget* widget) +{ + int i; + + switch (widgetIndex) { + case WIDX_MAP_SIZE_UP: + _mapSize = min(_mapSize + 1, 256); + window_invalidate(w); + break; + case WIDX_MAP_SIZE_DOWN: + _mapSize = max(_mapSize - 1, 16); + window_invalidate(w); + break; + case WIDX_BASE_HEIGHT_UP: + _baseHeight = min(_baseHeight + 2, 60); + window_invalidate(w); + break; + case WIDX_BASE_HEIGHT_DOWN: + _baseHeight = max(_baseHeight - 2, 0); + window_invalidate(w); + break; + case WIDX_WATER_LEVEL_UP: + _waterLevel = min(_waterLevel + 2, 54); + window_invalidate(w); + break; + case WIDX_WATER_LEVEL_DOWN: + _waterLevel = max(_waterLevel - 2, 0); + 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) + RCT2_GLOBAL(0x009DEBA2, sint16) = 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] + ); + 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) + RCT2_GLOBAL(0x009DEBA2, sint16) = 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] + ); + break; + } +} + +static void window_mapgen_base_dropdown() +{ + int type; + short dropdownIndex, widgetIndex; + rct_window *w; + + window_dropdown_get_registers(w, widgetIndex, dropdownIndex); + + switch (widgetIndex) { + case WIDX_FLOOR_TEXTURE: + if (dropdownIndex == -1) + dropdownIndex = RCT2_GLOBAL(0x009DEBA2, sint16); + + type = (dropdownIndex == -1) ? + _floorTexture : + *((uint32*)&gDropdownItemsArgs[dropdownIndex]) - SPR_FLOOR_TEXTURE_GRASS; + + if (RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_TERRAIN_SURFACE, uint8) == type) { + RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_TERRAIN_SURFACE, uint8) = 255; + } else { + RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_TERRAIN_SURFACE, uint8) = type; + _floorTexture = type; + } + window_invalidate(w); + break; + case WIDX_WALL_TEXTURE: + if (dropdownIndex == -1) + dropdownIndex = RCT2_GLOBAL(0x009DEBA2, sint16); + + type = (dropdownIndex == -1) ? + _wallTexture : + *((uint32*)&gDropdownItemsArgs[dropdownIndex]) - SPR_WALL_TEXTURE_ROCK; + + if (RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_TERRAIN_EDGE, uint8) == type) { + RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_TERRAIN_EDGE, uint8) = 255; + } else { + RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_TERRAIN_EDGE, uint8) = 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_base_invalidate() +{ + rct_window *w; + + window_get_register(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() +{ + uint16 arg; + rct_window *w; + rct_drawpixelinfo *dpi; + + window_paint_get_registers(w, dpi); + + 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, 2691, 0, 0, w->x + 4, w->y + w->widgets[WIDX_BASE_HEIGHT].top + 1); + gfx_draw_string_left(dpi, 2692, 0, 0, w->x + 4, w->y + w->widgets[WIDX_WATER_LEVEL].top + 1); + gfx_draw_string_left(dpi, 2693, 0, 0, w->x + 4, w->y + w->widgets[WIDX_FLOOR_TEXTURE].top + 1); + + uint16 mapSizeArgs[2] = { _mapSize, _mapSize }; + 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; + short widgetIndex; + mapgen_settings mapgenSettings; + + window_widget_get_registers(w, widgetIndex); + + switch (widgetIndex) { + case WIDX_CLOSE: + window_close(w); + break; + case WIDX_TAB_1: + case WIDX_TAB_2: + 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; + + 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; + + window_get_register(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_paint_get_registers(w, dpi); + + window_draw_widgets(w, dpi); + window_mapgen_draw_tab_images(dpi, w); +} + +#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->var_020 = 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 - 3 - height - 3; + 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 / 2; + if (page == WINDOW_MAPGEN_PAGE_BASE) + frame %= 8; + spriteIndex += frame; + } + + 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) +{ + +} + +#pragma endregion \ No newline at end of file diff --git a/src/windows/top_toolbar.c b/src/windows/top_toolbar.c new file mode 100644 index 0000000000..6cb873b68b --- /dev/null +++ b/src/windows/top_toolbar.c @@ -0,0 +1,992 @@ +/***************************************************************************** + * Copyright (c) 2014 Ted John + * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. + * + * This file is part of 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. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#include "../addresses.h" +#include "../editor.h" +#include "../game.h" +#include "../input.h" +#include "../sprites.h" +#include "../audio/audio.h" +#include "../interface/widget.h" +#include "../interface/window.h" +#include "../interface/viewport.h" +#include "../localisation/localisation.h" +#include "dropdown.h" +#include "scenery.h" + +enum { + WIDX_PAUSE, + WIDX_FILE_MENU, + WIDX_ZOOM_OUT, + WIDX_ZOOM_IN, + WIDX_ROTATE, + WIDX_VIEW_MENU, + WIDX_MAP, + + WIDX_LAND, + WIDX_WATER, + WIDX_SCENERY, + WIDX_PATH, + WIDX_CONSTRUCT_RIDE, + WIDX_RIDES, + WIDX_PARK, + WIDX_STAFF, + WIDX_GUESTS, + WIDX_CLEAR_SCENERY, + + //WIDX_FASTFORWARD, + WIDX_FINANCES, + WIDX_RESEARCH, + + WIDX_SEPARATOR, +}; + +typedef enum { + DDIDX_LOAD_GAME = 0, + DDIDX_SAVE_GAME = 1, + DDIDX_ABOUT = 3, + DDIDX_OPTIONS = 4, + DDIDX_SCREENSHOT = 5, + DDIDX_QUIT_GAME = 7, +} FILE_MENU_DDIDX; + +typedef enum { + DDIDX_UNDERGROUND_INSIDE = 0, + DDIDX_HIDE_BASE = 1, + DDIDX_HIDE_VERTICAL = 2, + DDIDX_SEETHROUGH_RIDES = 4, + DDIDX_SEETHROUGH_SCENARY = 5, + DDIDX_INVISIBLE_SUPPORTS = 6, + DDIDX_INVISIBLE_PEEPS = 7, + DDIDX_LAND_HEIGHTS = 9, + DDIDX_TRACK_HEIGHTS = 10, + DDIDX_PATH_HEIGHTS = 11, +} TOP_TOOLBAR_VIEW_MENU_DDIDX; + +#pragma region Toolbar_widget_ordering + +// from left to right +static const int left_aligned_widgets_order[] = { + WIDX_PAUSE, + //WIDX_FASTFORWARD, + WIDX_FILE_MENU, + + WIDX_SEPARATOR, + + WIDX_ZOOM_OUT, + WIDX_ZOOM_IN, + WIDX_ROTATE, + WIDX_VIEW_MENU, + WIDX_MAP, +}; + +// from right to left +static const int right_aligned_widgets_order[] = { + WIDX_GUESTS, + WIDX_STAFF, + WIDX_PARK, + WIDX_RIDES, + WIDX_RESEARCH, + WIDX_FINANCES, + + WIDX_SEPARATOR, + + WIDX_CONSTRUCT_RIDE, + WIDX_PATH, + WIDX_SCENERY, + WIDX_WATER, + WIDX_LAND, + WIDX_CLEAR_SCENERY, +}; + +#pragma endregion + +static rct_widget window_top_toolbar_widgets[] = { + { WWT_TRNBTN, 0, 0x0000, 0x001D, 0, 27, 0x20000000 | SPR_TOOLBAR_PAUSE, STR_PAUSE_GAME_TIP }, // Pause + { WWT_TRNBTN, 0, 0x001E + 30, 0x003B + 30, 0, 27, 0x20000000 | SPR_TOOLBAR_FILE, STR_DISC_AND_GAME_OPTIONS_TIP }, // File menu + { WWT_TRNBTN, 1, 0x0046 + 30, 0x0063 + 30, 0, 27, 0x20000000 | SPR_TOOLBAR_ZOOM_OUT, STR_ZOOM_OUT_TIP }, // Zoom out + { WWT_TRNBTN, 1, 0x0064 + 30, 0x0081 + 30, 0, 27, 0x20000000 | SPR_TOOLBAR_ZOOM_IN, STR_ZOOM_IN_TIP }, // Zoom in + { WWT_TRNBTN, 1, 0x0082 + 30, 0x009F + 30, 0, 27, 0x20000000 | SPR_TOOLBAR_ROTATE, STR_ROTATE_TIP }, // Rotate camera + { WWT_TRNBTN, 1, 0x00A0 + 30, 0x00BD + 30, 0, 27, 0x20000000 | SPR_TOOLBAR_VIEW, STR_VIEW_OPTIONS_TIP }, // Transparancy menu + { WWT_TRNBTN, 1, 0x00BE + 30, 0x00DB + 30, 0, 27, 0x20000000 | SPR_TOOLBAR_MAP, STR_SHOW_MAP_TIP }, // Map + + { WWT_TRNBTN, 2, 0x010B, 0x0128, 0, 27, 0x20000000 | SPR_TOOLBAR_LAND, STR_ADJUST_LAND_TIP }, // Land + { WWT_TRNBTN, 2, 0x0129, 0x0146, 0, 27, 0x20000000 | SPR_TOOLBAR_WATER, STR_ADJUST_WATER_TIP }, // Water + { WWT_TRNBTN, 2, 0x0147, 0x0164, 0, 27, 0x20000000 | SPR_TOOLBAR_SCENERY, STR_PLACE_SCENERY_TIP }, // Scenery + { WWT_TRNBTN, 2, 0x0165, 0x0182, 0, 27, 0x20000000 | SPR_TOOLBAR_FOOTPATH, STR_BUILD_FOOTPATH_TIP }, // Path + { WWT_TRNBTN, 2, 0x0183, 0x01A0, 0, 27, 0x20000000 | SPR_TOOLBAR_CONSTRUCT_RIDE, STR_BUILD_RIDE_TIP }, // Construct ride + { WWT_TRNBTN, 3, 0x01EA, 0x0207, 0, 27, 0x20000000 | SPR_TOOLBAR_RIDES, STR_RIDES_IN_PARK_TIP }, // Rides + { WWT_TRNBTN, 3, 0x0208, 0x0225, 0, 27, 0x20000000 | SPR_TOOLBAR_PARK, STR_PARK_INFORMATION_TIP }, // Park + { WWT_TRNBTN, 3, 0x0226, 0x0243, 0, 27, 0x20000000 | 0x15F9, STR_STAFF_TIP }, // Staff + { WWT_TRNBTN, 3, 0x0230, 0x024D, 0, 27, 0x20000000 | SPR_TOOLBAR_GUESTS, STR_GUESTS_TIP }, // Guests + { WWT_TRNBTN, 2, 0x0230, 0x024D, 0, 27, 0x20000000 | SPR_TOOLBAR_CLEAR_SCENERY, STR_CLEAR_SCENERY_TIP }, // Clear scenery + + //{ WWT_TRNBTN, 0, 0x001E, 0x003B, 0, 27, 0x20000000 | 0x15F9, STR_NONE }, // Fast forward + { WWT_TRNBTN, 3, 0x001E, 0x003B, 0, 27, 0x20000000 | 0x15F9, 3235 }, // Finances + { WWT_TRNBTN, 3, 0x001E, 0x003B, 0, 27, 0x20000000 | 0x15F9, 2275 }, // Research + + { WWT_EMPTY, 0, 0, 10-1, 0, 0, 0xFFFFFFFF, STR_NONE }, // Artificial widget separator + { WIDGETS_END }, +}; + +static void window_top_toolbar_emptysub() { } +static void window_top_toolbar_mouseup(); +static void window_top_toolbar_mousedown(int widgetIndex, rct_window*w, rct_widget* widget); +static void window_top_toolbar_dropdown(); +static void window_top_toolbar_tool_update(); +static void window_top_toolbar_tool_down(); +static void window_top_toolbar_tool_drag(); +static void window_top_toolbar_invalidate(); +static void window_top_toolbar_paint(); + +static void* window_top_toolbar_events[] = { + window_top_toolbar_emptysub, + window_top_toolbar_mouseup, + window_top_toolbar_emptysub, + window_top_toolbar_mousedown, + window_top_toolbar_dropdown, + window_top_toolbar_emptysub, + window_top_toolbar_emptysub, + window_top_toolbar_emptysub, + window_top_toolbar_emptysub, // check if editor versions are significantly different... + window_top_toolbar_tool_update, // editor: 0x0066fB0E + window_top_toolbar_tool_down, // editor: 0x0066fB5C + window_top_toolbar_tool_drag, // editor: 0x0066fB37 + (void*)0x0066CC5B, // editor: 0x0066fC44 + (void*)0x0066CA58, // editor: 0x0066fA74 + window_top_toolbar_emptysub, + window_top_toolbar_emptysub, + window_top_toolbar_emptysub, + window_top_toolbar_emptysub, + window_top_toolbar_emptysub, + window_top_toolbar_emptysub, + window_top_toolbar_emptysub, + window_top_toolbar_emptysub, + window_top_toolbar_emptysub, + window_top_toolbar_emptysub, + window_top_toolbar_emptysub, + window_top_toolbar_invalidate, + window_top_toolbar_paint, + window_top_toolbar_emptysub +}; + +void top_toolbar_init_view_menu(rct_window *window, rct_widget *widget); +void top_toolbar_view_menu_dropdown(short dropdownIndex); + +void toggle_footpath_window(); +void toggle_land_window(rct_window *topToolbar, int widgetIndex); +void toggle_clear_scenery_window(rct_window *topToolbar, int widgetIndex); +void toggle_water_window(rct_window *topToolbar, int widgetIndex); + +/** + * Creates the main game top toolbar window. + * rct2: 0x0066B485 (part of 0x0066B3E8) + */ +void window_top_toolbar_open() +{ + rct_window* window; + + window = window_create( + 0, 0, + RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16), 28, + (uint32*)window_top_toolbar_events, + WC_TOP_TOOLBAR, + WF_STICK_TO_FRONT | WF_TRANSPARENT | WF_5 + ); + window->widgets = window_top_toolbar_widgets; + + window_init_scroll_widgets(window); + window->colours[0] = 7; + window->colours[1] = 12; + window->colours[2] = 24; + window->colours[3] = 1; +} + +/** + * + * rct2: 0x0066C957 + */ +static void window_top_toolbar_mouseup() +{ + short widgetIndex; + rct_window *w, *mainWindow; + + window_widget_get_registers(w, widgetIndex); + + switch (widgetIndex) { + case WIDX_PAUSE: + game_do_command(0, 1, 0, 0, GAME_COMMAND_TOGGLE_PAUSE, 0, 0); + break; + // case WIDX_FASTFORWARD: + // // This is an excellent place to add in debugging statements and + // // print routines, that will be triggered when you press the + // // button in the game. Use "git update-index --skip-worktree + // // src/window_top_toolbar" to avoid committing these changes to + // // version control. + // window_cheats_open(); + // break; + + case WIDX_ZOOM_OUT: + if ((mainWindow = window_get_main()) != NULL) + window_zoom_out(mainWindow); + break; + case WIDX_ZOOM_IN: + if ((mainWindow = window_get_main()) != NULL) + window_zoom_in(mainWindow); + break; + case WIDX_ROTATE: + if ((mainWindow = window_get_main()) != NULL) + window_rotate_camera(mainWindow); + break; + case WIDX_CLEAR_SCENERY: + toggle_clear_scenery_window(w, WIDX_CLEAR_SCENERY); + break; + case WIDX_LAND: + toggle_land_window(w, WIDX_LAND); + break; + case WIDX_WATER: + toggle_water_window(w, WIDX_WATER); + break; + case WIDX_SCENERY: + if (!tool_set(w, WIDX_SCENERY, 0)) { + RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6; + window_scenery_open(); + } + break; + case WIDX_PATH: + toggle_footpath_window(); + break; + case WIDX_CONSTRUCT_RIDE: + window_new_ride_open(); + break; + case WIDX_RIDES: + window_ride_list_open(); + break; + case WIDX_PARK: + window_park_entrance_open(); + break; + case WIDX_STAFF: + window_staff_list_open(); + break; + case WIDX_GUESTS: + window_guest_list_open(); + break; + case WIDX_FINANCES: + window_finances_open(); + break; + case WIDX_RESEARCH: + window_research_open(); + break; + } +} + +/** + * + * rct2: 0x0066CA3B + */ +static void window_top_toolbar_mousedown(int widgetIndex, rct_window*w, rct_widget* widget) +{ + int numItems; + + switch (widgetIndex) { + case WIDX_FILE_MENU: + if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & (SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER)) { + gDropdownItemsFormat[0] = STR_ABOUT; + gDropdownItemsFormat[1] = STR_OPTIONS; + gDropdownItemsFormat[2] = STR_SCREENSHOT; + gDropdownItemsFormat[3] = 0; + gDropdownItemsFormat[4] = STR_QUIT_TRACK_DESIGNS_MANAGER; + + if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_DESIGNER) + gDropdownItemsFormat[4] = STR_QUIT_ROLLERCOASTER_DESIGNER; + + numItems = 5; + } else if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_SCENARIO_EDITOR) { + gDropdownItemsFormat[0] = STR_LOAD_LANDSCAPE; + gDropdownItemsFormat[1] = STR_SAVE_LANDSCAPE; + gDropdownItemsFormat[2] = 0; + gDropdownItemsFormat[3] = STR_ABOUT; + gDropdownItemsFormat[4] = STR_OPTIONS; + gDropdownItemsFormat[5] = STR_SCREENSHOT; + gDropdownItemsFormat[6] = 0; + gDropdownItemsFormat[7] = STR_QUIT_SCENARIO_EDITOR; + numItems = 8; + } else { + gDropdownItemsFormat[0] = STR_LOAD_GAME; + gDropdownItemsFormat[1] = STR_SAVE_GAME; + gDropdownItemsFormat[2] = 0; + gDropdownItemsFormat[3] = STR_ABOUT; + gDropdownItemsFormat[4] = STR_OPTIONS; + gDropdownItemsFormat[5] = STR_SCREENSHOT; + gDropdownItemsFormat[6] = 0; + gDropdownItemsFormat[7] = STR_QUIT_GAME; + numItems = 8; + } + window_dropdown_show_text( + w->x + widget->left, + w->y + widget->top, + widget->bottom - widget->top + 1, + w->colours[0] | 0x80, + 0x80, + numItems + ); + break; + case WIDX_VIEW_MENU: + top_toolbar_init_view_menu(w, widget); + break; + case WIDX_MAP: + gDropdownItemsFormat[0] = 2523; + gDropdownItemsFormat[1] = 2780; + numItems = 2; + + if ((RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_SCENARIO_EDITOR) && g_editor_step == EDITOR_STEP_LANDSCAPE_EDITOR) { + gDropdownItemsFormat[2] = 2690; + numItems++; + } + + window_dropdown_show_text( + w->x + widget->left, + w->y + widget->top, + widget->bottom - widget->top + 1, + w->colours[1] | 0x80, + 0, + numItems + ); + RCT2_GLOBAL(0x009DEBA2, uint16) = 0; + break; + } +} + +/** + * + * rct2: 0x0066C9EA + */ +static void window_top_toolbar_dropdown() +{ + short widgetIndex, dropdownIndex; + rct_window* w; + + window_dropdown_get_registers(w, widgetIndex, dropdownIndex); + + switch (widgetIndex) { + case WIDX_FILE_MENU: + if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & (SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER)) + dropdownIndex += DDIDX_ABOUT; + + switch (dropdownIndex) { + case DDIDX_LOAD_GAME: + game_do_command(0, 1, 0, 0, GAME_COMMAND_LOAD_OR_QUIT, 0, 0); + break; + case DDIDX_SAVE_GAME: + if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_SCENARIO_EDITOR) { + RCT2_CALLPROC_EBPSAFE(0x0066FE2A); + } else { + tool_cancel(); + save_game(); + } + break; + case DDIDX_ABOUT: + window_about_open(); + break; + case DDIDX_OPTIONS: + window_options_open(); + break; + case DDIDX_SCREENSHOT: + RCT2_GLOBAL(RCT2_ADDRESS_SCREENSHOT_COUNTDOWN, sint8) = 10; + break; + case DDIDX_QUIT_GAME: + window_close_by_class(WC_MANAGE_TRACK_DESIGN); + window_close_by_class(WC_TRACK_DELETE_PROMPT); + game_do_command(0, 1, 0, 0, GAME_COMMAND_LOAD_OR_QUIT, 1, 0); + break; + } + break; + case WIDX_VIEW_MENU: + top_toolbar_view_menu_dropdown(dropdownIndex); + break; + case WIDX_MAP: + if (dropdownIndex == -1) + dropdownIndex = RCT2_GLOBAL(0x009DEBA2, uint16); + + switch (dropdownIndex) { + case 0: + window_map_open(); + break; + case 1: + window_viewport_open(); + break; + case 2: + window_mapgen_open(); + break; + } + break; + } +} + +/** + * + * rct2: 0x0066C810 + */ +static void window_top_toolbar_invalidate() +{ + int i, x, enabledWidgets, widgetIndex, widgetWidth, firstAlignment; + rct_window *w; + rct_widget *widget; + + window_get_register(w); + + // Enable / disable buttons + window_top_toolbar_widgets[WIDX_PAUSE].type = WWT_TRNBTN; + window_top_toolbar_widgets[WIDX_FILE_MENU].type = WWT_TRNBTN; + window_top_toolbar_widgets[WIDX_ZOOM_OUT].type = WWT_TRNBTN; + window_top_toolbar_widgets[WIDX_ZOOM_IN].type = WWT_TRNBTN; + window_top_toolbar_widgets[WIDX_ROTATE].type = WWT_TRNBTN; + window_top_toolbar_widgets[WIDX_VIEW_MENU].type = WWT_TRNBTN; + window_top_toolbar_widgets[WIDX_MAP].type = WWT_TRNBTN; + window_top_toolbar_widgets[WIDX_LAND].type = WWT_TRNBTN; + window_top_toolbar_widgets[WIDX_WATER].type = WWT_TRNBTN; + window_top_toolbar_widgets[WIDX_SCENERY].type = WWT_TRNBTN; + window_top_toolbar_widgets[WIDX_PATH].type = WWT_TRNBTN; + window_top_toolbar_widgets[WIDX_CONSTRUCT_RIDE].type = WWT_TRNBTN; + window_top_toolbar_widgets[WIDX_RIDES].type = WWT_TRNBTN; + window_top_toolbar_widgets[WIDX_PARK].type = WWT_TRNBTN; + window_top_toolbar_widgets[WIDX_STAFF].type = WWT_TRNBTN; + window_top_toolbar_widgets[WIDX_GUESTS].type = WWT_TRNBTN; + window_top_toolbar_widgets[WIDX_CLEAR_SCENERY].type = WWT_TRNBTN; + window_top_toolbar_widgets[WIDX_FINANCES].type = WWT_TRNBTN; + window_top_toolbar_widgets[WIDX_RESEARCH].type = WWT_TRNBTN; + + if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & (SCREEN_FLAGS_SCENARIO_EDITOR | SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER)) { + window_top_toolbar_widgets[WIDX_PAUSE].type = WWT_EMPTY; + window_top_toolbar_widgets[WIDX_RIDES].type = WWT_EMPTY; + window_top_toolbar_widgets[WIDX_PARK].type = WWT_EMPTY; + window_top_toolbar_widgets[WIDX_STAFF].type = WWT_EMPTY; + window_top_toolbar_widgets[WIDX_GUESTS].type = WWT_EMPTY; + window_top_toolbar_widgets[WIDX_FINANCES].type = WWT_EMPTY; + window_top_toolbar_widgets[WIDX_RESEARCH].type = WWT_EMPTY; + + if (g_editor_step != EDITOR_STEP_LANDSCAPE_EDITOR) { + window_top_toolbar_widgets[WIDX_MAP].type = WWT_EMPTY; + window_top_toolbar_widgets[WIDX_LAND].type = WWT_EMPTY; + window_top_toolbar_widgets[WIDX_WATER].type = WWT_EMPTY; + window_top_toolbar_widgets[WIDX_SCENERY].type = WWT_EMPTY; + window_top_toolbar_widgets[WIDX_PATH].type = WWT_EMPTY; + window_top_toolbar_widgets[WIDX_CLEAR_SCENERY].type = WWT_EMPTY; + } + + if (g_editor_step != EDITOR_STEP_ROLLERCOASTER_DESIGNER) { + window_top_toolbar_widgets[WIDX_CONSTRUCT_RIDE].type = WWT_EMPTY; + } + + if (g_editor_step != EDITOR_STEP_LANDSCAPE_EDITOR && g_editor_step != EDITOR_STEP_ROLLERCOASTER_DESIGNER) { + window_top_toolbar_widgets[WIDX_ZOOM_OUT].type = WWT_EMPTY; + window_top_toolbar_widgets[WIDX_ZOOM_IN].type = WWT_EMPTY; + window_top_toolbar_widgets[WIDX_ROTATE].type = WWT_EMPTY; + window_top_toolbar_widgets[WIDX_VIEW_MENU].type = WWT_EMPTY; + } + } else { + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY) + window_top_toolbar_widgets[WIDX_FINANCES].type = WWT_EMPTY; + } + + enabledWidgets = 0; + for (i = WIDX_PAUSE; i <= WIDX_RESEARCH; i++) + if (window_top_toolbar_widgets[i].type != WWT_EMPTY) + enabledWidgets |= (1 << i); + w->enabled_widgets = enabledWidgets; + + // Align left hand side toolbar buttons + firstAlignment = 1; + x = 0; + for (int i = 0; i < countof(left_aligned_widgets_order); ++i) { + widgetIndex = left_aligned_widgets_order[i]; + widget = &window_top_toolbar_widgets[widgetIndex]; + if (widget->type == WWT_EMPTY && widgetIndex != WIDX_SEPARATOR) + continue; + + if (firstAlignment && widgetIndex == WIDX_SEPARATOR) + continue; + + widgetWidth = widget->right - widget->left; + widget->left = x; + x += widgetWidth; + widget->right = x; + x += 1; + firstAlignment = 0; + } + + // Align right hand side toolbar buttons + firstAlignment = 1; + x = max(640, RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16)); + for (int i = 0; i < countof(right_aligned_widgets_order); ++i) { + widgetIndex = right_aligned_widgets_order[i]; + widget = &window_top_toolbar_widgets[widgetIndex]; + if (widget->type == WWT_EMPTY && widgetIndex != WIDX_SEPARATOR) + continue; + + if (firstAlignment && widgetIndex == WIDX_SEPARATOR) + continue; + + widgetWidth = widget->right - widget->left; + x -= 1; + widget->right = x; + x -= widgetWidth; + widget->left = x; + firstAlignment = 0; + } + + // Footpath button pressed down + if (window_find_by_class(WC_FOOTPATH) == NULL) + w->pressed_widgets &= ~(1 << WIDX_PATH); + else + w->pressed_widgets |= (1 << WIDX_PATH); + + // Fast forward button pressed down + // if (0) + // w->pressed_widgets |= (1 << WIDX_FASTFORWARD); + // else + // w->pressed_widgets &= ~(1 << WIDX_FASTFORWARD); + + if (!(RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint32) & 1)) + w->pressed_widgets &= ~(1 << WIDX_PAUSE); + else + w->pressed_widgets |= (1 << WIDX_PAUSE); + + // Zoomed out/in disable. Not sure where this code is in the original. + if (window_get_main()->viewport->zoom == 0){ + w->disabled_widgets |= (1 << WIDX_ZOOM_IN); + } else if (window_get_main()->viewport->zoom == 3){ + w->disabled_widgets |= (1 << WIDX_ZOOM_OUT); + } else { + w->disabled_widgets &= ~((1 << WIDX_ZOOM_IN) | (1 << WIDX_ZOOM_OUT)); + } +} + +/** + * + * rct2: 0x0066C8EC + */ +static void window_top_toolbar_paint() +{ + int x, y, imgId; + rct_window *w; + rct_drawpixelinfo *dpi; + + window_paint_get_registers(w, dpi); + + window_draw_widgets(w, dpi); + + // Draw staff button image (setting masks to the staff colours) + if (window_top_toolbar_widgets[WIDX_STAFF].type != WWT_EMPTY) { + x = w->x + window_top_toolbar_widgets[WIDX_STAFF].left; + y = w->y + window_top_toolbar_widgets[WIDX_STAFF].top; + imgId = 5627; + if (widget_is_pressed(w, WIDX_STAFF)) + imgId++; + imgId |= (RCT2_GLOBAL(RCT2_ADDRESS_HANDYMAN_COLOUR, uint8) << 19) | 0xA0000000 | (RCT2_GLOBAL(RCT2_ADDRESS_MECHANIC_COLOUR, uint8) << 24); + gfx_draw_sprite(dpi, imgId, x, y, 0); + } + + // Draw research button + if (window_top_toolbar_widgets[WIDX_RESEARCH].type != WWT_EMPTY) { + x = w->x + window_top_toolbar_widgets[WIDX_RESEARCH].left - 1; + y = w->y + window_top_toolbar_widgets[WIDX_RESEARCH].top; + imgId = SPR_TAB_FINANCES_RESEARCH_0; + gfx_draw_sprite(dpi, imgId, x, y, 0); + } + + // Draw finances button + if (window_top_toolbar_widgets[WIDX_FINANCES].type != WWT_EMPTY) { + x = w->x + window_top_toolbar_widgets[WIDX_FINANCES].left + 3; + y = w->y + window_top_toolbar_widgets[WIDX_FINANCES].top + 1; + imgId = SPR_FINANCE; + gfx_draw_sprite(dpi, imgId, x, y, 0); + } +} + +/** + * rct2: 0x6e2cc6 + */ +static void window_top_toolbar_scenery_tool_down(short x, short y, rct_window* w, short widgetIndex){ + RCT2_CALLPROC_EBPSAFE(0x006E2712); + if (window_scenery_is_repaint_scenery_tool_on & 1){ + //6e3158 + RCT2_CALLPROC_X(0x6E2CC6, x, y, 0, widgetIndex, (int)w, 0, 0); + } + + int selected_tab = window_scenery_selected_scenery_by_tab[window_scenery_active_tab_index]; + if (selected_tab == -1) return; + + sint16 grid_x, grid_y, grid_z; + uint8 item_colour; + uint8 model_type; + int ebp = selected_tab; + + { + int eax = x, ebx = y, ecx = 0, edx = 0, esi = 0, edi = 0; + RCT2_CALLFUNC_X(0x6E1F34, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + item_colour = edi; + model_type = (ebx & 0xFF00) >> 8; + grid_x = eax; + grid_y = ecx; + grid_z = edx; + } + + if (grid_x == 0x8000)return; + + if (ebp >= 1024){ + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, rct_string_id) = 1161; + + // The return value will be banner id but the input is colour + int banner_id = item_colour; + + int ebx = (model_type << 8) | 1; + + { + int esi = 0, eax = grid_x, ecx = grid_y, edx = grid_z; + game_do_command_p(GAME_COMMAND_50, &eax, &ebx, &ecx, &edx, &esi, &banner_id, &ebp); + } + + if (ebx == 0x80000000)return; + + sound_play_panned(SOUND_PLACE_ITEM, 0x8001, RCT2_GLOBAL(0x009DEA5E, uint16), RCT2_GLOBAL(0x009DEA60, uint16), RCT2_GLOBAL(0x009DEA62, uint16)); + + window_banner_open(banner_id); + } + else if (ebp >= 768){ + //6e301c + RCT2_CALLPROC_X(0x6E2CC6, x, y, 0, widgetIndex, (int)w, 0, 0); + } + else if (ebp >= 512){ + //6e2f2e + RCT2_CALLPROC_X(0x6E2CC6, x, y, 0, widgetIndex, (int)w, 0, 0); + } + else if (ebp >= 256){ + //6e2eda + RCT2_CALLPROC_X(0x6E2CC6, x, y, 0, widgetIndex, (int)w, 0, 0); + } + else{ + //6e2d2d + RCT2_CALLPROC_X(0x6E2CC6, x, y, 0, widgetIndex, (int)w, 0, 0); + } +} + +/** + * + * rct2: 0x0066CB25 + */ +static void window_top_toolbar_tool_update() +{ + short widgetIndex; + rct_window *w; + short x, y; + + window_tool_get_registers(w, widgetIndex, x, y); + + switch (widgetIndex){ + case WIDX_CLEAR_SCENERY: + RCT2_CALLPROC_X(0x0068E213, x, y, 0, widgetIndex, (int)w, 0, 0); + break; + case WIDX_LAND: + RCT2_CALLPROC_X(0x00664280, x, y, 0, widgetIndex, (int)w, 0, 0); + break; + case WIDX_WATER: + RCT2_CALLPROC_X(0x006E6BDC, x, y, 0, widgetIndex, (int)w, 0, 0); + break; + case WIDX_SCENERY: + RCT2_CALLPROC_X(0x006E287B, x, y, 0, widgetIndex, (int)w, 0, 0); + break; + } +} + +/** + * rct2: 0x0066CB73 + */ +static void window_top_toolbar_tool_down(){ + short widgetIndex; + rct_window* w; + short x, y; + + window_tool_get_registers(w, widgetIndex, x, y); + + switch (widgetIndex){ + case WIDX_CLEAR_SCENERY: + if (!RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) & (1 << 0)) + break; + + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, rct_string_id) = 3438; + + game_do_command( + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, uint16), + 1, + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, uint16), + 0, + GAME_COMMAND_CLEAR_SCENERY, + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16), + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16) + ); + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) = 12; + break; + case WIDX_LAND: + if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16)&(1 << 0)){ + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, rct_string_id) = 1387; + game_do_command( + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, uint16), + 1, + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, uint16), + RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_TERRAIN_SURFACE, uint8) | (RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_TERRAIN_EDGE, uint8) << 8), + GAME_COMMAND_CHANGE_SURFACE_STYLE, + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16), + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16) + ); + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) = 3; + } + break; + case WIDX_WATER: + if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16)&(1 << 0)){ + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) = 3; + } + break; + case WIDX_SCENERY: + window_top_toolbar_scenery_tool_down(x, y, w, widgetIndex); + break; + } +} + +/** + * + * rct2: 0x0066CB4E + */ +static void window_top_toolbar_tool_drag() +{ + short widgetIndex; + rct_window *w; + short x, y; + + window_tool_get_registers(w, widgetIndex, x, y); + + switch (widgetIndex){ + case WIDX_CLEAR_SCENERY: + if (window_find_by_class(WC_ERROR) != NULL) + break; + + if (!RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) & (1 << 0)) + break; + + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, rct_string_id) = 3438; + + game_do_command( + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, uint16), + 1, + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, uint16), + 0, + GAME_COMMAND_CLEAR_SCENERY, + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16), + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16) + ); + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) = 12; + break; + case WIDX_LAND: + RCT2_CALLPROC_X(0x00664454, x, y, 0, widgetIndex, (int)w, 0, 0); + break; + case WIDX_WATER: + RCT2_CALLPROC_X(0x006E6D4B, x, y, 0, widgetIndex, (int)w, 0, 0); + break; + case WIDX_SCENERY: + RCT2_CALLPROC_X(0x006E2CBC, x, y, 0, widgetIndex, (int)w, 0, 0); + break; + } +} + +/** + * + * rct2: 0x0066CDE4 + */ +void top_toolbar_init_view_menu(rct_window* w, rct_widget* widget) { + gDropdownItemsFormat[0] = 1156; + gDropdownItemsFormat[1] = 1156; + gDropdownItemsFormat[2] = 1156; + gDropdownItemsFormat[3] = 0; + gDropdownItemsFormat[4] = 1156; + gDropdownItemsFormat[5] = 1156; + gDropdownItemsFormat[6] = 1156; + gDropdownItemsFormat[7] = 1156; + gDropdownItemsFormat[8] = 0; + gDropdownItemsFormat[9] = 1156; + gDropdownItemsFormat[10] = 1156; + gDropdownItemsFormat[11] = 1156; + + gDropdownItemsArgs[0] = STR_UNDERGROUND_VIEW; + gDropdownItemsArgs[1] = STR_REMOVE_BASE_LAND; + gDropdownItemsArgs[2] = STR_REMOVE_VERTICAL_FACES; + gDropdownItemsArgs[4] = STR_SEE_THROUGH_RIDES; + gDropdownItemsArgs[5] = STR_SEE_THROUGH_SCENERY; + gDropdownItemsArgs[6] = STR_INVISIBLE_SUPPORTS; + gDropdownItemsArgs[7] = STR_INVISIBLE_PEOPLE; + gDropdownItemsArgs[9] = STR_HEIGHT_MARKS_ON_LAND; + gDropdownItemsArgs[10] = STR_HEIGHT_MARKS_ON_RIDE_TRACKS; + gDropdownItemsArgs[11] = STR_HEIGHT_MARKS_ON_PATHS; + + window_dropdown_show_text( + w->x + widget->left, + w->y + widget->top, + widget->bottom - widget->top + 1, + w->colours[1] | 0x80, + 0, + 12 + ); + + // Set checkmarks + rct_viewport* mainViewport = window_get_main()->viewport; + if (mainViewport->flags & VIEWPORT_FLAG_UNDERGROUND_INSIDE) + gDropdownItemsChecked |= (1 << 0); + if (mainViewport->flags & VIEWPORT_FLAG_HIDE_BASE) + gDropdownItemsChecked |= (1 << 1); + if (mainViewport->flags & VIEWPORT_FLAG_HIDE_VERTICAL) + gDropdownItemsChecked |= (1 << 2); + if (mainViewport->flags & VIEWPORT_FLAG_SEETHROUGH_RIDES) + gDropdownItemsChecked |= (1 << 4); + if (mainViewport->flags & VIEWPORT_FLAG_SEETHROUGH_SCENERY) + gDropdownItemsChecked |= (1 << 5); + if (mainViewport->flags & VIEWPORT_FLAG_INVISIBLE_SUPPORTS) + gDropdownItemsChecked |= (1 << 6); + if (mainViewport->flags & VIEWPORT_FLAG_INVISIBLE_PEEPS) + gDropdownItemsChecked |= (1 << 7); + if (mainViewport->flags & VIEWPORT_FLAG_LAND_HEIGHTS) + gDropdownItemsChecked |= (1 << 9); + if (mainViewport->flags & VIEWPORT_FLAG_TRACK_HEIGHTS) + gDropdownItemsChecked |= (1 << 10); + if (mainViewport->flags & VIEWPORT_FLAG_PATH_HEIGHTS) + gDropdownItemsChecked |= (1 << 11); + + RCT2_GLOBAL(0x9DEBA2, uint16) = 0; +} + +/** + * + * rct2: 0x0066CF8A + */ +void top_toolbar_view_menu_dropdown(short dropdownIndex) { + if (dropdownIndex == -1) dropdownIndex = RCT2_GLOBAL(0x9DEBA2, uint16); + rct_window* w = window_get_main(); + if (w) { + switch (dropdownIndex) { + case DDIDX_UNDERGROUND_INSIDE: + w->viewport->flags ^= VIEWPORT_FLAG_UNDERGROUND_INSIDE; + break; + case DDIDX_HIDE_BASE: + w->viewport->flags ^= VIEWPORT_FLAG_HIDE_BASE; + break; + case DDIDX_HIDE_VERTICAL: + w->viewport->flags ^= VIEWPORT_FLAG_HIDE_VERTICAL; + break; + case DDIDX_SEETHROUGH_RIDES: + w->viewport->flags ^= VIEWPORT_FLAG_SEETHROUGH_RIDES; + break; + case DDIDX_SEETHROUGH_SCENARY: + w->viewport->flags ^= VIEWPORT_FLAG_SEETHROUGH_SCENERY; + break; + case DDIDX_INVISIBLE_SUPPORTS: + w->viewport->flags ^= VIEWPORT_FLAG_INVISIBLE_SUPPORTS; + break; + case DDIDX_INVISIBLE_PEEPS: + w->viewport->flags ^= VIEWPORT_FLAG_INVISIBLE_PEEPS; + break; + case DDIDX_LAND_HEIGHTS: + w->viewport->flags ^= VIEWPORT_FLAG_LAND_HEIGHTS; + break; + case DDIDX_TRACK_HEIGHTS: + w->viewport->flags ^= VIEWPORT_FLAG_TRACK_HEIGHTS; + break; + case DDIDX_PATH_HEIGHTS: + w->viewport->flags ^= VIEWPORT_FLAG_PATH_HEIGHTS; + break; + default: + return; + } + window_invalidate(w); + } +} + + +/** + * + * rct2: 0x0066CCE7 + */ +void toggle_footpath_window() +{ + if (window_find_by_class(WC_FOOTPATH) == NULL) { + window_footpath_open(); + } else { + tool_cancel(); + window_close_by_class(WC_FOOTPATH); + } +} + +/** + * + * rct2: 0x0066CD54 + */ +void toggle_land_window(rct_window *topToolbar, int widgetIndex) +{ + if ((RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE) && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, uint8) == 1 && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) == 7) { + tool_cancel(); + } else { + show_gridlines(); + tool_set(topToolbar, widgetIndex, 18); + RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6; + RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) = 1; + window_land_open(); + } +} + +/** + * + * rct2: 0x0066CD0C + */ +void toggle_clear_scenery_window(rct_window *topToolbar, int widgetIndex) +{ + if ((RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE) && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, uint8) == 1 && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) == 16) { + tool_cancel(); + } else { + show_gridlines(); + tool_set(topToolbar, widgetIndex, 12); + RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6; + RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) = 2; + window_clear_scenery_open(); + } +} + +/** + * + * rct2: 0x0066CD9C + */ +void toggle_water_window(rct_window *topToolbar, int widgetIndex) +{ + if ((RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE) && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, uint8) == 1 && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) == 8) { + tool_cancel(); + } else { + show_gridlines(); + tool_set(topToolbar, widgetIndex, 19); + RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6; + RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) = 1; + window_water_open(); + } +} \ No newline at end of file diff --git a/src/world/map.c b/src/world/map.c index cc221baa0f..29f883d71f 100644 --- a/src/world/map.c +++ b/src/world/map.c @@ -168,7 +168,7 @@ rct_map_element *map_get_surface_element_at(int x, int y) * * rct2: 0x0068AB4C */ -void map_init() +void map_init(int size) { int i; rct_map_element *map_element; @@ -194,10 +194,10 @@ void map_init() RCT2_GLOBAL(0x013B0E70, sint16) = 0; _sub_6A876D_save_x = 0; _sub_6A876D_save_y = 0; - RCT2_GLOBAL(0x01358830, sint16) = 4768; - RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAXIMUM_X_Y, sint16) = 5054; - RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, sint16) = 150; - RCT2_GLOBAL(0x01358836, sint16) = 4767; + RCT2_GLOBAL(0x01358830, sint16) = size * 32 - 32; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAXIMUM_X_Y, sint16) = size * 32 - 2; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, sint16) = size; + RCT2_GLOBAL(0x01358836, sint16) = size * 32 - 33; RCT2_GLOBAL(0x01359208, sint16) = 7; map_update_tile_pointers(); RCT2_CALLPROC_EBPSAFE(0x0068ADBC); diff --git a/src/world/map.h b/src/world/map.h index 07ba6b60af..eb83a32c6a 100644 --- a/src/world/map.h +++ b/src/world/map.h @@ -47,8 +47,8 @@ typedef struct { typedef struct { uint8 type; //4 uint8 age; //5 - uint8 colour; //6 - uint8 unused; //7 + uint8 colour_1; //6 + uint8 colour_2; //7 } rct_map_element_scenery_properties; typedef struct { @@ -223,7 +223,7 @@ typedef struct { extern const rct_xy16 TileDirectionDelta[]; extern rct_xy16 *gMapSelectionTiles; -void map_init(); +void map_init(int size); void map_update_tile_pointers(); rct_map_element *map_get_first_element_at(int x, int y); int map_element_is_last_for_tile(rct_map_element *element); diff --git a/src/world/map_helpers.c b/src/world/map_helpers.c new file mode 100644 index 0000000000..8e494a7b87 --- /dev/null +++ b/src/world/map_helpers.c @@ -0,0 +1,290 @@ +/***************************************************************************** + * Copyright (c) 2014 Ted John + * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. + * + * This file is part of 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. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#include "map.h" +#include "map_helpers.h" + +/** + * Not perfect, this still leaves some particular tiles unsmoothed. + */ +int map_smooth(int l, int t, int r, int b) +{ + int i, x, y, highest, count, cornerHeights[4], doubleCorner, raisedLand = 0; + rct_map_element *mapElement, *mapElement2; + for (y = t; y < b; y++) { + for (x = l; x < r; x++) { + mapElement = map_get_surface_element_at(x, y); + mapElement->properties.surface.slope &= ~0x1F; + + // Raise to edge height - 2 + highest = mapElement->base_height; + highest = max(highest, map_get_surface_element_at(x - 1, y + 0)->base_height); + highest = max(highest, map_get_surface_element_at(x + 1, y + 0)->base_height); + highest = max(highest, map_get_surface_element_at(x + 0, y - 1)->base_height); + highest = max(highest, map_get_surface_element_at(x + 0, y + 1)->base_height); + if (mapElement->base_height < highest - 2) { + raisedLand = 1; + mapElement->base_height = mapElement->clearance_height = highest - 2; + } + + // Check corners + doubleCorner = -1; + cornerHeights[0] = map_get_surface_element_at(x - 1, y - 1)->base_height; + cornerHeights[1] = map_get_surface_element_at(x + 1, y - 1)->base_height; + cornerHeights[2] = map_get_surface_element_at(x + 1, y + 1)->base_height; + cornerHeights[3] = map_get_surface_element_at(x - 1, y + 1)->base_height; + highest = mapElement->base_height; + for (i = 0; i < 4; i++) + highest = max(highest, cornerHeights[i]); + + if (highest >= mapElement->base_height + 4) { + count = 0; + for (i = 0; i < 4; i++) + if (cornerHeights[i] == highest) + count++; + + if (count == 1) { + if (mapElement->base_height < highest - 4) { + mapElement->base_height = mapElement->clearance_height = highest - 4; + raisedLand = 1; + } + if (cornerHeights[0] == highest && cornerHeights[2] <= cornerHeights[0] - 4) + doubleCorner = 0; + else if (cornerHeights[1] == highest && cornerHeights[3] <= cornerHeights[1] - 4) + doubleCorner = 1; + else if (cornerHeights[2] == highest && cornerHeights[0] <= cornerHeights[2] - 4) + doubleCorner = 2; + else if (cornerHeights[3] == highest && cornerHeights[1] <= cornerHeights[3] - 4) + doubleCorner = 3; + } else { + if (mapElement->base_height < highest - 2) { + mapElement->base_height = mapElement->clearance_height = highest - 2; + raisedLand = 1; + } + } + } + + if (doubleCorner != -1) { + mapElement->properties.surface.slope |= 16; + switch (doubleCorner) { + case 0: + mapElement->properties.surface.slope |= 2 | 4 | 8; + break; + case 1: + mapElement->properties.surface.slope |= 1 | 2 | 4; + break; + case 2: + mapElement->properties.surface.slope |= 1 | 2 | 8; + break; + case 3: + mapElement->properties.surface.slope |= 1 | 4 | 8; + break; + } + } else { + // Corners + mapElement2 = map_get_surface_element_at(x + 1, y + 1); + if (mapElement2->base_height > mapElement->base_height) + mapElement->properties.surface.slope |= 1; + + mapElement2 = map_get_surface_element_at(x - 1, y + 1); + if (mapElement2->base_height > mapElement->base_height) + mapElement->properties.surface.slope |= 8; + + mapElement2 = map_get_surface_element_at(x + 1, y - 1); + if (mapElement2->base_height > mapElement->base_height) + mapElement->properties.surface.slope |= 2; + + mapElement2 = map_get_surface_element_at(x - 1, y - 1); + if (mapElement2->base_height > mapElement->base_height) + mapElement->properties.surface.slope |= 4; + + // Sides + mapElement2 = map_get_surface_element_at(x + 1, y + 0); + if (mapElement2->base_height > mapElement->base_height) + mapElement->properties.surface.slope |= 1 | 2; + + mapElement2 = map_get_surface_element_at(x - 1, y + 0); + if (mapElement2->base_height > mapElement->base_height) + mapElement->properties.surface.slope |= 4 | 8; + + mapElement2 = map_get_surface_element_at(x + 0, y - 1); + if (mapElement2->base_height > mapElement->base_height) + mapElement->properties.surface.slope |= 2 | 4; + + mapElement2 = map_get_surface_element_at(x + 0, y + 1); + if (mapElement2->base_height > mapElement->base_height) + mapElement->properties.surface.slope |= 1 | 8; + + // Raise + if (mapElement->properties.surface.slope == (1 | 2 | 4 | 8)) { + mapElement->properties.surface.slope &= ~0x1F; + mapElement->base_height = mapElement->clearance_height += 2; + } + } + } + } + + return raisedLand; +} + +int map_get_corner_height(int x, int y, int corner) +{ + rct_map_element *mapElement = map_get_surface_element_at(x, y); + int baseHeight = mapElement->base_height; + int slope = mapElement->properties.surface.slope; + int doubleCorner = slope & 16; + if (doubleCorner) { + if (!(slope & 1)) doubleCorner = 4; + else if (!(slope & 2)) doubleCorner = 8; + else if (!(slope & 4)) doubleCorner = 1; + else if (!(slope & 8)) doubleCorner = 2; + } + + switch (corner) { + case 0: + return baseHeight + (slope & 1 ? (doubleCorner == 1 ? 4 : 2) : 0); + case 1: + return baseHeight + (slope & 8 ? (doubleCorner == 8 ? 4 : 2) : 0); + case 2: + return baseHeight + (slope & 2 ? (doubleCorner == 2 ? 4 : 2) : 0); + case 3: + return baseHeight + (slope & 4 ? (doubleCorner == 4 ? 4 : 2) : 0); + default: + return baseHeight; + } +} + +/** + * There are non-smoothed tiles with this version, but diagonal land blocks end up being wavy. + */ +int map_smooth_wavy(int l, int t, int r, int b) +{ + int i, x, y, highest, count, cornerHeights[4], doubleCorner, raisedLand = 0; + rct_map_element *mapElement; + for (y = t; y < b; y++) { + for (x = l; x < r; x++) { + mapElement = map_get_surface_element_at(x, y); + mapElement->properties.surface.slope &= ~0x1F; + + // Raise to edge height - 2 + highest = mapElement->base_height; + highest = max(highest, map_get_surface_element_at(x - 1, y + 0)->base_height); + highest = max(highest, map_get_surface_element_at(x + 1, y + 0)->base_height); + highest = max(highest, map_get_surface_element_at(x + 0, y - 1)->base_height); + highest = max(highest, map_get_surface_element_at(x + 0, y + 1)->base_height); + if (mapElement->base_height < highest - 2) { + raisedLand = 1; + mapElement->base_height = mapElement->clearance_height = highest - 2; + } + + // Check corners + doubleCorner = -1; + cornerHeights[0] = max(map_get_corner_height(x - 1, y - 1, 0), max(map_get_corner_height(x + 1, y + 0, 1), map_get_corner_height(x + 0, y + 1, 2))); + cornerHeights[1] = max(map_get_corner_height(x + 1, y - 1, 1), max(map_get_corner_height(x - 1, y + 0, 0), map_get_corner_height(x + 0, y + 1, 3))); + cornerHeights[2] = max(map_get_corner_height(x + 1, y + 1, 3), max(map_get_corner_height(x + 1, y + 0, 3), map_get_corner_height(x + 0, y - 1, 0))); + cornerHeights[3] = max(map_get_corner_height(x - 1, y + 1, 2), max(map_get_corner_height(x - 1, y + 0, 2), map_get_corner_height(x + 0, y - 1, 1))); + highest = mapElement->base_height; + for (i = 0; i < 4; i++) + highest = max(highest, cornerHeights[i]); + + if (highest >= mapElement->base_height + 4) { + count = 0; + for (i = 0; i < 4; i++) + if (cornerHeights[i] == highest) + count++; + + if (count == 1) { + if (mapElement->base_height < highest - 4) { + mapElement->base_height = mapElement->clearance_height = highest - 4; + raisedLand = 1; + } + if (cornerHeights[0] == highest && cornerHeights[2] <= cornerHeights[0] - 4) + doubleCorner = 0; + else if (cornerHeights[1] == highest && cornerHeights[3] <= cornerHeights[1] - 4) + doubleCorner = 1; + else if (cornerHeights[2] == highest && cornerHeights[0] <= cornerHeights[2] - 4) + doubleCorner = 2; + else if (cornerHeights[3] == highest && cornerHeights[1] <= cornerHeights[3] - 4) + doubleCorner = 3; + } else { + if (mapElement->base_height < highest - 2) { + mapElement->base_height = mapElement->clearance_height = highest - 2; + raisedLand = 1; + } + } + } + + if (doubleCorner != -1) { + mapElement->properties.surface.slope |= 16; + switch (doubleCorner) { + case 0: + mapElement->properties.surface.slope |= 2 | 4 | 8; + break; + case 1: + mapElement->properties.surface.slope |= 1 | 2 | 4; + break; + case 2: + mapElement->properties.surface.slope |= 1 | 2 | 8; + break; + case 3: + mapElement->properties.surface.slope |= 1 | 4 | 8; + break; + } + } else { + // Corners + if ( + map_get_corner_height(x + 1, y + 1, 3) > mapElement->base_height || + map_get_corner_height(x + 1, y + 0, 1) > mapElement->base_height || + map_get_corner_height(x + 0, y + 1, 2) > mapElement->base_height + ) + mapElement->properties.surface.slope |= 1; + + if ( + map_get_corner_height(x - 1, y + 1, 2) > mapElement->base_height || + map_get_corner_height(x - 1, y + 0, 0) > mapElement->base_height || + map_get_corner_height(x + 0, y + 1, 3) > mapElement->base_height + ) + mapElement->properties.surface.slope |= 8; + + if ( + map_get_corner_height(x + 1, y - 1, 1) > mapElement->base_height || + map_get_corner_height(x + 1, y + 0, 3) > mapElement->base_height || + map_get_corner_height(x + 0, y - 1, 0) > mapElement->base_height + ) + mapElement->properties.surface.slope |= 2; + + if ( + map_get_corner_height(x - 1, y - 1, 0) > mapElement->base_height || + map_get_corner_height(x - 1, y + 0, 2) > mapElement->base_height || + map_get_corner_height(x + 0, y - 1, 1) > mapElement->base_height + ) + mapElement->properties.surface.slope |= 4; + + // Raise + if (mapElement->properties.surface.slope == (1 | 2 | 4 | 8)) { + mapElement->properties.surface.slope &= ~0x1F; + mapElement->base_height = mapElement->clearance_height += 2; + } + } + } + } + + return raisedLand; +} \ No newline at end of file diff --git a/src/world/map_helpers.h b/src/world/map_helpers.h new file mode 100644 index 0000000000..423bb4c25e --- /dev/null +++ b/src/world/map_helpers.h @@ -0,0 +1,26 @@ +/***************************************************************************** + * Copyright (c) 2014 Ted John + * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. + * + * This file is part of 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. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#ifndef _MAP_HELPERS_H_ +#define _MAP_HELPERS_H_ + +int map_smooth(int l, int t, int r, int b); + +#endif \ No newline at end of file diff --git a/src/world/mapgen.c b/src/world/mapgen.c new file mode 100644 index 0000000000..8a27a6fa0b --- /dev/null +++ b/src/world/mapgen.c @@ -0,0 +1,565 @@ +/***************************************************************************** + * Copyright (c) 2014 Ted John + * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. + * + * This file is part of 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. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#ifndef _USE_MATH_DEFINES + #define _USE_MATH_DEFINES +#endif +#include +#include "../addresses.h" +#include "../object.h" +#include "map.h" +#include "map_helpers.h" +#include "mapgen.h" +#include "scenery.h" + +#pragma region Random objects + +const char *GrassTrees[] = { + // Dark + "TCF ", // Caucasian Fir Tree + "TRF ", // Red Fir Tree + "TRF2 ", // Red Fir Tree + "TSP ", // Scots Pine Tree + "TMZP ", // Montezuma Pine Tree + "TAP ", // Aleppo Pine Tree + "TCRP ", // Corsican Pine Tree + "TBP ", // Black Poplar Tree + + // Light + "TCL ", // Cedar of Lebanon Tree + "TEL ", // European Larch Tree +}; + +// Trees to be placed in proximity to water +const char *GrassWaterTrees[] = { + "TWW " // Weeping Willow Tree +}; + +const char *DesertTrees[] = { + "TMP ", // Monkey-Puzzle Tree + "THL ", // Honey Locust Tree + "TH1 ", // Canary Palm Tree + "TH2 ", // Palm Tree + "TPM ", // Palm Tree + "TROPT1 ", // Tree + "TBC ", // Cactus + "TSC ", // Cactus +}; + +const char *SnowTrees[] = { + "TCFS ", // Snow-covered Caucasian Fir Tree + "TNSS ", // Snow-covered Norway Spruce Tree + "TRF3 ", // Snow-covered Red Fir Tree + "TRFS ", // Snow-covered Red Fir Tree +}; + +#pragma endregion + +static void mapgen_place_trees(); +static void mapgen_set_water_level(int height); +static void mapgen_blob(int cx, int cy, int size, int height); +static void mapgen_smooth_height(int iterations); +static void mapgen_set_height(); + +static int _heightSize; +static uint8 *_height; + +#define HEIGHT(x, y) (_height[(y) * _heightSize + (x)]) + +const uint8 BaseTerrain[] = { TERRAIN_GRASS, TERRAIN_SAND, TERRAIN_SAND_LIGHT, TERRAIN_ICE }; + +void mapgen_generate_blank(mapgen_settings *settings) +{ + int x, y; + rct_map_element *mapElement; + + map_init(settings->mapSize); + for (y = 1; y < settings->mapSize - 1; y++) { + for (x = 1; x < settings->mapSize - 1; x++) { + mapElement = map_get_surface_element_at(x, y); + map_element_set_terrain(mapElement, settings->floor); + map_element_set_terrain_edge(mapElement, settings->wall); + mapElement->base_height = settings->height; + mapElement->clearance_height = settings->height; + } + } + + mapgen_set_water_level(settings->waterLevel); +} + +void mapgen_generate(mapgen_settings *settings) +{ + int i, x, y, mapSize, floorTexture, wallTexture; + rct_map_element *mapElement; + + srand((unsigned int)time(NULL)); + + mapSize = settings->mapSize; + floorTexture = settings->floor; + wallTexture = settings->wall; + + if (floorTexture == -1) + floorTexture = BaseTerrain[rand() % countof(BaseTerrain)]; + if (wallTexture == -1) { + wallTexture = TERRAIN_EDGE_ROCK; + if (floorTexture == TERRAIN_ICE) + wallTexture = TERRAIN_EDGE_ICE; + } + + map_init(mapSize); + for (y = 1; y < mapSize - 1; y++) { + for (x = 1; x < mapSize - 1; x++) { + mapElement = map_get_surface_element_at(x, y); + map_element_set_terrain(mapElement, floorTexture); + map_element_set_terrain_edge(mapElement, wallTexture); + mapElement->base_height = settings->height; + mapElement->clearance_height = settings->height; + } + } + + _heightSize = mapSize * 2; + _height = (uint8*)malloc((mapSize * 2) * (mapSize * 2) * sizeof(uint8)); + for (y = 0; y < mapSize * 2; y++) { + for (x = 0; x < mapSize * 2; x++) { + double a = abs(x - (mapSize)) / (double)(mapSize); + double b = abs(y - (mapSize)) / (double)(mapSize); + + a *= 2; + b *= 2; + double c = 1 - ((a*a + b*b) / 2); + c = clamp(0, c, 1); + + int h = 1 + rand() % ((int)(c * 22) + 1); + h = 1; + + HEIGHT(x, y) = h; + } + } + + int border = 2 + (rand() % 24); + for (i = 0; i < 128; i++) { + int radius = 4 + (rand() % 32); + mapgen_blob( + border + (rand() % (_heightSize - (border * 2))), + border + (rand() % (_heightSize - (border * 2))), + (int)(M_PI * radius * radius), + 1 + (rand() % 12) + ); + } + mapgen_smooth_height(2); + mapgen_set_height(); + free(_height); + + while (map_smooth(1, 1, mapSize - 1, mapSize - 1)) { } + mapgen_set_water_level(6 + (rand() % 4) * 2); + + if (settings->trees != 0) + mapgen_place_trees(); +} + +static void mapgen_place_tree(int type, int x, int y) +{ + uint8 baseHeight; + rct_map_element *mapElement, *surfaceElement, *nextFreeElement; + + nextFreeElement = RCT2_GLOBAL(0x0140E9A4, rct_map_element*); + + // Get first element of the tile + mapElement = TILE_MAP_ELEMENT_POINTER(y * 256 + x); + + // Find the last element + while (!(mapElement->flags & MAP_ELEMENT_FLAG_LAST_TILE)) { + if ((mapElement->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_SURFACE) + surfaceElement = mapElement; + mapElement++; + } + + // Shift elements for a free space + memmove(mapElement + 2, mapElement + 1, (int)nextFreeElement - (int)mapElement); + + baseHeight = map_element_height(x * 32 + 16, y * 32 + 16) / 8; + + mapElement->flags &= ~MAP_ELEMENT_FLAG_LAST_TILE; + mapElement++; + + mapElement->type = MAP_ELEMENT_TYPE_SCENERY | (rand() % 3); + mapElement->flags = MAP_ELEMENT_FLAG_LAST_TILE | (1 | 2 | 4 | 8); + mapElement->base_height = baseHeight; + mapElement->clearance_height = baseHeight + 15; + mapElement->properties.scenery.type = type; + mapElement->properties.scenery.age = 0; + mapElement->properties.scenery.colour_1 = 26; + mapElement->properties.scenery.colour_2 = 18; + + map_update_tile_pointers(); +} + +static void mapgen_place_trees() +{ + int x, y, mapSize, i, j, rindex, type; + rct_map_element *mapElement; + + int numGrassTreeIds = 0, numDesertTreeIds = 0, numSnowTreeIds = 0; + int *grassTreeIds = (int*)malloc(countof(GrassTrees) * sizeof(int)); + int *desertTreeIds = (int*)malloc(countof(DesertTrees) * sizeof(int)); + int *snowTreeIds = (int*)malloc(countof(SnowTrees) * sizeof(int)); + + for (i = 0; i < object_entry_group_counts[OBJECT_TYPE_SMALL_SCENERY]; i++) { + rct_scenery_entry *sceneryEntry = g_smallSceneryEntries[i]; + rct_object_entry_extended *entry = &object_entry_groups[OBJECT_TYPE_SMALL_SCENERY].entries[i]; + + if (sceneryEntry == (rct_scenery_entry*)0xFFFFFFFF || sceneryEntry == NULL) + continue; + + for (j = 0; j < countof(GrassTrees); j++) + if (strncmp(GrassTrees[j], entry->name, 8) == 0) + break; + if (j != countof(GrassTrees)) { + grassTreeIds[numGrassTreeIds++] = i; + continue; + } + + for (j = 0; j < countof(DesertTrees); j++) + if (strncmp(DesertTrees[j], entry->name, 8) == 0) + break; + if (j != countof(DesertTrees)) { + desertTreeIds[numDesertTreeIds++] = i; + continue; + } + + for (j = 0; j < countof(SnowTrees); j++) + if (strncmp(SnowTrees[j], entry->name, 8) == 0) + break; + if (j != countof(SnowTrees)) { + snowTreeIds[numSnowTreeIds++] = i; + continue; + } + } + + mapSize = RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, sint16); + + int availablePositionsCount = 0; + struct { int x; int y; } tmp, *pos, *availablePositions; + availablePositions = malloc(256 * 256 * sizeof(tmp)); + + // Create list of available tiles + for (y = 1; y < mapSize - 1; y++) { + for (x = 1; x < mapSize - 1; x++) { + mapElement = map_get_surface_element_at(x, y); + + // Exclude water tiles + if ((mapElement->properties.surface.terrain & 0x1F) != 0) + continue; + + pos = &availablePositions[availablePositionsCount++]; + pos->x = x; + pos->y = y; + } + } + + // Shuffle list + for (i = 0; i < availablePositionsCount; i++) { + rindex = rand() % availablePositionsCount; + if (rindex == i) + continue; + + tmp = availablePositions[i]; + availablePositions[i] = availablePositions[rindex]; + availablePositions[rindex] = tmp; + } + + // Place trees + mapSize = RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, sint16); + for (i = 0; i < min(availablePositionsCount, 2048 + (rand() % 10000)); i++) { + pos = &availablePositions[i]; + + type = -1; + mapElement = map_get_surface_element_at(pos->x, pos->y); + switch (map_element_get_terrain(mapElement)) { + case TERRAIN_GRASS: + case TERRAIN_DIRT: + case TERRAIN_GRASS_CLUMPS: + if (numGrassTreeIds == 0) + break; + + type = grassTreeIds[rand() % numGrassTreeIds]; + break; + + case TERRAIN_SAND: + case TERRAIN_SAND_DARK: + case TERRAIN_SAND_LIGHT: + if (numDesertTreeIds == 0) + break; + + if (rand() % 4 == 0) + type = desertTreeIds[rand() % numDesertTreeIds]; + break; + + case TERRAIN_ICE: + if (numSnowTreeIds == 0) + break; + + type = snowTreeIds[rand() % numSnowTreeIds]; + break; + } + + if (type != -1) + mapgen_place_tree(type, pos->x, pos->y); + } + + free(availablePositions); + free(grassTreeIds); + free(desertTreeIds); + free(snowTreeIds); +} + +static void mapgen_set_water_level(int waterLevel) +{ + int x, y, mapSize; + rct_map_element *mapElement; + + mapSize = RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, sint16); + + for (y = 1; y < mapSize - 1; y++) { + for (x = 1; x < mapSize - 1; x++) { + mapElement = map_get_surface_element_at(x, y); + if (mapElement->base_height < waterLevel) + mapElement->properties.surface.terrain |= (waterLevel / 2); + } + } +} + +static void mapgen_blob_fill(int height) +{ + // For each square find out whether it is landlocked by 255 and then fill it if it is + int left = 0, + top = 0, + right = _heightSize - 1, + bottom = _heightSize - 1; + + uint8 *landX = (uint8*)malloc(_heightSize * _heightSize * sizeof(uint8)); + int firstLand, lastLand; + + // Check each row and see if each tile is between first land x and last land x + for (int y = top; y <= bottom; y++) { + // Calculate first land + firstLand = -1; + for (int xx = left; xx <= right; xx++) { + if (HEIGHT(xx, y) == 255) { + firstLand = xx; + break; + } + } + + lastLand = -1; + if (firstLand >= 0) { + // Calculate last land + for (int xx = right; xx >= left; xx--) { + if (HEIGHT(xx, y) == 255) { + lastLand = xx; + break; + } + } + } else { + // No land on this row + continue; + } + + for (int x = left; x <= right; x++) + if (x >= firstLand && x <= lastLand) + landX[x, y] = 1; + } + + // Do the same for Y + for (int x = left; x <= right; x++) { + // Calculate first land + firstLand = -1; + for (int yy = top; yy <= bottom; yy++) { + if (HEIGHT(x, yy) == 255) { + firstLand = yy; + break; + } + } + + lastLand = -1; + if (firstLand >= 0) { + // Calculate last land + for (int yy = bottom; yy >= top; yy--) { + if (HEIGHT(x, yy) == 255) { + lastLand = yy; + break; + } + } + } else { + // No land on this row + continue; + } + + for (int y = top; y <= bottom; y++) { + if (y >= firstLand && y <= lastLand && landX[x, y]) { + // Not only do we know its landlocked to both x and y + // we can change the land too + HEIGHT(x, y) = 255; + } + } + } + + // Replace all the 255 with the actual land height + for (int x = left; x <= right; x++) + for (int y = top; y <= bottom; y++) + if (HEIGHT(x, y) == 255) + HEIGHT(x, y) = height; + + free(landX); +} + +static void mapgen_blob(int cx, int cy, int size, int height) +{ + int x, y, currentSize, direction; + + x = cx; + y = cy; + currentSize = 1; + direction = 0; + HEIGHT(y, x) = 255; + + while (currentSize < size) { + if (rand() % 2 == 0) { + HEIGHT(x, y) = 255; + currentSize++; + } + + switch (direction) { + case 0: + if (y == 0) { + currentSize = size; + break; + } + + y--; + if (HEIGHT(x + 1, y) != 255) + direction = 1; + else if (HEIGHT(x, y - 1) != 255) + direction = 0; + else if (HEIGHT(x - 1, y) != 255) + direction = 3; + break; + case 1: + if (x == _heightSize - 1) { + currentSize = size; + break; + } + + x++; + if (HEIGHT(x, y + 1) != 255) + direction = 2; + else if (HEIGHT(x + 1, y) != 255) + direction = 1; + else if (HEIGHT(x, y - 1) != 255) + direction = 0; + break; + case 2: + if (y == _heightSize - 1) { + currentSize = size; + break; + } + + y++; + if (HEIGHT(x - 1, y) != 255) + direction = 3; + else if (HEIGHT(x, y + 1) != 255) + direction = 2; + else if (HEIGHT(x + 1, y) != 255) + direction = 1; + break; + case 3: + if (x == 0) { + currentSize = size; + break; + } + + x--; + if (HEIGHT(x, y - 1) != 255) + direction = 0; + else if (HEIGHT(x - 1, y) != 255) + direction = 3; + else if (HEIGHT(x, y + 1) != 255) + direction = 2; + break; + } + } + + mapgen_blob_fill(height); +} + +static void mapgen_smooth_height(int iterations) +{ + int i, x, y, xx, yy, avg; + int arraySize = _heightSize * _heightSize * sizeof(uint8); + uint8 *copyHeight = malloc(arraySize); + memcpy(copyHeight, _height, arraySize); + + for (i = 0; i < iterations; i++) { + for (y = 1; y < _heightSize - 1; y++) { + for (x = 1; x < _heightSize - 1; x++) { + avg = 0; + for (yy = -1; yy <= 1; yy++) + for (xx = -1; xx <= 1; xx++) + avg += copyHeight[(y + yy) * _heightSize + (x + xx)]; + avg /= 9; + HEIGHT(x, y) = avg; + } + } + } +} + +static void mapgen_set_height() +{ + int x, y, heightX, heightY, mapSize; + rct_map_element *mapElement; + + mapSize = _heightSize / 2; + for (y = 1; y < mapSize - 1; y++) { + for (x = 1; x < mapSize - 1; x++) { + heightX = x * 2; + heightY = y * 2; + + uint8 q00 = HEIGHT(heightX + 0, heightY + 0); + uint8 q01 = HEIGHT(heightX + 0, heightY + 1); + uint8 q10 = HEIGHT(heightX + 1, heightY + 0); + uint8 q11 = HEIGHT(heightX + 1, heightY + 1); + + uint8 baseHeight = (q00 + q01 + q10 + q11) / 4; + + mapElement = map_get_surface_element_at(x, y); + mapElement->base_height = baseHeight * 2; + mapElement->clearance_height = mapElement->base_height; + + if (q00 > baseHeight) + mapElement->properties.surface.slope |= 4; + if (q01 > baseHeight) + mapElement->properties.surface.slope |= 8; + if (q10 > baseHeight) + mapElement->properties.surface.slope |= 2; + if (q11 > baseHeight) + mapElement->properties.surface.slope |= 1; + } + } +} \ No newline at end of file diff --git a/src/world/mapgen.h b/src/world/mapgen.h new file mode 100644 index 0000000000..d6771a48cd --- /dev/null +++ b/src/world/mapgen.h @@ -0,0 +1,39 @@ +/***************************************************************************** + * Copyright (c) 2014 Ted John + * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. + * + * This file is part of 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. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#ifndef _MAPGEN_H_ +#define _MAPGEN_H_ + +typedef struct { + // Base + int mapSize; + int height; + int waterLevel; + int floor; + int wall; + + // Features (e.g. tree, rivers, lakes etc.) + int trees; +} mapgen_settings; + +void mapgen_generate_blank(mapgen_settings *settings); +void mapgen_generate(mapgen_settings *settings); + +#endif \ No newline at end of file