Rev 1 | Rev 20 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 1 | pmbaty | 1 | #include "structur.h" |
| 2 | #include "car.h" |
||
| 3 | #include "controls.h" |
||
| 4 | #include "crush.h" |
||
| 5 | #include "cutscene.h" |
||
| 6 | #include "displays.h" |
||
| 7 | #include "drmem.h" |
||
| 8 | #include "finteray.h" |
||
| 9 | #include "flicplay.h" |
||
| 10 | #include "globvars.h" |
||
| 11 | #include "globvrkm.h" |
||
| 12 | #include "globvrpb.h" |
||
| 13 | #include "graphics.h" |
||
| 14 | #include "harness/config.h" |
||
| 15 | #include "harness/trace.h" |
||
| 16 | #include "init.h" |
||
| 17 | #include "loading.h" |
||
| 18 | #include "loadsave.h" |
||
| 19 | #include "mainloop.h" |
||
| 20 | #include "mainmenu.h" |
||
| 21 | #include "netgame.h" |
||
| 22 | #include "network.h" |
||
| 23 | #include "opponent.h" |
||
| 24 | #include "piping.h" |
||
| 25 | #include "pratcam.h" |
||
| 26 | #include "racestrt.h" |
||
| 27 | #include "racesumm.h" |
||
| 28 | #include "sound.h" |
||
| 29 | #include "utility.h" |
||
| 18 | pmbaty | 30 | #include "world.h" |
| 1 | pmbaty | 31 | #include <stdlib.h> |
| 32 | |||
| 33 | int gLast_wrong_checkpoint; |
||
| 34 | int gMirror_on__structur = 1; // suffix added to avoid duplicate symbol |
||
| 35 | int gPratcam_on = 1; |
||
| 36 | int gCockpit_on = 1; |
||
| 37 | int gOpponent_mix[10][5] = { |
||
| 38 | { 3, 4, 4, 5, 5 }, |
||
| 39 | { 2, 3, 4, 5, 5 }, |
||
| 40 | { 2, 3, 4, 4, 5 }, |
||
| 41 | { 2, 2, 4, 4, 5 }, |
||
| 42 | { 2, 2, 3, 4, 5 }, |
||
| 43 | { 1, 2, 3, 4, 4 }, |
||
| 44 | { 1, 2, 3, 3, 4 }, |
||
| 45 | { 1, 2, 2, 3, 4 }, |
||
| 46 | { 1, 1, 2, 3, 3 }, |
||
| 47 | { 1, 1, 2, 2, 3 } |
||
| 48 | }; |
||
| 49 | tU32 gLast_checkpoint_time; |
||
| 50 | tRace_over_reason gRace_over_reason; |
||
| 51 | |||
| 52 | // IDA: int __cdecl NumberOfOpponentsLeft() |
||
| 53 | int NumberOfOpponentsLeft(void) { |
||
| 54 | int i; |
||
| 55 | int car_count; |
||
| 56 | int result; |
||
| 57 | tCar_spec* the_car; |
||
| 58 | LOG_TRACE("()"); |
||
| 59 | |||
| 60 | result = 0; |
||
| 61 | car_count = GetCarCount(eVehicle_opponent); |
||
| 62 | for (i = 0; car_count > i; ++i) { |
||
| 63 | the_car = GetCarSpec(eVehicle_opponent, i); |
||
| 64 | if (!the_car->knackered) { |
||
| 65 | result++; |
||
| 66 | } |
||
| 67 | } |
||
| 68 | return result; |
||
| 69 | } |
||
| 70 | |||
| 71 | // IDA: void __usercall RaceCompleted(tRace_over_reason pReason@<EAX>) |
||
| 72 | void RaceCompleted(tRace_over_reason pReason) { |
||
| 73 | LOG_TRACE("(%d)", pReason); |
||
| 74 | |||
| 75 | if (!gRace_finished) { |
||
| 76 | if (gNet_mode == eNet_mode_host && pReason < eRace_over_network_victory) { |
||
| 77 | NetFinishRace(gCurrent_net_game, pReason); |
||
| 78 | } |
||
| 79 | if (pReason == eRace_over_out_of_time || pReason == eRace_over_demo) { |
||
| 80 | ChangeAmbientPratcam(35); |
||
| 81 | } else if (pReason < eRace_over_abandoned) { |
||
| 82 | ChangeAmbientPratcam(34); |
||
| 83 | } |
||
| 84 | gRace_over_reason = pReason; |
||
| 85 | if (gMap_mode) { |
||
| 86 | ToggleMap(); |
||
| 87 | } |
||
| 88 | switch (gRace_over_reason) { |
||
| 89 | case eRace_over_laps: |
||
| 90 | case eRace_over_peds: |
||
| 91 | case eRace_over_opponents: |
||
| 92 | ChangeAmbientPratcam(34); |
||
| 93 | DoFancyHeadup(kFancyHeadupRaceCompleted); |
||
| 94 | DRS3StartSound(gPedestrians_outlet, 8011); |
||
| 95 | break; |
||
| 96 | case eRace_over_abandoned: |
||
| 97 | if (gNet_mode == eNet_mode_client) { |
||
| 98 | gHost_abandon_game = 1; |
||
| 18 | pmbaty | 99 | NetFullScreenMessage(kMiscString_HOST_ABANDONED_RACE, 0); |
| 1 | pmbaty | 100 | } |
| 101 | break; |
||
| 102 | case eRace_over_out_of_time: |
||
| 103 | ChangeAmbientPratcam(35); |
||
| 104 | DoFancyHeadup(kFancyHeadupOutOfTime); |
||
| 105 | DRS3StartSound(gPedestrians_outlet, 8010); |
||
| 106 | break; |
||
| 107 | case eRace_over_demo: |
||
| 108 | ChangeAmbientPratcam(35); |
||
| 109 | DoFancyHeadup(kFancyHeadupDemoTimeout); |
||
| 110 | break; |
||
| 111 | case eRace_over_network_victory: |
||
| 112 | ChangeAmbientPratcam(34); |
||
| 113 | DoFancyHeadup(kFancyHeadupNetworkVictory); |
||
| 114 | break; |
||
| 115 | case eRace_over_network_loss: |
||
| 116 | ChangeAmbientPratcam(36); |
||
| 117 | DoFancyHeadup(kFancyHeadupNetworkRaceOverNetworkLoss); |
||
| 118 | break; |
||
| 119 | default: |
||
| 120 | break; |
||
| 121 | } |
||
| 122 | if (gNet_mode != eNet_mode_none) { |
||
| 123 | gRace_finished = 8000; |
||
| 124 | } else { |
||
| 125 | gRace_finished = 4000; |
||
| 126 | } |
||
| 127 | } |
||
| 128 | } |
||
| 129 | |||
| 130 | // IDA: void __usercall Checkpoint(int pCheckpoint_index@<EAX>, int pDo_sound@<EDX>) |
||
| 131 | void Checkpoint(int pCheckpoint_index, int pDo_sound) { |
||
| 132 | LOG_TRACE("(%d, %d)", pCheckpoint_index, pDo_sound); |
||
| 133 | |||
| 134 | PratcamEvent(33); |
||
| 135 | DoFancyHeadup(kFancyHeadupCheckpoint); |
||
| 136 | if (pDo_sound) { |
||
| 137 | DRS3StartSound(gPedestrians_outlet, 8012); |
||
| 138 | } |
||
| 139 | } |
||
| 140 | |||
| 141 | // IDA: void __cdecl IncrementCheckpoint() |
||
| 142 | void IncrementCheckpoint(void) { |
||
| 143 | int done_voice; |
||
| 144 | LOG_TRACE("()"); |
||
| 145 | |||
| 146 | done_voice = 0; |
||
| 147 | if (gRace_finished) { |
||
| 148 | return; |
||
| 149 | } |
||
| 150 | gLast_checkpoint_time = GetTotalTime(); |
||
| 151 | if (gCheckpoint < gCheckpoint_count) { |
||
| 152 | gCheckpoint++; |
||
| 153 | } else { |
||
| 154 | gCheckpoint = 1; |
||
| 155 | gLap++; |
||
| 156 | if (gLap == gTotal_laps) { |
||
| 157 | PratcamEvent(33); // FIXME: or PratcamEventNow |
||
| 158 | NewTextHeadupSlot(4, 0, 1000, -4, GetMiscString(kMiscString_FinalLap)); |
||
| 159 | DRS3StartSound(gPedestrians_outlet, 8014); |
||
| 160 | done_voice = 1; |
||
| 161 | } else if (gLap > gTotal_laps) { |
||
| 162 | gLap = gTotal_laps; |
||
| 163 | gCheckpoint = gCheckpoint_count; |
||
| 164 | RaceCompleted(eRace_over_laps); |
||
| 165 | } |
||
| 166 | } |
||
| 167 | if (!gRace_finished) { |
||
| 168 | Checkpoint(gCheckpoint, !done_voice); |
||
| 169 | if (gCheck_point_cash[gProgram_state.skill_level] != 0) { |
||
| 170 | EarnCredits(gCheck_point_cash[gProgram_state.skill_level]); |
||
| 171 | } |
||
| 172 | } |
||
| 173 | } |
||
| 174 | |||
| 175 | // IDA: void __cdecl IncrementLap() |
||
| 176 | void IncrementLap(void) { |
||
| 177 | int i; |
||
| 178 | LOG_TRACE("()"); |
||
| 179 | |||
| 180 | for (i = gCheckpoint; i <= gCheckpoint_count; i++) { |
||
| 181 | IncrementCheckpoint(); |
||
| 182 | } |
||
| 183 | } |
||
| 184 | |||
| 185 | // IDA: int __usercall RayHitFace@<EAX>(br_vector3 *pV0@<EAX>, br_vector3 *pV1@<EDX>, br_vector3 *pV2@<EBX>, br_vector3 *pNormal@<ECX>, br_vector3 *pStart, br_vector3 *pDir) |
||
| 186 | int RayHitFace(br_vector3* pV0, br_vector3* pV1, br_vector3* pV2, br_vector3* pNormal, br_vector3* pStart, br_vector3* pDir) { |
||
| 187 | tFace_ref the_face; |
||
| 188 | br_scalar rt; |
||
| 189 | LOG_TRACE("(%p, %p, %p, %p, %p, %p)", pV0, pV1, pV2, pNormal, pStart, pDir); |
||
| 190 | |||
| 191 | the_face.material = NULL; |
||
| 192 | BrVector3Copy(&the_face.v[0], pV0); |
||
| 193 | BrVector3Copy(&the_face.v[1], pV1); |
||
| 194 | BrVector3Copy(&the_face.v[2], pV2); |
||
| 195 | BrVector3Copy(&the_face.normal, pNormal); |
||
| 196 | CheckSingleFace(&the_face, pStart, pDir, &the_face.normal, &rt); |
||
| 197 | return rt >= 0.f && rt <= 1.f; |
||
| 198 | } |
||
| 199 | |||
| 200 | // IDA: void __usercall WrongCheckpoint(int pCheckpoint_index@<EAX>) |
||
| 201 | void WrongCheckpoint(int pCheckpoint_index) { |
||
| 202 | LOG_TRACE("(%d)", pCheckpoint_index); |
||
| 203 | |||
| 204 | if ((pCheckpoint_index == gLast_wrong_checkpoint && GetTotalTime() - gLast_checkpoint_time > 20000) || (pCheckpoint_index != gLast_wrong_checkpoint && GetTotalTime() - gLast_checkpoint_time > 2000)) { |
||
| 205 | if (gNet_mode == eNet_mode_none) { |
||
| 206 | if (gCheckpoint == ((gCurrent_race.check_point_count < pCheckpoint_index + 2) ? ((gLap == 1) ? -1 : 1) : (pCheckpoint_index + 2))) { |
||
| 207 | return; |
||
| 208 | } |
||
| 209 | } |
||
| 210 | NewTextHeadupSlot(4, 0, 1000, -4, GetMiscString(kMiscString_WrongCheckpoint)); |
||
| 211 | DRS3StartSound(gPedestrians_outlet, 8013); |
||
| 212 | gLast_checkpoint_time = GetTotalTime(); |
||
| 213 | gLast_wrong_checkpoint = pCheckpoint_index; |
||
| 214 | } |
||
| 215 | } |
||
| 216 | |||
| 217 | // IDA: void __cdecl CheckCheckpoints() |
||
| 218 | void CheckCheckpoints(void) { |
||
| 219 | tCar_spec* car; |
||
| 220 | br_vector3 orig; |
||
| 221 | br_vector3 dir; |
||
| 222 | int i; |
||
| 223 | int j; |
||
| 224 | int cat; |
||
| 225 | int car_count; |
||
| 226 | int car_index; |
||
| 227 | tNet_game_player_info* net_player; |
||
| 228 | LOG_TRACE("()"); |
||
| 229 | |||
| 230 | if (gNet_mode == eNet_mode_client) { |
||
| 231 | return; |
||
| 232 | } |
||
| 233 | if (gNet_mode == eNet_mode_host && gCurrent_net_game->type != eNet_game_type_checkpoint && gCurrent_net_game->type != eNet_game_type_sudden_death) { |
||
| 234 | return; |
||
| 235 | } |
||
| 236 | // in single-player mode (=eNet_mode_none), only the player will be checked, |
||
| 237 | // in multi-player, the host + clients will be tested, there are no drone opponents there |
||
| 238 | for (cat = 0; cat <= gNet_mode; cat++) { |
||
| 239 | if (cat == eVehicle_self) { |
||
| 240 | car_count = 1; |
||
| 241 | } else { |
||
| 242 | car_count = GetCarCount(cat); |
||
| 243 | } |
||
| 244 | for (car_index = 0; car_index < car_count; car_index++) { |
||
| 245 | if (cat == eVehicle_self) { |
||
| 246 | car = &gProgram_state.current_car; |
||
| 247 | } else { |
||
| 248 | car = GetCarSpec(cat, car_index); |
||
| 249 | } |
||
| 250 | BrVector3Copy(&orig, (br_vector3*)car->old_frame_mat.m[3]); |
||
| 251 | BrVector3Sub(&dir, &car->car_master_actor->t.t.translate.t, &orig); |
||
| 252 | for (i = 0; i < gCurrent_race.check_point_count; i++) { |
||
| 253 | for (j = 0; j < gCurrent_race.checkpoints[i].quad_count; j++) { |
||
| 254 | if ( |
||
| 255 | RayHitFace(&gCurrent_race.checkpoints[i].vertices[j][0], |
||
| 256 | &gCurrent_race.checkpoints[i].vertices[j][1], |
||
| 257 | &gCurrent_race.checkpoints[i].vertices[j][2], |
||
| 258 | &gCurrent_race.checkpoints[i].normal[j], |
||
| 259 | &orig, &dir) |
||
| 260 | || RayHitFace(&gCurrent_race.checkpoints[i].vertices[j][0], |
||
| 261 | &gCurrent_race.checkpoints[i].vertices[j][2], |
||
| 262 | &gCurrent_race.checkpoints[i].vertices[j][3], |
||
| 263 | &gCurrent_race.checkpoints[i].normal[j], |
||
| 264 | &orig, |
||
| 265 | &dir)) { |
||
| 266 | if (gNet_mode == eNet_mode_none) { |
||
| 267 | if (i + 1 == gCheckpoint) { |
||
| 268 | IncrementCheckpoint(); |
||
| 269 | } else { |
||
| 270 | WrongCheckpoint(i); |
||
| 271 | } |
||
| 272 | } else { |
||
| 273 | net_player = NetPlayerFromCar(car); |
||
| 274 | if (gCurrent_net_game->type == eNet_game_type_checkpoint) { |
||
| 275 | if (net_player->score & (1 << i)) { |
||
| 276 | net_player->score &= ~(1 << i); |
||
| 277 | SendGameplay(net_player->ID, eNet_gameplay_checkpoint, i, 0, 0, 0); |
||
| 278 | } else { |
||
| 279 | SendGameplay(net_player->ID, eNet_gameplay_wrong_checkpoint, i, 0, 0, 0); |
||
| 280 | } |
||
| 281 | } else if (net_player->score % gCurrent_race.check_point_count == i) { |
||
| 282 | net_player->score++; |
||
| 283 | SendGameplay(net_player->ID, eNet_gameplay_checkpoint, i, 0, 0, 0); |
||
| 284 | } else { |
||
| 285 | SendGameplay(net_player->ID, eNet_gameplay_wrong_checkpoint, i, 0, 0, 0); |
||
| 286 | } |
||
| 287 | } |
||
| 288 | break; |
||
| 289 | } |
||
| 290 | } |
||
| 291 | } |
||
| 292 | } |
||
| 293 | car->old_frame_mat = car->car_master_actor->t.t.mat; |
||
| 294 | } |
||
| 295 | } |
||
| 296 | |||
| 297 | // IDA: void __cdecl TotalRepair() |
||
| 298 | void TotalRepair(void) { |
||
| 299 | LOG_TRACE("()"); |
||
| 300 | |||
| 301 | TotallyRepairCar(); |
||
| 302 | NewTextHeadupSlot(4, 0, 1000, -4, GetMiscString(kMiscString_InstantRepair)); |
||
| 303 | } |
||
| 304 | |||
| 305 | // IDA: void __cdecl DoLogos() |
||
| 306 | void DoLogos(void) { |
||
| 307 | ClearEntireScreen(); |
||
| 308 | DoSCILogo(); |
||
| 309 | DoOpeningAnimation(); |
||
| 310 | DoStainlessLogo(); |
||
| 311 | gProgram_state.prog_status = eProg_opening; |
||
| 312 | } |
||
| 313 | |||
| 314 | // IDA: void __cdecl DoProgOpeningAnimation() |
||
| 315 | void DoProgOpeningAnimation(void) { |
||
| 316 | LOG_TRACE("()"); |
||
| 317 | |||
| 318 | gProgram_state.prog_status = eProg_idling; |
||
| 319 | DRS3StopOutletSound(gEffects_outlet); |
||
| 320 | } |
||
| 321 | |||
| 322 | // IDA: void __cdecl DoProgramDemo() |
||
| 323 | void DoProgramDemo(void) { |
||
| 324 | LOG_TRACE("()"); |
||
| 325 | |||
| 326 | DoLogos(); |
||
| 327 | gProgram_state.prog_status = eProg_idling; |
||
| 328 | DRS3StopOutletSound(gEffects_outlet); |
||
| 329 | } |
||
| 330 | |||
| 331 | // IDA: int __usercall ChooseOpponent@<EAX>(int pNastiness@<EAX>, int *pHad_scum@<EDX>) |
||
| 332 | int ChooseOpponent(int pNastiness, int* pHad_scum) { |
||
| 333 | int i; |
||
| 334 | int count; |
||
| 335 | int temp_array[40]; |
||
| 336 | LOG_TRACE("(%d, %p)", pNastiness, pHad_scum); |
||
| 337 | |||
| 338 | count = 0; |
||
| 339 | for (i = 0; i < gNumber_of_racers; ++i) { |
||
| 340 | if (gOpponents[i].strength_rating == pNastiness |
||
| 341 | && gProgram_state.current_car.index != i |
||
| 342 | && !gOpponents[i].picked |
||
| 343 | && (gOpponents[i].car_number >= 0 || !*pHad_scum)) { |
||
| 344 | temp_array[count++] = i; |
||
| 345 | } |
||
| 346 | } |
||
| 347 | i = temp_array[IRandomBetween(0, count - 1)]; |
||
| 348 | gOpponents[i].picked = 1; |
||
| 349 | if (gOpponents[i].car_number < 0) { |
||
| 350 | *pHad_scum = 1; |
||
| 351 | } |
||
| 352 | return i; |
||
| 353 | } |
||
| 354 | |||
| 355 | // IDA: void __usercall SelectOpponents(tRace_info *pRace_info@<EAX>) |
||
| 356 | void SelectOpponents(tRace_info* pRace_info) { |
||
| 357 | int i; |
||
| 358 | int rank_band; |
||
| 359 | int nastiness; |
||
| 360 | int had_scum; |
||
| 361 | LOG_TRACE("(%p)", pRace_info); |
||
| 362 | |||
| 363 | if (harness_game_info.mode == eGame_carmageddon_demo || harness_game_info.mode == eGame_splatpack_demo || harness_game_info.mode == eGame_splatpack_xmas_demo) { |
||
| 364 | pRace_info->number_of_racers = OPPONENT_COUNT; |
||
| 365 | for (i = 0; i < OPPONENT_COUNT; i++) { |
||
| 366 | pRace_info->opponent_list[i].index = gDemo_opponents[i]; |
||
| 367 | pRace_info->opponent_list[i].ranking = IRandomBetween(gProgram_state.rank - 10, gProgram_state.rank + 10); |
||
| 368 | } |
||
| 369 | return; |
||
| 370 | } |
||
| 371 | |||
| 372 | had_scum = 0; |
||
| 373 | if (gNet_mode == eNet_mode_none) { |
||
| 374 | pRace_info->number_of_racers = OPPONENT_COUNT; |
||
| 375 | for (i = 0; i < gNumber_of_racers; ++i) { |
||
| 376 | gOpponents[i].picked = 0; |
||
| 377 | } |
||
| 378 | if (gRace_list[gProgram_state.current_race_index].suggested_rank < 0) { |
||
| 379 | rank_band = 0; |
||
| 380 | } else { |
||
| 381 | rank_band = gRace_list[gProgram_state.current_race_index].suggested_rank / 10; |
||
| 382 | } |
||
| 383 | for (i = 0; i < OPPONENT_COUNT; i++) { |
||
| 384 | nastiness = gOpponent_mix[rank_band][i]; |
||
| 385 | pRace_info->opponent_list[i].index = ChooseOpponent(nastiness, &had_scum); |
||
| 386 | pRace_info->opponent_list[i].ranking = IRandomBetween(gProgram_state.rank - 10, gProgram_state.rank + 10); |
||
| 387 | } |
||
| 388 | } |
||
| 389 | } |
||
| 390 | |||
| 391 | // IDA: int __usercall PickNetRace@<EAX>(int pCurrent_race@<EAX>, tNet_sequence_type pNet_race_sequence@<EDX>) |
||
| 392 | int PickNetRace(int pCurrent_race, tNet_sequence_type pNet_race_sequence) { |
||
| 393 | int i; |
||
| 394 | int new_index; |
||
| 395 | int races_count; |
||
| 396 | int most_seldom_seen; |
||
| 397 | int races_to_pick_from[50]; |
||
| 398 | LOG_TRACE("(%d, %d)", pCurrent_race, pNet_race_sequence); |
||
| 399 | |||
| 400 | if (pNet_race_sequence == eNet_sequence_sequential) { |
||
| 401 | pCurrent_race++; |
||
| 402 | if (pCurrent_race >= gNumber_of_races) { |
||
| 403 | pCurrent_race = 0; |
||
| 404 | } |
||
| 405 | } else { |
||
| 406 | most_seldom_seen = 10000; |
||
| 407 | for (i = 0; i < gNumber_of_races; i++) { |
||
| 408 | if (gRace_list[i].been_there_done_that < most_seldom_seen) { |
||
| 409 | most_seldom_seen = gRace_list[i].been_there_done_that; |
||
| 410 | } |
||
| 411 | } |
||
| 412 | races_count = 0; |
||
| 413 | for (i = 0; i < gNumber_of_races; i++) { |
||
| 414 | if (gRace_list[i].been_there_done_that == most_seldom_seen && (i != pCurrent_race)) { |
||
| 415 | races_to_pick_from[races_count] = i; |
||
| 416 | races_count++; |
||
| 417 | } |
||
| 418 | } |
||
| 419 | new_index = IRandomBetween(0, races_count - 1); |
||
| 420 | pCurrent_race = races_to_pick_from[new_index]; |
||
| 421 | gRace_list[pCurrent_race].been_there_done_that++; |
||
| 422 | } |
||
| 423 | return pCurrent_race; |
||
| 424 | } |
||
| 425 | |||
| 426 | // IDA: void __cdecl SwapNetCarsLoad() |
||
| 427 | void SwapNetCarsLoad(void) { |
||
| 428 | int i; |
||
| 429 | int switched_res; |
||
| 430 | LOG_TRACE("()"); |
||
| 431 | |||
| 432 | DisableNetService(); |
||
| 433 | AboutToLoadFirstCar(); |
||
| 434 | switched_res = SwitchToRealResolution(); |
||
| 435 | for (i = 0; i < gNumber_of_net_players; i++) { |
||
| 436 | if (gNet_players[i].next_car_index >= 0) { |
||
| 437 | gNet_players[i].car_index = gNet_players[i].next_car_index; |
||
| 438 | } |
||
| 439 | gNet_players[i].next_car_index = -1; |
||
| 440 | LoadCar(gOpponents[gNet_players[i].car_index].car_file_name, |
||
| 441 | (gThis_net_player_index == i) ? eDriver_local_human : eDriver_net_human, |
||
| 442 | gNet_players[i].car, gNet_players[i].car_index, gNet_players[i].player_name, |
||
| 443 | &gNet_cars_storage_space); |
||
| 444 | } |
||
| 445 | if (switched_res) { |
||
| 446 | SwitchToLoresMode(); |
||
| 447 | } |
||
| 448 | ReenableNetService(); |
||
| 449 | } |
||
| 450 | |||
| 451 | // IDA: void __cdecl SwapNetCarsDispose() |
||
| 452 | void SwapNetCarsDispose(void) { |
||
| 18 | pmbaty | 453 | int i; |
| 1 | pmbaty | 454 | LOG_TRACE("()"); |
| 18 | pmbaty | 455 | |
| 456 | DisableNetService(); |
||
| 457 | for (i = 0; i < gNumber_of_net_players; i++) { |
||
| 458 | DisposeCar(gNet_players[i].car, gNet_players[i].car_index); |
||
| 459 | if (gNet_players[i].car_index >= 0) { |
||
| 460 | gCar_details[gNet_players[i].car_index].ownership = eCar_owner_none; |
||
| 461 | } |
||
| 462 | } |
||
| 463 | ClearOutStorageSpace(&gOur_car_storage_space); |
||
| 464 | ClearOutStorageSpace(&gNet_cars_storage_space); |
||
| 465 | ReenableNetService(); |
||
| 1 | pmbaty | 466 | } |
| 467 | |||
| 468 | // IDA: void __cdecl DoGame() |
||
| 469 | void DoGame(void) { |
||
| 470 | tSO_result options_result; |
||
| 471 | tRace_result race_result; |
||
| 472 | int second_select_race; |
||
| 473 | int first_summary_done; |
||
| 474 | int i; |
||
| 475 | LOG_TRACE("()"); |
||
| 476 | |||
| 477 | gAbandon_game = 0; |
||
| 478 | gDisallow_abandon_race = 0; |
||
| 479 | gCar_to_view = &gProgram_state.current_car; |
||
| 480 | StartLoadingScreen(); |
||
| 481 | gProgram_state.prog_status = eProg_game_ongoing; |
||
| 482 | second_select_race = 0; |
||
| 483 | if (gNet_mode == gNet_mode_of_last_game) { |
||
| 484 | PrintMemoryDump(0, "BEFORE START RACE SCREEN"); |
||
| 485 | SelectOpponents(&gCurrent_race); |
||
| 486 | if (gNet_mode != eNet_mode_none) { |
||
| 487 | LoadRaceInfo(gProgram_state.current_race_index, &gCurrent_race); |
||
| 488 | FillInRaceInfo(&gCurrent_race); |
||
| 489 | DisposeRaceInfo(&gCurrent_race); |
||
| 490 | } else { |
||
| 491 | do { |
||
| 492 | options_result = DoSelectRace(&second_select_race); |
||
| 493 | if (options_result == eSO_main_menu_invoked) { |
||
| 494 | DoMainMenuScreen(0, 1, 1); |
||
| 495 | } |
||
| 496 | gDisallow_abandon_race = 0; |
||
| 497 | } while (options_result == eSO_main_menu_invoked && gProgram_state.prog_status == eProg_game_ongoing && !gAbandon_game); |
||
| 498 | } |
||
| 499 | if (gProgram_state.prog_status == eProg_game_starting |
||
| 500 | || gProgram_state.prog_status == eProg_quit |
||
| 501 | || gProgram_state.prog_status == eProg_idling |
||
| 502 | || gAbandon_game) { |
||
| 503 | PrintMemoryDump(0, "AFTER ABANDONING START RACE SCREEN"); |
||
| 504 | if (gProgram_state.prog_status == eProg_game_ongoing) { |
||
| 505 | gProgram_state.prog_status = eProg_game_starting; |
||
| 506 | } |
||
| 507 | } else { |
||
| 508 | PrintMemoryDump(0, "AFTER START RACE SCREEN"); |
||
| 509 | DoNewGameAnimation(); |
||
| 510 | StartLoadingScreen(); |
||
| 511 | if (gNet_mode != eNet_mode_none) { |
||
| 512 | if (gCurrent_net_game->options.random_car_choice |
||
| 513 | && (gCurrent_net_game->options.car_choice == eNet_car_all || gCurrent_net_game->options.car_choice == eNet_car_both) |
||
| 514 | && !gNo_races_yet) { |
||
| 515 | SwapNetCarsLoad(); |
||
| 516 | } |
||
| 517 | } else { |
||
| 518 | LoadOpponentsCars(&gCurrent_race); |
||
| 519 | } |
||
| 520 | PrintMemoryDump(0, "AFTER LOADING OPPONENTS IN"); |
||
| 521 | InitRace(); |
||
| 522 | if (gNet_mode_of_last_game == gNet_mode) { |
||
| 523 | if (gProgram_state.prog_status == eProg_game_starting |
||
| 524 | || gProgram_state.prog_status == eProg_quit |
||
| 525 | || gProgram_state.prog_status == eProg_idling |
||
| 526 | || gAbandon_game) { |
||
| 527 | DisposeRace(); |
||
| 528 | if (gNet_mode == eNet_mode_none && gNet_mode_of_last_game == eNet_mode_none) { |
||
| 529 | DisposeOpponentsCars(&gCurrent_race); |
||
| 530 | } |
||
| 531 | DisposeTrack(); |
||
| 532 | if (gProgram_state.prog_status == eProg_game_ongoing) { |
||
| 533 | gProgram_state.prog_status = eProg_game_starting; |
||
| 534 | } |
||
| 535 | } else { |
||
| 536 | if (gNet_mode != eNet_mode_none) { |
||
| 537 | do { |
||
| 538 | options_result = NetSynchRaceStart(); |
||
| 539 | if (options_result == eSO_main_menu_invoked) { |
||
| 540 | DoMainMenuScreen(0, 1, 1); |
||
| 541 | } |
||
| 542 | } while (options_result == eSO_main_menu_invoked |
||
| 543 | && gProgram_state.prog_status == eProg_game_ongoing |
||
| 544 | && !gAbandon_game); |
||
| 545 | } else { |
||
| 546 | do { |
||
| 547 | options_result = DoGridPosition(); |
||
| 548 | if (options_result == eSO_main_menu_invoked) { |
||
| 549 | DoMainMenuScreen(0, 1, 1); |
||
| 550 | } |
||
| 551 | } while (options_result == eSO_main_menu_invoked |
||
| 552 | && gProgram_state.prog_status == eProg_game_ongoing |
||
| 553 | && !gAbandon_game); |
||
| 554 | SetInitialPositions(&gCurrent_race); |
||
| 555 | } |
||
| 556 | if (gProgram_state.prog_status == eProg_game_starting |
||
| 557 | || gProgram_state.prog_status == eProg_quit |
||
| 558 | || gProgram_state.prog_status == eProg_idling |
||
| 559 | || gAbandon_game) { |
||
| 560 | DisposeRace(); |
||
| 561 | if (!gNet_mode && !gNet_mode_of_last_game) { |
||
| 562 | DisposeOpponentsCars(&gCurrent_race); |
||
| 563 | } |
||
| 564 | DisposeTrack(); |
||
| 565 | if (gProgram_state.prog_status == eProg_game_ongoing) { |
||
| 566 | gProgram_state.prog_status = eProg_game_starting; |
||
| 567 | } |
||
| 568 | } else { |
||
| 569 | SwitchToRealResolution(); |
||
| 570 | InitOpponents(&gCurrent_race); |
||
| 571 | InitialiseCarsEtc(&gCurrent_race); |
||
| 572 | SetInitialCopPositions(); |
||
| 573 | InitSoundSources(); |
||
| 574 | InitLastDamageArrayEtc(); |
||
| 575 | race_result = DoRace(); |
||
| 576 | SwitchToLoresMode(); |
||
| 577 | DisposeRace(); |
||
| 578 | if (gNet_mode != eNet_mode_none) { |
||
| 579 | gProgram_state.current_race_index = gPending_race; |
||
| 580 | gCurrent_net_game->start_race = gPending_race; |
||
| 581 | gPending_race = -1; |
||
| 582 | } |
||
| 583 | if (race_result == eRace_completed || race_result == eRace_timed_out) { |
||
| 584 | DoEndRaceAnimation(); |
||
| 585 | first_summary_done = 0; |
||
| 586 | do { |
||
| 587 | options_result = DoEndRaceSummary(&first_summary_done, race_result); |
||
| 588 | if (options_result == eSO_main_menu_invoked) { |
||
| 589 | DoMainMenuScreen(0, 1, 1); |
||
| 590 | } |
||
| 591 | } while (options_result == eSO_main_menu_invoked && gProgram_state.prog_status == eProg_game_ongoing); |
||
| 592 | } |
||
| 593 | if (gNet_mode) { |
||
| 594 | for (i = 0; i < gNumber_of_net_players; i++) { |
||
| 595 | TotallyRepairACar(gNet_players[i].car); |
||
| 596 | } |
||
| 597 | } else { |
||
| 598 | TotallyRepairCar(); |
||
| 599 | } |
||
| 600 | if (gNet_mode) { |
||
| 601 | if (gCurrent_net_game->options.random_car_choice |
||
| 602 | && (gCurrent_net_game->options.car_choice == eNet_car_all |
||
| 603 | || gCurrent_net_game->options.car_choice == eNet_car_both) |
||
| 604 | && !gNo_races_yet) { |
||
| 605 | SwapNetCarsDispose(); |
||
| 606 | } |
||
| 607 | } else { |
||
| 608 | DisposeOpponentsCars(&gCurrent_race); |
||
| 609 | } |
||
| 610 | DisposeTrack(); |
||
| 611 | if (harness_game_info.mode == eGame_carmageddon_demo || harness_game_info.mode == eGame_splatpack_demo || harness_game_info.mode == eGame_splatpack_xmas_demo) { |
||
| 612 | DoFullVersionPowerpoint(); |
||
| 613 | } |
||
| 614 | gProgram_state.loaded = 0; |
||
| 615 | if (gProgram_state.prog_status == eProg_game_ongoing) { |
||
| 616 | gProgram_state.prog_status = eProg_game_starting; |
||
| 617 | } |
||
| 618 | } |
||
| 619 | } |
||
| 620 | } else { |
||
| 621 | gProgram_state.prog_status = eProg_idling; |
||
| 622 | } |
||
| 623 | } |
||
| 624 | } else { |
||
| 625 | gProgram_state.prog_status = eProg_idling; |
||
| 626 | } |
||
| 627 | } |
||
| 628 | |||
| 629 | // IDA: void __cdecl InitialiseProgramState() |
||
| 630 | void InitialiseProgramState(void) { |
||
| 631 | gProgram_state.loaded = 0; |
||
| 632 | gProgram_state.last_slot = 0; |
||
| 633 | gProgram_state.frank_or_anniness = eFrankie; |
||
| 634 | gProgram_state.skill_level = 1; |
||
| 635 | gProgram_state.view_type = eVT_Scene; |
||
| 636 | gProgram_state.auto_parts_reply = eAP_auto; |
||
| 637 | gProgram_state.racing = 0; |
||
| 638 | gProgram_state.cut_scene = 0; |
||
| 639 | gProgram_state.saving = 0; |
||
| 640 | gProgram_state.loading = 0; |
||
| 641 | gProgram_state.dont_save_or_load = 0; |
||
| 642 | gProgram_state.dont_load = 0; |
||
| 643 | gProgram_state.mirror_on = gMirror_on__structur; |
||
| 644 | gProgram_state.prog_status = eProg_intro; |
||
| 645 | if (gAusterity_mode) { |
||
| 646 | gProgram_state.prat_cam_on = 0; |
||
| 647 | gPratcam_on = 0; |
||
| 648 | } else { |
||
| 649 | gProgram_state.prat_cam_on = gPratcam_on; |
||
| 650 | } |
||
| 651 | gProgram_state.cockpit_on = gCockpit_on; |
||
| 652 | gProgram_state.car_name[0] = 0; |
||
| 653 | SetSoundVolumes(); |
||
| 654 | AllocateRearviewPixelmap(); |
||
| 655 | } |
||
| 656 | |||
| 657 | // IDA: void __cdecl DoProgram() |
||
| 658 | void DoProgram(void) { |
||
| 659 | InitialiseProgramState(); |
||
| 660 | while (gProgram_state.prog_status != eProg_quit) { |
||
| 661 | switch (gProgram_state.prog_status) { |
||
| 662 | case eProg_intro: |
||
| 663 | DisposeGameIfNecessary(); |
||
| 664 | DoLogos(); |
||
| 665 | break; |
||
| 666 | case eProg_opening: |
||
| 667 | DisposeGameIfNecessary(); |
||
| 668 | DoProgOpeningAnimation(); |
||
| 669 | break; |
||
| 670 | case eProg_idling: |
||
| 671 | DisposeGameIfNecessary(); |
||
| 672 | if (gGame_to_load < 0) { |
||
| 673 | DoMainMenuScreen(30000u, 0, 0); |
||
| 674 | } else { |
||
| 675 | DoLoadGame(); |
||
| 676 | } |
||
| 677 | break; |
||
| 678 | case eProg_demo: |
||
| 679 | DoProgramDemo(); |
||
| 680 | break; |
||
| 681 | case eProg_game_starting: |
||
| 682 | DoGame(); |
||
| 683 | break; |
||
| 684 | default: |
||
| 685 | break; |
||
| 686 | } |
||
| 687 | } |
||
| 688 | } |
||
| 689 | |||
| 690 | // IDA: void __cdecl JumpTheStart() |
||
| 691 | void JumpTheStart(void) { |
||
| 692 | char s[256]; |
||
| 693 | LOG_TRACE("()"); |
||
| 694 | |||
| 695 | if (gNet_mode == eNet_mode_none |
||
| 696 | || gProgram_state.credits_earned - gProgram_state.credits_lost >= gJump_start_fine[gProgram_state.skill_level]) { |
||
| 697 | WakeUpOpponentsToTheFactThatTheStartHasBeenJumped(gCountdown); |
||
| 698 | gCountdown = 0; |
||
| 699 | DRS3StopOutletSound(gPedestrians_outlet); |
||
| 700 | DRS3StartSound(gPedestrians_outlet, 8016); |
||
| 701 | SpendCredits(gJump_start_fine[gProgram_state.skill_level]); |
||
| 702 | sprintf(s, "%s %d %s", GetMiscString(gProgram_state.frank_or_anniness == eFrankie ? kMiscString_BadBoy : kMiscString_BadGirl), gJump_start_fine[gProgram_state.skill_level], GetMiscString(kMiscString_CreditFine)); |
||
| 703 | NewTextHeadupSlot(4, 0, 1000, -4, s); |
||
| 704 | } |
||
| 705 | } |
||
| 706 | |||
| 707 | // IDA: void __cdecl GoingToInterfaceFromRace() |
||
| 708 | void GoingToInterfaceFromRace(void) { |
||
| 709 | LOG_TRACE("()"); |
||
| 710 | |||
| 711 | gInterface_within_race_mode = 1; |
||
| 712 | PlayFlicsFromDisk(); |
||
| 713 | SwitchToLoresMode(); |
||
| 714 | if (gNet_mode == eNet_mode_host) { |
||
| 715 | SendGameplayToAllPlayers(eNet_gameplay_host_paused, 0, 0, 0, 0); |
||
| 716 | } |
||
| 717 | } |
||
| 718 | |||
| 719 | // IDA: void __cdecl GoingBackToRaceFromInterface() |
||
| 720 | void GoingBackToRaceFromInterface(void) { |
||
| 721 | LOG_TRACE("()"); |
||
| 722 | |||
| 723 | gInterface_within_race_mode = 0; |
||
| 724 | PlayFlicsFromMemory(); |
||
| 725 | SwitchToRealResolution(); |
||
| 726 | if (gNet_mode == eNet_mode_host) { |
||
| 727 | SendGameplayToAllPlayers(eNet_gameplay_host_unpaused, 0, 0, 0, 0); |
||
| 728 | } |
||
| 729 | } |