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 enum
22 {
23     SPR_WOODEN_WILD_MOUSE_FLAT_SW_NE = 28535,
24     SPR_WOODEN_WILD_MOUSE_FLAT_NW_SE = 28536,
25     SPR_WOODEN_WILD_MOUSE_25_DEG_SW_NE = 28537,
26     SPR_WOODEN_WILD_MOUSE_60_DEG_SW_NE = 28538,
27     SPR_WOODEN_WILD_MOUSE_FLAT_TO_25_DEG_SW_NE = 28539,
28     SPR_WOODEN_WILD_MOUSE_25_DEG_TO_60_DEG_SW_NE = 28540,
29     SPR_WOODEN_WILD_MOUSE_25_DEG_NE_SW = 28541,
30     SPR_WOODEN_WILD_MOUSE_60_DEG_NE_SW = 28542,
31     SPR_WOODEN_WILD_MOUSE_FLAT_TO_25_DEG_NE_SW = 28543,
32     SPR_WOODEN_WILD_MOUSE_25_DEG_TO_60_DEG_FRONT_NE_SW = 28544,
33     SPR_WOODEN_WILD_MOUSE_25_DEG_TO_FLAT_NE_SW = 28545,
34     SPR_WOODEN_WILD_MOUSE_60_DEG_TO_25_DEG_FRONT_NE_SW = 28546,
35     SPR_WOODEN_WILD_MOUSE_25_DEG_TO_FLAT_SW_NE = 28547,
36     SPR_WOODEN_WILD_MOUSE_60_DEG_TO_25_DEG_SW_NE = 28548,
37     SPR_WOODEN_WILD_MOUSE_25_DEG_NW_SE = 28549,
38     SPR_WOODEN_WILD_MOUSE_60_DEG_NW_SE = 28550,
39     SPR_WOODEN_WILD_MOUSE_25_DEG_SE_NW = 28551,
40     SPR_WOODEN_WILD_MOUSE_60_DEG_SE_NW = 28552,
41     SPR_WOODEN_WILD_MOUSE_FLAT_TO_25_DEG_NW_SE = 28553,
42     SPR_WOODEN_WILD_MOUSE_25_DEG_TO_60_DEG_FRONT_NW_SE = 28554,
43     SPR_WOODEN_WILD_MOUSE_FLAT_TO_25_DEG_SE_NW = 28555,
44     SPR_WOODEN_WILD_MOUSE_25_DEG_TO_60_DEG_SE_NW = 28556,
45     SPR_WOODEN_WILD_MOUSE_25_DEG_TO_FLAT_SE_NW = 28557,
46     SPR_WOODEN_WILD_MOUSE_60_DEG_TO_25_DEG_SE_NW = 28558,
47     SPR_WOODEN_WILD_MOUSE_25_DEG_TO_FLAT_NW_SE = 28559,
48     SPR_WOODEN_WILD_MOUSE_60_DEG_TO_25_DEG_FRONT_NW_SE = 28560,
49     SPR_WOODEN_WILD_MOUSE_25_DEG_TO_60_DEG_NE_SW = 28561,
50     SPR_WOODEN_WILD_MOUSE_60_DEG_TO_25_DEG_NE_SW = 28562,
51     SPR_WOODEN_WILD_MOUSE_25_DEG_TO_60_DEG_NW_SE = 28563,
52     SPR_WOODEN_WILD_MOUSE_60_DEG_TO_25_DEG_NW_SE = 28564,
53     SPR_WOODEN_WILD_MOUSE_FLAT_TO_60_DEG_SW_NE = 28565,
54     SPR_WOODEN_WILD_MOUSE_FLAT_TO_60_DEG_NW_SE = 28566,
55     SPR_WOODEN_WILD_MOUSE_FLAT_TO_60_DEG_NE_SW = 28567,
56     SPR_WOODEN_WILD_MOUSE_FLAT_TO_60_DEG_SE_NW = 28568,
57     SPR_WOODEN_WILD_MOUSE_FLAT_TO_60_DEG_FRONT_NW_SE = 28569,
58     SPR_WOODEN_WILD_MOUSE_FLAT_TO_60_DEG_FRONT_NE_SW = 28570,
59     SPR_WOODEN_WILD_MOUSE_60_DEG_TO_FLAT_SW_NE = 28571,
60     SPR_WOODEN_WILD_MOUSE_60_DEG_TO_FLAT_NW_SE = 28572,
61     SPR_WOODEN_WILD_MOUSE_60_DEG_TO_FLAT_NE_SW = 28573,
62     SPR_WOODEN_WILD_MOUSE_60_DEG_TO_FLAT_SE_NW = 28574,
63     SPR_WOODEN_WILD_MOUSE_60_DEG_TO_FLAT_FRONT_NW_SE = 28575,
64     SPR_WOODEN_WILD_MOUSE_60_DEG_TO_FLAT_FRONT_NE_SW = 28576,
65     SPR_WOODEN_WILD_MOUSE_25_DEG_CHAIN_SW_NE = 28577,
66     SPR_WOODEN_WILD_MOUSE_60_DEG_CHAIN_SW_NE = 28578,
67     SPR_WOODEN_WILD_MOUSE_FLAT_TO_25_DEG_CHAIN_SW_NE = 28579,
68     SPR_WOODEN_WILD_MOUSE_25_DEG_TO_60_DEG_CHAIN_SW_NE = 28580,
69     SPR_WOODEN_WILD_MOUSE_25_DEG_CHAIN_NE_SW = 28581,
70     SPR_WOODEN_WILD_MOUSE_60_DEG_CHAIN_NE_SW = 28582,
71     SPR_WOODEN_WILD_MOUSE_FLAT_TO_25_DEG_CHAIN_NE_SW = 28583,
72     SPR_WOODEN_WILD_MOUSE_25_DEG_TO_60_DEG_CHAIN_FRONT_NE_SW = 28584,
73     SPR_WOODEN_WILD_MOUSE_25_DEG_TO_FLAT_CHAIN_NE_SW = 28585,
74     SPR_WOODEN_WILD_MOUSE_60_DEG_TO_25_DEG_CHAIN_FRONT_NE_SW = 28586,
75     SPR_WOODEN_WILD_MOUSE_25_DEG_TO_FLAT_CHAIN_SW_NE = 28587,
76     SPR_WOODEN_WILD_MOUSE_60_DEG_TO_25_DEG_CHAIN_SW_NE = 28588,
77     SPR_WOODEN_WILD_MOUSE_25_DEG_CHAIN_NW_SE = 28589,
78     SPR_WOODEN_WILD_MOUSE_60_DEG_CHAIN_NW_SE = 28590,
79     SPR_WOODEN_WILD_MOUSE_25_DEG_CHAIN_SE_NW = 28591,
80     SPR_WOODEN_WILD_MOUSE_60_DEG_CHAIN_SE_NW = 28592,
81     SPR_WOODEN_WILD_MOUSE_FLAT_TO_25_DEG_CHAIN_NW_SE = 28593,
82     SPR_WOODEN_WILD_MOUSE_25_DEG_TO_60_DEG_CHAIN_FRONT_NW_SE = 28594,
83     SPR_WOODEN_WILD_MOUSE_FLAT_TO_25_DEG_CHAIN_SE_NW = 28595,
84     SPR_WOODEN_WILD_MOUSE_25_DEG_TO_60_DEG_CHAIN_SE_NW = 28596,
85     SPR_WOODEN_WILD_MOUSE_25_DEG_TO_FLAT_CHAIN_SE_NW = 28597,
86     SPR_WOODEN_WILD_MOUSE_60_DEG_TO_25_DEG_CHAIN_SE_NW = 28598,
87     SPR_WOODEN_WILD_MOUSE_25_DEG_TO_FLAT_CHAIN_NW_SE = 28599,
88     SPR_WOODEN_WILD_MOUSE_60_DEG_TO_25_DEG_CHAIN_FRONT_NW_SE = 28600,
89     SPR_WOODEN_WILD_MOUSE_25_DEG_TO_60_DEG_CHAIN_NE_SW = 28601,
90     SPR_WOODEN_WILD_MOUSE_60_DEG_TO_25_DEG_CHAIN_NE_SW = 28602,
91     SPR_WOODEN_WILD_MOUSE_25_DEG_TO_60_DEG_CHAIN_NW_SE = 28603,
92     SPR_WOODEN_WILD_MOUSE_60_DEG_TO_25_DEG_CHAIN_NW_SE = 28604,
93     SPR_WOODEN_WILD_MOUSE_FLAT_TO_60_DEG_CHAIN_SW_NE = 28605,
94     SPR_WOODEN_WILD_MOUSE_FLAT_TO_60_DEG_CHAIN_NW_SE = 28606,
95     SPR_WOODEN_WILD_MOUSE_FLAT_TO_60_DEG_CHAIN_NE_SW = 28607,
96     SPR_WOODEN_WILD_MOUSE_FLAT_TO_60_DEG_CHAIN_SE_NW = 28608,
97     SPR_WOODEN_WILD_MOUSE_FLAT_TO_60_DEG_CHAIN_FRONT_NW_SE = 28609,
98     SPR_WOODEN_WILD_MOUSE_FLAT_TO_60_DEG_CHAIN_FRONT_NE_SW = 28610,
99     SPR_WOODEN_WILD_MOUSE_60_DEG_TO_FLAT_CHAIN_SW_NE = 28611,
100     SPR_WOODEN_WILD_MOUSE_60_DEG_TO_FLAT_CHAIN_NW_SE = 28612,
101     SPR_WOODEN_WILD_MOUSE_60_DEG_TO_FLAT_CHAIN_NE_SW = 28613,
102     SPR_WOODEN_WILD_MOUSE_60_DEG_TO_FLAT_CHAIN_SE_NW = 28614,
103     SPR_WOODEN_WILD_MOUSE_60_DEG_TO_FLAT_CHAIN_FRONT_NW_SE = 28615,
104     SPR_WOODEN_WILD_MOUSE_60_DEG_TO_FLAT_CHAIN_FRONT_NE_SW = 28616,
105     SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_1_SW_NE = 28617,
106     SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_1_NW_SE = 28618,
107     SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_1_NE_SW = 28619,
108     SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_1_SE_NW = 28620,
109     SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_3_SW_SE_PART_0 = 28621,
110     SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_3_SW_SE_PART_1 = 28622,
111     SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_3_SW_SE_PART_2 = 28623,
112     SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_3_NW_SW_PART_0 = 28624,
113     SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_3_NW_SW_PART_1 = 28625,
114     SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_3_NW_SW_PART_2 = 28626,
115     SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_3_NE_NW_PART_0 = 28627,
116     SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_3_NE_NW_PART_1 = 28628,
117     SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_3_NE_NW_PART_2 = 28629,
118     SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_3_SE_NE_PART_0 = 28630,
119     SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_3_SE_NE_PART_1 = 28631,
120     SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_3_SE_NE_PART_2 = 28632,
121 };
122 
123 /** rct2: 0x008A5464 */
wooden_wild_mouse_track_flat(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)124 static void wooden_wild_mouse_track_flat(
125     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
126     const TrackElement& trackElement)
127 {
128     static constexpr const uint32_t imageIds[4] = {
129         SPR_WOODEN_WILD_MOUSE_FLAT_SW_NE,
130         SPR_WOODEN_WILD_MOUSE_FLAT_NW_SE,
131         SPR_WOODEN_WILD_MOUSE_FLAT_SW_NE,
132         SPR_WOODEN_WILD_MOUSE_FLAT_NW_SE,
133     };
134 
135     uint32_t imageId = imageIds[direction] | session->TrackColours[SCHEME_TRACK];
136     PaintAddImageAsParentRotated(session, direction, imageId, 0, 6, 32, 20, 1, height);
137     wooden_a_supports_paint_setup(session, direction & 1, 0, height, session->TrackColours[SCHEME_SUPPORTS]);
138     paint_util_push_tunnel_rotated(session, direction, height, TUNNEL_0);
139     paint_util_set_segment_support_height(
140         session,
141         paint_util_rotate_segments(SEGMENT_B4 | SEGMENT_B8 | SEGMENT_BC | SEGMENT_C0 | SEGMENT_C8 | SEGMENT_D4, direction),
142         height, 0x20);
143     paint_util_set_segment_support_height(
144         session, paint_util_rotate_segments(SEGMENT_C4 | SEGMENT_CC | SEGMENT_D0, direction), 0xFFFF, 0);
145     paint_util_set_general_support_height(session, height + 32, 0x20);
146 }
147 
wooden_wild_mouse_track_station(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)148 static void wooden_wild_mouse_track_station(
149     paint_session* session, const Ride* ride, [[maybe_unused]] uint8_t trackSequence, uint8_t direction, int32_t height,
150     const TrackElement& trackElement)
151 {
152     static constexpr const uint32_t imageIds[4][2] = {
153         { SPR_WOODEN_WILD_MOUSE_FLAT_SW_NE, SPR_STATION_BASE_B_SW_NE },
154         { SPR_WOODEN_WILD_MOUSE_FLAT_NW_SE, SPR_STATION_BASE_B_NW_SE },
155         { SPR_WOODEN_WILD_MOUSE_FLAT_SW_NE, SPR_STATION_BASE_B_SW_NE },
156         { SPR_WOODEN_WILD_MOUSE_FLAT_NW_SE, SPR_STATION_BASE_B_NW_SE },
157     };
158 
159     PaintAddImageAsParentRotated(
160         session, direction, imageIds[direction][1] | session->TrackColours[SCHEME_MISC], 0, 0, 32, 28, 1, height - 2, 0, 2,
161         height);
162     PaintAddImageAsChildRotated(
163         session, direction, imageIds[direction][0] | session->TrackColours[SCHEME_TRACK], 0, 6, 32, 20, 1, height, 0, 0,
164         height);
165     wooden_a_supports_paint_setup(session, direction & 1, 0, height, session->TrackColours[SCHEME_SUPPORTS]);
166     track_paint_util_draw_station(session, ride, direction, height, trackElement);
167     paint_util_push_tunnel_rotated(session, direction, height, TUNNEL_SQUARE_FLAT);
168     paint_util_set_segment_support_height(session, SEGMENTS_ALL, 0xFFFF, 0);
169     paint_util_set_general_support_height(session, height + 32, 0x20);
170 }
171 
172 /** rct2: 0x008A5474 */
wooden_wild_mouse_track_25_deg_up(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)173 static void wooden_wild_mouse_track_25_deg_up(
174     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
175     const TrackElement& trackElement)
176 {
177     static constexpr const uint32_t imageIds[2][4] = {
178         {
179             SPR_WOODEN_WILD_MOUSE_25_DEG_SW_NE,
180             SPR_WOODEN_WILD_MOUSE_25_DEG_NW_SE,
181             SPR_WOODEN_WILD_MOUSE_25_DEG_NE_SW,
182             SPR_WOODEN_WILD_MOUSE_25_DEG_SE_NW,
183         },
184         {
185             SPR_WOODEN_WILD_MOUSE_25_DEG_CHAIN_SW_NE,
186             SPR_WOODEN_WILD_MOUSE_25_DEG_CHAIN_NW_SE,
187             SPR_WOODEN_WILD_MOUSE_25_DEG_CHAIN_NE_SW,
188             SPR_WOODEN_WILD_MOUSE_25_DEG_CHAIN_SE_NW,
189         },
190     };
191 
192     uint8_t isChained = trackElement.HasChain() ? 1 : 0;
193     uint32_t imageId = imageIds[isChained][direction] | session->TrackColours[SCHEME_TRACK];
194     PaintAddImageAsParentRotated(session, direction, imageId, 0, 2, 32, 25, 1, height, 0, 3, height);
195 
196     wooden_a_supports_paint_setup(session, direction & 1, 9 + direction, height, session->TrackColours[SCHEME_SUPPORTS]);
197 
198     if (direction == 0 || direction == 3)
199     {
200         paint_util_push_tunnel_rotated(session, direction, height - 8, TUNNEL_1);
201     }
202     else
203     {
204         paint_util_push_tunnel_rotated(session, direction, height + 8, TUNNEL_2);
205     }
206 
207     paint_util_set_segment_support_height(session, SEGMENTS_ALL, 0xFFFF, 0);
208     paint_util_set_general_support_height(session, height + 56, 0x20);
209 }
210 
211 /** rct2: 0x008A5484 */
wooden_wild_mouse_track_60_deg_up(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)212 static void wooden_wild_mouse_track_60_deg_up(
213     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
214     const TrackElement& trackElement)
215 {
216     static constexpr const uint32_t imageIds[2][4] = {
217         {
218             SPR_WOODEN_WILD_MOUSE_60_DEG_SW_NE,
219             SPR_WOODEN_WILD_MOUSE_60_DEG_NW_SE,
220             SPR_WOODEN_WILD_MOUSE_60_DEG_NE_SW,
221             SPR_WOODEN_WILD_MOUSE_60_DEG_SE_NW,
222         },
223         {
224             SPR_WOODEN_WILD_MOUSE_60_DEG_CHAIN_SW_NE,
225             SPR_WOODEN_WILD_MOUSE_60_DEG_CHAIN_NW_SE,
226             SPR_WOODEN_WILD_MOUSE_60_DEG_CHAIN_NE_SW,
227             SPR_WOODEN_WILD_MOUSE_60_DEG_CHAIN_SE_NW,
228         },
229     };
230 
231     uint8_t isChained = trackElement.HasChain() ? 1 : 0;
232     uint32_t imageId = imageIds[isChained][direction] | session->TrackColours[SCHEME_TRACK];
233     if (direction == 0 || direction == 3)
234     {
235         PaintAddImageAsParentRotated(session, direction, imageId, 0, 2, 32, 25, 1, height, 0, 3, height);
236     }
237     else
238     {
239         session->WoodenSupportsPrependTo = PaintAddImageAsParentRotated(
240             session, direction, imageId, 0, 6, 2, 24, 93, height, 28, 4, height - 16);
241     }
242 
243     wooden_a_supports_paint_setup(session, direction & 1, 21 + direction, height, session->TrackColours[SCHEME_SUPPORTS]);
244 
245     if (direction == 0 || direction == 3)
246     {
247         paint_util_push_tunnel_rotated(session, direction, height - 8, TUNNEL_1);
248     }
249     else
250     {
251         paint_util_push_tunnel_rotated(session, direction, height + 56, TUNNEL_2);
252     }
253 
254     paint_util_set_segment_support_height(session, SEGMENTS_ALL, 0xFFFF, 0);
255     paint_util_set_general_support_height(session, height + 104, 0x20);
256 }
257 
258 /** rct2: 0x008A5494 */
wooden_wild_mouse_track_flat_to_25_deg_up(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)259 static void wooden_wild_mouse_track_flat_to_25_deg_up(
260     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
261     const TrackElement& trackElement)
262 {
263     static constexpr const uint32_t imageIds[2][4] = {
264         {
265             SPR_WOODEN_WILD_MOUSE_FLAT_TO_25_DEG_SW_NE,
266             SPR_WOODEN_WILD_MOUSE_FLAT_TO_25_DEG_NW_SE,
267             SPR_WOODEN_WILD_MOUSE_FLAT_TO_25_DEG_NE_SW,
268             SPR_WOODEN_WILD_MOUSE_FLAT_TO_25_DEG_SE_NW,
269         },
270         {
271             SPR_WOODEN_WILD_MOUSE_FLAT_TO_25_DEG_CHAIN_SW_NE,
272             SPR_WOODEN_WILD_MOUSE_FLAT_TO_25_DEG_CHAIN_NW_SE,
273             SPR_WOODEN_WILD_MOUSE_FLAT_TO_25_DEG_CHAIN_NE_SW,
274             SPR_WOODEN_WILD_MOUSE_FLAT_TO_25_DEG_CHAIN_SE_NW,
275         },
276     };
277 
278     uint8_t isChained = trackElement.HasChain() ? 1 : 0;
279     uint32_t imageId = imageIds[isChained][direction] | session->TrackColours[SCHEME_TRACK];
280     PaintAddImageAsParentRotated(session, direction, imageId, 0, 2, 32, 25, 1, height, 0, 3, height);
281 
282     wooden_a_supports_paint_setup(session, direction & 1, 1 + direction, height, session->TrackColours[SCHEME_SUPPORTS]);
283 
284     if (direction == 0 || direction == 3)
285     {
286         paint_util_push_tunnel_rotated(session, direction, height, TUNNEL_0);
287     }
288     else
289     {
290         paint_util_push_tunnel_rotated(session, direction, height, TUNNEL_2);
291     }
292 
293     paint_util_set_segment_support_height(session, SEGMENTS_ALL, 0xFFFF, 0);
294     paint_util_set_general_support_height(session, height + 48, 0x20);
295 }
296 
297 /** rct2: 0x008A54A4 */
wooden_wild_mouse_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)298 static void wooden_wild_mouse_track_25_deg_up_to_60_deg_up(
299     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
300     const TrackElement& trackElement)
301 {
302     static constexpr const uint32_t imageIds[2][4][2] = {
303         {
304             { SPR_WOODEN_WILD_MOUSE_25_DEG_TO_60_DEG_SW_NE, 0 },
305             { SPR_WOODEN_WILD_MOUSE_25_DEG_TO_60_DEG_NW_SE, SPR_WOODEN_WILD_MOUSE_25_DEG_TO_60_DEG_FRONT_NW_SE },
306             { SPR_WOODEN_WILD_MOUSE_25_DEG_TO_60_DEG_NE_SW, SPR_WOODEN_WILD_MOUSE_25_DEG_TO_60_DEG_FRONT_NE_SW },
307             { SPR_WOODEN_WILD_MOUSE_25_DEG_TO_60_DEG_SE_NW, 0 },
308         },
309         {
310             { SPR_WOODEN_WILD_MOUSE_25_DEG_TO_60_DEG_CHAIN_SW_NE, 0 },
311             { SPR_WOODEN_WILD_MOUSE_25_DEG_TO_60_DEG_CHAIN_NW_SE, SPR_WOODEN_WILD_MOUSE_25_DEG_TO_60_DEG_CHAIN_FRONT_NW_SE },
312             { SPR_WOODEN_WILD_MOUSE_25_DEG_TO_60_DEG_CHAIN_NE_SW, SPR_WOODEN_WILD_MOUSE_25_DEG_TO_60_DEG_CHAIN_FRONT_NE_SW },
313             { SPR_WOODEN_WILD_MOUSE_25_DEG_TO_60_DEG_CHAIN_SE_NW, 0 },
314         },
315     };
316 
317     uint8_t isChained = trackElement.HasChain() ? 1 : 0;
318     uint32_t imageId;
319     if (direction == 0 || direction == 3)
320     {
321         imageId = imageIds[isChained][direction][0] | session->TrackColours[SCHEME_TRACK];
322         PaintAddImageAsParentRotated(session, direction, imageId, 0, 2, 32, 25, 1, height, 0, 3, height);
323     }
324     else
325     {
326         imageId = imageIds[isChained][direction][0] | session->TrackColours[SCHEME_TRACK];
327         session->WoodenSupportsPrependTo = PaintAddImageAsParentRotated(
328             session, direction, imageId, 0, 6, 2, 24, 43, height, 28, 4, height + 2);
329         imageId = imageIds[isChained][direction][1] | session->TrackColours[SCHEME_TRACK];
330         PaintAddImageAsParentRotated(session, direction, imageId, 0, 6, 32, 2, 43, height, 0, 4, height);
331     }
332 
333     wooden_a_supports_paint_setup(session, direction & 1, 13 + direction, height, session->TrackColours[SCHEME_SUPPORTS]);
334 
335     if (direction == 0 || direction == 3)
336     {
337         paint_util_push_tunnel_rotated(session, direction, height - 8, TUNNEL_1);
338     }
339     else
340     {
341         paint_util_push_tunnel_rotated(session, direction, height + 24, TUNNEL_2);
342     }
343 
344     paint_util_set_segment_support_height(session, SEGMENTS_ALL, 0xFFFF, 0);
345     paint_util_set_general_support_height(session, height + 72, 0x20);
346 }
347 
wooden_wild_mouse_track_60_deg_to_25_deg_up(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)348 static void wooden_wild_mouse_track_60_deg_to_25_deg_up(
349     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
350     const TrackElement& trackElement)
351 {
352     static constexpr const uint32_t imageIds[2][4][2] = {
353         {
354             { SPR_WOODEN_WILD_MOUSE_60_DEG_TO_25_DEG_SW_NE, 0 },
355             { SPR_WOODEN_WILD_MOUSE_60_DEG_TO_25_DEG_NW_SE, SPR_WOODEN_WILD_MOUSE_60_DEG_TO_25_DEG_FRONT_NW_SE },
356             { SPR_WOODEN_WILD_MOUSE_60_DEG_TO_25_DEG_NE_SW, SPR_WOODEN_WILD_MOUSE_60_DEG_TO_25_DEG_FRONT_NE_SW },
357             { SPR_WOODEN_WILD_MOUSE_60_DEG_TO_25_DEG_SE_NW, 0 },
358         },
359         {
360             { SPR_WOODEN_WILD_MOUSE_60_DEG_TO_25_DEG_CHAIN_SW_NE, 0 },
361             { SPR_WOODEN_WILD_MOUSE_60_DEG_TO_25_DEG_CHAIN_NW_SE, SPR_WOODEN_WILD_MOUSE_60_DEG_TO_25_DEG_CHAIN_FRONT_NW_SE },
362             { SPR_WOODEN_WILD_MOUSE_60_DEG_TO_25_DEG_CHAIN_NE_SW, SPR_WOODEN_WILD_MOUSE_60_DEG_TO_25_DEG_CHAIN_FRONT_NE_SW },
363             { SPR_WOODEN_WILD_MOUSE_60_DEG_TO_25_DEG_CHAIN_SE_NW, 0 },
364         },
365     };
366 
367     uint8_t isChained = trackElement.HasChain() ? 1 : 0;
368     uint32_t imageId;
369     if (direction == 0 || direction == 3)
370     {
371         imageId = imageIds[isChained][direction][0] | session->TrackColours[SCHEME_TRACK];
372         PaintAddImageAsParentRotated(session, direction, imageId, 0, 2, 32, 25, 1, height, 0, 3, height);
373     }
374     else
375     {
376         imageId = imageIds[isChained][direction][0] | session->TrackColours[SCHEME_TRACK];
377         session->WoodenSupportsPrependTo = PaintAddImageAsParentRotated(
378             session, direction, imageId, 0, 6, 2, 24, 43, height, 28, 4, height + 2);
379         imageId = imageIds[isChained][direction][1] | session->TrackColours[SCHEME_TRACK];
380         PaintAddImageAsParentRotated(session, direction, imageId, 0, 6, 32, 2, 43, height, 0, 4, height);
381     }
382 
383     wooden_a_supports_paint_setup(session, direction & 1, 17 + direction, height, session->TrackColours[SCHEME_SUPPORTS]);
384 
385     if (direction == 0 || direction == 3)
386     {
387         paint_util_push_tunnel_rotated(session, direction, height - 8, TUNNEL_1);
388     }
389     else
390     {
391         paint_util_push_tunnel_rotated(session, direction, height + 24, TUNNEL_2);
392     }
393 
394     paint_util_set_segment_support_height(session, SEGMENTS_ALL, 0xFFFF, 0);
395     paint_util_set_general_support_height(session, height + 72, 0x20);
396 }
397 
398 /** rct2: 0x008A54C4 */
wooden_wild_mouse_track_25_deg_up_to_flat(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)399 static void wooden_wild_mouse_track_25_deg_up_to_flat(
400     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
401     const TrackElement& trackElement)
402 {
403     static constexpr const uint32_t imageIds[2][4] = {
404         {
405             SPR_WOODEN_WILD_MOUSE_25_DEG_TO_FLAT_SW_NE,
406             SPR_WOODEN_WILD_MOUSE_25_DEG_TO_FLAT_NW_SE,
407             SPR_WOODEN_WILD_MOUSE_25_DEG_TO_FLAT_NE_SW,
408             SPR_WOODEN_WILD_MOUSE_25_DEG_TO_FLAT_SE_NW,
409         },
410         {
411             SPR_WOODEN_WILD_MOUSE_25_DEG_TO_FLAT_CHAIN_SW_NE,
412             SPR_WOODEN_WILD_MOUSE_25_DEG_TO_FLAT_CHAIN_NW_SE,
413             SPR_WOODEN_WILD_MOUSE_25_DEG_TO_FLAT_CHAIN_NE_SW,
414             SPR_WOODEN_WILD_MOUSE_25_DEG_TO_FLAT_CHAIN_SE_NW,
415         },
416     };
417 
418     uint8_t isChained = trackElement.HasChain() ? 1 : 0;
419     uint32_t imageId = imageIds[isChained][direction] | session->TrackColours[SCHEME_TRACK];
420     PaintAddImageAsParentRotated(session, direction, imageId, 0, 2, 32, 25, 1, height, 0, 3, height);
421 
422     wooden_a_supports_paint_setup(session, direction & 1, 5 + direction, height, session->TrackColours[SCHEME_SUPPORTS]);
423 
424     if (direction == 0 || direction == 3)
425     {
426         paint_util_push_tunnel_rotated(session, direction, height - 8, TUNNEL_0);
427     }
428     else
429     {
430         paint_util_push_tunnel_rotated(session, direction, height + 8, TUNNEL_12);
431     }
432 
433     paint_util_set_segment_support_height(session, SEGMENTS_ALL, 0xFFFF, 0);
434     paint_util_set_general_support_height(session, height + 40, 0x20);
435 }
436 
437 /** rct2: 0x008A54D4 */
wooden_wild_mouse_track_25_deg_down(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)438 static void wooden_wild_mouse_track_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     wooden_wild_mouse_track_25_deg_up(session, ride, trackSequence, (direction + 2) & 3, height, trackElement);
443 }
444 
445 /** rct2: 0x008A54E4 */
wooden_wild_mouse_track_60_deg_down(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)446 static void wooden_wild_mouse_track_60_deg_down(
447     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
448     const TrackElement& trackElement)
449 {
450     wooden_wild_mouse_track_60_deg_up(session, ride, trackSequence, (direction + 2) & 3, height, trackElement);
451 }
452 
453 /** rct2: 0x008A54F4 */
wooden_wild_mouse_track_flat_to_25_deg_down(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)454 static void wooden_wild_mouse_track_flat_to_25_deg_down(
455     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
456     const TrackElement& trackElement)
457 {
458     wooden_wild_mouse_track_25_deg_up_to_flat(session, ride, trackSequence, (direction + 2) & 3, height, trackElement);
459 }
460 
461 /** rct2: 0x008A5504 */
wooden_wild_mouse_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)462 static void wooden_wild_mouse_track_25_deg_down_to_60_deg_down(
463     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
464     const TrackElement& trackElement)
465 {
466     wooden_wild_mouse_track_60_deg_to_25_deg_up(session, ride, trackSequence, (direction + 2) & 3, height, trackElement);
467 }
468 
469 /** rct2: 0x008A5514 */
wooden_wild_mouse_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)470 static void wooden_wild_mouse_track_60_deg_down_to_25_deg_down(
471     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
472     const TrackElement& trackElement)
473 {
474     wooden_wild_mouse_track_25_deg_up_to_60_deg_up(session, ride, trackSequence, (direction + 2) & 3, height, trackElement);
475 }
476 
477 /** rct2: 0x008A5524 */
wooden_wild_mouse_track_25_deg_down_to_flat(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)478 static void wooden_wild_mouse_track_25_deg_down_to_flat(
479     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
480     const TrackElement& trackElement)
481 {
482     wooden_wild_mouse_track_flat_to_25_deg_up(session, ride, trackSequence, (direction + 2) & 3, height, trackElement);
483 }
484 
wooden_wild_mouse_track_right_quarter_turn_3(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)485 static void wooden_wild_mouse_track_right_quarter_turn_3(
486     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
487     const TrackElement& trackElement)
488 {
489     static constexpr const sprite_bb imageIds[4][3] = {
490         {
491             { SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_3_SW_SE_PART_0, { 0, 6, 0 }, { 0, 0, 0 }, { 32, 20, 1 } },
492             { SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_3_SW_SE_PART_1, { 16, 16, 0 }, { 0, 0, 0 }, { 16, 16, 1 } },
493             { SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_3_SW_SE_PART_2, { 6, 0, 0 }, { 0, 0, 0 }, { 20, 32, 1 } },
494         },
495         {
496             { SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_3_NW_SW_PART_0, { 6, 0, 0 }, { 0, 0, 0 }, { 20, 32, 1 } },
497             { SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_3_NW_SW_PART_1, { 16, 0, 0 }, { 0, 0, 0 }, { 16, 16, 1 } },
498             { SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_3_NW_SW_PART_2, { 0, 6, 0 }, { 0, 0, 0 }, { 32, 20, 1 } },
499         },
500         {
501             { SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_3_NE_NW_PART_0, { 0, 6, 0 }, { 0, 0, 0 }, { 32, 20, 1 } },
502             { SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_3_NE_NW_PART_1, { 0, 0, 0 }, { 0, 0, 0 }, { 16, 16, 1 } },
503             { SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_3_NE_NW_PART_2, { 6, 0, 0 }, { 0, 0, 0 }, { 20, 32, 1 } },
504         },
505         {
506             { SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_3_SE_NE_PART_0, { 6, 0, 0 }, { 0, 0, 0 }, { 20, 32, 1 } },
507             { SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_3_SE_NE_PART_1, { 0, 16, 0 }, { 0, 0, 0 }, { 16, 16, 1 } },
508             { SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_3_SE_NE_PART_2, { 0, 6, 0 }, { 0, 0, 0 }, { 32, 20, 1 } },
509         },
510     };
511     static uint8_t supportType[] = { 4, 5, 2, 3 };
512 
513     track_paint_util_right_quarter_turn_3_tiles_paint_4(
514         session, height, direction, trackSequence, session->TrackColours[SCHEME_TRACK], imageIds);
515     track_paint_util_right_quarter_turn_3_tiles_tunnel(session, height, direction, trackSequence, TUNNEL_0);
516 
517     switch (trackSequence)
518     {
519         case 0:
520         case 3:
521             wooden_a_supports_paint_setup(session, supportType[direction], 0, height, session->TrackColours[SCHEME_SUPPORTS]);
522             break;
523     }
524 
525     int32_t blockedSegments = 0;
526     switch (trackSequence)
527     {
528         case 0:
529             blockedSegments = SEGMENTS_ALL;
530             break;
531         case 2:
532             blockedSegments = SEGMENT_C0 | SEGMENT_C4 | SEGMENT_D0 | SEGMENT_D4;
533             break;
534         case 3:
535             blockedSegments = SEGMENTS_ALL;
536             break;
537     }
538     paint_util_set_segment_support_height(session, paint_util_rotate_segments(blockedSegments, direction), 0xFFFF, 0);
539     paint_util_set_general_support_height(session, height + 32, 0x20);
540 }
541 
wooden_wild_mouse_track_left_quarter_turn_3(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)542 static void wooden_wild_mouse_track_left_quarter_turn_3(
543     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
544     const TrackElement& trackElement)
545 {
546     trackSequence = mapLeftQuarterTurn3TilesToRightQuarterTurn3Tiles[trackSequence];
547     wooden_wild_mouse_track_right_quarter_turn_3(session, ride, trackSequence, (direction + 1) % 4, height, trackElement);
548 }
549 
wooden_wild_mouse_track_left_quarter_turn_1(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)550 static void wooden_wild_mouse_track_left_quarter_turn_1(
551     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
552     const TrackElement& trackElement)
553 {
554     static constexpr const uint32_t imageIds[4] = {
555         SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_1_SW_NE,
556         SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_1_NW_SE,
557         SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_1_NE_SW,
558         SPR_WOODEN_WILD_MOUSE_QUARTER_TURN_1_SE_NW,
559     };
560     static uint8_t supportType[] = { 5, 2, 3, 4 };
561 
562     uint32_t imageId = imageIds[direction] | session->TrackColours[SCHEME_TRACK];
563     switch (direction)
564     {
565         case 0:
566             PaintAddImageAsParent(session, imageId, { 6, 0, height }, { 26, 24, 1 }, { 6, 2, height });
567             break;
568         case 1:
569             PaintAddImageAsParent(session, imageId, { 0, 0, height }, { 26, 26, 1 });
570             break;
571         case 2:
572             PaintAddImageAsParent(session, imageId, { 0, 6, height }, { 24, 26, 1 }, { 2, 6, height });
573             break;
574         case 3:
575             PaintAddImageAsParent(session, imageId, { 6, 6, height }, { 24, 24, 1 });
576             break;
577     }
578     wooden_a_supports_paint_setup(session, supportType[direction], 0, height, session->TrackColours[SCHEME_SUPPORTS]);
579     track_paint_util_left_quarter_turn_1_tile_tunnel(session, direction, height, 0, TUNNEL_0, 0, TUNNEL_0);
580     paint_util_set_segment_support_height(session, SEGMENTS_ALL, 0xFFFF, 0);
581     paint_util_set_general_support_height(session, height + 32, 0x20);
582 }
583 
584 /** rct2: 0x008A55D4 */
wooden_wild_mouse_track_right_quarter_turn_1(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)585 static void wooden_wild_mouse_track_right_quarter_turn_1(
586     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
587     const TrackElement& trackElement)
588 {
589     wooden_wild_mouse_track_left_quarter_turn_1(session, ride, trackSequence, (direction - 1) & 3, height, trackElement);
590 }
591 
592 /** rct2: 0x008A55E4 */
wooden_wild_mouse_track_flat_to_60_deg_up(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)593 static void wooden_wild_mouse_track_flat_to_60_deg_up(
594     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
595     const TrackElement& trackElement)
596 {
597     static constexpr const uint32_t imageIds[2][4][2] = {
598         {
599             { SPR_WOODEN_WILD_MOUSE_FLAT_TO_60_DEG_SW_NE, 0 },
600             { SPR_WOODEN_WILD_MOUSE_FLAT_TO_60_DEG_NW_SE, SPR_WOODEN_WILD_MOUSE_FLAT_TO_60_DEG_FRONT_NW_SE },
601             { SPR_WOODEN_WILD_MOUSE_FLAT_TO_60_DEG_NE_SW, SPR_WOODEN_WILD_MOUSE_FLAT_TO_60_DEG_FRONT_NE_SW },
602             { SPR_WOODEN_WILD_MOUSE_FLAT_TO_60_DEG_SE_NW, 0 },
603         },
604         {
605             { SPR_WOODEN_WILD_MOUSE_FLAT_TO_60_DEG_CHAIN_SW_NE, 0 },
606             { SPR_WOODEN_WILD_MOUSE_FLAT_TO_60_DEG_CHAIN_NW_SE, SPR_WOODEN_WILD_MOUSE_FLAT_TO_60_DEG_CHAIN_FRONT_NW_SE },
607             { SPR_WOODEN_WILD_MOUSE_FLAT_TO_60_DEG_CHAIN_NE_SW, SPR_WOODEN_WILD_MOUSE_FLAT_TO_60_DEG_CHAIN_FRONT_NE_SW },
608             { SPR_WOODEN_WILD_MOUSE_FLAT_TO_60_DEG_CHAIN_SE_NW, 0 },
609         },
610     };
611 
612     uint8_t isChained = trackElement.HasChain() ? 1 : 0;
613     uint32_t imageId;
614     if (direction == 0 || direction == 3)
615     {
616         imageId = imageIds[isChained][direction][0] | session->TrackColours[SCHEME_TRACK];
617         PaintAddImageAsParentRotated(session, direction, imageId, 0, 2, 32, 25, 1, height, 0, 3, height);
618     }
619     else
620     {
621         imageId = imageIds[isChained][direction][0] | session->TrackColours[SCHEME_TRACK];
622         PaintAddImageAsParentRotated(session, direction, imageId, 0, 6, 2, 24, 43, height, 28, 4, height + 2);
623         imageId = imageIds[isChained][direction][1] | session->TrackColours[SCHEME_TRACK];
624         PaintAddImageAsParentRotated(session, direction, imageId, 0, 6, 32, 2, 43, height, 0, 4, height);
625     }
626 
627     wooden_a_supports_paint_setup(session, direction & 1, 29 + direction, height, session->TrackColours[SCHEME_SUPPORTS]);
628 
629     if (direction == 0 || direction == 3)
630     {
631         paint_util_push_tunnel_rotated(session, direction, height, TUNNEL_0);
632     }
633     else
634     {
635         paint_util_push_tunnel_rotated(session, direction, height + 24, TUNNEL_2);
636     }
637 
638     paint_util_set_segment_support_height(session, SEGMENTS_ALL, 0xFFFF, 0);
639     paint_util_set_general_support_height(session, height + 64, 0x20);
640 }
641 
642 /** rct2: 0x008A55F4 */
wooden_wild_mouse_track_60_deg_up_to_flat(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)643 static void wooden_wild_mouse_track_60_deg_up_to_flat(
644     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
645     const TrackElement& trackElement)
646 {
647     static constexpr const uint32_t imageIds[2][4][2] = {
648         {
649             { SPR_WOODEN_WILD_MOUSE_60_DEG_TO_FLAT_SW_NE, 0 },
650             { SPR_WOODEN_WILD_MOUSE_60_DEG_TO_FLAT_NW_SE, SPR_WOODEN_WILD_MOUSE_60_DEG_TO_FLAT_FRONT_NW_SE },
651             { SPR_WOODEN_WILD_MOUSE_60_DEG_TO_FLAT_NE_SW, SPR_WOODEN_WILD_MOUSE_60_DEG_TO_FLAT_FRONT_NE_SW },
652             { SPR_WOODEN_WILD_MOUSE_60_DEG_TO_FLAT_SE_NW, 0 },
653         },
654         {
655             { SPR_WOODEN_WILD_MOUSE_60_DEG_TO_FLAT_CHAIN_SW_NE, 0 },
656             { SPR_WOODEN_WILD_MOUSE_60_DEG_TO_FLAT_CHAIN_NW_SE, SPR_WOODEN_WILD_MOUSE_60_DEG_TO_FLAT_CHAIN_FRONT_NW_SE },
657             { SPR_WOODEN_WILD_MOUSE_60_DEG_TO_FLAT_CHAIN_NE_SW, SPR_WOODEN_WILD_MOUSE_60_DEG_TO_FLAT_CHAIN_FRONT_NE_SW },
658             { SPR_WOODEN_WILD_MOUSE_60_DEG_TO_FLAT_CHAIN_SE_NW, 0 },
659         },
660     };
661 
662     uint8_t isChained = trackElement.HasChain() ? 1 : 0;
663     uint32_t imageId;
664     if (direction == 0 || direction == 3)
665     {
666         imageId = imageIds[isChained][direction][0] | session->TrackColours[SCHEME_TRACK];
667         PaintAddImageAsParentRotated(session, direction, imageId, 0, 2, 32, 25, 1, height, 0, 3, height);
668     }
669     else
670     {
671         imageId = imageIds[isChained][direction][0] | session->TrackColours[SCHEME_TRACK];
672         PaintAddImageAsParentRotated(session, direction, imageId, 0, 6, 2, 24, 43, height, 28, 4, height + 2);
673         imageId = imageIds[isChained][direction][1] | session->TrackColours[SCHEME_TRACK];
674         PaintAddImageAsParentRotated(session, direction, imageId, 0, 6, 32, 2, 43, height, 0, 4, height);
675     }
676 
677     wooden_a_supports_paint_setup(session, direction & 1, 33 + direction, height, session->TrackColours[SCHEME_SUPPORTS]);
678 
679     if (direction == 0 || direction == 3)
680     {
681         paint_util_push_tunnel_rotated(session, direction, height - 8, TUNNEL_1);
682     }
683     else
684     {
685         paint_util_push_tunnel_rotated(session, direction, height + 24, TUNNEL_0);
686     }
687 
688     paint_util_set_segment_support_height(session, SEGMENTS_ALL, 0xFFFF, 0);
689     paint_util_set_general_support_height(session, height + 72, 0x20);
690 }
691 
692 /** rct2: 0x008A5604 */
wooden_wild_mouse_track_flat_to_60_deg_down(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)693 static void wooden_wild_mouse_track_flat_to_60_deg_down(
694     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
695     const TrackElement& trackElement)
696 {
697     wooden_wild_mouse_track_60_deg_up_to_flat(session, ride, trackSequence, (direction + 2) & 3, height, trackElement);
698 }
699 
700 /** rct2: 0x008A5614 */
wooden_wild_mouse_track_60_deg_down_to_flat(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)701 static void wooden_wild_mouse_track_60_deg_down_to_flat(
702     paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
703     const TrackElement& trackElement)
704 {
705     wooden_wild_mouse_track_flat_to_60_deg_up(session, ride, trackSequence, (direction + 2) & 3, height, trackElement);
706 }
707 
get_track_paint_function_wooden_wild_mouse(int32_t trackType)708 TRACK_PAINT_FUNCTION get_track_paint_function_wooden_wild_mouse(int32_t trackType)
709 {
710     switch (trackType)
711     {
712         case TrackElemType::Flat:
713             return wooden_wild_mouse_track_flat;
714         case TrackElemType::EndStation:
715         case TrackElemType::BeginStation:
716         case TrackElemType::MiddleStation:
717             return wooden_wild_mouse_track_station;
718         case TrackElemType::Up25:
719             return wooden_wild_mouse_track_25_deg_up;
720         case TrackElemType::Up60:
721             return wooden_wild_mouse_track_60_deg_up;
722         case TrackElemType::FlatToUp25:
723             return wooden_wild_mouse_track_flat_to_25_deg_up;
724         case TrackElemType::Up25ToUp60:
725             return wooden_wild_mouse_track_25_deg_up_to_60_deg_up;
726         case TrackElemType::Up60ToUp25:
727             return wooden_wild_mouse_track_60_deg_to_25_deg_up;
728         case TrackElemType::Up25ToFlat:
729             return wooden_wild_mouse_track_25_deg_up_to_flat;
730         case TrackElemType::Down25:
731             return wooden_wild_mouse_track_25_deg_down;
732         case TrackElemType::Down60:
733             return wooden_wild_mouse_track_60_deg_down;
734         case TrackElemType::FlatToDown25:
735             return wooden_wild_mouse_track_flat_to_25_deg_down;
736         case TrackElemType::Down25ToDown60:
737             return wooden_wild_mouse_track_25_deg_down_to_60_deg_down;
738         case TrackElemType::Down60ToDown25:
739             return wooden_wild_mouse_track_60_deg_down_to_25_deg_down;
740         case TrackElemType::Down25ToFlat:
741             return wooden_wild_mouse_track_25_deg_down_to_flat;
742         case TrackElemType::LeftQuarterTurn3Tiles:
743             return wooden_wild_mouse_track_left_quarter_turn_3;
744         case TrackElemType::RightQuarterTurn3Tiles:
745             return wooden_wild_mouse_track_right_quarter_turn_3;
746         case TrackElemType::LeftQuarterTurn1Tile:
747             return wooden_wild_mouse_track_left_quarter_turn_1;
748         case TrackElemType::RightQuarterTurn1Tile:
749             return wooden_wild_mouse_track_right_quarter_turn_1;
750         case TrackElemType::FlatToUp60:
751             return wooden_wild_mouse_track_flat_to_60_deg_up;
752         case TrackElemType::Up60ToFlat:
753             return wooden_wild_mouse_track_60_deg_up_to_flat;
754         case TrackElemType::FlatToDown60:
755             return wooden_wild_mouse_track_flat_to_60_deg_down;
756         case TrackElemType::Down60ToFlat:
757             return wooden_wild_mouse_track_60_deg_down_to_flat;
758     }
759     return nullptr;
760 }
761