diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000..00a283e2ad --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,22 @@ +## Guidelines + +1. Rebase before opening a pull request +2. If you are sending several unrelated fixes or features, use a branch and a separate pull request for each +3. If possible try squashing everything in a single commit. This is particularly beneficial in the case of feature merges since it allows easy bisecting when a problem arises + + +## Description + +[Description of the pull request, detail any issues you are fixing or any features you are implementing] + +## Related Issues + +[Any issues this pull request may be addressing] + +## Related Pull Requests + +[Any other PRs from related repositories that might be needed for this pull request to work] + +## Reviewers + +[If possible @mention all the people that should review your pull request] diff --git a/.travis.yml b/.travis.yml index 73b48fb889..a67a17b635 100644 --- a/.travis.yml +++ b/.travis.yml @@ -55,6 +55,7 @@ addons: - libsdl-image1.2-dev - libsdl-mixer1.2-dev - libsdl-ttf2.0-dev + - libusb-1.0-0-dev coverity_scan: project: name: "RetroArch" diff --git a/Makefile.common b/Makefile.common index ace2a5c4a6..cac0ea4aaf 100644 --- a/Makefile.common +++ b/Makefile.common @@ -916,7 +916,11 @@ ifeq ($(HAVE_THREADS), 1) ifeq ($(HAVE_HID), 1) DEFINES += -DHAVE_LIBUSB OBJ += input/drivers_hid/libusb_hid.o - LIBS += -lusb-1.0 + ifneq ($(findstring BSD,$(OS)),) + LIBS += -lusb + else + LIBS += -lusb-1.0 + endif endif endif endif diff --git a/Makefile.griffin b/Makefile.griffin index fccba281b4..5e2217dd6e 100644 --- a/Makefile.griffin +++ b/Makefile.griffin @@ -334,7 +334,7 @@ else ifeq ($(platform), windows_msvc6_x86) PLATCFLAGS += -D_WIN32 -D_WIN32_WINNT=0x0351 -D__STDC_CONSTANT_MACROS -D_MBCS LDFLAGS += shell32.lib user32.lib gdi32.lib comdlg32.lib winmm.lib ole32.lib - VCDIR ?= $(shell reg query "HKLM\SOFTWARE\Wow6432Node\Microsoft\DevStudio\6.0\Products\Microsoft Visual C++" -v "ProductDir" | grep -o '[A-Z]:\\.*') + VCDIR ?= $(shell reg query "HKLM\SOFTWARE\Wow6432Node\Microsoft\DevStudio\6.0\Products\Microsoft Visual C++" -v "ProductDir" | grep -io '[A-Z]:\\.*') PATH := $(shell IFS=$$'\n'; cygpath "$(VCDIR)/bin"):$(PATH) PATH := $(PATH):$(shell IFS=$$'\n'; cygpath "$(VCDIR)/../Common/MSDev98/Bin") @@ -493,8 +493,8 @@ else ifneq (,$(findstring windows_msvc2010,$(platform))) PATH := $(PATH):$(shell IFS=$$'\n'; cygpath "$(VS100COMNTOOLS)../IDE") INCLUDE := $(shell IFS=$$'\n'; cygpath -w "$(VS100COMNTOOLS)../../VC/include") - WindowsSdkDir ?= $(shell reg query "HKLM\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.0A" -v "InstallationFolder" | grep -o '[A-Z]:\\.*') - WindowsSdkDir ?= $(shell reg query "HKLM\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1A" -v "InstallationFolder" | grep -o '[A-Z]:\\.*') + WindowsSdkDir ?= $(shell reg query "HKLM\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.0A" -v "InstallationFolder" | grep -io '[A-Z]:\\.*') + WindowsSdkDir ?= $(shell reg query "HKLM\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1A" -v "InstallationFolder" | grep -io '[A-Z]:\\.*') WindowsSdkDir := $(WindowsSdkDir:\=) ifeq ($(HAVE_DIRECTX), 1) @@ -568,7 +568,7 @@ else ifneq (,$(findstring windows_msvc2012,$(platform))) PATH := $(PATH):$(shell IFS=$$'\n'; cygpath "$(VS110COMNTOOLS)../IDE") INCLUDE := $(shell IFS=$$'\n'; cygpath -w "$(VS110COMNTOOLS)../../VC/include") - WindowsSdkDir ?= $(shell reg query "HKLM\SOFTWARE\Microsoft\Windows Kits\Installed Roots" -v "KitsRoot81" | grep -o '[A-Z]:\\.*') + WindowsSdkDir ?= $(shell reg query "HKLM\SOFTWARE\Microsoft\Windows Kits\Installed Roots" -v "KitsRoot81" | grep -io '[A-Z]:\\.*') WindowsSdkDir := $(WindowsSdkDir:\=) ifeq ($(HAVE_DIRECTX), 1) @@ -642,7 +642,7 @@ else ifneq (,$(findstring windows_msvc2013,$(platform))) PATH := $(PATH):$(shell IFS=$$'\n'; cygpath "$(VS120COMNTOOLS)../IDE") INCLUDE := $(shell IFS=$$'\n'; cygpath -w "$(VS120COMNTOOLS)../../VC/include") - WindowsSdkDir ?= $(shell reg query "HKLM\SOFTWARE\Microsoft\Windows Kits\Installed Roots" -v "KitsRoot81" | grep -o '[A-Z]:\\.*') + WindowsSdkDir ?= $(shell reg query "HKLM\SOFTWARE\Microsoft\Windows Kits\Installed Roots" -v "KitsRoot81" | grep -io '[A-Z]:\\.*') WindowsSdkDir := $(WindowsSdkDir:\=) ifeq ($(HAVE_DIRECTX), 1) @@ -833,6 +833,7 @@ ifeq ($(DEBUG), 1) endif CFLAGS += -Od -Zi -D_DEBUG -MTd -TP + LDFLAGS += -DEBUG else CFLAGS += -O0 -g -DDEBUG endif diff --git a/command.c b/command.c index 41f23e6ff7..67fa8014c5 100644 --- a/command.c +++ b/command.c @@ -1809,11 +1809,9 @@ bool command_event(enum event_command cmd, void *data) rarch_system_info_t *system_info = NULL; struct retro_system_info *system = NULL; const char *core_path = NULL; - - path_clear(RARCH_PATH_BASENAME); - system_info = runloop_get_system_info(); - system = &system_info->info; - core_path = path_get(RARCH_PATH_CORE); + system_info = runloop_get_system_info(); + system = &system_info->info; + core_path = path_get(RARCH_PATH_CORE); #if defined(HAVE_DYNAMIC) if (string_is_empty(core_path)) diff --git a/config.def.h b/config.def.h index cbbffb0ffb..c3fb49f6f6 100644 --- a/config.def.h +++ b/config.def.h @@ -293,6 +293,12 @@ static bool xmb_show_add = true; #endif #endif +#if defined(HAVE_LIBRETRODB) && !defined(RARCH_CONSOLE) +static bool automatically_add_content_to_playlist = true; +#else +static bool automatically_add_content_to_playlist = false; +#endif + static float menu_framebuffer_opacity = 0.900; static float menu_wallpaper_opacity = 0.300; diff --git a/configuration.c b/configuration.c index 7f2fa1fc91..14b8d82c0a 100644 --- a/configuration.c +++ b/configuration.c @@ -1114,6 +1114,7 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, unsigned count = 0; global_t *global = global_get_ptr(); + SETTING_BOOL("automatically_add_content_to_playlist", &settings->bools.automatically_add_content_to_playlist, true, automatically_add_content_to_playlist, false); SETTING_BOOL("ui_companion_start_on_boot", &settings->bools.ui_companion_start_on_boot, true, ui_companion_start_on_boot, false); SETTING_BOOL("ui_companion_enable", &settings->bools.ui_companion_enable, true, ui_companion_enable, false); SETTING_BOOL("video_gpu_record", &settings->bools.video_gpu_record, true, gpu_record, false); diff --git a/configuration.h b/configuration.h index 7dd74b9282..31dbeebff3 100644 --- a/configuration.h +++ b/configuration.h @@ -243,6 +243,8 @@ typedef struct settings bool ssh_enable; bool samba_enable; bool bluetooth_enable; + + bool automatically_add_content_to_playlist; } bools; struct diff --git a/deps/miniupnpc/minissdpc.c b/deps/miniupnpc/minissdpc.c index c015298b97..6cf1570787 100644 --- a/deps/miniupnpc/minissdpc.c +++ b/deps/miniupnpc/minissdpc.c @@ -67,13 +67,13 @@ struct sockaddr_un { #define PRINT_SOCKET_ERROR(x) perror(x) #endif -#if !defined(__DragonFly__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__APPLE__) && !defined(_WIN32) && !defined(__CYGWIN__) && !defined(__sun) && !defined(__GNU__) && !defined(__FreeBSD_kernel__) +#if !defined(__DragonFly__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__APPLE__) && !defined(_WIN32) && !defined(__CYGWIN__) && !defined(__sun) && !defined(__GNU__) && !defined(__FreeBSD_kernel__) && !defined(__HAIKU__) #define HAS_IP_MREQN #endif #if !defined(HAS_IP_MREQN) && !defined(_WIN32) #include -#if defined(__sun) +#if defined(__sun) || defined(__HAIKU__) #include #endif #endif diff --git a/deps/miniupnpc/portlistingparse.c b/deps/miniupnpc/portlistingparse.c index e864c0eb70..de596698aa 100644 --- a/deps/miniupnpc/portlistingparse.c +++ b/deps/miniupnpc/portlistingparse.c @@ -31,7 +31,7 @@ static const struct { /* Helper function */ static UNSIGNED_INTEGER -atoui(const char * p, int l) +my_atoui(const char * p, int l) { UNSIGNED_INTEGER r = 0; while(l > 0 && *p) @@ -106,7 +106,7 @@ static void portlisting_data(void * d, const char * data, int l) pm->remoteHost[l] = '\0'; break; case NewExternalPort: - pm->externalPort = (unsigned short)atoui(data, l); + pm->externalPort = (unsigned short)my_atoui(data, l); break; case NewProtocol: if(l > 3) @@ -115,21 +115,21 @@ static void portlisting_data(void * d, const char * data, int l) pm->protocol[l] = '\0'; break; case NewInternalPort: - pm->internalPort = (unsigned short)atoui(data, l); + pm->internalPort = (unsigned short)my_atoui(data, l); break; case NewInternalClient: memcpy(pm->internalClient, data, l); pm->internalClient[l] = '\0'; break; case NewEnabled: - pm->enabled = (unsigned char)atoui(data, l); + pm->enabled = (unsigned char)my_atoui(data, l); break; case NewDescription: memcpy(pm->description, data, l); pm->description[l] = '\0'; break; case NewLeaseTime: - pm->leaseTime = atoui(data, l); + pm->leaseTime = my_atoui(data, l); break; default: break; diff --git a/deps/miniupnpc/upnpcommands.c b/deps/miniupnpc/upnpcommands.c index 25483c0c45..017c5cdce6 100644 --- a/deps/miniupnpc/upnpcommands.c +++ b/deps/miniupnpc/upnpcommands.c @@ -14,7 +14,7 @@ #include "portlistingparse.h" static UNSIGNED_INTEGER -my_atoui(const char * s) +my_custom_atoui(const char * s) { return s ? ((UNSIGNED_INTEGER)STRTOUI(s, NULL, 0)) : 0; } @@ -38,7 +38,7 @@ UPNP_GetTotalBytesSent(const char * controlURL, /*DisplayNameValueList(buffer, bufsize);*/ free(buffer); buffer = NULL; p = GetValueFromNameValueList(&pdata, "NewTotalBytesSent"); - r = (unsigned)my_atoui(p); + r = (unsigned)my_custom_atoui(p); ClearNameValueList(&pdata); return r; } @@ -62,7 +62,7 @@ UPNP_GetTotalBytesReceived(const char * controlURL, /*DisplayNameValueList(buffer, bufsize);*/ free(buffer); buffer = NULL; p = GetValueFromNameValueList(&pdata, "NewTotalBytesReceived"); - r = (unsigned)my_atoui(p); + r = (unsigned)my_custom_atoui(p); ClearNameValueList(&pdata); return r; } @@ -86,7 +86,7 @@ UPNP_GetTotalPacketsSent(const char * controlURL, /*DisplayNameValueList(buffer, bufsize);*/ free(buffer); buffer = NULL; p = GetValueFromNameValueList(&pdata, "NewTotalPacketsSent"); - r = (unsigned)my_atoui(p); + r = (unsigned)my_custom_atoui(p); ClearNameValueList(&pdata); return r; } @@ -110,7 +110,7 @@ UPNP_GetTotalPacketsReceived(const char * controlURL, /*DisplayNameValueList(buffer, bufsize);*/ free(buffer); buffer = NULL; p = GetValueFromNameValueList(&pdata, "NewTotalPacketsReceived"); - r = (unsigned)my_atoui(p); + r = (unsigned)my_custom_atoui(p); ClearNameValueList(&pdata); return r; } @@ -903,11 +903,11 @@ UPNP_GetFirewallStatus(const char * controlURL, if(ipa && fe) ret = UPNPCOMMAND_SUCCESS; if(fe) - *firewallEnabled = (int)my_atoui(fe); + *firewallEnabled = (int)my_custom_atoui(fe); /*else *firewallEnabled = 0;*/ if(ipa) - *inboundPinholeAllowed = (int)my_atoui(ipa); + *inboundPinholeAllowed = (int)my_custom_atoui(ipa); /*else *inboundPinholeAllowed = 0;*/ p = GetValueFromNameValueList(&pdata, "errorCode"); @@ -971,7 +971,7 @@ UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype ret = UPNPCOMMAND_SUCCESS; p = GetValueFromNameValueList(&pdata, "OutboundPinholeTimeout"); if(p) - *opTimeout = (int)my_atoui(p); + *opTimeout = (int)my_custom_atoui(p); } ClearNameValueList(&pdata); return ret; @@ -1175,7 +1175,7 @@ UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype, p = GetValueFromNameValueList(&pdata, "IsWorking"); if(p) { - *isWorking = (int)my_atoui(p); + *isWorking = (int)my_custom_atoui(p); ret = UPNPCOMMAND_SUCCESS; } else @@ -1222,7 +1222,7 @@ UPNP_GetPinholePackets(const char * controlURL, const char * servicetype, p = GetValueFromNameValueList(&pdata, "PinholePackets"); if(p) { - *packets = (int)my_atoui(p); + *packets = (int)my_custom_atoui(p); ret = UPNPCOMMAND_SUCCESS; } diff --git a/gfx/drivers/gdi_gfx.c b/gfx/drivers/gdi_gfx.c index 59e18af6b8..b1ded17fdb 100644 --- a/gfx/drivers/gdi_gfx.c +++ b/gfx/drivers/gdi_gfx.c @@ -356,7 +356,8 @@ static bool gdi_gfx_alive(void *data) unsigned temp_height = 0; bool quit = false; bool resize = false; - + bool ret = false; + /* Needed because some context drivers don't track their sizes */ video_driver_get_size(&temp_width, &temp_height); @@ -365,12 +366,13 @@ static bool gdi_gfx_alive(void *data) size_data.width = &temp_width; size_data.height = &temp_height; - video_context_driver_check_window(&size_data); + if (video_context_driver_check_window(&size_data)) + ret = !quit; if (temp_width != 0 && temp_height != 0) video_driver_set_size(&temp_width, &temp_height); - return true; + return ret; } static bool gdi_gfx_focus(void *data) diff --git a/gfx/video_driver.c b/gfx/video_driver.c index 1656d11bab..d06252fb90 100644 --- a/gfx/video_driver.c +++ b/gfx/video_driver.c @@ -2312,7 +2312,7 @@ void video_driver_frame(const void *data, unsigned width, snprintf(frames_text, sizeof(frames_text), - STRING_REP_UINT64, + "%" PRIu64, (uint64_t)video_driver_frame_count); strlcat(video_driver_window_title, @@ -2330,7 +2330,7 @@ void video_driver_frame(const void *data, unsigned width, snprintf( video_info.fps_text, sizeof(video_info.fps_text), - "FPS: %6.1f || %s: " STRING_REP_UINT64, + "FPS: %6.1f || %s: %" PRIu64, last_fps, msg_hash_to_str(MSG_FRAMES), (uint64_t)video_driver_frame_count); diff --git a/input/connect/connect_nesusb.c b/input/connect/connect_nesusb.c index 04b24d6746..24c5f0532e 100644 --- a/input/connect/connect_nesusb.c +++ b/input/connect/connect_nesusb.c @@ -27,7 +27,7 @@ struct hidpad_nesusb_data struct pad_connection* connection; uint8_t data[64]; uint32_t slot; - uint64_t buttons; + uint32_t buttons; }; static void* hidpad_nesusb_init(void *data, uint32_t slot, send_control_t ptr) @@ -59,12 +59,14 @@ static void hidpad_nesusb_deinit(void *data) free(device); } -static uint64_t hidpad_nesusb_get_buttons(void *data) +static void hidpad_nesusb_get_buttons(void *data, retro_bits_t* state) { - struct hidpad_nesusb_data *device = (struct hidpad_nesusb_data*)data; - if (!device) - return 0; - return device->buttons; + struct hidpad_nesusb_data *device = (struct hidpad_nesusb_data*)data; + if (device) { + RARCH_INPUT_STATE_COPY16_PTR(state, device->buttons); + } else { + RARCH_INPUT_STATE_CLEAR_PTR(state); + } } static int16_t hidpad_nesusb_get_axis(void *data, unsigned axis) @@ -102,7 +104,6 @@ static void hidpad_nesusb_packet_handler(void *data, uint8_t *packet, uint16_t s RETRO_DEVICE_ID_JOYPAD_A, RETRO_DEVICE_ID_JOYPAD_Y, RETRO_DEVICE_ID_JOYPAD_X, - 16, /* HOME BUTTON when pressing SELECT+START */ }; struct hidpad_nesusb_data *device = (struct hidpad_nesusb_data*)data; @@ -113,12 +114,11 @@ static void hidpad_nesusb_packet_handler(void *data, uint8_t *packet, uint16_t s device->buttons = 0; - pressed_keys = device->data[7] | (device->data[6] << 8) | - (((device->data[7] & 0x30) == 0x30) ? (1 << 16) : 0); /* SELECT+START=HOME */ + pressed_keys = device->data[7] | (device->data[6] << 8); - for (i = 0; i < 17; i ++) + for (i = 0; i < 16; i ++) if (button_mapping[i] != NO_BTN) - device->buttons |= (pressed_keys & (1 << i)) ? (UINT64_C(1) << button_mapping[i]) : 0; + device->buttons |= (pressed_keys & (1 << i)) ? (1 << button_mapping[i]) : 0; } static void hidpad_nesusb_set_rumble(void *data, diff --git a/input/connect/connect_ps2adapter.c b/input/connect/connect_ps2adapter.c index 10c922b66c..78c3cf9c92 100644 --- a/input/connect/connect_ps2adapter.c +++ b/input/connect/connect_ps2adapter.c @@ -27,7 +27,7 @@ struct hidpad_ps2adapter_data struct pad_connection* connection; uint8_t data[64]; uint32_t slot; - uint64_t buttons; + uint32_t buttons; }; static void* hidpad_ps2adapter_init(void *data, uint32_t slot, send_control_t ptr) @@ -59,12 +59,14 @@ static void hidpad_ps2adapter_deinit(void *data) free(device); } -static uint64_t hidpad_ps2adapter_get_buttons(void *data) +static void hidpad_ps2adapter_get_buttons(void *data, retro_bits_t *state) { - struct hidpad_ps2adapter_data *device = (struct hidpad_ps2adapter_data*)data; - if (!device) - return 0; - return device->buttons; + struct hidpad_ps2adapter_data *device = (struct hidpad_ps2adapter_data*)data; + if ( device ) { + RARCH_INPUT_STATE_COPY16_PTR(state, device->buttons); + } else { + RARCH_INPUT_STATE_CLEAR_PTR(state); + } } static int16_t hidpad_ps2adapter_get_axis(void *data, unsigned axis) @@ -74,7 +76,7 @@ static int16_t hidpad_ps2adapter_get_axis(void *data, unsigned axis) if (!device || axis >= 4) return 0; - + switch (axis) { case 0: @@ -90,7 +92,7 @@ static int16_t hidpad_ps2adapter_get_axis(void *data, unsigned axis) val = device->data[2]; break; } - + val = (val << 8) - 0x8000; return (abs(val) > 0x1000) ? val : 0; @@ -133,7 +135,7 @@ static void hidpad_ps2adapter_packet_handler(void *data, uint8_t *packet, uint16 /* Check if the data corresponds to the first controller, exit otherwise */ if (packet[1] != 1) return; - + memcpy(device->data, packet, size); device->buttons = 0; @@ -143,7 +145,7 @@ static void hidpad_ps2adapter_packet_handler(void *data, uint8_t *packet, uint16 for (i = 0; i < 16; i ++) if (button_mapping[i] != NO_BTN) device->buttons |= (pressed_keys & (1 << i)) ? (UINT64_C(1) << button_mapping[i]) : 0; - + /* Now process the hat values as if they were pad buttons */ hat_value = PS2_H_GET(device->data[6]); device->buttons |= PS2_H_LEFT(hat_value) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT) : 0; diff --git a/input/connect/connect_ps3.c b/input/connect/connect_ps3.c index 37ca54b8d2..422a1b02a2 100644 --- a/input/connect/connect_ps3.c +++ b/input/connect/connect_ps3.c @@ -20,6 +20,7 @@ #include #include "joypad_connection.h" +#include "../input_defines.h" struct hidpad_ps3_data { @@ -27,7 +28,7 @@ struct hidpad_ps3_data send_control_t send_control; uint8_t data[512]; uint32_t slot; - uint64_t buttons; + uint32_t buttons; bool have_led; uint16_t motors[2]; }; @@ -104,12 +105,23 @@ static void hidpad_ps3_deinit(void *data) free(device); } -static uint64_t hidpad_ps3_get_buttons(void *data) +static void hidpad_ps3_get_buttons(void *data, retro_bits_t *state) { - struct hidpad_ps3_data *device = (struct hidpad_ps3_data*)data; - if (!device) - return 0; - return device->buttons; + struct hidpad_ps3_data *device = (struct hidpad_ps3_data*)data; + if ( device ) + { + /*copy first 16 bits - standard RetroPad controls*/ + RARCH_INPUT_STATE_COPY16_PTR(state, device->buttons); + + /*PS button?*/ + if ( device->buttons & 0x10000 ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RARCH_MENU_TOGGLE ); + } + } + else + { + RARCH_INPUT_STATE_CLEAR_PTR( state ); + } } static int16_t hidpad_ps3_get_axis(void *data, unsigned axis) diff --git a/input/connect/connect_ps4.c b/input/connect/connect_ps4.c index 198107842f..47a9cdabe6 100644 --- a/input/connect/connect_ps4.c +++ b/input/connect/connect_ps4.c @@ -184,35 +184,67 @@ static bool hidpad_ps4_check_dpad(struct ps4 *rpt, unsigned id) return false; } -static uint64_t hidpad_ps4_get_buttons(void *data) +static void hidpad_ps4_get_buttons(void *data, retro_bits_t* state) { - uint64_t buttonstate = 0; struct hidpad_ps4_data *device = (struct hidpad_ps4_data*)data; struct ps4 *rpt = device ? (struct ps4*)&device->data : NULL; if (!device || !rpt) - return 0; + return; - buttonstate |= (rpt->btn.r3 ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R3) : 0); - buttonstate |= (rpt->btn.l3 ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L3) : 0); - buttonstate |= (rpt->btn.options ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_START) : 0); - buttonstate |= (rpt->btn.share ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_SELECT) : 0); - buttonstate |= (rpt->btn.r2 ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R2) : 0); - buttonstate |= (rpt->btn.l2 ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L2) : 0); - buttonstate |= (rpt->btn.r1 ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R) : 0); - buttonstate |= (rpt->btn.l1 ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L) : 0); + RARCH_INPUT_STATE_CLEAR_PTR( state ); - buttonstate |= (rpt->btn.triangle ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_X) : 0); - buttonstate |= (rpt->btn.circle ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_A) : 0); - buttonstate |= (rpt->btn.cross ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_B) : 0); - buttonstate |= (rpt->btn.square ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_Y) : 0); - buttonstate |= ((hidpad_ps4_check_dpad(rpt, RETRO_DEVICE_ID_JOYPAD_LEFT)) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT) : 0); - buttonstate |= ((hidpad_ps4_check_dpad(rpt, RETRO_DEVICE_ID_JOYPAD_DOWN)) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN) : 0); - buttonstate |= ((hidpad_ps4_check_dpad(rpt, RETRO_DEVICE_ID_JOYPAD_RIGHT)) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_RIGHT) : 0); - buttonstate |= ((hidpad_ps4_check_dpad(rpt, RETRO_DEVICE_ID_JOYPAD_UP)) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP) : 0); - buttonstate |= (rpt->btn.ps ? (UINT64_C(1) << RARCH_MENU_TOGGLE) : 0); - - return buttonstate; + if ( rpt->btn.r3 ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_R3 ); + } + if ( rpt->btn.l3 ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_L3 ); + } + if ( rpt->btn.options ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_START ); + } + if ( rpt->btn.share ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_SELECT ); + } + if ( rpt->btn.r2 ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_R2 ); + } + if ( rpt->btn.l2 ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_L2 ); + } + if ( rpt->btn.r1 ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_R ); + } + if ( rpt->btn.l1 ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_L ); + } + if ( rpt->btn.triangle ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_X ); + } + if ( rpt->btn.circle ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_A ); + } + if ( rpt->btn.cross ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_B ); + } + if ( rpt->btn.square ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_Y ); + } + if ( (hidpad_ps4_check_dpad(rpt, RETRO_DEVICE_ID_JOYPAD_LEFT)) ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_LEFT ); + } + if ( (hidpad_ps4_check_dpad(rpt, RETRO_DEVICE_ID_JOYPAD_DOWN)) ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_DOWN ); + } + if ( (hidpad_ps4_check_dpad(rpt, RETRO_DEVICE_ID_JOYPAD_RIGHT)) ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_RIGHT ); + } + if ( (hidpad_ps4_check_dpad(rpt, RETRO_DEVICE_ID_JOYPAD_UP)) ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_UP ); + } + if ( rpt->btn.ps ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RARCH_MENU_TOGGLE ); + } } static int16_t hidpad_ps4_get_axis(void *data, unsigned axis) diff --git a/input/connect/connect_psxadapter.c b/input/connect/connect_psxadapter.c index d05bfc3793..6f77e77f72 100644 --- a/input/connect/connect_psxadapter.c +++ b/input/connect/connect_psxadapter.c @@ -27,7 +27,7 @@ struct hidpad_psxadapter_data struct pad_connection* connection; uint8_t data[64]; uint32_t slot; - uint64_t buttons; + uint32_t buttons; }; static void* hidpad_psxadapter_init(void *data, uint32_t slot, send_control_t ptr) @@ -59,12 +59,14 @@ static void hidpad_psxadapter_deinit(void *data) free(device); } -static uint64_t hidpad_psxadapter_get_buttons(void *data) +static void hidpad_psxadapter_get_buttons(void *data, retro_bits_t *state) { - struct hidpad_psxadapter_data *device = (struct hidpad_psxadapter_data*)data; - if (!device) - return 0; - return device->buttons; + struct hidpad_psxadapter_data *device = (struct hidpad_psxadapter_data*)data; + if ( device ) { + RARCH_INPUT_STATE_COPY16_PTR(state, device->buttons); + } else { + RARCH_INPUT_STATE_CLEAR_PTR(state); + } } static int16_t hidpad_psxadapter_get_axis(void *data, unsigned axis) @@ -75,7 +77,7 @@ static int16_t hidpad_psxadapter_get_axis(void *data, unsigned axis) if (!device || axis >= 4 || (device->data[2]==0x7F) ) /* digital mode detection */ return 0; - + switch (axis) { case 0: @@ -91,7 +93,7 @@ static int16_t hidpad_psxadapter_get_axis(void *data, unsigned axis) val = device->data[2]; break; } - + val = (val << 8) - 0x8000; return (abs(val) > 0x1000) ? val : 0; /* hard coded deadzone */ @@ -107,7 +109,7 @@ static void hidpad_psxadapter_packet_handler(void *data, uint8_t *packet, uint16 { uint32_t i, pressed_keys; int16_t hat_value; - static const uint32_t button_mapping[17] = + static const uint32_t button_mapping[16] = { RETRO_DEVICE_ID_JOYPAD_L2, RETRO_DEVICE_ID_JOYPAD_R2, @@ -125,7 +127,6 @@ static void hidpad_psxadapter_packet_handler(void *data, uint8_t *packet, uint16 RETRO_DEVICE_ID_JOYPAD_A, RETRO_DEVICE_ID_JOYPAD_B, RETRO_DEVICE_ID_JOYPAD_Y, - 16/* HOME BUTTON when pressing SELECT+START */ }; struct hidpad_psxadapter_data *device = (struct hidpad_psxadapter_data*)data; @@ -136,29 +137,28 @@ static void hidpad_psxadapter_packet_handler(void *data, uint8_t *packet, uint16 device->buttons = 0; - pressed_keys = device->data[7] | (device->data[6] << 8) | - (((device->data[7] & 0x30) == 0x30) ? (1 << 16) : 0); /* SELECT+START = MENU TOGGLE */ + pressed_keys = device->data[7] | (device->data[6] << 8); - for (i = 0; i < 17; i ++) + for (i = 0; i < 16; i ++) if (button_mapping[i] != NO_BTN) - device->buttons |= (pressed_keys & (1 << i)) ? (UINT64_C(1) << button_mapping[i]) : 0; + device->buttons |= (pressed_keys & (1 << i)) ? (1 << button_mapping[i]) : 0; if (device->data[2]==0x7F) /* digital mode detection */ { /* We're in digital mode, process the dpad values */ - device->buttons |= (device->data[4]==0x00) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT) : 0; - device->buttons |= (device->data[4]==0xFF) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_RIGHT) : 0; - device->buttons |= (device->data[5]==0x00) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP) : 0; - device->buttons |= (device->data[5]==0xFF) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN) : 0; + device->buttons |= (device->data[4]==0x00) ? (1 << RETRO_DEVICE_ID_JOYPAD_LEFT) : 0; + device->buttons |= (device->data[4]==0xFF) ? (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT) : 0; + device->buttons |= (device->data[5]==0x00) ? (1 << RETRO_DEVICE_ID_JOYPAD_UP) : 0; + device->buttons |= (device->data[5]==0xFF) ? (1 << RETRO_DEVICE_ID_JOYPAD_DOWN) : 0; } else { /* We're in analog mode, process the hat values as if they were pad buttons */ hat_value = PSX_H_GET(device->data[6]); - device->buttons |= PSX_H_LEFT(hat_value) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT) : 0; - device->buttons |= PSX_H_RIGHT(hat_value) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_RIGHT) : 0; - device->buttons |= PSX_H_UP(hat_value) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP) : 0; - device->buttons |= PSX_H_DOWN(hat_value) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN) : 0; + device->buttons |= PSX_H_LEFT(hat_value) ? (1 << RETRO_DEVICE_ID_JOYPAD_LEFT) : 0; + device->buttons |= PSX_H_RIGHT(hat_value) ? (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT) : 0; + device->buttons |= PSX_H_UP(hat_value) ? (1 << RETRO_DEVICE_ID_JOYPAD_UP) : 0; + device->buttons |= PSX_H_DOWN(hat_value) ? (1 << RETRO_DEVICE_ID_JOYPAD_DOWN) : 0; } } diff --git a/input/connect/connect_snesusb.c b/input/connect/connect_snesusb.c index d5cc9e2811..bbc9fb43a4 100644 --- a/input/connect/connect_snesusb.c +++ b/input/connect/connect_snesusb.c @@ -28,7 +28,7 @@ struct hidpad_snesusb_data struct pad_connection* connection; uint8_t data[64]; uint32_t slot; - uint64_t buttons; + uint32_t buttons; }; static void* hidpad_snesusb_init(void *data, uint32_t slot, send_control_t ptr) @@ -60,12 +60,14 @@ static void hidpad_snesusb_deinit(void *data) free(device); } -static uint64_t hidpad_snesusb_get_buttons(void *data) +static void hidpad_snesusb_get_buttons(void *data, retro_bits_t *state) { - struct hidpad_snesusb_data *device = (struct hidpad_snesusb_data*)data; - if (!device) - return 0; - return device->buttons; + struct hidpad_snesusb_data *device = (struct hidpad_snesusb_data*)data; + if ( device ) { + RARCH_INPUT_STATE_COPY16_PTR(state, device->buttons); + } else { + RARCH_INPUT_STATE_CLEAR_PTR(state); + } } static int16_t hidpad_snesusb_get_axis(void *data, unsigned axis) @@ -85,7 +87,7 @@ static int16_t hidpad_snesusb_get_axis(void *data, unsigned axis) static void hidpad_snesusb_packet_handler(void *data, uint8_t *packet, uint16_t size) { uint32_t i, pressed_keys; - static const uint32_t button_mapping[17] = + static const uint32_t button_mapping[16] = { RETRO_DEVICE_ID_JOYPAD_L, RETRO_DEVICE_ID_JOYPAD_R, @@ -102,8 +104,7 @@ static void hidpad_snesusb_packet_handler(void *data, uint8_t *packet, uint16_t RETRO_DEVICE_ID_JOYPAD_X, RETRO_DEVICE_ID_JOYPAD_A, RETRO_DEVICE_ID_JOYPAD_B, - RETRO_DEVICE_ID_JOYPAD_Y, - 16, /* HOME BUTTON when pressing SELECT+START */ + RETRO_DEVICE_ID_JOYPAD_Y }; struct hidpad_snesusb_data *device = (struct hidpad_snesusb_data*)data; @@ -114,12 +115,11 @@ static void hidpad_snesusb_packet_handler(void *data, uint8_t *packet, uint16_t device->buttons = 0; - pressed_keys = device->data[7] | (device->data[6] << 8) | - (((device->data[7] & 0x30) == 0x30) ? (1 << 16) : 0); /* SELECT+START = MENU TOGGLE */ + pressed_keys = device->data[7] | (device->data[6] << 8); - for (i = 0; i < 17; i ++) + for (i = 0; i < 16; i ++) if (button_mapping[i] != NO_BTN) - device->buttons |= (pressed_keys & (1 << i)) ? (UINT64_C(1) << button_mapping[i]) : 0; + device->buttons |= (pressed_keys & (1 << i)) ? (1 << button_mapping[i]) : 0; } static void hidpad_snesusb_set_rumble(void *data, diff --git a/input/connect/connect_wii.c b/input/connect/connect_wii.c index dcf342a5f1..ec4ceaaa72 100644 --- a/input/connect/connect_wii.c +++ b/input/connect/connect_wii.c @@ -25,6 +25,7 @@ #include #include "joypad_connection.h" +#include "../input_defines.h" /* wiimote state flags*/ #define WIIMOTE_STATE_DEV_FOUND 0x0001 @@ -198,7 +199,7 @@ static int wiimote_send(struct connect_wii_wiimote_t* wm, return 1; } -/* +/* * Request the wiimote controller status. * * Controller status includes: battery level, LED status, expansions. @@ -426,13 +427,13 @@ static int wiimote_handshake(struct connect_wii_wiimote_t* wm, switch (wm->handshake_state) { case 0: - /* no ha habido nunca handshake, debemos forzar un + /* no ha habido nunca handshake, debemos forzar un * mensaje de staus para ver que pasa. */ WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE); wiimote_set_leds(wm, WIIMOTE_LED_NONE); - /* Request the status of the Wiimote to + /* Request the status of the Wiimote to * see if there is an expansion */ wiimote_status(wm); @@ -440,16 +441,16 @@ static int wiimote_handshake(struct connect_wii_wiimote_t* wm, return 0; case 1: { - /* estamos haciendo handshake o bien se necesita iniciar un + /* estamos haciendo handshake o bien se necesita iniciar un * nuevo handshake ya que se inserta(quita una expansion. */ int attachment = 0; if(event != WM_RPT_CTRL_STATUS) return 0; - /* Is an attachment connected to + /* Is an attachment connected to * the expansion port? */ - if ((data[2] & WM_CTRL_STATUS_BYTE1_ATTACHMENT) == + if ((data[2] & WM_CTRL_STATUS_BYTE1_ATTACHMENT) == WM_CTRL_STATUS_BYTE1_ATTACHMENT) attachment = 1; @@ -473,19 +474,19 @@ static int wiimote_handshake(struct connect_wii_wiimote_t* wm, /* Rehandshake. */ WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE_COMPLETE); - /* forzamos un handshake por si venimos + /* forzamos un handshake por si venimos * de un hanshake completo. */ WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE); } - /*Old way. initialize the extension was by writing the + /*Old way. initialize the extension was by writing the * single encryption byte 0x00 to 0x(4)A40040. */ #if 0 buf = 0x00; wiimote_write_data(wm, WM_EXP_MEM_ENABLE, &buf, 1); #endif - /* NEW WAY 0x55 to 0x(4)A400F0, then writing + /* NEW WAY 0x55 to 0x(4)A400F0, then writing * 0x00 to 0x(4)A400FB. (support clones) */ buf = 0x55; wiimote_write_data(wm, 0x04A400F0, &buf, 1); @@ -515,7 +516,7 @@ static int wiimote_handshake(struct connect_wii_wiimote_t* wm, printf("rehandshake\n"); #endif WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE_COMPLETE); - /* forzamos un handshake por si venimos + /* forzamos un handshake por si venimos * de un hanshake completo. */ WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE); } @@ -671,12 +672,15 @@ static int16_t hidpad_wii_get_axis(void *data, unsigned axis) return 0; } -static uint64_t hidpad_wii_get_buttons(void *data) +static void hidpad_wii_get_buttons(void *data, retro_bits_t *state) { - struct connect_wii_wiimote_t* device = (struct connect_wii_wiimote_t*)data; - if (!device) - return 0; - return device->btns | (device->exp.cc.classic.btns << 16); + struct connect_wii_wiimote_t* device = (struct connect_wii_wiimote_t*)data; + if ( device ) + { + uint32_t b; + b = device->btns | (device->exp.cc.classic.btns << 16); /*broken? this doesn't match retropad!!*/ + RARCH_INPUT_STATE_COPY32_PTR(state, b); + } } static void hidpad_wii_packet_handler(void *data, diff --git a/input/connect/connect_wiiugca.c b/input/connect/connect_wiiugca.c index 8f1368fdd7..0f368e01fe 100644 --- a/input/connect/connect_wiiugca.c +++ b/input/connect/connect_wiiugca.c @@ -20,6 +20,7 @@ #include #include "joypad_connection.h" +#include "../input_defines.h" struct hidpad_wiiugca_data { @@ -27,7 +28,7 @@ struct hidpad_wiiugca_data send_control_t send_control; uint8_t data[64]; uint32_t slot; - uint64_t buttons; + uint32_t buttons; }; static void* hidpad_wiiugca_init(void *data, uint32_t slot, send_control_t ptr) @@ -62,12 +63,14 @@ static void hidpad_wiiugca_deinit(void *data) free(device); } -static uint64_t hidpad_wiiugca_get_buttons(void *data) +static void hidpad_wiiugca_get_buttons(void *data, retro_bits_t *state) { - struct hidpad_wiiugca_data *device = (struct hidpad_wiiugca_data*)data; - if (!device) - return 0; - return device->buttons; + struct hidpad_wiiugca_data *device = (struct hidpad_wiiugca_data*)data; + if ( device ) { + RARCH_INPUT_STATE_COPY16_PTR(state, device->buttons); + } else { + RARCH_INPUT_STATE_CLEAR_PTR(state); + } } static int16_t hidpad_wiiugca_get_axis(void *data, unsigned axis) diff --git a/input/connect/connect_wiiupro.c b/input/connect/connect_wiiupro.c index 05d36c240f..d380e119a0 100644 --- a/input/connect/connect_wiiupro.c +++ b/input/connect/connect_wiiupro.c @@ -97,7 +97,7 @@ static void* hidpad_wiiupro_init(void *data, device->connection = connection; device->slot = slot; device->send_control = ptr; - + calib_data->calib_round = 0; /* Without this, the digital buttons won't be reported. */ hidpad_wiiupro_send_control(device); @@ -118,35 +118,67 @@ static void hidpad_wiiupro_deinit(void *data) free(device); } -static uint64_t hidpad_wiiupro_get_buttons(void *data) +static void hidpad_wiiupro_get_buttons(void *data, retro_bits_t *state) { - uint64_t buttonstate = 0; struct hidpad_wiiupro_data *device = (struct hidpad_wiiupro_data*)data; struct wiiupro *rpt = device ? (struct wiiupro*)&device->data : NULL; if (!device || !rpt) - return 0; + return; - buttonstate |= (rpt->btn.r3 ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R3) : 0); - buttonstate |= (rpt->btn.l3 ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L3) : 0); - buttonstate |= (rpt->btn.plus ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_START) : 0); - buttonstate |= (rpt->btn.minus ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_SELECT) : 0); - buttonstate |= (rpt->btn.zr ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R2) : 0); - buttonstate |= (rpt->btn.zl ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L2) : 0); - buttonstate |= (rpt->btn.r ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R) : 0); - buttonstate |= (rpt->btn.l ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L) : 0); + RARCH_INPUT_STATE_CLEAR_PTR( state ); - buttonstate |= (rpt->btn.x ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_X) : 0); - buttonstate |= (rpt->btn.a ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_A) : 0); - buttonstate |= (rpt->btn.b ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_B) : 0); - buttonstate |= (rpt->btn.y ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_Y) : 0); - buttonstate |= (rpt->btn.left ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT) : 0); - buttonstate |= (rpt->btn.right ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_RIGHT) : 0); - buttonstate |= (rpt->btn.up ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP) : 0); - buttonstate |= (rpt->btn.down ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN) : 0); - buttonstate |= (rpt->btn.home ? (UINT64_C(1) << RARCH_MENU_TOGGLE) : 0); - - return buttonstate; + if ( rpt->btn.r3 ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_R3 ); + } + if ( rpt->btn.l3 ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_L3 ); + } + if ( rpt->btn.plus ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_START ); + } + if ( rpt->btn.minus ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_SELECT ); + } + if ( rpt->btn.zr ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_R2 ); + } + if ( rpt->btn.zl ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_L2 ); + } + if ( rpt->btn.r ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_R ); + } + if ( rpt->btn.l ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_L ); + } + if ( rpt->btn.x ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_X ); + } + if ( rpt->btn.a ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_A ); + } + if ( rpt->btn.b ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_B ); + } + if ( rpt->btn.y ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_Y ); + } + if ( rpt->btn.left ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_LEFT ); + } + if ( rpt->btn.down ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_DOWN ); + } + if ( rpt->btn.right ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_RIGHT ); + } + if ( rpt->btn.up ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_UP ); + } + if ( rpt->btn.home ) { + RARCH_INPUT_STATE_BIT_SET_PTR( state, RARCH_MENU_TOGGLE ); + } } static int16_t hidpad_wiiupro_get_axis(void *data, unsigned axis) @@ -214,18 +246,18 @@ static void hidpad_wiiupro_packet_handler(void *data, calib_data->hatvalue_calib[1] = (packet[8] | (packet[8 + 1] << 8)); calib_data->hatvalue_calib[2] = (packet[6] | (packet[6 + 1] << 8)); calib_data->hatvalue_calib[3] = (packet[10] | (packet[10 + 1] << 8)); - + calib_data->calib_round++; } else { - device->data.hatvalue[0] = (packet[4] | (packet[4 + 1] << 8)) + device->data.hatvalue[0] = (packet[4] | (packet[4 + 1] << 8)) - calib_data->hatvalue_calib[0]; - device->data.hatvalue[1] = (packet[8] | (packet[8 + 1] << 8)) + device->data.hatvalue[1] = (packet[8] | (packet[8 + 1] << 8)) - calib_data->hatvalue_calib[1]; - device->data.hatvalue[2] = (packet[6] | (packet[6 + 1] << 8)) + device->data.hatvalue[2] = (packet[6] | (packet[6 + 1] << 8)) - calib_data->hatvalue_calib[2]; - device->data.hatvalue[3] = (packet[10] | (packet[10 + 1] << 8)) + device->data.hatvalue[3] = (packet[10] | (packet[10 + 1] << 8)) - calib_data->hatvalue_calib[3]; } } diff --git a/input/connect/joypad_connection.c b/input/connect/joypad_connection.c index 0942505db2..18ae10612d 100644 --- a/input/connect/joypad_connection.c +++ b/input/connect/joypad_connection.c @@ -103,7 +103,7 @@ int32_t pad_connection_pad_init(joypad_connection_t *joyconn, const char *name_match = strstr(pad_map[i].name, name); /* Never change, Nintendo. */ - if(pad_map[i].vid == 1406 && pad_map[i].pid == 816) + if(pad_map[i].vid == 1406 && pad_map[i].pid == 816) { if(!string_is_equal(pad_map[i].name, name)) continue; @@ -133,7 +133,7 @@ int32_t pad_connection_pad_init(joypad_connection_t *joyconn, } } - /* We failed to find a matching pad, + /* We failed to find a matching pad, * set up one without an interface */ if (!s->connected) { @@ -173,11 +173,13 @@ void pad_connection_packet(joypad_connection_t *joyconn, uint32_t pad, joyconn->iface->packet_handler(joyconn->data, data, length); } -uint64_t pad_connection_get_buttons(joypad_connection_t *joyconn, unsigned pad) +void pad_connection_get_buttons(joypad_connection_t *joyconn, unsigned pad, retro_bits_t* state) { - if (!joyconn->iface) - return 0; - return joyconn->iface->get_buttons(joyconn->data); + if (joyconn->iface) { + joyconn->iface->get_buttons(joyconn->data, state); + } else { + RARCH_INPUT_STATE_CLEAR_PTR( state ); + } } int16_t pad_connection_get_axis(joypad_connection_t *joyconn, @@ -190,8 +192,8 @@ int16_t pad_connection_get_axis(joypad_connection_t *joyconn, bool pad_connection_has_interface(joypad_connection_t *joyconn, unsigned pad) { - if ( joyconn && pad < MAX_USERS - && joyconn[pad].connected + if ( joyconn && pad < MAX_USERS + && joyconn[pad].connected && joyconn[pad].iface) return true; return false; diff --git a/input/connect/joypad_connection.h b/input/connect/joypad_connection.h index c0d3669853..75b6dbb633 100644 --- a/input/connect/joypad_connection.h +++ b/input/connect/joypad_connection.h @@ -21,6 +21,7 @@ #include #include +#include typedef void (*send_control_t)(void *data, uint8_t *buf, size_t size); @@ -38,7 +39,7 @@ typedef struct pad_connection_interface void (*packet_handler)(void* device, uint8_t *packet, uint16_t size); void (*set_rumble)(void* device, enum retro_rumble_effect effect, uint16_t strength); - uint64_t (*get_buttons)(void *data); + void (*get_buttons)(void *data, retro_bits_t *state); int16_t (*get_axis)(void *data, unsigned axis); const char* (*get_name)(void *data); } pad_connection_interface_t; @@ -69,8 +70,8 @@ void pad_connection_pad_deinit(joypad_connection_t *joyconn, void pad_connection_packet(joypad_connection_t *joyconn, uint32_t idx, uint8_t* data, uint32_t length); -uint64_t pad_connection_get_buttons(joypad_connection_t *joyconn, - unsigned idx); +void pad_connection_get_buttons(joypad_connection_t *joyconn, + unsigned idx, retro_bits_t* state); int16_t pad_connection_get_axis(joypad_connection_t *joyconn, unsigned idx, unsigned i); diff --git a/input/drivers/cocoa_input.c b/input/drivers/cocoa_input.c index 9b84770b8b..ceeaf417b1 100644 --- a/input/drivers/cocoa_input.c +++ b/input/drivers/cocoa_input.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2011-2017 - Daniel De Matteis * Copyright (C) 2013-2014 - Jason Fetters - * + * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. @@ -36,13 +36,13 @@ float get_backing_scale_factor(void); int32_t cocoa_input_find_any_key(void) { cocoa_input_data_t *apple = (cocoa_input_data_t*)input_driver_get_data(); - + if (!apple) return 0; - + if (apple->joypad) apple->joypad->poll(); - + if (apple->sec_joypad) apple->sec_joypad->poll(); @@ -50,13 +50,13 @@ int32_t cocoa_input_find_any_key(void) } static int cocoa_input_find_any_button_ret(cocoa_input_data_t *apple, - unsigned buttons, unsigned port) + retro_bits_t * state, unsigned port) { unsigned i; - if (buttons) - for (i = 0; i < 32; i++) - if (buttons & (1 << i)) + if (state) + for (i = 0; i < 256; i++) + if (RARCH_INPUT_STATE_BIT_GET_PTR(state,i)) return i; return -1; } @@ -68,26 +68,32 @@ int32_t cocoa_input_find_any_button(uint32_t port) if (!apple) return -1; - + if (apple->joypad) { apple->joypad->poll(); if (apple->joypad->get_buttons) - ret = cocoa_input_find_any_button_ret(apple, (unsigned)apple->joypad->get_buttons(port), port); + { + retro_bits_t state; + apple->joypad->get_buttons(port,&state); + ret = cocoa_input_find_any_button_ret(apple, &state, port); + } } if (ret != -1) return ret; - + if (apple->sec_joypad) { apple->sec_joypad->poll(); if (apple->sec_joypad->get_buttons) { + retro_bits_t state; apple->sec_joypad->poll(); - ret = cocoa_input_find_any_button_ret(apple, (unsigned)apple->sec_joypad->get_buttons(port), port); + apple->sec_joypad->get_buttons(port,&state); + ret = cocoa_input_find_any_button_ret(apple, &state, port); } } @@ -101,17 +107,17 @@ int32_t cocoa_input_find_any_axis(uint32_t port) { int i; cocoa_input_data_t *apple = (cocoa_input_data_t*)input_driver_get_data(); - + if (apple && apple->joypad) apple->joypad->poll(); - + if (apple && apple->sec_joypad) apple->sec_joypad->poll(); for (i = 0; i < 6; i++) { int16_t value = apple->joypad ? apple->joypad->axis(port, i) : 0; - + if (abs(value) > 0x4000) return (value < 0) ? -(i + 1) : i + 1; @@ -130,15 +136,15 @@ static void *cocoa_input_init(const char *joypad_driver) cocoa_input_data_t *apple = (cocoa_input_data_t*)calloc(1, sizeof(*apple)); if (!apple) return NULL; - + input_keymaps_init_keyboard_lut(rarch_key_map_apple_hid); apple->joypad = input_joypad_init_driver(joypad_driver, apple); - + #ifdef HAVE_MFI apple->sec_joypad = input_joypad_init_driver("mfi", apple); #endif - + return apple; } @@ -149,14 +155,14 @@ static void cocoa_input_poll(void *data) #ifndef IOS float backing_scale_factor = get_backing_scale_factor(); #endif - + if (!apple) return; for (i = 0; i < apple->touch_count; i++) { struct video_viewport vp; - + vp.x = 0; vp.y = 0; vp.width = 0; @@ -249,13 +255,13 @@ static int16_t cocoa_pointer_state(cocoa_input_data_t *apple, int16_t x, y; const cocoa_touch_data_t *touch = (const cocoa_touch_data_t *) &apple->touches[idx]; - + if (!touch) return 0; - + x = touch->fixed_x; y = touch->fixed_y; - + if (want_full) { x = touch->full_x; @@ -328,16 +334,16 @@ static void cocoa_input_free(void *data) { unsigned i; cocoa_input_data_t *apple = (cocoa_input_data_t*)data; - + if (!apple || !data) return; - + if (apple->joypad) apple->joypad->destroy(); - + if (apple->sec_joypad) apple->sec_joypad->destroy(); - + for (i = 0; i < MAX_KEYS; i++) apple_key_state[i] = 0; @@ -348,7 +354,7 @@ static bool cocoa_input_set_rumble(void *data, unsigned port, enum retro_rumble_effect effect, uint16_t strength) { cocoa_input_data_t *apple = (cocoa_input_data_t*)data; - + if (apple && apple->joypad) return input_joypad_set_rumble(apple->joypad, port, effect, strength); @@ -364,7 +370,7 @@ static uint64_t cocoa_input_get_capabilities(void *data) { (void)data; - return + return (1 << RETRO_DEVICE_JOYPAD) | (1 << RETRO_DEVICE_MOUSE) | (1 << RETRO_DEVICE_KEYBOARD) | @@ -382,7 +388,7 @@ static void cocoa_input_grab_mouse(void *data, bool state) static const input_device_driver_t *cocoa_input_get_sec_joypad_driver(void *data) { cocoa_input_data_t *apple = (cocoa_input_data_t*)data; - + if (apple && apple->sec_joypad) return apple->sec_joypad; return NULL; @@ -391,7 +397,7 @@ static const input_device_driver_t *cocoa_input_get_sec_joypad_driver(void *data static const input_device_driver_t *cocoa_input_get_joypad_driver(void *data) { cocoa_input_data_t *apple = (cocoa_input_data_t*)data; - + if (apple && apple->joypad) return apple->joypad; return NULL; diff --git a/input/drivers/wiiu_input.c b/input/drivers/wiiu_input.c index 9673947317..7cb9444b3c 100644 --- a/input/drivers/wiiu_input.c +++ b/input/drivers/wiiu_input.c @@ -105,7 +105,11 @@ static int16_t wiiu_pointer_device_state(wiiu_input_t* wiiu, unsigned id) switch (id) { case RETRO_DEVICE_ID_POINTER_PRESSED: - return (wiiu->joypad->get_buttons(0) & VPAD_BUTTON_TOUCH) ? 1 : 0; + { + retro_bits_t state; + wiiu->joypad->get_buttons(0,&state); + return RARCH_INPUT_STATE_BIT_GET(state, VPAD_BUTTON_TOUCH) ? 1 : 0; + } case RETRO_DEVICE_ID_POINTER_X: return wiiu->joypad->axis(0, 0xFFFF0004UL); case RETRO_DEVICE_ID_POINTER_Y: diff --git a/input/drivers/winraw_input.c b/input/drivers/winraw_input.c index c7397d39d8..31f86cadb5 100644 --- a/input/drivers/winraw_input.c +++ b/input/drivers/winraw_input.c @@ -1,764 +1,858 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2011-2017 - Daniel De Matteis - * - * RetroArch is free software: you can redistribute it and/or modify it under the terms - * of the GNU General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with RetroArch. - * If not, see . - */ - -#include - -#include "../input_driver.h" -#include "../input_keymaps.h" - -#include "../../configuration.h" -#include "../../gfx/video_driver.h" -#include "../../verbosity.h" - -typedef struct -{ - uint8_t keys[256]; -} winraw_keyboard_t; - -typedef struct -{ - HANDLE hnd; - LONG x, y, dlt_x, dlt_y; - LONG whl_u, whl_d; - bool btn_l, btn_m, btn_r, btn_b4, btn_b5; -} winraw_mouse_t; - -typedef struct -{ - bool kbd_mapp_block; - bool mouse_grab; - winraw_keyboard_t keyboard; - HWND window; - winraw_mouse_t *mice; - const input_device_driver_t *joypad; -} winraw_input_t; - -static winraw_keyboard_t *g_keyboard = NULL; -static winraw_mouse_t *g_mice = NULL; -static unsigned g_mouse_cnt = 0; -static bool g_mouse_xy_mapping_ready = false; -static double g_view_abs_ratio_x = 0.0; -static double g_view_abs_ratio_y = 0.0; - -static HWND winraw_create_window(WNDPROC wnd_proc) -{ - HWND wnd; - WNDCLASSA wc = {0}; - - wc.hInstance = GetModuleHandleA(NULL); - - if (!wc.hInstance) - { - RARCH_ERR("[WINRAW]: GetModuleHandleA failed with error %lu.\n", GetLastError()); - return NULL; - } - - wc.lpfnWndProc = wnd_proc; - wc.lpszClassName = "winraw-input"; - if (!RegisterClassA(&wc) && GetLastError() != ERROR_CLASS_ALREADY_EXISTS) - { - RARCH_ERR("[WINRAW]: RegisterClassA failed with error %lu.\n", GetLastError()); - return NULL; - } - - wnd = CreateWindowExA(0, wc.lpszClassName, NULL, 0, 0, 0, 0, 0, - HWND_MESSAGE, NULL, NULL, NULL); - if (!wnd) - { - RARCH_ERR("[WINRAW]: CreateWindowExA failed with error %lu.\n", GetLastError()); - goto error; - } - - return wnd; - -error: - UnregisterClassA(wc.lpszClassName, NULL); - return NULL; -} - -static void winraw_destroy_window(HWND wnd) -{ - BOOL r; - - if (!wnd) - return; - - r = DestroyWindow(wnd); - - if (!r) - { - RARCH_WARN("[WINRAW]: DestroyWindow failed with error %lu.\n", GetLastError()); - } - - r = UnregisterClassA("winraw-input", NULL); - - if (!r) - { - RARCH_WARN("[WINRAW]: UnregisterClassA failed with error %lu.\n", GetLastError()); - } -} - -static bool winraw_set_keyboard_input(HWND window) -{ - RAWINPUTDEVICE rid; - BOOL r; - - rid.dwFlags = window ? 0 : RIDEV_REMOVE; - rid.hwndTarget = window; - rid.usUsagePage = 0x01; /* generic desktop */ - rid.usUsage = 0x06; /* keyboard */ - - r = RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE)); - - if (!r) - { - RARCH_ERR("[WINRAW]: RegisterRawInputDevices failed with error %lu.\n", GetLastError()); - return false; - } - - return true; -} - -static void winraw_log_mice_info(winraw_mouse_t *mice, unsigned mouse_cnt) -{ - UINT r; - unsigned i; - char name[256]; - UINT name_size = sizeof(name); - - for (i = 0; i < mouse_cnt; ++i) - { - r = GetRawInputDeviceInfoA(mice[i].hnd, RIDI_DEVICENAME, name, &name_size); - if (r == (UINT)-1 || r == 0) - name[0] = '\0'; - RARCH_LOG("[WINRAW]: Mouse #%u %s.\n", i, name); - } -} - -static bool winraw_init_devices(winraw_mouse_t **mice, unsigned *mouse_cnt) -{ - UINT i; - POINT crs_pos; - winraw_mouse_t *mice_r = NULL; - unsigned mouse_cnt_r = 0; - RAWINPUTDEVICELIST *devs = NULL; - UINT dev_cnt = 0; - UINT r = GetRawInputDeviceList( - NULL, &dev_cnt, sizeof(RAWINPUTDEVICELIST)); - - if (r == (UINT)-1) - { - RARCH_ERR("[WINRAW]: GetRawInputDeviceList failed with error %lu.\n", GetLastError()); - goto error; - } - - devs = (RAWINPUTDEVICELIST*)malloc(dev_cnt * sizeof(RAWINPUTDEVICELIST)); - if (!devs) - goto error; - - dev_cnt = GetRawInputDeviceList(devs, &dev_cnt, sizeof(RAWINPUTDEVICELIST)); - if (dev_cnt == (UINT)-1) - { - RARCH_ERR("[WINRAW]: GetRawInputDeviceList failed with error %lu.\n", GetLastError()); - goto error; - } - - for (i = 0; i < dev_cnt; ++i) - mouse_cnt_r += devs[i].dwType == RIM_TYPEMOUSE ? 1 : 0; - - if (mouse_cnt_r) - { - mice_r = (winraw_mouse_t*)calloc(1, mouse_cnt_r * sizeof(winraw_mouse_t)); - if (!mice_r) - goto error; - - if (!GetCursorPos(&crs_pos)) - goto error; - - for (i = 0; i < mouse_cnt_r; ++i) - { - mice_r[i].x = crs_pos.x; - mice_r[i].y = crs_pos.y; - } - } - - /* count is already checked, so this is safe */ - for (i = mouse_cnt_r = 0; i < dev_cnt; ++i) - { - if (devs[i].dwType == RIM_TYPEMOUSE) - mice_r[mouse_cnt_r++].hnd = devs[i].hDevice; - } - - winraw_log_mice_info(mice_r, mouse_cnt_r); - - *mice = mice_r; - *mouse_cnt = mouse_cnt_r; - - return true; - -error: - free(devs); - free(mice_r); - *mice = NULL; - *mouse_cnt = 0; - return false; -} - -static bool winraw_set_mouse_input(HWND window, bool grab) -{ - RAWINPUTDEVICE rid; - BOOL r; - - if (window) - rid.dwFlags = grab ? RIDEV_CAPTUREMOUSE : 0; - else - rid.dwFlags = RIDEV_REMOVE; - - rid.hwndTarget = window; - rid.usUsagePage = 0x01; /* generic desktop */ - rid.usUsage = 0x02; /* mouse */ - - r = RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE)); - - if (!r) - { - RARCH_ERR("[WINRAW]: RegisterRawInputDevice failed with error %lu.\n", GetLastError()); - return false; - } - - return true; -} - -static int16_t winraw_mouse_state(winraw_input_t *wr, - unsigned port, bool abs, unsigned id) -{ - unsigned i; - settings_t *settings = config_get_ptr(); - winraw_mouse_t *mouse = NULL; - - if (port >= MAX_USERS) - return 0; - - for (i = 0; i < g_mouse_cnt; ++i) - { - if (i == settings->uints.input_mouse_index[port]) - { - mouse = &wr->mice[i]; - break; - } - } - - if (!mouse) - return 0; - - switch (id) - { - case RETRO_DEVICE_ID_MOUSE_X: - return abs ? mouse->x : mouse->dlt_x; - case RETRO_DEVICE_ID_MOUSE_Y: - return abs ? mouse->y : mouse->dlt_y; - case RETRO_DEVICE_ID_MOUSE_LEFT: - return mouse->btn_l ? 1 : 0; - case RETRO_DEVICE_ID_MOUSE_RIGHT: - return mouse->btn_r ? 1 : 0; - case RETRO_DEVICE_ID_MOUSE_WHEELUP: - return mouse->whl_u ? 1 : 0; - case RETRO_DEVICE_ID_MOUSE_WHEELDOWN: - return mouse->whl_d ? 1 : 0; - case RETRO_DEVICE_ID_MOUSE_MIDDLE: - return mouse->btn_m ? 1 : 0; - case RETRO_DEVICE_ID_MOUSE_BUTTON_4: - return mouse->btn_b4 ? 1 : 0; - case RETRO_DEVICE_ID_MOUSE_BUTTON_5: - return mouse->btn_b5 ? 1 : 0; - } - - return 0; -} - -static bool winraw_mbutton_pressed(winraw_input_t *wr, unsigned port, unsigned key) -{ - unsigned i; - bool result; - winraw_mouse_t *mouse = NULL; - settings_t *settings = config_get_ptr(); - - if (port >= MAX_USERS) - return false; - - for (i = 0; i < g_mouse_cnt; ++i) - { - if (i == settings->uints.input_mouse_index[port]) - { - mouse = &wr->mice[i]; - break; - } - } - - if (!mouse) - return false; - - switch ( key ) - { - - case RETRO_DEVICE_ID_MOUSE_LEFT: - return mouse->btn_l; - case RETRO_DEVICE_ID_MOUSE_RIGHT: - return mouse->btn_r; - case RETRO_DEVICE_ID_MOUSE_MIDDLE: - return mouse->btn_m; - case RETRO_DEVICE_ID_MOUSE_BUTTON_4: - return mouse->btn_b4; - case RETRO_DEVICE_ID_MOUSE_BUTTON_5: - return mouse->btn_b5; - case RETRO_DEVICE_ID_MOUSE_WHEELUP: - return mouse->whl_u; - case RETRO_DEVICE_ID_MOUSE_WHEELDOWN: - return mouse->whl_d; - } - - return false; -} - -static int16_t winraw_joypad_state(winraw_input_t *wr, - rarch_joypad_info_t joypad_info, - const struct retro_keybind *binds, - unsigned port, unsigned id) -{ - const struct retro_keybind *bind = &binds[id]; - unsigned key = rarch_keysym_lut[(enum retro_key)bind->key]; - - if (!wr->kbd_mapp_block && (bind->key < RETROK_LAST) && wr->keyboard.keys[key]) - return 1; - - if (binds && binds[id].valid && winraw_mbutton_pressed(wr, port, bind->mbutton)) - return 1; - - return input_joypad_pressed(wr->joypad, joypad_info, port, binds, id); -} - -static void winraw_init_mouse_xy_mapping() -{ - struct video_viewport viewport; - int center_x; - int center_y; - unsigned i; - - if (video_driver_get_viewport_info(&viewport)) - { - center_x = viewport.x + viewport.width / 2; - center_y = viewport.y + viewport.height / 2; - - for (i = 0; i < g_mouse_cnt; ++i) - { - g_mice[i].x = center_x; - g_mice[i].y = center_y; - } - - g_view_abs_ratio_x = (double)viewport.full_width / 65535.0; - g_view_abs_ratio_y = (double)viewport.full_height / 65535.0; - - g_mouse_xy_mapping_ready = true; - } -} - -static int16_t winraw_lightgun_state(winraw_input_t *wr, - unsigned port, unsigned id) -{ - unsigned i; - settings_t *settings = config_get_ptr(); - winraw_mouse_t *mouse = NULL; - - if (port >= MAX_USERS) - return 0; - - for (i = 0; i < g_mouse_cnt; ++i) - { - if (i == settings->uints.input_mouse_index[port]) - { - mouse = &wr->mice[i]; - break; - } - } - - if (!mouse) - return 0; - - switch (id) - { - case RETRO_DEVICE_ID_LIGHTGUN_X: - return mouse->dlt_x; - case RETRO_DEVICE_ID_LIGHTGUN_Y: - return mouse->dlt_y; - case RETRO_DEVICE_ID_LIGHTGUN_TRIGGER: - return mouse->btn_l ? 1 : 0; - case RETRO_DEVICE_ID_LIGHTGUN_CURSOR: - return mouse->btn_m ? 1 : 0; - case RETRO_DEVICE_ID_LIGHTGUN_TURBO: - return mouse->btn_r ? 1 : 0; - case RETRO_DEVICE_ID_LIGHTGUN_START: - return (mouse->btn_m && mouse->btn_r) ? 1 : 0; - case RETRO_DEVICE_ID_LIGHTGUN_PAUSE: - return mouse->btn_m && mouse->btn_l ? 1 : 0; - } - - return 0; -} - -static void winraw_update_mouse_state(winraw_mouse_t *mouse, RAWMOUSE *state) -{ - POINT crs_pos; - - if (state->usFlags & MOUSE_MOVE_ABSOLUTE) - { - if (g_mouse_xy_mapping_ready) - { - state->lLastX = (LONG)(g_view_abs_ratio_x * state->lLastX); - state->lLastY = (LONG)(g_view_abs_ratio_y * state->lLastY); - InterlockedExchangeAdd(&mouse->dlt_x, state->lLastX - mouse->x); - InterlockedExchangeAdd(&mouse->dlt_y, state->lLastY - mouse->y); - mouse->x = state->lLastX; - mouse->y = state->lLastY; - } - else - winraw_init_mouse_xy_mapping(); - } - else if (state->lLastX || state->lLastY) - { - InterlockedExchangeAdd(&mouse->dlt_x, state->lLastX); - InterlockedExchangeAdd(&mouse->dlt_y, state->lLastY); - - if (!GetCursorPos(&crs_pos)) - { - RARCH_WARN("[WINRAW]: GetCursorPos failed with error %lu.\n", GetLastError()); - } - else if (!ScreenToClient((HWND)video_driver_window_get(), &crs_pos)) - { - RARCH_WARN("[WINRAW]: ScreenToClient failed with error %lu.\n", GetLastError()); - } - else - { - mouse->x = crs_pos.x; - mouse->y = crs_pos.y; - } - } - - if (state->usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN) - mouse->btn_l = true; - else if (state->usButtonFlags & RI_MOUSE_LEFT_BUTTON_UP) - mouse->btn_l = false; - - if (state->usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_DOWN) - mouse->btn_m = true; - else if (state->usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_UP) - mouse->btn_m = false; - - if (state->usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN) - mouse->btn_r = true; - else if (state->usButtonFlags & RI_MOUSE_RIGHT_BUTTON_UP) - mouse->btn_r = false; - - if (state->usButtonFlags & RI_MOUSE_BUTTON_4_DOWN) - mouse->btn_b4 = true; - else if (state->usButtonFlags & RI_MOUSE_BUTTON_4_UP) - mouse->btn_b4 = false; - - if (state->usButtonFlags & RI_MOUSE_BUTTON_5_DOWN) - mouse->btn_b5 = true; - else if (state->usButtonFlags & RI_MOUSE_BUTTON_5_UP) - mouse->btn_b5 = false; - - if (state->usButtonFlags & RI_MOUSE_WHEEL) - { - if ((SHORT)state->usButtonData > 0) - InterlockedExchange(&mouse->whl_u, 1); - else if ((SHORT)state->usButtonData < 0) - InterlockedExchange(&mouse->whl_d, 1); - } -} - -static LRESULT CALLBACK winraw_callback(HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar) -{ - static uint8_t data[1024]; - UINT r; - unsigned i; - RAWINPUT *ri = (RAWINPUT*)data; - UINT size = sizeof(data); - - if (msg != WM_INPUT) - return DefWindowProcA(wnd, msg, wpar, lpar); - - /* app is in the background */ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2011-2017 - Daniel De Matteis + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#include + +#include "../input_driver.h" +#include "../input_keymaps.h" + +#include "../../configuration.h" +#include "../../gfx/video_driver.h" +#include "../../verbosity.h" + +typedef struct +{ + uint8_t keys[256]; +} winraw_keyboard_t; + +typedef struct +{ + HANDLE hnd; + LONG x, y, dlt_x, dlt_y; + LONG whl_u, whl_d; + bool btn_l, btn_m, btn_r, btn_b4, btn_b5; +} winraw_mouse_t; + +typedef struct +{ + bool kbd_mapp_block; + bool mouse_grab; + winraw_keyboard_t keyboard; + HWND window; + winraw_mouse_t *mice; + const input_device_driver_t *joypad; +} winraw_input_t; + +static winraw_keyboard_t *g_keyboard = NULL; +static winraw_mouse_t *g_mice = NULL; +static unsigned g_mouse_cnt = 0; +static bool g_mouse_xy_mapping_ready = false; +static double g_view_abs_ratio_x = 0.0; +static double g_view_abs_ratio_y = 0.0; + +static HWND winraw_create_window(WNDPROC wnd_proc) +{ + HWND wnd; + WNDCLASSA wc = {0}; + + wc.hInstance = GetModuleHandleA(NULL); + + if (!wc.hInstance) + { + RARCH_ERR("[WINRAW]: GetModuleHandleA failed with error %lu.\n", GetLastError()); + return NULL; + } + + wc.lpfnWndProc = wnd_proc; + wc.lpszClassName = "winraw-input"; + if (!RegisterClassA(&wc) && GetLastError() != ERROR_CLASS_ALREADY_EXISTS) + { + RARCH_ERR("[WINRAW]: RegisterClassA failed with error %lu.\n", GetLastError()); + return NULL; + } + + wnd = CreateWindowExA(0, wc.lpszClassName, NULL, 0, 0, 0, 0, 0, + HWND_MESSAGE, NULL, NULL, NULL); + if (!wnd) + { + RARCH_ERR("[WINRAW]: CreateWindowExA failed with error %lu.\n", GetLastError()); + goto error; + } + + return wnd; + +error: + UnregisterClassA(wc.lpszClassName, NULL); + return NULL; +} + +static void winraw_destroy_window(HWND wnd) +{ + BOOL r; + + if (!wnd) + return; + + r = DestroyWindow(wnd); + + if (!r) + { + RARCH_WARN("[WINRAW]: DestroyWindow failed with error %lu.\n", GetLastError()); + } + + r = UnregisterClassA("winraw-input", NULL); + + if (!r) + { + RARCH_WARN("[WINRAW]: UnregisterClassA failed with error %lu.\n", GetLastError()); + } +} + +static bool winraw_set_keyboard_input(HWND window) +{ + RAWINPUTDEVICE rid; + BOOL r; + + rid.dwFlags = window ? 0 : RIDEV_REMOVE; + rid.hwndTarget = window; + rid.usUsagePage = 0x01; /* generic desktop */ + rid.usUsage = 0x06; /* keyboard */ + + r = RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE)); + + if (!r) + { + RARCH_ERR("[WINRAW]: RegisterRawInputDevices failed with error %lu.\n", GetLastError()); + return false; + } + + return true; +} + +static void winraw_log_mice_info(winraw_mouse_t *mice, unsigned mouse_cnt) +{ + UINT r; + unsigned i; + char name[256]; + UINT name_size = sizeof(name); + + for (i = 0; i < mouse_cnt; ++i) + { + r = GetRawInputDeviceInfoA(mice[i].hnd, RIDI_DEVICENAME, name, &name_size); + if (r == (UINT)-1 || r == 0) + name[0] = '\0'; + RARCH_LOG("[WINRAW]: Mouse #%u %s.\n", i, name); + } +} + +static bool winraw_init_devices(winraw_mouse_t **mice, unsigned *mouse_cnt) +{ + UINT i; + POINT crs_pos; + winraw_mouse_t *mice_r = NULL; + unsigned mouse_cnt_r = 0; + RAWINPUTDEVICELIST *devs = NULL; + UINT dev_cnt = 0; + UINT r = GetRawInputDeviceList( + NULL, &dev_cnt, sizeof(RAWINPUTDEVICELIST)); + + if (r == (UINT)-1) + { + RARCH_ERR("[WINRAW]: GetRawInputDeviceList failed with error %lu.\n", GetLastError()); + goto error; + } + + devs = (RAWINPUTDEVICELIST*)malloc(dev_cnt * sizeof(RAWINPUTDEVICELIST)); + if (!devs) + goto error; + + dev_cnt = GetRawInputDeviceList(devs, &dev_cnt, sizeof(RAWINPUTDEVICELIST)); + if (dev_cnt == (UINT)-1) + { + RARCH_ERR("[WINRAW]: GetRawInputDeviceList failed with error %lu.\n", GetLastError()); + goto error; + } + + for (i = 0; i < dev_cnt; ++i) + mouse_cnt_r += devs[i].dwType == RIM_TYPEMOUSE ? 1 : 0; + + if (mouse_cnt_r) + { + mice_r = (winraw_mouse_t*)calloc(1, mouse_cnt_r * sizeof(winraw_mouse_t)); + if (!mice_r) + goto error; + + if (!GetCursorPos(&crs_pos)) + goto error; + + for (i = 0; i < mouse_cnt_r; ++i) + { + mice_r[i].x = crs_pos.x; + mice_r[i].y = crs_pos.y; + } + } + + /* count is already checked, so this is safe */ + for (i = mouse_cnt_r = 0; i < dev_cnt; ++i) + { + if (devs[i].dwType == RIM_TYPEMOUSE) + mice_r[mouse_cnt_r++].hnd = devs[i].hDevice; + } + + winraw_log_mice_info(mice_r, mouse_cnt_r); + + *mice = mice_r; + *mouse_cnt = mouse_cnt_r; + + return true; + +error: + free(devs); + free(mice_r); + *mice = NULL; + *mouse_cnt = 0; + return false; +} + +static bool winraw_set_mouse_input(HWND window, bool grab) +{ + RAWINPUTDEVICE rid; + BOOL r; + + if (window) + rid.dwFlags = grab ? RIDEV_CAPTUREMOUSE : 0; + else + rid.dwFlags = RIDEV_REMOVE; + + rid.hwndTarget = window; + rid.usUsagePage = 0x01; /* generic desktop */ + rid.usUsage = 0x02; /* mouse */ + + r = RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE)); + + if (!r) + { + RARCH_ERR("[WINRAW]: RegisterRawInputDevice failed with error %lu.\n", GetLastError()); + return false; + } + + return true; +} + +static int16_t winraw_lightgun_aiming_state(winraw_input_t *wr, + unsigned port, unsigned id) +{ + const int edge_detect = 32700; + struct video_viewport vp; + bool inside = false; + unsigned i; + settings_t *settings = config_get_ptr(); + winraw_mouse_t *mouse = NULL; + int16_t res_x = 0; + int16_t res_y = 0; + int16_t res_screen_x = 0; + int16_t res_screen_y = 0; + + if (port >= MAX_USERS) + return 0; + + for (i = 0; i < g_mouse_cnt; ++i) + { + if (i == settings->uints.input_mouse_index[port]) + { + mouse = &wr->mice[i]; + break; + } + } + + if (!mouse) + return 0; + + vp.x = 0; + vp.y = 0; + vp.width = 0; + vp.height = 0; + vp.full_width = 0; + vp.full_height = 0; + + if ( !( video_driver_translate_coord_viewport_wrap( + &vp, mouse->x, mouse->y, &res_x, &res_y, &res_screen_x, &res_screen_y ) ) ) + { + return 0; + } + + inside = (res_x >= -edge_detect) && (res_y >= -edge_detect) && (res_x <= edge_detect) && (res_y <= edge_detect); + + switch ( id ) + { + case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X: + return inside ? res_x : 0; + case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y: + return inside ? res_y : 0; + case RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN: + return !inside; + default: + break; + } + + return 0; +} + +static int16_t winraw_mouse_state(winraw_input_t *wr, + unsigned port, bool abs, unsigned id) +{ + unsigned i; + settings_t *settings = config_get_ptr(); + winraw_mouse_t *mouse = NULL; + + if (port >= MAX_USERS) + return 0; + + for (i = 0; i < g_mouse_cnt; ++i) + { + if (i == settings->uints.input_mouse_index[port]) + { + mouse = &wr->mice[i]; + break; + } + } + + if (!mouse) + return 0; + + switch (id) + { + case RETRO_DEVICE_ID_MOUSE_X: + return abs ? mouse->x : mouse->dlt_x; + case RETRO_DEVICE_ID_MOUSE_Y: + return abs ? mouse->y : mouse->dlt_y; + case RETRO_DEVICE_ID_MOUSE_LEFT: + return mouse->btn_l ? 1 : 0; + case RETRO_DEVICE_ID_MOUSE_RIGHT: + return mouse->btn_r ? 1 : 0; + case RETRO_DEVICE_ID_MOUSE_WHEELUP: + return mouse->whl_u ? 1 : 0; + case RETRO_DEVICE_ID_MOUSE_WHEELDOWN: + return mouse->whl_d ? 1 : 0; + case RETRO_DEVICE_ID_MOUSE_MIDDLE: + return mouse->btn_m ? 1 : 0; + case RETRO_DEVICE_ID_MOUSE_BUTTON_4: + return mouse->btn_b4 ? 1 : 0; + case RETRO_DEVICE_ID_MOUSE_BUTTON_5: + return mouse->btn_b5 ? 1 : 0; + } + + return 0; +} + +static bool winraw_keyboard_pressed(winraw_input_t *wr, unsigned key) +{ + unsigned k = rarch_keysym_lut[(enum retro_key)key]; + return wr->keyboard.keys[k]; +} + +static bool winraw_mbutton_pressed(winraw_input_t *wr, unsigned port, unsigned key) +{ + unsigned i; + bool result; + winraw_mouse_t *mouse = NULL; + settings_t *settings = config_get_ptr(); + + if (port >= MAX_USERS) + return false; + + for (i = 0; i < g_mouse_cnt; ++i) + { + if (i == settings->uints.input_mouse_index[port]) + { + mouse = &wr->mice[i]; + break; + } + } + + if (!mouse) + return false; + + switch ( key ) + { + + case RETRO_DEVICE_ID_MOUSE_LEFT: + return mouse->btn_l; + case RETRO_DEVICE_ID_MOUSE_RIGHT: + return mouse->btn_r; + case RETRO_DEVICE_ID_MOUSE_MIDDLE: + return mouse->btn_m; + case RETRO_DEVICE_ID_MOUSE_BUTTON_4: + return mouse->btn_b4; + case RETRO_DEVICE_ID_MOUSE_BUTTON_5: + return mouse->btn_b5; + case RETRO_DEVICE_ID_MOUSE_WHEELUP: + return mouse->whl_u; + case RETRO_DEVICE_ID_MOUSE_WHEELDOWN: + return mouse->whl_d; + } + + return false; +} + +static bool winraw_is_pressed(winraw_input_t *wr, + rarch_joypad_info_t joypad_info, + const struct retro_keybind *binds, + unsigned port, unsigned id) +{ + const struct retro_keybind *bind = &binds[id]; + + if (!wr->kbd_mapp_block && (bind->key < RETROK_LAST) && winraw_keyboard_pressed(wr, bind->key)) + return true; + if (binds && binds[id].valid) + { + if (winraw_mbutton_pressed(wr, port, bind->mbutton)) + return true; + if (input_joypad_pressed(wr->joypad, joypad_info, port, binds, id)) + return true; + } + + return false; +} + +static void winraw_init_mouse_xy_mapping() +{ + struct video_viewport viewport; + int center_x; + int center_y; + unsigned i; + + if (video_driver_get_viewport_info(&viewport)) + { + center_x = viewport.x + viewport.width / 2; + center_y = viewport.y + viewport.height / 2; + + for (i = 0; i < g_mouse_cnt; ++i) + { + g_mice[i].x = center_x; + g_mice[i].y = center_y; + } + + g_view_abs_ratio_x = (double)viewport.full_width / 65535.0; + g_view_abs_ratio_y = (double)viewport.full_height / 65535.0; + + g_mouse_xy_mapping_ready = true; + } +} + +static int16_t winraw_deprecated_lightgun_state(winraw_input_t *wr, + unsigned port, unsigned id) +{ + unsigned i; + settings_t *settings = config_get_ptr(); + winraw_mouse_t *mouse = NULL; + + if (port >= MAX_USERS) + return 0; + + for (i = 0; i < g_mouse_cnt; ++i) + { + if (i == settings->uints.input_mouse_index[port]) + { + mouse = &wr->mice[i]; + break; + } + } + + if (!mouse) + return 0; + + switch (id) + { + case RETRO_DEVICE_ID_LIGHTGUN_X: + return mouse->dlt_x; + case RETRO_DEVICE_ID_LIGHTGUN_Y: + return mouse->dlt_y; + } + + return 0; +} + +static void winraw_update_mouse_state(winraw_mouse_t *mouse, RAWMOUSE *state) +{ + POINT crs_pos; + + if (state->usFlags & MOUSE_MOVE_ABSOLUTE) + { + if (g_mouse_xy_mapping_ready) + { + state->lLastX = (LONG)(g_view_abs_ratio_x * state->lLastX); + state->lLastY = (LONG)(g_view_abs_ratio_y * state->lLastY); + InterlockedExchangeAdd(&mouse->dlt_x, state->lLastX - mouse->x); + InterlockedExchangeAdd(&mouse->dlt_y, state->lLastY - mouse->y); + mouse->x = state->lLastX; + mouse->y = state->lLastY; + } + else + winraw_init_mouse_xy_mapping(); + } + else if (state->lLastX || state->lLastY) + { + InterlockedExchangeAdd(&mouse->dlt_x, state->lLastX); + InterlockedExchangeAdd(&mouse->dlt_y, state->lLastY); + + if (!GetCursorPos(&crs_pos)) + { + RARCH_WARN("[WINRAW]: GetCursorPos failed with error %lu.\n", GetLastError()); + } + else if (!ScreenToClient((HWND)video_driver_window_get(), &crs_pos)) + { + RARCH_WARN("[WINRAW]: ScreenToClient failed with error %lu.\n", GetLastError()); + } + else + { + mouse->x = crs_pos.x; + mouse->y = crs_pos.y; + } + } + + if (state->usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN) + mouse->btn_l = true; + else if (state->usButtonFlags & RI_MOUSE_LEFT_BUTTON_UP) + mouse->btn_l = false; + + if (state->usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_DOWN) + mouse->btn_m = true; + else if (state->usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_UP) + mouse->btn_m = false; + + if (state->usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN) + mouse->btn_r = true; + else if (state->usButtonFlags & RI_MOUSE_RIGHT_BUTTON_UP) + mouse->btn_r = false; + + if (state->usButtonFlags & RI_MOUSE_BUTTON_4_DOWN) + mouse->btn_b4 = true; + else if (state->usButtonFlags & RI_MOUSE_BUTTON_4_UP) + mouse->btn_b4 = false; + + if (state->usButtonFlags & RI_MOUSE_BUTTON_5_DOWN) + mouse->btn_b5 = true; + else if (state->usButtonFlags & RI_MOUSE_BUTTON_5_UP) + mouse->btn_b5 = false; + + if (state->usButtonFlags & RI_MOUSE_WHEEL) + { + if ((SHORT)state->usButtonData > 0) + InterlockedExchange(&mouse->whl_u, 1); + else if ((SHORT)state->usButtonData < 0) + InterlockedExchange(&mouse->whl_d, 1); + } +} + +static LRESULT CALLBACK winraw_callback(HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar) +{ + static uint8_t data[1024]; + UINT r; + unsigned i; + RAWINPUT *ri = (RAWINPUT*)data; + UINT size = sizeof(data); + + if (msg != WM_INPUT) + return DefWindowProcA(wnd, msg, wpar, lpar); + + /* app is in the background */ if (GET_RAWINPUT_CODE_WPARAM(wpar) != RIM_INPUT) - goto end; - - r = GetRawInputData((HRAWINPUT)lpar, RID_INPUT, - data, &size, sizeof(RAWINPUTHEADER)); - if (r == (UINT)-1) - { - RARCH_WARN("[WINRAW]: GetRawInputData failed with error %lu.\n", - GetLastError()); - goto end; - } - - if (ri->header.dwType == RIM_TYPEKEYBOARD) - { - if (ri->data.keyboard.Message == WM_KEYDOWN) - g_keyboard->keys[ri->data.keyboard.VKey] = 1; - else if (ri->data.keyboard.Message == WM_KEYUP) - g_keyboard->keys[ri->data.keyboard.VKey] = 0; - } - else if (ri->header.dwType == RIM_TYPEMOUSE) - { - for (i = 0; i < g_mouse_cnt; ++i) - { - if (g_mice[i].hnd == ri->header.hDevice) - { - winraw_update_mouse_state(&g_mice[i], &ri->data.mouse); - break; - } - } - } - -end: - DefWindowProcA(wnd, msg, wpar, lpar); - return 0; -} - -static void *winraw_init(const char *joypad_driver) -{ - bool r; - winraw_input_t *wr = (winraw_input_t *) - calloc(1, sizeof(winraw_input_t)); - g_keyboard = (winraw_keyboard_t*) - calloc(1, sizeof(winraw_keyboard_t)); - - if (!wr || !g_keyboard) - goto error; - - RARCH_LOG("[WINRAW]: Initializing input driver... \n"); - - input_keymaps_init_keyboard_lut(rarch_key_map_winraw); - - wr->window = winraw_create_window(winraw_callback); - if (!wr->window) - goto error; - - r = winraw_init_devices(&g_mice, &g_mouse_cnt); - if (!r) - goto error; - - if (!g_mouse_cnt) - { - RARCH_LOG("[WINRAW]: Mouse unavailable.\n"); - } - else - { - wr->mice = (winraw_mouse_t*) - malloc(g_mouse_cnt * sizeof(winraw_mouse_t)); - if (!wr->mice) - goto error; - - memcpy(wr->mice, g_mice, g_mouse_cnt * sizeof(winraw_mouse_t)); - } - - r = winraw_set_keyboard_input(wr->window); - if (!r) - goto error; - - r = winraw_set_mouse_input(wr->window, false); - if (!r) - goto error; - - wr->joypad = input_joypad_init_driver(joypad_driver, wr); - - return wr; - -error: - if (wr && wr->window) - { - winraw_set_mouse_input(NULL, false); - winraw_set_keyboard_input(NULL); - winraw_destroy_window(wr->window); - } - free(g_keyboard); - free(g_mice); - if (wr) - free(wr->mice); - free(wr); - return NULL; -} - -static void winraw_poll(void *d) -{ - unsigned i; - winraw_input_t *wr = (winraw_input_t*)d; - - memcpy(&wr->keyboard, g_keyboard, sizeof(winraw_keyboard_t)); - - /* following keys are not handled by windows raw input api */ - wr->keyboard.keys[VK_LCONTROL] = GetAsyncKeyState(VK_LCONTROL) >> 1 ? 1 : 0; - wr->keyboard.keys[VK_RCONTROL] = GetAsyncKeyState(VK_RCONTROL) >> 1 ? 1 : 0; - wr->keyboard.keys[VK_LMENU] = GetAsyncKeyState(VK_LMENU) >> 1 ? 1 : 0; - wr->keyboard.keys[VK_RMENU] = GetAsyncKeyState(VK_RMENU) >> 1 ? 1 : 0; - wr->keyboard.keys[VK_LSHIFT] = GetAsyncKeyState(VK_LSHIFT) >> 1 ? 1 : 0; - wr->keyboard.keys[VK_RSHIFT] = GetAsyncKeyState(VK_RSHIFT) >> 1 ? 1 : 0; - - for (i = 0; i < g_mouse_cnt; ++i) - { - wr->mice[i].x = g_mice[i].x; - wr->mice[i].y = g_mice[i].y; - wr->mice[i].dlt_x = InterlockedExchange(&g_mice[i].dlt_x, 0); - wr->mice[i].dlt_y = InterlockedExchange(&g_mice[i].dlt_y, 0); - wr->mice[i].whl_u = InterlockedExchange(&g_mice[i].whl_u, 0); - wr->mice[i].whl_d = InterlockedExchange(&g_mice[i].whl_d, 0); - wr->mice[i].btn_l = g_mice[i].btn_l; - wr->mice[i].btn_m = g_mice[i].btn_m; - wr->mice[i].btn_r = g_mice[i].btn_r; - wr->mice[i].btn_b4 = g_mice[i].btn_b4; - wr->mice[i].btn_b5 = g_mice[i].btn_b5; - } - - if (wr->joypad) - wr->joypad->poll(); -} - -static int16_t winraw_input_state(void *d, - rarch_joypad_info_t joypad_info, - const struct retro_keybind **binds, - unsigned port, unsigned device, unsigned index, unsigned id) -{ - winraw_input_t *wr = (winraw_input_t*)d; - - switch (device) - { - case RETRO_DEVICE_KEYBOARD: - if (id < RETROK_LAST) - { - unsigned key = rarch_keysym_lut[(enum retro_key)id]; - return wr->keyboard.keys[key]; - } - break; - case RETRO_DEVICE_MOUSE: - return winraw_mouse_state(wr, port, false, id); - case RARCH_DEVICE_MOUSE_SCREEN: - return winraw_mouse_state(wr, port, true, id); - case RETRO_DEVICE_JOYPAD: - return winraw_joypad_state(wr, joypad_info, binds[port], port, id); - case RETRO_DEVICE_ANALOG: - if (binds[port]) - return input_joypad_analog(wr->joypad, joypad_info, - port, index, id, binds[port]); - break; - case RETRO_DEVICE_LIGHTGUN: - return winraw_lightgun_state(wr, port, id); - } - - return 0; -} - -static bool winraw_meta_key_pressed(void *u1, int u2) -{ - return false; -} - -static void winraw_free(void *d) -{ - winraw_input_t *wr = (winraw_input_t*)d; - - if (wr->joypad) - wr->joypad->destroy(); - winraw_set_mouse_input(NULL, false); - winraw_set_keyboard_input(NULL); - winraw_destroy_window(wr->window); - free(g_mice); - free(g_keyboard); - free(wr->mice); - free(wr); - - g_mouse_xy_mapping_ready = false; -} - -static uint64_t winraw_get_capabilities(void *u) -{ - return (1 << RETRO_DEVICE_KEYBOARD) | - (1 << RETRO_DEVICE_MOUSE) | - (1 << RETRO_DEVICE_JOYPAD) | - (1 << RETRO_DEVICE_ANALOG) | - (1 << RETRO_DEVICE_LIGHTGUN); -} - -static void winraw_grab_mouse(void *d, bool grab) -{ - bool r = false; - winraw_input_t *wr = (winraw_input_t*)d; - - if (grab == wr->mouse_grab) - return; - - r = winraw_set_mouse_input(wr->window, grab); - if (!r) - return; - - wr->mouse_grab = grab; -} - -static bool winraw_set_rumble(void *d, unsigned port, - enum retro_rumble_effect effect, uint16_t strength) -{ - winraw_input_t *wr = (winraw_input_t*)d; - - return input_joypad_set_rumble(wr->joypad, port, effect, strength); -} - -static const input_device_driver_t *winraw_get_joypad_driver(void *d) -{ - winraw_input_t *wr = (winraw_input_t*)d; - - return wr->joypad; -} - -static bool winraw_keyboard_mapping_is_blocked(void *d) -{ - winraw_input_t *wr = (winraw_input_t*)d; - - return wr->kbd_mapp_block; -} - -static void winraw_keyboard_mapping_set_block(void *d, bool block) -{ - winraw_input_t *wr = (winraw_input_t*)d; - - wr->kbd_mapp_block = block; -} - -input_driver_t input_winraw = { - winraw_init, - winraw_poll, - winraw_input_state, - winraw_meta_key_pressed, - winraw_free, - NULL, - NULL, - winraw_get_capabilities, - "raw", - winraw_grab_mouse, - NULL, - winraw_set_rumble, - winraw_get_joypad_driver, - NULL, - winraw_keyboard_mapping_is_blocked, - winraw_keyboard_mapping_set_block, -}; + goto end; + + r = GetRawInputData((HRAWINPUT)lpar, RID_INPUT, + data, &size, sizeof(RAWINPUTHEADER)); + if (r == (UINT)-1) + { + RARCH_WARN("[WINRAW]: GetRawInputData failed with error %lu.\n", + GetLastError()); + goto end; + } + + if (ri->header.dwType == RIM_TYPEKEYBOARD) + { + if (ri->data.keyboard.Message == WM_KEYDOWN) + g_keyboard->keys[ri->data.keyboard.VKey] = 1; + else if (ri->data.keyboard.Message == WM_KEYUP) + g_keyboard->keys[ri->data.keyboard.VKey] = 0; + } + else if (ri->header.dwType == RIM_TYPEMOUSE) + { + for (i = 0; i < g_mouse_cnt; ++i) + { + if (g_mice[i].hnd == ri->header.hDevice) + { + winraw_update_mouse_state(&g_mice[i], &ri->data.mouse); + break; + } + } + } + +end: + DefWindowProcA(wnd, msg, wpar, lpar); + return 0; +} + +static void *winraw_init(const char *joypad_driver) +{ + bool r; + winraw_input_t *wr = (winraw_input_t *) + calloc(1, sizeof(winraw_input_t)); + g_keyboard = (winraw_keyboard_t*) + calloc(1, sizeof(winraw_keyboard_t)); + + if (!wr || !g_keyboard) + goto error; + + RARCH_LOG("[WINRAW]: Initializing input driver... \n"); + + input_keymaps_init_keyboard_lut(rarch_key_map_winraw); + + wr->window = winraw_create_window(winraw_callback); + if (!wr->window) + goto error; + + r = winraw_init_devices(&g_mice, &g_mouse_cnt); + if (!r) + goto error; + + if (!g_mouse_cnt) + { + RARCH_LOG("[WINRAW]: Mouse unavailable.\n"); + } + else + { + wr->mice = (winraw_mouse_t*) + malloc(g_mouse_cnt * sizeof(winraw_mouse_t)); + if (!wr->mice) + goto error; + + memcpy(wr->mice, g_mice, g_mouse_cnt * sizeof(winraw_mouse_t)); + } + + r = winraw_set_keyboard_input(wr->window); + if (!r) + goto error; + + r = winraw_set_mouse_input(wr->window, false); + if (!r) + goto error; + + wr->joypad = input_joypad_init_driver(joypad_driver, wr); + + return wr; + +error: + if (wr && wr->window) + { + winraw_set_mouse_input(NULL, false); + winraw_set_keyboard_input(NULL); + winraw_destroy_window(wr->window); + } + free(g_keyboard); + free(g_mice); + if (wr) + free(wr->mice); + free(wr); + return NULL; +} + +static void winraw_poll(void *d) +{ + unsigned i; + winraw_input_t *wr = (winraw_input_t*)d; + + memcpy(&wr->keyboard, g_keyboard, sizeof(winraw_keyboard_t)); + + /* following keys are not handled by windows raw input api */ + wr->keyboard.keys[VK_LCONTROL] = GetAsyncKeyState(VK_LCONTROL) >> 1 ? 1 : 0; + wr->keyboard.keys[VK_RCONTROL] = GetAsyncKeyState(VK_RCONTROL) >> 1 ? 1 : 0; + wr->keyboard.keys[VK_LMENU] = GetAsyncKeyState(VK_LMENU) >> 1 ? 1 : 0; + wr->keyboard.keys[VK_RMENU] = GetAsyncKeyState(VK_RMENU) >> 1 ? 1 : 0; + wr->keyboard.keys[VK_LSHIFT] = GetAsyncKeyState(VK_LSHIFT) >> 1 ? 1 : 0; + wr->keyboard.keys[VK_RSHIFT] = GetAsyncKeyState(VK_RSHIFT) >> 1 ? 1 : 0; + + for (i = 0; i < g_mouse_cnt; ++i) + { + wr->mice[i].x = g_mice[i].x; + wr->mice[i].y = g_mice[i].y; + wr->mice[i].dlt_x = InterlockedExchange(&g_mice[i].dlt_x, 0); + wr->mice[i].dlt_y = InterlockedExchange(&g_mice[i].dlt_y, 0); + wr->mice[i].whl_u = InterlockedExchange(&g_mice[i].whl_u, 0); + wr->mice[i].whl_d = InterlockedExchange(&g_mice[i].whl_d, 0); + wr->mice[i].btn_l = g_mice[i].btn_l; + wr->mice[i].btn_m = g_mice[i].btn_m; + wr->mice[i].btn_r = g_mice[i].btn_r; + wr->mice[i].btn_b4 = g_mice[i].btn_b4; + wr->mice[i].btn_b5 = g_mice[i].btn_b5; + } + + if (wr->joypad) + wr->joypad->poll(); +} + +static int16_t winraw_input_state(void *d, + rarch_joypad_info_t joypad_info, + const struct retro_keybind **binds, + unsigned port, unsigned device, unsigned index, unsigned id) +{ + winraw_input_t *wr = (winraw_input_t*)d; + + switch (device) + { + case RETRO_DEVICE_JOYPAD: + if (id < RARCH_BIND_LIST_END) + return winraw_is_pressed(wr, joypad_info, binds[port], port, id); + break; + case RETRO_DEVICE_KEYBOARD: + return (id < RETROK_LAST) && winraw_keyboard_pressed(wr, id); + case RETRO_DEVICE_MOUSE: + return winraw_mouse_state(wr, port, false, id); + case RARCH_DEVICE_MOUSE_SCREEN: + return winraw_mouse_state(wr, port, true, id); + case RETRO_DEVICE_ANALOG: + if (binds[port]) + return input_joypad_analog(wr->joypad, joypad_info, + port, index, id, binds[port]); + break; + case RETRO_DEVICE_LIGHTGUN: + switch ( id ) + { + /*aiming*/ + case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X: + case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y: + case RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN: + return winraw_lightgun_aiming_state( wr, port, id ); + + /*buttons*/ + case RETRO_DEVICE_ID_LIGHTGUN_TRIGGER: + return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_TRIGGER); + case RETRO_DEVICE_ID_LIGHTGUN_RELOAD: + return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_RELOAD); + case RETRO_DEVICE_ID_LIGHTGUN_AUX_A: + return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_AUX_A); + case RETRO_DEVICE_ID_LIGHTGUN_AUX_B: + return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_AUX_B); + case RETRO_DEVICE_ID_LIGHTGUN_AUX_C: + return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_AUX_C); + case RETRO_DEVICE_ID_LIGHTGUN_START: + return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_START); + case RETRO_DEVICE_ID_LIGHTGUN_SELECT: + return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_SELECT); + case RETRO_DEVICE_ID_LIGHTGUN_DPAD_UP: + return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_DPAD_UP); + case RETRO_DEVICE_ID_LIGHTGUN_DPAD_DOWN: + return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_DPAD_DOWN); + case RETRO_DEVICE_ID_LIGHTGUN_DPAD_LEFT: + return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_DPAD_LEFT); + case RETRO_DEVICE_ID_LIGHTGUN_DPAD_RIGHT: + return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_DPAD_RIGHT); + + /*deprecated*/ + case RETRO_DEVICE_ID_LIGHTGUN_X: + case RETRO_DEVICE_ID_LIGHTGUN_Y: + return winraw_deprecated_lightgun_state(wr, port, id); + case RETRO_DEVICE_ID_LIGHTGUN_PAUSE: + return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_START); + } + break; + } + + return 0; +} + +static bool winraw_meta_key_pressed(void *u1, int u2) +{ + return false; +} + +static void winraw_free(void *d) +{ + winraw_input_t *wr = (winraw_input_t*)d; + + if (wr->joypad) + wr->joypad->destroy(); + winraw_set_mouse_input(NULL, false); + winraw_set_keyboard_input(NULL); + winraw_destroy_window(wr->window); + free(g_mice); + free(g_keyboard); + free(wr->mice); + free(wr); + + g_mouse_xy_mapping_ready = false; +} + +static uint64_t winraw_get_capabilities(void *u) +{ + return (1 << RETRO_DEVICE_KEYBOARD) | + (1 << RETRO_DEVICE_MOUSE) | + (1 << RETRO_DEVICE_JOYPAD) | + (1 << RETRO_DEVICE_ANALOG) | + (1 << RETRO_DEVICE_LIGHTGUN); +} + +static void winraw_grab_mouse(void *d, bool grab) +{ + bool r = false; + winraw_input_t *wr = (winraw_input_t*)d; + + if (grab == wr->mouse_grab) + return; + + r = winraw_set_mouse_input(wr->window, grab); + if (!r) + return; + + wr->mouse_grab = grab; +} + +static bool winraw_set_rumble(void *d, unsigned port, + enum retro_rumble_effect effect, uint16_t strength) +{ + winraw_input_t *wr = (winraw_input_t*)d; + + return input_joypad_set_rumble(wr->joypad, port, effect, strength); +} + +static const input_device_driver_t *winraw_get_joypad_driver(void *d) +{ + winraw_input_t *wr = (winraw_input_t*)d; + + return wr->joypad; +} + +static bool winraw_keyboard_mapping_is_blocked(void *d) +{ + winraw_input_t *wr = (winraw_input_t*)d; + + return wr->kbd_mapp_block; +} + +static void winraw_keyboard_mapping_set_block(void *d, bool block) +{ + winraw_input_t *wr = (winraw_input_t*)d; + + wr->kbd_mapp_block = block; +} + +input_driver_t input_winraw = { + winraw_init, + winraw_poll, + winraw_input_state, + winraw_meta_key_pressed, + winraw_free, + NULL, + NULL, + winraw_get_capabilities, + "raw", + winraw_grab_mouse, + NULL, + winraw_set_rumble, + winraw_get_joypad_driver, + NULL, + winraw_keyboard_mapping_is_blocked, + winraw_keyboard_mapping_set_block, +}; diff --git a/input/drivers_hid/btstack_hid.c b/input/drivers_hid/btstack_hid.c index 02e4d0d5fb..83eec68c61 100644 --- a/input/drivers_hid/btstack_hid.c +++ b/input/drivers_hid/btstack_hid.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2013-2014 - Jason Fetters * Copyright (C) 2011-2017 - Daniel De Matteis - * + * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. @@ -44,13 +44,13 @@ #define LINK_KEY_LEN 16 /* The device name type. */ #define DEVICE_NAME_LEN 248 - + /* Type definitions. */ typedef uint16_t hci_con_handle_t; typedef uint8_t bd_addr_t[BD_ADDR_LEN]; typedef uint8_t link_key_t[LINK_KEY_LEN]; typedef uint8_t device_name_t[DEVICE_NAME_LEN+1]; - + /* Packet handler. */ typedef void (*btstack_packet_handler_t) (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); @@ -62,7 +62,7 @@ typedef enum HCI_POWER_ON, HCI_POWER_SLEEP } HCI_POWER_MODE; - + /* State of BTstack */ typedef enum { @@ -73,14 +73,14 @@ typedef enum HCI_STATE_SLEEPING, HCI_STATE_FALLING_ASLEEP } HCI_STATE; - + typedef enum { RUN_LOOP_POSIX = 1, RUN_LOOP_COCOA, RUN_LOOP_EMBEDDED } RUN_LOOP_TYPE; - + /* compact HCI Command packet description */ typedef struct { @@ -93,7 +93,7 @@ typedef struct linked_item struct linked_item *next; /* <-- next element in list, or NULL */ void *user_data; /* <-- pointer to struct base */ } linked_item_t; - + typedef linked_item_t *linked_list_t; typedef struct data_source @@ -108,7 +108,7 @@ typedef struct data_source typedef struct timer { - linked_item_t item; + linked_item_t item; /* Next timeout. */ struct timeval timeout; #ifdef HAVE_TICK @@ -167,7 +167,7 @@ BTDIMPORT const hci_cmd_t* l2cap_decline_connection_ptr; /* extension for client/server communication */ #define DAEMON_EVENT_PACKET 0x05 - + /* L2CAP data */ #define L2CAP_DATA_PACKET 0x06 @@ -179,7 +179,7 @@ BTDIMPORT const hci_cmd_t* l2cap_decline_connection_ptr; /* Security Manager protocol data */ #define SM_DATA_PACKET 0x09 - + /* debug log messages */ #define LOG_MESSAGE_PACKET 0xFC @@ -228,7 +228,7 @@ BTDIMPORT const hci_cmd_t* l2cap_decline_connection_ptr; #define HCI_SUBEVENT_LE_CONNECTION_UPDATE_COMPLETE 0x03 #define HCI_SUBEVENT_LE_READ_REMOTE_USED_FEATURES_COMPLETE 0x04 #define HCI_SUBEVENT_LE_LONG_TERM_KEY_REQUEST 0x05 - + /* last used HCI_EVENT in 2.1 is 0x3d */ /* events 0x50-0x5f are used internally */ @@ -257,7 +257,7 @@ BTDIMPORT const hci_cmd_t* l2cap_decline_connection_ptr; #define BTSTACK_EVENT_DISCOVERABLE_ENABLED 0x66 /* L2CAP EVENTS */ - + /* data: event (8), len(8), status (8), address(48), handle (16), psm (16), local_cid(16), remote_cid (16), local_mtu(16), remote_mtu(16) */ #define L2CAP_EVENT_CHANNEL_OPENED 0x70 @@ -277,31 +277,31 @@ BTDIMPORT const hci_cmd_t* l2cap_decline_connection_ptr; #define L2CAP_EVENT_SERVICE_REGISTERED 0x75 /* RFCOMM EVENTS */ - + // data: event(8), len(8), status (8), address (48), handle (16), server channel(8), rfcomm_cid(16), max frame size(16) #define RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE 0x80 - + // data: event(8), len(8), rfcomm_cid(16) #define RFCOMM_EVENT_CHANNEL_CLOSED 0x81 - + // data: event (8), len(8), address(48), channel (8), rfcomm_cid (16) #define RFCOMM_EVENT_INCOMING_CONNECTION 0x82 - + // data: event (8), len(8), rfcommid (16), ... #define RFCOMM_EVENT_REMOTE_LINE_STATUS 0x83 - + /* data: event(8), len(8), rfcomm_cid(16), credits(8) */ #define RFCOMM_EVENT_CREDITS 0x84 - + /* data: event(8), len(8), status (8), rfcomm server channel id (8) */ #define RFCOMM_EVENT_SERVICE_REGISTERED 0x85 - + /* data: event(8), len(8), status (8), rfcomm server channel id (8) */ #define RFCOMM_EVENT_PERSISTENT_CHANNEL 0x86 - + /* data: event(8), len(8), status(8), service_record_handle(32) */ #define SDP_SERVICE_REGISTERED 0x90 - + /* last error code in 2.1 is 0x38 - we start with 0x50 for BTstack errors */ #define BTSTACK_CONNECTION_TO_BTDAEMON_FAILED 0x50 @@ -329,14 +329,14 @@ BTDIMPORT const hci_cmd_t* l2cap_decline_connection_ptr; #define L2CAP_CONFIG_RESPONSE_RESULT_REJECTED 0x68 #define L2CAP_CONFIG_RESPONSE_RESULT_UNKNOWN_OPTIONS 0x69 #define L2CAP_SERVICE_ALREADY_REGISTERED 0x6a - + #define RFCOMM_MULTIPLEXER_STOPPED 0x70 #define RFCOMM_CHANNEL_ALREADY_REGISTERED 0x71 #define RFCOMM_NO_OUTGOING_CREDITS 0x72 #define SDP_HANDLE_ALREADY_REGISTERED 0x80 - -/* Default INQ Mode + +/* Default INQ Mode * 0x9E8B33: General/Unlimited Inquiry Access Code (GIAC) **/ #define HCI_INQUIRY_LAP 0x9E8B33L @@ -350,7 +350,7 @@ extern const hci_cmd_t btstack_get_system_bluetooth_enabled; extern const hci_cmd_t btstack_set_system_bluetooth_enabled; extern const hci_cmd_t btstack_set_discoverable; extern const hci_cmd_t btstack_set_bluetooth_enabled; /* only used by btstack config */ - + extern const hci_cmd_t hci_accept_connection_request; extern const hci_cmd_t hci_authentication_requested; extern const hci_cmd_t hci_change_connection_link_key; @@ -425,7 +425,7 @@ extern const hci_cmd_t hci_le_set_scan_response_data; extern const hci_cmd_t hci_le_start_encryption; extern const hci_cmd_t hci_le_test_end; extern const hci_cmd_t hci_le_transmitter_test; - + extern const hci_cmd_t l2cap_accept_connection; extern const hci_cmd_t l2cap_create_channel; extern const hci_cmd_t l2cap_create_channel_mtu; @@ -487,12 +487,12 @@ void run_loop_set_timer_handler(timer_source_t *ts, void (*process)(timer_source_t *_ts)); /* Add timer source. */ -void run_loop_add_timer(timer_source_t *timer); +void run_loop_add_timer(timer_source_t *timer); /* Remove timer source. */ int run_loop_remove_timer(timer_source_t *timer); -/* Init must be called before any other run_loop call. +/* Init must be called before any other run_loop call. * Use RUN_LOOP_EMBEDDED for embedded devices. */ void run_loop_init(RUN_LOOP_TYPE type); @@ -507,7 +507,7 @@ void run_loop_add_data_source(data_source_t *dataSource); /* Remove data source. */ int run_loop_remove_data_source(data_source_t *dataSource); -/* Execute configured run loop. +/* Execute configured run loop. * This function does not return. */ void run_loop_execute(void); @@ -525,7 +525,7 @@ uint32_t embedded_get_ticks(void); /* Connection handle type. */ - + /* helper for BT little endian format. */ #define READ_BT_16( buffer, pos) ( ((uint16_t) buffer[pos]) | (((uint16_t)buffer[pos+1]) << 8)) #define READ_BT_24( buffer, pos) ( ((uint32_t) buffer[pos]) | (((uint32_t)buffer[pos+1]) << 8) | (((uint32_t)buffer[pos+2]) << 16)) @@ -573,18 +573,18 @@ void hexdump(void *data, int size); void printUUID(uint8_t *uuid); /* Deprecated - please use more convenient bd_addr_to_str. */ -void print_bd_addr( bd_addr_t addr); +void print_bd_addr(bd_addr_t addr); char * bd_addr_to_str(bd_addr_t addr); int sscan_bd_addr(uint8_t * addr_string, bd_addr_t addr); - + uint8_t crc8_check(uint8_t *data, uint16_t len, uint8_t check_sum); uint8_t crc8_calc(uint8_t *data, uint16_t len); /* btstack.h */ - + /* Default TCP port for BTstack daemon. */ #define BTSTACK_PORT 13333 @@ -594,13 +594,13 @@ uint8_t crc8_calc(uint8_t *data, uint16_t len); /* Optional * - * If called before bt_open, TCP socket is used + * If called before bt_open, TCP socket is used * instead of local UNIX socket. * - * note: Address is not copied and must be + * note: Address is not copied and must be * valid during bt_open. */ -void bt_use_tcp(const char * address, uint16_t port); +void bt_use_tcp(const char * address, uint16_t port); /* Init BTstack library. */ int bt_open(void); @@ -611,7 +611,7 @@ int bt_close(void); /* Send HCI cmd packet. */ int bt_send_cmd(const hci_cmd_t *cmd, ...); -/* Register packet handler -- channel only valid +/* Register packet handler -- channel only valid for L2CAP and RFCOMM packets. */ btstack_packet_handler_t bt_register_packet_handler( @@ -783,7 +783,7 @@ static void btpad_queue_process_cmd(struct btpad_queue_command *cmd) { if (!cmd) return; - + if (cmd->command == btstack_set_power_mode_ptr) bt_send_cmd_ptr( cmd->command, @@ -808,7 +808,7 @@ static void btpad_queue_process_cmd(struct btpad_queue_command *cmd) cmd->hci_remote_name_request.page_scan_repetition_mode, cmd->hci_remote_name_request.reserved, cmd->hci_remote_name_request.clock_offset); - + else if (cmd->command == hci_pin_code_request_reply_ptr) bt_send_cmd_ptr( cmd->command, @@ -889,7 +889,7 @@ static void btpad_queue_hci_remote_name_request( cmd->command = hci_remote_name_request_ptr; memcpy(cmd->hci_remote_name_request.bd_addr, bd_addr, sizeof(bd_addr_t)); - cmd->hci_remote_name_request.page_scan_repetition_mode = + cmd->hci_remote_name_request.page_scan_repetition_mode = page_scan_repetition_mode; cmd->hci_remote_name_request.reserved = reserved; cmd->hci_remote_name_request.clock_offset = clock_offset; @@ -1024,7 +1024,7 @@ static void btpad_packet_handler(uint8_t packet_type, if (!connection || connection->state != BTPAD_CONNECTED) continue; - if ( connection->channels[0] == channel + if ( connection->channels[0] == channel || connection->channels[1] == channel) pad_connection_packet(&slots[connection->slot], connection->slot, packet, size); } @@ -1036,14 +1036,14 @@ static void btpad_packet_handler(uint8_t packet_type, RARCH_LOG("[BTstack]: HCI State %d.\n", packet[2]); switch (packet[2]) - { + { case HCI_STATE_WORKING: btpad_queue_reset(); btpad_queue_hci_read_bd_addr(cmd); /* TODO: Where did I get 672 for MTU? */ - bt_send_cmd_ptr(l2cap_register_service_ptr, PSM_HID_CONTROL, 672); + bt_send_cmd_ptr(l2cap_register_service_ptr, PSM_HID_CONTROL, 672); bt_send_cmd_ptr(l2cap_register_service_ptr, PSM_HID_INTERRUPT, 672); btpad_queue_hci_inquiry(cmd, HCI_INQUIRY_LAP, 3, 1); @@ -1052,7 +1052,7 @@ static void btpad_packet_handler(uint8_t packet_type, case HCI_STATE_HALTING: btpad_close_all_connections(); - break; + break; } break; @@ -1100,7 +1100,7 @@ static void btpad_packet_handler(uint8_t packet_type, break; case HCI_EVENT_INQUIRY_COMPLETE: - /* This must be turned off during gameplay + /* This must be turned off during gameplay * as it causes a ton of lag. */ inquiry_running = !inquiry_off; @@ -1363,26 +1363,29 @@ static const char *btstack_hid_joypad_name(void *data, unsigned pad) return NULL; } -static uint64_t btstack_hid_joypad_get_buttons(void *data, unsigned port) +static void btstack_hid_joypad_get_buttons(void *data, unsigned port, retro_bits_t *state) { - btstack_hid_t *hid = (btstack_hid_t*)data; - if (hid) - return pad_connection_get_buttons(&hid->slots[port], port); - return 0; + btstack_hid_t *hid = (btstack_hid_t*)data; + if (hid) + pad_connection_get_buttons(&hid->slots[port], port, state); + else + RARCH_INPUT_STATE_CLEAR_PTR(state); } static bool btstack_hid_joypad_button(void *data, unsigned port, uint16_t joykey) { - uint64_t buttons = btstack_hid_joypad_get_buttons(data, port); + retro_bits_t buttons; + btstack_hid_joypad_get_buttons(data, port, &buttons); - /* Check hat. */ - if (GET_HAT_DIR(joykey)) - return false; + /* Check hat. */ + if (GET_HAT_DIR(joykey)) + return false; - /* Check the button. */ - if ((port < MAX_USERS) && (joykey < 32)) - return ((buttons & (1 << joykey)) != 0); - return false; + /* Check the button. */ + if ((port < MAX_USERS) && (joykey < 32)) + return (RARCH_INPUT_STATE_BIT_GET(buttons, joykey) != 0); + + return false; } static bool btstack_hid_joypad_rumble(void *data, unsigned pad, diff --git a/input/drivers_hid/iohidmanager_hid.c b/input/drivers_hid/iohidmanager_hid.c index e63f3cf7ad..aac33afd56 100644 --- a/input/drivers_hid/iohidmanager_hid.c +++ b/input/drivers_hid/iohidmanager_hid.c @@ -108,21 +108,23 @@ static const char *iohidmanager_hid_joypad_name(void *data, unsigned pad) return NULL; } -static uint64_t iohidmanager_hid_joypad_get_buttons(void *data, unsigned port) +static void iohidmanager_hid_joypad_get_buttons(void *data, unsigned port, retro_bits_t *state) { - iohidmanager_hid_t *hid = (iohidmanager_hid_t*)data; - if (hid) - return pad_connection_get_buttons(&hid->slots[port], port); - return 0; + iohidmanager_hid_t *hid = (iohidmanager_hid_t*)data; + if (hid) + return pad_connection_get_buttons(&hid->slots[port], port, state); + else + RARCH_INPUT_STATE_CLEAR_PTR(state); } static bool iohidmanager_hid_joypad_button(void *data, unsigned port, uint16_t joykey) { - uint64_t buttons = - iohidmanager_hid_joypad_get_buttons(data, port); - iohidmanager_hid_t *hid = (iohidmanager_hid_t*)data; - unsigned hat_dir = GET_HAT_DIR(joykey); + retro_bits_t buttons; + iohidmanager_hid_t *hid = (iohidmanager_hid_t*)data; + unsigned hat_dir = GET_HAT_DIR(joykey); + + iohidmanager_hid_joypad_get_buttons(data, port, &buttons); /* Check hat. */ if (hat_dir) @@ -148,8 +150,9 @@ static bool iohidmanager_hid_joypad_button(void *data, /* Check the button. */ if ((port < MAX_USERS) && (joykey < 32)) - return ((buttons & (1 << joykey)) != 0) + return (RARCH_INPUT_STATE_BIT_GET(buttons, joykey) != 0) || ((hid->buttons[port] & (1 << joykey)) != 0); + return false; } diff --git a/input/drivers_hid/libusb_hid.c b/input/drivers_hid/libusb_hid.c index 357504e46b..4165762b16 100644 --- a/input/drivers_hid/libusb_hid.c +++ b/input/drivers_hid/libusb_hid.c @@ -16,7 +16,11 @@ #include #include +#ifdef __FreeBSD__ +#include +#else #include +#endif #include #include @@ -38,7 +42,11 @@ typedef struct libusb_hid libusb_context *ctx; joypad_connection_t *slots; sthread_t *poll_thread; +#if defined(__FreeBSD__) && LIBUSB_API_VERSION <= 0x01000102 + libusb_hotplug_callback_handle hp; +#else int hp; /* libusb_hotplug_callback_handle is just int */ +#endif int quit; } libusb_hid_t; @@ -157,7 +165,13 @@ static void libusb_get_description(struct libusb_device *device, unsigned i, k; struct libusb_config_descriptor *config; - libusb_get_config_descriptor(device, 0, &config); + int desc_ret = libusb_get_config_descriptor(device, 0, &config); + + if (desc_ret != 0) + { + RARCH_ERR("Error %d getting libusb config descriptor\n", desc_ret); + return; + } for (i = 0; i < (int)config->bNumInterfaces; i++) { @@ -200,11 +214,12 @@ static void libusb_get_description(struct libusb_device *device, } } } + goto ret; } } - ret: +ret: libusb_free_config_descriptor(config); } @@ -299,7 +314,8 @@ static int add_adapter(void *data, struct libusb_device *dev) if (!pad_connection_has_interface(hid->slots, adapter->slot)) { - RARCH_ERR(" Interface not found (%s).\n", adapter->name); + RARCH_ERR("Interface not found (%s) (VID/PID: %04x:%04x).\n", + adapter->name, desc.idVendor, desc.idProduct); goto error; } @@ -426,18 +442,20 @@ static const char *libusb_hid_joypad_name(void *data, unsigned pad) return NULL; } -static uint64_t libusb_hid_joypad_get_buttons(void *data, unsigned port) +static void libusb_hid_joypad_get_buttons(void *data, unsigned port, retro_bits_t *state) { libusb_hid_t *hid = (libusb_hid_t*)data; if (hid) - return pad_connection_get_buttons(&hid->slots[port], port); - return 0; + return pad_connection_get_buttons(&hid->slots[port], port, state); + else + RARCH_INPUT_STATE_CLEAR_PTR(state); } static bool libusb_hid_joypad_button(void *data, unsigned port, uint16_t joykey) { - uint64_t buttons = libusb_hid_joypad_get_buttons(data, port); + retro_bits_t buttons; + libusb_hid_joypad_get_buttons(data, port, &buttons); /* Check hat. */ if (GET_HAT_DIR(joykey)) @@ -445,7 +463,7 @@ static bool libusb_hid_joypad_button(void *data, /* Check the button. */ if ((port < MAX_USERS) && (joykey < 32)) - return ((buttons & (1 << joykey)) != 0); + return (RARCH_INPUT_STATE_BIT_GET(buttons, joykey) != 0); return false; } @@ -502,7 +520,8 @@ static void libusb_hid_free(void *data) sthread_join(hid->poll_thread); } - pad_connection_destroy(hid->slots); + if (hid->slots) + pad_connection_destroy(hid->slots); libusb_hotplug_deregister_callback(hid->ctx, hid->hp); @@ -537,8 +556,14 @@ static void *libusb_hid_init(void) if (ret < 0) goto error; +#if 0 + /* Don't use this for now since it requires a newer API + * version than FreeBSD has, and always returns false on Windows anyway. + * https://github.com/libusb/libusb/issues/86 + */ if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) goto error; +#endif hid->slots = pad_connection_init(MAX_USERS); diff --git a/input/drivers_hid/null_hid.c b/input/drivers_hid/null_hid.c index 10be0ba7c8..34f8bdb7d6 100644 --- a/input/drivers_hid/null_hid.c +++ b/input/drivers_hid/null_hid.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2013-2014 - Jason Fetters * Copyright (C) 2011-2017 - Daniel De Matteis - * + * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. @@ -38,12 +38,12 @@ static const char *null_hid_joypad_name(void *data, unsigned pad) return NULL; } -static uint64_t null_hid_joypad_get_buttons(void *data, unsigned port) +static void null_hid_joypad_get_buttons(void *data, unsigned port, retro_bits_t *state) { (void)data; (void)port; - return 0; + RARCH_INPUT_STATE_CLEAR_PTR(state); } static bool null_hid_joypad_button(void *data, unsigned port, uint16_t joykey) diff --git a/input/drivers_hid/wiiusb_hid.c b/input/drivers_hid/wiiusb_hid.c index 8c022a12b8..3f0fdb282c 100644 --- a/input/drivers_hid/wiiusb_hid.c +++ b/input/drivers_hid/wiiusb_hid.c @@ -64,7 +64,7 @@ struct wiiusb_adapter int32_t slot; uint8_t *data; - uint8_t send_control_type; + uint8_t send_control_type; uint8_t *send_control_buffer; uint32_t send_control_size; }; @@ -113,10 +113,10 @@ static int32_t wiiusb_hid_read_cb(int32_t size, void *data) pad_connection_packet(&hid->connections[adapter->slot], adapter->slot, adapter->data-1, size+1); - if (adapter) + if (adapter) adapter->busy = false; - return size; + return size; } static void wiiusb_hid_device_send_control(void *data, @@ -398,7 +398,7 @@ static void wiiusb_hid_scan_for_devices(wiiusb_hid_t *hid) for (i = 0; i < count; i++) { - /* first check the device is not already in our list */ + /* first check the device is not already in our list */ if (!wiiusb_hid_new_device(hid, dev_entries[i].device_id)) continue; @@ -461,11 +461,11 @@ static int wiiusb_hid_change_cb(int result, void *usrdata) return -1; /* As it's not coming from the removal callback - then we detected a new device being inserted */ - if (!hid->removal_cb) - hid->device_detected = true; - else - hid->removal_cb = false; + then we detected a new device being inserted */ + if (!hid->removal_cb) + hid->device_detected = true; + else + hid->removal_cb = false; /* Re-submit the change alert */ USB_DeviceChangeNotifyAsync(USB_CLASS_HID, wiiusb_hid_change_cb, usrdata); @@ -478,33 +478,36 @@ static bool wiiusb_hid_joypad_query(void *data, unsigned pad) return pad < MAX_USERS; } -static uint64_t wiiusb_hid_joypad_get_buttons(void *data, unsigned port) +static void wiiusb_hid_joypad_get_buttons(void *data, unsigned port, retro_bits_t *state) { - wiiusb_hid_t *hid = (wiiusb_hid_t*)data; - if (hid) - return pad_connection_get_buttons(&hid->connections[port], port); - return 0; + wiiusb_hid_t *hid = (wiiusb_hid_t*)data; + if (hid) + return pad_connection_get_buttons(&hid->connections[port], port, state); + else + RARCH_INPUT_STATE_CLEAR_PTR(state); } static bool wiiusb_hid_joypad_button(void *data, unsigned port, uint16_t joykey) { - uint64_t buttons = wiiusb_hid_joypad_get_buttons(data, port); + retro_bits_t buttons; - /* Check hat. */ - if (GET_HAT_DIR(joykey)) - return false; + wiiusb_hid_joypad_get_buttons(data, port, &buttons); - /* Check the button. */ - if ((port < MAX_USERS) && (joykey < 32)) - return ((buttons & (1 << joykey)) != 0); + /* Check hat. */ + if (GET_HAT_DIR(joykey)) + return false; - return false; + /* Check the button. */ + if ((port < MAX_USERS) && (joykey < 32)) + return (RARCH_INPUT_STATE_BIT_GET(buttons, joykey) != 0); + + return false; } static bool wiiusb_hid_joypad_rumble(void *data, unsigned pad, enum retro_rumble_effect effect, uint16_t strength) { - wiiusb_hid_t *hid = (wiiusb_hid_t*)data; + wiiusb_hid_t *hid = (wiiusb_hid_t*)data; if (!hid) return false; diff --git a/input/drivers_joypad/ctr_joypad.c b/input/drivers_joypad/ctr_joypad.c index aa1b3efcbe..a31a7511fe 100644 --- a/input/drivers_joypad/ctr_joypad.c +++ b/input/drivers_joypad/ctr_joypad.c @@ -31,7 +31,7 @@ #define MAX_PADS 1 #endif -static uint64_t pad_state; +static uint32_t pad_state; static int16_t analog_state[1][2][2]; extern uint64_t lifecycle_state; @@ -67,12 +67,16 @@ static bool ctr_joypad_button(unsigned port_num, uint16_t key) if (port_num >= MAX_PADS) return false; - return (pad_state & (UINT64_C(1) << key)); + return (pad_state & (1 << key)); } -static uint64_t ctr_joypad_get_buttons(unsigned port_num) +static void ctr_joypad_get_buttons(unsigned port_num, retro_bits_t *state) { - return pad_state; + if ( port_num < MAX_PADS ) { + RARCH_INPUT_STATE_COPY16_PTR( state, pad_state ); + } else { + RARCH_INPUT_STATE_CLEAR_PTR(state); + } } static int16_t ctr_joypad_axis(unsigned port_num, uint32_t joyaxis) @@ -140,20 +144,20 @@ static void ctr_joypad_poll(void) hidTouchRead(&state_tmp_touch); pad_state = 0; - pad_state |= (state_tmp & KEY_DLEFT) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT) : 0; - pad_state |= (state_tmp & KEY_DDOWN) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN) : 0; - pad_state |= (state_tmp & KEY_DRIGHT) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_RIGHT) : 0; - pad_state |= (state_tmp & KEY_DUP) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP) : 0; - pad_state |= (state_tmp & KEY_START) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_START) : 0; - pad_state |= (state_tmp & KEY_SELECT) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_SELECT) : 0; - pad_state |= (state_tmp & KEY_X) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_X) : 0; - pad_state |= (state_tmp & KEY_Y) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_Y) : 0; - pad_state |= (state_tmp & KEY_B) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_B) : 0; - pad_state |= (state_tmp & KEY_A) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_A) : 0; - pad_state |= (state_tmp & KEY_R) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R) : 0; - pad_state |= (state_tmp & KEY_L) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L) : 0; - pad_state |= (state_tmp & KEY_ZR) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R2) : 0; - pad_state |= (state_tmp & KEY_ZL) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L2) : 0; + pad_state |= (state_tmp & KEY_DLEFT) ? (1 << RETRO_DEVICE_ID_JOYPAD_LEFT) : 0; + pad_state |= (state_tmp & KEY_DDOWN) ? (1 << RETRO_DEVICE_ID_JOYPAD_DOWN) : 0; + pad_state |= (state_tmp & KEY_DRIGHT) ? (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT) : 0; + pad_state |= (state_tmp & KEY_DUP) ? (1 << RETRO_DEVICE_ID_JOYPAD_UP) : 0; + pad_state |= (state_tmp & KEY_START) ? (1 << RETRO_DEVICE_ID_JOYPAD_START) : 0; + pad_state |= (state_tmp & KEY_SELECT) ? (1 << RETRO_DEVICE_ID_JOYPAD_SELECT) : 0; + pad_state |= (state_tmp & KEY_X) ? (1 << RETRO_DEVICE_ID_JOYPAD_X) : 0; + pad_state |= (state_tmp & KEY_Y) ? (1 << RETRO_DEVICE_ID_JOYPAD_Y) : 0; + pad_state |= (state_tmp & KEY_B) ? (1 << RETRO_DEVICE_ID_JOYPAD_B) : 0; + pad_state |= (state_tmp & KEY_A) ? (1 << RETRO_DEVICE_ID_JOYPAD_A) : 0; + pad_state |= (state_tmp & KEY_R) ? (1 << RETRO_DEVICE_ID_JOYPAD_R) : 0; + pad_state |= (state_tmp & KEY_L) ? (1 << RETRO_DEVICE_ID_JOYPAD_L) : 0; + pad_state |= (state_tmp & KEY_ZR) ? (1 << RETRO_DEVICE_ID_JOYPAD_R2) : 0; + pad_state |= (state_tmp & KEY_ZL) ? (1 << RETRO_DEVICE_ID_JOYPAD_L2) : 0; analog_state[0][RETRO_DEVICE_INDEX_ANALOG_LEFT] [RETRO_DEVICE_ID_ANALOG_X] = ctr_joypad_fix_range(state_tmp_left_analog.dx); analog_state[0][RETRO_DEVICE_INDEX_ANALOG_LEFT] [RETRO_DEVICE_ID_ANALOG_Y] = -ctr_joypad_fix_range(state_tmp_left_analog.dy); diff --git a/input/drivers_joypad/gx_joypad.c b/input/drivers_joypad/gx_joypad.c index 348884e833..318eb637ed 100644 --- a/input/drivers_joypad/gx_joypad.c +++ b/input/drivers_joypad/gx_joypad.c @@ -162,9 +162,13 @@ static bool gx_joypad_button(unsigned port, uint16_t key) return (pad_state[port] & (UINT64_C(1) << key)); } -static uint64_t gx_joypad_get_buttons(unsigned port) +static void gx_joypad_get_buttons(unsigned port, retro_bits_t *state) { - return pad_state[port]; + if ( port < MAX_PADS ) { + RARCH_INPUT_STATE_COPY16_PTR( state, pad_state[port] ); + } else { + RARCH_INPUT_STATE_CLEAR_PTR(state); + } } static int16_t gx_joypad_axis(unsigned port, uint32_t joyaxis) @@ -501,8 +505,8 @@ static void gx_joypad_destroy(void) int i; for (i = 0; i < MAX_PADS; i++) { - /* Commenting this out fixes the Wii - * remote not reconnecting after + /* Commenting this out fixes the Wii + * remote not reconnecting after * core load, exit, etc. */ WPAD_Flush(i); WPADDisconnect(i); diff --git a/input/drivers_joypad/hid_joypad.c b/input/drivers_joypad/hid_joypad.c index 94eaaef7b6..eaed7efbed 100644 --- a/input/drivers_joypad/hid_joypad.c +++ b/input/drivers_joypad/hid_joypad.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2013-2014 - Jason Fetters * Copyright (C) 2011-2017 - Daniel De Matteis - * + * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. @@ -44,7 +44,7 @@ static void hid_joypad_free(void) if (generic_hid->free) generic_hid->free((void*)hid_driver_get_data()); - + generic_hid = NULL; } @@ -55,11 +55,13 @@ static bool hid_joypad_button(unsigned port, uint16_t joykey) return false; } -static uint64_t hid_joypad_get_buttons(unsigned port) +static void hid_joypad_get_buttons(unsigned port, retro_bits_t *state) { - if (generic_hid && generic_hid->get_buttons) - return generic_hid->get_buttons((void*)hid_driver_get_data(), port); - return 0; + if (generic_hid && generic_hid->get_buttons) { + generic_hid->get_buttons((void*)hid_driver_get_data(), port, state); + } else { + RARCH_INPUT_STATE_CLEAR_PTR( state ); + } } static int16_t hid_joypad_axis(unsigned port, uint32_t joyaxis) diff --git a/input/drivers_joypad/linuxraw_joypad.c b/input/drivers_joypad/linuxraw_joypad.c index 4178ffe188..212aeb8adc 100644 --- a/input/drivers_joypad/linuxraw_joypad.c +++ b/input/drivers_joypad/linuxraw_joypad.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis - * + * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. @@ -41,7 +41,7 @@ struct linuxraw_joypad { int fd; - uint64_t buttons; + uint32_t buttons; int16_t axes[NUM_AXES]; char *ident; @@ -55,7 +55,7 @@ static bool linuxraw_hotplug = false; static void linuxraw_poll_pad(struct linuxraw_joypad *pad) { struct js_event event; - + while (read(pad->fd, &event, sizeof(event)) == (ssize_t)sizeof(event)) { unsigned type = event.type & ~JS_EVENT_INIT; @@ -66,9 +66,9 @@ static void linuxraw_poll_pad(struct linuxraw_joypad *pad) if (event.number < NUM_BUTTONS) { if (event.value) - BIT64_SET(pad->buttons, event.number); + BIT32_SET(pad->buttons, event.number); else - BIT64_CLEAR(pad->buttons, event.number); + BIT32_CLEAR(pad->buttons, event.number); } break; @@ -200,7 +200,7 @@ retry: input_config_set_device_name(idx, NULL); } } - /* Sometimes, device will be created before + /* Sometimes, device will be created before * access to it is established. */ else if (event->mask & (IN_CREATE | IN_ATTRIB)) { @@ -210,7 +210,7 @@ retry: snprintf(path, sizeof(path), "/dev/input/%s", event->name); - if ( !string_is_empty(linuxraw_pads[idx].ident) + if ( !string_is_empty(linuxraw_pads[idx].ident) && linuxraw_joypad_init_pad(path, &linuxraw_pads[idx])) { if (!input_autoconfigure_connect( @@ -251,7 +251,7 @@ static bool linuxraw_joypad_init(void *data) pad->fd = -1; pad->ident = input_device_names[i]; - + snprintf(path, sizeof(path), "/dev/input/js%u", i); if (!input_autoconfigure_connect( @@ -323,15 +323,17 @@ static bool linuxraw_joypad_button(unsigned port, uint16_t joykey) const struct linuxraw_joypad *pad = (const struct linuxraw_joypad*) &linuxraw_pads[port]; - return joykey < NUM_BUTTONS && BIT64_GET(pad->buttons, joykey); + return joykey < NUM_BUTTONS && BIT32_GET(pad->buttons, joykey); } -static uint64_t linuxraw_joypad_get_buttons(unsigned port) +static void linuxraw_joypad_get_buttons(unsigned port, retro_bits_t *state) { - const struct linuxraw_joypad *pad = (const struct linuxraw_joypad*) - &linuxraw_pads[port]; - - return pad->buttons; + const struct linuxraw_joypad *pad = (const struct linuxraw_joypad*)&linuxraw_pads[port]; + if ( pad ) { + RARCH_INPUT_STATE_COPY16_PTR(state, pad->buttons); + } else { + RARCH_INPUT_STATE_CLEAR_PTR(state); + } } static int16_t linuxraw_joypad_axis(unsigned port, uint32_t joyaxis) diff --git a/input/drivers_joypad/mfi_joypad.m b/input/drivers_joypad/mfi_joypad.m index ef6f025746..10964893f0 100644 --- a/input/drivers_joypad/mfi_joypad.m +++ b/input/drivers_joypad/mfi_joypad.m @@ -221,9 +221,9 @@ static bool apple_gamecontroller_joypad_button(unsigned port, uint16_t joykey) return false; } -static uint64_t apple_gamecontroller_joypad_get_buttons(unsigned port) +static void apple_gamecontroller_joypad_get_buttons(unsigned port, retro_bits_t *state) { - return mfi_buttons[port]; + RARCH_INPUT_STATE_COPY16_PTR(state, mfi_buttons[port]); } static int16_t apple_gamecontroller_joypad_axis(unsigned port, uint32_t joyaxis) diff --git a/input/drivers_joypad/null_joypad.c b/input/drivers_joypad/null_joypad.c index c3377a45d6..d364433e06 100644 --- a/input/drivers_joypad/null_joypad.c +++ b/input/drivers_joypad/null_joypad.c @@ -37,9 +37,9 @@ static bool null_joypad_button(unsigned port_num, uint16_t joykey) return false; } -static uint64_t null_joypad_get_buttons(unsigned port_num) +static void null_joypad_get_buttons(unsigned port_num, retro_bits_t *state) { - return 0; + RARCH_INPUT_STATE_CLEAR_PTR( state ); } static int16_t null_joypad_axis(unsigned port_num, uint32_t joyaxis) diff --git a/input/drivers_joypad/parport_joypad.c b/input/drivers_joypad/parport_joypad.c index c3bc156db3..062e6dd958 100644 --- a/input/drivers_joypad/parport_joypad.c +++ b/input/drivers_joypad/parport_joypad.c @@ -40,7 +40,7 @@ struct parport_joypad { int fd; - uint64_t buttons; + uint32_t buttons; bool button_enable[PARPORT_NUM_BUTTONS]; char saved_data; char saved_control; @@ -97,22 +97,22 @@ static void parport_poll_pad(struct parport_joypad *pad) for (i = 0; i < 8; i++) { if (!(data & UINT8_C(1 << i)) && pad->button_enable[i]) - BIT64_SET(pad->buttons, i); + BIT32_SET(pad->buttons, i); else - BIT64_CLEAR(pad->buttons, i); + BIT32_CLEAR(pad->buttons, i); } for (i = 3; i < 8; i++) { if (!(status & UINT8_C(1 << i)) && pad->button_enable[i + 5]) - BIT64_SET(pad->buttons, i + 5); + BIT32_SET(pad->buttons, i + 5); else - BIT64_CLEAR(pad->buttons, i + 5); + BIT32_CLEAR(pad->buttons, i + 5); } - if (BIT64_GET(pad->buttons, 12) && pad->button_enable[12]) - BIT64_CLEAR(pad->buttons, 12); + if (BIT32_GET(pad->buttons, 12) && pad->button_enable[12]) + BIT32_CLEAR(pad->buttons, 12); else - BIT64_SET(pad->buttons, 12); + BIT32_SET(pad->buttons, 12); } static bool parport_joypad_init_pad(const char *path, struct parport_joypad *pad) @@ -268,7 +268,7 @@ static bool parport_joypad_init(void *data) for (j = 0; j < PARPORT_NUM_BUTTONS; j++) { - if (!(BIT64_GET(pad->buttons, j))) + if (!(BIT32_GET(pad->buttons, j))) { pad->button_enable[j] = true; found_enabled_button = true; @@ -337,13 +337,17 @@ static void parport_joypad_destroy(void) static bool parport_joypad_button(unsigned port, uint16_t joykey) { const struct parport_joypad *pad = (const struct parport_joypad*)&parport_pads[port]; - return joykey < PARPORT_NUM_BUTTONS && BIT64_GET(pad->buttons, joykey); + return joykey < PARPORT_NUM_BUTTONS && BIT32_GET(pad->buttons, joykey); } -static uint64_t parport_joypad_get_buttons(unsigned port) +static void parport_joypad_get_buttons(unsigned port, retro_bits_t *state) { - const struct parport_joypad *pad = (const struct parport_joypad*)&parport_pads[port]; - return pad->buttons; + const struct parport_joypad *pad = (const struct parport_joypad*)&parport_pads[port]; + if ( pad ) { + RARCH_INPUT_STATE_COPY16_PTR(state, pad->buttons); + } else { + RARCH_INPUT_STATE_CLEAR_PTR(state); + } } static int16_t parport_joypad_axis(unsigned port, uint32_t joyaxis) diff --git a/input/drivers_joypad/ps3_joypad.c b/input/drivers_joypad/ps3_joypad.c index 35fc7dadc9..c14277924c 100644 --- a/input/drivers_joypad/ps3_joypad.c +++ b/input/drivers_joypad/ps3_joypad.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis - * + * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. @@ -68,9 +68,13 @@ static bool ps3_joypad_button(unsigned port_num, uint16_t joykey) return pad_state[port_num] & (UINT64_C(1) << joykey); } -static uint64_t ps3_joypad_get_buttons(unsigned port_num) +static void ps3_joypad_get_buttons(unsigned port_num, retro_bits_t *state) { - return pad_state[port_num]; + if ( port_num < MAX_PADS ) { + RARCH_INPUT_STATE_COPY16_PTR( state, pad_state[port_num] ); + } else { + RARCH_INPUT_STATE_CLEAR_PTR(state); + } } static int16_t ps3_joypad_axis(unsigned port_num, uint32_t joyaxis) @@ -142,7 +146,7 @@ static void ps3_joypad_poll(void) ps3_joypad_autodetect_add(port); } } - + if (pads_connected[port] == 0) continue; diff --git a/input/drivers_joypad/psp_joypad.c b/input/drivers_joypad/psp_joypad.c index 9e569eeca2..967e9092e8 100644 --- a/input/drivers_joypad/psp_joypad.c +++ b/input/drivers_joypad/psp_joypad.c @@ -124,9 +124,13 @@ static bool psp_joypad_button(unsigned port_num, uint16_t key) return (pad_state[port_num] & (UINT64_C(1) << key)); } -static uint64_t psp_joypad_get_buttons(unsigned port_num) +static void psp_joypad_get_buttons(unsigned port_num, retro_bits_t *state) { - return pad_state[port_num]; + if ( port_num < PSP_MAX_PADS ) { + RARCH_INPUT_STATE_COPY16_PTR( state, pad_state[port_num] ); + } else { + RARCH_INPUT_STATE_CLEAR_PTR(state); + } } static int16_t psp_joypad_axis(unsigned port_num, uint32_t joyaxis) @@ -236,10 +240,10 @@ static void psp_joypad_poll(void) if (curr_ctrl_info.port[p] == SCE_CTRL_TYPE_UNPAIRED) continue; #elif defined(SN_TARGET_PSP2) - /* Dumb hack, but here's the explanation - + /* Dumb hack, but here's the explanation - * sceCtrlPeekBufferPositive's port parameter * can be 0 or 1 to read the first controller on - * a PSTV, but HAS to be 0 for a real VITA and 2 + * a PSTV, but HAS to be 0 for a real VITA and 2 * for the 2nd controller on a PSTV */ unsigned p = (player > 0) ? player+1 : player; #else @@ -256,12 +260,12 @@ static void psp_joypad_poll(void) continue; #endif #if defined(VITA) - if (psp2_model == SCE_KERNEL_MODEL_VITA + if (psp2_model == SCE_KERNEL_MODEL_VITA && settings->bools.input_backtouch_enable) { unsigned i; SceTouchData touch_surface = {0}; - sceTouchPeek(settings->bools.input_backtouch_toggle + sceTouchPeek(settings->bools.input_backtouch_toggle ? SCE_TOUCH_PORT_FRONT : SCE_TOUCH_PORT_BACK, &touch_surface, 1); for (i = 0; i < touch_surface.reportNum; i++) diff --git a/input/drivers_joypad/udev_joypad.c b/input/drivers_joypad/udev_joypad.c index ce3ad8617d..3aa6ba092a 100644 --- a/input/drivers_joypad/udev_joypad.c +++ b/input/drivers_joypad/udev_joypad.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2015 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis - * + * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. @@ -204,7 +204,7 @@ static int udev_add_pad(struct udev_device *dev, unsigned p, int fd, const char i = ABS_HAT3Y; continue; } - + if (test_bit(i, absbit)) { struct input_absinfo *abs = &pad->absinfo[axes]; @@ -420,11 +420,11 @@ static bool udev_set_rumble(unsigned i, static bool udev_joypad_poll_hotplug_available(struct udev_monitor *dev) { - struct pollfd fds; + struct pollfd fds; - fds.fd = udev_monitor_get_fd(dev); - fds.events = POLLIN; - fds.revents = 0; + fds.fd = udev_monitor_get_fd(dev); + fds.events = POLLIN; + fds.revents = 0; return (poll(&fds, 1, 0) == 1) && (fds.revents & POLLIN); } @@ -604,10 +604,14 @@ static bool udev_joypad_button(unsigned port, uint16_t joykey) return joykey < UDEV_NUM_BUTTONS && BIT64_GET(pad->buttons, joykey); } -static uint64_t udev_joypad_get_buttons(unsigned port) +static void udev_joypad_get_buttons(unsigned port, retro_bits_t *state) { - const struct udev_joypad *pad = (const struct udev_joypad*)&udev_pads[port]; - return pad->buttons; + const struct udev_joypad *pad = (const struct udev_joypad*)&udev_pads[port]; + if ( pad ) { + RARCH_INPUT_STATE_COPY16_PTR( state, pad->buttons ); + } else { + RARCH_INPUT_STATE_CLEAR_PTR(state); + } } static int16_t udev_joypad_axis(unsigned port, uint32_t joyaxis) diff --git a/input/drivers_joypad/wiiu_joypad.c b/input/drivers_joypad/wiiu_joypad.c index 8fac55d0ae..957e736241 100644 --- a/input/drivers_joypad/wiiu_joypad.c +++ b/input/drivers_joypad/wiiu_joypad.c @@ -122,9 +122,13 @@ static bool wiiu_joypad_button(unsigned port_num, uint16_t key) return (pad_state[port_num] & (UINT64_C(1) << key)); } -static uint64_t wiiu_joypad_get_buttons(unsigned port_num) +static void wiiu_joypad_get_buttons(unsigned port_num, retro_bits_t *state) { - return pad_state[port_num]; + if ( port_num < MAX_PADS ) { + RARCH_INPUT_STATE_COPY16_PTR( state, pad_state[port_num] ); + } else { + RARCH_INPUT_STATE_CLEAR_PTR(state); + } } static int16_t wiiu_joypad_axis(unsigned port_num, uint32_t joyaxis) diff --git a/input/drivers_joypad/xdk_joypad.c b/input/drivers_joypad/xdk_joypad.c index 6bdb3d25b3..b9e25268b4 100644 --- a/input/drivers_joypad/xdk_joypad.c +++ b/input/drivers_joypad/xdk_joypad.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis - * + * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. @@ -19,7 +19,7 @@ #include "../input_driver.h" #include "../../tasks/tasks_internal.h" -static uint64_t pad_state[MAX_PADS]; +static uint32_t pad_state[MAX_PADS]; static int16_t analog_state[MAX_PADS][2][2]; #ifdef _XBOX1 static HANDLE gamepads[MAX_PADS]; @@ -73,12 +73,16 @@ static bool xdk_joypad_button(unsigned port_num, uint16_t joykey) if (port_num >= MAX_PADS) return false; - return pad_state[port_num] & (UINT64_C(1) << joykey); + return pad_state[port_num] & (1 << joykey); } -static uint64_t xdk_joypad_get_buttons(unsigned port_num) +static void xdk_joypad_get_buttons(unsigned port_num, retro_bits_t *state) { - return pad_state[port_num]; + if ( port_num < MAX_PADS ) { + RARCH_INPUT_STATE_COPY16_PTR( state, pad_state[port_num] ); + } else { + RARCH_INPUT_STATE_CLEAR_PTR(state); + } } static int16_t xdk_joypad_axis(unsigned port_num, uint32_t joyaxis) @@ -154,7 +158,7 @@ static void xdk_joypad_poll(void) if(bRemoved[port]) { - /* if the controller was removed after + /* if the controller was removed after * XGetDeviceChanges but before * XInputOpen, the device handle will be NULL. */ if(gamepads[port]) @@ -178,14 +182,14 @@ static void xdk_joypad_poll(void) m_pollingParameters.bOutputInterval = 8; gamepads[port] = XInputOpen(XDEVICE_TYPE_GAMEPAD, port, XDEVICE_NO_SLOT, NULL); - + xdk_joypad_autodetect_add(port); } if (!gamepads[port]) continue; - /* if the controller is removed after + /* if the controller is removed after * XGetDeviceChanges but before XInputOpen, * the device handle will be NULL. */ #endif diff --git a/input/include/blissbox.h b/input/include/blissbox.h new file mode 100644 index 0000000000..fd515ee218 --- /dev/null +++ b/input/include/blissbox.h @@ -0,0 +1,100 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2016 - Daniel De Matteis + * Copyright (C) 2016-2017 - Brad Parker + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#ifndef __BLISSBOX_H +#define __BLISSBOX_H + +#include + +#define BLISSBOX_VID 0x16d0 /* requires firmware 2.0 */ +#define BLISSBOX_PID 0x0d04 /* first of 4 controllers, each one increments PID by 1 */ +#define BLISSBOX_UPDATE_MODE_PID 0x0a5f +#define BLISSBOX_OLD_PID 0x0a60 +#define BLISSBOX_MAX_PADS 4 +#define BLISSBOX_MAX_PAD_INDEX (BLISSBOX_MAX_PADS - 1) + +#define BLISSBOX_USB_FEATURE_REPORT_ID 17 + +RETRO_BEGIN_DECLS + +typedef struct { + const char *name; + int index; +} blissbox_pad_type_t; + +const blissbox_pad_type_t blissbox_pad_types[] = +{ + {"A5200", 6}, + {"A5200_TB", 50}, + {"A7800", 4}, + {"ATARI_KEYPAD", 43}, + {"ATMARK", 10}, + {"BALLY", 42}, + {"CD32", 24}, + {"CDI", 33}, + {"COL", 1}, + {"DC_ASCI", 15}, + {"DC_PAD", 16}, + {"FC_ARKANOID", 53}, + {"FC_NES", 52}, + {"GC", 9}, + {"GC_WHEEL", 18}, + {"GEN_3", 20}, + {"GEN_6", 21}, + {"GRAVIS_EX", 38}, + {"gx4000", 2}, + {"HAMMERHEAD", 40}, + {"HPD", 7}, + {"INTELI", 14}, + {"JAG", 11}, + {"MSSW", 39}, + {"N64", 19}, + {"NEO", 49}, + {"NES", 17}, + {"PADDLES", 41}, + {"PC_FX", 26}, + {"PC_GAMEPAD", 46}, + {"PSX_DIGITAL", 65}, + {"PSX_DS", 115}, + {"PSX_DS2", 121}, + {"PSX_FS", 83}, + {"PSX_NEGCON", 51}, + {"PSX_WHEEL", 12}, + {"SAC", 34}, + {"SATURN_ANALOG", 8}, + {"SATURN_DIGITAL", 3}, + {"SMS", 22}, + {"SPEEK", 45}, + {"TG16", 23}, + {"THREE_DO", 25}, + {"THREE_DO_ANALOG", 37}, + {"VEC", 5}, + {"WII_NUNCHUK", 13}, + {"ZXSINC", 44}, + {"NES_ARKANOID", 30}, + {"NES_GUN", 28}, + {"NES_POWERPAD", 36}, + {"SNES", 27}, + {"V_BOY", 29}, + {"WII_CLASSIC", 31}, + {"WII_MPLUS", 32}, + {NULL, 0}, /* used to mark unconnected ports, do not remove */ +}; + +RETRO_END_DECLS + +#endif diff --git a/input/input_defines.h b/input/input_defines.h index d9ef13cc37..fa697c54a4 100644 --- a/input/input_defines.h +++ b/input/input_defines.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis - * + * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. @@ -18,6 +18,7 @@ #define __INPUT_DEFINES__H #include +#include #include @@ -157,6 +158,30 @@ enum analog_dpad_mode #define GET_HAT_DIR(x) (x & HAT_MASK) #define GET_HAT(x) (x & (~HAT_MASK)) +#define RARCH_INPUT_STATE_BIT_SET(a,bit) ((a).data [((bit) >> 5)] |= (1 << ((bit) & 31))) +#define RARCH_INPUT_STATE_BIT_SET_PTR(a,bit) ((a)->data[((bit) >> 5)] |= (1 << ((bit) & 31))) +#define RARCH_INPUT_STATE_BIT_GET(a,bit) ((a).data [((bit) >> 5)] & (1 << ((bit) & 31))) +#define RARCH_INPUT_STATE_BIT_GET_PTR(a,bit) ((a)->data[((bit) >> 5)] & (1 << ((bit) & 31))) +#define RARCH_INPUT_STATE_CLEAR(a) memset(&a, 0, sizeof(a)); +#define RARCH_INPUT_STATE_CLEAR_PTR(a) memset(a, 0, sizeof(retro_bits_t)); +#define RARCH_INPUT_STATE_ANY_SET(a) ( ((a).data[0])||((a).data[1])||((a).data[2])||((a).data[3])|| \ + ((a).data[4])||((a).data[5])||((a).data[6])||((a).data[7]) ) +#define RARCH_INPUT_STATE_ANY_SET_PTR(a) ( ((a)->data[0])||((a)->data[1])||((a)->data[2])||((a)->data[3])|| \ + ((a)->data[4])||((a)->data[5])||((a)->data[6])||((a)->data[7]) ) +#define RARCH_INPUT_STATE_CLEAR_BITS(a,b) \ + ((a).data[0])&=(~((b).data[0])); \ + ((a).data[1])&=(~((b).data[1])); \ + ((a).data[2])&=(~((b).data[2])); \ + ((a).data[3])&=(~((b).data[3])); \ + ((a).data[4])&=(~((b).data[4])); \ + ((a).data[5])&=(~((b).data[5])); \ + ((a).data[6])&=(~((b).data[6])); \ + ((a).data[7])&=(~((b).data[7])); + +#define RARCH_INPUT_STATE_COPY16_PTR(a,bits) {memset(a, 0, sizeof(retro_bits_t));((a)->data[0] = (bits)&0xffff);} +#define RARCH_INPUT_STATE_COPY32_PTR(a,bits) {memset(a, 0, sizeof(retro_bits_t));((a)->data[0] = (bits));} + + RETRO_END_DECLS #endif diff --git a/input/input_driver.c b/input/input_driver.c index eabb1bd733..abfba95a91 100644 --- a/input/input_driver.c +++ b/input/input_driver.c @@ -480,9 +480,9 @@ const input_device_driver_t *input_driver_get_joypad_driver(void) const input_device_driver_t *input_driver_get_sec_joypad_driver(void) { - if (!current_input || !current_input->get_sec_joypad_driver) - return NULL; - return current_input->get_sec_joypad_driver(current_input_data); + if (!current_input || !current_input->get_sec_joypad_driver) + return NULL; + return current_input->get_sec_joypad_driver(current_input_data); } uint64_t input_driver_get_capabilities(void) @@ -499,7 +499,7 @@ void input_driver_set(const input_driver_t **input, void **input_data) *input = current_input; *input_data = current_input_data; } - + input_driver_set_own_driver(); } @@ -548,7 +548,7 @@ void input_poll(void) size_t i; settings_t *settings = config_get_ptr(); uint8_t max_users = (uint8_t)input_driver_max_users; - + current_input->poll(current_input_data); input_driver_turbo_btns.count++; @@ -804,8 +804,8 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) const struct retro_keybind *binds_auto = NULL; uint8_t max_users = (uint8_t)input_driver_max_users; uint8_t port_max = - settings->bools.input_all_users_control_menu - ? max_users : 1; + settings->bools.input_all_users_control_menu + ? max_users : 1; RARCH_INPUT_STATE_CLEAR_PTR( p_new_state ); @@ -882,7 +882,7 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) ? input_config_binds[port][i].joykey : joypad_info.auto_binds[i].joykey; joyaxis = (input_config_binds[port][i].joyaxis != AXIS_NONE) ? input_config_binds[port][i].joyaxis : joypad_info.auto_binds[i].joyaxis; - + if (sec) { if ((uint16_t)joykey == NO_BTN || !sec->button(joypad_info.joy_idx, (uint16_t)joykey)) @@ -1038,7 +1038,7 @@ void input_keys_pressed(void *data, retro_bits_t* p_new_state) joypad_info.joy_idx = settings->uints.input_joypad_map[0]; joypad_info.auto_binds = input_autoconf_binds[joypad_info.joy_idx]; joypad_info.axis_threshold = input_driver_axis_threshold; - + input_driver_block_libretro_input = false; input_driver_block_hotkey = false; @@ -1052,9 +1052,9 @@ void input_keys_pressed(void *data, retro_bits_t* p_new_state) && current_input->input_state( current_input_data, joypad_info, &binds, 0, RETRO_DEVICE_JOYPAD, 0, RARCH_ENABLE_HOTKEY)) - input_driver_block_libretro_input = true; - else - input_driver_block_hotkey = true; + input_driver_block_libretro_input = true; + else + input_driver_block_hotkey = true; } game_focus_toggle_valid = binds[RARCH_GAME_FOCUS_TOGGLE].valid; @@ -1073,7 +1073,7 @@ void input_keys_pressed(void *data, retro_bits_t* p_new_state) { if ( ((!input_driver_block_libretro_input && ((i < RARCH_FIRST_META_KEY))) - || !input_driver_block_hotkey) && + || !input_driver_block_hotkey) && binds[i].valid && current_input->input_state(current_input_data, joypad_info, &binds, 0, RETRO_DEVICE_JOYPAD, 0, i) @@ -1085,7 +1085,7 @@ void input_keys_pressed(void *data, retro_bits_t* p_new_state) if ((i >= RARCH_FIRST_META_KEY) && current_input->meta_key_pressed(current_input_data, i) - ) + ) { RARCH_INPUT_STATE_BIT_SET_PTR(p_new_state, i); continue; @@ -1317,7 +1317,7 @@ bool input_driver_init_command(void) } input_driver_command = command_new(); - + if (command_network_new( input_driver_command, stdin_cmd_enable && !grab_stdin, @@ -1582,7 +1582,7 @@ bool input_joypad_set_rumble(const input_device_driver_t *drv, if (!input_config_get_bind_idx(port, &joy_idx)) return false; - + if (!drv || !drv->set_rumble) return false; @@ -1613,99 +1613,99 @@ int16_t input_joypad_analog(const input_device_driver_t *drv, unsigned port, unsigned idx, unsigned ident, const struct retro_keybind *binds) { - int16_t res; + int16_t res; - if ( idx == RETRO_DEVICE_INDEX_ANALOG_BUTTON ) - { - /* A RETRO_DEVICE_JOYPAD button? */ - if ( ident < RARCH_FIRST_CUSTOM_BIND ) - { - uint32_t axis = 0; - const struct retro_keybind *bind = NULL; + if ( idx == RETRO_DEVICE_INDEX_ANALOG_BUTTON ) + { + /* A RETRO_DEVICE_JOYPAD button? */ + if ( ident < RARCH_FIRST_CUSTOM_BIND ) + { + uint32_t axis = 0; + const struct retro_keybind *bind = NULL; - bind = &binds[ ident ]; - if (!bind->valid) - return 0; + bind = &binds[ ident ]; + if (!bind->valid) + return 0; - axis = bind->joyaxis; - if ( axis == AXIS_NONE ) - axis = joypad_info.auto_binds[ ident ].joyaxis; + axis = bind->joyaxis; + if ( axis == AXIS_NONE ) + axis = joypad_info.auto_binds[ ident ].joyaxis; - /* Analog button. */ - res = abs( drv->axis( joypad_info.joy_idx, axis ) ); + /* Analog button. */ + res = abs( drv->axis( joypad_info.joy_idx, axis ) ); - /* If the result is zero, it's got a digital button attached to it */ - if ( res == 0 ) - { - uint64_t key = bind->joykey; + /* If the result is zero, it's got a digital button attached to it */ + if ( res == 0 ) + { + uint64_t key = bind->joykey; - if ( key == NO_BTN ) - key = joypad_info.auto_binds[ ident ].joykey; + if ( key == NO_BTN ) + key = joypad_info.auto_binds[ ident ].joykey; - if ( drv->button(joypad_info.joy_idx, (uint16_t)key)) - res = 0x7fff; - } - } - else - { - /* not a suitable button */ - res = 0; - } - } - else - { - /* Analog sticks. Either RETRO_DEVICE_INDEX_ANALOG_LEFT - * or RETRO_DEVICE_INDEX_ANALOG_RIGHT */ + if ( drv->button(joypad_info.joy_idx, (uint16_t)key)) + res = 0x7fff; + } + } + else + { + /* not a suitable button */ + res = 0; + } + } + else + { + /* Analog sticks. Either RETRO_DEVICE_INDEX_ANALOG_LEFT + * or RETRO_DEVICE_INDEX_ANALOG_RIGHT */ - uint32_t axis_minus, axis_plus; - int16_t pressed_minus, pressed_plus; - unsigned ident_minus = 0; - unsigned ident_plus = 0; - const struct retro_keybind *bind_minus = NULL; - const struct retro_keybind *bind_plus = NULL; + uint32_t axis_minus, axis_plus; + int16_t pressed_minus, pressed_plus; + unsigned ident_minus = 0; + unsigned ident_plus = 0; + const struct retro_keybind *bind_minus = NULL; + const struct retro_keybind *bind_plus = NULL; - input_conv_analog_id_to_bind_id(idx, ident, &ident_minus, &ident_plus); + input_conv_analog_id_to_bind_id(idx, ident, &ident_minus, &ident_plus); - bind_minus = &binds[ident_minus]; - bind_plus = &binds[ident_plus]; + bind_minus = &binds[ident_minus]; + bind_plus = &binds[ident_plus]; - if (!bind_minus->valid || !bind_plus->valid) - return 0; + if (!bind_minus->valid || !bind_plus->valid) + return 0; - axis_minus = bind_minus->joyaxis; - axis_plus = bind_plus->joyaxis; + axis_minus = bind_minus->joyaxis; + axis_plus = bind_plus->joyaxis; - if (axis_minus == AXIS_NONE) - axis_minus = joypad_info.auto_binds[ident_minus].joyaxis; - if (axis_plus == AXIS_NONE) - axis_plus = joypad_info.auto_binds[ident_plus].joyaxis; + if (axis_minus == AXIS_NONE) + axis_minus = joypad_info.auto_binds[ident_minus].joyaxis; + if (axis_plus == AXIS_NONE) + axis_plus = joypad_info.auto_binds[ident_plus].joyaxis; - pressed_minus = abs(drv->axis(joypad_info.joy_idx, axis_minus)); - pressed_plus = abs(drv->axis(joypad_info.joy_idx, axis_plus)); - res = pressed_plus - pressed_minus; + pressed_minus = abs(drv->axis(joypad_info.joy_idx, axis_minus)); + pressed_plus = abs(drv->axis(joypad_info.joy_idx, axis_plus)); + res = pressed_plus - pressed_minus; - if (res == 0) - { - int16_t digital_left = 0; - int16_t digital_right = 0; - uint64_t key_minus = bind_minus->joykey; - uint64_t key_plus = bind_plus->joykey; + if (res == 0) + { + int16_t digital_left = 0; + int16_t digital_right = 0; + uint64_t key_minus = bind_minus->joykey; + uint64_t key_plus = bind_plus->joykey; - if (key_minus == NO_BTN) - key_minus = joypad_info.auto_binds[ident_minus].joykey; - if (key_plus == NO_BTN) - key_plus = joypad_info.auto_binds[ident_plus].joykey; + if (key_minus == NO_BTN) + key_minus = joypad_info.auto_binds[ident_minus].joykey; + if (key_plus == NO_BTN) + key_plus = joypad_info.auto_binds[ident_plus].joykey; - if (drv->button(joypad_info.joy_idx, (uint16_t)key_minus)) - digital_left = -0x7fff; - if (drv->button(joypad_info.joy_idx, (uint16_t)key_plus)) - digital_right = 0x7fff; + if (drv->button(joypad_info.joy_idx, (uint16_t)key_minus)) + digital_left = -0x7fff; + if (drv->button(joypad_info.joy_idx, (uint16_t)key_plus)) + digital_right = 0x7fff; - return digital_right + digital_left; - } - } + return digital_right + digital_left; + } + } - return res; + return res; } /** @@ -1770,24 +1770,24 @@ bool input_joypad_hat_raw(const input_device_driver_t *drv, **/ bool input_mouse_button_raw(unsigned port, unsigned id) { - int16_t res; - rarch_joypad_info_t joypad_info; - settings_t *settings = config_get_ptr(); + int16_t res; + rarch_joypad_info_t joypad_info; + settings_t *settings = config_get_ptr(); - /*ignore axes*/ - if ( id == RETRO_DEVICE_ID_MOUSE_X || id == RETRO_DEVICE_ID_MOUSE_Y ) - return false; + /*ignore axes*/ + if ( id == RETRO_DEVICE_ID_MOUSE_X || id == RETRO_DEVICE_ID_MOUSE_Y ) + return false; - joypad_info.axis_threshold = input_driver_axis_threshold; - joypad_info.joy_idx = settings->uints.input_joypad_map[port]; - joypad_info.auto_binds = input_autoconf_binds[joypad_info.joy_idx]; + joypad_info.axis_threshold = input_driver_axis_threshold; + joypad_info.joy_idx = settings->uints.input_joypad_map[port]; + joypad_info.auto_binds = input_autoconf_binds[joypad_info.joy_idx]; - res = current_input->input_state(current_input_data, - joypad_info, libretro_input_binds, port, RETRO_DEVICE_MOUSE, 0, id); + res = current_input->input_state(current_input_data, + joypad_info, libretro_input_binds, port, RETRO_DEVICE_MOUSE, 0, id); - if (res) - return true; - return false; + if (res) + return true; + return false; } /** @@ -2024,8 +2024,8 @@ bool input_keyboard_line_append(const char *word) unsigned i = 0; unsigned len = (unsigned)strlen(word); char *newbuf = (char*) - realloc(g_keyboard_line->buffer, - g_keyboard_line->size + len*2); + realloc(g_keyboard_line->buffer, + g_keyboard_line->size + len*2); if (!newbuf) return false; @@ -2459,26 +2459,26 @@ void input_config_parse_joy_axis(void *data, const char *prefix, void input_config_parse_mouse_button(void *data, const char *prefix, const char *btn, struct retro_keybind *bind) { - int val; - char str[256]; - char tmp[64]; - char key[64]; - config_file_t *conf = (config_file_t*)data; + int val; + char str[256]; + char tmp[64]; + char key[64]; + config_file_t *conf = (config_file_t*)data; - str[0] = tmp[0] = key[0] = '\0'; + str[0] = tmp[0] = key[0] = '\0'; - fill_pathname_join_delim(str, prefix, btn, - '_', sizeof(str)); - fill_pathname_join_delim(key, str, - "mbtn", '_', sizeof(key)); + fill_pathname_join_delim(str, prefix, btn, + '_', sizeof(str)); + fill_pathname_join_delim(key, str, + "mbtn", '_', sizeof(key)); - if ( bind && config_get_array(conf, key, tmp, sizeof(tmp)) ) - { - bind->mbutton = NO_BTN; + if ( bind && config_get_array(conf, key, tmp, sizeof(tmp)) ) + { + bind->mbutton = NO_BTN; - if ( tmp[0]=='w' ) - { - switch ( tmp[1] ) + if ( tmp[0]=='w' ) + { + switch ( tmp[1] ) { case 'u': bind->mbutton = RETRO_DEVICE_ID_MOUSE_WHEELUP; @@ -2498,30 +2498,30 @@ void input_config_parse_mouse_button(void *data, const char *prefix, } break; } - } - else - { - val = atoi(tmp); - switch ( val ) + } + else + { + val = atoi(tmp); + switch ( val ) { - case 1: + case 1: bind->mbutton = RETRO_DEVICE_ID_MOUSE_LEFT; break; - case 2: + case 2: bind->mbutton = RETRO_DEVICE_ID_MOUSE_RIGHT; break; - case 3: + case 3: bind->mbutton = RETRO_DEVICE_ID_MOUSE_MIDDLE; break; - case 4: + case 4: bind->mbutton = RETRO_DEVICE_ID_MOUSE_BUTTON_4; break; - case 5: + case 5: bind->mbutton = RETRO_DEVICE_ID_MOUSE_BUTTON_5; break; - } - } - } + } + } + } } static void input_config_get_bind_string_joykey( @@ -2604,7 +2604,7 @@ static void input_config_get_bind_string_joyaxis(char *buf, const char *prefix, void input_config_get_bind_string(char *buf, const struct retro_keybind *bind, const struct retro_keybind *auto_bind, size_t size) { - int delim = 0; + int delim = 0; #ifndef RARCH_CONSOLE char key[64]; char keybuf[64]; @@ -2623,7 +2623,7 @@ void input_config_get_bind_string(char *buf, const struct retro_keybind *bind, input_config_get_bind_string_joyaxis(buf, "Auto: ", auto_bind, size); if (*buf) - delim = 1; + delim = 1; #ifndef RARCH_CONSOLE input_keymaps_translate_rk_to_str(bind->key, key, sizeof(key)); @@ -2640,10 +2640,10 @@ void input_config_get_bind_string(char *buf, const struct retro_keybind *bind, } #endif - if ( bind->mbutton != NO_BTN ) - { - int tag = 0; - switch ( bind->mbutton ) + if ( bind->mbutton != NO_BTN ) + { + int tag = 0; + switch ( bind->mbutton ) { case RETRO_DEVICE_ID_MOUSE_LEFT: tag = MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_LEFT; @@ -2674,18 +2674,17 @@ void input_config_get_bind_string(char *buf, const struct retro_keybind *bind, break; } /* switch ( bind->mbutton ) */ - if (tag != 0) - { - if (delim) - strlcat(buf, ", ", size); - strlcat(buf, msg_hash_to_str((enum msg_hash_enums)tag), size ); - delim = 1; - } - } + if (tag != 0) + { + if (delim) + strlcat(buf, ", ", size); + strlcat(buf, msg_hash_to_str((enum msg_hash_enums)tag), size ); + } + } /*completely empty?*/ if ( *buf == '\0' ) - strlcat(buf, "---", size); + strlcat(buf, "---", size); } const char *input_config_get_device_name(unsigned port) @@ -2783,7 +2782,7 @@ void input_config_reset(void) for (i = 1; i < MAX_USERS; i++) memcpy(input_config_binds[i], retro_keybinds_rest, sizeof(retro_keybinds_rest)); - + for (i = 0; i < MAX_USERS; i++) { input_config_vid[i] = 0; diff --git a/input/input_driver.h b/input/input_driver.h index c3084979a9..3222237a41 100644 --- a/input/input_driver.h +++ b/input/input_driver.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis - * + * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. @@ -79,7 +79,7 @@ enum rarch_input_keyboard_ctl_state RARCH_INPUT_KEYBOARD_CTL_LINE_FREE, /* - * Waits for keys to be pressed (used for binding + * Waits for keys to be pressed (used for binding * keys in the menu). * Callback returns false when all polling is done. **/ @@ -98,19 +98,19 @@ struct retro_keybind uint16_t mbutton; - /* Joypad key. Joypad POV (hats) + /* Joypad key. Joypad POV (hats) * are embedded into this key as well. */ uint64_t joykey; - /* Default key binding value - + /* Default key binding value - * for resetting bind to default */ uint64_t def_joykey; - /* Joypad axis. Negative and positive axes + /* Joypad axis. Negative and positive axes * are embedded into this variable. */ uint32_t joyaxis; - /* Default joy axis binding value - + /* Default joy axis binding value - * for resetting bind to default */ uint32_t def_joyaxis; @@ -130,7 +130,7 @@ typedef struct rarch_joypad_info typedef struct input_driver { - /* Inits input driver. + /* Inits input driver. */ void *(*init)(const char *joypad_driver); @@ -174,7 +174,7 @@ struct rarch_joypad_driver bool (*query_pad)(unsigned); void (*destroy)(void); bool (*button)(unsigned, uint16_t); - uint64_t (*get_buttons)(unsigned); + void (*get_buttons)(unsigned, retro_bits_t *); int16_t (*axis)(unsigned, uint32_t); void (*poll)(void); bool (*set_rumble)(unsigned, enum retro_rumble_effect, uint16_t); @@ -189,7 +189,7 @@ struct hid_driver bool (*query_pad)(void *, unsigned); void (*free)(void *); bool (*button)(void *, unsigned, uint16_t); - uint64_t (*get_buttons)(void *, unsigned); + void (*get_buttons)(void *, unsigned, retro_bits_t *); int16_t (*axis)(void *, unsigned, uint32_t); void (*poll)(void *); bool (*set_rumble)(void *, unsigned, enum retro_rumble_effect, uint16_t); @@ -336,26 +336,6 @@ void input_poll(void); int16_t input_state(unsigned port, unsigned device, unsigned idx, unsigned id); -#define RARCH_INPUT_STATE_BIT_SET(a,bit) ((a).data [((bit) >> 5)] |= (1 << ((bit) & 31))) -#define RARCH_INPUT_STATE_BIT_SET_PTR(a,bit) ((a)->data[((bit) >> 5)] |= (1 << ((bit) & 31))) -#define RARCH_INPUT_STATE_BIT_GET(a,bit) ((a).data [((bit) >> 5)] & (1 << ((bit) & 31))) -#define RARCH_INPUT_STATE_BIT_GET_PTR(a,bit) ((a)->data[((bit) >> 5)] & (1 << ((bit) & 31))) -#define RARCH_INPUT_STATE_CLEAR(a) memset(&a, 0, sizeof(a)); -#define RARCH_INPUT_STATE_CLEAR_PTR(a) memset(a, 0, sizeof(retro_bits_t)); -#define RARCH_INPUT_STATE_ANY_SET(a) ( ((a).data[0])||((a).data[1])||((a).data[2])||((a).data[3])|| \ - ((a).data[4])||((a).data[5])||((a).data[6])||((a).data[7]) ) -#define RARCH_INPUT_STATE_ANY_SET_PTR(a) ( ((a)->data[0])||((a)->data[1])||((a)->data[2])||((a)->data[3])|| \ - ((a)->data[4])||((a)->data[5])||((a)->data[6])||((a)->data[7]) ) -#define RARCH_INPUT_STATE_CLEAR_BITS(a,b) \ - ((a).data[0])&=(~((b).data[0])); \ - ((a).data[1])&=(~((b).data[1])); \ - ((a).data[2])&=(~((b).data[2])); \ - ((a).data[3])&=(~((b).data[3])); \ - ((a).data[4])&=(~((b).data[4])); \ - ((a).data[5])&=(~((b).data[5])); \ - ((a).data[6])&=(~((b).data[6])); \ - ((a).data[7])&=(~((b).data[7])); - void input_keys_pressed(void *data, retro_bits_t* new_state); #ifdef HAVE_MENU @@ -467,7 +447,7 @@ const char* config_get_joypad_driver_options(void); * * Initialize a joypad driver of name @ident. * - * If ident points to NULL or a zero-length string, + * If ident points to NULL or a zero-length string, * equivalent to calling input_joypad_init_first(). * * Returns: joypad driver if found, otherwise NULL. @@ -486,7 +466,7 @@ const input_device_driver_t *input_joypad_init_first(void *data); /** * input_conv_analog_id_to_bind_id: * @idx : Analog key index. - * E.g.: + * E.g.: * - RETRO_DEVICE_INDEX_ANALOG_LEFT * - RETRO_DEVICE_INDEX_ANALOG_RIGHT * @ident : Analog key identifier. @@ -525,7 +505,7 @@ static INLINE bool input_joypad_pressed( /* Auto-binds are per joypad, not per user. */ uint64_t joykey = (binds[key].joykey != NO_BTN) ? binds[key].joykey : joypad_info.auto_binds[key].joykey; - uint32_t joyaxis = (binds[key].joyaxis != AXIS_NONE) + uint32_t joyaxis = (binds[key].joyaxis != AXIS_NONE) ? binds[key].joyaxis : joypad_info.auto_binds[key].joyaxis; if ((uint16_t)joykey != NO_BTN && drv->button(joypad_info.joy_idx, (uint16_t)joykey)) @@ -540,7 +520,7 @@ static INLINE bool input_joypad_pressed( * @drv : Input device driver handle. * @port : User number. * @idx : Analog key index. - * E.g.: + * E.g.: * - RETRO_DEVICE_INDEX_ANALOG_LEFT * - RETRO_DEVICE_INDEX_ANALOG_RIGHT * - RETRO_DEVICE_INDEX_ANALOG_BUTTON @@ -575,12 +555,12 @@ bool input_joypad_set_rumble(const input_device_driver_t *driver, unsigned port, enum retro_rumble_effect effect, uint16_t strength); /** - * input_joypad_axis_raw: + * input_joypad_axis_raw: * @drv : Input device driver handle. * @port : Joystick number. * @axis : Identifier of axis. * - * Checks if axis (@axis) was being pressed by user + * Checks if axis (@axis) was being pressed by user * with joystick number @port. * * Returns: true (1) if axis was pressed, otherwise @@ -674,7 +654,7 @@ const hid_driver_t *input_hid_init_first(void); const void *hid_driver_get_data(void); #endif -/** Line complete callback. +/** Line complete callback. * Calls back after return is pressed with the completed line. * Line can be NULL. **/ @@ -711,8 +691,8 @@ bool input_keyboard_line_append(const char *word); * * Sets function pointer for keyboard line handle. * - * The underlying buffer can be reallocated at any time - * (or be NULL), but the pointer to it remains constant + * The underlying buffer can be reallocated at any time + * (or be NULL), but the pointer to it remains constant * throughout the objects lifetime. * * Returns: underlying buffer of the keyboard line. @@ -759,7 +739,7 @@ const char *input_config_get_prefix(unsigned user, bool meta); * * Translate string representation to bind ID. * - * Returns: Bind ID value on success, otherwise + * Returns: Bind ID value on success, otherwise * RARCH_BIND_LIST_END on not found. **/ unsigned input_config_translate_str_to_bind_id(const char *str); diff --git a/intl/msg_hash_chs.h b/intl/msg_hash_chs.h index d9d5f633c1..8879be108e 100644 --- a/intl/msg_hash_chs.h +++ b/intl/msg_hash_chs.h @@ -1,4 +1,4 @@ -MSG_HASH( +MSG_HASH( MSG_COMPILER, "编译器" ) @@ -3201,3 +3201,9 @@ MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_OK, "Password correct.") MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_NOK, "Password incorrect.") +MSG_HASH(MENU_ENUM_LABEL_VALUE_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Automatically add content to playlist") +MSG_HASH(MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Automatically scans loaded content so they appear inside playlists.") +MSG_HASH(MSG_SCANNING_OF_FILE_FINISHED, + "Scanning of file finished") diff --git a/intl/msg_hash_cht.h b/intl/msg_hash_cht.h index 3074dc5f32..33c9c5947d 100644 --- a/intl/msg_hash_cht.h +++ b/intl/msg_hash_cht.h @@ -1,4 +1,4 @@ -MSG_HASH( +MSG_HASH( MSG_COMPILER, "編譯器" ) @@ -3201,3 +3201,9 @@ MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_OK, "Password correct.") MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_NOK, "Password incorrect.") +MSG_HASH(MENU_ENUM_LABEL_VALUE_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Automatically add content to playlist") +MSG_HASH(MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Automatically scans loaded content so they appear inside playlists.") +MSG_HASH(MSG_SCANNING_OF_FILE_FINISHED, + "Scanning of file finished") diff --git a/intl/msg_hash_de.h b/intl/msg_hash_de.h index e5bf9687e8..26ac4331ac 100644 --- a/intl/msg_hash_de.h +++ b/intl/msg_hash_de.h @@ -3311,3 +3311,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_COLOR_BLUE, "Blau-Anteil der Bildschirmmeldungen") MSG_HASH(MENU_ENUM_LABEL_VALUE_FRAMECOUNT_SHOW, "Zeige die aktuelle Anzahl an Einzelbildern an") +MSG_HASH(MENU_ENUM_LABEL_VALUE_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Automatically add content to playlist") +MSG_HASH(MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Automatically scans loaded content so they appear inside playlists.") +MSG_HASH(MSG_SCANNING_OF_FILE_FINISHED, + "Scanning of file finished") diff --git a/intl/msg_hash_eo.h b/intl/msg_hash_eo.h index 3f16073e95..d5d1d0258b 100644 --- a/intl/msg_hash_eo.h +++ b/intl/msg_hash_eo.h @@ -3064,3 +3064,9 @@ MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_OK, "Password correct.") MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_NOK, "Password incorrect.") +MSG_HASH(MENU_ENUM_LABEL_VALUE_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Automatically add content to playlist") +MSG_HASH(MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Automatically scans loaded content so they appear inside playlists.") +MSG_HASH(MSG_SCANNING_OF_FILE_FINISHED, + "Scanning of file finished") diff --git a/intl/msg_hash_fr.h b/intl/msg_hash_fr.h index 1920e13ad8..7fe0883274 100644 --- a/intl/msg_hash_fr.h +++ b/intl/msg_hash_fr.h @@ -3233,3 +3233,9 @@ MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_OK, "Password correct.") MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_NOK, "Password incorrect.") +MSG_HASH(MENU_ENUM_LABEL_VALUE_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Automatically add content to playlist") +MSG_HASH(MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Automatically scans loaded content so they appear inside playlists.") +MSG_HASH(MSG_SCANNING_OF_FILE_FINISHED, + "Scanning of file finished") diff --git a/intl/msg_hash_it.h b/intl/msg_hash_it.h index 22232ed4f4..dfa0290a1e 100644 --- a/intl/msg_hash_it.h +++ b/intl/msg_hash_it.h @@ -3291,3 +3291,9 @@ MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_OK, "Password corretta.") MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_NOK, "Password non corretta.") +MSG_HASH(MENU_ENUM_LABEL_VALUE_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Automatically add content to playlist") +MSG_HASH(MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Automatically scans loaded content so they appear inside playlists.") +MSG_HASH(MSG_SCANNING_OF_FILE_FINISHED, + "Scanning of file finished") diff --git a/intl/msg_hash_ja.h b/intl/msg_hash_ja.h index ebae8a65ed..c1087e8ede 100644 --- a/intl/msg_hash_ja.h +++ b/intl/msg_hash_ja.h @@ -1,4 +1,4 @@ -#if defined(_MSC_VER) && !defined(_XBOX) +#if defined(_MSC_VER) && !defined(_XBOX) /* https://support.microsoft.com/en-us/kb/980263 */ #pragma execution_character_set("utf-8") #endif @@ -3243,3 +3243,9 @@ MSG_HASH(MSG_GAME_REMAP_FILE_LOADED, "ゲームの優先ファイルをロードしました。") MSG_HASH(MSG_CORE_REMAP_FILE_LOADED, "コアの優先ファイルをロードしました。") +MSG_HASH(MENU_ENUM_LABEL_VALUE_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Automatically add content to playlist") +MSG_HASH(MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Automatically scans loaded content so they appear inside playlists.") +MSG_HASH(MSG_SCANNING_OF_FILE_FINISHED, + "Scanning of file finished") diff --git a/intl/msg_hash_ko.h b/intl/msg_hash_ko.h index 9a22edd4c8..46c001d5aa 100644 --- a/intl/msg_hash_ko.h +++ b/intl/msg_hash_ko.h @@ -1,4 +1,4 @@ -MSG_HASH( +MSG_HASH( MSG_COMPILER, "컴파일러" ) @@ -3196,3 +3196,9 @@ MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_OK, "Password correct.") MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_NOK, "Password incorrect.") +MSG_HASH(MENU_ENUM_LABEL_VALUE_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Automatically add content to playlist") +MSG_HASH(MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Automatically scans loaded content so they appear inside playlists.") +MSG_HASH(MSG_SCANNING_OF_FILE_FINISHED, + "Scanning of file finished") diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index 32cd47b828..a097ee5c90 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -1375,3 +1375,5 @@ MSG_HASH(MENU_ENUM_LABEL_VIDEO_MESSAGE_COLOR_BLUE, "video_msg_color_blue") MSG_HASH(MENU_ENUM_LABEL_FRAMECOUNT_SHOW, "framecount_show") +MSG_HASH(MENU_ENUM_LABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "automatically_add_content_to_playlist") diff --git a/intl/msg_hash_nl.h b/intl/msg_hash_nl.h index dcd21e2962..f912f35260 100644 --- a/intl/msg_hash_nl.h +++ b/intl/msg_hash_nl.h @@ -3064,3 +3064,9 @@ MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_OK, "Wachtwoord correct.") MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_NOK, "Verkeerde wachtwoord.") +MSG_HASH(MENU_ENUM_LABEL_VALUE_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Automatically add content to playlist") +MSG_HASH(MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Automatically scans loaded content so they appear inside playlists.") +MSG_HASH(MSG_SCANNING_OF_FILE_FINISHED, + "Scanning of file finished") diff --git a/intl/msg_hash_pl.c b/intl/msg_hash_pl.c index a20415a68d..6aceda10d8 100644 --- a/intl/msg_hash_pl.c +++ b/intl/msg_hash_pl.c @@ -1,4 +1,4 @@ -/* RetroArch - A frontend for libretro. +/* RetroArch - A frontend for libretro. * Copyright (C) 2011-2017 - Daniel De Matteis * * RetroArch is free software: you can redistribute it and/or modify it under the terms diff --git a/intl/msg_hash_pt_br.h b/intl/msg_hash_pt_br.h index 2603504428..c2b0ae58f5 100644 --- a/intl/msg_hash_pt_br.h +++ b/intl/msg_hash_pt_br.h @@ -662,27 +662,27 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y_PLUS, "Analógico Direito Y+ (baixo)" ) MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_TRIGGER, - "Gun Trigger") + "Gatinho da Pistola") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_RELOAD, - "Gun Reload") + "Recarregar Pistola") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_A, - "Gun Aux A") + "Aux A da Pistola") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_B, - "Gun Aux B") + "Aux B da Pistola") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_AUX_C, - "Gun Aux C") + "Aux C da Pistola") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_START, - "Gun Start") + "Start da Pistola") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_SELECT, - "Gun Select") + "Select da Pistola") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_UP, - "Gun D-pad Up") + "D-pad Cima da Pistola") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_DOWN, - "Gun D-pad Down") + "D-pad Baixo da Pistola") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_LEFT, - "Gun D-pad Left") + "D-pad Esquerdo da Pistola") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_LIGHTGUN_DPAD_RIGHT, - "Gun D-pad Right") + "D-pad Direito da Pistola") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AUTODETECT_ENABLE, "Habilitar Autoconfiguração" ) @@ -790,13 +790,13 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_BUTTON4, MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_BUTTON5, "Mouse 5") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_WHEEL_UP, - "Wheel Up") + "Roda do Mouse para Cima") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_WHEEL_DOWN, - "Wheel Down") + "Roda do Mouse para Baixo") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_HORIZ_WHEEL_UP, - "Wheel Left") + "Roda do Mouse para Esquerda") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_HORIZ_WHEEL_DOWN, - "Wheel Right") + "Roda do Mouse para Diretira") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_KEYBOARD_GAMEPAD_MAPPING_TYPE, "Tipo de Mapeamento para Gamepad no Teclado" ) @@ -897,10 +897,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SLOWMOTION, "Câmera Lenta" ) MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_MINUS, - "Posição do Estado de Jogo -" + "Compartimento do Estado de Jogo -" ) MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_PLUS, - "Posição do Estado de Jogo +" + "Compartimento do Estado de Jogo +" ) MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_DOWN, "Volume -" @@ -1704,7 +1704,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_START_VIDEO_PROCESSOR, "Iniciar Processador de Vídeo" ) MSG_HASH(MENU_ENUM_LABEL_VALUE_STATE_SLOT, - "Posição do Estado de Jogo" + "Compartimento do Estado de Jogo" ) MSG_HASH(MENU_ENUM_LABEL_VALUE_STATUS, "Condição" @@ -2775,7 +2775,7 @@ MSG_HASH(MSG_FOUND_FIRST_DATA_TRACK_ON_FILE, "Encontrada primeira faixa de dados no arquivo" ) MSG_HASH(MSG_FOUND_LAST_STATE_SLOT, - "Encontrada última posição de Estado de Jogo" + "Encontrada último compartimento de Estado de Jogo" ) MSG_HASH(MSG_FOUND_SHADER, "Shader encontrado" @@ -2844,10 +2844,10 @@ MSG_HASH(MSG_LIBRETRO_FRONTEND, "Frontend para Libretro" ) MSG_HASH(MSG_LOADED_STATE_FROM_SLOT, - "Estado de Jogo carregado da posição #%d." + "Estado de Jogo carregado do compartimento #%d." ) MSG_HASH(MSG_LOADED_STATE_FROM_SLOT_AUTO, - "Estado de Jogo carregado da posição #-1 (automático)." + "Estado de Jogo carregado do compartimento #-1 (automático)." ) MSG_HASH(MSG_LOADING, "Carregando" @@ -2973,10 +2973,10 @@ MSG_HASH(MSG_SAVED_NEW_CONFIG_TO, "Nova configuração salva em" ) MSG_HASH(MSG_SAVED_STATE_TO_SLOT, - "Estado de Jogo salvo na posição #%d." + "Estado de Jogo salvo no compartimento #%d." ) MSG_HASH(MSG_SAVED_STATE_TO_SLOT_AUTO, - "Estado de Jogo salvo na posição #-1 (automático)." + "Estado de Jogo salvo no compartimento #-1 (automático)." ) MSG_HASH(MSG_SAVED_SUCCESSFULLY_TO, "Salvo com sucesso em" @@ -3030,7 +3030,7 @@ MSG_HASH(MSG_STATE_SIZE, "Tamanho do Estado de Jogo" ) MSG_HASH(MSG_STATE_SLOT, - "Posição do Estado de Jogo" + "Compartimento do Estado de Jogo" ) MSG_HASH(MSG_TAKING_SCREENSHOT, "Fazendo captura de tela" @@ -3636,10 +3636,10 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CLOSE_CONTENT, "Fecha o conteúdo atual. Alterações não salvas serão perdidas." ) MSG_HASH(MENU_ENUM_SUBLABEL_LOAD_STATE, - "Carregar um Estado de Jogo da posição selecionado atualmente." + "Carregar um Estado de Jogo do compartimento selecionado atualmente." ) MSG_HASH(MENU_ENUM_SUBLABEL_SAVE_STATE, - "Salvar um Estado de Jogo na posição selecionado atualmente." + "Salvar um Estado de Jogo no compartimento selecionado atualmente." ) MSG_HASH(MENU_ENUM_SUBLABEL_RESUME, "Retomar a execução do conteúdo atual e sair do Menu Rápido." @@ -3648,7 +3648,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_RESUME_CONTENT, "Retomar a execução do conteúdo atual e sair do Menu Rápido." ) MSG_HASH(MENU_ENUM_SUBLABEL_STATE_SLOT, - "Altera a posição do Estado de Jogo selecionado atualmente." + "Altera o compartimento do Estado de Jogo selecionado atualmente." ) MSG_HASH(MENU_ENUM_SUBLABEL_UNDO_LOAD_STATE, "Se um Estado de Jogo for carregado, o conteúdo voltará ao estado anterior ao carregamento." @@ -4181,3 +4181,9 @@ MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_OK, MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_NOK, "Password incorrect." ) +MSG_HASH(MENU_ENUM_LABEL_VALUE_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Automatically add content to playlist") +MSG_HASH(MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Automatically scans loaded content so they appear inside playlists.") +MSG_HASH(MSG_SCANNING_OF_FILE_FINISHED, + "Scanning of file finished") diff --git a/intl/msg_hash_pt_pt.h b/intl/msg_hash_pt_pt.h index 9e6cb8641d..b48e9717cd 100644 --- a/intl/msg_hash_pt_pt.h +++ b/intl/msg_hash_pt_pt.h @@ -3171,3 +3171,9 @@ MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_OK, "Password correct.") MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_NOK, "Password incorrect.") +MSG_HASH(MENU_ENUM_LABEL_VALUE_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Automatically add content to playlist") +MSG_HASH(MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Automatically scans loaded content so they appear inside playlists.") +MSG_HASH(MSG_SCANNING_OF_FILE_FINISHED, + "Scanning of file finished") diff --git a/intl/msg_hash_ru.c b/intl/msg_hash_ru.c index 6bfec695cc..9a48e61b7e 100644 --- a/intl/msg_hash_ru.c +++ b/intl/msg_hash_ru.c @@ -1,4 +1,4 @@ -/* RetroArch - A frontend for libretro. +/* RetroArch - A frontend for libretro. * Copyright (C) 2011-2017 - Daniel De Matteis * * RetroArch is free software: you can redistribute it and/or modify it under the terms diff --git a/intl/msg_hash_ru.h b/intl/msg_hash_ru.h index 84aec3c7ba..4eac6397c2 100644 --- a/intl/msg_hash_ru.h +++ b/intl/msg_hash_ru.h @@ -1,4 +1,4 @@ -#if defined(_MSC_VER) && !defined(_XBOX) +#if defined(_MSC_VER) && !defined(_XBOX) /* https://support.microsoft.com/en-us/kb/980263 */ #pragma execution_character_set("utf-8") #endif @@ -3254,3 +3254,9 @@ MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_OK, "Пароль верен.") MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_NOK, "Пароль неверен.") +MSG_HASH(MENU_ENUM_LABEL_VALUE_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Automatically add content to playlist") +MSG_HASH(MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Automatically scans loaded content so they appear inside playlists.") +MSG_HASH(MSG_SCANNING_OF_FILE_FINISHED, + "Scanning of file finished") diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index f877546905..5fb03ee34b 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -3333,3 +3333,9 @@ MSG_HASH(MSG_GAME_REMAP_FILE_LOADED, "Game remap file loaded.") MSG_HASH(MSG_CORE_REMAP_FILE_LOADED, "Core remap file loaded.") +MSG_HASH(MENU_ENUM_LABEL_VALUE_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Automatically add content to playlist") +MSG_HASH(MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Automatically scans loaded content so they appear inside playlists.") +MSG_HASH(MSG_SCANNING_OF_FILE_FINISHED, + "Scanning of file finished") diff --git a/intl/msg_hash_vn.h b/intl/msg_hash_vn.h index efea88ed20..9c68ac8d89 100644 --- a/intl/msg_hash_vn.h +++ b/intl/msg_hash_vn.h @@ -1,4 +1,4 @@ -MSG_HASH( +MSG_HASH( MSG_COMPILER, "Compiler" ) @@ -3225,3 +3225,9 @@ MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_OK, "Password correct.") MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_NOK, "Password incorrect.") +MSG_HASH(MENU_ENUM_LABEL_VALUE_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Automatically add content to playlist") +MSG_HASH(MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + "Automatically scans loaded content so they appear inside playlists.") +MSG_HASH(MSG_SCANNING_OF_FILE_FINISHED, + "Scanning of file finished") diff --git a/libretro-common/file/config_file.c b/libretro-common/file/config_file.c index 87f72238fb..70f7b64aab 100644 --- a/libretro-common/file/config_file.c +++ b/libretro-common/file/config_file.c @@ -892,7 +892,7 @@ void config_set_uint64(config_file_t *conf, const char *key, uint64_t val) char buf[128]; buf[0] = '\0'; - snprintf(buf, sizeof(buf), STRING_REP_UINT64, val); + snprintf(buf, sizeof(buf), "%" PRIu64, val); config_set_string(conf, key, buf); } diff --git a/libretro-common/file/file_path.c b/libretro-common/file/file_path.c index 1643b0d6cb..62ee9f20e7 100644 --- a/libretro-common/file/file_path.c +++ b/libretro-common/file/file_path.c @@ -219,6 +219,17 @@ int32_t path_get_size(const char *path) return -1; } +static bool path_mkdir_error(int ret) +{ +#if defined(VITA) + return (ret == SCE_ERROR_ERRNO_EEXIST); +#elif defined(PSP) || defined(_3DS) || defined(WIIU) + return (ret == -1); +#else + return (ret < 0 && errno == EEXIST); +#endif +} + /** * path_mkdir: * @dir : directory @@ -230,10 +241,13 @@ int32_t path_get_size(const char *path) bool path_mkdir(const char *dir) { /* Use heap. Real chance of stack overflow if we recurse too hard. */ - char *basedir = strdup(dir); const char *target = NULL; bool sret = false; bool norecurse = false; + char *basedir = NULL; + + if (dir && *dir) + basedir = strdup(dir); if (!basedir) return false; @@ -249,8 +263,8 @@ bool path_mkdir(const char *dir) } else { - target = basedir; - sret = path_mkdir(basedir); + target = basedir; + sret = path_mkdir(basedir); if (sret) { @@ -274,16 +288,9 @@ bool path_mkdir(const char *dir) #endif /* Don't treat this as an error. */ -#if defined(VITA) - if ((ret == SCE_ERROR_ERRNO_EEXIST) && path_is_directory(dir)) + if (path_mkdir_error(ret) && path_is_directory(dir)) ret = 0; -#elif defined(PSP) || defined(_3DS) || defined(WIIU) - if ((ret == -1) && path_is_directory(dir)) - ret = 0; -#else - if (ret < 0 && errno == EEXIST && path_is_directory(dir)) - ret = 0; -#endif + if (ret < 0) printf("mkdir(%s) error: %s.\n", dir, strerror(errno)); sret = (ret == 0); diff --git a/libretro-common/file/nbio/nbio_linux.c b/libretro-common/file/nbio/nbio_linux.c index 7b40551194..3395a2cef7 100644 --- a/libretro-common/file/nbio/nbio_linux.c +++ b/libretro-common/file/nbio/nbio_linux.c @@ -24,7 +24,9 @@ #if defined(__linux__) +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include #include #include diff --git a/libretro-common/file/nbio/nbio_windowsmmap.c b/libretro-common/file/nbio/nbio_windowsmmap.c index 42a22a16d6..caf0d72514 100644 --- a/libretro-common/file/nbio/nbio_windowsmmap.c +++ b/libretro-common/file/nbio/nbio_windowsmmap.c @@ -56,7 +56,11 @@ static void *nbio_mmap_win32_open(const char * filename, unsigned mode) { static const DWORD dispositions[] = { OPEN_EXISTING, CREATE_ALWAYS, OPEN_ALWAYS, OPEN_EXISTING, CREATE_ALWAYS }; HANDLE mem; +#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0500 LARGE_INTEGER len; +#else + SIZE_T len; +#endif struct nbio_mmap_win32_t* handle = NULL; void* ptr = NULL; bool is_write = (mode == NBIO_WRITE || mode == NBIO_UPDATE || mode == BIO_WRITE); @@ -74,17 +78,28 @@ static void *nbio_mmap_win32_open(const char * filename, unsigned mode) if (file == INVALID_HANDLE_VALUE) return NULL; +#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0500 + /* GetFileSizeEx is new for Windows 2000 */ GetFileSizeEx(file, &len); - mem = CreateFileMapping(file, NULL, is_write ? PAGE_READWRITE : PAGE_READONLY, 0, 0, NULL); ptr = MapViewOfFile(mem, is_write ? (FILE_MAP_READ|FILE_MAP_WRITE) : FILE_MAP_READ, 0, 0, len.QuadPart); +#else + GetFileSize(file, &len); + mem = CreateFileMapping(file, NULL, is_write ? PAGE_READWRITE : PAGE_READONLY, 0, 0, NULL); + ptr = MapViewOfFile(mem, is_write ? (FILE_MAP_READ|FILE_MAP_WRITE) : FILE_MAP_READ, 0, 0, len); +#endif + CloseHandle(mem); handle = (struct nbio_mmap_win32_t*)malloc(sizeof(struct nbio_mmap_win32_t)); handle->file = file; handle->is_write = is_write; +#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0500 handle->len = len.QuadPart; +#else + handle->len = len; +#endif handle->ptr = ptr; return handle; @@ -108,7 +123,11 @@ static bool nbio_mmap_win32_iterate(void *data) static void nbio_mmap_win32_resize(void *data, size_t len) { +#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0500 LARGE_INTEGER len_li; +#else + SIZE_T len_li; +#endif HANDLE mem; struct nbio_mmap_win32_t* handle = (struct nbio_mmap_win32_t*)data; @@ -125,8 +144,14 @@ static void nbio_mmap_win32_resize(void *data, size_t len) abort(); } +#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0500 + /* SetFilePointerEx is new for Windows 2000 */ len_li.QuadPart = len; SetFilePointerEx(handle->file, len_li, NULL, FILE_BEGIN); +#else + len_li = len; + SetFilePointer(handle->file, len_li, NULL, FILE_BEGIN); +#endif if (!SetEndOfFile(handle->file)) { diff --git a/libretro-common/include/retro_common_api.h b/libretro-common/include/retro_common_api.h index 659f90d76e..ef0860bbad 100644 --- a/libretro-common/include/retro_common_api.h +++ b/libretro-common/include/retro_common_api.h @@ -75,19 +75,18 @@ typedef int ssize_t; #include #endif -#ifdef _WIN32 -#define STRING_REP_INT64 "%I64d" -#define STRING_REP_UINT64 "%I64u" -#define STRING_REP_USIZE "%Iu" -#elif defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L && !defined(VITA) && !defined(WIIU) -#define STRING_REP_INT64 "%lld" -#define STRING_REP_UINT64 "%llu" -#define STRING_REP_USIZE "%zu" -#else -#define STRING_REP_INT64 "%lld" -#define STRING_REP_UINT64 "%llu" -#define STRING_REP_USIZE "%lu" +#ifdef _MSC_VER +#ifndef PRId64 +#define PRId64 "I64d" +#define PRIu64 "I64u" +#define PRIuPTR "Iu" #endif +#else +#include +#endif +#define STRING_REP_INT64 "%" PRId64 +#define STRING_REP_UINT64 "%" PRIu64 +#define STRING_REP_USIZE "%" PRIuPTR /* I would like to see retro_inline.h moved in here; possibly boolean too. diff --git a/libretro-common/streams/file_stream.c b/libretro-common/streams/file_stream.c index 9f6ad73437..c4dcddf0a7 100644 --- a/libretro-common/streams/file_stream.c +++ b/libretro-common/streams/file_stream.c @@ -169,8 +169,9 @@ void filestream_set_size(RFILE *stream) * If bufsize is > 0 for unbuffered modes (like RFILE_MODE_WRITE), file will instead be fully buffered. * Returns a pointer to an RFILE if opened successfully, otherwise NULL. **/ -RFILE *filestream_open(const char *path, unsigned mode, ssize_t bufsize) +RFILE *filestream_open(const char *path, unsigned mode, ssize_t unused) { + ssize_t bufsize = 0x4000; int flags = 0; int mode_int = 0; #if defined(HAVE_BUFFERED_IO) diff --git a/libretro-db/query.c b/libretro-db/query.c index 339a62d192..9509de2ad0 100644 --- a/libretro-db/query.c +++ b/libretro-db/query.c @@ -289,7 +289,7 @@ struct registered_func registered_functions[100] = { static void query_raise_expected_number(ssize_t where, const char **error) { snprintf(tmp_error_buff, MAX_ERROR_LEN, - STRING_REP_UINT64 "::Expected number", + "%" PRIu64 "::Expected number", (uint64_t)where); *error = tmp_error_buff; } @@ -297,7 +297,7 @@ static void query_raise_expected_number(ssize_t where, const char **error) static void query_raise_expected_string(ssize_t where, const char ** error) { snprintf(tmp_error_buff, MAX_ERROR_LEN, - STRING_REP_UINT64 "::Expected string", + "%" PRIu64 "::Expected string", (uint64_t)where); *error = tmp_error_buff; } @@ -305,7 +305,7 @@ static void query_raise_expected_string(ssize_t where, const char ** error) static void query_raise_unexpected_eof(ssize_t where, const char ** error) { snprintf(tmp_error_buff, MAX_ERROR_LEN, - STRING_REP_UINT64 "::Unexpected EOF", + "%" PRIu64 "::Unexpected EOF", (uint64_t)where ); *error = tmp_error_buff; @@ -321,7 +321,7 @@ static void query_raise_unknown_function(ssize_t where, const char *name, ssize_t len, const char **error) { int n = snprintf(tmp_error_buff, MAX_ERROR_LEN, - STRING_REP_UINT64 "::Unknown function '", + "%" PRIu64 "::Unknown function '", (uint64_t)where ); @@ -336,7 +336,7 @@ static void query_raise_expected_eof( ssize_t where, char found, const char **error) { snprintf(tmp_error_buff, MAX_ERROR_LEN, - STRING_REP_UINT64 "::Expected EOF found '%c'", + "%" PRIu64 "::Expected EOF found '%c'", (uint64_t)where, found ); @@ -348,7 +348,7 @@ static void query_raise_unexpected_char( const char **error) { snprintf(tmp_error_buff, MAX_ERROR_LEN, - STRING_REP_UINT64 "::Expected '%c' found '%c'", + "%" PRIu64 "::Expected '%c' found '%c'", (uint64_t)where, expected, found); *error = tmp_error_buff; } diff --git a/libretro-db/rmsgpack_dom.c b/libretro-db/rmsgpack_dom.c index f7d6d3d916..942282a17c 100644 --- a/libretro-db/rmsgpack_dom.c +++ b/libretro-db/rmsgpack_dom.c @@ -315,10 +315,10 @@ void rmsgpack_dom_value_print(struct rmsgpack_dom_value *obj) printf("false"); break; case RDT_INT: - printf(STRING_REP_INT64, (int64_t)obj->val.int_); + printf("%" PRId64, (int64_t)obj->val.int_); break; case RDT_UINT: - printf(STRING_REP_UINT64, (uint64_t)obj->val.uint_); + printf("%" PRIu64, (uint64_t)obj->val.uint_); break; case RDT_STRING: printf("\"%s\"", obj->val.string.buff); diff --git a/menu/cbs/menu_cbs_get_value.c b/menu/cbs/menu_cbs_get_value.c index 508121696a..7c42baa346 100644 --- a/menu/cbs/menu_cbs_get_value.c +++ b/menu/cbs/menu_cbs_get_value.c @@ -572,7 +572,7 @@ static void menu_action_setting_disp_set_label_perf_counters_common( return; snprintf(s, len, - STRING_REP_UINT64 " ticks, " STRING_REP_UINT64 " runs.", + "%" PRIu64 " ticks, %" PRIu64 " runs.", ((uint64_t)counters[offset]->total / (uint64_t)counters[offset]->call_cnt), (uint64_t)counters[offset]->call_cnt); diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 1b8172c6e5..dedf26bd8e 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -1032,6 +1032,23 @@ static bool menu_content_find_first_core(menu_content_ctx_defer_info_t *def_info return true; } +#ifdef HAVE_LIBRETRODB +void handle_dbscan_finished(void *task_data, void *user_data, const char *err); +#endif + +static void content_add_to_playlist(const char *path) +{ +#ifdef HAVE_LIBRETRODB + settings_t *settings = config_get_ptr(); + if (!settings || !settings->bools.automatically_add_content_to_playlist) + return; + task_push_dbscan( + settings->paths.directory_playlist, + settings->paths.path_content_database, + path, false, handle_dbscan_finished); +#endif +} + static int file_load_with_detect_core_wrapper( enum msg_hash_enums enum_label_idx, enum msg_hash_enums enum_idx, @@ -1118,6 +1135,7 @@ static int file_load_with_detect_core_wrapper( free(new_core_path); return -1; } + content_add_to_playlist(def_info.s); ret = 0; break; @@ -1370,6 +1388,7 @@ static int default_action_ok_load_content_with_core_from_menu(const char *_path, content_info.environ_get = NULL; if (!task_push_load_content_with_core_from_menu(_path, &content_info, (enum rarch_core_type)_type, NULL, NULL)) return -1; + content_add_to_playlist(_path); return 0; } @@ -1481,8 +1500,6 @@ static int action_ok_playlist_entry_collection(const char *path, const char *core_name = NULL; playlist_t *tmp_playlist = NULL; menu_handle_t *menu = NULL; - rarch_system_info_t *info = runloop_get_system_info(); - struct retro_system_info *system = &info->info; if (!menu_driver_ctl(RARCH_MENU_CTL_DRIVER_DATA_GET, &menu)) return menu_cbs_exit(); @@ -2280,6 +2297,7 @@ static int action_ok_load_core_deferred(const char *path, CORE_TYPE_PLAIN, NULL, NULL)) return -1; + content_add_to_playlist(path); return 0; } @@ -2374,9 +2392,10 @@ static int action_ok_file_load_detect_core(const char *path, if (!task_push_load_content_with_new_core_from_menu( path, detect_content_path, &content_info, - CORE_TYPE_FFMPEG, + CORE_TYPE_PLAIN, NULL, NULL)) return -1; + content_add_to_playlist(detect_content_path); return 0; } @@ -3571,6 +3590,7 @@ static int action_ok_start_core(const char *path, content_info.args = NULL; content_info.environ_get = NULL; + path_clear(RARCH_PATH_BASENAME); if (!task_push_start_current_core(&content_info)) return -1; diff --git a/menu/cbs/menu_cbs_scan.c b/menu/cbs/menu_cbs_scan.c index 213b6b8ad1..8e0168fc86 100644 --- a/menu/cbs/menu_cbs_scan.c +++ b/menu/cbs/menu_cbs_scan.c @@ -37,7 +37,7 @@ #endif #ifdef HAVE_LIBRETRODB -static void handle_dbscan_finished(void *task_data, void *user_data, const char *err) +void handle_dbscan_finished(void *task_data, void *user_data, const char *err) { menu_ctx_environment_t menu_environ; menu_environ.type = MENU_ENVIRON_RESET_HORIZONTAL_LIST; diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index 06170be390..2dd471d3cc 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -44,6 +44,7 @@ return 0; \ } +default_sublabel_macro(action_bind_sublabel_automatically_add_content_to_playlist, MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST) default_sublabel_macro(action_bind_sublabel_driver_settings_list, MENU_ENUM_SUBLABEL_DRIVER_SETTINGS) default_sublabel_macro(action_bind_sublabel_retro_achievements_settings_list, MENU_ENUM_SUBLABEL_RETRO_ACHIEVEMENTS_SETTINGS) default_sublabel_macro(action_bind_sublabel_saving_settings_list, MENU_ENUM_SUBLABEL_SAVING_SETTINGS) @@ -1376,6 +1377,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_CORE_SETTINGS: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_core_settings_list); break; + case MENU_ENUM_LABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_automatically_add_content_to_playlist); + break; case MENU_ENUM_LABEL_DRIVER_SETTINGS: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_driver_settings_list); break; diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index 0839610c25..0901e15beb 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -83,30 +83,6 @@ static uint16_t argb32_to_rgba4444(uint32_t col) } #endif -static void rgui_copy_glyph(uint8_t *glyph, const uint8_t *buf) -{ - int x, y; - - if (!glyph) - return; - - for (y = 0; y < FONT_HEIGHT; y++) - { - for (x = 0; x < FONT_WIDTH; x++) - { - uint32_t col = - ((uint32_t)buf[3 * (-y * 256 + x) + 0] << 0) | - ((uint32_t)buf[3 * (-y * 256 + x) + 1] << 8) | - ((uint32_t)buf[3 * (-y * 256 + x) + 2] << 16); - - uint8_t rem = 1 << ((x + y * FONT_WIDTH) & 7); - unsigned offset = (x + y * FONT_WIDTH) >> 3; - - if (col != 0xff) - glyph[offset] |= rem; - } - } -} static uint16_t rgui_gray_filler(unsigned x, unsigned y) { @@ -190,6 +166,32 @@ static void blit_line(int x, int y, } } +#if 0 +static void rgui_copy_glyph(uint8_t *glyph, const uint8_t *buf) +{ + int x, y; + + if (!glyph) + return; + + for (y = 0; y < FONT_HEIGHT; y++) + { + for (x = 0; x < FONT_WIDTH; x++) + { + uint32_t col = + ((uint32_t)buf[3 * (-y * 256 + x) + 0] << 0) | + ((uint32_t)buf[3 * (-y * 256 + x) + 1] << 8) | + ((uint32_t)buf[3 * (-y * 256 + x) + 2] << 16); + + uint8_t rem = 1 << ((x + y * FONT_WIDTH) & 7); + unsigned offset = (x + y * FONT_WIDTH) >> 3; + + if (col != 0xff) + glyph[offset] |= rem; + } + } +} + static bool init_font(menu_handle_t *menu, const uint8_t *font_bmp_buf) { unsigned i; @@ -213,17 +215,22 @@ static bool init_font(menu_handle_t *menu, const uint8_t *font_bmp_buf) return true; } +#endif static bool rguidisp_init_font(menu_handle_t *menu) { +#if 0 const uint8_t *font_bmp_buf = NULL; +#endif const uint8_t *font_bin_buf = bitmap_bin; if (!menu) return false; +#if 0 if (font_bmp_buf) return init_font(menu, font_bmp_buf); +#endif menu_display_set_font_framebuffer(font_bin_buf); diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index 6301b86cd1..0392da6f34 100755 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -2243,15 +2243,17 @@ static uintptr_t xmb_icon_get_id(xmb_handle_t *xmb, } #ifdef HAVE_CHEEVOS - if ((type >= MENU_SETTINGS_CHEEVOS_START) && - (type < MENU_SETTINGS_NETPLAY_ROOMS_START)) - { + if ( + (type >= MENU_SETTINGS_CHEEVOS_START) && + (type < MENU_SETTINGS_NETPLAY_ROOMS_START) + ) + { int new_id = type - MENU_SETTINGS_CHEEVOS_START; - if ( get_badge_texture(new_id) != 0 ) - return get_badge_texture( new_id ); - else - return xmb->textures.list[XMB_TEXTURE_SUBSETTING]; // Should be replaced with placeholder badge icon. - } + if (get_badge_texture(new_id) != 0) + return get_badge_texture(new_id); + /* Should be replaced with placeholder badge icon. */ + return xmb->textures.list[XMB_TEXTURE_SUBSETTING]; + } #endif return xmb->textures.list[XMB_TEXTURE_SUBSETTING]; diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 61d3ccc919..2622132870 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -834,21 +834,21 @@ static int menu_displaylist_parse_system_info(menu_displaylist_info_t *info) if (memory_used != 0 && memory_total != 0) { snprintf(tmp, sizeof(tmp), - "%s %s: " STRING_REP_UINT64 "/" STRING_REP_UINT64 " B", + "%s %s: %" PRIu64 "/%" PRIu64 " B", msg_hash_to_str(MSG_MEMORY), msg_hash_to_str(MSG_IN_BYTES), memory_used, memory_total ); snprintf(tmp2, sizeof(tmp2), - "%s %s: " STRING_REP_UINT64 "/" STRING_REP_UINT64 " MB", + "%s %s: %" PRIu64 "/%" PRIu64 " MB", msg_hash_to_str(MSG_MEMORY), msg_hash_to_str(MSG_IN_MEGABYTES), bytes_to_mb(memory_used), bytes_to_mb(memory_total) ); snprintf(tmp3, sizeof(tmp3), - "%s %s: " STRING_REP_UINT64 "/" STRING_REP_UINT64 " GB", + "%s %s: %" PRIu64 "/%" PRIu64 " GB", msg_hash_to_str(MSG_MEMORY), msg_hash_to_str(MSG_IN_GIGABYTES), bytes_to_gb(memory_used), @@ -5304,6 +5304,9 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_FILTER_BY_CURRENT_CORE, PARSE_ONLY_BOOL, false); + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + PARSE_ONLY_BOOL, false); info->need_refresh = true; info->need_push = true; break; diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 17e388340b..22e36c4b68 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -5985,6 +5985,23 @@ static bool setting_append_list( START_SUB_GROUP(list, list_info, "State", &group_info, &subgroup_info, parent_group); +#ifdef HAVE_LIBRETRODB + CONFIG_BOOL( + list, list_info, + &settings->bools.automatically_add_content_to_playlist, + MENU_ENUM_LABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + MENU_ENUM_LABEL_VALUE_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, + true, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE); +#endif + CONFIG_BOOL( list, list_info, &settings->bools.multimedia_builtin_mediaplayer_enable, diff --git a/menu/widgets/menu_input_dialog.c b/menu/widgets/menu_input_dialog.c index 4b138f55ef..1017c4c4d5 100644 --- a/menu/widgets/menu_input_dialog.c +++ b/menu/widgets/menu_input_dialog.c @@ -129,7 +129,7 @@ bool menu_input_dialog_start(menu_input_ctx_line_t *line) menu_input_dialog_display_kb(); - // Only copy over the menu label and setting if they exist. + /* Only copy over the menu label and setting if they exist. */ if (line->label) strlcpy(menu_input_dialog_keyboard_label, line->label, sizeof(menu_input_dialog_keyboard_label)); diff --git a/msg_hash.h b/msg_hash.h index 0cce4dfd36..fdd00470e1 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -357,6 +357,7 @@ enum msg_hash_enums MSG_PREPARING_FOR_CONTENT_SCAN, MSG_SCANNING, MSG_SCANNING_OF_DIRECTORY_FINISHED, + MSG_SCANNING_OF_FILE_FINISHED, MSG_LOADED_STATE_FROM_SLOT, MSG_LOADED_STATE_FROM_SLOT_AUTO, MSG_REMOVING_TEMPORARY_CONTENT_FILE, @@ -1023,6 +1024,7 @@ enum msg_hash_enums MENU_LABEL(INFORMATION), MENU_LABEL(INFORMATION_LIST), MENU_LABEL(USE_BUILTIN_PLAYER), + MENU_LABEL(AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST), MENU_LABEL(NETPLAY_SETTINGS), MENU_LABEL(CONTENT_SETTINGS), MENU_LABEL(LOAD_CONTENT_LIST), diff --git a/network/httpserver/httpserver.c b/network/httpserver/httpserver.c index 050604d0e6..c85b67ffa4 100644 --- a/network/httpserver/httpserver.c +++ b/network/httpserver/httpserver.c @@ -247,10 +247,10 @@ static int httpserver_handle_basic_info(struct mg_connection* conn, void* cbdata "\"frontendSupportsAchievements\":false," "\"coreSupportsAchievements\":null," #endif - "\"saveRam\":{\"pointer\":\"%" PRIXPTR "\",\"size\":" STRING_REP_UINT64 "}," - "\"rtcRam\":{\"pointer\":\"%" PRIXPTR "\",\"size\":" STRING_REP_UINT64 "}," - "\"systemRam\":{\"pointer\":\"%" PRIXPTR "\",\"size\":" STRING_REP_UINT64 "}," - "\"videoRam\":{\"pointer\":\"%" PRIXPTR "\",\"size\":" STRING_REP_UINT64 "},", + "\"saveRam\":{\"pointer\":\"%" PRIXPTR "\",\"size\":%" PRIu64 "}," + "\"rtcRam\":{\"pointer\":\"%" PRIXPTR "\",\"size\":%" PRIu64 "}," + "\"systemRam\":{\"pointer\":\"%" PRIXPTR "\",\"size\":%" PRIu64 "}," + "\"videoRam\":{\"pointer\":\"%" PRIXPTR "\",\"size\":%" PRIu64 "},", core_path, api.version, system->info.library_name, @@ -428,13 +428,13 @@ static int httpserver_handle_get_mmaps(struct mg_connection* conn, void* cbdata) mg_printf(conn, "%s{" "\"id\":%u," - "\"flags\":" STRING_REP_UINT64 "," + "\"flags\":%" PRIu64 "," "\"ptr\":\"%" PRIXPTR "\"," - "\"offset\":" STRING_REP_UINT64 "," - "\"start\":" STRING_REP_UINT64 "," - "\"select\":" STRING_REP_UINT64 "," - "\"disconnect\":" STRING_REP_UINT64 "," - "\"len\":" STRING_REP_UINT64 "," + "\"offset\":%" PRIu64 "," + "\"start\":%" PRIu64 "," + "\"select\":%" PRIu64 "," + "\"disconnect\":%" PRIu64 "," + "\"len\":%" PRIu64 "," "\"addrspace\":\"%s\"" "}", comma, diff --git a/network/netplay/netplay_frontend.c b/network/netplay/netplay_frontend.c index b393865a7a..86c8234849 100644 --- a/network/netplay/netplay_frontend.c +++ b/network/netplay/netplay_frontend.c @@ -644,10 +644,16 @@ static void netplay_announce(void) #endif task_push_http_post_transfer(url, buf, true, NULL, netplay_announce_cb, NULL); - free(username); - free(corename); - free(gamename); - free(coreversion); + if (username) + free(username); + if (corename) + free(corename); + if (gamename) + free(gamename); + if (coreversion) + free(coreversion); + if (frontend_ident) + free(frontend_ident); } int16_t input_state_net(unsigned port, unsigned device, diff --git a/qb/config.libs.sh b/qb/config.libs.sh index d93a6f2732..615c36853c 100644 --- a/qb/config.libs.sh +++ b/qb/config.libs.sh @@ -29,6 +29,7 @@ elif [ "$OS" = 'Haiku' ]; then CLIB=-lroot PTHREADLIB=-lroot SOCKETLIB=-lnetwork + CFLAGS="$CFLAGS -D_BSD_SOURCE" elif [ "$OS" = 'Win32' ]; then SOCKETLIB=-lws2_32 SOCKETHEADER="#include " @@ -264,7 +265,7 @@ if [ "$HAVE_SDL2" = 'yes' ]; then fi fi -check_pkgconf LIBUSB libusb-1.0 1.0.16 +check_pkgconf LIBUSB libusb-1.0 1.0.13 if [ "$OS" = 'Win32' ]; then check_lib '' DINPUT -ldinput8 diff --git a/qb/config.params.sh b/qb/config.params.sh index 34bd92590b..53612d047f 100644 --- a/qb/config.params.sh +++ b/qb/config.params.sh @@ -19,6 +19,7 @@ C89_SDL2=no HAVE_LIBUSB=auto # Libusb HID support C89_LIBUSB=no HAVE_DBUS=auto # dbus support +HAVE_SYSTEMD=auto # Systemd support HAVE_UDEV=auto # Udev/Evdev gamepad support HAVE_THREADS=auto # Threading support HAVE_THREAD_STORAGE=auto # Thread Local Storage support diff --git a/qb/qb.libs.sh b/qb/qb.libs.sh index 00411c9109..86868a3cfb 100644 --- a/qb/qb.libs.sh +++ b/qb/qb.libs.sh @@ -44,43 +44,40 @@ check_lib() # $1 = language $2 = HAVE_$2 $3 = lib $4 = function in lib $5 = ECHOBUF="Checking existence of ${3% }" printf %s\\n 'int main(void) { return 0; }' > "$TEMP_CODE" fi + + val="$2" + lib="$3" + error="${7:-}" answer='no' - "$COMPILER" -o \ - "$TEMP_EXE" \ - "$TEMP_CODE" \ - $INCLUDE_DIRS \ - $LIBRARY_DIRS \ - $(printf %s "$5") \ - $CFLAGS \ - $LDFLAGS \ - $(printf %s "$3") >>config.log 2>&1 && answer='yes' - eval "HAVE_$2=\"$answer\"" + eval "set -- $INCLUDE_DIRS $LIBRARY_DIRS $5 $CFLAGS $LDFLAGS $3" + "$COMPILER" -o "$TEMP_EXE" "$TEMP_CODE" "$@" >>config.log 2>&1 && answer='yes' + eval "HAVE_$val=\"$answer\"" printf %s\\n "$ECHOBUF ... $answer" rm -f -- "$TEMP_CODE" "$TEMP_EXE" if [ "$answer" = 'no' ]; then - [ "$7" ] && die 1 "$7" + [ "$error" ] && die 1 "$error" [ "$tmpval" = 'yes' ] && { - die 1 "Forced to build with library $3, but cannot locate. Exiting ..." + die 1 "Forced to build with library $lib, but cannot locate. Exiting ..." } else - eval "${2}_LIBS=\"$3\"" - PKG_CONF_USED="$PKG_CONF_USED $2" + eval "${val}_LIBS=\"$lib\"" + PKG_CONF_USED="$PKG_CONF_USED $val" fi return 0 } check_pkgconf() # $1 = HAVE_$1 $2 = package $3 = version $4 = critical error message [checked only if non-empty] -{ tmpval="$(eval echo \$HAVE_$1)" +{ tmpval="$(eval "printf %s \"\$HAVE_$1\"")" [ "$tmpval" = 'no' ] && return 0 ECHOBUF="Checking presence of package $2" [ "$3" ] && ECHOBUF="$ECHOBUF >= $3" [ "$PKG_CONF_PATH" = "none" ] && { - eval HAVE_$1="no" - echo "$ECHOBUF ... no" + eval "HAVE_$1=no" + printf %s\\n "$ECHOBUF ... no" return 0 } @@ -88,13 +85,13 @@ check_pkgconf() # $1 = HAVE_$1 $2 = package $3 = version $4 = critical error version='no' $PKG_CONF_PATH --atleast-version="${3:-0.0}" "$2" && { answer='yes' - version=$($PKG_CONF_PATH --modversion "$2") - eval $1_CFLAGS=\"$($PKG_CONF_PATH $2 --cflags)\" - eval $1_LIBS=\"$($PKG_CONF_PATH $2 --libs)\" + version="$("$PKG_CONF_PATH" --modversion "$2")" + eval "$1_CFLAGS=\"$("$PKG_CONF_PATH" "$2" --cflags)\"" + eval "$1_LIBS=\"$("$PKG_CONF_PATH" "$2" --libs)\"" } - eval HAVE_$1="$answer"; - echo "$ECHOBUF ... $version" + eval "HAVE_$1=\"$answer\"" + printf %s\\n "$ECHOBUF ... $version" if [ "$answer" = 'no' ]; then [ "$4" ] && die 1 "$4" [ "$tmpval" = 'yes' ] && \ @@ -104,25 +101,29 @@ check_pkgconf() # $1 = HAVE_$1 $2 = package $3 = version $4 = critical error fi } -check_header() #$1 = HAVE_$1 $2..$5 = header files -{ tmpval="$(eval echo \$HAVE_$1)" +check_header() #$1 = HAVE_$1 $2..$5 = header files +{ tmpval="$(eval "printf %s \"\$HAVE_$1\"")" [ "$tmpval" = 'no' ] && return 0 CHECKHEADER="$2" - echo "#include <$2>" > "$TEMP_C" - [ "$3" != "" ] && CHECKHEADER="$3" && echo "#include <$3>" >> "$TEMP_C" - [ "$4" != "" ] && CHECKHEADER="$4" && echo "#include <$4>" >> "$TEMP_C" - [ "$5" != "" ] && CHECKHEADER="$5" && echo "#include <$5>" >> "$TEMP_C" - echo "int main(void) { return 0; }" >> "$TEMP_C" + printf %s\\n "#include <$2>" > "$TEMP_C" + [ "$3" != '' ] && CHECKHEADER="$3" && printf %s\\n "#include <$3>" >> "$TEMP_C" + [ "$4" != '' ] && CHECKHEADER="$4" && printf %s\\n "#include <$4>" >> "$TEMP_C" + [ "$5" != '' ] && CHECKHEADER="$5" && printf %s\\n "#include <$5>" >> "$TEMP_C" + printf %s\\n "int main(void) { return 0; }" >> "$TEMP_C" answer='no' - "$CC" -o "$TEMP_EXE" "$TEMP_C" $INCLUDE_DIRS >>config.log 2>&1 && answer='yes' - eval HAVE_$1="$answer"; echo "Checking presence of header file $CHECKHEADER ... $answer" + val="$1" + header="$2" + eval "set -- $INCLUDE_DIRS" + "$CC" -o "$TEMP_EXE" "$TEMP_C" "$@" >>config.log 2>&1 && answer='yes' + eval "HAVE_$val=\"$answer\"" + printf %s\\n "Checking presence of header file $CHECKHEADER ... $answer" rm -f -- "$TEMP_C" "$TEMP_EXE" [ "$tmpval" = 'yes' ] && [ "$answer" = 'no' ] && \ - die 1 "Build assumed that $2 exists, but cannot locate. Exiting ..." + die 1 "Build assumed that $header exists, but cannot locate. Exiting ..." } -check_macro() #$1 = HAVE_$1 $2 = macro name -{ tmpval="$(eval echo \$HAVE_$1)" +check_macro() #$1 = HAVE_$1 $2 = macro name +{ tmpval="$(eval "printf %s \"\$HAVE_$1\"")" [ "$tmpval" = 'no' ] && return 0 ECHOBUF="Checking presence of predefined macro $2" cat << EOF > "$TEMP_C" @@ -132,11 +133,15 @@ check_macro() #$1 = HAVE_$1 $2 = macro name int main(void) { return 0; } EOF answer='no' - "$CC" -o "$TEMP_EXE" "$TEMP_C" $CFLAGS $INCLUDE_DIRS >>config.log 2>&1 && answer='yes' - eval HAVE_$1="$answer"; echo "$ECHOBUF ... $answer" + val="$1" + macro="$2" + eval "set -- $CFLAGS $INCLUDE_DIRS" + "$CC" -o "$TEMP_EXE" "$TEMP_C" "$@" >>config.log 2>&1 && answer='yes' + eval "HAVE_$val=\"$answer\"" + printf %s\\n "$ECHOBUF ... $answer" rm -f -- "$TEMP_C" "$TEMP_EXE" [ "$tmpval" = 'yes' ] && [ "$answer" = 'no' ] && \ - die 1 "Build assumed that $2 is defined, but it's not. Exiting ..." + die 1 "Build assumed that $macro is defined, but it's not. Exiting ..." } check_switch() # $1 = language $2 = HAVE_$2 $3 = switch $4 = critical error message [checked only if non-empty] @@ -227,9 +232,9 @@ create_config_make() case "$PKG_CONF_USED" in *$1*) - FLAGS="$(eval "printf %s \"\$$1_CFLAGS\"")" + FLAG="$(eval "printf %s \"\$$1_CFLAGS\"")" LIBS="$(eval "printf %s \"\$$1_LIBS\"")" - [ "${FLAGS}" ] && printf %s\\n "$1_CFLAGS = ${FLAGS%"${FLAGS##*[! ]}"}" + [ "${FLAG}" ] && printf %s\\n "$1_CFLAGS = ${FLAG%"${FLAG##*[! ]}"}" [ "${LIBS}" ] && printf %s\\n "$1_LIBS = ${LIBS%"${LIBS##*[! ]}"}" ;; esac diff --git a/tasks/task_autodetect.c b/tasks/task_autodetect.c index 7a25d9bc61..364cffea8a 100644 --- a/tasks/task_autodetect.c +++ b/tasks/task_autodetect.c @@ -1,6 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis + * Copyright (C) 2016-2017 - Brad Parker * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- @@ -24,7 +25,16 @@ #include #include +#ifdef HAVE_LIBUSB +#ifdef __FreeBSD__ +#include +#else +#include +#endif +#endif + #include "../input/input_driver.h" +#include "../input/include/blissbox.h" #include "../configuration.h" #include "../file_path_special.h" @@ -33,6 +43,19 @@ #include "tasks_internal.h" +/* HID Class-Specific Requests values. See section 7.2 of the HID specifications */ +#define USB_HID_GET_REPORT 0x01 +#define USB_CTRL_IN LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE +#define USB_PACKET_CTRL_LEN 64 +#define USB_TIMEOUT 5000 /* timeout in ms */ + +/* only one blissbox per machine is currently supported */ +static const blissbox_pad_type_t *blissbox_pads[BLISSBOX_MAX_PADS] = {NULL}; + +#ifdef HAVE_LIBUSB +static struct libusb_device_handle *autoconfig_libusb_handle = NULL; +#endif + typedef struct autoconfig_disconnect autoconfig_disconnect_t; typedef struct autoconfig_params autoconfig_params_t; @@ -120,13 +143,16 @@ static int input_autoconfigure_joypad_try_from_conf(config_file_t *conf, if (config_get_int (conf, "input_product_id", &tmp_int)) input_pid = tmp_int; + if (params->vid == BLISSBOX_VID) + input_pid = BLISSBOX_PID; + /* Check for VID/PID */ if ( (params->vid == input_vid) && (params->pid == input_pid) && (params->vid != 0) && (params->pid != 0) - && (input_vid != 0) - && (input_pid != 0)) + && (params->vid != BLISSBOX_VID) + && (params->pid != BLISSBOX_PID)) score += 3; /* Check for name match */ @@ -333,6 +359,131 @@ static void input_autoconfigure_params_free(autoconfig_params_t *params) params->autoconfig_directory = NULL; } +static const blissbox_pad_type_t* input_autoconfigure_get_blissbox_pad_type(int vid, int pid) +{ +#ifdef HAVE_LIBUSB + unsigned char answer[USB_PACKET_CTRL_LEN] = {0}; + unsigned i; + int ret = libusb_init(NULL); + + if (ret < 0) + { + RARCH_ERR("[Autoconf]: Could not initialize libusb.\n"); + return NULL; + } + + autoconfig_libusb_handle = libusb_open_device_with_vid_pid(NULL, vid, pid); + + if (!autoconfig_libusb_handle) + { + RARCH_ERR("[Autoconf]: Could not find or open libusb device %d:%d.\n", vid, pid); + goto error; + } + +#ifdef __linux__ + libusb_detach_kernel_driver(autoconfig_libusb_handle, 0); +#endif + + ret = libusb_set_configuration(autoconfig_libusb_handle, 1); + + if (ret < 0) + { + RARCH_ERR("[Autoconf]: Error during libusb_set_configuration.\n"); + goto error; + } + + ret = libusb_claim_interface(autoconfig_libusb_handle, 0); + + if (ret < 0) + { + RARCH_ERR("[Autoconf]: Error during libusb_claim_interface.\n"); + goto error; + } + + ret = libusb_control_transfer(autoconfig_libusb_handle, USB_CTRL_IN, USB_HID_GET_REPORT, BLISSBOX_USB_FEATURE_REPORT_ID, 0, answer, USB_PACKET_CTRL_LEN, USB_TIMEOUT); + + if (ret < 0) + RARCH_ERR("[Autoconf]: Error during libusb_control_transfer.\n"); + + libusb_release_interface(autoconfig_libusb_handle, 0); + +#ifdef __linux__ + libusb_attach_kernel_driver(autoconfig_libusb_handle, 0); +#endif + + libusb_close(autoconfig_libusb_handle); + libusb_exit(NULL); + + for (i = 0; i < sizeof(blissbox_pad_types) / sizeof(blissbox_pad_types[0]); i++) + { + const blissbox_pad_type_t *pad = &blissbox_pad_types[i]; + + if (!pad || string_is_empty(pad->name)) + continue; + + if (pad->index == answer[0]) + return pad; + } + + RARCH_LOG("[Autoconf]: Could not find connected pad in Bliss-Box port#%d.\n", pid - BLISSBOX_PID); + + return NULL; + +error: + libusb_close(autoconfig_libusb_handle); + libusb_exit(NULL); + return NULL; +#else + return NULL; +#endif +} + +static void input_autoconfigure_override_handler(autoconfig_params_t *params) +{ + if (params->vid == BLISSBOX_VID) + { + if (params->pid == BLISSBOX_UPDATE_MODE_PID) + RARCH_LOG("[Autoconf]: Bliss-Box in update mode detected. Ignoring.\n"); + else if (params->pid == BLISSBOX_OLD_PID) + RARCH_LOG("[Autoconf]: Bliss-Box 1.0 firmware detected. Please update to 2.0 or later.\n"); + else if (params->pid >= BLISSBOX_PID && params->pid <= BLISSBOX_PID + BLISSBOX_MAX_PAD_INDEX) + { + const blissbox_pad_type_t *pad; + char name[255] = {0}; + int index = params->pid - BLISSBOX_PID; + + RARCH_LOG("[Autoconf]: Bliss-Box detected. Getting pad type...\n"); + + if (blissbox_pads[index]) + pad = blissbox_pads[index]; + else + pad = input_autoconfigure_get_blissbox_pad_type(params->vid, params->pid); + + if (pad && !string_is_empty(pad->name)) + { + RARCH_LOG("[Autoconf]: Found Bliss-Box pad type: %s (%d) in port#%d\n", pad->name, pad->index, index); + + if (params->name) + free(params->name); + + /* override name given to autoconfig so it knows what kind of pad this is */ + strlcat(name, "Bliss-Box ", sizeof(name)); + strlcat(name, pad->name, sizeof(name)); + + params->name = strdup(name); + + blissbox_pads[index] = pad; + } + else + { + int count = sizeof(blissbox_pad_types) / sizeof(blissbox_pad_types[0]); + /* use NULL entry to mark as an unconnected port */ + blissbox_pads[index] = &blissbox_pad_types[count - 1]; + } + } + } +} + static void input_autoconfigure_connect_handler(retro_task_t *task) { autoconfig_params_t *params = (autoconfig_params_t*)task->state; @@ -499,6 +650,8 @@ bool input_autoconfigure_connect( state->max_users = *( input_driver_get_uint(INPUT_ACTION_MAX_USERS)); + input_autoconfigure_override_handler(state); + if (!string_is_empty(state->name)) input_config_set_device_name(state->idx, state->name); input_config_set_pid(state->idx, state->pid); diff --git a/tasks/task_database.c b/tasks/task_database.c index ddb079077d..afe42dd83e 100644 --- a/tasks/task_database.c +++ b/tasks/task_database.c @@ -1254,9 +1254,14 @@ static void task_database_handler(retro_task_t *task) } else { - runloop_msg_queue_push( - msg_hash_to_str(MSG_SCANNING_OF_DIRECTORY_FINISHED), - 0, 180, true); + if (db->is_directory) + runloop_msg_queue_push( + msg_hash_to_str(MSG_SCANNING_OF_DIRECTORY_FINISHED), + 0, 180, true); + else + runloop_msg_queue_push( + msg_hash_to_str(MSG_SCANNING_OF_FILE_FINISHED), + 0, 180, true); goto task_finished; } break;