Files
jak-project/game/system/hid/display_manager.h
T

104 lines
3.4 KiB
C++

#pragma once
#include <optional>
#include <string>
#include <unordered_map>
#include "game/settings/settings.h"
#include "third-party/SDL/include/SDL.h"
/*
TODO:
- hiDPI support, see https://wiki.libsdl.org/SDL2/SDL_GetRendererOutputSize
*/
enum class WindowDisplayMode { Windowed = 0, Fullscreen = 1, Borderless = 2 };
enum class WindowState { Minimized, Maximized, Restored };
enum class Orientation { Landscape, LandscapeFlipped, Portrait, PortraitFlipped, Unknown };
/// https://wiki.libsdl.org/SDL2/SDL_DisplayMode
struct DisplayMode {
/// https://wiki.libsdl.org/SDL2/SDL_PixelFormatEnum
uint32_t sdl_pixel_format;
int screen_width;
int screen_height;
/// refresh rate (in Hz), or 0 for unspecified
int refresh_rate;
Orientation orientation;
};
// Describes an available resolution
struct Resolution {
int width;
int height;
float aspect_ratio;
};
/// Monitors and handles all SDL events related to monitors and the window position
/// Stores related info for other parts of the application to use
/// Manages display related operations and querying
class DisplayManager {
public:
DisplayManager(SDL_Window* window);
~DisplayManager();
/// Propagate and handle the SDL event, ignoring it if it's not relevant
void process_sdl_event(const SDL_Event& event);
// Accessors
bool is_window_active() { return m_window != nullptr; }
bool is_minimized() { return m_window_state == WindowState::Minimized; }
int get_window_width() { return m_window_width; }
int get_window_height() { return m_window_height; }
float get_window_scale_x() { return m_window_scale_x; }
float get_window_scale_y() { return m_window_scale_y; }
int num_connected_displays() { return m_current_display_modes.size(); }
std::string get_connected_display_name(int id);
int get_active_display_refresh_rate();
int get_screen_width();
int get_screen_height();
WindowDisplayMode get_window_display_mode() { return m_window_display_mode; }
Resolution get_resolution(int id);
int get_num_resolutions() { return m_available_resolutions.size(); }
// Mutators
void set_window_resizable(bool resizable);
void set_window_size(int width, int height);
void initialize_window_position_from_settings();
void set_window_display_mode(WindowDisplayMode mode);
void set_fullscreen_display_id(int display_id);
private:
SDL_Window* m_window;
game_settings::DisplaySettings m_display_settings;
WindowDisplayMode m_window_display_mode = WindowDisplayMode::Windowed;
int m_active_display_id;
// This can differ from the active display id, this is set by the game
// to explicitly define which monitor the game should be fullscreened with
int m_selected_fullscreen_display_id;
int m_window_xpos = 0;
int m_window_ypos = 0;
int m_window_width = 0;
int m_window_height = 0;
float m_window_scale_x = 1.0;
float m_window_scale_y = 1.0;
WindowState m_window_state = WindowState::Restored;
// The currently set display mode for each display
// There is no reason to keep track of all display modes for all monitors
// the only one that matters is the one the user _currently_ has configured
//
// ie. allowing someone to set 150fps on a monitor set to 60hz is not correct
std::unordered_map<int, DisplayMode> m_current_display_modes;
std::vector<Resolution> m_available_resolutions;
void update_curr_display_info();
void update_video_modes();
void update_resolutions();
};