From 1246a14fe3df9d86adf54e1126d8faaa1885cc83 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Mon, 28 Apr 2014 17:35:12 +0100 Subject: [PATCH 01/37] add footpath window --- projects/openrct2.vcxproj | 1 + projects/openrct2.vcxproj.filters | 3 + src/gfx.c | 18 ++- src/gfx.h | 3 + src/strings.h | 17 +++ src/widget.c | 68 +++++++++- src/widget.h | 2 +- src/window.h | 1 + src/window_footpath.c | 210 ++++++++++++++++++++++++++++++ src/window_game_top_toolbar.c | 6 +- 10 files changed, 323 insertions(+), 6 deletions(-) create mode 100644 src/window_footpath.c diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj index 6cff1ca042..420cec74d5 100644 --- a/projects/openrct2.vcxproj +++ b/projects/openrct2.vcxproj @@ -86,6 +86,7 @@ + diff --git a/projects/openrct2.vcxproj.filters b/projects/openrct2.vcxproj.filters index ae7245d7f1..f5d490b809 100644 --- a/projects/openrct2.vcxproj.filters +++ b/projects/openrct2.vcxproj.filters @@ -254,6 +254,9 @@ Windows + + Windows + diff --git a/src/gfx.c b/src/gfx.c index 8890e67b5d..9cebbf2674 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -27,6 +27,10 @@ #include "strings.h" #include "window.h" +// HACK These were originally passed back through registers +int gLastDrawStringX; +int gLastDrawStringY; + uint8 _screenDirtyBlocks[5120]; static void gfx_draw_dirty_blocks(int x, int y, int columns, int rows); @@ -486,5 +490,17 @@ void gfx_draw_string_left(rct_drawpixelinfo *dpi, int format, void *args, int co */ void gfx_draw_string(rct_drawpixelinfo *dpi, char *format, int colour, int x, int y) { - RCT2_CALLPROC_X(0x00682702, colour, 0, x, y, format, dpi, 0); + int eax, ebx, ecx, edx, esi, edi, ebp; + + eax = colour; + ebx = 0; + ecx = x; + edx = y; + esi = format; + edi = dpi; + ebp = 0; + RCT2_CALLFUNC_X(0x00682702, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + + gLastDrawStringX = ecx; + gLastDrawStringY = edx; } diff --git a/src/gfx.h b/src/gfx.h index 47ef36c70a..9af771d4f8 100644 --- a/src/gfx.h +++ b/src/gfx.h @@ -46,6 +46,9 @@ typedef struct { sint16 unused; // 0x0E } rct_g1_element; +extern int gLastDrawStringX; +extern int gLastDrawStringY; + void gfx_load_g1(); void gfx_clear(rct_drawpixelinfo *dpi, int colour); diff --git a/src/strings.h b/src/strings.h index 583bc4738e..7a3c5b247d 100644 --- a/src/strings.h +++ b/src/strings.h @@ -197,6 +197,17 @@ enum { STR_BUILD_FOOTPATH_TIP = 1173, + STR_FOOTPATHS = 1181, + STR_TYPE = 1182, + STR_DIRECTION = 1183, + STR_SLOPE = 1184, + STR_DIRECTION_TIP = 1185, + STR_SLOPE_DOWN_TIP = 1186, + STR_LEVEL_TIP = 1187, + STR_SLOPE_UP_TIP = 1188, + STR_CONSTRUCT_THE_SELECTED_FOOTPATH_SECTION_TIP = 1189, + STR_REMOVE_PREVIOUS_FOOTPATH_SECTION_TIP = 1190, + STR_CLOSED = 1194, STR_TEST_RUN = 1195, STR_OPEN = 1196, @@ -212,10 +223,16 @@ enum { STR_NUMERIC_UP = 1218, STR_NUMERIC_DOWN = 1219, + STR_QUEUE_LINE_PATH_TIP = 1423, + STR_FOOTPATH_TIP = 1424, + STR_FREE = 1430, STR_GUESTS = 1463, + STR_CONSTRUCT_FOOTPATH_ON_LAND_TIP = 1655, + STR_CONSTRUCT_BRIDGE_OR_TUNNEL_FOOTPATH_TIP = 1656, + STR_GUESTS_TIP = 1693, STR_STAFF_TIP = 1694, diff --git a/src/widget.c b/src/widget.c index cf4c44f959..cccfc1434d 100644 --- a/src/widget.c +++ b/src/widget.c @@ -33,6 +33,7 @@ static void widget_text_button(rct_drawpixelinfo *dpi, rct_window *w, int widget static void widget_text_unknown(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex); static void widget_text(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex); static void widget_text_inset(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex); +static void widget_groupbox_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex); static void widget_caption_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex); static void widget_closebox_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex); static void widget_scroll_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex); @@ -94,6 +95,10 @@ void widget_scroll_update_thumbs(rct_window *w, int widget_index) } } +/** + * + * rct2: 0x006EB2A8 + */ void widget_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex) { switch (w->widgets[widgetIndex].type) { @@ -134,7 +139,8 @@ void widget_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex) break; case WWT_18: break; - case WWT_19: + case WWT_GROUPBOX: + widget_groupbox_draw(dpi, w, widgetIndex); break; case WWT_CAPTION: widget_caption_draw(dpi, w, widgetIndex); @@ -500,6 +506,66 @@ static void widget_text_inset(rct_drawpixelinfo *dpi, rct_window *w, int widgetI widget_text(dpi, w, widgetIndex); } +/** + * + * rct2: 0x006EB535 + */ +static void widget_groupbox_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex) +{ + rct_widget* widget; + int l, t, r, b, textRight; + uint8 colour; + + // Get the widget + widget = &w->widgets[widgetIndex]; + + // Resolve the absolute ltrb + l = w->x + widget->left + 5; + t = w->y + widget->top; + r = w->x + widget->right; + b = w->y + widget->bottom; + textRight = l; + + // Text + if (widget->image != (uint32)-1) { + colour = w->colours[widget->colour] & 0x7F; + if (colour & 1) + colour |= 0x40; + gfx_draw_string_left(dpi, widget->image, 0x013CE952, colour, l, t); + textRight = gLastDrawStringX + 1; + } + + // Border + // Resolve the absolute ltrb + l = w->x + widget->left; + t = w->y + widget->top + 4; + r = w->x + widget->right; + b = w->y + widget->bottom; + + // Get the colour + colour = w->colours[widget->colour] & 0x7F; + + // Border left of text + gfx_fill_rect(dpi, l, t, l + 4, t, RCT2_ADDRESS(0x0141FC47, uint8)[colour * 8]); + gfx_fill_rect(dpi, l + 1, t + 1, l + 4, t + 1, RCT2_ADDRESS(0x0141FC4B, uint8)[colour * 8]); + + // Border right of text + gfx_fill_rect(dpi, textRight, t, r - 1, t, RCT2_ADDRESS(0x0141FC47, uint8)[colour * 8]); + gfx_fill_rect(dpi, textRight, t + 1, r - 2, t + 1, RCT2_ADDRESS(0x0141FC4B, uint8)[colour * 8]); + + // Border right + gfx_fill_rect(dpi, r - 1, t + 1, r - 1, b - 1, RCT2_ADDRESS(0x0141FC47, uint8)[colour * 8]); + gfx_fill_rect(dpi, r, t, r, b, RCT2_ADDRESS(0x0141FC4B, uint8)[colour * 8]); + + // Border bottom + gfx_fill_rect(dpi, l, b - 1, r - 2, b - 1, RCT2_ADDRESS(0x0141FC47, uint8)[colour * 8]); + gfx_fill_rect(dpi, l, b, r - 1, b, RCT2_ADDRESS(0x0141FC4B, uint8)[colour * 8]); + + // Border left + gfx_fill_rect(dpi, l, t + 1, l, b - 2, RCT2_ADDRESS(0x0141FC47, uint8)[colour * 8]); + gfx_fill_rect(dpi, l + 1, t + 2, l + 1, b - 2, RCT2_ADDRESS(0x0141FC4B, uint8)[colour * 8]); +} + /** * * rct2: 0x006EB2F9 diff --git a/src/widget.h b/src/widget.h index 96ac2e6d68..ea4eccbf11 100644 --- a/src/widget.h +++ b/src/widget.h @@ -43,7 +43,7 @@ typedef enum { WWT_DROPDOWN = 16, WWT_VIEWPORT = 17, WWT_18, - WWT_19, + WWT_GROUPBOX = 19, WWT_CAPTION = 20, WWT_CLOSEBOX = 21, WWT_SCROLL = 22, diff --git a/src/window.h b/src/window.h index 41ec37d2e7..62f2bcf74d 100644 --- a/src/window.h +++ b/src/window.h @@ -324,6 +324,7 @@ void window_main_open(); void window_game_top_toolbar_open(); void window_game_bottom_toolbar_open(); void window_about_open(); +void window_footpath_open(); void window_title_menu_open(); void window_title_exit_open(); void window_title_logo_open(); diff --git a/src/window_footpath.c b/src/window_footpath.c new file mode 100644 index 0000000000..e6c01fae36 --- /dev/null +++ b/src/window_footpath.c @@ -0,0 +1,210 @@ +/***************************************************************************** + * Copyright (c) 2014 Ted John + * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. + * + * This file is part of OpenRCT2. + * + * OpenRCT2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#include +#include "addresses.h" +#include "strings.h" +#include "sprites.h" +#include "viewport.h" +#include "widget.h" +#include "window.h" + +static enum WINDOW_FOOTPATH_WIDGET_IDX { + WIDX_BACKGROUND, + WIDX_TITLE, + WIDX_CLOSE, + + WIDX_TYPE_GROUP, + WIDX_FOOTPATH_TYPE, + WIDX_QUEUELINE_TYPE, + + WIDX_DIRECTION_GROUP, + WIDX_DIRECTION_NW, + WIDX_DIRECTION_NE, + WIDX_DIRECTION_SW, + WIDX_DIRECTION_SE, + + WIDX_SLOPE_GROUP, + WIDX_SLOPEDOWN, + WIDX_LEVEL, + WIDX_SLOPEUP, + WIDX_CONSTRUCT, + WIDX_REMOVE, + + WIDX_MODE_GROUP, + WIDX_CONSTRUCT_ON_LAND, + WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL, +}; + +static rct_widget window_footpath_widgets[] = { + { WWT_FRAME, 0, 0, 105, 0, 380, 0x0FFFFFFFF, STR_NONE }, + { WWT_CAPTION, 0, 1, 104, 1, 14, STR_FOOTPATHS, STR_WINDOW_TITLE_TIP }, + { WWT_CLOSEBOX, 0, 93, 103, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, + + // Type group + { WWT_GROUPBOX, 0, 3, 102, 17, 71, STR_TYPE, STR_NONE }, + { WWT_FLATBTN, 1, 6, 52, 30, 65, 0xFFFFFFFF, STR_FOOTPATH_TIP }, + { WWT_FLATBTN, 1, 53, 99, 30, 65, 0xFFFFFFFF, STR_QUEUE_LINE_PATH_TIP }, + + // Direction group + { WWT_GROUPBOX, 0, 3, 102, 75, 151, STR_DIRECTION, STR_NONE }, + { WWT_FLATBTN, 1, 53, 97, 87, 115, 5635, STR_DIRECTION_TIP }, + { WWT_FLATBTN, 1, 53, 97, 116, 144, 5636, STR_DIRECTION_TIP }, + { WWT_FLATBTN, 1, 8, 52, 116, 144, 5637, STR_DIRECTION_TIP }, + { WWT_FLATBTN, 1, 8, 52, 87, 115, 5638, STR_DIRECTION_TIP }, + + // Slope group + { WWT_GROUPBOX, 0, 3, 102, 155, 195, STR_SLOPE, STR_NONE }, + { WWT_FLATBTN, 1, 17, 40, 167, 190, 5145, STR_SLOPE_DOWN_TIP }, + { WWT_FLATBTN, 1, 41, 64, 167, 190, 5146, STR_LEVEL_TIP }, + { WWT_FLATBTN, 1, 65, 88, 167, 190, 5147, STR_SLOPE_UP_TIP }, + { WWT_FLATBTN, 1, 8, 97, 202, 291, 0xFFFFFFFF, STR_CONSTRUCT_THE_SELECTED_FOOTPATH_SECTION_TIP }, + { WWT_FLATBTN, 1, 30, 75, 295, 318, 5162, STR_REMOVE_PREVIOUS_FOOTPATH_SECTION_TIP }, + + // Mode group + { WWT_GROUPBOX, 0, 3, 102, 321, 374, 0xFFFFFFFF, STR_NONE }, + { WWT_FLATBTN, 1, 13, 48, 332, 367, 5639, STR_CONSTRUCT_FOOTPATH_ON_LAND_TIP }, + { WWT_FLATBTN, 1, 57, 92, 332, 367, 5640, STR_CONSTRUCT_BRIDGE_OR_TUNNEL_FOOTPATH_TIP }, + { WIDGETS_END }, +}; + +static void window_footpath_emptysub() { } +static void window_footpath_mouseup(); +static void window_footpath_paint(); + +static uint32 window_footpath_events[] = { + window_footpath_emptysub, + window_footpath_mouseup, + window_footpath_emptysub, + window_footpath_emptysub, + window_footpath_emptysub, + window_footpath_emptysub, + window_footpath_emptysub, + window_footpath_emptysub, + window_footpath_emptysub, + window_footpath_emptysub, + window_footpath_emptysub, + window_footpath_emptysub, + window_footpath_emptysub, + window_footpath_emptysub, + window_footpath_emptysub, + window_footpath_emptysub, + window_footpath_emptysub, + window_footpath_emptysub, + window_footpath_emptysub, + window_footpath_emptysub, + window_footpath_emptysub, + window_footpath_emptysub, + window_footpath_emptysub, + window_footpath_emptysub, + window_footpath_emptysub, + window_footpath_emptysub, + window_footpath_paint, + window_footpath_emptysub +}; + +/** + * + * rct2: 0x006A7C43 + */ +void window_footpath_open() +{ + rct_window* window; + + // Check if window is already open + window = window_bring_to_front_by_id(WC_FOOTPATH, 0); + if (window != NULL) + return; + + window = window_create( + 0, + 29, + 106, + 381, + window_footpath_events, + WC_FOOTPATH, + 0 + ); + window->widgets = window_footpath_widgets; + window->enabled_widgets = + (1 << WIDX_CLOSE) | + (1 << WIDX_FOOTPATH_TYPE) | + (1 << WIDX_QUEUELINE_TYPE) | + (1 << WIDX_DIRECTION_NW) | + (1 << WIDX_DIRECTION_NE) | + (1 << WIDX_DIRECTION_SW) | + (1 << WIDX_DIRECTION_SE) | + (1 << WIDX_SLOPEDOWN) | + (1 << WIDX_LEVEL) | + (1 << WIDX_SLOPEUP) | + (1 << WIDX_CONSTRUCT) | + (1 << WIDX_REMOVE) | + (1 << WIDX_CONSTRUCT_ON_LAND) | + (1 << WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL); + + window_init_scroll_widgets(window); + RCT2_CALLPROC_EBPSAFE(0x006EE65A); + show_gridlines(); + window->colours[0] = 24; + window->colours[1] = 24; + window->colours[2] = 24; + + RCT2_CALLPROC_EBPSAFE(0x006EE281); + RCT2_GLOBAL(0x00F3EF99, uint8) = 0; + RCT2_CALLPROC_X(0x006EE212, 17, 0, 0, 18, window, 0, 0); + RCT2_GLOBAL(0x009DE518, uint32) |= (1 << 6); + RCT2_GLOBAL(0x00F3EF9F, uint8) = 0; + RCT2_CALLPROC_EBPSAFE(0x006A855C); +} + +/** + * + * rct2: 0x006A7E92 + */ +static void window_footpath_mouseup() +{ + short widgetIndex; + rct_window *w; + + __asm mov widgetIndex, dx + __asm mov w, esi + + switch (widgetIndex) { + case WIDX_CLOSE: + window_close(w); + break; + } +} + +/** + * + * rct2: 0x006A7D8B + */ +static void window_footpath_paint() +{ + int x, y; + rct_window *w; + rct_drawpixelinfo *dpi; + + __asm mov w, esi + __asm mov dpi, edi + + window_draw_widgets(w, dpi); +} \ No newline at end of file diff --git a/src/window_game_top_toolbar.c b/src/window_game_top_toolbar.c index 959fe03d5b..a0527fba7c 100644 --- a/src/window_game_top_toolbar.c +++ b/src/window_game_top_toolbar.c @@ -212,11 +212,11 @@ static void window_game_top_toolbar_mouseup() RCT2_CALLPROC_EBPSAFE(0x006E0FEF); break; case WIDX_PATH: - if (window_find_by_id(20, 0) == NULL) { - RCT2_CALLPROC_EBPSAFE(0x00006A7C43); + if (window_find_by_id(WC_FOOTPATH, 0) == NULL) { + window_footpath_open(); } else { RCT2_CALLPROC_EBPSAFE(0x006EE281); - window_close_by_id(0x80 | 20, 0); + window_close_by_id(0x80 | WC_FOOTPATH, 0); } break; case WIDX_CONSTRUCT_RIDE: From 3d6bdd67adb6712515cb7eb2cae5e2fbd8d7e950 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Mon, 28 Apr 2014 18:37:38 +0100 Subject: [PATCH 02/37] add path window invalidate and paint --- src/strings.h | 3 ++ src/window_footpath.c | 106 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 106 insertions(+), 3 deletions(-) diff --git a/src/strings.h b/src/strings.h index 7a3c5b247d..71f9e53899 100644 --- a/src/strings.h +++ b/src/strings.h @@ -223,6 +223,9 @@ enum { STR_NUMERIC_UP = 1218, STR_NUMERIC_DOWN = 1219, + STR_BUILD_THIS = 1407, + STR_COST_LABEL = 1408, + STR_QUEUE_LINE_PATH_TIP = 1423, STR_FOOTPATH_TIP = 1424, diff --git a/src/window_footpath.c b/src/window_footpath.c index e6c01fae36..f262be7707 100644 --- a/src/window_footpath.c +++ b/src/window_footpath.c @@ -26,6 +26,14 @@ #include "widget.h" #include "window.h" +typedef struct { + uint16 pad_00; + uint32 image; // 0x02 + uint32 pad_06; + uint8 pad_0A; + uint8 pad_0B; +} rct_path_type; + static enum WINDOW_FOOTPATH_WIDGET_IDX { WIDX_BACKGROUND, WIDX_TITLE, @@ -86,11 +94,13 @@ static rct_widget window_footpath_widgets[] = { }; static void window_footpath_emptysub() { } +static void window_footpath_close(); static void window_footpath_mouseup(); +static void window_footpath_invalidate(); static void window_footpath_paint(); static uint32 window_footpath_events[] = { - window_footpath_emptysub, + window_footpath_close, window_footpath_mouseup, window_footpath_emptysub, window_footpath_emptysub, @@ -115,11 +125,13 @@ static uint32 window_footpath_events[] = { window_footpath_emptysub, window_footpath_emptysub, window_footpath_emptysub, - window_footpath_emptysub, + window_footpath_invalidate, window_footpath_paint, window_footpath_emptysub }; +sint32 _window_footpath_cost; + /** * * rct2: 0x006A7C43 @@ -174,6 +186,24 @@ void window_footpath_open() RCT2_CALLPROC_EBPSAFE(0x006A855C); } +/** + * + * rct2: 0x006A852F + */ +static void window_footpath_close() +{ + rct_window *w; + + __asm mov w, esi + + RCT2_CALLPROC_EBPSAFE(0x006A7831); + RCT2_CALLPROC_X(0x006CB70A, 0, 0, 0, 0, 0, 0, 0); + RCT2_CALLPROC_EBPSAFE(0x0068AB1B); + RCT2_GLOBAL(0x009DE58A, uint16) &= ~2; + window_invalidate_by_id(WC_TOP_TOOLBAR, 0); + hide_gridlines(); +} + /** * * rct2: 0x006A7E92 @@ -193,13 +223,50 @@ static void window_footpath_mouseup() } } +/** + * + * rct2: 0x006A7D1C + */ +static void window_footpath_invalidate() +{ + int selectedPath; + rct_path_type *pathType; + rct_window *w; + + __asm mov w, esi + + // Press / unpress footpath and queue type buttons + w->pressed_widgets &= ~(1 << WIDX_FOOTPATH_TYPE); + w->pressed_widgets &= ~(1 << WIDX_QUEUELINE_TYPE); + w->pressed_widgets |= RCT2_GLOBAL(0x00F3EFA2, uint8) == 0 ? + (1 << WIDX_FOOTPATH_TYPE) : + (1 << WIDX_QUEUELINE_TYPE); + + // Enable / disable construct button + window_footpath_widgets[WIDX_CONSTRUCT].type = RCT2_GLOBAL(0x00F3EF99, uint8) == 0 ? WWT_EMPTY : WWT_IMGBTN; + + // Set footpath and queue type button images + selectedPath = RCT2_GLOBAL(0x00F3EFA0, uint16); + pathType = RCT2_ADDRESS(0x009ADA14, rct_path_type*)[selectedPath]; + + int pathImage = 71 + pathType->image; + window_footpath_widgets[WIDX_FOOTPATH_TYPE].image = pathImage; + window_footpath_widgets[WIDX_QUEUELINE_TYPE].image = pathImage + 1; + window_footpath_widgets[WIDX_QUEUELINE_TYPE].type = WWT_FLATBTN; + + // Disable queue in if in editor + if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2) + window_footpath_widgets[WIDX_QUEUELINE_TYPE].type = WWT_EMPTY; +} + /** * * rct2: 0x006A7D8B */ static void window_footpath_paint() { - int x, y; + int x, y, image, selectedPath; + rct_path_type *pathType; rct_window *w; rct_drawpixelinfo *dpi; @@ -207,4 +274,37 @@ static void window_footpath_paint() __asm mov dpi, edi window_draw_widgets(w, dpi); + + if (!(w->disabled_widgets & (1 << WIDX_CONSTRUCT))) { + // Get construction image + image = (RCT2_GLOBAL(0x00F3EF90, uint8) + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)) % 4; + if (RCT2_GLOBAL(0x00F3EF91, uint8) == 2) + image += 4; + else if (RCT2_GLOBAL(0x00F3EF91, uint8) == 6) + image += 8; + image = RCT2_ADDRESS(0x0098D7E0, uint8)[image]; + + selectedPath = RCT2_GLOBAL(0x00F3EFA0, uint16); + pathType = RCT2_ADDRESS(0x009ADA14, rct_path_type*)[selectedPath]; + image += pathType->image; + if (RCT2_GLOBAL(0x00F3EFA2, uint8) != 0) + image += 51; + + // Draw construction image + x = w->x + (window_footpath_widgets[WIDX_CONSTRUCT].left + window_footpath_widgets[WIDX_CONSTRUCT].right) / 2; + y = w->y + window_footpath_widgets[WIDX_CONSTRUCT].bottom - 60; + gfx_draw_sprite(dpi, image, x, y); + + // Draw build this... label + x = w->x + (window_footpath_widgets[WIDX_CONSTRUCT].left + window_footpath_widgets[WIDX_CONSTRUCT].right) / 2; + y = w->y + window_footpath_widgets[WIDX_CONSTRUCT].bottom - 23; + gfx_draw_string_centred(dpi, STR_BUILD_THIS, x, y, 0, 0); + } + + // Draw cost + x = w->x + (window_footpath_widgets[WIDX_CONSTRUCT].left + window_footpath_widgets[WIDX_CONSTRUCT].right) / 2; + y = w->y + window_footpath_widgets[WIDX_CONSTRUCT].bottom - 12; + if (_window_footpath_cost != 0x80000000) + if (!(RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) & GAME_FLAGS_NO_MONEY)) + gfx_draw_string_centred(dpi, STR_COST_LABEL, x, y, 0, &_window_footpath_cost); } \ No newline at end of file From e617b16e336ec5144f3768e24a4517e793b1f011 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Tue, 29 Apr 2014 03:12:52 +0100 Subject: [PATCH 03/37] add left over footpath window events --- src/window_footpath.c | 204 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 196 insertions(+), 8 deletions(-) diff --git a/src/window_footpath.c b/src/window_footpath.c index f262be7707..c1ba08e13c 100644 --- a/src/window_footpath.c +++ b/src/window_footpath.c @@ -96,6 +96,13 @@ static rct_widget window_footpath_widgets[] = { static void window_footpath_emptysub() { } static void window_footpath_close(); static void window_footpath_mouseup(); +static void window_footpath_mousedown(); +static void window_footpath_dropdown(); +static void window_footpath_update(); +static void window_footpath_toolupdate(); +static void window_footpath_tooldown(); +static void window_footpath_tooldrag(); +static void window_footpath_toolup(); static void window_footpath_invalidate(); static void window_footpath_paint(); @@ -103,16 +110,16 @@ static uint32 window_footpath_events[] = { window_footpath_close, window_footpath_mouseup, window_footpath_emptysub, + window_footpath_mousedown, + window_footpath_dropdown, + window_footpath_emptysub, + window_footpath_update, window_footpath_emptysub, window_footpath_emptysub, - window_footpath_emptysub, - window_footpath_emptysub, - window_footpath_emptysub, - window_footpath_emptysub, - window_footpath_emptysub, - window_footpath_emptysub, - window_footpath_emptysub, - window_footpath_emptysub, + window_footpath_toolupdate, + window_footpath_tooldown, + window_footpath_tooldrag, + window_footpath_toolup, window_footpath_emptysub, window_footpath_emptysub, window_footpath_emptysub, @@ -220,6 +227,187 @@ static void window_footpath_mouseup() case WIDX_CLOSE: window_close(w); break; + case WIDX_CONSTRUCT: + RCT2_CALLPROC_X(0x006A79B7, 0, 0, 0, 0, w, 0, 0); + break; + case WIDX_REMOVE: + RCT2_CALLPROC_X(0x006A7863, 0, 0, 0, 0, w, 0, 0); + break; + case WIDX_CONSTRUCT_ON_LAND: + RCT2_CALLPROC_X(0x006A8072, 0, 0, 0, 0, w, 0, 0); + break; + case WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL: + RCT2_CALLPROC_X(0x006A80C5, 0, 0, 0, 0, w, 0, 0); + break; + } +} + +/** + * + * rct2: 0x006A7EC5 + */ +static void window_footpath_mousedown() +{ + short widgetIndex; + rct_window *w; + rct_widget *widget; + + __asm mov widgetIndex, dx + __asm mov w, esi + __asm mov widget, edi + + switch (widgetIndex) { + case WIDX_FOOTPATH_TYPE: + RCT2_CALLPROC_X(0x006A7F88, 0, 0, 0, widgetIndex, w, widget, 0); + break; + case WIDX_QUEUELINE_TYPE: + RCT2_CALLPROC_X(0x006A7F88, 0, 0, 0, widgetIndex, w, widget, 0); + break; + case WIDX_DIRECTION_NW: + RCT2_CALLPROC_X(0x006A8111, 0, 0, 0, 0, w, 0, 0); + break; + case WIDX_DIRECTION_NE: + RCT2_CALLPROC_X(0x006A8135, 0, 0, 0, 0, w, 0, 0); + break; + case WIDX_DIRECTION_SW: + RCT2_CALLPROC_X(0x006A815C, 0, 0, 0, 0, w, 0, 0); + break; + case WIDX_DIRECTION_SE: + RCT2_CALLPROC_X(0x006A8183, 0, 0, 0, 0, w, 0, 0); + break; + case WIDX_SLOPEDOWN: + RCT2_CALLPROC_X(0x006A81AA, 0, 0, 0, 0, w, 0, 0); + break; + case WIDX_LEVEL: + RCT2_CALLPROC_X(0x006A81C5, 0, 0, 0, 0, w, 0, 0); + break; + case WIDX_SLOPEUP: + RCT2_CALLPROC_X(0x006A81E0, 0, 0, 0, 0, w, 0, 0); + break; + } +} + +/** + * + * rct2: 0x006A7F18 + */ +static void window_footpath_dropdown() +{ + short widgetIndex; + rct_window *w; + + __asm mov widgetIndex, dx + __asm mov w, esi + + if (widgetIndex == WIDX_FOOTPATH_TYPE) { + RCT2_CALLPROC_X(0x006A7F25, 0, 0, 0, 0, w, 0, 0); + } else if (widgetIndex == WIDX_QUEUELINE_TYPE) { + RCT2_CALLPROC_X(0x006A7F2E, 0, 0, 0, 0, w, 0, 0); + } +} + +/** + * + * rct2: 0x006A8032 + */ +static void window_footpath_toolupdate() +{ + short widgetIndex; + rct_window *w; + + __asm mov widgetIndex, dx + __asm mov w, esi + + if (widgetIndex == WIDX_CONSTRUCT_ON_LAND) { + RCT2_CALLPROC_X(0x006A81FB, 0, 0, 0, 0, w, 0, 0); + } else if (widgetIndex == WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL) { + RCT2_CALLPROC_X(0x006A8388, 0, 0, 0, 0, w, 0, 0); + } +} + +/** + * + * rct2: 0x006A8047 + */ +static void window_footpath_tooldown() +{ + short widgetIndex; + rct_window *w; + + __asm mov widgetIndex, dx + __asm mov w, esi + + if (widgetIndex == WIDX_CONSTRUCT_ON_LAND) { + RCT2_CALLPROC_X(0x006A82C5, 0, 0, 0, 0, w, 0, 0); + } else if (widgetIndex == WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL) { + RCT2_CALLPROC_X(0x006A840F, 0, 0, 0, 0, w, 0, 0); + } +} + +/** + * + * rct2: 0x006A8067 + */ +static void window_footpath_tooldrag() +{ + short widgetIndex; + rct_window *w; + + __asm mov widgetIndex, dx + __asm mov w, esi + + if (widgetIndex == WIDX_CONSTRUCT_ON_LAND) { + RCT2_CALLPROC_X(0x006A82C5, 0, 0, 0, 0, w, 0, 0); + } +} + +/** + * + * rct2: 0x006A8066 + */ +static void window_footpath_toolup() +{ + short widgetIndex; + rct_window *w; + + __asm mov widgetIndex, dx + __asm mov w, esi + + if (widgetIndex == WIDX_CONSTRUCT_ON_LAND) { + RCT2_CALLPROC_X(0x006A8380, 0, 0, 0, 0, w, 0, 0); + } +} + +/** + * + * rct2: 0x006A84BB + */ +static void window_footpath_update() +{ + rct_window *w; + + __asm mov w, esi + + // Invalidate construct button + widget_invalidate(WC_FOOTPATH, 0, WIDX_CONSTRUCT); + + RCT2_CALLPROC_EBPSAFE(0x006A7760); + + // Check tool + if (RCT2_GLOBAL(0x00F3EF99, uint8) == 0) { + if (!(RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3))) + window_close(w); + if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) != WC_FOOTPATH) + window_close(w); + if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) != WIDX_CONSTRUCT_ON_LAND) + window_close(w); + } else if (RCT2_GLOBAL(0x00F3EF99, uint8) == 1) { + if (!(RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3))) + window_close(w); + if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) != WC_FOOTPATH) + window_close(w); + if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) != WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL) + window_close(w); } } From c20d209b69f48f1d09d8ecd01c3347ad5a303b37 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Tue, 29 Apr 2014 22:25:37 +0100 Subject: [PATCH 04/37] add path dropdowns and disabled widgets --- src/widget.c | 28 ++++++++++++-- src/window_footpath.c | 88 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 106 insertions(+), 10 deletions(-) diff --git a/src/widget.c b/src/widget.c index cccfc1434d..e4016b56f2 100644 --- a/src/widget.c +++ b/src/widget.c @@ -18,6 +18,7 @@ * along with this program. If not, see . *****************************************************************************/ +#include #include #include "addresses.h" #include "sprites.h" @@ -800,6 +801,10 @@ static void widget_vscrollbar_draw(rct_drawpixelinfo *dpi, rct_scroll *scroll, i gfx_draw_string(dpi, (char*)0x009DED69, 0, l + 1, b - 8); } +/** + * + * rct2: 0x006EB951 + */ static void widget_draw_image(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex) { int l, t, r, b, colour, image; @@ -826,7 +831,26 @@ static void widget_draw_image(rct_drawpixelinfo *dpi, rct_window *w, int widgetI if (widget_is_pressed(w, widgetIndex) || widget_is_active_tool(w, widgetIndex)) image++; - if (!widget_is_disabled(w, widgetIndex)) { + if (widget_is_disabled(w, widgetIndex)) { + // Draw greyed out (light border bottom right shadow) + colour = w->colours[widget->colour]; + colour = RCT2_ADDRESS(0x00141FC4A, uint8)[(colour & 0x7F) * 8] & 0xFF; + RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009DED74; + memset(0x009DED74, colour, 256); + RCT2_GLOBAL(0x009DED74, uint8) = 0; + RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000; + image &= 0x7FFFF; + RCT2_CALLPROC_X(0x0067A46E, 0, image, l + 1, t + 1, 0, dpi, 0); + + // Draw greyed out (dark) + colour = w->colours[widget->colour]; + colour = RCT2_ADDRESS(0x00141FC48, uint8)[(colour & 0x7F) * 8] & 0xFF; + RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009DED74; + memset(0x009DED74, colour, 256); + RCT2_GLOBAL(0x009DED74, uint8) = 0; + RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000; + RCT2_CALLPROC_X(0x0067A46E, 0, image, l, t, 0, dpi, 0); + } else { if (image & 0x80000000) { // ? } @@ -837,8 +861,6 @@ static void widget_draw_image(rct_drawpixelinfo *dpi, rct_window *w, int widgetI image |= colour << 19; gfx_draw_sprite(dpi, image, l, t); - } else { - // ? } } diff --git a/src/window_footpath.c b/src/window_footpath.c index c1ba08e13c..b7f7d0cfc3 100644 --- a/src/window_footpath.c +++ b/src/window_footpath.c @@ -25,13 +25,14 @@ #include "viewport.h" #include "widget.h" #include "window.h" +#include "window_dropdown.h" typedef struct { uint16 pad_00; uint32 image; // 0x02 uint32 pad_06; uint8 pad_0A; - uint8 pad_0B; + uint8 flags; // 0x0B } rct_path_type; static enum WINDOW_FOOTPATH_WIDGET_IDX { @@ -139,6 +140,8 @@ static uint32 window_footpath_events[] = { sint32 _window_footpath_cost; +static void window_footpath_show_footpath_types_dialog(rct_window *w, rct_widget *widget, int showQueues); + /** * * rct2: 0x006A7C43 @@ -258,10 +261,10 @@ static void window_footpath_mousedown() switch (widgetIndex) { case WIDX_FOOTPATH_TYPE: - RCT2_CALLPROC_X(0x006A7F88, 0, 0, 0, widgetIndex, w, widget, 0); + window_footpath_show_footpath_types_dialog(w, widget, 0); break; case WIDX_QUEUELINE_TYPE: - RCT2_CALLPROC_X(0x006A7F88, 0, 0, 0, widgetIndex, w, widget, 0); + window_footpath_show_footpath_types_dialog(w, widget, 1); break; case WIDX_DIRECTION_NW: RCT2_CALLPROC_X(0x006A8111, 0, 0, 0, 0, w, 0, 0); @@ -293,17 +296,47 @@ static void window_footpath_mousedown() */ static void window_footpath_dropdown() { + int i, pathId; + short dropdownIndex; short widgetIndex; rct_window *w; + rct_path_type *pathType; + __asm mov dropdownIndex, ax __asm mov widgetIndex, dx __asm mov w, esi - if (widgetIndex == WIDX_FOOTPATH_TYPE) { - RCT2_CALLPROC_X(0x006A7F25, 0, 0, 0, 0, w, 0, 0); - } else if (widgetIndex == WIDX_QUEUELINE_TYPE) { - RCT2_CALLPROC_X(0x006A7F2E, 0, 0, 0, 0, w, 0, 0); + if (widgetIndex == WIDX_FOOTPATH_TYPE) + RCT2_GLOBAL(0x00F3EFA2, uint8) = 0; + else if (widgetIndex == WIDX_QUEUELINE_TYPE) + RCT2_GLOBAL(0x00F3EFA2, uint8) = 1; + else + return; + + pathId = dropdownIndex; + if (pathId == -1) { + pathId = RCT2_GLOBAL(0x00F3EFA0, sint16); + } else { + int flags = 4; + if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2) + flags = 0; + + i = -1; + do { + i++; + pathType = RCT2_ADDRESS(0x009ADA14, rct_path_type*)[i]; + if (pathType == (rct_path_type*)-1) + continue; + if (pathType->flags & flags) + continue; + } while (--pathId >= 0); + pathId = i; } + + RCT2_GLOBAL(0x00F3EFA0, sint16) = pathId; + RCT2_CALLPROC_EBPSAFE(0x006A7831); + _window_footpath_cost = 0x80000000; + window_invalidate(w); } /** @@ -495,4 +528,45 @@ static void window_footpath_paint() if (_window_footpath_cost != 0x80000000) if (!(RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) & GAME_FLAGS_NO_MONEY)) gfx_draw_string_centred(dpi, STR_COST_LABEL, x, y, 0, &_window_footpath_cost); +} + +/** + * + * rct2: 0x006A7F88 + */ +static void window_footpath_show_footpath_types_dialog(rct_window *w, rct_widget *widget, int showQueues) +{ + int i, flags, numPathTypes, image; + rct_path_type *pathType; + + numPathTypes = 0; + flags = 4; + if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2) + flags = 0; + + for (i = 0; i < 16; i++) { + pathType = RCT2_ADDRESS(0x009ADA14, rct_path_type*)[i]; + if (pathType == (rct_path_type*)-1) + continue; + if (pathType->flags & flags) + continue; + + image = pathType->image + 71; + if (showQueues) + image++; + + gDropdownItemsFormat[numPathTypes] = -1; + gDropdownItemsArgs[numPathTypes] = image; + numPathTypes++; + } + + window_dropdown_show_image( + w->x + widget->left, w->y + widget->top, widget->bottom - widget->top + 1, + w->colours[1], + 0, + numPathTypes, + 47, + 36, + gAppropriateImageDropdownItemsPerRow[numPathTypes] + ); } \ No newline at end of file From 8632b76271a3f01c67e154ae0662eba1f33ad59c Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Wed, 30 Apr 2014 01:59:11 +0100 Subject: [PATCH 05/37] add provisional and placement of paths --- src/addresses.h | 7 ++ src/window_footpath.c | 153 +++++++++++++++++++++++++++++++++++++++--- src/window_park.c | 16 ++--- 3 files changed, 158 insertions(+), 18 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index 347adaccfd..4889529805 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -104,6 +104,13 @@ #define RCT2_ADDRESS_CURSOR_OVER_WINDOWNUMBER 0x009DE55E #define RCT2_ADDRESS_CURSOR_OVER_WIDGETINDEX 0x009DE560 +#define RCT2_ADDRESS_MAP_SELECTION_FLAGS 0x009DE58A +#define RCT2_ADDRESS_MAP_SELECTION_A_X 0x009DE58C +#define RCT2_ADDRESS_MAP_SELECTION_B_X 0x009DE58E +#define RCT2_ADDRESS_MAP_SELECTION_A_Y 0x009DE590 +#define RCT2_ADDRESS_MAP_SELECTION_B_Y 0x009DE592 +#define RCT2_ADDRESS_MAP_SELECTION_TYPE 0x009DE594 + #define RCT2_ADDRESS_SCREEN_FLAGS 0x009DEA68 #define RCT2_ADDRESS_SCREENSHOT_COUNTDOWN 0x009DEA6D #define RCT2_ADDRESS_PLACE_OBJECT_MODIFIER 0x009DEA70 diff --git a/src/window_footpath.c b/src/window_footpath.c index b7f7d0cfc3..6f3c5d3896 100644 --- a/src/window_footpath.c +++ b/src/window_footpath.c @@ -20,6 +20,8 @@ #include #include "addresses.h" +#include "audio.h" +#include "map.h" #include "strings.h" #include "sprites.h" #include "viewport.h" @@ -141,6 +143,8 @@ static uint32 window_footpath_events[] = { sint32 _window_footpath_cost; static void window_footpath_show_footpath_types_dialog(rct_window *w, rct_widget *widget, int showQueues); +static void window_footpath_set_provisional_path(int x, int y); +static void window_footpath_place_path(int x, int y); /** * @@ -296,7 +300,7 @@ static void window_footpath_mousedown() */ static void window_footpath_dropdown() { - int i, pathId; + int i, j, pathId; short dropdownIndex; short widgetIndex; rct_window *w; @@ -313,6 +317,7 @@ static void window_footpath_dropdown() else return; + // Get path id pathId = dropdownIndex; if (pathId == -1) { pathId = RCT2_GLOBAL(0x00F3EFA0, sint16); @@ -321,18 +326,22 @@ static void window_footpath_dropdown() if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2) flags = 0; - i = -1; - do { - i++; + j = 0; + for (i = 0; i < 16; i++) { pathType = RCT2_ADDRESS(0x009ADA14, rct_path_type*)[i]; if (pathType == (rct_path_type*)-1) continue; if (pathType->flags & flags) continue; - } while (--pathId >= 0); + + if (j == pathId) + break; + j++; + } pathId = i; } + // Set selected path id RCT2_GLOBAL(0x00F3EFA0, sint16) = pathId; RCT2_CALLPROC_EBPSAFE(0x006A7831); _window_footpath_cost = 0x80000000; @@ -345,14 +354,18 @@ static void window_footpath_dropdown() */ static void window_footpath_toolupdate() { + int x, y, z; short widgetIndex; rct_window *w; + rct_map_element *mapElement; + __asm mov x, eax + __asm mov y, ebx __asm mov widgetIndex, dx __asm mov w, esi if (widgetIndex == WIDX_CONSTRUCT_ON_LAND) { - RCT2_CALLPROC_X(0x006A81FB, 0, 0, 0, 0, w, 0, 0); + window_footpath_set_provisional_path(x, y); } else if (widgetIndex == WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL) { RCT2_CALLPROC_X(0x006A8388, 0, 0, 0, 0, w, 0, 0); } @@ -364,16 +377,20 @@ static void window_footpath_toolupdate() */ static void window_footpath_tooldown() { + int x, y, z; short widgetIndex; rct_window *w; + rct_map_element *mapElement; + __asm mov x, eax + __asm mov y, ebx __asm mov widgetIndex, dx __asm mov w, esi if (widgetIndex == WIDX_CONSTRUCT_ON_LAND) { - RCT2_CALLPROC_X(0x006A82C5, 0, 0, 0, 0, w, 0, 0); + window_footpath_place_path(x, y); } else if (widgetIndex == WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL) { - RCT2_CALLPROC_X(0x006A840F, 0, 0, 0, 0, w, 0, 0); + RCT2_CALLPROC_X(0x006A840F, x, y, 0, 0, w, 0, 0); } } @@ -383,14 +400,17 @@ static void window_footpath_tooldown() */ static void window_footpath_tooldrag() { + int x, y; short widgetIndex; rct_window *w; + __asm mov x, eax + __asm mov y, ebx __asm mov widgetIndex, dx __asm mov w, esi if (widgetIndex == WIDX_CONSTRUCT_ON_LAND) { - RCT2_CALLPROC_X(0x006A82C5, 0, 0, 0, 0, w, 0, 0); + RCT2_CALLPROC_X(0x006A82C5, x, y, 0, 0, w, 0, 0); } } @@ -400,14 +420,17 @@ static void window_footpath_tooldrag() */ static void window_footpath_toolup() { + int x, y; short widgetIndex; rct_window *w; + __asm mov x, eax + __asm mov y, ebx __asm mov widgetIndex, dx __asm mov w, esi if (widgetIndex == WIDX_CONSTRUCT_ON_LAND) { - RCT2_CALLPROC_X(0x006A8380, 0, 0, 0, 0, w, 0, 0); + RCT2_CALLPROC_X(0x006A8380, x, y, 0, 0, w, 0, 0); } } @@ -569,4 +592,114 @@ static void window_footpath_show_footpath_types_dialog(rct_window *w, rct_widget 36, gAppropriateImageDropdownItemsPerRow[numPathTypes] ); +} + +/** + * + * rct2: 0x006A81FB + */ +static void window_footpath_set_provisional_path(int x, int y) +{ + int z; + rct_map_element *mapElement; + + RCT2_CALLPROC_EBPSAFE(0x0068AAE1); + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~4; + + int eax, ebx, ecx, edx, esi, edi, ebp; + eax = x; + ebx = y; + edx = -34; + RCT2_CALLFUNC_X(0x00685ADC, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + x = eax & 0xFFFF; + z = ebx & 0xFF; + y = ecx & 0xFFFF; + mapElement = edx; + + if (z == 0) { + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~1; + RCT2_CALLPROC_EBPSAFE(0x006A7831); + } else { + // Check for change + if ((RCT2_GLOBAL(0x00F3EF92, uint8) & 2) && RCT2_GLOBAL(0x00F3EF94, uint16) == x && RCT2_GLOBAL(0x00F3EF96, uint16) == y && RCT2_GLOBAL(0x00F3EF98, uint8) == mapElement->base_height) + return; + + // Set map selection + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) |= 1; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_TYPE, uint16) = 4; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, uint16) = x; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, uint16) = y; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16) = x; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16) = y; + + RCT2_CALLPROC_EBPSAFE(0x006A7831); + + // Set provisional path + edx = mapElement->properties.surface.slope & 0x1F; + int bh = RCT2_ADDRESS(0x0098D8B4, uint8)[edx]; + int dl = mapElement->base_height; + if (z == 6) + bh = mapElement->properties.surface.slope & 7; + int dh = (RCT2_GLOBAL(0x00F3EFA2, uint8) << 7) + RCT2_GLOBAL(0x00F3EFA0, uint8); + + ebx = (bh << 8) | z; + edx = (dh << 8) | dl; + edi = 0; + RCT2_CALLFUNC_X(0x006A76FF, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + + // + _window_footpath_cost = ebx; + // window_invalidate_by_id(eax, ebx); + } +} + +/** + * + * rct2: 0x006A82C5 + */ +static void window_footpath_place_path(int x, int y) +{ + int z; + rct_map_element *mapElement; + + if (RCT2_GLOBAL(0x00F3EF9F, uint8) != 0) + return; + + RCT2_CALLPROC_EBPSAFE(0x006A7831); + + int eax, ebx, ecx, edx, esi, edi, ebp; + eax = x; + ebx = y; + edx = -34; + RCT2_CALLFUNC_X(0x00685ADC, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + x = eax & 0xFFFF; + z = ebx & 0xFF; + y = ecx & 0xFFFF; + mapElement = edx; + + if (z == 0) + return; + + // Set path + edx = mapElement->properties.surface.slope & 0x1F; + int bh = RCT2_ADDRESS(0x0098D8B4, uint8)[edx]; + int dl = mapElement->base_height; + if (z == 6) + bh = mapElement->properties.surface.slope & 7; + RCT2_GLOBAL(0x0141E9AE, uint16) = 1176; + int dh = (RCT2_GLOBAL(0x00F3EFA2, uint8) << 7) + RCT2_GLOBAL(0x00F3EFA0, uint8); + + ebx = (bh << 8) | 1; + edx = (dh << 8) | dl; + edi = 0; + esi = 17; + RCT2_CALLFUNC_X(0x006677F2, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + if (ebx == 0x80000000) { + RCT2_GLOBAL(0x00F3EF9F, uint8) = 1; + } else if (RCT2_GLOBAL(0x00F3EFD9, uint32) != 0) { + // bp = 0x009DEA62 + // dx = 0x009DEA60 + // cx = 0x009DEA5E + sound_play_panned(6, 0x8001); + } } \ No newline at end of file diff --git a/src/window_park.c b/src/window_park.c index 5decd55290..29867a3540 100644 --- a/src/window_park.c +++ b/src/window_park.c @@ -797,17 +797,17 @@ static void window_park_entrance_toolupdate() __asm mov widgetIndex, dx __asm mov w, esi - if (widgetIndex == WIDX_BUY_LAND_RIGHTS) { + if (widgetIndex == WIDX_BUY_LAND_RIGHTS || widgetIndex == SPR_BUY_CONSTRUCTION_RIGHTS) { RCT2_CALLPROC_X(0x0068AAE1, x, y, 0, 0, w, 0, 0); - RCT2_GLOBAL(0x009DE58A, uint16) &= 0xFFFE; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~1; screen_pos_to_map_pos(&x, &y); if (x != SPRITE_LOCATION_NULL) { - RCT2_GLOBAL(0x009DE58A, uint16) |= 1; - RCT2_GLOBAL(0x009DE594, uint16) = 4; - RCT2_GLOBAL(0x009DE58C, uint16) = x; - RCT2_GLOBAL(0x009DE58E, uint16) = x; - RCT2_GLOBAL(0x009DE590, uint16) = y; - RCT2_GLOBAL(0x009DE592, uint16) = y; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) |= 1; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_TYPE, uint16) = 4; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, uint16) = x; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16) = x; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, uint16) = y; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16) = y; RCT2_CALLPROC_X(0x0068AAE1, x, y, 0, 0, w, 0, 0); } } From 6dd861a81560fe3723c27ad19b42221d5a23bee0 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Wed, 30 Apr 2014 02:25:54 +0100 Subject: [PATCH 06/37] fix construct path bridge or tunnel button --- src/window_footpath.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/window_footpath.c b/src/window_footpath.c index 6f3c5d3896..d62687af75 100644 --- a/src/window_footpath.c +++ b/src/window_footpath.c @@ -241,10 +241,10 @@ static void window_footpath_mouseup() RCT2_CALLPROC_X(0x006A7863, 0, 0, 0, 0, w, 0, 0); break; case WIDX_CONSTRUCT_ON_LAND: - RCT2_CALLPROC_X(0x006A8072, 0, 0, 0, 0, w, 0, 0); + RCT2_CALLPROC_X(0x006A8072, 0, 0, 0, widgetIndex, w, 0, 0); break; case WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL: - RCT2_CALLPROC_X(0x006A80C5, 0, 0, 0, 0, w, 0, 0); + RCT2_CALLPROC_X(0x006A80C5, 0, 0, 0, widgetIndex, w, 0, 0); break; } } From 46472c35aec416305dcd612b39657d9ce8a59c82 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Wed, 30 Apr 2014 13:38:27 +0100 Subject: [PATCH 07/37] improve footpath code --- src/strings.h | 1 + src/window_footpath.c | 97 ++++++++++++++++++++++++++++++------------- 2 files changed, 68 insertions(+), 30 deletions(-) diff --git a/src/strings.h b/src/strings.h index 71f9e53899..a3339928c6 100644 --- a/src/strings.h +++ b/src/strings.h @@ -196,6 +196,7 @@ enum { STR_ADJUST_WATER_TIP = 1160, STR_BUILD_FOOTPATH_TIP = 1173, + STR_CANT_BUILD_FOOTPATH_HERE = 1176, STR_FOOTPATHS = 1181, STR_TYPE = 1182, diff --git a/src/window_footpath.c b/src/window_footpath.c index d62687af75..0b90d247d2 100644 --- a/src/window_footpath.c +++ b/src/window_footpath.c @@ -143,8 +143,9 @@ static uint32 window_footpath_events[] = { sint32 _window_footpath_cost; static void window_footpath_show_footpath_types_dialog(rct_window *w, rct_widget *widget, int showQueues); -static void window_footpath_set_provisional_path(int x, int y); -static void window_footpath_place_path(int x, int y); +static void window_footpath_set_provisional_path_at_point(int x, int y); +static int window_footpath_set_provisional_path(int type, int x, int y, int z, int slope); +static void window_footpath_place_path_at_point(int x, int y); /** * @@ -365,7 +366,7 @@ static void window_footpath_toolupdate() __asm mov w, esi if (widgetIndex == WIDX_CONSTRUCT_ON_LAND) { - window_footpath_set_provisional_path(x, y); + window_footpath_set_provisional_path_at_point(x, y); } else if (widgetIndex == WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL) { RCT2_CALLPROC_X(0x006A8388, 0, 0, 0, 0, w, 0, 0); } @@ -388,7 +389,7 @@ static void window_footpath_tooldown() __asm mov w, esi if (widgetIndex == WIDX_CONSTRUCT_ON_LAND) { - window_footpath_place_path(x, y); + window_footpath_place_path_at_point(x, y); } else if (widgetIndex == WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL) { RCT2_CALLPROC_X(0x006A840F, x, y, 0, 0, w, 0, 0); } @@ -598,14 +599,15 @@ static void window_footpath_show_footpath_types_dialog(rct_window *w, rct_widget * * rct2: 0x006A81FB */ -static void window_footpath_set_provisional_path(int x, int y) +static void window_footpath_set_provisional_path_at_point(int x, int y) { - int z; + int z, slope, pathType; rct_map_element *mapElement; RCT2_CALLPROC_EBPSAFE(0x0068AAE1); RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~4; + // Get map coordinates from point int eax, ebx, ecx, edx, esi, edi, ebp; eax = x; ebx = y; @@ -635,31 +637,59 @@ static void window_footpath_set_provisional_path(int x, int y) RCT2_CALLPROC_EBPSAFE(0x006A7831); // Set provisional path - edx = mapElement->properties.surface.slope & 0x1F; - int bh = RCT2_ADDRESS(0x0098D8B4, uint8)[edx]; - int dl = mapElement->base_height; + slope = RCT2_ADDRESS(0x0098D8B4, uint8)[mapElement->properties.surface.slope & 0x1F]; if (z == 6) - bh = mapElement->properties.surface.slope & 7; - int dh = (RCT2_GLOBAL(0x00F3EFA2, uint8) << 7) + RCT2_GLOBAL(0x00F3EFA0, uint8); + slope = mapElement->properties.surface.slope & 7; + pathType = (RCT2_GLOBAL(0x00F3EFA2, uint8) << 7) + RCT2_GLOBAL(0x00F3EFA0, uint8); - ebx = (bh << 8) | z; - edx = (dh << 8) | dl; - edi = 0; - RCT2_CALLFUNC_X(0x006A76FF, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - - // - _window_footpath_cost = ebx; + _window_footpath_cost = window_footpath_set_provisional_path(pathType, x, y, mapElement->base_height, slope); // window_invalidate_by_id(eax, ebx); } } +/** + * + * rct2: 0x006A76FF + */ +static int window_footpath_set_provisional_path(int type, int x, int y, int z, int slope) +{ + int cost; + int eax, ebx, ecx, edx, esi, edi, ebp; + + RCT2_CALLPROC_EBPSAFE(0x006A77FF); + + // Try and show provisional path + eax = x; + ebx = (slope << 8) | 121; + ecx = y; + edx = (type << 8) | z; + esi = 17; + edi = 0; + RCT2_CALLFUNC_X(0x006677F2, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + cost = ebx; + + if (cost != 0x80000000) { + RCT2_GLOBAL(0x00F3EF94, uint16) = x; + RCT2_GLOBAL(0x00F3EF96, uint16) = y; + RCT2_GLOBAL(0x00F3EF98, uint8) = z & 0xFF; + RCT2_GLOBAL(0x00F3EF92, uint8) |= 2; + + eax = 3; + if (RCT2_GLOBAL(0x00F3EFA4, uint8) & 2) + eax = 1; + RCT2_CALLPROC_X(0x006CB70A, eax, 0, 0, 0, 0, 0, 0); + } + + return cost; +} + /** * * rct2: 0x006A82C5 */ -static void window_footpath_place_path(int x, int y) +static void window_footpath_place_path_at_point(int x, int y) { - int z; + int z, slope, type, cost; rct_map_element *mapElement; if (RCT2_GLOBAL(0x00F3EF9F, uint8) != 0) @@ -667,6 +697,7 @@ static void window_footpath_place_path(int x, int y) RCT2_CALLPROC_EBPSAFE(0x006A7831); + // Get map coordinates from point int eax, ebx, ecx, edx, esi, edi, ebp; eax = x; ebx = y; @@ -681,20 +712,26 @@ static void window_footpath_place_path(int x, int y) return; // Set path - edx = mapElement->properties.surface.slope & 0x1F; - int bh = RCT2_ADDRESS(0x0098D8B4, uint8)[edx]; - int dl = mapElement->base_height; + slope = RCT2_ADDRESS(0x0098D8B4, uint8)[mapElement->properties.surface.slope & 0x1F]; + z = mapElement->base_height; if (z == 6) - bh = mapElement->properties.surface.slope & 7; - RCT2_GLOBAL(0x0141E9AE, uint16) = 1176; - int dh = (RCT2_GLOBAL(0x00F3EFA2, uint8) << 7) + RCT2_GLOBAL(0x00F3EFA0, uint8); + slope = mapElement->properties.surface.slope & 7; + type = (RCT2_GLOBAL(0x00F3EFA2, uint8) << 7) + RCT2_GLOBAL(0x00F3EFA0, uint8); - ebx = (bh << 8) | 1; - edx = (dh << 8) | dl; - edi = 0; + // Prepare error text + RCT2_GLOBAL(0x0141E9AE, uint16) = STR_CANT_BUILD_FOOTPATH_HERE; + + // Try and place path + eax = x; + ebx = (slope << 8) | 1; + ecx = y; + edx = (type << 8) | z; esi = 17; + edi = 0; RCT2_CALLFUNC_X(0x006677F2, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - if (ebx == 0x80000000) { + cost = ebx; + + if (cost == 0x80000000) { RCT2_GLOBAL(0x00F3EF9F, uint8) = 1; } else if (RCT2_GLOBAL(0x00F3EFD9, uint32) != 0) { // bp = 0x009DEA62 From 46308abfe3c5f1c2553afa2f1de9cf3a33d20333 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Wed, 30 Apr 2014 16:57:27 +0100 Subject: [PATCH 08/37] add cancel and set tool along with path refactor --- src/addresses.h | 1 + src/window.c | 67 +++++++++++++++++++++++++++++++++++ src/window.h | 3 ++ src/window_clear_scenery.c | 2 +- src/window_footpath.c | 48 ++++++++++++++++++++----- src/window_game_top_toolbar.c | 18 +++++----- src/window_land.c | 2 +- src/window_park.c | 6 ++-- src/window_water.c | 2 +- 9 files changed, 126 insertions(+), 23 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index 4889529805..1772a58e77 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -98,6 +98,7 @@ #define RCT2_ADDRESS_TOOL_WINDOWNUMBER 0x009DE542 #define RCT2_ADDRESS_TOOL_WINDOWCLASS 0x009DE544 +#define RCT2_ADDRESS_CURRENT_TOOL 0x009DE545 #define RCT2_ADDRESS_TOOL_WIDGETINDEX 0x009DE546 #define RCT2_ADDRESS_CURSOR_OVER_WINDOWCLASS 0x009DE55C diff --git a/src/window.c b/src/window.c index 1c9b5e503b..da21178b58 100644 --- a/src/window.c +++ b/src/window.c @@ -1105,3 +1105,70 @@ void window_set_resize(rct_window *w, int minWidth, int minHeight, int maxWidth, window_invalidate(w); } } + +/** + * + * rct2: 0x006EE212 + * + * @param tool (al) + * @param widgetIndex (dx) + * @param w (esi) + */ +int tool_set(rct_window *w, int widgetIndex, int tool) +{ + if (RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3)) { + if ( + w->classification == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) && + w->number == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber) && + widgetIndex == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) + ) { + tool_cancel(); + return 1; + } + } + + RCT2_GLOBAL(0x009DE518, uint32) |= (1 << 3); + RCT2_GLOBAL(0x009DE518, uint32) &= ~(1 << 6); + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) = tool; + RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) = w->classification; + RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber) = w->number; + RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) = widgetIndex; + return 0; +} + +/** + * + * rct2: 0x006EE281 + */ +void tool_cancel() +{ + rct_window *w; + + if (RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3)) { + RCT2_GLOBAL(0x009DE518, uint32) &= ~(1 << 3); + + // + RCT2_CALLPROC_EBPSAFE(0x0068AAE1); + RCT2_CALLPROC_EBPSAFE(0x0068AB1B); + + // Reset map selection + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) = 0; + + if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, sint16) >= 0) { + // Invalidate tool widget + widget_invalidate( + RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass), + RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber), + RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) + ); + + // Abort tool event + w = window_find_by_id( + RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass), + RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber) + ); + if (w != NULL) + RCT2_CALLPROC_X(w->event_handlers[WE_TOOL_ABORT], 0, 0, 0, RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16), w, 0, 0); + } + } +} \ No newline at end of file diff --git a/src/window.h b/src/window.h index 62f2bcf74d..ff5257c90f 100644 --- a/src/window.h +++ b/src/window.h @@ -319,6 +319,9 @@ void window_move_position(rct_window *w, int dx, int dy); void window_resize(rct_window *w, int dw, int dh); void window_set_resize(rct_window *w, int minWidth, int minHeight, int maxWidth, int maxHeight); +int tool_set(rct_window *w, int widgetIndex, int tool); +void tool_cancel(); + // Open window functions void window_main_open(); void window_game_top_toolbar_open(); diff --git a/src/window_clear_scenery.c b/src/window_clear_scenery.c index 061de23294..f5a708f83d 100644 --- a/src/window_clear_scenery.c +++ b/src/window_clear_scenery.c @@ -116,7 +116,7 @@ static void window_clear_scenery_close() { // If the tool wasn't changed, turn tool off if (!window_clear_scenery_should_close()) - RCT2_CALLPROC_EBPSAFE(0x006EE281); + tool_cancel(); } /** diff --git a/src/window_footpath.c b/src/window_footpath.c index 0b90d247d2..1bed335299 100644 --- a/src/window_footpath.c +++ b/src/window_footpath.c @@ -29,6 +29,12 @@ #include "window.h" #include "window_dropdown.h" +enum { + PATH_CONSTRUCTION_MODE_LAND, + PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL, + PATH_CONSTRUCTION_MODE_2 +}; + typedef struct { uint16 pad_00; uint32 image; // 0x02 @@ -193,9 +199,9 @@ void window_footpath_open() window->colours[1] = 24; window->colours[2] = 24; - RCT2_CALLPROC_EBPSAFE(0x006EE281); - RCT2_GLOBAL(0x00F3EF99, uint8) = 0; - RCT2_CALLPROC_X(0x006EE212, 17, 0, 0, 18, window, 0, 0); + tool_cancel(); + RCT2_GLOBAL(0x00F3EF99, uint8) = PATH_CONSTRUCTION_MODE_LAND; + tool_set(window, WIDX_CONSTRUCT_ON_LAND, 17); RCT2_GLOBAL(0x009DE518, uint32) |= (1 << 6); RCT2_GLOBAL(0x00F3EF9F, uint8) = 0; RCT2_CALLPROC_EBPSAFE(0x006A855C); @@ -242,10 +248,36 @@ static void window_footpath_mouseup() RCT2_CALLPROC_X(0x006A7863, 0, 0, 0, 0, w, 0, 0); break; case WIDX_CONSTRUCT_ON_LAND: - RCT2_CALLPROC_X(0x006A8072, 0, 0, 0, widgetIndex, w, 0, 0); + // RCT2_CALLPROC_X(0x006A8072, 0, 0, 0, widgetIndex, w, 0, 0); + + if (RCT2_GLOBAL(0x00F3EF99, uint8) == PATH_CONSTRUCTION_MODE_LAND) + break; + _window_footpath_cost = 0x80000000; + tool_cancel(); + RCT2_CALLPROC_EBPSAFE(0x006A7831); + RCT2_CALLPROC_EBPSAFE(0x0068AB1B); + RCT2_GLOBAL(0x009DE58A, uint16) &= ~2; + RCT2_GLOBAL(0x00F3EF99, uint8) = PATH_CONSTRUCTION_MODE_LAND; + tool_set(w, WIDX_CONSTRUCT_ON_LAND, 17); + RCT2_GLOBAL(0x009DE518, uint32) |= (1 << 6); + RCT2_GLOBAL(0x00F3EF9F, uint8) = 0; + RCT2_CALLPROC_EBPSAFE(0x006A855C); break; case WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL: - RCT2_CALLPROC_X(0x006A80C5, 0, 0, 0, widgetIndex, w, 0, 0); + // RCT2_CALLPROC_X(0x006A80C5, 0, 0, 0, widgetIndex, w, 0, 0); + + if (RCT2_GLOBAL(0x00F3EF99, uint8) == PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL) + break; + _window_footpath_cost = 0x80000000; + RCT2_CALLPROC_EBPSAFE(0x006EE281); + RCT2_CALLPROC_EBPSAFE(0x006A7831); + RCT2_CALLPROC_EBPSAFE(0x0068AB1B); + RCT2_GLOBAL(0x009DE58A, uint16) &= ~2; + RCT2_GLOBAL(0x00F3EF99, uint8) = PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL; + tool_set(w, WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL, 12); + RCT2_GLOBAL(0x009DE518, uint32) |= (1 << 6); + RCT2_GLOBAL(0x00F3EF9F, uint8) = 0; + RCT2_CALLPROC_EBPSAFE(0x006A855C); break; } } @@ -451,14 +483,14 @@ static void window_footpath_update() RCT2_CALLPROC_EBPSAFE(0x006A7760); // Check tool - if (RCT2_GLOBAL(0x00F3EF99, uint8) == 0) { + if (RCT2_GLOBAL(0x00F3EF99, uint8) == PATH_CONSTRUCTION_MODE_LAND) { if (!(RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3))) window_close(w); if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) != WC_FOOTPATH) window_close(w); if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) != WIDX_CONSTRUCT_ON_LAND) window_close(w); - } else if (RCT2_GLOBAL(0x00F3EF99, uint8) == 1) { + } else if (RCT2_GLOBAL(0x00F3EF99, uint8) == PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL) { if (!(RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3))) window_close(w); if (RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) != WC_FOOTPATH) @@ -488,7 +520,7 @@ static void window_footpath_invalidate() (1 << WIDX_QUEUELINE_TYPE); // Enable / disable construct button - window_footpath_widgets[WIDX_CONSTRUCT].type = RCT2_GLOBAL(0x00F3EF99, uint8) == 0 ? WWT_EMPTY : WWT_IMGBTN; + window_footpath_widgets[WIDX_CONSTRUCT].type = RCT2_GLOBAL(0x00F3EF99, uint8) == PATH_CONSTRUCTION_MODE_LAND ? WWT_EMPTY : WWT_IMGBTN; // Set footpath and queue type button images selectedPath = RCT2_GLOBAL(0x00F3EFA0, uint16); diff --git a/src/window_game_top_toolbar.c b/src/window_game_top_toolbar.c index 020afbb811..d329e5c954 100644 --- a/src/window_game_top_toolbar.c +++ b/src/window_game_top_toolbar.c @@ -175,10 +175,10 @@ static void window_game_top_toolbar_mouseup() case WIDX_CLEAR_SCENERY: if ((RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3)) && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, uint8) == 1 && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) == 16) { - RCT2_CALLPROC_EBPSAFE(0x006EE281); + tool_cancel(); } else { show_gridlines(); - RCT2_CALLPROC_X(0x006EE212, 12, 0, 0, WIDX_CLEAR_SCENERY, w, 0, 0); + tool_set(w, WIDX_CLEAR_SCENERY, 12); RCT2_GLOBAL(0x009DE518, uint32) |= (1 << 6); RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) = 2; window_clear_scenery_open(); @@ -186,10 +186,10 @@ static void window_game_top_toolbar_mouseup() break; case WIDX_LAND: if ((RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3)) && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, uint8) == 1 && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) == 7) { - RCT2_CALLPROC_EBPSAFE(0x006EE281); + tool_cancel(); } else { show_gridlines(); - RCT2_CALLPROC_X(0x006EE212, 18, 0, 0, WIDX_LAND, w, 0, 0); + tool_set(w, WIDX_LAND, 18); RCT2_GLOBAL(0x009DE518, uint32) |= (1 << 6); RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) = 1; window_land_open(); @@ -197,17 +197,17 @@ static void window_game_top_toolbar_mouseup() break; case WIDX_WATER: if ((RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3)) && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, uint8) == 1 && RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) == 8) { - RCT2_CALLPROC_EBPSAFE(0x006EE281); + tool_cancel(); } else { show_gridlines(); - RCT2_CALLPROC_X(0x006EE212, 19, 0, 0, WIDX_WATER, w, 0, 0); + tool_set(w, WIDX_WATER, 19); RCT2_GLOBAL(0x009DE518, uint32) |= (1 << 6); RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) = 1; window_water_open(); } break; case WIDX_SCENERY: - RCT2_CALLPROC_X(0x006EE212, 0, 0, 0, WIDX_SCENERY, w, 0, 0); + tool_set(w, WIDX_SCENERY, 0); RCT2_GLOBAL(0x009DE518, uint32) |= (1 << 6); RCT2_CALLPROC_EBPSAFE(0x006E0FEF); break; @@ -215,7 +215,7 @@ static void window_game_top_toolbar_mouseup() if (window_find_by_id(WC_FOOTPATH, 0) == NULL) { window_footpath_open(); } else { - RCT2_CALLPROC_EBPSAFE(0x006EE281); + tool_cancel(); window_close_by_id(0x80 | WC_FOOTPATH, 0); } break; @@ -345,7 +345,7 @@ static void window_game_top_toolbar_dropdown() RCT2_CALLPROC_X(0x006677F2, 0, 1, 0, 0, 5, 0, 0); break; case 1: // save game - RCT2_CALLPROC_EBPSAFE(0x006EE281); + tool_cancel(); { int eax, ebx, ecx, edx, esi, edi, ebp; RCT2_CALLFUNC_X(0x006750E9, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); diff --git a/src/window_land.c b/src/window_land.c index 0c196b46f1..3a47fa0937 100644 --- a/src/window_land.c +++ b/src/window_land.c @@ -152,7 +152,7 @@ static void window_land_close() { // If the tool wasn't changed, turn tool off if (!window_land_should_close()) - RCT2_CALLPROC_EBPSAFE(0x006EE281); + tool_cancel(); } /** diff --git a/src/window_park.c b/src/window_park.c index 29867a3540..39b17519ae 100644 --- a/src/window_park.c +++ b/src/window_park.c @@ -645,7 +645,7 @@ static void window_park_entrance_close() if (RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3)) if (w->classification == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) && w->number == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber)) - RCT2_CALLPROC_EBPSAFE(0x006EE281); + tool_cancel(); } /** @@ -1618,7 +1618,7 @@ void window_park_objective_open() if (RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3)) if (window->classification == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) && window->number == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber)) - RCT2_CALLPROC_EBPSAFE(0x006EE281); + tool_cancel(); window->viewport = NULL; window->page = WINDOW_PARK_PAGE_OBJECTIVE; @@ -1895,7 +1895,7 @@ static void window_park_set_page(rct_window *w, int page) if (RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3)) if (w->classification == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) && w->number == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber)) - RCT2_CALLPROC_EBPSAFE(0x006EE281); + tool_cancel(); // Set listen only to viewport listen = 0; diff --git a/src/window_water.c b/src/window_water.c index 6b7eab58a5..56be72a634 100644 --- a/src/window_water.c +++ b/src/window_water.c @@ -117,7 +117,7 @@ static void window_water_close() { // If the tool wasn't changed, turn tool off if (!window_water_should_close()) - RCT2_CALLPROC_EBPSAFE(0x006EE281); + tool_cancel(); } /** From b41ea1c141811b357ff9bae978c01b007137c92c Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Wed, 30 Apr 2014 19:35:37 +0100 Subject: [PATCH 09/37] add path removal --- src/addresses.h | 1 + src/strings.h | 4 ++ src/window_footpath.c | 107 +++++++++++++++++++++++++++++++++++++++--- src/window_park.c | 6 +-- 4 files changed, 108 insertions(+), 10 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index 1772a58e77..d6c666f79e 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -191,6 +191,7 @@ #define RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS 0x013CE9A4 +#define RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID 0x0141E9AE #define RCT2_ADDRESS_CURRENT_ROTATION 0x0141E9E0 #define RCT2_ADDRESS_SCENARIO_NAME 0x0141F5B8 diff --git a/src/strings.h b/src/strings.h index a3339928c6..f2093860d8 100644 --- a/src/strings.h +++ b/src/strings.h @@ -197,6 +197,7 @@ enum { STR_BUILD_FOOTPATH_TIP = 1173, STR_CANT_BUILD_FOOTPATH_HERE = 1176, + STR_CANT_REMOVE_FOOTPATH_FROM_HERE = 1177, STR_FOOTPATHS = 1181, STR_TYPE = 1182, @@ -248,6 +249,9 @@ enum { STR_PARK_CLOSED = 1721, STR_PARK_OPEN = 1722, + STR_CANT_OPEN_PARK = 1723, + STR_CANT_CLOSE_PARK = 1724, + STR_INDIVIDUAL_GUESTS_TIP = 1752, STR_SUMMARISED_GUESTS_TIP = 1753, STR_ADMISSION_PRICE = 1756, diff --git a/src/window_footpath.c b/src/window_footpath.c index 1bed335299..e9d54c4237 100644 --- a/src/window_footpath.c +++ b/src/window_footpath.c @@ -152,6 +152,8 @@ static void window_footpath_show_footpath_types_dialog(rct_window *w, rct_widget static void window_footpath_set_provisional_path_at_point(int x, int y); static int window_footpath_set_provisional_path(int type, int x, int y, int z, int slope); static void window_footpath_place_path_at_point(int x, int y); +static void window_footpath_construct(); +static void window_footpath_remove(); /** * @@ -242,16 +244,15 @@ static void window_footpath_mouseup() window_close(w); break; case WIDX_CONSTRUCT: - RCT2_CALLPROC_X(0x006A79B7, 0, 0, 0, 0, w, 0, 0); + window_footpath_construct(); break; case WIDX_REMOVE: - RCT2_CALLPROC_X(0x006A7863, 0, 0, 0, 0, w, 0, 0); + window_footpath_remove(); break; case WIDX_CONSTRUCT_ON_LAND: - // RCT2_CALLPROC_X(0x006A8072, 0, 0, 0, widgetIndex, w, 0, 0); - if (RCT2_GLOBAL(0x00F3EF99, uint8) == PATH_CONSTRUCTION_MODE_LAND) break; + _window_footpath_cost = 0x80000000; tool_cancel(); RCT2_CALLPROC_EBPSAFE(0x006A7831); @@ -264,10 +265,9 @@ static void window_footpath_mouseup() RCT2_CALLPROC_EBPSAFE(0x006A855C); break; case WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL: - // RCT2_CALLPROC_X(0x006A80C5, 0, 0, 0, widgetIndex, w, 0, 0); - if (RCT2_GLOBAL(0x00F3EF99, uint8) == PATH_CONSTRUCTION_MODE_BRIDGE_OR_TUNNEL) break; + _window_footpath_cost = 0x80000000; RCT2_CALLPROC_EBPSAFE(0x006EE281); RCT2_CALLPROC_EBPSAFE(0x006A7831); @@ -751,7 +751,7 @@ static void window_footpath_place_path_at_point(int x, int y) type = (RCT2_GLOBAL(0x00F3EFA2, uint8) << 7) + RCT2_GLOBAL(0x00F3EFA0, uint8); // Prepare error text - RCT2_GLOBAL(0x0141E9AE, uint16) = STR_CANT_BUILD_FOOTPATH_HERE; + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, uint16) = STR_CANT_BUILD_FOOTPATH_HERE; // Try and place path eax = x; @@ -771,4 +771,97 @@ static void window_footpath_place_path_at_point(int x, int y) // cx = 0x009DEA5E sound_play_panned(6, 0x8001); } +} + +/** + * + * rct2: 0x006A79B7 + */ +static void window_footpath_construct() +{ + RCT2_CALLPROC_EBPSAFE(0x006A79B7); +} + +/** + * + * rct2: 0x006A7863 + */ +static void window_footpath_remove() +{ + int x, y, z, lastTile; + rct_map_element *mapElement; + + // RCT2_CALLPROC_EBPSAFE(0x006A7863); + + _window_footpath_cost = 0x80000000; + RCT2_CALLPROC_EBPSAFE(0x006A7831); + + x = RCT2_GLOBAL(0x00F3EF8A, uint16) / 32; + y = RCT2_GLOBAL(0x00F3EF8C, uint16) / 32; + int dl = (RCT2_GLOBAL(0x00F3EF8E, uint16) >> 3) & 0xFF; + int dh = dl - 2; + + if (x >= 256 || y >= 256) + goto loc_6A79B0; + + mapElement = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[y * 256 + x]; + do { + if ((mapElement->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_PATH) { + if (mapElement->base_height == dl) { + if (mapElement->properties.path.type & 4) + if (((mapElement->properties.path.type & 3) ^ 2) != RCT2_GLOBAL(0x00F3EF90, uint8)) + continue; + goto loc_6A78EF; + } else if (mapElement->base_height == dh) { + if (!(mapElement->properties.path.type & 4)) + if ((mapElement->properties.path.type & 3) == RCT2_GLOBAL(0x00F3EF90, uint8)) + continue; + goto loc_6A78EF; + } + } + lastTile = (mapElement->flags & MAP_ELEMENT_FLAG_LAST_TILE) != 0; + mapElement++; + } while (!lastTile); + goto loc_6A79B0; + +loc_6A78EF: + dl = mapElement->base_height; + int pathType = mapElement->properties.path.type; + if (pathType & 4) { + pathType &= 3; + pathType ^= 2; + if (pathType == RCT2_GLOBAL(0x00F3EF90, uint8)) + dl += 2; + } + + // Find a connected edge + int edge = RCT2_GLOBAL(0x00F3EF90, uint8) ^ 2; + if (!(mapElement->properties.path.edges & (1 << edge))) { + edge = (edge + 1) % 4; + if (!(mapElement->properties.path.edges & (1 << edge))) { + edge = (edge + 2) % 4; + if (!(mapElement->properties.path.edges & (1 << edge))) { + edge = (edge - 1) % 4; + if (!(mapElement->properties.path.edges & (1 << edge))) + edge ^= 2; + } + } + } + + // Remove path + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, uint16) = STR_CANT_REMOVE_FOOTPATH_FROM_HERE; + RCT2_CALLPROC_X(0x006677F2, RCT2_GLOBAL(0x00F3EF8A, uint16), 1, RCT2_GLOBAL(0x00F3EF8C, uint16), mapElement->base_height, 19, 0, 0); + + // Move selection + edge ^= 2; + x = RCT2_GLOBAL(0x00F3EF8A, uint16) - RCT2_GLOBAL(0x00993CCC + (edge * 4), sint16); + y = RCT2_GLOBAL(0x00F3EF8C, uint16) - RCT2_GLOBAL(0x00993CCE + (edge * 4), sint16); + RCT2_GLOBAL(0x00F3EF8A, uint16) = x; + RCT2_GLOBAL(0x00F3EF8C, uint16) = y; + RCT2_GLOBAL(0x00F3EF8E, uint16) = dl << 3; + RCT2_GLOBAL(0x00F3EF90, uint8) = edge; + RCT2_GLOBAL(0x00F3EF9E, uint8) = 255; + +loc_6A79B0: + RCT2_CALLPROC_EBPSAFE(0x006A855C); } \ No newline at end of file diff --git a/src/window_park.c b/src/window_park.c index 39b17519ae..84ef1b2c42 100644 --- a/src/window_park.c +++ b/src/window_park.c @@ -759,10 +759,10 @@ static void window_park_entrance_dropdown() if (dropdownIndex != 0) { dropdownIndex &= 0x00FF; dropdownIndex |= 0x0100; - RCT2_GLOBAL(0x0141E9AE, uint16) = 1724; + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, uint16) = STR_CANT_CLOSE_PARK; } else { dropdownIndex &= 0x00FF; - RCT2_GLOBAL(0x0141E9AE, uint16) = 1723; + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, uint16) = STR_CANT_OPEN_PARK; } RCT2_CALLPROC_X(0x006677F2, 0, 1, 0, dropdownIndex, 34, 0, 0); } @@ -886,7 +886,7 @@ static void window_park_entrance_textinput() if (widgetIndex == WIDX_RENAME) { if (result) { - RCT2_GLOBAL(0x0141E9AE, uint16) = STR_CANT_RENAME_PARK; + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, uint16) = STR_CANT_RENAME_PARK; RCT2_CALLPROC_X(0x006677F2, 1, 1, 0, *((int*)(text + 0)), '!', *((int*)(text + 8)), *((int*)(text + 4))); RCT2_CALLPROC_X(0x006677F2, 2, 1, 0, *((int*)(text + 12)), '!', *((int*)(text + 20)), *((int*)(text + 16))); RCT2_CALLPROC_X(0x006677F2, 0, 1, 0, *((int*)(text + 24)), '!', *((int*)(text + 32)), *((int*)(text + 28))); From 8c28dbaaeffc1cf55f7c097daa96e5ea478f0cf0 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Thu, 1 May 2014 09:18:29 +0200 Subject: [PATCH 10/37] Name peep variables for current train and car --- src/news_item.c | 8 +++++--- src/peep.h | 4 ++-- src/ride.h | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/news_item.c b/src/news_item.c index 71067660fb..42ba491aee 100644 --- a/src/news_item.c +++ b/src/news_item.c @@ -214,9 +214,11 @@ void news_item_get_subject_location(int type, int subject, int *x, int *y, int * break; } - sprite_2 = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[ride->var_086[sprite->peep.var_6A]]); - for (i = 0; i < sprite->peep.var_6B; i++) - sprite_2 = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[*((uint16*)&sprite_2->pad_00[0x3E])]); + // Find the train peep is on + sprite_2 = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[ride->train_car_map[sprite->peep.current_train]]); + // Find the car peep is on + for (i = 0; i < sprite->peep.current_car; i++) + sprite_2 = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[*((uint16*)&sprite_2->pad_00[0x3e])]); *x = sprite_2->unknown.x; *y = sprite_2->unknown.y; *z = sprite_2->unknown.z; diff --git a/src/peep.h b/src/peep.h index 335cbedf0b..b2574bec2b 100644 --- a/src/peep.h +++ b/src/peep.h @@ -72,8 +72,8 @@ typedef struct { uint8 happiness; // 0x3A uint8 pad_03B[0x2D]; uint8 current_ride; // 0x68 - uint8 var_6A; - uint8 var_6B; + uint8 current_train; // 0x6A + uint8 current_car; // 0x6B uint8 pad_6C[0x30]; uint32 id; // 0x9C uint8 pad_A0[0x10]; diff --git a/src/ride.h b/src/ride.h index 8d7294bfd3..ff90abd0e8 100644 --- a/src/ride.h +++ b/src/ride.h @@ -38,7 +38,7 @@ typedef struct { uint8 pad_052[0x18]; uint16 var_06A[4]; // probably entrance map coordinates uint8 pad_072[0x14]; - uint16 var_086[1]; + uint16 train_car_map[1]; // 0x86 Points to the first car in the train uint8 pad_088[0x68]; sint16 excitement; // 0x0F0 sint16 intensity; // 0x0F2 From d5ff2f27818fc35023fa25ffcce274db906db6f9 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Thu, 1 May 2014 13:16:41 +0200 Subject: [PATCH 11/37] Fix finding peep on ride news items Peep's current_* variables were offset by 1. Also fixed comparison between 32-bit and 16-bit ints. --- src/news_item.c | 6 ++++-- src/peep.h | 8 +++++--- src/window_game_bottom_toolbar.c | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/news_item.c b/src/news_item.c index 42ba491aee..f23bdf7408 100644 --- a/src/news_item.c +++ b/src/news_item.c @@ -200,7 +200,7 @@ void news_item_get_subject_location(int type, int subject, int *x, int *y, int * *x = sprite->unknown.x; *y = sprite->unknown.y; *z = sprite->unknown.z; - if (*x != SPRITE_LOCATION_NULL) + if (*((uint16*)x) != SPRITE_LOCATION_NULL) break; if (sprite->peep.state != 3 && sprite->peep.state != 7) { @@ -208,8 +208,10 @@ void news_item_get_subject_location(int type, int subject, int *x, int *y, int * break; } + // Find which ride peep is on ride = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[sprite->peep.current_ride]); - if (ride->var_1D0 & 1) { + // Check if there are trains on the track (first bit of var_1D0) + if (!(ride->var_1D0 & 1)) { *x = SPRITE_LOCATION_NULL; break; } diff --git a/src/peep.h b/src/peep.h index b2574bec2b..40beea32d5 100644 --- a/src/peep.h +++ b/src/peep.h @@ -72,9 +72,11 @@ typedef struct { uint8 happiness; // 0x3A uint8 pad_03B[0x2D]; uint8 current_ride; // 0x68 - uint8 current_train; // 0x6A - uint8 current_car; // 0x6B - uint8 pad_6C[0x30]; + uint8 pad_6a; // 0x6A Part of current_ride? + uint8 current_train; // 0x6B + uint8 current_car; // 0x6c + uint8 current_seat; // 0x6d + uint8 pad_6C[0x2e]; uint32 id; // 0x9C uint8 pad_A0[0x10]; rct_peep_thought thoughts[PEEP_MAX_THOUGHTS]; // 0xB0 diff --git a/src/window_game_bottom_toolbar.c b/src/window_game_bottom_toolbar.c index d24152414d..721b189ee6 100644 --- a/src/window_game_bottom_toolbar.c +++ b/src/window_game_bottom_toolbar.c @@ -185,7 +185,7 @@ static void window_game_bottom_toolbar_mouseup() news_item_get_subject_location(newsItem->type, subject, &x, &y, &z); - if (x == SPRITE_LOCATION_NULL) + if ((uint16)x == SPRITE_LOCATION_NULL) break; if ((mainWindow = window_get_main()) != NULL) From 6c550cbdd65f799c7ceb1183f7b4e57fe4ac79a1 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Thu, 1 May 2014 13:23:18 +0200 Subject: [PATCH 12/37] Change peep news item enum names --- src/news_item.c | 4 ++-- src/news_item.h | 4 ++-- src/window_game_bottom_toolbar.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/news_item.c b/src/news_item.c index f23bdf7408..bbb0be3386 100644 --- a/src/news_item.c +++ b/src/news_item.c @@ -195,7 +195,7 @@ void news_item_get_subject_location(int type, int subject, int *x, int *y, int * *z = edx; } break; - case NEWS_ITEM_PEEP_1: + case NEWS_ITEM_PEEP_ON_RIDE: sprite = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[subject]); *x = sprite->unknown.x; *y = sprite->unknown.y; @@ -225,7 +225,7 @@ void news_item_get_subject_location(int type, int subject, int *x, int *y, int * *y = sprite_2->unknown.y; *z = sprite_2->unknown.z; break; - case NEWS_ITEM_PEEP_2: + case NEWS_ITEM_PEEP: sprite = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[subject]); *x = sprite->unknown.x; *y = sprite->unknown.y; diff --git a/src/news_item.h b/src/news_item.h index 547b85e293..be8dd55e42 100644 --- a/src/news_item.h +++ b/src/news_item.h @@ -26,8 +26,8 @@ enum { NEWS_ITEM_NULL, NEWS_ITEM_RIDE, - NEWS_ITEM_PEEP_1, - NEWS_ITEM_PEEP_2, + NEWS_ITEM_PEEP_ON_RIDE, + NEWS_ITEM_PEEP, NEWS_ITEM_MONEY, NEWS_ITEM_BLANK, NEWS_ITEM_SCENERY, diff --git a/src/window_game_bottom_toolbar.c b/src/window_game_bottom_toolbar.c index 721b189ee6..2df493d1da 100644 --- a/src/window_game_bottom_toolbar.c +++ b/src/window_game_bottom_toolbar.c @@ -533,8 +533,8 @@ static void window_game_bottom_toolbar_draw_news_item(rct_drawpixelinfo *dpi, rc case NEWS_ITEM_RIDE: gfx_draw_sprite(dpi, SPR_RIDE, x, y); break; - case NEWS_ITEM_PEEP_1: - case NEWS_ITEM_PEEP_2: + case NEWS_ITEM_PEEP_ON_RIDE: + case NEWS_ITEM_PEEP: if (newsItem->flags & 1) break; From 63df868422c9744fd6d4536316712051a3513b5e Mon Sep 17 00:00:00 2001 From: ZedThree Date: Thu, 1 May 2014 14:02:28 +0200 Subject: [PATCH 13/37] Add rct_car sprite and tidy up news locator Also add (x,y,z) coordinate variables for rct_peep --- src/news_item.c | 35 ++++++++++++++++++----------------- src/peep.h | 5 ++++- src/sprite.h | 11 +++++++++++ 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/news_item.c b/src/news_item.c index bbb0be3386..0ddf9aa137 100644 --- a/src/news_item.c +++ b/src/news_item.c @@ -174,7 +174,8 @@ void news_item_get_subject_location(int type, int subject, int *x, int *y, int * { int i; rct_ride *ride; - rct_sprite *sprite, *sprite_2; + rct_peep *peep; + rct_car *car; switch (type) { case NEWS_ITEM_RIDE: @@ -196,20 +197,20 @@ void news_item_get_subject_location(int type, int subject, int *x, int *y, int * } break; case NEWS_ITEM_PEEP_ON_RIDE: - sprite = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[subject]); - *x = sprite->unknown.x; - *y = sprite->unknown.y; - *z = sprite->unknown.z; + peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[subject]); + *x = peep->x; + *y = peep->y; + *z = peep->z; if (*((uint16*)x) != SPRITE_LOCATION_NULL) break; - if (sprite->peep.state != 3 && sprite->peep.state != 7) { + if (peep->state != 3 && peep->state != 7) { *x = SPRITE_LOCATION_NULL; break; } // Find which ride peep is on - ride = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[sprite->peep.current_ride]); + ride = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[peep->current_ride]); // Check if there are trains on the track (first bit of var_1D0) if (!(ride->var_1D0 & 1)) { *x = SPRITE_LOCATION_NULL; @@ -217,19 +218,19 @@ void news_item_get_subject_location(int type, int subject, int *x, int *y, int * } // Find the train peep is on - sprite_2 = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[ride->train_car_map[sprite->peep.current_train]]); + car = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[ride->train_car_map[peep->current_train]]); // Find the car peep is on - for (i = 0; i < sprite->peep.current_car; i++) - sprite_2 = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[*((uint16*)&sprite_2->pad_00[0x3e])]); - *x = sprite_2->unknown.x; - *y = sprite_2->unknown.y; - *z = sprite_2->unknown.z; + for (i = 0; i < peep->current_car; i++) + car = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[car->next_car]); + *x = car->x; + *y = car->y; + *z = car->z; break; case NEWS_ITEM_PEEP: - sprite = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[subject]); - *x = sprite->unknown.x; - *y = sprite->unknown.y; - *z = sprite->unknown.z; + peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[subject]); + *x = peep->x; + *y = peep->y; + *z = peep->z; break; case NEWS_ITEM_BLANK: { diff --git a/src/peep.h b/src/peep.h index 40beea32d5..2e071d3c1e 100644 --- a/src/peep.h +++ b/src/peep.h @@ -55,7 +55,10 @@ typedef struct { uint8 pad_09; sint16 var_0A; uint16 var_0C; - uint8 var_0E[0x14]; + sint16 x; // 0x0E + sint16 y; // 0x10 + sint16 z; // 0x12 + uint8 pad_14[0x0E]; uint16 name_string_idx; // 0x22 uint16 next_x; // 0x24 uint16 next_y; // 0x26 diff --git a/src/sprite.h b/src/sprite.h index eea99b11b3..57efead6cb 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -46,6 +46,16 @@ typedef struct { sint32 var_24; } rct_litter; +typedef struct { + uint8 sprite_idetifier; // 0x00 + uint8 pad_01[0x0D]; + sint16 x; // 0x0E + sint16 y; // 0x10 + sint16 z; // 0x12 + uint8 pad_14[0x2a]; + uint16 next_car; // 0x3E +} rct_car; + /** * Sprite structure. * size: 0x0100 @@ -55,6 +65,7 @@ typedef union { rct_unk_sprite unknown; rct_peep peep; rct_litter litter; + rct_car car; } rct_sprite; #endif From a5c85f0cbecfd8c4a14baaef91a086fb2ec5490e Mon Sep 17 00:00:00 2001 From: ZedThree Date: Thu, 1 May 2014 14:12:30 +0200 Subject: [PATCH 14/37] Fix comments --- src/news_item.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/news_item.c b/src/news_item.c index 0ddf9aa137..f09f7f19c8 100644 --- a/src/news_item.c +++ b/src/news_item.c @@ -217,9 +217,9 @@ void news_item_get_subject_location(int type, int subject, int *x, int *y, int * break; } - // Find the train peep is on + // Find the first car of the train peep is on car = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[ride->train_car_map[peep->current_train]]); - // Find the car peep is on + // Find the actual car peep is on for (i = 0; i < peep->current_car; i++) car = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[car->next_car]); *x = car->x; From ae637f62913ef9d8491a52730fc25a92c7579d8f Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Thu, 1 May 2014 14:13:31 +0100 Subject: [PATCH 15/37] fix case and add author to source code header --- src/peep.h | 4 ++-- src/ride.h | 2 +- src/sprite.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/peep.h b/src/peep.h index 2e071d3c1e..62f8b75602 100644 --- a/src/peep.h +++ b/src/peep.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014 Ted John + * Copyright (c) 2014 Ted John, Peter Hill * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. * * This file is part of OpenRCT2. @@ -77,7 +77,7 @@ typedef struct { uint8 current_ride; // 0x68 uint8 pad_6a; // 0x6A Part of current_ride? uint8 current_train; // 0x6B - uint8 current_car; // 0x6c + uint8 current_car; // 0x6C uint8 current_seat; // 0x6d uint8 pad_6C[0x2e]; uint32 id; // 0x9C diff --git a/src/ride.h b/src/ride.h index ff90abd0e8..d7a251dbeb 100644 --- a/src/ride.h +++ b/src/ride.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014 Ted John + * Copyright (c) 2014 Ted John, Peter Hill * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. * * This file is part of OpenRCT2. diff --git a/src/sprite.h b/src/sprite.h index 57efead6cb..5a3a071ba0 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014 Ted John + * Copyright (c) 2014 Ted John, Peter Hill * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. * * This file is part of OpenRCT2. From 95649ba942daf68955b7b690f0e51dc98521a569 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Thu, 1 May 2014 22:55:26 +0100 Subject: [PATCH 16/37] Added happy peeps cheat. Labeled Bathroom peep offset. --- src/peep.h | 3 +- src/window_cheats.c | 127 +++++++++++++++++++++++++++++++++++++++----- 2 files changed, 115 insertions(+), 15 deletions(-) diff --git a/src/peep.h b/src/peep.h index d167afc2fb..1d4b092350 100644 --- a/src/peep.h +++ b/src/peep.h @@ -80,7 +80,8 @@ typedef struct { uint8 var_03D; uint8 hunger; // 0x3E uint8 thirst; // 0x3F - uint8 pad_040[0x28]; + uint8 bathroom; // 0x40 + uint8 pad_041[0x27]; uint8 current_ride; // 0x68 uint8 pad_6a; // 0x6A Part of current_ride? uint8 current_train; // 0x6B diff --git a/src/window_cheats.c b/src/window_cheats.c index 8e09e207cc..60861bb94f 100644 --- a/src/window_cheats.c +++ b/src/window_cheats.c @@ -21,11 +21,14 @@ #include #include "addresses.h" #include "park.h" +#include "peep.h" #include "strings.h" +#include "sprite.h" #include "sprites.h" #include "widget.h" #include "window.h" + #define WW 200 #define WH 128 @@ -41,10 +44,11 @@ static enum WINDOW_CHEATS_WIDGET_IDX { WIDX_PAGE_BACKGROUND, WIDX_TAB_1, WIDX_TAB_2, - WIDX_HIGH_MONEY + WIDX_HIGH_MONEY, + WIDX_HAPPY_GUESTS }; -static rct_widget window_cheats_widgets[] = { +static rct_widget window_cheats_money_widgets[] = { { WWT_FRAME, 0, 0, WW - 1, 0, WH - 1, 0x0FFFFFFFF, 65535}, // panel / background { WWT_CAPTION, 0, 1, WW - 2, 1, 14, 3165, STR_WINDOW_TITLE_TIP}, // title bar { WWT_CLOSEBOX, 0, WW - 13, WW - 3, 2, 13, 0x338, STR_CLOSE_WINDOW_TIP}, // close x button @@ -55,13 +59,30 @@ static rct_widget window_cheats_widgets[] = { { WIDGETS_END }, }; +static rct_widget window_cheats_guests_widgets[] = { + { WWT_FRAME, 0, 0, WW - 1, 0, WH - 1, 0x0FFFFFFFF, 65535 }, // panel / background + { WWT_CAPTION, 0, 1, WW - 2, 1, 14, 3165, STR_WINDOW_TITLE_TIP }, // title bar + { WWT_CLOSEBOX, 0, WW - 13, WW - 3, 2, 13, 0x338, STR_CLOSE_WINDOW_TIP }, // close x button + { WWT_IMGBTN, 1, 0, WW - 1, 43, WH - 1, 0x0FFFFFFFF, 65535 }, // tab content panel + { WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, 2462 }, // tab 1 + { WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, 2462 }, // tab 2 + { WWT_CLOSEBOX, 1, 4, 74, 47, 63, 2375, 2375 }, // happy guests + { WIDGETS_END }, +}; + +static rct_widget *window_cheats_page_widgets[] = { + window_cheats_money_widgets, + window_cheats_guests_widgets +}; + static void window_cheats_emptysub() { } static void window_cheats_mouseup(); static void window_cheats_update(); static void window_cheats_invalidate(); static void window_cheats_paint(); +static void window_cheats_set_page(rct_window *w, int page); -static uint32 window_cheats_events[] = { +static uint32 window_cheats_money_events[] = { window_cheats_emptysub, window_cheats_mouseup, window_cheats_emptysub, @@ -92,6 +113,47 @@ static uint32 window_cheats_events[] = { window_cheats_emptysub }; +static uint32 window_cheats_guests_events[] = { + window_cheats_emptysub, + window_cheats_mouseup, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_update, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_emptysub, + window_cheats_invalidate, + window_cheats_paint, + window_cheats_emptysub +}; + +static uint32 *window_cheats_page_events[] = { + window_cheats_money_events, + window_cheats_guests_events, +}; + +static uint32 window_cheats_page_enabled_widgets[] = { + (1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | (1 << WIDX_TAB_2) | (1 << WIDX_HIGH_MONEY), + (1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | (1 << WIDX_TAB_2) | (1 << WIDX_HIGH_MONEY) //Change to WIDX_HAPPY_GUESTSs when enabled widgets is figured out. +}; + static void window_cheats_draw_tab_images(rct_drawpixelinfo *dpi, rct_window *w); void window_cheats_open() @@ -103,11 +165,10 @@ void window_cheats_open() if (window != NULL) return; - window = window_create(32, 32, WW, WH, window_cheats_events, WC_CHEATS, 0); - window->widgets = window_cheats_widgets; - window->enabled_widgets = (1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | (1 << WIDX_TAB_2) | (1 << WIDX_HIGH_MONEY); + window = window_create(32, 32, WW, WH, window_cheats_money_events, WC_CHEATS, 0); + window->widgets = window_cheats_money_widgets; + window->enabled_widgets = window_cheats_page_enabled_widgets[0]; window_init_scroll_widgets(window); - window->page = WINDOW_CHEATS_PAGE_MONEY; window->colours[0] = 1; window->colours[1] = 19; @@ -122,16 +183,37 @@ static void window_cheats_mouseup() __asm mov widgetIndex, dx __asm mov w, esi + rct_peep* peep; + uint16 sprite_idx; switch (widgetIndex) { case WIDX_CLOSE: window_close(w); break; + case WIDX_TAB_1: + case WIDX_TAB_2: + window_cheats_set_page(w, widgetIndex - WIDX_TAB_1); + break; case WIDX_HIGH_MONEY: - i = DECRYPT_MONEY(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint32)); - i += 100000; - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint32) = ENCRYPT_MONEY(i); - + if (w->page == WINDOW_CHEATS_PAGE_MONEY){ + i = DECRYPT_MONEY(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint32)); + i += 100000; + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint32) = ENCRYPT_MONEY(i); + } + else{ + for (sprite_idx = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); sprite_idx != SPRITE_INDEX_NULL; sprite_idx = peep->next) { + peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[sprite_idx].peep); + if (peep->type != PEEP_TYPE_GUEST) + continue; + if (peep->var_2A != 0) + continue; + peep->happiness = 255; + } + } + window_invalidate_by_id(0x40 | WC_BOTTOM_TOOLBAR, 0); + break; + case WIDX_HAPPY_GUESTS: + //At present HAPPY_GUESTS does not activate window_invalidate_by_id(0x40 | WC_BOTTOM_TOOLBAR, 0); break; } @@ -144,7 +226,7 @@ static void window_cheats_update() __asm mov w, esi w->var_48E++; - widget_invalidate(w->classification, w->number, WIDX_TAB_1); + widget_invalidate(w->classification, w->number, WIDX_TAB_1+w->page); } static void window_cheats_invalidate() @@ -153,9 +235,14 @@ static void window_cheats_invalidate() rct_window *w; __asm mov w, esi - strcpy((char*)0x009BC677, "Cheats"); + rct_widget **widgets = window_cheats_page_widgets[w->page]; + if (w->widgets != widgets) { + w->widgets = widgets; + window_init_scroll_widgets(w); + } + // Set correct active tab for (i = 0; i < 7; i++) w->pressed_widgets &= ~(1 << (WIDX_TAB_1 + i)); @@ -190,7 +277,19 @@ static void window_cheats_draw_tab_images(rct_drawpixelinfo *dpi, rct_window *w) if (!(w->disabled_widgets & (1 << WIDX_TAB_2))) { sprite_idx = 5568; if (w->page == WINDOW_CHEATS_PAGE_GUESTS) - sprite_idx += w->var_48E / 4; + sprite_idx += (w->var_48E / 2) % 8; gfx_draw_sprite(dpi, sprite_idx, w->x + w->widgets[WIDX_TAB_2].left, w->y + w->widgets[WIDX_TAB_2].top); } } + +static void window_cheats_set_page(rct_window *w, int page) +{ + w->page = page; + + w->enabled_widgets = window_cheats_page_enabled_widgets[page]; + + w->event_handlers = window_cheats_page_events[page]; + w->widgets = window_cheats_page_widgets[page]; + + window_invalidate(w); +} \ No newline at end of file From d524ad16228bf0bc16958edc2c4e3da6a4253f89 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Fri, 2 May 2014 03:06:30 +0100 Subject: [PATCH 17/37] make footpath window use game_do_command --- src/window_footpath.c | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/src/window_footpath.c b/src/window_footpath.c index e9d54c4237..2ff607f8a9 100644 --- a/src/window_footpath.c +++ b/src/window_footpath.c @@ -21,6 +21,7 @@ #include #include "addresses.h" #include "audio.h" +#include "game.h" #include "map.h" #include "strings.h" #include "sprites.h" @@ -691,14 +692,7 @@ static int window_footpath_set_provisional_path(int type, int x, int y, int z, i RCT2_CALLPROC_EBPSAFE(0x006A77FF); // Try and show provisional path - eax = x; - ebx = (slope << 8) | 121; - ecx = y; - edx = (type << 8) | z; - esi = 17; - edi = 0; - RCT2_CALLFUNC_X(0x006677F2, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - cost = ebx; + cost = game_do_command(x, (slope << 8) | 121, y, (type << 8) | z, 17, 0, 0); if (cost != 0x80000000) { RCT2_GLOBAL(0x00F3EF94, uint16) = x; @@ -721,7 +715,7 @@ static int window_footpath_set_provisional_path(int type, int x, int y, int z, i */ static void window_footpath_place_path_at_point(int x, int y) { - int z, slope, type, cost; + int z, presentType, selectedType, cost; rct_map_element *mapElement; if (RCT2_GLOBAL(0x00F3EF9F, uint8) != 0) @@ -744,24 +738,17 @@ static void window_footpath_place_path_at_point(int x, int y) return; // Set path - slope = RCT2_ADDRESS(0x0098D8B4, uint8)[mapElement->properties.surface.slope & 0x1F]; - z = mapElement->base_height; + presentType = RCT2_ADDRESS(0x0098D8B4, uint8)[mapElement->properties.path.type & 0x1F]; if (z == 6) - slope = mapElement->properties.surface.slope & 7; - type = (RCT2_GLOBAL(0x00F3EFA2, uint8) << 7) + RCT2_GLOBAL(0x00F3EFA0, uint8); + presentType = mapElement->properties.path.type & 7; + z = mapElement->base_height; + selectedType = (RCT2_GLOBAL(0x00F3EFA2, uint8) << 7) + RCT2_GLOBAL(0x00F3EFA0, uint8); // Prepare error text RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, uint16) = STR_CANT_BUILD_FOOTPATH_HERE; // Try and place path - eax = x; - ebx = (slope << 8) | 1; - ecx = y; - edx = (type << 8) | z; - esi = 17; - edi = 0; - RCT2_CALLFUNC_X(0x006677F2, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - cost = ebx; + cost = game_do_command(x, (presentType << 8) | 1, y, (selectedType << 8) | z, 17, 0, 0); if (cost == 0x80000000) { RCT2_GLOBAL(0x00F3EF9F, uint8) = 1; @@ -850,7 +837,7 @@ loc_6A78EF: // Remove path RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, uint16) = STR_CANT_REMOVE_FOOTPATH_FROM_HERE; - RCT2_CALLPROC_X(0x006677F2, RCT2_GLOBAL(0x00F3EF8A, uint16), 1, RCT2_GLOBAL(0x00F3EF8C, uint16), mapElement->base_height, 19, 0, 0); + game_do_command(RCT2_GLOBAL(0x00F3EF8A, uint16), 1, RCT2_GLOBAL(0x00F3EF8C, uint16), mapElement->base_height, 19, 0, 0); // Move selection edge ^= 2; From 168df9171a0c1325f86c89e5809ff2df08c3746a Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Fri, 2 May 2014 06:59:12 +0100 Subject: [PATCH 18/37] Added seperate mouseup events so that happy cheat works. --- src/window_cheats.c | 68 ++++++++++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 26 deletions(-) diff --git a/src/window_cheats.c b/src/window_cheats.c index 60861bb94f..80b741bc6b 100644 --- a/src/window_cheats.c +++ b/src/window_cheats.c @@ -45,7 +45,7 @@ static enum WINDOW_CHEATS_WIDGET_IDX { WIDX_TAB_1, WIDX_TAB_2, WIDX_HIGH_MONEY, - WIDX_HAPPY_GUESTS + WIDX_HAPPY_GUESTS = 6 //Same as HIGH_MONEY as it is also the 6th widget but on a different page }; static rct_widget window_cheats_money_widgets[] = { @@ -66,7 +66,7 @@ static rct_widget window_cheats_guests_widgets[] = { { WWT_IMGBTN, 1, 0, WW - 1, 43, WH - 1, 0x0FFFFFFFF, 65535 }, // tab content panel { WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, 2462 }, // tab 1 { WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, 2462 }, // tab 2 - { WWT_CLOSEBOX, 1, 4, 74, 47, 63, 2375, 2375 }, // happy guests + { WWT_CLOSEBOX, 1, 4, 74, 47, 63, 2376, 2376 }, // happy guests { WIDGETS_END }, }; @@ -76,7 +76,8 @@ static rct_widget *window_cheats_page_widgets[] = { }; static void window_cheats_emptysub() { } -static void window_cheats_mouseup(); +static void window_cheats_money_mouseup(); +static void window_cheats_guests_mouseup(); static void window_cheats_update(); static void window_cheats_invalidate(); static void window_cheats_paint(); @@ -84,7 +85,7 @@ static void window_cheats_set_page(rct_window *w, int page); static uint32 window_cheats_money_events[] = { window_cheats_emptysub, - window_cheats_mouseup, + window_cheats_money_mouseup, window_cheats_emptysub, window_cheats_emptysub, window_cheats_emptysub, @@ -115,7 +116,7 @@ static uint32 window_cheats_money_events[] = { static uint32 window_cheats_guests_events[] = { window_cheats_emptysub, - window_cheats_mouseup, + window_cheats_guests_mouseup, window_cheats_emptysub, window_cheats_emptysub, window_cheats_emptysub, @@ -151,7 +152,7 @@ static uint32 *window_cheats_page_events[] = { static uint32 window_cheats_page_enabled_widgets[] = { (1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | (1 << WIDX_TAB_2) | (1 << WIDX_HIGH_MONEY), - (1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | (1 << WIDX_TAB_2) | (1 << WIDX_HIGH_MONEY) //Change to WIDX_HAPPY_GUESTSs when enabled widgets is figured out. + (1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | (1 << WIDX_TAB_2) | (1 << WIDX_HAPPY_GUESTS) }; static void window_cheats_draw_tab_images(rct_drawpixelinfo *dpi, rct_window *w); @@ -175,7 +176,33 @@ void window_cheats_open() window->colours[2] = 19; } -static void window_cheats_mouseup() +static void window_cheats_money_mouseup() +{ + int i; + short widgetIndex; + rct_window *w; + + __asm mov widgetIndex, dx + __asm mov w, esi + + switch (widgetIndex) { + case WIDX_CLOSE: + window_close(w); + break; + case WIDX_TAB_1: + case WIDX_TAB_2: + window_cheats_set_page(w, widgetIndex - WIDX_TAB_1); + break; + case WIDX_HIGH_MONEY: + i = DECRYPT_MONEY(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint32)); + i += 100000; + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint32) = ENCRYPT_MONEY(i); + window_invalidate_by_id(0x40 | WC_BOTTOM_TOOLBAR, 0); + break; + } +} + +static void window_cheats_guests_mouseup() { int i; short widgetIndex; @@ -194,26 +221,15 @@ static void window_cheats_mouseup() case WIDX_TAB_2: window_cheats_set_page(w, widgetIndex - WIDX_TAB_1); break; - case WIDX_HIGH_MONEY: - if (w->page == WINDOW_CHEATS_PAGE_MONEY){ - i = DECRYPT_MONEY(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint32)); - i += 100000; - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint32) = ENCRYPT_MONEY(i); - } - else{ - for (sprite_idx = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); sprite_idx != SPRITE_INDEX_NULL; sprite_idx = peep->next) { - peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[sprite_idx].peep); - if (peep->type != PEEP_TYPE_GUEST) - continue; - if (peep->var_2A != 0) - continue; - peep->happiness = 255; - } - } - window_invalidate_by_id(0x40 | WC_BOTTOM_TOOLBAR, 0); - break; case WIDX_HAPPY_GUESTS: - //At present HAPPY_GUESTS does not activate + for (sprite_idx = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); sprite_idx != SPRITE_INDEX_NULL; sprite_idx = peep->next) { + peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[sprite_idx].peep); + if (peep->type != PEEP_TYPE_GUEST) + continue; + if (peep->var_2A != 0) + continue; + peep->happiness = 255; + } window_invalidate_by_id(0x40 | WC_BOTTOM_TOOLBAR, 0); break; } From a3a8c1248f75a2b0634f217f12b77b38eda3bee5 Mon Sep 17 00:00:00 2001 From: Inseok Lee Date: Fri, 2 May 2014 21:32:44 +0900 Subject: [PATCH 19/37] Implement loading savefile from commandline argument. --- src/rct2.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/rct2.c b/src/rct2.c index df687dca0c..e8f5ef2e92 100644 --- a/src/rct2.c +++ b/src/rct2.c @@ -191,6 +191,53 @@ void rct2_update() rct2_update_2(); } +void check_cmdline_arg() +{ + if(RCT2_GLOBAL(0x009AC310, uint32) == 0xFFFFFFFF) + return; + + char *arg = RCT2_GLOBAL(0x009AC310, char *); + char processed_arg[255]; + int len, i, j; + int quote = 0; + int last_period = 0; + + RCT2_GLOBAL(0x009AC310, uint32) = 0xFFFFFFFF; + len = strlen(arg); + + for(i = 0, j = 0; i < len; i ++) + { + if(arg[i] == '\"') + { + if(quote) + quote = 0; + else + quote = 1; + continue; + } + if(arg[i] == ' ' && !quote) + break; + if(arg[i] == '.') + last_period = i; + processed_arg[j ++] = arg[i]; + } + processed_arg[j ++] = 0; + + if(!stricmp(processed_arg + last_period, "sv6")) + { + strcpy(0x00141EF68, processed_arg); + RCT2_CALLPROC_EBPSAFE(0x00675E1B); //load_saved_game + } + else if(!stricmp(processed_arg + last_period, "sc6")) + { + //TODO: scenario install + } + else if(!stricmp(processed_arg + last_period, "td6") || !stricmp(processed_arg + last_period, "td4")) + { + //TODO: track design install + } +} + void rct2_update_2() { int tick, tick2; @@ -213,6 +260,7 @@ void rct2_update_2() // TODO: screenshot countdown process + check_cmdline_arg(); // Screens if (RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) != 0) intro_update(); From 8da8519b6f3e19078e6ed77d207f6ab04c984a2b Mon Sep 17 00:00:00 2001 From: Maciek Baron Date: Fri, 2 May 2014 21:07:20 +0100 Subject: [PATCH 20/37] Capping money in cheats --- src/window_cheats.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/window_cheats.c b/src/window_cheats.c index 8e09e207cc..d04b70c2b4 100644 --- a/src/window_cheats.c +++ b/src/window_cheats.c @@ -28,6 +28,7 @@ #define WW 200 #define WH 128 +#define CHEATS_MONEY_INCREMENT 10000 enum { WINDOW_CHEATS_PAGE_MONEY, @@ -129,7 +130,13 @@ static void window_cheats_mouseup() break; case WIDX_HIGH_MONEY: i = DECRYPT_MONEY(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint32)); - i += 100000; + + if (i < INT_MAX - CHEATS_MONEY_INCREMENT) { + i += CHEATS_MONEY_INCREMENT; + } + else { + i = INT_MAX; + } RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint32) = ENCRYPT_MONEY(i); window_invalidate_by_id(0x40 | WC_BOTTOM_TOOLBAR, 0); From ca81c5e06d6281fbec485b85552de93931334307 Mon Sep 17 00:00:00 2001 From: Maciek Baron Date: Fri, 2 May 2014 21:07:48 +0100 Subject: [PATCH 21/37] Adding enum with peep states --- src/peep.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/peep.h b/src/peep.h index 62f8b75602..6f0af308d7 100644 --- a/src/peep.h +++ b/src/peep.h @@ -38,6 +38,32 @@ enum PEEP_THOUGHT_TYPE { PEEP_THOUGHT_TYPE_NONE = 255 }; +enum PEEP_STATE { + + PEEP_STATE_QUEUING_FRONT = 2, + PEEP_STATE_ON_RIDE = 3, + PEEP_STATE_LEAVING_RIDE = 4, + PEEP_STATE_WALKING = 5, + PEEP_STATE_QUEUING = 6, + PEEP_STATE_ENTERING_RIDE = 7, + PEEP_STATE_SITTING = 8, + PEEP_STATE_PICKED = 9, + PEEP_STATE_PATROLLING = 10, // Not sure + PEEP_STATE_MOPING = 11, + PEEP_STATE_SWEEPING = 12, + PEEP_STATE_ENTERING_PARK = 13, + PEEP_STATE_LEAVING_PARK = 14, + PEEP_STATE_ANSWERING = 15, + PEEP_STATE_FIXING = 16, + PEEP_STATE_BUYING = 17, + PEEP_STATE_WATCHING = 18, + PEEP_STATE_EMPTYING_BIN = 19, + + PEEP_STATE_WATERING = 21, + PEEP_STATE_HEADING_TO_INSPECTION = 22, + PEEP_STATE_INSPECTING = 23 +}; + typedef struct { uint8 type; uint8 item; From 297043fecd439c385becc579aba4dca1459c6415 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Fri, 2 May 2014 21:25:42 +0200 Subject: [PATCH 22/37] Add map_element_height (finishes sub_662783) Possibly wrong for some slopes... --- src/map.c | 119 ++++++++++++++++++++++++++++++++++++++++++++---- src/map.h | 1 + src/news_item.c | 28 +++--------- src/news_item.h | 1 + src/title.c | 12 ++--- 5 files changed, 122 insertions(+), 39 deletions(-) diff --git a/src/map.c b/src/map.c index 1e2dc405bd..57a305981b 100644 --- a/src/map.c +++ b/src/map.c @@ -123,34 +123,135 @@ void map_update_tile_pointers() } /** - * + * Return the absolute height of an element, given its (x,y) coordinates + * * rct2: 0x00662783 * UNFINISHED */ -int sub_662783(int x, int y) +int map_element_height(int x, int y) { int i; rct_map_element *mapElement; + // Off the map if (x >= 8192 || y >= 8192) return 16; - x &= 0xFFFFFFE0; - y &= 0xFFFFFFE0; + // Find the tile the element is on + int x_tile = x & 0xFFFFFFE0; + int y_tile = y & 0xFFFFFFE0; - i = ((y * 256) + x) / 8; + i = ((y_tile * 256) + x_tile) / 32; mapElement = TILE_MAP_ELEMENT_POINTER(i); while (mapElement->type & MAP_ELEMENT_TYPE_MASK) { mapElement++; } - uint32 result = + uint32 height = ((mapElement->properties.surface.terrain & MAP_ELEMENT_WATER_HEIGHT_MASK) << 20) | (mapElement->base_height << 3); - uint32 ebx = (mapElement->properties.surface.slope & MAP_ELEMENT_SLOPE_MASK) & ~0x16; - // slope logic + uint32 slope = (mapElement->properties.surface.slope & MAP_ELEMENT_SLOPE_MASK); + uint8 extra_height = (slope & 0x10) >> 4; // 0x10 is the 5th bit - sets slope to double height + slope &= 0xF; - return result; + uint8 quad, quad_2; // which quadrant the element is in? + + uint8 xl, yl; + + uint8 TILE_SIZE = 31; + + xl = x & 0x1f; + yl = y & 0x1f; + + // slope logic + // slope == 0 is flat, and slope == 15 is not used + + // One corner up + if ((slope == 1) || (slope == 2) || (slope == 4) || (slope == 8)) { + switch(slope) { + case 1: // NE corner up + quad = xl + yl - TILE_SIZE; + break; + case 2: // SE corner up + quad = xl - yl; + break; + case 4: // SW corner up + quad = TILE_SIZE - yl - xl; + break; + case 8: // NW corner up + quad = xl - yl; + break; + } + if (quad > 0) { + height += quad / 2; + } + } + + // One side up + switch(slope) { + case 3: // E side up + height += xl / 2; + break; + case 6: // S side up + height += (TILE_SIZE - yl) / 2; + break; + case 9: // N side up + height += yl / 2; + height++; + break; + case 12: // W side up + height += (TILE_SIZE - xl) / 2; + break; + } + + // One corner down + if ((slope == 7) || (slope == 11) || (slope == 13) || (slope == 14)) { + switch(slope) { + case 7: // NW corner down + quad = xl + TILE_SIZE - yl; + quad_2 = xl - yl; + break; + case 11: // SW corner down + quad = xl + yl; + quad_2 = xl + yl - TILE_SIZE; + break; + case 13: // SE corner down + quad = TILE_SIZE - xl + yl; + quad_2 = xl - yl; + break; + case 14: // NE corner down + quad = (TILE_SIZE - xl) + (TILE_SIZE - yl); + quad_2 = TILE_SIZE - yl - xl; + break; + } + height += 0x10; + if (extra_height) { + height += quad / 2; + height++; + } + if (quad_2 < 0) { + height += quad_2 / 2; + height += 0xFF00; + } + } + + // Valleys + if (slope == 5) { // NW-SE valley + quad = xl + yl; + if (quad > TILE_SIZE + 1) { + quad = TILE_SIZE - xl - yl; + if (quad > 0) { + height += quad / 2; + } + } + } else if (slope == 10) { // NE-SW valley + if (xl > yl) { + quad = xl - yl; + height += quad / 2; + } + } + + return height; } diff --git a/src/map.h b/src/map.h index 8a42517699..5d0f1a655b 100644 --- a/src/map.h +++ b/src/map.h @@ -184,5 +184,6 @@ enum { void map_init(); void map_update_tile_pointers(); +int map_element_height(int x, int y); #endif diff --git a/src/news_item.c b/src/news_item.c index f09f7f19c8..3f50fbfd96 100644 --- a/src/news_item.c +++ b/src/news_item.c @@ -184,17 +184,9 @@ void news_item_get_subject_location(int type, int subject, int *x, int *y, int * *x = SPRITE_LOCATION_NULL; break; } - { - uint32 eax, ebx, ecx, edx, esi, edi, ebp; - eax = (ride->var_050 & 0xFF) * 32 + 16; - ecx = (ride->var_050 >> 8) * 32 + 16; - RCT2_CALLFUNC_X(0x00662783, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - if (edx & 0xFFFF0000) - edx >>= 16; - *x = eax; - *y = ecx; - *z = edx; - } + *x = (ride->var_050 & 0xFF) * 32 + 16; + *y = (ride->var_050 >> 8) * 32 + 16; + *z = map_element_height(*x, *y); break; case NEWS_ITEM_PEEP_ON_RIDE: peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[subject]); @@ -233,16 +225,10 @@ void news_item_get_subject_location(int type, int subject, int *x, int *y, int * *z = peep->z; break; case NEWS_ITEM_BLANK: - { - uint32 eax, ebx, ecx, edx, esi, edi, ebp; - eax = subject; - ecx = subject >> 16; - RCT2_CALLFUNC_X(0x00662783, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - *x = eax; - *y = ecx; - *z = edx; - } - break; + *x = subject; + *y = subject >> 16; + *z = map_element_height(x, y); + break; default: *x = SPRITE_LOCATION_NULL; break; diff --git a/src/news_item.h b/src/news_item.h index be8dd55e42..de12b44e22 100644 --- a/src/news_item.h +++ b/src/news_item.h @@ -22,6 +22,7 @@ #define _NEWS_ITEM_H_ #include "rct2.h" +#include "map.h" enum { NEWS_ITEM_NULL, diff --git a/src/title.c b/src/title.c index 61d2e78f52..6a85e4e6c0 100644 --- a/src/title.c +++ b/src/title.c @@ -152,7 +152,7 @@ static void title_update_showcase() { rct_window* w; uint8 script_opcode, script_operand; - short x, y; + short x, y, z; int i, _edx; if (_scriptWaitCounter <= 0) { @@ -201,18 +201,12 @@ static void title_update_showcase() case TITLE_SCRIPT_LOCATION: x = (*_currentScript++) * 32 + 16; y = (*_currentScript++) * 32 + 16; - - // Set location - int eax, ebx, ecx, edx, esi, edi, ebp; - eax = x; - ecx = y; - RCT2_CALLFUNC_X(0x00662783, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - _edx = edx; + z = map_element_height(x, y); // Update viewport w = window_get_main(); if (w != NULL) { - window_scroll_to_location(w, x, y, _edx); + window_scroll_to_location(w, x, y, z); w->flags &= ~0x08; viewport_update_position(w); } From c87ec51c28672dc9cbd6c0959869fd3495e78b56 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Fri, 2 May 2014 21:54:19 +0100 Subject: [PATCH 23/37] Labelled some of the peep financial offsets. --- src/peep.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/peep.h b/src/peep.h index 13b4343346..7b061639d3 100644 --- a/src/peep.h +++ b/src/peep.h @@ -101,8 +101,17 @@ typedef struct { uint16 pad_C4; uint8 var_C6; uint8 pad_C7; - uint32 var_C8; - uint8 pad_CC[0x2A]; + uint32 var_C8; //Bit 11 tracking, Bit 8 leaving the park + uint8 var_CC; //Bit 0 mad, bit 1 Ice Cream + uint8 pad_CD[0x18]; + uint16 paid_to_enter; //0xE5 Number is /10 when displayed + uint16 paid_on_rides; //0xE7 Number is /10 when displayed + uint16 paid_on_food; //0xE9 Number is /10 when displayed + uint16 paid_on_souvenirs; //0xEB Number is /10 when displayed + uint8 no_of_food; //0xEC + uint8 no_of_drinks; //0xED + uint8 no_of_souvenirs; //0xEE + uint8 pad_EF[0x07]; uint8 balloon_colour; // 0xF6 uint8 umbrella_colour; // 0xF7 uint8 hat_colour; // 0xF8 From af5ef5e75d4adae33582ecfe13462687a7c16cf7 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Fri, 2 May 2014 22:21:08 +0100 Subject: [PATCH 24/37] add game_load_or_quit function --- projects/openrct2.vcxproj | 1 + projects/openrct2.vcxproj.filters | 3 + src/game.c | 211 +++++++++++++++++++++++++++++- src/game.h | 2 + src/strings.h | 15 +++ src/window.h | 2 + src/window_save_prompt.c | 192 +++++++++++++++++++++++++++ 7 files changed, 420 insertions(+), 6 deletions(-) create mode 100644 src/window_save_prompt.c diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj index f948462979..831470a580 100644 --- a/projects/openrct2.vcxproj +++ b/projects/openrct2.vcxproj @@ -88,6 +88,7 @@ + diff --git a/projects/openrct2.vcxproj.filters b/projects/openrct2.vcxproj.filters index 181b6cd8bd..3b8344d289 100644 --- a/projects/openrct2.vcxproj.filters +++ b/projects/openrct2.vcxproj.filters @@ -257,6 +257,9 @@ Source Files + + Windows + diff --git a/src/game.c b/src/game.c index b83169e0d8..ea88c3a7c2 100644 --- a/src/game.c +++ b/src/game.c @@ -29,6 +29,7 @@ #include "peep.h" #include "screenshot.h" #include "strings.h" +#include "title.h" #include "tutorial.h" #include "widget.h" #include "window.h" @@ -986,6 +987,8 @@ static int game_check_affordability(int cost) return ebp; } +static uint32 game_do_command_table[58]; + /** * * rct2: 0x006677F2 @@ -1004,9 +1007,6 @@ int game_do_command(int eax, int ebx, int ecx, int edx, int esi, int edi, int eb original_edi = edi; original_ebp = ebp; - RCT2_CALLFUNC_X(0x006677F2, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - return ebx; - flags = ebx; RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 0xFFFF; @@ -1016,7 +1016,7 @@ int game_do_command(int eax, int ebx, int ecx, int edx, int esi, int edi, int eb ebx &= ~1; // Primary command - RCT2_CALLFUNC_X(RCT2_ADDRESS(0x0097B9A4, uint32)[esi], &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + RCT2_CALLFUNC_X(game_do_command_table[esi], &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); cost = ebx; if (cost != 0x80000000) { @@ -1039,7 +1039,7 @@ int game_do_command(int eax, int ebx, int ecx, int edx, int esi, int edi, int eb } // Secondary command - RCT2_CALLFUNC_X(RCT2_ADDRESS(0x0097B9A4, uint32)[esi], &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + RCT2_CALLFUNC_X(game_do_command_table[esi], &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); edx = ebx; if (edx != 0x80000000 && edx < cost) @@ -1075,4 +1075,203 @@ int game_do_command(int eax, int ebx, int ecx, int edx, int esi, int edi, int eb window_error_open(RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, uint16), RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16)); return 0x80000000; -} \ No newline at end of file +} + +/** + * + * rct2: 0x0066DB5F + */ +static void game_load_or_quit() +{ + rct_window *w; + char input_bl, input_dl; + short input_di; + + __asm mov input_bl, bl + __asm mov input_dl, dl + __asm mov input_di, di + + if (!(input_bl & 1)) + return 0; + + switch (input_dl) { + case 0: + RCT2_GLOBAL(0x009A9802, uint16) = input_di; + window_save_prompt_open(); + break; + case 1: + window_close_by_id(WC_SAVE_PROMPT, 0); + break; + default: + game_load_or_quit_no_save_prompt(); + break; + } + + __asm mov ebx, 0 +} + +/** + * + * rct2: 0x00674F40 + */ +static int open_landscape_file_dialog() +{ + int eax, ebx, ecx, edx, esi, edi, ebp; + RCT2_CALLFUNC_X(0x00674F40, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + return eax; +} + +/** + * + * rct2: 0x00674EB6 + */ +static int open_load_game_dialog() +{ + int eax, ebx, ecx, edx, esi, edi, ebp; + RCT2_CALLFUNC_X(0x00674EB6, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + return eax; +} + +/** + * + * rct2: 0x0066DC0F + */ +static void load_landscape() +{ + if (open_landscape_file_dialog() == 0) { + gfx_invalidate_screen(); + } else { + // string stuff + + RCT2_CALLPROC_EBPSAFE(0x006758C0); + if (1) { + gfx_invalidate_screen(); + // game_loop_iteration + } else { + RCT2_GLOBAL(0x009DEA66, uint16) = 0; + // game_loop_iteration + } + } +} + +/** + * + * rct2: 0x0066DBB7 + */ +static void load_game() +{ + if (open_load_game_dialog() == 0) { + gfx_invalidate_screen(); + } else { + // string stuff + + RCT2_CALLPROC_EBPSAFE(0x00675E1B); + if (1) { + gfx_invalidate_screen(); + // game_loop_iteration + } else { + RCT2_GLOBAL(0x009DEA66, uint16) = 0; + // game_loop_iteration + } + } +} + +/** + * + * rct2: 0x006E3879 + */ +static void rct2_exit() +{ + RCT2_CALLPROC_EBPSAFE(0x006E3879); +} + +/** + * + * rct2: 0x0066DB79 + */ +void game_load_or_quit_no_save_prompt() +{ + if (RCT2_GLOBAL(0x009A9802, uint16) < 1) { + game_do_command(0, 1, 0, 1, 5, 0, 0); + RCT2_CALLPROC_EBPSAFE(0x006EE281); // tool_cancel + if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2) + load_landscape(); + else + load_game(); + } else if (RCT2_GLOBAL(0x009A9802, uint16) == 1) { + game_do_command(0, 1, 0, 1, 5, 0, 0); + if (RCT2_GLOBAL(0x009DE518, uint32) & (1 << 5)) { + RCT2_CALLPROC_EBPSAFE(0x0040705E); + RCT2_GLOBAL(0x009DE518, uint32) &= ~(1 << 5); + } + title_load(); + // game_loop_iteration + } else { + rct2_exit(); + } +} + +#pragma region Game command function table + +static uint32 game_do_command_table[58] = { + 0x006B2FC5, + 0x0066397F, + 0x00667C15, + 0x006C511D, + 0x006C5B69, + 0x0066DB5F, // game_load_or_quit, + 0x006B3F0F, + 0x006B49D9, + 0x006B4EA6, + 0x006B52D4, + 0x006B578B, + 0x006B5559, + 0x006660A8, + 0x0066640B, + 0x006E0E01, + 0x006E08F4, + 0x006E650F, + 0x006A61DE, + 0x006A68AE, + 0x006A67C0, + 0x00663CCD, + 0x006B53E9, + 0x00698D6C, + 0x0068C542, + 0x0068C6D1, + 0x0068BC01, + 0x006E66A0, + 0x006E6878, + 0x006C5AE9, + 0x006BEFA1, + 0x006C09D1, + 0x006C0B83, + 0x006C0BB5, + 0x00669C6D, + 0x00669D4A, + 0x006649BD, + 0x006666E7, + 0x00666A63, + 0x006CD8CE, + 0x00669E30, + 0x00669E55, + 0x006E519A, + 0x006E5597, + 0x006B893C, + 0x006B8E1B, + 0x0069DFB3, + 0x00684A7F, + 0x006D13FE, + 0x0069E73C, + 0x006CDEE4, + 0x006B9E6D, + 0x006BA058, + 0x006E0F26, + 0x006E56B5, + 0x006B909A, + 0x006BA16A, + 0x006648E3, + 0x0068DF91 +}; + +#pragma endregion \ No newline at end of file diff --git a/src/game.h b/src/game.h index cca9afb469..23aaff9a33 100644 --- a/src/game.h +++ b/src/game.h @@ -27,4 +27,6 @@ void game_logic_update(); int game_do_command(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp); +void game_load_or_quit_no_save_prompt(); + #endif diff --git a/src/strings.h b/src/strings.h index 583bc4738e..f088c56212 100644 --- a/src/strings.h +++ b/src/strings.h @@ -162,6 +162,8 @@ enum { STR_CREDIT_SPARE_6 = 863, STR_CREDIT_SPARE_7 = 864, + STR_QUIT_SCENARIO_EDITOR = 887, + STR_SCR_BMP = 890, STR_SCREENSHOT = 891, STR_SCREENSHOT_SAVED_AS = 892, @@ -170,6 +172,19 @@ enum { STR_VIEW_OPTIONS_TIP = 937, STR_ADJUST_LAND_TIP = 938, + STR_SAVE_PROMPT_SAVE = 944, + STR_SAVE_PROMPT_DONT_SAVE = 945, + STR_SAVE_PROMPT_CANCEL = 946, + + STR_SAVE_BEFORE_LOADING = 947, + STR_SAVE_BEFORE_QUITTING = 948, + STR_SAVE_BEFORE_QUITTING_2 = 949, + + STR_LOAD_GAME = 950, + STR_QUIT_GAME = 951, + STR_QUIT_GAME_2 = 952, + STR_LOAD_LANDSCAPE = 953, + STR_CANCEL = 972, STR_OK = 973, diff --git a/src/window.h b/src/window.h index d74e7e98d7..cc424965b8 100644 --- a/src/window.h +++ b/src/window.h @@ -250,6 +250,7 @@ enum { WC_ERROR = 11, WC_RIDE = 12, WC_RIDE_CONSTRUCTION = 13, + WC_SAVE_PROMPT = 14, WC_RIDE_LIST = 15, WC_CONSTRUCT_RIDE = 16, WC_SCENERY = 18, @@ -324,6 +325,7 @@ void window_main_open(); void window_game_top_toolbar_open(); void window_game_bottom_toolbar_open(); void window_about_open(); +void window_save_prompt_open(); void window_title_menu_open(); void window_title_exit_open(); void window_title_logo_open(); diff --git a/src/window_save_prompt.c b/src/window_save_prompt.c new file mode 100644 index 0000000000..35c95a7797 --- /dev/null +++ b/src/window_save_prompt.c @@ -0,0 +1,192 @@ +/***************************************************************************** + * Copyright (c) 2014 Ted John + * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. + * + * This file is part of OpenRCT2. + * + * OpenRCT2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#include "addresses.h" +#include "game.h" +#include "rct2.h" +#include "strings.h" +#include "sprites.h" +#include "tutorial.h" +#include "widget.h" +#include "window.h" + +static enum WINDOW_SAVE_PROMPT_WIDGET_IDX { + WIDX_BACKGROUND, + WIDX_TITLE, + WIDX_CLOSE, + WIDX_3, + WIDX_SAVE, + WIDX_DONT_SAVE, + WIDX_CANCEL +}; + +static rct_widget window_save_prompt_widgets[] = { + { WWT_FRAME, 0, 0, 259, 0, 49, -1, STR_NONE }, // panel / background + { WWT_CAPTION, 0, 1, 258, 1, 14, 0, STR_WINDOW_TITLE_TIP }, // title bar + { WWT_CLOSEBOX, 0, 247, 257, 2, 13, 824, STR_CLOSE_WINDOW_TIP }, // close x button + { WWT_12, 0, 2, 257, 19, 30, 0, STR_NONE }, // + { WWT_DROPDOWN_BUTTON, 0, 8, 85, 35, 46, STR_SAVE_PROMPT_SAVE, STR_NONE }, // save + { WWT_DROPDOWN_BUTTON, 0, 91, 168, 35, 46, STR_SAVE_PROMPT_DONT_SAVE, STR_NONE }, // don't save + { WWT_DROPDOWN_BUTTON, 0, 174, 251, 35, 46, STR_SAVE_PROMPT_CANCEL, STR_NONE }, // cancel + { WIDGETS_END }, +}; + +static void window_save_prompt_emptysub() { } +static void window_save_prompt_close(); +static void window_save_prompt_mouseup(); +static void window_save_prompt_paint(); + +static uint32 window_save_prompt_events[] = { + window_save_prompt_close, + window_save_prompt_mouseup, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_emptysub, + window_save_prompt_paint, + window_save_prompt_emptysub +}; + +/** + * + * rct2: 0x0066DCBE + */ +void window_save_prompt_open() +{ + int stringId; + rct_window* window; + + // Check if window is already open + window = window_bring_to_front_by_id(WC_SAVE_PROMPT, 0); + if (window == NULL) { + window = window_create( + (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16) / 2) - 130, + max(28, (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, sint16) / 2) - 25), + 260, + 50, + window_save_prompt_events, + WC_SAVE_PROMPT, + 0 + ); + + window->widgets = window_save_prompt_widgets; + window->enabled_widgets = + (1 << WIDX_CLOSE) | + (1 << WIDX_SAVE) | + (1 << WIDX_DONT_SAVE) | + (1 << WIDX_CANCEL); + window_init_scroll_widgets(window); + window->colours[0] = 154; + window->flags |= WF_TRANSPARENT; + + // Pause the game + RCT2_GLOBAL(0x009DEA6E, uint8) |= 2; + RCT2_CALLPROC_EBPSAFE(0x006BABB4); + window_invalidate_by_id(0x80 | WC_TOP_TOOLBAR, 0); + } + + stringId = RCT2_GLOBAL(0x009A9802, uint16) + STR_LOAD_GAME; + if (stringId == STR_LOAD_GAME && RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2) + stringId = STR_LOAD_LANDSCAPE; + if (stringId == STR_QUIT_GAME && RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2) + stringId = STR_QUIT_SCENARIO_EDITOR; + window_save_prompt_widgets[WIDX_TITLE].image = stringId; + window_save_prompt_widgets[WIDX_3].image = RCT2_GLOBAL(0x009A9802, uint16) + STR_SAVE_BEFORE_LOADING; + + if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 0x0D) { + game_load_or_quit_no_save_prompt(); + return; + } + + if (RCT2_GLOBAL(RCT2_ADDRESS_ON_TUTORIAL, uint8) != 0) { + if (RCT2_GLOBAL(RCT2_ADDRESS_ON_TUTORIAL, uint8) != 1) { + RCT2_CALLPROC_EBPSAFE(0x0066EE54); + game_load_or_quit_no_save_prompt(); + return; + } else { + tutorial_stop(); + game_load_or_quit_no_save_prompt(); + return; + } + } + + if (RCT2_GLOBAL(0x009DEA66, uint16) < 3840) { + game_load_or_quit_no_save_prompt(); + return; + } +} + +/** + * + * rct2: 0x0066DF17 + */ +static void window_save_prompt_close() +{ + // Unpause the game + RCT2_GLOBAL(0x009DEA6E, uint8) &= ~2; + RCT2_CALLPROC_EBPSAFE(0x006BABD8); + window_invalidate_by_id(0x80 | WC_TOP_TOOLBAR, 0); +} + +/** + * + * rct2: 0x0066DDF2 + */ +static void window_save_prompt_mouseup() +{ + short widgetIndex; + rct_window *w; + + __asm mov widgetIndex, dx + __asm mov w, esi + + // TODO +} + +static void window_save_prompt_paint() +{ + rct_window *w; + rct_drawpixelinfo *dpi; + + __asm mov w, esi + __asm mov dpi, edi + + window_draw_widgets(w, dpi); +} \ No newline at end of file From 9e3fedad59cbf1955a57e161d7c6ac016eb0a9a8 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Fri, 2 May 2014 22:34:14 +0100 Subject: [PATCH 25/37] add more peep fields --- src/peep.h | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/peep.h b/src/peep.h index 92790af4c2..6bd275f025 100644 --- a/src/peep.h +++ b/src/peep.h @@ -120,27 +120,31 @@ typedef struct { uint8 current_train; // 0x6B uint8 current_car; // 0x6C uint8 current_seat; // 0x6D - uint8 pad_6E[0x2E]; + uint8 pad_6E[0x0E]; + uint8 rides_been_on[32]; // 0x7C uint32 id; // 0x9C - uint8 pad_A0[0x10]; + sint32 cash_in_pocket; // 0xA0 + sint32 cash_spent; // 0xA4 + uint8 pad_A8[8]; rct_peep_thought thoughts[PEEP_MAX_THOUGHTS]; // 0xB0 uint16 pad_C4; uint8 var_C6; uint8 pad_C7; - uint32 var_C8; //Bit 11 tracking, Bit 8 leaving the park - uint8 var_CC; //Bit 0 mad, bit 1 Ice Cream + uint32 var_C8; // Bit 11 tracking, Bit 8 leaving the park + uint8 var_CC; // Bit 0 mad, bit 1 Ice Cream uint8 pad_CD[0x18]; - uint16 paid_to_enter; //0xE5 Number is /10 when displayed - uint16 paid_on_rides; //0xE7 Number is /10 when displayed - uint16 paid_on_food; //0xE9 Number is /10 when displayed - uint16 paid_on_souvenirs; //0xEB Number is /10 when displayed - uint8 no_of_food; //0xEC - uint8 no_of_drinks; //0xED - uint8 no_of_souvenirs; //0xEE + uint16 paid_to_enter; // 0xE5 + uint16 paid_on_rides; // 0xE7 + uint16 paid_on_food; // 0xE9 + uint16 paid_on_souvenirs; // 0xEB + uint8 no_of_food; // 0xEC + uint8 no_of_drinks; // 0xED + uint8 no_of_souvenirs; // 0xEE uint8 pad_EF[0x07]; uint8 balloon_colour; // 0xF6 uint8 umbrella_colour; // 0xF7 uint8 hat_colour; // 0xF8 + uint8 favourite_ride; // 0xF9 } rct_peep; int peep_get_staff_count(); From 59d0e94f06074f33b076c40c44f1bf78d48db564 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Fri, 2 May 2014 22:38:16 +0100 Subject: [PATCH 26/37] use written cancel tool function --- src/game.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game.c b/src/game.c index ea88c3a7c2..ce24c2a858 100644 --- a/src/game.c +++ b/src/game.c @@ -1193,7 +1193,7 @@ void game_load_or_quit_no_save_prompt() { if (RCT2_GLOBAL(0x009A9802, uint16) < 1) { game_do_command(0, 1, 0, 1, 5, 0, 0); - RCT2_CALLPROC_EBPSAFE(0x006EE281); // tool_cancel + tool_cancel(); if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2) load_landscape(); else From 51fa837cafc7e8bdca03bd5a33b8b66d0e336bad Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Sat, 3 May 2014 00:31:53 +0100 Subject: [PATCH 27/37] add more peep fields --- src/peep.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/peep.h b/src/peep.h index 6bd275f025..76f993fb3c 100644 --- a/src/peep.h +++ b/src/peep.h @@ -91,7 +91,9 @@ typedef struct { sint16 x; // 0x0E sint16 y; // 0x10 sint16 z; // 0x12 - uint8 pad_14[0x0E]; + uint8 pad_14[0x09]; + uint8 direction; // 0x1D + uint32 pad_1E; uint16 name_string_idx; // 0x22 uint16 next_x; // 0x24 uint16 next_y; // 0x26 @@ -102,15 +104,15 @@ typedef struct { uint8 sprite_type; // 0x2D uint8 type; // 0x2E uint8 staff_type; // 0x2F - uint8 var_30; - uint8 var_31; + uint8 tshirt_colour; // 0x30 + uint8 trousers_colour; // 0x31 uint8 pad_32[0x06]; uint8 energy; // 0x38 - uint8 var_39; + uint8 energy_growth_rate; // 0x39 uint8 happiness; // 0x3A - uint8 var_03B; + uint8 happiness_growth_rate; // 0x3B uint8 nausea; // 0x3C - uint8 var_03D; + uint8 nausea_growth_rate; // 0x3D uint8 hunger; // 0x3E uint8 thirst; // 0x3F uint8 bathroom; // 0x40 From 634ae0dbeb6cb5b05177d79ab150cee63299a1ff Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Sat, 3 May 2014 02:33:01 +0100 Subject: [PATCH 28/37] allow new quit game or load code to run --- src/game.c | 32 +++++++++++++++++++++++++++----- src/widget.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/src/game.c b/src/game.c index ce24c2a858..669ebc4675 100644 --- a/src/game.c +++ b/src/game.c @@ -1141,9 +1141,20 @@ static void load_landscape() if (open_landscape_file_dialog() == 0) { gfx_invalidate_screen(); } else { - // string stuff + // Set default filename + char *esi = 0x0141EF67; + while (1) { + esi++; + if (*esi == '.') + break; + if (*esi != 0) + continue; + strcpy(esi, ".SC6"); + break; + } + strcpy(0x009ABB37, 0x0141EF68); - RCT2_CALLPROC_EBPSAFE(0x006758C0); + RCT2_CALLPROC_EBPSAFE(0x006758C0); // landscape_load if (1) { gfx_invalidate_screen(); // game_loop_iteration @@ -1163,9 +1174,20 @@ static void load_game() if (open_load_game_dialog() == 0) { gfx_invalidate_screen(); } else { - // string stuff + // Set default filename + char *esi = 0x0141EF67; + while (1) { + esi++; + if (*esi == '.') + break; + if (*esi != 0) + continue; + strcpy(esi, ".SV6"); + break; + } + strcpy(0x009ABB37, 0x0141EF68); - RCT2_CALLPROC_EBPSAFE(0x00675E1B); + RCT2_CALLPROC_EBPSAFE(0x00675E1B); // game_load if (1) { gfx_invalidate_screen(); // game_loop_iteration @@ -1219,7 +1241,7 @@ static uint32 game_do_command_table[58] = { 0x00667C15, 0x006C511D, 0x006C5B69, - 0x0066DB5F, // game_load_or_quit, + game_load_or_quit, 0x006B3F0F, 0x006B49D9, 0x006B4EA6, diff --git a/src/widget.c b/src/widget.c index e4016b56f2..fe5bcd96cd 100644 --- a/src/widget.c +++ b/src/widget.c @@ -34,6 +34,7 @@ static void widget_text_button(rct_drawpixelinfo *dpi, rct_window *w, int widget static void widget_text_unknown(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex); static void widget_text(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex); static void widget_text_inset(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex); +static void widget_text_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex); static void widget_groupbox_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex); static void widget_caption_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex); static void widget_closebox_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex); @@ -507,6 +508,39 @@ static void widget_text_inset(rct_drawpixelinfo *dpi, rct_window *w, int widgetI widget_text(dpi, w, widgetIndex); } +/** + * + * rct2: 0x006EC1A6 + */ +static void widget_text_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex) +{ + rct_widget* widget; + int l, t, r, b, press; + uint8 colour; + + // Get the widget + widget = &w->widgets[widgetIndex]; + + // Resolve the absolute ltrb + l = w->x + widget->left + 5; + t = w->y + widget->top; + r = w->x + widget->right; + b = w->y + widget->bottom; + + // Get the colour + colour = w->colours[widget->colour]; + + press = 0; + if (widget_is_pressed(w, widgetIndex) || widget_is_active_tool(w, widgetIndex)) + press |= 0x20; + + gfx_fill_rect_inset(dpi, l, t, r, b, colour, press); + + // TODO + + gfx_fill_rect(dpi, l, t, r, b, colour); +} + /** * * rct2: 0x006EB535 From 2cc3a56ffc8527f72f7a2d06f9487c4108be7b98 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sat, 3 May 2014 08:37:07 +0100 Subject: [PATCH 29/37] Slowed down the cheat guests tab animation --- src/window_cheats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/window_cheats.c b/src/window_cheats.c index ae02e6e2ac..47ae59c9cd 100644 --- a/src/window_cheats.c +++ b/src/window_cheats.c @@ -300,7 +300,7 @@ static void window_cheats_draw_tab_images(rct_drawpixelinfo *dpi, rct_window *w) if (!(w->disabled_widgets & (1 << WIDX_TAB_2))) { sprite_idx = 5568; if (w->page == WINDOW_CHEATS_PAGE_GUESTS) - sprite_idx += (w->var_48E / 2) % 8; + sprite_idx += (w->var_48E / 3) % 8; gfx_draw_sprite(dpi, sprite_idx, w->x + w->widgets[WIDX_TAB_2].left, w->y + w->widgets[WIDX_TAB_2].top); } } From 5f8db5e1151fbc3b3107a36c9886c0fa395a216a Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Sat, 3 May 2014 09:00:49 +0100 Subject: [PATCH 30/37] add pause toggle game command --- src/game.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/game.c b/src/game.c index 669ebc4675..7f4978c3f1 100644 --- a/src/game.c +++ b/src/game.c @@ -1077,6 +1077,30 @@ int game_do_command(int eax, int ebx, int ecx, int edx, int esi, int edi, int eb return 0x80000000; } +/** + * + * rct2: 0x00667C15 + */ +static void game_pause_toggle() +{ + rct_window *w; + char input_bl, input_dl; + short input_di; + + __asm mov input_bl, bl + + if (input_bl & 1) { + RCT2_GLOBAL(0x009DEA6E, uint32) ^= 1; + window_invalidate_by_id(WC_TOP_TOOLBAR, 0); + if (RCT2_GLOBAL(0x009DEA6E, uint32) & 1) + RCT2_CALLPROC_EBPSAFE(0x006BABB4); // pause_sounds + else + RCT2_CALLPROC_EBPSAFE(0x006BABD8); // unpause_sounds + } + + __asm mov ebx, 0 +} + /** * * rct2: 0x0066DB5F @@ -1238,7 +1262,7 @@ void game_load_or_quit_no_save_prompt() static uint32 game_do_command_table[58] = { 0x006B2FC5, 0x0066397F, - 0x00667C15, + game_pause_toggle, 0x006C511D, 0x006C5B69, game_load_or_quit, From d4583339f47097883d70fe69e26cc2768f1e0dc7 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Sat, 3 May 2014 10:22:20 +0200 Subject: [PATCH 31/37] squash! Add map_element_height (finishes sub_662783) --- src/map.c | 53 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/src/map.c b/src/map.c index 57a305981b..4bfd297ef3 100644 --- a/src/map.c +++ b/src/map.c @@ -156,7 +156,8 @@ int map_element_height(int x, int y) uint8 extra_height = (slope & 0x10) >> 4; // 0x10 is the 5th bit - sets slope to double height slope &= 0xF; - uint8 quad, quad_2; // which quadrant the element is in? + uint8 quad, quad_extra; // which quadrant the element is in? + // quad_extra is for extra height tiles uint8 xl, yl; @@ -208,47 +209,53 @@ int map_element_height(int x, int y) // One corner down if ((slope == 7) || (slope == 11) || (slope == 13) || (slope == 14)) { - switch(slope) { + switch (slope) { case 7: // NW corner down - quad = xl + TILE_SIZE - yl; - quad_2 = xl - yl; + quad_extra = xl + TILE_SIZE - yl; + quad = xl - yl; break; case 11: // SW corner down - quad = xl + yl; - quad_2 = xl + yl - TILE_SIZE; + quad_extra = xl + yl; + quad = xl + yl - TILE_SIZE; break; case 13: // SE corner down - quad = TILE_SIZE - xl + yl; - quad_2 = xl - yl; + quad_extra = TILE_SIZE - xl + yl; + quad = xl - yl; break; case 14: // NE corner down - quad = (TILE_SIZE - xl) + (TILE_SIZE - yl); - quad_2 = TILE_SIZE - yl - xl; + quad_extra = (TILE_SIZE - xl) + (TILE_SIZE - yl); + quad = TILE_SIZE - yl - xl; break; } - height += 0x10; + if (extra_height) { - height += quad / 2; + height += quad_extra / 2; height++; + return height; } - if (quad_2 < 0) { - height += quad_2 / 2; + // This tile is essentially at the next height level + height += 0x10; + // so we move *down* the slope + if (quad < 0) { + height += quad / 2; height += 0xFF00; } } // Valleys - if (slope == 5) { // NW-SE valley - quad = xl + yl; - if (quad > TILE_SIZE + 1) { - quad = TILE_SIZE - xl - yl; - if (quad > 0) { - height += quad / 2; + if ((slope == 5) || (slope == 10)) { + switch (slope) { + case 5: // NW-SE valley + if (xl + yl <= TILE_SIZE + 1) { + return height; } - } - } else if (slope == 10) { // NE-SW valley - if (xl > yl) { + quad = TILE_SIZE - xl - yl; + break; + case 10: // NE-SW valley quad = xl - yl; + break; + } + if (quad > 0) { height += quad / 2; } } From 3cd254fbbb7bbfeaa8c8d4fb61a732d92b052faa Mon Sep 17 00:00:00 2001 From: ZedThree Date: Sat, 3 May 2014 10:24:25 +0200 Subject: [PATCH 32/37] Change formatting to VS style, improve comments --- src/map.c | 154 +++++++++++++++++++++++++----------------------- src/news_item.c | 8 +-- 2 files changed, 84 insertions(+), 78 deletions(-) diff --git a/src/map.c b/src/map.c index 4bfd297ef3..38064fe979 100644 --- a/src/map.c +++ b/src/map.c @@ -154,110 +154,116 @@ int map_element_height(int x, int y) uint32 slope = (mapElement->properties.surface.slope & MAP_ELEMENT_SLOPE_MASK); uint8 extra_height = (slope & 0x10) >> 4; // 0x10 is the 5th bit - sets slope to double height + // Remove the extra height bit slope &= 0xF; uint8 quad, quad_extra; // which quadrant the element is in? // quad_extra is for extra height tiles - uint8 xl, yl; + uint8 xl, yl; // coordinates across this tile uint8 TILE_SIZE = 31; xl = x & 0x1f; yl = y & 0x1f; - // slope logic - // slope == 0 is flat, and slope == 15 is not used + // Slope logic: + // Each of the four bits in slope represents that corner being raised + // slope == 15 (all four bits) is not used and slope == 0 is flat + // If the extra_height bit is set, then the slope goes up two z-levels + + // We arbitrarily take the SW corner to be closest to the viewer // One corner up if ((slope == 1) || (slope == 2) || (slope == 4) || (slope == 8)) { - switch(slope) { - case 1: // NE corner up - quad = xl + yl - TILE_SIZE; - break; - case 2: // SE corner up - quad = xl - yl; - break; - case 4: // SW corner up - quad = TILE_SIZE - yl - xl; - break; - case 8: // NW corner up - quad = xl - yl; - break; - } - if (quad > 0) { - height += quad / 2; - } + switch (slope) { + case 1: // NE corner up + quad = xl + yl - TILE_SIZE; + break; + case 2: // SE corner up + quad = xl - yl; + break; + case 4: // SW corner up + quad = TILE_SIZE - yl - xl; + break; + case 8: // NW corner up + quad = xl - yl; + break; + } + // If the element is in the quadrant with the slope, raise its height + if (quad > 0) { + height += quad / 2; + } } // One side up - switch(slope) { + switch (slope) { case 3: // E side up - height += xl / 2; - break; + height += xl / 2; + break; case 6: // S side up - height += (TILE_SIZE - yl) / 2; - break; + height += (TILE_SIZE - yl) / 2; + break; case 9: // N side up - height += yl / 2; - height++; - break; + height += yl / 2; + height++; + break; case 12: // W side up - height += (TILE_SIZE - xl) / 2; - break; + height += (TILE_SIZE - xl) / 2; + break; } // One corner down if ((slope == 7) || (slope == 11) || (slope == 13) || (slope == 14)) { - switch (slope) { - case 7: // NW corner down - quad_extra = xl + TILE_SIZE - yl; - quad = xl - yl; - break; - case 11: // SW corner down - quad_extra = xl + yl; - quad = xl + yl - TILE_SIZE; - break; - case 13: // SE corner down - quad_extra = TILE_SIZE - xl + yl; - quad = xl - yl; - break; - case 14: // NE corner down - quad_extra = (TILE_SIZE - xl) + (TILE_SIZE - yl); - quad = TILE_SIZE - yl - xl; - break; - } + switch (slope) { + case 7: // NW corner down + quad_extra = xl + TILE_SIZE - yl; + quad = xl - yl; + break; + case 11: // SW corner down + quad_extra = xl + yl; + quad = xl + yl - TILE_SIZE; + break; + case 13: // SE corner down + quad_extra = TILE_SIZE - xl + yl; + quad = xl - yl; + break; + case 14: // NE corner down + quad_extra = (TILE_SIZE - xl) + (TILE_SIZE - yl); + quad = TILE_SIZE - yl - xl; + break; + } - if (extra_height) { - height += quad_extra / 2; - height++; - return height; - } - // This tile is essentially at the next height level - height += 0x10; - // so we move *down* the slope - if (quad < 0) { - height += quad / 2; - height += 0xFF00; - } + if (extra_height) { + height += quad_extra / 2; + height++; + return height; + } + // This tile is essentially at the next height level + height += 0x10; + // so we move *down* the slope + if (quad < 0) { + height += quad / 2; + height += 0xFF00; + } } // Valleys if ((slope == 5) || (slope == 10)) { - switch (slope) { - case 5: // NW-SE valley - if (xl + yl <= TILE_SIZE + 1) { - return height; - } - quad = TILE_SIZE - xl - yl; - break; - case 10: // NE-SW valley - quad = xl - yl; - break; - } - if (quad > 0) { - height += quad / 2; - } + switch (slope) { + case 5: // NW-SE valley + if (xl + yl <= TILE_SIZE + 1) { + return height; + } + quad = TILE_SIZE - xl - yl; + break; + case 10: // NE-SW valley + quad = xl - yl; + break; + } + if (quad > 0) { + height += quad / 2; + } } return height; diff --git a/src/news_item.c b/src/news_item.c index 3f50fbfd96..4e862d599b 100644 --- a/src/news_item.c +++ b/src/news_item.c @@ -225,10 +225,10 @@ void news_item_get_subject_location(int type, int subject, int *x, int *y, int * *z = peep->z; break; case NEWS_ITEM_BLANK: - *x = subject; - *y = subject >> 16; - *z = map_element_height(x, y); - break; + *x = subject; + *y = subject >> 16; + *z = map_element_height(*x, *y); + break; default: *x = SPRITE_LOCATION_NULL; break; From 9b46c74279c477de11c637d2d083c45d1b2cc26d Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Sat, 3 May 2014 10:27:48 +0100 Subject: [PATCH 33/37] add load game and landscape dialog --- src/game.c | 20 +++++++++++----- src/osinterface.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++ src/osinterface.h | 2 ++ src/strings.h | 6 +++++ 4 files changed, 83 insertions(+), 6 deletions(-) diff --git a/src/game.c b/src/game.c index 7f4978c3f1..cf8fe6b6fc 100644 --- a/src/game.c +++ b/src/game.c @@ -1140,9 +1140,13 @@ static void game_load_or_quit() */ static int open_landscape_file_dialog() { - int eax, ebx, ecx, edx, esi, edi, ebp; - RCT2_CALLFUNC_X(0x00674F40, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - return eax; + format_string(0x0141ED68, STR_LOAD_LANDSCAPE_DIALOG_TITLE, 0); + strcpy(0x0141EF68, RCT2_ADDRESS_LANDSCAPES_PATH); + format_string(0x0141EE68, STR_RCT2_LANDSCAPE_FILE, 0); + RCT2_CALLPROC_EBPSAFE(0x006BABB4); // pause_sounds + osinterface_open_common_file_dialog(1, 0x0141ED68, 0x0141EF68, "*.SV6;*.SV4;*.SC6", 0x0141EE68); + RCT2_CALLPROC_EBPSAFE(0x006BABD8); // unpause_sounds + // window_proc } /** @@ -1151,9 +1155,13 @@ static int open_landscape_file_dialog() */ static int open_load_game_dialog() { - int eax, ebx, ecx, edx, esi, edi, ebp; - RCT2_CALLFUNC_X(0x00674EB6, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - return eax; + format_string(0x0141ED68, STR_LOAD_GAME_DIALOG_TITLE, 0); + strcpy(0x0141EF68, RCT2_ADDRESS_SAVED_GAMES_PATH); + format_string(0x0141EE68, STR_RCT2_SAVED_GAME, 0); + RCT2_CALLPROC_EBPSAFE(0x006BABB4); // pause_sounds + osinterface_open_common_file_dialog(1, 0x0141ED68, 0x0141EF68, "*.SV6", 0x0141EE68); + RCT2_CALLPROC_EBPSAFE(0x006BABD8); // unpause_sounds + // window_proc } /** diff --git a/src/osinterface.c b/src/osinterface.c index 2b2484f70c..3e97491e5b 100644 --- a/src/osinterface.c +++ b/src/osinterface.c @@ -19,6 +19,7 @@ *****************************************************************************/ #include +#include #include #include @@ -288,3 +289,63 @@ void osinterface_free() osinterface_close_window(); SDL_Quit(); } + +/** + * + * rct2: 0x004080EA + */ +int osinterface_open_common_file_dialog(int type, char *title, char *filename, char *filterPattern, char *filterName) +{ + char initialDirectory[MAX_PATH], *dotAddress, *slashAddress; + OPENFILENAME openFileName; + BOOL result; + int tmp; + + // Get directory path from given filename + strcpy(initialDirectory, filename); + dotAddress = strrchr(filename, '.'); + if (dotAddress != NULL) { + slashAddress = strrchr(filename, '\\'); + if (slashAddress < dotAddress) + *(slashAddress + 1) = 0; + } + + // Clear filename + *filename = 0; + + // Set open file name options + memset(&openFileName, 0, sizeof(OPENFILENAME)); + openFileName.lStructSize = sizeof(OPENFILENAME); + openFileName.hwndOwner = RCT2_GLOBAL(0x009E2D70, HWND); + openFileName.lpstrFile = filename; + openFileName.nMaxFile = MAX_PATH; + openFileName.lpstrInitialDir = initialDirectory; + openFileName.lpstrTitle = title; + + // Copy filter name + strcpy(0x01423800, filterName); + + // Copy filter pattern + strcpy(0x01423800 + strlen(filterName) + 1, filterPattern); + *((char*)(0x01423800 + strlen(filterName) + 1 + strlen(filterPattern) + 1)) = 0; + openFileName.lpstrFilter = 0x01423800; + + // + tmp = RCT2_GLOBAL(0x009E2C74, uint32); + if (RCT2_GLOBAL(0x009E2BB8, uint32) == 2 && RCT2_GLOBAL(0x009E1AF8, uint32) == 1) + RCT2_GLOBAL(0x009E2C74, uint32) = 1; + + // Open dialog + if (type == 0) { + openFileName.Flags = OFN_EXPLORER | OFN_CREATEPROMPT | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; + result = GetSaveFileName(&openFileName); + } else if (type == 1) { + openFileName.Flags = OFN_EXPLORER | OFN_NONETWORKBUTTON | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY; + result = GetOpenFileName(&openFileName); + } + + // + RCT2_GLOBAL(0x009E2C74, uint32) = tmp; + + return result; +} \ No newline at end of file diff --git a/src/osinterface.h b/src/osinterface.h index 205d0170a0..9ec682fea2 100644 --- a/src/osinterface.h +++ b/src/osinterface.h @@ -46,4 +46,6 @@ void osinterface_process_messages(); void osinterface_draw(); void osinterface_free(); +int osinterface_open_common_file_dialog(int type, char *title, char *filename, char *filterPattern, char *filterName); + #endif diff --git a/src/strings.h b/src/strings.h index a24ae919d1..1a990782d6 100644 --- a/src/strings.h +++ b/src/strings.h @@ -205,6 +205,12 @@ enum { STR_LOCATE_SUBJECT_TIP = 1027, + STR_LOAD_GAME_DIALOG_TITLE = 1036, + STR_LOAD_LANDSCAPE_DIALOG_TITLE = 1037, + + STR_RCT2_SAVED_GAME = 1043, + STR_RCT2_LANDSCAPE_FILE = 1045, + STR_RIDES_IN_PARK_TIP = 1053, STR_PLACE_SCENERY_TIP = 1159, From 57cff462c450fbecccfaf11db8fbf940c4ca0041 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sat, 3 May 2014 10:32:17 +0100 Subject: [PATCH 34/37] Fixed offset locations due to missing byte. --- src/peep.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/peep.h b/src/peep.h index 76f993fb3c..1de1187bcb 100644 --- a/src/peep.h +++ b/src/peep.h @@ -118,11 +118,11 @@ typedef struct { uint8 bathroom; // 0x40 uint8 pad_041[0x27]; uint8 current_ride; // 0x68 - uint8 pad_6A; // 0x6A Part of current_ride? - uint8 current_train; // 0x6B - uint8 current_car; // 0x6C - uint8 current_seat; // 0x6D - uint8 pad_6E[0x0E]; + uint8 pad_69; + uint8 current_train; // 0x6A + uint8 current_car; // 0x6B + uint8 current_seat; // 0x6C + uint8 pad_6D[0x0F]; uint8 rides_been_on[32]; // 0x7C uint32 id; // 0x9C sint32 cash_in_pocket; // 0xA0 @@ -132,13 +132,13 @@ typedef struct { uint16 pad_C4; uint8 var_C6; uint8 pad_C7; - uint32 var_C8; // Bit 11 tracking, Bit 8 leaving the park - uint8 var_CC; // Bit 0 mad, bit 1 Ice Cream - uint8 pad_CD[0x18]; - uint16 paid_to_enter; // 0xE5 - uint16 paid_on_rides; // 0xE7 - uint16 paid_on_food; // 0xE9 - uint16 paid_on_souvenirs; // 0xEB + uint32 var_C8; // Bit 25 Ice Cream, Bit 24 mad, Bit 3 tracking, Bit 0 leaving the park + uint8 var_CC; + uint8 pad_CD[0x17]; + uint16 paid_to_enter; // 0xE4 + uint16 paid_on_rides; // 0xE6 + uint16 paid_on_food; // 0xE8 + uint16 paid_on_souvenirs; // 0xEA uint8 no_of_food; // 0xEC uint8 no_of_drinks; // 0xED uint8 no_of_souvenirs; // 0xEE From a38b95755a3f30bf7210e8c7facc83e8431f8eef Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Sat, 3 May 2014 10:34:11 +0100 Subject: [PATCH 35/37] remove unfinished comment and credit author --- src/map.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/map.c b/src/map.c index 38064fe979..bae30cd6fa 100644 --- a/src/map.c +++ b/src/map.c @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014 Ted John + * Copyright (c) 2014 Ted John, Peter Hill * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. * * This file is part of OpenRCT2. @@ -126,7 +126,6 @@ void map_update_tile_pointers() * Return the absolute height of an element, given its (x,y) coordinates * * rct2: 0x00662783 - * UNFINISHED */ int map_element_height(int x, int y) { From 74041396a146011c5ea1e76bf6f2dcfe646d6102 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Sat, 3 May 2014 12:21:12 +0100 Subject: [PATCH 36/37] fix scenario name string bug --- src/addresses.h | 1 + src/scenario.c | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index 1db7aef73e..01c86a5e15 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -163,6 +163,7 @@ #define RCT2_ADDRESS_MAP_SIZE 0x01358834 +#define RCT2_ADDRESS_SCENARIO_NAME 0x0135920A #define RCT2_ADDRESS_SCENARIO_DETAILS 0x0135924A #define RCT2_ADDRESS_PARK_ENTRANCE_X 0x01359350 diff --git a/src/scenario.c b/src/scenario.c index d8da316012..c103d7a040 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -479,11 +479,13 @@ void scenario_load_and_play(rct_scenario_basic *scenario) // format_string(0x0141ED68, RCT2_GLOBAL(ebp + 0, uint16), 0); - strcpy_s(0x0135920A, 32, 0x0141ED68); + strncpy(RCT2_ADDRESS_SCENARIO_NAME, 0x0141ED68, 31); + ((char*)RCT2_ADDRESS_SCENARIO_NAME)[31] = '\0'; // Set scenario details format_string(0x0141ED68, RCT2_GLOBAL(ebp + 4, uint16), 0); - strcpy_s(RCT2_ADDRESS_SCENARIO_DETAILS, 256, 0x0141ED68); + strncpy(RCT2_ADDRESS_SCENARIO_DETAILS, 0x0141ED68, 255); + ((char*)RCT2_ADDRESS_SCENARIO_DETAILS)[255] = '\0'; } // Set the last saved game path From 9cf6f8f98a8c621470e7f8d0760c529ee8d30dcd Mon Sep 17 00:00:00 2001 From: ddevrien Date: Sat, 3 May 2014 13:39:36 +0200 Subject: [PATCH 37/37] Added some GAME_FLAGS Also renamed them to PARK_FLAGS and moved them to park.h, since they have to do with each park, and are probably saved somewhere in the sv6 file. --- src/addresses.h | 2 +- src/editor.c | 2 +- src/park.c | 4 ++-- src/park.h | 16 ++++++++++++++++ src/rct2.h | 8 -------- src/scenario.c | 12 ++++++------ src/window.h | 1 + src/window_footpath.c | 2 +- src/window_game_bottom_toolbar.c | 4 ++-- src/window_land.c | 2 +- src/window_park.c | 6 +++--- src/window_ride_list.c | 2 +- 12 files changed, 35 insertions(+), 26 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index 01c86a5e15..d9c7a46036 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -141,7 +141,7 @@ #define RCT2_ADDRESS_SPRITES_START_LITTER 0x013573C4 #define RCT2_ADDRESS_CURRENT_LOAN 0x013573E0 -#define RCT2_ADDRESS_GAME_FLAGS 0x013573E4 +#define RCT2_ADDRESS_PARK_FLAGS 0x013573E4 #define RCT2_ADDRESS_PARK_ENTRANCE_FEE 0x013573E8 #define RCT2_ADDRESS_GUESTS_IN_PARK 0x01357844 #define RCT2_ADDRESS_MONTHLY_RIDE_INCOME 0x01357894 diff --git a/src/editor.c b/src/editor.c index c34485048d..109e947e36 100644 --- a/src/editor.c +++ b/src/editor.c @@ -58,7 +58,7 @@ void editor_load() RCT2_CALLPROC_EBPSAFE(0x006BD39C); RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) = SCREEN_FLAGS_SCENARIO_EDITOR; RCT2_GLOBAL(0x0141F570, uint8) = 0; - RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) |= 16; + RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) |= 16; RCT2_CALLPROC_EBPSAFE(0x006ACA58); RCT2_GLOBAL(0x0141F571, uint8) = 4; viewport_init_all(); diff --git a/src/park.c b/src/park.c index 7a80e0356d..13f3728c2f 100644 --- a/src/park.c +++ b/src/park.c @@ -28,7 +28,7 @@ int park_is_open() { - return (RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) & GAME_FLAGS_PARK_OPEN) != 0; + return (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_PARK_OPEN) != 0; } /** @@ -86,7 +86,7 @@ int calculate_park_rating() int result; result = 1150; - if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) & 0x4000) + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & 0x4000) result = 1050; // Guests diff --git a/src/park.h b/src/park.h index 98b27d299f..287729ac6f 100644 --- a/src/park.h +++ b/src/park.h @@ -51,6 +51,22 @@ enum { PARK_AWARD_BEST_GENTLE_RIDES, }; +enum { + PARK_FLAGS_PARK_OPEN = (1 << 0), + PARK_FLAGS_FORBID_LANDSCAPE_CHANGES = (1 << 2), + PARK_FLAGS_FORBID_TREE_REMOVAL = (1 << 3), + PARK_FLAGS_SHOW_REAL_GUEST_NAMES = (1 << 4), + PARK_FLAGS_FORBID_HIGH_CONSTRUCTION = (1 << 5), // below tree height + PARK_FLAGS_PREF_LESS_INTENSE_RIDES = (1 << 6), + PARK_FLAGS_FORBID_MARKETING_CAMPAIGN = (1 << 7), + PARK_FLAGS_PREF_MORE_INTENSE_RIDES = (1 << 11), + PARK_FLAGS_DIFFICULT_GUEST_GENERATION = (1 << 12), + PARK_FLAGS_PARK_FREE_ENTRY = (1 << 13), + PARK_FLAGS_DIFFICULT_PARK_RATING = (1 << 14), + PARK_FLAGS_NO_MONEY = (1 << 17), + PARK_FLAGS_18 = (1 << 18) +}; + int park_is_open(); void park_init(); int park_calculate_size(); diff --git a/src/rct2.h b/src/rct2.h index c62e92e1d9..7239b89b7a 100644 --- a/src/rct2.h +++ b/src/rct2.h @@ -120,14 +120,6 @@ enum { }; -enum { - GAME_FLAGS_PARK_OPEN = (1 << 0), - GAME_FLAGS_BELOW_TREE_HEIGHT_ONLY = (1 << 5), - GAME_FLAGS_NO_MONEY = (1 << 11), - GAME_FLAGS_PARK_FREE_ENTRY = (1 << 13), - GAME_FLAGS_18 = (1 << 18) -}; - void rct2_endupdate(); char *get_file_path(int pathId); void get_system_info(); diff --git a/src/scenario.c b/src/scenario.c index c103d7a040..a4aa7f3510 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -446,9 +446,9 @@ void scenario_load_and_play(rct_scenario_basic *scenario) RCT2_GLOBAL(0x00F663B0, sint32) = RCT2_GLOBAL(0x009AA0F0, sint32); RCT2_GLOBAL(0x00F663B4, sint32) = RCT2_GLOBAL(0x009AA0F4, sint32); RCT2_GLOBAL(0x009DEB7C, sint16) = 0; - RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, sint32) &= 0xFFFFF7FF; - if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, sint32) & 0x20000) - RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, sint32) |= 0x800; + RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, sint32) &= 0xFFFFF7FF; + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, sint32) & 0x20000) + RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, sint32) |= 0x800; RCT2_CALLPROC_EBPSAFE(0x00684AC3); RCT2_CALLPROC_EBPSAFE(0x006DFEE4); news_item_init_queue(); @@ -514,12 +514,12 @@ void scenario_load_and_play(rct_scenario_basic *scenario) RCT2_GLOBAL(0x00135882E, uint16) = 0; // Open park with free entry when there is no money - if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) & GAME_FLAGS_NO_MONEY) { - RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) |= GAME_FLAGS_PARK_OPEN; + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY) { + RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) |= PARK_FLAGS_PARK_OPEN; RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, uint16) = 0; } - RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) |= GAME_FLAGS_18; + RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) |= PARK_FLAGS_18; RCT2_CALLPROC_EBPSAFE(0x006837E3); // (palette related) diff --git a/src/window.h b/src/window.h index 8d1104e48c..9fab72b82c 100644 --- a/src/window.h +++ b/src/window.h @@ -22,6 +22,7 @@ #define _WINDOW_H_ #include "gfx.h" +#include "park.h" #include "rct2.h" struct rct_window; diff --git a/src/window_footpath.c b/src/window_footpath.c index 2ff607f8a9..de147ada3d 100644 --- a/src/window_footpath.c +++ b/src/window_footpath.c @@ -583,7 +583,7 @@ static void window_footpath_paint() x = w->x + (window_footpath_widgets[WIDX_CONSTRUCT].left + window_footpath_widgets[WIDX_CONSTRUCT].right) / 2; y = w->y + window_footpath_widgets[WIDX_CONSTRUCT].bottom - 12; if (_window_footpath_cost != 0x80000000) - if (!(RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) & GAME_FLAGS_NO_MONEY)) + if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY)) gfx_draw_string_centred(dpi, STR_COST_LABEL, x, y, 0, &_window_footpath_cost); } diff --git a/src/window_game_bottom_toolbar.c b/src/window_game_bottom_toolbar.c index 19b4bfa581..53559bd86a 100644 --- a/src/window_game_bottom_toolbar.c +++ b/src/window_game_bottom_toolbar.c @@ -159,7 +159,7 @@ static void window_game_bottom_toolbar_mouseup() switch (widgetIndex) { case WIDX_LEFT_OUTSET: case WIDX_MONEY: - if (!(RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) & 0x800)) + if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & 0x800)) RCT2_CALLPROC_EBPSAFE(0x0069DDF1); break; case WIDX_GUESTS: @@ -302,7 +302,7 @@ static void window_game_bottom_toolbar_invalidate() } // Hide money if there is no money - if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) & 0x800) { + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & 0x800) { window_game_bottom_toolbar_widgets[WIDX_MONEY].type = WWT_EMPTY; window_game_bottom_toolbar_widgets[WIDX_GUESTS].top = 1; window_game_bottom_toolbar_widgets[WIDX_GUESTS].bottom = 17; diff --git a/src/window_land.c b/src/window_land.c index 3a47fa0937..ca9b9ea295 100644 --- a/src/window_land.c +++ b/src/window_land.c @@ -391,7 +391,7 @@ static void window_land_paint() if (RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_TERRAIN_EDGE, uint8) != 255) price += numTiles * 100; - if (price != 0 && !(RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) & GAME_FLAGS_NO_MONEY)) { + if (price != 0 && !(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY)) { RCT2_GLOBAL(0x013CE952, sint32) = price; gfx_draw_string_centred(dpi, 986, x, y, 0, 0x013CE952); } diff --git a/src/window_park.c b/src/window_park.c index e88059317b..8d2c3078f7 100644 --- a/src/window_park.c +++ b/src/window_park.c @@ -935,7 +935,7 @@ static void window_park_entrance_invalidate() } // Only allow closing of park and purchase of land when there is money - if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) & GAME_FLAGS_NO_MONEY) { + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY) { window_park_entrance_widgets[WIDX_OPEN_OR_CLOSE].type = WWT_EMPTY; window_park_entrance_widgets[WIDX_BUY_LAND_RIGHTS].type = WWT_EMPTY; window_park_entrance_widgets[WIDX_BUY_CONSTRUCTION_RIGHTS].type = WWT_EMPTY; @@ -1417,7 +1417,7 @@ static void window_park_price_invalidate() RCT2_GLOBAL(0x013CE952, uint16) = RCT2_GLOBAL(0x013573D4, uint16); RCT2_GLOBAL(0x013CE952 + 2, uint32) = RCT2_GLOBAL(0x013573D8, uint32); - if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) & GAME_FLAGS_PARK_FREE_ENTRY) { + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_PARK_FREE_ENTRY) { window_park_price_widgets[WIDX_PRICE].type = WWT_12; window_park_price_widgets[WIDX_INCREASE_PRICE].type = WWT_EMPTY; window_park_price_widgets[WIDX_DECREASE_PRICE].type = WWT_EMPTY; @@ -1711,7 +1711,7 @@ static void window_park_objective_invalidate() *((short*)0x013CE954) = RCT2_GLOBAL(0x013573D8, uint32); // - if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) & 0x02) + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & 0x02) window_park_objective_widgets[WIDX_ENTER_NAME].type = WWT_DROPDOWN_BUTTON; else window_park_objective_widgets[WIDX_ENTER_NAME].type = WWT_EMPTY; diff --git a/src/window_ride_list.c b/src/window_ride_list.c index 1d0476640f..92d08a7918 100644 --- a/src/window_ride_list.c +++ b/src/window_ride_list.c @@ -255,7 +255,7 @@ static void window_ride_list_mousedown() numItems = 9; if (w->page != PAGE_RIDES) numItems -= 5; - if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_FLAGS, uint32) & GAME_FLAGS_NO_MONEY) + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY) numItems--; for (i = 0; i < numItems; i++) {