From bf9a862a430c08aea1dd126ac852a3e7aa81f707 Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Wed, 5 Jun 2024 00:36:06 -0500 Subject: [PATCH] chess: pawn promotion For a lack of a better idea, bind board and piece rotation to X/Y chess::do_move no longer advances the turn--prior to this change, castle moves incorrectly double-negated turn. --- chess/board.FCStd | Bin 7525 -> 7819 bytes chess/chess.cpp | 17 +++++++++++++-- chess/chess.hpp | 9 ++++++++ chess/main.cpp | 53 ++++++++++++++++++++++++++++++++++++++-------- chess/render.cpp | 50 ++++++++++++++++++++++++++++++++++++++++--- chess/render.hpp | 6 ++++-- 6 files changed, 119 insertions(+), 16 deletions(-) diff --git a/chess/board.FCStd b/chess/board.FCStd index be2126245958646e0155484545780c8b7198151c..4bf59273c8df90191a77ef69b1ac36e0ceb717df 100644 GIT binary patch delta 6453 zcmZ8`byQSe7dD}EN=Y{oLrRCFv=Y*dGSp z-t~UpdcU*QJ?GxD_H*`g_aDzWXYUQkco{%j1M?9%8X6i7nvK^_BbIctsOH-W!9ZZ{TlU;qIYq%Mi8_fYF~J<_(>a8n5% zwIbqbP2-05b$eg)g<$sDPI{>`0F{m^yQ8#k6qlKLb-PGQct=0U?`-TJ)AjepNX(nJ ztwnGrgNJzY+A^zk&7Z7sk_`w{Q`3?KnjeoINqbO+x|KpuXKox zE;xHMb@oY?9(Jto|2esR5?TPtSo1Kpzg06woCsLj^)=hfG;Dv8W31!>I)m3X9S4GE z1IU5-_Q3{vZ0314Kz}wB$r%#(n3neeiX$<%)aYtnSzFiQ-i{GjLX$L@F^v}Rr_Ju^ zGUGuI7m=6r^?9e|qiu<(Lp&eoc3{3kmPJA)K_PFK0%jNWOs~W9r=}M(LifR-KMu9; zRzevpR=yjZ&d-N@jNAtHstIL?Yj4O(dUm%8%`NX;o-G~{5tMI*LR|cl4(?7J(qBODlbsf!sAT9y0Hl2O8VvuStad^zqvK4-U;?I|+Pur?VZlQB$A$wmN04)r`Bz%wWKo;Q0~ zz{o55)s2W6TIvK#I#ydv^tvyY3*IH+UggH~n1%@TW`^Oq;jkr|_yC>oa?VY5(kkTr zjQS}eqZVm`kdVAVaA$wC%>Vx4#7v4VlF}2)F>dVl;OWp0Z&x{G@Np^bKd-`8T||N_@p|P1a0?T_{AnU}By2~}eIpW*j^*IV2%c~U?A}5SJ zF5ykD=AXk$i%Sk|wQt|*yC6Ry1cv+8pwh%&8zUw5z+5rpxIUV!9?tk$_8pYFSo#*rNk7kVmUGz@oorc2ust_MkiBUVNr3Lw&~R2U zUBv-M^_=@e&k{Wg2FFbwIF{-*iSRR*=8y9MoikRB!goJNHuAl0As6S%gd;vsufQN=YO0t}0B{HA_K1@_RrT!U9cGs*aXKW;}(2Zon`mCg! z-&4>-_~-nusQSuPCq|7+C`IFMm6fJ^h1#F~>g@pH%1j4~A-110%N$m_C!BE5-;^7C z2$G8LPzJZ-Z9>`IgT0PzvsL_d89%sPOJsJoWM%3dsm9{g<-LE;E2vetuc;}=cEu?r z7p}4c#fw#k{Bq~2?=PR`QfSgXVa4WSVrcoRux%2BP=<9D7Q#)}J2#H+)HjO5h_*|+ zRslnW$Qw$r#7`Q8lylPWo;>keyD56_GF=@a=FTfCVCLVv((_kwxrVT>+HAC8zf(n^ z#RG?bq+HG;r37M%8PzbFgwaFKGL2hUo&Gqs5bcLEZ6SfC!`2KX9>#p68eSv@{tFKr zqsT`%&9U2covm7od6dkW|Bz;yV&df(1AI9+n1UwWVz@fI#SofQ(Tt=sRWImYDZyD$ z7)YXP!jZU1gX=fx5y^gjVE(dS^d08VukQkO6DoN;kqJS~6ZN#(qFLMww>R zf@A{uEk5~CN`XRvFI>^Xl=yD z@)`C@n;iyv`h?UW*xIXNVFHF7d<~jWlscgGY^#Tk3U`yT z=V2j#E>x4Mcq1p)hsYlqfe?)A+L`bH3!A(sf4(z< zZj?R2A;?=MuZYUaj4juU93z^Ng(7ZF`QML|Eyu^K*fx=SDLtlC0zjW%D2w{%Dai z8!rM2Uu!;Fx7>8%YQM0AGRg@w3Qgc`EwKYw6%B=qnz))11`KAcRuW=Cl6dU2pjJ|E z)?^-9kTg}sqxNh6i}1`ft(aTq^b$eUv=6)sU=|@}CVtbc?PMBL8YJ_rb$tKtSro6) z-mXimky&C!jpk_Xc{I0z2W2+5(^WuF37%cPGj0^&@I-;t=S&h0KhXA9>L+9@)U|-; zrDF6}o<%dS!bMib97|&eik$~({JpJu^sSe@-Xry_qG6q4QU0iwuP|o8`3g_aEF#1e z7x}U06R(+VY?zvJ0ckz?r!U@?g(1;p`F1hl+nHFOCu-eq))}y|ed~4pu4orc#r!H! zxNhWsoAyVu@ZlAa^bn_-f_^m`5kQ~kIk!mJ7?deB{HN5Xk1js^{Q6B_8OL6C*qW{I z2D`a1gB}d(Csa>U2q?J!mbR-}IN`3k9kJG1qlTGHbb}feT$73$h8DgHm9odSP^bNB z=Y&?&W6eMTl50Fw0Sg*V! zBWWYJd8t{!kj&c}{yZ?e6c;-(N=#YltT(@=Ix0u^FGg)WaX%#=$kUVsPBK7{UU9;YA4~OaxPmJVUt0iBVl@hRm%->{-j*mN($OnEL*0&$=+r z3WxWcw8p&4S5xkBZZ8(-#jgRm2HdgPe8#6Qv$}pN1Xdkay?xkyY3XMjw*ndxa?t`P zi|}zVMRC`%6cHW-%a?@H-XPi(y~k)L>G8*FZ-G4#KR@(FdZ8< zbHdb*51EA%Mb0p=1HMpa#=1w7OFnXDQeeU$gphyJs-O*68oQKX3<$TLi7J*>!usCT zDa?zn1h@L2GDrttJT1}#V#MMbux%_nLqCsUu+XHbFGloy!#lVXn&YjB?q3;(k#-jk zlfraLpK)CZcfE9J-}+by{Nd_iWoBN5!*{lA>oP||>~>>`l&LbPY}~gdg>JJxQ<1XJ ze9Ru%2Y<>;9{en?6RII%?;WtB@!c-gZ%EU!?fbs=IDrYkLa@-OVPpAI1#E_hQ6A1{nHeMC(a9H4hfIXVR zm}X)a5#$ckO5-oO#dJRS@OD`KJcn+0O7kIJfYLUs+XoYUs7Q`NsJ4kal(>C<1?%Q; zl#4&B76V2wVJNa|QT{$K-N=0u^zjHX$o_N$_GjMK=Vj-*ez}3IADL6sW%+I2WN@hE zxoEzi^SyKGkWb|v2~J3M^giv2D)!=uGPMjDb*Po59cO_UeCOUw=c;ET#DIUD(aydN+s5uOYbvRO{s$Rmq6o*7g z0ehGAb#0D*ML6UI{uO}?FRFt&q?8GhM~iY;CY1@>L)j-^a}zzr8>x5VZqL`PNL@Jd z>E!zSg=kYFg{!FRT6c)l1$>3|1*r-O8=smZbk^4uC>?empE@AF&KoRhKJ1nU7<8+z zJKh)s(Dia9m0>3BysU{E2wQB9D@7A41JqM?!m1-Tne|(4cf;Or@Yq%i6)2$&-xt>q z7!2l5=)F8TDOBv(9M{{stI93oGqU^XjqD;Y`CM^TT;V$w_bPnRP5+ui`?%~faS|@b z1jPtCQUAN!_EleHXVBA_Cw?&YqpsoYCIu92K6#RCQeUbnm}pyXtV~RvM-;uG6?m&_ z)ky6^PmmpFcsp%47WXQw?OdOy3S?nW za8ebxX1V{HA_oKGPJiD2!TjL$L<#}Jn+z+16J5A?kz_Dc+?mu}g-o+<1gIo2>|H1W+vL$m1J8V(+s_e4$ zEt%D>rHqbc{mCGT7p8ru54kC)Z+-j5%I~IZ5@Ohz8Y=yO`>)e}h?<+>l{$unAg=ab zL#;`}%2tI|3W~vwog`p#gh%wT@3moNXv^xyM^|ywBqeA1z_W+n)yA;!fmPA{N?nGZ z>E8$RaC9#H%ax7hfopHaTn|sEBzX76>R+n&{?|nRp?Vb78kpb4AT@hf#@m=z|1RA` zet8)0YO_dBh2xv6)*QMnhjuCV)sSp;=1Z!N#ysRL zsoM5y4oa3nhuac9MDt*+4f;UlDR&ch_6-;3Uw2W>U-))~oQ6yrSj_ESOaOGKfxz8k zLss0z-#?1%uBGFSA1#Bv(Rd+QtNRGMoCM%nEYU@N&(szx1?f;f`nfAjKh+&PV@SA_ zWO=7<=`r_xh0KxDdRI2d%Q7+EZ*b`7Jy&P{ao6{;B=Y|T{*pOZ7P+VhbMr3CWUJF;oFmefVlzy(YOln=Uv}|IWbjkDBg4ie#@nq=VTQ0~ zCe-$hj;B#p8IHsJ6kP%z{4VAzEz;mllJNBCAaP_+i68jlG7 z$wtwG+algSMnmg_!YQ5ti(aduB*3U;QSKe$v?y`@)DRl$wS0d>MZ-cZ^@KoJQ89x!!uBLJTy%v?M~I!6 zy~W=$wwg%wVjvlq>1Nu+@;YYz?BLKM9<5*nRDUetG8;`)uM35ui6hVxd zYeGVQoc(wOxxQ~2Uqb`jYP_w>K{)h6*;`bD%=3pruLh|D1n!8@E4#yKY9b6{{xisM zn*Gc}2`UbB=QvY_AyA~=qgni{P2NotH#)@yEb^#GD)`%}b0}%wZuLyR`-HG4jIRL^ zhUcCZ)Z6iT$U)dH^2hZy1O&L<#U*yv5hC#ipm!bj0ICcj*q^PWmSdl=Hck}bG{dh5${01>b*5A z+snriN>AG=xA(OXA-ePuwm!a%P_kjcM}H!GI9;!}O8Bn$UiI$$D)Bb<KqsE-n{o%3P`TZi5?e8?Lv`~ zY87xATa+#*!!YV^D|&wUhp!!ejGj&0zmRURG4(-yBiL|`>Bt)m06W=irI$%pSWJI& zL10i_jg$`i|Cp+YEnBV7k88GXC6^0{;}{c%;2DtVr|MDIMp*LHa|7Npk6qS;6RCl! zU+|kBTO793wNfVVrX0dEsZXOweiDpwzqcpmFS*1L4pO(>1;Xa!N5JbiHi~i!8A>A> z>o&tf+|GUFc(60gB@)NQ{?$9jVehfX@;tS77TamjdTCVoRo*6y_Oq&qOjy^DO;Bg6KOc#59lV4H}V}j-8b58VFxA zI@%J4ikByVR2*P%%v( zBT`DI?1%bR((}MiokHYoGZ={|@Mm{AW-X}~uJ+#s-(0NA{*P=!HE0DeA57S{=;;4-l0!#pYD@P}r~upB`*_(YLR=u8+8XE>N*Czy|yGvS9x+DYvX^>iw?v|8>FAWk)Bi$X+4NFV2O2ZP$0!u2L0x!>V z-Z;N^&Y8LA&fK|o?)>q&GoM(=ZE-+T1@##T5)#sLr136@J~Oe%6+IymlBEgp8KZNimtlhnwOS9&t4JBlFd6t zUFPkf`wI`5&m=OaBu){HYA>?&15hv!>;A6DC~(stuALQH^%-6;cs(l+4%9{#+e=^< zXBW3sA9f;o@3+^oPkQ}&L{`e5!SP4fR+J=+xm{E54ORFSJ~laJg3-hNZ1i5${fe>Y zJs25__o8K6VN|atQ#eL2j{d~G4|-Iq!+>(q6&kC$oG@N@vIm1bos)+|lV|w3pUb5%FPg5%$0dfNr`FkNn7dQ8k?AtC8s=w4Ad`ElNsIZ&AiXxueU23j= z)KJ@-I{WSz{?o;-lLEhq9d^xB7WGDg@|CEIw6bEyFG>WZ40C|TSvg*u37?gn+SW)dJ>NTOReywiyc<<6B8z-gdu^;vh&D!(P zKt4Qr_d9;3!!rDUzmq&PRPYYxPsYbJ&BUw#lLY)!JoB&0~bhpeD5RGv<*d(7!xZb z!7{icI$HkCt6~N*W4V|EGrZO6Z^|JtZ?8$fBaoxJufM`13VxZ49F?Qjykdaa2i>^) zX;q4iL;(g7O`B5!i|_IrF?#xB)$!E`_l}uJKnsxQXjuyxV(JB>qC1+kiemVJ7lY3LoO)P?3RssT9)D?;^ zOb=3S6@*Bkm@;L{qcr;~WoaW}YRHwFp|&`!EMF-GcG4W#^(4;W2{^0IhO{fDts4g} z7S{4?C7Y})e3#1_a=r$1!ZhasTEq{9Wqv_!a5hqE!#@DpXU(m`R)KaY(E#boiqAQ z^3bf7|Bh?)Cm6Noy=e)xQ(m9&GY-OCB}fKL_`BrF_mqg%lY+#2H|+hW0&!EENGD&V z_nl1j!|ln|YXRP@BZL_W)W$+sGbx0zlQ-BXSWw+=E35{+~L-~br@B9AJ zW5&Am^5?%~mlJ5(gMANou(usad8iXmazm?Jl2E^l9HeQL1mo{jn4PFF$p(eR74HIC zArW}cpW#E+IU6ELN8+u2@Qf$usd!e6wcUa?+MEX6xE7n7{dbut)U#yAZd0 zo)|I))q>xusxKB_aQ~Zxng5Ih3h>F+0!4UUUNtaJ7v<2&n z*0DB39?vM;Lg2Ys88m_+h3D4jA2)|3&hG>?WD7D@b-dnnMOsuGCoh|UjGO5TmsD>^ z!~$vwc$zWCkmC~V3TeI$l#+0lh3^?Mw5j-JDDQusZj|7-IKPe3^|g!!$|l32OHQ5m z7Jt-)Cf;Xs3$kS9ugkA7Mq<5sZ|~*l5SrnT`;a}U*v=@i}68K zZZcvDif1*GF~!#@2m>;h+!A-cg1>r-0qaR3U;lrI(o@&gU>d}hq5 zCNaZI<0CpG#@y5_nMLsU5(EB(lBDq_@|Syd>+++aP9{=|>0 zH%5j#KmbprL^kLD`ienjGC$Q)ZC4a+e~BI!KBm&(GjzvWlpeniE+RhVmFWCF7@KQ= zk`@58``2oiz*S=kqSfqKJ#8{4brLV`7`It7p>d#E^GTX@UPmizRQ*L^Tvm1tQ0s<}$v8yMU zA_kdxX|T*|E@2x5>jE8$6(@OzvocrjW)Wtx?0FiMO9Z4fd^T;kk=w{BIz)*&pYVcR zZg>yUca0-2sfOP$%ZIDHXKQ{pCMk^PtZVR>Ll|`rDjAc{n(pd zQ$dWc?RAW5Co6O+Wbs240dy>vSiQ!%o^G9Azk}Yy29323+#PqchSxt?tSUQaC0JEx zrsP-AkEuAztfB>#;7xY($*DM4PZ(b+?vGB=a;B_=w#UjS)jIoH(zni$4N>1!sQuXk zn-GrMyyK}vqfM5ygTeZM&r^R|&Vol^9 z`eDOS{FI}@$l|cGD21RYb907T&>g6;v@`v72U@HgbJguZT6s=;+r2@}RU%r$#0H}dePcpi-{C5w#xAV1*elL^pnN_c$h1{Bk5A=M3XJH~6MX(maJD{h5HTNa z^mPsGj8xD)y{2AjsV?r56`M@5bEbCAR0B8mUiRBq5M-YgZ4NxrA&$^@i)tx?IVY>K15~_=<{K> zFxk<=Fxj*joP(a=09hC!W>y#VijS;K;<4G&q5e6EBfL~C`^?`^s~}E>T#ou7@4H5k z)*c5qDUjKvuX-arfJSIwoXxQuc|#s1LR2GM;1D4+Ct2tH`}wu5UVtB-RD)r!q{2la zv@n}-{u?eNh;3e#0}su8TF4LJfaGh{BukvP^s#T3;gy#vK3*Jua2OpAAStY~6>sq* zJa1j#ulb=QQx(eaW5GS>PdrWKe|k=Yb7kC2Pu>5Q^=})2(fpt{^D9a_I;#jj0mWxBfsg z&aOL8soN5!=Y(~bt~+J?X1ID9yV^ML4J+E^R@%%#Zn>_??{Rm7v*DPyGE~oc^NQ;KHeFEZGam>HPog{B>vDE$xz*owJB*kv>kST} zZP($6+5Yiu1UaD`9@PO5U%`F9u5 zHK&bi!8xe*Sb10m(`O#s>#jNY*K5136Ur%!e0lj~ys1|7{ai;;-&fgfF zs-~R<=S!?9tG!Oo0UhB8^n&;FQYgGaR~x2ER&p94gGZO%5JOA6B6NSn#x@$Z0~cPA zHK}u&m-9>bRHtsQlV;+NaQAW>B#4C#*y1H?a*t`3R1Af@&O5z4OQ>Lt2C)YG6+92yo==a}!k8k6evP)H?$-@Z*aMK2Eq94r zJbd%vRoZ;|x%z+W*i0ou!(M_O0$l9_9)SW}K(`TCVHl0vfJi~4Gu=j}Rk;vm&opr^ zF@f;h8abeD?lOaLh$zouNEiA9o2R=#7WAbS1#kh;=AoE2mwqXXi6`t3P`Tv$!0k$8 z6~2RCt?|JzfXezBoefR@o5ss&=FyLAGAOlKzrqc^YMhCVw&IREkN)ih8tw2!^w*oz zkUOQ1Y1OqPEXmFSX;7K4SKL&TcsQ|qX(zS2Uqz<)@(yF;WO9(LaoA22E&rUx{fLbH zmgCPHt2EeiVQX$#5bp65FolijpPP4T@3+(W!*r~AL8E?(9pZ$suf^tr#d4X{rCH&%nDIQ6!PoT=)H zaE=kiuPcnY^Ih(#%6{pJ;y3vt3wZuW1Qk^=*o^JJ_tKB7A}EKg#9<&n0DO^c8 z2m4}Rs0|k;2||D>eyjSjgDnx8-@|j?n0deE?gVcoZHG6{KCUwvPCMiB zS)$&3=e2qxE_EC5QT)sA@^ar`GC8@_rggWqW-y^S-4%QGCD>9-%neA8&ZYeXh>MBI zf zH}G^)n9#yU-S68mbrP^X`G(p2-QPTO%H30?AXecncZ1krm9Ntv$5c|>#(mJ4~fnJ}i!Bx$5gK=}R4ZNq!)P zkU_49;d;xFR+}Et`g5+AEod@eaw{SHkVfJ|M4`un4rvW0UeOE@bt0NtkpWNDP%6(t zCr`l-T6hyjTMvMotGXF&bQ~OOG&D9X6#wQ1gVtItmQ@hRblKcwh6qCt3$?rRmsGnG zm5g`JO>%!JQ}Y%+b<5$}MH5jiJ}(}73_UYa#SBlFvf zQ3b}&U>+zn;#!=lZ*RRJ$R@T z&^LQBJAyI0jPw3ladHCVNM0qU^M87XWw6GI2(Y8iI1B1lfwWP&$~p@raJRCJh}X8O z%W`y7g1|te94X3B-Flr$)X-}@rN@xJ2XI>duv5TU!apBST2x=U{{yQq&z{*sjQWIbAu#dn8e@pf&J6oCi#_w$GyF|O#NDD(J_k+*bh{9ELArq_uNF$-(bakk%d|HVdTISC-+1l|dysltpiYNy1h?TTIaUbP&7=VJC&@Mxn z-mo?BV<>@sH*tzoTAI7%B|-dM58WJ|gL<(71t-eLR0n-^dX84E*hb$mN{z$k3)!)5 zPWy#}Tc$;eKhFidboPMyq7}yV>e^xSXR0&Vu`+= zez?{w0snL+EH zokRRjUW|AdMW2(>r=oA}n^YRYh`rX&Ii-(G%Hh256^T-ck2`68;T=t7HW_}BQ-HU5 zGlyqsB?NsiBMc{6*qbj1XIu?bhmGe- 0) + origin.type = promotion_types[game_state.interaction.promotion_ix[0]]; + else + origin.type = -promotion_types[game_state.interaction.promotion_ix[1]]; + } + break; default: break; } @@ -416,8 +430,6 @@ void do_move(game_state& game_state, int8_t from_position, move_t& move) game_state.piece_list.piece[origin.piece_list_offset] = &destination; game_state.interaction.last_move.from_position = from_position; game_state.interaction.last_move.to_position = move.to_position; - - game_state.turn = -game_state.turn; } void select_position(game_state& game_state, int8_t x, int8_t y) @@ -439,6 +451,7 @@ void select_position(game_state& game_state, int8_t x, int8_t y) do_move(game_state, game_state.interaction.selected_position, // from game_state.interaction.moves.moves[moves_ix]); // to + game_state.turn = -game_state.turn; // fall through to deselect } } diff --git a/chess/chess.hpp b/chess/chess.hpp index f4ba3fa..ed3d3f1 100644 --- a/chess/chess.hpp +++ b/chess/chess.hpp @@ -14,6 +14,13 @@ constexpr int8_t queen = 5; constexpr int8_t king = 6; }; +constexpr int8_t promotion_types[4] = { + piece_type::knight, + piece_type::bishop, + piece_type::rook, + piece_type::queen, +}; + namespace movement_state { constexpr int8_t not_moved = 0; constexpr int8_t moved = 1; @@ -45,6 +52,7 @@ enum struct move_type : int8_t { castle_long, pawn_double_advance, pawn_en_passant_capture, + pawn_promote, }; struct move_t { @@ -81,6 +89,7 @@ struct interaction_state { int8_t selected_position; struct moves_list moves; struct annotation_list annotation_list; + int8_t promotion_ix[2]; }; struct game_state { diff --git a/chess/main.cpp b/chess/main.cpp index 69a419e..6ff7bfb 100644 --- a/chess/main.cpp +++ b/chess/main.cpp @@ -46,6 +46,8 @@ void cursor_update(struct render::cursor_state& cursor_state, uint32_t frame_ix) cursor.y += static_cast(data.analog_coordinate_axis[3] - 0x80) * -0.0015 * invert; cursor.button[frame_ix].a = ft0::data_transfer::digital_button::a(data.digital_button) == 0; cursor.button[frame_ix].b = ft0::data_transfer::digital_button::b(data.digital_button) == 0; + cursor.button[frame_ix].x = ft0::data_transfer::digital_button::x(data.digital_button) == 0; + cursor.button[frame_ix].y = ft0::data_transfer::digital_button::y(data.digital_button) == 0; bool start = ft0::data_transfer::digital_button::start(data.digital_button) == 0; if (start) { cursor.x = 3.5f; @@ -70,27 +72,56 @@ void cursor_update(struct render::cursor_state& cursor_state, uint32_t frame_ix) } } - if (cursor.x < -1.0f) cursor.x = -1.0f; - if (cursor.x > 8.0f) cursor.x = 8.0f; + if (cursor.x < -2.0f) cursor.x = -2.0f; + if (cursor.x > 9.0f) cursor.x = 9.0f; if (cursor.y < -0.5f) cursor.y = -0.5f; if (cursor.y > 7.5f) cursor.y = 7.5f; } } +static bool piece_rotation = false; +static bool board_rotation = false; + +void promotion_select(chess::game_state& game_state, + int side, + int promotion_ix) +{ + if (promotion_ix < 0 || promotion_ix >= 4) { + return; + } + game_state.interaction.promotion_ix[side] = promotion_ix; +} + void cursor_events(chess::game_state& game_state, struct render::cursor_state& cursor_state, uint32_t frame_ix) { for (int cursor_ix = 0; cursor_ix < render::cursor_state::num_cursors; cursor_ix++) { auto& cursor = cursor_state.cur[cursor_ix]; const uint32_t last_frame = (frame_ix + 1) & 1; - const int8_t x = cursor.x + 0.5f; + const float x = cursor.x + 0.5f; const int8_t y = cursor.y + 0.5f; if (cursor.button[last_frame].a != cursor.button[frame_ix].a && cursor.button[frame_ix].a) { chess::clear_annotations(game_state); - chess::select_position(game_state, x, y); + if (x > 8.5) { + serial::string("white side\n"); + int8_t promotion_ix = y; + promotion_select(game_state, 0, promotion_ix); + } else if (x < -0.5) { + serial::string("black side\n"); + int8_t promotion_ix = 7 - y; + promotion_select(game_state, 1, promotion_ix); + } else { + chess::select_position(game_state, x, y); + } } if (cursor.button[last_frame].b != cursor.button[frame_ix].b && cursor.button[frame_ix].b) { chess::annotate_position(game_state, x, y); } + if (cursor.button[last_frame].x != cursor.button[frame_ix].x && cursor.button[frame_ix].x) { + piece_rotation = !piece_rotation; + } + if (cursor.button[last_frame].y != cursor.button[frame_ix].y && cursor.button[frame_ix].y) { + board_rotation = !board_rotation; + } } } @@ -134,27 +165,31 @@ void main() vt.board_rotation = 0.f; auto piece_rotation_animator = render::animator(0.f); + auto board_rotation_animator = render::animator(0.f); struct render::cursor_state cursor_state = render::cursor_state(); constexpr float pi = 3.141592653589793f; + piece_rotation = false; + board_rotation = false; while (true) { input::state_update(send_buf, recv_buf); cursor_update(cursor_state, frame_ix); cursor_events(game_state, cursor_state, frame_ix); - float target = game_state.turn == 1 ? 0.f : pi; - piece_rotation_animator.set_target(target, 60); - //vt.board_rotation = piece_rotation_animator.interpolate(); - //vt.piece_rotation = piece_rotation_animator.interpolate(); + //float target = game_state.turn == 1 ? 0.f : pi; + piece_rotation_animator.set_target(piece_rotation ? pi : 0.f, 60); + board_rotation_animator.set_target(board_rotation ? pi : 0.f, 60); + vt.board_rotation = board_rotation_animator.interpolate(); + vt.piece_rotation = piece_rotation_animator.interpolate(); ta_polygon_converter_init(opb_size.total(), ta_alloc, 640 / 32, 480 / 32); - render::render(game_state, vt, cursor_state); + render::render(vt, game_state, cursor_state); *reinterpret_cast(store_queue) = ta_global_parameter::end_of_list(para_control::para_type::end_of_list); diff --git a/chess/render.cpp b/chess/render.cpp index 1efbbba..ffdc278 100644 --- a/chess/render.cpp +++ b/chess/render.cpp @@ -190,7 +190,7 @@ void draw_moves(const view_transform vt, } void draw_piece(const view_transform vt, - int8_t type, int8_t x, int8_t y) + int8_t type, float x, float y) { bool white = type > 0; uint32_t color = white ? 0xffdddddd : 0xff444444; @@ -337,8 +337,50 @@ void draw_interaction(const view_transform vt, render::draw_illumination(vt, interaction.last_move.to_position, yellow_highlight); } -void render(const chess::game_state& game_state, - const view_transform vt, +void draw_promotion_selection(const view_transform vt, + const chess::game_state& game_state) +{ + constexpr uint32_t yellow_highlight = 0x7fffff33; + + draw_model(vt, + square::vertices, + square::faces, + square::num_faces, + yellow_highlight, + 8.5f, game_state.interaction.promotion_ix[0], + illumination_z, + 1.0f, // scale + 0.0f, // rotation + true, // always + true); // alpha + + for (int i = 0; i < 4; i++) { + draw_piece(vt, + chess::promotion_types[i], + 8.5f, i); + } + + draw_model(vt, + square::vertices, + square::faces, + square::num_faces, + yellow_highlight, + -1.5f, 7 - game_state.interaction.promotion_ix[1], + illumination_z, + 1.0f, // scale + 0.0f, // rotation + true, // always + true); // alpha + + for (int i = 0; i < 4; i++) { + draw_piece(vt, + -chess::promotion_types[i], + -1.5f, 7 - i); + } +} + +void render(const view_transform vt, + const chess::game_state& game_state, const cursor_state cursor_state) { render::draw_board(vt); @@ -347,6 +389,8 @@ void render(const chess::game_state& game_state, render::draw_annotation(vt, game_state.interaction.annotation_list); render::draw_pieces(vt, game_state); + render::draw_promotion_selection(vt, game_state); + render::draw_moves(vt, game_state.interaction.moves); for (int i = 0; i < cursor_state::num_cursors; i++) { auto& cursor = cursor_state.cur[i]; diff --git a/chess/render.hpp b/chess/render.hpp index ec58b64..28c36e4 100644 --- a/chess/render.hpp +++ b/chess/render.hpp @@ -46,6 +46,8 @@ struct animator { struct button { bool a; bool b; + bool x; + bool y; }; struct cursor { @@ -78,8 +80,8 @@ struct cursor_state { } }; -void render(const chess::game_state& game_state, - const view_transform vt, +void render(const view_transform vt, + const chess::game_state& game_state, const cursor_state cursor_state); }