arcade_fighter.hpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /* License Notice:
  2. **
  3. ** This program is free software: you can redistribute it and/or modify
  4. ** it under the terms of the GNU General Public License as published by
  5. ** the Free Software Foundation, either version 3 of the License, or
  6. ** (at your option) any later version.
  7. ** This program is distributed in the hope that it will be useful,
  8. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. ** GNU General Public License for more details.
  11. ** You should have received a copy of the GNU General Public License
  12. ** along with this program. If not, see <https://www.gnu.org/licenses/>.
  13. */
  14. /**
  15. * @file arcade_fighter.hpp
  16. * @author TooOld2Rock'nRoll
  17. * @date 2022/12/15
  18. * @version 0.1.0
  19. * @brief Arcade Fighter Library main class.
  20. *
  21. * The Arcade Fighter Library is a studying project!<br>
  22. * It is NOT in any way or form a stable and robust commercial
  23. * game engine. We may get there one day, but for now, it's simple not
  24. * the objective of this project to offer a commercial solution.<br>
  25. * What we mean by a studying project is that it's meant for people studying
  26. * game development in all it's forms. Our code tries to be easy to read
  27. * and well documented as much as possible, all our sources for ideas and
  28. * algorithms are stated on the class headers.<br>
  29. * Check the [README.md](../README.md) for more information.
  30. *
  31. * @see https://learnopengl.com/
  32. * @see https://gameprogrammingpatterns.com/
  33. *
  34. * @todo When upgrading to SDL3, we can use: https://wiki.libsdl.org/SDL3/SDL_SyncWindow instead of SDL_WaitEventTimeout at init().
  35. * @todo This is quickly reducing to a global setup/init method and the game loop, maybe separate everything and make specific??? Would it make easier when implementing menu screens, transitions, etc?
  36. * @todo Find a way to open the audio interface with custom values from config.
  37. * @todo is it necessary to change the shaders perspective when the window size changes? Add a callback to let user know and do something?
  38. * @todo program exit event shouldn't be hard coded, load from a default input file, change to a user defined when we implement auto map keys.
  39. * @todo setPlayer is doing nothing useful, this will probably change once we are saving/loading config from files.
  40. * @todo add a way to enable/disable fps count on screen/terminal (do this when text rendering is ready).
  41. * @todo implement all the Window events, like pause level when loose focus etc: https://wiki.libsdl.org/SDL2/SDL_WindowEventID
  42. */
  43. #ifndef _ARCADE_FIGHTER_H_
  44. #define _ARCADE_FIGHTER_H_
  45. /*---- Includes ----*/
  46. #include "graphics/window_manager.hpp"
  47. #include "graphics/opengl.hpp"
  48. #include "camera2D.hpp"
  49. #include "audio/audio.hpp"
  50. #include "event_manager.hpp"
  51. #include "resource_manager.hpp"
  52. #include "player.hpp"
  53. #include "scenery.hpp"
  54. #include "level.hpp"
  55. /**
  56. * @brief Main Class for the ArcadeFighter Library.
  57. *
  58. * This is the class where most of the automation is done, a high level interface that abstracts all other classes and
  59. * do as much of the work as possible without getting in your way and the actual game you are trying to implement.<br>
  60. * Some predefined configurations may be set in the config.h file, some options are to hardcode the library values and
  61. * behavior, some are just safe "first boot" defaults that are supposed to be set more permanently by the player at
  62. * some point.<br>
  63. * A instance of this class must be created before any other class from this library or other OpenGl related objects,
  64. * it's unfortunate to have this limitation, but it's necessary to load the OpenGl APIs.<br>
  65. * The constructor will create a generic window and, if required, just grab the window manager to set very particular
  66. * needs of your project.<br>
  67. * OpenGl itself will be initialized with common settings and generic values, like Black will be used to clear the
  68. * screen on every frame, transparency will be set to Alpha channel and so forth. Feel free to change any setting
  69. * to your project's needs using the usual OpenGl interfaces.<br>
  70. * This library comes with a set of very simple builtin shaders just use the default ResourceManager::getBasicShader (),
  71. * but if you choose to use custom ones, it's expected they contain a model, projection and view mat4 uniforms on the
  72. * vertex shader and a color vec3 uniform on the fragment shader for the various operations needed by the library.<br>
  73. * In case of panic, [Alt+F4] will be automatically handled as the system (GNU Linux) recommended method of hard exiting
  74. * the program no matter the current state it is in at the time. It is recommended to also offer an option for the
  75. * player to set their own preferred method.
  76. */
  77. class ArcadeFighter
  78. {
  79. public:
  80. /**
  81. * @brief Different Game Loop regimes depending on your game needs.
  82. *
  83. * Implemented based on <em>Gaffer On Games</em> article from 2004/Jun/10 titled "Fix Your Timestep!"
  84. *
  85. * @see https://gafferongames.com/post/fix_your_timestep/
  86. */
  87. enum delta_time_style_e
  88. {
  89. FIXED = 0, ///< Try to keep a set FPS.
  90. VARIABLE, ///< Runs as fast as it can all the time (most likely VSYNC bound!!).
  91. SEMI_FIXED, ///< Game logic iterates as fast it can, rendering tries to keep at a set FPS (Probably what you are looking for!!)
  92. CHUNKY, ///< Game logic iterates at set time chunks, rendering is bound by set FPS.
  93. _max_delta_style ///< Just to keep track of how many possible variation we are handling.
  94. };//end delta_time_style
  95. private:
  96. /* system state */
  97. bool b_should_quit = false;
  98. /* physical display and graphics interface */
  99. WindowManager *p_sdl_instance = nullptr;
  100. OpenGl *p_gl_instance = nullptr;
  101. unsigned ui_display = 0; //which display to use
  102. /* Players data */
  103. Player *p_players[PLAYERS_COUNT];
  104. /* keep track of delta time on the main game loop */
  105. time_keep_s _main_delta_t;
  106. float f_target_delta_t = 0; //in sec
  107. time_keep_s _inner_delta_t;
  108. float f_target_step_t = 0; //in sec
  109. /* Local reference to the ResourceManager singleton. */
  110. ResourceManager *p_res_mgr_instance = nullptr;
  111. ResourceManager::global_status *p_lib_status = nullptr;
  112. //at this level, we will always use the global resource id
  113. /* Event handling */
  114. EventManager *p_ev_mgr_instance = nullptr;
  115. listenerID_t _event_listener_ID = 0;
  116. const EventManager::event_s *_hard_exit_command = nullptr;
  117. /* Audio interface */
  118. Audio *p_audio_instance = nullptr;
  119. /* Keep track of Level running */
  120. Level *_lv_running = nullptr;
  121. protected:
  122. void loop_section_events (Level &lv, double delta_t);
  123. void loop_section_logic (Level &lv, double delta_t);
  124. void loop_section_render (Level &lv, double delta_t);
  125. void run_fixedDeltaTime (Level &lv);
  126. void run_variableDeltaTime (Level &lv);
  127. void run_semiFixedDeltaTime (Level &lv);
  128. void run_chunkyDeltaTime (Level &lv);
  129. public:
  130. ArcadeFighter (const char *title = WINDOW_TITLE, unsigned display = 0, SDL_WindowFlags window_flags = (SDL_WindowFlags)0);
  131. ~ArcadeFighter ();
  132. void exit ();
  133. /** @brief Use in your main loop to check if program should terminate. */
  134. bool shouldQuit () const { return this->b_should_quit; }
  135. // To keep the game environment consistent and handle high level events
  136. void processEvents (double delta_t);
  137. //void update (double delta_t) { }
  138. // Players
  139. void setPlayer (unsigned pl_number, Player *pl);
  140. // Level Management
  141. /** @brief Sets the target FPS for the Game Loop to run. */
  142. void setTargetFPS (unsigned fps) { this->f_target_delta_t = 1.f/fps; }
  143. /** @brief Sets the target FPS to bound the logic section of the Game Loop. */
  144. void setTargetGameLogicLoopFPS (unsigned state_fps) { this->f_target_step_t = 1.f/state_fps; }
  145. void levelStart (Level &lv, ArcadeFighter::delta_time_style_e style = GAME_LOOP_STYLE);
  146. };//END ArcadeFighter
  147. #endif //_ARCADE_FIGHTER_H_