diff --git a/openrct2.vcxproj b/openrct2.vcxproj
index e42016b61d..53dad229d7 100644
--- a/openrct2.vcxproj
+++ b/openrct2.vcxproj
@@ -49,7 +49,6 @@
-
@@ -57,8 +56,6 @@
-
-
@@ -90,6 +87,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -102,14 +113,90 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -233,7 +320,6 @@
-
@@ -241,8 +327,6 @@
-
-
@@ -270,6 +354,11 @@
+
+
+
+
+
@@ -287,6 +376,7 @@
+
@@ -412,4 +502,4 @@
-
+
\ No newline at end of file
diff --git a/openrct2.vcxproj.filters b/openrct2.vcxproj.filters
index 2a85bbab5b..8a5673ba04 100644
--- a/openrct2.vcxproj.filters
+++ b/openrct2.vcxproj.filters
@@ -1,941 +1,396 @@
-
- {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
- rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
-
-
- {4c8348c7-dfe9-4368-9d87-29733fe5950a}
-
-
- {8e15cd5b-d7a7-4bda-a58a-e1158ad6ffb4}
-
-
- {8a9b8831-4ba9-4104-b13f-949981e10c22}
-
-
- {97950d17-f655-49bb-85f4-309feb332b02}
-
-
- {9ac1caf2-4edc-4237-b441-16cc8923d9e3}
-
-
- {7f7d04b9-188e-4086-a2a2-5b7b2eb2310b}
-
-
- {22415bda-c4d8-425c-bd06-4c5bbdffe6d7}
-
-
- {3af99868-3e47-4832-bf01-409aec0b08e7}
-
-
- {2f881d9d-1f7e-40bf-ad3d-92db3a31ce90}
-
-
- {6c8e1ad1-9d13-41f8-a9db-64501ad65503}
-
-
- {81716f5d-b396-4a82-a450-76fee56d982b}
-
-
- {51e38783-5334-464c-8f90-61d725dc8013}
-
-
- {ae88ed08-902b-4167-a78c-9b521ce67749}
-
-
- {28a808eb-9017-44cc-939b-f828fd1e2e7d}
-
-
- {4bf369d2-3df8-40c9-a878-f484b0a0afd3}
-
-
- {f59cd7d6-b58d-4a6f-9118-34f94de84766}
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
- Resource Files
-
-
- Resource Files
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
- Source\Management
-
-
- Source\Management
-
-
- Source\Management
-
-
- Source\Management
-
-
- Source\Audio
-
-
- Source\Audio
-
-
- Source\Interface
-
-
- Source\Interface
-
-
- Source\Interface
-
-
- Source\Interface
-
-
- Source\Interface
-
-
- Source\World
-
-
- Source\World
-
-
- Source\World
-
-
- Source\World
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Localisation
-
-
- Source\Ride
-
-
- Source\Ride
-
-
- Source\Ride
-
-
- Source\Ride
-
-
- Source\Ride
-
-
- Source\Util
-
-
- Source\Util
-
-
- Source
-
-
- Source
-
-
- Source
-
-
- Source
-
-
- Source
-
-
- Source
-
-
- Source
-
-
- Source
-
-
- Source
-
-
- Source
-
-
- Source
-
-
- Source\Localisation
-
-
- Source\Drawing
-
-
- Source\Drawing
-
-
- Source\Drawing
-
-
- Source\Drawing
-
-
- Source\Drawing
-
-
- Source\Localisation
-
-
- Source\Platform
-
-
- Source\Platform
-
-
- Source\Platform
-
-
- Source\Localisation
-
-
- Source\Peep
-
-
- Source\Peep
-
-
- Source\Management
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Drawing
-
-
- Source
-
-
- Source\World
-
-
- Source\World
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Ride
-
-
- Source\Windows
-
-
- Source\Interface
-
-
- Source\Interface
-
-
- Source\World
-
-
- Source
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Localisation
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\World
-
-
- Source\World
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Ride
-
-
- Source
-
-
- Source\Windows
-
-
- Source
-
-
- Source\Windows
-
-
- Source\World
-
-
- Source\World
-
-
- Source
-
-
- Source\Windows
-
-
- Source
-
-
- Source\Windows
-
-
- Source\Interface
-
-
- Source\Network
-
-
- Source\Network
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Interface
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source
-
-
- Source\Localisation
-
-
- Source\Drawing
-
-
- Source\Drawing
-
-
- Source\Localisation
-
-
- Source\Network
-
-
- Source\Windows
-
-
- Source\Interface
-
-
- Source\Windows
-
-
- Source\World
-
-
- Source\World
-
-
- Source\World
-
-
- Source\World
-
-
- Source\Localisation
-
-
- Source\Localisation
-
-
- Source\Ride
-
-
- Source\Platform
-
-
- Source\Windows
-
-
- Source\Interface
-
-
- Source
-
-
- Source\Ride
-
-
- Source\Drawing
-
-
- Source\Windows
-
-
- Source
-
-
- Source
-
-
- Source\Core
-
-
- Source\CommandLine
-
-
- Source\CommandLine
-
-
- Source\CommandLine
-
-
- Source\CommandLine
-
-
- Source\Core
-
-
- Source\Core
-
-
- Source\Core
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Interface
-
-
- Source\Drawing
-
-
- Source\Core
-
-
- Source\Core
-
-
- Source\Core
-
-
- Source\Platform
-
-
- Source\Core
-
-
- Source\Windows
-
-
- Source\RCT1
-
-
- Source\RCT1
-
-
- Source\CommandLine
-
-
-
+
-
- Source\Management
-
-
- Source\Management
-
-
- Source\Management
-
-
- Source\Management
-
-
- Source\Audio
-
-
- Source\Audio
-
-
- Source\Interface
-
-
- Source\Interface
-
-
- Source\Interface
-
-
- Source\Interface
-
-
- Source\Interface
-
-
- Source\World
-
-
- Source\World
-
-
- Source\World
-
-
- Source\World
-
-
- Source\World
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Windows
-
-
- Source\Localisation
-
-
- Source\Localisation
-
-
- Source\Localisation
-
-
- Source\Ride
-
-
- Source\Ride
-
-
- Source\Ride
-
-
- Source\Ride
-
-
- Source\Ride
-
-
- Source\Util
-
-
- Source\Util
-
-
- Source
-
-
- Source
-
-
- Source
-
-
- Source
-
-
- Source
-
-
- Source
-
-
- Source
-
-
- Source
-
-
- Source
-
-
- Source
-
-
- Source
-
-
- Source
-
-
- Source
-
-
- Source\Localisation
-
-
- Source\Drawing
-
-
- Source
-
-
- Source\Localisation
-
-
- Source\Platform
-
-
- Source\Localisation
-
-
- Source\Peep
-
-
- Source\Peep
-
-
- Source\Management
-
-
- Source
-
-
- Source\World
-
-
- Source\Ride
-
-
- Source\Interface
-
-
- Source\World
-
-
- Source
-
-
- Source
-
-
- Source\World
-
-
- Source\World
-
-
- Source\Ride
-
-
- Source\World
-
-
- Source\World
-
-
- Source\World
-
-
- Source\World
-
-
- Source\Interface
-
-
- Source\Network
-
-
- Source\Network
-
-
- Source\Interface
-
-
- Source\Interface
-
-
- Source
-
-
- Source\Drawing
-
-
- Source\Network
-
-
- Source\Interface
-
-
- Source\Core
-
-
- Source\Core
-
-
- Source\Core
-
-
- Source\Core
-
-
- Source\Localisation
-
-
- Source\Core
-
-
- Source\Core
-
-
- Source\Core
-
-
- Source\Core
-
-
- Source\Ride
-
-
- Source\Interface
-
-
- Source\Ride
-
-
- Source\Core
-
-
- Source\Drawing
-
-
- Source
-
-
- Source\Core
-
-
- Source
-
-
- Source\Core
-
-
- Source\Core
-
-
- Source\CommandLine
-
-
- Source\Core
-
-
- Source\Core
-
-
- Source\Core
-
-
- Source\Core
-
-
- Source\Platform
-
-
- Source\Core
-
-
- Source\Core
-
-
- Source\Core
-
-
- Source\Core
-
-
- Source\RCT1
-
-
- Resource Files
-
-
- Source\RCT1
-
-
-
+
-
- Resource Files
-
+
+
-
-
- Resource Files
-
-
-
+
\ No newline at end of file
diff --git a/src/interface/viewport.c b/src/interface/viewport.c
index ef5dffc771..26b5fec266 100644
--- a/src/interface/viewport.c
+++ b/src/interface/viewport.c
@@ -17,7 +17,7 @@
#include "../addresses.h"
#include "../config.h"
#include "../drawing/drawing.h"
-#include "../drawing/supports.h"
+#include "../paint/supports.h"
#include "../game.h"
#include "../input.h"
#include "../localisation/localisation.h"
@@ -31,9 +31,8 @@
#include "../world/entrance.h"
#include "../world/footpath.h"
#include "../world/scenery.h"
-#include "paint_surface.h"
#include "colour.h"
-#include "paint.h"
+#include "../paint/paint.h"
#include "viewport.h"
#include "window.h"
@@ -697,1503 +696,6 @@ void viewport_render(rct_drawpixelinfo *dpi, rct_viewport *viewport, int left, i
#endif
}
-/**
- *
- * rct2: 0x006D5FAB
- */
-static void vehicle_visual_launched_freefall(int x, int imageDirection, int y, int z, rct_vehicle *vehicle, const rct_ride_entry_vehicle *vehicleEntry)
-{
- int image_id;
- int baseImage_id = vehicleEntry->base_image_id + ((vehicle->restraints_position / 64) * 2);
-
- // Draw back:
- image_id = (baseImage_id + 2) | (vehicle->colours.body_colour << 19) | (vehicle->colours.trim_colour << 24) | 0xA0000000;
- sub_98197C(image_id, 0, 0, 2, 2, 41, z, -11, -11, z + 1, get_current_rotation());
-
- // Draw front:
- image_id = (baseImage_id + 1) | (vehicle->colours.body_colour << 19) | (vehicle->colours.trim_colour << 24) | 0xA0000000;
- sub_98197C(image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1, get_current_rotation());
-
- // Draw peeps:
- if (RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*)->zoom_level < 2) {
- if (vehicle->num_peeps > 0) {
- baseImage_id = vehicleEntry->base_image_id + 9;
- if ((vehicle->restraints_position / 64) == 3) {
- baseImage_id += 2; // Draw peeps sitting without transparent area between them for restraints
- }
- image_id = (baseImage_id + ((((imageDirection / 8) + 0) & 3) * 3)) | (vehicle->peep_tshirt_colours[0] << 19) | (vehicle->peep_tshirt_colours[1] << 24) | 0xA0000000;
- sub_98199C(image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1, get_current_rotation());
- if (vehicle->num_peeps > 2) {
- image_id = (baseImage_id + ((((imageDirection / 8) + 1) & 3) * 3)) | (vehicle->peep_tshirt_colours[2] << 19) | (vehicle->peep_tshirt_colours[3] << 24) | 0xA0000000;
- sub_98199C(image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1, get_current_rotation());
- }
- if (vehicle->num_peeps > 4) {
- image_id = (baseImage_id + ((((imageDirection / 8) + 2) & 3) * 3)) | (vehicle->peep_tshirt_colours[4] << 19) | (vehicle->peep_tshirt_colours[5] << 24) | 0xA0000000;
- sub_98199C(image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1, get_current_rotation());
- }
- if (vehicle->num_peeps > 6) {
- image_id = (baseImage_id + ((((imageDirection / 8) + 3) & 3) * 3)) | (vehicle->peep_tshirt_colours[6] << 19) | (vehicle->peep_tshirt_colours[7] << 24) | 0xA0000000;
- sub_98199C(image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1, get_current_rotation());
- }
- }
- }
-
- assert(vehicleEntry->pad_5E == 1);
-}
-
-/**
- *
- * rct2: 0x006D6258
- */
-static void vehicle_visual_observation_tower(int x, int imageDirection, int y, int z, rct_vehicle *vehicle, const rct_ride_entry_vehicle *vehicleEntry)
-{
- int image_id;
- int baseImage_id = (vehicle->restraints_position / 64);
- if (vehicle->restraints_position >= 64) {
- if ((imageDirection / 8) && (imageDirection / 8) != 3) {
- baseImage_id *= 2;
- baseImage_id += vehicleEntry->base_image_id + 28;
- if ((imageDirection / 8) != 1) {
- baseImage_id -= 6;
- }
- } else {
- baseImage_id = vehicleEntry->base_image_id + 8;
- }
- } else {
- baseImage_id = (vehicle->var_C5 * 2) + vehicleEntry->base_image_id + 8;
- }
-
- image_id = baseImage_id | (vehicle->colours.body_colour << 19) | (vehicle->colours.trim_colour << 24) | 0x80000000;
- if (sub_98197C(image_id, 0, 0, 2, 2, 41, z, -11, -11, z + 1, get_current_rotation())) {
- paint_struct* ps = RCT2_GLOBAL(0xEE7888, paint_struct*) - 1; // sub_98197C increments this but need original
- ps->var_04 = vehicle->colours_extended;
- }
-
- image_id++;
- if (sub_98197C(image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1, get_current_rotation())) {
- paint_struct* ps = RCT2_GLOBAL(0xEE7888, paint_struct*) - 1; // sub_98197C increments this but need original
- ps->var_04 = vehicle->colours_extended;
- }
-
- assert(vehicleEntry->pad_5E == 1);
-}
-
-/**
- *
- * rct2: 0x006D5DA9
- */
-static void vehicle_visual_roto_drop(int x, int imageDirection, int y, int z, rct_vehicle *vehicle, const rct_ride_entry_vehicle *vehicleEntry)
-{
- int image_id;
- int baseImage_id = (vehicleEntry->base_image_id + 4) + ((vehicle->var_C5 / 4) & 0x3);
- if (vehicle->restraints_position >= 64) {
- baseImage_id += 7;
- baseImage_id += (vehicle->restraints_position / 64);
- }
-
- // Draw back:
- image_id = baseImage_id | (vehicle->colours.body_colour << 19) | (vehicle->colours.trim_colour << 24) | 0xA0000000;
- sub_98197C(image_id, 0, 0, 2, 2, 41, z, -11, -11, z + 1, get_current_rotation());
-
- // Draw front:
- image_id = (baseImage_id + 4) | (vehicle->colours.body_colour << 19) | (vehicle->colours.trim_colour << 24) | 0xA0000000;
- sub_98197C(image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1, get_current_rotation());
-
- uint8 riding_peep_sprites[64];
- memset(riding_peep_sprites, 0xFF, sizeof(riding_peep_sprites));
- for (int i = 0; i < vehicle->num_peeps; i++) {
- uint8 cl = (i & 3) * 16;
- cl += (i & 0xFC);
- cl += vehicle->var_C5 / 4;
- cl += (imageDirection / 8) * 16;
- cl &= 0x3F;
- riding_peep_sprites[cl] = vehicle->peep_tshirt_colours[i];
- }
-
- // Draw riding peep sprites in back to front order:
- for (int j = 0; j <= 48; j++) {
- int i = (j % 2) ? (48 - (j / 2)) : (j / 2);
- if (riding_peep_sprites[i] != 0xFF) {
- baseImage_id = vehicleEntry->base_image_id + 20 + i;
- if (vehicle->restraints_position >= 64) {
- baseImage_id += 64;
- baseImage_id += vehicle->restraints_position / 64;
- }
- image_id = baseImage_id | (riding_peep_sprites[i] << 19) | 0x20000000;
- sub_98199C(image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1, get_current_rotation());
- }
- };
-
- assert(vehicleEntry->pad_5E == 1);
- // 0x5E is treated as another car_visual paint setup jump table like in viewport_vehicle_paint_setup
- // in the original code right here but appears to only ever be 1 which goes to a nullsub so it was taken out.
-}
-
-/**
- *
- * rct2: 0x006D5B48
- */
-static void vehicle_visual_virginia_reel(int x, int imageDirection, int y, int z, rct_vehicle *vehicle, const rct_ride_entry_vehicle *vehicleEntry)
-{
- int image_id;
- int baseImage_id = imageDirection;
- int ecx = ((vehicle->var_BA / 8) + (get_current_rotation() * 8)) & 31;
- int j = 0;
- if (vehicle->vehicle_sprite_type == 0) {
- baseImage_id = ecx & 7;
- } else {
- if (vehicle->vehicle_sprite_type == 1 || vehicle->vehicle_sprite_type == 5) {
- if (vehicle->vehicle_sprite_type == 5){
- baseImage_id = imageDirection ^ 16;
- }
- baseImage_id &= 24;
- j = (baseImage_id / 8) + 1;
- baseImage_id += (ecx & 7);
- baseImage_id += 8;
- } else
- if (vehicle->vehicle_sprite_type == 2 || vehicle->vehicle_sprite_type == 6) {
- if (vehicle->vehicle_sprite_type == 6){
- baseImage_id = imageDirection ^ 16;
- }
- baseImage_id &= 24;
- j = (baseImage_id / 8) + 5;
- baseImage_id += (ecx & 7);
- baseImage_id += 40;
- } else {
- baseImage_id = ecx & 7;
- }
- }
- baseImage_id += vehicleEntry->base_image_id;
-
- sint16 bbo_x = RCT2_ADDRESS(0x009927E6, sint8)[j * 8];
- sint16 bbo_y = RCT2_ADDRESS(0x009927E7, sint8)[j * 8];
- sint16 bbo_z = RCT2_ADDRESS(0x009927E8, sint8)[j * 8] + z;
- uint16 bbl_x = RCT2_ADDRESS(0x009927E9, uint8)[j * 8];
- uint16 bbl_y = RCT2_ADDRESS(0x009927EA, uint8)[j * 8];
- uint8 bbl_z = RCT2_ADDRESS(0x009927EB, uint8)[j * 8];
- image_id = baseImage_id | (vehicle->colours.body_colour << 19) | (vehicle->colours.trim_colour << 24) | 0xA0000000;
- sub_98197C(image_id, 0, 0, bbl_x, bbl_y, bbl_z, z, bbo_x, bbo_y, bbo_z, get_current_rotation());
-
- if (RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*)->zoom_level < 2 && vehicle->num_peeps > 0) {
- uint8 riding_peep_sprites[4] = {0xFF, 0xFF, 0xFF, 0xFF};
- for (int i = 0; i < vehicle->num_peeps; i++) {
- riding_peep_sprites[((ecx / 8) + i) & 3] = vehicle->peep_tshirt_colours[i];
- }
- int draw_order[4] = {0, 1, 3, 2};
- for (int i = 0; i < countof(draw_order); i++) {
- if (riding_peep_sprites[draw_order[i]] != 0xFF) {
- image_id = (baseImage_id + ((draw_order[i] + 1) * 72)) | (riding_peep_sprites[draw_order[i]] << 19) | 0x20000000;
- sub_98199C(image_id, 0, 0, bbl_x, bbl_y, bbl_z, z, bbo_x, bbo_y, bbo_z, get_current_rotation());
- }
- }
- }
-
- assert(vehicleEntry->pad_5E == 1);
-}
-
-/**
- *
- * rct2: 0x006D4244
- */
-void viewport_vehicle_paint_setup(rct_vehicle *vehicle, int imageDirection)
-{
- rct_ride_entry *rideEntry;
- const rct_ride_entry_vehicle *vehicleEntry;
-
- int x = vehicle->x;
- int y = vehicle->y;
- int z = vehicle->z;
-
- if (vehicle->flags & SPRITE_FLAGS_IS_CRASHED_VEHICLE_SPRITE) {
- uint32 ebx = 22965 + vehicle->var_C5;
- sub_98197C(ebx, 0, 0, 1, 1, 0, z, 0, 0, z + 2, get_current_rotation());
- return;
- }
-
- if (vehicle->ride_subtype == 0xFF) {
- vehicleEntry = &CableLiftVehicle;
- } else {
- rideEntry = get_ride_entry(vehicle->ride_subtype);
- vehicleEntry = &rideEntry->vehicles[vehicle->vehicle_type];
-
- if (vehicle->update_flags & VEHICLE_UPDATE_FLAG_11) {
- vehicleEntry++;
- z += 16;
- }
- }
-
- uint32 rct2VehiclePtrFormat = ((uint32)vehicleEntry) - offsetof(rct_ride_entry, vehicles);
- RCT2_GLOBAL(0x00F64DFC, uint32) = rct2VehiclePtrFormat;
- switch (vehicleEntry->car_visual) {
- case VEHICLE_VISUAL_DEFAULT: RCT2_CALLPROC_X(0x006D45F8, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break;
- case VEHICLE_VISUAL_LAUNCHED_FREEFALL: vehicle_visual_launched_freefall(x, imageDirection, y, z, vehicle, vehicleEntry); break;
- case VEHICLE_VISUAL_OBSERVATION_TOWER: vehicle_visual_observation_tower(x, imageDirection, y, z, vehicle, vehicleEntry); break;
- case VEHICLE_VISUAL_RIVER_RAPIDS: RCT2_CALLPROC_X(0x006D5889, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break;
- case VEHICLE_VISUAL_MINI_GOLF_PLAYER: RCT2_CALLPROC_X(0x006D42F0, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break;
- case VEHICLE_VISUAL_MINI_GOLF_BALL: RCT2_CALLPROC_X(0x006D43C6, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break;
- case VEHICLE_VISUAL_REVERSER: RCT2_CALLPROC_X(0x006D4453, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break;
- case VEHICLE_VISUAL_SPLASH_BOATS_OR_WATER_COASTER: RCT2_CALLPROC_X(0x006D4295, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break;
- case VEHICLE_VISUAL_ROTO_DROP: vehicle_visual_roto_drop(x, imageDirection, y, z, vehicle, vehicleEntry); break;
- case 10: RCT2_CALLPROC_X(0x006D5600, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break;
- case 11: RCT2_CALLPROC_X(0x006D5696, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break;
- case 12: RCT2_CALLPROC_X(0x006D57EE, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break;
- case 13: RCT2_CALLPROC_X(0x006D5783, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break;
- case 14: RCT2_CALLPROC_X(0x006D5701, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break;
- case VEHICLE_VISUAL_VIRGINIA_REEL: vehicle_visual_virginia_reel(x, imageDirection, y, z, vehicle, vehicleEntry); break;
- case VEHICLE_VISUAL_SUBMARINE: RCT2_CALLPROC_X(0x006D44D5, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break;
- }
-}
-
-/**
- * rct2: 0x0068F0FB
- */
-void viewport_peep_paint_setup(rct_peep * peep, int imageDirection)
-{
- rct_drawpixelinfo * dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*);
- if (dpi->zoom_level > 2) {
- return;
- }
-
- if (gCurrentViewportFlags & VIEWPORT_FLAG_INVISIBLE_PEEPS) {
- return;
- }
-
- rct_sprite_entry sprite = g_sprite_entries[peep->sprite_type];
-
- uint8 spriteType = peep->action_sprite_type;
- uint8 imageOffset = peep->action_sprite_image_offset;
-
- if (peep->action == PEEP_ACTION_NONE_1) {
- spriteType = peep->next_action_sprite_type;
- imageOffset = 0;
- }
-
- uint32 baseImageId = (imageDirection >> 3) + sprite.sprite_image[spriteType].base_image + imageOffset * 4;
- uint32 imageId = baseImageId | peep->tshirt_colour << 19 | peep->trousers_colour << 24 | 0xA0000000;
- sub_98197C(imageId, 0, 0, 1, 1, 11, peep->z, 0, 0, peep->z + 3, get_current_rotation());
-
- if (baseImageId >= 10717 && baseImageId < 10749) {
- imageId = baseImageId + 32 | peep->hat_colour << 19 | 0x20000000;
- sub_98199C(imageId, 0, 0, 1, 1, 11, peep->z, 0, 0, peep->z + 3, get_current_rotation());
- return;
- }
-
- if (baseImageId >= 10781 && baseImageId < 10813) {
- imageId = baseImageId + 32 | peep->balloon_colour << 19 | 0x20000000;
- sub_98199C(imageId, 0, 0, 1, 1, 11, peep->z, 0, 0, peep->z + 3, get_current_rotation());
- return;
- }
-
- if (baseImageId >= 11197 && baseImageId < 11229) {
- imageId = baseImageId + 32 | peep->umbrella_colour << 19 | 0x20000000;
- sub_98199C(imageId, 0, 0, 1, 1, 11, peep->z, 0, 0, peep->z + 3, get_current_rotation());
- return;
- }
-}
-/**
- *
- * rct2: 0x00672AC9
- */
-void viewport_misc_paint_setup(rct_sprite *misc, int imageDirection)
-{
- RCT2_CALLPROC_X(0x00672AC9, misc->unknown.x, imageDirection, misc->unknown.y, misc->unknown.z, (int)misc, 0, 0);
-}
-
-/**
-* Litter Paint Setup
-* rct2: 0x006736FC
-*/
-void viewport_litter_paint_setup(rct_litter *litter, int imageDirection)
-{
- rct_drawpixelinfo *dpi;
-
- dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*);
- if (dpi->zoom_level != 0) return; // If zoomed at all no litter drawn
-
- // litter has no sprite direction so remove that
- imageDirection >>= 3;
- // Some litter types have only 1 direction so remove
- // anything that isn't required.
- imageDirection &= RCT2_ADDRESS(0x97EF6C, uint32)[litter->type * 2 + 1];
-
- uint32 image_id = imageDirection + RCT2_ADDRESS(0x97EF6C, uint32)[litter->type * 2];
-
- sub_98197C(image_id, 0, 0, 4, 4, -1, litter->z, -4, -4, litter->z + 2, get_current_rotation());
-}
-
-
-/**
-* Paint Quadrant
-* rct2: 0x0069E8B0
-*/
-void sprite_paint_setup(const uint16 eax, const uint16 ecx){
- rct_drawpixelinfo* dpi;
-
- if ((eax & 0xe000) | (ecx & 0xe000)) return;
-
- const int idx = ((eax << 3) & 0xff00) | (ecx >> 5);
- int sprite_idx = RCT2_ADDRESS(0xF1EF60, uint16)[idx];
- if (sprite_idx == SPRITE_INDEX_NULL) return;
-
- if (RCT2_GLOBAL(0x9DEA6F, uint8) & 1) return;
-
-
- if (gCurrentViewportFlags & VIEWPORT_FLAG_INVISIBLE_SPRITES) return;
-
- dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*);
- if (dpi->zoom_level > 2) return;
-
-
- for (rct_sprite* spr = &g_sprite_list[sprite_idx]; sprite_idx != SPRITE_INDEX_NULL; sprite_idx = spr->unknown.next_in_quadrant){
- spr = &g_sprite_list[sprite_idx];
- dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*);
-
- if (dpi->y + dpi->height <= spr->unknown.sprite_top) continue;
- if (spr->unknown.sprite_bottom <= dpi->y)continue;
- if (dpi->x + dpi->width <= spr->unknown.sprite_left)continue;
- if (spr->unknown.sprite_right <= dpi->x)continue;
-
- int image_direction = get_current_rotation();
- image_direction <<= 3;
- image_direction += spr->unknown.sprite_direction;
- image_direction &= 0x1F;
-
- RCT2_GLOBAL(0x9DE578, uint32) = (uint32)spr;
-
- RCT2_GLOBAL(0x9DE568, sint16) = spr->unknown.x;
- RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = VIEWPORT_INTERACTION_ITEM_SPRITE;
- RCT2_GLOBAL(0x9DE56C, sint16) = spr->unknown.y;
-
- switch (spr->unknown.sprite_identifier){
- case SPRITE_IDENTIFIER_VEHICLE:
- viewport_vehicle_paint_setup((rct_vehicle*)spr, image_direction);
- break;
- case SPRITE_IDENTIFIER_PEEP:
- viewport_peep_paint_setup((rct_peep*)spr, image_direction);
- break;
- case SPRITE_IDENTIFIER_MISC:
- viewport_misc_paint_setup(spr, image_direction);
- break;
- case SPRITE_IDENTIFIER_LITTER:
- viewport_litter_paint_setup((rct_litter*)spr, image_direction);
- break;
- default:
- assert(false);
- break;
- }
- }
-}
-
-/**
- *
- * rct2: 0x0066508C, 0x00665540
- */
-void viewport_ride_entrance_exit_paint_setup(uint8 direction, int height, rct_map_element* map_element)
-{
- rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*);
- uint8 is_exit = map_element->properties.entrance.type == ENTRANCE_TYPE_RIDE_EXIT;
-
- if (RCT2_GLOBAL(0x9DEA6F, uint8_t) & 1){
- if (map_element->properties.entrance.ride_index != RCT2_GLOBAL(0x00F64DE8, uint8))
- return;
- }
-
- rct_ride* ride = get_ride(map_element->properties.entrance.ride_index);
- if (ride->entrance_style == RIDE_ENTRANCE_STYLE_NONE) return;
-
- const rct_ride_entrance_definition *style = &RideEntranceDefinitions[ride->entrance_style];
-
- uint8 colour_1, colour_2;
- uint32 transparant_image_id = 0, image_id = 0;
- if (style->flags & (1 << 30)) {
- colour_1 = ride->track_colour_main[0] + 0x70;
- transparant_image_id = (colour_1 << 19) | 0x40000000;
- }
-
- colour_1 = ride->track_colour_main[0];
- colour_2 = ride->track_colour_additional[0];
- image_id = (colour_1 << 19) | (colour_2 << 24) | 0xA0000000;
-
- RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = VIEWPORT_INTERACTION_ITEM_RIDE;
- RCT2_GLOBAL(0x009E32BC, uint32) = 0;
-
- if (map_element->flags & MAP_ELEMENT_FLAG_GHOST){
- RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = VIEWPORT_INTERACTION_ITEM_NONE;
- image_id = RCT2_ADDRESS(0x993CC4, uint32_t)[gConfigGeneral.construction_marker_colour];
- RCT2_GLOBAL(0x009E32BC, uint32) = image_id;
- if (transparant_image_id)
- transparant_image_id = image_id;
- }
-
- if (is_exit){
- image_id |= style->sprite_index + direction + 8;
- }
- else{
- image_id |= style->sprite_index + direction;
- }
- // Format modifed to stop repeated code
-
- // Each entrance is split into 2 images for drawing
- // Certain entrance styles have another 2 images to draw for coloured windows
-
- sint8 ah = is_exit ? 0x23 : 0x33;
-
- sint16 lengthY = (direction & 1) ? 28 : 2;
- sint16 lengthX = (direction & 1) ? 2 : 28;
-
- sub_98197C(image_id, 0, 0, lengthX, lengthY, ah, height, 2, 2, height, get_current_rotation());
-
- if (transparant_image_id){
- if (is_exit){
- transparant_image_id |= style->sprite_index + direction + 24;
- }
- else{
- transparant_image_id |= style->sprite_index + direction + 16;
- }
-
- sub_98199C(transparant_image_id, 0, 0, lengthX, lengthY, ah, height, 2, 2, height, get_current_rotation());
- }
-
- image_id += 4;
-
- sub_98197C(image_id, 0, 0, lengthX, lengthY, ah, height, (direction & 1) ? 28 : 2, (direction & 1) ? 2 : 28, height, get_current_rotation());
-
- if (transparant_image_id){
- transparant_image_id += 4;
- sub_98199C(transparant_image_id, 0, 0, lengthX, lengthY, ah, height, (direction & 1) ? 28 : 2, (direction & 1) ? 2 : 28, height, get_current_rotation());
- }
-
- uint32 eax = 0xFFFF0600 | ((height / 16) & 0xFF);
- if (direction & 1){
- RCT2_ADDRESS(0x009E30B6, uint32)[RCT2_GLOBAL(0x141F56B, uint8) / 2] = eax;
- RCT2_GLOBAL(0x141F56B, uint8)++;
- }
- else{
- RCT2_ADDRESS(0x009E3138, uint32)[RCT2_GLOBAL(0x141F56A, uint8) / 2] = eax;
- RCT2_GLOBAL(0x141F56A, uint8)++;
- }
-
- if (!is_exit &&
- !(map_element->flags & MAP_ELEMENT_FLAG_GHOST) &&
- map_element->properties.entrance.ride_index != 0xFF){
-
- RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, uint32) = 0;
- RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 4, uint32) = 0;
-
- rct_string_id string_id = STR_RIDE_ENTRANCE_CLOSED;
-
- if (ride->status == RIDE_STATUS_OPEN &&
- !(ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN)){
-
- RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 0, rct_string_id) = ride->name;
- RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 2, uint32) = ride->name_arguments;
-
- string_id = STR_RIDE_ENTRANCE_NAME;
- }
-
- utf8 entrance_string[MAX_PATH];
- if (gConfigGeneral.upper_case_banners) {
- format_string_to_upper(entrance_string, string_id, RCT2_ADDRESS(RCT2_ADDRESS_COMMON_FORMAT_ARGS, void));
- } else {
- format_string(entrance_string, string_id, RCT2_ADDRESS(RCT2_ADDRESS_COMMON_FORMAT_ARGS, void));
- }
-
- gCurrentFontSpriteBase = FONT_SPRITE_BASE_TINY;
-
- uint16 string_width = gfx_get_string_width(entrance_string);
- uint16 scroll = (gCurrentTicks / 2) % string_width;
-
- sub_98199C(scrolling_text_setup(string_id, scroll, style->scrolling_mode), 0, 0, 0x1C, 0x1C, 0x33, height + style->height, 2, 2, height + style->height, get_current_rotation());
- }
-
- image_id = RCT2_GLOBAL(0x009E32BC, uint32);
- if (image_id == 0) {
- image_id = SPRITE_ID_PALETTE_COLOUR_1(COLOUR_SATURATED_BROWN);
- }
- wooden_a_supports_paint_setup(direction & 1, 0, height, image_id, NULL);
-
- 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 += is_exit ? 40 : 56;
- if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) < height){
- RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = height;
- RCT2_GLOBAL(0x141E9DA, uint8) = 32;
- }
-}
-
-/**
- *
- * rct2: 0x006658ED
- */
-void viewport_park_entrance_paint_setup(uint8 direction, int height, rct_map_element* map_element){
- if (RCT2_GLOBAL(0x9DEA6F, uint8_t) & 1)
- return;
-
- RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = VIEWPORT_INTERACTION_ITEM_PARK;
- RCT2_GLOBAL(0x009E32BC, uint32) = 0;
- uint32 image_id, ghost_id = 0;
- if (map_element->flags & MAP_ELEMENT_FLAG_GHOST){
- RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = VIEWPORT_INTERACTION_ITEM_NONE;
- ghost_id = RCT2_ADDRESS(0x993CC4, uint32)[gConfigGeneral.construction_marker_colour];
- RCT2_GLOBAL(0x009E32BC, uint32) = ghost_id;
- }
-
- rct_path_type* path_entry = g_pathTypeEntries[map_element->properties.entrance.path_type];
-
- // Index to which part of the entrance
- // Middle, left, right
- uint8 part_index = map_element->properties.entrance.index & 0xF;
- rct_entrance_type* entrance;
- uint8 di = (direction / 2 + part_index / 2) & 1 ? 0x1A : 0x20;
-
- switch (part_index){
- case 0:
- image_id = (path_entry->image + 5 * (1 + (direction & 1))) | ghost_id;
- sub_98197C(image_id, 0, 0, 32, 0x1C, 0, height, 0, 2, height, get_current_rotation());
-
- entrance = (rct_entrance_type*)object_entry_groups[OBJECT_TYPE_PARK_ENTRANCE].chunks[0];
- image_id = (entrance->image_id + direction * 3) | ghost_id;
- sub_98197C(image_id, 0, 0, 0x1C, 0x1C, 0x2F, height, 2, 2, height + 32, get_current_rotation());
-
- if ((direction + 1) & (1 << 1))
- break;
- if (ghost_id != 0)
- break;
-
- rct_string_id park_text_id = 1730;
- RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, uint32) = 0;
- RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 4, uint32) = 0;
-
- if (gParkFlags & PARK_FLAGS_PARK_OPEN){
- RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, rct_string_id) = gParkName;
- RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 2, uint32) = gParkNameArgs;
-
- park_text_id = 1731;
- }
-
- utf8 park_name[MAX_PATH];
- if (gConfigGeneral.upper_case_banners) {
- format_string_to_upper(park_name, park_text_id, RCT2_ADDRESS(RCT2_ADDRESS_COMMON_FORMAT_ARGS, void));
- } else {
- format_string(park_name, park_text_id, RCT2_ADDRESS(RCT2_ADDRESS_COMMON_FORMAT_ARGS, void));
- }
-
- gCurrentFontSpriteBase = FONT_SPRITE_BASE_TINY;
- uint16 string_width = gfx_get_string_width(park_name);
- uint16 scroll = (gCurrentTicks / 2) % string_width;
-
- if (entrance->scrolling_mode == 0xFF)
- break;
-
- sub_98199C(scrolling_text_setup(park_text_id, scroll, entrance->scrolling_mode + direction / 2), 0, 0, 0x1C, 0x1C, 0x2F, height + entrance->text_height, 2, 2, height + entrance->text_height, get_current_rotation());
- break;
- case 1:
- case 2:
- entrance = (rct_entrance_type*)object_entry_groups[OBJECT_TYPE_PARK_ENTRANCE].chunks[0];
- image_id = (entrance->image_id + part_index + direction * 3) | ghost_id;
- sub_98197C(image_id, 0, 0, 0x1A, di, 0x4F, height, 3, 3, height, get_current_rotation());
- break;
- }
-
- image_id = ghost_id;
- if (image_id == 0) {
- image_id = SPRITE_ID_PALETTE_COLOUR_1(COLOUR_SATURATED_BROWN);
- }
- wooden_a_supports_paint_setup(direction & 1, 0, height, image_id, NULL);
-
- 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 += 80;
- if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) < height){
- RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = height;
- RCT2_GLOBAL(0x141E9DA, uint8) = 32;
- }
-}
-
-/**
- *
- * rct2: 0x006C4794
- */
-void viewport_track_paint_setup(uint8 direction, int height, rct_map_element *mapElement)
-{
- rct_drawpixelinfo *dpi = RCT2_GLOBAL(0x0140E9A8, rct_drawpixelinfo*);
- rct_ride *ride;
- int rideIndex, trackType, trackColourScheme, trackSequence;
-
- rideIndex = mapElement->properties.track.ride_index;
- ride = get_ride(rideIndex);
- if (ride->type == RIDE_TYPE_NULL) {
- log_error("Attempted to paint invalid ride: %d", rideIndex);
- return;
- }
-
- // HACK Set entrance style to plain if none to stop glitch until entrance track piece is implemented
- bool isEntranceStyleNone = false;
- if (ride->entrance_style == RIDE_ENTRANCE_STYLE_NONE) {
- isEntranceStyleNone = true;
- ride->entrance_style = RIDE_ENTRANCE_STYLE_PLAIN;
- }
-
- if (!(RCT2_GLOBAL(0x009DEA6F, uint8) & 1) || rideIndex == RCT2_GLOBAL(0x00F64DE8, uint8)) {
- trackType = mapElement->properties.track.type;
- trackSequence = mapElement->properties.track.sequence & 0x0F;
- trackColourScheme = mapElement->properties.track.colour & 3;
-
- if ((gCurrentViewportFlags & VIEWPORT_FLAG_TRACK_HEIGHTS) && dpi->zoom_level == 0) {
- RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = 0;
- if (RCT2_ADDRESS(0x00999694, uint32)[trackType] & (1 << trackSequence)) {
- uint16 ax = RideData5[ride->type].z_offset;
- uint32 ebx = 0x20381689 + (height + 8) / 16;
- ebx += get_height_marker_offset();
- ebx -= RCT2_GLOBAL(0x01359208, uint16);
- sub_98197C(ebx, 16, 16, 1, 1, 0, height + ax + 3, 1000, 1000, 2047, get_current_rotation());
- }
- }
-
- RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = 3;
- RCT2_GLOBAL(0x00F44198, uint32) = (ride->track_colour_main[trackColourScheme] << 19) | (ride->track_colour_additional[trackColourScheme] << 24) | 0xA0000000;
- RCT2_GLOBAL(0x00F441A0, uint32) = 0x20000000;
- RCT2_GLOBAL(0x00F441A4, uint32) = 0x20C00000;
- RCT2_GLOBAL(0x00F4419C, uint32) = (ride->track_colour_supports[trackColourScheme] << 19) | 0x20000000;
- if (mapElement->type & 0x40) {
- RCT2_GLOBAL(0x00F44198, uint32) = 0x21600000;
- RCT2_GLOBAL(0x00F4419C, uint32) = 0x21600000;
- RCT2_GLOBAL(0x00F441A0, uint32) = 0x21600000;
- RCT2_GLOBAL(0x00F441A4, uint32) = 0x21600000;
- }
- if (mapElement->flags & MAP_ELEMENT_FLAG_GHOST) {
- uint32 ghost_id = RCT2_ADDRESS(0x00993CC4, uint32)[gConfigGeneral.construction_marker_colour];
- RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = 0;
- RCT2_GLOBAL(0x00F44198, uint32) = ghost_id;
- RCT2_GLOBAL(0x00F4419C, uint32) = ghost_id;
- RCT2_GLOBAL(0x00F441A0, uint32) = ghost_id;
- RCT2_GLOBAL(0x00F441A4, uint32) = ghost_id;
- }
-
- int rideType = ride->type;
- if (rideType == RIDE_TYPE_JUNIOR_ROLLER_COASTER) {
- switch (trackType) {
- case TRACK_ELEM_60_DEG_UP:
- case TRACK_ELEM_25_DEG_UP_TO_60_DEG_UP:
- case TRACK_ELEM_60_DEG_UP_TO_25_DEG_UP:
- case TRACK_ELEM_60_DEG_DOWN:
- case TRACK_ELEM_25_DEG_DOWN_TO_60_DEG_DOWN:
- case TRACK_ELEM_60_DEG_DOWN_TO_25_DEG_DOWN:
- rideType = RIDE_TYPE_WATER_COASTER;
- break;
-
- case TRACK_ELEM_FLAT_TO_60_DEG_UP:
- case TRACK_ELEM_60_DEG_UP_TO_FLAT:
- case TRACK_ELEM_FLAT_TO_60_DEG_DOWN:
- case TRACK_ELEM_60_DEG_DOWN_TO_FLAT:
- return;
- }
- }
-
- TRACK_PAINT_FUNCTION **trackTypeList = (TRACK_PAINT_FUNCTION**)RideTypeTrackPaintFunctionsOld[rideType];
- if (trackTypeList == NULL) {
- TRACK_PAINT_FUNCTION_GETTER paintFunctionGetter = RideTypeTrackPaintFunctions[rideType];
- TRACK_PAINT_FUNCTION paintFunction = paintFunctionGetter(trackType, direction);
- if (paintFunction != NULL) {
- paintFunction(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,
- rideType,
- (int)trackDirectionList,
- direction,
- height,
- (int)mapElement,
- rideIndex * sizeof(rct_ride),
- trackSequence
- );
- }
- }
-
- if (isEntranceStyleNone) {
- ride->entrance_style = RIDE_ENTRANCE_STYLE_NONE;
- }
-}
-
-/**
- *
- * rct2: 0x00664FD4
- */
-void viewport_entrance_paint_setup(uint8 direction, int height, rct_map_element* map_element){
- RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8_t) = VIEWPORT_INTERACTION_ITEM_LABEL;
-
- rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*);
-
- if (gCurrentViewportFlags & VIEWPORT_FLAG_PATH_HEIGHTS &&
- dpi->zoom_level == 0){
- uint32 ebx =
- (map_element->properties.entrance.type << 4) |
- (map_element->properties.entrance.index & 0xF);
-
- if (RCT2_ADDRESS(0x0097B974, uint8)[ebx] & 0xF){
-
- int z = map_element->base_height * 8 + 3;
- uint32 image_id =
- z / 16 +
- get_height_marker_offset() +
- 0x20101689;
-
- image_id -= RCT2_GLOBAL(0x01359208, sint16);
-
- sub_98197C(image_id, 16, 16, 1, 1, 0, height, 31, 31, z + 64, get_current_rotation());
- }
- }
-
- switch (map_element->properties.entrance.type){
- case ENTRANCE_TYPE_RIDE_ENTRANCE:
- case ENTRANCE_TYPE_RIDE_EXIT:
- viewport_ride_entrance_exit_paint_setup(direction, height, map_element);
- break;
- case ENTRANCE_TYPE_PARK_ENTRANCE:
- viewport_park_entrance_paint_setup(direction, height, map_element);
- break;
- }
-}
-
-/**
- *
- * rct2: 0x006B9CC4
- */
-void viewport_banner_paint_setup(uint8 direction, int height, rct_map_element* map_element)
-{
- uint16 boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ;
- rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*);
-
- RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8_t) = VIEWPORT_INTERACTION_ITEM_BANNER;
-
- if (dpi->zoom_level > 1 || RCT2_GLOBAL(0x9DEA6F, uint8_t) & 1) return;
-
- height -= 16;
-
- rct_scenery_entry* banner_scenery = g_bannerSceneryEntries[gBanners[map_element->properties.banner.index].type];
-
- direction += map_element->properties.banner.position;
- direction &= 3;
-
- boundBoxOffsetX = RCT2_ADDRESS(0x98D884, uint16)[direction * 4];
- boundBoxOffsetY = RCT2_ADDRESS(0x98D884 + 2, uint16)[direction * 4];
- boundBoxOffsetZ = height + 2;
-
- uint32 base_id = (direction << 1) + banner_scenery->image;
- uint32 image_id = base_id;
-
- if (map_element->flags & MAP_ELEMENT_FLAG_GHOST)//if being placed
- {
- RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8_t) = VIEWPORT_INTERACTION_ITEM_NONE;
- image_id |= RCT2_ADDRESS(0x993CC4, uint32_t)[gConfigGeneral.construction_marker_colour];
- }
- else{
- image_id |=
- (gBanners[map_element->properties.banner.index].colour << 19) |
- 0x20000000;
- }
-
- sub_98197C(image_id, 0, 0, 1, 1, 0x15, height, boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ, get_current_rotation());
- boundBoxOffsetX = RCT2_ADDRESS(0x98D888, uint16)[direction * 4];
- boundBoxOffsetY = RCT2_ADDRESS(0x98D888 + 2, uint16)[direction * 4];
-
- image_id++;
- sub_98197C(image_id, 0, 0, 1, 1, 0x15, height, boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ, get_current_rotation());
-
- // Opposite direction
- direction ^= 2;
- direction--;
- // If text not showing / ghost
- if (direction >= 2 || (map_element->flags & MAP_ELEMENT_FLAG_GHOST)) return;
-
- uint16 scrollingMode = banner_scenery->banner.scrolling_mode;
- scrollingMode += direction;
-
- RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, uint32) = 0;
- RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 4, uint32_t) = 0;
-
- rct_string_id string_id = STR_NO_ENTRY;
- if (!(gBanners[map_element->properties.banner.index].flags & BANNER_FLAG_NO_ENTRY))
- {
- RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, uint16) = gBanners[map_element->properties.banner.index].string_idx;
- string_id = STR_BANNER_TEXT;
- }
- if (gConfigGeneral.upper_case_banners) {
- format_string_to_upper(RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char), string_id, RCT2_ADDRESS(RCT2_ADDRESS_COMMON_FORMAT_ARGS, void));
- } else {
- format_string(RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char), string_id, RCT2_ADDRESS(RCT2_ADDRESS_COMMON_FORMAT_ARGS, void));
- }
-
- gCurrentFontSpriteBase = FONT_SPRITE_BASE_TINY;
-
- uint16 string_width = gfx_get_string_width(RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char));
- uint16 scroll = (gCurrentTicks / 2) % string_width;
-
- sub_98199C(scrolling_text_setup(string_id, scroll, scrollingMode), 0, 0, 1, 1, 0x15, height + 22, boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ, get_current_rotation());
-}
-
-/**
- *
- * rct2: 0x0068B3FB
- */
-static void sub_68B3FB(int x, int y)
-{
- rct_drawpixelinfo *dpi = RCT2_GLOBAL(0x0140E9A8, rct_drawpixelinfo*);
-
- RCT2_GLOBAL(0x141F56A, uint16_t) = 0;
- RCT2_GLOBAL(0x9E3138, uint8_t) = 0xFF;
- RCT2_GLOBAL(0x9E30B6, uint8_t) = 0xFF;
- RCT2_GLOBAL(0x9E323C, uint8_t) = 0xFF;
- RCT2_GLOBAL(0x9DE56A, uint16_t) = x;
- RCT2_GLOBAL(0x9DE56E, uint16_t) = y;
- RCT2_GLOBAL(0x9DE574, uint16_t) = x;
- RCT2_GLOBAL(0x9DE576, uint16_t) = y;
-
- rct_map_element* map_element = map_get_first_element_at(x >> 5, y >> 5);
- uint8 rotation = get_current_rotation();
-
- int dx = 0;
- switch (rotation) {
- case 0:
- dx = x + y;
- break;
- case 1:
- x += 32;
- dx = y - x;
- break;
- case 2:
- x += 32;
- y += 32;
- dx = -(x + y);
- break;
- case 3:
- y += 32;
- dx = x - y;
- break;
- }
- dx >>= 1;
- // Display little yellow arrow when building footpaths?
- if ((RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) & 4) &&
- RCT2_GLOBAL(0x9DE56A, uint16) == RCT2_GLOBAL(RCT2_ADDRESS_MAP_ARROW_X, uint16) &&
- RCT2_GLOBAL(0x9DE56E, uint16) == RCT2_GLOBAL(RCT2_ADDRESS_MAP_ARROW_Y, uint16)){
- uint8 arrowRotation =
- (rotation
- + (RCT2_GLOBAL(RCT2_ADDRESS_MAP_ARROW_DIRECTION, uint8) & 3)) & 3;
-
- uint32 imageId =
- arrowRotation +
- (RCT2_GLOBAL(RCT2_ADDRESS_MAP_ARROW_DIRECTION, uint8) & 0xFC) +
- 0x20900C27;
- int arrowZ = RCT2_GLOBAL(RCT2_ADDRESS_MAP_ARROW_Z, uint16);
-
- RCT2_GLOBAL(0x9DE568, sint16) = x;
- RCT2_GLOBAL(0x9DE56C, sint16) = y;
- RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = VIEWPORT_INTERACTION_ITEM_NONE;
-
- sub_98197C(imageId, 0, 0, 32, 32, 0xFF, arrowZ, 0, 0, arrowZ + 18, rotation);
- }
- int bx = dx + 52;
-
- if (bx <= dpi->y)
- return;
-
- const rct_map_element* element = map_element;//push map_element
-
- sint16 max_height = 0;
- do{
- max_height = max(max_height, element->clearance_height);
- } while (!map_element_is_last_for_tile(element++));
-
- element--;
-
- if (map_element_get_type(element) == MAP_ELEMENT_TYPE_SURFACE &&
- (element->properties.surface.terrain & MAP_ELEMENT_WATER_HEIGHT_MASK) != 0){
- max_height = (element->properties.surface.terrain & MAP_ELEMENT_WATER_HEIGHT_MASK) << 1;
- }
-
- max_height *= 8;
-
- dx -= max_height + 32;
-
- element = map_element;//pop map_element
- dx -= dpi->height;
- if (dx >= dpi->y)
- return;
-
- RCT2_GLOBAL(0x9DE568, sint16) = x;
- RCT2_GLOBAL(0x9DE56C, sint16) = y;
- RCT2_GLOBAL(0x9DE57C, uint16) = 0;
- do {
- int direction = (map_element->type + rotation) & MAP_ELEMENT_DIRECTION_MASK;
- int height = map_element->base_height * 8;
-
- uint32_t dword_9DE574 = RCT2_GLOBAL(0x9DE574, uint32_t);
- RCT2_GLOBAL(0x9DE578, rct_map_element*) = map_element;
- //setup the painting of for example: the underground, signs, rides, scenery, etc.
- switch (map_element_get_type(map_element))
- {
- case MAP_ELEMENT_TYPE_SURFACE:
- viewport_surface_paint_setup(direction, height, map_element);
- break;
- case MAP_ELEMENT_TYPE_PATH:
- RCT2_CALLPROC_X(0x6A3590, 0, 0, direction, height, (int)map_element, 0, 0);
- break;
- case MAP_ELEMENT_TYPE_TRACK:
- viewport_track_paint_setup(direction, height, map_element);
- break;
- case MAP_ELEMENT_TYPE_SCENERY:
- RCT2_CALLPROC_X(0x6DFF47, 0, 0, direction, height, (int)map_element, 0, 0);
- break;
- case MAP_ELEMENT_TYPE_ENTRANCE:
- viewport_entrance_paint_setup(direction, height, map_element);
- break;
- case MAP_ELEMENT_TYPE_FENCE:
- RCT2_CALLPROC_X(0x6E44B0, 0, 0, direction, height, (int)map_element, 0, 0);
- break;
- case MAP_ELEMENT_TYPE_SCENERY_MULTIPLE:
- RCT2_CALLPROC_X(0x6B7F0C, 0, 0, direction, height, (int)map_element, 0, 0);
- break;
- case MAP_ELEMENT_TYPE_BANNER:
- viewport_banner_paint_setup(direction, height, map_element);
- break;
- // A corrupt element inserted by OpenRCT2 itself, which skips the drawing of the next element only.
- case MAP_ELEMENT_TYPE_CORRUPT:
- if (map_element_is_last_for_tile(map_element))
- return;
- map_element++;
- break;
- default:
- // An undefined map element is most likely a corrupt element inserted by 8 cars' MOM feature to skip drawing of all elements after it.
- return;
- }
- RCT2_GLOBAL(0x9DE574, uint32_t) = dword_9DE574;
- } while (!map_element_is_last_for_tile(map_element++));
-}
-
-/**
- *
- * rct2: 0x0068B60E
- */
-static void viewport_blank_tiles_paint_setup(int x, int y)
-{
- rct_drawpixelinfo *dpi = RCT2_GLOBAL(0x0140E9A8, rct_drawpixelinfo*);
-
- int dx;
- switch (get_current_rotation()) {
- case 0:
- dx = x + y;
- break;
- case 1:
- x += 32;
- dx = y - x;
- break;
- case 2:
- x += 32;
- y += 32;
- dx = -(x + y);
- break;
- case 3:
- y += 32;
- dx = x - y;
- break;
- }
- dx /= 2;
- dx -= 16;
- int bx = dx + 32;
- if (bx <= dpi->y) return;
- dx -= 20;
- dx -= dpi->height;
- if (dx >= dpi->y) return;
- RCT2_GLOBAL(0x9DE568, sint16) = x;
- RCT2_GLOBAL(0x9DE56C, sint16) = y;
- RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8_t) = VIEWPORT_INTERACTION_ITEM_NONE;
- RCT2_CALLPROC_X(
- (int)RCT2_ADDRESS(0x98196C, uint32_t*)[get_current_rotation()],
- 0xFF00,
- 3123,
- y & 0xFF00,
- 16,
- 32,
- 32,
- get_current_rotation()
- );
-}
-
-/**
- *
- * rct2: 0x0068B2B7
- */
-void sub_68B2B7(int x, int y)
-{
- if (
- x < gMapSizeUnits &&
- y < gMapSizeUnits &&
- x >= 32 &&
- y >= 32
- ) {
- RCT2_GLOBAL(0x0141E9B4, uint32) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9B8, uint32) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9BC, uint32) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9C0, uint32) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9C4, uint32) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9C8, uint32) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9CC, uint32) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9D0, uint32) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9D4, uint32) = 0xFFFF;
- RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = -1;
- RCT2_GLOBAL(0x0141E9DA, uint16) = 0;
- RCT2_GLOBAL(0x0141E9DC, uint32) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9DB, uint8) |= 2;
-
- sub_68B3FB(x, y);
- } else {
- viewport_blank_tiles_paint_setup(x, y);
- }
-}
-
-/**
- *
- * rct2: 0x0068B35F
- */
-void map_element_paint_setup(int x, int y)
-{
- rct_drawpixelinfo *dpi = RCT2_GLOBAL(0x0140E9A8, rct_drawpixelinfo*);
- if (
- x < gMapSizeUnits &&
- y < gMapSizeUnits &&
- x >= 32 &&
- y >= 32
- ) {
- RCT2_GLOBAL(0x0141E9B4, uint32) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9B8, uint32) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9BC, uint32) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9C0, uint32) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9C4, uint32) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9C8, uint32) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9CC, uint32) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9D0, uint32) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9D4, uint32) = 0xFFFF;
- RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = -1;
- RCT2_GLOBAL(0x0141E9DA, sint16) = 0;
- RCT2_GLOBAL(0x0141E9DC, uint32) = 0xFFFF;
-
- sub_68B3FB(x, y);
- } else {
- viewport_blank_tiles_paint_setup(x, y);
- }
-}
-
-/**
-*
-* rct2: 0x0068B6C2
-*/
-void viewport_paint_setup()
-{
- rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*);
-
- rct_xy16 mapTile = {
- .x = dpi->x & 0xFFE0,
- .y = (dpi->y - 16) & 0xFFE0
- };
-
- sint16 half_x = mapTile.x >> 1;
-
- uint16 num_vertical_quadrants = (dpi->height + 2128) >> 5;
-
- switch (get_current_rotation()){
- case 0:
- mapTile.x = mapTile.y - half_x;
- mapTile.y = mapTile.y + half_x;
-
- mapTile.x &= 0xFFE0;
- mapTile.y &= 0xFFE0;
-
- for (; num_vertical_quadrants > 0; --num_vertical_quadrants){
- map_element_paint_setup(mapTile.x, mapTile.y);
- sprite_paint_setup(mapTile.x, mapTile.y);
-
- sprite_paint_setup(mapTile.x - 32, mapTile.y + 32);
-
- map_element_paint_setup(mapTile.x, mapTile.y + 32);
- sprite_paint_setup(mapTile.x, mapTile.y + 32);
-
- mapTile.x += 32;
- sprite_paint_setup(mapTile.x, mapTile.y);
-
- mapTile.y += 32;
- }
- break;
- case 1:
- mapTile.x = -mapTile.y - half_x;
- mapTile.y = mapTile.y - half_x - 16;
-
- mapTile.x &= 0xFFE0;
- mapTile.y &= 0xFFE0;
-
- for (; num_vertical_quadrants > 0; --num_vertical_quadrants){
- map_element_paint_setup(mapTile.x, mapTile.y);
- sprite_paint_setup(mapTile.x, mapTile.y);
-
- sprite_paint_setup(mapTile.x - 32, mapTile.y - 32);
-
- map_element_paint_setup(mapTile.x - 32, mapTile.y);
- sprite_paint_setup(mapTile.x - 32, mapTile.y);
-
- mapTile.y += 32;
- sprite_paint_setup(mapTile.x, mapTile.y);
-
- mapTile.x -= 32;
- }
- break;
- case 2:
- mapTile.x = -mapTile.y + half_x;
- mapTile.y = -mapTile.y - half_x;
-
- mapTile.x &= 0xFFE0;
- mapTile.y &= 0xFFE0;
-
- for (; num_vertical_quadrants > 0; --num_vertical_quadrants){
- map_element_paint_setup(mapTile.x, mapTile.y);
- sprite_paint_setup(mapTile.x, mapTile.y);
-
- sprite_paint_setup(mapTile.x + 32, mapTile.y - 32);
-
- map_element_paint_setup(mapTile.x, mapTile.y - 32);
- sprite_paint_setup(mapTile.x, mapTile.y - 32);
-
- mapTile.x -= 32;
-
- sprite_paint_setup(mapTile.x, mapTile.y);
-
- mapTile.y -= 32;
- }
- break;
- case 3:
- mapTile.x = mapTile.y + half_x;
- mapTile.y = -mapTile.y + half_x - 16;
-
- mapTile.x &= 0xFFE0;
- mapTile.y &= 0xFFE0;
-
- for (; num_vertical_quadrants > 0; --num_vertical_quadrants){
- map_element_paint_setup(mapTile.x, mapTile.y);
- sprite_paint_setup(mapTile.x, mapTile.y);
-
- sprite_paint_setup(mapTile.x + 32, mapTile.y + 32);
-
- map_element_paint_setup(mapTile.x + 32, mapTile.y);
- sprite_paint_setup(mapTile.x + 32, mapTile.y);
-
- mapTile.y -= 32;
-
- sprite_paint_setup(mapTile.x, mapTile.y);
-
- mapTile.x += 32;
- }
- break;
- }
-}
-
-void sub_688217_helper(uint16 ax, uint8 flag)
-{
- paint_struct *ps, *ps_temp;
- paint_struct *ps_next = RCT2_GLOBAL(0x00EE7884, paint_struct*);
-
- do {
- ps = ps_next;
- ps_next = ps_next->next_quadrant_ps;
- if (ps_next == NULL) return;
- } while (ax > ps_next->var_18);
-
- ps_temp = ps;
-
- do {
- ps = ps->next_quadrant_ps;
- if (ps == NULL) break;
-
- if (ps->var_18 > ax + 1) {
- ps->var_1B = 1 << 7;
- } else if (ps->var_18 == ax + 1) {
- ps->var_1B = (1 << 1) | (1 << 0);
- } else if (ps->var_18 == ax) {
- ps->var_1B = flag | (1 << 0);
- }
- } while (ps->var_18 <= ax + 1);
-
- ps = ps_temp;
-
- uint8 rotation = get_current_rotation();
- while (true) {
- while (true) {
- ps_next = ps->next_quadrant_ps;
- if (ps_next == NULL) return;
- if (ps_next->var_1B & (1 << 7)) return;
- if (ps_next->var_1B & (1 << 0)) break;
- ps = ps_next;
- }
-
- ps_next->var_1B &= ~(1 << 0);
- ps_temp = ps;
-
- typedef struct bound_box {
- uint16 x;
- uint16 y;
- uint16 z;
- uint16 x_end;
- uint16 y_end;
- uint16 z_end;
- } bound_box;
-
- bound_box initialBBox = {
- .x = ps_next->bound_box_x,
- .y = ps_next->bound_box_y,
- .z = ps_next->bound_box_z,
- .x_end = ps_next->bound_box_x_end,
- .y_end = ps_next->bound_box_y_end,
- .z_end = ps_next->bound_box_z_end
- };
-
-
- while (true) {
- ps = ps_next;
- ps_next = ps_next->next_quadrant_ps;
- if (ps_next == NULL) break;
- if (ps_next->var_1B & (1 << 7)) break;
- if (!(ps_next->var_1B & (1 << 1))) continue;
-
- int yes = 0;
- switch (rotation) {
- case 0:
- if (initialBBox.z_end >= ps_next->bound_box_z && initialBBox.y_end >= ps_next->bound_box_y && initialBBox.x_end >= ps_next->bound_box_x
- && !(initialBBox.z < ps_next->bound_box_z_end && initialBBox.y < ps_next->bound_box_y_end && initialBBox.x < ps_next->bound_box_x_end))
- yes = 1;
- break;
- case 1:
- if (initialBBox.z_end >= ps_next->bound_box_z && initialBBox.y_end >= ps_next->bound_box_y && initialBBox.x_end < ps_next->bound_box_x
- && !(initialBBox.z < ps_next->bound_box_z_end && initialBBox.y < ps_next->bound_box_y_end && initialBBox.x >= ps_next->bound_box_x_end))
- yes = 1;
- break;
- case 2:
- if (initialBBox.z_end >= ps_next->bound_box_z && initialBBox.y_end < ps_next->bound_box_y && initialBBox.x_end < ps_next->bound_box_x
- && !(initialBBox.z < ps_next->bound_box_z_end && initialBBox.y >= ps_next->bound_box_y_end && initialBBox.x >= ps_next->bound_box_x_end))
- yes = 1;
- break;
- case 3:
- if (initialBBox.z_end >= ps_next->bound_box_z && initialBBox.y_end < ps_next->bound_box_y && initialBBox.x_end >= ps_next->bound_box_x
- && !(initialBBox.z < ps_next->bound_box_z_end && initialBBox.y >= ps_next->bound_box_y_end && initialBBox.x < ps_next->bound_box_x_end))
- yes = 1;
- break;
- }
-
- if (yes) {
- ps->next_quadrant_ps = ps_next->next_quadrant_ps;
- paint_struct *ps_temp2 = ps_temp->next_quadrant_ps;
- ps_temp->next_quadrant_ps = ps_next;
- ps_next->next_quadrant_ps = ps_temp2;
- ps_next = ps;
- }
- }
-
- ps = ps_temp;
- }
-}
-
-/**
-*
-* rct2: 0x00688217
-*/
-void sub_688217()
-{
- paint_struct *ps = RCT2_GLOBAL(0x00EE7888, paint_struct*);
- paint_struct *ps_next;
- RCT2_GLOBAL(0x00EE7888, paint_struct*)++;
- RCT2_GLOBAL(0x00EE7884, paint_struct*) = ps;
- ps->next_quadrant_ps = NULL;
- uint32 edi = RCT2_GLOBAL(0x00F1AD0C, uint32);
- if (edi == -1)
- return;
-
- do {
- ps_next = RCT2_GLOBAL(0x00F1A50C + 4 * edi, paint_struct*);
- if (ps_next != NULL) {
- ps->next_quadrant_ps = ps_next;
- do {
- ps = ps_next;
- ps_next = ps_next->next_quadrant_ps;
- } while (ps_next != NULL);
- }
- } while (++edi <= RCT2_GLOBAL(0x00F1AD10, uint32));
-
- uint32 eax = RCT2_GLOBAL(0x00F1AD0C, uint32);
-
- sub_688217_helper(eax & 0xFFFF, 1 << 1);
-
- eax = RCT2_GLOBAL(0x00F1AD0C, uint32);
-
- while (++eax < RCT2_GLOBAL(0x00F1AD10, uint32))
- sub_688217_helper(eax & 0xFFFF, 0);
-}
-
-static void draw_pixel_info_crop_by_zoom(rct_drawpixelinfo *dpi)
-{
- int zoom = dpi->zoom_level;
- dpi->zoom_level = 0;
- dpi->x >>= zoom;
- dpi->y >>= zoom;
- dpi->width >>= zoom;
- dpi->height >>= zoom;
-}
-
-/**
- *
- * rct2: 0x00688596
- * Part of 0x688485
- */
-void paint_attached_ps(paint_struct* ps, attached_paint_struct* attached_ps, rct_drawpixelinfo* dpi) {
- for (; attached_ps; attached_ps = attached_ps->next) {
- sint16 x = attached_ps->x + ps->x;
- sint16 y = attached_ps->y + ps->y;
-
- int image_id = attached_ps->image_id;
- if (gCurrentViewportFlags & VIEWPORT_FLAG_SEETHROUGH_RIDES) {
- if (ps->sprite_type == 3) {
- if (image_id & 0x40000000) {
- image_id &= 0x7FFFF;
- image_id |= 0x41880000;
- }
- }
- }
-
- if (gCurrentViewportFlags & VIEWPORT_FLAG_SEETHROUGH_SCENERY) {
- if (ps->sprite_type == 5) {
- if (image_id & 0x40000000) {
- image_id &= 0x7FFFF;
- image_id |= 0x41880000;
- }
- }
- }
-
- if (attached_ps->flags & PAINT_STRUCT_FLAG_IS_MASKED) {
- gfx_draw_sprite_raw_masked(dpi, x, y, image_id, attached_ps->colour_image_id);
- }
- else {
- gfx_draw_sprite(dpi, image_id, x, y, ps->tertiary_colour);
- }
- }
-}
-
-/* rct2: 0x00688485 */
-void paint_quadrant_ps() {
- rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*);
- paint_struct* ps = RCT2_GLOBAL(0xEE7884, paint_struct*);
- paint_struct* previous_ps = ps->next_quadrant_ps;
-
- for (ps = ps->next_quadrant_ps; ps;) {
- sint16 x = ps->x;
- sint16 y = ps->y;
- if (ps->sprite_type == 2) {
- if (dpi->zoom_level >= 1) {
- x &= 0xFFFE;
- y &= 0xFFFE;
- if (dpi->zoom_level >= 2) {
- x &= 0xFFFC;
- y &= 0xFFFC;
- }
- }
- }
- int image_id = ps->image_id;
- if (gCurrentViewportFlags & VIEWPORT_FLAG_SEETHROUGH_RIDES) {
- if (ps->sprite_type == 3) {
- if (!(image_id & 0x40000000)) {
- image_id &= 0x7FFFF;
- image_id |= 0x41880000;
- }
- }
- }
- if (gCurrentViewportFlags & VIEWPORT_FLAG_UNDERGROUND_INSIDE) {
- if (ps->sprite_type == 9) {
- if (!(image_id & 0x40000000)) {
- image_id &= 0x7FFFF;
- image_id |= 0x41880000;
- }
- }
- }
- if (gCurrentViewportFlags & VIEWPORT_FLAG_SEETHROUGH_SCENERY) {
- if (ps->sprite_type == 10 || ps->sprite_type == 12 || ps->sprite_type == 9 || ps->sprite_type == 5) {
- if (!(image_id & 0x40000000)) {
- image_id &= 0x7FFFF;
- image_id |= 0x41880000;
- }
- }
- }
-
- if (ps->flags & PAINT_STRUCT_FLAG_IS_MASKED)
- gfx_draw_sprite_raw_masked(dpi, x, y, image_id, ps->colour_image_id);
- else
- gfx_draw_sprite(dpi, image_id, x, y, ps->tertiary_colour);
-
- if (ps->var_20 != 0) {
- ps = ps->var_20;
- continue;
- }
-
- paint_attached_ps(ps, ps->attached_ps, dpi);
- ps = previous_ps->next_quadrant_ps;
- previous_ps = ps;
- }
-
-}
-
-/**
- *
- * rct2: 0x006860C3
- */
-static void viewport_draw_money_effects()
-{
- utf8 buffer[256];
-
- paint_string_struct *ps = RCT2_GLOBAL(0x00F1AD20, paint_string_struct*);
- if (ps == NULL)
- return;
-
- rct_drawpixelinfo dpi = *(RCT2_GLOBAL(0x0140E9A8, rct_drawpixelinfo*));
- draw_pixel_info_crop_by_zoom(&dpi);
-
- do {
- format_string(buffer, ps->string_id, &ps->args);
- gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM;
-
- bool forceSpriteFont = false;
- const currency_descriptor *currencyDesc = &CurrencyDescriptors[gConfigGeneral.currency_format];
- if (gUseTrueTypeFont && font_supports_string_sprite(currencyDesc->symbol_unicode)) {
- forceSpriteFont = true;
- }
-
- gfx_draw_string_with_y_offsets(&dpi, buffer, 0, ps->x, ps->y, (sint8 *)ps->y_offsets, forceSpriteFont);
- } while ((ps = ps->next) != NULL);
-}
-
/**
*
* rct2: 0x00685CBF
diff --git a/src/interface/viewport.h b/src/interface/viewport.h
index fceb9208c2..6a9dc679de 100644
--- a/src/interface/viewport.h
+++ b/src/interface/viewport.h
@@ -72,56 +72,6 @@ enum {
VIEWPORT_INTERACTION_MASK_BANNER = ~(1 << (VIEWPORT_INTERACTION_ITEM_BANNER - 2)), // Note the -2 for BANNER
};
-typedef struct paint_struct paint_struct;
-typedef struct attached_paint_struct attached_paint_struct;
-
-struct attached_paint_struct {
- uint32 image_id; // 0x00
- union {
- uint32 tertiary_colour;
- // If masked image_id is masked_id
- uint32 colour_image_id;
- };
- uint16 x; // 0x08
- uint16 y; // 0x0A
- uint8 flags;
- uint8 pad_0D;
- attached_paint_struct* next; //0x0E
-};
-
-struct paint_struct {
- uint32 image_id; // 0x00
- union {
- uint32 tertiary_colour;
- // If masked image_id is masked_id
- uint32 colour_image_id;
- };
- uint16 bound_box_x; // 0x08
- uint16 bound_box_y; // 0x0A
- uint16 bound_box_z; // 0x0C
- uint16 bound_box_z_end; // 0x0E
- uint16 bound_box_x_end; // 0x10
- uint16 bound_box_y_end; // 0x12
- uint16 x; // 0x14
- uint16 y; // 0x16
- uint16 var_18;
- uint8 flags;
- uint8 var_1B;
- attached_paint_struct* attached_ps; //0x1C
- paint_struct* var_20;
- paint_struct* next_quadrant_ps; // 0x24
- uint8 sprite_type; //0x28
- uint8 var_29;
- uint16 pad_2A;
- uint16 map_x; // 0x2C
- uint16 map_y; // 0x2E
- rct_map_element *mapElement; // 0x30 (or sprite pointer)
-};
-
-enum PAINT_STRUCT_FLAGS {
- PAINT_STRUCT_FLAG_IS_MASKED = (1 << 0)
-};
-
typedef struct {
int type;
int x;
@@ -186,11 +136,6 @@ void painter_setup();
void paint_quadrant_ps();
void sub_688217();
-bool sub_98196C(uint32 image_id, sint8 x_offset, sint8 y_offset, sint16 bound_box_length_x, sint16 bound_box_length_y, sint8 bound_box_length_z, uint16 z_offset, uint32 rotation);
-bool sub_98197C(uint32 image_id, sint8 x_offset, sint8 y_offset, sint16 bound_box_length_x, sint16 bound_box_length_y, sint8 bound_box_length_z, uint16 z_offset, sint16 bound_box_offset_x, sint16 bound_box_offset_y, sint16 bound_box_offset_z, uint32 rotation);
-bool sub_98198C(uint32 image_id, sint8 x_offset, sint8 y_offset, sint16 bound_box_length_x, sint16 bound_box_length_y, sint8 bound_box_length_z, uint16 z_offset, sint16 bound_box_offset_x, uint16 bound_box_offset_y, sint16 bound_box_offset_z, uint32 rotation);
-bool sub_98199C(uint32 image_id, sint8 x_offset, sint8 y_offset, sint16 bound_box_length_x, sint16 bound_box_length_y, sint8 bound_box_length_z, uint16 z_offset, sint16 bound_box_offset_x, uint16 bound_box_offset_y, sint16 bound_box_offset_z, uint32 rotation);
-
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/paint/map_element/banner.c b/src/paint/map_element/banner.c
new file mode 100644
index 0000000000..3b97fec431
--- /dev/null
+++ b/src/paint/map_element/banner.c
@@ -0,0 +1,101 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
+
+#include "../paint.h"
+#include "../../addresses.h"
+#include "../../config.h"
+#include "../../game.h"
+#include "../../interface/viewport.h"
+#include "../../localisation/localisation.h"
+#include "../../world/banner.h"
+#include "../../world/scenery.h"
+
+/**
+ *
+ * rct2: 0x006B9CC4
+ */
+void banner_paint(uint8 direction, int height, rct_map_element* map_element)
+{
+ uint16 boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ;
+ rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*);
+
+ RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8_t) = VIEWPORT_INTERACTION_ITEM_BANNER;
+
+ if (dpi->zoom_level > 1 || RCT2_GLOBAL(0x9DEA6F, uint8_t) & 1) return;
+
+ height -= 16;
+
+ rct_scenery_entry* banner_scenery = g_bannerSceneryEntries[gBanners[map_element->properties.banner.index].type];
+
+ direction += map_element->properties.banner.position;
+ direction &= 3;
+
+ boundBoxOffsetX = RCT2_ADDRESS(0x98D884, uint16)[direction * 4];
+ boundBoxOffsetY = RCT2_ADDRESS(0x98D884 + 2, uint16)[direction * 4];
+ boundBoxOffsetZ = height + 2;
+
+ uint32 base_id = (direction << 1) + banner_scenery->image;
+ uint32 image_id = base_id;
+
+ if (map_element->flags & MAP_ELEMENT_FLAG_GHOST)//if being placed
+ {
+ RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8_t) = VIEWPORT_INTERACTION_ITEM_NONE;
+ image_id |= RCT2_ADDRESS(0x993CC4, uint32_t)[gConfigGeneral.construction_marker_colour];
+ }
+ else{
+ image_id |=
+ (gBanners[map_element->properties.banner.index].colour << 19) |
+ 0x20000000;
+ }
+
+ sub_98197C(image_id, 0, 0, 1, 1, 0x15, height, boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ, get_current_rotation());
+ boundBoxOffsetX = RCT2_ADDRESS(0x98D888, uint16)[direction * 4];
+ boundBoxOffsetY = RCT2_ADDRESS(0x98D888 + 2, uint16)[direction * 4];
+
+ image_id++;
+ sub_98197C(image_id, 0, 0, 1, 1, 0x15, height, boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ, get_current_rotation());
+
+ // Opposite direction
+ direction ^= 2;
+ direction--;
+ // If text not showing / ghost
+ if (direction >= 2 || (map_element->flags & MAP_ELEMENT_FLAG_GHOST)) return;
+
+ uint16 scrollingMode = banner_scenery->banner.scrolling_mode;
+ scrollingMode += direction;
+
+ RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, uint32) = 0;
+ RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 4, uint32_t) = 0;
+
+ rct_string_id string_id = STR_NO_ENTRY;
+ if (!(gBanners[map_element->properties.banner.index].flags & BANNER_FLAG_NO_ENTRY))
+ {
+ RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, uint16) = gBanners[map_element->properties.banner.index].string_idx;
+ string_id = STR_BANNER_TEXT;
+ }
+ if (gConfigGeneral.upper_case_banners) {
+ format_string_to_upper(RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char), string_id, RCT2_ADDRESS(RCT2_ADDRESS_COMMON_FORMAT_ARGS, void));
+ } else {
+ format_string(RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char), string_id, RCT2_ADDRESS(RCT2_ADDRESS_COMMON_FORMAT_ARGS, void));
+ }
+
+ gCurrentFontSpriteBase = FONT_SPRITE_BASE_TINY;
+
+ uint16 string_width = gfx_get_string_width(RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char));
+ uint16 scroll = (gCurrentTicks / 2) % string_width;
+
+ sub_98199C(scrolling_text_setup(string_id, scroll, scrollingMode), 0, 0, 1, 1, 0x15, height + 22, boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ, get_current_rotation());
+}
\ No newline at end of file
diff --git a/src/paint/map_element/entrance.c b/src/paint/map_element/entrance.c
new file mode 100644
index 0000000000..a1460c8b0f
--- /dev/null
+++ b/src/paint/map_element/entrance.c
@@ -0,0 +1,308 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
+
+#include "../paint.h"
+#include "../../addresses.h"
+#include "../../config.h"
+#include "../../game.h"
+#include "../../interface/viewport.h"
+#include "../../localisation/localisation.h"
+#include "../supports.h"
+#include "../../ride/ride_data.h"
+#include "../../world/entrance.h"
+#include "../../world/footpath.h"
+
+/**
+ *
+ * rct2: 0x0066508C, 0x00665540
+ */
+void ride_entrance_exit_paint(uint8 direction, int height, rct_map_element* map_element)
+{
+ rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*);
+ uint8 is_exit = map_element->properties.entrance.type == ENTRANCE_TYPE_RIDE_EXIT;
+
+ if (RCT2_GLOBAL(0x9DEA6F, uint8_t) & 1){
+ if (map_element->properties.entrance.ride_index != RCT2_GLOBAL(0x00F64DE8, uint8))
+ return;
+ }
+
+ rct_ride* ride = get_ride(map_element->properties.entrance.ride_index);
+ if (ride->entrance_style == RIDE_ENTRANCE_STYLE_NONE) return;
+
+ const rct_ride_entrance_definition *style = &RideEntranceDefinitions[ride->entrance_style];
+
+ uint8 colour_1, colour_2;
+ uint32 transparant_image_id = 0, image_id = 0;
+ if (style->flags & (1 << 30)) {
+ colour_1 = ride->track_colour_main[0] + 0x70;
+ transparant_image_id = (colour_1 << 19) | 0x40000000;
+ }
+
+ colour_1 = ride->track_colour_main[0];
+ colour_2 = ride->track_colour_additional[0];
+ image_id = (colour_1 << 19) | (colour_2 << 24) | 0xA0000000;
+
+ RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = VIEWPORT_INTERACTION_ITEM_RIDE;
+ RCT2_GLOBAL(0x009E32BC, uint32) = 0;
+
+ if (map_element->flags & MAP_ELEMENT_FLAG_GHOST){
+ RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = VIEWPORT_INTERACTION_ITEM_NONE;
+ image_id = RCT2_ADDRESS(0x993CC4, uint32_t)[gConfigGeneral.construction_marker_colour];
+ RCT2_GLOBAL(0x009E32BC, uint32) = image_id;
+ if (transparant_image_id)
+ transparant_image_id = image_id;
+ }
+
+ if (is_exit){
+ image_id |= style->sprite_index + direction + 8;
+ }
+ else{
+ image_id |= style->sprite_index + direction;
+ }
+ // Format modifed to stop repeated code
+
+ // Each entrance is split into 2 images for drawing
+ // Certain entrance styles have another 2 images to draw for coloured windows
+
+ sint8 ah = is_exit ? 0x23 : 0x33;
+
+ sint16 lengthY = (direction & 1) ? 28 : 2;
+ sint16 lengthX = (direction & 1) ? 2 : 28;
+
+ sub_98197C(image_id, 0, 0, lengthX, lengthY, ah, height, 2, 2, height, get_current_rotation());
+
+ if (transparant_image_id){
+ if (is_exit){
+ transparant_image_id |= style->sprite_index + direction + 24;
+ }
+ else{
+ transparant_image_id |= style->sprite_index + direction + 16;
+ }
+
+ sub_98199C(transparant_image_id, 0, 0, lengthX, lengthY, ah, height, 2, 2, height, get_current_rotation());
+ }
+
+ image_id += 4;
+
+ sub_98197C(image_id, 0, 0, lengthX, lengthY, ah, height, (direction & 1) ? 28 : 2, (direction & 1) ? 2 : 28, height, get_current_rotation());
+
+ if (transparant_image_id){
+ transparant_image_id += 4;
+ sub_98199C(transparant_image_id, 0, 0, lengthX, lengthY, ah, height, (direction & 1) ? 28 : 2, (direction & 1) ? 2 : 28, height, get_current_rotation());
+ }
+
+ uint32 eax = 0xFFFF0600 | ((height / 16) & 0xFF);
+ if (direction & 1){
+ RCT2_ADDRESS(0x009E30B6, uint32)[RCT2_GLOBAL(0x141F56B, uint8) / 2] = eax;
+ RCT2_GLOBAL(0x141F56B, uint8)++;
+ }
+ else{
+ RCT2_ADDRESS(0x009E3138, uint32)[RCT2_GLOBAL(0x141F56A, uint8) / 2] = eax;
+ RCT2_GLOBAL(0x141F56A, uint8)++;
+ }
+
+ if (!is_exit &&
+ !(map_element->flags & MAP_ELEMENT_FLAG_GHOST) &&
+ map_element->properties.entrance.ride_index != 0xFF){
+
+ RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, uint32) = 0;
+ RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 4, uint32) = 0;
+
+ rct_string_id string_id = STR_RIDE_ENTRANCE_CLOSED;
+
+ if (ride->status == RIDE_STATUS_OPEN &&
+ !(ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN)){
+
+ RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 0, rct_string_id) = ride->name;
+ RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 2, uint32) = ride->name_arguments;
+
+ string_id = STR_RIDE_ENTRANCE_NAME;
+ }
+
+ utf8 entrance_string[MAX_PATH];
+ if (gConfigGeneral.upper_case_banners) {
+ format_string_to_upper(entrance_string, string_id, RCT2_ADDRESS(RCT2_ADDRESS_COMMON_FORMAT_ARGS, void));
+ } else {
+ format_string(entrance_string, string_id, RCT2_ADDRESS(RCT2_ADDRESS_COMMON_FORMAT_ARGS, void));
+ }
+
+ gCurrentFontSpriteBase = FONT_SPRITE_BASE_TINY;
+
+ uint16 string_width = gfx_get_string_width(entrance_string);
+ uint16 scroll = (gCurrentTicks / 2) % string_width;
+
+ sub_98199C(scrolling_text_setup(string_id, scroll, style->scrolling_mode), 0, 0, 0x1C, 0x1C, 0x33, height + style->height, 2, 2, height + style->height, get_current_rotation());
+ }
+
+ image_id = RCT2_GLOBAL(0x009E32BC, uint32);
+ if (image_id == 0) {
+ image_id = SPRITE_ID_PALETTE_COLOUR_1(COLOUR_SATURATED_BROWN);
+ }
+ wooden_a_supports_paint_setup(direction & 1, 0, height, image_id, NULL);
+
+ 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 += is_exit ? 40 : 56;
+ if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) < height){
+ RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = height;
+ RCT2_GLOBAL(0x141E9DA, uint8) = 32;
+ }
+}
+
+/**
+ *
+ * rct2: 0x006658ED
+ */
+void park_entrance_paint(uint8 direction, int height, rct_map_element* map_element){
+ if (RCT2_GLOBAL(0x9DEA6F, uint8_t) & 1)
+ return;
+
+ RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = VIEWPORT_INTERACTION_ITEM_PARK;
+ RCT2_GLOBAL(0x009E32BC, uint32) = 0;
+ uint32 image_id, ghost_id = 0;
+ if (map_element->flags & MAP_ELEMENT_FLAG_GHOST){
+ RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = VIEWPORT_INTERACTION_ITEM_NONE;
+ ghost_id = RCT2_ADDRESS(0x993CC4, uint32)[gConfigGeneral.construction_marker_colour];
+ RCT2_GLOBAL(0x009E32BC, uint32) = ghost_id;
+ }
+
+ rct_path_type* path_entry = g_pathTypeEntries[map_element->properties.entrance.path_type];
+
+ // Index to which part of the entrance
+ // Middle, left, right
+ uint8 part_index = map_element->properties.entrance.index & 0xF;
+ rct_entrance_type* entrance;
+ uint8 di = (direction / 2 + part_index / 2) & 1 ? 0x1A : 0x20;
+
+ switch (part_index){
+ case 0:
+ image_id = (path_entry->image + 5 * (1 + (direction & 1))) | ghost_id;
+ sub_98197C(image_id, 0, 0, 32, 0x1C, 0, height, 0, 2, height, get_current_rotation());
+
+ entrance = (rct_entrance_type*)object_entry_groups[OBJECT_TYPE_PARK_ENTRANCE].chunks[0];
+ image_id = (entrance->image_id + direction * 3) | ghost_id;
+ sub_98197C(image_id, 0, 0, 0x1C, 0x1C, 0x2F, height, 2, 2, height + 32, get_current_rotation());
+
+ if ((direction + 1) & (1 << 1))
+ break;
+ if (ghost_id != 0)
+ break;
+
+ rct_string_id park_text_id = 1730;
+ RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, uint32) = 0;
+ RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 4, uint32) = 0;
+
+ if (gParkFlags & PARK_FLAGS_PARK_OPEN){
+ RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, rct_string_id) = gParkName;
+ RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 2, uint32) = gParkNameArgs;
+
+ park_text_id = 1731;
+ }
+
+ utf8 park_name[MAX_PATH];
+ if (gConfigGeneral.upper_case_banners) {
+ format_string_to_upper(park_name, park_text_id, RCT2_ADDRESS(RCT2_ADDRESS_COMMON_FORMAT_ARGS, void));
+ } else {
+ format_string(park_name, park_text_id, RCT2_ADDRESS(RCT2_ADDRESS_COMMON_FORMAT_ARGS, void));
+ }
+
+ gCurrentFontSpriteBase = FONT_SPRITE_BASE_TINY;
+ uint16 string_width = gfx_get_string_width(park_name);
+ uint16 scroll = (gCurrentTicks / 2) % string_width;
+
+ if (entrance->scrolling_mode == 0xFF)
+ break;
+
+ sub_98199C(scrolling_text_setup(park_text_id, scroll, entrance->scrolling_mode + direction / 2), 0, 0, 0x1C, 0x1C, 0x2F, height + entrance->text_height, 2, 2, height + entrance->text_height, get_current_rotation());
+ break;
+ case 1:
+ case 2:
+ entrance = (rct_entrance_type*)object_entry_groups[OBJECT_TYPE_PARK_ENTRANCE].chunks[0];
+ image_id = (entrance->image_id + part_index + direction * 3) | ghost_id;
+ sub_98197C(image_id, 0, 0, 0x1A, di, 0x4F, height, 3, 3, height, get_current_rotation());
+ break;
+ }
+
+ image_id = ghost_id;
+ if (image_id == 0) {
+ image_id = SPRITE_ID_PALETTE_COLOUR_1(COLOUR_SATURATED_BROWN);
+ }
+ wooden_a_supports_paint_setup(direction & 1, 0, height, image_id, NULL);
+
+ 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 += 80;
+ if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) < height){
+ RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = height;
+ RCT2_GLOBAL(0x141E9DA, uint8) = 32;
+ }
+}
+
+/**
+ *
+ * rct2: 0x00664FD4
+ */
+void entrance_paint(uint8 direction, int height, rct_map_element* map_element){
+ RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8_t) = VIEWPORT_INTERACTION_ITEM_LABEL;
+
+ rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*);
+
+ if (gCurrentViewportFlags & VIEWPORT_FLAG_PATH_HEIGHTS &&
+ dpi->zoom_level == 0){
+ uint32 ebx =
+ (map_element->properties.entrance.type << 4) |
+ (map_element->properties.entrance.index & 0xF);
+
+ if (RCT2_ADDRESS(0x0097B974, uint8)[ebx] & 0xF){
+
+ int z = map_element->base_height * 8 + 3;
+ uint32 image_id =
+ z / 16 +
+ RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_HEIGHT_MARKERS,sint16) +
+ 0x20101689;
+
+ image_id -= RCT2_GLOBAL(0x01359208, sint16);
+
+ sub_98197C(image_id, 16, 16, 1, 1, 0, height, 31, 31, z + 64, get_current_rotation());
+ }
+ }
+
+ switch (map_element->properties.entrance.type){
+ case ENTRANCE_TYPE_RIDE_ENTRANCE:
+ case ENTRANCE_TYPE_RIDE_EXIT:
+ ride_entrance_exit_paint(direction, height, map_element);
+ break;
+ case ENTRANCE_TYPE_PARK_ENTRANCE:
+ park_entrance_paint(direction, height, map_element);
+ break;
+ }
+}
\ No newline at end of file
diff --git a/src/paint/map_element/fence.c b/src/paint/map_element/fence.c
new file mode 100644
index 0000000000..939c697c22
--- /dev/null
+++ b/src/paint/map_element/fence.c
@@ -0,0 +1,23 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
+
+#include "map_element.h"
+#include "../../addresses.h"
+#include "../../world/map.h"
+
+void fence_paint(uint8 direction, int height, rct_map_element* mapElement) {
+ RCT2_CALLPROC_X(0x6E44B0, 0, 0, direction, height, (int)mapElement, 0, 0);
+}
\ No newline at end of file
diff --git a/src/paint/map_element/map_element.c b/src/paint/map_element/map_element.c
new file mode 100644
index 0000000000..abcee7de65
--- /dev/null
+++ b/src/paint/map_element/map_element.c
@@ -0,0 +1,288 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
+
+#include "../paint.h"
+#include "../../interface/viewport.h"
+#include "../../addresses.h"
+#include "map_element.h"
+#include "../../drawing/drawing.h"
+#include "../../ride/ride_data.h"
+#include "../../ride/track_data.h"
+#include "../../ride/track_paint.h"
+#include "../../config.h"
+#include "../../world/sprite.h"
+#include "../../world/banner.h"
+#include "../../world/entrance.h"
+#include "../../world/footpath.h"
+#include "../../world/scenery.h"
+#include "../../sprites.h"
+#include "../../localisation/localisation.h"
+#include "../../game.h"
+#include "../supports.h"
+
+static void blank_tiles_paint(int x, int y);
+static void sub_68B3FB(int x, int y);
+
+/**
+ *
+ * rct2: 0x0068B35F
+ */
+void map_element_paint_setup(int x, int y)
+{
+ rct_drawpixelinfo *dpi = RCT2_GLOBAL(0x0140E9A8, rct_drawpixelinfo*);
+ if (
+ x < gMapSizeUnits &&
+ y < gMapSizeUnits &&
+ x >= 32 &&
+ y >= 32
+ ) {
+ RCT2_GLOBAL(0x0141E9B4, uint32) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9B8, uint32) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9BC, uint32) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9C0, uint32) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9C4, uint32) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9C8, uint32) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9CC, uint32) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9D0, uint32) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9D4, uint32) = 0xFFFF;
+ RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = -1;
+ RCT2_GLOBAL(0x0141E9DA, sint16) = 0;
+ RCT2_GLOBAL(0x0141E9DC, uint32) = 0xFFFF;
+
+ sub_68B3FB(x, y);
+ } else {
+ blank_tiles_paint(x, y);
+ }
+}
+
+/**
+ *
+ * rct2: 0x0068B2B7
+ */
+void sub_68B2B7(int x, int y)
+{
+ if (
+ x < gMapSizeUnits &&
+ y < gMapSizeUnits &&
+ x >= 32 &&
+ y >= 32
+ ) {
+ RCT2_GLOBAL(0x0141E9B4, uint32) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9B8, uint32) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9BC, uint32) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9C0, uint32) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9C4, uint32) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9C8, uint32) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9CC, uint32) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9D0, uint32) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9D4, uint32) = 0xFFFF;
+ RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = -1;
+ RCT2_GLOBAL(0x0141E9DA, uint16) = 0;
+ RCT2_GLOBAL(0x0141E9DC, uint32) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9DB, uint8) |= 2;
+
+ sub_68B3FB(x, y);
+ } else {
+ blank_tiles_paint(x, y);
+ }
+}
+
+/**
+ *
+ * rct2: 0x0068B60E
+ */
+static void blank_tiles_paint(int x, int y)
+{
+ rct_drawpixelinfo *dpi = RCT2_GLOBAL(0x0140E9A8, rct_drawpixelinfo*);
+
+ int dx;
+ switch (get_current_rotation()) {
+ case 0:
+ dx = x + y;
+ break;
+ case 1:
+ x += 32;
+ dx = y - x;
+ break;
+ case 2:
+ x += 32;
+ y += 32;
+ dx = -(x + y);
+ break;
+ case 3:
+ y += 32;
+ dx = x - y;
+ break;
+ }
+ dx /= 2;
+ dx -= 16;
+ int bx = dx + 32;
+ if (bx <= dpi->y) return;
+ dx -= 20;
+ dx -= dpi->height;
+ if (dx >= dpi->y) return;
+ RCT2_GLOBAL(0x9DE568, sint16) = x;
+ RCT2_GLOBAL(0x9DE56C, sint16) = y;
+ RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8_t) = VIEWPORT_INTERACTION_ITEM_NONE;
+ RCT2_CALLPROC_X(
+ (int)RCT2_ADDRESS(0x98196C, uint32_t*)[get_current_rotation()],
+ 0xFF00,
+ 3123,
+ y & 0xFF00,
+ 16,
+ 32,
+ 32,
+ get_current_rotation()
+ );
+}
+
+/**
+ *
+ * rct2: 0x0068B3FB
+ */
+static void sub_68B3FB(int x, int y)
+{
+ rct_drawpixelinfo *dpi = RCT2_GLOBAL(0x0140E9A8, rct_drawpixelinfo*);
+
+ RCT2_GLOBAL(0x141F56A, uint16_t) = 0;
+ RCT2_GLOBAL(0x9E3138, uint8_t) = 0xFF;
+ RCT2_GLOBAL(0x9E30B6, uint8_t) = 0xFF;
+ RCT2_GLOBAL(0x9E323C, uint8_t) = 0xFF;
+ RCT2_GLOBAL(0x9DE56A, uint16_t) = x;
+ RCT2_GLOBAL(0x9DE56E, uint16_t) = y;
+ RCT2_GLOBAL(0x9DE574, uint16_t) = x;
+ RCT2_GLOBAL(0x9DE576, uint16_t) = y;
+
+ rct_map_element* map_element = map_get_first_element_at(x >> 5, y >> 5);
+ uint8 rotation = get_current_rotation();
+
+ int dx = 0;
+ switch (rotation) {
+ case 0:
+ dx = x + y;
+ break;
+ case 1:
+ x += 32;
+ dx = y - x;
+ break;
+ case 2:
+ x += 32;
+ y += 32;
+ dx = -(x + y);
+ break;
+ case 3:
+ y += 32;
+ dx = x - y;
+ break;
+ }
+ dx >>= 1;
+ // Display little yellow arrow when building footpaths?
+ if ((RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) & 4) &&
+ RCT2_GLOBAL(0x9DE56A, uint16) == RCT2_GLOBAL(RCT2_ADDRESS_MAP_ARROW_X, uint16) &&
+ RCT2_GLOBAL(0x9DE56E, uint16) == RCT2_GLOBAL(RCT2_ADDRESS_MAP_ARROW_Y, uint16)){
+ uint8 arrowRotation =
+ (rotation
+ + (RCT2_GLOBAL(RCT2_ADDRESS_MAP_ARROW_DIRECTION, uint8) & 3)) & 3;
+
+ uint32 imageId =
+ arrowRotation +
+ (RCT2_GLOBAL(RCT2_ADDRESS_MAP_ARROW_DIRECTION, uint8) & 0xFC) +
+ 0x20900C27;
+ int arrowZ = RCT2_GLOBAL(RCT2_ADDRESS_MAP_ARROW_Z, uint16);
+
+ RCT2_GLOBAL(0x9DE568, sint16) = x;
+ RCT2_GLOBAL(0x9DE56C, sint16) = y;
+ RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = VIEWPORT_INTERACTION_ITEM_NONE;
+
+ sub_98197C(imageId, 0, 0, 32, 32, 0xFF, arrowZ, 0, 0, arrowZ + 18, rotation);
+ }
+ int bx = dx + 52;
+
+ if (bx <= dpi->y)
+ return;
+
+ const rct_map_element* element = map_element;//push map_element
+
+ sint16 max_height = 0;
+ do{
+ max_height = max(max_height, element->clearance_height);
+ } while (!map_element_is_last_for_tile(element++));
+
+ element--;
+
+ if (map_element_get_type(element) == MAP_ELEMENT_TYPE_SURFACE &&
+ (element->properties.surface.terrain & MAP_ELEMENT_WATER_HEIGHT_MASK) != 0){
+ max_height = (element->properties.surface.terrain & MAP_ELEMENT_WATER_HEIGHT_MASK) << 1;
+ }
+
+ max_height *= 8;
+
+ dx -= max_height + 32;
+
+ element = map_element;//pop map_element
+ dx -= dpi->height;
+ if (dx >= dpi->y)
+ return;
+
+ RCT2_GLOBAL(0x9DE568, sint16) = x;
+ RCT2_GLOBAL(0x9DE56C, sint16) = y;
+ RCT2_GLOBAL(0x9DE57C, uint16) = 0;
+ do {
+ int direction = (map_element->type + rotation) & MAP_ELEMENT_DIRECTION_MASK;
+ int height = map_element->base_height * 8;
+
+ uint32_t dword_9DE574 = RCT2_GLOBAL(0x9DE574, uint32_t);
+ RCT2_GLOBAL(0x9DE578, rct_map_element*) = map_element;
+ //setup the painting of for example: the underground, signs, rides, scenery, etc.
+ switch (map_element_get_type(map_element))
+ {
+ case MAP_ELEMENT_TYPE_SURFACE:
+ surface_paint(direction, height, map_element);
+ break;
+ case MAP_ELEMENT_TYPE_PATH:
+ path_paint(direction, height, map_element);
+ break;
+ case MAP_ELEMENT_TYPE_TRACK:
+ track_paint(direction, height, map_element);
+ break;
+ case MAP_ELEMENT_TYPE_SCENERY:
+ scenery_paint(direction, height, map_element);
+ break;
+ case MAP_ELEMENT_TYPE_ENTRANCE:
+ entrance_paint(direction, height, map_element);
+ break;
+ case MAP_ELEMENT_TYPE_FENCE:
+ fence_paint(direction, height, map_element);
+ break;
+ case MAP_ELEMENT_TYPE_SCENERY_MULTIPLE:
+ scenery_multiple_paint(direction, height, map_element);
+ break;
+ case MAP_ELEMENT_TYPE_BANNER:
+ banner_paint(direction, height, map_element);
+ break;
+ // A corrupt element inserted by OpenRCT2 itself, which skips the drawing of the next element only.
+ case MAP_ELEMENT_TYPE_CORRUPT:
+ if (map_element_is_last_for_tile(map_element))
+ return;
+ map_element++;
+ break;
+ default:
+ // An undefined map element is most likely a corrupt element inserted by 8 cars' MOM feature to skip drawing of all elements after it.
+ return;
+ }
+ RCT2_GLOBAL(0x9DE574, uint32_t) = dword_9DE574;
+ } while (!map_element_is_last_for_tile(map_element++));
+}
diff --git a/src/paint/map_element/map_element.h b/src/paint/map_element/map_element.h
new file mode 100644
index 0000000000..dbdaae8a44
--- /dev/null
+++ b/src/paint/map_element/map_element.h
@@ -0,0 +1,34 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
+
+#ifndef _PAINT_MAP_ELEMENT_H
+#define _PAINT_MAP_ELEMENT_H
+
+#include "../../common.h"
+#include "../../world/map.h"
+
+void map_element_paint_setup(int x, int y);
+
+void entrance_paint(uint8 direction, int height, rct_map_element* map_element);
+void banner_paint(uint8 direction, int height, rct_map_element* map_element);
+void surface_paint(uint8 direction, uint16 height, rct_map_element *mapElement);
+void path_paint(uint8 direction, uint16 height, rct_map_element *mapElement);
+void scenery_paint(uint8 direction, int height, rct_map_element* mapElement);
+void fence_paint(uint8 direction, int height, rct_map_element* mapElement);
+void scenery_multiple_paint(uint8 direction, uint16 height, rct_map_element *mapElement);
+void track_paint(uint8 direction, int height, rct_map_element *mapElement);
+
+#endif
\ No newline at end of file
diff --git a/src/paint/map_element/path.c b/src/paint/map_element/path.c
new file mode 100644
index 0000000000..d53e2d8ea5
--- /dev/null
+++ b/src/paint/map_element/path.c
@@ -0,0 +1,23 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion.
+
+#include "map_element.h"
+#include "../../addresses.h"
+#include "../../world/map.h"
+
+void path_paint(uint8 direction, uint16 height, rct_map_element *mapElement) {
+ RCT2_CALLPROC_X(0x6A3590, 0, 0, direction, height, (int)mapElement, 0, 0);
+}
\ No newline at end of file
diff --git a/src/paint/map_element/scenery.c b/src/paint/map_element/scenery.c
new file mode 100644
index 0000000000..e11b0327bb
--- /dev/null
+++ b/src/paint/map_element/scenery.c
@@ -0,0 +1,23 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
+
+#include "map_element.h"
+#include "../../addresses.h"
+#include "../../world/map.h"
+
+void scenery_paint(uint8 direction, int height, rct_map_element* mapElement) {
+ RCT2_CALLPROC_X(0x6DFF47, 0, 0, direction, height, (int)mapElement, 0, 0);
+}
\ No newline at end of file
diff --git a/src/paint/map_element/scenery_multiple.c b/src/paint/map_element/scenery_multiple.c
new file mode 100644
index 0000000000..76d9fb543f
--- /dev/null
+++ b/src/paint/map_element/scenery_multiple.c
@@ -0,0 +1,23 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
+
+#include "map_element.h"
+#include "../../addresses.h"
+#include "../../world/map.h"
+
+void scenery_multiple_paint(uint8 direction, uint16 height, rct_map_element *mapElement) {
+ RCT2_CALLPROC_X(0x6B7F0C, 0, 0, direction, height, (int)mapElement, 0, 0);
+}
\ No newline at end of file
diff --git a/src/interface/paint_surface.c b/src/paint/map_element/surface.c
similarity index 98%
rename from src/interface/paint_surface.c
rename to src/paint/map_element/surface.c
index f6b3a4e33e..35e2e081bb 100644
--- a/src/interface/paint_surface.c
+++ b/src/paint/map_element/surface.c
@@ -14,12 +14,13 @@
*****************************************************************************/
#pragma endregion
-#include "../common.h"
-#include "paint_surface.h"
-#include "viewport.h"
-#include "../config.h"
-#include "../peep/staff.h"
-#include "../world/map.h"
+#include "../../common.h"
+#include "surface.h"
+#include "../../interface/viewport.h"
+#include "../paint.h"
+#include "../../config.h"
+#include "../../peep/staff.h"
+#include "../../world/map.h"
const uint8 byte_97B444[] = {
0, 2, 1, 3, 8, 10, 9, 11, 4, 6,
@@ -467,11 +468,12 @@ void viewport_surface_smoothen_edge(enum edge edge, struct tile_descriptor self,
uint32 image_id = maskImageBase + byte_97B444[self.slope];
- paint_struct * out;
- if (sub_68818E(image_id, 0, 0, &out)) {
+ attached_paint_struct * out;
+ if (paint_attach_to_previous_ps(image_id, 0, 0)) {
+ out = RCT2_GLOBAL(0xF1AD2C, attached_paint_struct *);
// set content and enable masking
- out->var_04 = dword_97B804[neighbour.terrain] + cl;
- out->var_0C |= 1;
+ out->colour_image_id = dword_97B804[neighbour.terrain] + cl;
+ out->flags |= PAINT_STRUCT_FLAG_IS_MASKED;
}
}
@@ -529,7 +531,7 @@ void viewport_surface_draw_land_side_top(enum edge edge, uint8 height, uint8 ter
uint32 image_id = stru_97B5C0[terrain][3] + (edge == EDGE_TOPLEFT ? 3 : 0) + incline; // var_c;
sint16 y = (regs.dl - regs.al) * 16;
- sub_68818E(image_id, 0, y, NULL);
+ paint_attach_to_previous_ps(image_id, 0, y);
return;
}
@@ -1002,7 +1004,7 @@ void viewport_surface_draw_water_side_bottom(enum edge edge, uint8 height, uint8
* @param height (dx)
* @param map_element (esi)
*/
-void viewport_surface_paint_setup(uint8 direction, uint16 height, rct_map_element * mapElement)
+void surface_paint(uint8 direction, uint16 height, rct_map_element * mapElement)
{
rct_drawpixelinfo * dpi = RCT2_GLOBAL(0x0140E9A8, rct_drawpixelinfo*);
RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = VIEWPORT_INTERACTION_ITEM_TERRAIN;
@@ -1184,7 +1186,7 @@ void viewport_surface_paint_setup(uint8 direction, uint16 height, rct_map_elemen
image_id |= SPR_TERRAIN_SELECTION_PATROL_AREA + byte_97B444[surfaceShape];
image_id |= patrolColour << 19;
- sub_68818E(image_id, 0, 0, NULL);
+ paint_attach_to_previous_ps(image_id, 0, 0);
}
}
@@ -1212,7 +1214,7 @@ void viewport_surface_paint_setup(uint8 direction, uint16 height, rct_map_elemen
if (mapElement->properties.surface.ownership & OWNERSHIP_OWNED) {
assert(surfaceShape < countof(byte_97B444));
// TODO: SPR_TERRAIN_SELECTION_SQUARE?
- sub_68818E(2625 + byte_97B444[surfaceShape], 0, 0, NULL);
+ paint_attach_to_previous_ps(2625 + byte_97B444[surfaceShape], 0, 0);
} else if (mapElement->properties.surface.ownership & OWNERSHIP_AVAILABLE) {
rct_xy16 pos = {RCT2_GLOBAL(0x009DE56A, sint16), RCT2_GLOBAL(0x009DE56E, sint16)};
paint_struct * backup = RCT2_GLOBAL(0xF1AD28, paint_struct*);
@@ -1227,7 +1229,7 @@ void viewport_surface_paint_setup(uint8 direction, uint16 height, rct_map_elemen
if (mapElement->properties.surface.ownership & OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED) {
assert(surfaceShape < countof(byte_97B444));
// TODO: SPR_TERRAIN_SELECTION_DOTTED ???
- sub_68818E(2644 + byte_97B444[surfaceShape], 0, 0, NULL);
+ paint_attach_to_previous_ps(2644 + byte_97B444[surfaceShape], 0, 0);
} else if (mapElement->properties.surface.ownership & OWNERSHIP_CONSTRUCTION_RIGHTS_AVAILABLE) {
paint_struct * backup = RCT2_GLOBAL(0xF1AD28, paint_struct*);
rct_xy16 pos = {RCT2_GLOBAL(0x009DE56A, sint16), RCT2_GLOBAL(0x009DE56E, sint16)};
@@ -1255,13 +1257,13 @@ void viewport_surface_paint_setup(uint8 direction, uint16 height, rct_map_elemen
// loc_661089:
uint32 eax = ((((mapSelectionType - 9) + get_current_rotation()) & 3) + 0x21) << 19;
uint32 image_id = (SPR_TERRAIN_SELECTION_EDGE + byte_97B444[surfaceShape]) | eax | 0x20000000;
- sub_68818E(image_id, 0, 0, NULL);
+ paint_attach_to_previous_ps(image_id, 0, 0);
} else if (mapSelectionType >= 6) {
// loc_661051:(no jump)
// Selection split into four quarter segments
uint32 eax = ((((mapSelectionType - 6) + get_current_rotation()) & 3) + 0x27) << 19;
uint32 image_id = (SPR_TERRAIN_SELECTION_QUARTER + byte_97B444[surfaceShape]) | eax | 0x20000000;
- sub_68818E(image_id, 0, 0, NULL);
+ paint_attach_to_previous_ps(image_id, 0, 0);
} else if (mapSelectionType <= 4) {
// Corners
uint32 eax = mapSelectionType;
@@ -1271,7 +1273,7 @@ void viewport_surface_paint_setup(uint8 direction, uint16 height, rct_map_elemen
eax = (eax + 0x21) << 19;
uint32 image_id = (SPR_TERRAIN_SELECTION_CORNER + byte_97B444[surfaceShape]) | eax | 0x20000000;
- sub_68818E(image_id, 0, 0, NULL);
+ paint_attach_to_previous_ps(image_id, 0, 0);
} else {
int local_surfaceShape = surfaceShape;
int local_height = height;
@@ -1319,7 +1321,7 @@ void viewport_surface_paint_setup(uint8 direction, uint16 height, rct_map_elemen
}
uint32 image_id = (SPR_TERRAIN_SELECTION_CORNER + byte_97B444[surfaceShape]) | colours | 0x20000000;
- sub_68818E(image_id, 0, 0, NULL);
+ paint_attach_to_previous_ps(image_id, 0, 0);
break;
}
}
@@ -1346,7 +1348,7 @@ void viewport_surface_paint_setup(uint8 direction, uint16 height, rct_map_elemen
base_image = byte_97B84A[terrain_type];
}
uint32 image_id = dword_97B7C8[base_image] + image_offset;
- sub_68818E(image_id, 0, 0, NULL);
+ paint_attach_to_previous_ps(image_id, 0, 0);
}
if (!(gCurrentViewportFlags & VIEWPORT_FLAG_HIDE_VERTICAL)) {
@@ -1391,7 +1393,7 @@ void viewport_surface_paint_setup(uint8 direction, uint16 height, rct_map_elemen
int image_id = (SPR_WATER_MASK + image_offset) | 0x61000000;
sub_98196C(image_id, 0, 0, 32, 32, -1, waterHeight, get_current_rotation());
- sub_68818E(SPR_WATER_OVERLAY + image_offset, 0, 0, NULL);
+ paint_attach_to_previous_ps(SPR_WATER_OVERLAY + image_offset, 0, 0);
for (int i = 0; i <= 0x7C; i += 4) {
RCT2_GLOBAL(0x009E3138 + i, uint32) = RCT2_GLOBAL(0x009E2F30 + i, uint32);
diff --git a/src/interface/paint_surface.h b/src/paint/map_element/surface.h
similarity index 96%
rename from src/interface/paint_surface.h
rename to src/paint/map_element/surface.h
index 4ccd5deb54..ebdd9d30b7 100644
--- a/src/interface/paint_surface.h
+++ b/src/paint/map_element/surface.h
@@ -17,8 +17,8 @@
#ifndef _PAINT_SURFACE_H
#define _PAINT_SURFACE_H
-#include "../common.h"
-#include "../world/map.h"
+#include "../../common.h"
+#include "../../world/map.h"
enum
{
@@ -100,6 +100,6 @@ enum
SPR_TERRAIN_PATTERN_ICE = 29007,
};
-void viewport_surface_paint_setup(uint8 direction, uint16 height, rct_map_element *mapElement);
+
#endif //_PAINT_SURFACE_H
diff --git a/src/interface/paint.c b/src/paint/paint.c
similarity index 50%
rename from src/interface/paint.c
rename to src/paint/paint.c
index 456bce4264..3021bb2816 100644
--- a/src/interface/paint.c
+++ b/src/paint/paint.c
@@ -1,5 +1,26 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
+
#include "paint.h"
#include "../drawing/drawing.h"
+#include "../localisation/localisation.h"
+#include "../config.h"
+#include "../interface/viewport.h"
+#include "map_element/map_element.h"
+#include "sprite/sprite.h"
#include "../addresses.h"
/**
@@ -18,47 +39,6 @@ void painter_setup() {
RCT2_GLOBAL(0xF1AD24, uint32) = 0;
}
-/**
- *
- * rct2: 0x006874B0, 0x00687618, 0x0068778C, 0x00687902, 0x0098199C
- *
- * @param image_id (ebx)
- * @param x_offset (al)
- * @param y_offset (cl)
- * @param bound_box_length_x (di)
- * @param bound_box_length_y (si)
- * @param bound_box_length_z (ah)
- * @param z_offset (dx)
- * @param bound_box_offset_x (0x009DEA52)
- * @param bound_box_offset_y (0x009DEA54)
- * @param bound_box_offset_z (0x009DEA56)
- * @param rotation (ebp)
- * @return (!CF) success
- */
-bool sub_98199C(
- uint32 image_id,
- sint8 x_offset, sint8 y_offset,
- sint16 bound_box_length_x, sint16 bound_box_length_y, sint8 bound_box_length_z,
- uint16 z_offset,
- sint16 bound_box_offset_x, uint16 bound_box_offset_y, sint16 bound_box_offset_z,
- uint32 rotation
-) {
- RCT2_GLOBAL(RCT2_ADDRESS_PAINT_BOUNDBOX_OFFSET_X, uint16) = bound_box_offset_x;
- RCT2_GLOBAL(RCT2_ADDRESS_PAINT_BOUNDBOX_OFFSET_Y, uint16) = bound_box_offset_y;
- RCT2_GLOBAL(RCT2_ADDRESS_PAINT_BOUNDBOX_OFFSET_Z, uint16) = bound_box_offset_z;
-
- int flags = RCT2_CALLPROC_X(RCT2_ADDRESS(0x98199C, uint32_t)[rotation],
- x_offset | (bound_box_length_z << 8),
- image_id,
- y_offset,
- z_offset,
- bound_box_length_y,
- bound_box_length_x,
- rotation);
-
- return !(flags & (1 << 8));
-}
-
/**
* rct2: 0x006861AC, 0x00686337, 0x006864D0, 0x0068666B, 0x0098196C
*
@@ -312,6 +292,47 @@ bool sub_98198C(
return !(flags & (1 << 8));
}
+/**
+ *
+ * rct2: 0x006874B0, 0x00687618, 0x0068778C, 0x00687902, 0x0098199C
+ *
+ * @param image_id (ebx)
+ * @param x_offset (al)
+ * @param y_offset (cl)
+ * @param bound_box_length_x (di)
+ * @param bound_box_length_y (si)
+ * @param bound_box_length_z (ah)
+ * @param z_offset (dx)
+ * @param bound_box_offset_x (0x009DEA52)
+ * @param bound_box_offset_y (0x009DEA54)
+ * @param bound_box_offset_z (0x009DEA56)
+ * @param rotation (ebp)
+ * @return (!CF) success
+ */
+bool sub_98199C(
+ uint32 image_id,
+ sint8 x_offset, sint8 y_offset,
+ sint16 bound_box_length_x, sint16 bound_box_length_y, sint8 bound_box_length_z,
+ uint16 z_offset,
+ sint16 bound_box_offset_x, uint16 bound_box_offset_y, sint16 bound_box_offset_z,
+ uint32 rotation
+) {
+ RCT2_GLOBAL(RCT2_ADDRESS_PAINT_BOUNDBOX_OFFSET_X, uint16) = bound_box_offset_x;
+ RCT2_GLOBAL(RCT2_ADDRESS_PAINT_BOUNDBOX_OFFSET_Y, uint16) = bound_box_offset_y;
+ RCT2_GLOBAL(RCT2_ADDRESS_PAINT_BOUNDBOX_OFFSET_Z, uint16) = bound_box_offset_z;
+
+ int flags = RCT2_CALLPROC_X(RCT2_ADDRESS(0x98199C, uint32_t)[rotation],
+ x_offset | (bound_box_length_z << 8),
+ image_id,
+ y_offset,
+ z_offset,
+ bound_box_length_y,
+ bound_box_length_x,
+ rotation);
+
+ return !(flags & (1 << 8));
+}
+
/**
* rct2: 0x006881D0
*
@@ -431,3 +452,395 @@ void sub_685EBC(money32 amount, uint16 string_id, sint16 y, sint16 z, sint8 y_of
oldPs->next = ps;
}
}
+
+/**
+ *
+ * rct2: 0x0068B6C2
+ */
+void viewport_paint_setup()
+{
+ rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*);
+
+ rct_xy16 mapTile = {
+ .x = dpi->x & 0xFFE0,
+ .y = (dpi->y - 16) & 0xFFE0
+ };
+
+ sint16 half_x = mapTile.x >> 1;
+
+ uint16 num_vertical_quadrants = (dpi->height + 2128) >> 5;
+
+ switch (get_current_rotation()){
+ case 0:
+ mapTile.x = mapTile.y - half_x;
+ mapTile.y = mapTile.y + half_x;
+
+ mapTile.x &= 0xFFE0;
+ mapTile.y &= 0xFFE0;
+
+ for (; num_vertical_quadrants > 0; --num_vertical_quadrants){
+ map_element_paint_setup(mapTile.x, mapTile.y);
+ sprite_paint_setup(mapTile.x, mapTile.y);
+
+ sprite_paint_setup(mapTile.x - 32, mapTile.y + 32);
+
+ map_element_paint_setup(mapTile.x, mapTile.y + 32);
+ sprite_paint_setup(mapTile.x, mapTile.y + 32);
+
+ mapTile.x += 32;
+ sprite_paint_setup(mapTile.x, mapTile.y);
+
+ mapTile.y += 32;
+ }
+ break;
+ case 1:
+ mapTile.x = -mapTile.y - half_x;
+ mapTile.y = mapTile.y - half_x - 16;
+
+ mapTile.x &= 0xFFE0;
+ mapTile.y &= 0xFFE0;
+
+ for (; num_vertical_quadrants > 0; --num_vertical_quadrants){
+ map_element_paint_setup(mapTile.x, mapTile.y);
+ sprite_paint_setup(mapTile.x, mapTile.y);
+
+ sprite_paint_setup(mapTile.x - 32, mapTile.y - 32);
+
+ map_element_paint_setup(mapTile.x - 32, mapTile.y);
+ sprite_paint_setup(mapTile.x - 32, mapTile.y);
+
+ mapTile.y += 32;
+ sprite_paint_setup(mapTile.x, mapTile.y);
+
+ mapTile.x -= 32;
+ }
+ break;
+ case 2:
+ mapTile.x = -mapTile.y + half_x;
+ mapTile.y = -mapTile.y - half_x;
+
+ mapTile.x &= 0xFFE0;
+ mapTile.y &= 0xFFE0;
+
+ for (; num_vertical_quadrants > 0; --num_vertical_quadrants){
+ map_element_paint_setup(mapTile.x, mapTile.y);
+ sprite_paint_setup(mapTile.x, mapTile.y);
+
+ sprite_paint_setup(mapTile.x + 32, mapTile.y - 32);
+
+ map_element_paint_setup(mapTile.x, mapTile.y - 32);
+ sprite_paint_setup(mapTile.x, mapTile.y - 32);
+
+ mapTile.x -= 32;
+
+ sprite_paint_setup(mapTile.x, mapTile.y);
+
+ mapTile.y -= 32;
+ }
+ break;
+ case 3:
+ mapTile.x = mapTile.y + half_x;
+ mapTile.y = -mapTile.y + half_x - 16;
+
+ mapTile.x &= 0xFFE0;
+ mapTile.y &= 0xFFE0;
+
+ for (; num_vertical_quadrants > 0; --num_vertical_quadrants){
+ map_element_paint_setup(mapTile.x, mapTile.y);
+ sprite_paint_setup(mapTile.x, mapTile.y);
+
+ sprite_paint_setup(mapTile.x + 32, mapTile.y + 32);
+
+ map_element_paint_setup(mapTile.x + 32, mapTile.y);
+ sprite_paint_setup(mapTile.x + 32, mapTile.y);
+
+ mapTile.y -= 32;
+
+ sprite_paint_setup(mapTile.x, mapTile.y);
+
+ mapTile.x += 32;
+ }
+ break;
+ }
+}
+
+void sub_688217_helper(uint16 ax, uint8 flag)
+{
+ paint_struct *ps, *ps_temp;
+ paint_struct *ps_next = RCT2_GLOBAL(0x00EE7884, paint_struct*);
+
+ do {
+ ps = ps_next;
+ ps_next = ps_next->next_quadrant_ps;
+ if (ps_next == NULL) return;
+ } while (ax > ps_next->var_18);
+
+ ps_temp = ps;
+
+ do {
+ ps = ps->next_quadrant_ps;
+ if (ps == NULL) break;
+
+ if (ps->var_18 > ax + 1) {
+ ps->var_1B = 1 << 7;
+ }
+ else if (ps->var_18 == ax + 1) {
+ ps->var_1B = (1 << 1) | (1 << 0);
+ }
+ else if (ps->var_18 == ax) {
+ ps->var_1B = flag | (1 << 0);
+ }
+ } while (ps->var_18 <= ax + 1);
+
+ ps = ps_temp;
+
+ uint8 rotation = get_current_rotation();
+ while (true) {
+ while (true) {
+ ps_next = ps->next_quadrant_ps;
+ if (ps_next == NULL) return;
+ if (ps_next->var_1B & (1 << 7)) return;
+ if (ps_next->var_1B & (1 << 0)) break;
+ ps = ps_next;
+ }
+
+ ps_next->var_1B &= ~(1 << 0);
+ ps_temp = ps;
+
+ typedef struct bound_box {
+ uint16 x;
+ uint16 y;
+ uint16 z;
+ uint16 x_end;
+ uint16 y_end;
+ uint16 z_end;
+ } bound_box;
+
+ bound_box initialBBox = {
+ .x = ps_next->bound_box_x,
+ .y = ps_next->bound_box_y,
+ .z = ps_next->bound_box_z,
+ .x_end = ps_next->bound_box_x_end,
+ .y_end = ps_next->bound_box_y_end,
+ .z_end = ps_next->bound_box_z_end
+ };
+
+
+ while (true) {
+ ps = ps_next;
+ ps_next = ps_next->next_quadrant_ps;
+ if (ps_next == NULL) break;
+ if (ps_next->var_1B & (1 << 7)) break;
+ if (!(ps_next->var_1B & (1 << 1))) continue;
+
+ int yes = 0;
+ switch (rotation) {
+ case 0:
+ if (initialBBox.z_end >= ps_next->bound_box_z && initialBBox.y_end >= ps_next->bound_box_y && initialBBox.x_end >= ps_next->bound_box_x
+ && !(initialBBox.z < ps_next->bound_box_z_end && initialBBox.y < ps_next->bound_box_y_end && initialBBox.x < ps_next->bound_box_x_end))
+ yes = 1;
+ break;
+ case 1:
+ if (initialBBox.z_end >= ps_next->bound_box_z && initialBBox.y_end >= ps_next->bound_box_y && initialBBox.x_end < ps_next->bound_box_x
+ && !(initialBBox.z < ps_next->bound_box_z_end && initialBBox.y < ps_next->bound_box_y_end && initialBBox.x >= ps_next->bound_box_x_end))
+ yes = 1;
+ break;
+ case 2:
+ if (initialBBox.z_end >= ps_next->bound_box_z && initialBBox.y_end < ps_next->bound_box_y && initialBBox.x_end < ps_next->bound_box_x
+ && !(initialBBox.z < ps_next->bound_box_z_end && initialBBox.y >= ps_next->bound_box_y_end && initialBBox.x >= ps_next->bound_box_x_end))
+ yes = 1;
+ break;
+ case 3:
+ if (initialBBox.z_end >= ps_next->bound_box_z && initialBBox.y_end < ps_next->bound_box_y && initialBBox.x_end >= ps_next->bound_box_x
+ && !(initialBBox.z < ps_next->bound_box_z_end && initialBBox.y >= ps_next->bound_box_y_end && initialBBox.x < ps_next->bound_box_x_end))
+ yes = 1;
+ break;
+ }
+
+ if (yes) {
+ ps->next_quadrant_ps = ps_next->next_quadrant_ps;
+ paint_struct *ps_temp2 = ps_temp->next_quadrant_ps;
+ ps_temp->next_quadrant_ps = ps_next;
+ ps_next->next_quadrant_ps = ps_temp2;
+ ps_next = ps;
+ }
+ }
+
+ ps = ps_temp;
+ }
+}
+
+/**
+ *
+ * rct2: 0x00688217
+ */
+void sub_688217()
+{
+ paint_struct *ps = RCT2_GLOBAL(0x00EE7888, paint_struct*);
+ paint_struct *ps_next;
+ RCT2_GLOBAL(0x00EE7888, paint_struct*)++;
+ RCT2_GLOBAL(0x00EE7884, paint_struct*) = ps;
+ ps->next_quadrant_ps = NULL;
+ uint32 edi = RCT2_GLOBAL(0x00F1AD0C, uint32);
+ if (edi == -1)
+ return;
+
+ do {
+ ps_next = RCT2_GLOBAL(0x00F1A50C + 4 * edi, paint_struct*);
+ if (ps_next != NULL) {
+ ps->next_quadrant_ps = ps_next;
+ do {
+ ps = ps_next;
+ ps_next = ps_next->next_quadrant_ps;
+ } while (ps_next != NULL);
+ }
+ } while (++edi <= RCT2_GLOBAL(0x00F1AD10, uint32));
+
+ uint32 eax = RCT2_GLOBAL(0x00F1AD0C, uint32);
+
+ sub_688217_helper(eax & 0xFFFF, 1 << 1);
+
+ eax = RCT2_GLOBAL(0x00F1AD0C, uint32);
+
+ while (++eax < RCT2_GLOBAL(0x00F1AD10, uint32))
+ sub_688217_helper(eax & 0xFFFF, 0);
+}
+
+/**
+ *
+ * rct2: 0x00688596
+ * Part of 0x688485
+ */
+void paint_attached_ps(paint_struct* ps, attached_paint_struct* attached_ps, rct_drawpixelinfo* dpi) {
+ for (; attached_ps; attached_ps = attached_ps->next) {
+ sint16 x = attached_ps->x + ps->x;
+ sint16 y = attached_ps->y + ps->y;
+
+ int image_id = attached_ps->image_id;
+ if (gCurrentViewportFlags & VIEWPORT_FLAG_SEETHROUGH_RIDES) {
+ if (ps->sprite_type == 3) {
+ if (image_id & 0x40000000) {
+ image_id &= 0x7FFFF;
+ image_id |= 0x41880000;
+ }
+ }
+ }
+
+ if (gCurrentViewportFlags & VIEWPORT_FLAG_SEETHROUGH_SCENERY) {
+ if (ps->sprite_type == 5) {
+ if (image_id & 0x40000000) {
+ image_id &= 0x7FFFF;
+ image_id |= 0x41880000;
+ }
+ }
+ }
+
+ if (attached_ps->flags & PAINT_STRUCT_FLAG_IS_MASKED) {
+ gfx_draw_sprite_raw_masked(dpi, x, y, image_id, attached_ps->colour_image_id);
+ }
+ else {
+ gfx_draw_sprite(dpi, image_id, x, y, ps->tertiary_colour);
+ }
+ }
+}
+
+/* rct2: 0x00688485 */
+void paint_quadrant_ps() {
+ rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*);
+ paint_struct* ps = RCT2_GLOBAL(0xEE7884, paint_struct*);
+ paint_struct* previous_ps = ps->next_quadrant_ps;
+
+ for (ps = ps->next_quadrant_ps; ps;) {
+ sint16 x = ps->x;
+ sint16 y = ps->y;
+ if (ps->sprite_type == 2) {
+ if (dpi->zoom_level >= 1) {
+ x &= 0xFFFE;
+ y &= 0xFFFE;
+ if (dpi->zoom_level >= 2) {
+ x &= 0xFFFC;
+ y &= 0xFFFC;
+ }
+ }
+ }
+ int image_id = ps->image_id;
+ if (gCurrentViewportFlags & VIEWPORT_FLAG_SEETHROUGH_RIDES) {
+ if (ps->sprite_type == 3) {
+ if (!(image_id & 0x40000000)) {
+ image_id &= 0x7FFFF;
+ image_id |= 0x41880000;
+ }
+ }
+ }
+ if (gCurrentViewportFlags & VIEWPORT_FLAG_UNDERGROUND_INSIDE) {
+ if (ps->sprite_type == 9) {
+ if (!(image_id & 0x40000000)) {
+ image_id &= 0x7FFFF;
+ image_id |= 0x41880000;
+ }
+ }
+ }
+ if (gCurrentViewportFlags & VIEWPORT_FLAG_SEETHROUGH_SCENERY) {
+ if (ps->sprite_type == 10 || ps->sprite_type == 12 || ps->sprite_type == 9 || ps->sprite_type == 5) {
+ if (!(image_id & 0x40000000)) {
+ image_id &= 0x7FFFF;
+ image_id |= 0x41880000;
+ }
+ }
+ }
+
+ if (ps->flags & PAINT_STRUCT_FLAG_IS_MASKED)
+ gfx_draw_sprite_raw_masked(dpi, x, y, image_id, ps->colour_image_id);
+ else
+ gfx_draw_sprite(dpi, image_id, x, y, ps->tertiary_colour);
+
+ if (ps->var_20 != 0) {
+ ps = ps->var_20;
+ continue;
+ }
+
+ paint_attached_ps(ps, ps->attached_ps, dpi);
+ ps = previous_ps->next_quadrant_ps;
+ previous_ps = ps;
+ }
+
+}
+
+static void draw_pixel_info_crop_by_zoom(rct_drawpixelinfo *dpi)
+{
+ int zoom = dpi->zoom_level;
+ dpi->zoom_level = 0;
+ dpi->x >>= zoom;
+ dpi->y >>= zoom;
+ dpi->width >>= zoom;
+ dpi->height >>= zoom;
+}
+
+/**
+ *
+ * rct2: 0x006860C3
+ */
+void viewport_draw_money_effects()
+{
+ utf8 buffer[256];
+
+ paint_string_struct *ps = RCT2_GLOBAL(0x00F1AD20, paint_string_struct*);
+ if (ps == NULL)
+ return;
+
+ rct_drawpixelinfo dpi = *(RCT2_GLOBAL(0x0140E9A8, rct_drawpixelinfo*));
+ draw_pixel_info_crop_by_zoom(&dpi);
+
+ do {
+ format_string(buffer, ps->string_id, &ps->args);
+ gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM;
+
+ bool forceSpriteFont = false;
+ const currency_descriptor *currencyDesc = &CurrencyDescriptors[gConfigGeneral.currency_format];
+ if (gUseTrueTypeFont && font_supports_string_sprite(currencyDesc->symbol_unicode)) {
+ forceSpriteFont = true;
+ }
+
+ gfx_draw_string_with_y_offsets(&dpi, buffer, 0, ps->x, ps->y, (sint8 *)ps->y_offsets, forceSpriteFont);
+ } while ((ps = ps->next) != NULL);
+}
diff --git a/src/interface/paint.h b/src/paint/paint.h
similarity index 50%
rename from src/interface/paint.h
rename to src/paint/paint.h
index c1fe8a5bf4..ca97b281f2 100644
--- a/src/interface/paint.h
+++ b/src/paint/paint.h
@@ -1,3 +1,19 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
+
#ifndef _PAINT_H
#define _PAINT_H
@@ -69,8 +85,18 @@ enum PAINT_STRUCT_FLAGS {
PAINT_STRUCT_FLAG_IS_MASKED = (1 << 0)
};
+void painter_setup();
+
+bool sub_98196C(uint32 image_id, sint8 x_offset, sint8 y_offset, sint16 bound_box_length_x, sint16 bound_box_length_y, sint8 bound_box_length_z, uint16 z_offset, uint32 rotation);
+bool sub_98197C(uint32 image_id, sint8 x_offset, sint8 y_offset, sint16 bound_box_length_x, sint16 bound_box_length_y, sint8 bound_box_length_z, uint16 z_offset, sint16 bound_box_offset_x, sint16 bound_box_offset_y, sint16 bound_box_offset_z, uint32 rotation);
+bool sub_98198C(uint32 image_id, sint8 x_offset, sint8 y_offset, sint16 bound_box_length_x, sint16 bound_box_length_y, sint8 bound_box_length_z, uint16 z_offset, sint16 bound_box_offset_x, uint16 bound_box_offset_y, sint16 bound_box_offset_z, uint32 rotation);
+bool sub_98199C(uint32 image_id, sint8 x_offset, sint8 y_offset, sint16 bound_box_length_x, sint16 bound_box_length_y, sint8 bound_box_length_z, uint16 z_offset, sint16 bound_box_offset_x, uint16 bound_box_offset_y, sint16 bound_box_offset_z, uint32 rotation);
+
bool paint_attach_to_previous_attach(uint32 image_id, uint16 x, uint16 y);
bool paint_attach_to_previous_ps(uint32 image_id, uint16 x, uint16 y);
void sub_685EBC(money32 amount, uint16 string_id, sint16 y, sint16 z, sint8 y_offsets[], sint16 offset_x, uint32 rotation);
+void viewport_draw_money_effects();
+void viewport_paint_setup();
+
#endif
diff --git a/src/paint/sprite/litter.c b/src/paint/sprite/litter.c
new file mode 100644
index 0000000000..59a49b5557
--- /dev/null
+++ b/src/paint/sprite/litter.c
@@ -0,0 +1,42 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
+
+#include "sprite.h"
+#include "../../world/sprite.h"
+#include "../../interface/viewport.h"
+#include "../paint.h"
+
+/**
+ * Litter Paint Setup
+ * rct2: 0x006736FC
+ */
+void litter_paint(rct_litter *litter, int imageDirection)
+{
+ rct_drawpixelinfo *dpi;
+
+ dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*);
+ if (dpi->zoom_level != 0) return; // If zoomed at all no litter drawn
+
+ // litter has no sprite direction so remove that
+ imageDirection >>= 3;
+ // Some litter types have only 1 direction so remove
+ // anything that isn't required.
+ imageDirection &= RCT2_ADDRESS(0x97EF6C, uint32)[litter->type * 2 + 1];
+
+ uint32 image_id = imageDirection + RCT2_ADDRESS(0x97EF6C, uint32)[litter->type * 2];
+
+ sub_98197C(image_id, 0, 0, 4, 4, -1, litter->z, -4, -4, litter->z + 2, get_current_rotation());
+}
\ No newline at end of file
diff --git a/src/paint/sprite/misc.c b/src/paint/sprite/misc.c
new file mode 100644
index 0000000000..2ec1304bc7
--- /dev/null
+++ b/src/paint/sprite/misc.c
@@ -0,0 +1,27 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
+
+#include "../../world/sprite.h"
+#include "../../addresses.h"
+
+/**
+ *
+ * rct2: 0x00672AC9
+ */
+void misc_paint(rct_sprite *misc, int imageDirection)
+{
+ RCT2_CALLPROC_X(0x00672AC9, misc->unknown.x, imageDirection, misc->unknown.y, misc->unknown.z, (int)misc, 0, 0);
+}
\ No newline at end of file
diff --git a/src/paint/sprite/peep.c b/src/paint/sprite/peep.c
new file mode 100644
index 0000000000..6b359a76a0
--- /dev/null
+++ b/src/paint/sprite/peep.c
@@ -0,0 +1,68 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
+
+#include "../../world/sprite.h"
+#include "../../interface/viewport.h"
+#include "../../peep/peep.h"
+#include "../paint.h"
+
+/**
+ *
+ * rct2: 0x0068F0FB
+ */
+void peep_paint(rct_peep * peep, int imageDirection)
+{
+ rct_drawpixelinfo * dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*);
+ if (dpi->zoom_level > 2) {
+ return;
+ }
+
+ if (gCurrentViewportFlags & VIEWPORT_FLAG_INVISIBLE_PEEPS) {
+ return;
+ }
+
+ rct_sprite_entry sprite = g_sprite_entries[peep->sprite_type];
+
+ uint8 spriteType = peep->action_sprite_type;
+ uint8 imageOffset = peep->action_sprite_image_offset;
+
+ if (peep->action == PEEP_ACTION_NONE_1) {
+ spriteType = peep->next_action_sprite_type;
+ imageOffset = 0;
+ }
+
+ uint32 baseImageId = (imageDirection >> 3) + sprite.sprite_image[spriteType].base_image + imageOffset * 4;
+ uint32 imageId = baseImageId | peep->tshirt_colour << 19 | peep->trousers_colour << 24 | 0xA0000000;
+ sub_98197C(imageId, 0, 0, 1, 1, 11, peep->z, 0, 0, peep->z + 3, get_current_rotation());
+
+ if (baseImageId >= 10717 && baseImageId < 10749) {
+ imageId = baseImageId + 32 | peep->hat_colour << 19 | 0x20000000;
+ sub_98199C(imageId, 0, 0, 1, 1, 11, peep->z, 0, 0, peep->z + 3, get_current_rotation());
+ return;
+ }
+
+ if (baseImageId >= 10781 && baseImageId < 10813) {
+ imageId = baseImageId + 32 | peep->balloon_colour << 19 | 0x20000000;
+ sub_98199C(imageId, 0, 0, 1, 1, 11, peep->z, 0, 0, peep->z + 3, get_current_rotation());
+ return;
+ }
+
+ if (baseImageId >= 11197 && baseImageId < 11229) {
+ imageId = baseImageId + 32 | peep->umbrella_colour << 19 | 0x20000000;
+ sub_98199C(imageId, 0, 0, 1, 1, 11, peep->z, 0, 0, peep->z + 3, get_current_rotation());
+ return;
+ }
+}
\ No newline at end of file
diff --git a/src/paint/sprite/sprite.c b/src/paint/sprite/sprite.c
new file mode 100644
index 0000000000..9b626cd517
--- /dev/null
+++ b/src/paint/sprite/sprite.c
@@ -0,0 +1,85 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
+
+#include "sprite.h"
+#include "../paint.h"
+#include "../../drawing/drawing.h"
+#include "../../world/sprite.h"
+#include "../../ride/ride_data.h"
+#include "../../interface/viewport.h"
+#include "../../ride/vehicle_paint.h"
+
+/**
+ * Paint Quadrant
+ * rct2: 0x0069E8B0
+ */
+void sprite_paint_setup(const uint16 eax, const uint16 ecx) {
+ rct_drawpixelinfo* dpi;
+
+ if ((eax & 0xe000) | (ecx & 0xe000)) return;
+
+ const int idx = ((eax << 3) & 0xff00) | (ecx >> 5);
+ int sprite_idx = RCT2_ADDRESS(0xF1EF60, uint16)[idx];
+ if (sprite_idx == SPRITE_INDEX_NULL) return;
+
+ if (RCT2_GLOBAL(0x9DEA6F, uint8) & 1) return;
+
+
+ if (gCurrentViewportFlags & VIEWPORT_FLAG_INVISIBLE_SPRITES) return;
+
+ dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*);
+ if (dpi->zoom_level > 2) return;
+
+
+ for (rct_sprite* spr = &g_sprite_list[sprite_idx]; sprite_idx != SPRITE_INDEX_NULL; sprite_idx = spr->unknown.next_in_quadrant) {
+ spr = &g_sprite_list[sprite_idx];
+ dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*);
+
+ if (dpi->y + dpi->height <= spr->unknown.sprite_top) continue;
+ if (spr->unknown.sprite_bottom <= dpi->y)continue;
+ if (dpi->x + dpi->width <= spr->unknown.sprite_left)continue;
+ if (spr->unknown.sprite_right <= dpi->x)continue;
+
+ int image_direction = get_current_rotation();
+ image_direction <<= 3;
+ image_direction += spr->unknown.sprite_direction;
+ image_direction &= 0x1F;
+
+ RCT2_GLOBAL(0x9DE578, uint32) = (uint32)spr;
+
+ RCT2_GLOBAL(0x9DE568, sint16) = spr->unknown.x;
+ RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = VIEWPORT_INTERACTION_ITEM_SPRITE;
+ RCT2_GLOBAL(0x9DE56C, sint16) = spr->unknown.y;
+
+ switch (spr->unknown.sprite_identifier) {
+ case SPRITE_IDENTIFIER_VEHICLE:
+ vehicle_paint((rct_vehicle*)spr, image_direction);
+ break;
+ case SPRITE_IDENTIFIER_PEEP:
+ peep_paint((rct_peep*)spr, image_direction);
+ break;
+ case SPRITE_IDENTIFIER_MISC:
+ misc_paint(spr, image_direction);
+ break;
+ case SPRITE_IDENTIFIER_LITTER:
+ litter_paint((rct_litter*)spr, image_direction);
+ break;
+ default:
+ assert(false);
+ break;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/paint/sprite/sprite.h b/src/paint/sprite/sprite.h
new file mode 100644
index 0000000000..0c4109afed
--- /dev/null
+++ b/src/paint/sprite/sprite.h
@@ -0,0 +1,30 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
+
+#ifndef _PAINT_SPRITE_H
+#define _PAINT_SPRITE_H
+
+#include "../../common.h"
+#include "../../world/sprite.h"
+
+void sprite_paint_setup(const uint16 eax, const uint16 ecx);
+
+void misc_paint(rct_sprite *misc, int imageDirection);
+void litter_paint(rct_litter *litter, int imageDirection);
+void peep_paint(rct_peep *peep, int imageDirection);
+void vehicle_paint(rct_vehicle *vehicle, int imageDirection);
+
+#endif
diff --git a/src/drawing/supports.c b/src/paint/supports.c
similarity index 99%
rename from src/drawing/supports.c
rename to src/paint/supports.c
index ab099fb554..1ff7e04c4a 100644
--- a/src/drawing/supports.c
+++ b/src/paint/supports.c
@@ -16,6 +16,7 @@
#include "../addresses.h"
#include "../interface/viewport.h"
+#include "../paint/paint.h"
#include "supports.h"
typedef struct {
diff --git a/src/drawing/supports.h b/src/paint/supports.h
similarity index 100%
rename from src/drawing/supports.h
rename to src/paint/supports.h
diff --git a/src/ride/coaster/air_powered_vertical_coaster.c b/src/ride/coaster/air_powered_vertical_coaster.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/coaster/air_powered_vertical_coaster.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/coaster/bobsleigh_coaster.c b/src/ride/coaster/bobsleigh_coaster.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/coaster/bobsleigh_coaster.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/coaster/compact_inverted_coaster.c b/src/ride/coaster/compact_inverted_coaster.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/coaster/compact_inverted_coaster.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/coaster/corkscrew_roller_coaster.c b/src/ride/coaster/corkscrew_roller_coaster.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/coaster/corkscrew_roller_coaster.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/coaster/flying_roller_coaster.c b/src/ride/coaster/flying_roller_coaster.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/coaster/flying_roller_coaster.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/coaster/giga_coaster.c b/src/ride/coaster/giga_coaster.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/coaster/giga_coaster.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/coaster/heartline_twister_coaster.c b/src/ride/coaster/heartline_twister_coaster.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/coaster/heartline_twister_coaster.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/coaster/inverted_hairpin_coaster.c b/src/ride/coaster/inverted_hairpin_coaster.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/coaster/inverted_hairpin_coaster.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/coaster/inverted_impulse_coaster.c b/src/ride/coaster/inverted_impulse_coaster.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/coaster/inverted_impulse_coaster.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/coaster/inverted_roller_coaster.c b/src/ride/coaster/inverted_roller_coaster.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/coaster/inverted_roller_coaster.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/coaster/junior_roller_coaster.c b/src/ride/coaster/junior_roller_coaster.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/coaster/junior_roller_coaster.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/coaster/lay_down_roller_coaster.c b/src/ride/coaster/lay_down_roller_coaster.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/coaster/lay_down_roller_coaster.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/coaster/lim_launched_roller_coaster.c b/src/ride/coaster/lim_launched_roller_coaster.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/coaster/lim_launched_roller_coaster.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/coaster/looping_roller_coaster.c b/src/ride/coaster/looping_roller_coaster.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/coaster/looping_roller_coaster.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/coaster/mine_ride.c b/src/ride/coaster/mine_ride.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/coaster/mine_ride.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/coaster/mine_train_coaster.c b/src/ride/coaster/mine_train_coaster.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/coaster/mine_train_coaster.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/coaster/mini_roller_coaster.c b/src/ride/coaster/mini_roller_coaster.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/coaster/mini_roller_coaster.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/coaster/mini_suspended_coaster.c b/src/ride/coaster/mini_suspended_coaster.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/coaster/mini_suspended_coaster.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/coaster/multi_dimension_roller_coaster.c b/src/ride/coaster/multi_dimension_roller_coaster.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/coaster/multi_dimension_roller_coaster.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/coaster/reverse_freefall_coaster.c b/src/ride/coaster/reverse_freefall_coaster.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/coaster/reverse_freefall_coaster.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/coaster/reverser_roller_coaster.c b/src/ride/coaster/reverser_roller_coaster.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/coaster/reverser_roller_coaster.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/coaster/side_friction_roller_coaster.c b/src/ride/coaster/side_friction_roller_coaster.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/coaster/side_friction_roller_coaster.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/coaster/spiral_roller_coaster.c b/src/ride/coaster/spiral_roller_coaster.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/coaster/spiral_roller_coaster.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/coaster/stand_up_roller_coaster.c b/src/ride/coaster/stand_up_roller_coaster.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/coaster/stand_up_roller_coaster.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/coaster/steeplechase.c b/src/ride/coaster/steeplechase.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/coaster/steeplechase.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/coaster/suspended_swinging_coaster.c b/src/ride/coaster/suspended_swinging_coaster.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/coaster/suspended_swinging_coaster.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/coaster/twister_roller_coaster.c b/src/ride/coaster/twister_roller_coaster.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/coaster/twister_roller_coaster.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/coaster/vertical_drop_roller_coaster.c b/src/ride/coaster/vertical_drop_roller_coaster.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/coaster/vertical_drop_roller_coaster.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/coaster/virginia_reel.c b/src/ride/coaster/virginia_reel.c
new file mode 100644
index 0000000000..ed1e6c2bed
--- /dev/null
+++ b/src/ride/coaster/virginia_reel.c
@@ -0,0 +1,83 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
+
+#include "../../addresses.h"
+#include "../../config.h"
+#include "../../interface/viewport.h"
+#include "../../world/sprite.h"
+#include "../../paint/paint.h"
+
+/**
+ *
+ * rct2: 0x006D5B48
+ */
+void vehicle_visual_virginia_reel(int x, int imageDirection, int y, int z, rct_vehicle *vehicle, const rct_ride_entry_vehicle *vehicleEntry)
+{
+ int image_id;
+ int baseImage_id = imageDirection;
+ int ecx = ((vehicle->var_BA / 8) + (get_current_rotation() * 8)) & 31;
+ int j = 0;
+ if (vehicle->vehicle_sprite_type == 0) {
+ baseImage_id = ecx & 7;
+ } else {
+ if (vehicle->vehicle_sprite_type == 1 || vehicle->vehicle_sprite_type == 5) {
+ if (vehicle->vehicle_sprite_type == 5){
+ baseImage_id = imageDirection ^ 16;
+ }
+ baseImage_id &= 24;
+ j = (baseImage_id / 8) + 1;
+ baseImage_id += (ecx & 7);
+ baseImage_id += 8;
+ } else
+ if (vehicle->vehicle_sprite_type == 2 || vehicle->vehicle_sprite_type == 6) {
+ if (vehicle->vehicle_sprite_type == 6){
+ baseImage_id = imageDirection ^ 16;
+ }
+ baseImage_id &= 24;
+ j = (baseImage_id / 8) + 5;
+ baseImage_id += (ecx & 7);
+ baseImage_id += 40;
+ } else {
+ baseImage_id = ecx & 7;
+ }
+ }
+ baseImage_id += vehicleEntry->base_image_id;
+
+ sint16 bbo_x = RCT2_ADDRESS(0x009927E6, sint8)[j * 8];
+ sint16 bbo_y = RCT2_ADDRESS(0x009927E7, sint8)[j * 8];
+ sint16 bbo_z = RCT2_ADDRESS(0x009927E8, sint8)[j * 8] + z;
+ uint16 bbl_x = RCT2_ADDRESS(0x009927E9, uint8)[j * 8];
+ uint16 bbl_y = RCT2_ADDRESS(0x009927EA, uint8)[j * 8];
+ uint8 bbl_z = RCT2_ADDRESS(0x009927EB, uint8)[j * 8];
+ image_id = baseImage_id | (vehicle->colours.body_colour << 19) | (vehicle->colours.trim_colour << 24) | 0xA0000000;
+ sub_98197C(image_id, 0, 0, bbl_x, bbl_y, bbl_z, z, bbo_x, bbo_y, bbo_z, get_current_rotation());
+
+ if (RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*)->zoom_level < 2 && vehicle->num_peeps > 0) {
+ uint8 riding_peep_sprites[4] = {0xFF, 0xFF, 0xFF, 0xFF};
+ for (int i = 0; i < vehicle->num_peeps; i++) {
+ riding_peep_sprites[((ecx / 8) + i) & 3] = vehicle->peep_tshirt_colours[i];
+ }
+ int draw_order[4] = {0, 1, 3, 2};
+ for (int i = 0; i < countof(draw_order); i++) {
+ if (riding_peep_sprites[draw_order[i]] != 0xFF) {
+ image_id = (baseImage_id + ((draw_order[i] + 1) * 72)) | (riding_peep_sprites[draw_order[i]] << 19) | 0x20000000;
+ sub_98199C(image_id, 0, 0, bbl_x, bbl_y, bbl_z, z, bbo_x, bbo_y, bbo_z, get_current_rotation());
+ }
+ }
+ }
+
+ assert(vehicleEntry->pad_5E == 1);
+}
\ No newline at end of file
diff --git a/src/ride/coaster/wild_mouse.c b/src/ride/coaster/wild_mouse.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/coaster/wild_mouse.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/coaster/wooden_roller_coaster.c b/src/ride/coaster/wooden_roller_coaster.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/coaster/wooden_roller_coaster.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/coaster/wooden_wild_mouse.c b/src/ride/coaster/wooden_wild_mouse.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/coaster/wooden_wild_mouse.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/gentle/car_ride.c b/src/ride/gentle/car_ride.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/gentle/car_ride.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/gentle/circus_show.c b/src/ride/gentle/circus_show.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/gentle/circus_show.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/gentle/crooked_house.c b/src/ride/gentle/crooked_house.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/gentle/crooked_house.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/gentle/dodgems.c b/src/ride/gentle/dodgems.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/gentle/dodgems.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/gentle/ferris_wheel.c b/src/ride/gentle/ferris_wheel.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/gentle/ferris_wheel.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/gentle/flying_saucers.c b/src/ride/gentle/flying_saucers.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/gentle/flying_saucers.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/gentle/ghost_train.c b/src/ride/gentle/ghost_train.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/gentle/ghost_train.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/gentle/haunted_house.c b/src/ride/gentle/haunted_house.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/gentle/haunted_house.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/gentle/maze.c b/src/ride/gentle/maze.c
new file mode 100644
index 0000000000..e2f90d827f
--- /dev/null
+++ b/src/ride/gentle/maze.c
@@ -0,0 +1,196 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
+
+#include "../../addresses.h"
+#include "../../paint/supports.h"
+#include "../../interface/viewport.h"
+#include "../../paint/paint.h"
+#include "../../sprites.h"
+#include "../../world/map.h"
+#include "../track_paint.h"
+
+enum {
+ SPR_MAZE_BASE_HEDGE = 21938,
+ SPR_MAZE_BASE_BRICK = 21951,
+ SPR_MAZE_BASE_ICE = 21964,
+ SPR_MAZE_BASE_WOOD = 21977,
+};
+
+enum {
+ SPR_MAZE_OFFSET_WALL_CENTER = 0,
+ SPR_MAZE_OFFSET_WALL_INNER_NE_SW,
+ SPR_MAZE_OFFSET_WALL_INNER_NW_SE,
+ SPR_MAZE_OFFSET_WALL_TOP_LEFT,
+ SPR_MAZE_OFFSET_WALL_TOP_RIGHT,
+ SPR_MAZE_OFFSET_WALL_BOTTOM_RIGHT,
+ SPR_MAZE_OFFSET_WALL_BOTTOM_LEFT,
+ SPR_MAZE_OFFSET_COLUMN_CENTER,
+ SPR_MAZE_OFFSET_COLUMN_TOP_RIGHT,
+ SPR_MAZE_OFFSET_COLUMN_TOP_LEFT,
+ SPR_MAZE_OFFSET_COLUMN_BOTTOM_LEFT,
+ SPR_MAZE_OFFSET_COLUMN_BOTTOM_RIGHT,
+ SPR_MAZE_OFFSET_COLUMN_CORNER,
+};
+
+/**
+ * rct: 0x004ACF4A
+ */
+static void maze_paint_setup(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element *mapElement) {
+ uint16 maze_entry = mapElement->properties.track.maze_entry;
+ maze_entry = rol16(maze_entry, direction * 4);
+
+ // draw ground
+ int image_id = 2485 | RCT2_GLOBAL(0x00F441A0, uint32);
+ sub_98196C(image_id, 0, 0, 32, 32, 0, height, get_current_rotation());
+
+ wooden_a_supports_paint_setup(direction & 1, 0, height, RCT2_GLOBAL(0x00F441A4, uint32), NULL);
+
+ RCT2_GLOBAL(0x0141E9B4, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9B8, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9BC, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9C0, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9C8, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9CC, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9D0, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9D4, uint16) = 0xFFFF;
+
+ int base_image_id;
+ switch (get_ride(rideIndex)->track_colour_supports[0]) {
+ case 0: base_image_id = SPR_MAZE_BASE_BRICK; break;
+ case 1: base_image_id = SPR_MAZE_BASE_HEDGE; break;
+ case 2: base_image_id = SPR_MAZE_BASE_ICE; break;
+ case 3: base_image_id = SPR_MAZE_BASE_WOOD; break;
+ }
+
+ base_image_id |= RCT2_GLOBAL(0x00F441A0, uint32);
+
+
+ image_id = base_image_id + SPR_MAZE_OFFSET_WALL_CENTER;
+ if (maze_entry & (1 << 3))
+ sub_98197C(image_id, 2, 2, 10, 10, 9, height, 3, 3, height + 2, get_current_rotation());
+
+ if (maze_entry & (1 << 7))
+ sub_98197C(image_id, 2, 18, 10, 10, 9, height, 3, 19, height + 2, get_current_rotation());
+
+ if (maze_entry & (1 << 11))
+ sub_98197C(image_id, 18, 18, 10, 10, 9, height, 19, 19, height + 2, get_current_rotation());
+
+ if (maze_entry & (1 << 15))
+ sub_98197C(image_id, 18, 2, 10, 10, 9, height, 19, 3, height + 2, get_current_rotation());
+
+
+ image_id = base_image_id + SPR_MAZE_OFFSET_WALL_TOP_LEFT;
+ if (maze_entry & (1 << 0))
+ sub_98197C(image_id, 2, 0, 10, 1, 9, height, 3, 1, height + 2, get_current_rotation());
+
+ if (maze_entry & (1 << 13))
+ sub_98197C(image_id, 18, 0, 10, 1, 9, height, 19, 1, height + 2, get_current_rotation());
+
+
+ image_id = base_image_id + SPR_MAZE_OFFSET_WALL_BOTTOM_RIGHT;
+ if (maze_entry & (1 << 5))
+ sub_98197C(image_id, 2, 30, 10, 1, 9, height, 3, 30, height + 2, get_current_rotation());
+
+ if (maze_entry & (1 << 8))
+ sub_98197C(image_id, 18, 30, 10, 1, 9, height, 19, 30, height + 2, get_current_rotation());
+
+
+ image_id = base_image_id + SPR_MAZE_OFFSET_WALL_TOP_RIGHT;
+ if (maze_entry & (1 << 1))
+ sub_98197C(image_id, 0, 2, 1, 10, 9, height, 1, 3, height + 2, get_current_rotation());
+
+ if (maze_entry & (1 << 4))
+ sub_98197C(image_id, 0, 18, 1, 10, 9, height, 1, 19, height + 2, get_current_rotation());
+
+
+ image_id = base_image_id + SPR_MAZE_OFFSET_WALL_BOTTOM_LEFT;
+ if (maze_entry & (1 << 12))
+ sub_98197C(image_id, 30, 2, 1, 10, 9, height, 30, 3, height + 2, get_current_rotation());
+
+ if (maze_entry & (1 << 9))
+ sub_98197C(image_id, 30, 18, 1, 10, 9, height, 30, 19, height + 2, get_current_rotation());
+
+
+ image_id = base_image_id + SPR_MAZE_OFFSET_WALL_INNER_NE_SW;
+ if (maze_entry & (1 << 2))
+ sub_98197C(image_id, 2, 14, 10, 4, 9, height, 3, 14, height + 2, get_current_rotation());
+
+ if (maze_entry & (1 << 10))
+ sub_98197C(image_id, 18, 14, 10, 4, 9, height, 19, 14, height + 2, get_current_rotation());
+
+
+ image_id = base_image_id + SPR_MAZE_OFFSET_WALL_INNER_NW_SE;
+ if (maze_entry & (1 << 14))
+ sub_98197C(image_id, 14, 2, 4, 10, 9, height, 14, 3, height + 2, get_current_rotation());
+
+ if (maze_entry & (1 << 6))
+ sub_98197C(image_id, 14, 18, 4, 10, 9, height, 14, 19, height + 2, get_current_rotation());
+
+
+ image_id = base_image_id + SPR_MAZE_OFFSET_COLUMN_CORNER;
+ if (maze_entry & (1 << 0 | 1 << 1))
+ sub_98197C(image_id, 0, 0, 1, 1, 9, height, 1, 1, height + 2, get_current_rotation());
+
+ if (maze_entry & (1 << 4 | 1 << 5))
+ sub_98197C(image_id, 0, 30, 1, 1, 9, height, 1, 30, height + 2, get_current_rotation());
+
+ if (maze_entry & (1 << 8 | 1 << 9))
+ sub_98197C(image_id, 30, 30, 1, 1, 9, height, 30, 30, height + 2, get_current_rotation());
+
+ if (maze_entry & (1 << 12 | 1 << 13))
+ sub_98197C(image_id, 30, 0, 1, 1, 9, height, 30, 1, height + 2, get_current_rotation());
+
+
+ if (maze_entry & (1 << 0 | 1 << 13 | 1 << 14))
+ sub_98197C(base_image_id + SPR_MAZE_OFFSET_COLUMN_TOP_LEFT, 14, 0, 2, 1, 9, height, 15, 1, height + 2, get_current_rotation());
+
+
+ if (maze_entry & (1 << 5 | 1 << 6 | 1 << 8))
+ sub_98197C(base_image_id + SPR_MAZE_OFFSET_COLUMN_BOTTOM_RIGHT, 14, 30, 2, 1, 9, height, 15, 30, height + 2, get_current_rotation());
+
+
+ if (maze_entry & (1 << 1 | 1 << 2 | 1 << 4))
+ sub_98197C(base_image_id + SPR_MAZE_OFFSET_COLUMN_TOP_RIGHT, 0, 14, 1, 2, 9, height, 1, 15, height + 2, get_current_rotation());
+
+
+ if (maze_entry & (1 << 9 | 1 << 10 | 1 << 12))
+ sub_98197C(base_image_id + SPR_MAZE_OFFSET_COLUMN_BOTTOM_LEFT, 30, 14, 1, 2, 9, height, 30, 15, height + 2, get_current_rotation());
+
+
+ if (maze_entry & (1 << 2 | 1 << 6 | 1 << 10 | 1 << 14)) {
+ sub_98197C(base_image_id + SPR_MAZE_OFFSET_COLUMN_CENTER, 14, 14, 2, 2, 8, height, 15, 15, height + 2, get_current_rotation());
+
+ RCT2_GLOBAL(0x141E9C4, uint16) = height + 12;
+ RCT2_GLOBAL(0x141E9C6, uint8) = 0x20;
+ }
+
+ height += 32;
+ if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) < height) {
+ RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = height;
+ RCT2_GLOBAL(0x141E9DA, uint8) = 0x20;
+ }
+}
+
+/**
+ * rct2: 0x008A81E8
+ */
+TRACK_PAINT_FUNCTION get_track_paint_function_maze(int trackType, int direction) {
+ if (trackType != 101) {
+ return NULL;
+ }
+
+ return maze_paint_setup;
+}
diff --git a/src/ride/gentle/merry_go_round.c b/src/ride/gentle/merry_go_round.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/gentle/merry_go_round.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/gentle/mini_golf.c b/src/ride/gentle/mini_golf.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/gentle/mini_golf.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/gentle/mini_helicopters.c b/src/ride/gentle/mini_helicopters.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/gentle/mini_helicopters.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/gentle/monorail_cycles.c b/src/ride/gentle/monorail_cycles.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/gentle/monorail_cycles.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/gentle/observation_tower.c b/src/ride/gentle/observation_tower.c
new file mode 100644
index 0000000000..e0694b0638
--- /dev/null
+++ b/src/ride/gentle/observation_tower.c
@@ -0,0 +1,58 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
+
+#include "../../addresses.h"
+#include "../../config.h"
+#include "../../interface/viewport.h"
+#include "../../world/sprite.h"
+#include "../../paint/paint.h"
+
+/**
+ *
+ * rct2: 0x006D6258
+ */
+void vehicle_visual_observation_tower(int x, int imageDirection, int y, int z, rct_vehicle *vehicle, const rct_ride_entry_vehicle *vehicleEntry)
+{
+ int image_id;
+ int baseImage_id = (vehicle->restraints_position / 64);
+ if (vehicle->restraints_position >= 64) {
+ if ((imageDirection / 8) && (imageDirection / 8) != 3) {
+ baseImage_id *= 2;
+ baseImage_id += vehicleEntry->base_image_id + 28;
+ if ((imageDirection / 8) != 1) {
+ baseImage_id -= 6;
+ }
+ } else {
+ baseImage_id = vehicleEntry->base_image_id + 8;
+ }
+ } else {
+ baseImage_id = (vehicle->var_C5 * 2) + vehicleEntry->base_image_id + 8;
+ }
+
+ image_id = baseImage_id | (vehicle->colours.body_colour << 19) | (vehicle->colours.trim_colour << 24) | 0x80000000;
+ if (sub_98197C(image_id, 0, 0, 2, 2, 41, z, -11, -11, z + 1, get_current_rotation())) {
+ paint_struct* ps = RCT2_GLOBAL(0xEE7888, paint_struct*) - 1; // sub_98197C increments this but need original
+ ps->tertiary_colour = vehicle->colours_extended;
+ }
+
+ image_id++;
+ if (sub_98197C(image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1, get_current_rotation())) {
+ paint_struct* ps = RCT2_GLOBAL(0xEE7888, paint_struct*) - 1; // sub_98197C increments this but need original
+ ps->tertiary_colour = vehicle->colours_extended;
+ }
+
+ assert(vehicleEntry->pad_5E == 1);
+}
diff --git a/src/ride/gentle/space_rings.c b/src/ride/gentle/space_rings.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/gentle/space_rings.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/gentle/spiral_slide.c b/src/ride/gentle/spiral_slide.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/gentle/spiral_slide.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/shops/facility.c b/src/ride/shops/facility.c
new file mode 100644
index 0000000000..bf1343c9a7
--- /dev/null
+++ b/src/ride/shops/facility.c
@@ -0,0 +1,93 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
+
+#include "../../addresses.h"
+#include "../../paint/supports.h"
+#include "../../interface/viewport.h"
+#include "../../paint/paint.h"
+#include "../../sprites.h"
+#include "../../world/map.h"
+#include "../track_paint.h"
+
+/**
+ *
+ * rct2: 0x00763234
+ * rct2: 0x0076338C
+ * rct2: 0x00762F50
+ * rct2: 0x007630DE
+ */
+static void facility_paint_setup(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element* mapElement)
+{
+ bool hasSupports = wooden_a_supports_paint_setup(direction & 1, 0, height, RCT2_GLOBAL(0x00F441A4, uint32), NULL);
+
+ RCT2_GLOBAL(0x0141E9D0, sint16) = -1;
+ RCT2_GLOBAL(0x0141E9C4, sint16) = -1;
+ RCT2_GLOBAL(0x0141E9CC, sint16) = -1;
+ RCT2_GLOBAL(0x0141E9B8, sint16) = -1;
+ RCT2_GLOBAL(0x0141E9BC, sint16) = -1;
+ RCT2_GLOBAL(0x0141E9B4, sint16) = -1;
+ RCT2_GLOBAL(0x0141E9C0, sint16) = -1;
+ RCT2_GLOBAL(0x0141E9C8, sint16) = -1;
+ RCT2_GLOBAL(0x0141E9D4, sint16) = -1;
+
+ rct_ride *ride = get_ride(rideIndex);
+ rct_ride_entry *rideEntry = get_ride_entry(ride->subtype);
+ rct_ride_entry_vehicle *firstVehicleEntry = &rideEntry->vehicles[0];
+
+ uint32 imageId = RCT2_GLOBAL(0x00F44198, uint32);
+ imageId |= firstVehicleEntry->base_image_id;
+ imageId += (direction + 2) & 3;
+
+ sint16 height16 = (sint16)height;
+ int rotation = get_current_rotation();
+ int lengthX = (direction & 1) == 0 ? 28 : 2;
+ int lengthY = (direction & 1) == 0 ? 2 : 28;
+ if (hasSupports) {
+ uint32 foundationImageId = RCT2_GLOBAL(0x00F441A4, uint32);
+ foundationImageId |= 3395;
+ sub_98197C(foundationImageId, 0, 0, lengthX, lengthY, 29, height, direction == 3 ? 28 : 2, direction == 0 ? 28 : 2, height16, rotation);
+
+ // Door image or base
+ sub_98199C(imageId, 0, 0, lengthX, lengthY, 29, height, direction == 3 ? 28 : 2, direction == 0 ? 28 : 2, height16, rotation);
+ } else {
+ // Door image or base
+ sub_98197C(imageId, 0, 0, lengthX, lengthY, 29, height, direction == 3 ? 28 : 2, direction == 0 ? 28 : 2, height16, rotation);
+ }
+
+ // Base image if door was drawn
+ if (direction == 1) {
+ imageId += 2;
+ sub_98197C(imageId, 0, 0, 2, 28, 29, height, 28, 2, height16, rotation);
+ } else if (direction == 2) {
+ imageId += 4;
+ sub_98197C(imageId, 0, 0, 28, 2, 29, height, 2, 28, height16, rotation);
+ }
+
+ height16 += 32;
+ if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) < height16) {
+ RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = height16;
+ RCT2_GLOBAL(0x00141E9DA, uint8) = 32;
+ }
+}
+
+/* 0x00762D44 */
+TRACK_PAINT_FUNCTION get_track_paint_function_facility(int trackType, int direction)
+{
+ switch (trackType) {
+ case 118: return facility_paint_setup;
+ }
+ return NULL;
+}
diff --git a/src/ride/shops/misc.c b/src/ride/shops/misc.c
new file mode 100644
index 0000000000..5bdb8af6e7
--- /dev/null
+++ b/src/ride/shops/misc.c
@@ -0,0 +1,78 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
+
+#include "../../addresses.h"
+#include "../../paint/supports.h"
+#include "../../interface/viewport.h"
+#include "../../paint/paint.h"
+#include "../../sprites.h"
+#include "../../world/map.h"
+#include "../track_paint.h"
+
+/**
+ * rct2: 0x00761378, 0x007614DB, 0x0076163F, 0x007617A5
+ */
+static void ride_50_52_53_54_paint_setup(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element *mapElement) {
+ bool supportsDrawn = wooden_a_supports_paint_setup(direction & 1, 0, height, RCT2_GLOBAL(0x00F441A4, uint32), NULL);
+
+ RCT2_GLOBAL(0x0141E9D0, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9C4, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9CC, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9B8, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9BC, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9B4, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9C0, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9C8, uint16) = 0xFFFF;
+ RCT2_GLOBAL(0x0141E9D4, uint16) = 0xFFFF;
+
+ rct_ride *ride = get_ride(rideIndex);
+
+ rct_ride_entry *rideEntry = get_ride_entry(ride->subtype);
+
+ uint32 image_id = RCT2_GLOBAL(0x00F44198, uint32);
+ if (image_id & 0x80000000) {
+ image_id &= 0x60FFFFFF;
+ }
+
+ image_id += rideEntry->vehicles[0].base_image_id;
+ image_id += direction;
+ if (supportsDrawn) {
+ uint32 ebx = (direction & 1 ? 3396 : 3395) | RCT2_GLOBAL(0x00F441A4, uint32);
+ sub_98197C(ebx, 0, 0, 28, 28, 45, height, 2, 2, height, get_current_rotation());
+
+ sub_98199C(image_id, 0, 0, 28, 28, 45, height, 2, 2, height, get_current_rotation());
+ } else {
+ sub_98197C(image_id, 0, 0, 28, 28, 45, height, 2, 2, height, get_current_rotation());
+ }
+
+ height += 48;
+ if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) < height) {
+ RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = height;
+ RCT2_GLOBAL(0x00141E9DA, uint8) = 0x20;
+ }
+}
+
+/**
+ * rct2: 0x00761160
+ */
+TRACK_PAINT_FUNCTION get_track_paint_function_50_52_53_54(int trackType, int direction) {
+ switch (trackType) {
+ case 118:
+ case 121:
+ return ride_50_52_53_54_paint_setup;
+ }
+ return NULL;
+}
\ No newline at end of file
diff --git a/src/ride/shops/shop.c b/src/ride/shops/shop.c
new file mode 100644
index 0000000000..e28a20de28
--- /dev/null
+++ b/src/ride/shops/shop.c
@@ -0,0 +1,84 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
+
+#include "../../addresses.h"
+#include "../../paint/supports.h"
+#include "../../interface/viewport.h"
+#include "../../paint/paint.h"
+#include "../../sprites.h"
+#include "../../world/map.h"
+#include "../track_paint.h"
+
+/**
+ *
+ * rct2: 0x00761378
+ * rct2: 0x007614DB
+ * rct2: 0x0076163F
+ * rct2: 0x007617A5
+ */
+static void shop_paint_setup(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element* mapElement)
+{
+ bool hasSupports = wooden_a_supports_paint_setup(direction & 1, 0, height, RCT2_GLOBAL(0x00F441A4, uint32), NULL);
+
+ RCT2_GLOBAL(0x0141E9D0, sint16) = -1;
+ RCT2_GLOBAL(0x0141E9C4, sint16) = -1;
+ RCT2_GLOBAL(0x0141E9CC, sint16) = -1;
+ RCT2_GLOBAL(0x0141E9B8, sint16) = -1;
+ RCT2_GLOBAL(0x0141E9BC, sint16) = -1;
+ RCT2_GLOBAL(0x0141E9B4, sint16) = -1;
+ RCT2_GLOBAL(0x0141E9C0, sint16) = -1;
+ RCT2_GLOBAL(0x0141E9C8, sint16) = -1;
+ RCT2_GLOBAL(0x0141E9D4, sint16) = -1;
+
+ rct_ride *ride = get_ride(rideIndex);
+ rct_ride_entry *rideEntry = get_ride_entry(ride->subtype);
+ rct_ride_entry_vehicle *firstVehicleEntry = &rideEntry->vehicles[0];
+
+ uint32 imageId = RCT2_GLOBAL(0x00F44198, uint32);
+ if (imageId & 0x80000000) {
+ imageId &= 0x60FFFFFF;
+ }
+ imageId += firstVehicleEntry->base_image_id;
+ imageId += direction;
+
+ sint16 height16 = (sint16)height;
+ int rotation = get_current_rotation();
+ if (hasSupports) {
+ uint32 foundationImageId = RCT2_GLOBAL(0x00F441A4, uint32);
+ foundationImageId |= 3395;
+ sub_98197C(foundationImageId, 0, 0, 28, 28, 45, height, 2, 2, height16, rotation);
+
+ sub_98199C(imageId, 0, 0, 28, 28, 45, height, 2, 2, height16, rotation);
+ } else {
+ sub_98197C(imageId, 0, 0, 28, 28, 45, height, 2, 2, height16, rotation);
+ }
+
+ height16 += 48;
+ if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) < height16) {
+ RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = height16;
+ RCT2_GLOBAL(0x00141E9DA, uint8) = 32;
+ }
+}
+
+/* 0x00761160 */
+TRACK_PAINT_FUNCTION get_track_paint_function_shop(int trackType, int direction)
+{
+ switch (trackType) {
+ case 118:
+ case 121: return shop_paint_setup;
+ }
+ return NULL;
+}
diff --git a/src/ride/thrill/3d_cinema.c b/src/ride/thrill/3d_cinema.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/thrill/3d_cinema.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/thrill/enterprise.c b/src/ride/thrill/enterprise.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/thrill/enterprise.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/thrill/go_karts.c b/src/ride/thrill/go_karts.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/thrill/go_karts.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/thrill/launched_freefall.c b/src/ride/thrill/launched_freefall.c
new file mode 100644
index 0000000000..09845d373a
--- /dev/null
+++ b/src/ride/thrill/launched_freefall.c
@@ -0,0 +1,65 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
+
+#include "../../addresses.h"
+#include "../../config.h"
+#include "../../interface/viewport.h"
+#include "../../world/sprite.h"
+#include "../../paint/paint.h"
+
+/**
+ *
+ * rct2: 0x006D5FAB
+ */
+void vehicle_visual_launched_freefall(int x, int imageDirection, int y, int z, rct_vehicle *vehicle, const rct_ride_entry_vehicle *vehicleEntry)
+{
+ int image_id;
+ int baseImage_id = vehicleEntry->base_image_id + ((vehicle->restraints_position / 64) * 2);
+
+ // Draw back:
+ image_id = (baseImage_id + 2) | (vehicle->colours.body_colour << 19) | (vehicle->colours.trim_colour << 24) | 0xA0000000;
+ sub_98197C(image_id, 0, 0, 2, 2, 41, z, -11, -11, z + 1, get_current_rotation());
+
+ // Draw front:
+ image_id = (baseImage_id + 1) | (vehicle->colours.body_colour << 19) | (vehicle->colours.trim_colour << 24) | 0xA0000000;
+ sub_98197C(image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1, get_current_rotation());
+
+ // Draw peeps:
+ if (RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*)->zoom_level < 2) {
+ if (vehicle->num_peeps > 0) {
+ baseImage_id = vehicleEntry->base_image_id + 9;
+ if ((vehicle->restraints_position / 64) == 3) {
+ baseImage_id += 2; // Draw peeps sitting without transparent area between them for restraints
+ }
+ image_id = (baseImage_id + ((((imageDirection / 8) + 0) & 3) * 3)) | (vehicle->peep_tshirt_colours[0] << 19) | (vehicle->peep_tshirt_colours[1] << 24) | 0xA0000000;
+ sub_98199C(image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1, get_current_rotation());
+ if (vehicle->num_peeps > 2) {
+ image_id = (baseImage_id + ((((imageDirection / 8) + 1) & 3) * 3)) | (vehicle->peep_tshirt_colours[2] << 19) | (vehicle->peep_tshirt_colours[3] << 24) | 0xA0000000;
+ sub_98199C(image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1, get_current_rotation());
+ }
+ if (vehicle->num_peeps > 4) {
+ image_id = (baseImage_id + ((((imageDirection / 8) + 2) & 3) * 3)) | (vehicle->peep_tshirt_colours[4] << 19) | (vehicle->peep_tshirt_colours[5] << 24) | 0xA0000000;
+ sub_98199C(image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1, get_current_rotation());
+ }
+ if (vehicle->num_peeps > 6) {
+ image_id = (baseImage_id + ((((imageDirection / 8) + 3) & 3) * 3)) | (vehicle->peep_tshirt_colours[6] << 19) | (vehicle->peep_tshirt_colours[7] << 24) | 0xA0000000;
+ sub_98199C(image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1, get_current_rotation());
+ }
+ }
+ }
+
+ assert(vehicleEntry->pad_5E == 1);
+}
diff --git a/src/ride/thrill/magic_carpet.c b/src/ride/thrill/magic_carpet.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/thrill/magic_carpet.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/thrill/motion_simulator.c b/src/ride/thrill/motion_simulator.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/thrill/motion_simulator.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/thrill/pirate_ship.c b/src/ride/thrill/pirate_ship.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/thrill/pirate_ship.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/thrill/roto_drop.c b/src/ride/thrill/roto_drop.c
new file mode 100644
index 0000000000..5f58cce21b
--- /dev/null
+++ b/src/ride/thrill/roto_drop.c
@@ -0,0 +1,72 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
+
+#include "../../addresses.h"
+#include "../../config.h"
+#include "../../interface/viewport.h"
+#include "../../world/sprite.h"
+#include "../../paint/paint.h"
+
+/**
+ *
+ * rct2: 0x006D5DA9
+ */
+void vehicle_visual_roto_drop(int x, int imageDirection, int y, int z, rct_vehicle *vehicle, const rct_ride_entry_vehicle *vehicleEntry)
+{
+ int image_id;
+ int baseImage_id = (vehicleEntry->base_image_id + 4) + ((vehicle->var_C5 / 4) & 0x3);
+ if (vehicle->restraints_position >= 64) {
+ baseImage_id += 7;
+ baseImage_id += (vehicle->restraints_position / 64);
+ }
+
+ // Draw back:
+ image_id = baseImage_id | (vehicle->colours.body_colour << 19) | (vehicle->colours.trim_colour << 24) | 0xA0000000;
+ sub_98197C(image_id, 0, 0, 2, 2, 41, z, -11, -11, z + 1, get_current_rotation());
+
+ // Draw front:
+ image_id = (baseImage_id + 4) | (vehicle->colours.body_colour << 19) | (vehicle->colours.trim_colour << 24) | 0xA0000000;
+ sub_98197C(image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1, get_current_rotation());
+
+ uint8 riding_peep_sprites[64];
+ memset(riding_peep_sprites, 0xFF, sizeof(riding_peep_sprites));
+ for (int i = 0; i < vehicle->num_peeps; i++) {
+ uint8 cl = (i & 3) * 16;
+ cl += (i & 0xFC);
+ cl += vehicle->var_C5 / 4;
+ cl += (imageDirection / 8) * 16;
+ cl &= 0x3F;
+ riding_peep_sprites[cl] = vehicle->peep_tshirt_colours[i];
+ }
+
+ // Draw riding peep sprites in back to front order:
+ for (int j = 0; j <= 48; j++) {
+ int i = (j % 2) ? (48 - (j / 2)) : (j / 2);
+ if (riding_peep_sprites[i] != 0xFF) {
+ baseImage_id = vehicleEntry->base_image_id + 20 + i;
+ if (vehicle->restraints_position >= 64) {
+ baseImage_id += 64;
+ baseImage_id += vehicle->restraints_position / 64;
+ }
+ image_id = baseImage_id | (riding_peep_sprites[i] << 19) | 0x20000000;
+ sub_98199C(image_id, 0, 0, 16, 16, 41, z, -5, -5, z + 1, get_current_rotation());
+ }
+ };
+
+ assert(vehicleEntry->pad_5E == 1);
+ // 0x5E is treated as another car_visual paint setup jump table like in viewport_vehicle_paint_setup
+ // in the original code right here but appears to only ever be 1 which goes to a nullsub so it was taken out.
+}
diff --git a/src/ride/thrill/swinging_inverter_ship.c b/src/ride/thrill/swinging_inverter_ship.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/thrill/swinging_inverter_ship.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/thrill/top_spin.c b/src/ride/thrill/top_spin.c
new file mode 100644
index 0000000000..158bfba8d0
--- /dev/null
+++ b/src/ride/thrill/top_spin.c
@@ -0,0 +1,855 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
+
+#include "../../addresses.h"
+#include "../../paint/supports.h"
+#include "../../interface/viewport.h"
+#include "../../paint/paint.h"
+#include "../../localisation/localisation.h"
+#include "../../sprites.h"
+#include "../../world/map.h"
+#include "../../world/sprite.h"
+#include "../ride_data.h"
+#include "../track_data.h"
+#include "../track_paint.h"
+
+/**
+ *
+ * rct2: 0x0076687C
+ */
+static 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);
+ wooden_a_supports_paint_setup(direction & 1, 0, height, image_id, NULL);
+
+ image_id = 22137 | RCT2_GLOBAL(0x00F44198, uint32);
+ sub_98197C(image_id, 0, 0, 32, 32, 1, height, 0, 0, height, get_current_rotation());
+
+ 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(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) < height) {
+ RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = height;
+ RCT2_GLOBAL(0x141E9DA, uint8) = 32;
+ }
+}
+
+/* rct2: 0x007667AE */
+static rct_xy16 loc_7667AE[] = {
+ { .x = 0, .y = -1 },
+ { .x = 1, .y = 0 },
+ { .x = 0, .y = 1},
+ { .x = -1, .y = 0 },
+};
+
+/* rct2: 0x007667AC */
+static rct_xy16 loc_7667AC[] = {
+ { .x = -1, .y = 0 },
+ { .x = 0, .y = -1 },
+ { .x = 1, .y = 0 },
+ { .x = 0, .y = 1 },
+};
+
+/**
+ *
+ * rct2: 0x0142811C
+ * Can be calculated as Rounddown(34*sin(x)+0.5)
+ * where x is in 7.5 deg segments.
+ */
+static sint8 TopSpinSeatPositionOffset[] = {
+ 0, 4, 9, 13, 17, 21, 24, 27, 29, 31, 33, 34, 34, 34, 33, 31,
+ 29, 27, 24, 21, 17, 13, 9, 4, 0, -3, -8, -12, -16, -20, -23, -26,
+ -28, -30, -32, -33, -33, -33, -32, -30, -28, -26, -23, -20, -16, -12, -8, -3,
+ 0
+};
+
+/**
+ *
+ * rct2: 0x0076750D
+ */
+static void top_spin_paint_vehicle(sint8 al, sint8 cl, uint8 rideIndex, uint8 direction, int height, rct_map_element* mapElement) {
+ uint16 boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ;
+ // 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_entry* 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->vehicle_sprite_type;
+ seatRotation = vehicle->bank_rotation;
+ }
+
+ boundBoxOffsetX = al + 16;
+ boundBoxOffsetY = cl + 16;
+ boundBoxOffsetZ = height;
+
+ //di
+ uint8 lengthX = 24;
+ //si
+ uint8 lengthY = 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(image_id, al, cl, lengthX, lengthY, 90, height, boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ, get_current_rotation());
+
+ 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(image_id, al, cl, lengthX, lengthY, 90, height, boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ, get_current_rotation());
+
+ uint32 seatImageId;
+
+ if (vehicle != NULL && vehicle->restraints_position >= 64) {
+ // Open Restraints
+ image_id = (vehicle->restraints_position - 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];
+
+ assert(armRotation < sizeof(TopSpinSeatPositionOffset));
+ switch (direction) {
+ case 0:
+ seatCoords.x -= TopSpinSeatPositionOffset[armRotation];
+ break;
+ case 1:
+ seatCoords.y += TopSpinSeatPositionOffset[armRotation];
+ break;
+ case 2:
+ seatCoords.x += TopSpinSeatPositionOffset[armRotation];
+ break;
+ case 3:
+ seatCoords.y -= TopSpinSeatPositionOffset[armRotation];
+ break;
+ }
+
+ RCT2_GLOBAL(0x014280B8, sint8) = (sint8)seatCoords.x;
+ RCT2_GLOBAL(0x014280B9, sint8) = (sint8)seatCoords.y;
+ RCT2_GLOBAL(0x014280BA, sint16) = seatCoords.z;
+
+ sub_98199C(image_id, (sint8) seatCoords.x, (sint8) seatCoords.y, lengthX, lengthY, 90, seatCoords.z, boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ, get_current_rotation());
+
+ 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(image_id, (sint8) seatCoords.x, (sint8) seatCoords.y, lengthX, lengthY, 90, seatCoords.z, boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ, get_current_rotation());
+
+ 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(image_id, (sint8) seatCoords.x, (sint8) seatCoords.y, lengthX, lengthY, 90, seatCoords.z, boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ, get_current_rotation());
+ }
+
+ 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(image_id, (sint8) seatCoords.x, (sint8) seatCoords.y, lengthX, lengthY, 90, seatCoords.z, boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ, get_current_rotation());
+ }
+
+ 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(image_id, (sint8) seatCoords.x, (sint8) seatCoords.y, lengthX, lengthY, 90, seatCoords.z, boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ, get_current_rotation());
+ }
+ }
+
+ 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(image_id, al, cl, lengthX, lengthY, 90, height, boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ, get_current_rotation());
+
+ 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(image_id, al, cl, lengthX, lengthY, 90, height, boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ, get_current_rotation());
+
+ RCT2_GLOBAL(0x009DE578, rct_map_element*) = curMapElement;
+ RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = VIEWPORT_INTERACTION_ITEM_RIDE;
+}
+
+/**
+ *
+ * rct2: 0x0076693F
+ */
+static 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);
+ wooden_a_supports_paint_setup(direction & 1, 0, height, image_id, NULL);
+
+ image_id = 22137 | RCT2_GLOBAL(0x00F44198, uint32);
+ sub_98197C(image_id, 0, 0, 32, 32, 1, height, 0, 0, height, get_current_rotation());
+
+ sint16 x = RCT2_GLOBAL(0x009DE56A, sint16), y = RCT2_GLOBAL(0x009DE56E, sint16);
+ uint16 entranceLoc =
+ ((x / 32) + loc_7667AE[get_current_rotation()].x) |
+ (((y / 32) + loc_7667AE[get_current_rotation()].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);
+ sub_98199C(image_id, 0, 0, 32, 1, 7, height, 0, 2, height + 2, get_current_rotation());
+ }
+
+ entranceLoc =
+ ((x / 32) + loc_7667AC[get_current_rotation()].x) |
+ (((y / 32) + loc_7667AC[get_current_rotation()].y) << 8);
+
+ if (ride->entrances[entranceId] != entranceLoc && ride->exits[entranceId] != entranceLoc) {
+ image_id = 22138 | RCT2_GLOBAL(0x00F441A0, uint32);
+ sub_98199C(image_id, 0, 0, 1, 32, 7, height, 0, 2, height + 2, get_current_rotation());
+ }
+
+ 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(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) < height) {
+ RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = height;
+ RCT2_GLOBAL(0x141E9DA, uint8) = 32;
+ }
+}
+
+/**
+ *
+ * rct2: 0x00767033
+ */
+static 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);
+ wooden_a_supports_paint_setup(direction & 1, 0, height, image_id, NULL);
+
+ image_id = 22137 | RCT2_GLOBAL(0x00F44198, uint32);
+ sub_98197C(image_id, 0, 0, 32, 32, 1, height, 0, 0, height, get_current_rotation());
+
+ sint16 x = RCT2_GLOBAL(0x009DE56A, sint16), y = RCT2_GLOBAL(0x009DE56E, sint16);
+ uint16 entranceLoc =
+ ((x / 32) + loc_7667AC[get_current_rotation()].x) |
+ (((y / 32) + loc_7667AC[get_current_rotation()].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);
+ sub_98199C(image_id, 0, 0, 1, 32, 7, height, 2, 0, height + 2, get_current_rotation());
+ }
+
+ 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(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) < height) {
+ RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = height;
+ RCT2_GLOBAL(0x141E9DA, uint8) = 32;
+ }
+}
+
+/**
+ *
+ * rct2: 0x0076718D
+ */
+static 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);
+ wooden_a_supports_paint_setup(direction & 1, 0, height, image_id, NULL);
+
+ image_id = 22137 | RCT2_GLOBAL(0x00F44198, uint32);
+ sub_98197C(image_id, 0, 0, 32, 32, 1, height, 0, 0, height, get_current_rotation());
+
+ sint16 x = RCT2_GLOBAL(0x009DE56A, sint16), y = RCT2_GLOBAL(0x009DE56E, sint16);
+ uint16 entranceLoc =
+ ((x / 32) + loc_7667AE[get_current_rotation()].x) |
+ (((y / 32) + loc_7667AE[get_current_rotation()].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);
+ sub_98199C(image_id, 0, 0, 32, 1, 7, height, 0, 2, height + 2, get_current_rotation());
+ }
+
+ 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(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) < height) {
+ RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = height;
+ RCT2_GLOBAL(0x141E9DA, uint8) = 32;
+ }
+}
+
+/**
+ *
+ * rct2: 0x00766B4C
+ */
+static 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);
+ wooden_a_supports_paint_setup(direction & 1, 0, height, image_id, NULL);
+
+ image_id = 22136 | RCT2_GLOBAL(0x00F44198, uint32);
+ sub_98197C(image_id, 0, 0, 32, 32, 1, height, 0, 0, height, get_current_rotation());
+
+ sint16 x = RCT2_GLOBAL(0x009DE56A, sint16), y = RCT2_GLOBAL(0x009DE56E, sint16);
+ uint16 entranceLoc =
+ ((x / 32) + loc_7667AC[get_current_rotation()].x) |
+ (((y / 32) + loc_7667AC[get_current_rotation()].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);
+ sub_98199C(image_id, 0, 0, 1, 32, 7, height, 2, 0, height + 2, get_current_rotation());
+ }
+
+ entranceLoc =
+ ((x / 32) + loc_7667AC[(get_current_rotation() + 3) & 3].x) |
+ (((y / 32) + loc_7667AC[(get_current_rotation() + 3) & 3].y) << 8);
+
+ if (ride->entrances[entranceId] != entranceLoc && ride->exits[entranceId] != entranceLoc) {
+
+ image_id = 22139 | RCT2_GLOBAL(0x00F441A0, uint32);
+ sub_98197C(image_id, 0, 0, 32, 1, 7, height, 0, 30, height + 2, get_current_rotation());
+ }
+
+ 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(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) < height) {
+ RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = height;
+ RCT2_GLOBAL(0x141E9DA, uint8) = 32;
+ }
+}
+
+/**
+ *
+ * rct2: 0x007672E7
+ */
+static 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);
+ wooden_a_supports_paint_setup(direction & 1, 0, height, image_id, NULL);
+
+ image_id = 22136 | RCT2_GLOBAL(0x00F44198, uint32);
+ sub_98197C(image_id, 0, 0, 32, 32, 1, height, 0, 0, height, get_current_rotation());
+
+ 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[(get_current_rotation() + 3) & 3].x) |
+ (((y / 32) + loc_7667AC[(get_current_rotation() + 3) & 3].y) << 8);
+
+ if (ride->entrances[entranceId] != entranceLoc && ride->exits[entranceId] != entranceLoc) {
+ image_id = 22139 | RCT2_GLOBAL(0x00F441A0, uint32);
+ sub_98197C(image_id, 0, 0, 32, 1, 7, height, 0, 30, height + 2, get_current_rotation());
+ }
+
+ 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(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) < height) {
+ RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = height;
+ RCT2_GLOBAL(0x141E9DA, uint8) = 32;
+ }
+}
+
+/**
+ *
+ * rct2: 0x00766D09
+ */
+static 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);
+ wooden_a_supports_paint_setup(direction & 1, 0, height, image_id, NULL);
+
+ image_id = 22135 | RCT2_GLOBAL(0x00F44198, uint32);
+ sub_98197C(image_id, 0, 0, 32, 32, 1, height, 0, 0, height, get_current_rotation());
+
+ sint16 x = RCT2_GLOBAL(0x009DE56A, sint16), y = RCT2_GLOBAL(0x009DE56E, sint16);
+ uint16 entranceLoc =
+ ((x / 32) + loc_7667AE[get_current_rotation()].x) |
+ (((y / 32) + loc_7667AE[get_current_rotation()].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);
+ sub_98199C(image_id, 0, 0, 32, 1, 7, height, 0, 2, height + 2, get_current_rotation());
+ }
+
+ entranceLoc =
+ ((x / 32) + loc_7667AE[(get_current_rotation() + 1) & 3].x) |
+ (((y / 32) + loc_7667AE[(get_current_rotation() + 1) & 3].y) << 8);
+
+ if (ride->entrances[entranceId] != entranceLoc && ride->exits[entranceId] != entranceLoc) {
+
+ image_id = 22140 | RCT2_GLOBAL(0x00F441A0, uint32);
+ sub_98197C(image_id, 0, 0, 1, 32, 7, height, 30, 2, height + 2, get_current_rotation());
+ }
+
+ 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(0x141E9D2, uint16) = 32;
+ RCT2_GLOBAL(0x141E9D4, uint16) = 0xFFFF;
+
+ height += 110;
+ if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) < height) {
+ RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = height;
+ RCT2_GLOBAL(0x141E9DA, uint8) = 32;
+ }
+}
+
+/**
+ *
+ * rct2: 0x00766EC6
+ */
+static 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);
+ wooden_a_supports_paint_setup(direction & 1, 0, height, image_id, NULL);
+
+ image_id = 22134 | RCT2_GLOBAL(0x00F44198, uint32);
+ sub_98197C(image_id, 0, 0, 32, 32, 1, height, 0, 0, height, get_current_rotation());
+
+ 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[(get_current_rotation() + 1) & 3].x) |
+ (((y / 32) + loc_7667AE[(get_current_rotation() + 1) & 3].y) << 8);
+
+ if (ride->entrances[entranceId] != entranceLoc && ride->exits[entranceId] != entranceLoc) {
+
+ image_id = 22140 | RCT2_GLOBAL(0x00F441A0, uint32);
+ sub_98197C(image_id, 0, 0, 1, 28, 7, height, 29, 0, height + 3, get_current_rotation());
+ }
+
+ entranceLoc =
+ ((x / 32) + loc_7667AC[(get_current_rotation() + 3) & 3].x) |
+ (((y / 32) + loc_7667AC[(get_current_rotation() + 3) & 3].y) << 8);
+
+ if (ride->entrances[entranceId] != entranceLoc && ride->exits[entranceId] != entranceLoc) {
+
+ image_id = 22139 | RCT2_GLOBAL(0x00F441A0, uint32);
+ sub_98197C(image_id, 0, 0, 28, 1, 7, height, 0, 29, height + 3, get_current_rotation());
+ }
+
+ 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(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) < height) {
+ RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = height;
+ RCT2_GLOBAL(0x141E9DA, uint8) = 32;
+ }
+}
+
+/**
+ *
+ * rct2: 0x007673FA
+ */
+static 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);
+ wooden_a_supports_paint_setup(direction & 1, 0, height, image_id, NULL);
+
+ image_id = 22135 | RCT2_GLOBAL(0x00F44198, uint32);
+ sub_98197C(image_id, 0, 0, 32, 32, 1, height, 0, 0, height, get_current_rotation());
+
+ 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[(get_current_rotation() + 1) & 3].x) |
+ (((y / 32) + loc_7667AE[(get_current_rotation() + 1) & 3].y) << 8);
+
+ if (ride->entrances[entranceId] != entranceLoc && ride->exits[entranceId] != entranceLoc) {
+
+ image_id = 22140 | RCT2_GLOBAL(0x00F441A0, uint32);
+ sub_98197C(image_id, 0, 0, 1, 32, 7, height, 30, 0, height + 2, get_current_rotation());
+ }
+ 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(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) < height) {
+ RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = height;
+ RCT2_GLOBAL(0x141E9DA, uint8) = 32;
+ }
+}
+
+/**
+ *
+ * rct2: 0x007667BC
+ */
+static 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
+*/
+static 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
+*/
+static 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
+*/
+static 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;
+}
+
+/* 0x0076659C */
+TRACK_PAINT_FUNCTION get_track_paint_function_topspin(int trackType, int direction)
+{
+ switch (trackType) {
+ case 123:
+ switch (direction) {
+ case 0: return top_spin_paint_setup_rot_0;
+ case 1: return top_spin_paint_setup_rot_1;
+ case 2: return top_spin_paint_setup_rot_2;
+ case 3: return top_spin_paint_setup_rot_3;
+ }
+ break;
+ }
+ return NULL;
+}
diff --git a/src/ride/thrill/twist.c b/src/ride/thrill/twist.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/thrill/twist.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/track_paint.c b/src/ride/track_paint.c
index 54b1045235..6d5421ae3b 100644
--- a/src/ride/track_paint.c
+++ b/src/ride/track_paint.c
@@ -17,8 +17,9 @@
#include "../addresses.h"
#include "../config.h"
#include "../drawing/drawing.h"
-#include "../drawing/supports.h"
+#include "../paint/supports.h"
#include "../interface/viewport.h"
+#include "../paint/paint.h"
#include "../interface/window.h"
#include "../localisation/localisation.h"
#include "../sprites.h"
@@ -30,1187 +31,110 @@
/**
*
- * rct2: 0x0076687C
+ * rct2: 0x006C4794
*/
-static 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);
- wooden_a_supports_paint_setup(direction & 1, 0, height, image_id, NULL);
+void track_paint(uint8 direction, int height, rct_map_element *mapElement)
+{
+ rct_drawpixelinfo *dpi = RCT2_GLOBAL(0x0140E9A8, rct_drawpixelinfo*);
+ rct_ride *ride;
+ int rideIndex, trackType, trackColourScheme, trackSequence;
- image_id = 22137 | RCT2_GLOBAL(0x00F44198, uint32);
- sub_98197C(image_id, 0, 0, 32, 32, 1, height, 0, 0, height, get_current_rotation());
-
- 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(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) < height) {
- RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = height;
- RCT2_GLOBAL(0x141E9DA, uint8) = 32;
- }
-}
-
-/* rct2: 0x007667AE */
-static rct_xy16 loc_7667AE[] = {
- { .x = 0, .y = -1 },
- { .x = 1, .y = 0 },
- { .x = 0, .y = 1},
- { .x = -1, .y = 0 },
-};
-
-/* rct2: 0x007667AC */
-static rct_xy16 loc_7667AC[] = {
- { .x = -1, .y = 0 },
- { .x = 0, .y = -1 },
- { .x = 1, .y = 0 },
- { .x = 0, .y = 1 },
-};
-
-/**
- *
- * rct2: 0x0142811C
- * Can be calculated as Rounddown(34*sin(x)+0.5)
- * where x is in 7.5 deg segments.
- */
-static sint8 TopSpinSeatPositionOffset[] = {
- 0, 4, 9, 13, 17, 21, 24, 27, 29, 31, 33, 34, 34, 34, 33, 31,
- 29, 27, 24, 21, 17, 13, 9, 4, 0, -3, -8, -12, -16, -20, -23, -26,
- -28, -30, -32, -33, -33, -33, -32, -30, -28, -26, -23, -20, -16, -12, -8, -3,
- 0
-};
-
-/**
- *
- * rct2: 0x0076750D
- */
-static void top_spin_paint_vehicle(sint8 al, sint8 cl, uint8 rideIndex, uint8 direction, int height, rct_map_element* mapElement) {
- uint16 boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ;
- // 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_entry* 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->vehicle_sprite_type;
- seatRotation = vehicle->bank_rotation;
+ rideIndex = mapElement->properties.track.ride_index;
+ ride = get_ride(rideIndex);
+ if (ride->type == RIDE_TYPE_NULL) {
+ log_error("Attempted to paint invalid ride: %d", rideIndex);
+ return;
}
- boundBoxOffsetX = al + 16;
- boundBoxOffsetY = cl + 16;
- boundBoxOffsetZ = height;
-
- //di
- uint8 lengthX = 24;
- //si
- uint8 lengthY = 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);
+ // HACK Set entrance style to plain if none to stop glitch until entrance track piece is implemented
+ bool isEntranceStyleNone = false;
+ if (ride->entrance_style == RIDE_ENTRANCE_STYLE_NONE) {
+ isEntranceStyleNone = true;
+ ride->entrance_style = RIDE_ENTRANCE_STYLE_PLAIN;
}
- image_id += (direction & 1) << 1;
- image_id += rideEntry->vehicles[0].base_image_id;
- // Left back bottom support
- image_id += 572;
- sub_98197C(image_id, al, cl, lengthX, lengthY, 90, height, boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ, get_current_rotation());
+ if (!(RCT2_GLOBAL(0x009DEA6F, uint8) & 1) || rideIndex == RCT2_GLOBAL(0x00F64DE8, uint8)) {
+ trackType = mapElement->properties.track.type;
+ trackSequence = mapElement->properties.track.sequence & 0x0F;
+ trackColourScheme = mapElement->properties.track.colour & 3;
- 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(image_id, al, cl, lengthX, lengthY, 90, height, boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ, get_current_rotation());
-
- uint32 seatImageId;
-
- if (vehicle != NULL && vehicle->restraints_position >= 64) {
- // Open Restraints
- image_id = (vehicle->restraints_position - 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];
-
- assert(armRotation < sizeof(TopSpinSeatPositionOffset));
- switch (direction) {
- case 0:
- seatCoords.x -= TopSpinSeatPositionOffset[armRotation];
- break;
- case 1:
- seatCoords.y += TopSpinSeatPositionOffset[armRotation];
- break;
- case 2:
- seatCoords.x += TopSpinSeatPositionOffset[armRotation];
- break;
- case 3:
- seatCoords.y -= TopSpinSeatPositionOffset[armRotation];
- break;
- }
-
- RCT2_GLOBAL(0x014280B8, sint8) = (sint8)seatCoords.x;
- RCT2_GLOBAL(0x014280B9, sint8) = (sint8)seatCoords.y;
- RCT2_GLOBAL(0x014280BA, sint16) = seatCoords.z;
-
- sub_98199C(image_id, (sint8) seatCoords.x, (sint8) seatCoords.y, lengthX, lengthY, 90, seatCoords.z, boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ, get_current_rotation());
-
- 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(image_id, (sint8) seatCoords.x, (sint8) seatCoords.y, lengthX, lengthY, 90, seatCoords.z, boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ, get_current_rotation());
-
- 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(image_id, (sint8) seatCoords.x, (sint8) seatCoords.y, lengthX, lengthY, 90, seatCoords.z, boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ, get_current_rotation());
+ if ((gCurrentViewportFlags & VIEWPORT_FLAG_TRACK_HEIGHTS) && dpi->zoom_level == 0) {
+ RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = 0;
+ if (RCT2_ADDRESS(0x00999694, uint32)[trackType] & (1 << trackSequence)) {
+ uint16 ax = RideData5[ride->type].z_offset;
+ uint32 ebx = 0x20381689 + (height + 8) / 16;
+ ebx += RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_HEIGHT_MARKERS, uint16);
+ ebx -= RCT2_GLOBAL(0x01359208, uint16);
+ sub_98197C(ebx, 16, 16, 1, 1, 0, height + ax + 3, 1000, 1000, 2047, get_current_rotation());
+ }
}
- 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(image_id, (sint8) seatCoords.x, (sint8) seatCoords.y, lengthX, lengthY, 90, seatCoords.z, boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ, get_current_rotation());
+ RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = 3;
+ RCT2_GLOBAL(0x00F44198, uint32) = (ride->track_colour_main[trackColourScheme] << 19) | (ride->track_colour_additional[trackColourScheme] << 24) | 0xA0000000;
+ RCT2_GLOBAL(0x00F441A0, uint32) = 0x20000000;
+ RCT2_GLOBAL(0x00F441A4, uint32) = 0x20C00000;
+ RCT2_GLOBAL(0x00F4419C, uint32) = (ride->track_colour_supports[trackColourScheme] << 19) | 0x20000000;
+ if (mapElement->type & 0x40) {
+ RCT2_GLOBAL(0x00F44198, uint32) = 0x21600000;
+ RCT2_GLOBAL(0x00F4419C, uint32) = 0x21600000;
+ RCT2_GLOBAL(0x00F441A0, uint32) = 0x21600000;
+ RCT2_GLOBAL(0x00F441A4, uint32) = 0x21600000;
+ }
+ if (mapElement->flags & MAP_ELEMENT_FLAG_GHOST) {
+ uint32 ghost_id = RCT2_ADDRESS(0x00993CC4, uint32)[gConfigGeneral.construction_marker_colour];
+ RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = 0;
+ RCT2_GLOBAL(0x00F44198, uint32) = ghost_id;
+ RCT2_GLOBAL(0x00F4419C, uint32) = ghost_id;
+ RCT2_GLOBAL(0x00F441A0, uint32) = ghost_id;
+ RCT2_GLOBAL(0x00F441A4, uint32) = ghost_id;
}
- 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;
+ int rideType = ride->type;
+ if (rideType == RIDE_TYPE_JUNIOR_ROLLER_COASTER) {
+ switch (trackType) {
+ case TRACK_ELEM_60_DEG_UP:
+ case TRACK_ELEM_25_DEG_UP_TO_60_DEG_UP:
+ case TRACK_ELEM_60_DEG_UP_TO_25_DEG_UP:
+ case TRACK_ELEM_60_DEG_DOWN:
+ case TRACK_ELEM_25_DEG_DOWN_TO_60_DEG_DOWN:
+ case TRACK_ELEM_60_DEG_DOWN_TO_25_DEG_DOWN:
+ rideType = RIDE_TYPE_WATER_COASTER;
+ break;
- sub_98199C(image_id, (sint8) seatCoords.x, (sint8) seatCoords.y, lengthX, lengthY, 90, seatCoords.z, boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ, get_current_rotation());
+ case TRACK_ELEM_FLAT_TO_60_DEG_UP:
+ case TRACK_ELEM_60_DEG_UP_TO_FLAT:
+ case TRACK_ELEM_FLAT_TO_60_DEG_DOWN:
+ case TRACK_ELEM_60_DEG_DOWN_TO_FLAT:
+ return;
+ }
+ }
+
+ TRACK_PAINT_FUNCTION **trackTypeList = (TRACK_PAINT_FUNCTION**)RideTypeTrackPaintFunctionsOld[rideType];
+ if (trackTypeList == NULL) {
+ TRACK_PAINT_FUNCTION_GETTER paintFunctionGetter = RideTypeTrackPaintFunctions[rideType];
+ TRACK_PAINT_FUNCTION paintFunction = paintFunctionGetter(trackType, direction);
+ if (paintFunction != NULL) {
+ paintFunction(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,
+ rideType,
+ (int)trackDirectionList,
+ direction,
+ height,
+ (int)mapElement,
+ rideIndex * sizeof(rct_ride),
+ trackSequence
+ );
}
}
- 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(image_id, al, cl, lengthX, lengthY, 90, height, boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ, get_current_rotation());
-
- 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(image_id, al, cl, lengthX, lengthY, 90, height, boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ, get_current_rotation());
-
- RCT2_GLOBAL(0x009DE578, rct_map_element*) = curMapElement;
- RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8) = VIEWPORT_INTERACTION_ITEM_RIDE;
-}
-
-/**
- *
- * rct2: 0x0076693F
- */
-static 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);
- wooden_a_supports_paint_setup(direction & 1, 0, height, image_id, NULL);
-
- image_id = 22137 | RCT2_GLOBAL(0x00F44198, uint32);
- sub_98197C(image_id, 0, 0, 32, 32, 1, height, 0, 0, height, get_current_rotation());
-
- sint16 x = RCT2_GLOBAL(0x009DE56A, sint16), y = RCT2_GLOBAL(0x009DE56E, sint16);
- uint16 entranceLoc =
- ((x / 32) + loc_7667AE[get_current_rotation()].x) |
- (((y / 32) + loc_7667AE[get_current_rotation()].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);
- sub_98199C(image_id, 0, 0, 32, 1, 7, height, 0, 2, height + 2, get_current_rotation());
- }
-
- entranceLoc =
- ((x / 32) + loc_7667AC[get_current_rotation()].x) |
- (((y / 32) + loc_7667AC[get_current_rotation()].y) << 8);
-
- if (ride->entrances[entranceId] != entranceLoc && ride->exits[entranceId] != entranceLoc) {
- image_id = 22138 | RCT2_GLOBAL(0x00F441A0, uint32);
- sub_98199C(image_id, 0, 0, 1, 32, 7, height, 0, 2, height + 2, get_current_rotation());
- }
-
- 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(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) < height) {
- RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = height;
- RCT2_GLOBAL(0x141E9DA, uint8) = 32;
+ if (isEntranceStyleNone) {
+ ride->entrance_style = RIDE_ENTRANCE_STYLE_NONE;
}
}
-
-/**
- *
- * rct2: 0x00767033
- */
-static 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);
- wooden_a_supports_paint_setup(direction & 1, 0, height, image_id, NULL);
-
- image_id = 22137 | RCT2_GLOBAL(0x00F44198, uint32);
- sub_98197C(image_id, 0, 0, 32, 32, 1, height, 0, 0, height, get_current_rotation());
-
- sint16 x = RCT2_GLOBAL(0x009DE56A, sint16), y = RCT2_GLOBAL(0x009DE56E, sint16);
- uint16 entranceLoc =
- ((x / 32) + loc_7667AC[get_current_rotation()].x) |
- (((y / 32) + loc_7667AC[get_current_rotation()].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);
- sub_98199C(image_id, 0, 0, 1, 32, 7, height, 2, 0, height + 2, get_current_rotation());
- }
-
- 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(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) < height) {
- RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = height;
- RCT2_GLOBAL(0x141E9DA, uint8) = 32;
- }
-}
-
-/**
- *
- * rct2: 0x0076718D
- */
-static 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);
- wooden_a_supports_paint_setup(direction & 1, 0, height, image_id, NULL);
-
- image_id = 22137 | RCT2_GLOBAL(0x00F44198, uint32);
- sub_98197C(image_id, 0, 0, 32, 32, 1, height, 0, 0, height, get_current_rotation());
-
- sint16 x = RCT2_GLOBAL(0x009DE56A, sint16), y = RCT2_GLOBAL(0x009DE56E, sint16);
- uint16 entranceLoc =
- ((x / 32) + loc_7667AE[get_current_rotation()].x) |
- (((y / 32) + loc_7667AE[get_current_rotation()].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);
- sub_98199C(image_id, 0, 0, 32, 1, 7, height, 0, 2, height + 2, get_current_rotation());
- }
-
- 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(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) < height) {
- RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = height;
- RCT2_GLOBAL(0x141E9DA, uint8) = 32;
- }
-}
-
-/**
- *
- * rct2: 0x00766B4C
- */
-static 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);
- wooden_a_supports_paint_setup(direction & 1, 0, height, image_id, NULL);
-
- image_id = 22136 | RCT2_GLOBAL(0x00F44198, uint32);
- sub_98197C(image_id, 0, 0, 32, 32, 1, height, 0, 0, height, get_current_rotation());
-
- sint16 x = RCT2_GLOBAL(0x009DE56A, sint16), y = RCT2_GLOBAL(0x009DE56E, sint16);
- uint16 entranceLoc =
- ((x / 32) + loc_7667AC[get_current_rotation()].x) |
- (((y / 32) + loc_7667AC[get_current_rotation()].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);
- sub_98199C(image_id, 0, 0, 1, 32, 7, height, 2, 0, height + 2, get_current_rotation());
- }
-
- entranceLoc =
- ((x / 32) + loc_7667AC[(get_current_rotation() + 3) & 3].x) |
- (((y / 32) + loc_7667AC[(get_current_rotation() + 3) & 3].y) << 8);
-
- if (ride->entrances[entranceId] != entranceLoc && ride->exits[entranceId] != entranceLoc) {
-
- image_id = 22139 | RCT2_GLOBAL(0x00F441A0, uint32);
- sub_98197C(image_id, 0, 0, 32, 1, 7, height, 0, 30, height + 2, get_current_rotation());
- }
-
- 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(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) < height) {
- RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = height;
- RCT2_GLOBAL(0x141E9DA, uint8) = 32;
- }
-}
-
-/**
- *
- * rct2: 0x007672E7
- */
-static 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);
- wooden_a_supports_paint_setup(direction & 1, 0, height, image_id, NULL);
-
- image_id = 22136 | RCT2_GLOBAL(0x00F44198, uint32);
- sub_98197C(image_id, 0, 0, 32, 32, 1, height, 0, 0, height, get_current_rotation());
-
- 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[(get_current_rotation() + 3) & 3].x) |
- (((y / 32) + loc_7667AC[(get_current_rotation() + 3) & 3].y) << 8);
-
- if (ride->entrances[entranceId] != entranceLoc && ride->exits[entranceId] != entranceLoc) {
- image_id = 22139 | RCT2_GLOBAL(0x00F441A0, uint32);
- sub_98197C(image_id, 0, 0, 32, 1, 7, height, 0, 30, height + 2, get_current_rotation());
- }
-
- 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(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) < height) {
- RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = height;
- RCT2_GLOBAL(0x141E9DA, uint8) = 32;
- }
-}
-
-/**
- *
- * rct2: 0x00766D09
- */
-static 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);
- wooden_a_supports_paint_setup(direction & 1, 0, height, image_id, NULL);
-
- image_id = 22135 | RCT2_GLOBAL(0x00F44198, uint32);
- sub_98197C(image_id, 0, 0, 32, 32, 1, height, 0, 0, height, get_current_rotation());
-
- sint16 x = RCT2_GLOBAL(0x009DE56A, sint16), y = RCT2_GLOBAL(0x009DE56E, sint16);
- uint16 entranceLoc =
- ((x / 32) + loc_7667AE[get_current_rotation()].x) |
- (((y / 32) + loc_7667AE[get_current_rotation()].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);
- sub_98199C(image_id, 0, 0, 32, 1, 7, height, 0, 2, height + 2, get_current_rotation());
- }
-
- entranceLoc =
- ((x / 32) + loc_7667AE[(get_current_rotation() + 1) & 3].x) |
- (((y / 32) + loc_7667AE[(get_current_rotation() + 1) & 3].y) << 8);
-
- if (ride->entrances[entranceId] != entranceLoc && ride->exits[entranceId] != entranceLoc) {
-
- image_id = 22140 | RCT2_GLOBAL(0x00F441A0, uint32);
- sub_98197C(image_id, 0, 0, 1, 32, 7, height, 30, 2, height + 2, get_current_rotation());
- }
-
- 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(0x141E9D2, uint16) = 32;
- RCT2_GLOBAL(0x141E9D4, uint16) = 0xFFFF;
-
- height += 110;
- if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) < height) {
- RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = height;
- RCT2_GLOBAL(0x141E9DA, uint8) = 32;
- }
-}
-
-/**
- *
- * rct2: 0x00766EC6
- */
-static 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);
- wooden_a_supports_paint_setup(direction & 1, 0, height, image_id, NULL);
-
- image_id = 22134 | RCT2_GLOBAL(0x00F44198, uint32);
- sub_98197C(image_id, 0, 0, 32, 32, 1, height, 0, 0, height, get_current_rotation());
-
- 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[(get_current_rotation() + 1) & 3].x) |
- (((y / 32) + loc_7667AE[(get_current_rotation() + 1) & 3].y) << 8);
-
- if (ride->entrances[entranceId] != entranceLoc && ride->exits[entranceId] != entranceLoc) {
-
- image_id = 22140 | RCT2_GLOBAL(0x00F441A0, uint32);
- sub_98197C(image_id, 0, 0, 1, 28, 7, height, 29, 0, height + 3, get_current_rotation());
- }
-
- entranceLoc =
- ((x / 32) + loc_7667AC[(get_current_rotation() + 3) & 3].x) |
- (((y / 32) + loc_7667AC[(get_current_rotation() + 3) & 3].y) << 8);
-
- if (ride->entrances[entranceId] != entranceLoc && ride->exits[entranceId] != entranceLoc) {
-
- image_id = 22139 | RCT2_GLOBAL(0x00F441A0, uint32);
- sub_98197C(image_id, 0, 0, 28, 1, 7, height, 0, 29, height + 3, get_current_rotation());
- }
-
- 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(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) < height) {
- RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = height;
- RCT2_GLOBAL(0x141E9DA, uint8) = 32;
- }
-}
-
-/**
- *
- * rct2: 0x007673FA
- */
-static 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);
- wooden_a_supports_paint_setup(direction & 1, 0, height, image_id, NULL);
-
- image_id = 22135 | RCT2_GLOBAL(0x00F44198, uint32);
- sub_98197C(image_id, 0, 0, 32, 32, 1, height, 0, 0, height, get_current_rotation());
-
- 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[(get_current_rotation() + 1) & 3].x) |
- (((y / 32) + loc_7667AE[(get_current_rotation() + 1) & 3].y) << 8);
-
- if (ride->entrances[entranceId] != entranceLoc && ride->exits[entranceId] != entranceLoc) {
-
- image_id = 22140 | RCT2_GLOBAL(0x00F441A0, uint32);
- sub_98197C(image_id, 0, 0, 1, 32, 7, height, 30, 0, height + 2, get_current_rotation());
- }
- 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(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) < height) {
- RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = height;
- RCT2_GLOBAL(0x141E9DA, uint8) = 32;
- }
-}
-
-/**
- *
- * rct2: 0x007667BC
- */
-static 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
-*/
-static 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
-*/
-static 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
-*/
-static 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;
-}
-
-/* 0x0076659C */
-TRACK_PAINT_FUNCTION get_track_paint_function_topspin(int trackType, int direction)
-{
- switch (trackType) {
- case 123:
- switch (direction) {
- case 0: return top_spin_paint_setup_rot_0;
- case 1: return top_spin_paint_setup_rot_1;
- case 2: return top_spin_paint_setup_rot_2;
- case 3: return top_spin_paint_setup_rot_3;
- }
- break;
- }
- return NULL;
-}
-
-enum {
- SPR_MAZE_BASE_HEDGE = 21938,
- SPR_MAZE_BASE_BRICK = 21951,
- SPR_MAZE_BASE_ICE = 21964,
- SPR_MAZE_BASE_WOOD = 21977,
-};
-
-enum {
- SPR_MAZE_OFFSET_WALL_CENTER = 0,
- SPR_MAZE_OFFSET_WALL_INNER_NE_SW,
- SPR_MAZE_OFFSET_WALL_INNER_NW_SE,
- SPR_MAZE_OFFSET_WALL_TOP_LEFT,
- SPR_MAZE_OFFSET_WALL_TOP_RIGHT,
- SPR_MAZE_OFFSET_WALL_BOTTOM_RIGHT,
- SPR_MAZE_OFFSET_WALL_BOTTOM_LEFT,
- SPR_MAZE_OFFSET_COLUMN_CENTER,
- SPR_MAZE_OFFSET_COLUMN_TOP_RIGHT,
- SPR_MAZE_OFFSET_COLUMN_TOP_LEFT,
- SPR_MAZE_OFFSET_COLUMN_BOTTOM_LEFT,
- SPR_MAZE_OFFSET_COLUMN_BOTTOM_RIGHT,
- SPR_MAZE_OFFSET_COLUMN_CORNER,
-};
-
-/**
- * rct: 0x004ACF4A
- */
-static void maze_paint_setup(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element *mapElement) {
- uint16 maze_entry = mapElement->properties.track.maze_entry;
- maze_entry = rol16(maze_entry, direction * 4);
-
- // draw ground
- int image_id = 2485 | RCT2_GLOBAL(0x00F441A0, uint32);
- sub_98196C(image_id, 0, 0, 32, 32, 0, height, get_current_rotation());
-
- wooden_a_supports_paint_setup(direction & 1, 0, height, RCT2_GLOBAL(0x00F441A4, uint32), NULL);
-
- RCT2_GLOBAL(0x0141E9B4, uint16) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9B8, uint16) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9BC, uint16) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9C0, uint16) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9C8, uint16) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9CC, uint16) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9D0, uint16) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9D4, uint16) = 0xFFFF;
-
- int base_image_id;
- switch (get_ride(rideIndex)->track_colour_supports[0]) {
- case 0: base_image_id = SPR_MAZE_BASE_BRICK; break;
- case 1: base_image_id = SPR_MAZE_BASE_HEDGE; break;
- case 2: base_image_id = SPR_MAZE_BASE_ICE; break;
- case 3: base_image_id = SPR_MAZE_BASE_WOOD; break;
- }
-
- base_image_id |= RCT2_GLOBAL(0x00F441A0, uint32);
-
-
- image_id = base_image_id + SPR_MAZE_OFFSET_WALL_CENTER;
- if (maze_entry & (1 << 3))
- sub_98197C(image_id, 2, 2, 10, 10, 9, height, 3, 3, height + 2, get_current_rotation());
-
- if (maze_entry & (1 << 7))
- sub_98197C(image_id, 2, 18, 10, 10, 9, height, 3, 19, height + 2, get_current_rotation());
-
- if (maze_entry & (1 << 11))
- sub_98197C(image_id, 18, 18, 10, 10, 9, height, 19, 19, height + 2, get_current_rotation());
-
- if (maze_entry & (1 << 15))
- sub_98197C(image_id, 18, 2, 10, 10, 9, height, 19, 3, height + 2, get_current_rotation());
-
-
- image_id = base_image_id + SPR_MAZE_OFFSET_WALL_TOP_LEFT;
- if (maze_entry & (1 << 0))
- sub_98197C(image_id, 2, 0, 10, 1, 9, height, 3, 1, height + 2, get_current_rotation());
-
- if (maze_entry & (1 << 13))
- sub_98197C(image_id, 18, 0, 10, 1, 9, height, 19, 1, height + 2, get_current_rotation());
-
-
- image_id = base_image_id + SPR_MAZE_OFFSET_WALL_BOTTOM_RIGHT;
- if (maze_entry & (1 << 5))
- sub_98197C(image_id, 2, 30, 10, 1, 9, height, 3, 30, height + 2, get_current_rotation());
-
- if (maze_entry & (1 << 8))
- sub_98197C(image_id, 18, 30, 10, 1, 9, height, 19, 30, height + 2, get_current_rotation());
-
-
- image_id = base_image_id + SPR_MAZE_OFFSET_WALL_TOP_RIGHT;
- if (maze_entry & (1 << 1))
- sub_98197C(image_id, 0, 2, 1, 10, 9, height, 1, 3, height + 2, get_current_rotation());
-
- if (maze_entry & (1 << 4))
- sub_98197C(image_id, 0, 18, 1, 10, 9, height, 1, 19, height + 2, get_current_rotation());
-
-
- image_id = base_image_id + SPR_MAZE_OFFSET_WALL_BOTTOM_LEFT;
- if (maze_entry & (1 << 12))
- sub_98197C(image_id, 30, 2, 1, 10, 9, height, 30, 3, height + 2, get_current_rotation());
-
- if (maze_entry & (1 << 9))
- sub_98197C(image_id, 30, 18, 1, 10, 9, height, 30, 19, height + 2, get_current_rotation());
-
-
- image_id = base_image_id + SPR_MAZE_OFFSET_WALL_INNER_NE_SW;
- if (maze_entry & (1 << 2))
- sub_98197C(image_id, 2, 14, 10, 4, 9, height, 3, 14, height + 2, get_current_rotation());
-
- if (maze_entry & (1 << 10))
- sub_98197C(image_id, 18, 14, 10, 4, 9, height, 19, 14, height + 2, get_current_rotation());
-
-
- image_id = base_image_id + SPR_MAZE_OFFSET_WALL_INNER_NW_SE;
- if (maze_entry & (1 << 14))
- sub_98197C(image_id, 14, 2, 4, 10, 9, height, 14, 3, height + 2, get_current_rotation());
-
- if (maze_entry & (1 << 6))
- sub_98197C(image_id, 14, 18, 4, 10, 9, height, 14, 19, height + 2, get_current_rotation());
-
-
- image_id = base_image_id + SPR_MAZE_OFFSET_COLUMN_CORNER;
- if (maze_entry & (1 << 0 | 1 << 1))
- sub_98197C(image_id, 0, 0, 1, 1, 9, height, 1, 1, height + 2, get_current_rotation());
-
- if (maze_entry & (1 << 4 | 1 << 5))
- sub_98197C(image_id, 0, 30, 1, 1, 9, height, 1, 30, height + 2, get_current_rotation());
-
- if (maze_entry & (1 << 8 | 1 << 9))
- sub_98197C(image_id, 30, 30, 1, 1, 9, height, 30, 30, height + 2, get_current_rotation());
-
- if (maze_entry & (1 << 12 | 1 << 13))
- sub_98197C(image_id, 30, 0, 1, 1, 9, height, 30, 1, height + 2, get_current_rotation());
-
-
- if (maze_entry & (1 << 0 | 1 << 13 | 1 << 14))
- sub_98197C(base_image_id + SPR_MAZE_OFFSET_COLUMN_TOP_LEFT, 14, 0, 2, 1, 9, height, 15, 1, height + 2, get_current_rotation());
-
-
- if (maze_entry & (1 << 5 | 1 << 6 | 1 << 8))
- sub_98197C(base_image_id + SPR_MAZE_OFFSET_COLUMN_BOTTOM_RIGHT, 14, 30, 2, 1, 9, height, 15, 30, height + 2, get_current_rotation());
-
-
- if (maze_entry & (1 << 1 | 1 << 2 | 1 << 4))
- sub_98197C(base_image_id + SPR_MAZE_OFFSET_COLUMN_TOP_RIGHT, 0, 14, 1, 2, 9, height, 1, 15, height + 2, get_current_rotation());
-
-
- if (maze_entry & (1 << 9 | 1 << 10 | 1 << 12))
- sub_98197C(base_image_id + SPR_MAZE_OFFSET_COLUMN_BOTTOM_LEFT, 30, 14, 1, 2, 9, height, 30, 15, height + 2, get_current_rotation());
-
-
- if (maze_entry & (1 << 2 | 1 << 6 | 1 << 10 | 1 << 14)) {
- sub_98197C(base_image_id + SPR_MAZE_OFFSET_COLUMN_CENTER, 14, 14, 2, 2, 8, height, 15, 15, height + 2, get_current_rotation());
-
- RCT2_GLOBAL(0x141E9C4, uint16) = height + 12;
- RCT2_GLOBAL(0x141E9C6, uint8) = 0x20;
- }
-
- height += 32;
- if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) < height) {
- RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = height;
- RCT2_GLOBAL(0x141E9DA, uint8) = 0x20;
- }
-}
-
-/**
- * rct2: 0x008A81E8
- */
-TRACK_PAINT_FUNCTION get_track_paint_function_maze(int trackType, int direction) {
- if (trackType != 101) {
- return NULL;
- }
-
- return maze_paint_setup;
-}
-
-/**
- *
- * rct2: 0x00761378
- * rct2: 0x007614DB
- * rct2: 0x0076163F
- * rct2: 0x007617A5
- */
-static void shop_paint_setup(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element* mapElement)
-{
- bool hasSupports = wooden_a_supports_paint_setup(direction & 1, 0, height, RCT2_GLOBAL(0x00F441A4, uint32), NULL);
-
- RCT2_GLOBAL(0x0141E9D0, sint16) = -1;
- RCT2_GLOBAL(0x0141E9C4, sint16) = -1;
- RCT2_GLOBAL(0x0141E9CC, sint16) = -1;
- RCT2_GLOBAL(0x0141E9B8, sint16) = -1;
- RCT2_GLOBAL(0x0141E9BC, sint16) = -1;
- RCT2_GLOBAL(0x0141E9B4, sint16) = -1;
- RCT2_GLOBAL(0x0141E9C0, sint16) = -1;
- RCT2_GLOBAL(0x0141E9C8, sint16) = -1;
- RCT2_GLOBAL(0x0141E9D4, sint16) = -1;
-
- rct_ride *ride = get_ride(rideIndex);
- rct_ride_entry *rideEntry = get_ride_entry(ride->subtype);
- rct_ride_entry_vehicle *firstVehicleEntry = &rideEntry->vehicles[0];
-
- uint32 imageId = RCT2_GLOBAL(0x00F44198, uint32);
- if (imageId & 0x80000000) {
- imageId &= 0x60FFFFFF;
- }
- imageId += firstVehicleEntry->base_image_id;
- imageId += direction;
-
- sint16 height16 = (sint16)height;
- int rotation = get_current_rotation();
- if (hasSupports) {
- uint32 foundationImageId = RCT2_GLOBAL(0x00F441A4, uint32);
- foundationImageId |= 3395;
- sub_98197C(foundationImageId, 0, 0, 28, 28, 45, height, 2, 2, height16, rotation);
-
- sub_98199C(imageId, 0, 0, 28, 28, 45, height, 2, 2, height16, rotation);
- } else {
- sub_98197C(imageId, 0, 0, 28, 28, 45, height, 2, 2, height16, rotation);
- }
-
- height16 += 48;
- if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) < height16) {
- RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = height16;
- RCT2_GLOBAL(0x00141E9DA, uint8) = 32;
- }
-}
-
-/* 0x00761160 */
-TRACK_PAINT_FUNCTION get_track_paint_function_shop(int trackType, int direction)
-{
- switch (trackType) {
- case 118:
- case 121: return shop_paint_setup;
- }
- return NULL;
-}
-
-/**
- *
- * rct2: 0x00763234
- * rct2: 0x0076338C
- * rct2: 0x00762F50
- * rct2: 0x007630DE
- */
-static void facility_paint_setup(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element* mapElement)
-{
- bool hasSupports = wooden_a_supports_paint_setup(direction & 1, 0, height, RCT2_GLOBAL(0x00F441A4, uint32), NULL);
-
- RCT2_GLOBAL(0x0141E9D0, sint16) = -1;
- RCT2_GLOBAL(0x0141E9C4, sint16) = -1;
- RCT2_GLOBAL(0x0141E9CC, sint16) = -1;
- RCT2_GLOBAL(0x0141E9B8, sint16) = -1;
- RCT2_GLOBAL(0x0141E9BC, sint16) = -1;
- RCT2_GLOBAL(0x0141E9B4, sint16) = -1;
- RCT2_GLOBAL(0x0141E9C0, sint16) = -1;
- RCT2_GLOBAL(0x0141E9C8, sint16) = -1;
- RCT2_GLOBAL(0x0141E9D4, sint16) = -1;
-
- rct_ride *ride = get_ride(rideIndex);
- rct_ride_entry *rideEntry = get_ride_entry(ride->subtype);
- rct_ride_entry_vehicle *firstVehicleEntry = &rideEntry->vehicles[0];
-
- uint32 imageId = RCT2_GLOBAL(0x00F44198, uint32);
- imageId |= firstVehicleEntry->base_image_id;
- imageId += (direction + 2) & 3;
-
- sint16 height16 = (sint16)height;
- int rotation = get_current_rotation();
- int lengthX = (direction & 1) == 0 ? 28 : 2;
- int lengthY = (direction & 1) == 0 ? 2 : 28;
- if (hasSupports) {
- uint32 foundationImageId = RCT2_GLOBAL(0x00F441A4, uint32);
- foundationImageId |= 3395;
- sub_98197C(foundationImageId, 0, 0, lengthX, lengthY, 29, height, direction == 3 ? 28 : 2, direction == 0 ? 28 : 2, height16, rotation);
-
- // Door image or base
- sub_98199C(imageId, 0, 0, lengthX, lengthY, 29, height, direction == 3 ? 28 : 2, direction == 0 ? 28 : 2, height16, rotation);
- } else {
- // Door image or base
- sub_98197C(imageId, 0, 0, lengthX, lengthY, 29, height, direction == 3 ? 28 : 2, direction == 0 ? 28 : 2, height16, rotation);
- }
-
- // Base image if door was drawn
- if (direction == 1) {
- imageId += 2;
- sub_98197C(imageId, 0, 0, 2, 28, 29, height, 28, 2, height16, rotation);
- } else if (direction == 2) {
- imageId += 4;
- sub_98197C(imageId, 0, 0, 28, 2, 29, height, 2, 28, height16, rotation);
- }
-
- height16 += 32;
- if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) < height16) {
- RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = height16;
- RCT2_GLOBAL(0x00141E9DA, uint8) = 32;
- }
-}
-
-/* 0x00762D44 */
-TRACK_PAINT_FUNCTION get_track_paint_function_facility(int trackType, int direction)
-{
- switch (trackType) {
- case 118: return facility_paint_setup;
- }
- return NULL;
-}
-
-/**
- * rct2: 0x00761378, 0x007614DB, 0x0076163F, 0x007617A5
- */
-static void ride_50_52_53_54_paint_setup(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element *mapElement) {
- bool supportsDrawn = wooden_a_supports_paint_setup(direction & 1, 0, height, RCT2_GLOBAL(0x00F441A4, uint32), NULL);
-
- RCT2_GLOBAL(0x0141E9D0, uint16) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9C4, uint16) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9CC, uint16) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9B8, uint16) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9BC, uint16) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9B4, uint16) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9C0, uint16) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9C8, uint16) = 0xFFFF;
- RCT2_GLOBAL(0x0141E9D4, uint16) = 0xFFFF;
-
- rct_ride *ride = get_ride(rideIndex);
-
- rct_ride_entry *rideEntry = get_ride_entry(ride->subtype);
-
- uint32 image_id = RCT2_GLOBAL(0x00F44198, uint32);
- if (image_id & 0x80000000) {
- image_id &= 0x60FFFFFF;
- }
-
- image_id += rideEntry->vehicles[0].base_image_id;
- image_id += direction;
- if (supportsDrawn) {
- uint32 ebx = (direction & 1 ? 3396 : 3395) | RCT2_GLOBAL(0x00F441A4, uint32);
- sub_98197C(ebx, 0, 0, 28, 28, 45, height, 2, 2, height, get_current_rotation());
-
- sub_98199C(image_id, 0, 0, 28, 28, 45, height, 2, 2, height, get_current_rotation());
- } else {
- sub_98197C(image_id, 0, 0, 28, 28, 45, height, 2, 2, height, get_current_rotation());
- }
-
- height += 48;
- if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) < height) {
- RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, sint16) = height;
- RCT2_GLOBAL(0x00141E9DA, uint8) = 0x20;
- }
-}
-
-/**
- * rct2: 0x00761160
- */
-TRACK_PAINT_FUNCTION get_track_paint_function_50_52_53_54(int trackType, int direction) {
- switch (trackType) {
- case 118:
- case 121:
- return ride_50_52_53_54_paint_setup;
- }
- return NULL;
-}
diff --git a/src/ride/transport/chairlift.c b/src/ride/transport/chairlift.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/transport/chairlift.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/transport/lift.c b/src/ride/transport/lift.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/transport/lift.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/transport/minature_railway.c b/src/ride/transport/minature_railway.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/transport/minature_railway.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/transport/monorail.c b/src/ride/transport/monorail.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/transport/monorail.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/transport/suspended_monorail.c b/src/ride/transport/suspended_monorail.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/transport/suspended_monorail.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/vehicle_paint.c b/src/ride/vehicle_paint.c
new file mode 100644
index 0000000000..005c7ef01a
--- /dev/null
+++ b/src/ride/vehicle_paint.c
@@ -0,0 +1,76 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
+
+#include "../paint/paint.h"
+#include "../drawing/drawing.h"
+#include "../world/sprite.h"
+#include "../ride/ride_data.h"
+#include "../interface/viewport.h"
+#include "vehicle_paint.h"
+
+/**
+ *
+ * rct2: 0x006D4244
+ */
+void vehicle_paint(rct_vehicle *vehicle, int imageDirection)
+{
+ rct_ride_entry *rideEntry;
+ const rct_ride_entry_vehicle *vehicleEntry;
+
+ int x = vehicle->x;
+ int y = vehicle->y;
+ int z = vehicle->z;
+
+ if (vehicle->flags & SPRITE_FLAGS_IS_CRASHED_VEHICLE_SPRITE) {
+ uint32 ebx = 22965 + vehicle->var_C5;
+ sub_98197C(ebx, 0, 0, 1, 1, 0, z, 0, 0, z + 2, get_current_rotation());
+ return;
+ }
+
+ if (vehicle->ride_subtype == 0xFF) {
+ vehicleEntry = &CableLiftVehicle;
+ } else {
+ rideEntry = get_ride_entry(vehicle->ride_subtype);
+ vehicleEntry = &rideEntry->vehicles[vehicle->vehicle_type];
+
+ if (vehicle->update_flags & VEHICLE_UPDATE_FLAG_11) {
+ vehicleEntry++;
+ z += 16;
+ }
+ }
+
+ uint32 rct2VehiclePtrFormat = ((uint32)vehicleEntry) - offsetof(rct_ride_entry, vehicles);
+ RCT2_GLOBAL(0x00F64DFC, uint32) = rct2VehiclePtrFormat;
+ switch (vehicleEntry->car_visual) {
+ case VEHICLE_VISUAL_DEFAULT: RCT2_CALLPROC_X(0x006D45F8, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break;
+ case VEHICLE_VISUAL_LAUNCHED_FREEFALL: vehicle_visual_launched_freefall(x, imageDirection, y, z, vehicle, vehicleEntry); break;
+ case VEHICLE_VISUAL_OBSERVATION_TOWER: vehicle_visual_observation_tower(x, imageDirection, y, z, vehicle, vehicleEntry); break;
+ case VEHICLE_VISUAL_RIVER_RAPIDS: RCT2_CALLPROC_X(0x006D5889, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break;
+ case VEHICLE_VISUAL_MINI_GOLF_PLAYER: RCT2_CALLPROC_X(0x006D42F0, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break;
+ case VEHICLE_VISUAL_MINI_GOLF_BALL: RCT2_CALLPROC_X(0x006D43C6, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break;
+ case VEHICLE_VISUAL_REVERSER: RCT2_CALLPROC_X(0x006D4453, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break;
+ case VEHICLE_VISUAL_SPLASH_BOATS_OR_WATER_COASTER: RCT2_CALLPROC_X(0x006D4295, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break;
+ case VEHICLE_VISUAL_ROTO_DROP: vehicle_visual_roto_drop(x, imageDirection, y, z, vehicle, vehicleEntry); break;
+ case 10: RCT2_CALLPROC_X(0x006D5600, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break;
+ case 11: RCT2_CALLPROC_X(0x006D5696, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break;
+ case 12: RCT2_CALLPROC_X(0x006D57EE, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break;
+ case 13: RCT2_CALLPROC_X(0x006D5783, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break;
+ case 14: RCT2_CALLPROC_X(0x006D5701, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break;
+ case VEHICLE_VISUAL_VIRGINIA_REEL: vehicle_visual_virginia_reel(x, imageDirection, y, z, vehicle, vehicleEntry); break;
+ case VEHICLE_VISUAL_SUBMARINE: RCT2_CALLPROC_X(0x006D44D5, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break;
+ }
+}
+
diff --git a/src/ride/vehicle_paint.h b/src/ride/vehicle_paint.h
new file mode 100644
index 0000000000..410e6af70f
--- /dev/null
+++ b/src/ride/vehicle_paint.h
@@ -0,0 +1,29 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
+
+#ifndef _VEHICLE_PAINT_H
+#define _VEHICLE_PAINT_H
+
+#include "vehicle.h"
+
+void vehicle_paint(rct_vehicle *vehicle, int imageDirection);
+
+void vehicle_visual_roto_drop(int x, int imageDirection, int y, int z, rct_vehicle *vehicle, const rct_ride_entry_vehicle *vehicleEntry);
+void vehicle_visual_observation_tower(int x, int imageDirection, int y, int z, rct_vehicle *vehicle, const rct_ride_entry_vehicle *vehicleEntry);
+void vehicle_visual_launched_freefall(int x, int imageDirection, int y, int z, rct_vehicle *vehicle, const rct_ride_entry_vehicle *vehicleEntry);
+void vehicle_visual_virginia_reel(int x, int imageDirection, int y, int z, rct_vehicle *vehicle, const rct_ride_entry_vehicle *vehicleEntry);
+
+#endif
\ No newline at end of file
diff --git a/src/ride/water/boat_ride.c b/src/ride/water/boat_ride.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/water/boat_ride.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/water/dingy_slide.c b/src/ride/water/dingy_slide.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/water/dingy_slide.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/water/log_flume.c b/src/ride/water/log_flume.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/water/log_flume.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/water/river_rafts.c b/src/ride/water/river_rafts.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/water/river_rafts.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/water/river_rapids.c b/src/ride/water/river_rapids.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/water/river_rapids.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/water/splash_boats.c b/src/ride/water/splash_boats.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/water/splash_boats.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/water/submarine_ride.c b/src/ride/water/submarine_ride.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/water/submarine_ride.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file
diff --git a/src/ride/water/water_coaster.c b/src/ride/water/water_coaster.c
new file mode 100644
index 0000000000..934a276c17
--- /dev/null
+++ b/src/ride/water/water_coaster.c
@@ -0,0 +1,15 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+*
+* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+* For more information, visit https://github.com/OpenRCT2/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.
+*
+* A full copy of the GNU General Public License can be found in licence.txt
+*****************************************************************************/
+#pragma endregion
\ No newline at end of file