From 7ac0f061cf897675b042c0e12abe58ccdf889f39 Mon Sep 17 00:00:00 2001 From: CrazyRedMachine Date: Sun, 5 Sep 2021 16:47:42 +0200 Subject: [PATCH] coin blocker fix --- ezusb/ezusb-popn15.dll | Bin 6144 -> 6656 bytes ezusb/ezusb.dll | Bin 6144 -> 6656 bytes ezusb/src/ezusb.cpp | 158 ++++++++++++++++++++++------------------- 3 files changed, 84 insertions(+), 74 deletions(-) diff --git a/ezusb/ezusb-popn15.dll b/ezusb/ezusb-popn15.dll index 27f4ca8c5cd65394e2413138455b2d2431bbeeae..dab1b164b825d4b3450ed773b8cea55825d8a812 100644 GIT binary patch delta 823 zcmZ8fPe>F|7=JUnvop?)>tecvEU5Iyq$S09&x421YDmhZU2XNyt`KF&BowiNbjXc8 zG|n_4y@RJ9yA?vlNEAej2x|uqYX<|3kfhiZp$*jbusOX^x0b%gkNNTYe((F<``#p) z6L2C^uP?)E;2_ojUGJuN05~Fe_QmJ8jB29gZQMp(ESo0UL>&NrJVgiaTdINYauLZ( zz~K$*6eVCE-GB$^N_?62HTsBN672xApT0XVbo)9HDS{9IO>o2*r#;S58R$|WB)jzB zR=9gXDv%6FNn6eZy9cnU19iZwNrhzI6&I3uN1RQ5u(WTn`HI)&{$}9S&of&}&{8`s zb&39HFMcWUwL^*Qs-fLtNd-m9t0^->A9EMKuUMzJ8q)4uTeQQ- zdj*D?#*FV$^j*uRmV4qO@s;>Sq#z4@uogDLCWxQ}qwppif_LG4sKdwbC7gvnpbL4> qVN{C(2%@v-0_s9x6h(t5jvkRf+VfkFa6%r^NIqc$VgWHBanMxn`eOzMgvKv5*%z`)?3SCpEQpUlAU z4w}X3K{{&>Q_4$x_)Avt@ z?~g22pkF#dzjlj?0IdoP0{V#czo-n18QqN!jkcVnStTI zs0h%eEQS{=A%YMOZhpW~z&MF#iWn@`nSk*S4#aoVfLLJjDxO!&%s{!x(*;xmF9h!3EN!PFwt50KSt<`sO*$N@?$$yPCmn|}!LurjWg%qrm>w#|s&xYD@Q zc%$(S}+ m{4rrP%Co(&Vx^Z_7a7VF^K|+E5hu-hZ#|z5K5O5 zLs^FJ%q1+xKex-FZ6&as&dQsd~ij{;fx zY2HR(=b|iJ6;{-mYV(Zd)#S()8Q~6*N$v=aWP1$5SlSKRyIURNGqc-<(HmJ<67_|> z%-?)s!W)IqUkG-JtK<}a{F;hAbUt00KOc;;S}6C}oXM2gv@@YC1*wKdtC3{pLzN$?}RPkUvPu3NCqB}@K57Bcpi@qZp scH;fG7JD(mr|~)5frB`V`*954#rN?Tp1_ar8=S`87GFzp3SMIV00$Bz1poj5 delta 743 zcmZoLX)u`ZLQ$&UD3JjQ9xyN|ax-!Rf+VfkFa6%r^NIqc$VgWHBanMxn`eOzMgvKv5*%z`)?3SCpEQpUlAU z4w}X3K{{&>Q_4$x_)Avt@ z?~g22pkF#dzjlj?0IdoP0{V#czo-n18QqN!jkcVnStTI zs0h%eEQS{=A%YMOZhpW~z&MF#iWn@`nSk*S4#W%8fmm?!DxO!&%s{!x(*;xmF9h!3EN!PFwt50KSt<`rDd#K8}=F4-z3aq}Kw4;IE1lUXIa!?qdm8&?{) z8gDe-Vf^0st1*iSuZg&ctckLTv5A{WfJvB1j7g?RjmdnIZ6^Cnj+>k}xnuIg 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; - - /* check if the device contains our wanted vid/pid */ - if ( wcsstr( pspdidd->DevicePath, L"vid_1ccf&pid_1000&mi_02" ) == NULL ) - { + + /* check if the device contains our wanted vid/pid */ + if ( wcsstr( pspdidd->DevicePath, L"vid_1ccf&pid_1000&mi_02" ) == NULL ) + { continue; - } + } #ifdef DEBUG - printf("\r\nDevice found at %S\r\n", &pspdidd->DevicePath); + printf("\r\nDevice found at %S\r\n", &pspdidd->DevicePath); #endif - //copy devpath into lPath - wcscpy(lPath, pspdidd->DevicePath); - SetupDiDestroyDeviceInfoList(hDevInfo); - return TRUE; + //copy devpath into lPath + wcscpy(lPath, pspdidd->DevicePath); + SetupDiDestroyDeviceInfoList(hDevInfo); + return TRUE; } - SetupDiDestroyDeviceInfoList(hDevInfo); - return FALSE; + SetupDiDestroyDeviceInfoList(hDevInfo); + return FALSE; } /** @@ -81,46 +83,46 @@ BOOLEAN get_device_path(wchar_t *lPath) * @return 0 on success, -1 on error */ static int controller_init(){ - static uint8_t err_count = 0; - wchar_t lPath[256]; - char path[256]; - FILE *file; + static uint8_t err_count = 0; + wchar_t lPath[256]; + char path[256]; + FILE *file; - /* first check if there's a devicepath.dat override */ - file = fopen("devicepath.dat", "r"); + /* first check if there's a devicepath.dat override */ + file = fopen("devicepath.dat", "r"); if (file != NULL) { - while ( fgets(path,256,file) != NULL ) - { - path[strcspn(path, "\r\n")] = 0; - g_hid_handle = CreateFileA(path, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); - if ( g_hid_handle != INVALID_HANDLE_VALUE ) - { - fclose(file); - return 0; - } - } - fclose(file); + while ( fgets(path,256,file) != NULL ) + { + path[strcspn(path, "\r\n")] = 0; + g_hid_handle = CreateFileA(path, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + if ( g_hid_handle != INVALID_HANDLE_VALUE ) + { + fclose(file); + return 0; + } + } + fclose(file); } - /* auto detect device path */ - if (!get_device_path(lPath)) - { - printf("\r\nPOPN MUSIC USB not detected.\r\n"); - err_count++; - if (err_count > 2){ - printf("Could not init device after multiple attempts. Exiting.\r\n"); - exit(1); - } - return -1; - } + /* auto detect device path */ + if (!get_device_path(lPath)) + { + printf("\r\nPOPN MUSIC USB not detected.\r\n"); + err_count++; + if (err_count > 2){ + printf("Could not init device after multiple attempts. Exiting.\r\n"); + exit(1); + } + return -1; + } - g_hid_handle = CreateFile(lPath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + g_hid_handle = CreateFile(lPath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if ( g_hid_handle == INVALID_HANDLE_VALUE ) { printf("Could not open detected device (err = %x).\r\n", GetLastError()); - return -1; + return -1; } return 0; } @@ -140,7 +142,7 @@ static int controller_init(){ * @return 0 on success, -1 on error */ static int controller_read_buttons(uint32_t *pad_bits){ - DWORD bytesRead = 0; + DWORD bytesRead = 0; uint8_t res[4]; unsigned char buf[6]; // gamepad report length is 3 bytes in firmware, doubled because NumInputBuffer is set to 2 @@ -158,18 +160,15 @@ static int controller_read_buttons(uint32_t *pad_bits){ } /* HID read ok, convert latest report bytes to pop'n bitfield */ - res[3] = 0; - res[2] = (buf[bytesRead-1]<<3 | buf[bytesRead-1]) & 0x41; - res[1] = buf[bytesRead-2]; + res[3] = g_dip_state; // dip switches + res[2] = (buf[bytesRead-1]<<3 | buf[bytesRead-1]) & 0x41; // button 9 (0x01) and coin mech (0x40) + res[1] = buf[bytesRead-2]; // button 1 to 8 res[0] = 0; buf[bytesRead-1] >>= 1; - if ( buf[bytesRead-1]&1 ) res[0] |= 0x80; + if ( buf[bytesRead-1]&1 ) res[0] |= 0x80; // test buf[bytesRead-1] >>= 1; - if ( buf[bytesRead-1]&1 ) res[0] |= 0x40; + if ( buf[bytesRead-1]&1 ) res[0] |= 0x40; // service *pad_bits = *(uint32_t *)res; - - /* dip switches */ - *pad_bits |= g_dip_state << 24; #ifdef DEBUG for (int i = 0; i<32; i++){ @@ -177,7 +176,7 @@ static int controller_read_buttons(uint32_t *pad_bits){ if (((i+1)%4)==0) printf(" "); } printf("\n"); - if (*pad_bits & 0x8000000) printf("31kHz mode\r\n"); + if (*pad_bits & 0x8000000) printf("31kHz mode\r\n"); #endif return 0; } @@ -188,22 +187,33 @@ static int controller_read_buttons(uint32_t *pad_bits){ * Pop'n Music sends lights state as a int32_t bitfield with the following format : * bits 0 (LSB) to 4 : neons from top to bottom * bits 8 to 11 : side lamps (left blue, left red, right blue, right red) - * bits 23 to 31 : button lamps from left to right + * bits 16 to 19 : coin blocker (0x0 for on, 0xF for off) + * bits 23 to 31 : button lamps from left to right (note: technically game sets the whole 20-23 to 0xF rather than 0x8 for lamp 1) * * @param lamp_bits[in] lamp state bitfield * @return 0 on success, -1 on error */ static int controller_write_leds(int32_t lamp_bits){ - DWORD bytesWritten = 0; + DWORD bytesWritten = 0; uint8_t *src = (uint8_t*) &lamp_bits; //cast as uint8_t array for fast conversion uint8_t buf[5]; // HID lights report length is 5 bytes in Arduino firmware + +#ifdef DEBUG_LAMP + for (int i = 0; i<32; i++){ + printf("%c",( ((uint32_t )lamp_bits>>(31-i))&1)?'1':'0'); + if (((i+1)%4)==0) printf(" "); + } + printf("\n"); +#endif /* convert bitfield into HID Report format */ - buf[4] = 0; - buf[3] = (src[1] >> 2); - buf[2] = (src[1] << 6) | (src[0] << 1) | (src[3] >> 7); - buf[1] = (src[3] << 1) | (src[2] >> 7); - buf[0] = 0x05; // HID lights report id is 5 in Arduino firmware + buf[4] = 0; // hid report padding + buf[3] = ((src[1]&0x0F) >> 2); // right lamps + if ( !(src[2] & 0x0F) ) buf[3] |= 0x04; // coin blocker + if ( src[1] & 0xF0 ) buf[3] |= 0x08; // coin counter? + buf[2] = (src[1] << 6) | (src[0] << 1) | (src[3] >> 7); // button 9, top and left lamps + buf[1] = (src[3] << 1) | (src[2] >> 7); // button lamps 1-8 + buf[0] = 0x05; // HID lights report id /* send HID Report */ WriteFile(g_hid_handle, buf, 5, &bytesWritten, NULL); @@ -316,13 +326,13 @@ __declspec(dllexport) int __cdecl usbStart(int i) { return -1; } - /* read dip switches */ - uint8_t feat[2] = {0x06, 0x00}; - if (!HidD_GetFeature(g_hid_handle, &feat, 2)) - { - printf("Cannot read dipswitches (error %d)\r\n",GetLastError()); - }; - g_dip_state = feat[1]; + /* read dip switches */ + uint8_t feat[2] = {0x06, 0x00}; + if (!HidD_GetFeature(g_hid_handle, &feat, 2)) + { + printf("Cannot read dipswitches (error %d)\r\n",GetLastError()); + }; + g_dip_state = feat[1]; #ifdef FORCE_DIP4 g_dip_state |= 0x08; @@ -335,7 +345,7 @@ __declspec(dllexport) int __cdecl usbStart(int i) { #ifdef DEBUG printf("Managed to open device %x\n",g_hid_handle); - printf("Dip state is %x\n", g_dip_state); + printf("Dip state is %x\n", g_dip_state); #endif return 0; } @@ -360,7 +370,7 @@ __declspec(dllexport) int __cdecl usbWdtStartDone() { BOOL APIENTRY DllMain( HMODULE hModule, DWORD fdwReason, LPVOID lpReserved - ) { + ) { if (fdwReason == 1) { //https://blogs.msdn.microsoft.com/larryosterman/2004/06/03/little-known-win32-apis-disablethreadlibrarycalls/ DisableThreadLibraryCalls(hModule);