{"id":34677,"date":"2018-03-22T10:09:25","date_gmt":"2018-03-22T01:09:25","guid":{"rendered":"http:\/\/kako.com\/blog\/?p=34677"},"modified":"2018-03-23T18:06:39","modified_gmt":"2018-03-23T09:06:39","slug":"nintendo-switch%e3%81%aejoycon%e3%81%aehack%e3%82%92%e8%a9%a6%e3%81%97%e3%81%a6%e3%81%bf%e3%82%8b-%e3%81%9d%e3%81%ae2","status":"publish","type":"post","link":"http:\/\/kako.com\/blog\/?p=34677","title":{"rendered":"Nintendo Switch\u306eJoyCon\u306ehack\u3092\u8a66\u3057\u3066\u307f\u308b \u2013 \u305d\u306e2"},"content":{"rendered":"<p><a href=\"http:\/\/kako.com\/blog\/?p=24397\">Nintendo Switch\u306eJoyCon\u306ehack\u3092\u8a66\u3057\u3066\u307f\u308b<\/a>\u3001\u3068\u3044\u3046\u8a71\u306e\u7d9a\u304d\u3002(\u524d\u56de\u304b\u3089\u968f\u5206\u3068\u6642\u9593\u304c\u7a7a\u3044\u3066\u3057\u307e\u3063\u305f\u304c)<\/p>\n<p>\u524d\u56de\u306f\u30dc\u30bf\u30f3\u60c5\u5831\u3092\u8aad\u307f\u53d6\u308b\u3060\u3051\u3057\u304b\u3067\u304d\u3066\u3044\u306a\u304b\u3063\u305f\u304c\u3001<a href=\"http:\/\/kako.com\/blog\/?p=24599\">\u6d77\u5916\u3067\u306f\u89e3\u6790\u304c\u9032\u3093\u3067\u3044\u3066<\/a>JoyCon\u306b\u5185\u8535\u3055\u308c\u305f\u52a0\u901f\u5ea6\u30bb\u30f3\u30b5\u30fc\u3084\u30b8\u30e3\u30a4\u30ed\u30bb\u30f3\u30b5\u30fc\u306e\u5024\u3082\u8aad\u307f\u51fa\u305b\u308b\u3089\u3057\u3044\u3002(\u524d\u306b\u898b\u305f\u3068\u304d\u306b\u306f\u89e3\u6790\u304c\u305d\u3053\u307e\u3067\u9032\u3093\u3067\u3044\u306a\u304b\u3063\u305f\u306e\u3060\u304c\u3001\u6700\u8fd1\u30c1\u30a7\u30c3\u30af\u3057\u305f\u3089\u51c4\u304f\u89e3\u6790\u304c\u9032\u3093\u3067\u3044\u308b\u306e\u3067\u9a5a\u3044\u305f\u3002)<\/p>\n<p>\u6d77\u5916\u306e\u60c5\u5831\u3092\u53c2\u8003\u306b\u3001\u6614\u4f5c\u3063\u305f<a href=\"http:\/\/www.kako.com\/neta\/2006-019\/2006-019.html\">Wii\u30ea\u30e2\u30b3\u30f3\u7528\u306e\u30bd\u30d5\u30c8<\/a>\u3092\u30d9\u30fc\u30b9\u306b\u6539\u9020\u3057\u3066\u4f5c\u308a\u76f4\u3057\u3066\u3001JoyCon\u306e\u30dc\u30bf\u30f3\/\u30b9\u30c6\u30a3\u30c3\u30af\u3068\u30bb\u30f3\u30b5\u30fc\u306e\u60c5\u5831\u3092\u30ea\u30a2\u30eb\u30bf\u30a4\u30e0\u306b\u8868\u793a\u3055\u305b\u308b\u30bd\u30d5\u30c8\u3092\u4f5c\u3063\u3066\u307f\u305f\u3002<\/p>\n<p>\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u306f\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u306a\u3063\u3066\u3044\u308b\u3002(zip\u30d5\u30a1\u30a4\u30eb\u3067\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u3068exe\u30d5\u30a1\u30a4\u30eb\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3067\u304d\u308b\u3088\u3046\u306b\u3057\u3066\u304a\u3044\u305f)<br \/>\n<!--more--><\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n\/\/ JoyCon Test  version 0.1   Copyright(c)2018 by E.Kako  \r\n\/\/   This version supports JoyCon-R only.\r\n\r\n#include &lt;windows.h&gt;\r\n#include &lt;process.h&gt;\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;conio.h&gt;\r\n#include &lt;string.h&gt;\r\n#include &lt;time.h&gt;\r\n\r\n\/\/ for tiny_hid_dll\r\n#define FUNC __declspec(dllimport) __stdcall\r\nextern &quot;C&quot; HANDLE FUNC OpenHidHandle(unsigned short vendor_id, unsigned short product_id);\r\nextern &quot;C&quot; void FUNC ReadReport(HANDLE handle,unsigned char *InputReport,int *len);\r\nextern &quot;C&quot; void FUNC WriteReport(HANDLE handle,unsigned char *OutputReport, int *len);\r\nextern &quot;C&quot; void FUNC CloseHidHandle(HANDLE handle);\r\n\r\nHANDLE hRsDevHandle;\r\n\r\nconst USHORT VID = 0x057e; \/\/ Nintendo\r\nconst USHORT PID = 0x2007; \/\/ JonCon - R\r\n\r\n#define MAXREPORTSIZE 256\r\nint\t\tInputLength,OutputLength;\r\nunsigned char\tInputReport[MAXREPORTSIZE];\r\nunsigned char\tOutputReport[MAXREPORTSIZE];\r\nint packet_num = 0;\r\n\r\nunsigned char\tjoycon_loop_flag;\r\nunsigned char\tjoycon_in_use;\r\nuintptr_t joycon_th;\r\n\r\nunsigned char\tres_type;\r\nunsigned char\tbutton1,button2;\r\nunsigned int\tStickX,StickY;\r\nunsigned int\tAx,Ay,Az;\r\nunsigned int\tRx,Ry,Rz;\r\n\r\nvoid Sleep2(int msec)\r\n{\r\n\tLARGE_INTEGER f; \/\/ for hi-res. performance counter\r\n\tLARGE_INTEGER t1,t2; \/\/ for hi-res. performance counter\r\n\tdouble t;\r\n\tQueryPerformanceFrequency(&amp;f);\r\n\tQueryPerformanceCounter(&amp;t1);\r\n\twhile (1) {\r\n\t\tQueryPerformanceCounter(&amp;t2);\r\n\t\tt = (double)t2.QuadPart - (double)t1.QuadPart;\r\n\t\tt \/= (double)f.QuadPart;\r\n\t\tt *= 1000;\r\n\t\tif (t&gt;(double)msec) { return; }\r\n\t}\r\n}\r\n\r\nvoid cmd_0x01_parameter_set()\r\n{\r\n\tOutputReport[0]=0x01;\r\n\tOutputReport[1]=( (++packet_num) % 16);\r\n\tOutputReport[2]=0; OutputReport[3]=0; OutputReport[4]=0; OutputReport[5]=0;\r\n\tOutputReport[6]=0; OutputReport[7]=0; OutputReport[8]=0; OutputReport[9]=0;\r\n}\r\n\r\nvoid Report_subcmd_0x30(unsigned char data)\r\n{\r\n\tcmd_0x01_parameter_set();\r\n\tOutputReport[10]= 0x30;\r\n\tOutputReport[11]= data;\r\n\tWriteReport( hRsDevHandle , OutputReport , &amp;OutputLength);\r\n\tReadReport( hRsDevHandle , InputReport, &amp;InputLength);\r\n}\r\n\r\nvoid Report_subcmd_0x03(unsigned char data)\r\n{\r\n\tcmd_0x01_parameter_set();\r\n\tOutputReport[10]= 0x03;\r\n\tOutputReport[11]= data;\r\n\tWriteReport( hRsDevHandle , OutputReport , &amp;OutputLength);\r\n\tReadReport( hRsDevHandle , InputReport, &amp;InputLength);\r\n}\r\n\r\nvoid Report_subcmd_0x40(unsigned char data)\r\n{\r\n\tcmd_0x01_parameter_set();\r\n\tOutputReport[10]= 0x40;\r\n\tOutputReport[11]= data;\r\n\tWriteReport( hRsDevHandle , OutputReport , &amp;OutputLength);\r\n\tReadReport( hRsDevHandle , InputReport, &amp;InputLength);\r\n}\r\n\r\nvoid Report_subcmd_0x48(unsigned char data)\r\n{\r\n\tcmd_0x01_parameter_set();\r\n\tOutputReport[10]= 0x48;\r\n\tOutputReport[11]= data;\r\n\tWriteReport( hRsDevHandle , OutputReport , &amp;OutputLength);\r\n\tReadReport( hRsDevHandle , InputReport, &amp;InputLength);\r\n}\r\n\r\nvoid Joycon_mode_0x30(void)\r\n{\r\n\tReport_subcmd_0x03(0x30); \/\/ standard full mode\r\n\t\/\/ respond automatically (interval = ??)\r\n}\r\n\r\nvoid Joycon_mode_0x3F(void)\r\n{\r\n\tReport_subcmd_0x03(0x3F); \/\/ button ONLY Report Mode (HID gamepad mode)\r\n\t\/\/ respond when button changes only\r\n}\r\n\r\nvoid Joycon_IMU_enable(void)\r\n{\r\n\tReport_subcmd_0x40(0x01);\r\n}\r\n\r\nvoid Joycon_IMU_disable(void)\r\n{\r\n\tReport_subcmd_0x40(0x00);\r\n}\r\n\r\nvoid JoyCon_LED_on()\r\n{\r\n\tReport_subcmd_0x30(0x01);  \/\/ set LED data  0x01 ... LED1 on\r\n\t\/\/ 0x01 = led 1(top)   ,   0x02 = led 2        ,  0x04 = led 3        ,  0x08 = led 4\r\n\t\/\/ 0x10 = led 1 blink  ,   0x20 = led 2 blink  ,  0x40 = led 3 blink  ,  0x80 = led 4 blink\r\n}\r\n\r\nvoid JoyCon_LED_off()\r\n{\r\n\tReport_subcmd_0x30(0x00);  \/\/ set LED data -&gt; all OFF\r\n}\r\n\r\nvoid Joycon_Haptic_enable(void)\r\n{\r\n\tReport_subcmd_0x48(0x01);\r\n}\r\n\r\nvoid Joycon_Haptic_disable(void)\r\n{\r\n\tReport_subcmd_0x48(0x00);\r\n}\r\n\r\nvoid JoyCon_Haptic_test(unsigned char d1,unsigned char d2,unsigned char d3,unsigned char d4)\r\n{\r\n\tOutputReport[0]=0x10;\r\n\tOutputReport[1]=( (++packet_num) % 16);\r\n\tOutputReport[2]=d1; OutputReport[3]=d2; OutputReport[4]=d3; OutputReport[5]=d4;\r\n\tOutputReport[6]=d1; OutputReport[7]=d2; OutputReport[8]=d3; OutputReport[9]=d4;\r\n\tWriteReport( hRsDevHandle , OutputReport , &amp;OutputLength);\r\n}\r\n\r\nvoid JoyCon_Haptic_off(unsigned char d1,unsigned char d2,unsigned char d3,unsigned char d4)\r\n{\r\n\tJoyCon_Haptic_test(0x3c,0,0x2f,0x40);\r\n}\r\n\r\nvoid Joycon_Input(void)\r\n{\r\n\tint l;\r\n\tReadReport( hRsDevHandle , InputReport, &amp;InputLength);\r\n\tres_type=InputReport[0];\r\n\tif (InputLength == 362) {\r\n\t\/\/\tbutton1=InputReport[5]; button2=InputReport[4]; \/\/ JoyCon-L\r\n\t\tbutton1=InputReport[3]; button2=InputReport[4]; \/\/ JoyCon-R\r\n\t\/\/\tStickX = InputReport[6] | ((unsigned int)InputReport[7]&amp;0x0F)&lt;&lt;8;  \/\/ JoyCon-L\r\n\t\/\/\tStickY = (InputReport[7]&gt;&gt;4 ) | (InputReport[8] &lt;&lt;4 );\r\n\t\tStickX = InputReport[9] | ((unsigned int)InputReport[10]&amp;0x0F)&lt;&lt;8;  \/\/ JoyCon-R\r\n\t\tStickY = (InputReport[10]&gt;&gt;4 ) | (InputReport[11] &lt;&lt;4 );\r\n\t\tAx=InputReport[13] | (unsigned int)InputReport[14]&lt;&lt;8;\r\n\t\tAy=InputReport[15] | (unsigned int)InputReport[16]&lt;&lt;8;\r\n\t\tAz=InputReport[17] | (unsigned int)InputReport[18]&lt;&lt;8;\r\n\t\tRx=InputReport[19] | (unsigned int)InputReport[20]&lt;&lt;8;\r\n\t\tRy=InputReport[21] | (unsigned int)InputReport[22]&lt;&lt;8;\r\n\t\tRz=InputReport[23] | (unsigned int)InputReport[24]&lt;&lt;8;\r\n\t} else {\r\n\t\tprintf(&quot;%d\\n&quot;,InputLength);\r\n\t}\r\n}\r\n\r\nvoid Joycon_Input_Main(void *)\r\n{\r\n\t\/\/ Joycon input thread\r\n\twhile (joycon_loop_flag) {\r\n\t\tjoycon_in_use=1;\r\n\t\tJoycon_Input();\r\n\t\tSleep2(16);\r\n\t}\r\n\tjoycon_in_use=0;\r\n\treturn;\r\n}\r\n\r\nvoid Start_JoyCon_th(void)\r\n{\r\n\tjoycon_loop_flag=1;\r\n\tjoycon_th = _beginthread( Joycon_Input_Main , 0 , NULL );\r\n}\r\n\r\nint JoyCon_th_check(void)\r\n{\r\n\tres_type=0;\r\n\tSleep2(100);\r\n\treturn (res_type!=0);\r\n}\r\n\r\nvoid Stop_Joycon_th(void)\r\n{\r\n\tjoycon_loop_flag=0;\r\n\tSleep2(100);\r\n\tif (joycon_in_use==1) {\r\n\t\tTerminateThread( (HANDLE)joycon_th , -1); \/\/ kill thread  if it stucks\r\n\t}\r\n}\r\n\r\nvoid MainLoop()\r\n{\r\n\tunsigned char c;\r\n\twhile (1) {\r\n\t\tif (kbhit()) { c= getch();\r\n\t\t\tif (c==0x1B) { break; }\r\n\t\t}\r\n\t\tprintf(&quot;button=%02X,%02X , stick=%04X,%04X , Acc=%04X,%04X,%04X , Gyr=%04X,%04X,%04X\\n&quot;,\r\n\t\t\tbutton1,button2,StickX,StickY,Ax,Ay,Az,Rx,Ry,Rz);\r\n\t\tSleep2(16);\r\n\t}\r\n}\r\n\r\nint main( int argc, char *argv[])\r\n{ \r\n\thRsDevHandle = OpenHidHandle(VID,PID);\r\n\tif ( hRsDevHandle == INVALID_HANDLE_VALUE) {\r\n\t\tMessageBox(0,&quot;JoyCon-R not found.&quot;,0,0);\r\n\t\treturn 1;\r\n\t}\r\n\tJoycon_mode_0x30(); \/\/ joycon standard mode\r\n\tJoycon_IMU_enable(); \/\/ gyro acc sensor enable\r\n\tJoyCon_LED_on();\r\n\tStart_JoyCon_th();\r\n\tif ( JoyCon_th_check() ) {\r\n\t\tMainLoop();\r\n\t} else {\r\n\t\tMessageBox(0,&quot;Joycon-R cannot open.&quot;,0,0);\r\n\t}\r\n\tStop_Joycon_th();\r\n\tJoyCon_LED_off();\r\n\tJoycon_IMU_disable();\r\n\tJoycon_mode_0x3F(); \/\/ HID mode\r\n\tCloseHidHandle( hRsDevHandle );\r\n\treturn 0;\r\n} \r\n\r\n<\/pre>\n<p>download: <a href=\"http:\/\/www.kako.com\/zipfile_here\/joycon_test_v01.zip\">joycon_test_v01.zip<\/a> (12.6kbyte)<\/p>\n<p>\u307e\u3060\u4f5c\u3063\u3066\u3044\u308b\u9014\u4e2d\u306a\u306e\u3067\u3001JoyCon-L\u306b\u5bfe\u5fdc\u3057\u3066\u3044\u306a\u3044\u3068\u304b\u306e\u672a\u5b8c\u6210\u306a\u90e8\u5206\u3082\u3042\u308b\u306e\u3060\u304c\u3001\u3068\u308a\u3042\u3048\u305a\u516c\u958b\u3057\u3066\u304a\u304f\u3002<\/p>\n<p>&#8212;<br \/>\n\u8ffd\u8a18<br \/>\n\u898b\u76f4\u3057\u3066\u307f\u305f\u3089\u3001\u95a2\u6570\u540d\u306bJoyCon\uff5e\u3068\u66f8\u3044\u3066\u3042\u308b\u3082\u306e\u3068Joycon\uff5e\u3068\u66f8\u3044\u3066\u3042\u308b\u3082\u306e\u304c\u6df7\u5728\u3057\u3066\u3044\u3066\u30c0\u30b5\u3044\u3002<br \/>\n\u3042\u3068\u3067\u76f4\u3057\u305f\u3082\u306e\u3092\u516c\u958b\u3059\u308b\u3002<br \/>\n\u2192 <a href=\"http:\/\/kako.com\/blog\/?p=34685\">\u516c\u958b\u3057\u305f\u3002<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nintendo Switch\u306eJoyCon\u306ehack\u3092\u8a66\u3057\u3066\u307f\u308b\u3001\u3068\u3044\u3046\u8a71\u306e\u7d9a\u304d\u3002(\u524d\u56de\u304b\u3089\u968f\u5206\u3068\u6642\u9593\u304c\u7a7a\u3044\u3066\u3057\u307e\u3063\u305f\u304c) \u524d\u56de\u306f\u30dc\u30bf\u30f3\u60c5\u5831\u3092\u8aad\u307f\u53d6\u308b\u3060\u3051\u3057\u304b\u3067\u304d\u3066\u3044\u306a\u304b\u3063\u305f\u304c\u3001\u6d77\u5916\u3067\u306f\u89e3\u6790\u304c\u9032\u3093\u3067\u3044\u3066JoyCon\u306b\u5185 [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[7,14],"tags":[],"_links":{"self":[{"href":"http:\/\/kako.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/34677"}],"collection":[{"href":"http:\/\/kako.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/kako.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/kako.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/kako.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=34677"}],"version-history":[{"count":7,"href":"http:\/\/kako.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/34677\/revisions"}],"predecessor-version":[{"id":34688,"href":"http:\/\/kako.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/34677\/revisions\/34688"}],"wp:attachment":[{"href":"http:\/\/kako.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=34677"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/kako.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=34677"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/kako.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=34677"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}