| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- #include "std.h"
- #include "gxinput.h"
- #include "gxruntime.h"
- #include <dinput.h>
- static const int QUE_SIZE=32;
- class Device : public gxDevice{
- public:
- bool acquired;
- gxInput *input;
- IDirectInputDevice7 *device;
- Device( gxInput *i,IDirectInputDevice7 *d ):input(i),acquired(false),device(d){
- }
- virtual ~Device(){
- device->Release();
- }
- bool acquire(){
- return acquired=device->Acquire()>=0;
- }
- void unacquire(){
- device->Unacquire();
- acquired=false;
- }
- };
- class Keyboard : public Device{
- public:
- Keyboard( gxInput *i,IDirectInputDevice7 *d ):Device(i,d){
- }
- void update(){
- if( !acquired ){
- input->runtime->idle();
- return;
- }
- int k,cnt=32;
- DIDEVICEOBJECTDATA data[32],*curr;
- if( device->GetDeviceData( sizeof(DIDEVICEOBJECTDATA),data,(DWORD*)&cnt,0 )<0 ) return;
- curr=data;
- for( k=0;k<cnt;++curr,++k ){
- int n=curr->dwOfs;if( !n || n>255 ) continue;
- if( curr->dwData&0x80 ) downEvent( n );
- else upEvent( n );
- }
- }
- };
- class Mouse : public Device{
- public:
- Mouse( gxInput *i,IDirectInputDevice7 *d ):Device(i,d){
- }
- void update(){
- if( !acquired ){
- input->runtime->idle();
- return;
- }
- DIMOUSESTATE state;
- if( device->GetDeviceState(sizeof(state),&state)<0 ) return;
- if( gxGraphics *g=input->runtime->graphics ){
- int mx=axis_states[0]+state.lX;
- int my=axis_states[1]+state.lY;
- if( mx<0 ) mx=0;
- else if( mx>=g->getWidth() ) mx=g->getWidth()-1;
- if( my<0 ) my=0;
- else if( my>=g->getHeight() ) my=g->getHeight()-1;
- axis_states[0]=mx;
- axis_states[1]=my;
- axis_states[2]+=state.lZ;
- }
- for( int k=0;k<3;++k ){
- setDownState( k+1,state.rgbButtons[k]&0x80 ? true : false );
- }
- }
- };
- class Joystick : public Device{
- public:
- int type,poll_time;
- int mins[12],maxs[12];
- Joystick( gxInput *i,IDirectInputDevice7 *d,int t ):Device(i,d),type(t),poll_time(0){
- for( int k=0;k<12;++k ){
- //initialize joystick axis ranges (d'oh!)
- DIPROPRANGE range;
- range.diph.dwSize=sizeof(DIPROPRANGE);
- range.diph.dwHeaderSize=sizeof(DIPROPHEADER);
- range.diph.dwObj=k*4+12;
- range.diph.dwHow=DIPH_BYOFFSET;
- if( d->GetProperty( DIPROP_RANGE,&range.diph )<0 ){
- mins[k]=0;
- maxs[k]=65535;
- continue;
- }
- mins[k]=range.lMin;
- maxs[k]=range.lMax-range.lMin;
- }
- }
- void update(){
- unsigned tm=timeGetTime();
- if( tm-poll_time<3 ) return;
- if( device->Poll()<0 ){
- acquired=false;
- input->runtime->idle();
- acquire();if( device->Poll()<0 ) return;
- }
- poll_time=tm;
- DIJOYSTATE state;
- if( device->GetDeviceState( sizeof( state ),&state )<0 ) return;
- axis_states[0]=(state.lX-mins[0])/(float)maxs[0]*2-1;
- axis_states[1]=(state.lY-mins[1])/(float)maxs[1]*2-1;
- axis_states[2]=(state.lZ-mins[2])/(float)maxs[2]*2-1;
- axis_states[3]=(state.rglSlider[0]-mins[6])/(float)maxs[6]*2-1;
- axis_states[4]=(state.rglSlider[1]-mins[7])/(float)maxs[7]*2-1;
- axis_states[5]=(state.lRx-mins[3])/(float)maxs[3]*2-1;
- axis_states[6]=(state.lRy-mins[4])/(float)maxs[4]*2-1;
- axis_states[7]=(state.lRz-mins[5])/(float)maxs[5]*2-1;
- if( (state.rgdwPOV[0]&0xffff)==0xffff ) axis_states[8]=-1;
- else axis_states[8]=floor(state.rgdwPOV[0]/100.0f+.5f);
- for( int k=0;k<31;++k ){
- setDownState( k+1,state.rgbButtons[k]&0x80 ? true : false );
- }
- }
- };
- static Keyboard *keyboard;
- static Mouse *mouse;
- static vector<Joystick*> joysticks;
-
- static Keyboard *createKeyboard( gxInput *input ){
- IDirectInputDevice7 *dev;
- if( input->dirInput->CreateDeviceEx( GUID_SysKeyboard,IID_IDirectInputDevice7,(void**)&dev,0 )>=0 ){
- if( dev->SetCooperativeLevel( input->runtime->hwnd,DISCL_FOREGROUND|DISCL_EXCLUSIVE )>=0 ){
- if( dev->SetDataFormat( &c_dfDIKeyboard )>=0 ){
- DIPROPDWORD dword;
- memset( &dword,0,sizeof(dword) );
- dword.diph.dwSize=sizeof(DIPROPDWORD);
- dword.diph.dwHeaderSize=sizeof(DIPROPHEADER);
- dword.diph.dwObj=0;
- dword.diph.dwHow=DIPH_DEVICE;
- dword.dwData=32;
- if( dev->SetProperty( DIPROP_BUFFERSIZE,&dword.diph )>=0 ){
- return d_new Keyboard( input,dev );
- }else{
- // input->runtime->debugInfo( "keyboard: SetProperty failed" );
- }
- }else{
- // input->runtime->debugInfo( "keyboard: SetDataFormat failed" );
- }
- return d_new Keyboard( input,dev );
- }else{
- input->runtime->debugInfo( "keyboard: SetCooperativeLevel failed" );
- }
- dev->Release();
- }else{
- input->runtime->debugInfo( "keyboard: CreateDeviceEx failed" );
- }
- return 0;
- }
- static Mouse *createMouse( gxInput *input ){
- IDirectInputDevice7 *dev;
- if( input->dirInput->CreateDeviceEx( GUID_SysMouse,IID_IDirectInputDevice7,(void**)&dev,0 )>=0 ){
- if( dev->SetCooperativeLevel( input->runtime->hwnd,DISCL_FOREGROUND|DISCL_EXCLUSIVE )>=0 ){
- if( dev->SetDataFormat( &c_dfDIMouse )>=0 ){
- return d_new Mouse( input,dev );
- }else{
- // input->runtime->debugInfo( "mouse: SetDataFormat failed" );
- }
- return d_new Mouse( input,dev );
- }else{
- input->runtime->debugInfo( "mouse: SetCooperativeLevel failed" );
- }
- dev->Release();
- }else{
- input->runtime->debugInfo( "mouse: CreateDeviceEx failed" );
- }
- return 0;
- }
- static Joystick *createJoystick( gxInput *input,LPCDIDEVICEINSTANCE devinst ){
- IDirectInputDevice7 *dev;
- if( input->dirInput->CreateDeviceEx( devinst->guidInstance,IID_IDirectInputDevice7,(void**)&dev,0 )>=0 ){
- if( dev->SetCooperativeLevel( input->runtime->hwnd,DISCL_FOREGROUND|DISCL_EXCLUSIVE )>=0 ){
- if( dev->SetDataFormat( &c_dfDIJoystick )>=0 ){
- int t=((devinst->dwDevType>>8)&0xff)==DIDEVTYPEJOYSTICK_GAMEPAD ? 1 : 2;
- return d_new Joystick( input,dev,t );
- }
- }
- dev->Release();
- }
- return 0;
- }
- static BOOL CALLBACK enumJoystick( LPCDIDEVICEINSTANCE devinst,LPVOID pvRef ){
- if( (devinst->dwDevType&0xff)!=DIDEVTYPE_JOYSTICK ) return DIENUM_CONTINUE;
- if( Joystick *joy=createJoystick( (gxInput*)pvRef,devinst ) ){
- joysticks.push_back( joy );
- }
- return DIENUM_CONTINUE;
- }
- gxInput::gxInput( gxRuntime *rt,IDirectInput7 *di ):
- runtime(rt),dirInput(di){
- keyboard=createKeyboard( this );
- mouse=createMouse( this );
- joysticks.clear();
- dirInput->EnumDevices( DIDEVTYPE_JOYSTICK,enumJoystick,this,DIEDFL_ATTACHEDONLY );
- }
- gxInput::~gxInput(){
- for( int k=0;k<joysticks.size();++k ) delete joysticks[k];
- joysticks.clear();
- delete mouse;
- delete keyboard;
- dirInput->Release();
- }
- void gxInput::wm_keydown( int key ){
- if( keyboard ) keyboard->downEvent( key );
- }
- void gxInput::wm_keyup( int key ){
- if( keyboard ) keyboard->upEvent( key );
- }
- void gxInput::wm_mousedown( int key ){
- if( mouse ) mouse->downEvent( key );
- }
- void gxInput::wm_mouseup( int key ){
- if( mouse ) mouse->upEvent( key );
- }
- void gxInput::wm_mousemove( int x,int y ){
- if( mouse ){
- mouse->axis_states[0]=x;
- mouse->axis_states[1]=y;
- }
- }
- void gxInput::wm_mousewheel( int dz ){
- if( mouse ) mouse->axis_states[2]+=dz;
- }
- void gxInput::reset(){
- if( mouse ) mouse->reset();
- if( keyboard ) keyboard->reset();
- for( int k=0;k<joysticks.size();++k ) joysticks[k]->reset();
- }
- bool gxInput::acquire(){
- bool m_ok=true,k_ok=true;
- if( mouse ) m_ok=mouse->acquire();
- if( keyboard ) k_ok=keyboard->acquire();
- if( m_ok && k_ok ) return true;
- if( k_ok ) keyboard->unacquire();
- if( m_ok ) mouse->unacquire();
- return false;
- }
- void gxInput::unacquire(){
- if( keyboard ) keyboard->unacquire();
- if( mouse ) mouse->unacquire();
- }
- void gxInput::moveMouse( int x,int y ){
- if( !mouse ) return;
- mouse->axis_states[0]=x;
- mouse->axis_states[1]=y;
- runtime->moveMouse( x,y );
- }
- gxDevice *gxInput::getMouse()const{
- return mouse;
- }
- gxDevice *gxInput::getKeyboard()const{
- return keyboard;
- }
- gxDevice *gxInput::getJoystick( int n )const{
- return n>=0 && n<joysticks.size() ? joysticks[n] : 0;
- }
- int gxInput::getJoystickType( int n )const{
- return n>=0 && n<joysticks.size() ? joysticks[n]->type : 0;
- }
- int gxInput::numJoysticks()const{
- return joysticks.size();
- }
- int gxInput::toAscii( int scan )const{
- switch( scan ){
- case DIK_INSERT:return ASC_INSERT;
- case DIK_DELETE:return ASC_DELETE;
- case DIK_HOME:return ASC_HOME;
- case DIK_END:return ASC_END;
- case DIK_PGUP:return ASC_PAGEUP;
- case DIK_PGDN:return ASC_PAGEDOWN;
- case DIK_UP:return ASC_UP;
- case DIK_DOWN:return ASC_DOWN;
- case DIK_LEFT:return ASC_LEFT;
- case DIK_RIGHT:return ASC_RIGHT;
- }
- scan&=0x7f;
- int virt=MapVirtualKey( scan,1 );
- if( !virt ) return 0;
- static unsigned char mat[256];
- mat[VK_LSHIFT]=keyboard->keyDown( DIK_LSHIFT ) ? 0x80 : 0;
- mat[VK_RSHIFT]=keyboard->keyDown( DIK_RSHIFT ) ? 0x80 : 0;
- mat[VK_SHIFT]=mat[VK_LSHIFT]|mat[VK_RSHIFT];
- mat[VK_LCONTROL]=keyboard->keyDown( DIK_LCONTROL ) ? 0x80 : 0;
- mat[VK_RCONTROL]=keyboard->keyDown( DIK_RCONTROL ) ? 0x80 : 0;
- mat[VK_CONTROL]=mat[VK_LCONTROL]|mat[VK_RCONTROL];
- mat[VK_LMENU]=keyboard->keyDown( DIK_LMENU ) ? 0x80 : 0;
- mat[VK_RMENU]=keyboard->keyDown( DIK_RMENU ) ? 0x80 : 0;
- mat[VK_MENU]=mat[VK_LMENU]|mat[VK_RMENU];
- WORD ch;
- if( ToAscii( virt,scan,mat,&ch,0 )!=1 ) return 0;
- return ch & 255;
- }
|