diff --git a/src/audio.c b/src/audio.c index 86b9b8d36a..f9be13d26e 100644 --- a/src/audio.c +++ b/src/audio.c @@ -1179,19 +1179,19 @@ int sound_play_panned(int sound_id, int ebx, sint16 x, sint16 y, sint16 z) sint16 v11; sint16 v12; switch (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)) { - case MAP_ELEMENT_DIRECTION_WEST: + case 0: v11 = y - x; v12 = ((y + x) / 2) - z; break; - case MAP_ELEMENT_DIRECTION_NORTH: + case 1: v11 = -x - y; v12 = ((y - x) / 2) - z; break; - case MAP_ELEMENT_DIRECTION_EAST: + case 2: v11 = x - y; v12 = ((-y - x) / 2) - z; break; - case MAP_ELEMENT_DIRECTION_SOUTH: + case 3: v11 = y + x; v12 = ((x - y) / 2) - z; break; 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/gfx.c b/src/gfx.c index 53c4942d59..6ca5237ec7 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -2072,7 +2072,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in // Control codes switch (al) { case FORMAT_MOVE_X://Start New Line at start+buffer x, same y. (Overwrite?) - max_x = x + *++buffer; + max_x = x + (uint8)*++buffer; break; case FORMAT_ADJUST_PALETTE: al = *++buffer; diff --git a/src/peep.c b/src/peep.c index d798790f79..623fff5273 100644 --- a/src/peep.c +++ b/src/peep.c @@ -32,6 +32,35 @@ static void peep_update(rct_peep *peep); +const char *gPeepEasterEggNames[] = { + "MICHAEL SCHUMACHER", + "JACQUES VILLENEUVE", + "DAMON HILL", + "MR BEAN", + "CHRIS SAWYER", + "KATIE BRAYSHAW", + "MELANIE WARN", + "SIMON FOSTER", + "JOHN WARDLEY", + "LISA STIRLING", + "DONALD MACRAE", + "KATHERINE MCGOWAN", + "FRANCES MCGOWAN", + "CORINA MASSOURA", + "CAROL YOUNG", + "MIA SHERIDAN", + "KATIE RODGER", + "EMMA GARRELL", + "JOANNE BARTON", + "FELICITY ANDERSON", + "KATIE SMITH", + "EILIDH BELL", + "NANCY STILLWAGON", + "ANDY HINE", + "ELISSA WHITE", + "DAVID ELLIS" +}; + int peep_get_staff_count() { uint16 spriteIndex; @@ -669,53 +698,49 @@ int get_face_sprite_offset(rct_peep *peep){ } /** -* Function split into large and small sprite -* rct2: 0x00698721 -*/ + * Function split into large and small sprite + * rct2: 0x00698721 + */ int get_peep_face_sprite_small(rct_peep *peep){ return face_sprite_small[get_face_sprite_offset(peep)]; } /** -* Function split into large and small sprite -* rct2: 0x00698721 -*/ + * Function split into large and small sprite + * rct2: 0x00698721 + */ int get_peep_face_sprite_large(rct_peep *peep){ return face_sprite_large[get_face_sprite_offset(peep)]; } /** -* -* rct2: 0x0069A5A0 -* tests if a peep's name matches a cheat code, normally returns using a register flag -* @param index (eax) -* @param ride (esi) -*/ -int peep_check_cheatcode(int index, rct_peep *peep) + * + * rct2: 0x0069A5A0 + * tests if a peep's name matches a cheat code, normally returns using a register flag + * @param index (eax) + * @param ride (esi) + */ +int peep_check_easteregg_name(int index, rct_peep *peep) { - char* str = RCT2_ADDRESS(RCT2_ADDRESS_EASTEREGG_NAMES, char*)[index]; - char* dst = (char*)RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER; - format_string(dst, peep->name_string_idx, &peep->id); + char buffer[256]; - // strtoupper: - int i = 0; - while(dst[i]) { - if (dst[i] >= 0x61 && dst[i] <= 0x7A) { - dst[i] -= 0x20; - } - i++; - } + format_string(buffer, peep->name_string_idx, &peep->id); + return _stricmp(buffer, gPeepEasterEggNames[index]) == 0; +} - // check for match, characters are -1 to obfuscate the cheat codes - i = 0; - while(str[i] + 1) { - if (str[i] + 1 != dst[i]) { - return 0; - } - i++; - } +int peep_get_easteregg_name_id(rct_peep *peep) +{ + char buffer[256]; + int i; + + format_string(buffer, peep->name_string_idx, &peep->id); + + for (i = 0; i < countof(gPeepEasterEggNames); i++) + if (_stricmp(buffer, gPeepEasterEggNames[i]) == 0) + return i; + + return -1; - return 1; } int peep_is_mechanic(rct_peep *peep) diff --git a/src/peep.h b/src/peep.h index 78569e99be..858047cdfb 100644 --- a/src/peep.h +++ b/src/peep.h @@ -426,6 +426,35 @@ typedef struct { uint32 item_standard_flags; // 0xFC } rct_peep; +enum { + EASTEREGG_PEEP_NAME_MICHAEL_SCHUMACHER, + EASTEREGG_PEEP_NAME_JACQUES_VILLENEUVE, + EASTEREGG_PEEP_NAME_DAMON_HILL, + EASTEREGG_PEEP_NAME_MR_BEAN, + EASTEREGG_PEEP_NAME_CHRIS_SAWYER, + EASTEREGG_PEEP_NAME_KATIE_BRAYSHAW, + EASTEREGG_PEEP_NAME_MELANIE_WARN, + EASTEREGG_PEEP_NAME_SIMON_FOSTER, + EASTEREGG_PEEP_NAME_JOHN_WARDLEY, + EASTEREGG_PEEP_NAME_LISA_STIRLING, + EASTEREGG_PEEP_NAME_DONALD_MACRAE, + EASTEREGG_PEEP_NAME_KATHERINE_MCGOWAN, + EASTEREGG_PEEP_NAME_FRANCES_MCGOWAN, + EASTEREGG_PEEP_NAME_CORINA_MASSOURA, + EASTEREGG_PEEP_NAME_CAROL_YOUNG, + EASTEREGG_PEEP_NAME_MIA_SHERIDAN, + EASTEREGG_PEEP_NAME_KATIE_RODGER, + EASTEREGG_PEEP_NAME_EMMA_GARRELL, + EASTEREGG_PEEP_NAME_JOANNE_BARTON, + EASTEREGG_PEEP_NAME_FELICITY_ANDERSON, + EASTEREGG_PEEP_NAME_KATIE_SMITH, + EASTEREGG_PEEP_NAME_EILIDH_BELL, + EASTEREGG_PEEP_NAME_NANCY_STILLWAGON, + EASTEREGG_PEEP_NAME_ANDY_HINE, + EASTEREGG_PEEP_NAME_ELISSA_WHITE, + EASTEREGG_PEEP_NAME_DAVID_ELLIS +}; + /** Helper macro until rides are stored in this module. */ #define GET_PEEP(sprite_index) &(g_sprite_list[sprite_index].peep) @@ -456,7 +485,8 @@ void get_arguments_from_action(rct_peep* peep, uint32 *argument_1, uint32* argum void get_arguments_from_thought(rct_peep_thought thought, uint32* argument_1, uint32* argument_2); int get_peep_face_sprite_small(rct_peep *peep); int get_peep_face_sprite_large(rct_peep *peep); -int peep_check_cheatcode(int index, rct_peep *peep); +int peep_check_easteregg_name(int index, rct_peep *peep); +int peep_get_easteregg_name_id(rct_peep *peep); int peep_is_mechanic(rct_peep *peep); #endif diff --git a/src/ride.c b/src/ride.c index a13c4dc12d..da87ccce29 100644 --- a/src/ride.c +++ b/src/ride.c @@ -26,6 +26,7 @@ #include "staff.h" #include "sprite.h" #include "ride.h" +#include "ride_data.h" #include "scenario.h" #include "sprite.h" #include "peep.h" @@ -154,7 +155,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; } } @@ -590,48 +591,46 @@ vehicle_colour ride_get_vehicle_colour(rct_ride *ride, int vehicleIndex) } /** -* -* rct2: 0x006AC988 -* set the speed of the gokart type vehicle at the start to a random value or alter if peep name is a cheat code -* @param ride (esi) -*/ + * + * rct2: 0x006AC988 + * set the speed of the go kart type vehicle at the start to a random value or alter if peep name is an easter egg + * @param ride (esi) + */ void ride_init_vehicle_speed(rct_ride *ride) { - int ecx = -1; - while (1) { - ecx++; - if (ecx >= ride->num_vehicles) { - break; - } - rct_vehicle *vehicle = &g_sprite_list[ride->vehicles[ecx]].vehicle; - vehicle->var_48 &= (1 << 6); - uint8 r = scenario_rand(); - r = 0xC; - r &= 0xF; - r -= 8; + rct_ride_type *rideEntry; + rct_vehicle *vehicle; + uint8 *unk; + int i; - int testaddr = (vehicle->var_31 * 0x65); - testaddr += (int)RCT2_ADDRESS(0x009ACFA4, rct_ride_type*)[vehicle->var_D6]; - uint8 test = ((uint8*)testaddr)[0x76]; - r += test; + for (i = 0; i < ride->num_vehicles; i++) { + vehicle = &g_sprite_list[ride->vehicles[i]].vehicle; + vehicle->var_48 &= ~(1 << 6); + + rideEntry = GET_RIDE_ENTRY(vehicle->var_D6); + unk = (uint8*)((int)rideEntry + (vehicle->var_31 * 0x65)); + + vehicle->speed = (scenario_rand() & 16) - 8 + RCT2_GLOBAL(unk + 0x76, uint8); - vehicle->speed = r; if (vehicle->var_B3) { rct_peep *peep = &g_sprite_list[vehicle->peep].peep; - if (peep_check_cheatcode(0, peep)) { // MICHAEL SCHUMACHER + + switch (peep_get_easteregg_name_id(peep)) { + case EASTEREGG_PEEP_NAME_MICHAEL_SCHUMACHER: vehicle->speed += 35; - } - if (peep_check_cheatcode(1, peep)) { // JACQUES VILLENEUVE + break; + case EASTEREGG_PEEP_NAME_JACQUES_VILLENEUVE: vehicle->speed += 25; - } - if (peep_check_cheatcode(2, peep)) { // DAMON HILL + break; + case EASTEREGG_PEEP_NAME_DAMON_HILL: vehicle->speed += 55; - } - if (peep_check_cheatcode(4, peep)) { // CHRIS SAWYER + break; + case EASTEREGG_PEEP_NAME_CHRIS_SAWYER: vehicle->speed += 14; - } - if (peep_check_cheatcode(3, peep)) { // MR BEAN + break; + case EASTEREGG_PEEP_NAME_MR_BEAN: vehicle->speed = 9; + break; } } } @@ -653,4 +652,195 @@ 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(RCT2_ADDRESS_SCENARIO_TICKS, 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(RCT2_ADDRESS_SCENARIO_TICKS, 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(RCT2_ADDRESS_SCENARIO_TICKS, 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; + } + } + + } + } +} + +/** + * + * rct2: 0x006B66D9 + */ +rct_ride_measurement *ride_get_measurement(int rideIndex, rct_string_id *message) +{ + rct_ride *ride; + rct_ride_measurement *measurement; + uint32 lruTicks; + int i, lruIndex; + + ride = GET_RIDE(rideIndex); + + // Check if ride type supports data logging + if (!(RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + (ride->type * 8), uint32) & 0x200)) { + if (message != NULL) *message = STR_DATA_LOGGING_NOT_AVAILABLE_FOR_THIS_TYPE_OF_RIDE; + return NULL; + } + + // Check if a measurement already exists for this ride + for (i = 0; i < MAX_RIDE_MEASUREMENTS; i++) { + measurement = GET_RIDE_MEASUREMENT(i); + if (measurement->ride_index == i) + goto use_measurement; + } + + // Find a free measurement + for (i = 0; i < MAX_RIDE_MEASUREMENTS; i++) { + measurement = GET_RIDE_MEASUREMENT(i); + if (measurement->ride_index == 255) + goto new_measurement; + } + + // Use last recently used measurement for some other ride + lruIndex = 0; + lruTicks = 0xFFFFFFFF; + for (i = 0; i < MAX_RIDE_MEASUREMENTS; i++) { + measurement = GET_RIDE_MEASUREMENT(i); + + if (measurement->last_use_tick <= lruTicks) { + lruTicks = measurement->last_use_tick; + lruIndex = i; + } + } + + i = lruIndex; + measurement = GET_RIDE_MEASUREMENT(i); + ride->measurement_index = 255; + +new_measurement: + measurement->ride_index = rideIndex; + ride->measurement_index = i; + measurement->flags = 0; + if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + (ride->type * 8), uint32) & 0x80) + measurement->flags |= RIDE_MEASUREMENT_FLAG_G_FORCES; + measurement->num_items = 0; + measurement->current_item = 0; + +use_measurement: + measurement->last_use_tick = RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, uint32); + if (measurement->flags & 1) { + if (message != NULL) *message = 0; + return measurement; + } else { + RCT2_GLOBAL(0x013CE952, uint16) = RideNameConvention[ride->type].vehicle_name; + RCT2_GLOBAL(0x013CE952 + 2, uint16) = RideNameConvention[ride->type].station_name; + if (message != NULL) *message = STR_DATA_LOGGING_WILL_START_WHEN_NEXT_LEAVES; + return NULL; + } } \ No newline at end of file diff --git a/src/ride.h b/src/ride.h index 0c27f18ca6..1116903b04 100644 --- a/src/ride.h +++ b/src/ride.h @@ -89,7 +89,9 @@ typedef struct { uint16 overall_view; // 0x050 00XX = X, XX00 = Y (* 32 + 16) uint16 station_starts[4]; // 0x052 uint8 station_heights[4]; // 0x05A - uint8 pad_05E[0xC]; + uint8 pad_05E[0x4]; + uint8 var_062[4]; + uint8 pad_066[0x4]; uint16 entrances[4]; // 0x06A uint16 exits[4]; // 0x072 uint8 pad_07A[0x0C]; @@ -106,7 +108,9 @@ typedef struct { uint8 min_waiting_time; // 0x0CE uint8 max_waiting_time; // 0x0CF uint8 var_0D0; - uint8 pad_0D1[0x7]; + uint8 pad_0D1[0x3]; + uint8 measurement_index; // 0x0D4 + uint8 pad_0D5[0x3]; sint32 max_speed; // 0x0D8 sint32 average_speed; // 0x0DC uint8 pad_0E0[0x4]; @@ -120,7 +124,8 @@ typedef struct { uint8 drops; // 0x115 (??XX XXXX) uint8 pad_116; uint8 highest_drop_height; // 0x117 - uint8 pad_118[0x0C]; + uint32 var_118; + uint8 pad_11C[0x08]; sint16 var_124; sint16 var_126; sint16 var_128; @@ -177,7 +182,7 @@ typedef struct { uint8 track_colour_supports[4]; // 0x1C4 uint8 music; // 0x1C8 uint8 entrance_style; // 0x1C9 - uint8 pad_1CA[0x02]; + uint16 var_1CA; uint8 num_block_brakes; // 0x1CC uint8 lift_hill_speed; // 0x1CD uint16 guests_favourite; // 0x1CE @@ -198,12 +203,13 @@ typedef struct { * size: 0x04B0C */ typedef struct { - uint8 var_00; - uint8 var_01; - uint8 pad_02[4]; + uint8 ride_index; // 0x0000 + uint8 flags; // 0x0001 + uint32 last_use_tick; // 0x0002 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 +503,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 +553,7 @@ 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(); +rct_ride_measurement *ride_get_measurement(int rideIndex, rct_string_id *message); #endif diff --git a/src/string_ids.h b/src/string_ids.h index 49d8eced3d..9cf960b8f6 100644 --- a/src/string_ids.h +++ b/src/string_ids.h @@ -474,6 +474,8 @@ enum { STR_BUILD_THIS = 1407, STR_COST_LABEL = 1408, + STR_DATA_LOGGING_NOT_AVAILABLE_FOR_THIS_TYPE_OF_RIDE = 1412, + STR_DATA_LOGGING_WILL_START_WHEN_NEXT_LEAVES = 1413, STR_LOGGING_DATA_FROM_TIP = 1422, STR_QUEUE_LINE_PATH_TIP = 1423, STR_FOOTPATH_TIP = 1424, 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/widget.c b/src/widget.c index 0e4038d337..7a460654d2 100644 --- a/src/widget.c +++ b/src/widget.c @@ -809,6 +809,9 @@ static void widget_scroll_draw(rct_drawpixelinfo *dpi, rct_window *w, int widget if (scroll->flags & VSCROLLBAR_VISIBLE) r -= 11; + b++; + r++; + // Create a new inner scroll dpi scroll_dpi = *dpi; diff --git a/src/window.c b/src/window.c index 7f12a29de5..41553254cc 100644 --- a/src/window.c +++ b/src/window.c @@ -39,6 +39,28 @@ rct_window* g_window_list = RCT2_ADDRESS(RCT2_ADDRESS_WINDOW_LIST, rct_window); +// converted from uint16 values at 0x009A41EC - 0x009A4230 +// these are percentage coordinates of the viewport to center to, if a window is obscuring a location, the next is tried +float window_scroll_locations[][2] = { + 0.5f, 0.5f, + 0.75f, 0.5f, + 0.25f, 0.5f, + 0.5f, 0.75f, + 0.5f, 0.25f, + 0.75f, 0.75f, + 0.75f, 0.25f, + 0.25f, 0.75f, + 0.25f, 0.25f, + 0.125f, 0.5f, + 0.875f, 0.5f, + 0.5f, 0.125f, + 0.5f, 0.875f, + 0.875f, 0.125f, + 0.875f, 0.875f, + 0.125f, 0.875f, + 0.125f, 0.125f, +}; + static void window_all_wheel_input(); static int window_draw_split(rct_window *w, int left, int top, int right, int bottom); @@ -720,6 +742,7 @@ void window_init_scroll_widgets(rct_window *w) } scroll = &w->scrolls[scroll_index]; + scroll->flags = 0; window_get_scroll_size(w, scroll_index, &width, &height); scroll->h_left = 0; scroll->h_right = width + 1; @@ -952,12 +975,87 @@ void window_scroll_to_viewport(rct_window *w) } /** - * - * rct2: 0x006E7C9C - */ +* +* rct2: 0x006E7C9C +* @param w (esi) +* @param x (eax) +* @param y (ecx) +* @param z (edx) +*/ void window_scroll_to_location(rct_window *w, int x, int y, int z) { - RCT2_CALLPROC_X(0x006E7C9C, x, 0, y, z, (int)w, 0, 0); + if (w->viewport) { + sint16 height = map_element_height(x, y); + if (z < height - 16) { + if (!(w->viewport->flags & 1 << 0)) { + w->viewport->flags |= 1 << 0; + window_invalidate(w); + } + } else { + if (w->viewport->flags & 1 << 0) { + w->viewport->flags &= ~(1 << 0); + window_invalidate(w); + } + } + sint16 sx; + sint16 sy; + switch (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint8)) { + case 0: + sx = y - x; + sy = ((x + y) / 2) - z; + break; + case 1: + sx = -y - x; + sy = ((-x + y) / 2) - z; + break; + case 2: + sx = -y + x; + sy = ((-x - y) / 2) - z; + break; + case 3: + sx = y + x; + sy = ((x - y) / 2) - z; + break; + } + int i = 0; + if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TITLE_DEMO)) { + int found = 0; + while (!found) { + sint16 x2 = w->viewport->x + (sint16)(w->viewport->width * window_scroll_locations[i][0]); + sint16 y2 = w->viewport->y + (sint16)(w->viewport->height * window_scroll_locations[i][1]); + rct_window* w2 = w; + while (1) { + w2++; + if (w2 >= RCT2_GLOBAL(RCT2_ADDRESS_NEW_WINDOW_PTR, rct_window*)) { + found = 1; + break; + } + sint16 x1 = w2->x - 10; + sint16 y1 = w2->y - 10; + if (x2 >= x1 && x2 <= w2->width + x1 + 20) { + if (y2 >= y1 && y2 <= w2->height + y1 + 20) { + // window is covering this area, try the next one + i++; + found = 0; + break; + } + } + } + if (i >= countof(window_scroll_locations)) { + i = 0; + found = 1; + } + } + } + // rct2: 0x006E7C76 + if (w->viewport_target_sprite == -1) { + if (!(w->flags & WF_2)) { + w->saved_view_x = sx - (sint16)(w->viewport->view_width * window_scroll_locations[i][0]); + w->saved_view_y = sy - (sint16)(w->viewport->view_height * window_scroll_locations[i][1]); + w->flags |= WF_SCROLLING_TO_LOCATION; + } + } + } } /** diff --git a/src/window_ride.c b/src/window_ride.c index a96f0241da..4b80aa6f4f 100644 --- a/src/window_ride.c +++ b/src/window_ride.c @@ -1201,6 +1201,7 @@ static void window_ride_set_page(rct_window *w, int page) w->enabled_widgets = window_ride_page_enabled_widgets[page]; w->var_020 = RCT2_ADDRESS(0x0098DD68, uint32)[page]; w->event_handlers = window_ride_page_events[page]; + w->pressed_widgets = 0; w->widgets = window_ride_page_widgets[page]; RCT2_CALLPROC_X(0x006AEB9F, 0, 0, 0, 0, (int)w, 0, 0); window_invalidate(w); @@ -3908,11 +3909,11 @@ static void window_ride_colour_scrollpaint() vehicleColour = ride_get_vehicle_colour(ride, w->var_48C); // Background colour - gfx_fill_rect(dpi, dpi->x, dpi->y, dpi->x + dpi->width, dpi->y + dpi->height, 12); + gfx_fill_rect(dpi, dpi->x, dpi->y, dpi->x + dpi->width - 1, dpi->y + dpi->height - 1, 12); // ? - x = dpi->x + (vehiclePreviewWidget->right - vehiclePreviewWidget->left) / 2; - y = dpi->y + vehiclePreviewWidget->bottom - vehiclePreviewWidget->top - 15; + x = (vehiclePreviewWidget->right - vehiclePreviewWidget->left) / 2; + y = vehiclePreviewWidget->bottom - vehiclePreviewWidget->top - 15; RCT2_CALLPROC_X(0x006DE4CD, (ride->num_cars_per_train << 8) | ride->subtype, (int)ride, x, y, (int)w, (int)dpi, 0); // ? @@ -4611,28 +4612,6 @@ enum { GRAPH_LATERAL }; -/** - * - * rct2: 0x006B66D9 - */ -rct_ride_measurement *ride_get_measurement(int rideIndex, rct_string_id *message) -{ - int eax, ebx, ecx, edx, esi, edi, ebp; - edx = rideIndex; - - RCT2_CALLFUNC_X(0x006B66D9, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - eax &= 0xFFFF; - - if ((eax & 0xFF) < 10) { - eax &= 0xFF; - return GET_RIDE_MEASUREMENT(eax); - } else { - if (message != NULL) - *message = eax; - return NULL; - } -} - /** * * rct2: 0x006AE8A6 @@ -4810,8 +4789,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;