From 42ef09253e0fc2270fde96a2cb489361ad10e2a1 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Sun, 21 Sep 2014 13:50:35 +0100 Subject: [PATCH] implement ride measurement update --- src/game.c | 11 +++-- src/ride.c | 122 +++++++++++++++++++++++++++++++++++++++++++++- src/ride.h | 14 ++++-- src/vehicle.c | 18 +++++++ src/vehicle.h | 3 +- src/window_ride.c | 4 +- 6 files changed, 160 insertions(+), 12 deletions(-) diff --git a/src/game.c b/src/game.c index 39556fc8e9..a0d310d434 100644 --- a/src/game.c +++ b/src/game.c @@ -22,15 +22,16 @@ #include "audio.h" #include "climate.h" #include "config.h" -#include "rct2.h" -#include "game.h" #include "finance.h" +#include "game.h" #include "input.h" #include "news_item.h" #include "object.h" #include "osinterface.h" #include "park.h" #include "peep.h" +#include "rct2.h" +#include "ride.h" #include "sawyercoding.h" #include "scenario.h" #include "screenshot.h" @@ -379,9 +380,9 @@ void game_logic_update() RCT2_CALLPROC_EBPSAFE(0x00672AA4); // update text effects RCT2_CALLPROC_EBPSAFE(0x006ABE4C); // update rides park_update(); - RCT2_CALLPROC_EBPSAFE(0x00684C7A); - RCT2_CALLPROC_EBPSAFE(0x006B5A2A); - RCT2_CALLPROC_EBPSAFE(0x006B6456); // update ride measurements + RCT2_CALLPROC_EBPSAFE(0x00684C7A); // update research + RCT2_CALLPROC_EBPSAFE(0x006B5A2A); // update ride ratings + ride_measurements_update(); RCT2_CALLPROC_EBPSAFE(0x0068AFAD); vehicle_sounds_update();//RCT2_CALLPROC_EBPSAFE(0x006BBC6B); // vehicle and scream sounds peep_update_crowd_noise(); diff --git a/src/ride.c b/src/ride.c index a13c4dc12d..2effab9c45 100644 --- a/src/ride.c +++ b/src/ride.c @@ -154,7 +154,7 @@ void ride_init_all() for (i = 0; i < MAX_RIDE_MEASUREMENTS; i++) { ride_measurement = GET_RIDE_MEASUREMENT(i); - ride_measurement->var_00 = 0xFF; + ride_measurement->ride_index = 255; } } @@ -653,4 +653,124 @@ uint8 *get_ride_entry_indices_for_ride_type(uint8 rideType) rideType--; } return entryIndexList; +} + + + +/** + * rct2: 0x006B64F2 + */ +void ride_measurement_update(rct_ride_measurement *measurement) +{ + uint16 spriteIndex; + rct_ride *ride; + rct_vehicle *vehicle; + int unk, velocity, altitude, verticalG, lateralG; + + ride = GET_RIDE(measurement->ride_index); + spriteIndex = ride->vehicles[measurement->vehicle_index]; + if (spriteIndex == SPRITE_INDEX_NULL) + return; + + vehicle = &(g_sprite_list[spriteIndex].vehicle); + + if (measurement->flags & RIDE_MEASUREMENT_FLAG_UNLOADING) { + if (vehicle->status != VEHICLE_STATUS_DEPARTING && vehicle->status != VEHICLE_STATUS_STOPPING) + return; + + measurement->flags &= ~RIDE_MEASUREMENT_FLAG_UNLOADING; + if (measurement->var_0B == vehicle->var_4B) + measurement->current_item = 0; + } + + if (vehicle->status == VEHICLE_STATUS_UNLOADING_PASSENGERS) { + measurement->flags |= RIDE_MEASUREMENT_FLAG_UNLOADING; + return; + } + + unk = (vehicle->var_36 / 4) & 0xFF; + if (unk == 216 || unk == 123 || unk == 9 || unk == 63 || unk == 147 || unk == 155) + if (vehicle->velocity == 0) + return; + + if (measurement->current_item >= RIDE_MEASUREMENT_MAX_ITEMS) + return; + + if (measurement->flags & RIDE_MEASUREMENT_FLAG_G_FORCES) { + vehicle_get_g_forces(vehicle, &verticalG, &lateralG); + verticalG = clamp(-127, verticalG / 8, 127); + lateralG = clamp(-127, lateralG / 8, 127); + + if (RCT2_GLOBAL(0x00F663AC, uint32) & 1) { + verticalG = (verticalG + measurement->vertical[measurement->current_item]) / 2; + lateralG = (lateralG + measurement->lateral[measurement->current_item]) / 2; + } + + measurement->vertical[measurement->current_item] = verticalG & 0xFF; + measurement->lateral[measurement->current_item] = lateralG & 0xFF; + } + + velocity = min(abs((vehicle->velocity * 5) >> 16), 255); + altitude = min(vehicle->z / 8, 255); + + if (RCT2_GLOBAL(0x00F663AC, uint32) & 1) { + velocity = (velocity + measurement->velocity[measurement->current_item]) / 2; + altitude = (altitude + measurement->altitude[measurement->current_item]) / 2; + } + + measurement->velocity[measurement->current_item] = velocity & 0xFF; + measurement->altitude[measurement->current_item] = altitude & 0xFF; + + if (RCT2_GLOBAL(0x00F663AC, uint32) & 1) { + measurement->current_item++; + measurement->num_items = max(measurement->num_items, measurement->current_item); + } +} + +/** + * rct2: 0x006B6456 + */ +void ride_measurements_update() +{ + rct_ride *ride; + rct_ride_measurement *measurement; + rct_vehicle *vehicle; + int i, j; + uint16 spriteIndex; + + if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_SCENARIO_EDITOR) + return; + + // For each ride measurement + for (i = 0; i < MAX_RIDE_MEASUREMENTS; i++) { + measurement = GET_RIDE_MEASUREMENT(i); + if (measurement->ride_index == 255) + continue; + + ride = GET_RIDE(measurement->ride_index); + if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK)) + continue; + + if (measurement->flags & RIDE_MEASUREMENT_FLAG_RUNNING) { + ride_measurement_update(measurement); + } else { + // For each vehicle + for (j = 0; j < ride->num_vehicles; j++) { + spriteIndex = ride->vehicles[j]; + if (spriteIndex == SPRITE_INDEX_NULL) + continue; + + vehicle = &(g_sprite_list[spriteIndex].vehicle); + if (vehicle->status == VEHICLE_STATUS_DEPARTING || vehicle->status == VEHICLE_STATUS_STOPPING) { + measurement->vehicle_index = j; + measurement->var_0B = vehicle->var_4B; + measurement->flags |= RIDE_MEASUREMENT_FLAG_RUNNING; + measurement->flags &= ~RIDE_MEASUREMENT_FLAG_UNLOADING; + ride_measurement_update(measurement); + break; + } + } + + } + } } \ No newline at end of file diff --git a/src/ride.h b/src/ride.h index 0c27f18ca6..7f3d0e0e53 100644 --- a/src/ride.h +++ b/src/ride.h @@ -198,12 +198,13 @@ typedef struct { * size: 0x04B0C */ typedef struct { - uint8 var_00; - uint8 var_01; + uint8 ride_index; // 0x0000 + uint8 flags; uint8 pad_02[4]; uint16 num_items; // 0x0006 uint16 current_item; // 0x0008 - uint16 var_0A; + uint8 vehicle_index; // 0x000A + uint8 var_0B; sint8 vertical[RIDE_MEASUREMENT_MAX_ITEMS]; // 0x000C sint8 lateral[RIDE_MEASUREMENT_MAX_ITEMS]; // 0x12CC uint8 velocity[RIDE_MEASUREMENT_MAX_ITEMS]; // 0x258C @@ -497,6 +498,12 @@ typedef struct { uint8 additional_2; } vehicle_colour; +enum { + RIDE_MEASUREMENT_FLAG_RUNNING = 1 << 0, + RIDE_MEASUREMENT_FLAG_UNLOADING = 1 << 1, + RIDE_MEASUREMENT_FLAG_G_FORCES = 1 << 2 +}; + #define MAX_RIDES 255 #define MAX_RIDE_MEASUREMENTS 8 @@ -541,5 +548,6 @@ track_colour ride_get_track_colour(rct_ride *ride, int colourScheme); vehicle_colour ride_get_vehicle_colour(rct_ride *ride, int vehicleIndex); rct_ride_type *ride_get_entry(rct_ride *ride); uint8 *get_ride_entry_indices_for_ride_type(uint8 rideType); +void ride_measurements_update(); #endif diff --git a/src/vehicle.c b/src/vehicle.c index 5c802c1c93..4575d61547 100644 --- a/src/vehicle.c +++ b/src/vehicle.c @@ -490,4 +490,22 @@ void vehicle_update_all() static void vehicle_update(rct_vehicle *vehicle) { RCT2_CALLPROC_X(0x006D77F2, 0, 0, 0, 0, (int)vehicle, 0, 0); +} + +/** + * + * rct2: 0x006D73D0 + * ax: verticalG + * dx: lateralG + * esi: vehicle + */ +void vehicle_get_g_forces(rct_vehicle *vehicle, int *verticalG, int *lateralG) +{ + int eax, ebx, ecx, edx, esi, edi, ebp; + + esi = (int)vehicle; + RCT2_CALLFUNC_X(0x006D73D0, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + + if (verticalG != NULL) *verticalG = (sint16)(eax & 0xFFFF); + if (lateralG != NULL) *lateralG = (sint16)(edx & 0xFFFF); } \ No newline at end of file diff --git a/src/vehicle.h b/src/vehicle.h index 668f16a350..d781ba8202 100644 --- a/src/vehicle.h +++ b/src/vehicle.h @@ -64,7 +64,7 @@ typedef struct { uint8 pad_4A; uint8 var_4B; uint8 pad_4C[0x4]; - uint8 status; + uint8 status; // 0x50 uint8 var_51; uint16 peep; // 0x52 uint8 pad_54[0x2C]; @@ -125,6 +125,7 @@ void vehicle_update_all(); int sub_6BC2F3(rct_vehicle* vehicle); void sub_6BB9FF(rct_vehicle* vehicle); void vehicle_sounds_update(); +void vehicle_get_g_forces(rct_vehicle *vehicle, int *verticalG, int *lateralG); /** Helper macro until rides are stored in this module. */ #define GET_VEHICLE(sprite_index) &(g_sprite_list[sprite_index].vehicle) diff --git a/src/window_ride.c b/src/window_ride.c index a3f2cfe33c..d937d0f05e 100644 --- a/src/window_ride.c +++ b/src/window_ride.c @@ -4811,8 +4811,8 @@ static void window_ride_graphs_tooltip() if (widgetIndex == WIDX_GRAPH) { RCT2_GLOBAL(0x013CE952, uint16) = 3158; measurement = ride_get_measurement(w->number, &stringId); - if (measurement != NULL && (measurement->var_01 & 1)) { - RCT2_GLOBAL(0x013CE952 + 4, uint16) = measurement->var_0A + 1; + if (measurement != NULL && (measurement->flags & RIDE_MEASUREMENT_FLAG_RUNNING)) { + RCT2_GLOBAL(0x013CE952 + 4, uint16) = measurement->vehicle_index + 1; ride = GET_RIDE(w->number); RCT2_GLOBAL(0x013CE952 + 2, uint16) = RideNameConvention[ride->type].vehicle_name + 6; result = 0;