src/main.cpp

Go to the documentation of this file.
00001  // vim: set noet sw=8 cino=:
00002 #define GL_GLEXT_PROTOTYPES
00003 
00004 #include <fenv.h>
00005 
00006 #include <stdio.h>
00007 #include <stdlib.h>
00008 #include <GL/gl.h>
00009 #include <GL/glu.h>
00010 #include <GL/glext.h>
00011 #include <SDL/SDL.h>
00012 #include <math.h>
00013 #include <string>
00014 #include <vector>
00015 
00016 using namespace std;
00017 
00018 #include "font.h"
00019 #include "utility.h"
00020 #include "textures.h"
00021 #include "backdrop.h"
00022 #include "camera.h"
00023 #include "weather.h"
00024 #include "keyman.h"
00025 #include "mouse.h"
00026 #include "messageq.h"
00027 #include "particles.h"
00028 /*#include "mesh.h"                     // Header File For The MESH Class
00029 #include "entity.h"                     // ...etc
00030 #include "meshlist.h"
00031 #include "entitylist.h"
00032 #include "water.h"
00033 #include "model.h"
00034 #include "gamedb.h"
00035 #include "ships.h"*/
00036 #include "settings.h"
00037 #include "sound.h"
00038 /* #include "menu.h" */
00039 #include "timer.h"
00040 #include "controls.h"
00041 #include "vamosworld.h"
00042 #include "replay.h"
00043 //#include "trees.h"
00044 #include "logo.h"
00045 #include "gamestate.h"
00046 #include "objects.h"
00047 #include "multiplay.h"
00048 #include "net.h"
00049 #include "configfile.h"
00050 #include "bezier.h"
00051 #include "track.h"
00052 #include "textures.h"
00053 #include "exception.h"
00054 #include "cardinfo.h"
00055 
00056 using namespace VDrift;
00057 
00058 #include <vamos/body/Gl_Car.h>
00059 #include <vamos/geometry/Texture_Image.h>
00060 #include <vamos/geometry/Three_Vector.h>
00061 //#include <vamos/track/Strip_Track.h>
00062 #include <vamos/body/Car.h>
00063 #include <vamos/body/Fuel_Tank.h>
00064 #include <vamos/body/Wheel.h>
00065 #include <vamos/geometry/Conversions.h>
00066 //#include <vamos/track/Track.h>
00067 #include <vamos/world/World.h>
00068 
00069 #include "gui/gui.h"
00070 
00071 #ifdef _WIN32
00072 //#define GL_GLEXT_PROTOTYPES
00073 #include <GL/glext.h>
00074 //#include <GL/wglext.h>
00075 //#include <GL/glprocs.h>
00076 #endif
00077 
00078 //#define PERFORMANCE_PROFILE
00079 
00080 //fps less than below will not tick the simulation
00081 //#define MIN_FPS 5.0
00082 
00083 #ifdef PERFORMANCE_PROFILE
00084 #include <sys/time.h>
00085 suseconds_t GetMicroSeconds()
00086 {
00087         struct timeval tv;
00088         struct timezone tz;
00089                 
00090         tz.tz_minuteswest = 0;
00091         tz.tz_dsttime = 0;
00092         
00093         gettimeofday(&tv, &tz);
00094         
00095         return tv.tv_usec;
00096 }
00097 #endif
00098 
00099 
00100 // Set up some booleans
00101 #define TRUE  1
00102 #define FALSE 0
00103 
00104 // screen width, height, and bit depth
00105 //const int SCREEN_WIDTH = 1024;
00106 //const int SCREEN_HEIGHT = 768;
00107 //const int SCREEN_BPP = 32;
00108 
00109 int SCREEN_WIDTH = 1024;
00110 int SCREEN_HEIGHT = 768;
00111 int SCREEN_BPP = 32;
00112 
00113 //#define PATCH_DEBUG
00114 
00115 bool verbose_output = false;
00116 
00117 //bool in_menu = false;
00118 //bool menu_display = false;
00119 
00120 /*const int SCREEN_WIDTH = 1280;
00121 const int SCREEN_HEIGHT = 1024;
00122 const int SCREEN_BPP = 32;*/
00123 
00124 // This is our SDL surface
00125 SDL_Surface *surface;
00126 
00127 // Ambient Light Values ( NEW )
00128 //GLfloat LightAmbient[]  = { 1.0f, 1.0f, 1.0f, 1.0f };
00129 GLfloat LightAmbient[]  = { 0.15f, 0.15f, 0.15f, 1.0f };
00130 // Diffuse Light Values ( NEW )
00131 //GLfloat LightDiffuse[]  = { 1.0f, 1.0f, 1.0f, 1.0f };
00132 GLfloat LightDiffuse[]  = { 1.0f, 1.0f, 1.0f, 1.0f };
00133 GLfloat LightSpecular[]  = { 0.0f, 0.0f, 0.0f, 0.0f };
00134 // Light Position ( NEW )
00135 GLfloat LightPosition[4];
00136 
00137 /*
00138 ENTITYLIST entities;
00139 MESHLIST meshes;
00140 TERRAIN terrain;
00141 TREES foliage;
00142 WATER water;
00143 GAMEDB gamedb;
00144 SHIPS ships;*/
00145 KEYMAN keyman;
00146 GAMECONTROLS gamecontrols;
00147 SETTINGS settings;
00148 TEXTURES textures;
00149 CAMERA cam;
00150 FONT font;
00151 UTILITY utility;
00152 BACKDROP backdrop;
00153 WEATHER weathersystem;
00154 MOUSE mouse;
00155 MESSAGEQ mq1;
00156 //TERRAIN terrain;
00157 PARTICLE particle;
00158 SOUNDMANAGER sound;
00159 /* MENU menu; */
00160 TIMER timer;
00161 REPLAY replay;
00162 //TREES trees;
00163 LOGO logo;
00164 GAMESTATE state;
00165 OBJECTS objects;
00166 NET net;
00167 MULTIPLAY multiplay;
00168 VGUI::Gui gui;
00169 TRACK track;
00170 CARDINFO gfxcard;
00171 
00172 VAMOSWORLD world;
00173 //Vamos_Track::Strip_Track *road;
00174 
00175 ofstream error_log;
00176 
00177 #define CAR_Y_OFFSET 1.0
00178 
00179 double day_time;
00180 double abs_time;
00181 
00182 //for game timing and FPS stuff
00183 static GLint T0;
00184 static GLint Frames;
00185 static GLfloat fps;
00186 
00187 bool showfps;
00188 
00189 static int frameno;
00190 
00191 float timefactor = 1.0f;
00192 
00193 //#define AVERAGEFRAMES 30
00194 #define AVERAGEFRAMES 5
00195 
00196 float pfps;
00197 float lfps[AVERAGEFRAMES];
00198 int lfpspos = 0;
00199 bool lfpsfull = false;
00200 
00201 //#define FRAME_TIME 0.002
00202 #define FRAME_TIME 0.004
00203 double execution_time = 0.0;
00204 
00205 bool pauserequest = false;
00206 bool unpauserequest = false;
00207 bool esc_pressed = false;
00208 
00209 float view_dist = 10000.0;
00210 
00211 //int screenshots = 0;
00212 string cur_tex_size = "";
00213 int cur_screen_w = 0;
00214 int cur_screen_h = 0;
00215 int cur_screen_bpp = 0;
00216 bool cur_fullscreen = false;
00217 string tree_detail = "";
00218 
00219 float FrameTime()
00220 {
00221         return FRAME_TIME;
00222 }
00223 
00224 int Screenshot(char *filename)
00225 {
00226         SDL_Surface *screen;
00227         SDL_Surface *temp = NULL;
00228         unsigned char *pixels;
00229         int i;
00230         
00231         screen = surface;
00232         
00233         if (!(screen->flags & SDL_OPENGL))
00234         {
00235                 SDL_SaveBMP(temp, filename);
00236                 return 0;
00237         }
00238         
00239         temp = SDL_CreateRGBSurface(SDL_SWSURFACE, screen->w, screen->h, 16,
00240         #if SDL_BYTEORDER == SDL_LIL_ENDIAN
00241         0x000000FF, 0x0000FF00, 0x00FF0000, 0
00242         #else
00243         0x00FF0000, 0x0000FF00, 0x000000FF, 0
00244         #endif
00245         );
00246         if (temp == NULL)
00247                 return -1;
00248         
00249         pixels = (unsigned char *) malloc(3 * screen->w * screen->h);
00250         if (pixels == NULL)
00251         {
00252                 SDL_FreeSurface(temp);
00253                 return -1;
00254         }
00255         
00256         glReadPixels(0, 0, screen->w, screen->h, GL_RGB, GL_UNSIGNED_BYTE, pixels);
00257         
00258         for (i=0; i<screen->h; i++)
00259                 memcpy(((char *) temp->pixels) + temp->pitch * i, pixels + 3*screen->w * (screen->h-i-1), screen->w*3);
00260         free(pixels);
00261         
00262         SDL_SaveBMP(temp, filename);
00263         SDL_FreeSurface(temp);
00264         return 0;
00265 }
00266 
00267 void ResetWorld(bool fullreset);
00268 
00275 void Quit(int returnCode)
00276 {
00277         state.SetGameState(STATE_EXIT);
00278 
00279         if (replay.Recording() != -1)
00280                 replay.Stop();
00281 
00282         gamecontrols.WriteControlFile();
00283 
00284         if (verbose_output)
00285                 cout << "Quit called" << endl;
00286 
00287         error_log.close();
00288 
00289         /* clean up the window */
00290         SDL_Quit( );
00291 
00292         if (verbose_output)
00293                 cout << "SDL_Quit finished" << endl;
00294 
00295         exit(returnCode);
00296 }
00297 
00298 // function to reset our viewport after a window resize
00299 int resizeWindow( int width, int height )
00300 {
00301         // Height / width ration
00302         GLfloat ratio;
00303  
00304         // Protect against a divide by zero
00305         if ( height == 0 )
00306                 height = 1;
00307 
00308         ratio = ( GLfloat )width / ( GLfloat )height;
00309 
00310         // Setup our viewport.
00311         glViewport( 0, 0, ( GLint )width, ( GLint )height );
00312 
00313         // change to the projection matrix and set our viewing volume.
00314         glMatrixMode( GL_PROJECTION );
00315         glLoadIdentity( );
00316 
00317         // Set our perspective
00318         gluPerspective( 45.0f, ratio, 0.1f, 10000.0f );
00319 
00320         // Make sure we're chaning the model view and not the projection
00321         glMatrixMode( GL_MODELVIEW );
00322 
00323         // Reset The View
00324         glLoadIdentity( );
00325 
00326         return( TRUE );
00327 }
00328 
00329 void LoadingScreen(string loadtext);
00330 
00331 void ChangeDisplay(int w, int h, int bpp, bool fullscreen, bool reloadtextures)
00332 {
00333         SCREEN_WIDTH = w;
00334         SCREEN_HEIGHT = h;
00335         SCREEN_BPP = bpp;
00336         
00337         // the flags to pass to SDL_SetVideoMode
00338         int videoFlags = SDL_OPENGL;       // Enable OpenGL in SDL
00339         videoFlags |= SDL_GL_DOUBLEBUFFER; // Enable double buffering
00340         videoFlags |= SDL_HWPALETTE;       // Store the palette in hardware
00341         videoFlags |= SDL_RESIZABLE;       // Enable window resizing
00342 
00343         // This checks to see if surfaces can be stored in memory
00344         /*if ( videoInfo->hw_available )
00345                 videoFlags |= SDL_HWSURFACE;
00346         else
00347                 videoFlags |= SDL_SWSURFACE;
00348 
00349         if ( videoInfo->blit_hw )
00350                 videoFlags |= SDL_HWACCEL;*/
00351 
00352         if (fullscreen)
00353         {
00354                 videoFlags |= SDL_HWSURFACE|SDL_ANYFORMAT|SDL_FULLSCREEN;  
00355         }       
00356         else
00357         {
00358                 videoFlags |= SDL_SWSURFACE|SDL_ANYFORMAT;
00359         }
00360 
00361         // get a SDL surface
00362         if (surface != NULL)
00363         {
00364                 SDL_FreeSurface(surface);
00365                 surface = NULL;
00366         }
00367         surface = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, videoFlags );
00368 
00369         resizeWindow( SCREEN_WIDTH, SCREEN_HEIGHT );
00370 
00371         if (reloadtextures)
00372         {
00373                 if( gui.GetEnabled() ) gui.SetEnabled( false );
00374                 LoadingScreen("Loading...\nReloading textures");
00375                 //textures.DeleteAll();
00376                 textures.ReloadAll();
00377                 LoadingScreen("Loading...\nFont");
00378                 font.Load();
00379                 LoadingScreen("Loading...\nBackdrop");
00380                 backdrop.Init();
00381                 //menu.Load();
00382                 LoadingScreen("Loading...\nGame Controls");
00383                 gamecontrols.LoadControls();
00384                 LoadingScreen("Loading...\nParticles");
00385                 particle.Load();
00386                 LoadingScreen("Loading...\nTimer");
00387                 timer.Load();
00388                 LoadingScreen("Loading...\nHUD");
00389                 world.UnloadHUD();
00390                 world.LoadHUD();
00391                 LoadingScreen("Loading...\nUser interface");
00392                 //gui.DeInit();
00393                 gui.ReInit();
00394                 //menu.MainMenu();
00395                 //gui.ChangePage( "Main" );
00396                 //gui.SetEnabled( true );
00397         }
00398 
00399         gui.UpdateScreenSize();
00400 }
00401 
00402 void ReloadDisplay()
00403 {
00404         string tex_size;
00405         int w, h, bpp;
00406         bool fullscreen, show_fps, reload_tex;
00407 
00408         settings.Get( "display.width", w );
00409         settings.Get( "display.height", h );
00410         settings.Get( "display.depth", bpp );
00411         settings.Get( "display.fullscreen", fullscreen );
00412         settings.Get( "display.show_fps", show_fps );
00413         settings.Get( "display.texture_size", tex_size );
00414         settings.Get( "display.view_distance", view_dist );
00415         settings.Get( "display.tree_detail", tree_detail );
00416 
00417         reload_tex = ( tex_size == cur_tex_size ) &&
00418                      ( w == cur_screen_w ) &&
00419                      ( h == cur_screen_h ) &&
00420                      ( fullscreen == cur_fullscreen ) &&
00421                      ( bpp == cur_screen_bpp ) ? false : true;
00422         reload_tex = true;
00423 
00424         showfps = show_fps;
00425         world.UpdateSettings();
00426         objects.UpdateSettings();
00427         //trees.UpdateSettings();
00428         //terrain.UpdateSettings();
00429         ChangeDisplay( w, h, bpp, fullscreen, reload_tex );
00430         cur_tex_size = tex_size;
00431         cur_screen_w = w;
00432         cur_screen_h = h;
00433         cur_screen_bpp = bpp;
00434         cur_fullscreen = fullscreen;
00435 }
00436 
00437 void Update()
00438 {
00439         //cam.position.DebugPrint();
00440 
00441         if (MP_DBGDEEP)
00442                 cout << "main update start" << endl;
00443 
00444         bool mainloop = false;
00445 
00446         //if unpaused and getting a reasonable framerate
00447         //if (fps > MIN_FPS && timefactor != 0.0f)
00448         if (fps > 0.0f && timefactor != 0.0f && state.GetGameState() != STATE_INITIALMENU)
00449         {
00450                 /*VERTEX campos = cam.position;
00451                 campos.Scale(-1.0);
00452                 cout << campos.x << "," << campos.z << ": " << track.Elevation(campos) << endl;*/
00453                 
00454                 
00455                 execution_time += timefactor / fps;
00456                 int num_updates = (int) (execution_time / FRAME_TIME);
00457                 double this_frame = (double) num_updates * FRAME_TIME;
00458 
00459                 mouse.Update(cam, SCREEN_WIDTH, SCREEN_HEIGHT, timefactor, fps);
00460                 weathersystem.Update(abs_time);
00461 
00462                 while (execution_time > FRAME_TIME)
00463                 {
00464                         #ifdef PERFORMANCE_PROFILE
00465                         suseconds_t t1, t2;
00466                         t1 = GetMicroSeconds();
00467                         t1 = GetMicroSeconds();
00468                         #endif
00469 
00470                         //multiplay.Update(FRAME_TIME);
00471                         
00472                         //weather tick
00473 
00474                         #ifdef PERFORMANCE_PROFILE
00475                         t2 = GetMicroSeconds();
00476                         cout << "multiplay.Update() ticks: " << t2-t1 << endl;
00477                         t1 = GetMicroSeconds();
00478                         #endif
00479 
00480                         //timer tick
00481                         //timer.TickTimer(timefactor,fps);
00482                         timer.TickTimer(1.0, 1.0/FRAME_TIME);
00483 
00484                         cam.Update();
00485 
00486                         //handle input
00487                         //keyman.DoHeldKeys(timefactor, fps, cam);
00488                         keyman.DoHeldKeys(1.0, 1.0/FRAME_TIME, cam);
00489 
00490                         #ifdef PERFORMANCE_PROFILE
00491                         t1 = GetMicroSeconds();
00492                         t1 = GetMicroSeconds();
00493                         #endif
00494 
00495                         //world.Update(timefactor, fps, js);
00496                         world.Update(1.0, 1.0/FRAME_TIME, gamecontrols.Get_js());
00497 
00498                         #ifdef PERFORMANCE_PROFILE
00499                         t2 = GetMicroSeconds();
00500                         cout << "world update ticks: " << t2-t1 << endl;
00501                         t1 = GetMicroSeconds();
00502                         #endif
00503 
00504                         keyman.DoOneTimeKeys(cam);
00505 
00506                         //particle.Update(timefactor, fps);
00507                         //particle.Update(1.0, 1.0/FRAME_TIME);
00508 
00509                         cam.ExtractFrustum();
00510 
00511                         LightPosition[0] = cos(backdrop.sunpos_lat);
00512                         LightPosition[1] = sin(backdrop.sunpos_lat);
00513                         if (LightPosition[1] < 0)
00514                                 LightPosition[1] *= 10.0f; //to simulate sun disappearing behind horizon
00515                         LightPosition[2] = 0.0f;//tan(backdrop.sunpos_lng);
00516 
00517                         float dusktime = 0.5;
00518                         float dawntime = 0.0;
00519                         float transtime = 0.05;
00520 
00521                         float diffuse = 1.0f;
00522                         if (day_time >= dusktime || day_time <= dawntime)
00523                         {
00524                                 diffuse = 0.0;
00525                         }
00526 
00527                         if (day_time > dawntime && day_time < transtime)
00528                         {
00529                                 diffuse = day_time / (transtime);
00530                         }
00531 
00532                         if (day_time > dusktime - transtime && day_time < dusktime)
00533                         {
00534                                 diffuse = (day_time - dusktime - transtime) / transtime;
00535                         }
00536 
00537                         diffuse = diffuse*0.9+0.1;
00538 
00539                         VERTEX ld;
00540                         ld.Set(LightDiffuse[0], LightDiffuse[1], LightDiffuse[2]);
00541                         ld.Scale(diffuse);
00542                         glLightfv( GL_LIGHT1, GL_DIFFUSE, ld.v3() );
00543 
00544                         //float timepassed = (timefactor/fps)/86400.0;
00545                         float timepassed = (FRAME_TIME)/86400.0;
00546                         /*if (keyman.keys[keyman.GetKey("AccelTimeVFast")])
00547                                 timefactor = 10000.0;
00548                         else if (keyman.keys[keyman.GetKey("AccelTimeFast")])
00549                                 timefactor = 1000.0;
00550                         else
00551                                 timefactor = 1.0;*/
00552                         //float timepassed = (timefactor/fps)/60.0;
00553                         //float timepassed = (timefactor/fps)/10.0;
00554                         abs_time += timepassed;
00555                         day_time += timepassed;
00556                         if (day_time > 1.0f)
00557                                 day_time -= 1.0f;
00558 
00559                         #ifdef PERFORMANCE_PROFILE
00560                         t2 = GetMicroSeconds();
00561                         cout << "Time increment ticks: " << t2-t1 << endl;
00562                         t1 = GetMicroSeconds();
00563                         #endif
00564 
00565                         multiplay.Send(FRAME_TIME);
00566 
00567                         mainloop = true;
00568 
00569                         //terrain.Update(cam, timefactor, fps, day_time);
00570                         //terrain.Update(cam, 1.0, 1.0/FRAME_TIME, day_time);
00571 
00572                         execution_time -= FRAME_TIME;
00573                         num_updates++;
00574 
00575                         //replay.IncrementFrame();
00576                 }
00577                 particle.Update(1.0, 1.0/this_frame);
00578 //              terrain.Update(cam, 1.0, 1.0/this_frame, day_time);
00579         }
00580         else
00581         {
00582                 //print "paused"
00583                 if (state.GetGameState() != STATE_INITIALMENU)
00584                         world.Update(timefactor, fps, gamecontrols.Get_js());
00585         }
00586 
00587         if (pauserequest)
00588         {
00589                 if (timefactor != 0.0f)
00590                         timefactor = 0.0f;
00591                 pauserequest = false;
00592         }
00593         if (unpauserequest)
00594         {
00595                 if (timefactor == 0.0f)
00596                         timefactor = 1.0f;
00597                 unpauserequest = false;
00598         }
00599 
00600         sound.Update();
00601         /*if (!mainloop)
00602                 multiplay.Update(0);*/ //don't need this anymore because we're stopping things from being paused in multiplayer mode
00603 
00604         if (MP_DBGDEEP)
00605                 cout << "main update done" << endl;
00606 }
00607 
00608 void snap_screenshot()
00609 {
00610         char scrname[64];
00611         int num_shots;
00612         settings.Get( "game.num_shots", num_shots );
00613         sprintf(scrname, "%s/screenshots/shot%03d.bmp", (settings.GetSettingsDir()).c_str(), num_shots );
00614         Screenshot(scrname);
00615         settings.Set( "game.num_shots", num_shots + 1 );
00616 }
00617 
00618 void MainPause()
00619 {
00620         //if (!menu.InMenu() && !multiplay.NumConnected() > 0)
00621         //if (state.GetGameState() == STATE_PLAYING)
00622         if( !gui.GetEnabled() && !multiplay.NumConnected() > 0 )
00623                 pauserequest = true;
00624         /*bool mouse_enabled;
00625         settings.Get( "mouse.enabled", mouse_enabled );
00626         if( mouse_enabled )
00627         {
00628                 gui.MouseReturn();
00629         }*/
00630         gui.ProcessAction( "Pause" );
00631 }
00632 
00633 void MainUnpause()
00634 {
00635         unpauserequest = true;
00636 }
00637 
00638 // function to handle key press events
00639 void handleKeyPress( SDL_keysym *keysym )
00640 {
00641         //Vamos_Geometry::Three_Vector tvec1(44.464,-126.8737,0);
00642         //VERTEX tvec2;
00643         //QUATERNION trot;
00644 
00645         //if (state.GetGameState() == STATE_MENU)
00646         //if (menu.InMenu())
00647         //      menu.MenuKey(keysym->sym);
00648         //else if (timefactor == 0 && !menu.InMenu()) timefactor = 0;
00649                 //              else timefactor = 1.0;
00650         if( !gui.GetEnabled() )
00651         {
00652                 switch ( keysym->sym )
00653                 {
00654                 case SDLK_ESCAPE:
00655                         // ESC key was pressed
00656                         //Quit(0);
00657                         //gui.ChangePage( "InGameMenu" );
00658                         //menu.MainMenu();
00659                         esc_pressed = true;
00660                         break;
00661                 /*case SDLK_F7:
00662                         
00663                         tvec1 = tvec1.rotate(0,0,6.21652);
00664                         cout << tvec1[0] << "," << tvec1[1] << endl;
00665                 
00666                         
00667                         tvec2.Set(44.464,-126.8737,0);
00668                         
00669                         trot.Rotate(6.21652, 0, 0, 1);
00670                         tvec2 = trot.RotateVec(tvec2);
00671                         tvec2.DebugPrint();
00672                         break;*/
00673                 /*case SDLK_F7:
00674                         if (timefactor != 100.0f)
00675                                 timefactor = 100.0f;
00676                         else
00677                                 timefactor = 1.0f;
00678                         break;*/
00679                 /*case SDLK_PAGEUP:
00680                         //tmpvert = cam.GetVelocity();
00681                         cam.MoveRelative(0.0f, 0.0f, -2.0f);
00682                         //cam.Update();
00683                         //cam.LoadVelocityIdentity();
00684                         break;
00685                 case SDLK_PAGEDOWN:
00686                         //tmpvert = cam.GetVelocity();
00687                         cam.MoveRelative(0.0f, 0.0f, 2.0f);
00688                         //cam.Update();
00689                         //cam.LoadVelocityIdentity();
00690                         break;*/
00691                 
00692                 //case SDLK_F11:
00693                         //SDL_WM_ToggleFullScreen( surface );
00694                         //ChangeDisplay(1280,1024,32,true);
00695                         //menu.DisplayMenu();//DisplaySelect();
00696                         //break;
00697                 
00698                 //case SDLK_F12:
00699                         //menu.MainMenu();
00700                         //break;
00701 
00702                 default:
00703                         /*if (timefactor == 0.0f)
00704                                 MainUnpause();
00705                         else
00706                                 keyman.OneTime(keysym->sym);*/
00707                         break;
00708                 }
00709         }
00710 
00711         return;
00712 }
00713 
00714 void handleKeyRelease( SDL_keysym *keysym )
00715 {
00716         if( !gui.GetEnabled() )
00717         {
00718                 switch ( keysym->sym )
00719                 {
00720                 case SDLK_ESCAPE:
00721                         // ESC key was released
00722                         if( esc_pressed )
00723                         {
00724                                 esc_pressed = false;
00725                                 MainPause();
00726                         }
00727                         break;
00728                 default:
00729                         /*if (timefactor == 0.0f)
00730                                 MainUnpause();
00731                         else*/
00732                                 keyman.OneTime(keysym->sym);
00733                         break;
00734                 }
00735         }
00736 
00737         return;
00738 }
00739 
00740 void glSetup()
00741 {
00742         // Enable Texture Mapping ( NEW )
00743         glEnable( GL_TEXTURE_2D );
00744         // Enable smooth shading
00745         glShadeModel( GL_SMOOTH );
00746         // Set the background black
00747         //glClearColor( 0.53f, 0.74f, 0.91f, 0.0f );
00748         glClearColor(0,0,0,0);
00749         // Depth buffer setup
00750         glClearDepth( 1.0f );
00751         // Enables Depth Testing
00752         glEnable( GL_DEPTH_TEST );
00753         // The Type Of Depth Test To Do
00754         glDepthFunc( GL_LEQUAL );
00755         // Really Nice Perspective Calculations
00756         glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
00757         // Enable Lighting
00758         glEnable( GL_LIGHTING );
00759 
00760         //set the clipping planes
00761         //glFrustum(1000,1000,1000,1000,1,1000);
00762 
00763         //utility.Tex2D(3, false);
00764         //utility.Tex2D(2, false);
00765         //utility.Tex2D(1, false);
00766         //utility.Tex2D(0, true);
00767 }
00768 
00769 //string otrack_file;
00770 //string car_file;
00771 string data_dir;
00772 //int car_paint;
00773 
00774 //int number_of_opponents;
00775 //int focused_car;
00776 
00777 void SelectCar(string cfile, bool trim)
00778 {       
00779         //if (clearold)
00780         world.clear_cars();
00781         //string car_name;
00782         //settings.Get( "game.selected_car", car_name );
00783         //int car_paint;
00784         //settings.Get( "game.car_paint", car_paint );
00785         //car_file = cfile;
00786         state.SetCarName(0, cfile);
00787 
00788         Vamos_Body::Gl_Car* car = 0;
00789 /*      try
00790         {
00791 */              car = new Vamos_Body::Gl_Car (Vamos_Geometry::Three_Vector (11.0, 0.0, 0.6));
00792                 car->read (data_dir, cfile);
00793                 car->SetPaint(state.GetCarPaint(0));
00794                 car->chassis ().translate (Vamos_Geometry::Three_Vector(track.GetStart().x, -track.GetStart().z, track.GetStart().y));
00795                 car->chassis ().translate (Vamos_Geometry::Three_Vector (10.0*multiplay.MyNum(), 0.0, 
00796                                                                                            -car->chassis ().lowest_contact_position () + CAR_Y_OFFSET));
00797                 car->start_engine ();
00798                 car->set_controller(1);
00799                 world.add_car (car);
00800 
00801                 /*for (int i = 0; i < number_of_opponents; i++)
00802                 {
00803                         car = new Vamos_Body::Gl_Car (Vamos_Geometry::Three_Vector (11.0, 0.0, 0.6));
00804                         car->read (data_dir, cfile);
00805                         car->chassis ().translate (Vamos_Geometry::Three_Vector (10.0 * (i + 1), 0.0, 
00806                                 -car->chassis ().lowest_contact_position () + CAR_Y_OFFSET));
00807                         car->start_engine ();
00808                         car->set_controller(-1);
00809                         world.add_car (car);
00810                 }*/
00811 
00812                 int i;
00813                 //if (!multiplay.Server()) //the client re-loads the world, the server doesn't (NOT TRUE ANYMORE)
00814                 {
00815                         for (i = 0; i < multiplay.NumConnected()+1; i++)
00816                         {
00817                                 if (i != multiplay.MyNum())
00818                                 {
00819                                         int idx = i;
00820                                         if (idx == 0)
00821                                                 idx = 1;
00822                                         car = new Vamos_Body::Gl_Car (Vamos_Geometry::Three_Vector (11.0, 0.0, 0.6));
00823                                         car->read (data_dir, state.GetCarName(idx));
00824                                         car->SetPaint(state.GetCarPaint(idx));
00825                                         car->chassis ().translate (Vamos_Geometry::Three_Vector(track.GetStart().x, -track.GetStart().z, track.GetStart().y));
00826                                         car->chassis ().translate (Vamos_Geometry::Three_Vector (10.0*i, 0.0, 
00827                                                 -car->chassis ().lowest_contact_position () + CAR_Y_OFFSET));
00828                                         car->start_engine ();
00829                                         car->set_controller(2);
00830                                         world.add_car (car);
00831                                 }
00832                         }
00833                 }
00834 
00835                 if (replay.GhostCar())
00836                 {
00837                         car = new Vamos_Body::Gl_Car (Vamos_Geometry::Three_Vector (11.0, 0.0, 0.6));
00838                         car->read (data_dir, replay.ReplayCar());
00839                         car->SetPaint(replay.ReplayPaint());
00840                         car->chassis ().translate (Vamos_Geometry::Three_Vector (10.0*multiplay.MyNum(), 0.0, 
00841                                 -car->chassis ().lowest_contact_position () + CAR_Y_OFFSET));
00842                         car->start_engine ();
00843                         car->set_controller(3);
00844                         world.add_car (car);
00845                 }
00846 
00847                 world.reset();
00848 /*      }
00849         catch (Vamos_Geometry::XML_Exception& error)
00850         {
00851                 std::cerr << error.message () << std::endl;
00852                 std::exit (EXIT_FAILURE);
00853         }
00854 */
00855         if (trim)
00856                 ResetWorld(false);
00857 }
00858 
00859 bool UnloadWorld()
00860 {
00861         //these should have error catching such that if they're called before
00862         // init, it's OK
00863         //textures.DeleteAll();
00864         backdrop.DeInit();
00865 //      terrain.DeInit();
00866         world.DeInit();
00867         sound.Unload();
00868         
00869         return true;
00870 }
00871 
00872 #ifdef PATCH_DEBUG
00873 BEZIER * thepatch;
00874 #endif
00875 
00876 bool LoadWorld()
00877 {
00878         UnloadWorld();
00879 
00880         //begin loading world
00881         timefactor = 1.0;
00882         
00883         //reset best lap time
00884         timer.ResetBest();
00885         timer.ResetLast();
00886 
00887         LoadingScreen("Loading...\nConfiguration files");
00888 
00889         //state.SetCarName( 0, "" );
00890         //state.SetCarPaint( 0, 0 );
00891         //state.SetTrackName( "" );
00892 
00893         string selected_car = "";
00894         string track_name;
00895         int car_paint = 0;
00896 
00897         settings.Get( "game.selected_car", selected_car );
00898         settings.Get( "game.car_paint", car_paint );
00899         settings.Get( "game.track", track_name );
00900 
00901         //cout << "selected " << track_name << " " << selected_car << endl;
00902         state.SetCarName( 0, selected_car );
00903         state.SetCarPaint( 0, car_paint );
00904         state.SetTrackName( track_name );
00905 
00906         if (state.GetCarName(0) == "")
00907                 state.SetCarName(0, "CS");
00908 
00909         //if (track_name == "")
00910         //      state.SetTrackName( "ruudskogen" );
00911 
00912         //string world_file = "default-world";
00913         //string controls_file = "default-controls";
00914         //number_of_opponents = 0;
00915         //focused_car = 0;
00916         //string track_file = "tracks/" + state.GetTrackName() + "/" + state.GetTrackName() + ".xml";
00917         //world_file = "worlds/" + world_file + ".xml";
00918         //controls_file = settings.GetSettingsDir() + "/controls/" + controls_file + ".xml";
00919         data_dir = settings.GetDataDir() + "/";
00920 
00921         /*LoadingScreen("Loading...\nLoading terrain");
00922         //terrain.Init(2000,200,2000,"outermap3.raw","outermap1-detail.bmp","outermap2-test.png");
00923         //terrain.Init(2000,200,2000,"shaw4.raw","outermap1-detail.bmp","shawtestmap2.png", REFLECT_RES);
00924         //terrain.Init(2000,200,2000,"shawlike.raw","detail-lowfreq.bmp","shawlike.png", REFLECT_RES_X, REFLECT_RES_Y);
00925         //terrain.Init(2000,200,2000,"outermap4.raw","outermap1-detail.bmp","outermap4v1.png");
00926         string terrainfile;
00927         string trackpath = settings.GetDataDir() + "/tracks/" + state.GetTrackName() + "/";
00928         terrainfile = trackpath + "parameters.txt";
00929 
00930         ifstream tf(terrainfile.c_str());
00931         int numparam, i;
00932         numparam = 7;
00933         float param[numparam];
00934         if (tf)
00935         {
00936                 for (i = 0; i < numparam; i++)
00937                         param[i] = utility.fGetParam(tf);
00938                 terrain.Init((int)param[0],(int)param[1],(int)param[2], trackpath+"terrain.png", trackpath+"mask.png", trackpath+"texture.png", trackpath+"detail.png", trackpath+"detail2.png", trackpath+"parametric.png", param[3], param[4], param[5], param[6]);
00939         }
00940         else
00941         {
00942                 cout << "Couldn't find track terrain parameter file " << terrainfile << endl;
00943                 //terrain.Init(3000,300,3000, otrack_file+".png", otrack_file+"-mask.png", otrack_file+".png", otrack_file+"-detail.png", otrack_file+"-detail2.png", otrack_file+"-parametric.png", -1500, -2000, 150, 100);
00944                 param[0] = 3000; param[1] = 300; param[2] = 3000;
00945                 param[3] = -1500;
00946                 param[4] = -2000;
00947                 param[5] = 150;
00948                 param[6] = 100;
00949                 terrain.Init((int)param[0],(int)param[1],(int)param[2], trackpath+"terrain.png", trackpath+"mask.png", trackpath+"texture.png", trackpath+"detail.png", trackpath+"detail2.png", trackpath+"parametric.png", param[3], param[4], param[5], param[6]);
00950         }
00951 
00952         LoadingScreen("Loading...\nTrack");
00953         try
00954         {
00955                 road = new Vamos_Track::Strip_Track;
00956                 road->read (data_dir, track_file);
00957         }
00958         catch (Vamos_Geometry::XML_Exception& error)
00959         {
00960                 std::cerr << error.message () << std::endl;
00961                 std::exit (EXIT_FAILURE);
00962         }*/
00963 
00964         LoadingScreen("Loading...\nTrack");
00965         track.Load(state.GetTrackName());
00966         
00967         LoadingScreen("Loading...\nLoading backdrop");
00968         backdrop.Init();
00969         
00970         LoadingScreen("Loading...\nLoading scenery objects");
00971         string objectpath = settings.GetDataDir() + "/tracks/" + state.GetTrackName() + "/objects";
00972         objects.LoadObjectsFromFolder(objectpath);
00973 
00974         #ifdef COLLISION_TESTING
00975         if (0)
00976         {
00977                 bool col = false;
00978                 VERTEX origin, dir, colpt, normal;
00979                 bool closest = true;
00980                 origin.Set(496.334,1000,-1.11335);
00981                 dir.Set(0,-1,0);
00982                 BEZIER * colpatch;
00983                 ROADSTRIP * colstrip;
00984                 ofstream deb;
00985                 deb.open("debug.log");
00986                 deb << "Debug log start" << endl;
00987                 deb.close();
00988                 
00989                 col = track.CollideRoads(origin, dir, colpt, closest, colstrip, colpatch, normal);
00990                 deb.open("debug.log", ofstream::out | ofstream::app);
00991                 deb << "col: " << col << endl;
00992                 deb << "origin: "; origin.DebugPrint(deb);
00993                 deb << "dir: "; dir.DebugPrint(deb);
00994                 deb << "colpt: "; colpt.DebugPrint(deb);
00995                 deb << "closest: " << closest << endl;
00996                 deb << "normal: "; normal.DebugPrint(deb);
00997                 deb << "seglen: " << 10000.0f << endl;
00998                 deb << "-------------" << endl;
00999                 deb.close();
01000                 
01001                 col = objects.Collide(origin, dir, colpt, closest, normal, 10000.0f);
01002                 deb.open("debug.log", ofstream::out | ofstream::app);
01003                 deb << "col: " << col << endl;
01004                 deb << "origin: "; origin.DebugPrint(deb);
01005                 deb << "dir: "; dir.DebugPrint(deb);
01006                 deb << "colpt: "; colpt.DebugPrint(deb);
01007                 deb << "closest: " << closest << endl;
01008                 deb << "normal: "; normal.DebugPrint(deb);
01009                 deb << "seglen: " << 10000.0f << endl;
01010                 deb << "-------------" << endl;
01011                 deb.close();
01012         }
01013         #endif
01014         
01015         //Quit(0);
01016         
01017         LoadingScreen("Loading...\nLoading sound");
01018         //sound.Deinit();
01019         //sound.Init();
01020         sound.Reload();
01021 
01022         LoadingScreen("Loading...\nWorld");
01023         world.Init(&track);
01024 
01025         LoadingScreen("Loading...\nCar");
01026         SelectCar(state.GetCarName(0), true);
01027         //world.GetPlayerCar()->SetPaint(car_paint); <-done in selectcar instead.
01028 
01029         //LoadingScreen("Loading...\nLoading Trees");
01030         //trees.ReadFromFile(settings.GetFullDataPath("tracks/" + state.GetTrackName() + "/treemap.png"), settings.GetFullDataPath("tracks/" + state.GetTrackName() + "/foliagemap.png"));
01031         /*trees.DeleteAll();
01032         int numtrees = 200;
01033         for (i = 0; i < numtrees/2; i++)
01034         {
01035                 VERTEX tp;
01036                 tp.x = ((float) rand()/RAND_MAX)*(param[0]/2.0)+param[0]/4.0;
01037                 tp.z = ((float) rand()/RAND_MAX)*(param[2]/2.0)+param[2]/4.0;
01038                 tp.x += param[3];
01039                 tp.z += param[4];
01040                 tp.y = terrain.GetHeight(tp.x, tp.z);
01041                 trees.Add(tp, 40.0, 0, 5);
01042         }
01043 
01044         for (i = 0; i < numtrees/2; i++)
01045         {
01046                 VERTEX tp;
01047                 tp.x = ((float) rand()/RAND_MAX)*(param[0]/2.0)+param[0]/4.0;
01048                 tp.z = ((float) rand()/RAND_MAX)*(param[2]/2.0)+param[2]/4.0;
01049                 tp.x += param[3];
01050                 tp.z += param[4];
01051                 tp.y = terrain.GetHeight(tp.x, tp.z);
01052                 trees.Add(tp, 60.0, 1, 5);
01053         }*/
01054 
01055         timer.Reset();
01056         particle.Clear();
01057 
01058         LoadingScreen("Loading...\nDone");
01059 
01060         mq1.AddMessage("Simulation start");
01061 
01062         #ifdef PATCH_DEBUG
01063         {
01064                 VERTEX v[4];
01065                 /*v[0].Set(-2045.29,604.818,-566.924);
01066                 v[1].Set(-2040.08,605.083,-572.898);
01067                 v[2].Set(-2026.6,602.961,-550.628);
01068                 v[3].Set(-2020.85,602.961,-557.449);*/
01069                 v[0].Set(-2148.81,583.537,-1395.68);
01070                 v[1].Set(-2151.04,583.525,-1396.96);
01071                 v[2].Set(-2145.45,583.378,-1401.53);
01072                 v[3].Set(-2147.67,583.341,-1402.81);
01073 
01074                 thepatch = track.GetPatch(v);
01075                 if (thepatch != NULL)
01076                 {
01077                         cout << "Got patch" << endl;
01078                 
01079                         VERTEX p1,p2;
01080                         /*p1.Set(-2032.96,603.927,-562.198);
01081                         p2.Set(-2033,603.931,-562.227);*/
01082                         p1 = (v[0] + v[1]).ScaleR(0.5);
01083                         p2 = (v[2] +