mirror of
https://github.com/open-goal/jak-project
synced 2026-08-03 00:47:12 -04:00
b6649d2433
Prior to SDL3, borderless windows were kinda a hack, they cleaned all of that up. The side-effect of that is that the C++ code keeps track of the current window size (it does this for framebuffer sizing, but also to set the size of the window). This is now an issue because SDL is properly firing events when you change to borderless mode, so our window size gets updated to the size of the entire monitor. When you switch to windowed mode from borderless, it now seems like it didn't work (it did, its just still taking up the entire screen). This could be better cleaned up if more settings are extracted out of GOAL and put into C++ so they can be managed and accessed where they belong. But for now, this is a minimally invasive fix. Fixes #3917
145 lines
4.9 KiB
C++
145 lines
4.9 KiB
C++
#pragma once
|
|
|
|
#include <mutex>
|
|
#include <optional>
|
|
#include <queue>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <variant>
|
|
|
|
#include "game/settings/settings.h"
|
|
#include "game/system/hid/input_manager.h"
|
|
|
|
#include "third-party/SDL/include/SDL3/SDL.h"
|
|
|
|
/*
|
|
TODO:
|
|
- hiDPI support, see https://wiki.libsdl.org/SDL2/SDL_GetRendererOutputSize
|
|
*/
|
|
|
|
enum class WindowState { Minimized, Maximized, Restored };
|
|
|
|
enum class Orientation { Landscape, LandscapeFlipped, Portrait, PortraitFlipped, Unknown };
|
|
|
|
/// https://wiki.libsdl.org/SDL3/SDL_DisplayMode
|
|
struct DisplayMode {
|
|
SDL_DisplayID sdl_display_id;
|
|
std::string display_name;
|
|
/// https://wiki.libsdl.org/SDL3/SDL_PixelFormat
|
|
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 {
|
|
private:
|
|
enum class EEDisplayEventType { SET_WINDOW_SIZE, SET_DISPLAY_MODE, SET_DISPLAY_ID };
|
|
game_settings::DisplaySettings::DisplayMode m_previous_fullscreen_display_mode =
|
|
game_settings::DisplaySettings::DisplayMode::Fullscreen;
|
|
struct EEDisplayEvent {
|
|
EEDisplayEventType type;
|
|
std::variant<bool, int, game_settings::DisplaySettings::DisplayMode> param1;
|
|
std::variant<bool, int> param2;
|
|
std::variant<int> param3;
|
|
};
|
|
|
|
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);
|
|
/// Any event coming from the EE thread that interacts directly with SDL should be enqueued as an
|
|
/// event so it can be ran from the proper thread context (the graphics thread)
|
|
void process_ee_events();
|
|
|
|
int get_active_display_index() { return m_display_settings.display_id; }
|
|
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; }
|
|
int get_window_game_width() { return m_window_game_width; }
|
|
int get_window_game_height() { return m_window_game_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();
|
|
game_settings::DisplaySettings::DisplayMode get_display_mode() {
|
|
return m_display_settings.display_mode;
|
|
}
|
|
int get_num_resolutions(bool for_window_size);
|
|
Resolution get_resolution(int id, bool for_window_size);
|
|
bool is_supported_resolution(int width, int height);
|
|
|
|
// Mutators
|
|
void enqueue_set_window_size(int width, int height);
|
|
void enqueue_set_window_display_mode(game_settings::DisplaySettings::DisplayMode mode,
|
|
const int window_width,
|
|
const int window_height);
|
|
void toggle_display_mode();
|
|
void enqueue_set_display_id(int display_id);
|
|
|
|
void set_game_size(int width, int height) {
|
|
m_window_game_width = width;
|
|
m_window_game_height = height;
|
|
}
|
|
|
|
void set_input_manager(std::shared_ptr<InputManager> input_manager) {
|
|
m_input_manager = input_manager;
|
|
}
|
|
|
|
private:
|
|
SDL_Window* m_window;
|
|
game_settings::DisplaySettings m_display_settings;
|
|
std::optional<std::shared_ptr<InputManager>> m_input_manager;
|
|
|
|
std::mutex event_queue_mtx;
|
|
std::queue<EEDisplayEvent> ee_event_queue;
|
|
|
|
int m_window_xpos = 0;
|
|
int m_window_ypos = 0;
|
|
int m_window_width = 0;
|
|
int m_window_height = 0;
|
|
int m_window_game_width = 0;
|
|
int m_window_game_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::vector<DisplayMode> m_current_display_modes;
|
|
std::vector<Resolution> m_available_resolutions;
|
|
std::vector<Resolution> m_available_window_sizes;
|
|
|
|
void initialize_window_position_from_settings();
|
|
void update_curr_display_info();
|
|
void update_video_modes();
|
|
void update_resolutions();
|
|
|
|
void set_window_size(int width, int height);
|
|
void set_display_mode(game_settings::DisplaySettings::DisplayMode mode,
|
|
const int window_width,
|
|
const int window_height);
|
|
void set_display_id(int display_id);
|
|
};
|