00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "rFont.h"
00029
00030 #include "defs.h"
00031
00032 #include <string>
00033 #include "rTexture.h"
00034 #include "rScreen.h"
00035 #include "rSysdep.h"
00036 #include "rConsole.h"
00037 #include "rViewport.h"
00038 #include "tConfiguration.h"
00039 #include "tRecorder.h"
00040 #include "tSysTime.h"
00041
00042 #ifndef DEDICATED
00043
00044 #include "rGL.h"
00045 #include "rSDL.h"
00046
00047 #ifdef POWERPAK_DEB
00048 #include <PowerPak/powerdraw>
00049 #endif
00050 #endif
00051
00052 #ifndef SDL_OPENGL
00053 #ifndef DIRTY
00054 #define DIRTY
00055 #endif
00056 #endif
00057
00058 #ifdef DEBUG
00059
00060 #define FORCE_WINDOW
00061
00062 #endif
00063
00064 tCONFIG_ENUM( rResolution );
00065 tCONFIG_ENUM( rColorDepth );
00066 tCONFIG_ENUM( rVSync );
00067
00068 SDL_Surface *sr_screen=NULL;
00069
00070 #ifndef DEDICATED
00071 static int default_texturemode = GL_LINEAR_MIPMAP_LINEAR;
00072 #endif
00073
00074 rDisplayListUsage sr_useDisplayLists=rDisplayList_Off;
00075
00076 static int width[ArmageTron_Custom+2] = {0, 320, 320, 400, 512, 640, 800, 1024 , 1280, 1280, 1280, 1600, 1680, 2048,800,320};
00077 static int height[ArmageTron_Custom+2] = {0, 200, 240, 300, 384, 480, 600, 768 , 800, 854, 1024, 1200, 1050, 1572,600,200};
00078 static REAL aspect[ArmageTron_Custom+2]= {1, 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1, 1, 1 , 1, 1, 1,1, 1};
00079
00080 int sr_screenWidth,sr_screenHeight;
00081
00082 static tSettingItem<int> at_ch("CUSTOM_SCREEN_HEIGHT" , height[ArmageTron_Custom]);
00083 static tSettingItem<int> at_cw("CUSTOM_SCREEN_WIDTH" , width [ArmageTron_Custom]);
00084 static tSettingItem<REAL> at_ca("CUSTOM_SCREEN_ASPECT" , aspect[ArmageTron_Custom]);
00085
00086 #define MAXEMERGENCY 6
00087
00088 rScreenSettings lastSuccess(ArmageTron_640_480, false);
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 #ifndef DEBUG
00103 static rScreenSettings em6(ArmageTron_320_240, false, ArmageTron_ColorDepth_16, true, false);
00104 static rScreenSettings em5(ArmageTron_320_240, false, ArmageTron_ColorDepth_Desktop, true, false);
00105 static rScreenSettings em4(ArmageTron_640_480, false,ArmageTron_ColorDepth_16);
00106 static rScreenSettings em3(ArmageTron_640_480, true, ArmageTron_ColorDepth_16);
00107 static rScreenSettings em2(ArmageTron_640_480, true, ArmageTron_ColorDepth_16, false);
00108 static rScreenSettings em1(ArmageTron_640_480);
00109
00110 static rScreenSettings *emergency[MAXEMERGENCY+2]={ &lastSuccess, &lastSuccess, &em1, &em2, &em3 , &em4, &em5, &em6};
00111 #endif
00112
00113 #ifdef DEBUG
00114 rScreenSettings currentScreensetting(ArmageTron_640_480);
00115 #else
00116 rScreenSettings currentScreensetting(sr_DesktopScreensizeSupported() ? ArmageTron_Desktop : ArmageTron_800_600, true);
00117 #endif
00118
00119 bool sr_DesktopScreensizeSupported()
00120 {
00121 #ifndef DEDICATED
00122 SDL_version const & sdlVersion = *SDL_Linked_Version();
00123
00124 return
00125 sdlVersion.major > 1 || sdlVersion.major == 1 &&
00126 ( sdlVersion.minor > 2 || sdlVersion.minor == 2 &&
00127 ( sdlVersion.patch >= 10 ) );
00128 #else
00129 return false;
00130 #endif
00131 }
00132
00133 static int failed_attempts = 0;
00134
00135 static tConfItem<rResolution> screenres("ARMAGETRON_SCREENMODE",currentScreensetting.res.res);
00136 static tConfItem<rResolution> screenresLast("ARMAGETRON_LAST_SCREENMODE",lastSuccess.res.res);
00137
00138 static tConfItem<rResolution> winsize("ARMAGETRON_WINDOWSIZE",currentScreensetting.windowSize.res);
00139 static tConfItem<rResolution> winsizeLast("ARMAGETRON_LAST_WINDOWSIZE",lastSuccess.windowSize.res);
00140
00141 static tConfItem<rVSync> vSync("ARMAGETRON_VSYNC",currentScreensetting.vSync);
00142 static tConfItem<rVSync> vSyncLast("ARMAGETRON_VSYNC_LAST",lastSuccess.vSync);
00143
00144 static tConfItem<int> screenres_w("ARMAGETRON_SCREENMODE_W",currentScreensetting.res.width);
00145 static tConfItem<int> screenresLast_w("ARMAGETRON_LAST_SCREENMODE_W", lastSuccess.res.width);
00146
00147 static tConfItem<int> winsize_w("ARMAGETRON_WINDOWSIZE_W",currentScreensetting.windowSize.width);
00148 static tConfItem<int> winsizeLast_w("ARMAGETRON_LAST_WINDOWSIZE_W",lastSuccess.windowSize.width);
00149
00150 static tConfItem<int> screenres_h("ARMAGETRON_SCREENMODE_H",currentScreensetting.res.height);
00151 static tConfItem<int> screenresLast_h("ARMAGETRON_LAST_SCREENMODE_H", lastSuccess.res.height);
00152
00153
00154
00155 static tConfItem<int> winsize_h("ARMAGETRON_WINDOWSIZE_H",currentScreensetting.windowSize.height);
00156 static tConfItem<int> winsizeLast_h("ARMAGETRON_LAST_WINDOWSIZE_H",lastSuccess.windowSize.height);
00157
00158 static tConfItem<bool> fs_ci("FULLSCREEN",currentScreensetting.fullscreen);
00159 static tConfItem<bool> fs_lci("LAST_FULLSCREEN",currentScreensetting.fullscreen);
00160
00161 static tConfItem<rColorDepth> tc("COLORDEPTH",currentScreensetting.colorDepth);
00162 static tConfItem<rColorDepth> ltc("LAST_COLORDEPTH",lastSuccess.colorDepth);
00163 static tConfItem<rColorDepth> tzd("ZDEPTH",currentScreensetting.zDepth);
00164 static tConfItem<rColorDepth> ltzd("LAST_ZDEPTH",lastSuccess.zDepth);
00165
00166 #ifdef DIRTY
00167 #ifdef SDL_OPENGL
00168 static tConfItem<bool> sdl("USE_SDL",currentScreensetting.useSDL);
00169 static tConfItem<bool> lsdl("LAST_USE_SDL",lastSuccess.useSDL);
00170 #endif
00171 #endif
00172
00173 static tConfItem<bool> check_errors("CHECK_ERRORS",currentScreensetting.checkErrors);
00174 static tConfItem<bool> check_errorsl("LAST_CHECK_ERRORS",lastSuccess.checkErrors);
00175
00176 static tConfItem<int> fa("FAILED_ATTEMPTS", failed_attempts);
00177
00178
00179
00180 static tCallback *rPerFrameTask_anchor;
00181
00182 #ifdef HAVE_LIBRUBY
00183 static tCallbackRuby * rPerFrameTaskRuby_anchor;
00184 #endif
00185
00186 bool sr_True(){return true;}
00187
00188 rPerFrameTask::rPerFrameTask(AA_VOIDFUNC *f):tCallback(rPerFrameTask_anchor, f){}
00189 void rPerFrameTask::DoPerFrameTasks(){
00190
00191 rNoAutoDisplayAtNewlineCallback noAutoDisplay( sr_True );
00192 Exec(rPerFrameTask_anchor);
00193 }
00194
00195 #ifdef HAVE_LIBRUBY
00196 rPerFrameTaskRuby::rPerFrameTaskRuby()
00197 :tCallbackRuby(rPerFrameTaskRuby_anchor)
00198 {
00199 }
00200
00201 void rPerFrameTaskRuby::DoPerFrameTasks(){
00202 rNoAutoDisplayAtNewlineCallback noAutoDisplay( sr_True );
00203 Exec(rPerFrameTaskRuby_anchor);
00204 }
00205 #endif
00206
00207
00208
00209
00210
00211 static tCallbackString *RenderId_anchor;
00212
00213 rRenderIdCallback::rRenderIdCallback(STRINGRETFUNC *f)
00214 :tCallbackString(RenderId_anchor, f){}
00215 tString rRenderIdCallback::RenderId(){return Exec(RenderId_anchor);}
00216
00217
00218
00219
00220
00221
00222
00223
00228
00229
00230 rScreenSize::rScreenSize( int w, int h )
00231 :res( ArmageTron_Invalid ), width(w), height(h)
00232 {
00233 }
00234
00235
00236
00237
00238
00239
00243
00244
00245 rScreenSize::rScreenSize( rResolution r )
00246 :res( r ), width(0), height(0)
00247 {
00248 UpdateSize();
00249 }
00250
00251
00252
00253
00254
00255
00258
00259
00260 void rScreenSize::UpdateSize( void )
00261 {
00262 if ( res != ArmageTron_Invalid )
00263 {
00264 width = ::width[res];
00265 height = ::height[res];
00266
00267 }
00268 }
00269
00270
00271
00272
00273
00274
00279
00280
00281 bool rScreenSize::operator ==( rScreenSize const & other ) const
00282 {
00283 return Compare( other ) == 0;
00284 }
00285
00286
00287
00288
00289
00290
00295
00296
00297 bool rScreenSize::operator !=( rScreenSize const & other ) const
00298 {
00299 return Compare( other ) != 0;
00300 }
00301
00302
00303
00304
00305
00306
00311
00312
00313 int rScreenSize::Compare( rScreenSize const & other ) const
00314 {
00315
00316 if ( width == 0 && other.width != 0 )
00317 return 1;
00318 if ( other.width == 0 && width != 0 )
00319 return -1;
00320
00321 if ( width < other.width )
00322 return -1;
00323 else if ( width > other.width )
00324 return 1;
00325
00326 if ( height < other.height )
00327 return -1;
00328 else if ( height > other.height )
00329 return 1;
00330
00331
00332
00333
00334
00335
00336
00337
00338 return 0;
00339 }
00340
00341
00342
00343
00344
00345
00346
00354
00355
00356 rScreenSettings::rScreenSettings( rResolution r, bool fs, rColorDepth cd, bool sdl, bool ce )
00357 :res(r), windowSize(r), fullscreen(fs), colorDepth(cd), zDepth( ArmageTron_ColorDepth_Desktop ), useSDL(sdl), checkErrors(true), vSync( ArmageTron_VSync_Default ), aspect (1)
00358 {
00359
00360 if ( r == ArmageTron_Desktop )
00361 {
00362 windowSize = rScreenSize( ArmageTron_640_480 );
00363 }
00364 }
00365
00366 void sr_ReinitDisplay(){
00367 sr_ExitDisplay();
00368 if (!sr_InitDisplay()){
00369 tERR_ERROR("Oops. Failed to reinit video hardware. "
00370 "Resetting to defaults..\n");
00371 exit(-1);
00372 }
00373
00374 }
00375
00376
00377
00378
00379
00380
00381
00382
00383 tString gl_vendor;
00384 tString gl_renderer;
00385 tString gl_version;
00386 tString gl_extensions;
00387
00388 bool software_renderer=false;
00389 bool last_software_renderer=false;
00390
00391 static tConfItem<bool> lsr("SOFTWARE_RENDERER",last_software_renderer);
00392
00393 tString lastError("Unknown");
00394
00395 #ifndef DEDICATED
00396 static int countBits(unsigned int count)
00397 {
00398 int ret = 0;
00399 while (count)
00400 {
00401 ret += count & 1;
00402 count >>= 1;
00403 }
00404
00405 return ret;
00406 }
00407 #endif
00408
00409 #ifndef DEDICATED
00410 #ifdef SDL_OPENGL
00411
00412 static void sr_SetSwapControl( int frames, bool after = false )
00413 {
00414 bool success = false;
00415
00416 #ifdef LINUX
00417
00418
00419
00420 char hack[2];
00421 hack[0] = '0' + frames;
00422 hack[1] = 0;
00423 setenv( "__GL_SYNC_TO_VBLANK", hack, 1 );
00424 #endif
00425
00426 #ifdef WIN32
00427
00428 typedef BOOL (APIENTRY *PFNWGLSWAPINTERVALFARPROC)( int );
00429 PFNWGLSWAPINTERVALFARPROC wglSwapIntervalEXT = 0;
00430
00431 {
00432 const char *extensions = gl_extensions;
00433
00434 if( extensions && strstr( extensions, "WGL_EXT_swap_control" ) )
00435 {
00436 wglSwapIntervalEXT = (PFNWGLSWAPINTERVALFARPROC)wglGetProcAddress( "wglSwapIntervalEXT" );
00437
00438 if( wglSwapIntervalEXT )
00439 {
00440 success = true;
00441 if ( after )
00442 wglSwapIntervalEXT( frames );
00443 }
00444 }
00445 }
00446 #endif
00447
00448
00449 #if SDL_VERSION_ATLEAST(1, 2, 10)
00450 if ( !success )
00451 SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, frames );
00452 #endif
00453 }
00454
00455 static void sr_SetSwapControlAuto( bool after = false )
00456 {
00457
00458 if ( tRecorder::IsRecording() )
00459 {
00460
00461 sr_SetSwapControl( 1 );
00462 }
00463 else
00464 {
00465 switch (currentScreensetting.vSync)
00466 {
00467 case ArmageTron_VSync_On:
00468 sr_SetSwapControl( 1, after );
00469 break;
00470 case ArmageTron_VSync_Off:
00471 case ArmageTron_VSync_MotionBlur:
00472 sr_SetSwapControl( 0, after );
00473 break;
00474 case ArmageTron_VSync_Default:
00475 break;
00476 }
00477 }
00478 }
00479
00480 static void sr_SetGLAttributes( int rDepth, int gDepth, int bDepth, int zDepth )
00481 {
00482
00483 SDL_GL_SetAttribute( SDL_GL_RED_SIZE, rDepth );
00484 SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, gDepth );
00485 SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, bDepth );
00486 SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, zDepth );
00487 SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
00488
00489 sr_SetSwapControlAuto();
00490 }
00491
00492
00493 static void sr_CompleteGLAttributes()
00494 {
00495 sr_SetSwapControlAuto( true );
00496 }
00497 #endif // SDL_OPENGL
00498 #endif // DEDICATED
00499
00500 static bool lowlevel_sr_InitDisplay(){
00501 #ifndef DEDICATED
00502 rScreenSize & res = currentScreensetting.fullscreen ? currentScreensetting.res : currentScreensetting.windowSize;
00503
00504
00505 if ( res.res != ArmageTron_Invalid )
00506 currentScreensetting.aspect = aspect[res.res];
00507
00508 #ifndef DIRTY
00509 currentScreensetting.useSDL = true;
00510 #endif
00511 res.UpdateSize();
00512 sr_screenWidth = res.width;
00513 sr_screenHeight= res.height;
00514
00515 if (!sr_screen)
00516 {
00517 int singleCD_R = 5;
00518 int singleCD_G = 5;
00519 int singleCD_B = 5;
00520 int fullCD = 16;
00521 int zDepth = 16;
00522
00523 switch (currentScreensetting.colorDepth)
00524 {
00525 case ArmageTron_ColorDepth_16:
00526
00527 break;
00528 case ArmageTron_ColorDepth_Desktop:
00529 {
00530 const SDL_VideoInfo* videoInfo = SDL_GetVideoInfo( );
00531 const SDL_PixelFormat* pixelFormat = videoInfo->vfmt;
00532 fullCD = pixelFormat->BitsPerPixel;
00533 singleCD_R = countBits(pixelFormat->Rmask);
00534 singleCD_G = countBits(pixelFormat->Gmask);
00535 singleCD_B = countBits(pixelFormat->Bmask);
00536 }
00537 break;
00538 case ArmageTron_ColorDepth_32:
00539 singleCD_R = 8;
00540 singleCD_G = 8;
00541 singleCD_B = 8;
00542 fullCD = 24;
00543 zDepth = 32;
00544 break;
00545 }
00546
00547 switch ( currentScreensetting.zDepth )
00548 {
00549 case ArmageTron_ColorDepth_16: zDepth = 16; break;
00550 case ArmageTron_ColorDepth_32: zDepth = 32; break;
00551 default: break;
00552 }
00553
00554 #ifdef SDL_OPENGL
00555 if (currentScreensetting.useSDL)
00556 {
00557 sr_SetGLAttributes( singleCD_R, singleCD_G, singleCD_B, zDepth );
00558 }
00559 #else
00560 currentScreensetting.useSDL = false;
00561 #endif
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572 int attrib;
00573
00574 #ifdef SDL_OPENGL
00575 if (currentScreensetting.useSDL)
00576 {
00577
00578 #ifndef FORCE_WINDOW
00579 if (currentScreensetting.fullscreen)
00580 attrib=SDL_OPENGL | SDL_FULLSCREEN;
00581 else
00582 #endif
00583 attrib=SDL_OPENGL;
00584 }
00585 else
00586 #endif
00587 {
00588 #ifndef FORCE_WINDOW
00589 if (currentScreensetting.fullscreen)
00590 attrib=SDL_DOUBLEBUF | SDL_SWSURFACE | SDL_FULLSCREEN;
00591 else
00592 #endif
00593 attrib=SDL_DOUBLEBUF | SDL_SWSURFACE;
00594 }
00595
00596 #ifdef FORCE_WINDOW
00597 #ifdef WIN32
00598
00599
00600 #else
00601
00602
00603 #endif
00604 #endif
00605 int CD = fullCD;
00606
00607 if (currentScreensetting.checkErrors)
00608 {
00609
00610 CD = SDL_VideoModeOK
00611 (sr_screenWidth, sr_screenHeight, fullCD,
00612 attrib);
00613
00614
00615 if (CD < fullCD){
00616
00617 int CD_fsinv = SDL_VideoModeOK
00618 (sr_screenWidth, sr_screenHeight, fullCD,
00619 attrib^SDL_FULLSCREEN);
00620
00621 if (CD_fsinv > fullCD){
00622
00623 currentScreensetting.fullscreen=!currentScreensetting.fullscreen;
00624 attrib ^= SDL_FULLSCREEN;
00625 CD = CD_fsinv;
00626 }
00627 }
00628
00629 if (CD < fullCD && currentScreensetting.colorDepth != ArmageTron_ColorDepth_16)
00630 {
00631 currentScreensetting.colorDepth = ArmageTron_ColorDepth_16;
00632
00633 #ifdef SDL_OPENGL
00634 if (currentScreensetting.useSDL)
00635 {
00636 sr_SetGLAttributes( 5, 5, 5, 16 );
00637 }
00638 #endif
00639 }
00640 }
00641
00642
00643 static int sr_desktopWidth = 0, sr_desktopHeight = 0;
00644 if ( sr_desktopWidth == 0 && !sr_screen )
00645 {
00646
00647 sr_desktopWidth = 640;
00648 sr_desktopHeight = 480;
00649
00650 if ( sr_DesktopScreensizeSupported() )
00651 {
00652 sr_screen=SDL_SetVideoMode( 0, 0, CD, attrib );
00653 if ( sr_screen )
00654 {
00655 sr_desktopWidth = sr_screen->w;
00656 sr_desktopHeight = sr_screen->h;
00657 }
00658 }
00659 }
00660
00661
00662 if ( sr_screenWidth + sr_screenHeight == 0 )
00663 {
00664 sr_screenWidth = sr_desktopWidth;
00665 sr_screenHeight = sr_desktopHeight;
00666 }
00667
00668 if ( (sr_screen=SDL_SetVideoMode
00669 (sr_screenWidth, sr_screenHeight, CD,
00670 attrib))
00671 == NULL)
00672 {
00673 if((sr_screen=SDL_SetVideoMode
00674 (sr_screenWidth, sr_screenHeight, CD,
00675 attrib^SDL_FULLSCREEN))==NULL )
00676 {
00677 lastError.Clear();
00678 lastError << "Couldn't set video mode: ";
00679 lastError << SDL_GetError();
00680 std::cerr << lastError << '\n';
00681 return false;
00682 }
00683 else
00684 {
00685 currentScreensetting.fullscreen=!currentScreensetting.fullscreen;
00686 }
00687 }
00688
00689
00690 #ifdef MACOSX
00691 if(!currentScreensetting.fullscreen)
00692 #endif
00693 {
00694 tOutput o("Armagetron Advanced");
00695 tString s;
00696 s << o;
00697 SDL_WM_SetCaption(s, s);
00698 }
00699
00700 sr_CompleteGLAttributes();
00701
00702 SDL_EnableUNICODE(1);
00703 }
00704
00705 #ifdef DIRTY
00706 if (!currentScreensetting.useSDL)
00707 if(!rSysDep::InitGL()) return false;
00708 #endif
00709
00710 #ifndef DEDICATED
00711 gl_vendor.Clear();
00712 gl_renderer.Clear();
00713 gl_version.Clear();
00714 gl_extensions.Clear();
00715 renderer_identification.Clear();
00716
00717 gl_vendor << reinterpret_cast<const char *>(glGetString(GL_VENDOR));
00718 gl_renderer << reinterpret_cast<const char *>(glGetString(GL_RENDERER));
00719 gl_version << reinterpret_cast<const char *>(glGetString(GL_VERSION));
00720 gl_extensions << reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS));
00721
00722 #ifndef WIN32
00723 if(!strstr(gl_renderer,"Voodoo3"))
00724 #endif
00725 if(currentScreensetting.fullscreen)
00726 SDL_ShowCursor(0);
00727 else
00728 SDL_ShowCursor(1);
00729
00730 #ifdef WIN32
00731 renderer_identification << "WIN32 ";
00732 #else
00733 #ifdef MACOSX
00734 renderer_identification << "MACOSX ";
00735 #else
00736 renderer_identification << "LINUX ";
00737 #endif
00738 #endif
00739 renderer_identification << rRenderIdCallback::RenderId() << ' ';
00740 #ifdef SDL_OPENGL
00741 renderer_identification << "SDL 1.2\n";
00742 renderer_identification << "USE_SDL=" << currentScreensetting.useSDL
00743 << '\n';
00744 #else
00745 renderer_identification << "SDL 1.0\n";
00746 #endif
00747 renderer_identification << "CD=" << currentScreensetting.colorDepth << '\n';
00748 renderer_identification << "FS=" << currentScreensetting.fullscreen << '\n';
00749 renderer_identification << "GL_VENDOR=" << gl_vendor << '\n';
00750 renderer_identification << "GL_RENDERER=" << gl_renderer << '\n';
00751 renderer_identification << "GL_VERSION=" << gl_version << '\n';
00752 #endif
00753
00754 if (
00755 (
00756 strstr(gl_vendor,"icrosoft") || strstr(gl_vendor,"SGI")
00757 )
00758 && strstr(gl_renderer,"eneric")
00759 )
00760 software_renderer=true;
00761
00762 if (
00763 strstr(gl_vendor,"rian") && strstr(gl_renderer,"X11") &&
00764 strstr(gl_renderer,"esa")
00765 )
00766 software_renderer=true;
00767
00768 if (
00769 strstr(gl_renderer,"GLX") &&
00770 strstr(gl_renderer,"ndirect") &&
00771 strstr(gl_renderer,"esa")
00772 )
00773 software_renderer=true;
00774
00775
00776 if ( strstr( gl_renderer, "SavageMX" ) )
00777 {
00778 rISurfaceTexture::storageHack_ = true;
00779 }
00780
00781
00782 if ( rTextureGroups::TextureMode[rTextureGroups::TEX_FONT] > GL_LINEAR )
00783 rTextureGroups::TextureMode[rTextureGroups::TEX_FONT] = GL_LINEAR;
00784
00785
00786 if ( strstr( gl_vendor, "ATI" ) )
00787 {
00788 default_texturemode = GL_LINEAR_MIPMAP_NEAREST;
00789 }
00790
00791
00792 while ( (SDL_GetAppState() & SDL_APPACTIVE) == 0)
00793 {
00794 SDL_Delay(100);
00795 SDL_PumpEvents();
00796 }
00797
00798 if (software_renderer && !last_software_renderer && !tRecorder::IsPlayingBack())
00799 sr_LoadDefaultConfig();
00800
00801 last_software_renderer=software_renderer;
00802
00803
00804
00805 while ( (SDL_GetAppState() & SDL_APPACTIVE) == 0)
00806 {
00807 SDL_Delay(100);
00808 SDL_PumpEvents();
00809 }
00810
00811 sr_ResetRenderState(true);
00812
00813 rCallbackAfterScreenModeChange::Exec();
00814 #endif
00815 return true;
00816 }
00817
00818 extern bool cycleprograminited;
00819
00820 bool sr_InitDisplay(){
00821 cycleprograminited = false;
00822 while (failed_attempts <= MAXEMERGENCY+1)
00823 {
00824 #ifndef DEBUG
00825 if (failed_attempts)
00826 currentScreensetting = *emergency[failed_attempts];
00827
00828 failed_attempts++;
00829 st_SaveConfig();
00830
00831
00832
00833 #endif
00834
00835 #ifdef MACOSX
00836
00837 static bool first = true;
00838 if ( first && currentScreensetting.fullscreen )
00839 {
00840 first = false;
00841 currentScreensetting.fullscreen = false;
00842
00843 sr_LockSDL();
00844 if (lowlevel_sr_InitDisplay())
00845 {
00846 sr_ExitDisplay();
00847 }
00848 sr_UnlockSDL();
00849
00850 currentScreensetting.fullscreen = true;
00851 }
00852 #endif
00853
00854 sr_LockSDL();
00855 if (lowlevel_sr_InitDisplay())
00856 {
00857 lastSuccess=currentScreensetting;
00858 sr_UnlockSDL();
00859 return true;
00860 }
00861
00862 st_SaveConfig();
00863
00864 if (lowlevel_sr_InitDisplay())
00865 {
00866 lastSuccess=currentScreensetting;
00867 sr_UnlockSDL();
00868 return true;
00869 }
00870 sr_UnlockSDL();
00871
00872
00873 }
00874
00875 failed_attempts = 1;
00876 st_SaveConfig();
00877
00878 tERR_ERROR("\nSorry, played all my cards trying to "
00879 "initialize your video system.\n"
00880 << tOutput("$program_name") << " won't run on your computer. Reason:\n\n"
00881 << lastError
00882 << "\n\nI'll try again from the beginning, but the "
00883 << "chances of success are minimal.\n"
00884 );
00885
00886 return false;
00887 }
00888
00889
00890 void sr_ExitDisplay(){
00891 #ifndef DEDICATED
00892 rCallbackBeforeScreenModeChange::Exec();
00893
00894 #ifdef DIRTY
00895 rSysDep::ExitGL();
00896 #endif
00897
00898 if (sr_screen){
00899 failed_attempts = 0;
00900 st_SaveConfig();
00901
00902 sr_LockSDL();
00903
00904
00905 sr_screen=NULL;
00906 sr_UnlockSDL();
00907
00908 }
00909 #endif
00910 }
00911
00912 bool sr_alphaBlend=true;
00913 bool sr_glOut=true;
00914 bool sr_smoothShading=true;
00915
00916
00917 int sr_floorMirror=0;
00918 int sr_floorDetail=rFLOOR_TEXTURE;
00919 bool sr_highRim=true;
00920 bool sr_upperSky=false;
00921 bool sr_lowerSky=false;
00922 bool sr_skyWobble=true;
00923 bool sr_dither=true;
00924 bool sr_infinityPlane=false;
00925 bool sr_laggometer=true;
00926 bool sr_predictObjects=false;
00927 bool sr_texturesTruecolor=false;
00928
00929 bool sr_textOut=false;
00930 bool sr_FPSOut=true;
00931
00932 bool sr_keepWindowActive=false;
00933
00934 tString renderer_identification;
00935
00936 void sr_LoadDefaultConfig(){
00937
00938
00939 sr_alphaBlend=true;
00940 sr_useDisplayLists=rDisplayList_Off;
00941 sr_textOut=true;
00942 sr_dither=true;
00943 sr_smoothShading=true;
00944 int i;
00945 #ifndef DEDICATED
00946 for (i=rTextureGroups::TEX_GROUPS-1;i>=0;i--)
00947 rTextureGroups::TextureMode[i]=default_texturemode;
00948
00949
00950 rTextureGroups::TextureMode[rTextureGroups::TEX_FONT]=GL_LINEAR;
00951 #endif
00952 sr_floorDetail=rFLOOR_TWOTEXTURE;
00953 sr_floorMirror=rMIRROR_OFF;
00954 sr_infinityPlane=false;
00955 sr_lowerSky=false;
00956 sr_upperSky=false;
00957 sr_keepWindowActive=false;
00958 rSysDep::swapMode_=rSysDep::rSwap_glFinish;
00959
00960 if (software_renderer){
00961
00962 for (i=rTextureGroups::TEX_GROUPS-1;i>=0;i--)
00963 rTextureGroups::TextureMode[i]=-1;
00964
00965 #ifndef DEDICATED
00966 rTextureGroups::TextureMode[rTextureGroups::TEX_OBJ]=GL_NEAREST_MIPMAP_NEAREST;
00967 rTextureGroups::TextureMode[rTextureGroups::TEX_FONT]=GL_NEAREST_MIPMAP_NEAREST;
00968 #endif
00969
00970 sr_highRim=false;
00971 sr_dither=false;
00972 sr_alphaBlend=false;
00973 sr_smoothShading=true;
00974
00975 sr_floorDetail=rFLOOR_GRID;
00976 sr_floorMirror=rMIRROR_OFF;
00977 }
00978 else if(strstr(gl_vendor,"3Dfx")){
00979
00980
00981 }
00982 else if(strstr(gl_vendor,"NVIDIA")){
00983
00984 sr_infinityPlane=true;
00985 sr_useDisplayLists=rDisplayList_CAC;
00986 rSysDep::swapMode_=rSysDep::rSwap_glFlush;
00987 }
00988 #ifdef MACOSX
00989 else if(strstr(gl_vendor,"ATI")){
00990
00991 rSysDep::swapMode_=rSysDep::rSwap_glFlush;
00992 }
00993 #endif
00994 else if(strstr(gl_vendor,"Matrox")){
00995 sr_floorDetail = rFLOOR_TEXTURE;
00996 }
00997 }
00998
00999 void sr_ResetRenderState(bool menu){
01000 if(!sr_glOut)
01001 return;
01002 #ifndef DEDICATED
01003
01004
01005
01006 if (menu){
01007 glDisable(GL_DEPTH_TEST);
01008 glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
01009 glViewport (0, 0, GLsizei(sr_screenWidth), GLsizei(sr_screenHeight));
01010 }
01011 else{
01012 glEnable(GL_DEPTH_TEST);
01013 glDepthFunc(GL_LEQUAL);
01014 }
01015
01016 if (sr_dither)
01017 glEnable(GL_DITHER);
01018 else
01019 glDisable(GL_DITHER);
01020
01021 glDisable(GL_LIGHTING);
01022
01023
01024
01025
01026 glDisable(GL_TEXTURE_2D);
01027
01028
01029
01030 if (sr_smoothShading)
01031 glShadeModel(GL_SMOOTH);
01032 else
01033 glShadeModel(GL_FLAT);
01034
01035
01036 if (sr_alphaBlend){
01037 glEnable(GL_ALPHA_TEST);
01038 glAlphaFunc(GL_GREATER,0);
01039 glEnable(GL_BLEND);
01040 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
01041 }
01042 else{
01043 glDisable(GL_ALPHA_TEST);
01044 glDisable(GL_BLEND);
01045 }
01046
01047
01048 glMatrixMode(GL_TEXTURE);
01049 glLoadIdentity();
01050
01051 glMatrixMode(GL_PROJECTION);
01052 glLoadIdentity();
01053
01054 glMatrixMode(GL_MODELVIEW);
01055 glLoadIdentity();
01056 #endif
01057 }
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075 void sr_DepthOffset(bool offset){
01076
01077
01078
01079 #ifndef DEDICATED
01080 if (offset){
01081
01082
01083 glPolygonOffset(-2,-5);
01084 glEnable(GL_POLYGON_OFFSET_LINE);
01085 glEnable(GL_POLYGON_OFFSET_POINT);
01086 glEnable(GL_POLYGON_OFFSET_FILL);
01087 }
01088 else{
01089 glPolygonOffset(0,0);
01090 glDisable(GL_POLYGON_OFFSET_POINT);
01091 glDisable(GL_POLYGON_OFFSET_LINE);
01092 glDisable(GL_POLYGON_OFFSET_FILL);
01093
01094
01095 }
01096
01097 #endif
01098 }
01099
01100
01101 void sr_Activate(bool active)
01102 {
01103 #ifndef DEDICATED
01104 if ( !currentScreensetting.fullscreen && !active && sr_keepWindowActive )
01105 {
01106 sr_glOut=!active;
01107 }
01108 else
01109 {
01110 sr_glOut=active;
01111 }
01112
01113
01114 if (!sr_glOut)
01115 rCallbackBeforeScreenModeChange::Exec();
01116
01117
01118
01119
01120
01121
01122 #ifdef WIN32
01123 if ( currentScreensetting.fullscreen && !active )
01124 {
01125 SDL_WM_IconifyWindow();
01126 }
01127 #endif
01128 #endif
01129 }
01130
01131
01132
01133
01134
01135
01136 static tCallback *sr_BeforeAnchor;
01137
01138 rCallbackBeforeScreenModeChange::rCallbackBeforeScreenModeChange(AA_VOIDFUNC *f)
01139 :tCallback(sr_BeforeAnchor, f){}
01140
01141 void rCallbackBeforeScreenModeChange::Exec()
01142 {
01143 tCallback::Exec(sr_BeforeAnchor);
01144 }
01145
01146 static tCallback *sr_AfterAnchor;
01147
01148 rCallbackAfterScreenModeChange::rCallbackAfterScreenModeChange(AA_VOIDFUNC *f)
01149 :tCallback(sr_AfterAnchor, f){}
01150
01151 void rCallbackAfterScreenModeChange::Exec()
01152 {
01153 tCallback::Exec(sr_AfterAnchor);
01154 }
01155