From 9051f1352045f72d320d161e048717c8bf5ff5e0 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sun, 26 Apr 2015 16:09:16 +0100 Subject: [PATCH] Implemented sub_6c683d This is some sort of function that gets the map element of the first part of a track segment. It is also used to update the flashing colour when in construct mode --- src/ride/ride.c | 166 ++++++++++++++++++++++++++++++-- src/ride/ride.h | 2 +- src/ride/ride_ratings.c | 11 ++- src/ride/ride_ratings.h | 1 + src/ride/track.c | 75 +++++++++++++-- src/ride/track.h | 2 +- src/windows/ride_construction.c | 2 +- 7 files changed, 238 insertions(+), 21 deletions(-) diff --git a/src/ride/ride.c b/src/ride/ride.c index 8a8f51c5d4..90be7e46a4 100644 --- a/src/ride/ride.c +++ b/src/ride/ride.c @@ -769,10 +769,164 @@ static void ride_remove_peeps(int rideIndex) ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN; } -int sub_6C683D(int* x, int* y, int z, int direction, int type, int esi, int edi, int ebp) +int sub_6C683D(int* x, int* y, int* z, int direction, int type, uint16 extra_params, rct_map_element* output_element, uint16 flags) { - int ebx = (direction << 8) | type; - return RCT2_CALLFUNC_X(0x006C683D, x, &ebx, y, &z, &esi, &edi, &ebp)&0x100; + //int ebx = (direction << 8) | type; + //return RCT2_CALLFUNC_X(0x006C683D, x, &ebx, y, &z, &esi, &edi, &ebp)&0x100; + + rct_map_element* map_element = map_get_first_element_at(*x / 32, *y / 32); + rct_map_element* success_map = NULL; + + do{ + if (map_element->base_height != *z / 8) + continue; + + if (map_element_get_type(map_element) != MAP_ELEMENT_TYPE_TRACK) + continue; + + if ((map_element->type & MAP_ELEMENT_DIRECTION_MASK) != direction) + continue; + + if (type != map_element->properties.track.type) + continue; + + success_map = map_element; + if (!(map_element->properties.track.sequence & 0xF)) + break; + }while(!map_element_is_last_for_tile(map_element++)); + + map_element = success_map; + + if (map_element == NULL){ + return 1; + } + + // Possibly z should be &0xF8 + rct_ride* ride = GET_RIDE(map_element->properties.track.ride_index); + rct_preview_track *trackBlock; + + if (RCT2_ADDRESS(RCT2_ADDRESS_RIDE_FLAGS, uint32)[ride->type * 2] & RIDE_TYPE_FLAG_SELLS_FOOD){ + trackBlock = RCT2_ADDRESS(0x00994A38, rct_preview_track*)[type]; + } + else{ + trackBlock = RCT2_ADDRESS(0x00994638, rct_preview_track*)[type]; + } + + int sequence = map_element->properties.track.sequence & 0xF; + + uint8 map_direction = map_element->type & MAP_ELEMENT_DIRECTION_MASK; + + switch (map_direction){ + case MAP_ELEMENT_DIRECTION_WEST: + *x -= trackBlock[sequence].x; + *y -= trackBlock[sequence].y; + break; + case MAP_ELEMENT_DIRECTION_NORTH: + *x -= trackBlock[sequence].y; + *y += trackBlock[sequence].x; + break; + case MAP_ELEMENT_DIRECTION_EAST: + *x += trackBlock[sequence].x; + *y += trackBlock[sequence].y; + break; + case MAP_ELEMENT_DIRECTION_SOUTH: + *x += trackBlock[sequence].y; + *y -= trackBlock[sequence].x; + break; + } + + *z -= trackBlock[sequence].z; + + int start_x = *x, start_y = *y, start_z = *z; + + *z += trackBlock[0].z; + + for (int i = 0; trackBlock[i].var_00 != 0xFF; ++i){ + int cur_x = start_x, cur_y = start_y, cur_z = start_z; + + switch (map_direction){ + case MAP_ELEMENT_DIRECTION_WEST: + cur_x += trackBlock[i].x; + cur_y += trackBlock[i].y; + break; + case MAP_ELEMENT_DIRECTION_NORTH: + cur_x += trackBlock[i].y; + cur_y -= trackBlock[i].x; + break; + case MAP_ELEMENT_DIRECTION_EAST: + cur_x -= trackBlock[i].x; + cur_y -= trackBlock[i].y; + break; + case MAP_ELEMENT_DIRECTION_SOUTH: + cur_x -= trackBlock[i].y; + cur_y += trackBlock[i].x; + break; + } + + cur_z += trackBlock[i].z; + + map_invalidate_tile_full(cur_x, cur_y); + + map_element = map_get_first_element_at(cur_x / 32, cur_y / 32); + success_map = NULL; + + do{ + if (map_element->base_height != cur_z / 8) + continue; + + if (map_element_get_type(map_element) != MAP_ELEMENT_TYPE_TRACK) + continue; + + if ((map_element->type & MAP_ELEMENT_DIRECTION_MASK) != direction) + continue; + + if ((map_element->properties.track.sequence & 0xF) != trackBlock[i].var_00) + continue; + + if (type == map_element->properties.track.type) + { + success_map = map_element; + break; + } + } while (!map_element_is_last_for_tile(map_element++)); + + if (success_map == NULL){ + return 1; + } + + if (i == 0) + output_element = map_element; + + if (flags & (1 << 0)){ + // Quadrant related ?? + map_element->type &= ~(1 << 6); + } + + if (flags & (1 << 1)){ + // Quadrant related ?? + map_element->type |= (1 << 6); + } + + if (flags & (1 << 2)){ + map_element->properties.track.colour &= 0xFC; + map_element->properties.track.colour |= extra_params & 0xFF; + } + + if (flags & (1 << 5)){ + map_element->properties.track.colour &= 0x0F; + map_element->properties.track.colour |= (extra_params & 0xFF) << 4; + } + + if (flags & (1 << 3)){ + map_element->properties.track.colour |= (1 << 3); + } + + if (flags & (1 << 4)){ + map_element->properties.track.colour &= 0xF7; + } + } + + return 0; } void sub_6C96C0() @@ -785,11 +939,11 @@ void sub_6C9627() switch (RCT2_GLOBAL(0x00F440A6, uint8)) { case 3: { - int x = RCT2_GLOBAL(0x00F440A8, uint16), y = RCT2_GLOBAL(0x00F440AA, uint16); + int x = RCT2_GLOBAL(0x00F440A8, uint16), y = RCT2_GLOBAL(0x00F440AA, uint16), z = RCT2_GLOBAL(0x00F440AC, uint16); sub_6C683D( &x, &y, - RCT2_GLOBAL(0x00F440AC, uint16), + &z, RCT2_GLOBAL(RCT2_ADDRESS_TRACK_PREVIEW_ROTATION, uint8) & 3, RCT2_GLOBAL(0x00F440AF, uint8), 0, @@ -969,7 +1123,7 @@ int ride_modify(rct_xy_element *input) direction = mapElement.element->type & 3; type = mapElement.element->properties.track.type; - if (sub_6C683D(&x, &y, z, direction, type, 0, 0, 0)) + if (sub_6C683D(&x, &y, &z, direction, type, 0, 0, 0)) return 0; RCT2_GLOBAL(0x00F440A7, uint8) = rideIndex; diff --git a/src/ride/ride.h b/src/ride/ride.h index 64931ecd08..16751dd589 100644 --- a/src/ride/ride.h +++ b/src/ride/ride.h @@ -754,7 +754,7 @@ void ride_breakdown_add_news_item(int rideIndex); rct_peep *ride_find_closest_mechanic(rct_ride *ride, int forInspection); int sub_6CC3FB(int rideIndex); void sub_6C9627(); -int sub_6C683D(int* x, int* y, int z, int direction, int type, int esi, int edi, int ebp); +int sub_6C683D(int* x, int* y, int* z, int direction, int type, uint16 extra_params, rct_map_element* output_element, uint16 flags); void ride_set_map_tooltip(rct_map_element *mapElement); int ride_music_params_update(sint16 x, sint16 y, sint16 z, uint8 rideIndex, uint16 sampleRate, uint32 position, uint8 *tuneId); void ride_music_update_final(); diff --git a/src/ride/ride_ratings.c b/src/ride/ride_ratings.c index 7907654c97..b8d934d554 100644 --- a/src/ride/ride_ratings.c +++ b/src/ride/ride_ratings.c @@ -51,18 +51,19 @@ static void loc_6B5BB2(); static void ride_ratings_calculate(rct_ride *ride); static void ride_ratings_calculate_value(rct_ride *ride); -static int sub_6C6402(rct_map_element *mapElement, int *x, int *y, int *z) +int sub_6C6402(rct_map_element **mapElement, int *x, int *y, int *z) { int eax, ebx, ecx, edx, esi, edi, ebp; eax = *x; ecx = *y; - esi = (int)mapElement; - RCT2_CALLFUNC_X(0x006C6402, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + esi = (int)*mapElement; + int result = RCT2_CALLFUNC_X(0x006C6402, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); *x = *((uint16*)&eax); *y = *((uint16*)&ecx); *z = *((uint8*)&edx); - return 1; + *mapElement = (rct_map_element*)esi; + return result & (0x100); } /** @@ -338,7 +339,7 @@ static void ride_ratings_update_state_5() x = RCT2_GLOBAL(0x0138B584, uint16); y = RCT2_GLOBAL(0x0138B586, uint16); - if (!sub_6C6402(mapElement, &x, &y, &z)) { + if (!sub_6C6402(&mapElement, &x, &y, &z)) { _rideRatingsState = RIDE_RATINGS_STATE_CALCULATE; return; } diff --git a/src/ride/ride_ratings.h b/src/ride/ride_ratings.h index 5baa99e2e9..467b2c23a8 100644 --- a/src/ride/ride_ratings.h +++ b/src/ride/ride_ratings.h @@ -25,5 +25,6 @@ #include "ride.h" void ride_ratings_update_all(); +int sub_6C6402(rct_map_element **mapElement, int *x, int *y, int *z); #endif \ No newline at end of file diff --git a/src/ride/track.c b/src/ride/track.c index cfef660c1e..7afc2e8276 100644 --- a/src/ride/track.c +++ b/src/ride/track.c @@ -29,6 +29,7 @@ #include "../util/util.h" #include "../world/park.h" #include "../windows/error.h" +#include "ride_ratings.h" #include "ride.h" #include "track.h" @@ -1295,7 +1296,8 @@ int copy_scenery_to_track(uint8** track_pointer){ return 1; } -int sub_6CE44F(rct_ride* ride){ +int sub_6CE44F(uint8 rideIndex){ + rct_ride* ride = GET_RIDE(rideIndex); rct_track_td6* track_design = RCT2_ADDRESS(0x009D8178, rct_track_td6); track_design->type = ride->type; @@ -1307,8 +1309,8 @@ int sub_6CE44F(rct_ride* ride){ track_design->ride_mode = ride->mode; - track_design->version_and_colour_scheme = - (ride->colour_scheme_type & 3) | + track_design->version_and_colour_scheme = + (ride->colour_scheme_type & 3) | (1 << 3); // Version .TD6 for (int i = 0; i < 32; ++i){ @@ -1328,8 +1330,8 @@ int sub_6CE44F(rct_ride* ride){ track_design->min_waiting_time = ride->min_waiting_time; track_design->max_waiting_time = ride->max_waiting_time; track_design->var_50 = ride->var_0D0; - track_design->lift_hill_speed_num_circuits = - ride->lift_hill_speed | + track_design->lift_hill_speed_num_circuits = + ride->lift_hill_speed | (ride->num_circuits << 5); track_design->entrance_style = ride->entrance_style; @@ -1347,7 +1349,66 @@ int sub_6CE44F(rct_ride* ride){ if (total_air_time > 255) total_air_time = 0; track_design->total_air_time = (uint8)total_air_time; - //6ce5fd + + track_design->excitement = ride->ratings.excitement / 10; + track_design->intensity = ride->ratings.intensity / 10; + track_design->nausea = ride->ratings.nausea / 10; + + track_design->upkeep_cost = ride->upkeep_cost; + track_design->cost = 0; + track_design->var_6C = 0; + + if (ride->lifecycle_flags & RIDE_LIFECYCLE_SIX_FLAGS) + track_design->var_6C |= (1 << 31); + + uint8* track_elements = RCT2_ADDRESS(0x9D821B, uint8); + memset(track_elements, 0, 8000); + + if (track_design->type == RIDE_TYPE_MAZE){ + //6CEAAE + } + + rct_xy_element trackElement; + if (sub_6CAF80(rideIndex, &trackElement) == 0){ + RCT2_GLOBAL(0x00141E9AC, uint16) = 3347; + return 0; + } + + int x = trackElement.x, y = trackElement.y, z = 0; + rct_map_element* map_element = trackElement.element; + + //6ce69e + + if (!(sub_6C6402(&map_element, &x, &y, &z))){ + trackElement.element = map_element; + trackElement.x = x; + trackElement.y = y; + rct_map_element* initial_map = map_element; + do { + x = trackElement.x; + y = trackElement.y; + map_element = trackElement.element; + if (sub_6C6402(&map_element, &x, &y, &z)){ + break; + } + trackElement.x = x; + trackElement.y = y; + trackElement.element = map_element; + } while (initial_map != trackElement.element); + } + + z = map_element->base_height * 8; + uint8 track_type = map_element->properties.track.type; + uint8 direction = map_element->type & MAP_ELEMENT_DIRECTION_MASK; + RCT2_GLOBAL(0x00F4414D, uint8) = direction; + + if (sub_6C683D(&trackElement.x, &trackElement.y, &z, direction, track_type, 0, 0, 0)){ + RCT2_GLOBAL(0x00141E9AC, uint16) = 3347; + return 0; + } + + + } /* rct2: 0x006D2804 & 0x006D264D */ @@ -1369,7 +1430,7 @@ int save_track_design(uint8 rideIndex){ return 0; } - if (sub_6CE44F(ride)){ + if (!sub_6CE44F(rideIndex)){ window_error_open(3346, RCT2_GLOBAL(0x141E9AC, rct_string_id)); return 0; } diff --git a/src/ride/track.h b/src/ride/track.h index 68ee024230..7e1a431b5b 100644 --- a/src/ride/track.h +++ b/src/ride/track.h @@ -141,7 +141,7 @@ typedef struct { uint8 excitement; // 0x5B uint8 intensity; // 0x5C uint8 nausea; // 0x5D - uint8 pad_5E[2]; + money16 upkeep_cost; // 0x5E uint8 track_spine_colour[4]; // 0x60 uint8 track_rail_colour[4]; // 0x64 uint8 track_support_colour[4]; // 0x68 diff --git a/src/windows/ride_construction.c b/src/windows/ride_construction.c index 4486c5a9a5..15eaef3b6d 100644 --- a/src/windows/ride_construction.c +++ b/src/windows/ride_construction.c @@ -322,7 +322,7 @@ void window_construction_mouseup_demolish(rct_window* w){ ecx = RCT2_GLOBAL(0xF440AA, uint16), edx = RCT2_GLOBAL(0xF440AC, uint16); - sub_6C683D(&eax, &ecx, edx, RCT2_GLOBAL(RCT2_ADDRESS_TRACK_PREVIEW_ROTATION, uint8), RCT2_GLOBAL(0xF440AF, uint8) & 0x3FF, 0, 0, 0); + sub_6C683D(&eax, &ecx, &edx, RCT2_GLOBAL(RCT2_ADDRESS_TRACK_PREVIEW_ROTATION, uint8), RCT2_GLOBAL(0xF440AF, uint8) & 0x3FF, 0, 0, 0); } int ride_id = RCT2_GLOBAL(0xF440A7, uint8);