Jump to content

Steel Battalion controller and win 7 64-Bit drivers


417 replies to this topic

#401 Buttsechuani

    Rookie

  • 6 posts

Posted 08 August 2016 - 10:09 PM

Here's the code I use for EvoChronLegacy to set my throttle lever as a maximum input adjustment for my pedal. My pedal has been set as Z axis

			//Gear Lever controlled RightPedal Z.
			int gearValue = controller.GearLever;
			if (gearValue == -2)
			{
				joystick.setAxis(1, controller.Scaled.RightPedal / 5, HID_USAGES.HID_USAGE_Z);
			}
			else if (gearValue == -1)
			{
				joystick.setAxis(1, controller.Scaled.RightPedal / 4, HID_USAGES.HID_USAGE_Z);
				controller.SetLEDState(ControllerLEDEnum.GearN, 4);
			}
			else if (gearValue == 1)
			{
				joystick.setAxis(1, controller.Scaled.RightPedal / 3, HID_USAGES.HID_USAGE_Z);
				controller.SetLEDState(ControllerLEDEnum.Gear1, 6);
				controller.SetLEDState(ControllerLEDEnum.GearN, 4);
			}
			else if (gearValue == 2)
			{
				joystick.setAxis(1, controller.Scaled.RightPedal / 2, HID_USAGES.HID_USAGE_Z);
				controller.SetLEDState(ControllerLEDEnum.Gear2, 8);
				controller.SetLEDState(ControllerLEDEnum.Gear1, 6);
				controller.SetLEDState(ControllerLEDEnum.GearN, 4);
			}
			else if (gearValue == 3)
			{
				joystick.setAxis(1, controller.Scaled.RightPedal / 2 + controller.Scaled.RightPedal / 5, HID_USAGES.HID_USAGE_Z);
				controller.SetLEDState(ControllerLEDEnum.Gear3, 10);
				controller.SetLEDState(ControllerLEDEnum.Gear2, 8);
				controller.SetLEDState(ControllerLEDEnum.Gear1, 6);
				controller.SetLEDState(ControllerLEDEnum.GearN, 4);
			}
			else if (gearValue == 4)
			{
				joystick.setAxis(1, controller.Scaled.RightPedal / 2 + controller.Scaled.RightPedal / 4, HID_USAGES.HID_USAGE_Z);
				controller.SetLEDState(ControllerLEDEnum.Gear4, 12);
				controller.SetLEDState(ControllerLEDEnum.Gear3, 10);
				controller.SetLEDState(ControllerLEDEnum.Gear2, 8);
				controller.SetLEDState(ControllerLEDEnum.Gear1, 6);
				controller.SetLEDState(ControllerLEDEnum.GearN, 4);
			}
			else if (gearValue == 5)
			{
				joystick.setAxis(1, controller.Scaled.RightPedal, HID_USAGES.HID_USAGE_Z);
				controller.SetLEDState(ControllerLEDEnum.Gear5, 15);
				controller.SetLEDState(ControllerLEDEnum.Gear4, 12);
				controller.SetLEDState(ControllerLEDEnum.Gear3, 10);
				controller.SetLEDState(ControllerLEDEnum.Gear2, 8);
				controller.SetLEDState(ControllerLEDEnum.Gear1, 6);
				controller.SetLEDState(ControllerLEDEnum.GearN, 4);
			}


The set led parts are optional but they are nice. Evochron Legacy also has a button that reverses throttle so I just us that instead of having R be a dedicated reverse. Combining this with what was previously mentioned would probably be the best. You'll also have to put the first two gear changes in an if statement so that you don't just get repeated key presses and you'll have to define a variable for the current gear value after the public int getRefreshRate() part. Something like gearValueSaved. You'll use this in your encapsulating if statement. If gearValueSaved != gearValue then send key down else send key up. I'm sure there are more elegant ways to do it using link statements and what not.

			//Gear Lever controlled RightPedal Z.
			int gearValue = controller.GearLever;
            if (gearValue == -2)
            {
                controller.sendKeyPress(SBC.Key.NumPad1); //this will send a constant press if -2 
            }
            else if (gearValue == -1 && gearValueSaved != gearValue) //this will only send key press if -1 & false
            {
                controller.sendKeyPress(SBC.Key.X);
            }            else if (gearValue == 1)
			{
				joystick.setAxis(1, controller.Scaled.RightPedal / 3, HID_USAGES.HID_USAGE_Z);
				controller.SetLEDState(ControllerLEDEnum.Gear1, 6);
				controller.SetLEDState(ControllerLEDEnum.GearN, 4);
			}
			else if (gearValue == 2)
			{
				joystick.setAxis(1, controller.Scaled.RightPedal / 2, HID_USAGES.HID_USAGE_Z);
				controller.SetLEDState(ControllerLEDEnum.Gear2, 8);
				controller.SetLEDState(ControllerLEDEnum.Gear1, 6);
				controller.SetLEDState(ControllerLEDEnum.GearN, 4);
			}
			else if (gearValue == 3)
			{
				joystick.setAxis(1, controller.Scaled.RightPedal / 2 + controller.Scaled.RightPedal / 5, HID_USAGES.HID_USAGE_Z);
				controller.SetLEDState(ControllerLEDEnum.Gear3, 10);
				controller.SetLEDState(ControllerLEDEnum.Gear2, 8);
				controller.SetLEDState(ControllerLEDEnum.Gear1, 6);
				controller.SetLEDState(ControllerLEDEnum.GearN, 4);
			}
			else if (gearValue == 4)
			{
				joystick.setAxis(1, controller.Scaled.RightPedal / 2 + controller.Scaled.RightPedal / 4, HID_USAGES.HID_USAGE_Z);
				controller.SetLEDState(ControllerLEDEnum.Gear4, 12);
				controller.SetLEDState(ControllerLEDEnum.Gear3, 10);
				controller.SetLEDState(ControllerLEDEnum.Gear2, 8);
				controller.SetLEDState(ControllerLEDEnum.Gear1, 6);
				controller.SetLEDState(ControllerLEDEnum.GearN, 4);
			}
			else if (gearValue == 5)
			{
				joystick.setAxis(1, controller.Scaled.RightPedal, HID_USAGES.HID_USAGE_Z);
				controller.SetLEDState(ControllerLEDEnum.Gear5, 15);
				controller.SetLEDState(ControllerLEDEnum.Gear4, 12);
				controller.SetLEDState(ControllerLEDEnum.Gear3, 10);
				controller.SetLEDState(ControllerLEDEnum.Gear2, 8);
				controller.SetLEDState(ControllerLEDEnum.Gear1, 6);
				controller.SetLEDState(ControllerLEDEnum.GearN, 4);
			}


You could then if you wanted "cruise control" wrap all of that in an if statement that's bound to a toggle switch and you'd have to come up with a way to save the axis position to a var outside of the gear if statements. You could also code something up so that a key press is sent only if an axis is greater than a specific number. This would be a sort of hybrid set up where once you release said pedal it would stop sending key presses and the game would stop increasing throttle. If you wanted to get real fance you could probably combine all of these things. Since the gear lever can set it so your pedal can only travel up to a certain point defined as a number on your axis you could try to code it so that once it reaches a point near the top of that specific gear setting it sends a keypress for set throttle to x percentage if you where to tie that to a gear state change then you would probably not need to code a cruise control toggle.

Edited by Buttsechuani, 08 August 2016 - 10:57 PM.


#402 LordC

    Rookie

  • 6 posts

Posted 09 August 2016 - 02:58 PM

Thank You for your answers and the kind words Golden Gun.

Most of the questions I did ask I already found the answer or workaround by my self, but I still think that its important to talk about them because of other users. Now I have one new question, but I will react also on few thing you have wrote.


NewQuestion:

View PostGolden Gun, on 03 August 2016 - 04:04 PM, said:

None of the inputs from the controller are hard bound. This includes all axes.
And what about joystick buttons? By default I like leave all buttons as joystick buttons, but when I need to add some extra functionality to some buttons as alternative bindings, I have problem when is alternative bindings activated Im not able to deactivate it

example:
lets say that I using these buttons:
ButtonEnum.CockpitHatch
ButtonEnum.Ignition
ButtonEnum.Start
as default jouystick buttons (Button5, Button6, Button7)

But when I create for them alternative binding...
for example if ToggleFuelFlowRate is ON than:
controller.AddButtonKeyLightMapping(ButtonEnum.CockpitHatch, false, 3, SBC.Key.A, true);
controller.AddButtonKeyLightMapping(ButtonEnum.Ignition, false, 3, SBC.Key.B, true);
controller.AddButtonKeyLightMapping(ButtonEnum.Start, false, 3, SBC.Key.C, true);

After starting the SBC driver these buttons work normally as Button5, Button6, Button7, when I switch ToggleFuelFlowRate ON, these buttons work as A,B,C ... but when I switch ToggleFuelFlowRate OFF, these buttons still keeps working as A,B,C and not like Button5, Button6, Button7
only working workaround I found is to set all buttons to keys for both default and alterntive keybindings...
I would like to do somethnig like this:
controller.AddButtonKeyLightMapping(ButtonEnum.CockpitHatch, false, 3, SBC.Key.Button5, true);
controller.AddButtonKeyLightMapping(ButtonEnum.Ignition, false, 3, SBC.Key.Button6, true);
controller.AddButtonKeyLightMapping(ButtonEnum.Start, false, 3, SBC.Key.Button7, true);
But I dont know how, all my attemps so far failed ... is it possible somehow?



About "SolExodus.cs" file & older versions of SBC64...
Yes I am aware of the fact that these files are probably already obsolete, etc, but I still like to get my hands on them... because ... well because I am curious and I would like to look into them... and even when "SolExodus.cs" is obsolete, maybe one can learn from it something (for example that there is nothing more to learn from it nowdays)... does it make sense? So if you dont mind I would like to still look on to these obsolete files... I can sent you PM with access to my FTP if you want... or you can upload it anywhere you want Posted Image



32vs39 buttons:

View PostGolden Gun, on 03 August 2016 - 04:04 PM, said:

The latest version of VJoy can use up to 128 joystick buttons so there is no need to pick and choose. Just make sure when you setup VJoy you increase the button count as well as the other needed configs. You can doublecheck this change in the Windows Joystick Config. program.

Yes we have to change button count to 39 in vJoyConf.exe and than in the vJoy Monitor all 39 buttons works, problem is that all 39 buttons works as joystick buttons only in vJoy Monitor and not in games or windows 8.1 calibration. "Set up USB game controllers" configuration still shows only 32 buttons. Or do I miss something?



GearLever windows Calibration:

View PostGolden Gun, on 03 August 2016 - 04:04 PM, said:

.
The gear shift, as it stands in the original code, has it mapped to SL1. But there seems to be a very simple way to use its output. Once you activate SBC, go to the windows joystick config. and start to calibrate.

In theory its true, but in reality its useless because I was NEVER able to properly calibrate it, the GearLever slider tends to hit N value between higher gears when gear is changed... and thanks to that I wasnt able to properly calibrate it (not once from 20 tries!) thats why I used the preset axis values in my answer to Q3.

#403 LordC

    Rookie

  • 6 posts

Posted 09 August 2016 - 03:04 PM

Very nice idea for GearLever and also for SetLEDState for gears I like it a lot, thanks again for sharing Buttsechuani Posted Image

Edited by LordC, 09 August 2016 - 03:15 PM.


#404 Buttsechuani

    Rookie

  • 6 posts

Posted 09 August 2016 - 03:44 PM

I think you'll have to wrap them in if statements based on a true false statement. Place this right before main loop

//bool array to save toggle states used in mainloop
bool[] togglesState = new bool[5];


Place this in mainloop prior to toggle stuffs

/*Bool Array for every toggle switch. This will be used to compare a state.
This will be used as a comparator? to determine whether a keystroke is sent
based on state change
*/
bool[] toggles = new bool[5];
toggles[0] = controller.GetButtonState(34);
toggles[1] = controller.GetButtonState(35);
toggles[2] = controller.GetButtonState(36);
toggles[3] = controller.GetButtonState(37);
toggles[4] = controller.GetButtonState(38);


Some example if statements the first one would change the key mappings anytime the states don't match. The second would change it to a set mapping on a specific atate

if (toggles[0] == togglesState[0])
{
I'm a list of controller mappings;
}
else if (toggles[0] != togglesState[0])
{
I'm the alternate list;
}
if (toggles[1] == true)
{
I'm a list of controller mappings for the up position;
}
else if (toggles[1] != true)
{
I'm the list for the off position;
}

/*These will save the toggle state changes to an array outside the mainloop
* for comparison
*/

togglesState[0] = toggles[0];
togglesState[1] = toggles[1];
togglesState[2] = toggles[2];
togglesState[3] = toggles[3];
togglesState[4] = toggles[4];
Something like that might work

#405 Khobai

    Member

  • PipPipPipPipPipPipPipPipPipPipPipPipPip
  • Elite Founder
  • Elite Founder
  • 23,364 posts
  • LocationStranded on Isla Nublar

Posted 09 August 2016 - 04:47 PM

all he needs now is a steering wheel

#406 Golden Gun

    Member

  • PipPipPip
  • Legendary Founder
  • Legendary Founder
  • 87 posts
  • LocationIdaho

Posted 09 August 2016 - 04:48 PM

View PostLordC, on 09 August 2016 - 02:58 PM, said:


NewQuestion:
And what about joystick buttons? By default I like leave all buttons as joystick buttons, but when I need to add some extra functionality to some buttons as alternative bindings, I have problem when is alternative bindings activated Im not able to deactivate it

example:
lets say that I using these buttons:
ButtonEnum.CockpitHatch
ButtonEnum.Ignition
ButtonEnum.Start
as default jouystick buttons (Button5, Button6, Button7)

But when I create for them alternative binding...
for example if ToggleFuelFlowRate is ON than:
controller.AddButtonKeyLightMapping(ButtonEnum.CockpitHatch, false, 3, SBC.Key.A, true);
controller.AddButtonKeyLightMapping(ButtonEnum.Ignition, false, 3, SBC.Key.B, true);
controller.AddButtonKeyLightMapping(ButtonEnum.Start, false, 3, SBC.Key.C, true);

After starting the SBC driver these buttons work normally as Button5, Button6, Button7, when I switch ToggleFuelFlowRate ON, these buttons work as A,B,C ... but when I switch ToggleFuelFlowRate OFF, these buttons still keeps working as A,B,C and not like Button5, Button6, Button7
only working workaround I found is to set all buttons to keys for both default and alterntive keybindings...
I would like to do somethnig like this:
controller.AddButtonKeyLightMapping(ButtonEnum.CockpitHatch, false, 3, SBC.Key.Button5, true);
controller.AddButtonKeyLightMapping(ButtonEnum.Ignition, false, 3, SBC.Key.Button6, true);
controller.AddButtonKeyLightMapping(ButtonEnum.Start, false, 3, SBC.Key.Button7, true);
But I dont know how, all my attemps so far failed ... is it possible somehow?


good question and i think LordC's latest post covers all of that. TBH, I couldn't have answered it any better...

Quote

About "SolExodus.cs" file & older versions of SBC64...
Yes I am aware of the fact that these files are probably already obsolete, etc, but I still like to get my hands on them... because ... well because I am curious and I would like to look into them... and even when "SolExodus.cs" is obsolete, maybe one can learn from it something (for example that there is nothing more to learn from it nowdays)... does it make sense? So if you dont mind I would like to still look on to these obsolete files... I can sent you PM with access to my FTP if you want... or you can upload it anywhere you want Posted Image


No problem, I completely understand. I'll root around in my archives and see how many I can find.

Quote

32vs39 buttons:

Yes we have to change button count to 39 in vJoyConf.exe and than in the vJoy Monitor all 39 buttons works, problem is that all 39 buttons works as joystick buttons only in vJoy Monitor and not in games or windows 8.1 calibration. "Set up USB game controllers" configuration still shows only 32 buttons. Or do I miss something?


I've never had a problem, but I am using Windows 10, not 8.1. I DID find the following thread on the Vjoy sight that might help you.

http://vjoystick.sou...ve-buttons-axis

Quote

GearLever windows Calibration:

In theory its true, but in reality its useless because I was NEVER able to properly calibrate it, the GearLever slider tends to hit N value between higher gears when gear is changed... and thanks to that I wasnt able to properly calibrate it (not once from 20 tries!) thats why I used the preset axis values in my answer to Q3.


Ouch! you might be experiencing something that most SB controller owner's don't know about. The contact mechanism for the slider can wear out and also "smear" contact points. This is the most common reason why you couldn't calibrate.

Here is the fix most people find the most useful:

http://www.bigmech.c.../gearleaver.htm

While doing this fix, you can also see how worn down the traces are on the "left side"(the pads for each state) and see if some cleaning and/or resurfacing will get you back up and running! Posted Image

GOOD LUCK!

#407 Buttsechuani

    Rookie

  • 6 posts

Posted 09 August 2016 - 07:18 PM

I give you SolExodus

using SBC;
using System;
namespace SBC {
public class DynamicClass
{
SteelBattalionController controller;//the object we actually use to get information from the Steel Batallion Controller
//this is where we define how many joysticks the program is expecting to update, for now we are only using one joystick
//to keep things simple.  Since Windows only supports 8 axis joysticks natively, if you wanted to support all 10 axes
//on the steel batallion you would have to spread it out over 2 joysticks.  I can't think of a reason you would want
//to do that though.  Its easier to mix and match as you need, and you can usually combine the middle and right pedals.
//as I do here.  In case you aren't familiar with C# anything following a // or between /* */ is commented out and
//does not affect actual code
const int numJoysticks = 1;
const int defaultAxisValue = 100;//just a default value to send back to the program if you somehow fail to provide
		 //a return value in the switch statement
//there are lots of ways to do this, enumeration would come to mind, but I"m keeping it simple for now.
//These are equivalent to the names of the axes you would see when calibrating the joystick
const int x_axis = 0;
const int y_axis = 1;
const int z_axis = 2;
const int z_rotation = 3;
const int slider = 4;
const int x_rotation = 5;
const int y_rotation = 6;
const int dial = 7;
int pedalTriggerLevel = 50;//used in special handlign of left pedal, the amount we have to press to get it to trigger the button
bool jumpPressed = false;//boolean used to store when the jump pedal was pressed.
VirtualKeyCode jumpKey = VirtualKeyCode.VK_J;//this is used in the extraCode section and is the key we want pressed when
		   //the left pedal gets depressed passed the left pedal trigger level
//This function must be defined
public int getNumJoysticks()
{
	 return numJoysticks;
}
 
//Here is a list of all buttons available for mapping
/*
  RightJoyMainWeapon,
  RightJoyFire,
  RightJoyLockOn,
		Eject,
  CockpitHatch,
  Ignition,
  Start,
  MultiMonOpenClose,
  MultiMonMapZoomInOut,
  MultiMonModeSelect,
  MultiMonSubMonitor,
  MainMonZoomIn,
  MainMonZoomOut,
		FunctionFSS,
		FunctionManipulator,
		FunctionLineColorChange,
  Washing,
  Extinguisher,
  Chaff,
		FunctionTankDetach,
		FunctionOverride,
		FunctionNightScope,
		FunctionF1,
		FunctionF2,
		FunctionF3,
  WeaponConMain,
  WeaponConSub,
  WeaponConMagazine,
  Comm1,
  Comm2,
  Comm3,
  Comm4,
  Comm5,
  LeftJoySightChange,
  ToggleFilterControl,
  ToggleOxygenSupply,
  ToggleFuelFlowRate,
  ToggleBufferMaterial,
  ToggleVTLocation,
  TunerDialStateChange,
  GearLeverStateChange
*/
//this function must be defined and is called only once by the program.  This is where most people will do their
//modifications specific to a game
	public void Initialize()
	{
  controller = new SteelBattalionController();//We have to first initialize the controller
  controller.Init(50);//50 is refresh rate in milliseconds
  //Now add all the keymapping you desire
  //AddButtonKeyMapping requires a Button, a keycode, and whether or not to send separate keydown/ key up presses
		controller.AddButtonKeyMapping(ButtonEnum.RightJoyMainWeapon,					   VirtualKeyCode.VK_Q,						false);//false is equivalent to quickly hitting button once and releasing
		controller.AddButtonKeyMapping(ButtonEnum.RightJoyFire,							 VirtualKeyCode.VK_W,						true);//true is equal to holding down a key
		controller.AddButtonKeyMapping(ButtonEnum.RightJoyLockOn,						   VirtualKeyCode.VK_E,						false);
		controller.AddButtonKeyLightMapping(ButtonEnum.Eject,				   true, 15,   VirtualKeyCode.VK_R,						true);
		controller.AddButtonKeyLightMapping(ButtonEnum.CockpitHatch,			true, 3,	VirtualKeyCode.VK_T,						true);
		controller.AddButtonKeyLightMapping(ButtonEnum.Ignition,				true, 15,   VirtualKeyCode.VK_Y,						true);
		controller.AddButtonKeyLightMapping(ButtonEnum.Start,				   true, 15,   VirtualKeyCode.VK_U,						true);
		controller.AddButtonKeyLightMapping(ButtonEnum.MultiMonOpenClose,	   true, 3,	VirtualKeyCode.VK_I,						true);
		controller.AddButtonKeyLightMapping(ButtonEnum.MultiMonMapZoomInOut,	true, 3,	VirtualKeyCode.VK_O,						true);
		controller.AddButtonKeyLightMapping(ButtonEnum.MultiMonModeSelect,	  true, 3,	VirtualKeyCode.VK_P,						true);
		controller.AddButtonKeyLightMapping(ButtonEnum.MultiMonSubMonitor,	  true, 7,	VirtualKeyCode.VK_A,						true);
		controller.AddButtonKeyLightMapping(ButtonEnum.MainMonZoomIn,		   true, 3,	VirtualKeyCode.VK_S,						true);
		controller.AddButtonKeyLightMapping(ButtonEnum.MainMonZoomOut,		  true, 3,	VirtualKeyCode.VK_D,						true);
		controller.AddButtonKeyLightMapping(ButtonEnum.FunctionFSS,			 true, 7,	VirtualKeyCode.VK_F,						true);
		controller.AddButtonKeyLightMapping(ButtonEnum.FunctionManipulator,	 true, 3,	VirtualKeyCode.VK_G,						true);
		controller.AddButtonKeyLightMapping(ButtonEnum.FunctionLineColorChange, true, 7,	VirtualKeyCode.VK_H,						true);
		controller.AddButtonKeyLightMapping(ButtonEnum.Washing,				 true, 3,	VirtualKeyCode.VK_J,						true);
		controller.AddButtonKeyLightMapping(ButtonEnum.Extinguisher,			true, 3,	VirtualKeyCode.VK_K,						true);
		controller.AddButtonKeyLightMapping(ButtonEnum.Chaff,				   true, 3,	VirtualKeyCode.VK_L,						true);
		controller.AddButtonKeyLightMapping(ButtonEnum.FunctionTankDetach,	  true, 3,	VirtualKeyCode.VK_Z,						true);
		controller.AddButtonKeyLightMapping(ButtonEnum.FunctionOverride,		true, 3,	VirtualKeyCode.VK_X,						true);
		controller.AddButtonKeyLightMapping(ButtonEnum.FunctionNightScope,	  false, 7,   VirtualKeyCode.VK_C,						true);
		controller.AddButtonKeyLightMapping(ButtonEnum.FunctionF1,			  true, 3,	VirtualKeyCode.VK_V,						true);
		controller.AddButtonKeyLightMapping(ButtonEnum.FunctionF2,			  true, 3,	VirtualKeyCode.VK_B,						true);
		controller.AddButtonKeyLightMapping(ButtonEnum.FunctionF3,			  true, 3,	VirtualKeyCode.VK_N,						true);
		controller.AddButtonKeyLightMapping(ButtonEnum.WeaponConMain,		   true, 3,	VirtualKeyCode.VK_M,						true);
		controller.AddButtonKeyLightMapping(ButtonEnum.WeaponConSub,			true, 3,	VirtualKeyCode.OEM_4,					   true);
		controller.AddButtonKeyLightMapping(ButtonEnum.WeaponConMagazine,	   true, 7,	VirtualKeyCode.OEM_6,					   true);
}
 
//we only want to use keymapping or buttonmapping for now, no reason you can't do both, but it might end up being confusing having
	//a button that both presses a joystick button and a key
	public bool useButtons()
	{
		return false;//using keymapping for now
	}
 
// Function must be defined, only important if useButtons returns True
	// return number of buttons per joystick, program will then ask for values for each button (only using one joystick right now)
	public int getNumButtons(int joyNum)
	{
		return 13;
	}
//Function must be defined, to keep things simple, leave this at 8
	//return number of axis per joystick, program will then ask for values for each axis  (only using one joystick right now)
	public int getNumAxis(int joyNum)
	{
		return 8;//8 happens to be the maximum number of axes that PPJoy/Windows currently supports
	}
 
//HERE is where we assign axis, each case corresponds to the name of an axis you would see under
//the usb game controller calibration
//only axis not shown here is the tuner dial axis, which can be accessed using
//  controller.TunerDial
 
//
 
 
	public int getAxisValue(int joyNum, int axisNum)
	{
		//technically we should be accounting the joystickNumber as well, but only dealing with one joystick for the moment
		//we should handle all cases from 0 to getNumAxis()
		switch (axisNum)
		{
			//case 0 means we asked for what is the value to axis number 0
			case x_axis:
				return controller.AimingX;//Corresponds to the "Aiming Lever" joystick on the right.  X Axis value.
			case y_axis:
					return controller.AimingY;//Corresponds to the "Aiming Lever" joystick on the right.  Y Axis value.
			case z_axis:
				return -1*(controller.RightPedal - controller.MiddlePedal);//throttle, combining middle and right pedals
			case z_rotation:
					return controller.RotationLever;//Corresponds to the "Rotation Lever" joystick on the left.
			case slider:
				return controller.SightChangeX;//Corresponds to the "Sight Change" analog stick on the "Rotation Lever" joystick.  X Axis value.
			case x_rotation:
				return controller.SightChangeY;//Corresponds to the "Sight Change" analog stick on the "Rotation Lever" joystick.  Y Axis value.
			case y_rotation:
				return controller.LeftPedal;
			case dial:
				return controller.GearLever;
		}
		return defaultAxisValue;//we always have to return something
	}
  
 
	//this function has to be here even if we do not use it
	public bool getButtonValue(int joyNum, int buttonNumber)
	{
		//technically we should be accounting the joystickNumber as well, but only dealing with one joystick for the moment
		return controller.GetButtonState(buttonNumber);
	}
	//this function has to be here even if we do not use it
	public void extraCode()//place any extra code you want executed during the loop here.
	{
  if(controller.LeftPedal > pedalTriggerLevel)
  {
	  //take care of the button logic separately, to be less confusing
	  if(!jumpPressed)//if not currently holding down jump key
	  {
	   controller.sendKeyDown(jumpKey);
	   jumpPressed = true;
	  }
  }
  else//jump button was pressed
  {
   if(jumpPressed)
   {
	controller.sendKeyUp(jumpKey);
	jumpPressed = false;
   }
  }
	}
}
}


#408 Golden Gun

    Member

  • PipPipPip
  • Legendary Founder
  • Legendary Founder
  • 87 posts
  • LocationIdaho

Posted 09 August 2016 - 07:37 PM

Meh, I've seen better.... :D

#409 LordC

    Rookie

  • 6 posts

Posted 09 August 2016 - 10:28 PM

I think You misunderstand what I was asking for...
Yes I understand this:

View PostButtsechuani, on 09 August 2016 - 03:44 PM, said:

if (toggles[0] == togglesState[0])
{
I'm a list of controller mappings; // <= I HAVE PROBLEM WITH THIS!
}
else if (toggles[0] != togglesState[0])
{
I'm the alternate list;
}
if (toggles[1] == true)
{
I'm a list of controller mappings for the up position;
}
else if (toggles[1] != true)
{
I'm the list for the off position; // <= I HAVE PROBLEM WITH THIS!
}
...infact I use similar approach, but the question is how to define list of controller mappings for buttons to be just joystick buttons? Not the key Storkes, I only know how to bind a key to a button, but how to bind a joystick button (which is by default in beginning already binded to it)?

I was thinking about something like this:
controller.AddButtonKeyLightMapping(ButtonEnum.CockpitHatch, false, 3, SBC.Key.Button5, true);
or this:
controller.AddButtonKeyLightMapping(ButtonEnum.CockpitHatch, false, 3, SBC.Button.5, true);
but somethnig like this does NOT work

So the question is "How to make a list of controller mappings for buttons to be a joystick buttons"?!?

Edited by LordC, 09 August 2016 - 10:51 PM.


#410 Golden Gun

    Member

  • PipPipPip
  • Legendary Founder
  • Legendary Founder
  • 87 posts
  • LocationIdaho

Posted 12 August 2016 - 10:59 PM

I've been doing a little testing of my own and I've come to a conclusion. To make what you want work, you would have to do it in one of two ways.

1) map both sets of the Toggle Switch bindings to keyboard keys (not using joystick buttons at all).

2) find a way to null the bindings

Basically, the joystick buttons remain joystick buttons until they are mapped to a keystroke but once they are, they remain in that state until issue another command. In theory, to do what you want you'll need to overwrite the key binding with another keystroke or find a way to erase the current binding, which sounds like a null command or something.

PS- for me, If I map a key to the keyboard, it is also still its button. Example, If I mapped the main weapon button to "P" on the keyboard, it will press the button "P" AS WELL AS press Joystick button "1".

Because of this, I would just assign ALL you buttons to keyboard presses, then you have positive control over what each one is doing.

Edited by Golden Gun, 12 August 2016 - 11:12 PM.


#411 Buttsechuani

    Rookie

  • 6 posts

Posted 15 August 2016 - 12:19 AM

I was reading through the actual driver. You can download a snapshot of the current project from sourceforge if you make an account. I'm not sure if that's what was desired or not. It seems that the buttons are enumerated the way they are because that's the order they are presented to the usb interface. There's also a little note in the code that states not to reorder them. I'm assuming something further could be done with an alternate enumeration or button mask of some sort. That sort of stuff is out of my league entirely though.

#412 Golden Gun

    Member

  • PipPipPip
  • Legendary Founder
  • Legendary Founder
  • 87 posts
  • LocationIdaho

Posted 15 August 2016 - 07:23 AM

Ah, dang. Sorry Dude. I was hoping we were on to something to help you along. I hope mapping to keyboard tests will do the same thing for you, even though not in the way you'd like.

Best of Luck!

#413 HackNFly

    Member

  • PipPipPipPipPip
  • 130 posts

Posted 15 August 2016 - 08:52 AM

View PostLordC, on 09 August 2016 - 10:28 PM, said:

I think You misunderstand what I was asking for...
Yes I understand this:
...infact I use similar approach, but the question is how to define list of controller mappings for buttons to be just joystick buttons? Not the key Storkes, I only know how to bind a key to a button, but how to bind a joystick button (which is by default in beginning already binded to it)?

I was thinking about something like this:
controller.AddButtonKeyLightMapping(ButtonEnum.CockpitHatch, false, 3, SBC.Key.Button5, true);
or this:
controller.AddButtonKeyLightMapping(ButtonEnum.CockpitHatch, false, 3, SBC.Button.5, true);
but somethnig like this does NOT work

So the question is "How to make a list of controller mappings for buttons to be a joystick buttons"?!?


You may already know this, but I figure I'd chime in with this part. Dealing with actual joystick buttons is done through one part in code specifically:
            for (int i = 1; i <= vJoyButtons; i++)
            {
                joystick.setButton((bool)controller.GetButtonState(i - 1), (uint)1, (char)(i - 1));
            }


The i-1 is for the typical programming start with zero vs logical button 1.

joystick.setButton is modeled after the function in vJoy, where its


/// <param name="buttonNum">Button number, 0-31</param>
        /// <param name="value">True for button down, false for button up</param>
        public void setButton(bool value, uint rID, int buttonNum)


rId always equals 1, although it really represents the vJoy joystick #. If you had multiple joysticks set up you could modify that there.

#414 HackNFly

    Member

  • PipPipPipPipPip
  • 130 posts

Posted 15 August 2016 - 09:04 AM

View PostGolden Gun, on 12 August 2016 - 10:59 PM, said:

I've been doing a little testing of my own and I've come to a conclusion. To make what you want work, you would have to do it in one of two ways.

1) map both sets of the Toggle Switch bindings to keyboard keys (not using joystick buttons at all).

2) find a way to null the bindings

Basically, the joystick buttons remain joystick buttons until they are mapped to a keystroke but once they are, they remain in that state until issue another command. In theory, to do what you want you'll need to overwrite the key binding with another keystroke or find a way to erase the current binding, which sounds like a null command or something.

PS- for me, If I map a key to the keyboard, it is also still its button. Example, If I mapped the main weapon button to "P" on the keyboard, it will press the button "P" AS WELL AS press Joystick button "1".

Because of this, I would just assign ALL you buttons to keyboard presses, then you have positive control over what each one is doing.



If you want to remove a binding use the RemoveButtonKeyMapping function

 public void RemoveButtonKeyMapping(ButtonEnum button)


It's located in SteelBatallionController.cs
If you wanted to remove all bindings you could define a function inside your cs file such as:

 
public void removeAllBindings()
{
            //set all buttons by default to light up only when you press them down
 
            for (int i = 1; i <= 39; i++)
            {
                    controller.RemoveButtonKeyMapping((ButtonEnum)(i - 1));
            }
}


I don't have my controller connected, nor have an easy way to test it at the moment, but I'm pretty sure that will work. If you can test it I'll help with any bugs.

#415 Irishtoker

    Member

  • PipPipPipPipPip
  • FP Veteran - Beta 2
  • FP Veteran - Beta 2
  • 102 posts
  • LocationIn a hole at the bottom of the Nexus.

Posted 20 February 2017 - 08:06 AM

Call me lazy, but can anyone tell me if this indeed will work? I'm considering buying a SB console/controller from a friend expressly for playing MWO.

Thanks and Happy Hunting.

#416 Golden Gun

    Member

  • PipPipPip
  • Legendary Founder
  • Legendary Founder
  • 87 posts
  • LocationIdaho

Posted 20 February 2017 - 10:26 AM

In a word, YES!

That being said, it is NOT a plug and play driver. To get it to do what you want, you will need to learn some simple coding to program the wrapper for the driver HackNFly made.

Also, there never was a complete fix for using this in MWO. The biggest issue (and only issue IMHO), was using the aiming lever (Right Joystick) for controlling the torso twist and arm movement.

The issue was that there is no direct way to set the inputs to work more like a mouse. "Right out of the box" it will move the targeting reticle around, but it is in a way that makes it hard to control.

EXAMPLE: Right now, if you move the joystick forward half way, the targeting reticle will continuously move up the screen (down if you have that axis reversed) at a medium speed until you either center the joystick or it reaches its maximum limit. When you center the joystick, the reticle will stop where ever it is on the screen.

The ideal method would be for the reticle to move to certain distance and then stop, speed being determined by how fast you move the joystick from position to position.

EXAMPLE: With this type of input, we move the joystick forward half way like before, but this time the reticle moves up (or down) half way between the center and its maximum limit, the reticle's speed being determined by how fast you move the joy stick from center to half way forward. When you center the joystick, the reticle will all go back to center.

This may not seem like a big deal, but for most people who want to specifically use this Joystick setup for MWO, this is a deal breaker. It is really REALLY hard to keep the reticle centered, IE not moving in one direction or another, since there is no center spring on the joystick.

This issue is not really the driver's fault, as it is MWO's input architecture that is not geared to translate joystick inputs properly, again IMHO. If they would add this support, ANY joystick would rock in MWO.

NOW! With all that being said. If you plan on using this AWESOME joystick for flight sims or games that DO have the support mentioned above, you would be hard pressed to find something better for the price. Again, you'll set the inputs (or find someone else's .CS file that has already been created) to get the most out of it, but it is SOOOOOOOOOOO worth it!

#417 Buttsechuani

    Rookie

  • 6 posts

Posted 02 February 2018 - 10:56 PM

I haven't posted here in a while but I figured I'd post again as I've been putzing about trying to get this to work in Elite Dangerous. The original elite dangerous file had a cool feature which would read toggle states and reassign keyboard presses to things like the left hat or a button on the right joystick. I've managed to duplicate the function and I believe improve on it some as the original required two toggle switches for full UI control. I've bound them all to one toggle switch so that the hat will send WASD keyboard presses and "lock on" button will send a space if the VT Location/Measurement switch is in the up position. I'm assuming someone more clever could take my hat switch reinvention and turn it into a moue x and y remap. I didn't bother with the original Elite dangerous led controller toggle as it wasn't something that interested me. Below is my current Elite dangerous code. Perhaps it can be made use of in this game.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SBC
{
	public class DynamicClass
	{
		String debugString = "";
		SteelBattalionController controller;
		vJoy joystick;
		int vJoyButtons = 39;
		bool acquired;
		const int refreshRate = 50;
		public void Initialize()
		{
			int baseLineIntensity = 6;
			int emergencyLightIntensity = 15;
			controller = new SteelBattalionController();
			controller.Init(50);
			for (int i = 4; i < 4 + 30; i++)
			{
				if (i != (int)ButtonEnum.Eject)
					controller.AddButtonLightMapping((ButtonEnum)(i - 1), (ControllerLEDEnum)(i), true, baseLineIntensity);
			}
			joystick = new vJoy();
			acquired = joystick.acquireVJD(1);
			joystick.resetAll();
		}
		public int getRefreshRate()
		{
			return refreshRate;
		}
		// Parts of this are used to define the rotation dial as if it where analog axis it also sets the gear lever as a maximum input adjustment for the right pedal
		//sets neutral position SL1 and Z
		int defaultValue = 16384;
		//1/15 of total Axis Value
		int stepValue = 2184;
		//tunerValue * stepValue set inside warp speed tuner dial loop
		int tunerMultiplier = 0;
		//bool array to save toggle and lockon states used in mainloop
		bool[] lockonState = new bool[1];
  bool[] togglesState = new bool[5];
 
 
		public void mainLoop()
		{
			//These are for the right joystick
			joystick.setAxis(1, controller.Scaled.AimingX, HID_USAGES.HID_USAGE_X);
			joystick.setAxis(1, controller.Scaled.AimingY, HID_USAGES.HID_USAGE_Y);
			//This is for the left joystick
			joystick.setAxis(1, controller.Scaled.RotationLever, HID_USAGES.HID_USAGE_RZ);
			//These are for the left thumbstick
			joystick.setAxis(1, controller.Scaled.SightChangeX, HID_USAGES.HID_USAGE_RX);
			joystick.setAxis(1, controller.Scaled.SightChangeY, HID_USAGES.HID_USAGE_RY);
			//Left and Middle Pedal join
			joystick.setAxis(1, defaultValue - (controller.Scaled.LeftPedal - controller.Scaled.MiddlePedal), HID_USAGES.HID_USAGE_SL0);
			for (int i = 1; i <= vJoyButtons; i++)
			{
				joystick.setButton((bool)controller.GetButtonState(i - 1), (uint)1, (char)(i - 1));
			}
			//Sends a continuous key while sightchange button is pressed;
			if (controller.GetButtonState(33) == true)
			{
				controller.sendKeyDown(SBC.Key.NumPad0);
			}
   else if (controller.GetButtonState(33) != true)
			{
				controller.sendKeyUp(SBC.Key.NumPad0);
			}
			if (controller.GetButtonState(32) == true)
			{
				controller.sendKeyDown(SBC.Key.NumPad6);
			}
   else if (controller.GetButtonState(32) != true)
			{
				controller.sendKeyUp(SBC.Key.NumPad6);
			}
			/*Bool Array for every toggle switch and the lockon button. This will be used to compare a state.
			  This will be used as a comparator? to determine whether a keystroke is sent
			  based on state change
			*/
   bool[] lockon = new bool [1];
   lockon[0] = controller.GetButtonState(2);
			bool[] toggles = new bool[5];
			toggles[0] = controller.GetButtonState(34);
			toggles[1] = controller.GetButtonState(35);
			toggles[2] = controller.GetButtonState(36);
			toggles[3] = controller.GetButtonState(37);
			toggles[4] = controller.GetButtonState(38);
			/*These are the if statements for defining what key to send
			  on state change.*/
			if (toggles[0] == togglesState[0])
			{
				controller.sendKeyUp(SBC.Key.NumPad1);
			}
			else if (toggles[0] != togglesState[0])
			{
				controller.sendKeyDown(SBC.Key.NumPad1);
			}
			if (toggles[1] == true)
			{
				controller.sendKeyDown(SBC.Key.NumPad2);
			}
			else if (toggles[1] != true)
			{
				controller.sendKeyUp(SBC.Key.NumPad2);
			}
			if (toggles[2] == true)
			{
				controller.sendKeyDown(SBC.Key.NumPad3);
			}
			else if (toggles[2] != true)
			{
				controller.sendKeyUp(SBC.Key.NumPad3);
			}
			if (toggles[3] == true)
			{
				controller.sendKeyDown(SBC.Key.NumPad4);
			}
			else if (toggles[3] != true)
			{
				controller.sendKeyUp(SBC.Key.NumPad4);
			}
   /*VT Toggle will change the function of the Lockon button and hat
   when in the up position
   */
			if (toggles[4] == true)
			{
	if (controller.SightChangeX != 0)
	{
	 //Sends a key stroke after certain point is reached
	 if (controller.SightChangeX < -380)
	 {
	  controller.sendKeyDown(SBC.Key.A);
	 }
	 //This releases the above key
	 else if (controller.SightChangeX >= -380)
	 {
	  controller.sendKeyUp(SBC.Key.A);
	 }
	 //Sends a key stroke after certain point is reached
	 if (controller.SightChangeX > 380)
	 {
	  controller.sendKeyDown(SBC.Key.D);
	 }
	 //This releases the above key
	 else if (controller.SightChangeX <= 380)
	 {
	  controller.sendKeyUp(SBC.Key.D);
	 }
	}
	if (controller.SightChangeY != 0)
	{
	 if (controller.SightChangeY < -380)
	 {
	  controller.sendKeyDown(SBC.Key.W);
	 }
	 else if (controller.SightChangeY >= -380)
	  {
	   controller.sendKeyUp(SBC.Key.W);
	  }
	 if (controller.SightChangeY > 380)
	 {
	  controller.sendKeyDown(SBC.Key.S);
	 }
	 else if (controller.SightChangeY <= 380)
	 {
	  controller.sendKeyUp(SBC.Key.S);
	 }
	
	}
   /*Sends a spacebar key press on pressing of the lockon button
   only if the toggle is in the up position
   */  
   if (lockon[0] != true)
	{
	 controller.sendKeyUp(SBC.Key.Space);
	}
   else if (lockon[0] == true)
	{
	 controller.sendKeyDown(SBC.Key.Space);
	}
   }
			/*These will save the lock on button state changes to an array outside the mainloop
			* for comparison
			*/
   lockonState[0] = lockon[0];
   /*These will save the toggle state changes to an array outside the mainloop
			* for comparison
			*/
			togglesState[0] = toggles[0];
			togglesState[1] = toggles[1];
			togglesState[2] = toggles[2];
			togglesState[3] = toggles[3];
			togglesState[4] = toggles[4];
			// Tuner controls SL1 Axis
			int tunerValue = controller.TunerDial;
			joystick.setAxis(1, tunerValue * stepValue, HID_USAGES.HID_USAGE_SL1);
			//Gear Lever controlled RightPedal Z.
			int gearValue = controller.GearLever;
			if (gearValue == -2)
			{
				joystick.setAxis(1, controller.Scaled.RightPedal / 5, HID_USAGES.HID_USAGE_Z);
			}
			else if (gearValue == -1)
			{
				joystick.setAxis(1, controller.Scaled.RightPedal / 4, HID_USAGES.HID_USAGE_Z);
				controller.SetLEDState(ControllerLEDEnum.GearN, 4);
			}
			else if (gearValue == 1)
			{
				joystick.setAxis(1, controller.Scaled.RightPedal / 3, HID_USAGES.HID_USAGE_Z);
				controller.SetLEDState(ControllerLEDEnum.Gear1, 6);
				controller.SetLEDState(ControllerLEDEnum.GearN, 4);
			}
			else if (gearValue == 2)
			{
				joystick.setAxis(1, controller.Scaled.RightPedal / 2, HID_USAGES.HID_USAGE_Z);
				controller.SetLEDState(ControllerLEDEnum.Gear2, 8);
				controller.SetLEDState(ControllerLEDEnum.Gear1, 6);
				controller.SetLEDState(ControllerLEDEnum.GearN, 4);
			}
			else if (gearValue == 3)
			{
				joystick.setAxis(1, controller.Scaled.RightPedal / 2 + controller.Scaled.RightPedal / 5, HID_USAGES.HID_USAGE_Z);
				controller.SetLEDState(ControllerLEDEnum.Gear3, 10);
				controller.SetLEDState(ControllerLEDEnum.Gear2, 8);
				controller.SetLEDState(ControllerLEDEnum.Gear1, 6);
				controller.SetLEDState(ControllerLEDEnum.GearN, 4);
			}
			else if (gearValue == 4)
			{
				joystick.setAxis(1, controller.Scaled.RightPedal / 2 + controller.Scaled.RightPedal / 4, HID_USAGES.HID_USAGE_Z);
				controller.SetLEDState(ControllerLEDEnum.Gear4, 12);
				controller.SetLEDState(ControllerLEDEnum.Gear3, 10);
				controller.SetLEDState(ControllerLEDEnum.Gear2, 8);
				controller.SetLEDState(ControllerLEDEnum.Gear1, 6);
				controller.SetLEDState(ControllerLEDEnum.GearN, 4);
			}
			else if (gearValue == 5)
			{
				joystick.setAxis(1, controller.Scaled.RightPedal, HID_USAGES.HID_USAGE_Z);
				controller.SetLEDState(ControllerLEDEnum.Gear5, 15);
				controller.SetLEDState(ControllerLEDEnum.Gear4, 12);
				controller.SetLEDState(ControllerLEDEnum.Gear3, 10);
				controller.SetLEDState(ControllerLEDEnum.Gear2, 8);
				controller.SetLEDState(ControllerLEDEnum.Gear1, 6);
				controller.SetLEDState(ControllerLEDEnum.GearN, 4);
			}
			joystick.sendUpdate(1);
		}
		public String getDebugString()
		{
			return debugString;
		}
		//this gets called at the end of the program and must be present, as it cleans up resources
		public void shutDown()
		{
			controller.sendKeyUp(SBC.Key.NumPad1);
			controller.sendKeyUp(SBC.Key.NumPad2);
			controller.sendKeyUp(SBC.Key.NumPad3);
			controller.sendKeyUp(SBC.Key.NumPad4);
			controller.sendKeyUp(SBC.Key.NumPad5);
   controller.sendKeyUp(SBC.Key.Space);
			controller.UnInit();
			joystick.Release(1);
		}
	}
}
 


#418 Golden Gun

    Member

  • PipPipPip
  • Legendary Founder
  • Legendary Founder
  • 87 posts
  • LocationIdaho

Posted 09 May 2020 - 03:00 AM

Hey all, I know it's been forever, but I've been playing with this again and found an issue that keeps me from using it or trying to program for it.

The problem is that the left stick and hat are not using their full motion for input. The rotation lever is maxing out in both directions at about 2/3 the distance from middle to the full side. If that doesn't make sense imagine that the joystick can move one inch to either side. But when I use it, and even after calibration, the input maxes out when the joystick get s to about 5/8ths from the center.

The hats are worse, since they have the same range but are not centered. So mapping anything to it has things moving down and to the left.

An clues as to what can cause this?





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users