Sign in to follow this  
Daaark

DirectInput Questions

Recommended Posts

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;
}

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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));
}


Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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[i] == KeysPrev[i]) Keys[i] = 0;
else KeysPrev[i] = Keys[i];
}



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

Share this post


Link to post
Share on other sites
Everywhere I look about the mouse coords problem, it is written to use GetCursorPos() if you want the exact pixel location of the cursor. Doesn't this defeat the purpose of using DirectInput in the first place? [depressed]

I tried to track it on my own, adding the relative coords to some that I set to GetCursorPos when the mouse is acquired, but it goes off after a second by an increasing ammount, because the mouse can move faster then 60fps(I guess).

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this