If you want access to all four possible XBox360 controllers at the same time, you have a couple of options already that are simply not obvious to you at this point.
The first is to use the DLL that Microsoft provides for XBox360 controllers, xinput1_3.dll There are only 6 function calls in that dll, and only a couple of them are needed to get you 4 simultaneous controllers. Here is a source file that I use for getting at them in my programs in DBPro. I think it is compatible to some extent with DBC. Certainly, you can already load the dll and make the calls, anyway:
rem jzDirectX.dba - DirectX extensions for DarkBASIC Pro.
remstart
dim controller(MAX_CONTROLLER) as CONTROLLERMEMORY
dim dsoundguids() as GUID
global dxdlls as DIRECTXDLLS
remend
type DIRECTXDLLS
xinput as integer
xinputmemory as JZMEMORY
dsound as integer
dsoundmemory as JZMEMORY
endtype
#constant D3DFVF_RESERVED0 0x001
#constant D3DFVF_POSITION_MASK 0x400E
#constant D3DFVF_XYZ 0x002
#constant D3DFVF_XYZRHW 0x004
#constant D3DFVF_XYZB1 0x006
#constant D3DFVF_XYZB2 0x008
#constant D3DFVF_XYZB3 0x00a
#constant D3DFVF_XYZB4 0x00c
#constant D3DFVF_XYZB5 0x00e
#constant D3DFVF_XYZW 0x4002
#constant D3DFVF_NORMAL 0x010
#constant D3DFVF_PSIZE 0x020
#constant D3DFVF_DIFFUSE 0x040
#constant D3DFVF_SPECULAR 0x080
#constant D3DFVF_TEXCOUNT_MASK 0xf00
#constant D3DFVF_TEXCOUNT_SHIFT 8
#constant D3DFVF_TEX0 0x000
#constant D3DFVF_TEX1 0x100
#constant D3DFVF_TEX2 0x200
#constant D3DFVF_TEX3 0x300
#constant D3DFVF_TEX4 0x400
#constant D3DFVF_TEX5 0x500
#constant D3DFVF_TEX6 0x600
#constant D3DFVF_TEX7 0x700
#constant D3DFVF_TEX8 0x800
#constant D3DFVF_LASTBETA_UBYTE4 0x1000
#constant D3DFVF_LASTBETA_D3DCOLOR 0x8000
#constant D3DFVF_RESERVED2 0x6000
#constant LOAD_XINPUT 0x00000001
#constant XINPUT_DEVTYPE_GAMEPAD 0x01
#constant XINPUT_DEVSUBTYPE_GAMEPAD 0x01
#constant XINPUT_DEVSUBTYPE_WHEEL 0x02
#constant XINPUT_DEVSUBTYPE_ARCADE_STICK 0x03
#constant XINPUT_DEVSUBTYPE_FLIGHT_SICK 0x04
#constant XINPUT_DEVSUBTYPE_DANCE_PAD 0x05
#constant XINPUT_CAPS_VOICE_SUPPORTED 0x0004
#constant XINPUT_GAMEPAD_DPAD_UP 0x0001
#constant XINPUT_GAMEPAD_DPAD_DOWN 0x0002
#constant XINPUT_GAMEPAD_DPAD_LEFT 0x0004
#constant XINPUT_GAMEPAD_DPAD_RIGHT 0x0008
#constant XINPUT_GAMEPAD_START 0x0010
#constant XINPUT_GAMEPAD_BACK 0x0020
#constant XINPUT_GAMEPAD_LEFT_THUMB 0x0040
#constant XINPUT_GAMEPAD_RIGHT_THUMB 0x0080
#constant XINPUT_GAMEPAD_LEFT_SHOULDER 0x0100
#constant XINPUT_GAMEPAD_RIGHT_SHOULDER 0x0200
#constant XINPUT_GAMEPAD_A 0x1000
#constant XINPUT_GAMEPAD_B 0x2000
#constant XINPUT_GAMEPAD_X 0x4000
#constant XINPUT_GAMEPAD_Y 0x8000
#constant XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE 7849
#constant XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE 8689
#constant XINPUT_GAMEPAD_TRIGGER_THRESHOLD 30
#constant XINPUT_FLAG_GAMEPAD 0x00000001
#constant BATTERY_DEVTYPE_HEADSET 0x01
#constant BATTERY_TYPE_DISCONNECTED 0x00
#constant BATTERY_TYPE_WIRED 0x01
#constant BATTERY_TYPE_ALKALINE 0x02
#constant BATTERY_TYPE_NIMH 0x03
#constant BATTERY_TYPE_UNKNOWN 0xFF
#constant BATTERY_LEVEL_EMPTY 0x00
#constant BATTERY_LEVEL_LOW 0x01
#constant BATTERY_LEVEL_MEDIUM 0x02
#constant BATTERY_LEVEL_FULL 0x03
#constant XUSER_MAX_COUNT 4
#constant XUSER_INDEX_ANY 0x000000FF
type XINPUT_GAMEPAD
wButtons as word
bLeftTrigger as byte
bRightTrigger as byte
sThumbLX as word
sThumbLY as word
sThumbRX as word
sThumbRY as word
endtype
#constant SIZEOF_XINPUT_GAMEPAD 12
type XINPUT_STATE
dwPacketNumber as dword
Gamepad as XINPUT_GAMEPAD
endtype
#constant SIZEOF_XINPUT_STATE 16
type XINPUT_VIBRATION
wLeftMotorSpeed as word
wRightMotorSpeed as word
endtype
#constant SIZEOF_XINPUT_VIBRATION 4
type XINPUT_CAPABILITIES
xType as byte
SubType as byte
Flags as word
Gamepad as XINPUT_GAMEPAD
Vibration as XINPUT_VIBRATION
endtype
#constant SIZEOF_XINPUT_CAPABILITIES 20
type XINPUT_BATTERY_INFORMATION
BatteryType as byte
BatteryLevel as byte
endtype
#constant SIZEOF_XINPUT_BATTERY_INFORMATION 2
type XINPUT_KEYSTROKE
VirtualKey as word
Unicode as word
Flags as word
UserIndex as byte
HidCode as byte
endtype
#constant SIZEOF_XINPUT_KEYSTROKE 8
type GUID
Data1 as dword
Data2 as word
Data3 as word
Data41 as byte
Data42 as byte
Data43 as byte
Data44 as byte
Data45 as byte
Data46 as byte
Data47 as byte
Data48 as byte
endtype
#constant SIZEOF_GUID 16
#constant MAX_CONTROLLER 4
#constant ERROR_SUCCESS 0
type CONTROLLERMEMORY
inputstate as JZMEMORY
playbackGUID as JZMEMORY
captureGUID as JZMEMORY
endtype
type XBOX360SCAN_1
time as float
controller as XINPUT_STATE
endtype
type XBOX360SCAN_4
time as float
controller1 as XINPUT_STATE
controller2 as XINPUT_STATE
controller3 as XINPUT_STATE
controller4 as XINPUT_STATE
endtype
#constant PLAYERACTION_NULL 0x00000000
#constant PLAYERACTION_FWD 0x00000001
#constant PLAYERACTION_BACK 0x00000002
#constant PLAYERACTION_LEFT 0x00000004
#constant PLAYERACTION_RIGHT 0x00000008
#constant PLAYERACTION_LUP 0x00000010
#constant PLAYERACTION_LDOWN 0x00000020
#constant PLAYERACTION_LLEFT 0x00000040
#constant PLAYERACTION_LRIGHT 0x00000080
#constant PLAYERACTION_CROUCH 0x00000100
#constant PLAYERACTION_JUMP 0x00000200
#constant PLAYERACTION_FIRE_1 0x00000400
#constant PLAYERACTION_FIRE_2 0x00000800
#constant PLAYERACTION_DUP 0x00001000
#constant PLAYERACTION_DDOWN 0x00002000
#constant PLAYERACTION_DLEFT 0x00004000
#constant PLAYERACTION_DRIGHT 0x00008000
rem ***************************************************************************
function jzXInputInit()
local i as integer
local j as integer
for i = 0 to MAX_CONTROLLER - 1
j = jzGetNextAvailableMemblockID(1)
make memblock j, SIZEOF_XINPUT_STATE
controller(i).inputstate.memblockID = j
controller(i).inputstate.ptr = get memblock ptr(j)
fill memory controller(i).inputstate.ptr, 0x00, SIZEOF_XINPUT_STATE
j = jzGetNextAvailableMemblockID(1)
make memblock j, SIZEOF_GUID
controller(i).playbackGUID.memblockID = j
controller(i).playbackGUID.ptr = get memblock ptr(j)
fill memory controller(i).playbackGUID.ptr, 0x00, SIZEOF_GUID
j = jzGetNextAvailableMemblockID(1)
make memblock j, SIZEOF_GUID
controller(i).captureGUID.memblockID = j
controller(i).captureGUID.ptr = get memblock ptr(j)
fill memory controller(i).captureGUID.ptr, 0x00, SIZEOF_GUID
next i
dxdlls.xinput = jzGetNextAvailableDLLID(0, 1)
load dll "xinput1_3.dll", dxdlls.xinput
call dll dxdlls.xinput, "XInputEnable", 1
endfunction
function jzXInputShutdown()
local i as integer
for i = 0 to MAX_CONTROLLER - 1
if memblock exist(controller(i).inputstate.memblockID)
delete memblock controller(i).inputstate.memblockID
endif
if memblock exist(controller(i).playbackGUID.memblockID)
delete memblock controller(i).playbackGUID.memblockID
endif
if memblock exist(controller(i).captureGUID.memblockID)
delete memblock controller(i).captureGUID.memblockID
endif
next i
if dll exist(dxdlls.xinput)
delete dll dxdlls.xinput
dxdlls.xinput = -1
endif
endfunction
function jzXInputQueryController(usernum as integer)
local j as integer = -1
if usernum = -1
j = call dll(dxdlls.xinput, "XInputGetState", 0, controller(0).inputstate.ptr)
j = call dll(dxdlls.xinput, "XInputGetState", 1, controller(1).inputstate.ptr)
j = call dll(dxdlls.xinput, "XInputGetState", 2, controller(2).inputstate.ptr)
j = call dll(dxdlls.xinput, "XInputGetState", 3, controller(3).inputstate.ptr)
exitfunction 0
endif
j = call dll(dxdlls.xinput, "XInputGetState", usernum, controller(usernum).inputstate.ptr)
endfunction j
function jzXBox360Vibrate(usernum as integer, vibeleft as word, viberight as word)
local dwtemp as dword
if usernum > -1 and usernum < MAX_CONTROLLER
write memblock word controller(usernum).inputstate.memblockID, 0, vibeleft
write memblock word controller(usernum).inputstate.memblockID, 2, viberight
dwtemp = call dll(dxdlls.xinput, "XInputSetState", usernum, ...
controller(usernum).inputstate.ptr)
else
dwtemp = 0xffffffff
endif
endfunction dwtemp
function jzDoXBox360GameControl(usernum as integer)
local packet as integer
local useraction as dword = 0x00000000
local wtemp as word
local ltrigger as byte
local rtrigger as byte
local lx as integer
local ly as integer
local rx as integer
local ry as integer
packet = memblock dword(controller(usernum).inputstate.memblockID, 0)
wtemp = memblock word(controller(usernum).inputstate.memblockID, 4)
ltrigger = memblock byte(controller(usernum).inputstate.memblockID, 6)
rtrigger = memblock byte(controller(usernum).inputstate.memblockID, 7)
lx = jzMakeWordIntValue(memblock word(controller(usernum).inputstate.memblockID, ...
8))
ly = jzMakeWordIntValue(memblock word(controller(usernum).inputstate.memblockID, ...
10))
rx = jzMakeWordIntValue(memblock word(controller(usernum).inputstate.memblockID, ...
12))
ry = jzMakeWordIntValue(memblock word(controller(usernum).inputstate.memblockID, ...
14))
if rtrigger > 0
useraction = useraction || PLAYERACTION_FIRE_1
endif
if ltrigger > 0
useraction = useraction || PLAYERACTION_FIRE_2
endif
if wtemp && XINPUT_GAMEPAD_Y
rem
endif
if wtemp && XINPUT_GAMEPAD_B
rem
endif
if wtemp && XINPUT_GAMEPAD_A
useraction = useraction || PLAYERACTION_JUMP
endif
if wtemp && XINPUT_GAMEPAD_X
rem
endif
if wtemp && XINPUT_GAMEPAD_RIGHT_THUMB
useraction = useraction || PLAYERACTION_CROUCH
endif
if wtemp && XINPUT_GAMEPAD_DPAD_UP
useraction = useraction || PLAYERACTION_DUP
endif
if wtemp && XINPUT_GAMEPAD_DPAD_DOWN
useraction = useraction || PLAYERACTION_DDOWN
endif
if wtemp && XINPUT_GAMEPAD_DPAD_LEFT
useraction = useraction || PLAYERACTION_DLEFT
endif
if wtemp && XINPUT_GAMEPAD_DPAD_RIGHT
useraction = useraction || PLAYERACTION_DRIGHT
endif
if rtrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD
useraction = useraction || PLAYERACTION_FIRE_1
endif
if lx > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE
useraction = useraction || PLAYERACTION_RIGHT
endif
if lx < -(XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)
useraction = useraction || PLAYERACTION_LEFT
endif
if ly > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE
useraction = useraction || PLAYERACTION_FWD
endif
if ly < -(XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)
useraction = useraction || PLAYERACTION_BACK
endif
if rx > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE
useraction = useraction || PLAYERACTION_LRIGHT
else
if rx < -(XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE)
useraction = useraction || PLAYERACTION_LLEFT
endif
endif
if ry > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE
useraction = useraction || PLAYERACTION_LUP
else
if ry < -(XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE)
useraction = useraction || PLAYERACTION_LDOWN
endif
endif
endfunction useraction
remstart
DirectSound API.
remend
type DSBUFFERDESC
dwSize as dword
dwFlags as dword
dwBufferBytes as dword
dwReserved as dword
lpwfxFormat as dword
guid3DAlgorithm as GUID
endtype
#constant SIZEOF_DSBUFFERDESC = 36
type DSBCAPS
dwSize as dword
dwFlags as dword
dwBufferBytes as dword
dwUnlockTransferRate as dword
dwPlayCpuOverhead as dword
endtype
#constant SIZEOF_DSBCAPS = 20
remstart
Defines for dwFlags member of DSBCAPS/DSBUFFERDESC structure.
DSBCAPS_CTRL3D The buffer has 3D control capability.
DSBCAPS_CTRLFREQUENCY The buffer has frequency control capability.
DSBCAPS_CTRLFX The buffer supports effects processing.
DSBCAPS_CTRLPAN The buffer has pan control capability.
DSBCAPS_CTRLVOLUME The buffer has volume control capability.
DSBCAPS_CTRLPOSITIONNOTIFY The buffer has position notification capability.
See the Remarks for DSCBUFFERDESC.
DSBCAPS_GETCURRENTPOSITION2 The buffer uses the new behavior of the play cursor
when IDirectSoundBuffer8::GetCurrentPosition is called.
In the first version of DirectSound, the play cursor was
significantly ahead of the actual playing sound on emulated
sound cards; it was directly behind the write cursor. Now,
if the DSBCAPS_GETCURRENTPOSITION2 flag is specified, the
application can get a more accurate play cursor. If this
flag is not specified, the old behavior is preserved for
compatibility. This flag affects only emulated devices;
if a DirectSound driver is present, the play cursor is
accurate for DirectSound in all versions of DirectX.
DSBCAPS_GLOBALFOCUS The buffer is a global sound buffer. With this flag set,
an application using DirectSound can continue to play its
buffers if the user switches focus to another application,
even if the new application uses DirectSound. The one
exception is if you switch focus to a DirectSound
application that uses the DSSCL_WRITEPRIMARY flag for
its cooperative level. In this case, the global sounds
from other applications will not be audible.
DSBCAPS_LOCDEFER The buffer can be assigned to a hardware or software
resource at play time, or when
IDirectSoundBuffer8::AcquireResources is called.
DSBCAPS_LOCHARDWARE The buffer uses hardware mixing.
DSBCAPS_LOCSOFTWARE The buffer is in software memory and uses software mixing.
DSBCAPS_MUTE3DATMAXDISTANCE The sound is reduced to silence at the maximum distance.
The buffer will stop playing when the maximum distance is
exceeded, so that processor time is not wasted. Applies
only to software buffers.
DSBCAPS_PRIMARYBUFFER The buffer is a primary buffer.
DSBCAPS_STATIC The buffer is in on-board hardware memory.
DSBCAPS_STICKYFOCUS The buffer has sticky focus. If the user switches to
another application not using DirectSound, the buffer is
still audible. However, if the user switches to another
DirectSound application, the buffer is muted.
DSBCAPS_TRUEPLAYPOSITION Force IDirectSoundBuffer8::GetCurrentPosition to return
the buffer's true play position. This flag is only valid
in Windows Vista.
remend
rem DirectSound return codes.
#constant DS_OK 0x00000000
#constant DS_NO_VIRTUALIZATION 0x00000878000a
#constant DSERR_ALLOCATED 0x00010878000a
#constant DSERR_CONTROLUNAVAIL 0x00010878001e
#constant DSERR_INVALIDPARAM 0x80070057
#constant DSERR_INVALIDCALL 0x000108780032
#constant DSERR_GENERIC 0x80004005
#constant DSERR_PRIOLEVELNEEDED 0x000108780046
#constant DSERR_OUTOFMEMORY 0x80000002
#constant DSERR_BADFORMAT 0x000108780064
#constant DSERR_UNSUPPORTED 0x80000001
#constant DSERR_NODRIVER 0x000108780078
#constant DSERR_ALREADYINITIALIZED 0x000108780082
#constant DSERR_NOAGGREGATION 0x80040110
#constant DSERR_BUFFERLOST 0x000108780096
#constant DSERR_OTHERAPPHASPRIO 0x0001087800a0
#constant DSERR_UNINITIALIZED 0x0001087800aa
#constant DSERR_NOINTERFACE 0x80000004
#constant DSERR_ACCESSDENIED 0x80000009
#constant DSERR_BUFFERTOOSMALL 0x0001087800b4
#constant DSERR_DS8_REQUIRED 0x0001087800be
#constant DSERR_SENDLOOP 0x0001087800c8
#constant DSERR_BADSENDBUFFERGUID 0x0001087800d2
#constant DSERR_OBJECTNOTFOUND 0x000108781161
#constant DSERR_FXUNAVAILABLE 0x0001087800dc
rem DirectSound Flags.
#constant DSCAPS_PRIMARYMONO 0x00000001
#constant DSCAPS_PRIMARYSTEREO 0x00000002
#constant DSCAPS_PRIMARY8BIT 0x00000004
#constant DSCAPS_PRIMARY16BIT 0x00000008
#constant DSCAPS_CONTINUOUSRATE 0x00000010
#constant DSCAPS_EMULDRIVER 0x00000020
#constant DSCAPS_CERTIFIED 0x00000040
#constant DSCAPS_SECONDARYMONO 0x00000100
#constant DSCAPS_SECONDARYSTEREO 0x00000200
#constant DSCAPS_SECONDARY8BIT 0x00000400
#constant DSCAPS_SECONDARY16BIT 0x00000800
#constant DSSCL_NORMAL 0x00000001
#constant DSSCL_PRIORITY 0x00000002
#constant DSSCL_EXCLUSIVE 0x00000003
#constant DSSCL_WRITEPRIMARY 0x00000004
#constant DSSPEAKER_DIRECTOUT 0x00000000
#constant DSSPEAKER_HEADPHONE 0x00000001
#constant DSSPEAKER_MONO 0x00000002
#constant DSSPEAKER_QUAD 0x00000003
#constant DSSPEAKER_STEREO 0x00000004
#constant DSSPEAKER_SURROUND 0x00000005
#constant DSSPEAKER_5POINT1 0x00000006
#constant DSSPEAKER_7POINT1 0x00000007
#constant DSSPEAKER_7POINT1_SURROUND 0x00000008
#constant DSSPEAKER_7POINT1_WIDE 0x00000007
#constant DSSPEAKER_GEOMETRY_MIN 0x00000005
#constant DSSPEAKER_GEOMETRY_NARROW 0x0000000A
#constant DSSPEAKER_GEOMETRY_WIDE 0x00000014
#constant DSSPEAKER_GEOMETRY_MAX 0x000000B4
remstart
#constant DSSPEAKER_COMBINED(c, g) ((DWORD)(((BYTE)(c)) | ((DWORD)((BYTE)(g))) << 16))
#constant DSSPEAKER_CONFIG(a) ((BYTE)(a))
#constant DSSPEAKER_GEOMETRY(a) ((BYTE)(((DWORD)(a) >> 16) & 0x00FF))
remend
#constant DSBCAPS_PRIMARYBUFFER 0x00000001
#constant DSBCAPS_STATIC 0x00000002
#constant DSBCAPS_LOCHARDWARE 0x00000004
#constant DSBCAPS_LOCSOFTWARE 0x00000008
#constant DSBCAPS_CTRL3D 0x00000010
#constant DSBCAPS_CTRLFREQUENCY 0x00000020
#constant DSBCAPS_CTRLPAN 0x00000040
#constant DSBCAPS_CTRLVOLUME 0x00000080
#constant DSBCAPS_CTRLPOSITIONNOTIFY 0x00000100
#constant DSBCAPS_CTRLFX 0x00000200
#constant DSBCAPS_STICKYFOCUS 0x00004000
#constant DSBCAPS_GLOBALFOCUS 0x00008000
#constant DSBCAPS_GETCURRENTPOSITION2 0x00010000
#constant DSBCAPS_MUTE3DATMAXDISTANCE 0x00020000
#constant DSBCAPS_LOCDEFER 0x00040000
#constant DSBPLAY_LOOPING 0x00000001
#constant DSBPLAY_LOCHARDWARE 0x00000002
#constant DSBPLAY_LOCSOFTWARE 0x00000004
#constant DSBPLAY_TERMINATEBY_TIME 0x00000008
#constant DSBPLAY_TERMINATEBY_DISTANCE 0x000000010
#constant DSBPLAY_TERMINATEBY_PRIORITY 0x000000020
#constant DSBSTATUS_PLAYING 0x00000001
#constant DSBSTATUS_BUFFERLOST 0x00000002
#constant DSBSTATUS_LOOPING 0x00000004
#constant DSBSTATUS_LOCHARDWARE 0x00000008
#constant DSBSTATUS_LOCSOFTWARE 0x00000010
#constant DSBSTATUS_TERMINATED 0x00000020
#constant DSBLOCK_FROMWRITECURSOR 0x00000001
#constant DSBLOCK_ENTIREBUFFER 0x00000002
#constant DSBFREQUENCY_ORIGINAL 0
#constant DSBFREQUENCY_MIN 100
#constant DSBFREQUENCY_MAX 200000
#constant DSBPAN_LEFT -10000
#constant DSBPAN_CENTER 0
#constant DSBPAN_RIGHT 10000
#constant DSBVOLUME_MIN -10000
#constant DSBVOLUME_MAX 0
#constant DSBSIZE_MIN 4
#constant DSBSIZE_MAX 0x0FFFFFFF
#constant DSBSIZE_FX_MIN 150
#constant DSBNOTIFICATIONS_MAX 100000
#constant DS3DMODE_NORMAL 0x00000000
#constant DS3DMODE_HEADRELATIVE 0x00000001
#constant DS3DMODE_DISABLE 0x00000002
#constant DS3D_IMMEDIATE 0x00000000
#constant DS3D_DEFERRED 0x00000001
rem #constant DS3D_MINDISTANCEFACTOR FLT_MIN
rem #constant DS3D_MAXDISTANCEFACTOR FLT_MAX
#constant DS3D_DEFAULTDISTANCEFACTOR 1.0
#constant DS3D_MINROLLOFFFACTOR 0.0
#constant DS3D_MAXROLLOFFFACTOR 10.0
#constant DS3D_DEFAULTROLLOFFFACTOR 1.0
#constant DS3D_MINDOPPLERFACTOR 0.0
#constant DS3D_MAXDOPPLERFACTOR 10.0
#constant DS3D_DEFAULTDOPPLERFACTOR 1.0
#constant DS3D_DEFAULTMINDISTANCE 1.0
#constant DS3D_DEFAULTMAXDISTANCE 1000000000.0
#constant DS3D_MINCONEANGLE 0
#constant DS3D_MAXCONEANGLE 360
#constant DS3D_DEFAULTCONEANGLE 360
#constant DS3D_DEFAULTCONEOUTSIDEVOLUME DSBVOLUME_MAX
#constant SPEAKER_FRONT_LEFT 0x1
#constant SPEAKER_FRONT_RIGHT 0x2
#constant SPEAKER_FRONT_CENTER 0x4
#constant SPEAKER_LOW_FREQUENCY 0x8
#constant SPEAKER_BACK_LEFT 0x10
#constant SPEAKER_BACK_RIGHT 0x20
#constant SPEAKER_FRONT_LEFT_OF_CENTER 0x40
#constant SPEAKER_FRONT_RIGHT_OF_CENTER 0x80
#constant SPEAKER_BACK_CENTER 0x100
#constant SPEAKER_SIDE_LEFT 0x200
#constant SPEAKER_SIDE_RIGHT 0x400
#constant SPEAKER_TOP_CENTER 0x800
#constant SPEAKER_TOP_FRONT_LEFT 0x1000
#constant SPEAKER_TOP_FRONT_CENTER 0x2000
#constant SPEAKER_TOP_FRONT_RIGHT 0x4000
#constant SPEAKER_TOP_BACK_LEFT 0x8000
#constant SPEAKER_TOP_BACK_CENTER 0x10000
#constant SPEAKER_TOP_BACK_RIGHT 0x20000
rem IDirectSoundCapture attributes
#constant DSCCAPS_EMULDRIVER 0x00000020
#constant DSCCAPS_CERTIFIED 0x00000040
#constant DSCCAPS_MULTIPLECAPTURE 0x00000001
rem IDirectSoundCaptureBuffer attributes
#constant DSCBCAPS_WAVEMAPPED 0x80000000
#constant DSCBCAPS_CTRLFX 0x00000200
#constant DS3DALG_DEFAULT 0
#constant DS3DALG_NO_VIRTUALIZATION 1
#constant DS3DALG_HRTF_FULL 2
#constant DS3DALG_HRTF_LIGHT 3
#constant GUID_DSFX_STANDARD_GARGLE 4
#constant GUID_DSFX_STANDARD_CHORUS 5
#constant GUID_DSFX_STANDARD_FLANGER 6
#constant GUID_DSFX_STANDARD_ECHO 7
#constant GUID_DSFX_STANDARD_DISTORTION 8
#constant GUID_DSFX_STANDARD_COMPRESSOR 9
#constant GUID_DSFX_STANDARD_PARAMEQ 10
#constant GUID_DSFX_STANDARD_I3DL2REVERB 11
#constant GUID_DSFX_WAVES_REVERB 12
#constant GUID_DSCFX_CLASS_AEC 13
#constant GUID_DSCFX_MS_AEC 14
#constant GUID_DSCFX_SYSTEM_AEC 15
#constant GUID_DSCFX_CLASS_NS 16
#constant GUID_DSCFX_MS_NS 17
#constant GUID_DSCFX_SYSTEM_NS 18
function jzDSoundInit()
empty array dsoundguids()
rem DS3DALG_DEFAULT = 00000000-0000-0000-0000-000000000000
array insert at bottom dsoundGUIDs()
dsoundguids().Data1 = 0x00000000
dsoundguids().Data2 = 0x0000
dsoundguids().Data3 = 0x0000
dsoundguids().Data41 = 0x00
dsoundguids().Data42 = 0x00
dsoundguids().Data43 = 0x00
dsoundguids().Data44 = 0x00
dsoundguids().Data45 = 0x00
dsoundguids().Data46 = 0x00
dsoundguids().Data47 = 0x00
dsoundguids().Data48 = 0x00
rem DS3DALG_NO_VIRTUALIZATION (Pan3D) C241333F-1C1B-11d2-94F5-00C04FC28ACA
array insert at bottom dsoundGUIDs()
dsoundguids().Data1 = 0xC241333F
dsoundguids().Data2 = 0x1C1B
dsoundguids().Data3 = 0x11D2
dsoundguids().Data41 = 0x94
dsoundguids().Data42 = 0xF5
dsoundguids().Data43 = 0x00
dsoundguids().Data44 = 0xC0
dsoundguids().Data45 = 0x4F
dsoundguids().Data46 = 0xC2
dsoundguids().Data47 = 0x8A
dsoundguids().Data48 = 0xCA
rem DS3DALG_HRTF_FULL C2413340-1C1B-11d2-94F5-00C04FC28ACA
array insert at bottom dsoundGUIDs()
dsoundguids().Data1 = 0xC2413340
dsoundguids().Data2 = 0x1C1B
dsoundguids().Data3 = 0x11D2
dsoundguids().Data41 = 0x94
dsoundguids().Data42 = 0xF5
dsoundguids().Data43 = 0x00
dsoundguids().Data44 = 0xC0
dsoundguids().Data45 = 0x4F
dsoundguids().Data46 = 0xC2
dsoundguids().Data47 = 0x8A
dsoundguids().Data48 = 0xCA
rem DS3DALG_HRTF_LIGHT C2413342-1C1B-11d2-94F5-00C04FC28ACA
array insert at bottom dsoundGUIDs()
dsoundguids().Data1 = 0xC2413342
dsoundguids().Data2 = 0x1C1B
dsoundguids().Data3 = 0x11D2
dsoundguids().Data41 = 0x94
dsoundguids().Data42 = 0xF5
dsoundguids().Data43 = 0x00
dsoundguids().Data44 = 0xC0
dsoundguids().Data45 = 0x4F
dsoundguids().Data46 = 0xC2
dsoundguids().Data47 = 0x8A
dsoundguids().Data48 = 0xCA
rem GUID_DSFX_STANDARD_GARGLE DAFD8210-5711-4B91-9FE3-F75B7AE279BF
array insert at bottom dsoundGUIDs()
dsoundguids().Data1 = 0xDAFD8210
dsoundguids().Data2 = 0x5711
dsoundguids().Data3 = 0x4B91
dsoundguids().Data41 = 0x9F
dsoundguids().Data42 = 0xE3
dsoundguids().Data43 = 0xF7
dsoundguids().Data44 = 0x5B
dsoundguids().Data45 = 0x7A
dsoundguids().Data46 = 0xE2
dsoundguids().Data47 = 0x79
dsoundguids().Data48 = 0xBF
rem GUID_DSFX_STANDARD_CHORUS EFE6629C-81F7-4281-BD91-C9D604A95AF6
array insert at bottom dsoundGUIDs()
dsoundguids().Data1 = 0xEFE6629C
dsoundguids().Data2 = 0x81F7
dsoundguids().Data3 = 0x4281
dsoundguids().Data41 = 0xBD
dsoundguids().Data42 = 0x91
dsoundguids().Data43 = 0xC9
dsoundguids().Data44 = 0xD6
dsoundguids().Data45 = 0x04
dsoundguids().Data46 = 0xA9
dsoundguids().Data47 = 0x5A
dsoundguids().Data48 = 0xF6
rem GUID_DSFX_STANDARD_FLANGER EFCA3D92-DFD8-4672-A603-7420894BAD98
array insert at bottom dsoundGUIDs()
dsoundguids().Data1 = 0xEFCA3D92
dsoundguids().Data2 = 0xDFD8
dsoundguids().Data3 = 0x4672
dsoundguids().Data41 = 0xA6
dsoundguids().Data42 = 0x03
dsoundguids().Data43 = 0x74
dsoundguids().Data44 = 0x20
dsoundguids().Data45 = 0x89
dsoundguids().Data46 = 0x4B
dsoundguids().Data47 = 0xAD
dsoundguids().Data48 = 0x98
rem GUID_DSFX_STANDARD_ECHO EF3E932C-D40B-4F51-8CCF-3F98F1B29D5D
array insert at bottom dsoundGUIDs()
dsoundguids().Data1 = 0xEF3E932C
dsoundguids().Data2 = 0xD40B
dsoundguids().Data3 = 0x4F51
dsoundguids().Data41 = 0x8C
dsoundguids().Data42 = 0xCF
dsoundguids().Data43 = 0x3F
dsoundguids().Data44 = 0x98
dsoundguids().Data45 = 0xF1
dsoundguids().Data46 = 0xB2
dsoundguids().Data47 = 0x9D
dsoundguids().Data48 = 0x5D
rem GUID_DSFX_STANDARD_DISTORTION EF114C90-CD1D-484E-96E5-09CFAF912A21
array insert at bottom dsoundGUIDs()
dsoundguids().Data1 = 0xEF114C90
dsoundguids().Data2 = 0xCD1D
dsoundguids().Data3 = 0x484E
dsoundguids().Data41 = 0x96
dsoundguids().Data42 = 0xE5
dsoundguids().Data43 = 0x09
dsoundguids().Data44 = 0xCF
dsoundguids().Data45 = 0xAF
dsoundguids().Data46 = 0x91
dsoundguids().Data47 = 0x2A
dsoundguids().Data48 = 0x21
rem GUID_DSFX_STANDARD_COMPRESSOR EF011F79-4000-406D-87AF-BFFB3FC39D57
array insert at bottom dsoundGUIDs()
dsoundguids().Data1 = 0xEF011F79
dsoundguids().Data2 = 0x4000
dsoundguids().Data3 = 0x406D
dsoundguids().Data41 = 0x87
dsoundguids().Data42 = 0xAF
dsoundguids().Data43 = 0xBF
dsoundguids().Data44 = 0xFB
dsoundguids().Data45 = 0x3F
dsoundguids().Data46 = 0xC3
dsoundguids().Data47 = 0x9D
dsoundguids().Data48 = 0x57
rem GUID_DSFX_STANDARD_PARAMEQ 120CED89-3BF4-4173-A132-3CB406CF3231
dsoundguids().Data1 = 0x120CED89
dsoundguids().Data2 = 0x3BF4
dsoundguids().Data3 = 0x4173
dsoundguids().Data41 = 0xA1
dsoundguids().Data42 = 0x32
dsoundguids().Data43 = 0x3C
dsoundguids().Data44 = 0xB4
dsoundguids().Data45 = 0x06
dsoundguids().Data46 = 0xCF
dsoundguids().Data47 = 0x32
dsoundguids().Data48 = 0x31
rem GUID_DSFX_STANDARD_I3DL2REVERB EF985E71-D5C7-42D4-BA4D-2D073E2E96F4
dsoundguids().Data1 = 0xEF985E71
dsoundguids().Data2 = 0xD5C7
dsoundguids().Data3 = 0x42D4
dsoundguids().Data41 = 0xBA
dsoundguids().Data42 = 0x4D
dsoundguids().Data43 = 0x2D
dsoundguids().Data44 = 0x07
dsoundguids().Data45 = 0x3E
dsoundguids().Data46 = 0x2E
dsoundguids().Data47 = 0x96
dsoundguids().Data48 = 0xF4
rem GUID_DSFX_WAVES_REVERB 87FC0268-9A55-4360-95AA-004A1D9DE26C
dsoundguids().Data1 = 0x87FC0268
dsoundguids().Data2 = 0x9A55
dsoundguids().Data3 = 0x4360
dsoundguids().Data41 = 0x95
dsoundguids().Data42 = 0xAA
dsoundguids().Data43 = 0x00
dsoundguids().Data44 = 0x4A
dsoundguids().Data45 = 0x1D
dsoundguids().Data46 = 0x9D
dsoundguids().Data47 = 0xE2
dsoundguids().Data48 = 0x6C
rem GUID_DSCFX_CLASS_AEC BF963D80-C559-11D0-8A2B-00A0C9255AC1
dsoundguids().Data1 = 0xBF963D80
dsoundguids().Data2 = 0xC559
dsoundguids().Data3 = 0x11D0
dsoundguids().Data41 = 0x8A
dsoundguids().Data42 = 0x2B
dsoundguids().Data43 = 0x00
dsoundguids().Data44 = 0xA0
dsoundguids().Data45 = 0xC9
dsoundguids().Data46 = 0x25
dsoundguids().Data47 = 0x5A
dsoundguids().Data48 = 0xC1
rem GUID_DSCFX_MS_AEC CDEBB919-379A-488a-8765-F53CFD36DE40
dsoundguids().Data1 = 0xCDEBB919
dsoundguids().Data2 = 0x379A
dsoundguids().Data3 = 0x488A
dsoundguids().Data41 = 0x87
dsoundguids().Data42 = 0x65
dsoundguids().Data43 = 0xF5
dsoundguids().Data44 = 0x3C
dsoundguids().Data45 = 0xFD
dsoundguids().Data46 = 0x36
dsoundguids().Data47 = 0xDE
dsoundguids().Data48 = 0x40
rem GUID_DSCFX_SYSTEM_AEC 1C22C56D-9879-4f5b-A389-27996DDC2810
dsoundguids().Data1 = 0x1C22C56D
dsoundguids().Data2 = 0x9879
dsoundguids().Data3 = 0x4F5B
dsoundguids().Data41 = 0xA3
dsoundguids().Data42 = 0x89
dsoundguids().Data43 = 0x27
dsoundguids().Data44 = 0x99
dsoundguids().Data45 = 0x6D
dsoundguids().Data46 = 0xDC
dsoundguids().Data47 = 0x28
dsoundguids().Data48 = 0x10
rem GUID_DSCFX_CLASS_NS E07F903F-62FD-4e60-8CDD-DEA7236665B5
dsoundguids().Data1 = 0xE07F903F
dsoundguids().Data2 = 0x62FD
dsoundguids().Data3 = 0x4E60
dsoundguids().Data41 = 0x8C
dsoundguids().Data42 = 0xDD
dsoundguids().Data43 = 0xDE
dsoundguids().Data44 = 0xA7
dsoundguids().Data45 = 0x23
dsoundguids().Data46 = 0x66
dsoundguids().Data47 = 0x65
dsoundguids().Data48 = 0xB5
rem GUID_DSCFX_MS_NS 11C5C73B-66E9-4ba1-A0BA-E814C6EED92D
dsoundguids().Data1 = 0x11C5C73B
dsoundguids().Data2 = 0x66E9
dsoundguids().Data3 = 0x4BA1
dsoundguids().Data41 = 0xA0
dsoundguids().Data42 = 0xBA
dsoundguids().Data43 = 0xE8
dsoundguids().Data44 = 0x14
dsoundguids().Data45 = 0xC6
dsoundguids().Data46 = 0xEE
dsoundguids().Data47 = 0xD9
dsoundguids().Data48 = 0x2D
rem GUID_DSCFX_SYSTEM_NS 5AB0882E-7274-4516-877D-4EEE99BA4FD0
dsoundguids().Data1 = 0x5AB0882E
dsoundguids().Data2 = 0x7274
dsoundguids().Data3 = 0x4516
dsoundguids().Data41 = 0x87
dsoundguids().Data42 = 0x7D
dsoundguids().Data43 = 0x4E
dsoundguids().Data44 = 0xEE
dsoundguids().Data45 = 0x99
dsoundguids().Data46 = 0xBA
dsoundguids().Data47 = 0x4F
dsoundguids().Data48 = 0xD0
dxdlls.dsound = -1
dxdlls.dsoundmemory.memblockID = jzGetNextAvailableMemblockID(1)
make memblock dxdlls.dsoundmemory.memblockID, 256
dxdlls.dsoundmemory.ptr = get memblock ptr(dxdlls.dsoundmemory.memblockID)
endfunction
function jzGetDirectSoundErrorString(error as integer)
local errortext as string = "Unknown error code: " + hex$(error)
select error
case DS_OK
exitfunction "Success."
endcase
case DS_NO_VIRTUALIZATION
exitfunction "No virtulization."
endcase
case DSERR_ALLOCATED
exitfunction "Resource in use."
endcase
case DSERR_CONTROLUNAVAIL
exitfunction "Control unavailable."
endcase
case DSERR_INVALIDPARAM
exitfunction "Invalid parameter."
endcase
case DSERR_INVALIDCALL
exitfunction "Invalid call."
endcase
case DSERR_GENERIC
exitfunction "Undetermined generic error."
endcase
case DSERR_PRIOLEVELNEEDED
exitfunction "Priority level insufficient."
endcase
case DSERR_OUTOFMEMORY
exitfunction "Out of memory."
endcase
case DSERR_BADFORMAT
exitfunction "Bad format."
endcase
case DSERR_UNSUPPORTED
exitfunction "Unsupported."
endcase
case DSERR_NODRIVER
exitfunction "No driver."
endcase
case DSERR_ALREADYINITIALIZED
exitfunction "Already initialized."
endcase
case DSERR_NOAGGREGATION
exitfunction "Aggregation not supported."
endcase
case DSERR_BUFFERLOST
exitfunction "Buffer lost."
endcase
case DSERR_OTHERAPPHASPRIO
exitfunction "Another application has priority."
endcase
case DSERR_UNINITIALIZED
exitfunction "Not initialized."
endcase
case DSERR_NOINTERFACE
exitfunction "No interface."
endcase
case DSERR_ACCESSDENIED
exitfunction "Access denied."
endcase
case DSERR_BUFFERTOOSMALL
exitfunction "Buffer too small."
endcase
case DSERR_DS8_REQUIRED
exitfunction "DirectSound 8.0 required."
endcase
case DSERR_SENDLOOP
exitfunction "Circular effects loop detected."
endcase
case DSERR_BADSENDBUFFERGUID
exitfunction "Bad send buffer GUID."
endcase
case DSERR_OBJECTNOTFOUND
exitfunction "Object not found."
endcase
case DSERR_FXUNAVAILABLE
exitfunction "Effect not available."
endcase
case default
endcase
endselect
endfunction errortext
That's a lot of code, and I'd apologize, but...there's alot in there for someone willing to give it the once over. At the top in the first comment are the globals I use in DBPro...you will have to sort that, but...I think global is probably superfluous to your programs in DBC.
Basically, to use XInput is quite simple, you don't even need to get an interface to DirectX....too simple, really. The function
jzDoXBox360GameControl returns a DWORD that is the basis of creating a control unit that any sort of input can define, so that the game loop looks more state oriented, so as to eliminate alot of device-specific code in the game loop.
Next, there are third party options, but TBH...there is nearly always a catch of some sort with those, the most immutable of those is the fact that most generic options require another bit of code that is not geared to your game and generally unavailable for direct exchange of information. This is both difficult for casual gamers to get installed and working, and slower in general than what we already have, or can get at through the tools we were given by TGC when we bought their products.
XInput and DirectInput are great options for DB users because they are standard with DX9 and work across all of our code and systems very well. Other solutions, particularly ones based on .NET have less compatibility, and are onerous, to say the least.
I am hoping to change that drastically in the near term.
Here is an early version of that code above that might be easier on the eyes:
REM Project: xinput - Demonstrate support for XBox360 controllers.
REM Created: 12/12/2007 11:15:53 PM
REM
REM
remstart
Here are the prototypes for the entire XInput API:
DWORD XInputGetCapabilities(DWORD dwUserIndex, DWORD dwFlags,
XINPUT_CAPABILITIES* pCapabilities);
DWORD XInputGetKeystroke(DWORD dwUserIndex, DWORD dwReserved,
PXINPUT_KEYSTROKE pKeystroke);
DWORD XInputGetState(DWORD dwUserIndex, XINPUT_STATE* pState);
DWORD XInputSetState(DWORD dwUserIndex, XINPUT_VIBRATION* pVibration);
DWORD XInputGetDSoundAudioDeviceGuids(DWORD dwUserIndex, GUID* pDSoundRenderGuid,
GUID* pDSoundCaptureGuid);
void XInputEnable(BOOL enable);
remend
rem Device types available in XINPUT_CAPABILITIES
#constant XINPUT_DEVTYPE_GAMEPAD 0x01
rem Device subtypes available in XINPUT_CAPABILITIES
#constant XINPUT_DEVSUBTYPE_GAMEPAD 0x01
#constant XINPUT_DEVSUBTYPE_WHEEL 0x02
#constant XINPUT_DEVSUBTYPE_ARCADE_STICK 0x03
#constant XINPUT_DEVSUBTYPE_FLIGHT_SICK 0x04
#constant XINPUT_DEVSUBTYPE_DANCE_PAD 0x05
rem Flags for XINPUT_CAPABILITIES
#constant XINPUT_CAPS_VOICE_SUPPORTED 0x0004
rem Constants for gamepad buttons
#constant XINPUT_GAMEPAD_DPAD_UP 0x0001
#constant XINPUT_GAMEPAD_DPAD_DOWN 0x0002
#constant XINPUT_GAMEPAD_DPAD_LEFT 0x0004
#constant XINPUT_GAMEPAD_DPAD_RIGHT 0x0008
#constant XINPUT_GAMEPAD_START 0x0010
#constant XINPUT_GAMEPAD_BACK 0x0020
#constant XINPUT_GAMEPAD_LEFT_THUMB 0x0040
#constant XINPUT_GAMEPAD_RIGHT_THUMB 0x0080
#constant XINPUT_GAMEPAD_LEFT_SHOULDER 0x0100
#constant XINPUT_GAMEPAD_RIGHT_SHOULDER 0x0200
#constant XINPUT_GAMEPAD_A 0x1000
#constant XINPUT_GAMEPAD_B 0x2000
#constant XINPUT_GAMEPAD_X 0x4000
#constant XINPUT_GAMEPAD_Y 0x8000
rem Gamepad thresholds
#constant XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE 7849
#constant XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE 8689
#constant XINPUT_GAMEPAD_TRIGGER_THRESHOLD 30
rem Flags to pass to XInputGetCapabilities
#constant XINPUT_FLAG_GAMEPAD 0x00000001
rem Devices that support batteries
#constant BATTERY_DEVTYPE_HEADSET 0x01
rem Flags for battery status level
#constant BATTERY_TYPE_DISCONNECTED 0x00
#constant BATTERY_TYPE_WIRED 0x01
#constant BATTERY_TYPE_ALKALINE 0x02
#constant BATTERY_TYPE_NIMH 0x03
#constant BATTERY_TYPE_UNKNOWN 0xFF
rem These are only valid for wireless, connected devices, with known battery types
rem The amount of use time remaining depends on the type of device.
#constant BATTERY_LEVEL_EMPTY 0x00
#constant BATTERY_LEVEL_LOW 0x01
#constant BATTERY_LEVEL_MEDIUM 0x02
#constant BATTERY_LEVEL_FULL 0x03
rem User index definitions
#constant XUSER_MAX_COUNT 4
#constant XUSER_INDEX_ANY 0x000000FF
rem Types used by XInput.
type XINPUT_GAMEPAD
wButtons as word
bLeftTrigger as byte
bRightTrigger as byte
sThumbLX as word
sThumbsLY as word
sThumbRX as word
sThumbRY as word
endtype
#constant SIZEOF_XINPUT_GAMEPAD 12
type XINPUT_STATE
dwPacketNumber as dword
Gamepad as XINPUT_GAMEPAD
endtype
#constant SIZEOF_XINPUT_STATE 16
type XINPUT_VIBRATION
wLeftMotorSpeed as word
wRightMotorSpeed as word
endtype
#constant SIZEOF_XINPUT_VIBRATION 4
type XINPUT_CAPABILITIES
xType as byte
SubType as byte
Flags as word
Gamepad as XINPUT_GAMEPAD
Vibration as XINPUT_VIBRATION
endtype
#constant SIZEOF_XINPUT_CAPABILITIES 20
type XINPUT_BATTERY_INFORMATION
BatteryType as byte
BatteryLevel as byte
endtype
#constant SIZEOF_XINPUT_BATTERY_INFORMATION 2
type XINPUT_KEYSTROKE
VirtualKey as word
Unicode as word
Flags as word
UserIndex as byte
HidCode as byte
endtype
#constant SIZEOF_XINPUT_KEYSTROKE 8
type GUID
Data1 as dword
Data2 as word
Data3 as word
Data41 as byte
Data42 as byte
Data43 as byte
Data44 as byte
Data45 as byte
Data46 as byte
Data47 as byte
Data48 as byte
endtype
#constant SIZEOF_GUID 16
rem Types used by this code snippet.
#constant MAX_CONTROLLER 4
#constant ERROR_SUCCESS 0
type JZMEMORY
ptr as dword
memblockID as integer
endtype
type CONTROLLERMEMORY
inputstate as JZMEMORY
playbackGUID as JZMEMORY
captureGUID as JZMEMORY
endtype
type printposition
x as integer
y as integer
endtype
dim controller(MAX_CONTROLLER) as CONTROLLERMEMORY
dim line1(MAX_CONTROLLER) as printposition
dim line2(MAX_CONTROLLER) as printposition
dim line3(MAX_CONTROLLER) as printposition
dim line4(MAX_CONTROLLER) as printposition
dim line5(MAX_CONTROLLER) as printposition
dim line6(MAX_CONTROLLER) as printposition
dim line7(MAX_CONTROLLER) as printposition
dim line8(MAX_CONTROLLER) as printposition
dim line9(MAX_CONTROLLER) as printposition
line1(0).x = 80
line1(0).y = 10
line1(1).x = 596
line1(1).y = 10
line1(2).x = 80
line1(2).y = 393
line1(3).x = 596
line1(3).y = 393
line2(0).x = 80
line2(0).y = 40
line2(1).x = 596
line2(1).y = 40
line2(2).x = 80
line2(2).y = 416
line2(3).x = 596
line2(3).y = 416
line3(0).x = 80
line3(0).y = 60
line3(1).x = 596
line3(1).y = 60
line3(2).x = 80
line3(2).y = 436
line3(3).x = 596
line3(3).y = 436
line4(0).x = 80
line4(0).y = 80
line4(1).x = 596
line4(1).y = 80
line4(2).x = 80
line4(2).y = 456
line4(3).x = 596
line4(3).y = 456
line5(0).x = 80
line5(0).y = 100
line5(1).x = 596
line5(1).y = 100
line5(2).x = 80
line5(2).y = 476
line5(3).x = 596
line5(3).y = 476
line6(0).x = 80
line6(0).y = 120
line6(1).x = 596
line6(1).y = 120
line6(2).x = 80
line6(2).y = 496
line6(3).x = 596
line6(3).y = 496
line7(0).x = 80
line7(0).y = 140
line7(1).x = 520
line7(1).y = 140
line7(2).x = 80
line7(2).y = 516
line7(3).x = 520
line7(3).y = 516
line8(0).x = 20
line8(0).y = 160
line8(1).x = 520
line8(1).y = 160
line8(2).x = 20
line8(2).y = 536
line8(3).x = 520
line8(3).y = 536
line9(0).x = 20
line9(0).y = 180
line9(1).x = 520
line9(1).y = 180
line9(2).x = 20
line9(2).y = 556
line9(3).x = 520
line9(3).y = 556
global dwtemp as dword
global wtemp as word
global btemp as byte
global i as integer
global j as integer
global xinput as integer
global screen_x as integer
global screen_y as integer
global half_x as integer
global half_y as integer
rem First, obtain some memory for calls into XInput for the controller states, etc.
rem The GUIDs are for the headset audio, if attached. You can use them to create
rem DirectSound devices for capture and playback.
for i = 0 to MAX_CONTROLLER - 1
j = jzGetNextAvailableMemblockID(1)
make memblock j, SIZEOF_XINPUT_STATE
controller(i).inputstate.memblockID = j
controller(i).inputstate.ptr = get memblock ptr(j)
fill memory controller(i).inputstate.ptr, 0x00, SIZEOF_XINPUT_STATE
j = jzGetNextAvailableMemblockID(1)
make memblock j, SIZEOF_GUID
controller(i).playbackGUID.memblockID = j
controller(i).playbackGUID.ptr = get memblock ptr(j)
fill memory controller(i).playbackGUID.ptr, 0x00, SIZEOF_GUID
j = jzGetNextAvailableMemblockID(1)
make memblock j, SIZEOF_GUID
controller(i).captureGUID.memblockID = j
controller(i).captureGUID.ptr = get memblock ptr(j)
fill memory controller(i).captureGUID.ptr, 0x00, SIZEOF_GUID
next i
set display mode 1024, 768, 32
sync on
screen_x = screen width()
screen_y = screen height()
half_x = screen_x >> 1
half_y = screen_y >> 1
rem Next, load the XInput DLL.
xinput = jzGetNextAvailableDLLID(1)
load dll "xinput1_3.dll", xinput
call dll xinput, "XInputEnable", 1
do
cls
line half_x, 0, half_x, screen_y
line 0, half_y, screen_x, half_y
for i = 0 to MAX_CONTROLLER - 1
fill memory controller(i).inputstate.ptr, 0x00, SIZEOF_XINPUT_STATE
j = call dll(xinput, "XInputGetState", i, controller(i).inputstate.ptr)
set cursor line1(i).x, line1(i).y
print "Controller " + str$(i + 1);
if j <> ERROR_SUCCESS
print " not";
else
j = call dll(xinput, "XInputGetDSoundAudioDeviceGuids", i, ...
controller(i).playbackGUID.ptr, controller(i).captureGUID.ptr)
endif
print " connected.";
print " Packet: " + str$(memblock dword(controller(i).inputstate.memblockID, 0))
set cursor line2(i).x, line2(i).y
wtemp = memblock word(controller(i).inputstate.memblockID, 4)
if wtemp && XINPUT_GAMEPAD_A
set cursor line2(i).x, line2(i).y
ink rgb(0, 255, 0), 0
print "A ";
endif
if wtemp && XINPUT_GAMEPAD_B
set cursor line2(i).x + 32, line2(i).y
ink rgb(255, 0, 0), 0
print "B ";
endif
if wtemp && XINPUT_GAMEPAD_Y
set cursor line2(i).x + 64, line2(i).y
ink rgb(255, 255, 0), 0
print "Y ";
endif
if wtemp && XINPUT_GAMEPAD_X
set cursor line2(i).x + 96, line2(i).y
ink rgb(0, 0, 255), 0
print "X ";
endif
ink rgb(255, 255, 255), 0
set cursor line2(i).x + 128, line2(i).y
if wtemp && XINPUT_GAMEPAD_DPAD_UP
print "DPAD UP ";
endif
if wtemp && XINPUT_GAMEPAD_DPAD_DOWN
print "DPAD DOWN ";
endif
if wtemp && XINPUT_GAMEPAD_DPAD_LEFT
print "DPAD LEFT ";
endif
if wtemp && XINPUT_GAMEPAD_DPAD_RIGHT
print "DPAD RIGHT ";
endif
set cursor line3(i).x, line3(i).y
if wtemp && XINPUT_GAMEPAD_LEFT_SHOULDER
print "Left Shoulder ";
endif
if wtemp && XINPUT_GAMEPAD_RIGHT_SHOULDER
print "Right Shoulder ";
endif
set cursor line4(i).x, line4(i).y
print "Left Trigger :" + ...
str$(memblock byte(controller(i).inputstate.memblockID, 6));
set cursor line4(i).x + 160, line4(i).y
print "Right Trigger:" + ...
str$(memblock byte(controller(i).inputstate.memblockID, 7))
set cursor line5(i).x, line5(i).y
print "Lx :" + ...
str$(jzMakeWordIntValue(memblock word(controller(i).inputstate.memblockID, 8)));
print " Ly :" + ...
str$(jzMakeWordIntValue(memblock word(controller(i).inputstate.memblockID, 10)));
print " Rx :" + ...
str$(jzMakeWordIntValue(memblock word(controller(i).inputstate.memblockID, 12)));
print " Ry :" + ...
str$(jzMakeWordIntValue(memblock word(controller(i).inputstate.memblockID, 14)))
set cursor line6(i).x, line6(i).y
if wtemp && XINPUT_GAMEPAD_LEFT_THUMB
print "Left Thumb ";
endif
if wtemp && XINPUT_GAMEPAD_RIGHT_THUMB
print "Right Thumb ";
endif
set cursor line7(i).x, line7(i).y
if wtemp && XINPUT_GAMEPAD_START
print "START ";
endif
if wtemp && XINPUT_GAMEPAD_BACK
print "BACK ";
endif
set cursor line8(i).x, line8(i).y
print "playback GUID:" + ...
hex$(memblock dword(controller(i).playbackGUID.memblockID, 0)) + "-" + ...
hex$(memblock word(controller(i).playbackGUID.memblockID, 4)) + "-" + ...
hex$(memblock word(controller(i).playbackGUID.memblockID, 6)) + "-" + ...
hex$(memblock byte(controller(i).playbackGUID.memblockID, 7)) + ...
hex$(memblock byte(controller(i).playbackGUID.memblockID, 8)) + "-" + ...
hex$(memblock byte(controller(i).playbackGUID.memblockID, 9)) + ...
hex$(memblock byte(controller(i).playbackGUID.memblockID, 10)) + ...
hex$(memblock byte(controller(i).playbackGUID.memblockID, 11)) + ...
hex$(memblock byte(controller(i).playbackGUID.memblockID, 12)) + ...
hex$(memblock byte(controller(i).playbackGUID.memblockID, 13)) + ...
hex$(memblock byte(controller(i).playbackGUID.memblockID, 14))
set cursor line9(i).x, line9(i).y
print "capture GUID:" + ...
hex$(memblock dword(controller(i).captureGUID.memblockID, 0)) + "-" + ...
hex$(memblock word(controller(i).captureGUID.memblockID, 4)) + "-" + ...
hex$(memblock word(controller(i).captureGUID.memblockID, 6)) + "-" + ...
hex$(memblock byte(controller(i).captureGUID.memblockID, 7)) + ...
hex$(memblock byte(controller(i).captureGUID.memblockID, 8)) + "-" + ...
hex$(memblock byte(controller(i).captureGUID.memblockID, 9)) + ...
hex$(memblock byte(controller(i).captureGUID.memblockID, 10)) + ...
hex$(memblock byte(controller(i).captureGUID.memblockID, 11)) + ...
hex$(memblock byte(controller(i).captureGUID.memblockID, 12)) + ...
hex$(memblock byte(controller(i).captureGUID.memblockID, 13)) + ...
hex$(memblock byte(controller(i).captureGUID.memblockID, 14))
next i
set cursor 10, 725
print str$(screen fps()) + " fps"
sync
loop
for i = 0 to MAX_CONTROLLER - 1
if memblock exist(controller(i).inputstate.memblockID)
delete memblock controller(i).inputstate.memblockID
endif
if memblock exist(controller(i).playbackGUID.memblockID)
delete memblock controller(i).playbackGUID.memblockID
endif
if memblock exist(controller(i).captureGUID.memblockID)
delete memblock controller(i).captureGUID.memblockID
endif
next i
if dll exist(xinput)
delete dll xinput
endif
end
rem *******************************[END PROGRAM]*******************************************
function jzMakeWordIntValue(wordvalue as word)
local intValue as integer
if wordvalue && 0x08000
intValue = wordvalue - 65536
else
intValue = wordvalue
endif
endfunction intValue
function jzGetNextAvailableMemblockID(seed as integer)
local temp = seed
if seed < 1 then exitfunction -1
do
if memblock exist(temp) = 0 then exitfunction temp
inc temp
if temp < 0 then exitfunction -1
loop
endfunction -1
function jzGetNextAvailableDLLID(seed as integer)
local temp = seed
if seed < 1 or seed > 255 then exitfunction -1
do
if dll exist(temp) = 0 then exitfunction temp
inc temp
if temp > 255 then exitfunction -1
loop
endfunction -1
...And here is a bonus function for you, in case you are actually reading this:
function jzXBox360Vibrate(usernum as integer, vibeleft as word, viberight as word)
local dwtemp as dword
if usernum > -1 and usernum < MAX_CONTROLLER
write memblock word controller(usernum).inputstate.memblockID, 0, vibeleft
write memblock word controller(usernum).inputstate.memblockID, 2, viberight
dwtemp = call dll(dxdlls.xinput, "XInputSetState", usernum, ...
controller(usernum).inputstate.ptr)
else
dwtemp = 0xffffffff
endif
endfunction dwtemp
btw, the ... is to continue the line, you can edit it out and combine the lines if that is necessary. If you have any questions, ask...I will answer if I can.