]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Pad GUI control
authorToni Wilen <twilen@winuae.net>
Sat, 7 Oct 2023 16:21:54 +0000 (19:21 +0300)
committerToni Wilen <twilen@winuae.net>
Sat, 7 Oct 2023 16:21:54 +0000 (19:21 +0300)
include/options.h
od-win32/hardfile_win32.cpp
od-win32/resources/winuae.rc
od-win32/win32.cpp
od-win32/win32gfx.cpp
od-win32/win32gui.cpp
od-win32/win32gui.h
od-win32/win32gui_extra.cpp
od-win32/winuae_msvc15/winuae_msvc.vcxproj

index 6e82c899914ddfc4cd5dd7c74c49a069acaf5442..4a903ed4e6a3b47728912c20a0045075507c1e54 100644 (file)
@@ -907,6 +907,7 @@ struct uae_prefs {
        bool win32_filesystem_mangle_reserved_names;
        bool win32_shutdown_notification;
        bool win32_warn_exit;
+       bool win32_gui_control;
        bool right_control_is_right_win_key;
 #ifdef WITH_SLIRP
        struct slirp_redir slirp_redirs[MAX_SLIRP_REDIRS];
index be998fd42a51721d51037ae7812e2381de7779cc..c2e0ad0a1c26f2e55673e1a0084d5759586bc15f 100644 (file)
@@ -897,7 +897,8 @@ static bool hd_get_meta_hack_realtek(HWND hDlg, HANDLE h, uae_u8 *data, uae_u8 *
 
        progressdialogreturn = -1;
        progressdialogactive = 1;
-       HWND hwnd = CustomCreateDialog(IDD_PROGRESSBAR, hDlg, ProgressDialogProc);
+       struct newresource *res;
+       HWND hwnd = CustomCreateDialog(&res, IDD_PROGRESSBAR, hDlg, ProgressDialogProc);
        if (hwnd == NULL)
                return false;
        HWND hwndprogress = GetDlgItem (hwnd, IDC_PROGRESSBAR);
@@ -934,6 +935,7 @@ static bool hd_get_meta_hack_realtek(HWND hDlg, HANDLE h, uae_u8 *data, uae_u8 *
                        tcnt = 0;
                }
        }
+       freescaleresource(res);
 
        if (progressdialogactive) {
                DestroyWindow (hwnd);
@@ -1400,6 +1402,7 @@ static int gethdfchs(HWND hDlg, struct uae_driveinfo *udi, HANDLE h, int *cylsp,
        DWORD err = 0;
        HFONT font;
        HWND hwnd;
+       struct newresource *res;
 
        memset(data, 0, 512);
        memset(cmd, 0, sizeof(cmd));
@@ -1427,7 +1430,7 @@ static int gethdfchs(HWND hDlg, struct uae_driveinfo *udi, HANDLE h, int *cylsp,
        }
 
        chsdialogactive = 1;
-       hwnd = CustomCreateDialog(IDD_CHSQUERY, hDlg, CHSDialogProc);
+       hwnd = CustomCreateDialog(&res, IDD_CHSQUERY, hDlg, CHSDialogProc);
        if (hwnd == NULL) {
                err = -15;
                goto end;
@@ -1448,6 +1451,7 @@ static int gethdfchs(HWND hDlg, struct uae_driveinfo *udi, HANDLE h, int *cylsp,
                        }
                }
        }
+       freescaleresource(res);
        DeleteObject(font);
        if (chsdialogactive == 0) {
                err = -100;
@@ -1533,6 +1537,7 @@ void hd_get_meta(HWND hDlg, int idx, TCHAR *geometryfile)
        bool atapi = false;
        HWND hwnd;
        bool empty = true;
+       struct newresource *res;
 
        geometryfile[0] = 0;
        text = xcalloc(TCHAR, 100000);
@@ -1660,7 +1665,7 @@ doout:
 
        stringboxdialogactive = 1;
        hdini = ini;
-       hwnd = CustomCreateDialog (IDD_DISKINFO, hDlg, StringBoxDialogProc);
+       hwnd = CustomCreateDialog(&res, IDD_DISKINFO, hDlg, StringBoxDialogProc);
        if (hwnd != NULL) {
                HFONT font = CreateFont (getscaledfontsize(-1), 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, _T("Lucida Console"));
                if (font)
@@ -1682,6 +1687,7 @@ doout:
                                break;
                }
                DeleteObject (font);
+               freescaleresource(res);
        }
 
 end:
@@ -3635,6 +3641,7 @@ int harddrive_to_hdf (HWND hDlg, struct uae_prefs *p, int idx)
        TCHAR path[MAX_DPATH], tmp[MAX_DPATH], tmp2[MAX_DPATH];
        DWORD retcode = 0;
        HWND hwnd, hwndprogress, hwndprogresstxt;
+       struct newresource *res;
        MSG msg;
        int pct, cnt;
        DWORD r;
@@ -3710,7 +3717,7 @@ int harddrive_to_hdf (HWND hDlg, struct uae_prefs *p, int idx)
        SetFilePointer (h, 0, &li.HighPart, FILE_BEGIN);
        progressdialogreturn = -1;
        progressdialogactive = 1;
-       hwnd = CustomCreateDialog(IDD_PROGRESSBAR, hDlg, ProgressDialogProc);
+       hwnd = CustomCreateDialog(&res, IDD_PROGRESSBAR, hDlg, ProgressDialogProc);
        if (hwnd == NULL)
                goto err;
        hwndprogress = GetDlgItem (hwnd, IDC_PROGRESSBAR);
@@ -3806,6 +3813,7 @@ int harddrive_to_hdf (HWND hDlg, struct uae_prefs *p, int idx)
                sizecnt += got;
                pct = (int)(sizecnt * 100 / size);
        }
+       freescaleresource(res);
        if (progressdialogactive) {
                DestroyWindow (hwnd);
                while (PeekMessage (&msg, 0, 0, 0, PM_REMOVE)) {
index 5ed71a6c0355efd69b291a7fd550bddb8e1ba41a..58b3e17af084bd9bef3e02785f4dbf0a14d7abe6 100644 (file)
@@ -2189,7 +2189,7 @@ END
 
 STRINGTABLE
 BEGIN
-    IDS_MISCLISTITEMS4      "Windows shutdown/logoff notification\nWarn when attempting to close window\nPower led dims when audio filter is disabled\nAutomatically capture mouse when window is activated\nDebug memory space\nForce hard reset if CPU halted\nA600/A1200/A4000 IDE scsi.device disable\nWarp mode reset\n"
+    IDS_MISCLISTITEMS4      "Windows shutdown/logoff notification\nWarn when attempting to close window\nPower led dims when audio filter is disabled\nAutomatically capture mouse when window is activated\nDebug memory space\nForce hard reset if CPU halted\nA600/A1200/A4000 IDE scsi.device disable\nWarp mode reset\nGUI gamepad control\n"
     IDS_SHUTDOWN_NOTIFICATION "Emulation session active"
     IDS_QUIT_WARNING        "Are you sure you want to quit WinUAE?"
     IDS_UNMAPPED_ADDRESS    "Floating\nAll zeros\nAll ones\n"
index 718b47434046c4c4c452fa8a0bdfd38005b23719..43daf3303dbf92180e0a23c0c21d46baeac14e65 100644 (file)
@@ -2059,6 +2059,11 @@ static void EndCustomResize(HWND hWindow, BOOL bCanceled)
 
 #define MSGDEBUG 1
 
+static int externaldialogguicontrol;
+static void CALLBACK gui_control_cb(HWND h, UINT v, UINT_PTR v3, DWORD v4)
+{
+}
+
 static LRESULT CALLBACK AmigaWindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
 {
        struct AmigaMonitor *mon = NULL;
@@ -2082,6 +2087,18 @@ static LRESULT CALLBACK AmigaWindowProc(HWND hWnd, UINT message, WPARAM wParam,
                mon = &AMonitors[0];
        }
 
+       if (externaldialogactive && gui_control) {
+               if (!externaldialogguicontrol) {
+                       externaldialogguicontrol = 1;
+                       SetTimer(hWnd, 8, 20, gui_control_cb);
+               }
+       } else {
+               if (externaldialogguicontrol) {
+                       externaldialogguicontrol = 0;
+                       KillTimer(hWnd, 8);
+               }
+       }
+
 #if MSGDEBUG > 1
        write_log (_T("AWP: %p %08x %08x %08x\n"), hWnd, message, wParam, lParam);
 #endif
@@ -4460,6 +4477,7 @@ void target_default_options (struct uae_prefs *p, int type)
                p->win32_borderless = 0;
                p->win32_blankmonitors = false;
                p->win32_powersavedisabled = true;
+               p->win32_gui_control = false;
                p->sana2 = 0;
                p->win32_rtgmatchdepth = 1;
                p->gf[GF_RTG].gfx_filter_autoscale = RTG_MODE_SCALE;
@@ -4552,6 +4570,7 @@ void target_save_options (struct zfile *f, struct uae_prefs *p)
        cfgfile_target_dwrite_bool(f, _T("active_capture_automatically"), p->win32_capture_always);
        cfgfile_target_dwrite_bool(f, _T("start_iconified"), p->win32_start_minimized);
        cfgfile_target_dwrite_bool(f, _T("start_not_captured"), p->win32_start_uncaptured);
+       cfgfile_target_dwrite_bool(f, _T("gui_control"), p->win32_gui_control);
 
        cfgfile_target_dwrite_bool (f, _T("ctrl_f11_is_quit"), p->win32_ctrl_F11_is_quit);
 
@@ -4955,6 +4974,9 @@ static int target_parse_option_host(struct uae_prefs *p, const TCHAR *option, co
        if (cfgfile_yesno(option, value, _T("start_not_captured"), &p->win32_start_uncaptured))
                return 1;
 
+       if (cfgfile_yesno(option, value, _T("gui_control"), &p->win32_gui_control))
+               return 1;
+
        if (cfgfile_string_escape(option, value, _T("serial_port"), &p->sername[0], 256)) {
                sernametodev(p->sername);
                if (p->sername[0])
@@ -6922,6 +6944,10 @@ static int parseargs(const TCHAR *argx, const TCHAR *np, const TCHAR *np2)
                key_swap_hack2 = 1;
                return 1;
        }
+       if (!_tcscmp(arg, _T("gui_control"))) {
+               gui_control = 1;
+               return 1;
+       }
 
        if (!np)
                return 0;
index 9526a9cc542821d942575b106c8601e3b11edb40..9e69592a197b6f052481cc70bded509ff0318a4e 100644 (file)
@@ -2549,6 +2549,7 @@ int check_prefs_changed_gfx(void)
                currprefs.win32_ctrl_F11_is_quit != changed_prefs.win32_ctrl_F11_is_quit ||
                currprefs.win32_shutdown_notification != changed_prefs.win32_shutdown_notification ||
                currprefs.win32_warn_exit != changed_prefs.win32_warn_exit ||
+               currprefs.win32_gui_control != changed_prefs.win32_gui_control ||
                currprefs.right_control_is_right_win_key != changed_prefs.right_control_is_right_win_key)
        {
                currprefs.win32_minimize_inactive = changed_prefs.win32_minimize_inactive;
@@ -2572,6 +2573,7 @@ int check_prefs_changed_gfx(void)
                currprefs.win32_ctrl_F11_is_quit = changed_prefs.win32_ctrl_F11_is_quit;
                currprefs.win32_shutdown_notification = changed_prefs.win32_shutdown_notification;
                currprefs.win32_warn_exit = changed_prefs.win32_warn_exit;
+               currprefs.win32_gui_control = changed_prefs.win32_gui_control;
                currprefs.right_control_is_right_win_key = changed_prefs.right_control_is_right_win_key;
                inputdevice_unacquire ();
                currprefs.keyboard_leds_in_use = changed_prefs.keyboard_leds_in_use = (currprefs.keyboard_leds[0] | currprefs.keyboard_leds[1] | currprefs.keyboard_leds[2]) != 0;
index 58754fb39ca1d85b02d7e5d79a260e89d649d926..b0e95b886dda57783e8a5bf907dbf64f4d2d6cae 100644 (file)
@@ -141,8 +141,11 @@ int dialog_inhibit;
 static HMODULE hHtmlHelp;
 pathtype path_type;
 
+int externaldialogactive;
 static int stringboxdialogactive;
 static int customdialogactive;
+static struct newresource *customdialogres;
+static HWND customdialoghwnd;
 
 void HtmlHelp(const TCHAR *panel)
 {
@@ -310,6 +313,28 @@ struct GUIPAGE {
 };
 static struct GUIPAGE ppage[MAX_C_PAGES];
 
+static void CALLBACK gui_control_cb(HWND h, UINT v, UINT_PTR v3, DWORD v4)
+{
+       HWND ha = GetActiveWindow();
+       if (externaldialogactive) {
+               if (ha) {
+                       HWND p = GetParent(ha);
+                       HWND mainhwnd = AMonitors[0].hAmigaWnd;
+                       if (p && (p == customdialoghwnd || p == guiDlg || p == mainhwnd)) {
+                               process_gui_control(ha, NULL);
+                       }
+               }
+       } else if (customdialogactive > 0 && customdialogres && customdialoghwnd) {
+               if (ha == customdialoghwnd) {
+                       process_gui_control(customdialoghwnd, customdialogres);
+               }
+       } else {
+               if (ha == h) {
+                       process_gui_control(h, panelresource);
+               }
+       }
+}
+
 static bool ischecked(HWND hDlg, DWORD id)
 {
        return IsDlgButtonChecked(hDlg, id) == BST_CHECKED;
@@ -631,7 +656,25 @@ static BOOL GetFileDialog (OPENFILENAME *opn, const GUID *guid, int mode)
                        pfd->SetFolder (shellitem);
        }
 
-       hr = pfd->Show (opn->hwndOwner);
+       externaldialogactive = 1;
+       // GUI control without GUI
+       if (gui_control && hGUIWnd == NULL) {
+               HWND h = AMonitors[0].hAmigaWnd;
+               if (h) {
+                       SetTimer(h, 8, 20, gui_control_cb);
+               }
+       }
+
+       hr = pfd->Show(opn->hwndOwner);
+
+       externaldialogactive = 0;
+       if (gui_control && hGUIWnd == NULL) {
+               HWND h = AMonitors[0].hAmigaWnd;
+               if (h) {
+                       KillTimer(h, 8);
+               }
+       }
+
        if (SUCCEEDED (hr)) {
                UINT idx;
                IShellItemArray *pitema;
@@ -2066,6 +2109,7 @@ int scan_roms (HWND hDlg, int show)
        UAEREG *fkey, *fkey2;
        TCHAR *paths[MAX_ROM_PATHS];
        MSG msg;
+       struct newresource *res = NULL;
 
        if (recursive)
                return 0;
@@ -2081,7 +2125,7 @@ int scan_roms (HWND hDlg, int show)
        infoboxdialogstate = true;
        infoboxhwnd = NULL;
        if (!rp_isactive ()) {
-               HWND hwnd = CustomCreateDialog(IDD_INFOBOX, hDlg, InfoBoxDialogProc);
+               HWND hwnd = CustomCreateDialog(&res, IDD_INFOBOX, hDlg, InfoBoxDialogProc);
                if (!hwnd)
                        goto end;
                infoboxhwnd = hwnd;
@@ -2143,6 +2187,7 @@ end:
                        TranslateMessage (&msg);
                        DispatchMessage (&msg);
                }
+               FreeResource(res);
        }
        read_rom_list(false);
        if (show)
@@ -2577,7 +2622,8 @@ static void eject_cd (void)
 void gui_infotextbox(HWND hDlg, const TCHAR *text)
 {
        stringboxdialogactive = 1;
-       HWND hwnd = CustomCreateDialog(IDD_DISKINFO, hDlg ? hDlg : hGUIWnd, StringBoxDialogProc);
+       struct newresource *res;
+       HWND hwnd = CustomCreateDialog(&res, IDD_DISKINFO, hDlg ? hDlg : hGUIWnd, StringBoxDialogProc);
        if (hwnd == NULL)
                return;
 
@@ -2600,6 +2646,7 @@ void gui_infotextbox(HWND hDlg, const TCHAR *text)
                                break;
                }
        }
+       freescaleresource(res);
        if (font) {
                DeleteObject(font);
        }
@@ -2610,6 +2657,7 @@ static void infofloppy (HWND hDlg, int n)
        struct diskinfo di;
        TCHAR tmp2[MAX_DPATH], tmp1[MAX_DPATH], tmp3[MAX_DPATH];
        TCHAR text[20000];
+       struct newresource *res;
 
        DISK_examine_image (&workprefs, n, &di, true, tmp3);
        DISK_validate_filename(&workprefs, workprefs.floppyslots[n].df, n, tmp1, 0, NULL, NULL, NULL);
@@ -2673,7 +2721,7 @@ static void infofloppy (HWND hDlg, int n)
        }
 
        stringboxdialogactive = 1;
-       HWND hwnd = CustomCreateDialog(IDD_DISKINFO, hDlg, StringBoxDialogProc);
+       HWND hwnd = CustomCreateDialog(&res, IDD_DISKINFO, hDlg, StringBoxDialogProc);
        if (hwnd == NULL)
                return;
 
@@ -2696,6 +2744,7 @@ static void infofloppy (HWND hDlg, int n)
                                break;
                }
        }
+       freescaleresource(res);
        DeleteObject (font);
 }
 
@@ -4756,6 +4805,7 @@ static const struct miscentry misclist[] = {
        { 0, 1, _T("Force hard reset if CPU halted"), &workprefs.crash_auto_reset },
        { 0, 0, _T("A600/A1200/A4000 IDE scsi.device disable"), &workprefs.scsidevicedisable },
        { 0, 1, _T("Warp mode reset"), &workprefs.turbo_boot },
+       { 0, 1, _T("GUI game pad control"), &workprefs.win32_gui_control },
        { 0, 0, NULL }
 };
 
@@ -5782,8 +5832,7 @@ static INT_PTR CALLBACK InfoSettingsProc(HWND hDlg, UINT msg, WPARAM wParam, LPA
                PostQuitMessage(0);
                return TRUE;
        case WM_CLOSE:
-               customdialogactive = 0;
-               DestroyWindow(hDlg);
+               CustomDialogClose(hDlg);
                return TRUE;
        case WM_INITDIALOG:
        {
@@ -5837,13 +5886,11 @@ static INT_PTR CALLBACK InfoSettingsProc(HWND hDlg, UINT msg, WPARAM wParam, LPA
                        DiskSelection(hDlg, IDC_PATH_NAME, 8, &workprefs, NULL, NULL);
                        break;
                        case IDOK:
-                       customdialogactive = -1;
-                       DestroyWindow(hDlg);
+                       CustomDialogClose(hDlg);
                        recursive = 0;
                        return TRUE;
                        case IDCANCEL:
-                       customdialogactive = 0;
-                       DestroyWindow(hDlg);
+                       CustomDialogClose(hDlg);
                        recursive = 0;
                        return TRUE;
                        case IDC_CONFIGAUTO:
@@ -6481,13 +6528,11 @@ static INT_PTR CALLBACK ErrorLogProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM
        switch (msg) {
        case WM_COMMAND:
                if (wParam == IDOK) {
-                       customdialogactive = -1;
-                       DestroyWindow(hDlg);
+                       CustomDialogClose(hDlg);
                        return TRUE;
                } else if (wParam == IDC_ERRORLOGCLEAR) {
                        error_log (NULL);
-                       customdialogactive = 0;
-                       DestroyWindow(hDlg);
+                       CustomDialogClose(hDlg);
                        return TRUE;
                }
                break;
@@ -6554,13 +6599,11 @@ static INT_PTR CALLBACK ContributorsProc (HWND hDlg, UINT msg, WPARAM wParam, LP
                PostQuitMessage(0);
                return TRUE;
        case WM_CLOSE:
-               customdialogactive = 0;
-               DestroyWindow(hDlg);
+               CustomDialogClose(hDlg);
                return TRUE;
        case WM_COMMAND:
                if (wParam == ID_OK) {
-                       customdialogactive = -1;
-                       DestroyWindow(hDlg);
+                       CustomDialogClose(hDlg);
                        return TRUE;
                }
                break;
@@ -14537,8 +14580,7 @@ static INT_PTR CALLBACK VolumeSettingsProc (HWND hDlg, UINT msg, WPARAM wParam,
                PostQuitMessage(0);
                return TRUE;
        case WM_CLOSE:
-               customdialogactive = 0;
-               DestroyWindow(hDlg);
+               CustomDialogClose(hDlg);
                return TRUE;
        case WM_INITDIALOG:
                {
@@ -14623,13 +14665,11 @@ static INT_PTR CALLBACK VolumeSettingsProc (HWND hDlg, UINT msg, WPARAM wParam,
                                volumeselectdir (hDlg, 0, 1);
                                break;
                        case IDOK:
-                               customdialogactive = -1;
-                               DestroyWindow(hDlg);
+                               CustomDialogClose(hDlg);
                                recursive = 0;
                                return TRUE;
                        case IDCANCEL:
-                               customdialogactive = 0;
-                               DestroyWindow(hDlg);
+                               CustomDialogClose(hDlg);
                                recursive = 0;
                                return TRUE;
                        }
@@ -15146,8 +15186,7 @@ static INT_PTR CALLBACK TapeDriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara
                PostQuitMessage(0);
                return TRUE;
        case WM_CLOSE:
-               customdialogactive = 0;
-               DestroyWindow(hDlg);
+               CustomDialogClose(hDlg);
                return TRUE;
        case WM_INITDIALOG:
                recursive++;
@@ -15235,13 +15274,11 @@ static INT_PTR CALLBACK TapeDriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara
                        break;
                }
                case IDOK:
-                       customdialogactive = -1;
-                       DestroyWindow(hDlg);
+                       CustomDialogClose(hDlg);
                        recursive = 0;
                        return TRUE;
                case IDCANCEL:
-                       customdialogactive = 0;
-                       DestroyWindow(hDlg);
+                       CustomDialogClose(hDlg);
                        recursive = 0;
                        return TRUE;
                }
@@ -15268,8 +15305,7 @@ static INT_PTR CALLBACK CDDriveSettingsProc (HWND hDlg, UINT msg, WPARAM wParam,
                PostQuitMessage(0);
                return TRUE;
        case WM_CLOSE:
-               customdialogactive = 0;
-               DestroyWindow(hDlg);
+               CustomDialogClose(hDlg);
                return TRUE;
 
        case WM_INITDIALOG:
@@ -15289,8 +15325,7 @@ static INT_PTR CALLBACK CDDriveSettingsProc (HWND hDlg, UINT msg, WPARAM wParam,
                if (((LPNMHDR) lParam)->idFrom == IDC_CDLIST) {
                        NM_LISTVIEW *nmlistview = (NM_LISTVIEW *)lParam;
                        if (nmlistview->hdr.code == NM_DBLCLK) {
-                               customdialogactive = -1;
-                               DestroyWindow(hDlg);
+                               CustomDialogClose(hDlg);
                                return TRUE;
                        }
                }
@@ -15302,13 +15337,11 @@ static INT_PTR CALLBACK CDDriveSettingsProc (HWND hDlg, UINT msg, WPARAM wParam,
                switch (LOWORD (wParam))
                {
                case IDOK:
-                       customdialogactive = -1;
-                       DestroyWindow(hDlg);
+                       CustomDialogClose(hDlg);
                        recursive = 0;
                        return TRUE;
                case IDCANCEL:
-                       customdialogactive = 0;
-                       DestroyWindow(hDlg);
+                       CustomDialogClose(hDlg);
                        recursive = 0;
                        return TRUE;
                case IDC_HDF_CONTROLLER:
@@ -15382,8 +15415,7 @@ static INT_PTR CALLBACK HardfileSettingsProc (HWND hDlg, UINT msg, WPARAM wParam
                PostQuitMessage(0);
                return TRUE;
        case WM_CLOSE:
-               customdialogactive = 0;
-               DestroyWindow(hDlg);
+               CustomDialogClose(hDlg);
                return TRUE;
        case WM_DROPFILES:
                dragdrop (hDlg, (HDROP)wParam, &changed_prefs, -2);
@@ -15544,13 +15576,11 @@ static INT_PTR CALLBACK HardfileSettingsProc (HWND hDlg, UINT msg, WPARAM wParam
                        DISK_history_add(current_hfdlg.ci.filesys, -1, HISTORY_FS, 1);
                        break;
                case IDOK:
-                       customdialogactive = -1;
-                       DestroyWindow(hDlg);
+                       CustomDialogClose(hDlg);
                        recursive = 0;
                        return TRUE;
                case IDCANCEL:
-                       customdialogactive = 0;
-                       DestroyWindow(hDlg);
+                       CustomDialogClose(hDlg);
                        recursive = 0;
                        return TRUE;
                case IDC_HDF_PHYSGEOMETRY:
@@ -15677,8 +15707,7 @@ static INT_PTR CALLBACK HarddriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara
                PostQuitMessage(0);
                return TRUE;
        case WM_CLOSE:
-               customdialogactive = 0;
-               DestroyWindow(hDlg);
+               CustomDialogClose(hDlg);
                return TRUE;
        case WM_INITDIALOG:
                {
@@ -15735,13 +15764,11 @@ static INT_PTR CALLBACK HarddriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara
                if (HIWORD (wParam) == BN_CLICKED) {
                        switch (LOWORD (wParam)) {
                        case IDOK:
-                               customdialogactive = -1;
-                               DestroyWindow(hDlg);
+                               CustomDialogClose(hDlg);
                                recursive = 0;
                                return TRUE;
                        case IDCANCEL:
-                               customdialogactive = 0;
-                               DestroyWindow(hDlg);
+                               CustomDialogClose(hDlg);
                                recursive = 0;
                                return TRUE;
                        case IDC_HDF_PHYSGEOMETRY:
@@ -18536,10 +18563,11 @@ static void values_to_inputdlg (HWND hDlg)
 static int askinputcustom (HWND hDlg, TCHAR *custom, int maxlen, DWORD titleid)
 {
        HWND hwnd;
+       struct newresource *res;
        TCHAR txt[MAX_DPATH];
 
        stringboxdialogactive = 1;
-       hwnd = CustomCreateDialog (IDD_STRINGBOX, hDlg, StringBoxDialogProc);
+       hwnd = CustomCreateDialog(&res, IDD_STRINGBOX, hDlg, StringBoxDialogProc);
        if (hwnd == NULL)
                return 0;
        if (titleid != 0) {
@@ -18563,9 +18591,11 @@ static int askinputcustom (HWND hDlg, TCHAR *custom, int maxlen, DWORD titleid)
                }
                if (stringboxdialogactive == -1) {
                        _tcscpy (custom, txt);
+                       freescaleresource(res);
                        return 1;
                }
        }
+       freescaleresource(res);
        return 0;
 }
 
@@ -19491,8 +19521,7 @@ static INT_PTR CALLBACK RemapSpecialsProc(HWND hDlg, UINT msg, WPARAM wParam, LP
                                if (inputmap_handle(NULL, -1, -1, NULL, NULL, -1, NULL, inputmap_selected,
                                        remapcustoms[entry].flags, IDEV_MAPPED_AUTOFIRE_SET | IDEV_MAPPED_TOGGLE | IDEV_MAPPED_INVERTTOGGLE | IDEV_MAPPED_INVERT, NULL)) {
                                        inputdevice_generate_jport_custom(&workprefs, inputmap_port);
-                                       customdialogactive = -1;
-                                       DestroyWindow(hDlg);
+                                       CustomDialogClose(hDlg);
                                        return TRUE;
                                }
                        }
@@ -19513,13 +19542,11 @@ static INT_PTR CALLBACK RemapSpecialsProc(HWND hDlg, UINT msg, WPARAM wParam, LP
                break;
        }
        case IDOK:
-       customdialogactive = -1;
-       DestroyWindow(hDlg);
+       CustomDialogClose(hDlg);
        recursive = 0;
        return TRUE;
        case IDCANCEL:
-       customdialogactive = 0;
-       DestroyWindow(hDlg);
+       CustomDialogClose(hDlg);
        recursive = 0;
        return TRUE;
        }
@@ -19531,7 +19558,9 @@ static INT_PTR CALLBACK RemapSpecialsProc(HWND hDlg, UINT msg, WPARAM wParam, LP
 
 static void input_remapspecials(HWND hDlg)
 {
-       CustomCreateDialog(IDD_LIST, hDlg, RemapSpecialsProc);
+       struct newresource *res;
+       CustomCreateDialog(&res, IDD_LIST, hDlg, RemapSpecialsProc);
+       freescaleresource(res);
 }
 
 static INT_PTR CALLBACK InputMapDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
@@ -19697,12 +19726,13 @@ static INT_PTR CALLBACK InputMapDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPA
 
 static void ports_remap (HWND hDlg, int port, int sub)
 {
+       struct newresource *res;
        inputmap_port = port;
        if (sub < 0) {
                sub = 0;
        }
        inputmap_port_sub = sub;
-       HWND dlg = CustomCreateDialog (IDD_INPUTMAP, hDlg, InputMapDlgProc);
+       HWND dlg = CustomCreateDialog(&res, IDD_INPUTMAP, hDlg, InputMapDlgProc);
        if (dlg == NULL)
                return;
        MSG msg;
@@ -19726,6 +19756,7 @@ static void ports_remap (HWND hDlg, int port, int sub)
                TranslateMessage (&msg);
                DispatchMessage (&msg);
        }
+       freescaleresource(res);
 }
 
 static void input_togglesetmode (void)
@@ -19949,13 +19980,11 @@ static INT_PTR CALLBACK QualifierProc (HWND hDlg, UINT msg, WPARAM wParam, LPARA
                                break;
                        }
                case IDOK:
-                       customdialogactive = -1;
-                       DestroyWindow(hDlg);
+                       CustomDialogClose(hDlg);
                        recursive = 0;
                        return TRUE;
                case IDCANCEL:
-                       customdialogactive = 0;
-                       DestroyWindow(hDlg);
+                       CustomDialogClose(hDlg);
                        recursive = 0;
                        return TRUE;
                }
@@ -19971,6 +20000,7 @@ static void input_qualifiers (HWND hDlg)
        int evt;
        TCHAR name[256];
        TCHAR custom[MAX_DPATH];
+       struct newresource *res;
        
        if (input_selected_device < 0 || input_selected_widget < 0)
                return;
@@ -19979,7 +20009,8 @@ static void input_qualifiers (HWND hDlg)
        if (evt <= 0)
                name[0] = 0;
        
-       CustomCreateDialog(IDD_LIST, hDlg, QualifierProc);
+       CustomCreateDialog(&res, IDD_LIST, hDlg, QualifierProc);
+       freescaleresource(res);
 #if 0
        int item = genericpopupmenu (hDlg, names, mflags, MAX_INPUT_QUALIFIERS * 2);
        if (item >= 0)
@@ -21959,6 +21990,7 @@ static HWND updatePanel (int id, UINT action)
        static HWND hwndTT;
        static bool first = true;
        int fullpanel;
+       HWND focus = GetFocus();
 
        SaveListView(panelDlg, false);
        listview_id = 0;
@@ -22056,9 +22088,15 @@ static HWND updatePanel (int id, UINT action)
 
        hAccelTable = ppage[currentpage].accel;
 
+#if 0
        if (ppage[id].focusid > 0 && action != TVC_BYKEYBOARD) {
                setfocus (panelDlg, ppage[id].focusid);
        }
+#endif
+
+       if (focus) {
+               SetFocus(focus);
+       }
 
        return panelDlg;
 }
@@ -23000,6 +23038,7 @@ static INT_PTR CALLBACK DialogProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l
                gui_size_changed = 1;
                return 0;
        }
+
        handlerawinput (hDlg, msg, wParam, lParam);
        return FALSE;
 }
@@ -23051,7 +23090,16 @@ struct newresource *getresource (int tmpl)
        return nr;
 }
 
-INT_PTR CustomDialogBox (int templ, HWND hDlg, DLGPROC proc)
+void CustomDialogClose(HWND hDlg)
+{
+       customdialogactive = 0;
+       customdialoghwnd = NULL;
+       freescaleresource(customdialogres);
+       customdialogres = NULL;
+       DestroyWindow(hDlg);
+}
+
+INT_PTR CustomDialogBox(int templ, HWND hDlg, DLGPROC proc)
 {
        struct newresource *res;
        struct dlgcontext dctx;
@@ -23070,12 +23118,13 @@ INT_PTR CustomDialogBox (int templ, HWND hDlg, DLGPROC proc)
        return h;
 }
 
-HWND CustomCreateDialog(int templ, HWND hDlg, DLGPROC proc)
+HWND CustomCreateDialog(struct newresource **resp, int templ, HWND hDlg, DLGPROC proc)
 {
        struct newresource *res;
        struct dlgcontext dctx;
        HWND h = NULL;
 
+       *resp = NULL;
        res = getresource (templ);
        if (!res)
                return h;
@@ -23083,17 +23132,20 @@ HWND CustomCreateDialog(int templ, HWND hDlg, DLGPROC proc)
                res->parent = panelresource;
                h = x_CreateDialogIndirectParam(res->inst, res->resource, hDlg, proc, NULL, res);
        }
-       freescaleresource (res);
+       *resp = res;
        return h;
 }
 
 int CustomCreateDialogBox(int templ, HWND hDlg, DLGPROC proc)
 {
+       struct newresource *res;
        customdialogactive = 1;
-       HWND hwnd = CustomCreateDialog(templ, hDlg, proc);
+       HWND hwnd = CustomCreateDialog(&res, templ, hDlg, proc);
        if (!hwnd) {
                return 0;
        }
+       customdialogres = res;
+       customdialoghwnd = hwnd;
        while (customdialogactive == 1) {
                MSG msg;
                int ret;
@@ -23300,6 +23352,7 @@ static int GetSettings (int all_options, HWND hwnd)
        int fmultx = 0, fmulty = 0;
        int resetcount = 0;
        bool boxart_reopen = false;
+       int use_gui_control = gui_control > 0 ? 2 : -1;
        setdefaultguisize(0);
        getstoredguisize();
        scaleresource_setsize(-1, -1, -1);
@@ -23473,8 +23526,12 @@ static int GetSettings (int all_options, HWND hwnd)
                                reset_box_art_window();
                                boxart_reopen = false;
                        }
-                       if (devicechangetimer < 0)
+                       if (devicechangetimer < 0) {
                                SetTimer(dhwnd, 4, 2000, NULL);
+                       }
+                       if (use_gui_control > 1) {
+                               SetTimer(dhwnd, 8, 20, gui_control_cb);
+                       }
                        
                        for (;;) {
                                HANDLE IPChandle;
@@ -23540,6 +23597,14 @@ static int GetSettings (int all_options, HWND hwnd)
                                        // reset after IDCANCEL which would save coordinates
                                        gui_fullscreen = 0;
                                }
+                               if ((workprefs.win32_gui_control ? 1 : 0) != use_gui_control && use_gui_control < 2) {
+                                       use_gui_control = workprefs.win32_gui_control;
+                                       if (use_gui_control) {
+                                               SetTimer(dhwnd, 8, 30, gui_control_cb);
+                                       } else {
+                                               KillTimer(dhwnd, 8);
+                                       }
+                               }
                        }
                        psresult = dialogreturn;
                } else {
@@ -23560,6 +23625,10 @@ gui_exit:
                quit_program = 0;
        }
 
+       if (use_gui_control > 0) {
+               KillTimer(dhwnd, 8);
+       }
+
        hGUIWnd = NULL;
        if (quit_program) {
                psresult = -2;
index 5ca49cae6a13ef65440cc2adfdcb17e901e06294..a855590f2146f3b275918a769504647fed5028d1 100644 (file)
@@ -72,8 +72,12 @@ typedef struct
 
 struct newreswnd
 {
-       HWND hwnd;
+       HWND hwnd, hwndx[5];
        LONG x, y, w, h;
+       int style;
+       int region;
+       bool selectable;
+       bool list, listn;
 };
 
 struct newresource
@@ -114,6 +118,8 @@ struct newresource
 
 extern struct uae_prefs workprefs;
 extern int dialog_inhibit;
+extern int gui_control;
+extern int externaldialogactive;
 
 HWND x_CreateDialogIndirectParam(HINSTANCE hInstance, LPCDLGTEMPLATE lpTemplate, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM lParamInit, struct newresource*);
 void x_DestroyWindow(HWND, struct newresource*);
@@ -122,8 +128,9 @@ extern int scaleresource(struct newresource*, struct dlgcontext *dctx, HWND, int
 extern void rescaleresource(struct newresource*, bool);
 extern void freescaleresource (struct newresource*);
 extern void scaleresource_setsize (int w, int h, int fs);
-extern HWND CustomCreateDialog (int templ, HWND hDlg, DLGPROC proc);
+extern HWND CustomCreateDialog (struct newresource **, int templ, HWND hDlg, DLGPROC proc);
 extern int CustomCreateDialogBox(int templ, HWND hDlg, DLGPROC proc);
+extern void CustomDialogClose(HWND);
 extern INT_PTR CustomDialogBox (int templ, HWND hDlg, DLGPROC proc);
 extern struct newresource *getresource (int tmpl);
 extern void scaleresource_init(const TCHAR*, int);
@@ -143,6 +150,9 @@ extern int calculated_boxart_window_width;
 void getextendedframebounds(HWND hwnd, RECT *r);
 void reset_box_art_window(void);
 
+void gui_cursor(HWND, struct newresource*, int, int, int);
+void process_gui_control(HWND h, struct newresource *nres);
+
 void darkmode_initdialog(HWND hDlg);
 void darkmode_themechanged(HWND hDlg);
 INT_PTR darkmode_ctlcolor(WPARAM wParam, bool *handled);
index e628bfeff9448f0dce9be4342ad3ac73bfb81f7b..5fb753bc52a4d286ada4fbcdcd1a46ac57ae065b 100644 (file)
@@ -6,6 +6,8 @@
 #include <Dwmapi.h>
 #include <shellscalingapi.h>
 #include <shlwapi.h>
+#include <uiautomation.h>
+#include "Xinput.h"
 
 #include "sysconfig.h"
 #include "sysdeps.h"
@@ -41,6 +43,8 @@ static int fontweight_list = FW_REGULAR;
 static TEXTMETRIC listview_tm;
 static const TCHAR *fontprefix;
 
+static IUIAutomation *Automation;
+
 #include <pshpack2.h>
 typedef struct {
        WORD dlgVer;
@@ -259,7 +263,6 @@ static const WORD *DIALOG_GetControl32(const WORD *p, DLG_CONTROL_INFO *info,
        return (const WORD *)(((UINT_PTR)p + 3) & ~3);
 }
 
-
 static BOOL DIALOG_CreateControls32(HWND hwnd, LPCSTR tmpl, const DLG_TEMPLATE *dlgTemplate,
        HINSTANCE hInst, struct newresource *res)
 {
@@ -314,6 +317,75 @@ static BOOL DIALOG_CreateControls32(HWND hwnd, LPCSTR tmpl, const DLG_TEMPLATE *
                nrw->y = y;
                nrw->w = w;
                nrw->h = h;
+               if (info.id != IDC_STATIC) {
+                       int style = info.style & BS_TYPEMASK;
+                       if (!_tcsicmp(info.className, _T("Button")) ||
+                               !_tcsicmp(info.className, _T("ComboBox")) ||
+                               !_tcsicmp(info.className, _T("SysTreeView32")) ||
+                               !_tcsicmp(info.className, _T("SysListView32")) ||
+                               !_tcsicmp(info.className, _T("msctls_trackbar32")) ||
+                               !_tcsicmp(info.className, _T("Edit"))) {                
+                               if (style == BS_GROUPBOX) {
+                                       nrw->selectable = false;
+                               } else {
+                                       nrw->selectable = true;
+                               }
+                               if (!_tcsicmp(info.className, _T("Edit"))) {
+                                       if (info.style & ES_READONLY)  {
+                                               nrw->selectable = false;
+                                       }
+                               }
+                               if (!_tcsicmp(info.className, _T("ComboBox"))) {
+                                       style |= 0x100;
+                               }
+                               if (!_tcsicmp(info.className, _T("msctls_trackbar32"))) {
+                                       style |= 0x200;
+                               }
+                               if (!_tcsicmp(info.className, _T("SysTreeView32"))) {
+                                       nrw->list = true;
+                                       nrw->region = 3;
+                                       style |= 0x400;
+                               }
+                               if (!_tcsicmp(info.className, _T("SysListView32"))) {
+                                       nrw->listn = true;
+                                       nrw->region = 3;
+                                       style |= 0x400;
+                               }
+                               nrw->style = style;
+                               int i = 0;
+                               nrw->hwndx[i++] = nrw->hwnd;
+                               if (!_tcsicmp(info.className, _T("ComboBox"))) {
+                                       COMBOBOXINFO pcbi = {};
+                                       pcbi.cbSize = sizeof(COMBOBOXINFO);
+                                       GetComboBoxInfo(nrw->hwnd, &pcbi);
+                                       if (pcbi.hwndItem && pcbi.hwndItem != nrw->hwnd) {
+                                               nrw->hwndx[i++] = pcbi.hwndItem;
+                                       }
+                                       if (pcbi.hwndCombo && pcbi.hwndCombo != nrw->hwnd) {
+                                               nrw->hwndx[i++] = pcbi.hwndCombo;
+                                       }
+                                       if (pcbi.hwndList && pcbi.hwndList != nrw->hwnd) {
+                                               nrw->hwndx[i++] = pcbi.hwndList;
+                                       }
+                               }
+                               switch(info.id)
+                               {
+                                       case IDC_PANELTREE:
+                                       nrw->region = 2;
+                                       break;
+                                       case IDC_RESETAMIGA:
+                                       case IDC_QUITEMU:
+                                       case IDC_RESTARTEMU:
+                                       case IDC_ERRORLOG:
+                                       case IDOK:
+                                       case IDCANCEL:
+                                       case IDHELP:
+                                       nrw->region = 1;
+                                       break;
+                               }
+                       }
+                       //write_log(_T("%p %s %d %08x\n"), hwndCtrl, info.className, info.id, info.style);
+               }
 
                /* Send initialisation messages to the control */
                if (dlgInfo->hUserFont) SendMessage(hwndCtrl, WM_SETFONT,
@@ -2002,3 +2074,646 @@ LRESULT CALLBACK BoxArtWindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
        }
        return DefWindowProc(hWnd, message, wParam, lParam);
 }
+
+
+static HRESULT InitializeUIAutomation(IUIAutomation **ppAutomation)
+{
+       return CoCreateInstance(CLSID_CUIAutomation, NULL,
+               CLSCTX_INPROC_SERVER, IID_IUIAutomation,
+               reinterpret_cast<void **>(ppAutomation));
+}
+
+struct elxy
+{
+       int sx, sy;
+       int ex, ey;
+       int region;
+       bool selectable;
+       struct newreswnd *nres;
+};
+
+static struct elxy *findclosestelement(struct elxy *xy, int total, struct elxy *curxy, int x, int y, int region, int newdist, int xydist)
+{
+       struct elxy *closest = NULL;
+       int olddist = 10000;
+
+       int cx = curxy->sx;
+       int cy = curxy->sy;
+       int cxe = curxy->ex;
+       int cye = curxy->ey;
+
+       if (x > 0) {
+               cxe = cx = curxy->ex + 1;
+       } else if (x < 0) {
+               cxe = cx = curxy->sx - 1;
+       }
+       if (y > 0) {
+               cye = cy = curxy->ey + 1;
+       } else if (y < 0) {
+               cye = cy = curxy->sy - 1;
+       }
+
+       cx += x * newdist;
+       cy += y * newdist;
+       cxe += x * newdist;
+       cye += y * newdist;
+
+       int cxs = cx + (cxe - cx) / 2;
+       int cys = cy + (cye - cy) / 2;
+
+       for (int i = 0; i < total; i++) {
+               struct elxy *txy = &xy[i];
+               int dist = -1;
+               int sx = txy->sx;
+               int sy = txy->sy;
+               int ex = txy->ex;
+               int ey = txy->ey;
+
+               if (!txy->selectable) {
+                       continue;
+               }
+
+               if (txy->region != region) {
+                       continue;
+               }
+
+               if (x) {
+                       ey += xydist;
+                       sy -= xydist;
+               }
+               if (y) {
+                       ex += xydist;
+                       sx -= xydist;
+               }
+
+               if ((sx <= cxs && ex >= cxs) && y) {
+                       if ((y < 0 && txy->ey < curxy->sy) || (y > 0 && txy->sy > curxy->ey)) {
+                               dist = abs(txy->sy + (txy->ey - txy->sy) / 2 - cys);
+                       }
+               } else if ((sy <= cys && ey >= cys) && x) {
+                       if ((x < 0 && txy->ex < curxy->sx) || (x > 0 && txy->sx > curxy->ex)) {
+                               dist = abs(txy->sx + (txy->ex - txy->sx) / 2 - cxs);
+                       }
+               }
+               if (dist > 0 && dist < olddist) {
+                       closest = txy;
+                       olddist = dist;
+               }
+       }
+       return closest;
+}
+
+static void UIA_Invoke(HWND hwnd)
+{
+       IUIAutomationElement *el;
+       HRESULT hr = Automation->GetFocusedElement(&el);
+       if (SUCCEEDED(hr)) {
+               IUIAutomationInvokePattern *InvokePattern;
+               hr = el->GetCurrentPattern(UIA_InvokePatternId, (IUnknown **)&InvokePattern);
+               if (SUCCEEDED(hr) && InvokePattern) {
+                       InvokePattern->Invoke();
+                       InvokePattern->Release();
+               }
+               el->Release();
+       }
+}
+
+static void treeview_cursor(HWND h, HTREEITEM next)
+{
+       TreeView_SelectItem(h, next);
+       RECT r;
+       r.left = -1;
+       r.top = -1;
+       TreeView_GetItemRect(h, next, &r, TRUE);
+       if (r.left != -1 && r.top != -1) {
+               RECT r2;
+               GetWindowRect(h, &r2);
+               r.left += r2.left;
+               r.right += r2.left;
+               r.top += r2.top;
+               r.bottom += r2.top;
+               SetCursorPos(r.left + (r.right - r.left) / 2, r.top + (r.bottom - r.top) / 2);
+       }
+}
+
+void gui_cursor(HWND hwnd, struct newresource *ns, int x, int y, int click)
+{
+       struct elxy *found = NULL;
+       struct elxy *currres;
+       struct elxy xy[MAX_DLGID];
+       int total = 0;
+       int maxdist = 0;
+       int mindist = 32000;
+
+       if (!Automation) {
+               InitializeUIAutomation(&Automation);
+       }
+       if (!Automation) {
+               return;
+       }
+
+       for (int i = 0; ns->hwnds[i].hwnd; i++) {
+               struct newreswnd *nrw = &ns->hwnds[i];
+               if (nrw->selectable && IsWindowVisible(nrw->hwnd) && IsWindowEnabled(nrw->hwnd)) {
+                       RECT r;
+                       GetWindowRect(nrw->hwnd, &r);
+                       struct elxy *txy = &xy[total];
+                       txy->sx = r.left;
+                       txy->sy = r.top;
+                       txy->ex = r.right;
+                       txy->ey = r.bottom;
+                       txy->region = nrw->region;
+                       txy->selectable = nrw->selectable;
+                       txy->nres = nrw;
+                       total++;
+               }
+       }
+       ns = ns->child;
+       if (ns) {
+               for (int i = 0; ns->hwnds[i].hwnd; i++) {
+                       struct newreswnd *nrw = &ns->hwnds[i];
+                       if (IsWindowVisible(nrw->hwnd) && IsWindowEnabled(nrw->hwnd)) {
+                               RECT r;
+                               GetWindowRect(nrw->hwnd, &r);
+                               struct elxy *txy = &xy[total];
+                               txy->sx = r.left;
+                               txy->sy = r.top;
+                               txy->ex = r.right;
+                               txy->ey = r.bottom;
+                               txy->region = nrw->region;
+                               txy->selectable = nrw->selectable;
+                               txy->nres = nrw;
+                               total++;
+                       }
+               }
+       }
+
+       for (int i = 0; i < total; i++) {
+               struct elxy *txy = &xy[i];
+               struct newreswnd *nrw = txy->nres;
+               if (nrw->x + nrw->w > maxdist) {
+                       maxdist = nrw->x + nrw->x;
+               }
+               if (nrw->y + nrw->h > maxdist) {
+                       maxdist = nrw->y + nrw->h;
+               }
+               if (nrw->x < mindist) {
+                       mindist = nrw->x;
+               }
+               if (nrw->y < mindist) {
+                       mindist = nrw->y;
+               }
+       }
+
+       currres = NULL;
+       HWND focus = GetFocus();
+       for (int i = 0; i < total; i++) {
+               struct elxy *txy = &xy[i];
+               for (int j = 0; txy->nres->hwndx[j]; j++) {
+                       HWND h = txy->nres->hwndx[j];
+                       if (h == focus && txy->selectable) {
+                               RECT r;
+                               GetWindowRect(h, &r);
+                               currres = txy;
+                               write_log("%p %d\n", currres->nres->hwnd, currres->region);
+                               break;
+                       }
+               }
+       }
+
+       if (click == 8) {
+               bool regfound = false;
+               int region = 0;
+               if (currres) {
+                       region = currres->region;
+               }
+               while (!regfound) {
+                       region++;
+                       if (region >= 4) {
+                               region = 0;
+                       }
+                       for (int i = 0; i < total; i++) {
+                               struct elxy *txy = &xy[i];
+                               if (txy->region == region) {
+                                       if (txy->selectable) {
+                                               found = txy;
+                                               goto end;
+                                       }
+                                       regfound = true;
+                               }
+                       }
+               }
+               return;
+       }
+
+
+       if (currres && click == 1 && x && !y) {
+               int style = currres->nres->style;
+               // msctls_trackbar32
+               if (style & 0x200) {
+                       HWND h = currres->nres->hwnd;
+                       LRESULT v = SendMessage(h, TBM_GETPOS, 0, 0);
+                       LRESULT min = SendMessage(h, TBM_GETRANGEMIN, 0, 0);
+                       LRESULT max = SendMessage(h, TBM_GETRANGEMAX, 0, 0);
+                       LRESULT change = SendMessage(h, TBM_GETLINESIZE, 0, 0);
+                       v += change * x;
+                       if (v < min) {
+                               v = min;
+                       }
+                       if (v > max) {
+                               v = max;
+                       }
+                       SendMessage(h, TBM_SETPOSNOTIFY, 0, v);
+               }
+               return;
+       }
+
+       if (currres && click == 1 && !x && !y) {
+               HWND h = currres->nres->hwnd;
+               int style = currres->nres->style;
+               int style2 = style & BS_TYPEMASK;
+               // ComboBox expand/collapse
+               if (style & 0x100) {
+                       IUIAutomationElement *el;
+                       HRESULT hr = Automation->ElementFromHandle(currres->nres->hwndx[0], &el);
+                       if (SUCCEEDED(hr)) {
+                               IUIAutomationExpandCollapsePattern *ExpandCollapsePattern;
+                               hr = el->GetCurrentPattern(UIA_ExpandCollapsePatternId, (IUnknown **)&ExpandCollapsePattern);
+                               if (SUCCEEDED(hr) && ExpandCollapsePattern) {
+                                       ExpandCollapseState ecs;
+                                       hr = ExpandCollapsePattern->get_CurrentExpandCollapseState(&ecs);
+                                       if (SUCCEEDED(hr)) {
+                                               if (ecs == ExpandCollapseState_Collapsed) {
+                                                       ExpandCollapsePattern->Expand();
+                                               } else {
+                                                       ExpandCollapsePattern->Collapse();
+                                               }
+                                       }
+                                       ExpandCollapsePattern->Release();
+                               }
+                               el->Release();
+                       }
+               } else if (currres->nres->listn) {
+                       // ListView
+                       int c = ListView_GetHotItem(h);
+                       UINT state = ListView_GetItemState(h, c, LVIS_STATEIMAGEMASK);
+                       // checkbox toggle
+                       if (state & 0x3000) {
+                               if ((state & 0x3000) == 0x1000) {
+                                       state &= ~0x1000;
+                                       state |= 0x2000;
+                               } else {
+                                       state &= ~0x2000;
+                                       state |= 0x1000;
+                               }
+                               ListView_SetItemState(h, c, state, LVIS_STATEIMAGEMASK);
+                       }
+                       return;
+               } else if (style2 == BS_PUSHBUTTON ||
+                       style2 == BS_DEFPUSHBUTTON ||
+                       style2 == BS_CHECKBOX ||
+                       style2 == BS_AUTOCHECKBOX ||
+                       style2 == BS_RADIOBUTTON ||
+                       style2 == BS_AUTORADIOBUTTON ||
+                       style2 == BS_3STATE ||
+                       style2 == BS_AUTO3STATE)
+               {
+                       // button, checkbox etc click
+                       UIA_Invoke(h);
+                       return;
+               }
+               return;
+       }
+       
+       if (currres) {
+               int style = currres->nres->style;
+               HWND h = currres->nres->hwnd;
+               // TreeView up/down
+               if (currres->nres->list) {
+                       if (x || y) {
+                               HTREEITEM c = TreeView_GetSelection(h);
+                               HTREEITEM next;
+                               if (x < 0) {
+                                       next = TreeView_GetNextItem(h, c, TVGN_PARENT);
+                               } else if (x > 0) {
+                                       next = TreeView_GetNextItem(h, c, TVGN_CHILD);
+                                       if (!next) {
+                                               HTREEITEM next2 = c;
+                                               for (;;) {
+                                                       next2 = TreeView_GetNextItem(h, next2, TVGN_NEXT);
+                                                       if (!next2) {
+                                                               break;
+                                                       }
+                                                       next = TreeView_GetNextItem(h, next2, TVGN_CHILD);
+                                                       if (next) {
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                               } else if (y < 0) {
+                                       next = TreeView_GetNextItem(h, c, TVGN_PREVIOUS);
+                                       if (!next) {
+                                               next = c;
+                                               for (;;) {
+                                                       HTREEITEM next2 = TreeView_GetNextItem(h, next, TVGN_NEXT);
+                                                       if (!next2) {
+                                                               break;
+                                                       }
+                                                       next = next2;
+                                               }
+                                       }
+                               } else if (y > 0) {
+                                       next = TreeView_GetNextItem(h, c, TVGN_NEXT);
+                                       if (!next) {
+                                               next = TreeView_GetNextItem(h, c, TVGN_PARENT);
+                                               if (next) {
+                                                       next = TreeView_GetNextItem(h, next, TVGN_CHILD);
+                                               } else {
+                                                       next = TreeView_GetNextItem(h, c, TVGN_CHILD);
+                                               }
+                                       }
+                               }
+                               if (!next) {
+                                       next = TreeView_GetNextItem(h, next, TVGN_ROOT);
+                               }
+                               if (next) {
+                                       treeview_cursor(h, next);
+                               }
+                               return;
+                       }
+               } else if (currres->nres->listn) {
+                       // ListView
+                       if (!x && y) {
+                               int c = ListView_GetHotItem(h);
+                               int total = ListView_GetItemCount(h);
+                               c += y;
+                               if (c < 0) {
+                                       c = total - 1;
+                                       if (c < 0) {
+                                               c = 0;
+                                       }
+                               }
+                               if (c >= total) {
+                                       c = 0;
+                               }
+                               ListView_SetHotItem(h, c);
+                               ListView_EnsureVisible(h, c, FALSE);
+                               RECT r;
+                               r.left = -1;
+                               r.top = -1;
+                               ListView_GetItemRect(h, c, &r, LVIR_BOUNDS);
+                               if (r.left != -1 && r.top != -1) {
+                                       RECT r2;
+                                       GetWindowRect(h, &r2);
+                                       r.left += r2.left;
+                                       r.right += r2.left;
+                                       r.top += r2.top;
+                                       r.bottom += r2.top;
+                                       SetCursorPos(r.left + (r.right - r.left) / 3, r.top + (r.bottom - r.top) / 2);
+                               }
+                       }
+                       return;
+               } else if (style & 0x100) {
+                       // ComboBox expanded up/down
+                       IUIAutomationElement *el;
+                       //HRESULT hr = Automation->GetFocusedElement(&el);
+                       HRESULT hr = Automation->ElementFromHandle(currres->nres->hwndx[0], &el);
+                       if (SUCCEEDED(hr)) {
+                               IUIAutomationExpandCollapsePattern *ExpandCollapsePattern;
+                               hr = el->GetCurrentPattern(UIA_ExpandCollapsePatternId, (IUnknown **)&ExpandCollapsePattern);
+                               if (SUCCEEDED(hr) && ExpandCollapsePattern) {
+                                       ExpandCollapseState ecs;
+                                       hr = ExpandCollapsePattern->get_CurrentExpandCollapseState(&ecs);
+                                       if (SUCCEEDED(hr)) {
+                                               if (ecs != ExpandCollapseState_Collapsed) {
+                                                       ExpandCollapsePattern->Release();
+                                                       el->Release();
+                                                       INPUT inp[2] = {};
+                                                       inp[0].type = INPUT_KEYBOARD;
+                                                       inp[0].ki.wVk = y < 0 ? VK_UP : VK_DOWN;
+                                                       inp[1].type = INPUT_KEYBOARD;
+                                                       inp[1].ki.wVk = inp[0].ki.wVk;
+                                                       inp[1].ki.dwFlags = KEYEVENTF_KEYUP;
+                                                       SendInput(ARRAYSIZE(inp), inp, sizeof(INPUT));
+                                                       return;
+                                               }
+                                       }
+                                       ExpandCollapsePattern->Release();
+                               }
+                               el->Release();
+                       }
+               }
+       }
+
+       if (currres && (x || y)) {
+               int dist_min = 10;
+               int dist_max = maxdist - mindist;
+               int dist_step = 10;
+
+               int region = currres->region;
+               for(int j = 0; j < 5 && !found; j++) {
+                       for (int i = dist_min; i < dist_max && !found; i += dist_step) {
+                               struct elxy *n = findclosestelement(xy, total, currres, x, y, region, i, dist_max * j / 10);
+                               if (n && n != currres) {
+                                       found = n;
+                               }
+                       }
+               }
+       }
+end:
+       if (found) {
+               HWND h = found->nres->hwnd;
+               if (found->nres->list) {
+                       HTREEITEM c = TreeView_GetSelection(h);
+                       treeview_cursor(h, c);
+               } else {
+                       RECT r;
+                       GetWindowRect(h, &r);
+                       SetCursorPos(r.left + (r.right - r.left) / 3, r.top + (r.bottom - r.top) / 2);
+                       //SetCursorPos(r.left, r.top);
+               }
+               HWND parent = GetParent(h);
+               SetFocus(parent);
+               SendMessage(hwnd, WM_NEXTDLGCTL, (WPARAM)h, TRUE);
+
+               //write_log("%p -> %p\n", focus, h);
+       }
+
+}
+
+#define MAX_PADS 4
+
+int gui_control = 1;
+
+void process_gui_control(HWND h, struct newresource *nres)
+{
+       static int clicked[MAX_PADS];
+       static int lastbuttons[MAX_PADS];
+       static int mousemove;
+
+       if (h == NULL || nres == NULL) {
+               mousemove = 1;
+       }
+
+       for (int i = 0; i < MAX_PADS; i++) {
+               XINPUT_STATE xstate;
+               DWORD state = XInputGetState(i, &xstate);
+               if (state == ERROR_SUCCESS) {
+                       int buttons = xstate.Gamepad.wButtons;
+                       int oldclick = clicked[i];
+                       bool clickchanged = false;
+                       if (buttons & XINPUT_GAMEPAD_A) {
+                               clicked[i] |= 1;
+                       } else {
+                               clicked[i] &= ~1;
+                       }
+                       if (buttons & XINPUT_GAMEPAD_B) {
+                               clicked[i] |= 2;
+                       } else {
+                               clicked[i] &= ~2;
+                       }
+                       if (buttons & XINPUT_GAMEPAD_X) {
+                               clicked[i] |= 4;
+                       } else {
+                               clicked[i] &= ~4;
+                       }
+                       if (buttons & XINPUT_GAMEPAD_Y) {
+                               clicked[i] |= 8;
+                       } else {
+                               clicked[i] &= ~8;
+                       }
+                       if (clicked[i] != oldclick) {
+                               clickchanged = true;
+                       }
+
+                       int newbuttons = buttons;
+                       if (lastbuttons[i] & (XINPUT_GAMEPAD_DPAD_UP | XINPUT_GAMEPAD_DPAD_DOWN | XINPUT_GAMEPAD_DPAD_LEFT | XINPUT_GAMEPAD_DPAD_RIGHT)) {
+                               if (buttons & (XINPUT_GAMEPAD_DPAD_UP | XINPUT_GAMEPAD_DPAD_DOWN | XINPUT_GAMEPAD_DPAD_LEFT | XINPUT_GAMEPAD_DPAD_RIGHT)) {
+                                       buttons &= ~(XINPUT_GAMEPAD_DPAD_UP | XINPUT_GAMEPAD_DPAD_DOWN | XINPUT_GAMEPAD_DPAD_LEFT | XINPUT_GAMEPAD_DPAD_RIGHT);
+                               }
+                       }
+
+                       int x = 0, y = 0;
+                       if (buttons & XINPUT_GAMEPAD_DPAD_UP) {
+                               y = -1;
+                               mousemove = 0;
+                       }
+                       if (buttons & XINPUT_GAMEPAD_DPAD_DOWN) {
+                               y = 1;
+                               mousemove = 0;
+                       }
+                       if (buttons & XINPUT_GAMEPAD_DPAD_LEFT) {
+                               x = -1;
+                               mousemove = 0;
+                       }
+                       if (buttons & XINPUT_GAMEPAD_DPAD_RIGHT) {
+                               x = 1;
+                               mousemove = 0;
+                       }
+
+                       if (mousemove && clicked[i] == 1 && clickchanged) {
+
+                               INPUT inputs[2] = { 0 };
+                               inputs[0].type = INPUT_MOUSE;
+                               inputs[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
+                               inputs[1].type = INPUT_MOUSE;
+                               inputs[1].mi.dwFlags = MOUSEEVENTF_LEFTUP;
+                               SendInput(sizeof(inputs) / sizeof(INPUT), inputs, sizeof(INPUT));
+
+                               lastbuttons[i] = newbuttons;
+
+                       } else if (mousemove && clicked[i] == 2 && clickchanged) {
+
+                               INPUT inputs[2] = { 0 };
+                               inputs[0].type = INPUT_MOUSE;
+                               inputs[0].mi.dwFlags = MOUSEEVENTF_RIGHTDOWN;
+                               inputs[1].type = INPUT_MOUSE;
+                               inputs[1].mi.dwFlags = MOUSEEVENTF_RIGHTUP;
+                               SendInput(sizeof(inputs) / sizeof(INPUT), inputs, sizeof(INPUT));
+
+                               lastbuttons[i] = newbuttons;
+
+                       } else if (mousemove && clicked[i] == 8 && clickchanged) {
+
+                               INPUT inputs[2] = { 0 };
+                               inputs[0].type = INPUT_KEYBOARD;
+                               inputs[0].ki.wVk = VK_TAB;
+                               inputs[1].type = INPUT_KEYBOARD;
+                               inputs[1].ki.wVk = VK_TAB;
+                               inputs[1].ki.dwFlags = KEYEVENTF_KEYUP;
+                               SendInput(sizeof(inputs) / sizeof(INPUT), inputs, sizeof(INPUT));
+
+                               lastbuttons[i] = newbuttons;
+
+                       } else {
+
+                               if (nres && h && (x || y || (clickchanged && clicked[i]))) {
+                                       gui_cursor(h, nres, x, y, clicked[i]);
+                               }
+                               lastbuttons[i] = newbuttons;
+
+                               int min = 4096;
+                               int max = 30;
+                               int xdiff = 0, ydiff = 0;
+                               if (xstate.Gamepad.sThumbLX < -min || xstate.Gamepad.sThumbLX > min) {
+                                       xdiff = abs(xstate.Gamepad.sThumbLX) - min;
+                                       if (xstate.Gamepad.sThumbLX < 0) {
+                                               xdiff = -xdiff;
+                                       }
+                               }
+                               if (xstate.Gamepad.sThumbLY < -min || xstate.Gamepad.sThumbLY > min) {
+                                       ydiff = abs(xstate.Gamepad.sThumbLY) - min;
+                                       if (xstate.Gamepad.sThumbLY < 0) {
+                                               ydiff = -ydiff;
+                                       }
+                               }
+                               if (xdiff || ydiff) {
+                                       xdiff /= 1024;
+                                       ydiff /= 1024;
+                                       if (xdiff < -max) {
+                                               xdiff = -max;
+                                       }
+                                       if (xdiff > max) {
+                                               xdiff = max;
+                                       }
+                                       if (ydiff < -max) {
+                                               ydiff = -max;
+                                       }
+                                       if (ydiff > max) {
+                                               ydiff = max;
+                                       }
+                                       POINT pt;
+                                       if ((xdiff || ydiff) && GetCursorPos(&pt)) {
+                                               POINT ptx = pt;
+                                               pt.x += xdiff;
+                                               pt.y += -ydiff;
+                                               if (h) {
+                                                       RECT r;
+                                                       WINDOWINFO wi = { 0 };
+                                                       wi.cbSize = sizeof(wi);
+                                                       GetWindowInfo(h, &wi);
+                                                       r = wi.rcClient;
+                                                       if (pt.x < r.left) {
+                                                               pt.x = r.left;
+                                                       }
+                                                       if (pt.x > r.right) {
+                                                               pt.x = r.right;
+                                                       }
+                                                       if (pt.y < r.top) {
+                                                               pt.y = r.top;
+                                                       }
+                                                       if (pt.y > r.bottom) {
+                                                               pt.y = r.bottom;
+                                                       }
+                                               }
+                                               if (ptx.x != pt.x || ptx.y != pt.y) {
+                                                       mousemove = 1;
+                                                       SetCursorPos(pt.x, pt.y);
+                                               }
+                                       }
+                               }
+                       }
+
+               }
+       }
+}
index c2a8abe15e4b8b7615385e14091cbf181d021f1e..5a7ae28fbe755b328ba277ab19dd03820c308902 100644 (file)
       <Culture>0x0409</Culture>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;winio.lib;setupapi.lib;wininet.lib;shlwapi.lib;libpng16.lib;lglcd.lib;openal32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;enet.lib;lzmalib.lib;prowizard.lib;libFLAC_static.lib;hid.lib;zlibstat.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;Dwmapi.lib;mt32emu.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;winio.lib;setupapi.lib;wininet.lib;shlwapi.lib;libpng16.lib;lglcd.lib;openal32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;enet.lib;lzmalib.lib;prowizard.lib;libFLAC_static.lib;hid.lib;zlibstat.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;Dwmapi.lib;mt32emu.lib;XINPUT9_1_0.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories);$(SolutionDir)\..\lib\</AdditionalLibraryDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;winio.lib;setupapi.lib;wininet.lib;shlwapi.lib;libpng16.lib;lglcd.lib;openal32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;enet.lib;lzmalib.lib;prowizard.lib;libFLAC_static.lib;hid.lib;zlibstat.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;Dwmapi.lib;mt32emu.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;winio.lib;setupapi.lib;wininet.lib;shlwapi.lib;libpng16.lib;lglcd.lib;openal32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;enet.lib;lzmalib.lib;prowizard.lib;libFLAC_static.lib;hid.lib;zlibstat.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;Dwmapi.lib;mt32emu.lib;XINPUT9_1_0.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories);$(SolutionDir)\..\lib\</AdditionalLibraryDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;winio.lib;setupapi.lib;wininet.lib;shlwapi.lib;libpng16.lib;lglcd.lib;openal32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;enet.lib;lzmalib.lib;prowizard.lib;libFLAC_static.lib;hid.lib;zlibstat.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;Dwmapi.lib;mt32emu.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;winio.lib;setupapi.lib;wininet.lib;shlwapi.lib;libpng16.lib;lglcd.lib;openal32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;enet.lib;lzmalib.lib;prowizard.lib;libFLAC_static.lib;hid.lib;zlibstat.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;Dwmapi.lib;mt32emu.lib;XINPUT9_1_0.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories);$(SolutionDir)\..\lib\</AdditionalLibraryDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;openal32.lib;libpng16.lib;lglcd.lib;wtsapi32.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;hid.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;Dwmapi.lib;mt32emu.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;openal32.lib;libpng16.lib;lglcd.lib;wtsapi32.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;hid.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;Dwmapi.lib;mt32emu.lib;XINPUT9_1_0.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <ShowProgress>NotSet</ShowProgress>
       <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <Culture>0x0409</Culture>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;openal32.lib;libpng16.lib;lglcd.lib;wtsapi32.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;hid.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;Dwmapi.lib;mt32emu.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;openal32.lib;libpng16.lib;lglcd.lib;wtsapi32.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;hid.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;Dwmapi.lib;mt32emu.lib;XINPUT9_1_0.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <ShowProgress>NotSet</ShowProgress>
       <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <Culture>0x0409</Culture>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;openal32.lib;libpng16.lib;lglcd.lib;wtsapi32.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;hid.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;Dwmapi.lib;mt32emu.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;openal32.lib;libpng16.lib;lglcd.lib;wtsapi32.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;hid.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;Dwmapi.lib;mt32emu.lib;XINPUT9_1_0.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <ShowProgress>NotSet</ShowProgress>
       <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <Culture>0x0409</Culture>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;winio.lib;setupapi.lib;wininet.lib;shlwapi.lib;libpng16.lib;lglcd.lib;openal32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;enet.lib;lzmalib.lib;prowizard.lib;libFLAC_static.lib;hid.lib;zlibstat.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;Dwmapi.lib;mt32emu.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;winio.lib;setupapi.lib;wininet.lib;shlwapi.lib;libpng16.lib;lglcd.lib;openal32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;enet.lib;lzmalib.lib;prowizard.lib;libFLAC_static.lib;hid.lib;zlibstat.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;Dwmapi.lib;mt32emu.lib;XINPUT9_1_0.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories);$(SolutionDir)\..\lib\</AdditionalLibraryDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;openal32.lib;libpng16.lib;lglcd.lib;wtsapi32.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;hid.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;Dwmapi.lib;mt32emu.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;openal32.lib;libpng16.lib;lglcd.lib;wtsapi32.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;hid.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;Dwmapi.lib;mt32emu.lib;XINPUT9_1_0.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <ShowProgress>NotSet</ShowProgress>
       <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
       <SuppressStartupBanner>true</SuppressStartupBanner>