spacebox/src/Display.hpp
Cocktail Frank bef0960109 Add support for storing and loading user preferences
A field is added to the configuration object for user preferences at
"storage" > "preferences file", corresponding to a
sb::progress::Progress object at sb::Game::preferences. If the file
exists, load and merge into the configuration at sb::Game construction
time. This allows the project to save user preferences using
sb::Game::preferences.

Update sb::Game constructor to merge CLI and constructor config
overrides into the configuration multiple times during the configuration
load phase to make sure the overrides apply to each configuration loaded
during the phase.

Add an overload to sb::progress::Progress::config for setting a single
field of the config section, using the same signature as
sb::progress::Progress::set.

Added a function to sb::Display for getting the fullscreen status of a
sb::Game object's window.
2024-11-01 19:09:55 -04:00

112 lines
4.7 KiB
C++

/* +-------------------------------------------------------+
____/ \____ /| Open source game framework licensed to freely use, |
\ / / | copy, and modify - created for dank.game |
+--\ ^__^ /--+ | |
| ~/ \~ | | Download at https://open.shampoo.ooo/shampoo/spacebox |
| ~~~~~~~~~~~~ | +-------------------------------------------------------+
| SPACE ~~~~~ | /
| ~~~~~~~ BOX |/
+--------------+
Access the game's window/screen. The intention of this class is that only one object will exist per game, and it will
act as a "manager of the game's display", rather than corresponding to one of potentially many specific displays.
This means it probably shouldn't ever be instantiated directly because it is already created by the game object and can
be accessed through the game object. This class will probably be reorganized in the future — see the warning below.
@warning As this framework is reorganized, this class will probably be replaced in favor of using a Window class to
allow access to one or more displays which can be created and removed arbitrarily while the program is running.
*/
#pragma once
#include <sstream>
#include "glm/vec2.hpp"
#include "SDL.h"
#include "SDL_image.h"
#include "sdl2-gfx/SDL2_gfxPrimitives.h"
#include "sdl2-gfx/SDL2_rotozoom.h"
#if defined(__EMSCRIPTEN__)
#include "emscripten/html5.h"
#endif
#include "Node.hpp"
#include "Box.hpp"
#include "Log.hpp"
namespace sb
{
class Display : public Node
{
public:
const static int bpp = 32;
inline const static Box ndc {-1.0f, -1.0f, 2.0f, 2.0f, true};
Display(Node*);
glm::ivec2 window_size() const;
Uint32 pixel_format(int = 0) const;
Box window_box(bool = false) const;
Box ndc_subsection(const Box&) const;
Box ndc_to_pixel(const Box&) const;
/*!
* Fill the supplied, pre-allocated buffer with 32-bit pixels (8 bits per component) from the GL read buffer.
* This buffer of unsigned 8-bit values must be large enough to hold w x h x 32-bits of data
*
* @param pixels Pre-allocated, unsigned 8-bit buffer that will be filled with pixel color data
* @param w Size in width of the region to read from the GL read buffer
* @param h Size in height of the region to read from the GL read buffer
* @param x X position of the corner to start reading from in the GL read buffer
* @param y Y position of the corner to start reading from in the GL read buffer
*/
void screen_pixels(unsigned char* pixels, int w, int h, int x = 0, int y = 0) const;
SDL_Surface* screen_surface() const;
SDL_Surface* screen_surface_from_pixels(unsigned char* pixels, bool flip = true) const;
/*!
* Respond to full screen requests and window resize events. If fluid resize is enabled in the configuration,
* respond to resize events as the screen is being resized, otherwise respond once when the resize is finished.
*
* The display object subscribes to SDL events in its constructor, so this function will be called automatically
* by sb::Delegate::dispatch when an event happens.
*
* @param event an SDL event
*/
void respond(SDL_Event& event);
/*!
* Set window to fullscreen if it is not currently displayed fullscreen, otherwise exit fullscreen.
*
* In builds other than Emscripten, this uses the SDL_WINDOW_FULLSCREEN_DESKTOP flag to create a fullscreen
* window. SDL creates the fullscreen window without changing video modes by resizing the window to the size of
* desktop and removing borders.
*
* Emscripten builds use `emscripten_request_fullscreen()` instead, which handles fullscreen from web browsers
* more smoothly.
*
* If "display" > "fullscreen enabled" is false in the configuration, this function does nothing.
*/
void toggle_fullscreen() const;
/*!
* Check the state of whether the window is fullscreen or not. The window in question is the game object's
* window, returned by Game::window(), which is the only window SPACE🪐BOX currently supports.
*
* If this is not an Emscripten build, this uses `SDL_GetWindowFlags` to check the status of the window.
*
* If it is an Emscripten build, `emscripten_get_fullscreen_status` is used instead.
*
* @return True if the window is currently fullscreen, false otherwise
*/
bool fullscreen_status() const;
};
}