Previous Thread
Next Thread
Print Thread
Rate This Thread
Hop To
#4427345 - 06/23/18 02:01 PM 8 way Hat Switch button names  
Joined: May 2001
Posts: 468
Joao Muas Offline
Member
Joao Muas  Offline
Member

Joined: May 2001
Posts: 468
Portugal
Hello.

The 8 way hat switch button names... H1U, H1D, H1R, H1L

How about the other in between four? I tried H1UR, H1UL, H1DR, H1DL... but it doesn't work...

Examples on the target software only state the first four... how do I program the others?

Thanks in advance.

Inline advert (2nd and 3rd post)

#4427524 - 06/24/18 02:58 PM Re: 8 way Hat Switch button names [Re: Joao Muas]  
Joined: May 2001
Posts: 468
Joao Muas Offline
Member
Joao Muas  Offline
Member

Joined: May 2001
Posts: 468
Portugal
I looked at the defines.tmh file and didn't find these in between buttons...
They are defined at the virtual joystick section though...
Code
define DXHATUP		3300
define DXHATUPRIGHT 	3301
define DXHATRIGHT	3302
define DXHATDOWNRIGHT   3303
define DXHATDOWN	3304
define DXHATDOWNLEFT 	3305
define DXHATLEFT	3306
define DXHATUPLEFT	3307

Does this mean they can only be assigned as DX buttons and configured within the game?
I used to be able to program these buttons in my Cougar when using the Foxy software before... does this mean that we cannot program them with Target?!?...

#4427637 - 06/25/18 03:25 AM Re: 8 way Hat Switch button names [Re: Joao Muas]  
Joined: Jul 2016
Posts: 61
Drakoz Offline
Junior Member
Drakoz  Offline
Junior Member

Joined: Jul 2016
Posts: 61
Yes, you are correct, there is no H1UR, H1UL, etc. button names. Also, the DXHATUP, DXHATUPRIGHT, etc. don't help for detecting U and L or U and R for example.

You can do the following which will map HAT1 to operate as the normal 8 position DirectX HAT.

Code
MapKey(&Joystick, H1U, DXHATUP);
MapKey(&Joystick, H1D, DXHATDOWN);
MapKey(&Joystick, H1L, DXHATLEFT);
MapKey(&Joystick, H1R, DXHATRIGHT);


At first, it might seem that this won't work because it only maps the UP/DOWN/LEFT/RIGHT DX buttons, but with this mapping, TARGET will automatically detect and send the diagonal mappings as well (e.g. DXHATUPRIGHT). Probably not what you want, but it is an important point to understand if you actually do want to map a HAT to work as a DirectX HAT.

To map specific keys for all 8 directions, though, you would need to do something like this:

Code
MapKey(&Joystick, H1U, EXEC(
	"if (Joystick[H1L]) ActKey(PULSE+KEYON+'8');"		// H1UL
	"else if (!Joystick[H1R]) ActKey(PULSE+KEYON+'1');")	// H1U
);
MapKey(&Joystick, H1R, EXEC(
	"if (Joystick[H1U]) ActKey(PULSE+KEYON+'2');"		// H1UR
	"else if (!Joystick[H1D]) ActKey(PULSE+KEYON+'3');")	// H1R
);
MapKey(&Joystick, H1D, EXEC(
	"if (Joystick[H1R]) ActKey(PULSE+KEYON+'4');"		// H1DR
	"else if (!Joystick[H1L]) ActKey(PULSE+KEYON+'5');")	// H1D
);
MapKey(&Joystick, H1L, EXEC(
	"if (Joystick[H1D]) ActKey(PULSE+KEYON+'6');"		// H1DL
	"else if (!Joystick[H1U]) ActKey(PULSE+KEYON+'7');")	// H1L
);


This works, but not very well. If you don't press the hat exactly in a diagonal direction (pressing U and L at the same time for example), then you will get a double key press as TARGET will think you are pressing U or L first, then then it will see U and L at the same time and output two keys.

The solution is to add delay before you evaluate which hat buttons are pressed using TEMPO() as follows.

Code
MapKey(&Joystick, H1U, TEMPO( 0,
	EXEC(
		"if (Joystick[H1L]) ActKey(PULSE+KEYON+'8');"		// H1UL
		"else if (!Joystick[H1R]) ActKey(PULSE+KEYON+'1');"	// H1U
	),
	100)
);
MapKey(&Joystick, H1R, TEMPO( 0,
	EXEC(
		"if (Joystick[H1U]) ActKey(PULSE+KEYON+'2');"		// H1UR
		"else if (!Joystick[H1D]) ActKey(PULSE+KEYON+'3');"	// H1R
	),
	100)
);
MapKey(&Joystick, H1D, TEMPO( 0,
	EXEC(
		"if (Joystick[H1R]) ActKey(PULSE+KEYON+'4');"		// H1DR
		"else if (!Joystick[H1L]) ActKey(PULSE+KEYON+'5');"	// H1D
	),
	100)
);
MapKey(&Joystick, H1L, TEMPO( 0,
	EXEC(
		"if (Joystick[H1D]) ActKey(PULSE+KEYON+'6');"		// H1DL
		"else if (!Joystick[H1U]) ActKey(PULSE+KEYON+'7');"	// H1L
	),	
	100)
);


This works very well for pulsed outputs. Change the delay (100) as desired, but 100ms seemed to work well for me.

If you want the HAT to be able to press and hold a key, you will need to remove the PULSE statements above as well as create MapKeyR() statements to release the keys as follows. The first section (the MapKey() statements) still uses TEMPO() to create a delay for accurately detecting which HAT direction is being pressed. The second section (the MapKeyR() statements) just blindly releases all possible key combos that were previously pressed. There's no need for if statements for the MapKeyR() statements because blindly releasing a key doesn't harm anything.

Code
// Press and hold keys
MapKey(&Joystick, H1U, TEMPO( 0,
	EXEC(
		"if (Joystick[H1L]) ActKey(KEYON+'8');"		// H1UL
		"else if (!Joystick[H1R]) ActKey(KEYON+'1');"	// H1U
	),
	100)
);
MapKey(&Joystick, H1R, TEMPO( 0,
	EXEC(
		"if (Joystick[H1U]) ActKey(KEYON+'2');"		// H1UR
		"else if (!Joystick[H1D]) ActKey(KEYON+'3');"	// H1R
	),
	100)
);
MapKey(&Joystick, H1D, TEMPO( 0,
	EXEC(
		"if (Joystick[H1R]) ActKey(KEYON+'4');"		// H1DR
		"else if (!Joystick[H1L]) ActKey(KEYON+'5');"	// H1D
	),
	100)
);
MapKey(&Joystick, H1L, TEMPO( 0,
	EXEC(
		"if (Joystick[H1D]) ActKey(KEYON+'6');"		// H1DL
		"else if (!Joystick[H1U]) ActKey(KEYON+'7');"	// H1L
	),	
	100)
);
// Release keys
MapKeyR(&Joystick, H1U, EXEC("ActKey('8'); ActKey('1'); ActKey('2');") );	// Release UL, U, UR
MapKeyR(&Joystick, H1R, EXEC("ActKey('2'); ActKey('3'); ActKey('4');") );	// Release UR, R, DR
MapKeyR(&Joystick, H1D, EXEC("ActKey('4'); ActKey('5'); ActKey('6');") );	// Release DR, D, DL
MapKeyR(&Joystick, H1L, EXEC("ActKey('6'); ActKey('7'); ActKey('8');") );	// Release DL, L, UL


You could also do all this using a custom function or functions which might be cleaner or provide more control. For example, if I wanted to use IO or UMD shift modes with the HAT, I would probably just write pure C code in a function to deal with it. Otherwise, using the above ideas with MapKeyIOUMD() would get very messy. A single function could handle all possible hat positions and IOUMD states by passing in parameters depending on the hat button and state.

#4427729 - 06/25/18 09:10 PM Re: 8 way Hat Switch button names [Re: Drakoz]  
Joined: May 2001
Posts: 468
Joao Muas Offline
Member
Joao Muas  Offline
Member

Joined: May 2001
Posts: 468
Portugal
All this to program the hat corners?!?
Wow...

I would prefer a function really, but I can't do it myself... unless you show me the way... smile

#4427743 - 06/25/18 10:08 PM Re: 8 way Hat Switch button names [Re: Joao Muas]  
Joined: Jul 2016
Posts: 61
Drakoz Offline
Junior Member
Drakoz  Offline
Junior Member

Joined: Jul 2016
Posts: 61
Ya, sadly, TARGET doesn't offer a built in solution for this.

What I wrote seems like a lot of coding, but really it's just a simple EXEC("if... else... ActKey()") statement repeated 4 times (once for each hat direction U, D, L, R), buried in a TEMPO statement to make sure TARGET doesn't confuse U with UR or UL for example. Then I did this in two versions, one for pulsed outputs, and one for press and hold outputs. So for the press and hold outputs, you need to do the MapKeyR() statements to release the keys.

When I get a chance, I'll try making a function to clean this up.

#4427761 - 06/25/18 11:37 PM Re: 8 way Hat Switch button names [Re: Drakoz]  
Joined: May 2001
Posts: 468
Joao Muas Offline
Member
Joao Muas  Offline
Member

Joined: May 2001
Posts: 468
Portugal
Originally Posted by Drakoz
When I get a chance, I'll try making a function to clean this up.
Thank you!

#4427878 - 06/26/18 10:04 PM Re: 8 way Hat Switch button names [Re: Joao Muas]  
Joined: May 2001
Posts: 468
Joao Muas Offline
Member
Joao Muas  Offline
Member

Joined: May 2001
Posts: 468
Portugal
Originally Posted by Drakoz
Code
// Press and hold keys
MapKey(&Joystick, H1U, TEMPO( 0,
	EXEC(
		"if (Joystick[H1L]) ActKey(KEYON+'8');"		// H1UL
		"else if (!Joystick[H1R]) ActKey(KEYON+'1');"	// H1U
	),
	100)
);
MapKey(&Joystick, H1R, TEMPO( 0,
	EXEC(
		"if (Joystick[H1U]) ActKey(KEYON+'2');"		// H1UR
		"else if (!Joystick[H1D]) ActKey(KEYON+'3');"	// H1R
	),
	100)
);
MapKey(&Joystick, H1D, TEMPO( 0,
	EXEC(
		"if (Joystick[H1R]) ActKey(KEYON+'4');"		// H1DR
		"else if (!Joystick[H1L]) ActKey(KEYON+'5');"	// H1D
	),
	100)
);
MapKey(&Joystick, H1L, TEMPO( 0,
	EXEC(
		"if (Joystick[H1D]) ActKey(KEYON+'6');"		// H1DL
		"else if (!Joystick[H1U]) ActKey(KEYON+'7');"	// H1L
	),	
	100)
);
// Release keys
MapKeyR(&Joystick, H1U, EXEC("ActKey('8'); ActKey('1'); ActKey('2');") );	// Release UL, U, UR
MapKeyR(&Joystick, H1R, EXEC("ActKey('2'); ActKey('3'); ActKey('4');") );	// Release UR, R, DR
MapKeyR(&Joystick, H1D, EXEC("ActKey('4'); ActKey('5'); ActKey('6');") );	// Release DR, D, DL
MapKeyR(&Joystick, H1L, EXEC("ActKey('6'); ActKey('7'); ActKey('8');") );	// Release DL, L, UL
This actually does the job pretty well...

#4427892 - 06/27/18 01:45 AM Re: 8 way Hat Switch button names [Re: Joao Muas]  
Joined: Jul 2016
Posts: 61
Drakoz Offline
Junior Member
Drakoz  Offline
Junior Member

Joined: Jul 2016
Posts: 61
Originally Posted by Joao Muas
This actually does the job pretty well...


Great to hear.

If you find that sometimes it still gets some false clicks (like U when you intended UL, or you get a U and UL double click), increase the delay time for the 4 TEMPO statements from 100 to 150 or 200 or higher to see if you like it better. Or be more deliberate when you press a diagonal HAT position and 100 should work fine.

The down side about this 8 way hat method is that it uses TEMPO which makes it less easy to use TEMPO for it's intended purpose.

TEMPO allows creating a short press and a long press. I use this all the time to create 0.5 second long presses for things like TrackIR center or game pause while allowing the same buttons to be used for flight or weapon controls normally with a short press. A long press is often more convenient than an IO press to create more functions on a single button. So with TEMPO used on a hat normally, you can get 8 buttons (U, ULONG, D, DLONG, R, RLONG, L, LLONG). But because I used TEMPO to make the 8 way hat function more accurate by adding a small delay, we can't use it to add long delay button presses.

Well, we can, but the 8 way hat function always has to be the long press. So actually using TEMPO to create an 8 way hat allows for 12 buttons on a hat - a short press U, L, D, R, and a long press 8 way hat.

Here is my 8 way hat code, but I changed the TEMPO delay to 500ms, and added 'u', 'r', 'd', and 'l' to the short press modes giving us 12 buttons on a single hat now. This works the same for the "pulsed" code below as well as "press and hold" version of my code posted earlier.

Code
MapKey(&Joystick, H1U, TEMPO( 'u',							// H1U short press
	EXEC(
		"if (Joystick[H1L]) ActKey(PULSE+KEYON+'8');"		// H1UL long press
		"else if (!Joystick[H1R]) ActKey(PULSE+KEYON+'1');"	// H1U long press
	),
	500)
);
MapKey(&Joystick, H1R, TEMPO( 'r',							// H1R short press
	EXEC(
		"if (Joystick[H1U]) ActKey(PULSE+KEYON+'2');"		// H1UR long press
		"else if (!Joystick[H1D]) ActKey(PULSE+KEYON+'3');"	// H1R long press
	),
	500)
);
MapKey(&Joystick, H1D, TEMPO( 'd',							// H1D short press
	EXEC(
		"if (Joystick[H1R]) ActKey(PULSE+KEYON+'4');"		// H1DR	long press
		"else if (!Joystick[H1L]) ActKey(PULSE+KEYON+'5');"	// H1D long press
	),
	500)
);
MapKey(&Joystick, H1L, TEMPO( 'l',							// H1L short press
	EXEC(
		"if (Joystick[H1D]) ActKey(PULSE+KEYON+'6');"		// H1DL long press
		"else if (!Joystick[H1U]) ActKey(PULSE+KEYON+'7');"	// H1L long press
	),	
	500)
);


I was playing with a method of adding 8 way hat code to the short presses as well using nested TEMPO commands, but it doesn't work because it turns out the if... else... statements can't tell the state of the HAT buttons on a short press. The short press EXEC() code executes after the hat buttons have been released, which means the Joystick[H1U], Joystick[H1L], etc. states are all 0 and the if else statements don't work. I would have to save the state of the Hat buttons separately. It is trivial to do this, but now the code starts to grow into using special functions, and if I'm going to do that, I might as well write a single function to make all this work more cleanly. I know, some of my explanation starts to sound like gibberish. Don't be afraid to ask questions if you really want to understand what I mean.

At least I did confirm it is possible to nest TEMPO commands. For example the following code adds a short press (<500ms), medium press (< 500ms, > 1000ms), and long press (> 1000ms) to S1. Maybe nested TMEPO commands is getting a little ridiculous, but nice to know it works.

Code
MapKey(&Joystick, S1, PULSE+TEMPO(
	'1',			// short press < 500ms
	TEMPO(
		'a',		// medium press > 500ms, but < 1000ms 
		'b',		// long press > 1000ms
		500
	), 
	500)
);


Note, each TEMPO command has only a 500ms delay because delays are cumulative. The nested TEMPO command runs after the delay from the first TEMPO command so the delays add together (500 + 500 = the 1000ms delay for a long press). Also, it only works to place nested TEMPO commands in the long delay part of the first TEMPO command. The following example where I nest the TEMPO command on the short delay part does not work. If you release the button to cause the short delay action of the first TEMPO to execute, the nested TEMPO will always execute it's short action as well because the button has been released.

Code
MapKey(&Joystick, S1, PULSE+TEMPO(
	TEMPO(			// short press - nested TEMPO does not work
		'a',
		'b',
		500
	), 
	'1'				// long press
	500)
);


Now that you got me started on this, I really like the idea of having short and long press 8 way hats. I tend to use the two hats on my Warthog Throttle for a lot of stuff and I run out of buttons. So I'll see what I can do to tackle this with a custom function, and one that still works with IO and UMD states.

#4427923 - 06/27/18 01:53 PM Re: 8 way Hat Switch button names [Re: Drakoz]  
Joined: May 2001
Posts: 468
Joao Muas Offline
Member
Joao Muas  Offline
Member

Joined: May 2001
Posts: 468
Portugal
Originally Posted by Drakoz

Now that you got me started on this, I really like the idea of having short and long press 8 way hats. I tend to use the two hats on my Warthog Throttle for a lot of stuff and I run out of buttons. So I'll see what I can do to tackle this with a custom function, and one that still works with IO and UMD states.
That is good news.
Thank you!

I never used TEMPO before, but I understand what you did.

Here is how I use to set up my main HAT switch for flight simulators...
Code
              trim nose
     trim roll  down   trim roll
         left     U      right
             UL   |   UR
   Track      \      /       Track
     IR   L -            - R  IR
   center     /      \       pause
             DL   |   DR
    trim rudder   D   trim rudder
        left  trim nose   right
                 up


Note that the diagonals (UL, UR, DL, DR) are set with "I" mode, that is, the "cross" (U, R, L, D) is the most used, and works in "O" mode.
To trim the ailerons and rudder I have to press my "I" key.
This avoids any mistakenly pressed buttons on the hat, and I'm pretty used to it for long time.
With the old Cougar programming this was very straight forward, for all eight buttons are coded.

This is because the diagonals are sometimes hard to hit with a single press, without hitting on of the cross buttons first.
By doing this arrangement, when I want to trim rudder left for example, I press my "I" button, then press L and then DL, with a fairly easy left and down movement of the finger.
The same for all other diagonals - I always press L or R first in a left up/down or right up/down movement. It's error proof, and I got all my trims and Track IR in one HAT.

With your code above, this technic doesn't work, because of your "around the clock" conditions test. it works for UL and DR but it doesn't for UR and DL.
If I was using my old Cougar, this would be a problem... lately I've been using the T16000 and I must say its HAT switch is very accurate and I can hit the diagonals precisely with only one stroke, like 90% of the times. And like this, your code works flawlessly!

Of course I'd fancy a custom function to make it work "coming from all directions" if I may say it that way, but, as I said, I'm happy with it so far.
Anyway, I'd be happy to see your developments on this subject, maybe I will start using the TEMPO feature too. smile
Thank you.

#4428011 - 06/28/18 01:08 AM Re: 8 way Hat Switch button names [Re: Joao Muas]  
Joined: Jul 2016
Posts: 61
Drakoz Offline
Junior Member
Drakoz  Offline
Junior Member

Joined: Jul 2016
Posts: 61
I like your way of doing the trim. Logical and clean provided of course you can press the diagonal buttons without error (which you solved with the I and O in Foxy). Using diagonal positions on a hat has always been a problem, which is why people don't use them very often unless it is for something like looking around or adjusting a cursor on an MFD.

Originally Posted by Joao Muas

With your code above, this technic doesn't work, because of your "around the clock" conditions test. it works for UL and DR but it doesn't for UR and DL.


Increase the TEMPO delay (change the four 100 numbers to 200 or 300). I tested exactly the scenario you are talking about and it works 100% provided you make the diagonal button press faster than the TEMPO delay. A delay of 100 requires that you quickly and crisply move to the diagonal position. I tested this the way you described by pushing L first, then U, and L first and D (and all the other possible combos) and I consistently got UL and DL as long as I did the motion faster than 100ms. A delay of 200 to 300 allows you to be a bit more lazy, but of course also makes the button less responsive. So adjust the delay to suit your taste. The entire purpose for using TEMPO was to solve exactly the issue you describe.


Moderated by  RacerGT 

Quick Search
Recent Articles
Support SimHQ

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


Recent Topics
Actors portraying US Presidents
by PanzerMeyer. 04/19/24 12:19 PM
Dickey Betts was 80
by Rick_Rawlings. 04/19/24 01:11 AM
Exodus
by RedOneAlpha. 04/18/24 05:46 PM
Grumman Wildcat unique landing gear
by Coot. 04/17/24 03:54 PM
Peter Higgs was 94
by Rick_Rawlings. 04/17/24 12:28 AM
Whitey Herzog was 92
by F4UDash4. 04/16/24 04:41 PM
Anyone can tell me what this is?
by NoFlyBoy. 04/16/24 04:10 PM
10 Years ago MV Sewol
by wormfood. 04/15/24 08:25 PM
Pride Of Jenni race win
by NoFlyBoy. 04/15/24 12:22 AM
It's Friday: grown up humor for the weekend.
by NoFlyBoy. 04/12/24 01:41 PM
Copyright 1997-2016, SimHQ Inc. All Rights Reserved.

Powered by UBB.threads™ PHP Forum Software 7.6.0