aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans-Christoph Steiner <eighthave@users.sourceforge.net>2005-06-10 20:17:42 +0000
committerHans-Christoph Steiner <eighthave@users.sourceforge.net>2005-06-10 20:17:42 +0000
commite07d12e285c5f7c3abcac12fb8413f532e846124 (patch)
tree3270d3d380fffe8a25b1af187ba4cc8db23f4900
parent3252d2cc2c0759898c2d5b3f2ccf228e780406c5 (diff)
- got ff_autocenter and ff_gain working fine, now its time for some actual
effects!! svn path=/trunk/externals/hcs/hid/; revision=3164
-rw-r--r--Makefile16
-rw-r--r--TODO6
-rw-r--r--hid.c13
-rw-r--r--hid.h42
-rw-r--r--hid_darwin.c188
5 files changed, 236 insertions, 29 deletions
diff --git a/Makefile b/Makefile
index c454bdd..e0e340f 100644
--- a/Makefile
+++ b/Makefile
@@ -21,7 +21,7 @@ LDFLAGS = -bundle -bundle_loader $(PDEXECUTABLE) \
$(patsubst %,-framework %,$(FRAMEWORKS))
.SUFFIXES: .pd_darwin
-all: input_arrays pd_darwin
+all: input_arrays hid_utilities pd_darwin
pd_darwin: hid.pd_darwin
endif
@@ -31,9 +31,11 @@ endif
PDEXECUTABLE = ../../../pd/bin/pd
# generic optimization
-OPT_FLAGS = -O3
-# G4 7450 optimization (gives errors)
-#OPT_FLAGS = -fast -mcpu=7450 -maltivec
+#OPT_FLAGS = -O3 -ffast-math
+# G4 optimization
+OPT_FLAGS = -O3 -mcpu=7400 -faltivec -ffast-math -fPIC
+# faster G4 7450 optimization (gives errors)
+#OPT_FLAGS = -ffast -mcpu=7450 -faltivec -ffast-math -fPIC
CFLAGS = $(OPT_FLAGS) -Wall -W -Wno-shadow -Wstrict-prototypes -Wno-unused
@@ -48,11 +50,13 @@ INCLUDE = -I./ -I../../../pd/src -I./HID\ Utilities\ Source
.o.pd_linux:
ld $(LDFLAGS) -o $*.pd_linux *.o -lc -lm
strip --strip-unneeded $*.pd_linux
-# rm $*.o
input_arrays:
- ./make-arrays-from-input.h.pl
+ test -f input_arrays.h || ./make-arrays-from-input.h.pl
+hid_utilities:
+ test -f ./HID\ Utilities\ Source/build/libHIDUtilities.a || \
+ ( cd ./HID\ Utilities\ Source && pbxbuild )
clean: ; rm -f *.pd_* *.o *~ input_arrays.? doc/ev*-list.pd
diff --git a/TODO b/TODO
index 487ccb9..1e63c7d 100644
--- a/TODO
+++ b/TODO
@@ -27,11 +27,9 @@ by # (1,2,...), generic name (mouse1, joystick2, tablet3...), or device name
==============================================================================
-= make second outlet for device name
+= Report available FF effects
-just output the USB device name to the second outlet
-
-- maybe the manufacturer too?
+- check against HID Utilities Source/PID.h
diff --git a/hid.c b/hid.c
index 2509d7b..4d01ef5 100644
--- a/hid.c
+++ b/hid.c
@@ -238,6 +238,7 @@ static void *hid_new(t_float f)
#endif
/* init vars */
+ x->x_has_ff = 0;
x->x_device_open = 0;
x->x_started = 0;
x->x_delay = DEFAULT_DELAY;
@@ -285,5 +286,17 @@ void hid_setup(void)
class_addmethod(hid_class,(t_method) hid_start,gensym("poll"),A_DEFFLOAT,0);
class_addmethod(hid_class,(t_method) hid_stop,gensym("stop"),0);
class_addmethod(hid_class,(t_method) hid_stop,gensym("nopoll"),0);
+ /* force feedback messages */
+ class_addmethod(hid_class,(t_method) hid_ff_autocenter,
+ gensym("ff_autocenter"),A_DEFFLOAT,0);
+ class_addmethod(hid_class,(t_method) hid_ff_gain,gensym("ff_gain"),A_DEFFLOAT,0);
+ class_addmethod(hid_class,(t_method) hid_ff_motors,gensym("ff_motors"),A_DEFFLOAT,0);
+ class_addmethod(hid_class,(t_method) hid_ff_continue,gensym("ff_continue"),0);
+ class_addmethod(hid_class,(t_method) hid_ff_pause,gensym("ff_pause"),0);
+ class_addmethod(hid_class,(t_method) hid_ff_reset,gensym("ff_reset"),0);
+ class_addmethod(hid_class,(t_method) hid_ff_stopall,gensym("ff_stopall"),0);
+ /* ff tests */
+ class_addmethod(hid_class,(t_method) hid_ff_fftest,gensym("fftest"),A_DEFFLOAT,0);
+ class_addmethod(hid_class,(t_method) hid_ff_print,gensym("ff_print"),0);
}
diff --git a/hid.h b/hid.h
index c83363d..d1b707b 100644
--- a/hid.h
+++ b/hid.h
@@ -14,7 +14,7 @@
#define HID_MAJOR_VERSION 0
#define HID_MINOR_VERSION 5
-static char *version = "$Revision: 1.15 $";
+static char *version = "$Revision: 1.16 $";
/*------------------------------------------------------------------------------
* CLASS DEF
@@ -26,6 +26,8 @@ typedef struct _hid
t_object x_obj;
t_int x_fd;
t_int x_device_number;
+ t_int x_has_ff;
+ void *x_ff_device;
t_clock *x_clock;
t_int x_delay;
t_int x_started;
@@ -58,14 +60,34 @@ t_int hid_instance_count;
*/
/* support functions */
-void hid_output_event(t_hid *x, char *type, char *code, t_float value);
-
-/* generic, cross-platform functions */
-t_int hid_open_device(t_hid *x, t_int device_number);
-t_int hid_close_device(t_hid *x);
-t_int hid_build_device_list(t_hid* x);
-t_int hid_get_events(t_hid *x) ;
-void hid_print(t_hid* x);
-void hid_platform_specific_free(t_hid *x);
+void hid_output_event( t_hid *x, char *type, char *code, t_float value );
+
+/* generic, cross-platform functions implemented in a separate file for each
+ * platform
+ */
+t_int hid_open_device( t_hid *x, t_int device_number );
+t_int hid_close_device( t_hid *x );
+t_int hid_build_device_list( t_hid* x );
+t_int hid_get_events( t_hid *x ) ;
+void hid_print( t_hid* x );
+void hid_platform_specific_free( t_hid *x );
+
+/* cross-platform force feedback functions */
+t_int hid_ff_autocenter( t_hid *x, t_float value );
+t_int hid_ff_gain( t_hid *x, t_float value );
+t_int hid_ff_motors( t_hid *x, t_float value );
+t_int hid_ff_continue( t_hid *x );
+t_int hid_ff_pause( t_hid *x );
+t_int hid_ff_reset( t_hid *x );
+t_int hid_ff_stopall( t_hid *x );
+// these are just for testing...
+t_int hid_ff_fftest ( t_hid *x, t_float value);
+
+#include "HID_Utilities_External.h"
+void hid_ff_print( t_hid *x );
+
+
+
+
#endif /* #ifndef _HID_H */
diff --git a/hid_darwin.c b/hid_darwin.c
index a8f03b2..6d413f8 100644
--- a/hid_darwin.c
+++ b/hid_darwin.c
@@ -43,6 +43,7 @@
#include <Carbon/Carbon.h>
#include "HID_Utilities_External.h"
+#include "ImmrHIDUtilAddOn.h"
#include <IOKit/hid/IOHIDUsageTables.h>
#include <ForceFeedback/ForceFeedback.h>
@@ -207,10 +208,9 @@ void hid_build_element_list(t_hid *x)
}
-
t_int hid_print_element_list(t_hid *x)
{
- DEBUG(post("hid_build_element_list"););
+ DEBUG(post("hid_print_element_list"););
UInt32 i;
pRecElement pCurrentHIDElement;
@@ -262,12 +262,37 @@ t_int hid_print_element_list(t_hid *x)
}
+void hid_ff_print( t_hid *x )
+{
+ DEBUG(post("hid_ff_print"););
+ HRESULT result;
+ UInt32 value;
+
+ if ( x->x_has_ff )
+ {
+ result = FFDeviceGetForceFeedbackProperty( (FFDeviceObjectReference) x->x_ff_device,
+ FFPROP_AUTOCENTER,
+ &value,
+ (IOByteCount) sizeof( value ) );
+ if ( result == FF_OK ) post( "autocenter: %d",value );
+
+ result = FFDeviceGetForceFeedbackProperty( (FFDeviceObjectReference) x->x_ff_device,
+ FFPROP_FFGAIN,
+ &value,
+ (IOByteCount) sizeof( value ) );
+ if ( result == FF_OK ) post( "gain: %d", value );
+ }
+
+// FFEffectGetParameters( );
+}
+
+
void hid_print_device_list(t_hid *x)
{
char cstrDeviceName [256];
t_int i,numdevs;
UInt32 usagePage, usage;
- pRecDevice pCurrentHIDDevice;
+ pRecDevice pCurrentHIDDevice = NULL;
if( HIDHaveDeviceList() )
{
@@ -308,6 +333,139 @@ void hid_output_device_name(t_hid *x, char *manufacturer, char *product)
outlet_symbol( x->x_device_name_outlet, gensym( device_name ) );
}
+/* ==============================================================================
+ * FORCE FEEDBACK
+ * ============================================================================== */
+
+/* --------------------------------------------------------------------------
+ * FF "Properties"
+ * autocenter ( 0/1 ), ffgain (overall feedback gain 0-10000)
+ */
+
+t_int hid_ff_autocenter(t_hid *x, t_float value)
+{
+ DEBUG(post("hid_ff_autocenter"););
+ HRESULT result;
+ UInt32 autocenter_value;
+
+ if( x->x_has_ff )
+ {
+ if ( value > 0 ) autocenter_value = 1;
+ else if ( value <= 0 ) autocenter_value = 0;
+ /* FFPROP_AUTOCENTER is either 0 or 1 */
+ result = FFDeviceSetForceFeedbackProperty(
+ (FFDeviceObjectReference) x->x_ff_device,
+ FFPROP_AUTOCENTER,
+ &autocenter_value );
+ if ( result != FF_OK )
+ {
+ post("[hid]: ff_autocenter failed!");
+ }
+ }
+
+ return(0);
+}
+
+t_int hid_ff_gain(t_hid *x, t_float value)
+{
+ DEBUG(post("hid_ff_gain"););
+ HRESULT result;
+ UInt32 ffgain_value;
+
+ if( x->x_has_ff )
+ {
+ if ( value > 1 ) value = 1;
+ else if ( value < 0 ) value = 0;
+ ffgain_value = value * 10000;
+ /* FFPROP_FFGAIN has a integer range of 0-10000 */
+ result = FFDeviceSetForceFeedbackProperty(
+ (FFDeviceObjectReference)x->x_ff_device, FFPROP_FFGAIN, &ffgain_value );
+ if ( result != FF_OK )
+ {
+ post("[hid]: ff_gain failed!");
+ }
+ }
+
+ return(0);
+}
+
+/* --------------------------------------------------------------------------
+ * FF "Commands"
+ * continue, pause, reset, setactuatorsoff, setactuatorson, stopall
+ */
+
+t_int hid_ff_send_ff_command (t_hid *x, UInt32 ff_command)
+{
+ HRESULT result = 0;
+
+ if( x->x_has_ff )
+ {
+ result = FFDeviceSendForceFeedbackCommand( x->x_ff_device, ff_command );
+ }
+
+ return ( (t_int) result );
+}
+
+t_int hid_ff_continue( t_hid *x )
+{
+ DEBUG(post("hid_ff_continue"););
+ return( hid_ff_send_ff_command( x, FFSFFC_CONTINUE ) );
+}
+
+t_int hid_ff_pause( t_hid *x )
+{
+ DEBUG(post("hid_ff_pause"););
+ return( hid_ff_send_ff_command( x, FFSFFC_PAUSE ) );
+}
+
+t_int hid_ff_reset( t_hid *x )
+{
+ DEBUG(post("hid_ff_reset"););
+ return( hid_ff_send_ff_command( x, FFSFFC_RESET ) );
+}
+
+t_int hid_ff_setactuatorsoff( t_hid *x )
+{
+ DEBUG(post("hid_ff_setactuatorsoff"););
+ return( hid_ff_send_ff_command( x, FFSFFC_SETACTUATORSOFF ) );
+}
+
+t_int hid_ff_setactuatorson( t_hid *x )
+{
+ DEBUG(post("hid_ff_setactuatorson"););
+ return( hid_ff_send_ff_command( x, FFSFFC_SETACTUATORSON ) );
+}
+
+t_int hid_ff_stopall( t_hid *x )
+{
+ DEBUG(post("hid_ff_stopall"););
+ return( hid_ff_send_ff_command( x, FFSFFC_STOPALL ) );
+}
+
+t_int hid_ff_motors( t_hid *x, t_float value )
+{
+ if ( value > 0 )
+ {
+ return ( hid_ff_setactuatorson( x ) );
+ }
+ else
+ {
+ return ( hid_ff_setactuatorsoff( x ) );
+ }
+}
+
+
+/* --------------------------------------------------------------------------
+ * FF test functions
+ */
+
+t_int hid_ff_fftest ( t_hid *x, t_float value)
+{
+ DEBUG(post("hid_get_events"););
+
+ return( 0 );
+}
+
/* ============================================================================== */
/* Pd [hid] FUNCTIONS */
/* ============================================================================== */
@@ -471,7 +629,7 @@ t_int hid_open_device(t_hid *x, t_int device_number)
pRecDevice pCurrentHIDDevice = NULL;
io_service_t hidDevice = NULL;
- FFDeviceObjectReference *pDeviceReference = NULL;
+ FFDeviceObjectReference ffDeviceReference = NULL;
/* rebuild device list to make sure the list is current */
if ( ! HIDHaveDeviceList() )
@@ -499,12 +657,20 @@ t_int hid_open_device(t_hid *x, t_int device_number)
hid_build_element_list(x);
+ hidDevice = AllocateHIDObjectFromRecDevice( pCurrentHIDDevice );
if ( FFIsForceFeedback(hidDevice) == FF_OK )
{
- post("device has Force Feedback support");
- if ( FFCreateDevice(hidDevice,pDeviceReference) == FF_OK )
+ post("\tdevice has Force Feedback support");
+ if ( FFCreateDevice(hidDevice,&ffDeviceReference) == FF_OK )
{
- post("created FF device");
+ x->x_has_ff = 1;
+ x->x_ff_device = ffDeviceReference;
+ }
+ else
+ {
+ x->x_has_ff = 0;
+ post("[hid]: FF device creation failed!");
+ return( -1 );
}
}
@@ -548,7 +714,8 @@ t_int hid_build_device_list(t_hid *x)
pCurrentHIDDevice = HIDGetFirstDevice();
while ( pCurrentHIDDevice != NULL )
{
- hid_output_device_name( x, pCurrentHIDDevice->manufacturer, pCurrentHIDDevice->product );
+ hid_output_device_name( x, pCurrentHIDDevice->manufacturer,
+ pCurrentHIDDevice->product );
pCurrentHIDDevice = HIDGetNextDevice(pCurrentHIDDevice);
}
@@ -560,8 +727,11 @@ void hid_print(t_hid *x)
{
hid_print_device_list(x);
- if(x->x_device_open)
+ if(x->x_device_open)
+ {
hid_print_element_list(x);
+ hid_ff_print( x );
+ }
}