2022-11-08 17:16:05 -05:00
|
|
|
/* +------------------------------------------------------+
|
|
|
|
____/ \____ /| - Open source game framework licensed to freely use, |
|
|
|
|
\ / / | copy, modify and sell without restriction |
|
|
|
|
+--\ ^__^ /--+ | |
|
|
|
|
| ~/ \~ | | - created for <https://foam.shampoo.ooo> |
|
|
|
|
| ~~~~~~~~~~~~ | +------------------------------------------------------+
|
|
|
|
| SPACE ~~~~~ | /
|
|
|
|
| ~~~~~~~ BOX |/
|
|
|
|
+-------------*/
|
|
|
|
|
2022-06-16 16:45:41 -04:00
|
|
|
#pragma once
|
2019-04-23 01:42:19 -04:00
|
|
|
|
2021-06-26 20:25:03 -04:00
|
|
|
#include <stdlib.h>
|
2020-09-04 23:10:39 -04:00
|
|
|
#include <vector>
|
2019-04-23 01:42:19 -04:00
|
|
|
#include <string>
|
|
|
|
#include <iostream>
|
|
|
|
#include <sstream>
|
2021-05-08 20:01:53 -04:00
|
|
|
#include <ctime>
|
2021-07-02 22:42:48 -04:00
|
|
|
#include <fstream>
|
2019-04-23 01:42:19 -04:00
|
|
|
|
|
|
|
#define SDL_MAIN_HANDLED
|
2020-09-04 23:10:39 -04:00
|
|
|
#include "SDL.h"
|
|
|
|
#include "SDL_mixer.h"
|
|
|
|
#include "SDL_ttf.h"
|
2019-04-23 01:42:19 -04:00
|
|
|
|
|
|
|
#define GL_GLEXT_PROTOTYPES
|
|
|
|
#define GLEW_STATIC
|
2020-06-27 17:47:14 -04:00
|
|
|
#if defined(__EMSCRIPTEN__)
|
|
|
|
#include <emscripten.h>
|
|
|
|
#include <emscripten/html5.h>
|
|
|
|
#include <GL/glew.h>
|
2022-10-17 21:57:56 -04:00
|
|
|
#elif defined(__ANDROID__) || defined(ANDROID)
|
|
|
|
#include <GLES3/gl3.h>
|
|
|
|
#include <GLES3/gl3ext.h>
|
2020-06-27 17:47:14 -04:00
|
|
|
#else
|
2019-04-29 19:27:13 -04:00
|
|
|
#include "glew/glew.h"
|
2020-06-27 17:47:14 -04:00
|
|
|
#endif
|
|
|
|
|
2022-11-08 17:16:05 -05:00
|
|
|
#if defined(__ANDROID__) || defined(ANDROID)
|
|
|
|
#include <android/log.h>
|
|
|
|
#endif
|
|
|
|
|
2019-04-23 01:42:19 -04:00
|
|
|
#include "Node.hpp"
|
2019-05-18 17:39:47 -04:00
|
|
|
#include "Input.hpp"
|
2020-09-04 23:10:39 -04:00
|
|
|
#include "Display.hpp"
|
|
|
|
#include "Configuration.hpp"
|
|
|
|
#include "Delegate.hpp"
|
2020-07-19 15:43:47 -04:00
|
|
|
#include "Recorder.hpp"
|
2020-09-04 23:10:39 -04:00
|
|
|
#include "Sprite.hpp"
|
2020-09-11 18:01:27 -04:00
|
|
|
#include "Audio.hpp"
|
2021-10-02 19:21:07 -04:00
|
|
|
#include "Log.hpp"
|
2021-07-02 22:42:48 -04:00
|
|
|
#include "filesystem.hpp"
|
|
|
|
#include "extension.hpp"
|
2019-06-16 03:05:02 -04:00
|
|
|
|
2021-09-24 02:43:38 -04:00
|
|
|
class FramerateIndicator : public Sprite
|
2020-07-19 15:43:47 -04:00
|
|
|
{
|
2019-06-16 03:05:02 -04:00
|
|
|
|
2021-09-24 02:43:38 -04:00
|
|
|
public:
|
|
|
|
|
2020-07-19 15:43:47 -04:00
|
|
|
FramerateIndicator(Node*);
|
|
|
|
void respond(SDL_Event&);
|
|
|
|
SDL_Surface* get_surface();
|
|
|
|
void refresh();
|
2019-06-16 03:05:02 -04:00
|
|
|
|
2020-07-19 15:43:47 -04:00
|
|
|
};
|
2019-04-23 01:42:19 -04:00
|
|
|
|
2021-06-24 17:40:30 -04:00
|
|
|
class Game : public Node
|
2019-04-23 01:42:19 -04:00
|
|
|
{
|
|
|
|
|
2021-06-24 17:40:30 -04:00
|
|
|
private:
|
|
|
|
|
2021-08-02 20:18:56 -04:00
|
|
|
int ticks;
|
|
|
|
float frame_length = 1000.0 / 60.0;
|
2022-06-16 16:45:41 -04:00
|
|
|
Configuration _configuration {this};
|
|
|
|
SDL_Window* _window;
|
2021-08-02 20:18:56 -04:00
|
|
|
|
2022-11-08 17:16:05 -05:00
|
|
|
/*!
|
|
|
|
* Overrides SDL's default log function to log a message to stdout/stderr and, if log is enabled in the
|
|
|
|
* global configuration, to a file. Debug level statements may be suppressed, printed to stdout, or printed to
|
|
|
|
* both stdout and file, depending on the global configuration. This shouldn't be called directly. Use
|
|
|
|
* `sb::Log::log` instead.
|
|
|
|
*
|
|
|
|
* @see sb::Log::log(const std::string&)
|
|
|
|
*
|
|
|
|
* @param userdata must be a pointer to Game
|
|
|
|
* @param category SDL log category. It is not used by SPACEBOX, so it should be sb::Log::DEFAULT_CATEGORY
|
|
|
|
* @param priority SDL log priority, which is equivalent to the values in sb::Log::Level
|
|
|
|
* @param message message as a C-style string
|
|
|
|
*/
|
|
|
|
static void sdl_log_override(void* userdata, int category, SDL_LogPriority priority, const char* message);
|
2021-06-24 17:40:30 -04:00
|
|
|
|
|
|
|
public:
|
2021-08-02 20:18:56 -04:00
|
|
|
|
2021-08-31 23:55:38 -04:00
|
|
|
/* two-state enum equivalent to a boolean that can improve readability depending on the context */
|
|
|
|
enum class Flip {
|
|
|
|
OFF,
|
|
|
|
ON
|
|
|
|
};
|
|
|
|
|
2021-08-02 20:18:56 -04:00
|
|
|
/* Prevent an instance of this class from being copied or moved */
|
2019-04-23 01:42:19 -04:00
|
|
|
Game(const Game&) = delete;
|
|
|
|
Game& operator=(const Game&) = delete;
|
|
|
|
Game(Game&&) = delete;
|
|
|
|
Game& operator=(Game&&) = delete;
|
|
|
|
|
2021-07-02 22:42:48 -04:00
|
|
|
SDL_Renderer* renderer = nullptr;
|
|
|
|
SDL_GLContext glcontext = nullptr;
|
2021-08-02 20:18:56 -04:00
|
|
|
int frame_count_this_second = 0, last_frame_length;
|
|
|
|
float frame_time_overflow = 0, last_frame_timestamp, last_frame_count_timestamp;
|
2019-07-21 03:13:19 -04:00
|
|
|
bool done = false, show_framerate = true, is_gl_context = true;
|
2021-11-19 14:13:37 -05:00
|
|
|
Delegate delegate {this};
|
|
|
|
sb::Display display {this};
|
|
|
|
Recorder recorder {this};
|
|
|
|
Input input {this};
|
|
|
|
Audio audio {this};
|
2020-07-13 00:53:12 -04:00
|
|
|
std::vector<float> frame_length_history;
|
2021-08-31 23:55:38 -04:00
|
|
|
TTF_Font* bp_mono_font = nullptr;
|
2021-11-19 14:13:37 -05:00
|
|
|
FramerateIndicator framerate_indicator {this};
|
2019-04-23 01:42:19 -04:00
|
|
|
|
|
|
|
Game();
|
2020-08-19 03:29:46 -04:00
|
|
|
virtual void reset() { activate(); }
|
2020-07-13 00:53:12 -04:00
|
|
|
void print_frame_length_history();
|
2019-04-23 01:42:19 -04:00
|
|
|
void load_sdl_context();
|
|
|
|
void load_gl_context();
|
2021-07-02 22:42:48 -04:00
|
|
|
GLuint load_shader(const fs::path&, GLenum) const;
|
|
|
|
bool link_shader(GLuint program) const;
|
2020-08-28 22:17:01 -04:00
|
|
|
void log_renderer_info(SDL_RendererInfo&);
|
2022-10-07 18:29:25 -04:00
|
|
|
|
|
|
|
/*!
|
|
|
|
* Write resolution, monitor refresh rate, and pixel format to the log. Taken from SDL_GetCurrentDisplayMode.html
|
|
|
|
* on the SDL wiki.
|
|
|
|
*/
|
|
|
|
void log_display_mode() const;
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* Log properties of the GL context. Taken from `sdl_source/tests/testgles2.c`
|
|
|
|
*/
|
|
|
|
void log_gl_properties() const;
|
|
|
|
|
2019-06-16 03:05:02 -04:00
|
|
|
void log_surface_format(SDL_Surface*, std::string = "surface");
|
2022-06-16 16:45:41 -04:00
|
|
|
const nlohmann::json& configuration() const;
|
|
|
|
nlohmann::json& configuration();
|
|
|
|
const SDL_Window* window() const;
|
|
|
|
SDL_Window* window();
|
2020-08-09 16:32:32 -04:00
|
|
|
const SDL_Renderer* get_renderer() const;
|
2020-06-27 17:47:14 -04:00
|
|
|
SDL_Renderer* get_renderer();
|
2020-08-19 03:29:46 -04:00
|
|
|
const Input& get_input() const;
|
|
|
|
Input& get_input();
|
2020-09-11 18:01:27 -04:00
|
|
|
Audio& get_audio();
|
2019-04-23 01:42:19 -04:00
|
|
|
void run();
|
2020-06-27 17:47:14 -04:00
|
|
|
void frame(float);
|
2019-04-23 01:42:19 -04:00
|
|
|
void flag_to_end();
|
2019-05-03 02:09:48 -04:00
|
|
|
virtual void update() {};
|
2019-04-23 01:42:19 -04:00
|
|
|
void set_framerate(int);
|
2021-08-02 20:18:56 -04:00
|
|
|
float get_frame_length() const;
|
2019-05-04 03:25:35 -04:00
|
|
|
void handle_quit_event(SDL_Event&);
|
2019-04-23 01:42:19 -04:00
|
|
|
void quit();
|
2021-08-14 19:53:39 -04:00
|
|
|
virtual std::string class_name() const { return "Game"; }
|
2021-07-02 22:42:48 -04:00
|
|
|
~Game();
|
2019-04-23 01:42:19 -04:00
|
|
|
|
2022-11-08 17:16:05 -05:00
|
|
|
/*!
|
|
|
|
* Applies delta timing to a value: returns the value as weighted by the amount of time passed since the
|
2022-07-23 18:55:27 -04:00
|
|
|
* last frame update, allowing for values to change the same amount over time independent of the frame rate.
|
2022-11-08 17:16:05 -05:00
|
|
|
* The amount is how much the value should change per second.
|
|
|
|
*
|
|
|
|
* @param amount any scalar value to be weighted
|
|
|
|
* @return weighted value
|
|
|
|
*/
|
2019-04-23 01:42:19 -04:00
|
|
|
template<typename T>
|
2022-07-23 18:55:27 -04:00
|
|
|
T weight(T amount)
|
2019-04-23 01:42:19 -04:00
|
|
|
{
|
|
|
|
return (last_frame_length / (1000.0 / 60)) * amount;
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
2020-06-27 17:47:14 -04:00
|
|
|
#if defined(__EMSCRIPTEN__)
|
|
|
|
|
|
|
|
void loop(void*);
|
|
|
|
|
|
|
|
#endif
|