AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Graphically Enhanced Joystick and Gamepad Test Script

 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
[VxE]



Joined: 07 Oct 2006
Posts: 1496

PostPosted: Thu Aug 28, 2008 1:06 am    Post subject: Graphically Enhanced Joystick and Gamepad Test Script Reply with quote

[edit:] Old version removed. New version in next post.
_________________
My Home Thread
More Common Answers: [1]. It's in the FAQ [2]. Ternary ( a ? b : c ) guide [3]. Post code inside [code][/code] tags !
Back to top
View user's profile Send private message
[VxE]



Joined: 07 Oct 2006
Posts: 1496

PostPosted: Thu Nov 20, 2008 11:28 am    Post subject: Reply with quote

[edit: New version two posts down]
_________________
My Home Thread
More Common Answers: [1]. It's in the FAQ [2]. Ternary ( a ? b : c ) guide [3]. Post code inside [code][/code] tags !


Last edited by [VxE] on Sat Nov 22, 2008 2:12 am; edited 1 time in total
Back to top
View user's profile Send private message
Laszlo



Joined: 14 Feb 2005
Posts: 4078
Location: Pittsburgh

PostPosted: Thu Nov 20, 2008 5:25 pm    Post subject: Reply with quote

Could be very useful. Thanks!
A couple of points, though:
- The buttons of the second gamepad are not captured, still the first gamepad actions are shown
- The ovals around the buttons look horrible in my Vista PC. Maybe WinSet Region... is better, with rounded corners
- My joystick has 32 buttons. The rightmost 2 corresponding fields (16,32) in the GUI are partially cut-off
- Selecting the functions by clicking in the graphic boxes is neat, but at an accidental click it the display changes, which is tedious to fix. Requesting a confirmation would be useful, and a way to reset the default/previous settings.
Back to top
View user's profile Send private message
[VxE]



Joined: 07 Oct 2006
Posts: 1496

PostPosted: Thu Nov 20, 2008 9:34 pm    Post subject: Reply with quote

I think I've addressed the issues regarding ugliness (ok, so maybe black and white isn't exactly pimpin') of the buttons, and correct reporting for different joystick numbers.
» Sizing and orientation of the buttons is now more context-based.
» Changing axes is now more intuitive, although at the cost of not being able to select both axes in one go. Also, the axis select window does not appear directly beneath the mouse
» Changed "Rectangle" to "RoundRect" for aesthetic consideration

Todo: I'll try to develop a gui-based system for assigning various joystick inputs to scriptable actions and attributes used in those actions. The result will be (hopefully) working AHKscript for remapping the specified joystick.

Feedback welcome!
[edit: Updated Script]
Code:
; Gamepad and Joystick Test Script: Revamped
; Graphically provides feedback about joysticks
; currently connected to the computer. The buttons
; at the top of the script represent the current
; numbers of joysticks that are connected and available
OnExit, GuiClose
Loop 32
   If GetKeyState(A_Index "JoyButtons") > 1
   {
      If !Mod(nb, 9)
         options = xm section
      Gui, Add, Button, %options% gPickNum, Joy %A_Index%
      options = ys xp+52
      nb++
   }
Gui, Add, Text, xm section vtx1 hwndhtx1 w109 h109 grebind,
Gui, Add, Text, ys vtx2 hwndhtx2 w109 h109 grebind,
Gui, Add, Text, ys vtx3 hwndhtx3 w109 h109 grebind,
Gui, Add, Text, ys vtx4 hwndhtx4 w109 h109 grebind,
Gui, Add, Text, xs vtx5 hwndhtx5 w466 h80,
Gui, +LastFound
Gui, Show,, Gamepad and Joystick Visual Test Script`, by [VxE] (v2.34)
ghwnd := WinExist()
bind1 = PoV
bind2 = X,Y
bind3 = Z,R
bind4 = U,V

PickNum:
SetTimer, Disp, off
StringTrimLeft, Joynum, A_GuiControl, 4
axes := "_" SubStr("XY" info := GetKeyState(Joynum "JoyInfo")
, 1, GetKeyState(Joynum "joyaxes")+(InStr(info, "p")>0))
btns := GetKeyState(Joynum "joybuttons")

wipe:
SetTimer, Disp, off
DllCall("DeleteObject", UInt, hPen)
DllCall("DeleteObject", UInt, hPen2)
hPen := DllCall("CreatePen", UInt, 0, UInt, 3, UInt, 0)
hPen2 := DllCall("CreatePen", UInt, 0, UInt, 0, UInt, 0)
Loop 5
{
   DllCall("ReleaseDC", UInt, hDC%A_Index%)
   hDC%A_Index% := DllCall("GetDC", UInt, htx%A_Index%)
   DllCall("SelectObject", UInt, hDC%A_Index%, UInt, hPen)
   DllCall("SetROP2", UInt, hDC%A_Index%, UInt, 1)
   If A_Index < 5
   DllCall("RoundRect", UInt, hDC%A_Index%, Int, 1
      , Int, 1, Int, 108, Int, 108, Int, 9, Int, 9)
   Else DllCall("RoundRect", UInt, hDC5, Int, 1
   , Int, 1, Int, 465, Int, 79, Int, 9, Int, 9)
   DllCall("SetROP2", UInt, hDC%A_Index%, UInt, 6)
   DllCall("SetBkMode", UInt, hDC%A_Index%, UInt, 1)
   If A_Index < 5
   DllCall("SelectObject", UInt, hDC%A_Index%, UInt, hPen2)
   old%A_Index% =
}
SetTimer, Disp, 10
return

GuiClose:
DllCall("DeleteObject", UInt, hPen)
DllCall("DeleteObject", UInt, hPen2)
Loop 5
   DllCall("ReleaseDC", UInt, hDC%A_Index%)
Exitapp
return

Disp:
old1 := DisplayAxisGraphic( Joynum, bind1, hDC1, old1 )
old2 := DisplayAxisGraphic( Joynum, bind2, hDC2, old2 )
old3 := DisplayAxisGraphic( Joynum, bind3, hDC3, old3 )
old4 := DisplayAxisGraphic( Joynum, bind4, hDC4, old4 )
old5 := DisplayButtonGraphic( Joynum, btns, hDC5, old5 )
If ((!wca) = (wca := !WinActive("Ahk_ID " ghwnd))) && !wca
   Gosub wipe
return

rebind:
SetTimer, Disp, off
StringRight, field, A_GuiControl, 1
bind%field% := Rebind( hDC%field%, bind%field%, axes )
sleep 30
Gosub wipe
return

DisplayButtonGraphic( joynum, buttons, hDC, predata )
{
   m := buttons//(dy := (buttons-1)//8 + 1)
   m += (m*dy < buttons)
   x := Round(233 / m)
   StringSplit, p, predata, "|"
   Loop, %Buttons%
   {
      c := GetKeyState(joynum "Joy" A_Index)
      If (p%A_Index% != c)
      {
         l := A_Index
         y := (40 // dy) * (1+2*((l-1)//m))
         q := (p%A_Index% = "")
         cx := Mod(l-1,m) * 2 * x + x
         DllCall("Ellipse", UInt, hDC
         , Int, cx-15-q, Int, y-13-q+dy*2
         , Int, cx+15+q, Int, y+13+q-dy*2 )
         DllCall("SetTextColor", UInt, hDC, UInt, c*0xFFFFFF)
         DllCall("TextOut", UInt, hDC
         , Int, cx-5-(l>9)*4, Int, y-8
         , UInt, &l, UInt, StrLen(l) )
      }
      data .= "|" c
   }
   return substr(data,2)
}

DisplayPoVGraphic( joynum, hDC, predata )
{
   Static 2pi = 6.283185307179586
   pov := GetKeyState(joynum "JoyPoV")
   If !InStr(GetKeyState(joynum "JoyInfo"),"P")
      pov = N/A
   tex := "PoV = " pov
   If pov = N/A
      pov = -1
   StringSplit, o, predata, |
   If (o5 = tex)
      return predata
   If (predata != "")
   {
      DllCall("MoveToEx", UInt, hDC, int, o3, int, o4 )
      DllCall("LineTo", UInt, hDC, Int, o1, Int, o2)
      DllCall("MoveToEx", UInt, hDC, int, o1, int, o2-4 )
      DllCall("Arc", UInt, hDC, Int, o1-4, Int, o2-4
      , Int, o1+5, Int, o2+5, Int, o1, Int, o2-4, Int, o1, Int, o2-4)
      DllCall("SetTextColor", UInt, hDC, UInt, 0)
      DllCall("TextOut", UInt, hDC, Int, 20, Int, 4
         , UInt, &o5, UInt, StrLen(o5))
   }
   DllCall("SetTextColor", UInt, hDC, UInt, 0xFFFFFF)
   DllCall("TextOut", UInt, hDC, Int, 20, Int, 4
      , UInt, &tex, UInt, StrLen(tex))
   dx := dy := 54
   If (pov >= 0)
   {
      a := 2pi * pov / 36000
      dx := 80 * Sin(a), dy := -80 * Cos(a)
      sx := (dx>0)*2-1, sy := (dy>0)*2-1
      If (dx:=Abs(dx)) > (dy:=Abs(dy))
         dy := 5+Floor(49.5+sy*dy*49.5/dx), dx := 5+Floor(49.5+sx*49.5)
      Else
         dx := 5+Floor(49.5+sx*dx*49.5/dy), dy := 5+Floor(49.5+sy*49.5)
      DllCall("MoveToEx", UInt, hDC, int, 54, int, 54 )
      DllCall("LineTo", UInt, hDC, Int, dx, Int, dy)
   }
      DllCall("MoveToEx", UInt, hDC, int, dx, int, dy-4 )
      DllCall("Arc", UInt, hDC, Int, dx-4, Int, dy-4
      , Int, dx+5, Int, dy+5, Int, dx, Int, dy-4, Int, dx, Int, dy-4)

   return dx "|" dy "|" 54 "|" 54 "|" tex
}

DisplayAxisGraphic( joynum, axis, hDC, predata )
{
   If InStr(axis, "pov")
      return DisplayPoVGraphic( joynum, hDC, predata )
   StringSplit, c, axis, |`,, %A_Space%`r`n
   StringSplit, o, predata, |
   a1 := a2 := 50.01
   Loop 2
      If InStr("XY" GetKeyState(joynum "JoyInfo"), c%A_Index%)
         a%A_Index% := GetKeyState(joynum "Joy" c%A_Index%)
   If (o1 = a1 && o2 = a2)
      return predata
   If (predata != "")
   {
      DllCall("MoveToEx", UInt, hDC, int, o1+4, int o2 )
      DllCall("Arc", UInt, hDC, Int, o1, Int, o2
      , Int, o1+9, Int, o2+9, Int, o1+4, Int, o2, Int, o1+4, Int, o2)
      DllCall("SetTextColor", UInt, hDC, UInt, 0)
      DllCall("TextOut", UInt, hDC, Int, 5, Int, 87
         , UInt, &o4, UInt, StrLen(o4))
      DllCall("TextOut", UInt, hDC, Int, 45, Int, 1
         , UInt, &o3, UInt, StrLen(o3))
   }
   DllCall("MoveToEx", UInt, hDC, int, a1+4, int a2 )
   DllCall("Arc", UInt, hDC, Int, a1, Int, a2
   , Int, a1+9, Int, a2+9, Int, a1+4, Int, a2, Int, a1+4, Int, a2)
   Loop 2
      tex%A_Index% := c%A_Index% " = " Round(a%A_Index%)
   DllCall("SetTextColor", UInt, hDC, UInt, 0xFFFFFF)
   If a2 != 50.01
      DllCall("TextOut", UInt, hDC, Int, 5, Int, 87
      , UInt, &tex2, UInt, StrLen(tex2))
   If a1 != 50.01
      DllCall("TextOut", UInt, hDC, Int, 45, Int, 1
      , UInt, &tex1, UInt, StrLen(tex1))
   return a1 "|" a2 "|" tex1 "|" tex2
}

Rebind( hDC, old, axes )
{
   VarSetCapacity(point, 8, 0)
   DllCall("GetDCOrgEx", UInt, hDC, UInt, &point)
   x := NumGet(point, 0, "Int")
   y := NumGet(point, 4, "Int")
   Gui, 2:Margin, 2, 2
   old2 := "_"
   StringSplit, old, old, `,
   If SubStr(axes,0) = "p"
   {
      StringSplit, a, Axes
      a1 := "P", a%a0% := "_"
   }
   else
   {
      axes := " " axes
      StringSplit, a, axes
   }
   d := Round(111 / (a0-1)) - 2
   Loop % a0*2-1
   {
      u := Mod(A_Index-1, a0)+1 + (A_Index > a0)
      m%A_Index% := a%u%
      ym := (A_Index > a0 || A_Index = 1) ? "ym" : "yp+" d+2
      Gui, 2:Add, Text, %ym% +Border w%d% h%d%, % " " m%A_Index%
   }
   c := " "
   n := "-"
   x -= d+4
   y -= d+4
   old := 0 n 0 c 115+d n 0 c 115+d n d+4 c d+4
   . n d+4 c d+4 n 115+d c 0 n 115+d c 0 n 0
   w := h := 115+d
   Gui, +Disabled
   Gui, 2:Default
   Gui, 2:+ToolWindow -Caption +LastFound
   Gui, Show, x-200 y-200 w%w% h%h%, Dummy Pick Axes
   WinSet, Region, %old%, Dummy Pick Axes
   WinMove, x, y
   KeyWait, LButton
   MouseGetPos,,,w, c
   If (w = WinExist())
   {
      If (n := SubStr(c,7)) > a0 ; i.e. "Static4"
         old1 := m%n%, old2 := old2 = "pov" ? "_" : old2
      else   old2 := m%n%, old1 := old1 = "pov" ? "_" : old1
   }
   else n =
   Gui, 1:Default
   Gui, -Disabled
   Gui, 2:Hide
   Gui, 2:Destroy
   return m%n% = "p" ? "pov" : old1 "," old2
}

_________________
My Home Thread
More Common Answers: [1]. It's in the FAQ [2]. Ternary ( a ? b : c ) guide [3]. Post code inside [code][/code] tags !
Back to top
View user's profile Send private message
TheLeO



Joined: 11 Jun 2005
Posts: 179
Location: England ish

PostPosted: Sun Nov 23, 2008 12:42 am    Post subject: Reply with quote

For some reason, your code fails at line 8, saying that it's not a valid line?
_________________
And i say: where there is a problem , there is a solution.(well some where that is.)
::
I Have Spoken
::
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
Laszlo



Joined: 14 Feb 2005
Posts: 4078
Location: Pittsburgh

PostPosted: Sun Nov 23, 2008 1:52 am    Post subject: Reply with quote

It works perfectly for me (VISTA-32, with a Nintendo gamepad and with a home-made 32 button joystick). Good job!
Back to top
View user's profile Send private message
[VxE]



Joined: 07 Oct 2006
Posts: 1496

PostPosted: Sun Nov 23, 2008 2:46 am    Post subject: Reply with quote

TheLeO wrote:
For some reason, your code fails at line 8, saying that it's not a valid line?

I have no idea why that might happen. Line 8 would be the first "If GetKeyState" line? Maybe if you gave more info about the error you're getting?
_________________
My Home Thread
More Common Answers: [1]. It's in the FAQ [2]. Ternary ( a ? b : c ) guide [3]. Post code inside [code][/code] tags !
Back to top
View user's profile Send private message
TheLeO



Joined: 11 Jun 2005
Posts: 179
Location: England ish

PostPosted: Mon Nov 24, 2008 5:21 am    Post subject: Reply with quote

Never mind, I figured it out, it was Google chrome that was being evil.
_________________
And i say: where there is a problem , there is a solution.(well some where that is.)
::
I Have Spoken
::
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
TheLeO



Joined: 11 Jun 2005
Posts: 179
Location: England ish

PostPosted: Mon Nov 24, 2008 5:21 am    Post subject: Reply with quote

btw, thank you for the scipt, very very nice.
_________________
And i say: where there is a problem , there is a solution.(well some where that is.)
::
I Have Spoken
::
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group