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.

main.cc 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #include <time.h>
  2. #include <unistd.h>
  3. #include <stdio.h>
  4. #include <vector>
  5. #include <memory>
  6. #include <chrono>
  7. #include <ratio>
  8. #include <SDL2/SDL.h>
  9. #include <SDL2/SDL_image.h>
  10. #include <swan/common.h>
  11. #include <swan/World.h>
  12. #include <swan/Game.h>
  13. #include <swan/Timer.h>
  14. #include <swan/Win.h>
  15. using namespace Swan;
  16. #define errassert(expr, str, errfn) do { \
  17. if (!(expr)) { \
  18. fprintf(stderr, "%s: %s\n", str, errfn()); \
  19. return EXIT_FAILURE; \
  20. } \
  21. } while (0)
  22. #define sdlassert(expr, str) errassert(expr, str, SDL_GetError);
  23. #define imgassert(expr, str) errassert(expr, str, IMG_GetError);
  24. template<typename T>
  25. using DeleteFunc = void (*)(T *);
  26. int main() {
  27. sdlassert(SDL_Init(SDL_INIT_VIDEO) >= 0, "Could not initialize SDL");
  28. std::unique_ptr<void, DeleteFunc<void>> sdl(nullptr, [](void *){ SDL_Quit(); });
  29. int imgflags = IMG_INIT_PNG;
  30. imgassert(IMG_Init(imgflags) == imgflags, "Could not initialize SDL_Image");
  31. std::unique_ptr<void, DeleteFunc<void>> sdl_image(nullptr, [](void *){ IMG_Quit(); });
  32. std::unique_ptr<SDL_Window, DeleteFunc<SDL_Window>> window(
  33. SDL_CreateWindow(
  34. "Project: SWAN",
  35. SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
  36. 640, 480,
  37. SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE),
  38. SDL_DestroyWindow);
  39. std::unique_ptr<SDL_Renderer, DeleteFunc<SDL_Renderer>> renderer(
  40. SDL_CreateRenderer(
  41. window.get(), -1, SDL_RENDERER_ACCELERATED),
  42. SDL_DestroyRenderer);
  43. sdlassert(renderer, "Could not create renderer\n");
  44. Win win(renderer.get());
  45. Game game(win);
  46. std::vector<std::unique_ptr<Mod>> mods;
  47. mods.push_back(game.loadMod("core.mod"));
  48. game.createWorld("core::default", std::move(mods));
  49. auto prevTime = std::chrono::steady_clock::now();
  50. float fpsAcc = 0;
  51. float tickAcc = 0;
  52. int fcount = 0;
  53. int slowFrames = 0;
  54. while (1) {
  55. SDL_Event evt;
  56. while (SDL_PollEvent(&evt)) {
  57. switch (evt.type) {
  58. case SDL_QUIT:
  59. goto exit;
  60. break;
  61. case SDL_KEYDOWN:
  62. game.onKeyDown(evt.key.keysym);
  63. break;
  64. case SDL_KEYUP:
  65. game.onKeyUp(evt.key.keysym);
  66. break;
  67. case SDL_MOUSEMOTION:
  68. game.onMouseMove(evt.motion.x, evt.motion.y);
  69. break;
  70. case SDL_MOUSEBUTTONDOWN:
  71. game.onMouseDown(evt.button.x, evt.button.y, evt.button.button);
  72. break;
  73. case SDL_MOUSEBUTTONUP:
  74. game.onMouseUp(evt.button.x, evt.button.y, evt.button.button);
  75. break;
  76. }
  77. }
  78. auto now = std::chrono::steady_clock::now();
  79. std::chrono::duration<float> dur(prevTime - now);
  80. prevTime = now;
  81. float dt = dur.count();
  82. // Display FPS
  83. fpsAcc += dt;
  84. fcount += 1;
  85. if (fpsAcc >= 4) {
  86. fprintf(stderr, "FPS: %.3f\n", fcount / 4.0);
  87. fpsAcc -= 4;
  88. fcount = 0;
  89. }
  90. game.update(dt);
  91. if (dt > 0.1) {
  92. if (slowFrames == 0)
  93. fprintf(stderr, "Warning: delta time is too high! (%.3fs).\n", dt);
  94. slowFrames += 1;
  95. } else {
  96. if (slowFrames > 0) {
  97. if (slowFrames > 1)
  98. fprintf(stderr, "%i consecutive slow frames.\n", slowFrames);
  99. slowFrames = 0;
  100. }
  101. tickAcc += dt;
  102. while (tickAcc >= 1.0 / TICK_RATE) {
  103. tickAcc -= 1.0 / TICK_RATE;
  104. game.tick(1.0 / TICK_RATE);
  105. }
  106. }
  107. game.draw();
  108. SDL_UpdateWindowSurface(window.get());
  109. }
  110. exit:
  111. return EXIT_SUCCESS;
  112. }