123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- /* License Notice:
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
- /**
- * @file arcade_fighter.hpp
- * @author TooOld2Rock'nRoll
- * @date 2022/12/15
- * @version 0.1.0
- * @brief Arcade Fighter Library main class.
- *
- * The Arcade Fighter Library is a studying project!<br>
- * It is NOT in any way or form a stable and robust commercial
- * game engine. We may get there one day, but for now, it's simple not
- * the objective of this project to offer a commercial solution.<br>
- * What we mean by a studying project is that it's meant for people studying
- * game development in all it's forms. Our code tries to be easy to read
- * and well documented as much as possible, all our sources for ideas and
- * algorithms are stated on the class headers.<br>
- * Check the [README.md](../README.md) for more information.
- *
- * @see https://learnopengl.com/
- * @see https://gameprogrammingpatterns.com/
- *
- * @todo When upgrading to SDL3, we can use: https://wiki.libsdl.org/SDL3/SDL_SyncWindow instead of SDL_WaitEventTimeout at init().
- * @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?
- * @todo Find a way to open the audio interface with custom values from config.
- * @todo is it necessary to change the shaders perspective when the window size changes? Add a callback to let user know and do something?
- * @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.
- * @todo setPlayer is doing nothing useful, this will probably change once we are saving/loading config from files.
- * @todo add a way to enable/disable fps count on screen/terminal (do this when text rendering is ready).
- * @todo implement all the Window events, like pause level when loose focus etc: https://wiki.libsdl.org/SDL2/SDL_WindowEventID
- */
- #ifndef _ARCADE_FIGHTER_H_
- #define _ARCADE_FIGHTER_H_
- /*---- Includes ----*/
- #include "graphics/window_manager.hpp"
- #include "graphics/opengl.hpp"
- #include "camera2D.hpp"
- #include "audio/audio.hpp"
- #include "event_manager.hpp"
- #include "resource_manager.hpp"
- #include "player.hpp"
- #include "scenery.hpp"
- #include "level.hpp"
- /**
- * @brief Main Class for the ArcadeFighter Library.
- *
- * This is the class where most of the automation is done, a high level interface that abstracts all other classes and
- * do as much of the work as possible without getting in your way and the actual game you are trying to implement.<br>
- * Some predefined configurations may be set in the config.h file, some options are to hardcode the library values and
- * behavior, some are just safe "first boot" defaults that are supposed to be set more permanently by the player at
- * some point.<br>
- * A instance of this class must be created before any other class from this library or other OpenGl related objects,
- * it's unfortunate to have this limitation, but it's necessary to load the OpenGl APIs.<br>
- * The constructor will create a generic window and, if required, just grab the window manager to set very particular
- * needs of your project.<br>
- * OpenGl itself will be initialized with common settings and generic values, like Black will be used to clear the
- * screen on every frame, transparency will be set to Alpha channel and so forth. Feel free to change any setting
- * to your project's needs using the usual OpenGl interfaces.<br>
- * This library comes with a set of very simple builtin shaders just use the default ResourceManager::getBasicShader (),
- * but if you choose to use custom ones, it's expected they contain a model, projection and view mat4 uniforms on the
- * vertex shader and a color vec3 uniform on the fragment shader for the various operations needed by the library.<br>
- * In case of panic, [Alt+F4] will be automatically handled as the system (GNU Linux) recommended method of hard exiting
- * the program no matter the current state it is in at the time. It is recommended to also offer an option for the
- * player to set their own preferred method.
- */
- class ArcadeFighter
- {
- public:
- /**
- * @brief Different Game Loop regimes depending on your game needs.
- *
- * Implemented based on <em>Gaffer On Games</em> article from 2004/Jun/10 titled "Fix Your Timestep!"
- *
- * @see https://gafferongames.com/post/fix_your_timestep/
- */
- enum delta_time_style_e
- {
- FIXED = 0, ///< Try to keep a set FPS.
- VARIABLE, ///< Runs as fast as it can all the time (most likely VSYNC bound!!).
- SEMI_FIXED, ///< Game logic iterates as fast it can, rendering tries to keep at a set FPS (Probably what you are looking for!!)
- CHUNKY, ///< Game logic iterates at set time chunks, rendering is bound by set FPS.
- _max_delta_style ///< Just to keep track of how many possible variation we are handling.
- };//end delta_time_style
- private:
- /* system state */
- bool b_should_quit = false;
- /* physical display and graphics interface */
- WindowManager *p_sdl_instance = nullptr;
- OpenGl *p_gl_instance = nullptr;
- unsigned ui_display = 0; //which display to use
- /* Players data */
- Player *p_players[PLAYERS_COUNT];
- /* keep track of delta time on the main game loop */
- time_keep_s _main_delta_t;
- float f_target_delta_t = 0; //in sec
- time_keep_s _inner_delta_t;
- float f_target_step_t = 0; //in sec
- /* Local reference to the ResourceManager singleton. */
- ResourceManager *p_res_mgr_instance = nullptr;
- ResourceManager::global_status *p_lib_status = nullptr;
- //at this level, we will always use the global resource id
- /* Event handling */
- EventManager *p_ev_mgr_instance = nullptr;
- listenerID_t _event_listener_ID = 0;
- const EventManager::event_s *_hard_exit_command = nullptr;
- /* Audio interface */
- Audio *p_audio_instance = nullptr;
- /* Keep track of Level running */
- Level *_lv_running = nullptr;
- protected:
- void loop_section_events (Level &lv, double delta_t);
- void loop_section_logic (Level &lv, double delta_t);
- void loop_section_render (Level &lv, double delta_t);
- void run_fixedDeltaTime (Level &lv);
- void run_variableDeltaTime (Level &lv);
- void run_semiFixedDeltaTime (Level &lv);
- void run_chunkyDeltaTime (Level &lv);
- public:
- ArcadeFighter (const char *title = WINDOW_TITLE, unsigned display = 0, SDL_WindowFlags window_flags = (SDL_WindowFlags)0);
- ~ArcadeFighter ();
- void exit ();
- /** @brief Use in your main loop to check if program should terminate. */
- bool shouldQuit () const { return this->b_should_quit; }
- // To keep the game environment consistent and handle high level events
- void processEvents (double delta_t);
- //void update (double delta_t) { }
- // Players
- void setPlayer (unsigned pl_number, Player *pl);
- // Level Management
- /** @brief Sets the target FPS for the Game Loop to run. */
- void setTargetFPS (unsigned fps) { this->f_target_delta_t = 1.f/fps; }
- /** @brief Sets the target FPS to bound the logic section of the Game Loop. */
- void setTargetGameLogicLoopFPS (unsigned state_fps) { this->f_target_step_t = 1.f/state_fps; }
- void levelStart (Level &lv, ArcadeFighter::delta_time_style_e style = GAME_LOOP_STYLE);
- };//END ArcadeFighter
- #endif //_ARCADE_FIGHTER_H_
|