From 4b3de1f3606ccbf59dee3d69dd2b3641cbc4c20b Mon Sep 17 00:00:00 2001 From: Simon Date: Sun, 15 May 2022 10:33:49 +0100 Subject: [PATCH] Support for ForeceTube/ProTube Stock Also added f2hunter to the credits --- android/app/libs/haptic_service.aar | Bin 10085 -> 10030 bytes android/app/src/main/AndroidManifest.xml | 4 +- .../app/src/main/cpp/code/cgame/cg_weapons.c | 8 +- .../app/src/main/cpp/code/q3_ui/ui_credits.c | 4 +- .../com/drbeef/ioq3quest/MainActivity.java | 91 ++++++++++++------ android/run.bat | 4 +- 6 files changed, 73 insertions(+), 38 deletions(-) diff --git a/android/app/libs/haptic_service.aar b/android/app/libs/haptic_service.aar index 9c2dfc7ee944862adf4b02dafa2ba54e751a4705..6197bf36d9e3fab5d2157aa569317e4a2c2a3eae 100644 GIT binary patch delta 9555 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 delta 9601 zcmV-{C4SnjPUTLpQvrW+qo3ybBme*mD*yls0001EY+-YAWpgfSVRE&4Wl&~K(k1rb zE{(g>jk~+MySww?H13VNyF=sd(zv_3Lj#R#W81Sc8*jYqZp3`^?Vfw@kE$OxBQj4_ zoytrFX>bU15D*Y(5MpRzFsFf`vqex4ke^^6Ak2SejqPpeO&ouXOij(`P2HVM9qkNl zEDRl-EsdR=OdVYdya;kr*@GaTc_OzDLcWod-uQk=QXjl>LMZC|?486s%gm>jl6p`rDN8y2wOB%c3$ zBT=4qtNMK~uc3fyQRp+B^zsPR=00AH(9QClR>6*BweEkQw9wUb{i|JfqXNnHs$o`Ld$X6~H6}f$MR5%3*Ra?%-#xTzIi9#67kSY-=A0-~CiL|o{6$4{drWx zOiAn2*+YLTcloS>+}?{ux!40wqNhxAVLZPmcE^{#YX>MunNW$2e(qZID%gDVgH$u1 zP!mG%Kws83(b9ClZcf%Q?3&2bc3kK{thiR+FJ*mOs>vQ%HrO1${B(nFL;pl~BWLzb zP(2(O_zV1A0}c|_-q){-UWh;slldNH?L-xXU~hk9x9FTMKl=@!@Hd+HhGZv9{TV6# zp^DW%_6Az%iTmPtH^91%$!OcEMea<4@8a>6k4 z`8Wqza5CMQ^VVFafFvdxcrv~a^)2S)&eUc9Et_M)R&c_m1X<^8cwb(&y3{!--lQA23HoPmAlB;V~AaGzndB=L1k^XQ}>?$?H ziGyCOt9TcPA#br9FsJCHyWX8g98Ebe$39SJAI7^Cy~}O1PtADU5Mq95gN_6@H&y1Y zHvp&DQJP1%6}9WR`{wPx55@R`%#VMXLRkJ71_|JgA`Z?edu$ES-%g>SD}77~m?Ry{ zv`>O9_FSY%D-dhdVUaRNKjvIx+nA}_@hC1K;$d`b4sd^K04@$EB6xBsU+Ru!Ptqtz zNB_z=@&c?~hwvV7EvkqiuK1WWa1E&17WJ@1xu{HxKdW&jH1lxk))d?J<+y*z0%9uC z2qsf9SH=^yStgXRwU~9+sHP;AAt-_7I0aPN&Ryk}CM({zi;TwZ2=%auQ0NU%V%CAp zHa$*NKaiuE5w)8RE|d+(tA>YMqNqHC1Wo4CNVa7?#@L3A%p;1q4bjJnCDMcs<*};B zHv@ls<2PnRYSzbvAHS}UH=?JOx4 z?~}p^dkOmbq6~DsQ}jd$(0Fltu^68|0nI?)iUMHo=#*{$-QAXt&F% zXi*g^aD3^2b5k89hg&XJRQ!vby6A^1H$byqf-VN(@go#p;oE6zTeEw*NP=IZGn<)E zF^ArgcC;MAmZ9q!?i5?oXX9{}<+R~ymw1dy+xOqU;YV#Y9=RY^GHa%5>#9!X3`13p z9psH(HM@Ms(%^sEtSjm7bx>j*7Olo7(%2?SGE(KMaA8@dlJjZ@BGa!D&%)g-d2Po~C7X@lloi~XoxpW=&(7FO^<$ubLs0R#JA;h&4K18 zAG~dsAbWp8;&ESe0k*~<1u0Dt4j1gW1ZfLR5$hA(21LC8oL&atL5UruP@mNWxMb>z|h5~$H z$mmbbnCBGxWbfH{#4ikvcpKrG1kQHYMZ+u?R|29^un8#4b#%9I)4d2T3B1<$}SlRI;3B zs2q^mfQh&J)Cr6f7CKzN%5kb-$fFY61;BqK_XK%F;9v;`)xn6&0~-)3!Rm|=Vqt$P z8G;H)brpe1vV%jyT!{J46PCEk6a5gFgLfgPZqO5EM$d%_Luvu(gJy*G%AhNFH+eZE zKMTL8+OBtzE0^*@X6&^;>YV&l+~XkOg${X`jWFu0kho8NmUpO`3Io8L?h7ppK#G6E zk$<@TV!VwC+1K*;v-`vaJH?Z*s23hmsUJj&Rm(F>U|y?{PE81BKb-paC$0$MTS5z( zabG84^b)Is8TuVC+pAlqkWIno02L8k#;iy~EitA*ZL(-&Yrd$d=B6F&j%apL+xHJ= za&;pjqVXR!3~9`v}kGBX8C_8&WJpL z*mo{1#jg{t)(ZCDJ6Cn#hak%It6KT{DIwxM+c`d@6S=FMpar2@4+jO0$}XnMvzk4W znlW4$Cd)x9;qjlSfm1 z-fTQYau;=Z9yKSSz`=`5*MohvCKW$&{8P3pZcxdT>+Rs% zru+U>^#+vR=W%cu@NuwA26%lD!=#Q%3GI-Zfmbn=0CS;g51Xjj)6@4Ps_b?5ICxnn;`ioqM(+pGM1C7Rrd zEL2!9^I5`6W=xZkY%9fO)EV^}Q%*px6h37eI! zQ^Z5>fo_Rej~f3Q9v;8B?VR#AZwLV*NQpN@6v1xk3}{GHv=)E<(n*VPvm3(`c zts@%!SqhZ^5D>n9%d3)q)2L)3re=mNHvdwoSxVaSXoBc`b8u_8$q_0Lq6&$haF(D5 zBC%v4aM&yv@`j(C-BuCp%$GK7!QZ8FWV|k+9t$GP=`3m&@{zc2vY3yaC)v4=)*k5f zK@BiZ01|!409AiDt4}s)sU9N$c|8;fb!&47rf2^l=)?@2nmxhpiG1bNd&c@{c%74+ znQvpuWXzH=Ll70FTpcF`AuQEDP_U(Oq_SVqsLO)H9BpC2VuTt2U%a=-Pig_ppb6I0zmwBnZMe?JPU~ zv4=x6FeYhglfi=HF8Dx(jVnvc&ZAa|)Sd+Cabm^I6qd`n6!AzmPl+#hdM#fP$Cm@} z!ERPB+oua)n47HG>nnLuSi6%T@(k@azVY_jiZo2gwLTN%^uF-rK-GFd4lE-GRTns>_4p#`eYyX%0M1?L2F?N5odQt|wyI9Qa)=vN|yIQb$@4Ap;=Kpd1JbgiJZW7&Li5$s@^Z*{O6 z{-*PZ$8;ocYRKjcS_2mZ>+E7$quUUqrluxK-(EK)4oXl~Sez;saCjIh_4ZP-=dA=A zwb)U8?O18rqjhN83uq{Y>7qJ*B%PJ^4?2e(P@^K1NLR?kxkF@_<(`=3D(&yt<5-j8 zP#1s11q@kv2YB@031<3}?E8M$6JCf;!CU@Zu*m*gumt}T_9{EO7?CMB+Pi!Flfa!C z);4(R7;jZ>X67Aw{6^-TS%o2=g!UeqELVd#T%`7FIt)tW7GY$i6QY-lJ>&1rnYdkT z{E3vvgH*1-$+Sk|9zg>xiv|0mKpS~TMTCFIk?o0#i2U7Qr~xqj1(zG#d$qdUN=nGr z=dDNUe_p5Vi*--)*A4Zq7aqT?RAz=m0ocCA{{JQN3_Q>gdHCtj%n{ z9#R*J0pQ9*DSC|L4Zac&-2e==oYYki=vq&ze}EsOcYhk)b9B!kaXZU-(#DlcYx;i( z?|$+ieziQ2CcXp3Sz3NhMin~16&_=BE)8fu4y0h3%)D?XZ|5*o_i9$C#`#OFl_N$h}Gd*+^(C$8duVWdS zmCk>lwzB`4##o&CISJ3+cg76zY(am#<9fZL2fR7+gbmw1!!bqElbESk7l8@G!uDbr zt9VgzXex_mf^!>*+qB!t+xe?4`JAHmL zZ+W_uF*9i@AUBm=)=`1OiEh&clE5c}J)k z>6q!SU=-(mQW1aBoMh%dZb?vfo|lha>!O{m`+7&(r0x)oT9%NlOg-Dmcd-^c*XJsF zWn!SCijxH6-|ycVpd6Q=jvxbT1B=X|WoSa#pSO4Dpg_a|`R38B1Jl{OmH0rjRbejA zU0}DC78AVb?ASmjc_K?#nVS_u4~y)QJJO38Q0@oU3M7193CiH2+Zi& zh@8e1Io{w9x>$t{;tZp1k<9GYjFi<7~&HE|(A%+dK7#iJK$Aogq%Emzlj@f~s9d z%X=s$ErD(d;p{S>tsZ}em<}*h;o!7Y;M6XDd98}kmWzReO&%%Ct+=4n!Zlc3a*aav zQ}M$i$j_Z(cVw$sGo&-yfG6Hlh#g%8w%71RrYW-Jy7|D=nin_#7g}?B$pS$QvHV?~ zgC=?NoGLUu8&Ad6S_etg&rzcD%iU2Za=?!01hFY6}Ssy@sh6fv(Z#oim*mo}Ji9TT=7l%i~H*q}Nzs zD%z)^V-~K~80CoHWVd0=efQh}LzB-9DoH)$*(_KsxddGpoL3q`*CZroBitK~F-GGP z1eG_hgi`|PLW(O|P14Z?V5#kinH752mNp|6@56{ps z<`wbDl!AT_Ilvg;a{Eh^9YtPZnnY@ofV{Kj#-F31u={lvS;Z+e#}%mvM1mM^8T9iZDN0b9G=G@H;0f|L{|0^qPM3D zl1Bn6Dy$<|pTL`V?84YVv(KFTM;kg&8cAajW30_cQ~k@SB`ujsv-4*HRI9>Bfarm# z4Fa^RwY0^&;Q+a8TRszAS)`3*QLB-bnS^P!02rl$f^D$58+raU)&tQc#^JMSv{!by zx4(){RQZ1+SJ?|>*$ai>)2D~+X6z$af*-0p(PNSK_=D}e+`BaNAs39h7}@XYS9T{C z0})COT(#Um5LZk+^7Sb&DhGJ!#@YCk_%F*p_o)4 zI~%*YQwEXnzAUoe+&Q8i!hmqs71A3Besaq@5yhT!&ip$GCI7rIzf- zyC1(K4!=acEotb}?-2P+Qgs_-T8liAGd)U+wS`cY#wh3XSEK)a6)6vNm%crKObwsT z`SX9m&MX~M$0d7Yt4LVG{%j|k4MdrhohB_*-_hxYG}n73p48^3&h$vcLb~E!FEU8p z#?jpXZF;qZTh5Q&kZBE)^#YPx>7uI9AdC%qu>6`yMvzucP1g}mzH(z+s%WExRK+z& zH#G$5Hq-0g8Q!`se#Ey=+;Woj&E0ZYTpfR_sN~dwL9pU%!k^H6TF6x+N_IW*HMUWhhj9s`VCzQ5jSY z(=N)ql++v8040)s(f5KO_sVdm2-JqqT%#F|7K_D?Cc^b$HEFj;ti$P0?JVs;us2wf zk?nHdC>!yGfF`&Nd;cH{ZbKLhEFgbDK;jYp-Ms7nK^FW=(W*<@;HqN1W&d)wF~>32 zx6C6~7}C^{(w0(|S|g(fVX@s~(bX93&nBDWV*cr_q_kM)V#w_mwA~w~{FB(v1VZAQ zs1*v79Pb@8>TW+MS&)e8Rc9?4MOcId#*^=b@5OufyYGem=6>j@z8Am%ZBu{AfhxcZ zPtAcWNSyR?uT~10r)nDpAWjOsGXl*LDIFh2_Bo7hBq%XEv7VZfnT(TS1SshkFC%Tk zEQ2onBT|6q*LXBsDfQg^uddAGsZ$UCaPKBoHz}f7{@8O|$zQk|+$0Lz&NAF(7IYYBmXxc(`9Y_)^=f1b&DJgZ zeN2b|uphrdEIGI#UTUKmH`Q{I4u}hcL&}h*O%x`t<(~4AvP>S~yC$iTSa4x8$aHaP; zi-5|O>*FfY$%oolL6Nw1AZRjZrJs!h>YDfxjN8;@_8TO{zQixwV6UYDzi5L_p<}0x z9d`&8w}G9jAGnn0=S-V9$yt4+pse9^y-|#Xg2Sr%J*XXKxUhfEM9DT_M~z8hX`TEK z%VILRNV{aEZC;iQ3sp}ew_BEfEsKqD+)2*A zw!uaf!&Tz9H|H)kP#@0|dZgOnH%Ft_FHNI2_?bpev^kuaqkI={vfN#^u3Gv!gbc|b zG@L!|Q|Zboe7Vh8lL1v>uOY^1GH|)YbiyXv@e=m=GO8S3Xrb3hE-0A2|*u;ZUs(Fq1+Z?Jd&v&@PJv_wgMH!G;Ul4omU<$>Hg17K!emSt$ z=nqE2=SqK$R;U_Vee?AzhA??8o5V;y&-o9rXv6g}`7)A4xWs#4yjir|6|a6$S^E&v(Icd6z5L1Y@dLwb-~8y zv^rZ-h0ljEB2j3c@CwlWq*5`V8-O&oTB*Z6>b=+LqP*M~ibEuV$ zPSORGt_9GkN~qhyw6dJdLR&5@N~L_iN;Zg?MYe)w7fGkdm0I0lE$}KE9NS0IU z2uy!O?dzt2S#>^Nft@5@-HknlkPzCRp4dTqg$zbSfOhndffMZWp7j&`W{dh}yMO}XgkG{C?&;$F@N@?w+?Mo`7=ar$B0!@uK;2S0MTPf@ zv3!AsQ+EJUH{7G#zk-YN8Nl=DqkfU==f8h~e=|bW8?xN#iy--yA_8qLf-xDcm5CO` zL7)D_FnsJA#r3-}i=f)9VlYjOn^W1s7TmQ~N9dL%dLuK~vIyThQ`Ev3VT!FsiDRNp z%CUHM?;dp&aQ;d0uvJ@R2OrJUk4jxZKfZmmj%Ji`Na~5w9I4fm#yqftGl$zVmAQYL z+cT&g)W@>=2eQlO_4#VSV;o3~GsU+-;jp!W87g``ih^yIP;9@~BBNz}nvhlbX=m*6 z-4x_#-|*rd(f4lRiX=%HVH6)O%Pt|{Mgtp&aJ|rpC1aFY^KtVtb!T#M`*WVAY|5czL zlj{{g51A4ua!kl@7u-mL4y&bOVFXgMurV^$p7?O_8q~^+G$3bB1S4$=W6M+1q#%4r zXMRt4dgo*=(cdD>0dW9Oa-E$zhF*T{w(#n`?i^#C`gS z-UmbDD7lOi3nw#>y!j48rc9@5NDoFff6>%_8Dr6|hIh;g6R3lVH;TbliLXh?8zapW zZCZ@TJWN9E#s~DJJ=@SeWG<b}+Q(?nlSKhlkmC8sGAMz`(tlz- z<+B7?SVnV4A?)8)f&lMRMKpg}>X8hRa^#oHd&sn7`Q!~h`cBKo<&Ex~z?D)3%d-S6 z)K^C~;Oxd5?<-H=%??f1$%3Abl4Uh1fT9X=1-yYdEJqX5?}(LR zY3M>pN=a2wVVgqez}r92gvHWk3Dd0 zIK_LZA&N6(Ki=4rulZHhjup^Xln`Axd;Qz$fE@g@(v6lsSYkQ4TAxS|1)kZriHxS7 z^b8`iX|f^5@yeu`+3}VUcV?Y5>#)^YLV6d+>#O@!)UOO!cW!?&F^2ht+;?6Rm9Vv0 zm>1qVtLv*f2wU^K@-5HBbl2oV?t2-@;=<)FU6jMs4uOU|uk6+19x9~S7pOaRQ+J)L zo6wY4+#6jcz^P~PW;+k1?0ch-#}2z-)Kb%upC?8GiNhm%VU(sw!sqXJ`Yf{LVz?`8 z2ngULP8-?~(Cy0^-YWqX2?1uomKgmXK2uG^L4}CvZ{Is#sg% zS?(9?ti~9u*XZSTVX88BxG)>6=tV7s5&OK;Z5h5uK*~r&JMp^&hNLsG_~r-*V4ci| zXs|B%AV7aotXHyF7zYS8-$mjvJy`gTu7KCfh_lS?Yk~#C)GsH8@f09O4d4b4bsK{o zKidDD;ce5p<~M)#Bt-CkcTZAwHgq=qST<1_v-=0n*(dvCl~=hE#obwKEhRw=gO>ec zzjH_^Mv=1Gk*O{8r#0Da08P0Mt|TjZVZ#7~J>q}F=VXE~e=c6kPLr9>>1q1izAq4$ zuu)7h^RhN+%WSpAyK!L~sP|ItGBsb{y0-XSxjNOBZdPf#e<7C&Ygi7@OazVoCc%*m zBt3v$C|f=KJ%k_gP_^cI8z-odMTp<@kcE^^5x`m04uun_;Dz>`!Bd(6XM&G-D?Btl zYeRoQ(%zXfHjEw;g*h1)isU4MY~Ee$u)dywyu&&0ah8AroLb)Ii8>(+btbK4w3kTM z)Da(Y_S}>t!B<;CA1zsV;<1)=&aY_?6K}3|Z zIFCJp@r_i+r))1M?+gjME1k?(NV^-IG+2jFVgH0B2m8Yp(?gr3t`mO0l2pW3Qnr7U zrWG8Ub~QU2Y~#=TO|Zu09N7}i={S^N>gq>i+&a$$OKbZ$IY955dA9Rjrx2gN@|{{xdTCcX-Cqo3ybBme*mE0g&qF9v8P00000wG!8^ diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 58a97f76..390df5c7 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -2,8 +2,8 @@ + android:versionCode="55" + android:versionName="1.1.0"> diff --git a/android/app/src/main/cpp/code/cgame/cg_weapons.c b/android/app/src/main/cpp/code/cgame/cg_weapons.c index bc9ed218..25423f7b 100644 --- a/android/app/src/main/cpp/code/cgame/cg_weapons.c +++ b/android/app/src/main/cpp/code/cgame/cg_weapons.c @@ -1318,6 +1318,10 @@ static void CG_LightningBolt( centity_t *cent, vec3_t origin ) { vec3_t angle; CG_CalculateVRWeaponPosition(muzzlePoint, angle); AngleVectors(angle, forward, NULL, NULL ); + + //Handle this here so it is refreshed on every frame, not just when the lightning gun is first fired + int position = vr->weapon_stabilised ? 4 : (vr->right_handed ? 1 : 2); + trap_HapticEvent("RTCWQuest:fire_tesla", position, 0, 100, 0, 0); } else { // !CPMA AngleVectors( cent->lerpAngles, forward, NULL, NULL ); @@ -2517,7 +2521,7 @@ void CG_FireWeapon( centity_t *cent ) { trap_HapticEvent("rocket_fire", position, 0, 100, 0, 0); break; case WP_LIGHTNING: - trap_HapticEvent("RTCWQuest:fire_tesla", position, 0, 100, 0, 0); + //Haptics handled in the CG_LightningBolt code break; case WP_RAILGUN: trap_HapticEvent("RTCWQuest:fire_sniper", position, 0, 100, 0, 0); @@ -2531,7 +2535,7 @@ void CG_FireWeapon( centity_t *cent ) { trap_HapticEvent("bfg_fire", position, 0, 100, 0, 0); break; case WP_GRAPPLING_HOOK: - trap_HapticEvent("chainsaw_fire", position, 0, 100, 0, 0); + //No Haptics break; #ifdef MISSIONPACK case WP_NAILGUN: diff --git a/android/app/src/main/cpp/code/q3_ui/ui_credits.c b/android/app/src/main/cpp/code/q3_ui/ui_credits.c index 1153b886..f7b16c92 100644 --- a/android/app/src/main/cpp/code/q3_ui/ui_credits.c +++ b/android/app/src/main/cpp/code/q3_ui/ui_credits.c @@ -145,11 +145,11 @@ Special Thanks to the whole discord! y += 1.42 * PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; UI_DrawProportionalString( 320, y, "Dedicated Beta Testers", UI_CENTER|UI_SMALLFONT, color_red ); y += PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; - UI_DrawString( 320, y, "XQuader, Ceno, Cukier, Bummser, Retro1N, Benny91, April, Ikarus,", UI_CENTER|UI_SMALLFONT, color_white ); + UI_DrawString( 320, y, "f2hunter, XQuader, Ceno, Cukier, Bummser, Retro1N, Benny91, Ikarus,", UI_CENTER|UI_SMALLFONT, color_white ); y += PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; UI_DrawString( 320, y, "Bim, Lubos, MasakaPete, Config2, Maniac, Ghostdog72, Slydog43,", UI_CENTER|UI_SMALLFONT, color_white ); y += PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; - UI_DrawString( 320, y, "Cornelius, Ferret, RealityForge, PvtGenO, SatanSlayer", UI_CENTER|UI_SMALLFONT, color_white ); + UI_DrawString( 320, y, "April, Cornelius, Ferret, RealityForge, PvtGenO, SatanSlayer", UI_CENTER|UI_SMALLFONT, color_white ); y += 1.42 * PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; UI_DrawProportionalString( 320, y, "Special Thanks to the whole Team Beef discord!", UI_CENTER|UI_SMALLFONT, color_red ); diff --git a/android/app/src/main/java/com/drbeef/ioq3quest/MainActivity.java b/android/app/src/main/java/com/drbeef/ioq3quest/MainActivity.java index 3ed36d50..e025a54d 100644 --- a/android/app/src/main/java/com/drbeef/ioq3quest/MainActivity.java +++ b/android/app/src/main/java/com/drbeef/ioq3quest/MainActivity.java @@ -1,16 +1,19 @@ package com.drbeef.ioq3quest; import android.Manifest; +import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.AssetManager; import android.os.Bundle; import android.os.RemoteException; import android.util.Log; +import android.util.Pair; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import com.drbeef.externalhapticsservice.HapticServiceClient; +import com.drbeef.externalhapticsservice.HapticsConstants; import org.libsdl.app.SDLActivity; @@ -24,6 +27,7 @@ import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.Vector; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; @@ -40,7 +44,11 @@ public class MainActivity extends SDLActivity // implements KeyEvent.Callback String commandLineParams; - private HapticServiceClient externalHapticsServiceClient = null; + private Vector externalHapticsServiceClients = new Vector<>(); + + //Use a vector of pairs, it is possible a given package _could_ in the future support more than one haptic service + //so a map here of Package -> Action would not work. + private static Vector> externalHapticsServiceDetails = new Vector<>(); @Override protected void onCreate(Bundle savedInstanceState) { @@ -53,6 +61,16 @@ public class MainActivity extends SDLActivity // implements KeyEvent.Callback } + @Override protected void onDestroy() + { + Log.i(TAG, "onDestroy called"); + + for (HapticServiceClient externalHapticsServiceClient : externalHapticsServiceClients) { + externalHapticsServiceClient.stopBinding(); + } + + super.onDestroy(); + } /** * Initializes the Activity only if the permission has been granted. @@ -141,11 +159,15 @@ public class MainActivity extends SDLActivity // implements KeyEvent.Callback } catch (Exception e) { } - externalHapticsServiceClient = new HapticServiceClient(this, (state, desc) -> { - Log.v(TAG, "ExternalHapticsService is:" + desc); - }); + for (Pair serviceDetail : externalHapticsServiceDetails) { + HapticServiceClient client = new HapticServiceClient(this, (state, desc) -> { + Log.v(TAG, "ExternalHapticsService " + serviceDetail.second + ": " + desc); + }, new Intent(serviceDetail.second) + .setPackage(serviceDetail.first)); - externalHapticsServiceClient.bindService(); + client.bindService(); + externalHapticsServiceClients.add(client); + } Log.d(TAG, "nativeCreate"); nativeCreate(this); @@ -202,39 +224,48 @@ public class MainActivity extends SDLActivity // implements KeyEvent.Callback static { System.loadLibrary("main"); + + //Add possible external haptic service details here + externalHapticsServiceDetails.add(Pair.create(HapticsConstants.BHAPTICS_PACKAGE, HapticsConstants.BHAPTICS_ACTION_FILTER)); + externalHapticsServiceDetails.add(Pair.create(HapticsConstants.FORCETUBE_PACKAGE, HapticsConstants.FORCETUBE_ACTION_FILTER)); } public void haptic_event(String event, int position, int flags, int intensity, float angle, float yHeight) { - if (externalHapticsServiceClient.hasService()) { - try { - if (!hapticsEnabled) - { - externalHapticsServiceClient.getHapticsService().hapticEnable(); - hapticsEnabled = true; - return; - } + boolean areHapticsEnabled = hapticsEnabled; + for (HapticServiceClient externalHapticsServiceClient : externalHapticsServiceClients) { - if (event.compareTo("frame_tick") == 0) - { - externalHapticsServiceClient.getHapticsService().hapticFrameTick(); - } + if (externalHapticsServiceClient.hasService()) { + try { + //Enabled all haptics services if required + if (!areHapticsEnabled) + { + externalHapticsServiceClient.getHapticsService().hapticEnable(); + hapticsEnabled = true; + continue; + } - //Use the Doom3Quest haptic patterns for now - String app = "Doom3Quest"; - if (event.contains(":")) - { - String[] items = event.split(":"); - app = items[0]; - event = items[1]; + if (event.compareTo("frame_tick") == 0) + { + externalHapticsServiceClient.getHapticsService().hapticFrameTick(); + } + + //Uses the Doom3Quest and RTCWQuest haptic patterns + String app = "Doom3Quest"; + String eventID = event; + if (event.contains(":")) + { + String[] items = event.split(":"); + app = items[0]; + eventID = items[1]; + } + externalHapticsServiceClient.getHapticsService().hapticEvent(app, eventID, position, flags, intensity, angle, yHeight); + } + catch (RemoteException r) + { + Log.v(TAG, r.toString()); } - externalHapticsServiceClient.getHapticsService().hapticEvent(app, event, position, flags, intensity, angle, yHeight); - } - catch (RemoteException r) - { - Log.v(TAG, r.toString()); } } } - } diff --git a/android/run.bat b/android/run.bat index eb30af1d..3aec3a18 100644 --- a/android/run.bat +++ b/android/run.bat @@ -2,8 +2,8 @@ setlocal -set BUILD_TYPE=release -set VERSION=0.30.2-multiview +set BUILD_TYPE=debug +set VERSION=1.1.0 @REM Define the following environment variables to sign a release build @REM set KEYSTORE=