00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00033
00034 #ifdef _MSC_VER
00035 #pragma warning( disable : 4786 )
00036 #endif
00037
00038
00039 #include <math.h>
00040 #include <GL/glut.h>
00041 #include <plib/ssg.h>
00042 #include <plib/ssgAux.h>
00043
00044 #include "../Ssg/ssgLocal.h"
00045
00046 #include "../Include/FlyLegacy.h"
00047 #include "../Include/Globals.h"
00048 #include "../Include/Situation.h"
00049 #include "../Include/KeyMap.h"
00050 #include "../Include/Ui.h"
00051 #include "../Include/Database.h"
00052 #include "../Include/Utility.h"
00053 #include "../Include/LogFile.h"
00054 #include "../Include/Pod.h"
00055
00056
00057
00058 SGlobals *globals = NULL;
00059
00060
00061
00062
00063 #ifdef _WIN32
00064 static BYTE savedkeys[256];
00065
00066 typedef struct {
00067 BYTE vk;
00068 EKeyboardKeys key;
00069 } SNonGlutKey;
00070
00071 SNonGlutKey nonGlutKeys[] =
00072 {
00073 { VK_CAPITAL, KB_KEY_CAPSLOCK },
00074 { VK_NUMLOCK, KB_KEY_NUMLOCK },
00075 { VK_SCROLL, KB_KEY_SCROLLLOCK },
00076 { VK_SUBTRACT, KB_KEY_KEYPAD_MINUS },
00077 { VK_CLEAR, KB_KEY_CENTER },
00078 { VK_ADD, KB_KEY_KEYPAD_PLUS },
00079 { VK_RETURN, KB_KEY_KEYPAD_ENTER },
00080 { VK_DIVIDE, KB_KEY_KEYPAD_SLASH },
00081 };
00082 #endif
00083
00084 #ifdef _WIN32
00085
00086
00087
00088 static WORD savedGammaRamp[3][0x100];
00089 static HDC hdc = 0;
00090 #endif // _WIN32
00091
00092
00093 static void idle (void);
00094 static void reshape (int w, int h);
00095 static void motion (int x, int y);
00096 static void passive_motion (int x, int y);
00097 static void mouse (int button, int updown, int x, int y);
00098 static void keyboard (unsigned char key, int x, int y);
00099 static void special (int key, int x, int y);
00100 static void redraw (void);
00101
00102
00103
00104
00105
00106 static void InitGraphics ()
00107 {
00108 int fake_argc = 1 ;
00109 char *fake_argv[3] ;
00110 fake_argv[0] = "Fly! Legacy";
00111 fake_argv[1] = "Fly! Legacy";
00112 fake_argv[2] = NULL ;
00113
00114
00115 int w = globals->screenWidth;
00116 int h = globals->screenHeight;
00117 int bpp = globals->screenDepth;
00118 int refresh = globals->screenRefresh;
00119
00120
00121 int autoFullScreen = 0;
00122 GetIniVar ("Graphics", "autoFullScreen", &autoFullScreen);
00123
00124
00125 glutInit ( &fake_argc, fake_argv ) ;
00126 glutInitDisplayMode ( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ) ;
00127 if (autoFullScreen) {
00128 char game[64];
00129 sprintf (game, "%dx%d:%d@%d", w, h, bpp, refresh);
00130 glutGameModeString (game);
00131 glutEnterGameMode ();
00132 } else {
00133 glutInitWindowPosition ( 0, 0 ) ;
00134 glutInitWindowSize ( w, h ) ;
00135 glutCreateWindow ( fake_argv[1] ) ;
00136 }
00137 glutIdleFunc (idle);
00138 glutMouseFunc (mouse);
00139 glutMotionFunc (motion);
00140 glutPassiveMotionFunc (passive_motion);
00141 glutDisplayFunc (redraw);
00142 glutReshapeFunc (reshape);
00143 glutKeyboardFunc (keyboard);
00144 glutSpecialFunc (special);
00145
00146
00147 glClearColor ( 0, 0, 0, 1.0f ) ;
00148
00149 #ifdef _WIN32
00150
00151 float gamma = 1.0f;
00152 GetIniFloat ("Graphics", "displayGamma", &gamma);
00153
00154
00155 hdc = wglGetCurrentDC ();
00156 if (!GetDeviceGammaRamp (hdc, savedGammaRamp)) {
00157 WARNINGLOG ("Failed to get Win32 gamma ramp");
00158 }
00159
00160
00161 float invgamma = 1.0f / gamma;
00162 WORD ramp[3][0x100];
00163 for (int i=0; i<0x100; i++) {
00164 float factor = pow((float)i / 256.0f, invgamma);
00165 if (factor > 1.0f) factor = 1.0f;
00166 WORD value = (WORD)((factor * 65535.0f) + 0.5f);
00167 ramp[0][i] = value;
00168 ramp[1][i] = value;
00169 ramp[2][i] = value;
00170 }
00171
00172
00173 if (!SetDeviceGammaRamp (hdc, ramp)) {
00174 WARNINGLOG ("Failed to set Win32 gamma ramp");
00175 }
00176 #endif // _WIN32
00177
00178
00179 glutSetCursor (GLUT_CURSOR_NONE);
00180
00181
00182
00184 char *mark1 = new char[32];
00185 strcpy (mark1, "ssgInit Start");
00186 ssgInit ();
00187 char *mark2 = new char[32];
00188 strcpy (mark2, "ssgInit End");
00189
00190 globals->context = new ssgContext;
00191 ssgSetNearFar (1.0, 1.0E20);
00192 }
00193
00194 void InitFonts (void)
00195 {
00197 char *mark1 = new char[32];
00198 strcpy (mark1, "ftascm10 Start");
00199 strcpy (globals->fonts.ftascm10.fontName, "ART\\FTASCM10.RAW");
00200 LoadFont (&globals->fonts.ftascm10);
00201 char *mark2 = new char[32];
00202 strcpy (mark2, "ftascm10 End");
00203 strcpy (globals->fonts.ftdigi9.fontName, "ART\\FTDIGI9.RAW");
00204 LoadFont (&globals->fonts.ftdigi9);
00205 strcpy (globals->fonts.ftdigi9b.fontName, "ART\\FTDIGI9B.RAW");
00206 LoadFont (&globals->fonts.ftdigi9b);
00207 strcpy (globals->fonts.ftdigi9d.fontName, "ART\\FTDIGI9D.RAW");
00208 LoadFont (&globals->fonts.ftdigi9d);
00209 strcpy (globals->fonts.ftdigi13.fontName, "ART\\FTDIGI13.RAW");
00210 LoadFont (&globals->fonts.ftdigi13);
00211 strcpy (globals->fonts.ftmicro5.fontName, "ART\\FTMICRO5.RAW");
00212 LoadFont (&globals->fonts.ftmicro5);
00213 strcpy (globals->fonts.ftmno14b.fontName, "ART\\FTMNO14B.RAW");
00214 LoadFont (&globals->fonts.ftmno14b);
00215 strcpy (globals->fonts.ftmono12.fontName, "ART\\FTMONO12.RAW");
00216 LoadFont (&globals->fonts.ftmono12);
00217 strcpy (globals->fonts.ftsmal10.fontName, "ART\\FTSMAL10.RAW");
00218 LoadFont (&globals->fonts.ftsmal10);
00219 strcpy (globals->fonts.ftthin24.fontName, "ART\\FTTHIN24.RAW");
00220 LoadFont (&globals->fonts.ftthin24);
00221 strcpy (globals->fonts.fttiny7.fontName, "ART\\FTTINY7.RAW");
00222 LoadFont (&globals->fonts.fttiny7);
00223 strcpy (globals->fonts.ftasci10.fontName, "ART\\FTASCI10.RAW");
00224 LoadFont (&globals->fonts.ftasci10);
00225
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244 }
00245
00246 void cleanup_fonts (void)
00247 {
00248 FreeFont (&globals->fonts.ftascm10);
00249 FreeFont (&globals->fonts.ftdigi9);
00250 FreeFont (&globals->fonts.ftdigi9b);
00251 FreeFont (&globals->fonts.ftdigi9d);
00252 FreeFont (&globals->fonts.ftdigi13);
00253 FreeFont (&globals->fonts.ftmicro5);
00254 FreeFont (&globals->fonts.ftmno14b);
00255 FreeFont (&globals->fonts.ftmono12);
00256 FreeFont (&globals->fonts.ftsmal10);
00257 FreeFont (&globals->fonts.ftthin24);
00258 FreeFont (&globals->fonts.fttiny7);
00259 FreeFont (&globals->fonts.ftasci10);
00260
00261
00262
00263
00264 }
00265
00266
00268 CDatabase* dbAirport;
00269 CDatabase* dbAtsRoute;
00270 CDatabase* dbComm;
00271 CDatabase* dbCountry;
00272 CDatabase* dbState;
00273 CDatabase* dbIls;
00274 CDatabase* dbNavaid;
00275 CDatabase* dbObstruct;
00276 CDatabase* dbRunway;
00277 CDatabase* dbWaypoint;
00278
00279
00280
00281
00282
00283 void LoadDatabases (void)
00284 {
00285
00286 dbAirport = new CDatabase ("Airport.dbt");
00287 dbAirport->Mount ("Airport.dbd");
00288 dbAirport->AddIndex ("Airport.dbi");
00289 dbAirport->AddIndex ("AprtCtry.dbi");
00290 dbAirport->AddIndex ("AprtStat.dbi");
00291 dbAirport->AddIndex ("AprtFaa.dbi");
00292 dbAirport->AddIndex ("AprtIcao.dbi");
00293 dbAirport->AddIndex ("AprtGlob.dbi");
00294 dbAirport->AddIndex ("AprtName.dbi");
00295
00296
00297 dbAtsRoute = new CDatabase ("AtsRoute.dbt");
00298 dbAtsRoute->Mount ("AtsRoute.dbd");
00299
00300
00301 dbComm = new CDatabase ("Comm.dbt");
00302 dbComm->Mount ("Comm.dbd");
00303 dbComm->AddIndex ("Comm.dbi");
00304 dbComm->AddIndex ("CommGlob.dbi");
00305
00306
00307 dbCountry = new CDatabase ("Country.dbt");
00308 dbCountry->Mount ("Country.dbd");
00309 dbCountry->AddIndex ("Country.dbi");
00310 dbCountry->AddIndex ("CtryName.dbi");
00311
00312
00313 dbState = new CDatabase ("State.dbt");
00314 dbState->Mount ("State.dbd");
00315 dbState->AddIndex ("Statctry.dbi");
00316 dbState->AddIndex ("State.dbi");
00317 dbState->AddIndex ("StatName.dbi");
00318
00319
00320 dbIls = new CDatabase ("Ils.dbt");
00321 dbIls->Mount ("Ils.dbd");
00322 dbIls->AddIndex ("Ils.dbi");
00323 dbIls->AddIndex ("IlsGlob.dbi");
00324 dbIls->AddIndex ("IlsLocal.dbi");
00325
00326
00327 dbNavaid = new CDatabase ("Navaid.dbt");
00328 dbNavaid->Mount ("Navaid.dbd");
00329 dbNavaid->AddIndex ("Navaid.dbi");
00330 dbNavaid->AddIndex ("NavNdbId.dbi");
00331 dbNavaid->AddIndex ("NavNdbNm.dbi");
00332 dbNavaid->AddIndex ("NavVorId.dbi");
00333 dbNavaid->AddIndex ("NavVorNm.dbi");
00334
00335
00336 dbObstruct = new CDatabase ("Obstruct.dbt");
00337 dbObstruct->Mount ("Obstruct.dbd");
00338 dbObstruct->AddIndex ("ObstGlob.dbi");
00339
00340
00341 dbRunway = new CDatabase ("Runway.dbt");
00342 dbRunway->Mount ("Runway.dbd");
00343 dbRunway->AddIndex ("Runway.dbi");
00344
00345
00346 dbWaypoint = new CDatabase ("Waypoint.dbt");
00347 dbWaypoint->Mount ("Waypoint.dbd");
00348 dbWaypoint->AddIndex ("Waypoint.dbi");
00349 dbWaypoint->AddIndex ("WayKey.dbi");
00350 }
00351
00352 void UnloadDatabases (void)
00353 {
00354 delete dbAirport;
00355 delete dbAtsRoute;
00356 delete dbComm;
00357 delete dbCountry;
00358 delete dbState;
00359 delete dbIls;
00360 delete dbNavaid;
00361 delete dbObstruct;
00362 delete dbRunway;
00363 delete dbWaypoint;
00364 }
00365
00366
00367
00368
00369
00370
00371 static void InitGlobalsNoPodFilesystem (void)
00372 {
00373 bool iniChanged = false;
00374
00375 globals = new SGlobals;
00376
00377
00378 globals->logDebug = new CLogFile ("Logs\\Debug.log", "w");
00379 globals->logWarning = new CLogFile ("Logs\\Warning.log", "w");
00380
00381
00382
00383
00384
00385
00386 int w = 1024;
00387 GetIniVar ("Graphics", "gamePIXX", &w);
00388
00389 int h = 768;
00390 GetIniVar ("Graphics", "gamePIXY", &h);
00391
00392
00393 bool screen640 = (w == 640) && (h == 480);
00394 bool screen800 = (w == 800) && (h == 600);
00395 bool screen1024 = (w == 1024) && (h == 768);
00396 if (!(screen640 || screen800 || screen1024)) {
00397
00398 if (globals->logWarning) globals->logWarning->Write ("Invalid screen resolution in INI settings, default to 1024x768");
00399 w = 1024;
00400 h = 768;
00401 SetIniVar ("Graphics", "gamePIXX", w);
00402 SetIniVar ("Graphics", "gamePIXY", h);
00403 iniChanged = true;
00404 }
00405
00406
00407 int bpp = 32;
00408 GetIniVar ("Graphics", "gameBitsPerPixel", &bpp);
00409 if ((bpp != 16) && (bpp != 32)) {
00410
00411 if (globals->logWarning) globals->logWarning->Write ("Invalid screen colour depth in INI settings, default to 32bpp");
00412 bpp = 32;
00413 SetIniVar ("Graphics", "gameBitsPerPixel", bpp);
00414 iniChanged = true;
00415 }
00416
00417
00418 int refresh = 0;
00419 GetIniVar ("Graphics", "gameRefreshRate", &refresh);
00420
00421
00422 globals->screenWidth = w;
00423 globals->screenHeight = h;
00424 globals->screenDepth = bpp;
00425 globals->screenRefresh = refresh;
00426
00427
00428
00429
00430 int i = -1;
00431 GetIniVar ("Cockpit", "mouseScrollingEnabled", &i);
00432 if (i == -1) {
00433
00434 i = 1;
00435 SetIniVar ("Cockpit", "mouseScrollingEnabled", i);
00436 iniChanged = true;
00437 }
00438 globals->mouseScrollingEnabled = (i != 0);
00439
00440
00441 i = -1;
00442 GetIniVar ("Cockpit", "panelScrollStep", &i);
00443 if (i == -1) {
00444
00445 i = 10;
00446 SetIniVar ("Cockpit", "panelScrollStep", i);
00447 iniChanged = true;
00448 }
00449 globals->panelScrollStep = i;
00450
00451
00452 i = -1;
00453 GetIniVar ("Cockpit", "panelCreepStep", &i);
00454 if (i == -1) {
00455
00456 i = 10;
00457 SetIniVar ("Cockpit", "panelCreepStep", i);
00458 iniChanged = true;
00459 }
00460 globals->panelCreepStep = i;
00461
00462
00463 globals->settings = new SGlobalSettings;
00464
00465
00466 i = -1;
00467 GetIniVar ("Graphics", "skydomeWireframe", &i);
00468 if (i == -1) {
00469
00470 i = 0;
00471 SetIniVar ("Graphics", "skydomeWireframe", i);
00472 iniChanged = true;
00473 }
00474 globals->settings->skydomeWireframe = (i != 0);
00475
00476
00477 i = -1;
00478 GetIniVar ("Graphics", "terrainWireframe", &i);
00479 if (i == -1) {
00480
00481 i = 0;
00482 SetIniVar ("Graphics", "terrainWireframe", i);
00483 iniChanged = true;
00484 }
00485 globals->settings->terrainWireframe = (i != 0);
00486
00487
00488 i = -1;
00489 GetIniVar ("Graphics", "aircraftWireframe", &i);
00490 if (i == -1) {
00491
00492 i = 0;
00493 SetIniVar ("Graphics", "aircraftWireframe", i);
00494 iniChanged = true;
00495 }
00496 globals->settings->aircraftWireframe = (i != 0);
00497
00498
00499 i = -1;
00500 GetIniVar ("Graphics", "terrainReliefShaded", &i);
00501 if (i == -1) {
00502
00503 i = 0;
00504 SetIniVar ("Graphics", "terrainReliefShaded", i);
00505 iniChanged = true;
00506 }
00507 globals->settings->terrainReliefShaded = (i != 0);
00508
00509
00510 if (iniChanged) {
00511 SaveIniSettings ();
00512 }
00513
00514
00515 globals->timemgr = new CTimeManager;
00516 globals->timemgr->Prepare ();
00517 globals->timemgr->SetTimeScale (1.0);
00518
00519
00520 globals->audiomgr = new CAudioManager;
00521 globals->audiomgr->Init ();
00522
00523
00524 globals->cursormgr = new CCursorManager;
00525
00526
00527 globals->slewmgr = new CSlewManager;
00528
00529
00530 globals->simRate = new CFrameRateTracker (200);
00531 globals->drawRate = new CFrameRateTracker (200);
00532
00533
00534 globals->sit = NULL;
00535 globals->keymap = NULL;
00536 globals->terrainmgr = NULL;
00537 globals->skymgr = NULL;
00538 globals->fuimgr = NULL;
00539 }
00540
00541 static void InitGlobalsWithPodFilesystem (void)
00542 {
00543 LoadDatabases ();
00544
00545
00546 globals->terrainmgr = new CTerrainManager;
00547
00548
00549 globals->skymgr = new CSkyManager;
00550
00551
00552 globals->fuimgr = new CFuiManager;
00553 FILE *f = fopen ("Debug\\Fui.txt", "w");
00554 globals->fuimgr->Print (f);
00555 fclose (f);
00556 }
00557
00558
00559
00560
00561
00562 void CleanupGlobals (void)
00563 {
00564 cleanup_ui ();
00565 cleanup_fonts();
00566
00567 if (globals->settings != NULL) delete globals->settings;
00568 if (globals->context != NULL) delete globals->context;
00569 if (globals->sit != NULL) delete globals->sit;
00570 if (globals->keymap != NULL) delete globals->keymap;
00571 if (globals->timemgr != NULL) delete globals->timemgr;
00572 if (globals->cursormgr != NULL) delete globals->cursormgr;
00573 if (globals->audiomgr != NULL) delete globals->audiomgr;
00574 if (globals->fuimgr != NULL) delete globals->fuimgr;
00575 if (globals->terrainmgr != NULL) delete globals->terrainmgr;
00576 if (globals->skymgr != NULL) delete globals->skymgr;
00577 if (globals->slewmgr != NULL) delete globals->slewmgr;
00578 if (globals->logDebug != NULL) delete globals->logDebug;
00579 if (globals->logWarning != NULL) delete globals->logWarning;
00580
00581
00582 pshutdown (&globals->pfs);
00583
00584 delete globals;
00585 }
00586
00587
00588 #if defined(_DEBUG) && defined(HAVE_CRTDBG_H)
00589
00590
00591
00592 _CrtMemState memoryState;
00593 #endif
00594
00595
00596
00597
00598
00599 void ShutdownAll (void)
00600 {
00601
00602 UnloadDatabases ();
00603
00604
00605 UnloadIniSettings ();
00606
00607
00608 CleanupGlobals ();
00609
00610 #ifdef _WIN32
00611
00612 if (!SetDeviceGammaRamp (hdc, savedGammaRamp)) {
00613 if (globals->logWarning) globals->logWarning->Write ("Failed to set Win32 gamma ramp");
00614 }
00615 #endif // _WIN32
00616 }
00617
00618
00619 static void idle (void)
00620 {
00621 #ifdef WIN32
00622
00623
00624
00625
00626
00627
00628 BYTE keys[256];
00629 GetKeyboardState(keys);
00630
00631
00632 int flymod = KB_MODIFIER_NONE;
00633 bool shift = (keys[VK_SHIFT] & 0x80) != 0;
00634 if (shift) {
00635 flymod |= KB_MODIFIER_SHIFT;
00636 }
00637 bool ctrl = (keys[VK_CONTROL] & 0x80) != 0;
00638 if (ctrl) {
00639 flymod |= KB_MODIFIER_CTRL;
00640 }
00641 bool alt = (keys[VK_MENU] & 0x80) != 0;
00642 if (alt) {
00643 flymod |= KB_MODIFIER_ALT;
00644 }
00645
00646
00647 static bool first = true;
00648 if (first) {
00649
00650 first = false;
00651 for (int i=0; i<256; i++) {
00652 savedkeys[i] = (keys[i] & 0x80) != 0;
00653 }
00654 }
00655
00656
00657
00658 int nKeys = sizeof(nonGlutKeys) / sizeof(SNonGlutKey);
00659 for (int i=0; i<nKeys; i++) {
00660 BYTE vk = nonGlutKeys[i].vk;
00661 if (keys[vk] & 0x80) {
00662
00663 if (!savedkeys[vk]) {
00664
00665 savedkeys[vk] = true;
00666 globals->keymap->KeyPress (nonGlutKeys[i].key, (EKeyboardModifiers)flymod);
00667 }
00668 } else {
00669
00670 savedkeys[vk] = false;
00671 }
00672 }
00673 #endif // WIN32
00674 }
00675
00676
00677
00678
00679
00680 static void reshape ( int w, int h )
00681 {
00682 glViewport ( 0, 0, w, h ) ;
00683 }
00684
00685
00686
00687
00688
00689 void motion ( int x, int y )
00690 {
00691 bool used = false;
00692
00693
00694 if (globals->fuimgr) used = globals->fuimgr->MouseMove (x, y);
00695
00696 if (!used) {
00697
00698 puMouse (x, y);
00699
00700
00701 if (globals->sit) {
00702 CPanel *panl = globals->sit->GetCurrentPanel ();
00703 if (panl) {
00704
00705 panl->MouseMotion (x, y);
00706 }
00707 }
00708 }
00709
00710
00711 if (globals->cursormgr) {
00712 globals->cursormgr->MouseMotion (x, y);
00713 }
00714
00715
00716 glutPostRedisplay () ;
00717 }
00718
00719
00720
00721
00722
00723 void passive_motion ( int x, int y )
00724 {
00725 bool used = false;
00726
00727
00728 if (globals->fuimgr) used = globals->fuimgr->MouseMove (x, y);
00729
00730 if (!used) {
00731
00732 puMouse (x, y);
00733
00734
00735 if (globals->sit) {
00736 CPanel *panl = globals->sit->GetCurrentPanel ();
00737 if (panl) {
00738
00739 panl->MouseMotion (x, y);
00740 }
00741 }
00742 }
00743
00744
00745 if (globals->cursormgr) {
00746 globals->cursormgr->MouseMotion (x, y);
00747 }
00748
00749
00750 glutPostRedisplay () ;
00751 }
00752
00753
00754
00755
00756
00757 void mouse ( int button, int updown, int x, int y )
00758 {
00759 bool used = false;
00760
00761
00762 EMouseButton b = MOUSE_BUTTON_LEFT;
00763 switch (updown) {
00764 case GLUT_DOWN:
00765 switch (button) {
00766 case GLUT_LEFT_BUTTON:
00767 b = MOUSE_BUTTON_LEFT;
00768 break;
00769
00770 case GLUT_MIDDLE_BUTTON:
00771 b = MOUSE_BUTTON_MIDDLE;
00772 break;
00773
00774 case GLUT_RIGHT_BUTTON:
00775 b = MOUSE_BUTTON_RIGHT;
00776 break;
00777 }
00778 used = globals->fuimgr->MouseClick (x, y, b);
00779 break;
00780
00781 case GLUT_UP:
00782 switch (button) {
00783 case GLUT_LEFT_BUTTON:
00784 b = MOUSE_BUTTON_LEFT;
00785 break;
00786
00787 case GLUT_MIDDLE_BUTTON:
00788 b = MOUSE_BUTTON_MIDDLE;
00789 break;
00790
00791 case GLUT_RIGHT_BUTTON:
00792 b = MOUSE_BUTTON_RIGHT;
00793 break;
00794 }
00795 used = globals->fuimgr->MouseStopClick (x, y, b);
00796 break;
00797 }
00798
00799 if (!used) {
00800
00801 puMouse (button, updown, x, y);
00802
00803
00804 if (globals->sit) {
00805 CPanel *panl = globals->sit->GetCurrentPanel ();
00806 if (panl) {
00807
00808 panl->MouseClick (button, updown, x, y);
00809 }
00810 }
00811 }
00812
00813
00814 glutPostRedisplay () ;
00815 }
00816
00817
00818
00819
00820
00821 static void keyboard (unsigned char key, int x, int y)
00822 {
00823
00824 if (!puKeyboard (key, PU_DOWN)) {
00825
00826
00827 if (globals->keymap == NULL) return;
00828
00829
00830 int glutmod = glutGetModifiers ();
00831 EKeyboardModifiers flymod = glutModifiersToFlyLegacyModifiers (glutmod);
00832
00833
00834 EKeyboardKeys flykey;
00835 if (glutKeyToFlyLegacyKey (key, &flykey)) {
00836 globals->keymap->KeyPress (flykey, flymod);
00837 } else {
00838 if (globals->logWarning) globals->logWarning->Write ("keyboard : Unmapped GLUT key %d", key);
00839 }
00840 }
00841 }
00842
00843
00844
00845
00846 static void special (int key, int x, int y)
00847 {
00848
00849 if (!puKeyboard (key + PU_KEY_GLUT_SPECIAL_OFFSET, PU_DOWN)) {
00850
00851
00852
00853
00854 if (globals->keymap == NULL) return;
00855
00856
00857 int glutmod = glutGetModifiers ();
00858 EKeyboardModifiers flymod = glutModifiersToFlyLegacyModifiers (glutmod);
00859
00860
00861 EKeyboardKeys flykey;
00862 if (glutSpecialToFlyLegacyKey (key, &flykey)) {
00863 globals->keymap->KeyPress (flykey, flymod);
00864 } else {
00865 if (globals->logWarning) globals->logWarning->Write ("special : Unmapped GLUT key %d", key);
00866 }
00867 }
00868 }
00869
00870
00871
00872
00873
00874 SBitmap *bmSplash = NULL;
00875 SSurface *surfSplash = NULL;
00876
00877 static void InitSplashScreen (void)
00878 {
00879
00880 bmSplash = new SBitmap;
00881 strcpy (bmSplash->bitmapName, "UI\\LOADING SCREEN\\OPENING.PBM");
00882 LoadBitmap (bmSplash) ;
00883 int w, h;
00884 GetBitmapSize (bmSplash, &w, &h);
00885
00886
00887 surfSplash = CreateSurface (globals->screenWidth, globals->screenHeight);
00888 EraseSurface (surfSplash);
00889 surfSplash->xScreen = 0;
00890 surfSplash->yScreen = 0;
00891
00892
00893 int x = (globals->screenWidth - w) / 2;
00894 int y = (globals->screenHeight - h) / 2;
00895 DrawBitmap (surfSplash, bmSplash, x, y, 0);
00896
00897
00898 char buildString[80];
00899 sprintf (buildString, "%s Build %d.%d.%03d",
00900 FLY_LEGACY_TITLE,
00901 FLY_LEGACY_MAJOR_VERSION,
00902 FLY_LEGACY_MINOR_VERSION,
00903 FLY_LEGACY_BUILD);
00904 unsigned int black = MakeRGB (0, 0, 0);
00905 unsigned int white = MakeRGB (255, 255, 255);
00906 x = globals->screenWidth / 2;
00907 y = ((globals->screenHeight - h) / 2) + 20;
00908 DrawTextC (surfSplash, &globals->fonts.ftthin24, x+1, y+1, black, buildString);
00909 DrawTextC (surfSplash, &globals->fonts.ftthin24, x, y, white, buildString);
00910 }
00911
00912 static void Draw2D (SSurface *surf)
00913 {
00914
00915 glMatrixMode(GL_PROJECTION);
00916 glPushMatrix();
00917 glLoadIdentity();
00918 gluOrtho2D (0, globals->screenWidth, 0, globals->screenHeight);
00919
00920
00921 glPushAttrib (GL_ENABLE_BIT);
00922 glEnable (GL_ALPHA_TEST);
00923 glDisable (GL_DEPTH_TEST);
00924 glDisable (GL_LIGHTING);
00925 glDisable (GL_COLOR_MATERIAL);
00926 glDisable (GL_TEXTURE_2D);
00927
00928
00929 glRasterPos2i (0, 0);
00930 Blit (surf);
00931
00932
00933 glPopAttrib();
00934
00935
00936 glMatrixMode(GL_PROJECTION);
00937 glPopMatrix();
00938
00939
00940 GLenum e = glGetError ();
00941 if (e != GL_NO_ERROR) {
00942 gtfo ("CPanel::Draw:Return : GL Error 0x%04X", e);
00943 }
00944 }
00945
00946 static void RedrawSplashScreen (void)
00947 {
00948
00949 Draw2D (surfSplash);
00950 }
00951
00952 static void CleanupSplashScreen (void)
00953 {
00954 FreeBitmap (bmSplash);
00955 delete bmSplash;
00956 FreeSurface (surfSplash);
00957 }
00958
00959
00960
00961
00962 static void Initialize (void)
00963 {
00964
00965
00966 globals->crsrArrow = globals->cursormgr->BindCursor ("MPARROW.CSR");
00967 globals->cursormgr->SetCursor (globals->crsrArrow);
00968
00969
00970
00971 init_keyboard ();
00972 init_globe_tile_table ();
00973
00974 InitGlobalsWithPodFilesystem();
00975 }
00976
00977
00978
00979
00980 SBitmap *bmLoading;
00981 SSurface *surfLoading;
00982 static void InitLoadingScreen (void)
00983 {
00984
00985 bmLoading = new SBitmap;
00986 strcpy (bmLoading->bitmapName, "UI\\LOADING SCREEN\\LOADING.PBM");
00987 LoadBitmap (bmLoading);
00988 int w, h;
00989 GetBitmapSize (bmLoading, &w, &h);
00990
00991
00992 surfLoading = CreateSurface (globals->screenWidth, globals->screenHeight);
00993 EraseSurface (surfLoading);
00994 surfLoading->xScreen = 0;
00995 surfLoading->yScreen = 0;
00996
00997
00998 if ((w > globals->screenWidth) || (h > globals->screenHeight)) {
00999
01000 int x1 = (w - globals->screenWidth) / 2;
01001 int y1 = (h - globals->screenHeight) / 2;
01002 int x2 = x1 + globals->screenWidth;
01003 int y2 = y1 + globals->screenHeight;
01004 DrawBitmapPartial (surfLoading, bmLoading, 0, 0, x1, y1, x2, y2, 0);
01005 } else {
01006
01007 int x = (globals->screenWidth - w) / 2;
01008 int y = (globals->screenHeight - h) / 2;
01009 DrawBitmap (surfLoading, bmLoading, x, y, 0);
01010 }
01011 }
01012
01013 static void RedrawLoadingScreen (void)
01014 {
01015
01016
01017
01018 Draw2D (surfLoading);
01019 }
01020
01021 static void CleanupLoadingScreen (void)
01022 {
01023 if (bmLoading != NULL) {
01024 FreeBitmap (bmLoading);
01025 delete bmLoading;
01026 bmLoading = NULL;
01027 }
01028
01029 if (surfLoading != NULL) {
01030 FreeSurface (surfLoading);
01031 surfLoading = NULL;
01032 }
01033 }
01034
01035
01036
01037
01038 static void LoadStartupSituation (void)
01039 {
01040
01041 char sitFilename[80];
01042 strcpy (sitFilename, "");
01043 GetIniString ("UI", "startupSituation", sitFilename, 80);
01044 if (strlen (sitFilename) == 0) {
01045
01046 strcpy (sitFilename, "Default.sit");
01047 SetIniString ("UI", "startupSituation", sitFilename);
01048 SaveIniSettings ();
01049 }
01050
01051 char *mark1 = new char[32];
01052 strcpy (mark1, "sit start");
01053 globals->sit = new CSituation (sitFilename);
01054 char *mark2 = new char[32];
01055 strcpy (mark2, "sit end");
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068 }
01069
01070
01071
01072
01073 static unsigned int nFrames = 0;
01074 static float tFrames = 0.0f;
01075 static float frameRate = 0.0f;
01076
01077 static void RedrawSimulation (void)
01078 {
01079
01080
01081
01082 globals->timemgr->Update ();
01083 float dRealT = globals->timemgr->GetDeltaRealTime();
01084 float dSimT = globals->timemgr->GetDeltaSimTime();
01085
01086
01087 nFrames++;
01088 tFrames += dRealT;
01089 if (tFrames > 1.0f) {
01090 frameRate = (float)nFrames / tFrames;
01091 tFrames = 0.0f;
01092 nFrames = 0;
01093 }
01094
01095
01096
01097
01098
01099
01100 if (globals->sit != NULL) {
01101 globals->sit->Timeslice (dSimT);
01102 }
01103
01104
01105
01107 globals->sit->Draw (dRealT);
01108
01109
01110 DrawUi (dRealT);
01111 globals->fuimgr->Draw ();
01112
01113
01114 globals->cursormgr->Draw ();
01115 }
01116
01117
01118
01119
01120 SBitmap *bmExit = NULL;
01121 SSurface *surfExit = NULL;
01122
01123 static void InitExitScreen (void)
01124 {
01125
01126 bmExit = new SBitmap;
01127 strcpy (bmExit->bitmapName, "UI\\LOADING SCREEN\\LEAVING.PBM");
01128 LoadBitmap (bmExit);
01129 int w, h;
01130 GetBitmapSize (bmExit, &w, &h);
01131
01132
01133 surfExit = CreateSurface (globals->screenWidth, globals->screenHeight);
01134 EraseSurface (surfExit);
01135 surfExit->xScreen = 0;
01136 surfExit->yScreen = 0;
01137
01138
01139 int x = (globals->screenWidth - w) / 2;
01140 int y = (globals->screenHeight - h) / 2;
01141 DrawBitmap (surfExit, bmExit, x, y, 0);
01142
01143
01144 char exitMsg[80];
01145 strcpy (exitMsg, "You are cleared for departure...");
01146 unsigned int white = MakeRGB (255, 255, 255);
01147 DrawTextC (surfExit, &globals->fonts.ftthin24,
01148 globals->screenWidth / 2, globals->screenHeight - 40,
01149 white, exitMsg);
01150 }
01151
01152 static void RedrawExitScreen (void)
01153 {
01154
01155 Draw2D (surfExit);
01156 }
01157
01158 static void CleanupExitScreen (void)
01159 {
01160 FreeBitmap (bmExit);
01161 delete bmExit;
01162 FreeSurface (surfExit);
01163 }
01164
01165 static void ExitApp ()
01166 {
01167
01168 ShutdownAll ();
01169
01170
01171 glutLeaveGameMode ();
01172
01173 CleanupExitScreen ();
01174
01175 #if defined(_DEBUG) && defined(HAVE_CRTDBG_H)
01176
01177 HANDLE hfile = CreateFile ("Logs\\MemoryLeaks.log",
01178 GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
01179 FILE_ATTRIBUTE_NORMAL, NULL);
01180 _CrtSetReportMode (_CRT_WARN, _CRTDBG_MODE_FILE);
01181 _CrtSetReportFile (_CRT_WARN, hfile);
01182 _CrtSetReportMode (_CRT_ERROR, _CRTDBG_MODE_FILE);
01183 _CrtSetReportFile (_CRT_ERROR, hfile);
01184 _CrtMemDumpAllObjectsSince(&memoryState);
01185 CloseHandle (hfile);
01186 #endif
01187
01188
01189
01190
01191
01192 #if defined(WIN32) && defined(_DEBUG)
01193
01194 TerminateProcess (GetCurrentProcess(), 0);
01195 #else
01196 exit (0);
01197 #endif // _WIN32 && _DEBUG
01198 }
01199
01200
01201
01202
01203 static void redraw ()
01204 {
01205
01206 glEnable (GL_DEPTH_TEST);
01207 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
01208
01209 switch (globals->appState) {
01210 case APP_SPLASH_SCREEN:
01211
01212 InitSplashScreen ();
01213 RedrawSplashScreen ();
01214 globals->appState = APP_INIT;
01215 break;
01216
01217 case APP_INIT:
01218 {
01219
01220 Initialize();
01221 RedrawSplashScreen ();
01222 globals->appState = APP_GENERATE_SITUATION;
01223 }
01224 break;
01225
01226 case APP_GENERATE_SITUATION:
01227
01228
01235 RedrawSplashScreen ();
01236 globals->appState = APP_LOADING_SCREEN;
01237 break;
01238
01239 case APP_LOADING_SCREEN:
01240
01241 InitLoadingScreen ();
01242 RedrawLoadingScreen ();
01243 CleanupSplashScreen ();
01244 globals->appState = APP_LOAD_SITUATION;
01245 break;
01246
01247 case APP_LOAD_SITUATION:
01248
01249 {
01250 LoadStartupSituation ();
01251 RedrawLoadingScreen ();
01252 globals->appState = APP_PREPARE;
01253 }
01254 break;
01255
01256 case APP_PREPARE:
01257
01258 globals->sit->Prepare ();
01259 globals->appState = APP_SIMULATION;
01260 RedrawLoadingScreen ();
01261 CleanupLoadingScreen ();
01262 break;
01263
01264 case APP_SIMULATION:
01265
01266 RedrawSimulation ();
01267 break;
01268
01269 case APP_EXIT_SCREEN:
01270
01271 InitExitScreen ();
01272 RedrawExitScreen ();
01273 globals->appState = APP_EXIT;
01274 break;
01275
01276 case APP_EXIT:
01277
01278 ExitApp ();
01279 break;
01280 }
01281
01282 glutPostRedisplay ();
01283 glutSwapBuffers ();
01284 }
01285
01286
01287 int main (int argc, char **argv)
01288 {
01289 #if defined(_DEBUG) && defined(HAVE_CRTDBG_H)
01290
01291 _CrtMemCheckpoint (&memoryState);
01292 #endif
01293
01294
01295 LoadIniSettings ();
01296
01297
01298
01299 InitGlobalsNoPodFilesystem ();
01300 globals->appState = APP_SPLASH_SCREEN;
01301
01302
01303 InitGraphics ();
01304
01305
01306
01307
01308 char flyRootFolder[64];
01309 strcpy (flyRootFolder, "");
01310 GetIniString ("UI", "flyRootFolder", flyRootFolder, 64);
01311 if (strlen (flyRootFolder) == 0) {
01312 strcpy (flyRootFolder, "C:\\Program Files\\Terminal Reality\\Fly! II");
01313 SetIniString ("UI", "flyRootFolder", flyRootFolder);
01314 SaveIniSettings ();
01315 }
01316 pinit (&globals->pfs, flyRootFolder, false);
01317 char *mark1 = new char[32];
01318 strcpy (mark1, "padd Start");
01319 paddpodfolder (&globals->pfs, "System");
01320 char *mark2 = new char[32];
01321 strcpy (mark2, "System End");
01322 padddiskfolder (&globals->pfs, "Saved Simulations");
01323 padddiskfolder (&globals->pfs, "System");
01324 padddiskfolder (&globals->pfs, "Art");
01325 padddiskfolder (&globals->pfs, "BT");
01326 padddiskfolder (&globals->pfs, "Data");
01327 padddiskfolder (&globals->pfs, "Ui");
01328 padddiskfolder (&globals->pfs, "World");
01329 padddiskfolder (&globals->pfs, "Scenery");
01330 paddpodfolder (&globals->pfs, "Aircraft");
01331 paddpodfolder (&globals->pfs, "Scenery\\Shared");
01332 char *mark9 = new char[32];
01333 strcpy (mark9, "padd End");
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346 init_ui ();
01347 char *mark3 = new char[32];
01348 strcpy (mark3, "fonts Start");
01349 InitFonts ();
01350 char *mark4 = new char[32];
01351 strcpy (mark4, "fonts End");
01352
01353
01354 glutMainLoop ();
01355
01356
01357 GLenum e = glGetError ();
01358 if (e != GL_NO_ERROR) {
01359 gtfo ("main() : GL Error 0x%08x", e);
01360 }
01361
01362 return 0;
01363 }
01364
01365
01366 #ifdef _WINDOWS
01367
01368
01369
01370 int APIENTRY WinMain (HINSTANCE hInstance,
01371 HINSTANCE hPrevInstance,
01372 LPSTR lpCmdLine,
01373 int nShowCmd)
01374 {
01375 main(0, NULL);
01376 return 0;
01377 }
01378 #endif // _WINDOWS
01379
01380
01381 void GTFO::operator() (const char* fmt, ...)
01382 {
01383 glutLeaveGameMode ();
01384
01385 CLogFile *log = new CLogFile ("Logs\\gtfo.log", "a");
01386
01387 char usermsg[512];
01388
01389 if (fmt != NULL) {
01390 va_list argp;
01391 va_start(argp, fmt);
01392 vsprintf(usermsg, fmt, argp);
01393 va_end(argp);
01394 } else {
01395
01396 strcpy (usermsg, "");
01397 }
01398
01399
01401 char separator = '\\';
01402 int nSeparators = 0;
01403 int len = strlen(m_file);
01404
01405
01406 char file[1024];
01407 char *c;
01408 for (c = (m_file + len); c >= m_file; c--) {
01409 if (*c == separator) {
01410 nSeparators++;
01411 if (nSeparators == 2) {
01412
01413 c++;
01414 break;
01415 }
01416 }
01417 }
01418 strcpy (file, c);
01419
01420
01421 log->Write ("Abnormal exit\n File: %s Line: %d\n %s\n\n", file, m_line, usermsg);
01422
01423 delete log;
01424
01425 #if defined(WIN32) && defined(_DEBUG)
01426 TerminateProcess (GetCurrentProcess(), 0);
01427 #endif
01428 exit (0);
01429 }
01430
01431 void WARN::operator() (const char* fmt, ...)
01432 {
01433 if (globals->logWarning != NULL) {
01434 char usermsg[512];
01435
01436 if (fmt != NULL) {
01437 va_list argp;
01438 va_start(argp, fmt);
01439 vsprintf(usermsg, fmt, argp);
01440 va_end(argp);
01441 } else {
01442
01443 strcpy (usermsg, "");
01444 }
01445
01446
01448 char separator = '\\';
01449 int nSeparators = 0;
01450 int len = strlen(m_file);
01451
01452
01453 char file[1024];
01454 char *c;
01455 for (c = (m_file + len); c >= m_file; c--) {
01456 if (*c == separator) {
01457 nSeparators++;
01458 if (nSeparators == 2) {
01459
01460 c++;
01461 break;
01462 }
01463 }
01464 }
01465 strcpy (file, c);
01466
01467
01468 globals->logWarning->Write ("Warning\n File: %s Line: %d\n %s\n\n",
01469 file, m_line, usermsg);
01470 }
01471 }
01472
01473 void DEBUG::operator() (const char* fmt, ...)
01474 {
01475 if (globals->logDebug != NULL) {
01476 char usermsg[512];
01477
01478 if (fmt != NULL) {
01479 va_list argp;
01480 va_start(argp, fmt);
01481 vsprintf(usermsg, fmt, argp);
01482 va_end(argp);
01483 } else {
01484
01485 strcpy (usermsg, "");
01486 }
01487
01488
01490 char separator = '\\';
01491 int nSeparators = 0;
01492 int len = strlen(m_file);
01493
01494
01495 char file[1024];
01496 char *c;
01497 for (c = (m_file + len); c >= m_file; c--) {
01498 if (*c == separator) {
01499 nSeparators++;
01500 if (nSeparators == 2) {
01501
01502 c++;
01503 break;
01504 }
01505 }
01506 }
01507 strcpy (file, c);
01508
01509
01510 globals->logDebug->Write ("Debug\n File: %s Line: %d\n %s\n\n",
01511 file, m_line, usermsg);
01512 }
01513 }