diff --git a/firmware/mai2/mai2io/mai2io.c b/firmware/mai2/mai2io/mai2io.c index 6d3eb94..8a7aba8 100644 --- a/firmware/mai2/mai2io/mai2io.c +++ b/firmware/mai2/mai2io/mai2io.c @@ -11,17 +11,19 @@ #include "mai2io/mai2io.h" #include "mai2io/config.h" +static FILE *logfile; static GUID hidclass_guid = {0x745a17a0, 0x74d3, 0x11d0, {0xb6, 0xfe, 0x00, 0xa0, 0xc9, 0x0f, 0x57, 0xda}}; -static BOOLEAN get_device_path(char *lPath, uint16_t vid, uint16_t pid, int8_t mi) +static BOOLEAN get_device_path(char *lPath, uint16_t vid, uint16_t pid, int8_t mi, const char *skip) { const GUID *guid = &hidclass_guid; HidD_GetHidGuid(&hidclass_guid); // Get device interface info set handle // for all devices attached to system HDEVINFO hDevInfo = SetupDiGetClassDevs(guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); // Function class devices. - if(hDevInfo == INVALID_HANDLE_VALUE) + if (hDevInfo == INVALID_HANDLE_VALUE) { return FALSE; + } // Retrieve a context structure for a device interface of a device information set. BYTE buf[1024]; @@ -29,53 +31,42 @@ static BOOLEAN get_device_path(char *lPath, uint16_t vid, uint16_t pid, int8_t m SP_DEVICE_INTERFACE_DATA spdid; SP_DEVINFO_DATA spdd; DWORD dwSize; - char vidstr[64]; - char mistr[64]; + char pidstr[16]; + char vidstr[16]; + char mistr[16]; - (void) pid; /* not used for now */ - //sprintf(vidpidstr, "vid_%04x&pid_%04x&mi_%02x", vid, pid, mi); -sprintf(vidstr, "vid_%04x&", vid); -if (mi != -1) sprintf(mistr, "&mi_%02x", mi); + sprintf(pidstr, "pid_%04x&", pid); + sprintf(vidstr, "vid_%04x&", vid); + sprintf(mistr, "&mi_%02x", mi); - #if DEBUG == 1 -printf("looking for substring %s in device path\r\n", vidstr); - #endif + printf("Looking up `%s` skip `%s`.\n", vidstr, + skip ? skip : "none"); spdid.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); -// Iterate through all the interfaces and try to match one based on -// the device number. - for(DWORD i = 0; SetupDiEnumDeviceInterfaces(hDevInfo, NULL,guid, i, &spdid); i++) - { - // Get the device path. + for (DWORD i = 0; SetupDiEnumDeviceInterfaces(hDevInfo, NULL, guid, i, &spdid); i++) { dwSize = 0; SetupDiGetDeviceInterfaceDetail(hDevInfo, &spdid, NULL, 0, &dwSize, NULL); - if(dwSize == 0 || dwSize > sizeof(buf)) + if (dwSize == 0 || dwSize > sizeof(buf)) { continue; - + } + pspdidd->cbSize = sizeof(*pspdidd); ZeroMemory((PVOID)&spdd, sizeof(spdd)); spdd.cbSize = sizeof(spdd); - if(!SetupDiGetDeviceInterfaceDetail(hDevInfo, &spdid, pspdidd, - dwSize, &dwSize, &spdd)) - continue; - - #if DEBUG == 1 -printf("checking path %s... ", pspdidd->DevicePath); - #endif - - /* check if the device contains our wanted vid/pid */ - // if ( strstr( pspdidd->DevicePath, vidpidstr ) == NULL ) - if ( strstr( pspdidd->DevicePath, vidstr ) == NULL || ((mi!= -1) && strstr( pspdidd->DevicePath, mistr ) == NULL) ) - { - #if DEBUG == 1 - printf("that's not it.\r\n"); - #endif + if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &spdid, pspdidd, + dwSize, &dwSize, &spdd)) { continue; } -#if DEBUG == 1 - printf("\r\nDevice found at %s\r\n", pspdidd->DevicePath); -#endif - //copy devpath into lPath + if (strstr(pspdidd->DevicePath, vidstr) == NULL || + ((mi != -1) && strstr(pspdidd->DevicePath, mistr) == NULL)) { + continue; + } + if (skip != NULL && strcmp(pspdidd->DevicePath, skip) == 0) { + fprintf(logfile, "DevicePath already used: %s\n", skip); + continue; + } + + fprintf(logfile, "Found Device: %s\n", pspdidd->DevicePath); strcpy(lPath, pspdidd->DevicePath); SetupDiDestroyDeviceInfoList(hDevInfo); return TRUE; @@ -84,57 +75,44 @@ printf("checking path %s... ", pspdidd->DevicePath); return FALSE; } +HANDLE hid_open_device(uint16_t vid, uint16_t pid, uint8_t mi, bool first) +{ + static char path1[256]; + static char path2[256]; -int hid_open_device(HANDLE *device_handle, uint16_t vid, uint16_t pid, uint8_t mi){ - static uint8_t err_count = 0; - char path[256]; - - if (!get_device_path(path, vid, pid, mi)) - { -#if DEBUG == 1 - printf("\r\nDevice not detected (vid %04x pid %04x mi %02x).\r\n",vid,pid,mi); -#endif - err_count++; - if (err_count > 2){ - printf("Could not init device after multiple attempts. Exiting.\r\n"); - exit(1); - } - return -1; + char *path = first ? path1 : path2; + const char *skip = first ? NULL : path1; + + if (!get_device_path(path, vid, pid, mi, skip)) { + return INVALID_HANDLE_VALUE; } -#if DEBUG == 1 - printf("\r\nDevice found (vid %04x pid %04x mi %02x).\r\n",vid,pid,mi); -#endif - *device_handle = CreateFile(path, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); - - if ( *device_handle == INVALID_HANDLE_VALUE ) - { - printf("Could not open detected device (err = %lx).\r\n", GetLastError()); - return -1; - } - return 0; + + fprintf(logfile, "Opening Device: %s\n", path); + fflush(logfile); + return CreateFile(path, GENERIC_READ|GENERIC_WRITE, + FILE_SHARE_READ|FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, 0, NULL); } -int hid_get_report(HANDLE device_handle, uint8_t *buf, uint8_t report_id, uint8_t nb_bytes) +int hid_get_report(HANDLE handle, uint8_t *buf, uint8_t report_id, uint8_t nb_bytes) { DWORD bytesRead = 0; static uint8_t tmp_buf[128]; - if (buf == NULL) return -1; + if (buf == NULL) { + return -1; + } tmp_buf[0] = report_id; - ReadFile(device_handle, tmp_buf, nb_bytes*2, &bytesRead, NULL); + ReadFile(handle, tmp_buf, nb_bytes, &bytesRead, NULL); // bytesRead should either be nb_bytes*2 (if it successfully read 2 reports) or nb_bytes (only one) - if ( bytesRead != nb_bytes*2 && bytesRead != nb_bytes ) - { -#ifdef DEBUG - printf("HID read error (expected %u (or twice that), but got %lu bytes)\n",nb_bytes, bytesRead); -#endif + if (bytesRead != nb_bytes) { return -1; } /* HID read ok, copy latest report bytes */ - memcpy(buf, tmp_buf + bytesRead - nb_bytes, nb_bytes); + memcpy(buf, tmp_buf, nb_bytes); return 0; } @@ -150,18 +128,34 @@ uint16_t mai2_io_get_api_version(void) return 0x0100; } -static HANDLE joy_handle; +static HANDLE joy1_handle; +static HANDLE joy2_handle; HRESULT mai2_io_init(void) { mai2_io_config_load(&mai2_io_cfg, L".\\segatools.ini"); + logfile = fopen(".\\mai2_log.txt", "w+"); - if (hid_open_device(&joy_handle, 0x0f0d, 0x0092, 0) != 0) { - return S_OK; + joy1_handle = hid_open_device(0x0f0d, 0x0092, -1, true); + fprintf(logfile, "Handle1: %Id\n", (intptr_t)joy1_handle); + fflush(logfile); + joy2_handle = hid_open_device(0x0f0d, 0x0092, -1, false); + fprintf(logfile, "Handle2: %Id\n", (intptr_t)joy2_handle); + fflush(logfile); + + if (joy1_handle != INVALID_HANDLE_VALUE) { + fprintf(logfile, "Joy1 OK\n"); + HidD_SetNumInputBuffers(joy1_handle, 2); + } + if (joy2_handle != INVALID_HANDLE_VALUE) { + fprintf(logfile, "Joy2 OK\n"); + HidD_SetNumInputBuffers(joy2_handle, 2); } - HidD_SetNumInputBuffers(joy_handle, 2); + fprintf(logfile, "MAI2 JOY Init Done\n"); + fflush(logfile); + fclose(logfile); return S_OK; } @@ -174,114 +168,14 @@ typedef struct joy_report_s { uint8_t VendorSpec; } joy_report_t; -joy_report_t joy_data; - -HRESULT mai2_io_poll_(void) -{ - mai2_opbtn = 0; - mai2_player1_btn = 0; - mai2_player2_btn = 0; - - if (GetAsyncKeyState(mai2_io_cfg.vk_test) & 0x8000) { - mai2_opbtn |= MAI2_IO_OPBTN_TEST; - } - - if (GetAsyncKeyState(mai2_io_cfg.vk_service) & 0x8000) { - mai2_opbtn |= MAI2_IO_OPBTN_SERVICE; - } - - if (GetAsyncKeyState(mai2_io_cfg.vk_coin) & 0x8000) { - if (!mai2_io_coin) { - mai2_io_coin = true; - mai2_opbtn |= MAI2_IO_OPBTN_COIN; - } - } else { - mai2_io_coin = false; - } - - //Player 1 - if (GetAsyncKeyState(mai2_io_cfg.vk_1p_btn[0])) { - mai2_player1_btn |= MAI2_IO_GAMEBTN_1; - } - - if (GetAsyncKeyState(mai2_io_cfg.vk_1p_btn[1])) { - mai2_player1_btn |= MAI2_IO_GAMEBTN_2; - } - - if (GetAsyncKeyState(mai2_io_cfg.vk_1p_btn[2])) { - mai2_player1_btn |= MAI2_IO_GAMEBTN_3; - } - - if (GetAsyncKeyState(mai2_io_cfg.vk_1p_btn[3])) { - mai2_player1_btn |= MAI2_IO_GAMEBTN_4; - } - - if (GetAsyncKeyState(mai2_io_cfg.vk_1p_btn[4])) { - mai2_player1_btn |= MAI2_IO_GAMEBTN_5; - } - - if (GetAsyncKeyState(mai2_io_cfg.vk_1p_btn[5])) { - mai2_player1_btn |= MAI2_IO_GAMEBTN_6; - } - - if (GetAsyncKeyState(mai2_io_cfg.vk_1p_btn[6])) { - mai2_player1_btn |= MAI2_IO_GAMEBTN_7; - } - - if (GetAsyncKeyState(mai2_io_cfg.vk_1p_btn[7])) { - mai2_player1_btn |= MAI2_IO_GAMEBTN_8; - } - - if (GetAsyncKeyState(mai2_io_cfg.vk_1p_btn[8])) { - mai2_player1_btn |= MAI2_IO_GAMEBTN_SELECT; - } - - //Player 2 - if (GetAsyncKeyState(mai2_io_cfg.vk_2p_btn[0])) { - mai2_player2_btn |= MAI2_IO_GAMEBTN_1; - } - - if (GetAsyncKeyState(mai2_io_cfg.vk_2p_btn[1])) { - mai2_player2_btn |= MAI2_IO_GAMEBTN_2; - } - - if (GetAsyncKeyState(mai2_io_cfg.vk_2p_btn[2])) { - mai2_player2_btn |= MAI2_IO_GAMEBTN_3; - } - - if (GetAsyncKeyState(mai2_io_cfg.vk_2p_btn[3])) { - mai2_player2_btn |= MAI2_IO_GAMEBTN_4; - } - - if (GetAsyncKeyState(mai2_io_cfg.vk_2p_btn[4])) { - mai2_player2_btn |= MAI2_IO_GAMEBTN_5; - } - - if (GetAsyncKeyState(mai2_io_cfg.vk_2p_btn[5])) { - mai2_player2_btn |= MAI2_IO_GAMEBTN_6; - } - - if (GetAsyncKeyState(mai2_io_cfg.vk_2p_btn[6])) { - mai2_player2_btn |= MAI2_IO_GAMEBTN_7; - } - - if (GetAsyncKeyState(mai2_io_cfg.vk_2p_btn[7])) { - mai2_player2_btn |= MAI2_IO_GAMEBTN_8; - } - - if (GetAsyncKeyState(mai2_io_cfg.vk_2p_btn[8])) { - mai2_player2_btn |= MAI2_IO_GAMEBTN_SELECT; - } - - return S_OK; -} - HRESULT mai2_io_poll(void) { mai2_opbtn = 0; mai2_player1_btn = 0; mai2_player2_btn = 0; + logfile = fopen(".\\mai2_log.txt", "a+"); + if (GetAsyncKeyState(mai2_io_cfg.vk_test) & 0x8000) { mai2_opbtn |= MAI2_IO_OPBTN_TEST; } @@ -299,9 +193,26 @@ HRESULT mai2_io_poll(void) mai2_io_coin = false; } - hid_get_report(joy_handle, (uint8_t *)&joy_data, 0x01, sizeof(joy_data)); - mai2_player1_btn = joy_data.buttons; + fprintf(logfile, "OPT: %d\n", mai2_opbtn); + fflush(logfile); + if (joy1_handle != INVALID_HANDLE_VALUE) { + joy_report_t joy_data; + hid_get_report(joy1_handle, (uint8_t *)&joy_data, 0x01, sizeof(joy_data)); + mai2_player1_btn = joy_data.buttons; + fprintf(logfile, "Joy1: %d\n", mai2_player1_btn); + fflush(logfile); + } + + if (joy2_handle != INVALID_HANDLE_VALUE) { + joy_report_t joy_data; + hid_get_report(joy2_handle, (uint8_t *)&joy_data, 0x01, sizeof(joy_data)); + mai2_player2_btn = joy_data.buttons; + fprintf(logfile, "Joy2: %d\n", mai2_player2_btn); + fflush(logfile); + } + fprintf(logfile, "Joy Poll Done\n"); + fclose(logfile); return S_OK; }