From e07d12e285c5f7c3abcac12fb8413f532e846124 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 10 Jun 2005 20:17:42 +0000 Subject: - got ff_autocenter and ff_gain working fine, now its time for some actual effects!! svn path=/trunk/externals/hcs/hid/; revision=3164 --- Makefile | 16 +++-- TODO | 6 +- hid.c | 13 +++++ hid.h | 42 +++++++++---- hid_darwin.c | 188 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 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 #include "HID_Utilities_External.h" +#include "ImmrHIDUtilAddOn.h" #include #include @@ -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 ); + } } -- cgit v1.2.1