window.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #include "window.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #define ERROR(...) fprintf(stderr, __VA_ARGS__)
  5. Window *windowNew(const char *title, int width, int height) {
  6. Window *window = malloc(sizeof(Window));
  7. if (!window) {
  8. ERROR("error: out of memory\n");
  9. exit(EXIT_FAILURE);
  10. }
  11. window->obj = SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED,
  12. SDL_WINDOWPOS_UNDEFINED, width, height,
  13. SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
  14. if (!window->obj) {
  15. ERROR("error: sdl2: %s\n", SDL_GetError());
  16. free(window);
  17. exit(EXIT_FAILURE);
  18. }
  19. window->render = SDL_CreateRenderer(
  20. window->obj, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
  21. if (!window->render) {
  22. ERROR("error: sdl2: %s\n", SDL_GetError());
  23. SDL_DestroyWindow(window->obj);
  24. free(window);
  25. exit(EXIT_FAILURE);
  26. }
  27. window->background = NULL;
  28. window->focus.x = 0.0f;
  29. window->focus.y = 0.0f;
  30. window->targetFocus.x = 0.0f;
  31. window->targetFocus.y = 0.0f;
  32. window->zoom = 1.0f;
  33. window->state = WINDOW_STATE_NORMAL;
  34. return window;
  35. }
  36. void windowDelete(Window *window) {
  37. SDL_DestroyRenderer(window->render);
  38. SDL_DestroyWindow(window->obj);
  39. free(window);
  40. }
  41. static void zoomRect(const Window *window, SDL_Rect *rect) {
  42. int winW, winH;
  43. SDL_GetWindowSize(window->obj, &winW, &winH);
  44. int texW, texH;
  45. SDL_QueryTexture(window->background, NULL, NULL, &texW, &texH);
  46. const Point *focus = &window->focus;
  47. rect->x = (texW * focus->x) - (texW / window->zoom / 2);
  48. rect->y = (texH * focus->y) - (texH / window->zoom / 2);
  49. rect->w = texW / window->zoom;
  50. rect->h = texH / window->zoom;
  51. }
  52. void windowDraw(Window *window) {
  53. window->lastTime = window->nowTime;
  54. window->nowTime = SDL_GetPerformanceCounter();
  55. window->delta = (double)(((window->nowTime - window->lastTime) * 1000) /
  56. SDL_GetPerformanceFrequency());
  57. SDL_SetRenderDrawColor(window->render, 0xFF, 0xFF, 0xFF, SDL_ALPHA_OPAQUE);
  58. SDL_RenderClear(window->render);
  59. if (window->background) {
  60. if (window->state == WINDOW_STATE_ZOOMING_IN) {
  61. window->zoom += MAX_ZOOM * (window->delta / ZOOM_TIME);
  62. window->focus.x += (window->targetFocus.x - window->startFocus.x) *
  63. (window->delta / ZOOM_TIME);
  64. window->focus.y += (window->targetFocus.y - window->startFocus.y) *
  65. (window->delta / ZOOM_TIME);
  66. if (window->zoom >= MAX_ZOOM) {
  67. window->state = WINDOW_STATE_ZOOMED;
  68. }
  69. } else if (window->state == WINDOW_STATE_ZOOMING_OUT) {
  70. window->zoom -= MAX_ZOOM * (window->delta / ZOOM_TIME);
  71. window->focus.x += (window->targetFocus.x - window->startFocus.x) *
  72. (window->delta / ZOOM_TIME);
  73. window->focus.y += (window->targetFocus.y - window->startFocus.y) *
  74. (window->delta / ZOOM_TIME);
  75. if (window->zoom <= 1.0f) {
  76. window->state = WINDOW_STATE_NORMAL;
  77. }
  78. }
  79. if (window->state == WINDOW_STATE_NORMAL) {
  80. SDL_RenderCopy(window->render, window->background, NULL, NULL);
  81. } else {
  82. SDL_Rect area;
  83. zoomRect(window, &area);
  84. SDL_RenderCopy(window->render, window->background, &area, NULL);
  85. }
  86. }
  87. }
  88. void windowUpdate(Window *window) {
  89. SDL_RenderPresent(window->render);
  90. }
  91. void windowZoomTo(Window *window, float x, float y) {
  92. window->zoom = 1.0f;
  93. window->startFocus.x = 0.5f;
  94. window->startFocus.y = 0.5f;
  95. window->focus = window->startFocus;
  96. window->targetFocus.x = x;
  97. window->targetFocus.y = y;
  98. window->state = WINDOW_STATE_ZOOMING_IN;
  99. }
  100. void windowZoomOut(Window *window) {
  101. window->startFocus = window->focus;
  102. window->targetFocus.x = 0.5f;
  103. window->targetFocus.y = 0.5f;
  104. window->state = WINDOW_STATE_ZOOMING_OUT;
  105. }