-
-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathreadme.md.old
More file actions
1353 lines (1036 loc) · 110 KB
/
readme.md.old
File metadata and controls
1353 lines (1036 loc) · 110 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
Joystick Gremlin EX
================
## Contents
<!-- TOC start (generated with https://github.com/derlin/bitdowntoc) -->
- [Changelog](#changelog)
* [13.40.16ex (pre-release)](#134016ex-pre-release)
+ [(patches)](#patches)
* [13.40.15ex ](#134015ex)
+ [(m5.4) hotfix](#m54-hotfix)
+ [(m5.3) hotfix](#m53-hotfix)
+ [(m5.2) hotfix](#m52-hotfix)
+ [(m5)](#m5)
+ [(m4.10) hotfix](#m410-hotfix)
+ [(m4.8) hotfix](#m48-hotfix)
+ [(m4.6) hotfix](#m46-hotfix)
+ [(m4.5) hotfix](#m45-hotfix)
+ [(m4.2) hotfix](#m42-hotfix)
+ [(m4.1) hotfix](#m41-hotfix)
+ [(m4)](#m4-1)
+ [(m3)](#m3-1)
+ [(m2)](#m2-1)
+ [(m1)](#m1-1)
* [13.40.14ex (m22)](#134014ex-m22)
- [Virus false-positives](#virus-false-positives)
- [Releases](#releases)
- [General](#general)
- [Compatibility](#compatibility)
- [There be dragons ahead! ](#there-be-dragons-ahead)
* [Support](#support)
* [History](#history)
- [Installation](#installation)
- [Automatic Input detection](#automatic-input-detection)
+ [Button detect only overrides](#button-detect-only-overrides)
- [Remote control feature](#remote-control-feature)
+ [Master machine setup](#master-machine-setup)
- [Local mode](#local-mode)
- [Broadcast mode](#broadcast-mode)
- [Concurrent mode](#concurrent-mode)
+ [Client machine setup](#client-machine-setup)
* [Master remote control functions](#master-remote-control-functions)
- [Profile mapping](#profile-mapping)
* [Automatic activation](#automatic-activation)
* [Keep profile active when focus is lost](#keep-profile-active-when-focus-is-lost)
* [Mode selection](#mode-selection)
- [Profile device substitution and input order](#profile-device-substitution-and-input-order)
* [Substitution](#substitution)
* [Caveats with profile automation](#caveats-with-profile-automation)
* [Caveats with loading to the prior mode](#caveats-with-loading-to-the-prior-mode)
- [Copy/Paste operations](#copypaste-operations)
- [Devices](#devices)
* [HID devices](#hid-devices)
* [Device change detection](#device-change-detection)
+ [Avoiding device detection and sleep issues](#avoiding-device-detection-and-sleep-issues)
- [Make sure all devices are awake and visible at profile start](#make-sure-all-devices-are-awake-and-visible-at-profile-start)
- [Sleeping devices after startup](#sleeping-devices-after-startup)
- [Undetected devices may not be available after startup](#undetected-devices-may-not-be-available-after-startup)
- [Runtime device changes create a dragon rich environment](#runtime-device-changes-create-a-dragon-rich-environment)
* [Joystick (axis) device](#joystick-axis-device)
+ [Calibration](#calibration)
- [Global scope](#global-scope)
- [Range and accuracy](#range-and-accuracy)
- [Live feedback](#live-feedback)
- [Centering](#centering)
- [Inversion](#inversion)
- [Calibration limits](#calibration-limits)
- [Calibration center](#calibration-center)
- [Reset](#reset)
- [Deadzones](#deadzones)
+ [Calibration Tips](#calibration-tips)
+ [Curve Editor](#curve-editor)
+ [Curve types](#curve-types)
- [Coordinate system](#coordinate-system)
- [Control Points](#control-points)
- [Live input](#live-input)
- [Curve presets](#curve-presets)
- [Curve copy/paste](#curve-copypaste)
- [Symmetry mode](#symmetry-mode)
- [Inversion](#inversion-1)
- [Deadzones](#deadzones-1)
- [Curve processing order](#curve-processing-order)
* [Keyboard (+Mouse) device](#keyboard-mouse-device)
- [Keyboard inputs](#keyboard-inputs)
- [Scan Codes](#scan-codes)
+ [Numlock state](#numlock-state)
+ [Virtual Keyboard](#virtual-keyboard)
- [Selecting a key](#selecting-a-key)
- [Shift state](#shift-state)
- [Select single](#select-single)
- [Selected keys](#selected-keys)
- [Listen button](#listen-button)
- [Pass-through](#pass-through)
+ [Special considerations](#special-considerations)
* [MIDI device](#midi-device)
+ [MIDI inputs](#midi-inputs)
+ [MIDI trigger modes](#midi-trigger-modes)
+ [Changing modes](#changing-modes)
+ [MIDI conflicts](#midi-conflicts)
+ [MIDI ports](#midi-ports)
+ [Network MIDI](#network-midi)
+ [Using MIDI from touch surfaces](#using-midi-from-touch-surfaces)
+ [MIDI controllers](#midi-controllers)
+ [MIDI troubleshooting](#midi-troubleshooting)
* [OSC device (Open Sound Control)](#osc-device-open-sound-control)
+ [OSC port](#osc-port)
+ [OSC inputs](#osc-inputs)
- [OSC Trigger modes](#osc-trigger-modes)
+ [Changing modes](#changing-modes-1)
* [Gamepad (X-Box controller)](#gamepad-x-box-controller)
+ [Requirements](#requirements)
+ [HIDHide interaction](#hidhide-interaction)
+ [Number of devices and device lifecycle](#number-of-devices-and-device-lifecycle)
+ [Mapping to a gamepad device](#mapping-to-a-gamepad-device)
+ [Gamepad input](#gamepad-input)
- [Profile](#profile)
* [Profile association](#profile-association)
* [Profile modes](#profile-modes)
+ [Mode background](#mode-background)
+ [Default mode](#default-mode)
+ [Nesting modes](#nesting-modes)
+ [Mode addition/removal](#mode-additionremoval)
+ [Mode device](#mode-device)
+ [Mode enter / exit use-cases](#mode-enter-exit-use-cases)
* [General mapping process](#general-mapping-process)
- [User plugins](#user-plugins)
- [Containers](#containers)
- [Actions](#actions)
* [Action priorities](#action-priorities)
* [General Action Types](#general-action-types)
* [Profile edit time vs runtime behavior](#profile-edit-time-vs-runtime-behavior)
+ [Edit time](#edit-time)
+ [Run time](#run-time)
* [Profile map visualization](#profile-map-visualization)
- [VJoyRemap action ](#vjoyremap-action)
* [VJoyRemap button press actions](#vjoyremap-button-press-actions)
* [VJoyRemap axis mapping actions](#vjoyremap-axis-mapping-actions)
- [Gated axis action](#gated-axis-action)
* [Gates](#gates)
* [Gate mappings](#gate-mappings)
+ [Gate Delay](#gate-delay)
* [Ranges](#ranges)
* [Default range](#default-range)
* [Range mapping](#range-mapping)
* [Range output mode](#range-output-mode)
+ [Default range](#default-range-1)
* [Use-cases and scenarios](#use-cases-and-scenarios)
- [Map to mouse EX action](#map-to-mouse-ex-action)
- [Map to keyboard EX action](#map-to-keyboard-ex-action)
* [Output modes](#output-modes)
* [Latching](#latching)
* [Numlock behavior](#numlock-behavior)
+ [Dragons](#dragons)
- [Merged Axis action](#merged-axis-action)
* [Lower and upper inputs](#lower-and-upper-inputs)
* [Operations](#operations)
* [Invert](#invert)
* [Output](#output)
* [Action configuration](#action-configuration)
- [Simconnect (MSFS)](#simconnect-msfs)
- [Range container](#range-container)
+ [Ranges](#ranges-1)
+ [Include/exclude flag](#includeexclude-flag)
+ [Symmetry](#symmetry)
+ [Latching](#latching-1)
+ [Dragons](#dragons-1)
- [Button Container](#button-container)
+ [Usage tips](#usage-tips)
+ [Pressed block](#pressed-block)
+ [Release block](#release-block)
- [TempoEx Container (tempo with chain)](#tempoex-container-tempo-with-chain)
- [Sequence Container](#sequence-container)
- [Plugin Script enhancements](#plugin-script-enhancements)
+ [@gremlin.input_devices.gremlin_start](#gremlininput_devicesgremlin_start)
+ [@gremlin.input_devices.gremlin_stop](#gremlininput_devicesgremlin_stop)
+ [@gremlin.input_devices.gremlin_mode](#gremlininput_devicesgremlin_mode)
+ [@gremlin.input_devices.gremlin_state](#gremlininput_devicesgremlin_state)
- [Recipes](#recipes)
* [One way or two way switch to two way switch / three way switch](#one-way-or-two-way-switch-to-two-way-switch-three-way-switch)
* [Long/short press - buttons or keyboard](#longshort-press-buttons-or-keyboard)
+ [To setup concurrent button presses (hold the short press while long press is active)](#to-setup-concurrent-button-presses-hold-the-short-press-while-long-press-is-active)
+ [To setup a latched short, then long button press with only one button active](#to-setup-a-latched-short-then-long-button-press-with-only-one-button-active)
* [Scripting logic](#scripting-logic)
+ [Attaching a function to a hardware event](#attaching-a-function-to-a-hardware-event)
* [Recommended Resources](#recommended-resources)
- [VJOY virtual joystick driver ](#vjoy-virtual-joystick-driver)
- [OSC support in Joystick Gremlin from TouchOSC](#osc-support-in-joystick-gremlin-from-touchosc)
- [HIDHIDE](#hidhide)
- [Hexler TouchOSC](#hexler-touchosc)
- [Troubleshooting guide ](#troubleshooting-guide)
* [HID devices - detection / random disconnects](#hid-devices-detection-random-disconnects)
* [HID troubleshooting tips ](#hid-troubleshooting-tips)
* [HIDHide troubleshooting](#hidhide-troubleshooting)
* [Checking your mappings](#checking-your-mappings)
* [GremlinEx has been tested with ](#gremlinex-has-been-tested-with)
* [Sample scripts](#sample-scripts)
* [OSC (open stage control) info](#osc-open-stage-control-info)
* [Python dependencies](#python-dependencies)
* [Credits](#credits)
<!-- TOC end -->
<!-- TOC --><a name="changelog"></a>
# Changelog
<!-- TOC --><a name="134016ex-pre-release"></a>
## 1.0ex (pre-release)
### (m73)
- Due to significant core changes, changed versioning scheme to drop original Gremlin version and restart at 1.0 as this is now a different product.
- EXE: name change to GremlinEx to distinguish it from the original gremlin (note, HIDHide update needed to add the EXE)
- New graph based execution logic (WIP)
+ Graph structure represents complete profile
+ Graph nodes include conditions and actions
+ Execution can start at any node
+ Shortcut evaluation with PASS/FAIL nodes during execution
+ Graph nodes support group/any/all hiearchical evaluations
- Improved handling of profile start errors (inability to connect for example)
- Added notes field for all containers (eliminates the need for the description action in most cases)
- New: disconnected devices (devices that are not found) will load and show up as disconnected in the device tabs. This allows copy/paste of components for disconnected devices or for devices that no longer exist, or opening someone else's profile.
- Improved: most recent profile list will be sorted by the most recently loaded profile
- Improved (experimental): Remap dialog to remap devices to another device (this is also known as the GUID remap or changing devices - used for transferring containers to a new device.).
- Improved: Remap function loads to a new, unsaved profile to preserve the original data. This profile must be saved to be persisted.
- Changed version number from base Gremlin to reflect the product is now significantly different to 16ex
- VjoyRemap: startup axis value optional, will read raw hardware on start if not set.
- VjoyRemap: range and scale correctly applied to output
- Fix: UI theme fixes for components and icons.
- Fix: context menu on devices functioning again.
- Fix: complex recursive condition evaluation (via the new graph execution logic)
- Fix: virtual button on legacy remap
T22
- Fix: keyboard widget hover and selection state clicked/hovered stylesheets
- Fix: mode rename not renaming all modes
- Fix: actions added to Mode device not recognizing the special input as a joystick button
- Improved: default icon pixmap created if the icon cannot be found to provide a suitable default on a missing file (whatever the reason).
- Fix: axis repeater visualization issues (custom widget refactor)
- New: calibration result will be visualized on an axis repeater if calibration data is enabled on that axis
- New: option to enable visualization of raw and calibrated data on repeaters
T24
- Fix: some container functors not called causing some containers to fail (like TempoEx, Chain, Sequence, etc)
- API: container functors should return False by default to stop further processing of container contents. Previous logic would call for them to return True. The reason for this is the containers are now part of an execution group so the return value means something different now - do not automatically process subcomponents.
T25
- Improved: QOL macro multi-selection - ability to select one or more entries concurrently - settings only show if a single selection is made - multi-select is for delete/duplicate operations.
- Improved: QOL new macro duplicate button in toolbar (will duplicate current multi-selection as new entries)
- Improved: macro dark theme icons and visuals
- Improved: macro delete applies to multi-selection with confirm prompt
- Improved: macro can now execute on input press, input release, or both when mapped to a momentary type input (will not show on linear inputs)
- Fix: virtual buttons/hats use the new execution graph and execution logic
- Fix: mode switch and temporary mode switch actions selectors now default to the incorrect entry on load (was broken by flipped return values in the API)
- Fix: default container condition set to "always" to default to trigger on press/release by default. This setting is also defined for each container/action default_button_activation() member.
T26
- Improved: Popup dialogs will move to a more centered UI location
- Fix: Vjoy devices used as input will be forcibly released when their input state is toggled or when the profile start so they trigger DirectInput events.
- Fix: some actions not executing in containers that contain multiple actions
- Fix: added missing dark theme icons to the macro toolbar
- Fix: SmartToggle container updated to use current event logic to detect press/release events - this would prevent it from detecting the correct input state.
- Fix: Settings UI if selected on start will not display as blank in some cases.
T27
- Improved: OSC: new dialog to select IP if host has multiple network interfaces
- Improved: execution graph runtime evaluation speed increase
- Fix: SmartToggle now behaves like the original [now that I understand how the original was supposed to work (thanks @Speed)]
- Fix: Execution order respects priority and sequence
- Fix: Individual actions no longer fail whole container if one fails executing
- API: action base class implements default priority for all actions
T28
- Improved: Tempo/TempoEx containers now have a separate delay for the autorelease delay instead of being hardcoded - that autorelease is the time between short press/release
- Improved: SmartToggle has two modes that flips the behavior between short press/long press based on user preferences (defaults to the legacy mode if not set)
- Improved: declutter option for execution graph debug information to make it easier to read on large profiles (new verbose option execDetails)
- Improved: Macro editor right panel width no longer jumps all over the place depending on the options selected
- Fix: Macro editor delete works again
- Fix: JoystickCondition and VJoyCondition axis range comparisons failing when they should succeed due to Python FP precision variance when matching exact FP values
- Fix: Tempo container uses the updated API to detect presses
T29
- Improved: paste of container data is now enabled for action paste: actions defined in a copied container will be extracted and pasted as individual actions.
- Fix: copy/paste of containers/actions functional again after the update to ensure unique IDs
- Fix: Mouse input (via the keyboard tab, selecting the special virtual mouse keys) now triggers containers/actions.
- Fix: Stepped axis mode on vjoy remap index not persisted on correct object between calls resulting in incorrect output values.
- Fix: Latched functors (extra inputs for merge axis, stepped axis and others) could include duplicate calls resulting in incorrect behavior.
- Improved: input viewer will update VJOY based on internal values sent to VJOY even if the device is not setup as an input device to keep things synchronized.
T30
- Improved: low level mouse wheel handling refactored: wheel release no longer triggers while wheel motion detected before a timeout. New option added to set the timeout in options. The timeout value determines the wait time in milliseconds for a wheel release event after the last detected wheel motion for that direction. Default is 500ms (half a second).
- New feature: Stepped axis mode of vjoy remap can disable the "down" component latching. If disabled, the "down" action will not be latched.
- New feature: Stepped axis mode of vjoy remap can change the step direction via the new direction option. When checked, the step direction will be reversed, so up is down, and down is up.
- Fix: event callback cache now always resets before a new profile start to clear prior cached data. This will reset any prior cached execution data if the profile is changed, and run again.
T31
- New: Add copy/paste functionality to all conditions (may have a few dragons)
- New: Add listen widget to VJoy conditions
- New: Add listen widget to keyboard conditions
- Improved: Further pass on UI for look and feel and consistency including use of icons
- Fix: ensure action icons on the input selectors are updated on action CRUD (create/read/update/delete) operations in the various permutations allowed by the UI (may still need more work).
T32
- Fix: Button repeater disappeared in T30
- Fix: Resolved an issue where some actions would not execute because of shortcut logic. This should resolve several reported condition issues.
T33
- Fix: Refactored gated axis execution graph build and evaluation logic to resolve a few more complex condition evaluations.
- Fix: Added virtual button condition (legacy virtual button) to execution graph for both axis and hat input. This resolves a number of issues when virtual buttons are used and deprecates the legacy callback mechanisms.
- API: execution graph: when the trigger entry point in the execution graph is a container trigger (which is a default state), the logic will check to see if the container is parented to a condition node and switch to that node as the entry point if needed.
- Fix: when the legacy remap action is attached to an axis or a hat and outputs a button, the virtual button tab will appear in the UI without having to reload. Note: This doesn't apply to other actions like vjoy remap because that has a built-in ability to handle that. This resolves issues with older profiles relying on this functionality working in m73.
- Fix: virtual button UI in dark mode not showing information.
T34
- New: Upgrade to Python 3.13.3 April 2025 release
- New: Upgrade to Pyside6 6.9
- Fix: MSFS interface will unload the SimConnect DLL on profile stop. This ensures any DLL settings are not persisted across sessions.
- API: increased time to get buffer data from MSFS to 100 ms per attempt as some requests would fail.
T35
- API: new SelfTriggerFunctor base class to handle containers that do their own execution switching. These container functors can have multiple action groups that execute based on container options and input values.
- API: Container node callback checks for condition parent by default.
- Fix: refactored to use new API to Chain, Sequence, Range, SmartToggle, Switch, Tempo, Button, TempoEx and Tick containers. This fix is intended to resolve multiple potential execution issues with the new execution graph model for complex containers and their associated conditions.
T36
- OSC: fix send and receive (was using old API)
- Fix: some IDs were not saving properly
- Fix: some actions not executing at all in some situations.
- API: added check for well formed IP address
T37
- OSC: re-added external event for custom plugins to trigger on VJOY output changes
- Improved: new checkboxes on Map to OSC to enable/disable value send on press/release
## 13.40.16ex (pre-release)
### (m72)
- Improvements: new "outputs" verbose mode to track outputs (warning, very verbose, will slow things down considerably)
- New: XY pads (or multidimensional data) for OSC inputs allow to specify which argument is used. The UI was also modified to allow duplicate OSC inputs provided that they use different source parameters. When the action is listened to, the UI will automatically determine how many parameters were sent. That also means that manual entries will default to 1 parameter for now (I'll see if I can improve that).
- API: Events now have an override input type (optional).
- Fix: syslog consolidated to eliminate 476 calls.
- Fix: macro keyboard output using correct API call for remote control.
- Fix: mode switch action entries reverting to default settings in certain conditions.
- Improvement: performance optimization related to logging.
- Fix: non vjoy virtual devices (such as OSC) formally added to known device lists so API calls are aware of these devices instead of reporting them as unknown.
- Fix: double release on joystick button press if an auto-release was already registered
### (m71)
- New: Tick container. The tick container is a container that triggers actions at regular ticks on an axis. The actions can be different based on the tick crossing direction.
- New: Stepped Axis mode in Vjoy Remap. When attached to a button, this mode allows the action to set a VJOY axis value based on configurable ticks. The mapped button is the tick "up" (increase). The latched button defined in the action is the tick "down" (decrease) button. The ticks are configurable to any position on the axis. Use this mode to easily set axis values based on an up/down scheme.
- Improved: Settings tab has new preset buttons to setup default startup VJOY axis values at profile start.
- Fixed: Gated axis will now send a button event on range enter/exit triggers instead of axis triggers. This was confusing actions added to these triggers because they were never seeing a button input, so ignore the trigger completely.
- Improved: Gated axis ranges now also have a delay entry for the triggers that are momentary (exit/enter). The delay, as with normal gates, is the time between a press and a release.
- Fixed: Simconnect connection start/stop behavior not reconnecting, causing errors if MSFS is not ready/running, or getting in some cases in a race condition with the WASM bridge module. Tested with MSFS 24 beta patch.
- Fixed: Simconnect WASM (c++) - alive ping no longer sends the LVARs.
- Fixed: various UI fixes and exceptions.
### (m70)
- Improved: Options button added to main toolbar.
- Improved: Options dialog has dedicated tabs for various options
- Improved: Options performance improvements on close.
- Improved: Simconnect: configuration button available in all action modes
- Improved: Macro: additional diagnostics data output in macro verbose mode
- Improved: Switch mode and Temporary Switch mode not longer show current mode as a choice.
- Fix: mode name change may not be updated in the profile
- Fix: Macro: do not reschedule an existing macro if already scheduled
- Fix: Simconnect: RPN calculator text will now paste MIME types as plain text
- Fix: Simconnect: RPN UI elements are only displayed in the RPN/calculator mode
- Fix: Simconnect: stop intercepting mode changes in monitor thread.
- Fix: OSC: Changing OSC port and IP options will reconfigure internal OSC client/server live so listen behavior uses the current configured port.
### (m69a)
- Fix: device sorting (sort menu)
- Fix: input type exception when attempting to derive at type from an input that no longer exists, such as, the device is removed/disconnects.
- Fix: references to deprecated highlighting tracking system
### (m69)
- Improved: Keyboard macro bring up the unified keyboard list for enhanced keys.
- Improved: Keyboard macro has quick add shortcut buttons for add a press, or add a release.
- Improved: Input Viewer will synchronize with current input state on start.
- Fix: more reliable profile auto-start behaviors across different options (profiles associated with processes)
- Fix: TTS rate now uses word per minute rather and the older offset method.
- Fix: XML sometimes saving integers as floating point and unable to read the data back.
- Fix: Unified highlighting - suspends on all input listening
### (m68)
- Fix: TTS enabled at design time to allow for playback at design time (this was broken when TTS was moved to a queueing system to help with spamming messages that could hang the system)
- Improved: TTS message on mode change will now trigger (if enabled) on profile start (to remind you what mode the profile is starting in), will also not trigger if the mode changes within 2 seconds to avoid TTS spamming. The windows TTS API is not very kind to rapid fire TTS. TTS messages generated by GremlinEx are currently hard coded to play at 150 words per minute to also make the message less intrusive. You can always turn the feature off if you do not want automated TTS messages on mode change and provide your own through actions.
- Improved: Simconnect WASM module has a ping/pong mechanism to validate the GremlinEx bridge is connected and communicating before sending commands. This also verifies the proper installation/configuration of the WASM module in MSFS to avoid errors in Gremlin Ex.
- Fix: Simconnect quit (profile stop) may not restart the connection at next profile start.
- Improved: Input viewer added to master toolbar for convenience.
- Improved: Highlight on/off added to bottom right status bar for convenience.
- Improved: Options window revamped with scrolling to ease navigation with various scaling and resolutions.
### (m67)
Pre-release stabilization:
- Fix: Resolve an exception when selecting a tab without any prior input selected.
- Fix: Gated Axis UI rework to address some gate add/remove and movement issues.
- New: Barebones undo for gated axis. Ctrl-Z hotkey will undo last gated action such as adding a gate or moving a gate. This is very rudimentary at this point and doesn't handle adding or removing actions to gates/ranges at this time.
- Improved: swap device UI has now has an ok/cancel button pair to exit out of the dialog.
- Fix: 1:1 mapping forces an update of action icons
- Fix: Using VJOY as input in settings does not update device list
### (m66)
Pre-release stabilization:
- New: "use calibrated input" on axis conditions. When checked, the condition will use the calibrated data on the input, when unchecked, will use the raw (uncalibrated) data. If the input is not calibrated, this setting doesn't matter.
- Fix: Non-centered calibration scales properly based on deadzone extremities.
- Fix: conditions deemed "invalid" weren't persisted. Conditions are now saved regardless of validity. Note: this also means that it's possible to save mutually exclusive conditions. The verbose mode "condition" will output to the log file the execution tree and the result of any conditions tested, in the order of testing.
- Fix: condition default mode was not always defaulted causing the condition to fail all the time.
- Fix: some condition types could not be applied to some actions
- Fix: issue pasting vjoy remap action if changing input type from axis to buttons
- Fix: Simconnect action not populating description and range data when selecting a command in non calculator mode.
- Fix: Center zero preset was ignored in calibration window.
- Fix: latched functors not responding to event triggers due to the change in event processing in m58 (this was in particular impacting the axis merge functionality in vjoy remap)
- Improved: Integer and Floating point input boxes now have a custom input validator that is a bit more forgiving for inputs than the default validator. The default validator would prevent valid data entry due to a stricter set of rules.
- Fix: UI disables consistently regardless of how a profile is started.
### (m65)
- New: Macro verbose option to handle verbose diagnostics mode for macros specifically
- Fix: Keyboard Mapper Ex wasn't sending "press" events in certain option combinations with the new "direct" mode
### (m64)
- New: Run Process action: allows GremlinEx to execute an arbitrary process based on an input press or release. Note: The ability for GremlinEx to spawn processes depends on the permissions given to GremlinEx.
- Fix: Virtual button enabled user setting (Virtual Button Tab) now loads the correct saved option.
- New: Open GremlinEx folder option in file menu
- Fix: Additional logic to track modes associated with specific processes and profiles so that when a process is given focus, the profile and the mode last associated with the process is restored. This is still a work in progress.
### (m63)
- Improved: Input Viewer remembers last selection
- Fix: Input viewer has correct axis number for non-sequential inputs
### (m62)
- Improved: hat button repeater enabled - now shows the direction of the hat "live".
- Fix: OSC output port value will update the correct port.
- Fix: Joystick conditions will now correctly skip axes (the dropdown previously assumed axes were sequential - depends on the hardware).
### (m61)
m61 is a **general stabilization** patch focused on cleaning up remaining issues linked to new features introduced and module refactors in this version.
- Fix: input listener not detecting some axis changes
- Improved: Joystick condition UI now has manual device input selectors so select the hardware latching condition latching.
- Improved: range selectors in conditions include a repeater that shows current input values and in line with the gated axis, includes record buttons to set the values from the live input.
- Fix: multiple references to older properties of the removed tab widget impacting UI functions such as 1:1, device substitution causing exeptions
- Fix: calibration icon not showing correct state
- Fix: some containers are missing their action condition entries for each action in the container
- Fix: condition counts in the condition tab does not always update as conditions are added or removed
- Fix: map to vjoy merged value repeater not updating correctly
- Fix: virtual button on axis input not triggering action (note: if a virtual button condition is used, any other joystick condition is ignored)
- Fix: UI not disabling at runtime with the option selected to prevent inadvertent interactions/changes.
- New: Virtual button condition is now user controllable via a checkbox on the virtual button tab. This was added because virtual buttons override any other conditions, which is not always the desired behavior for some use-cases. The enabled state is also visible on the virtual button tab.
### (m59/m60)
- Fix: Special mode device not always creating entries for a new mode causing a key exception.
- Improved: hourglass now more consistently displayed for operations that can take a while to refresh.
- Fix: triggering an OSC or MIDI input was not selecting the input when pressed and highlight is enabled.
- Fix: Occasional QT C++ reference exception on button or axis repeaters.
### (m58)
- Fix: Simconnect dll detection in packaged version could lead to a DLL not found error which caused a connection failure. Updated to the latest SDK version of SimConnect as well for MSFS 2024.
- Fix: Autorelease of callback registrations not handling the new event callback key system (prior fix was for button release actions). This impacted the temporary mode switch and any functor using the callback autorelease functionality.
- Fix: GremlinEx triggers not functional due to event serialization changes to support the auto-release functionality on more complex inputs introduced in m57. The serialization changes would cause the logic to miss the events because they are coded differently to allow serialization, so there are now two keys, one for serialization, and one for triggers.
- Fix: More UI work to keep device and modes in sync with the display with the new UI logic and replacement of the problematic UI component introduced in m50. This caused issues with blank screens on mode changes and general display of information not always in sync with UI navigation. This continues to be a bit of whack-a-mole as the navigation logic is quite complex as some inputs are fixed, some are user-defined, and others are application driven. To this end, much of the legacy device logic was redone to be consistent for all input types so all devices respond similarly to UI actions and thus can refresh/update more appropriately. There is probably more work here to be done and this gets us closer to the resolution of this issue. I knew yanking a core component out of the UI would be complicated and painful - not disappointed - however the choices were continued random race condition and crashes or a gut/replace of the UI management system.
- New: Map to VJOY has a new option to do automatic button releases on Keyboard, OSC and MIDI inputs. This was not possible before due to the serialization issues on complex inputs. This means keyboard inputs, when mapped to a VJOY button, will release when that button is released (it will remain "on" if not selected which is the prior behavior).
### (m56/m57)
- Fix: GremlinEx will no longer attempt to connect to SimConnect if no SimConnect action is detected (side effect of some features added to m53/m54).
- New: Experimental - Simconnect Action includes an auto-repeat feature to send RPN expressions to MSFS while the input is pressed (similar to Keyboard auto-repeat). This is added because some expressions in RPN don't have the notion of "do while...".
- New: Experimental - Simconnect Action issue an optional RPN expression on release which is different from the RPN expression on press. This is helpful for toggle type situations, or to for "while pressed" situations without having to code another separate action on release.
### (m55)
- Fix: Highlighting for OSC/MIDI inputs if highlighting is enabled while in edit mode.
### (m54)
- Fix: disabling MIDI or OSC device in options was not necessarily updating the device tabs correctly.
- Fix: UI not updating correctly on some refresh functions (new profile, options window).
- Fix: OSC entries showing up under MIDI in the profile data if MIDI is disabled.
- Fix: resolved one issue with curve function getting confused with no center deadzone values if the curve doesn't have a center deadzone. Deadzone will now provide suitable defaults.
- Fix: device state not always initialized in some edge cases. State data will now initialize to default state for the device and input if queried.
- New: Experimental. The UI is not finished and this is still very much in active development, but functional enough to make it available because of the significant functionality gain. GremlinEx now has a new custom WASM module written in C++ for MSFS to help it interface with the simulator. This lets GremlinEx access LVARS and run expressions againts the simulator to change state based on GremlinEx triggers. WASM is needed as the Simconnect SDK does not easily expose some functionality in MSFS that can only be read or set via an internal WASM module. Barebones to test, functional with MSFS 2024 and will save the information. The WASM module is in the "msfs wasm module" folder. The gremlinex-module folder should be copied as-is to the MSFS Community folder. Currently GremlinEx does not check for this module to be installed (yet) so using these features will do nothing if the WASM module is not there. New features introduced:
-- GremlinEx can pull a list of internal variables used by the simulator defined by add-ons
-- GremlinEx can send RPN expressions to the simulator on a trigger actions - this lets GremlinEx control complex add-on aicraft that have their own state variables defined. For a curated list of commands, see https://hubhop.mobiflight.com/
-- Functionality requires the GremlinEx WASM module to be copied to the Community folder (zip is in the distribution). Copy the contents of gremlinex-module to the Community folder and restart the simulator.
### (m53)
- Fix: For profiles using Simconnect, a failure to connect on profile start (such as, simulator is not running or not "ready") is now handled more gracefully. The profile will automatically stop when this happens and display a message box on connection failures. A profile using Simconnect should only start when the simulator is fully loaded and available, which can take significant time. The rule of thumb is Simconnect is available when the Simulator's user interface becomes available.
- Fix: Toolbar icon updates when GremlinEx is activated via the system tray menu.
- Fix: Settings and Plugins tabs no longer cause an assertion when selected (introduced in m50)
### (m52)
- Fix: tab reorder and selecting tabs not always updating the display to show the correct device.
- Fix: hat input in some situations not detected
### (m51)
- Fix: Centering presets visible on non-centered curves causing an exception.
- Improved: All curves can now force a centering mode for deadzone purposes (new "centered" option) regardless of curve type. This option may not make any sense on certain curve shapes but is there nonetheless if you need to force a centered deadzone on the input depending on your use-case.
- Fix: TempoEx container conditions does not show its actions because it uses non-standard action groupings.
- New: Vjoy Remap has a new relative option for the Set Axis mode that applies the value relatively to the current axis.
- Fix: duplicate device list and a very confused UI when devices are connected/disconnected while GremlinEx is running. This was not handled correctly in m50.
### (m50)
- Improved: This patch includes a significant rework of the UI (user interface) "wiring" logic to improve performance and resolve issues with highlighting options and in particular it eliminates a problematic QT behavior that was causing numerous headaches and bugs (QT is the library under the hood that renders the UI). The UI is significantly more responsive across the board.
- Improved: The inputs panel (left) are more compact and use less vertical space, so less scrolling.
- Improved: The interface to Microsoft Flight Simulator has been reworked and tested with MSFS 2024. The Simconnect feature to automatically switch profile modes based on the current player aircraft now has a mode locking option to freeze the mode to a specific aircraft. This is necessary because GremlinEx has potentially conflicting options to change modes that work well with other application but cause a loss of control if profile modes are associated with aircraft. The lock feature only impacts profiles using Simconnect and when automatic profile switching is enabled. The idea of automatic profile mode switching is each aircraft can have its own mode, with unique and inherited mappings, control curves and gated components.
The documentation has been updated to explain the MSFS connectivity and how profile modes can be used to create mappings to multiple aircraft. GremlinEx has been tested with MSFS 2024 with built-in aicraft and third party commercial add-ons (such as the FenixSim Airbus series). While the GremlinEx Simconnect interface is completely bi-directional, however the Map to Simconnect action is send only for obvious reasons. Note to plugin users: the API and calls have changed in this version due to changes in threading to maintain a high response rate with the sim, so the code may need to be tweaked.
The Simconnect features are still in development.
- New: GremlinEx will now make automatic backups of profiles when saving a profile. The number of backups kept is determined by a new option in the profiles options dialog. If the count is zero, backups will be disabled. GremlinEx will store numerically named backups named based on the profile name. If the total count of per profile backups is exceeded, the oldest one is removed. The backups are saved to a folder named after the version of GremlinEx so it is easier to undo changes made by a new version if this becomes necessary. The log file will contain the backup file name whenever a profile is saved. Profiles are saved in the profile folder (%userprofile%\Joystick Gremlin Ex).
### (m49)
- New: OSC and MIDI live input status. At edit time, GremlinEx will listen for OSC or MIDI events to real-time update the inputs as their hardware input counterparts can. OSC and MIDI inputs can behave either as linear (axis) or momentary (button) inputs. For OSC, a value of 1.0 indicates the button is pressed, and 0.0 indicates the button is released (other values are ignored). For MIDI, a value of 0-63 indicates the button is released, and 64 to 127 indicates the button is pressed.
- API: OSC clients are now pooled per server/port.
- API: MIDI and OSC input models refactored to use the updated event model (this fixes a number of recent issues with OSC and MIDI inputs)
- Improved: It is now possible to use the Keyboard Ex mapper in auto-repeat mode with containers that do not auto-release with a caveat that you need a way to turn that off. To cancel auto-repeat, you can setup a Keyboard Ex action with no keys set to release mode. When triggered, that action will stop the auto-repeat function globally and release any pressed keys. This enables using auto-repeat in containers that do not auto-release automatically (by design). One such use-case for this is to autorepeat keystrokes while the input is in a gated axis range (trigger autorepeat on range enter), and another key entry set to stop the autorepeat can be triggered when the range exits. A typical scenario would be using an axis input for a rotary input, and is particularly useful with OSC rotary inputs on glass input surfaces that send an axis value corresponding to the position of the knob.
- API: The macro manager now has a clear queue function that can clear scheduled actions that haven't executed yet, in effect stopping macro executions.
- Fix: MIDI not triggering actions due to API rework in a prior m release.
### (m48)
- New: OSC send action. This allows GremlinEx to send OSC commands outbound. For now it's a single IP address and port specified in the options menu. OSC commands start with a forward slash (improperly formatted commands will not send), and it has two optional parameters per the OSC protocol which can be integer or floating point.
- Improved: profile runtime determination startup logic consolidated and simplified. The change primarily impacts profiles attached to processes for automatic load/execution if those options are enabled for automatic profile execution/swaps.
- Improved: UI will now display mode hierarchies as folders in the actions that change profiles to make it easier to visualize mode nesting. This is a visual change only and does not change the mode names in any way.
- API: UDP ports keep alive now event based (this is for the OSC and remote control capability).
- API: Execution tree is built before a profile is started. This is available through the new ExecutionContext.
- Fix: scale value not loading correctly from profile on restart for VjoyRemap and legacy remap not allowing scales > 1.0.
- Fix: UI exception when not using joystick input repeaters
### (m47)
- API: in general, the code makes more use of internal events to start/stop and record changes and simplify the logic, which results in performance gains.
- API: in general, more detailed diagnostics logging if the appropriate log option is enabled. Warning: log entries can have a performance hit on GremlinEx when executing profiles.
- Improved: Keyboard, OSC and MIDI input now support mappings via mode hierarchy and match the behavior of regular axis, button and hat inputs: If a mapping is not found for a keyboard/OSC/MIDI defined in the current mode, and a mapping exists for that input in a parent mode, the parent mode mapping will trigger. This behavior was missing in prior releases pending improvements to the execution tree, which exists as of m42 which now make this possible.
- Improved: The execution graph will abort on profile stop at the next step which should interrupt large container executions and return to edit mode much faster.
- Improved: The macro scheduler will now abort on profile stop at the next step if a stop request occurs while the macro executes. Before this, a macro usually had to completely execute before stopping.
- New (experimental): Sequence container - similar to macros but as a container. This container executes all actions sequentially once triggered.
- Improved: Pause action now functions as a delay as well as a callback pause (mode selectable). The delay is selectable and entered in milliseconds.
- Improved: Filter box added to the process picker dialog.
- Improved: MIDI and OSC listening interfaces won't automatically start if there are no MIDI or OSC inputs defined in the profile.
- Improved: Simconnect
- scan speed for aircraft folder data - the community folder scan will now only look for folders that contain player flyable aircraft and do its best to ignore the rest (the MSFS folder structure is convoluted so there is only so much that can be done here...)
- config will pull the current aircraft (if one is loaded in the sim)
- Simconnect action has a trigger on release option if mapped to a momentary input (button or hat)
- Simconnect aicraft profile mode is now saved with mode data (if defined). This mode is auto-selected when an aicraft is detected if the option is selected.
- Many missing simvars added
- Simconnect action data can now be entered as normalized (-1 to +1) or MSFS range and displays percentages
- simconnect_lvars.xml can be user edited to define L: variables that will be loaded by GremlinEx. LVars are custom defined by aircraft and thus user customizable. There is currently no interface to edit LVARs - that has to be manually done currently. A sample file is created if it doesn't exist.
- New: clickable highlight button repeaters on the status bar (bottom right). Click to change auto-highlight status without going to options.
Fixes:
- Fix: Restore last mode on profile to process mapping wasn't saving correctly.
- Fix: Restore last mode on profile activation does not restore the last profile that was selected (this is related to the prior fix). There may be more work needed on this as process to profile mapping and auto-loading is rather convoluted with all the options available.
- Fix: auto activate profile error or noop when option is enabled and a suitable process is selected and the action is on.
- Fix: closing GremlinEx when a profile is active no longer leaves the process running (bug introduced with recent process monitoring logic changes)
- Fix: unknown "hardware_device_guid" member found in profile class introduced in m44
- Fix: Some paste of actions causing an exception post refactor to require a secondary parameter introduced in m45.
- Fix: Input selection on profile load may have selected the incorrect item.
- Fix: Relative scaling in vjoy remap now supports value 0 to 1000 (previously was limited at 1)
### (m46)
- Improved logic and event handling around automatic process activation based on the active (foreground) process.
### (m45)
- New (experimental): Mode tab. The mode tab provides two new virtual buttons that trigger assigned actions whenever a mode is entered (activated) or exited (deactivated). See the mode tab in the documentation [here](#profile-modes)
- Fix: changing modes will restore the last selected device at edit time
- Fix: since m31, vjoyremap (Map to Vjoy) ignores conditions set on companion curves
- Improved: GremlinEx now remembers up to 15 profiles
### (m44)
- Improved: The legacy calibration method has been deprecated. Legacy data will be loaded if it exists the first time GremlinEx runs from an older version. The calibration tool is removed, and calibration options are moved to individual input via a configuration button for each that brings up a dialog specific to that input. The new features include new visualization of live data, inversion, and deadzone settings applied at the input level without needing a curve. The calibration applies to the input before further processing by GremlinEx, including before any curve is applied. By default all axes are setup as "centered" and no calibration is applied so no changes are needed unless calibration should be applied. Calibration data is now saved to a separate XML datafile in the user profile folder where profiles are kept and includes the new flags/options in it.
- Experimental: ability to disable certain inputs and manage input enabled state at profile runtime via the new control action. The control action can only be mapped to a momentary input and can control the enabled state on any known input. The idea of this feature is to (1) enable/disable inputs without having to connect/disconnect them which can cause problems or conflicts or re-ordering (2) for advanced setups where multiple inputs may be mapped to the same output and this is not desirable due to conflict in certain scenarios.
- Improved: individual input enable button now available on any input to enable or disable it from the profile. By default, all inputs are enabled when a profile starts. The buttons can be enabled via an option.
- Improved: Most dialogs will remember position and size.
- Fix: Invalid input type in legacy remap
- Fix: curve in vjoyremap not applied to final output starting with m43
- New: documentation on calibration
### (m43)
- Improved: curve dialog window on input has scrollbars for lower resolution displays.
- Fix: Simconnect functor exception with new API tree feature
### (m42)
- API: Refactored the execution graph to also create a new execution tree data structure. This makes it much easier to navigate the execution graph at runtime from any point of the execution, output diagnostics and derive latched actions.
- Improved: The API improvement simplifies curve computations and resolves merged axis curve application in map to vjoy.
- Fix: last runtime profile restore on profile start non longer throws an exception if option is enabled
- Fix: automatic profile load based on mapped process if option is enabled
### (m41)
- Improved: Keyboard mapper Ex enhanced display of selected keys.
- Improved: Simconnect (MSFS) supports two-way communication via OSC (see osc_msfs.py as the demo of the parking brakes). The demo OSC/Pilot and user plugin module to support two way comms is in the demo msfs zip file. Note: this is not OSC/Pilot specific - just provided as a demo here. The concept is similar with other OSC surface control software although it may have to be tweaked based on that software's capabilities.
- Improved: Added autorelease option for OSC commands that do not issue a release (example, StreamDeck OSC plugin). This enables a release to be issued on an OSC message receipt to trigger the missing release after a user selectable delay (default 250ms)
- Fix: Containers not always telling actions what container type they are when the container type overrides the input type.
- Fix: Gated Axis triggers on a single condition gate crossings ignoring the others
- Fix: C++ reference error on gated axis after stopping a profile and moving the associated input device
<!-- TOC --><a name="m40"></a>
### (m40)
- Fix: small update for mouse ex not releasing mouse button (thanks for reporting!)
### (m39)
- Improved: OSC output can send to any IP address (set IP and port in options). The prior implementation was sending to the local server only.
### (m38)
- Fix: removed redundant "force numlock off" check box in profile to process mapping as that option is superfluous. Each profile can set its own option in the profile config window, or it can be set globally in options. Those two methods are sufficient to achieve the desired behavior.
- Fix: Curves applied to input axes not always loaded post converting to the new curve editor.
- New: Conditions have their own verbose mode for log output for troubleshooting conditions in the log. When this is enabled, the execution plan and the outcome of tested conditions will be output to the log to help diagnose issues around conditions. Conditions and execution plans are very complicated (warning, when enabled, as with most verbose modes, this can generate a lot of log data and consequently slows GremlinEx down significantly).
- Fix: Docktab for mappings generating an internal Python exception because the C++ reference was garbage collected before the Python reference.
### (m37)
- Fix: exception on mode change with certain curve setups
### (m36)
- Improved: Added OSC send capability
- Improved: Added VJOY output events
- New: GremlinEx to OSC vjoy output script user plugin demo
### (m35)
- Improved: Condition processing for containers and actions are now cumulative, meaning that each container has a set of conditions for the whole container, and another concurrent set for each action in the container to toggle each one individually. If a condition on a container fails, the whole container is disabled, regardless of the individual conditions on actions.
- Improved: Condition logic
- New: Global numlock off startup state option. This option, when set, overrides the per profile numlock setting. In most cases, this option should be on to avoid problems with keyboard output using numlock.
- Fix: Keyboard input: Arrows keys no longer get translated to Numpad arrow keys
- API: reworked the container and actions conditions API.
### (m34)
- Unreleased test version
### (m33)
- New: Map to vjoy, hat to button mode has a new sticky option. When enabled and the position mapping is in the hold mode, any pressed hat positions will "stick" until the hat is returned to center, and when disabled, only the current hat position is pressed. This mode is only relevant when in hold mode, it has no meaning in the pulse mode for obvious reasons.
- Fix: Tempo/TempoEx/Chain/Switch/Button did not support hats as input
- Fix: When in symmetry mode, curve editor did not mirror the center point bezier handle
- Fix: Map to Vjoy in axis to button mode, change in triggering logic.
### (m32)
- Improved: cross-reference data returned by Vjoy API with data returned by DirectInput and more detailed log data for what was detected. This can help with troubleshooting.
- Fix: typo in tempo/tempoEx in variable name
- Fix: possible tray icon exception when the application exits and the tray icon has already been discarded.
### (m31)
- Improved: support for Simconnect for MSFS2024. This is a work in progress and does not include all planned features, such as, a facility to add custom simvars from add-on products. The barebones module is functional with MSFS 2024 released Tuesday, November 10th, 2024.
- Improved: Map to vjoy adds a new hat to button mode to map up to 8 hat positions directly to buttons. The buttons can be pulsed or held.
- Fix: Tempo and TempoEx now handle hat inputs (as usual using tempo with a hat is best done with a pulse option because of how Tempo works)
- Fix: Remap to Vjoy does not reload saved set target value
- Fix: conditions do not work with hat input or hat conditions
- Known issue: condition marker does not always update in all use cases (this does not impact functionality)
- Known issue: conditions if also mapped for their own actions may cause some conflicts because they fire at the same time.
### (m30)
- Fix for condition tab error when adding a condition that applies to the container - related to the addition of the status flag in m27
### (m29)
- Fix for m28 vjoy mapper ignoring curve data on load due to a tag change in m28
- Fix for missing panel in vjoy mapper for some other button modes (m28 fixed the axis to button but missed a few others that had the same issue when mapping to a button input)
### (m28)
- Improved: GremlinEx can automatically convert legacy Remap and Response Curve to their GremlinEx version provided that options are enabled from the Profile page in the options. Converting is recommended and will occur when a profile is loaded. When the convert option is selected, the legacy mappers will no longer be visible from the action drop down either to encourage the use of the new actions.
- Improved: Added option to toggle the display of button grids in the GremlinEx options panel. This is the same as holding the control key down when toggling the "show button grid" in the Map to Vjoy mapper.
- Fix: Missing button options panel when in Axis to Button mapping mode of Map to Vjoy
- Fix: Response curve Ex saving to profile as a legacy response curve action.
- Fix: Response curve text inputs not always updating the UI correctly
- Fix: Floating point and integer text input wheel events are no longer propagated (that could cause random unexpected scrolling of a parent containers)
### (m27)
- Fix: Input or output axis curves: setting deadzone via buttons not saving values.
- Improved: [experimental] Condition tab will show a marker when one or more conditions are defined (I've set it up to pickup any condition however I am not a heavy user of conditions so it's completely possible this will trip up somewhere)
- Fix: VJOY used button state now takes into account axis to button mappings.
- Fix: VJoy Remap typo in diagnostics code to handle invalid VJOY IDs
### (m26)
- Improved: Complete input mappings for an input (all containers) can now be copied and pasted all at once from the clipboard as a set. This makes is easier to copy/paste multiple container mappings between inputs. Note: when pasting multiple containers, only valid containers in the clipboard will be pasted so if you are missing a container, it's because it wasn't valid for the input. This comes into play when copying containers for an axis and pasting it to a button input, and vice versa. (new container toolbar button).
- Improved: It is now possible to clear all mappings from an input. A confirmation box will be presented (new container toolbar button).
- API: added axis flag to containers if the container is only for axis inputs as the type of the input can change so containers need to know if the current input is configured as an axis - previously was relying on input type alone
- Fix: Input axis flag was not always set correctly in input items in the API
- Fix: OSC range min value for axis not updating correct property
- Fix: Paste action didn't recognize XML ObjectEncoder data
- Improved: Vjoy Remap will validate the VJOY device ID and gracefully provide an error message with the offending ID rather than causing an exception if it cannot be found in the active VJOY device list. The action will also check at profile load if an ID is not valid, for example an older profile referencing an ID that no longer exists. IDs are assigned by the VJOY Configurator.
### (m25)
- Fix: Curve controller now checks for duplicated points when fitting a curve
### (m24)
- Improved: The range container now supports directional triggers based on a relative input axis position change. The container can now trigger its actions based on an input increase or decrease, or both, provided that the input change (delta) exceeds the percentage or range set (default 10% deviation). The use case for this is to trigger a button or key based on a slider input going up or down. Note: if mapping a button or key, use the pulse feature as the container is only an "on" container - in trigger on change mode, it does not issue a release so the action must self release if that is the desired behavior.
- Improved: Import profile function UI improvements
- Improved: Import profile "no map" option for mappings
- Improved: Import profile automated mapping behavior (unused, stop, round-robin) added
- Improved: file search will skip folders marked hidden (starting with a ".")
- Improved: file search will cache previously found items to improves UI responsiveness associated with locating icons in particular
- Improved: Map to Mouse Ex can now send double-clicks
- Fix: Input load skips loading vjoy inputs that do not exist anymore whatever the reason and will output a warning log entry if it cannot find something
### (m23)
- Improved: 1:1 mapping now has a configuration dialog box to select target and mapping mode.
- Fix: 1:1 usable mode accounts for vjoy mappings by both vjoy mappers
- Fix: Input selection can throw a missing argument exception in m22 patch
### (m22)
- Improved: axis repeater bar no longer causes a small window to flash temporarily on the UI
- Improved: vjoy remap show/hide button grid checkbox can now change the state for all vjoy remap actions in the profile if the state is changed while a control key is held
- Improved: 1:1 mapping uses Vjoy Remap as the default mapper instead of the legacy remap (1:1 mapper may need some more work)
- Improved: vjoy remap button grid color icon click shows where that button mapping is used across entire profile including those of legacy remap action
- Fix: 1:1 mapper displays an hourglass while processing
- Fix: right mapping panel was not always updating on input selection or state changes
- Fix: left input panel icons were not always updating on global profile actions
- Fix: switch container caused an exception when adding a new switch position
### (m21)
- Fix: Legacy remap displays blank (or incorrect) value on reload for certain input choices
- Fix: TempoEx container condition UI invalid index exception when setting conditions based on actions
- Improved: Refactored button usage tracking
### (m20)
- Fix: display details in MIDI inputs would hide details on other entries
- Fix: MIDI configuration update was not not updating input description consistently
- Fix: input display fails to update for keyboard entries in m19
### (m19)
- Improved: legacy remap and map to vjoy actions now synchronize the used data.
- Improved: action list for button mappings now updates when queried to ensure the usage data is up to date across the entire profile.
### (m18)
- Improved: Axis names. GremlinEx will attempt to derive the axis usage name (X, Y, Z, RX, RY, RZ, SL1, SL2) for inputs and VJOY output as reported and mapped by DirectInput. While many device report as expected, some (non VJOY) devices do not report a usage for an axis. When this happens, the name of the axis will be its axis sequence number (1 to 8). If a usage is defined and can be derived, the specified usage name will be used and displayed in GremlinEx. Names are informational only and GremlinEx will always use the hardware device and input IDs for mapping.
- Improved: GremlinEx considers axis names when a VJOY definition has skipped axes
- API: VJOYSelector is now based on data instead of naming conventions which fixes the legacy mapper (remap to vjoy does not use this).
### (m17)
- Fix: action icon not always updating when adding, changing or removing an action/container.
- Fix: usage icons on map to vjoy button grid update on profile load
- Fix: usage icons on map to vjoy button grid show other mappings when clicked
### (m16)
- Fix: missing raw value in curve
### (m15)
- Fix: enabled/disabled state of MIDI and OSC inputs did not impact UI such as sort and device visibility. They now do.
### (m14)
- Fix: Gated Axis delete gate does not update range data.
- Fix: Gated Axis add/remove container or actions in range or gate action could disable input tracking and cause the Gated Axis action to become unresponsive.
### (m13)
- Fix: Merge Axis action creating invalid axis reference for second device upon initialization if the first device was the last axis on the particular input device selected.
- Fix: Merge Axis action not marked as a singleton action.
- Fix: Merge Axis action not showing output value at design time in some situations.
- Improved: Map to Vjoy action in an action container will display the correct design time axis output when nested or no data if the parent action does not support it.
### (m12)
- Fix: With a new, unsaved profile, removing a container for a gate or range in the Gated Axis action results also removes the container on the parent action (this was a visual item, upon saving it would load correctly the next time). This is resolved in m12.
- Improved: Singleton actions (actions that can only apply once per input) will generate a message box error if added more than once, or if nested.
- API: Actions can now be marked as singleton at the plugin level to indicate they must be unique per input mapping.
- Improved: Detail button in profile import will show the capabilities of the source and target for mapping purposes.
- Fix: debug mode left on in m11 would call up XML profile in the default text editor if they differed.
### (m11)
- Fix: for midi and osc enabled options not saving properly after changes to the validation logic for these two services introduced in m6.
### (m10)
- Improved: profiles no longer save empty entries (entries with no mappings and entries that use defaults) - this reduces the size of the saved profile and improves loading/save time.
- Improved: detection of profile changes when loading a new profile (will now ignore default entries or entries with no mappings)
- Fix: window title doesn't always get updated when loading a profile from the menu
### (m9)
- New: left and right panels can be resized via a splitter
- Fix: Gated Axis add/remove gate manually throws an exception when manually setting the gate count
### (m7/8)
- Fix: saving calibration throws an exception (bad reference)
- Fix: add gate via the add button throws an exception (bad reference)
- WIP: profile import - added re-import button on device imports for automatic remap when device changes and axis/button/hat counts changed.
### (m6)
- Improved: still a WIP: import of profiles now includes un-mapped modes, deselecting a mode in one mapping deselects all, and input descriptions carry over.
- Fix: curve input causing a recursive exception when moving control points.
### (m6)
- Fix: Updated logic used to determine if changes are made to a profile to avoid excessive prompting to save on profile load if an existing profile is already loaded: the updated check does away with hash values, ignores comments, internal IDs, file encodings and other non-relevant changes as these would trigger a save change prompt, even when there were none on a substantive basis.
- Improved: still a WIP: improved handling of profile import logic and mapping to devices with fewer axes/buttons/hats. Fix for keyboard, MIDI and OSC inputs that cannot have a remap change - they import as they are since the input is fixed.
- Fix: Update selection on tab change recalls correct input description
- Fix: Curve option buttons sometimes appeared on non joystick inputs
- Fix: Clicking on a curve or calling up a curve could cause a cast exception
- Fix: Selecting a new mode does not select an active input in the UI
- Improved: New profiles will show as "untitled" in the main window title bar
### (m4)
- Added descriptive error message on DirectInput interface load errors if UAC (user access control) prevents it from loading depending on the permissions of the logged in account. If a DLL load error occurs at startup, running the process in administrator mode usually solves the load issue.
- Added check for MIDI ports to be available before offering the MIDI device tab. If you get an exception when changing to the MIDI or OSC devices, please create a GitHub issue and attach the screenshot of the exception.
### (m3)
- Refactored behavior of *cycle mode* and *temporary mode* switch actions to handle gremlinEx backend changes
- Bug fix: deleting a mode from a profile did not remove all references or mappings from actions
### (m2)
- Added option to show or hide the button grid in vjoy remap
### (m1)
- Ensure mode names ignore leading/trailing spaces
- Add log entry if action reports invalid (to the log file) thus disabling the container at profile runtime
- Reworked priority of Cycle Modes action to match other mode actions (to execute last)
- Improved handling of mode mapping in profile import (still not ideal but workable)
- New switch container (experimental). The switch container is designed to map a switch with multiple positions to make it easier to map a set of input buttons to actions. The container is not essential but can be used to map two-way, three-way and rotary buttons more easily, and the functionality is not new - the only "new" aspect is to do this in a single container rather than multiple buttons.
<!-- TOC --><a name="134015ex"></a>
## 13.40.15ex
<!-- TOC --><a name="m54-hotfix"></a>
### (m5.4) hotfix
- Allow vjoy devices setup as wheel that then misreport direct input data to function in GremlinEx (the hack causes the devices to report fewer axes than they actually have causing a mismatch). GremlinEx will use the misreported information as "correct".
<!-- TOC --><a name="m53-hotfix"></a>
### (m5.3) hotfix
- The range container now supports press and release actions automatically an mimic a button mapping being "pressed" while in the range and "released" when the axis value exits the range.
- API: containers and actions now have the concept of an "override" input type and input id for containers that change the behavior of the input to something else so the actions configure themselves correctly (example, containers that split up an axis range)
- TTS is threaded by default now to avoid text to speech from delaying the execution of containers/actions. This is experimental. All speech will now run in parallel to the rest of the execution graph so the actions will run while the speech executes. This could lead to unexpected consequences but in general avoids TTS from being such a terrible impact on the timely execution of other commands.
<!-- TOC --><a name="m52-hotfix"></a>
### (m5.2) hotfix
- Bug fix: joystick hat incorrect output
- Bug fix: Joystick axis value not functional with legacy "Remap" mapper in m5
- Added invert flag to Map to Mouse Ex for motion output
<!-- TOC --><a name="m5"></a>
### (m5)
- New feature (experimental): It is now possible to assign a response curve directly to the input axis. This directly impacts the value passed to a container/action. The curve can be edited directly on an axis input and removed as needed.
- API: joystick event has a new member, curve_value that contains any curved data.
- bug fix: merge axis option on vjoy remap now shows the output axis in the drop down again.
- bug fix: input icons now appear for the tempo ex container.
<!-- TOC --><a name="m410-hotfix"></a>
### (m4.10) hotfix
- Slight rework of curve editor UI (added repeater)
- Output display is now clamped in case the computed axis value is out of bounds due to the curve settings
- Bug fix: an extra point at the center is no longer created when loading control points, and fix for a log error when saving gated axis data.
<!-- TOC --><a name="m48-hotfix"></a>
### (m4.8) hotfix
- Added a latched functor ability to register extra functor callbacks to trigger on defined inputs. This enables a functor to register additional triggers on inputs other than the one it is attached to. This is much cleaner than hooking inputs directly in the functor and follows the GremlinEx "wiring" model.
- Fixed vjoy remap's computation of merged data and enabled the latched functor feature for that action when input is merged.
- Fixed hat input causing an unknown input exception in callbacks
<!-- TOC --><a name="m46-hotfix"></a>
### (m4.6) hotfix
- Fix for paste of some actions or containers failing
- Fix for output values of vjoy remap in certain modes not having display axes
- Fix for loading certain vjoy remap modes not updating some UI fields correctly
- Additional verbose logging if certain TTS voice cannot be loaded or executed with fall-back to default voice if possible.
- Fix for restore last input feature not consistently restoring the correct last input
<!-- TOC --><a name="m45-hotfix"></a>
### (m4.5) hotfix
- Added remap curve ex additional functionality to traverse and edit control and handle coordinates
<!-- TOC --><a name="m42-hotfix"></a>
### (m4.2) hotfix
- removed button timer on auto input highlighting causing some buttons inputs from being ignored
- allowed shift/control overrides to also change devices for auto input highlighting
- response curve - adjusted opacity on input marker to make it easier to see behind it
<!-- TOC --><a name="m41-hotfix"></a>
### (m4.1) hotfix
- added additional log output for device and plugin load
- added additional log output on device naming mapping
<!-- TOC --><a name="m4-1"></a>
### (m4)
- Updated plugin - Response Curve EX - uses revamped internal curve mapper
- Updated response curve mapper (standalone in Response Curve EX) and built-in to Map to Vjoy (VjoyRemap):
+ ability to store and load curve presets - presets are stored as XML files
+ snap to grid of control points (and handles) including 0, 45 and 90 degree snap
+ use shift for fine grid, control for coarse grid
+ updated look
+ help guide
<!-- TOC --><a name="m3-1"></a>
### (m3)
- VjoyRemap plugin now supports curved output directly in the action without having to add a response curve. The curve can be added or removed. The curve dialog now has a number of bezier curve presets. The curve is applied after all the other transforms, including merging.
<!-- TOC --><a name="m2-1"></a>
### (m2)
- First attempt with multiple code refactors and bug fixes detailed below.
- Added cleanup events for action plugins so they can release resources via _cleanup() \[AbstractAction] and _cleanup_ui() \[AbstractActionWidget] - the methods are virtual so are optional but will be called when an action is deleted or unloaded. This helps with releasing references that could cause problems with the automatic garbage collection and hooks into various events.
- **Cut/Paste refactor** for Containers and Actions - this eliminates keeping a reference to the source binary object that can cause problems with garbage collection. The refactor now only stores XML configuration data in the internal clipboard and is thus much smaller memory wise.
- Many UI objects are now persisted rather than being recreated on UI refresh (performance and memory optimization)
- Refactored **Gated Axis with custom control** to avoid QT internal critical crash involving QT sliders.
- **Gated Axis** now supports concurrent mappings for range and gate condition (they stack)
- Added a **new axis merge** capability direct into the "**map to vjoy**" plugin. This avoids the need to use the separate merged axis functionality. The base iteration lets you merge another input concurrently via the "Merge Axis" mode and select add, average and center mode, optional inversion, and output scaling. The merged output data will be sent to the mapped containers/actions.
- Fixed a minor icon sizing issue for action icons - they are now all consistent.
- For newer users using legacy profiles, legacy keyboard, mouse and remap plugins now indicate there are replacements plugins in GremlinEx.
- GremlinEx now has separate preferences kept with each profile (will have a .json extension)
- One such preference is remembering the last selection per device per profile that will be restored on subsequent profile load if the device/input still exists.
- Fixed an issue with automated description entries being saved to a profile overriding the manually entered description for an input.
- Fixed an issue with OSC and MIDI UI due to prior UI refactors
- Further refactor of **ComboBoxes** to only display up to 20 items before scrolling
- Update to QT 6.7.3
- Refinement of device highlight to clarify options. If highlighting is enabled, button highlighting can be enabled by holding shift down, and axis highlighting can be enabled temporary by holding the control key.
<!-- TOC --><a name="m1-1"></a>
### (m1)
- **Gamepad support** JGEX supports up to four (4) virtual XBox 360 gamepads via VIGEM. See gamepad section. Gamepads can be mapped via the new **map to gamepad** action.
- Improved device mapping output.
- **Profile Import** JGEX can import mappings from another profile into the current profile optionally changing the destination, mode and mappings. This feature is experimental and still in development and is not feature complete at this time.
A new menu option "import profile" in the file menu, or the context menu on a device tab brings up the option.
Current features are:
- import to another device
- import to the same mode or a different mode (that exists)
- selectively select imports from a device. mode, input or container (four levels)
- import is currently additive (imported items are added to the current input in the current profile)
+ import to another input (button or axis)
+ supports importing mappings for joystick, keyboard, MIDI and OSC
- QOL feature: most drop downs limited to 20 items before they start scrolling
- bug fixes
<!-- TOC --><a name="134014ex-m22"></a>
## 13.40.14ex (m22)
This release adds major new features, including some minor changes in UI functionality, and a few more QOL (quality of life) enhancements.
- **VJoy device name enhancement** VJoy devices are now displayed including the axis/button/hat count in the name to make them easier to distinguish. This works because VJoy requires each defined virtual joystick to be different either in the number of axes, buttons or hats defined so they are unique.
- **New Merge Axis action** The merge axis action is similar to the merge-axis profile feature (from the menu) option except that it can be attached to any joystick axis input (any device will do) in a profile as a regular action. The merge action, as with the gated axis action, allows the action itself to define sub-containers and sub-actions by clicking on the configuration button. The output of the merged axis action will be sent to these sub-actions for processing, which can include response curve and any other action applicable to axis input data. Note: output from this action is not going to be sent to other actions defined alongside it, only the sub-containers the action defines itself.
- **New device reorder** It is now possible to re-order the hardware device tabs. The order is persisted from one session to the next. Right click on the tab to sort the input back to default. This is only a visual feature - the hardware order of the devices cannot be changed as it's determined by the operating system.
- **New device substitution** It is now possible to replace one or more device hardware IDs with another so long as the id is not duplicated. This is a requested feature if your hardware IDs change frequently (a rare condition). This is a QOL feature to do an edit to the profile that had to be done in the XML directly until now. The dialog shows the profile devices in the top drop down, and the detected hardware devices with the new IDs in the bottom. The old profile is backed up for you just in case and the updated profile is reloaded for you if a replace occurred.
- **New virtual keyboard** dialog to simplify key and mouse button selection. The updated editor supports hidden keys such as F13 to F24 and enables mouse buttons to be used as any "key" input to simplify mapping. (QOL)
- Revamped keyboard input device and UI with virtual keyboard with mouse input support with multiple key latching. Profiles using the old style should convert automatically to the new style. Inputs can be added, edited and removed. Latching (concurrent keys pressed) allows for complex and unusual keyboard input combinations to trigger actions including latching with mouse button and mouse wheel inputs.
- Revamped keyboard conditions on actions or containers: a keyboard condition now uses the new virtual keyboard editor and allows for multiple latched keys and mouse button triggers. (QOL)
- **New MIDI input device** - GremlinEx can now map MIDI events to GremlinEx actions. The new MIDI inputs can be added, edited and removed in the MIDI device tab.
- **New OSC (Open Sound Control) input device** - GremlinEx can now map OSC events to GremlinEx actions. The new OSC inputs can be added, edited and removed from the OSC device tab.
- **New Gated Axis action** functionality for some actions (SimConnect axis mapping as well as VJoy axis mapping - new axis mode). Gates axes have the notion of "gates", or points along an axis that can be used to trigger one or more sub-actions and modify the axis value output behavior. Data and triggers for this action will be sent to the sub-containers and sub-actions it defines on each gate or range based on conditions as defined. Note: output from this action is not going to be sent to other actions defined alongside it, only the sub-containers the action defines itself.
- **New Input Map dialog** - in the tools menu, "view input map" tool displays a dialog containing the current profile mappings as a tree, can be exported to the clipboard.
- Improved icon reload speed (speeds up the UI load/refresh/update)
- New file menu for opening Explorer to the current profile folder (QOL)
- New file menu for opening the profile XML in a text editor (it will save the profile first) (QOL)
- New mouse event drop down selector in map to mouse ex: adds a mouse event selection drop down so mouse actions can be selected by name rather than mouse input only.
- Action container will now scroll horizontally if the action is too wide to fit based on windows size / UI scaling options. (QOL)
- Profiles can be saved even if one or more actions are not configured (QOL)
- Updated profile to application (process) mapping in the options dialog (QOL)
- Options dialog remembers which tab it was last in (QOL)
- Options dialog has a close button (QOL)
- Options dialog saves profile mapping information on close (QOL)
- Pressing F5 in the UI will activate the current profile (QOL)
- New configuration dialog for the loaded profile, separate from the global options (QOL). This lets you quickly set profile activation options.
- New option to force numlock off when a profile starts to help with the more complex latching that use numpad keys.
- Added joystick input value display on axis inputs - shows an axis bar with the current axis value in the input (QOL) - can be toggled in options.
- Update to Python 3.12.5
- Profile mode change is now disabled when the profile runs to avoid conflicts. Use the new profile startup profile option to pick a profile when the profile is loaded if the profile mode needs to be changed when the profile runs.
- User plugins that use plugin variables now support partial save. This can be enabled or disabled in options. When enabled, plugin instance configurations setup in user-plugin tab will save in-progress work at edit time to the profile when the profile is saved. Instances that are not fully configured will not be active at profile runtime and a log entry will be issued as a warning to skip the instance load. This is on a per instance basis.
- The JGEX UI and configuration options are mostly disabled when a profile runs so edits to an active profile are only permitted when a profile is not active. The change has to do with changes in behaviors in the core system and the potential for conflicting events impacting profile state while a profile runs.
- When changing modes, the hourglass will be displayed during the UI update operation (this can be time consuming because each device is reloaded on mode change for the current mode)
- Play sound action now has a play button to test play the sound file while in edit mode.
- Curve editor now remembers the symmetry setting.
- Curve editor now displays current input if input visualization is enabled.
- New clear map tool - removes all mappings from the selected device and mode
- Improved device change behavior - new option to ignore device changes at runtime to avoid profile runtime disruptions especially if the connect or disconnect is momentary (due to sleep mode for example). See section on device change.
6/6/24 - 13.40.13ex (h) **potentially breaking change**
- GremlinEx will now more gracefully handle DLL errors and check driver and DLL versions. If the driver and DLL versions are not at minimum levels expected, an error box will be displayed and will exit the app to avoid further errors due to mismatched versions.
GremlinEx requires vJoy device driver 12.53.21.621 (VJOY release 2.1.9.1 minimum). The distribution includes the interface DLL for 2.1.9.1, but not the software which by licensing agreement cannot be included in the GremlinEx distribution. The latest version can be found here:
The vJoy version can be found here: https://sourceforge.net/projects/vjoystick/files/Beta%202.x/2.1.9.1-160719/