mirror of
https://github.com/86Box/86Box.git
synced 2026-02-25 21:43:16 -07:00
clang-format in src/win and other misc places
This commit is contained in:
1598
src/win/glad.c
1598
src/win/glad.c
File diff suppressed because it is too large
Load Diff
907
src/win/win.c
907
src/win/win.c
File diff suppressed because it is too large
Load Diff
@@ -32,15 +32,14 @@
|
||||
#include <86box/win.h>
|
||||
#include <86box/version.h>
|
||||
|
||||
|
||||
void
|
||||
AboutDialogCreate(HWND hwnd)
|
||||
{
|
||||
int i;
|
||||
TASKDIALOGCONFIG tdconfig = {0};
|
||||
int i;
|
||||
TASKDIALOGCONFIG tdconfig = { 0 };
|
||||
TASKDIALOG_BUTTON tdbuttons[] = {
|
||||
{IDOK, EMU_SITE_W},
|
||||
{IDCANCEL, MAKEINTRESOURCE(IDS_2127)}
|
||||
{IDOK, EMU_SITE_W },
|
||||
{ IDCANCEL, MAKEINTRESOURCE(IDS_2127)}
|
||||
};
|
||||
|
||||
wchar_t emu_version[256];
|
||||
@@ -49,19 +48,19 @@ AboutDialogCreate(HWND hwnd)
|
||||
swprintf(&emu_version[i], sizeof(emu_version) - i, L" [%ls]", EMU_GIT_HASH_W);
|
||||
#endif
|
||||
|
||||
tdconfig.cbSize = sizeof(tdconfig);
|
||||
tdconfig.hwndParent = hwnd;
|
||||
tdconfig.hInstance = hinstance;
|
||||
tdconfig.dwCommonButtons = 0;
|
||||
tdconfig.pszWindowTitle = MAKEINTRESOURCE(IDS_2124);
|
||||
tdconfig.pszMainIcon = (PCWSTR) 10;
|
||||
tdconfig.cbSize = sizeof(tdconfig);
|
||||
tdconfig.hwndParent = hwnd;
|
||||
tdconfig.hInstance = hinstance;
|
||||
tdconfig.dwCommonButtons = 0;
|
||||
tdconfig.pszWindowTitle = MAKEINTRESOURCE(IDS_2124);
|
||||
tdconfig.pszMainIcon = (PCWSTR) 10;
|
||||
tdconfig.pszMainInstruction = emu_version;
|
||||
tdconfig.pszContent = MAKEINTRESOURCE(IDS_2126);
|
||||
tdconfig.cButtons = ARRAYSIZE(tdbuttons);
|
||||
tdconfig.pButtons = tdbuttons;
|
||||
tdconfig.nDefaultButton = IDCANCEL;
|
||||
tdconfig.pszContent = MAKEINTRESOURCE(IDS_2126);
|
||||
tdconfig.cButtons = ARRAYSIZE(tdbuttons);
|
||||
tdconfig.pButtons = tdbuttons;
|
||||
tdconfig.nDefaultButton = IDCANCEL;
|
||||
TaskDialogIndirect(&tdconfig, &i, NULL, NULL);
|
||||
|
||||
if (i == IDOK)
|
||||
ShellExecute(hwnd, L"open", L"https://" EMU_SITE_W, NULL, NULL, SW_SHOW);
|
||||
ShellExecute(hwnd, L"open", L"https://" EMU_SITE_W, NULL, NULL, SW_SHOW);
|
||||
}
|
||||
|
||||
@@ -44,7 +44,6 @@
|
||||
#include <86box/ui.h>
|
||||
#include <86box/win.h>
|
||||
|
||||
|
||||
void
|
||||
cassette_mount(char *fn, uint8_t wp)
|
||||
{
|
||||
@@ -53,14 +52,13 @@ cassette_mount(char *fn, uint8_t wp)
|
||||
cassette_ui_writeprot = wp;
|
||||
pc_cas_set_fname(cassette, fn);
|
||||
if (fn != NULL)
|
||||
memcpy(cassette_fname, fn, MIN(511, strlen(fn)));
|
||||
memcpy(cassette_fname, fn, MIN(511, strlen(fn)));
|
||||
ui_sb_update_icon_state(SB_CASSETTE, (fn == NULL) ? 1 : 0);
|
||||
media_menu_update_cassette();
|
||||
ui_sb_update_tip(SB_CASSETTE);
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cassette_eject(void)
|
||||
{
|
||||
@@ -72,7 +70,6 @@ cassette_eject(void)
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cartridge_mount(uint8_t id, char *fn, uint8_t wp)
|
||||
{
|
||||
@@ -84,7 +81,6 @@ cartridge_mount(uint8_t id, char *fn, uint8_t wp)
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cartridge_eject(uint8_t id)
|
||||
{
|
||||
@@ -95,7 +91,6 @@ cartridge_eject(uint8_t id)
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
floppy_mount(uint8_t id, char *fn, uint8_t wp)
|
||||
{
|
||||
@@ -108,7 +103,6 @@ floppy_mount(uint8_t id, char *fn, uint8_t wp)
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
floppy_eject(uint8_t id)
|
||||
{
|
||||
@@ -119,20 +113,19 @@ floppy_eject(uint8_t id)
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
plat_cdrom_ui_update(uint8_t id, uint8_t reload)
|
||||
{
|
||||
cdrom_t *drv = &cdrom[id];
|
||||
|
||||
if (drv->host_drive == 0) {
|
||||
ui_sb_update_icon_state(SB_CDROM|id, 1);
|
||||
ui_sb_update_icon_state(SB_CDROM | id, 1);
|
||||
} else {
|
||||
ui_sb_update_icon_state(SB_CDROM|id, 0);
|
||||
ui_sb_update_icon_state(SB_CDROM | id, 0);
|
||||
}
|
||||
|
||||
media_menu_update_cdrom(id);
|
||||
ui_sb_update_tip(SB_CDROM|id);
|
||||
ui_sb_update_tip(SB_CDROM | id);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -141,18 +134,18 @@ cdrom_mount(uint8_t id, char *fn)
|
||||
cdrom[id].prev_host_drive = cdrom[id].host_drive;
|
||||
strcpy(cdrom[id].prev_image_path, cdrom[id].image_path);
|
||||
if (cdrom[id].ops && cdrom[id].ops->exit)
|
||||
cdrom[id].ops->exit(&(cdrom[id]));
|
||||
cdrom[id].ops->exit(&(cdrom[id]));
|
||||
cdrom[id].ops = NULL;
|
||||
memset(cdrom[id].image_path, 0, sizeof(cdrom[id].image_path));
|
||||
cdrom_image_open(&(cdrom[id]), fn);
|
||||
/* Signal media change to the emulated machine. */
|
||||
if (cdrom[id].insert)
|
||||
cdrom[id].insert(cdrom[id].priv);
|
||||
cdrom[id].insert(cdrom[id].priv);
|
||||
cdrom[id].host_drive = (strlen(cdrom[id].image_path) == 0) ? 0 : 200;
|
||||
if (cdrom[id].host_drive == 200) {
|
||||
ui_sb_update_icon_state(SB_CDROM | id, 0);
|
||||
ui_sb_update_icon_state(SB_CDROM | id, 0);
|
||||
} else {
|
||||
ui_sb_update_icon_state(SB_CDROM | id, 1);
|
||||
ui_sb_update_icon_state(SB_CDROM | id, 1);
|
||||
}
|
||||
media_menu_update_cdrom(id);
|
||||
ui_sb_update_tip(SB_CDROM | id);
|
||||
@@ -166,8 +159,8 @@ mo_eject(uint8_t id)
|
||||
|
||||
mo_disk_close(dev);
|
||||
if (mo_drives[id].bus_type) {
|
||||
/* Signal disk change to the emulated machine. */
|
||||
mo_insert(dev);
|
||||
/* Signal disk change to the emulated machine. */
|
||||
mo_insert(dev);
|
||||
}
|
||||
|
||||
ui_sb_update_icon_state(SB_MO | id, 1);
|
||||
@@ -176,7 +169,6 @@ mo_eject(uint8_t id)
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mo_mount(uint8_t id, char *fn, uint8_t wp)
|
||||
{
|
||||
@@ -194,7 +186,6 @@ mo_mount(uint8_t id, char *fn, uint8_t wp)
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mo_reload(uint8_t id)
|
||||
{
|
||||
@@ -202,13 +193,13 @@ mo_reload(uint8_t id)
|
||||
|
||||
mo_disk_reload(dev);
|
||||
if (strlen(mo_drives[id].image_path) == 0) {
|
||||
ui_sb_update_icon_state(SB_MO|id, 1);
|
||||
ui_sb_update_icon_state(SB_MO | id, 1);
|
||||
} else {
|
||||
ui_sb_update_icon_state(SB_MO|id, 0);
|
||||
ui_sb_update_icon_state(SB_MO | id, 0);
|
||||
}
|
||||
|
||||
media_menu_update_mo(id);
|
||||
ui_sb_update_tip(SB_MO|id);
|
||||
ui_sb_update_tip(SB_MO | id);
|
||||
|
||||
config_save();
|
||||
}
|
||||
@@ -220,8 +211,8 @@ zip_eject(uint8_t id)
|
||||
|
||||
zip_disk_close(dev);
|
||||
if (zip_drives[id].bus_type) {
|
||||
/* Signal disk change to the emulated machine. */
|
||||
zip_insert(dev);
|
||||
/* Signal disk change to the emulated machine. */
|
||||
zip_insert(dev);
|
||||
}
|
||||
|
||||
ui_sb_update_icon_state(SB_ZIP | id, 1);
|
||||
@@ -230,7 +221,6 @@ zip_eject(uint8_t id)
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
zip_mount(uint8_t id, char *fn, uint8_t wp)
|
||||
{
|
||||
@@ -248,7 +238,6 @@ zip_mount(uint8_t id, char *fn, uint8_t wp)
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
zip_reload(uint8_t id)
|
||||
{
|
||||
@@ -256,13 +245,13 @@ zip_reload(uint8_t id)
|
||||
|
||||
zip_disk_reload(dev);
|
||||
if (strlen(zip_drives[id].image_path) == 0) {
|
||||
ui_sb_update_icon_state(SB_ZIP|id, 1);
|
||||
ui_sb_update_icon_state(SB_ZIP | id, 1);
|
||||
} else {
|
||||
ui_sb_update_icon_state(SB_ZIP|id, 0);
|
||||
ui_sb_update_icon_state(SB_ZIP | id, 0);
|
||||
}
|
||||
|
||||
media_menu_update_zip(id);
|
||||
ui_sb_update_tip(SB_ZIP|id);
|
||||
ui_sb_update_tip(SB_ZIP | id);
|
||||
|
||||
config_save();
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -33,15 +33,11 @@
|
||||
#include <86box/ui.h>
|
||||
#include <86box/win.h>
|
||||
|
||||
#define STRING_OR_RESOURCE(s) ((!(s)) ? (NULL) : ((((uintptr_t) s) < ((uintptr_t) 65636)) ? (MAKEINTRESOURCE((uintptr_t) s)) : (s)))
|
||||
|
||||
|
||||
#define STRING_OR_RESOURCE(s) ((!(s)) ? (NULL) : ((((uintptr_t)s) < ((uintptr_t)65636)) ? (MAKEINTRESOURCE((uintptr_t)s)) : (s)))
|
||||
|
||||
|
||||
WCHAR wopenfilestring[512];
|
||||
char openfilestring[512];
|
||||
uint8_t filterindex = 0;
|
||||
|
||||
WCHAR wopenfilestring[512];
|
||||
char openfilestring[512];
|
||||
uint8_t filterindex = 0;
|
||||
|
||||
int
|
||||
ui_msgbox(int flags, void *message)
|
||||
@@ -49,125 +45,127 @@ ui_msgbox(int flags, void *message)
|
||||
return ui_msgbox_ex(flags, NULL, message, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ui_msgbox_header(int flags, void *header, void *message)
|
||||
{
|
||||
return ui_msgbox_ex(flags, header, message, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ui_msgbox_ex(int flags, void *header, void *message, void *btn1, void *btn2, void *btn3) {
|
||||
WCHAR temp[512];
|
||||
TASKDIALOGCONFIG tdconfig = {0};
|
||||
ui_msgbox_ex(int flags, void *header, void *message, void *btn1, void *btn2, void *btn3)
|
||||
{
|
||||
WCHAR temp[512];
|
||||
TASKDIALOGCONFIG tdconfig = { 0 };
|
||||
TASKDIALOG_BUTTON tdbuttons[3],
|
||||
tdb_yes = {IDYES, STRING_OR_RESOURCE(btn1)},
|
||||
tdb_no = {IDNO, STRING_OR_RESOURCE(btn2)},
|
||||
tdb_cancel = {IDCANCEL, STRING_OR_RESOURCE(btn3)},
|
||||
tdb_exit = {IDCLOSE, MAKEINTRESOURCE(IDS_2119)};
|
||||
tdb_yes = { IDYES, STRING_OR_RESOURCE(btn1) },
|
||||
tdb_no = { IDNO, STRING_OR_RESOURCE(btn2) },
|
||||
tdb_cancel = { IDCANCEL, STRING_OR_RESOURCE(btn3) },
|
||||
tdb_exit = { IDCLOSE, MAKEINTRESOURCE(IDS_2119) };
|
||||
int ret = 0, checked = 0;
|
||||
|
||||
/* Configure the default OK button. */
|
||||
tdconfig.cButtons = 0;
|
||||
if (btn1)
|
||||
tdbuttons[tdconfig.cButtons++] = tdb_yes;
|
||||
tdbuttons[tdconfig.cButtons++] = tdb_yes;
|
||||
else
|
||||
tdconfig.dwCommonButtons = TDCBF_OK_BUTTON;
|
||||
tdconfig.dwCommonButtons = TDCBF_OK_BUTTON;
|
||||
|
||||
/* Configure the message type. */
|
||||
switch(flags & 0x1f) {
|
||||
case MBX_INFO: /* just an informational message */
|
||||
tdconfig.pszMainIcon = TD_INFORMATION_ICON;
|
||||
break;
|
||||
switch (flags & 0x1f) {
|
||||
case MBX_INFO: /* just an informational message */
|
||||
tdconfig.pszMainIcon = TD_INFORMATION_ICON;
|
||||
break;
|
||||
|
||||
case MBX_ERROR: /* error message */
|
||||
if (flags & MBX_FATAL) {
|
||||
tdconfig.pszMainIcon = TD_ERROR_ICON;
|
||||
tdconfig.pszMainInstruction = MAKEINTRESOURCE(IDS_2050); /* "Fatal error" */
|
||||
case MBX_ERROR: /* error message */
|
||||
if (flags & MBX_FATAL) {
|
||||
tdconfig.pszMainIcon = TD_ERROR_ICON;
|
||||
tdconfig.pszMainInstruction = MAKEINTRESOURCE(IDS_2050); /* "Fatal error" */
|
||||
|
||||
/* replace default "OK" button with "Exit" button */
|
||||
if (btn1)
|
||||
tdconfig.cButtons = 0;
|
||||
else
|
||||
tdconfig.dwCommonButtons = 0;
|
||||
tdbuttons[tdconfig.cButtons++] = tdb_exit;
|
||||
} else {
|
||||
tdconfig.pszMainIcon = TD_WARNING_ICON;
|
||||
tdconfig.pszMainInstruction = MAKEINTRESOURCE(IDS_2049); /* "Error" */
|
||||
}
|
||||
break;
|
||||
/* replace default "OK" button with "Exit" button */
|
||||
if (btn1)
|
||||
tdconfig.cButtons = 0;
|
||||
else
|
||||
tdconfig.dwCommonButtons = 0;
|
||||
tdbuttons[tdconfig.cButtons++] = tdb_exit;
|
||||
} else {
|
||||
tdconfig.pszMainIcon = TD_WARNING_ICON;
|
||||
tdconfig.pszMainInstruction = MAKEINTRESOURCE(IDS_2049); /* "Error" */
|
||||
}
|
||||
break;
|
||||
|
||||
case MBX_QUESTION: /* question */
|
||||
case MBX_QUESTION_YN:
|
||||
case MBX_QUESTION_OK:
|
||||
if (!btn1) /* replace default "OK" button with "Yes" button */
|
||||
tdconfig.dwCommonButtons = (flags & MBX_QUESTION_OK) ? TDCBF_OK_BUTTON : TDCBF_YES_BUTTON;
|
||||
case MBX_QUESTION: /* question */
|
||||
case MBX_QUESTION_YN:
|
||||
case MBX_QUESTION_OK:
|
||||
if (!btn1) /* replace default "OK" button with "Yes" button */
|
||||
tdconfig.dwCommonButtons = (flags & MBX_QUESTION_OK) ? TDCBF_OK_BUTTON : TDCBF_YES_BUTTON;
|
||||
|
||||
if (btn2) /* "No" button */
|
||||
tdbuttons[tdconfig.cButtons++] = tdb_no;
|
||||
else
|
||||
tdconfig.dwCommonButtons |= (flags & MBX_QUESTION_OK) ? TDCBF_CANCEL_BUTTON : TDCBF_NO_BUTTON;
|
||||
if (btn2) /* "No" button */
|
||||
tdbuttons[tdconfig.cButtons++] = tdb_no;
|
||||
else
|
||||
tdconfig.dwCommonButtons |= (flags & MBX_QUESTION_OK) ? TDCBF_CANCEL_BUTTON : TDCBF_NO_BUTTON;
|
||||
|
||||
if (flags & MBX_QUESTION) {
|
||||
if (btn3) /* "Cancel" button */
|
||||
tdbuttons[tdconfig.cButtons++] = tdb_cancel;
|
||||
else
|
||||
tdconfig.dwCommonButtons |= TDCBF_CANCEL_BUTTON;
|
||||
}
|
||||
if (flags & MBX_QUESTION) {
|
||||
if (btn3) /* "Cancel" button */
|
||||
tdbuttons[tdconfig.cButtons++] = tdb_cancel;
|
||||
else
|
||||
tdconfig.dwCommonButtons |= TDCBF_CANCEL_BUTTON;
|
||||
}
|
||||
|
||||
if (flags & MBX_WARNING)
|
||||
tdconfig.pszMainIcon = TD_WARNING_ICON;
|
||||
break;
|
||||
if (flags & MBX_WARNING)
|
||||
tdconfig.pszMainIcon = TD_WARNING_ICON;
|
||||
break;
|
||||
}
|
||||
|
||||
/* If the message is an ANSI string, convert it. */
|
||||
tdconfig.pszContent = (WCHAR *) STRING_OR_RESOURCE(message);
|
||||
if (flags & MBX_ANSI) {
|
||||
mbstoc16s(temp, (char *)message, strlen((char *)message)+1);
|
||||
tdconfig.pszContent = temp;
|
||||
mbstoc16s(temp, (char *) message, strlen((char *) message) + 1);
|
||||
tdconfig.pszContent = temp;
|
||||
}
|
||||
|
||||
/* Configure the rest of the TaskDialog. */
|
||||
tdconfig.cbSize = sizeof(tdconfig);
|
||||
tdconfig.cbSize = sizeof(tdconfig);
|
||||
tdconfig.hwndParent = hwndMain;
|
||||
if (flags & MBX_LINKS)
|
||||
tdconfig.dwFlags = TDF_USE_COMMAND_LINKS;
|
||||
tdconfig.dwFlags = TDF_USE_COMMAND_LINKS;
|
||||
tdconfig.pszWindowTitle = MAKEINTRESOURCE(IDS_STRINGS);
|
||||
if (header)
|
||||
tdconfig.pszMainInstruction = STRING_OR_RESOURCE(header);
|
||||
tdconfig.pszMainInstruction = STRING_OR_RESOURCE(header);
|
||||
tdconfig.pButtons = tdbuttons;
|
||||
if (flags & MBX_DONTASK)
|
||||
tdconfig.pszVerificationText = MAKEINTRESOURCE(IDS_2135);
|
||||
tdconfig.pszVerificationText = MAKEINTRESOURCE(IDS_2135);
|
||||
|
||||
/* Run the TaskDialog. */
|
||||
TaskDialogIndirect(&tdconfig, &ret, NULL, &checked);
|
||||
|
||||
/* Convert return values to generic ones. */
|
||||
if (ret == IDNO) ret = 1;
|
||||
else if (ret == IDCANCEL) ret = -1;
|
||||
else ret = 0;
|
||||
if (ret == IDNO)
|
||||
ret = 1;
|
||||
else if (ret == IDCANCEL)
|
||||
ret = -1;
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
/* 10 is added to the return value if "don't show again" is checked. */
|
||||
if (checked) ret += 10;
|
||||
if (checked)
|
||||
ret += 10;
|
||||
|
||||
return(ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
file_dlg_w(HWND hwnd, WCHAR *f, WCHAR *fn, WCHAR *title, int save)
|
||||
{
|
||||
OPENFILENAME ofn;
|
||||
BOOL r;
|
||||
BOOL r;
|
||||
/* DWORD err; */
|
||||
int old_dopause;
|
||||
|
||||
/* Initialize OPENFILENAME */
|
||||
ZeroMemory(&ofn, sizeof(ofn));
|
||||
ofn.lStructSize = sizeof(ofn);
|
||||
ofn.hwndOwner = hwnd;
|
||||
ofn.lpstrFile = wopenfilestring;
|
||||
ofn.hwndOwner = hwnd;
|
||||
ofn.lpstrFile = wopenfilestring;
|
||||
|
||||
/*
|
||||
* Set lpstrFile[0] to '\0' so that GetOpenFileName does
|
||||
@@ -175,40 +173,39 @@ file_dlg_w(HWND hwnd, WCHAR *f, WCHAR *fn, WCHAR *title, int save)
|
||||
*/
|
||||
memset(ofn.lpstrFile, 0x00, 512 * sizeof(WCHAR));
|
||||
memcpy(ofn.lpstrFile, fn, (wcslen(fn) << 1) + 2);
|
||||
ofn.nMaxFile = sizeof_w(wopenfilestring);
|
||||
ofn.lpstrFilter = f;
|
||||
ofn.nFilterIndex = 1;
|
||||
ofn.lpstrFileTitle = NULL;
|
||||
ofn.nMaxFileTitle = 0;
|
||||
ofn.nMaxFile = sizeof_w(wopenfilestring);
|
||||
ofn.lpstrFilter = f;
|
||||
ofn.nFilterIndex = 1;
|
||||
ofn.lpstrFileTitle = NULL;
|
||||
ofn.nMaxFileTitle = 0;
|
||||
ofn.lpstrInitialDir = NULL;
|
||||
ofn.Flags = OFN_PATHMUSTEXIST;
|
||||
if (! save)
|
||||
ofn.Flags |= OFN_FILEMUSTEXIST;
|
||||
ofn.Flags = OFN_PATHMUSTEXIST;
|
||||
if (!save)
|
||||
ofn.Flags |= OFN_FILEMUSTEXIST;
|
||||
if (title)
|
||||
ofn.lpstrTitle = title;
|
||||
ofn.lpstrTitle = title;
|
||||
|
||||
/* Display the Open dialog box. */
|
||||
old_dopause = dopause;
|
||||
plat_pause(1);
|
||||
if (save)
|
||||
r = GetSaveFileName(&ofn);
|
||||
r = GetSaveFileName(&ofn);
|
||||
else
|
||||
r = GetOpenFileName(&ofn);
|
||||
r = GetOpenFileName(&ofn);
|
||||
plat_pause(old_dopause);
|
||||
|
||||
plat_chdir(usr_path);
|
||||
|
||||
if (r) {
|
||||
c16stombs(openfilestring, wopenfilestring, sizeof(openfilestring));
|
||||
filterindex = ofn.nFilterIndex;
|
||||
c16stombs(openfilestring, wopenfilestring, sizeof(openfilestring));
|
||||
filterindex = ofn.nFilterIndex;
|
||||
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
return(1);
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
file_dlg(HWND hwnd, WCHAR *f, char *fn, char *title, int save)
|
||||
{
|
||||
@@ -218,10 +215,9 @@ file_dlg(HWND hwnd, WCHAR *f, char *fn, char *title, int save)
|
||||
if (title)
|
||||
mbstoc16s(title_buf, title, sizeof title_buf);
|
||||
|
||||
return(file_dlg_w(hwnd, f, ufn, title ? title_buf : NULL, save));
|
||||
return (file_dlg_w(hwnd, f, ufn, title ? title_buf : NULL, save));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
file_dlg_mb(HWND hwnd, char *f, char *fn, char *title, int save)
|
||||
{
|
||||
@@ -232,22 +228,20 @@ file_dlg_mb(HWND hwnd, char *f, char *fn, char *title, int save)
|
||||
if (title)
|
||||
mbstoc16s(title_buf, title, sizeof title_buf);
|
||||
|
||||
return(file_dlg_w(hwnd, uf, ufn, title ? title_buf : NULL, save));
|
||||
return (file_dlg_w(hwnd, uf, ufn, title ? title_buf : NULL, save));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
file_dlg_w_st(HWND hwnd, int id, WCHAR *fn, char *title, int save)
|
||||
{
|
||||
WCHAR title_buf[512];
|
||||
if (title)
|
||||
mbstoc16s(title_buf, title, sizeof title_buf);
|
||||
return(file_dlg_w(hwnd, plat_get_string(id), fn, title ? title_buf : NULL, save));
|
||||
return (file_dlg_w(hwnd, plat_get_string(id), fn, title ? title_buf : NULL, save));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
file_dlg_st(HWND hwnd, int id, char *fn, char *title, int save)
|
||||
{
|
||||
return(file_dlg(hwnd, plat_get_string(id), fn, title, save));
|
||||
return (file_dlg(hwnd, plat_get_string(id), fn, title, save));
|
||||
}
|
||||
|
||||
@@ -25,63 +25,59 @@
|
||||
#include <86box/86box.h>
|
||||
#include <86box/plat_dynld.h>
|
||||
|
||||
|
||||
#ifdef ENABLE_DYNLD_LOG
|
||||
int dynld_do_log = ENABLE_DYNLD_LOG;
|
||||
|
||||
|
||||
static void
|
||||
dynld_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (dynld_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define dynld_log(fmt, ...)
|
||||
# define dynld_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
void *
|
||||
dynld_module(const char *name, dllimp_t *table)
|
||||
{
|
||||
HMODULE h;
|
||||
HMODULE h;
|
||||
dllimp_t *imp;
|
||||
void *func;
|
||||
void *func;
|
||||
|
||||
/* See if we can load the desired module. */
|
||||
if ((h = LoadLibrary(name)) == NULL) {
|
||||
dynld_log("DynLd(\"%s\"): library not found! (%08X)\n", name, GetLastError());
|
||||
return(NULL);
|
||||
dynld_log("DynLd(\"%s\"): library not found! (%08X)\n", name, GetLastError());
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Now load the desired function pointers. */
|
||||
for (imp=table; imp->name!=NULL; imp++) {
|
||||
func = GetProcAddress(h, imp->name);
|
||||
if (func == NULL) {
|
||||
dynld_log("DynLd(\"%s\"): function '%s' not found! (%08X)\n",
|
||||
name, imp->name, GetLastError());
|
||||
FreeLibrary(h);
|
||||
return(NULL);
|
||||
}
|
||||
for (imp = table; imp->name != NULL; imp++) {
|
||||
func = GetProcAddress(h, imp->name);
|
||||
if (func == NULL) {
|
||||
dynld_log("DynLd(\"%s\"): function '%s' not found! (%08X)\n",
|
||||
name, imp->name, GetLastError());
|
||||
FreeLibrary(h);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* To overcome typing issues.. */
|
||||
*(char **)imp->func = (char *)func;
|
||||
/* To overcome typing issues.. */
|
||||
*(char **) imp->func = (char *) func;
|
||||
}
|
||||
|
||||
/* All good. */
|
||||
dynld_log("loaded %s\n", name);
|
||||
return((void *)h);
|
||||
return ((void *) h);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dynld_close(void *handle)
|
||||
{
|
||||
if (handle != NULL)
|
||||
FreeLibrary((HMODULE)handle);
|
||||
FreeLibrary((HMODULE) handle);
|
||||
}
|
||||
|
||||
@@ -28,138 +28,138 @@
|
||||
#include <86box/ui.h>
|
||||
#include <86box/win.h>
|
||||
|
||||
HICON hIcon[256]; /* icon data loaded from resources */
|
||||
char icon_set[256] = ""; /* name of the iconset to be used */
|
||||
HICON hIcon[256]; /* icon data loaded from resources */
|
||||
char icon_set[256] = ""; /* name of the iconset to be used */
|
||||
|
||||
void win_clear_icon_set()
|
||||
void
|
||||
win_clear_icon_set()
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
if (hIcon[i] != 0)
|
||||
{
|
||||
DestroyIcon(hIcon[i]);
|
||||
hIcon[i] = 0;
|
||||
}
|
||||
for (i = 0; i < 256; i++)
|
||||
if (hIcon[i] != 0) {
|
||||
DestroyIcon(hIcon[i]);
|
||||
hIcon[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void win_system_icon_set()
|
||||
void
|
||||
win_system_icon_set()
|
||||
{
|
||||
int i, x = win_get_system_metrics(SM_CXSMICON, dpi), y = win_get_system_metrics(SM_CYSMICON, dpi);
|
||||
int i, x = win_get_system_metrics(SM_CXSMICON, dpi), y = win_get_system_metrics(SM_CYSMICON, dpi);
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
hIcon[i] = LoadImage(hinstance, MAKEINTRESOURCE(i), IMAGE_ICON, x, y, LR_DEFAULTCOLOR);
|
||||
for (i = 0; i < 256; i++)
|
||||
hIcon[i] = LoadImage(hinstance, MAKEINTRESOURCE(i), IMAGE_ICON, x, y, LR_DEFAULTCOLOR);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int id;
|
||||
char* filename;
|
||||
int id;
|
||||
char *filename;
|
||||
} _ICON_DATA;
|
||||
|
||||
const _ICON_DATA icon_files[] =
|
||||
{
|
||||
{16, "floppy_525.ico"},
|
||||
{17, "floppy_525_active.ico"},
|
||||
{24, "floppy_35.ico"},
|
||||
{25, "floppy_35_active.ico"},
|
||||
{32, "cdrom.ico"},
|
||||
{33, "cdrom_active.ico"},
|
||||
{48, "zip.ico"},
|
||||
{49, "zip_active.ico"},
|
||||
{56, "mo.ico"},
|
||||
{57, "mo_active.ico"},
|
||||
{64, "cassette.ico"},
|
||||
{65, "cassette_active.ico"},
|
||||
{80, "hard_disk.ico"},
|
||||
{81, "hard_disk_active.ico"},
|
||||
{96, "network.ico"},
|
||||
{97, "network_active.ico"},
|
||||
{104, "cartridge.ico"},
|
||||
{144, "floppy_525_empty.ico"},
|
||||
{145, "floppy_525_empty_active.ico"},
|
||||
{152, "floppy_35_empty.ico"},
|
||||
{153, "floppy_35_empty_active.ico"},
|
||||
{160, "cdrom_empty.ico"},
|
||||
{161, "cdrom_empty_active.ico"},
|
||||
{176, "zip_empty.ico"},
|
||||
{177, "zip_empty_active.ico"},
|
||||
{184, "mo_empty.ico"},
|
||||
{185, "mo_empty_active.ico"},
|
||||
{192, "cassette_empty.ico"},
|
||||
{193, "cassette_empty_active.ico"},
|
||||
{200, "run.ico"},
|
||||
{201, "pause.ico"},
|
||||
{202, "send_cad.ico"},
|
||||
{203, "send_cae.ico"},
|
||||
{204, "hard_reset.ico"},
|
||||
{205, "acpi_shutdown.ico"},
|
||||
{206, "settings.ico"},
|
||||
{232, "cartridge_empty.ico"},
|
||||
{240, "machine.ico"},
|
||||
{241, "display.ico"},
|
||||
{242, "input_devices.ico"},
|
||||
{243, "sound.ico"},
|
||||
{244, "ports.ico"},
|
||||
{245, "other_peripherals.ico"},
|
||||
{246, "floppy_and_cdrom_drives.ico"},
|
||||
{247, "other_removable_devices.ico"},
|
||||
{248, "floppy_disabled.ico"},
|
||||
{249, "cdrom_disabled.ico"},
|
||||
{250, "zip_disabled.ico"},
|
||||
{251, "mo_disabled.ico"},
|
||||
{252, "storage_controllers.ico"}
|
||||
};
|
||||
const _ICON_DATA icon_files[] = {
|
||||
{16, "floppy_525.ico" },
|
||||
{ 17, "floppy_525_active.ico" },
|
||||
{ 24, "floppy_35.ico" },
|
||||
{ 25, "floppy_35_active.ico" },
|
||||
{ 32, "cdrom.ico" },
|
||||
{ 33, "cdrom_active.ico" },
|
||||
{ 48, "zip.ico" },
|
||||
{ 49, "zip_active.ico" },
|
||||
{ 56, "mo.ico" },
|
||||
{ 57, "mo_active.ico" },
|
||||
{ 64, "cassette.ico" },
|
||||
{ 65, "cassette_active.ico" },
|
||||
{ 80, "hard_disk.ico" },
|
||||
{ 81, "hard_disk_active.ico" },
|
||||
{ 96, "network.ico" },
|
||||
{ 97, "network_active.ico" },
|
||||
{ 104, "cartridge.ico" },
|
||||
{ 144, "floppy_525_empty.ico" },
|
||||
{ 145, "floppy_525_empty_active.ico"},
|
||||
{ 152, "floppy_35_empty.ico" },
|
||||
{ 153, "floppy_35_empty_active.ico" },
|
||||
{ 160, "cdrom_empty.ico" },
|
||||
{ 161, "cdrom_empty_active.ico" },
|
||||
{ 176, "zip_empty.ico" },
|
||||
{ 177, "zip_empty_active.ico" },
|
||||
{ 184, "mo_empty.ico" },
|
||||
{ 185, "mo_empty_active.ico" },
|
||||
{ 192, "cassette_empty.ico" },
|
||||
{ 193, "cassette_empty_active.ico" },
|
||||
{ 200, "run.ico" },
|
||||
{ 201, "pause.ico" },
|
||||
{ 202, "send_cad.ico" },
|
||||
{ 203, "send_cae.ico" },
|
||||
{ 204, "hard_reset.ico" },
|
||||
{ 205, "acpi_shutdown.ico" },
|
||||
{ 206, "settings.ico" },
|
||||
{ 232, "cartridge_empty.ico" },
|
||||
{ 240, "machine.ico" },
|
||||
{ 241, "display.ico" },
|
||||
{ 242, "input_devices.ico" },
|
||||
{ 243, "sound.ico" },
|
||||
{ 244, "ports.ico" },
|
||||
{ 245, "other_peripherals.ico" },
|
||||
{ 246, "floppy_and_cdrom_drives.ico"},
|
||||
{ 247, "other_removable_devices.ico"},
|
||||
{ 248, "floppy_disabled.ico" },
|
||||
{ 249, "cdrom_disabled.ico" },
|
||||
{ 250, "zip_disabled.ico" },
|
||||
{ 251, "mo_disabled.ico" },
|
||||
{ 252, "storage_controllers.ico" }
|
||||
};
|
||||
|
||||
void win_get_icons_path(char* path_root)
|
||||
void
|
||||
win_get_icons_path(char *path_root)
|
||||
{
|
||||
char roms_root[1024] = {0};
|
||||
if (rom_path[0])
|
||||
strcpy(roms_root, rom_path);
|
||||
else
|
||||
path_append_filename(roms_root, exe_path, "roms");
|
||||
char roms_root[1024] = { 0 };
|
||||
if (rom_path[0])
|
||||
strcpy(roms_root, rom_path);
|
||||
else
|
||||
path_append_filename(roms_root, exe_path, "roms");
|
||||
|
||||
path_append_filename(path_root, roms_root, "icons");
|
||||
path_slash(path_root);
|
||||
path_append_filename(path_root, roms_root, "icons");
|
||||
path_slash(path_root);
|
||||
}
|
||||
|
||||
void win_load_icon_set()
|
||||
void
|
||||
win_load_icon_set()
|
||||
{
|
||||
win_clear_icon_set();
|
||||
win_system_icon_set();
|
||||
win_clear_icon_set();
|
||||
win_system_icon_set();
|
||||
|
||||
if (strlen(icon_set) == 0) {
|
||||
ToolBarLoadIcons();
|
||||
return;
|
||||
}
|
||||
if (strlen(icon_set) == 0) {
|
||||
ToolBarLoadIcons();
|
||||
return;
|
||||
}
|
||||
|
||||
char path_root[2048] = {0}, temp[2048] = {0};
|
||||
wchar_t wtemp[2048] = {0};
|
||||
char path_root[2048] = { 0 }, temp[2048] = { 0 };
|
||||
wchar_t wtemp[2048] = { 0 };
|
||||
|
||||
win_get_icons_path(path_root);
|
||||
strcat(path_root, icon_set);
|
||||
path_slash(path_root);
|
||||
win_get_icons_path(path_root);
|
||||
strcat(path_root, icon_set);
|
||||
path_slash(path_root);
|
||||
|
||||
int i, count = sizeof(icon_files) / sizeof(_ICON_DATA),
|
||||
x = win_get_system_metrics(SM_CXSMICON, dpi), y = win_get_system_metrics(SM_CYSMICON, dpi);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
path_append_filename(temp, path_root, icon_files[i].filename);
|
||||
mbstoc16s(wtemp, temp, strlen(temp) + 1);
|
||||
int i, count = sizeof(icon_files) / sizeof(_ICON_DATA),
|
||||
x = win_get_system_metrics(SM_CXSMICON, dpi), y = win_get_system_metrics(SM_CYSMICON, dpi);
|
||||
for (i = 0; i < count; i++) {
|
||||
path_append_filename(temp, path_root, icon_files[i].filename);
|
||||
mbstoc16s(wtemp, temp, strlen(temp) + 1);
|
||||
|
||||
HICON ictemp;
|
||||
ictemp = LoadImageW(NULL, (LPWSTR)wtemp, IMAGE_ICON, x, y, LR_LOADFROMFILE | LR_DEFAULTCOLOR);
|
||||
if (ictemp)
|
||||
{
|
||||
if (hIcon[icon_files[i].id])
|
||||
DestroyIcon(hIcon[icon_files[i].id]);
|
||||
hIcon[icon_files[i].id] = ictemp;
|
||||
}
|
||||
}
|
||||
HICON ictemp;
|
||||
ictemp = LoadImageW(NULL, (LPWSTR) wtemp, IMAGE_ICON, x, y, LR_LOADFROMFILE | LR_DEFAULTCOLOR);
|
||||
if (ictemp) {
|
||||
if (hIcon[icon_files[i].id])
|
||||
DestroyIcon(hIcon[icon_files[i].id]);
|
||||
hIcon[icon_files[i].id] = ictemp;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t curr_lang = lang_id;
|
||||
lang_id = 0;
|
||||
set_language(curr_lang);
|
||||
uint32_t curr_lang = lang_id;
|
||||
lang_id = 0;
|
||||
set_language(curr_lang);
|
||||
|
||||
ToolBarLoadIcons();
|
||||
ToolBarLoadIcons();
|
||||
}
|
||||
|
||||
@@ -36,435 +36,447 @@
|
||||
#ifdef ENABLE_JOYSTICK_LOG
|
||||
int joystick_do_log = ENABLE_JOYSTICK_LOG;
|
||||
|
||||
|
||||
static void
|
||||
joystick_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_list ap;
|
||||
|
||||
if (joystick_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
if (joystick_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define joystick_log(fmt, ...)
|
||||
# define joystick_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
HANDLE hdevice;
|
||||
PHIDP_PREPARSED_DATA data;
|
||||
HANDLE hdevice;
|
||||
PHIDP_PREPARSED_DATA data;
|
||||
|
||||
USAGE usage_button[256];
|
||||
USAGE usage_button[256];
|
||||
|
||||
struct raw_axis_t {
|
||||
USAGE usage;
|
||||
USHORT link;
|
||||
USHORT bitsize;
|
||||
LONG max;
|
||||
LONG min;
|
||||
} axis[8];
|
||||
struct raw_axis_t {
|
||||
USAGE usage;
|
||||
USHORT link;
|
||||
USHORT bitsize;
|
||||
LONG max;
|
||||
LONG min;
|
||||
} axis[8];
|
||||
|
||||
struct raw_pov_t {
|
||||
USAGE usage;
|
||||
USHORT link;
|
||||
LONG max;
|
||||
LONG min;
|
||||
} pov[4];
|
||||
struct raw_pov_t {
|
||||
USAGE usage;
|
||||
USHORT link;
|
||||
LONG max;
|
||||
LONG min;
|
||||
} pov[4];
|
||||
} raw_joystick_t;
|
||||
|
||||
plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS];
|
||||
joystick_t joystick_state[MAX_JOYSTICKS];
|
||||
int joysticks_present = 0;
|
||||
joystick_t joystick_state[MAX_JOYSTICKS];
|
||||
int joysticks_present = 0;
|
||||
|
||||
raw_joystick_t raw_joystick_state[MAX_PLAT_JOYSTICKS];
|
||||
|
||||
/* We only use the first 32 buttons reported, from Usage ID 1-128 */
|
||||
void joystick_add_button(raw_joystick_t* rawjoy, plat_joystick_t* joy, USAGE usage) {
|
||||
if (joy->nr_buttons >= 32) return;
|
||||
if (usage < 1 || usage > 128) return;
|
||||
|
||||
rawjoy->usage_button[usage] = joy->nr_buttons;
|
||||
sprintf(joy->button[joy->nr_buttons].name, "Button %d", usage);
|
||||
joy->nr_buttons++;
|
||||
}
|
||||
|
||||
void joystick_add_axis(raw_joystick_t* rawjoy, plat_joystick_t* joy, PHIDP_VALUE_CAPS prop) {
|
||||
if (joy->nr_axes >= 8) return;
|
||||
|
||||
switch (prop->Range.UsageMin) {
|
||||
case HID_USAGE_GENERIC_X:
|
||||
sprintf(joy->axis[joy->nr_axes].name, "X");
|
||||
break;
|
||||
case HID_USAGE_GENERIC_Y:
|
||||
sprintf(joy->axis[joy->nr_axes].name, "Y");
|
||||
break;
|
||||
case HID_USAGE_GENERIC_Z:
|
||||
sprintf(joy->axis[joy->nr_axes].name, "Z");
|
||||
break;
|
||||
case HID_USAGE_GENERIC_RX:
|
||||
sprintf(joy->axis[joy->nr_axes].name, "RX");
|
||||
break;
|
||||
case HID_USAGE_GENERIC_RY:
|
||||
sprintf(joy->axis[joy->nr_axes].name, "RY");
|
||||
break;
|
||||
case HID_USAGE_GENERIC_RZ:
|
||||
sprintf(joy->axis[joy->nr_axes].name, "RZ");
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
joy->axis[joy->nr_axes].id = joy->nr_axes;
|
||||
rawjoy->axis[joy->nr_axes].usage = prop->Range.UsageMin;
|
||||
rawjoy->axis[joy->nr_axes].link = prop->LinkCollection;
|
||||
rawjoy->axis[joy->nr_axes].bitsize = prop->BitSize;
|
||||
|
||||
/* Assume unsigned when min >= 0 */
|
||||
if (prop->LogicalMin < 0) {
|
||||
rawjoy->axis[joy->nr_axes].max = prop->LogicalMax;
|
||||
} else {
|
||||
/*
|
||||
* Some joysticks will send -1 in LogicalMax, like Xbox Controllers
|
||||
* so we need to mask that to appropriate value (instead of 0xFFFFFFFF)
|
||||
*/
|
||||
rawjoy->axis[joy->nr_axes].max = prop->LogicalMax & ((1 << prop->BitSize) - 1);
|
||||
}
|
||||
rawjoy->axis[joy->nr_axes].min = prop->LogicalMin;
|
||||
|
||||
joy->nr_axes++;
|
||||
}
|
||||
|
||||
void joystick_add_pov(raw_joystick_t* rawjoy, plat_joystick_t* joy, PHIDP_VALUE_CAPS prop) {
|
||||
if (joy->nr_povs >= 4) return;
|
||||
|
||||
sprintf(joy->pov[joy->nr_povs].name, "POV %d", joy->nr_povs+1);
|
||||
rawjoy->pov[joy->nr_povs].usage = prop->Range.UsageMin;
|
||||
rawjoy->pov[joy->nr_povs].link = prop->LinkCollection;
|
||||
rawjoy->pov[joy->nr_povs].min = prop->LogicalMin;
|
||||
rawjoy->pov[joy->nr_povs].max = prop->LogicalMax;
|
||||
|
||||
joy->nr_povs++;
|
||||
}
|
||||
|
||||
void joystick_get_capabilities(raw_joystick_t* rawjoy, plat_joystick_t* joy) {
|
||||
UINT size = 0;
|
||||
PHIDP_BUTTON_CAPS btn_caps = NULL;
|
||||
PHIDP_VALUE_CAPS val_caps = NULL;
|
||||
|
||||
/* Get preparsed data (HID data format) */
|
||||
GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_PREPARSEDDATA, NULL, &size);
|
||||
rawjoy->data = malloc(size);
|
||||
if (GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_PREPARSEDDATA, rawjoy->data, &size) <= 0)
|
||||
fatal("joystick_get_capabilities: Failed to get preparsed data.\n");
|
||||
|
||||
HIDP_CAPS caps;
|
||||
HidP_GetCaps(rawjoy->data, &caps);
|
||||
|
||||
/* Buttons */
|
||||
if (caps.NumberInputButtonCaps > 0) {
|
||||
btn_caps = calloc(caps.NumberInputButtonCaps, sizeof(HIDP_BUTTON_CAPS));
|
||||
if (HidP_GetButtonCaps(HidP_Input, btn_caps, &caps.NumberInputButtonCaps, rawjoy->data) != HIDP_STATUS_SUCCESS) {
|
||||
joystick_log("joystick_get_capabilities: Failed to query input buttons.\n");
|
||||
goto end;
|
||||
}
|
||||
/* We only detect generic stuff */
|
||||
for (int c=0; c<caps.NumberInputButtonCaps; c++) {
|
||||
if (btn_caps[c].UsagePage != HID_USAGE_PAGE_BUTTON) continue;
|
||||
|
||||
int button_count = btn_caps[c].Range.UsageMax - btn_caps[c].Range.UsageMin + 1;
|
||||
for (int b=0; b<button_count; b++) {
|
||||
joystick_add_button(rawjoy, joy, b + btn_caps[c].Range.UsageMin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Values (axes and povs) */
|
||||
if (caps.NumberInputValueCaps > 0) {
|
||||
val_caps = calloc(caps.NumberInputValueCaps, sizeof(HIDP_VALUE_CAPS));
|
||||
if (HidP_GetValueCaps(HidP_Input, val_caps, &caps.NumberInputValueCaps, rawjoy->data) != HIDP_STATUS_SUCCESS) {
|
||||
joystick_log("joystick_get_capabilities: Failed to query axes and povs.\n");
|
||||
goto end;
|
||||
}
|
||||
/* We only detect generic stuff */
|
||||
for (int c=0; c<caps.NumberInputValueCaps; c++) {
|
||||
if (val_caps[c].UsagePage != HID_USAGE_PAGE_GENERIC) continue;
|
||||
|
||||
if (val_caps[c].Range.UsageMin == HID_USAGE_GENERIC_HATSWITCH)
|
||||
joystick_add_pov(rawjoy, joy, &val_caps[c]);
|
||||
else
|
||||
joystick_add_axis(rawjoy, joy, &val_caps[c]);
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
free(btn_caps);
|
||||
free(val_caps);
|
||||
}
|
||||
|
||||
void joystick_get_device_name(raw_joystick_t* rawjoy, plat_joystick_t* joy, PRID_DEVICE_INFO info) {
|
||||
UINT size = 0;
|
||||
char *device_name = NULL;
|
||||
WCHAR device_desc_wide[200] = {0};
|
||||
|
||||
GetRawInputDeviceInfoA(rawjoy->hdevice, RIDI_DEVICENAME, device_name, &size);
|
||||
device_name = calloc(size, sizeof(char));
|
||||
if (GetRawInputDeviceInfoA(rawjoy->hdevice, RIDI_DEVICENAME, device_name, &size) <= 0)
|
||||
fatal("joystick_get_capabilities: Failed to get device name.\n");
|
||||
|
||||
HANDLE hDevObj = CreateFile(device_name, GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (hDevObj) {
|
||||
HidD_GetProductString(hDevObj, device_desc_wide, sizeof(WCHAR) * 200);
|
||||
CloseHandle(hDevObj);
|
||||
}
|
||||
free(device_name);
|
||||
|
||||
int result = WideCharToMultiByte(CP_ACP, 0, device_desc_wide, 200, joy->name, 260, NULL, NULL);
|
||||
if (result == 0 || strlen(joy->name) == 0)
|
||||
sprintf(joy->name,
|
||||
"RawInput %s, VID:%04lX PID:%04lX",
|
||||
info->hid.usUsage == HID_USAGE_GENERIC_JOYSTICK ? "Joystick" : "Gamepad",
|
||||
info->hid.dwVendorId,
|
||||
info->hid.dwProductId);
|
||||
}
|
||||
|
||||
void joystick_init()
|
||||
void
|
||||
joystick_add_button(raw_joystick_t *rawjoy, plat_joystick_t *joy, USAGE usage)
|
||||
{
|
||||
UINT size = 0;
|
||||
atexit(joystick_close);
|
||||
if (joy->nr_buttons >= 32)
|
||||
return;
|
||||
if (usage < 1 || usage > 128)
|
||||
return;
|
||||
|
||||
joysticks_present = 0;
|
||||
memset(raw_joystick_state, 0, sizeof(raw_joystick_t) * MAX_PLAT_JOYSTICKS);
|
||||
|
||||
/* Get a list of raw input devices from Windows */
|
||||
UINT raw_devices = 0;
|
||||
GetRawInputDeviceList(NULL, &raw_devices, sizeof(RAWINPUTDEVICELIST));
|
||||
PRAWINPUTDEVICELIST deviceList = calloc(raw_devices, sizeof(RAWINPUTDEVICELIST));
|
||||
GetRawInputDeviceList(deviceList, &raw_devices, sizeof(RAWINPUTDEVICELIST));
|
||||
|
||||
for (int i=0; i<raw_devices; i++) {
|
||||
PRID_DEVICE_INFO info = NULL;
|
||||
|
||||
if (joysticks_present >= MAX_PLAT_JOYSTICKS) break;
|
||||
if (deviceList[i].dwType != RIM_TYPEHID) continue;
|
||||
|
||||
/* Get device info: hardware IDs and usage IDs */
|
||||
GetRawInputDeviceInfoA(deviceList[i].hDevice, RIDI_DEVICEINFO, NULL, &size);
|
||||
info = malloc(size);
|
||||
info->cbSize = sizeof(RID_DEVICE_INFO);
|
||||
if (GetRawInputDeviceInfoA(deviceList[i].hDevice, RIDI_DEVICEINFO, info, &size) <= 0)
|
||||
goto end_loop;
|
||||
|
||||
/* If this is not a joystick/gamepad, skip */
|
||||
if (info->hid.usUsagePage != HID_USAGE_PAGE_GENERIC) goto end_loop;
|
||||
if (info->hid.usUsage != HID_USAGE_GENERIC_JOYSTICK &&
|
||||
info->hid.usUsage != HID_USAGE_GENERIC_GAMEPAD) goto end_loop;
|
||||
|
||||
plat_joystick_t *joy = &plat_joystick_state[joysticks_present];
|
||||
raw_joystick_t *rawjoy = &raw_joystick_state[joysticks_present];
|
||||
rawjoy->hdevice = deviceList[i].hDevice;
|
||||
|
||||
joystick_get_capabilities(rawjoy, joy);
|
||||
joystick_get_device_name(rawjoy, joy, info);
|
||||
|
||||
joystick_log("joystick_init: %s - %d buttons, %d axes, %d POVs\n",
|
||||
joy->name, joy->nr_buttons, joy->nr_axes, joy->nr_povs);
|
||||
|
||||
joysticks_present++;
|
||||
|
||||
end_loop:
|
||||
free(info);
|
||||
}
|
||||
|
||||
joystick_log("joystick_init: joysticks_present=%i\n", joysticks_present);
|
||||
|
||||
/* Initialize the RawInput (joystick and gamepad) module. */
|
||||
RAWINPUTDEVICE ridev[2];
|
||||
ridev[0].dwFlags = 0;
|
||||
ridev[0].hwndTarget = NULL;
|
||||
ridev[0].usUsagePage = HID_USAGE_PAGE_GENERIC;
|
||||
ridev[0].usUsage = HID_USAGE_GENERIC_JOYSTICK;
|
||||
|
||||
ridev[1].dwFlags = 0;
|
||||
ridev[1].hwndTarget = NULL;
|
||||
ridev[1].usUsagePage = HID_USAGE_PAGE_GENERIC;
|
||||
ridev[1].usUsage = HID_USAGE_GENERIC_GAMEPAD;
|
||||
|
||||
if (!RegisterRawInputDevices(ridev, 2, sizeof(RAWINPUTDEVICE)))
|
||||
fatal("plat_joystick_init: RegisterRawInputDevices failed\n");
|
||||
rawjoy->usage_button[usage] = joy->nr_buttons;
|
||||
sprintf(joy->button[joy->nr_buttons].name, "Button %d", usage);
|
||||
joy->nr_buttons++;
|
||||
}
|
||||
|
||||
void joystick_close()
|
||||
void
|
||||
joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS prop)
|
||||
{
|
||||
RAWINPUTDEVICE ridev[2];
|
||||
ridev[0].dwFlags = RIDEV_REMOVE;
|
||||
ridev[0].hwndTarget = NULL;
|
||||
ridev[0].usUsagePage = HID_USAGE_PAGE_GENERIC;
|
||||
ridev[0].usUsage = HID_USAGE_GENERIC_JOYSTICK;
|
||||
if (joy->nr_axes >= 8)
|
||||
return;
|
||||
|
||||
ridev[1].dwFlags = RIDEV_REMOVE;
|
||||
ridev[1].hwndTarget = NULL;
|
||||
ridev[1].usUsagePage = HID_USAGE_PAGE_GENERIC;
|
||||
ridev[1].usUsage = HID_USAGE_GENERIC_GAMEPAD;
|
||||
switch (prop->Range.UsageMin) {
|
||||
case HID_USAGE_GENERIC_X:
|
||||
sprintf(joy->axis[joy->nr_axes].name, "X");
|
||||
break;
|
||||
case HID_USAGE_GENERIC_Y:
|
||||
sprintf(joy->axis[joy->nr_axes].name, "Y");
|
||||
break;
|
||||
case HID_USAGE_GENERIC_Z:
|
||||
sprintf(joy->axis[joy->nr_axes].name, "Z");
|
||||
break;
|
||||
case HID_USAGE_GENERIC_RX:
|
||||
sprintf(joy->axis[joy->nr_axes].name, "RX");
|
||||
break;
|
||||
case HID_USAGE_GENERIC_RY:
|
||||
sprintf(joy->axis[joy->nr_axes].name, "RY");
|
||||
break;
|
||||
case HID_USAGE_GENERIC_RZ:
|
||||
sprintf(joy->axis[joy->nr_axes].name, "RZ");
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
RegisterRawInputDevices(ridev, 2, sizeof(RAWINPUTDEVICE));
|
||||
joy->axis[joy->nr_axes].id = joy->nr_axes;
|
||||
rawjoy->axis[joy->nr_axes].usage = prop->Range.UsageMin;
|
||||
rawjoy->axis[joy->nr_axes].link = prop->LinkCollection;
|
||||
rawjoy->axis[joy->nr_axes].bitsize = prop->BitSize;
|
||||
|
||||
/* Assume unsigned when min >= 0 */
|
||||
if (prop->LogicalMin < 0) {
|
||||
rawjoy->axis[joy->nr_axes].max = prop->LogicalMax;
|
||||
} else {
|
||||
/*
|
||||
* Some joysticks will send -1 in LogicalMax, like Xbox Controllers
|
||||
* so we need to mask that to appropriate value (instead of 0xFFFFFFFF)
|
||||
*/
|
||||
rawjoy->axis[joy->nr_axes].max = prop->LogicalMax & ((1 << prop->BitSize) - 1);
|
||||
}
|
||||
rawjoy->axis[joy->nr_axes].min = prop->LogicalMin;
|
||||
|
||||
joy->nr_axes++;
|
||||
}
|
||||
|
||||
|
||||
void win_joystick_handle(PRAWINPUT raw)
|
||||
void
|
||||
joystick_add_pov(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS prop)
|
||||
{
|
||||
HRESULT r;
|
||||
int j = -1; /* current joystick index, -1 when not found */
|
||||
if (joy->nr_povs >= 4)
|
||||
return;
|
||||
|
||||
/* If the input is not from a known device, we ignore it */
|
||||
for (int i=0; i<joysticks_present; i++) {
|
||||
if (raw_joystick_state[i].hdevice == raw->header.hDevice) {
|
||||
j = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j == -1) return;
|
||||
sprintf(joy->pov[joy->nr_povs].name, "POV %d", joy->nr_povs + 1);
|
||||
rawjoy->pov[joy->nr_povs].usage = prop->Range.UsageMin;
|
||||
rawjoy->pov[joy->nr_povs].link = prop->LinkCollection;
|
||||
rawjoy->pov[joy->nr_povs].min = prop->LogicalMin;
|
||||
rawjoy->pov[joy->nr_povs].max = prop->LogicalMax;
|
||||
|
||||
/* Read buttons */
|
||||
USAGE usage_list[128] = {0};
|
||||
ULONG usage_length = plat_joystick_state[j].nr_buttons;
|
||||
memset(plat_joystick_state[j].b, 0, 32 * sizeof(int));
|
||||
|
||||
r = HidP_GetUsages(HidP_Input, HID_USAGE_PAGE_BUTTON, 0, usage_list, &usage_length,
|
||||
raw_joystick_state[j].data, (PCHAR)raw->data.hid.bRawData, raw->data.hid.dwSizeHid);
|
||||
|
||||
if (r == HIDP_STATUS_SUCCESS) {
|
||||
for (int i=0; i<usage_length; i++) {
|
||||
int button = raw_joystick_state[j].usage_button[usage_list[i]];
|
||||
plat_joystick_state[j].b[button] = 128;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read axes */
|
||||
for (int a=0; a<plat_joystick_state[j].nr_axes; a++) {
|
||||
struct raw_axis_t* axis = &raw_joystick_state[j].axis[a];
|
||||
ULONG uvalue = 0;
|
||||
LONG value = 0;
|
||||
LONG center = (axis->max - axis->min + 1) / 2;
|
||||
|
||||
r = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, axis->link, axis->usage, &uvalue,
|
||||
raw_joystick_state[j].data, (PCHAR)raw->data.hid.bRawData, raw->data.hid.dwSizeHid);
|
||||
|
||||
if (r == HIDP_STATUS_SUCCESS) {
|
||||
if (axis->min < 0) {
|
||||
/* extend signed uvalue to LONG */
|
||||
if (uvalue & (1 << (axis->bitsize-1))) {
|
||||
ULONG mask = (1 << axis->bitsize) - 1;
|
||||
value = -1U ^ mask;
|
||||
value |= uvalue;
|
||||
} else {
|
||||
value = uvalue;
|
||||
}
|
||||
} else {
|
||||
/* Assume unsigned when min >= 0, convert to a signed value */
|
||||
value = (LONG)uvalue - center;
|
||||
}
|
||||
if (abs(value) == 1) value = 0;
|
||||
value = value * 32768 / center;
|
||||
}
|
||||
|
||||
plat_joystick_state[j].a[a] = value;
|
||||
//joystick_log("%s %-06d ", plat_joystick_state[j].axis[a].name, plat_joystick_state[j].a[a]);
|
||||
}
|
||||
|
||||
/* read povs */
|
||||
for (int p=0; p<plat_joystick_state[j].nr_povs; p++) {
|
||||
struct raw_pov_t* pov = &raw_joystick_state[j].pov[p];
|
||||
ULONG uvalue = 0;
|
||||
LONG value = -1;
|
||||
|
||||
r = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, pov->link, pov->usage, &uvalue,
|
||||
raw_joystick_state[j].data, (PCHAR)raw->data.hid.bRawData, raw->data.hid.dwSizeHid);
|
||||
|
||||
if (r == HIDP_STATUS_SUCCESS && (uvalue >= pov->min && uvalue <= pov->max)) {
|
||||
value = (uvalue - pov->min) * 36000;
|
||||
value /= (pov->max - pov->min + 1);
|
||||
value %= 36000;
|
||||
}
|
||||
|
||||
plat_joystick_state[j].p[p] = value;
|
||||
|
||||
//joystick_log("%s %-3d ", plat_joystick_state[j].pov[p].name, plat_joystick_state[j].p[p]);
|
||||
|
||||
}
|
||||
//joystick_log("\n");
|
||||
joy->nr_povs++;
|
||||
}
|
||||
|
||||
|
||||
static int joystick_get_axis(int joystick_nr, int mapping)
|
||||
void
|
||||
joystick_get_capabilities(raw_joystick_t *rawjoy, plat_joystick_t *joy)
|
||||
{
|
||||
if (mapping & POV_X)
|
||||
{
|
||||
int pov = plat_joystick_state[joystick_nr].p[mapping & 3];
|
||||
if (LOWORD(pov) == 0xFFFF)
|
||||
return 0;
|
||||
else
|
||||
return sin((2*M_PI * (double)pov) / 36000.0) * 32767;
|
||||
}
|
||||
else if (mapping & POV_Y)
|
||||
{
|
||||
int pov = plat_joystick_state[joystick_nr].p[mapping & 3];
|
||||
UINT size = 0;
|
||||
PHIDP_BUTTON_CAPS btn_caps = NULL;
|
||||
PHIDP_VALUE_CAPS val_caps = NULL;
|
||||
|
||||
if (LOWORD(pov) == 0xFFFF)
|
||||
return 0;
|
||||
else
|
||||
return -cos((2*M_PI * (double)pov) / 36000.0) * 32767;
|
||||
}
|
||||
else
|
||||
return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id];
|
||||
/* Get preparsed data (HID data format) */
|
||||
GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_PREPARSEDDATA, NULL, &size);
|
||||
rawjoy->data = malloc(size);
|
||||
if (GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_PREPARSEDDATA, rawjoy->data, &size) <= 0)
|
||||
fatal("joystick_get_capabilities: Failed to get preparsed data.\n");
|
||||
|
||||
HIDP_CAPS caps;
|
||||
HidP_GetCaps(rawjoy->data, &caps);
|
||||
|
||||
/* Buttons */
|
||||
if (caps.NumberInputButtonCaps > 0) {
|
||||
btn_caps = calloc(caps.NumberInputButtonCaps, sizeof(HIDP_BUTTON_CAPS));
|
||||
if (HidP_GetButtonCaps(HidP_Input, btn_caps, &caps.NumberInputButtonCaps, rawjoy->data) != HIDP_STATUS_SUCCESS) {
|
||||
joystick_log("joystick_get_capabilities: Failed to query input buttons.\n");
|
||||
goto end;
|
||||
}
|
||||
/* We only detect generic stuff */
|
||||
for (int c = 0; c < caps.NumberInputButtonCaps; c++) {
|
||||
if (btn_caps[c].UsagePage != HID_USAGE_PAGE_BUTTON)
|
||||
continue;
|
||||
|
||||
int button_count = btn_caps[c].Range.UsageMax - btn_caps[c].Range.UsageMin + 1;
|
||||
for (int b = 0; b < button_count; b++) {
|
||||
joystick_add_button(rawjoy, joy, b + btn_caps[c].Range.UsageMin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Values (axes and povs) */
|
||||
if (caps.NumberInputValueCaps > 0) {
|
||||
val_caps = calloc(caps.NumberInputValueCaps, sizeof(HIDP_VALUE_CAPS));
|
||||
if (HidP_GetValueCaps(HidP_Input, val_caps, &caps.NumberInputValueCaps, rawjoy->data) != HIDP_STATUS_SUCCESS) {
|
||||
joystick_log("joystick_get_capabilities: Failed to query axes and povs.\n");
|
||||
goto end;
|
||||
}
|
||||
/* We only detect generic stuff */
|
||||
for (int c = 0; c < caps.NumberInputValueCaps; c++) {
|
||||
if (val_caps[c].UsagePage != HID_USAGE_PAGE_GENERIC)
|
||||
continue;
|
||||
|
||||
if (val_caps[c].Range.UsageMin == HID_USAGE_GENERIC_HATSWITCH)
|
||||
joystick_add_pov(rawjoy, joy, &val_caps[c]);
|
||||
else
|
||||
joystick_add_axis(rawjoy, joy, &val_caps[c]);
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
free(btn_caps);
|
||||
free(val_caps);
|
||||
}
|
||||
|
||||
|
||||
void joystick_process(void)
|
||||
void
|
||||
joystick_get_device_name(raw_joystick_t *rawjoy, plat_joystick_t *joy, PRID_DEVICE_INFO info)
|
||||
{
|
||||
int c, d;
|
||||
UINT size = 0;
|
||||
char *device_name = NULL;
|
||||
WCHAR device_desc_wide[200] = { 0 };
|
||||
|
||||
if (joystick_type == 7) return;
|
||||
GetRawInputDeviceInfoA(rawjoy->hdevice, RIDI_DEVICENAME, device_name, &size);
|
||||
device_name = calloc(size, sizeof(char));
|
||||
if (GetRawInputDeviceInfoA(rawjoy->hdevice, RIDI_DEVICENAME, device_name, &size) <= 0)
|
||||
fatal("joystick_get_capabilities: Failed to get device name.\n");
|
||||
|
||||
for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++)
|
||||
{
|
||||
if (joystick_state[c].plat_joystick_nr)
|
||||
{
|
||||
int joystick_nr = joystick_state[c].plat_joystick_nr - 1;
|
||||
HANDLE hDevObj = CreateFile(device_name, GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (hDevObj) {
|
||||
HidD_GetProductString(hDevObj, device_desc_wide, sizeof(WCHAR) * 200);
|
||||
CloseHandle(hDevObj);
|
||||
}
|
||||
free(device_name);
|
||||
|
||||
for (d = 0; d < joystick_get_axis_count(joystick_type); d++)
|
||||
joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]);
|
||||
for (d = 0; d < joystick_get_button_count(joystick_type); d++)
|
||||
joystick_state[c].button[d] = plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]];
|
||||
|
||||
for (d = 0; d < joystick_get_pov_count(joystick_type); d++)
|
||||
{
|
||||
int x, y;
|
||||
double angle, magnitude;
|
||||
|
||||
x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]);
|
||||
y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]);
|
||||
|
||||
angle = (atan2((double)y, (double)x) * 360.0) / (2*M_PI);
|
||||
magnitude = sqrt((double)x*(double)x + (double)y*(double)y);
|
||||
|
||||
if (magnitude < 16384)
|
||||
joystick_state[c].pov[d] = -1;
|
||||
else
|
||||
joystick_state[c].pov[d] = ((int)angle + 90 + 360) % 360;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (d = 0; d < joystick_get_axis_count(joystick_type); d++)
|
||||
joystick_state[c].axis[d] = 0;
|
||||
for (d = 0; d < joystick_get_button_count(joystick_type); d++)
|
||||
joystick_state[c].button[d] = 0;
|
||||
for (d = 0; d < joystick_get_pov_count(joystick_type); d++)
|
||||
joystick_state[c].pov[d] = -1;
|
||||
}
|
||||
}
|
||||
int result = WideCharToMultiByte(CP_ACP, 0, device_desc_wide, 200, joy->name, 260, NULL, NULL);
|
||||
if (result == 0 || strlen(joy->name) == 0)
|
||||
sprintf(joy->name,
|
||||
"RawInput %s, VID:%04lX PID:%04lX",
|
||||
info->hid.usUsage == HID_USAGE_GENERIC_JOYSTICK ? "Joystick" : "Gamepad",
|
||||
info->hid.dwVendorId,
|
||||
info->hid.dwProductId);
|
||||
}
|
||||
|
||||
void
|
||||
joystick_init()
|
||||
{
|
||||
UINT size = 0;
|
||||
atexit(joystick_close);
|
||||
|
||||
joysticks_present = 0;
|
||||
memset(raw_joystick_state, 0, sizeof(raw_joystick_t) * MAX_PLAT_JOYSTICKS);
|
||||
|
||||
/* Get a list of raw input devices from Windows */
|
||||
UINT raw_devices = 0;
|
||||
GetRawInputDeviceList(NULL, &raw_devices, sizeof(RAWINPUTDEVICELIST));
|
||||
PRAWINPUTDEVICELIST deviceList = calloc(raw_devices, sizeof(RAWINPUTDEVICELIST));
|
||||
GetRawInputDeviceList(deviceList, &raw_devices, sizeof(RAWINPUTDEVICELIST));
|
||||
|
||||
for (int i = 0; i < raw_devices; i++) {
|
||||
PRID_DEVICE_INFO info = NULL;
|
||||
|
||||
if (joysticks_present >= MAX_PLAT_JOYSTICKS)
|
||||
break;
|
||||
if (deviceList[i].dwType != RIM_TYPEHID)
|
||||
continue;
|
||||
|
||||
/* Get device info: hardware IDs and usage IDs */
|
||||
GetRawInputDeviceInfoA(deviceList[i].hDevice, RIDI_DEVICEINFO, NULL, &size);
|
||||
info = malloc(size);
|
||||
info->cbSize = sizeof(RID_DEVICE_INFO);
|
||||
if (GetRawInputDeviceInfoA(deviceList[i].hDevice, RIDI_DEVICEINFO, info, &size) <= 0)
|
||||
goto end_loop;
|
||||
|
||||
/* If this is not a joystick/gamepad, skip */
|
||||
if (info->hid.usUsagePage != HID_USAGE_PAGE_GENERIC)
|
||||
goto end_loop;
|
||||
if (info->hid.usUsage != HID_USAGE_GENERIC_JOYSTICK && info->hid.usUsage != HID_USAGE_GENERIC_GAMEPAD)
|
||||
goto end_loop;
|
||||
|
||||
plat_joystick_t *joy = &plat_joystick_state[joysticks_present];
|
||||
raw_joystick_t *rawjoy = &raw_joystick_state[joysticks_present];
|
||||
rawjoy->hdevice = deviceList[i].hDevice;
|
||||
|
||||
joystick_get_capabilities(rawjoy, joy);
|
||||
joystick_get_device_name(rawjoy, joy, info);
|
||||
|
||||
joystick_log("joystick_init: %s - %d buttons, %d axes, %d POVs\n",
|
||||
joy->name, joy->nr_buttons, joy->nr_axes, joy->nr_povs);
|
||||
|
||||
joysticks_present++;
|
||||
|
||||
end_loop:
|
||||
free(info);
|
||||
}
|
||||
|
||||
joystick_log("joystick_init: joysticks_present=%i\n", joysticks_present);
|
||||
|
||||
/* Initialize the RawInput (joystick and gamepad) module. */
|
||||
RAWINPUTDEVICE ridev[2];
|
||||
ridev[0].dwFlags = 0;
|
||||
ridev[0].hwndTarget = NULL;
|
||||
ridev[0].usUsagePage = HID_USAGE_PAGE_GENERIC;
|
||||
ridev[0].usUsage = HID_USAGE_GENERIC_JOYSTICK;
|
||||
|
||||
ridev[1].dwFlags = 0;
|
||||
ridev[1].hwndTarget = NULL;
|
||||
ridev[1].usUsagePage = HID_USAGE_PAGE_GENERIC;
|
||||
ridev[1].usUsage = HID_USAGE_GENERIC_GAMEPAD;
|
||||
|
||||
if (!RegisterRawInputDevices(ridev, 2, sizeof(RAWINPUTDEVICE)))
|
||||
fatal("plat_joystick_init: RegisterRawInputDevices failed\n");
|
||||
}
|
||||
|
||||
void
|
||||
joystick_close()
|
||||
{
|
||||
RAWINPUTDEVICE ridev[2];
|
||||
ridev[0].dwFlags = RIDEV_REMOVE;
|
||||
ridev[0].hwndTarget = NULL;
|
||||
ridev[0].usUsagePage = HID_USAGE_PAGE_GENERIC;
|
||||
ridev[0].usUsage = HID_USAGE_GENERIC_JOYSTICK;
|
||||
|
||||
ridev[1].dwFlags = RIDEV_REMOVE;
|
||||
ridev[1].hwndTarget = NULL;
|
||||
ridev[1].usUsagePage = HID_USAGE_PAGE_GENERIC;
|
||||
ridev[1].usUsage = HID_USAGE_GENERIC_GAMEPAD;
|
||||
|
||||
RegisterRawInputDevices(ridev, 2, sizeof(RAWINPUTDEVICE));
|
||||
}
|
||||
|
||||
void
|
||||
win_joystick_handle(PRAWINPUT raw)
|
||||
{
|
||||
HRESULT r;
|
||||
int j = -1; /* current joystick index, -1 when not found */
|
||||
|
||||
/* If the input is not from a known device, we ignore it */
|
||||
for (int i = 0; i < joysticks_present; i++) {
|
||||
if (raw_joystick_state[i].hdevice == raw->header.hDevice) {
|
||||
j = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j == -1)
|
||||
return;
|
||||
|
||||
/* Read buttons */
|
||||
USAGE usage_list[128] = { 0 };
|
||||
ULONG usage_length = plat_joystick_state[j].nr_buttons;
|
||||
memset(plat_joystick_state[j].b, 0, 32 * sizeof(int));
|
||||
|
||||
r = HidP_GetUsages(HidP_Input, HID_USAGE_PAGE_BUTTON, 0, usage_list, &usage_length,
|
||||
raw_joystick_state[j].data, (PCHAR) raw->data.hid.bRawData, raw->data.hid.dwSizeHid);
|
||||
|
||||
if (r == HIDP_STATUS_SUCCESS) {
|
||||
for (int i = 0; i < usage_length; i++) {
|
||||
int button = raw_joystick_state[j].usage_button[usage_list[i]];
|
||||
plat_joystick_state[j].b[button] = 128;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read axes */
|
||||
for (int a = 0; a < plat_joystick_state[j].nr_axes; a++) {
|
||||
struct raw_axis_t *axis = &raw_joystick_state[j].axis[a];
|
||||
ULONG uvalue = 0;
|
||||
LONG value = 0;
|
||||
LONG center = (axis->max - axis->min + 1) / 2;
|
||||
|
||||
r = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, axis->link, axis->usage, &uvalue,
|
||||
raw_joystick_state[j].data, (PCHAR) raw->data.hid.bRawData, raw->data.hid.dwSizeHid);
|
||||
|
||||
if (r == HIDP_STATUS_SUCCESS) {
|
||||
if (axis->min < 0) {
|
||||
/* extend signed uvalue to LONG */
|
||||
if (uvalue & (1 << (axis->bitsize - 1))) {
|
||||
ULONG mask = (1 << axis->bitsize) - 1;
|
||||
value = -1U ^ mask;
|
||||
value |= uvalue;
|
||||
} else {
|
||||
value = uvalue;
|
||||
}
|
||||
} else {
|
||||
/* Assume unsigned when min >= 0, convert to a signed value */
|
||||
value = (LONG) uvalue - center;
|
||||
}
|
||||
if (abs(value) == 1)
|
||||
value = 0;
|
||||
value = value * 32768 / center;
|
||||
}
|
||||
|
||||
plat_joystick_state[j].a[a] = value;
|
||||
// joystick_log("%s %-06d ", plat_joystick_state[j].axis[a].name, plat_joystick_state[j].a[a]);
|
||||
}
|
||||
|
||||
/* read povs */
|
||||
for (int p = 0; p < plat_joystick_state[j].nr_povs; p++) {
|
||||
struct raw_pov_t *pov = &raw_joystick_state[j].pov[p];
|
||||
ULONG uvalue = 0;
|
||||
LONG value = -1;
|
||||
|
||||
r = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, pov->link, pov->usage, &uvalue,
|
||||
raw_joystick_state[j].data, (PCHAR) raw->data.hid.bRawData, raw->data.hid.dwSizeHid);
|
||||
|
||||
if (r == HIDP_STATUS_SUCCESS && (uvalue >= pov->min && uvalue <= pov->max)) {
|
||||
value = (uvalue - pov->min) * 36000;
|
||||
value /= (pov->max - pov->min + 1);
|
||||
value %= 36000;
|
||||
}
|
||||
|
||||
plat_joystick_state[j].p[p] = value;
|
||||
|
||||
// joystick_log("%s %-3d ", plat_joystick_state[j].pov[p].name, plat_joystick_state[j].p[p]);
|
||||
}
|
||||
// joystick_log("\n");
|
||||
}
|
||||
|
||||
static int
|
||||
joystick_get_axis(int joystick_nr, int mapping)
|
||||
{
|
||||
if (mapping & POV_X) {
|
||||
int pov = plat_joystick_state[joystick_nr].p[mapping & 3];
|
||||
if (LOWORD(pov) == 0xFFFF)
|
||||
return 0;
|
||||
else
|
||||
return sin((2 * M_PI * (double) pov) / 36000.0) * 32767;
|
||||
} else if (mapping & POV_Y) {
|
||||
int pov = plat_joystick_state[joystick_nr].p[mapping & 3];
|
||||
|
||||
if (LOWORD(pov) == 0xFFFF)
|
||||
return 0;
|
||||
else
|
||||
return -cos((2 * M_PI * (double) pov) / 36000.0) * 32767;
|
||||
} else
|
||||
return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id];
|
||||
}
|
||||
|
||||
void
|
||||
joystick_process(void)
|
||||
{
|
||||
int c, d;
|
||||
|
||||
if (joystick_type == 7)
|
||||
return;
|
||||
|
||||
for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) {
|
||||
if (joystick_state[c].plat_joystick_nr) {
|
||||
int joystick_nr = joystick_state[c].plat_joystick_nr - 1;
|
||||
|
||||
for (d = 0; d < joystick_get_axis_count(joystick_type); d++)
|
||||
joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]);
|
||||
for (d = 0; d < joystick_get_button_count(joystick_type); d++)
|
||||
joystick_state[c].button[d] = plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]];
|
||||
|
||||
for (d = 0; d < joystick_get_pov_count(joystick_type); d++) {
|
||||
int x, y;
|
||||
double angle, magnitude;
|
||||
|
||||
x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]);
|
||||
y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]);
|
||||
|
||||
angle = (atan2((double) y, (double) x) * 360.0) / (2 * M_PI);
|
||||
magnitude = sqrt((double) x * (double) x + (double) y * (double) y);
|
||||
|
||||
if (magnitude < 16384)
|
||||
joystick_state[c].pov[d] = -1;
|
||||
else
|
||||
joystick_state[c].pov[d] = ((int) angle + 90 + 360) % 360;
|
||||
}
|
||||
} else {
|
||||
for (d = 0; d < joystick_get_axis_count(joystick_type); d++)
|
||||
joystick_state[c].axis[d] = 0;
|
||||
for (d = 0; d < joystick_get_button_count(joystick_type); d++)
|
||||
joystick_state[c].button[d] = 0;
|
||||
for (d = 0; d < joystick_get_pov_count(joystick_type); d++)
|
||||
joystick_state[c].pov[d] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,233 +32,234 @@
|
||||
#include <86box/win.h>
|
||||
|
||||
#define XINPUT_MAX_JOYSTICKS 4
|
||||
#define XINPUT_NAME "Xinput compatiable controller"
|
||||
#define XINPUT_NAME_LX "Left Stick X"
|
||||
#define XINPUT_NAME_LY "Left Stick Y"
|
||||
#define XINPUT_NAME_RX "Right Stick X"
|
||||
#define XINPUT_NAME_RY "Right Stick Y"
|
||||
#define XINPUT_NAME_DPAD_X "D-pad X"
|
||||
#define XINPUT_NAME_DPAD_Y "D-pad Y"
|
||||
#define XINPUT_NAME_LB "LB"
|
||||
#define XINPUT_NAME_RB "RB"
|
||||
#define XINPUT_NAME_LT "LT"
|
||||
#define XINPUT_NAME_RT "RT"
|
||||
#define XINPUT_NAME_A "A"
|
||||
#define XINPUT_NAME_B "B"
|
||||
#define XINPUT_NAME_X "X"
|
||||
#define XINPUT_NAME_Y "Y"
|
||||
#define XINPUT_NAME_BACK "Back/View"
|
||||
#define XINPUT_NAME_START "Start/Menu"
|
||||
#define XINPUT_NAME_LS "Left Stick"
|
||||
#define XINPUT_NAME_RS "Right Stick"
|
||||
#define XINPUT_NAME "Xinput compatiable controller"
|
||||
#define XINPUT_NAME_LX "Left Stick X"
|
||||
#define XINPUT_NAME_LY "Left Stick Y"
|
||||
#define XINPUT_NAME_RX "Right Stick X"
|
||||
#define XINPUT_NAME_RY "Right Stick Y"
|
||||
#define XINPUT_NAME_DPAD_X "D-pad X"
|
||||
#define XINPUT_NAME_DPAD_Y "D-pad Y"
|
||||
#define XINPUT_NAME_LB "LB"
|
||||
#define XINPUT_NAME_RB "RB"
|
||||
#define XINPUT_NAME_LT "LT"
|
||||
#define XINPUT_NAME_RT "RT"
|
||||
#define XINPUT_NAME_A "A"
|
||||
#define XINPUT_NAME_B "B"
|
||||
#define XINPUT_NAME_X "X"
|
||||
#define XINPUT_NAME_Y "Y"
|
||||
#define XINPUT_NAME_BACK "Back/View"
|
||||
#define XINPUT_NAME_START "Start/Menu"
|
||||
#define XINPUT_NAME_LS "Left Stick"
|
||||
#define XINPUT_NAME_RS "Right Stick"
|
||||
|
||||
#ifdef ENABLE_JOYSTICK_LOG
|
||||
int joystick_do_log = ENABLE_JOYSTICK_LOG;
|
||||
|
||||
|
||||
static void
|
||||
joystick_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (joystick_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define joystick_log(fmt, ...)
|
||||
# define joystick_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS];
|
||||
joystick_t joystick_state[MAX_JOYSTICKS];
|
||||
int joysticks_present = 0;
|
||||
joystick_t joystick_state[MAX_JOYSTICKS];
|
||||
int joysticks_present = 0;
|
||||
|
||||
XINPUT_STATE controllers[XINPUT_MAX_JOYSTICKS];
|
||||
|
||||
void joystick_init()
|
||||
void
|
||||
joystick_init()
|
||||
{
|
||||
int c;
|
||||
int c;
|
||||
|
||||
atexit(joystick_close);
|
||||
atexit(joystick_close);
|
||||
|
||||
joysticks_present = 0;
|
||||
joysticks_present = 0;
|
||||
|
||||
memset(controllers, 0, sizeof(XINPUT_STATE) * XINPUT_MAX_JOYSTICKS);
|
||||
memset(controllers, 0, sizeof(XINPUT_STATE) * XINPUT_MAX_JOYSTICKS);
|
||||
|
||||
for (c=0; c<XINPUT_MAX_JOYSTICKS; c++) {
|
||||
int value = XInputGetState(c, &controllers[c]);
|
||||
if (value != ERROR_SUCCESS) continue;
|
||||
memcpy(plat_joystick_state[c].name, XINPUT_NAME, sizeof(XINPUT_NAME));
|
||||
for (c = 0; c < XINPUT_MAX_JOYSTICKS; c++) {
|
||||
int value = XInputGetState(c, &controllers[c]);
|
||||
if (value != ERROR_SUCCESS)
|
||||
continue;
|
||||
memcpy(plat_joystick_state[c].name, XINPUT_NAME, sizeof(XINPUT_NAME));
|
||||
|
||||
plat_joystick_state[c].nr_axes = 8;
|
||||
plat_joystick_state[c].nr_axes = 8;
|
||||
|
||||
/* analog stick */
|
||||
memcpy(plat_joystick_state[c].axis[0].name, XINPUT_NAME_LX, sizeof(XINPUT_NAME_LX));
|
||||
plat_joystick_state[c].axis[0].id = 0; /* X axis */
|
||||
memcpy(plat_joystick_state[c].axis[1].name, XINPUT_NAME_LY, sizeof(XINPUT_NAME_LY));
|
||||
plat_joystick_state[c].axis[1].id = 1; /* Y axis */
|
||||
memcpy(plat_joystick_state[c].axis[2].name, XINPUT_NAME_RX, sizeof(XINPUT_NAME_RX));
|
||||
plat_joystick_state[c].axis[2].id = 3; /* RX axis */
|
||||
memcpy(plat_joystick_state[c].axis[3].name, XINPUT_NAME_RY, sizeof(XINPUT_NAME_RY));
|
||||
plat_joystick_state[c].axis[3].id = 4; /* RY axis */
|
||||
/* analog stick */
|
||||
memcpy(plat_joystick_state[c].axis[0].name, XINPUT_NAME_LX, sizeof(XINPUT_NAME_LX));
|
||||
plat_joystick_state[c].axis[0].id = 0; /* X axis */
|
||||
memcpy(plat_joystick_state[c].axis[1].name, XINPUT_NAME_LY, sizeof(XINPUT_NAME_LY));
|
||||
plat_joystick_state[c].axis[1].id = 1; /* Y axis */
|
||||
memcpy(plat_joystick_state[c].axis[2].name, XINPUT_NAME_RX, sizeof(XINPUT_NAME_RX));
|
||||
plat_joystick_state[c].axis[2].id = 3; /* RX axis */
|
||||
memcpy(plat_joystick_state[c].axis[3].name, XINPUT_NAME_RY, sizeof(XINPUT_NAME_RY));
|
||||
plat_joystick_state[c].axis[3].id = 4; /* RY axis */
|
||||
|
||||
/* d-pad, assigned to Z and RZ */
|
||||
memcpy(plat_joystick_state[c].axis[4].name, XINPUT_NAME_DPAD_X, sizeof(XINPUT_NAME_DPAD_X));
|
||||
plat_joystick_state[c].axis[4].id = 2;
|
||||
memcpy(plat_joystick_state[c].axis[5].name, XINPUT_NAME_DPAD_Y, sizeof(XINPUT_NAME_DPAD_Y));
|
||||
plat_joystick_state[c].axis[5].id = 5;
|
||||
/* d-pad, assigned to Z and RZ */
|
||||
memcpy(plat_joystick_state[c].axis[4].name, XINPUT_NAME_DPAD_X, sizeof(XINPUT_NAME_DPAD_X));
|
||||
plat_joystick_state[c].axis[4].id = 2;
|
||||
memcpy(plat_joystick_state[c].axis[5].name, XINPUT_NAME_DPAD_Y, sizeof(XINPUT_NAME_DPAD_Y));
|
||||
plat_joystick_state[c].axis[5].id = 5;
|
||||
|
||||
/* Analog trigger */
|
||||
memcpy(plat_joystick_state[c].axis[6].name, XINPUT_NAME_LT, sizeof(XINPUT_NAME_LT));
|
||||
plat_joystick_state[c].axis[6].id = 6;
|
||||
memcpy(plat_joystick_state[c].axis[7].name, XINPUT_NAME_RT, sizeof(XINPUT_NAME_RT));
|
||||
plat_joystick_state[c].axis[7].id = 7;
|
||||
/* Analog trigger */
|
||||
memcpy(plat_joystick_state[c].axis[6].name, XINPUT_NAME_LT, sizeof(XINPUT_NAME_LT));
|
||||
plat_joystick_state[c].axis[6].id = 6;
|
||||
memcpy(plat_joystick_state[c].axis[7].name, XINPUT_NAME_RT, sizeof(XINPUT_NAME_RT));
|
||||
plat_joystick_state[c].axis[7].id = 7;
|
||||
|
||||
plat_joystick_state[c].nr_buttons = 12;
|
||||
memcpy(plat_joystick_state[c].button[0].name, XINPUT_NAME_A, sizeof(XINPUT_NAME_A));
|
||||
memcpy(plat_joystick_state[c].button[1].name, XINPUT_NAME_B, sizeof(XINPUT_NAME_B));
|
||||
memcpy(plat_joystick_state[c].button[2].name, XINPUT_NAME_X, sizeof(XINPUT_NAME_X));
|
||||
memcpy(plat_joystick_state[c].button[3].name, XINPUT_NAME_Y, sizeof(XINPUT_NAME_Y));
|
||||
memcpy(plat_joystick_state[c].button[4].name, XINPUT_NAME_LB, sizeof(XINPUT_NAME_LB));
|
||||
memcpy(plat_joystick_state[c].button[5].name, XINPUT_NAME_RB, sizeof(XINPUT_NAME_RB));
|
||||
memcpy(plat_joystick_state[c].button[6].name, XINPUT_NAME_LT, sizeof(XINPUT_NAME_LT));
|
||||
memcpy(plat_joystick_state[c].button[7].name, XINPUT_NAME_RT, sizeof(XINPUT_NAME_RT));
|
||||
memcpy(plat_joystick_state[c].button[8].name, XINPUT_NAME_BACK, sizeof(XINPUT_NAME_BACK));
|
||||
memcpy(plat_joystick_state[c].button[9].name, XINPUT_NAME_START, sizeof(XINPUT_NAME_START));
|
||||
memcpy(plat_joystick_state[c].button[10].name, XINPUT_NAME_LS, sizeof(XINPUT_NAME_LS));
|
||||
memcpy(plat_joystick_state[c].button[11].name, XINPUT_NAME_RS, sizeof(XINPUT_NAME_RS));
|
||||
plat_joystick_state[c].nr_buttons = 12;
|
||||
memcpy(plat_joystick_state[c].button[0].name, XINPUT_NAME_A, sizeof(XINPUT_NAME_A));
|
||||
memcpy(plat_joystick_state[c].button[1].name, XINPUT_NAME_B, sizeof(XINPUT_NAME_B));
|
||||
memcpy(plat_joystick_state[c].button[2].name, XINPUT_NAME_X, sizeof(XINPUT_NAME_X));
|
||||
memcpy(plat_joystick_state[c].button[3].name, XINPUT_NAME_Y, sizeof(XINPUT_NAME_Y));
|
||||
memcpy(plat_joystick_state[c].button[4].name, XINPUT_NAME_LB, sizeof(XINPUT_NAME_LB));
|
||||
memcpy(plat_joystick_state[c].button[5].name, XINPUT_NAME_RB, sizeof(XINPUT_NAME_RB));
|
||||
memcpy(plat_joystick_state[c].button[6].name, XINPUT_NAME_LT, sizeof(XINPUT_NAME_LT));
|
||||
memcpy(plat_joystick_state[c].button[7].name, XINPUT_NAME_RT, sizeof(XINPUT_NAME_RT));
|
||||
memcpy(plat_joystick_state[c].button[8].name, XINPUT_NAME_BACK, sizeof(XINPUT_NAME_BACK));
|
||||
memcpy(plat_joystick_state[c].button[9].name, XINPUT_NAME_START, sizeof(XINPUT_NAME_START));
|
||||
memcpy(plat_joystick_state[c].button[10].name, XINPUT_NAME_LS, sizeof(XINPUT_NAME_LS));
|
||||
memcpy(plat_joystick_state[c].button[11].name, XINPUT_NAME_RS, sizeof(XINPUT_NAME_RS));
|
||||
|
||||
plat_joystick_state[c].nr_povs = 0;
|
||||
plat_joystick_state[c].nr_povs = 0;
|
||||
|
||||
joysticks_present++;
|
||||
}
|
||||
joystick_log("joystick_init: joysticks_present=%i\n", joysticks_present);
|
||||
joysticks_present++;
|
||||
}
|
||||
joystick_log("joystick_init: joysticks_present=%i\n", joysticks_present);
|
||||
}
|
||||
|
||||
void joystick_close()
|
||||
void
|
||||
joystick_close()
|
||||
{
|
||||
}
|
||||
|
||||
void joystick_poll(void)
|
||||
void
|
||||
joystick_poll(void)
|
||||
{
|
||||
for (int c=0; c<joysticks_present; c++) {
|
||||
int value = XInputGetState(c, &controllers[c]);
|
||||
if (value != ERROR_SUCCESS) continue;
|
||||
for (int c = 0; c < joysticks_present; c++) {
|
||||
int value = XInputGetState(c, &controllers[c]);
|
||||
if (value != ERROR_SUCCESS)
|
||||
continue;
|
||||
|
||||
plat_joystick_state[c].a[0] = controllers[c].Gamepad.sThumbLX;
|
||||
plat_joystick_state[c].a[1] = - controllers[c].Gamepad.sThumbLY;
|
||||
plat_joystick_state[c].a[3] = controllers[c].Gamepad.sThumbRX;
|
||||
plat_joystick_state[c].a[4] = - controllers[c].Gamepad.sThumbRY;
|
||||
plat_joystick_state[c].a[6] = (double)controllers[c].Gamepad.bLeftTrigger / 255 * 32767;
|
||||
plat_joystick_state[c].a[7] = (double)controllers[c].Gamepad.bRightTrigger / 255 * 32767;
|
||||
plat_joystick_state[c].a[0] = controllers[c].Gamepad.sThumbLX;
|
||||
plat_joystick_state[c].a[1] = -controllers[c].Gamepad.sThumbLY;
|
||||
plat_joystick_state[c].a[3] = controllers[c].Gamepad.sThumbRX;
|
||||
plat_joystick_state[c].a[4] = -controllers[c].Gamepad.sThumbRY;
|
||||
plat_joystick_state[c].a[6] = (double) controllers[c].Gamepad.bLeftTrigger / 255 * 32767;
|
||||
plat_joystick_state[c].a[7] = (double) controllers[c].Gamepad.bRightTrigger / 255 * 32767;
|
||||
|
||||
plat_joystick_state[c].b[0] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_A) ? 128 : 0;
|
||||
plat_joystick_state[c].b[1] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_B) ? 128 : 0;
|
||||
plat_joystick_state[c].b[2] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_X) ? 128 : 0;
|
||||
plat_joystick_state[c].b[3] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_Y) ? 128 : 0;
|
||||
plat_joystick_state[c].b[4] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) ? 128 : 0;
|
||||
plat_joystick_state[c].b[5] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER) ? 128 : 0;
|
||||
plat_joystick_state[c].b[6] = (controllers[c].Gamepad.bLeftTrigger > 127) ? 128 : 0;
|
||||
plat_joystick_state[c].b[7] = (controllers[c].Gamepad.bRightTrigger > 127) ? 128 : 0;
|
||||
plat_joystick_state[c].b[8] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_BACK) ? 128 : 0;
|
||||
plat_joystick_state[c].b[9] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_START) ? 128 : 0;
|
||||
plat_joystick_state[c].b[10] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB) ? 128 : 0;
|
||||
plat_joystick_state[c].b[11] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) ? 128 : 0;
|
||||
plat_joystick_state[c].b[0] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_A) ? 128 : 0;
|
||||
plat_joystick_state[c].b[1] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_B) ? 128 : 0;
|
||||
plat_joystick_state[c].b[2] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_X) ? 128 : 0;
|
||||
plat_joystick_state[c].b[3] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_Y) ? 128 : 0;
|
||||
plat_joystick_state[c].b[4] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) ? 128 : 0;
|
||||
plat_joystick_state[c].b[5] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER) ? 128 : 0;
|
||||
plat_joystick_state[c].b[6] = (controllers[c].Gamepad.bLeftTrigger > 127) ? 128 : 0;
|
||||
plat_joystick_state[c].b[7] = (controllers[c].Gamepad.bRightTrigger > 127) ? 128 : 0;
|
||||
plat_joystick_state[c].b[8] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_BACK) ? 128 : 0;
|
||||
plat_joystick_state[c].b[9] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_START) ? 128 : 0;
|
||||
plat_joystick_state[c].b[10] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB) ? 128 : 0;
|
||||
plat_joystick_state[c].b[11] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) ? 128 : 0;
|
||||
|
||||
int dpad_x = 0, dpad_y = 0;
|
||||
if (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP)
|
||||
dpad_y-=32767;
|
||||
if (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN)
|
||||
dpad_y+=32767;
|
||||
if (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT)
|
||||
dpad_x-=32767;
|
||||
if (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT)
|
||||
dpad_x+=32767;
|
||||
int dpad_x = 0, dpad_y = 0;
|
||||
if (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP)
|
||||
dpad_y -= 32767;
|
||||
if (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN)
|
||||
dpad_y += 32767;
|
||||
if (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT)
|
||||
dpad_x -= 32767;
|
||||
if (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT)
|
||||
dpad_x += 32767;
|
||||
|
||||
plat_joystick_state[c].a[2] = dpad_x;
|
||||
plat_joystick_state[c].a[5] = dpad_y;
|
||||
plat_joystick_state[c].a[2] = dpad_x;
|
||||
plat_joystick_state[c].a[5] = dpad_y;
|
||||
|
||||
for (int a=0; a<8; a++) {
|
||||
if (plat_joystick_state[c].a[a] == -32768)
|
||||
plat_joystick_state[c].a[a] = -32767;
|
||||
if (plat_joystick_state[c].a[a] == 32768)
|
||||
plat_joystick_state[c].a[a] = 32767;
|
||||
}
|
||||
for (int a = 0; a < 8; a++) {
|
||||
if (plat_joystick_state[c].a[a] == -32768)
|
||||
plat_joystick_state[c].a[a] = -32767;
|
||||
if (plat_joystick_state[c].a[a] == 32768)
|
||||
plat_joystick_state[c].a[a] = 32767;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int joystick_get_axis(int joystick_nr, int mapping)
|
||||
static int
|
||||
joystick_get_axis(int joystick_nr, int mapping)
|
||||
{
|
||||
if (mapping & POV_X)
|
||||
{
|
||||
int pov = plat_joystick_state[joystick_nr].p[mapping & 3];
|
||||
if (mapping & POV_X) {
|
||||
int pov = plat_joystick_state[joystick_nr].p[mapping & 3];
|
||||
|
||||
if (LOWORD(pov) == 0xFFFF)
|
||||
return 0;
|
||||
else
|
||||
return sin((2*M_PI * (double)pov) / 36000.0) * 32767;
|
||||
}
|
||||
else if (mapping & POV_Y)
|
||||
{
|
||||
int pov = plat_joystick_state[joystick_nr].p[mapping & 3];
|
||||
|
||||
if (LOWORD(pov) == 0xFFFF)
|
||||
return 0;
|
||||
else
|
||||
return -cos((2*M_PI * (double)pov) / 36000.0) * 32767;
|
||||
}
|
||||
if (LOWORD(pov) == 0xFFFF)
|
||||
return 0;
|
||||
else
|
||||
return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id];
|
||||
return sin((2 * M_PI * (double) pov) / 36000.0) * 32767;
|
||||
} else if (mapping & POV_Y) {
|
||||
int pov = plat_joystick_state[joystick_nr].p[mapping & 3];
|
||||
|
||||
if (LOWORD(pov) == 0xFFFF)
|
||||
return 0;
|
||||
else
|
||||
return -cos((2 * M_PI * (double) pov) / 36000.0) * 32767;
|
||||
} else
|
||||
return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id];
|
||||
}
|
||||
|
||||
void joystick_process(void)
|
||||
void
|
||||
joystick_process(void)
|
||||
{
|
||||
int c, d;
|
||||
int c, d;
|
||||
|
||||
if (!joystick_type) return;
|
||||
if (!joystick_type)
|
||||
return;
|
||||
|
||||
joystick_poll();
|
||||
joystick_poll();
|
||||
|
||||
for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++)
|
||||
{
|
||||
if (joystick_state[c].plat_joystick_nr)
|
||||
{
|
||||
int joystick_nr = joystick_state[c].plat_joystick_nr - 1;
|
||||
for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) {
|
||||
if (joystick_state[c].plat_joystick_nr) {
|
||||
int joystick_nr = joystick_state[c].plat_joystick_nr - 1;
|
||||
|
||||
for (d = 0; d < joystick_get_axis_count(joystick_type); d++)
|
||||
joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]);
|
||||
for (d = 0; d < joystick_get_button_count(joystick_type); d++)
|
||||
joystick_state[c].button[d] = plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]];
|
||||
for (d = 0; d < joystick_get_axis_count(joystick_type); d++)
|
||||
joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]);
|
||||
for (d = 0; d < joystick_get_button_count(joystick_type); d++)
|
||||
joystick_state[c].button[d] = plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]];
|
||||
|
||||
for (d = 0; d < joystick_get_pov_count(joystick_type); d++)
|
||||
{
|
||||
int x, y;
|
||||
double angle, magnitude;
|
||||
for (d = 0; d < joystick_get_pov_count(joystick_type); d++) {
|
||||
int x, y;
|
||||
double angle, magnitude;
|
||||
|
||||
x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]);
|
||||
y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]);
|
||||
x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]);
|
||||
y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]);
|
||||
|
||||
angle = (atan2((double)y, (double)x) * 360.0) / (2*M_PI);
|
||||
magnitude = sqrt((double)x*(double)x + (double)y*(double)y);
|
||||
angle = (atan2((double) y, (double) x) * 360.0) / (2 * M_PI);
|
||||
magnitude = sqrt((double) x * (double) x + (double) y * (double) y);
|
||||
|
||||
if (magnitude < 16384)
|
||||
joystick_state[c].pov[d] = -1;
|
||||
else
|
||||
joystick_state[c].pov[d] = ((int)angle + 90 + 360) % 360;
|
||||
}
|
||||
}
|
||||
if (magnitude < 16384)
|
||||
joystick_state[c].pov[d] = -1;
|
||||
else
|
||||
{
|
||||
for (d = 0; d < joystick_get_axis_count(joystick_type); d++)
|
||||
joystick_state[c].axis[d] = 0;
|
||||
for (d = 0; d < joystick_get_button_count(joystick_type); d++)
|
||||
joystick_state[c].button[d] = 0;
|
||||
for (d = 0; d < joystick_get_pov_count(joystick_type); d++)
|
||||
joystick_state[c].pov[d] = -1;
|
||||
}
|
||||
joystick_state[c].pov[d] = ((int) angle + 90 + 360) % 360;
|
||||
}
|
||||
} else {
|
||||
for (d = 0; d < joystick_get_axis_count(joystick_type); d++)
|
||||
joystick_state[c].axis[d] = 0;
|
||||
for (d = 0; d < joystick_get_button_count(joystick_type); d++)
|
||||
joystick_state[c].button[d] = 0;
|
||||
for (d = 0; d < joystick_get_pov_count(joystick_type); d++)
|
||||
joystick_state[c].pov[d] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void win_joystick_handle(PRAWINPUT raw) {}
|
||||
void
|
||||
win_joystick_handle(PRAWINPUT raw)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -14,151 +14,134 @@
|
||||
#include <86box/plat.h>
|
||||
#include <86box/win.h>
|
||||
|
||||
|
||||
static int joystick_nr;
|
||||
static int joystick_config_type;
|
||||
#define AXIS_STRINGS_MAX 3
|
||||
static char *axis_strings[AXIS_STRINGS_MAX] = {"X Axis", "Y Axis", "Z Axis"};
|
||||
static char *axis_strings[AXIS_STRINGS_MAX] = { "X Axis", "Y Axis", "Z Axis" };
|
||||
|
||||
static uint8_t joystickconfig_changed = 0;
|
||||
|
||||
|
||||
static void rebuild_axis_button_selections(HWND hdlg)
|
||||
static void
|
||||
rebuild_axis_button_selections(HWND hdlg)
|
||||
{
|
||||
int id = IDC_CONFIG_BASE + 2;
|
||||
HWND h;
|
||||
int joystick;
|
||||
int c, d;
|
||||
char s[269];
|
||||
int id = IDC_CONFIG_BASE + 2;
|
||||
HWND h;
|
||||
int joystick;
|
||||
int c, d;
|
||||
char s[269];
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_CONFIG_BASE);
|
||||
joystick = SendMessage(h, CB_GETCURSEL, 0, 0);
|
||||
h = GetDlgItem(hdlg, IDC_CONFIG_BASE);
|
||||
joystick = SendMessage(h, CB_GETCURSEL, 0, 0);
|
||||
|
||||
for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++)
|
||||
{
|
||||
int sel = c;
|
||||
for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++) {
|
||||
int sel = c;
|
||||
|
||||
h = GetDlgItem(hdlg, id);
|
||||
SendMessage(h, CB_RESETCONTENT, 0, 0);
|
||||
h = GetDlgItem(hdlg, id);
|
||||
SendMessage(h, CB_RESETCONTENT, 0, 0);
|
||||
|
||||
if (joystick)
|
||||
{
|
||||
for (d = 0; d < plat_joystick_state[joystick-1].nr_axes; d++)
|
||||
{
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)plat_joystick_state[joystick-1].axis[d].name);
|
||||
if (c < AXIS_STRINGS_MAX)
|
||||
{
|
||||
if (!stricmp(axis_strings[c], plat_joystick_state[joystick-1].axis[d].name))
|
||||
sel = d;
|
||||
}
|
||||
}
|
||||
for (d = 0; d < plat_joystick_state[joystick-1].nr_povs; d++)
|
||||
{
|
||||
sprintf(s, "%s (X axis)", plat_joystick_state[joystick-1].pov[d].name);
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s);
|
||||
sprintf(s, "%s (Y axis)", plat_joystick_state[joystick-1].pov[d].name);
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s);
|
||||
}
|
||||
for (d = 0; d < plat_joystick_state[joystick - 1].nr_sliders; d++)
|
||||
{
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)plat_joystick_state[joystick - 1].slider[d].name);
|
||||
}
|
||||
SendMessage(h, CB_SETCURSEL, sel, 0);
|
||||
EnableWindow(h, TRUE);
|
||||
if (joystick) {
|
||||
for (d = 0; d < plat_joystick_state[joystick - 1].nr_axes; d++) {
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) plat_joystick_state[joystick - 1].axis[d].name);
|
||||
if (c < AXIS_STRINGS_MAX) {
|
||||
if (!stricmp(axis_strings[c], plat_joystick_state[joystick - 1].axis[d].name))
|
||||
sel = d;
|
||||
}
|
||||
else
|
||||
EnableWindow(h, FALSE);
|
||||
}
|
||||
for (d = 0; d < plat_joystick_state[joystick - 1].nr_povs; d++) {
|
||||
sprintf(s, "%s (X axis)", plat_joystick_state[joystick - 1].pov[d].name);
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) s);
|
||||
sprintf(s, "%s (Y axis)", plat_joystick_state[joystick - 1].pov[d].name);
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) s);
|
||||
}
|
||||
for (d = 0; d < plat_joystick_state[joystick - 1].nr_sliders; d++) {
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) plat_joystick_state[joystick - 1].slider[d].name);
|
||||
}
|
||||
SendMessage(h, CB_SETCURSEL, sel, 0);
|
||||
EnableWindow(h, TRUE);
|
||||
} else
|
||||
EnableWindow(h, FALSE);
|
||||
|
||||
id += 2;
|
||||
}
|
||||
id += 2;
|
||||
}
|
||||
|
||||
for (c = 0; c < joystick_get_button_count(joystick_config_type); c++)
|
||||
{
|
||||
h = GetDlgItem(hdlg, id);
|
||||
SendMessage(h, CB_RESETCONTENT, 0, 0);
|
||||
for (c = 0; c < joystick_get_button_count(joystick_config_type); c++) {
|
||||
h = GetDlgItem(hdlg, id);
|
||||
SendMessage(h, CB_RESETCONTENT, 0, 0);
|
||||
|
||||
if (joystick)
|
||||
{
|
||||
for (d = 0; d < plat_joystick_state[joystick-1].nr_buttons; d++)
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)plat_joystick_state[joystick-1].button[d].name);
|
||||
SendMessage(h, CB_SETCURSEL, c, 0);
|
||||
EnableWindow(h, TRUE);
|
||||
}
|
||||
else
|
||||
EnableWindow(h, FALSE);
|
||||
if (joystick) {
|
||||
for (d = 0; d < plat_joystick_state[joystick - 1].nr_buttons; d++)
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) plat_joystick_state[joystick - 1].button[d].name);
|
||||
SendMessage(h, CB_SETCURSEL, c, 0);
|
||||
EnableWindow(h, TRUE);
|
||||
} else
|
||||
EnableWindow(h, FALSE);
|
||||
|
||||
id += 2;
|
||||
}
|
||||
id += 2;
|
||||
}
|
||||
|
||||
for (c = 0; c < joystick_get_pov_count(joystick_config_type)*2; c++)
|
||||
{
|
||||
int sel = c;
|
||||
for (c = 0; c < joystick_get_pov_count(joystick_config_type) * 2; c++) {
|
||||
int sel = c;
|
||||
|
||||
h = GetDlgItem(hdlg, id);
|
||||
SendMessage(h, CB_RESETCONTENT, 0, 0);
|
||||
h = GetDlgItem(hdlg, id);
|
||||
SendMessage(h, CB_RESETCONTENT, 0, 0);
|
||||
|
||||
if (joystick)
|
||||
{
|
||||
for (d = 0; d < plat_joystick_state[joystick-1].nr_povs; d++)
|
||||
{
|
||||
sprintf(s, "%s (X axis)", plat_joystick_state[joystick-1].pov[d].name);
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s);
|
||||
sprintf(s, "%s (Y axis)", plat_joystick_state[joystick-1].pov[d].name);
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s);
|
||||
}
|
||||
for (d = 0; d < plat_joystick_state[joystick-1].nr_axes; d++)
|
||||
{
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)plat_joystick_state[joystick-1].axis[d].name);
|
||||
}
|
||||
SendMessage(h, CB_SETCURSEL, sel, 0);
|
||||
EnableWindow(h, TRUE);
|
||||
}
|
||||
else
|
||||
EnableWindow(h, FALSE);
|
||||
|
||||
id += 2;
|
||||
}
|
||||
if (joystick) {
|
||||
for (d = 0; d < plat_joystick_state[joystick - 1].nr_povs; d++) {
|
||||
sprintf(s, "%s (X axis)", plat_joystick_state[joystick - 1].pov[d].name);
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) s);
|
||||
sprintf(s, "%s (Y axis)", plat_joystick_state[joystick - 1].pov[d].name);
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) s);
|
||||
}
|
||||
for (d = 0; d < plat_joystick_state[joystick - 1].nr_axes; d++) {
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) plat_joystick_state[joystick - 1].axis[d].name);
|
||||
}
|
||||
SendMessage(h, CB_SETCURSEL, sel, 0);
|
||||
EnableWindow(h, TRUE);
|
||||
} else
|
||||
EnableWindow(h, FALSE);
|
||||
|
||||
id += 2;
|
||||
}
|
||||
}
|
||||
|
||||
static int get_axis(HWND hdlg, int id)
|
||||
static int
|
||||
get_axis(HWND hdlg, int id)
|
||||
{
|
||||
HWND h = GetDlgItem(hdlg, id);
|
||||
int axis_sel = SendMessage(h, CB_GETCURSEL, 0, 0);
|
||||
int nr_axes = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr-1].nr_axes;
|
||||
int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_povs;
|
||||
HWND h = GetDlgItem(hdlg, id);
|
||||
int axis_sel = SendMessage(h, CB_GETCURSEL, 0, 0);
|
||||
int nr_axes = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_axes;
|
||||
int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_povs;
|
||||
|
||||
if (axis_sel < nr_axes)
|
||||
return axis_sel;
|
||||
if (axis_sel < nr_axes)
|
||||
return axis_sel;
|
||||
|
||||
axis_sel -= nr_axes;
|
||||
if (axis_sel < nr_povs * 2)
|
||||
{
|
||||
if (axis_sel & 1)
|
||||
return POV_Y | (axis_sel >> 1);
|
||||
else
|
||||
return POV_X | (axis_sel >> 1);
|
||||
}
|
||||
axis_sel -= nr_povs;
|
||||
axis_sel -= nr_axes;
|
||||
if (axis_sel < nr_povs * 2) {
|
||||
if (axis_sel & 1)
|
||||
return POV_Y | (axis_sel >> 1);
|
||||
else
|
||||
return POV_X | (axis_sel >> 1);
|
||||
}
|
||||
axis_sel -= nr_povs;
|
||||
|
||||
return SLIDER | (axis_sel >> 1);
|
||||
return SLIDER | (axis_sel >> 1);
|
||||
}
|
||||
|
||||
static int get_pov(HWND hdlg, int id)
|
||||
static int
|
||||
get_pov(HWND hdlg, int id)
|
||||
{
|
||||
HWND h = GetDlgItem(hdlg, id);
|
||||
int axis_sel = SendMessage(h, CB_GETCURSEL, 0, 0);
|
||||
int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr-1].nr_povs*2;
|
||||
HWND h = GetDlgItem(hdlg, id);
|
||||
int axis_sel = SendMessage(h, CB_GETCURSEL, 0, 0);
|
||||
int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_povs * 2;
|
||||
|
||||
if (axis_sel < nr_povs)
|
||||
{
|
||||
if (axis_sel & 1)
|
||||
return POV_Y | (axis_sel >> 1);
|
||||
else
|
||||
return POV_X | (axis_sel >> 1);
|
||||
}
|
||||
if (axis_sel < nr_povs) {
|
||||
if (axis_sel & 1)
|
||||
return POV_Y | (axis_sel >> 1);
|
||||
else
|
||||
return POV_X | (axis_sel >> 1);
|
||||
}
|
||||
|
||||
return axis_sel - nr_povs;
|
||||
return axis_sel - nr_povs;
|
||||
}
|
||||
|
||||
#if defined(__amd64__) || defined(__aarch64__)
|
||||
@@ -168,175 +151,210 @@ static BOOL CALLBACK
|
||||
#endif
|
||||
joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
HWND h;
|
||||
int c;
|
||||
int id;
|
||||
int joystick;
|
||||
int nr_axes;
|
||||
int nr_povs;
|
||||
int mapping;
|
||||
HWND h;
|
||||
int c;
|
||||
int id;
|
||||
int joystick;
|
||||
int nr_axes;
|
||||
int nr_povs;
|
||||
int mapping;
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
h = GetDlgItem(hdlg, IDC_CONFIG_BASE);
|
||||
id = IDC_CONFIG_BASE + 2;
|
||||
joystick = joystick_state[joystick_nr].plat_joystick_nr;
|
||||
switch (message) {
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
h = GetDlgItem(hdlg, IDC_CONFIG_BASE);
|
||||
id = IDC_CONFIG_BASE + 2;
|
||||
joystick = joystick_state[joystick_nr].plat_joystick_nr;
|
||||
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"None");
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) "None");
|
||||
|
||||
for (c = 0; c < joysticks_present; c++)
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)plat_joystick_state[c].name);
|
||||
for (c = 0; c < joysticks_present; c++)
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) plat_joystick_state[c].name);
|
||||
|
||||
SendMessage(h, CB_SETCURSEL, joystick, 0);
|
||||
SendMessage(h, CB_SETCURSEL, joystick, 0);
|
||||
|
||||
rebuild_axis_button_selections(hdlg);
|
||||
|
||||
if (joystick_state[joystick_nr].plat_joystick_nr) {
|
||||
nr_axes = plat_joystick_state[joystick - 1].nr_axes;
|
||||
nr_povs = plat_joystick_state[joystick - 1].nr_povs;
|
||||
|
||||
for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++) {
|
||||
int mapping = joystick_state[joystick_nr].axis_mapping[c];
|
||||
|
||||
h = GetDlgItem(hdlg, id);
|
||||
if (mapping & POV_X)
|
||||
SendMessage(h, CB_SETCURSEL, nr_axes + (mapping & 3) * 2, 0);
|
||||
else if (mapping & POV_Y)
|
||||
SendMessage(h, CB_SETCURSEL, nr_axes + (mapping & 3) * 2 + 1, 0);
|
||||
else if (mapping & SLIDER)
|
||||
SendMessage(h, CB_SETCURSEL, nr_axes + nr_povs * 2 + (mapping & 3), 0);
|
||||
else
|
||||
SendMessage(h, CB_SETCURSEL, mapping, 0);
|
||||
id += 2;
|
||||
}
|
||||
for (c = 0; c < joystick_get_button_count(joystick_config_type); c++) {
|
||||
h = GetDlgItem(hdlg, id);
|
||||
SendMessage(h, CB_SETCURSEL, joystick_state[joystick_nr].button_mapping[c], 0);
|
||||
id += 2;
|
||||
}
|
||||
for (c = 0; c < joystick_get_pov_count(joystick_config_type); c++) {
|
||||
h = GetDlgItem(hdlg, id);
|
||||
mapping = joystick_state[joystick_nr].pov_mapping[c][0];
|
||||
if (mapping & POV_X)
|
||||
SendMessage(h, CB_SETCURSEL, (mapping & 3) * 2, 0);
|
||||
else if (mapping & POV_Y)
|
||||
SendMessage(h, CB_SETCURSEL, (mapping & 3) * 2 + 1, 0);
|
||||
else
|
||||
SendMessage(h, CB_SETCURSEL, mapping + nr_povs * 2, 0);
|
||||
id += 2;
|
||||
h = GetDlgItem(hdlg, id);
|
||||
mapping = joystick_state[joystick_nr].pov_mapping[c][1];
|
||||
if (mapping & POV_X)
|
||||
SendMessage(h, CB_SETCURSEL, (mapping & 3) * 2, 0);
|
||||
else if (mapping & POV_Y)
|
||||
SendMessage(h, CB_SETCURSEL, (mapping & 3) * 2 + 1, 0);
|
||||
else
|
||||
SendMessage(h, CB_SETCURSEL, mapping + nr_povs * 2, 0);
|
||||
id += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam)) {
|
||||
case IDC_CONFIG_BASE:
|
||||
if (HIWORD(wParam) == CBN_SELCHANGE)
|
||||
rebuild_axis_button_selections(hdlg);
|
||||
break;
|
||||
|
||||
if (joystick_state[joystick_nr].plat_joystick_nr)
|
||||
{
|
||||
nr_axes = plat_joystick_state[joystick-1].nr_axes;
|
||||
nr_povs = plat_joystick_state[joystick-1].nr_povs;
|
||||
case IDOK:
|
||||
{
|
||||
id = IDC_CONFIG_BASE + 2;
|
||||
|
||||
for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++)
|
||||
{
|
||||
int mapping = joystick_state[joystick_nr].axis_mapping[c];
|
||||
h = GetDlgItem(hdlg, IDC_CONFIG_BASE);
|
||||
joystick_state[joystick_nr].plat_joystick_nr = SendMessage(h, CB_GETCURSEL, 0, 0);
|
||||
|
||||
h = GetDlgItem(hdlg, id);
|
||||
if (mapping & POV_X)
|
||||
SendMessage(h, CB_SETCURSEL, nr_axes + (mapping & 3)*2, 0);
|
||||
else if (mapping & POV_Y)
|
||||
SendMessage(h, CB_SETCURSEL, nr_axes + (mapping & 3)*2 + 1, 0);
|
||||
else if (mapping & SLIDER)
|
||||
SendMessage(h, CB_SETCURSEL, nr_axes + nr_povs * 2 + (mapping & 3), 0);
|
||||
else
|
||||
SendMessage(h, CB_SETCURSEL, mapping, 0);
|
||||
id += 2;
|
||||
}
|
||||
for (c = 0; c < joystick_get_button_count(joystick_config_type); c++)
|
||||
{
|
||||
h = GetDlgItem(hdlg, id);
|
||||
SendMessage(h, CB_SETCURSEL, joystick_state[joystick_nr].button_mapping[c], 0);
|
||||
id += 2;
|
||||
}
|
||||
for (c = 0; c < joystick_get_pov_count(joystick_config_type); c++)
|
||||
{
|
||||
h = GetDlgItem(hdlg, id);
|
||||
mapping = joystick_state[joystick_nr].pov_mapping[c][0];
|
||||
if (mapping & POV_X)
|
||||
SendMessage(h, CB_SETCURSEL, (mapping & 3)*2, 0);
|
||||
else if (mapping & POV_Y)
|
||||
SendMessage(h, CB_SETCURSEL, (mapping & 3)*2 + 1, 0);
|
||||
else
|
||||
SendMessage(h, CB_SETCURSEL, mapping + nr_povs*2, 0);
|
||||
id += 2;
|
||||
h = GetDlgItem(hdlg, id);
|
||||
mapping = joystick_state[joystick_nr].pov_mapping[c][1];
|
||||
if (mapping & POV_X)
|
||||
SendMessage(h, CB_SETCURSEL, (mapping & 3)*2, 0);
|
||||
else if (mapping & POV_Y)
|
||||
SendMessage(h, CB_SETCURSEL, (mapping & 3)*2 + 1, 0);
|
||||
else
|
||||
SendMessage(h, CB_SETCURSEL, mapping + nr_povs*2, 0);
|
||||
id += 2;
|
||||
}
|
||||
if (joystick_state[joystick_nr].plat_joystick_nr) {
|
||||
for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++) {
|
||||
joystick_state[joystick_nr].axis_mapping[c] = get_axis(hdlg, id);
|
||||
id += 2;
|
||||
}
|
||||
for (c = 0; c < joystick_get_button_count(joystick_config_type); c++) {
|
||||
h = GetDlgItem(hdlg, id);
|
||||
joystick_state[joystick_nr].button_mapping[c] = SendMessage(h, CB_GETCURSEL, 0, 0);
|
||||
id += 2;
|
||||
}
|
||||
for (c = 0; c < joystick_get_button_count(joystick_config_type); c++) {
|
||||
h = GetDlgItem(hdlg, id);
|
||||
joystick_state[joystick_nr].pov_mapping[c][0] = get_pov(hdlg, id);
|
||||
id += 2;
|
||||
h = GetDlgItem(hdlg, id);
|
||||
joystick_state[joystick_nr].pov_mapping[c][1] = get_pov(hdlg, id);
|
||||
id += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDC_CONFIG_BASE:
|
||||
if (HIWORD(wParam) == CBN_SELCHANGE)
|
||||
rebuild_axis_button_selections(hdlg);
|
||||
break;
|
||||
|
||||
case IDOK:
|
||||
{
|
||||
id = IDC_CONFIG_BASE + 2;
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_CONFIG_BASE);
|
||||
joystick_state[joystick_nr].plat_joystick_nr = SendMessage(h, CB_GETCURSEL, 0, 0);
|
||||
|
||||
if (joystick_state[joystick_nr].plat_joystick_nr)
|
||||
{
|
||||
for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++)
|
||||
{
|
||||
joystick_state[joystick_nr].axis_mapping[c] = get_axis(hdlg, id);
|
||||
id += 2;
|
||||
}
|
||||
for (c = 0; c < joystick_get_button_count(joystick_config_type); c++)
|
||||
{
|
||||
h = GetDlgItem(hdlg, id);
|
||||
joystick_state[joystick_nr].button_mapping[c] = SendMessage(h, CB_GETCURSEL, 0, 0);
|
||||
id += 2;
|
||||
}
|
||||
for (c = 0; c < joystick_get_button_count(joystick_config_type); c++)
|
||||
{
|
||||
h = GetDlgItem(hdlg, id);
|
||||
joystick_state[joystick_nr].pov_mapping[c][0] = get_pov(hdlg, id);
|
||||
id += 2;
|
||||
h = GetDlgItem(hdlg, id);
|
||||
joystick_state[joystick_nr].pov_mapping[c][1] = get_pov(hdlg, id);
|
||||
id += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
joystickconfig_changed = 1;
|
||||
EndDialog(hdlg, 0);
|
||||
return TRUE;
|
||||
case IDCANCEL:
|
||||
joystickconfig_changed = 0;
|
||||
EndDialog(hdlg, 0);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
joystickconfig_changed = 1;
|
||||
EndDialog(hdlg, 0);
|
||||
return TRUE;
|
||||
case IDCANCEL:
|
||||
joystickconfig_changed = 0;
|
||||
EndDialog(hdlg, 0);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
uint8_t joystickconfig_open(HWND hwnd, int joy_nr, int type)
|
||||
uint8_t
|
||||
joystickconfig_open(HWND hwnd, int joy_nr, int type)
|
||||
{
|
||||
uint16_t *data_block = malloc(16384);
|
||||
uint16_t *data;
|
||||
DLGTEMPLATE *dlg = (DLGTEMPLATE *)data_block;
|
||||
DLGITEMTEMPLATE *item;
|
||||
int y = 10;
|
||||
int id = IDC_CONFIG_BASE;
|
||||
int c;
|
||||
char s[269];
|
||||
uint16_t *data_block = malloc(16384);
|
||||
uint16_t *data;
|
||||
DLGTEMPLATE *dlg = (DLGTEMPLATE *) data_block;
|
||||
DLGITEMTEMPLATE *item;
|
||||
int y = 10;
|
||||
int id = IDC_CONFIG_BASE;
|
||||
int c;
|
||||
char s[269];
|
||||
|
||||
joystickconfig_changed = 0;
|
||||
joystickconfig_changed = 0;
|
||||
|
||||
joystick_nr = joy_nr;
|
||||
joystick_config_type = type;
|
||||
joystick_nr = joy_nr;
|
||||
joystick_config_type = type;
|
||||
|
||||
memset(data_block, 0, 4096);
|
||||
memset(data_block, 0, 4096);
|
||||
|
||||
dlg->style = DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU;
|
||||
dlg->x = 10;
|
||||
dlg->y = 10;
|
||||
dlg->cx = 220;
|
||||
dlg->cy = 70;
|
||||
dlg->style = DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU;
|
||||
dlg->x = 10;
|
||||
dlg->y = 10;
|
||||
dlg->cx = 220;
|
||||
dlg->cy = 70;
|
||||
|
||||
data = (uint16_t *)(dlg + 1);
|
||||
data = (uint16_t *) (dlg + 1);
|
||||
|
||||
*data++ = 0; /*no menu*/
|
||||
*data++ = 0; /*predefined dialog box class*/
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "Joystick Configuration", -1, data, 50);
|
||||
*data++ = 0; /*no menu*/
|
||||
*data++ = 0; /*predefined dialog box class*/
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "Joystick Configuration", -1, data, 50);
|
||||
|
||||
*data++ = 9; /*Point*/
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "Segoe UI", -1, data, 50);
|
||||
*data++ = 9; /*Point*/
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "Segoe UI", -1, data, 50);
|
||||
|
||||
if (((uintptr_t)data) & 2)
|
||||
data++;
|
||||
if (((uintptr_t) data) & 2)
|
||||
data++;
|
||||
|
||||
/*Combo box*/
|
||||
item = (DLGITEMTEMPLATE *) data;
|
||||
item->x = 70;
|
||||
item->y = y;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 140;
|
||||
item->cy = 150;
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | WS_VSCROLL;
|
||||
|
||||
data = (uint16_t *) (item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0085; /* combo box class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "Device", -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((uintptr_t) data) & 2)
|
||||
data++;
|
||||
|
||||
/*Static text*/
|
||||
item = (DLGITEMTEMPLATE *) data;
|
||||
item->x = 10;
|
||||
item->y = y + 2;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 60;
|
||||
item->cy = 15;
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE;
|
||||
|
||||
data = (uint16_t *) (item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0082; /* static class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "Device", -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((uintptr_t) data) & 2)
|
||||
data++;
|
||||
|
||||
y += 20;
|
||||
|
||||
for (c = 0; c < joystick_get_axis_count(type); c++) {
|
||||
/*Combo box*/
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 70;
|
||||
item->y = y;
|
||||
item = (DLGITEMTEMPLATE *) data;
|
||||
item->x = 70;
|
||||
item->y = y;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 140;
|
||||
@@ -344,20 +362,20 @@ uint8_t joystickconfig_open(HWND hwnd, int joy_nr, int type)
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | WS_VSCROLL;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
data = (uint16_t *) (item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0085; /* combo box class */
|
||||
*data++ = 0x0085; /* combo box class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "Device", -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
data += MultiByteToWideChar(CP_ACP, 0, joystick_get_axis_name(type, c), -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((uintptr_t)data) & 2)
|
||||
data++;
|
||||
if (((uintptr_t) data) & 2)
|
||||
data++;
|
||||
|
||||
/*Static text*/
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 10;
|
||||
item->y = y + 2;
|
||||
item = (DLGITEMTEMPLATE *) data;
|
||||
item->x = 10;
|
||||
item->y = y + 2;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 60;
|
||||
@@ -365,204 +383,155 @@ uint8_t joystickconfig_open(HWND hwnd, int joy_nr, int type)
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
data = (uint16_t *) (item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0082; /* static class */
|
||||
*data++ = 0x0082; /* static class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "Device", -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
data += MultiByteToWideChar(CP_ACP, 0, joystick_get_axis_name(type, c), -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((uintptr_t)data) & 2)
|
||||
data++;
|
||||
if (((uintptr_t) data) & 2)
|
||||
data++;
|
||||
|
||||
y += 20;
|
||||
}
|
||||
|
||||
for (c = 0; c < joystick_get_button_count(type); c++) {
|
||||
/*Combo box*/
|
||||
item = (DLGITEMTEMPLATE *) data;
|
||||
item->x = 70;
|
||||
item->y = y;
|
||||
item->id = id++;
|
||||
|
||||
for (c = 0; c < joystick_get_axis_count(type); c++)
|
||||
{
|
||||
/*Combo box*/
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 70;
|
||||
item->y = y;
|
||||
item->id = id++;
|
||||
item->cx = 140;
|
||||
item->cy = 150;
|
||||
|
||||
item->cx = 140;
|
||||
item->cy = 150;
|
||||
item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | WS_VSCROLL;
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | WS_VSCROLL;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0085; /* combo box class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, joystick_get_axis_name(type, c), -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((uintptr_t)data) & 2)
|
||||
data++;
|
||||
|
||||
/*Static text*/
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 10;
|
||||
item->y = y + 2;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 60;
|
||||
item->cy = 15;
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0082; /* static class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, joystick_get_axis_name(type, c), -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((uintptr_t)data) & 2)
|
||||
data++;
|
||||
|
||||
y += 20;
|
||||
}
|
||||
|
||||
for (c = 0; c < joystick_get_button_count(type); c++)
|
||||
{
|
||||
/*Combo box*/
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 70;
|
||||
item->y = y;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 140;
|
||||
item->cy = 150;
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | WS_VSCROLL;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0085; /* combo box class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, joystick_get_button_name(type, c), -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((uintptr_t)data) & 2)
|
||||
data++;
|
||||
|
||||
/*Static text*/
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 10;
|
||||
item->y = y + 2;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 60;
|
||||
item->cy = 15;
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0082; /* static class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, joystick_get_button_name(type, c), -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((uintptr_t)data) & 2)
|
||||
data++;
|
||||
|
||||
y += 20;
|
||||
}
|
||||
|
||||
for (c = 0; c < joystick_get_pov_count(type)*2; c++)
|
||||
{
|
||||
/*Combo box*/
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 70;
|
||||
item->y = y;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 140;
|
||||
item->cy = 150;
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | WS_VSCROLL;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0085; /* combo box class */
|
||||
|
||||
if (c & 1)
|
||||
sprintf(s, "%s (Y axis)", joystick_get_pov_name(type, c/2));
|
||||
else
|
||||
sprintf(s, "%s (X axis)", joystick_get_pov_name(type, c/2));
|
||||
data += MultiByteToWideChar(CP_ACP, 0, s, -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((uintptr_t)data) & 2)
|
||||
data++;
|
||||
|
||||
/*Static text*/
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 10;
|
||||
item->y = y + 2;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 60;
|
||||
item->cy = 15;
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0082; /* static class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, s, -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((uintptr_t)data) & 2)
|
||||
data++;
|
||||
|
||||
y += 20;
|
||||
}
|
||||
|
||||
dlg->cdit = (id - IDC_CONFIG_BASE) + 2;
|
||||
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 100;
|
||||
item->y = y + 5;
|
||||
item->cx = 50;
|
||||
item->cy = 14;
|
||||
item->id = IDOK; /* OK button identifier */
|
||||
item->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
data = (uint16_t *) (item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0080; /* button class */
|
||||
*data++ = 0x0085; /* combo box class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "OK", -1, data, 50);
|
||||
*data++ = 0; /* no creation data */
|
||||
data += MultiByteToWideChar(CP_ACP, 0, joystick_get_button_name(type, c), -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((uintptr_t)data) & 2)
|
||||
data++;
|
||||
if (((uintptr_t) data) & 2)
|
||||
data++;
|
||||
|
||||
/*Static text*/
|
||||
item = (DLGITEMTEMPLATE *) data;
|
||||
item->x = 10;
|
||||
item->y = y + 2;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 60;
|
||||
item->cy = 15;
|
||||
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 160;
|
||||
item->y = y + 5;
|
||||
item->cx = 50;
|
||||
item->cy = 14;
|
||||
item->id = IDCANCEL; /* Cancel button identifier */
|
||||
item->style = WS_CHILD | WS_VISIBLE;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
data = (uint16_t *) (item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0080; /* button class */
|
||||
*data++ = 0x0082; /* static class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "Cancel", -1, data, 50);
|
||||
*data++ = 0; /* no creation data */
|
||||
data += MultiByteToWideChar(CP_ACP, 0, joystick_get_button_name(type, c), -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
dlg->cy = y + 25;
|
||||
if (((uintptr_t) data) & 2)
|
||||
data++;
|
||||
|
||||
DialogBoxIndirect(hinstance, dlg, hwnd, joystickconfig_dlgproc);
|
||||
y += 20;
|
||||
}
|
||||
|
||||
free(data_block);
|
||||
for (c = 0; c < joystick_get_pov_count(type) * 2; c++) {
|
||||
/*Combo box*/
|
||||
item = (DLGITEMTEMPLATE *) data;
|
||||
item->x = 70;
|
||||
item->y = y;
|
||||
item->id = id++;
|
||||
|
||||
return joystickconfig_changed;
|
||||
item->cx = 140;
|
||||
item->cy = 150;
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | WS_VSCROLL;
|
||||
|
||||
data = (uint16_t *) (item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0085; /* combo box class */
|
||||
|
||||
if (c & 1)
|
||||
sprintf(s, "%s (Y axis)", joystick_get_pov_name(type, c / 2));
|
||||
else
|
||||
sprintf(s, "%s (X axis)", joystick_get_pov_name(type, c / 2));
|
||||
data += MultiByteToWideChar(CP_ACP, 0, s, -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((uintptr_t) data) & 2)
|
||||
data++;
|
||||
|
||||
/*Static text*/
|
||||
item = (DLGITEMTEMPLATE *) data;
|
||||
item->x = 10;
|
||||
item->y = y + 2;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 60;
|
||||
item->cy = 15;
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE;
|
||||
|
||||
data = (uint16_t *) (item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0082; /* static class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, s, -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((uintptr_t) data) & 2)
|
||||
data++;
|
||||
|
||||
y += 20;
|
||||
}
|
||||
|
||||
dlg->cdit = (id - IDC_CONFIG_BASE) + 2;
|
||||
|
||||
item = (DLGITEMTEMPLATE *) data;
|
||||
item->x = 100;
|
||||
item->y = y + 5;
|
||||
item->cx = 50;
|
||||
item->cy = 14;
|
||||
item->id = IDOK; /* OK button identifier */
|
||||
item->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;
|
||||
|
||||
data = (uint16_t *) (item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0080; /* button class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "OK", -1, data, 50);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((uintptr_t) data) & 2)
|
||||
data++;
|
||||
|
||||
item = (DLGITEMTEMPLATE *) data;
|
||||
item->x = 160;
|
||||
item->y = y + 5;
|
||||
item->cx = 50;
|
||||
item->cy = 14;
|
||||
item->id = IDCANCEL; /* Cancel button identifier */
|
||||
item->style = WS_CHILD | WS_VISIBLE;
|
||||
|
||||
data = (uint16_t *) (item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0080; /* button class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "Cancel", -1, data, 50);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
dlg->cy = y + 25;
|
||||
|
||||
DialogBoxIndirect(hinstance, dlg, hwnd, joystickconfig_dlgproc);
|
||||
|
||||
free(data_block);
|
||||
|
||||
return joystickconfig_changed;
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
*/
|
||||
#define UNICODE
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#define BITMAP WINDOWS_BITMAP
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#define BITMAP WINDOWS_BITMAP
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#undef BITMAP
|
||||
@@ -30,9 +30,7 @@
|
||||
#include <86box/plat.h>
|
||||
#include <86box/win.h>
|
||||
|
||||
|
||||
static uint16_t scancode_map[768];
|
||||
|
||||
static uint16_t scancode_map[768];
|
||||
|
||||
/* This is so we can disambiguate scan codes that would otherwise conflict and get
|
||||
passed on incorrectly. */
|
||||
@@ -40,34 +38,33 @@ static UINT16
|
||||
convert_scan_code(UINT16 scan_code)
|
||||
{
|
||||
if ((scan_code & 0xff00) == 0xe000)
|
||||
scan_code = (scan_code & 0xff) | 0x0100;
|
||||
scan_code = (scan_code & 0xff) | 0x0100;
|
||||
|
||||
if (scan_code == 0xE11D)
|
||||
scan_code = 0x0100;
|
||||
scan_code = 0x0100;
|
||||
/* E0 00 is sent by some USB keyboards for their special keys, as it is an
|
||||
invalid scan code (it has no untranslated set 2 equivalent), we mark it
|
||||
appropriately so it does not get passed through. */
|
||||
else if ((scan_code > 0x01FF) || (scan_code == 0x0100))
|
||||
scan_code = 0xFFFF;
|
||||
scan_code = 0xFFFF;
|
||||
|
||||
return scan_code;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
keyboard_getkeymap(void)
|
||||
{
|
||||
WCHAR *keyName = L"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout";
|
||||
WCHAR *valueName = L"Scancode Map";
|
||||
WCHAR *keyName = L"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout";
|
||||
WCHAR *valueName = L"Scancode Map";
|
||||
unsigned char buf[32768];
|
||||
DWORD bufSize;
|
||||
HKEY hKey;
|
||||
int j;
|
||||
UINT32 *bufEx2;
|
||||
int scMapCount;
|
||||
UINT16 *bufEx;
|
||||
int scancode_unmapped;
|
||||
int scancode_mapped;
|
||||
DWORD bufSize;
|
||||
HKEY hKey;
|
||||
int j;
|
||||
UINT32 *bufEx2;
|
||||
int scMapCount;
|
||||
UINT16 *bufEx;
|
||||
int scancode_unmapped;
|
||||
int scancode_mapped;
|
||||
|
||||
/* First, prepare the default scan code map list which is 1:1.
|
||||
* Remappings will be inserted directly into it.
|
||||
@@ -75,131 +72,124 @@ keyboard_getkeymap(void)
|
||||
* prefix.
|
||||
*/
|
||||
for (j = 0; j < 512; j++)
|
||||
scancode_map[j] = j;
|
||||
scancode_map[j] = j;
|
||||
|
||||
/* Get the scan code remappings from:
|
||||
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout */
|
||||
bufSize = 32768;
|
||||
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS) {
|
||||
if (RegQueryValueEx(hKey, valueName, NULL, NULL, buf, &bufSize) == ERROR_SUCCESS) {
|
||||
bufEx2 = (UINT32 *) buf;
|
||||
scMapCount = bufEx2[2];
|
||||
if ((bufSize != 0) && (scMapCount != 0)) {
|
||||
bufEx = (UINT16 *) (buf + 12);
|
||||
for (j = 0; j < scMapCount*2; j += 2) {
|
||||
/* Each scan code is 32-bit: 16 bits of remapped scan code,
|
||||
and 16 bits of original scan code. */
|
||||
scancode_unmapped = bufEx[j + 1];
|
||||
scancode_mapped = bufEx[j];
|
||||
if (RegQueryValueEx(hKey, valueName, NULL, NULL, buf, &bufSize) == ERROR_SUCCESS) {
|
||||
bufEx2 = (UINT32 *) buf;
|
||||
scMapCount = bufEx2[2];
|
||||
if ((bufSize != 0) && (scMapCount != 0)) {
|
||||
bufEx = (UINT16 *) (buf + 12);
|
||||
for (j = 0; j < scMapCount * 2; j += 2) {
|
||||
/* Each scan code is 32-bit: 16 bits of remapped scan code,
|
||||
and 16 bits of original scan code. */
|
||||
scancode_unmapped = bufEx[j + 1];
|
||||
scancode_mapped = bufEx[j];
|
||||
|
||||
scancode_unmapped = convert_scan_code(scancode_unmapped);
|
||||
scancode_mapped = convert_scan_code(scancode_mapped);
|
||||
scancode_unmapped = convert_scan_code(scancode_unmapped);
|
||||
scancode_mapped = convert_scan_code(scancode_mapped);
|
||||
|
||||
/* Ignore source scan codes with prefixes other than E1
|
||||
that are not E1 1D. */
|
||||
if (scancode_unmapped != 0xFFFF)
|
||||
scancode_map[scancode_unmapped] = scancode_mapped;
|
||||
}
|
||||
}
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
/* Ignore source scan codes with prefixes other than E1
|
||||
that are not E1 1D. */
|
||||
if (scancode_unmapped != 0xFFFF)
|
||||
scancode_map[scancode_unmapped] = scancode_mapped;
|
||||
}
|
||||
}
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
keyboard_handle(PRAWINPUT raw)
|
||||
{
|
||||
USHORT scancode;
|
||||
USHORT scancode;
|
||||
static int recv_lalt = 0, recv_ralt = 0, recv_tab = 0;
|
||||
|
||||
RAWKEYBOARD rawKB = raw->data.keyboard;
|
||||
scancode = rawKB.MakeCode;
|
||||
scancode = rawKB.MakeCode;
|
||||
|
||||
if (kbd_req_capture && !mouse_capture && !video_fullscreen)
|
||||
return;
|
||||
return;
|
||||
|
||||
/* If it's not a scan code that starts with 0xE1 */
|
||||
if (!(rawKB.Flags & RI_KEY_E1)) {
|
||||
if (rawKB.Flags & RI_KEY_E0)
|
||||
scancode |= 0x100;
|
||||
if (rawKB.Flags & RI_KEY_E0)
|
||||
scancode |= 0x100;
|
||||
|
||||
/* Translate the scan code to 9-bit */
|
||||
scancode = convert_scan_code(scancode);
|
||||
/* Translate the scan code to 9-bit */
|
||||
scancode = convert_scan_code(scancode);
|
||||
|
||||
/* Remap it according to the list from the Registry */
|
||||
if (scancode != scancode_map[scancode])
|
||||
pclog("Scan code remap: %03X -> %03X\n", scancode, scancode);
|
||||
scancode = scancode_map[scancode];
|
||||
/* Remap it according to the list from the Registry */
|
||||
if (scancode != scancode_map[scancode])
|
||||
pclog("Scan code remap: %03X -> %03X\n", scancode, scancode);
|
||||
scancode = scancode_map[scancode];
|
||||
|
||||
/* If it's not 0xFFFF, send it to the emulated
|
||||
keyboard.
|
||||
We use scan code 0xFFFF to mean a mapping that
|
||||
has a prefix other than E0 and that is not E1 1D,
|
||||
which is, for our purposes, invalid. */
|
||||
if ((scancode == 0x00F) &&
|
||||
!(rawKB.Flags & RI_KEY_BREAK) &&
|
||||
(recv_lalt || recv_ralt) &&
|
||||
!mouse_capture) {
|
||||
/* We received a TAB while ALT was pressed, while the mouse
|
||||
is not captured, suppress the TAB and send an ALT key up. */
|
||||
if (recv_lalt) {
|
||||
keyboard_input(0, 0x038);
|
||||
/* Extra key press and release so the guest is not stuck in the
|
||||
menu bar. */
|
||||
keyboard_input(1, 0x038);
|
||||
keyboard_input(0, 0x038);
|
||||
recv_lalt = 0;
|
||||
}
|
||||
if (recv_ralt) {
|
||||
keyboard_input(0, 0x138);
|
||||
/* Extra key press and release so the guest is not stuck in the
|
||||
menu bar. */
|
||||
keyboard_input(1, 0x138);
|
||||
keyboard_input(0, 0x138);
|
||||
recv_ralt = 0;
|
||||
}
|
||||
} else if (((scancode == 0x038) || (scancode == 0x138)) &&
|
||||
!(rawKB.Flags & RI_KEY_BREAK) &&
|
||||
recv_tab &&
|
||||
!mouse_capture) {
|
||||
/* We received an ALT while TAB was pressed, while the mouse
|
||||
is not captured, suppress the ALT and send a TAB key up. */
|
||||
keyboard_input(0, 0x00F);
|
||||
recv_tab = 0;
|
||||
} else {
|
||||
switch(scancode) {
|
||||
case 0x00F:
|
||||
recv_tab = !(rawKB.Flags & RI_KEY_BREAK);
|
||||
break;
|
||||
case 0x038:
|
||||
recv_lalt = !(rawKB.Flags & RI_KEY_BREAK);
|
||||
break;
|
||||
case 0x138:
|
||||
recv_ralt = !(rawKB.Flags & RI_KEY_BREAK);
|
||||
break;
|
||||
}
|
||||
/* If it's not 0xFFFF, send it to the emulated
|
||||
keyboard.
|
||||
We use scan code 0xFFFF to mean a mapping that
|
||||
has a prefix other than E0 and that is not E1 1D,
|
||||
which is, for our purposes, invalid. */
|
||||
if ((scancode == 0x00F) && !(rawKB.Flags & RI_KEY_BREAK) && (recv_lalt || recv_ralt) && !mouse_capture) {
|
||||
/* We received a TAB while ALT was pressed, while the mouse
|
||||
is not captured, suppress the TAB and send an ALT key up. */
|
||||
if (recv_lalt) {
|
||||
keyboard_input(0, 0x038);
|
||||
/* Extra key press and release so the guest is not stuck in the
|
||||
menu bar. */
|
||||
keyboard_input(1, 0x038);
|
||||
keyboard_input(0, 0x038);
|
||||
recv_lalt = 0;
|
||||
}
|
||||
if (recv_ralt) {
|
||||
keyboard_input(0, 0x138);
|
||||
/* Extra key press and release so the guest is not stuck in the
|
||||
menu bar. */
|
||||
keyboard_input(1, 0x138);
|
||||
keyboard_input(0, 0x138);
|
||||
recv_ralt = 0;
|
||||
}
|
||||
} else if (((scancode == 0x038) || (scancode == 0x138)) && !(rawKB.Flags & RI_KEY_BREAK) && recv_tab && !mouse_capture) {
|
||||
/* We received an ALT while TAB was pressed, while the mouse
|
||||
is not captured, suppress the ALT and send a TAB key up. */
|
||||
keyboard_input(0, 0x00F);
|
||||
recv_tab = 0;
|
||||
} else {
|
||||
switch (scancode) {
|
||||
case 0x00F:
|
||||
recv_tab = !(rawKB.Flags & RI_KEY_BREAK);
|
||||
break;
|
||||
case 0x038:
|
||||
recv_lalt = !(rawKB.Flags & RI_KEY_BREAK);
|
||||
break;
|
||||
case 0x138:
|
||||
recv_ralt = !(rawKB.Flags & RI_KEY_BREAK);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Translate right CTRL to left ALT if the user has so
|
||||
chosen. */
|
||||
if ((scancode == 0x11D) && rctrl_is_lalt)
|
||||
scancode = 0x038;
|
||||
/* Translate right CTRL to left ALT if the user has so
|
||||
chosen. */
|
||||
if ((scancode == 0x11D) && rctrl_is_lalt)
|
||||
scancode = 0x038;
|
||||
|
||||
/* Normal scan code pass through, pass it through as is if
|
||||
it's not an invalid scan code. */
|
||||
if (scancode != 0xFFFF)
|
||||
keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode);
|
||||
}
|
||||
/* Normal scan code pass through, pass it through as is if
|
||||
it's not an invalid scan code. */
|
||||
if (scancode != 0xFFFF)
|
||||
keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode);
|
||||
}
|
||||
} else {
|
||||
if (rawKB.MakeCode == 0x1D) {
|
||||
scancode = scancode_map[0x100]; /* Translate E1 1D to 0x100 (which would
|
||||
otherwise be E0 00 but that is invalid
|
||||
anyway).
|
||||
Also, take a potential mapping into
|
||||
account. */
|
||||
} else
|
||||
scancode = 0xFFFF;
|
||||
if (scancode != 0xFFFF)
|
||||
keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode);
|
||||
if (rawKB.MakeCode == 0x1D) {
|
||||
scancode = scancode_map[0x100]; /* Translate E1 1D to 0x100 (which would
|
||||
otherwise be E0 00 but that is invalid
|
||||
anyway).
|
||||
Also, take a potential mapping into
|
||||
account. */
|
||||
} else
|
||||
scancode = 0xFFFF;
|
||||
if (scancode != 0xFFFF)
|
||||
keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -27,14 +27,14 @@
|
||||
#include <86box/plat.h>
|
||||
#include <86box/win.h>
|
||||
|
||||
int mouse_capture;
|
||||
int mouse_capture;
|
||||
double mouse_sensitivity = 1.0; /* Unused. */
|
||||
|
||||
typedef struct {
|
||||
int buttons;
|
||||
int dx;
|
||||
int dy;
|
||||
int dwheel;
|
||||
int buttons;
|
||||
int dx;
|
||||
int dy;
|
||||
int dwheel;
|
||||
} MOUSESTATE;
|
||||
|
||||
MOUSESTATE mousestate;
|
||||
@@ -46,70 +46,69 @@ win_mouse_init(void)
|
||||
|
||||
mouse_capture = 0;
|
||||
|
||||
/* Initialize the RawInput (mouse) module. */
|
||||
RAWINPUTDEVICE ridev;
|
||||
ridev.dwFlags = 0;
|
||||
ridev.hwndTarget = NULL;
|
||||
ridev.usUsagePage = 0x01;
|
||||
ridev.usUsage = 0x02;
|
||||
if (! RegisterRawInputDevices(&ridev, 1, sizeof(ridev)))
|
||||
fatal("plat_mouse_init: RegisterRawInputDevices failed\n");
|
||||
/* Initialize the RawInput (mouse) module. */
|
||||
RAWINPUTDEVICE ridev;
|
||||
ridev.dwFlags = 0;
|
||||
ridev.hwndTarget = NULL;
|
||||
ridev.usUsagePage = 0x01;
|
||||
ridev.usUsage = 0x02;
|
||||
if (!RegisterRawInputDevices(&ridev, 1, sizeof(ridev)))
|
||||
fatal("plat_mouse_init: RegisterRawInputDevices failed\n");
|
||||
|
||||
memset(&mousestate, 0, sizeof(MOUSESTATE));
|
||||
memset(&mousestate, 0, sizeof(MOUSESTATE));
|
||||
}
|
||||
|
||||
void
|
||||
win_mouse_handle(PRAWINPUT raw)
|
||||
{
|
||||
RAWMOUSE state = raw->data.mouse;
|
||||
RAWMOUSE state = raw->data.mouse;
|
||||
static int x, y;
|
||||
|
||||
/* read mouse buttons and wheel */
|
||||
if (state.usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN)
|
||||
mousestate.buttons |= 1;
|
||||
else if (state.usButtonFlags & RI_MOUSE_LEFT_BUTTON_UP)
|
||||
mousestate.buttons &= ~1;
|
||||
/* read mouse buttons and wheel */
|
||||
if (state.usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN)
|
||||
mousestate.buttons |= 1;
|
||||
else if (state.usButtonFlags & RI_MOUSE_LEFT_BUTTON_UP)
|
||||
mousestate.buttons &= ~1;
|
||||
|
||||
if (state.usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_DOWN)
|
||||
mousestate.buttons |= 4;
|
||||
else if (state.usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_UP)
|
||||
mousestate.buttons &= ~4;
|
||||
if (state.usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_DOWN)
|
||||
mousestate.buttons |= 4;
|
||||
else if (state.usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_UP)
|
||||
mousestate.buttons &= ~4;
|
||||
|
||||
if (state.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN)
|
||||
mousestate.buttons |= 2;
|
||||
else if (state.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_UP)
|
||||
mousestate.buttons &= ~2;
|
||||
|
||||
if (state.usButtonFlags & RI_MOUSE_WHEEL) {
|
||||
mousestate.dwheel += (SHORT)state.usButtonData / 120;
|
||||
}
|
||||
if (state.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN)
|
||||
mousestate.buttons |= 2;
|
||||
else if (state.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_UP)
|
||||
mousestate.buttons &= ~2;
|
||||
|
||||
if (state.usButtonFlags & RI_MOUSE_WHEEL) {
|
||||
mousestate.dwheel += (SHORT) state.usButtonData / 120;
|
||||
}
|
||||
|
||||
if (state.usFlags & MOUSE_MOVE_ABSOLUTE) {
|
||||
/* absolute mouse, i.e. RDP or VNC
|
||||
* seems to work fine for RDP on Windows 10
|
||||
* Not sure about other environments.
|
||||
*/
|
||||
mousestate.dx += (state.lLastX - x)/25;
|
||||
mousestate.dy += (state.lLastY - y)/25;
|
||||
x=state.lLastX;
|
||||
y=state.lLastY;
|
||||
} else {
|
||||
/* relative mouse, i.e. regular mouse */
|
||||
mousestate.dx += state.lLastX;
|
||||
mousestate.dy += state.lLastY;
|
||||
}
|
||||
/* absolute mouse, i.e. RDP or VNC
|
||||
* seems to work fine for RDP on Windows 10
|
||||
* Not sure about other environments.
|
||||
*/
|
||||
mousestate.dx += (state.lLastX - x) / 25;
|
||||
mousestate.dy += (state.lLastY - y) / 25;
|
||||
x = state.lLastX;
|
||||
y = state.lLastY;
|
||||
} else {
|
||||
/* relative mouse, i.e. regular mouse */
|
||||
mousestate.dx += state.lLastX;
|
||||
mousestate.dy += state.lLastY;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
win_mouse_close(void)
|
||||
{
|
||||
RAWINPUTDEVICE ridev;
|
||||
ridev.dwFlags = RIDEV_REMOVE;
|
||||
ridev.hwndTarget = NULL;
|
||||
ridev.usUsagePage = 0x01;
|
||||
ridev.usUsage = 0x02;
|
||||
RegisterRawInputDevices(&ridev, 1, sizeof(ridev));
|
||||
RAWINPUTDEVICE ridev;
|
||||
ridev.dwFlags = RIDEV_REMOVE;
|
||||
ridev.hwndTarget = NULL;
|
||||
ridev.usUsagePage = 0x01;
|
||||
ridev.usUsage = 0x02;
|
||||
RegisterRawInputDevices(&ridev, 1, sizeof(ridev));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -117,21 +116,21 @@ mouse_poll(void)
|
||||
{
|
||||
static int b = 0;
|
||||
if (mouse_capture || video_fullscreen) {
|
||||
if (mousestate.dx != 0 || mousestate.dy != 0 || mousestate.dwheel != 0) {
|
||||
mouse_x += mousestate.dx;
|
||||
mouse_y += mousestate.dy;
|
||||
mouse_z = mousestate.dwheel;
|
||||
if (mousestate.dx != 0 || mousestate.dy != 0 || mousestate.dwheel != 0) {
|
||||
mouse_x += mousestate.dx;
|
||||
mouse_y += mousestate.dy;
|
||||
mouse_z = mousestate.dwheel;
|
||||
|
||||
mousestate.dx=0;
|
||||
mousestate.dy=0;
|
||||
mousestate.dwheel=0;
|
||||
mousestate.dx = 0;
|
||||
mousestate.dy = 0;
|
||||
mousestate.dwheel = 0;
|
||||
|
||||
//pclog("dx=%d, dy=%d, dwheel=%d\n", mouse_x, mouse_y, mouse_z);
|
||||
}
|
||||
// pclog("dx=%d, dy=%d, dwheel=%d\n", mouse_x, mouse_y, mouse_z);
|
||||
}
|
||||
|
||||
if (b != mousestate.buttons) {
|
||||
mouse_buttons = mousestate.buttons;
|
||||
b = mousestate.buttons;
|
||||
}
|
||||
}
|
||||
if (b != mousestate.buttons) {
|
||||
mouse_buttons = mousestate.buttons;
|
||||
b = mousestate.buttons;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -27,12 +27,10 @@
|
||||
#include <86box/plat.h>
|
||||
#include <86box/plat_dir.h>
|
||||
|
||||
|
||||
#define SUFFIX "\\*"
|
||||
#define FINDATA struct _finddata_t
|
||||
#define FINDFIRST _findfirst
|
||||
#define FINDNEXT _findnext
|
||||
|
||||
#define SUFFIX "\\*"
|
||||
#define FINDATA struct _finddata_t
|
||||
#define FINDFIRST _findfirst
|
||||
#define FINDNEXT _findnext
|
||||
|
||||
/* Open a directory. */
|
||||
DIR *
|
||||
@@ -43,17 +41,17 @@ opendir(const char *name)
|
||||
/* Create a new control structure. */
|
||||
p = (DIR *) malloc(sizeof(DIR));
|
||||
if (p == NULL)
|
||||
return(NULL);
|
||||
return (NULL);
|
||||
memset(p, 0x00, sizeof(DIR));
|
||||
p->flags = (DIR_F_LOWER | DIR_F_SANE);
|
||||
p->flags = (DIR_F_LOWER | DIR_F_SANE);
|
||||
p->offset = 0;
|
||||
p->sts = 0;
|
||||
p->sts = 0;
|
||||
|
||||
/* Create a work area. */
|
||||
p->dta = (char *)malloc(sizeof(FINDATA));
|
||||
p->dta = (char *) malloc(sizeof(FINDATA));
|
||||
if (p->dta == NULL) {
|
||||
free(p);
|
||||
return(NULL);
|
||||
free(p);
|
||||
return (NULL);
|
||||
}
|
||||
memset(p->dta, 0x00, sizeof(struct _finddata_t));
|
||||
|
||||
@@ -63,38 +61,36 @@ opendir(const char *name)
|
||||
|
||||
/* Special case: flag if we are in the root directory. */
|
||||
if (strlen(p->dir) == 3)
|
||||
p->flags |= DIR_F_ISROOT;
|
||||
p->flags |= DIR_F_ISROOT;
|
||||
|
||||
/* Start the searching by doing a FindFirst. */
|
||||
p->handle = FINDFIRST(p->dir, (FINDATA *)p->dta);
|
||||
p->handle = FINDFIRST(p->dir, (FINDATA *) p->dta);
|
||||
if (p->handle < 0L) {
|
||||
free(p->dta);
|
||||
free(p);
|
||||
return(NULL);
|
||||
free(p->dta);
|
||||
free(p);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* All OK. */
|
||||
return(p);
|
||||
return (p);
|
||||
}
|
||||
|
||||
|
||||
/* Close an open directory. */
|
||||
int
|
||||
closedir(DIR *p)
|
||||
{
|
||||
if (p == NULL)
|
||||
return(0);
|
||||
return (0);
|
||||
|
||||
_findclose(p->handle);
|
||||
|
||||
if (p->dta != NULL)
|
||||
free(p->dta);
|
||||
free(p->dta);
|
||||
free(p);
|
||||
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read the next entry from a directory.
|
||||
* Note that the DOS (FAT), Windows (FAT, FAT32) and Windows NTFS
|
||||
@@ -108,26 +104,26 @@ readdir(DIR *p)
|
||||
FINDATA *ffp;
|
||||
|
||||
if (p == NULL || p->sts == 1)
|
||||
return(NULL);
|
||||
return (NULL);
|
||||
|
||||
/* Format structure with current data. */
|
||||
ffp = (FINDATA *)p->dta;
|
||||
ffp = (FINDATA *) p->dta;
|
||||
p->dent.d_ino = 1L;
|
||||
p->dent.d_off = p->offset++;
|
||||
switch(p->offset) {
|
||||
case 1: /* . */
|
||||
strncpy(p->dent.d_name, ".", MAXNAMLEN+1);
|
||||
p->dent.d_reclen = 1;
|
||||
break;
|
||||
switch (p->offset) {
|
||||
case 1: /* . */
|
||||
strncpy(p->dent.d_name, ".", MAXNAMLEN + 1);
|
||||
p->dent.d_reclen = 1;
|
||||
break;
|
||||
|
||||
case 2: /* .. */
|
||||
strncpy(p->dent.d_name, "..", MAXNAMLEN+1);
|
||||
p->dent.d_reclen = 2;
|
||||
break;
|
||||
case 2: /* .. */
|
||||
strncpy(p->dent.d_name, "..", MAXNAMLEN + 1);
|
||||
p->dent.d_reclen = 2;
|
||||
break;
|
||||
|
||||
default: /* regular entry. */
|
||||
strncpy(p->dent.d_name, ffp->name, MAXNAMLEN+1);
|
||||
p->dent.d_reclen = (char)strlen(p->dent.d_name);
|
||||
default: /* regular entry. */
|
||||
strncpy(p->dent.d_name, ffp->name, MAXNAMLEN + 1);
|
||||
p->dent.d_reclen = (char) strlen(p->dent.d_name);
|
||||
}
|
||||
|
||||
/* Read next entry. */
|
||||
@@ -135,48 +131,47 @@ readdir(DIR *p)
|
||||
|
||||
/* Fake the "." and ".." entries here.. */
|
||||
if ((p->flags & DIR_F_ISROOT) && (p->offset <= 2))
|
||||
return(&(p->dent));
|
||||
return (&(p->dent));
|
||||
|
||||
/* Get the next entry if we did not fake the above. */
|
||||
if (FINDNEXT(p->handle, ffp) < 0)
|
||||
p->sts = 1;
|
||||
p->sts = 1;
|
||||
|
||||
return(&(p->dent));
|
||||
return (&(p->dent));
|
||||
}
|
||||
|
||||
|
||||
/* Report current position within the directory. */
|
||||
long
|
||||
telldir(DIR *p)
|
||||
{
|
||||
return(p->offset);
|
||||
return (p->offset);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
seekdir(DIR *p, long newpos)
|
||||
{
|
||||
short pos;
|
||||
|
||||
/* First off, rewind to start of directory. */
|
||||
p->handle = FINDFIRST(p->dir, (FINDATA *)p->dta);
|
||||
p->handle = FINDFIRST(p->dir, (FINDATA *) p->dta);
|
||||
if (p->handle < 0L) {
|
||||
p->sts = 1;
|
||||
return;
|
||||
p->sts = 1;
|
||||
return;
|
||||
}
|
||||
p->offset = 0;
|
||||
p->sts = 0;
|
||||
p->sts = 0;
|
||||
|
||||
/* If we are rewinding, that's all... */
|
||||
if (newpos == 0L) return;
|
||||
if (newpos == 0L)
|
||||
return;
|
||||
|
||||
/* Nope.. read entries until we hit the right spot. */
|
||||
pos = (short) newpos;
|
||||
while (p->offset != pos) {
|
||||
p->offset++;
|
||||
if (FINDNEXT(p->handle, (FINDATA *)p->dta) < 0) {
|
||||
p->sts = 1;
|
||||
return;
|
||||
}
|
||||
p->offset++;
|
||||
if (FINDNEXT(p->handle, (FINDATA *) p->dta) < 0) {
|
||||
p->sts = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1476
src/win/win_opengl.c
1476
src/win/win_opengl.c
File diff suppressed because it is too large
Load Diff
@@ -40,10 +40,10 @@
|
||||
#include <86box/plat.h>
|
||||
#include <86box/win_opengl_glslp.h>
|
||||
|
||||
/**
|
||||
* @brief Default vertex shader.
|
||||
/**
|
||||
* @brief Default vertex shader.
|
||||
*/
|
||||
static const GLchar* vertex_shader = "#version 130\n\
|
||||
static const GLchar *vertex_shader = "#version 130\n\
|
||||
in vec2 VertexCoord;\n\
|
||||
in vec2 TexCoord;\n\
|
||||
out vec2 tex;\n\
|
||||
@@ -55,7 +55,7 @@ void main(){\n\
|
||||
/**
|
||||
* @brief Default fragment shader.
|
||||
*/
|
||||
static const GLchar* fragment_shader = "#version 130\n\
|
||||
static const GLchar *fragment_shader = "#version 130\n\
|
||||
in vec2 tex;\n\
|
||||
uniform sampler2D texsampler;\n\
|
||||
out vec4 color;\n\
|
||||
@@ -65,208 +65,204 @@ void main() {\n\
|
||||
|
||||
/**
|
||||
* @brief OpenGL shader program build targets
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
OPENGL_BUILD_TARGET_VERTEX,
|
||||
OPENGL_BUILD_TARGET_FRAGMENT,
|
||||
OPENGL_BUILD_TARGET_LINK
|
||||
*/
|
||||
typedef enum {
|
||||
OPENGL_BUILD_TARGET_VERTEX,
|
||||
OPENGL_BUILD_TARGET_FRAGMENT,
|
||||
OPENGL_BUILD_TARGET_LINK
|
||||
} opengl_build_target_t;
|
||||
|
||||
/**
|
||||
* @brief Reads a whole file into a null terminated string.
|
||||
* @param Path Path to the file relative to executable path.
|
||||
* @return Pointer to the string or NULL on error. Remember to free() after use.
|
||||
*/
|
||||
static char* read_file_to_string(const char* path)
|
||||
*/
|
||||
static char *
|
||||
read_file_to_string(const char *path)
|
||||
{
|
||||
FILE* file_handle = plat_fopen(path, "rb");
|
||||
FILE *file_handle = plat_fopen(path, "rb");
|
||||
|
||||
if (file_handle != NULL)
|
||||
{
|
||||
/* get file size */
|
||||
fseek(file_handle, 0, SEEK_END);
|
||||
if (file_handle != NULL) {
|
||||
/* get file size */
|
||||
fseek(file_handle, 0, SEEK_END);
|
||||
|
||||
size_t file_size = (size_t)ftell(file_handle);
|
||||
size_t file_size = (size_t) ftell(file_handle);
|
||||
|
||||
fseek(file_handle, 0, SEEK_SET);
|
||||
fseek(file_handle, 0, SEEK_SET);
|
||||
|
||||
/* read to buffer and close */
|
||||
char* content = (char*)malloc(sizeof(char) * (file_size + 1));
|
||||
/* read to buffer and close */
|
||||
char *content = (char *) malloc(sizeof(char) * (file_size + 1));
|
||||
|
||||
if (!content)
|
||||
return NULL;
|
||||
if (!content)
|
||||
return NULL;
|
||||
|
||||
size_t length = fread(content, sizeof(char), file_size, file_handle);
|
||||
size_t length = fread(content, sizeof(char), file_size, file_handle);
|
||||
|
||||
fclose(file_handle);
|
||||
fclose(file_handle);
|
||||
|
||||
content[length] = 0;
|
||||
content[length] = 0;
|
||||
|
||||
return content;
|
||||
}
|
||||
return NULL;
|
||||
return content;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int check_status(GLuint id, opengl_build_target_t build_target, const char* shader_path)
|
||||
static int
|
||||
check_status(GLuint id, opengl_build_target_t build_target, const char *shader_path)
|
||||
{
|
||||
GLint status = GL_FALSE;
|
||||
GLint status = GL_FALSE;
|
||||
|
||||
if (build_target != OPENGL_BUILD_TARGET_LINK)
|
||||
glGetShaderiv(id, GL_COMPILE_STATUS, &status);
|
||||
else
|
||||
glGetProgramiv(id, GL_LINK_STATUS, &status);
|
||||
if (build_target != OPENGL_BUILD_TARGET_LINK)
|
||||
glGetShaderiv(id, GL_COMPILE_STATUS, &status);
|
||||
else
|
||||
glGetProgramiv(id, GL_LINK_STATUS, &status);
|
||||
|
||||
if (status == GL_FALSE)
|
||||
{
|
||||
int info_log_length;
|
||||
if (status == GL_FALSE) {
|
||||
int info_log_length;
|
||||
|
||||
if (build_target != OPENGL_BUILD_TARGET_LINK)
|
||||
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &info_log_length);
|
||||
else
|
||||
glGetProgramiv(id, GL_INFO_LOG_LENGTH, &info_log_length);
|
||||
if (build_target != OPENGL_BUILD_TARGET_LINK)
|
||||
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &info_log_length);
|
||||
else
|
||||
glGetProgramiv(id, GL_INFO_LOG_LENGTH, &info_log_length);
|
||||
|
||||
GLchar* info_log_text = (GLchar*)malloc(sizeof(GLchar) * info_log_length);
|
||||
GLchar *info_log_text = (GLchar *) malloc(sizeof(GLchar) * info_log_length);
|
||||
|
||||
if (build_target != OPENGL_BUILD_TARGET_LINK)
|
||||
glGetShaderInfoLog(id, info_log_length, NULL, info_log_text);
|
||||
else
|
||||
glGetProgramInfoLog(id, info_log_length, NULL, info_log_text);
|
||||
if (build_target != OPENGL_BUILD_TARGET_LINK)
|
||||
glGetShaderInfoLog(id, info_log_length, NULL, info_log_text);
|
||||
else
|
||||
glGetProgramInfoLog(id, info_log_length, NULL, info_log_text);
|
||||
|
||||
const char* reason = NULL;
|
||||
const char *reason = NULL;
|
||||
|
||||
switch (build_target)
|
||||
{
|
||||
case OPENGL_BUILD_TARGET_VERTEX:
|
||||
reason = "compiling vertex shader";
|
||||
break;
|
||||
case OPENGL_BUILD_TARGET_FRAGMENT:
|
||||
reason = "compiling fragment shader";
|
||||
break;
|
||||
case OPENGL_BUILD_TARGET_LINK:
|
||||
reason = "linking shader program";
|
||||
break;
|
||||
}
|
||||
switch (build_target) {
|
||||
case OPENGL_BUILD_TARGET_VERTEX:
|
||||
reason = "compiling vertex shader";
|
||||
break;
|
||||
case OPENGL_BUILD_TARGET_FRAGMENT:
|
||||
reason = "compiling fragment shader";
|
||||
break;
|
||||
case OPENGL_BUILD_TARGET_LINK:
|
||||
reason = "linking shader program";
|
||||
break;
|
||||
}
|
||||
|
||||
/* Shader compilation log can be lengthy, mark begin and end */
|
||||
const char* line = "--------------------";
|
||||
/* Shader compilation log can be lengthy, mark begin and end */
|
||||
const char *line = "--------------------";
|
||||
|
||||
pclog("OpenGL: Error when %s in %s:\n%sBEGIN%s\n%s\n%s END %s\n", reason, shader_path, line, line, info_log_text, line, line);
|
||||
pclog("OpenGL: Error when %s in %s:\n%sBEGIN%s\n%s\n%s END %s\n", reason, shader_path, line, line, info_log_text, line, line);
|
||||
|
||||
free(info_log_text);
|
||||
free(info_log_text);
|
||||
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Compile custom shaders into a program.
|
||||
* @return Shader program identifier.
|
||||
*/
|
||||
GLuint load_custom_shaders(const char* path)
|
||||
*/
|
||||
GLuint
|
||||
load_custom_shaders(const char *path)
|
||||
{
|
||||
char* shader = read_file_to_string(path);
|
||||
char *shader = read_file_to_string(path);
|
||||
|
||||
if (shader != NULL)
|
||||
{
|
||||
int success = 1;
|
||||
if (shader != NULL) {
|
||||
int success = 1;
|
||||
|
||||
const char* vertex_sources[3] = { "#version 130\n", "#define VERTEX\n", shader };
|
||||
const char* fragment_sources[3] = { "#version 130\n", "#define FRAGMENT\n", shader };
|
||||
const char *vertex_sources[3] = { "#version 130\n", "#define VERTEX\n", shader };
|
||||
const char *fragment_sources[3] = { "#version 130\n", "#define FRAGMENT\n", shader };
|
||||
|
||||
/* Check if the shader program defines version directive */
|
||||
char* version_start = strstr(shader, "#version");
|
||||
/* Check if the shader program defines version directive */
|
||||
char *version_start = strstr(shader, "#version");
|
||||
|
||||
/* If the shader program contains a version directive,
|
||||
it must be captured and placed as the first statement. */
|
||||
if (version_start != NULL)
|
||||
{
|
||||
/* Version directive found, search the line end */
|
||||
char* version_end = strchr(version_start, '\n');
|
||||
/* If the shader program contains a version directive,
|
||||
it must be captured and placed as the first statement. */
|
||||
if (version_start != NULL) {
|
||||
/* Version directive found, search the line end */
|
||||
char *version_end = strchr(version_start, '\n');
|
||||
|
||||
if (version_end != NULL)
|
||||
{
|
||||
char version[30] = "";
|
||||
if (version_end != NULL) {
|
||||
char version[30] = "";
|
||||
|
||||
size_t version_len = MIN(version_end - version_start + 1, 29);
|
||||
size_t version_len = MIN(version_end - version_start + 1, 29);
|
||||
|
||||
strncat(version, version_start, version_len);
|
||||
strncat(version, version_start, version_len);
|
||||
|
||||
/* replace the default version directive */
|
||||
vertex_sources[0] = version;
|
||||
fragment_sources[0] = version;
|
||||
}
|
||||
/* replace the default version directive */
|
||||
vertex_sources[0] = version;
|
||||
fragment_sources[0] = version;
|
||||
}
|
||||
|
||||
/* Comment out the original version directive
|
||||
as only one is allowed. */
|
||||
memset(version_start, '/', 2);
|
||||
}
|
||||
/* Comment out the original version directive
|
||||
as only one is allowed. */
|
||||
memset(version_start, '/', 2);
|
||||
}
|
||||
|
||||
GLuint vertex_id = glCreateShader(GL_VERTEX_SHADER);
|
||||
GLuint fragment_id = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
GLuint vertex_id = glCreateShader(GL_VERTEX_SHADER);
|
||||
GLuint fragment_id = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
|
||||
glShaderSource(vertex_id, 3, vertex_sources, NULL);
|
||||
glCompileShader(vertex_id);
|
||||
success *= check_status(vertex_id, OPENGL_BUILD_TARGET_VERTEX, path);
|
||||
glShaderSource(vertex_id, 3, vertex_sources, NULL);
|
||||
glCompileShader(vertex_id);
|
||||
success *= check_status(vertex_id, OPENGL_BUILD_TARGET_VERTEX, path);
|
||||
|
||||
glShaderSource(fragment_id, 3, fragment_sources, NULL);
|
||||
glCompileShader(fragment_id);
|
||||
success *= check_status(fragment_id, OPENGL_BUILD_TARGET_FRAGMENT, path);
|
||||
glShaderSource(fragment_id, 3, fragment_sources, NULL);
|
||||
glCompileShader(fragment_id);
|
||||
success *= check_status(fragment_id, OPENGL_BUILD_TARGET_FRAGMENT, path);
|
||||
|
||||
free(shader);
|
||||
free(shader);
|
||||
|
||||
GLuint prog_id = 0;
|
||||
GLuint prog_id = 0;
|
||||
|
||||
if (success)
|
||||
{
|
||||
prog_id = glCreateProgram();
|
||||
if (success) {
|
||||
prog_id = glCreateProgram();
|
||||
|
||||
glAttachShader(prog_id, vertex_id);
|
||||
glAttachShader(prog_id, fragment_id);
|
||||
glLinkProgram(prog_id);
|
||||
check_status(prog_id, OPENGL_BUILD_TARGET_LINK, path);
|
||||
glAttachShader(prog_id, vertex_id);
|
||||
glAttachShader(prog_id, fragment_id);
|
||||
glLinkProgram(prog_id);
|
||||
check_status(prog_id, OPENGL_BUILD_TARGET_LINK, path);
|
||||
|
||||
glDetachShader(prog_id, vertex_id);
|
||||
glDetachShader(prog_id, fragment_id);
|
||||
}
|
||||
glDetachShader(prog_id, vertex_id);
|
||||
glDetachShader(prog_id, fragment_id);
|
||||
}
|
||||
|
||||
glDeleteShader(vertex_id);
|
||||
glDeleteShader(fragment_id);
|
||||
glDeleteShader(vertex_id);
|
||||
glDeleteShader(fragment_id);
|
||||
|
||||
return prog_id;
|
||||
}
|
||||
return 0;
|
||||
return prog_id;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Compile default shaders into a program.
|
||||
* @return Shader program identifier.
|
||||
*/
|
||||
GLuint load_default_shaders()
|
||||
*/
|
||||
GLuint
|
||||
load_default_shaders()
|
||||
{
|
||||
GLuint vertex_id = glCreateShader(GL_VERTEX_SHADER);
|
||||
GLuint fragment_id = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
GLuint vertex_id = glCreateShader(GL_VERTEX_SHADER);
|
||||
GLuint fragment_id = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
|
||||
glShaderSource(vertex_id, 1, &vertex_shader, NULL);
|
||||
glCompileShader(vertex_id);
|
||||
glShaderSource(vertex_id, 1, &vertex_shader, NULL);
|
||||
glCompileShader(vertex_id);
|
||||
|
||||
glShaderSource(fragment_id, 1, &fragment_shader, NULL);
|
||||
glCompileShader(fragment_id);
|
||||
glShaderSource(fragment_id, 1, &fragment_shader, NULL);
|
||||
glCompileShader(fragment_id);
|
||||
|
||||
GLuint prog_id = glCreateProgram();
|
||||
GLuint prog_id = glCreateProgram();
|
||||
|
||||
glAttachShader(prog_id, vertex_id);
|
||||
glAttachShader(prog_id, fragment_id);
|
||||
glAttachShader(prog_id, vertex_id);
|
||||
glAttachShader(prog_id, fragment_id);
|
||||
|
||||
glLinkProgram(prog_id);
|
||||
glLinkProgram(prog_id);
|
||||
|
||||
glDetachShader(prog_id, vertex_id);
|
||||
glDetachShader(prog_id, fragment_id);
|
||||
glDetachShader(prog_id, vertex_id);
|
||||
glDetachShader(prog_id, fragment_id);
|
||||
|
||||
glDeleteShader(vertex_id);
|
||||
glDeleteShader(fragment_id);
|
||||
glDeleteShader(vertex_id);
|
||||
glDeleteShader(fragment_id);
|
||||
|
||||
return prog_id;
|
||||
return prog_id;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
/* Language */
|
||||
static LCID temp_language;
|
||||
|
||||
static char temp_icon_set[256] = {0};
|
||||
static char temp_icon_set[256] = { 0 };
|
||||
|
||||
int enum_helper, c;
|
||||
|
||||
@@ -44,112 +44,108 @@ HWND hwndPreferences;
|
||||
BOOL CALLBACK
|
||||
EnumResLangProc(HMODULE hModule, LPCTSTR lpszType, LPCTSTR lpszName, WORD wIDLanguage, LONG_PTR lParam)
|
||||
{
|
||||
wchar_t temp[LOCALE_NAME_MAX_LENGTH + 1];
|
||||
LCIDToLocaleName(wIDLanguage, temp, LOCALE_NAME_MAX_LENGTH, 0);
|
||||
wchar_t dispname[MAX_PATH + 1];
|
||||
GetLocaleInfoEx(temp, LOCALE_SENGLISHDISPLAYNAME, dispname, MAX_PATH);
|
||||
SendMessage((HWND)lParam, CB_ADDSTRING, 0, (LPARAM)dispname);
|
||||
SendMessage((HWND)lParam, CB_SETITEMDATA, c, (LPARAM)wIDLanguage);
|
||||
wchar_t temp[LOCALE_NAME_MAX_LENGTH + 1];
|
||||
LCIDToLocaleName(wIDLanguage, temp, LOCALE_NAME_MAX_LENGTH, 0);
|
||||
wchar_t dispname[MAX_PATH + 1];
|
||||
GetLocaleInfoEx(temp, LOCALE_SENGLISHDISPLAYNAME, dispname, MAX_PATH);
|
||||
SendMessage((HWND) lParam, CB_ADDSTRING, 0, (LPARAM) dispname);
|
||||
SendMessage((HWND) lParam, CB_SETITEMDATA, c, (LPARAM) wIDLanguage);
|
||||
|
||||
if (wIDLanguage == lang_id)
|
||||
enum_helper = c;
|
||||
c++;
|
||||
if (wIDLanguage == lang_id)
|
||||
enum_helper = c;
|
||||
c++;
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Load available languages */
|
||||
static void
|
||||
preferences_fill_languages(HWND hdlg)
|
||||
{
|
||||
temp_language = GetThreadUILanguage();
|
||||
HWND lang_combo = GetDlgItem(hdlg, IDC_COMBO_LANG);
|
||||
temp_language = GetThreadUILanguage();
|
||||
HWND lang_combo = GetDlgItem(hdlg, IDC_COMBO_LANG);
|
||||
|
||||
SendMessage(lang_combo, CB_RESETCONTENT, 0, 0);
|
||||
SendMessage(lang_combo, CB_ADDSTRING, 0, win_get_string(IDS_7168));
|
||||
SendMessage(lang_combo, CB_SETITEMDATA, 0, 0xFFFF);
|
||||
SendMessage(lang_combo, CB_RESETCONTENT, 0, 0);
|
||||
SendMessage(lang_combo, CB_ADDSTRING, 0, win_get_string(IDS_7168));
|
||||
SendMessage(lang_combo, CB_SETITEMDATA, 0, 0xFFFF);
|
||||
|
||||
enum_helper = 0; c = 1;
|
||||
//if no one is selected, then it was 0xFFFF or unsupported language, in either case go with index enum_helper=0
|
||||
//also start enum index from c=1
|
||||
EnumResourceLanguages(hinstance, RT_MENU, L"MainMenu", &EnumResLangProc, (LPARAM)lang_combo);
|
||||
enum_helper = 0;
|
||||
c = 1;
|
||||
// if no one is selected, then it was 0xFFFF or unsupported language, in either case go with index enum_helper=0
|
||||
// also start enum index from c=1
|
||||
EnumResourceLanguages(hinstance, RT_MENU, L"MainMenu", &EnumResLangProc, (LPARAM) lang_combo);
|
||||
|
||||
SendMessage(lang_combo, CB_SETCURSEL, enum_helper, 0);
|
||||
SendMessage(lang_combo, CB_SETCURSEL, enum_helper, 0);
|
||||
}
|
||||
|
||||
/* Load available iconsets */
|
||||
static void
|
||||
preferences_fill_iconsets(HWND hdlg)
|
||||
{
|
||||
HWND icon_combo = GetDlgItem(hdlg, IDC_COMBO_ICON);
|
||||
HWND icon_combo = GetDlgItem(hdlg, IDC_COMBO_ICON);
|
||||
|
||||
/* Add the default one */
|
||||
wchar_t buffer[512] = L"(";
|
||||
wcscat(buffer, plat_get_string(IDS_2090));
|
||||
wcscat(buffer, L")");
|
||||
/* Add the default one */
|
||||
wchar_t buffer[512] = L"(";
|
||||
wcscat(buffer, plat_get_string(IDS_2090));
|
||||
wcscat(buffer, L")");
|
||||
|
||||
SendMessage(icon_combo, CB_RESETCONTENT, 0, 0);
|
||||
SendMessage(icon_combo, CB_ADDSTRING, 0, (LPARAM)buffer);
|
||||
SendMessage(icon_combo, CB_SETITEMDATA, 0, (LPARAM)strdup(""));
|
||||
SendMessage(icon_combo, CB_RESETCONTENT, 0, 0);
|
||||
SendMessage(icon_combo, CB_ADDSTRING, 0, (LPARAM) buffer);
|
||||
SendMessage(icon_combo, CB_SETITEMDATA, 0, (LPARAM) strdup(""));
|
||||
|
||||
int combo_index = -1;
|
||||
int combo_index = -1;
|
||||
|
||||
/* Find for extra ones */
|
||||
HANDLE hFind;
|
||||
WIN32_FIND_DATA data;
|
||||
/* Find for extra ones */
|
||||
HANDLE hFind;
|
||||
WIN32_FIND_DATA data;
|
||||
|
||||
char icon_path_root[512];
|
||||
win_get_icons_path(icon_path_root);
|
||||
char icon_path_root[512];
|
||||
win_get_icons_path(icon_path_root);
|
||||
|
||||
wchar_t search[512];
|
||||
mbstoc16s(search, icon_path_root, strlen(icon_path_root) + 1);
|
||||
wcscat(search, L"*.*");
|
||||
wchar_t search[512];
|
||||
mbstoc16s(search, icon_path_root, strlen(icon_path_root) + 1);
|
||||
wcscat(search, L"*.*");
|
||||
|
||||
hFind = FindFirstFile((LPCWSTR)search, &data);
|
||||
hFind = FindFirstFile((LPCWSTR) search, &data);
|
||||
|
||||
if (hFind != INVALID_HANDLE_VALUE) {
|
||||
do {
|
||||
if (wcscmp(data.cFileName, L".") && wcscmp(data.cFileName, L"..") &&
|
||||
(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
wchar_t temp[512] = {0}, dispname[512] = {0};
|
||||
mbstoc16s(temp, icon_path_root, strlen(icon_path_root) + 1);
|
||||
wcscat(temp, data.cFileName);
|
||||
wcscat(temp, L"\\iconinfo.txt");
|
||||
if (hFind != INVALID_HANDLE_VALUE) {
|
||||
do {
|
||||
if (wcscmp(data.cFileName, L".") && wcscmp(data.cFileName, L"..") && (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
wchar_t temp[512] = { 0 }, dispname[512] = { 0 };
|
||||
mbstoc16s(temp, icon_path_root, strlen(icon_path_root) + 1);
|
||||
wcscat(temp, data.cFileName);
|
||||
wcscat(temp, L"\\iconinfo.txt");
|
||||
|
||||
wcscpy(dispname, data.cFileName);
|
||||
FILE *fp = _wfopen(temp, L"r");
|
||||
if (fp)
|
||||
{
|
||||
char line[512] = {0};
|
||||
if (fgets(line, 511, fp))
|
||||
{
|
||||
mbstoc16s(dispname, line, strlen(line) + 1);
|
||||
}
|
||||
wcscpy(dispname, data.cFileName);
|
||||
FILE *fp = _wfopen(temp, L"r");
|
||||
if (fp) {
|
||||
char line[512] = { 0 };
|
||||
if (fgets(line, 511, fp)) {
|
||||
mbstoc16s(dispname, line, strlen(line) + 1);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
char filename[512];
|
||||
c16stombs(filename, data.cFileName, 511);
|
||||
char filename[512];
|
||||
c16stombs(filename, data.cFileName, 511);
|
||||
|
||||
int index = SendMessage(icon_combo, CB_ADDSTRING, 0, (LPARAM)dispname);
|
||||
SendMessage(icon_combo, CB_SETITEMDATA, index, (LPARAM)(strdup(filename)));
|
||||
int index = SendMessage(icon_combo, CB_ADDSTRING, 0, (LPARAM) dispname);
|
||||
SendMessage(icon_combo, CB_SETITEMDATA, index, (LPARAM) (strdup(filename)));
|
||||
|
||||
if (!strcmp(filename, icon_set))
|
||||
combo_index = index;
|
||||
}
|
||||
} while (FindNextFile(hFind, &data));
|
||||
FindClose(hFind);
|
||||
}
|
||||
if (!strcmp(filename, icon_set))
|
||||
combo_index = index;
|
||||
}
|
||||
} while (FindNextFile(hFind, &data));
|
||||
FindClose(hFind);
|
||||
}
|
||||
|
||||
if (combo_index == -1)
|
||||
{
|
||||
combo_index = 0;
|
||||
strcpy(temp_icon_set, "");
|
||||
}
|
||||
if (combo_index == -1) {
|
||||
combo_index = 0;
|
||||
strcpy(temp_icon_set, "");
|
||||
}
|
||||
|
||||
SendMessage(icon_combo, CB_SETCURSEL, combo_index, 0);
|
||||
SendMessage(icon_combo, CB_SETCURSEL, combo_index, 0);
|
||||
}
|
||||
|
||||
/* This returns 1 if any variable has changed, 0 if not. */
|
||||
@@ -209,85 +205,84 @@ static BOOL CALLBACK
|
||||
PreferencesDlgProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (message) {
|
||||
case WM_INITDIALOG:
|
||||
hwndPreferences = hdlg;
|
||||
/* Language */
|
||||
temp_language = lang_id;
|
||||
strcpy(temp_icon_set, icon_set);
|
||||
preferences_fill_languages(hdlg);
|
||||
preferences_fill_iconsets(hdlg);
|
||||
break;
|
||||
case WM_INITDIALOG:
|
||||
hwndPreferences = hdlg;
|
||||
/* Language */
|
||||
temp_language = lang_id;
|
||||
strcpy(temp_icon_set, icon_set);
|
||||
preferences_fill_languages(hdlg);
|
||||
preferences_fill_iconsets(hdlg);
|
||||
break;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam)) {
|
||||
case IDOK:
|
||||
if (preferences_settings_changed())
|
||||
preferences_settings_save();
|
||||
EndDialog(hdlg, 0);
|
||||
return TRUE;
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam)) {
|
||||
case IDOK:
|
||||
if (preferences_settings_changed())
|
||||
preferences_settings_save();
|
||||
EndDialog(hdlg, 0);
|
||||
return TRUE;
|
||||
|
||||
case IDCANCEL:
|
||||
EndDialog(hdlg, 0);
|
||||
return TRUE;
|
||||
case IDCANCEL:
|
||||
EndDialog(hdlg, 0);
|
||||
return TRUE;
|
||||
|
||||
case IDC_COMBO_LANG:
|
||||
if (HIWORD(wParam) == CBN_SELCHANGE) {
|
||||
HWND combo = GetDlgItem(hdlg, IDC_COMBO_LANG);
|
||||
int index = SendMessage(combo, CB_GETCURSEL, 0, 0);
|
||||
temp_language = SendMessage(combo, CB_GETITEMDATA, index, 0);
|
||||
}
|
||||
break;
|
||||
case IDC_COMBO_LANG:
|
||||
if (HIWORD(wParam) == CBN_SELCHANGE) {
|
||||
HWND combo = GetDlgItem(hdlg, IDC_COMBO_LANG);
|
||||
int index = SendMessage(combo, CB_GETCURSEL, 0, 0);
|
||||
temp_language = SendMessage(combo, CB_GETITEMDATA, index, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_COMBO_ICON:
|
||||
if (HIWORD(wParam) == CBN_SELCHANGE) {
|
||||
HWND combo = GetDlgItem(hdlg, IDC_COMBO_ICON);
|
||||
int index = SendMessage(combo, CB_GETCURSEL, 0, 0);
|
||||
strcpy(temp_icon_set, (char*)SendMessage(combo, CB_GETITEMDATA, index, 0));
|
||||
}
|
||||
break;
|
||||
case IDC_COMBO_ICON:
|
||||
if (HIWORD(wParam) == CBN_SELCHANGE) {
|
||||
HWND combo = GetDlgItem(hdlg, IDC_COMBO_ICON);
|
||||
int index = SendMessage(combo, CB_GETCURSEL, 0, 0);
|
||||
strcpy(temp_icon_set, (char *) SendMessage(combo, CB_GETITEMDATA, index, 0));
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_BUTTON_DEFAULT: {
|
||||
HWND combo = GetDlgItem(hdlg, IDC_COMBO_LANG);
|
||||
int index = preferences_indexof(combo, DEFAULT_LANGUAGE);
|
||||
SendMessage(combo, CB_SETCURSEL, index, 0);
|
||||
temp_language = DEFAULT_LANGUAGE;
|
||||
break;
|
||||
}
|
||||
case IDC_BUTTON_DEFAULT:
|
||||
{
|
||||
HWND combo = GetDlgItem(hdlg, IDC_COMBO_LANG);
|
||||
int index = preferences_indexof(combo, DEFAULT_LANGUAGE);
|
||||
SendMessage(combo, CB_SETCURSEL, index, 0);
|
||||
temp_language = DEFAULT_LANGUAGE;
|
||||
break;
|
||||
}
|
||||
|
||||
case IDC_BUTTON_DEFICON: {
|
||||
SendMessage(GetDlgItem(hdlg, IDC_COMBO_ICON), CB_SETCURSEL, 0, 0);
|
||||
strcpy(temp_icon_set, "");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_DESTROY: {
|
||||
int i;
|
||||
LRESULT temp;
|
||||
HWND combo = GetDlgItem(hdlg, IDC_COMBO_ICON);
|
||||
for (i = 0; i < SendMessage(combo, CB_GETCOUNT, 0, 0); i++)
|
||||
{
|
||||
temp = SendMessage(combo, CB_GETITEMDATA, i, 0);
|
||||
if (temp)
|
||||
{
|
||||
free((void*)temp);
|
||||
SendMessage(combo, CB_SETITEMDATA, i, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IDC_BUTTON_DEFICON:
|
||||
{
|
||||
SendMessage(GetDlgItem(hdlg, IDC_COMBO_ICON), CB_SETCURSEL, 0, 0);
|
||||
strcpy(temp_icon_set, "");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_DESTROY:
|
||||
{
|
||||
int i;
|
||||
LRESULT temp;
|
||||
HWND combo = GetDlgItem(hdlg, IDC_COMBO_ICON);
|
||||
for (i = 0; i < SendMessage(combo, CB_GETCOUNT, 0, 0); i++) {
|
||||
temp = SendMessage(combo, CB_GETITEMDATA, i, 0);
|
||||
if (temp) {
|
||||
free((void *) temp);
|
||||
SendMessage(combo, CB_SETITEMDATA, i, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PreferencesDlgCreate(HWND hwnd)
|
||||
{
|
||||
DialogBox(hinstance, (LPCTSTR)DLG_PREFERENCES, hwnd, PreferencesDlgProcedure);
|
||||
DialogBox(hinstance, (LPCTSTR) DLG_PREFERENCES, hwnd, PreferencesDlgProcedure);
|
||||
}
|
||||
|
||||
@@ -72,48 +72,45 @@
|
||||
#include <86box/win_sdl.h>
|
||||
#include <86box/version.h>
|
||||
|
||||
#define RENDERER_FULL_SCREEN 1
|
||||
#define RENDERER_HARDWARE 2
|
||||
#define RENDERER_OPENGL 4
|
||||
|
||||
#define RENDERER_FULL_SCREEN 1
|
||||
#define RENDERER_HARDWARE 2
|
||||
#define RENDERER_OPENGL 4
|
||||
|
||||
|
||||
static SDL_Window *sdl_win = NULL;
|
||||
static SDL_Renderer *sdl_render = NULL;
|
||||
static SDL_Texture *sdl_tex = NULL;
|
||||
static HWND sdl_parent_hwnd = NULL;
|
||||
static int sdl_w, sdl_h;
|
||||
static int sdl_fs, sdl_flags = -1;
|
||||
static int cur_w, cur_h;
|
||||
static int cur_wx = 0, cur_wy = 0, cur_ww =0, cur_wh = 0;
|
||||
static volatile int sdl_enabled = 0;
|
||||
static SDL_mutex* sdl_mutex = NULL;
|
||||
|
||||
static SDL_Window *sdl_win = NULL;
|
||||
static SDL_Renderer *sdl_render = NULL;
|
||||
static SDL_Texture *sdl_tex = NULL;
|
||||
static HWND sdl_parent_hwnd = NULL;
|
||||
static int sdl_w, sdl_h;
|
||||
static int sdl_fs, sdl_flags = -1;
|
||||
static int cur_w, cur_h;
|
||||
static int cur_wx = 0, cur_wy = 0, cur_ww = 0, cur_wh = 0;
|
||||
static volatile int sdl_enabled = 0;
|
||||
static SDL_mutex *sdl_mutex = NULL;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const void *magic;
|
||||
Uint32 id;
|
||||
char *title;
|
||||
const void *magic;
|
||||
Uint32 id;
|
||||
char *title;
|
||||
SDL_Surface *icon;
|
||||
int x, y;
|
||||
int w, h;
|
||||
int min_w, min_h;
|
||||
int max_w, max_h;
|
||||
Uint32 flags;
|
||||
Uint32 last_fullscreen_flags;
|
||||
int x, y;
|
||||
int w, h;
|
||||
int min_w, min_h;
|
||||
int max_w, max_h;
|
||||
Uint32 flags;
|
||||
Uint32 last_fullscreen_flags;
|
||||
|
||||
/* Stored position and size for windowed mode */
|
||||
SDL_Rect windowed;
|
||||
|
||||
SDL_DisplayMode fullscreen_mode;
|
||||
|
||||
float brightness;
|
||||
float brightness;
|
||||
Uint16 *gamma;
|
||||
Uint16 *saved_gamma; /* (just offset into gamma) */
|
||||
Uint16 *saved_gamma; /* (just offset into gamma) */
|
||||
|
||||
SDL_Surface *surface;
|
||||
SDL_bool surface_valid;
|
||||
SDL_bool surface_valid;
|
||||
|
||||
SDL_bool is_hiding;
|
||||
SDL_bool is_destroying;
|
||||
@@ -121,7 +118,7 @@ typedef struct
|
||||
void *shaper;
|
||||
|
||||
SDL_HitTest hit_test;
|
||||
void *hit_test_data;
|
||||
void *hit_test_data;
|
||||
|
||||
void *data;
|
||||
|
||||
@@ -131,112 +128,107 @@ typedef struct
|
||||
SDL_Window *next;
|
||||
} SDL_Window_Ex;
|
||||
|
||||
|
||||
#ifdef ENABLE_SDL_LOG
|
||||
int sdl_do_log = ENABLE_SDL_LOG;
|
||||
|
||||
|
||||
static void
|
||||
sdl_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (sdl_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define sdl_log(fmt, ...)
|
||||
# define sdl_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
sdl_integer_scale(double *d, double *g)
|
||||
{
|
||||
double ratio;
|
||||
|
||||
if (*d > *g) {
|
||||
ratio = floor(*d / *g);
|
||||
*d = *g * ratio;
|
||||
ratio = floor(*d / *g);
|
||||
*d = *g * ratio;
|
||||
} else {
|
||||
ratio = ceil(*d / *g);
|
||||
*d = *g / ratio;
|
||||
ratio = ceil(*d / *g);
|
||||
*d = *g / ratio;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sdl_stretch(int *w, int *h, int *x, int *y)
|
||||
{
|
||||
double hw, gw, hh, gh, dx, dy, dw, dh, gsr, hsr;
|
||||
|
||||
hw = (double) sdl_w;
|
||||
hh = (double) sdl_h;
|
||||
gw = (double) *w;
|
||||
gh = (double) *h;
|
||||
hw = (double) sdl_w;
|
||||
hh = (double) sdl_h;
|
||||
gw = (double) *w;
|
||||
gh = (double) *h;
|
||||
hsr = hw / hh;
|
||||
|
||||
switch (video_fullscreen_scale) {
|
||||
case FULLSCR_SCALE_FULL:
|
||||
default:
|
||||
*w = sdl_w;
|
||||
*h = sdl_h;
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
break;
|
||||
case FULLSCR_SCALE_43:
|
||||
case FULLSCR_SCALE_KEEPRATIO:
|
||||
if (video_fullscreen_scale == FULLSCR_SCALE_43)
|
||||
gsr = 4.0 / 3.0;
|
||||
else
|
||||
gsr = gw / gh;
|
||||
if (gsr <= hsr) {
|
||||
dw = hh * gsr;
|
||||
dh = hh;
|
||||
} else {
|
||||
dw = hw;
|
||||
dh = hw / gsr;
|
||||
}
|
||||
dx = (hw - dw) / 2.0;
|
||||
dy = (hh - dh) / 2.0;
|
||||
*w = (int) dw;
|
||||
*h = (int) dh;
|
||||
*x = (int) dx;
|
||||
*y = (int) dy;
|
||||
break;
|
||||
case FULLSCR_SCALE_INT:
|
||||
gsr = gw / gh;
|
||||
if (gsr <= hsr) {
|
||||
dw = hh * gsr;
|
||||
dh = hh;
|
||||
} else {
|
||||
dw = hw;
|
||||
dh = hw / gsr;
|
||||
}
|
||||
sdl_integer_scale(&dw, &gw);
|
||||
sdl_integer_scale(&dh, &gh);
|
||||
dx = (hw - dw) / 2.0;
|
||||
dy = (hh - dh) / 2.0;
|
||||
*w = (int) dw;
|
||||
*h = (int) dh;
|
||||
*x = (int) dx;
|
||||
*y = (int) dy;
|
||||
break;
|
||||
case FULLSCR_SCALE_FULL:
|
||||
default:
|
||||
*w = sdl_w;
|
||||
*h = sdl_h;
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
break;
|
||||
case FULLSCR_SCALE_43:
|
||||
case FULLSCR_SCALE_KEEPRATIO:
|
||||
if (video_fullscreen_scale == FULLSCR_SCALE_43)
|
||||
gsr = 4.0 / 3.0;
|
||||
else
|
||||
gsr = gw / gh;
|
||||
if (gsr <= hsr) {
|
||||
dw = hh * gsr;
|
||||
dh = hh;
|
||||
} else {
|
||||
dw = hw;
|
||||
dh = hw / gsr;
|
||||
}
|
||||
dx = (hw - dw) / 2.0;
|
||||
dy = (hh - dh) / 2.0;
|
||||
*w = (int) dw;
|
||||
*h = (int) dh;
|
||||
*x = (int) dx;
|
||||
*y = (int) dy;
|
||||
break;
|
||||
case FULLSCR_SCALE_INT:
|
||||
gsr = gw / gh;
|
||||
if (gsr <= hsr) {
|
||||
dw = hh * gsr;
|
||||
dh = hh;
|
||||
} else {
|
||||
dw = hw;
|
||||
dh = hw / gsr;
|
||||
}
|
||||
sdl_integer_scale(&dw, &gw);
|
||||
sdl_integer_scale(&dh, &gh);
|
||||
dx = (hw - dw) / 2.0;
|
||||
dy = (hh - dh) / 2.0;
|
||||
*w = (int) dw;
|
||||
*h = (int) dh;
|
||||
*x = (int) dx;
|
||||
*y = (int) dy;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sdl_blit(int x, int y, int w, int h, int monitor_index)
|
||||
{
|
||||
SDL_Rect r_src;
|
||||
int ret;
|
||||
int ret;
|
||||
|
||||
if (!sdl_enabled || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (sdl_render == NULL) || (sdl_tex == NULL) || monitor_index >= 1) {
|
||||
video_blit_complete_monitor(monitor_index);
|
||||
return;
|
||||
video_blit_complete_monitor(monitor_index);
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_LockMutex(sdl_mutex);
|
||||
@@ -248,7 +240,7 @@ sdl_blit(int x, int y, int w, int h, int monitor_index)
|
||||
SDL_UpdateTexture(sdl_tex, &r_src, &(buffer32->line[y][x]), 2048 * sizeof(uint32_t));
|
||||
|
||||
if (monitors[0].mon_screenshots)
|
||||
video_screenshot((uint32_t *) buffer32->dat, x, y, 2048);
|
||||
video_screenshot((uint32_t *) buffer32->dat, x, y, 2048);
|
||||
|
||||
video_blit_complete();
|
||||
|
||||
@@ -261,24 +253,23 @@ sdl_blit(int x, int y, int w, int h, int monitor_index)
|
||||
|
||||
ret = SDL_RenderCopy(sdl_render, sdl_tex, &r_src, 0);
|
||||
if (ret)
|
||||
sdl_log("SDL: unable to copy texture to renderer (%s)\n", sdl_GetError());
|
||||
sdl_log("SDL: unable to copy texture to renderer (%s)\n", sdl_GetError());
|
||||
|
||||
SDL_RenderPresent(sdl_render);
|
||||
SDL_UnlockMutex(sdl_mutex);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sdl_blit_ex(int x, int y, int w, int h, int monitor_index)
|
||||
{
|
||||
SDL_Rect r_src;
|
||||
void *pixeldata;
|
||||
int pitch, ret;
|
||||
int row;
|
||||
void *pixeldata;
|
||||
int pitch, ret;
|
||||
int row;
|
||||
|
||||
if (!sdl_enabled || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (sdl_render == NULL) || (sdl_tex == NULL)) {
|
||||
video_blit_complete();
|
||||
return;
|
||||
video_blit_complete();
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_LockMutex(sdl_mutex);
|
||||
@@ -286,10 +277,10 @@ sdl_blit_ex(int x, int y, int w, int h, int monitor_index)
|
||||
SDL_LockTexture(sdl_tex, 0, &pixeldata, &pitch);
|
||||
|
||||
for (row = 0; row < h; ++row)
|
||||
video_copy(&(((uint8_t *) pixeldata)[row * 2048 * sizeof(uint32_t)]), &(buffer32->line[y + row][x]), w * sizeof(uint32_t));
|
||||
video_copy(&(((uint8_t *) pixeldata)[row * 2048 * sizeof(uint32_t)]), &(buffer32->line[y + row][x]), w * sizeof(uint32_t));
|
||||
|
||||
if (monitors[0].mon_screenshots)
|
||||
video_screenshot((uint32_t *) pixeldata, 0, 0, 2048);
|
||||
video_screenshot((uint32_t *) pixeldata, 0, 0, 2048);
|
||||
|
||||
SDL_UnlockTexture(sdl_tex);
|
||||
|
||||
@@ -304,54 +295,51 @@ sdl_blit_ex(int x, int y, int w, int h, int monitor_index)
|
||||
|
||||
ret = SDL_RenderCopy(sdl_render, sdl_tex, &r_src, 0);
|
||||
if (ret)
|
||||
sdl_log("SDL: unable to copy texture to renderer (%s)\n", sdl_GetError());
|
||||
sdl_log("SDL: unable to copy texture to renderer (%s)\n", sdl_GetError());
|
||||
|
||||
SDL_RenderPresent(sdl_render);
|
||||
SDL_UnlockMutex(sdl_mutex);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sdl_destroy_window(void)
|
||||
{
|
||||
if (sdl_win != NULL) {
|
||||
SDL_DestroyWindow(sdl_win);
|
||||
sdl_win = NULL;
|
||||
SDL_DestroyWindow(sdl_win);
|
||||
sdl_win = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sdl_destroy_texture(void)
|
||||
{
|
||||
if (sdl_tex != NULL) {
|
||||
SDL_DestroyTexture(sdl_tex);
|
||||
sdl_tex = NULL;
|
||||
SDL_DestroyTexture(sdl_tex);
|
||||
sdl_tex = NULL;
|
||||
}
|
||||
|
||||
/* SDL_DestroyRenderer also automatically destroys all associated textures. */
|
||||
if (sdl_render != NULL) {
|
||||
SDL_DestroyRenderer(sdl_render);
|
||||
sdl_render = NULL;
|
||||
SDL_DestroyRenderer(sdl_render);
|
||||
sdl_render = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sdl_close(void)
|
||||
{
|
||||
if (sdl_mutex != NULL)
|
||||
SDL_LockMutex(sdl_mutex);
|
||||
SDL_LockMutex(sdl_mutex);
|
||||
|
||||
/* Unregister our renderer! */
|
||||
video_setblit(NULL);
|
||||
|
||||
if (sdl_enabled)
|
||||
sdl_enabled = 0;
|
||||
sdl_enabled = 0;
|
||||
|
||||
if (sdl_mutex != NULL) {
|
||||
SDL_DestroyMutex(sdl_mutex);
|
||||
sdl_mutex = NULL;
|
||||
SDL_DestroyMutex(sdl_mutex);
|
||||
sdl_mutex = NULL;
|
||||
}
|
||||
|
||||
sdl_destroy_texture();
|
||||
@@ -360,8 +348,8 @@ sdl_close(void)
|
||||
SetFocus(hwndMain);
|
||||
|
||||
if (sdl_parent_hwnd != NULL) {
|
||||
DestroyWindow(sdl_parent_hwnd);
|
||||
sdl_parent_hwnd = NULL;
|
||||
DestroyWindow(sdl_parent_hwnd);
|
||||
sdl_parent_hwnd = NULL;
|
||||
}
|
||||
|
||||
/* Quit. */
|
||||
@@ -369,41 +357,36 @@ sdl_close(void)
|
||||
sdl_flags = -1;
|
||||
}
|
||||
|
||||
|
||||
static int old_capture = 0;
|
||||
|
||||
|
||||
static void
|
||||
sdl_select_best_hw_driver(void)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
SDL_RendererInfo renderInfo;
|
||||
|
||||
for (i = 0; i < SDL_GetNumRenderDrivers(); ++i)
|
||||
{
|
||||
SDL_GetRenderDriverInfo(i, &renderInfo);
|
||||
if (renderInfo.flags & SDL_RENDERER_ACCELERATED) {
|
||||
SDL_SetHint(SDL_HINT_RENDER_DRIVER, renderInfo.name);
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) {
|
||||
SDL_GetRenderDriverInfo(i, &renderInfo);
|
||||
if (renderInfo.flags & SDL_RENDERER_ACCELERATED) {
|
||||
SDL_SetHint(SDL_HINT_RENDER_DRIVER, renderInfo.name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sdl_init_texture(void)
|
||||
{
|
||||
if (sdl_flags & RENDERER_HARDWARE) {
|
||||
sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_ACCELERATED);
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_filter_method ? "1" : "0");
|
||||
sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_ACCELERATED);
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_filter_method ? "1" : "0");
|
||||
} else
|
||||
sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_SOFTWARE);
|
||||
sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_SOFTWARE);
|
||||
|
||||
sdl_tex = SDL_CreateTexture(sdl_render, SDL_PIXELFORMAT_ARGB8888,
|
||||
SDL_TEXTUREACCESS_STREAMING, 2048, 2048);
|
||||
SDL_TEXTUREACCESS_STREAMING, 2048, 2048);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sdl_reinit_texture(void)
|
||||
{
|
||||
@@ -414,67 +397,65 @@ sdl_reinit_texture(void)
|
||||
sdl_init_texture();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sdl_set_fs(int fs)
|
||||
{
|
||||
int w = 0, h = 0, x = 0, y = 0;
|
||||
int w = 0, h = 0, x = 0, y = 0;
|
||||
RECT rect;
|
||||
|
||||
SDL_LockMutex(sdl_mutex);
|
||||
sdl_enabled = 0;
|
||||
|
||||
if (fs) {
|
||||
ShowWindow(sdl_parent_hwnd, TRUE);
|
||||
SetParent(hwndRender, sdl_parent_hwnd);
|
||||
ShowWindow(hwndRender, TRUE);
|
||||
MoveWindow(sdl_parent_hwnd, 0, 0, sdl_w, sdl_h, TRUE);
|
||||
ShowWindow(sdl_parent_hwnd, TRUE);
|
||||
SetParent(hwndRender, sdl_parent_hwnd);
|
||||
ShowWindow(hwndRender, TRUE);
|
||||
MoveWindow(sdl_parent_hwnd, 0, 0, sdl_w, sdl_h, TRUE);
|
||||
|
||||
/* Show the window, make it topmost, and give it focus. */
|
||||
w = unscaled_size_x;
|
||||
h = efscrnsz_y;
|
||||
sdl_stretch(&w, &h, &x, &y);
|
||||
MoveWindow(hwndRender, x, y, w, h, TRUE);
|
||||
ImmAssociateContext(sdl_parent_hwnd, NULL);
|
||||
SetFocus(sdl_parent_hwnd);
|
||||
/* Show the window, make it topmost, and give it focus. */
|
||||
w = unscaled_size_x;
|
||||
h = efscrnsz_y;
|
||||
sdl_stretch(&w, &h, &x, &y);
|
||||
MoveWindow(hwndRender, x, y, w, h, TRUE);
|
||||
ImmAssociateContext(sdl_parent_hwnd, NULL);
|
||||
SetFocus(sdl_parent_hwnd);
|
||||
|
||||
/* Redirect RawInput to this new window. */
|
||||
old_capture = mouse_capture;
|
||||
GetWindowRect(hwndRender, &rect);
|
||||
ClipCursor(&rect);
|
||||
mouse_capture = 1;
|
||||
/* Redirect RawInput to this new window. */
|
||||
old_capture = mouse_capture;
|
||||
GetWindowRect(hwndRender, &rect);
|
||||
ClipCursor(&rect);
|
||||
mouse_capture = 1;
|
||||
} else {
|
||||
SetParent(hwndRender, hwndMain);
|
||||
ShowWindow(sdl_parent_hwnd, FALSE);
|
||||
ShowWindow(hwndRender, TRUE);
|
||||
ImmAssociateContext(hwndMain, NULL);
|
||||
SetFocus(hwndMain);
|
||||
mouse_capture = old_capture;
|
||||
SetParent(hwndRender, hwndMain);
|
||||
ShowWindow(sdl_parent_hwnd, FALSE);
|
||||
ShowWindow(hwndRender, TRUE);
|
||||
ImmAssociateContext(hwndMain, NULL);
|
||||
SetFocus(hwndMain);
|
||||
mouse_capture = old_capture;
|
||||
|
||||
if (mouse_capture) {
|
||||
GetWindowRect(hwndRender, &rect);
|
||||
ClipCursor(&rect);
|
||||
} else
|
||||
ClipCursor(&oldclip);
|
||||
if (mouse_capture) {
|
||||
GetWindowRect(hwndRender, &rect);
|
||||
ClipCursor(&rect);
|
||||
} else
|
||||
ClipCursor(&oldclip);
|
||||
}
|
||||
|
||||
sdl_fs = fs;
|
||||
|
||||
if (fs)
|
||||
sdl_flags |= RENDERER_FULL_SCREEN;
|
||||
sdl_flags |= RENDERER_FULL_SCREEN;
|
||||
else
|
||||
sdl_flags &= ~RENDERER_FULL_SCREEN;
|
||||
sdl_flags &= ~RENDERER_FULL_SCREEN;
|
||||
|
||||
// sdl_reinit_texture();
|
||||
sdl_enabled = 1;
|
||||
SDL_UnlockMutex(sdl_mutex);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
sdl_init_common(int flags)
|
||||
{
|
||||
wchar_t temp[128];
|
||||
wchar_t temp[128];
|
||||
SDL_version ver;
|
||||
|
||||
sdl_log("SDL: init (fs=%d)\n", fs);
|
||||
@@ -485,15 +466,15 @@ sdl_init_common(int flags)
|
||||
|
||||
/* Initialize the SDL system. */
|
||||
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
||||
sdl_log("SDL: initialization failed (%s)\n", sdl_GetError());
|
||||
return(0);
|
||||
sdl_log("SDL: initialization failed (%s)\n", sdl_GetError());
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (flags & RENDERER_HARDWARE) {
|
||||
if (flags & RENDERER_OPENGL)
|
||||
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "OpenGL");
|
||||
else
|
||||
sdl_select_best_hw_driver();
|
||||
if (flags & RENDERER_OPENGL)
|
||||
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "OpenGL");
|
||||
else
|
||||
sdl_select_best_hw_driver();
|
||||
}
|
||||
|
||||
/* Get the size of the (current) desktop. */
|
||||
@@ -503,16 +484,16 @@ sdl_init_common(int flags)
|
||||
/* Create the desktop-covering window. */
|
||||
_swprintf(temp, L"%s v%s", EMU_NAME_W, EMU_VERSION_FULL_W);
|
||||
sdl_parent_hwnd = CreateWindow(SDL_CLASS_NAME, temp, WS_POPUP, 0, 0, sdl_w, sdl_h,
|
||||
HWND_DESKTOP, NULL, hinstance, NULL);
|
||||
HWND_DESKTOP, NULL, hinstance, NULL);
|
||||
ShowWindow(sdl_parent_hwnd, FALSE);
|
||||
|
||||
sdl_flags = flags;
|
||||
|
||||
if (sdl_win == NULL) {
|
||||
sdl_log("SDL: unable to CreateWindowFrom (%s)\n", SDL_GetError());
|
||||
sdl_log("SDL: unable to CreateWindowFrom (%s)\n", SDL_GetError());
|
||||
}
|
||||
|
||||
sdl_win = SDL_CreateWindowFrom((void *)hwndRender);
|
||||
sdl_win = SDL_CreateWindowFrom((void *) hwndRender);
|
||||
sdl_init_texture();
|
||||
sdl_set_fs(video_fullscreen & 1);
|
||||
|
||||
@@ -523,50 +504,45 @@ sdl_init_common(int flags)
|
||||
video_setblit((video_grayscale || invert_display) ? sdl_blit_ex : sdl_blit);
|
||||
|
||||
sdl_enabled = 1;
|
||||
sdl_mutex = SDL_CreateMutex();
|
||||
sdl_mutex = SDL_CreateMutex();
|
||||
|
||||
return(1);
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sdl_inits(HWND h)
|
||||
{
|
||||
return sdl_init_common(0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sdl_inith(HWND h)
|
||||
{
|
||||
return sdl_init_common(RENDERER_HARDWARE);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sdl_initho(HWND h)
|
||||
{
|
||||
return sdl_init_common(RENDERER_HARDWARE | RENDERER_OPENGL);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sdl_pause(void)
|
||||
{
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sdl_resize(int x, int y)
|
||||
{
|
||||
int ww = 0, wh = 0, wx = 0, wy = 0;
|
||||
|
||||
if (video_fullscreen & 2)
|
||||
return;
|
||||
return;
|
||||
|
||||
if ((x == cur_w) && (y == cur_h))
|
||||
return;
|
||||
return;
|
||||
|
||||
SDL_LockMutex(sdl_mutex);
|
||||
|
||||
@@ -574,8 +550,8 @@ sdl_resize(int x, int y)
|
||||
wh = y;
|
||||
|
||||
if (sdl_fs) {
|
||||
sdl_stretch(&ww, &wh, &wx, &wy);
|
||||
MoveWindow(hwndRender, wx, wy, ww, wh, TRUE);
|
||||
sdl_stretch(&ww, &wh, &wx, &wy);
|
||||
MoveWindow(hwndRender, wx, wy, ww, wh, TRUE);
|
||||
}
|
||||
|
||||
cur_w = x;
|
||||
@@ -594,35 +570,33 @@ sdl_resize(int x, int y)
|
||||
SDL_UnlockMutex(sdl_mutex);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sdl_enable(int enable)
|
||||
{
|
||||
if (sdl_flags == -1)
|
||||
return;
|
||||
return;
|
||||
|
||||
SDL_LockMutex(sdl_mutex);
|
||||
sdl_enabled = !!enable;
|
||||
|
||||
if (enable == 1) {
|
||||
SDL_SetWindowSize(sdl_win, cur_ww, cur_wh);
|
||||
sdl_reinit_texture();
|
||||
SDL_SetWindowSize(sdl_win, cur_ww, cur_wh);
|
||||
sdl_reinit_texture();
|
||||
}
|
||||
|
||||
SDL_UnlockMutex(sdl_mutex);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sdl_reload(void)
|
||||
{
|
||||
if (sdl_flags & RENDERER_HARDWARE) {
|
||||
SDL_LockMutex(sdl_mutex);
|
||||
SDL_LockMutex(sdl_mutex);
|
||||
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_filter_method ? "1" : "0");
|
||||
sdl_reinit_texture();
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_filter_method ? "1" : "0");
|
||||
sdl_reinit_texture();
|
||||
|
||||
SDL_UnlockMutex(sdl_mutex);
|
||||
SDL_UnlockMutex(sdl_mutex);
|
||||
}
|
||||
|
||||
video_setblit((video_grayscale || invert_display) ? sdl_blit_ex : sdl_blit);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,9 +31,7 @@
|
||||
#include <86box/sound.h>
|
||||
#include <86box/win.h>
|
||||
|
||||
|
||||
static uint8_t old_gain;
|
||||
|
||||
static uint8_t old_gain;
|
||||
|
||||
#if defined(__amd64__) || defined(__aarch64__)
|
||||
static LRESULT CALLBACK
|
||||
@@ -45,48 +43,47 @@ SoundGainDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
HWND h;
|
||||
|
||||
switch (message) {
|
||||
case WM_INITDIALOG:
|
||||
old_gain = sound_gain;
|
||||
h = GetDlgItem(hdlg, IDC_SLIDER_GAIN);
|
||||
SendMessage(h, TBM_SETRANGE, (WPARAM)1, (LPARAM)MAKELONG(0, 9));
|
||||
SendMessage(h, TBM_SETPOS, (WPARAM)1, 9 - (sound_gain >> 1));
|
||||
SendMessage(h, TBM_SETTICFREQ, (WPARAM)1, 0);
|
||||
SendMessage(h, TBM_SETLINESIZE, (WPARAM)0, 1);
|
||||
SendMessage(h, TBM_SETPAGESIZE, (WPARAM)0, 2);
|
||||
break;
|
||||
case WM_INITDIALOG:
|
||||
old_gain = sound_gain;
|
||||
h = GetDlgItem(hdlg, IDC_SLIDER_GAIN);
|
||||
SendMessage(h, TBM_SETRANGE, (WPARAM) 1, (LPARAM) MAKELONG(0, 9));
|
||||
SendMessage(h, TBM_SETPOS, (WPARAM) 1, 9 - (sound_gain >> 1));
|
||||
SendMessage(h, TBM_SETTICFREQ, (WPARAM) 1, 0);
|
||||
SendMessage(h, TBM_SETLINESIZE, (WPARAM) 0, 1);
|
||||
SendMessage(h, TBM_SETPAGESIZE, (WPARAM) 0, 2);
|
||||
break;
|
||||
|
||||
case WM_VSCROLL:
|
||||
h = GetDlgItem(hdlg, IDC_SLIDER_GAIN);
|
||||
sound_gain = (9 - SendMessage(h, TBM_GETPOS, (WPARAM)0, 0)) << 1;
|
||||
break;
|
||||
case WM_VSCROLL:
|
||||
h = GetDlgItem(hdlg, IDC_SLIDER_GAIN);
|
||||
sound_gain = (9 - SendMessage(h, TBM_GETPOS, (WPARAM) 0, 0)) << 1;
|
||||
break;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam)) {
|
||||
case IDOK:
|
||||
h = GetDlgItem(hdlg, IDC_SLIDER_GAIN);
|
||||
sound_gain = (9 - SendMessage(h, TBM_GETPOS, (WPARAM)0, 0)) << 1;
|
||||
config_save();
|
||||
EndDialog(hdlg, 0);
|
||||
return TRUE;
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam)) {
|
||||
case IDOK:
|
||||
h = GetDlgItem(hdlg, IDC_SLIDER_GAIN);
|
||||
sound_gain = (9 - SendMessage(h, TBM_GETPOS, (WPARAM) 0, 0)) << 1;
|
||||
config_save();
|
||||
EndDialog(hdlg, 0);
|
||||
return TRUE;
|
||||
|
||||
case IDCANCEL:
|
||||
sound_gain = old_gain;
|
||||
config_save();
|
||||
EndDialog(hdlg, 0);
|
||||
return TRUE;
|
||||
case IDCANCEL:
|
||||
sound_gain = old_gain;
|
||||
config_save();
|
||||
EndDialog(hdlg, 0);
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SoundGainDialogCreate(HWND hwnd)
|
||||
{
|
||||
DialogBox(hinstance, (LPCTSTR)DLG_SND_GAIN, hwnd, SoundGainDialogProcedure);
|
||||
DialogBox(hinstance, (LPCTSTR) DLG_SND_GAIN, hwnd, SoundGainDialogProcedure);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
#include <86box/sound.h>
|
||||
#include <86box/win.h>
|
||||
|
||||
|
||||
#if defined(__amd64__) || defined(__aarch64__)
|
||||
static LRESULT CALLBACK
|
||||
#else
|
||||
@@ -40,140 +39,139 @@ static BOOL CALLBACK
|
||||
#endif
|
||||
SpecifyDimensionsDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
HWND h, h2;
|
||||
HMENU hmenu;
|
||||
UDACCEL accel, accel2;
|
||||
RECT r;
|
||||
HWND h, h2;
|
||||
HMENU hmenu;
|
||||
UDACCEL accel, accel2;
|
||||
RECT r;
|
||||
uint32_t temp_x = 0, temp_y = 0;
|
||||
int dpi = 96, lock;
|
||||
LPTSTR lptsTemp;
|
||||
char *stransi;
|
||||
int dpi = 96, lock;
|
||||
LPTSTR lptsTemp;
|
||||
char *stransi;
|
||||
|
||||
switch (message) {
|
||||
case WM_INITDIALOG:
|
||||
GetWindowRect(hwndRender, &r);
|
||||
case WM_INITDIALOG:
|
||||
GetWindowRect(hwndRender, &r);
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_WIDTHSPIN);
|
||||
h2 = GetDlgItem(hdlg, IDC_EDIT_WIDTH);
|
||||
SendMessage(h, UDM_SETBUDDY, (WPARAM)h2, 0);
|
||||
SendMessage(h, UDM_SETRANGE, 0, (120 << 16) | 2048);
|
||||
accel.nSec = 0;
|
||||
accel.nInc = 8;
|
||||
SendMessage(h, UDM_SETACCEL, 1, (LPARAM)&accel);
|
||||
SendMessage(h, UDM_SETPOS, 0, r.right - r.left);
|
||||
h = GetDlgItem(hdlg, IDC_WIDTHSPIN);
|
||||
h2 = GetDlgItem(hdlg, IDC_EDIT_WIDTH);
|
||||
SendMessage(h, UDM_SETBUDDY, (WPARAM) h2, 0);
|
||||
SendMessage(h, UDM_SETRANGE, 0, (120 << 16) | 2048);
|
||||
accel.nSec = 0;
|
||||
accel.nInc = 8;
|
||||
SendMessage(h, UDM_SETACCEL, 1, (LPARAM) &accel);
|
||||
SendMessage(h, UDM_SETPOS, 0, r.right - r.left);
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_HEIGHTSPIN);
|
||||
h2 = GetDlgItem(hdlg, IDC_EDIT_HEIGHT);
|
||||
SendMessage(h, UDM_SETBUDDY, (WPARAM)h2, 0);
|
||||
SendMessage(h, UDM_SETRANGE, 0, (120 << 16) | 2048);
|
||||
accel2.nSec = 0;
|
||||
accel2.nInc = 8;
|
||||
SendMessage(h, UDM_SETACCEL, 1, (LPARAM)&accel2);
|
||||
SendMessage(h, UDM_SETPOS, 0, r.bottom - r.top);
|
||||
h = GetDlgItem(hdlg, IDC_HEIGHTSPIN);
|
||||
h2 = GetDlgItem(hdlg, IDC_EDIT_HEIGHT);
|
||||
SendMessage(h, UDM_SETBUDDY, (WPARAM) h2, 0);
|
||||
SendMessage(h, UDM_SETRANGE, 0, (120 << 16) | 2048);
|
||||
accel2.nSec = 0;
|
||||
accel2.nInc = 8;
|
||||
SendMessage(h, UDM_SETACCEL, 1, (LPARAM) &accel2);
|
||||
SendMessage(h, UDM_SETPOS, 0, r.bottom - r.top);
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_CHECK_LOCK_SIZE);
|
||||
SendMessage(h, BM_SETCHECK, !!(vid_resize & 2), 0);
|
||||
break;
|
||||
h = GetDlgItem(hdlg, IDC_CHECK_LOCK_SIZE);
|
||||
SendMessage(h, BM_SETCHECK, !!(vid_resize & 2), 0);
|
||||
break;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam)) {
|
||||
case IDOK:
|
||||
lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR));
|
||||
stransi = (char *)malloc(512);
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam)) {
|
||||
case IDOK:
|
||||
lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR));
|
||||
stransi = (char *) malloc(512);
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_EDIT_WIDTH);
|
||||
SendMessage(h, WM_GETTEXT, 255, (LPARAM) lptsTemp);
|
||||
wcstombs(stransi, lptsTemp, 512);
|
||||
sscanf(stransi, "%u", &temp_x);
|
||||
fixed_size_x = temp_x;
|
||||
h = GetDlgItem(hdlg, IDC_EDIT_WIDTH);
|
||||
SendMessage(h, WM_GETTEXT, 255, (LPARAM) lptsTemp);
|
||||
wcstombs(stransi, lptsTemp, 512);
|
||||
sscanf(stransi, "%u", &temp_x);
|
||||
fixed_size_x = temp_x;
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_EDIT_HEIGHT);
|
||||
SendMessage(h, WM_GETTEXT, 255, (LPARAM) lptsTemp);
|
||||
wcstombs(stransi, lptsTemp, 512);
|
||||
sscanf(stransi, "%u", &temp_y);
|
||||
fixed_size_y = temp_y;
|
||||
h = GetDlgItem(hdlg, IDC_EDIT_HEIGHT);
|
||||
SendMessage(h, WM_GETTEXT, 255, (LPARAM) lptsTemp);
|
||||
wcstombs(stransi, lptsTemp, 512);
|
||||
sscanf(stransi, "%u", &temp_y);
|
||||
fixed_size_y = temp_y;
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_CHECK_LOCK_SIZE);
|
||||
lock = SendMessage(h, BM_GETCHECK, 0, 0);
|
||||
h = GetDlgItem(hdlg, IDC_CHECK_LOCK_SIZE);
|
||||
lock = SendMessage(h, BM_GETCHECK, 0, 0);
|
||||
|
||||
if (lock) {
|
||||
vid_resize = 2;
|
||||
window_remember = 0;
|
||||
} else {
|
||||
vid_resize = 1;
|
||||
window_remember = 1;
|
||||
}
|
||||
hmenu = GetMenu(hwndMain);
|
||||
CheckMenuItem(hmenu, IDM_VID_REMEMBER, (window_remember == 1) ? MF_CHECKED : MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, IDM_VID_RESIZE, (vid_resize == 1) ? MF_CHECKED : MF_UNCHECKED);
|
||||
EnableMenuItem(hmenu, IDM_VID_RESIZE, (vid_resize & 2) ? MF_GRAYED : MF_ENABLED);
|
||||
if (lock) {
|
||||
vid_resize = 2;
|
||||
window_remember = 0;
|
||||
} else {
|
||||
vid_resize = 1;
|
||||
window_remember = 1;
|
||||
}
|
||||
hmenu = GetMenu(hwndMain);
|
||||
CheckMenuItem(hmenu, IDM_VID_REMEMBER, (window_remember == 1) ? MF_CHECKED : MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, IDM_VID_RESIZE, (vid_resize == 1) ? MF_CHECKED : MF_UNCHECKED);
|
||||
EnableMenuItem(hmenu, IDM_VID_RESIZE, (vid_resize & 2) ? MF_GRAYED : MF_ENABLED);
|
||||
|
||||
if (vid_resize == 1)
|
||||
SetWindowLongPtr(hwndMain, GWL_STYLE, (WS_OVERLAPPEDWINDOW) | WS_VISIBLE);
|
||||
else
|
||||
SetWindowLongPtr(hwndMain, GWL_STYLE, (WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX & ~WS_MAXIMIZEBOX) | WS_VISIBLE);
|
||||
if (vid_resize == 1)
|
||||
SetWindowLongPtr(hwndMain, GWL_STYLE, (WS_OVERLAPPEDWINDOW) | WS_VISIBLE);
|
||||
else
|
||||
SetWindowLongPtr(hwndMain, GWL_STYLE, (WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX & ~WS_MAXIMIZEBOX) | WS_VISIBLE);
|
||||
|
||||
/* scale the screen base on DPI */
|
||||
if (dpi_scale) {
|
||||
dpi = win_get_dpi(hwndMain);
|
||||
temp_x = MulDiv(temp_x, dpi, 96);
|
||||
temp_y = MulDiv(temp_y, dpi, 96);
|
||||
}
|
||||
/* scale the screen base on DPI */
|
||||
if (dpi_scale) {
|
||||
dpi = win_get_dpi(hwndMain);
|
||||
temp_x = MulDiv(temp_x, dpi, 96);
|
||||
temp_y = MulDiv(temp_y, dpi, 96);
|
||||
}
|
||||
|
||||
ResizeWindowByClientArea(hwndMain, temp_x, temp_y + sbar_height + tbar_height);
|
||||
ResizeWindowByClientArea(hwndMain, temp_x, temp_y + sbar_height + tbar_height);
|
||||
|
||||
if (vid_resize) {
|
||||
CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, IDM_VID_SCALE_2X, MF_CHECKED);
|
||||
scale = 1;
|
||||
}
|
||||
EnableMenuItem(hmenu, IDM_VID_SCALE_1X, vid_resize ? MF_GRAYED : MF_ENABLED);
|
||||
EnableMenuItem(hmenu, IDM_VID_SCALE_2X, vid_resize ? MF_GRAYED : MF_ENABLED);
|
||||
EnableMenuItem(hmenu, IDM_VID_SCALE_3X, vid_resize ? MF_GRAYED : MF_ENABLED);
|
||||
EnableMenuItem(hmenu, IDM_VID_SCALE_4X, vid_resize ? MF_GRAYED : MF_ENABLED);
|
||||
if (vid_resize) {
|
||||
CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, IDM_VID_SCALE_2X, MF_CHECKED);
|
||||
scale = 1;
|
||||
}
|
||||
EnableMenuItem(hmenu, IDM_VID_SCALE_1X, vid_resize ? MF_GRAYED : MF_ENABLED);
|
||||
EnableMenuItem(hmenu, IDM_VID_SCALE_2X, vid_resize ? MF_GRAYED : MF_ENABLED);
|
||||
EnableMenuItem(hmenu, IDM_VID_SCALE_3X, vid_resize ? MF_GRAYED : MF_ENABLED);
|
||||
EnableMenuItem(hmenu, IDM_VID_SCALE_4X, vid_resize ? MF_GRAYED : MF_ENABLED);
|
||||
|
||||
scrnsz_x = fixed_size_x;
|
||||
scrnsz_y = fixed_size_y;
|
||||
atomic_store(&doresize_monitors[0], 1);
|
||||
scrnsz_x = fixed_size_x;
|
||||
scrnsz_y = fixed_size_y;
|
||||
atomic_store(&doresize_monitors[0], 1);
|
||||
|
||||
GetWindowRect(hwndMain, &r);
|
||||
GetWindowRect(hwndMain, &r);
|
||||
|
||||
if (mouse_capture)
|
||||
ClipCursor(&r);
|
||||
if (mouse_capture)
|
||||
ClipCursor(&r);
|
||||
|
||||
if (window_remember || (vid_resize & 2)) {
|
||||
window_x = r.left;
|
||||
window_y = r.top;
|
||||
if (!(vid_resize & 2)) {
|
||||
window_w = r.right - r.left;
|
||||
window_h = r.bottom - r.top;
|
||||
}
|
||||
}
|
||||
if (window_remember || (vid_resize & 2)) {
|
||||
window_x = r.left;
|
||||
window_y = r.top;
|
||||
if (!(vid_resize & 2)) {
|
||||
window_w = r.right - r.left;
|
||||
window_h = r.bottom - r.top;
|
||||
}
|
||||
}
|
||||
|
||||
config_save();
|
||||
config_save();
|
||||
|
||||
free(stransi);
|
||||
free(lptsTemp);
|
||||
free(stransi);
|
||||
free(lptsTemp);
|
||||
|
||||
EndDialog(hdlg, 0);
|
||||
return TRUE;
|
||||
EndDialog(hdlg, 0);
|
||||
return TRUE;
|
||||
|
||||
case IDCANCEL:
|
||||
EndDialog(hdlg, 0);
|
||||
return TRUE;
|
||||
case IDCANCEL:
|
||||
EndDialog(hdlg, 0);
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SpecifyDimensionsDialogCreate(HWND hwnd)
|
||||
{
|
||||
DialogBox(hinstance, (LPCTSTR)DLG_SPECIFY_DIM, hwnd, SpecifyDimensionsDialogProcedure);
|
||||
DialogBox(hinstance, (LPCTSTR) DLG_SPECIFY_DIM, hwnd, SpecifyDimensionsDialogProcedure);
|
||||
}
|
||||
|
||||
1098
src/win/win_stbar.c
1098
src/win/win_stbar.c
File diff suppressed because it is too large
Load Diff
@@ -36,36 +36,34 @@ typedef struct {
|
||||
HANDLE handle;
|
||||
} win_event_t;
|
||||
|
||||
|
||||
thread_t *
|
||||
thread_create(void (*func)(void *param), void *param)
|
||||
{
|
||||
uintptr_t bt = _beginthread(func, 0, param);
|
||||
return((thread_t *)bt);
|
||||
return ((thread_t *) bt);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
thread_test_mutex(thread_t *arg)
|
||||
{
|
||||
if (arg == NULL) return(0);
|
||||
if (arg == NULL)
|
||||
return (0);
|
||||
|
||||
return (WaitForSingleObject(arg, 0) == WAIT_OBJECT_0) ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
thread_wait(thread_t *arg)
|
||||
{
|
||||
if (arg == NULL) return(0);
|
||||
if (arg == NULL)
|
||||
return (0);
|
||||
|
||||
if (WaitForSingleObject(arg, INFINITE)) return(1);
|
||||
if (WaitForSingleObject(arg, INFINITE))
|
||||
return (1);
|
||||
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
event_t *
|
||||
thread_create_event(void)
|
||||
{
|
||||
@@ -73,63 +71,64 @@ thread_create_event(void)
|
||||
|
||||
ev->handle = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
|
||||
return((event_t *)ev);
|
||||
return ((event_t *) ev);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
thread_set_event(event_t *arg)
|
||||
{
|
||||
win_event_t *ev = (win_event_t *)arg;
|
||||
win_event_t *ev = (win_event_t *) arg;
|
||||
|
||||
if (arg == NULL) return;
|
||||
if (arg == NULL)
|
||||
return;
|
||||
|
||||
SetEvent(ev->handle);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
thread_reset_event(event_t *arg)
|
||||
{
|
||||
win_event_t *ev = (win_event_t *)arg;
|
||||
win_event_t *ev = (win_event_t *) arg;
|
||||
|
||||
if (arg == NULL) return;
|
||||
if (arg == NULL)
|
||||
return;
|
||||
|
||||
ResetEvent(ev->handle);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
thread_wait_event(event_t *arg, int timeout)
|
||||
{
|
||||
win_event_t *ev = (win_event_t *)arg;
|
||||
win_event_t *ev = (win_event_t *) arg;
|
||||
|
||||
if (arg == NULL) return(0);
|
||||
if (arg == NULL)
|
||||
return (0);
|
||||
|
||||
if (ev->handle == NULL) return(0);
|
||||
if (ev->handle == NULL)
|
||||
return (0);
|
||||
|
||||
if (timeout == -1)
|
||||
timeout = INFINITE;
|
||||
timeout = INFINITE;
|
||||
|
||||
if (WaitForSingleObject(ev->handle, timeout)) return(1);
|
||||
if (WaitForSingleObject(ev->handle, timeout))
|
||||
return (1);
|
||||
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
thread_destroy_event(event_t *arg)
|
||||
{
|
||||
win_event_t *ev = (win_event_t *)arg;
|
||||
win_event_t *ev = (win_event_t *) arg;
|
||||
|
||||
if (arg == NULL) return;
|
||||
if (arg == NULL)
|
||||
return;
|
||||
|
||||
CloseHandle(ev->handle);
|
||||
|
||||
free(ev);
|
||||
}
|
||||
|
||||
|
||||
mutex_t *
|
||||
thread_create_mutex(void)
|
||||
{
|
||||
@@ -140,39 +139,39 @@ thread_create_mutex(void)
|
||||
return mutex;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
thread_wait_mutex(mutex_t *mutex)
|
||||
{
|
||||
if (mutex == NULL) return(0);
|
||||
if (mutex == NULL)
|
||||
return (0);
|
||||
|
||||
LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION)mutex;
|
||||
LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION) mutex;
|
||||
|
||||
EnterCriticalSection(critsec);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
thread_release_mutex(mutex_t *mutex)
|
||||
{
|
||||
if (mutex == NULL) return(0);
|
||||
if (mutex == NULL)
|
||||
return (0);
|
||||
|
||||
LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION)mutex;
|
||||
LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION) mutex;
|
||||
|
||||
LeaveCriticalSection(critsec);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
thread_close_mutex(mutex_t *mutex)
|
||||
{
|
||||
if (mutex == NULL) return;
|
||||
if (mutex == NULL)
|
||||
return;
|
||||
|
||||
LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION)mutex;
|
||||
LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION) mutex;
|
||||
|
||||
DeleteCriticalSection(critsec);
|
||||
|
||||
|
||||
@@ -11,36 +11,34 @@
|
||||
#include <86box/video.h>
|
||||
#include <86box/win.h>
|
||||
|
||||
HWND hwndRebar = NULL;
|
||||
static HWND hwndToolbar = NULL;
|
||||
static HIMAGELIST hImageList = NULL;
|
||||
static wchar_t wTitle[512] = { 0 };
|
||||
static WNDPROC pOriginalProcedure = NULL;
|
||||
|
||||
HWND hwndRebar = NULL;
|
||||
static HWND hwndToolbar = NULL;
|
||||
static HIMAGELIST hImageList = NULL;
|
||||
static wchar_t wTitle[512] = { 0 };
|
||||
static WNDPROC pOriginalProcedure = NULL;
|
||||
|
||||
enum image_index {
|
||||
RUN,
|
||||
PAUSE,
|
||||
CTRL_ALT_DEL,
|
||||
CTRL_ALT_ESC,
|
||||
HARD_RESET,
|
||||
ACPI_SHUTDOWN,
|
||||
SETTINGS
|
||||
RUN,
|
||||
PAUSE,
|
||||
CTRL_ALT_DEL,
|
||||
CTRL_ALT_ESC,
|
||||
HARD_RESET,
|
||||
ACPI_SHUTDOWN,
|
||||
SETTINGS
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
ToolBarLoadIcons()
|
||||
{
|
||||
if (!hwndToolbar)
|
||||
return;
|
||||
return;
|
||||
|
||||
if (hImageList)
|
||||
ImageList_Destroy(hImageList);
|
||||
ImageList_Destroy(hImageList);
|
||||
|
||||
hImageList = ImageList_Create(win_get_system_metrics(SM_CXSMICON, dpi),
|
||||
win_get_system_metrics(SM_CYSMICON, dpi),
|
||||
ILC_MASK | ILC_COLOR32, 1, 1);
|
||||
win_get_system_metrics(SM_CYSMICON, dpi),
|
||||
ILC_MASK | ILC_COLOR32, 1, 1);
|
||||
|
||||
// The icons must be loaded in the same order as the `image_index`
|
||||
// enumeration above.
|
||||
@@ -56,55 +54,54 @@ ToolBarLoadIcons()
|
||||
SendMessage(hwndToolbar, TB_SETIMAGELIST, 0, (LPARAM) hImageList);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ToolBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (message) {
|
||||
case WM_NOTIFY:
|
||||
switch (((LPNMHDR) lParam)->code) {
|
||||
case TTN_GETDISPINFO: {
|
||||
LPTOOLTIPTEXT lpttt = (LPTOOLTIPTEXT)lParam;
|
||||
case WM_NOTIFY:
|
||||
switch (((LPNMHDR) lParam)->code) {
|
||||
case TTN_GETDISPINFO:
|
||||
{
|
||||
LPTOOLTIPTEXT lpttt = (LPTOOLTIPTEXT) lParam;
|
||||
|
||||
// Set the instance of the module that contains the resource.
|
||||
lpttt->hinst = hinstance;
|
||||
// Set the instance of the module that contains the resource.
|
||||
lpttt->hinst = hinstance;
|
||||
|
||||
uintptr_t idButton = lpttt->hdr.idFrom;
|
||||
uintptr_t idButton = lpttt->hdr.idFrom;
|
||||
|
||||
switch (idButton) {
|
||||
case IDM_ACTION_PAUSE:
|
||||
if (dopause)
|
||||
lpttt->lpszText = MAKEINTRESOURCE(IDS_2154);
|
||||
else
|
||||
lpttt->lpszText = MAKEINTRESOURCE(IDS_2155);
|
||||
break;
|
||||
switch (idButton) {
|
||||
case IDM_ACTION_PAUSE:
|
||||
if (dopause)
|
||||
lpttt->lpszText = MAKEINTRESOURCE(IDS_2154);
|
||||
else
|
||||
lpttt->lpszText = MAKEINTRESOURCE(IDS_2155);
|
||||
break;
|
||||
|
||||
case IDM_ACTION_RESET_CAD:
|
||||
lpttt->lpszText = MAKEINTRESOURCE(IDS_2156);
|
||||
break;
|
||||
case IDM_ACTION_RESET_CAD:
|
||||
lpttt->lpszText = MAKEINTRESOURCE(IDS_2156);
|
||||
break;
|
||||
|
||||
case IDM_ACTION_CTRL_ALT_ESC:
|
||||
lpttt->lpszText = MAKEINTRESOURCE(IDS_2157);
|
||||
break;
|
||||
case IDM_ACTION_CTRL_ALT_ESC:
|
||||
lpttt->lpszText = MAKEINTRESOURCE(IDS_2157);
|
||||
break;
|
||||
|
||||
case IDM_ACTION_HRESET:
|
||||
lpttt->lpszText = MAKEINTRESOURCE(IDS_2158);
|
||||
break;
|
||||
case IDM_ACTION_HRESET:
|
||||
lpttt->lpszText = MAKEINTRESOURCE(IDS_2158);
|
||||
break;
|
||||
|
||||
case IDM_CONFIG:
|
||||
lpttt->lpszText = MAKEINTRESOURCE(IDS_2160);
|
||||
break;
|
||||
}
|
||||
case IDM_CONFIG:
|
||||
lpttt->lpszText = MAKEINTRESOURCE(IDS_2160);
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(CallWindowProc(pOriginalProcedure, hwnd, message, wParam, lParam));
|
||||
return (CallWindowProc(pOriginalProcedure, hwnd, message, wParam, lParam));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ToolBarUpdatePause(int pause)
|
||||
{
|
||||
@@ -117,35 +114,29 @@ ToolBarUpdatePause(int pause)
|
||||
SendMessage(hwndToolbar, TB_SETBUTTONINFO, IDM_ACTION_PAUSE, (LPARAM) &tbbi);
|
||||
}
|
||||
|
||||
|
||||
static TBBUTTON buttons[] = {
|
||||
{ PAUSE, IDM_ACTION_PAUSE, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, 0 },
|
||||
{ HARD_RESET, IDM_ACTION_HRESET, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, 0 },
|
||||
{ ACPI_SHUTDOWN, 0, TBSTATE_HIDDEN, BTNS_BUTTON, { 0 }, 0, 0 },
|
||||
{ 0, 0, TBSTATE_INDETERMINATE, BTNS_SEP, { 0 }, 0, 0 },
|
||||
{ CTRL_ALT_DEL, IDM_ACTION_RESET_CAD, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, 0 },
|
||||
{ CTRL_ALT_ESC, IDM_ACTION_CTRL_ALT_ESC, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, 0 },
|
||||
{ 0, 0, TBSTATE_INDETERMINATE, BTNS_SEP, { 0 }, 0, 0 },
|
||||
{ SETTINGS, IDM_CONFIG, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, 0 }
|
||||
{PAUSE, IDM_ACTION_PAUSE, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, 0},
|
||||
{ HARD_RESET, IDM_ACTION_HRESET, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, 0},
|
||||
{ ACPI_SHUTDOWN, 0, TBSTATE_HIDDEN, BTNS_BUTTON, { 0 }, 0, 0},
|
||||
{ 0, 0, TBSTATE_INDETERMINATE, BTNS_SEP, { 0 }, 0, 0},
|
||||
{ CTRL_ALT_DEL, IDM_ACTION_RESET_CAD, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, 0},
|
||||
{ CTRL_ALT_ESC, IDM_ACTION_CTRL_ALT_ESC, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, 0},
|
||||
{ 0, 0, TBSTATE_INDETERMINATE, BTNS_SEP, { 0 }, 0, 0},
|
||||
{ SETTINGS, IDM_CONFIG, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, 0}
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
ToolBarCreate(HWND hwndParent, HINSTANCE hInst)
|
||||
{
|
||||
REBARINFO rbi = { 0 };
|
||||
REBARINFO rbi = { 0 };
|
||||
REBARBANDINFO rbbi = { 0 };
|
||||
int btnSize;
|
||||
int btnSize;
|
||||
|
||||
// Create the toolbar.
|
||||
hwndToolbar = CreateWindowEx(WS_EX_PALETTEWINDOW, TOOLBARCLASSNAME, NULL,
|
||||
WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN |
|
||||
WS_CLIPSIBLINGS | TBSTYLE_TOOLTIPS |
|
||||
TBSTYLE_FLAT | CCS_TOP | BTNS_AUTOSIZE |
|
||||
CCS_NOPARENTALIGN | CCS_NORESIZE |
|
||||
CCS_NODIVIDER,
|
||||
0, 0, 0, 0,
|
||||
hwndParent, NULL, hInst, NULL);
|
||||
WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | TBSTYLE_TOOLTIPS | TBSTYLE_FLAT | CCS_TOP | BTNS_AUTOSIZE | CCS_NOPARENTALIGN | CCS_NORESIZE | CCS_NODIVIDER,
|
||||
0, 0, 0, 0,
|
||||
hwndParent, NULL, hInst, NULL);
|
||||
|
||||
ToolBarLoadIcons();
|
||||
|
||||
@@ -154,41 +145,39 @@ ToolBarCreate(HWND hwndParent, HINSTANCE hInst)
|
||||
SendMessage(hwndToolbar, TB_ADDBUTTONS, sizeof(buttons) / sizeof(TBBUTTON), (LPARAM) &buttons);
|
||||
|
||||
// Autosize the toolbar and determine its size.
|
||||
btnSize = LOWORD(SendMessage(hwndToolbar, TB_GETBUTTONSIZE, 0,0));
|
||||
btnSize = LOWORD(SendMessage(hwndToolbar, TB_GETBUTTONSIZE, 0, 0));
|
||||
|
||||
// Replace the original procedure with ours.
|
||||
pOriginalProcedure = (WNDPROC) GetWindowLongPtr(hwndToolbar, GWLP_WNDPROC);
|
||||
SetWindowLongPtr(hwndToolbar, GWLP_WNDPROC, (LONG_PTR)&ToolBarProcedure);
|
||||
SetWindowLongPtr(hwndToolbar, GWLP_WNDPROC, (LONG_PTR) &ToolBarProcedure);
|
||||
|
||||
// Make sure the Pause button is in the correct state.
|
||||
ToolBarUpdatePause(dopause);
|
||||
|
||||
// Create the containing Rebar.
|
||||
hwndRebar = CreateWindowEx(0, REBARCLASSNAME, NULL,
|
||||
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS |
|
||||
WS_CLIPCHILDREN | RBS_VARHEIGHT |
|
||||
CCS_NODIVIDER | CCS_NOPARENTALIGN,
|
||||
0, 0, scrnsz_x, 0,
|
||||
hwndParent, NULL, hInst, NULL);
|
||||
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | RBS_VARHEIGHT | CCS_NODIVIDER | CCS_NOPARENTALIGN,
|
||||
0, 0, scrnsz_x, 0,
|
||||
hwndParent, NULL, hInst, NULL);
|
||||
|
||||
// Create and send the REBARINFO structure.
|
||||
rbi.cbSize = sizeof(rbi);
|
||||
SendMessage(hwndRebar, RB_SETBARINFO, 0, (LPARAM)&rbi);
|
||||
SendMessage(hwndRebar, RB_SETBARINFO, 0, (LPARAM) &rbi);
|
||||
|
||||
// Add the toolbar to the rebar.
|
||||
rbbi.cbSize = sizeof(rbbi);
|
||||
rbbi.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_STYLE;
|
||||
rbbi.hwndChild = hwndToolbar;
|
||||
rbbi.cbSize = sizeof(rbbi);
|
||||
rbbi.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_STYLE;
|
||||
rbbi.hwndChild = hwndToolbar;
|
||||
rbbi.cxMinChild = 0;
|
||||
rbbi.cyMinChild = btnSize;
|
||||
rbbi.fStyle = RBBS_NOGRIPPER;
|
||||
SendMessage(hwndRebar, RB_INSERTBAND, -1, (LPARAM)&rbbi);
|
||||
rbbi.fStyle = RBBS_NOGRIPPER;
|
||||
SendMessage(hwndRebar, RB_INSERTBAND, -1, (LPARAM) &rbbi);
|
||||
|
||||
// Add a label for machine information.
|
||||
rbbi.fMask = RBBIM_TEXT | RBBIM_STYLE;
|
||||
rbbi.fMask = RBBIM_TEXT | RBBIM_STYLE;
|
||||
rbbi.lpText = TEXT("Test");
|
||||
rbbi.fStyle = RBBS_NOGRIPPER;
|
||||
SendMessage(hwndRebar, RB_INSERTBAND, -1, (LPARAM)&rbbi);
|
||||
SendMessage(hwndRebar, RB_INSERTBAND, -1, (LPARAM) &rbbi);
|
||||
|
||||
SendMessage(hwndRebar, RB_MAXIMIZEBAND, 0, 0);
|
||||
ShowWindow(hwndRebar, TRUE);
|
||||
@@ -196,25 +185,24 @@ ToolBarCreate(HWND hwndParent, HINSTANCE hInst)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
wchar_t *
|
||||
ui_window_title(wchar_t *s)
|
||||
{
|
||||
REBARBANDINFO rbbi = { 0 };
|
||||
if (! video_fullscreen) {
|
||||
if (s != NULL) {
|
||||
wcsncpy(wTitle, s, sizeof_w(wTitle) - 1);
|
||||
} else
|
||||
s = wTitle;
|
||||
if (!video_fullscreen) {
|
||||
if (s != NULL) {
|
||||
wcsncpy(wTitle, s, sizeof_w(wTitle) - 1);
|
||||
} else
|
||||
s = wTitle;
|
||||
|
||||
rbbi.cbSize = sizeof(rbbi);
|
||||
rbbi.fMask = RBBIM_TEXT;
|
||||
rbbi.lpText = s;
|
||||
SendMessage(hwndRebar, RB_SETBANDINFO, 1, (LPARAM) &rbbi);
|
||||
rbbi.cbSize = sizeof(rbbi);
|
||||
rbbi.fMask = RBBIM_TEXT;
|
||||
rbbi.lpText = s;
|
||||
SendMessage(hwndRebar, RB_SETBANDINFO, 1, (LPARAM) &rbbi);
|
||||
} else {
|
||||
if (s == NULL)
|
||||
s = wTitle;
|
||||
if (s == NULL)
|
||||
s = wTitle;
|
||||
}
|
||||
|
||||
return(s);
|
||||
return (s);
|
||||
}
|
||||
|
||||
1911
src/win/win_ui.c
1911
src/win/win_ui.c
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user