#+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