1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-22 15:23:01 +01:00

merge in random map generator

This commit is contained in:
IntelOrca
2015-02-10 20:11:59 +00:00
28 changed files with 2775 additions and 1598 deletions

View File

@@ -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 :???

View File

@@ -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 :???

View File

@@ -73,7 +73,6 @@
<ClCompile Include="..\src\scenario.c" />
<ClCompile Include="..\src\scenario_list.c" />
<ClCompile Include="..\src\title.c" />
<ClCompile Include="..\src\toolbar.c" />
<ClCompile Include="..\src\tutorial.c" />
<ClCompile Include="..\src\util\sawyercoding.c" />
<ClCompile Include="..\src\util\util.c" />
@@ -89,16 +88,15 @@
<ClCompile Include="..\src\windows\editor_objective_options.c" />
<ClCompile Include="..\src\windows\editor_object_selection.c" />
<ClCompile Include="..\src\windows\editor_scenario_options.c" />
<ClCompile Include="..\src\windows\editor_top_toolbar.c" />
<ClCompile Include="..\src\windows\error.c" />
<ClCompile Include="..\src\windows\finances.c" />
<ClCompile Include="..\src\windows\footpath.c" />
<ClCompile Include="..\src\windows\game_bottom_toolbar.c" />
<ClCompile Include="..\src\windows\game_top_toolbar.c" />
<ClCompile Include="..\src\windows\guest_list.c" />
<ClCompile Include="..\src\windows\land.c" />
<ClCompile Include="..\src\windows\main.c" />
<ClCompile Include="..\src\windows\map.c" />
<ClCompile Include="..\src\windows\mapgen.c" />
<ClCompile Include="..\src\windows\map_tooltip.c" />
<ClCompile Include="..\src\windows\music_credits.c" />
<ClCompile Include="..\src\windows\news.c" />
@@ -126,6 +124,7 @@
<ClCompile Include="..\src\windows\title_menu.c" />
<ClCompile Include="..\src\windows\title_scenarioselect.c" />
<ClCompile Include="..\src\windows\tooltip.c" />
<ClCompile Include="..\src\windows\top_toolbar.c" />
<ClCompile Include="..\src\windows\track_list.c" />
<ClCompile Include="..\src\windows\track_manage.c" />
<ClCompile Include="..\src\windows\track_place.c" />
@@ -136,6 +135,8 @@
<ClCompile Include="..\src\world\footpath.c" />
<ClCompile Include="..\src\world\fountain.c" />
<ClCompile Include="..\src\world\map.c" />
<ClCompile Include="..\src\world\mapgen.c" />
<ClCompile Include="..\src\world\map_helpers.c" />
<ClCompile Include="..\src\world\park.c" />
<ClCompile Include="..\src\world\sprite.c" />
</ItemGroup>
@@ -189,7 +190,6 @@
<ClInclude Include="..\src\scenario.h" />
<ClInclude Include="..\src\sprites.h" />
<ClInclude Include="..\src\title.h" />
<ClInclude Include="..\src\toolbar.h" />
<ClInclude Include="..\src\tutorial.h" />
<ClInclude Include="..\src\util\sawyercoding.h" />
<ClInclude Include="..\src\util\util.h" />
@@ -201,6 +201,8 @@
<ClInclude Include="..\src\world\climate.h" />
<ClInclude Include="..\src\world\footpath.h" />
<ClInclude Include="..\src\world\map.h" />
<ClInclude Include="..\src\world\mapgen.h" />
<ClInclude Include="..\src\world\map_helpers.h" />
<ClInclude Include="..\src\world\park.h" />
<ClInclude Include="..\src\world\scenery.h" />
<ClInclude Include="..\src\world\sprite.h" />

View File

@@ -120,9 +120,6 @@
<ClCompile Include="..\src\windows\game_bottom_toolbar.c">
<Filter>Source\Windows</Filter>
</ClCompile>
<ClCompile Include="..\src\windows\game_top_toolbar.c">
<Filter>Source\Windows</Filter>
</ClCompile>
<ClCompile Include="..\src\windows\guest_list.c">
<Filter>Source\Windows</Filter>
</ClCompile>
@@ -330,8 +327,6 @@
<ClCompile Include="..\src\drawing\rain.c">
<Filter>Source\Drawing</Filter>
</ClCompile>
<ClCompile Include="..\lib\lodepng\lodepng.c" />
<ClCompile Include="..\lib\lodepng\lodepng.c" />
<ClCompile Include="..\src\cmdline.c">
<Filter>Source</Filter>
</ClCompile>
@@ -350,14 +345,14 @@
<ClCompile Include="..\src\windows\staff_fire_prompt.c">
<Filter>Source\Windows</Filter>
</ClCompile>
<ClCompile Include="..\lib\libspeex\resample.c;..\lib\lodepng\lodepng.c" />
<ClCompile Include="..\lib\lodepng\lodepng.c" />
<ClCompile Include="..\src\windows\viewport.c">
<Filter>Source\Windows</Filter>
</ClCompile>
<ClCompile Include="..\src\windows\text_input.c">
<Filter>Source\Windows</Filter>
</ClCompile>
<ClCompile Include="..\lib\libspeex\resample.c;..\lib\lodepng\lodepng.c" />
<ClCompile Include="..\lib\lodepng\lodepng.c" />
<ClCompile Include="..\src\windows\map_tooltip.c">
<Filter>Source\Windows</Filter>
</ClCompile>
@@ -392,9 +387,6 @@
<Filter>Source</Filter>
</ClCompile>
<ClCompile Include="..\lib\libspeex\resample.c;..\lib\lodepng\lodepng.c" />
<ClCompile Include="..\src\toolbar.c">
<Filter>Source</Filter>
</ClCompile>
<ClCompile Include="..\src\windows\editor_bottom_toolbar.c">
<Filter>Source\Windows</Filter>
</ClCompile>
@@ -404,9 +396,6 @@
<ClCompile Include="..\src\windows\editor_object_selection.c">
<Filter>Source\Windows</Filter>
</ClCompile>
<ClCompile Include="..\src\windows\editor_top_toolbar.c">
<Filter>Source\Windows</Filter>
</ClCompile>
<ClCompile Include="..\lib\libspeex\resample.c;..\lib\lodepng\lodepng.c" />
<ClCompile Include="..\src\localisation\user.c">
<Filter>Source\Localisation</Filter>
@@ -422,7 +411,19 @@
<Filter>Source\Windows</Filter>
</ClCompile>
<ClCompile Include="..\lib\lodepng\lodepng.c" />
<ClCompile Include="..\src\ride\track_data.c">
<ClCompile Include="..\src\world\map_helpers.c">
<Filter>Source\World</Filter>
</ClCompile>
<ClCompile Include="..\src\world\mapgen.c">
<Filter>Source\World</Filter>
</ClCompile>
<ClCompile Include="..\src\windows\mapgen.c">
<Filter>Source\Windows</Filter>
</ClCompile>
<ClCompile Include="..\src\windows\top_toolbar.c">
<Filter>Source\Windows</Filter>
</ClCompile>
<ClCompile Include="..\src\ride\track_data.c">
<Filter>Source\Ride</Filter>
</ClCompile>
</ItemGroup>
@@ -610,12 +611,15 @@
<ClInclude Include="..\src\diagnostic.h">
<Filter>Source</Filter>
</ClInclude>
<ClInclude Include="..\src\toolbar.h">
<Filter>Source</Filter>
</ClInclude>
<ClInclude Include="..\src\rct1.h">
<Filter>Source</Filter>
</ClInclude>
<ClInclude Include="..\src\world\mapgen.h">
<Filter>Source\World</Filter>
</ClInclude>
<ClInclude Include="..\src\world\map_helpers.h">
<Filter>Source\World</Filter>
</ClInclude>
<ClInclude Include="..\src\ride\track_data.h">
<Filter>Source\Ride</Filter>
</ClInclude>

View File

@@ -7,14 +7,10 @@
<LocalDebuggerCommand>$(TargetDir)\openrct2.exe</LocalDebuggerCommand>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
<LocalDebuggerCommandArguments>
</LocalDebuggerCommandArguments>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LocalDebuggerCommand>$(TargetDir)\openrct2.exe</LocalDebuggerCommand>
<LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerCommandArguments>
</LocalDebuggerCommandArguments>
</PropertyGroup>
</Project>

View File

@@ -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();

View File

@@ -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);
}

View File

@@ -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;
}
}
}

View File

@@ -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();

View File

@@ -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;
}

View File

@@ -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));

View File

@@ -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);
}
}

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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 <http://www.gnu.org/licenses/>.
*****************************************************************************/
#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();
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*****************************************************************************/
#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

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*****************************************************************************/
#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);
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*****************************************************************************/
#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;
}
}

646
src/windows/mapgen.c Normal file
View File

@@ -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 <http://www.gnu.org/licenses/>.
*****************************************************************************/
#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

992
src/windows/top_toolbar.c Normal file
View File

@@ -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 <http://www.gnu.org/licenses/>.
*****************************************************************************/
#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();
}
}

View File

@@ -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);

View File

@@ -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);

290
src/world/map_helpers.c Normal file
View File

@@ -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 <http://www.gnu.org/licenses/>.
*****************************************************************************/
#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;
}

26
src/world/map_helpers.h Normal file
View File

@@ -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 <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef _MAP_HELPERS_H_
#define _MAP_HELPERS_H_
int map_smooth(int l, int t, int r, int b);
#endif

565
src/world/mapgen.c Normal file
View File

@@ -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 <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef _USE_MATH_DEFINES
#define _USE_MATH_DEFINES
#endif
#include <math.h>
#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;
}
}
}

39
src/world/mapgen.h Normal file
View File

@@ -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 <http://www.gnu.org/licenses/>.
*****************************************************************************/
#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