+++ /dev/null
-/* FCE Ultra - NES/Famicom Emulator\r
- *\r
- * Copyright notice for this file:\r
- * Copyright (C) 2002 Ben Parnell\r
- *\r
- * This program is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 2 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
- */\r
-\r
-#include "common.h"\r
-#include <dinput.h>\r
-\r
-#include "input.h"\r
-#include "joystick.h"\r
-\r
-\r
-HRESULT ddrval;\r
-\r
-static GUID joyGUID[64];\r
-\r
-static int joycounter;\r
-\r
-static LPDIRECTINPUTDEVICE7 lpJoy[4]={0,0,0,0};\r
-\r
-int joyOptions[4]={0,0,0,0};\r
-int joyA[4]={1,1,1,1};\r
-int joyB[4]={0,0,0,0};\r
-int joySelect[4]={2,2,2,2};\r
-int joyStart[4]={3,3,3,3};\r
-int joyUp[4]={4,4,4,4};\r
-int joyDown[4]={5,5,5,5};\r
-int joyLeft[4]={6,6,6,6};\r
-int joyRight[4]={7,7,7,7};\r
-\r
-int joy[4]={0,0,0,0};\r
-\r
-static int JoyXMax[4];\r
-static int JoyXMin[4];\r
-\r
-static int JoyYMax[4];\r
-static int JoyYMin[4];\r
-\r
-static DIJOYSTATE2 JoyStatus;\r
-\r
-static void ShowDIJErr(int w, char *s)\r
-{\r
- char tempo[128];\r
- sprintf(tempo,"DirectInput: Joystick %d: %s",w+1,s);\r
- FCEUD_PrintError(tempo);\r
-}\r
-\r
-static void JoyAutoRestore(HRESULT ddrval,LPDIRECTINPUTDEVICE7 lpJJoy)\r
-{\r
- switch(ddrval)\r
- {\r
- case DIERR_INPUTLOST:\r
- case DIERR_NOTACQUIRED:\r
- IDirectInputDevice7_Acquire(lpJJoy);\r
- break;\r
- }\r
-}\r
-\r
-static int GetJoystickButton(int x)\r
-{\r
- int errc=0;\r
- int z;\r
-\r
- if(lpJoy[x])\r
- {\r
- doagaino:\r
- if(errc>8) return(-1);\r
-\r
- ddrval=IDirectInputDevice7_Poll(lpJoy[x]);\r
- if(ddrval!=DI_OK && ddrval!=DI_NOEFFECT) {JoyAutoRestore(ddrval,lpJoy[x]);errc++;goto doagaino;}\r
-\r
- ddrval=IDirectInputDevice7_GetDeviceState(lpJoy[x],sizeof(JoyStatus),&JoyStatus);\r
- if(ddrval!=DI_OK) {JoyAutoRestore(ddrval,lpJoy[x]);errc++;goto doagaino;}\r
-\r
- for(z=0;z<128;z++)\r
- if(JoyStatus.rgbButtons[z]&0x80)\r
- return z;\r
- }\r
- return(-1);\r
-}\r
-\r
-uint32 GetJSOr(void)\r
-{\r
- unsigned long ret;\r
- int x;\r
- ret=0;\r
-\r
- for(x=0;x<4;x++)\r
- {\r
- if(lpJoy[x])\r
- {\r
-\r
- ddrval=IDirectInputDevice7_Poll(lpJoy[x]);\r
- if(ddrval!=DI_OK && ddrval!=DI_NOEFFECT) JoyAutoRestore(ddrval,lpJoy[x]);\r
-\r
- ddrval=IDirectInputDevice7_GetDeviceState(lpJoy[x],sizeof(JoyStatus),&JoyStatus);\r
- if(ddrval!=DI_OK) JoyAutoRestore(ddrval,lpJoy[x]);\r
-\r
- if(joyOptions[x]&1)\r
- {\r
- if(JoyStatus.rgbButtons[joyUp[x]&127]&0x80) ret|=JOY_UP<<(x<<3);\r
- if(JoyStatus.rgbButtons[joyDown[x]&127]&0x80) ret|=JOY_DOWN<<(x<<3);\r
- if(JoyStatus.rgbButtons[joyLeft[x]&127]&0x80) ret|=JOY_LEFT<<(x<<3);\r
- if(JoyStatus.rgbButtons[joyRight[x]&127]&0x80) ret|=JOY_RIGHT<<(x<<3);\r
- }\r
- else\r
- {\r
- if(JoyStatus.lX>=JoyXMax[x])\r
- ret|=JOY_RIGHT<<(x<<3);\r
- else if(JoyStatus.lX<=JoyXMin[x])\r
- ret|=JOY_LEFT<<(x<<3);\r
-\r
- if(JoyStatus.lY>=JoyYMax[x])\r
- ret|=JOY_DOWN<<(x<<3);\r
- else if(JoyStatus.lY<=JoyYMin[x])\r
- ret|=JOY_UP<<(x<<3);\r
- }\r
- if(JoyStatus.rgbButtons[joyA[x]&127]&0x80) ret|=1<<(x<<3);\r
- if(JoyStatus.rgbButtons[joyB[x]&127]&0x80) ret|=2<<(x<<3);\r
- if(JoyStatus.rgbButtons[joySelect[x]&127]&0x80) ret|=4<<(x<<3);\r
- if(JoyStatus.rgbButtons[joyStart[x]&127]&0x80) ret|=8<<(x<<3);\r
- }\r
- }\r
-\r
- return ret;\r
-}\r
-\r
-static void KillJoystick(int w)\r
-{\r
- if(lpJoy[w])\r
- {\r
- IDirectInputDevice7_Unacquire(lpJoy[w]);\r
- IDirectInputDevice7_Release(lpJoy[w]);\r
- lpJoy[w]=0;\r
- }\r
-}\r
-\r
-void KillJoysticks(void)\r
-{\r
- int x;\r
- for(x=0;x<4;x++)\r
- KillJoystick(x);\r
-}\r
-\r
-static BOOL CALLBACK JoystickFound(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)\r
-{\r
- if(joycounter<64)\r
- {\r
- joyGUID[joycounter]=lpddi->guidInstance;\r
- joycounter++;\r
- if(pvRef)\r
- {\r
- SendDlgItemMessage(pvRef,106,CB_ADDSTRING,0,(LPARAM)(LPSTR)lpddi->tszProductName);\r
- SendDlgItemMessage(pvRef,112,CB_ADDSTRING,0,(LPARAM)(LPSTR)lpddi->tszProductName);\r
- }\r
- return DIENUM_CONTINUE;\r
- }\r
- else\r
- return 0; \r
-}\r
-\r
-void InitJoystick(int w, HWND wnd)\r
-{\r
- if(joy[w])\r
- {\r
- if(joy[w]>joycounter)\r
- {\r
- ShowDIJErr(w,"Not found."); \r
- joy[w]=0;\r
- return;\r
- }\r
- ddrval=IDirectInput7_CreateDeviceEx(lpDI,&joyGUID[joy[w]-1],&IID_IDirectInputDevice7,(LPVOID *)&lpJoy[w],0);\r
- if(ddrval != DI_OK)\r
- { \r
- ShowDIJErr(w,"Error creating device.");\r
- joy[w]=0;\r
- return;\r
- }\r
- ddrval=IDirectInputDevice7_SetCooperativeLevel(lpJoy[w],wnd,DISCL_FOREGROUND|DISCL_NONEXCLUSIVE);\r
- if (ddrval != DI_OK)\r
- {\r
- ShowDIJErr(w,"Error setting cooperative level.");\r
- KillJoystick(w);\r
- joy[w]=0;\r
- return;\r
- }\r
- ddrval=IDirectInputDevice7_SetDataFormat(lpJoy[w],&c_dfDIJoystick2);\r
- if (ddrval != DI_OK)\r
- {\r
- ShowDIJErr(w,"Error setting data format.");\r
- KillJoystick(w);\r
- joy[w]=0;\r
- return;\r
- }\r
-\r
- {\r
- DIPROPRANGE diprg;\r
- int r;\r
-\r
- memset(&diprg,0,sizeof(DIPROPRANGE));\r
- diprg.diph.dwSize=sizeof(DIPROPRANGE);\r
- diprg.diph.dwHeaderSize=sizeof(DIPROPHEADER);\r
- diprg.diph.dwHow=DIPH_BYOFFSET;\r
- diprg.diph.dwObj=DIJOFS_X;\r
- ddrval=IDirectInputDevice7_GetProperty(lpJoy[w],DIPROP_RANGE,&diprg.diph);\r
- if(ddrval!=DI_OK)\r
- {\r
- ShowDIJErr(w,"Error getting X axis range.");\r
- joy[w]=0;\r
- KillJoystick(w);\r
- joy[w]=0;\r
- return;\r
- }\r
- r=diprg.lMax-diprg.lMin;\r
- JoyXMax[w]=diprg.lMax-(r>>2);\r
- JoyXMin[w]=diprg.lMin+(r>>2);\r
-\r
- memset(&diprg,0,sizeof(DIPROPRANGE));\r
- diprg.diph.dwSize=sizeof(DIPROPRANGE);\r
- diprg.diph.dwHeaderSize=sizeof(DIPROPHEADER);\r
- diprg.diph.dwHow=DIPH_BYOFFSET;\r
- diprg.diph.dwObj=DIJOFS_Y;\r
- ddrval=IDirectInputDevice7_GetProperty(lpJoy[w],DIPROP_RANGE,&diprg.diph);\r
- if(ddrval!=DI_OK)\r
- {\r
- ShowDIJErr(w,"Error getting X axis range.");\r
- KillJoystick(w);\r
- joy[w]=0;\r
- return;\r
- }\r
- r=diprg.lMax-diprg.lMin;\r
- JoyYMax[w]=diprg.lMax-(r>>2);\r
- JoyYMin[w]=diprg.lMin+(r>>2);\r
- }\r
-\r
- }\r
-}\r
-\r
-void InitJoysticks(HWND wnd)\r
-{\r
- int x;\r
-\r
- joycounter=0;\r
- IDirectInput7_EnumDevices(lpDI, DIDEVTYPE_JOYSTICK,JoystickFound,0,DIEDFL_ATTACHEDONLY);\r
- \r
- for(x=0;x<4;x++)\r
- InitJoystick(x,wnd);\r
-}\r
-\r
-\r
-static int joyconport;\r
-\r
-static BOOL CALLBACK JoyConCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)\r
-{\r
- char tempo[64];\r
- int x;\r
- static int bid;\r
-\r
- switch(uMsg) {\r
- case WM_TIMER:\r
- if(bid>=200 && bid<=215)\r
- {\r
- int z;\r
-\r
- /* GetJoystickButton() makes sure there is a joystick,\r
- so we don't need to here.\r
- */ \r
- if(bid<=207)\r
- {\r
- if( (z=GetJoystickButton(joyconport))!=-1)\r
- SetDlgItemInt(hwndDlg,bid,z,0);\r
- }\r
- else\r
- {\r
- if( (z=GetJoystickButton(2+joyconport))!=-1)\r
- SetDlgItemInt(hwndDlg,bid,z,0);\r
- }\r
- }\r
- break;\r
- case WM_INITDIALOG:\r
- bid=0;\r
- SetTimer(hwndDlg,666,20,0); /* Every 20ms(50x a second).*/\r
-\r
- InitJoysticks(hwndDlg);\r
-\r
- SendDlgItemMessage(hwndDlg,106,CB_ADDSTRING,0,(LPARAM)(LPSTR)"<none>");\r
- SendDlgItemMessage(hwndDlg,112,CB_ADDSTRING,0,(LPARAM)(LPSTR)"<none>");\r
-\r
- sprintf(tempo,"Virtual Gamepad %d",joyconport+1);\r
- SetDlgItemText(hwndDlg,102,tempo);\r
- sprintf(tempo,"Virtual Gamepad %d",joyconport+3);\r
- SetDlgItemText(hwndDlg,104,tempo);\r
-\r
- for(x=0;x<=2;x+=2)\r
- {\r
- SetDlgItemInt(hwndDlg,200+(x<<2),joySelect[x+joyconport],0);\r
- SetDlgItemInt(hwndDlg,201+(x<<2),joyStart[x+joyconport],0);\r
- SetDlgItemInt(hwndDlg,202+(x<<2),joyB[x+joyconport],0);\r
- SetDlgItemInt(hwndDlg,203+(x<<2),joyA[x+joyconport],0);\r
-\r
- SetDlgItemInt(hwndDlg,204+(x<<2),joyUp[x+joyconport],0);\r
- SetDlgItemInt(hwndDlg,205+(x<<2),joyDown[x+joyconport],0);\r
- SetDlgItemInt(hwndDlg,206+(x<<2),joyLeft[x+joyconport],0);\r
- SetDlgItemInt(hwndDlg,207+(x<<2),joyRight[x+joyconport],0);\r
-\r
- }\r
- joycounter=0;\r
- IDirectInput7_EnumDevices(lpDI, DIDEVTYPE_JOYSTICK,JoystickFound,hwndDlg,DIEDFL_ATTACHEDONLY);\r
-\r
- SendDlgItemMessage(hwndDlg,106,CB_SETCURSEL,joy[0+joyconport],(LPARAM)(LPSTR)0);\r
- SendDlgItemMessage(hwndDlg,112,CB_SETCURSEL,joy[2+joyconport],(LPARAM)(LPSTR)0);\r
- \r
- if(joyOptions[joyconport]&1)\r
- CheckDlgButton(hwndDlg,300,BST_CHECKED);\r
- if(joyOptions[joyconport+2]&1)\r
- CheckDlgButton(hwndDlg,301,BST_CHECKED); \r
- break;\r
- case WM_CLOSE:\r
- case WM_QUIT: goto gornk;\r
- case WM_COMMAND:\r
- if(HIWORD(wParam)==EN_SETFOCUS)\r
- {\r
- bid=LOWORD(wParam);\r
- }\r
- else if(HIWORD(wParam)==EN_KILLFOCUS)\r
- {\r
- bid=0;\r
- }\r
- else if(HIWORD(wParam)==CBN_SELENDOK)\r
- {\r
- switch(LOWORD(wParam))\r
- {\r
- case 106:\r
- KillJoystick(joyconport);\r
- joy[0+(joyconport)]=SendDlgItemMessage(hwndDlg,106,CB_GETCURSEL,0,(LPARAM)(LPSTR)0);\r
- InitJoystick(joyconport,hwndDlg);\r
- SendDlgItemMessage(hwndDlg,106,CB_SETCURSEL,joy[0+joyconport],(LPARAM)(LPSTR)0);\r
- break;\r
- case 112:\r
- KillJoystick(2+joyconport);\r
- joy[2+(joyconport)]=SendDlgItemMessage(hwndDlg,112,CB_GETCURSEL,0,(LPARAM)(LPSTR)0);\r
- InitJoystick(2+joyconport,hwndDlg); \r
- SendDlgItemMessage(hwndDlg,112,CB_SETCURSEL,joy[2+joyconport],(LPARAM)(LPSTR)0);\r
- break;\r
- }\r
- }\r
-\r
- if(!(wParam>>16))\r
- switch(wParam&0xFFFF)\r
- {\r
- case 1:\r
- gornk:\r
-\r
- KillTimer(hwndDlg,666);\r
- KillJoysticks();\r
-\r
- for(x=0;x<=2;x+=2)\r
- {\r
- joySelect[x+(joyconport)]=GetDlgItemInt(hwndDlg,200+(x<<2),0,0);\r
- joyStart[x+(joyconport)]=GetDlgItemInt(hwndDlg,201+(x<<2),0,0);\r
- joyB[x+(joyconport)]=GetDlgItemInt(hwndDlg,202+(x<<2),0,0);\r
- joyA[x+(joyconport)]=GetDlgItemInt(hwndDlg,203+(x<<2),0,0);\r
-\r
- joyUp[x+(joyconport)]=GetDlgItemInt(hwndDlg,204+(x<<2),0,0);\r
- joyDown[x+(joyconport)]=GetDlgItemInt(hwndDlg,205+(x<<2),0,0);\r
- joyLeft[x+(joyconport)]=GetDlgItemInt(hwndDlg,206+(x<<2),0,0);\r
- joyRight[x+(joyconport)]=GetDlgItemInt(hwndDlg,207+(x<<2),0,0);\r
- }\r
- if(IsDlgButtonChecked(hwndDlg,300)==BST_CHECKED)\r
- joyOptions[joyconport]|=1;\r
- else\r
- joyOptions[joyconport]&=~1;\r
- if(IsDlgButtonChecked(hwndDlg,301)==BST_CHECKED)\r
- joyOptions[joyconport+2]|=1;\r
- else\r
- joyOptions[joyconport+2]&=~1; \r
- EndDialog(hwndDlg,0);\r
- break;\r
- }\r
- }\r
- return 0;\r
-}\r
-\r
-void ConfigJoystickies(HWND hParent, int port)\r
-{\r
- joyconport=port;\r
-\r
- KillJoysticks();\r
- DialogBox(fceu_hInstance,"JOYCONFIG",hParent,JoyConCallB);\r
- InitJoysticks(hAppWnd);\r
-}\r
-\r