mirror of
https://github.com/open-goal/jak-project.git
synced 2024-10-06 19:03:24 +00:00
game: ensure the default game-size
is also valid when initializing the pc-settings.gc
file (#3624)
Also saves out the default `pc-settings.gc` file so it's less confusing _and_ so we can request it from users to actually see what it's doing. The fix in the last release was only to fix bad `game-size` values when _loading_ the file. But if you don't have a file, it picks a default. Right now it picks that default by: 1. Your largest reported resolution 2. If that fails, the one that is currently set In reality this scenario can never really happen (if you have a set resolution, it will be one of the reported ones). However what can happen is for SDL to be misinformed by bad display/monitor drivers/the OS and be given "supported" resolutions that aren't actually supported. For example some users have a 4K resolution as their highest, despite them using a 1080p monitor. The solution is to not blindly assume the largest resolution is valid, instead use the one the user already has set. I'm also now filtering out resolutions by refresh rate, as perhaps this also caused a problem. ie. the monitor supports a resolution if the refresh rate is lowered, but it's currently set high (at 144hz for example).
This commit is contained in:
parent
a13b0dce45
commit
8b7e0bde53
@ -322,3 +322,6 @@ endif()
|
||||
|
||||
add_executable(gk main.cpp)
|
||||
target_link_libraries(gk runtime)
|
||||
if(WIN32)
|
||||
set_target_properties(gk PROPERTIES VS_DPI_AWARE "PerMonitor")
|
||||
endif()
|
||||
|
@ -187,7 +187,7 @@ Resolution DisplayManager::get_resolution(int id) {
|
||||
}
|
||||
|
||||
bool DisplayManager::is_supported_resolution(int width, int height) {
|
||||
for (const auto resolution : m_available_resolutions) {
|
||||
for (const auto& resolution : m_available_resolutions) {
|
||||
if (resolution.width == width && resolution.height == height) {
|
||||
return true;
|
||||
}
|
||||
@ -358,6 +358,10 @@ void DisplayManager::update_video_modes() {
|
||||
DisplayMode new_mode = {display_name_str, curr_mode.format, curr_mode.w,
|
||||
curr_mode.h, curr_mode.refresh_rate, orient};
|
||||
m_current_display_modes[display_id] = new_mode;
|
||||
lg::info(
|
||||
"[DISPLAY]: Found monitor {}, currently set to {}x{}@{}hz. Format: {}, Orientation: {}",
|
||||
new_mode.display_name, new_mode.screen_width, new_mode.screen_height, new_mode.refresh_rate,
|
||||
new_mode.sdl_pixel_format, static_cast<int>(new_mode.orientation));
|
||||
}
|
||||
update_resolutions();
|
||||
}
|
||||
@ -365,17 +369,29 @@ void DisplayManager::update_video_modes() {
|
||||
void DisplayManager::update_resolutions() {
|
||||
lg::info("[DISPLAY] Enumerating resolutions");
|
||||
// Enumerate display's display modes to get the resolutions
|
||||
auto num_display_modes = SDL_GetNumDisplayModes(get_active_display_id());
|
||||
const auto active_display_id = get_active_display_id();
|
||||
const auto active_refresh_rate = m_current_display_modes[active_display_id].refresh_rate;
|
||||
auto num_display_modes = SDL_GetNumDisplayModes(active_display_id);
|
||||
SDL_DisplayMode curr_mode;
|
||||
for (int i = 0; i < num_display_modes; i++) {
|
||||
auto ok = SDL_GetDisplayMode(get_active_display_id(), i, &curr_mode);
|
||||
auto ok = SDL_GetDisplayMode(active_display_id, i, &curr_mode);
|
||||
if (ok != 0) {
|
||||
sdl_util::log_error(fmt::format("unable to get display mode for display {}, index {}",
|
||||
get_active_display_id(), i));
|
||||
sdl_util::log_error(
|
||||
fmt::format("unable to get display mode for display {}, index {}", active_display_id, i));
|
||||
continue;
|
||||
}
|
||||
// Skip resolutions that aren't using the current refresh rate, they won't work.
|
||||
// For example if your monitor is currently set to `60hz` and the monitor _could_ support
|
||||
// resolution X but only at `30hz`...then there's no reason for us to consider it as an option.
|
||||
if (curr_mode.refresh_rate != active_refresh_rate) {
|
||||
lg::debug(
|
||||
"[DISPLAY]: Skipping {}x{} as it requires {}hz but the monitor is currently set to {}hz",
|
||||
curr_mode.w, curr_mode.h, curr_mode.refresh_rate, active_refresh_rate);
|
||||
continue;
|
||||
}
|
||||
Resolution new_res = {curr_mode.w, curr_mode.h,
|
||||
static_cast<float>(curr_mode.w) / static_cast<float>(curr_mode.h)};
|
||||
lg::info("[DISPLAY]: {}x{} is supported", new_res.width, new_res.height);
|
||||
m_available_resolutions.push_back(new_res);
|
||||
}
|
||||
|
||||
|
@ -34,13 +34,14 @@
|
||||
(defmethod set-window-size! ((obj pc-settings) (width int) (height int))
|
||||
"sets the size of the display window"
|
||||
(let ((display-mode (pc-get-display-mode)))
|
||||
(format 0 "Setting ~A size to ~D x ~D~%" display-mode width height)
|
||||
(cond
|
||||
((= display-mode 'windowed)
|
||||
(set! (-> obj window-width) width)
|
||||
(set! (-> obj window-height) height)
|
||||
(format 0 "Setting window size to ~D x ~D~%" width height)
|
||||
(pc-set-window-size! (max PC_MIN_WIDTH (-> obj window-width)) (max PC_MIN_HEIGHT (-> obj window-height))))
|
||||
(else
|
||||
(format 0 "Setting borderless/fullscreen size to ~D x ~D~%" width height)
|
||||
(set! (-> obj width) width)
|
||||
(set! (-> obj height) height))))
|
||||
(none))
|
||||
@ -642,7 +643,11 @@
|
||||
(unless (read-from-file obj *pc-temp-string-1*)
|
||||
(format 0 "[PC] PC Settings found at '~S' but could not be loaded, using defaults!~%" *pc-temp-string-1*)
|
||||
(reset obj #t)))
|
||||
(else (format 0 "[PC] PC Settings not found at '~S'...initializing with defaults!~%" *pc-temp-string-1*) (reset obj #t)))
|
||||
(else
|
||||
(format 0 "[PC] PC Settings not found at '~S'...initializing with defaults!~%" *pc-temp-string-1*)
|
||||
(reset obj #t)
|
||||
;; save the file so users aren't confused, and so we can debug what the game is producing for them
|
||||
(commit-to-file obj)))
|
||||
0)
|
||||
|
||||
(defmethod initialize ((obj pc-settings))
|
||||
|
@ -318,18 +318,21 @@
|
||||
(set! (-> obj aspect-ratio-auto?) #t)
|
||||
(set! (-> obj vsync?) #t)
|
||||
(set! (-> obj letterbox?) #t)
|
||||
;; get screen size and set to borderless at screen res (if retail)
|
||||
(cond
|
||||
((> (pc-get-num-resolutions) 0)
|
||||
;; pick first available resolution by default
|
||||
(pc-get-resolution 0 (&-> obj width) (&-> obj height)))
|
||||
(else
|
||||
;; somehow didn't get a single resolution. this is pretty bad.
|
||||
(pc-get-active-display-size (&-> obj width) (&-> obj height))
|
||||
(max! (-> obj width) PC_MIN_WIDTH)
|
||||
(max! (-> obj height) PC_MIN_HEIGHT)
|
||||
(format 0 "!!!! failed to get any screen resolutions !!!!")))
|
||||
(format 0 "fullscreen resolution defaulted to ~D x ~D~%" (-> obj width) (-> obj height))
|
||||
;; default to the displays currently chosen resolution
|
||||
(pc-get-active-display-size (&-> obj width) (&-> obj height))
|
||||
(max! (-> obj width) PC_MIN_WIDTH)
|
||||
(max! (-> obj height) PC_MIN_HEIGHT)
|
||||
;; ensure the default resolution was a valid choice
|
||||
(let* ((saved-width (-> obj width))
|
||||
(saved-height (-> obj height))
|
||||
(supported-resolution? (pc-is-supported-resolution? saved-width saved-height)))
|
||||
(cond
|
||||
(supported-resolution?
|
||||
(format 0 "[PC Settings]: Valid default game-size resolution set ~D x ~D~%" saved-width saved-height))
|
||||
(else
|
||||
(pc-get-active-display-size (&-> obj width) (&-> obj height))
|
||||
(format 0 "[PC Settings]: Invalid game-size resolution ~D x ~D, defaulting to ~D x ~D~%" saved-width saved-height (-> obj width) (-> obj height)))))
|
||||
(format 0 "[PC Settings]: fullscreen resolution defaulted to ~D x ~D~%" (-> obj width) (-> obj height))
|
||||
(set! (-> obj gfx-msaa) PC_DEFAULT_MSAA) ;; default msaa
|
||||
0)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user