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
00029 #include "defs.h"
00030
00031 #include "rGL.h"
00032
00033 #ifndef DEDICATED
00034 #include "rSDL.h"
00035 #endif
00036
00037 #include "rSysdep.h"
00038 #include "tInitExit.h"
00039 #include "tDirectories.h"
00040 #include "tSysTime.h"
00041 #include "rConsole.h"
00042 #include "aa_config.h"
00043 #include <iostream>
00044 #include "rScreen.h"
00045 #include "rTexture.h"
00046 #include "tCommandLine.h"
00047 #include "tConfiguration.h"
00048 #include "tRecorder.h"
00049 #include "rTextureRenderTarget.h"
00050 #include <memory>
00051
00052 #ifndef DEDICATED
00053 #include "SDL_thread.h"
00054 #include "SDL_mutex.h"
00055
00056 #include <png.h>
00057 #include <unistd.h>
00058 #define SCREENSHOT_PNG_BITDEPTH 8
00059 #define SCREENSHOT_BYTES_PER_PIXEL 3
00060 #ifndef SDL_OPENGL
00061 #ifndef DIRTY
00062 #define DIRTY
00063 #endif
00064 #endif
00065
00066
00067
00068
00069
00070 #ifndef DIRTY
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 #elif defined(WIN32)
00083
00084 #include <windows.h>
00085 #include <windef.h>
00086 #include "rGL.h"
00087 static HDC hDC=NULL;
00088 static HGLRC hRC=NULL;
00089
00090 #elif defined(unix) || defined(__unix__)
00091
00092 #include <GL/glx.h>
00093 static GLXContext cx;
00094 Display *dpy=NULL;
00095 Window win;
00096
00097 #endif
00098
00099 #ifdef DIRTY
00100 #include <SDL_syswm.h>
00101
00102
00103 bool rSysDep::InitGL(){
00104 SDL_SysWMinfo system;
00105 SDL_VERSION(&system.version);
00106 if (!SDL_GetWMInfo(&system)){
00107 std::cerr << "Video information not available!\n";
00108 return(false);
00109 }
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 #ifdef WIN32
00137
00138
00139
00140 if (!hRC){
00141 HWND hWnd=system.window;
00142
00143 PIXELFORMATDESCRIPTOR pfd;
00144 int iFormat;
00145
00146
00147 hDC = GetDC( hWnd );
00148 if (!hDC) return false;
00149
00150
00151 ZeroMemory( &pfd, sizeof( pfd ) );
00152 pfd.nSize = sizeof( pfd );
00153 pfd.nVersion = 1;
00154 pfd.dwFlags = PFD_DRAW_TO_WINDOW |
00155 PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
00156 pfd.iPixelType = PFD_TYPE_RGBA;
00157 pfd.cColorBits = currentScreensetting.colorDepth ? 24 : 16;
00158 pfd.cDepthBits = 16;
00159 pfd.iLayerType = PFD_MAIN_PLANE;
00160 iFormat = ChoosePixelFormat( hDC, &pfd );
00161 SetPixelFormat( hDC, iFormat, &pfd );
00162
00163
00164 hRC = wglCreateContext( hDC );
00165 if (!hRC || !wglMakeCurrent( hDC, hRC ))
00166 return false;
00167 }
00168
00169 #elif defined(unix) || defined(__unix__)
00170 if (system.subsystem!=SDL_SYSWM_X11){
00171 std::cerr << "System is not X11!\n";
00172 std::cerr << (int)system.subsystem << "!=" << (int)SDL_SYSWM_X11 <<'\n';
00173 return false;
00174 }
00175
00176 if (!dpy){
00177
00178 dpy=system.info.x11.display;
00179 win=system.info.x11.window;
00180
00181 int errorbase,tEventbase;
00182 if (glXQueryExtension(dpy,&errorbase,&tEventbase) == False){
00183 std::cerr << "OpenGL through GLX not supported.\n";
00184 return false;
00185 }
00186
00187 int configuration[]={GLX_DOUBLEBUFFER,GLX_RGBA,GLX_DEPTH_SIZE ,12, GLX_RED_SIZE,1,
00188 GLX_BLUE_SIZE,1,GLX_GREEN_SIZE,1,None
00189 };
00190
00191 XVisualInfo *vi=glXChooseVisual(dpy,DefaultScreen(dpy),configuration);
00192
00193 if (vi== NULL){
00194 std::cerr << "Could not initialize Visual.\n";
00195 return false;
00196 }
00197
00198 cx=glXCreateContext(dpy,vi,
00199 NULL,True);
00200
00201 if (cx== NULL){
00202 std::cerr << "Could not initialize GL context.\n";
00203 return false;
00204 }
00205
00206 if (!glXMakeCurrent(dpy,win,cx)){
00207 dpy=0;
00208 return false;
00209 }
00210 }
00211
00212 #endif
00213
00214 return true;
00215 }
00216
00217 void rSysDep::ExitGL(){
00218 SDL_SysWMinfo system;
00219 SDL_GetWMInfo(&system);
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 #if defined(WIN32)
00232 HWND hWnd=system.window;
00233
00234
00235
00236 if (hRC){
00237
00238 wglMakeCurrent( NULL, NULL );
00239 wglDeleteContext( hRC );
00240 ReleaseDC( hWnd, hDC );
00241
00242 hRC=NULL;
00243 hDC=NULL;
00244 }
00245 #elif defined(unix) || defined(__unix__)
00246 if (dpy){
00247
00248
00249 glXMakeCurrent(dpy,None,NULL);
00250 glXDestroyContext(dpy, cx );
00251 dpy=NULL;
00252 }
00253 #endif
00254 }
00255 #endif // DIRTY
00256
00257 bool sr_screenshotIsPlanned=false;
00258 static bool s_videoout =false;
00259 static int s_videooutDest=fileno(stdout);
00260
00261 static bool png_screenshot=true;
00262 static tConfItem<bool> pns("PNG_SCREENSHOT",png_screenshot);
00263 #ifndef DEDICATED
00264
00265 static void SDL_SavePNG(SDL_Surface *image, tString filename){
00266 png_structp png_ptr;
00267 png_infop info_ptr;
00268 png_byte **row_ptrs;
00269 int i;
00270 static FILE *fp;
00271
00272 if (!(fp = fopen(filename, "wb"))) {
00273 fprintf(stderr, "can't open file for writing\n");
00274 return;
00275 }
00276
00277 if (!(png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL))) {
00278 return;
00279 }
00280
00281 if (!(info_ptr = png_create_info_struct(png_ptr))) {
00282 png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
00283 return;
00284 }
00285
00286 png_init_io(png_ptr, fp);
00287
00288 png_set_IHDR(png_ptr, info_ptr, sr_screenWidth, sr_screenHeight,
00289 SCREENSHOT_PNG_BITDEPTH, PNG_COLOR_TYPE_RGB,
00290 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
00291 PNG_FILTER_TYPE_DEFAULT);
00292 png_write_info(png_ptr, info_ptr);
00293
00294
00295 if (!(row_ptrs = (png_byte**) malloc(sr_screenHeight * sizeof(png_byte*)))) {
00296 png_destroy_write_struct(&png_ptr, &info_ptr);
00297 return;
00298 }
00299
00300 for (i = 0; i < sr_screenHeight; i++) {
00301 row_ptrs[i] = (png_byte *)image->pixels + (sr_screenHeight - i - 1)
00302 * SCREENSHOT_BYTES_PER_PIXEL * sr_screenWidth;
00303 }
00304
00305 png_write_image(png_ptr, row_ptrs);
00306 png_write_end(png_ptr, info_ptr);
00307 png_destroy_write_struct(&png_ptr, &info_ptr);
00308
00309 free(row_ptrs);
00310 fclose(fp);
00311 }
00312 #endif
00313
00314 static void make_screenshot(){
00315 #ifndef DEDICATED
00316
00317 static int number=0;
00318 number++;
00319
00320 SDL_Surface *image;
00321 SDL_Surface *temp;
00322 int idx;
00323 image = SDL_CreateRGBSurface(SDL_SWSURFACE, sr_screenWidth, sr_screenHeight,
00324 24, 0x0000FF, 0x00FF00, 0xFF0000 ,0);
00325 temp = SDL_CreateRGBSurface(SDL_SWSURFACE, sr_screenWidth, sr_screenHeight,
00326 24, 0x0000FF, 0x00FF00, 0xFF0000, 0);
00327
00328
00329
00330 glReadPixels(0,0,sr_screenWidth, sr_screenHeight, GL_RGB,
00331 GL_UNSIGNED_BYTE, image->pixels);
00332
00333
00334 for (idx = 0; idx < sr_screenHeight; idx++)
00335 {
00336 memcpy(reinterpret_cast<char *>(temp->pixels) + 3 * sr_screenWidth * idx,
00337 reinterpret_cast<char *>(image->pixels)+ 3
00338 * sr_screenWidth*(sr_screenHeight - idx-1),
00339 3*sr_screenWidth);
00340 }
00341
00342 if (s_videoout)
00343 write(s_videooutDest, temp->pixels, sr_screenWidth * sr_screenHeight * 3);
00344
00345 if (sr_screenshotIsPlanned) {
00346
00347 bool done = false;
00348 while ( !done )
00349 {
00350
00351 tString fileName("screenshot_");
00352 fileName << number;
00353 if (png_screenshot)
00354 fileName << ".png";
00355 else
00356 fileName << ".bmp";
00357
00358
00359 std::ifstream s;
00360 if ( tDirectories::Screenshot().Open( s, fileName ) )
00361 {
00362
00363 number++;
00364 continue;
00365 }
00366
00367
00368 if (png_screenshot)
00369 SDL_SavePNG(image, tDirectories::Screenshot().GetWritePath( fileName ));
00370 else
00371 SDL_SaveBMP(temp, tDirectories::Screenshot().GetWritePath( fileName ) );
00372 done = true;
00373 }
00374 }
00375
00376
00377 SDL_FreeSurface(image);
00378 SDL_FreeSurface(temp);
00379 #endif
00380 }
00381
00382 class PerformanceCounter
00383 {
00384 public:
00385 PerformanceCounter(): count_(0){
00386 tRealSysTimeFloat();
00387 }
00388 unsigned int Count(){
00389 return count_++;
00390 }
00391 ~PerformanceCounter()
00392 {
00393 double time = tRealSysTimeFloat();
00394 std::stringstream s;
00395 s << count_ << " frames in " << time << " seconds: " << count_ / time << " fps.\n";
00396 #ifdef WIN32
00397 MessageBox (NULL, s.str().c_str() , "Performance", MB_OK);
00398 #else
00399 std::cout << s.str();
00400 #endif
00401 }
00402 private:
00403 unsigned int count_;
00404 };
00405
00406 static double s_nextFastForwardFrameRecorded=0;
00407 static double s_nextFastForwardFrameReal=0;
00408 #endif // DEDICATED
00409
00410
00411 static REAL sr_FF_Maxstep=1;
00412 static tSettingItem<REAL> c_ff( "FAST_FORWARD_MAXSTEP",
00413 sr_FF_Maxstep );
00414
00415 static REAL sr_FF_MaxstepReal=.05;
00416 static tSettingItem<REAL> c_ffre( "FAST_FORWARD_MAXSTEP_REAL",
00417 sr_FF_MaxstepReal );
00418
00419 static REAL sr_FF_MaxstepRel=1;
00420 static tSettingItem<REAL> c_ffr( "FAST_FORWARD_MAXSTEP_REL",
00421 sr_FF_MaxstepRel );
00422
00423
00424 static double s_fastForwardTo=0;
00425 static bool s_fastForward =false;
00426 static bool s_benchmark =false;
00427
00428 class rFastForwardCommandLineAnalyzer: public tCommandLineAnalyzer
00429 {
00430 private:
00431 virtual bool DoAnalyze( tCommandLineParser & parser )
00432 {
00433
00434 tString forward;
00435 if ( parser.GetOption( forward, "--fastforward" ) )
00436 {
00437
00438 s_fastForward = true;
00439
00440
00441 std::stringstream str(static_cast< char const * >( forward ) );
00442 str >> s_fastForwardTo;
00443
00444 return true;
00445 }
00446
00447 if ( parser.GetSwitch( "--benchmark" ) )
00448 {
00449
00450 s_benchmark = true;
00451 return true;
00452 }
00453
00454 #ifndef DEDICATED
00455 if ( parser.GetSwitch( "--videoout" ) )
00456 {
00457
00458 if ((s_videooutDest = dup(fileno(stdout))) == -1)
00459 std::cout << "Warning: Failed to duplicate stdout descriptor for video\n";
00460 else {
00461 if (-1 == dup2(fileno(stderr), fileno(stdout)))
00462 std::cout << "Warning: Failed to redirect default output to stderr\n";
00463 else
00464 std::cout << "Video Output: normal output redirected to stderr\n";
00465 }
00466
00467 s_videoout = true;
00468 return true;
00469 }
00470 #endif
00471
00472 return false;
00473 }
00474
00475 virtual void DoHelp( std::ostream & s )
00476 {
00477 s << "--fastforward <time> : lets time run very fast until the given time is reached\n";
00478 s << "--benchmark : renders frames as they were recorded\n";
00479 #ifndef DEDICATED
00480 s << "--videoout : writes a raw video stream of frames to stdout\n";
00481 #endif
00482 }
00483 };
00484
00485 static rFastForwardCommandLineAnalyzer analyzer;
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513 rSysDep::rSwapMode rSysDep::swapMode_ = rSysDep::rSwap_glFlush;
00514
00515
00516
00517 #ifndef DEDICATED
00518
00519 static void breakpoint(){}
00520
00521 static bool sr_netSyncThreadGoOn = true;
00522 static rSysDep::rNetIdler * sr_netIdler = NULL;
00523 int sr_NetSyncThread(void *lockVoid)
00524 {
00525 SDL_mutex *lock = (SDL_mutex *)lockVoid;
00526
00527 SDL_mutexP(lock);
00528
00529 while ( sr_netSyncThreadGoOn )
00530 {
00531 SDL_mutexV(lock);
00532
00533 bool toDo = sr_netIdler->Wait();
00534 SDL_mutexP(lock);
00535
00536 if ( toDo )
00537 {
00538
00539 bool glout = sr_glOut;
00540 sr_glOut = false;
00541
00542
00543 sr_netIdler->Do();
00544
00545
00546 sr_glOut = glout;
00547 }
00548 }
00549
00550 SDL_mutexV(lock);
00551
00552 return 0;
00553 }
00554
00555 static SDL_Thread * sr_netSyncThread = NULL;
00556 static SDL_mutex * sr_netLock = NULL;
00557 void rSysDep::StartNetSyncThread( rNetIdler * idler )
00558 {
00559 sr_netIdler = idler;
00560
00561 return;
00562
00563
00564 if ( tRecorder::IsRunning() )
00565 return;
00566
00567 if ( sr_netSyncThread )
00568 return;
00569
00570
00571 if ( !sr_netLock )
00572 sr_netLock = SDL_CreateMutex();
00573
00574
00575 sr_netSyncThread = SDL_CreateThread( sr_NetSyncThread, sr_netLock );
00576 if ( !sr_netSyncThread )
00577 return;
00578
00579
00580 SDL_mutexP( sr_netLock );
00581 }
00582
00583 void rSysDep::StopNetSyncThread()
00584 {
00585
00586 if ( sr_netSyncThread )
00587 {
00588 SDL_mutexV( sr_netLock );
00589 sr_netSyncThreadGoOn = false;
00590 SDL_WaitThread( sr_netSyncThread, NULL );
00591 sr_netSyncThread = NULL;
00592 sr_netIdler = NULL;
00593 }
00594
00595
00596 if ( sr_netLock )
00597 {
00598 SDL_DestroyMutex( sr_netLock );
00599 sr_netLock = NULL;
00600 }
00601 }
00602
00603 int NextPowerOfTwo( int in )
00604 {
00605 int x = 1;
00606 while ( x * 32 <= in )
00607 x <<= 5;
00608 while ( x < in )
00609 x <<= 1;
00610
00611 return x;
00612 }
00613
00614 bool sr_MotionBlurCore( REAL alpha, rTextureRenderTarget & blurTarget )
00615 {
00616 sr_CheckGLError();
00617
00618 if ( alpha < 0 )
00619 alpha = 0;
00620
00621 {
00622 if ( blurTarget.IsTarget() )
00623 {
00624 blurTarget.Pop();
00625
00626 blurTarget.Select();
00627
00628 glDrawBuffer( GL_FRONT );
00629
00630 sr_CheckGLError();
00631
00632
00633 REAL maxu = REAL(sr_screenWidth)/blurTarget.GetWidth();
00634 REAL maxv = REAL(sr_screenHeight)/blurTarget.GetHeight();
00635
00636 glEnable(GL_TEXTURE_2D);
00637
00638
00639 glDisable( GL_DEPTH_TEST );
00640 glDepthMask(0);
00641
00642 glMatrixMode( GL_PROJECTION );
00643 glLoadIdentity();
00644 glMatrixMode( GL_MODELVIEW );
00645 glLoadIdentity();
00646 glViewport(0,0,sr_screenWidth, sr_screenHeight);
00647
00648 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,
00649 GL_NEAREST);
00650 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,
00651 GL_NEAREST);
00652
00653 glDisable(GL_ALPHA_TEST);
00654
00655 glEnable(GL_BLEND);
00656 glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
00657
00658 glDisable(GL_LIGHTING);
00659
00660 glBegin( GL_QUADS );
00661 glColor4f( 1,1,1,alpha );
00662
00663 glTexCoord2f( 0, 0 );
00664 glVertex2f( -1, -1 );
00665
00666 glTexCoord2f( maxu, 0 );
00667 glVertex2f( 1, -1 );
00668
00669 glTexCoord2f( maxu, maxv );
00670 glVertex2f( 1, 1 );
00671
00672 glTexCoord2f( 0, maxv );
00673 glVertex2f( -1, 1 );
00674 glEnd();
00675
00676 sr_CheckGLError();
00677
00678
00679 glDepthMask(1);
00680
00681 glDrawBuffer( GL_BACK );
00682 }
00683
00684 blurTarget.Push();
00685
00686 sr_CheckGLError();
00687
00688 return false;
00689 }
00690
00691 return true;
00692
00693 #if 0
00694 GLenum error = glGetError();
00695 if ( error != GL_NO_ERROR )
00696 con << "GL error " << error << "\n";
00697 #endif
00698 }
00699
00700
00701 static REAL sr_motionBlurTime = .0075;
00702 static tSettingItem<REAL> c_mb( "MOTION_BLUR_TIME",
00703 sr_motionBlurTime );
00704
00705
00706 bool sr_MotionBlur( double time, std::auto_ptr< rTextureRenderTarget > & blurTarget )
00707 {
00708 static bool lastActive = false;
00709 bool active = false;
00710
00711
00712 static double lastTime = time;
00713 REAL frameTime = time - lastTime;
00714
00715 if ( currentScreensetting.vSync == ArmageTron_VSync_MotionBlur )
00716 {
00717
00718
00719 static int hyster = 0;
00720 static int thresh = 100;
00721 active = lastActive;
00722
00723 if ( frameTime * 2 < sr_motionBlurTime )
00724 {
00725 if ( ++hyster > thresh )
00726 {
00727 active = true;
00728 hyster = thresh;
00729 }
00730 }
00731 else if ( frameTime > sr_motionBlurTime * 2 )
00732 {
00733 if ( --hyster < -thresh )
00734 {
00735 active = false;
00736 hyster = -thresh;
00737 }
00738 }
00739 else
00740 {
00741 if ( hyster < 0 )
00742 ++hyster;
00743 else
00744 --hyster;
00745 }
00746
00747 lastTime = time;
00748 }
00749
00750
00751 if ( lastActive )
00752 {
00753
00754 int blurWidth = NextPowerOfTwo( sr_screenWidth );
00755 int blurHeight = NextPowerOfTwo( sr_screenHeight );
00756
00757
00758 if ( blurTarget.get() && ( blurTarget->GetWidth() < blurWidth || blurTarget->GetHeight() < blurHeight ) )
00759 {
00760 blurTarget = std::auto_ptr< rTextureRenderTarget >();
00761 }
00762
00763
00764 if ( !blurTarget.get() )
00765 {
00766 try
00767 {
00768 blurTarget = std::auto_ptr< rTextureRenderTarget >( new rTextureRenderTarget( blurWidth, blurHeight ) );
00769 }
00770 catch( rExceptionGLEW const & e )
00771 {
00772
00773 currentScreensetting.vSync = ArmageTron_VSync_Off;
00774 lastActive = false;
00775
00776 con << tOutput("$screen_vsync_motionblur_unsupported");
00777
00778 return true;
00779 }
00780 }
00781
00782
00783 bool ret = sr_MotionBlurCore( 1 - frameTime / sr_motionBlurTime, *blurTarget );
00784
00785
00786 lastActive = active;
00787
00788
00789 if ( !active )
00790 {
00791 blurTarget->Pop();
00792 }
00793
00794 return ret;
00795 }
00796
00797 lastActive = active;
00798
00799
00800 if ( blurTarget.get() && blurTarget->IsTarget() )
00801 {
00802 blurTarget->Pop();
00803 }
00804
00805 return true;
00806 }
00807
00808 void rSysDep::SwapGL(){
00809 static std::auto_ptr< rTextureRenderTarget > blurTarget(0);
00810
00811 if ( s_benchmark )
00812 {
00813 static PerformanceCounter counter;
00814 counter.Count();
00815 }
00816
00817 double time = tSysTimeFloat();
00818 double realTime = tRealSysTimeFloat();
00819
00820 bool next_glOut = sr_glOut;
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833 if ( !s_benchmark && !s_fastForward && tRecorder::IsPlayingBack() )
00834 {
00835 static double timeOffset=0;
00836 static double lastRendered=0;
00837
00838
00839 double behind = - time + realTime + timeOffset;
00840
00841
00842
00843 if ( behind > .5 || realTime > lastRendered + .2 )
00844 {
00845 timeOffset -= behind;
00846 next_glOut = true;
00847 }
00848 else
00849 {
00850
00851 if ( behind > .1 )
00852 {
00853 next_glOut = false;
00854 }
00855 else if ( sr_glOut )
00856 {
00857 lastRendered=realTime;
00858
00859 if ( behind < -.5 )
00860 timeOffset -= behind;
00861 else if ( behind < -.1 )
00862 {
00863 int delay = int( -( behind + .1 ) * 1000000 );
00864
00865 tDelayForce( delay );
00866 }
00867 }
00868 else
00869 {
00870
00871 next_glOut = true;
00872 }
00873 }
00874
00875 if ( next_glOut )
00876 lastRendered=realTime;
00877 }
00878
00879 if (!sr_glOut)
00880 {
00881
00882 if ( s_fastForward && ( time > s_nextFastForwardFrameRecorded || realTime > s_nextFastForwardFrameReal ) || next_glOut )
00883 {
00884 sr_glOut = true;
00885 rSysDep::ClearGL();
00886 }
00887
00888
00889 if ( tRecorder::IsRunning() ) {
00890 rPerFrameTask::DoPerFrameTasks();
00891 #ifdef HAVE_LIBRUBY
00892 rPerFrameTaskRuby::DoPerFrameTasks();
00893 #endif
00894 }
00895
00896
00897 return;
00898 }
00899
00900
00901 rPerFrameTask::DoPerFrameTasks();
00902 #ifdef HAVE_LIBRUBY
00903 rPerFrameTaskRuby::DoPerFrameTasks();
00904 #endif
00905
00906
00907 SDL_mutexV( sr_netLock );
00908 sr_LockSDL();
00909
00910
00911 bool shouldSwap = sr_MotionBlur( time, blurTarget );
00912
00913 switch ( swapMode_ )
00914 {
00915 case rSwap_Fastest:
00916 break;
00917 case rSwap_glFlush:
00918 glFlush();
00919 break;
00920 case rSwap_glFinish:
00921 glFinish();
00922 break;
00923 }
00924
00925 if ( shouldSwap )
00926 {
00927 #if defined(SDL_OPENGL)
00928 if (lastSuccess.useSDL)
00929 SDL_GL_SwapBuffers();
00930
00931
00932 #endif
00933
00934 #ifdef DIRTY
00935 if (!lastSuccess.useSDL){
00936 #if defined(WIN32)
00937 SwapBuffers( hDC );
00938 #elif defined(unix) || defined(__unix__)
00939 glXSwapBuffers(dpy,win);
00940 #endif
00941 }
00942 #endif
00943 }
00944
00945 if (sr_screenshotIsPlanned){
00946 make_screenshot();
00947 sr_screenshotIsPlanned=false;
00948 }
00949 else if (s_videoout)
00950 make_screenshot();
00951
00952 sr_UnlockSDL();
00953
00954 SDL_mutexP( sr_netLock );
00955
00956
00957
00958 if ( s_fastForward && tRecorder::IsPlayingBack() )
00959 {
00960 if ( time < s_fastForwardTo )
00961 {
00962
00963 s_nextFastForwardFrameRecorded = ( s_fastForwardTo - time ) * sr_FF_MaxstepRel;
00964 if ( s_nextFastForwardFrameRecorded > sr_FF_Maxstep )
00965 s_nextFastForwardFrameRecorded = sr_FF_Maxstep ;
00966 s_nextFastForwardFrameRecorded += time;
00967 s_nextFastForwardFrameReal = realTime + sr_FF_MaxstepReal ;
00968
00969 next_glOut = false;
00970 }
00971 else
00972 {
00973 std::cout << "End of fast forward mode.\n";
00974 st_Breakpoint();
00975 s_fastForward = false;
00976 }
00977 }
00978
00979
00980 if ( !s_fastForward )
00981 {
00982 breakpoint();
00983 }
00984
00985
00986
00987
00988
00989 sr_glOut = next_glOut;
00990 }
00991 #endif // dedicated
00992
00993 #ifndef DEDICATED
00994 static SDL_mutex *mut;
00995
00996 static void stuff_init(){
00997 mut=SDL_CreateMutex();
00998 }
00999
01000 static tInitExit stuff_ie(&stuff_init);
01001 #endif
01002
01003 void sr_LockSDL(){
01004
01005 #ifndef DEDICATED
01006 #ifndef WIN32
01007
01008 #endif
01009 #endif
01010
01011 }
01012
01013 void sr_UnlockSDL(){
01014
01015 #ifndef DEDICATED
01016 #ifndef WIN32
01017
01018 #endif
01019 #endif
01020
01021 }
01022
01023 #ifndef DEDICATED
01024 void rSysDep::ClearGL(){
01025 if (sr_glOut){
01026
01027
01028
01029
01030
01031
01032
01033
01034 glClearColor(0.0,0.0,0.0,1.0);
01035 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
01036 }
01037 }
01038 #endif
01039
01040