home *** CD-ROM | disk | FTP | other *** search
/ RISCWORLD 7 / RISCWORLD_VOL7.iso / Software / Issue4 / SDL / gcc346 / rwsdlex2 / c / main
Encoding:
Text File  |  2006-11-13  |  13.4 KB  |  414 lines

  1.  
  2. // main.c part of a RISC OS SDL tutorial by Neil White
  3. // This tells the conmpiler we will be using the SDL suite of libraries
  4. #include <SDL/SDL.h>
  5. #include <SDL/SDL_gfxPrimitives.h>
  6. #include <SDL/SDL_rotozoom.h>
  7. #include <SDL/SDL_image.h>
  8. #include <SDL/SDL_mixer.h>
  9. // This includes the C standard library, for basic maths i/o functions etc.
  10. #include <stdlib.h>
  11. // This Includes string.h which has basic string functions.
  12. #include <string.h>
  13. // This includes the header file containing the backgrnd xpm
  14. #include "xpmgfx.h"
  15. // All images, including the actual screen area are defined as surfaces, here we define a poinetr to 'screen' which we will use as the main windows image. All other images are plotted to this s   urface to be displayed on screen.
  16. SDL_Surface *screen;
  17. // This sets aside a surface for where we will keep the Risc World logo. And a surface we can use for the background.
  18. SDL_Surface *background;
  19. SDL_Surface *rwlogo;
  20. // This sets the variable we will use to get mouse events.
  21. SDL_MouseMotionEvent mmevent;
  22. // int defines an integer, here for the x and y positions of the mouse.
  23. int mousex,mousey;
  24. // ints to represent key presses
  25. int up_pressed,down_pressed,left_pressed,down_pressed;
  26. // This defines unsigned 32 bit integers needed, in this case 'secs' and 'cents' for holding information about time for control of the speed of the program.
  27. Uint32 sec, cents;
  28. // This sets a pointer we can use for collecting data from a file on disk.
  29. FILE *file_ptr;
  30. // Some more integers, in this case if we set quit to 1 the code will quit, bounce factor is how much the logo will move, rwx and rwy are the coordinates of the logo and bouncing is used to tell the program if the logo is bouncing or not.
  31. int quit = 0,bouncefactor=0,rwy=60,rwx=60,bouncing=0;
  32.  
  33. // This function is used when we want to plot an image to the screen surface SDL_Surface (in this function called image) is the image we are sending to the function, x and y are the co-ordinates we sent to the function.
  34.  
  35. void imageplot(SDL_Surface *image, int x, int y)
  36. {
  37. // An SDL_Rect holds the width height and x,y positions of a rectangle, here we define a SDL rectangle called pos.
  38.     SDL_Rect pos;
  39. // Set the x and y value of the rectangle to the x and y value sent to the function
  40.     pos.x = x;
  41.     pos.y = y ;
  42. // Now we blit (plot) the surface image into the screen surface at the x and y positions we sent to the function
  43.     SDL_BlitSurface(image, NULL, screen, &pos);
  44. // Note- all SDL co-ordinates origin from the top left of the surface
  45. }
  46.  
  47. // This funtion will load the images we want when called
  48. SDL_Surface *loadimage(char *name)
  49. {
  50. // Define some surfaces for use within this function
  51.     SDL_Surface *surface;
  52.     SDL_Surface *image;
  53. // Define a string to hold the location of the file we want to load
  54.     char path[256];
  55. // In the Makefile we defined DATA_PREFIX as <rwsdlex1$dir>/ this line makes that the start opf our files location
  56.     strcpy(path, DATA_PREFIX);
  57. // Now we add gfx/, the directory the images are stored
  58.     strcat(path, "gfx/");
  59. // Here we add the name of the file that was sent to the function
  60.     strcat(path, name);
  61. // Load the image into a surface
  62.     surface = IMG_Load(path);
  63. // this is a little error trap for if we cant find the file.
  64.     if (surface == NULL)
  65.     {
  66.         fprintf(stderr, "Can't load image %s", path);
  67.         return NULL;
  68.     }
  69. // this tells SDL what colour to treat as transparent.
  70.     SDL_SetColorKey(surface, SDL_SRCCOLORKEY, SDL_MapRGB(surface->format, 255,255,255));
  71. // now we have set the transparency colour as white, we send the new image to another temporary surface.
  72.     image = SDL_DisplayFormat(surface);
  73. // free up some  memory it is a good idea to use lots of error traps and make sure all memory is accounted for.
  74.     SDL_FreeSurface(surface);
  75. // now we return our loaded image to the surface we used the function for.
  76.     return image;
  77. }
  78. // A function to load xpm's into a surface
  79. SDL_Surface *loadxpm(char **xpm)
  80. {
  81. // two surfaces for working withing the function
  82.         SDL_Surface *surface;
  83.         SDL_Surface *image;
  84. // the command to retrive the xpm from the included header file
  85.         surface = IMG_ReadXPMFromArray(xpm);
  86. // set the transparancey colour
  87.     SDL_SetColorKey(surface, SDL_SRCCOLORKEY, SDL_MapRGB(surface->format,255,255,255));
  88.     image = SDL_DisplayFormat(surface);
  89.     SDL_FreeSurface(surface);
  90.  
  91.     return image;
  92. }
  93.  
  94. // This function is used to load all the images we want using the loadimage function above.
  95. static int loadimages()
  96. {
  97.  
  98.         rwlogo = loadimage( "rwlogo.png" );
  99.         background     = loadxpm( background_xpm );
  100. // by returing 1 we can tell if the function as worked or not.
  101.     return 1;
  102. }
  103. // load the sound systems and sound
  104. /*
  105. static void initandloadsounds()
  106. {
  107.  
  108.     // choose the sample rate stereo and buffers
  109.     Mix_OpenAudio(22050, AUDIO_S16, 2, 2048);
  110.  
  111.     // string for filename
  112.     char path[256];
  113.  
  114.     // create <riscworldex2$dir>.sounds.noise/wav
  115.     strcpy(path, DATA_PREFIX "sounds/noise.wav");
  116.  
  117.     // load the sound into a mix chunk
  118.     noise_sound = Mix_LoadWAV_RW(SDL_RWFromFile(path, "rb"), 1);
  119.  
  120.   // nothing to return end of function
  121. }
  122. */
  123. // a function used for checking events, called checkkeys, but at this stage it only contains code for detecting mouse events.
  124. static void checkkeys(void)
  125. {
  126. // define the approprate variable type to hold event information.
  127.     SDL_Event event;
  128. // this is a polling loop
  129.     while (SDL_PollEvent(&event) != 0)
  130.     {
  131. // ask SDL if the mouse button has been pressed, if it has, set the bouncefactor to 8, which will start the logo bouncing.
  132.       if(SDL_GetMouseState(NULL,NULL)&SDL_BUTTON(1)){bouncefactor=8;}
  133.         switch(event.type)
  134.         {
  135. // SDL_QUIT is if either the x on the window has been clicked or escape has been pressed, if this happens we set quit to 1 and the code will quit.
  136.         case SDL_QUIT:
  137.             SDL_Quit();
  138. // This breaks from the loop so we can quit.
  139.             break;
  140.         }
  141.     }
  142. }
  143.  
  144.  
  145. // the next two functions are taken from the rotozoom test program
  146.  
  147. void ClearScreen(SDL_Surface *screen)
  148. {
  149.     int i;
  150.     /* Set the screen to black */
  151.     if ( SDL_LockSurface(screen) == 0 ) {
  152.         Uint8 *pixels;
  153.         pixels = (Uint8 *)screen->pixels;
  154.         for ( i=0; i<screen->h; ++i ) {
  155.             memset(pixels, 0,
  156.                 screen->w*screen->format->BytesPerPixel);
  157.             pixels += screen->pitch;
  158.         }
  159.         SDL_UnlockSurface(screen);
  160.     }
  161. }
  162.  
  163.  
  164.  
  165. void RotatePicture (SDL_Surface *screen, SDL_Surface *picture, int rotate, int flip, int smooth)
  166. {
  167.  
  168.     SDL_Surface *rotozoom_picture;
  169.     SDL_Rect dest;
  170.     int framecount, framemax, frameinc;
  171.     float angle, zoomf, zoomfx, zoomfy;
  172.  
  173.     /* Rotate and display the picture */
  174.     framemax=4*360; frameinc=1;
  175.     for (framecount=360; framecount<framemax; framecount += frameinc) {
  176.         if ((framecount % 360)==0) frameinc++;
  177.           checkkeys();
  178.         ClearScreen(screen);
  179.                 zoomf=(float)framecount/(float)framemax;
  180.                 zoomf=1.5*zoomf*zoomf;
  181.                 /* Are we in flipping mode? */
  182.         if (flip) {
  183.          /* Flip X factor */
  184.                  if (flip & 1) {
  185.                   zoomfx=-zoomf;
  186.                  } else {
  187.                   zoomfx=zoomf;
  188.                  }
  189.                  /* Flip Y factor */
  190.                  if (flip & 2) {
  191.                   zoomfy=-zoomf;
  192.                  } else {
  193.                   zoomfy=zoomf;
  194.                  }
  195.                  angle=framecount*rotate;
  196.                  if ((framecount % 120)==0) {
  197.                  }
  198.          if ((rotozoom_picture=rotozoomSurfaceXY (picture, angle, zoomfx, zoomfy, smooth))!=NULL) {
  199.             dest.x = (screen->w - rotozoom_picture->w)/2;;
  200.             dest.y = (screen->h - rotozoom_picture->h)/2;
  201.             dest.w = rotozoom_picture->w;
  202.             dest.h = rotozoom_picture->h;
  203.             if ( SDL_BlitSurface(rotozoom_picture, NULL, screen, &dest) < 0 ) {
  204.                 fprintf(stderr, "Blit failed: %s\n", SDL_GetError());
  205.                 break;
  206.             }
  207.             SDL_FreeSurface(rotozoom_picture);
  208.          }
  209.         } else {
  210.                  angle=framecount*rotate;
  211.                  if ((framecount % 120)==0) {
  212.                  }
  213.          if ((rotozoom_picture=rotozoomSurface (picture, angle, zoomf, smooth))!=NULL) {
  214.             dest.x = (screen->w - rotozoom_picture->w)/2;;
  215.             dest.y = (screen->h - rotozoom_picture->h)/2;
  216.             dest.w = rotozoom_picture->w;
  217.             dest.h = rotozoom_picture->h;
  218.             if ( SDL_BlitSurface(rotozoom_picture, NULL, screen, &dest) < 0 ) {
  219.                 fprintf(stderr, "Blit failed: %s\n", SDL_GetError());
  220.                 break;
  221.             }
  222.             SDL_FreeSurface(rotozoom_picture);
  223.          }
  224.                 }
  225.         /* Display by flipping screens */
  226.         SDL_UpdateRect(screen,0,0,0,0);
  227.     }
  228.  
  229.     if (rotate) {
  230.         /* Final display with angle=0 */
  231.         ClearScreen(screen);
  232.           checkkeys();
  233.         if (flip) {
  234.           if ((rotozoom_picture=rotozoomSurfaceXY (picture, 0.01, zoomfx, zoomfy, smooth))!=NULL) {
  235.             dest.x = (screen->w - rotozoom_picture->w)/2;;
  236.             dest.y = (screen->h - rotozoom_picture->h)/2;
  237.             dest.w = rotozoom_picture->w;
  238.             dest.h = rotozoom_picture->h;
  239.             if ( SDL_BlitSurface(rotozoom_picture, NULL, screen, &dest) < 0 ) {
  240.                 fprintf(stderr, "Blit failed: %s\n", SDL_GetError());
  241.                 return;
  242.             }
  243.             SDL_FreeSurface(rotozoom_picture);
  244.          }
  245.         } else {
  246.           if ((rotozoom_picture=rotozoomSurface (picture, 0.01, zoomf, smooth))!=NULL) {
  247.             dest.x = (screen->w - rotozoom_picture->w)/2;;
  248.             dest.y = (screen->h - rotozoom_picture->h)/2;
  249.             dest.w = rotozoom_picture->w;
  250.             dest.h = rotozoom_picture->h;
  251.             if ( SDL_BlitSurface(rotozoom_picture, NULL, screen, &dest) < 0 ) {
  252.                 fprintf(stderr, "Blit failed: %s\n", SDL_GetError());
  253.                 return;
  254.             }
  255.             SDL_FreeSurface(rotozoom_picture);
  256.          }
  257.             }
  258.         /* Display by flipping screens */
  259.         SDL_UpdateRect(screen,0,0,0,0);
  260.     }
  261.  
  262.     /* Pause for a sec */
  263.     SDL_Delay(1000);
  264. }
  265.  
  266.  
  267. // This function is the workings for the bounce mechanism.
  268. static void bouncer(void)
  269. {
  270. // bouncefactor is how many pixels the logo will move each step.
  271.   if ( bouncefactor>0 )
  272.   {
  273. // Here the logo will move up until it is less than 2 pixels from the top of the screen, then switch to going down.
  274.   if ( bouncing==1 )
  275.   {
  276.     rwy-=bouncefactor;
  277.     if (rwy<2) { bouncing=0; bouncefactor-=1; }
  278.   }
  279. // here it will move down until the logo is over 100 pixels down the screen, then switch to going up.
  280.   if ( bouncing==0 )
  281.   {
  282.     rwy+=bouncefactor;
  283.     if (rwy>100) { bouncing=1; bouncefactor-=1; }
  284.   }
  285.   }
  286. }
  287.  
  288.  
  289.  
  290.  
  291.  
  292. // All C programs require a main() function to run, this is where all the previously defined functions are called.
  293.  
  294. // argc and argv are for collecting any extra information on the command line, usually used for setting nosound or fullscreen, which does not apply here.
  295.  
  296. int main(int argc, char *argv[])
  297. {
  298. // reserve i as a counter variablefor loops
  299. int i;
  300.     // Initialize SDL
  301.     if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) < 0 ) {
  302.         fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
  303.         return EXIT_FAILURE;
  304.     }
  305.     atexit(SDL_Quit);
  306.  
  307. // Set video mode ( x width , y height , Bits per pixel and pallette information )
  308.     if ( (screen=SDL_SetVideoMode(640,480,8, SDL_HWSURFACE|SDL_HWPALETTE)) == NULL )
  309.     {
  310.         return EXIT_FAILURE;
  311.     }
  312. // Calling the loadimage function to load all the images.
  313.     if (!loadimages()) return EXIT_FAILURE;
  314. // Set the title of the SDL window.
  315.         SDL_WM_SetCaption("Risc World SDL Example 2", 0);
  316. // Tell SDL if we want the cursor or not, in this case we will leave it on ( 1 ).
  317.     SDL_ShowCursor( 1 );
  318.  
  319. // Collect time information for controlling the speed of the program.
  320.     sec = SDL_GetTicks();
  321. // The beginning of the main loop.
  322.     do
  323.     {
  324. // more time controll stuff, here we get the time and wait 80 centeseconds then continue with the program.
  325.                 cents = SDL_GetTicks();
  326.                 if (cents < sec + 80) SDL_Delay(sec + 80 - cents);
  327.                 sec = SDL_GetTicks();
  328. // Calling the checkkeys function to see if the mouse has been clicked.
  329.                                 checkkeys();
  330. // Plot the background image.
  331.                                 imageplot(background,0,0);
  332. // Plot the Risc World Logo.
  333.                                 imageplot(rwlogo,rwx,rwy);
  334. // Move the image if clicked.
  335.  
  336.  
  337. RotatePicture(screen,rwlogo,1,1,0);
  338.  
  339.  // wait a second clear the screen and check for quit
  340.     SDL_Delay(1000);    SDL_Flip(screen);  checkkeys();
  341.  // draw the shape
  342.       pixelRGBA(screen, 10, 15, 255, 255, 255, 255);
  343.  
  344.     SDL_Delay(1000);    SDL_Flip(screen);  checkkeys();
  345.  
  346.       lineRGBA(screen, 20, 10, 70, 90, 255, 0, 0, 255);
  347.  
  348.     SDL_Delay(1000);    SDL_Flip(screen);  checkkeys();
  349.  
  350.       trigonRGBA(screen, 500, 50, 550, 200, 600, 150, 0, 255, 255, 255);
  351.  
  352.     SDL_Delay(1000);    SDL_Flip(screen);  checkkeys();
  353.  
  354.       filledTrigonRGBA(screen, 200, 200, 300, 50, 400, 200, 0, 0, 255, 255);
  355.  
  356.     SDL_Delay(1000);    SDL_Flip(screen);  checkkeys();
  357.  
  358.       rectangleRGBA(screen,  -10, 300, 100, 380, 0, 255, 0, 255);
  359.  
  360.           SDL_Delay(1000);    SDL_Flip(screen);  checkkeys();
  361.  
  362.       boxRGBA(screen,  210, 76, 325, 300, 255, 0, 0, 150);
  363.  
  364.     SDL_Delay(1000);    SDL_Flip(screen);  checkkeys();
  365.  
  366.       ellipseRGBA(screen, 600, 400, 50, 90, 255, 255, 0, 200);
  367.  
  368.     SDL_Delay(1000);    SDL_Flip(screen);  checkkeys();
  369.  
  370.       filledEllipseRGBA(screen, 600, 400, 25, 150, 0, 255, 0, 255);
  371.  
  372.     SDL_Delay(1000);    SDL_Flip(screen);  checkkeys();
  373.  
  374.       short x[6] = { 350, 275, 300, 325, 350, 400 };
  375.       short y[6] = { 325, 325, 390, 390, 375, 300 };
  376.  
  377.     SDL_Delay(1000);    SDL_Flip(screen); checkkeys();
  378.  
  379.       polygonRGBA(screen, x, y, 6, 255, 255, 255, 155);
  380.  
  381.       short s[5] = { 400, 450, 450, 425, 300 };
  382.       short t[5] = { 400, 410, 450, 425, 500};
  383.  
  384.     SDL_Delay(1000);    SDL_Flip(screen); checkkeys();
  385.  
  386.       filledPolygonRGBA(screen, s, t, 5, 255, 0, 255, 155);
  387.  
  388.     SDL_Delay(1000);    SDL_Flip(screen);
  389.  
  390.         checkkeys();
  391.  
  392.     SDL_Delay(1000);
  393.  
  394.         checkkeys();
  395.  
  396.     SDL_Delay(1000);
  397.  
  398.         checkkeys();
  399.  
  400. // The end of the main loop, if quit has been detected the program will stop.
  401.     }
  402.     while (quit == 0);
  403. // We assume everything went ok and the code quits.
  404.     return EXIT_SUCCESS;
  405. }
  406.  
  407.  
  408.  
  409.  
  410.  
  411.  
  412.  
  413.  
  414.