Skip to content

Latest commit

 

History

History
340 lines (271 loc) · 10.4 KB

NOTES_IDirectInput.md

File metadata and controls

340 lines (271 loc) · 10.4 KB

This block of text has been generated by Chat-GPT. What is real and what is fake / untrue is yet to determine, but it can stil be useful for documentation purposes

Prompt:

List all the functions available in the IID_IDirectInput8 class with their prototypes

// Creates a new input device object
HRESULT CreateDevice(
    REFGUID rguid,
    LPDIRECTINPUTDEVICE8W* lplpDirectInputDevice,
    LPUNKNOWN pUnkOuter
);

// Enumerates the available input devices
HRESULT EnumDevices(
    DWORD dwDevType,
    LPDIENUMDEVICESCALLBACKW lpCallback,
    LPVOID pvRef,
    DWORD dwFlags
);

// Retrieves the currently available input device data
HRESULT GetDeviceStatus(
    REFGUID rguidInstance
);

// Runs a control panel applet for configuring input devices
HRESULT RunControlPanel(
    HWND hwndOwner,
    DWORD dwFlags
);

// Initializes the DirectInput API
HRESULT Initialize(
    HINSTANCE hinst,
    DWORD dwVersion
);

// Retrieves the version of the DirectInput API
HRESULT GetVersion(
    DWORD* pdwVersion
);

// Sets the cooperative level for the input devices
HRESULT SetCooperativeLevel(
    HWND hwnd,
    DWORD dwFlags
);

// Registers a device for input data
HRESULT RegisterDeviceNotification(
    HANDLE hRecipient,
    DWORD dwFlags
);

// Unregisters a device for input data
HRESULT UnregisterDeviceNotification(
    HANDLE hHandle
);

Prompt: Can you provide the methods of this class as well ?

// Sets the data format for the input device
HRESULT SetDataFormat(
    LPCDIDATAFORMAT lpFormat
);

// Sets the cooperative level for the input device
HRESULT SetCooperativeLevel(
    HWND hwnd,
    DWORD dwFlags
);

// Acquires the input device
HRESULT Acquire();

// Unacquires the input device
HRESULT Unacquire();

// Retrieves the current input device state
HRESULT GetDeviceState(
    DWORD cbData,
    LPVOID lpvData
);

// Retrieves the capabilities of the input device
HRESULT GetCapabilities(
    LPDIDEVCAPS lpDIDevCaps
);

// Enumerates the available object types for the input device
HRESULT EnumObjects(
    LPDIENUMDEVICEOBJECTSCALLBACKW lpCallback,
    LPVOID pvRef,
    DWORD dwFlags
);

// Retrieves the properties of a specific object on the input device
HRESULT GetObjectInfo(
    LPDIDEVICEOBJECTINSTANCEW pdidoi,
    DWORD dwObj,
    DWORD dwHow
);

// Retrieves the properties of the input device's force feedback system
HRESULT GetForceFeedbackState(
    LPDWORD pdwOut
);

// Sends a force feedback effect to the input device
HRESULT SendForceFeedbackCommand(
    DWORD dwFlags
);

// Sends a force feedback effect to the input device
HRESULT SendForceFeedbackEffect(
    LPDIEFFECT lpEff,
    DWORD dwFlags
);

// Retrieves the status of a force feedback effect on the input device
HRESULT GetForceFeedbackEffectStatus(
    DWORD dwFlags,
    LPDWORD pdwOut
);

// Downloads a force feedback effect to the input device
HRESULT DownloadEffect(
    LPDIEFFECT lpEff,
    LPDWORD pdwEffectId,
    DWORD dwFlags
);

// Removes a force feedback effect from the input device
HRESULT UnloadEffect(
    DWORD dwEffectId
);

Warning /!\ Here DirectInput version is 8 and not 5 (hope this isnt very important)

Prompt: Can you provide an example usage of the GetDeviceState function ?

#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>

LPDIRECTINPUT8 g_pDI = NULL;
LPDIRECTINPUTDEVICE8 g_pDevice = NULL;
HRESULT hr;

// Initialize DirectInput
hr = DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&g_pDI, NULL);

// Create the input device
hr = g_pDI->CreateDevice(GUID_SysKeyboard, &g_pDevice, NULL);

// Set the data format for the device
hr = g_pDevice->SetDataFormat(&c_dfDIKeyboard);

// Set the cooperative level for the device
hr = g_pDevice->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_EXCLUSIVE);

// Acquire the device
hr = g_pDevice->Acquire();

// Loop to handle input events
while (true)
{
    // Get the current state of the keyboard
    char keyboardState[256];
    hr = g_pDevice->GetDeviceState(sizeof(keyboardState), (LPVOID)&keyboardState);

    // Check for errors or lost input
    if (FAILED(hr))
    {
        // Try to re-acquire the device
        hr = g_pDevice->Acquire();
        continue;
    }

    // Check for keys that are currently pressed
    for (int i = 0; i < 256; ++i)
    {
        if (keyboardState[i] & 0x80)
        {
            // Handle the pressed key
            // ...
        }
    }
}

Prompt: What is the c_dfDIKeyboard variable in this example ?

Answer: The c_dfDIKeyboard variable in the example is a predefined data format structure that specifies the format of the data that will be retrieved from a keyboard device. It is a constant of type DIDATAFORMAT that is defined in the dinput.h header file, and it contains information about the keyboard device's button and key states.

By calling the SetDataFormat method of the IDirectInputDevice8 interface and passing in the c_dfDIKeyboard variable as an argument, the application is telling DirectInput that it wants to receive input data from a keyboard device, and it wants that data to be formatted in the standard keyboard data format.

Here's the definition of the c_dfDIKeyboard constant:

const DIDATAFORMAT c_dfDIKeyboard = {
    sizeof(DIDATAFORMAT),
    sizeof(DIDEVICEOBJECTDATA),
    DIDF_RELAXIS,
    (DWORD)256,
    (DWORD)sizeof(DIDEVICEOBJECTDATA),
    (DWORD)DIK_ESCAPE,
    (DWORD)DIKEYBOARD_MAX,
    sizeof(DIPROPDWORD),
    0,
    NULL,
    NULL,
};

This structure contains various pieces of information about the data format, such as the size of the structure, the size of each data element, the minimum and maximum values of the data, and so on. By using this predefined format, the application can be sure that it will receive input data in a consistent and standardized way, regardless of the specific keyboard device being used.

Prompt: How would I check if the space button is pressed or released ?

To check if the space button is pressed or released using DirectInput, you can retrieve the current state of the keyboard using the GetDeviceState method of the IDirectInputDevice8 interface, and then check the corresponding bit in the retrieved state array for the space key.

Here's an example:

#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>

LPDIRECTINPUT8 g_pDI = NULL;
LPDIRECTINPUTDEVICE8 g_pDevice = NULL;
HRESULT hr;

// Initialize DirectInput
hr = DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&g_pDI, NULL);

// Create the input device
hr = g_pDI->CreateDevice(GUID_SysKeyboard, &g_pDevice, NULL);

// Set the data format for the device
hr = g_pDevice->SetDataFormat(&c_dfDIKeyboard);

// Set the cooperative level for the device
hr = g_pDevice->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_EXCLUSIVE);

// Acquire the device
hr = g_pDevice->Acquire();

// Previous state of the space key
bool bPrevSpacePressed = false;

// Loop to handle input events
while (true)
{
    // Get the current state of the keyboard
    char keyboardState[256];
    hr = g_pDevice->GetDeviceState(sizeof(keyboardState), (LPVOID)&keyboardState);

    // Check for errors or lost input
    if (FAILED(hr))
    {
        // Try to re-acquire the device
        hr = g_pDevice->Acquire();
        continue;
    }

    // Check if the space key is currently pressed
    bool bSpacePressed = (keyboardState[DIK_SPACE] & 0x80) != 0;

    // Check if the space key was just pressed
    if (bSpacePressed && !bPrevSpacePressed)
    {
        // Handle the space key press event
        // ...
    }

    // Check if the space key was just released
    if (!bSpacePressed && bPrevSpacePressed)
    {
        // Handle the space key release event
        // ...
    }

    // Save the current state of the space key for the next iteration
    bPrevSpacePressed = bSpacePressed;
}

Prompt: Can you provide the class source code for the IID_IDirectInput8 class ?

The IID_IDirectInput8 class is not an actual class in DirectInput, but rather an interface identifier that is used to identify the IDirectInput8 interface. As such, there is no source code for the IID_IDirectInput8 class. Instead, the IDirectInput8 interface is defined in the dinput.h header file, which is included in DirectInput applications.

Here is an example of the definition of the IDirectInput8 interface in dinput.h:

#undef INTERFACE
#define INTERFACE IDirectInput8A
DECLARE_INTERFACE_(IDirectInput8A,IUnknown)
{
    // IUnknown methods
    STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID *ppvObj) PURE;
    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
    STDMETHOD_(ULONG,Release)(THIS) PURE;

    // IDirectInput8A methods
    STDMETHOD(CreateDevice)(THIS_ REFGUID rguid, LPDIRECTINPUTDEVICE8A *lplpDirectInputDevice, LPUNKNOWN pUnkOuter) PURE;
    STDMETHOD(EnumDevices)(THIS_ DWORD dwDevType, LPDIENUMDEVICESCALLBACKA lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
    STDMETHOD(GetDeviceStatus)(THIS_ REFGUID rguidInstance) PURE;
    STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
    STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion) PURE;
    STDMETHOD(FindDevice)(THIS_ REFGUID rguidClass, LPCSTR ptszName, LPGUID pguidInstance) PURE;
    STDMETHOD(EnumDevicesBySemantics)(THIS_ LPCSTR ptszUserName, LPDIACTIONFORMATA lpdiActionFormat, LPDIENUMDEVICESBYSEMANTICSCBA lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
    STDMETHOD(ConfigureDevices)(THIS_ LPDICONFIGUREDEVICESCALLBACK lpdiCallback, LPDICONFIGUREDEVICESPARAMSA lpdiCDParams, DWORD dwFlags, LPVOID pvRefData) PURE;
};

The IDirectInput8 interface inherits from the IUnknown interface, which is a standard interface for COM objects. The interface defines several methods for creating and enumerating input devices, getting the status of a device, and initializing and configuring DirectInput.

After some talking, here is what I got from Chat-GPT:

Here are the method names for each offset:

Offset Method 0x8 QueryInterface 0xc EnumDevices 0x10 ConfigureDevices (personal note: This function is never called) 0x18 GetDeviceStatus 0x20 RunControlPanel 0x28 Initialize

These are all methods of the IDirectInput8 interface. The QueryInterface method is used to query the interface for other interfaces that it may implement. The GetDeviceStatus method is used to retrieve the status of a device. The RunControlPanel method is used to run the DirectInput control panel. The Initialize method is used to initialize DirectInput.

Note: This looks incorrect when looking at the list of methods defined just above. The offset 0x8 should be the destructor which look like it is according to this function: FUN_00489e40