From 87adc0a1df7c1d042af2adf0d76524a9e963c4cb Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 11 Apr 2026 12:04:30 +0000 Subject: [PATCH] games: add solitare(#362) Simple Solitaire game written in FASM. Bitmaps free license. Co-authored-by: Burer Reviewed-on: https://git.kolibrios.org/KolibriOS/kolibrios/pulls/362 Co-authored-by: Max Co-committed-by: Max --- data/Tupfile.lua | 1 + programs/games/solitare/License free.txt | 45 + programs/games/solitare/Tupfile.lua | 6 + programs/games/solitare/jd.bmp | Bin 0 -> 7254 bytes programs/games/solitare/jh.bmp | Bin 0 -> 7254 bytes programs/games/solitare/jp.bmp | Bin 0 -> 7254 bytes programs/games/solitare/jt.bmp | Bin 0 -> 7254 bytes programs/games/solitare/kd.bmp | Bin 0 -> 7254 bytes programs/games/solitare/kh.bmp | Bin 0 -> 7254 bytes programs/games/solitare/kp.bmp | Bin 0 -> 7254 bytes programs/games/solitare/kt.bmp | Bin 0 -> 7254 bytes programs/games/solitare/qd.bmp | Bin 0 -> 7254 bytes programs/games/solitare/qh.bmp | Bin 0 -> 7254 bytes programs/games/solitare/qp.bmp | Bin 0 -> 7254 bytes programs/games/solitare/qt.bmp | Bin 0 -> 7254 bytes programs/games/solitare/solitare.asm | 1597 ++++++++++++++++++++++ 16 files changed, 1649 insertions(+) create mode 100644 programs/games/solitare/License free.txt create mode 100644 programs/games/solitare/Tupfile.lua create mode 100644 programs/games/solitare/jd.bmp create mode 100644 programs/games/solitare/jh.bmp create mode 100644 programs/games/solitare/jp.bmp create mode 100644 programs/games/solitare/jt.bmp create mode 100644 programs/games/solitare/kd.bmp create mode 100644 programs/games/solitare/kh.bmp create mode 100644 programs/games/solitare/kp.bmp create mode 100644 programs/games/solitare/kt.bmp create mode 100644 programs/games/solitare/qd.bmp create mode 100644 programs/games/solitare/qh.bmp create mode 100644 programs/games/solitare/qp.bmp create mode 100644 programs/games/solitare/qt.bmp create mode 100644 programs/games/solitare/solitare.asm diff --git a/data/Tupfile.lua b/data/Tupfile.lua index 2a2122b97..7a3e79898 100644 --- a/data/Tupfile.lua +++ b/data/Tupfile.lua @@ -771,6 +771,7 @@ tup.append_table(extra_files, { {"kolibrios/games/marblematch3", VAR_PROGS .. "/games/marblematch3/marblematch3"}, {"kolibrios/games/nsider", VAR_PROGS .. "/games/nsider/nsider"}, {"kolibrios/games/fridge/", VAR_PROGS .. "/games/fridge/fridge"}, + {"kolibrios/games/solitare", VAR_PROGS .. "/games/solitare/solitare"}, {"kolibrios/develop/lua/lua", VAR_CONTRIB .. "/other/lua-5.2.0/lua"}, {"kolibrios/develop/lua/calc.lua", "../contrib/other/lua-5.2.0/calc.lua"}, {"kolibrios/develop/lua/console.lua", "../contrib/other/lua-5.2.0/console.lua"}, diff --git a/programs/games/solitare/License free.txt b/programs/games/solitare/License free.txt new file mode 100644 index 000000000..61899af79 --- /dev/null +++ b/programs/games/solitare/License free.txt @@ -0,0 +1,45 @@ +IMPORTANT NOTICE: This license only applies if you downloaded this content as +an unsubscribed user. If you are a premium user (ie, you pay a subscription) +you are bound to the license terms described in the accompanying file +"License premium.txt". + +--------------------- + +You must attribute the image to its author: + +In order to use a content or a part of it, you must attribute it to rawpixel.com / Freepik, +so we will be able to continue creating new graphic resources every day. + + +How to attribute it? + +For websites: + +Please, copy this code on your website to accredit the author: +Designed by rawpixel.com / Freepik + +For printing: + +Paste this text on the final work so the authorship is known. +- For example, in the acknowledgements chapter of a book: +"Designed by rawpixel.com / Freepik" + + +You are free to use this image: + +- For both personal and commercial projects and to modify it. +- In a website or presentation template or application or as part of your design. + +You are not allowed to: + +- Sub-license, resell or rent it. +- Include it in any online or offline archive or database. + +The full terms of the license are described in section 7 of the Freepik +terms of use, available online in the following link: + + http://www.freepik.com/terms_of_use + +The terms described in the above link have precedence over the terms described +in the present document. In case of disagreement, the Freepik Terms of Use +will prevail. diff --git a/programs/games/solitare/Tupfile.lua b/programs/games/solitare/Tupfile.lua new file mode 100644 index 000000000..6aa6f3884 --- /dev/null +++ b/programs/games/solitare/Tupfile.lua @@ -0,0 +1,6 @@ +if tup.getconfig("NO_FASM") ~= "" then return end +HELPERDIR = (tup.getconfig("HELPERDIR") == "") and "../.." or tup.getconfig("HELPERDIR") +tup.include(HELPERDIR .. "/use_fasm.lua") +add_include(tup.getvariantdir()) + +tup.rule("solitare.asm", FASM .. " %f %o " .. tup.getconfig("KPACK_CMD"), "solitare") diff --git a/programs/games/solitare/jd.bmp b/programs/games/solitare/jd.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0ba9f893b7c29ad2a93854b0f6aac88128f534d2 GIT binary patch literal 7254 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 x0bvG#8cqj-=z}M1gB}udhlVy62pYS9Z zvoicq+S12}e~?Glxg^+xNbG`xc$y z#gFe_y?&4UeD?g^Pj5b;j{p?GEo|*7KG28s|MQ>!L{i!u(k6WY3(z74 z;Wh1OoHlKuSamB8dSE4ZO-Cxbbz*WBeKEi2#^2<}<&-B54*WfR$F;v;#uV|B6GtB+ z15n(!&auSaN$7m~{rCH)PNT0Q1kcJ{QCUY$PHD@QEr0#%Uu9&r$iUy0zd@6g!^mM2 z6&2M50{4#}KO*B{cYnc-{jc08eDK=G{tqK1{wzCc!8?NtL2(m$CXxRP<^=FOYg+1bN~53jDSe)rvXn_saK%>Q{~zbG`|78Kt=#-O+f9Yb~{O$T}p)-B%j z>Yi>|yt#Q2ppy zlPD+aF$BiGD5shC8oxSbZcqCw8u4rlr zL3#G<*}%X6i1FOq+-6~hr_(c!WtAroXm!HW?e*8_!cg3_{^J3Shx(2TB~4wjDQfII zyNZqh;@!J!MPlF~kuR^K5$cGZ95ScP?mzBs!2@P}uc=YjJD`*Zp7 z<;|T4-Pm$>>HO~oLqCd});*fgJpnzd*KZ{D9Yr)^`syvWsverP6G4~c+d1XeJLBK~ zrC;~Sq=}`?I=-~D)ZN|P(9nQ_{6?h_8t?4vB9i%RD^cvOw#c}eCr@9EjZJv@r!rjg z&0H!BOtZln)7S@SoDLeN6C42$dekhYb*YI(sH;~=Lqps38{cMDjkom-OS<~&PA!*C zpWk)*TJqd_?3I^319Q>mAI~l>!`4vTytaedrYu!;jA7UnG9zXqk(SP}*&PyIRa@J%x_V{e*hMxkdPilKlS`11 zkx@?Wp82z%B(QCCYJ2^lbxg+Kkt6f-^9U};zkvZAk5^a0X)3Caade^^YaT}sjlC6Bo5oDj3dMpw&fLf z$ji%PFc^PPjktWcxVU&>VPSA^@aWX>va+(Fp`iy49sq8AeS?ZJPDRaZtCllXUPD=x z#)wGMw{tbM5N7P_!>f}C1Omxk=)bF{QZl%(c>D2_pI-m;?#-L`&z`@%aOrMs!;q&a z->#rpQAyd=KYd3iTS{M81o#3imui*D}d=y>76h3V<(>S|bO7s6*2i%ldF)ikW+ z6}6RA3}j^Gta2-T`p?L#;ypt0!_y=N1{4JqT-5R-x^tmEEn8DRa4W%;ZX(bk25OVS zjhOXLWy7Z8cq-j8zIcCrQ49D=@RA6wov1*^(pFDTkIUtrI(4e1rbZ%>fK`Y6+6qE& zcykCLlyDTBj=r#MLXYVda^gnR`Nu?_Fet4n)Q0Q``gHTSw)v((^@dVf*^lPPVqTR#sLN3MDr;7mNeo!ZL7p1~5iY zw%;cSJ7d< zB%VTd+1+u1phFRQr<+?lnTMw`W3n(9EVAE?h-ixr+sf3`Oh-ot&Ynoia@y`~V;>}k zRS28AZ@>z-h{$kj9^PicRKc6UV)6_R#{pH2ykl#0Wf;B_#zWU_&~FgPqc!H8;+TG{IzkU^msi*lOck|jnK zb#%*485!At;3Nm<@R+!wl=Pa-xLEnETeaPwheRT2nQ-(?!S(h3EN(Wp1A}Qa9nIdI^zCNrRQZQi7 zX56%_rnrO>2bU-xzet$V(7ejXLXwcyB+6(oGNOMGu{*1(*VN1^A~My(BgnwO0P-ck z^#}VbDu5#c-yw%l1!DzA$>myVn!?$#GL9}AI*N^Ge2^|gbU_ScvDnSH{fEzhz}&g_ z!d(a|0|qC@)*&fx|G1Ve)6ULLRu&tPQW_Mq$H07#o>3wegEciVh{?|dr%$wX0bFikA(%=8S5XyD_YD%`I%xcQnGB_Ku=- z$zgR3vbKqXjg9qIEjwV5Z*WfBt`-GFb!2Ox;&O6|Dyk-Yn?RmzqO7c(iKoceQ>3a% z(AU#<4T}Yn6}z)2G&~J7h|J=GLE|PAf^kD|!QA0=Nw$9CmiD=akAIp!_YWe8QqVME z%JJohqV2w;&IM+;^qM))ZF1KEkAOW2M(<(KvSgAdMX{DZ>pzk*@52o0o{V143 zFwS72O&RtH2?;QUZfs0oS#gr`!I&esVBTRbthnro%KjT`kDOhj3rojBvg&lmbTd&h z#i9;WgJisuKo7Es%c7guCswqYv;9n&A>dF-D-I~B5W&T$k&M8RF{3iU^+YZ`RMsSb zGjekAB+_%h6zl5hnwpwY9NfTb12fU{L(_}}Rt?1^3EW8z9-f`Y#nHKid&gXZb9KoS$BJ(7gLHNi z1U!HXK?p-!#7WpGCx?kh-Rl>%8^oAz7l)NshY%wA;`jF1`}rxA5Ly6NRn(-41R)3L zNNH&)NG4cafk2>d zYQ|&5W(x`q8JLypQWDAZSgw^P#YC)U6bng&@%FsfD?ci2)7H`=gr!yo#_qu?t9kd$ z+U}}_NfcEK6qI!Fn)W(6x(J^koreT=&z?OePMla-SqTUT(59OQ=C>mL2wq__xv6Cx zuHH#t{cLwOdWRM?x1G3g>mj7ckhgApe_XlxWKY#VKwc-&#vQh-iYF!(H(Buf^sJph zLBOOKBY=ZqlmfX|R14+cut%T}x%;LR3j*wHQdl%M3`?sH{da&JIuCy!LiTMIXXonz2JbY(+qH zHC6$V0xC!p!JLy))eMs(xWD}J%c;3}ND{qzPsLq*l{9w;l1E4(>t@bFI@#Vilu(&Fx2W?~U+!7I?G<$$|{xLul=O4CwEPTLL4vKekQjO}?|{^^jw{_yOlxTFS1 zX(6%I(POr@v_h&IUDt);0s(FItM%}K(@+_6uIUe(yB9cd*?;sx#L~lEgU6pddD79* z$+RkD@slCRhQX&#e;FFNhsvyyLWA;dmpB);`5&AWO8OjgDm|Nq1d+u%^C}?CZ|gog zwQv=ZS$HdXU^=GhAP~rYfk4{(4<8^>7n>2iDf_jxQ`jxd2iCUr8qS{C0kadAyb!+t|*yMg$(xaTiEhhi5xGfF`2eC5iOn>T+~Lj30O)6nDBpxOh) z!@$D}frDo=ntD=N4?)2Vsc}IG&c3vzdgcPm1Eo1p-M{Dat=q5g+EY+H?m74^iii+U zD?p~&+&_BlZs6d8_kl?$9*QSdpoaP4m(U)%Wb#vtZmNCMKX(fIP|_n+qCR1YFU`dGW-hfCCdqtq*+> zN~|umhuY3vE3c}C(yMpHzw{Rw^Xl~nI%9To(O5=l{Mz+Tr7&d7wQJYFxTU3~fpmdF zJ%0MVXk-~U9CYNYX!Ly0@RF!)6h%ac=B1n7eKXbP)*9N{1?304D?gX3+=8#5G`+cE z478=qm%kP7rPF-#%{L%aQ0N9+Siphho8J4!JsOUPCs%`qmx4yldo~Rt3XY;5U0ov! zgJY&vI!BL+TL!)NwZo&$e1;PwyCDU2P>_tY9b>e2R*Qu!J(5VE=tT_TRVCA8vF!YxH9|CcWN6? z@72|}@dRajK{>}J$HFp(Cn#rd!dO;m8$>vZmjsVk{8STj59r}LlsjzCUOcyW{kL}a X&N`^xw|{?pZt?!3N8jJRef$3bhPcA- literal 0 HcmV?d00001 diff --git a/programs/games/solitare/jp.bmp b/programs/games/solitare/jp.bmp new file mode 100644 index 0000000000000000000000000000000000000000..af422ad5bb4bf908378e789db9f9210036cf212c GIT binary patch literal 7254 zcmai3cUV)&+P~l5S0JH;79c=?gpvXw5L)QHhAKVMK~$R36hVLFM zv0%mSy6&pG_O9!$uDg4`UpU@e?(RO%od=JTIWzN{_no&NN1qVtKNcGwPsZ1OHu(Sl z{-LrsPQ&|n^d$fO-AJeEaRUfBfr@jP|{EzPCsPj2CopK~)vVtbpwp)d2vuxQiLtZJzX4js*6aT$|iQb<%MCc|Fvzv-T$9r(T_x=d4GpQPs@mAtym|9RI*1N|`|Gd2`nL>qo;Z(@ zf!XN*RQ1$2wc$X-#QH3PoF-mI)2M*L(MOrK1t^^H#gUBuV0nEYIO9_!ot<4y6&LH z{Xs25QG;g#n+|wwYH%;AJ3D_tI-lr(QWX^y0+e_@h86rZtUcZpFaL9osUjjT-;wliIMBquVcccOP2^-|E2@B ztBda5ySL%=y}-_i;mdc3eeT}H*gcSmr*!A?i8B!cry}>Cjyv&P$nMG5@oVpX`Y3&i z4sP>raTOI6ad=E1_>7LIb-1W|@WA+F((HZfjN-YQ5+CDelXcFPHaD1#It+96A>@JRfuTig-s);I{5{J)_TFN%ZCU^XCx}5r&3_zP`R1 z8X9hHZd@+c+}ymYtBcr2itAI;Md0o~bGhrp{8E(c?Ci^zFP}McX6azo{^LazD^5h9RxJMAqAEMH#8@uHD;|XlPGv_Z~y>;jMox6ALefQ$!ONk0CHYu)O&29qs=+UXx zq1m3j3-8~5C@!w#+hnX zwYD`kw+s&-Ja_io;X`AuUcI_?=XrQ^p}IOPA-B13ORugj9UfzOczjU7iHO8hc;vHZ z&q5!Iii*a@#$Y;t>+bHZNMTa7JrtFVD5@NiyoPV%el@0vtz+!k>OM7fJuNLQc3^B^ zQBOfp$H?Ie-+cS(`O9Bkz5eCLM;~TR-Yl=`_Vms0-Zr2})#O?Ft*zM|5w%+4rxtMo zvL^NHT#Sv4`}+EB+_+I+U*Fc&cJ$~`;F_4Q=z0beRW3!v3S5Q?C z5*LayYI!_!1$AoD{By2n5&XLjbA_g^zZuU#+aQc?ypknouuExjDQRFbP2$#Vuc#ZL zP$)}rY39}nDyk+XCe_u|K+Md{B%FesbEcdeMM;H4BCGLY(u6ss9QTBzb59e_KGx^C ztuAX9x`_4YdQKZ^U5j@jsDLEvvvTb1?QsV5S%UhAgO~Wu?k+y5xmCTc?*96YUU1V= zdf}}>vbD7}>{VD;*x|#633=w42^Ey|ai7p=%IR>9ccPU0n@%<183taSd zE$lozJj~3@EG#V4)zupt8_g~KWaZ>3G+nonCf~|~g48?}IzvgBxhAXf?YsBxUP)wm zjl_al(efO1ZC(G?gGT0M3~nKt%?2*RJj)@oM2*VM-qs_q_U2i5`}m7pHZ__?Br9oZ zOL0Lv!`0V>#R9$PYtjR)g>h!)uI!-Lu)VVkPK0o6IV4JnN{2QffUK+UefsRBfpM^% zLu__c2aDqDpFVltDk53i!p_(y zl)#lGku4H3_3S;UCS2SO1S}~j#l|I)%QYpD$+1Un#-Dr;w(k^4QAt_d9GpQT$x~fC zvt(rCmdPv=XVxX=)RIUPmMGeQoe9;@GfuIMOfcqn)$E_s(KYJon||~5)7a!yZ{Jw6 zs8k(Gp%m99zChc;R!`^(4lAo@H8rfU9_b))Tt9y16+yIU(*+r@6v7K(oA4heScil5@z&AQBFb zT$zxNW@u!#W@~R)WG;)v3Cr4%ncvK|lq528a!PJ)?g7DhaS4Sxnx~N?U==|xI-2wV zBskcLuBXTKS?A!E8$q1;@m->yecuC#9CGNGQ_QF%ZWW5T_+@DQadMn+^>f9}FVU zGH~)79UIThFJ6~di15k4&KV8@5SV~z%4+6PT+ELauUAk|@DEH+NG`%pmgRQLv9*u& z4NIYEv&}7hw6t`mW^RGWBjfk%gdU5B{YtN_oT8q|N*G}b(r7eTOS+YZlUD^u7P@4c z1r&k_$bblFJeT6uHB96dY>yI`Iy<`qmt)<=w%n3g&>oyx$>o{_h2^eq++%2D6Sh1d zGJ1`wsv40=eWh2Gi$lWS;pDi=z`#I57uXPXU_lw*E>MG}L*rTDG9jh7Zsc52+<*Ra z+4+kfp(W=>NpsEp>SdvlN3oiq8_72FESNv)aRH?|IW&B%)V<&DU zo_<8pq(LeK4x!-@QLxx(s&ocSoK40?_+J9o*f$KGg%uFFfB5{-Fib*UzIxNybx4)Up{Q`=Q>(F<`*Nd_BZ9Zz~yOao7rU+ z8(HPE1>1321NJ(UK0KsT$}cy?XUFudp62m7=9%k(ljUH3(OW4M|EA zIA2JVo}S(!xg12s`@EG&A!a)EReFIKz)Zr@z zJWGgHX8A4zNF*{w);x)(YxHRc!W~0hYAz}1XsX?ZX)?Y&;?@xgRd`iLoi10 zc~Lf(G2H@u1EX@Qdu^S?#^!?1J+myqjz!!mq0r8NBf*8WbjoW&*g&W2**QfaAk<^q zi)Zd3MCAFcvdb>z$7jN7AykG#M=%LoM79M51;>sZYi(_1u~=#vn%aCDDK4O43d-w; zBUV*1nZ}6X?9+D|^0v^8(+pVgLWf{OPBep^iUOL6!`jp3HA zI&EEIkpcww9Ftd~!N(yrfWK3qFyIS-i<%E2>imL&@yR3Oa&k|-yzmf7ac*vL+Ugcls|^P1ES8|jm|vsM&SqORvjlYlVeX2=%I@xd zppPH9%Hq0(#BW}aQKz6p2YWSiyva%wEAgriA3gvS4K;)11=yNKw_q)ob767nFJWuV-4saP2l5@k%(>I}uAGGex{1(JAY8p)g=n!o;McGK17UZ2#PgCAb(w1BV|!eth?vZ;(12J3hU0 z`dnDY;k-UcM$wixTvC_z=A<6 zsU4dI7TeJ~>fi-bkiz%QhISnZ-*aN+o})+@#OQ*PJg%*2mZt^N?^(@#reDL7DeFOL$(9qD>*Vivy1?Ic1DoC1G zc=PTZAy+>qh}WGfL6c z-30{0IF~@;0YNuP)1`+10Y9+`MWQ91JbALY`Qv~4ft4RTc<{#`f3#1|U0hiMVn@3; zw@5QSNMSciO3Ta0VyMQQD(W^85>mR%YBbjUTL}r0L79r0l{7+`%s!;Yta$kF@s1VX z^~;wpo12@TKYtc~diLy@2sf&s%ye)G*Y#>U1!|NOJ4Q;aKU?9V)L z9y+hzxz~7lX8Uy5t)r7G0wF6YDe=uW|0}tzNl0wbkA-8V`4NSIw?@cAY&qySihMtl8WC$L6+hhcEl}&-xEsT)+Pa z#sFeiSlGRL_pV&IvSUg~Nr_m(B9=wZy1F_sZa{sHO<{9)|3K5F8@z+Zs?T5Bu}I?R zA|MJ!R`>&R{K18&?y=u~`whnY{`>DsOH0q6KL`E1d-v}4S(TNQ|Hg%$rluw_ZfNUJ zaPvUd!12hjtCl$p-E%AA6=3BzZ{G@zoDQ70;n#n`{opaLwy};2JEaQaf%jj2`9(bO z-Me>YW@b`SQkIsMAY=}Q12l`p0`>bFx8;~fpQ~n8tn!=I?`~b{&tJZDP0dHO4aKz{ z+mi6fD_%#&0owQI%-YuhVuE_dyQjRnCU;f$1oTb+`s=Ua_1D(cMn^}J zl9EJ{hkjW6#ful>0o~o*2?+^(eSP8{F>X-p5rBjKSFc_@eELi@pksWCHT$d@kCv0} zhlbn_4STkZdbXZQIWfC~ua%XR{{DXPvK?bn!_%|k*MAdY+}$k$nP2a(Xbc?F`r3Ly zO`B_7zhy$Mcjts#!!ei2E}!m6pWbOhmpYz%-tdV(RZBFbukZMsJNHC%;nMNW+S>Zm;+25$>p?U3 zJ^Ri_uDtf@J0EoJj_~waYR}2HUk8hE!|J>C_l}j9m#b^CjJW)`qK=U8%4eHzMn}gy zy<_Pnk-A3vb!bTxPP?8_BbZ{a*c46&nRA$AP)cH?>CyddopTOkm9B5x$*(?Ja_Csy z!N%s%a|frEO2!xVjm(Em-xZ#@9(>`4ilOmKmoABMqe~mq^ytcHuDlXmR$kjHtjsT} z1f#_o7`*iI<*WAg4lmzCu5B*asD@-%g{LNiKOz~F6Da$cW+lSV+Pu8dndzC;ji+qW z;KZ_yn7CrFQ6Zr*M+YZCVL%#JudeVrPZOPey1qLmwi{z(V`^$RG+Iqw0VAuRqo7Qe zkyVe#X)>`2kdTnJbqG0oZvFM^w-+wVc6Id>6jmjtmZhXs4vvW*t%_;1foWAk+>D!MVfBU~*KfitV z>(y%y8=FtMd8OFow9271bV%H|!WK{O2$4MmTtVR?&df$fM+dwTXiimCRa;xz?CdPy zqEKi}O-&^f2Puz7%4tbTOIzhOc=cUCs-SlX(xNk(ad@H}N-bpeA;T?)K+V9CqHrW3 zi^IbZ1X`qMA|sy@Qg2(-qNSxHh%GIu8I+Tg6XWs=7cnd|lqQBmB2`pW3=R%vWMn`n z0=Pu7yR5v93{pc@9h%9*ehL!JS~`EHcYmaxPp1M}%dA=jZC{>pMF;FDxv; zaRaW79#0yfB(F%3Q`1E0F(R+Mq1r~v$Sb0$hEh^;EaTvPr5#ut6QhL_p4reg+y_`B z{d_8wD#E2Z71@@wB9N-VsWsIHhe;0ZE=@!7>X<*z7jPvdu^bB~i)CS9L8sG=jErvI zz74plswhQO7DNOvo)w&Cn{ha7Vbe0Z4k4q;HVc=Ol<^A73)@#AjZk2Q#IwT-sm4c0 z`UU3Z=GwF@pslhGW2yQ!yr`7&fxYo%E)4@jCol7iEl>0(zmk#&Ie84z#Ky)3aEU}B zDDcqG5C%&_$eqpJyn{#!(Gi0y6Sy&bWKUO`pGY>dXdP5UHw1*RgXI;~K|iX|lLz5(TaX z2r524K?SXY*EWDV?$LQRU~I#8a6u7EkWUs zoE_K946VaPY3WAfwfPBCzG_jFgL4Q%Mn({rO!E$gGZo{S?#)F}3{;3@P+fwa51!$p zW9~q;a*R(*iiwGVr~p(>28@WJ@~&O3**Uq1$pvT)4loPLs%d%avtyF0yI33#86_1m znT%9Y;W|er7k8u3I2gk*<_dxfViQVg8^<-M`rGxH9iE0FZ=EdG*b;nkX=^9Z+(Atf zi{qGwhK5oo6cL1+f-b1BsZWXnFUi!*no6a~$jE3A0!RiWp27LaCGCpJTEH(-PBXr= zi|3Z8$E=l*lm?x-dhJKJn;SP@%F8Qk$A#mTLLel*{Z_-!SVmq=hw4h;SfJ5pf~BLa zoxP!gppD?xs*ViPZyvyK{*|J&%~mgw#ed zvyf`iB`vLJWo_@k+ZPg+SyDM93S9q^vy=uw0M-MT!V|Qq&S^ZiI7h!gwrP+$-UG)n zff#ISyd(mn6AY@w{R@i+GvhiFh}Jy*9#e||l3@khV$j2| zi0r_SEOm9PkAFN&fhNLLMjKN(tt#r)fD6Gh!P>dEub<1cH+9?F*Eir1lL#6P@{~cU zQ#dUco!#4U?H&C{x&}Pg@S?I~2n0e)Hx}|E4Bo+mA4?*enwtBQ$@H1o??K3eBexBi zrrU85NEDX18-Y{@roi6PXfzz#U0ut;yRtnfDxJuV(;(BaSS;)cjdhhqsETo+XHRTd zSVWcy*P9=(A6|9n*<^NeNJLd^ahD#M1x6sX`iL&sEI2q^7#IgC2d5+ES6+z>>7;_P zKKKg<2L~@NFKuflBvRJDeUxY&h$9$*vcZ}#9!1udl#}<%KfCI<@Ur?q@-kqgoNVp1SC?P&1S<@1uI=& zUvKZ>6WD)V&oPX_j+I6z0?X2J@}{wQs=720uCfM3*TvVHAFrUO3|=%Lu^x6#*SAb> z7{cIK8VoaY3tNxgFNn%9WQw7tb|Bd~0z6B^{`$zwW+^FIkO|K%SwTq~2xt&E!PCCHLvU(s z_xv*@EWwaYG7H-0>gESI9ekoQ7&ucK3{O8uBl;Y!j4YM$~*Gp+53>)*-7c$ zQTc6P)s3RlbeT1lRt^}Q01RojX?!*Ys~eSB>*%>p8Ev+$splQ8H6Q6-U?YsWMm}p3sI1Txdmv~-?(rSB_*BfzheaK35rZfDDI#z z>`9KE=KEWqwnH=N(bJ=1wFQ7n)Gvf+P}|fRtwxB=J>)9LLm<^a04>VY5W14Mj$Z%33C^Z?1hV&LLLdi@6=cE= zEEVA%{Mt^RKFwq@!J6T?wqji19iaEd749$ZrqIlFY+YR%Mj>CollS4t@l=Mj8rBI* ziX>1{aOAkqxhJ6iVE0`8QbSW}WaZUN_7@0GZ-CIG5Q+-Q40$Dr4#_}2bRXbCp`)dx z1(G8O>^C+xK-wB~L%Zl|kv{@l8qF}X>jp1u3+w=bVR z|GxSB!_4fxl8Szx)MjRI5^w}gJUpe|GdNF5M%Jme4#yzT5f${NX67;vR6`KRHFwT#95S`p)6zD6ed9*!;f~PoB3oW5 zo*W0)M~9J5pr%teZ6y6dwt1$jXL@yY12D3>{uB}`BNPAVtVR_ST~)(YRl`mmrEU_P z_WI{H5I+MhR5E*pPVQd((WB>F)apC`uJN4Fx!TFa_L-&1rsnp}p~R|DSf{nM!-rph z*A)`!DR>Ixq-|8=E-I%T(1C#b6e@>QP6eLq?dTF$U*GiV)$6*(Q=usxu7WfrRi;oF z(0FRf_xSwgi@DBn%MioYjm_M-d$+Bvoo$|O z?NkDn?$=MBMox|M153!PN>Jl1#pc$UM^w91_IS0Q=9L_FE;(!&nI9RQxv_D5@Z`1r ziRJlATlJs*`Kx}zOV6Ia*p3VRPzShs=MMNL$YLfYr#hz>_;p?WT@#`*3*5EZx+W35 zwb4KRfC7#%xR_#8;n_Oj)o~gMATCwiP=2vZE!$OlG`yf;YVzFscYhZx0oU{B%+nvA z@4ywUw*C3@n>R6y-Qu3f$;r97x$PBQ_|!5s?b$Z!(=+AKe8RJBY!_4{Iwznsk<>RX zng|8n>$mR!4Y(ei6OT84+<^;aC@A<86cmUnLcrb2moLS*kiZ^4etZXX#oSHruCs1U zQ1BTFJhKrnwx-YXb*btp9{IDb+j(}jerl_j3ApZEXCFP=+>Q%kgpGl<%*)GzL)=k? zhFOre!Vv(=;<5~MLJk$sdSX}2QUAdO{?HK+TZJ%{^d6m~RRIqse{L&Tk*aNPI zNA5q~V))jr+faD`2LFv~XJ@xvq_7&41VOL@fdK3ql&xSVA>HFa6E^}zuffUsbWZpU z%z@S2jyrvM#j|HBYw^L@)U-uhwp-iSy+>ON1HUjVH#Zlm9103s`2{p}b#?Gfa80(a z05n(_=mbLwPbh0ot={4vzZ5)qJ9PF3;mB35)>Fch%MTy@<6j$4s3iM@MqGJS)H9fT zsLOX~>H8lZig960*e9H?2sbV+ZU>_16)b9TadAX=L`%!zQ>RY(WmnpyS6C(&?>czQ zHmk-WA;)xY=HQ8u9dpCVn}WwyUcY&}rB}!1Za?@3?xRPKMDaG9Y+zvEj=7>&UtgiL zw49`*w3L(##DS3YK;8;fW!Nn^I!P%R_=+cxpFP{$K7Hxto$jeQ=mA{U*3p~y9&G0q z`oRssL4&~mEn)b&yu3m&s>TvS6;+rNc9WWx7h2PaVpNMI2B9=<$gEmzdbSeE1kxpU z-?AOoP*gXbTDszXpzP7MdnDf8n>TO7Mnl{wBE0z3VE+LW>LHM)fHOtP6Cm1wxCMFu zPF2GZWJRE6!mzx;jvdqC_2o~m;@gkG`oQm%b!LNC|?x literal 0 HcmV?d00001 diff --git a/programs/games/solitare/kd.bmp b/programs/games/solitare/kd.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d687ef91637d98072265afdbed410a4be5f0e317 GIT binary patch literal 7254 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 literal 0 HcmV?d00001 diff --git a/programs/games/solitare/kh.bmp b/programs/games/solitare/kh.bmp new file mode 100644 index 0000000000000000000000000000000000000000..a92279b0854d7b8c999ad81641746d6438b01867 GIT binary patch literal 7254 zcma)B2UJwo)=sikj7k}L7X+j;Ff+hVW`?eabm<+GUIYO}6oml`q7-Q&ATS_;NE<+! z2#N&+1w{chmPBJoRx~DRiY@PhtMl{2OV+zFK{eU)Qc(`}pzW#KgqsiP`^SQ@3^w4kr%XB%3D%aYyqm4LKj_((_169Dl+d zz3EikW)!@0*YIT0*mru~@fO>16Z=P5acmvO;MVh(KYslC^_%za-hCtpzWM$A+qbjh zAAa~@YHEs@1meAW_x}9zPfY&$>#xKl?jJsW+m6A>wC5lLwli?wRiDt{*6bY_eGwKlzFeeT zMyZ?I@nk;khYugV`|i677cMk3G`x86f`^O2(9n>CoV>NWuVZu))hom$J=ZL0k84iV znmwgH<*gp2O)kZaZlz6*xiud7HD)n8tUdgmK7Cqy{NWP8wr@ynxU1>(eHxS6L}fbf z-FwWFm%u%H_H0W_%k$^Y=i_4RnarlR2dP`zYp|?zSr$}dCdGhmU}&hPZ=g*kD=Dv% zl9iKGP?RUr)K@$1E~&tlqQm!iSi}H4%zgyh?%jL10Qb_ROO=(Ci*Zk%K8^VkCr-fk zZr;3k{rdH>u`!qic@nq)#aH0|^wUr0&z~O{80hKgdG+cQ?$};e zS65hAh^N?xw*ODfB*dgINsOAxbVs9>S{vI&>Nfw zp!N0jmqa%>*te zJbU&G^r1tLg55zJW7q=F@HB7&E6+CyA{uF@ySsaGauR!aKnn(o?F&+fg`a=^8M`3( zuC%?ovl=3!cV=W}mzQ%AlF|Y;WHvQ5_xAQeSOhQf%WaCFOb@yIkW-=s-PShFq}S?k{Y`-?$&xQ`w^LhMs06sV5KS1VSmI9|TD zE+^0=EKx*KMow{^j&TW~X`eoI80Z)mQd!lyj0zg7md6z_P}SWctD?6hZet%OdEeg5 z`LRr}0eNF%V?{(nWL4B<)U^?VaDJFrR!!4njqO)Zr|MCFy8wGDHr ztlH1$JT^WJsLX0rokVddGJUq|GLxXPo$2VNN{ysZ(v|xVq(J2&o3t@2MZDj z4Y*V)75qT4N=nK!zX?KKDDj(Z$+Bh_ z+3YJf3y!Tj-U!!~m6gRK8jUu5=~7VQwj;e4kX=b6Qgn2*v9a-nAm1r&!qy#8=E+%( zCCzS}KCk+-?wp>mq5F~j*WHeGIu$h7<_BzI~mCkBaFUl8`vW z5fTzoR#sk{RW2eaB_tv$yUKp)Qa(pV$K>Q>XdC*^$;sJJT$edG`O7cA;G_g+P*PHo zkdWY%WQ^B`d8F^RJy7Lb#Mf5gR4fW zny+;^+NsR6;>oKY7~@jWA*XF7DMK+bGGa2BPEJmQLRQ<@*zU|>_=YMdC=kjab{QHP zj&su*3ZsKh&qR*DaINl*y8f$?{~@yZE?@4okP8n3x+g;}JPOY(o#Ae-JCbP`xdjH* z^N-TBaZ;Sqwwjunu!y9XoV@f3^T?<>9uhwG6Qai5-5o3e6qlr=BpfUw zb@Oy{cw$~&=*Ux#`m=POYzm`-Oba424|*KG=+}M~jyHHBW2|MDH7<71n%#%pkM)a4 z&sq@i0;^#_5>{TiTn36=x^!t~W+qhn_19l7Teggkk55jUCN3%E@9)2M?OKALprD|L zhzR)Pxkh$x^=ALp%O)EODa;z0X@$jFHo{rQG~c!IY(`1ZbW7BMJv&52#RLR|RMpgG zU6mvTBA~W<_3Guz`NX76iE@FWE}IY^Ehqb_&RDW!2?Siaj9*Z2c0De9m6w+{H8sU} zYf}8Jw%G8*P3rUnih++;z=8dTYmLlOl+-;{scxgK8ROk~`uh414ZGk=#CBpVC?F^- zMqcub$jX%~0qtO^8|809@bKlAUqUoLKR;nHsw~-1XT2XuNMaV7A184>+(GklYesWv zf@4ve4)YL&S#4;Vio{6w%uUPBzs22DoSy|I0|Nu0$+>;}Fwh(W0?U^#7m+aZ^z=lG zEL*x%Ut2B2YqhbVzKe?saOrfqxVVIvl<_LoYU_+*nr}F`g+IgApaU~yB!~5tZM556 zvSxRM4l`$!ra#Rt%Y)N1a3b^enLH>H>yZETL18U*8y^7@NzK|`KOh?32>U>XKSLGJV z(D=34m3sb3TIPvPrES64#Z#@DhE7!>=zxorxPwm}=RgD}YE(j9xPuy`o*q0r)0gG2x7050q?%s5Y0|;f zyARt3ZLB{OQ&nCBSpXdw87U(p1BMaND4GO?gq7%S5Ec-kqN4Hf@jmOVRaKZi&gQ~` zOYstfKMM+L^9zUr1u_CiOiWZtN(#n;>hLu&A>q!ct%W(M9<@U{CV85=-eg9u?f%+; zgC!FUp@}gYum*OV&Bk*VGl6ZnD}R-_t(2UprKKg*1!y}vJ7JQbz78$Y&qhj85-AJS zoT#KRc0fxo1hE%mtoQQrf*@Td3TIBGc<$J%Yo3Rb0Lwa+%Bs;Z&9%#}8LUe>UB5>~ zMTOV}^yPef2qGn8a~V}LJ^>j-BB0?ygkr7eie7H^7>kRGlSH9aG5EQ(v^3ywfe181 z3<3lEraQNBN_MHzBDE+!y7ZJ|ZCxf7DeBs8nkI?qd$-TDCvFT5z!pTSmX;Q=3poeb z0^y1LKp^6d?3a}muc4uV@mF6h5tXE4mz$d#@iHQj#6@LRD5z-&l0=o2Robd|-|pHT zT6SW6MZYeq0O4b3x_vfjm=rtYcX(HKjWopf)@Q+9n>TMp#DNsl4qGE7N-C==nOGng zVM;In(>vO)gY$zcAu$>szcBnCi?IdQD$_MyCokA$SK&1j6BTx=eREM^rb~H;SJOo| z&RM8eMaxr{QDUFVbt!L;ocJXzCu62HDmHQ>DBzmamw*5mKpr-Z-tNo20-BhaB|VoA zQc_a9eF7!qOysnwvT}-0IG(~%jM!9psv*|6#itC`r;aqG2GsUMTz&4}H5qm7SKqdA zO_Ss`X&k&J@Ro_X_R_y~q_aHwVpArRj9okfA>Z1h=B$p|>fqo2%5Zg8S68?zUUm|) zrYjB2oJw1?oqVtbPr(-1*$*=`d$-cO)LU&au{%>Cms4>Q5=Yh#y)mNb;7)+TUcte^dU|>|(nt1A1|+AUSc78mx=%_<($?0d>RGJN zT?;T74Kgz>4G}a4%TE%Ll-1OYhzy@8h zEVS8I=60-K&C>CcymN-YVdG5gw#z4z-7^p2HRM&(m(kr5(mmnM>9x5^C7Kd0=BlcaB`eXIK}Ll)|kZn!r=Z}UdIP4w(e84v?B=#&*efP0YM=QKt_?yV#c#Q z>dpjoUUNO%5A$> zlCp+4U?T)vj-HCX@hV~WwmUsLp>4y^M9TzrdR}31B`2e_%A>Nw!P_6WKq;#dK4@pQ`#mvUNZXi1|?0jpE z4&6vWQ3*8{4vHw~BvvX*N=YHI^78WL;}Yk2lvfpH#jWMrSmvg(idJN!qWSd^a-*(s zp^ni38Z+O}yinKV2!&b2;|E_?C_AIH(f5x!SrAf^n~swe%0raxxcmD0qM(C^>g&nwo9UQvbJAm!!mz9%SfLaDcA1WzyjSw9bm0T*blFBNhF^edS z5(W5^a2lO>Zi>npOt!^2UhqeMd4NE8d8|1Y?BilP$e%`MF+ez6PHBAoEI-+n{! z`}px=RN_SKf2g1|EIi@x;lsUseW*kd6SuUqcJJT6pJ)hNxpIZ*0xiHL{ECoq!5uX< zb|LOi^5fC(zyFTj1qM%^JOTeGe$h<=Z+J>{vCwrvO@~Sr7nF&10T!cUfB||k3vmBQ z&jb&U3q1`K_z(?!5BLTM;t|>l00lZ4#b69=2dn`c)?ffEjA2u(1m{o}*!$mc(HKF~ z4;>QJ@_<0+1eOIgqNf3xn1?Kwgyvy!*bxlCdkIG(tO*{#EqwLgalgI$nvfLtAAkH2 zjTH2AFh*+#eI!7md&64*k>Opyf>7wufdO8VhqneA#$K50UvTRi9|=o$_MQ2Ww~J69 zzCtwk7`nT>M;JhR=(^wnE{DUxeR1yyih@oMzyE~W)bf~5v>gpSA*qhu{!h@55nV^L zK2WI<_ImyLHC&oN2QC-`OF*otsevazMe`ZM7?0op=p-z_CHk>#?N64AaOd|>6imFhZ3W)oSN~PdkAC=FQsLBmQ1nif zGUe1YZl0hIEsjwSVDBd z=iLFFmN}axa3H~<_t2q3AdY?@&=Dg5h4SGuxWF4c86BZLd-lM!7U&tfkT+nX#kgzi zF8~Gd&fWh{+n#=-=)d`^E&A>9Jp>FKGx`)>mgA}RFj z=X&Q>TBYVXXCHOUD)-Fiur{-u({pX&QW?G>%Eo3EwsvM_rl`VT%K5mE7dn9(EWjO~ zn11{2BYuO3+;pwE_3?*~e^=Lj9}#;Epf6s$#34;uMh1Ne4NVQQE=8VZB&$Wik2p%Y zdYWt3D;h8i=yU~|5!E}4Y~!THus|bXZ$rm?Tp+?CNU#u@NV9l~_X6+th53sy#?MBn zjXj!{!M?TKnPXGTsH}Ba^}DXz*>m%WzU%hD-s$}#qfz6}Y0f)>dTtbq47(R`wJqW^ z#-`#1uHF6q(R^w!E}{<}$eRQ%JPnhJuZG@%kc*EPVFxx0-i^8ZgMCh`JLg>F=#LR& zKba>Kp_>sg`YdeZsZ~;8`1uDh!;d0QPdQ~A3F)}vS3j6=s05q_qW^G=j?6o=BN0N&0&fs?azNK{QufN zWH;$lypP0eeQ+Amt$^jZg_b3<*$wZGY02bKItJ{^EGEqyXSVgq_k#Vyj!@m zViQ=-ZJnt&yO?_UJ%{jG|E8(p#mfoj)>z&-374KGU3r$(H?g+1Cdf)~e){xj{QU3c z_~x5$o<4p0~1<&FGcgZ;R!N6!)5;w3 z8k{S8TxloS6&9A1loXc~$H&Km9vB$7+tt<7%v^(E z7?GGvem*fVp{S@Ry*aeCweQ@yL%iCe?=QdnGBq_dIXOvwh{@HfS6f;Rj5 z^2sNNPXv-6oZ#Hn*7mQs@Z%k04R#yN!$O-Xa8O$-kPkaIa5GRO=Cr_RzC@28;tFONL^wUp?Z@1uL zU-b6<nNjRt3Xz=gtwk9!#JM-eM)pPACfnVSnuU(a}-Z8K78?Xh*z363}xu2iB8p zx8VNt(@)r{#AYGZzKpdePx%*SY8?}oa`w=mJmEx33TA%2on|-*5?HK1qMND;O^hQpWzoC9TT}emmXPN=hMGH zHM0_zP^4-EZs@+L5h(yM*&tf=X&V`uxIo0^KrtG zDgzfpQ&ZEZx=wCGU+&SV%&sBd@^;(IDp>`^wua)R?ueixv$5Bnd$f*g*f|S}h)PIN zl~mo-w4*f{DVq8j8uVlpTA2KH2T?I;85MQMoSK9?FADgz55}UJE7OsUah74{3JD46 z>gpoBkop1_L=6oMF=>i@UOf&|WrndZNJ2vR>e6^gS9PRk!+>A+eDL^{u+wWcykfd{ zDAkxLyF-&g-65x`v%`jM7M-#)tBN~tHfZ!xXw%W#6Dg^WZ3UBB3wrjA3qWe&ooJ#~*xvt%t+{Tyb&npg`{WY-%zu+_P;WWb$gwrq&AaEc!<0(Or@gKgR z=N079I$_WD$5w?>kOyn3tE;gM!+Yn~9>34y@ia9xQ&Ur6oX&>a+as}V3CZ?3wVrL0 z`15L;^y!`tpIP-Ekctl7 zE~{!o7inct2|6gaFeD@-h>3{>2M6=g(qfkXbN1GKoVGeTIzd4jG8-BiUY#fyZI0u# zP2d*i(LU+XJnCH0#f;5%DnIPiG40tg<=!+JJbgX5vG3kg+Fb7;6B`F*BMZO5bFdgp zy{WaROHH43YKfw%Bb)66=i&}vU|<0L^78UV4o=RM-71 z#ohgm(|tVh;xpgg^EzgS%(!(?S3dFSTL>7x5;}ips=xHscuHJ$z82dPCiZNf#3hG_ zA1!SS(k2)on>cdhd3wr1Isju7jf~ayrNQETpaWz&|z>TC8fE(!W*MWA$=z} zU2~porx>gzbDK#etdj<;BelM9yLoC~X}sv_;+rW(NYdoazbuFv!7U7|DV z46Kg0`!?7*A2wih8nCO~>yIsu7v7pLx3sj}U?D7`p{^k;EGjG_jw=?T1$Q1XNv${E zrV!;qfU9v#bOfT8`1$tRZ@=@-J7VHe5)zW|IAI6mE((PLm8W}4uZ{AoLekW9!mW4Z zXO#4WMe~_gM$OoI|K$Uo(LWQZTytd-L9;ilapg*WyNJ{X=pohcG0nOaUB9WE@R5dYBE$7 zofGUka85x>51%03^z`%)A&{1TXirkKC+_gp`x`ar@p|UvyYjm;4)?81#E=JB zv#^DKaZ~d4_67y{=j!R+{?S} z1AKgZe4Z>;jCZ8FR&~2pPiPoNyB4>wB9r#-kDctRadUISN<<)pL@;cpQtdJ~5{0y? z1|0YL>#qX>Uce>_^)OYZv3J|hpeQT}y129nL*oBS4X^j^_2r z_`Jq?x4LNtvsK3+%FwmUy=5%5BxkBV(3``78R1Yo2~j-{Ph0Vdl=Pf*>6XY&Us21TD zfMPGFq@-9|Tgz+dQB-z-Id<`zZ@vk^*tUk)u&{%KjK#KXe@ci2m@)kJdL5qT^c-in z_*4{SAT8w9)gXHJE`8vT-mlN>q#H*uteU)g&J)DJ=Hz>G`79O_{sjjN7}m?n3%YZ9 zPM}QQ;Qn%84LobV(??p-KvGVDMx(N@4fK6qH{dOPlL22%EnZedQDX zV@nD5e{?Dx)i%xMbe!II^J|Z`iG+JU?rrVAITYL5l!sIU_Jn!Cip65FOFL|RgJCq# zkpxUkOyE{JogpR5V)%v!POZx9(0nP85WBpSxj)C;$$h*tZ+$i;xTuEHHIGx_Cq zoVGAN&R-chLyC$%;EY1!v>n}X`e2R);!^UuuD*HMy!FY1;zI|l4;F$sGL>^#2d8Z^ zXlyy_`s47^>$rIM_ML`Ec#BTUL{r3-sdA|1?(U8_LFtD|XJ7lVhQ`LOt}dug*dH5w zU)%wojwxnhE_d{jye6Fh-Sn^!w&cq2!Bah&AlM+dQ6Uosa4E=s3s zH*eW^_(&^JMMb3`4@8BJa2c38l7D|XC91hM?D$>o;36wNOWVZ<*Evz~jU#)*Cektr zI{I`@h)ZpM=O@4ox) z;K75$xr1DdW1_h#^TAkTL0x(D(tB3>(j+MI6j^<$Mt~+GP1m%FVcASKZ`3g^QP)jW zRM{;dr6w*TXA+*c=gh;X<&Rn_qgLmtu~T*xHgoc-vupYMfsuHAcj(|5M`ss6Bd(w? zd7VaGkAoYbn4B1g6g1si?37t1r?^8|-A|u+7`t`Lb)Ec)S2`wT@=CTMqT=SU>3+Q@ z=32tK_=RdlW)3@d5`_|q!tD$bY-$)B6}liU1VG7vTV+Q>;o?Y{wz0XA>TZT*hai7I zAW3c#`#0wQyL`|wE~UsBDCinE?n}NlmL9n`6kbDR`uXRd!_f$Dl&FBf{do&6sXGd^ zfZziL7KIGUc70~oMtx*;G+<9Fzo~bBVp?Bce|kndcLgfw)D9O5oZ>0A;eD%93==ah>G}u;&3i}2Rp<2q&k?u;D|8@fH@Yx z8hAn^Vhv;f1!8Q$g?)ha$^mG?r0^Qimj)u7y9F2gfdY460s+v0AwfX_F8WK5e+w?3 z&j$oP~}P77znQM$-w4x8TBSxR$&U z8n+`fuW*o|=>e6At`uShE`~;U1=T7lDu4?(ggVY#9CpY{$Ve|?|BD@gZ(kYDP>Q(f zZ_yfkU3`u`f}nz4kemoAJVA#6LBuP>IpPWvpaU0l5)>1}16=uc`3jp9*C7%Y>O&FY z^P-kcn#1lLCYB5{OG_&&Y&2XXLPA19Lqh`s0(^aaabtIKazYT|4r63yj@=}P3**BS zuiQt(G8hfeK!ontg9P!5=g*bY)LkPJ+|ml|)60CChP+xv{W>OGYI@!42b?OpU2A$> zYx>;z!@fPoxx*K@-Lnhl76ox(9QYT$*y3Noa{;**Cw_f>J^5k7(4;{?6ittzrAMbw z)x^Zbp)77kLff|C?&s+2tg1mn&&0;w0oQw6t56Q$01{Lg5sqNM5KJbJK@b;ka3Tr% z?TZ&Fvx|AFYet-GpYDa?)w_XX%W9^MA+tA=R-U4>p=PnuqiM*ud)71}SzSA(nIN{&Ekx=@43I?NA{zkum7`=}BKhh^$txc_#aHh;aXWi?J!a;b4JZHL zm1ot9i?K7SHlBs)OLt1nulQ9By2Lesm^5|H!hsh(aPsQP3ds`(3i25F6B8uE{{gmU B^J)M9 literal 0 HcmV?d00001 diff --git a/programs/games/solitare/kt.bmp b/programs/games/solitare/kt.bmp new file mode 100644 index 0000000000000000000000000000000000000000..dff881013643810ebfee791312a67f2c1d0428bf GIT binary patch literal 7254 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 literal 0 HcmV?d00001 diff --git a/programs/games/solitare/qd.bmp b/programs/games/solitare/qd.bmp new file mode 100644 index 0000000000000000000000000000000000000000..8fb8712dd12fce727052b540a62b4e1f6221efda GIT binary patch literal 7254 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 Mr6HIS2Rg?850ntb-T(jq literal 0 HcmV?d00001 diff --git a/programs/games/solitare/qh.bmp b/programs/games/solitare/qh.bmp new file mode 100644 index 0000000000000000000000000000000000000000..cda415734d03b0ba15fc00eab46971e3efd336eb GIT binary patch literal 7254 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 qAt2I4EM-Mol_p*(DafR+>!! literal 0 HcmV?d00001 diff --git a/programs/games/solitare/qt.bmp b/programs/games/solitare/qt.bmp new file mode 100644 index 0000000000000000000000000000000000000000..92753dce51a466259cc2dc11b1ce8138b2cc5382 GIT binary patch literal 7254 zcmai3cT`hppZ@m$*_l74oIPj08IWch1yrQkKsrbdEhO}gNKug90|*I_1PGz`A|>=* z1VZnKC;}>AA1mPK=Vor8;&e?k|mpAvm_kG@9FIU}=^zVP|9j9?UwEw4u|Nrr? z|Ju7Rj_1x83I4twd_Mo~*Q1mj(ayHT$&7NKC8nP}f!h*u4rlwqO zZc$NjLw!S0VNqOc+}BtC*Z+-;jVE7^_4W1p_wRrGwf}!^ZVsdW{(5v2hY#o3HfFlF z;mYTa^!4^};vAX_!rEHfc6WD$Yl;q3RaFVx z@4x^4k3aqpJ`%-!`0!y1)3&y{@~jr^5;elPyk)G&4xqQI?9-AWTbf(U%}C{C6>r|W znVy<%Y;5xP4=gDx=*h9K;EyPoE zUdDxmMcdok!ZkmA`ZPB;kDtk@rI60d1ivrGj#qpGvJf)-=bwKTMZ}mO{PE+*|A;#} zyI^0|-k&SrFixPSrzVw_mSI0aTnugv3_@Q1SJ_sS3}Es5+j=?H16@s^nwS<55kX+d z$jC@bOGB@K>*3)+JpCKJU%q_ttsl%{co3ktW`(#4QpFe+|7@t^QTc;&vpH}n1PaF+t z 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 literal 0 HcmV?d00001 diff --git a/programs/games/solitare/solitare.asm b/programs/games/solitare/solitare.asm new file mode 100644 index 000000000..d38bb1978 --- /dev/null +++ b/programs/games/solitare/solitare.asm @@ -0,0 +1,1597 @@ +; SPDX-License-Identifier: GPL-2.0-only +; Program - Solitaire card game +; Copyright (C) 2026 KolibriOS team +; Author: Max +; Graphics: Designed by rawpixel.com / Freepik (see 'License free.txt') +; http://www.freepik.com + +use32 +org 0x0 + +db 'MENUET01' +dd 0x01 +dd start +dd i_end +dd mem_end +dd stacktop +dd 0, 0 + +include '../../macros.inc' +include '../../KOSfuncs.inc' + +; --- CONSTANTS --- +CARD_W equ 70 +CARD_H equ 100 +STACK_OFFSET equ 25 +WIN_W equ 760 +WIN_H equ 560 +BPP equ 3 +STRIDE equ WIN_W * BPP +BMP_W equ 40 +BMP_H equ 60 +BMP_BPP equ 3 +BMP_LINE equ (BMP_W * BMP_BPP) +COL_TABLE equ 0x207020 +COL_REVERSE equ 0x0000AA +COL_WHITE equ 0xFFFFFF +COL_RED equ 0xCC0000 +COL_BLACK equ 0x000000 +COL_SLOT equ 0x185018 ; Dark gray/green for slots +CARD_STRUCT_SIZE equ 12 +CARD_VALUE equ 0 +CARD_SUIT equ 1 +CARD_STATE equ 2 +CARD_LOC equ 3 +CARD_X equ 4 +CARD_Y equ 6 +CARD_OLD_X equ 8 +CARD_OLD_Y equ 10 +STOCK_X equ 20 +WASTE_X equ 100 +FOUNDATION_X equ 420 +FOUND_Y equ 20 +SCORE_Y equ 525 +BTN_REPLAY equ 100 +BTN_EXIT equ 101 + +start: + mcall SF_STYLE_SETTINGS, SSF_GET_SKIN_HEIGHT + mov [skin_h], eax + call init_game_state + +event_loop: + cmp byte [exit_request], 1 + je .force_exit + mcall SF_CHECK_EVENT + cmp eax, 1 + je on_redraw + cmp eax, 2 + je on_key + cmp eax, 3 + je on_button + cmp byte [game_won], 1 + je .win_animation + call handle_mouse + jmp .check_redraw + +.win_animation: + call update_cascade + mov byte [force_redraw], 1 + cmp byte [win_thread_active], 0 + jne .check_reset + inc dword [win_timer] + cmp dword [win_timer], 120 + jl .check_reset + mov byte [win_thread_active], 1 + call create_win_thread + +.check_reset: + cmp byte [should_reset], 1 + jne .no_reset + call init_game_state + call draw_main_window +.no_reset: + mcall SF_SLEEP, 1 + jmp update_screen_only + +.check_redraw: + cmp dword [active_card_count], 0 + ja update_screen_only + cmp byte [force_redraw], 1 + je update_screen_only + mcall SF_SLEEP, 1 + jmp event_loop + +.force_exit: + mcall SF_TERMINATE_PROCESS + +on_key: + mcall SF_GET_KEY + jmp event_loop + +on_button: + mcall SF_GET_BUTTON + shr eax, 8 + cmp eax, 1 + jne event_loop + mcall SF_TERMINATE_PROCESS + +on_redraw: + call draw_main_window + mov byte [force_redraw], 1 + jmp update_screen_only + +update_screen_only: + mov byte [force_redraw], 0 + call prepare_buffer + mov edx, 4 shl 16 + add dx, word [skin_h] + mcall SF_PUT_IMAGE, screen_buffer, WIN_W shl 16 + WIN_H + jmp event_loop + +init_game_state: + call init_deck + call shuffle_deck + call layout_tableau + mov dword [score], 0 + mov byte [game_won], 0 + mov dword [win_timer], 0 + mov byte [win_thread_active], 0 + mov byte [should_reset], 0 + mov byte [exit_request], 0 + mov dword [active_cascade_idx], -1 + mov dword [cascade_timer], 0 + ret + +draw_main_window: + mcall SF_REDRAW, SSF_BEGIN_DRAW + mov ebx, 100 shl 16 + (WIN_W + 9) + mov eax, [skin_h] + add eax, WIN_H + 5 + mov ecx, 100 shl 16 + mov cx, ax + mcall SF_CREATE_WINDOW, , , 0x14000000 or COL_TABLE, 0, title + mcall SF_REDRAW, SSF_END_DRAW + ret + +create_win_thread: + mcall SF_CREATE_THREAD, SSF_CREATE_THREAD, win_thread_entry, win_stack_top + ret + +win_thread_entry: + mcall SF_THREAD_INFO, win_proc_info, -1 + mov eax, [win_proc_info + 34] + add eax, 200 + shl eax, 16 + add eax, 300 + mov [win_pos_x], eax + mov eax, [win_proc_info + 38] + add eax, 180 + shl eax, 16 + add eax, 180 + mov [win_pos_y], eax +.redr: + mcall SF_REDRAW, SSF_BEGIN_DRAW + mcall SF_CREATE_WINDOW, [win_pos_x], [win_pos_y], 0x34FFFFFF, 0x80505050, title_win + mcall SF_DRAW_TEXT, 70 shl 16 + 35, 0x80000000, msg_congrats + mcall SF_DRAW_TEXT, 100 shl 16 + 65, 0x80000000, msg_score_lbl + mov eax, [score] + mov edi, score_str + call int_to_string + mcall SF_DRAW_TEXT, 160 shl 16 + 65, 0x80000000, score_str + mcall SF_DEFINE_BUTTON, 40 shl 16 + 100, 100 shl 16 + 30, BTN_REPLAY, 0xCCCCCC + mcall SF_DRAW_TEXT, 66 shl 16 + 110, 0x80000000, txt_replay + mcall SF_DEFINE_BUTTON, 160 shl 16 + 100, 100 shl 16 + 30, BTN_EXIT, 0xCCCCCC + mcall SF_DRAW_TEXT, 194 shl 16 + 110, 0x80000000, txt_exit + mcall SF_REDRAW, SSF_END_DRAW +.wait_ev: + mcall SF_WAIT_EVENT + cmp eax, 1 + je .redr + cmp eax, 3 + jne .wait_ev + mcall SF_GET_BUTTON + shr eax, 8 + cmp eax, BTN_EXIT + je .trigger_exit + cmp eax, BTN_REPLAY + jne .wait_ev +.replay_game: + mov byte [should_reset], 1 + mcall SF_TERMINATE_PROCESS + jmp .wait_ev +.trigger_exit: + mov byte [exit_request], 1 + mcall SF_TERMINATE_PROCESS + +int_to_string: + pushad + mov ebx, 10 + xor ecx, ecx + test eax, eax + jnz .l1 + mov byte [edi], '0' + inc edi + jmp .fin +.l1: xor edx, edx + div ebx + add dl, '0' + push edx + inc ecx + test eax, eax + jnz .l1 +.l2: pop edx + mov [edi], dl + inc edi + loop .l2 +.fin: + mov byte [edi], 0 + popad + ret + +update_cascade: + pushad + inc dword [cascade_timer] + cmp dword [cascade_timer], 3 + jl .move_active + mov dword [cascade_timer], 0 + cmp dword [active_cascade_idx], 51 + jge .move_active + inc dword [active_cascade_idx] +.move_active: + mov ecx, [active_cascade_idx] + cmp ecx, 0 + jl .done +.l: + push ecx + imul esi, ecx, CARD_STRUCT_SIZE + add esi, deck_data + imul edi, ecx, 4 + add edi, card_vectors + inc word [edi+2] + mov ax, [edi+2] + add [esi+CARD_Y], ax + mov ax, [edi] + add [esi+CARD_X], ax + mov ax, [esi+CARD_Y] + add ax, CARD_H + cmp ax, WIN_H + jl .no_y_bounce + mov word [esi+CARD_Y], WIN_H - CARD_H + mov ax, [edi+2] + neg ax + sar ax, 1 + mov [edi+2], ax +.no_y_bounce: + mov ax, [esi+CARD_X] + cmp ax, 0 + jg .not_left + mov word [esi+CARD_X], 0 + neg word [edi] +.not_left: + add ax, CARD_W + cmp ax, WIN_W + jl .no_x_bounce + mov word [esi+CARD_X], WIN_W - CARD_W + neg word [edi] +.no_x_bounce: + pop ecx + dec ecx + jns .l +.done: + popad + ret + +init_cascade_vectors: + pushad + xor ecx, ecx +.l: + imul edi, ecx, 4 + add edi, card_vectors + mcall SF_GET_SYS_TIME + push eax + and eax, 0x0F + sub eax, 7 + jnz .x_ok + inc eax +.x_ok: + mov [edi], ax + pop eax + shr eax, 4 + and eax, 0x07 + neg eax + sub eax, 4 + mov [edi+2], ax + inc ecx + cmp ecx, 52 + jl .l + popad + ret + +handle_mouse: + pushad + mcall SF_MOUSE_GET, SSF_WINDOW_POSITION + mov ebp, eax + shr ebp, 16 + sub ebp, 5 + and eax, 0xFFFF + sub eax, [skin_h] + mov edi, eax + mcall SF_MOUSE_GET, SSF_BUTTON + test eax, 1 + jnz .dragging_state + cmp dword [mouse_lock], 1 + jne .exit + mov dword [mouse_lock], 0 + cmp dword [active_card_count], 0 + je .exit + call check_stack_move + mov dword [active_card_count], 0 + mov byte [force_redraw], 1 + popad + ret +.dragging_state: + cmp dword [mouse_lock], 1 + je .no_deal_click + cmp ebp, STOCK_X + jb .find_card + cmp ebp, STOCK_X+CARD_W + jae .find_card + cmp edi, FOUND_Y + jb .find_card + cmp edi, FOUND_Y+CARD_H + jae .find_card + mov dword [mouse_lock], 1 + call deal_from_stock + mov byte [force_redraw], 1 + popad + ret +.find_card: + mov ebx, 51 +.f_loop: + imul edx, ebx, CARD_STRUCT_SIZE + add edx, deck_data + movsx esi, word [edx+CARD_X] + movsx ecx, word [edx+CARD_Y] + cmp ebp, esi + jb .next_s + add esi, CARD_W + cmp ebp, esi + jae .next_s + cmp edi, ecx + jb .next_s + add ecx, CARD_H + cmp edi, ecx + jae .next_s + test byte [edx+CARD_STATE], 1 + jz .next_s + mov dword [mouse_lock], 1 + mov [active_stack], ebx + mov dword [active_card_count], 1 + mov ax, word [edx+CARD_X] + sub ax, bp + mov [mouse_off_x], ax + mov ax, word [edx+CARD_Y] + sub ax, di + mov [mouse_off_y], ax + mov eax, ebx + call build_active_stack + popad + ret +.next_s: + dec ebx + jns .f_loop + popad + ret +.no_deal_click: + cmp dword [active_card_count], 0 + je .exit_drag + xor ecx, ecx +.d_lp: + cmp ecx, [active_card_count] + jae .exit_drag + mov eax, [active_stack + ecx*4] + imul eax, CARD_STRUCT_SIZE + add eax, deck_data + mov dx, [mouse_off_x] + add dx, bp + mov [eax+CARD_X], dx + mov dx, [mouse_off_y] + add dx, di + push eax + mov eax, ecx + imul eax, STACK_OFFSET + add dx, ax + pop eax + mov [eax+CARD_Y], dx + inc ecx + jmp .d_lp +.exit_drag: + popad + ret +.exit: + popad + ret + +prepare_buffer: + mov edi, screen_buffer + mov ecx, WIN_W * WIN_H + mov eax, COL_TABLE +.clear_loop: + mov [edi], al + mov [edi+1], ah + push eax + shr eax, 16 + mov byte [edi+2], al + pop eax + add edi, 3 + dec ecx + jnz .clear_loop + call draw_slots + call render_score_ui + xor ecx, ecx +.draw_loop: + call is_card_active + jc .skip + push ecx + imul esi, ecx, CARD_STRUCT_SIZE + add esi, deck_data + call draw_card_to_buffer + pop ecx +.skip: + inc ecx + cmp ecx, 52 + jl .draw_loop + xor ecx, ecx +.draw_active: + cmp ecx, [active_card_count] + jae .done_rendering + push ecx + mov eax, [active_stack + ecx*4] + imul esi, eax, CARD_STRUCT_SIZE + add esi, deck_data + call draw_card_to_buffer + pop ecx + inc ecx + jmp .draw_active +.done_rendering: + ret + +draw_card_to_buffer: + pushad + movsx ebx, word [esi+CARD_X] + movsx ecx, word [esi+CARD_Y] + mov edx, COL_BLACK + mov edi, CARD_W + mov ebp, CARD_H + call fill_rect_buf + inc ebx + inc ecx + mov edx, COL_WHITE + mov edi, CARD_W-2 + mov ebp, CARD_H-2 + call fill_rect_buf + test byte [esi+CARD_STATE], 1 + jnz .face_up + add ebx, 4 + add ecx, 4 + mov edx, COL_REVERSE + mov edi, CARD_W-10 + mov ebp, CARD_H-10 + call fill_rect_buf + popad + ret + +.face_up: + mov edx, COL_RED + cmp byte [esi+CARD_SUIT], 2 + jb .is_red + mov edx, COL_BLACK +.is_red: + push edx + push esi + movzx eax, byte [esi+CARD_VALUE] + dec eax + push esi + mov esi, eax + push ebx + push ecx + add ebx, 4 + add ecx, 4 + call draw_char_to_buf + pop ecx + pop ebx + pop esi + push esi + movzx eax, byte [esi+CARD_SUIT] + add eax, 13 + push ebx + push ecx + add ebx, 10 + add ecx, 4 + mov esi, eax + call draw_char_to_buf + pop ecx + pop ebx + pop esi + push esi + movzx eax, byte [esi+CARD_SUIT] + add eax, 13 + push ebx + push ecx + add ebx, CARD_W - 15 + add ecx, CARD_H - 11 + mov esi, eax + call draw_char_to_buf + pop ecx + pop ebx + pop esi + movzx eax, byte [esi+CARD_VALUE] + dec eax + push esi + mov esi, eax + push ebx + push ecx + add ebx, CARD_W - 9 + add ecx, CARD_H - 11 + call draw_char_to_buf + pop ecx + pop ebx + pop esi + pop esi + pop edx + + pushad + movzx eax, byte [esi+CARD_VALUE] + movzx edx, byte [esi+CARD_SUIT] + + movsx ebx, word [esi+CARD_X] + add ebx, 15 + movsx ecx, word [esi+CARD_Y] + add ecx, 20 + + cmp eax, 11 + je .face_jack + cmp eax, 12 + je .face_queen + cmp eax, 13 + je .face_king + jmp .patterns + +.face_jack: + cmp edx, 0 + je .set_jp + cmp edx, 1 + je .set_jd + cmp edx, 2 + je .set_jh + mov esi, db_jt + jmp .render_face + .set_jp: mov esi, db_jp + jmp .render_face + .set_jd: mov esi, db_jd + jmp .render_face + .set_jh: mov esi, db_jh + jmp .render_face + +.face_queen: + cmp edx, 0 + je .set_qp + cmp edx, 1 + je .set_qd + cmp edx, 2 + je .set_qh + mov esi, db_queen + jmp .render_face + .set_qp: mov esi, db_qp + jmp .render_face + .set_qd: mov esi, db_qd + jmp .render_face + .set_qh: mov esi, db_qh + jmp .render_face + +.face_king: + cmp edx, 0 + je .set_kp + cmp edx, 1 + je .set_kd + cmp edx, 2 + je .set_kh + mov esi, db_kt + jmp .render_face + .set_kp: mov esi, db_kp + jmp .render_face + .set_kd: mov esi, db_kkaro + jmp .render_face + .set_kh: mov esi, db_kh + jmp .render_face + +.render_face: + call draw_bitmap_to_buf + jmp .face_done + +.patterns: + mov edx, COL_RED + cmp byte [esi+CARD_SUIT], 2 + jb .set_center_color + mov edx, COL_BLACK +.set_center_color: + dec eax + mov eax, [pattern_offsets + eax*4] + add eax, card_patterns + mov ebp, eax +.pat_loop: + mov al, [ebp] + cmp al, 0xFF + je .face_done + push edx + movzx ebx, byte [ebp] + add bx, word [esi+CARD_X] + movzx ecx, byte [ebp+1] + add cx, word [esi+CARD_Y] + movzx eax, byte [esi+CARD_SUIT] + add eax, 13 + push esi + mov esi, eax + call draw_char_to_buf + pop esi + pop edx + add ebp, 2 + jmp .pat_loop + +.face_done: + popad + popad + ret + +draw_bitmap_to_buf: + pushad + add ecx, BMP_H + dec ecx + mov dword [temp_counter2], BMP_H +.row_loop: + cmp ecx, 0 + jl .skip_row + cmp ecx, WIN_H + jge .skip_row + push ebx + mov eax, ecx + imul eax, STRIDE + add eax, screen_buffer + mov ebp, BMP_W +.pixel_loop: + cmp ebx, 0 + jl .next_p + cmp ebx, WIN_W + jge .next_p + lea edi, [ebx*2 + ebx] + mov dl, [esi] + mov [eax+edi], dl + mov dl, [esi+1] + mov [eax+edi+1], dl + mov dl, [esi+2] + mov [eax+edi+2], dl +.next_p: + add esi, 3 + inc ebx + dec ebp + jnz .pixel_loop + pop ebx + jmp .row_finish +.skip_row: + add esi, BMP_LINE +.row_finish: + dec ecx + dec dword [temp_counter2] + jnz .row_loop + popad + ret + +fill_rect_buf: + pushad + mov esi, ebp +.yl: + cmp ecx, 0 + jl .skip_line + cmp ecx, WIN_H + jge .skip_line + push ecx + push ebx + mov eax, ecx + imul eax, STRIDE + add eax, screen_buffer + mov dword [temp_counter], edi +.xl: + cmp ebx, 0 + jl .skip_pixel + cmp ebx, WIN_W + jge .skip_pixel + push eax + mov ecx, ebx + imul ecx, 3 + add eax, ecx + mov [eax], dl + mov [eax+1], dh + push edx + shr edx, 16 + mov [eax+2], dl + pop edx + pop eax +.skip_pixel: + inc ebx + dec dword [temp_counter] + jnz .xl + pop ebx + pop ecx +.skip_line: + inc ecx + dec esi + jnz .yl + popad + ret + +draw_char_to_buf: + pushad + imul esi, 7 + add esi, font_5x7 + mov ebp, 7 +.y_loop: + push ebx + push ecx + mov al, [esi] + mov ah, 10000000b + mov dword [temp_counter], 5 +.x_loop: + test al, ah + jz .skip_pixel + cmp ebx, 0 + jl .skip_pixel + cmp ebx, WIN_W + jge .skip_pixel + cmp ecx, 0 + jl .skip_pixel + cmp ecx, WIN_H + jge .skip_pixel + push eax + mov eax, ecx + imul eax, STRIDE + push ebx + imul ebx, 3 + add eax, ebx + pop ebx + add eax, screen_buffer + mov [eax], dl + mov [eax+1], dh + push edx + shr edx, 16 + mov [eax+2], dl + pop edx + pop eax +.skip_pixel: + shr ah, 1 + inc ebx + dec dword [temp_counter] + jnz .x_loop + pop ecx + pop ebx + inc esi + inc ecx + dec ebp + jnz .y_loop + popad + ret + +draw_large_char_to_buf: + pushad + imul esi, 12 + add esi, font_8x12 + mov ebp, 12 +.y_loop: + push ebx + push ecx + mov al, [esi] + mov ah, 10000000b + mov dword [temp_counter], 8 +.x_loop: + test al, ah + jz .skip_pixel + cmp ebx, 0 + jl .skip_pixel + cmp ebx, WIN_W + jge .skip_pixel + cmp ecx, 0 + jl .skip_pixel + cmp ecx, WIN_H + jge .skip_pixel + push eax + mov eax, ecx + imul eax, STRIDE + push ebx + imul ebx, 3 + add eax, ebx + pop ebx + add eax, screen_buffer + mov [eax], dl + mov [eax+1], dh + push edx + shr edx, 16 + mov [eax+2], dl + pop edx + pop eax +.skip_pixel: + shr ah, 1 + inc ebx + dec dword [temp_counter] + jnz .x_loop + pop ecx + pop ebx + inc esi + inc ecx + dec ebp + jnz .y_loop + popad + ret + +render_score_ui: + mov edx, COL_BLACK + mov ebx, 480 + mov ecx, SCORE_Y + xor esi, esi + call draw_large_char_to_buf + add ebx, 10 + mov esi, 1 + call draw_large_char_to_buf + add ebx, 10 + mov esi, 2 + call draw_large_char_to_buf + add ebx, 10 + mov esi, 3 + call draw_large_char_to_buf + add ebx, 10 + mov esi, 4 + call draw_large_char_to_buf + add ebx, 20 + mov eax, [score] + test eax, eax + jns .pos + neg eax + push eax + mov ecx, SCORE_Y + mov esi, 5 + call draw_large_char_to_buf + add ebx, 10 + pop eax +.pos: + mov edi, 10 + xor ecx, ecx +.dec_loop: + xor edx, edx + div edi + push edx + inc ecx + test eax, eax + jnz .dec_loop +.print_dec: + pop edx + add edx, 6 + push ecx + mov ecx, SCORE_Y + mov esi, edx + mov edx, COL_BLACK + call draw_large_char_to_buf + add ebx, 10 + pop ecx + loop .print_dec + ret + +draw_slots: + pushad + ; Foundation slots (Top Right) + mov ebx, FOUNDATION_X + mov ecx, FOUND_Y + mov dword [temp_counter2], 4 +.f_loop: + mov edx, COL_SLOT + mov edi, CARD_W + mov ebp, CARD_H + call fill_rect_buf + add ebx, 80 + dec dword [temp_counter2] + jnz .f_loop + + ; Stock slot (Top Left) + mov ebx, STOCK_X + mov ecx, FOUND_Y + mov edx, COL_SLOT + mov edi, CARD_W + mov ebp, CARD_H + call fill_rect_buf + + ; Waste slot (Next to Stock) + mov ebx, WASTE_X + mov ecx, FOUND_Y + mov edx, COL_SLOT + mov edi, CARD_W + mov ebp, CARD_H + call fill_rect_buf + + ; Tableau slots (Bottom rows) + mov ebx, 40 + mov ecx, 140 + mov dword [temp_counter2], 7 +.t_loop: + mov edx, COL_SLOT + mov edi, CARD_W + mov ebp, CARD_H + call fill_rect_buf + add ebx, 105 + dec dword [temp_counter2] + jnz .t_loop + popad + ret + +is_card_active: + push eax + push ebx + xor ebx, ebx +.l: + cmp ebx, [active_card_count] + jae .no + mov eax, [active_stack + ebx*4] + cmp eax, ecx + je .yes + inc ebx + jmp .l +.yes: + pop ebx + pop eax + stc + ret +.no: + pop ebx + pop eax + clc + ret + +build_active_stack: + pushad + imul esi, eax, CARD_STRUCT_SIZE + add esi, deck_data + mov bx, [esi+CARD_X] + mov dx, [esi+CARD_Y] + movzx ebp, dx + add ebp, STACK_OFFSET +.y_search: + xor ecx, ecx +.l: + imul edi, ecx, CARD_STRUCT_SIZE + add edi, deck_data + cmp word [edi+CARD_X], bx + jne .nx + cmp word [edi+CARD_Y], bp + jne .nx + mov edx, [active_card_count] + mov [active_stack + edx*4], ecx + inc dword [active_card_count] + add ebp, STACK_OFFSET + jmp .y_search +.nx: + inc ecx + cmp ecx, 52 + jl .l +.done: + xor ecx, ecx +.save: + cmp ecx, [active_card_count] + jae .fin + mov eax, [active_stack + ecx*4] + imul eax, CARD_STRUCT_SIZE + add eax, deck_data + mov dx, [eax+CARD_X] + mov [eax+CARD_OLD_X], dx + mov dx, [eax+CARD_Y] + mov [eax+CARD_OLD_Y], dx + inc ecx + jmp .save +.fin: + popad + ret + +check_stack_move: + pushad + mov esi, [active_stack] + imul esi, CARD_STRUCT_SIZE + add esi, deck_data + cmp dword [active_card_count], 1 + jne .tableau_check + mov ebx, FOUNDATION_X + xor ecx, ecx +.f_lp: + movsx eax, word [esi+CARD_X] + sub eax, ebx + add eax, 35 + cmp eax, 70 + ja .next_f + movsx eax, word [esi+CARD_Y] + sub eax, FOUND_Y + add eax, 50 + cmp eax, 100 + ja .next_f + call check_foundation_logic + jc .found_match +.next_f: + add ebx, 80 + inc ecx + cmp ecx, 4 + jl .f_lp +.tableau_check: + mov ebx, 40 +.col_lp: + xor ecx, ecx + mov dword [temp_val], -1 + mov dword [temp_counter], 0 +.find_l: + imul edi, ecx, CARD_STRUCT_SIZE + add edi, deck_data + push ecx + call is_card_active + pop ecx + jc .sk_l + cmp word [edi+CARD_X], bx + jne .sk_l + movzx eax, word [edi+CARD_Y] + cmp eax, [temp_counter] + jl .sk_l + mov [temp_counter], eax + mov [temp_val], ecx +.sk_l: + inc ecx + cmp ecx, 52 + jl .find_l + cmp dword [temp_val], -1 + je .empty_col + mov ecx, [temp_val] + imul edi, ecx, CARD_STRUCT_SIZE + add edi, deck_data + movsx eax, word [esi+CARD_X] + movsx edx, word [edi+CARD_X] + sub eax, edx + add eax, 35 + cmp eax, 70 + ja .nx_col + movsx eax, word [esi+CARD_Y] + movsx edx, word [edi+CARD_Y] + sub eax, edx + add eax, 50 + cmp eax, 100 + ja .nx_col + mov al, [esi+CARD_SUIT] + mov dl, [edi+CARD_SUIT] + shr al, 1 + shr dl, 1 + cmp al, dl + je .nx_col + mov al, [esi+CARD_VALUE] + mov dl, [edi+CARD_VALUE] + inc al + cmp al, dl + jne .nx_col + mov dx, word [edi+CARD_Y] + add dx, STACK_OFFSET + jmp .apply_move +.empty_col: + movsx eax, word [esi+CARD_X] + sub eax, ebx + add eax, 35 + cmp eax, 70 + ja .nx_col + movsx eax, word [esi+CARD_Y] + sub eax, 140 + add eax, 50 + cmp eax, 100 + ja .nx_col + cmp byte [esi+CARD_VALUE], 13 + jne .nx_col + mov dx, 140 + jmp .apply_move +.nx_col: + add ebx, 105 + cmp ebx, 750 + jl .col_lp + xor ecx, ecx +.back: + cmp ecx, [active_card_count] + jae .out + mov eax, [active_stack + ecx*4] + imul eax, CARD_STRUCT_SIZE + add eax, deck_data + mov dx, [eax+CARD_OLD_X] + mov [eax+CARD_X], dx + mov dx, [eax+CARD_OLD_Y] + mov [eax+CARD_Y], dx + inc ecx + jmp .back +.out: + popad + ret +.found_match: + test byte [esi+CARD_STATE], 0x80 + jnz .already_scored + add dword [score], 10 + or byte [esi+CARD_STATE], 0x80 +.already_scored: + mov word [esi+CARD_X], bx + mov word [esi+CARD_Y], FOUND_Y + mov byte [esi+CARD_LOC], 8 + pushad + mov eax, [active_stack] + mov [temp_active], eax + call move_single_to_top + popad + call auto_reveal_all + call check_win + popad + ret +.apply_move: + xor ecx, ecx + push eax + push edx + mov eax, ebx + sub eax, 40 + xor edx, edx + mov edi, 105 + div edi + mov [temp_val], eax + pop edx + pop eax + mov [temp_counter2], edx +.sticky_loop: + cmp ecx, [active_card_count] + jae .sticky_done + mov eax, [active_stack + ecx*4] + imul eax, CARD_STRUCT_SIZE + add eax, deck_data + mov word [eax+CARD_X], bx + mov dx, word [temp_counter2] + mov word [eax+CARD_Y], dx + mov dl, byte [temp_val] + mov byte [eax+CARD_LOC], dl + add word [temp_counter2], STACK_OFFSET + inc ecx + jmp .sticky_loop +.sticky_done: + xor ecx, ecx +.top_loop: + cmp ecx, [active_card_count] + jae .ok + push ecx + mov eax, [active_stack + ecx*4] + mov [temp_active], eax + call move_single_to_top + call update_active_stack_after_move + pop ecx + inc ecx + jmp .top_loop +.ok: + call auto_reveal_all + popad + ret + +update_active_stack_after_move: + pushad + mov edx, [temp_active] + xor ecx, ecx +.up_lp: + cmp ecx, [active_card_count] + jae .up_dn + mov eax, [active_stack + ecx*4] + cmp eax, edx + jbe .no_chg + dec eax + mov [active_stack + ecx*4], eax +.no_chg: + inc ecx + jmp .up_lp +.up_dn: + popad + ret + +check_foundation_logic: + pushad + xor eax, eax + mov dword [temp_val], 0 + mov dword [temp_counter], -1 + xor ebp, ebp +.find_top: + imul edi, ebp, CARD_STRUCT_SIZE + add edi, deck_data + cmp word [edi+CARD_X], bx + jne .nx_c + cmp word [edi+CARD_Y], FOUND_Y + jne .nx_c + movzx edx, byte [edi+CARD_VALUE] + cmp edx, [temp_val] + jle .nx_c + mov [temp_val], edx + mov [temp_counter], ebp +.nx_c: + inc ebp + cmp ebp, 52 + jl .find_top + mov al, [esi+CARD_VALUE] + mov dl, [esi+CARD_SUIT] + cmp dword [temp_counter], -1 + jne .not_empty + cmp al, 1 + je .valid + jmp .invalid +.not_empty: + mov edi, [temp_counter] + imul edi, CARD_STRUCT_SIZE + add edi, deck_data + cmp dl, [edi+CARD_SUIT] + jne .invalid + mov dl, [edi+CARD_VALUE] + inc dl + cmp al, dl + je .valid +.invalid: + popad + clc + ret +.valid: + popad + stc + ret + +check_win: + pushad + xor ecx, ecx + xor eax, eax +.l: + imul esi, ecx, CARD_STRUCT_SIZE + add esi, deck_data + cmp byte [esi+CARD_LOC], 8 + jne .no + inc eax +.no: + inc ecx + cmp ecx, 52 + jl .l + cmp eax, 52 + jne .out + cmp byte [game_won], 0 + jne .out + add dword [score], 100 + mov byte [game_won], 1 + call init_cascade_vectors +.out: + popad + ret + +auto_reveal_all: + pushad + mov ebx, 40 +.col_loop: + xor esi, esi + mov dword [temp_val], -1 + xor ecx, ecx +.find_lowest: + imul edi, ecx, CARD_STRUCT_SIZE + add edi, deck_data + cmp word [edi+CARD_X], bx + jne .next_card + movzx eax, word [edi+CARD_Y] + cmp eax, [temp_val] + jle .next_card + mov [temp_val], eax + mov esi, edi +.next_card: + inc ecx + cmp ecx, 52 + jl .find_lowest + cmp dword [temp_val], -1 + je .next_col + or byte [esi+CARD_STATE], 1 +.next_col: + add ebx, 105 + cmp ebx, 750 + jl .col_loop + popad + ret + +move_single_to_top: + mov eax, [temp_active] + cmp eax, 51 + je .done + imul esi, eax, CARD_STRUCT_SIZE + add esi, deck_data + mov edi, temp_card_buf + mov ecx, 3 + cld + rep movsd + mov eax, [temp_active] + inc eax + imul esi, eax, CARD_STRUCT_SIZE + add esi, deck_data + imul edi, [temp_active], CARD_STRUCT_SIZE + add edi, deck_data + mov ecx, 51 + sub ecx, [temp_active] + imul ecx, 3 + rep movsd + mov esi, temp_card_buf + mov edi, deck_data + (51 * CARD_STRUCT_SIZE) + mov ecx, 3 + rep movsd +.done: ret + +deal_from_stock: + pushad + mov ecx, 51 +.f: + imul esi, ecx, CARD_STRUCT_SIZE + add esi, deck_data + cmp byte [esi+CARD_LOC], 7 + jne .n + test byte [esi+CARD_STATE], 1 + jnz .n +.o: + or byte [esi+CARD_STATE], 1 + mov byte [esi+CARD_LOC], 9 + mov word [esi+CARD_X], WASTE_X + mov word [esi+CARD_Y], FOUND_Y + mov [temp_active], ecx + call move_single_to_top + popad + ret +.n: dec ecx + jns .f + call reset_stock + popad + ret + +reset_stock: + sub dword [score], 20 + xor ecx, ecx +.l: + imul esi, ecx, CARD_STRUCT_SIZE + add esi, deck_data + cmp byte [esi+CARD_LOC], 9 + jne .s + and byte [esi+CARD_STATE], 0xFE + mov byte [esi+CARD_LOC], 7 + mov word [esi+CARD_X], STOCK_X + mov word [esi+CARD_Y], FOUND_Y +.s: inc ecx + cmp ecx, 52 + jl .l + ret + +init_deck: + mov edi, deck_data + xor eax, eax +.s: xor ebx, ebx +.r: inc ebx + mov byte [edi+CARD_VALUE], bl + mov byte [edi+CARD_SUIT], al + mov byte [edi+CARD_STATE], 0 + mov byte [edi+CARD_LOC], 7 + add edi, CARD_STRUCT_SIZE + cmp ebx, 13 + jne .r + inc eax + cmp eax, 4 + jne .s + ret + +; --- PRNG (Linear Congruential Generator) --- +; Uses constants from Numerical Recipes: a=1103515245, c=12345 +seed_rng: + mcall SF_GET_SYS_TIME + imul eax, eax, 1103515245 + add eax, 12345 + mov [rng_state], eax + ret + +; Returns pseudo-random value in eax +rng_next: + mov eax, [rng_state] + imul eax, eax, 1103515245 + add eax, 12345 + mov [rng_state], eax + shr eax, 16 + and eax, 0x7FFF + ret + +shuffle_deck: + call seed_rng + mov dword [temp_counter2], 51 +.sh: + call rng_next + xor edx, edx + mov ebx, [temp_counter2] + inc ebx + div ebx + imul esi, [temp_counter2], CARD_STRUCT_SIZE + add esi, deck_data + imul edi, edx, CARD_STRUCT_SIZE + add edi, deck_data + mov ecx, 3 +.sw: + mov eax, [esi] + mov edx, [edi] + mov [esi], edx + mov [edi], eax + add esi, 4 + add edi, 4 + loop .sw + dec dword [temp_counter2] + jnz .sh + ret + +layout_tableau: + mov edi, deck_data + mov ebx, 40 + xor edx, edx +.cols: + mov ecx, 140 + mov eax, edx + inc eax + mov ebp, eax +.cards: + mov word [edi+CARD_X], bx + mov word [edi+CARD_Y], cx + mov byte [edi+CARD_LOC], dl + dec ebp + jnz .h + or byte [edi+CARD_STATE], 1 + jmp .nx +.h: + and byte [edi+CARD_STATE], 0xFE +.nx: + add edi, CARD_STRUCT_SIZE + add ecx, STACK_OFFSET + cmp edx, 6 + je .cl + cmp ebp, 0 + jne .cards + add ebx, 105 + inc edx + jmp .cols +.cl: + cmp ebp, 0 + jne .cards +.sf: + cmp edi, deck_data + (52 * CARD_STRUCT_SIZE) + jae .fin + mov word [edi+CARD_X], STOCK_X + mov word [edi+CARD_Y], FOUND_Y + mov byte [edi+CARD_LOC], 7 + and byte [edi+CARD_STATE], 0xFE + add edi, CARD_STRUCT_SIZE + jmp .sf +.fin: ret + +; --- DATA --- +title db 'Solitare V1.6', 0 +title_win db 'Winner!', 0 +msg_congrats db 'Congrats You Win', 0 +msg_score_lbl db 'SCORE: ', 0 +txt_replay db 'REPLAY', 0 +txt_exit db 'EXIT', 0 + + +; ... Font Data ... +font_8x12: +db 01111100b,10000010b,10000000b,10000000b,01111100b,00000010b,00000010b,10000010b,01111100b,00000000b,00000000b,00000000b +db 01111100b,10000010b,10000000b,10000000b,10000000b,10000000b,10000000b,10000010b,01111100b,00000000b,00000000b,00000000b +db 01111100b,10000010b,10000010b,10000010b,10000010b,10000010b,10000010b,10000010b,01111100b,00000000b,00000000b,00000000b +db 11111100b,10000010b,10000010b,10000010b,11111100b,10010000b,10001000b,10000100b,10000010b,00000000b,00000000b,00000000b +db 11111110b,10000000b,10000000b,10000000b,11111100b,10000000b,10000000b,10000000b,11111110b,00000000b,00000000b,00000000b +db 00000000b,00000000b,00000000b,00000000b,11111111b,00000000b,00000000b,00000000b,00000000b,00000000b,00000000b,00000000b +db 00111100b,01000010b,10000001b,10000001b,10000001b,10000001b,10000001b,01000010b,00111100b,00000000b,00000000b,00000000b +db 00011000b,00111000b,00001000b,00001000b,00001000b,00001000b,00001000b,00001000b,00111100b,00000000b,00000000b,00000000b +db 01111100b,10000010b,00000010b,00000010b,01111100b,10000000b,10000000b,10000000b,11111110b,00000000b,00000000b,00000000b +db 01111100b,10000010b,00000010b,00000010b,00111100b,00000010b,00000010b,10000010b,01111100b,00000000b,00000000b,00000000b +db 00001000b,00011000b,00101000b,01001000b,10001000b,11111111b,00001000b,00001000b,00001000b,00000000b,00000000b,00000000b +db 11111110b,10000000b,10000000b,11111100b,00000010b,00000010b,00000010b,10000010b,01111100b,00000000b,00000000b,00000000b +db 01111100b,10000010b,10000000b,11111100b,10000010b,10000010b,10000010b,10000010b,01111100b,00000000b,00000000b,00000000b +db 11111110b,00000010b,00000100b,00001000b,00010000b,00100000b,00100000b,00100000b,00100000b,00000000b,00000000b,00000000b +db 01111100b,10000010b,10000010b,10000010b,01111100b,10000010b,10000010b,10000010b,01111100b,00000000b,00000000b,00000000b +db 01111100b,10000010b,10000010b,10000010b,10000010b,01111110b,00000010b,10000010b,01111100b,00000000b,00000000b,00000000b + +font_5x7: +db 01110000b,10001000b,10001000b,11111000b,10001000b,10001000b,10001000b +db 11110000b,00001000b,00010000b,00100000b,01000000b,10000000b,11111000b +db 11110000b,00001000b,00001000b,01110000b,00001000b,00001000b,11111000b +db 10001000b,10001000b,10001000b,11111000b,00001000b,00001000b,00001000b +db 11111000b,10000000b,10000000b,11110000b,00001000b,00001000b,11111000b +db 01110000b,10000000b,10000000b,11110000b,10001000b,10001000b,01110000b +db 11111000b,00001000b,00010000b,00100000b,01000000b,01000000b,01000000b +db 01110000b,10001000b,10001000b,01110000b,10001000b,10001000b,01110000b +db 01110000b,10001000b,10001000b,01111000b,00001000b,00001000b,01110000b +db 10111000b,10101000b,10101000b,10101000b,10101000b,10101000b,10111000b +db 00011000b,00001000b,00001000b,00001000b,00001000b,10001000b,01110000b +db 01110000b,10001000b,10001000b,10001000b,10101000b,10010000b,01101000b +db 10001000b,10010000b,10100000b,11000000b,10100000b,10010000b,10001000b +db 01010000b,11111000b,11111000b,01110000b,00100000b,00000000b,00000000b +db 00100000b,01110000b,11111000b,11111000b,01110000b,00100000b,00000000b +db 00100000b,00100000b,11111000b,11111000b,00100000b,00100000b,01110000b +db 00100000b,01110000b,11111000b,11111000b,01110000b,00100000b,01110000b + +pattern_offsets: +dd p1-card_patterns, p2-card_patterns, p3-card_patterns, p4-card_patterns, p5-card_patterns +dd p6-card_patterns, p7-card_patterns, p8-card_patterns, p9-card_patterns, p10-card_patterns +card_patterns: +p1 db 32,46, 0xFF +p2 db 32,20, 32,72, 0xFF +p3 db 32,20, 32,46, 32,72, 0xFF +p4 db 18,20, 47,20, 18,72, 47,72, 0xFF +p5 db 18,20, 47,20, 18,72, 47,72, 32,46, 0xFF +p6 db 18,20, 47,20, 18,46, 47,46, 18,72, 47,72, 0xFF +p7 db 18,20, 47,20, 18,46, 47,46, 18,72, 47,72, 32,33, 0xFF +p8 db 18,20, 47,20, 18,46, 47,46, 18,72, 47,72, 32,33, 32,59, 0xFF +p9 db 18,20, 47,20, 18,40, 47,40, 18,60, 47,60, 18,80, 47,80, 32,50, 0xFF +p10 db 18,20, 47,20, 18,40, 47,40, 18,60, 47,60, 18,80, 47,80, 32,30, 32,70, 0xFF + +align 4 +; --- Bitmap Data --- +; Suit mapping: 0=hearts(red), 1=diamonds(red), 2=clubs(black), 3=spades(black) +; File naming: h=hearts, d=diamonds, t=trefl/clubs, p=pik/spades +db_jp: file 'jh.bmp':54 +db_jh: file 'jt.bmp':54 +db_jd: file 'jd.bmp':54 +db_jt: file 'jp.bmp':54 +db_qp: file 'qh.bmp':54 +db_qh: file 'qt.bmp':54 +db_qd: file 'qd.bmp':54 +db_queen: file 'qp.bmp':54 +db_kp: file 'kh.bmp':54 +db_kh: file 'kt.bmp':54 +db_kkaro: file 'kd.bmp':54 +db_kt: file 'kp.bmp':54 + + +i_end: + +score rd 1 +game_won rb 1 +win_timer rd 1 +win_thread_active rb 1 +should_reset rb 1 +exit_request rb 1 +mouse_lock rd 1 +force_redraw rb 1 +temp_counter rd 1 +temp_counter2 rd 1 +temp_val rd 1 +mouse_off_x rw 1 +mouse_off_y rw 1 +temp_active rd 1 +temp_card_buf rd 3 +active_card_count rd 1 +active_stack rd 13 +skin_h rd 1 +cascade_timer rd 1 +active_cascade_idx rd 1 +win_pos_x rd 1 +win_pos_y rd 1 +rng_state rd 1 + +align 4 +deck_data: rb 52 * CARD_STRUCT_SIZE +card_vectors: rw 52 * 2 +win_proc_info: rb 1024 +score_str rb 16 + +align 64 +stack_bottom: rb 16384 +stacktop: + +align 64 +win_stack_bottom: rb 8192 +win_stack_top: + +screen_buffer: rb WIN_W * WIN_H * 3 + 32768 +mem_end: