00001
00002 #include <stdio.h>
00003 #include <unistd.h>
00004
00005 #include <sstream>
00006
00007 #include <vrs/vrs.h>
00008 #include <vrs/glut/glutcanvas.h>
00009 #include <vrs/opengl/transparencytechniquegl.h>
00010
00011 #include <ode/ode.h>
00012
00013 #include "SDL.h"
00014
00015 #include <vrsode/BoxShape.h>
00016 #include <vrsode/PhysicsBody.h>
00017 #include <vrsode/PhysicsManager.h>
00018 #include <vrsode/PlaneShape.h>
00019 #include <vrsode/CylinderShape.h>
00020 #include <vrsode/TriangleData.h>
00021 #include <vrsode/TrimeshShape.h>
00022
00023 #include <random_utils/Macros.h>
00024 #include <random_utils/ThreadSafeCanvas.h>
00025
00026 #include "BuggyCar.h"
00027 #include "BuggyFunCar.h"
00028 #include "CenterScreenDisplay.h"
00029 #include "Console.h"
00030 #include "ControlPointContainer.h"
00031 #include "ControlPointGenerator.h"
00032 #include "GameContext.h"
00033 #include "ItemDistributor.h"
00034 #include "LoaderGlue.h"
00035 #include "ODETerrainLoader.h"
00036 #include "ReloadPlane.h"
00037 #include "ResourceManager.h"
00038 #include "TestCar.h"
00039 #include "ThirdPersonCameraHelper.h"
00040 #include "VRSTerrainLoader.h"
00041 #include "Version.h"
00042 #include "Presenter.h"
00043
00044 #include "MainApplication.h"
00045
00046 using namespace VRS;
00047 using namespace vrsode;
00048 using namespace random_utils;
00049
00050 #define _RR_VRSODE_RUN_MULTITHREADED_
00051 #define _RR_PRESENTATION_
00052
00053 namespace random_racer
00054 {
00055
00056 const double MainApplication::c_defaultFov = 72.0;
00057 const unsigned int MainApplication::c_canvasWidth = 800;
00058 const unsigned int MainApplication::c_canvasHeight = 600;
00059
00060 MainApplication* MainApplication::s_daMainApp = NULL;
00061
00062 MainApplication::MainApplication()
00063 {
00064 s_daMainApp = this;
00065
00066 m_oldFov = -1;
00067
00068 m_canvas = new ThreadSafeCanvas("Random Racer", c_canvasWidth,
00069 c_canvasHeight, GLCanvas::RGBDDS);
00070
00071 m_isFullscreen = false;
00072
00073
00074 m_scene = new SceneThing();
00075 m_canvas->append(m_scene);
00076
00077
00078 Console::get()->attach(m_canvas);
00079 Console::get()->hide();
00080
00081 #ifdef _RR_PRESENTATION_
00082
00083 m_presenter = new Presenter(m_canvas);
00084 #endif
00085
00086 m_centerScreen = new CenterScreenDisplay(m_canvas);
00087 m_centerScreen->showText(
00088 12000,
00089 "Welcome to Random Racer "RR_VERSION,
00090 "Press < or ^ for the console.");
00091
00092
00093
00094 m_scene->append(new DistantLight(
00095 Vector(1,2,1)));
00096
00097
00098
00099
00100
00101
00102
00103
00104 m_lookAt = new LookAt();
00105 m_perspective = new Perspective(c_defaultFov, 2.5, 333.3);
00106
00107 m_scene->append(new Camera(m_perspective, m_lookAt));
00108
00109
00110 m_scene->append(new TransparencyTechniqueGL());
00111
00112
00113 m_fog = new Fog(0.96, Color(0.6, 0.6, 0.7), Fog::Linear, 196, 224);
00114 m_scene->append(m_fog);
00115
00116
00117 SO<ImageCubeMapTextureGL> cubeTexture =
00118 ResourceManager::get()->loadCubeTexture("miramar", ".png");
00119 cubeTexture->setWrap(TextureGL::REPEAT);
00120 cubeTexture->setFilter(TextureGL::LINEAR_MIPMAP_LINEAR);
00121 m_scene->append(new BackgroundGL(cubeTexture));
00122
00123
00124 m_geometryRoot = new SceneThing(m_scene);
00125
00126
00127 m_activeCar = 0;
00128 SO<SceneThing> car = new SceneThing(m_geometryRoot);
00129
00130 #ifdef RR_OTHER_CAR
00131
00132 m_car[m_activeCar] = new BuggyCar(car);
00133 m_car[m_activeCar]->setPosition(0,5,0);
00134 #else
00135 m_car[m_activeCar] = new BuggyFunCar(car);
00136 m_car[m_activeCar]->setPosition(0,2,0);
00137 #endif
00138
00139
00140
00141 m_camHelper = new ThirdPersonCameraHelper(
00142 m_lookAt, m_car[m_activeCar]->cameraHook(), Vector(0, -15, 10));
00143
00144 camResetCommand();
00145
00146
00147
00148 m_keyCallBack = new BehaviorCallback();
00149 m_canvas->append(m_keyCallBack);
00150
00151 m_keyCallBack->setCanvasCallback(
00152 new MethodCallback<MainApplication>(this, &MainApplication::keyEvent));
00153
00154 m_keyCallBack->activate();
00155
00156 registerCommands();
00157
00158
00159 m_car[m_activeCar]->cameraHook()->setCollisionCategory(
00160 m_car[m_activeCar]->cameraHook()->collisionCategory() | 1);
00161
00162
00163 m_car[m_activeCar]->cameraHook()->setCollisionPartnerCategories(
00164 m_car[m_activeCar]->cameraHook()->collisionPartnerCategories() | 32);
00165
00166
00167
00168 SO<SceneThing> vrsTerrainThing = new SceneThing(m_geometryRoot);
00169 SO<SceneThing> odeTerrainThing = new SceneThing(m_geometryRoot);
00170
00171
00172 m_generator = new ControlPointGenerator(32);
00173 m_container = new ControlPointContainer(
00174 32, 1024, m_generator->getCallback(), -35.0, 20.0);
00175
00176
00177 m_vrsLoader = new VRSTerrainLoader(
00178
00179 vrsTerrainThing, m_container, 128.0, 512.0);
00180
00181 SO<SceneThing> itemRoot = new SceneThing(m_geometryRoot);
00182 itemRoot->append(cubeTexture);
00183 itemRoot->append(new TexGenGL(TexGenGL::ReflectionMap));
00184
00185 m_itemDistributor = new ItemDistributor(
00186 itemRoot, m_vrsLoader, m_centerScreen);
00187
00188
00189 m_vrsGlue = new LoaderGlue(
00190
00191 m_car[m_activeCar]->cameraHook(), m_vrsLoader, 128.0, 128.0 - 32.0,
00192 VRS::Vector(0,0,0), m_itemDistributor);
00193
00194
00195 m_odeLoader = new ODETerrainLoader(
00196 odeTerrainThing, m_vrsLoader, 30.0, 64.0);
00197
00198 m_odeGlue = new LoaderGlue(
00199 m_car[m_activeCar]->cameraHook(), m_odeLoader, 30.0, 20.0);
00200
00201
00202
00203 for(unsigned int i = 0; i < 8; i++)
00204 if(i < 4)
00205 m_planes[i] = new ReloadPlane(m_geometryRoot,
00206 m_vrsGlue->getCallback(), i);
00207 else
00208 m_planes[i] = new ReloadPlane(m_geometryRoot,
00209 m_odeGlue->getCallback(), i, false);
00210
00211 m_vrsGlue->registerPlanes(m_planes);
00212 m_odeGlue->registerPlanes(m_planes+4);
00213 }
00214
00215 MainApplication::~MainApplication()
00216 {
00217 }
00218
00219 void
00220 MainApplication::keyEvent()
00221 {
00222 KeyEvent* event = VRS_Cast(KeyEvent, m_keyCallBack->currentCanvasEvent());
00223
00224 if(event != NULL && event->pressed())
00225 switch(event->keyCode())
00226 {
00227 case Key::Up: m_car[m_activeCar]->accelerate(1.0); break;
00228 case Key::Down: m_car[m_activeCar]->accelerate(-0.2); break;
00229 case Key::Left: m_car[m_activeCar]->steer(-1.0); break;
00230 case Key::Right: m_car[m_activeCar]->steer(1.0); break;
00231 case Key::End:
00232 if(m_oldFov == -1)
00233 {
00234 m_oldFov = m_perspective->getFovy();
00235 m_targetFov = m_oldFov + 45;
00236 m_lastFov = m_oldFov;
00237 }
00238 else if(m_lastFov != m_targetFov)
00239 {
00240 m_perspective->setFovy(
00241 random_utils::inRange(0.001,
00242 m_lastFov + ((m_targetFov - m_lastFov) * 0.09),
00243 179.999));
00244
00245 m_lastFov = m_lastFov + ((m_targetFov - m_lastFov) * 0.09);
00246 }
00247 m_car[m_activeCar]->nitro(1.0);
00248 break;
00249 case ' ': m_car[m_activeCar]->handBreak(1.0); break;
00250 }
00251 if(event != NULL && event->released())
00252 switch(event->keyCode())
00253 {
00254 case Key::Up: m_car[m_activeCar]->accelerate(0.0); break;
00255 case Key::Down: m_car[m_activeCar]->accelerate(0.0); break;
00256 case Key::Left: m_car[m_activeCar]->steer(0.0); break;
00257 case Key::Right: m_car[m_activeCar]->steer(0.0); break;
00258 case Key::End:
00259 if(m_oldFov > -1)
00260 m_perspective->setFovy(
00261 random_utils::inRange(0.001, m_oldFov, 179.999));
00262 m_oldFov = -1;
00263 break;
00264 case ' ': m_car[m_activeCar]->handBreak(0.0); break;
00265 }
00266
00267 m_canvas->postForRedisplay();
00268 }
00269
00270 void
00271 MainApplication::updatePhysics(int p_args)
00272 {
00273 #ifndef _RR_VRSODE_RUN_MULTITHREADED_
00274 PhysicsManager::get()->update(0.02);
00275 glutTimerFunc(50, MainApplication::updatePhysics, p_args);
00276 #endif
00277 }
00278
00279 void
00280 MainApplication::everyFrame(int p_args)
00281 {
00282 MainApplication* self = (MainApplication*)p_args;
00283
00284
00285
00286
00287
00288
00289 self->m_vrsGlue->checkForCollisions();
00290
00291 self->m_itemDistributor->checkForCollisionsAndRotate(1.4);
00292
00293 glutTimerFunc(10, MainApplication::everyFrame, p_args);
00294 }
00295
00296 void
00297 MainApplication::registerCommands()
00298 {
00299 Console::get()->registerCommand("car_reset",
00300 new MethodCallback<MainApplication>(
00301 this, &MainApplication::carResetCommand));
00302
00303 Console::get()->registerCommand("car_position",
00304 new MethodCallback<MainApplication>(
00305 this, &MainApplication::carPositionCommand));
00306
00307 Console::get()->registerCommand("cam_fov",
00308 new MethodCallback1<MainApplication, const std::string&>(
00309 this, &MainApplication::fovCommand));
00310
00311 Console::get()->registerCommand("cam_static",
00312 new MethodCallback1<MainApplication, const std::string&>(
00313 this, &MainApplication::camStaticCommand));
00314
00315 Console::get()->registerCommand("cam_up",
00316 new MethodCallback1<MainApplication, const std::string&>(
00317 this, &MainApplication::camUpCommand));
00318
00319 Console::get()->registerCommand("cam_correct",
00320 new MethodCallback1<MainApplication, const std::string&>(
00321 this, &MainApplication::camCorrectCommand));
00322
00323 Console::get()->registerCommand("cam_back",
00324 new MethodCallback1<MainApplication, const std::string&>(
00325 this, &MainApplication::camBackCommand));
00326
00327 Console::get()->registerCommand("cam_reset",
00328 new MethodCallback<MainApplication>(
00329 this, &MainApplication::camResetCommand));
00330
00331 Console::get()->registerCommand("cam_fog",
00332 new MethodCallback1<MainApplication, const std::string&>(
00333 this, &MainApplication::camFogCommand));
00334
00335
00336
00337
00338
00339 Console::get()->registerCommand("collect_coins",
00340 new MethodCallback1<MainApplication, const std::string&>(
00341 this, &MainApplication::collectCoinsCommand));
00342
00343 Console::get()->registerCommand("quit",
00344 new MethodCallback<MainApplication>(
00345 this, &MainApplication::quitCommand));
00346
00347 Console::get()->registerCommand("version",
00348 new MethodCallback<MainApplication>(
00349 this, &MainApplication::versionCommand));
00350
00351 Console::get()->registerCommand("fullscreen",
00352 new MethodCallback<MainApplication>(
00353 this, &MainApplication::fullscreenCommand));
00354
00355 Console::get()->registerCommand("autoexec",
00356 new MethodCallback<MainApplication>(
00357 this, &MainApplication::autoexecCommand));
00358
00359 Console::get()->registerCommand("phy_debug",
00360 new MethodCallback1<MainApplication, const std::string&>(
00361 this, &MainApplication::phyDebugCommand));
00362
00363 Console::get()->registerCommand("phy_performance_adjust",
00364 new MethodCallback1<MainApplication, const std::string&>(
00365 this, &MainApplication::phyPerformanceAdjustCommand));
00366
00367 Console::get()->registerCommand("phy_step_time",
00368 new MethodCallback1<MainApplication, const std::string&>(
00369 this, &MainApplication::phyStepTimeCommand));
00370
00371 Console::get()->registerCommand("phy_step_size",
00372 new MethodCallback1<MainApplication, const std::string&>(
00373 this, &MainApplication::phyStepSizeCommand));
00374
00375 Console::get()->registerCommand("ter_debug_planes",
00376 new MethodCallback1<MainApplication, const std::string&>(
00377 this, &MainApplication::terDebugPlanesCommand));
00378
00379 Console::get()->registerCommand("ter_debug_phy",
00380 new MethodCallback1<MainApplication, const std::string&>(
00381 this, &MainApplication::terDebugPhyCommand));
00382
00383 Console::get()->registerCommand("pre_start",
00384 new MethodCallback1<MainApplication, const std::string&>(
00385 this, &MainApplication::preStartCommand));
00386 }
00387
00388 void
00389 MainApplication::fovCommand(const std::string& p_newFov)
00390 {
00391 if(!p_newFov.empty())
00392 {
00393 double fov;
00394 std::istringstream s(p_newFov);
00395 s >> fov;
00396
00397 m_perspective->setFovy(random_utils::inRange(0.001, fov, 179.999));
00398 }
00399 else
00400 {
00401 std::ostringstream s;
00402 s << m_perspective->getFovy();
00403
00404 Console::get()->addLine(s.str());
00405 }
00406 }
00407
00408 void
00409 MainApplication::quitCommand()
00410 {
00411
00412 exit(0);
00413 }
00414
00415 void
00416 MainApplication::autoexecCommand()
00417 {
00418 Console::get()->autoexec();
00419 }
00420
00421 void
00422 MainApplication::carResetCommand()
00423 {
00424 if(!(m_car[m_activeCar]->chassis()))
00425 std::cerr << "ERROR: chassis is NULL" << std::endl;
00426
00427 Vector pos = m_car[m_activeCar]->chassis()->position();
00428 pos[1] += 2;
00429
00430 m_car[m_activeCar]->chassis()->setRotation(Vector(0,1,0), 1);
00431 m_car[m_activeCar]->setPosition(pos);
00432 }
00433
00434 void
00435 MainApplication::carPositionCommand()
00436 {
00437 std::ostringstream s;
00438 s << m_car[m_activeCar]->cameraHook()->position();
00439
00440 Console::get()->addLine(s.str());
00441 }
00442
00443 void
00444 MainApplication::camUpCommand(const std::string& p_newUp)
00445 {
00446 if(!p_newUp.empty())
00447 {
00448 double up;
00449 std::istringstream s(p_newUp);
00450 s >> up;
00451
00452 m_camHelper->setDistanceY(up);
00453 }
00454 else
00455 {
00456 std::ostringstream s;
00457 s << m_camHelper->distanceY();
00458
00459 Console::get()->addLine(s.str());
00460 }
00461 }
00462
00463 void
00464 MainApplication::camBackCommand(const std::string& p_newBack)
00465 {
00466 if(!p_newBack.empty())
00467 {
00468 double back;
00469 std::istringstream s(p_newBack);
00470 s >> back;
00471
00472 if(back == 0.0)
00473 back = 0.05;
00474
00475 m_camHelper->setDistanceX(back);
00476 }
00477 else
00478 {
00479 std::ostringstream s;
00480 s << m_camHelper->distanceX();
00481
00482 Console::get()->addLine(s.str());
00483 }
00484 }
00485
00486 void
00487 MainApplication::camResetCommand()
00488 {
00489 m_perspective->setFovy(c_defaultFov);
00490 m_camHelper->setDistanceX(12.0);
00491 m_camHelper->setDistanceY(3.5);
00492 m_camHelper->setCorrectY(3.0);
00493 m_camHelper->setStaticY(false);
00494 }
00495
00496 void
00497 MainApplication::camStaticCommand(const std::string& p_newStatic)
00498 {
00499 if(p_newStatic.empty())
00500 {
00501 if(m_camHelper->isStaticY())
00502 Console::get()->addLine("true");
00503 else
00504 Console::get()->addLine("false");
00505 }
00506 else if(p_newStatic == "true" || p_newStatic == "1")
00507 m_camHelper->setStaticY(true);
00508
00509 else
00510 m_camHelper->setStaticY(false);
00511 }
00512
00513 void
00514 MainApplication::camCorrectCommand(const std::string& p_newDouble)
00515 {
00516 if(p_newDouble.empty())
00517 {
00518 std::ostringstream s;
00519 s << m_camHelper->correctY();
00520
00521 Console::get()->addLine(s.str());
00522 }
00523 else
00524 {
00525 double correct;
00526 std::istringstream s(p_newDouble);
00527 s >> correct;
00528
00529 m_camHelper->setCorrectY(correct);
00530 }
00531 }
00532
00533 void
00534 MainApplication::camFogCommand(const std::string& p_fogToggle)
00535 {
00536 if(p_fogToggle.empty())
00537 {
00538 m_scene->contains(m_fog) ?
00539 m_scene->remove(m_fog) :
00540 m_scene->prepend(m_fog);
00541 }
00542 else if(p_fogToggle == "true" || p_fogToggle == "1")
00543 {
00544 if(!m_scene->contains(m_fog))
00545 m_scene->prepend(m_fog);
00546 }
00547 else
00548 {
00549 if(m_scene->contains(m_fog))
00550 m_scene->remove(m_fog);
00551 }
00552 }
00553
00554
00555 void
00556 MainApplication::phyDebugCommand(const std::string& p_newDebug)
00557 {
00558 if(p_newDebug.empty() || p_newDebug == "true" || p_newDebug == "1")
00559 PhysicsManager::get()->setDebugNodesGlobal(true);
00560 else
00561 PhysicsManager::get()->setDebugNodesGlobal(false);
00562 }
00563
00564 void
00565 MainApplication::phyPerformanceAdjustCommand(const std::string& p_newPerf)
00566 {
00567 if(p_newPerf.empty())
00568 PhysicsManager::get()->performanceAutoAdjust() ?
00569 Console::get()->addLine("true") :
00570 Console::get()->addLine("false");
00571
00572 else if(p_newPerf == "true" || p_newPerf == "1")
00573 PhysicsManager::get()->setPerformanceAutoAdjust(true);
00574
00575 else
00576 PhysicsManager::get()->setPerformanceAutoAdjust(false);
00577 }
00578
00579 void
00580 MainApplication::phyStepTimeCommand(const std::string& p_newTime)
00581 {
00582 if(!p_newTime.empty())
00583 {
00584 double time;
00585 std::istringstream s(p_newTime);
00586 s >> time;
00587
00588 PhysicsManager::get()->setStepTime(time);
00589 }
00590 else
00591 {
00592 std::ostringstream s;
00593 s << PhysicsManager::get()->stepTime();
00594
00595 Console::get()->addLine(s.str());
00596 }
00597 }
00598
00599 void
00600 MainApplication::phyStepSizeCommand(const std::string& p_newSize)
00601 {
00602 if(!p_newSize.empty())
00603 {
00604 double size;
00605 std::istringstream s(p_newSize);
00606 s >> size;
00607
00608 PhysicsManager::get()->setStepSize(size);
00609 }
00610 else
00611 {
00612 std::ostringstream s;
00613 s << PhysicsManager::get()->stepSize();
00614
00615 Console::get()->addLine(s.str());
00616 }
00617 }
00618
00619 void
00620 MainApplication::versionCommand()
00621 {
00622 std::string versionString;
00623 versionString += "Random Racer "RR_VERSION;
00624 versionString += " - using ";
00625 versionString += PhysicsManager::get()->odeVersionString();
00626 versionString += ", ";
00627
00628 std::stringstream sdlVersionString;
00629 sdlVersionString << "libSDL "
00630 << SDL_MAJOR_VERSION << "."
00631 << SDL_MINOR_VERSION << "."
00632 << SDL_PATCHLEVEL;
00633
00634 versionString += sdlVersionString.str();
00635
00636 versionString += ", ";
00637
00638 std::stringstream vrsVersionString;
00639 vrsVersionString << "VRS3D "
00640 << VRS_MAJOR_VERSION << "."
00641 << VRS_MINOR_VERSION << "."
00642 << VRS_PATCH_VERSION;
00643
00644 versionString += vrsVersionString.str();
00645
00646 Console::get()->addLine(versionString);
00647 }
00648
00649 void
00650 MainApplication::fullscreenCommand()
00651 {
00652 if(m_isFullscreen)
00653 {
00654 m_canvas->setSize(c_canvasWidth, c_canvasHeight);
00655 m_isFullscreen = false;
00656 }
00657 else
00658 {
00659 glutFullScreen();
00660 m_isFullscreen = true;
00661 }
00662 }
00663
00664 void
00665 MainApplication::terDebugPlanesCommand(const std::string& p_which)
00666 {
00667 if(p_which == "ode")
00668 for(unsigned int i = 4; i < 8; i++)
00669 m_planes[i]->setDebug(true);
00670
00671 else if(p_which == "vrs")
00672 for(unsigned int i = 0; i < 4; i++)
00673 m_planes[i]->setDebug(true);
00674
00675 else if(p_which == "off" || p_which == "none" ||
00676 p_which == "0" || p_which == "false")
00677 for(unsigned int i = 0; i < 8; i++)
00678 m_planes[i]->setDebug(false);
00679
00680 else
00681 Console::get()->addLine("try ode, vrs oder off");
00682 }
00683
00684 void
00685 MainApplication::camDelayCommand(const std::string& p_newIntDelay)
00686 {
00687 if(p_newIntDelay.empty())
00688 {
00689 std::ostringstream s;
00690 s << m_camHelper->delay();
00691
00692 Console::get()->addLine(s.str());
00693 }
00694 else
00695 {
00696 unsigned int delay;
00697 std::istringstream s(p_newIntDelay);
00698 s >> delay;
00699
00700 m_camHelper->setDelay(delay);
00701 }
00702 }
00703
00704 void
00705 MainApplication::terDebugPhyCommand(const std::string& p_newBool)
00706 {
00707 if(p_newBool.empty() || p_newBool == "true" || p_newBool == "1")
00708 m_odeLoader->setDebug(true);
00709 else
00710 m_odeLoader->setDebug(false);
00711 }
00712
00713 void
00714 MainApplication::collectCoinsCommand(const std::string& p_newBool)
00715 {
00716 if(p_newBool.empty() || p_newBool == "true" || p_newBool == "1")
00717 m_itemDistributor->setEnabled(true);
00718 else
00719 m_itemDistributor->setEnabled(false);
00720 }
00721
00722 void
00723 MainApplication::preStartCommand(const std::string& p_temp)
00724 {
00725 m_presenter->startPresentation();
00726 }
00727
00728 void
00729 MainApplication::cleanUpAtExit()
00730 {
00731 PhysicsManager::terminate();
00732
00733 s_daMainApp->m_vrsLoader->terminate();
00734
00735 SDL_Quit();
00736 }
00737
00738 void
00739 MainApplication::signalHandler(int sig)
00740 {
00741 exit(0);
00742 }
00743
00744 }
00745
00746
00747 using namespace random_racer;
00748
00749
00750 #ifdef __APPLE__
00751 #undef main
00752 #endif
00753
00754 int
00755 main(int p_argc, char** p_argv)
00756 {
00757
00758
00759 assert(sizeof(int) == sizeof(MainApplication*));
00760
00761
00762 SharedObj::enableThreadSafeSOs(true);
00763
00764
00765 glutInit(&p_argc, p_argv);
00766 SDL_Init(SDL_INIT_TIMER);
00767
00768 glutSetKeyRepeat(GLUT_KEY_REPEAT_ON);
00769
00770 ResourceManager::get()->setArgv((p_argc >= 1) ? p_argv[0] : "");
00771
00772 SO<MainApplication> app = new MainApplication;
00773
00774 srand(SDL_GetTicks());
00775 srandom(SDL_GetTicks()*23);
00776
00777
00778
00779 atexit(MainApplication::cleanUpAtExit);
00780
00781 signal(SIGHUP, MainApplication::signalHandler);
00782 signal(SIGINT, MainApplication::signalHandler);
00783 signal(SIGKILL, MainApplication::signalHandler);
00784
00785
00786 Console::get()->autoexec();
00787
00788 #ifdef _RR_VRSODE_RUN_MULTITHREADED_
00789 PhysicsManager::get()->startThread();
00790 #endif
00791
00792 glutTimerFunc(0, MainApplication::updatePhysics,
00793 (int)((MainApplication*)app));
00794
00795 glutTimerFunc(0, MainApplication::everyFrame,
00796 (int)((MainApplication*)app));
00797
00798 glutMainLoop();
00799
00800
00801 return 0;
00802 }