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 "../../drawing/Drawing.h"
11 #include "../../interface/Viewport.h"
12 #include "../../paint/Paint.h"
13 #include "../../paint/Supports.h"
14 #include "../../paint/tile_element/Paint.TileElement.h"
15 #include "../../sprites.h"
16 #include "../../world/Map.h"
17 #include "../RideData.h"
18 #include "../TrackData.h"
19 #include "../TrackPaint.h"
20 
21 /** rct2: 0x008B0460 */
inverted_impulse_rc_track_flat(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)22 static void inverted_impulse_rc_track_flat(
23     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
24     const TrackElement& trackElement)
25 {
26     switch (direction)
27     {
28         case 0:
29         case 2:
30             PaintAddImageAsParentRotated(
31                 session, direction, session->TrackColours[SCHEME_TRACK] | 19662, 0, 0, 32, 20, 3, height + 29, 0, 6,
32                 height + 29);
33             break;
34         case 1:
35         case 3:
36             PaintAddImageAsParentRotated(
37                 session, direction, session->TrackColours[SCHEME_TRACK] | 19663, 0, 0, 32, 20, 3, height + 29, 0, 6,
38                 height + 29);
39             break;
40     }
41 
42     paint_util_set_segment_support_height(
43         session, paint_util_rotate_segments(SEGMENT_C4 | SEGMENT_CC | SEGMENT_D0, direction), 0xFFFF, 0);
44     if (track_paint_util_should_paint_supports(session->MapPosition))
45     {
46         metal_a_supports_paint_setup(
47             session, METAL_SUPPORTS_TUBES_INVERTED, 4, 0, height + 44, session->TrackColours[SCHEME_SUPPORTS]);
48     }
49 
50     paint_util_push_tunnel_rotated(session, direction, height, TUNNEL_INVERTED_3);
51     paint_util_set_general_support_height(session, height + 48, 0x20);
52 }
53 
54 /** rct2: 0x008B0470, 0x008B0480, 0x008B0490 */
inverted_impulse_rc_track_station(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)55 static void inverted_impulse_rc_track_station(
56     paint_session* session, const Ride* ride, [[maybe_unused]] uint8_t trackSequence, uint8_t direction, int32_t height,
57     const TrackElement& trackElement)
58 {
59     static constexpr const uint32_t imageIds[4][3] = {
60         { SPR_STATION_BASE_C_SW_NE, 19662, SPR_STATION_INVERTED_BAR_B_SW_NE },
61         { SPR_STATION_BASE_C_NW_SE, 19663, SPR_STATION_INVERTED_BAR_B_NW_SE },
62         { SPR_STATION_BASE_C_SW_NE, 19662, SPR_STATION_INVERTED_BAR_B_SW_NE },
63         { SPR_STATION_BASE_C_NW_SE, 19663, SPR_STATION_INVERTED_BAR_B_NW_SE },
64     };
65 
66     PaintAddImageAsParentRotated(
67         session, direction, imageIds[direction][0] | session->TrackColours[SCHEME_MISC], 0, 0, 32, 28, 1, height, 0, 2, height);
68     PaintAddImageAsParentRotated(
69         session, direction, imageIds[direction][1] | session->TrackColours[SCHEME_TRACK], 0, 0, 32, 20, 3, height + 29, 0, 6,
70         height + 29);
71     PaintAddImageAsChildRotated(
72         session, direction, imageIds[direction][2] | session->TrackColours[SCHEME_SUPPORTS], 0, 6, 32, 20, 3, height + 29, 0, 6,
73         height + 29);
74     track_paint_util_draw_station_metal_supports_2(session, direction, height, session->TrackColours[SCHEME_SUPPORTS], 11);
75     track_paint_util_draw_station_inverted(session, ride, direction, height, trackElement, STATION_VARIANT_TALL);
76     paint_util_push_tunnel_rotated(session, direction, height, TUNNEL_SQUARE_INVERTED_9);
77     paint_util_set_segment_support_height(session, SEGMENTS_ALL, 0xFFFF, 0);
78     paint_util_set_general_support_height(session, height + 48, 0x20);
79 }
80 
81 /** rct2: 0x008B04A0 */
inverted_impulse_rc_track_25_deg_up(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)82 static void inverted_impulse_rc_track_25_deg_up(
83     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
84     const TrackElement& trackElement)
85 {
86     switch (direction)
87     {
88         case 0:
89             PaintAddImageAsParentRotated(
90                 session, direction, session->TrackColours[SCHEME_TRACK] | 19672, 0, 0, 32, 20, 3, height + 29, 0, 6,
91                 height + 45);
92             break;
93         case 1:
94             PaintAddImageAsParentRotated(
95                 session, direction, session->TrackColours[SCHEME_TRACK] | 19673, 0, 0, 32, 20, 3, height + 29, 0, 6,
96                 height + 45);
97             break;
98         case 2:
99             PaintAddImageAsParentRotated(
100                 session, direction, session->TrackColours[SCHEME_TRACK] | 19674, 0, 0, 32, 20, 3, height + 29, 0, 6,
101                 height + 45);
102             break;
103         case 3:
104             PaintAddImageAsParentRotated(
105                 session, direction, session->TrackColours[SCHEME_TRACK] | 19675, 0, 0, 32, 20, 3, height + 29, 0, 6,
106                 height + 45);
107             break;
108     }
109 
110     paint_util_set_segment_support_height(
111         session, paint_util_rotate_segments(SEGMENT_C4 | SEGMENT_CC | SEGMENT_D0, direction), 0xFFFF, 0);
112     if (track_paint_util_should_paint_supports(session->MapPosition))
113     {
114         switch (direction)
115         {
116             case 0:
117                 metal_a_supports_paint_setup(
118                     session, METAL_SUPPORTS_TUBES_INVERTED, 6, 0, height + 62, session->TrackColours[SCHEME_SUPPORTS]);
119                 break;
120             case 1:
121                 metal_a_supports_paint_setup(
122                     session, METAL_SUPPORTS_TUBES_INVERTED, 8, 0, height + 62, session->TrackColours[SCHEME_SUPPORTS]);
123                 break;
124             case 2:
125                 metal_a_supports_paint_setup(
126                     session, METAL_SUPPORTS_TUBES_INVERTED, 7, 0, height + 62, session->TrackColours[SCHEME_SUPPORTS]);
127                 break;
128             case 3:
129                 metal_a_supports_paint_setup(
130                     session, METAL_SUPPORTS_TUBES_INVERTED, 5, 0, height + 62, session->TrackColours[SCHEME_SUPPORTS]);
131                 break;
132         }
133     }
134 
135     if (direction == 0 || direction == 3)
136     {
137         paint_util_push_tunnel_rotated(session, direction, height - 8, TUNNEL_INVERTED_4);
138     }
139     else
140     {
141         paint_util_push_tunnel_rotated(session, direction, height + 8, TUNNEL_INVERTED_5);
142     }
143     paint_util_set_general_support_height(session, height + 72, 0x20);
144 }
145 
146 /** rct2: 0x008B04B0 */
inverted_impulse_rc_track_60_deg_up(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)147 static void inverted_impulse_rc_track_60_deg_up(
148     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
149     const TrackElement& trackElement)
150 {
151     switch (direction)
152     {
153         case 0:
154             PaintAddImageAsParentRotated(
155                 session, direction, session->TrackColours[SCHEME_TRACK] | 19688, 0, 0, 32, 20, 3, height + 29, 0, 6,
156                 height + 93);
157             break;
158         case 1:
159             PaintAddImageAsParentRotated(
160                 session, direction, session->TrackColours[SCHEME_TRACK] | 19689, 0, 0, 32, 2, 81, height + 29, 0, 4,
161                 height + 11);
162             break;
163         case 2:
164             PaintAddImageAsParentRotated(
165                 session, direction, session->TrackColours[SCHEME_TRACK] | 19690, 0, 0, 32, 2, 81, height + 29, 0, 4,
166                 height + 11);
167             break;
168         case 3:
169             PaintAddImageAsParentRotated(
170                 session, direction, session->TrackColours[SCHEME_TRACK] | 19691, 0, 0, 32, 20, 3, height + 29, 0, 6,
171                 height + 93);
172             break;
173     }
174     if (direction == 0 || direction == 3)
175     {
176         paint_util_push_tunnel_rotated(session, direction, height - 8, TUNNEL_INVERTED_4);
177     }
178     else
179     {
180         paint_util_push_tunnel_rotated(session, direction, height + 56, TUNNEL_INVERTED_5);
181     }
182     paint_util_set_segment_support_height(
183         session, paint_util_rotate_segments(SEGMENT_C4 | SEGMENT_CC | SEGMENT_D0, direction), 0xFFFF, 0);
184     paint_util_set_general_support_height(session, height + 120, 0x20);
185 }
186 
187 /** rct2: 0x008B04C0 */
inverted_impulse_rc_track_flat_to_25_deg_up(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)188 static void inverted_impulse_rc_track_flat_to_25_deg_up(
189     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
190     const TrackElement& trackElement)
191 {
192     switch (direction)
193     {
194         case 0:
195             PaintAddImageAsParentRotated(
196                 session, direction, session->TrackColours[SCHEME_TRACK] | 19664, 0, 0, 32, 20, 3, height + 29, 0, 6,
197                 height + 37);
198             break;
199         case 1:
200             PaintAddImageAsParentRotated(
201                 session, direction, session->TrackColours[SCHEME_TRACK] | 19665, 0, 0, 32, 20, 3, height + 29, 0, 6,
202                 height + 37);
203             break;
204         case 2:
205             PaintAddImageAsParentRotated(
206                 session, direction, session->TrackColours[SCHEME_TRACK] | 19666, 0, 0, 32, 20, 3, height + 29, 0, 6,
207                 height + 37);
208             break;
209         case 3:
210             PaintAddImageAsParentRotated(
211                 session, direction, session->TrackColours[SCHEME_TRACK] | 19667, 0, 0, 32, 20, 3, height + 29, 0, 6,
212                 height + 37);
213             break;
214     }
215 
216     paint_util_set_segment_support_height(
217         session, paint_util_rotate_segments(SEGMENT_C4 | SEGMENT_CC | SEGMENT_D0, direction), 0xFFFF, 0);
218     switch (direction)
219     {
220         case 0:
221             metal_a_supports_paint_setup(
222                 session, METAL_SUPPORTS_TUBES_INVERTED, 6, 0, height + 54, session->TrackColours[SCHEME_SUPPORTS]);
223             break;
224         case 1:
225             metal_a_supports_paint_setup(
226                 session, METAL_SUPPORTS_TUBES_INVERTED, 8, 0, height + 54, session->TrackColours[SCHEME_SUPPORTS]);
227             break;
228         case 2:
229             metal_a_supports_paint_setup(
230                 session, METAL_SUPPORTS_TUBES_INVERTED, 7, 0, height + 54, session->TrackColours[SCHEME_SUPPORTS]);
231             break;
232         case 3:
233             metal_a_supports_paint_setup(
234                 session, METAL_SUPPORTS_TUBES_INVERTED, 5, 0, height + 54, session->TrackColours[SCHEME_SUPPORTS]);
235             break;
236     }
237 
238     if (direction == 0 || direction == 3)
239     {
240         paint_util_push_tunnel_rotated(session, direction, height, TUNNEL_INVERTED_3);
241     }
242     else
243     {
244         paint_util_push_tunnel_rotated(session, direction, height, TUNNEL_INVERTED_5);
245     }
246     paint_util_set_general_support_height(session, height + 64, 0x20);
247 }
248 
249 /** rct2: 0x008B04D0 */
inverted_impulse_rc_track_25_deg_up_to_60_deg_up(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)250 static void inverted_impulse_rc_track_25_deg_up_to_60_deg_up(
251     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
252     const TrackElement& trackElement)
253 {
254     switch (direction)
255     {
256         case 0:
257             PaintAddImageAsParentRotated(
258                 session, direction, session->TrackColours[SCHEME_TRACK] | 19676, 0, 0, 32, 20, 3, height + 29, 0, 6,
259                 height + 61);
260             break;
261         case 1:
262             PaintAddImageAsParentRotated(
263                 session, direction, session->TrackColours[SCHEME_TRACK] | 19680, 0, 0, 32, 10, 49, height + 29, 0, 10,
264                 height + 11);
265             PaintAddImageAsParentRotated(
266                 session, direction, session->TrackColours[SCHEME_TRACK] | 19677, 0, 0, 32, 2, 49, height + 29, 0, 4,
267                 height + 11);
268             break;
269         case 2:
270             PaintAddImageAsParentRotated(
271                 session, direction, session->TrackColours[SCHEME_TRACK] | 19681, 0, 0, 32, 10, 49, height + 29, 0, 10,
272                 height + 11);
273             PaintAddImageAsParentRotated(
274                 session, direction, session->TrackColours[SCHEME_TRACK] | 19678, 0, 0, 32, 2, 49, height + 29, 0, 4,
275                 height + 11);
276             break;
277         case 3:
278             PaintAddImageAsParentRotated(
279                 session, direction, session->TrackColours[SCHEME_TRACK] | 19679, 0, 0, 32, 20, 3, height + 29, 0, 6,
280                 height + 61);
281             break;
282     }
283     if (direction == 0 || direction == 3)
284     {
285         paint_util_push_tunnel_rotated(session, direction, height - 8, TUNNEL_INVERTED_4);
286     }
287     else
288     {
289         paint_util_push_tunnel_rotated(session, direction, height + 24, TUNNEL_INVERTED_5);
290     }
291     paint_util_set_segment_support_height(
292         session, paint_util_rotate_segments(SEGMENT_C4 | SEGMENT_CC | SEGMENT_D0, direction), 0xFFFF, 0);
293     paint_util_set_general_support_height(session, height + 88, 0x20);
294 }
295 
296 /** rct2: 0x008B04E0 */
inverted_impulse_rc_track_60_deg_up_to_25_deg_up(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)297 static void inverted_impulse_rc_track_60_deg_up_to_25_deg_up(
298     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
299     const TrackElement& trackElement)
300 {
301     switch (direction)
302     {
303         case 0:
304             PaintAddImageAsParentRotated(
305                 session, direction, session->TrackColours[SCHEME_TRACK] | 19682, 0, 0, 32, 20, 3, height + 29, 0, 6,
306                 height + 61);
307             break;
308         case 1:
309             PaintAddImageAsParentRotated(
310                 session, direction, session->TrackColours[SCHEME_TRACK] | 19686, 0, 0, 32, 10, 49, height + 29, 0, 10,
311                 height + 11);
312             PaintAddImageAsParentRotated(
313                 session, direction, session->TrackColours[SCHEME_TRACK] | 19683, 0, 0, 32, 2, 49, height + 29, 0, 4,
314                 height + 11);
315             break;
316         case 2:
317             PaintAddImageAsParentRotated(
318                 session, direction, session->TrackColours[SCHEME_TRACK] | 19687, 0, 0, 32, 10, 49, height + 29, 0, 10,
319                 height + 11);
320             PaintAddImageAsParentRotated(
321                 session, direction, session->TrackColours[SCHEME_TRACK] | 19684, 0, 0, 32, 2, 49, height + 29, 0, 4,
322                 height + 11);
323             break;
324         case 3:
325             PaintAddImageAsParentRotated(
326                 session, direction, session->TrackColours[SCHEME_TRACK] | 19685, 0, 0, 32, 20, 3, height + 29, 0, 6,
327                 height + 61);
328             break;
329     }
330     if (direction == 0 || direction == 3)
331     {
332         paint_util_push_tunnel_rotated(session, direction, height - 8, TUNNEL_INVERTED_4);
333     }
334     else
335     {
336         paint_util_push_tunnel_rotated(session, direction, height + 24, TUNNEL_INVERTED_5);
337     }
338     paint_util_set_segment_support_height(
339         session, paint_util_rotate_segments(SEGMENT_C4 | SEGMENT_CC | SEGMENT_D0, direction), 0xFFFF, 0);
340     paint_util_set_general_support_height(session, height + 88, 0x20);
341 }
342 
343 /** rct2: 0x008B04F0 */
inverted_impulse_rc_track_25_deg_up_to_flat(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)344 static void inverted_impulse_rc_track_25_deg_up_to_flat(
345     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
346     const TrackElement& trackElement)
347 {
348     switch (direction)
349     {
350         case 0:
351             PaintAddImageAsParentRotated(
352                 session, direction, session->TrackColours[SCHEME_TRACK] | 19668, 0, 0, 32, 20, 3, height + 29, 0, 6,
353                 height + 37);
354             break;
355         case 1:
356             PaintAddImageAsParentRotated(
357                 session, direction, session->TrackColours[SCHEME_TRACK] | 19669, 0, 0, 32, 20, 3, height + 29, 0, 6,
358                 height + 37);
359             break;
360         case 2:
361             PaintAddImageAsParentRotated(
362                 session, direction, session->TrackColours[SCHEME_TRACK] | 19670, 0, 0, 32, 20, 3, height + 29, 0, 6,
363                 height + 37);
364             break;
365         case 3:
366             PaintAddImageAsParentRotated(
367                 session, direction, session->TrackColours[SCHEME_TRACK] | 19671, 0, 0, 32, 20, 3, height + 29, 0, 6,
368                 height + 37);
369             break;
370     }
371 
372     paint_util_set_segment_support_height(
373         session, paint_util_rotate_segments(SEGMENT_C4 | SEGMENT_CC | SEGMENT_D0, direction), 0xFFFF, 0);
374     switch (direction)
375     {
376         case 0:
377             metal_a_supports_paint_setup(
378                 session, METAL_SUPPORTS_TUBES_INVERTED, 6, 0, height + 52, session->TrackColours[SCHEME_SUPPORTS]);
379             break;
380         case 1:
381             metal_a_supports_paint_setup(
382                 session, METAL_SUPPORTS_TUBES_INVERTED, 8, 0, height + 52, session->TrackColours[SCHEME_SUPPORTS]);
383             break;
384         case 2:
385             metal_a_supports_paint_setup(
386                 session, METAL_SUPPORTS_TUBES_INVERTED, 7, 0, height + 52, session->TrackColours[SCHEME_SUPPORTS]);
387             break;
388         case 3:
389             metal_a_supports_paint_setup(
390                 session, METAL_SUPPORTS_TUBES_INVERTED, 5, 0, height + 52, session->TrackColours[SCHEME_SUPPORTS]);
391             break;
392     }
393 
394     if (direction == 0 || direction == 3)
395     {
396         paint_util_push_tunnel_rotated(session, direction, height - 8, TUNNEL_INVERTED_3);
397     }
398     else
399     {
400         paint_util_push_tunnel_rotated(session, direction, height + 8, TUNNEL_13);
401     }
402     paint_util_set_general_support_height(session, height + 56, 0x20);
403 }
404 
405 /** rct2: 0x008B0500 */
inverted_impulse_rc_track_25_deg_down(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)406 static void inverted_impulse_rc_track_25_deg_down(
407     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
408     const TrackElement& trackElement)
409 {
410     inverted_impulse_rc_track_25_deg_up(session, ride, trackSequence, (direction + 2) & 3, height, trackElement);
411 }
412 
413 /** rct2: 0x008B0510 */
inverted_impulse_rc_track_60_deg_down(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)414 static void inverted_impulse_rc_track_60_deg_down(
415     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
416     const TrackElement& trackElement)
417 {
418     inverted_impulse_rc_track_60_deg_up(session, ride, trackSequence, (direction + 2) & 3, height, trackElement);
419 }
420 
421 /** rct2: 0x008B0520 */
inverted_impulse_rc_track_flat_to_25_deg_down(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)422 static void inverted_impulse_rc_track_flat_to_25_deg_down(
423     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
424     const TrackElement& trackElement)
425 {
426     inverted_impulse_rc_track_25_deg_up_to_flat(session, ride, trackSequence, (direction + 2) & 3, height, trackElement);
427 }
428 
429 /** rct2: 0x008B0530 */
inverted_impulse_rc_track_25_deg_down_to_60_deg_down(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)430 static void inverted_impulse_rc_track_25_deg_down_to_60_deg_down(
431     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
432     const TrackElement& trackElement)
433 {
434     inverted_impulse_rc_track_60_deg_up_to_25_deg_up(session, ride, trackSequence, (direction + 2) & 3, height, trackElement);
435 }
436 
437 /** rct2: 0x008B0540 */
inverted_impulse_rc_track_60_deg_down_to_25_deg_down(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)438 static void inverted_impulse_rc_track_60_deg_down_to_25_deg_down(
439     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
440     const TrackElement& trackElement)
441 {
442     inverted_impulse_rc_track_25_deg_up_to_60_deg_up(session, ride, trackSequence, (direction + 2) & 3, height, trackElement);
443 }
444 
445 /** rct2: 0x008B0550 */
inverted_impulse_rc_track_25_deg_down_to_flat(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)446 static void inverted_impulse_rc_track_25_deg_down_to_flat(
447     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
448     const TrackElement& trackElement)
449 {
450     inverted_impulse_rc_track_flat_to_25_deg_up(session, ride, trackSequence, (direction + 2) & 3, height, trackElement);
451 }
452 
453 /** rct2: 0x008B05A0 */
inverted_impulse_rc_track_90_deg_up(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)454 static void inverted_impulse_rc_track_90_deg_up(
455     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
456     const TrackElement& trackElement)
457 {
458     switch (trackSequence)
459     {
460         case 0:
461             switch (direction)
462             {
463                 case 0:
464                     PaintAddImageAsParentRotated(
465                         session, direction, session->TrackColours[SCHEME_TRACK] | 19700, 0, 0, 32, 20, 3, height + 29, 0, 6,
466                         height + 61);
467                     break;
468                 case 1:
469                     PaintAddImageAsParentRotated(
470                         session, direction, session->TrackColours[SCHEME_TRACK] | 19701, 0, 0, 32, 2, 31, height + 29, 0, 4,
471                         height + 11);
472                     break;
473                 case 2:
474                     PaintAddImageAsParentRotated(
475                         session, direction, session->TrackColours[SCHEME_TRACK] | 19702, 0, 0, 32, 2, 31, height + 29, 0, 4,
476                         height + 11);
477                     break;
478                 case 3:
479                     PaintAddImageAsParentRotated(
480                         session, direction, session->TrackColours[SCHEME_TRACK] | 19703, 0, 0, 32, 20, 3, height + 29, 0, 6,
481                         height + 61);
482                     break;
483             }
484             paint_util_set_vertical_tunnel(session, height + 32);
485             paint_util_set_segment_support_height(
486                 session, paint_util_rotate_segments(SEGMENT_C4 | SEGMENT_CC | SEGMENT_D0, direction), 0xFFFF, 0);
487             paint_util_set_general_support_height(session, height + 32, 0x20);
488             break;
489         case 1:
490             break;
491     }
492 }
493 
494 /** rct2: 0x008B05B0 */
inverted_impulse_rc_track_90_deg_down(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)495 static void inverted_impulse_rc_track_90_deg_down(
496     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
497     const TrackElement& trackElement)
498 {
499     inverted_impulse_rc_track_90_deg_up(session, ride, trackSequence, (direction + 2) & 3, height, trackElement);
500 }
501 
502 /** rct2: 0x008B0560 */
inverted_impulse_rc_track_60_deg_up_to_90_deg_up(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)503 static void inverted_impulse_rc_track_60_deg_up_to_90_deg_up(
504     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
505     const TrackElement& trackElement)
506 {
507     switch (trackSequence)
508     {
509         case 0:
510             switch (direction)
511             {
512                 case 0:
513                     PaintAddImageAsParentRotated(
514                         session, direction, session->TrackColours[SCHEME_TRACK] | 19692, 0, 0, 32, 20, 3, height + 29, 0, 6,
515                         height + 85);
516                     break;
517                 case 1:
518                     PaintAddImageAsParentRotated(
519                         session, direction, session->TrackColours[SCHEME_TRACK] | 19693, 0, 0, 32, 2, 55, height + 29, 0, 4,
520                         height + 11);
521                     break;
522                 case 2:
523                     PaintAddImageAsParentRotated(
524                         session, direction, session->TrackColours[SCHEME_TRACK] | 19694, 0, 0, 32, 2, 55, height + 29, 0, 4,
525                         height + 11);
526                     break;
527                 case 3:
528                     PaintAddImageAsParentRotated(
529                         session, direction, session->TrackColours[SCHEME_TRACK] | 19695, 0, 0, 32, 20, 3, height + 29, 0, 6,
530                         height + 85);
531                     break;
532             }
533             if (direction == 0 || direction == 3)
534             {
535                 paint_util_push_tunnel_rotated(session, direction, height - 8, TUNNEL_INVERTED_4);
536             }
537             paint_util_set_vertical_tunnel(session, height + 56);
538             paint_util_set_segment_support_height(
539                 session, paint_util_rotate_segments(SEGMENT_C4 | SEGMENT_CC | SEGMENT_D0, direction), 0xFFFF, 0);
540             paint_util_set_general_support_height(session, height + 72, 0x20);
541             break;
542         case 1:
543             break;
544     }
545 }
546 
547 /** rct2: 0x008B0570 */
inverted_impulse_rc_track_90_deg_down_to_60_deg_down(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)548 static void inverted_impulse_rc_track_90_deg_down_to_60_deg_down(
549     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
550     const TrackElement& trackElement)
551 {
552     inverted_impulse_rc_track_60_deg_up_to_90_deg_up(session, ride, trackSequence, (direction + 2) & 3, height, trackElement);
553 }
554 
555 /** rct2: 0x008B0580 */
inverted_impulse_rc_track_90_deg_up_to_60_deg_up(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)556 static void inverted_impulse_rc_track_90_deg_up_to_60_deg_up(
557     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
558     const TrackElement& trackElement)
559 {
560     switch (direction)
561     {
562         case 0:
563             PaintAddImageAsParentRotated(
564                 session, direction, session->TrackColours[SCHEME_TRACK] | 19696, 0, 0, 32, 20, 3, height + 29, 0, 6,
565                 height + 85);
566             break;
567         case 1:
568             PaintAddImageAsParentRotated(
569                 session, direction, session->TrackColours[SCHEME_TRACK] | 19697, 0, 0, 32, 2, 55, height + 29, 0, 4,
570                 height + 11);
571             break;
572         case 2:
573             PaintAddImageAsParentRotated(
574                 session, direction, session->TrackColours[SCHEME_TRACK] | 19698, 0, 0, 32, 2, 55, height + 29, 0, 4,
575                 height + 11);
576             break;
577         case 3:
578             PaintAddImageAsParentRotated(
579                 session, direction, session->TrackColours[SCHEME_TRACK] | 19699, 0, 0, 32, 20, 3, height + 29, 0, 6,
580                 height + 85);
581             break;
582     }
583     switch (direction)
584     {
585         case 1:
586             paint_util_push_tunnel_right(session, height + 48, TUNNEL_INVERTED_5);
587             break;
588         case 2:
589             paint_util_push_tunnel_left(session, height + 48, TUNNEL_INVERTED_5);
590             break;
591     }
592     paint_util_set_segment_support_height(
593         session, paint_util_rotate_segments(SEGMENT_C4 | SEGMENT_CC | SEGMENT_D0, direction), 0xFFFF, 0);
594     paint_util_set_general_support_height(session, height + 96, 0x20);
595 }
596 
597 /** rct2: 0x008B0590 */
inverted_impulse_rc_track_60_deg_down_to_90_deg_down(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)598 static void inverted_impulse_rc_track_60_deg_down_to_90_deg_down(
599     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
600     const TrackElement& trackElement)
601 {
602     switch (trackSequence)
603     {
604         case 0:
605             switch (direction)
606             {
607                 case 0:
608                     PaintAddImageAsParentRotated(
609                         session, direction, session->TrackColours[SCHEME_TRACK] | 19698, 0, 0, 32, 2, 55, height + 29, 0, 4,
610                         height + 11);
611                     break;
612                 case 1:
613                     PaintAddImageAsParentRotated(
614                         session, direction, session->TrackColours[SCHEME_TRACK] | 19699, 0, 0, 32, 20, 3, height + 29, 0, 6,
615                         height + 85);
616                     break;
617                 case 2:
618                     PaintAddImageAsParentRotated(
619                         session, direction, session->TrackColours[SCHEME_TRACK] | 19696, 0, 0, 32, 20, 3, height + 29, 0, 6,
620                         height + 85);
621                     break;
622                 case 3:
623                     PaintAddImageAsParentRotated(
624                         session, direction, session->TrackColours[SCHEME_TRACK] | 19697, 0, 0, 32, 2, 55, height + 29, 0, 4,
625                         height + 11);
626                     break;
627             }
628             if (direction == 0 || direction == 3)
629             {
630                 paint_util_push_tunnel_rotated(session, direction, height + 48, TUNNEL_INVERTED_5);
631             }
632             paint_util_set_segment_support_height(
633                 session, paint_util_rotate_segments(SEGMENT_C4 | SEGMENT_CC | SEGMENT_D0, direction), 0xFFFF, 0);
634             paint_util_set_general_support_height(session, height + 96, 0x20);
635             break;
636         case 1:
637             break;
638     }
639 }
640 
641 /** rct2: 0x008B05C0 */
inverted_impulse_rc_track_left_quarter_turn_1_90_deg_up(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)642 static void inverted_impulse_rc_track_left_quarter_turn_1_90_deg_up(
643     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
644     const TrackElement& trackElement)
645 {
646     switch (trackSequence)
647     {
648         case 0:
649             switch (direction)
650             {
651                 case 0:
652                     PaintAddImageAsParentRotated(
653                         session, direction, session->TrackColours[SCHEME_TRACK] | 19708, 0, 0, 32, 20, 3, height + 29, 0, 6,
654                         height + 125);
655                     break;
656                 case 1:
657                     PaintAddImageAsParentRotated(
658                         session, direction, session->TrackColours[SCHEME_TRACK] | 19709, 0, 0, 32, 20, 3, height + 29, 0, 6,
659                         height + 125);
660                     PaintAddImageAsParentRotated(
661                         session, direction, session->TrackColours[SCHEME_TRACK] | 19717, 0, 0, 2, 32, 31, height + 29, 4, 0,
662                         height + 11);
663                     break;
664                 case 2:
665                     PaintAddImageAsParentRotated(
666                         session, direction, session->TrackColours[SCHEME_TRACK] | 19710, 0, 0, 32, 20, 3, height + 29, 0, 6,
667                         height + 125);
668                     PaintAddImageAsParentRotated(
669                         session, direction, session->TrackColours[SCHEME_TRACK] | 19718, 0, 0, 32, 2, 31, height + 29, 0, 4,
670                         height + 11);
671                     break;
672                 case 3:
673                     PaintAddImageAsParentRotated(
674                         session, direction, session->TrackColours[SCHEME_TRACK] | 19711, 0, 0, 32, 20, 3, height + 29, 0, 6,
675                         height + 125);
676                     PaintAddImageAsParentRotated(
677                         session, direction, session->TrackColours[SCHEME_TRACK] | 19719, 0, 0, 32, 2, 31, height + 29, 0, 4,
678                         height + 11);
679                     break;
680             }
681             paint_util_set_vertical_tunnel(session, height + 96);
682             paint_util_set_segment_support_height(
683                 session, paint_util_rotate_segments(SEGMENT_C4 | SEGMENT_CC | SEGMENT_D0, direction), 0xFFFF, 0);
684             paint_util_set_general_support_height(session, height + 96, 0x20);
685             break;
686         case 1:
687             break;
688     }
689 }
690 
691 /** rct2: 0x008B05D0 */
inverted_impulse_rc_track_right_quarter_turn_1_90_deg_up(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)692 static void inverted_impulse_rc_track_right_quarter_turn_1_90_deg_up(
693     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
694     const TrackElement& trackElement)
695 {
696     switch (trackSequence)
697     {
698         case 0:
699             switch (direction)
700             {
701                 case 0:
702                     PaintAddImageAsParentRotated(
703                         session, direction, session->TrackColours[SCHEME_TRACK] | 19704, 0, 0, 32, 20, 3, height + 29, 0, 6,
704                         height + 125);
705                     PaintAddImageAsParentRotated(
706                         session, direction, session->TrackColours[SCHEME_TRACK] | 19712, 0, 0, 32, 2, 31, height + 29, 0, 4,
707                         height + 11);
708                     break;
709                 case 1:
710                     PaintAddImageAsParentRotated(
711                         session, direction, session->TrackColours[SCHEME_TRACK] | 19705, 0, 0, 32, 20, 3, height + 29, 0, 6,
712                         height + 125);
713                     PaintAddImageAsParentRotated(
714                         session, direction, session->TrackColours[SCHEME_TRACK] | 19713, 0, 0, 32, 2, 31, height + 29, 0, 4,
715                         height + 11);
716                     break;
717                 case 2:
718                     PaintAddImageAsParentRotated(
719                         session, direction, session->TrackColours[SCHEME_TRACK] | 19706, 0, 0, 32, 20, 3, height + 29, 0, 6,
720                         height + 125);
721                     PaintAddImageAsParentRotated(
722                         session, direction, session->TrackColours[SCHEME_TRACK] | 19714, 0, 0, 32, 2, 31, height + 29, 0, 4,
723                         height + 11);
724                     break;
725                 case 3:
726                     PaintAddImageAsParentRotated(
727                         session, direction, session->TrackColours[SCHEME_TRACK] | 19707, 0, 0, 32, 20, 3, height + 29, 0, 6,
728                         height + 125);
729                     break;
730             }
731             paint_util_set_vertical_tunnel(session, height + 96);
732             paint_util_set_segment_support_height(
733                 session, paint_util_rotate_segments(SEGMENT_C4 | SEGMENT_CC | SEGMENT_D0, direction), 0xFFFF, 0);
734             paint_util_set_general_support_height(session, height + 96, 0x20);
735             break;
736         case 1:
737             break;
738     }
739 }
740 
741 /** rct2: 0x008B05E0 */
inverted_impulse_rc_track_left_quarter_turn_1_90_deg_down(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)742 static void inverted_impulse_rc_track_left_quarter_turn_1_90_deg_down(
743     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
744     const TrackElement& trackElement)
745 {
746     inverted_impulse_rc_track_right_quarter_turn_1_90_deg_up(
747         session, ride, trackSequence, (direction + 1) & 3, height, trackElement);
748 }
749 
750 /** rct2: 0x008B05F0 */
inverted_impulse_rc_track_right_quarter_turn_1_90_deg_down(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)751 static void inverted_impulse_rc_track_right_quarter_turn_1_90_deg_down(
752     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
753     const TrackElement& trackElement)
754 {
755     inverted_impulse_rc_track_left_quarter_turn_1_90_deg_up(
756         session, ride, trackSequence, (direction - 1) & 3, height, trackElement);
757 }
758 
get_track_paint_function_inverted_impulse_rc(int32_t trackType)759 TRACK_PAINT_FUNCTION get_track_paint_function_inverted_impulse_rc(int32_t trackType)
760 {
761     switch (trackType)
762     {
763         case TrackElemType::Flat:
764             return inverted_impulse_rc_track_flat;
765         case TrackElemType::EndStation:
766         case TrackElemType::BeginStation:
767         case TrackElemType::MiddleStation:
768             return inverted_impulse_rc_track_station;
769         case TrackElemType::Up25:
770             return inverted_impulse_rc_track_25_deg_up;
771         case TrackElemType::Up60:
772             return inverted_impulse_rc_track_60_deg_up;
773         case TrackElemType::FlatToUp25:
774             return inverted_impulse_rc_track_flat_to_25_deg_up;
775         case TrackElemType::Up25ToUp60:
776             return inverted_impulse_rc_track_25_deg_up_to_60_deg_up;
777         case TrackElemType::Up60ToUp25:
778             return inverted_impulse_rc_track_60_deg_up_to_25_deg_up;
779         case TrackElemType::Up25ToFlat:
780             return inverted_impulse_rc_track_25_deg_up_to_flat;
781         case TrackElemType::Down25:
782             return inverted_impulse_rc_track_25_deg_down;
783         case TrackElemType::Down60:
784             return inverted_impulse_rc_track_60_deg_down;
785         case TrackElemType::FlatToDown25:
786             return inverted_impulse_rc_track_flat_to_25_deg_down;
787         case TrackElemType::Down25ToDown60:
788             return inverted_impulse_rc_track_25_deg_down_to_60_deg_down;
789         case TrackElemType::Down60ToDown25:
790             return inverted_impulse_rc_track_60_deg_down_to_25_deg_down;
791         case TrackElemType::Down25ToFlat:
792             return inverted_impulse_rc_track_25_deg_down_to_flat;
793         case TrackElemType::Up90:
794             return inverted_impulse_rc_track_90_deg_up;
795         case TrackElemType::Down90:
796             return inverted_impulse_rc_track_90_deg_down;
797         case TrackElemType::Up60ToUp90:
798             return inverted_impulse_rc_track_60_deg_up_to_90_deg_up;
799         case TrackElemType::Down90ToDown60:
800             return inverted_impulse_rc_track_90_deg_down_to_60_deg_down;
801         case TrackElemType::Up90ToUp60:
802             return inverted_impulse_rc_track_90_deg_up_to_60_deg_up;
803         case TrackElemType::Down60ToDown90:
804             return inverted_impulse_rc_track_60_deg_down_to_90_deg_down;
805         case TrackElemType::LeftQuarterTurn1TileUp90:
806             return inverted_impulse_rc_track_left_quarter_turn_1_90_deg_up;
807         case TrackElemType::RightQuarterTurn1TileUp90:
808             return inverted_impulse_rc_track_right_quarter_turn_1_90_deg_up;
809         case TrackElemType::LeftQuarterTurn1TileDown90:
810             return inverted_impulse_rc_track_left_quarter_turn_1_90_deg_down;
811         case TrackElemType::RightQuarterTurn1TileDown90:
812             return inverted_impulse_rc_track_right_quarter_turn_1_90_deg_down;
813     }
814     return nullptr;
815 }
816