Previous Thread
Next Thread
Print Thread
Rate This Thread
Hop To
#4422248 - 05/23/18 01:28 PM Controlling combined keys behavior  
Joined: May 2001
Posts: 468
Joao Muas Offline
Member
Joao Muas  Offline
Member

Joined: May 2001
Posts: 468
Portugal
Hello all again.

This one is bugging me for quite some time...
It's not really a programming issue, but it's about the TARGET behavior.

If you set

MapKey(&Joystick, TG1, L_SHFT+'b')

And then check what is happening in the event viewer, you will see something like this

Key Press: L_SHFT
Key Press: b
Key Release: L_SHFT [112ms]
Key Release: b [112ms]

Which should be ok, but... sometimes you see this...

Key Press: L_SHFT
Key Press: b
Key Release: L_SHFT [112ms]
Key Release: b [113ms]

And then what happens?

In the sim (I'm referring to iL-2 BOS series, my current favorite) you will get the L_SFHT+'b' input, but also a single 'b' input alone!! Unacceptable!!

I got around this by programing all my combined keys in a press/release configuration (press L_SHFT, press b, release b, release L_SHFT, and with delays in the middle to make sure it wont fail), but it's double the work, and the code starts to get too clumsy...

Why don't we get the result in this order?

Key Press: L_SHFT
Key Press: b
Key Release: b [112ms]
Key Release: L_SHFT [112ms]
or
Key Release: L_SHFT [113ms]

Am I missing something? Is it a problem with iL-2 BOS itself?

I downloaded a iL-2 BOS target config file from Thrustmaster, and guess what, it's programmed in a press/release configuration too...

Is it possible that a MapKey(&Joystick, TG1, 'b') can only work flawlessly with single keys only? I doubt very much...

Any ideas? Did anyone struggled with this before?

Thank you.

Inline advert (2nd and 3rd post)

#4422323 - 05/23/18 09:44 PM Re: Controlling combined keys behavior [Re: Joao Muas]  
Joined: Jul 2016
Posts: 61
Drakoz Offline
Junior Member
Drakoz  Offline
Junior Member

Joined: Jul 2016
Posts: 61
Ya, this is a problem with several games. I haven't tried IL-2, but I'm not surprised to see this issue. Most games see the modifier key correctly, but some are picky about it. I recently did a TARGET script for the Warthog for Train Sim World, and ran into this for almost all multi-key combos. The solution is to just use CHAIN with LOCK and D() to press the keys one at a time with delays between them. See the examples below.

I'm sure you know this, but I'll explain for clarity. CHAIN of course issues each action one by one which allows you to put a delay like D() or D(25) between key presses. Below, you'll see I have some delays in the hundreds of ms (e.g. D(250) and D(300)). That is just a Train Sim World thing and should not be needed for most games. The default delay D(), or D(25) should work for most games.

First, the simple example to press SHIFT-h.

Code
MapKeyIO (&Throttle, EORIGN, 0, CHAIN(LOCK+DOWN+L_SHIFT, D(50), DOWN+'h', D(250), UP+'h', D(50), UP+L_SHIFT, D(50), LOCK));


DOWN+ causes the given key to be pressed. UP+ causes the given key to be released.

LOCK makes sure that the entire key press combo happens uninterrupted. This may or may not be needed. But without it, if you press two buttons at once, TARGET will send both key combos at the same time which could have bad results. The first LOCK locks the CHAIN. The second LOCK unlocks it and allows other key presses to go forward. TARGET will never miss a button press because of LOCK. It will just queue them up and issue each locked key combo one after the other. So keep your delays to a minimum or you will have lag. I have queued dozens of key press combos like this in my Train Sim World script and it doesn't miss a single key press.

The D(50) delay at the end just before the releasing LOCK may or may not be needed. I added it because if multiple key combos were queued up, you may want TARGET to wait a moment before sending the next key combo.

If you want to make macros so you can reuse them you can create the CHAIN() commands with define in your .ttm, or if you want to create them locally in your .tmc, within main() or within a function, you can define the CHAIN with an integer variable (e.g. int headlightFrontFwd = ...). Either should work, but remember that you can't do a define inside a function or main(). CHAIN() returns a unique number (pointer reference), and all you need is an int variable that holds that pointer reference and you can reuse it in your other MapKey() commands as if you did a define. It's a preference thing, more about code readability than anything else.

Here's the full example...

Code
// Headlight Switch
// Following complicated CHAIN commands needed to overcome issues with SHIFT & CTL not being received properly by TSW (bug with TSW?)
int headlightFrontFwd = CHAIN(LOCK+DOWN+'h', D(250), UP+'h', D(50), LOCK);
int headlightFrontBkd = CHAIN(LOCK+DOWN+L_SHIFT, D(50), DOWN+'h', D(250), UP+'h', D(50), UP+L_SHIFT, D(50), LOCK);
int headlightRearFwd = CHAIN(LOCK+DOWN+L_CTL, D(50), DOWN+'h', D(300), UP+'h', D(50), UP+L_CTL, D(50), LOCK);
int headlightRearBkd = CHAIN(LOCK+DOWN+L_SHIFT, D(50), DOWN+L_CTL, D(50), DOWN+'h', D(300), UP+'h', D(50), UP+L_CTL, D(50), UP+L_SHIFT, D(50), LOCK);
// Engine Operate Switch - Right
MapKeyIO (&Throttle, EORIGN, 0, headlightFrontFwd);
MapKeyIO (&Throttle, EORNORM, 0, 0);
MapKeyRIO(&Throttle, EORMOTOR, 0, 0);
MapKeyIO (&Throttle, EORMOTOR, 0, headlightFrontBkd);	
// Engine Operate Switch - Left
MapKeyIO (&Throttle, EOLIGN, 0, headlightRearFwd);
MapKeyIO (&Throttle, EOLNORM, 0, 0);
MapKeyRIO(&Throttle, EOLMOTOR, 0, 0);
MapKeyIO (&Throttle, EOLMOTOR, 0, headlightRearBkd);	


BTW, my Train Sim World TARGET script can be found here: https://forums.dovetailgames.com/th...warthog-throttle-saitek-tq-profile.3634/

Train Sim World (TSW) does not support game controllers, so I wrote custom C functions in TARGET to do axis to keyboard mapping to control trains via the keyboard from a Warthog Throttle. The built in functions which can do Axis to keyboard mapping (AXMAP1() and AXMAP2()) do not do what I needed. So I had to create the equivalent of a function that does AXMAP1() and AXMAP2() at the same time. This TARGET script extensively uses the concept of CHAIN() commands and LOCK+, UP+, DOWN+ and D() to make this happen reliably. I mention it here because if you want to see this concept taken to the limit, check out my TSW Script. There is a PDF included that documents most of what I did. Just FYI.


Moderated by  RacerGT 

Quick Search
Recent Articles
Support SimHQ

If you shop on Amazon use this Amazon link to support SimHQ
.
Social


Recent Topics
Grown ups joke time
by NoFlyBoy. 03/18/24 10:34 PM
Anyone Heard from Nimits?
by F4UDash4. 03/18/24 10:01 PM
RIP Gemini/Apollo astronaut Tom Stafford
by semmern. 03/18/24 02:14 PM
10 years after 3/8/2014
by NoFlyBoy. 03/17/24 10:25 AM
Hans Zimmer North American concert tour 2024
by NoFlyBoy. 03/16/24 10:54 PM
Steam Spring Sale.
by RedToo. 03/15/24 09:09 PM
Starship Attempt Three
by F4UDash4. 03/14/24 12:06 PM
This is one cool turbofan model
by Zamzow. 03/14/24 02:41 AM
Map Errors
by F4UDash4. 03/13/24 11:25 AM
Copyright 1997-2016, SimHQ Inc. All Rights Reserved.

Powered by UBB.threads™ PHP Forum Software 7.6.0