#+TITLE: sdl2 org src
#+AUTHOR: screwtape
* Rich media sdl2 C applications
(skip past window settings in your reading; they are just better at the top)
** Window settings
#+NAME: w-sizing
#+HEADER: :includes "/usr/local/include/SDL2/SDL.h"
#+begin_src C
SDL_WINDOW_RESIZABLE
#+end_src

#+NAME: w-height
#+begin_src C
768
#+end_src

#+NAME: w-width
#+begin_src C
1280
#+end_src

** template
#+BEGIN_EXAMPLE
 This template does seem a little bit  goto cleanup rather than some clunky
 long, but that is because it handles  quit flag;  but then,  it was easier
 keyboard  and mouse events and mouse  to goto quit which gotos cleanup. At
 position  in the general case.  I do  least the loop isn't goto based!
#+END_EXAMPLE
includes and libs might need to be customized. I found that  my  sdl2-config
flags on arm64 openbsd didn't actually work!
#+name: template
#+HEADER: :includes "/usr/local/include/SDL2/SDL.h"
#+HEADER: :libs "-L/usr/local/lib -lSDL2"
#+HEADER: :exports code
#+HEADER: :results none
#+HEADER: :noweb yes
#+begin_src C
   SDL_Event e;
   int mx, my;
   Uint32 mdown;

   <<hero-init>>

     /* Sort of clock */
   int cycle_limit = 10000;
   int cycle_now = 0;


   /* spinning animation */
   int ticks = 0;
   int tox, toy, centerx, centery;
   float xoff=0.0, yoff=0.0, l;

 centerx = 635; centery = 384; l = 100.0;
 /*/spinning animation */

   <<sdlstart>>

   for(;;){
     while(SDL_PollEvent(&e))
       if (e.type == SDL_QUIT)
       quit:
         goto cleanup;
       else if (e.type == SDL_MOUSEBUTTONDOWN)
         switch (1){
         default:
           break;
         }
       else if (e.type == SDL_MOUSEBUTTONUP)
         switch (1){
         default:
           break;
         }
       else if (e.type == SDL_KEYDOWN)
         switch (e.key.keysym.sym){
         case SDLK_UP:
           hero.rect.y -= 10;
           break;

         case SDLK_DOWN:
           hero.rect.y += 10;
           break;
         case SDLK_q:
           goto quit;
         default:
           break;
         }
       else if (e.type == SDL_KEYUP)
         switch (1){
         default:
           break;
         }

     mdown = SDL_GetMouseState(&mx, &my);

     SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
     SDL_RenderClear(renderer);

     <<hero-update>>

         SDL_SetRenderDrawColor(renderer, 100, 200, 200, 255);


     /* spinning animation */
     ticks++;

     xoff= l * SDL_sin((float)ticks / (2.0 * M_PI));
     tox = centerx + (int)xoff;
     yoff= l * SDL_cos((float)ticks / (2.0 * M_PI));
     toy = centery + (int)yoff;

     SDL_RenderDrawLine(renderer, centerx, centery, tox, toy);
     /*/spinning animation */


     SDL_RenderPresent(renderer);
     SDL_Delay(25);

     if ((cycle_now+=25) < cycle_limit) {
       if (cycle_now < (cycle_limit / 2)) centerx--;
       else centerx++;
     } else {
       cycle_now = 0;
     }
    }
   cleanup:
   <<sdlcleanup>>
#+end_src

** My macros
*** Hero
**** Hero init
#+name: hero-init
#+begin_src C
 struct hero{
   int xpos, ypos, width, height, r, g, b, a, speed;
   SDL_Rect rect;
 } hero;

 hero.rect.x=100; hero.rect.y=200; hero.rect.w=50; hero.rect.h=60;

 hero.r = 30; hero.g = 60; hero.b = 90; hero.a = 255;
 hero.speed = 10;
#+end_src

**** Hero update
#+name: hero-update
#+begin_src C
 SDL_SetRenderDrawColor(renderer, hero.r, hero.g, hero.b, hero.a);
 SDL_RenderFillRect(renderer, &(hero.rect));
#+end_src


** Simple SDL2, window, renderer init
#+NAME: sdlstart
#+HEADER: :noweb yes
#+begin_src C
 SDL_Window *window;
 SDL_Renderer *renderer;

 if (SDL_Init(SDL_INIT_VIDEO) < 0){
   SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to init SDL: %s",
                SDL_GetError());
   return 3;
  }

 if (SDL_CreateWindowAndRenderer(<<w-width>>, <<w-height>>,
                                 <<w-sizing>>, &window, &renderer)){
   SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create renderer and window: %s",
                SDL_GetError());
   return 3;
  }
#+end_src

** Simple SDL2 cleanup
#+NAME: sdlcleanup
#+begin_src C
 SDL_DestroyRenderer(renderer);
 SDL_DestroyWindow(window);
 SDL_Quit();
 return 0;
#+end_src