From caa7a50ec2c0c000f2f53ee55a0acfd3788c1853 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Fri, 5 Sep 2014 18:10:30 +0100 Subject: [PATCH] implement measurements tab on ride window --- src/park.c | 2 +- src/rct2.h | 2 +- src/ride.c | 8 + src/ride.h | 35 ++-- src/ride_ratings.c | 19 +- src/scenario.c | 8 +- src/string_ids.c | 4 +- src/string_ids.h | 50 ++++- src/window_ride.c | 509 ++++++++++++++++++++++++++++++++++++++++++++- 9 files changed, 590 insertions(+), 47 deletions(-) diff --git a/src/park.c b/src/park.c index 3621c3db7f..ed937cab47 100644 --- a/src/park.c +++ b/src/park.c @@ -395,7 +395,7 @@ static int park_calculate_guest_generation_probability() continue; if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_TESTED)) continue; - if (ride->var_0E4 < 0x2580000) + if (ride->length[0] < (600 << 16)) continue; if (ride->excitement < RIDE_RATING(6,00)) continue; diff --git a/src/rct2.h b/src/rct2.h index 643aec1c29..6589990001 100644 --- a/src/rct2.h +++ b/src/rct2.h @@ -84,7 +84,7 @@ typedef fixed32_1dp money32; // would write FIXED_2DP(3,65) #define FIXED_XDP(x, whole, fraction) ((whole) * (10 * x) + (fraction)) #define FIXED_1DP(whole, fraction) FIXED_XDP(1, whole, fraction) -#define FIXED_2DP(whole, fraction) FIXED_XDP(2, whole, fraction) +#define FIXED_2DP(whole, fraction) FIXED_XDP(10, whole, fraction) // Construct a money value in the format MONEY(10,70) to represent 10.70. Fractional part must be two digits. #define MONEY(whole, fraction) ((whole) * 10 + ((fraction) / 10)) diff --git a/src/ride.c b/src/ride.c index 35bdafb0a1..e212989516 100644 --- a/src/ride.c +++ b/src/ride.c @@ -539,4 +539,12 @@ rct_peep *ride_get_assigned_mechanic(rct_ride *ride) } return NULL; +} + +int ride_get_total_length(rct_ride *ride) +{ + int i, totalLength = 0; + for (i = 0; i < ride->num_stations; i++) + totalLength += ride->length[i]; + return totalLength; } \ No newline at end of file diff --git a/src/ride.h b/src/ride.h index 0708d9c521..0d1615fcee 100644 --- a/src/ride.h +++ b/src/ride.h @@ -95,17 +95,21 @@ typedef struct { uint8 num_vehicles; // 0x0C8 uint8 var_0C9; - uint8 pad_0CA[0x1A]; - - sint32 var_0E4; - sint32 var_0E8; - sint32 var_0EC; - sint32 var_0F0; - uint8 pad_0F4[0x20]; - uint8 var_114; - // Track length? Number of track segments? - uint8 var_115; - uint8 pad_116[0x0E]; + uint8 pad_0CA[0xE]; + sint32 max_speed; // 0x0D8 + sint32 average_speed; // 0x0DC + uint8 pad_0E0[0x4]; + sint32 length[4]; // 0x0E4 + uint16 time[4]; // 0x0F4 + fixed16_2dp maxPositiveVerticalGs; // 0x0FC + fixed16_2dp maxNegativeVerticalGs; // 0x0FE + fixed16_2dp maxLateralGs; // 0x100 + uint8 pad_102[0x12]; + uint8 inversions; // 0x114 (???X XXXX) holes for mini golf + uint8 drops; // 0x115 (??XX XXXX) + uint8 pad_116; + uint8 highest_drop_height; // 0x117 + uint8 pad_118[0x0C]; sint16 var_124; sint16 var_126; sint16 var_128; @@ -118,9 +122,9 @@ typedef struct { sint16 var_136; money16 price; // 0x138 uint8 pad_13A[0x06]; - sint16 excitement; // 0x140 - sint16 intensity; // 0x142 - uint16 nausea; // 0x144 + ride_rating excitement; // 0x140 + ride_rating intensity; // 0x142 + ride_rating nausea; // 0x144 uint16 reliability; // 0x146 uint16 pad_148; uint16 var_14A; @@ -169,7 +173,7 @@ typedef struct { // Example value for wild mouse ride is d5 (before it's been constructed) // I tried searching the IDA file for "1F4" but couldn't find places where // this is written to. - uint16 var_1F4; + uint16 totalAirTime; // 0x1F4 uint8 pad_1F6[0x0a]; uint16 queue_length[4]; // 0x200 uint8 pad_208[0x58]; @@ -459,5 +463,6 @@ void ride_construct_new(int list_item); int ride_try_construct(rct_map_element *trackMapElement); void ride_get_status(int rideIndex, int *formatSecondary, int *argument); rct_peep *ride_get_assigned_mechanic(rct_ride *ride); +int ride_get_total_length(rct_ride *ride); #endif diff --git a/src/ride_ratings.c b/src/ride_ratings.c index b479d72d72..df269ee027 100644 --- a/src/ride_ratings.c +++ b/src/ride_ratings.c @@ -56,9 +56,9 @@ void crooked_house_excitement(rct_ride *ride) ride->var_14D |= 2; // clear all bits except lowest 5 - ride->var_114 &= 0x1f; + ride->inversions &= 0x1F; // set 6th,7th,8th bits - ride->var_114 |= 0xE0; + ride->inversions |= 0xE0; } /** @@ -75,27 +75,22 @@ uint16 compute_upkeep(rct_ride *ride) uint16 upkeep = initialUpkeepCosts[ride->type]; uint16 trackCost = costPerTrackPiece[ride->type]; - uint8 dl = ride->var_115; + uint8 dl = ride->drops; dl = dl >> 6; dl = dl & 3; upkeep += trackCost * dl; - uint32 cuml = ride->var_0E4; - cuml += ride->var_0E8; - cuml += ride->var_0EC; - cuml += ride->var_0F0; - cuml = cuml >> 0x10; + uint32 totalLength = (ride->length[0] + ride->length[1] + ride->length[2] + ride->length[3]) >> 16; // The data originally here was 20's and 0's. The 20's all represented // rides that had tracks. The 0's were fixed rides like crooked house or // bumper cars. // Data source is 0x0097E3AC if (hasRunningTrack[ride->type]) { - cuml = cuml * 20; + totalLength *= 20; } - cuml = cuml >> 0x0A; - upkeep += (uint16)cuml; + upkeep += (uint16)(totalLength >> 10); if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_RIDE_PHOTO) { // The original code read from a table starting at 0x0097E3AE and @@ -184,7 +179,7 @@ rating_tuple per_ride_rating_adjustments(rct_ride *ride, ride_rating excitement, // more detail: https://gist.github.com/kevinburke/d951e74e678b235eef3e uint16 ridetype_var = RCT2_GLOBAL(0x0097D4F2 + ride->type * 8, uint16); if (ridetype_var & 0x80) { - uint16 ax = ride->var_1F4; + uint16 ax = ride->totalAirTime; if (rideType->var_008 & 0x800) { // 65e86e ax = ax - 96; diff --git a/src/scenario.c b/src/scenario.c index 13925312d1..4851a038d6 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -419,13 +419,7 @@ void scenario_objective8_check() ride->status == RIDE_STATUS_OPEN && ride->excitement >= RIDE_RATING(7,00) && type_already_counted[subtype_id] == 0){ - // this calculates the length, no idea why it's done so complicated though. - uint8 limit = ride->num_stations; - uint32 sum = 0; - for (int j = 0; j < limit; ++j) { - sum += ((uint32*)&ride->var_0E4)[j]; - } - if ((sum >> 16) > (uint32)objective_length) { + if ((ride_get_total_length(ride) >> 16) > objective_length) { type_already_counted[subtype_id]++; rcs++; } diff --git a/src/string_ids.c b/src/string_ids.c index bbd2b709cf..3e1277ab64 100644 --- a/src/string_ids.c +++ b/src/string_ids.c @@ -1508,7 +1508,7 @@ void format_string_code(unsigned char format_code, char **dest, char **args) } format_integer(dest, value % 60); - strcpy(*dest, value % 60 == 1 ? "sec:" : "secs:"); + strcpy(*dest, value % 60 == 1 ? "sec" : "secs"); *dest += strlen(*dest); break; case FORMAT_REALTIME: @@ -1523,7 +1523,7 @@ void format_string_code(unsigned char format_code, char **dest, char **args) } format_integer(dest, value % 60); - strcpy(*dest, value % 60 == 1 ? "min:" : "mins:"); + strcpy(*dest, value % 60 == 1 ? "min" : "mins"); *dest += strlen(*dest); break; case FORMAT_LENGTH: diff --git a/src/string_ids.h b/src/string_ids.h index 3bbe41dc3e..a055583399 100644 --- a/src/string_ids.h +++ b/src/string_ids.h @@ -373,6 +373,22 @@ enum { STR_ROTATE_OBJECTS_90 = 1327, + STR_NO_TEST_RESULTS_YET = 1339, + STR_MAX_SPEED = 1340, + STR_RIDE_TIME = 1341, + STR_RIDE_LENGTH = 1344, + STR_AVERAGE_SPEED = 1347, + STR_MAX_POSITIVE_VERTICAL_G = 1348, + STR_MAX_POSITIVE_VERTICAL_G_RED = 1349, + STR_MAX_NEGATIVE_VERTICAL_G = 1350, + STR_MAX_NEGATIVE_VERTICAL_G_RED = 1351, + STR_MAX_LATERAL_G = 1352, + STR_MAX_LATERAL_G_RED = 1353, + STR_HIGHEST_DROP_HEIGHT = 1354, + STR_DROPS = 1355, + STR_INVERSIONS = 1356, + STR_HOLES = 1357, + STR_TOTAL_AIR_TIME = 1358, STR_QUEUE_TIME_MINUTE = 1359, STR_QUEUE_TIME_MINUTES = 1360, @@ -416,7 +432,15 @@ enum { STR_GUESTS = 1463, STR_STAFF = 1468, - + + STR_EXCITEMENT_RATING = 1473, + STR_EXCITEMENT_RATING_NOT_YET_AVAILABLE = 1474, + STR_INTENSITY_RATING = 1475, + STR_INTENSITY_RATING_NOT_YET_AVAILABLE = 1476, + STR_INTENSITY_RATING_RED = 1477, + STR_NAUSEA_RATING = 1478, + STR_NAUSEA_RATING_NOT_YET_AVAILABLE = 1479, + STR_THOUGHT_START = 1480, STR_CONSTRUCT_FOOTPATH_ON_LAND_TIP = 1655, @@ -731,12 +755,12 @@ enum { STR_LOW = 2369, STR_AVERAGE = 2370, STR_HIGH = 2371, - //STR_LOW = 2372, - STR_MEDIUM = 2373, - //STR_HIGH = 2374, - STR_VERY_HIGH = 2375, - STR_EXTREME = 2376, - STR_ULTRA_EXTREME = 2377, + STR_RATING_LOW = 2372, + STR_RATING_MEDIUM = 2373, + STR_RATING_HIGH = 2374, + STR_RATING_VERY_HIGH = 2375, + STR_RATING_EXTREME = 2376, + STR_RATING_ULTRA_EXTREME = 2377, STR_ADJUST_SMALLER_LAND_TIP = 2378, STR_ADJUST_LARGER_LAND_TIP = 2379, @@ -987,6 +1011,9 @@ enum { STR_TEST_RIDE = 3108, STR_OPEN_RIDE = 3109, + STR_SAVE_TRACK_DESIGN = 3115, + STR_SAVE_TRACK_DESIGN_NOT_POSSIBLE = 3116, + STR_CALLING_MECHANIC = 3117, STR_MEHCANIC_IS_HEADING_FOR_THE_RIDE = 3118, STR_MEHCANIC_IS_FIXING_THE_RIDE = 3119, @@ -995,6 +1022,15 @@ enum { STR_FAVOURITE_RIDE_OF_GUEST = 3122, STR_FAVOURITE_RIDE_OF_GUESTS = 3123, + STR_SAVE_TRACK_DESIGN_ITEM = 3128, + STR_SAVE_TRACK_DESIGN_WITH_SCENERY_ITEM = 3129, + STR_DESIGN_SAVE = 3130, + STR_DESIGN_CANCEL = 3131, + STR_CLICK_ITEMS_OF_SCENERY_TO_SELECT = 3132, + + STR_SELECT_NEARBY_SCENERY = 3137, + STR_RESET_SELECTION = 3138, + STR_SCROLL_LEFT_TIP = 3145, STR_SCROLL_RIGHT_TIP = STR_SCROLL_LEFT_TIP + 1, STR_SCROLL_LEFT_FAST_TIP = STR_SCROLL_LEFT_TIP + 2, diff --git a/src/window_ride.c b/src/window_ride.c index 64ca1f20ba..1a301eaa5f 100644 --- a/src/window_ride.c +++ b/src/window_ride.c @@ -83,6 +83,12 @@ enum { WIDX_MUSIC, WIDX_MUSIC_DROPDOWN, + WIDX_SAVE_TRACK_DESIGN = 14, + WIDX_SELECT_NEARBY_SCENERY, + WIDX_RESET_SELECTION, + WIDX_SAVE_DESIGN, + WIDX_CANCEL_DESIGN, + WIDX_SHOW_GUESTS_THOUGHTS = 14, WIDX_SHOW_GUESTS_ON_RIDE, WIDX_SHOW_GUESTS_QUEUING @@ -163,6 +169,31 @@ static rct_widget window_ride_music_widgets[] = { { WIDGETS_END }, }; +// 0x009AE5DC +static rct_widget window_ride_measurements_widgets[] = { + { WWT_FRAME, 0, 0, 315, 0, 206, 0x0FFFFFFFF, STR_NONE }, + { WWT_CAPTION, 0, 1, 314, 1, 14, 0x3DD, STR_WINDOW_TITLE_TIP }, + { WWT_CLOSEBOX, 0, 303, 313, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, + { WWT_RESIZE, 1, 0, 315, 43, 179, 0x0FFFFFFFF, STR_NONE }, + { WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, STR_VIEW_OF_RIDE_ATTRACTION_TIP }, + { WWT_TAB, 1, 34, 64, 17, 46, 0x2000144E, STR_VEHICLE_DETAILS_AND_OPTIONS_TIP }, + { WWT_TAB, 1, 65, 95, 17, 43, 0x2000144E, STR_OPERATING_OPTIONS_TIP }, + { WWT_TAB, 1, 96, 126, 17, 43, 0x2000144E, STR_MAINTENANCE_OPTIONS_TIP }, + { WWT_TAB, 1, 127, 157, 17, 43, 0x2000144E, STR_COLOUR_SCHEME_OPTIONS_TIP }, + { WWT_TAB, 1, 158, 188, 17, 43, 0x2000144E, STR_SOUND_AND_MUSIC_OPTIONS_TIP }, + { WWT_TAB, 1, 189, 219, 17, 43, 0x2000144E, STR_MEASUREMENTS_AND_TEST_DATA_TIP }, + { WWT_TAB, 1, 220, 250, 17, 43, 0x2000144E, STR_GRAPHS_TIP }, + { WWT_TAB, 1, 251, 281, 17, 43, 0x2000144E, STR_INCOME_AND_COSTS_TIP }, + { WWT_TAB, 1, 282, 312, 17, 43, 0x2000144E, STR_CUSTOMER_INFORMATION_TIP }, + + { WWT_FLATBTN, 1, 288, 311, 164, 187, 5183, STR_SAVE_TRACK_DESIGN }, + { WWT_DROPDOWN_BUTTON, 1, 4, 157, 128, 139, STR_SELECT_NEARBY_SCENERY, STR_NONE }, + { WWT_DROPDOWN_BUTTON, 1, 158, 311, 128, 139, STR_RESET_SELECTION, STR_NONE }, + { WWT_DROPDOWN_BUTTON, 1, 4, 157, 178, 189, STR_DESIGN_SAVE, STR_NONE }, + { WWT_DROPDOWN_BUTTON, 1, 158, 311, 178, 189, STR_DESIGN_CANCEL, STR_NONE }, + { WIDGETS_END }, +}; + // 0x009AE9C8 static rct_widget window_ride_customer_widgets[] = { { WWT_FRAME, 0, 0, 315, 0, 206, 0x0FFFFFFFF, STR_NONE }, @@ -193,7 +224,7 @@ static rct_widget *window_ride_page_widgets[] = { window_ride_maintenance_widgets, (rct_widget*)0x009AE2A4, window_ride_music_widgets, - (rct_widget*)0x009AE5DC, + window_ride_measurements_widgets, (rct_widget*)0x009AE710, (rct_widget*)0x009AE844, window_ride_customer_widgets @@ -244,6 +275,17 @@ static void window_ride_music_update(rct_window *w); static void window_ride_music_invalidate(); static void window_ride_music_paint(); +static void window_ride_measurements_close(); +static void window_ride_measurements_mouseup(); +static void window_ride_measurements_resize(); +static void window_ride_measurements_mousedown(int widgetIndex, rct_window *w, rct_widget *widget); +static void window_ride_measurements_dropdown(); +static void window_ride_measurements_update(rct_window *w); +static void window_ride_measurements_tooldown(); +static void window_ride_measurements_toolabort(); +static void window_ride_measurements_invalidate(); +static void window_ride_measurements_paint(); + static void window_ride_customer_mouseup(); static void window_ride_customer_resize(); static void window_ride_customer_update(rct_window *w); @@ -346,6 +388,38 @@ static void* window_ride_music_events[] = { window_ride_emptysub }; +// 0x0098DE14 +static void* window_ride_measurements_events[] = { + window_ride_emptysub, + window_ride_measurements_mouseup, + window_ride_measurements_resize, + window_ride_measurements_mousedown, + window_ride_measurements_dropdown, + window_ride_emptysub, + window_ride_measurements_update, + window_ride_emptysub, + window_ride_emptysub, + window_ride_emptysub, + window_ride_measurements_tooldown, + window_ride_emptysub, + window_ride_emptysub, + window_ride_measurements_toolabort, + window_ride_emptysub, + window_ride_emptysub, + window_ride_emptysub, + window_ride_emptysub, + window_ride_emptysub, + window_ride_emptysub, + window_ride_emptysub, + window_ride_emptysub, + window_ride_emptysub, + window_ride_emptysub, + window_ride_emptysub, + window_ride_measurements_invalidate, + window_ride_measurements_paint, + window_ride_emptysub +}; + // 0x0098DE84 static void* window_ride_customer_events[] = { window_ride_emptysub, @@ -385,7 +459,7 @@ static uint32* window_ride_page_events[] = { (uint32*)window_ride_maintenance_events, (uint32*)0x0098E044, (uint32*)window_ride_music_events, - (uint32*)0x0098DE14, + (uint32*)window_ride_measurements_events, (uint32*)0x0098DF64, (uint32*)0x0098DEF4, (uint32*)window_ride_customer_events @@ -1952,6 +2026,437 @@ static void window_ride_music_paint() #pragma endregion +#pragma region Measurements + +/** + * + * rct2: 0x006D3026 + */ +static void window_ride_measurements_design_reset() +{ + RCT2_CALLPROC_EBPSAFE(0x006D3026); +} + +/** + * + * rct2: 0x006D303D + */ +static void window_ride_measurements_design_select_nearby_scenery() +{ + RCT2_CALLPROC_EBPSAFE(0x006D303D); +} + +/** + * + * rct2: 0x006AD4CD + */ +static void window_ride_measurements_design_save(rct_window *w) +{ + RCT2_CALLPROC_X(0x006D2804, 1, 0, 0, 0, (int)w, 0, 0); +} + +/** + * + * rct2: 0x006AD4DA + */ +static void window_ride_measurements_design_cancel() +{ + if (RCT2_GLOBAL(0x009DEA6F, uint8) & 1) + RCT2_CALLPROC_X(0x006D2804, 0, 0, 0, 0, 0, 0, 0); +} + +/** + * + * rct2: 0x006AD4DA + */ +static void window_ride_measurements_close() +{ + window_ride_measurements_design_cancel(); +} + +/** + * + * rct2: 0x006AD478 + */ +static void window_ride_measurements_mouseup() +{ + short widgetIndex; + rct_window *w; + + window_widget_get_registers(w, widgetIndex); + + switch (widgetIndex) { + case WIDX_CLOSE: + window_close(w); + break; + case WIDX_TAB_1: + case WIDX_TAB_2: + case WIDX_TAB_3: + case WIDX_TAB_4: + case WIDX_TAB_5: + case WIDX_TAB_6: + case WIDX_TAB_7: + case WIDX_TAB_8: + case WIDX_TAB_9: + case WIDX_TAB_10: + window_ride_set_page(w, widgetIndex - WIDX_TAB_1); + break; + case WIDX_SELECT_NEARBY_SCENERY: + window_ride_measurements_design_select_nearby_scenery(); + break; + case WIDX_RESET_SELECTION: + window_ride_measurements_design_reset(); + break; + case WIDX_SAVE_DESIGN: + window_ride_measurements_design_save(w); + break; + case WIDX_CANCEL_DESIGN: + window_ride_measurements_design_cancel(); + break; + } +} + +/** + * + * rct2: 0x006AD564 + */ +static void window_ride_measurements_resize() +{ + rct_window *w; + + window_get_register(w); + + window_set_resize(w, 316, 202, 316, 202); +} + +/** + * + * rct2: 0x006AD4AB + */ +static void window_ride_measurements_mousedown(int widgetIndex, rct_window *w, rct_widget *widget) +{ + if (widgetIndex != WIDX_SAVE_TRACK_DESIGN) + return; + + rct_ride *ride = GET_RIDE(w->number); + + gDropdownItemsFormat[0] = STR_SAVE_TRACK_DESIGN_ITEM; + gDropdownItemsFormat[1] = STR_SAVE_TRACK_DESIGN_WITH_SCENERY_ITEM; + + window_dropdown_show_text( + w->x + widget->left, + w->y + widget->top, + widget->bottom - widget->top + 1, + w->colours[1], + 0, + 2 + ); + RCT2_GLOBAL(0x009DEBA2, sint16) = 0; + if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_DESIGNER) + RCT2_GLOBAL(0x009DED34, uint32) |= 2; +} + +/** + * + * rct2: 0x006AD4B2 + */ +static void window_ride_measurements_dropdown() +{ + rct_window *w; + short widgetIndex, dropdownIndex; + + window_dropdown_get_registers(w, widgetIndex, dropdownIndex); + + if (widgetIndex != WIDX_SAVE_TRACK_DESIGN) + return; + + if (dropdownIndex == -1) + dropdownIndex = RCT2_GLOBAL(0x009DEBA2, sint16); + + if (dropdownIndex == 0) + RCT2_CALLPROC_X(0x006D264D, 0, 0, 0, 0, (int)w, 0, 0); + else + RCT2_CALLPROC_X(0x006D27A3, 0, 0, 0, 0, (int)w, 0, 0); +} + +/** + * + * rct2: 0x006AD5DD + */ +static void window_ride_measurements_update(rct_window *w) +{ + w->frame_no++; + RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0); + widget_invalidate(WC_RIDE, w->number, WIDX_TAB_7); +} + +/** + * + * rct2: 0x006AD4EB + */ +static void window_ride_measurements_tooldown() +{ + rct_window *w; + + window_get_register(w); + + RCT2_CALLPROC_X(0x006D2AE7, 0, 0, 0, 0, (int)w, 0, 0); +} + +/** + * + * rct2: 0x006AD4DA + */ +static void window_ride_measurements_toolabort(rct_window *w) +{ + window_ride_measurements_design_cancel(); +} + +/** + * + * rct2: 0x006ACDBC + */ +static void window_ride_measurements_invalidate() +{ + rct_window *w; + rct_widget *widgets; + + window_get_register(w); + + widgets = window_ride_page_widgets[w->page]; + if (w->widgets != widgets) { + w->widgets = widgets; + window_init_scroll_widgets(w); + } + + window_ride_set_pressed_tab(w); + + rct_ride *ride = GET_RIDE(w->number); + RCT2_GLOBAL(0x013CE952 + 0, uint16) = ride->name; + RCT2_GLOBAL(0x013CE952 + 2, uint32) = ride->name_arguments; + + window_ride_measurements_widgets[WIDX_SAVE_TRACK_DESIGN].tooltip = STR_SAVE_TRACK_DESIGN_NOT_POSSIBLE; + window_ride_measurements_widgets[WIDX_SAVE_TRACK_DESIGN].type = WWT_EMPTY; + if ((RCT2_GLOBAL(0x009DEA6F, uint8) & 1) && RCT2_GLOBAL(0x00F64DE8, uint8) == w->number) { + window_ride_measurements_widgets[WIDX_SELECT_NEARBY_SCENERY].type = WWT_DROPDOWN_BUTTON; + window_ride_measurements_widgets[WIDX_RESET_SELECTION].type = WWT_DROPDOWN_BUTTON; + window_ride_measurements_widgets[WIDX_SAVE_DESIGN].type = WWT_DROPDOWN_BUTTON; + window_ride_measurements_widgets[WIDX_CANCEL_DESIGN].type = WWT_DROPDOWN_BUTTON; + } else { + window_ride_measurements_widgets[WIDX_SELECT_NEARBY_SCENERY].type = WWT_EMPTY; + window_ride_measurements_widgets[WIDX_RESET_SELECTION].type = WWT_EMPTY; + window_ride_measurements_widgets[WIDX_SAVE_DESIGN].type = WWT_EMPTY; + window_ride_measurements_widgets[WIDX_CANCEL_DESIGN].type = WWT_EMPTY; + if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_19)) { + if (RCT2_GLOBAL(0x0097CF40 + (ride->type * 8), uint32) & 0x10000000) { + window_ride_measurements_widgets[WIDX_SAVE_TRACK_DESIGN].type = WWT_FLATBTN; + w->disabled_widgets |= (1 << WIDX_SAVE_TRACK_DESIGN); + if (ride->lifecycle_flags & RIDE_LIFECYCLE_TESTED) { + if (ride->excitement != -1) { + w->disabled_widgets &= ~(1 << WIDX_SAVE_TRACK_DESIGN); + window_ride_measurements_widgets[WIDX_SAVE_TRACK_DESIGN].tooltip = STR_SAVE_TRACK_DESIGN; + } + } + } + } + } + + window_ride_anchor_border_widgets(w); + window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_10); +} + +/** + * + * rct2: 0x006ACF07 + */ +static void window_ride_measurements_paint() +{ + rct_window *w; + rct_drawpixelinfo *dpi; + rct_widget *widget; + rct_ride *ride; + rct_string_id stringId; + int x, y, i, numTimes, numLengths; + sint16 holes, maxSpeed, averageSpeed, drops, highestDropHeight, inversions, time; + sint32 maxPositiveVerticalGs, maxNegativeVerticalGs, maxLateralGs, totalAirTime, length; + + window_paint_get_registers(w, dpi); + + window_draw_widgets(w, dpi); + window_ride_draw_tab_images(dpi, w); + + if (window_ride_measurements_widgets[WIDX_SAVE_DESIGN].type == WWT_DROPDOWN_BUTTON) { + widget = &window_ride_measurements_widgets[WIDX_PAGE_BACKGROUND]; + + x = w->x + (widget->right - widget->left) / 2; + y = w->y + widget->top + 40; + gfx_draw_string_centred_wrapped(dpi, NULL, x, y, w->width - 8, STR_CLICK_ITEMS_OF_SCENERY_TO_SELECT, 0); + + x = w->x + 4; + y = w->y + window_ride_measurements_widgets[WIDX_SELECT_NEARBY_SCENERY].bottom + 17; + gfx_fill_rect_inset(dpi, x, y, w->x + 312, y + 1, w->colours[1], 0x20); + } else { + ride = GET_RIDE(w->number); + + if (ride->lifecycle_flags & RIDE_LIFECYCLE_19) + gfx_draw_sprite(dpi, 23225, w->x + w->width - 53, w->y + w->height - 73, 0); + + x = w->x + window_ride_measurements_widgets[WIDX_PAGE_BACKGROUND].left + 4; + y = w->y + window_ride_measurements_widgets[WIDX_PAGE_BACKGROUND].top + 4; + + if (ride->lifecycle_flags & RIDE_LIFECYCLE_TESTED) { + // Excitement + RCT2_GLOBAL(0x013CE952 + 0, uint32) = ride->excitement; + RCT2_GLOBAL(0x013CE952 + 4, uint16) = STR_RATING_LOW + min(ride->excitement >> 8, 5); + stringId = ride->excitement == -1 ? STR_EXCITEMENT_RATING_NOT_YET_AVAILABLE : STR_EXCITEMENT_RATING; + gfx_draw_string_left(dpi, stringId, (void*)0x013CE952, 0, x, y); + y += 10; + + // Intensity + RCT2_GLOBAL(0x013CE952 + 0, uint32) = ride->intensity; + RCT2_GLOBAL(0x013CE952 + 4, uint16) = STR_RATING_LOW + min(ride->intensity >> 8, 5); + + stringId = STR_INTENSITY_RATING; + if (ride->excitement == -1) + stringId = STR_INTENSITY_RATING_NOT_YET_AVAILABLE; + else if (ride->intensity >= RIDE_RATING(10,00)) + stringId = STR_INTENSITY_RATING_RED; + + gfx_draw_string_left(dpi, stringId, (void*)0x013CE952, 0, x, y); + y += 10; + + // Nausea + RCT2_GLOBAL(0x013CE952 + 0, uint32) = ride->nausea; + RCT2_GLOBAL(0x013CE952 + 4, uint16) = STR_RATING_LOW + min(ride->nausea >> 8, 5); + stringId = ride->excitement == -1 ? STR_NAUSEA_RATING_NOT_YET_AVAILABLE : STR_NAUSEA_RATING; + gfx_draw_string_left(dpi, stringId, (void*)0x013CE952, 0, x, y); + y += 20; + + // Horizontal rule + gfx_fill_rect_inset(dpi, x, y - 6, x + 303, y - 5, w->colours[1], 0x20); + + if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_NO_RAW_STATS)) { + if (ride->type == RIDE_TYPE_MINI_GOLF) { + // Holes + holes = ride->inversions & 0x1F; + gfx_draw_string_left(dpi, STR_HOLES, &holes, 0, x, y); + y += 10; + } else { + // Max speed + maxSpeed = (ride->max_speed * 9) >> 18; + gfx_draw_string_left(dpi, STR_MAX_SPEED, &maxSpeed, 0, x, y); + y += 10; + + // Average speed + averageSpeed = (ride->average_speed * 9) >> 18; + gfx_draw_string_left(dpi, STR_AVERAGE_SPEED, &averageSpeed, 0, x, y); + y += 10; + + // Ride time + numTimes = 0; + for (i = 0; i < ride->num_stations; i++) { + time = ride->time[numTimes]; + if (time != 0) { + RCT2_GLOBAL(0x013CE952 + 0 + (numTimes * 4), uint16) = 1343; + RCT2_GLOBAL(0x013CE952 + 2 + (numTimes * 4), uint16) = time; + numTimes++; + } + } + if (numTimes == 0) { + RCT2_GLOBAL(0x013CE952 + 0, uint16) = 1343; + RCT2_GLOBAL(0x013CE952 + 2, uint16) = 0; + numTimes++; + } + RCT2_GLOBAL(0x013CE94E + (numTimes * 4), uint16) = 1342; + RCT2_GLOBAL(0x013CE952 + 0 + (numTimes * 4), uint16) = 0; + RCT2_GLOBAL(0x013CE952 + 2 + (numTimes * 4), uint16) = 0; + RCT2_GLOBAL(0x013CE952 + 4 + (numTimes * 4), uint16) = 0; + RCT2_GLOBAL(0x013CE952 + 6 + (numTimes * 4), uint16) = 0; + gfx_draw_string_left_clipped(dpi, STR_RIDE_TIME, (void*)0x013CE952, 0, x, y, 308); + y += 10; + } + + // Ride length + numLengths = 0; + for (i = 0; i < ride->num_stations; i++) { + length = ride->length[numLengths]; + if (length != 0) { + length >>= 16; + RCT2_GLOBAL(0x013CE952 + 0 + (numLengths * 4), uint16) = 1346; + RCT2_GLOBAL(0x013CE952 + 2 + (numLengths * 4), uint16) = (length & 0xFFFF); + numLengths++; + } + } + if (numLengths == 0) { + RCT2_GLOBAL(0x013CE952 + 0, uint16) = 1346; + RCT2_GLOBAL(0x013CE952 + 2, uint16) = 0; + numLengths++; + } + RCT2_GLOBAL(0x013CE94E + (numLengths * 4), uint16) = 1345; + RCT2_GLOBAL(0x013CE952 + 0 + (numLengths * 4), uint16) = 0; + RCT2_GLOBAL(0x013CE952 + 2 + (numLengths * 4), uint16) = 0; + RCT2_GLOBAL(0x013CE952 + 4 + (numLengths * 4), uint16) = 0; + RCT2_GLOBAL(0x013CE952 + 6 + (numLengths * 4), uint16) = 0; + gfx_draw_string_left_clipped(dpi, STR_RIDE_LENGTH, (void*)0x013CE952, 0, x, y, 308); + y += 10; + + if (RCT2_GLOBAL(0x0097CF40 + (ride->type * 8), uint32) & 0x80) { + // Max. positive vertical G's + maxPositiveVerticalGs = ride->maxPositiveVerticalGs; + stringId = maxPositiveVerticalGs >= FIXED_2DP(5,00) ? + STR_MAX_POSITIVE_VERTICAL_G_RED : STR_MAX_POSITIVE_VERTICAL_G; + gfx_draw_string_left(dpi, stringId, &maxPositiveVerticalGs, 0, x, y); + y += 10; + + // Max. negative vertical G's + maxNegativeVerticalGs = ride->maxNegativeVerticalGs; + stringId = maxNegativeVerticalGs <= -FIXED_2DP(2,00) ? + STR_MAX_NEGATIVE_VERTICAL_G_RED : STR_MAX_NEGATIVE_VERTICAL_G; + gfx_draw_string_left(dpi, stringId, &maxNegativeVerticalGs, 0, x, y); + y += 10; + + // Max lateral G's + maxLateralGs = ride->maxLateralGs; + stringId = maxLateralGs >= FIXED_2DP(2,80) ? + STR_MAX_LATERAL_G_RED : STR_MAX_LATERAL_G; + gfx_draw_string_left(dpi, stringId, &maxLateralGs, 0, x, y); + y += 10; + + // Total 'air' time + totalAirTime = ride->totalAirTime * 3; + gfx_draw_string_left(dpi, STR_TOTAL_AIR_TIME, &totalAirTime, 0, x, y); + y += 10; + } + + if (RCT2_GLOBAL(0x0097CF40 + (ride->type * 8), uint32) & 0x400) { + // Drops + drops = ride->drops & 0x3F; + gfx_draw_string_left(dpi, STR_DROPS, &drops, 0, x, y); + y += 10; + + // Highest drop height + highestDropHeight = (ride->highest_drop_height * 3) / 4; + gfx_draw_string_left(dpi, STR_HIGHEST_DROP_HEIGHT, &highestDropHeight, 0, x, y); + y += 10; + } + + if (ride->type != RIDE_TYPE_MINI_GOLF) { + // Inversions + inversions = ride->inversions & 0x1F; + if (inversions != 0) { + gfx_draw_string_left(dpi, STR_INVERSIONS, &inversions, 0, x, y); + y += 10; + } + } + } + } else { + gfx_draw_string_left(dpi, STR_NO_TEST_RESULTS_YET, NULL, 0, x, y); + } + } +} + +#pragma endregion + #pragma region Customer /**