00001
00002 #include "revolt.h"
00003 #include "panel.h"
00004 #include "ctrlread.h"
00005 #include "object.h"
00006 #include "player.h"
00007 #include "timing.h"
00008 #include "geom.h"
00009 #include "trigger.h"
00010 #include "text.h"
00011 #include "input.h"
00012 #include "camera.h"
00013
00014
00015
00016 #if USE_DEBUG_ROUTINES
00017 extern VEC DEBUG_DownForce;
00018 #endif
00019
00020
00021 long SpeedUnits = SPEED_MPH;
00022
00023 static long TrackDirType;
00024 static long TrackDirCount = 0;
00025 static long DisplaySplitTime;
00026 static float DisplaySplitCount;
00027 static long RevLit[REV_LIT_MAX];
00028 static long WrongWayFlag;
00029 static float WrongWayTimer;
00030
00031 static char *SpeedUnitText[SPEED_NTYPES] = {
00032 "mph",
00033 "fpm",
00034 "kph"
00035 };
00036 static REAL SpeedUnitScale[SPEED_NTYPES] = {
00037 OGU2MPH_SPEED,
00038 OGU2FPM_SPEED,
00039 OGU2KPH_SPEED
00040 };
00041
00042 static MAP_INFO MapInfo[] = {
00043 {"MARKET1", 24.0f, 400.0f, 0.01f, 0.01f, 0.0f, 128.0f, 64.0f, 64.0f},
00044
00045 {""},
00046 };
00047
00048
00049
00050 static float TrackDirUV[] = {
00051 128, 0, -64, 64,
00052 64, 0, -64, 64,
00053 128, 64, -64, 62,
00054 256, 0, -64, 64,
00055 64, 0, 64, 64,
00056 0, 0, 64, 64,
00057 64, 64, 64, 62,
00058 192, 0, 64, 64,
00059 0, 64, 64, 62,
00060 128, 0, 64, 64,
00061 192, 64, 64, 62,
00062 };
00063
00064
00065
00066 static float RevsUV[] = {
00067 143, 128, 15, 14,
00068 119, 128, 16, 16,
00069 95, 128, 19, 18,
00070 71, 128, 19, 19,
00071 47, 128, 21, 21,
00072 23, 128, 22, 22,
00073 0, 128, 22, 24,
00074 };
00075
00076
00077
00078 static float RevsPositions[] = {
00079 492, 451,
00080 502, 435,
00081 517, 422,
00082 536, 412,
00083 558, 405,
00084 581, 400,
00085 606, 399,
00086 };
00087
00088
00089
00090 static float PickupUV[] = {
00091 0, 224,
00092 64, 224,
00093 96, 224,
00094 32, 224,
00095 128, 224,
00096 224, 224,
00097 192, 224,
00098 0, 192,
00099 32, 192,
00100 };
00101
00103
00105
00106 void TriggerSplit(PLAYER *player, long flag, long n, VEC *vec)
00107 {
00108 CAR *car;
00109
00110
00111
00112 if (player != PLR_LocalPlayer)
00113 return;
00114
00115 car = &player->car;
00116
00117
00118
00119 if (n == -1)
00120 {
00121 DisplaySplitCount = SPLIT_COUNT;
00122 DisplaySplitTime = car->CurrentLapTime - TrackRecords.RecordLap[0].Time;
00123 car->NextSplit++;
00124 }
00125
00126
00127
00128 if (n >= MAX_SPLIT_TIMES)
00129 return;
00130
00131
00132
00133 if (n != car->NextSplit)
00134 return;
00135
00136
00137
00138 car->SplitTime[n] = car->CurrentLapTime;
00139
00140
00141
00142 DisplaySplitCount = SPLIT_COUNT;
00143 DisplaySplitTime = car->SplitTime[n] - TrackRecords.SplitTime[n];
00144 car->NextSplit++;
00145 }
00146
00148
00150
00151 void TriggerTrackDir(PLAYER *player, long flag, long n, VEC *vec)
00152 {
00153
00154
00155
00156 if (player != PLR_LocalPlayer)
00157 return;
00158
00159
00160
00161 if (!(flag & TRIGGER_GLOBAL_FIRST))
00162 return;
00163
00164
00165
00166 TrackDirType = n;
00167 TrackDirCount = TRACK_DIR_COUNT;
00168 }
00169
00171
00173
00174 static void EditRevsPos(void)
00175 {
00176 long i;
00177 char buf[128];
00178 static long edit = 0;
00179
00180 if (Keys[DIK_MINUS] && !LastKeys[DIK_MINUS] && edit > 0) edit--;
00181 if (Keys[DIK_EQUALS] && !LastKeys[DIK_EQUALS] && edit < 6) edit++;
00182
00183 if (Keys[DIK_LEFT] && !LastKeys[DIK_LEFT]) RevsPositions[edit * 2]--;
00184 if (Keys[DIK_RIGHT] && !LastKeys[DIK_RIGHT]) RevsPositions[edit * 2]++;
00185
00186 if (Keys[DIK_UP] && !LastKeys[DIK_UP]) RevsPositions[edit * 2 + 1]--;
00187 if (Keys[DIK_DOWN] && !LastKeys[DIK_DOWN]) RevsPositions[edit * 2 + 1]++;
00188
00189 SET_TPAGE(TPAGE_FONT);
00190
00191 for (i = 0 ; i < 7 ; i++)
00192 {
00193 wsprintf(buf, "%d = %d, %d", i, (long)RevsPositions[i * 2], (long)RevsPositions[i * 2 + 1]);
00194 DumpText(0, i * 32, 24, 32, 0xffffffff, buf);
00195 }
00196
00197 SET_TPAGE(TPAGE_FX2);
00198 }
00199
00201
00203
00204 void DrawControlPanel(void)
00205 {
00206 float x, y, xsize, ysize, tu, tv, twidth, theight, *p, frevs, dist;
00207 long i, col, speed, revs, revdest, revper, revadd, pickup, pickup2;
00208 char buf[128];
00209 PLAYER *player;
00210
00211
00212
00213 if (CAM_MainCamera->Type == CAM_EDIT)
00214 return;
00215
00216
00217
00218 ZBUFFER_OFF();
00219
00220 ALPHA_ON();
00221 ALPHA_SRC(D3DBLEND_SRCALPHA);
00222 ALPHA_DEST(D3DBLEND_INVSRCALPHA);
00223
00224
00225
00226 SET_TPAGE(TPAGE_FX1);
00227
00228
00229
00230 DrawPanelSprite(16, 368, 96, 96, 1.0f / 256.0f, 129.0f / 256.0f, 62.0f / 256.0f, 62.0f / 256.0f, 0xc0ffffff);
00231 for (player = PLR_PlayerHead ; player ; player = player->next)
00232 {
00233 dist = player->CarAI.FinishDistPanel * RAD;
00234
00235 x = -(float)sin(dist) * 46.0f + 58.0f;
00236 y = -(float)cos(dist) * 46.0f + 412.0f;
00237
00238 tu = 208.0f / 256.0f;
00239 tv = 216.0f / 256.0f;
00240
00241 DrawPanelSprite(x, y, 10.0f, 10.0f, tu, tv, 8.0f / 256.0f, 8.0f / 256.0f, 0xc0ffffff);
00242 }
00243
00244
00245
00246 SET_TPAGE(TPAGE_FX2);
00247
00248
00249
00250 if (WrongWayFlag != PLR_LocalPlayer->CarAI.WrongWay)
00251 WrongWayTimer += TimeStep;
00252 else
00253 WrongWayTimer = 0.0f;
00254
00255 if (WrongWayTimer >= WRONG_WAY_TOLERANCE) WrongWayFlag = !WrongWayFlag;
00256
00257 if (WrongWayFlag && TIME2MS(TimerCurrent) & 256)
00258 {
00259 DrawPanelSprite(256, 0, 128, 128, 128.0f / 256.0f, 64.0f / 256.0f, 64.0f / 256.0f, 64.0f / 256.0f, 0xc0ffffff);
00260 }
00261
00262
00263
00264 if (TrackDirCount)
00265 {
00266 if (!WrongWayFlag)
00267 {
00268 p = &TrackDirUV[TrackDirType * 4];
00269 tu = *p++ / 256.0f;
00270 tv = *p++ / 256.0f;
00271 twidth = *p++ / 256.0f;
00272 theight = *p++ / 256.0f;
00273
00274 if (TrackDirCount > TRACK_DIR_COUNT - TRACK_DIR_FADE_COUNT) col = (TRACK_DIR_COUNT - TrackDirCount) << 25;
00275 else if (TrackDirCount < TRACK_DIR_FADE_COUNT) col = (TrackDirCount) << 25;
00276 else col = 255 << 24;
00277 col |= 0xffffff;
00278
00279 DrawPanelSprite(256, 0, 128, 128, tu, tv, twidth, theight, col);
00280 }
00281
00282 if ((TrackDirCount -= (long)(TimeFactor * 10)) < 0) TrackDirCount = 0;
00283 }
00284
00285
00286
00287 frevs = abs(PLR_LocalPlayer->car.Revs / PLR_LocalPlayer->car.MaxRevs);
00288 FTOL(frevs, revs);
00289 FTOL((frevs - (float)revs) * REV_LIT_MAX, revper);
00290 FTOL(TimeStep * 1024, revadd);
00291
00292 for (i = 0 ; i < REV_LIT_NUM ; i++)
00293 {
00294 if (revs > i) revdest = REV_LIT_MAX;
00295 else if (revs < i) revdest = 0;
00296 else revdest = revper;
00297
00298 if (RevLit[i] < revdest)
00299 {
00300 RevLit[i] += revadd * 4;
00301 if (RevLit[i] > REV_LIT_MAX) RevLit[i] = REV_LIT_MAX;
00302 }
00303 else if (RevLit[i] > revdest)
00304 {
00305 RevLit[i] -= revadd;
00306 if (RevLit[i] < 0) RevLit[i] = 0;
00307 }
00308 }
00309
00310 p = RevsUV;
00311
00312 for (i = 0 ; i < REV_LIT_NUM ; i++)
00313 {
00314 tu = *p++ / 256.0f;
00315 tv = *p++ / 256.0f;
00316 twidth = *p++ / 256.0f;
00317 theight = *p++ / 256.0f;
00318
00319 x = RevsPositions[i * 2];
00320 y = RevsPositions[i * 2 + 1];
00321
00322 xsize = twidth * 256;
00323 ysize = theight * 256;
00324
00325 if (!RevLit[i])
00326 DrawPanelSprite(x, y, xsize, ysize, tu, tv, twidth, theight, 0xc0ffffff);
00327 else if (RevLit[i] == REV_LIT_MAX)
00328 DrawPanelSprite(x, y, xsize, ysize, tu, tv + (25.0f / 256.0f), twidth, theight, 0xc0ffffff);
00329 else
00330 {
00331 col = RevLit[i] * 0xc0 / REV_LIT_MAX;
00332 DrawPanelSprite(x, y, xsize, ysize, tu, tv, twidth, theight, ((0xc0 - col) << 24) | 0xffffff);
00333 DrawPanelSprite(x, y, xsize, ysize, tu, tv + (25.0f / 256.0f), twidth, theight, (col << 24) | 0xffffff);
00334 }
00335 }
00336
00337
00338
00339 DrawPanelSprite(4, 56, 64, 64, 190.0f / 256.0f, 157.0f / 256.0f, 64.0f / 256.0f, 64.0f / 256.0f, 0xe0ffffff);
00340
00341 if (PLR_LocalPlayer->PickupCycleSpeed)
00342 {
00343 pickup = (long)PLR_LocalPlayer->PickupCycleType;
00344 pickup2 = (pickup + 1) % PICKUP_NUM;
00345
00346 FTOL((PLR_LocalPlayer->PickupCycleType - (float)pickup) * 255.0f, col);
00347 col |= (col << 8) | (col << 16);
00348 }
00349 else if (PLR_LocalPlayer->PickupNum)
00350 {
00351 pickup = PLR_LocalPlayer->PickupType;
00352 col = 0;
00353 }
00354 else
00355 {
00356 pickup = -1;
00357 }
00358
00359 if (pickup != -1)
00360 {
00361 ALPHA_SRC(D3DBLEND_ONE);
00362 ALPHA_DEST(D3DBLEND_ONE);
00363
00364 tu = (PickupUV[pickup * 2]) / 256.0f;
00365 tv = (PickupUV[pickup * 2 + 1]) / 256.0f;
00366 DrawPanelSprite(20, 72, 32, 32, tu, tv, 32.0f / 256.0f, 32.0f / 256.0f, 0xffffff - col);
00367
00368 if (col)
00369 {
00370 tu = (PickupUV[pickup2 * 2]) / 256.0f;
00371 tv = (PickupUV[pickup2 * 2 + 1]) / 256.0f;
00372 DrawPanelSprite(20, 72, 32, 32, tu, tv, 32.0f / 256.0f, 32.0f / 256.0f, col);
00373 }
00374
00375 ALPHA_SRC(D3DBLEND_SRCALPHA);
00376 ALPHA_DEST(D3DBLEND_INVSRCALPHA);
00377 }
00378
00379
00380
00381 SET_TPAGE(TPAGE_BIGFONT);
00382
00383
00384
00385 if (CountdownTime && CountdownTime < (1000 * 3))
00386 {
00387 wsprintf(buf, "%d", (CountdownTime / 1000 + 1));
00388 DumpBigText(224, 0, 192, 256, 0xc0ffffff, buf);
00389 }
00390
00391
00392
00393 SET_TPAGE(TPAGE_FONT);
00394
00395
00396
00397 if (DisplaySplitCount)
00398 {
00399 DisplaySplitCount -= TimeStep;
00400 if (DisplaySplitCount < 0) DisplaySplitCount = 0;
00401
00402 DumpText(290, 128, 12, 16, 0xc000ffff, "split");
00403 if (DisplaySplitTime > 0) wsprintf(buf, "+%02d:%02d:%03d", MINUTES(DisplaySplitTime), SECONDS(DisplaySplitTime), THOUSANDTHS(DisplaySplitTime));
00404 else wsprintf(buf, "-%02d:%02d:%03d", MINUTES(-DisplaySplitTime), SECONDS(-DisplaySplitTime), THOUSANDTHS(-DisplaySplitTime));
00405 DumpText(260, 144, 12, 16, 0xc0ffffff, buf);
00406 }
00407
00408
00409
00410 DumpText(588, 96, 12, 16, 0xc000ffff, "lap");
00411 wsprintf(buf, "%02d:%02d:%03d", MINUTES(PLR_LocalPlayer->car.CurrentLapTime), SECONDS(PLR_LocalPlayer->car.CurrentLapTime), THOUSANDTHS(PLR_LocalPlayer->car.CurrentLapTime));
00412 DumpText(516, 112, 12, 16, 0xc0ffffff, buf);
00413
00414
00415
00416 DumpText(576, 136, 12, 16, 0xc000ffff, "race");
00417 wsprintf(buf, "%02d:%02d:%03d", MINUTES(TotalRaceTime), SECONDS(TotalRaceTime), THOUSANDTHS(TotalRaceTime));
00418 DumpText(516, 152, 12, 16, 0xc0ffffff, buf);
00419
00420
00421
00422 DumpText(588, 448, 12, 16, 0xc000ffff, SpeedUnitText[SpeedUnits]);
00423 speed = (long)(SpeedUnitScale[SpeedUnits] * VecLen(&PLR_LocalPlayer->car.Body->Centre.Vel));
00424 wsprintf(buf, "%4d", speed);
00425 DumpText(528, 448, 12, 16, 0xc0ffffff, buf);
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441 DumpText(16, 16, 12, 16, 0xc000ffff, "lap");
00442 wsprintf(buf, "%d/%d", PLR_LocalPlayer->car.Laps + 1, 5);
00443 DumpText(16, 32, 12, 16, 0xc0ffffff, buf);
00444
00445
00446
00447 if (GameSettings.GameType != GAMETYPE_TRIAL)
00448 {
00449 DumpText(58, 416, 12, 16, 0xc0ffffff, "1");
00450 }
00451
00452
00453
00454 DumpText(528, 16, 12, 16, 0xc000ffff, "last lap");
00455 wsprintf(buf, "%02d:%02d:%03d", MINUTES(PLR_LocalPlayer->car.LastLapTime), SECONDS(PLR_LocalPlayer->car.LastLapTime), THOUSANDTHS(PLR_LocalPlayer->car.LastLapTime));
00456 DumpText(516, 32, 12, 16, 0xc0ffffff, buf);
00457
00458
00459
00460 DumpText(528, 56, 12, 16, 0xc000ffff, "best lap");
00461 wsprintf(buf, "%02d:%02d:%03d", MINUTES(PLR_LocalPlayer->car.BestLapTime), SECONDS(PLR_LocalPlayer->car.BestLapTime), THOUSANDTHS(PLR_LocalPlayer->car.BestLapTime));
00462 DumpText(516, 72, 12, 16, 0xc0ffffff, buf);
00463
00464
00465
00466 return;
00467 VEC vec;
00468 static VEC light = {0, 0, -128};
00469 static VEC tl = {-64, -64, 0};
00470 static VEC tr = {64, -64, 0};
00471 static VEC br = {64, 64, 0};
00472 static VEC bl = {-64, 64, 0};
00473 static float tu0, tv0, tu1, tv1, tu2, tv2, tu3, tv3;
00474
00475 if (Keys[DIK_LEFT]) light.v[X]--;
00476 if (Keys[DIK_RIGHT]) light.v[X]++;
00477 if (Keys[DIK_UP]) light.v[Y]--;
00478 if (Keys[DIK_DOWN]) light.v[Y]++;
00479
00480 SubVector(&tl, &light, &vec);
00481 NormalizeVector(&vec);
00482 tu0 = 0.0f / 256.0f - vec.v[X] / 64.0f;
00483 tv0 = 0.0f / 256.0f - vec.v[Y] / 64.0f;
00484
00485 SubVector(&tr, &light, &vec);
00486 NormalizeVector(&vec);
00487 tu1 = 64.0f / 256.0f - vec.v[X] / 64.0f;
00488 tv1 = 0.0f / 256.0f - vec.v[Y] / 64.0f;
00489
00490 SubVector(&br, &light, &vec);
00491 NormalizeVector(&vec);
00492 tu2 = 64.0f / 256.0f - vec.v[X] / 64.0f;
00493 tv2 = 64.0f / 256.0f - vec.v[Y] / 64.0f;
00494
00495 SubVector(&bl, &light, &vec);
00496 NormalizeVector(&vec);
00497 tu3 = 0.0f / 256.0f - vec.v[X] / 64.0f;
00498 tv3 = 64.0f / 256.0f - vec.v[Y] / 64.0f;
00499
00500 DrawVertsTEX2[0].sx = 128;
00501 DrawVertsTEX2[0].sy = 128;
00502 DrawVertsTEX2[0].sz = 0.01f;
00503 DrawVertsTEX2[0].rhw = 1;
00504 DrawVertsTEX2[0].color = 0x808080;
00505 DrawVertsTEX2[0].tu = 0.0f / 256.0f;
00506 DrawVertsTEX2[0].tv = 0.0f / 256.0f;
00507
00508 DrawVertsTEX2[1].sx = 256;
00509 DrawVertsTEX2[1].sy = 128;
00510 DrawVertsTEX2[1].sz = 0.01f;
00511 DrawVertsTEX2[1].rhw = 1;
00512 DrawVertsTEX2[1].color = 0x808080;
00513 DrawVertsTEX2[1].tu = 64.0f / 256.0f;
00514 DrawVertsTEX2[1].tv = 0.0f / 256.0f;
00515
00516 DrawVertsTEX2[2].sx = 256;
00517 DrawVertsTEX2[2].sy = 256;
00518 DrawVertsTEX2[2].sz = 0.01f;
00519 DrawVertsTEX2[2].rhw = 1;
00520 DrawVertsTEX2[2].color = 0x808080;
00521 DrawVertsTEX2[2].tu = 64.0f / 256.0f;
00522 DrawVertsTEX2[2].tv = 64.0f / 256.0f;
00523
00524 DrawVertsTEX2[3].sx = 128;
00525 DrawVertsTEX2[3].sy = 256;
00526 DrawVertsTEX2[3].sz = 0.01f;
00527 DrawVertsTEX2[3].rhw = 1;
00528 DrawVertsTEX2[3].color = 0x808080;
00529 DrawVertsTEX2[3].tu = 0.0f / 256.0f;
00530 DrawVertsTEX2[3].tv = 64.0f / 256.0f;
00531
00532 DrawVertsTEX2[0].tu2 = tu0;
00533 DrawVertsTEX2[0].tv2 = tv0;
00534
00535 DrawVertsTEX2[1].tu2 = tu1;
00536 DrawVertsTEX2[1].tv2 = tv1;
00537
00538 DrawVertsTEX2[2].tu2 = tu2;
00539 DrawVertsTEX2[2].tv2 = tv2;
00540
00541 DrawVertsTEX2[3].tu2 = tu3;
00542 DrawVertsTEX2[3].tv2 = tv3;
00543
00544 ALPHA_OFF();
00545 SET_TPAGE(TPAGE_FX1);
00546 SET_TPAGE2(TPAGE_FX1);
00547
00548 SET_STAGE_STATE(1, D3DTSS_TEXCOORDINDEX, 1);
00549 SET_STAGE_STATE(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
00550 SET_STAGE_STATE(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
00551 SET_STAGE_STATE(1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
00552
00553 D3Ddevice->DrawPrimitive(D3DPT_TRIANGLEFAN, FVF_TEX2, DrawVertsTEX2, 4, D3DDP_DONOTUPDATEEXTENTS);
00554
00555 SET_STAGE_STATE(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
00556 }
00557
00559
00561
00562 void DrawPanelSprite(float x, float y, float width, float height, float tu, float tv, float twidth, float theight, long rgba)
00563 {
00564 long i;
00565 float xstart, ystart, xsize, ysize;
00566
00567
00568
00569 xstart = x * RenderSettings.GeomScaleX + ScreenLeftClip;
00570 ystart = y * RenderSettings.GeomScaleY + ScreenTopClip;
00571
00572 xsize = width * RenderSettings.GeomScaleX;
00573 ysize = height * RenderSettings.GeomScaleY;
00574
00575
00576
00577 for (i = 0 ; i < 4 ; i++)
00578 {
00579 DrawVertsTEX1[i].color = rgba;
00580 DrawVertsTEX1[i].rhw = 1;
00581 }
00582
00583
00584
00585 DrawVertsTEX1[0].sx = DrawVertsTEX1[3].sx = xstart;
00586 DrawVertsTEX1[1].sx = DrawVertsTEX1[2].sx = xstart + xsize;
00587 DrawVertsTEX1[0].sy = DrawVertsTEX1[1].sy = ystart;
00588 DrawVertsTEX1[2].sy = DrawVertsTEX1[3].sy = ystart + ysize;
00589
00590
00591
00592 DrawVertsTEX1[0].tu = DrawVertsTEX1[3].tu = tu;
00593 DrawVertsTEX1[1].tu = DrawVertsTEX1[2].tu = tu + twidth;
00594 DrawVertsTEX1[0].tv = DrawVertsTEX1[1].tv = tv;
00595 DrawVertsTEX1[2].tv = DrawVertsTEX1[3].tv = tv + theight;
00596
00597
00598
00599 D3Ddevice->DrawPrimitive(D3DPT_TRIANGLEFAN, FVF_TEX1, DrawVertsTEX1, 4, D3DDP_DONOTUPDATEEXTENTS | D3DDP_DONOTCLIP);
00600 }