00001
00002 #include "revolt.h"
00003 #include "timing.h"
00004 #include "ctrlread.h"
00005 #include "object.h"
00006 #include "player.h"
00007 #include "aizone.h"
00008 #ifdef _PC
00009 #include "registry.h"
00010 #endif
00011 #include "camera.h"
00012 #ifdef _PC
00013 #include "input.h"
00014 #endif
00015 #include "NewColl.h"
00016 #include "Particle.h"
00017 #include "Body.h"
00018 #include "Wheel.h"
00019 #include "Car.h"
00020 #include "Geom.h"
00021 #include "Main.h"
00022 #include "Control.h"
00023 #ifdef _PC
00024 #include "Ghost.h"
00025 #include "panel.h"
00026 #endif
00027 #ifdef _N64
00028 #include "gfx.h"
00029 #endif
00030
00031
00032
00033 unsigned long TimerLast, TimerDiff, TimerFreq, TotalRaceTime, TotalRaceStartTime, CountdownTime, CountdownEndTime;
00034 #ifdef _PC
00035 unsigned long TimerCurrent = CurrentTimer();
00036 #else
00037 unsigned long TimerCurrent = 0;
00038 #endif
00039 long TimeQueue, TimeLoopCount;
00040 RECORD_ENTRY TrackRecords;
00041
00042 static long RecordLapFlag[MAX_RECORD_TIMES];
00043 static long RecordRaceFlag[MAX_RECORD_TIMES];
00044
00045
00047
00049
00050 #ifdef _N64
00051 void UpdateTimeFactor(void)
00052 {
00053
00054
00055 TimerLast = TimerCurrent;
00056 TimerCurrent = CurrentTimer();
00057 TimerDiff = TimerCurrent - TimerLast;
00058
00059
00060 TimeFactor = (REAL)(TimerDiff) / 1000 * 60;
00061 if (TimeFactor > 15) TimeFactor = 15;
00062
00063 TimeStep = TimeFactor / PhysicalFramesPerSecond;
00064 }
00065 #endif
00066
00067 #ifdef _PC
00068 void UpdateTimeFactor(void)
00069 {
00070
00071
00072
00073 #if RECORD_AVI
00074 TimerDiff = MS2TIME(1000 / 30);
00075
00076 TimerLast = TimerCurrent;
00077 TimerCurrent += TimerDiff;
00078 #else
00079 TimerLast = TimerCurrent;
00080 TimerCurrent = CurrentTimer();
00081 TimerDiff = TimerCurrent - TimerLast;
00082 #endif
00083
00084
00085
00086 TimeQueue += TimerDiff;
00087 TimeLoopCount = TimeQueue / (TimerFreq / 72);
00088 TimeQueue %= (TimerFreq / 72);
00089 if (TimeLoopCount > 10) TimeLoopCount = 10;
00090
00091
00092
00093 TimeFactor = (float)(TimerDiff) / ((float)TimerFreq / 72.0f);
00094 if (TimeFactor > 10) TimeFactor = 10;
00095
00096
00097
00098 #if FIXED_TIME_STEP
00099
00100 TimeStep = (REAL)1.0f / 100.0f;
00101 #else
00102 TimeStep = TimeFactor / 72.0f;
00103 #endif
00104 }
00105 #endif
00106
00107
00109
00111
00112 #ifdef _PC
00113 unsigned long CurrentTimer(void)
00114 {
00115 LARGE_INTEGER time;
00116 QueryPerformanceCounter(&time);
00117 return time.LowPart;
00118 }
00119 #endif
00120
00121 #ifdef _N64
00122 unsigned long CurrentTimer(void)
00123 {
00124 return(OS_CYCLES_TO_USEC(osGetTime()) / 1000);
00125 }
00126 #endif
00128 // update race timers //
00130
00131 void UpdateRaceTimers(void)
00132 {
00133 unsigned long time, countdown;
00134 CAR *car;
00135 PLAYER *player;
00136
00137
00138
00139 time = TimerCurrent;
00140
00141
00142
00143 if (CountdownTime)
00144 {
00145 countdown = (CountdownEndTime - time);
00146 CountdownTime = TIME2MS(countdown);
00147
00148 if (countdown & 0x80000000)
00149 {
00150 TotalRaceStartTime = time + countdown;
00151 CountdownTime = 0;
00152
00153 for (player = PLR_PlayerHead ; player ; player = player->next)
00154 {
00155 player->car.CurrentLapStartTime = TotalRaceStartTime;
00156 }
00157 }
00158 return;
00159 }
00160
00161
00162
00163 #if RECORD_AVI
00164 TotalRaceTime += (1000 / 30);
00165 #else
00166 if (GameSettings.Paws) TotalRaceStartTime += TimerDiff;
00167 TotalRaceTime = TIME2MS(time - TotalRaceStartTime);
00168 #endif
00169
00170
00171
00172 for (player = PLR_PlayerHead ; player ; player = player->next)
00173 {
00174 car = &player->car;
00175
00176 switch (player->type)
00177 {
00178
00179
00180
00181 case PLAYER_LOCAL:
00182
00183
00184
00185 #if RECORD_AVI
00186 car->CurrentLapTime += (1000 / 30);
00187 #else
00188 if (GameSettings.Paws) car->CurrentLapStartTime += TimerDiff;
00189 car->CurrentLapTime = TIME2MS(time - car->CurrentLapStartTime);
00190 #endif
00191
00192
00193
00194 if (UpdateCarAiZone(player))
00195 {
00196
00197
00198
00199 TriggerSplit(player, 0, -1, &LookVec);
00200
00201
00202
00203 car->Laps++;
00204 car->NextSplit = 0;
00205
00206 car->LastLapTime = car->CurrentLapTime;
00207 car->CurrentLapTime = 0;
00208 car->CurrentLapStartTime = time;
00209
00210
00211
00212 #ifdef _PC
00213 EndGhostData(PLR_LocalPlayer);
00214 #endif
00215
00216
00217
00218 if (car->LastLapTime < car->BestLapTime)
00219 car->BestLapTime = car->LastLapTime;
00220
00221 if (car->AllowedBestTime) {
00222 CheckForBestLap(car);
00223 }
00224
00225
00226 #ifdef _PC
00227 InitGhostData(PLR_LocalPlayer);
00228 InitBestGhostData();
00229 #endif
00230
00231
00232 if (car->Laps == 5)
00233 {
00234 car->LastRaceTime = TotalRaceTime;
00235 TotalRaceTime = 0;
00236 TotalRaceStartTime = time;
00237
00238 if (car->LastRaceTime < car->BestRaceTime)
00239 car->BestRaceTime = car->LastRaceTime;
00240
00241 if (car->AllowedBestTime) {
00242 CheckForBestRace(car);
00243 }
00244 }
00245
00246 }
00247
00248 break;
00249
00250
00251
00252 #ifdef _PC
00253 case PLAYER_GHOST:
00254
00255 if (Keys[DIK_6]) {
00256 if (Keys[DIK_LSHIFT]) {
00257 car->CurrentLapStartTime -= TimerDiff;
00258 } else {
00259 car->CurrentLapStartTime += TimerDiff;
00260 }
00261 }
00262 if (Keys[DIK_7]) {
00263 car->CurrentLapStartTime += TimerDiff * 2;
00264 }
00265
00266 #if RECORD_AVI
00267 car->CurrentLapTime += (1000 / 30);
00268 #else
00269 if (GameSettings.Paws) car->CurrentLapStartTime += TimerDiff;
00270 car->CurrentLapTime = TIME2MS(time - car->CurrentLapStartTime);
00271 #endif
00272
00273 break;
00274 #endif
00275
00276
00277
00278 case PLAYER_CPU:
00279 break;
00280
00281
00282
00283 default:
00284 break;
00285
00286 }
00287 }
00288 }
00289
00291
00293
00294 void CheckForBestLap(CAR *car)
00295 {
00296 bool newGhostCar;
00297 unsigned long i, j;
00298
00299
00300 #ifdef _PC
00301 if (car->LastLapTime < GHO_BestGhostInfo->Time[GHOST_LAP_TIME]) {
00302 newGhostCar = TRUE;
00303 } else {
00304 newGhostCar = FALSE;
00305 }
00306 #endif
00307
00308
00309 for (i = 0 ; i < MAX_RECORD_TIMES ; i++)
00310 {
00311
00312
00313
00314 if (car->LastLapTime < TrackRecords.RecordLap[i].Time)
00315 {
00316
00317
00318
00319 #ifdef _PC
00320 PlaySfx(SFX_RECORD, SFX_MAX_VOL, SFX_CENTRE_PAN, 22050);
00321 #endif
00322 for (j = MAX_RECORD_TIMES - 1 ; j > i ; j--)
00323 {
00324 TrackRecords.RecordLap[j] = TrackRecords.RecordLap[j - 1];
00325 RecordLapFlag[j] = RecordLapFlag[j - 1];
00326 }
00327
00328
00329
00330 TrackRecords.RecordLap[i].Time = car->LastLapTime;
00331 memcpy(TrackRecords.RecordLap[i].Car, CarInfo[car->CarID].Name, CAR_NAMELEN);
00332 #ifdef _PC
00333 memcpy(TrackRecords.RecordLap[i].Player, RegistrySettings.PlayerName, MAX_PLAYER_NAME);
00334 #endif
00335 RecordLapFlag[i] = TRUE;
00336
00337
00338
00339 if (i == 0)
00340 {
00341 for (j = 0 ; j < MAX_SPLIT_TIMES ; j++)
00342 TrackRecords.SplitTime[j] = car->SplitTime[j];
00343
00344 newGhostCar = TRUE;
00345 }
00346
00347 break;
00348 }
00349 }
00350
00351
00352 #ifdef _PC
00353 if (newGhostCar || !GHO_GhostExists) {
00354 SwitchGhostDataStores();
00355 }
00356 #endif
00357 }
00358
00360
00362
00363 void CheckForBestRace(CAR *car)
00364 {
00365 unsigned long i, j;
00366
00367
00368
00369 for (i = 0 ; i < MAX_RECORD_TIMES ; i++)
00370 {
00371
00372
00373
00374 if (car->LastRaceTime < TrackRecords.RecordRace[i].Time)
00375 {
00376
00377
00378
00379 for (j = MAX_RECORD_TIMES - 1 ; j > i ; j--)
00380 {
00381 TrackRecords.RecordRace[j] = TrackRecords.RecordRace[j - 1];
00382 RecordRaceFlag[j] = RecordRaceFlag[j - 1];
00383 }
00384
00385
00386
00387 TrackRecords.RecordRace[i].Time = car->LastRaceTime;
00388 memcpy(TrackRecords.RecordRace[i].Car, CarInfo[car->CarID].Name, CAR_NAMELEN);
00389 #ifdef _PC
00390 memcpy(TrackRecords.RecordRace[i].Player, RegistrySettings.PlayerName, MAX_PLAYER_NAME);
00391 #endif
00392 RecordRaceFlag[i] = TRUE;
00393
00394 break;
00395 }
00396 }
00397 }
00398
00399
00400 #ifdef _PC
00402 // load track times //
00404
00405 void LoadTrackTimes(LEVELINFO *lev)
00406 {
00407 long i;
00408 FILE *fp;
00409
00410
00411
00412 for (i = 0 ; i < MAX_SPLIT_TIMES ; i++)
00413 {
00414 TrackRecords.SplitTime[i] = MAKE_TIME(60, 0, 0);
00415 }
00416
00417 for (i = 0 ; i < MAX_RECORD_TIMES ; i++)
00418 {
00419 TrackRecords.RecordLap[i].Time = MAKE_TIME(5, 0, 0);
00420 wsprintf(TrackRecords.RecordLap[i].Player, "Player");
00421 wsprintf(TrackRecords.RecordLap[i].Car, "Car");
00422
00423 TrackRecords.RecordRace[i].Time = MAKE_TIME(60, 0, 0);
00424 wsprintf(TrackRecords.RecordRace[i].Player, "Player");
00425 wsprintf(TrackRecords.RecordRace[i].Car, "Car");
00426
00427 RecordLapFlag[i] = FALSE;
00428 RecordRaceFlag[i] = FALSE;
00429 }
00430
00431
00432
00433 if (GameSettings.Mirrored)
00434 fp = fopen(GetLevelFilename(RECORDS_FILENAME_MIRRORED, FILENAME_GAME_SETTINGS), "rb");
00435 else
00436 fp = fopen(GetLevelFilename(RECORDS_FILENAME, FILENAME_GAME_SETTINGS), "rb");
00437 if (!fp) return;
00438
00439 fread(&TrackRecords, sizeof(TrackRecords), 1, fp);
00440 fclose(fp);
00441 }
00442
00444
00446
00447 void SaveTrackTimes(LEVELINFO *lev)
00448 {
00449 long j, k, l, update, updateGhost;
00450 FILE *fp;
00451 char buf[128];
00452 RECORD_ENTRY record;
00453
00454
00455
00456 if (GameSettings.Mirrored)
00457 fp = fopen(GetLevelFilename(RECORDS_FILENAME_MIRRORED, FILENAME_GAME_SETTINGS), "rb+");
00458 else
00459 fp = fopen(GetLevelFilename(RECORDS_FILENAME, FILENAME_GAME_SETTINGS), "rb+");
00460
00461
00462
00463 if (!fp)
00464 {
00465 if (GameSettings.Mirrored)
00466 fp = fopen(GetLevelFilename(RECORDS_FILENAME_MIRRORED, FILENAME_GAME_SETTINGS), "wb");
00467 else
00468 fp = fopen(GetLevelFilename(RECORDS_FILENAME, FILENAME_GAME_SETTINGS), "wb");
00469
00470
00471 if (!fp)
00472 {
00473 Box(buf, "Failed to create record file", MB_OK);
00474 return;
00475 }
00476
00477 fwrite(&TrackRecords, sizeof(TrackRecords), 1, fp);
00478 fclose(fp);
00479 SaveGhostData(lev);
00480 return;
00481 }
00482
00483
00484
00485 updateGhost = FALSE;
00486 update = FALSE;
00487 fread(&record, sizeof(record), 1, fp);
00488
00489
00490
00491 for (j = 0 ; j < MAX_RECORD_TIMES ; j++)
00492 {
00493 if (RecordLapFlag[j])
00494 {
00495 RecordLapFlag[j] = FALSE;
00496
00497 for (k = 0 ; k < MAX_RECORD_TIMES ; k++)
00498 {
00499 if (TrackRecords.RecordLap[j].Time < record.RecordLap[k].Time)
00500 {
00501 for (l = MAX_RECORD_TIMES - 1 ; l > k ; l--) record.RecordLap[l] = record.RecordLap[l - 1];
00502 record.RecordLap[k] = TrackRecords.RecordLap[j];
00503 update = TRUE;
00504
00505
00506
00507 if (k == 0)
00508 {
00509 for (l = 0 ; l < MAX_SPLIT_TIMES ; l++)
00510 record.SplitTime[l] = TrackRecords.SplitTime[l];
00511
00512 updateGhost = TRUE;
00513 }
00514 break;
00515 }
00516 }
00517 }
00518 }
00519
00520
00521
00522 for (j = 0 ; j < MAX_RECORD_TIMES ; j++)
00523 {
00524 if (RecordRaceFlag[j])
00525 {
00526 RecordRaceFlag[j] = FALSE;
00527
00528 for (k = 0 ; k < MAX_RECORD_TIMES ; k++)
00529 {
00530 if (TrackRecords.RecordRace[j].Time < record.RecordRace[k].Time)
00531 {
00532 for (l = MAX_RECORD_TIMES - 1 ; l > k ; l--) record.RecordRace[l] = record.RecordRace[l - 1];
00533 record.RecordRace[k] = TrackRecords.RecordRace[j];
00534 update = TRUE;
00535 break;
00536 }
00537 }
00538 }
00539 }
00540
00541
00542
00543 if (update)
00544 {
00545 fseek(fp, 0, SEEK_SET);
00546 fwrite(&record, sizeof(record), 1, fp);
00547 }
00548
00549
00550
00551 fclose(fp);
00552
00553
00554
00555 if (updateGhost)
00556 {
00557 SaveGhostData(&LevelInf[GameSettings.Level]);
00558 } else {
00559 LoadGhostData(&LevelInf[GameSettings.Level]);
00560 }
00561 }
00562
00563 #endif