A 2D tile-based sandbox game.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Win.h 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. #pragma once
  2. #include "log.h"
  3. #include "common.h"
  4. #include <SDL.h>
  5. #include <optional>
  6. namespace Swan {
  7. class Win {
  8. public:
  9. Win(SDL_Window *window, SDL_Renderer *renderer, float scale):
  10. window_(window), renderer_(renderer), scale_(scale) {
  11. if (SDL_GetRendererInfo(renderer_, &rinfo_) < 0) {
  12. panic << "GetRenedrerInfo failed: " << SDL_GetError();
  13. abort();
  14. }
  15. // For HiDPI, we must set the renderer's logical size.
  16. int w, h;
  17. SDL_GetWindowSize(window_, &w, &h);
  18. onResize(w, h);
  19. info << "Using renderer: " << rinfo_.name;
  20. }
  21. Vec2 getPixSize() {
  22. int w, h;
  23. SDL_GetWindowSize(window_, &w, &h);
  24. return Vec2((float)w / scale_, (float)h / scale_);
  25. }
  26. Vec2 getSize() {
  27. int w, h;
  28. SDL_GetWindowSize(window_, &w, &h);
  29. return Vec2(((float)w / (scale_ * zoom_)) / TILE_SIZE, ((float)h / (scale_ * zoom_)) / TILE_SIZE);
  30. }
  31. void onResize(int w, int h) {
  32. SDL_RenderSetLogicalSize(renderer_, (int)((float)w / scale_), (int)((float)h / scale_));
  33. }
  34. SDL_Rect createDestRect(Vec2 pos, Vec2 pixsize) {
  35. return SDL_Rect{
  36. (int)floor((pos.x - cam_.x) * TILE_SIZE * zoom_),
  37. (int)floor((pos.y - cam_.y) * TILE_SIZE * zoom_),
  38. (int)ceil(pixsize.x * zoom_), (int)ceil(pixsize.y * zoom_),
  39. };
  40. }
  41. struct ShowTextureArgs {
  42. SDL_RendererFlip flip = SDL_FLIP_NONE;
  43. double hscale = 1;
  44. double vscale = 1;
  45. double angle = 0;
  46. std::optional<SDL_Point> center = std::nullopt;
  47. };
  48. void showTexture(
  49. const Vec2 &pos, SDL_Texture *tex, SDL_Rect *srcrect,
  50. ShowTextureArgs args) {
  51. SDL_Point *center = args.center ? &*args.center : nullptr;
  52. SDL_Rect destrect = createDestRect(pos, Vec2(srcrect->w * args.hscale, srcrect->h * args.hscale));
  53. if (SDL_RenderCopyEx(renderer_, tex, srcrect, &destrect, args.angle, center, args.flip) < 0)
  54. warn << "RenderCopyEx failed: " << SDL_GetError();
  55. }
  56. void showTexture(const Vec2 &pos, SDL_Texture *tex, SDL_Rect *srcrect,
  57. SDL_Rect *dest, ShowTextureArgs args) {
  58. SDL_Point *center = args.center ? &*args.center : nullptr;
  59. SDL_Rect destrect = createDestRect(pos, Vec2(dest->w * args.hscale, dest->h * args.hscale));
  60. if (SDL_RenderCopyEx(renderer_, tex, srcrect, &destrect, args.angle, center, args.flip) < 0)
  61. warn << "RenderCopyEx failed: " << SDL_GetError();
  62. }
  63. // We want an overload which uses RenderCopy instead of RenderCopyEx,
  64. // because RenderCopy might be faster
  65. void showTexture(const Vec2 &pos, SDL_Texture *tex, SDL_Rect *srcrect) {
  66. SDL_Rect destrect = createDestRect(pos, Vec2(srcrect->w, srcrect->h));
  67. if (SDL_RenderCopy(renderer_, tex, srcrect, &destrect) < 0)
  68. warn << "RenderCopy failed: " << SDL_GetError();
  69. }
  70. // Another overload without RenderCopyEx
  71. void showTexture(const Vec2 &pos, SDL_Texture *tex, SDL_Rect *srcrect,
  72. SDL_Rect *dest) {
  73. SDL_Rect destrect = createDestRect(pos, Vec2(dest->w, dest->h));
  74. if (SDL_RenderCopy(renderer_, tex, srcrect, &destrect) < 0)
  75. warn << "RenderCopy failed: " << SDL_GetError();
  76. }
  77. void drawRect(const Vec2 &pos, const Vec2 &size) {
  78. SDL_Rect destrect = createDestRect(pos, size * TILE_SIZE);
  79. if (SDL_RenderDrawRect(renderer_, &destrect) < 0)
  80. warn << "RenderDrawRect failed: " << SDL_GetError();
  81. }
  82. Vec2 cam_;
  83. float zoom_ = 1;
  84. SDL_Window *window_;
  85. SDL_Renderer *renderer_;
  86. float scale_;
  87. SDL_RendererInfo rinfo_;
  88. };
  89. }