I just ordered the Gaming Jacket from TNGames and guess what? I couldn't resist to implement a F#/VSLab library for controlling the gaming Jacket from F#.
I compiled a C++ DLL that simply exposes the API and defined F# PInvoke statements in a module. A class is used to expose the Jacket to F# programs including to the F# interactive.
This is an example of usage:
#light
#r @"ManagedJacket.dll"
open ManagedJacket
open System
let j = new Jacket()
let sequence = [| Actuator.BackBottomLeft; Actuator.FrontBottomLeft; Actuator.BackBottomRight; Actuator.FrontBottomRight; Actuator.BackTopLeft; Actuator.FrontTopLeft; Actuator.BackTopRight; Actuator.FrontTopRight |]
for i in 1..10 do
for v in sequence do
j.SetAirCell 5uy v
System.Threading.Thread.Sleep 100
(j :> IDisposable).Dispose()
This code performs a very simple form of massage. Now we are considering to use blasts when you do bad coding in Visual Studio!!!
I include the definition of the library that maps one on one on the functionality of the SDK.
This is the content of the interop.fs file:
#light
module ManagedJacket.Interop
open System.Runtime.InteropServices
[<DllImport("JacketDLL.dll")>]
extern int internal Jacket_SetUpJacket()
[<DllImport("JacketDLL.dll")>]
extern void internal Jacket_TearDownJacket()
[<DllImport("JacketDLL.dll")>]
extern int internal Jacket_SetEffect(int nEffect)
[<DllImport("JacketDLL.dll")>]
extern int internal Jacket_SetEffect2(int speed,int actuator)
[<DllImport("JacketDLL.dll")>]
extern void internal Jacket_FlushBuffer(int actuator)
[<DllImport("JacketDLL.dll")>]
extern int internal Jacket_GetErrorCode()
And this is the public definition of the library (jacket.fs):
#light
namespace ManagedJacket
open ManagedJacket.Interop
type Effect =
| MachinegunFront = 0
| MachinegunBack = 1
| BigBlastFront = 2
| BigBlastBack = 3
| SmallBlastFront = 4
| SmallBlastBack = 5
| PistolFront = 6
| PunchFront = 7
| StabFront = 8
| ShotgunFront = 9
| RifleFront = 10
| PistolBack = 11
| PunchBack = 12
| StabBack = 13
| ShotgunBack = 14
| RifleBack = 15
| LeftSideHit = 16
| RightSideHit = 17
| Acceleration = 18
| Deceleration = 19
| Leftturn = 20
| Rightturn = 21
| AccelerationStop = 22
| DecelerationStop = 23
| LeftturnStop = 24
| RightturnStop = 25
type Actuator =
| FrontTopRight = 1
| FrontTopLeft = 2
| FrontBottomRight = 3
| FrontBottomLeft = 4
| BackTopRight = 5
| BackTopLeft = 6
| BackBottomRight = 7
| BackBottomLeft = 8
type Jacket() =
do
if Jacket_SetUpJacket() <> 0 then failwith "Error connecting with Jacket"
member x.SetPredefinedEffect(e:Effect) =
if Jacket_SetEffect (int e) <> 0 then failwith "Error activating effect"
member x.SetAirCell (speed:byte) (actuator:Actuator) =
if Jacket_SetEffect2((int speed), (int actuator)) <> 0 then failwith "Error activating effect"
member x.FlushBuffer (actuator:Actuator) =
Jacket_FlushBuffer(int actuator)
interface System.IDisposable with
member x.Dispose() =
Jacket_TearDownJacket()
A video will follow.