From c9de15ba6428aa6adac7677280d16086c33ff6a2 Mon Sep 17 00:00:00 2001 From: ManDude <7569514+ManDude@users.noreply.github.com> Date: Sat, 25 Jun 2022 16:05:20 +0100 Subject: [PATCH] framerate and vsync menus and fixes (#1552) * in-game vsync option, automatically framelimit correctly, fix minimize/alttab bugs * fix jp text errors * bump version number as panic * this makes more sense i think * clang * oops delete debug print --- decompiler/config/all-types.gc | 3 +- game/assets/jak1/text/game_text_en.gs | 2 + game/assets/jak1/text/game_text_ja.gs | 6 +- game/graphics/display.h | 5 +- game/graphics/gfx.cpp | 26 +++++- game/graphics/gfx.h | 17 +++- game/graphics/opengl_renderer/debug_gui.cpp | 11 +-- game/graphics/opengl_renderer/debug_gui.h | 11 +-- game/graphics/pipelines/opengl.cpp | 89 ++++++++++++--------- game/graphics/pipelines/opengl.h | 5 +- game/kernel/kmachine.cpp | 35 ++++++-- goal_src/engine/ui/text-h.gc | 3 +- goal_src/game.gp | 2 +- goal_src/kernel-defs.gc | 6 +- goal_src/pc/pckernel-h.gc | 7 +- goal_src/pc/pckernel.gc | 45 +++++++++-- goal_src/pc/progress-pc.gc | 78 +++++++++++++----- 17 files changed, 254 insertions(+), 97 deletions(-) diff --git a/decompiler/config/all-types.gc b/decompiler/config/all-types.gc index e31ec33049..71da4324c8 100644 --- a/decompiler/config/all-types.gc +++ b/decompiler/config/all-types.gc @@ -1316,7 +1316,7 @@ (camera-controls-first-vert #x1004) (camera-controls-third-horz #x1005) (camera-controls-third-vert #x1006) - (camera-controls-original #x1007) + (restore-defaults #x1007) (misc-options #x100f) (accessibility-options #x1010) (money-starburst #x1011) @@ -1336,6 +1336,7 @@ (ps2-aspect-ratio-msg #x1038) (aspect-ratio-ps2 #x1039) (fit-to-screen #x103a) + (vsync #x103b) (msaa #x1050) (x-times-fmt #x1051) (2-times #x1052) diff --git a/game/assets/jak1/text/game_text_en.gs b/game/assets/jak1/text/game_text_en.gs index 7d24c7b4dc..f98fed4df0 100644 --- a/game/assets/jak1/text/game_text_en.gs +++ b/game/assets/jak1/text/game_text_en.gs @@ -66,6 +66,8 @@ "ASPECT RATIO (PS2)") (#x103a "FIT TO SCREEN" "FIT TO SCREEN") +(#x103b "V-SYNC" + "V-SYNC") (#x1050 "MSAA" "MSAA") diff --git a/game/assets/jak1/text/game_text_ja.gs b/game/assets/jak1/text/game_text_ja.gs index 5c8d0456b6..6ee71dd962 100644 --- a/game/assets/jak1/text/game_text_ja.gs +++ b/game/assets/jak1/text/game_text_ja.gs @@ -35,6 +35,8 @@ (#x10d2 "セイジィ") (#x10d3 "セイジィの家") +(#x10d6 "ケイラ") + (#x10df "みしよう") (#x10e3 "みしよう1") @@ -59,13 +61,13 @@ (#x10fc "ラーカーのとりで") (#x10fd "ゆきだま") (#x10fe "マグマチューブの中かん") -(#x10ff "マグマチューブのさいしゅうかい") +(#x10ff "マグマチューブのけつまつ") (#x1100 "黄の賢者") (#x1101 "赤の賢者") (#x1102 "青の賢者") (#x1103 "城のハブ") (#x1104 "ラスボスの中かん") -(#x1105 "ラスボスのさいしゅうかい") +(#x1105 "ラスボスのけつまつ") diff --git a/game/graphics/display.h b/game/graphics/display.h index e783105b19..26508c14d6 100644 --- a/game/graphics/display.h +++ b/game/graphics/display.h @@ -42,12 +42,15 @@ class GfxDisplay { virtual void set_size(int w, int h) = 0; virtual void update_fullscreen(GfxDisplayMode mode, int screen) = 0; virtual void get_scale(float* x, float* y) = 0; - virtual void get_screen_size(int vmode_idx, s32* w, s32* h, s32* c) = 0; + virtual int get_screen_vmode_count() = 0; + virtual void get_screen_size(int vmode_idx, s32* w, s32* h) = 0; + virtual int get_screen_rate(int vmode_idx) = 0; virtual void get_position(int* x, int* y) = 0; virtual void get_size(int* w, int* h) = 0; virtual GfxDisplayMode get_fullscreen() = 0; virtual void render() = 0; virtual void set_lock(bool lock) = 0; + virtual bool minimized() = 0; bool is_active() const { return get_window() != nullptr; } void set_title(const char* title); const char* title() const { return m_title; } diff --git a/game/graphics/gfx.cpp b/game/graphics/gfx.cpp index fd3b05a887..a495bafce0 100644 --- a/game/graphics/gfx.cpp +++ b/game/graphics/gfx.cpp @@ -229,10 +229,32 @@ GfxDisplayMode get_fullscreen() { } } -void get_screen_size(s64 vmode_idx, s32* w, s32* h, s32* c) { +int get_screen_vmode_count() { if (Display::GetMainDisplay()) { - Display::GetMainDisplay()->get_screen_size(vmode_idx, w, h, c); + return Display::GetMainDisplay()->get_screen_vmode_count(); } + return 0; +} + +int get_screen_rate(s64 vmode_idx) { + if (Display::GetMainDisplay()) { + return Display::GetMainDisplay()->get_screen_rate(vmode_idx); + } + return 0; +} + +void get_screen_size(s64 vmode_idx, s32* w, s32* h) { + if (Display::GetMainDisplay()) { + Display::GetMainDisplay()->get_screen_size(vmode_idx, w, h); + } +} + +void set_vsync(bool vsync) { + g_global_settings.vsync = vsync; +} + +void set_frame_rate(int rate) { + g_global_settings.target_fps = rate; } void set_letterbox(int w, int h) { diff --git a/game/graphics/gfx.h b/game/graphics/gfx.h index e39bb2c59e..3b82338674 100644 --- a/game/graphics/gfx.h +++ b/game/graphics/gfx.h @@ -82,6 +82,17 @@ struct GfxGlobalSettings { bool collision_enable = false; bool collision_wireframe = true; + // vsync enable + bool vsync = true; + bool old_vsync = false; + // target frame rate + float target_fps = 60; + // use custom frame limiter + bool framelimiter = true; + + bool experimental_accurate_lag = false; + bool sleep_in_frame_limiter = true; + // matching enum in kernel-defs.gc !! enum CollisionRendererMode { None, Mode, Event, Material, Skip } collision_mode = Mode; std::array collision_mode_mask = {UINT32_MAX}; @@ -113,7 +124,11 @@ u64 get_window_height(); void set_window_size(u64 w, u64 h); void get_window_scale(float* x, float* y); GfxDisplayMode get_fullscreen(); -void get_screen_size(s64 vmode_idx, s32* w, s32* h, s32* c); +int get_screen_vmode_count(); +int get_screen_rate(s64 vmode_idx); +void get_screen_size(s64 vmode_idx, s32* w, s32* h); +void set_frame_rate(int rate); +void set_vsync(bool vsync); void set_letterbox(int w, int h); void set_fullscreen(GfxDisplayMode mode, int screen); void set_window_lock(bool lock); diff --git a/game/graphics/opengl_renderer/debug_gui.cpp b/game/graphics/opengl_renderer/debug_gui.cpp index 29df6807c6..2fb9fcffba 100644 --- a/game/graphics/opengl_renderer/debug_gui.cpp +++ b/game/graphics/opengl_renderer/debug_gui.cpp @@ -3,6 +3,7 @@ #include +#include "game/graphics/gfx.h" #include "game/kernel/svnrev.h" #include "third-party/imgui/imgui.h" @@ -113,16 +114,16 @@ void OpenGlDebugGui::draw(const DmaStats& dma_stats) { } if (ImGui::BeginMenu("Frame Rate")) { - ImGui::Checkbox("Enable V-Sync", &m_vsync); + ImGui::Checkbox("Enable V-Sync", &Gfx::g_global_settings.vsync); ImGui::Separator(); - ImGui::Checkbox("Framelimiter", &framelimiter); + ImGui::Checkbox("Framelimiter", &Gfx::g_global_settings.framelimiter); ImGui::InputFloat("Target FPS", &target_fps_input); if (ImGui::MenuItem("Apply")) { - target_fps = target_fps_input; + Gfx::g_global_settings.target_fps = target_fps_input; } ImGui::Separator(); - ImGui::Checkbox("Accurate Lag Mode", &experimental_accurate_lag); - ImGui::Checkbox("Sleep in Frame Limiter", &sleep_in_frame_limiter); + ImGui::Checkbox("Accurate Lag Mode", &Gfx::g_global_settings.experimental_accurate_lag); + ImGui::Checkbox("Sleep in Frame Limiter", &Gfx::g_global_settings.sleep_in_frame_limiter); ImGui::EndMenu(); } diff --git a/game/graphics/opengl_renderer/debug_gui.h b/game/graphics/opengl_renderer/debug_gui.h index 0dfd366a0b..bdefa0d093 100644 --- a/game/graphics/opengl_renderer/debug_gui.h +++ b/game/graphics/opengl_renderer/debug_gui.h @@ -48,9 +48,7 @@ class OpenGlDebugGui { const char* screenshot_name() const { return m_screenshot_save_name; } bool should_advance_frame() { return m_frame_timer.should_advance_frame(); } - bool should_gl_finish() { return m_frame_timer.do_gl_finish; } - - void init_framerate_settings(); + bool should_gl_finish() const { return m_frame_timer.do_gl_finish; } bool get_screenshot_flag() { if (m_want_screenshot) { @@ -60,17 +58,10 @@ class OpenGlDebugGui { return false; } - bool get_vsync_flag() { return m_vsync; } - - bool framelimiter = false; - float target_fps = 60.f; - bool experimental_accurate_lag = false; - bool sleep_in_frame_limiter = true; bool small_profiler = false; bool record_events = false; bool dump_events = false; bool want_reboot_in_debug = false; - bool m_vsync = true; private: FrameTimeRecorder m_frame_timer; diff --git a/game/graphics/pipelines/opengl.cpp b/game/graphics/pipelines/opengl.cpp index e1a0c80dbe..9e350b1507 100644 --- a/game/graphics/pipelines/opengl.cpp +++ b/game/graphics/pipelines/opengl.cpp @@ -39,7 +39,6 @@ struct GraphicsData { // vsync std::mutex sync_mutex; std::condition_variable sync_cv; - bool vsync_enabled = true; // dma chain transfer std::mutex dma_mutex; @@ -185,39 +184,37 @@ static std::shared_ptr gl_make_display(int width, stbi_image_free(images[0].pixels); // init framerate settings - GLFWmonitor* primary_monitor = glfwGetPrimaryMonitor(); - if (primary_monitor) { + /* + if (GLFWmonitor* primary_monitor = glfwGetPrimaryMonitor()) { auto primary_monitor_video_mode = glfwGetVideoMode(primary_monitor); if (primary_monitor_video_mode && primary_monitor_video_mode->refreshRate > 60) { // Use the framelimiter by default and disable vsync - g_gfx_data->debug_gui.framelimiter = true; - g_gfx_data->debug_gui.m_vsync = false; - g_gfx_data->vsync_enabled = false; - glfwSwapInterval(false); + Gfx::g_global_settings.framelimiter = true; + Gfx::g_global_settings.vsync = false; + glfwSwapInterval(0); if (primary_monitor_video_mode->refreshRate > 100) { BootVideoMode = VideoMode::FPS150; - g_gfx_data->debug_gui.target_fps = 150; + Gfx::g_global_settings.target_fps = 150; } else if (primary_monitor_video_mode->refreshRate > 60) { BootVideoMode = VideoMode::FPS100; - g_gfx_data->debug_gui.target_fps = 100; + Gfx::g_global_settings.target_fps = 100; } } else { // enable vsync - g_gfx_data->debug_gui.framelimiter = false; - g_gfx_data->debug_gui.m_vsync = true; - g_gfx_data->vsync_enabled = true; + Gfx::g_global_settings.framelimiter = false; + Gfx::g_global_settings.vsync = true; // glfwSwapInterval(1); glfwSwapInterval(settings.vsync); } } else { // enable vsync - g_gfx_data->debug_gui.framelimiter = false; - g_gfx_data->debug_gui.m_vsync = true; - g_gfx_data->vsync_enabled = true; + Gfx::g_global_settings.framelimiter = false; + Gfx::g_global_settings.vsync = true; // glfwSwapInterval(1); glfwSwapInterval(settings.vsync); } + */ SetDisplayCallbacks(window); Pad::initialize(); @@ -417,24 +414,25 @@ GfxDisplayMode GLDisplay::get_fullscreen() { } } -void GLDisplay::get_screen_size(int vmode_idx, s32* w_out, s32* h_out, s32* count_out) { +int GLDisplay::get_screen_vmode_count() { int count = 0; + auto vmodes = glfwGetVideoModes(glfwGetPrimaryMonitor(), &count); + return count; +} + +void GLDisplay::get_screen_size(int vmode_idx, s32* w_out, s32* h_out) { auto vmode = glfwGetVideoMode(glfwGetPrimaryMonitor()); - if (get_fullscreen() == GfxDisplayMode::Fullscreen) { - auto vmodes = glfwGetVideoModes(glfwGetPrimaryMonitor(), &count); - if (vmode_idx >= 0) { - vmode = &vmodes[vmode_idx]; - } else { - for (int i = 0; i < count; ++i) { - if (!vmode || vmode->height < vmodes[i].height) { - vmode = &vmodes[i]; - } + int count = 0; + auto vmodes = glfwGetVideoModes(glfwGetPrimaryMonitor(), &count); + if (vmode_idx >= 0) { + vmode = &vmodes[vmode_idx]; + } else if (get_fullscreen() == GfxDisplayMode::Fullscreen) { + for (int i = 0; i < count; ++i) { + if (!vmode || vmode->height < vmodes[i].height) { + vmode = &vmodes[i]; } } } - if (count_out) { - *count_out = count; - } if (w_out) { *w_out = vmode->width; } @@ -443,6 +441,26 @@ void GLDisplay::get_screen_size(int vmode_idx, s32* w_out, s32* h_out, s32* coun } } +int GLDisplay::get_screen_rate(int vmode_idx) { + auto vmode = glfwGetVideoMode(glfwGetPrimaryMonitor()); + int count = 0; + auto vmodes = glfwGetVideoModes(glfwGetPrimaryMonitor(), &count); + if (vmode_idx >= 0) { + vmode = &vmodes[vmode_idx]; + } else if (get_fullscreen() == GfxDisplayMode::Fullscreen) { + for (int i = 0; i < count; ++i) { + if (!vmode || vmode->refreshRate < vmodes[i].refreshRate) { + vmode = &vmodes[i]; + } + } + } + return vmode->refreshRate; +} + +bool GLDisplay::minimized() { + return glfwGetWindowAttrib(m_window, GLFW_ICONIFIED); +} + void GLDisplay::set_lock(bool lock) { glfwSetWindowAttrib(m_window, GLFW_RESIZABLE, lock ? GLFW_TRUE : GLFW_FALSE); } @@ -521,10 +539,9 @@ void GLDisplay::render() { } // switch vsync modes, if requested - bool req_vsync = g_gfx_data->debug_gui.get_vsync_flag(); - if (req_vsync != g_gfx_data->vsync_enabled) { - g_gfx_data->vsync_enabled = req_vsync; - glfwSwapInterval(req_vsync); + if (Gfx::g_global_settings.vsync != Gfx::g_global_settings.old_vsync) { + Gfx::g_global_settings.old_vsync = Gfx::g_global_settings.vsync; + glfwSwapInterval(Gfx::g_global_settings.vsync); } // actual vsync @@ -533,17 +550,17 @@ void GLDisplay::render() { auto p = scoped_prof("swap-buffers"); glfwSwapBuffers(m_window); } - if (g_gfx_data->debug_gui.framelimiter) { + if (Gfx::g_global_settings.framelimiter) { auto p = scoped_prof("frame-limiter"); g_gfx_data->frame_limiter.run( - g_gfx_data->debug_gui.target_fps, g_gfx_data->debug_gui.experimental_accurate_lag, - g_gfx_data->debug_gui.sleep_in_frame_limiter, g_gfx_data->last_engine_time); + Gfx::g_global_settings.target_fps, Gfx::g_global_settings.experimental_accurate_lag, + Gfx::g_global_settings.sleep_in_frame_limiter, g_gfx_data->last_engine_time); } g_gfx_data->debug_gui.start_frame(); prof().instant_event("ROOT"); update_global_profiler(); - if (fullscreen_pending()) { + if (!minimized() && fullscreen_pending()) { fullscreen_flush(); } update_last_fullscreen_mode(); diff --git a/game/graphics/pipelines/opengl.h b/game/graphics/pipelines/opengl.h index 8d170f01b2..0f13215c67 100644 --- a/game/graphics/pipelines/opengl.h +++ b/game/graphics/pipelines/opengl.h @@ -29,11 +29,14 @@ class GLDisplay : public GfxDisplay { void get_position(int* x, int* y); void get_size(int* w, int* h); void get_scale(float* x, float* y); - void get_screen_size(int vmode_idx, s32* w, s32* h, s32* c); + void get_screen_size(int vmode_idx, s32* w, s32* h); + int get_screen_rate(int vmode_idx); + int get_screen_vmode_count(); GfxDisplayMode get_fullscreen(); void set_size(int w, int h); void update_fullscreen(GfxDisplayMode mode, int screen); void render(); + bool minimized(); void set_lock(bool lock); }; diff --git a/game/kernel/kmachine.cpp b/game/kernel/kmachine.cpp index abb9f54a32..2cf5f805ae 100644 --- a/game/kernel/kmachine.cpp +++ b/game/kernel/kmachine.cpp @@ -812,18 +812,29 @@ void get_window_scale(u32 x_ptr, u32 y_ptr) { /*! * Returns resolution of the monitor. */ -void get_screen_size(s64 vmode_idx, u32 w_ptr, u32 h_ptr, u32 c_ptr) { - s32 *w_out = 0, *h_out = 0, *c_out = 0; +void get_screen_size(s64 vmode_idx, u32 w_ptr, u32 h_ptr) { + s32 *w_out = 0, *h_out = 0; if (w_ptr) { w_out = Ptr(w_ptr).c(); } if (h_ptr) { h_out = Ptr(h_ptr).c(); } - if (c_ptr) { - c_out = Ptr(c_ptr).c(); - } - Gfx::get_screen_size(vmode_idx, w_out, h_out, c_out); + Gfx::get_screen_size(vmode_idx, w_out, h_out); +} + +/*! + * Returns refresh rate of the monitor. + */ +s64 get_screen_rate(s64 vmode_idx) { + return Gfx::get_screen_rate(vmode_idx); +} + +/*! + * Returns amount of video modes of the monitor. + */ +s64 get_screen_vmode_count() { + return Gfx::get_screen_vmode_count(); } void update_discord_rpc(u32 discord_info) { @@ -970,6 +981,14 @@ void set_fullscreen(u32 symptr, s64 screen) { } } +void set_frame_rate(s64 rate) { + Gfx::set_frame_rate(rate); +} + +void set_vsync(u32 symptr) { + Gfx::set_vsync(symptr != s7.offset); +} + void set_window_lock(u32 symptr) { Gfx::set_window_lock(symptr == s7.offset); } @@ -1020,8 +1039,12 @@ void InitMachine_PCPort() { make_function_symbol_from_c("pc-get-window-scale", (void*)get_window_scale); make_function_symbol_from_c("pc-get-fullscreen", (void*)get_fullscreen); make_function_symbol_from_c("pc-get-screen-size", (void*)get_screen_size); + make_function_symbol_from_c("pc-get-screen-rate", (void*)get_screen_rate); + make_function_symbol_from_c("pc-get-screen-vmode-count", (void*)get_screen_vmode_count); make_function_symbol_from_c("pc-set-window-size", (void*)Gfx::set_window_size); make_function_symbol_from_c("pc-set-fullscreen", (void*)set_fullscreen); + make_function_symbol_from_c("pc-set-frame-rate", (void*)set_frame_rate); + make_function_symbol_from_c("pc-set-vsync", (void*)set_vsync); make_function_symbol_from_c("pc-set-window-lock", (void*)set_window_lock); // graphics things diff --git a/goal_src/engine/ui/text-h.gc b/goal_src/engine/ui/text-h.gc index 90bb3ce279..1a5a42b801 100644 --- a/goal_src/engine/ui/text-h.gc +++ b/goal_src/engine/ui/text-h.gc @@ -466,7 +466,7 @@ (camera-controls-first-vert #x1004) (camera-controls-third-horz #x1005) (camera-controls-third-vert #x1006) - (camera-controls-original #x1007) + (restore-defaults #x1007) (misc-options #x100f) (accessibility-options #x1010) (money-starburst #x1011) @@ -486,6 +486,7 @@ (ps2-aspect-ratio-msg #x1038) (aspect-ratio-ps2 #x1039) (fit-to-screen #x103a) + (vsync #x103b) (msaa #x1050) (x-times-fmt #x1051) (2-times #x1052) diff --git a/goal_src/game.gp b/goal_src/game.gp index 079399bff3..434554a9a3 100644 --- a/goal_src/game.gp +++ b/goal_src/game.gp @@ -1976,7 +1976,7 @@ ;; Custom or Modified Code (goal-src "pc/pckernel-h.gc" "dma-disasm") -(goal-src "pc/pckernel.gc" "settings") +(goal-src "pc/pckernel.gc" "settings" "video") (goal-src "pc/subtitle.gc" "text" "pckernel" "hint-control" "loader-h" "gsound" "ambient") (goal-src "pc/progress-pc.gc" "progress" "pckernel") (goal-src "pc/anim-tester-x.gc" "pckernel" "gstring" "joint" "process-drawable" "art-h" "effect-control") diff --git a/goal_src/kernel-defs.gc b/goal_src/kernel-defs.gc index 9294b3b37e..e5b3e7e067 100644 --- a/goal_src/kernel-defs.gc +++ b/goal_src/kernel-defs.gc @@ -334,12 +334,16 @@ (define-extern pc-pad-input-map-save! (function none)) (define-extern pc-pad-get-mapped-button (function int int int)) (define-extern pc-get-fullscreen (function symbol)) -(define-extern pc-get-screen-size (function int (pointer int32) (pointer int32) (pointer int32) none)) +(define-extern pc-get-screen-size (function int (pointer int32) (pointer int32) none)) +(define-extern pc-get-screen-rate (function int int)) +(define-extern pc-get-screen-vmode-count (function int)) (define-extern pc-get-os (function symbol)) (define-extern pc-get-window-size (function (pointer int32) (pointer int32) none)) (define-extern pc-get-window-scale (function (pointer float) (pointer float) none)) (define-extern pc-set-window-size (function int int none)) (define-extern pc-set-fullscreen (function symbol int none)) +(define-extern pc-set-frame-rate (function int none)) +(define-extern pc-set-vsync (function symbol none)) (define-extern pc-renderer-tree-set-lod (function pc-renderer-tree-type int none)) (define-extern pc-set-letterbox (function int int none)) (define-extern pc-set-collision (function symbol none)) diff --git a/goal_src/pc/pckernel-h.gc b/goal_src/pc/pckernel-h.gc index 392cf0e374..1ebbd18fb5 100644 --- a/goal_src/pc/pckernel-h.gc +++ b/goal_src/pc/pckernel-h.gc @@ -31,7 +31,7 @@ (defglobalconstant PC_KERNEL_VERSION_BUILD #x0001) (defglobalconstant PC_KERNEL_VERSION_REVISION #x0006) -(defglobalconstant PC_KERNEL_VERSION_MINOR #x0005) +(defglobalconstant PC_KERNEL_VERSION_MINOR #x0006) (defglobalconstant PC_KERNEL_VERSION_MAJOR #x0001) (defglobalconstant PC_KERNEL_VERSION (logior (ash PC_KERNEL_VERSION_MAJOR 48) @@ -48,6 +48,8 @@ (defconstant ASPECT_16X9_SCALE (/ ASPECT_16X9 ASPECT_4X3)) (defconstant PC_BASE_WIDTH 640) (defconstant PC_BASE_HEIGHT 480) +(defconstant PC_MIN_WIDTH 320) +(defconstant PC_MIN_HEIGHT 240) ;; how many entries the music log has. the game only has 21 tracks but let's have more space for no reason. @@ -322,6 +324,7 @@ (set-aspect! (_type_ int int) none) (set-aspect-ratio! (_type_ float) none) (set-window-lock! (_type_ symbol) symbol) + (set-frame-rate! (_type_ int) int) (read-from-file (_type_ string) symbol) (write-to-file (_type_ string) symbol) (update-cheats (_type_) int) @@ -418,7 +421,7 @@ (set! (-> obj letterbox?) #t) (set-display-mode! obj 'windowed) - (set-size! obj 640 480) + (set-size! obj PC_BASE_WIDTH PC_BASE_HEIGHT) (set-aspect! obj 4 3) (set! (-> obj gfx-msaa) 4) ;; 4x msaa diff --git a/goal_src/pc/pckernel.gc b/goal_src/pc/pckernel.gc index 243b49bd0d..3d498325ed 100644 --- a/goal_src/pc/pckernel.gc +++ b/goal_src/pc/pckernel.gc @@ -96,6 +96,33 @@ (pc-set-window-lock lock) (set! (-> obj window-lock?) lock)) +(defmethod set-frame-rate! pc-settings ((obj pc-settings) (rate int)) + "set the aspect ratio used for rendering." + + (pc-set-frame-rate rate) + (if (and (!= 'fullscreen (-> obj display-mode)) + (!= (pc-get-screen-rate -1) rate)) + (set! (-> obj vsync?) #f)) + (case rate + ((60) + (set! (-> obj target-fps) rate) + (set! (-> *setting-control* default video-mode) 'ntsc) + (set-video-mode 'ntsc) + ) + ((100) + (set! (-> obj target-fps) rate) + (set! (-> *setting-control* default video-mode) '100fps) + (set-video-mode '100fps) + ) + ((150) + (set! (-> obj target-fps) rate) + (set! (-> *setting-control* default video-mode) '150fps) + (set-video-mode '150fps) + ) + ) + + rate) + (defmethod commit-to-file pc-settings ((obj pc-settings)) "commits the current settings to the file" ;; auto load settings if available @@ -161,11 +188,19 @@ ) (pc-set-fullscreen (-> obj display-mode) 0) - (if (and (= 'windowed (-> obj display-mode)) - (-> obj window-lock?) - (or (!= (-> obj win-width) (-> obj real-width)) - (!= (-> obj win-height) (-> obj real-height)))) - (pc-set-window-size (max 320 (-> obj win-width)) (max 240 (-> obj win-height)))) + (when (-> obj window-lock?) + (pc-set-vsync (-> obj vsync?)) + + (when (!= 'fullscreen (-> obj display-mode)) + (if (< (pc-get-screen-rate -1) (-> obj target-fps)) + (pc-set-vsync #f)) + (pc-set-frame-rate (-> obj target-fps))) + + (if (and (= 'windowed (-> obj display-mode)) + (or (!= (-> obj win-width) (-> obj real-width)) + (!= (-> obj win-height) (-> obj real-height)))) + (pc-set-window-size (max PC_MIN_WIDTH (-> obj win-width)) (max PC_MIN_HEIGHT (-> obj win-height)))) + ) (pc-discord-rpc-set (if (-> obj discord-rpc?) 1 0)) diff --git a/goal_src/pc/progress-pc.gc b/goal_src/pc/progress-pc.gc index ee68c969f7..73450a93e0 100644 --- a/goal_src/pc/progress-pc.gc +++ b/goal_src/pc/progress-pc.gc @@ -85,7 +85,9 @@ (def-progress-carousell *carousell-lod-fg* (lod-high lod-low lod-ps2)) (def-progress-carousell *carousell-subtitle-language* (english french german spanish italian japanese)) (def-progress-carousell *carousell-speaker* (speaker-always speaker-never speaker-auto)) -(def-progress-carousell *carousell-frame-rate* (60fps 100fps 150fps)) +(def-progress-carousell *carousell-frame-rate-150fps* (60fps 100fps 150fps)) +(def-progress-carousell *carousell-frame-rate-100fps* (60fps 100fps)) +(define *carousell-frame-rate* *carousell-frame-rate-150fps*) @@ -107,6 +109,7 @@ (define *graphic-options-pc* (new 'static 'boxed-array :type game-option (new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id game-resolution) :scale #t :param3 (game-option-menu resolution)) (new 'static 'game-option :option-type (game-option-type display-mode) :name (game-text-id display-mode) :scale #t) + (new 'static 'game-option :option-type (game-option-type on-off) :name (game-text-id vsync) :scale #t) (new 'static 'game-option :option-type (game-option-type aspect-native) :name (game-text-id ps2-aspect-ratio) :scale #t) (new 'static 'game-option :option-type (game-option-type aspect-ratio) :name (game-text-id aspect-ratio-ps2) :scale #t) (new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id aspect-ratio) :scale #t :param3 (game-option-menu aspect-ratio)) @@ -117,6 +120,19 @@ ) ) +(define *graphic-options-no-frame-rate-pc* (new 'static 'boxed-array :type game-option + (new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id game-resolution) :scale #t :param3 (game-option-menu resolution)) + (new 'static 'game-option :option-type (game-option-type display-mode) :name (game-text-id display-mode) :scale #t) + (new 'static 'game-option :option-type (game-option-type on-off) :name (game-text-id vsync) :scale #t) + (new 'static 'game-option :option-type (game-option-type aspect-native) :name (game-text-id ps2-aspect-ratio) :scale #t) + (new 'static 'game-option :option-type (game-option-type aspect-ratio) :name (game-text-id aspect-ratio-ps2) :scale #t) + (new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id aspect-ratio) :scale #t :param3 (game-option-menu aspect-ratio)) + ;(new 'static 'game-option :option-type (game-option-type msaa) :name (game-text-id msaa) :scale #t) + (new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id ps2-options) :scale #t :param3 (game-option-menu gfx-ps2-options)) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) + ) + ) + (define *misc-options* (new 'static 'boxed-array :type game-option (new 'static 'game-option :option-type (game-option-type on-off) :name (game-text-id discord-rpc) :scale #t) (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) @@ -128,7 +144,7 @@ (new 'static 'game-option :option-type (game-option-type normal-inverted) :name (game-text-id camera-controls-first-vert) :scale #t) (new 'static 'game-option :option-type (game-option-type normal-inverted) :name (game-text-id camera-controls-third-horz) :scale #t) (new 'static 'game-option :option-type (game-option-type normal-inverted) :name (game-text-id camera-controls-third-vert) :scale #t) - (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id camera-controls-original) :scale #t) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id restore-defaults) :scale #t) (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) ) ) @@ -272,7 +288,7 @@ (defun find-highest-resolution () (let ((sx 0) (sy 0) (found #f) (mult GAME_MIN_RES_MULT) (lastr 0) (hir 0) (lor 0)) - (pc-get-screen-size -1 (the (pointer int32) (& sx)) (the (pointer int32) (& sy)) (the (pointer int32) 0)) + (pc-get-screen-size -1 (the (pointer int32) (& sx)) (the (pointer int32) (& sy))) (if (> sy sx) (set! sy sx)) @@ -342,25 +358,25 @@ (set! (-> *temp-options* length) 0) - (let ((done? #f) (mult (find-highest-resolution)) (sx 0) (sy 0) (vmodes 0) (flip? #f) (aspect 0.0) + (let ((done? #f) (mult (find-highest-resolution)) (sx 0) (sy 0) (flip? #f) (aspect 0.0) ;; hack - do not use screen resolution in windowed mode, taskbar etc. messes it up and makes it useless! (skip? (= 'windowed (pc-get-fullscreen))) ;; shortcut (max-options (1- (-> *temp-options* allocated-length)))) + ;; get screen size (for capping) + (pc-get-screen-size -1 (the (pointer int32) (& sx)) (the (pointer int32) (& sy))) ;; portrait mode. unused (set! flip? (> sy sx)) - ;; get screen size (for capping) - (pc-get-screen-size -1 (the (pointer int32) (& sx)) (the (pointer int32) (& sy)) (the (pointer int32) (& vmodes))) (case (pc-get-fullscreen) (('fullscreen) ;; insert psyched out trollface here (set! sx 0) (set! sy 0) - (countdown (i vmodes) + (countdown (i (pc-get-screen-vmode-count)) (let ((thisx 0) (thisy 0)) - (pc-get-screen-size i (the (pointer int32) (& thisx)) (the (pointer int32) (& thisy)) (the (pointer int32) 0)) + (pc-get-screen-size i (the (pointer int32) (& thisx)) (the (pointer int32) (& thisy))) (when (not (and (= thisx sx) (= thisy sy))) (add-resolution-option thisx thisy) @@ -389,7 +405,8 @@ (when (and (not skip?) (< (length *temp-options*) max-options) (<= thisy sy) (<= thisx sx) - (= aspect (/ (the float thisx) (the float thisy)))) + (= aspect (/ (the float thisx) (the float thisy))) + (>= thisx PC_MIN_WIDTH) (>= thisy PC_MIN_HEIGHT)) (add-resolution-option thisx thisy) )) (false! skip?) @@ -524,7 +541,20 @@ ;; set up options for each screen (set! (-> *options-remap* (progress-screen settings)) *main-options*) (set! (-> *options-remap* (progress-screen game-settings)) *game-options-pc*) - (set! (-> *options-remap* (progress-screen graphic-settings)) *graphic-options-pc*) + (let ((max-refresh-rate (pc-get-screen-rate -1))) + (cond + ((or *debug-segment* (> max-refresh-rate 100)) + (set! (-> *options-remap* (progress-screen graphic-settings)) *graphic-options-pc*) + (set! *carousell-frame-rate* *carousell-frame-rate-150fps*) + ) + ((> max-refresh-rate 60) + (set! (-> *options-remap* (progress-screen graphic-settings)) *graphic-options-pc*) + (set! *carousell-frame-rate* *carousell-frame-rate-100fps*) + ) + (else + (set! (-> *options-remap* (progress-screen graphic-settings)) *graphic-options-no-frame-rate-pc*) + ) + )) (set! (-> *options-remap* (progress-screen sound-settings)) *sound-options-pc*) (set! (-> *options-remap* (progress-screen memcard-no-space)) *ok-options*) @@ -578,8 +608,6 @@ (set! (-> *game-options-demo* 0 value-to-modify) (&-> *setting-control* default vibration)) (set! (-> *game-options-demo* 1 value-to-modify) (&-> *setting-control* default play-hints)) (set! (-> *graphic-options* 1 value-to-modify) (&-> *progress-state* aspect-ratio-choice)) - (set! (-> *graphic-title-options-pal* 1 value-to-modify) (&-> *progress-state* video-mode-choice)) - (set! (-> *graphic-title-options-pal* 2 value-to-modify) (&-> *progress-state* aspect-ratio-choice)) (set! (-> *sound-options* 0 value-to-modify) (&-> *setting-control* default sfx-volume)) (set! (-> *sound-options* 1 value-to-modify) (&-> *setting-control* default music-volume)) (set! (-> *sound-options* 2 value-to-modify) (&-> *setting-control* default dialog-volume)) @@ -588,10 +616,16 @@ ;(set! (-> *game-options-pc* 0 value-to-modify) (&-> *setting-control* default vibration)) (set! (-> *game-options-pc* 0 value-to-modify) (&-> *setting-control* default play-hints)) (set! (-> *graphic-options-pc* 1 value-to-modify) (&-> *progress-carousell* int-backup)) - (set! (-> *graphic-options-pc* 2 value-to-modify) (&-> *progress-carousell* aspect-native-choice)) - (set! (-> *graphic-options-pc* 3 value-to-modify) (&-> *progress-state* aspect-ratio-choice)) - ;(set! (-> *graphic-options-pc* 5 value-to-modify) (&-> *progress-carousell* int-backup)) - (set! (-> *graphic-options-pc* 5 value-to-modify) (&-> *progress-carousell* int-backup)) + (set! (-> *graphic-options-pc* 2 value-to-modify) (&-> *pc-settings* vsync?)) + (set! (-> *graphic-options-pc* 3 value-to-modify) (&-> *progress-carousell* aspect-native-choice)) + (set! (-> *graphic-options-pc* 4 value-to-modify) (&-> *progress-state* aspect-ratio-choice)) + ;(set! (-> *graphic-options-pc* 6 value-to-modify) (&-> *progress-carousell* int-backup)) + (set! (-> *graphic-options-pc* 6 value-to-modify) (&-> *progress-carousell* int-backup)) + (set! (-> *graphic-options-no-frame-rate-pc* 1 value-to-modify) (&-> *progress-carousell* int-backup)) + (set! (-> *graphic-options-no-frame-rate-pc* 2 value-to-modify) (&-> *pc-settings* vsync?)) + (set! (-> *graphic-options-no-frame-rate-pc* 3 value-to-modify) (&-> *progress-carousell* aspect-native-choice)) + (set! (-> *graphic-options-no-frame-rate-pc* 4 value-to-modify) (&-> *progress-state* aspect-ratio-choice)) + ;(set! (-> *graphic-options-pc* 6 value-to-modify) (&-> *progress-carousell* int-backup)) (set! (-> *misc-options* 0 value-to-modify) (&-> *pc-settings* discord-rpc?)) (set! (-> *camera-options* 0 value-to-modify) (&-> *pc-settings* first-camera-h-inverted?)) (set! (-> *camera-options* 1 value-to-modify) (&-> *pc-settings* first-camera-v-inverted?)) @@ -1018,7 +1052,7 @@ (load-level-text-files (-> *level-task-data* (-> obj display-level-index) text-group-index)) (set! (-> obj next-display-state) (progress-screen invalid)) ) - (((game-text-id camera-controls-original)) + (((game-text-id restore-defaults)) ;; restore default camera controls (reset-original-camera *pc-settings*) (sound-play "cursor-options") @@ -1211,9 +1245,9 @@ ) (((game-option-type frame-rate)) (case (-> *progress-carousell* int-backup) - ((0) (set! (-> *setting-control* default video-mode) 'ntsc)) - ((1) (set! (-> *setting-control* default video-mode) '100fps)) - ((2) (set! (-> *setting-control* default video-mode) '150fps)) + ((0) (set-frame-rate! *pc-settings* 60)) + ((1) (set-frame-rate! *pc-settings* 100)) + ((2) (set-frame-rate! *pc-settings* 150)) ) (set-video-mode (-> *setting-control* default video-mode)) ) @@ -1473,13 +1507,13 @@ (case (-> obj display-state) (((progress-screen music-player)) (set-color! font (font-color default)) - (set-origin! font (- 17 (-> obj left-x-offset)) 15) + (set-origin! font (- 17 (-> obj left-x-offset)) 14) (set-scale! font (* 0.6 (-> obj transition-percentage-invert))) (print-game-text (lookup-text! *common-text* (game-text-id select-level) #f) font #f (the int (* 128.0 (-> obj transition-percentage-invert))) 22) ) (((progress-screen flava-player)) (set-color! font (font-color default)) - (set-origin! font (- 17 (-> obj left-x-offset)) 15) + (set-origin! font (- 17 (-> obj left-x-offset)) 14) (set-scale! font (* 0.6 (-> obj transition-percentage-invert))) (print-game-text (lookup-text! *common-text* (game-text-id select-flava) #f) font #f (the int (* 128.0 (-> obj transition-percentage-invert))) 22) )