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 

Request: Streamline a function.

 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help
View previous topic :: View next topic  
Author Message
[VxE]



Joined: 07 Oct 2006
Posts: 926

PostPosted: Mon Feb 18, 2008 3:33 am    Post subject: Request: Streamline a function. Reply with quote

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
Back to top
View user's profile Send private message
Titan



Joined: 11 Aug 2004
Posts: 5020
Location: imaginationland

PostPosted: Mon Feb 18, 2008 2:26 pm    Post subject: Reply with quote

kiu done something similar with Radial Menu and rocket gestures: radialM 1.1.
_________________

RegExReplace("irc.freenode.net/autohotkey", "^(?=(.(?=[\0-r\[]*((?<=\.).))))(?:[c-\x73]{2,8}(\S))+((2)|\b[^\2-]){2}\D++$", "$u3$1$3$4$2")
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help 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