News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Getting my joystick working under Direct Input

Started by hamper, December 01, 2013, 10:00:30 AM

Previous topic - Next topic

hamper

Re "the simplest way is probably to use dynamic linking that will get you up and running", well I looked up how to do that, but it all depends on knowing, of course, which particular .dll you need to dynamically link. I studied the utility "dumpbin" and tried to use that to try and find out which functions were in which libraries, but all I ever got out from it was an empty text file (0 bytes in length).

dedndave

i wanted to go a similar path
build the directx SDK joystick example, then disassemble it to see the imports
unfortunately, the VS C++ version that i have is apparently too old to build the example

but, let me see if i can struggle my way through the source.....

dedndave

ahhhh - i found Joystick.exe in the bin folder   :P

i used an old DisAsm program to get the imports
those of interest....
   Import Module 004: DINPUT8.dll

Addr:0000326C hint(0000) Name: DirectInput8Create

   Import Module 006: OLEAUT32.dll

Addr:80000006 hint(0006) Name: OLEAUT32:NoName0000
Addr:80000002 hint(0002) Name: OLEAUT32:NoName0001

   Import Module 008: ole32.dll

Addr:000032E0 hint(0010) Name: CoCreateInstance
Addr:000032F4 hint(003E) Name: CoInitialize
Addr:000032CC hint(0063) Name: CoSetProxyBlanket


so, it would seem the dinput8 inc/lib has all we need
what we want is the GUID(s) for the COM interface - that should be a matter of google'ing
CoSetProxyBlanket is a new one on me - i may have to look that one up - lol

jj2007

Quote from: hamper on December 03, 2013, 05:37:00 AMI studied the utility "dumpbin" and tried to use that to try and find out which functions were in which libraries, but all I ever got out from it was an empty text file (0 bytes in length).

Example: \masm32\bin\dumpbin /exports dx8vb.dll >1.txt

Result attached, but it's not the solution :(

hamper

In the link that jj2007 provided a few posts back, the author mentions two possible approaches, and the second approach uses the "CoCreateInstance"... methodology. I'd found the DirectInputCreateA function, but there's loads of other functions used by the author which I couldn't find anywhere (that's not to say they're not there - just that I simply could not find them).

But even if the function CoCreateInstance, et al, have now been found lurking around ole32.dll (thanks dave), it still leaves all the other functions needed, such as CreateDevice, EnumDevices, SetDataFormat, SetCooperativeLevel, and so on, and I've no idea where any of them are. The author mentions one function is in the regular WindowsAPI, but there's no mention of it in the WindowsAPI help file! All very, very confusing to me.


dedndave

those are "sub-functions" (i forget what they're called - lol) of the COM interface

because a joystick is not the simplest example of COM,
perhaps a simple COM example is in order - to get you warmed up

in the mean time - i am doing some reading on the DirectInput COM interface....
check your PM's

Antariy

Did not read the whole thread yet, but maybe these functions are the COM-based virtual-table functions of object that was created by DirectInput8Create?

Antariy

Ah, did not refreshed the page, Dave has already posted this thought.

hamper

Will do.

In the meantime I've been running Borland's IMPDEF.EXE program on the following - dinput.dll, dinput8.dll, dx7vb.dll, dx8vb.dll, hid.dll, mmcbase.dll, mmfutil.dll, mmsystem.dll, mmutilse.dll and winmm.dll. It doesn't report any of the elusive functions in any of them. They're also not mentioned in the WindowsAPI. The search continues I guess, but something must be doing the job, because my joystick works automatically under the Windows (e.g. the calibration program from the Start menu).

dedndave

it's COM stuff
once you create a COM instance, the "virtual-table functions" are available (thanks Alex  :biggrin: )

i really like qWord's "METHOD" macro for COM interfaces
i was trying to find a simple example for you to get your feet wet

Antariy


DEFINE_GUID(GUID_Joystick   ,0x6F1D2B70,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);

extern HRESULT WINAPI DirectInput8Create(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID *ppvOut, LPUNKNOWN punkOuter);


DECLARE_INTERFACE_(IDirectInputDevice8A, IUnknown)
{
    /*** IUnknown methods ***/
    STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE;
    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
    STDMETHOD_(ULONG,Release)(THIS) PURE;

    /*** IDirectInputDevice8A methods ***/
    STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS) PURE;
    STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKA,LPVOID,DWORD) PURE;
    STDMETHOD(GetProperty)(THIS_ REFGUID,LPDIPROPHEADER) PURE;
    STDMETHOD(SetProperty)(THIS_ REFGUID,LPCDIPROPHEADER) PURE;
    STDMETHOD(Acquire)(THIS) PURE;
    STDMETHOD(Unacquire)(THIS) PURE;
    STDMETHOD(GetDeviceState)(THIS_ DWORD,LPVOID) PURE;
    STDMETHOD(GetDeviceData)(THIS_ DWORD,LPDIDEVICEOBJECTDATA,LPDWORD,DWORD) PURE;
    STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT) PURE;
    STDMETHOD(SetEventNotification)(THIS_ HANDLE) PURE;
    STDMETHOD(SetCooperativeLevel)(THIS_ HWND,DWORD) PURE;
    STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEA,DWORD,DWORD) PURE;
    STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEA) PURE;
    STDMETHOD(RunControlPanel)(THIS_ HWND,DWORD) PURE;
    STDMETHOD(Initialize)(THIS_ HINSTANCE,DWORD,REFGUID) PURE;
    STDMETHOD(CreateEffect)(THIS_ REFGUID,LPCDIEFFECT,LPDIRECTINPUTEFFECT *,LPUNKNOWN) PURE;
    STDMETHOD(EnumEffects)(THIS_ LPDIENUMEFFECTSCALLBACKA,LPVOID,DWORD) PURE;
    STDMETHOD(GetEffectInfo)(THIS_ LPDIEFFECTINFOA,REFGUID) PURE;
    STDMETHOD(GetForceFeedbackState)(THIS_ LPDWORD) PURE;
    STDMETHOD(SendForceFeedbackCommand)(THIS_ DWORD) PURE;
    STDMETHOD(EnumCreatedEffectObjects)(THIS_ LPDIENUMCREATEDEFFECTOBJECTSCALLBACK,LPVOID,DWORD) PURE;
    STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE) PURE;
    STDMETHOD(Poll)(THIS) PURE;
    STDMETHOD(SendDeviceData)(THIS_ DWORD,LPCDIDEVICEOBJECTDATA,LPDWORD,DWORD) PURE;
    STDMETHOD(EnumEffectsInFile)(THIS_ LPCSTR,LPDIENUMEFFECTSINFILECALLBACK,LPVOID,DWORD) PURE;
    STDMETHOD(WriteEffectToFile)(THIS_ LPCSTR,DWORD,LPDIFILEEFFECT,DWORD) PURE;
    STDMETHOD(BuildActionMap)(THIS_ LPDIACTIONFORMATA,LPCSTR,DWORD) PURE;
    STDMETHOD(SetActionMap)(THIS_ LPDIACTIONFORMATA,LPCSTR,DWORD) PURE;
    STDMETHOD(GetImageInfo)(THIS_ LPDIDEVICEIMAGEINFOHEADERA) PURE;
};


Probably the way to get the interface of Joystic is something like (pseudocode):

LOCAL obj:DWORD
LOCAL wtf:DWORD

invoke DirectInput8Create,GetModuleHandle(0),0800h,offset GUID_Joystick,addr obj, addr wtf

If the call was successfull, then in the obj is the address of the object of DirectInput.
The virtual table is above in the post... i.e., to call the function GetCapabilities, for an instance, you need this:

mov eax,obj
push eax
mov eax,[eax]
call dword ptr [eax+3*4]

hamper

Thanks for the PM dedndave, I tried to reply but I'm not sure it worked. Will have to download and read tomorrow now - I've already exceeded my internet usage limit for today, so will have to log off very shortly.

dedndave

i am doing some reading, Alex
once you get the COM interface going, the next thing to do is to enumerate input devices

for hamper....
here is the MSDN page (with links) for COM interface

if you try to read it like a book, you will be watching porn in about 30 minutes - lol
instead - use it as a reference to look up specific things you have questions about

http://msdn.microsoft.com/en-us/library/windows/desktop/ms680573%28v=vs.85%29.aspx

above, Alex has posted some example COM code
i was going to find one that was really simple - lol

jj2007

Quote from: hamper on December 03, 2013, 06:08:01 AMAll very, very confusing to me.

Yep, that's COM. There is a good tutorial by Michael Dunn, Introduction to COM - What It Is and How to Use It. COM is very powerful but the learning curve is kind of steep.

Here is a very simple demo, it opens Masm32 in Internet Explorer:

include \masm32\MasmBasic\MasmBasic.inc        ; download
.code                ; This COM demo opens a page in MS Internet Explorer
CLSID_IExplorer           GuidFromString("0002DF01-0000-0000-C000-000000000046")
IID_IWebBrowser2          GuidFromString(D30C1661-CDAF-11D0-8A3E-00C04FC9E26E)

MyBrowser proc uses edi url
LOCAL vEmpty:VARIANT, hWin, WebInterface
  ClearLocals
  lea edi, WebInterface
  pInterface equ dword ptr [edi]
  invoke CoCreateInstance, addr CLSID_IExplorer, NULL, CLSCTX_LOCAL_SERVER, addr IID_IWebBrowser2, edi
  .if eax==S_OK                ; OK, now configure the browser:
        CoInvoke pInterface, IWebBrowserVtbl.put_Visible, VARIANT_TRUE
        lea edx, vEmpty                ; it needs pointers to four empty VARIANTS
        CoInvoke pInterface, IWebBrowserVtbl.Navigate, Ole$(url), edx, edx, edx, edx        ; COM needs a BSTR, so the ANSI URL needs to be converted
  .endif
  ret
MyBrowser endp
        Init
        invoke OleInitialize, NULL
        .if eax==S_OK
            invoke MyBrowser, Chr$("http://masm32.com/board/index.php?action=unread")
        .endif
        invoke OleUninitialize
        Exit
end start

dedndave

to understand that code, he also has to learn MasmBasic
probably a bit much to unload on him all at once - COM is bad enough   :P

personally, i learned from examples by Donkey (Edgar) and qWord
Edgar's code is in GoAsm, of course - but it still helped a lot