2014-05-25 19:40:11 +02:00
|
|
|
/*****************************************************************************
|
|
|
|
* Copyright (c) 2014 Ted John
|
|
|
|
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
|
|
|
|
*
|
|
|
|
* This file is part of OpenRCT2.
|
|
|
|
*
|
|
|
|
* OpenRCT2 is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
2015-10-20 20:16:30 +02:00
|
|
|
|
2014-05-25 19:40:11 +02:00
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
2015-10-20 20:16:30 +02:00
|
|
|
|
2014-05-25 19:40:11 +02:00
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*****************************************************************************/
|
|
|
|
|
2014-10-06 18:36:58 +02:00
|
|
|
#include "../addresses.h"
|
|
|
|
#include "../audio/audio.h"
|
2014-10-07 20:10:16 +02:00
|
|
|
#include "../audio/mixer.h"
|
2015-07-15 00:38:56 +02:00
|
|
|
#include "../config.h"
|
2015-10-25 22:25:54 +01:00
|
|
|
#include "../hook.h"
|
2014-10-06 18:36:58 +02:00
|
|
|
#include "../interface/viewport.h"
|
2015-09-12 19:17:25 +02:00
|
|
|
#include "../openrct2.h"
|
2014-11-12 00:05:04 +01:00
|
|
|
#include "../scenario.h"
|
2014-10-06 18:36:58 +02:00
|
|
|
#include "../world/sprite.h"
|
2015-04-05 16:57:08 +02:00
|
|
|
#include "../world/scenery.h"
|
2015-04-05 13:36:02 +02:00
|
|
|
#include "track.h"
|
2014-09-13 19:51:58 +02:00
|
|
|
#include "ride.h"
|
2014-11-10 01:40:59 +01:00
|
|
|
#include "ride_data.h"
|
2015-09-12 19:17:25 +02:00
|
|
|
#include "track.h"
|
2014-05-25 19:40:11 +02:00
|
|
|
#include "vehicle.h"
|
|
|
|
|
|
|
|
static void vehicle_update(rct_vehicle *vehicle);
|
2014-11-12 02:32:20 +01:00
|
|
|
|
|
|
|
static void vehicle_D6_255_update_moving_to_end_of_station(rct_vehicle *vehicle);
|
|
|
|
static void vehicle_D6_255_update_waiting_to_depart(rct_vehicle *vehicle);
|
|
|
|
static void vehicle_D6_255_update_departing(rct_vehicle *vehicle);
|
|
|
|
static void vehicle_D6_255_update_travelling(rct_vehicle *vehicle);
|
|
|
|
static void vehicle_D6_255_update_arriving(rct_vehicle *vehicle);
|
|
|
|
|
|
|
|
static void vehicle_update_doing_circus_show(rct_vehicle *vehicle);
|
|
|
|
|
2014-11-12 00:05:04 +01:00
|
|
|
static void vehicle_update_sound(rct_vehicle *vehicle);
|
2014-11-12 02:04:50 +01:00
|
|
|
static int vehicle_update_scream_sound(rct_vehicle *vehicle);
|
|
|
|
|
|
|
|
#define NO_SCREAM 254
|
|
|
|
|
|
|
|
const uint8 byte_9A3A14[] = { SOUND_SCREAM_8, SOUND_SCREAM_1 };
|
|
|
|
const uint8 byte_9A3A16[] = { SOUND_SCREAM_1, SOUND_SCREAM_6 };
|
|
|
|
const uint8 byte_9A3A18[] = {
|
|
|
|
SOUND_SCREAM_3, SOUND_SCREAM_1, SOUND_SCREAM_5, SOUND_SCREAM_6,
|
|
|
|
SOUND_SCREAM_7, SOUND_SCREAM_2, SOUND_SCREAM_4, SOUND_LIFT_1
|
|
|
|
};
|
2014-05-25 19:40:11 +02:00
|
|
|
|
2014-09-13 19:51:58 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006BB9FF
|
|
|
|
*/
|
2014-10-07 04:21:55 +02:00
|
|
|
void vehicle_update_sound_params(rct_vehicle* vehicle)
|
2014-09-13 19:51:58 +02:00
|
|
|
{
|
2015-03-26 21:48:42 +01:00
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_SCENARIO_EDITOR) && (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_DESIGNER) || RCT2_GLOBAL(0x0141F570, uint8) == 6)) {
|
2014-10-07 04:21:55 +02:00
|
|
|
if (vehicle->sound1_id != (uint8)-1 || vehicle->sound2_id != (uint8)-1) {
|
2015-06-03 19:02:41 +02:00
|
|
|
if (vehicle->sprite_left != (sint16)0x8000) {
|
2014-11-10 18:23:13 +01:00
|
|
|
RCT2_GLOBAL(0x009AF5A0, sint16) = vehicle->sprite_left;
|
|
|
|
RCT2_GLOBAL(0x009AF5A2, sint16) = vehicle->sprite_top;
|
|
|
|
RCT2_GLOBAL(0x009AF5A4, sint16) = vehicle->sprite_right;
|
|
|
|
RCT2_GLOBAL(0x009AF5A6, sint16) = vehicle->sprite_bottom;
|
2014-09-13 19:51:58 +02:00
|
|
|
sint16 v4 = RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_x;
|
|
|
|
sint16 v5 = RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_y;
|
|
|
|
sint16 v6 = RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_width / 4;
|
|
|
|
sint16 v7 = RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_height / 4;
|
|
|
|
if (!RCT2_GLOBAL(0x00F438A8, rct_window*)->classification) {
|
|
|
|
v4 -= v6;
|
|
|
|
v5 -= v7;
|
|
|
|
}
|
2014-10-16 04:02:56 +02:00
|
|
|
if (v4 < RCT2_GLOBAL(0x009AF5A4, sint16) && v5 < RCT2_GLOBAL(0x009AF5A6, sint16)) {
|
2014-09-13 19:51:58 +02:00
|
|
|
sint16 t8 = RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_width + v4;
|
|
|
|
sint16 t9 = RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_height + v5;
|
|
|
|
if (!RCT2_GLOBAL(0x00F438A8, rct_window*)->classification) {
|
|
|
|
t8 += v6 + v6;
|
|
|
|
t9 += v7 + v7;
|
|
|
|
}
|
2014-10-16 04:02:56 +02:00
|
|
|
if (t8 >= RCT2_GLOBAL(0x009AF5A0, sint16) && t9 >= RCT2_GLOBAL(0x009AF5A2, sint16)) {
|
2014-09-13 19:51:58 +02:00
|
|
|
uint16 v9 = sub_6BC2F3(vehicle);
|
2014-10-07 04:21:55 +02:00
|
|
|
rct_vehicle_sound_params* i;
|
|
|
|
for (i = &gVehicleSoundParamsList[0]; i < gVehicleSoundParamsListEnd && v9 <= i->var_A; i++);
|
|
|
|
if (i < &gVehicleSoundParamsList[countof(gVehicleSoundParamsList)]) {
|
|
|
|
if (gVehicleSoundParamsListEnd < &gVehicleSoundParamsList[countof(gVehicleSoundParamsList)]) {
|
|
|
|
gVehicleSoundParamsListEnd++;
|
2014-09-13 19:51:58 +02:00
|
|
|
}
|
2014-10-07 04:21:55 +02:00
|
|
|
rct_vehicle_sound_params* j = gVehicleSoundParamsListEnd - 1;
|
2014-09-13 19:51:58 +02:00
|
|
|
while (j >= i) {
|
|
|
|
j--;
|
2014-09-15 23:12:25 +02:00
|
|
|
*(j + 1) = *j;
|
2014-09-13 19:51:58 +02:00
|
|
|
}
|
2014-09-22 20:35:47 +02:00
|
|
|
i->var_A = v9;
|
2015-11-16 23:39:40 +01:00
|
|
|
int pan_x = (RCT2_GLOBAL(0x009AF5A0, sint16) / 2) + (RCT2_GLOBAL(0x009AF5A4, sint16) / 2) - RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_x;
|
|
|
|
pan_x >>= RCT2_GLOBAL(0x00F438A4, rct_viewport*)->zoom;
|
|
|
|
pan_x += RCT2_GLOBAL(0x00F438A4, rct_viewport*)->x;
|
2014-09-13 19:51:58 +02:00
|
|
|
|
2014-10-16 04:02:56 +02:00
|
|
|
uint16 screenwidth = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16);
|
|
|
|
if (screenwidth < 64) {
|
|
|
|
screenwidth = 64;
|
2014-09-13 19:51:58 +02:00
|
|
|
}
|
2015-11-16 23:39:40 +01:00
|
|
|
i->pan_x = ((((pan_x << 16) / screenwidth) - 0x8000) >> 4);
|
2014-09-13 19:51:58 +02:00
|
|
|
|
2015-11-16 23:39:40 +01:00
|
|
|
int pan_y = (RCT2_GLOBAL(0x009AF5A2, sint16) / 2) + (RCT2_GLOBAL(0x009AF5A6, sint16) / 2) - RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_y;
|
|
|
|
pan_y >>= RCT2_GLOBAL(0x00F438A4, rct_viewport*)->zoom;
|
|
|
|
pan_y += RCT2_GLOBAL(0x00F438A4, rct_viewport*)->y;
|
2014-10-16 04:02:56 +02:00
|
|
|
|
|
|
|
uint16 screenheight = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16);
|
|
|
|
if (screenheight < 64) {
|
|
|
|
screenheight = 64;
|
2014-09-13 19:51:58 +02:00
|
|
|
}
|
2015-11-16 23:39:40 +01:00
|
|
|
i->pan_y = ((((pan_y << 16) / screenheight) - 0x8000) >> 4);
|
2014-10-16 04:02:56 +02:00
|
|
|
|
2014-09-19 23:17:14 +02:00
|
|
|
sint32 v19 = vehicle->velocity;
|
2014-09-13 19:51:58 +02:00
|
|
|
|
2015-03-21 12:11:06 +01:00
|
|
|
rct_ride_type* ride_type = GET_RIDE_ENTRY(vehicle->ride_subtype);
|
2015-03-19 21:34:53 +01:00
|
|
|
uint8 test = ride_type->vehicles[vehicle->vehicle_type].var_5A;
|
2014-09-13 19:51:58 +02:00
|
|
|
|
|
|
|
if (test & 1) {
|
|
|
|
v19 *= 2;
|
|
|
|
}
|
|
|
|
if (v19 < 0) {
|
|
|
|
v19 = -v19;
|
|
|
|
}
|
|
|
|
v19 >>= 5;
|
2014-10-07 04:21:55 +02:00
|
|
|
v19 *= 5512;
|
2014-09-13 19:51:58 +02:00
|
|
|
v19 >>= 14;
|
2014-10-07 04:21:55 +02:00
|
|
|
v19 += 11025;
|
2014-09-13 19:51:58 +02:00
|
|
|
v19 += 16 * vehicle->var_BF;
|
|
|
|
i->frequency = (uint16)v19;
|
|
|
|
i->id = vehicle->sprite_index;
|
2014-10-16 04:02:56 +02:00
|
|
|
i->volume = 0;
|
2015-06-03 19:02:41 +02:00
|
|
|
if (vehicle->x != (sint16)0x8000) {
|
2014-10-16 04:02:56 +02:00
|
|
|
int tile_idx = (((vehicle->y & 0xFFE0) * 256) + (vehicle->x & 0xFFE0)) / 32;
|
2014-09-13 19:51:58 +02:00
|
|
|
rct_map_element* map_element;
|
2014-10-16 04:02:56 +02:00
|
|
|
for (map_element = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; map_element->type & MAP_ELEMENT_TYPE_MASK; map_element++);
|
|
|
|
if (map_element->base_height * 8 > vehicle->z) { // vehicle underground
|
|
|
|
i->volume = 0x30;
|
2014-09-13 19:51:58 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006BC2F3
|
|
|
|
*/
|
|
|
|
int sub_6BC2F3(rct_vehicle* vehicle)
|
|
|
|
{
|
|
|
|
int result = 0;
|
|
|
|
rct_vehicle* vehicle_temp = vehicle;
|
|
|
|
do {
|
2015-10-25 17:00:21 +01:00
|
|
|
result += vehicle_temp->friction;
|
2014-09-13 19:51:58 +02:00
|
|
|
} while (vehicle_temp->next_vehicle_on_train != (uint16)-1 && (vehicle_temp = GET_VEHICLE(vehicle_temp->next_vehicle_on_train)));
|
2014-09-19 23:17:14 +02:00
|
|
|
sint32 v4 = vehicle->velocity;
|
2014-09-13 19:51:58 +02:00
|
|
|
if (v4 < 0) {
|
|
|
|
v4 = -v4;
|
|
|
|
}
|
|
|
|
result += ((uint16)v4) >> 13;
|
2014-10-16 04:02:56 +02:00
|
|
|
rct_vehicle_sound* vehicle_sound = &gVehicleSoundList[0];
|
2015-10-25 20:54:19 +01:00
|
|
|
|
2014-09-13 19:51:58 +02:00
|
|
|
while (vehicle_sound->id != vehicle->sprite_index) {
|
|
|
|
vehicle_sound++;
|
2015-10-25 20:54:19 +01:00
|
|
|
|
2014-10-07 04:21:55 +02:00
|
|
|
if (vehicle_sound >= &gVehicleSoundList[countof(gVehicleSoundList)]) {
|
2014-09-13 19:51:58 +02:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result + 300;
|
|
|
|
}
|
|
|
|
|
2014-09-15 23:12:25 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006BBC6B
|
|
|
|
*/
|
|
|
|
void vehicle_sounds_update()
|
|
|
|
{
|
2015-08-19 18:07:04 +02:00
|
|
|
if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, uint32) != -1 && !gGameSoundsOff && gConfigSound.sound && !gOpenRCT2Headless) {
|
2014-09-15 23:12:25 +02:00
|
|
|
RCT2_GLOBAL(0x00F438A4, rct_viewport*) = (rct_viewport*)-1;
|
|
|
|
rct_viewport* viewport = (rct_viewport*)-1;
|
2014-11-10 16:23:42 +01:00
|
|
|
rct_window* window = RCT2_GLOBAL(RCT2_ADDRESS_NEW_WINDOW_PTR, rct_window*);
|
|
|
|
while (1) {
|
|
|
|
window--;
|
|
|
|
if (window < RCT2_ADDRESS(RCT2_ADDRESS_WINDOW_LIST, rct_window)) {
|
|
|
|
break;
|
|
|
|
}
|
2014-09-15 23:12:25 +02:00
|
|
|
viewport = window->viewport;
|
|
|
|
if (viewport && viewport->flags & VIEWPORT_FLAG_SOUND_ON) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
RCT2_GLOBAL(0x00F438A4, rct_viewport*) = viewport;
|
|
|
|
if (viewport != (rct_viewport*)-1) {
|
|
|
|
if (window) {
|
|
|
|
RCT2_GLOBAL(0x00F438A8, rct_window*) = window;
|
2014-10-04 00:28:39 +02:00
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_VOLUME_ADJUST_ZOOM, uint8) = 0;
|
2014-09-15 23:12:25 +02:00
|
|
|
if (viewport->zoom) {
|
2014-10-04 00:28:39 +02:00
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_VOLUME_ADJUST_ZOOM, uint8) = 35;
|
2014-09-15 23:12:25 +02:00
|
|
|
if (viewport->zoom != 1) {
|
2014-10-04 00:28:39 +02:00
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_VOLUME_ADJUST_ZOOM, uint8) = 70;
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-10-07 04:21:55 +02:00
|
|
|
gVehicleSoundParamsListEnd = &gVehicleSoundParamsList[0];
|
2014-09-15 23:12:25 +02:00
|
|
|
for (uint16 i = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_VEHICLE, uint16); i != SPRITE_INDEX_NULL; i = g_sprite_list[i].vehicle.next) {
|
2014-10-07 04:21:55 +02:00
|
|
|
vehicle_update_sound_params(&g_sprite_list[i].vehicle);
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
2014-10-07 04:21:55 +02:00
|
|
|
for(int i = 0; i < countof(gVehicleSoundList); i++){
|
|
|
|
rct_vehicle_sound* vehicle_sound = &gVehicleSoundList[i];
|
2014-09-15 23:12:25 +02:00
|
|
|
if (vehicle_sound->id != (uint16)-1) {
|
2014-10-07 04:21:55 +02:00
|
|
|
for (rct_vehicle_sound_params* vehicle_sound_params = &gVehicleSoundParamsList[0]; vehicle_sound_params != gVehicleSoundParamsListEnd; vehicle_sound_params++) {
|
|
|
|
if (vehicle_sound->id == vehicle_sound_params->id) {
|
2014-09-15 23:12:25 +02:00
|
|
|
goto label26;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (vehicle_sound->sound1_id != (uint16)-1) {
|
2014-10-07 04:21:55 +02:00
|
|
|
Mixer_Stop_Channel(vehicle_sound->sound1_channel);
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
|
|
|
if (vehicle_sound->sound2_id != (uint16)-1) {
|
2014-10-07 04:21:55 +02:00
|
|
|
Mixer_Stop_Channel(vehicle_sound->sound2_channel);
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
|
|
|
vehicle_sound->id = (uint16)-1;
|
|
|
|
}
|
|
|
|
label26:
|
2015-04-12 23:26:15 +02:00
|
|
|
;
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
|
|
|
|
2014-10-07 04:21:55 +02:00
|
|
|
for (rct_vehicle_sound_params* vehicle_sound_params = &gVehicleSoundParamsList[0]; ; vehicle_sound_params++) {
|
2014-09-22 20:35:47 +02:00
|
|
|
label28:
|
2014-10-07 04:21:55 +02:00
|
|
|
if (vehicle_sound_params >= gVehicleSoundParamsListEnd) {
|
2014-09-22 20:35:47 +02:00
|
|
|
return;
|
|
|
|
}
|
2014-10-04 00:28:39 +02:00
|
|
|
uint8 vol1 = 0xFF;
|
|
|
|
uint8 vol2 = 0xFF;
|
2015-11-16 23:39:40 +01:00
|
|
|
sint16 pan_y = vehicle_sound_params->pan_y;
|
|
|
|
if (pan_y < 0) {
|
|
|
|
pan_y = -pan_y;
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
2015-11-16 23:39:40 +01:00
|
|
|
if (pan_y > 0xFFF) {
|
|
|
|
pan_y = 0xFFF;
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
2015-11-16 23:39:40 +01:00
|
|
|
pan_y -= 0x800;
|
|
|
|
if (pan_y > 0) {
|
|
|
|
pan_y -= 0x400;
|
|
|
|
pan_y = -pan_y;
|
|
|
|
pan_y = pan_y / 4;
|
|
|
|
vol1 = LOBYTE(pan_y);
|
|
|
|
if ((sint8)HIBYTE(pan_y) != 0) {
|
2014-10-04 00:28:39 +02:00
|
|
|
vol1 = 0xFF;
|
2015-11-16 23:39:40 +01:00
|
|
|
if ((sint8)HIBYTE(pan_y) < 0) {
|
2014-10-04 00:28:39 +02:00
|
|
|
vol1 = 0;
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-16 23:39:40 +01:00
|
|
|
sint16 pan_x = vehicle_sound_params->pan_x;
|
|
|
|
if (pan_x < 0) {
|
|
|
|
pan_x = -pan_x;
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
2015-11-16 23:39:40 +01:00
|
|
|
if (pan_x > 0xFFF) {
|
|
|
|
pan_x = 0xFFF;
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
2015-11-16 23:39:40 +01:00
|
|
|
pan_x -= 0x800;
|
|
|
|
if (pan_x > 0) {
|
|
|
|
pan_x -= 0x400;
|
|
|
|
pan_x = -pan_x;
|
|
|
|
pan_x = pan_x / 4;
|
|
|
|
vol2 = LOBYTE(pan_x);
|
|
|
|
if ((sint8)HIBYTE(pan_x) != 0) {
|
2014-10-04 00:28:39 +02:00
|
|
|
vol2 = 0xFF;
|
2015-11-16 23:39:40 +01:00
|
|
|
if ((sint8)HIBYTE(pan_x) < 0) {
|
2014-10-04 00:28:39 +02:00
|
|
|
vol2 = 0;
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-04 00:28:39 +02:00
|
|
|
if (vol1 >= vol2) {
|
|
|
|
vol1 = vol2;
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
2014-10-04 00:28:39 +02:00
|
|
|
if (vol1 < RCT2_GLOBAL(RCT2_ADDRESS_VOLUME_ADJUST_ZOOM, uint8)) {
|
|
|
|
vol1 = 0;
|
2014-09-19 04:48:04 +02:00
|
|
|
} else {
|
2014-10-04 00:28:39 +02:00
|
|
|
vol1 = vol1 - RCT2_GLOBAL(RCT2_ADDRESS_VOLUME_ADJUST_ZOOM, uint8);
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
|
|
|
|
2014-10-16 04:02:56 +02:00
|
|
|
rct_vehicle_sound* vehicle_sound = &gVehicleSoundList[0];
|
2014-10-07 04:21:55 +02:00
|
|
|
while (vehicle_sound_params->id != vehicle_sound->id) {
|
2015-10-16 10:25:56 +02:00
|
|
|
vehicle_sound++;
|
2014-10-07 04:21:55 +02:00
|
|
|
if (vehicle_sound >= &gVehicleSoundList[countof(gVehicleSoundList)]) {
|
2014-10-16 04:02:56 +02:00
|
|
|
vehicle_sound = &gVehicleSoundList[0];
|
2014-09-15 23:12:25 +02:00
|
|
|
int i = 0;
|
|
|
|
while (vehicle_sound->id != (uint16)-1) {
|
|
|
|
vehicle_sound++;
|
|
|
|
i++;
|
2015-10-16 10:25:56 +02:00
|
|
|
if (i >= countof(gVehicleSoundList)) {
|
2014-10-07 04:21:55 +02:00
|
|
|
vehicle_sound_params = (rct_vehicle_sound_params*)((int)vehicle_sound_params + 10);
|
2014-09-15 23:12:25 +02:00
|
|
|
goto label28;
|
|
|
|
}
|
|
|
|
}
|
2014-10-07 04:21:55 +02:00
|
|
|
vehicle_sound->id = vehicle_sound_params->id;
|
2014-09-15 23:12:25 +02:00
|
|
|
vehicle_sound->sound1_id = (uint16)-1;
|
|
|
|
vehicle_sound->sound2_id = (uint16)-1;
|
2014-10-16 04:02:56 +02:00
|
|
|
vehicle_sound->volume = 0x30;
|
2014-09-15 23:12:25 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-16 04:02:56 +02:00
|
|
|
int tempvolume = vehicle_sound->volume;
|
|
|
|
if (tempvolume != vehicle_sound_params->volume) {
|
|
|
|
if (tempvolume < vehicle_sound_params->volume) {
|
|
|
|
tempvolume += 4;
|
2014-09-15 23:12:25 +02:00
|
|
|
} else {
|
2014-10-16 04:02:56 +02:00
|
|
|
tempvolume -= 4;
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
|
|
|
}
|
2014-10-16 04:02:56 +02:00
|
|
|
vehicle_sound->volume = tempvolume;
|
|
|
|
if (vol1 < tempvolume) {
|
2014-10-04 00:28:39 +02:00
|
|
|
vol1 = 0;
|
2014-09-19 04:48:04 +02:00
|
|
|
} else {
|
2014-10-16 04:02:56 +02:00
|
|
|
vol1 = vol1 - tempvolume;
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
2014-10-16 04:02:56 +02:00
|
|
|
|
2014-09-15 23:12:25 +02:00
|
|
|
// do sound1 stuff, track noise
|
2014-10-07 04:21:55 +02:00
|
|
|
rct_sprite* sprite = &g_sprite_list[vehicle_sound_params->id];
|
2014-10-16 04:02:56 +02:00
|
|
|
int volume = sprite->vehicle.sound1_volume;
|
2014-10-04 00:28:39 +02:00
|
|
|
volume *= vol1;
|
2014-10-16 04:02:56 +02:00
|
|
|
volume = volume / 8;
|
2014-09-15 23:12:25 +02:00
|
|
|
volume -= 0x1FFF;
|
|
|
|
if (volume < -10000) {
|
|
|
|
volume = -10000;
|
|
|
|
}
|
2014-10-07 04:21:55 +02:00
|
|
|
if (sprite->vehicle.sound1_id == (uint8)-1) {
|
2014-09-15 23:12:25 +02:00
|
|
|
if (vehicle_sound->sound1_id != (uint16)-1) {
|
|
|
|
vehicle_sound->sound1_id = -1;
|
2015-10-20 20:16:30 +02:00
|
|
|
Mixer_Stop_Channel(vehicle_sound->sound1_channel);
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (vehicle_sound->sound1_id == (uint16)-1) {
|
|
|
|
goto label69;
|
|
|
|
}
|
2014-10-07 04:21:55 +02:00
|
|
|
if (sprite->vehicle.sound1_id != vehicle_sound->sound1_id) {
|
|
|
|
Mixer_Stop_Channel(vehicle_sound->sound1_channel);
|
2014-09-15 23:12:25 +02:00
|
|
|
label69:
|
2014-10-07 04:21:55 +02:00
|
|
|
vehicle_sound->sound1_id = sprite->vehicle.sound1_id;
|
2015-11-16 23:39:40 +01:00
|
|
|
vehicle_sound->sound1_pan = vehicle_sound_params->pan_x;
|
2014-09-15 23:12:25 +02:00
|
|
|
vehicle_sound->sound1_volume = volume;
|
2014-10-07 04:21:55 +02:00
|
|
|
vehicle_sound->sound1_freq = vehicle_sound_params->frequency;
|
|
|
|
uint16 frequency = vehicle_sound_params->frequency;
|
|
|
|
if (RCT2_ADDRESS(0x009AF51F, uint8)[2 * sprite->vehicle.sound1_id] & 2) {
|
2014-09-15 23:12:25 +02:00
|
|
|
frequency = (frequency / 2) + 4000;
|
|
|
|
}
|
2014-10-07 04:21:55 +02:00
|
|
|
uint8 looping = RCT2_ADDRESS(0x009AF51E, uint8)[2 * sprite->vehicle.sound1_id];
|
2015-11-16 23:39:40 +01:00
|
|
|
int pan = vehicle_sound_params->pan_x;
|
2014-10-08 07:00:11 +02:00
|
|
|
vehicle_sound->sound1_channel = Mixer_Play_Effect(sprite->vehicle.sound1_id, looping ? MIXER_LOOP_INFINITE : MIXER_LOOP_NONE, DStoMixerVolume(volume), DStoMixerPan(pan), DStoMixerRate(frequency), 0);
|
2014-09-15 23:12:25 +02:00
|
|
|
goto label87;
|
|
|
|
}
|
|
|
|
if (volume != vehicle_sound->sound1_volume) {
|
|
|
|
vehicle_sound->sound1_volume = volume;
|
2014-10-07 04:21:55 +02:00
|
|
|
Mixer_Channel_Volume(vehicle_sound->sound1_channel, DStoMixerVolume(volume));
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
2015-11-16 23:39:40 +01:00
|
|
|
if (vehicle_sound_params->pan_x != vehicle_sound->sound1_pan) {
|
|
|
|
vehicle_sound->sound1_pan = vehicle_sound_params->pan_x;
|
|
|
|
Mixer_Channel_Pan(vehicle_sound->sound1_channel, DStoMixerPan(vehicle_sound_params->pan_x));
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
2014-10-07 04:21:55 +02:00
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) & 3) && vehicle_sound_params->frequency != vehicle_sound->sound1_freq) {
|
|
|
|
vehicle_sound->sound1_freq = vehicle_sound_params->frequency;
|
|
|
|
uint16 frequency = vehicle_sound_params->frequency;
|
|
|
|
if (RCT2_GLOBAL(0x009AF51F, uint8*)[2 * sprite->vehicle.sound1_id] & 2) {
|
2014-09-15 23:12:25 +02:00
|
|
|
frequency = (frequency / 2) + 4000;
|
|
|
|
}
|
2014-10-07 04:21:55 +02:00
|
|
|
Mixer_Channel_Rate(vehicle_sound->sound1_channel, DStoMixerRate(frequency));
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
2014-09-17 21:44:29 +02:00
|
|
|
}
|
|
|
|
label87: // do sound2 stuff, screams
|
2014-10-07 04:21:55 +02:00
|
|
|
sprite = &g_sprite_list[vehicle_sound_params->id];
|
|
|
|
volume = sprite->vehicle.sound2_volume;
|
2014-10-04 00:28:39 +02:00
|
|
|
volume *= vol1;
|
2014-09-17 21:44:29 +02:00
|
|
|
volume = (uint16)volume / 8;
|
|
|
|
volume -= 0x1FFF;
|
|
|
|
if (volume < -10000) {
|
|
|
|
volume = -10000;
|
|
|
|
}
|
2014-10-07 04:21:55 +02:00
|
|
|
if (sprite->vehicle.sound2_id == (uint8)-1) {
|
2014-09-17 21:44:29 +02:00
|
|
|
if (vehicle_sound->sound2_id != (uint16)-1) {
|
|
|
|
vehicle_sound->sound2_id = -1;
|
2014-10-07 04:21:55 +02:00
|
|
|
Mixer_Stop_Channel(vehicle_sound->sound2_channel);
|
2014-09-17 21:44:29 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (vehicle_sound->sound2_id == (uint16)-1) {
|
|
|
|
goto label93;
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
2014-10-07 04:21:55 +02:00
|
|
|
if (sprite->vehicle.sound2_id != vehicle_sound->sound2_id) {
|
|
|
|
Mixer_Stop_Channel(vehicle_sound->sound2_channel);
|
2014-09-17 21:44:29 +02:00
|
|
|
label93:
|
2014-10-07 04:21:55 +02:00
|
|
|
vehicle_sound->sound2_id = sprite->vehicle.sound2_id;
|
2015-11-16 23:39:40 +01:00
|
|
|
vehicle_sound->sound2_pan = vehicle_sound_params->pan_x;
|
2014-09-17 21:44:29 +02:00
|
|
|
vehicle_sound->sound2_volume = volume;
|
2014-10-07 04:21:55 +02:00
|
|
|
vehicle_sound->sound2_freq = vehicle_sound_params->frequency;
|
|
|
|
uint16 frequency = vehicle_sound_params->frequency;
|
|
|
|
if (RCT2_ADDRESS(0x009AF51F, uint8)[2 * sprite->vehicle.sound2_id] & 1) {
|
2014-09-17 21:44:29 +02:00
|
|
|
frequency = 12649;
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
2014-09-17 21:44:29 +02:00
|
|
|
frequency = (frequency * 2) - 3248;
|
|
|
|
if (frequency > 25700) {
|
|
|
|
frequency = 25700;
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
2014-10-07 04:21:55 +02:00
|
|
|
uint8 looping = RCT2_ADDRESS(0x009AF51E, uint8)[2 * sprite->vehicle.sound2_id];
|
2015-11-16 23:39:40 +01:00
|
|
|
int pan = vehicle_sound_params->pan_x;
|
2014-10-08 07:00:11 +02:00
|
|
|
vehicle_sound->sound2_channel = Mixer_Play_Effect(sprite->vehicle.sound2_id, looping ? MIXER_LOOP_INFINITE : MIXER_LOOP_NONE, DStoMixerVolume(volume), DStoMixerPan(pan), DStoMixerRate(frequency), 0);
|
2014-09-17 21:44:29 +02:00
|
|
|
goto label114;
|
|
|
|
}
|
|
|
|
if (volume != vehicle_sound->sound2_volume) {
|
2014-10-07 04:21:55 +02:00
|
|
|
Mixer_Channel_Volume(vehicle_sound->sound2_channel, DStoMixerVolume(volume));
|
|
|
|
vehicle_sound->sound2_volume = volume;
|
2014-09-17 21:44:29 +02:00
|
|
|
}
|
2015-11-16 23:39:40 +01:00
|
|
|
if (vehicle_sound_params->pan_x != vehicle_sound->sound2_pan) {
|
|
|
|
vehicle_sound->sound2_pan = vehicle_sound_params->pan_x;
|
|
|
|
Mixer_Channel_Pan(vehicle_sound->sound2_channel, DStoMixerPan(vehicle_sound_params->pan_x));
|
2014-09-17 21:44:29 +02:00
|
|
|
}
|
2014-10-07 04:21:55 +02:00
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) & 3) && vehicle_sound_params->frequency != vehicle_sound->sound2_freq) {
|
|
|
|
vehicle_sound->sound2_freq = vehicle_sound_params->frequency;
|
|
|
|
if (!(RCT2_ADDRESS(0x009AF51F, uint8)[2 * sprite->vehicle.sound2_id] & 1)) {
|
|
|
|
uint16 frequency = (vehicle_sound_params->frequency * 2) - 3248;
|
2014-09-15 23:12:25 +02:00
|
|
|
if (frequency > 25700) {
|
|
|
|
frequency = 25700;
|
|
|
|
}
|
2014-10-07 04:21:55 +02:00
|
|
|
Mixer_Channel_Rate(vehicle_sound->sound2_channel, DStoMixerRate(frequency));
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-09-17 21:44:29 +02:00
|
|
|
label114:
|
2015-04-12 23:26:15 +02:00
|
|
|
;
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-25 19:40:11 +02:00
|
|
|
/**
|
2015-10-20 20:16:30 +02:00
|
|
|
*
|
2014-05-25 19:40:11 +02:00
|
|
|
* rct2: 0x006D4204
|
|
|
|
*/
|
|
|
|
void vehicle_update_all()
|
|
|
|
{
|
|
|
|
uint16 sprite_index;
|
|
|
|
rct_vehicle *vehicle;
|
|
|
|
|
2015-03-26 21:48:42 +01:00
|
|
|
if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_SCENARIO_EDITOR)
|
2014-05-25 19:40:11 +02:00
|
|
|
return;
|
|
|
|
|
2015-03-26 21:48:42 +01:00
|
|
|
if ((RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_DESIGNER) && RCT2_GLOBAL(0x0141F570, uint8) != 6)
|
2014-05-25 19:40:11 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
sprite_index = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_VEHICLE, uint16);
|
|
|
|
while (sprite_index != SPRITE_INDEX_NULL) {
|
2014-06-29 15:51:18 +02:00
|
|
|
vehicle = &(g_sprite_list[sprite_index].vehicle);
|
2014-05-25 19:40:11 +02:00
|
|
|
sprite_index = vehicle->next;
|
|
|
|
|
|
|
|
vehicle_update(vehicle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-05 16:57:08 +02:00
|
|
|
/* rct2: 0x006D6D1F */
|
|
|
|
static void vehicle_update_measurements(rct_vehicle *vehicle)
|
2014-11-12 00:05:04 +01:00
|
|
|
{
|
|
|
|
rct_ride *ride;
|
|
|
|
|
|
|
|
ride = GET_RIDE(vehicle->ride);
|
2015-04-05 16:57:08 +02:00
|
|
|
//RCT2_CALLPROC_X(0x006D6D1F, 0, 0, 0, 0, (int)vehicle, (int)vehicle->ride, 0);
|
|
|
|
//return;
|
2015-04-05 10:38:37 +02:00
|
|
|
|
|
|
|
if (vehicle->status == VEHICLE_STATUS_TRAVELLING_07){
|
|
|
|
ride->lifecycle_flags |= RIDE_LIFECYCLE_TESTED;
|
|
|
|
ride->lifecycle_flags |= RIDE_LIFECYCLE_NO_RAW_STATS;
|
|
|
|
ride->lifecycle_flags &= ~RIDE_LIFECYCLE_TEST_IN_PROGRESS;
|
|
|
|
vehicle->var_48 &= ~(1 << 1);
|
|
|
|
window_invalidate_by_number(WC_RIDE, vehicle->ride);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8 entrance = ride->var_1F6;
|
|
|
|
if (ride->entrances[entrance] != 0xFFFF){
|
|
|
|
|
|
|
|
//ecx
|
|
|
|
uint8 var_E0 = ride->var_0E0;
|
|
|
|
|
|
|
|
ride->var_0E1++;
|
|
|
|
if (ride->var_0E1 >= 32)ride->var_0E1 = 0;
|
|
|
|
|
|
|
|
sint32 velocity = abs(vehicle->velocity);
|
|
|
|
if (velocity > ride->max_speed){
|
|
|
|
ride->max_speed = velocity;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ride->var_0E1 == 0 && velocity > 0x8000){
|
|
|
|
ride->average_speed += velocity;
|
|
|
|
ride->time[var_E0]++;
|
|
|
|
}
|
|
|
|
|
|
|
|
sint32 distance = abs(((vehicle->velocity + vehicle->var_2C) / 1024) * 42);
|
2015-04-05 16:57:08 +02:00
|
|
|
if (vehicle->var_CE == 0){
|
2015-04-05 10:38:37 +02:00
|
|
|
ride->length[var_E0] += distance;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (RCT2_ADDRESS(RCT2_ADDRESS_RIDE_FLAGS, uint32)[ride->type * 2] & RIDE_TYPE_FLAG_HAS_G_FORCES){
|
|
|
|
int vertical_g, lateral_g;
|
|
|
|
vehicle_get_g_forces(vehicle, &vertical_g, &lateral_g);
|
|
|
|
|
|
|
|
vertical_g += ride->previous_vertical_g;
|
|
|
|
lateral_g += ride->previous_lateral_g;
|
|
|
|
vertical_g /= 2;
|
|
|
|
lateral_g /= 2;
|
|
|
|
|
|
|
|
ride->previous_vertical_g = vertical_g;
|
|
|
|
ride->previous_lateral_g = lateral_g;
|
|
|
|
|
|
|
|
if (vertical_g <= 0){
|
|
|
|
ride->total_air_time++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vertical_g > ride->max_positive_vertical_g)
|
|
|
|
ride->max_positive_vertical_g = vertical_g;
|
|
|
|
|
|
|
|
if (vertical_g < ride->max_negative_vertical_g)
|
|
|
|
ride->max_negative_vertical_g = vertical_g;
|
|
|
|
|
|
|
|
lateral_g = abs(lateral_g);
|
|
|
|
|
|
|
|
if (lateral_g > ride->max_lateral_g)
|
|
|
|
ride->max_lateral_g = lateral_g;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16 map_location = (vehicle->var_38 / 32) | ((vehicle->var_3A / 32) << 8);
|
2015-04-05 16:57:08 +02:00
|
|
|
if (vehicle->var_3C / 8 != ride->var_11F || map_location != ride->var_10C){
|
2015-04-05 10:38:37 +02:00
|
|
|
ride->var_11F = vehicle->var_3C / 8;
|
|
|
|
ride->var_10C = map_location;
|
|
|
|
|
2015-04-05 19:28:42 +02:00
|
|
|
if (ride->entrances[ride->var_1F6] == 0xFFFF)
|
|
|
|
return;
|
|
|
|
|
|
|
|
uint16 track_elem_type = vehicle->track_type / 4;
|
|
|
|
if (track_elem_type == TRACK_ELEM_POWERED_LIFT || !(vehicle->var_48 & (1 << 0))){
|
|
|
|
if (!(ride->var_108 & (1 << 6))){
|
|
|
|
ride->var_108 |= (1 << 6);
|
|
|
|
if (ride->drops + 64 < 0xFF){
|
|
|
|
ride->drops += 64;
|
2015-04-05 13:36:02 +02:00
|
|
|
}
|
|
|
|
}
|
2015-04-05 19:28:42 +02:00
|
|
|
}
|
|
|
|
else{
|
|
|
|
ride->var_108 &= ~(1 << 6);
|
|
|
|
}
|
2015-04-05 13:36:02 +02:00
|
|
|
|
2015-04-05 19:28:42 +02:00
|
|
|
if (ride->type == RIDE_TYPE_WATER_COASTER){
|
|
|
|
if (track_elem_type >= TRACK_ELEM_FLAT_COVERED && track_elem_type <= TRACK_ELEM_RIGHT_QUARTER_TURN_3_TILES_COVERED){
|
2015-04-05 16:57:08 +02:00
|
|
|
ride->special_track_elements |= RIDE_ELEMENT_TUNNEL_SPLASH_OR_RAPIDS;
|
2015-04-05 10:38:37 +02:00
|
|
|
}
|
2015-04-05 19:28:42 +02:00
|
|
|
}
|
2015-04-05 10:38:37 +02:00
|
|
|
|
2015-04-05 19:28:42 +02:00
|
|
|
switch (track_elem_type)
|
|
|
|
{
|
|
|
|
case TRACK_ELEM_RAPIDS:
|
|
|
|
case TRACK_ELEM_SPINNING_TUNNEL:
|
|
|
|
ride->special_track_elements |= RIDE_ELEMENT_TUNNEL_SPLASH_OR_RAPIDS;
|
|
|
|
break;
|
|
|
|
case TRACK_ELEM_WATERFALL:
|
|
|
|
case TRACK_ELEM_LOG_FLUME_REVERSER:
|
|
|
|
ride->special_track_elements |= RIDE_ELEMENT_REVERSER_OR_WATERFALL;
|
|
|
|
break;
|
|
|
|
case TRACK_ELEM_WHIRLPOOL:
|
|
|
|
ride->special_track_elements |= RIDE_ELEMENT_WHIRLPOOL;
|
|
|
|
break;
|
|
|
|
case TRACK_ELEM_WATER_SPLASH:
|
|
|
|
if (vehicle->velocity >= 0xB0000){
|
|
|
|
ride->special_track_elements |= RIDE_ELEMENT_TUNNEL_SPLASH_OR_RAPIDS;
|
2015-04-05 13:36:02 +02:00
|
|
|
}
|
2015-04-05 19:28:42 +02:00
|
|
|
}
|
2015-04-05 13:36:02 +02:00
|
|
|
|
2015-04-05 19:28:42 +02:00
|
|
|
// ax
|
|
|
|
uint16 track_flags = RCT2_ADDRESS(0x0099423C, uint16)[track_elem_type];
|
2015-04-05 13:36:02 +02:00
|
|
|
|
2015-04-05 19:28:42 +02:00
|
|
|
uint32 var_108 = ride->var_108;
|
|
|
|
if (var_108 & (1 << 1) && track_flags & TRACK_ELEM_FLAG_TURN_LEFT){
|
|
|
|
ride->var_10E += 0x800;
|
|
|
|
}
|
|
|
|
else if (var_108 & (1 << 2) && track_flags & TRACK_ELEM_FLAG_TURN_RIGHT){
|
|
|
|
ride->var_10E += 0x800;
|
|
|
|
}
|
|
|
|
else if (var_108 & (1 << 2) || var_108 & (1 << 1)){
|
|
|
|
ride->var_108 &= ~(0x6);
|
|
|
|
ride->var_108 &= ~(0x18);
|
|
|
|
|
|
|
|
uint16* ebp = &ride->var_110;
|
|
|
|
if (!(var_108 & (1 << 3))){
|
|
|
|
ebp = &ride->var_112;
|
|
|
|
if (!(var_108 & (1 << 4))){
|
|
|
|
ebp = &ride->var_10E;
|
2015-04-05 13:36:02 +02:00
|
|
|
}
|
|
|
|
}
|
2015-04-05 19:28:42 +02:00
|
|
|
uint16 bx;
|
|
|
|
switch (ride->var_10E >> 11){
|
|
|
|
case 0:
|
|
|
|
bx = *ebp & 0x1F;
|
|
|
|
if (bx != 0x1F){
|
|
|
|
bx++;
|
2015-04-05 13:36:02 +02:00
|
|
|
}
|
2015-04-05 19:28:42 +02:00
|
|
|
*ebp &= 0xFFE0;
|
|
|
|
*ebp |= bx;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
bx = *ebp & 0xE0;
|
|
|
|
if (bx != 0xE0){
|
|
|
|
bx += 0x20;
|
|
|
|
}
|
|
|
|
*ebp &= 0xFF1F;
|
|
|
|
*ebp |= bx;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (var_108&(1 << 4)){
|
|
|
|
bx = *ebp & 0xF800;
|
|
|
|
if (bx != 0xF800){
|
|
|
|
bx += 0x800;
|
2015-04-05 13:36:02 +02:00
|
|
|
}
|
2015-04-05 19:28:42 +02:00
|
|
|
*ebp &= 0x7FF;
|
2015-04-05 13:36:02 +02:00
|
|
|
*ebp |= bx;
|
|
|
|
break;
|
|
|
|
}
|
2015-04-05 19:28:42 +02:00
|
|
|
// fall through to case 2
|
|
|
|
case 2:
|
|
|
|
bx = *ebp & 0x700;
|
|
|
|
if (bx != 0x700){
|
|
|
|
bx += 0x100;
|
2015-04-05 16:57:08 +02:00
|
|
|
}
|
2015-04-05 19:28:42 +02:00
|
|
|
*ebp &= 0xF8FF;
|
|
|
|
*ebp |= bx;
|
|
|
|
break;
|
2015-04-05 16:57:08 +02:00
|
|
|
}
|
2015-04-05 19:28:42 +02:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (track_flags & TRACK_ELEM_FLAG_TURN_LEFT){
|
|
|
|
ride->var_108 |= (1 << 1);
|
|
|
|
ride->var_10E &= 0x7FF;
|
2015-04-05 16:57:08 +02:00
|
|
|
|
2015-04-05 19:28:42 +02:00
|
|
|
if (track_flags & TRACK_ELEM_FLAG_TURN_BANKED){
|
|
|
|
ride->var_108 |= (1 << 3);
|
|
|
|
}
|
|
|
|
if (track_flags & TRACK_ELEM_FLAG_TURN_SLOPED){
|
|
|
|
ride->var_108 |= (1 << 4);
|
|
|
|
}
|
2015-04-05 16:57:08 +02:00
|
|
|
}
|
|
|
|
|
2015-04-05 19:28:42 +02:00
|
|
|
if (track_flags & TRACK_ELEM_FLAG_TURN_RIGHT){
|
|
|
|
ride->var_108 |= (1 << 2);
|
|
|
|
ride->var_10E &= 0x7FF;
|
2015-04-05 16:57:08 +02:00
|
|
|
|
2015-04-05 19:28:42 +02:00
|
|
|
if (track_flags & TRACK_ELEM_FLAG_TURN_BANKED){
|
|
|
|
ride->var_108 |= (1 << 3);
|
|
|
|
}
|
|
|
|
if (track_flags & TRACK_ELEM_FLAG_TURN_SLOPED){
|
|
|
|
ride->var_108 |= (1 << 4);
|
2015-04-05 16:57:08 +02:00
|
|
|
}
|
|
|
|
}
|
2015-04-05 19:28:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (var_108 & (1 << 5)){
|
|
|
|
if (vehicle->velocity < 0 || !(track_flags & TRACK_ELEM_FLAG_DOWN)){
|
2015-04-05 16:57:08 +02:00
|
|
|
ride->var_108 &= ~(1 << 5);
|
|
|
|
|
2015-04-05 19:28:42 +02:00
|
|
|
sint16 z = vehicle->z / 8 - ride->start_drop_height;
|
|
|
|
if (z < 0){
|
|
|
|
z = abs(z);
|
|
|
|
if (z > ride->highest_drop_height){
|
|
|
|
ride->highest_drop_height = (uint8)z;
|
|
|
|
}
|
|
|
|
}
|
2015-04-05 16:57:08 +02:00
|
|
|
}
|
2015-04-05 19:28:42 +02:00
|
|
|
}
|
|
|
|
else if (track_flags & TRACK_ELEM_FLAG_DOWN && vehicle->velocity >= 0){
|
|
|
|
ride->var_108 &= ~(1 << 7);
|
|
|
|
ride->var_108 |= (1 << 5);
|
|
|
|
|
|
|
|
uint8 drops = ride->drops & 0x3F;
|
|
|
|
if (drops != 0x3F)
|
|
|
|
drops++;
|
|
|
|
ride->drops &= ~0x3F;
|
|
|
|
ride->drops |= drops;
|
|
|
|
|
|
|
|
ride->start_drop_height = vehicle->z / 8;
|
|
|
|
var_108 &= ~(1 << 7);
|
|
|
|
}
|
2015-04-05 16:57:08 +02:00
|
|
|
|
2015-04-05 19:28:42 +02:00
|
|
|
if (var_108 & (1 << 7)){
|
|
|
|
if (vehicle->velocity > 0 || !(track_flags & TRACK_ELEM_FLAG_UP)){
|
|
|
|
ride->var_108 &= ~(1 << 7);
|
2015-04-05 16:57:08 +02:00
|
|
|
|
2015-04-05 19:28:42 +02:00
|
|
|
sint16 z = vehicle->z / 8 - ride->start_drop_height;
|
|
|
|
if (z < 0){
|
|
|
|
z = abs(z);
|
|
|
|
if (z > ride->highest_drop_height){
|
|
|
|
ride->highest_drop_height = (uint8)z;
|
|
|
|
}
|
|
|
|
}
|
2015-04-05 16:57:08 +02:00
|
|
|
}
|
2015-04-05 19:28:42 +02:00
|
|
|
}
|
|
|
|
else if (track_flags & TRACK_ELEM_FLAG_UP && vehicle->velocity <= 0){
|
|
|
|
ride->var_108 &= ~(1 << 5);
|
|
|
|
ride->var_108 |= (1 << 7);
|
|
|
|
|
|
|
|
uint8 drops = ride->drops & 0x3F;
|
|
|
|
if (drops != 0x3F)
|
|
|
|
drops++;
|
|
|
|
ride->drops &= ~0x3F;
|
|
|
|
ride->drops |= drops;
|
|
|
|
|
|
|
|
ride->start_drop_height = vehicle->z / 8;
|
|
|
|
var_108 &= ~(1 << 7);
|
|
|
|
}
|
2015-04-05 16:57:08 +02:00
|
|
|
|
2015-04-05 19:28:42 +02:00
|
|
|
if (track_flags & TRACK_ELEM_FLAG_INVERSION){
|
|
|
|
uint8 inversions = ride->inversions & 0x1F;
|
|
|
|
if (inversions != 0x1F)
|
|
|
|
inversions++;
|
2015-04-05 16:57:08 +02:00
|
|
|
|
2015-04-05 19:28:42 +02:00
|
|
|
ride->inversions &= ~0x1F;
|
|
|
|
ride->inversions |= inversions;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (track_flags & TRACK_ELEM_FLAG_HELIX){
|
|
|
|
uint8 helixes = ride_get_helix_sections(ride);
|
|
|
|
if (helixes != 0x1F)
|
|
|
|
helixes++;
|
|
|
|
|
|
|
|
ride->special_track_elements &= ~0x1F;
|
|
|
|
ride->special_track_elements |= helixes;
|
2015-04-05 10:38:37 +02:00
|
|
|
}
|
2015-04-05 19:28:42 +02:00
|
|
|
|
2015-04-05 10:38:37 +02:00
|
|
|
}
|
2015-04-05 16:57:08 +02:00
|
|
|
|
|
|
|
if (ride->entrances[ride->var_1F6] == 0xFFFF)
|
|
|
|
return;
|
|
|
|
|
|
|
|
sint16 x, y;
|
|
|
|
x = vehicle->x;
|
|
|
|
y = vehicle->y;
|
|
|
|
|
|
|
|
if (x == SPRITE_LOCATION_NULL){
|
|
|
|
ride->var_108 &= (1 << 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
rct_map_element* map_element = map_get_surface_element_at(x / 32, y / 32);
|
|
|
|
if (map_element->base_height * 8 > vehicle->z){
|
|
|
|
|
|
|
|
for (;; map_element++){
|
|
|
|
if (map_element_is_last_for_tile(map_element)){
|
|
|
|
ride->var_108 &= (1 << 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (map_element_get_type(map_element) == MAP_ELEMENT_TYPE_SCENERY_MULTIPLE)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (map_element_get_type(map_element) == MAP_ELEMENT_TYPE_PATH)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (map_element_get_type(map_element) != MAP_ELEMENT_TYPE_SCENERY)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
rct_scenery_entry* scenery = (rct_scenery_entry*)object_entry_groups[OBJECT_TYPE_SMALL_SCENERY].chunks[map_element->properties.scenery.type];
|
|
|
|
if (scenery->small_scenery.flags & SMALL_SCENERY_FLAG_FULL_TILE)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(ride->var_108 & (1 << 0))){
|
|
|
|
ride->var_108 |= (1 << 0);
|
|
|
|
|
|
|
|
uint8 num_sheltered_sections = ride->num_sheltered_sections & 0x1F;
|
|
|
|
if (num_sheltered_sections != 0x1F)
|
|
|
|
num_sheltered_sections++;
|
|
|
|
ride->num_sheltered_sections &= ~0x1F;
|
|
|
|
ride->num_sheltered_sections |= num_sheltered_sections;
|
|
|
|
|
|
|
|
if (vehicle->var_1F != 0){
|
|
|
|
ride->num_sheltered_sections |= (1 << 5);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vehicle->var_20 != 0){
|
|
|
|
ride->num_sheltered_sections |= (1 << 6);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sint32 distance = ((vehicle->velocity + vehicle->var_2C) / 1024) * 42;
|
|
|
|
if (distance < 0)return;
|
|
|
|
|
|
|
|
ride->sheltered_length += distance;
|
2014-11-12 00:05:04 +01:00
|
|
|
}
|
|
|
|
|
2014-11-12 02:04:50 +01:00
|
|
|
static uint16 sub_6D7AC0(int currentSoundId, int currentVolume, int targetSoundId, int targetVolume)
|
2014-11-12 00:05:04 +01:00
|
|
|
{
|
2014-11-12 02:04:50 +01:00
|
|
|
if (currentSoundId != 255) {
|
|
|
|
if (currentSoundId == targetSoundId) {
|
|
|
|
currentVolume = min(currentVolume + 15, targetVolume);
|
|
|
|
return (currentVolume << 8) | currentSoundId;
|
2014-11-12 00:05:04 +01:00
|
|
|
} else {
|
2014-11-12 02:04:50 +01:00
|
|
|
currentVolume -= 9;
|
|
|
|
if (currentVolume >= 80)
|
|
|
|
return (currentVolume << 8) | currentSoundId;
|
2014-11-12 00:05:04 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-12 02:04:50 +01:00
|
|
|
// Begin sound at quarter volume
|
|
|
|
currentSoundId = targetSoundId;
|
|
|
|
currentVolume = targetVolume == 255 ? 255 : targetVolume / 4;
|
2014-11-12 00:05:04 +01:00
|
|
|
|
2014-11-12 02:04:50 +01:00
|
|
|
return (currentVolume << 8) | currentSoundId;
|
2014-11-12 00:05:04 +01:00
|
|
|
}
|
|
|
|
|
2014-05-25 19:40:11 +02:00
|
|
|
/**
|
2015-10-20 20:16:30 +02:00
|
|
|
*
|
2014-05-25 19:40:11 +02:00
|
|
|
* rct2: 0x006D77F2
|
|
|
|
*/
|
|
|
|
static void vehicle_update(rct_vehicle *vehicle)
|
|
|
|
{
|
2014-11-12 00:05:04 +01:00
|
|
|
// RCT2_CALLPROC_X(0x006D77F2, 0, 0, 0, 0, (int)vehicle, 0, 0);
|
|
|
|
|
|
|
|
rct_ride *ride;
|
|
|
|
rct_ride_type *rideEntry;
|
|
|
|
|
|
|
|
if (vehicle->ride_subtype == 255) {
|
|
|
|
switch (vehicle->status) {
|
|
|
|
case VEHICLE_STATUS_MOVING_TO_END_OF_STATION:
|
2014-11-12 02:32:20 +01:00
|
|
|
vehicle_D6_255_update_moving_to_end_of_station(vehicle);
|
2014-11-12 00:05:04 +01:00
|
|
|
break;
|
|
|
|
case VEHICLE_STATUS_WAITING_TO_DEPART:
|
2014-11-12 02:32:20 +01:00
|
|
|
vehicle_D6_255_update_waiting_to_depart(vehicle);
|
2014-11-12 00:05:04 +01:00
|
|
|
break;
|
|
|
|
case VEHICLE_STATUS_DEPARTING:
|
2014-11-12 02:32:20 +01:00
|
|
|
vehicle_D6_255_update_departing(vehicle);
|
2014-11-12 00:05:04 +01:00
|
|
|
break;
|
|
|
|
case VEHICLE_STATUS_TRAVELLING:
|
2014-11-12 02:32:20 +01:00
|
|
|
vehicle_D6_255_update_travelling(vehicle);
|
2014-11-12 00:05:04 +01:00
|
|
|
break;
|
|
|
|
case VEHICLE_STATUS_ARRIVING:
|
2014-11-12 02:32:20 +01:00
|
|
|
vehicle_D6_255_update_arriving(vehicle);
|
2014-11-12 00:05:04 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
rideEntry = GET_RIDE_ENTRY(vehicle->ride_subtype);
|
|
|
|
|
|
|
|
rct_ride_type_vehicle* vehicleEntry = &rideEntry->vehicles[vehicle->vehicle_type];
|
|
|
|
|
|
|
|
ride = GET_RIDE(vehicle->ride);
|
|
|
|
if (vehicle->var_48 & 0x20)
|
2015-04-05 16:57:08 +02:00
|
|
|
vehicle_update_measurements(vehicle);
|
2014-11-12 00:05:04 +01:00
|
|
|
|
|
|
|
RCT2_GLOBAL(0x00F64E34, uint8) = 255;
|
|
|
|
if (ride->lifecycle_flags & (RIDE_LIFECYCLE_BREAKDOWN_PENDING | RIDE_LIFECYCLE_BROKEN_DOWN)) {
|
|
|
|
RCT2_GLOBAL(0x00F64E34, uint8) = ride->breakdown_reason_pending;
|
|
|
|
if ((vehicleEntry->var_14 & 8) && ride->breakdown_reason_pending == BREAKDOWN_SAFETY_CUT_OUT) {
|
|
|
|
if (!(vehicleEntry->var_14 & 0x2000) ||
|
|
|
|
(
|
|
|
|
vehicle->var_1F == 2 &&
|
|
|
|
vehicle->velocity <= 0x20000
|
|
|
|
)
|
|
|
|
) {
|
|
|
|
vehicle->var_48 |= 0x80;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-12 02:32:20 +01:00
|
|
|
switch (vehicle->status) {
|
|
|
|
case VEHICLE_STATUS_MOVING_TO_END_OF_STATION:
|
|
|
|
case VEHICLE_STATUS_WAITING_FOR_PASSENGERS:
|
|
|
|
case VEHICLE_STATUS_WAITING_TO_DEPART:
|
|
|
|
case VEHICLE_STATUS_DEPARTING:
|
|
|
|
case VEHICLE_STATUS_TRAVELLING:
|
|
|
|
case VEHICLE_STATUS_ARRIVING:
|
|
|
|
case VEHICLE_STATUS_UNLOADING_PASSENGERS:
|
|
|
|
case VEHICLE_STATUS_TRAVELLING_07:
|
|
|
|
case VEHICLE_STATUS_CRASHING:
|
|
|
|
case VEHICLE_STATUS_CRASHED:
|
|
|
|
case VEHICLE_STATUS_TRAVELLING_0A:
|
|
|
|
case VEHICLE_STATUS_SWINGING:
|
|
|
|
case VEHICLE_STATUS_ROTATING:
|
|
|
|
case VEHICLE_STATUS_ROTATING_0D:
|
|
|
|
case VEHICLE_STATUS_OPERATING:
|
|
|
|
case VEHICLE_STATUS_SHOWING_FILM:
|
|
|
|
case VEHICLE_STATUS_ROTATING_10:
|
|
|
|
case VEHICLE_STATUS_OPERATING_11:
|
|
|
|
case VEHICLE_STATUS_OPERATING_12:
|
|
|
|
case VEHICLE_STATUS_OPERATING_13:
|
|
|
|
case VEHICLE_STATUS_WAITING_FOR_CABLE_LIFT:
|
|
|
|
case VEHICLE_STATUS_TRAVELLING_15:
|
|
|
|
{
|
|
|
|
int *addressSwitchPtr = (int*)(0x006D7B70 + (vehicle->status * 4));
|
|
|
|
RCT2_CALLPROC_X(*addressSwitchPtr, 0, 0, 0, (vehicle->var_51 << 8) | ride->mode, (int)vehicle, 0, 0);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case VEHICLE_STATUS_DOING_CIRCUS_SHOW:
|
|
|
|
vehicle_update_doing_circus_show(vehicle);
|
|
|
|
}
|
2014-11-12 00:05:04 +01:00
|
|
|
|
|
|
|
vehicle_update_sound(vehicle);
|
|
|
|
}
|
|
|
|
|
2014-11-12 02:32:20 +01:00
|
|
|
static void vehicle_D6_255_update_moving_to_end_of_station(rct_vehicle *vehicle)
|
2014-11-12 00:05:04 +01:00
|
|
|
{
|
|
|
|
RCT2_CALLPROC_X(0x006DF8A4, 0, 0, 0, 0, (int)vehicle, 0, 0);
|
|
|
|
}
|
|
|
|
|
2014-11-12 02:32:20 +01:00
|
|
|
static void vehicle_D6_255_update_waiting_to_depart(rct_vehicle *vehicle)
|
2014-11-12 00:05:04 +01:00
|
|
|
{
|
|
|
|
RCT2_CALLPROC_X(0x006DF8F1, 0, 0, 0, 0, (int)vehicle, 0, 0);
|
|
|
|
}
|
|
|
|
|
2014-11-12 02:32:20 +01:00
|
|
|
static void vehicle_D6_255_update_departing(rct_vehicle *vehicle)
|
2014-11-12 00:05:04 +01:00
|
|
|
{
|
|
|
|
RCT2_CALLPROC_X(0x006DF97A, 0, 0, 0, 0, (int)vehicle, 0, 0);
|
|
|
|
}
|
|
|
|
|
2014-11-12 02:32:20 +01:00
|
|
|
static void vehicle_D6_255_update_travelling(rct_vehicle *vehicle)
|
2014-11-12 00:05:04 +01:00
|
|
|
{
|
|
|
|
RCT2_CALLPROC_X(0x006DF99C, 0, 0, 0, 0, (int)vehicle, 0, 0);
|
|
|
|
}
|
|
|
|
|
2014-11-12 02:32:20 +01:00
|
|
|
static void vehicle_D6_255_update_arriving(rct_vehicle *vehicle)
|
2014-11-12 00:05:04 +01:00
|
|
|
{
|
|
|
|
vehicle->var_51++;
|
|
|
|
if (vehicle->var_51 >= 64)
|
|
|
|
vehicle->status = VEHICLE_STATUS_MOVING_TO_END_OF_STATION;
|
|
|
|
}
|
|
|
|
|
2014-11-12 02:32:20 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006D95F7
|
|
|
|
*/
|
|
|
|
static void vehicle_update_doing_circus_show(rct_vehicle *vehicle)
|
|
|
|
{
|
|
|
|
int currentTime, totalTime;
|
|
|
|
|
|
|
|
if (RCT2_GLOBAL(0x00F64E34, uint8) == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
totalTime = *(RCT2_ADDRESS(0x009A0AB4, uint16*)[vehicle->var_51]);
|
|
|
|
currentTime = vehicle->var_4C + 1;
|
|
|
|
if (currentTime <= totalTime) {
|
|
|
|
vehicle->var_4C = currentTime;
|
|
|
|
} else {
|
|
|
|
vehicle->status = VEHICLE_STATUS_ARRIVING;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
vehicle->var_51 = 0;
|
|
|
|
vehicle->var_C0 = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-12 00:05:04 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006D7888
|
|
|
|
*/
|
|
|
|
static void vehicle_update_sound(rct_vehicle *vehicle)
|
|
|
|
{
|
|
|
|
RCT2_CALLPROC_X(0x006D7888, 0, 0, 0, 0, (int)vehicle, 0, 0); return;
|
|
|
|
|
|
|
|
// PROBLEMS
|
|
|
|
rct_ride *ride;
|
|
|
|
rct_ride_type *rideEntry;
|
2014-11-12 02:04:50 +01:00
|
|
|
uint8 bl, dl = 255;
|
|
|
|
uint8 screamId, screamVolume;
|
|
|
|
uint16 soundIdVolume;
|
2014-11-12 00:05:04 +01:00
|
|
|
|
|
|
|
ride = GET_RIDE(vehicle->ride);
|
|
|
|
rideEntry = GET_RIDE_ENTRY(vehicle->ride_subtype);
|
|
|
|
|
|
|
|
rct_ride_type_vehicle* vehicleEntry = &rideEntry->vehicles[vehicle->vehicle_type];
|
|
|
|
|
|
|
|
int ecx = abs(vehicle->velocity) - 0x10000;
|
|
|
|
if (ecx >= 0) {
|
|
|
|
dl = vehicleEntry->var_57;
|
|
|
|
ecx >>= 15;
|
|
|
|
bl = 208 + (ecx & 0xFF);
|
|
|
|
if (bl < 0)
|
|
|
|
bl = 255;
|
|
|
|
}
|
|
|
|
|
2014-11-12 02:04:50 +01:00
|
|
|
switch (vehicleEntry->sound_range) {
|
|
|
|
case 3:
|
|
|
|
screamVolume = vehicle->scream_sound_id;
|
2014-11-12 00:05:04 +01:00
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) & 0x7F)) {
|
2014-11-12 02:04:50 +01:00
|
|
|
if (vehicle->velocity < 0x40000 || vehicle->scream_sound_id != 255)
|
2014-11-12 00:05:04 +01:00
|
|
|
goto loc_6D7A97;
|
|
|
|
|
|
|
|
if ((scenario_rand() & 0xFFFF) <= 0x5555) {
|
2014-11-12 02:04:50 +01:00
|
|
|
vehicle->scream_sound_id = SOUND_TRAIN_WHISTLE;
|
|
|
|
screamId = 255;
|
|
|
|
break;
|
2014-11-12 00:05:04 +01:00
|
|
|
}
|
|
|
|
}
|
2014-11-12 02:04:50 +01:00
|
|
|
if (screamVolume != 254) screamVolume = 255;
|
|
|
|
screamId = 255;
|
|
|
|
break;
|
2014-11-12 00:05:04 +01:00
|
|
|
|
2014-11-12 02:04:50 +01:00
|
|
|
case 4:
|
|
|
|
screamVolume = vehicle->scream_sound_id;
|
2014-11-12 00:05:04 +01:00
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) & 0x7F)) {
|
2014-11-12 02:04:50 +01:00
|
|
|
if (vehicle->velocity < 0x40000 || vehicle->scream_sound_id != 255)
|
2014-11-12 00:05:04 +01:00
|
|
|
goto loc_6D7A97;
|
|
|
|
|
|
|
|
if ((scenario_rand() & 0xFFFF) <= 0x5555) {
|
2014-11-12 02:04:50 +01:00
|
|
|
vehicle->scream_sound_id = SOUND_TRAM;
|
|
|
|
screamId = 255;
|
|
|
|
break;
|
2014-11-12 00:05:04 +01:00
|
|
|
}
|
|
|
|
}
|
2014-11-12 02:04:50 +01:00
|
|
|
if (screamVolume != 254) screamVolume = 255;
|
|
|
|
screamId = 255;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
if ((vehicleEntry->var_14 & 0x10)) {
|
|
|
|
screamId = vehicle_update_scream_sound(vehicle);
|
|
|
|
if (screamId == 255)
|
2014-11-12 00:05:04 +01:00
|
|
|
goto loc_6D7A97;
|
|
|
|
|
2014-11-12 02:04:50 +01:00
|
|
|
screamVolume = 255;
|
|
|
|
break;
|
2014-11-12 00:05:04 +01:00
|
|
|
}
|
|
|
|
|
2014-11-12 02:04:50 +01:00
|
|
|
loc_6D7A97:
|
|
|
|
vehicle->scream_sound_id = 255;
|
|
|
|
screamVolume = RCT2_GLOBAL(0x0097D7C8 + (ride->type * 4), uint8);
|
|
|
|
screamId = 243;
|
|
|
|
if (!(vehicle->var_B8 & 2))
|
|
|
|
screamVolume = 255;
|
2014-11-12 00:05:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-11-12 02:04:50 +01:00
|
|
|
// Friction sound
|
2014-11-12 00:05:04 +01:00
|
|
|
soundIdVolume = sub_6D7AC0(vehicle->sound1_id, vehicle->sound1_volume, bl, dl);
|
|
|
|
vehicle->sound1_id = soundIdVolume & 0xFF;
|
|
|
|
vehicle->sound1_volume = (soundIdVolume >> 8) & 0xFF;
|
2014-11-12 02:04:50 +01:00
|
|
|
|
|
|
|
// Scream sound
|
|
|
|
soundIdVolume = sub_6D7AC0(vehicle->sound2_id, vehicle->sound2_volume, screamId, screamVolume);
|
2014-11-12 00:05:04 +01:00
|
|
|
vehicle->sound2_id = soundIdVolume & 0xFF;
|
|
|
|
vehicle->sound2_volume = (soundIdVolume >> 8) & 0xFF;
|
|
|
|
|
|
|
|
{
|
|
|
|
int ebx = RCT2_ADDRESS(0x009A3684, sint16)[vehicle->sprite_direction];
|
|
|
|
int eax = ((vehicle->velocity >> 14) * ebx) >> 14;
|
|
|
|
eax = max(eax, 0xFF81);
|
|
|
|
eax = min(eax, 0x7F);
|
|
|
|
vehicle->var_BF = eax & 0xFF;
|
|
|
|
}
|
2014-09-21 14:50:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-11-12 02:04:50 +01:00
|
|
|
<<<<<<< 0bfcf9391dbd97ecf76b3e6440e443ad52442517
|
2015-10-20 20:16:30 +02:00
|
|
|
*
|
2014-11-12 02:04:50 +01:00
|
|
|
=======
|
|
|
|
*
|
|
|
|
* rct2: 0x006D796B
|
|
|
|
*/
|
|
|
|
static int vehicle_update_scream_sound(rct_vehicle *vehicle)
|
|
|
|
{
|
|
|
|
int r;
|
|
|
|
uint16 spriteIndex;
|
|
|
|
rct_ride_type *rideEntry;
|
|
|
|
rct_vehicle *vehicle2;
|
|
|
|
|
|
|
|
rideEntry = GET_RIDE_ENTRY(vehicle->ride_subtype);
|
|
|
|
|
|
|
|
rct_ride_type_vehicle* vehicleEntry = &rideEntry->vehicles[vehicle->vehicle_type];
|
|
|
|
|
|
|
|
int totalNumPeeps = vehicle_get_total_num_peeps(vehicle);
|
|
|
|
if (totalNumPeeps == 0)
|
|
|
|
return 255;
|
|
|
|
|
|
|
|
if (vehicle->velocity < 0) {
|
|
|
|
if (vehicle->velocity > -0x2C000)
|
|
|
|
return 255;
|
|
|
|
|
|
|
|
spriteIndex = vehicle->sprite_index;
|
|
|
|
do {
|
|
|
|
vehicle2 = &(g_sprite_list[spriteIndex].vehicle);
|
|
|
|
if (vehicle2->var_1F < 1)
|
|
|
|
continue;
|
|
|
|
if (vehicle2->var_1F <= 4)
|
|
|
|
goto produceScream;
|
|
|
|
if (vehicle2->var_1F < 9)
|
|
|
|
continue;
|
|
|
|
if (vehicle2->var_1F <= 15)
|
|
|
|
goto produceScream;
|
|
|
|
} while ((spriteIndex = vehicle2->next_vehicle_on_train) != SPRITE_INDEX_NULL);
|
|
|
|
return 255;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vehicle->velocity < 0x2C000)
|
|
|
|
return 255;
|
|
|
|
|
|
|
|
spriteIndex = vehicle->sprite_index;
|
|
|
|
do {
|
|
|
|
vehicle2 = &(g_sprite_list[spriteIndex].vehicle);
|
|
|
|
if (vehicle2->var_1F < 5)
|
|
|
|
continue;
|
|
|
|
if (vehicle2->var_1F <= 8)
|
|
|
|
goto produceScream;
|
|
|
|
if (vehicle2->var_1F < 17)
|
|
|
|
continue;
|
|
|
|
if (vehicle2->var_1F <= 23)
|
|
|
|
goto produceScream;
|
|
|
|
} while ((spriteIndex = vehicle2->next_vehicle_on_train) != SPRITE_INDEX_NULL);
|
|
|
|
return 255;
|
|
|
|
|
|
|
|
produceScream:
|
|
|
|
if (vehicle->scream_sound_id == 255) {
|
|
|
|
r = scenario_rand();
|
|
|
|
if (totalNumPeeps >= r % 16) {
|
|
|
|
switch (vehicleEntry->sound_range) {
|
|
|
|
case 0:
|
|
|
|
vehicle->scream_sound_id = byte_9A3A14[r % 2];
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
vehicle->scream_sound_id = byte_9A3A18[r % 8];
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
vehicle->scream_sound_id = byte_9A3A16[r % 2];
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
vehicle->scream_sound_id = NO_SCREAM;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
vehicle->scream_sound_id = NO_SCREAM;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return vehicle->scream_sound_id;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
2014-09-21 14:50:35 +02:00
|
|
|
* 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);
|
2015-10-20 20:16:30 +02:00
|
|
|
|
2014-09-21 14:50:35 +02:00
|
|
|
if (verticalG != NULL) *verticalG = (sint16)(eax & 0xFFFF);
|
|
|
|
if (lateralG != NULL) *lateralG = (sint16)(edx & 0xFFFF);
|
2014-11-10 01:40:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void vehicle_set_map_toolbar(rct_vehicle *vehicle)
|
|
|
|
{
|
|
|
|
rct_ride *ride;
|
|
|
|
int vehicleIndex;
|
|
|
|
|
|
|
|
ride = GET_RIDE(vehicle->ride);
|
|
|
|
|
2015-10-25 17:00:21 +01:00
|
|
|
while (vehicle->is_child) {
|
|
|
|
vehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride);
|
|
|
|
}
|
2014-11-10 01:40:59 +01:00
|
|
|
|
|
|
|
for (vehicleIndex = 0; vehicleIndex < 32; vehicleIndex++)
|
|
|
|
if (ride->vehicles[vehicleIndex] == vehicle->sprite_index)
|
|
|
|
break;
|
|
|
|
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 0, uint16) = 2215;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 2, uint16) = 1165;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 4, uint16) = ride->name;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 6, uint32) = ride->name_arguments;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 10, uint16) = RideNameConvention[ride->type].vehicle_name + 2;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 12, uint16) = vehicleIndex + 1;
|
|
|
|
|
|
|
|
int arg0, arg1;
|
|
|
|
ride_get_status(vehicle->ride, &arg0, &arg1);
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 14, uint16) = (uint16)arg0;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 16, uint32) = (uint16)arg1;
|
2014-11-29 16:55:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
rct_vehicle *vehicle_get_head(rct_vehicle *vehicle)
|
|
|
|
{
|
|
|
|
rct_vehicle *prevVehicle;
|
|
|
|
|
|
|
|
for (;;) {
|
2015-10-25 17:00:21 +01:00
|
|
|
prevVehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride);
|
2014-11-29 16:55:44 +01:00
|
|
|
if (prevVehicle->next_vehicle_on_train == SPRITE_INDEX_NULL)
|
|
|
|
break;
|
|
|
|
|
|
|
|
vehicle = prevVehicle;
|
|
|
|
}
|
|
|
|
|
|
|
|
return vehicle;
|
2015-03-21 13:26:28 +01:00
|
|
|
}
|
|
|
|
|
2015-10-25 22:25:54 +01:00
|
|
|
rct_vehicle *vehicle_get_tail(rct_vehicle *vehicle)
|
|
|
|
{
|
|
|
|
uint16 spriteIndex;
|
|
|
|
|
|
|
|
while ((spriteIndex = vehicle->next_vehicle_on_train) != SPRITE_INDEX_NULL) {
|
|
|
|
vehicle = GET_VEHICLE(spriteIndex);
|
|
|
|
}
|
|
|
|
return vehicle;
|
|
|
|
}
|
|
|
|
|
2015-03-21 13:26:28 +01:00
|
|
|
int vehicle_is_used_in_pairs(rct_vehicle *vehicle)
|
|
|
|
{
|
|
|
|
return vehicle->num_seats & VEHICLE_SEAT_PAIR_FLAG;
|
2015-09-12 19:17:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006DEF56
|
|
|
|
*/
|
|
|
|
void sub_6DEF56(rct_vehicle *cableLift)
|
|
|
|
{
|
|
|
|
RCT2_CALLPROC_X(0x006DEF56, 0, 0, 0, 0, (int)cableLift, 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
rct_vehicle *cable_lift_segment_create(int rideIndex, int x, int y, int z, int direction, uint16 var_44, uint32 var_24, bool head)
|
|
|
|
{
|
|
|
|
rct_ride *ride = GET_RIDE(rideIndex);
|
|
|
|
rct_vehicle *current = &(create_sprite(1)->vehicle);
|
|
|
|
current->sprite_identifier = SPRITE_IDENTIFIER_VEHICLE;
|
|
|
|
current->ride = rideIndex;
|
|
|
|
current->ride_subtype = 0xFF;
|
|
|
|
if (head) {
|
|
|
|
move_sprite_to_list((rct_sprite*)current, SPRITE_LINKEDLIST_OFFSET_VEHICLE);
|
|
|
|
ride->cable_lift = current->sprite_index;
|
|
|
|
}
|
2015-10-25 17:00:21 +01:00
|
|
|
current->is_child = head ? 0 : 1;
|
2015-09-12 19:17:25 +02:00
|
|
|
current->var_44 = var_44;
|
|
|
|
current->var_24 = var_24;
|
|
|
|
current->sprite_width = 10;
|
|
|
|
current->sprite_height_negative = 10;
|
|
|
|
current->sprite_height_positive = 10;
|
2015-10-25 17:00:21 +01:00
|
|
|
current->friction = 100;
|
2015-09-12 19:17:25 +02:00
|
|
|
current->num_seats = 0;
|
|
|
|
current->speed = 20;
|
2015-10-25 17:00:21 +01:00
|
|
|
current->acceleration = 80;
|
2015-09-12 19:17:25 +02:00
|
|
|
current->velocity = 0;
|
|
|
|
current->var_2C = 0;
|
|
|
|
current->var_4A = 0;
|
|
|
|
current->var_4C = 0;
|
|
|
|
current->var_4E = 0;
|
|
|
|
current->var_B5 = 0;
|
|
|
|
current->var_BA = 0;
|
|
|
|
current->var_B6 = 0;
|
|
|
|
current->var_B8 = 0;
|
|
|
|
current->sound1_id = 0xFF;
|
|
|
|
current->sound2_id = 0xFF;
|
|
|
|
current->var_C4 = 0;
|
|
|
|
current->var_C5 = 0;
|
|
|
|
current->var_C8 = 0;
|
2015-10-25 22:25:54 +01:00
|
|
|
current->scream_sound_id = 0xFF;
|
2015-09-12 19:17:25 +02:00
|
|
|
current->var_1F = 0;
|
|
|
|
current->var_20 = 0;
|
|
|
|
for (int j = 0; j < 32; j++) {
|
|
|
|
current->peep[j] = SPRITE_INDEX_NULL;
|
|
|
|
}
|
|
|
|
current->var_CD = 0;
|
|
|
|
current->sprite_direction = direction << 3;
|
2015-10-25 17:00:21 +01:00
|
|
|
current->track_x = x;
|
|
|
|
current->track_y = y;
|
2015-09-12 19:17:25 +02:00
|
|
|
|
|
|
|
z = z * 8;
|
2015-10-25 17:00:21 +01:00
|
|
|
current->track_z = z;
|
2015-09-12 19:17:25 +02:00
|
|
|
z += RCT2_GLOBAL(0x0097D21A + (ride->type * 8), uint8);
|
|
|
|
|
|
|
|
sprite_move(16, 16, z, (rct_sprite*)current);
|
2015-10-25 22:25:54 +01:00
|
|
|
current->track_type = (TRACK_ELEM_CABLE_LIFT_HILL << 2) | (current->sprite_direction >> 3);
|
2015-09-12 19:17:25 +02:00
|
|
|
current->var_34 = 164;
|
2015-10-25 22:25:54 +01:00
|
|
|
current->update_flags = VEHICLE_UPDATE_FLAG_1;
|
2015-09-12 19:17:25 +02:00
|
|
|
current->status = VEHICLE_STATUS_MOVING_TO_END_OF_STATION;
|
|
|
|
current->var_51 = 0;
|
|
|
|
current->num_peeps = 0;
|
|
|
|
current->next_free_seat = 0;
|
|
|
|
return current;
|
|
|
|
}
|
2015-10-25 17:00:21 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
2015-10-25 22:25:54 +01:00
|
|
|
* rct2: 0x006DD365
|
2015-10-25 17:00:21 +01:00
|
|
|
*/
|
2015-10-25 22:25:54 +01:00
|
|
|
bool sub_6DD365(rct_vehicle *vehicle)
|
2015-10-25 17:00:21 +01:00
|
|
|
{
|
|
|
|
registers regs;
|
|
|
|
regs.esi = (int)vehicle;
|
|
|
|
|
2015-10-25 22:25:54 +01:00
|
|
|
return RCT2_CALLFUNC_Y(0x006DD365, ®s) & 0x100;
|
2015-10-25 17:00:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
2015-10-25 22:25:54 +01:00
|
|
|
* rct2: 0x006DAB4C
|
2015-10-25 17:00:21 +01:00
|
|
|
*/
|
2015-10-25 22:25:54 +01:00
|
|
|
int sub_6DAB4C(rct_vehicle *vehicle, int *outStation)
|
2015-10-25 17:00:21 +01:00
|
|
|
{
|
|
|
|
registers regs;
|
|
|
|
regs.esi = (int)vehicle;
|
|
|
|
|
2015-10-25 22:25:54 +01:00
|
|
|
RCT2_CALLFUNC_Y(0x006DAB4C, ®s);
|
|
|
|
|
|
|
|
if (outStation != NULL) *outStation = regs.ebx;
|
|
|
|
return regs.eax;
|
2015-10-25 17:00:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
rct_ride_type_vehicle *vehicle_get_vehicle_entry(rct_vehicle *vehicle)
|
|
|
|
{
|
|
|
|
rct_ride_type *rideEntry = GET_RIDE_ENTRY(vehicle->ride_subtype);
|
|
|
|
return &rideEntry->vehicles[vehicle->vehicle_type];
|
|
|
|
}
|
2014-11-12 02:04:50 +01:00
|
|
|
|
|
|
|
int vehicle_get_total_num_peeps(rct_vehicle *vehicle)
|
|
|
|
{
|
|
|
|
uint16 spriteIndex;
|
|
|
|
int numPeeps = 0;
|
|
|
|
for (;;) {
|
|
|
|
numPeeps += vehicle->num_peeps;
|
|
|
|
spriteIndex = vehicle->next_vehicle_on_train;
|
|
|
|
if (spriteIndex == SPRITE_INDEX_NULL)
|
|
|
|
break;
|
|
|
|
|
|
|
|
vehicle = &(g_sprite_list[spriteIndex].vehicle);
|
|
|
|
}
|
|
|
|
|
|
|
|
return numPeeps;
|
|
|
|
}
|
2014-11-12 02:32:20 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006DA1EC
|
|
|
|
*/
|
|
|
|
void vehicle_invalidate_window(rct_vehicle *vehicle)
|
|
|
|
{
|
|
|
|
int viewVehicleIndex;
|
|
|
|
rct_ride *ride;
|
|
|
|
rct_window *w;
|
|
|
|
|
|
|
|
w = window_find_by_number(WC_RIDE, vehicle->ride);
|
|
|
|
if (w == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
ride = GET_RIDE(vehicle->ride);
|
|
|
|
viewVehicleIndex = w->ride.view - 1;
|
|
|
|
if (viewVehicleIndex < 0 || viewVehicleIndex >= ride->num_vehicles)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (vehicle->sprite_index != ride->vehicles[viewVehicleIndex])
|
|
|
|
return;
|
|
|
|
|
|
|
|
window_invalidate(w);
|
|
|
|
}
|