Main Restorations Software Audio/Jukebox/MP3 Everything Else Buy/Sell/Trade
Project Announcements Monitor/Video GroovyMAME Merit/JVL Touchscreen Meet Up Retail Vendors
Driving & Racing Woodworking Software Support Forums Consoles Project Arcade Reviews
Automated Projects Artwork Frontend Support Forums Pinball Forum Discussion Old Boards
Raspberry Pi & Dev Board controls.dat Linux Miscellaneous Arcade Wiki Discussion Old Archives
Lightguns Arcade1Up Try the site in https mode Site News

Unread posts | New Replies | Recent posts | Rules | Chatroom | Wiki | File Repository | RSS | Submit news

  

Author Topic: Windows 7- Steam Gauntlet for Arcade (kind of works)  (Read 1847 times)

0 Members and 1 Guest are viewing this topic.

whitebabylon

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 28
  • Last login:April 26, 2015, 12:10:26 am
  • I want to build my own arcade controls!
Windows 7- Steam Gauntlet for Arcade (kind of works)
« on: November 04, 2014, 12:50:42 pm »
Hey all,

Video here:
http://s16.photobucket.com/user/whitebabylon/media/glet_zpsx2afql7e.mp4.html

Basically I remapped the controls. When you move up/down/left/right it also moves your mouse cursor so your guy points that way too. My stick only does 4 directions, so when you press up, it checks if right or left is down as well to do diagnol, so you get the 8 directionals. To allow strafing I coded 'if your firing a spell, don't change the direction you point'. Keyboard and mouse inputs are all mapped to the xarcade button presses.

Code for a week here:
http://pastebin.com/Uv3KAQS8

If you also have windows 7 and don't think me silly then take a gander. I can explain it if people want.

pbj

  • Trade Count: (+4)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 11054
  • Last login:Today at 07:06:16 am
  • Obey.
    • The Chris Burke Band
Re: Windows 7- Steam Gauntlet for Arcade (kind of works)
« Reply #1 on: November 04, 2014, 12:55:15 pm »
I can explain it if people want.

Go on.

whitebabylon

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 28
  • Last login:April 26, 2015, 12:10:26 am
  • I want to build my own arcade controls!
Re: Windows 7- Steam Gauntlet for Arcade (kind of works)
« Reply #2 on: November 04, 2014, 02:11:52 pm »
I can explain it if people want.

Go on.

Cool. Wasn't sure if anyone would care or not, ha.

Mostly, the functionality is similar to AutoHotKey. What we are doing is detecting keyboard presses from the X-Arcade (same as a keyboard key press) and re-mapping the keys to other Keyboard Inputs along with mouse inputs as well.

I create a global keyboard hook that listens for any key events, and I manually map my keys to the keys that Gauntlet expects. A few limitations though, I don't think you could map 'W' to 'S' and then 'S' to 'D'. W would then fire S->D. So you'll have to watch out for that.

If you scroll through the code with me we can discuss what is happening.
Code: [Select]
[DllImport("user32.dll")]
        static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData,
           int dwExtraInfo);
http://www.pinvoke.net/default.aspx/user32.mouse_event
pInvoke is a cool resource for pretty much everything used here. First up mouse_event.
When I use this, I fire off the right and left clicks, which mouse_events takes as its dwFlag value. I also give the mouses current X and Y value for its x and y.

Code: [Select]
                    const uint RIGHTDOWN = 0x0008;
                    const uint RIGHTUP = 0x0010;
                    const uint MOUSEEVENTF_LEFTDOWN = 0x0002;
                    const uint MOUSEEVENTF_LEFTUP = 0x0004;
                    mouse_event(MOUSEEVENTF_LEFTDOWN, (uint)Cursor.Position.X, (uint)Cursor.Position.Y, 0, 0);
                    mouse_event(MOUSEEVENTF_LEFTUP, (uint)Cursor.Position.X, (uint)Cursor.Position.Y, 0, 0);
 
In the code snippet above, you have the events that happen with each button (up,down). Then you call mouse_event. This basically left/right clicks.

Next up is the keyhook
Code: [Select]
[DllImport("user32.dll")]
        private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);

Used along with this code
Code: [Select]
private static LowLevelKeyboardProc hookProc2 = HookCallback2;
        private static IntPtr hookId = IntPtr.Zero;
        public IntPtr moduleHandle;
 private static IntPtr SetHook(LowLevelKeyboardProc hookProc, IntPtr moduleHandle)
        {
 
            return SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, moduleHandle, 0);
        }
 
        private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);

And then we use the code
Code: [Select]
moduleHandle = GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName);
            hookId = SetHook(hookProc2, moduleHandle);
So we have a hook for our key presses, the code that launches is the function hookProc2

So in the hookProc2 function we either have a keyUp or keyDown event
Code: [Select]
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
            {
...
}
//ALSO
 if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
            {
..
}

This is how you send a KeyDown. First you detect the keystroke you want to alter, in this case an F key
Code: [Select]
if (((System.Windows.Forms.Keys)vkCode).ToString() == "F5") //F
                {
                    INPUT[] inputs = new INPUT[] {
                                                INPUT.VirtualKeyDown((ushort)0x21),
                    };
                    returnMe = 1;
                    SendInput(inputs.Length, inputs, Marshal.SizeOf(typeof(INPUT)));
                }

You have an array of inputs you can technically send off more than 1 keystroke, I only do 1 for 1. I have a flag returnMe so that later I can tell it to not fire the original key event of F5, because it launched my keyEvent of 0x21.
0x21 is a keycode, theres a list of all the keycodes here: http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html
To do a keyUp event, you want to do VirtualKeyUp(0x21) instead of virtualKeyDown above.

In my down events, I fire off right and left downclicks
Code: [Select]
if (((System.Windows.Forms.Keys)vkCode).ToString() == "F12") //spell
                {
                    const uint MOUSEEVENTF_LEFTDOWN = 0x0002;
                    const uint MOUSEEVENTF_LEFTUP = 0x0004;
                    mouse_event(MOUSEEVENTF_LEFTDOWN, (uint)Cursor.Position.X, (uint)Cursor.Position.Y, 0, 0);
                    //mouse_event(MOUSEEVENTF_LEFTUP, (uint)Cursor.Position.X, (uint)Cursor.Position.Y, 0, 0);
 
                }
                if (((System.Windows.Forms.Keys)vkCode).ToString() == "F8") //ligghtning
                {
                   const uint RIGHTDOWN  = 0x0008;
                   const uint RIGHTUP = 0x0010;
                   mouse_event(RIGHTDOWN, (uint)Cursor.Position.X, (uint)Cursor.Position.Y, 0, 0);
                  // mouse_event(RIGHTUP, (uint)Cursor.Position.X, (uint)Cursor.Position.Y, 0, 0);
 
                }
You can see in the code the variation the Up code has, its virtually the same, just a different event flag.


Other than that its all just map key1->key2 or key1->mouse1

Here I detect if a key press is already in place
It's the left mouse button
Code: [Select]
Keys myKey3 = new Keys();
                   
                    myKey3 = Keys.LButton;
                    if (!IsKeyDown(myKey3))
                    {
...
}

Where it takes your key you made, and runs it through this
Code: [Select]
private static KeyStates GetKeyState(Keys key)
        {
            KeyStates state = KeyStates.None;
 
            short retVal = GetKeyState((int)key);
 
            //If the high-order bit is 1, the key is down
            //otherwise, it is up.
            if ((retVal & 0x8000) == 0x8000)
                state |= KeyStates.Down;
 
            //If the low-order bit is 1, the key is toggled.
            if ((retVal & 1) == 1)
                state |= KeyStates.Toggled;
 
            return state;
        }
 
        public static bool IsKeyDown(Keys key)
        {
            return KeyStates.Down == (GetKeyState(key) & KeyStates.Down);
        }
true if its down, false if it isn't. So if your not firing a spell its ok to change your position.
When you press one of the 4 directionals, and it checks if its diagnol too, you move the mouse position to move your characters pointing direction.

My mouse coordinates are manually added, you could do a variable so that all you have to do is type your resolution once

Code: [Select]
int screenWidth = 1440;
                            int screenHeight = 0;// 900;
                            Win32.POINT p = new Win32.POINT();
                            p.x = Convert.ToInt16(screenWidth);
                            p.y = Convert.ToInt16(screenHeight);
 
                            //Win32.ClientToScreen(moduleHandle, ref p);
                            Win32.SetCursorPos(p.x, p.y);
Basically moves the mouse position to 0 (out of 900) for the height, and 1440 for the width (my monitor was 1440x900 resolution). Which is top right corner of the screen if I remember correctly.

I think thats the gist of it. On key press, don't fire original key press and send a different keystroke instead. Sometimes you move the mouse too. Sometimes you determine the keystate of other keys while firing off other key events.

whitebabylon

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 28
  • Last login:April 26, 2015, 12:10:26 am
  • I want to build my own arcade controls!
Re: Windows 7- Steam Gauntlet for Arcade (kind of works)
« Reply #3 on: November 04, 2014, 02:20:10 pm »
A few limitations, as it requires a mouse to navigate menus and shops I think. I actually only played gauntlet the game for 5 minutes before I decided to do this for fun.
One solution would be if your holding down a certain key, your control stick moves the mouse so you can pretend its a mouse to navigate menus.
Or, you could map out every menu item on every screen based on resolution and position and have a special 3 to 4 button press combination for each to basically send the mouse to that position of the screen and click the menu item. XD

pbj

  • Trade Count: (+4)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 11054
  • Last login:Today at 07:06:16 am
  • Obey.
    • The Chris Burke Band
Re: Windows 7- Steam Gauntlet for Arcade (kind of works)
« Reply #4 on: November 04, 2014, 02:36:36 pm »
Cool, so how do we use your code with the game?

whitebabylon

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 28
  • Last login:April 26, 2015, 12:10:26 am
  • I want to build my own arcade controls!
Re: Windows 7- Steam Gauntlet for Arcade (kind of works)
« Reply #5 on: November 04, 2014, 03:33:35 pm »
Cool, so how do we use your code with the game?

1.) Step one download Microsoft Visual C# 2010
http://www.visualstudio.com/en-us/downloads#d-2010-express
2.) Install and open
3.) go to file -> New project -> Windows Forms Applications Visual c# and down at bottom change WindowsformsApplication1 to keysGauntlet
4.) Paste this code in over everything else:
http://pastebin.com/GD35eev8

Now find this section of the code and edit it where "F1" etc are your keys
Code: [Select]
/* user details */
            //-----------------Movement
            //W
            string key_W = "F1";
            //A
            string key_A = "F4";
            //S
            string key_S = "F3";
            //D
            string key_D = "F2";
            //-----------------Spells
            //Left click
            string key_LClick = "F12";
            //Right click
            string key_RClick = "F8";
            //Left shift
            string key_LShift = "F10";
            //Space
            string key_Space = "F9";
            //esc
            string key_Esc = "F11";
            //-----------------Other
            //Relic 1 Q
            string key_Q = "F6";
            //Relic 2 E
            string key_E = "F7";
            //Interact F
            string key_F = "F5";
            //-----------------Resolution
            int resolution_Height = 1080;
            int resolution_Width = 1920;

Also adjust the resolution to yours. Keys are normally Capitilized
If you want to find the proper string for a key uncomment out this line
MessageBox.Show(((System.Windows.Forms.Keys)vkCode).ToString());
I believe its found more than once.

Lastly, make sure your project has all the references (right hand side, right click -> Add reference)
http://s16.photobucket.com/user/whitebabylon/media/refs_zps41d4b895.jpg.html
« Last Edit: November 04, 2014, 03:38:51 pm by whitebabylon »

whitebabylon

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 28
  • Last login:April 26, 2015, 12:10:26 am
  • I want to build my own arcade controls!
Re: Windows 7- Steam Gauntlet for Arcade (kind of works)
« Reply #6 on: November 04, 2014, 03:36:27 pm »
I might be able to make an .exe that reads from a text file from C:\gauntletKeys.txt so that you don't have to do any of this stuff. Just edit a text file.
I don't recommend that.
But if you really really want it.

pbj

  • Trade Count: (+4)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 11054
  • Last login:Today at 07:06:16 am
  • Obey.
    • The Chris Burke Band
Re: Windows 7- Steam Gauntlet for Arcade (kind of works)
« Reply #7 on: November 04, 2014, 04:08:32 pm »
An executable that pulls the variables from a text file would be excellent

whitebabylon

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 28
  • Last login:April 26, 2015, 12:10:26 am
  • I want to build my own arcade controls!
Re: Windows 7- Steam Gauntlet for Arcade (kind of works)
« Reply #8 on: November 04, 2014, 05:55:12 pm »
An executable that pulls the variables from a text file would be excellent
http://s000.tinyupload.com/?file_id=43612653628917712292

I've never used tinyupload, so I'm not sure how this will go.
I advise not running .exes from the internet. Or test it somewhere safe first maybe.

So two folders. Key Name Finder you can run 'WindowsFormsApplication1.exe' and press a key when on focus with the window and hopefully it will tell you the name you want to put for the key your trying to map.
Application to run folder you want to run keysGauntlet.exe. this reads the text file -> C:\keysGauntlet.txt
Not sure if caps matter. It only reads the very first line, with comma seperators.
Here's what mine looks like. I included the code that correspondes with the comma seperated values too:

Code: [Select]
F1,F4,F3,F2,F12,F8,F10,F9,F11,F6,F7,F5,1080,1920
//W
        private static string key_W = "F1";
        //A
        private static string key_A = "F4";
        //S
        private static string key_S = "F3";
        //D
        private static string key_D = "F2";
        //-----------------Spells
        //Left click
        private static string key_LClick = "F12";
        //Right click
        private static string key_RClick = "F8";
        //Left shift
        private static string key_LShift = "F10";
        //Space
        private static string key_Space = "F9";
        //esc
        private static string key_Esc = "F11";
        //-----------------Other
        //Relic 1 Q
        private static string key_Q = "F6";
        //Relic 2 E
        private static string key_E = "F7";
        //Interact F
        private static string key_F = "F5";
        //-----------------Resolution
        private static int resolution_Height = 1080;
        private static int resolution_Width = 1920;
So you can get an idea of what to put in your text file.

Kind of ghetto I know. maybe I'll do something easier sometime.

Careful mapping keys. If you map A to B and B to A I hear it can do bad things (force a restart). I've never had it crash my PC though so who knows.

whitebabylon

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 28
  • Last login:April 26, 2015, 12:10:26 am
  • I want to build my own arcade controls!
Re: Windows 7- Steam Gauntlet for Arcade (kind of works)
« Reply #9 on: November 04, 2014, 05:57:04 pm »
I'll also note these are global hooks. While the exe is running it will perma map those keys.. till you close the window.
Also note on resolution, if your full screening the game, put in the games resolution from the settings menu.  ;)

I'll also note AutoHotKey is very well made, if you've never used it and this type of stuff is interesting.
For me I like to know whats going on so I like to do things the hard way sometimes..
« Last Edit: November 04, 2014, 06:17:31 pm by whitebabylon »