Guest User

SpinningCube.cpp

a guest
Jan 8th, 2014
116
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.  
  7. // setup some basic data types
  8. typedef   signed long long s64;
  9. typedef unsigned long long u64;
  10. typedef unsigned int       u32;
  11. typedef   signed int       s32;
  12. typedef   signed short     s16;
  13. typedef unsigned char      byte;
  14. typedef   signed long long fp64;
  15.  
  16. // ---- ----- ---- ---- ---- ---- ---- ---- FRAMEWORK SPECIFICS
  17. namespace framework
  18. {
  19.     // the title name for this application
  20.     const char *app_name    = "Spinning Cube Demo";
  21.  
  22.     // size of the video buffer
  23.     const int vidSize       = 256;
  24.  
  25.     // pixel size
  26.     const int vidScale      = 2;
  27.  
  28.     // video buffer
  29.     u32 *video              = NULL;
  30.  
  31.     // number of pixels in the video buffer
  32.     const int nPixels       = vidSize * vidSize;
  33.  
  34.     // calculated real SDL video buffer size
  35.     const int scrRes        = vidSize * vidScale;
  36.  
  37.     // the real SDL video buffer
  38.     SDL_Surface *screen     = NULL;
  39.  
  40.     // rate onTick is called in FPS
  41.     const int tickFPS       = 45;
  42.  
  43.     // mouse position
  44.     int mousex              = 0;
  45.     int mousey              = 0;
  46.  
  47. }; // namespace framework
  48. using namespace framework;
  49.  
  50. // ---- ----- ---- ---- ---- ---- ---- ---- MATH HELPER FUNCTIONS
  51. namespace mathHelper
  52. {
  53.     static u32 randSeed = 0xBABEFACE;
  54.  
  55.     static s64 absi( s64 a )
  56.     {
  57.         if ( a < 0 ) return -a;
  58.         else         return  a;
  59.     }
  60.  
  61.     static s64 maxi( s64 a, s64 b )
  62.     {
  63.         if ( a > b ) return a;
  64.         else         return b;
  65.     }
  66.  
  67.     static s64 mini( s64 a, s64 b )
  68.     {
  69.         if ( a < b ) return a;
  70.         else         return b;
  71.     }
  72.  
  73.     inline u32 randi( void )
  74.     {
  75.         randSeed *= 1103515245;
  76.         randSeed += 12345;
  77.         return (randSeed >> 15) & 0xFFFF;
  78.     }
  79.  
  80.     inline u32 scale( u32 a, byte scale )
  81.     {
  82.         return (a * scale) >> 8;
  83.     }
  84.  
  85. }; // namespace mathHelper
  86. using namespace mathHelper;
  87.  
  88. // ---- ----- ---- ---- ---- ---- ---- ---- FIXED POINT HELPER FUNCTIONS
  89. namespace fixedPointHelper
  90. {
  91.     const fp64 fp_1 = 0x10000;
  92.  
  93.     fp64 fp_mul( fp64 a, fp64 b )
  94.     {
  95.         return (a * b) >> 16;
  96.     }
  97.  
  98.     fp64 fp_div( fp64 a, fp64 b )
  99.     {
  100.         return (a << 16) / b;
  101.     }
  102.  
  103.     fp64 fp_ceil( fp64 a )
  104.     {
  105.         return (a | 0xFFFF) + 1;
  106.     }
  107.  
  108.     fp64 fp_floor( fp64 a )
  109.     {
  110.         return a & (~0xFFFF);
  111.     }
  112.  
  113.     fp64 fp_fract( fp64 a )
  114.     {
  115.         return a & 0xFFFF;
  116.     }
  117.  
  118.     fp64 fp_ifract( fp64 a )
  119.     {
  120.         return 0xFFFF - (a & 0xFFFF);
  121.     }
  122.  
  123.     int fp_to_int( fp64 a )
  124.     {
  125.         return (int) (a >> 16);
  126.     }
  127.  
  128.     fp64 int_to_fp( int a )
  129.     {
  130.         return (a << 16);
  131.     }
  132.  
  133.     fp64 fp_rand( int max )
  134.     {
  135.         return ((randi() % max) << 16) | (randi() & 0xFFFF);
  136.     }
  137.  
  138. }; // namespace fixedPointHelper
  139. using namespace fixedPointHelper;
  140.  
  141. // ---- ----- ---- ---- ---- ---- ---- ---- DRAWING HELPER FUNCTIONS
  142. namespace videoHelper
  143. {
  144.     static u32 drawColour = 0xFFFFFF;
  145.  
  146.     inline void plot( int x, int y )
  147.     {
  148.         bool out  = x < 0;
  149.              out |= y < 0;
  150.              out |= x >= vidSize;
  151.              out |= y >= vidSize;
  152.         if ( out ) return;
  153.         video[ x + y * vidSize ] = drawColour;
  154.     }
  155.    
  156.     inline u32 readPixel( int x, int y )
  157.     {
  158.         bool out  = x < 0;
  159.              out |= y < 0;
  160.              out |= x >= vidSize;
  161.              out |= y >= vidSize;
  162.         if ( out ) return 0;
  163.         return video[ x + y * vidSize ];
  164.     }
  165.  
  166.     void circle( s32 x0, s32 y0, s32 radius )
  167.     {
  168.         s32 error  =  1 - radius;
  169.         s32 errorY =  1;
  170.         s32 errorX = -2 * radius;
  171.  
  172.         s32 x = radius, y = 0;
  173.  
  174.         plot(x0, y0 + radius);
  175.         plot(x0, y0 - radius);
  176.         plot(x0 + radius, y0);
  177.         plot(x0 - radius, y0);
  178.  
  179.         while(y < x)
  180.         {
  181.             if (error > 0)
  182.                 { x--; errorX += 2; error += errorX; }
  183.                 { y++; errorY += 2; error += errorY; }
  184.  
  185.             plot(x0 + x, y0 + y);
  186.             plot(x0 - x, y0 + y);
  187.             plot(x0 + x, y0 - y);
  188.             plot(x0 - x, y0 - y);
  189.             plot(x0 + y, y0 + x);
  190.             plot(x0 - y, y0 + x);
  191.             plot(x0 + y, y0 - x);
  192.             plot(x0 - y, y0 - x);
  193.         }
  194.     }
  195.  
  196.     void line( s32 X0, s32 Y0, s32 X1, s32 Y1 )
  197.     {
  198.         s32  incrementVal = 0;
  199.         s32  shortLen     = Y1 - Y0;
  200.         s32  longLen      = X1 - X0;
  201.         bool yLonger      = false;
  202.         s32  decInc       = 0;
  203.         s32  endVal       = 0;
  204.         s32  j            = 0;
  205.  
  206.         if ( absi( shortLen ) > absi( longLen ) )
  207.         {
  208.             int swap = shortLen;
  209.             shortLen = longLen;
  210.             longLen  = swap;
  211.             yLonger  = true;
  212.         }
  213.  
  214.         endVal = longLen;
  215.  
  216.         if ( longLen < 0 )
  217.         {
  218.             incrementVal = -1;
  219.             longLen      = -longLen;
  220.         }
  221.         else
  222.             incrementVal = 1;
  223.  
  224.         if ( longLen == 0 )
  225.             decInc = 0;
  226.         else
  227.             decInc = (shortLen << 16) / longLen;
  228.  
  229.         if ( yLonger )
  230.         {
  231.             for ( s32 i=0; i!=endVal; i+=incrementVal )
  232.             {
  233.                 plot( X0 + (j >> 16), Y0 + i );
  234.                 j += decInc;
  235.             }
  236.         }
  237.         else
  238.         {
  239.             for ( s32 i=0; i!=endVal; i+=incrementVal )
  240.             {
  241.                 plot( X0 + i, Y0 + (j >> 16) );
  242.                 j += decInc;
  243.             }
  244.         }
  245.     }
  246.  
  247. }; // namesapce videoHelper
  248. using namespace videoHelper;
  249.  
  250. // ---- ----- ---- ---- ---- ---- ---- ---- DEMO CODE ( the good stuff )
  251. namespace demo
  252. {  
  253.     struct sPoint
  254.     {
  255.         float x, y, z;
  256.  
  257.         void rotateX( float a )
  258.         {
  259.             float c  = cosf( a );
  260.             float s  = sinf( a );
  261.             float ty = y * c - z * s;
  262.                    z = y * s + z * c;
  263.                    y = ty;
  264.         }
  265.  
  266.         void rotateY( float a )
  267.         {
  268.             float c  = cosf( a );
  269.             float s  = sinf( a );
  270.             float tz = z * c - x * s;
  271.                    x = z * s + x * c;
  272.                    z = tz;
  273.         }
  274.  
  275.         void rotateZ( float a )
  276.         {
  277.             float c  = cosf( a );
  278.             float s  = sinf( a );
  279.             float tx = x * c - y * s;
  280.                    y = x * s + y * c;
  281.                    x = tx;
  282.         }
  283.  
  284.         void rotate( float x, float y, float z )
  285.         {
  286.             rotateX( x );
  287.             rotateY( y );
  288.             rotateZ( z );
  289.         }
  290.  
  291.         void project( float w, float h, float fov, float dist )
  292.         {
  293.             float factor = fov / (dist + z);
  294.             x = x * factor + (w * 0.5f);
  295.             y = y * factor + (h * 0.5f);
  296.         }
  297.  
  298.     };
  299.  
  300.     sPoint cube[8] =
  301.     {
  302.         {-1,-1, 1 }, { 1,-1, 1 }, {-1,-1,-1 }, { 1,-1,-1 },
  303.         {-1, 1, 1 }, { 1, 1, 1 }, {-1, 1,-1 }, { 1, 1,-1 }
  304.     };
  305.  
  306.     struct sTriangle
  307.     {
  308.         int i, j, k;
  309.     };
  310.  
  311.     sTriangle tri[12] =
  312.     {
  313.         { 0, 1, 2 }, { 1, 2, 3 },
  314.         { 4, 5, 6 }, { 5, 6, 7 },
  315.         { 0, 1, 4 }, { 1, 4, 5 },
  316.         { 0, 2, 4 }, { 2, 4, 6 },
  317.         { 2, 3, 6 }, { 3, 6, 7 },
  318.         { 1, 3, 5 }, { 3, 5, 7 },
  319.     };
  320.  
  321.     float rx = 0.0f;
  322.     float ry = 0.0f;
  323.     float rz = 0.0f;
  324.  
  325.     void onInit( void )
  326.     {
  327.         rx = 0.0f;
  328.         ry = 0.0f;
  329.         rz = 0.0f;
  330.     }
  331.  
  332.     void onKeyHit( SDLKey key )
  333.     {
  334.         switch ( key )
  335.         {
  336.         case ( SDLK_SPACE ):
  337.             onInit( );
  338.         }
  339.     }
  340.  
  341.     void incWrap( float &x, float y )
  342.     {
  343.         const float _2PI = 6.28318530718f;
  344.         if ( (x+=y) > _2PI ) x -= _2PI;
  345.     }
  346.  
  347.     void onTick( void )
  348.     {
  349.         for ( int i=0; i<nPixels; i++ )
  350.             video[ i ] = 0;
  351.  
  352.         // transformed cube
  353.         sPoint tcube[8];
  354.  
  355.         for ( int i=0; i<8; i++ )
  356.         {
  357.             tcube[i] = cube[i];
  358.             tcube[i].rotate( rx, ry, rz );
  359.             tcube[i].project( vidSize, vidSize, 128.0f, 3.0f );
  360.         }
  361.  
  362.         for ( int i=0; i<12; i++ )
  363.         {
  364.             sPoint &a = tcube[ tri[i].i ];
  365.             sPoint &b = tcube[ tri[i].j ];
  366.             sPoint &c = tcube[ tri[i].k ];
  367.  
  368.             line( a.x, a.y, b.x, b.y );
  369.             line( a.x, a.y, c.x, c.y );
  370.             line( b.x, b.y, c.x, c.y );
  371.         }
  372.  
  373.         incWrap( rx, 0.01111f );
  374.         incWrap( ry, 0.02123f );
  375.         incWrap( rz, 0.01313f );
  376.     }
  377.  
  378. }; // namespace demo
  379. using namespace demo;
  380.  
  381. // ---- ----- ---- ---- ---- ---- ---- ---- FRAMEWORK FUNCIONS
  382. namespace framework
  383. {
  384.     static bool app_init( void )
  385.     {
  386.         if ( SDL_Init( SDL_INIT_VIDEO ) != 0 )
  387.             return false;
  388.  
  389.         SDL_WM_SetCaption( app_name, NULL );
  390.  
  391.         screen = SDL_SetVideoMode( scrRes, scrRes, 32, 0 );
  392.         if ( screen == NULL )
  393.             return false;
  394.  
  395.         if ( vidScale == 1 )    video = (u32*)screen->pixels;
  396.         else                    video = new u32[ nPixels ];
  397.  
  398.         return true;
  399.     }
  400.  
  401.     static void blit_2x( void )
  402.     {
  403.         //
  404.         const int stride = screen->w;
  405.  
  406.         u32 *dst = (u32*) screen->pixels;
  407.  
  408.         int a = 0;
  409.  
  410.         for ( int i=0; i<nPixels; i++ )
  411.         {
  412.             u32 colour = video[ i ];
  413.            
  414.             // x4 pixel write
  415.             dst[0       ] = colour;
  416.             dst[1       ] = colour;
  417.             dst[  stride] = colour;
  418.             dst[1+stride] = colour;
  419.  
  420.             dst += 2;
  421.             if ( a++ >= vidSize )
  422.             {
  423.                 a = 0;
  424.                 // add on ONE stride not two since one length
  425.                 // has already been walked
  426.                 dst += stride;
  427.             }
  428.         }
  429.     }
  430.  
  431.     static void app_draw( void )
  432.     {
  433.         if ( vidScale <= 1 )
  434.             return;
  435.  
  436.         if ( vidScale == 2 )
  437.         {
  438.             blit_2x( );
  439.             return;
  440.         }
  441.  
  442.         for ( int i=0; i<nPixels; i++ )
  443.         {
  444.             SDL_Rect rect =
  445.             {
  446.                 (i % vidSize) * vidScale,
  447.                 (i / vidSize) * vidScale,
  448.                                 vidScale,
  449.                                 vidScale
  450.             };
  451.             SDL_FillRect( screen, &rect, video[ i ] );
  452.         }
  453.     }
  454.  
  455.     static bool app_tick( void )
  456.     {
  457.         static bool active = true;
  458.  
  459.         SDL_Event event;
  460.         while ( SDL_PollEvent( &event ) )
  461.         {
  462.             switch ( event.type )
  463.             {
  464.             case ( SDL_QUIT ):
  465.                 active = false;
  466.                 break;
  467.             case ( SDL_KEYUP ):
  468.                 {
  469.                     if ( event.key.keysym.sym == SDLK_ESCAPE )
  470.                         active = false;
  471.                     else
  472.                         onKeyHit( event.key.keysym.sym );
  473.                 }
  474.                 break;
  475.             }
  476.         }
  477.         return active;
  478.     }
  479.  
  480.     static void app_quit( void )
  481.     {
  482.         //
  483.         if ( video != NULL )
  484.             if ( video != screen->pixels )
  485.                 delete [] video;
  486.         video = NULL;
  487.         //
  488.         if ( screen != NULL )
  489.             SDL_FreeSurface( screen );
  490.         //
  491.         SDL_Quit( );
  492.     }
  493.  
  494. }; // namespace framework
  495.  
  496. // windows entry point
  497. int __stdcall WinMain( int, int, int, int )
  498. {
  499.     // start up SDL
  500.     atexit( app_quit );
  501.     if (! app_init( ) )
  502.         return 1;
  503.     // get keyboard access
  504.     u32 keyCount = 0;
  505.     byte *keys = SDL_GetKeyState( (int*) &keyCount );
  506.     // seed the random
  507.     randSeed ^= SDL_GetTicks( );
  508.     // call the on initialize function 
  509.     onInit( );
  510.     //
  511.     int oldTicks = SDL_GetTicks( );
  512.     // work out the tick threshold in milliseconds
  513.     const int tickThresh = 1000 / tickFPS;
  514.     //
  515.     while ( app_tick( ) )
  516.     {
  517.         int diff = SDL_GetTicks() - oldTicks;
  518.  
  519.         if ( diff < 10  )
  520.             SDL_Delay( 10 );
  521.  
  522.         if ( diff > 500 )
  523.         {
  524.             oldTicks += diff;
  525.             continue;
  526.         }
  527.  
  528.         while ( diff > tickThresh )
  529.         {
  530.             // grab the mouse state
  531.             SDL_GetMouseState( &mousex, &mousey );
  532.             // tick the application
  533.             onTick( );
  534.             app_draw( );
  535.             SDL_Flip( screen );
  536.             // progress the tick count
  537.             oldTicks += tickThresh;
  538.             diff     -= tickThresh;
  539.         }
  540.     }
  541.     return 0;
  542. }
RAW Paste Data