Loading

Paste #p7yc8na5p

  1.  
  2. #include "stdafx.h"
  3. #include <SDL.h>
  4. #include <SDL_image.h>
  5. #include <memory>
  6. #include <vector>
  7. #include <iostream>
  8.  
  9. bool _finish = false;
  10. SDL_Window *_window;
  11. SDL_Renderer *_renderer;
  12.  
  13. static const uint32 FRAME_DELAY = 30;
  14.  
  15. class ImageData {
  16. public:
  17.     ImageData(const std::string &name)
  18.     {
  19.         std::string img_path = name + ".png";
  20.         this->image = IMG_LoadTexture(_renderer, img_path.c_str());
  21.         if (this->image == nullptr) {
  22.             throw std::string(SDL_GetError());
  23.         }
  24.  
  25.         std::string mask0_path = name + "_m0.png";
  26.         this->masks.emplace_back(IMG_LoadTexture(_renderer, mask0_path.c_str()));
  27.         if (this->masks[0] == nullptr) {
  28.             throw std::string(SDL_GetError());
  29.         }
  30.         std::string mask1_path = name + "_m1.png";
  31.         this->masks.emplace_back(IMG_LoadTexture(_renderer, mask1_path.c_str()));
  32.         if (this->masks[1] == nullptr) {
  33.             throw std::string(SDL_GetError());
  34.         }
  35.     }
  36.  
  37.     ~ImageData()
  38.     {
  39.         SDL_DestroyTexture(this->image);
  40.         this->image = nullptr;
  41.         for (auto &mask : this->masks) {
  42.             SDL_DestroyTexture(mask);
  43.             mask = nullptr;
  44.         }
  45.     }
  46.  
  47.     uint32 flags;  ///< Flags of the image. @see ImageFlags
  48.     uint16 width = 0;  ///< Width of the image.
  49.     uint16 height = 0; ///< Height of the image.
  50.     int16 xoffset; ///< Horizontal offset of the image.
  51.     int16 yoffset; ///< Vertical offset of the image.
  52.     SDL_Texture *image;
  53.     std::vector<SDL_Texture *> masks;
  54. };
  55.  
  56. std::vector<std::unique_ptr<ImageData>> _sprites;
  57.  
  58. /** Returns true when event polling ending event happens */
  59. bool HandleEvent()
  60. {
  61.     SDL_Event event;
  62.     if (SDL_PollEvent(&event) != 1) return true;
  63.     switch (event.type) {
  64.         case SDL_USEREVENT:
  65.             return true;
  66.         case SDL_KEYDOWN:
  67.             switch (event.key.keysym.sym) {
  68.                 case SDLK_q:
  69.                     _finish = true;
  70.                     return true;
  71.                 default:
  72.                     break;
  73.             }
  74.             return false;
  75.         case SDL_WINDOWEVENT:
  76.         default:
  77.             return false;
  78.     }
  79. }
  80.  
  81. uint8 GetR(uint32 rgba)
  82. {
  83.     return rgba >> 24;
  84. }
  85. uint8 GetG(uint32 rgba)
  86. {
  87.     return rgba >> 16;
  88. }
  89. uint8 GetB(uint32 rgba)
  90. {
  91.     return rgba >> 8;
  92. }
  93. uint8 GetA(uint32 rgba)
  94. {
  95.     return rgba;
  96. }
  97.  
  98. void DrawSprite(int x, int y, const std::vector<uint32> &cols)
  99. {
  100.     auto &imd = _sprites[0];
  101.     int w, h;
  102.     SDL_QueryTexture(imd->image, nullptr, nullptr, &w, &h);
  103.     SDL_Rect rect = {x, y, w, h};
  104.     SDL_RenderCopy(_renderer, imd->image, NULL, &rect);
  105.     SDL_SetRenderDrawBlendMode(_renderer, SDL_BLENDMODE_BLEND);
  106.     for (size_t i = 0; i < imd->masks.size(); i++) {
  107.         auto &mask = imd->masks[i];
  108.         SDL_SetTextureColorMod(mask, GetR(cols[i]), GetG(cols[i]), GetB(cols[i]));
  109.         SDL_RenderCopy(_renderer, mask, nullptr, &rect);
  110.     }
  111. }
  112.  
  113. void OnNewFrame(uint delay)
  114. {
  115.     (void)delay;
  116.     DrawSprite(50, 50, {0x0000FF00, 0x00FF0000});
  117.     SDL_RenderPresent(_renderer);
  118. }
  119.  
  120. void LoadSprite(const std::string &name)
  121. {
  122.     _sprites.emplace_back(new ImageData(name));
  123. }
  124.  
  125. int main()
  126. {
  127.     SDL_CreateWindowAndRenderer(800, 600, SDL_WINDOW_RESIZABLE, &_window, &_renderer);
  128.     IMG_Init(IMG_INIT_PNG);
  129.     if (_window == nullptr || _renderer == nullptr) return 1;
  130.  
  131.     try {
  132.         LoadSprite("icecream");
  133.     } catch(std::string& ex) {
  134.         std::cout << ex << std::endl;
  135.     }
  136.     SDL_SetRenderDrawColor(_renderer, 0, 0, 0, 255);
  137.     while(!_finish) {
  138.         uint start = SDL_GetTicks();
  139.  
  140.         OnNewFrame(FRAME_DELAY);
  141.  
  142.         for (;;) {
  143.             if (HandleEvent()) break;
  144.         }
  145.         if (_finish) break;
  146.  
  147.         uint now = SDL_GetTicks();
  148.         if (now >= start) {
  149.             now -= start;
  150.             if (now < FRAME_DELAY) SDL_Delay(FRAME_DELAY - now); // Wait
  151.         }
  152.     }
  153. }
  154.  

Comments