00001
00002
00004 #include "revolt.h"
00005 #include "draw.h"
00006 #include "main.h"
00007 #include "text.h"
00008 #include "input.h"
00009 #include "play.h"
00010 #include "model.h"
00011 #include "world.h"
00012 #include "texture.h"
00013 #include "geom.h"
00014 #include "camera.h"
00015 #include "Particle.h"
00016 #include "NewColl.h"
00017 #include "Body.h"
00018 #include "Aerial.h"
00019 #include "Wheel.h"
00020 #include "DrawObj.h"
00021 #include "visibox.h"
00022 #include "level.h"
00023 #include "ctrlread.h"
00024 #include "object.h"
00025 #include "player.h"
00026 #include "gameloop.h"
00027 #include "registry.h"
00028 #include "ghost.h"
00029 #include "ai.h"
00030 #ifdef _PC
00031 #include "spark.h"
00032 #endif
00033 #include "timing.h"
00034
00035 #include "Text.h"
00036 #include "TitleScreen.h"
00037 #include "Menu.h"
00038 #include "MenuData.h"
00039 #include "MenuText.h"
00040
00041
00043
00045 extern char MainMenuAllowed[];
00046 extern char *MainMenuText[];
00047 extern char *EditMenuText[];
00048 extern char *NoYesText[];
00049
00050 t_Menu *gMenu;
00051 t_Flag gFlag;
00052
00053 #define MENU_LIGHT_MAX 3
00054 t_Light gLight[MENU_LIGHT_MAX];
00055
00056 MODEL gModel[1];
00057
00058
00060
00062 #define TS_COORD_SCALE (Real(200))
00063
00064 t_CameraPos gCameraPositions[] =
00065 {
00066 {Real(-0.002),Real(-29.79),Real(1.885), Real(-0.002),Real(0.066),Real(4.37)},
00067 {Real(9.587),Real(7.127),Real(2.395), Real(16.676),Real(12.887),Real(1.849)},
00068 {Real(11.37),Real(-19.888),Real(5.72), Real(26.234),Real(-12.128),Real(3.72)},
00069 {Real(12.36),Real(-14.955),Real(5.257), Real(26.913),Real(-21.921),Real(3.951)},
00070 {Real(-13.194),Real(-1.497),Real(3.862), Real(-22.397),Real(-4.682),Real(6.635)},
00071 {Real(-15.784),Real(0.415),Real(2.86), Real(-23.098),Real(0.418),Real(4.835)},
00072 {Real(-14.642),Real(4.748),Real(5.062), Real(-21.258),Real(3.829),Real(5.873)},
00073 {Real(-14.086),Real(7.223),Real(3.014), Real(-22.498),Real(7.924),Real(4.835)},
00074 {Real(0.0),Real(0.042),Real(63.661), Real(0.0),Real(-0.361),Real(-0.748)},
00075
00076
00077 };
00078
00079 enum TS_CAMPOS
00080 {
00081 TS_CAMPOS_START,
00082 TS_CAMPOS_CAR_SELECT,
00083 TS_CAMPOS_TRACK_SELECT,
00084 TS_CAMPOS_USER_SELECT,
00085 TS_CAMPOS_TROPHY_1,
00086 TS_CAMPOS_TROPHY_2,
00087 TS_CAMPOS_TROPHY_3,
00088 TS_CAMPOS_TROPHY_4,
00089 TS_CAMPOS_OVER_VIEW,
00090 TS_CAMPOS_NUM
00091 };
00092
00093
00094
00096
00098 void GoTitleScreen(void)
00099 {
00100
00101 if (!InitD3D(DrawDevices[RegistrySettings.DrawDevice].DisplayMode[DisplayModeCount].Width, DrawDevices[RegistrySettings.DrawDevice].DisplayMode[DisplayModeCount].Height, DrawDevices[RegistrySettings.DrawDevice].DisplayMode[DisplayModeCount].Bpp, 0))
00102 {
00103 QuitGame = TRUE;
00104 return;
00105 }
00106
00107 GetTextureFormat(RegistrySettings.TextureBpp);
00108 InitTextures();
00109
00110
00111
00112 SetupDxState();
00113
00114
00115
00116 RenderSettings.GeomPers = BaseGeomPers;
00117
00118 SetNearFar(48.0f, 60000.0f);
00119 SetViewport(0, 0, (float)ScreenXsize, (float)ScreenYsize, RenderSettings.GeomPers);
00120
00121
00122
00123 LoadMipTexture("gfx\\font1.bmp", TPAGE_FONT, 256, 256, 0, 1);
00124
00125 LoadBitmap("gfx\\title.bmp", &TitleHbm);
00126
00127 MenuCount = 0;
00128 Event = TitleScreen;
00129
00130
00131
00132 InitFlag(&gFlag, 32,32, 10,10);
00133
00134
00135 SetLightPos(&gLight[0], 100,-100,-100);
00136 SetLightDir(&gLight[0], -0.5,1,0.5);
00137 SetLightPower(&gLight[0], 15);
00138 SetLightStrength(&gLight[0], 1000);
00139 SetLightRange(&gLight[0], 250);
00140
00141
00142 SetLightPos(&gLight[1], -200,-100,0);
00143 SetLightDir(&gLight[1], 1,1,0);
00144 SetLightPower(&gLight[1], 25);
00145 SetLightStrength(&gLight[1], 1250);
00146 SetLightRange(&gLight[1], 300);
00147
00148
00149 SetLightPos(&gLight[2], 0,100,150);
00150 SetLightDir(&gLight[2], 0,-4,-2);
00151 SetLightPower(&gLight[2], 30);
00152 SetLightStrength(&gLight[2], 500);
00153 SetLightRange(&gLight[2], 500);
00154
00155
00156
00157
00158
00159 gMenu = &gMainOptions_Menu;
00160 MenuInit(gMenu, NULL);
00161
00162
00163
00164
00165
00166
00167 LoadModel("models\\trolley.m", &gModel[0], 0,1, LOADMODEL_OFFSET_TPAGE, 100);
00168
00169
00170
00171 GameSettings.Level = GetLevelNum("FRONTEND");
00172 if (GameSettings.Level < 0)
00173 GameSettings.Level = 12;
00174 LEV_InitLevel();
00175
00176 ts_InitCameraPositions();
00177
00178
00179
00180
00181 }
00182
00184
00186 void ReleaseTitleScreen(void)
00187 {
00188 ReleaseFlag(&gFlag);
00189 FreeModel(&gModel[0], 1);
00190 LEV_EndLevel();
00191 }
00192
00193
00195
00197 void ts_InitCameraPositions(void)
00198 {
00199 t_CameraPos* pCamPos;
00200 MAT matrix;
00201 REAL y;
00202 int i;
00203
00204 pCamPos = gCameraPositions;
00205 for (i = 0; i < TS_CAMPOS_NUM; i++)
00206 {
00207 y = pCamPos->eye.v[1];
00208 pCamPos->eye.v[0] = MulScalar(TS_COORD_SCALE, pCamPos->eye.v[0]);
00209 pCamPos->eye.v[1] = MulScalar(TS_COORD_SCALE, -pCamPos->eye.v[2]);
00210 pCamPos->eye.v[2] = MulScalar(TS_COORD_SCALE, y);
00211
00212 y = pCamPos->focus.v[1];
00213 pCamPos->focus.v[0] = MulScalar(TS_COORD_SCALE, pCamPos->focus.v[0]);
00214 pCamPos->focus.v[1] = MulScalar(TS_COORD_SCALE, -pCamPos->focus.v[2]);
00215 pCamPos->focus.v[2] = MulScalar(TS_COORD_SCALE, y);
00216
00217 BuildLookMatrixForward(&pCamPos->eye, &pCamPos->focus, &matrix);
00218 MatToQuat(&matrix, &pCamPos->quat);
00219
00220 pCamPos++;
00221 }
00222 }
00223
00224
00226
00228 void TitleScreen(void)
00229 {
00230
00231
00232
00233 CheckSurfaces();
00234 FlipBuffers();
00235
00236
00237
00238
00239 InitRenderStates();
00240
00241
00242
00243 Reset3dPolyList();
00244 InitPolyBuckets();
00245
00246
00247 ReadMouse();
00248 ReadKeyboard();
00249 UpdateTimeFactor();
00250
00251
00252
00253
00254 D3Ddevice->BeginScene();
00255
00256
00257
00258 BeginTextState();
00259
00260
00261
00262 gMenu = MenuProcess(gMenu);
00263
00264
00265
00266
00267 int CameraCount = 0;
00268
00269 UpdateCamera(&Camera[CameraCount]);
00270
00271 static VEC camFocus = {5000,5000,0};
00272
00273
00274 if (Keys[DIK_NUMPAD4])
00275 camFocus.v[0] -= 100;
00276 if (Keys[DIK_NUMPAD6])
00277 camFocus.v[0] += 100;
00278 if (Keys[DIK_NUMPAD2])
00279 camFocus.v[2] -= 100;
00280 if (Keys[DIK_NUMPAD8])
00281 camFocus.v[2] += 100;
00282
00283 if (Keys[DIK_NUMPAD7])
00284 Camera[CameraCount].WPos.v[1] -= 100;
00285 if (Keys[DIK_NUMPAD9])
00286 Camera[CameraCount].WPos.v[1] += 100;
00287
00288
00289
00290 t_CameraPos* pCamPos;
00291 pCamPos = &gCameraPositions[0];
00292 Camera[CameraCount].WPos.v[0] = pCamPos->eye.v[0];
00293 Camera[CameraCount].WPos.v[1] = pCamPos->eye.v[1];
00294 Camera[CameraCount].WPos.v[2] = pCamPos->eye.v[2];
00295 camFocus.v[0] = pCamPos->focus.v[0];
00296 camFocus.v[1] = pCamPos->focus.v[1];
00297 camFocus.v[2] = pCamPos->focus.v[2];
00298
00299 QuatToMat(&pCamPos->quat, &Camera[CameraCount].WMatrix);
00300
00301
00302
00303 SetViewport(Camera[CameraCount].X, Camera[CameraCount].Y, Camera[CameraCount].Xsize, Camera[CameraCount].Ysize, BaseGeomPers + Camera[CameraCount].Lens);
00304 InitRenderStates();
00305 ClearBuffers();
00306
00307 SetCameraView(&Camera[CameraCount].WMatrix, &Camera[CameraCount].WPos, Camera[CameraCount].Shake);
00308 SetCameraVisiMask(&Camera[CameraCount].WPos);
00309
00310
00311
00312 ResetSemiList();
00313
00314
00315
00316
00317
00318
00319 {
00320 DrawWorld();
00321 DrawInstances();
00322 }
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 MAT camMat;
00336
00337 static VEC camPos = {0,0,-200};
00338 RotMatrixZYX(&camMat, (REAL)0/360,(REAL)0/360,(REAL)0/360);
00339 SetCameraView(&camMat, &camPos, 0);
00340
00341 static VEC modelRot = {0,0,0};
00342 MAT modelMat;
00343 VEC modelPos = {0,0,0};
00344 RotMatrixZYX(&modelMat, (REAL)modelRot.v[0]/360,(REAL)modelRot.v[1]/360,(REAL)modelRot.v[2]/360);
00345
00346
00347 modelRot.v[0] += 0;
00348 modelRot.v[1] += 10;
00349 modelRot.v[2] += 0;
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361 FlushPolyBuckets();
00362 FlushEnvBuckets();
00363
00364
00365
00366 if (gMenu)
00367 {
00368 BeginTextState();
00369 MenuRender(gMenu);
00370 }
00371
00372
00373 D3Ddevice->EndScene();
00374
00375
00376
00377 if (!gMenu)
00378 {
00379 ReleaseTitleScreen();
00380 Event = GoFront;
00381 }
00382 }
00383
00384
00386
00388 void SetLightPos(t_Light* pLight, REAL x, REAL y, REAL z)
00389 {
00390 pLight->pos.v[0] = x;
00391 pLight->pos.v[1] = y;
00392 pLight->pos.v[2] = z;
00393 }
00394
00395 void SetLightDir(t_Light* pLight, REAL x, REAL y, REAL z)
00396 {
00397 REAL l = MulScalar(x, x) + MulScalar(y, y) + MulScalar(z, z);
00398 if (l != (ONE*ONE))
00399 {
00400 l = ONE / (REAL)sqrt(l);
00401 x = MulScalar(x, l);
00402 y = MulScalar(y, l);
00403 z = MulScalar(z, l);
00404 }
00405
00406 pLight->dir.v[0] = x;
00407 pLight->dir.v[1] = y;
00408 pLight->dir.v[2] = z;
00409 }
00410
00411 void SetLightPower(t_Light* pLight, REAL power)
00412 {
00413 pLight->power = power;
00414 }
00415
00416 void SetLightStrength(t_Light* pLight, REAL strength)
00417 {
00418 pLight->strength = strength;
00419 }
00420
00421 void SetLightRange(t_Light* pLight, REAL range)
00422 {
00423 pLight->range = range;
00424 pLight->range2 = MulScalar(range, range);
00425 pLight->rangeInv = DivScalar(ONE, range);
00426 }
00427
00428
00430
00432 void InitFlag(t_Flag *pFlag, int w, int h, REAL sX, REAL sY)
00433 {
00434 REAL x, y, z, Dx, Dy, Dz;
00435 int cX, cY;
00436
00437
00438 pFlag->w = w;
00439 pFlag->h = h;
00440 pFlag->pPoints = (t_FlagPoint*)malloc(w * h * sizeof(t_FlagPoint));
00441
00442
00443 Dx = sX;
00444 Dy = 0;
00445 Dz = -sY;
00446
00447 y = 0;
00448 z = (h >> 1) * -Dz;
00449
00450 for (cY = 0; cY < h; cY++)
00451 {
00452 x = (w >> 1) * -Dx;
00453
00454 for (cX = 0; cX < w; cX++)
00455 {
00456 pFlag->pPoints[cX + (cY * w)].pos.v[0] = x;
00457 pFlag->pPoints[cX + (cY * w)].pos.v[1] = y;
00458 pFlag->pPoints[cX + (cY * w)].pos.v[2] = z;
00459
00460 pFlag->pPoints[cX + (cY * w)].u = 0;
00461 pFlag->pPoints[cX + (cY * w)].v = 0;
00462
00463 x += Dx;
00464 }
00465
00466 z += Dz;
00467 }
00468 }
00469
00471
00473 void ReleaseFlag(t_Flag *pFlag)
00474 {
00475 if (pFlag->pPoints)
00476 {
00477 free(pFlag->pPoints);
00478 pFlag->pPoints = NULL;
00479 }
00480 }
00481
00482
00484
00486 void RenderFlag(t_Flag *pFlag)
00487 {
00488 VERTEX_TEX1 v[64*64*2];
00489 VERTEX_TEX1 *pDV;
00490 t_FlagPoint *pSV;
00491 int cX, cY;
00492 int cL;
00493 int i;
00494 static rX = 25;
00495 static rY = 45;
00496 static rZ = 0;
00497
00498
00499
00500
00501 ZBUFFER_ON();
00502 ZWRITE_ON();
00503 ZCMP(D3DCMP_LESSEQUAL);
00504
00505
00506 CULL_OFF();
00507
00508 MAT viewMatrix;
00509 VEC viewPos;
00510 VEC tempPos;
00511 VEC tempPos2;
00512
00513 tempPos.v[0] = 0;
00514 tempPos.v[1] = -150;
00515 tempPos.v[2] = -750;
00516
00517 tempPos2.v[0] = 0;
00518 tempPos2.v[1] = 0;
00519 tempPos2.v[2] = 0;
00520
00521
00522 if (Keys[DIK_NUMPAD8])
00523 rX -= 10;
00524 if (Keys[DIK_NUMPAD2])
00525 rX += 10;
00526 if (Keys[DIK_NUMPAD4])
00527 rY -= 10;
00528 if (Keys[DIK_NUMPAD6])
00529 rY += 10;
00530
00531
00532 if (Keys[DIK_COMMA])
00533 gLight[0].strength -= 2;
00534
00535 if (Keys[DIK_PERIOD])
00536 gLight[0].strength += 2;
00537
00538 if (Keys[DIK_LBRACKET])
00539 gLight[0].power -= 1;
00540 if (Keys[DIK_RBRACKET])
00541 gLight[0].power += 1;
00542 if (gLight[0].power < 1)
00543 gLight[0].power = 1;
00544
00545 RotMatrixZYX(&viewMatrix, (REAL)rX/360,(REAL)rY/360,(REAL)rZ/360);
00546 RotTransVector(&viewMatrix, &tempPos2, &tempPos, &viewPos);
00547 SetCameraView(&viewMatrix, &viewPos, 0);
00548
00549
00550
00551 pSV = pFlag->pPoints;
00552 pDV = v;
00553 for (cY = 0; cY < pFlag->h; cY++)
00554 {
00555 for (cX = 0; cX < pFlag->w; cX++)
00556 {
00557 static VEC normal = {0,-1,0};
00558 VEC lightPullVec[MENU_LIGHT_MAX];
00559
00560 tempPos.v[0] = 0;
00561 tempPos.v[1] = 0;
00562 tempPos.v[2] = 0;
00563 for (cL = 0; cL < MENU_LIGHT_MAX; cL++)
00564 {
00565 ts_ApplyLightPull(&gLight[cL], &normal, &pSV->pos, &lightPullVec[cL]);
00566 VecPlusEqVec(&tempPos, &lightPullVec[cL]);
00567 }
00568
00569 tempPos.v[0] = MulScalar(tempPos.v[0], ONE/MENU_LIGHT_MAX);
00570 tempPos.v[1] = MulScalar(tempPos.v[1], ONE/MENU_LIGHT_MAX);
00571 tempPos.v[2] = MulScalar(tempPos.v[2], ONE/MENU_LIGHT_MAX);
00572
00573 RotTransPersVector(&ViewMatrixScaled, &ViewTransScaled, &tempPos, (float*)&pDV->sx);
00574
00575
00576
00577 pDV->tu = pSV->u;
00578 pDV->tv = pSV->v;
00579 pDV->color = 0xFFFFFF;
00580 pDV->specular = 0x000000;
00581
00582 #if 1
00583 #if 1
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595 int rgb[3];
00596 for (i = 0; i < 3; i++)
00597 {
00598
00599 rgb[i] = (int)((((tempPos.v[i]) / 320) * 255) + 128);
00600
00601 if (rgb[i] < 0) rgb[i] = 0;
00602 if (rgb[i] > 255) rgb[i] = 255;
00603 }
00604
00605
00606
00607 pDV->color = rgb[0] | (rgb[1] << 8) | (rgb[2] << 16);
00608 #else
00609 int f = (cX & 1) + ((cY & 1) << 1);
00610 switch (f)
00611 {
00612 case 0:
00613 pDV->color = 0x000000;
00614 break;
00615 case 1:
00616 pDV->color = 0x0000FF;
00617 break;
00618 case 2:
00619 pDV->color = 0x00FF00;
00620 break;
00621 case 3:
00622 pDV->color = 0xFF0000;
00623 break;
00624 }
00625 #endif
00626 #endif
00627
00628 pSV++;
00629 pDV++;
00630 }
00631 }
00632
00633
00634
00635 SET_TPAGE(-1);
00636
00637 pDV = v;
00638 for (cY = 0; cY < pFlag->h-1; cY++)
00639 {
00640 for (cX = 0; cX < pFlag->w-1; cX++)
00641 {
00642 DrawTriClip(&pDV[0], &pDV[1], &pDV[pFlag->w+1]);
00643 DrawTriClip(&pDV[0], &pDV[pFlag->w+1], &pDV[pFlag->w]);
00644 pDV++;
00645 }
00646
00647 pDV++;
00648 }
00649 }
00650
00651
00653
00655 void ts_ApplyLightPull(t_Light* pLight, VEC* pN, VEC* pS, VEC* pE)
00656 {
00657 REAL dotP;
00658 VEC delta;
00659 REAL l, lInv;
00660 REAL strength;
00661
00662 delta.v[0] = pS->v[0] - pLight->pos.v[0];
00663 delta.v[1] = pS->v[1] - pLight->pos.v[1];
00664 delta.v[2] = pS->v[2] - pLight->pos.v[2];
00665 l = MulScalar(delta.v[0], delta.v[0]) +
00666 MulScalar(delta.v[1], delta.v[1]) +
00667 MulScalar(delta.v[2], delta.v[2]);
00668
00669 if (l >= pLight->range2)
00670 {
00671 pE->v[0] = pS->v[0];
00672 pE->v[1] = pS->v[1];
00673 pE->v[2] = pS->v[2];
00674 return;
00675 }
00676
00677 l = (REAL)sqrt(l);
00678 lInv = ONE / l;
00679 delta.v[0] = MulScalar(delta.v[0], lInv);
00680 delta.v[1] = MulScalar(delta.v[1], lInv);
00681 delta.v[2] = MulScalar(delta.v[2], lInv);
00682
00683 dotP = MulScalar(pLight->dir.v[0], delta.v[0]) +
00684 MulScalar(pLight->dir.v[1], delta.v[1]) +
00685 MulScalar(pLight->dir.v[2], delta.v[2]);
00686
00687 if (dotP > 0)
00688 {
00689 strength = MulScalar(pLight->strength, ONE - MulScalar(l, pLight->rangeInv));
00690 dotP = ts_Power(dotP, pLight->power);
00691 dotP = MulScalar(dotP, strength);
00692
00693 pE->v[0] = pS->v[0] - MulScalar(dotP, pLight->dir.v[0]);
00694 pE->v[1] = pS->v[1] - MulScalar(dotP, pLight->dir.v[1]);
00695 pE->v[2] = pS->v[2] - MulScalar(dotP, pLight->dir.v[2]);
00696 }
00697 else
00698 {
00699 pE->v[0] = pS->v[0];
00700 pE->v[1] = pS->v[1];
00701 pE->v[2] = pS->v[2];
00702 }
00703
00704 CopyVec(&delta, pN);
00705 }
00706
00707
00709
00711 REAL ts_Power(REAL value, REAL power)
00712 {
00713 REAL denominator = power - MulScalar(power, value) + value;
00714 if (denominator == 0)
00715 return 0;
00716
00717 return (value / denominator);
00718 }