Пример #1
0
    // Callback that lists all gamepads.
    static BOOL CALLBACK gamepadCallback(LPCDIDEVICEINSTANCE device,
        LPVOID userData)
    {
        Impl* pimpl = static_cast<Impl*>(userData);

        IDirectInputDevice8* gamepad;
        if (FAILED(pimpl->input->CreateDevice(device->guidInstance,
            &gamepad, 0)))
        {
            return DIENUM_CONTINUE;
        }

        if (FAILED(gamepad->SetDataFormat(&c_dfDIJoystick)) ||
            FAILED(gamepad->SetCooperativeLevel(pimpl->window,
                DISCL_EXCLUSIVE | DISCL_FOREGROUND)) ||
            FAILED(gamepad->EnumObjects(axisCallback, gamepad, DIDFT_AXIS)))
        {
            gamepad->Release();
            return DIENUM_CONTINUE;
        }

        pimpl->gamepads.push_back(Win::shareComPtr(gamepad));

        return DIENUM_CONTINUE;
    }
Пример #2
0
// enumerate the dinput devices 
int __stdcall plDInputMgr::EnumGamepadCallback(const DIDEVICEINSTANCE* device, void* pRef)
{
    HRESULT hr;
    
    plDInput* pDI = (plDInput*)pRef;
    IDirectInputDevice8* fStick = nil;
    hr = pDI->fDInput->CreateDevice(device->guidInstance, &fStick, NULL);
    
    if(!FAILED(hr)) 
    {
        pDI->fSticks.Append(new plDIDevice(fStick));
        
        // the following code pertaining to the action map shouldn't be here.
        // in fact this shouldn't work at all according to MS, but this is 
        // currently the only way this works.  Whatever - the correct
        // code is here and commented out in case this ever gets fixed by MS
        // in a future release of dinput.
        HRESULT hr = fStick->BuildActionMap(pDI->fActionFormat, NULL, NULL);
        if (!FAILED(hr))
        {
            hr = fStick->SetActionMap( pDI->fActionFormat, NULL, NULL );

            DIPROPDWORD dipW; 
            dipW.diph.dwSize        = sizeof(DIPROPDWORD); 
            dipW.diph.dwHeaderSize  = sizeof(DIPROPHEADER); 
            dipW.diph.dwHow         = DIPH_DEVICE; 
            dipW.diph.dwObj         = 0;
            dipW.dwData             = 500; // 5% of axis range for deadzone

            hr = fStick->SetProperty(DIPROP_DEADZONE , &dipW.diph);
        }
        return DIENUM_CONTINUE;
    }
    return DIENUM_STOP;
}
	//In morrowind this only got called for keyboards when typing into the console. Probably no point in overriding it
	//And so it turns out that oblivion uses this whever it's in menumode instead of just consoles. Figures.
	HRESULT _stdcall GetDeviceData(DWORD a,DIDEVICEOBJECTDATA* b,DWORD* c,DWORD d) {
		if (bufferedPresses.empty())
			return RealDevice->GetDeviceData(a,b,c,d);
		if(!b) {
			DWORD temp=*c;
			HRESULT hr = RealDevice->GetDeviceData(a,b,c,d);
			if(c) *c=min(bufferedPresses.size(),temp);
			if(!(d|DIGDD_PEEK)) while(!bufferedPresses.empty()) bufferedPresses.pop();
			return hr;
		}
		int count=0;
		while (bufferedPresses.size()) {
			//Stricktly speaking, should return a buffer overflow by here, but if you do it breaks?
			//Presumably, if you could mash your keyboard fast enough, no keypresses would register...
			if(count==*c) return DI_OK; //DI_BUFFEROVERFLOW;
			//This will not work correctly if DIGDD_PEEK is specified. afaik, it's only ever used if b == NULL
			*b=bufferedPresses.front();
			bufferedPresses.pop();
			b+=sizeof(void*);
			count++;
		}
		if(count==*c) return DI_OK;
		//Can probably just return DI_OK here, because afaik *c is only ever 1 unless oblivion is trying to empty the buffer
		*c-=count;
		HRESULT hr=RealDevice->GetDeviceData(a,b,c,d);
		*c+=count;
		return hr;
	}
    ULONG _stdcall Release(void) {
		if(--Refs==0) {
			RealDevice->Release();
			delete this;
			return 0;
		} else { return Refs; }
	}
Пример #5
0
    // Callback that adjusts all found axes to [-stickRange, +stickRange].
    static BOOL CALLBACK axisCallback(LPCDIDEVICEOBJECTINSTANCE instance,
        LPVOID userData)
    {
        IDirectInputDevice8* dev = static_cast<IDirectInputDevice8*>(userData);

        DIPROPRANGE range;
        range.diph.dwSize = sizeof(DIPROPRANGE);
        range.diph.dwHeaderSize = sizeof(DIPROPHEADER);
        range.diph.dwHow = DIPH_BYID;
        range.diph.dwObj = instance->dwType;
        range.lMin = -stickRange;
        range.lMax = +stickRange;
        dev->SetProperty(DIPROP_RANGE, &range.diph);

        return DIENUM_CONTINUE;
    }
Пример #6
0
sge::dinput::joypad::ff::dinput_effect_unique_ptr
sge::dinput::joypad::ff::create_effect(
	IDirectInputDevice8 &_device,
	REFGUID _guid,
	DIEFFECT const &_effect
)
{
	IDirectInputEffect *result;

	if(
		_device.CreateEffect(
			_guid,
			&_effect,
			&result,
			nullptr
		)
		!=
		DI_OK
	)
		throw
			sge::input::exception{
				FCPPT_TEXT("CreateEffect failed")
			};

	return
		sge::dinput::joypad::ff::dinput_effect_unique_ptr{
			result
		};
}
Пример #7
0
IDirectInputDevice8 *BaseInputDevice::create_device(IDirectInput8 *pDI, GUID guid)
{
    IDirectInputDevice8 *device;
    HRESULT hr;
    
    hr = pDI->CreateDevice(guid, &device, NULL);
    if(FAILED(hr))  return NULL;
    
    hr = device->SetCooperativeLevel(Render::hWnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);
    if(FAILED(hr))
    {
        device->Release();  return NULL;
    }
    
    device->Acquire();
    return device;
}
Пример #8
0
bool
sge::dinput::device::funcs::acquire(
	IDirectInputDevice8 &_device
)
{
	switch(
		_device.Acquire()
	)
	{
	case S_FALSE:
	case DI_OK:
		return
			true;
	case DIERR_OTHERAPPHASPRIO:
		return
			false;
	default:
		throw sge::input::exception(
			FCPPT_TEXT("Acquire() failed!")
		);
	}
}
 HRESULT _stdcall Unacquire(void) { return RealDevice->Unacquire(); }
 HRESULT _stdcall SetProperty(REFGUID a,const DIPROPHEADER* b) { return RealDevice->SetProperty(a,b); }
 HRESULT _stdcall Acquire(void) { return RealDevice->Acquire(); }
 HRESULT _stdcall Escape(LPDIEFFESCAPE a) { return RealDevice->Escape(a); }
 HRESULT _stdcall GetProperty(REFGUID a,DIPROPHEADER* b) { return RealDevice->GetProperty(a,b); }
Пример #14
0
Gosu::Input::Input(HWND window)
: pimpl(new Impl)
{
    pimpl->window = window;
    pimpl->mouseFactorX = pimpl->mouseFactorY = 1.0;

    // Create the main input object (only necessary for setup).

    IDirectInput8* inputRaw;
    Impl::check("creating the main DirectInput object",
        ::DirectInput8Create(Win::instance(), DIRECTINPUT_VERSION,
            IID_IDirectInput8, reinterpret_cast<void**>(&inputRaw), 0));
    pimpl->input = Win::shareComPtr(inputRaw);


    // Prepare property struct for setting the amount of data to buffer.

    DIPROPDWORD bufferSize;
    bufferSize.diph.dwSize = sizeof(DIPROPDWORD);
    bufferSize.diph.dwHeaderSize = sizeof(DIPROPHEADER);
    bufferSize.diph.dwHow = DIPH_DEVICE;
    bufferSize.diph.dwObj = 0;
    bufferSize.dwData = Impl::inputBufferSize;


    // Set up the system keyboard.

    IDirectInputDevice8* kbRaw;
    Impl::check("creating the keyboard device object",
        pimpl->input->CreateDevice(GUID_SysKeyboard, &kbRaw, 0));
    pimpl->keyboard = Win::shareComPtr(kbRaw);

    Impl::check("setting the keyboard's data format",
        kbRaw->SetDataFormat(&c_dfDIKeyboard));
    Impl::check("setting the keyboard's cooperative level",
        kbRaw->SetCooperativeLevel(window,
            DISCL_FOREGROUND | DISCL_NONEXCLUSIVE));
    Impl::check("setting the keyboard's buffer size",
        kbRaw->SetProperty(DIPROP_BUFFERSIZE, &bufferSize.diph));

    kbRaw->Acquire();

    
    // Set up the system mouse.

    IDirectInputDevice8* mouseRaw;
    Impl::check("creating the mouse device object",
        pimpl->input->CreateDevice(GUID_SysMouse, &mouseRaw, 0));
    pimpl->mouse = Win::shareComPtr(mouseRaw);

    Impl::check("setting the mouse's data format",
        mouseRaw->SetDataFormat(&c_dfDIMouse));
    Impl::check("setting the mouse's cooperative level",
        mouseRaw->SetCooperativeLevel(window,
            DISCL_FOREGROUND | DISCL_NONEXCLUSIVE));
    Impl::check("setting the mouse's buffer size",
        mouseRaw->SetProperty(DIPROP_BUFFERSIZE, &bufferSize.diph));

    mouseRaw->Acquire();

    pimpl->swapMouse = ::GetSystemMetrics(SM_SWAPBUTTON) != 0;


    // Set up all gamepads.

    pimpl->input->EnumDevices(DI8DEVCLASS_GAMECTRL, Impl::gamepadCallback,
        pimpl.get(), DIEDFL_ATTACHEDONLY);


    // Get into a usable default state.

	pimpl->mouseX = pimpl->mouseY = 0;
    pimpl->updateMousePos();
    buttons.assign(false);
}
 HRESULT _stdcall CreateEffect(REFGUID a,LPCDIEFFECT b,LPDIRECTINPUTEFFECT *c,LPUNKNOWN d) { return RealDevice->CreateEffect(a,b,c,d); }
 HRESULT _stdcall SendForceFeedbackCommand(DWORD a) { return RealDevice->SendForceFeedbackCommand(a); }
 /*** IUnknown methods ***/
 HRESULT _stdcall QueryInterface (REFIID riid, LPVOID * ppvObj) { return RealDevice->QueryInterface(riid,ppvObj); }
 HRESULT _stdcall WriteEffectToFile(LPCSTR a,DWORD b,LPDIFILEEFFECT c,DWORD d) { return RealDevice->WriteEffectToFile(a,b,c,d); }
 HRESULT _stdcall SetActionMap(LPDIACTIONFORMATA a,LPCSTR b,DWORD c) { return RealDevice->SetActionMap(a,b,c); }
 HRESULT _stdcall EnumEffectsInFile(LPCSTR a,LPDIENUMEFFECTSINFILECALLBACK b,LPVOID c,DWORD d) { return RealDevice->EnumEffectsInFile(a,b,c,d); }
 HRESULT _stdcall SendDeviceData(DWORD a,LPCDIDEVICEOBJECTDATA b,LPDWORD c,DWORD d) { return RealDevice->SendDeviceData(a,b,c,d); }
 HRESULT _stdcall Poll(void) { return RealDevice->Poll(); }
    HRESULT _stdcall GetDeviceState(DWORD a,LPVOID b) {
        if(DeviceType==kDeviceType_KEYBOARD) {
            //This is a keyboard, so get a list of bytes (Dont forget the mouse too)
            BYTE bytes[kMaxMacros];
            HRESULT hr=RealDevice->GetDeviceState(256,bytes);
            if(hr!=DI_OK) return hr;
            CopyMemory(&bytes[256],&DI_data.MouseOut,10);
			//Get any extra key presses
			DI_data.GlobalHammer = !DI_data.GlobalHammer;

			BYTE	* hammerList = DI_data.GlobalHammer ? DI_data.HammerStates : DI_data.AHammerStates;

			for(DWORD byte=0;byte<kMaxMacros-2;byte++)
			{
				if(!ShouldIgnoreKey(byte))
					bytes[byte] |= hammerList[byte];
			}

			for(DWORD byte=0;byte<256;byte++) {
				if(!ShouldIgnoreKey(byte))
				{
					bytes[byte]|=DI_data.FakeStates[byte];
					bytes[byte]&=DI_data.DisallowStates[byte];
				}

				if(DI_data.TapStates[byte]) {
					bytes[byte]=0x80;
					DI_data.TapStates[byte]=0;
				}
			}

			for(DWORD byte=256;byte<kMaxMacros-2;byte++) bytes[byte]|=DI_data.FakeStates[byte];

			::CopyMemory(b,bytes,a);
			::CopyMemory(DI_data.LastBytes,bytes,kMaxMacros);
			::CopyMemory(DI_data.MouseIn,&bytes[256],10);

			return DI_OK;
		} else {
            //This is a mouse
			
			//measure length of last frame
			DWORD time=GetTickCount();
			fps_LastFrameLength=(float)(time-fps_LastTime)/1000.0f;
			fps_LastTime=time;

			fps_FrameTimeHistory[fps_FrameTimeHistoryIdx] = fps_LastFrameLength;
			if(fps_FrameTimeHistoryIdx < kFrameTimeHistoryLength)
				fps_FrameTimeHistoryIdx++;
			else
				fps_FrameTimeHistoryIdx = 0;

			if(fps_FrameTimeHistoryNum < kFrameTimeHistoryLength)
				fps_FrameTimeHistoryNum++;
			else
			{
				float	total = 0;

				for(UInt32 i = 0; i < kFrameTimeHistoryLength; i++)
					total += fps_FrameTimeHistory[i];

				total /= ((float)kFrameTimeHistoryLength);

				fps_AverageFrameTime = total;
			}

			//Mouse control gunk
            DIMOUSESTATE2* MouseState=(DIMOUSESTATE2*)b;
            HRESULT hr=RealDevice->GetDeviceState(sizeof(DIMOUSESTATE2),MouseState);
            if(hr!=DI_OK) return hr;
            if(MouseState->lZ>0) {
                DI_data.MouseOut[8]=0x80;
                DI_data.MouseOut[9]=0;
            } else if(MouseState->lZ<0) {
                DI_data.MouseOut[8]=0;
                DI_data.MouseOut[9]=0x80;
            } else {
                DI_data.MouseOut[8]=0;
                DI_data.MouseOut[9]=0;
            }
            if(DI_data.MouseDisable) {
                MouseState->lX=0;
                MouseState->lY=0;
            }
            if(DI_data.MouseXMov) {
                MouseState->lX+=DI_data.MouseXMov;
                DI_data.MouseXMov=0;
            }
            if(DI_data.MouseYMov) {
                MouseState->lY+=DI_data.MouseYMov;
                DI_data.MouseYMov=0;
            }
            if(DI_data.MouseXSpeed) {
                float move=DI_data.MouseXSpeed*fps_LastFrameLength;
                MouseState->lX+=(long)move;
                if(DI_data.MouseXSpeed>0) {
                    DI_data.MouseXLeft+=fmodf(move,1.0f);
                    if(DI_data.MouseXLeft>1) {
                        MouseState->lX+=1;
                        DI_data.MouseXLeft-=1;
                    }
                } else {
                    DI_data.MouseXLeft-=fmodf(-move,1.0f);
                    if(DI_data.MouseXLeft<-1) {
                        MouseState->lX-=1;
                        DI_data.MouseXLeft+=1;
                    }
                }
            }
            if(DI_data.MouseYSpeed) {
                float move=DI_data.MouseYSpeed*fps_LastFrameLength;
                MouseState->lY+=(long)move;
                if(DI_data.MouseYSpeed>0) {
                    DI_data.MouseYLeft+=fmodf(move,1.0f);
                    if(DI_data.MouseYLeft>1) {
                        MouseState->lY+=1;
                        DI_data.MouseYLeft-=1;
                    }
                } else {
                    DI_data.MouseYLeft-=fmodf(-move,1.0f);
                    if(DI_data.MouseYLeft<-1) {
                        MouseState->lY-=1;
                        DI_data.MouseYLeft+=1;
                    }
                }
            }
            for(DWORD i=0;i<8;i++) {
                DI_data.MouseOut[i]=MouseState->rgbButtons[i];
                MouseState->rgbButtons[i]|=DI_data.MouseIn[i];
                MouseState->rgbButtons[i]&=DI_data.DisallowStates[i+256];
                if(DI_data.TapStates[i+256]) {
                    MouseState->rgbButtons[i]=0x80;
                    DI_data.TapStates[i+256]=0x00;
                }
            }
            return DI_OK;
        }
    }
 HRESULT _stdcall GetForceFeedbackState(LPDWORD a) { return RealDevice->GetForceFeedbackState(a); }
 HRESULT _stdcall GetEffectInfo(LPDIEFFECTINFOA a,REFGUID b) { return RealDevice->GetEffectInfo(a,b); }
 /*** IDirectInputDevice8A methods ***/
 HRESULT _stdcall GetCapabilities(LPDIDEVCAPS a) { return RealDevice->GetCapabilities(a); }
 HRESULT _stdcall EnumEffects(LPDIENUMEFFECTSCALLBACKA a,LPVOID b,DWORD c) { return RealDevice->EnumEffects(a,b,c); }
 HRESULT _stdcall EnumObjects(LPDIENUMDEVICEOBJECTSCALLBACKA a,LPVOID b,DWORD c) { return RealDevice->EnumObjects(a,b,c); }
 HRESULT _stdcall GetImageInfo(LPDIDEVICEIMAGEINFOHEADERA a) { return RealDevice->GetImageInfo(a); }
 HRESULT _stdcall EnumCreatedEffectObjects(LPDIENUMCREATEDEFFECTOBJECTSCALLBACK a,LPVOID b,DWORD c) { return RealDevice->EnumCreatedEffectObjects(a,b,c); }