From c7986d140c5154b0cc88a137f3846f9e37e8923b Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Tue, 19 Aug 2014 21:33:05 +0100 Subject: [PATCH 1/8] add widgets, sizing and basic events for new ride window --- src/park.h | 2 +- src/string_ids.h | 17 +- src/window.h | 1 + src/window_finances.c | 14 ++ src/window_new_ride.c | 428 ++++++++++++++++++++++++++++++++++++++++-- src/window_research.c | 6 +- 6 files changed, 448 insertions(+), 20 deletions(-) diff --git a/src/park.h b/src/park.h index b12fcbad51..bb7d823e86 100644 --- a/src/park.h +++ b/src/park.h @@ -35,7 +35,7 @@ enum { PARK_FLAGS_PREF_LESS_INTENSE_RIDES = (1 << 6), PARK_FLAGS_FORBID_MARKETING_CAMPAIGN = (1 << 7), PARK_FLAGS_PREF_MORE_INTENSE_RIDES = (1 << 8), - PARK_FLAGS_11 = (1 << 11), + PARK_FLAGS_11 = (1 << 11), // appears to be a copy of PARK_FLAGS_NO_MONEY PARK_FLAGS_DIFFICULT_GUEST_GENERATION = (1 << 12), PARK_FLAGS_PARK_FREE_ENTRY = (1 << 13), PARK_FLAGS_DIFFICULT_PARK_RATING = (1 << 14), diff --git a/src/string_ids.h b/src/string_ids.h index 15d483ca12..bf2b46bde3 100644 --- a/src/string_ids.h +++ b/src/string_ids.h @@ -237,7 +237,14 @@ enum { STR_SHOPS_AND_STALLS = 975, STR_RESTROOMS_AND_INFORMATION_KIOSKS = 976, + STR_NEW_TRANSPORT_RIDES = 977, + STR_NEW_GENTLE_RIDES = 978, + STR_NEW_ROLLER_COASTERS = 979, + STR_NEW_THRILL_RIDES = 980, + STR_NEW_WATER_RIDES = 981, + STR_NEW_SHOPS_STALLS = 982, STR_RESEARCH_AND_DEVELOPMENT = 983, + STR_RAISE_COST_AMOUNT = 984, STR_LOWER_COST_AMOUNT = 985, STR_COST_AMOUNT = 986, @@ -297,6 +304,13 @@ enum { STR_NUMERIC_UP = 1218, STR_NUMERIC_DOWN = 1219, + STR_TRANSPORT_RIDES_TIP = 1223, + STR_GENTLE_RIDES_TIP = 1224, + STR_ROLLER_COASTERS_TIP = 1225, + STR_THRILL_RIDES_TIP = 1226, + STR_WATER_RIDES_TIP = 1227, + STR_SHOPS_STALLS_TIP = 1228, + STR_ROTATE_OBJECTS_90 = 1327, STR_BUILD_THIS = 1407, @@ -511,7 +525,8 @@ enum { STR_RESEARCH_FUNDING_ = 2264, STR_RESEARCH_COST_PER_MONTH = 2265, STR_RESEARCH_PRIORITIES = 2266, - + STR_CURRENTLY_IN_DEVELOPMENT = 2267, + STR_LAST_DEVELOPMENT = 2268, STR_RESEARCH_TYPE_LABEL = 2269, STR_RESEARCH_PROGRESS_LABEL = 2270, STR_RESEARCH_EXPECTED_LABEL = 2271, diff --git a/src/window.h b/src/window.h index 9629975068..0881470998 100644 --- a/src/window.h +++ b/src/window.h @@ -373,6 +373,7 @@ void window_park_guests_open(); void window_park_objective_open(); void window_park_rating_open(); void window_finances_open(); +void window_finances_research_open(); void window_new_campaign_open(int campaignType); void window_ride_list_open(); void window_new_ride_open(); diff --git a/src/window_finances.c b/src/window_finances.c index d29c79e727..13c546cff3 100644 --- a/src/window_finances.c +++ b/src/window_finances.c @@ -553,6 +553,20 @@ void window_finances_open() window_init_scroll_widgets(w); } +/** + * + * rct2: 0x0069DDE1 + */ +void window_finances_research_open() +{ + rct_window *w; + + window_finances_open(); + w = window_find_by_id(WC_FINANCES, 0); + if (w != NULL) + window_finances_set_page(w, WINDOW_FINANCES_PAGE_RESEARCH); +} + #pragma region Summary page /** diff --git a/src/window_new_ride.c b/src/window_new_ride.c index 79137b0b29..ad99c387ac 100644 --- a/src/window_new_ride.c +++ b/src/window_new_ride.c @@ -21,17 +21,25 @@ #include #include "addresses.h" #include "game.h" +#include "news_item.h" +#include "string_ids.h" +#include "widget.h" #include "window.h" +#define _window_new_ride_current_tab RCT2_GLOBAL(0x00F43824, uint8) + enum { - WINDOW_NEW_RIDE_TAB_TRANSPORT, - WINDOW_NEW_RIDE_TAB_GENTLE, - WINDOW_NEW_RIDE_TAB_ROLLER_COASTER, - WINDOW_NEW_RIDE_TAB_THRILL, - WINDOW_NEW_RIDE_TAB_WATER, - WINDOW_NEW_RIDE_TAB_SHOP, - WINDOW_NEW_RIDE_TAB_RESEARCH -} WINDOW_RIDE_CONSTRUCTION_TAB; + WINDOW_NEW_RIDE_PAGE_TRANSPORT, + WINDOW_NEW_RIDE_PAGE_GENTLE, + WINDOW_NEW_RIDE_PAGE_ROLLER_COASTER, + WINDOW_NEW_RIDE_PAGE_THRILL, + WINDOW_NEW_RIDE_PAGE_WATER, + WINDOW_NEW_RIDE_PAGE_SHOP, + WINDOW_NEW_RIDE_PAGE_RESEARCH, + WINDOW_NEW_RIDE_PAGE_COUNT +}; + +#pragma region Widgets enum { WIDX_BACKGROUND, @@ -45,12 +53,89 @@ enum { WIDX_TAB_5, WIDX_TAB_6, WIDX_TAB_7, - + WIDX_RIDE_LIST, WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP, WIDX_LAST_DEVELOPMENT_GROUP, - WIDX_LAST_DEVELOPMENT_BUTTON + WIDX_LAST_DEVELOPMENT_BUTTON, + WIDX_RESEARCH_FUNDING_BUTTON }; +static rct_widget window_new_ride_widgets[] = { + { WWT_FRAME, 0, 0, 600, 0, 369, 0xFFFFFFFF, STR_NONE }, + { WWT_CAPTION, 0, 1, 599, 1, 14, 0xFFFFFFFF, STR_WINDOW_TITLE_TIP }, + { WWT_CLOSEBOX, 0, 588, 598, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, + { WWT_RESIZE, 1, 0, 600, 43, 369, 0xFFFFFFFF, STR_NONE }, + { WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, STR_TRANSPORT_RIDES_TIP }, + { WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, STR_GENTLE_RIDES_TIP }, + { WWT_TAB, 1, 65, 95, 17, 43, 0x2000144E, STR_ROLLER_COASTERS_TIP }, + { WWT_TAB, 1, 96, 126, 17, 43, 0x2000144E, STR_THRILL_RIDES_TIP }, + { WWT_TAB, 1, 127, 157, 17, 43, 0x2000144E, STR_WATER_RIDES_TIP }, + { WWT_TAB, 1, 158, 188, 17, 43, 0x2000144E, STR_SHOPS_STALLS_TIP }, + { WWT_TAB, 1, 189, 219, 17, 43, 0x2000144E, STR_RESEARCH_AND_DEVELOPMENT_TIP }, + { WWT_SCROLL, 1, 3, 597, 46, 317, 2, STR_NONE }, + { WWT_GROUPBOX, 2, 3, 292, 47, 116, STR_CURRENTLY_IN_DEVELOPMENT, STR_NONE }, + { WWT_GROUPBOX, 2, 3, 292, 124, 188, STR_LAST_DEVELOPMENT, STR_NONE }, + { WWT_FLATBTN, 2, 265, 288, 161, 184, 0xFFFFFFFF, STR_RESEARCH_SHOW_DETAILS_TIP }, + { WWT_FLATBTN, 2, 265, 288, 68, 91, 5190, STR_FINANCES_RESEARCH }, + { WIDGETS_END }, +}; + +#pragma endregion + +#pragma region Events + +static void window_new_ride_emptysub() { } + +static void window_new_ride_mouseup(); +static void window_new_ride_mousedown(int widgetIndex, rct_window *w, rct_widget *widget); +static void window_new_ride_update(rct_window *w); +static void window_new_ride_scrollgetsize(); +static void window_new_ride_scrollmousedown(); +static void window_new_ride_scrollmouseover(); +static void window_new_ride_tooltip(); +static void window_new_ride_invalidate(); +static void window_new_ride_paint(); +static void window_new_ride_scrollpaint(); + +// 0x0098E354 +static void* window_new_ride_events[] = { + window_new_ride_emptysub, + window_new_ride_mouseup, + window_new_ride_emptysub, + window_new_ride_mousedown, + window_new_ride_emptysub, + window_new_ride_emptysub, + window_new_ride_update, + window_new_ride_emptysub, + window_new_ride_emptysub, + window_new_ride_emptysub, + window_new_ride_emptysub, + window_new_ride_emptysub, + window_new_ride_emptysub, + window_new_ride_emptysub, + window_new_ride_emptysub, + window_new_ride_scrollgetsize, + window_new_ride_scrollmousedown, + window_new_ride_emptysub, + window_new_ride_scrollmouseover, + window_new_ride_emptysub, + window_new_ride_emptysub, + window_new_ride_emptysub, + window_new_ride_tooltip, + window_new_ride_emptysub, + window_new_ride_emptysub, + window_new_ride_invalidate, + window_new_ride_paint, + window_new_ride_scrollpaint +}; + +#pragma endregion + +const int window_new_ride_tab_animation_loops[] = { 20, 32, 10, 72, 24, 28, 16 }; +const int window_new_ride_tab_animation_divisor[] = { 4, 8, 2, 4, 4, 4, 2 }; + +static void window_new_ride_refresh_widget_sizing(rct_window *w); + /** * * rct2: 0x006ACA58 @@ -58,10 +143,10 @@ enum { void window_new_ride_init_vars() { // If we are in the track designer, default to the Roller Coaster tab if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_DESIGNER) { - RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_RIDE_LIST_SELECTED_TAB, uint8) = WINDOW_NEW_RIDE_TAB_ROLLER_COASTER; + RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_RIDE_LIST_SELECTED_TAB, uint8) = WINDOW_NEW_RIDE_PAGE_ROLLER_COASTER; } else { - RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_RIDE_LIST_SELECTED_TAB, uint8) = WINDOW_NEW_RIDE_TAB_TRANSPORT; + RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_RIDE_LIST_SELECTED_TAB, uint8) = WINDOW_NEW_RIDE_PAGE_TRANSPORT; } for (short i = 0; i < 6; i++) { @@ -91,8 +176,8 @@ void window_new_ride_open() window_close_by_id(161, 0); window_close_by_id(162, 0); - w = window_create_auto_pos(601, 370, (uint32*)0x0098E354, WC_CONSTRUCT_RIDE, 0x400); - w->widgets = (rct_widget*)0x009AEBF4; + w = window_create_auto_pos(601, 370, (uint32*)window_new_ride_events, WC_CONSTRUCT_RIDE, 0x400); + w->widgets = window_new_ride_widgets; w->enabled_widgets = (1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | @@ -121,6 +206,319 @@ void window_new_ride_open() w->var_482 = RCT2_GLOBAL(0x00F43523, sint16); w->width = 1; - RCT2_CALLPROC_EBPSAFE(0x006B3DF1); // initialise window size and widgets + window_new_ride_refresh_widget_sizing(w); RCT2_CALLPROC_EBPSAFE(0x006B7220); +} + +/** + * + * rct2: 0x006B3DF1 + */ +static void window_new_ride_refresh_widget_sizing(rct_window *w) +{ + int width, height; + + // Show or hide unrelated widgets + if (_window_new_ride_current_tab != WINDOW_NEW_RIDE_PAGE_RESEARCH) { + window_new_ride_widgets[WIDX_RIDE_LIST].type = WWT_SCROLL; + window_new_ride_widgets[WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP].type = WWT_EMPTY; + window_new_ride_widgets[WIDX_LAST_DEVELOPMENT_GROUP].type = WWT_EMPTY; + window_new_ride_widgets[WIDX_LAST_DEVELOPMENT_BUTTON].type = WWT_EMPTY; + window_new_ride_widgets[WIDX_RESEARCH_FUNDING_BUTTON].type = WWT_EMPTY; + + width = 601; + height = 370; + } else { + window_new_ride_widgets[WIDX_RIDE_LIST].type = WWT_EMPTY; + window_new_ride_widgets[WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP].type = WWT_GROUPBOX; + window_new_ride_widgets[WIDX_LAST_DEVELOPMENT_GROUP].type = WWT_GROUPBOX; + window_new_ride_widgets[WIDX_LAST_DEVELOPMENT_BUTTON].type = WWT_FLATBTN; + if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_11)) + window_new_ride_widgets[WIDX_RESEARCH_FUNDING_BUTTON].type = WWT_FLATBTN; + + width = 300; + height = 196; + } + + // Handle new window size + if (w->width != width || w->height != height) { + window_invalidate(w); + + // Resize widgets to new window size + window_new_ride_widgets[WIDX_BACKGROUND].right = width - 1; + window_new_ride_widgets[WIDX_BACKGROUND].bottom = height - 1; + window_new_ride_widgets[WIDX_PAGE_BACKGROUND].right = width - 1; + window_new_ride_widgets[WIDX_PAGE_BACKGROUND].bottom = height - 1; + window_new_ride_widgets[WIDX_TITLE].right = width - 2; + window_new_ride_widgets[WIDX_CLOSE].left = width - 13; + window_new_ride_widgets[WIDX_CLOSE].right = width - 3; + + w->width = width; + w->height = height; + window_invalidate(w); + } + + window_init_scroll_widgets(w); +} + +static void window_new_ride_set_pressed_tab(rct_window *w) +{ + int i; + for (i = 0; i < WINDOW_NEW_RIDE_PAGE_COUNT; i++) + w->pressed_widgets &= ~(1 << (WIDX_TAB_1 + i)); + w->pressed_widgets |= 1LL << (WIDX_TAB_1 + _window_new_ride_current_tab); +} + +const int ThrillRidesTabAnimationSequence[] = { + 5, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0 +}; + +static void window_new_ride_draw_tab_image(rct_drawpixelinfo *dpi, rct_window *w, int page, int spriteIndex) +{ + int widgetIndex = WIDX_TAB_1 + page; + + if (!(w->disabled_widgets & (1LL << widgetIndex))) { + int frame = 0; + if (_window_new_ride_current_tab == page) + frame = w->frame_no / window_new_ride_tab_animation_divisor[page]; + + spriteIndex += page == WINDOW_NEW_RIDE_PAGE_THRILL ? + ThrillRidesTabAnimationSequence[frame] : frame; + + spriteIndex |= w->colours[1] << 19; + + gfx_draw_sprite(dpi, spriteIndex, w->x + w->widgets[widgetIndex].left, w->y + w->widgets[widgetIndex].top, 0); + } +} + +static void window_new_ride_draw_tab_images(rct_drawpixelinfo *dpi, rct_window *w) +{ + window_new_ride_draw_tab_image(dpi, w, WINDOW_NEW_RIDE_PAGE_TRANSPORT, 0x200015A1); + window_new_ride_draw_tab_image(dpi, w, WINDOW_NEW_RIDE_PAGE_GENTLE, 5542); + window_new_ride_draw_tab_image(dpi, w, WINDOW_NEW_RIDE_PAGE_ROLLER_COASTER, 0x200015AA); + window_new_ride_draw_tab_image(dpi, w, WINDOW_NEW_RIDE_PAGE_THRILL, 5557); + window_new_ride_draw_tab_image(dpi, w, WINDOW_NEW_RIDE_PAGE_WATER, 5551); + window_new_ride_draw_tab_image(dpi, w, WINDOW_NEW_RIDE_PAGE_SHOP, 5530); + window_new_ride_draw_tab_image(dpi, w, WINDOW_NEW_RIDE_PAGE_RESEARCH, 5327); +} + +/** + * + * rct2: 0x006B6B38 + */ +static void window_new_ride_mouseup() +{ + short widgetIndex; + rct_window *w; + + window_mouse_up_get_registers(w, widgetIndex); + + switch (widgetIndex) { + case WIDX_CLOSE: + window_close(w); + break; + case WIDX_LAST_DEVELOPMENT_BUTTON: + news_item_open_subject(NEWS_ITEM_RESEARCH, RCT2_GLOBAL(RCT2_ADDRESS_LAST_RESEARCHED_ITEM_SUBJECT, sint32)); + break; + case WIDX_RESEARCH_FUNDING_BUTTON: + window_finances_research_open(); + break; + } +} + +/** + * + * rct2: 0x006B6B4F + */ +static void window_new_ride_mousedown(int widgetIndex, rct_window *w, rct_widget *widget) +{ + int page; + if (widgetIndex < WIDX_TAB_1 || widgetIndex > WIDX_TAB_7) + return; + + page = widgetIndex - WIDX_TAB_1; + + _window_new_ride_current_tab = page; + w->frame_no = 0; + w->var_482 = -1; + w->var_480 = -1; + RCT2_CALLPROC_EBPSAFE(0x006B6F3E); + if (page < WINDOW_NEW_RIDE_PAGE_RESEARCH) { + w->var_482 = RCT2_ADDRESS(0x00F43825, sint16)[page]; + if (w->var_482 == -1) + w->var_482 = RCT2_GLOBAL(0x00F43523, sint16); + } + + window_new_ride_refresh_widget_sizing(w); + window_invalidate(w); + RCT2_CALLPROC_EBPSAFE(0x006B7220); +} + +/** + * + * rct2: 0x006B6CE7 + */ +static void window_new_ride_update(rct_window *w) +{ + w->frame_no++; + if (w->frame_no >= window_new_ride_tab_animation_loops[_window_new_ride_current_tab]) + w->frame_no = 0; + + widget_invalidate(w->classification, w->number, WIDX_TAB_1 + _window_new_ride_current_tab); + + if (w->var_480 != -1 && w->var_488 == 1) + RCT2_CALLPROC_X(0x006B6B78, 0, 0, 0, 0, (int)w, 0, 0); +} + +/** + * + * rct2: 0x006B6BC9 + */ +static void window_new_ride_scrollgetsize() +{ + +} + +/** + * + * rct2: 0x006B6C89 + */ +static void window_new_ride_scrollmousedown() +{ + +} + +/** + * + * rct2: 0x006B6BBF + */ +static void window_new_ride_scrollmouseover() +{ + +} + +/** + * + * rct2: 0x006B6BBF + */ +static void window_new_ride_tooltip() +{ + RCT2_GLOBAL(0x013CE952, uint16) = 3159; +} + +/** + * + * rct2: 0x006B6819 + */ +static void window_new_ride_invalidate() +{ + rct_window *w; + + window_get_register(w); + + window_new_ride_set_pressed_tab(w); + + window_new_ride_widgets[WIDX_TITLE].image = STR_NEW_TRANSPORT_RIDES + _window_new_ride_current_tab; + window_new_ride_widgets[WIDX_TAB_7].type = WWT_TAB; + if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 4) + window_new_ride_widgets[WIDX_TAB_7].type = WWT_EMPTY; + + if (_window_new_ride_current_tab == WINDOW_NEW_RIDE_PAGE_RESEARCH) { + window_new_ride_widgets[WIDX_LAST_DEVELOPMENT_BUTTON].type = WWT_EMPTY; + uint32 typeId = RCT2_GLOBAL(0x01357CF4, uint32); + if (typeId != 0xFFFFFFFF) { + window_new_ride_widgets[WIDX_LAST_DEVELOPMENT_BUTTON].type = WWT_FLATBTN; + window_new_ride_widgets[WIDX_LAST_DEVELOPMENT_BUTTON].image = typeId >= 0x10000 ? 5189 : 5191; + } + } +} + +/** + * + * rct2: 0x006B689B + */ +static void window_new_ride_paint() +{ + rct_window *w; + rct_drawpixelinfo *dpi; + + window_paint_get_registers(w, dpi); + + window_draw_widgets(w, dpi); + window_new_ride_draw_tab_images(dpi, w); + + if (_window_new_ride_current_tab != WINDOW_NEW_RIDE_PAGE_RESEARCH) + return; + + int x = w->x + 10; + int y = w->y + window_new_ride_widgets[WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP].top + 12; + + // Research type + rct_string_id stringId = STR_RESEARCH_UNKNOWN; + if (RCT2_GLOBAL(0x01357CF3, uint8) != 0) { + stringId = STR_TRANSPORT_RIDE + RCT2_GLOBAL(0x013580E6, uint8); + if (RCT2_GLOBAL(0x01357CF3, uint8) != 1) { + uint32 typeId = RCT2_GLOBAL(0x013580E0, uint32); + if (typeId >= 0x10000) { + uint8 *rideEntry = RCT2_GLOBAL(0x009ACFA4 + (typeId & 0xFF) * 4, uint8*); + if (RCT2_GLOBAL(rideEntry + 8, uint32) & 0x1000) + stringId = RCT2_GLOBAL(rideEntry, uint16); + else + stringId = (typeId & 0xFF00) + 2; + } else { + uint8 *sceneryEntry = RCT2_GLOBAL(0x009ADA90 + (typeId & 0xFFFF) * 4, uint8*); + stringId = RCT2_GLOBAL(sceneryEntry, uint16); + } + } + } + gfx_draw_string_left_wrapped(dpi, &stringId, x, y, 296, STR_RESEARCH_TYPE_LABEL, 0); + y += 25; + + // Progress + stringId = 2285 + RCT2_GLOBAL(0x01357CF3, uint8); + gfx_draw_string_left_wrapped(dpi, &stringId, x, y, 296, STR_RESEARCH_PROGRESS_LABEL, 0); + y += 15; + + // Expected + RCT2_GLOBAL(0x013CE952, uint16) = STR_UNKNOWN; + if (RCT2_GLOBAL(0x01357CF3, uint8) != 0) { + uint16 expectedDay = RCT2_GLOBAL(RCT2_ADDRESS_NEXT_RESEARCH_EXPECTED_DAY, uint8); + if (expectedDay != 255) { + RCT2_GLOBAL(0x013CE952 + 2, uint16) = STR_DATE_DAY_1 + expectedDay; + RCT2_GLOBAL(0x013CE952 + 4, uint16) = STR_MONTH_MARCH + RCT2_GLOBAL(RCT2_ADDRESS_NEXT_RESEARCH_EXPECTED_MONTH, uint8); + RCT2_GLOBAL(0x013CE952, uint16) = 2289; + } + } + gfx_draw_string_left(dpi, STR_RESEARCH_EXPECTED_LABEL, (void*)0x013CE952, 0, x, y); + + // Last development + x = w->x + 10; + y = w->y + window_new_ride_widgets[WIDX_LAST_DEVELOPMENT_GROUP].top + 12; + + uint32 typeId = RCT2_GLOBAL(0x01357CF4, uint32); + if (typeId != 0xFFFFFFFF) { + if (typeId >= 0x10000) { + uint8 *rideEntry = RCT2_GLOBAL(0x009ACFA4 + (typeId & 0xFF) * 4, uint8*); + if (RCT2_GLOBAL(rideEntry + 8, uint32) & 0x1000) + stringId = RCT2_GLOBAL(rideEntry, uint16); + else + stringId = (typeId & 0xFF00) + 2; + } else { + uint8 *sceneryEntry = RCT2_GLOBAL(0x009ADA90 + (typeId & 0xFFFF) * 4, uint8*); + stringId = RCT2_GLOBAL(sceneryEntry, uint16); + } + gfx_draw_string_left_wrapped(dpi, &stringId, x, y, 266, STR_RESEARCH_RIDE_LABEL, 0); + } +} + +/** + * + * rct2: 0x006B6ABF + */ +static void window_new_ride_scrollpaint() +{ + rct_window *w; + rct_drawpixelinfo *dpi; + + window_paint_get_registers(w, dpi); } \ No newline at end of file diff --git a/src/window_research.c b/src/window_research.c index fd29a3b290..1ef643334b 100644 --- a/src/window_research.c +++ b/src/window_research.c @@ -68,8 +68,8 @@ static rct_widget window_research_development_widgets[] = { { WWT_RESIZE, 1, 0, 299, 43, 195, 0xFFFFFFFF, STR_NONE }, { WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, STR_RESEARCH_AND_DEVELOPMENT_TIP }, { WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, STR_FINANCES_RESEARCH }, - { WWT_GROUPBOX, 2, 3, 292, 47, 116, 2267, STR_NONE }, - { WWT_GROUPBOX, 2, 3, 292, 124, 188, 2268, STR_NONE }, + { WWT_GROUPBOX, 2, 3, 292, 47, 116, STR_CURRENTLY_IN_DEVELOPMENT, STR_NONE }, + { WWT_GROUPBOX, 2, 3, 292, 124, 188, STR_LAST_DEVELOPMENT, STR_NONE }, { WWT_FLATBTN, 2, 265, 288, 161, 184, 0xFFFFFFFF, STR_RESEARCH_SHOW_DETAILS_TIP }, { WIDGETS_END }, }; @@ -390,7 +390,7 @@ static void window_research_development_paint() stringId = RCT2_GLOBAL(sceneryEntry, uint16); } gfx_draw_string_left_wrapped(dpi, &stringId, x, y, 266, STR_RESEARCH_RIDE_LABEL, 0); - } + } } #pragma endregion From 9b08db7020415b668972e53090eed062460d63ac Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Wed, 20 Aug 2014 00:05:40 +0100 Subject: [PATCH 2/8] add window_new_ride_populate_list --- src/ride.h | 3 +- src/window_new_ride.c | 196 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 195 insertions(+), 4 deletions(-) diff --git a/src/ride.h b/src/ride.h index 264e7c13f4..be34a4eb33 100644 --- a/src/ride.h +++ b/src/ride.h @@ -259,7 +259,8 @@ enum { RIDE_TYPE_INVERTED_IMPULSE_COASTER, RIDE_TYPE_MINI_ROLLER_COASTER, RIDE_TYPE_MINE_RIDE, - RIDE_TYPE_LIM_LAUNCHED_ROLLER_COASTER + RIDE_TYPE_LIM_LAUNCHED_ROLLER_COASTER, + RIDE_TYPE_90 }; enum { diff --git a/src/window_new_ride.c b/src/window_new_ride.c index c955110573..bedda7fcdf 100644 --- a/src/window_new_ride.c +++ b/src/window_new_ride.c @@ -22,12 +22,118 @@ #include "addresses.h" #include "game.h" #include "news_item.h" +#include "ride.h" #include "string_ids.h" #include "widget.h" #include "window.h" #define _window_new_ride_current_tab RCT2_GLOBAL(0x00F43824, uint8) +typedef struct { + uint8 type; + uint8 entry_index; +} ride_list_item; + +#pragma region Ride type category mappings + +char RideTypeCategoryMap[] = { + // Transport rides + RIDE_TYPE_MINIATURE_RAILWAY, + RIDE_TYPE_MONORAIL, + RIDE_TYPE_SUSPENDED_MONORAIL, + RIDE_TYPE_CHAIRLIFT, + RIDE_TYPE_ELEVATOR, + + // Roller Coasters + RIDE_TYPE_SIDE_FRICTION_ROLLER_COASTER, + RIDE_TYPE_VIRGINIA_REEL, + RIDE_TYPE_REVERSER_ROLLER_COASTER, + RIDE_TYPE_WOODEN_ROLLER_COASTER, + RIDE_TYPE_WOODEN_WILD_MOUSE, + RIDE_TYPE_WILD_MOUSE, + RIDE_TYPE_INVERTED_HAIRPIN_COASTER, + RIDE_TYPE_JUNIOR_ROLLER_COASTER, + RIDE_TYPE_MINI_ROLLER_COASTER, + RIDE_TYPE_SPIRAL_ROLLER_COASTER, + RIDE_TYPE_MINE_TRAIN_COASTER, + RIDE_TYPE_LOOPING_ROLLER_COASTER, + RIDE_TYPE_STAND_UP_ROLLER_COASTER, + RIDE_TYPE_CORKSCREW_ROLLER_COASTER, + RIDE_TYPE_90, + RIDE_TYPE_TWISTER_ROLLER_COASTER, + RIDE_TYPE_GIGA_COASTER, + RIDE_TYPE_SUSPENDED_SWINGING_COASTER, + RIDE_TYPE_COMPACT_INVERTED_COASTER, + RIDE_TYPE_INVERTED_ROLLER_COASTER, + RIDE_TYPE_INVERTED_IMPULSE_COASTER, + RIDE_TYPE_MINI_SUSPENDED_COASTER, + RIDE_TYPE_STEEPLECHASE, + RIDE_TYPE_BOBSLEIGH_COASTER, + RIDE_TYPE_MINE_RIDE, + RIDE_TYPE_HEARTLINE_TWISTER_COASTER, + RIDE_TYPE_LAY_DOWN_ROLLER_COASTER, + RIDE_TYPE_FLYING_ROLLER_COASTER, + RIDE_TYPE_MULTI_DIMENSION_ROLLER_COASTER, + RIDE_TYPE_REVERSE_FREEFALL_COASTER, + RIDE_TYPE_VERTICAL_DROP_ROLLER_COASTER, + RIDE_TYPE_AIR_POWERED_VERTICAL_COASTER, + + // Gentle rides + RIDE_TYPE_MONORAIL_CYCLES, + RIDE_TYPE_CROOKED_HOUSE, + RIDE_TYPE_HAUNTED_HOUSE, + RIDE_TYPE_FERRIS_WHEEL, + RIDE_TYPE_MAZE, + RIDE_TYPE_MERRY_GO_ROUND, + RIDE_TYPE_MINI_GOLF, + RIDE_TYPE_OBSERVATION_TOWER, + RIDE_TYPE_CAR_RIDE, + RIDE_TYPE_MINI_HELICOPTERS, + RIDE_TYPE_SPIRAL_SLIDE, + RIDE_TYPE_BUMPER_CARS, + RIDE_TYPE_SPACE_RINGS, + RIDE_TYPE_CIRCUS_SHOW, + RIDE_TYPE_GHOST_TRAIN, + RIDE_TYPE_FLYING_SAUCERS, + + // Thrill rides + RIDE_TYPE_TWIST, + RIDE_TYPE_MAGIC_CARPET, + RIDE_TYPE_LAUNCHED_FREEFALL, + RIDE_TYPE_PIRATE_SHIP, + RIDE_TYPE_GO_KARTS, + RIDE_TYPE_SWINGING_INVERTER_SHIP, + RIDE_TYPE_MOTION_SIMULATOR, + RIDE_TYPE_3D_CINEMA, + RIDE_TYPE_TOP_SPIN, + RIDE_TYPE_ROTO_DROP, + RIDE_TYPE_ENTERPRISE, + + // Water rides + RIDE_TYPE_DINGHY_SLIDE, + RIDE_TYPE_LOG_FLUME, + RIDE_TYPE_RIVER_RAPIDS, + RIDE_TYPE_SPLASH_BOATS, + RIDE_TYPE_SUBMARINE_RIDE, + RIDE_TYPE_BUMPER_BOATS, + RIDE_TYPE_RIVER_RAFTS, + RIDE_TYPE_WATER_COASTER, + + // Shops / stalls + RIDE_TYPE_FOOD_STALL, + RIDE_TYPE_1D, + RIDE_TYPE_DRINK_STALL, + RIDE_TYPE_1F, + RIDE_TYPE_SHOP, + RIDE_TYPE_22, + RIDE_TYPE_INFORMATION_KIOSK, + RIDE_TYPE_FIRST_AID, + RIDE_TYPE_ATM, + RIDE_TYPE_BATHROOM +}; + +#pragma endregion + enum { WINDOW_NEW_RIDE_PAGE_TRANSPORT, WINDOW_NEW_RIDE_PAGE_GENTLE, @@ -160,6 +266,88 @@ void window_new_ride_init_vars() { RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_RIDE_LIST_INFORMATION_TYPE, uint8) = 0; } +uint8 *get_ride_entry_indices_for_ride_type(uint8 rideType) +{ + uint8 *typeToRideEntryIndexMap = (uint8*)0x009E32F8; + uint8 *entryIndexList = typeToRideEntryIndexMap; + while (rideType > 0) { + do { + entryIndexList++; + } while (*(entryIndexList - 1) != 255); + rideType--; + } + return entryIndexList; +} + +/** + * + * rct2: 0x006B6F3E + */ +static void window_new_ride_populate_list() +{ + int i, quadIndex, bitIndex; + + uint8 currentCategory = _window_new_ride_current_tab; + ride_list_item *nextListItem = (ride_list_item*)0x00F43523; + uint8 **rideEntries = (uint8**)0x009ACFA4; + + for (i = 0; i < countof(RideTypeCategoryMap); i++) { + uint8 rideType = RideTypeCategoryMap[i]; + if (rideType == RIDE_TYPE_NULL) + continue; + + quadIndex = rideType >> 5; + bitIndex = rideType & 0x1F; + if (RCT2_ADDRESS(0x01357404, uint32)[quadIndex] & (1 << bitIndex)) { + int dh = 0; + uint8 *rideEntryIndexPtr = get_ride_entry_indices_for_ride_type(rideType); + + // For each ride entry for this ride type + while (*rideEntryIndexPtr != 255) { + uint8 rideEntryIndex = *rideEntryIndexPtr++; + + quadIndex = rideEntryIndex >> 5; + bitIndex = rideEntryIndex & 0x1F; + if (!(RCT2_ADDRESS(0x01357424, uint32)[quadIndex] & (1 << bitIndex))) + continue; + + // Ride entries + uint8 *rideEntry = rideEntries[rideEntryIndex]; + uint8 categoryA = rideEntry[0x1BE]; + uint8 categoryB = rideEntry[0x1BF]; + + // Check if ride is in this category + if (currentCategory != categoryA && currentCategory != categoryB) + continue; + + if (rideEntry[8] & 0x2000) { + // loc_6B6FFB: + dh &= ~4; + nextListItem->type = rideType; + nextListItem->entry_index = rideEntryIndex; + nextListItem++; + } else if (!(dh & 1)) { + // loc_6B6FEA: + dh |= 5; + nextListItem->type = rideType; + nextListItem->entry_index = rideEntryIndex; + nextListItem++; + } else if (dh & 4) { + if (rideType == rideEntry[0x0C]) { + nextListItem--; + nextListItem->type = rideType; + nextListItem->entry_index = rideEntryIndex; + nextListItem++; + } + } + } + } + } + + nextListItem->type = 255; + nextListItem->entry_index = 255; +} + /** * * rct2: 0x006B3CFF @@ -199,9 +387,9 @@ void window_new_ride_open() w->var_482 = -1; RCT2_GLOBAL(0x00F43866, sint16) = -1; - RCT2_CALLPROC_EBPSAFE(0x006B6F3E); + window_new_ride_populate_list(); - w->var_482 = RCT2_ADDRESS(0x00F43825, sint16)[RCT2_GLOBAL(0x00F43824, uint8)]; + w->var_482 = RCT2_ADDRESS(0x00F43825, sint16)[_window_new_ride_current_tab]; if (w->var_482 == -1) w->var_482 = RCT2_GLOBAL(0x00F43523, sint16); @@ -342,7 +530,7 @@ static void window_new_ride_mousedown(int widgetIndex, rct_window *w, rct_widget w->frame_no = 0; w->var_482 = -1; w->var_480 = -1; - RCT2_CALLPROC_EBPSAFE(0x006B6F3E); + window_new_ride_populate_list(); if (page < WINDOW_NEW_RIDE_PAGE_RESEARCH) { w->var_482 = RCT2_ADDRESS(0x00F43825, sint16)[page]; if (w->var_482 == -1) @@ -521,4 +709,6 @@ static void window_new_ride_scrollpaint() rct_drawpixelinfo *dpi; window_paint_get_registers(w, dpi); + + RCT2_CALLPROC_X(0x006B6ABF, 0, 0, 0, 0, w, dpi, 0); } \ No newline at end of file From 01e32c301d3885f11f723df613e22131c943977e Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Wed, 20 Aug 2014 07:50:01 +0100 Subject: [PATCH 3/8] improve new ride window populate docs --- src/window_new_ride.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/window_new_ride.c b/src/window_new_ride.c index bedda7fcdf..ac16cc6a88 100644 --- a/src/window_new_ride.c +++ b/src/window_new_ride.c @@ -34,9 +34,13 @@ typedef struct { uint8 entry_index; } ride_list_item; -#pragma region Ride type category mappings +#pragma region Ride type view order -char RideTypeCategoryMap[] = { +/** + * The order of ride types shown in the new ride window so that the order stays consistent across games and rides of the same + * type are kept together. + */ +const char RideTypeViewOrder[] = { // Transport rides RIDE_TYPE_MINIATURE_RAILWAY, RIDE_TYPE_MONORAIL, @@ -291,8 +295,9 @@ static void window_new_ride_populate_list() ride_list_item *nextListItem = (ride_list_item*)0x00F43523; uint8 **rideEntries = (uint8**)0x009ACFA4; - for (i = 0; i < countof(RideTypeCategoryMap); i++) { - uint8 rideType = RideTypeCategoryMap[i]; + // For each ride type in the view order list + for (i = 0; i < countof(RideTypeViewOrder); i++) { + uint8 rideType = RideTypeViewOrder[i]; if (rideType == RIDE_TYPE_NULL) continue; @@ -710,5 +715,5 @@ static void window_new_ride_scrollpaint() window_paint_get_registers(w, dpi); - RCT2_CALLPROC_X(0x006B6ABF, 0, 0, 0, 0, w, dpi, 0); + RCT2_CALLPROC_X(0x006B6ABF, 0, 0, 0, 0, (int)w, (int)dpi, 0); } \ No newline at end of file From 8e4cc238cc4e7b394d9f1970db9661f90fbd53ea Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Wed, 20 Aug 2014 20:18:17 +0100 Subject: [PATCH 4/8] fix window_new_ride_populate_list and add window_new_ride_scroll_to_focused_ride --- src/window_new_ride.c | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/src/window_new_ride.c b/src/window_new_ride.c index ac16cc6a88..badaef4f73 100644 --- a/src/window_new_ride.c +++ b/src/window_new_ride.c @@ -325,14 +325,12 @@ static void window_new_ride_populate_list() if (currentCategory != categoryA && currentCategory != categoryB) continue; - if (rideEntry[8] & 0x2000) { - // loc_6B6FFB: + if (RCT2_GLOBAL(rideEntry + 8, uint32) & 0x2000) { dh &= ~4; nextListItem->type = rideType; nextListItem->entry_index = rideEntryIndex; nextListItem++; } else if (!(dh & 1)) { - // loc_6B6FEA: dh |= 5; nextListItem->type = rideType; nextListItem->entry_index = rideEntryIndex; @@ -353,6 +351,43 @@ static void window_new_ride_populate_list() nextListItem->entry_index = 255; } +/** + * + * rct2: 0x006B7220 + */ +static void window_new_ride_scroll_to_focused_ride(rct_window *w) +{ + int eax, ebx, ecx, edx, esi, edi, ebp; + + // Get the scroll height + eax = 0; + esi = (int)w; + RCT2_CALLFUNC_X(w->event_handlers[WE_SCROLL_GETSIZE], &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + int scrollHeight = edx; + ebx = 0; + + // Find row index of the focused ride type + rct_widget *listWidget = &window_new_ride_widgets[WIDX_RIDE_LIST]; + int focusRideType = RCT2_ADDRESS(0x00F43825, uint16)[_window_new_ride_current_tab]; + int count = 0, row = 0; + ride_list_item *listItem = (ride_list_item*)0x00F43523; + while (listItem->type != 255 || listItem->entry_index != 255) { + if (listItem->type == focusRideType) { + row = count / 5; + break; + } + + count++; + listItem++; + }; + + // Update the Y scroll position + int listWidgetHeight = listWidget->bottom - listWidget->top - 1; + scrollHeight = max(0, scrollHeight - listWidgetHeight); + w->scrolls[0].v_top = min(row * 116, scrollHeight); + widget_scroll_update_thumbs(w, WIDX_RIDE_LIST); +} + /** * * rct2: 0x006B3CFF @@ -400,7 +435,7 @@ void window_new_ride_open() w->width = 1; window_new_ride_refresh_widget_sizing(w); - RCT2_CALLPROC_X(0x006B7220, 0, 0, 0, 0, (int)w, 0, 0); + window_new_ride_scroll_to_focused_ride(w); } /** From 8644ed5b578fffb8ee94afd998c68e011ddce2aa Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Wed, 20 Aug 2014 22:06:47 +0100 Subject: [PATCH 5/8] implement scroll mouse events for new ride window --- src/window_new_ride.c | 118 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 114 insertions(+), 4 deletions(-) diff --git a/src/window_new_ride.c b/src/window_new_ride.c index badaef4f73..367562f90f 100644 --- a/src/window_new_ride.c +++ b/src/window_new_ride.c @@ -20,6 +20,7 @@ #include #include "addresses.h" +#include "audio.h" #include "game.h" #include "news_item.h" #include "ride.h" @@ -245,6 +246,9 @@ const int window_new_ride_tab_animation_loops[] = { 20, 32, 10, 72, 24, 28, 16 } const int window_new_ride_tab_animation_divisor[] = { 4, 8, 2, 4, 4, 4, 2 }; static void window_new_ride_refresh_widget_sizing(rct_window *w); +static ride_list_item window_new_ride_scroll_get_ride_list_item_at(rct_window *w, int x, int y); +static void window_new_ride_paint_ride_information(rct_window *w, rct_drawpixelinfo *dpi, ride_list_item item, int x, int y, int width, int unk); +static void window_new_ride_select(rct_window *w); /** * @@ -594,8 +598,8 @@ static void window_new_ride_update(rct_window *w) widget_invalidate(w->classification, w->number, WIDX_TAB_1 + _window_new_ride_current_tab); - if (w->var_480 != -1 && w->var_488 == 1) - RCT2_CALLPROC_X(0x006B6B78, 0, 0, 0, 0, (int)w, 0, 0); + if (w->var_480 != -1 && w->var_488-- == 0) + window_new_ride_select(w); } /** @@ -604,7 +608,28 @@ static void window_new_ride_update(rct_window *w) */ static void window_new_ride_scrollgetsize() { + ride_list_item *listItem = (ride_list_item*)0x00F43523; + int scrollWidth, scrollHeight; + int count = 0; + while (listItem->type != 255 || listItem->entry_index != 255) { + count++; + listItem++; + } + scrollWidth = 0; + scrollHeight = ((count + 4) / 5) * 116; + + #ifdef _MSC_VER + __asm mov ecx, scrollWidth + #else + __asm__ ( "mov ecx, %[scrollWidth] " : [scrollWidth] "+m" (scrollWidth) ); + #endif + + #ifdef _MSC_VER + __asm mov edx, scrollHeight + #else + __asm__ ( "mov edx, %[scrollHeight] " : [scrollHeight] "+m" (scrollHeight) ); + #endif } /** @@ -613,16 +638,47 @@ static void window_new_ride_scrollgetsize() */ static void window_new_ride_scrollmousedown() { + short x, y; + rct_window *w; + window_scrollmouse_get_registers(w, x, y); + + if (RCT2_GLOBAL(0x009DEA6E, uint8) != 0) + return; + + ride_list_item item = window_new_ride_scroll_get_ride_list_item_at(w, x, y); + if (item.type == 255 && item.entry_index == 255) + return; + + RCT2_ADDRESS(0x00F43825, ride_list_item)[_window_new_ride_current_tab] = item; + w->var_480 = *((sint16*)&item); + + sound_play_panned(SOUND_CLICK_1, w->x + (w->width / 2)); + w->var_488 = 8; + window_invalidate(w); } /** * - * rct2: 0x006B6BBF + * rct2: 0x006B6C51 */ static void window_new_ride_scrollmouseover() { + short x, y; + rct_window *w; + window_scrollmouse_get_registers(w, x, y); + + if (w->var_480 != -1) + return; + + ride_list_item item = window_new_ride_scroll_get_ride_list_item_at(w, x, y); + if (w->var_482 == *((sint16*)&item)) + return; + + w->var_482 = *((sint16*)&item); + RCT2_ADDRESS(0x00F43825, ride_list_item)[_window_new_ride_current_tab] = item; + window_invalidate(w); } /** @@ -675,8 +731,14 @@ static void window_new_ride_paint() window_draw_widgets(w, dpi); window_new_ride_draw_tab_images(dpi, w); - if (_window_new_ride_current_tab != WINDOW_NEW_RIDE_PAGE_RESEARCH) + if (_window_new_ride_current_tab != WINDOW_NEW_RIDE_PAGE_RESEARCH) { + ride_list_item item = *((ride_list_item*)&w->var_482); + if (item.type == 255 && item.entry_index == 255) + return; + + window_new_ride_paint_ride_information(w, dpi, item, w->x + 3, w->y + w->height - 52, w->width - 6, 256); return; + } int x = w->x + 10; int y = w->y + window_new_ride_widgets[WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP].top + 12; @@ -751,4 +813,52 @@ static void window_new_ride_scrollpaint() window_paint_get_registers(w, dpi); RCT2_CALLPROC_X(0x006B6ABF, 0, 0, 0, 0, (int)w, (int)dpi, 0); +} + +/** + * + * rct2: 0x006B6D3C + */ +static ride_list_item window_new_ride_scroll_get_ride_list_item_at(rct_window *w, int x, int y) +{ + ride_list_item result; + result.type = 255; + result.entry_index = 255; + + if (--x < 0 || --y < 0) + return result; + + int column = x / 116; + int row = y / 116; + if (row >= 5) + return result; + + int index = column + (row * 5); + + ride_list_item *listItem = (ride_list_item*)0x00F43523; + while (listItem->type != 255 || listItem->entry_index != 255) { + if (index-- == 0) + return *listItem; + listItem++; + } + + return result; +} + +/** + * + * rct2: 0x006B701C + */ +static void window_new_ride_paint_ride_information(rct_window *w, rct_drawpixelinfo *dpi, ride_list_item item, int x, int y, int width, int unk) +{ + RCT2_CALLPROC_X(0x006B701C, w->var_482, unk, x, y, (int)w, (int)dpi, width); +} + +/** + * + * rct2: 0x006B6B78 + */ +static void window_new_ride_select(rct_window *w) +{ + RCT2_CALLPROC_X(0x006B6B78, 0, 0, 0, 0, (int)w, 0, 0); } \ No newline at end of file From b4e72cf960f49e4877ae7e003cf9768cf0f1ce41 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Thu, 21 Aug 2014 21:48:23 +0100 Subject: [PATCH 6/8] add window_new_ride_paint_ride_information --- src/window_new_ride.c | 95 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 2 deletions(-) diff --git a/src/window_new_ride.c b/src/window_new_ride.c index 367562f90f..88b909ed25 100644 --- a/src/window_new_ride.c +++ b/src/window_new_ride.c @@ -25,6 +25,7 @@ #include "news_item.h" #include "ride.h" #include "string_ids.h" +#include "track.h" #include "widget.h" #include "window.h" @@ -250,6 +251,9 @@ static ride_list_item window_new_ride_scroll_get_ride_list_item_at(rct_window *w static void window_new_ride_paint_ride_information(rct_window *w, rct_drawpixelinfo *dpi, ride_list_item item, int x, int y, int width, int unk); static void window_new_ride_select(rct_window *w); +static ride_list_item _lastTrackDesignCountRideType; +static int _lastTrackDesignCount; + /** * * rct2: 0x006ACA58 @@ -429,7 +433,8 @@ void window_new_ride_open() w->colours[2] = 26; w->var_480 = -1; w->var_482 = -1; - RCT2_GLOBAL(0x00F43866, sint16) = -1; + _lastTrackDesignCountRideType.type = 255; + _lastTrackDesignCountRideType.entry_index = 255; window_new_ride_populate_list(); @@ -845,13 +850,99 @@ static ride_list_item window_new_ride_scroll_get_ride_list_item_at(rct_window *w return result; } +static int get_num_track_designs(ride_list_item item) +{ + track_load_list(*((uint16*)&item)); + + uint8 *trackDesignList = (uint8*)0x00F441EC; + int count = 0; + while (*trackDesignList != 0 && trackDesignList < (uint8*)0x00F635EC) { + trackDesignList += 128; + count++; + } + return count; +} + /** * * rct2: 0x006B701C */ static void window_new_ride_paint_ride_information(rct_window *w, rct_drawpixelinfo *dpi, ride_list_item item, int x, int y, int width, int unk) { - RCT2_CALLPROC_X(0x006B701C, w->var_482, unk, x, y, (int)w, (int)dpi, width); + uint8 **rideEntries = (uint8**)0x009ACFA4; + + if (unk & 1) { + if (unk & 6) + gfx_fill_rect_inset(dpi, x, y, x + 115, y + 115, w->colours[1], 0x20); + + uint8 *rideEntry = rideEntries[item.entry_index]; + int ebp = RCT2_GLOBAL(rideEntry + 4, uint32); + if (item.type != RCT2_GLOBAL(rideEntry + 12, uint32)) + ebp++; + if (item.type != RCT2_GLOBAL(rideEntry + 13, uint32)) + ebp++; + + RCT2_CALLPROC_X(0x00681DE2, 0, 29013, x + 2, y + 2, (int)w, (int)dpi, ebp); + } + + if (unk & 0x100) { + uint8 *rideEntry = rideEntries[item.entry_index]; + + // Ride name and description + rct_string_id rideName = RCT2_GLOBAL(rideEntry + 0, uint16); + rct_string_id rideDescription = RCT2_GLOBAL(rideEntry + 2, uint16); + if (!(RCT2_GLOBAL(rideEntry + 8, uint32) & 0x1000)) { + rideName = item.type + 2; + rideDescription = item.type + 512; + } + + RCT2_GLOBAL(0x013CE952 + 0, rct_string_id) = rideName; + RCT2_GLOBAL(0x013CE952 + 2, rct_string_id) = rideDescription; + gfx_draw_string_left_wrapped(dpi, (void*)0x013CE952, x, y, width, 1690, 0); + + // Number of designs available + uint32 rideTypeFlags = RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + (item.type * 8), uint32); + if (rideTypeFlags & 0x10000000) { + if (item.type != _lastTrackDesignCountRideType.type || item.entry_index != _lastTrackDesignCountRideType.entry_index) { + _lastTrackDesignCountRideType = item; + _lastTrackDesignCount = get_num_track_designs(item); + } + + rct_string_id stringId; + switch (_lastTrackDesignCount) { + case 0: + stringId = 3338; + break; + case 1: + stringId = 3339; + break; + default: + stringId = 3340; + break; + } + gfx_draw_string_left(dpi, stringId, &_lastTrackDesignCount, 0, x, y + 40); + } + + // Price + if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_11)) { + // Get price of ride + int unk2 = RCT2_GLOBAL(0x0097CC68 + (item.type * 2), uint8); + money32 price = RCT2_GLOBAL(0x0097DD78 + (item.type * 4), uint16); + if (rideTypeFlags & 0x80000) { + price *= RCT2_ADDRESS(0x0099DE34, uint32)[unk2]; + } else { + price *= RCT2_ADDRESS(0x0099DA34, uint32)[unk2]; + } + price = (price >> 17) * 10 * RCT2_GLOBAL(0x0097D21D + (item.type * 8), uint8); + + // + rct_string_id stringId = 1691; + if (!(rideTypeFlags & 0x8000)) + stringId++; + + gfx_draw_string_right(dpi, stringId, &price, 0, x + width, y + 40); + } + } } /** From 25a31b9875117969671a6463148d0524ae14adbe Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Thu, 21 Aug 2014 22:33:36 +0100 Subject: [PATCH 7/8] clear up window_new_ride a bit --- src/window_new_ride.c | 155 ++++++++++++++++++++++++------------------ 1 file changed, 87 insertions(+), 68 deletions(-) diff --git a/src/window_new_ride.c b/src/window_new_ride.c index 88b909ed25..0dd1c09184 100644 --- a/src/window_new_ride.c +++ b/src/window_new_ride.c @@ -248,7 +248,7 @@ const int window_new_ride_tab_animation_divisor[] = { 4, 8, 2, 4, 4, 4, 2 }; static void window_new_ride_refresh_widget_sizing(rct_window *w); static ride_list_item window_new_ride_scroll_get_ride_list_item_at(rct_window *w, int x, int y); -static void window_new_ride_paint_ride_information(rct_window *w, rct_drawpixelinfo *dpi, ride_list_item item, int x, int y, int width, int unk); +static void window_new_ride_paint_ride_information(rct_window *w, rct_drawpixelinfo *dpi, ride_list_item item, int x, int y, int width); static void window_new_ride_select(rct_window *w); static ride_list_item _lastTrackDesignCountRideType; @@ -588,7 +588,7 @@ static void window_new_ride_mousedown(int widgetIndex, rct_window *w, rct_widget window_new_ride_refresh_widget_sizing(w); window_invalidate(w); - RCT2_CALLPROC_EBPSAFE(0x006B7220); + window_new_ride_scroll_to_focused_ride(w); } /** @@ -741,7 +741,7 @@ static void window_new_ride_paint() if (item.type == 255 && item.entry_index == 255) return; - window_new_ride_paint_ride_information(w, dpi, item, w->x + 3, w->y + w->height - 52, w->width - 6, 256); + window_new_ride_paint_ride_information(w, dpi, item, w->x + 3, w->y + w->height - 52, w->width - 6); return; } @@ -814,10 +814,46 @@ static void window_new_ride_scrollpaint() { rct_window *w; rct_drawpixelinfo *dpi; + uint8 **rideEntries = (uint8**)0x009ACFA4; window_paint_get_registers(w, dpi); - RCT2_CALLPROC_X(0x006B6ABF, 0, 0, 0, 0, (int)w, (int)dpi, 0); + if (_window_new_ride_current_tab == WINDOW_NEW_RIDE_PAGE_RESEARCH) + return; + + gfx_clear(dpi, RCT2_GLOBAL(0x0141FC48 + (w->colours[1] * 8), uint8) * 0x1010101); + + int x = 1; + int y = 1; + ride_list_item *listItem = (ride_list_item*)0x00F43523; + while (listItem->type != 255 || listItem->entry_index != 255) { + // Draw flat button rectangle + int flags = 0; + if (w->var_480 == *((sint16*)listItem)) + flags |= 0x20; + if (w->var_482 == *((sint16*)listItem) || flags != 0) + gfx_fill_rect_inset(dpi, x, y, x + 115, y + 115, w->colours[1], 0x80 | flags); + + // Draw ride image + uint8 *rideEntry = rideEntries[listItem->entry_index]; + int unk = RCT2_GLOBAL(rideEntry + 4, uint32); + if (listItem->type != RCT2_GLOBAL(rideEntry + 12, uint8)) { + unk++; + if (listItem->type != RCT2_GLOBAL(rideEntry + 13, uint8)) + unk++; + } + RCT2_CALLPROC_X(0x00681DE2, 0, 29013, x + 2, y + 2, 0xA0, (int)dpi, unk); + + // Next position + x += 116; + if (x >= 116 * 5 + 1) { + x = 1; + y += 116; + } + + // Next item + listItem++; + } } /** @@ -867,81 +903,64 @@ static int get_num_track_designs(ride_list_item item) * * rct2: 0x006B701C */ -static void window_new_ride_paint_ride_information(rct_window *w, rct_drawpixelinfo *dpi, ride_list_item item, int x, int y, int width, int unk) +static void window_new_ride_paint_ride_information(rct_window *w, rct_drawpixelinfo *dpi, ride_list_item item, int x, int y, int width) { uint8 **rideEntries = (uint8**)0x009ACFA4; + uint8 *rideEntry = rideEntries[item.entry_index]; - if (unk & 1) { - if (unk & 6) - gfx_fill_rect_inset(dpi, x, y, x + 115, y + 115, w->colours[1], 0x20); - - uint8 *rideEntry = rideEntries[item.entry_index]; - int ebp = RCT2_GLOBAL(rideEntry + 4, uint32); - if (item.type != RCT2_GLOBAL(rideEntry + 12, uint32)) - ebp++; - if (item.type != RCT2_GLOBAL(rideEntry + 13, uint32)) - ebp++; - - RCT2_CALLPROC_X(0x00681DE2, 0, 29013, x + 2, y + 2, (int)w, (int)dpi, ebp); + // Ride name and description + rct_string_id rideName = RCT2_GLOBAL(rideEntry + 0, uint16); + rct_string_id rideDescription = RCT2_GLOBAL(rideEntry + 2, uint16); + if (!(RCT2_GLOBAL(rideEntry + 8, uint32) & 0x1000)) { + rideName = item.type + 2; + rideDescription = item.type + 512; } - if (unk & 0x100) { - uint8 *rideEntry = rideEntries[item.entry_index]; + RCT2_GLOBAL(0x013CE952 + 0, rct_string_id) = rideName; + RCT2_GLOBAL(0x013CE952 + 2, rct_string_id) = rideDescription; + gfx_draw_string_left_wrapped(dpi, (void*)0x013CE952, x, y, width, 1690, 0); - // Ride name and description - rct_string_id rideName = RCT2_GLOBAL(rideEntry + 0, uint16); - rct_string_id rideDescription = RCT2_GLOBAL(rideEntry + 2, uint16); - if (!(RCT2_GLOBAL(rideEntry + 8, uint32) & 0x1000)) { - rideName = item.type + 2; - rideDescription = item.type + 512; + // Number of designs available + uint32 rideTypeFlags = RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + (item.type * 8), uint32); + if (rideTypeFlags & 0x10000000) { + if (item.type != _lastTrackDesignCountRideType.type || item.entry_index != _lastTrackDesignCountRideType.entry_index) { + _lastTrackDesignCountRideType = item; + _lastTrackDesignCount = get_num_track_designs(item); } - RCT2_GLOBAL(0x013CE952 + 0, rct_string_id) = rideName; - RCT2_GLOBAL(0x013CE952 + 2, rct_string_id) = rideDescription; - gfx_draw_string_left_wrapped(dpi, (void*)0x013CE952, x, y, width, 1690, 0); - - // Number of designs available - uint32 rideTypeFlags = RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + (item.type * 8), uint32); - if (rideTypeFlags & 0x10000000) { - if (item.type != _lastTrackDesignCountRideType.type || item.entry_index != _lastTrackDesignCountRideType.entry_index) { - _lastTrackDesignCountRideType = item; - _lastTrackDesignCount = get_num_track_designs(item); - } - - rct_string_id stringId; - switch (_lastTrackDesignCount) { - case 0: - stringId = 3338; - break; - case 1: - stringId = 3339; - break; - default: - stringId = 3340; - break; - } - gfx_draw_string_left(dpi, stringId, &_lastTrackDesignCount, 0, x, y + 40); + rct_string_id stringId; + switch (_lastTrackDesignCount) { + case 0: + stringId = 3338; + break; + case 1: + stringId = 3339; + break; + default: + stringId = 3340; + break; } + gfx_draw_string_left(dpi, stringId, &_lastTrackDesignCount, 0, x, y + 40); + } - // Price - if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_11)) { - // Get price of ride - int unk2 = RCT2_GLOBAL(0x0097CC68 + (item.type * 2), uint8); - money32 price = RCT2_GLOBAL(0x0097DD78 + (item.type * 4), uint16); - if (rideTypeFlags & 0x80000) { - price *= RCT2_ADDRESS(0x0099DE34, uint32)[unk2]; - } else { - price *= RCT2_ADDRESS(0x0099DA34, uint32)[unk2]; - } - price = (price >> 17) * 10 * RCT2_GLOBAL(0x0097D21D + (item.type * 8), uint8); - - // - rct_string_id stringId = 1691; - if (!(rideTypeFlags & 0x8000)) - stringId++; - - gfx_draw_string_right(dpi, stringId, &price, 0, x + width, y + 40); + // Price + if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_11)) { + // Get price of ride + int unk2 = RCT2_GLOBAL(0x0097CC68 + (item.type * 2), uint8); + money32 price = RCT2_GLOBAL(0x0097DD78 + (item.type * 4), uint16); + if (rideTypeFlags & 0x80000) { + price *= RCT2_ADDRESS(0x0099DE34, uint32)[unk2]; + } else { + price *= RCT2_ADDRESS(0x0099DA34, uint32)[unk2]; } + price = (price >> 17) * 10 * RCT2_GLOBAL(0x0097D21D + (item.type * 8), uint8); + + // + rct_string_id stringId = 1691; + if (!(rideTypeFlags & 0x8000)) + stringId++; + + gfx_draw_string_right(dpi, stringId, &price, 0, x + width, y + 40); } } From 76ca655b0eddf83b9c673aba64bf167b904e59af Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Thu, 21 Aug 2014 22:50:06 +0100 Subject: [PATCH 8/8] finish window_new_ride --- src/window_new_ride.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/window_new_ride.c b/src/window_new_ride.c index 0dd1c09184..8f0969b269 100644 --- a/src/window_new_ride.c +++ b/src/window_new_ride.c @@ -970,5 +970,24 @@ static void window_new_ride_paint_ride_information(rct_window *w, rct_drawpixeli */ static void window_new_ride_select(rct_window *w) { - RCT2_CALLPROC_X(0x006B6B78, 0, 0, 0, 0, (int)w, 0, 0); + ride_list_item item = *((ride_list_item*)&w->var_480); + if (item.type == 255) + return; + + window_close(w); + + uint32 rideTypeFlags = RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + (item.type * 8), uint32); + if (rideTypeFlags & 0x10000000) { + track_load_list(*((sint16*)&item)); + + uint8 *trackDesignList = (uint8*)0x00F441EC; + if (*trackDesignList != 0) { + // Show track design list + RCT2_CALLPROC_X(0x006CF1A2, *((sint16*)&item), 0, 0, 0, 0, 0, 0); + return; + } + } + + // Show ride construction window + RCT2_CALLPROC_X(0x006B4800, *((sint16*)&item), 0, 0, 0, 0, 0, 0); } \ No newline at end of file