diff --git a/game/graphics/opengl_renderer/debug_gui.cpp b/game/graphics/opengl_renderer/debug_gui.cpp index 48383211a2..5d3b1bf2ae 100644 --- a/game/graphics/opengl_renderer/debug_gui.cpp +++ b/game/graphics/opengl_renderer/debug_gui.cpp @@ -5,6 +5,7 @@ #include "common/global_profiler/GlobalProfiler.h" +#include "game/graphics/display.h" #include "game/graphics/gfx.h" #include "game/system/hid/sdl_util.h" @@ -151,6 +152,12 @@ void OpenGlDebugGui::draw(const DmaStats& dma_stats) { ImGui::TreePop(); } ImGui::Checkbox("Treat Pad0 as Pad1", &Gfx::g_debug_settings.treat_pad0_as_pad1); + auto is_keyboard_enabled = + Display::GetMainDisplay()->get_input_manager()->is_keyboard_enabled(); + if (ImGui::Checkbox("Enable Keyboard (forced on if no controllers detected)", + &is_keyboard_enabled)) { + Display::GetMainDisplay()->get_input_manager()->enable_keyboard(is_keyboard_enabled); + } ImGui::EndMenu(); } diff --git a/game/kernel/common/kmachine.cpp b/game/kernel/common/kmachine.cpp index f321f15de0..20a1bbc730 100644 --- a/game/kernel/common/kmachine.cpp +++ b/game/kernel/common/kmachine.cpp @@ -676,6 +676,13 @@ void pc_set_controller(u32 controller_id, u32 port) { } } +u32 pc_get_keyboard_enabled() { + if (Display::GetMainDisplay()) { + return bool_to_symbol(Display::GetMainDisplay()->get_input_manager()->is_keyboard_enabled()); + } + return bool_to_symbol(false); +} + void pc_set_keyboard_enabled(u32 sym_val) { if (Display::GetMainDisplay()) { Display::GetMainDisplay()->get_input_manager()->enable_keyboard(symbol_to_bool(sym_val)); @@ -921,6 +928,7 @@ void init_common_pc_port_functions( make_func_symbol_func("pc-get-controller-count", (void*)pc_get_controller_count); make_func_symbol_func("pc-get-controller-index", (void*)pc_get_controller_index); make_func_symbol_func("pc-set-controller!", (void*)pc_set_controller); + make_func_symbol_func("pc-get-keyboard-enabled?", (void*)pc_get_keyboard_enabled); make_func_symbol_func("pc-set-keyboard-enabled!", (void*)pc_set_keyboard_enabled); make_func_symbol_func("pc-set-mouse-options!", (void*)pc_set_mouse_options); make_func_symbol_func("pc-set-mouse-camera-sens!", (void*)pc_set_mouse_camera_sens); diff --git a/game/overlord/jak2/ssound.h b/game/overlord/jak2/ssound.h index 3701e75b07..47fdede72e 100644 --- a/game/overlord/jak2/ssound.h +++ b/game/overlord/jak2/ssound.h @@ -3,6 +3,8 @@ namespace jak2 { #define VOICE_BIT(voice) (1 << ((voice) >> 1)) +// Our CI is on an ancient version of clang-format, manually format this +// so we don't have to worry about the version locally // clang-format off #define CORE_BIT(voice) ((voice)&1) // clang-format on diff --git a/game/settings/settings.cpp b/game/settings/settings.cpp index b550f5359a..adcb819d8e 100644 --- a/game/settings/settings.cpp +++ b/game/settings/settings.cpp @@ -59,9 +59,10 @@ void DebugSettings::save_settings() { } void to_json(json& j, const DisplaySettings& obj) { - j = json{{"display_id", obj.display_id}, - {"window_xpos", obj.window_xpos}, - {"window_ypos", obj.window_ypos}}; + json_serialize(version); + json_serialize(display_id); + json_serialize(window_xpos); + json_serialize(window_ypos); } void from_json(const json& j, DisplaySettings& obj) { json_deserialize_if_exists(version); @@ -94,12 +95,13 @@ void DisplaySettings::save_settings() { } void to_json(json& j, const InputSettings& obj) { - j = json{{"version", obj.version}, - {"last_selected_controller_guid", obj.last_selected_controller_guid}, - {"controller_port_mapping", obj.controller_port_mapping}, - {"controller_binds", obj.controller_binds}, - {"keyboard_binds", obj.keyboard_binds}, - {"mouse_binds", obj.mouse_binds}}; + json_serialize(version); + json_serialize(last_selected_controller_guid); + json_serialize(controller_port_mapping); + json_serialize(controller_binds); + json_serialize(keyboard_binds); + json_serialize(mouse_binds); + json_serialize(keyboard_enabled); } void from_json(const json& j, InputSettings& obj) { @@ -109,6 +111,7 @@ void from_json(const json& j, InputSettings& obj) { json_deserialize_if_exists(controller_binds); json_deserialize_if_exists(keyboard_binds); json_deserialize_if_exists(mouse_binds); + json_deserialize_if_exists(keyboard_enabled); } InputSettings::InputSettings() { diff --git a/game/settings/settings.h b/game/settings/settings.h index 8293d7a3c8..4f161a6ffd 100644 --- a/game/settings/settings.h +++ b/game/settings/settings.h @@ -56,6 +56,9 @@ struct InputSettings { std::unordered_map controller_binds; InputBindingGroups keyboard_binds; InputBindingGroups mouse_binds; + bool keyboard_enabled = false; + bool keyboard_temp_enabled = + false; // not saved or restored, flips on if no controllers are detected void save_settings(); }; diff --git a/game/system/hid/input_manager.cpp b/game/system/hid/input_manager.cpp index 30b3f09e5c..b788d3250c 100644 --- a/game/system/hid/input_manager.cpp +++ b/game/system/hid/input_manager.cpp @@ -128,8 +128,10 @@ void InputManager::refresh_device_list() { lg::warn( "No active game controllers could be found or loaded successfully - inputs will not " "work!"); + m_settings->keyboard_temp_enabled = true; } else { lg::info("Found {} controllers", m_available_controllers.size()); + m_settings->keyboard_temp_enabled = false; } } } @@ -203,7 +205,7 @@ void InputManager::process_sdl_event(const SDL_Event& event) { } void InputManager::poll_keyboard_data() { - if (m_keyboard_enabled && m_skip_polling_for_n_frames <= 0 && !m_waiting_for_bind) { + if (is_keyboard_enabled() && m_skip_polling_for_n_frames <= 0 && !m_waiting_for_bind) { if (m_data.find(m_keyboard_and_mouse_port) != m_data.end()) { m_keyboard.poll_state(m_data.at(m_keyboard_and_mouse_port)); } @@ -211,7 +213,7 @@ void InputManager::poll_keyboard_data() { } void InputManager::clear_keyboard_actions() { - if (m_keyboard_enabled) { + if (is_keyboard_enabled()) { if (m_data.find(m_keyboard_and_mouse_port) != m_data.end()) { m_keyboard.clear_actions(m_data.at(m_keyboard_and_mouse_port)); } @@ -427,8 +429,8 @@ int InputManager::update_rumble(int port, u8 low_intensity, u8 high_intensity) { } void InputManager::enable_keyboard(const bool enabled) { - m_keyboard_enabled = enabled; - if (!m_keyboard_enabled) { + m_settings->keyboard_enabled = enabled; + if (!m_settings->keyboard_enabled) { // Reset inputs as this device won't be able to be read from again! clear_inputs(); } diff --git a/game/system/hid/input_manager.h b/game/system/hid/input_manager.h index ea306ddc3f..600765e786 100644 --- a/game/system/hid/input_manager.h +++ b/game/system/hid/input_manager.h @@ -101,6 +101,9 @@ class InputManager { void reset_input_bindings_to_defaults(const int port, const InputDeviceType device_type); bool auto_hiding_cursor() { return m_auto_hide_mouse || m_mouse.is_camera_being_controlled(); } void hide_cursor(const bool hide_cursor); + bool is_keyboard_enabled() { + return m_settings->keyboard_enabled || m_settings->keyboard_temp_enabled; + } private: std::mutex m_event_queue_mtx; @@ -128,7 +131,6 @@ class InputManager { /// Collection of arbitrary commands to run on user actions CommandBindingGroups m_command_binds; - bool m_keyboard_enabled = true; bool m_mouse_enabled = false; int m_skip_polling_for_n_frames = 0; bool m_auto_hide_mouse = true; diff --git a/goal_src/jak1/kernel-defs.gc b/goal_src/jak1/kernel-defs.gc index e8ae838d62..4de78d369c 100644 --- a/goal_src/jak1/kernel-defs.gc +++ b/goal_src/jak1/kernel-defs.gc @@ -346,6 +346,7 @@ (define-extern pc-set-waiting-for-bind! (function int symbol symbol int none)) (define-extern pc-stop-waiting-for-bind! (function none)) (define-extern pc-set-controller! (function int int none)) +(define-extern pc-get-keyboard-enabled? (function symbol)) (define-extern pc-set-keyboard-enabled! (function symbol none)) (define-extern pc-set-mouse-options! (function symbol symbol symbol none)) (define-extern pc-set-mouse-camera-sens! (function float float none)) diff --git a/goal_src/jak1/pc/pckernel-common.gc b/goal_src/jak1/pc/pckernel-common.gc index 5d673d2bea..c480097a8f 100644 --- a/goal_src/jak1/pc/pckernel-common.gc +++ b/goal_src/jak1/pc/pckernel-common.gc @@ -375,12 +375,6 @@ (pc-ignore-background-controller-events! val) (none)) -(defmethod set-enable-keyboard! pc-settings ((obj pc-settings) (val symbol)) - "sets whether to ignore keyboard input events" - (set! (-> obj keyboard-enabled?) val) - (pc-set-keyboard-enabled! val) - (none)) - (defmethod update-mouse-controls! pc-settings ((obj pc-settings)) "Uses whatever is set on the [[pc-settings]] to update the runtime on how it should interpret mouse events" (pc-set-mouse-options! (-> obj mouse-enabled?) (-> obj mouse-camera?) (-> obj mouse-movement?)) @@ -668,7 +662,9 @@ (("controller-eco-led?") (set! (-> obj controller-led-eco?) (file-stream-read-symbol file))) (("controller-heat-led?") (set! (-> obj controller-led-heat?) (file-stream-read-symbol file))) (("stick-deadzone") (set! (-> obj stick-deadzone) (file-stream-read-float file))) - (("keyboard-enabled?") (set-enable-keyboard! obj (file-stream-read-symbol file))) + ;; TODO - remove this eventually, setting moved into json input-settings + ;; has to stay here or the settings parsing code explodes + (("keyboard-enabled?") (file-stream-read-symbol file)) (("mouse-enabled?") (set! (-> obj mouse-enabled?) (file-stream-read-symbol file))) (("mouse-camera?") (set! (-> obj mouse-camera?) (file-stream-read-symbol file))) (("mouse-xsens") (set! (-> obj mouse-xsens) (file-stream-read-float file))) @@ -754,7 +750,6 @@ (format file " (controller-led-min-brightness ~f)~%" (-> obj controller-led-min-brightness)) (format file " (controller-led-max-brightness ~f)~%" (-> obj controller-led-max-brightness)) (format file " (stick-deadzone ~f)~%" (-> obj stick-deadzone)) - (format file " (keyboard-enabled? ~A)~%" (-> obj keyboard-enabled?)) (format file " (mouse-enabled? ~A)~%" (-> obj mouse-enabled?)) (format file " (mouse-camera? ~A)~%" (-> obj mouse-camera?)) (format file " (mouse-xsens ~f)~%" (-> obj mouse-xsens)) @@ -834,6 +829,7 @@ ;; if saved settings are corrupted or not found, the object will be fully reset to use all defaults (load-settings obj) ;; any post-operations that need to be done after loading + (set! (-> obj keyboard-enabled?) (pc-get-keyboard-enabled?)) (update-mouse-controls! obj) obj) diff --git a/goal_src/jak1/pc/pckernel-h.gc b/goal_src/jak1/pc/pckernel-h.gc index 169d5716f9..f001b3dc3f 100644 --- a/goal_src/jak1/pc/pckernel-h.gc +++ b/goal_src/jak1/pc/pckernel-h.gc @@ -152,7 +152,7 @@ (controller-led-max-brightness float) (controller-led-color rgbaf :inline) (stick-deadzone float) ;; analog stick deadzone. 0-1 - (keyboard-enabled? symbol) + (keyboard-enabled? symbol) ;; NOTE - this is here solely to satisfy jak 1's menu design, the setting has been moved into `input-settings.json` (mouse-enabled? symbol) (mouse-camera? symbol) (mouse-xsens float) @@ -258,7 +258,6 @@ (commit-to-file (_type_) none) (load-settings (_type_) int) (set-ignore-controller-in-bg! (_type_ symbol) none) - (set-enable-keyboard! (_type_ symbol) none) (update-mouse-controls! (_type_) none) (debug-font-scale-factor (_type_) float) ) @@ -389,9 +388,9 @@ (set! (-> obj controller-led-min-brightness) 0.25) (set! (-> obj controller-led-max-brightness) 1.0) ) - + (when (or (= device 'all) (= device 'input)) - (set! (-> obj keyboard-enabled?) #t) + (set! (-> obj keyboard-enabled?) #f) (set! (-> obj mouse-enabled?) #f) (set! (-> obj auto-hide-cursor?) #t) ) diff --git a/goal_src/jak1/pc/pckernel-impl.gc b/goal_src/jak1/pc/pckernel-impl.gc index 4c312f64b6..b13c8db7ac 100644 --- a/goal_src/jak1/pc/pckernel-impl.gc +++ b/goal_src/jak1/pc/pckernel-impl.gc @@ -43,7 +43,7 @@ (big-head-npc) (oh-my-goodness) ) - + ;; pc enum for languages. this is the game's languages + custom ones. (defenum pc-language :type uint16 @@ -184,7 +184,7 @@ (set! (-> obj cheats) (pc-cheats)) (set! (-> obj cheats-known) (pc-cheats)) - + (dotimes (i PC_SPOOL_LOG_LENGTH) (set! (-> obj scenes-seen i) 0) ) diff --git a/goal_src/jak1/pc/progress-pc.gc b/goal_src/jak1/pc/progress-pc.gc index ed47d8ff7c..7c0d330c76 100644 --- a/goal_src/jak1/pc/progress-pc.gc +++ b/goal_src/jak1/pc/progress-pc.gc @@ -245,7 +245,7 @@ (new 'static 'game-option :option-type (game-option-type menu) :name (text-id input-opts-binds-controller) :scale #t :param3 (game-option-menu controller-binds) :option-disabled-func (lambda () (<= (pc-get-controller-count) 0))) (new 'static 'game-option :option-type (game-option-type menu) :name (text-id input-opts-binds-keyboard) :scale #t :param3 (game-option-menu keyboard-binds) - :option-disabled-func (lambda () (not (-> *pc-settings* keyboard-enabled?)))) + :option-disabled-func (lambda () (not (pc-get-keyboard-enabled?)))) (new 'static 'game-option :option-type (game-option-type menu) :name (text-id input-opts-binds-mouse) :scale #t :param3 (game-option-menu mouse-binds) :option-disabled-func (lambda () (not (-> *pc-settings* mouse-enabled?)))) (new 'static 'game-option :option-type (game-option-type button) :name (text-id back) :scale #t))) @@ -257,7 +257,8 @@ (new 'static 'game-option :option-type (game-option-type on-off) :name (text-id input-opts-enable-kb) :scale #t :on-change (lambda ((val object)) (let ((val-sym (the-as symbol val))) - (set-enable-keyboard! *pc-settings* val-sym) + (pc-set-keyboard-enabled! val-sym) + (set! (-> *pc-settings* keyboard-enabled?) val-sym) (none)))) (new 'static 'game-option :option-type (game-option-type on-off) :name (text-id input-opts-enable-mouse) :scale #t :on-change (lambda ((val object)) @@ -277,7 +278,7 @@ (new 'static 'game-option :option-type (game-option-type confirmation) :name (text-id restore-defaults) :scale #t :on-confirm (lambda () (reset-input *pc-settings* 'input #t) - (set-enable-keyboard! *pc-settings* (-> *pc-settings* keyboard-enabled?)) + (pc-set-keyboard-enabled! (-> *pc-settings* keyboard-enabled?)) (update-mouse-controls! *pc-settings*) (none))) (new 'static 'game-option :option-type (game-option-type button) :name (text-id back) :scale #t))) diff --git a/goal_src/jak2/kernel-defs.gc b/goal_src/jak2/kernel-defs.gc index 5e947a8213..661e629702 100644 --- a/goal_src/jak2/kernel-defs.gc +++ b/goal_src/jak2/kernel-defs.gc @@ -183,6 +183,7 @@ (define-extern pc-stop-waiting-for-bind! (function none)) (define-extern pc-get-controller-index (function int int)) (define-extern pc-set-controller! (function int int none)) +(define-extern pc-get-keyboard-enabled? (function symbol)) (define-extern pc-set-keyboard-enabled! (function symbol none)) (define-extern pc-set-mouse-options! (function symbol symbol symbol none)) (define-extern pc-set-mouse-camera-sens! (function float float none)) diff --git a/goal_src/jak2/pc/pckernel.gc b/goal_src/jak2/pc/pckernel.gc index 6ff09deb22..fa3a198eb4 100644 --- a/goal_src/jak2/pc/pckernel.gc +++ b/goal_src/jak2/pc/pckernel.gc @@ -60,7 +60,7 @@ (when (= (get-base-height *ocean-map*) -216498.17) (set! (-> *pc-cheat-state* sewer-valve-start-time) (get-current-time)) ) - + ;; no cheating! (cond ((task-node-open? (game-task-node sewer-board-drain)) @@ -85,7 +85,7 @@ (else (let ( (time-taken (- (-> *pc-cheat-state* sewer-valve-end-time) (-> *pc-cheat-state* sewer-valve-start-time)))) - + (and (< 0 time-taken) (< time-taken (seconds (-> *pc-cheat-state* sewer-valve-target-seconds))) (= #b111 (-> *pc-cheat-state* sewer-valve-on))) @@ -236,7 +236,7 @@ (defmethod enable ((this led-fader-state) (start-from vector)) "begin transition." - + (when (-> this enable?) (disable this)) @@ -247,7 +247,7 @@ (defmethod disable ((this led-fader-state)) "disable transition." - + (set! (-> this amount) 0.0) (update this 0.0 0.1) (false! (-> this enable?)) @@ -291,7 +291,7 @@ (defmethod update ((this led-fader-state) (to float) (duration float)) "disable transition." - + (when (-> this enable?) (seek! (-> this amount) to (/ (-> *target* clock seconds-per-frame) duration)) (vector4-lerp! (-> this cur-color) (-> this start-color) (-> this end-color) (-> this amount)) @@ -363,7 +363,7 @@ "Set the default misc settings" ((method-of-type pc-settings update) obj) - + (set! *hires-sky* (-> obj hires-clouds?)) (when (not (led-enabled? obj)) @@ -448,7 +448,7 @@ (defmethod update-led ((obj pc-settings-jak2)) "set the controller led color by modifying the controller-led-color vector" - + ;; default color is just blue. (set-vector-xyz! (-> obj controller-led-color) 0.0 0.0 1.0) @@ -533,7 +533,7 @@ (set-vector-xyz! (-> obj controller-led-color) 0.6875 0.6 0.78125)) ) ) - + ;; darkjak ((and (nonzero? (-> *target* darkjak)) (focus-test? *target* dark)) (vector-copy! (-> *led-fader-state* end-color) *led-darkjak-color*) @@ -545,23 +545,23 @@ (update *led-fader-state* 1.0 0.3)) (vector3-copy!! (-> obj controller-led-color) (-> *led-fader-state* cur-color)) ) - + ;; indax ((focus-test? *target* indax) (set-vector-xyz! (-> obj controller-led-color) 1.0 0.5 0.0) ) - + ;; mech ((focus-test? *target* mech) (set-vector-xyz! (-> obj controller-led-color) 1.0 1.0 0.0) ) - + ;; board ((focus-test? *target* board) (set-vector-xyz! (-> obj controller-led-color) 0.0 1.0 1.0) ) ) - + ;; wanted flash (awhen (the hud-map (process-by-name "hud-map" *active-pool*)) (when (not (hidden? it)) @@ -641,7 +641,7 @@ ;; check unlocked cheats ;;;;;;;;;;;;;;;;;;;;;;;; (dotimes (i (-> *pc-cheats-list* length)) - + ;; reveals cheats if they have been purchased, purchases cheats if they have been unlocked, unlocks cheats if they have been enabled. ;; the cheat process requires the steps to be filled in this order, see sequential checking below (logior! (-> *pc-settings* cheats-revealed) (logior! (-> *pc-settings* cheats-purchased) (logior! (-> *pc-settings* cheats-unlocked) (-> *pc-settings* cheats)))) @@ -649,7 +649,7 @@ (let* ((cheat (-> *pc-cheats-list* i)) (cost (-> cheat skill)) (unlock-func (the (function symbol) (-> cheat unlock-func value)))) - + (when (if (logtest? (-> *game-info* secrets) (game-secrets hero-mode)) (task-node-closed? (-> cheat avail-after-hero)) (task-node-closed? (-> cheat avail-after))) @@ -657,7 +657,7 @@ (when (>= (-> *game-info* skill-total) cost) (logior! (-> obj cheats-purchased) (-> cheat flag)) - + (when (or (zero? unlock-func) (not unlock-func) (unlock-func)) diff --git a/goal_src/jak2/pc/progress/progress-static-pc.gc b/goal_src/jak2/pc/progress/progress-static-pc.gc index 535d11dc54..7da0fa6f29 100644 --- a/goal_src/jak2/pc/progress/progress-static-pc.gc +++ b/goal_src/jak2/pc/progress/progress-static-pc.gc @@ -188,10 +188,8 @@ This gives us more freedom to write code how we want. :name (text-id progress-input-options-enable-keyboard) :truthy-text (text-id progress-on) :falsey-text (text-id progress-off) - :get-value-fn (lambda () (-> *pc-settings* keyboard-enabled?)) - :on-confirm (lambda ((val symbol)) - (set! (-> *pc-settings* keyboard-enabled?) val) - (pc-settings-save))) + :get-value-fn (lambda () (pc-get-keyboard-enabled?)) + :on-confirm (lambda ((val symbol)) (pc-set-keyboard-enabled! val))) (new 'static 'menu-generic-boolean-option :name (text-id progress-input-options-enable-mouse) :truthy-text (text-id progress-on) @@ -265,7 +263,7 @@ This gives us more freedom to write code how we want. :entries (select l3 r3 start dpad-up dpad-right dpad-down dpad-left l2 r2 l1 r1 triangle circle cross square) :confirm ((text-id progress-restore-defaults) (lambda () (pc-reset-bindings-to-defaults! 0 0)))) (progress-new-generic-link-to-keybind-details-page (text-id progress-reassign-binds-keyboard) - :should-disable? (lambda () (not (-> *pc-settings* keyboard-enabled?))) + :should-disable? (lambda () (not (pc-get-keyboard-enabled?))) :device-type keyboard :entries (l-analog-up l-analog-down l-analog-left l-analog-right r-analog-up r-analog-down r-analog-left r-analog-left r-analog-right select l3 r3 start dpad-up dpad-right dpad-down dpad-left l2 r2 l1 r1 triangle circle cross square) @@ -279,7 +277,7 @@ This gives us more freedom to write code how we want. :name (text-id progress-restore-defaults) :on-confirm (lambda ((val symbol)) (reset-input *pc-settings* 'input #t) - (set-enable-keyboard! *pc-settings* (-> *pc-settings* keyboard-enabled?)) + (pc-set-keyboard-enabled! (-> *pc-settings* keyboard-enabled?)) (update-mouse-controls! *pc-settings*) (pc-settings-save)))))