/* ----------------------------------------------------------------------------- This source file is part of OpenSpace3D For the latest info, see http://www.openspace3d.com Copyright (c) 2012 I-maginer This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA, or go to http://www.gnu.org/copyleft/lesser.txt ----------------------------------------------------------------------------- */ /* Version : 1.0 First version : 05/08/2010 Author : Bourineau Bastien */ struct ObjJoyPadStr = [ PJOY_inst : PInstance, PJOY_joypad : ObjJoypad, PJOY_iIndex : I, PJOY_control : [[F F F] [F F F]], PJOY_lPrevAxis : [[F F] [F F] [F F] [F F] [F F]], PJOY_lBtnState : [[I I] r1], PJOY_iLstickState : I, PJOY_iRstickState : I, PJOY_bUpdated : I, PJOY_bControl : I, PJOY_bLstick : I, PJOY_bRstick : I, PJOY_bLz : I, PJOY_bRz : I, PJOY_bPov : I, PJOY_bSlider : I ]mkObjJoyPadStr;; /*! \brief Callback on instance destruction * * Prototype: fun [PInstance ObjJoypad] I * * \param PInstance : destroyed plugIT instance * \param ObjJoypad : joypad object * * \return I : 0 **/ fun deleteOb(inst, obstr)= setPluginInstanceCbPreRender inst nil; _CloseJoypad obstr.PJOY_joypad; 0;; fun cbJoyPreRender(inst, viewstr, obstr)= if (!obstr.PJOY_bUpdated) then nil else let obstr.PJOY_control -> [[vx vy vz] [ax ay az]] in ( SendPluginEvent inst "Control" (strbuild ((ftoa vx)::(ftoa vy)::(ftoa -.vz)::nil)::((ftoa ay)::(ftoa ax)::(ftoa az)::nil)::nil) inst.INST_sName; set obstr.PJOY_bUpdated = 0; ); 0;; // for infos on pov values see : http://msdn.microsoft.com/en-us/library/microsoft.directx_sdk.reference.dijoystate2(VS.85).aspx fun cbJoypadData(joypad, obstr, stick1, lzaxis, stick2, rzaxis, pov, sliders, lbtn)= let obstr.PJOY_inst -> inst in let obstr.PJOY_control -> [v a] in let 0.4 -> deadzone in ( let stick1 -> [jx1 jy1] in let (itof jx1) /. 1000.0 -> jfx1 in let if ((absf jfx1) <=. deadzone) then 0.0 else (if (jfx1 <. 0.0) then (jfx1 +. deadzone) else (jfx1 -. deadzone)) /. (1.0 -. deadzone) -> jfx1 in let (itof jy1) /. 1000.0 -> jfy1 in let if ((absf jfy1) <=. deadzone) then 0.0 else (if (jfy1 <. 0.0) then (jfy1 +. deadzone) else (jfy1 -. deadzone)) /. (1.0 -. deadzone) -> jfy1 in let stick2 -> [jx2 jy2] in let (itof jx2) /. 1000.0 -> jfx2 in let if ((absf jfx2) <=. deadzone) then 0.0 else (if (jfx2 <. 0.0) then (jfx2 +. deadzone) else (jfx2 -. deadzone)) /. (1.0 -. deadzone) -> jfx2 in let (itof jy2) /. 1000.0 -> jfy2 in let if ((absf jfy2) <=. deadzone) then 0.0 else (if (jfy2 <. 0.0) then (jfy2 +. deadzone) else (jfy2 -. deadzone)) /. (1.0 -. deadzone) -> jfy2 in let (itof lzaxis) /. 1000.0 -> lfzaxis in let if ((absf lfzaxis) <=. deadzone) then 0.0 else (if (lfzaxis <. 0.0) then (lfzaxis +. deadzone) else (lfzaxis -. deadzone)) /. (1.0 -. deadzone) -> lfzaxis in let (itof rzaxis) /. 1000.0 -> rfzaxis in let if ((absf rfzaxis) <=. deadzone) then 0.0 else (if (rfzaxis <. 0.0) then (rfzaxis +. deadzone) else (rfzaxis -. deadzone)) /. (1.0 -. deadzone) -> rfzaxis in let sliders -> [slx sly] in let (itof slx) /. 1000.0 -> sslx in let if ((absf sslx) <=. deadzone) then 0.0 else (if (sslx <. 0.0) then (sslx +. deadzone) else (sslx -. deadzone)) /. (1.0 -. deadzone) -> sslx in let (itof sly) /. 1000.0 -> ssly in let if ((absf ssly) <=. deadzone) then 0.0 else (if (ssly <. 0.0) then (ssly +. deadzone) else (ssly -. deadzone)) /. (1.0 -. deadzone) -> ssly in let pov -> [pov1 pov2 pov3 pov4] in let if (pov1 == -1) then [0.0 0.0] else if (pov1 == 0) then [0.0 1.0] else if (pov1 == 4500) then [1.0 1.0] else if (pov1 == 9000) then [1.0 0.0] else if (pov1 == 13500) then [1.0 (-.1.0)] else if (pov1 == 18000) then [0.0 (-.1.0)] else if (pov1 == 22500) then [(-.1.0) (-.1.0)] else if (pov1 == 27000) then [(-.1.0) 0.0] else if (pov1 == 31500) then [(-.1.0) 1.0] else [0.0 0.0] -> [povx povy] in ( mutate a <-[-.((maxf jfx1 jfx2) +. (minf jfx1 jfx2)) (-.jfy2) _]; mutate v <-[povx povy (-.jfy1)]; let obstr.PJOY_lPrevAxis -> [[pjfx1 pjfy1] [pjfx2 pjfy2] [plfzaxis prfzaxis] [ppovx ppovy] [pslx psly]] in ( if ((!obstr.PJOY_bLstick) || ((obstr.PJOY_lPrevAxis != nil) && ((absf (jfx1 -. pjfx1)) <=. 0.001) && ((absf (jfy1 -. pjfy1)) <=. 0.001))) then nil else SendPluginEvent inst "Left stick" strcatn (ftoa jfx1)::" "::(ftoa jfy1)::nil nil; if ((!obstr.PJOY_bRstick) || ((obstr.PJOY_lPrevAxis != nil) && ((absf (jfx2 -. pjfx2)) <=. 0.001) && ((absf (jfy2 -. pjfy2)) <=. 0.001))) then nil else SendPluginEvent inst "Right stick" strcatn (ftoa jfx2)::" "::(ftoa jfy2)::nil nil; let if (obstr.PJOY_lPrevAxis == nil) then 0 else if (jfx1 <. (-.0.7)) then //left -1 else if (jfx1 >. 0.7) then //right 1 else if (jfy1 <. (-.0.7)) then //up 2 else if (jfy1 >. 0.7) then //down -2 else 0 -> ladir in ( if (obstr.PJOY_iLstickState == ladir) then nil else if (ladir == 0) then SendPluginEvent inst "Left stick center" nil nil else if (ladir == (-1)) then SendPluginEvent inst "Left stick left" nil nil else if (ladir == 1) then SendPluginEvent inst "Left stick right" nil nil else if (ladir == (-2)) then SendPluginEvent inst "Left stick down" nil nil else if (ladir == 2) then SendPluginEvent inst "Left stick up" nil nil else nil; set obstr.PJOY_iLstickState = ladir; ); let if (obstr.PJOY_lPrevAxis == nil) then 0 else if (jfx2 <. (-.0.7)) then //left -1 else if (jfx2 >. 0.7) then //right 1 else if (jfy2 <. (-.0.7)) then //up 2 else if (jfy2 >. 0.7) then //down -2 else 0 -> radir in ( if (obstr.PJOY_iRstickState == radir) then nil else if (radir == 0) then SendPluginEvent inst "Right stick center" nil nil else if (radir == (-1)) then SendPluginEvent inst "Right stick left" nil nil else if (radir == 1) then SendPluginEvent inst "Right stick right" nil nil else if (radir == (-2)) then SendPluginEvent inst "Right stick down" nil nil else if (radir == 2) then SendPluginEvent inst "Right stick up" nil nil else nil; set obstr.PJOY_iRstickState = radir; ); if ((!obstr.PJOY_bLz) || ((obstr.PJOY_lPrevAxis != nil) && ((absf (lfzaxis -. plfzaxis)) <=. 0.001))) then nil else SendPluginEvent inst "LZ axis" (ftoa lfzaxis) nil; if ((!obstr.PJOY_bRz) || ((obstr.PJOY_lPrevAxis != nil) && ((absf (rfzaxis -. prfzaxis)) <=. 0.001))) then nil else SendPluginEvent inst "RZ axis" (ftoa rfzaxis) nil; if ((!obstr.PJOY_bSlider) || ((obstr.PJOY_lPrevAxis != nil) && ((absf (sslx -. pslx)) <=. 0.001) && ((absf (ssly -. psly)) <=. 0.001))) then nil else SendPluginEvent inst "Slider axis" strcatn (ftoa sslx)::" "::(ftoa ssly)::nil nil; if ((!obstr.PJOY_bPov) || ((obstr.PJOY_lPrevAxis != nil) && ((absf (povx -. ppovx)) == 0.0) && ((absf (povy -. ppovy)) == 0.0))) then nil else SendPluginEvent inst "Pov" strcatn (ftoa povx)::" "::(ftoa povy)::nil nil; if ((obstr.PJOY_lPrevAxis != nil) && ((absf (povx -. ppovx)) == 0.0)) then nil else if (povx >. 0.0) then SendPluginEvent inst "Pov right" nil nil else if (povx <. 0.0) then SendPluginEvent inst "Pov left" nil nil else nil; if ((obstr.PJOY_lPrevAxis != nil) && ((absf (povy -. ppovy)) == 0.0)) then nil else if (povy >. 0.0) then SendPluginEvent inst "Pov up" nil nil else if (povy <. 0.0) then SendPluginEvent inst "Pov down" nil nil else nil; if ((obstr.PJOY_lPrevAxis != nil) && ((povx != ppovx) || (povy != ppovy)) && ((povx == 0.0) && (povy == 0.0))) then SendPluginEvent inst "Pov center" nil nil else nil; ); set obstr.PJOY_lPrevAxis = [[jfx1 jfy1] [jfx2 jfy2] [lfzaxis rfzaxis] [povx povy] [sslx ssly]]; ); if obstr.PJOY_lBtnState != nil then nil else ( let sizelist lbtn -> size in let 0 -> i in while (i < size) do ( set obstr.PJOY_lBtnState = [i (nth_list lbtn i)]::obstr.PJOY_lBtnState; set i = i + 1; ); set obstr.PJOY_lBtnState = revertlist obstr.PJOY_lBtnState; ); let sizelist lbtn -> size in let 0 -> i in while (i < size) do ( let (nth_list lbtn i) -> curstate in ( if !curstate then nil else SendPluginEvent inst strcat "Button " (itoa i+1) nil nil; let switch obstr.PJOY_lBtnState i -> btnstate in if (btnstate == curstate) then nil else ( if curstate then SendPluginEvent inst strcatn "Button "::(itoa i+1)::" down"::nil nil nil else SendPluginEvent inst strcatn "Button "::(itoa i+1)::" up"::nil nil nil; ); //update btn states let nth_list obstr.PJOY_lBtnState i -> btn in mutate btn <- [_ curstate]; ); set i = i + 1; ); ); set obstr.PJOY_bUpdated = 1; 0;; fun cbStartRumble(inst, from, action, param, rep, obstr)= let strextr param -> lp in let if (atof (nth_list (hd lp) 0)) == nil then 0.5 else (atof (nth_list (hd lp) 0)) -> intensity in _StartJoypadRumble obstr.PJOY_joypad intensity; 0;; fun cbStopRumble(inst, from, action, param, rep, obstr)= _StopJoypadRumble obstr.PJOY_joypad; 0;; fun cbConnect(inst, from, action, param, rep, obstr)= if (obstr.PJOY_joypad != nil) then nil else ( let _OpenJoypadEx _channel obstr.PJOY_iIndex @cbJoypadData obstr -> joypad in set obstr.PJOY_joypad = joypad; if (obstr.PJOY_joypad == nil) || (!obstr.PJOY_bControl) then nil else setPluginInstanceCbPreRender inst mkfun3 @cbJoyPreRender obstr; ); 0;; fun cbDisconnect(inst, from, action, param, rep, obstr)= setPluginInstanceCbPreRender inst nil; _CloseJoypad obstr.PJOY_joypad; set obstr.PJOY_joypad = nil; 0;; fun cbSetDeviceIndex(inst, from, action, param, rep, obstr)= if ((atoi param) == nil) then nil else ( set obstr.PJOY_iIndex = atoi param; if (obstr.PJOY_joypad == nil) then nil else ( cbDisconnect inst nil nil nil nil obstr; cbConnect inst nil nil nil nil obstr; ); ); 0;; /*! \brief Callback on new plugIT instance * * Read the parameters from editor values and connect the joypad * * Prototype: fun [PInstance] I * * \param PInstance : plugIT instance * * \return I : 0 **/ fun newOb(inst)= let atoi (getPluginInstanceParam inst "index") -> index in let if index == nil then 0 else index -> index in let atoi (getPluginInstanceParam inst "init") -> init in let if init == nil then 1 else init -> init in let (IsInEditor inst) || IsEventLinked inst "Control" -> bcontrol in let (IsInEditor inst) || IsEventLinked inst "Left stick" -> blstick in let (IsInEditor inst) || IsEventLinked inst "Right stick" -> brstick in let (IsInEditor inst) || IsEventLinked inst "LZ axis" -> blz in let (IsInEditor inst) || IsEventLinked inst "RZ axis" -> brz in let (IsInEditor inst) || IsEventLinked inst "Pov" -> bpov in let (IsInEditor inst) || IsEventLinked inst "Slider axis" -> bslider in let mkObjJoyPadStr [inst nil index [[0.0 0.0 0.0] [0.0 0.0 0.0]] nil nil 0 0 0 bcontrol blstick brstick blz brz bpov bslider] -> obstr in ( if (!init) then nil else cbConnect inst nil nil nil nil obstr; PluginRegisterAction inst "Connect" mkfun6 @cbConnect obstr; PluginRegisterAction inst "Disconnect" mkfun6 @cbDisconnect obstr; PluginRegisterAction inst "Set device index" mkfun6 @cbSetDeviceIndex obstr; PluginRegisterAction inst "Start rumble" mkfun6 @cbStartRumble obstr; PluginRegisterAction inst "Stop rumble" mkfun6 @cbStopRumble obstr; setPluginInstanceCbDel inst mkfun2 @deleteOb obstr; ); 0;; /*! \brief Global plugIT function to initialize the plugIT callbacks * * Prototype: fun [S] I * * \param S : plugIT file path * * \return I : 0 **/ fun IniPlug(file)= PlugRegister @newOb nil; setPluginEditor @dynamicedit; 0;;