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