Files
Client/Library/dxx8/samples/Multimedia/VBSamples/DirectInput/Feedback/ForceFeedback.frm
LGram16 e067522598 Initial commit: ROW Client source code
Game client codebase including:
- CharacterActionControl: Character and creature management
- GlobalScript: Network, items, skills, quests, utilities
- RYLClient: Main client application with GUI and event handlers
- Engine: 3D rendering engine (RYLGL)
- MemoryManager: Custom memory allocation
- Library: Third-party dependencies (DirectX, boost, etc.)
- Tools: Development utilities

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 16:24:34 +09:00

1482 lines
64 KiB
Plaintext

VERSION 5.00
Object = "{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}#2.0#0"; "MSCOMCTL.OCX"
Begin VB.Form frmForceFeedback
BorderStyle = 3 'Fixed Dialog
Caption = "VB Force Feedback"
ClientHeight = 7020
ClientLeft = 45
ClientTop = 330
ClientWidth = 9315
Icon = "ForceFeedback.frx":0000
LinkTopic = "Form1"
MaxButton = 0 'False
MinButton = 0 'False
ScaleHeight = 7020
ScaleWidth = 9315
StartUpPosition = 2 'CenterScreen
Begin VB.Frame frameDirection
Caption = "Direction"
Height = 2895
Left = 6720
TabIndex = 70
Top = 3960
Width = 2415
Begin VB.OptionButton optDirection
Caption = "Option1"
Height = 210
Index = 0
Left = 1080
TabIndex = 78
Top = 480
Value = -1 'True
Width = 200
End
Begin VB.OptionButton optDirection
Caption = "Option2"
Height = 210
Index = 4
Left = 1080
TabIndex = 77
Top = 2280
Width = 200
End
Begin VB.OptionButton optDirection
Caption = "Option3"
Height = 210
Index = 6
Left = 240
TabIndex = 76
Top = 1380
Width = 200
End
Begin VB.OptionButton optDirection
Caption = "Option4"
Height = 210
Index = 2
Left = 1920
TabIndex = 75
Top = 1320
Width = 200
End
Begin VB.OptionButton optDirection
Caption = "Option5"
Height = 210
Index = 7
Left = 480
TabIndex = 74
Top = 840
Width = 200
End
Begin VB.OptionButton optDirection
Caption = "Option6"
Height = 210
Index = 1
Left = 1680
TabIndex = 73
Top = 840
Width = 200
End
Begin VB.OptionButton optDirection
Caption = "Option7"
Height = 210
Index = 5
Left = 480
TabIndex = 72
Top = 1920
Width = 200
End
Begin VB.OptionButton optDirection
Caption = "Option8"
Height = 210
Index = 3
Left = 1680
TabIndex = 71
Top = 1920
Width = 200
End
End
Begin VB.Frame frameEnvelope
Caption = "Envelope"
Height = 2895
Left = 3720
TabIndex = 56
Top = 3960
Width = 2775
Begin MSComctlLib.Slider sldEnvelope
Height = 255
Index = 0
Left = 240
TabIndex = 58
Top = 855
Width = 2295
_ExtentX = 4048
_ExtentY = 450
_Version = 393216
LargeChange = 100
SmallChange = 10
Max = 10000
SelStart = 10000
TickFrequency = 1000
Value = 10000
End
Begin VB.CheckBox chkEnvelope
Caption = "Use envelope"
Height = 255
Left = 720
TabIndex = 57
Top = 280
Width = 1335
End
Begin MSComctlLib.Slider sldEnvelope
Height = 255
Index = 1
Left = 240
TabIndex = 59
Top = 1380
Width = 2295
_ExtentX = 4048
_ExtentY = 450
_Version = 393216
LargeChange = 10000
SmallChange = 1000
Max = 5000000
TickFrequency = 500000
End
Begin MSComctlLib.Slider sldEnvelope
Height = 255
Index = 2
Left = 240
TabIndex = 60
Top = 1965
Width = 2295
_ExtentX = 4048
_ExtentY = 450
_Version = 393216
LargeChange = 100
SmallChange = 10
Max = 10000
SelStart = 10000
TickFrequency = 1000
Value = 10000
End
Begin MSComctlLib.Slider sldEnvelope
Height = 255
Index = 3
Left = 240
TabIndex = 61
Top = 2520
Width = 2295
_ExtentX = 4048
_ExtentY = 450
_Version = 393216
LargeChange = 1000
SmallChange = 100
Max = 5000000
TickFrequency = 500000
End
Begin VB.Label lblEnvelope
AutoSize = -1 'True
Caption = "0"
Height = 195
Index = 3
Left = 1440
TabIndex = 69
Top = 2325
Width = 90
End
Begin VB.Label lblEnvelope
AutoSize = -1 'True
Caption = "10000"
Height = 195
Index = 2
Left = 1440
TabIndex = 68
Top = 1740
Width = 450
End
Begin VB.Label lblEnvelope
AutoSize = -1 'True
Caption = "0"
Height = 195
Index = 1
Left = 1440
TabIndex = 67
Top = 1170
Width = 90
End
Begin VB.Label lblEnvelope
AutoSize = -1 'True
Caption = "10000"
Height = 195
Index = 0
Left = 1440
TabIndex = 66
Top = 600
Width = 450
End
Begin VB.Label Label20
AutoSize = -1 'True
Caption = "Fade Time:"
Height = 195
Left = 510
TabIndex = 65
Top = 2325
Width = 795
End
Begin VB.Label Label19
AutoSize = -1 'True
Caption = "Fade Level:"
Height = 195
Left = 465
TabIndex = 64
Top = 1740
Width = 840
End
Begin VB.Label Label18
AutoSize = -1 'True
Caption = "Attack Time:"
Height = 195
Left = 405
TabIndex = 63
Top = 1170
Width = 900
End
Begin VB.Label Label17
AutoSize = -1 'True
Caption = "Attack Level:"
Height = 195
Left = 360
TabIndex = 62
Top = 600
Width = 945
End
End
Begin VB.Frame frameTypeContainer
Caption = "Type-Specific Parameters"
Height = 3495
Left = 3720
TabIndex = 12
Top = 240
Width = 5415
Begin VB.Frame frameCondition
Caption = "Conditional Force"
Height = 3015
Left = 120
TabIndex = 37
Top = 240
Visible = 0 'False
Width = 5175
Begin VB.OptionButton optConditionAxis
Caption = "Y Axis"
Height = 255
Index = 1
Left = 2280
TabIndex = 80
Top = 2700
Width = 735
End
Begin VB.OptionButton optConditionAxis
Caption = "X Axis"
Height = 255
Index = 0
Left = 2280
TabIndex = 79
Top = 2440
Value = -1 'True
Width = 735
End
Begin MSComctlLib.Slider sldCondition
Height = 255
Index = 0
Left = 240
TabIndex = 38
Top = 600
Width = 2055
_ExtentX = 3625
_ExtentY = 450
_Version = 393216
LargeChange = 100
SmallChange = 10
Max = 10000
TickFrequency = 1000
End
Begin MSComctlLib.Slider sldCondition
Height = 255
Index = 1
Left = 240
TabIndex = 39
Top = 1320
Width = 2055
_ExtentX = 3625
_ExtentY = 450
_Version = 393216
LargeChange = 100
SmallChange = 10
Min = -10000
Max = 10000
TickFrequency = 1000
End
Begin MSComctlLib.Slider sldCondition
Height = 255
Index = 2
Left = 240
TabIndex = 40
Top = 2160
Width = 2055
_ExtentX = 3625
_ExtentY = 450
_Version = 393216
LargeChange = 100
SmallChange = 10
Max = 10000
SelStart = 10000
TickFrequency = 1000
Value = 10000
End
Begin MSComctlLib.Slider sldCondition
Height = 255
Index = 3
Left = 2880
TabIndex = 41
Top = 600
Width = 2055
_ExtentX = 3625
_ExtentY = 450
_Version = 393216
LargeChange = 100
SmallChange = 10
Min = -10000
Max = 10000
TickFrequency = 1000
End
Begin MSComctlLib.Slider sldCondition
Height = 255
Index = 4
Left = 2880
TabIndex = 42
Top = 1320
Width = 2055
_ExtentX = 3625
_ExtentY = 450
_Version = 393216
LargeChange = 100
SmallChange = 10
Min = -10000
Max = 10000
TickFrequency = 1000
End
Begin MSComctlLib.Slider sldCondition
Height = 255
Index = 5
Left = 2880
TabIndex = 43
Top = 2160
Width = 2055
_ExtentX = 3625
_ExtentY = 450
_Version = 393216
LargeChange = 100
SmallChange = 10
Max = 10000
SelStart = 10000
TickFrequency = 1000
Value = 10000
End
Begin VB.Label Label11
AutoSize = -1 'True
Caption = "Dead band:"
Height = 195
Left = 240
TabIndex = 55
Top = 360
Width = 840
End
Begin VB.Label Label12
AutoSize = -1 'True
Caption = "Negative Coefficient:"
Height = 195
Left = 240
TabIndex = 54
Top = 1080
Width = 1455
End
Begin VB.Label Label13
AutoSize = -1 'True
Caption = "Negative Saturation:"
Height = 195
Left = 240
TabIndex = 53
Top = 1920
Width = 1455
End
Begin VB.Label Label14
AutoSize = -1 'True
Caption = "Offset:"
Height = 195
Left = 3120
TabIndex = 52
Top = 360
Width = 465
End
Begin VB.Label Label15
AutoSize = -1 'True
Caption = "Positive Coefficient:"
Height = 195
Left = 3000
TabIndex = 51
Top = 1080
Width = 1365
End
Begin VB.Label Label16
AutoSize = -1 'True
Caption = "Positive Saturation:"
Height = 195
Left = 3000
TabIndex = 50
Top = 1920
Width = 1365
End
Begin VB.Label lblCondition
AutoSize = -1 'True
Caption = "0"
Height = 195
Index = 0
Left = 1200
TabIndex = 49
Top = 360
Width = 90
End
Begin VB.Label lblCondition
AutoSize = -1 'True
Caption = "0"
Height = 195
Index = 1
Left = 1800
TabIndex = 48
Top = 1080
Width = 90
End
Begin VB.Label lblCondition
AutoSize = -1 'True
Caption = "10000"
Height = 195
Index = 2
Left = 1800
TabIndex = 47
Top = 1920
Width = 450
End
Begin VB.Label lblCondition
AutoSize = -1 'True
Caption = "0"
Height = 195
Index = 3
Left = 3600
TabIndex = 46
Top = 360
Width = 90
End
Begin VB.Label lblCondition
AutoSize = -1 'True
Caption = "0"
Height = 195
Index = 4
Left = 4440
TabIndex = 45
Top = 1080
Width = 90
End
Begin VB.Label lblCondition
AutoSize = -1 'True
Caption = "10000"
Height = 195
Index = 5
Left = 4410
TabIndex = 44
Top = 1920
Width = 450
End
End
Begin VB.Frame framePeriodic
Caption = "Periodic Force"
Height = 3015
Left = 120
TabIndex = 24
Top = 240
Visible = 0 'False
Width = 5175
Begin MSComctlLib.Slider sldPeriodic
Height = 255
Index = 0
Left = 600
TabIndex = 25
Top = 480
Width = 4095
_ExtentX = 7223
_ExtentY = 450
_Version = 393216
LargeChange = 100
SmallChange = 10
Max = 10000
TickFrequency = 1000
End
Begin MSComctlLib.Slider sldPeriodic
Height = 255
Index = 1
Left = 600
TabIndex = 26
Top = 1080
Width = 4095
_ExtentX = 7223
_ExtentY = 450
_Version = 393216
LargeChange = 1000
SmallChange = 100
Min = -10000
Max = 10000
TickFrequency = 1000
End
Begin MSComctlLib.Slider sldPeriodic
Height = 255
Index = 2
Left = 600
TabIndex = 27
Top = 1800
Width = 4095
_ExtentX = 7223
_ExtentY = 450
_Version = 393216
LargeChange = 1000
SmallChange = 100
Max = 35999
TickFrequency = 1000
End
Begin MSComctlLib.Slider sldPeriodic
Height = 255
Index = 3
Left = 600
TabIndex = 28
Top = 2520
Width = 4095
_ExtentX = 7223
_ExtentY = 450
_Version = 393216
LargeChange = 1000
SmallChange = 100
Max = 500000
TickFrequency = 10000
End
Begin VB.Label lblPeriodic
AutoSize = -1 'True
Caption = "0"
Height = 195
Index = 3
Left = 2400
TabIndex = 36
Top = 2280
Width = 90
End
Begin VB.Label Label10
AutoSize = -1 'True
Caption = "Period:"
Height = 195
Left = 1800
TabIndex = 35
Top = 2280
Width = 495
End
Begin VB.Label lblPeriodic
AutoSize = -1 'True
Caption = "0"
Height = 195
Index = 2
Left = 2400
TabIndex = 34
Top = 1560
Width = 90
End
Begin VB.Label Label9
AutoSize = -1 'True
Caption = "Phase:"
Height = 195
Left = 1800
TabIndex = 33
Top = 1560
Width = 495
End
Begin VB.Label lblPeriodic
AutoSize = -1 'True
Caption = "0"
Height = 195
Index = 1
Left = 2400
TabIndex = 32
Top = 840
Width = 90
End
Begin VB.Label Label8
AutoSize = -1 'True
Caption = "Offset:"
Height = 195
Left = 1800
TabIndex = 31
Top = 840
Width = 465
End
Begin VB.Label lblPeriodic
AutoSize = -1 'True
Caption = "0"
Height = 195
Index = 0
Left = 2400
TabIndex = 30
Top = 240
Width = 90
End
Begin VB.Label Label7
AutoSize = -1 'True
Caption = "Magnitude:"
Height = 195
Left = 1560
TabIndex = 29
Top = 240
Width = 795
End
End
Begin VB.Frame frameRampForce
Caption = "Ramp Force"
Height = 3015
Left = 120
TabIndex = 17
Top = 240
Width = 5175
Begin MSComctlLib.Slider sldRampRange
Height = 495
Index = 0
Left = 480
TabIndex = 18
Top = 840
Width = 4215
_ExtentX = 7435
_ExtentY = 873
_Version = 393216
LargeChange = 1000
SmallChange = 100
Min = -10000
Max = 10000
TickFrequency = 1000
End
Begin MSComctlLib.Slider sldRampRange
Height = 495
Index = 1
Left = 480
TabIndex = 19
Top = 1920
Width = 4215
_ExtentX = 7435
_ExtentY = 873
_Version = 393216
LargeChange = 1000
SmallChange = 100
Min = -10000
Max = 10000
TickFrequency = 1000
End
Begin VB.Label lblRange
AutoSize = -1 'True
Caption = "0"
Height = 195
Index = 1
Left = 2400
TabIndex = 23
Top = 1680
Width = 90
End
Begin VB.Label Label2
AutoSize = -1 'True
Caption = "Range End:"
Height = 195
Left = 1440
TabIndex = 22
Top = 1680
Width = 855
End
Begin VB.Label lblRange
AutoSize = -1 'True
Caption = "0"
Height = 195
Index = 0
Left = 2400
TabIndex = 21
Top = 600
Width = 90
End
Begin VB.Label Label1
AutoSize = -1 'True
Caption = "Range Start:"
Height = 195
Left = 1440
TabIndex = 20
Top = 600
Width = 900
End
End
Begin VB.Frame frameConstantForce
Caption = "Constant Force"
Height = 3015
Left = 120
TabIndex = 13
Top = 240
Visible = 0 'False
Width = 5175
Begin MSComctlLib.Slider sldConstantForce
Height = 495
Left = 840
TabIndex = 14
Top = 1320
Width = 3615
_ExtentX = 6376
_ExtentY = 873
_Version = 393216
LargeChange = 100
SmallChange = 10
Max = 10000
SelStart = 10000
TickFrequency = 1000
Value = 10000
End
Begin VB.Label lblConstantForce
AutoSize = -1 'True
Caption = "10000"
Height = 195
Left = 3360
TabIndex = 16
Top = 1080
Width = 450
End
Begin VB.Label Label5
AutoSize = -1 'True
Caption = "Constant Force Magnitude:"
Height = 195
Left = 1320
TabIndex = 15
Top = 1080
Width = 1920
End
End
End
Begin VB.Frame frmGeneral
Caption = "General Parameters"
Height = 2895
Left = 120
TabIndex = 1
Top = 3960
Width = 3375
Begin MSComctlLib.Slider sldDuration
Height = 495
Left = 240
TabIndex = 2
Top = 600
Width = 2775
_ExtentX = 4895
_ExtentY = 873
_Version = 393216
LargeChange = 100
SmallChange = 10
Min = 1
Max = 50001
SelStart = 50001
TickFrequency = 5000
Value = 50001
End
Begin MSComctlLib.Slider sldGain
Height = 495
Left = 240
TabIndex = 5
Top = 1320
Width = 2775
_ExtentX = 4895
_ExtentY = 873
_Version = 393216
LargeChange = 100
SmallChange = 10
Max = 10000
SelStart = 10000
TickFrequency = 1000
Value = 10000
End
Begin MSComctlLib.Slider sldSamplePeriod
Height = 495
Left = 240
TabIndex = 9
Top = 2160
Width = 2775
_ExtentX = 4895
_ExtentY = 873
_Version = 393216
LargeChange = 1000
SmallChange = 100
Max = 100000
TickFrequency = 10000
End
Begin VB.Label lblSamplePeriod
AutoSize = -1 'True
Caption = "Default"
Height = 195
Left = 1320
TabIndex = 11
Top = 1920
Width = 510
End
Begin VB.Label Label6
AutoSize = -1 'True
Caption = "Sample rate:"
Height = 195
Left = 360
TabIndex = 10
Top = 1920
Width = 885
End
Begin VB.Label lblGain
AutoSize = -1 'True
Caption = "10000"
Height = 195
Left = 1200
TabIndex = 7
Top = 1080
Width = 450
End
Begin VB.Label Label4
AutoSize = -1 'True
Caption = "Effect gain:"
Height = 195
Left = 360
TabIndex = 6
Top = 1080
Width = 810
End
Begin VB.Label lblDuration
AutoSize = -1 'True
Caption = "Infinite"
Height = 195
Left = 1560
TabIndex = 4
Top = 360
Width = 465
End
Begin VB.Label Label3
AutoSize = -1 'True
Caption = "Effect Duration:"
Height = 195
Left = 360
TabIndex = 3
Top = 360
Width = 1110
End
End
Begin VB.ListBox lstEffects
Height = 3375
Left = 120
TabIndex = 0
Top = 360
Width = 3375
End
Begin VB.Label lblAvailable
AutoSize = -1 'True
Caption = "Available effects:"
Height = 195
Left = 120
TabIndex = 8
Top = 120
Width = 1215
End
End
Attribute VB_Name = "frmForceFeedback"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'
' Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
'
' File: ForceFeedback.frm
' Content: Demonstrates the use of force feedback using
' stock dinput effects
'
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Option Explicit
Dim dx As New DirectX8 'DirectX 8 object
Dim di As DirectInput8 'DirectInput object
Dim diJoystick As DirectInputDevice8 'DirectInput device object
Dim enumDevice As DirectInputEnumDevices8 'DirectInput enumeration for devices object
Dim diEnumObjects As DirectInputEnumDeviceObjects 'DirectInput enumeration for objects on a device object
Dim diDevObjInstance As DirectInputDeviceObjectInstance 'DirectInput object on a device object
Dim diEffEnum As DirectInputEnumEffects 'DirectInput enumeration for force feedback effects object
Dim diFFEffect() As DirectInputEffect 'Force feedback effects object
Dim diEffectType As Long 'Will be used to store the type of effect an effect object is
Dim diFFStaticParams As Long 'Will be used to store the static parameters of an effect object
Dim EffectParams() As Long 'Used to store the type of effect it is
Dim Caps As DIDEVCAPS 'Will be used to store the capabilities of the diJoystick
Dim lngLastEffectIndex As Long 'Will be used to store the last effect
Dim bInit As Boolean
Private Function CreateFFEffect(Index As Integer) As DIEFFECT
'This sub creates a generic effect DIEFFECT structure to be used in creating the effect
With CreateFFEffect
.lDuration = &HFFFFFFFF 'Infinite duration
.lGain = 10000 'Full gain
.lSamplePeriod = 1000 'Default sample period
.lTriggerButton = DIEB_NOTRIGGER 'Do Not require a trigger for the effects
.lTriggerRepeatInterval = -1 'Turn off trigger repeat interval
.constantForce.lMagnitude = 10000 'Make the magnitude of a constant force effect at full
.rampForce.lRangeStart = 0 'Make the magnitude at the start of a ramp force 0
.rampForce.lRangeEnd = 0 'Make the magnitude at the end of a ramp force 0
.conditionFlags = DICONDITION_USE_BOTH_AXES 'Use both axis when using a conditional force
With .conditionX 'For the X axis
.lDeadBand = 0 'Make an effect with no deadband
.lNegativeSaturation = 10000 'Turn the negative saturation all the way up
.lOffset = 0 'Zero the offset
.lPositiveSaturation = 10000 'Turn the positive saturation all the way up
End With
With .conditionY 'For the Y axis
.lDeadBand = 0 'Make an effect with no deadband
.lNegativeSaturation = 10000 'Turn the negative saturation all the way up
.lOffset = 0 'Zero the offset
.lPositiveSaturation = 10000 'Turn the positive saturation all the way up
End With
With .periodicForce 'For a periodic force
.lMagnitude = 10000 'Turn the magnitude of the force all the way up
.lOffset = 0 'Zero the offset
.lPeriod = 0 'Set the length of a cycle to 0. This tells the driver to use the default.
.lPhase = 0 'Zero the starting phase. Phase is something that has very
'limited support, so changing this parameter will almost always
'fail. Be prepared to catch the error this will return.
End With
End With
End Function
Private Sub chkEnvelope_Click()
Call ChangeParameter("envelope") 'Call the sub to change the parameters for the envelope of the effect.
End Sub
Private Sub Form_Activate()
Dim i As Long 'Count variable
Dim j As Integer 'Count variable
Dim prop As DIPROPLONG 'Device property structure
Dim diedo As DirectInputEnumDeviceObjects 'Holds the collection of individual objects on a device
Dim didoi As DirectInputDeviceObjectInstance 'Holds the instance of an object on a device
Dim lFFAxisCount As Long 'Holds the number of axis that support FF
Set di = dx.DirectInputCreate 'Create the direct input device
Set enumDevice = di.GetDIDevices(DI8DEVCLASS_GAMECTRL, DIEDFL_ATTACHEDONLY Or DIEDFL_FORCEFEEDBACK)
'Enumerate all joysticks that are attached to the system
For i = 1 To enumDevice.GetCount
Set diJoystick = di.CreateDevice(enumDevice.GetItem(i).GetGuidInstance)
diJoystick.GetCapabilities Caps 'Get the capabilites of the device
Set diedo = diJoystick.GetDeviceObjectsEnum(DIDFT_AXIS) ' Get info about all the axis on the device
'This loops through to make sure that there
'are at least two axis that support FF
For j = 1 To diedo.GetCount
Set didoi = diedo.GetItem(j)
If (didoi.GetFlags And DIDOI_FFACTUATOR) Then
lFFAxisCount = lFFAxisCount + 1
End If
Next
If lFFAxisCount > 1 Then
diJoystick.SetCommonDataFormat DIFORMAT_JOYSTICK 'Set the format of the device to that of a joystick
diJoystick.SetCooperativeLevel Me.hWnd, DISCL_BACKGROUND Or DISCL_EXCLUSIVE
'Set the cooperative level of the device as an exclusive
'background device, and attach it to the form's hwnd
prop.lData = 0
prop.lHow = DIPH_DEVICE
prop.lObj = 0
Call diJoystick.SetProperty("DIPROP_AUTOCENTER", prop) 'Turn off autocenter
diJoystick.Acquire 'Make sure to aquire the device
Set diEffEnum = diJoystick.GetEffectsEnum(DIEFT_ALL)
'Enumerate all the available effects
For j = 1 To diEffEnum.GetCount 'Loop through all the effects
diEffectType = diEffEnum.GetType(j) And &HFF
'Filter out the major type of effect it is
diFFStaticParams = diEffEnum.GetStaticParams(j)
'Get the static parameters of this effect
If (diEffectType = DIEFT_HARDWARE) And _
(diFFStaticParams And DIEP_TYPESPECIFICPARAMS) <> 0 Then
'If this is a hardware effect that has type-specific parameters,
GoTo Ignore 'ignore it and skip to the next effect
ElseIf diEffectType = DIEFT_CUSTOMFORCE Then
'If this effect is a custom effect,
GoTo Ignore 'ignore it and skip to the next effect
End If
lstEffects.AddItem diEffEnum.GetName(j)
'Add this effect to the listbox, displaying the name of the
'effect
ReDim Preserve EffectParams(lstEffects.ListCount - 1)
'Redimension the array that stores the type of effect this
'effect is
EffectParams(lstEffects.ListCount - 1) = diEffectType
'store the type of effect in the EffectParams array
ReDim Preserve diFFEffect(lstEffects.ListCount - 1)
'Redimension the effect object array
On Local Error GoTo ErrorHandler 'Catch any errors when creating the effect object
Set diFFEffect(UBound(diFFEffect)) = diJoystick.CreateEffect(diEffEnum.GetEffectGuid(j), _
CreateFFEffect(j)) 'Create the effect, using the return value from the
'CreateFFEffect function, which returns a generic effect
'structure
diFFEffect(UBound(diFFEffect)).Unload 'Since creating an effect automtically downloads it, unload
'it so we don't run out of room on the device.
Ignore:
Next
Exit For 'Keep the first FF joystick found
Else
Set diJoystick = Nothing 'Destroy this device and try again if there are more devices
End If
Next
If diJoystick Is Nothing Then 'If no FF joystick is found attached to the system
MsgBox "No force feedback joystick attached, app will exit" 'Display this message
Unload Me 'Unload the form
End 'End the program
End If
If diFFEffect(0) Is Nothing Then 'If this device has no downloadable effects, end the app
MsgBox "This device does not contain any downloadable effects, app will exit"
Unload Me 'Unload the form
End 'End the program
End If
lngLastEffectIndex = UBound(diFFEffect) 'Store the ubound of the effect array as the last effect accessed
bInit = True
lstEffects.ListIndex = 0 'make the first index of the listbox selected
Exit Sub 'Exit the sub
ErrorHandler: 'Handle any errors that occur when trying to create an effect object
If Err.Number = 5 Then 'If this is an effect that isn't able to be loaded
If lstEffects.ListCount > 0 Then
lstEffects.RemoveItem lstEffects.ListCount - 1 'Remove the item from the list
If (lstEffects.ListCount > 0) Then
ReDim Preserve diFFEffect(lstEffects.ListCount - 1) 'Redimension the array since this effect will not be included
ReDim Preserve EffectParams(lstEffects.ListCount - 1) 'Redimension the effect params array as well
Else
Erase diFFEffect
Erase EffectParams
End If
End If
Err.Clear
GoTo Ignore 'Skip this effect
ElseIf Err.Number = DIERR_NOTEXCLUSIVEACQUIRED Then 'If the program loses exclusive use of the joystick,
diJoystick.Unacquire 'Unacquire the joystick
diJoystick.SetCooperativeLevel Me.hWnd, DISCL_BACKGROUND Or DISCL_EXCLUSIVE
'Set the cooperative level again
diJoystick.Acquire 'Acquire the joystick again
Resume 'Resume execution on that line again, since the program
'now has control of the joystick
End If
End Sub
Private Sub lstEffects_Click()
If bInit = False Then Exit Sub
'This sub unloads the last effect, downloads the new one, stores the index in the last effect variable, and
'calls the sub to update all the frames and controls on the form
Dim EffectInfo As DIEFFECT 'Dim a DIEFFECT structure
On Local Error GoTo ErrorHandler 'Catch any errors while unloading/downloading effects
diFFEffect(lngLastEffectIndex).Unload 'Unload the last effect
diFFEffect(lstEffects.ListIndex).Start 1, 0 'Start the effect playing (this will also download the effect)
lngLastEffectIndex = lstEffects.ListIndex 'Store this list index in the lasteffectindex variable
Call UpdateFrames 'Call the sub that updates all the frames and the controls
'they contain on the form
Exit Sub
ErrorHandler: 'Handle any errors
If Err.Number = DIERR_NOTEXCLUSIVEACQUIRED Then 'If the program loses exclusive use of the joystick,
diJoystick.Unacquire 'Unacquire the joystick
diJoystick.SetCooperativeLevel Me.hWnd, DISCL_BACKGROUND Or DISCL_EXCLUSIVE
'Set the cooperative level again
diJoystick.Acquire 'Acquire the joystick again
Resume 'Resume execution on that line again, since the program
'now has control of the joystick
End If
End Sub
Private Sub ChangeParameter(Param As String)
On Local Error GoTo ErrorHandler
'This sub changes the specified parameter
If lstEffects.ListIndex = -1 Then Exit Sub
Dim EffectInfo As DIEFFECT 'Dim a DIEFFECT structure
diFFEffect(lstEffects.ListIndex).GetParameters EffectInfo
'Get the parameters of this effect
On Local Error GoTo ErrorHandler 'If there are any errors that occur, trap them
Select Case Param 'Select the string value passed to the sub
Case "duration" 'If duration is being changed
If sldDuration = 50001 Then 'If the slider's value is at 50,001
EffectInfo.lDuration = -1 'Then make the effect have an infinite duration
Else 'Otherwise
EffectInfo.lDuration = sldDuration * 100
'Multiply the slider's value by 100 to convert to microseconds
End If
diFFEffect(lstEffects.ListIndex).Stop
diFFEffect(lstEffects.ListIndex).SetParameters EffectInfo, DIEP_DURATION
'Set the new parameter, specifiying the duration is what needs
'to be changed
diFFEffect(lstEffects.ListIndex).Start 1, 0
Case "gain" 'If gain is the parameter to be changed,
EffectInfo.lGain = sldGain 'Set the effect info element lGain to the value of the gain slider
diFFEffect(lstEffects.ListIndex).SetParameters EffectInfo, DIEP_GAIN
'Set the new gain
Case "samplerate" 'The sample rate is the parameter to be changed
EffectInfo.lSamplePeriod = sldSamplePeriod 'Set the effectinfo lSamplePeriod to the value of the sample period slider
diFFEffect(lstEffects.ListIndex).SetParameters EffectInfo, DIEP_SAMPLEPERIOD
'Set the parameter
Case "constantforcemagnitude" 'If the constant force magnitude is to be changed
EffectInfo.constantForce.lMagnitude = sldConstantForce
'Set the constant force element to the value of the constant
'force slider
diFFEffect(lstEffects.ListIndex).SetParameters EffectInfo, DIEP_TYPESPECIFICPARAMS
'Change the parameter
Case "rampforce" 'If ramp force is the parameter to change
EffectInfo.rampForce.lRangeStart = sldRampRange(0).Value
'Set the start range to the range slider(0) value
EffectInfo.rampForce.lRangeEnd = sldRampRange(1).Value
'Set the end range to the range slider(1) value
diFFEffect(lstEffects.ListIndex).SetParameters EffectInfo, DIEP_TYPESPECIFICPARAMS
'Set the parameters
Case "periodic" 'If a periodic effect parameter needs to be changed
With EffectInfo.periodicForce
.lMagnitude = sldPeriodic(0) 'set the magnitude
.lOffset = sldPeriodic(1) 'the offset
.lPhase = sldPeriodic(2) 'the phase (this is almost always going to fail, there aren't
'a lot of drivers that will support this)
.lPeriod = sldPeriodic(3) 'the period of the effect
End With
diFFEffect(lstEffects.ListIndex).SetParameters EffectInfo, DIEP_TYPESPECIFICPARAMS
'set the parameters
Case "condition" 'If it is a conditional effect parameter
If optConditionAxis(0) Then 'If the X axis is selected
With EffectInfo.conditionX 'Update the X axis condition information
.lDeadBand = sldCondition(0) 'set the deadband
.lNegativeCoefficient = sldCondition(1)
'set the negative coefficient
.lNegativeSaturation = sldCondition(2)
'set the negative saturation
.lOffset = sldCondition(3) 'set the offset
.lPositiveCoefficient = sldCondition(4)
'set the positive coefficient
.lPositiveSaturation = sldCondition(5)
'set the positive saturation
End With
Else 'Otherwise, the Y axis is being set
With EffectInfo.conditionY
.lDeadBand = sldCondition(0) 'set the deadband
.lNegativeCoefficient = sldCondition(1)
'set the negative coefficient
.lNegativeSaturation = sldCondition(2)
'set the negative saturation
.lOffset = sldCondition(3) 'set the offset
.lPositiveCoefficient = sldCondition(4)
'set the positive coefficient
.lPositiveSaturation = sldCondition(5)
'set the positive saturation
End With
End If
diFFEffect(lstEffects.ListIndex).SetParameters EffectInfo, DIEP_TYPESPECIFICPARAMS
'set the parameters
Case "envelope" 'the envelope needs to be changed
If chkEnvelope.Value = 1 Then 'if the envelope checkbox is checked
With EffectInfo
.bUseEnvelope = True 'let DirectInput know this effect has an envelope
With .envelope
.lAttackLevel = sldEnvelope(0) 'set the attack level
.lAttackTime = sldEnvelope(1) 'set the attack time
.lFadeLevel = sldEnvelope(2) 'set the fade level
.lFadeTime = sldEnvelope(3) 'set the fade time
End With
End With
diFFEffect(lstEffects.ListIndex).SetParameters EffectInfo, DIEP_ENVELOPE
'Set the new parameters
Else
EffectInfo.bUseEnvelope = False 'Otherwise, let DirectInput know that this effect doesn't use an envelope
diFFEffect(lstEffects.ListIndex).SetParameters EffectInfo, DIEP_ENVELOPE
'Set the parameters to reflect this change
End If
Case "direction" 'Direction is the parameter that needs to be changed
With EffectInfo
If optDirection(0) Then 'If the north button is selected
.x = 0 'set the effect's direction to come from the north
ElseIf optDirection(1) Then 'If the north-east button is selected
.x = 4500 'set the effect's direction to come from the north-east
ElseIf optDirection(2) Then 'if the east button is selected
.x = 9000 'set the effect's direction to come from the east
ElseIf optDirection(3) Then 'if the south-east button is selected
.x = 13500 'set the effect's direction to come from the south east
ElseIf optDirection(4) Then 'if the south button is selected
.x = 18000 'set the effect's direction to come from the south
ElseIf optDirection(5) Then 'if the south-west button is selected
.x = 22500 'set the effect's direction to come from the south-west
ElseIf optDirection(6) Then 'if the west button is selected
.x = 27000 'set the effect's direction to come from the west
ElseIf optDirection(7) Then 'if the north-west button is selected
.x = 31500 'set the effects's direction to come from the north-west
End If
End With
diFFEffect(lstEffects.ListIndex).SetParameters EffectInfo, DIEP_DIRECTION
'set the parameters
End Select
Exit Sub
ErrorHandler: 'if an error is encountered while setting a parameter
If Err.Number = 445 Then 'If the object doesn't support this action then
MsgBox "The parameter cannot be set to this value for this effect type"
'display this message
ElseIf Err.Number = DIERR_NOTEXCLUSIVEACQUIRED Then 'If the program loses exclusive use of the joystick,
diJoystick.Unacquire 'Unacquire the joystick
diJoystick.SetCooperativeLevel Me.hWnd, DISCL_BACKGROUND Or DISCL_EXCLUSIVE
'Set the cooperative level again
diJoystick.Acquire 'Acquire the joystick again
Resume 'Resume execution on that line again, since the program
'now has control of the joystick
End If
End Sub
Private Sub UpdateFrames()
'This sub updates all the frames and controls the frame contains on the form, with the values in the
'currently selected effect
Dim EffType As DIEFFECT 'dim a DIEFFECT structure
frameConstantForce.Visible = False '
frameRampForce.Visible = False 'Hide all type-specific frames
framePeriodic.Visible = False '
frameCondition.Visible = False '
diFFEffect(lstEffects.ListIndex).GetParameters EffType
'get the parameters of the effect
optDirection(EffType.x \ 4500).Value = True 'make sure the correct direction is displayed
If EffType.bUseEnvelope = True Then 'if this effect is using an envelope
chkEnvelope.Value = 1 'make sure the envelope checkbox is checked
sldEnvelope(0).Value = EffType.envelope.lAttackLevel
'display the attack level
sldEnvelope(1).Value = EffType.envelope.lAttackTime
'display the attack time
sldEnvelope(2).Value = EffType.envelope.lFadeLevel
'display the fade level
sldEnvelope(3).Value = EffType.envelope.lFadeTime
'display the fade time
Else 'otherwise
chkEnvelope.Value = 0 '
sldEnvelope(0).Value = 0 'Zero everything out
sldEnvelope(1).Value = 0 '
sldEnvelope(2).Value = 0 '
sldEnvelope(3).Value = 0 '
End If
If EffType.lDuration = -1 Then 'If the effect duration is infinite
sldDuration = 50001 'make sure the slider reflects this
Else 'otherwise
sldDuration = EffType.lDuration \ 100 'set the slider to the milliseconds
End If
sldGain = EffType.lGain 'display the gain
sldSamplePeriod = EffType.lSamplePeriod 'display the sample period
sldConstantForce = EffType.constantForce.lMagnitude 'display the constant force magnitude
sldRampRange(0) = EffType.rampForce.lRangeStart 'display the range start of the ramp force
sldRampRange(1) = EffType.rampForce.lRangeEnd 'display the range end of the ramp force
sldPeriodic(0) = EffType.periodicForce.lMagnitude 'display the magnitude of the periodic force
sldPeriodic(1) = EffType.periodicForce.lOffset 'display the offset of the periodic force
sldPeriodic(2) = EffType.periodicForce.lPhase 'display the phase of the periodic force
sldPeriodic(3) = EffType.periodicForce.lPeriod 'display the period of the periodic force
If optConditionAxis(0) Then 'if the X axis option button is selected
sldCondition(0) = EffType.conditionX.lDeadBand 'display the deadband value
sldCondition(1) = EffType.conditionX.lNegativeCoefficient
'display the neg. coefficient
sldCondition(2) = EffType.conditionX.lNegativeSaturation
'display the neg. saturation
sldCondition(3) = EffType.conditionX.lOffset 'display the offset
sldCondition(4) = EffType.conditionX.lPositiveCoefficient
'display the pos. coefficient
sldCondition(5) = EffType.conditionX.lPositiveSaturation
'display the pos. saturation
Else 'otherwise, display all the info for the Y axis
sldCondition(0) = EffType.conditionY.lDeadBand 'display the deadband value
sldCondition(1) = EffType.conditionY.lNegativeCoefficient
'display the neg. coefficient
sldCondition(2) = EffType.conditionY.lNegativeSaturation
'display the neg. saturation
sldCondition(3) = EffType.conditionY.lOffset 'display the offset
sldCondition(4) = EffType.conditionY.lPositiveCoefficient
'display the pos. coefficient
sldCondition(5) = EffType.conditionY.lPositiveSaturation
'display the pos. saturation
End If
Select Case EffectParams(lstEffects.ListIndex)
'Get the effect type of this effect from the type stored in
'the array.
Case DIEFT_CONSTANTFORCE 'If this is a constant force effect
frameConstantForce.Visible = True 'display the constant force frame
Case DIEFT_RAMPFORCE 'If this is a ramp force effect
frameRampForce.Visible = True 'Show the ramp force frame
Case DIEFT_PERIODIC 'If this is a square force
framePeriodic.Visible = True 'show the periodic effect frame
Case DIEFT_CONDITION 'if this is a spring effect
frameCondition.Visible = True 'show the condition frame
Case Else 'this effect is a hardware effect with no type-specific parameters
End Select
End Sub
Private Sub optConditionAxis_Click(Index As Integer)
Call UpdateFrames 'Update the frames
End Sub
Private Sub optDirection_Click(Index As Integer)
Call ChangeParameter("direction") 'Change the direction parameter
End Sub
Private Sub sldCondition_Change(Index As Integer)
lblCondition(Index) = sldCondition(Index) 'display the value in the label
Call ChangeParameter("condition") 'change the condition parameter
End Sub
Private Sub sldCondition_Scroll(Index As Integer)
lblCondition(Index) = sldCondition(Index) 'display the value in the label
Call ChangeParameter("condition") 'change the condition parameter
End Sub
Private Sub sldConstantForce_Change()
lblConstantForce = sldConstantForce 'display the value
Call ChangeParameter("constantforcemagnitude") 'change the parameter
End Sub
Private Sub sldDuration_Change()
lblDuration = sldDuration \ 10 & " Milliseconds" 'show the value in milliseconds
If sldDuration = 50001 Then lblDuration = "Infinite"
'if the value is 50,001 make sure that infinite is displayed
Call ChangeParameter("duration") 'change the duration parameter
End Sub
Private Sub sldDuration_Scroll()
lblDuration = sldDuration \ 10 & " Milliseconds" 'show the value in milliseconds
If sldDuration = 50001 Then lblDuration = "Infinite"
'if the value is 50,001 make sure that infinite is displayed
Call ChangeParameter("duration") 'change the duration parameter
End Sub
Private Sub sldEnvelope_Change(Index As Integer)
lblEnvelope(Index) = sldEnvelope(Index) \ 1000 'show the value in milliseconds
If chkEnvelope.Value = 1 Then 'if the envelope check box is checked
Call ChangeParameter("envelope") 'change the envelope parameter
End If
End Sub
Private Sub sldEnvelope_Scroll(Index As Integer)
lblEnvelope(Index) = sldEnvelope(Index) \ 1000 'show the value in milliseconds
If chkEnvelope.Value = 1 Then 'if the envelope check box is checked
Call ChangeParameter("envelope") 'change the envelope parameter
End If
End Sub
Private Sub sldGain_Change()
lblGain = sldGain 'show the value
Call ChangeParameter("gain") 'change the parameter
End Sub
Private Sub sldGain_Scroll()
lblGain = sldGain 'show the value
Call ChangeParameter("gain") 'change the parameter
End Sub
Private Sub sldPeriodic_Change(Index As Integer)
lblPeriodic(Index) = sldPeriodic(Index) 'show the value
Call ChangeParameter("periodic") 'change the parameter
End Sub
Private Sub sldrampRange_Change(Index As Integer)
lblRange(Index) = sldRampRange(Index).Value 'show the value
Call ChangeParameter("rampforce") 'change the parameter
End Sub
Private Sub sldSamplePeriod_Change()
If sldSamplePeriod = 0 Then 'if the sample period is 0,
lblSamplePeriod = "Default" 'display that it is the default
Else 'otherwise
lblSamplePeriod = sldSamplePeriod 'display the sample period
End If
Call ChangeParameter("samplerate") 'change the parameter
End Sub
Private Sub sldSamplePeriod_Scroll()
If sldSamplePeriod = 0 Then 'if the sample period is 0,
lblSamplePeriod = "Default" 'display that it is the default
Else 'otherwise
lblSamplePeriod = sldSamplePeriod 'display the sample period
End If
Call ChangeParameter("samplerate") 'change the parameter
End Sub