DirectInput Questions

Started by
9 comments, last by Daaark 18 years, 9 months ago
I'm new to everything DX, so I just have some stupid questions... :D
LPDIRECTINPUT8       diObject   = NULL; // The DirectInput object         
LPDIRECTINPUTDEVICE8 diKeyboard = NULL; // The keyboard device 
LPDIRECTINPUTDEVICE8 diMouse    = NULL; // The mouse device
What are the LPDIRECTINPUT objects for? I use it to get to my keyboard object, and then it seems I never have to call it again, other than to release it when I'm done. Am I supposed to create my mouse 'under' this thing too, or do I make a new one for it? Also, what does this do? "&0 x80"?
if( keys[DIK_A] &0 x80)
{
    // The 'A' key has been pressed on the keyboard
    // We don't know if it's keydown or keyup
}
This is what I put together after looking at some samples, and the docs. am I on the right path?
//input.cpp
//all input related functions belong in this file

#include "main.h"


#define DIRECTINPUT_VERSION 0x0800
#include "dinput.h"

#define SAFE_DELETE(p)  { if(p) { delete (p);     (p)=NULL; } }
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }

extern bool bAcquired;


LPDIRECTINPUT8       diObject   = NULL; // The DirectInput object         
LPDIRECTINPUTDEVICE8 diKeyboard = NULL; // The keyboard device 
LPDIRECTINPUTDEVICE8 diMouse    = NULL; // The mouse device


// *** Init functions


void InputAcquire(void)
{
    diKeyboard->Acquire();
    //diMouse->Acquire();
    
    bAcquired = true;
    
    return;
}


bool InputInit(HWND hWnd)
{
    
    DWORD   dwKeyboardFlags = DISCL_FOREGROUND|DISCL_EXCLUSIVE;
    DWORD   dwMouseFlags;
    
    HRESULT hResult = NULL;
    
    // Create a DirectInput object
    if (DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, 
    IID_IDirectInput8, (VOID**)&diObject, NULL) != DI_OK)        
    {
        MessageBox(NULL,"ERROR: Failed to initialize Direct Input.",
        APP_TITLE,MB_OK|MB_ICONERROR);
        return false;
    }
    
    //create an interface to the keyboard
    if (diObject->CreateDevice(GUID_SysKeyboard, &diKeyboard, NULL)!= DI_OK)
    {
        MessageBox(NULL,"ERROR: Failed to acquire the keyboard.",
        APP_TITLE,MB_OK|MB_ICONERROR);
        return false;
    }
    
    //set the dataformat
    if (diKeyboard->SetDataFormat(&c_dfDIKeyboard) != DI_OK)
    {
        MessageBox(NULL,"ERROR: Failed to set keyboard data format.",
        APP_TITLE,MB_OK|MB_ICONERROR);
        return false;
    }
    
    //set the cooperation level
    if (diKeyboard->SetCooperativeLevel(hWnd,dwKeyboardFlags) != DI_OK)
    {
        MessageBox(NULL,"ERROR: Failed to set keyboard co-op level.",
        APP_TITLE,MB_OK|MB_ICONERROR);
        return false;
    }    
    

    InputAcquire();

    return true;
}


void InputShutdown(void)
{
    
    if (diKeyboard) diKeyboard->Unacquire();
    
    // Release any DirectInput objects.
    SAFE_RELEASE(diKeyboard);
    SAFE_RELEASE(diObject);   

    return;
}


// *** Standard Functions


//check the mouse and keyboard
void InputPoll(void)
{
    HRESULT hRes;
    BYTE    Keys[256];
    
    ZeroMemory(Keys,sizeof(Keys));
    
    hRes = diKeyboard->GetDeviceState(sizeof(Keys),Keys);        
    if (hRes != DI_OK)
    {
        if (hr == DIERR_INPUTLOST) diKeyboard->Acquire();
        return;    
    }

    //nothing here yet


    return;
}
Advertisement
Quote:Original post by Vampyre_Dark
What are the LPDIRECTINPUT objects for? I use it to get to my keyboard object, and then it seems I never have to call it again, other than to release it when I'm done. Am I supposed to create my mouse 'under' this thing too, or do I make a new one for it?

It's always a good idea to read the documentation. The documentation of IDirectInput8 answers your question:
Applications use the methods of the IDirectInput8 interface to enumerate, create, and retrieve the status of Microsoft DirectInput devices, initialize the DirectInput object, and invoke an instance of the Microsoft Windows Control Panel


So yes, create your mouse under this object too. You typically create one input object per application.

Quote:Also, what does this do? "&0x80"?

if( keys[DIK_A] & 0x80){    // The 'A' key has been pressed on the keyboard    // We don't know if it's keydown or keyup}

0x80 hexadecimal is 10000000 in binary. The bitwise and operation yields a non-zero value only if keys[DIK_A] eighth bit is set, which happens when the key is down. So the comment in the code is wrong, you now know the key is down.


I am reading the docs, it's slowly sinking in. But I can't absorb the whole API and how everything works in 2 days. There's so much to take in, and it's all different then what I'm used to, having never touched a com setup before.

When I switch between windows, I lose my keyboard, and my old windows key_up messages which I have yet to remove start to work again. Do I just have to call device->acquire() again? It 'works' when I called my InputAcquire() function n WM_ACTIVATE, but I'm not sure that I don't have to set the dataformat and all that again, as I am yet to actually try to acquire any input.

The code snippet you say is wrong was taken out of this forum's FAQ.

Quote:Original post by Vampyre_Dark
When I switch between windows, I lose my keyboard, and my old windows key_up messages which I have yet to remove start to work again. Do I just have to call device->acquire() again? It 'works' when I called my InputAcquire() function n WM_ACTIVATE, but I'm not sure that I don't have to set the dataformat and all that again, as I am yet to actually try to acquire any input.


Yeah, you just have to call Acquire() again. It's usually a good idea to loop until the device is actually Acquire()'d since it might not immediately be available to re Acquire(). Code snippet:

/*EDIT: m_direct3D is a pointer to a LPDIRECT3DDEVICE9. m_keyboard is a DirectInput device.The HandleMessages() function runs through the whole PeekMessage() messaging thing for your Window. You have to call it here otherwise it doesn't let you reacquire the device.*/HRESULT hResultKeyboard = m_keyboard->GetDeviceState(256, &m_keyBuffer);	if(hResultKeyboard == DIERR_INPUTLOST){			do	{		hResultKeyboard = m_keyboard->Acquire();			m_window->HandleMessages(*m_direct3D);		Sleep(10);	}	while(FAILED(hResultKeyboard));}
Quote:Original post by Vampyre_Dark
I am reading the docs, it's slowly sinking in. But I can't absorb the whole API and how everything works in 2 days. There's so much to take in, and it's all different then what I'm used to, having never touched a com setup before.

It's Ok [smile]
I was just reminding you to search the docs when you have a question about something specific (as opposed to sequential reading).

Quote:The code snippet you say is wrong was taken out of this forum's FAQ.

[embarrass] Now that's embarassing. I fixed it in the FAQ.

Does a user pressing a key, or mouse button between checks (once per frame) become a problem in immediate mode?
Quote:Original post by Vampyre_Dark
Does a user pressing a key, or mouse button between checks (once per frame) become a problem in immediate mode?


I don't think it'll be a problem except at very low fps. Hmm... I'll go toy with Sleep() sometime today and tell you if I hit some sort of a FPS threshhold where input slips through. I'm interested in finding out myself. [smile]
Hey Vampyre_Dark
I just did some work on a simple DInput class. If you have anymore questions I can try to help. This way I can get some more practice and see if I understand everything correctly also. I did a simple class, no action mapping, but multiple joysticks and 1 keyboard (no mouse, but mouse is same as keyboard pretty much in terms of difficulty to understand). I just have what I know fresh in my mind so if you have some questions I can try to help. you can e-mail MAZ at WPI dot EDU or pm me I usually notice when I have pm's

-THACO
Heh, now I have to get used to something new.

GAME MODE: Game
User pressed 'Q' to quit the menu

Game Mode: Menu
'Q' still pressed, quit program. [lol]

All this in a blink of an eye.
If I store the last keyboard values, then scan the new values against the previous array of data, eliminating anything that is the same, would that be a good fix for the above problem?

And do I set them to 0, or some other hex value?

-edit-
okay, this did the trick. I checked the documentation for possible values, but the only thing I ever saw mentioned was 0x80 for a depressed key (which make sme wonder why not just use true or false?), so I'll assume this is the proper way.
    //compare the old keys with the current keys    //and nullify any similar values and then    //copy the current Keys array into KeysPrev    //so that it can be compared next call    for (int i = 0; i < 256; ++i)    {        if (Keys == KeysPrev) Keys = 0;        else KeysPrev = Keys;    }


[Edited by - Vampyre_Dark on June 25, 2005 2:54:43 AM]

This topic is closed to new replies.

Advertisement