From b3caca09a71e2c5f4e131a6593a5c7fa232f0ccc Mon Sep 17 00:00:00 2001 From: Vegz78 <> Date: Thu, 16 Dec 2021 15:25:59 +0100 Subject: [PATCH] Recalbox 8 support -Upgraded uinput-mapper to Python 3.x support in addition to old Python 2.7 support -Saved game data/states from settings and DB extensions should work with new launch instead of /tmp on Recalbox 8 -Small fixes/improvements to launCharc -Automatic installation script, systemlist.xml and alsa hack for Recalbox 8 coming soon -Porting to comined support for Python 2.7 and 3.x in uinput-mapper is not tested exetensively and might have introduced instability/regressions. Please report in a new issue here if you experience problems! -When running McAirpos with uinput-mapper for the first time on Recalbox 8, remember to set / writable(mount -o remount,rw /), so *.pyc files can be written for faster Python execution. --- McAirpos/launCharc/launCharc | Bin 33928 -> 21480 bytes McAirpos/launCharc/launCharc.c | 37 ++++++++++---- McAirpos/uinput-mapper/input-create | 23 +++++++-- McAirpos/uinput-mapper/input-read | 22 ++++++--- McAirpos/uinput-mapper/uinputmapper/cinput.py | 42 +++++++++++----- .../uinput-mapper/uinputmapper/ioctlhelp.py | 3 +- .../uinput-mapper/uinputmapper/linux_input.py | 24 ++++++--- .../uinputmapper/linux_uinput.py | 8 +-- McAirpos/uinput-mapper/uinputmapper/mapper.py | 46 ++++++++++++------ 9 files changed, 143 insertions(+), 62 deletions(-) diff --git a/McAirpos/launCharc/launCharc b/McAirpos/launCharc/launCharc index d14823592e3792a2f232a96b77a68daa3e7e6d70..421455c53c8fb6f20ffc316bd2dc734995a5c1cd 100755 GIT binary patch literal 21480 zcmeHv4Rln;m1eahun@wMK?YgK){87Kw$(r4$7nFN1qdt_Fa)s28RN8C-A_`7R(Gf0 zYY+}j2qqbiLu?X=<5@dV&#WgWlX%V{8)t@OY_H;E5{{Qi*ok*1KaNK~ycwb}871p+ z@CIA^eXm}%N)M4RyP4fHXDGO;x^-{ex^=7SR@Hm2>qF}|ZwLeeLWL5sL=dyf17bPi z&aL=UCT1)bhL{D~^`f5i>}n8KFAum-4i-Y02Qv|~>~e4t3=|+JdMRi-f$v1UgzJD4 zNJq8{h`dxlbU+wkhL=a4>bnRfE*wC{IDqxCbP4{}f?f+c;Vf_h=}Lzz__L^+(2jh9 zqP^R(6F@HtEME=S4!U0dIPwTAPu;?)WLG$q2&R(he19;O>+9_fS((r>kX#G0kbgjkZB+OmSY3X~rVUw+VK!inn-bz`#MJ9rz$|hwzTwSX)&Jwz(fY!`pH`i3zW=4Y&XfD2Padtm<^#{{KaxK<=c5Of zR6p<^Z?Bp-cc^A&*siLm`pTc|HXp2+Kep$co3B4ykE*AHA8MF^G(m;ANN~8SK>Vaa z5EF0k;UDzjxA}0|NClQBsKE45g&-#WXFmKXAHLRyclhx4`S5}df4>j!_u>D=hqw6f z&-w6XA0GGNt9|%xAHK+kKj_0bj#Qw1KB5rB#1H%M`+y&5D{<$+H5`SQOL5Mg+eCMF zDsS})vp;DIE1OHE?QYSX$(m`AHFLR4PGs}8g`C`O5$nq2Y>{<|-909 zU<~Kb#28Lt31c{uX2x(15yo&z%Ne6nTN%TNtY(Y})W#Ujvz;;O?_dlEwwduPcqztk zKsy;%3UNQxJrlw<60ql8N*4Y7{ftj8N*Z9j4OobXMB|q`x#?lIl%aO z_`SB^PtrpCwEVz}XUm3yPTA0abM?>@L*?TyIpKB=V#we$%seOya_UP~9W^ix{;h?ag-OCQkE{aQM!rF*q>rd%~+V-$wV4D^KvI@N;%PT644sT2cF zWn{p4X=381V}J{d0a0EN5YHg4L4J)f;FLz57%DN2{sUIy(Hkbhfv-+XjJ2%{h(j3b zwJ2W;J|T7tlU6O$F5kR~@bD3g2LeMAc$=!hTfJsz%{7JLKWg~!(ATSv|Hg9F7)!Nn zC>ME^^^8^@c(HZ}x&|U>TjZM#@UzEI$KOLQ(GmPf+3}B$RG;25QY~gX2?IRUg;5)I ze+Ff;sJ~h)bP7n9gI*q4=*q+puDhSQM~*u4Q6_*gn^7jkdPHILAYvg3!{x?8CjlDU zav$>|g<{`Wpk{0%8Mk7CKf#$33ra8L5Px z*{fzd_JY~Yb9W6mk;rUk{au?zPI`J%P6je(-LYw8Q&_fzdGABs%RW96d4Gkx3axA> z^0F%zIwjDNZM2ati##$SjH3?AmsA&qDQ^Y%FuljfTMAyd2$#2f8s1yLtIJ`XO3sa- z!Oaxqpyywq%m8GH)_95Bu)*8Dfk&%$l=l1bs50|1n{lNeJoyop|d#hu82n@3n;`p5#B4L`>a7}Z{;O6OTy@>aJLNd)2s1wDEP_48uOD#6=L|UC zATQd~jJ_7eBhCfLd$*?hIPkyF zeG5FC51&C?Un<5DUR!CydQZ-apk?mdG*T8>H&PBzbC7jVPxf0q`eM9tz?rMs4%)XR zZ8(52*9v;MC%YAM?qt2x@pItWkVtw7Fm)e`oW6^CWElG4Nqo9rM$dd-O*@*Xv+ge}uf%=&RN2tH}3U zKl5qyC-tJwn1TA5?vP{UTIfWdb9VNCvlZnkncsHQ@yn$B>2qc@Lr-I^3nv!Bm!rNY zXe(fw8m)buUY-FP9s?isdLQ!i{$bu0Pj0CJf1~wXN#v2C&RbD#s4!eISQxGnFPs(P zai^^Mai`pP9BaqpXxnQ}b>usaUT#Hba?ajB*=_KLqAq?sn^L{{_pfU|MsL_b5uRh%dWdvuRUmwvUhzo#uaofZK3Xu3^6W^ z930Z^UIKZ)u}s^+A=>0;)PwR+_Zv4~UYpp@^gk^BEtGf1I_3@M6~`^-5a$8=y%l(= z*gm{!V&ZFYuW$9W~b1Y^Bp^&$1=3=OFAk#5wm8=G_Z~D(%7XQ6UPWyHStwIXE)Z>GtC~U-0-No)0>F)qoR1nMb|+r@j1s zH;s$WqWi9d! zYX18!pU$_V&(E#&>hkPOzfKuL^9LO2c8YZD<=T*U8hMnv0QtHPVO|yTR3GRx_Q5lY zy*_|luM%IL(g!+kTQ%obVff62i{<|kd6$x3Nxh7z{!iJW#?yHM<GcxwIaaCT_cVQ&$9A4zc~6g0x19$u)(*OJtUU6vgX3#)EyYo_ zF3Y;v&pzARki)uE8@73ReFu5;1FfFUjox_bm@(iS1I_UA@AdMZMgHT+=Qw)=@vll` z{q#rQ7UG9$y>5jr`ut@3o(8|Nw@za_Uuzn0N(SL)w-tsXorgze3>Ahe+c>|Tzi3UX z9y~l!z3n3-GsUjqH?X&Nd5hy30Jz=;^55XeV1M6n9w%5)Za2h4=XcN{t__nbo_@jrbc8ucD#t%;} zlXE2KjjMAd1J3zhP5kt@m#@a#^3nn47s!ucoUuIDPRbhu|NE3KTyG-r5$fbjOjLXx zv^Z$(Sda8M*Y5d(VaQW+?oFiCm{fBv)d<@RqW_CyYSO=RZL5SIM;perLt|R4O!%W9r+QoA*s#F1j-5QD{0psgRbkEyn1r4d*)pO?z#5Afk(|RoEPd& z2L_z4Ay1b{SzkdO+eCZdu~XeH>I0vk%l|IU1jnu!aK5U^>nsOJ+J z-`fFE*NMERSr6)aD1dIckZV8A8 z;C{eiz*B%{0jB^Rx8k`B-~yn(8To)$0j)vk0eAs01SksyL_MGr@EqWqfU|(=Fk}PT z0owpJfX{CVh))8}0BRxu(F-^N7)PChh))B~1DaZ(C*Tm^^MG#x48S;`bt&otWC5=N z+Lr~ye!w8?^L@Y>KqVeZui7NUd8F4PegX8?01>?Z;`5UN@?ATN2B!vn@NA^PUFSI_ z|LK2C{4}WbRTll30N*|@kNuei{&(P0W5s{Io&jF}`MQ8IXHbS?=}Q=gJYPRo-Qb?D z$23_yUk`%!2gu{u`#Q){V++qj>io}Z-U1(=IlNr8X{7gE4bDl-)1M=cd~DBIPjMtFF zKN_6=j8}?tUp3BsH8}SjkGwW~qUAeoS?c+pA+G~|umisHiOLJ^-7Z@pRqp`GZtRgY$9F@a}T#2e5~}FaIL)b$_J$xMx8_-;OrJ zKRkRFp5Y;e{}_Eg@|!*1P8wzE{_p#Z4X*$D1o^OM+zeixnYfM|SSsxp_H+}a4Nf=s zp7QdQ53WIeC-T1wzpw=5y?&_E_lg{Yt>C*oAc|uUkI^eOqfY9_I&gr>S-x0BsO7j_Ds@EcM@rxq-3tUgm+H{!_OX`)s|(PaXdp`y0PKPD2Kt zb8Z2j?$eh-AGMxPAHUqsdU7pqZK=ewl=7wqXDMW@0`1f?ITl!-E&x0l~{@gOqi+S@X1M3y_ zQhT@mj&jOR;8jRP|FQ?%KE;@>IJR82gEI7XTtGYCMmao78av_f=(=;x)nD7-ya67T zWq&PMB>RhcCcHXMqfemM=r@q3Y(hOZc)C+h_A&F$Xywq~6@z#VzI=t$&tLZu)XjG3 zb5XbTtDq^LV$W!BjsaITfDfzC<>}AD&Y%tKi?4$p_8GerU-@Fm_ZL1L*p340^2V#u z;XHJ(G#zMrUPd-a6Sn-=Fr$Kq@O^Vw%2*G$o~W6!#|JpBmGgN_apwFh}kyI z$wz^|$HO@%8c`3%Nb$Mrhd}eM3nx(Ky~yW$4p@!x;3T(seNW!oV<XZgP*A>%#lx2aN~9*_hoMwliU{#u8>v ztj`RYsqP0wSIjcgz>Gzfh^NdL>(9Fx!I-h%uye*u{I@H86R@6~nKibrU$zIu5}`IA_LVsjf_a*n+NRxGR&f_aqZ$#tQevcAN1` z!VE879PjPRB#c}8FN+=Oig4b_g}ajJaCg_9rAD|n(`SaW$?%r=nq)2u*^>!WvW}H( z@eZflJdMsN-ObYQNh%$#)xz5~g< zU!$)ieHnFKf8QM~OCymMm5wm28oAb3O2$?rxZb#FTkk&WjwN}kYuAojcgdPtR<-P( zk`dYeKrHysn&9t6g1__N2bMm(WYtvs<`1lRICRU+?B;2_f$Y9t-|zn(+TZIA!s*BT zCV1pbESJEF#7t zK4;3=jWXNdye&AK+&;tZHH}8snKZ)t*vU-Vz@VBeV}z}Qw-AKl-97LW>3l4e+7~i5 zb{m$RkMC|avQnHow@|t3#9~IyOvT`gjHG4dO#{Qa*S53Ps&KdmZYbXs!dex+&+K_< zW$UERtWfR2bS$<0OMksLmr3_D8~k7ld9ru@b*zeSqJGVicWFnt z&Iq;}V*jsOFQ+RU$560MBZ%TVF2AfCrFJpyPIUXXdy#x*<2TL6E-AMT^P4PZr`!< zJXaX+HRHPtZhYxJ-R~$3>>B#uyx_T#WF?5skps^l&NExChx>!#PUesZ66BtbP z!?)t2(42t{jS1(Ox3V%xTd6g{-9u*k?O-;Um}a{veD-p!#ciioL}V?l=-vXK&8P6i zs8IWCV+Hma$y5sd+i*#-d?J~-xE6QTT@EAkzMSnkH$be#zdiQ0(A>lBjajZA#AxV} zi&EY)v6SS{=bTB&bdc+T^!FF{8Ri?i!|XTXdE4Dg`#X=Nqun?w@hIamPwl&+{oTFS zA}h>Eez9r9v~#^XiON|61{=$pmSt>gcL%uMpX}#~cJwPZ|85zszEsN4+1zqPeYDP< zX3D{K+Sr+*JI^Q6l_;)#I54I;eW-X*ZO%ZflE$`;?RTj4H7mEoY0k1sNp;JiuQ;>m z3yTuaX2_CFcDE{=O5|=<&QeYw_v9gYEgOS$+7hm+TrbVUT@^byKhrqJpbf<%i|1mC z<2?9&YJKU!r-r%LG`-xE<>XQljKzx$B?EQIGVV_3QYGLIxT;-L$XmBARg4u)U+_27 zHaX{~G|25pO?gdod9wBCIc?!73SA^&${BX;j!kQQXIS5veDdJ$e$@`oVrB9wEO5mFS1fSF0#__>#R69> zaK!@uW-ZV;3*Q6*xUVJPTMKb+X2AWObTz)8;_uY?yK{W+>i$NRzmcv1&L1k{ov8Td zcP28=2LfUS(uJ~s`s1W5EBVfxnMe;XK;;{{vM0jPG8zZk4fQ zd(6sqC1Yu$HMA@g3Ep;VE}Lw*Sz=;M2z)U!)|C{2CM0LvCT7ko56lWwl*}!g7pMtb z8(2_U8@Mh|S5hBnyo5=3?*K!o+spDU0EtU`94XTA1 zEdfHPz9m}Mvx zyfHwCM~gVVUPDm7uPk*(vYX}pDaEfd^-zi#B{h?|W#Z=(9Z2$C1{q4kCM0+tg$#29 z>8d@P6~v$Q(N+6}sB-B_Ki+O|k0*%{>!bYRTKP|DcnM}c<)6~%&!yH$X!d3ZQ8odFm{B0{s1kk^fM;|D|Jb}+Ki+DiHbLG>o$}mUVhor)leEL)w z=87)R6;97b`K(Wd1>(a>6f)F!;cr=GsB-H|X!WuDc@6(KSo!-`zFeaIY(IZrEQ9Rt zSFfAIN#DG15~nRbCX^Gv}i5!TQzw zo$h^;<4zL_ruuA97TK-J%f`g1<|pAlapGg;puBq!^iFFppGq zR$#<2gMq90Keyy+@f_)zyc0hDSA6)7efU55@PJ%`Se;wnT+Lq9uvdeR9`@mzefWDd z+$WdAJ?btHI!@|%Hkz8}L#V# z4u!n`(~;vjyCswnO$pHy`)vqILKr?GOGWpZvE9+`^lw9Enlf`XK6&Ww4#h>n%$Yq& z+`f{F+I>;nzmhgBT$z%{M0--1u2?FXuroO;8q4ZrFg& z(xN-ptlhkxBHXKG;#S^m32;`0`f~BUY+IXttxT6?6>pVs@5j-}-6`)Lohg~TB1g}V zSK{b7Q8N*wrD=JMS(^0%WP0;$d zR7hv=t_9Mww4UQAC|(Jq^T=z7^qil1`L2Bv}XI35MFpD`bEg>m0m!yO9vp?RT@HLeaSc~%s`M7fX)#7){0+< z3RhgrwsXm@ybXtS`GL<9xa@H$=Ghd#F>#+YC<$t}bt5u(q9mWZzfK4PX%*Dcflp_P zd_2n@fq*8(gjn&lBmE|x9Z(+6xX**{9MbYsEBVOFGt+DU`3fcYjTjREo_47ldAPsB zPo;1s^!V`nqX2?_z9BEedjWiQK`}flKZXk1kXH42;>B*{@mU9Po}o{H!9ZHC7pQm$ zz>_rjc(y(VKI)_7QNMD)BLMQP1@O#$0Sx0vlaD7^#djEK>dJb!R-Z$H&w^ASAH(kh z6rX%{g72zSBS9k{;gcF4_cAt=d4>;d1l}}h>C`+ zVtc=hG@m?>k7tjXOYnUUblRAF^1jB&yBd+@%47Rq1F*g1bI&GiI5RNq1?oT;1}HwB zDIRT`-hTf8KFXy$?$wTfFN?Gas!f~=lo#;`y&q z5ZRC+8j%+R)00b?f+_}=40}Pih`@Zwcj0dd_$A;ooB_^2zP2#}`3Ul6r~{or^HwEe zL7*SIn7#;MHTcf_&x6Lm^t7$2qkUslN3f!!Jsj_;2y}P0wNysCDz61g%1{U8ZeF>T zB*FTi&Ah0i7=bkMf9Rfa_THC2DwtjTm~Y&fz4z{0v@~z z8?3TkYrlJP8}#=IccTzK@d{kcUu!FalvD0x#M$8etql2?E=r6k#HQh47^Po*8+eeBH}il8>6-j7GT=0FTyi4 zf|&ScGVl`__;VTf^bCA&27Y}8o}YoU{`AHCmuUns@s~63zskVTa;b~*x27S>ROXr#M69BUCRU6D{&L_*!&UELxQk3~W0 z-XsDWySif{BAG}Q>*^3Kts!uMbRa=zs52UZmRPVW9uqA{*i0JLw={QjMME;PKuolE zHOD$cbZayg>J$;hYT44=9t$CrG9lU#3Ppt9-xG}?0gdb=O7s07b;tajf%Y&M5vq@d z?PPv`YiC#3mhg+48k6s&Y)?IKZp8y&c1YOZ-})VlV1?ECg8R z#gj39Aie^FMG<2RCdG^~xRfx)08`2sgNwx&onb0tI8GU33`FIO(W`xoF|f{NYza}r zc#IGW7-Jx;WsCu=jxm~fDPvgHz!(EyBV*Xr#2ACzI>zXX>lvdk8yFV~5oA18h&IL; zWIGsRAdN7dfccK`6+-kd#-O*IF`TlOajp=%7+)#GZpM=^_SROs`<7e$%G3MO8TUX% z(mjw!77jcx;5qkl^4T&N^!*1;kA8LU>1QvznAGr74)~x0e#imub-=qE@OB3rbHE)A zIOu@aJK!b<+~9!g9Pk1MJlg@6JK(7fxYPj`JKzEb>~_Ex-%r=Wc?bNS1AfN=pK`!& zIN;YD@G%Gcq60n*_}ncO?`EA^ak}8diqoRDf6!>`9}JA#clx;1KO~C!hu*q$=~u$n zKjackLx*Plc(BB`FIkEJ7tS+5+u{;=10xg3??BEF{X}L&;S5ma^^g-~pkS7|4ZZyP%z8e$C zzULB2;d>BaPjdI9M6yKeI~}%VZV+NZ;KqHYORRmTBj5?~Xp;HTChFM$eGejDk9fbG zMl|-1Sqb|aKOu;DLh1F;9b*ZS@bbY|nZVNmcg#p})Fx>1?11bp{%FZAcTe+wTbK=ySk# zLHBIfm}k?k0vGe_s+q&sn2(*J-!7ZLkgXXNcQ}{&?xqtD?7m=n?4fpuJhvo2l2=KX|bs zk$eRHMcR#^F)py%z$4ZS{_4`DJde12FoyOiLR*l3#3KO_2onk*Fe z{nA~uH(AvGS~3eZd#t_50^idUHVc z{TO=TgJNLE0A)vt7tb6yy6<$p*bBY)L+?*)z4t>e0`$IZ>wO<_G3x3ox#ob!g8%h> z`Lx-;W5Dd)@yo;2KO1!S?m?OMpiFyEradxWmi=9%JMtRJJ+Nm0^*va0sP{DU^@u$( z&wR0GK$S)1c^vZS3ulY^A5Yd-seaD-834VfRQ0O^fZ6v*KZd?_0{BO;Z9Vux+%u2> zPF}*a`%Q#?xn}4t^oO!WlppP0gZ7%*yDu55-FMpEoAnNTV0k*H@s6yv5L8 z1Nj9AwFq?xZt#nG?@N9cGKBvQ@u?rNth;1cRXKP4Qiy}e!@Z{lvyYxi%6b;}Cq>bt zNz~7f$5Q1!{KcOPUUBp%$^Q-=0{;0B$|Za!QJytJbKqw=R{!9xD_OorlV62Q4s2qc zn*p=^A3)spDe$fP2E@_+K~sF|jPSjVHl)w&Kp%P~8AKU4ZjLV8cX}`6-M;=o!n0>4 zl0ndSfu_fV`;jMkouIL<&!g@rpAS1cwjFWs{`sRzXD?1jBroPAk~P40{|#;2lk5k6 zBkLb_9soSk*7FY^UCI-%!-f1_1N{!tF;+qU^9JZILRXzFdzVW*ugmxh@?oE*Pq1Cq zLxy8&-!+M3{Uk+e0*$;{#M`0!2E>N1e+XlDvJdIm=5l<1O{|NWTC^uZEkYdv%Ue`? zUvdf3$+ktDZ`Y9z`LK?R+Ww*Wpig}?ku2`*AF@7&cv~WgWzpFYptG*9^vJt&WYf?# z#MD^|I>#UKgymBF!%`<{ZgQB+t6U zuX5Q2pkqE9;uypBAB(g@=r>ul7z+^R181MuJ)Z4x&%jTS-#pM=@U0V=$2bPkzm}t2 z>0?qS#1`(=M%A2?EkvO@1G&?kEP z2j4<`sw9!zhBAl<`|s|7XF%H~kPl#v87~26nqy3Zx^0E+9DAQeI`)$vgWkU`k?e0v zV7|m0(75*W>#&(=4xk?OoO%Iu+v~v`Od9mE?fa3I_4-}JZ8gw$6#Z(Te=x`HS9&Zi z@V$m|?M===-3s5M$r-TMKzr6e-(I9;yBtjBHCjdmmN%^AwCzCjtJcOzYu ztz)}QTWjO*q;N{c@S;$Oy z8u(_3KPv5{&STk$L&oz&n8#pzl!kx1l?RbZwx)AJ29G4go$4xjH+aX94?c z9q&M1_w@nLH;|6L{s*D@x^EoTBc!2x$F4}o@pOruwguw>+ks<30pxD9=_f8-`Wu0K ztAPI)HhAoH+-%@n)0K#Qr>g;f`NKk)~-vIbt-sl4^jJQvKaPf zS!jFM!9K;jnYJ5cXIpWecxbw6E4JG_@Mb|5$5YDI04LoAJs!x-0-fuRiw`G~W(4D1 zuj;Fmy#}(>=|+Ba%n!ag1+<{8k2cY^bw@EbL2fGak;ZYNU_<}l1n_EnKTBpG?H?@O z0KG`pVC_pbA~YcsSOxERj_ykq!7tgjbC7m2+Wgc-Ro;I$utq6Dxh*wzWZU{E`&;x) zH|U4QD!aJ$`T*%X@H39TLF8p3E&CAZ^qakIte*kXR@z7(BR@7RF%}`~KfxpZQ^dEh z%>aKFFw68EhbcXvJUW52ql6I9zyBddR59YeCx!nj!j!?m|2YdTBrBy*JE6@^Q+eFU+y~!m%-l zh)44YWTUjR+7H$DxR zbsI%|VHWs*V!aWCo`cX?2U*qw+EeDI>unc!-?MG-**3&Ly8-gF>oJ=a1Z|$JVoCa_L=`4G{0Zb9w%f15ZmTyyZv^cG;j!&!T~(zaaZH%fY%V~5gKM-uK?i)!fOcU7$D~XuLjS14k3OIVfG}*Bb-NY zTi_#4s=SIE643vhN_R1(~v$hS-HXP9Q#ZjUfu~AbAP$C<5&O z@-K%yJ&=DI;Z1}($m~Tpj8KAb5wtewI)L=2P^OE>yA-$&=`SEyEI0C84?TSdhiMmN z+F*YN;^PRjA@c_8oQ?e6KpJrfh>JllwlFXH9vE<0590o4^^o^cm9h4NOJ{5GfO0RMSC&Gi6gq@& z@jy1lT=4f7fyVKdvSTh)4L*kUWgGLFT7>zW@VW8va>g+w%d|kJNK5 zY$~dK=?tDroh`JdlrhY-uCb7aLHgs87ye z>~HV>QT3faa9##J2l5tlL|~VN{I9V49p|ZH(0>hijQk;emmyMuZJF4H&(coBA*>BmGT*LxbnO^pc17O7gjh@8Ngk7zdlUmS8#E z;?}|UVH4!eoEQxsK|oy(@|h~1r*a4Hra*f~C}_pHtnPT&YVPXn41|MuLd2ti*3f*b zBM=WSZVPlbTX%%JIs*}_%Gwm#x-q&%f}2C#8}U^BGu9ndkwC1iD%Mp6(LgZN8t4pF zhB{h4Bbqxxfo{}sJPeXm5wNyfv2JSy|E&+t0M^a6^?gwShH@JUM+-O zbg^Y7_91DF)>zrm)e1Xfv8|UaOt>p%1uSqOBXuf}^|P@f#CG8Bh!WTm=nl`flQIQ${M=rUhl=!WQY26(MU;(@OuEriH7UEREc(|U&uX3)QU%h=8!MFX6K*hF&6`%H1%=^q2 zX5Cpfe>i^i7p}Xr@|vsJ%$Mous`>tOyZ?Wo{B6<+FYovD7-72t-9dC5?NHL6)+}DQ z(!UsEz?$nFu8T?OCfPsGtL?rVwYs|HI87~44l2!E;gbVG^j`0=9X5B6ybQFqho8OwXDU8#^TMJ%B_e}C;JvM zmxEZq>JD`TFc?|w(P%tm!L8e3u}E}&RaGm7q4>s1%r{lHhFZ7Htx1ocdAdC4j;ZoE zi(qwy=jX9+ai*FU&0|+X->QskwWeQ9*shOs`e8L-Cr2tG~oEv8q*o~M7Zi)j8Ry;C1x!vjhl5veA@f4M}%6h()u^^e^7+CXCD=0axqVE2; z=b>^RwnTH9EBoK@x>E}lSvRa)RT*3pRJ2=Ds-x2@ubDn&T6D_vDH-F8=)|ywWdfF_ zAqkduZ?US7L6nQDiuN9iQ#ftXZDDZ`!ax*{MifXJ^!O^*W|5v)MWj7=nPr^FutQqG z<(!>FM53G>?a49{@4y)pv8lbI1LL11(Lg-d-t}?K(u4mJLDXxIdzXkUJTuVz~&I*B6oR6ub)>K`}HOaJS6+6Pmi!3hNA6nXxIqjPfwU|B> zjatjE@h9Sp)TW=sJl>aGzRCpYzk>A=af+J#=IsraTx1+lp(d0w}+vW|5kjSR)4bdY4^2@=1ezi$o(V@ z*7WI?)`7fK8o5IFq!j4e9Qi+%$R682DH$`me8NAITe>d~E0AnRhw%=})!ko)otI5K z%%G2H7WX)xGgU<+9f4?D74AB_DsWTE zUi}HTtZLkh2ErJ^#F|h{ItQjIG;e!2HOpA)wpVxAjHMrMALabV3Gn0NGbU}&c`w72 zCqVJ>@dz$1PwH8j!%#+69JGdyL%#pGbT^)A{r}hh%WEKbC7%Bx@Zw*F0)(0zL!Oo1 zi|1h2|CDFWaTHLv5wHO+itxOS2b78b?xRaxhYdqy0Y2_F%j91?Ym-m>kRi{0^L#gsR*ITzL&9ZZ=vin&qpW>$|Rcj#yZUgn>|CW4kb>0?e8tva>x#u94>&?H*$k8)J=eW{EN0nBXck zrbrQ0cs3jk+MwzA_?VBH53&vH>+P#l)8emj4@3)|LF0ZE%sxkTyZX?Q?l*lPo9>*u z7#W_6q+!QTn68{}LKqxAUo(yDkH9fqS=CUN<<7!tQJ9{r?~&)pi6L@rhIrQ87J@VI zC#$BD;AkYv+Rn4xECSo;k*kM_b}>_!mx~NsQ%SjxGTCm|ea!M}L{Mn}pOD~WQlBH3zqFjF35cx z$AWYINVq6>H~!{)K)5*fca*tExFq*k%6v$;G@1#DcJJ>p&PNM%z>>J&|# zAqwY%IPxS@eaawxWSmv8K*1}R?s^I5xUr2S-1QJCdKXak-!S_kzM+!+O$ipD1li9@ za095G3ACwz?y?VIlyK9div9(EJXez9!2wnHP0uTUb8iBiyX_ne%{55)!Wd?!>}48R ziZNp3lYsN4xZXyT&*6ZCP;jV!)oy zLYZ0pfJ<|;313T{RxVwlU^aD@<^B*h7R;gJmFIp6nHS9e5U?-z$JBE@MlCTrcMR=W z`Z#i_$@LRnMz}V25+nKJH(std+vY!6?}Vt;Tc4xlx#b>j+Pl9*(xkp+n?lRLkYj5X%|*LsAv7@`kB^uCm+uu5&3G>&`3u%rXlahdWV zhZ7=28B z1lq@apWOXKv(XpEa&2!s*e`_-ZXR3d0{XYAtq*P+SHZN0see9&$B_FXM!!+j* za=5Al)Uivc_p2vuz2mxwK1w5g0g;J3*`#XkG1i{)ehE%hZS+{W)*h3!CMMS)aXB&@ zTZ9xwzq0Y*Hg8|PYP?Z+2?mV^Ul!h{Kcr?q`s`OL%>sWjhDr;(tY=KJY1-?!6zF_q>-I*kPFG$+z&PS|O_ol0{uokoIo znv>}?Csmrs8&Il!sIGBeWheU$sa)xfy9IPZt|~dTPVNCZn__aX`7PD|C+MonNc1X- zjFT1mTV_*;(P5mNG~`-#E>Nom^U|=!@|J?aF0u-`;UHNi59;X7(O`?WNhYQlp4<`M zbs*FEw=1%AgAJh3?db;SAY$6O$(R!JlqVSbUxw)PHjo~m8E=4oP71FweDuiq(0T|& zT5?KT!lO!Hs!8T3xb)YHDo=JH`ZH6zJVD`QRxH^V9Hf*U&qGead)`*+lVlW+=bo5m z3z%-Z58R^Cpd4wHWx`88W|mzxTMi8}M>R#dN2nt2Oz|-ng7yK@^y~b1mP*?Ak?@v+ zNgEG45^MmCnf$9w;}mT7Lo*LIZr)wC!0&7UX{7F`i-mVD_^kL`ygbOtmm?Nv?yJ~O zBn{Q;Jr5FVcb+7nB6zq8GEH$?;Z z96J7f7$2>K?6OQACbP#5?*>S6Z)yQ3(hQVbTQV}|4ij6ybEySz(Kwkv!Qf*o|8iYJTQ~I zsr0nSyms4@N2k`y^K@FT%QHoI584tBXbGO;OG~W9>lMn}V>%I! z=A{!Y7v3NwXd4dnk}=#*BVe-DKTye4hn0TX0}lOkB%X)ZLy-3kJF{v<%QAWPFP)hW zJ=~U9qa}DUFfH+z@ScMN%g~}EP=*;7?5w;?$0=*}*m=sXt9+mlESmF#&7uzkL8A{G zvolNk0M8;yr;Q753{v!gAthz|09S{y=^g@`)l-D$Y_fWIhH*ek{x{;;vgVfyON>{h$ZjOli7QWGjgB>{_%0HTmox7S`8eZA%wlD7t*`K_ zwcvO;|IRQt0e=Lc@p1y5A#Val;by>k2O8NQWiC9Vi)%9fygycmDIZ`}Y%DWwx6}>V z__a`h&df!@3Z%ZW6w?`Ra+>f**)vDl!~cjQ>Fa}s)yaUc^km0gy;N7 z8Kb6qX3Ng<3q@4RQ^nd27G358r~CmB=^G`eMd=$n>&%wrV9oQkZ2tL@$z_aWszK7_ zSuMOrATb{{tk)8J5CA>KEb53s$7_&S0*UQPLJd7;-u!w9aAZ3Lek1)q#TPTqfVLhq z?>PYMF@L9+svO7BJ2{R1Bu!+FYDIG#Qw;b_G?eCJB8#t~i@z3%!Nr9A5=>Mo{8Q;Pq4PgJNTc z@k@*PaNmdZkTCAE(;wV6CGG-#zpek^<|+5kTmPHQKfe9S6UEAResTqzQTCpPrSB+D zRj_pmLblV%8Ge;1cBkto%N*8wuH=&@_Rm{ObPk7P4nI%jpzw*Gf`H25 zkRyjfb`BSzCe`(awUqW(9NJ$|+PxMIPIJ&Z1gZ3R z<1Gi7nf^eN<--;4Zd>|oO;)4RL$>RRVHwiGjuyGv8WtB(hh`e7%AzX0E-Tf+PpO3u#G=Ubf17 zZ1N$wftAf`w#HeCq|J~TF*j><=OD(0S*FCYOuoK>RX-M@w5MH>Rll_FIktj-5Z=N8 z^*)`9Z*p+(;^PIEX9n!F*Q)*L{Dt>0h%EYHTWuVwj)TUm-bxEXk-Aw(8#?2Zouilj z&aAVqv|Z_A%gz!sCaY+omf));SSj1&*_zC^O~ed(kQ}2o*!(8Vmv7p5V>Wq{Ci4Xq z+!NU39h%H{R)qIikU5WhU6Y;j2;1c-1UQZSlM>L=NWrc4G{V;m$R8TcSJMnvtTx}o zJ}#PCr(dF{p$p)1ewd*6xZPqYy**g*vzF@=d6+w7nS8HCd&F)?(tn$s8Q7E3EaC05 zZzp=viqNjM_5;o|E{~i$=`P2?=j8l?GHYiF08OfLE5ge4sx&mo?&6+h*akd`U~p9P=Zc_hV0{{@Xkzh=`g)_9MC zMxzI88v6?8QyP6y(d>Mc*&Zx0X!c|*1W=SLlP^T2>e#;7Erk#jER#ZfP@_ssImb=$ zj51r9w*dgHZC44hOuk-)CjhtwBDq(SebURG0-4VDRZZqgSHjx<@imM0qDNKakCZ4^ zL@*`2_?emuK2)97s`&03R&pTo2JroKGU4TZ3au%eWDg0d=NHFB*aqel3897<}+ zhwb*>#Zd^c>TgnMxsp3>tNV;r$5-l5`8GMG$$ZOB%y8SQ(HTVm?uVus#Q?qrz`GX@ zGQI)eIh}&<&dIjni*#sW@HtqV(EQB7;tdFJFgT|KbZ1YkIo|=FYfd-(L=6TQy3tcu zL*o@qEj5d6Vx=Zx$HZ%a$ZA`nh-h0D$Qt-~YsqcYc8JMs$sed~%B>pD#s1q30=skE zg6#u!=DWb)Cz8;w#hMlV9gQ3I9;cN0fll^-o$RC*Tcnb44Js2ntZ;S>iC2sA6Qpy077nw+J53neNv>(7I?J5ZFoNGyI!`RRa9)uaZpo zEm9nYZjMe<5M&DGnC?~>osL4{B_z2~NhpuPSRp&t0GK}n({D4?AS?F-IksBo!2eg3 zA8|3~dJ|gRP!b1 zVaWSOV@@^9n1L`t5UOEb4264)c{NDNF!G6cwn`sN6uC{km$zoBox^MWT*(ECZo8cLG>t`ZyfI`!9)8>Hm#8AloB6KjLb@{i;DxaPus--P6phz$W+@z$_<5p7{Cd4&Nx*DpGG>h5Hlywg` zDj!~TmQ;+r-n3KT+l#ukG4`dzvslwg+-HlUW-y{v+E%7oVAgEg%xfipQq7iz1GtV9 z^twvH<_#CBT*L6cxoHyoI*p*&VfDOW1h|lR3q8dp)}oqR#s`HX1itkPSRfekC~teX zxg#D7srONB1aG`_+8?iN4aa$&uC0X!e3cMCZrj@2d|9D6csK7a)VC3DBRXE^tZar= zI0+nt`pP!ihhyn6KBoqaRVGHE;E+vaZ8ibvGeBZO9J<8M&i{WJ$ zB^3{Y7*sGm?}=B+6l~`N*##Tp?H#d-_An=2WPne0wknwxy!YFoK>6Y;Kv;%>z{Oe0 ztTAR?Gpn`r7U6Om*~_zETw!im{(`Fj)eQ+An=xM#MvIxZd{#ys{&I6m<<3NX>xz}v{QI&*y{mkTYwDQqR(;Xu zd2i>=imE5;E2>tnyk@q!tPV@JKY|L)}p^HsxR`O0_g++&Wcyw;3XnxC(1{l-1zyUH8P(UoSn@=ee| z!{4eGTEG56t8Zp?xv#+twbZ`=!;A#~RP)cx{6jO1WmPNRFkifTxj7`BHv-SDG7Li;R=zq9@G5 z#*Url-n%`0tvfwGtXfuYegL0&3MsFAqG6|*`-C~A#r!9r4;d}}u9ppZ7oXDL4Dclk zp4$rxMhFZZ^3rRkMTJGX-1nIGy6(5vN8svXT#E{)?#jK#b8pUT`&&8!tx;KeKfffb zO1y+`oIC7*cE~ixyZy~w9r4aESaxON1$bK+RVQCh@JC|Z!r#>qWW(^Q#C|_sx`=lm zOIA7FG;>thMsT`ALcKi8&l$twuI5b=inpT#(ApX3-W2MVqbW0Pm0u#}8(iI+L&4b} zqg-bXi!0@u?zglw27>sCvi+4}zG1OgeXBw0zG+#*5`P4rV-_fgX2jdk;u_&_9fmUq zf0W*$UKd2eHL6##mer{*G}~WIhPlze=8%6QUJ-_6VSHhI6B~?$N`2&6)%h&i*(^V? zEWg@}vPavu;XBOo!_E#*gdgZHLX*ljbNr!jkd=n77l_zqe>fUy7EH{^2ifACcVx;+ zg%})rYZNcRboirmSz43wFIs@FJIl`mH1@=9f?LUIk$K2=bc)hHXaNgDm%^LN;W)kx z4HD~-dOJ4J3^2E}L6`D0Kdjx{j#qaf5T;Vhl>zue+HYi)u}FS=S%P1u))S=uRJQE{ z(k*12ia@NZU8GzIeH{(Nk5AiOTK5YU5MQaLiD*4pZORMT&!o3WgIS5JLsb15`E6|V z^#M6GM@^GZ6$-m=B0Yv~n2s)3 zts;!X#I98l`#3Ok?9|7`QU7YNkzNxIvaUwC?i${O3Nqs|A+u8BjyV#_lJLk04k#a2{s+X z^Ui(*P#HZd!KN5;>y;Tdy@p8H(4=!+ii+StXqWIM7_(wbfpZ9~lQP&K5!M3@l8A03 zm#9t@V`pYBf@GATCN>~Qq!BhfjUbUGm_q9$auk3Ybt91;07o=(5dh7V99>}&(dN=T zo^7DHjAO78HOj_0BmHJAqXJk&>lo8QNbJTfH@ArZGU7H5b+GaH;E^z67J(^g`9)c) zYiS(~LrT^k%>t+mV*RmET%txQW4jX8eAX!|%q8X~vE@}1c3A;W(QFF5kQ@*8)bEtTa~XVZEBM?)mc6sCf<$!Qz#jf z`8R5vJdnwr!S-hH>0^X-KOn5lCcFTKs&=Z8?Zg~O*X9ytPoc%<9(W9gcCzQOg$T18Zz2$;Z`Gku3DdcJXd%M7&lA?2p0Li2r=~6j^Q9LqMzJ5u!e2eL1XHFx<^}$VwGtUV?08@H~gX^Be}xa~PZ+IyR(q z%ysCPo8Zi$3Y{K?cw~U50$5N`?00x1U|-CM&7x#zlowLpAG)-I%bRSe-*SH~WKfI+&N>p1jgA z&yjAPBVD?Exb3gfrEOq+--lp`)r@$i!!2;mJn;sgQz?wl83c&w5-}ykvxUiTV9Ep( z(YTi5!;V7;C?BI^5^Q3`Peu-3U~#MFgcN9G#0?^}GNS^>LIWcv16AwSo~yl9cQM_) zbl1}I2jQi1-2q$mfXW)wzMxw|w*m)KPI$T{w4Uuq-;1E@;Z4BrAn1#&#KS)F)C6LE zF>em&I&VFYv-N4a9>AHWE`!dSWzhq+*2hVQ6OEo_G@Xk~PDV9<0e=BxVxJ&a059Ez zpoe6w-vVta0!LbovHD_rvx)d1iwl)MbMZIkcwwVQ#{A7Uh08~{c#m7-c)*N{@9*<6 z;X1td{yr~L;1N46zSqyogd_6O@77r8M>SJVBPAK~*t&9D zroiDO$7Kqf&T(9({Hj8lfVVNz2q077xPs#{#UuwtzLkMb&cLVG9-+u?@taFLE2#a0 zJ16zP(=Ikbkgw|(`*0F}D&>NTuiFC~capE`2m5GZrOHbFWq#Cu$dUeG2kyd_C-ZyF z!Kb|T7i=F&`?Nn`$51>8zP_~nTHC+0e4p(vl;@cOeQ9}iFLkN>xgoA`=Fe`YaoXp` z32!IP?QwOLh~EJq9z={=Us)cxEiMIA{U|RbVG`ccmkjxb_Hb0w{)hohmiG-uec-ht zp>bVb7aV-r>voi9GUPR`<$Vr5%kxmm{&6zD1rGjfq}RAkzrn#@4nDv6izroI-M{$t zj!%Q3aU7A6`h$-2Uj$#{TK_{1KJC-}m%jwK5Aqu4S3<~V{^}|b&(aY4((TKkQ(dZk zdmT9IYqtZ>Y!B+!;|br#KLS-6=hsTe*X;#Jd>?#`v;CYG?fDn*b$zfrL%{WTV~DZh zJ>a^0XE9f#22=9;D|*{rv#b`Hd6* z4LJMfUhrxEKPXWt&-BML@JYb+_%Is%{ind4`g!0&Urc`?1J74eq7)&2Vg_E7f!Ai> ztAXqKD?Qg}$hNZwCH^1Gm6mmto)Eg0K7QD4aid-XTwYuaa-K_b80V|DM7B zRR;bMaQ2T4NXz;yR7(J0#BmNG1AiN?=d90lNU!G$rpIrS4dX8W&i14l`o~Her+&8g zr^&D{=GOt7<1If(Lw%pm;P1%5@f&ohi|N0ffqw_M_9xcYD;azba6P|_#{6*|jB1MwbgA$Hqa9D`9isS(B91n+$11zlK=h{73s)@hFIia!GnLI69+nV02X(ivT)1M{ zVn{hS*bKsNruuJgxMk782LCNL-GuLe`(Dhpq+)s4Msoz_5Qj|g1 z073nzUyL2jmHQA*lG;snQdsUl%t?{EK28EfB3qplcn2(2H6eeab~sbktgL+O+O>zB zOy!nNO2)6oLUpvu--a*PVIz|J^uuJad%`0%VLx|!*k;&}bPCv;yiSs%q3If_9VDlW z`te*Rg*%q4Rpf^4z2Tgc6WF_EPOjYZksC`+Du2Ou7|y+VC&B*lUnj}$Z(6a~_I>%| zzfPw5-Cid}R7SUUVuunj{8q+o8p2Lzs5>Gm@qN%x<-$eFDq?|F8^caxC3i}L71)2P zB-VycB8tl3)-d#`82h!7V}BxX7~%&HU#h0O0wUPuuap&C8RLFoB}W6Wx}=X+E?m8$ z60I8S5tX4fH54duH3}$k4S%i~+Mzkn+1`v?yP!>JK??|e0Gprf7gA>+hF#E&@fe1# zN_=`P-U=OoaBCWE54UusSQ|HXW6RGL#0Gsx!*XoW2&zwm*zeY$tu{4-{ds_Qj9mS3 zS-|`JCLqqcOuaI^3Vhz3Q;zp{5il&k`qI-H5BzF5J{RbN+*B=uSj*J`#&1IL!z=Q6 z!C}aq2dthDC^^dVelH(^a(s^PGyn^MPY#eo>f`;-tq52;NI5=VIF7`B0In~}^7imQ&vx#5#=x`=T7fR}i!u z*FkT>n8WHZg_P9#4mjkv-sLaG({6ofxhFuNK9-m3!iOMtD18H(vhS~zTx17g-tX5{ zD1GV)Ou8I@ujHgY-Ul^6PUi(y3Vs1FpVqLAc|TK7mF9sY<(TdV2z-h|Io=l)eS+NU z;IkZ*8sL$nupIw43o>kjw$ca^rhvl&5#?wj@{2$c>B_F zH)hBk#k2kmS_rYOmj+u7=F7`kFT?;F(!QvV;kFEYq8SIG)ni2|Nf}-nGvuaqVm#7J z@HNQTQ9N-Xj7mqxpGqAFw66$(V}YZ1qP7PgCep@(r}d4>kehZV$6pZbON0LlBma^g diff --git a/McAirpos/launCharc/launCharc.c b/McAirpos/launCharc/launCharc.c index bd62833..2984d78 100644 --- a/McAirpos/launCharc/launCharc.c +++ b/McAirpos/launCharc/launCharc.c @@ -80,9 +80,14 @@ int main(int argc, char** argv) { // Variables for whole main function scope char* path = "/dev/tty"; int fd; + char basename[200]; + memset (basename, 0, sizeof(basename)); + char copyCmd[300]; + memset (copyCmd, 0, sizeof(copyCmd)); // Read game file argument to execute + // Note: Should be updated to allow for combinations of more than one argument, e.g. "nomap verbose" and future additions char game[200]; memset (game, 0, sizeof(game)); char options[10]; @@ -98,15 +103,22 @@ int main(int argc, char** argv) { } - // Check if run on Recalbox + // Find rom's basename + snprintf(copyCmd, 300, "basename %s", game); + strcat(basename, getSystemOutput(copyCmd)); + + + // Clear Linux console screen system("clear"); + + + // Check if run on Recalbox int isRecalbox = 0; if (!strcmp("RECALBOX", getSystemOutput("uname -a | tr ' ' '\\n' | grep RECALBOX | tr -d [:cntrl:]"))) { isRecalbox = 1; // Copy game_file.elf to /tmp(.../roms folder mount exFAT and cannot execute files) - char copyCmd[300]; memset (copyCmd, 0, sizeof(copyCmd)); - snprintf(copyCmd, 300, "cp %s /tmp/arcade.elf&&chmod +x /tmp/arcade.elf", game); + snprintf(copyCmd, 300, "rsync %s /recalbox/share/bootvideos/makecode/&&chmod +x /recalbox/share/bootvideos/makecode/%s", game, basename); system(copyCmd); system("/usr/bin/fbv2 /home/pi/McAirpos/McAirpos/MakeCode/MakeCode_Arcade.png >>/dev/null 2>&1"); } @@ -150,7 +162,11 @@ int main(int argc, char** argv) { if (numberOfPads < 2) { char padCommand[150]; memset (padCommand, 0, sizeof(padCommand)); - snprintf(padCommand, 150, "/home/pi/McAirpos/McAirpos/uinput-mapper/input-read -vp /dev/input/event%d 2>&1 | grep -e BTN_START -e BTN_SOUTH -e BTN_PINKIE", i); + if (isRecalbox == 1) { + snprintf(padCommand, 150, "/home/pi/McAirpos/McAirpos/uinput-mapper/input-read -vp /dev/input/event%d 2>&1 | grep -e BTN_START -e BTN_SOUTH -e BTN_PINKIE", i); + }else { + snprintf(padCommand, 150, "/home/pi/McAirpos/McAirpos/uinput-mapper/input-read -vp /dev/input/event%d 2>&1 | grep -e BTN_START -e BTN_SOUTH -e BTN_PINKIE", i); + } char* event = getSystemOutput(padCommand); if (strcmp(event, "")) { if (numberOfPads == 0) { @@ -294,9 +310,12 @@ int main(int argc, char** argv) { } if (strcmp("", getSystemOutput("ps -A | grep pulse"))) { if (isRecalbox == 1) { - system("killall pulseaudio >>/dev/null 2>&1"); //Kill PulseAudio if running, can sometimes halt game looking for ALSA + if (strcmp("RECALBOX 5", getSystemOutput("uname -a | tr ' ' '\\n' | grep RECALBOX | tr -d [:cntrl:]"))) { + system("killall pulseaudio >>/dev/null 2>&1"); //Kill PulseAudio if running below kernel 5, can sometimes halt game looking for ALSA + } } else { - system("sudo killall pulseaudio >>/dev/null 2>&1"); //Kill PulseAudio if running, can sometimes halt game looking for ALSA + system("sudo killall pulseaudio >>/dev/null 2>&1"); //Kill PulseAudio if running on RPi OS/RetroPie, can sometimes halt game looking for ALSA + // Note: Pulseaudio used to restart automatically on kernels below 5, keep an eye on how this is handled > 5 on RPi OS/RetroPie } } fflush(stdout); @@ -319,13 +338,13 @@ int main(int argc, char** argv) { close(fd); } - // Run copy of game to circumvent Recalbox' read-only file system + // Run copy of game to circumvent Recalbox' read-only(/) and/or non-executablel(.../share/roms exFAT) file systems if (isRecalbox == 1) { memset (game, 0, sizeof(game)); - strcat(game, "/tmp/arcade.elf"); + snprintf(game, 200, "/recalbox/share/bootvideos/makecode/%s", basename); //New location instead of /tmp allows for saving game states in settings and DB extensions etc. } - // Silence the game launch + // Silence the game launch information to Linux console if verbose option is not given char gameString[200]; memcpy(gameString, game, strlen(game)+1); if (strcmp("verbose", options)) { diff --git a/McAirpos/uinput-mapper/input-create b/McAirpos/uinput-mapper/input-create index 9ebcfab..cbb135f 100755 --- a/McAirpos/uinput-mapper/input-create +++ b/McAirpos/uinput-mapper/input-create @@ -13,7 +13,8 @@ try: except ImportError: import pickle -import imp +#import imp #Deprecated +#import importlib.machinery as imp #Deprecated and not backwards compatible with 2.7 import optparse _usage = 'python create.py /path/to/config1 ... /path/to/configN' @@ -31,7 +32,12 @@ parser.add_option('-v', '--verbose', action='store_true', args, cfg = parser.parse_args() # Unpickle from stdin ; currently this is the default and only way -in_f = pickle.Unpickler(sys.stdin) +# Python 3 changed os.write() to require to specify bytes vs strings, +# since strings=bytes in Python 2.7... +if sys.version_info.major == 3: + in_f = pickle.Unpickler(sys.stdin.buffer) +else: + in_f = pickle.Unpickler(sys.stdin) # Read input device count nifd = in_f.load() @@ -47,7 +53,15 @@ if args.verbose: # Allow configurations to change our current configuration for path in cfg: - config_merge = imp.load_source('', path).config_merge +# config_merge = imp.load_source('', path).config_merge #Deprecated +# config_merge = imp.SourceFileLoader('', path).load_module() #Deprecated in 3.5, not backwards compatible to 2.7 + + #Should work to dynamically load modules in 2.7-3.x + config_file = path + with open(config_file) as f: + code = compile(f.read(), config_file, 'exec') + exec(code, globals(), locals()) + config_merge(conf, names) if args.verbose: @@ -60,7 +74,8 @@ nofd = get_exported_device_count(conf) # Create and expose uinput devices ofs = [] -for f in xrange(nofd): +#for f in xrange(nofd): +for f in range(nofd): name = names[f] d = UInputDevice() m.expose(d, f) diff --git a/McAirpos/uinput-mapper/input-read b/McAirpos/uinput-mapper/input-read index 29c5cd8..00f7cea 100755 --- a/McAirpos/uinput-mapper/input-read +++ b/McAirpos/uinput-mapper/input-read @@ -36,10 +36,10 @@ if len(input_file) + len(args.grab) == 0: exit(0) # Open input devices -fs = map(InputDevice, input_file) +fs = list(map(InputDevice, input_file)) # Open devices in grab mode -fsg = map(InputDevice, args.grab) +fsg = list(map(InputDevice, args.grab)) # Grab devices for _ in fsg: @@ -73,16 +73,21 @@ for f in fs: # Human readable info if args.dump: for f in fs: - print 'Version:', f.get_version() - print f.get_name() + print ('Version:', f.get_version()) + print (f.get_name()) d = f.get_exposed_events() for k, v in d.iteritems(): - print k + ':', ', '.join(v) + print (k + ':', ', '.join(v)) else: # Dump initial information over pickle to stdout - p = pickle.Pickler(sys.stdout) + # Python 3.x requires to specify bytes vs strings, + # since in 2.7 strings=bytes... + if sys.version_info.major == 3: + p = pickle.Pickler(sys.stdout.buffer) + else: + p = pickle.Pickler(sys.stdout) p.dump(len(fs)) @@ -91,6 +96,7 @@ else: sys.stdout.flush() + while True: events = pp.poll() @@ -110,10 +116,10 @@ while True: if args.dump: try: - print i, ev.time.tv_sec, ev.time.tv_usec + print (i, ev.time.tv_sec, ev.time.tv_usec) s = '%s %s %d' % (rev_events[ev.type], rev_event_keys[ev.type][ev.code], ev.value) - print 'Event type:', s + print ('Event type:', s) except KeyError: pass diff --git a/McAirpos/uinput-mapper/uinputmapper/cinput.py b/McAirpos/uinput-mapper/uinputmapper/cinput.py index 8b439ca..f2c5287 100644 --- a/McAirpos/uinput-mapper/uinputmapper/cinput.py +++ b/McAirpos/uinput-mapper/uinputmapper/cinput.py @@ -1,5 +1,5 @@ -from linux_input import * -from linux_uinput import * +from uinputmapper.linux_input import * +from uinputmapper.linux_uinput import * import array, struct, fcntl, os, sys @@ -16,9 +16,15 @@ def get_input_name(f, l=256): """ Returns the name of a specified fd of a device """ - buf = array.array('c', ' ' * l) +# buf = array.array('c', ' ' * l) + buf = array.array('B', [0] * l) r = fcntl.ioctl(f, EVIOCGNAME(l), buf) - return ''.join(buf.tolist()[:r]) + buflist = buf.tolist() + buflistchar = [] + for i in range(0, r): + buflistchar.append(chr(buflist[i])) +# return ''.join(buf.tolist()[:r]) + return ''.join(buflistchar) def read_abs_values(f, abs_ev): buf = array.array('i', [0] * 6) @@ -30,17 +36,19 @@ def read_abs_values(f, abs_ev): _bpl = struct.calcsize('@L') * 8 _nbits = lambda x: ((x-1) / _bpl) + 1 _ll = _nbits(KEY_MAX) -test_bit = lambda j, v: (v[j / _bpl] >> (j % _bpl)) & 1 +#test_bit = lambda j, v: (v[j / _bpl] >> (j % _bpl)) & 1 +test_bit = lambda j, v: (v[int(j / _bpl)] >> (j % _bpl)) & 1 def get_keys(f, ev): """ Get keys of type *f* from a specific input device *f*. """ - buf = array.array('L', [0L] * _ll) +# buf = array.array('L', [0L] * _ll) + buf = array.array('L', [0] * int(_ll)) try: fcntl.ioctl(f, EVIOCGBIT(ev, KEY_MAX), buf) except IOError: - #print >>sys.stderr, 'Whoops!', rev_events[ev] + #print >>sys.stderr, 'Whoopso!', rev_events[ev] return None v = struct.unpack('@%dL' % _ll, buf) @@ -89,7 +97,8 @@ def get_exposed_events(self): Returns all the keys exposed by this input device. """ d = dict() - for k, v in events.iteritems(): +# for k, v in events.iteritems(): + for k, v in events.items(): l = get_keys(self._f, v) if l: d[k] = [] @@ -142,7 +151,7 @@ def open_uinput(): try: f = os.open('/dev/input/uinput', os.O_WRONLY | os.O_NONBLOCK) except OSError: - print 'FAIL MUCH?' + print ('FAIL MUCH?') return None return f @@ -157,13 +166,17 @@ def write_uinput_device_info(uidev, f, name): # Allocate other info # TODO: Get from specs - uidev.name = name +# uidev.name = name + uidev.name = name.encode() uidev._id.bustype = 0x03 # BUS_USB (TODO) uidev._id.vendor = 0x42 uidev._id.product = 0xbebe uidev._id.version = 1 - buf = buffer(uidev)[:] + if sys.version_info.major == 3: + buf = bytes(memoryview(uidev))[:] + else: + buf = buffer(uidev)[:] # Write dev info os.write(f, buf) @@ -185,7 +198,7 @@ class UInputDevice(object): def __init__(self): self._f = open_uinput() if not self._f: - print 'Failed to open uinput' + print ('Failed to open uinput') raise OSError self.uidev = uinput_user_dev() @@ -218,7 +231,10 @@ def fire_event(self, ev): """ Fire a new input event. """ - os.write(self._f, buffer(ev)[:]) + if sys.version_info.major == 3: + os.write(self._f, bytes(memoryview(ev))[:]) + else: + os.write(self._f, buffer(ev)[:]) def __del__(self): if hasattr(self, '_f'): diff --git a/McAirpos/uinput-mapper/uinputmapper/ioctlhelp.py b/McAirpos/uinput-mapper/uinputmapper/ioctlhelp.py index 5448ac6..b729111 100644 --- a/McAirpos/uinput-mapper/uinputmapper/ioctlhelp.py +++ b/McAirpos/uinput-mapper/uinputmapper/ioctlhelp.py @@ -25,7 +25,8 @@ def IOC(_dir, _type, nr, size): - if type(size) in (str, unicode): +# if type(size) in (str, unicode): + if type(size) in (str, u''.__class__): size = struct.calcsize(size) return _dir << _IOC_DIRSHIFT | _type << _IOC_TYPESHIFT | \ nr << _IOC_NRSHIFT | size << _IOC_SIZESHIFT diff --git a/McAirpos/uinput-mapper/uinputmapper/linux_input.py b/McAirpos/uinput-mapper/uinputmapper/linux_input.py index 6f548a8..8a6520e 100644 --- a/McAirpos/uinput-mapper/uinputmapper/linux_input.py +++ b/McAirpos/uinput-mapper/uinputmapper/linux_input.py @@ -2,19 +2,27 @@ import struct -from uinput_gen import input_constants_dict as icd +from uinputmapper.uinput_gen import input_constants_dict as icd -for k, v in icd.iteritems(): - locals()[k] = v -rdict = lambda x: dict(map(lambda (k, v): (v, k), x.iteritems())) +#for k, v in icd.iteritems(): +# locals()[k] = v +for k, v in icd.items(): + locals()[k] = v -events = dict(filter(lambda (k, v): k in ["EV_SYN", "EV_KEY", "EV_REL", +#rdict = lambda x: dict(map(lambda (k, v): (v, k), x.iteritems())) +rdict = lambda x: dict(map(lambda kv: (kv[1], kv[0]), x.items())) + +#events = dict(filter(lambda (k, v): k in ["EV_SYN", "EV_KEY", "EV_REL", +# "EV_ABS", "EV_MSC", "EV_SW", "EV_LED", "EV_SND", "EV_REP", +# "EV_FF", "EV_PWR", "EV_FF_STATUS"], icd.iteritems())) +events = dict(filter(lambda kv: kv[0] in ["EV_SYN", "EV_KEY", "EV_REL", "EV_ABS", "EV_MSC", "EV_SW", "EV_LED", "EV_SND", "EV_REP", - "EV_FF", "EV_PWR", "EV_FF_STATUS"], icd.iteritems())) + "EV_FF", "EV_PWR", "EV_FF_STATUS"], icd.items())) rev_events = rdict(events) -filter_event = lambda c: dict(filter(lambda (k, v): c(k), icd.iteritems())) +#filter_event = lambda c: dict(filter(lambda (k, v): c(k), icd.iteritems())) +filter_event = lambda c: dict(filter(lambda kv: c(kv[0]), icd.items())) keys = filter_event(lambda x: x.startswith("KEY_") or x.startswith("BTN_")) rev_keys = rdict(keys) @@ -108,7 +116,7 @@ class input_absinfo(ctypes.Structure): ] -from ioctlhelp import IOR, IOW, IOC, IO, _IOC_READ +from uinputmapper.ioctlhelp import IOR, IOW, IOC, IO, _IOC_READ # Get driver version EVIOCGVERSION = IOR(ord('E'), 0x01, '@i') diff --git a/McAirpos/uinput-mapper/uinputmapper/linux_uinput.py b/McAirpos/uinput-mapper/uinputmapper/linux_uinput.py index 9f2bcc0..5a269b9 100644 --- a/McAirpos/uinput-mapper/uinputmapper/linux_uinput.py +++ b/McAirpos/uinput-mapper/uinputmapper/linux_uinput.py @@ -1,6 +1,8 @@ -from ioctlhelp import * +from uinputmapper.ioctlhelp import * +import sys + +import uinputmapper.linux_input as linux_input -import linux_input # For uinput version 3 @@ -48,7 +50,7 @@ UI_FF_ERASE = 2 import ctypes -import linux_input +import uinputmapper.linux_input as linux_input UINPUT_MAX_NAME_SIZE = 80 class uinput_user_dev(ctypes.Structure): diff --git a/McAirpos/uinput-mapper/uinputmapper/mapper.py b/McAirpos/uinput-mapper/uinputmapper/mapper.py index f4123c0..4b9933f 100644 --- a/McAirpos/uinput-mapper/uinputmapper/mapper.py +++ b/McAirpos/uinput-mapper/uinputmapper/mapper.py @@ -1,5 +1,6 @@ # encoding: utf-8 -import cinput +import uinputmapper.cinput as cinput +import sys """ Module to help out with config parsing and input mapping @@ -14,7 +15,8 @@ def parse_conf(f, devname): """ conf = {} e = f.get_exposed_events() - for k, v in e.iteritems(): +# for k, v in e.iteritems(): + for k, v in e.items(): t = cinput.events[k] if t == cinput.EV_SYN: continue @@ -47,20 +49,28 @@ def pretty_conf_print(c): """ Function to print an entire configuration """ - for k, v in c.iteritems(): - print 'Input:', k[0], 'Type:', cinput.rev_events[k[1]] - for kk, vv in v.iteritems(): +# for k, v in c.iteritems(): + for k, v in c.items(): + print ('Input:', k[0], 'Type:', cinput.rev_events[k[1]]) +# for kk, vv in v.iteritems(): + for kk, vv in v.items(): n_ev_d, n_ev_t = vv['type'] - print ' ' * 4, - print cinput.rev_event_keys[k[1]][kk], - print ' → ([%d, %s], %s)' % (n_ev_d, - cinput.rev_events[n_ev_t], - cinput.rev_event_keys[n_ev_t][vv['code']]) + #Check for Python version to actually get pretty_conf_print in all versions 2.7-3.x... + if sys.version_info.major == 3: + print (' ' * 4, cinput.rev_event_keys[k[1]][kk], ' → ([%d, %s], %s)' % (n_ev_d, + cinput.rev_events[n_ev_t], + cinput.rev_event_keys[n_ev_t][vv['code']])) + else: + print (' ' * 4), + print (cinput.rev_event_keys[k[1]][kk]), + print (' → ([%d, %s], %s)' % (n_ev_d, + cinput.rev_events[n_ev_t], + cinput.rev_event_keys[n_ev_t][vv['code']])) if n_ev_t == cinput.EV_ABS: - print 'Properties: Max: %d Min: %d Fuzz: %d Flat: %d' % ( + print ('Properties: Max: %d Min: %d Fuzz: %d Flat: %d' % ( vv['prop']['max'], vv['prop']['min'], - vv['prop']['fuzz'], vv['prop']['flat']) + vv['prop']['fuzz'], vv['prop']['flat'])) def get_exported_device_count(c): """ @@ -68,8 +78,10 @@ def get_exported_device_count(c): (Rather simple at the moment) """ m = 0 - for _, v in c.iteritems(): - for _, o in v.iteritems(): +# for _, v in c.iteritems(): + for _, v in c.items(): +# for _, o in v.iteritems(): + for _, o in v.items(): m = max(m, o['type'][0]) return m + 1 @@ -105,8 +117,10 @@ def expose(self, d, fd): Expose exposes events to a uinput-device *d* with index *fd* from the config passed to __init__. """ - for (n, evt), v in self._config.iteritems(): - for code, dat in v.iteritems(): +# for (n, evt), v in self._config.iteritems(): + for (n, evt), v in self._config.items(): +# for code, dat in v.iteritems(): + for code, dat in v.items(): ofd, t = dat['type'] if ofd != fd: continue