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