コード例 #1
0
ファイル: InputWin.cpp プロジェクト: psde/gosu
	void updateButtons(bool collectEvents)
	{
		DIDEVICEOBJECTDATA data[inputBufferSize];
		DWORD inOut;
		HRESULT hr;
        
        RECT rect;
        ::GetClientRect(window, &rect);
        bool ignoreClicks = mouseX < 0 || mouseX > rect.right || mouseY < 0 || mouseY > rect.bottom;

		inOut = inputBufferSize;
		hr = mouse->GetDeviceData(sizeof data[0], data, &inOut, 0);
		switch(hr)
		{
			case DI_OK:
			case DI_BUFFEROVERFLOW:
			{
				// Everything's ok: Update buttons and fire events.
				for (unsigned i = 0; i < inOut; ++i)
				{
					bool down = (data[i].dwData & 0x80) != 0 && !ignoreClicks;
	                    
					switch (data[i].dwOfs)
					{
						case DIMOFS_BUTTON0:
						{
							unsigned id = swapMouse ? msRight : msLeft;
							setButton(id, down, collectEvents);
							break;
						}
						case DIMOFS_BUTTON1:
						{
							unsigned id = swapMouse ? msLeft : msRight;
							setButton(id, down, collectEvents);
							break;
						}
						case DIMOFS_BUTTON2:
						{
							setButton(msMiddle, down, collectEvents);
							break;
						}
						case DIMOFS_Z:
						{
							if (!collectEvents || data[i].dwData == 0)
								break;

							EventInfo event;
							event.action = EventInfo::buttonDown;
							if (int(data[i].dwData) < 0)
								event.id = msWheelDown;
							else
								event.id = msWheelUp;
							events.push_back(event);
                            event.action = EventInfo::buttonUp;
                            events.push_back(event);
							break;
						}
					}
				}
				break;
			}

			case DIERR_NOTACQUIRED:
			case DIERR_INPUTLOST:
			{
				// Cannot fetch new events: Release all buttons.
				for (unsigned id = msRangeBegin; id < msRangeEnd; ++id)
					setButton(id, false, collectEvents);
				mouse->Acquire();
				break;
			}
		}
        
        keyboard:

		inOut = inputBufferSize;
		hr = keyboard->GetDeviceData(sizeof data[0], data, &inOut, 0);
		switch (hr)
		{
			case DI_OK:
			case DI_BUFFEROVERFLOW:
			{
				for (unsigned i = 0; i < inOut; ++i)
					forceButton(data[i].dwOfs, (data[i].dwData & 0x80) != 0, collectEvents);
				break;
			}

			case DIERR_NOTACQUIRED:
			case DIERR_INPUTLOST:
			{
				for (unsigned id = kbRangeBegin; id < kbRangeEnd; ++id)
					setButton(id, false, collectEvents);
				keyboard->Acquire();
				break;
			}
		}

		boost::array<bool, gpNum> gpBuffer;
		gpBuffer.assign(false);
		for (unsigned gp = 0; gp < gamepads.size(); ++gp)
		{
			gamepads[gp]->Poll();

			DIJOYSTATE joy;
			hr = gamepads[gp]->GetDeviceState(sizeof joy, &joy);
			switch (hr)
			{
				case DI_OK:
				{
					if (joy.lX < -stickThreshold)
						gpBuffer[gpLeft - gpRangeBegin] = true;
					else if (joy.lX > stickThreshold)
						gpBuffer[gpRight - gpRangeBegin] = true;

					if (joy.lY < -stickThreshold)
						gpBuffer[gpUp - gpRangeBegin] = true;
					else if (joy.lY > stickThreshold)
						gpBuffer[gpDown - gpRangeBegin] = true;

					for (unsigned id = gpButton0; id < gpRangeEnd; ++id)
						if (joy.rgbButtons[id - gpButton0])
                    		gpBuffer[id - gpRangeBegin] = true;
					
					break;
				}

				case DIERR_NOTACQUIRED:
				case DIERR_INPUTLOST:
				{
					gamepads[gp]->Acquire();

					break;
				}
			}
		}
		for (unsigned id = gpRangeBegin; id < gpRangeEnd; ++id)
			setButton(id, gpBuffer[id - gpRangeBegin], collectEvents);
	}
コード例 #2
0
    void updateButtons(bool collectEvents)
    {
        DIDEVICEOBJECTDATA data[inputBufferSize];
        DWORD inOut;
        HRESULT hr;
        
        RECT rect;
        ::GetClientRect(window, &rect);
        bool ignoreClicks = mouseX < 0 || mouseX > rect.right || mouseY < 0 || mouseY > rect.bottom;

        inOut = inputBufferSize;
        hr = mouse->GetDeviceData(sizeof data[0], data, &inOut, 0);
        switch(hr)
        {
            case DI_OK:
            case DI_BUFFEROVERFLOW:
            {
                // Everything's ok: Update buttons and fire events.
                for (unsigned i = 0; i < inOut; ++i)
                {
                    bool down = (data[i].dwData & 0x80) != 0 && !ignoreClicks;
                    
                    // No switch statement here because it breaks compilation with MinGW.
                    if (data[i].dwOfs == DIMOFS_BUTTON0)
                    {
                        unsigned id = swapMouse ? msRight : msLeft;
                        setButton(id, down, collectEvents);
                    }
                    else if (data[i].dwOfs == DIMOFS_BUTTON1)
                    {
                        unsigned id = swapMouse ? msLeft : msRight;
                        setButton(id, down, collectEvents);
                    }
                    else if (data[i].dwOfs == DIMOFS_BUTTON2)
                    {
                        setButton(msMiddle, down, collectEvents);
                    }
                    else if (data[i].dwOfs == DIMOFS_Z &&
                        collectEvents && data[i].dwData)
                    {
                        EventInfo event;
                        event.action = EventInfo::buttonDown;
                        if (int(data[i].dwData) < 0)
                            event.id = msWheelDown;
                        else
                            event.id = msWheelUp;
                        events.push_back(event);
                        event.action = EventInfo::buttonUp;
                        events.push_back(event);
                    }
                }
                break;
            }

            case DIERR_NOTACQUIRED:
            case DIERR_INPUTLOST:
            {
                // Cannot fetch new events: Release all buttons.
                for (unsigned id = msRangeBegin; id <= msRangeEnd; ++id)
                    setButton(id, false, collectEvents);
                mouse->Acquire();
                break;
            }
        }
        
        inOut = inputBufferSize;
        hr = keyboard->GetDeviceData(sizeof data[0], data, &inOut, 0);
        switch (hr)
        {
            case DI_OK:
            case DI_BUFFEROVERFLOW:
            {
                for (unsigned i = 0; i < inOut; ++i)
                    forceButton(data[i].dwOfs, (data[i].dwData & 0x80) != 0, collectEvents);
                break;
            }

            case DIERR_NOTACQUIRED:
            case DIERR_INPUTLOST:
            {
                for (unsigned id = kbRangeBegin; id <= kbRangeEnd; ++id)
                    setButton(id, false, collectEvents);
                keyboard->Acquire();
                break;
            }
        }

        std::tr1::array<bool, gpNum> gpBuffer = { false };
        for (unsigned gp = 0; gp < gamepads.size() && gp < numGamepads; ++gp)
        {
            gamepads[gp]->Poll();
            
            int rangeOffset = (gp + 1) * gpNumPerGamepad - gpRangeBegin;

            DIJOYSTATE joy;
            hr = gamepads[gp]->GetDeviceState(sizeof joy, &joy);
            switch (hr)
            {
                case DI_OK:
                {
                    if (joy.lX < -stickThreshold)
                        gpBuffer[gpLeft + rangeOffset] = true;
                    else if (joy.lX > stickThreshold)
                        gpBuffer[gpRight + rangeOffset] = true;

                    if (joy.lY < -stickThreshold)
                        gpBuffer[gpUp + rangeOffset] = true;
                    else if (joy.lY > stickThreshold)
                        gpBuffer[gpDown + rangeOffset] = true;

                    for (unsigned id = gpButton0; id <= gpButton15; ++id)
                        if (joy.rgbButtons[id - gpButton0])
                            gpBuffer[id + rangeOffset] = true;
                    
                    break;
                }

                case DIERR_NOTACQUIRED:
                case DIERR_INPUTLOST:
                {
                    gamepads[gp]->Acquire();

                    break;
                }
            }

            // Merge these results into the area for "all gamepads OR'ed together"
            for (int index = 0; index < gpNumPerGamepad; ++index)
                gpBuffer[index] = (gpBuffer[index] || gpBuffer[index + (gp + 1) * gpNumPerGamepad]);
        }

        for (unsigned id = gpRangeBegin; id <= gpRangeEnd; ++id)
            setButton(id, gpBuffer[id - gpRangeBegin], collectEvents);
    }