Use the SDL gamepad API to add full gamepad support. Adds rumble for supported
gamepads and changes the FF in-game options to take immediate effect instead
of requiring a restart.
Additionally this makes changes to allow gamepad triggers to be used as both
an axis and a button. This support is specific to gamepads since we can
explicitly identify the trigger with the API and act on it accordingly. FSO
control config doesn't currently support such an action directly however so
we have to hack it in just a bit. Due to this the control binding will show
the trigger axis name bound to a button control only while a gamepad is
connected, otherwise it shows a button name associated with the trigger.
Setting SDL_HINT_JOYSTICK_THREAD=1 before SDL_InitSubSystem(SDL_INIT_JOYSTICK)
tells SDL2 to run joystick polling and HID device-detection on a dedicated
background thread, rather than processing them inline inside SDL_PollEvent
on the main thread.
Without this hint, every WM_DEVICECHANGE broadcast (which Windows sends when
*any* HID device wakes, sleeps, or pulses the USB bus) causes SDL to walk
every HID device class via SetupAPI / cfgmgr32 from inside SDL_PollEvent,
stalling the frame loop for multiple seconds on machines with many HID
peripherals - especially wireless Logitech mice and keyboards that
periodically pulse the bus. Diagnosed via ProcMon stack capture on one
affected user's machine, with the slow frame's call chain ending in
SDL2.dll -> SETUPAPI.dll -> cfgmgr32.dll -> kernel registry queries against
HKLM\System\CurrentControlSet\Enum\HID\*.
With the hint enabled, that work happens on SDL's own thread and the main
thread just dequeues already-collected events.
Add coverity[GLOBAL_INIT_ORDER] annotations to ~50 global variables
across 27 files. These were all analyzed and confirmed safe:
- ~48 OptionBuilder::finish() globals use a Meyers singleton
(OptionsManager::instance()), which guarantees safe init order.
Destruction is also safe due to shared_ptr ref-counting.
- 6 default-constructed container globals (vectors, maps) have no
cross-TU dependencies at construction or destruction time.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Update haptic code with changes from icculus.org tree which optimizes
effect loading to better support low-memory devices and no longer
requires full support of every haptic effect type. Additionally...
- avoids attempting FF init for non-haptic devices
- avoids attempting FF init for gamepads
- properly resets FF when device is hot-plugged
- better start/stop/update of effects
- avoid stopping effects unless really needed
- use timestamp for dir effect restarts instead of sys calls
- avoid playing FF effects when window is in background
- general code cleanup
For every move and move-assignment constructor, do the following:
1. Make it default if possible
2. Add or delete where appropriate
3. Check for move-onto-self
4. Apply `std::move` where needed
Also fix problematic moves in `player_h`
* Create the ingame options game state
* Base working version of in-game options
* Cleanup + Optimization
* Localization pass
* more cleanup + documentation
* tooltips on option hover
* documentation and better inbounds check
* match case
* format strings instead of direct strings
* unused parameter
* address feedback
* localization id conflict with master
* Add this line back in
* pass the new option flags as well
* resolve xstr id conflict
This advances the versions for Clang to 16 and GCC to 13 along with
fixing any warnings these new versions are detecting now.
The new image versions also include Vulkan so the additional workflow
step for installing that is not necessary anymore.
* In fillValues(), Check the size values returned by SDL to assert they are non-negative. If they are negative, abort vector resize and mprintf the SDL Error.
Add XSTR entries for "or", "None", and "Nothing".
Note that there is already an XSTR entry for "none", but it does not have the right capitalization.
Note that "None" is localized in `textify_scancode` but not `textify_scancode_universal`.
This makes "Nothing" cargo use appropriate localization.
Fixes#5227.
Locale Sensitive Controls and Textfield Input
+ Add Keyboard Layout sensitive InputBoxes
+ Remove obsolete helper function
* Fig [] usage and remove old keybinding names
+ Fix Compile Warnings
+ Fix Compile Warnings 2
+ Fix Clang Warnings
+ Fix faulty style + remove lambda
+ Change reverse-lookup map to iterating function
+ Added controlconfigdefault.tbl generator
+ Fixed gcc warning
+ Fixed msvc warning
+ make debug console keyboard layout independent
+ Expand DCF Functionality for saving control presets
+ Address Issues
* Controls/update tbl (#5)
Updates controlconfigdefaults.tbl to write Primary and Secondary bindings.
* Added Scripting Hooks for controlsconfigdefault.tbl (#6)
* Handle Asserted Switch cases
* Controls is a library and should be in the libs folder
* Add Lock & EnableScripting Functionality and expose it to scripting API
* Added scripting isLocked
* Move Key Hooks to register-able callback
* Add option to remove hook
* Repurpose CCI.used for Axes
* Morph bitfield into a singleton class
* Add encoding conversion helpers
+ Add keyname conversion if needed
+ Merge refactored encoding functions
+ Change keycode encoding call
+ remove bad type modifier
+ Move Conversion functions to util/unicode
+ Change Encoding Enum to Enum Class
+ Adapt KeyName call for encoding enum class
+ Fix Warning due to enum class
+ Change validation to own function
* Make mActionToVal Assertion more helpful
* Fix typo
* Fix style
* Use constant, not magic number
* Document Ignored_keys[]
* Doxy class controls_lua_override_cache a bit better
* Put NameToVal safeties back in
* Reorder the +Disable and $Disable: options, and be exclusive
* Reorder the +Locked and $Loacked options, and be exclusive
* Revert changes in ValToJoy
* Revert errant duplicates
* Refactor printJoyJSON() to use getJsonArray for consistency
* Remove unused FS2toSDL map
* Remove ADE_FUNC(AxisActionInverted)
* Address gcc-5 issues
* Remove unused param for textify_scancode
* Declare textify_scancode_universal() in controlsconfig.h for use
* Clean up textify_scancode() and *_universal() a smidge for clarity
* Address most clang-9 issues
* Modernize NULL to nullptr
* Expand logic and document in controlsconfig::check_control() for clarity.
* Fix typo
* Remove unecassary static_cast
* Use Assertion instead of Assert within control_config_common_read_section()
* mprintf()'s need new lines!
Co-authored-by: Birk Magnussen <[email protected]>
Co-authored-by: Birk Magnussen <[email protected]>
* Updates the AxisInverted hooks to use the new CC_bind. Currently assumes only Joy0, so this may need further tweaking or replacement
* * Add ability to claim up to 4 joysticks for player use, using the launcher (via registry or fs2_open.ini) or the new menu system
* Hack into existing control polling system to get the new primary/secondary binding schema to work. This should be reworked into a reverse-lookup system.
* Finally break the mouse loose from overlapping with Joystick binidngs
* Fix bug where joy button wouldn't register on search function
* Fix bug with mousewheel not always decaying as it should.
* Fix rebase conflict with selecting item during search mode
* Fix bug where mouse buttons were incorrectly labeled.
* Move some enums around
* Fix bug with joy axis labels being displayed as buttons.
* Fix possible bug where Other conflict axis wouldn't clear
* Updated default joystick axis text. A new strings.tbl will need to be supplied for localization support
* Deprecate nAxisInverted ADE functions and replace with AxisInverted(int, int, bool)
* Merge Axis mappings into Control_config
* More utility functions for CC_bind and CCB
* Adds another ADE function for inverting the axis action, instead of individual bindings
* Hacks to get plr file to compile. Currently slices out many of the new features like secondary axis and the mouse axis, and the additional joystick bindings (joy1, joy2, joy3)
* Fix bug with uncontrollable spin (slopily)
* Fix some warnings
* Add flags for Hats and Balls for future implementation
* Fix bug where inverting an axis would trigger an assert
* Fix bug where joy wasn't detected as present
* Most axis actions should be relative, instead of absolute
* Hopefully optimize joy_get_unscaled_reading
* Properly break out of double-for search function for search and bind modes in config menu
* Refactor control_get_axes_readings to provide more consistent behavior
* Use JOY_REL_THROTTLE instead of Action::REL_THROTTLE when indexing into Control_config
* Bank axis has a default binding, Throttle does not.
* Fix bug where conflicts weren't being detected.
Fix bug where default presets weren't being detectd
* Elegantly break out of double fors with goto.
Fix bug with bind mode not detecting axis
* Save new binding scheme to playerfile
* Add cid_assign() to standardize cid assignment with shorts
* Add write and read handlers for int8_t
* Remove saving controls to csg. This will be replaced by presets.
* Fix bug with reading pilotfile
* Use "Joy-n" instead of "joystick n" to match default identifiers in config menu
* Fix bug with CC_TYPE_TRIGGER controls always marked as used, if not bound with a key.
Fix bug with Joy-0 btn 1 triggering multiple controls that are not bound to it.
* Improve readibility of the joy info output to log
* Message when a joystick connects and using legacy system.
* Fix bug where system joystick 0 was mapped in pJoystick that should've been nullptr
* Fix bug where *not* having a joystick will cause bind mode in the config menu to immediately cancel.
* Add reverse lookup functions for actions. mActionToVal[] does string -> int, mValToAction() does int -> string
* Add the foundation for writing the presets files.
* Adds a bunch of reverse lookup functions to get the stringified version of various enums, etc.
* presets.h and presets.cpp are in something of a barebones at this point
* Add new subdir for preset files 'player/presets'
* add utility for finding the distance of a bitfield/bitmask. Used to translate mouse button masks into mouse button id's
* Write PresetFileHandler as standalone, instead of a subclass. Still mostly a copy of JSONFileHandler
* Make functions to map and reverse-map the bindings for use with the preset files and ultimately the ControlConfigDefaults.tbl as well
* Check presets from file to see if they are duplicate with an existing preset.
* Check for uniqueness of presets fron controlconfigdefaults.tbl before adding them, and warn the user if there are duplicates.
* Rename the test functions into proper load/save.
* save function has some standard checks
* load function is called on init
* make finding duplicates its own function outside of the preset label rendering function
* Initial draft of saving presets in-game
* Fix bug where all loaded presets were thought to be duplicate of defaults.
* Fix bug where preset cycling would get stuck on the first preset other than default
* Fix bug where saving a mouse button saves the wrong textified string.
* Prevent preset names from being too long.
* Crash still occurs if the name is too long, as if set outside of FSO
* Workaround text running off the popups in 640x480. Doesn't look as nice, sadly
* CSG's now track preset names instead of containing bindings
* remake control_config_reset_defaults() into control_config_use_preset()
* provide a function to get the currently selected preset.
* Do PLR backward compatibility, hopefully.
* PLR now tracks presets instead of saving the bindings.
* On Loading pre PLR3 or CSG6 data, create a new preset.
* Strip off file extension before saving preset files. Jason.json.json just looks dumb
* Add "-joy_info" commandline option. Will output SDL joystick info of all detected joysticks to stdout
* Fix non-standard behavior with registry_read_string().
* Returning NULL instead of the default value, or an empty string, will trigger an access violation with SCP_string and other string copy functions.
* Modify io::joystick::init() to take an optional param, no_register, to use with -joy_info
* Address CI complaints
* Address CI issues 2.
* Supress preset duplicate warning if in unit tests.
* Address scripting unittest failure due to incorrect argument type. (Ints don't technically exist in LUA)
* Use Mouse enums instead of Joy enums or magic numbers
* More signed/unsigned madness
* Address CI issues 3
* Address gcc-5 issues. (No auto in lambdas)
* Fix bug with bit_distance()
* Address gcc-5 issues 2
* Address clang issues
* Address clang-tidy issues
* Address clang-tidy issues in undosys. May need to be cherry picked to Controls2.
* Address clang-tidy issues
* Improve logic of preset name prompt.
* Fix bug with selected presets not being saved
* No, a cstr is not a std::string.
* Can't use i there because its already defined.
* Fix bug where CSG's wouldn't save selected preset
* Fix bug where presets wouldn't be loaded correctly from player files
* Fix bug where loaded preset files would not update the preset cycle position correctly
* Some QoL changes for the preset name prompt
* Address Appveyor issues.
* Add forward compatibility for player file. This is required because currently any "missing" data in the pilotfile will trigger an Error, and crash FSO.
* Fix bug where mouse X axis was unusable.
Apparently stating that MOUSE_Z_AXIS IS MOUSE_Z_AXIS doesn't get the point across.
* Address CI issues.
* Address CI issues.
* sel default assigned to -1
* static_cast enum to an int
* Assimilate -joy_info int -get_flags, replacing the existing method that launchers use to get joystick information.
* Add '\n' to PST log messages.
* Change logic of checking joystick .ini keys: Should the multi-joy key not be found, try legacy joy key.
* Add some more missing '\n' to mprintf messages.
* Notify the player when converting to the new multi-joy system. (Using ReleaseWarning for now...)
* Warn the player if a preset defined in their .PLR could not be found.
* Actually disable control items without a valid tab, instead of relying on the fact that they're disabled by default.
* Add CC_preset::is_duplicate_of() method to make checking for preset uniqueness less of a brain teaser.
* Doxy the first_override param of control_config_common_read_section
* Adds the os::dialogs::Information() method, which displays an information-only dialog in similar format to Warning and Error dialogs. Does not throw Warning nor Error exceptions
* load_player now uses os::dialogs::Information() instead of ::ReleaseWarning, thus not halting unit tests.
* Breaks retail localization support for Joystick and Mice labels - This is because the new multi-joy axis end up very confusing "Joy-0 Joystick/Mouse X Axis"
* Renames Joy_axis_text to Axis_text, intended to be used both by joysticks and the mouse.
* Moves mouse axis and button labels into an array to ease future XSTR support
* Adds asserts to ensure indices are within the array sizes of label arrays
* Adds XSTR indices for Axis labels, mouse buttons, and mouse wheels.
* Seperates conflict check comparisons from equality comparisons.
* Conflict checks can ignore certain combinations of CC_bind::flag's; i.e. an Axis bound to a different control but is inverted or relative will still cause a conflict with another control that has the same axis
* Equality comparisons is exact equality, allowing presets to check if binds have the same binding and flag configurations.
* More UI string changes and localization
* Tweaks positioning of top button labels in CC menu
* Adds the following XSTR's:
1659 "Preset: %s"
1660 "Preset: custom"
1661 "Next Preset"
* Fix bug where mouse axis turned into mouse button when inverting control by its control name.
* Fix bug with the new conflict checking subroutine not working with non-axis controls
* Address CI issues.
* Don't trigger modal popups while in unit tests.
* Address clang tidy issues
* use nullptr
* be consistent with conditional style
* use booleans to stuff debug states, methods with just Assertions in it will trigger a false positive on clang tidy
* use string::empty() instead of checking for "".
* Remove dead code of -joy_info. Functionality has been merged with -get_flags
* Address clang-tidy [readability-simplify-boolean-expr]
--z64 says "I don't like it!"
* fix axis check
* Implement revised axis action virtvars for scripting. Also protect against a control mismatch in the CSG file due to a script-inverted control
* Encapsulate CC_bind properly
* Add mouse and joystick cid's to AxisInverted description
* Update translate_key() and its user to correctly translate multijoy bindings for training messages.
* Prompt user trying to escape from config menu when they have changes.
* Remove dead function.
* Fix crash during training missions due to key translation that would overflow internal buffer.
* Went back with cstring as return value instead of SCP string, because caller would need a significant refactor
* Update doxy of the textify functions
* Unify textify_scancode() and textify_scancode_universal() to ensure common code path.
* Add "Multijoy" entry to json caps. (For Knossos)
* Make CI happy.
* Remove unused lambda captures.
* Instead of overwrite during plr2 => plr3 conversion, try to use the existing preset file.
* Fix conditional for checking if file exists within presets::save_preset_file()
* Revert Majority of PR#3739
* PLR and CSG versions are incremented past versions set by 3739
* Forward compatibility feature of #3739 (Only save sexp containers into the CSG if they are used) is removed
* Remove forward compatibilty of PLR file when going in between pre- and post-Controls5 FSO versions
* Add missing startSection() and endSection() for csg_write_controls()
* Fix clang-tidy error #1
* Fix clang-tidy error #2
* fix clandy tidy error #1 part 2/2
* Fix clang tidy error 3
Co-authored-by: Goober5000 <[email protected]>
Co-authored-by: Tyler Blount <[email protected]>
Co-authored-by: wookieejedi <[email protected]>
Co-authored-by: BMagnu <[email protected]>
This refactors the tolower/toupper code to use standards-conformant logic, and also adds some helpful utility functions. Regular tolower/toupper must be supplied a value that can be represented as `unsigned char`, but the std:: functions are a bit more robust.
This adds a mechanism for running generic operations at specific points
of the frame execution. This can be used by any part of the code an not
just Lua since it simply executes std::functions. It also adds an
"execution context" concept that specifies in which situation an
operation should be executed.
This is then used by the Lua Coroutines code for resuming coroutines at
specific points instead of always when the awaited promise resolves.
The largest new feature is that it is now possible to include other
files into the RML by using the "include" tag. This is useful for making
markup files more modular.
Also added some more options for existing things (e.g. built-in detail
options).
Not sure why we didn't catch this earlier but this should hopefully fix
the crash. The cause was that we constructed an SCP_string from a null
pointer instead of using the empty string as the default.
This is a system for storing arbitrary data in the config file and then
easily retrieving it later on. This has full Lua support for exposing
the available options in a custom UI and changing the values of the
options. This ported some of the existing command line options over to
the new system which is opt-in for the moment by using a mod_table flag.
Travis CI recently added support for running builds in Windows. This
adds support for testing compilation on Windows using that feature.
The newer version of Visual Studio and MinGW required some code changes
and an update of Google Test which is included in this commit.
Before, they were assuming any joystick had at least 1 hat; this way, they now treat it similarly to buttons. If requesting the status of a button the joystick doesn't have, they return 0. If the joystick doesn't have a hat, querying a hat position will likewise now also return 0. This code will obviously need changed when we get around to proper (e.g. multiple) hat support.
The new joystick API (commit f91c681ee1) didn't include calls to joy_ff_init() and joy_ff_shutdown(), disabling haptic support. Simply restoring these calls was enough to make it work on my system again.
If CurrentJoystickGUID was present but set to an empty string, the new code was comparing all joystick GUIDs against the empty string, and therefore concluding that no joystick was currently selected. This just treats an empty string as though CurrentJoystickGUID weren't set at all, allowing the index-based CurrentJoystick to take over.
Kobrar reported that joystick events were not properly assigned to the
right Joystick instances because the GUIDs of the joysticks was the same
(that's another problem since the code assumes that they actually are
Globally Unique like the name says).
The fix was to simply use the instance ID for checking if two sticks are
the same which seems to work more reliably.
* There's now registers for both 4 position and 8 position hats for both timestamps and downcounts
* There's conversion code to allow an 8-position hat to act like a 4-position hat, which is needed by the FSO codebase which only uses 4-pos hats
* There's also conversion code to allow a 4-pos hat to act like an 8-position hat to some degree.
getHatPosition() returns a value from the HatPosition enum, so the conversion to a 0-based index is incorrect (and causes the hat switch to basically not work with continuous controls).
When the hat switch code was fixed to restrict joysticks to 32 buttons again, it forgot to invalidate buttons between numButtons() and 32. This could lead to some assertions being failed when the joystick got asked for the status of a nonexistent button.
* Fix (undocumented) issue with hat presses not registering.
* Use array instead of a vector for _hat::DownCount
* No, no die-nam-ick numbor of boot-ons to-day. Und no, ve only haff vone hat. Sad Heavy is Sad.
* Fixes an out-of-bounds error caused by incorrect indexing in Joystick::handleHatEvent.
Also fixes a bug where the hatGetDownTime would return a nonzero value if the hat was active but in a different position than the input parameter.