Example #1
0
s32 F_API INPKBUpdate()
{
	if(!g_pDKeyboard)
		return RETCODE_SUCCESS;

	u32 i;

	//////////////////////
	//reset buffer
	for(i=0; i < g_prevKNum; i++)
	{
		if(KEYRELEASED(g_buffState[i].ofs))
		{
			g_buffState[i].state = INPUT_UP;
			g_keyState[g_buffState[i].ofs] = INPUT_UP;
		}
	}

	g_buffStateSize = 0;
	//////////////////////

	HRESULT hr;

	g_prevKNum = SAMPLE_BUFFER_SIZE;
	
	//First, check to see if the keyboard is still working/functioning
    hr= g_pDKeyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA),g_pKbBuff,(LPDWORD)&g_prevKNum,0);
    if(hr != DI_OK)
	{
		g_prevKNum = 0;

		//did we lose the keyboard?
        if(hr==DIERR_INPUTLOST || hr==DIERR_NOTACQUIRED) 
		{
			//we gotta have it back!
			g_pDKeyboard->Acquire();
			/*hr = g_pDKeyboard->Acquire();
			if(FAILED(hr))
			{ DInputError(hr, "_INPKBUpdate"); return RETCODE_FAILURE; }
*/
			return RETCODE_SUCCESS;
		}
		else
			return RETCODE_FAILURE;
	}

	//update the keyboard states
	for(i=0; i < g_prevKNum; i++)
	{
		g_buffState[i].ofs = g_pKbBuff[i].dwOfs;
		g_buffState[i].state = (g_pKbBuff[i].dwData & INPUT_DOWN) ? INPUT_DOWN : INPUT_RELEASED;

		g_keyState[g_buffState[i].ofs] = g_buffState[i].state;
	}

	g_buffStateSize=g_prevKNum;

	return RETCODE_SUCCESS;
}
void PsychHIDOSKbQueueFlush(int deviceIndex)
{
    LPDIRECTINPUTDEVICE8 kb;
    HRESULT rc;
    DWORD dwItems = INFINITE;

    if (deviceIndex < 0) {
        deviceIndex = PsychHIDGetDefaultKbQueueDevice();
        // Ok, deviceIndex now contains our default keyboard to use - The first suitable keyboard.
    }

    if ((deviceIndex < 0) || (deviceIndex >= ndevices)) {
        // Out of range index:
        PsychErrorExitMsg(PsychError_user, "Invalid 'deviceIndex' specified. No such device!");
    }

    // Does Keyboard queue for this deviceIndex already exist?
    if (NULL == psychHIDKbQueueFirstPress[deviceIndex]) {
        // No. Bad bad...
        printf("PsychHID-ERROR: Tried to flush non-existent keyboard queue for deviceIndex %i! Call KbQueueCreate first!\n", deviceIndex);
        PsychErrorExitMsg(PsychError_user, "Invalid 'deviceIndex' specified. No queue for that device yet!");
    }

    kb = GetXDevice(deviceIndex);

    // Clear out current state for this queue:
    PsychLockMutex(&KbQueueMutex);

    // Flush device buffer:
    rc = kb->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), NULL, &dwItems, 0);

    // Clear our buffer:
    memset(psychHIDKbQueueFirstPress[deviceIndex]   , 0, (256 * sizeof(double)));
    memset(psychHIDKbQueueFirstRelease[deviceIndex] , 0, (256 * sizeof(double)));
    memset(psychHIDKbQueueLastPress[deviceIndex]    , 0, (256 * sizeof(double)));
    memset(psychHIDKbQueueLastRelease[deviceIndex]  , 0, (256 * sizeof(double)));

    PsychUnlockMutex(&KbQueueMutex);

    return;
}
Example #3
0
//-----------------------------------------------------------------------------
// Name: ReadBufferedData()
// Desc: Read the input device's state when in buffered mode and display it.
//-----------------------------------------------------------------------------
HRESULT ReadBufferedData( HWND hDlg )
{
    TCHAR              strNewText[128] = TEXT(""); 
    DIDEVICEOBJECTDATA didod[ SAMPLE_BUFFER_SIZE ];  // Receives buffered data 
    DWORD              dwElements;
    DWORD              i;
    HRESULT            hr;

    if( NULL == g_pMouse ) 
        return S_OK;
    
    dwElements = SAMPLE_BUFFER_SIZE;
    hr = g_pMouse->GetDeviceData( sizeof(DIDEVICEOBJECTDATA),
                                     didod, &dwElements, 0 );
    if( hr != DI_OK ) 
    {
        // We got an error or we got DI_BUFFEROVERFLOW.
        //
        // Either way, it means that continuous contact with the
        // device has been lost, either due to an external
        // interruption, or because the buffer overflowed
        // and some events were lost.
        //
        // Consequently, if a button was pressed at the time
        // the buffer overflowed or the connection was broken,
        // the corresponding "up" message might have been lost.
        //
        // But since our simple sample doesn't actually have
        // any state associated with button up or down events,
        // there is no state to reset.  (In a real game, ignoring
        // the buffer overflow would result in the game thinking
        // a key was held down when in fact it isn't; it's just
        // that the "up" event got lost because the buffer
        // overflowed.)
        //
        // If we want to be cleverer, we could do a
        // GetDeviceState() and compare the current state
        // against the state we think the device is in,
        // and process all the states that are currently
        // different from our private state.
        hr = g_pMouse->Acquire();
        while( hr == DIERR_INPUTLOST ) 
            hr = g_pMouse->Acquire();

        // Update the dialog text 
        if( hr == DIERR_OTHERAPPHASPRIO || 
            hr == DIERR_NOTACQUIRED ) 
            SetDlgItemText( hDlg, IDC_DATA, TEXT("Unacquired") );

        // hr may be DIERR_OTHERAPPHASPRIO or other errors.  This
        // may occur when the app is minimized or in the process of 
        // switching, so just try again later 
        return S_OK; 
    }

    if( FAILED(hr) )  
        return hr;

    // Study each of the buffer elements and process them.
    //
    // Since we really don't do anything, our "processing"
    // consists merely of squirting the name into our
    // local buffer.
    for( i = 0; i < dwElements; i++ ) 
    {
        // this will display then scan code of the key
        // plus a 'D' - meaning the key was pressed 
        //   or a 'U' - meaning the key was released
        switch( didod[ i ].dwOfs )
        {
            case DIMOFS_BUTTON0:
                _tcscat( strNewText, TEXT("B0") );
                break;

            case DIMOFS_BUTTON1:
                _tcscat( strNewText, TEXT("B1") );
                break;

            case DIMOFS_BUTTON2:
                _tcscat( strNewText, TEXT("B2") );
                break;

            case DIMOFS_BUTTON3:
                _tcscat( strNewText, TEXT("B3") );
                break;

            case DIMOFS_X:
                _tcscat( strNewText, TEXT("X") );
                break;

            case DIMOFS_Y:
                _tcscat( strNewText, TEXT("Y") );
                break;

            case DIMOFS_Z:
                _tcscat( strNewText, TEXT("Z") );
                break;

            default:
                _tcscat( strNewText, TEXT("") );
        }

        switch( didod[ i ].dwOfs )
        {
            case DIMOFS_BUTTON0:
            case DIMOFS_BUTTON1:
            case DIMOFS_BUTTON2:
            case DIMOFS_BUTTON3:
                if( didod[ i ].dwData & 0x80 )
                    _tcscat( strNewText, TEXT("U ") );
                else
                    _tcscat( strNewText, TEXT("D ") );
                break;

            case DIMOFS_X:
            case DIMOFS_Y:
            case DIMOFS_Z:
            {
                TCHAR strCoordValue[20];
                wsprintf( strCoordValue, TEXT("%d "), didod[ i ].dwData );
                _tcscat( strNewText, strCoordValue );
                break;
            }
        }
    }

    // Get the old text in the text box
    TCHAR strOldText[128];
    GetDlgItemText( hDlg, IDC_DATA, strOldText, 127 );

    // If nothing changed then don't repaint - avoid flicker
    if( 0 != lstrcmp( strOldText, strNewText ) ) 
        SetDlgItemText( hDlg, IDC_DATA, strNewText );    

    return S_OK;
}
// This is the event dequeue & process function which updates
// Keyboard queue state. It can be called with 'blockingSinglepass'
// set to TRUE to process exactly one event, if called from the
// background keyboard queue processing thread. Alternatively it
// can be called synchronously from KbQueueCheck with a setting of FALSE
// to iterate over all available events and process them instantaneously:
void KbQueueProcessEvents(psych_bool blockingSinglepass)
{
    LPDIRECTINPUTDEVICE8 kb;
    DIDEVICEOBJECTDATA event;
    HRESULT rc;
    DWORD dwItems;
    double tnow;
    unsigned int i, keycode, keystate;
    PsychHIDEventRecord evt;
    WORD asciiValue[2];
    UCHAR keyboardState[256];

    while (1) {
        // Single pass or multi-pass?
        if (blockingSinglepass) {
            // Wait until at least one event available and dequeue it:
            // We use a timeout of 100 msecs.
            WaitForSingleObject(hEvent, 100);
        } else {
            // Check if event available, dequeue it, if so. Abort
            // processing if no new event available, aka queue empty:
            // TODO if (!XCheckTypedEvent(thread_dpy, GenericEvent, &KbQueue_xevent)) break;
        }

        // Take timestamp:
        PsychGetAdjustedPrecisionTimerSeconds(&tnow);

        // Need the lock from here on:
        PsychLockMutex(&KbQueueMutex);

        // Do a sweep over all keyboard devices whose queues are active:
        for (i = 0; i < (unsigned int) ndevices; i++) {
            // Skip this one if inactive:
            if (!psychHIDKbQueueActive[i]) continue;

            // Check this device:
            kb = GetXDevice(i);

            // Fetch one item from the buffer:
            // event.dwTimeStamp = Timestamp in msecs of timeGetTime() timebase.
            // event.dwSequence = Sequence number.

            // Fetch from this device, item-by-item, until nothing more to fetch:
            while (TRUE) {
                // Try one fetch from this device:
                dwItems = 1;
                rc = kb->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), &event, &dwItems, 0);

                // If failed or nothing more to fetch, break out of fetch loop:
                if (!SUCCEEDED(rc) || (0 == dwItems)) break;

                // Clear ringbuffer event:
                memset(&evt, 0 , sizeof(evt));

                // Init character code to "unmapped": It will stay like that for anything but real keyboards:
                evt.cookedEventCode = -1;

                // Map to key code and key state:
                keycode = event.dwOfs & 0xff;
                keystate = event.dwData & 0x80;

                // Remap keycode into target slot in our arrays, depending on input device:
                switch (info[i].dwDevType & 0xff) {
                case DI8DEVTYPE_KEYBOARD:
                    // Try to map scancode to ascii character:
                    memset(keyboardState, 0, sizeof(keyboardState));
                    if (GetAsyncKeyState(VK_SHIFT)) keyboardState[VK_SHIFT] = 0xff;

                    if ((1 == ToAsciiEx(MapVirtualKeyEx(keycode, 1, GetKeyboardLayout(0)), keycode, keyboardState, (LPWORD) &(asciiValue[0]), 0, GetKeyboardLayout(0)))) {
                        // Mapped to single char: Return it as cooked keycode:
                        evt.cookedEventCode = (int) (asciiValue[0] & 0xff);
                    }
                    else {
                        // Could not map key to valid ascii character: Mark as "not mapped" aka zero:
                        evt.cookedEventCode = 0;
                    }

                    // Map scancode 'keycode' to virtual key code 'keycode':
                    keycode = PsychHIDOSMapKey(keycode);
                    break;

                case DI8DEVTYPE_MOUSE:
                case DI8DEVTYPE_SCREENPOINTER:
                    // Button event? Otherwise skip it.
                    if (keycode < 3 * sizeof(LONG)) continue;
                    // Correct for buttons offset in data structure DIMOUSESTATE2:
                    keycode -= 3 * sizeof(LONG);
                    break;

                case DI8DEVTYPE_JOYSTICK:
                    // Button event? Otherwise skip it.
                    if (keycode < (8 * sizeof(LONG) + 4 * sizeof(DWORD))) continue;
                    // Correct for buttons offset in data structure DIJOYSTATE2:
                    keycode -= (8 * sizeof(LONG) + 4 * sizeof(DWORD));
                    // Also skip if beyond button array:
                    if (keycode >= 128) continue;
                    break;

                default: // Unkown device -- Skip it.
                    continue;
                }

                // This keyboard queue interested in this keycode?
                if (psychHIDKbQueueScanKeys[i][keycode] != 0) {
                    // Yes: The queue wants to receive info about this key event.

                    // Press or release?
                    if (keystate) {
                        // Enqueue key press. Always in the "last press" array, because any
                        // press at this time is the best candidate for the last press.
                        // Only enqeue in "first press" if there wasn't any registered before,
                        // ie., the slot is so far empty:
                        if (psychHIDKbQueueFirstPress[i][keycode] == 0) psychHIDKbQueueFirstPress[i][keycode] = tnow;
                        psychHIDKbQueueLastPress[i][keycode] = tnow;
                        evt.status |= (1 << 0);
                    } else {
                        // Enqueue key release. See logic above:
                        if (psychHIDKbQueueFirstRelease[i][keycode] == 0) psychHIDKbQueueFirstRelease[i][keycode] = tnow;
                        psychHIDKbQueueLastRelease[i][keycode] = tnow;
                        evt.status &= ~(1 << 0);
                        // Clear cooked keycode - We don't record key releases this way:
                        if (evt.cookedEventCode > 0) evt.cookedEventCode = 0;
                    }

                    // Update event buffer:
                    evt.timestamp = tnow;
                    evt.rawEventCode = keycode + 1;
                    PsychHIDAddEventToEventBuffer(i, &evt);

                    // Tell waiting userspace (under KbQueueMutex protection for better scheduling) something interesting has changed:
                    PsychSignalCondition(&KbQueueCondition);
                }
                // Next fetch iteration for this device...
            }
            // Check next device...
        }

        // Done with shared data access:
        PsychUnlockMutex(&KbQueueMutex);

        // Done if we were only supposed to handle one sweep, which we did:
        if (blockingSinglepass) break;
    }

    return;
}
Example #5
0
//-----------------------------------------------------------------------------
// Name: OnLeftButtonDown()
// Desc: If we are drawing a curve, then read buffered data and draw
//      lines from point to point.  By reading buffered data, we can
//      track the motion of the mouse accurately without coalescing.
//
//      This function illustrates how a non-message-based program can
//      process buffered data directly from a device, processing
//      messages only occasionally (as required by Windows).
//
//      This function also illustrates how an application can piece
//      together buffered data elements based on the sequence number.
//      A single mouse action (e.g., moving diagonally) is reported
//      as a series of events, all with the same sequence number.
//      Zero is never a valid DirectInput sequence number, so it is
//      safe to use it as a sentinel value.
//-----------------------------------------------------------------------------
VOID OnLeftButtonDown( HWND hWnd )
{
    HRESULT             hr;
    LEFTBUTTONINFO      lbInfo;
    BOOL                bDone;
    DIDEVICEOBJECTDATA  od;
    DWORD               dwElements;
    MSG                 msg;

    // For performance, draw directly onto the window's DC instead of
    // invalidating and waiting for the WM_PAINT message.  Of course,
    // we always draw onto our bitmap, too, since that's what really
    // counts.

    // hide cursor and initialize button info with cursor position
    StartPenDraw( hWnd, &lbInfo );
    InvalidateCursorRect( hWnd );
    UpdateWindow( hWnd );

    // Keep reading data elements until we see a "mouse button up" event.
    bDone = FALSE;
    while( !bDone ) 
    {
        dwElements = 1;
        hr = g_pMouse->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), 
                                      &od, &dwElements, 0 );
        if( FAILED(hr) )       
            break;

        // If theres no data available, finish the element 
        // we have been collecting, and then process our message 
        // queue so the system doesn't think the app has hung.
        if( dwElements == 0 ) 
        {
            // if there is a partial motion, flush it out 
            OnLeftButtonDown_FlushMotion( &lbInfo );

            while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) 
            {
                // If it's a quit message, we're outta here 
                if( msg.message == WM_QUIT ) 
                {
                    // Re-post the quit message so the
                    // outer loop will see it and exit.
                    PostQuitMessage( (int)msg.wParam );
                    bDone = TRUE;                    
                    break;
                } 
                else 
                {
                    TranslateMessage( &msg );
                    DispatchMessage( &msg );
                }
            }
            continue;
        }

        // If this is the start of a new event, flush out the old one 
        if( od.dwSequence != lbInfo.dwSeqLastSeen ) 
        {
            OnLeftButtonDown_FlushMotion( &lbInfo );
            lbInfo.dwSeqLastSeen = od.dwSequence;
        }

        // Look at the element to see what happened 
        switch( od.dwOfs ) 
        {
            case DIMOFS_X:      // Mouse horizontal motion 
                UpdateCursorPosition( od.dwData, 0 );
                lbInfo.bMoved = TRUE;
                break;

            case DIMOFS_Y:      // Mouse vertical motion 
                UpdateCursorPosition( 0, od.dwData );
                lbInfo.bMoved = TRUE;
                break;

            case DIMOFS_BUTTON0: // Button 0 pressed or released 
            case DIMOFS_BUTTON1: // Button 1 pressed or released 
                if( ( g_bSwapMouseButtons  && DIMOFS_BUTTON1 == od.dwOfs ) ||
                    ( !g_bSwapMouseButtons && DIMOFS_BUTTON0 == od.dwOfs ) )
                {
                    if( !(od.dwData & 0x80) ) 
                    { 
                        // Button released, so flush out dregs 
                        bDone = TRUE;
                        OnLeftButtonDown_FlushMotion( &lbInfo ); 
                    }
                }
                break;
        }
    }

    ReleaseDC( hWnd, lbInfo.hdcWindow );

    // Re-show the cursor now that scrawling is finished 
    FinishPenDraw( hWnd );
    InvalidateCursorRect( hWnd );
}
Example #6
0
//-----------------------------------------------------------------------------
// Name: OnMouseInput()
// Desc: Handles responding to any mouse input that is generated from
//       the mouse event being triggered.
//-----------------------------------------------------------------------------
VOID OnMouseInput( HWND hWnd )
{
    BOOL                bDone;
    DIDEVICEOBJECTDATA  od;
    DWORD               dwElements;
    HRESULT             hr;

    // Invalidate the old cursor so it will be erased 
    InvalidateCursorRect( hWnd );

    // Attempt to read one data element.  Continue as long as
    // device data is available.
    bDone = FALSE;
    while( !bDone ) 
    {
        dwElements = 1;
        hr = g_pMouse->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), 
                                      &od, &dwElements, 0 );

        if( hr == DIERR_INPUTLOST ) 
        {
            SetAcquire();
            break;
        }

        // Unable to read data or no data available
        if( FAILED(hr) || dwElements == 0 ) 
        {
            break;
        }

        // Look at the element to see what happened
        switch( od.dwOfs ) 
        {     
            case DIMOFS_X:       // Mouse horizontal motion 
                UpdateCursorPosition( od.dwData, 0 ); 
                break;

            case DIMOFS_Y:       // Mouse vertical motion 
                UpdateCursorPosition( 0, od.dwData ); 
                break;

            case DIMOFS_BUTTON0: // Right button pressed or released 
            case DIMOFS_BUTTON1: // Left button pressed or released 
                // Is the right or a swapped left button down?
                if( ( g_bSwapMouseButtons  && DIMOFS_BUTTON1 == od.dwOfs ) ||
                    ( !g_bSwapMouseButtons && DIMOFS_BUTTON0 == od.dwOfs ) )
                {
                    if( od.dwData & 0x80 ) 
                    { 
                        // left button pressed, so go into button-down mode 
                        bDone = TRUE;
                        OnLeftButtonDown( hWnd ); 
                    }
                }

                // is the left or a swapped right button down?
                if( ( g_bSwapMouseButtons  && DIMOFS_BUTTON0 == od.dwOfs ) ||
                    ( !g_bSwapMouseButtons && DIMOFS_BUTTON1 == od.dwOfs ) )
                {
                    if( !(od.dwData & 0x80) ) 
                    {  
                        // button released, so check context menu 
                        bDone = TRUE;
                        OnRightButtonUp( hWnd ); 
                    }
                }
                break;
        }
    }

    // Invalidate the new cursor so it will be drawn 
    InvalidateCursorRect( hWnd );
}
Example #7
0
void input_Proc(const xhn::vector<input_buffer>& buffer)
{
    if(g_pMouse != NULL)
    {
        DIDEVICEOBJECTDATA didod[DINPUT_BUFFERSIZE]; // Receives buffered data
        DWORD               dwElements;
        HRESULT             hr;

        hr = DIERR_INPUTLOST;

        memset(didod, 0, sizeof(didod));
        dwElements = DINPUT_BUFFERSIZE;
        hr = g_pMouse->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), didod, &dwElements, 0);
        if (hr != DI_OK)
        {
            hr = g_pMouse->Acquire();
            if(FAILED(hr))
                return;
            hr = g_pMouse->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), didod, &dwElements, 0);
        }

        if(FAILED(hr))
        {
            if (hr == (HRESULT)DIERR_INPUTLOST)
                printf("DIERR_INPUTLOST\n");
            if (hr == (HRESULT)DIERR_INVALIDPARAM)
                printf("DIERR_INVALIDPARAM\n");
            if (hr == (HRESULT)DIERR_NOTACQUIRED)
                printf("DIERR_NOTACQUIRED\n");
            if (hr == (HRESULT)DIERR_NOTBUFFERED)
                printf("DIERR_NOTBUFFERED\n");
            if (hr == (HRESULT)DIERR_NOTINITIALIZED)
                printf("DIERR_NOTINITIALIZED\n");

            return;
        }
        else
        {
            for(DWORD i=0; i<dwElements; i++)
            {
                input_event event;
                memset(&event, 0, sizeof(event));

                event.time_stamp = didod[i].dwTimeStamp;
                if (didod[i].dwOfs == (DWORD)DIMOFS_X)
                {
                    int disp = didod[i].dwData;
                    event.info.mouse_info.mouse_move_info.x = disp;
                    event.type = MouseMoveEvent;
                }
                else if (didod[i].dwOfs == (DWORD)DIMOFS_Y)
                {
                    int disp = didod[i].dwData;
                    event.info.mouse_info.mouse_move_info.y = disp;
                    event.type = MouseMoveEvent;
                }
                else if (didod[i].dwOfs == (DWORD)DIMOFS_BUTTON0)
                {
                    if (didod[i].dwData & 0x80)
                        event.type = MouseButtonDownEvent;
                    else
                        event.type = MouseButtonUpEvent;
                    event.info.mouse_info.mouse_button_info = LeftButton;
                }
                else if (didod[i].dwOfs == (DWORD)DIMOFS_BUTTON1)
                {
                    if (didod[i].dwData & 0x80)
                        event.type = MouseButtonDownEvent;
                    else
                        event.type = MouseButtonUpEvent;
                    event.info.mouse_info.mouse_button_info = RightButton;
                }
                else if (didod[i].dwOfs == (DWORD)DIMOFS_BUTTON2)
                {
                    if (didod[i].dwData & 0x80)
                        event.type = MouseButtonDownEvent;
                    else
                        event.type = MouseButtonUpEvent;
                    event.info.mouse_info.mouse_button_info = MiddleButton;
                }
                else
                    continue;
				for (euint i = 0; i < buffer.size(); i++) {
					RWBuffer input_buffer = buffer[i].input_buffer;
					InterRWBuffer inter_input_buffer = buffer[i].inter_input_buffer;
					inter_input_buffer.write(input_buffer, (const euint*)&event, sizeof(event));
				}
            }
            POINT curPos;
            GetCursorPos(&curPos);
            ScreenToClient(g_hwnd, &curPos);
            input_event event;
            event.type = MouseAbsolutePositionEvent;
            event.info.mouse_info.mouse_abs_pos.x = curPos.x;
            event.info.mouse_info.mouse_abs_pos.y = curPos.y;
            ///inter_input_buffer.write(input_buffer, (const euint*)&event, sizeof(event));
			for (euint i = 0; i < buffer.size(); i++) {
				RWBuffer input_buffer = buffer[i].input_buffer;
				InterRWBuffer inter_input_buffer = buffer[i].inter_input_buffer;
				inter_input_buffer.write(input_buffer, (const euint*)&event, sizeof(event));
			}
        }

    }
    if(g_pKeyboard != NULL)
    {
        DIDEVICEOBJECTDATA didod[DINPUT_BUFFERSIZE]; // Receives buffered data
        DWORD               dwElements;
        HRESULT             hr;

        hr = DIERR_INPUTLOST;

        memset(didod, 0, sizeof(didod));
        dwElements = DINPUT_BUFFERSIZE;
        hr = g_pKeyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), didod, &dwElements, 0);
        if (hr != DI_OK)
        {
            hr = g_pKeyboard->Acquire();
            if(FAILED(hr))
                return;
            hr = g_pKeyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), didod, &dwElements, 0);
        }

        if(FAILED(hr))
        {
            if (hr == (HRESULT)DIERR_INPUTLOST)
                printf("DIERR_INPUTLOST\n");
            if (hr == (HRESULT)DIERR_INVALIDPARAM)
                printf("DIERR_INVALIDPARAM\n");
            if (hr == (HRESULT)DIERR_NOTACQUIRED)
                printf("DIERR_NOTACQUIRED\n");
            if (hr == (HRESULT)DIERR_NOTBUFFERED)
                printf("DIERR_NOTBUFFERED\n");
            if (hr == (HRESULT)DIERR_NOTINITIALIZED)
                printf("DIERR_NOTINITIALIZED\n");

            return;
        }
        else
        {
            for(DWORD i=0; i<dwElements; i++)
            {
                input_event event;
                memset(&event, 0, sizeof(event));

                event.time_stamp = didod[i].dwTimeStamp;
                if (didod[i].dwData & 0x80)
                    event.type = KeyDownEvent;
                else
                    event.type = KeyUpEvent;
                event.info.key_info = didod[i].dwOfs & 0xff;
                ///inter_input_buffer.write(input_buffer, (const euint*)&event, sizeof(event));
				for (euint i = 0; i < buffer.size(); i++) {
					RWBuffer input_buffer = buffer[i].input_buffer;
					InterRWBuffer inter_input_buffer = buffer[i].inter_input_buffer;
					inter_input_buffer.write(input_buffer, (const euint*)&event, sizeof(event));
				}
            }
        }

    }
}
 HRESULT _stdcall GetDeviceData(DWORD a,LPDIDEVICEOBJECTDATA b,LPDWORD c,DWORD d) {
     //This only gets called for keyboards, and can be ignored because we don't want to change buffered data
     return RealDevice->GetDeviceData(a,b,c,d);
 }
Example #9
0
int main(int argc, wchar_t* argv[])
{
	try
	{
		HWND wnd;
		if (FAILED(wnd = CreateWindow(NULL, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL)))
			throw "Can't create message window";

		LPDIRECTINPUT8 di;
		if (FAILED(DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&di, NULL)))
			throw "Can't create directinput";

		LPDIRECTINPUTDEVICE8 dev;

		if (FAILED(di->CreateDevice(GUID_SysKeyboard, &dev, NULL)))
			throw "Can't create device";

		if (FAILED(dev->SetDataFormat(&c_dfDIKeyboard)))
			throw "Can't set keyboard format";

		if (FAILED(dev->SetCooperativeLevel(wnd, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE)))
			throw "Can't set cooperative level.";

		HANDLE ev = CreateEvent(NULL, FALSE, FALSE, NULL);

		const size_t buffer_size = 50;
		{
			DIPROPDWORD dipdw;
			dipdw.diph.dwSize = sizeof(DIPROPDWORD);
			dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
			dipdw.diph.dwObj = 0;
			dipdw.diph.dwHow = DIPH_DEVICE;
			dipdw.dwData = buffer_size;

			if (FAILED(dev->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph)))
				throw "Couldn't set buffer size";
		}

		if (FAILED(dev->SetEventNotification(ev)))
			throw "Couldn't set event";

		if (FAILED(dev->Acquire()))
			throw "Failed to acquire";

		DIDEVICEOBJECTDATA buffer[buffer_size];
	
		while (WaitForSingleObject(ev, INFINITE) != WAIT_FAILED)
		{
			DWORD items = buffer_size;
			HRESULT hr;
			if (FAILED(hr = dev->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), buffer, &items, 0)))
				throw "Couldn't get data";
			for (size_t i = 0; i < items; ++i)
				if (buffer[i].dwData)
					std::cout << buffer[i].dwData << ", " << buffer[i].dwOfs << std::endl;
		}
		return 0;

	}
	catch (const char * c)
	{
		std::cout << "failure: " << c << std::endl;
	}
	catch (HRESULT hr)
	{
		std::cout << "failureno: " << hr << std::endl;
	}
	catch (...)
	{
		std::cout << "general failure" << std::endl;
	}

	return 7;
}
Example #10
0
//-----------------------------------------------------------------------------
// Name: UpdateInput()
// Desc: Update the user input.  Called once per frame 
//-----------------------------------------------------------------------------
void CMyApplication::UpdateInput()
{
    if( NULL == m_pInputDeviceManager )
        return;
    
    CMultiplayerInputDeviceManager::DeviceInfo* pDeviceInfos;
    DWORD dwNumDevices;

    // Get access to the list of semantically-mapped input devices
    m_pInputDeviceManager->GetDevices( &pDeviceInfos, &dwNumDevices );

    // Loop through all devices and check game input
    for( DWORD i=0; i<dwNumDevices; i++ )
    {
        // skip past any devices that aren't assigned, 
        // since we don't care about them
        if( pDeviceInfos[i].pPlayerInfo == NULL )
            continue;

        DIDEVICEOBJECTDATA rgdod[10];
        DWORD   dwItems = 10;
        HRESULT hr;
        LPDIRECTINPUTDEVICE8 pdidDevice = pDeviceInfos[i].pdidDevice;
        InputDeviceState* pInputDeviceState = (InputDeviceState*) pDeviceInfos[i].pParam;
        FLOAT fScale = 1.0f;

        if( pDeviceInfos[i].bRelativeAxis )
        {
            // For relative axis data, the action mapper only informs us when
            // the delta data is non-zero, so we need to zero its state
            // out each frame
            pInputDeviceState->fAxisMoveUD   = 0.0f;
            pInputDeviceState->fAxisRotateLR = 0.0f;      

            // Scale the relative axis data to make it more equal to 
            // absolute joystick data
            fScale = 5.0f;
        }

        hr = pdidDevice->Acquire();
        hr = pdidDevice->Poll();
        hr = pdidDevice->GetDeviceData( sizeof(DIDEVICEOBJECTDATA),
                                        rgdod, &dwItems, 0 );
        if( FAILED(hr) )
            continue;

        // Get the sematics codes for the game menu
        for( DWORD j=0; j<dwItems; j++ )
        {
            BOOL  bButtonState = (rgdod[j].dwData==0x80) ? TRUE : FALSE;
            FLOAT fButtonState = (rgdod[j].dwData==0x80) ? 1.0f : 0.0f;
            FLOAT fAxisState   = (FLOAT)((int)rgdod[j].dwData)/100.0f * fScale;

            switch( rgdod[j].uAppData )
            {
                // Handle relative axis data
                case INPUT_ROTATE_AXIS_LR: 
                    pInputDeviceState->fAxisRotateLR = fAxisState;
                    break;
                case INPUT_MOVE_AXIS_UD:
                    pInputDeviceState->fAxisMoveUD = -fAxisState;
                    break;

                // Handle buttons separately so the button state data
                // doesn't overwrite the axis state data, and handle
                // each button separately so they don't overwrite each other
                case INPUT_TURNLEFT:        pInputDeviceState->bButtonRotateLeft    = bButtonState; break;
                case INPUT_TURNRIGHT:       pInputDeviceState->bButtonRotateRight   = bButtonState; break;
                case INPUT_FORWARDTHRUST:   pInputDeviceState->bButtonForwardThrust = bButtonState; break;
                case INPUT_REVERSETHRUST:   pInputDeviceState->bButtonReverseThrust = bButtonState; break;
                case INPUT_FIREWEAPONS:     pInputDeviceState->bButtonFireWeapons   = bButtonState; break;
                case INPUT_ENABLESHIELD:    pInputDeviceState->bButtonEnableShield  = bButtonState; break;

                // Handle one-shot buttons
                case INPUT_DISPLAYGAMEMENU: if( bButtonState ) m_UserInput[0].bDoConfigureInput = TRUE; break;
                case INPUT_QUITGAME:        if( bButtonState ) m_UserInput[0].bDoQuitGame       = TRUE; break;
            }
        }
    }

    for( DWORD iPlayer=0; iPlayer<m_dwNumPlayers; iPlayer++ )
    {       
        // Process user input and store result into pUserInput struct
        m_UserInput[iPlayer].fAxisRotateLR = 0.0f;
        m_UserInput[iPlayer].fAxisMoveUD   = 0.0f;
        m_UserInput[iPlayer].bButtonFireWeapons  = FALSE;
        m_UserInput[iPlayer].bButtonEnableShield = FALSE;

        // Concatinate the data from all the DirectInput devices
        for( i=0; i<dwNumDevices; i++ )
        {
            // Only look at devices that are assigned to this player 
            if( pDeviceInfos[i].pPlayerInfo == NULL || 
                pDeviceInfos[i].pPlayerInfo->dwPlayerIndex != iPlayer )
                continue;

            InputDeviceState* pInputDeviceState = (InputDeviceState*) pDeviceInfos[i].pParam;

            // Use the axis data that is furthest from zero
            if( fabs(pInputDeviceState->fAxisRotateLR) > fabs(m_UserInput[iPlayer].fAxisRotateLR) )
                m_UserInput[iPlayer].fAxisRotateLR = pInputDeviceState->fAxisRotateLR;

            if( fabs(pInputDeviceState->fAxisMoveUD) > fabs(m_UserInput[iPlayer].fAxisMoveUD) )
                m_UserInput[iPlayer].fAxisMoveUD = pInputDeviceState->fAxisMoveUD;

            // Process the button data 
            if( pInputDeviceState->bButtonRotateLeft )
                m_UserInput[iPlayer].fAxisRotateLR = -1.0f;
            else if( pInputDeviceState->bButtonRotateRight )
                m_UserInput[iPlayer].fAxisRotateLR = 1.0f;

            if( pInputDeviceState->bButtonForwardThrust )
                m_UserInput[iPlayer].fAxisMoveUD = 1.0f;
            else if( pInputDeviceState->bButtonReverseThrust )
                m_UserInput[iPlayer].fAxisMoveUD = -1.0f;

            if( pInputDeviceState->bButtonFireWeapons )
                m_UserInput[iPlayer].bButtonFireWeapons = TRUE;
            if( pInputDeviceState->bButtonEnableShield )
                m_UserInput[iPlayer].bButtonEnableShield = TRUE;
        } 
    }
}