1 /*****************************************************************************
2 * Copyright (c) 2014-2020 OpenRCT2 developers
3 *
4 * For a complete list of all authors, please refer to contributors.md
5 * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
6 *
7 * OpenRCT2 is licensed under the GNU General Public License version 3.
8 *****************************************************************************/
9
10 #include "../../common.h"
11 #include "../../interface/Viewport.h"
12 #include "../../paint/Paint.h"
13 #include "../../paint/Supports.h"
14 #include "../Track.h"
15 #include "../TrackPaint.h"
16 #include "../Vehicle.h"
17 #include "../VehiclePaint.h"
18
19 // 0x009927E6:
20 static constexpr const vehicle_boundbox _virginiaReelBoundbox[] = {
21 { -11, -11, 1, 22, 22, 13 }, { -11, -11, 1, 22, 22, 13 }, { -11, -11, 1, 22, 22, 13 },
22 { -11, -11, 1, 22, 22, 13 }, { -11, -11, 1, 22, 22, 13 }, { -11, -11, 1, 22, 22, 13 },
23 { -11, -11, 1, 22, 22, 13 }, { -11, -11, 1, 22, 22, 13 }, { -11, -11, 1, 22, 22, 13 },
24 };
25
26 enum
27 {
28 SPR_VIRGINIA_REEL_FLAT_SW_NE = 21458,
29 SPR_VIRGINIA_REEL_FLAT_NW_SE = 21459,
30 SPR_VIRGINIA_REEL_FLAT_TO_25_DEG_UP_SW_NE = 21460,
31 SPR_VIRGINIA_REEL_FLAT_TO_25_DEG_UP_NW_SE = 21461,
32 SPR_VIRGINIA_REEL_FLAT_TO_25_DEG_UP_NE_SW = 21462,
33 SPR_VIRGINIA_REEL_FLAT_TO_25_DEG_UP_SE_NW = 21463,
34 SPR_VIRGINIA_REEL_25_DEG_UP_TO_FLAT_SW_NE = 21464,
35 SPR_VIRGINIA_REEL_25_DEG_UP_TO_FLAT_NW_SE = 21465,
36 SPR_VIRGINIA_REEL_25_DEG_UP_TO_FLAT_NE_SW = 21466,
37 SPR_VIRGINIA_REEL_25_DEG_UP_TO_FLAT_SE_NW = 21467,
38 SPR_VIRGINIA_REEL_25_DEG_UP_SW_NE = 21468,
39 SPR_VIRGINIA_REEL_25_DEG_UP_NW_SE = 21469,
40 SPR_VIRGINIA_REEL_25_DEG_UP_NE_SW = 21470,
41 SPR_VIRGINIA_REEL_25_DEG_UP_SE_NW = 21471,
42 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_3_TILES_SW_SE_PART_0 = 21472,
43 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_3_TILES_SW_SE_PART_1 = 21473,
44 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_3_TILES_SW_SE_PART_2 = 21474,
45 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_3_TILES_NW_SW_PART_0 = 21475,
46 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_3_TILES_NW_SW_PART_1 = 21476,
47 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_3_TILES_NW_SW_PART_2 = 21477,
48 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_3_TILES_NE_NW_PART_0 = 21478,
49 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_3_TILES_NE_NW_PART_1 = 21479,
50 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_3_TILES_NE_NW_PART_2 = 21480,
51 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_3_TILES_SE_NE_PART_0 = 21481,
52 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_3_TILES_SE_NE_PART_1 = 21482,
53 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_3_TILES_SE_NE_PART_2 = 21483,
54 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_1_TILE_SW_NW = 21484,
55 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_1_TILE_NW_NE = 21485,
56 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_1_TILE_NE_SE = 21486,
57 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_1_TILE_SE_SW = 21487,
58 SPR_VIRGINIA_REEL_FLAT_LIFT_HILL_SW_NE = 21488,
59 SPR_VIRGINIA_REEL_FLAT_LIFT_HILL_NW_SE = 21489,
60 SPR_VIRGINIA_REEL_FLAT_LIFT_HILL_NE_SW = 21490,
61 SPR_VIRGINIA_REEL_FLAT_LIFT_HILL_SE_NW = 21491,
62 SPR_VIRGINIA_REEL_FLAT_TO_25_DEG_UP_LIFT_HILL_SW_NE = 21492,
63 SPR_VIRGINIA_REEL_FLAT_TO_25_DEG_UP_LIFT_HILL_NW_SE = 21493,
64 SPR_VIRGINIA_REEL_FLAT_TO_25_DEG_UP_LIFT_HILL_NE_SW = 21494,
65 SPR_VIRGINIA_REEL_FLAT_TO_25_DEG_UP_LIFT_HILL_SE_NW = 21495,
66 SPR_VIRGINIA_REEL_25_DEG_UP_TO_FLAT_LIFT_HILL_SW_NE = 21496,
67 SPR_VIRGINIA_REEL_25_DEG_UP_TO_FLAT_LIFT_HILL_NW_SE = 21497,
68 SPR_VIRGINIA_REEL_25_DEG_UP_TO_FLAT_LIFT_HILL_NE_SW = 21498,
69 SPR_VIRGINIA_REEL_25_DEG_UP_TO_FLAT_LIFT_HILL_SE_NW = 21499,
70 SPR_VIRGINIA_REEL_25_DEG_UP_LIFT_HILL_SW_NE = 21500,
71 SPR_VIRGINIA_REEL_25_DEG_UP_LIFT_HILL_NW_SE = 21501,
72 SPR_VIRGINIA_REEL_25_DEG_UP_LIFT_HILL_NE_SW = 21502,
73 SPR_VIRGINIA_REEL_25_DEG_UP_LIFT_HILL_SE_NW = 21503,
74 };
75
76 static constexpr const uint32_t virginia_reel_track_pieces_flat[4] = {
77 SPR_VIRGINIA_REEL_FLAT_SW_NE,
78 SPR_VIRGINIA_REEL_FLAT_NW_SE,
79 SPR_VIRGINIA_REEL_FLAT_SW_NE,
80 SPR_VIRGINIA_REEL_FLAT_NW_SE,
81 };
82
83 static constexpr const uint32_t virginia_reel_track_pieces_flat_lift_hill[4] = {
84 SPR_VIRGINIA_REEL_FLAT_LIFT_HILL_SW_NE,
85 SPR_VIRGINIA_REEL_FLAT_LIFT_HILL_NW_SE,
86 SPR_VIRGINIA_REEL_FLAT_LIFT_HILL_NE_SW,
87 SPR_VIRGINIA_REEL_FLAT_LIFT_HILL_SE_NW,
88 };
89
90 static constexpr const uint32_t virginia_reel_track_pieces_flat_to_25_deg_up[4] = {
91 SPR_VIRGINIA_REEL_FLAT_TO_25_DEG_UP_SW_NE,
92 SPR_VIRGINIA_REEL_FLAT_TO_25_DEG_UP_NW_SE,
93 SPR_VIRGINIA_REEL_FLAT_TO_25_DEG_UP_NE_SW,
94 SPR_VIRGINIA_REEL_FLAT_TO_25_DEG_UP_SE_NW,
95 };
96
97 static constexpr const uint32_t virginia_reel_track_pieces_flat_to_25_deg_up_lift_hill[4] = {
98 SPR_VIRGINIA_REEL_FLAT_TO_25_DEG_UP_LIFT_HILL_SW_NE,
99 SPR_VIRGINIA_REEL_FLAT_TO_25_DEG_UP_LIFT_HILL_NW_SE,
100 SPR_VIRGINIA_REEL_FLAT_TO_25_DEG_UP_LIFT_HILL_NE_SW,
101 SPR_VIRGINIA_REEL_FLAT_TO_25_DEG_UP_LIFT_HILL_SE_NW,
102 };
103
104 static constexpr const uint32_t virginia_reel_track_pieces_25_deg_up_to_flat[4] = {
105 SPR_VIRGINIA_REEL_25_DEG_UP_TO_FLAT_SW_NE,
106 SPR_VIRGINIA_REEL_25_DEG_UP_TO_FLAT_NW_SE,
107 SPR_VIRGINIA_REEL_25_DEG_UP_TO_FLAT_NE_SW,
108 SPR_VIRGINIA_REEL_25_DEG_UP_TO_FLAT_SE_NW,
109 };
110
111 static constexpr const uint32_t virginia_reel_track_pieces_25_deg_up_to_flat_lift_hill[4] = {
112 SPR_VIRGINIA_REEL_25_DEG_UP_TO_FLAT_LIFT_HILL_SW_NE,
113 SPR_VIRGINIA_REEL_25_DEG_UP_TO_FLAT_LIFT_HILL_NW_SE,
114 SPR_VIRGINIA_REEL_25_DEG_UP_TO_FLAT_LIFT_HILL_NE_SW,
115 SPR_VIRGINIA_REEL_25_DEG_UP_TO_FLAT_LIFT_HILL_SE_NW,
116 };
117
118 static constexpr const uint32_t virginia_reel_track_pieces_25_deg_up[4] = {
119 SPR_VIRGINIA_REEL_25_DEG_UP_SW_NE,
120 SPR_VIRGINIA_REEL_25_DEG_UP_NW_SE,
121 SPR_VIRGINIA_REEL_25_DEG_UP_NE_SW,
122 SPR_VIRGINIA_REEL_25_DEG_UP_SE_NW,
123 };
124
125 static constexpr const uint32_t virginia_reel_track_pieces_25_deg_up_lift_hill[4] = {
126 SPR_VIRGINIA_REEL_25_DEG_UP_LIFT_HILL_SW_NE,
127 SPR_VIRGINIA_REEL_25_DEG_UP_LIFT_HILL_NW_SE,
128 SPR_VIRGINIA_REEL_25_DEG_UP_LIFT_HILL_NE_SW,
129 SPR_VIRGINIA_REEL_25_DEG_UP_LIFT_HILL_SE_NW,
130 };
131
132 static constexpr const uint32_t virginia_reel_track_pieces_flat_quarter_turn_3_tiles[4][3] = {
133 {
134 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_3_TILES_SW_SE_PART_0,
135 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_3_TILES_SW_SE_PART_1,
136 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_3_TILES_SW_SE_PART_2,
137 },
138 {
139 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_3_TILES_NW_SW_PART_0,
140 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_3_TILES_NW_SW_PART_1,
141 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_3_TILES_NW_SW_PART_2,
142 },
143 {
144 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_3_TILES_NE_NW_PART_0,
145 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_3_TILES_NE_NW_PART_1,
146 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_3_TILES_NE_NW_PART_2,
147 },
148 {
149 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_3_TILES_SE_NE_PART_0,
150 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_3_TILES_SE_NE_PART_1,
151 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_3_TILES_SE_NE_PART_2,
152 },
153 };
154
155 static constexpr const uint32_t virginia_reel_track_pieces_flat_quarter_turn_1_tile[4] = {
156 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_1_TILE_SW_NW,
157 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_1_TILE_NW_NE,
158 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_1_TILE_NE_SE,
159 SPR_VIRGINIA_REEL_FLAT_QUARTER_TURN_1_TILE_SE_SW,
160 };
161
162 /**
163 *
164 * rct2: 0x006D5B48
165 */
vehicle_visual_virginia_reel(paint_session * session,int32_t x,int32_t imageDirection,int32_t y,int32_t z,const Vehicle * vehicle,const rct_ride_entry_vehicle * vehicleEntry)166 void vehicle_visual_virginia_reel(
167 paint_session* session, int32_t x, int32_t imageDirection, int32_t y, int32_t z, const Vehicle* vehicle,
168 const rct_ride_entry_vehicle* vehicleEntry)
169 {
170 const uint8_t rotation = session->CurrentRotation;
171 int32_t ecx = ((vehicle->spin_sprite / 8) + (rotation * 8)) & 31;
172 int32_t baseImage_id = [&] {
173 switch (vehicle->Pitch)
174 {
175 case 1:
176 return (imageDirection & 24) + 8;
177 case 2:
178 return (imageDirection & 24) + 40;
179 case 5:
180 return ((imageDirection ^ 16) & 24) + 8;
181 case 6:
182 return ((imageDirection ^ 16) & 24) + 40;
183 default:
184 return 0;
185 }
186 }();
187 baseImage_id += ecx & 7;
188 const vehicle_boundbox* bb = &_virginiaReelBoundbox[baseImage_id >> 3];
189
190 baseImage_id += vehicleEntry->base_image_id;
191 int32_t image_id = baseImage_id | SPRITE_ID_PALETTE_COLOUR_2(vehicle->colours.body_colour, vehicle->colours.trim_colour);
192 if (vehicle->IsGhost())
193 {
194 image_id = (image_id & 0x7FFFF) | CONSTRUCTION_MARKER;
195 }
196 PaintAddImageAsParent(
197 session, image_id, { 0, 0, z }, { bb->length_x, bb->length_y, bb->length_z },
198 { bb->offset_x, bb->offset_y, bb->offset_z + z });
199
200 if (session->DPI.zoom_level < 2 && vehicle->num_peeps > 0 && !vehicle->IsGhost())
201 {
202 uint8_t riding_peep_sprites[4] = { 0xFF, 0xFF, 0xFF, 0xFF };
203 for (int32_t i = 0; i < vehicle->num_peeps; i++)
204 {
205 riding_peep_sprites[((ecx / 8) + i) & 3] = vehicle->peep_tshirt_colours[i];
206 }
207 int32_t draw_order[4] = { 0, 1, 3, 2 };
208 for (auto i : draw_order)
209 {
210 if (riding_peep_sprites[i] != 0xFF)
211 {
212 image_id = (baseImage_id + ((i + 1) * 72)) | SPRITE_ID_PALETTE_COLOUR_1(riding_peep_sprites[i]);
213 PaintAddImageAsChild(
214 session, image_id, 0, 0, bb->length_x, bb->length_y, bb->length_z, z, bb->offset_x, bb->offset_y,
215 bb->offset_z + z);
216 }
217 }
218 }
219
220 assert(vehicleEntry->effect_visual == 1);
221 }
222
223 /** rct2: 0x00811264 */
paint_virginia_reel_track_flat(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)224 static void paint_virginia_reel_track_flat(
225 paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
226 const TrackElement& trackElement)
227 {
228 const uint32_t* sprites = virginia_reel_track_pieces_flat;
229 if (trackElement.HasChain())
230 {
231 sprites = virginia_reel_track_pieces_flat_lift_hill;
232 }
233
234 uint32_t imageId = sprites[direction] | session->TrackColours[SCHEME_TRACK];
235 if (direction & 1)
236 {
237 PaintAddImageAsParent(session, imageId, { 0, 0, height }, { 27, 32, 2 }, { 2, 0, height });
238 paint_util_push_tunnel_right(session, height, TUNNEL_SQUARE_FLAT);
239 }
240 else
241 {
242 PaintAddImageAsParent(session, imageId, { 0, 0, height }, { 32, 27, 2 }, { 0, 2, height });
243 paint_util_push_tunnel_left(session, height, TUNNEL_SQUARE_FLAT);
244 }
245
246 wooden_a_supports_paint_setup(session, (direction & 1), 0, height, session->TrackColours[SCHEME_SUPPORTS]);
247
248 paint_util_set_segment_support_height(session, SEGMENTS_ALL, 0xFFFF, 0);
249 paint_util_set_general_support_height(session, height + 32, 0x20);
250 }
251
252 /** rct2: 0x00811274 */
paint_virginia_reel_track_25_deg_up(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)253 static void paint_virginia_reel_track_25_deg_up(
254 paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
255 const TrackElement& trackElement)
256 {
257 const uint32_t* sprites = virginia_reel_track_pieces_25_deg_up;
258 if (trackElement.HasChain())
259 {
260 sprites = virginia_reel_track_pieces_25_deg_up_lift_hill;
261 }
262
263 uint32_t imageId = sprites[direction] | session->TrackColours[SCHEME_TRACK];
264 paint_struct* ps;
265
266 if (direction & 1)
267 {
268 ps = PaintAddImageAsParent(session, imageId, { 0, 0, height }, { 27, 32, 2 }, { 2, 0, height });
269 }
270 else
271 {
272 ps = PaintAddImageAsParent(session, imageId, { 0, 0, height }, { 32, 27, 2 }, { 0, 2, height });
273 }
274
275 if (direction == 1 || direction == 2)
276 {
277 session->WoodenSupportsPrependTo = ps;
278 }
279
280 switch (direction)
281 {
282 case 0:
283 wooden_a_supports_paint_setup(session, 0, 9, height, session->TrackColours[SCHEME_SUPPORTS]);
284 paint_util_push_tunnel_left(session, height - 8, TUNNEL_SQUARE_7);
285 break;
286 case 1:
287 wooden_a_supports_paint_setup(session, 1, 10, height, session->TrackColours[SCHEME_SUPPORTS]);
288 paint_util_push_tunnel_right(session, height + 8, TUNNEL_SQUARE_8);
289 break;
290 case 2:
291 wooden_a_supports_paint_setup(session, 0, 11, height, session->TrackColours[SCHEME_SUPPORTS]);
292 paint_util_push_tunnel_left(session, height + 8, TUNNEL_SQUARE_8);
293 break;
294 case 3:
295 wooden_a_supports_paint_setup(session, 1, 12, height, session->TrackColours[SCHEME_SUPPORTS]);
296 paint_util_push_tunnel_right(session, height - 8, TUNNEL_SQUARE_7);
297 break;
298 }
299
300 paint_util_set_segment_support_height(session, SEGMENTS_ALL, 0xFFFF, 0);
301 paint_util_set_general_support_height(session, height + 56, 0x20);
302 }
303
304 /** rct2: 0x00811294 */
paint_virginia_reel_track_flat_to_25_deg_up(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)305 static void paint_virginia_reel_track_flat_to_25_deg_up(
306 paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
307 const TrackElement& trackElement)
308 {
309 const uint32_t* sprites = virginia_reel_track_pieces_flat_to_25_deg_up;
310 if (trackElement.HasChain())
311 {
312 sprites = virginia_reel_track_pieces_flat_to_25_deg_up_lift_hill;
313 }
314
315 uint32_t imageId = sprites[direction] | session->TrackColours[SCHEME_TRACK];
316 paint_struct* ps;
317 switch (direction)
318 {
319 case 0:
320 PaintAddImageAsParent(session, imageId, { 0, 0, height }, { 32, 27, 2 }, { 0, 2, height });
321
322 wooden_a_supports_paint_setup(session, 0, 1, height, session->TrackColours[SCHEME_SUPPORTS]);
323 paint_util_push_tunnel_left(session, height, TUNNEL_SQUARE_FLAT);
324 break;
325 case 1:
326 ps = PaintAddImageAsParent(session, imageId, { 0, 0, height }, { 27, 32, 2 }, { 2, 0, height });
327 session->WoodenSupportsPrependTo = ps;
328
329 wooden_a_supports_paint_setup(session, 1, 2, height, session->TrackColours[SCHEME_SUPPORTS]);
330 paint_util_push_tunnel_right(session, height, TUNNEL_SQUARE_8);
331 break;
332 case 2:
333 ps = PaintAddImageAsParent(session, imageId, { 0, 0, height }, { 32, 27, 2 }, { 0, 2, height });
334 session->WoodenSupportsPrependTo = ps;
335
336 wooden_a_supports_paint_setup(session, 0, 3, height, session->TrackColours[SCHEME_SUPPORTS]);
337 paint_util_push_tunnel_left(session, height, TUNNEL_SQUARE_8);
338 break;
339 case 3:
340 PaintAddImageAsParent(session, imageId, { 0, 0, height }, { 27, 32, 2 }, { 2, 0, height });
341
342 wooden_a_supports_paint_setup(session, 1, 4, height, session->TrackColours[SCHEME_SUPPORTS]);
343 paint_util_push_tunnel_right(session, height, TUNNEL_SQUARE_FLAT);
344 break;
345 }
346
347 paint_util_set_segment_support_height(session, SEGMENTS_ALL, 0xFFFF, 0);
348 paint_util_set_general_support_height(session, height + 48, 0x20);
349 }
350
351 /** rct2: 0x00811294 */
paint_virginia_reel_track_25_deg_up_to_flat(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)352 static void paint_virginia_reel_track_25_deg_up_to_flat(
353 paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
354 const TrackElement& trackElement)
355 {
356 const uint32_t* sprites = virginia_reel_track_pieces_25_deg_up_to_flat;
357 if (trackElement.HasChain())
358 {
359 sprites = virginia_reel_track_pieces_25_deg_up_to_flat_lift_hill;
360 }
361
362 uint32_t imageId = sprites[direction] | session->TrackColours[SCHEME_TRACK];
363 paint_struct* ps;
364
365 if (direction & 1)
366 {
367 ps = PaintAddImageAsParent(session, imageId, { 0, 0, height }, { 27, 32, 2 }, { 2, 0, height });
368 }
369 else
370 {
371 ps = PaintAddImageAsParent(session, imageId, { 0, 0, height }, { 32, 27, 2 }, { 0, 2, height });
372 }
373
374 if (direction == 1 || direction == 2)
375 {
376 session->WoodenSupportsPrependTo = ps;
377 }
378
379 switch (direction)
380 {
381 case 0:
382 wooden_a_supports_paint_setup(session, 0, 5, height, session->TrackColours[SCHEME_SUPPORTS]);
383 paint_util_push_tunnel_left(session, height - 8, TUNNEL_SQUARE_FLAT);
384 break;
385 case 1:
386 wooden_a_supports_paint_setup(session, 1, 6, height, session->TrackColours[SCHEME_SUPPORTS]);
387 paint_util_push_tunnel_right(session, height + 8, TUNNEL_14);
388 break;
389 case 2:
390 wooden_a_supports_paint_setup(session, 0, 7, height, session->TrackColours[SCHEME_SUPPORTS]);
391 paint_util_push_tunnel_left(session, height + 8, TUNNEL_14);
392 break;
393 case 3:
394 wooden_a_supports_paint_setup(session, 1, 8, height, session->TrackColours[SCHEME_SUPPORTS]);
395 paint_util_push_tunnel_right(session, height - 8, TUNNEL_SQUARE_FLAT);
396 break;
397 }
398
399 paint_util_set_segment_support_height(session, SEGMENTS_ALL, 0xFFFF, 0);
400 paint_util_set_general_support_height(session, height + 40, 0x20);
401 }
402
403 /** rct2: 0x008112A4 */
paint_virginia_reel_track_25_deg_down(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)404 static void paint_virginia_reel_track_25_deg_down(
405 paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
406 const TrackElement& trackElement)
407 {
408 paint_virginia_reel_track_25_deg_up(session, ride, trackSequence, (direction + 2) % 4, height, trackElement);
409 }
410
411 /** rct2: 0x008112B4 */
paint_virginia_reel_track_flat_to_25_deg_down(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)412 static void paint_virginia_reel_track_flat_to_25_deg_down(
413 paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
414 const TrackElement& trackElement)
415 {
416 paint_virginia_reel_track_25_deg_up_to_flat(session, ride, trackSequence, (direction + 2) % 4, height, trackElement);
417 }
418
419 /** rct2: 0x008112C4 */
paint_virginia_reel_track_25_deg_down_to_flat(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)420 static void paint_virginia_reel_track_25_deg_down_to_flat(
421 paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
422 const TrackElement& trackElement)
423 {
424 paint_virginia_reel_track_flat_to_25_deg_up(session, ride, trackSequence, (direction + 2) % 4, height, trackElement);
425 }
426
427 /** rct2: 0x008112D4, 0x008112E4, 0x008112F4 */
paint_virginia_reel_station(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)428 static void paint_virginia_reel_station(
429 paint_session* session, const Ride* ride, [[maybe_unused]] uint8_t trackSequence, uint8_t direction, int32_t height,
430 const TrackElement& trackElement)
431 {
432 uint32_t imageId;
433
434 if (direction == 0 || direction == 2)
435 {
436 imageId = SPR_STATION_BASE_B_SW_NE | session->TrackColours[SCHEME_MISC];
437 PaintAddImageAsParent(session, imageId, { 0, 0, height - 2 }, { 32, 28, 2 }, { 0, 2, height });
438
439 imageId = SPR_VIRGINIA_REEL_FLAT_SW_NE | session->TrackColours[SCHEME_TRACK];
440 PaintAddImageAsChild(session, imageId, 0, 0, 32, 20, 2, height, 0, 0, height);
441
442 paint_util_push_tunnel_left(session, height, TUNNEL_SQUARE_FLAT);
443 }
444 else if (direction == 1 || direction == 3)
445 {
446 imageId = SPR_STATION_BASE_B_NW_SE | session->TrackColours[SCHEME_MISC];
447 PaintAddImageAsParent(session, imageId, { 0, 0, height - 2 }, { 28, 32, 2 }, { 2, 0, height });
448
449 imageId = SPR_VIRGINIA_REEL_FLAT_NW_SE | session->TrackColours[SCHEME_TRACK];
450 PaintAddImageAsChild(session, imageId, 0, 0, 20, 32, 2, height, 0, 0, height);
451
452 paint_util_push_tunnel_right(session, height, TUNNEL_SQUARE_FLAT);
453 }
454
455 wooden_a_supports_paint_setup(session, (direction & 1), 0, height, session->TrackColours[SCHEME_SUPPORTS]);
456 track_paint_util_draw_station(session, ride, direction, height, trackElement);
457
458 paint_util_set_segment_support_height(session, SEGMENTS_ALL, 0xFFFF, 0);
459 paint_util_set_general_support_height(session, height + 32, 0x20);
460 }
461
462 static constexpr const uint8_t virginia_reel_left_quarter_turn_supports[] = {
463 5,
464 2,
465 3,
466 4,
467 };
468
469 /** rct2: 0x00811304 */
paint_virginia_reel_track_left_quarter_turn_3_tiles(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)470 static void paint_virginia_reel_track_left_quarter_turn_3_tiles(
471 paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
472 const TrackElement& trackElement)
473 {
474 track_paint_util_left_quarter_turn_3_tiles_paint(
475 session, 2, height, direction, trackSequence, session->TrackColours[SCHEME_TRACK],
476 virginia_reel_track_pieces_flat_quarter_turn_3_tiles);
477 track_paint_util_left_quarter_turn_3_tiles_tunnel(session, height, TUNNEL_SQUARE_FLAT, direction, trackSequence);
478
479 switch (trackSequence)
480 {
481 case 2:
482 paint_util_set_segment_support_height(
483 session, paint_util_rotate_segments(SEGMENT_C8 | SEGMENT_C4 | SEGMENT_D0 | SEGMENT_B8, direction), 0xFFFF, 0);
484 break;
485 case 0:
486 case 3:
487 wooden_a_supports_paint_setup(
488 session, virginia_reel_left_quarter_turn_supports[direction], 0, height,
489 session->TrackColours[SCHEME_SUPPORTS]);
490 paint_util_set_segment_support_height(session, paint_util_rotate_segments(SEGMENTS_ALL, direction), 0xFFFF, 0);
491 break;
492 }
493
494 paint_util_set_general_support_height(session, height + 32, 0x20);
495 }
496
497 static constexpr const uint8_t virginia_reel_right_quarter_turn_3_tiles_to_left_turn_map[] = {
498 3,
499 1,
500 2,
501 0,
502 };
503
504 /** rct2: 0x00811314 */
paint_virginia_reel_track_right_quarter_turn_3_tiles(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)505 static void paint_virginia_reel_track_right_quarter_turn_3_tiles(
506 paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
507 const TrackElement& trackElement)
508 {
509 trackSequence = virginia_reel_right_quarter_turn_3_tiles_to_left_turn_map[trackSequence];
510 paint_virginia_reel_track_left_quarter_turn_3_tiles(
511 session, ride, trackSequence, (direction + 3) % 4, height, trackElement);
512 }
513
514 /** rct2: 0x00811324 */
paint_virginia_reel_track_left_quarter_turn_1_tile(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)515 static void paint_virginia_reel_track_left_quarter_turn_1_tile(
516 paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
517 const TrackElement& trackElement)
518 {
519 track_paint_util_left_quarter_turn_1_tile_paint(
520 session, 2, height, 0, direction, session->TrackColours[SCHEME_TRACK],
521 virginia_reel_track_pieces_flat_quarter_turn_1_tile);
522
523 switch (direction)
524 {
525 case 0:
526 wooden_a_supports_paint_setup(session, 5, 0, height, session->TrackColours[SCHEME_SUPPORTS]);
527 paint_util_push_tunnel_left(session, height, TUNNEL_SQUARE_FLAT);
528 break;
529 case 1:
530 wooden_a_supports_paint_setup(session, 2, 0, height, session->TrackColours[SCHEME_SUPPORTS]);
531 break;
532 case 2:
533 wooden_a_supports_paint_setup(session, 3, 0, height, session->TrackColours[SCHEME_SUPPORTS]);
534 paint_util_push_tunnel_right(session, height, TUNNEL_SQUARE_FLAT);
535 break;
536 case 3:
537 wooden_a_supports_paint_setup(session, 4, 0, height, session->TrackColours[SCHEME_SUPPORTS]);
538 paint_util_push_tunnel_right(session, height, TUNNEL_SQUARE_FLAT);
539 paint_util_push_tunnel_left(session, height, TUNNEL_SQUARE_FLAT);
540 break;
541 }
542
543 paint_util_set_segment_support_height(session, SEGMENTS_ALL, 0xFFFF, 0);
544 paint_util_set_general_support_height(session, height + 32, 0x20);
545 }
546
547 /** rct2: 0x00811334 */
paint_virginia_reel_track_right_quarter_turn_1_tile(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)548 static void paint_virginia_reel_track_right_quarter_turn_1_tile(
549 paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
550 const TrackElement& trackElement)
551 {
552 paint_virginia_reel_track_left_quarter_turn_1_tile(session, ride, trackSequence, (direction + 3) % 4, height, trackElement);
553 }
554
555 /**
556 * rct2: 0x00811184
557 */
get_track_paint_function_virginia_reel(int32_t trackType)558 TRACK_PAINT_FUNCTION get_track_paint_function_virginia_reel(int32_t trackType)
559 {
560 switch (trackType)
561 {
562 case TrackElemType::Flat:
563 return paint_virginia_reel_track_flat;
564
565 case TrackElemType::EndStation:
566 case TrackElemType::BeginStation:
567 case TrackElemType::MiddleStation:
568 return paint_virginia_reel_station;
569
570 case TrackElemType::Up25:
571 return paint_virginia_reel_track_25_deg_up;
572 case TrackElemType::FlatToUp25:
573 return paint_virginia_reel_track_flat_to_25_deg_up;
574 case TrackElemType::Up25ToFlat:
575 return paint_virginia_reel_track_25_deg_up_to_flat;
576
577 case TrackElemType::Down25:
578 return paint_virginia_reel_track_25_deg_down;
579 case TrackElemType::FlatToDown25:
580 return paint_virginia_reel_track_flat_to_25_deg_down;
581 case TrackElemType::Down25ToFlat:
582 return paint_virginia_reel_track_25_deg_down_to_flat;
583
584 case TrackElemType::LeftQuarterTurn3Tiles:
585 return paint_virginia_reel_track_left_quarter_turn_3_tiles;
586 case TrackElemType::RightQuarterTurn3Tiles:
587 return paint_virginia_reel_track_right_quarter_turn_3_tiles;
588
589 case TrackElemType::LeftQuarterTurn1Tile:
590 return paint_virginia_reel_track_left_quarter_turn_1_tile;
591 case TrackElemType::RightQuarterTurn1Tile:
592 return paint_virginia_reel_track_right_quarter_turn_1_tile;
593 }
594
595 return nullptr;
596 }
597