00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "revolt.h"
00018 #ifndef _PSX
00019 #include "main.h"
00020 #include "dx.h"
00021 #include "geom.h"
00022 #include "particle.h"
00023 #include "texture.h"
00024 #include "model.h"
00025 #include "aerial.h"
00026 #include "NewColl.h"
00027 #include "Body.h"
00028 #include "car.h"
00029 #include "camera.h"
00030 #include "light.h"
00031 #include "world.h"
00032 #include "draw.h"
00033 #include "visibox.h"
00034 #include "texture.h"
00035 #include "ctrlread.h"
00036 #include "object.h"
00037 #include "Control.h"
00038 #include "level.h"
00039 #include "player.h"
00040 #include "editobj.h"
00041 #include "instance.h"
00042 #include "editai.h"
00043 #include "editzone.h"
00044 #include "aizone.h"
00045 #include "registry.h"
00046 #include "field.h"
00047 #include "Ghost.h"
00048 #include "mirror.h"
00049 #include "timing.h"
00050 #include "trigger.h"
00051 #include "edittrig.h"
00052 #include "editcam.h"
00053 #include "edfield.h"
00054 #include "sfx.h"
00055 #include "aizone.h"
00056 #include "ainode.h"
00057 #include "input.h"
00058 #include "obj_init.h"
00059 #include "ai.h"
00060 #include "edportal.h"
00061 #endif
00062
00063 #ifdef _PC
00064 #include "spark.h"
00065 #endif
00066
00067
00068
00069
00070 static void s_LoadTrackData(void);
00071 static void LoadStaticLevelModels(void);
00072
00073
00074
00075
00076
00077 LEVELINFO *LevelInf;
00078 VEC LEV_StartPos;
00079 REAL LEV_StartRot;
00080 long LEV_StartGrid;
00081 VEC *LEV_LevelFieldPos = NULL;
00082 MAT *LEV_LevelFieldMat = NULL;
00083
00084 static char LevelFilenameBuffer[128];
00085
00086
00087
00088
00089 void LEV_InitLevel(void);
00090 void LEV_EndLevel(void);
00091
00093
00095
00096 static void LoadStaticLevelModels(void)
00097 {
00098 struct renderflags rflag;
00099
00100 LoadOneLevelModel(LEVEL_MODEL_PICKUP, FALSE, rflag, 0);
00101 LoadOneLevelModel(LEVEL_MODEL_FIREWORK, FALSE, rflag, TPAGE_FX1);
00102 LoadOneLevelModel(LEVEL_MODEL_WATERBOMB, FALSE, rflag, 0);
00103 LoadOneLevelModel(LEVEL_MODEL_CHROMEBALL, FALSE, rflag, 0);
00104 LoadOneLevelModel(LEVEL_MODEL_BOMBBALL, FALSE, rflag, 0);
00105 }
00106
00108
00110
00111 void LEV_InitLevel(void)
00112 {
00113
00114
00115 if (!OBJ_InitObjSys())
00116 {
00117 Box(NULL, "Can't initialise object system!", MB_OK);
00118 QuitGame = TRUE;
00119 return;
00120 }
00121
00122
00123 PLR_InitPlayers();
00124
00125
00126 InitLevelModels();
00127 LoadStaticLevelModels();
00128
00129
00130 SetNearFar(48.0f, LevelInf[GameSettings.Level].FarClip);
00131 SetFogVars(LevelInf[GameSettings.Level].FogStart, LevelInf[GameSettings.Level].VertFogStart, LevelInf[GameSettings.Level].VertFogEnd);
00132 FOG_COLOR(LevelInf[GameSettings.Level].FogColor);
00133 SetBackgroundColor(LevelInf[GameSettings.Level].FogColor);
00134
00135
00136 InitSparks();
00137
00138
00139 InitPolyBuckets();
00140
00141
00142 InitCameras();
00143 CAM_MainCamera = AddCamera(0, 0, 0, 0, CAMERA_FLAG_PRIMARY);
00144
00145
00146 ClearSkids();
00147
00148
00149 s_LoadTrackData();
00150
00151
00152 InitJumpSparkOffsets();
00153
00154
00155 FLD_GravityField = AddLinearField(FIELD_PARENT_NONE, FIELD_PRIORITY_MAX, &ZeroVector, &Identity, &FLD_GlobalBBox, &FLD_GlobalSize, &DownVec, FLD_Gravity, ZERO);
00156
00157
00158 GameSettings.Paws = FALSE;
00159 }
00160
00162
00164
00165 void LEV_EndLevel(void)
00166 {
00167
00168 DestroyCollGrids();
00169 DestroyCollPolys(COL_WorldCollPoly);
00170 COL_WorldCollPoly = NULL;
00171 COL_NWorldCollPolys = 0;
00172 DestroyCollPolys(COL_InstanceCollPoly);
00173 COL_InstanceCollPoly = NULL;
00174 COL_NInstanceCollPolys = 0;
00175
00176
00177 FreeForceFields();
00178
00179
00180 FreeTextures();
00181
00182
00183 FreeWorld();
00184
00185
00186
00187
00188
00189
00190 KillPolyBuckets();
00191
00192
00193 FreeMirrorPlanes();
00194
00195
00196 FreeInstanceRGBs();
00197 FreeInstanceModels();
00198
00199
00200 FreeSfx();
00201
00202
00203 FreeAiNodes();
00204
00205
00206 FreeAiZones();
00207
00208
00209 FreeTriggers();
00210
00211
00212 SaveTrackTimes(&LevelInf[GameSettings.Level]);
00213
00214
00215 if (AI_Testing)
00216 {
00217 FreeEditAiNodeModels();
00218 }
00219
00220 if (EditMode == EDIT_VISIBOXES)
00221 {
00222 if (!AI_Testing) FreeEditAiNodeModels();
00223 }
00224
00225 if (EditMode == EDIT_LIGHTS)
00226 {
00227 FreeEditLightModels();
00228 }
00229
00230 if (EditMode == EDIT_OBJECTS)
00231 {
00232 KillFileObjects();
00233 FreeFileObjectModels();
00234 }
00235
00236 if (EditMode == EDIT_AINODES)
00237 {
00238 KillEditAiNodes();
00239 if (!AI_Testing) FreeEditAiNodeModels();
00240 }
00241
00242 if (EditMode == EDIT_ZONES)
00243 {
00244 KillFileZones();
00245 if (!AI_Testing) FreeEditAiNodeModels();
00246 }
00247
00248 if (EditMode == EDIT_TRIGGERS)
00249 {
00250 KillFileTriggers();
00251 }
00252
00253 if (EditMode == EDIT_CAM)
00254 {
00255 KillEditCamNodes();
00256 FreeEditCamNodeModels();
00257 }
00258
00259 if (EditMode == EDIT_FIELDS)
00260 {
00261 KillFileFields();
00262 FreeFileFieldModels();
00263 }
00264
00265 if (EditMode == EDIT_PORTALS)
00266 {
00267 KillEditPortals();
00268 }
00269
00270
00271 FreeLevelModels();
00272
00273
00274 PLR_KillAllPlayers();
00275
00276
00277 OBJ_KillObjSys();
00278
00279
00280 GRD_FreeGrids();
00281 }
00282
00284
00286
00287 static void s_LoadTrackData(void)
00288 {
00289 char ii;
00290 char buf[128];
00291 FILE *fp;
00292
00293
00294 InitFields();
00295
00296
00297 if (GameSettings.Reversed)
00298 {
00299 LEV_StartPos = LevelInf[GameSettings.Level].ReverseStartPos;
00300 LEV_StartRot = LevelInf[GameSettings.Level].ReverseStartRot;
00301 LEV_StartGrid = LevelInf[GameSettings.Level].ReverseStartGrid;
00302 }
00303 else
00304 {
00305 LEV_StartPos = LevelInf[GameSettings.Level].NormalStartPos;
00306 LEV_StartRot = LevelInf[GameSettings.Level].NormalStartRot;
00307 LEV_StartGrid = LevelInf[GameSettings.Level].NormalStartGrid;
00308 }
00309
00310
00311 LoadMipTexture("gfx\\font1.bmp", TPAGE_FONT, 256, 256, 0, 1);
00312 LoadMipTexture("gfx\\font2.bmp", TPAGE_BIGFONT, 256, 256, 0, 1);
00313
00314 LoadTextureClever(LevelInf[GameSettings.Level].EnvStill, TPAGE_ENVSTILL, 256, 256, 0, FxTextureSet, TRUE);
00315 LoadTextureClever(LevelInf[GameSettings.Level].EnvRoll, TPAGE_ENVROLL, 256, 256, 0, FxTextureSet, TRUE);
00316 LoadTextureClever("gfx\\shadow.bmp", TPAGE_SHADOW, 256, 256, 0, FxTextureSet, TRUE);
00317
00318 LoadMipTexture("gfx\\fxpage1.bmp", TPAGE_FX1, 256, 256, 0, 1);
00319 LoadMipTexture("gfx\\fxpage2.bmp", TPAGE_FX2, 256, 256, 0, 1);
00320 LoadMipTexture("gfx\\fxpage3.bmp", TPAGE_FX3, 256, 256, 0, 1);
00321
00322
00323 for (ii = 0 ; ii < TPAGE_WORLD_NUM ; ii++)
00324 {
00325 wsprintf(buf, "levels\\%s\\%s%c.bmp", LevelInf[GameSettings.Level].Dir, LevelInf[GameSettings.Level].Dir, ii + 'a');
00326 LoadTextureClever(buf, ii, 256, 256, 0, WorldTextureSet, TRUE);
00327 }
00328
00329
00330 SetMirrorParams(&LevelInf[GameSettings.Level]);
00331 LoadWorld(GetLevelFilename("w", FILENAME_MAKE_BODY));
00332
00333
00334 InitVisiBoxes();
00335 LoadVisiBoxes(GetLevelFilename("vis", FILENAME_MAKE_BODY | FILENAME_GAME_SETTINGS));
00336 SetPermVisiBoxes();
00337
00338
00339 LoadMirrorPlanes(GetLevelFilename("rim", FILENAME_MAKE_BODY));
00340 MirrorWorldPolys();
00341 SetWorldMirror();
00342
00343
00344 LoadInstanceModels();
00345 LoadInstances(GetLevelFilename("fin", FILENAME_MAKE_BODY | FILENAME_GAME_SETTINGS));
00346 BuildInstanceCollPolys();
00347
00348
00349 if ((fp = fopen(GetLevelFilename("ncp", FILENAME_MAKE_BODY), "rb")) == NULL) {
00350 COL_WorldCollPoly = NULL;
00351 COL_NWorldCollPolys = 0;
00352 Box("Error", "Level has no Collision Polygon data", MB_OK | MB_ICONSTOP);
00353 QuitGame = TRUE;
00354 return;
00355 }
00356 if ((COL_WorldCollPoly = LoadNewCollPolys(fp, &COL_NWorldCollPolys)) == NULL) {
00357 Box("Error", "Collision polygon data corrupt", MB_OK | MB_ICONSTOP);
00358 fclose(fp);
00359 QuitGame = TRUE;
00360 return;
00361 }
00362
00363 if (!LoadGridInfo(fp)) {
00364 Box("Warning", "No collision grid information", MB_OK | MB_ICONEXCLAMATION);
00365 fclose(fp);
00366 return;
00367 }
00368 fclose(fp);
00369
00370
00371 InitLights();
00372 LoadLights(GetLevelFilename("lit", FILENAME_MAKE_BODY | FILENAME_GAME_SETTINGS));
00373
00374
00375 LoadSfx(LevelInf[GameSettings.Level].Dir);
00376
00377
00378 LoadObjects(GetLevelFilename("fob", FILENAME_MAKE_BODY | FILENAME_GAME_SETTINGS));
00379
00380
00381 LoadAiZones(GetLevelFilename("taz", FILENAME_MAKE_BODY | FILENAME_GAME_SETTINGS));
00382
00383
00384 LoadAiNodes(GetLevelFilename("fan", FILENAME_MAKE_BODY | FILENAME_GAME_SETTINGS));
00385 ZoneAiNodes();
00386
00387
00388 LoadTriggers(GetLevelFilename("tri", FILENAME_MAKE_BODY | FILENAME_GAME_SETTINGS));
00389
00390
00391 LoadLevelFields(&LevelInf[GameSettings.Level]);
00392
00393
00394 LoadTrackTimes(&LevelInf[GameSettings.Level]);
00395
00396
00397 if ((fp = fopen(GetLevelFilename("cam", FILENAME_MAKE_BODY), "rb")) != NULL) {
00398 CAM_NCameraNodes = LoadCameraNodes(fp);
00399 fclose(fp);
00400 } else {
00401 CAM_NCameraNodes = 0;
00402 }
00403
00404
00405 if (EditMode == EDIT_VISIBOXES)
00406 {
00407 LoadEditAiNodeModels();
00408 }
00409
00410
00411 if (EditMode == EDIT_LIGHTS)
00412 {
00413 LoadEditLightModels();
00414 }
00415
00416
00417 if (EditMode == EDIT_OBJECTS)
00418 {
00419 InitFileObjects();
00420 LoadFileObjects(GetLevelFilename("fob", FILENAME_MAKE_BODY | FILENAME_GAME_SETTINGS));
00421 LoadFileObjectModels();
00422 }
00423
00424
00425 if (EditMode == EDIT_VISIBOXES)
00426 {
00427 if (!AI_Testing) LoadEditAiNodeModels();
00428 }
00429
00430
00431 if (EditMode == EDIT_AINODES)
00432 {
00433 InitEditAiNodes();
00434 LoadEditAiNodes(GetLevelFilename("fan", FILENAME_MAKE_BODY | FILENAME_GAME_SETTINGS));
00435 if (!AI_Testing) LoadEditAiNodeModels();
00436 }
00437
00438
00439 if (EditMode == EDIT_ZONES)
00440 {
00441 InitFileZones();
00442 LoadFileZones(GetLevelFilename("taz", FILENAME_MAKE_BODY | FILENAME_GAME_SETTINGS));
00443 if (!AI_Testing) LoadEditAiNodeModels();
00444 }
00445
00446
00447 if (EditMode == EDIT_TRIGGERS)
00448 {
00449 InitFileTriggers();
00450 LoadFileTriggers(GetLevelFilename("tri", FILENAME_MAKE_BODY | FILENAME_GAME_SETTINGS));
00451 }
00452
00453
00454 if (EditMode == EDIT_CAM || EditMode == EDIT_TRIGGERS)
00455 {
00456 InitEditCamNodes();
00457 LoadEditCamNodes(GetLevelFilename("cam", FILENAME_MAKE_BODY | FILENAME_GAME_SETTINGS));
00458 LoadEditCamNodeModels();
00459 }
00460
00461
00462 if (EditMode == EDIT_FIELDS)
00463 {
00464 InitFileFields();
00465 LoadFileFields(GetLevelFilename("fld", FILENAME_MAKE_BODY | FILENAME_GAME_SETTINGS));
00466 LoadFileFieldModels();
00467 }
00468
00469
00470 if (EditMode == EDIT_PORTALS)
00471 {
00472 LoadEditPortals(GetLevelFilename("por", FILENAME_MAKE_BODY | FILENAME_GAME_SETTINGS));
00473 }
00474 }
00475
00477
00479
00480 void FindLevels(void)
00481 {
00482 long i, j;
00483 long r, g, b;
00484 int ch;
00485 WIN32_FIND_DATA data;
00486 HANDLE handle;
00487 FILE *fp;
00488 LEVELINFO templevel;
00489 char buf[256];
00490 char string[256];
00491 char names[MAX_LEVELS][MAX_LEVEL_DIR_NAME];
00492
00493
00494
00495 handle = FindFirstFile("levels\\*.*", &data);
00496 if (handle == INVALID_HANDLE_VALUE)
00497 {
00498 Box("ERROR", "Can't find any level directories", MB_OK);
00499 QuitGame = TRUE;
00500 return;
00501 }
00502
00503
00504
00505 GameSettings.LevelNum = 0;
00506
00507 while (TRUE)
00508 {
00509 if (!FindNextFile(handle, &data))
00510 break;
00511
00512
00513
00514 if (!(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
00515 continue;
00516
00517 if (!strcmp(data.cFileName, "."))
00518 continue;
00519
00520 if (!strcmp(data.cFileName, ".."))
00521 continue;
00522
00523
00524
00525 wsprintf(buf, "levels\\%s\\%s.inf", data.cFileName, data.cFileName);
00526 fp = fopen(buf, "rb");
00527
00528 if (fp && GameSettings.LevelNum < MAX_LEVELS)
00529 {
00530 for (i = 0 ; i < (long)strlen(data.cFileName) ; i++) data.cFileName[i] = toupper(data.cFileName[i]);
00531 memcpy(names[GameSettings.LevelNum], data.cFileName, MAX_LEVEL_DIR_NAME);
00532 GameSettings.LevelNum++;
00533 fclose(fp);
00534 }
00535 }
00536
00537
00538
00539 FindClose(handle);
00540
00541
00542
00543 LevelInf = (LEVELINFO*)malloc(sizeof(LEVELINFO) * GameSettings.LevelNum);
00544 if (!LevelInf)
00545 {
00546 Box("ERROR", "Can't alloc memory for level info", MB_OK);
00547 QuitGame = TRUE;
00548 return;
00549 }
00550
00551
00552
00553 for (i = 0 ; i < GameSettings.LevelNum ; i++)
00554 {
00555
00556
00557
00558 memcpy(LevelInf[i].Dir, names[i], MAX_LEVEL_DIR_NAME);
00559
00560
00561
00562 wsprintf(LevelInf[i].Name, "Untitled");
00563 wsprintf(LevelInf[i].EnvStill, "gfx\\envstill.bmp");
00564 wsprintf(LevelInf[i].EnvRoll, "gfx\\envroll.bmp");
00565 SetVector(&LevelInf[i].NormalStartPos, 0, 0, 0);
00566 SetVector(&LevelInf[i].ReverseStartPos, 0, 0, 0);
00567 LevelInf[i].NormalStartRot = 0;
00568 LevelInf[i].ReverseStartRot = 0;
00569 LevelInf[i].NormalStartGrid = 0;
00570 LevelInf[i].ReverseStartGrid = 0;
00571 LevelInf[i].FarClip = 6144;
00572 LevelInf[i].FogStart = 5120;
00573 LevelInf[i].FogColor = 0x000000;
00574 LevelInf[i].VertFogStart = 0;
00575 LevelInf[i].VertFogEnd = 0;
00576 LevelInf[i].WorldRGBper = 100;
00577 LevelInf[i].ModelRGBper = 100;
00578 LevelInf[i].InstanceRGBper = 100;
00579 LevelInf[i].MirrorType = 0;
00580 LevelInf[i].MirrorMix = 0.75f;
00581 LevelInf[i].MirrorIntensity = 1;
00582 LevelInf[i].MirrorDist = 256;
00583
00584
00585
00586 wsprintf(buf, "levels\\%s\\%s.inf", names[i], names[i]);
00587 fp = fopen(buf, "r");
00588
00589
00590
00591 while (TRUE)
00592 {
00593
00594
00595
00596 if (fscanf(fp, "%s", string) == EOF)
00597 break;
00598
00599
00600
00601 if (string[0] == ';')
00602 {
00603 do
00604 {
00605 ch = fgetc(fp);
00606 } while (ch != '\n' && ch != EOF);
00607 continue;
00608 }
00609
00610
00611
00612 if (!strcmp(string, "NAME"))
00613 {
00614 do
00615 {
00616 ch = fgetc(fp);
00617 } while (ch != '\'' && ch != EOF);
00618
00619 j = 0;
00620 while (TRUE)
00621 {
00622 ch = fgetc(fp);
00623 if (ch != '\'' && ch != EOF && j < MAX_LEVEL_NAME - 1)
00624 {
00625 LevelInf[i].Name[j] = (char)ch;
00626 j++;
00627 }
00628 else
00629 {
00630 LevelInf[i].Name[j] = 0;
00631 break;
00632 }
00633 }
00634 continue;
00635 }
00636
00637
00638
00639 if (!strcmp(string, "ENVSTILL"))
00640 {
00641 do
00642 {
00643 ch = fgetc(fp);
00644 } while (ch != '\'' && ch != EOF);
00645
00646 j = 0;
00647 while (TRUE)
00648 {
00649 ch = fgetc(fp);
00650 if (ch != '\'' && ch != EOF && j < MAX_ENV_NAME - 1)
00651 {
00652 LevelInf[i].EnvStill[j] = (char)ch;
00653 j++;
00654 }
00655 else
00656 {
00657 LevelInf[i].EnvStill[j] = 0;
00658 break;
00659 }
00660 }
00661 continue;
00662 }
00663
00664
00665
00666 if (!strcmp(string, "ENVROLL"))
00667 {
00668 do
00669 {
00670 ch = fgetc(fp);
00671 } while (ch != '\'' && ch != EOF);
00672
00673 j = 0;
00674 while (TRUE)
00675 {
00676 ch = fgetc(fp);
00677 if (ch != '\'' && ch != EOF && j < MAX_ENV_NAME - 1)
00678 {
00679 LevelInf[i].EnvRoll[j] = (char)ch;
00680 j++;
00681 }
00682 else
00683 {
00684 LevelInf[i].EnvRoll[j] = 0;
00685 break;
00686 }
00687 }
00688 continue;
00689 }
00690
00691
00692
00693 if (!strcmp(string, "STARTPOS"))
00694 {
00695 fscanf(fp, "%f %f %f", &LevelInf[i].NormalStartPos.v[X], &LevelInf[i].NormalStartPos.v[Y], &LevelInf[i].NormalStartPos.v[Z]);
00696 continue;
00697 }
00698
00699
00700
00701 if (!strcmp(string, "STARTPOSREV"))
00702 {
00703 fscanf(fp, "%f %f %f", &LevelInf[i].ReverseStartPos.v[X], &LevelInf[i].ReverseStartPos.v[Y], &LevelInf[i].ReverseStartPos.v[Z]);
00704 continue;
00705 }
00706
00707
00708
00709 if (!strcmp(string, "STARTROT"))
00710 {
00711 fscanf(fp, "%f", &LevelInf[i].NormalStartRot);
00712 continue;
00713 }
00714
00715
00716
00717 if (!strcmp(string, "STARTROTREV"))
00718 {
00719 fscanf(fp, "%f", &LevelInf[i].ReverseStartRot);
00720 continue;
00721 }
00722
00723
00724
00725 if (!strcmp(string, "STARTGRID"))
00726 {
00727 fscanf(fp, "%d", &LevelInf[i].NormalStartGrid);
00728 continue;
00729 }
00730
00731
00732
00733 if (!strcmp(string, "STARTGRIDREV"))
00734 {
00735 fscanf(fp, "%d", &LevelInf[i].ReverseStartGrid);
00736 continue;
00737 }
00738
00739
00740
00741 if (!strcmp(string, "FARCLIP"))
00742 {
00743 fscanf(fp, "%f", &LevelInf[i].FarClip);
00744 continue;
00745 }
00746
00747
00748
00749 if (!strcmp(string, "FOGSTART"))
00750 {
00751 fscanf(fp, "%f", &LevelInf[i].FogStart);
00752 continue;
00753 }
00754
00755
00756
00757 if (!strcmp(string, "FOGCOLOR"))
00758 {
00759 fscanf(fp, "%ld %ld %ld", &r, &g, &b);
00760 LevelInf[i].FogColor = (r << 16) | (g << 8) | b;
00761 continue;
00762 }
00763
00764
00765
00766 if (!strcmp(string, "VERTFOGSTART"))
00767 {
00768 fscanf(fp, "%f", &LevelInf[i].VertFogStart);
00769 continue;
00770 }
00771
00772
00773
00774 if (!strcmp(string, "VERTFOGEND"))
00775 {
00776 fscanf(fp, "%f", &LevelInf[i].VertFogEnd);
00777 continue;
00778 }
00779
00780
00781
00782 if (!strcmp(string, "WORLDRGBPER"))
00783 {
00784 fscanf(fp, "%ld", &LevelInf[i].WorldRGBper);
00785 continue;
00786 }
00787
00788
00789
00790 if (!strcmp(string, "MODELRGBPER"))
00791 {
00792 fscanf(fp, "%ld", &LevelInf[i].ModelRGBper);
00793 continue;
00794 }
00795
00796
00797
00798 if (!strcmp(string, "INSTANCERGBPER"))
00799 {
00800 fscanf(fp, "%ld", &LevelInf[i].InstanceRGBper);
00801 continue;
00802 }
00803
00804
00805
00806 if (!strcmp(string, "MIRRORS"))
00807 {
00808 fscanf(fp, "%ld %f %f %f", &LevelInf[i].MirrorType, &LevelInf[i].MirrorMix, &LevelInf[i].MirrorIntensity, &LevelInf[i].MirrorDist);
00809 continue;
00810 }
00811 }
00812
00813
00814
00815 fclose(fp);
00816 }
00817
00818
00819
00820 for (i = GameSettings.LevelNum - 1 ; i ; i--) for (j = 0 ; j < i ; j++)
00821 {
00822 if (strcmp(LevelInf[j].Name, LevelInf[j + 1].Name) > 0)
00823 {
00824 templevel = LevelInf[j];
00825 LevelInf[j] = LevelInf[j + 1];
00826 LevelInf[j + 1] = templevel;
00827 }
00828 }
00829 }
00830
00832
00834
00835 void FreeLevels(void)
00836 {
00837 free(LevelInf);
00838 }
00839
00841
00843
00844 long GetLevelNum(char *dir)
00845 {
00846 long i;
00847
00848
00849
00850 for (i = 0 ; i < GameSettings.LevelNum ; i++)
00851 {
00852 if (!strcmp(LevelInf[i].Dir, dir))
00853 {
00854 return i;
00855 }
00856 }
00857
00858
00859
00860 return -1;
00861 }
00862
00864
00866
00867 char *GetLevelFilename(char *filename, long flag)
00868 {
00869
00870
00871
00872 if (flag & FILENAME_MAKE_BODY)
00873 {
00874 if (flag & FILENAME_GAME_SETTINGS && GameSettings.Reversed)
00875 wsprintf(LevelFilenameBuffer, "levels\\%s\\reversed\\%s.%s", LevelInf[GameSettings.Level].Dir, LevelInf[GameSettings.Level].Dir, filename);
00876 else
00877 wsprintf(LevelFilenameBuffer, "levels\\%s\\%s.%s", LevelInf[GameSettings.Level].Dir, LevelInf[GameSettings.Level].Dir, filename);
00878 }
00879
00880
00881
00882 else
00883 {
00884 if (flag & FILENAME_GAME_SETTINGS && GameSettings.Reversed)
00885 wsprintf(LevelFilenameBuffer, "levels\\%s\\reversed\\%s", LevelInf[GameSettings.Level].Dir, filename);
00886 else
00887 wsprintf(LevelFilenameBuffer, "levels\\%s\\%s", LevelInf[GameSettings.Level].Dir, filename);
00888 }
00889
00890 return LevelFilenameBuffer;
00891 }
00892
00893
00895
00896
00897
00898
00900 #ifdef _PC
00901 bool LoadLevelFields(LEVELINFO *levelInfo)
00902 {
00903 int iField;
00904 long nFields;
00905 REAL rad;
00906 BBOX bBox;
00907 FILE *fp;
00908 FILE_FIELD fileField;
00909
00910
00911 fp = fopen(GetLevelFilename("fld", FILENAME_MAKE_BODY | FILENAME_GAME_SETTINGS), "rb");
00912 if (fp == NULL) {
00913 return FALSE;
00914 }
00915
00916
00917 if (fread(&nFields, sizeof(long), 1, fp) < 1) {
00918 fclose(fp);
00919 return FALSE;
00920 }
00921
00922 if (nFields < 1) {
00923 fclose(fp);
00924 return TRUE;
00925 }
00926
00927
00928 LEV_LevelFieldPos = (VEC *)malloc(sizeof(VEC) * nFields);
00929 LEV_LevelFieldMat = (MAT *)malloc(sizeof(MAT) * nFields);
00930
00931
00932 for (iField = 0; iField < nFields; iField++) {
00933
00934 if (fread(&fileField, sizeof(FILE_FIELD), 1, fp) < 1) {
00935 fclose(fp);
00936 return FALSE;
00937 }
00938
00939
00940 CopyVec(&fileField.Pos, &LEV_LevelFieldPos[iField]);
00941 CopyMat(&fileField.Matrix, &LEV_LevelFieldMat[iField]);
00942
00943
00944 switch(fileField.Type) {
00945
00946 case FILE_FIELD_TYPE_LINEAR:
00947 rad = (REAL)sqrt(fileField.Size[0] * fileField.Size[0] + fileField.Size[1] * fileField.Size[1] + fileField.Size[2] * fileField.Size[2]);
00948 SetBBox(&bBox, -rad, rad, -rad, rad, -rad, rad);
00949 AddLinearField(FIELD_PARENT_NONE, FIELD_PRIORITY_MAX, &LEV_LevelFieldPos[iField], &LEV_LevelFieldMat[iField], &bBox, (VEC *)&fileField.Size, &fileField.Dir, fileField.Mag, fileField.Damping);
00950 break;
00951
00952 case FILE_FIELD_TYPE_ORIENTATION:
00953 rad = (REAL)sqrt(fileField.Size[0] * fileField.Size[0] + fileField.Size[1] * fileField.Size[1] + fileField.Size[2] * fileField.Size[2]);
00954 SetBBox(&bBox, -rad, rad, -rad, rad, -rad, rad);
00955 AddOrientationField(FIELD_PARENT_NONE, FIELD_PRIORITY_MAX, &LEV_LevelFieldPos[iField], &LEV_LevelFieldMat[iField], &bBox, (VEC *)&fileField.Size, &fileField.Dir, fileField.Mag, fileField.Damping);
00956 break;
00957
00958 case FILE_FIELD_TYPE_VELOCITY:
00959 rad = (REAL)sqrt(fileField.Size[0] * fileField.Size[0] + fileField.Size[1] * fileField.Size[1] + fileField.Size[2] * fileField.Size[2]);
00960 SetBBox(&bBox, -rad, rad, -rad, rad, -rad, rad);
00961 AddVelocityField(FIELD_PARENT_NONE, FIELD_PRIORITY_MAX, &LEV_LevelFieldPos[iField], &LEV_LevelFieldMat[iField], &bBox, (VEC *)&fileField.Size, &fileField.Dir, fileField.Mag);
00962 break;
00963
00964 case FILE_FIELD_TYPE_SPHERICAL:
00965 rad = fileField.RadEnd;
00966 SetBBox(&bBox, -rad, rad, -rad, rad, -rad, rad);
00967 AddSphericalField(FIELD_PARENT_NONE, FIELD_PRIORITY_MAX, &LEV_LevelFieldPos[iField], fileField.RadStart, fileField.RadEnd, fileField.GradStart, fileField.GradEnd);
00968 break;
00969
00970 default:
00971 break;
00972 }
00973 }
00974
00975 fclose(fp);
00976 return TRUE;
00977 }
00978 #endif
00979