PDA

View Full Version : How to create force feedback Effect?



Attapong
11-09-2004, 07:48 AM
when I use
hr := g_pJoystick.CreateEffect(GUID_ConstantForce,@eff,g _pEffect,Nil);
it return -2147024809 to hr. How can I fix it.
I use clootie Directx9.0c header.
Sorry for my bad english I come from Thailand. 0^0
**************************************************

function TJoyst.InitDirectInput: HRESULT;
var hr: HRESULT;
diprg: TDIPROPDWORD;
rgdwAxes: Array[0..1] of DWORD;
rglDirection: Array[0..1] of LongInt;
cf : Array[0..0] of DICONSTANTFORCE;
eff : DIEFFECT;
begin
// Register with the DirectInput subsystem and get a pointer
// to a IDirectInput interface we can use.
// Create a DInput object
hr := DirectInput8Create( HInstance, DIRECTINPUT_VERSION,
IID_IDirectInput8, g_pDI, nil );
if FAILED( hr ) then
begin
Result := hr;
Exit;
end;

// Look for a simple joystick we can use for this sample program.
hr := g_pDI.EnumDevices( DI8DEVCLASS_GAMECTRL,
EnumFFDevicesCallback,
nil,DIEDFL_ATTACHEDONLY or DIEDFL_FORCEFEEDBACK );
if FAILED( hr ) then
begin
Result := hr;
Application.MessageBox( 'Force feedback device not found. The sample will now exit.',
'DirectInput Sample',
MB_ICONERROR or MB_OK );
Exit;
end;

// Make sure we got a joystick
if g_pJoystick = nil then
begin
Application.MessageBox( 'Joystick not found. The sample will now exit.',
'DirectInput Sample',
MB_ICONERROR or MB_OK );

Close;
Result := S_OK;
Exit;
end;

// Set the data format to "simple joystick" - a predefined data format
//
// A data format specifies which controls on a device we are interested in,
// and how they should be reported. This tells DInput that we will be
// passing a DIJOYSTATE2 structure to IDirectInputDevice::GetDeviceState().
hr := g_pJoystick.SetDataFormat( c_dfDIJoystick );
if FAILED( hr ) then
begin
Result := hr;
Exit;
end;

// Set the cooperative level to let DInput know how this device should
// interact with the system and with other DInput applications.
hr := g_pJoystick.SetCooperativeLevel( Handle, DISCL_EXCLUSIVE or DISCL_FOREGROUND );
if FAILED( hr ) then
begin
Result := hr;
Exit;
end;
diprg.diph.dwSize := sizeof(TDIPROPDWORD);
diprg.diph.dwHeaderSize := sizeof(TDIPropHeader);
diprg.diph.dwHow := DIPH_DEVICE;
diprg.diph.dwObj := 0; // Specify the enumerated axis
diprg.dwData := 0;
// Set the range for the axis
hr := g_pJoystick.SetProperty( DIPROP_AUTOCENTER, diprg.diph );
if FAILED( hr ) then
begin
Result := hr;
Exit;
end;
// Enumerate the axes of the joyctick and set the range of each axis. Note:
// we could just use the defaults, but we're just trying to show an example
// of enumerating device objects (axes, buttons, etc.).
g_pJoystick.EnumObjects( EnumAxesCallback,@g_dwNumForceFeedbackAxis, DIDFT_AXIS );
if FAILED( hr ) then
begin
Result := hr;
Exit;
end;
if( g_dwNumForceFeedbackAxis > 2 ) then
g_dwNumForceFeedbackAxis := 2;
// Determine how many axis the joystick has (so we don't error out setting
// properties for unavailable axis)
rgdwAxes[0] := DIJOFS_X;
rgdwAxes[1] := DIJOFS_Y;
rglDirection[0]:= 0;
rglDirection[1]:= 0;
//cf[0] := ;
ZeroMemory( @eff, sizeof(eff) );
eff.dwSize := sizeof(DIEFFECT);
eff.dwFlags := DIEFF_CARTESIAN or DIEFF_OBJECTOFFSETS;
eff.dwDuration := INFINITE;
eff.dwSamplePeriod := 0;
eff.dwGain := DI_FFNOMINALMAX;
eff.dwTriggerButton := DIEB_NOTRIGGER;
eff.dwTriggerRepeatInterval := 0;
eff.cAxes := g_dwNumForceFeedbackAxis;
eff.rgdwAxes := @rgdwAxes;
eff.rglDirection := @rglDirection;
eff.lpEnvelope := 0;
eff.cbTypeSpecificParams := sizeof(DICONSTANTFORCE);
eff.lpvTypeSpecificParams := @cf;
//eff.dwStartDelay := 0;
g_diDevCaps.dwSize := SizeOf(TDIDevCaps);
hr := g_pJoystick.CreateEffect( GUID_ConstantForce,@eff,g_pEffect,Nil);
if FAILED( hr ) then
begin
Result := hr;
Exit;
end;



Result := S_OK;
end;

Useless Hacker
11-09-2004, 12:15 PM
That HRESULT means: "E_INVALIDARG - An invalid parameter was passed to the returning function", but beyond that I cannot help. (You can use the DXErr9 unit to get names/descriptions of errors.)

Clootie
11-09-2004, 12:28 PM
Your error code is:


HRESULT: 0x80070057 (2147942487)
Name: E_INVALIDARG
Description: An invalid parameter was passed to the returning function
Severity code: Failed
Facility Code: FACILITY_WIN32 (7)
Error Code: 0x0057 (87)


Try calling CreateEffect with NIL DIEFFECT:
Result := g_pJoystick.CreateEffect(GUID_ConstantForce, nil, g_pEffect, nil);
if FAILED(Result) then Exit;
If this succeeded then error is in customizing your DIEFFECT record.

Attapong
11-09-2004, 01:46 PM
Thanks alot, I will try do with your answer and it seem work. (Sory for my bad english again ^*^)

Attapong
12-09-2004, 06:51 PM
Try calling CreateEffect with NIL DIEFFECT:
Pascal Code:
Result := g_pJoystick.CreateEffect(GUID_ConstantForce, nil, g_pEffect, nil);
if FAILED(Result) then Exit;

If this succeeded then error is in customizing your DIEFFECT record.
************************************************** ******
How I create DIEFFECT record ?
I will try alot of any way to solve this problem but it not work.

Clootie
12-09-2004, 09:06 PM
have you tried this:
ZeroMemory( @eff, sizeof(eff) );
eff.dwSize := sizeof(DIEFFECT);
eff.dwFlags := DIEFF_CARTESIAN or DIEFF_OBJECTOFFSETS;
eff.dwDuration := INFINITE;
eff.dwSamplePeriod := 0;
eff.dwGain := DI_FFNOMINALMAX;
eff.dwTriggerButton := DIEB_NOTRIGGER;
eff.dwTriggerRepeatInterval := 0;
eff.cAxes := g_dwNumForceFeedbackAxis;
eff.rgdwAxes := rgdwAxes; // <- !!!
eff.rglDirection := rglDirection; // <- !!!
eff.lpEnvelope := 0;
eff.cbTypeSpecificParams := sizeof(DICONSTANTFORCE);
eff.lpvTypeSpecificParams := @cf;
eff.dwStartDelay := 0; // <- !!!

Attapong
13-09-2004, 02:04 PM
1)
if I change
eff.rgdwAxes :=@ rgdwAxes;
eff.rglDirection := @rglDirection;
to
eff.rgdwAxes := rgdwAxes;
eff.rglDirection := rglDirection;
delphi 6 tell me at Incompatible types 'Array' and 'PDWORD'.
(I use Delphi6 with windows XP)

2) Why DIEFFECT Structor haven't dwStartDelay option in Directinput.pas (clootie source)
******** So sorry for my bad english again *******

Clootie
13-09-2004, 07:20 PM
Yes!!! Seems bug is in definition of DIEFFECT in DirectInput.pas! :roll: Do you have debug DirectX runtime installed (it's included with MS DirectX SDK)? Have you seen any error messages in output LOG?

It's really weird: althrow MS defined that there was no version 6 of DInput, but actually had some changes in headers...

Current Workaround:
1) Use headers from JEDI sub-dir
2) manually define "DIRECTINPUT_VERSION_6" conditional (in project options dlg).

Or just use updated headers from CVS: http://cvs.sourceforge.net/viewcvs.py/delphi-dx9sdk/Headers. Warning: web-mirror of CVS is updated with some delay (up to 12 hours, but usially earlier)

Attapong
13-09-2004, 07:52 PM
1) Use headers from JEDI sub-dir .
*****************
OK. I try use JEDI header (this header have dwStartDelay option in DIEFFECT structor. :o

2) manually define "DIRECTINPUT_VERSION_6" conditional (in project options dlg).
I will try to do. :roll:

Or just use updated headers from CVS: http://cvs.sourceforge.net/viewcvs.py/delphi-dx9sdk/Headers .
I download new header from http://clootie.narod.ru/delphi/download_dx92.html in last night. Are there same header?

this my source code link (but still problem when try to use forcefeedback ) :oops:
http://berry.cpe.mut.ac.th/~comclub/FFB.EXE(56k)
http://berry.cpe.mut.ac.th/~comclub/problem.jpg

Clootie
13-09-2004, 08:32 PM
I download new header from http://clootie.narod.ru/delphi/download_dx92.html in last night. Are there same header?
nope, CVS should have updated version (labeled as 1.2)

Sorry, I don't have any force feedback joysticks, so can't test your program.

To be sure you compiling to correct code, just edit your existent DirectInput.pas so it will look like this: [background=#FFFFFF][normal=#000000][number=#0000FF][string=#0000FF][comment=#248F24][reserved=#000000] DIEFFECT = packed record
dwSize: DWORD; (* sizeof(DIEFFECT) *)
dwFlags: DWORD; (* DIEFF_* *)
dwDuration: DWORD; (* Microseconds *)
dwSamplePeriod: DWORD; (* Microseconds *)
dwGain: DWORD;
dwTriggerButton: DWORD; (* or DIEB_NOTRIGGER *)
dwTriggerRepeatInterval: DWORD; (* Microseconds *)
cAxes: DWORD; (* Number of axes *)
rgdwAxes: PDWORD; (* Array of axes *)
rglDirection: PLongint; (* Array of directions *)
lpEnvelope: PDIEnvelope; (* Optional *)
cbTypeSpecificParams: DWORD; (* Size of params *)
lpvTypeSpecificParams: Pointer; (* Pointer to params *)
//{$IFDEF DIRECTINPUT_VERSION_6}
dwStartDelay: DWORD; (* Microseconds *)
//{$ENDIF} (* DIRECTINPUT_VERSION >= 0x0600 *)
end;


PS. "DIEFFECT structor" -> "DIEFFECT structure"?

Attapong
13-09-2004, 09:09 PM
:shock: So sory for my bad english again :oops: :oops: :lol: :lol:

structure structure structure structure structure structure structure structure structure structure structure structure structure structure
structure structure structure structure structure structure structure structure structure structure structure structure structure sructure structure structure structure structure structure structure structure structure structure structure structure structure structure structure

OK. I remeber that :wink:

Attapong
14-09-2004, 12:00 AM
OK. I download new header from CVS but it require d3dx9xofab.dll file.
Where download this file?

------------------------------------------------------------------------------
To be sure you compiling to correct code, just edit your existent DirectInput.pas so it will look like this: Pascal Code:
DIEFFECT = packed record
dwSize: DWORD; (* sizeof(DIEFFECT) *)
dwFlags: DWORD; (* DIEFF_* *)
dwDuration: DWORD; (* Microseconds *)
dwSamplePeriod: DWORD; (* Microseconds *)
dwGain: DWORD;
dwTriggerButton: DWORD; (* or DIEB_NOTRIGGER *)
dwTriggerRepeatInterval: DWORD; (* Microseconds *)
cAxes: DWORD; (* Number of axes *)
rgdwAxes: PDWORD; (* Array of axes *)
rglDirection: PLongint; (* Array of directions *)
lpEnvelope: PDIEnvelope; (* Optional *)
cbTypeSpecificParams: DWORD; (* Size of params *)
lpvTypeSpecificParams: Pointer; (* Pointer to params *)
//{$IFDEF DIRECTINPUT_VERSION_6}
dwStartDelay: DWORD; (* Microseconds *)
//{$ENDIF} (* DIRECTINPUT_VERSION >= 0x0600 *)
end;

Sure. My compiling to correct code.

Clootie
14-09-2004, 08:49 PM
Ok, download updated headers once more. Now official release is available (dated 14-Sep-2004). Available both at SourceForge (http://sourceforge.net/projects/delphi-dx9sdk) file release system and clootie.narod.ru.

In these headers D3DX9File unit is intergated in d3dx9.pas and don't require specail DLL, just default d3dx92ab.dll.

Attapong
15-09-2004, 05:16 PM
Thanks. :o

Attapong
17-09-2004, 07:54 PM
Every one can download my finished code at http://berry.cpe.mut.ac.th/~comclub/FF.exe (219 K Byte include source and EXE file)
*************************************************
Thanks alot for clootie you are great person for me. 8) .
I hope you can fix my source code to right gramma in delphi standart source code and send that to public.
*************************************************
sorry for my bad english again. :oops: