game: windowed mode related fixes (#1778)

* game: restore windowed mode settings properly

* game: use the game version for saving settings/saves

* game: prevent windowed mode from being auto-centered on initial init

* game: save and restore window coordinates

* lint: formatting
This commit is contained in:
Tyler Wilding
2022-08-21 18:13:27 -04:00
committed by GitHub
parent 7fd206be9c
commit dec7da2110
11 changed files with 107 additions and 42 deletions
+7 -7
View File
@@ -33,8 +33,8 @@
#include <cstring>
#include <unistd.h>
#endif
#include "common/log/log.h"
#include "common/util/Assert.h"
#include <common/log/log.h>
namespace file_util {
fs::path get_user_home_dir() {
@@ -66,14 +66,14 @@ fs::path get_user_config_dir() {
return config_base_path / "OpenGOAL";
}
fs::path get_user_settings_dir() {
// TODO - jak2
return get_user_config_dir() / "jak1" / "settings";
fs::path get_user_settings_dir(GameVersion game_version) {
auto game_version_name = game_version_names[game_version];
return get_user_config_dir() / game_version_name / "settings";
}
fs::path get_user_memcard_dir() {
// TODO - jak2
return get_user_config_dir() / "jak1" / "saves";
fs::path get_user_memcard_dir(GameVersion game_version) {
auto game_version_name = game_version_names[game_version];
return get_user_config_dir() / game_version_name / "saves";
}
struct {
+3 -2
View File
@@ -22,14 +22,15 @@
#include <vector>
#include "common/common_types.h"
#include "common/versions.h"
namespace fs = ghc::filesystem;
namespace file_util {
fs::path get_user_home_dir();
fs::path get_user_config_dir();
fs::path get_user_settings_dir();
fs::path get_user_memcard_dir();
fs::path get_user_settings_dir(GameVersion game_version);
fs::path get_user_memcard_dir(GameVersion game_version);
fs::path get_jak_project_dir();
bool create_dir_if_needed(const fs::path& path);
+41
View File
@@ -5,9 +5,17 @@
#include "display.h"
#include <optional>
#include "gfx.h"
#include "common/log/log.h"
#include "common/util/FileUtil.h"
#include "common/util/json_util.h"
#include "game/runtime.h"
#include "third-party/json.hpp"
/*
********************************
@@ -61,6 +69,35 @@ int GfxDisplay::height() {
return h;
}
void GfxDisplay::save_display_settings() {
nlohmann::json json;
json["window_xpos"] = m_last_windowed_xpos;
json["window_ypos"] = m_last_windowed_ypos;
std::string file_path =
(file_util::get_user_settings_dir(g_game_version) / "display-settings.json").string();
file_util::write_text_file(file_path, json.dump(2));
}
void GfxDisplay::restore_display_settings() {
try {
std::string file_path =
(file_util::get_user_settings_dir(g_game_version) / "display-settings.json").string();
if (!file_util::file_exists(file_path)) {
return;
}
auto raw = file_util::read_text_file(file_path);
auto json = parse_commented_json(raw, "display-settings.json");
if (json.contains("window_xpos")) {
m_last_windowed_xpos = json.at("window_xpos").get<int>();
}
if (json.contains("window_ypos")) {
m_last_windowed_ypos = json.at("window_ypos").get<int>();
}
} catch (std::exception& e) {
// do nothing
}
}
/*
********************************
* DISPLAY
@@ -93,6 +130,8 @@ int InitMainDisplay(int width,
return 1;
}
set_main_display(display);
// Restore window settings
display->restore_display_settings();
return 0;
}
@@ -108,6 +147,8 @@ void KillDisplay(std::shared_ptr<GfxDisplay> display) {
}
if (GetMainDisplay() == display) {
// Save the main display's position to a file so it can be restored upon re-opening
display->save_display_settings();
// killing the main display, kill all children displays too!
while (g_displays.size() > 1) {
KillDisplay(g_displays.at(1));
+12 -3
View File
@@ -28,12 +28,13 @@ class GfxDisplay {
// next mode
GfxDisplayMode m_fullscreen_target_mode = GfxDisplayMode::Windowed;
// current mode (start as -1 to force an initial fullscreen update)
GfxDisplayMode m_fullscreen_mode = (GfxDisplayMode)-1;
GfxDisplayMode m_fullscreen_mode = GfxDisplayMode::ForceUpdate;
// previous mode (last frame)
GfxDisplayMode m_last_fullscreen_mode = GfxDisplayMode::Windowed;
int m_last_windowed_xpos = 0;
int m_last_windowed_ypos = 0;
// move it a bit away from the top, or the title bar can be hidden
int m_last_windowed_xpos = 50;
int m_last_windowed_ypos = 50;
int m_last_windowed_width = 640;
int m_last_windowed_height = 480;
@@ -84,6 +85,14 @@ class GfxDisplay {
int width();
int height();
struct DisplaySettings {
int window_xpos;
int window_ypos;
};
void save_display_settings();
void restore_display_settings();
};
namespace Display {
+1 -1
View File
@@ -21,7 +21,7 @@ class GfxDisplay;
// enum for rendering pipeline
enum class GfxPipeline { Invalid = 0, OpenGL };
enum GfxDisplayMode { Windowed = 0, Fullscreen = 1, Borderless = 2 };
enum GfxDisplayMode { ForceUpdate = -1, Windowed = 0, Fullscreen = 1, Borderless = 2 };
// module for the different rendering pipelines
struct GfxRendererModule {
+16 -7
View File
@@ -371,14 +371,18 @@ void GLDisplay::on_cursor_position(GLFWwindow* window, double xposition, double
}
void GLDisplay::on_window_pos(GLFWwindow* /*window*/, int xpos, int ypos) {
if (m_fullscreen_target_mode == GfxDisplayMode::Windowed) {
// only change them on a legit change, not on the initial update
if (m_fullscreen_mode != GfxDisplayMode::ForceUpdate &&
m_fullscreen_target_mode == GfxDisplayMode::Windowed) {
m_last_windowed_xpos = xpos;
m_last_windowed_ypos = ypos;
}
}
void GLDisplay::on_window_size(GLFWwindow* /*window*/, int width, int height) {
if (m_fullscreen_target_mode == GfxDisplayMode::Windowed) {
// only change them on a legit change, not on the initial update
if (m_fullscreen_mode != GfxDisplayMode::ForceUpdate &&
m_fullscreen_target_mode == GfxDisplayMode::Windowed) {
m_last_windowed_width = width;
m_last_windowed_height = height;
}
@@ -556,11 +560,13 @@ void GLDisplay::update_fullscreen(GfxDisplayMode mode, int screen) {
glfwSetWindowMonitor(m_window, NULL, x, y, width, height, GLFW_DONT_CARE);
// these might have changed
m_last_windowed_width = width;
m_last_windowed_height = height;
m_last_windowed_xpos = x;
m_last_windowed_ypos = y;
// these might have changed, only store them on a legit change, not on the initial update
if (m_last_fullscreen_mode != GfxDisplayMode::ForceUpdate) {
m_last_windowed_width = width;
m_last_windowed_height = height;
m_last_windowed_xpos = x;
m_last_windowed_ypos = y;
}
} break;
case GfxDisplayMode::Fullscreen: {
// fullscreen
@@ -584,6 +590,9 @@ void GLDisplay::update_fullscreen(GfxDisplayMode mode, int screen) {
glfwSetWindowMonitor(m_window, NULL, x, y, vmode->width, vmode->height, GLFW_DONT_CARE);
#endif
} break;
default: {
break;
}
}
}
+3 -2
View File
@@ -69,8 +69,9 @@ class GLDisplay : public GfxDisplay {
};
struct DisplayState {
s32 window_pos_x = 0;
s32 window_pos_y = 0;
// move it a bit away from the top by default
s32 window_pos_x = 50;
s32 window_pos_y = 50;
int window_size_width = 640, window_size_height = 480;
float window_scale_x = 1.f, window_scale_y = 1.f;
+12 -9
View File
@@ -116,7 +116,7 @@ u32 mc_checksum(Ptr<u8> data, s32 size) {
* PC port function that returns whether a given bank ID's file exists or not.
*/
bool file_is_present(int id, int bank = 0) {
auto bankname = file_util::get_user_memcard_dir() / filename[4 + id * 2 + bank];
auto bankname = file_util::get_user_memcard_dir(g_game_version) / filename[4 + id * 2 + bank];
if (!fs::exists(bankname) || fs::file_size(bankname) < BANK_TOTAL_SIZE) {
// file doesn't exist, or size is bad. we do not want to open files that will crash on read!
return false;
@@ -146,13 +146,14 @@ void pc_update_card() {
// int highest_save_count = 0;
mc_last_file = -1;
for (s32 file = 0; file < 4; file++) {
auto bankname = file_util::get_user_memcard_dir() / filename[4 + file * 2];
auto bankname = file_util::get_user_memcard_dir(g_game_version) / filename[4 + file * 2];
mc_files[file].present = file_is_present(file);
if (mc_files[file].present) {
auto bankdata = file_util::read_binary_file(bankname.string());
auto header1 = reinterpret_cast<McHeader*>(bankdata.data());
if (file_is_present(file, 1)) {
auto bankname2 = file_util::get_user_memcard_dir() / filename[1 + 4 + file * 2];
auto bankname2 =
file_util::get_user_memcard_dir(g_game_version) / filename[1 + 4 + file * 2];
auto bankdata2 = file_util::read_binary_file(bankname2.string());
auto header2 = reinterpret_cast<McHeader*>(bankdata2.data());
@@ -189,7 +190,7 @@ void pc_game_save_synch() {
Timer mc_timer;
mc_timer.start();
pc_update_card();
auto path = file_util::get_user_memcard_dir() / filename[0];
auto path = file_util::get_user_memcard_dir(g_game_version) / filename[0];
file_util::create_dir_if_needed_for_file(path.string());
// cd_reprobe_save //
@@ -211,7 +212,8 @@ void pc_game_save_synch() {
// file*2 + p4 is the bank (2 banks per file, p4 is 0 or 1 to select the bank)
// 4 is the first bank file
mc_print("open {} for saving", filename[op.param2 * 2 + 4 + p4]);
auto save_path = file_util::get_user_memcard_dir() / filename[op.param2 * 2 + 4 + p4];
auto save_path =
file_util::get_user_memcard_dir(g_game_version) / filename[op.param2 * 2 + 4 + p4];
file_util::create_dir_if_needed_for_file(save_path.string());
auto fd = file_util::open_file(save_path.string().c_str(), "wb");
mc_print("synchronous save file open took {:.2f}ms\n", mc_timer.getMs());
@@ -281,11 +283,12 @@ void pc_game_load_open_file(FILE* fd) {
if (fclose(fd) == 0) {
// cb_closedload //
// added : check if aux bank exists
if (p2 < 1 &&
fs::exists(file_util::get_user_memcard_dir() / filename[op.param2 * 2 + 4 + p2 + 1])) {
if (p2 < 1 && fs::exists(file_util::get_user_memcard_dir(g_game_version) /
filename[op.param2 * 2 + 4 + p2 + 1])) {
p2++;
mc_print("reading next save bank {}", filename[op.param2 * 2 + 4 + p2]);
auto new_bankname = file_util::get_user_memcard_dir() / filename[op.param2 * 2 + 4 + p2];
auto new_bankname =
file_util::get_user_memcard_dir(g_game_version) / filename[op.param2 * 2 + 4 + p2];
auto new_fd = file_util::open_file(new_bankname.string().c_str(), "rb");
pc_game_load_open_file(new_fd);
} else {
@@ -402,7 +405,7 @@ void pc_game_load_synch() {
p2 = 0;
mc_print("opening save file {}", filename[op.param2 * 2 + 4]);
auto path = file_util::get_user_memcard_dir() / filename[op.param2 * 2 + 4];
auto path = file_util::get_user_memcard_dir(g_game_version) / filename[op.param2 * 2 + 4];
auto fd = file_util::open_file(path.string().c_str(), "rb");
pc_game_load_open_file(fd);
+1 -2
View File
@@ -677,8 +677,7 @@ void InitMachine_PCPort() {
auto user_dir_path = file_util::get_user_config_dir();
intern_from_c("*pc-user-dir-base-path*")->value =
make_string_from_c(user_dir_path.string().c_str());
// TODO - we will eventually need a better way to know what game we are playing
auto settings_path = file_util::get_user_settings_dir();
auto settings_path = file_util::get_user_settings_dir(g_game_version);
intern_from_c("*pc-settings-folder*")->value = make_string_from_c(settings_path.string().c_str());
intern_from_c("*pc-settings-built-sha*")->value = make_string_from_c(GIT_VERSION);
}
+1 -2
View File
@@ -521,8 +521,7 @@ void InitMachine_PCPort() {
auto user_dir_path = file_util::get_user_config_dir();
intern_from_c("*pc-user-dir-base-path*")->value() =
make_string_from_c(user_dir_path.string().c_str());
// TODO - we will eventually need a better way to know what game we are playing
auto settings_path = file_util::get_user_settings_dir();
auto settings_path = file_util::get_user_settings_dir(g_game_version);
intern_from_c("*pc-settings-folder*")->value() =
make_string_from_c(settings_path.string().c_str());
intern_from_c("*pc-settings-built-sha*")->value() = make_string_from_c(GIT_VERSION);
+10 -7
View File
@@ -48,18 +48,18 @@
;;;; updates
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defmethod set-display-mode! pc-settings ((obj pc-settings) (mode symbol))
"sets the game's display mode"
;; change the display mode.
(set! (-> obj display-mode) mode)
;; if windowed mode, set the size properly
(when (= (-> obj display-mode) 'windowed)
(pc-set-window-size (max PC_MIN_WIDTH (-> obj win-width)) (max PC_MIN_HEIGHT (-> obj win-height))))
0)
(defmethod set-size! pc-settings ((obj pc-settings) (width int) (height int))
"sets the size of the display window"
(format #t "Setting size to ~D x ~D~%" width height)
(format 0 "Setting ~A size to ~D x ~D~%" (-> obj display-mode) width height)
(cond
((= 'windowed (-> obj display-mode))
(set! (-> obj win-width) width)
@@ -73,7 +73,6 @@
)
(none))
(defmethod set-aspect! pc-settings ((obj pc-settings) (aw int) (ah int))
"set the aspect ratio used for rendering. this forces native widescreen and takes width and height ratios."
(let ((aspect (/ (the float aw) (the float ah))))
@@ -916,6 +915,10 @@
(format 0 "pc settings file read: ~A~%" filename)
;; restore the windowed mode resolution properly
(when (= (-> obj display-mode) 'windowed)
(pc-set-window-size (max PC_MIN_WIDTH (-> obj win-width)) (max PC_MIN_HEIGHT (-> obj win-height))))
#t
)
@@ -932,13 +935,13 @@
(format file "(settings #x~X~%" (-> obj version))
(format file " (fps ~D)~%" (-> obj target-fps))
(format file " (game-size ~D ~D)~%" (-> obj width) (-> obj height))
(format file " (msaa ~D)~%" (-> obj gfx-msaa))
(format file " (window-size ~D ~D)~%" (-> obj win-width) (-> obj win-height))
(format file " (aspect-state ~A ~D ~D ~A)~%" (-> *setting-control* default aspect-ratio)
(-> obj aspect-custom-x) (-> obj aspect-custom-y)
(-> obj aspect-ratio-auto?))
(format file " (display-mode ~A)~%" (-> obj display-mode))
(format file " (window-size ~D ~D)~%" (-> obj win-width) (-> obj win-height))
(format file " (game-size ~D ~D)~%" (-> obj width) (-> obj height))
(format file " (monitor ~D)~%" (-> obj monitor))
(format file " (letterbox ~A)~%" (-> obj letterbox?))
(format file " (vsync ~A)~%" (-> obj vsync?))