Guest User

Raytrace4.cpp

a guest
Jan 9th, 2014
15
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // include Simple Direct-media Layer
  2. #include <SDL/SDL.h>
  3. #pragma comment( lib, "SDL.lib" )
  4.  
  5. #include <math.h>
  6. #include <intrin.h>
  7.  
  8. // setup some basic data types
  9. typedef   signed long long s64;
  10. typedef unsigned long long u64;
  11. typedef unsigned int       u32;
  12. typedef   signed int       s32;
  13. typedef   signed short     s16;
  14. typedef unsigned char      byte;
  15. typedef   signed long long fp64;
  16.  
  17. // ---- ----- ---- ---- ---- ---- ---- ---- FRAMEWORK SPECIFICS
  18. namespace framework
  19. {
  20.     #define _threading
  21.  
  22.     // number of threads alive
  23.     volatile long threads = 0;
  24.  
  25.     // true while program is running
  26.     volatile bool active = true;
  27.  
  28.     // the title name for this application
  29.     const char *app_name    = "Raytrace Demo";
  30.  
  31.     // size of the video buffer
  32.     const int vidSize       = 728;
  33.  
  34.     // pixel size
  35.     const int vidScale      = 1;
  36.  
  37.     // video buffer
  38.     u32 *video              = NULL;
  39.      
  40.     // number of pixels in the video buffer
  41.     const int nPixels       = vidSize * vidSize;
  42.  
  43.     // calculated real SDL video buffer size
  44.     const int scrRes        = vidSize * vidScale;
  45.  
  46.     // the real SDL video buffer
  47.     SDL_Surface *screen     = NULL;
  48.  
  49.     // rate onTick is called in FPS
  50.     const int tickFPS       = 60;
  51.  
  52.     // mouse position
  53.     int mousex              = 0;
  54.     int mousey              = 0;
  55.  
  56. }; // namespace framework
  57. using namespace framework;
  58.  
  59. // ---- ----- ---- ---- ---- ---- ---- ---- MATH HELPER FUNCTIONS
  60. namespace mathHelper
  61. {
  62.     static u32 randSeed = 0xBABEFACE;
  63.  
  64.     static s64 absi( s64 a )
  65.     {
  66.         if ( a < 0 ) return -a;
  67.         else         return  a;
  68.     }
  69.  
  70.     static s64 maxi( s64 a, s64 b )
  71.     {
  72.         if ( a > b ) return a;
  73.         else         return b;
  74.     }
  75.  
  76.     static s64 mini( s64 a, s64 b )
  77.     {
  78.         if ( a < b ) return a;
  79.         else         return b;
  80.     }
  81.  
  82.     inline u32 randi( void )
  83.     {
  84.         randSeed *= 1103515245;
  85.         randSeed += 12345;
  86.         return (randSeed >> 15) & 0xFFFF;
  87.     }
  88.  
  89.     inline u32 scale( u32 a, byte scale )
  90.     {
  91.         return (a * scale) >> 8;
  92.     }
  93.  
  94. }; // namespace mathHelper
  95. using namespace mathHelper;
  96.  
  97. // ---- ----- ---- ---- ---- ---- ---- ---- FIXED POINT HELPER FUNCTIONS
  98. namespace fixedPointHelper
  99. {
  100.     const fp64 fp_1 = 0x10000;
  101.  
  102.     fp64 fp_mul( fp64 a, fp64 b )
  103.     {
  104.         return (a * b) >> 16;
  105.     }
  106.  
  107.     fp64 fp_div( fp64 a, fp64 b )
  108.     {
  109.         return (a << 16) / b;
  110.     }
  111.  
  112.     fp64 fp_ceil( fp64 a )
  113.     {
  114.         return (a | 0xFFFF) + 1;
  115.     }
  116.  
  117.     fp64 fp_floor( fp64 a )
  118.     {
  119.         return a & (~0xFFFF);
  120.     }
  121.  
  122.     fp64 fp_fract( fp64 a )
  123.     {
  124.         return a & 0xFFFF;
  125.     }
  126.  
  127.     fp64 fp_ifract( fp64 a )
  128.     {
  129.         return 0xFFFF - (a & 0xFFFF);
  130.     }
  131.  
  132.     int fp_to_int( fp64 a )
  133.     {
  134.         return (int) (a >> 16);
  135.     }
  136.  
  137.     fp64 int_to_fp( int a )
  138.     {
  139.         return (a << 16);
  140.     }
  141.  
  142.     fp64 fp_rand( int max )
  143.     {
  144.         return ((randi() % max) << 16) | (randi() & 0xFFFF);
  145.     }
  146.  
  147. }; // namespace fixedPointHelper
  148. using namespace fixedPointHelper;
  149.  
  150. // ---- ----- ---- ---- ---- ---- ---- ---- DRAWING HELPER FUNCTIONS
  151. namespace videoHelper
  152. {
  153.     static u32 drawColour = 0xFFFFFF;
  154.  
  155.     inline void plot( int x, int y )
  156.     {
  157.         bool out  = x < 0;
  158.              out |= y < 0;
  159.              out |= x >= vidSize;
  160.              out |= y >= vidSize;
  161.         if ( out ) return;
  162.         video[ x + y * vidSize ] = drawColour;
  163.     }
  164.    
  165.     inline u32 readPixel( int x, int y )
  166.     {
  167.         bool out  = x < 0;
  168.              out |= y < 0;
  169.              out |= x >= vidSize;
  170.              out |= y >= vidSize;
  171.         if ( out ) return 0;
  172.         return video[ x + y * vidSize ];
  173.     }
  174.  
  175.     void circle( s32 x0, s32 y0, s32 radius )
  176.     {
  177.         s32 error  =  1 - radius;
  178.         s32 errorY =  1;
  179.         s32 errorX = -2 * radius;
  180.  
  181.         s32 x = radius, y = 0;
  182.  
  183.         plot(x0, y0 + radius);
  184.         plot(x0, y0 - radius);
  185.         plot(x0 + radius, y0);
  186.         plot(x0 - radius, y0);
  187.  
  188.         while(y < x)
  189.         {
  190.             if (error > 0)
  191.                 { x--; errorX += 2; error += errorX; }
  192.                 { y++; errorY += 2; error += errorY; }
  193.  
  194.             plot(x0 + x, y0 + y);
  195.             plot(x0 - x, y0 + y);
  196.             plot(x0 + x, y0 - y);
  197.             plot(x0 - x, y0 - y);
  198.             plot(x0 + y, y0 + x);
  199.             plot(x0 - y, y0 + x);
  200.             plot(x0 + y, y0 - x);
  201.             plot(x0 - y, y0 - x);
  202.         }
  203.     }
  204.  
  205.     void line( s32 X0, s32 Y0, s32 X1, s32 Y1 )
  206.     {
  207.         s32  incrementVal = 0;
  208.         s32  shortLen     = Y1 - Y0;
  209.         s32  longLen      = X1 - X0;
  210.         bool yLonger      = false;
  211.         s32  decInc       = 0;
  212.         s32  endVal       = 0;
  213.         s32  j            = 0;
  214.  
  215.         if ( absi( shortLen ) > absi( longLen ) )
  216.         {
  217.             int swap = shortLen;
  218.             shortLen = longLen;
  219.             longLen  = swap;
  220.             yLonger  = true;
  221.         }
  222.  
  223.         endVal = longLen;
  224.  
  225.         if ( longLen < 0 )
  226.         {
  227.             incrementVal = -1;
  228.             longLen      = -longLen;
  229.         }
  230.         else
  231.             incrementVal = 1;
  232.  
  233.         if ( longLen == 0 )
  234.             decInc = 0;
  235.         else
  236.             decInc = (shortLen << 16) / longLen;
  237.  
  238.         if ( yLonger )
  239.         {
  240.             for ( s32 i=0; i!=endVal; i+=incrementVal )
  241.             {
  242.                 plot( X0 + (j >> 16), Y0 + i );
  243.                 j += decInc;
  244.             }
  245.         }
  246.         else
  247.         {
  248.             for ( s32 i=0; i!=endVal; i+=incrementVal )
  249.             {
  250.                 plot( X0 + i, Y0 + (j >> 16) );
  251.                 j += decInc;
  252.             }
  253.         }
  254.     }
  255.  
  256.     u32 randColour( void )
  257.     {
  258.         return ((randi()&0xFF) << 16 ) | ((randi()&0xFF) << 8 ) | ((randi()&0xFF) );
  259.     }
  260.  
  261. }; // namesapce videoHelper
  262. using namespace videoHelper;
  263.  
  264. // ---- ----- ---- ---- ---- ---- ---- ---- DEMO CODE ( the good stuff )
  265. namespace demo
  266. {  
  267.     inline float isqrtf( float number )
  268.     {
  269.         long i;
  270.         float x2, y;
  271.         const float threehalfs = 1.5F;
  272.  
  273.         x2 = number * 0.5F;
  274.         y  = number;
  275.         i  = * ( long * ) &y;                       // evil floating point bit level hacking
  276.         i  = 0x5f3759df - ( i >> 1 );               // what the fuck?
  277.         y  = * ( float * ) &i;
  278.         y  = y * ( threehalfs - ( x2 * y * y ) );   // 1st iteration
  279.         y  = y * ( threehalfs - ( x2 * y * y ) );   // 2nd iteration, this can be removed
  280.         return y;
  281.     }
  282.  
  283.     struct vec3
  284.     {
  285.         float x, y, z;
  286.  
  287.         vec3( )
  288.             : x( 0 ), y( 0 ), z( 0 )
  289.         {
  290.         }
  291.  
  292.         vec3( float _tx, float _ty, float _tz )
  293.             : x( _tx ), y( _ty ), z( _tz )
  294.         {
  295.         }
  296.  
  297.         void fnorm( void )
  298.         {
  299.             float d = isqrtf( x*x + y*y + z*z );
  300.             x *= d;
  301.             y *= d;
  302.             z *= d;
  303.         }
  304. /*
  305.         void norm( void )
  306.         {
  307.             float d = 1.0f / sqrtf( x*x + y*y + z*z );
  308.             x *= d;
  309.             y *= d;
  310.             z *= d;
  311.         }
  312.  */
  313.  
  314.         vec3 project( vec3 &a )
  315.         {
  316.             return (*this) * ((a * (*this)) / length( ));
  317.         }
  318.  
  319.         vec3 operator - ( const vec3 &a ) const
  320.         {
  321.             return vec3( x - a.x, y - a.y, z - a.z );
  322.         }
  323.  
  324.         vec3 operator + ( const vec3 &a ) const
  325.         {
  326.             return vec3( x + a.x, y + a.y, z + a.z );
  327.         }
  328.  
  329.         float operator * ( const vec3 &a )
  330.         {
  331.             return x*a.x + y*a.y + z*a.z;
  332.         }
  333.  
  334.         vec3 operator * ( const float s )
  335.         {
  336.             return vec3( x*s, y*s, z*s );
  337.         }
  338.  
  339.         float length( void )
  340.         {
  341.             return sqrt( lengthSqr() );
  342.         }
  343.  
  344.         float lengthSqr( void )
  345.         {
  346.             return x*x + y*y + z*z;
  347.         }
  348.  
  349.         static vec3 findNormal( const vec3 &s, const vec3 &d )
  350.         {
  351.             vec3 n = d - s;
  352.             n.fnorm( );
  353.             return n;
  354.         }
  355.  
  356.         static float lengthSqr( const vec3 &s, const vec3 &d )
  357.         {
  358.             return (d.x-s.x)*(d.x-s.x) + (d.y-s.y)*(d.y-s.y) + (d.z-s.z)*(d.z-s.z);
  359.         }
  360.  
  361.     };
  362.  
  363.     struct sSphere
  364.     {
  365.         sSphere( )
  366.             : origin( 0, 0, 0 ), radius( 0 )
  367.         {
  368.         }
  369.  
  370.         sSphere( vec3 &center, float r )
  371.             : origin( center ), radius( r )
  372.         {
  373.         }
  374.  
  375.         sSphere( vec3 &center, float r, u32 c )
  376.             : origin( center ), radius( r ), colour( c )
  377.         {
  378.         }
  379.  
  380.         vec3   origin;
  381.         float radius;
  382.         u32    colour;
  383.     };
  384.  
  385.     struct sPlane
  386.     {
  387.         vec3  normal;
  388.         float offset;
  389.         u32   colour;
  390.     };
  391.  
  392.     struct sRay
  393.     {  
  394.         sRay( )
  395.         {
  396.         }
  397.  
  398.         sRay( vec3 &a )
  399.             : origin( ), normal( a )
  400.         {
  401.         }
  402.  
  403.         sRay( vec3 &a, vec3 &b )
  404.         {
  405.             origin = a;
  406.             normal = b - a;
  407.             normal.fnorm( );
  408.         }
  409.  
  410.         vec3 origin;
  411.         vec3 normal;
  412.     };
  413.  
  414.     //
  415.     // precise ray intersection test
  416.     //
  417.     bool intersect( sRay &ray, sSphere &sphere, vec3 &ipoint )
  418.     {
  419.         float t1 = -1;
  420.         float t2 = -1;
  421.         float discriminant;
  422.         float t = -1;
  423.         //temporary == e-c
  424.         vec3 temp = ray.origin - sphere.origin;
  425.         float b = 2 * (ray.normal * temp);
  426.         float a = ray.normal * ray.normal;
  427.         float c = temp * temp - (sphere.radius * sphere.radius);
  428.         float disc;
  429.         disc = b*b - 4*a*c;
  430.         if ( disc < 0 )
  431.             return false;
  432.         else
  433.         {
  434.             discriminant = 1.0f / isqrtf( disc );
  435.             t1 = (-b+discriminant)/(2*a);
  436.             t2 = (-b-discriminant)/(2*a);  
  437.  
  438.             if (t2 > 0)
  439.             {
  440.                 ipoint = ray.origin + ray.normal * t2;
  441.                 return true;
  442.             }
  443.             if ( t1 > 0 )
  444.             {
  445.                 ipoint = ray.origin + ray.normal * t1;
  446.                 return true;
  447.             }
  448.         }
  449.         return false;
  450.     }
  451.    
  452.     bool intersect( sRay &ray, sPlane &plane, vec3 &ipoint )
  453.     {
  454.         float t = - ( ray.origin * plane.normal + plane.offset ) / ( ray.normal * plane.normal );
  455.         ipoint = ray.origin + ray.normal * t;
  456.         return (t > 0);
  457.     }
  458.    
  459.     const int nSpheres = 3;
  460.  
  461.     sSphere spheres[ nSpheres ] =
  462.     {
  463.         sSphere( vec3(   0, 128.f - 128.f, 420        ), 32.f, randColour( ) ),
  464.         sSphere( vec3( -64, 128.f -  48.f, 512.f-64.f ), 64.f, randColour( ) ),
  465.         sSphere( vec3(  32, 128.f -  32.f, 360        ), 32.f, randColour( ) )
  466.     };
  467.  
  468.     sPlane planes[] =
  469.     {
  470.         { vec3( 0,-1, 0), 128.0f, 0xC0D0E0 },
  471.         { vec3( 0, 1, 0), 128.0f, 0xC0D0E0 },
  472.         { vec3( 0, 0,-1), 512.0f, 0xC0D0E0 },
  473.         { vec3( 1, 0, 0), 128.0f, 0xFF7070 },
  474.         { vec3(-1, 0, 0), 128.0f, 0x70FF70 }
  475.     };
  476.    
  477.     vec3 light( 0,-120, 256+128 );
  478.    
  479.     bool useShadows = true;
  480.  
  481.     void rayShoot( sRay &ray, vec3 &xpoint, vec3 &normal, u32 &colour, float &min )
  482.     {
  483.         min = 99999999.f;
  484.         vec3  ipoint;
  485.  
  486.         // sphere intersections
  487.         for ( int i=0; i<nSpheres; i++ )
  488.         {
  489.             sSphere &sphere = spheres[ i ];
  490.             if ( intersect( ray, sphere, ipoint ) )
  491.             {
  492.                 float dst = (ipoint-ray.origin).lengthSqr( );
  493.                 if ( dst < min /*|| min < 0.0f*/ )
  494.                 {
  495.                     xpoint      = ipoint;
  496.                     float irad  = 1.0f / sphere.radius;
  497.                     min         = dst;
  498.                     normal      = (ipoint - sphere.origin);
  499.                     normal.x   *= irad;
  500.                     normal.y   *= irad;
  501.                     normal.z   *= irad;
  502.                     colour      = sphere.colour;
  503.                 }
  504.             }
  505.         }
  506.  
  507.         // plane intersections
  508.         for ( int i=0; i<5; i++ )
  509.         {
  510.             sPlane &plane = planes[i];
  511.             if ( intersect( ray, plane, ipoint ) )
  512.             {
  513.                 float dst = (ipoint-ray.origin).lengthSqr( );
  514.                 if ( dst < min /*|| min < 0.0f*/ )
  515.                 {
  516.                     xpoint = ipoint;
  517.                     min    = dst;
  518.                     normal = plane.normal;
  519.                     colour = plane.colour;
  520.                 }
  521.             }
  522.         }
  523.  
  524.     }
  525.  
  526.     void incWrap( float &x, float y )
  527.     {
  528.         const float _2PI = 6.28318530718f;
  529.         if ( (x+=y) > _2PI ) x -= _2PI;
  530.     }
  531.  
  532.     int renderRegion( void *arg )
  533.     {
  534. #ifdef _threading
  535.         _InterlockedIncrement( &threads );
  536. #endif
  537.         float hvs = vidSize / 2.0;
  538.  
  539.         SDL_Rect *rect = (SDL_Rect*)arg;
  540.  
  541.         int x1 = rect->x;
  542.         int x2 = rect->x + rect->w;
  543.         int y1 = rect->y;
  544.         int y2 = rect->y + rect->h;
  545.        
  546. #ifdef _threading
  547.         while ( active )
  548.         {
  549. #endif
  550.             for ( int y=y1; y<y2; y++ )
  551.             {
  552.                 for ( int x=x1; x<x2; x++ )
  553.                 {
  554.                     sRay ray( vec3( x-hvs, y-hvs, hvs*2 ) );
  555.                     ray.normal.fnorm( );
  556.  
  557.                     vec3  ipoint;
  558.                     vec3  normal;
  559.                     float dist;
  560.  
  561.                     rayShoot( ray, ipoint, normal, drawColour, dist );
  562.  
  563.                     //
  564.                     // dot product lighting
  565.                     //
  566.                     vec3 lightNorm = vec3::findNormal( ipoint, light );
  567.                     float dplight = normal * lightNorm;
  568.                     if (  dplight < 0.0f )
  569.                           dplight = 0.0f;
  570.                     u32 dp3 = (u32)( dplight * 255 );
  571.                     drawColour = dp3 | (dp3 << 8) | (dp3 << 16);
  572.  
  573.                     //
  574.                     // shadows
  575.                     //
  576.  
  577.                     // distance from intersection point to light
  578.                     float ldist = vec3::lengthSqr( ipoint, light );
  579.  
  580.                     // trace from light to interection point
  581.                     sRay lightRay( light, ipoint );
  582.                     u32   colour = 0;
  583.                     float mdist  = 0;
  584.                     rayShoot( lightRay, vec3(), vec3(), colour, mdist );
  585.                                
  586.                     if ( useShadows )
  587.                     {
  588.                         if ( ldist-1 > mdist )
  589.                             drawColour = 0; //(drawColour>>1) & 0x7f7f7f;
  590.                     }
  591.  
  592.                     plot( x, y );
  593.                 }
  594.             }
  595. #ifdef _threading
  596.         } // while ( active )
  597. #endif
  598.  
  599. #ifdef _threading
  600.         _InterlockedDecrement( &threads );
  601. #endif
  602.         return 1;
  603.     }
  604.  
  605.     void onTick( void )
  606.     {
  607.         static float t=0.0f; incWrap( t, 0.012346f );
  608.         spheres[0].origin.x = sin( (float)t ) * 64.f;
  609.  
  610. #ifndef _threading
  611.         SDL_Rect r1 = { 0  ,   0, vidSize, vidSize };
  612.         renderRegion( &r1 );
  613. #endif
  614.  
  615.         static float g=0.0f; incWrap( g, 0.024243f );
  616.         light.x = sin( g ) * 64;
  617.         light.z = cos( g ) * 64 + (256+128);
  618.     }
  619.  
  620.     void onInit( void )
  621.     {
  622. #ifdef _threading
  623.         float hvs = vidSize / 2.0;
  624.         SDL_Rect r1 = {     0  ,   0, hvs, hvs };
  625.         SDL_Rect r3 = {     hvs,   0, hvs, hvs };
  626.        
  627.         SDL_Rect r5 = {     0  , hvs, hvs, hvs };
  628.         SDL_Rect r7 = {     hvs, hvs, hvs, hvs };
  629.  
  630.         SDL_CreateThread( renderRegion, &r1 );
  631.         SDL_CreateThread( renderRegion, &r3 );
  632.  
  633.         SDL_CreateThread( renderRegion, &r5 );
  634.         SDL_CreateThread( renderRegion, &r7 );
  635. #endif
  636.     }
  637.  
  638.     void onKeyHit( SDLKey key )
  639.     {
  640.         switch ( key )
  641.         {
  642.         case ( SDLK_SPACE ):
  643.             useShadows = !useShadows;
  644.         }
  645.     }
  646.  
  647. }; // namespace demo
  648. using namespace demo;
  649.  
  650. // ---- ----- ---- ---- ---- ---- ---- ---- FRAMEWORK FUNCIONS
  651. namespace framework
  652. {
  653.     static bool app_init( void )
  654.     {
  655.         if ( SDL_Init( SDL_INIT_VIDEO ) != 0 )
  656.             return false;
  657.  
  658.         SDL_WM_SetCaption( app_name, NULL );
  659.  
  660.         screen = SDL_SetVideoMode( scrRes, scrRes, 32, 0 );
  661.         if ( screen == NULL )
  662.             return false;
  663.  
  664.         if ( vidScale == 1 )    video = (u32*)screen->pixels;
  665.         else                    video = new u32[ nPixels ];
  666.  
  667.         return true;
  668.     }
  669.  
  670.     static void blit_2x( void )
  671.     {
  672.         //
  673.         const int stride = screen->w;
  674.  
  675.         u32 *dst = (u32*) screen->pixels;
  676.  
  677.         int a = 0;
  678.  
  679.         for ( int i=0; i<nPixels; i++ )
  680.         {
  681.             u32 colour = video[ i ];
  682.            
  683.             // x4 pixel write
  684.             dst[0       ] = colour;
  685.             dst[1       ] = colour;
  686.             dst[  stride] = colour;
  687.             dst[1+stride] = colour;
  688.  
  689.             dst += 2;
  690.             if ( a++ >= vidSize )
  691.             {
  692.                 a = 0;
  693.                 // add on ONE stride not two since one length
  694.                 // has already been walked
  695.                 dst += stride;
  696.             }
  697.         }
  698.     }
  699.  
  700.     static void app_draw( void )
  701.     {
  702.         if ( vidScale <= 1 )
  703.             return;
  704.  
  705.         if ( vidScale == 2 )
  706.         {
  707.             blit_2x( );
  708.             return;
  709.         }
  710.  
  711.         for ( int i=0; i<nPixels; i++ )
  712.         {
  713.             SDL_Rect rect =
  714.             {
  715.                 (i % vidSize) * vidScale,
  716.                 (i / vidSize) * vidScale,
  717.                                 vidScale,
  718.                                 vidScale
  719.             };
  720.             SDL_FillRect( screen, &rect, video[ i ] );
  721.         }
  722.     }
  723.  
  724.     static bool app_tick( void )
  725.     {
  726.         SDL_Event event;
  727.         while ( SDL_PollEvent( &event ) )
  728.         {
  729.             switch ( event.type )
  730.             {
  731.             case ( SDL_QUIT ):
  732.                 active = false;
  733.                 break;
  734.             case ( SDL_KEYUP ):
  735.                 {
  736.                     if ( event.key.keysym.sym == SDLK_ESCAPE )
  737.                     {
  738.                         active = false;
  739.                     }
  740.                     else
  741.                         onKeyHit( event.key.keysym.sym );
  742.                 }
  743.                 break;
  744.             }
  745.         }
  746.         return active;
  747.     }
  748.  
  749.     static void app_quit( void )
  750.     {
  751.         //
  752.         if ( video != NULL )
  753.             if ( video != screen->pixels )
  754.                 delete [] video;
  755.         video = NULL;
  756.         //
  757.         if ( screen != NULL )
  758.             SDL_FreeSurface( screen );
  759.         //
  760.         SDL_Quit( );
  761.     }
  762.  
  763. }; // namespace framework
  764.  
  765. // windows entry point
  766. int __stdcall WinMain( int, int, int, int )
  767. {
  768.     // start up SDL
  769.     atexit( app_quit );
  770.     if (! app_init( ) )
  771.         return 1;
  772.     // get keyboard access
  773.     u32 keyCount = 0;
  774.     byte *keys = SDL_GetKeyState( (int*) &keyCount );
  775.     // seed the random
  776.     randSeed ^= SDL_GetTicks( );
  777.     // call the on initialize function 
  778.     onInit( );
  779.     //
  780.     int oldTicks = SDL_GetTicks( );
  781.     // work out the tick threshold in milliseconds
  782.     const int tickThresh = 1000 / tickFPS;
  783.     //
  784.     while ( app_tick( ) )
  785.     {
  786.         int diff = SDL_GetTicks() - oldTicks;
  787.  
  788.         if ( diff < 10  )
  789.             SDL_Delay( 10 );
  790.  
  791.         if ( diff > 500 )
  792.         {
  793.             oldTicks += diff;
  794.             continue;
  795.         }
  796.  
  797.         while ( diff > tickThresh )
  798.         {
  799.             // grab the mouse state
  800.             SDL_GetMouseState( &mousex, &mousey );
  801.             // tick the application
  802.             onTick( );
  803.             app_draw( );
  804.             SDL_Flip( screen );
  805.             // progress the tick count
  806.             oldTicks += tickThresh;
  807.             diff     -= tickThresh;
  808.         }
  809.     }
  810.  
  811.     //
  812.     while ( threads > 0 )
  813.         SDL_Delay( 100 );
  814.  
  815.     return 0;
  816. }
RAW Paste Data