Skip to content

Commit

Permalink
game: cleanup some display settings related code, forbid invalid `gam…
Browse files Browse the repository at this point in the history
…e-size` resolutions (#3601)

Fixes #3563

These users have the following spamming in logs:
> OpenGL error 0x502 S8246 T824C: GL_INVALID_OPERATION error generated.
Source and destination dimensions must be identical with the current
filtering modes.

And the solution is to correctly set their game-size. The way this
change accomplishes that is by confirming whether or not the set
`game-size` is a valid resolution informed by SDL, if not, it defaults
to the monitor's currently set display mode's resolution.

This also moves the selected display id, and the display mode into the
C++ settings -- closer to where it's actually managed and used. I'm
tempted to do this eventually for the resolutions as well but that stuff
is much more burdensome. This hopefully simplifies debugging, reduces
startup flickering, and removes back-and-forth complexity. Hopefully
this makes debugging display related problems easier. It also adds a
bunch more logging to the related code.
  • Loading branch information
xTVaser authored Jul 28, 2024
1 parent ce97863 commit d819d6d
Show file tree
Hide file tree
Showing 18 changed files with 247 additions and 218 deletions.
1 change: 0 additions & 1 deletion .vs/launch.vs.json
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,6 @@
"name": "Game - Jak 1 - Runtime (boot)",
"args": [
"-v",
"--portable",
"--game",
"jak1",
"--",
Expand Down
1 change: 1 addition & 0 deletions common/formatter/rules/rule_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ static FormFormattingConfig new_top_level_inline_form(bool elide_new_line) {

const std::unordered_map<std::string, FormFormattingConfig> opengoal_form_config = {
{"case", new_pair_rule(true)},
{"case-str", new_pair_rule(true)},
{"cond", new_pair_rule(false)},
{"#cond", new_pair_rule(false)},
{"in-package", new_top_level_inline_form(true)},
Expand Down
50 changes: 33 additions & 17 deletions game/kernel/common/kmachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,19 @@ u64 pc_get_mips2c(u32 name) {
return Mips2C::gLinkedFunctionTable.get(n);
}

u64 pc_get_display_id() {
if (Display::GetMainDisplay()) {
return Display::GetMainDisplay()->get_display_manager()->get_active_display_id();
}
return 0;
}

void pc_set_display_id(u64 display_id) {
if (Display::GetMainDisplay()) {
Display::GetMainDisplay()->get_display_manager()->enqueue_set_display_id(display_id);
}
}

u64 pc_get_display_name(u32 id, u32 str_dest_ptr) {
std::string name = "";
if (Display::GetMainDisplay()) {
Expand All @@ -469,17 +482,16 @@ u64 pc_get_display_name(u32 id, u32 str_dest_ptr) {
}

u32 pc_get_display_mode() {
auto display_mode = WindowDisplayMode::Windowed;
auto display_mode = game_settings::DisplaySettings::DisplayMode::Windowed;
if (Display::GetMainDisplay()) {
display_mode = Display::GetMainDisplay()->get_display_manager()->get_window_display_mode();
display_mode = Display::GetMainDisplay()->get_display_manager()->get_display_mode();
}
switch (display_mode) {
case WindowDisplayMode::Borderless:
case game_settings::DisplaySettings::DisplayMode::Borderless:
return g_pc_port_funcs.intern_from_c("borderless").offset;
case WindowDisplayMode::Fullscreen:
case game_settings::DisplaySettings::DisplayMode::Fullscreen:
return g_pc_port_funcs.intern_from_c("fullscreen").offset;
default:
case WindowDisplayMode::Windowed:
return g_pc_port_funcs.intern_from_c("windowed").offset;
}
}
Expand All @@ -490,13 +502,13 @@ void pc_set_display_mode(u32 symptr) {
}
if (symptr == g_pc_port_funcs.intern_from_c("windowed").offset || symptr == s7.offset) {
Display::GetMainDisplay()->get_display_manager()->enqueue_set_window_display_mode(
WindowDisplayMode::Windowed);
game_settings::DisplaySettings::DisplayMode::Windowed);
} else if (symptr == g_pc_port_funcs.intern_from_c("borderless").offset) {
Display::GetMainDisplay()->get_display_manager()->enqueue_set_window_display_mode(
WindowDisplayMode::Borderless);
game_settings::DisplaySettings::DisplayMode::Borderless);
} else if (symptr == g_pc_port_funcs.intern_from_c("fullscreen").offset) {
Display::GetMainDisplay()->get_display_manager()->enqueue_set_window_display_mode(
WindowDisplayMode::Fullscreen);
game_settings::DisplaySettings::DisplayMode::Fullscreen);
}
}

Expand Down Expand Up @@ -568,12 +580,6 @@ void pc_get_window_scale(u32 x_ptr, u32 y_ptr) {
}
}

void pc_get_fullscreen_display(u64 display_id) {
if (Display::GetMainDisplay()) {
Display::GetMainDisplay()->get_display_manager()->enqueue_set_fullscreen_display_id(display_id);
}
}

void pc_set_window_size(u64 width, u64 height) {
if (Display::GetMainDisplay()) {
Display::GetMainDisplay()->get_display_manager()->enqueue_set_window_size(width, height);
Expand Down Expand Up @@ -601,6 +607,14 @@ void pc_get_resolution(u32 id, u32 w_ptr, u32 h_ptr) {
}
}

u64 pc_is_supported_resolution(u64 width, u64 height) {
if (Display::GetMainDisplay()) {
return bool_to_symbol(
Display::GetMainDisplay()->get_display_manager()->is_supported_resolution(width, height));
}
return bool_to_symbol(false);
}

u64 pc_get_controller_name(u32 id, u32 str_dest_ptr) {
std::string name = "";
if (Display::GetMainDisplay()) {
Expand Down Expand Up @@ -912,9 +926,11 @@ void init_common_pc_port_functions(

// -- DISPLAY RELATED --
// Returns the name of the display with the given id or #f if not found / empty
make_func_symbol_func("pc-get-display-id", (void*)pc_get_display_id);
make_func_symbol_func("pc-set-display-id!", (void*)pc_set_display_id);
make_func_symbol_func("pc-get-display-name", (void*)pc_get_display_name);
make_func_symbol_func("pc-get-display-mode", (void*)pc_get_display_mode);
make_func_symbol_func("pc-set-display-mode", (void*)pc_set_display_mode);
make_func_symbol_func("pc-set-display-mode!", (void*)pc_set_display_mode);
make_func_symbol_func("pc-get-display-count", (void*)pc_get_display_count);
// Returns resolution of the monitor's current display mode
make_func_symbol_func("pc-get-active-display-size", (void*)pc_get_active_display_size);
Expand All @@ -925,10 +941,10 @@ void init_common_pc_port_functions(
make_func_symbol_func("pc-get-window-size", (void*)pc_get_window_size);
// Returns scale of window. This is for DPI stuff.
make_func_symbol_func("pc-get-window-scale", (void*)pc_get_window_scale);
make_func_symbol_func("pc-set-fullscreen-display", (void*)pc_get_fullscreen_display);
make_func_symbol_func("pc-set-window-size", (void*)pc_set_window_size);
make_func_symbol_func("pc-set-window-size!", (void*)pc_set_window_size);
make_func_symbol_func("pc-get-num-resolutions", (void*)pc_get_num_resolutions);
make_func_symbol_func("pc-get-resolution", (void*)pc_get_resolution);
make_func_symbol_func("pc-is-supported-resolution?", (void*)pc_is_supported_resolution);

// -- INPUT RELATED --
// Returns the name of the display with the given id or #f if not found / empty
Expand Down
11 changes: 11 additions & 0 deletions game/settings/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ void DebugSettings::load_settings() {
}

void DebugSettings::save_settings() {
// Update the version string as we are now saving it back ground
version = current_version;
json data = *this;
auto debug_settings_filename =
file_util::get_user_misc_dir(g_game_version) / "debug-settings.json";
Expand All @@ -65,12 +67,17 @@ void to_json(json& j, const DisplaySettings& obj) {
json_serialize(display_id);
json_serialize(window_xpos);
json_serialize(window_ypos);
json_serialize(display_mode);
}
void from_json(const json& j, DisplaySettings& obj) {
json_deserialize_if_exists(version);
json_deserialize_if_exists(display_id);
json_deserialize_if_exists(window_xpos);
json_deserialize_if_exists(window_ypos);
if (j.contains("display_mode")) {
int mode = j.at("display_mode");
obj.display_mode = static_cast<DisplaySettings::DisplayMode>(mode);
}
}

DisplaySettings::DisplaySettings() {}
Expand All @@ -92,6 +99,8 @@ void DisplaySettings::load_settings() {
}

void DisplaySettings::save_settings() {
// Update the version string as we are now saving it back ground
version = current_version;
json data = *this;
auto file_path = file_util::get_user_settings_dir(g_game_version) / "display-settings.json";
file_util::create_dir_if_needed_for_file(file_path);
Expand Down Expand Up @@ -139,6 +148,8 @@ void InputSettings::load_settings() {
}

void InputSettings::save_settings() {
// Update the version string as we are now saving it back ground
version = current_version;
json data = *this;
auto file_path = file_util::get_user_settings_dir(g_game_version) / "input-settings.json";
file_util::create_dir_if_needed_for_file(file_path);
Expand Down
12 changes: 9 additions & 3 deletions game/settings/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ namespace game_settings {
struct DebugSettings {
DebugSettings();

std::string version = "1.2";
std::string current_version = "1.2";
std::string version = current_version;

bool show_imgui = false;
int imgui_font_size = 16;
Expand All @@ -32,13 +33,17 @@ void to_json(json& j, const DebugSettings& obj);
void from_json(const json& j, DebugSettings& obj);

struct DisplaySettings {
enum class DisplayMode { Windowed = 0, Fullscreen = 1, Borderless = 2 };

DisplaySettings();

std::string version = "1.1";
std::string current_version = "1.2";
std::string version = current_version;

int window_xpos = 50;
int window_ypos = 50;
int display_id = 0;
DisplayMode display_mode = DisplayMode::Borderless;

void load_settings();
void save_settings();
Expand All @@ -50,7 +55,8 @@ void from_json(const json& j, DisplaySettings& obj);
struct InputSettings {
InputSettings();

std::string version = "1.0";
std::string current_version = "1.0";
std::string version = current_version;

// NOTE - assumes only port 0
std::string last_selected_controller_guid = "";
Expand Down
Loading

0 comments on commit d819d6d

Please sign in to comment.