home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2009 February / maximum-cd-2009-02.iso / DiscContents / SMC_1.6_win32.exe / src / core / framerate.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2008-04-21  |  4.2 KB  |  208 lines

  1. /***************************************************************************
  2.  * framerate.cpp  -  Framerate independant motion control
  3.  *
  4.  * Copyright (C) 2003 - 2008 Florian Richter
  5.  ***************************************************************************/
  6. /*
  7.    This program is free software; you can redistribute it and/or modify
  8.    it under the terms of the GNU General Public License as published by
  9.    the Free Software Foundation; either version 3 of the License, or
  10.    (at your option) any later version.
  11.    
  12.    You should have received a copy of the GNU General Public License
  13.    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  14. */
  15.  
  16. #include "../core/globals.h"
  17. #include "../core/framerate.h"
  18.  
  19.  
  20. /* *** *** *** *** *** *** cPerformance_Timer *** *** *** *** *** *** *** *** *** *** *** */
  21.  
  22. cPerformance_Timer :: cPerformance_Timer( void )
  23. {
  24.     Reset();
  25. }
  26.  
  27. cPerformance_Timer :: ~cPerformance_Timer( void )
  28. {
  29.  
  30. }
  31.  
  32. void cPerformance_Timer :: Reset( void )
  33. {
  34.     frame_counter = 0;
  35.     ms_counter = 0;
  36.     ms = 0;
  37. }
  38.  
  39. void cPerformance_Timer :: Update( void )
  40. {
  41.     // count frame
  42.     frame_counter++;
  43.  
  44.     // add milliseconds
  45.     Uint32 new_ticks = SDL_GetTicks();
  46.     ms_counter += new_ticks - pFramerate->perf_last_ticks;
  47.     pFramerate->perf_last_ticks = new_ticks;
  48.  
  49.     // counted 100 frames
  50.     if( frame_counter >= 100 )
  51.     {
  52.         ms = ms_counter;
  53.         frame_counter = 0;
  54.         ms_counter = 0;
  55.     }
  56. }
  57.  
  58.  
  59. /* *** *** *** *** *** *** cFramerate *** *** *** *** *** *** *** *** *** *** *** */
  60.  
  61. cFramerate :: cFramerate( float tfps /* = DESIRED_FPS */ )
  62. {
  63.     speedfactor = 0.1f;
  64.     fps = 0;
  65.     fps_best = 0;
  66.     fps_worst = 100;
  67.     fps_average = 0;
  68.  
  69.     force_speedfactor = 0;
  70.  
  71.     perf_last_ticks = 0;
  72.  
  73.     // create performance timers
  74.     for( unsigned int i = 0; i < 20; i++ )
  75.     {
  76.         perf_timer.push_back( new cPerformance_Timer() );
  77.     }
  78.  
  79.     Init( tfps );
  80. }
  81.  
  82. cFramerate :: ~cFramerate ( void )
  83. {
  84.     // clear performance timer
  85.     for( Performance_Timer_List::iterator itr = perf_timer.begin(), itr_end = perf_timer.end(); itr != itr_end; ++itr )
  86.     {
  87.         delete *itr;
  88.     }
  89.  
  90.     perf_timer.clear();
  91. }
  92.  
  93. void cFramerate :: Init( float tfps )
  94. {
  95.     fps_target = tfps;
  96.     maxspeedfactor = tfps * 0.15f;
  97.     currentticks = SDL_GetTicks();
  98.     framedelay = currentticks;
  99.     fps_average_framedelay = currentticks;
  100.     frames_counted = 0;
  101. }
  102.  
  103. void cFramerate :: Update( void )
  104. {
  105.     currentticks = SDL_GetTicks();
  106.  
  107.     // if speedfactor is forced
  108.     if( force_speedfactor != 0 )
  109.     {
  110.         speedfactor = force_speedfactor;
  111.     }
  112.     // default speedfactor measuring
  113.     else
  114.     {
  115.         // check if the update was too early for SDL
  116.         if( currentticks == framedelay )
  117.         {
  118.             // prevent division by 0
  119.             speedfactor = 0.00001f;
  120.         }
  121.         else
  122.         {
  123.             // frame speedfactor calculation
  124.             speedfactor = static_cast<float>(( currentticks - framedelay ) / ( 1000 / fps_target ));
  125.         }
  126.  
  127.         if( speedfactor <= 0 )
  128.         {
  129.             speedfactor = 0.00001f;
  130.         }
  131.         else if( speedfactor > maxspeedfactor ) 
  132.         {
  133.             speedfactor = maxspeedfactor;
  134.         }
  135.     }
  136.  
  137.     // speedfactor based fps
  138.     fps = fps_target / speedfactor;
  139.     
  140.     // calculate average fps every second
  141.     if( currentticks - fps_average_framedelay > 1000 )
  142.     {
  143.         fps_average = frames_counted;
  144.  
  145.         fps_average_framedelay += 1000;
  146.         frames_counted = 0;
  147.     }
  148.     // count a fps
  149.     else
  150.     {
  151.         frames_counted++;
  152.     }
  153.  
  154.     // best fps
  155.     if( fps > fps_best )
  156.     {
  157.         fps_best = fps;
  158.     }
  159.     // worst fps
  160.     else if( fps < fps_worst )
  161.     {
  162.         fps_worst = fps;
  163.     }
  164.  
  165.     framedelay = currentticks;
  166. }
  167.  
  168. void cFramerate :: Reset( void )
  169. {
  170.     framedelay = SDL_GetTicks();
  171.     speedfactor = 0.1f;
  172.     fps_best = 0;
  173.     fps_worst = 100000;
  174.     fps_average = 0;
  175.  
  176.     // reset performance timer
  177.     for( Performance_Timer_List::iterator itr = perf_timer.begin(), itr_end = perf_timer.end(); itr != itr_end; ++itr )
  178.     {
  179.         (*itr)->Reset();
  180.     }
  181. }
  182.  
  183. void cFramerate :: Set_Max_Speed_Factor( float maximum )
  184. {
  185.     maxspeedfactor = maximum;
  186. }
  187.  
  188. void cFramerate :: Set_Fixed_Speedfacor( float val )
  189. {
  190.     force_speedfactor = val;
  191. }
  192.  
  193. void Correct_Frame_Time( unsigned int fps )
  194. {
  195.     static Uint32 stime = 0;
  196.     
  197.     while( SDL_GetTicks () - stime < 1000 / fps )
  198.     {
  199.         SDL_Delay( 1 );
  200.     }
  201.  
  202.     stime = SDL_GetTicks();
  203. }
  204.  
  205. /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
  206.  
  207. cFramerate *pFramerate = NULL;
  208.