[VxE]
Joined: 07 Oct 2006 Posts: 926
|
Posted: Mon Feb 18, 2008 3:33 am Post subject: Request: Streamline a function. |
|
|
Hey everyone! I'm building a script for a USB Gamepad which has 2 Analogue Sticks (XY and ZR) a D-Pad (8-way POV), and 12 Buttons (on each analogue stick, 4 shoulder, 4 R>Thumb, and (start/select)). The eventual purpose of this script is to turn the gamepad into a keyboard and mouse. I have most of the script written, but there's one essential function that I'd like help streamlining.
If anyone can make this function simpler or more elegant, please help me out.
NOTE: this functioin works as-is, so I'm only looking to make it more compact and fluid. I included 3 lines at the top so you can copy and run the script to get a quick glimpse of the function. It would be nice if you have a joystick or gamepad to play with the function, but it won't hurt to run this code as-is. | Code: | something := CircleMenu( "Undo`nCut`nCopy`nPaste`nSave`nOpen`nSave As", "xy", 0, 5000, 70)
msgbox %something%
return
; CircleMenu( StringOfOptions, DefaultChoice, TimeOut, CircleRadius, InputAxises )
CircleMenu( string, WhichAxis = "", Default = 0, TimeOut = 0, Distance = 70 ) ; make a circle of tooltips for quick menu selection
{ ; the selection items in the string are seperated by a newline char
; axises : only [X,Y] & [Z,R] & [PoV] are supported, so this parameter must be "xy" "zr" "pov" or omitted
; default can either be a literal string or an integer corresponding to a menu choice, NOT BOTH
; timeout is in milliseconds. This is a soft timeout, so it resets if the user changes the pending selection
; distance is in pixels
oldselect = 1
If !WhichAxis
WhichAxis = xy ; use default axises
If ( WhichAxis = "zr" || WhichAxis = "xy" )
StringSplit, waxis, WhichAxis
If WhichAxis = pov
{ ; because the POV on a gamepad has only 9 states, force the menu to 8 options
tmstring = %string%`n`n`n`n`n`n`n
Loop, Parse, tmstring, `n, `r
If ((nmscount := a_index) = 1)
NewMenuString = %a_loopfield%
else If a_index <= 8
NewMenuString .= "`n" a_loopfield
string := NewMenuString
}
StringReplace, string, string, `n, `n, UseErrorLevel
Strlenth := ErrorLevel + 1 ; how many options in our menu
If !Strlenth || (Strlenth > 18)
return 0
If Timeout ; user has specified a timeout, initialize here and handle default option
{
Begintime := a_tickcount
Loop, Parse, string, `n, `r
If default = %a_index%
default := a_loopfield
}
Loop ; watch the specified axis
{
sleep 25
If Timeout && ( a_tickcount > Begintime + timeout )
return % ClearTooltips(Strlenth) . Default
If FinChoice && !radial ; return the chosen item
return % ClearTooltips(Strlenth) . FinChoice
If WhichAxis = pov ; zero denotes centered axes, 1 is up, 7 is left
{
pov5 := pov4 ; sometimes, on my d-pad, the laterals are much
pov4 := pov3 ; touchier than the diagonals, so this is just to
pov3 := pov2 ; avoid botching the selection when releasing the
pov2 := pov1 ; d-pad
pov1 := ((GetKeyState("JoyPOV", "p") + 4500) // 4500) * 4500
If (pov5 = 0) || (pov1 = 0)
radial := pov1
else If (pov1 = pov2) && (pov2 = pov3)
&& (pov3 = pov4) && (pov4 = pov5)
radial := pov1
}
Else If ( WhichAxis = "zr" || WhichAxis = "xy" )
{ ; typical axises range from 0,0 (upper left) to 100,100 (lower right)
wax1 := (GetKeyState("Joy" Waxis1, "p") - 50) / -50
wax2 := (GetKeyState("Joy" Waxis2, "p") - 50) / -50
; calculate a radial value, zero if the stick is far from the edge
radial := 36000 * ((( wax1**2 + wax2**2 )**0.5) > 0.75)
* (wax1=0 ? ((wax2<0)*0.5+0.25) : (ATan(wax2/wax1)
/ (8*ATan(1))+(wax1>0)*(wax2<0)+(wax1<0)/2))
}
Else
return 0
; reduce radial value to a selection choice
; if the radial is zero, ignore.
If radial
Selected := Floor( (Strlenth * radial / 36000) )
if Selected = 0
Selected := Strlenth
If Selected = %oldSelect% ; no change, so don't update the tooltips
Continue
oldselect := selected
If Timeout ; user is still deciding, so reset timeout
Begintime := a_tickcount
Loop, Parse, String, `n, `r
If A_LoopField ; don't display blank menu items, even though they still take up space
If ( Selected = A_Index )
ToolTip, % ">" (FinChoice := a_LoopField) "<", % percRad( (rw := (a_index
- 1)/Strlenth), Distance), % percRad(rw, Distance, "y" ), % a_index + 1
else
ToolTip, [%a_LoopField%], % percRad( (rw := (a_index
- 1)/Strlenth), Distance), % percRad(rw, Distance, "y" ), % a_index + 1
}
}
ClearToolTips( howmany )
{ ; clear whatever tooltips we've used. we never use the first tooltip here
loop %howmany%
Tooltip,,,, % a_index + 1
return
}
percRad( percent , distance = 50, axi = "") ; default to the x axis
{ ; get the X.Y of an evenly spaced position around a circle
MouseGetPos, mx, my
If axi = y
return % Floor(-Cos(percent * 2 * 3.14159) * distance) + my
return % Floor(Sin(percent * 2 * 3.14159) * distance) + mx
} |
Thanks a bajillion _________________ My Home Thread
More Common Answers: 1. It's in the FAQ 2. Ternary ( ? : ) guide 3. Post code with [code][/code] tags |
|