diff --git a/src/drivers/win/mapinput.cpp b/src/drivers/win/mapinput.cpp index b94eb7c1..df2b5a10 100644 --- a/src/drivers/win/mapinput.cpp +++ b/src/drivers/win/mapinput.cpp @@ -3,133 +3,17 @@ #include "input.h" #include "keyscan.h" #include "keyboard.h" +#include "gui.h" #include "../../input.h" -static int* ConflictTable=0; -static uint8 keyonce[MKK_COUNT]; -static unsigned char *keys_nr=0; - void KeyboardUpdateState(void); //mbg merge 7/17/06 yech had to add this -static const char* ScanNames[256]= -{ - /* 0x00-0x0f */ 0, "Escape", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "Minus", "Equals", "Backspace", "Tab", - /* 0x10-0x1f */ "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "[", "]", "Enter", "Left Ctrl", "A", "S", - /* 0x20-0x2f */ "D", "F", "G", "H", "J", "K", "L", "Semicolon", "Apostrophe", "Tilde", "Left Shift", "Backslash", "Z", "X", "C", "V", - /* 0x30-0x3f */ "B", "N", "M", "Comma", "Period", "Slash", "Right Shift", "Numpad *", "Left Alt", "Space", "Caps Lock", "F1", "F2", "F3", "F4", "F5", - /* 0x40-0x4f */ "F6", "F7", "F8", "F9", "F10", "NumLock", "ScrollLock", "Numpad 7", "Numpad 8", "Numpad 9", "Numpad Minus", "Numpad 4", "Numpad 5", "Numpad 6", "Numpad Plus", "Numpad 1", - /* 0x50-0x5f */ "Numpad 2", "Numpad 3", "Numpad 0", "Numpad Period", 0, 0, "Backslash", "F11", "F12", 0, 0, 0, 0, 0, 0, 0, - /* 0x60-0x6f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 0x70-0x7f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 0x80-0x8f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 0x90-0x9f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Numpad Enter", "Right Ctrl", 0, 0, - /* 0xa0-0xaf */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 0xb0-0xbf */ 0, 0, 0, 0, 0, "Numpad Divide", 0, "PrintScrn", "Right Alt", 0, 0, 0, 0, 0, 0, 0, - /* 0xc0-0xcf */ 0, 0, 0, 0, 0, "Pause", 0, "Home", "Up Arrow", "PgUp", 0, "Left Arrow", 0, "Right Arrow", 0, "End", - /* 0xd0-0xdf */ "Down Arrow", "PgDn", "Ins", "Del", 0, 0, 0, 0, 0, 0, 0, "Left Win", "Right Win", "AppMenu", 0, 0, - /* 0xe0-0xef */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 0xf0-0xff */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - struct INPUTDLGTHREADARGS { HANDLE hThreadExit; HWND hwndDlg; }; -static int _keyonly(int a) -{ - if(keys_nr[a]) - { - if(!keyonce[a]) - { - keyonce[a]=1; - return(1); - } - } - else - keyonce[a]=0; - return(0); -} - -static int GetKeyPressed() -{ - int key=0; - int i; - - keys_nr=GetKeyboard_nr(); - - for(i=0; i<256 && !key; ++i) - { - if(_keyonly(i)) - key=i; - } - return key; -} - -static int NothingPressed() -{ - int i; - - keys_nr=GetKeyboard_nr(); - - for(i=0; i<256; ++i) - { - if(keys_nr[i]) - return 0; - } - return 1; -} - -static int GetKeyMeta(int key) -{ - int meta = key & (~CMD_KEY_MASK); - switch(key & CMD_KEY_MASK) - { - case SCAN_LEFTCONTROL: - case SCAN_RIGHTCONTROL: return CMD_KEY_CTRL | meta; - case SCAN_LEFTALT: - case SCAN_RIGHTALT: return CMD_KEY_ALT | meta; - case SCAN_LEFTSHIFT: - case SCAN_RIGHTSHIFT: return CMD_KEY_SHIFT | meta; - default: - break; - } - - return meta; -} - -static void ClearExtraMeta(int* key) -{ - switch((*key)&0xff) - { - case SCAN_LEFTCONTROL: - case SCAN_RIGHTCONTROL: *key &= ~(CMD_KEY_CTRL); break; - case SCAN_LEFTALT: - case SCAN_RIGHTALT: *key &= ~(CMD_KEY_ALT); break; - case SCAN_LEFTSHIFT: - case SCAN_RIGHTSHIFT: *key &= ~(CMD_KEY_SHIFT); break; - default: - break; - } -} - -static DWORD WINAPI NewInputDialogThread(LPVOID lpvArg) -{ - struct INPUTDLGTHREADARGS* args = (struct INPUTDLGTHREADARGS*)lpvArg; - - while (args->hThreadExit) - { - if (WaitForSingleObject(args->hThreadExit, 20) == WAIT_OBJECT_0) - break; - - // Poke our owner dialog periodically. - PostMessage(args->hwndDlg, WM_USER, 0, 0); - } - - return 0; -} - static struct { int cmd; @@ -200,110 +84,432 @@ static struct #define NUM_DEFAULT_MAPPINGS (sizeof(DefaultCommandMapping)/sizeof(DefaultCommandMapping[0])) -static const char* GetKeyName(int code) +static uint8 keyonce[MKK_COUNT]; +static unsigned char *keys_nr = 0; + +static const char* ScanNames[256]= +{ + /* 0x00-0x0f */ 0, "Escape", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "Minus", "Equals", "Backspace", "Tab", + /* 0x10-0x1f */ "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "[", "]", "Enter", "Left Ctrl", "A", "S", + /* 0x20-0x2f */ "D", "F", "G", "H", "J", "K", "L", "Semicolon", "Apostrophe", "Tilde", "Left Shift", "Backslash", "Z", "X", "C", "V", + /* 0x30-0x3f */ "B", "N", "M", "Comma", "Period", "Slash", "Right Shift", "Numpad *", "Left Alt", "Space", "Caps Lock", "F1", "F2", "F3", "F4", "F5", + /* 0x40-0x4f */ "F6", "F7", "F8", "F9", "F10", "NumLock", "ScrollLock", "Numpad 7", "Numpad 8", "Numpad 9", "Numpad Minus", "Numpad 4", "Numpad 5", "Numpad 6", "Numpad Plus", "Numpad 1", + /* 0x50-0x5f */ "Numpad 2", "Numpad 3", "Numpad 0", "Numpad Period", 0, 0, "Backslash", "F11", "F12", 0, 0, 0, 0, 0, 0, 0, + /* 0x60-0x6f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0x70-0x7f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0x80-0x8f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0x90-0x9f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Numpad Enter", "Right Ctrl", 0, 0, + /* 0xa0-0xaf */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0xb0-0xbf */ 0, 0, 0, 0, 0, "Numpad Divide", 0, "PrintScrn", "Right Alt", 0, 0, 0, 0, 0, 0, 0, + /* 0xc0-0xcf */ 0, 0, 0, 0, 0, "Pause", 0, "Home", "Up Arrow", "PgUp", 0, "Left Arrow", 0, "Right Arrow", 0, "End", + /* 0xd0-0xdf */ "Down Arrow", "PgDn", "Ins", "Del", 0, 0, 0, 0, 0, 0, 0, "Left Win", "Right Win", "AppMenu", 0, 0, + /* 0xe0-0xef */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0xf0-0xff */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +int _keyonly(int a) +{ + if(keys_nr[a]) + { + if(!keyonce[a]) + { + keyonce[a] = 1; + return 1; + } + } + else + { + keyonce[a] = 0; + } + + return 0; +} + +int GetKeyPressed() +{ + int key = 0; + int i; + + keys_nr = GetKeyboard_nr(); + + for(i = 0; i < 256 && !key; ++i) + { + if(_keyonly(i)) + { + key = i; + } + } + + return key; +} + +int NothingPressed() +{ + int i; + + keys_nr = GetKeyboard_nr(); + + for(i = 0; i < 256; ++i) + { + if(keys_nr[i]) + { + return 0; + } + } + + return 1; +} + +int GetKeyMeta(int key) +{ + int meta = key & (~CMD_KEY_MASK); + + switch(key & CMD_KEY_MASK) + { + case SCAN_LEFTCONTROL: + case SCAN_RIGHTCONTROL: + return CMD_KEY_CTRL | meta; + + case SCAN_LEFTALT: + case SCAN_RIGHTALT: + return CMD_KEY_ALT | meta; + + case SCAN_LEFTSHIFT: + case SCAN_RIGHTSHIFT: + return CMD_KEY_SHIFT | meta; + + default: + break; + } + + return meta; +} + +void ClearExtraMeta(int* key) +{ + switch((*key)&0xff) + { + case SCAN_LEFTCONTROL: + case SCAN_RIGHTCONTROL: + *key &= ~(CMD_KEY_CTRL); + break; + + case SCAN_LEFTALT: + case SCAN_RIGHTALT: + *key &= ~(CMD_KEY_ALT); + break; + + case SCAN_LEFTSHIFT: + case SCAN_RIGHTSHIFT: + *key &= ~(CMD_KEY_SHIFT); + break; + + default: + break; + } +} + +DWORD WINAPI NewInputDialogThread(LPVOID lpvArg) +{ + struct INPUTDLGTHREADARGS* args = (struct INPUTDLGTHREADARGS*)lpvArg; + + while (args->hThreadExit) + { + if (WaitForSingleObject(args->hThreadExit, 20) == WAIT_OBJECT_0) + break; + + // Poke our owner dialog periodically. + PostMessage(args->hwndDlg, WM_USER, 0, 0); + } + + return 0; +} + +/** +* Returns the name of a single key. +* +* @param code Keycode +* +* @return Name of the key +* +* TODO: Replace return value with parameter. +**/ +const char* GetKeyName(int code) { static char name[16]; code &= 0xff; + if(ScanNames[code]) + { return ScanNames[code]; + } sprintf(name, "Key 0x%.2x", code); + return name; } -static char* GetKeyComboName(int c) +/** +* Returns the name of a pressed key combination. +* +* @param c A keycode +* +* @return The name of the key combination. +* +* TODO: Replace return value with parameter. +**/ +char* GetKeyComboName(int c) { static char text[80]; - text[0]='\0'; + text[0] = '\0'; + if(!c) + { return text; + } - if ((c & CMD_KEY_CTRL) == CMD_KEY_CTRL) strcat(text, "Ctrl + "); - else if ((c & CMD_KEY_CTRL) == CMD_KEY_LCTRL) strcat(text, "Left Ctrl + "); - else if ((c & CMD_KEY_CTRL) == CMD_KEY_RCTRL) strcat(text, "Right Ctrl + "); - if ((c & CMD_KEY_ALT) == CMD_KEY_ALT) strcat(text, "Alt + "); - else if ((c & CMD_KEY_ALT) == CMD_KEY_LALT) strcat(text, "Left Alt + "); - else if ((c & CMD_KEY_ALT) == CMD_KEY_RALT) strcat(text, "Right Alt + "); - if ((c & CMD_KEY_SHIFT) == CMD_KEY_SHIFT) strcat(text, "Shift + "); - else if ((c & CMD_KEY_SHIFT) == CMD_KEY_LSHIFT) strcat(text, "Left Shift + "); - else if ((c & CMD_KEY_SHIFT) == CMD_KEY_RSHIFT) strcat(text, "Right Shift + "); + if ((c & CMD_KEY_CTRL) == CMD_KEY_CTRL) + { + strcat(text, "Ctrl + "); + } + else if ((c & CMD_KEY_CTRL) == CMD_KEY_LCTRL) + { + strcat(text, "Left Ctrl + "); + } + else if ((c & CMD_KEY_CTRL) == CMD_KEY_RCTRL) + { + strcat(text, "Right Ctrl + "); + } + + if ((c & CMD_KEY_ALT) == CMD_KEY_ALT) + { + strcat(text, "Alt + "); + } + else if ((c & CMD_KEY_ALT) == CMD_KEY_LALT) + { + strcat(text, "Left Alt + "); + } + else if ((c & CMD_KEY_ALT) == CMD_KEY_RALT) + { + strcat(text, "Right Alt + "); + } + + if ((c & CMD_KEY_SHIFT) == CMD_KEY_SHIFT) + { + strcat(text, "Shift + "); + } + else if ((c & CMD_KEY_SHIFT) == CMD_KEY_LSHIFT) + { + strcat(text, "Left Shift + "); + } + else if ((c & CMD_KEY_SHIFT) == CMD_KEY_RSHIFT) + { + strcat(text, "Right Shift + "); + } strcat(text, GetKeyName(c & CMD_KEY_MASK)); return text; } -void ApplyDefaultCommandMapping(void) +/** +* Callback function for the dialog where the user can change hotkeys. +**/ +BOOL CALLBACK ChangeInputDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { - int i; + static HANDLE hThread = NULL; + static DWORD dwThreadId = 0; + static struct INPUTDLGTHREADARGS threadargs; + static int key = 0; - memset(FCEUD_CommandMapping, 0, sizeof(FCEUD_CommandMapping)); - - for(i=0; i0; --i) - SendMessage(hwndListView, LVM_DELETEITEM, (WPARAM)i-1, 0); - - // Get the filter type. - ConflictTable=0; - if (filter == EMUCMDTYPE_MAX+3) + // Check whether there are conflicts between the + // selected hotkeys. + for(unsigned i = 0; i < EMUCMD_MAX - 1; ++i) { - // Set up the conflict table. - ConflictTable=(int*)malloc(sizeof(int)*EMUCMD_MAX); - memset(ConflictTable, 0, sizeof(int)*EMUCMD_MAX); - for(i=0; i0; --i) + { + SendMessage(hwndListView, LVM_DELETEITEM, (WPARAM)i-1, 0); + } + + int* conflictTable = 0; + + // Get the filter type. + if (filter == EMUCMDTYPE_MAX + 3) + { + // Set up the conflict table. + conflictTable = (int*)malloc(sizeof(int)*EMUCMD_MAX); + memset(conflictTable, 0, sizeof(int)*EMUCMD_MAX); + + PopulateConflictTable(conflictTable); + } + + LVITEM lvi; // Populate display. - for(i=0, idx=0; icode == LVN_ITEMACTIVATE) + case LV_MAPPING: + if (lParam) { - int nSel = SendMessage(hwndListView, LVM_GETNEXTITEM, (WPARAM)-1, LVNI_SELECTED); - if (nSel != -1) + NMHDR* pnm = (NMHDR*)lParam; + + if (pnm->code == LVN_ITEMACTIVATE) { - int nCmd; - int nRet; - LVITEM lvi; + HWND hwndListView = GetDlgItem(hwndDlg, LV_MAPPING); - // Get the corresponding input - memset(&lvi, 0, sizeof(lvi)); - lvi.mask = LVIF_PARAM; - lvi.iItem = nSel; - lvi.iSubItem = 0; - SendMessage(hwndListView, LVM_GETITEM, 0, (LPARAM)&lvi); - nCmd = lvi.lParam; + AskForHotkey(hwndListView); - nRet = DialogBox(fceu_hInstance,"NEWINPUT",hwndListView,ChangeInputDialogProc); - if (nRet) - { - // nRet will be -1 when the user selects "clear". - FCEUD_CommandMapping[nCmd] = (nRet<0) ? 0 : nRet; - - memset(&lvi, 0, sizeof(lvi)); - lvi.mask = LVIF_TEXT; - lvi.iItem = nSel; - lvi.iSubItem = 2; - lvi.pszText = GetKeyComboName(FCEUD_CommandMapping[nCmd]); - SendMessage(hwndListView, LVM_SETITEM, (WPARAM)0, (LPARAM)&lvi); - } + // TODO: Only redraw if Conflicts filter + // is active. + PopulateMappingDisplay(hwndDlg); } - } - return TRUE; - } - break; - default: - break; + return TRUE; + } + break; + + default: + break; } break; diff --git a/src/drivers/win/res.rc b/src/drivers/win/res.rc index 31596cc4..36509935 100644 Binary files a/src/drivers/win/res.rc and b/src/drivers/win/res.rc differ diff --git a/src/drivers/win/resource.h b/src/drivers/win/resource.h index 466b5fd6..c30a37b7 100644 --- a/src/drivers/win/resource.h +++ b/src/drivers/win/resource.h @@ -41,6 +41,8 @@ #define MENU_RESET 200 #define BUTTON_CHEATS 200 #define TXT_PAD1 200 +#define BTN_RESTORE_DEFAULTS 200 +#define BTN_CLEAR 200 #define MENU_POWER 201 #define TXT_PAD2 201 #define MENU_EJECT_DISK 202 @@ -49,6 +51,7 @@ #define MENU_INSERT_COIN 204 #define MENU_HIDE_MENU 300 #define CHECK_SCREENSHOT_NAMES 300 +#define COMBO_FILTER 300 #define MENU_RUN_IN_BACKGROUND 301 #define MENU_BACKGROUND_INPUT 302 #define MENU_SHOW_STATUS_ICON 303 @@ -62,6 +65,7 @@ #define GUI_BOT_B_1 1001 #define GUI_BOT_SELECT_1 1002 #define GUI_BOT_START_1 1003 +#define LV_MAPPING 1003 #define GUI_BOT_UP_1 1004 #define GUI_BOT_DOWN_1 1005 #define GUI_BOT_LEFT_1 1006