diff --git a/src/ride/gentle/car_ride.c b/src/ride/gentle/car_ride.c index b35fc0a630..04cc64343e 100644 --- a/src/ride/gentle/car_ride.c +++ b/src/ride/gentle/car_ride.c @@ -161,37 +161,6 @@ static const uint32 car_ride_track_pieces_quarter_turn_3_tiles[4][3] = { } }; -static const uint32 car_ride_track_pieces_tunnel[2][2][4] = { - { - { - SPR_SPINNING_TUNNEL_BACK_SW_NE_FRAME_0, - SPR_SPINNING_TUNNEL_BACK_SW_NE_FRAME_1, - SPR_SPINNING_TUNNEL_BACK_SW_NE_FRAME_2, - SPR_SPINNING_TUNNEL_BACK_SW_NE_FRAME_3 - }, - { - SPR_SPINNING_TUNNEL_FRONT_SW_NE_FRAME_0, - SPR_SPINNING_TUNNEL_FRONT_SW_NE_FRAME_1, - SPR_SPINNING_TUNNEL_FRONT_SW_NE_FRAME_2, - SPR_SPINNING_TUNNEL_FRONT_SW_NE_FRAME_3 - } - }, - { - { - SPR_SPINNING_TUNNEL_BACK_NW_SE_FRAME_0, - SPR_SPINNING_TUNNEL_BACK_NW_SE_FRAME_1, - SPR_SPINNING_TUNNEL_BACK_NW_SE_FRAME_2, - SPR_SPINNING_TUNNEL_BACK_NW_SE_FRAME_3 - }, - { - SPR_SPINNING_TUNNEL_FRONT_NW_SE_FRAME_0, - SPR_SPINNING_TUNNEL_FRONT_NW_SE_FRAME_1, - SPR_SPINNING_TUNNEL_FRONT_NW_SE_FRAME_2, - SPR_SPINNING_TUNNEL_FRONT_NW_SE_FRAME_3 - } - } -}; - /** rct2: 0x006F72C8 */ static void paint_car_ride_track_flat(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element * mapElement) { @@ -340,9 +309,9 @@ static void paint_car_ride_station(uint8 rideIndex, uint8 trackSequence, uint8 d imageId = car_ride_track_pieces_flat[direction] | RCT2_GLOBAL(0x00F44198, uint32); if (direction == 0 || direction == 2) { - sub_98196C(imageId, 0, 6, 32, 20, 1, height, get_current_rotation()); + sub_98199C(imageId, 0, 6, 32, 20, 1, height, 0, 0, height, get_current_rotation()); } else { - sub_98196C(imageId, 6, 0, 20, 32, 1, height, get_current_rotation()); + sub_98199C(imageId, 6, 0, 20, 32, 1, height, 0, 0, height, get_current_rotation()); } if (direction == 0 || direction == 2) { @@ -434,27 +403,7 @@ static void paint_car_ride_track_spinning_tunnel(uint8 rideIndex, uint8 trackSeq sub_98196C(imageId, 6, 0, 20, 32, 1, height, get_current_rotation()); } - int frame = gScenarioTicks >> 2 & 3; - uint32 colourFlags = RCT2_GLOBAL(0x00F4419C, uint32); - - uint32 colourFlags2 = RCT2_GLOBAL(0x00F44198, uint32); - if (colourFlags2 & (IMAGE_TYPE_UNKNOWN << 28)) { - colourFlags |= colourFlags2 & (IMAGE_TYPE_UNKNOWN << 28 | 0x1F << 24); - } - - imageId = car_ride_track_pieces_tunnel[direction & 1][0][frame] | colourFlags; - if (direction == 0 || direction == 2) { - sub_98199C(imageId, 0, 0, 28, 20, 1, height, 2, 6, height, get_current_rotation()); - } else { - sub_98199C(imageId, 0, 0, 20, 28, 1, height, 6, 2, height, get_current_rotation()); - } - - imageId = car_ride_track_pieces_tunnel[direction & 1][1][frame] | colourFlags; - if (direction == 0 || direction == 2) { - sub_98197C(imageId, 0, 0, 26, 1, 23, height, 4, 28, height, get_current_rotation()); - } else { - sub_98197C(imageId, 0, 0, 1, 26, 23, height, 28, 4, height, get_current_rotation()); - } + track_paint_util_spinning_tunnel_paint(1, height, direction, get_current_rotation()); if (direction == 0 || direction == 2) { paint_util_push_tunnel_left(height, TUNNEL_0); diff --git a/src/ride/gentle/ghost_train.c b/src/ride/gentle/ghost_train.c index 846fd9695d..1b1071799e 100644 --- a/src/ride/gentle/ghost_train.c +++ b/src/ride/gentle/ghost_train.c @@ -13,3 +13,494 @@ * A full copy of the GNU General Public License can be found in licence.txt *****************************************************************************/ #pragma endregion + +#include "../track_paint.h" +#include "../track.h" +#include "../vehicle_paint.h" +#include "../../interface/viewport.h" +#include "../../paint/paint.h" +#include "../../paint/supports.h" +#include "../ride_data.h" +#include "../../world/map.h" + +enum +{ + SPR_GHOST_TRAIN_TRACK_FLAT_SW_NE = 28821, + SPR_GHOST_TRAIN_TRACK_FLAT_NW_SE = 28822, + SPR_GHOST_TRAIN_TRACK_FLAT_TO_25_DEG_UP_SW_NE = 28823, + SPR_GHOST_TRAIN_TRACK_FLAT_TO_25_DEG_UP_NW_SE = 28824, + SPR_GHOST_TRAIN_TRACK_FLAT_TO_25_DEG_UP_NE_SW = 28825, + SPR_GHOST_TRAIN_TRACK_FLAT_TO_25_DEG_UP_SE_NW = 28826, + SPR_GHOST_TRAIN_TRACK_25_DEG_UP_TO_FLAT_SW_NE = 28827, + SPR_GHOST_TRAIN_TRACK_25_DEG_UP_TO_FLAT_NW_SE = 28828, + SPR_GHOST_TRAIN_TRACK_25_DEG_UP_TO_FLAT_NE_SW = 28829, + SPR_GHOST_TRAIN_TRACK_25_DEG_UP_TO_FLAT_SE_NW = 28830, + SPR_GHOST_TRAIN_TRACK_25_DEG_UP_SW_NE = 28831, + SPR_GHOST_TRAIN_TRACK_25_DEG_UP_NW_SE = 28832, + SPR_GHOST_TRAIN_TRACK_25_DEG_UP_NE_SW = 28833, + SPR_GHOST_TRAIN_TRACK_25_DEG_UP_SE_NW = 28834, + SPR_GHOST_TRAIN_TRACK_FLAT_TO_25_DEG_UP_FRONT_SW_NE = 28835, + SPR_GHOST_TRAIN_TRACK_FLAT_TO_25_DEG_UP_FRONT_NW_SE = 28836, + SPR_GHOST_TRAIN_TRACK_FLAT_TO_25_DEG_UP_FRONT_NE_SW = 28837, + SPR_GHOST_TRAIN_TRACK_FLAT_TO_25_DEG_UP_FRONT_SE_NW = 28838, + SPR_GHOST_TRAIN_TRACK_25_DEG_UP_TO_FLAT_FRONT_SW_NE = 28839, + SPR_GHOST_TRAIN_TRACK_25_DEG_UP_TO_FLAT_FRONT_NW_SE = 28840, + SPR_GHOST_TRAIN_TRACK_25_DEG_UP_TO_FLAT_FRONT_NE_SW = 28841, + SPR_GHOST_TRAIN_TRACK_25_DEG_UP_TO_FLAT_FRONT_SE_NW = 28842, + SPR_GHOST_TRAIN_TRACK_25_DEG_UP_FRONT_SW_NE = 28843, + SPR_GHOST_TRAIN_TRACK_25_DEG_UP_FRONT_NW_SE = 28844, + SPR_GHOST_TRAIN_TRACK_25_DEG_UP_FRONT_NE_SW = 28845, + SPR_GHOST_TRAIN_TRACK_25_DEG_UP_FRONT_SE_NW = 28846, + SPR_GHOST_TRAIN_QUARTER_TURN_1_TILE_SW_NW = 28847, + SPR_GHOST_TRAIN_QUARTER_TURN_1_TILE_NW_NE = 28848, + SPR_GHOST_TRAIN_QUARTER_TURN_1_TILE_NE_SE = 28849, + SPR_GHOST_TRAIN_QUARTER_TURN_1_TILE_SE_SW = 28850, + SPR_GHOST_TRAIN_QUARTER_TURN_3_TILES_SW_SE_PART_0 = 28851, + SPR_GHOST_TRAIN_QUARTER_TURN_3_TILES_SW_SE_PART_1 = 28852, + SPR_GHOST_TRAIN_QUARTER_TURN_3_TILES_SW_SE_PART_2 = 28853, + SPR_GHOST_TRAIN_QUARTER_TURN_3_TILES_NW_SW_PART_0 = 28854, + SPR_GHOST_TRAIN_QUARTER_TURN_3_TILES_NW_SW_PART_1 = 28855, + SPR_GHOST_TRAIN_QUARTER_TURN_3_TILES_NW_SW_PART_2 = 28856, + SPR_GHOST_TRAIN_QUARTER_TURN_3_TILES_NE_NW_PART_0 = 28857, + SPR_GHOST_TRAIN_QUARTER_TURN_3_TILES_NE_NW_PART_1 = 28858, + SPR_GHOST_TRAIN_QUARTER_TURN_3_TILES_NE_NW_PART_2 = 28859, + SPR_GHOST_TRAIN_QUARTER_TURN_3_TILES_SE_NE_PART_0 = 28860, + SPR_GHOST_TRAIN_QUARTER_TURN_3_TILES_SE_NE_PART_1 = 28861, + SPR_GHOST_TRAIN_QUARTER_TURN_3_TILES_SE_NE_PART_2 = 28862, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_TRACK_SW_NE = 28863, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_TRACK_NW_SE = 28864, + + SPR_GHOST_TRAIN_TRACK_BRAKES_SW_NE = 28881, + SPR_GHOST_TRAIN_TRACK_BRAKES_NW_SE = 28882 +}; + +static const uint32 ghost_train_track_pieces_flat[4] = { + SPR_GHOST_TRAIN_TRACK_FLAT_SW_NE, + SPR_GHOST_TRAIN_TRACK_FLAT_NW_SE, + SPR_GHOST_TRAIN_TRACK_FLAT_SW_NE, + SPR_GHOST_TRAIN_TRACK_FLAT_NW_SE, +}; + +static const uint32 ghost_train_track_pieces_flat_to_25_deg_up[4][2] = { + {SPR_GHOST_TRAIN_TRACK_FLAT_TO_25_DEG_UP_SW_NE, SPR_GHOST_TRAIN_TRACK_FLAT_TO_25_DEG_UP_FRONT_SW_NE}, + {SPR_GHOST_TRAIN_TRACK_FLAT_TO_25_DEG_UP_NW_SE, SPR_GHOST_TRAIN_TRACK_FLAT_TO_25_DEG_UP_FRONT_NW_SE}, + {SPR_GHOST_TRAIN_TRACK_FLAT_TO_25_DEG_UP_NE_SW, SPR_GHOST_TRAIN_TRACK_FLAT_TO_25_DEG_UP_FRONT_NE_SW}, + {SPR_GHOST_TRAIN_TRACK_FLAT_TO_25_DEG_UP_SE_NW, SPR_GHOST_TRAIN_TRACK_FLAT_TO_25_DEG_UP_FRONT_SE_NW}, +}; + +static const uint32 ghost_train_track_pieces_25_deg_up_to_flat[4][2] = { + {SPR_GHOST_TRAIN_TRACK_25_DEG_UP_TO_FLAT_SW_NE, SPR_GHOST_TRAIN_TRACK_25_DEG_UP_TO_FLAT_FRONT_SW_NE}, + {SPR_GHOST_TRAIN_TRACK_25_DEG_UP_TO_FLAT_NW_SE, SPR_GHOST_TRAIN_TRACK_25_DEG_UP_TO_FLAT_FRONT_NW_SE}, + {SPR_GHOST_TRAIN_TRACK_25_DEG_UP_TO_FLAT_NE_SW, SPR_GHOST_TRAIN_TRACK_25_DEG_UP_TO_FLAT_FRONT_NE_SW}, + {SPR_GHOST_TRAIN_TRACK_25_DEG_UP_TO_FLAT_SE_NW, SPR_GHOST_TRAIN_TRACK_25_DEG_UP_TO_FLAT_FRONT_SE_NW}, +}; + +static const uint32 ghost_train_track_pieces_25_deg_up[4][2] = { + {SPR_GHOST_TRAIN_TRACK_25_DEG_UP_SW_NE, SPR_GHOST_TRAIN_TRACK_25_DEG_UP_FRONT_SW_NE}, + {SPR_GHOST_TRAIN_TRACK_25_DEG_UP_NW_SE, SPR_GHOST_TRAIN_TRACK_25_DEG_UP_FRONT_NW_SE}, + {SPR_GHOST_TRAIN_TRACK_25_DEG_UP_NE_SW, SPR_GHOST_TRAIN_TRACK_25_DEG_UP_FRONT_NE_SW}, + {SPR_GHOST_TRAIN_TRACK_25_DEG_UP_SE_NW, SPR_GHOST_TRAIN_TRACK_25_DEG_UP_FRONT_SE_NW}, +}; + +static const uint32 ghost_train_track_pieces_quarter_turn_1_tile[4] = { + SPR_GHOST_TRAIN_QUARTER_TURN_1_TILE_SW_NW, + SPR_GHOST_TRAIN_QUARTER_TURN_1_TILE_NW_NE, + SPR_GHOST_TRAIN_QUARTER_TURN_1_TILE_NE_SE, + SPR_GHOST_TRAIN_QUARTER_TURN_1_TILE_SE_SW, +}; + +static const uint32 ghost_train_track_pieces_quarter_turn_3_tiles[4][3] = { + { + SPR_GHOST_TRAIN_QUARTER_TURN_3_TILES_SW_SE_PART_0, + SPR_GHOST_TRAIN_QUARTER_TURN_3_TILES_SW_SE_PART_1, + SPR_GHOST_TRAIN_QUARTER_TURN_3_TILES_SW_SE_PART_2 + }, + { + SPR_GHOST_TRAIN_QUARTER_TURN_3_TILES_NW_SW_PART_0, + SPR_GHOST_TRAIN_QUARTER_TURN_3_TILES_NW_SW_PART_1, + SPR_GHOST_TRAIN_QUARTER_TURN_3_TILES_NW_SW_PART_2 + }, + { + SPR_GHOST_TRAIN_QUARTER_TURN_3_TILES_NE_NW_PART_0, + SPR_GHOST_TRAIN_QUARTER_TURN_3_TILES_NE_NW_PART_1, + SPR_GHOST_TRAIN_QUARTER_TURN_3_TILES_NE_NW_PART_2 + }, + { + SPR_GHOST_TRAIN_QUARTER_TURN_3_TILES_SE_NE_PART_0, + SPR_GHOST_TRAIN_QUARTER_TURN_3_TILES_SE_NE_PART_1, + SPR_GHOST_TRAIN_QUARTER_TURN_3_TILES_SE_NE_PART_2 + } +}; + +static const uint32 ghost_train_track_pieces_spinning_tunnel_track[4] = { + SPR_GHOST_TRAIN_SPINNING_TUNNEL_TRACK_SW_NE, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_TRACK_NW_SE, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_TRACK_SW_NE, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_TRACK_NW_SE, +}; + +static const uint32 ghost_train_track_pieces_brakes[4] = { + SPR_GHOST_TRAIN_TRACK_BRAKES_SW_NE, + SPR_GHOST_TRAIN_TRACK_BRAKES_NW_SE, + SPR_GHOST_TRAIN_TRACK_BRAKES_SW_NE, + SPR_GHOST_TRAIN_TRACK_BRAKES_NW_SE, +}; + +/** rct2: 0x00770BEC */ +static void paint_ghost_train_track_flat(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element * mapElement) +{ + rct_xy16 position = {RCT2_GLOBAL(0x009DE56A, sint16), RCT2_GLOBAL(0x009DE56E, sint16)}; + + uint32 imageId = ghost_train_track_pieces_flat[direction] | RCT2_GLOBAL(0x00F44198, uint32); + + if (direction == 0 || direction == 2) { + sub_98197C(imageId, 0, 0, 32, 20, 3, height, 0, 6, height, get_current_rotation()); + } else { + sub_98197C(imageId, 0, 0, 20, 32, 3, height, 6, 0, height, get_current_rotation()); + } + + if (direction == 0 || direction == 2) { + paint_util_push_tunnel_left(height, TUNNEL_0); + } else { + paint_util_push_tunnel_right(height, TUNNEL_0); + } + + if (track_paint_util_should_paint_supports(position)) { + metal_a_supports_paint_setup(3, 4, 0, height, RCT2_GLOBAL(0x00F4419C, uint32)); + } + + paint_util_set_segment_support_height(paint_util_rotate_segments(SEGMENT_D0 | SEGMENT_C4 | SEGMENT_CC, direction), 0xFFFF, 0); + paint_util_set_general_support_height(height + 32, 0x20); +} + +/** rct2: 0x00770BFC */ +static void paint_ghost_train_track_25_deg_up(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element * mapElement) +{ + rct_xy16 position = {RCT2_GLOBAL(0x009DE56A, sint16), RCT2_GLOBAL(0x009DE56E, sint16)}; + + uint32 imageId = ghost_train_track_pieces_25_deg_up[direction][0] | RCT2_GLOBAL(0x00F44198, uint32); + if (direction == 0 || direction == 2) { + sub_98197C(imageId, 0, 0, 32, 20, 3, height, 0, 6, height, get_current_rotation()); + } else { + sub_98197C(imageId, 0, 0, 20, 32, 3, height, 6, 0, height, get_current_rotation()); + } + + imageId = ghost_train_track_pieces_25_deg_up[direction][1] | RCT2_GLOBAL(0x00F44198, uint32); + if (direction == 0 || direction == 2) { + sub_98197C(imageId, 0, 0, 32, 1, 23, height, 0, 27, height, get_current_rotation()); + } else { + sub_98197C(imageId, 0, 0, 1, 32, 23, height, 27, 0, height, get_current_rotation()); + } + + if (track_paint_util_should_paint_supports(position)) { + metal_a_supports_paint_setup(3, 4, 8, height, RCT2_GLOBAL(0x00F4419C, uint32)); + } + + + switch (direction) { + case 0: + paint_util_push_tunnel_left(height - 8, TUNNEL_1); + break; + case 1: + paint_util_push_tunnel_right(height + 8, TUNNEL_2); + break; + case 2: + paint_util_push_tunnel_left(height + 8, TUNNEL_2); + break; + case 3: + paint_util_push_tunnel_right(height - 8, TUNNEL_1); + break; + } + + paint_util_set_segment_support_height(paint_util_rotate_segments(SEGMENT_D0 | SEGMENT_C4 | SEGMENT_CC, direction), 0xFFFF, 0); + paint_util_set_general_support_height(height + 56, 0x20); +} + +/** rct2: 0x00770C0C */ +static void paint_ghost_train_track_flat_to_25_deg_up(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element * mapElement) +{ + rct_xy16 position = {RCT2_GLOBAL(0x009DE56A, sint16), RCT2_GLOBAL(0x009DE56E, sint16)}; + + uint32 imageId = ghost_train_track_pieces_flat_to_25_deg_up[direction][0] | RCT2_GLOBAL(0x00F44198, uint32); + if (direction == 0 || direction == 2) { + sub_98197C(imageId, 0, 0, 32, 20, 3, height, 0, 6, height, get_current_rotation()); + } else { + sub_98197C(imageId, 0, 0, 20, 32, 3, height, 6, 0, height, get_current_rotation()); + } + + imageId = ghost_train_track_pieces_flat_to_25_deg_up[direction][1] | RCT2_GLOBAL(0x00F44198, uint32); + if (direction == 0 || direction == 2) { + sub_98197C(imageId, 0, 0, 32, 1, 15, height, 0, 27, height, get_current_rotation()); + } else { + sub_98197C(imageId, 0, 0, 1, 32, 15, height, 27, 0, height, get_current_rotation()); + } + + if (track_paint_util_should_paint_supports(position)) { + metal_a_supports_paint_setup(3, 4, 3, height, RCT2_GLOBAL(0x00F4419C, uint32)); + } + + switch (direction) { + case 0: + paint_util_push_tunnel_left(height, TUNNEL_0); + break; + case 1: + paint_util_push_tunnel_right(height, TUNNEL_2); + break; + case 2: + paint_util_push_tunnel_left(height, TUNNEL_2); + break; + case 3: + paint_util_push_tunnel_right(height, TUNNEL_0); + break; + } + + paint_util_set_segment_support_height(paint_util_rotate_segments(SEGMENT_D0 | SEGMENT_C4 | SEGMENT_CC, direction), 0xFFFF, 0); + paint_util_set_general_support_height(height + 48, 0x20); +} + +/** rct2: 0x00770C1C */ +static void paint_ghost_train_track_25_deg_up_to_flat(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element * mapElement) +{ + rct_xy16 position = {RCT2_GLOBAL(0x009DE56A, sint16), RCT2_GLOBAL(0x009DE56E, sint16)}; + + uint32 imageId = ghost_train_track_pieces_25_deg_up_to_flat[direction][0] | RCT2_GLOBAL(0x00F44198, uint32); + if (direction == 0 || direction == 2) { + sub_98197C(imageId, 0, 0, 32, 20, 3, height, 0, 6, height, get_current_rotation()); + } else { + sub_98197C(imageId, 0, 0, 20, 32, 3, height, 6, 0, height, get_current_rotation()); + } + + imageId = ghost_train_track_pieces_25_deg_up_to_flat[direction][1] | RCT2_GLOBAL(0x00F44198, uint32); + if (direction == 0 || direction == 2) { + sub_98197C(imageId, 0, 0, 32, 1, 15, height, 0, 27, height, get_current_rotation()); + } else { + sub_98197C(imageId, 0, 0, 1, 32, 15, height, 27, 0, height, get_current_rotation()); + } + + if (track_paint_util_should_paint_supports(position)) { + metal_a_supports_paint_setup(3, 4, 6, height, RCT2_GLOBAL(0x00F4419C, uint32)); + } + + switch (direction) { + case 0: + paint_util_push_tunnel_left(height - 8, TUNNEL_0); + break; + case 1: + paint_util_push_tunnel_right(height + 8, TUNNEL_12); + break; + case 2: + paint_util_push_tunnel_left(height + 8, TUNNEL_12); + break; + case 3: + paint_util_push_tunnel_right(height - 8, TUNNEL_0); + break; + } + + paint_util_set_segment_support_height(paint_util_rotate_segments(SEGMENT_D0 | SEGMENT_C4 | SEGMENT_CC, direction), 0xFFFF, 0); + paint_util_set_general_support_height(height + 40, 0x20); +} + +/** rct2: 0x00770C2C */ +static void paint_ghost_train_track_25_deg_down(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element * mapElement) +{ + paint_ghost_train_track_25_deg_up(rideIndex, trackSequence, (direction + 2) % 4, height, mapElement); +} + +/** rct2: 0x00770C3C */ +static void paint_ghost_train_track_flat_to_25_deg_down(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element * mapElement) +{ + paint_ghost_train_track_25_deg_up_to_flat(rideIndex, trackSequence, (direction + 2) % 4, height, mapElement); +} + +/** rct2: 0x00770C4C */ +static void paint_ghost_train_track_25_deg_down_to_flat(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element * mapElement) +{ + paint_ghost_train_track_flat_to_25_deg_up(rideIndex, trackSequence, (direction + 2) % 4, height, mapElement); +} + +/** rct2: 0x00770C5C, 0x00770C6C, 0x00770C7C */ +static void paint_ghost_train_station(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element * mapElement) +{ + uint32 imageId; + + if (direction == 0 || direction == 2) { + imageId = SPR_STATION_BASE_B_SW_NE | RCT2_GLOBAL(0x00F441A0, uint32); + sub_98197C(imageId, 0, 0, 32, 28, 3, height - 2, 0, 2, height, get_current_rotation()); + } else if (direction == 1 || direction == 3) { + imageId = SPR_STATION_BASE_B_NW_SE | RCT2_GLOBAL(0x00F441A0, uint32); + sub_98197C(imageId, 0, 0, 28, 32, 3, height - 2, 2, 0, height, get_current_rotation()); + } + + imageId = ghost_train_track_pieces_flat[direction] | RCT2_GLOBAL(0x00F44198, uint32); + if (direction == 0 || direction == 2) { + sub_98199C(imageId, 0, 0, 32, 20, 3, height, 0, 0, height, get_current_rotation()); + } else { + sub_98199C(imageId, 0, 0, 20, 32, 3, height, 0, 0, height, get_current_rotation()); + } + + if (direction == 0 || direction == 2) { + paint_util_push_tunnel_left(height, TUNNEL_6); + } else { + paint_util_push_tunnel_right(height, TUNNEL_6); + } + + if (direction == 0 || direction == 2) { + metal_a_supports_paint_setup(3, 5, 0, height, RCT2_GLOBAL(0x00F4419C, uint32)); + metal_a_supports_paint_setup(3, 8, 0, height, RCT2_GLOBAL(0x00F4419C, uint32)); + } else { + metal_a_supports_paint_setup(3, 6, 0, height, RCT2_GLOBAL(0x00F4419C, uint32)); + metal_a_supports_paint_setup(3, 7, 0, height, RCT2_GLOBAL(0x00F4419C, uint32)); + } + + track_paint_util_draw_station(rideIndex, trackSequence, direction, height, mapElement); + + paint_util_set_segment_support_height(SEGMENTS_ALL, 0xFFFF, 0); + paint_util_set_general_support_height(height + 32, 0x20); +} + +/** rct2: 0x00770C9C */ +static void paint_ghost_train_track_right_quarter_turn_3_tiles(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element * mapElement) +{ + track_paint_util_right_quarter_turn_3_tiles_paint(3, height, direction, trackSequence, RCT2_GLOBAL(0x00F44198, uint32), ghost_train_track_pieces_quarter_turn_3_tiles, NULL, defaultRightQuarterTurn3TilesBoundLengths, defaultRightQuarterTurn3TilesOffsets, get_current_rotation()); + track_paint_util_right_quarter_turn_3_tiles_tunnel(height, direction, trackSequence); + + switch (trackSequence) { + case 0: + case 3: + metal_a_supports_paint_setup(3, 4, 0, height, RCT2_GLOBAL(0x00F4419C, uint32)); + break; + } + + int blockedSegments = 0; + switch (trackSequence) { + case 0: blockedSegments = SEGMENT_D0 | SEGMENT_C4 | SEGMENT_CC | SEGMENT_BC; break; + case 2: blockedSegments = SEGMENT_D0 | SEGMENT_C4 | SEGMENT_D4 | SEGMENT_C0; break; + case 3: blockedSegments = SEGMENT_D4 | SEGMENT_C4 | SEGMENT_C8 | SEGMENT_B8; break; + } + paint_util_set_segment_support_height(paint_util_rotate_segments(blockedSegments, direction), 0xFFFF, 0); + + paint_util_set_general_support_height(height + 32, 0x20); +} + +/** rct2: 0x00770CAC */ +static void paint_ghost_train_track_left_quarter_turn_3_tiles(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element * mapElement) +{ + trackSequence = mapLeftQuarterTurn3TilesToRightQuarterTurn3Tiles[trackSequence]; + paint_ghost_train_track_right_quarter_turn_3_tiles(rideIndex, trackSequence, (direction + 1) % 4, height, mapElement); +} + +/** rct2: 0x00770CAC */ +static void paint_ghost_train_track_left_quarter_turn_1_tile(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element * mapElement) +{ + track_paint_util_left_quarter_turn_1_tile_paint(3, height, 0, direction, RCT2_GLOBAL(0x00F44198, uint32), ghost_train_track_pieces_quarter_turn_1_tile, get_current_rotation()); + track_paint_util_left_quarter_turn_1_tile_tunnel(height, direction, trackSequence); + + metal_a_supports_paint_setup(3, 4, 0, height, RCT2_GLOBAL(0x00F4419C, uint32)); + paint_util_set_segment_support_height(SEGMENTS_ALL, 0xFFFF, 0); + paint_util_set_general_support_height(height + 32, 0x20); +} + +/** rct2: 0x00770CBC */ +static void paint_ghost_train_track_right_quarter_turn_1_tile(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element * mapElement) +{ + paint_ghost_train_track_left_quarter_turn_1_tile(rideIndex, trackSequence, (direction + 3) % 4, height, mapElement); +} + +/** rct2: 0x00770CCC */ +static void paint_ghost_train_track_spinning_tunnel(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element * mapElement) +{ + uint32 imageId = ghost_train_track_pieces_spinning_tunnel_track[direction] | RCT2_GLOBAL(0x00F44198, uint32); + + if (direction == 0 || direction == 2) { + sub_98197C(imageId, 0, 0, 28, 20, 3, height, 2, 6, height, get_current_rotation()); + } else { + sub_98197C(imageId, 0, 0, 20, 28, 3, height, 6, 2, height, get_current_rotation()); + } + + track_paint_util_spinning_tunnel_paint(3, height, direction, get_current_rotation()); + + if (direction == 0 || direction == 2) { + paint_util_push_tunnel_left(height, TUNNEL_0); + } else { + paint_util_push_tunnel_right(height, TUNNEL_0); + } + + wooden_a_supports_paint_setup((direction & 1), 0, height, RCT2_GLOBAL(0x00F441A0, uint32), NULL); + + paint_util_set_segment_support_height(SEGMENTS_ALL, 0xFFFF, 0); + paint_util_set_general_support_height(height + 32, 0x20); +} + +/** rct2: 0x00770CDC */ +static void paint_ghost_train_track_brakes(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element * mapElement) +{ + rct_xy16 position = {RCT2_GLOBAL(0x009DE56A, sint16), RCT2_GLOBAL(0x009DE56E, sint16)}; + + uint32 imageId = ghost_train_track_pieces_brakes[direction] | RCT2_GLOBAL(0x00F44198, uint32); + + if (direction == 0 || direction == 2) { + sub_98197C(imageId, 0, 0, 32, 20, 3, height, 0, 6, height, get_current_rotation()); + } else { + sub_98197C(imageId, 0, 0, 20, 32, 3, height, 6, 0, height, get_current_rotation()); + } + + if (direction == 0 || direction == 2) { + paint_util_push_tunnel_left(height, TUNNEL_0); + } else { + paint_util_push_tunnel_right(height, TUNNEL_0); + } + + if (track_paint_util_should_paint_supports(position)) { + metal_a_supports_paint_setup(3, 4, 0, height, RCT2_GLOBAL(0x00F4419C, uint32)); + } + + paint_util_set_segment_support_height(paint_util_rotate_segments(SEGMENT_D0 | SEGMENT_C4 | SEGMENT_CC, direction), 0xFFFF, 0); + paint_util_set_general_support_height(height + 32, 0x20); +} + +/** + * rct2: 0x00770924 + */ +TRACK_PAINT_FUNCTION get_track_paint_function_ghost_train(int trackType, int direction) { + switch(trackType) { + case TRACK_ELEM_FLAT: + return paint_ghost_train_track_flat; + + case TRACK_ELEM_END_STATION: + case TRACK_ELEM_BEGIN_STATION: + case TRACK_ELEM_MIDDLE_STATION: + return paint_ghost_train_station; + + case TRACK_ELEM_25_DEG_UP: + return paint_ghost_train_track_25_deg_up; + case TRACK_ELEM_FLAT_TO_25_DEG_UP: + return paint_ghost_train_track_flat_to_25_deg_up; + case TRACK_ELEM_25_DEG_UP_TO_FLAT: + return paint_ghost_train_track_25_deg_up_to_flat; + + case TRACK_ELEM_25_DEG_DOWN: + return paint_ghost_train_track_25_deg_down; + case TRACK_ELEM_FLAT_TO_25_DEG_DOWN: + return paint_ghost_train_track_flat_to_25_deg_down; + case TRACK_ELEM_25_DEG_DOWN_TO_FLAT: + return paint_ghost_train_track_25_deg_down_to_flat; + + case TRACK_ELEM_LEFT_QUARTER_TURN_3_TILES: + return paint_ghost_train_track_left_quarter_turn_3_tiles; + case TRACK_ELEM_RIGHT_QUARTER_TURN_3_TILES: + return paint_ghost_train_track_right_quarter_turn_3_tiles; + + case TRACK_ELEM_LEFT_QUARTER_TURN_1_TILE: + return paint_ghost_train_track_left_quarter_turn_1_tile; + case TRACK_ELEM_RIGHT_QUARTER_TURN_1_TILE: + return paint_ghost_train_track_right_quarter_turn_1_tile; + + case TRACK_ELEM_BRAKES: + return paint_ghost_train_track_brakes; + + case TRACK_ELEM_SPINNING_TUNNEL: + return paint_ghost_train_track_spinning_tunnel; + } + + return NULL; +} diff --git a/src/ride/track_data.c b/src/ride/track_data.c index 6092025521..5333bf40da 100644 --- a/src/ride/track_data.c +++ b/src/ride/track_data.c @@ -5612,7 +5612,7 @@ const TRACK_PAINT_FUNCTION_GETTER RideTypeTrackPaintFunctions[91] = { get_track_paint_function_haunted_house, // RIDE_TYPE_HAUNTED_HOUSE get_track_paint_function_facility, // RIDE_TYPE_FIRST_AID get_track_paint_function_circus_show, // RIDE_TYPE_CIRCUS_SHOW - 0, // RIDE_TYPE_GHOST_TRAIN + get_track_paint_function_ghost_train, // RIDE_TYPE_GHOST_TRAIN 0, // RIDE_TYPE_TWISTER_ROLLER_COASTER 0, // RIDE_TYPE_WOODEN_ROLLER_COASTER 0, // RIDE_TYPE_SIDE_FRICTION_ROLLER_COASTER diff --git a/src/ride/track_paint.c b/src/ride/track_paint.c index be01c3c170..3bc377d454 100644 --- a/src/ride/track_paint.c +++ b/src/ride/track_paint.c @@ -160,6 +160,37 @@ const uint32 trackSpritesSubmarineRideMiniHelicoptersQuarterTurn1Tile[4] = { SPR_TRACK_SUBMARINE_RIDE_MINI_HELICOPTERS_FLAT_QUARTER_TURN_1_TILE_SE_SW, }; +static const uint32 trackSpritesGhostTrainSpinningTunnel[2][2][4] = { + { + { + SPR_GHOST_TRAIN_SPINNING_TUNNEL_BACK_SW_NE_FRAME_0, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_BACK_SW_NE_FRAME_1, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_BACK_SW_NE_FRAME_2, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_BACK_SW_NE_FRAME_3 + }, + { + SPR_GHOST_TRAIN_SPINNING_TUNNEL_FRONT_SW_NE_FRAME_0, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_FRONT_SW_NE_FRAME_1, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_FRONT_SW_NE_FRAME_2, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_FRONT_SW_NE_FRAME_3 + } + }, + { + { + SPR_GHOST_TRAIN_SPINNING_TUNNEL_BACK_NW_SE_FRAME_0, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_BACK_NW_SE_FRAME_1, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_BACK_NW_SE_FRAME_2, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_BACK_NW_SE_FRAME_3 + }, + { + SPR_GHOST_TRAIN_SPINNING_TUNNEL_FRONT_NW_SE_FRAME_0, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_FRONT_NW_SE_FRAME_1, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_FRONT_NW_SE_FRAME_2, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_FRONT_NW_SE_FRAME_3 + } + } +}; + enum { SPR_STATION_COVER_OFFSET_NE_SW_BACK_0 = 0, @@ -771,6 +802,32 @@ void track_paint_util_left_quarter_turn_1_tile_tunnel(sint16 height, uint8 direc } } +void track_paint_util_spinning_tunnel_paint(sint8 thickness, sint16 height, uint8 direction, uint8 rotation) +{ + + int frame = gScenarioTicks >> 2 & 3; + uint32 colourFlags = RCT2_GLOBAL(0x00F4419C, uint32); + + uint32 colourFlags2 = RCT2_GLOBAL(0x00F44198, uint32); + if (colourFlags2 & (IMAGE_TYPE_UNKNOWN << 28)) { + colourFlags |= colourFlags2 & (IMAGE_TYPE_UNKNOWN << 28 | 0x1F << 24); + } + + uint32 imageId = trackSpritesGhostTrainSpinningTunnel[direction & 1][0][frame] | colourFlags; + if (direction == 0 || direction == 2) { + sub_98199C(imageId, 0, 0, 28, 20, thickness, height, 2, 6, height, rotation); + } else { + sub_98199C(imageId, 0, 0, 20, 28, thickness, height, 6, 2, height, rotation); + } + + imageId = trackSpritesGhostTrainSpinningTunnel[direction & 1][1][frame] | colourFlags; + if (direction == 0 || direction == 2) { + sub_98197C(imageId, 0, 0, 26, 1, 23, height, 4, 28, height, rotation); + } else { + sub_98197C(imageId, 0, 0, 1, 26, 23, height, 28, 4, height, rotation); + } +} + /** * * rct2: 0x006C4794 diff --git a/src/ride/track_paint.h b/src/ride/track_paint.h index 705c118ca4..1682498231 100644 --- a/src/ride/track_paint.h +++ b/src/ride/track_paint.h @@ -153,22 +153,22 @@ enum { SPR_ON_RIDE_PHOTO_SIGN_NE_SW = 25625, SPR_ON_RIDE_PHOTO_SIGN_SE_NW = 25626, - SPR_SPINNING_TUNNEL_BACK_SW_NE_FRAME_0 = 28865, - SPR_SPINNING_TUNNEL_BACK_SW_NE_FRAME_1 = 28866, - SPR_SPINNING_TUNNEL_BACK_SW_NE_FRAME_2 = 28867, - SPR_SPINNING_TUNNEL_BACK_SW_NE_FRAME_3 = 28868, - SPR_SPINNING_TUNNEL_BACK_NW_SE_FRAME_0 = 28869, - SPR_SPINNING_TUNNEL_BACK_NW_SE_FRAME_1 = 28870, - SPR_SPINNING_TUNNEL_BACK_NW_SE_FRAME_2 = 28871, - SPR_SPINNING_TUNNEL_BACK_NW_SE_FRAME_3 = 28872, - SPR_SPINNING_TUNNEL_FRONT_SW_NE_FRAME_0 = 28873, - SPR_SPINNING_TUNNEL_FRONT_SW_NE_FRAME_1 = 28874, - SPR_SPINNING_TUNNEL_FRONT_SW_NE_FRAME_2 = 28875, - SPR_SPINNING_TUNNEL_FRONT_SW_NE_FRAME_3 = 28876, - SPR_SPINNING_TUNNEL_FRONT_NW_SE_FRAME_0 = 28877, - SPR_SPINNING_TUNNEL_FRONT_NW_SE_FRAME_1 = 28878, - SPR_SPINNING_TUNNEL_FRONT_NW_SE_FRAME_2 = 28879, - SPR_SPINNING_TUNNEL_FRONT_NW_SE_FRAME_3 = 28880, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_BACK_SW_NE_FRAME_0 = 28865, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_BACK_SW_NE_FRAME_1 = 28866, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_BACK_SW_NE_FRAME_2 = 28867, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_BACK_SW_NE_FRAME_3 = 28868, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_BACK_NW_SE_FRAME_0 = 28869, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_BACK_NW_SE_FRAME_1 = 28870, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_BACK_NW_SE_FRAME_2 = 28871, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_BACK_NW_SE_FRAME_3 = 28872, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_FRONT_SW_NE_FRAME_0 = 28873, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_FRONT_SW_NE_FRAME_1 = 28874, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_FRONT_SW_NE_FRAME_2 = 28875, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_FRONT_SW_NE_FRAME_3 = 28876, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_FRONT_NW_SE_FRAME_0 = 28877, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_FRONT_NW_SE_FRAME_1 = 28878, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_FRONT_NW_SE_FRAME_2 = 28879, + SPR_GHOST_TRAIN_SPINNING_TUNNEL_FRONT_NW_SE_FRAME_3 = 28880, }; extern const uint32 floorSpritesCork[]; @@ -202,6 +202,7 @@ void track_paint_util_left_quarter_turn_3_tiles_paint(sint8 thickness, sint16 he void track_paint_util_left_quarter_turn_3_tiles_tunnel(sint16 height, uint8 direction, uint8 trackSequence); void track_paint_util_left_quarter_turn_1_tile_paint(sint8 thickness, sint16 height, sint16 boundBoxZOffset, int direction, uint32 colourFlags, const uint32 * sprites, uint8 rotation); void track_paint_util_left_quarter_turn_1_tile_tunnel(sint16 height, uint8 direction, uint8 trackSequence); +void track_paint_util_spinning_tunnel_paint(sint8 thickness, sint16 height, uint8 direction, uint8 rotation); typedef void (*TRACK_PAINT_FUNCTION)(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element* mapElement); typedef TRACK_PAINT_FUNCTION (*TRACK_PAINT_FUNCTION_GETTER)(int trackType, int direction); @@ -230,6 +231,7 @@ TRACK_PAINT_FUNCTION get_track_paint_function_facility(int trackType, int direct TRACK_PAINT_FUNCTION get_track_paint_function_twist(int trackType, int direction); TRACK_PAINT_FUNCTION get_track_paint_function_haunted_house(int trackType, int direction); TRACK_PAINT_FUNCTION get_track_paint_function_circus_show(int trackType, int direction); +TRACK_PAINT_FUNCTION get_track_paint_function_ghost_train(int trackType, int direction); TRACK_PAINT_FUNCTION get_track_paint_function_virginia_reel(int trackType, int direction); TRACK_PAINT_FUNCTION get_track_paint_function_mini_helicopters(int trackType, int direction); TRACK_PAINT_FUNCTION get_track_paint_function_mini_golf(int trackType, int direction);