Advertisement
Guest User

Untitled

a guest
Nov 9th, 2024
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.78 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. #include <SDL2/SDL.h>
  5.  
  6. #include <stdbool.h>
  7. #include <stdint.h>
  8.  
  9. #include <SDL2/SDL_ttf.h>
  10.  
  11. #define WINDOW_WIDTH 600
  12. #define WINDOW_HEIGHT 650
  13.  
  14. #define FONT_COORDINATES "fonts/Hack-Regular.ttf"
  15.  
  16. #define FONT_HEIGHT 20
  17.  
  18. void panic(const char* format, ...) {
  19.   va_list va;
  20.   va_start(va, format);
  21.  
  22.   vfprintf(stderr, format, va);
  23.   fprintf(stderr, "\n");
  24.  
  25.   va_end(va);
  26.   exit(1);
  27. }
  28.  
  29. typedef struct {
  30.   SDL_Window* window;
  31.   SDL_Renderer* r;
  32.  
  33.   struct {
  34.     int width;
  35.     int height;
  36.   } windowDimensions;
  37.  
  38.   struct {
  39.     SDL_Texture* coordinates_horizontal;
  40.   } textures;
  41.  
  42.   int tileSize;
  43. } RenderContext;
  44.  
  45. SDL_Texture* generateHorizontalCoordinates(RenderContext* rc) {
  46.   if (rc == NULL) {
  47.     panic("Passed NULL to generateHorizontalCoordinates()");
  48.   }
  49.  
  50.   // load font
  51.   TTF_Font* font = TTF_OpenFont(FONT_COORDINATES, 10);
  52.   if (font == NULL) {
  53.     panic("Could not open font");
  54.   }
  55.  
  56.   // 1. calculate texture dimensions (board width and font height)
  57.   // and load font in correct size
  58.   const int fontSize = FONT_HEIGHT;
  59.  
  60.   int ret = TTF_SetFontSize(font, fontSize);
  61.   if (ret == -1) {
  62.     panic("Could not set font size");
  63.   }
  64.  
  65.   // 2. allocate master texture
  66.   SDL_Texture* masterTexture = SDL_CreateTexture(
  67.       rc->r,
  68.       SDL_PIXELFORMAT_RGBA32,
  69.       SDL_TEXTUREACCESS_TARGET,
  70.       rc->windowDimensions.width,
  71.       FONT_HEIGHT
  72.   );
  73.   if (masterTexture == NULL) {
  74.     panic("Could not create texture");
  75.   }
  76.   SDL_SetTextureBlendMode(masterTexture, SDL_BLENDMODE_BLEND);
  77.  
  78.   // 3. generate temporary textures for each letter and copy it to "master texture"
  79.   //TODO FIXME sometimes some letters are not rendered at all!
  80.   for (int i = 0; i < 9; i++) {
  81.     char text[2] = {0};
  82.     text[0] = '1' + i;
  83.     SDL_Color color = {0, 0, 0, 255};
  84.     SDL_Surface* letterSurface = TTF_RenderUTF8_Solid(font, text, color);
  85.     if (letterSurface == NULL) {
  86.       panic("Could not create letterSurface");
  87.     }
  88.  
  89.     SDL_Texture* letterTexture = SDL_CreateTextureFromSurface(rc->r, letterSurface);
  90.     if (letterTexture == NULL) {
  91.       panic("Could not create letterTexture");
  92.     }
  93.     // NB: We'll keep the surface around for its metadata
  94.  
  95.     // render to master texture
  96.     int res = SDL_SetRenderTarget(rc->r, masterTexture);
  97.     if (res != 0) {
  98.       panic("Could not set render target");
  99.     }
  100.  
  101.     SDL_Rect dst = {
  102.         .w = letterSurface->w,
  103.         .h = letterSurface->h,
  104.         .x = (rc->tileSize / 2) + (i * rc->tileSize)
  105.              - (letterSurface->w / 2),
  106.         .y = 0
  107.     };
  108.     printf("i: %d, w: %d, h: %d, x: %d, y: %d\n", i, dst.w, dst.h, dst.x, dst.y); //XXX
  109.     SDL_RenderCopy(rc->r, letterTexture, NULL, &dst);
  110.  
  111.     // clean-up
  112.     SDL_SetRenderTarget(rc->r, NULL);
  113.     SDL_FreeSurface(letterSurface);
  114.     SDL_DestroyTexture(letterTexture);
  115.   }
  116.  
  117.   // 4. free font and return master texture (free in rc_free())
  118.   TTF_CloseFont(font);
  119.   return masterTexture;
  120. }
  121.  
  122. void renderContext_init(RenderContext* rc, int boardSize) {
  123.   if (rc == NULL) {
  124.     panic("Passed NULL to rendercontext_init()");
  125.   }
  126.  
  127.   rc->window = SDL_CreateWindow(
  128.       "Goban",
  129.       SDL_WINDOWPOS_CENTERED,
  130.       SDL_WINDOWPOS_CENTERED,
  131.       WINDOW_WIDTH,
  132.       WINDOW_HEIGHT,
  133.       0
  134.   );
  135.   if (rc->window == NULL) {
  136.     panic("Could not init Window: %s", SDL_GetError());
  137.   }
  138.  
  139.   rc->r = SDL_CreateRenderer(
  140.       rc->window,
  141.       -1,
  142.       SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE
  143.   );
  144.   if (rc->r == NULL) {
  145.     panic("Could not init Renderer: %s", SDL_GetError());
  146.   }
  147.  
  148.   // init SDL_TTF
  149.   TTF_Init();
  150.  
  151.   rc->windowDimensions.width = WINDOW_WIDTH;
  152.   rc->windowDimensions.height = WINDOW_HEIGHT;
  153.   rc->tileSize = rc->windowDimensions.width / boardSize;
  154.  
  155.   rc->textures.coordinates_horizontal = generateHorizontalCoordinates(rc);
  156. }
  157.  
  158. void renderContext_free(RenderContext* rc) {
  159.   if (rc == NULL) {
  160.     panic("Passed NULL to rendercontext_free()");
  161.   }
  162.  
  163.   TTF_Quit();
  164.   SDL_DestroyTexture(rc->textures.coordinates_horizontal);
  165.   SDL_DestroyRenderer(rc->r);
  166.   SDL_DestroyWindow(rc->window);
  167. }
  168.  
  169. void renderBackground(RenderContext* rc) {
  170.   if (rc == NULL) {
  171.     panic("Passed NULL to renderBackground()");
  172.   }
  173.  
  174.   SDL_SetRenderDrawColor(rc->r, 255, 255, 255, 255);
  175.   SDL_Rect rect = {
  176.     .w = rc->windowDimensions.width,
  177.     .h = rc->windowDimensions.width,
  178.     .x = 0,
  179.     .y = 0
  180.   };
  181.   SDL_RenderFillRect(rc->r, &rect);
  182. }
  183.  
  184. void renderCoordinates(RenderContext* rc) {
  185.   if (rc == NULL) {
  186.     panic("Passed NULL to renderCoordinates()");
  187.   }
  188.  
  189.   SDL_Rect dst = {0};
  190.   dst.w = rc->windowDimensions.width;
  191.   dst.h = FONT_HEIGHT;
  192.   SDL_RenderCopy(rc->r, rc->textures.coordinates_horizontal, NULL, &dst);
  193. }
  194.  
  195. void renderBoard(RenderContext* rc) {
  196.   if (rc == NULL) {
  197.     panic("Passed NULL to renderBoard()");
  198.   }
  199.  
  200.   renderBackground(rc);
  201.   renderCoordinates(rc);
  202. }
  203.  
  204. void renderContext_render(RenderContext* rc) {
  205.   if (rc == NULL) {
  206.     panic("Passed NULL to rendercontext_render()");
  207.   }
  208.  
  209.   SDL_SetRenderDrawColor(rc->r, 255, 255, 255, 255);
  210.   SDL_RenderClear(rc->r);
  211.  
  212.   renderBoard(rc);
  213.  
  214.   SDL_RenderPresent(rc->r);
  215. }
  216.  
  217. bool shouldQuit = false;
  218.  
  219. void handleEvents(RenderContext* rc) {
  220.   if (rc == NULL) {
  221.     panic("Passed NULL to handleEvents()");
  222.   }
  223.  
  224.   SDL_Event e;
  225.   while (SDL_PollEvent(&e)) {
  226.     switch (e.type) {
  227.       case SDL_QUIT:
  228.         shouldQuit = true;
  229.         break;
  230.     }
  231.   }
  232. }
  233.  
  234. int main(void) {
  235.   int ret;
  236.   ret = SDL_Init(SDL_INIT_VIDEO);
  237.   if (ret != 0) {
  238.     panic("Could not init SDL: %s", SDL_GetError());
  239.   }
  240.  
  241.   RenderContext rc;
  242.   renderContext_init(&rc, 9);
  243.  
  244.   while (!shouldQuit) {
  245.     handleEvents(&rc);
  246.     renderContext_render(&rc);
  247.   }
  248.  
  249.   renderContext_free(&rc);
  250.   SDL_Quit();
  251.   return 0;
  252. }
  253.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement