18c2ecf20Sopenharmony_ci===============
28c2ecf20Sopenharmony_ciIforce Protocol
38c2ecf20Sopenharmony_ci===============
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci:Author: Johann Deneux <johann.deneux@gmail.com>
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ciHome page at `<http://web.archive.org/web/*/http://www.esil.univ-mrs.fr>`_
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci:Additions: by Vojtech Pavlik.
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ciIntroduction
138c2ecf20Sopenharmony_ci============
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ciThis document describes what I managed to discover about the protocol used to
168c2ecf20Sopenharmony_cispecify force effects to I-Force 2.0 devices.  None of this information comes
178c2ecf20Sopenharmony_cifrom Immerse. That's why you should not trust what is written in this
188c2ecf20Sopenharmony_cidocument. This document is intended to help understanding the protocol.
198c2ecf20Sopenharmony_ciThis is not a reference. Comments and corrections are welcome.  To contact me,
208c2ecf20Sopenharmony_cisend an email to: johann.deneux@gmail.com
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ci.. warning::
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci    I shall not be held responsible for any damage or harm caused if you try to
258c2ecf20Sopenharmony_ci    send data to your I-Force device based on what you read in this document.
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ciPreliminary Notes
288c2ecf20Sopenharmony_ci=================
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ciAll values are hexadecimal with big-endian encoding (msb on the left). Beware,
318c2ecf20Sopenharmony_civalues inside packets are encoded using little-endian.  Bytes whose roles are
328c2ecf20Sopenharmony_ciunknown are marked ???  Information that needs deeper inspection is marked (?)
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ciGeneral form of a packet
358c2ecf20Sopenharmony_ci------------------------
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ciThis is how packets look when the device uses the rs232 to communicate.
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci== == === ==== ==
408c2ecf20Sopenharmony_ci2B OP LEN DATA CS
418c2ecf20Sopenharmony_ci== == === ==== ==
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ciCS is the checksum. It is equal to the exclusive or of all bytes.
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ciWhen using USB:
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci== ====
488c2ecf20Sopenharmony_ciOP DATA
498c2ecf20Sopenharmony_ci== ====
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ciThe 2B, LEN and CS fields have disappeared, probably because USB handles
528c2ecf20Sopenharmony_ciframes and data corruption is handled or unsignificant.
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ciFirst, I describe effects that are sent by the device to the computer
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ciDevice input state
578c2ecf20Sopenharmony_ci==================
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ciThis packet is used to indicate the state of each button and the value of each
608c2ecf20Sopenharmony_ciaxis::
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci    OP= 01 for a joystick, 03 for a wheel
638c2ecf20Sopenharmony_ci    LEN= Varies from device to device
648c2ecf20Sopenharmony_ci    00 X-Axis lsb
658c2ecf20Sopenharmony_ci    01 X-Axis msb
668c2ecf20Sopenharmony_ci    02 Y-Axis lsb, or gas pedal for a wheel
678c2ecf20Sopenharmony_ci    03 Y-Axis msb, or brake pedal for a wheel
688c2ecf20Sopenharmony_ci    04 Throttle
698c2ecf20Sopenharmony_ci    05 Buttons
708c2ecf20Sopenharmony_ci    06 Lower 4 bits: Buttons
718c2ecf20Sopenharmony_ci       Upper 4 bits: Hat
728c2ecf20Sopenharmony_ci    07 Rudder
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ciDevice effects states
758c2ecf20Sopenharmony_ci=====================
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ci::
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_ci    OP= 02
808c2ecf20Sopenharmony_ci    LEN= Varies
818c2ecf20Sopenharmony_ci    00 ? Bit 1 (Value 2) is the value of the deadman switch
828c2ecf20Sopenharmony_ci    01 Bit 8 is set if the effect is playing. Bits 0 to 7 are the effect id.
838c2ecf20Sopenharmony_ci    02 ??
848c2ecf20Sopenharmony_ci    03 Address of parameter block changed (lsb)
858c2ecf20Sopenharmony_ci    04 Address of parameter block changed (msb)
868c2ecf20Sopenharmony_ci    05 Address of second parameter block changed (lsb)
878c2ecf20Sopenharmony_ci    ... depending on the number of parameter blocks updated
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ciForce effect
908c2ecf20Sopenharmony_ci------------
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci::
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci    OP=  01
958c2ecf20Sopenharmony_ci    LEN= 0e
968c2ecf20Sopenharmony_ci    00 Channel (when playing several effects at the same time, each must
978c2ecf20Sopenharmony_ci                be assigned a channel)
988c2ecf20Sopenharmony_ci    01 Wave form
998c2ecf20Sopenharmony_ci	    Val 00 Constant
1008c2ecf20Sopenharmony_ci	    Val 20 Square
1018c2ecf20Sopenharmony_ci	    Val 21 Triangle
1028c2ecf20Sopenharmony_ci	    Val 22 Sine
1038c2ecf20Sopenharmony_ci	    Val 23 Sawtooth up
1048c2ecf20Sopenharmony_ci	    Val 24 Sawtooth down
1058c2ecf20Sopenharmony_ci	    Val 40 Spring (Force = f(pos))
1068c2ecf20Sopenharmony_ci	    Val 41 Friction (Force = f(velocity)) and Inertia
1078c2ecf20Sopenharmony_ci	           (Force = f(acceleration))
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci    02 Axes affected and trigger
1118c2ecf20Sopenharmony_ci	    Bits 4-7: Val 2 = effect along one axis. Byte 05 indicates direction
1128c2ecf20Sopenharmony_ci		    Val 4 = X axis only. Byte 05 must contain 5a
1138c2ecf20Sopenharmony_ci		    Val 8 = Y axis only. Byte 05 must contain b4
1148c2ecf20Sopenharmony_ci		    Val c = X and Y axes. Bytes 05 must contain 60
1158c2ecf20Sopenharmony_ci	    Bits 0-3: Val 0 = No trigger
1168c2ecf20Sopenharmony_ci		    Val x+1 = Button x triggers the effect
1178c2ecf20Sopenharmony_ci	    When the whole byte is 0, cancel the previously set trigger
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci    03-04 Duration of effect (little endian encoding, in ms)
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_ci    05 Direction of effect, if applicable. Else, see 02 for value to assign.
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci    06-07 Minimum time between triggering.
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ci    08-09 Address of periodicity or magnitude parameters
1268c2ecf20Sopenharmony_ci    0a-0b Address of attack and fade parameters, or ffff if none.
1278c2ecf20Sopenharmony_ci    *or*
1288c2ecf20Sopenharmony_ci    08-09 Address of interactive parameters for X-axis,
1298c2ecf20Sopenharmony_ci          or ffff if not applicable
1308c2ecf20Sopenharmony_ci    0a-0b Address of interactive parameters for Y-axis,
1318c2ecf20Sopenharmony_ci	  or ffff if not applicable
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci    0c-0d Delay before execution of effect (little endian encoding, in ms)
1348c2ecf20Sopenharmony_ci
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_ciTime based parameters
1378c2ecf20Sopenharmony_ci---------------------
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_ciAttack and fade
1408c2ecf20Sopenharmony_ci^^^^^^^^^^^^^^^
1418c2ecf20Sopenharmony_ci
1428c2ecf20Sopenharmony_ci::
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_ci    OP=  02
1458c2ecf20Sopenharmony_ci    LEN= 08
1468c2ecf20Sopenharmony_ci    00-01 Address where to store the parameters
1478c2ecf20Sopenharmony_ci    02-03 Duration of attack (little endian encoding, in ms)
1488c2ecf20Sopenharmony_ci    04 Level at end of attack. Signed byte.
1498c2ecf20Sopenharmony_ci    05-06 Duration of fade.
1508c2ecf20Sopenharmony_ci    07 Level at end of fade.
1518c2ecf20Sopenharmony_ci
1528c2ecf20Sopenharmony_ciMagnitude
1538c2ecf20Sopenharmony_ci^^^^^^^^^
1548c2ecf20Sopenharmony_ci
1558c2ecf20Sopenharmony_ci::
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_ci    OP=  03
1588c2ecf20Sopenharmony_ci    LEN= 03
1598c2ecf20Sopenharmony_ci    00-01 Address
1608c2ecf20Sopenharmony_ci    02 Level. Signed byte.
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_ciPeriodicity
1638c2ecf20Sopenharmony_ci^^^^^^^^^^^
1648c2ecf20Sopenharmony_ci
1658c2ecf20Sopenharmony_ci::
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_ci    OP=  04
1688c2ecf20Sopenharmony_ci    LEN= 07
1698c2ecf20Sopenharmony_ci    00-01 Address
1708c2ecf20Sopenharmony_ci    02 Magnitude. Signed byte.
1718c2ecf20Sopenharmony_ci    03 Offset. Signed byte.
1728c2ecf20Sopenharmony_ci    04 Phase. Val 00 = 0 deg, Val 40 = 90 degs.
1738c2ecf20Sopenharmony_ci    05-06 Period (little endian encoding, in ms)
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ciInteractive parameters
1768c2ecf20Sopenharmony_ci----------------------
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_ci::
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_ci    OP=  05
1818c2ecf20Sopenharmony_ci    LEN= 0a
1828c2ecf20Sopenharmony_ci    00-01 Address
1838c2ecf20Sopenharmony_ci    02 Positive Coeff
1848c2ecf20Sopenharmony_ci    03 Negative Coeff
1858c2ecf20Sopenharmony_ci    04+05 Offset (center)
1868c2ecf20Sopenharmony_ci    06+07 Dead band (Val 01F4 = 5000 (decimal))
1878c2ecf20Sopenharmony_ci    08 Positive saturation (Val 0a = 1000 (decimal) Val 64 = 10000 (decimal))
1888c2ecf20Sopenharmony_ci    09 Negative saturation
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_ciThe encoding is a bit funny here: For coeffs, these are signed values. The
1918c2ecf20Sopenharmony_cimaximum value is 64 (100 decimal), the min is 9c.
1928c2ecf20Sopenharmony_ciFor the offset, the minimum value is FE0C, the maximum value is 01F4.
1938c2ecf20Sopenharmony_ciFor the deadband, the minimum value is 0, the max is 03E8.
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_ciControls
1968c2ecf20Sopenharmony_ci--------
1978c2ecf20Sopenharmony_ci
1988c2ecf20Sopenharmony_ci::
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_ci    OP=  41
2018c2ecf20Sopenharmony_ci    LEN= 03
2028c2ecf20Sopenharmony_ci    00 Channel
2038c2ecf20Sopenharmony_ci    01 Start/Stop
2048c2ecf20Sopenharmony_ci	    Val 00: Stop
2058c2ecf20Sopenharmony_ci	    Val 01: Start and play once.
2068c2ecf20Sopenharmony_ci	    Val 41: Start and play n times (See byte 02 below)
2078c2ecf20Sopenharmony_ci    02 Number of iterations n.
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_ciInit
2108c2ecf20Sopenharmony_ci----
2118c2ecf20Sopenharmony_ci
2128c2ecf20Sopenharmony_ci
2138c2ecf20Sopenharmony_ciQuerying features
2148c2ecf20Sopenharmony_ci^^^^^^^^^^^^^^^^^
2158c2ecf20Sopenharmony_ci::
2168c2ecf20Sopenharmony_ci
2178c2ecf20Sopenharmony_ci    OP=  ff
2188c2ecf20Sopenharmony_ci    Query command. Length varies according to the query type.
2198c2ecf20Sopenharmony_ci    The general format of this packet is:
2208c2ecf20Sopenharmony_ci    ff 01 QUERY [INDEX] CHECKSUM
2218c2ecf20Sopenharmony_ci    responses are of the same form:
2228c2ecf20Sopenharmony_ci    FF LEN QUERY VALUE_QUERIED CHECKSUM2
2238c2ecf20Sopenharmony_ci    where LEN = 1 + length(VALUE_QUERIED)
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_ciQuery ram size
2268c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~
2278c2ecf20Sopenharmony_ci
2288c2ecf20Sopenharmony_ci::
2298c2ecf20Sopenharmony_ci
2308c2ecf20Sopenharmony_ci    QUERY = 42 ('B'uffer size)
2318c2ecf20Sopenharmony_ci
2328c2ecf20Sopenharmony_ciThe device should reply with the same packet plus two additional bytes
2338c2ecf20Sopenharmony_cicontaining the size of the memory:
2348c2ecf20Sopenharmony_ciff 03 42 03 e8 CS would mean that the device has 1000 bytes of ram available.
2358c2ecf20Sopenharmony_ci
2368c2ecf20Sopenharmony_ciQuery number of effects
2378c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~
2388c2ecf20Sopenharmony_ci
2398c2ecf20Sopenharmony_ci::
2408c2ecf20Sopenharmony_ci
2418c2ecf20Sopenharmony_ci    QUERY = 4e ('N'umber of effects)
2428c2ecf20Sopenharmony_ci
2438c2ecf20Sopenharmony_ciThe device should respond by sending the number of effects that can be played
2448c2ecf20Sopenharmony_ciat the same time (one byte)
2458c2ecf20Sopenharmony_ciff 02 4e 14 CS would stand for 20 effects.
2468c2ecf20Sopenharmony_ci
2478c2ecf20Sopenharmony_ciVendor's id
2488c2ecf20Sopenharmony_ci~~~~~~~~~~~
2498c2ecf20Sopenharmony_ci
2508c2ecf20Sopenharmony_ci::
2518c2ecf20Sopenharmony_ci
2528c2ecf20Sopenharmony_ci    QUERY = 4d ('M'anufacturer)
2538c2ecf20Sopenharmony_ci
2548c2ecf20Sopenharmony_ciQuery the vendors'id (2 bytes)
2558c2ecf20Sopenharmony_ci
2568c2ecf20Sopenharmony_ciProduct id
2578c2ecf20Sopenharmony_ci~~~~~~~~~~
2588c2ecf20Sopenharmony_ci
2598c2ecf20Sopenharmony_ci::
2608c2ecf20Sopenharmony_ci
2618c2ecf20Sopenharmony_ci    QUERY = 50 ('P'roduct)
2628c2ecf20Sopenharmony_ci
2638c2ecf20Sopenharmony_ciQuery the product id (2 bytes)
2648c2ecf20Sopenharmony_ci
2658c2ecf20Sopenharmony_ciOpen device
2668c2ecf20Sopenharmony_ci~~~~~~~~~~~
2678c2ecf20Sopenharmony_ci
2688c2ecf20Sopenharmony_ci::
2698c2ecf20Sopenharmony_ci
2708c2ecf20Sopenharmony_ci    QUERY = 4f ('O'pen)
2718c2ecf20Sopenharmony_ci
2728c2ecf20Sopenharmony_ciNo data returned.
2738c2ecf20Sopenharmony_ci
2748c2ecf20Sopenharmony_ciClose device
2758c2ecf20Sopenharmony_ci~~~~~~~~~~~~
2768c2ecf20Sopenharmony_ci
2778c2ecf20Sopenharmony_ci::
2788c2ecf20Sopenharmony_ci
2798c2ecf20Sopenharmony_ci    QUERY = 43 ('C')lose
2808c2ecf20Sopenharmony_ci
2818c2ecf20Sopenharmony_ciNo data returned.
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_ciQuery effect
2848c2ecf20Sopenharmony_ci~~~~~~~~~~~~
2858c2ecf20Sopenharmony_ci
2868c2ecf20Sopenharmony_ci::
2878c2ecf20Sopenharmony_ci
2888c2ecf20Sopenharmony_ci    QUERY = 45 ('E')
2898c2ecf20Sopenharmony_ci
2908c2ecf20Sopenharmony_ciSend effect type.
2918c2ecf20Sopenharmony_ciReturns nonzero if supported (2 bytes)
2928c2ecf20Sopenharmony_ci
2938c2ecf20Sopenharmony_ciFirmware Version
2948c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~
2958c2ecf20Sopenharmony_ci
2968c2ecf20Sopenharmony_ci::
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_ci    QUERY = 56 ('V'ersion)
2998c2ecf20Sopenharmony_ci
3008c2ecf20Sopenharmony_ciSends back 3 bytes - major, minor, subminor
3018c2ecf20Sopenharmony_ci
3028c2ecf20Sopenharmony_ciInitialisation of the device
3038c2ecf20Sopenharmony_ci^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3048c2ecf20Sopenharmony_ci
3058c2ecf20Sopenharmony_ciSet Control
3068c2ecf20Sopenharmony_ci~~~~~~~~~~~
3078c2ecf20Sopenharmony_ci
3088c2ecf20Sopenharmony_ci.. note::
3098c2ecf20Sopenharmony_ci    Device dependent, can be different on different models!
3108c2ecf20Sopenharmony_ci
3118c2ecf20Sopenharmony_ci::
3128c2ecf20Sopenharmony_ci
3138c2ecf20Sopenharmony_ci    OP=  40 <idx> <val> [<val>]
3148c2ecf20Sopenharmony_ci    LEN= 2 or 3
3158c2ecf20Sopenharmony_ci    00 Idx
3168c2ecf20Sopenharmony_ci       Idx 00 Set dead zone (0..2048)
3178c2ecf20Sopenharmony_ci       Idx 01 Ignore Deadman sensor (0..1)
3188c2ecf20Sopenharmony_ci       Idx 02 Enable comm watchdog (0..1)
3198c2ecf20Sopenharmony_ci       Idx 03 Set the strength of the spring (0..100)
3208c2ecf20Sopenharmony_ci       Idx 04 Enable or disable the spring (0/1)
3218c2ecf20Sopenharmony_ci       Idx 05 Set axis saturation threshold (0..2048)
3228c2ecf20Sopenharmony_ci
3238c2ecf20Sopenharmony_ciSet Effect State
3248c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~
3258c2ecf20Sopenharmony_ci
3268c2ecf20Sopenharmony_ci::
3278c2ecf20Sopenharmony_ci
3288c2ecf20Sopenharmony_ci    OP=  42 <val>
3298c2ecf20Sopenharmony_ci    LEN= 1
3308c2ecf20Sopenharmony_ci    00 State
3318c2ecf20Sopenharmony_ci       Bit 3 Pause force feedback
3328c2ecf20Sopenharmony_ci       Bit 2 Enable force feedback
3338c2ecf20Sopenharmony_ci       Bit 0 Stop all effects
3348c2ecf20Sopenharmony_ci
3358c2ecf20Sopenharmony_ciSet overall
3368c2ecf20Sopenharmony_ci~~~~~~~~~~~
3378c2ecf20Sopenharmony_ci
3388c2ecf20Sopenharmony_ci::
3398c2ecf20Sopenharmony_ci
3408c2ecf20Sopenharmony_ci    OP=  43 <val>
3418c2ecf20Sopenharmony_ci    LEN= 1
3428c2ecf20Sopenharmony_ci    00 Gain
3438c2ecf20Sopenharmony_ci       Val 00 = 0%
3448c2ecf20Sopenharmony_ci       Val 40 = 50%
3458c2ecf20Sopenharmony_ci       Val 80 = 100%
3468c2ecf20Sopenharmony_ci
3478c2ecf20Sopenharmony_ciParameter memory
3488c2ecf20Sopenharmony_ci----------------
3498c2ecf20Sopenharmony_ci
3508c2ecf20Sopenharmony_ciEach device has a certain amount of memory to store parameters of effects.
3518c2ecf20Sopenharmony_ciThe amount of RAM may vary, I encountered values from 200 to 1000 bytes. Below
3528c2ecf20Sopenharmony_ciis the amount of memory apparently needed for every set of parameters:
3538c2ecf20Sopenharmony_ci
3548c2ecf20Sopenharmony_ci - period : 0c
3558c2ecf20Sopenharmony_ci - magnitude : 02
3568c2ecf20Sopenharmony_ci - attack and fade : 0e
3578c2ecf20Sopenharmony_ci - interactive : 08
3588c2ecf20Sopenharmony_ci
3598c2ecf20Sopenharmony_ciAppendix: How to study the protocol?
3608c2ecf20Sopenharmony_ci====================================
3618c2ecf20Sopenharmony_ci
3628c2ecf20Sopenharmony_ci1. Generate effects using the force editor provided with the DirectX SDK, or
3638c2ecf20Sopenharmony_ciuse Immersion Studio (freely available at their web site in the developer section:
3648c2ecf20Sopenharmony_ciwww.immersion.com)
3658c2ecf20Sopenharmony_ci2. Start a soft spying RS232 or USB (depending on where you connected your
3668c2ecf20Sopenharmony_cijoystick/wheel). I used ComPortSpy from fCoder (alpha version!)
3678c2ecf20Sopenharmony_ci3. Play the effect, and watch what happens on the spy screen.
3688c2ecf20Sopenharmony_ci
3698c2ecf20Sopenharmony_ciA few words about ComPortSpy:
3708c2ecf20Sopenharmony_ciAt first glance, this software seems, hum, well... buggy. In fact, data appear with a
3718c2ecf20Sopenharmony_cifew seconds latency. Personally, I restart it every time I play an effect.
3728c2ecf20Sopenharmony_ciRemember it's free (as in free beer) and alpha!
3738c2ecf20Sopenharmony_ci
3748c2ecf20Sopenharmony_ciURLS
3758c2ecf20Sopenharmony_ci====
3768c2ecf20Sopenharmony_ci
3778c2ecf20Sopenharmony_ciCheck http://www.immerse.com for Immersion Studio,
3788c2ecf20Sopenharmony_ciand http://www.fcoder.com for ComPortSpy.
3798c2ecf20Sopenharmony_ci
3808c2ecf20Sopenharmony_ci
3818c2ecf20Sopenharmony_ciI-Force is trademark of Immersion Corp.
382