diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj
index ea6a74ab68..44e73ff7e8 100644
--- a/projects/openrct2.vcxproj
+++ b/projects/openrct2.vcxproj
@@ -94,6 +94,7 @@
+
@@ -250,6 +251,7 @@
+
diff --git a/projects/openrct2.vcxproj.filters b/projects/openrct2.vcxproj.filters
index 070539ff77..247c93564f 100644
--- a/projects/openrct2.vcxproj.filters
+++ b/projects/openrct2.vcxproj.filters
@@ -540,6 +540,9 @@
Source\Localisation
+
+ Source\Ride
+
@@ -806,5 +809,8 @@
Source\Core
+
+ Source\Ride
+
\ No newline at end of file
diff --git a/src/interface/viewport.c b/src/interface/viewport.c
index aa92041b0b..9de5abdec6 100644
--- a/src/interface/viewport.c
+++ b/src/interface/viewport.c
@@ -24,6 +24,7 @@
#include "../localisation/localisation.h"
#include "../ride/ride_data.h"
#include "../ride/track_data.h"
+#include "../ride/track_paint.h"
#include "../sprites.h"
#include "../world/map.h"
#include "../world/sprite.h"
@@ -720,8 +721,21 @@ void sub_688485(){
}
+/* rct2: 0x006874B0, 0x00687618, 0x0068778C, 0x00687902, 0x0098199C */
+int sub_98199C(sint8 al, sint8 ah, int image_id, sint8 cl, int height, sint16 length_x, sint16 length_y, uint32 rotation){
+ RCT2_CALLPROC_X(RCT2_ADDRESS(0x98199C, uint32_t)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)],
+ al | (ah << 8),
+ image_id,
+ cl,
+ height,
+ length_x,
+ length_y,
+ rotation);
+ return 1;
+}
+
/* rct2: 0x00686806, 0x006869B2, 0x00686B6F, 0x00686D31, 0x0098197C */
-int sub_98197C(sint8 al, sint8 ah, int image_id, sint8 cl, int edx, sint16 si, sint16 di, uint32 rotation){
+int sub_98197C(sint8 al, sint8 ah, int image_id, sint8 cl, int height, sint16 length_x, sint16 length_y, uint32 rotation){
int ebp = ah + RCT2_GLOBAL(0x9DEA56, uint16);
RCT2_GLOBAL(0xF1AD28, paint_struct*) = 0;
@@ -730,7 +744,7 @@ int sub_98197C(sint8 al, sint8 ah, int image_id, sint8 cl, int edx, sint16 si, s
//Not a paint struct but something similar
paint_struct* ps = RCT2_GLOBAL(0xEE7888, paint_struct*);
- if ((uint32)ps >= RCT2_GLOBAL(0xEE7880, uint32)) return 1;
+ if ((uint32)ps >= RCT2_GLOBAL(0xEE7880, uint32))return 1;
ps->image_id = image_id;
@@ -747,11 +761,23 @@ int sub_98197C(sint8 al, sint8 ah, int image_id, sint8 cl, int edx, sint16 si, s
rct_xyz16 coord_3d = {
.x = al,
.y = cl,
- .z = edx
+ .z = height
};
- rotate_map_coordinates(&coord_3d.x, &coord_3d.y, rotation);
-
+ switch (rotation) {
+ case 0:
+ rotate_map_coordinates(&coord_3d.x, &coord_3d.y, 0);
+ break;
+ case 1:
+ rotate_map_coordinates(&coord_3d.x, &coord_3d.y, 3);
+ break;
+ case 2:
+ rotate_map_coordinates(&coord_3d.x, &coord_3d.y, 2);
+ break;
+ case 3:
+ rotate_map_coordinates(&coord_3d.x, &coord_3d.y, 1);
+ break;
+ }
coord_3d.x += RCT2_GLOBAL(0x9DE568, sint16);
coord_3d.y += RCT2_GLOBAL(0x9DE56C, sint16);
@@ -773,12 +799,12 @@ int sub_98197C(sint8 al, sint8 ah, int image_id, sint8 cl, int edx, sint16 si, s
if (right <= dpi->x)return 1;
if (top <= dpi->y)return 1;
- if (left > dpi->x + dpi->width) return 1;
- if (bottom > dpi->y + dpi->height) return 1;
+ if (left > dpi->x + dpi->width)return 1;
+ if (bottom > dpi->y + dpi->height)return 1;
- rct_xy16 unk = {
- .x = di,
- .y = si
+ rct_xy16 boundBox = {
+ .x = length_x,
+ .y = length_y
};
rct_xy16 s_unk = {
@@ -789,31 +815,31 @@ int sub_98197C(sint8 al, sint8 ah, int image_id, sint8 cl, int edx, sint16 si, s
// Unsure why rots 1 and 3 need to swap
switch (rotation){
case 0:
- rotate_map_coordinates(&unk.x, &unk.y, 0);
+ rotate_map_coordinates(&boundBox.x, &boundBox.y, 0);
rotate_map_coordinates(&s_unk.x, &s_unk.y, 0);
- unk.x--;
- unk.y--;
+ boundBox.x--;
+ boundBox.y--;
break;
case 1:
- rotate_map_coordinates(&unk.x, &unk.y, 3);
+ rotate_map_coordinates(&boundBox.x, &boundBox.y, 3);
rotate_map_coordinates(&s_unk.x, &s_unk.y, 3);
- unk.y--;
+ boundBox.y--;
break;
case 2:
- rotate_map_coordinates(&unk.x, &unk.y, 2);
+ rotate_map_coordinates(&boundBox.x, &boundBox.y, 2);
rotate_map_coordinates(&s_unk.x, &s_unk.y, 2);
break;
case 3:
- rotate_map_coordinates(&unk.x, &unk.y, 1);
+ rotate_map_coordinates(&boundBox.x, &boundBox.y, 1);
rotate_map_coordinates(&s_unk.x, &s_unk.y, 1);
- unk.x--;
+ boundBox.x--;
break;
}
- ps->other_x = unk.x + s_unk.x + RCT2_GLOBAL(0x9DE568, sint16);
+ ps->other_x = boundBox.x + s_unk.x + RCT2_GLOBAL(0x9DE568, sint16);
ps->some_x = RCT2_GLOBAL(0x009DEA56, sint16);
ps->some_y = ebp;
- ps->other_y = unk.y + s_unk.y + RCT2_GLOBAL(0x009DE56C, sint16);
+ ps->other_y = boundBox.y + s_unk.y + RCT2_GLOBAL(0x009DE56C, sint16);
ps->var_1A = 0;
ps->attached_x = s_unk.x + RCT2_GLOBAL(0x9DE568, sint16);
ps->attached_y = s_unk.y + RCT2_GLOBAL(0x009DE56C, sint16);
@@ -845,7 +871,7 @@ int sub_98197C(sint8 al, sint8 ah, int image_id, sint8 cl, int edx, sint16 si, s
break;
}
- di = attach.x + attach.y;
+ sint16 di = attach.x + attach.y;
if (di < 0)
di = 0;
@@ -859,12 +885,12 @@ int sub_98197C(sint8 al, sint8 ah, int image_id, sint8 cl, int edx, sint16 si, s
RCT2_ADDRESS(0x00F1A50C, paint_struct*)[di] = ps;
ps->next_quadrant_ps = old_ps;
- if (di < RCT2_GLOBAL(0x00F1AD0C, sint32)){
- RCT2_GLOBAL(0x00F1AD0C, sint32) = di;
+ if ((uint16)di < RCT2_GLOBAL(0x00F1AD0C, uint32)){
+ RCT2_GLOBAL(0x00F1AD0C, uint32) = di;
}
- if (di > RCT2_GLOBAL(0x00F1AD10, sint32)){
- RCT2_GLOBAL(0x00F1AD10, sint32) = di;
+ if ((uint16)di > RCT2_GLOBAL(0x00F1AD10, uint32)){
+ RCT2_GLOBAL(0x00F1AD10, uint32) = di;
}
RCT2_GLOBAL(0xEE7888, paint_struct*) += 1;
@@ -1121,8 +1147,7 @@ void viewport_ride_entrance_exit_paint_setup(uint8 direction, int height, rct_ma
RCT2_GLOBAL(0x009DEA54, uint16) = 2;
RCT2_GLOBAL(0x009DEA56, uint16) = height;
- RCT2_CALLPROC_X(RCT2_ADDRESS(0x98199C, uint32_t)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)],
- ah << 8, transparant_image_id, 0, height, 2, 0x1C, 0);
+ sub_98199C(0, ah, transparant_image_id, 0, height, 2, 0x1C, 0);
}
image_id += 4;
@@ -1139,8 +1164,7 @@ void viewport_ride_entrance_exit_paint_setup(uint8 direction, int height, rct_ma
RCT2_GLOBAL(0x009DEA54, uint16) = 28;
RCT2_GLOBAL(0x009DEA56, uint16) = height;
- RCT2_CALLPROC_X(RCT2_ADDRESS(0x98199C, uint32_t)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)],
- ah << 8, transparant_image_id, 0, height, 2, 0x1C, 0);
+ sub_98199C(0, ah, transparant_image_id, 0, height, 2, 0x1C, 0);
}
uint32 eax = 0xFFFF0600 | ((height / 16) & 0xFF);
@@ -1186,8 +1210,7 @@ void viewport_ride_entrance_exit_paint_setup(uint8 direction, int height, rct_ma
RCT2_GLOBAL(0x009DEA52, uint16) = 2;
RCT2_GLOBAL(0x009DEA54, uint16) = 2;
RCT2_GLOBAL(0x009DEA56, uint16) = height + style->height;
- RCT2_CALLPROC_X(RCT2_ADDRESS(0x98199C, uint32_t)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)],
- 0x3300, scrolling_text_setup(string_id, scroll, style->scrolling_mode), 0, height + style->height, 0x1C, 0x1C, 0);
+ sub_98199C(0, 0x33, scrolling_text_setup(string_id, scroll, style->scrolling_mode), 0, height + style->height, 0x1C, 0x1C, 0);
}
image_id = RCT2_GLOBAL(0x009E32BC, uint32);
@@ -1293,8 +1316,7 @@ void viewport_park_entrance_paint_setup(uint8 direction, int height, rct_map_ele
RCT2_GLOBAL(0x009DEA54, uint16) = 2;
RCT2_GLOBAL(0x009DEA56, sint16) = height + entrance->text_height;
- RCT2_CALLPROC_X(RCT2_ADDRESS(0x98199C, uint32_t)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)],
- 0x2F00, scrolling_text_setup(park_text_id, scroll, entrance->scrolling_mode + direction / 2), 0, height + entrance->text_height, 0x1C, 0x1C, 0);
+ sub_98199C(0, 0x2F, scrolling_text_setup(park_text_id, scroll, entrance->scrolling_mode + direction / 2), 0, height + entrance->text_height, 0x1C, 0x1C, 0);
break;
case 1:
case 2:
@@ -1373,16 +1395,7 @@ void viewport_track_paint_setup(uint8 direction, int height, rct_map_element *ma
RCT2_GLOBAL(0x009DEA52, uint16) = 1000;
RCT2_GLOBAL(0x009DEA54, uint16) = 1000;
RCT2_GLOBAL(0x009DEA56, uint16) = 2047;
- RCT2_CALLPROC_X(
- RCT2_ADDRESS(0x0098197C, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint8)],
- 16,
- ebx,
- 16,
- height + ax + 3,
- 1,
- 1,
- 0
- );
+ sub_98197C(16, 0, ebx, 16, height + ax + 3, 1, 1, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32));
}
}
@@ -1398,28 +1411,36 @@ void viewport_track_paint_setup(uint8 direction, int height, rct_map_element *ma
RCT2_GLOBAL(0x00F441A4, uint32) = 0x21600000;
}
if (mapElement->flags & MAP_ELEMENT_FLAG_GHOST) {
- uint32 meh = RCT2_ADDRESS(0x00993CC4, uint32)[RCT2_GLOBAL(0x009AACBF, uint8)];
+ uint32 ghost_id = RCT2_ADDRESS(0x00993CC4, uint32)[RCT2_GLOBAL(0x009AACBF, uint8)];
RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = 0;
- RCT2_GLOBAL(0x00F44198, uint32) = meh;
- RCT2_GLOBAL(0x00F4419C, uint32) = meh;
- RCT2_GLOBAL(0x00F441A0, uint32) = meh;
- RCT2_GLOBAL(0x00F441A4, uint32) = meh;
+ RCT2_GLOBAL(0x00F44198, uint32) = ghost_id;
+ RCT2_GLOBAL(0x00F4419C, uint32) = ghost_id;
+ RCT2_GLOBAL(0x00F441A0, uint32) = ghost_id;
+ RCT2_GLOBAL(0x00F441A4, uint32) = ghost_id;
}
- uint32 **trackTypeList = (uint32**)RideTypeTrackPaintFunctions[ride->type];
- uint32 *trackDirectionList = trackTypeList[trackType];
+ TRACK_PAINT_FUNCTION **trackTypeList = (TRACK_PAINT_FUNCTION**)RideTypeTrackPaintFunctionsOld[ride->type];
+ if (trackTypeList == NULL) {
+ trackTypeList = (TRACK_PAINT_FUNCTION**)RideTypeTrackPaintFunctions[ride->type];
- // Have to call from this point as it pushes esi and expects callee to pop it
- RCT2_CALLPROC_X(
- 0x006C4934,
- ride->type,
- (int)trackDirectionList,
- direction,
- height,
- (int)mapElement,
- rideIndex * sizeof(rct_ride),
- trackSequence
- );
+ if (trackTypeList[trackType] != NULL)
+ trackTypeList[trackType][direction](rideIndex, trackSequence, direction, height, mapElement);
+ }
+ else {
+ uint32 *trackDirectionList = (uint32*)trackTypeList[trackType];
+
+ // Have to call from this point as it pushes esi and expects callee to pop it
+ RCT2_CALLPROC_X(
+ 0x006C4934,
+ ride->type,
+ (int)trackDirectionList,
+ direction,
+ height,
+ (int)mapElement,
+ rideIndex * sizeof(rct_ride),
+ trackSequence
+ );
+ }
}
if (isEntranceStyleNone) {
@@ -1538,8 +1559,7 @@ void viewport_banner_paint_setup(uint8 direction, int height, rct_map_element* m
uint16 string_width = gfx_get_string_width(RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char));
uint16 scroll = (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) / 2) % string_width;
- RCT2_CALLPROC_X(RCT2_ADDRESS(0x98199C, uint32_t)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32_t)],
- 0x1500, scrolling_text_setup(string_id, scroll, scrollingMode), 0, height + 22, 1, 1, 0);
+ sub_98199C(0, 0x15, scrolling_text_setup(string_id, scroll, scrollingMode), 0, height + 22, 1, 1, 0);
}
/**
diff --git a/src/interface/viewport.h b/src/interface/viewport.h
index a1fd91a45d..d13305eb17 100644
--- a/src/interface/viewport.h
+++ b/src/interface/viewport.h
@@ -131,6 +131,10 @@ void painter_setup();
void sub_688485();
void sub_688217();
+int sub_98197C(sint8 al, sint8 ah, int image_id, sint8 cl, int height, sint16 length_x, sint16 length_y, uint32 rotation);
+int sub_98199C(sint8 al, sint8 ah, int image_id, sint8 cl, int height, sint16 length_x, sint16 length_y, uint32 rotation);
+int sub_6629BC(int height, uint16 ax, uint32 image_id, int edi);
+
void viewport_invalidate(rct_viewport *viewport, int left, int top, int right, int bottom);
void screen_get_map_xy(int screenX, int screenY, sint16 *x, sint16 *y, rct_viewport **viewport);
diff --git a/src/ride/ride.h b/src/ride/ride.h
index e1320f4da8..0734fedc7e 100644
--- a/src/ride/ride.h
+++ b/src/ride/ride.h
@@ -828,7 +828,7 @@ extern rct_ride* g_ride_list;
/** Helper macros until rides are stored in this module. */
#define GET_RIDE(x) (&g_ride_list[x])
#define GET_RIDE_MEASUREMENT(x) (&(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_MEASUREMENTS, rct_ride_measurement)[x]))
-#define GET_RIDE_ENTRY(x) RCT2_ADDRESS(RCT2_ADDRESS_RIDE_ENTRIES, rct_ride_type*)[x]
+#define GET_RIDE_ENTRY(x) gRideTypeList[x]
/**
* Helper macro loop for enumerating through all the non null rides.
diff --git a/src/ride/track_data.c b/src/ride/track_data.c
index 1ba63b6e65..f1590b882e 100644
--- a/src/ride/track_data.c
+++ b/src/ride/track_data.c
@@ -20,6 +20,7 @@
#include "track.h"
#include "track_data.h"
+#include "track_paint.h"
const rct_track_coordinates* FlatTrackCoordinates = RCT2_ADDRESS(0x009972BB, const rct_track_coordinates);
@@ -5469,7 +5470,7 @@ const track_curve_chain gFlatRideTrackCurveChain[256] = {
{ 0, 57088 },
};
-const uint32 RideTypeTrackPaintFunctions[91] = {
+const uint32 RideTypeTrackPaintFunctionsOld[91] = {
0x008A42F4, // RIDE_TYPE_SPIRAL_ROLLER_COASTER
0x008A6DB0, // RIDE_TYPE_STAND_UP_ROLLER_COASTER
0x008A85E4, // RIDE_TYPE_SUSPENDED_SWINGING_COASTER
@@ -5510,7 +5511,7 @@ const uint32 RideTypeTrackPaintFunctions[91] = {
0x008A8CC8, // RIDE_TYPE_FERRIS_WHEEL
0x00763520, // RIDE_TYPE_MOTION_SIMULATOR
0x0076554C, // RIDE_TYPE_3D_CINEMA
- 0x0076659C, // RIDE_TYPE_TOP_SPIN
+ 0, // RIDE_TYPE_TOP_SPIN
0x00767A40, // RIDE_TYPE_SPACE_RINGS
0x00768BAC, // RIDE_TYPE_REVERSE_FREEFALL_COASTER
0x0076C5BC, // RIDE_TYPE_LIFT
@@ -5562,3 +5563,98 @@ const uint32 RideTypeTrackPaintFunctions[91] = {
0x00000000, // RIDE_TYPE_59
0x008A5F6C, // RIDE_TYPE_LIM_LAUNCHED_ROLLER_COASTER
};
+
+
+const uint32 RideTypeTrackPaintFunctions[91] = {
+ 0, // RIDE_TYPE_SPIRAL_ROLLER_COASTER
+ 0, // RIDE_TYPE_STAND_UP_ROLLER_COASTER
+ 0, // RIDE_TYPE_SUSPENDED_SWINGING_COASTER
+ 0, // RIDE_TYPE_INVERTED_ROLLER_COASTER
+ 0, // RIDE_TYPE_JUNIOR_ROLLER_COASTER
+ 0, // RIDE_TYPE_MINIATURE_RAILWAY
+ 0, // RIDE_TYPE_MONORAIL
+ 0, // RIDE_TYPE_MINI_SUSPENDED_COASTER
+ 0, // RIDE_TYPE_BOAT_RIDE
+ 0, // RIDE_TYPE_WOODEN_WILD_MOUSE
+ 0, // RIDE_TYPE_STEEPLECHASE
+ 0, // RIDE_TYPE_CAR_RIDE
+ 0, // RIDE_TYPE_LAUNCHED_FREEFALL
+ 0, // RIDE_TYPE_BOBSLEIGH_COASTER
+ 0, // RIDE_TYPE_OBSERVATION_TOWER
+ 0, // RIDE_TYPE_LOOPING_ROLLER_COASTER
+ 0, // RIDE_TYPE_DINGHY_SLIDE
+ 0, // RIDE_TYPE_MINE_TRAIN_COASTER
+ 0, // RIDE_TYPE_CHAIRLIFT
+ 0, // RIDE_TYPE_CORKSCREW_ROLLER_COASTER
+ 0, // RIDE_TYPE_MAZE
+ 0, // RIDE_TYPE_SPIRAL_SLIDE
+ 0, // RIDE_TYPE_GO_KARTS
+ 0, // RIDE_TYPE_LOG_FLUME
+ 0, // RIDE_TYPE_RIVER_RAPIDS
+ 0, // RIDE_TYPE_DODGEMS
+ 0, // RIDE_TYPE_PIRATE_SHIP
+ 0, // RIDE_TYPE_SWINGING_INVERTER_SHIP
+ 0, // RIDE_TYPE_FOOD_STALL
+ 0, // RIDE_TYPE_1D
+ 0, // RIDE_TYPE_DRINK_STALL
+ 0, // RIDE_TYPE_1F
+ 0, // RIDE_TYPE_SHOP
+ 0, // RIDE_TYPE_MERRY_GO_ROUND
+ 0, // RIDE_TYPE_22
+ 0, // RIDE_TYPE_INFORMATION_KIOSK
+ 0, // RIDE_TYPE_TOILETS
+ 0, // RIDE_TYPE_FERRIS_WHEEL
+ 0, // RIDE_TYPE_MOTION_SIMULATOR
+ 0, // RIDE_TYPE_3D_CINEMA
+ (uint32)top_spin_track_paint_functions, // RIDE_TYPE_TOP_SPIN
+ 0, // RIDE_TYPE_SPACE_RINGS
+ 0, // RIDE_TYPE_REVERSE_FREEFALL_COASTER
+ 0, // RIDE_TYPE_LIFT
+ 0, // RIDE_TYPE_VERTICAL_DROP_ROLLER_COASTER
+ 0, // RIDE_TYPE_CASH_MACHINE
+ 0, // RIDE_TYPE_TWIST
+ 0, // RIDE_TYPE_HAUNTED_HOUSE
+ 0, // RIDE_TYPE_FIRST_AID
+ 0, // RIDE_TYPE_CIRCUS_SHOW
+ 0, // RIDE_TYPE_GHOST_TRAIN
+ 0, // RIDE_TYPE_TWISTER_ROLLER_COASTER
+ 0, // RIDE_TYPE_WOODEN_ROLLER_COASTER
+ 0, // RIDE_TYPE_SIDE_FRICTION_ROLLER_COASTER
+ 0, // RIDE_TYPE_WILD_MOUSE
+ 0, // RIDE_TYPE_MULTI_DIMENSION_ROLLER_COASTER
+ 0, // RIDE_TYPE_38
+ 0, // RIDE_TYPE_FLYING_ROLLER_COASTER
+ 0, // RIDE_TYPE_3A
+ 0, // RIDE_TYPE_VIRGINIA_REEL
+ 0, // RIDE_TYPE_SPLASH_BOATS
+ 0, // RIDE_TYPE_MINI_HELICOPTERS
+ 0, // RIDE_TYPE_LAY_DOWN_ROLLER_COASTER
+ 0, // RIDE_TYPE_SUSPENDED_MONORAIL
+ 0, // RIDE_TYPE_40
+ 0, // RIDE_TYPE_REVERSER_ROLLER_COASTER
+ 0, // RIDE_TYPE_HEARTLINE_TWISTER_COASTER
+ 0, // RIDE_TYPE_MINI_GOLF
+ 0, // RIDE_TYPE_GIGA_COASTER
+ 0, // RIDE_TYPE_ROTO_DROP
+ 0, // RIDE_TYPE_FLYING_SAUCERS
+ 0, // RIDE_TYPE_CROOKED_HOUSE
+ 0, // RIDE_TYPE_MONORAIL_CYCLES
+ 0, // RIDE_TYPE_COMPACT_INVERTED_COASTER
+ 0, // RIDE_TYPE_WATER_COASTER
+ 0, // RIDE_TYPE_AIR_POWERED_VERTICAL_COASTER
+ 0, // RIDE_TYPE_INVERTED_HAIRPIN_COASTER
+ 0, // RIDE_TYPE_MAGIC_CARPET
+ 0, // RIDE_TYPE_SUBMARINE_RIDE
+ 0, // RIDE_TYPE_RIVER_RAFTS
+ 0, // RIDE_TYPE_50
+ 0, // RIDE_TYPE_ENTERPRISE
+ 0, // RIDE_TYPE_52
+ 0, // RIDE_TYPE_53
+ 0, // RIDE_TYPE_54
+ 0, // RIDE_TYPE_55
+ 0, // RIDE_TYPE_INVERTED_IMPULSE_COASTER
+ 0, // RIDE_TYPE_MINI_ROLLER_COASTER
+ 0, // RIDE_TYPE_MINE_RIDE
+ 0, // RIDE_TYPE_59
+ 0, // RIDE_TYPE_LIM_LAUNCHED_ROLLER_COASTER
+};
diff --git a/src/ride/track_data.h b/src/ride/track_data.h
index 1a6010df89..366e642589 100644
--- a/src/ride/track_data.h
+++ b/src/ride/track_data.h
@@ -41,3 +41,4 @@ extern const track_curve_chain gTrackCurveChain[256];
extern const track_curve_chain gFlatRideTrackCurveChain[256];
extern const uint32 RideTypeTrackPaintFunctions[91];
+extern const uint32 RideTypeTrackPaintFunctionsOld[91];
diff --git a/src/ride/track_paint.c b/src/ride/track_paint.c
new file mode 100644
index 0000000000..c923988399
--- /dev/null
+++ b/src/ride/track_paint.c
@@ -0,0 +1,1055 @@
+/*****************************************************************************
+* Copyright (c) 2014 Ted John
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* This file is part of OpenRCT2.
+*
+* OpenRCT2 is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*****************************************************************************/
+
+
+#include "../addresses.h"
+#include "../config.h"
+#include "../drawing/drawing.h"
+#include "../localisation/localisation.h"
+#include "ride_data.h"
+#include "track_data.h"
+#include "../sprites.h"
+#include "../world/map.h"
+#include "../world/sprite.h"
+#include "../interface/viewport.h"
+#include "../interface/window.h"
+#include "track_paint.h"
+
+void top_spin_paint_setup_rot_0(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element* mapElement);
+void top_spin_paint_setup_rot_1(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element* mapElement);
+void top_spin_paint_setup_rot_2(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element* mapElement);
+void top_spin_paint_setup_rot_3(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element* mapElement);
+
+/* 0x0076679C */
+TRACK_PAINT_FUNCTION top_spin_base_functions[] = {
+ top_spin_paint_setup_rot_0,
+ top_spin_paint_setup_rot_1,
+ top_spin_paint_setup_rot_2,
+ top_spin_paint_setup_rot_3,
+};
+
+TRACK_PAINT_FUNCTION* top_spin_track_paint_functions[] = {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ top_spin_base_functions // 123
+};
+
+/* rct2: 0x0076687C */
+void top_spin_paint_tile_0(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element* mapElement) {
+ uint32 image_id = RCT2_GLOBAL(0x00F441A0, uint32);
+ sub_6629BC(height, 0, image_id, direction & 1);
+
+ image_id = 22137 | RCT2_GLOBAL(0x00F44198, uint32);
+
+ RCT2_GLOBAL(0x009DEA52, uint16) = 0;
+ RCT2_GLOBAL(0x009DEA54, uint16) = 0;
+ RCT2_GLOBAL(0x009DEA56, uint16) = height;
+ sub_98197C(0, 1, image_id, 0, height, 32, 32, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32));
+
+ RCT2_GLOBAL(0x141E9B4, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9B8, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9BC, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9C0, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9C4, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9C8, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9CC, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9D0, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9D4, uint16) = 0xFFFF;
+
+ height += 112;
+ if (RCT2_GLOBAL(0x141E9D8, sint16) < height) {
+ RCT2_GLOBAL(0x141E9D8, sint16) = height;
+ RCT2_GLOBAL(0x141E9DA, uint8) = 32;
+ }
+}
+
+/* rct2:0x007667AE */
+rct_xy16 loc_7667AE[] = {
+ { .x = 0, .y = -1 },
+ { .x = 1, .y = 0 },
+ { .x = 0, .y = 1},
+ { .x = -1, .y = 0 },
+};
+
+/* rct2:0x007667AC */
+rct_xy16 loc_7667AC[] = {
+ { .x = -1, .y = 0 },
+ { .x = 0, .y = -1 },
+ { .x = 1, .y = 0 },
+ { .x = 0, .y = 1 },
+};
+
+/* rct2: 0x0076750D */
+void top_spin_paint_vehicle(sint8 al, sint8 cl, uint8 rideIndex, uint8 direction, int height, rct_map_element* mapElement) {
+ // As we will be drawing a vehicle we need to backup the mapElement that
+ // is assigned to the drawings.
+ rct_map_element* curMapElement = RCT2_GLOBAL(0x009DE578, rct_map_element*);
+
+ height += 3;
+
+ rct_ride* ride = GET_RIDE(rideIndex);
+ rct_ride_type* rideEntry = GET_RIDE_ENTRY(ride->subtype);
+ rct_vehicle* vehicle = NULL;
+
+ uint8 seatRotation = 0;
+ sint8 armRotation = 0;
+
+ if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK &&
+ ride->vehicles[0] != SPRITE_INDEX_NULL) {
+ vehicle = GET_VEHICLE(ride->vehicles[0]);
+
+ RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = VIEWPORT_INTERACTION_ITEM_SPRITE;
+ RCT2_GLOBAL(0x009DE578, rct_vehicle*) = vehicle;
+
+ armRotation = vehicle->var_1F;
+ seatRotation = vehicle->var_20;
+ }
+
+ RCT2_GLOBAL(0x009DEA52, sint16) = al + 16;
+ RCT2_GLOBAL(0x009DEA54, sint16) = cl + 16;
+ RCT2_GLOBAL(0x009DEA56, sint16) = height;
+
+ //di
+ uint8 lengthY = 24;
+ //si
+ uint8 lengthX = 24;
+
+ uint32 image_id = RCT2_GLOBAL(0x00F441A0, uint32);
+ if (image_id == 0x20000000) {
+ image_id =
+ 0xA0000000 |
+ (ride->track_colour_main[0] << 19) |
+ (ride->track_colour_supports[0] << 24);
+ }
+
+ image_id += (direction & 1) << 1;
+ image_id += rideEntry->vehicles[0].base_image_id;
+ // Left back bottom support
+ image_id += 572;
+
+ sub_98197C(al, 90, image_id, cl, height, lengthX, lengthY, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32));
+
+ image_id = RCT2_GLOBAL(0x00F441A0, uint32);
+ if (image_id == 0x20000000) {
+ image_id =
+ 0xA0000000 |
+ (ride->track_colour_main[0] << 19) |
+ (ride->track_colour_additional[0] << 24);
+ }
+
+ sint32 var_1F = armRotation;
+ if (direction & 2) {
+ var_1F = -var_1F;
+ if (var_1F != 0)
+ var_1F += 48;
+ }
+ image_id += var_1F;
+ image_id += (direction & 1) * 48;
+ image_id += rideEntry->vehicles[0].base_image_id;
+ // Left hand arm
+ image_id += 380;
+
+ sub_98199C(
+ al,
+ 90,
+ image_id,
+ cl,
+ height,
+ lengthX,
+ lengthY,
+ 0);
+
+ uint32 seatImageId;
+
+ if (vehicle != NULL && vehicle->var_B5 >= 64) {
+ // Open Restraints
+ image_id = (vehicle->var_B5 - 64) >> 6;
+ image_id += direction * 3;
+ image_id += rideEntry->vehicles[0].base_image_id;
+ image_id += 64;
+ seatImageId = image_id;
+ }
+ else {
+ image_id = direction * 16;
+ // Var_20 Rotation of seats
+ image_id += seatRotation;
+ image_id += rideEntry->vehicles[0].base_image_id;
+ seatImageId = image_id;
+ }
+
+ image_id = RCT2_GLOBAL(0x00F441A0, uint32);
+ if (image_id == 0x20000000) {
+ image_id =
+ 0xA0000000 |
+ (ride->vehicle_colours[0].body_colour << 19) |
+ (ride->vehicle_colours[0].trim_colour << 24);
+ }
+ image_id += seatImageId;
+
+ rct_xyz16 seatCoords = {
+ .x = al,
+ .y = cl,
+ .z = height
+ };
+ seatCoords.z += RCT2_ADDRESS(0x14280BC, sint16)[armRotation];
+
+ switch (direction) {
+ case 0:
+ seatCoords.x -= RCT2_ADDRESS(0x0142811C, sint8)[armRotation];
+ break;
+ case 1:
+ seatCoords.y += RCT2_ADDRESS(0x0142811C, sint8)[armRotation];
+ break;
+ case 2:
+ seatCoords.x += RCT2_ADDRESS(0x0142811C, sint8)[armRotation];
+ break;
+ case 3:
+ seatCoords.y -= RCT2_ADDRESS(0x0142811C, sint8)[armRotation];
+ break;
+ }
+
+ RCT2_GLOBAL(0x014280B8, sint8) = (sint8)seatCoords.x;
+ RCT2_GLOBAL(0x014280B9, sint8) = (sint8)seatCoords.y;
+ RCT2_GLOBAL(0x014280BA, sint16) = seatCoords.z;
+
+ sub_98199C(
+ (sint8)seatCoords.x,
+ 90,
+ image_id,
+ (sint8)seatCoords.y,
+ seatCoords.z,
+ lengthX,
+ lengthY,
+ 0);
+
+ rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*);
+ if (dpi->zoom_level < 2 && vehicle != NULL && vehicle->num_peeps != 0) {
+ image_id =
+ (vehicle->peep_tshirt_colours[0] << 19) |
+ (vehicle->peep_tshirt_colours[1] << 24);
+ image_id += seatImageId;
+ image_id += 0xA0000000;
+ image_id += 76;
+
+ sub_98199C((sint8)seatCoords.x, 90, image_id, (sint8)seatCoords.y, seatCoords.z, lengthX, lengthY, 0);
+
+ if (vehicle->num_peeps > 2) {
+ image_id =
+ (vehicle->peep_tshirt_colours[2] << 19) |
+ (vehicle->peep_tshirt_colours[3] << 24);
+ image_id += seatImageId;
+ image_id += 0xA0000000;
+ image_id += 152;
+
+ sub_98199C((sint8)seatCoords.x, 90, image_id, (sint8)seatCoords.y, seatCoords.z, lengthX, lengthY, 0);
+ }
+
+ if (vehicle->num_peeps > 4) {
+ image_id =
+ (vehicle->peep_tshirt_colours[4] << 19) |
+ (vehicle->peep_tshirt_colours[5] << 24);
+ image_id += seatImageId;
+ image_id += 0xA0000000;
+ image_id += 228;
+
+ sub_98199C((sint8)seatCoords.x, 90, image_id, (sint8)seatCoords.y, seatCoords.z, lengthX, lengthY, 0);
+ }
+
+ if (vehicle->num_peeps > 6) {
+ image_id =
+ (vehicle->peep_tshirt_colours[6] << 19) |
+ (vehicle->peep_tshirt_colours[7] << 24);
+ image_id += seatImageId;
+ image_id += 0xA0000000;
+ image_id += 304;
+
+ sub_98199C((sint8)seatCoords.x, 90, image_id, (sint8)seatCoords.y, seatCoords.z, lengthX, lengthY, 0);
+ }
+ }
+
+ image_id = RCT2_GLOBAL(0x00F441A0, uint32);
+ if (image_id == 0x20000000) {
+ image_id =
+ 0xA0000000 |
+ (ride->track_colour_main[0] << 19) |
+ (ride->track_colour_additional[0] << 24);
+ }
+
+ image_id += var_1F;
+ image_id += (direction & 1) * 48;
+ image_id += rideEntry->vehicles[0].base_image_id;
+ // Right hand arm
+ image_id += 476;
+
+ sub_98199C(
+ al,
+ 90,
+ image_id,
+ cl,
+ height,
+ lengthX,
+ lengthY,
+ 0);
+
+ image_id = RCT2_GLOBAL(0x00F441A0, uint32);
+ if (image_id == 0x20000000) {
+ image_id =
+ 0xA0000000 |
+ (ride->track_colour_main[0] << 19) |
+ (ride->track_colour_supports[0] << 24);
+ }
+
+ image_id += (direction & 1) << 1;
+ image_id += rideEntry->vehicles[0].base_image_id;
+ // Right back bottom support
+ image_id += 573;
+
+ sub_98199C(
+ al,
+ 90,
+ image_id,
+ cl,
+ height,
+ lengthX,
+ lengthY,
+ 0);
+
+ RCT2_GLOBAL(0x009DE578, rct_map_element*) = curMapElement;
+ RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = VIEWPORT_INTERACTION_ITEM_RIDE;
+}
+
+/* rct2: 0x0076693F */
+void top_spin_paint_tile_1(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element* mapElement) {
+ uint32 image_id = RCT2_GLOBAL(0x00F441A0, uint32);
+ sub_6629BC(height, 0, image_id, direction & 1);
+
+ image_id = 22137 | RCT2_GLOBAL(0x00F44198, uint32);
+
+ RCT2_GLOBAL(0x009DEA52, uint16) = 0;
+ RCT2_GLOBAL(0x009DEA54, uint16) = 0;
+ RCT2_GLOBAL(0x009DEA56, uint16) = height;
+ sub_98197C(0, 1, image_id, 0, height, 32, 32, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32));
+
+ sint16 x = RCT2_GLOBAL(0x009DE56A, sint16), y = RCT2_GLOBAL(0x009DE56E, sint16);
+ uint16 entranceLoc =
+ ((x / 32) + loc_7667AE[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)].x) |
+ (((y / 32) + loc_7667AE[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)].y) << 8);
+
+ uint8 entranceId = (mapElement->properties.track.sequence & 0x70) >> 4;
+ rct_ride* ride = GET_RIDE(rideIndex);
+
+ if (ride->entrances[entranceId] != entranceLoc && ride->exits[entranceId] != entranceLoc) {
+
+ image_id = 22141 | RCT2_GLOBAL(0x00F441A0, uint32);
+ RCT2_GLOBAL(0x009DEA52, uint16) = 0;
+ RCT2_GLOBAL(0x009DEA54, uint16) = 2;
+ RCT2_GLOBAL(0x009DEA56, uint16) = height + 2;
+
+ sub_98199C(0, 7, image_id, 0, height, 1, 32, 0);
+ }
+
+ entranceLoc =
+ ((x / 32) + loc_7667AC[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)].x) |
+ (((y / 32) + loc_7667AC[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)].y) << 8);
+
+ if (ride->entrances[entranceId] != entranceLoc && ride->exits[entranceId] != entranceLoc) {
+
+ image_id = 22138 | RCT2_GLOBAL(0x00F441A0, uint32);
+ RCT2_GLOBAL(0x009DEA52, uint16) = 0;
+ RCT2_GLOBAL(0x009DEA54, uint16) = 2;
+ RCT2_GLOBAL(0x009DEA56, uint16) = height + 2;
+
+ sub_98199C(0, 7, image_id, 0, height, 32, 1, 0);
+ }
+
+ top_spin_paint_vehicle(32, 32, rideIndex, direction, height, mapElement);
+
+ RCT2_GLOBAL(0x141E9B4, uint16) = height + 2;
+ RCT2_GLOBAL(0x141E9B6, uint16) = 32;
+ RCT2_GLOBAL(0x141E9B8, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9BC, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9C0, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9C4, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9C8, uint16) = height + 2;
+ RCT2_GLOBAL(0x141E9CA, uint16) = 32;
+ RCT2_GLOBAL(0x141E9CC, uint16) = height + 2;
+ RCT2_GLOBAL(0x141E9CE, uint16) = 32;
+ RCT2_GLOBAL(0x141E9D0, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9D4, uint16) = 0xFFFF;
+
+ height += 110;
+ if (RCT2_GLOBAL(0x141E9D8, sint16) < height) {
+ RCT2_GLOBAL(0x141E9D8, sint16) = height;
+ RCT2_GLOBAL(0x141E9DA, uint8) = 32;
+ }
+}
+
+/* rct2: 0x00767033 */
+void top_spin_paint_tile_2(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element* mapElement) {
+ uint32 image_id = RCT2_GLOBAL(0x00F441A0, uint32);
+ sub_6629BC(height, 0, image_id, direction & 1);
+
+ image_id = 22137 | RCT2_GLOBAL(0x00F44198, uint32);
+
+ RCT2_GLOBAL(0x009DEA52, uint16) = 0;
+ RCT2_GLOBAL(0x009DEA54, uint16) = 0;
+ RCT2_GLOBAL(0x009DEA56, uint16) = height;
+ sub_98197C(0, 1, image_id, 0, height, 32, 32, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32));
+
+ sint16 x = RCT2_GLOBAL(0x009DE56A, sint16), y = RCT2_GLOBAL(0x009DE56E, sint16);
+ uint16 entranceLoc =
+ ((x / 32) + loc_7667AC[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)].x) |
+ (((y / 32) + loc_7667AC[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)].y) << 8);
+
+ uint8 entranceId = (mapElement->properties.track.sequence & 0x70) >> 4;
+ rct_ride* ride = GET_RIDE(rideIndex);
+
+ if (ride->entrances[entranceId] != entranceLoc && ride->exits[entranceId] != entranceLoc) {
+
+ image_id = 22138 | RCT2_GLOBAL(0x00F441A0, uint32);
+ RCT2_GLOBAL(0x009DEA52, uint16) = 2;
+ RCT2_GLOBAL(0x009DEA54, uint16) = 0;
+ RCT2_GLOBAL(0x009DEA56, uint16) = height + 2;
+
+ sub_98199C(0, 7, image_id, 0, height, 32, 1, 0);
+ }
+
+ RCT2_GLOBAL(0x141E9B4, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9B8, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9BC, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9C0, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9C4, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9C8, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9CC, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9D0, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9D4, uint16) = 0xFFFF;
+
+ height += 110;
+ if (RCT2_GLOBAL(0x141E9D8, sint16) < height) {
+ RCT2_GLOBAL(0x141E9D8, sint16) = height;
+ RCT2_GLOBAL(0x141E9DA, uint8) = 32;
+ }
+}
+
+/* rct2: 0x0076718D */
+void top_spin_paint_tile_4(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element* mapElement) {
+ uint32 image_id = RCT2_GLOBAL(0x00F441A0, uint32);
+ sub_6629BC(height, 0, image_id, direction & 1);
+
+ image_id = 22137 | RCT2_GLOBAL(0x00F44198, uint32);
+
+ RCT2_GLOBAL(0x009DEA52, uint16) = 0;
+ RCT2_GLOBAL(0x009DEA54, uint16) = 0;
+ RCT2_GLOBAL(0x009DEA56, uint16) = height;
+ sub_98197C(0, 1, image_id, 0, height, 32, 32, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32));
+
+ sint16 x = RCT2_GLOBAL(0x009DE56A, sint16), y = RCT2_GLOBAL(0x009DE56E, sint16);
+ uint16 entranceLoc =
+ ((x / 32) + loc_7667AE[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)].x) |
+ (((y / 32) + loc_7667AE[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)].y) << 8);
+
+ uint8 entranceId = (mapElement->properties.track.sequence & 0x70) >> 4;
+ rct_ride* ride = GET_RIDE(rideIndex);
+
+ if (ride->entrances[entranceId] != entranceLoc && ride->exits[entranceId] != entranceLoc) {
+
+ image_id = 22141 | RCT2_GLOBAL(0x00F441A0, uint32);
+ RCT2_GLOBAL(0x009DEA52, uint16) = 0;
+ RCT2_GLOBAL(0x009DEA54, uint16) = 2;
+ RCT2_GLOBAL(0x009DEA56, uint16) = height + 2;
+
+ sub_98199C(0, 7, image_id, 0, height, 1, 32, 0);
+ }
+
+ RCT2_GLOBAL(0x141E9B4, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9B8, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9BC, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9C0, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9C4, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9C8, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9CC, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9D0, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9D4, uint16) = 0xFFFF;
+
+ height += 110;
+ if (RCT2_GLOBAL(0x141E9D8, sint16) < height) {
+ RCT2_GLOBAL(0x141E9D8, sint16) = height;
+ RCT2_GLOBAL(0x141E9DA, uint8) = 32;
+ }
+}
+
+/* rct2: 0x00766B4C */
+void top_spin_paint_tile_3(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element* mapElement) {
+ uint32 image_id = RCT2_GLOBAL(0x00F441A0, uint32);
+ sub_6629BC(height, 0, image_id, direction & 1);
+
+ image_id = 22136 | RCT2_GLOBAL(0x00F44198, uint32);
+
+ RCT2_GLOBAL(0x009DEA52, uint16) = 0;
+ RCT2_GLOBAL(0x009DEA54, uint16) = 0;
+ RCT2_GLOBAL(0x009DEA56, uint16) = height;
+ sub_98197C(0, 1, image_id, 0, height, 32, 32, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32));
+
+ sint16 x = RCT2_GLOBAL(0x009DE56A, sint16), y = RCT2_GLOBAL(0x009DE56E, sint16);
+ uint16 entranceLoc =
+ ((x / 32) + loc_7667AC[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)].x) |
+ (((y / 32) + loc_7667AC[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)].y) << 8);
+
+ uint8 entranceId = (mapElement->properties.track.sequence & 0x70) >> 4;
+ rct_ride* ride = GET_RIDE(rideIndex);
+
+ if (ride->entrances[entranceId] != entranceLoc && ride->exits[entranceId] != entranceLoc) {
+
+ image_id = 22138 | RCT2_GLOBAL(0x00F441A0, uint32);
+ RCT2_GLOBAL(0x009DEA52, uint16) = 2;
+ RCT2_GLOBAL(0x009DEA54, uint16) = 0;
+ RCT2_GLOBAL(0x009DEA56, uint16) = height + 2;
+
+ sub_98199C(0, 7, image_id, 0, height, 32, 1, 0);
+ }
+
+ entranceLoc =
+ ((x / 32) + loc_7667AC[(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32) + 3) & 3].x) |
+ (((y / 32) + loc_7667AC[(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32) + 3) & 3].y) << 8);
+
+ if (ride->entrances[entranceId] != entranceLoc && ride->exits[entranceId] != entranceLoc) {
+
+ image_id = 22139 | RCT2_GLOBAL(0x00F441A0, uint32);
+
+ RCT2_GLOBAL(0x009DEA52, uint16) = 0;
+ RCT2_GLOBAL(0x009DEA54, uint16) = 30;
+ RCT2_GLOBAL(0x009DEA56, uint16) = height + 2;
+ sub_98197C(0, 7, image_id, 0, height, 1, 32, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32));
+ }
+
+ top_spin_paint_vehicle(32, -32, rideIndex, direction, height, mapElement);
+
+ RCT2_GLOBAL(0x141E9B4, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9B8, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9BC, uint16) = height + 2;
+ RCT2_GLOBAL(0x141E9BE, uint16) = 32;
+ RCT2_GLOBAL(0x141E9C0, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9C4, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9C8, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9CC, uint16) = height + 2;
+ RCT2_GLOBAL(0x141E9CE, uint16) = 32;
+ RCT2_GLOBAL(0x141E9D0, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9D4, uint16) = height + 2;
+ RCT2_GLOBAL(0x141E9D6, uint16) = 32;
+
+ height += 110;
+ if (RCT2_GLOBAL(0x141E9D8, sint16) < height) {
+ RCT2_GLOBAL(0x141E9D8, sint16) = height;
+ RCT2_GLOBAL(0x141E9DA, uint8) = 32;
+ }
+}
+
+/* rct2: 0x007672E7 */
+void top_spin_paint_tile_5(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element* mapElement) {
+ uint32 image_id = RCT2_GLOBAL(0x00F441A0, uint32);
+ sub_6629BC(height, 0, image_id, direction & 1);
+
+ image_id = 22136 | RCT2_GLOBAL(0x00F44198, uint32);
+
+ RCT2_GLOBAL(0x009DEA52, uint16) = 0;
+ RCT2_GLOBAL(0x009DEA54, uint16) = 0;
+ RCT2_GLOBAL(0x009DEA56, uint16) = height;
+ sub_98197C(0, 1, image_id, 0, height, 32, 32, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32));
+
+ sint16 x = RCT2_GLOBAL(0x009DE56A, sint16), y = RCT2_GLOBAL(0x009DE56E, sint16);
+ uint8 entranceId = (mapElement->properties.track.sequence & 0x70) >> 4;
+ rct_ride* ride = GET_RIDE(rideIndex);
+
+ uint16 entranceLoc =
+ ((x / 32) + loc_7667AC[(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32) + 3) & 3].x) |
+ (((y / 32) + loc_7667AC[(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32) + 3) & 3].y) << 8);
+
+ if (ride->entrances[entranceId] != entranceLoc && ride->exits[entranceId] != entranceLoc) {
+ image_id = 22139 | RCT2_GLOBAL(0x00F441A0, uint32);
+
+ RCT2_GLOBAL(0x009DEA52, uint16) = 0;
+ RCT2_GLOBAL(0x009DEA54, uint16) = 30;
+ RCT2_GLOBAL(0x009DEA56, uint16) = height + 2;
+ sub_98197C(0, 7, image_id, 0, height, 1, 32, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32));
+ }
+
+ top_spin_paint_vehicle(0, -32, rideIndex, direction, height, mapElement);
+
+ RCT2_GLOBAL(0x141E9B4, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9B8, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9BC, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9C0, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9C4, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9C8, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9CC, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9D0, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9D4, uint16) = 0xFFFF;
+
+ height += 112;
+ if (RCT2_GLOBAL(0x141E9D8, sint16) < height) {
+ RCT2_GLOBAL(0x141E9D8, sint16) = height;
+ RCT2_GLOBAL(0x141E9DA, uint8) = 32;
+ }
+}
+
+/* rct2: 0x00766D09 */
+void top_spin_paint_tile_6(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element* mapElement) {
+ uint32 image_id = RCT2_GLOBAL(0x00F441A0, uint32);
+ sub_6629BC(height, 0, image_id, direction & 1);
+
+ image_id = 22135 | RCT2_GLOBAL(0x00F44198, uint32);
+
+ RCT2_GLOBAL(0x009DEA52, uint16) = 0;
+ RCT2_GLOBAL(0x009DEA54, uint16) = 0;
+ RCT2_GLOBAL(0x009DEA56, uint16) = height;
+ sub_98197C(0, 1, image_id, 0, height, 32, 32, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32));
+
+ sint16 x = RCT2_GLOBAL(0x009DE56A, sint16), y = RCT2_GLOBAL(0x009DE56E, sint16);
+ uint16 entranceLoc =
+ ((x / 32) + loc_7667AE[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)].x) |
+ (((y / 32) + loc_7667AE[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)].y) << 8);
+
+ uint8 entranceId = (mapElement->properties.track.sequence & 0x70) >> 4;
+ rct_ride* ride = GET_RIDE(rideIndex);
+
+ if (ride->entrances[entranceId] != entranceLoc && ride->exits[entranceId] != entranceLoc) {
+
+ image_id = 22141 | RCT2_GLOBAL(0x00F441A0, uint32);
+ RCT2_GLOBAL(0x009DEA52, uint16) = 0;
+ RCT2_GLOBAL(0x009DEA54, uint16) = 2;
+ RCT2_GLOBAL(0x009DEA56, uint16) = height + 2;
+
+ sub_98199C(0, 7, image_id, 0, height, 1, 32, 0);
+ }
+
+ entranceLoc =
+ ((x / 32) + loc_7667AE[(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32) + 1) & 3].x) |
+ (((y / 32) + loc_7667AE[(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32) + 1) & 3].y) << 8);
+
+ if (ride->entrances[entranceId] != entranceLoc && ride->exits[entranceId] != entranceLoc) {
+
+ image_id = 22140 | RCT2_GLOBAL(0x00F441A0, uint32);
+ RCT2_GLOBAL(0x009DEA52, uint16) = 30;
+ RCT2_GLOBAL(0x009DEA54, uint16) = 2;
+ RCT2_GLOBAL(0x009DEA56, uint16) = height + 2;
+
+ sub_98197C(0, 7, image_id, 0, height, 32, 1, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32));
+ }
+
+ top_spin_paint_vehicle(-32, 32, rideIndex, direction, height, mapElement);
+
+ RCT2_GLOBAL(0x141E9B4, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9B8, uint16) = height + 2;
+ RCT2_GLOBAL(0x141E9BA, uint16) = 32;
+ RCT2_GLOBAL(0x141E9BC, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9C0, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9C4, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9C8, uint16) = height + 2;
+ RCT2_GLOBAL(0x141E9CA, uint16) = 32;
+ RCT2_GLOBAL(0x141E9CC, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9D0, uint16) = height + 2;
+ RCT2_GLOBAL(0x141E9D0, uint16) = 32;
+ RCT2_GLOBAL(0x141E9D4, uint16) = 0xFFFF;
+
+ height += 110;
+ if (RCT2_GLOBAL(0x141E9D8, sint16) < height) {
+ RCT2_GLOBAL(0x141E9D8, sint16) = height;
+ RCT2_GLOBAL(0x141E9DA, uint8) = 32;
+ }
+}
+
+/* rct2: 0x00766EC6 */
+void top_spin_paint_tile_7(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element* mapElement) {
+ uint32 image_id = RCT2_GLOBAL(0x00F441A0, uint32);
+ sub_6629BC(height, 0, image_id, direction & 1);
+
+ image_id = 22134 | RCT2_GLOBAL(0x00F44198, uint32);
+
+ RCT2_GLOBAL(0x009DEA52, uint16) = 0;
+ RCT2_GLOBAL(0x009DEA54, uint16) = 0;
+ RCT2_GLOBAL(0x009DEA56, uint16) = height;
+ sub_98197C(0, 1, image_id, 0, height, 32, 32, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32));
+
+ sint16 x = RCT2_GLOBAL(0x009DE56A, sint16), y = RCT2_GLOBAL(0x009DE56E, sint16);
+ uint8 entranceId = (mapElement->properties.track.sequence & 0x70) >> 4;
+ rct_ride* ride = GET_RIDE(rideIndex);
+
+ uint16 entranceLoc =
+ ((x / 32) + loc_7667AE[(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32) + 1) & 3].x) |
+ (((y / 32) + loc_7667AE[(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32) + 1) & 3].y) << 8);
+
+ if (ride->entrances[entranceId] != entranceLoc && ride->exits[entranceId] != entranceLoc) {
+
+ image_id = 22140 | RCT2_GLOBAL(0x00F441A0, uint32);
+
+ RCT2_GLOBAL(0x009DEA52, uint16) = 29;
+ RCT2_GLOBAL(0x009DEA54, uint16) = 0;
+ RCT2_GLOBAL(0x009DEA56, uint16) = height + 3;
+ sub_98197C(0, 7, image_id, 0, height, 28, 1, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32));
+ }
+
+ entranceLoc =
+ ((x / 32) + loc_7667AC[(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32) + 3) & 3].x) |
+ (((y / 32) + loc_7667AC[(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32) + 3) & 3].y) << 8);
+
+ if (ride->entrances[entranceId] != entranceLoc && ride->exits[entranceId] != entranceLoc) {
+
+ image_id = 22139 | RCT2_GLOBAL(0x00F441A0, uint32);
+
+ RCT2_GLOBAL(0x009DEA52, uint16) = 0;
+ RCT2_GLOBAL(0x009DEA54, uint16) = 29;
+ RCT2_GLOBAL(0x009DEA56, uint16) = height + 3;
+ sub_98197C(0, 7, image_id, 0, height, 1, 28, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32));
+ }
+
+ top_spin_paint_vehicle(-32, -32, rideIndex, direction, height, mapElement);
+
+ RCT2_GLOBAL(0x141E9B4, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9B8, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9BC, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9C0, uint16) = height + 2;
+ RCT2_GLOBAL(0x141E9C2, uint16) = 32;
+ RCT2_GLOBAL(0x141E9C4, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9C8, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9CC, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9D0, uint16) = height + 2;
+ RCT2_GLOBAL(0x141E9D2, uint16) = 32;
+ RCT2_GLOBAL(0x141E9D4, uint16) = height + 2;
+ RCT2_GLOBAL(0x141E9D6, uint16) = 32;
+
+ height += 110;
+ if (RCT2_GLOBAL(0x141E9D8, sint16) < height) {
+ RCT2_GLOBAL(0x141E9D8, sint16) = height;
+ RCT2_GLOBAL(0x141E9DA, uint8) = 32;
+ }
+}
+
+/* rct2: 0x007673FA */
+void top_spin_paint_tile_8(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element* mapElement) {
+ uint32 image_id = RCT2_GLOBAL(0x00F441A0, uint32);
+ sub_6629BC(height, 0, image_id, direction & 1);
+
+ image_id = 22135 | RCT2_GLOBAL(0x00F44198, uint32);
+
+ RCT2_GLOBAL(0x009DEA52, uint16) = 0;
+ RCT2_GLOBAL(0x009DEA54, uint16) = 0;
+ RCT2_GLOBAL(0x009DEA56, uint16) = height;
+ sub_98197C(0, 1, image_id, 0, height, 32, 32, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32));
+
+ sint16 x = RCT2_GLOBAL(0x009DE56A, sint16), y = RCT2_GLOBAL(0x009DE56E, sint16);
+ uint8 entranceId = (mapElement->properties.track.sequence & 0x70) >> 4;
+ rct_ride* ride = GET_RIDE(rideIndex);
+
+ uint16 entranceLoc =
+ ((x / 32) + loc_7667AE[(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32) + 1) & 3].x) |
+ (((y / 32) + loc_7667AE[(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32) + 1) & 3].y) << 8);
+
+ if (ride->entrances[entranceId] != entranceLoc && ride->exits[entranceId] != entranceLoc) {
+
+ image_id = 22140 | RCT2_GLOBAL(0x00F441A0, uint32);
+ RCT2_GLOBAL(0x009DEA52, uint16) = 30;
+ RCT2_GLOBAL(0x009DEA54, uint16) = 0;
+ RCT2_GLOBAL(0x009DEA56, uint16) = height + 2;
+
+ sub_98197C(0, 7, image_id, 0, height, 32, 1, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32));
+ }
+ top_spin_paint_vehicle(-32, 0, rideIndex, direction, height, mapElement);
+
+ RCT2_GLOBAL(0x141E9B4, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9B8, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9BC, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9C0, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9C4, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9C8, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9CC, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9D0, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x141E9D4, uint16) = 0xFFFF;
+
+ height += 112;
+ if (RCT2_GLOBAL(0x141E9D8, sint16) < height) {
+ RCT2_GLOBAL(0x141E9D8, sint16) = height;
+ RCT2_GLOBAL(0x141E9DA, uint8) = 32;
+ }
+}
+
+/* rct2: 0x007667BC
+ */
+void top_spin_paint_setup_rot_0(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element* mapElement) {
+ switch (trackSequence)
+ {
+ case 0:
+ top_spin_paint_tile_0(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 1:
+ top_spin_paint_tile_1(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 2:
+ top_spin_paint_tile_2(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 3:
+ top_spin_paint_tile_3(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 4:
+ top_spin_paint_tile_4(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 5:
+ top_spin_paint_tile_5(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 6:
+ top_spin_paint_tile_6(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 7:
+ top_spin_paint_tile_7(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 8:
+ top_spin_paint_tile_8(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ }
+ return;
+}
+
+/* rct2: 0x007667EC
+*/
+void top_spin_paint_setup_rot_1(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element* mapElement) {
+ switch (trackSequence)
+ {
+ case 0:
+ top_spin_paint_tile_0(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 1:
+ top_spin_paint_tile_3(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 2:
+ top_spin_paint_tile_5(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 3:
+ top_spin_paint_tile_7(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 4:
+ top_spin_paint_tile_2(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 5:
+ top_spin_paint_tile_8(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 6:
+ top_spin_paint_tile_1(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 7:
+ top_spin_paint_tile_6(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 8:
+ top_spin_paint_tile_4(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ }
+ return;
+}
+
+/* rct2: 0x0076681C
+*/
+void top_spin_paint_setup_rot_2(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element* mapElement) {
+ switch (trackSequence)
+ {
+ case 0:
+ top_spin_paint_tile_0(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 1:
+ top_spin_paint_tile_7(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 2:
+ top_spin_paint_tile_8(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 3:
+ top_spin_paint_tile_6(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 4:
+ top_spin_paint_tile_5(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 5:
+ top_spin_paint_tile_4(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 6:
+ top_spin_paint_tile_3(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 7:
+ top_spin_paint_tile_1(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 8:
+ top_spin_paint_tile_2(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ }
+ return;
+}
+
+/* rct2: 0x0076684C
+*/
+void top_spin_paint_setup_rot_3(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element* mapElement) {
+ switch (trackSequence)
+ {
+ case 0:
+ top_spin_paint_tile_0(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 1:
+ top_spin_paint_tile_6(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 2:
+ top_spin_paint_tile_4(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 3:
+ top_spin_paint_tile_1(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 4:
+ top_spin_paint_tile_8(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 5:
+ top_spin_paint_tile_2(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 6:
+ top_spin_paint_tile_7(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 7:
+ top_spin_paint_tile_3(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ case 8:
+ top_spin_paint_tile_5(rideIndex, trackSequence, direction, height, mapElement);
+ break;
+ }
+ return;
+}
\ No newline at end of file
diff --git a/src/ride/track_paint.h b/src/ride/track_paint.h
new file mode 100644
index 0000000000..f020078c8a
--- /dev/null
+++ b/src/ride/track_paint.h
@@ -0,0 +1,10 @@
+#ifndef _TRACK_PAINT_H
+#define _TRACK_PAINT_H
+
+#include "../common.h"
+
+typedef void (*TRACK_PAINT_FUNCTION)(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element* mapElement);
+
+extern TRACK_PAINT_FUNCTION* top_spin_track_paint_functions[];
+
+#endif
\ No newline at end of file