Advertisement
Guest User

Untitled

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