From a6577f520b6923858960b069e552458c12975a62 Mon Sep 17 00:00:00 2001 From: James Bulman Date: Mon, 6 Oct 2025 17:49:08 +0100 Subject: [PATCH] Fixed ??? Some files have been renamed --- assets/npc_back_base_0.png | Bin 0 -> 650 bytes assets/npc_back_base_1.png | Bin 0 -> 677 bytes assets/npc_back_face_1.png | Bin 0 -> 232 bytes assets/npc_back_face_2.png | Bin 0 -> 204 bytes assets/npc_back_hair_1.png | Bin 0 -> 483 bytes assets/npc_back_hair_2.png | Bin 0 -> 395 bytes assets/npc_back_hair_3.png | Bin 0 -> 243 bytes assets/npc_back_hat_1.png | Bin 0 -> 319 bytes assets/npc_back_hat_2.png | Bin 0 -> 298 bytes assets/npc_back_shirt_0.png | Bin 0 -> 560 bytes assets/npc_back_shirt_1.png | Bin 0 -> 521 bytes assets/npc_back_shoes_0.png | Bin 0 -> 274 bytes assets/npc_back_trousers_0.png | Bin 0 -> 337 bytes assets/npc_back_trousers_1.png | Bin 0 -> 325 bytes ...nt_base_black.png => npc_front_base_0.png} | Bin ...nt_base_white.png => npc_front_base_1.png} | Bin ...ont_eyes_blue.png => npc_front_eyes_0.png} | Bin ...nt_eyes_brown.png => npc_front_eyes_1.png} | Bin ...nt_eyes_green.png => npc_front_eyes_2.png} | Bin ..._face_redMask.png => npc_front_face_1.png} | Bin ...ace_whiteMask.png => npc_front_face_2.png} | Bin ..._face_glasses.png => npc_front_face_3.png} | Bin ...ace_moustache.png => npc_front_face_4.png} | Bin ...t_hair_blonde.png => npc_front_hair_1.png} | Bin ...nt_hair_brown.png => npc_front_hair_2.png} | Bin ...ont_hair_grey.png => npc_front_hair_3.png} | Bin ...ront_hat_brown.png => npc_front_hat_1.png} | Bin ...ront_hat_white.png => npc_front_hat_2.png} | Bin ..._shirt_brown.png => npc_front_shirt_0.png} | Bin ..._shirt_white.png => npc_front_shirt_1.png} | Bin ..._shoes_brown.png => npc_front_shoes_0.png} | Bin ...sers_blue.png => npc_front_trousers_0.png} | Bin ...ers_white.png => npc_front_trousers_1.png} | Bin assets/npc_side_base_0.png | Bin 0 -> 636 bytes assets/npc_side_base_1.png | Bin 0 -> 639 bytes assets/npc_side_eyes_0.png | Bin 0 -> 199 bytes assets/npc_side_eyes_1.png | Bin 0 -> 191 bytes assets/npc_side_eyes_2.png | Bin 0 -> 176 bytes assets/npc_side_eyes_closed.png | Bin 0 -> 124 bytes assets/npc_side_face_1.png | Bin 0 -> 257 bytes assets/npc_side_face_2.png | Bin 0 -> 242 bytes assets/npc_side_face_3.png | Bin 0 -> 135 bytes assets/npc_side_face_4.png | Bin 0 -> 133 bytes assets/npc_side_hair_1.png | Bin 0 -> 346 bytes assets/npc_side_hair_2.png | Bin 0 -> 329 bytes assets/npc_side_hair_3.png | Bin 0 -> 235 bytes assets/npc_side_hat_1.png | Bin 0 -> 321 bytes assets/npc_side_hat_2.png | Bin 0 -> 328 bytes assets/npc_side_shirt_0.png | Bin 0 -> 448 bytes assets/npc_side_shirt_1.png | Bin 0 -> 403 bytes assets/npc_side_shoes_0.png | Bin 0 -> 259 bytes assets/npc_side_trousers_0.png | Bin 0 -> 421 bytes assets/npc_side_trousers_1.png | Bin 0 -> 393 bytes code/core/string.h | 1 + code/draw/core.c | 85 ++++++++------- code/draw/core.h | 9 +- code/first.c | 49 ++++----- code/game/core.h | 46 +++++++- code/game/impl/player.c | 102 +++++++++++++++++- code/game/impl/world.c | 7 +- code/game/player.h | 5 + 61 files changed, 229 insertions(+), 75 deletions(-) create mode 100644 assets/npc_back_base_0.png create mode 100644 assets/npc_back_base_1.png create mode 100644 assets/npc_back_face_1.png create mode 100644 assets/npc_back_face_2.png create mode 100644 assets/npc_back_hair_1.png create mode 100644 assets/npc_back_hair_2.png create mode 100644 assets/npc_back_hair_3.png create mode 100644 assets/npc_back_hat_1.png create mode 100644 assets/npc_back_hat_2.png create mode 100644 assets/npc_back_shirt_0.png create mode 100644 assets/npc_back_shirt_1.png create mode 100644 assets/npc_back_shoes_0.png create mode 100644 assets/npc_back_trousers_0.png create mode 100644 assets/npc_back_trousers_1.png rename assets/{npc_front_base_black.png => npc_front_base_0.png} (100%) rename assets/{npc_front_base_white.png => npc_front_base_1.png} (100%) rename assets/{npc_front_eyes_blue.png => npc_front_eyes_0.png} (100%) rename assets/{npc_front_eyes_brown.png => npc_front_eyes_1.png} (100%) rename assets/{npc_front_eyes_green.png => npc_front_eyes_2.png} (100%) rename assets/{npc_front_face_redMask.png => npc_front_face_1.png} (100%) rename assets/{npc_front_face_whiteMask.png => npc_front_face_2.png} (100%) rename assets/{npc_front_face_glasses.png => npc_front_face_3.png} (100%) rename assets/{npc_front_face_moustache.png => npc_front_face_4.png} (100%) rename assets/{npc_front_hair_blonde.png => npc_front_hair_1.png} (100%) rename assets/{npc_front_hair_brown.png => npc_front_hair_2.png} (100%) rename assets/{npc_front_hair_grey.png => npc_front_hair_3.png} (100%) rename assets/{npc_front_hat_brown.png => npc_front_hat_1.png} (100%) rename assets/{npc_front_hat_white.png => npc_front_hat_2.png} (100%) rename assets/{npc_front_shirt_brown.png => npc_front_shirt_0.png} (100%) rename assets/{npc_front_shirt_white.png => npc_front_shirt_1.png} (100%) rename assets/{npc_front_shoes_brown.png => npc_front_shoes_0.png} (100%) rename assets/{npc_front_trousers_blue.png => npc_front_trousers_0.png} (100%) rename assets/{npc_front_trousers_white.png => npc_front_trousers_1.png} (100%) create mode 100644 assets/npc_side_base_0.png create mode 100644 assets/npc_side_base_1.png create mode 100644 assets/npc_side_eyes_0.png create mode 100644 assets/npc_side_eyes_1.png create mode 100644 assets/npc_side_eyes_2.png create mode 100644 assets/npc_side_eyes_closed.png create mode 100644 assets/npc_side_face_1.png create mode 100644 assets/npc_side_face_2.png create mode 100644 assets/npc_side_face_3.png create mode 100644 assets/npc_side_face_4.png create mode 100644 assets/npc_side_hair_1.png create mode 100644 assets/npc_side_hair_2.png create mode 100644 assets/npc_side_hair_3.png create mode 100644 assets/npc_side_hat_1.png create mode 100644 assets/npc_side_hat_2.png create mode 100644 assets/npc_side_shirt_0.png create mode 100644 assets/npc_side_shirt_1.png create mode 100644 assets/npc_side_shoes_0.png create mode 100644 assets/npc_side_trousers_0.png create mode 100644 assets/npc_side_trousers_1.png diff --git a/assets/npc_back_base_0.png b/assets/npc_back_base_0.png new file mode 100644 index 0000000000000000000000000000000000000000..9d0cab353940fe9c9f879ab1278cfc5ffb6927fd GIT binary patch literal 650 zcmV;50(Jd~P)Px%L`g(JRA_1HI_$n&!ulRBwVFTC)=e@4RnuwAc8{G8=Sc5WYtrQa|L!s+B$8!sN(%aOJL z#MZA3Zr7{Q6gE*jwCF@g07K|&QOy$&02Ks`n=3Q4ey0f-BN_>q&Qo@>^xIhZZ}1mjj{^UGEu0-2Qoojf{o#~s*Q;{5n30pumz&D+6T1PWlV>Gt3c`3g;T<1BpEUOM z`Cd{6_6J@ZfOm4R0phkDdE=-Riv_S2I0z&rJqn_ z$pGhsB<_-gq4deW0A;{s7w-x&^|f+rK{3pZYRvpb1r!fWZaVjCQT5Xj#>THkd`iq# zqBdKhCEkY5`KP%_KH_8MN81GZUg5TLwNgrPt)~Rc@#X)tw7;*hQ2i`FCg;no6~9pd z(r)Uq)7s{k!FQ$ak_3vcmCR^KT zuoBd@6u0`J`T(jYfY%?CJ?4{_qF?}s_}O-#85{p~B}NTS=V_yH@O=%2@I&<}K8Ic^ zAm+iz6`W7KB*5naBNjNHdfNm3QW7LzI=vFxZ9d2g%{IwsdnG1umW!F%Z9e!9BM<=B zh)@PF&X-$t>~uN0nh4eB0RG&sg)+OvnwMMvk^zh?KPH%m-?=WU7^+WcVIQbIfc-j* k$<&xDe7_Qh>ig<_13krRdLhNlX8-^I07*qoM6N<$f;oICssI20 literal 0 HcmV?d00001 diff --git a/assets/npc_back_base_1.png b/assets/npc_back_base_1.png new file mode 100644 index 0000000000000000000000000000000000000000..10218cd1aaed2824b6047bec00f58a95b1c435f6 GIT binary patch literal 677 zcmV;W0$TlvP)Px%Ur9tkRA_=`SS62%dEBu5*#8dVXz4}CTW>MmrvlLTpiKFLg1`eGhn&mdH+ zA~pN=AYA!f=}#!KWPt00BiZ_KW^&@ahL3P*})sXow9#G^N8FWge zp82$dq4A#+;NxOdE?Q+P)Wz%Yx&B35BOmc0^E(TIZLe_Mwh;ipYQ1qLAasr|KTTp| z8w=In?vG*$E%9GGK#Ha=k+!OhJ@}^dT_%CzM_?rx)JY24=&r@3s#Qq{HTY0{1ls0O zXNn)e?|cS7$Qn zUWrMZ)p`T>+r{`WVqA;kLoN|P1MeT7G0YZAr(-LHP<;;1?NIxVFgyU0mm<%M zhFHd=g2Q%yoaj7#&vjYFP<={E?*o+wuwRFDGF9ga-><}>`o4NUWrK<*Q*YxP00000 LNkvXXu0mjf{P!!z literal 0 HcmV?d00001 diff --git a/assets/npc_back_face_1.png b/assets/npc_back_face_1.png new file mode 100644 index 0000000000000000000000000000000000000000..a1a9d870acc7815bc218a29f8c1dc6b5f8a27444 GIT binary patch literal 232 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBJ!3HEPd2A*DDaPU;cPEB*=VV?2Ig319978f1 z-(K9v+iW1>dhz)d9YK}p(=v?Pyu&`QoSDEmqrLB%?WD~tTZ1i?Se9t;I_+Hk>*)S% zI^ICd4Q%f}ueUyU>rbxyn!9(bzx+$cjgu?NpLIQGruUxj4W;%K^V#2j-gQ5_f5-hb z{5!&?s=N%lE*1Q1hWzI>b+hj6GX6e2^^TRg=c^B}Wc=WMY!#;rJA^@+W~iv=4u=r96RuUhqMo4V4g%QY@J zzw_qG3!27HnwcJaU3Op9fm!+4|Fo))|4A25?rB%K8J2dfQ0CN`S=qPq_gWX<+m@4k y_Wd2(|99f@SGRwkxqa8~#`yEhKoddW-$Cw8QORtVp8rY#aXnrAT-G@yGywn-{ZP>W literal 0 HcmV?d00001 diff --git a/assets/npc_back_hair_1.png b/assets/npc_back_hair_1.png new file mode 100644 index 0000000000000000000000000000000000000000..d8a715591d7c549aef87d2f963a6c041fdbd3a67 GIT binary patch literal 483 zcmV<90UZ8`P)Px$ok>JNRA_AfFcd{EDNVqZn$S7WCoO0C;UhT!n& zfIvcHl1M}lweLul@bBGsZHxhk|Bcbs;k(P?ciYMfTE}0SzVx*LeRo+{Gr+bP;yA*3 zv+a=QC)341pZW(4zPl`(1uH9=M68-aY@0!Z(a{9D80cGnq!VYHgK-YraMPx$MM*?KRA__Pj;|SIVKs=I214?80{?Xa+kpM&Zqw5A`ku7h6ATb(N04NPB z8rka$R-4`30M-eTSYUmC^@2Q00i~+}+XD3M*Vj#q9AH!^zrGXL!Xb$?yenYja8uk2 zfLefK&RT#j`t~<=K;is(m}9N?zFJ#v_nq6=$N^A*iDKBo0g!V50KWa)9mIdJ17`Du zT5tE2?E1PVuh)53z^DMD!bO19X4l$d2!H26a%;dY`Kk6T9o<~}N`SuoPx-e#65ucR p2_b|KLI@#*5JCtcgb?yO`2@;$X#X4t-D&^;002ovPDHLkV1nj@v9ACC literal 0 HcmV?d00001 diff --git a/assets/npc_back_hair_3.png b/assets/npc_back_hair_3.png new file mode 100644 index 0000000000000000000000000000000000000000..75b26047bb35900a786b1a922f9962c7e9e26532 GIT binary patch literal 243 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBJ!3HEPd2A*DDaPU;cPEB*=VV?2Icqϒf1 z-(K9v)f6Do{;^)DV~4AL`EqLua~D6peV)$2`s$CA9+k|_n>o=*a{Hs-x$KkQ%S>iq zFmL~RZttfz;lD3hOis_VN;D)V9=&1H7_^4`uNI6Q0jKPj1Gsw>}CnU;Rt z2ozoXk^iqy?se_W$5O9Z*!v%yZlT~(Z!6Qc{Il02qwG6ZY__+UMf2YO?0r^NVAp<$ l|L1LI|KH0GbR`&kn5rk@b?;*F-dtZ0-_zC4Wt~$(699YgU&jCd literal 0 HcmV?d00001 diff --git a/assets/npc_back_hat_1.png b/assets/npc_back_hat_1.png new file mode 100644 index 0000000000000000000000000000000000000000..d7f254200fe95a60e8483ab3c37fc82555261344 GIT binary patch literal 319 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBJ!3HEPd2A*DDaPU;cPEB*=VV?2IX^vJ978f1 z-(GR#I%FWgdV%u`SCasj+`@$L*qtv7?|ezgvuWcFUngSIq`-R6`AX;^6Td8PFZL(< zLp|sIoVmhKCF9ke$=CRoFQ0hr`L>jQ;fI%<+r9N}KwwzO{)jlGkjy6d&(}D_4$YZTZBjUvTgE<}LD3Z_EG9tXF=>kZAv}^4!&|XTNy^3Ld@t zBJ*-?_6(zj)z?qGmvxX(c_=-*m|<;=^P75O*8e}3@+f?bFuEVlv9VjDEnZENIpg{F zJeTaZWj=+sw{0)bO=URyC&%mJ`Zl1<)AWtvQd>SV0=)|Z|8B7dcSv{IP3%tw33=eFtHy7TqX3zd{$#6zzO?_W3nsK7*5wr7t@J5 z^Ce8|%N%K;z-t@Q7+(LWU~y3qD^V)^z9sGD_FIf=K5w>Gh;7+c{rW@D+lfH#-5NEu z_kYt4+%n+V^6&3Co`kvb`Yo3%wLJAFKQ*^Wl00B#zgzJ3w%RwEa>qZu?zqa6Fth$9 o+n=nx+O-=J=JEr51_K|i+fAFV)O4mY&JQHy>FVdQ&MBb@0P7=tMF0Q* literal 0 HcmV?d00001 diff --git a/assets/npc_back_shirt_0.png b/assets/npc_back_shirt_0.png new file mode 100644 index 0000000000000000000000000000000000000000..9b22f724fe7683ece126113c8e7e926bfcedf121 GIT binary patch literal 560 zcmV-00?+-4P)Px$>PbXFRA_~{pby{$Iy{73T8HoXr5ilX0r(&=m|03wk{Boc{4B9TZW0!X4onM8|n zX#Zd5Jw9kYy9WS()A>RM;{NsaNVp+<{QLk}UO4kM{^4>8>1IEOzcaz$2LP}m0m9Xz zYV9D2pyZP<@u%}e8-pJ}xC*RzCx10=J}dNsb^q6=8e8*|hKV2OcDS4}bK2(Oe6@I2 z-pQY}aZ;|EKzR>T_To6!83I43+gxgbX`1R%>f*D!&fGjWS zXGa+k)6E{T11-%yzAkAu-pc>5BRpAr#peZK>IC47^X#|nM$4EqO&b%l;hp@MxF?wt zibpCy!zfEtn`f>|x}4E2+VErj$yinT`VnE87$LZ3smCSKm#G z8p4nD@8i4X+6aViW59N%>lTLf`tqc&oVNT}e}0?9vEJT48m#dpI7UP6>p!L5{{nbm yRc^Ms|C@L~Rba#GAg1Px$!%0LzRA_R{9AP9mW2!bF8f*=4GV}dazTpj=K`WK(nwk=*Jlj-<4j*lbrBmFQ8uq;cp zzQq6ieqYwVa$@g26#xK$)|w{T6_L}=^BnVd??G!_q_6SUS|@s}L2C_4sa+GE+{Aky z<~Zkqb1r$FKIyHsxAZ0cTt~fme$*#B zU|AOE`#yFH!MN{xSl9J%1#)`a(zW^$|8-pxJ?rdx;??EXAUDsvjK64`2x^!foTTwa( z@6#M5`WpYEoVeQbKFt@8L3(86Oeym`pN^gB`7w6Kf6Ep4(V5G`wXp#_37^=uZ9Ln@ zaeUCXFkbU literal 0 HcmV?d00001 diff --git a/assets/npc_back_shoes_0.png b/assets/npc_back_shoes_0.png new file mode 100644 index 0000000000000000000000000000000000000000..b33644656c3156bbc7dec3aeeefa04a27c264353 GIT binary patch literal 274 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBJ!3HEPd2A*DDaPU;cPEB*=VV?2IcGdw978f1 z-(K3w+ms;E`jFXn;-pC%8WS0{veXk;+6!6KH!Le+O!7|k$ar(*LbGT~z0(4t_rZnx zYwi@EbY%jX00aNe-PnBdXUQ5B&9nEnx1uE-b8A*&GiJ&dT#Ic`Df#2e`o$6mHpA; RdZq@*NuI8LF6*2UngC!&cEA7t literal 0 HcmV?d00001 diff --git a/assets/npc_back_trousers_0.png b/assets/npc_back_trousers_0.png new file mode 100644 index 0000000000000000000000000000000000000000..83662f6dc4f98dc925f7907edc81f39bd82d3764 GIT binary patch literal 337 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBJ!3HEPd2A*DDaPU;cPEB*=VV?2+1#Ekjv*P1 zZ?E}tH93f|eOP}YOwu)X5i`fy*G#gDoXe(0vCAI#=g_Pqcy*cBvW~rm#a;sY?`O&U zeP(;#jZp~>7TwBtk!NxFsB-1rSpBW%!z}-Ad+8(I?^)jcSMxx|4c3N=y_|FUdtF+8 ze-C}QC$m=b{nqqH3Q?C7t+V-h8e+EyuD`qH*2a4YJpPPv0_*mloqf&!S?yD%w;TB5 z_dcI}iLvbXsjbVC%h!B3x|ogYiSKLm?C)&Jxp6WMN5a=xY~3^^(7u?Vbb;)Fr)!Rs z#)Y2jX10*y+xe|z)fDmlOv~PFe{J8VtFwCke13($bAA6$nDX|vyvBp8C7V8e+4{2b g|GNBJ`d3d1SF&!?U@gAY1q>qwPgg&ebxsLQ0OqZcb^rhX literal 0 HcmV?d00001 diff --git a/assets/npc_back_trousers_1.png b/assets/npc_back_trousers_1.png new file mode 100644 index 0000000000000000000000000000000000000000..8dc87f4687bf607005f3479dd70a897facc99645 GIT binary patch literal 325 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBJ!3HEPd2A*DDaPU;cPEB*=VV?2IsZLf978f1 z-(E8mYBCUDy>NBow$5Jm2W;0ezcS4`ARY09%`E09cgF6mqHCQ`-iWAV%xF0IfQ?x& zP2%5brw8fNa~n8-ra(c0nb9mT>wA3T=bI^?<7Xe6@#p7`%dh_~e4FO$60&~r z-GAxIp^5uqtDif+_O7h8=xUDeY@c&Z{9{2{-s;%PQQg`1YcguB&z}*QTI=z1X-PxS zsqFKvnxXqELbqhwZP^zao&EMqH}eXE&EK!I8@T$!=zkNk_8J zr+QU>)E3b4y{y>xcJ12v`}r6AoSXY^LeJXQ{33xjx7@AxZ1rW&!q@HJxQl}rYGbxo Ts_&ol0OSKtS3j3^P6 literal 0 HcmV?d00001 diff --git a/assets/npc_front_base_black.png b/assets/npc_front_base_0.png similarity index 100% rename from assets/npc_front_base_black.png rename to assets/npc_front_base_0.png diff --git a/assets/npc_front_base_white.png b/assets/npc_front_base_1.png similarity index 100% rename from assets/npc_front_base_white.png rename to assets/npc_front_base_1.png diff --git a/assets/npc_front_eyes_blue.png b/assets/npc_front_eyes_0.png similarity index 100% rename from assets/npc_front_eyes_blue.png rename to assets/npc_front_eyes_0.png diff --git a/assets/npc_front_eyes_brown.png b/assets/npc_front_eyes_1.png similarity index 100% rename from assets/npc_front_eyes_brown.png rename to assets/npc_front_eyes_1.png diff --git a/assets/npc_front_eyes_green.png b/assets/npc_front_eyes_2.png similarity index 100% rename from assets/npc_front_eyes_green.png rename to assets/npc_front_eyes_2.png diff --git a/assets/npc_front_face_redMask.png b/assets/npc_front_face_1.png similarity index 100% rename from assets/npc_front_face_redMask.png rename to assets/npc_front_face_1.png diff --git a/assets/npc_front_face_whiteMask.png b/assets/npc_front_face_2.png similarity index 100% rename from assets/npc_front_face_whiteMask.png rename to assets/npc_front_face_2.png diff --git a/assets/npc_front_face_glasses.png b/assets/npc_front_face_3.png similarity index 100% rename from assets/npc_front_face_glasses.png rename to assets/npc_front_face_3.png diff --git a/assets/npc_front_face_moustache.png b/assets/npc_front_face_4.png similarity index 100% rename from assets/npc_front_face_moustache.png rename to assets/npc_front_face_4.png diff --git a/assets/npc_front_hair_blonde.png b/assets/npc_front_hair_1.png similarity index 100% rename from assets/npc_front_hair_blonde.png rename to assets/npc_front_hair_1.png diff --git a/assets/npc_front_hair_brown.png b/assets/npc_front_hair_2.png similarity index 100% rename from assets/npc_front_hair_brown.png rename to assets/npc_front_hair_2.png diff --git a/assets/npc_front_hair_grey.png b/assets/npc_front_hair_3.png similarity index 100% rename from assets/npc_front_hair_grey.png rename to assets/npc_front_hair_3.png diff --git a/assets/npc_front_hat_brown.png b/assets/npc_front_hat_1.png similarity index 100% rename from assets/npc_front_hat_brown.png rename to assets/npc_front_hat_1.png diff --git a/assets/npc_front_hat_white.png b/assets/npc_front_hat_2.png similarity index 100% rename from assets/npc_front_hat_white.png rename to assets/npc_front_hat_2.png diff --git a/assets/npc_front_shirt_brown.png b/assets/npc_front_shirt_0.png similarity index 100% rename from assets/npc_front_shirt_brown.png rename to assets/npc_front_shirt_0.png diff --git a/assets/npc_front_shirt_white.png b/assets/npc_front_shirt_1.png similarity index 100% rename from assets/npc_front_shirt_white.png rename to assets/npc_front_shirt_1.png diff --git a/assets/npc_front_shoes_brown.png b/assets/npc_front_shoes_0.png similarity index 100% rename from assets/npc_front_shoes_brown.png rename to assets/npc_front_shoes_0.png diff --git a/assets/npc_front_trousers_blue.png b/assets/npc_front_trousers_0.png similarity index 100% rename from assets/npc_front_trousers_blue.png rename to assets/npc_front_trousers_0.png diff --git a/assets/npc_front_trousers_white.png b/assets/npc_front_trousers_1.png similarity index 100% rename from assets/npc_front_trousers_white.png rename to assets/npc_front_trousers_1.png diff --git a/assets/npc_side_base_0.png b/assets/npc_side_base_0.png new file mode 100644 index 0000000000000000000000000000000000000000..e47df36cd4969825f12d0d4733a78b46c5114a36 GIT binary patch literal 636 zcmV-?0)zdDP)Px%Hc3Q5RA_AmQZSX&kkSQM^9PN1P`!Q)I{K~> z88Bu6OYnba2MWgRV1xwDEg&are&7JC&8{9!@^~f2!@j=H}8wW03#1i~yL_MF5?^qC#q#zhejc6OMp2LFAIskvy z79nF6V9jU4a=m`_pImOuNwause&B$Z_YV85*oaRXpH0k~fRZz^9z{AjPuu6B1t)dp~f(v4%buOz5h@{?|Y zNhN|p#dlR7y{UXxsm`+^Ia7!UsH=; zf**BN+xY%0Nwy&v4&$&fC9>p4ufy;ZG-nVzivvvC_#!7*@}mxb05aS{@|1)F(BB;T z@fQ5-tfl#UD$UKGeRaO8%$=y=v4s$Ru^>IixFEsO-s;BkW2uniCtW3d3&RPD5?7cJ z#_*{VIDXOr+M5_WeW>GcUU$lCtrdUv!-;b=He&2cj;Z*p18`9x*^2n=({hsHs{a)0000Px%IY~r8RA_1Z> zS5J>$Vjv{>95=C@V$4@xef6JJa6jCx?Hhlu>W1yRgtYk9q!dggH6(Qb+Wbi)9<)Ck zCmqMW6B&@RfHnAA+JS;`I~XB>a|;Mbn{PP)Ygd-j2Eih77O)1Nb$|s=P|5;AEMA*$Il$$;)A=Gc;;)TocK|3RpoEM}d6G-> zH?#v+NJvG;;{}Aa^BR0>2f%<`Sw>ZEw`==8oiCs9u~pw%eCH9^m8E$;?$L1bn{EK^ z+P;#Yrpfol0GL!F$g^YLeWEwj*mqH9T7z#n04CZWj!{nmw z2p9*|oXZGq>>7OM5y0iAWE;}*6&sTxO}_Iw3{N5E41#BIfO!o=k`pxfP6t2$kzQc9 z@u_oY@`IINYCfM!OY?&c$ko_)>Q0Q|v4s$Ru^>IixFErbz18LNU8#`cdv`$U83aL5 zViGe#4xc)K<9i(tdlQ4F4|P1w>n8GAtHobD2H+fxjmUk;F&Ce804^#dTM?gqT5eJ! zBr!pY&sKs|K7*m1R$^G#2*?avS**zq9swLod`4g}*AI-S>ZXvsBV3w4+rPte{hh7N Z{{hG$ubRGBPqY94002ovPDHLkV1h4jAQ=Dv literal 0 HcmV?d00001 diff --git a/assets/npc_side_eyes_0.png b/assets/npc_side_eyes_0.png new file mode 100644 index 0000000000000000000000000000000000000000..6534e3d581401a69d2e19d550943cd3619ab4818 GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBJ!3HEPd2A*DDaPU;cPEB*=VV?2IgOq!jv*P1 zZ!c}+JZvD)`cT{>`2t(!I^X4oLfI~`MILls7B*ASsO4AjQmq9N((V>N?FBgA`Smk< zGBEsE8@zgk+vlo!oA|T$Y`>hFuJUxw-Mo|HTlRS_uC#SO8?JeD{r8opneLykudh;Q s+3@o9Q3=zSoUb+SYk(GmLBo7Q<{!6>HvPP{?-oeF)78&qol`;+0H$V3zW@LL literal 0 HcmV?d00001 diff --git a/assets/npc_side_eyes_1.png b/assets/npc_side_eyes_1.png new file mode 100644 index 0000000000000000000000000000000000000000..401e570adb7f78add9150110ba5fb25e894dc19d GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBJ!3HEPd2A*DDaPU;cPEB*=VV?2IhCF+jv*P1 zZ!Z~gH7JN2`>3D6DP!G`J-a!*!|#&fY*}lU_JZx28CqIitN!z|JpB1*-U1ee1NoxS zN3Y%9@}|A;mQ8j0ou8AI2slOY7rDI7jk*^7Sv1+F_IgU?0pXud@39`6;T?b8Qaw6+ i`S0TA%s?B#pyn7)n6pul@wM<{Aik%opUXO@geCylD@0!a literal 0 HcmV?d00001 diff --git a/assets/npc_side_eyes_2.png b/assets/npc_side_eyes_2.png new file mode 100644 index 0000000000000000000000000000000000000000..c433cd058fb988570a8ce8d468a89fc37ba953ec GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBJ!3HEPd2A*DDaPU;cPEB*=VV?2Ia!`Ajv*P1 zZ_gWY9Z=wDeRzHLj*=JeZroh_Wx`z9>JGU>wtkmbdu%q@HbU&nK8Sm4{_rt64fF$9|h0f6s*bYrZz#{LBcn0u0(FGKQyH UHw0|I5(naYy85}Sb4q9e0Dvn(KL7v# literal 0 HcmV?d00001 diff --git a/assets/npc_side_eyes_closed.png b/assets/npc_side_eyes_closed.png new file mode 100644 index 0000000000000000000000000000000000000000..b3634d4ced555905ed00672f278e0f256b837b24 GIT binary patch literal 124 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBJ!3HEPd2A*DDaPU;cPEB*=VV?2IcAReHr_*-#`sOuqTQ6VY;~F S*Urt!Ag-sYpUXO@geCxJfh1-C literal 0 HcmV?d00001 diff --git a/assets/npc_side_face_1.png b/assets/npc_side_face_1.png new file mode 100644 index 0000000000000000000000000000000000000000..27b2ebe104495164c29e6ae0965b2a0dcf1b53ea GIT binary patch literal 257 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBJ!3HEPd2A*DDaPU;cPEB*=VV?2IlDbw978f1 z-(E1}Ych~%d$|AD+UX5Tls&`E*B^KxYQd%cK`Q28uk(Z}-Uio?3OR9H4Oy%BezU{u zOYi>+Faiy~vv%Fzd!P8PXr#Z}KIA-m{8)Hbdo?|zo< zi;6R_zaa5AUh>yu)}m+X+|1{%pWbWxoEhk9Aox+wANlkM^Wq4m=^(DBtDnm{r-UW| DFYjq~ literal 0 HcmV?d00001 diff --git a/assets/npc_side_face_2.png b/assets/npc_side_face_2.png new file mode 100644 index 0000000000000000000000000000000000000000..15eedc43396cf11f185205e6b18b4802bc812337 GIT binary patch literal 242 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBJ!3HEPd2A*DDaPU;cPEB*=VV?2Icq#!978f1 z-(I-L*=!)<_AvWpfK}V+J8veW8o9j-tB=nL)Vw9+GV$|X7SoENWS}VxwUbJ=|9d>Y z!o}oh6r07W|2rAVuW#qA>gLd1YI1Zto5kw?I~(Q{PY>D@wOS=JO8HP-=XSn=u>U*l zj#%`0Y3iCy4bpjjCs+2t-`K5TUu*LP6E9o+O+GLA_bBU*-EE08+D(4{T*w@=@cx;* mTkGQX?=F@Hx)KNueBH}1bIV_8i8%r8Aik%opUXO@geCxlPGNBX literal 0 HcmV?d00001 diff --git a/assets/npc_side_face_3.png b/assets/npc_side_face_3.png new file mode 100644 index 0000000000000000000000000000000000000000..83295ba8e0d316dbe6d5637568a989674cef377e GIT binary patch literal 135 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBJ!3HEPd2A*DDaPU;cPEB*=VV?2IgXw#jv*P1 zZ_jV!Z7^V9KBzP0q3yz#883uX1n%g5_$I-?5TlxT`(~Ni%lp5ccU=7;%RcX2{%y+- gt#&}o3=ALS*thU|6;@sHc?RNoy85}Sb4q9e0Q8P5lK=n! literal 0 HcmV?d00001 diff --git a/assets/npc_side_face_4.png b/assets/npc_side_face_4.png new file mode 100644 index 0000000000000000000000000000000000000000..8802f19122404891fec66bfbf413f2d63146393a GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBJ!3HEPd2A*DDaPU;cPEB*=VV?2Irg3|jv*P1 zZ!aC>We^Z?an$V;k`Z~Z5t3mZ(o1U d2-M5aQ0`;@Nao%S{t}t(=++rkqi-SbQyN=C-IA z-BXxv(^sxPXMTHb#&-F=D-1tBkA0}s>HIilV*1MdX$vFe+I_3M z8IzxPe{-06q+=-ygGF}Z8sYh&uxIxOB89z6B3-5F~EW+o; zt?}~Xwkr3?y4YQR*EB?UJ#ckeYr87(w$KVn&`_C2f?F>w8No-JpaH6ypgU7q#3zcKG#+OYETd!_S1 o@v^bk<;4D|{B%JA{%@rhzHy9M_w6(vFt8XrUHx3vIVCg!0JT|_{Qv*} literal 0 HcmV?d00001 diff --git a/assets/npc_side_hair_2.png b/assets/npc_side_hair_2.png new file mode 100644 index 0000000000000000000000000000000000000000..1fc4c88699cef64189a0053fbe6f0b8b9e034d4b GIT binary patch literal 329 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBJ!3HEPd2A*DDaPU;cPEB*=VV?2+033Ujv*P1 zZ?E`fH9IgI{aAlSVWG&vt?M>@W0E^?_&dX1hwG6ymnf*7NJ!fy;4FMGDcAJE_voLN z`SawNmHyva_15Y6)Svj38h5r=cYW{A=e}`E zaMrHi1#=VP8+U%T=09*#nZdEbT_%^|Tw@{2!Cl3t*Na9d?Ki%)Z%xNy-g9y{r;7%} z?pX`8=R&&8)&qBbHvhkPW9s(3>v{9I3|1Y`ed0eYedYeR*5_MF_H`h@3Ey8VI(BR^ UQxX@71H*>F)78&qol`;+0I~Ft9RL6T literal 0 HcmV?d00001 diff --git a/assets/npc_side_hair_3.png b/assets/npc_side_hair_3.png new file mode 100644 index 0000000000000000000000000000000000000000..9041ffe8d59ec2c4fd13b4c8a3819aa956e7a6c6 GIT binary patch literal 235 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBJ!3HEPd2A*DDaPU;cPEB*=VV?2IZHiV978f1 z-(FnEcgR4*;i9?ICY|Dz`Ob|$gd++Y8zmTE2Daw1+k!-f7nCA^vrA5Abq>F>*x?=A1keY`VgC0ops-@!+>?mWj1^e_zk$n?Jv@?E}DW$6)+ Nkf*Dk%Q~loCIIeQgwp^3 literal 0 HcmV?d00001 diff --git a/assets/npc_side_hat_2.png b/assets/npc_side_hat_2.png new file mode 100644 index 0000000000000000000000000000000000000000..693f8574d04a9ef94ccdd84a72c7240b73011828 GIT binary patch literal 328 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBJ!3HEPd2A*DDaPU;cPEB*=VV?2*-V};jv*P1 zZ?B&1Z8i{KeIVYcr=e_lp>4KgmO*VnndCRs)PUn}PIk;U>~v}g-~E2FlB?WpedhxV z|L>fY5)s^btUb}-dHwCFKYK;r&2he7y87c3A%+*$_K$p+!=IlQSI{pyr`XaUa43)Y zxeUXLK;!vl0ownkiC4bA_}!M_Kz06G+v}U3rrl=KIen`v_iRl^$1#bov4(E3_tKOW zty-nD=;vz|*SKRMs;@N!k;nw^?UAK6cTTIH3w-F@vJw%4~0+SqJc^ZdOJv+3t> z>8-id^;;`uElXb+W>vf0i#?+E&)w_~J%uvz>z~P(1}N{h)QVeMW+#XM7w3Ot4*A;9 VdBrLI3ovLHJYD@<);T3K0RWzTiy8m` literal 0 HcmV?d00001 diff --git a/assets/npc_side_shirt_0.png b/assets/npc_side_shirt_0.png new file mode 100644 index 0000000000000000000000000000000000000000..d3abdcb9b34f83597b1766498d6133ee5e9ccc08 GIT binary patch literal 448 zcmV;x0YCnUP)Px$dPzh+RoGXU^h8_U$$?)Im0^YGt%<(q6Vzh7Oz zbM5ry>l1+SXntzIsb?#LwzuoOo8Dwqd*LFY{ z#Q;oZE9K2XT5Zp@j}9%>!?&5=uYR!I?MszR>ci#7A*rZ<_bdf7o#=_0?j z1B#XUcza5+iP~i2B~JKNu5Tam=l{+>m;uEFUY_q0)muE)-hb%=mebbqYo%P)Px$O-V#SRA_VL6h%=KMNt$*Q4|2Y_tASF)9+vPPdV8+hcN~q0$6JSV%xTdlJIZxkGV}o z8Rs0EwTngABmb!bM1&9m z#u&P;!x%$VRja|?`)IAbb48@s-zz`+1OS?*f$=7$mRbw1>-x?u_4mww8iFZXT5qE3 zy4icIeBbw!46;w=XFEVd0JvN(#fN3AwsY>~&?^1;Pv)O83u3zXd_Esyj78I1MCK~D zZObqWam)MPBR~5D(n{TKw>VAIEeB6o^OtxxUqt4P%JEcybc10S;*$Kzdpy7v{yTq- xtTav4^et@(_;!EZWRvh?zM?3KqA1GG^9LnlXyi1d73Tl|002ovPDHLkV1fk@xX=Iq literal 0 HcmV?d00001 diff --git a/assets/npc_side_shoes_0.png b/assets/npc_side_shoes_0.png new file mode 100644 index 0000000000000000000000000000000000000000..7878df03e8f2b96f0470e571092762c27b9b6431 GIT binary patch literal 259 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBJ!3HEPd2A*DDaPU;cPEB*=VV?2IeR@_978f1 z-(IxlYjO~2eYn^#D`U%?%!LZmj!bG(-M}>cfL?41tLZdnXKOLH$H@W7Av*uoHy2nw zKj#6|4FeCPKVA7@WBO12)A9MgGDFk!bwj4k^v_vx#O>D;#XYm@%NeFGU1hX;*UEi| zmVckER2QM--&?*e^lr(j*?zb0)|r(2Q~C06S;ya^ofC@J3Q2n!)$QFh>-@4wPn?g= z%|5?*QWLk_eBXk)6@S{z1uljED|>fyQf=MbdWKDR8W;FY2`>b>!_(EzWt~$(695C4 BYeWD5 literal 0 HcmV?d00001 diff --git a/assets/npc_side_trousers_0.png b/assets/npc_side_trousers_0.png new file mode 100644 index 0000000000000000000000000000000000000000..da162cf8baf5bf0035e98d693bb5f21724f94ea6 GIT binary patch literal 421 zcmV;W0b2fvP)Px$Ur9tkRA__j|f$%SWm;%6} z%6o70FX=U40iou=8ftia27p)P+7s2FHPmXG?W10>iX(i-KU>!*J3!tbOB0NoN$Ui% zG-;*n;-94nbi-W7+lrvOydI$|Kwdfq6*$IyD}_0Jp^Z)nLS$TlYkeCIW&loVl-Zgse7G*Obr^aH~|0gu~X z%1=+3yLWz8UQyAd$tJ-L0xXUwsISd8oZa~MjR)SSjziBrN6aZ+J9oya`^W7?ow`yOQX~D$QqufgOlv=1)9p&SqIu)E z{hl>j#iCyO$~c{>zv#~pcr~dU&MKS>Wew#v>bcaZkK%KiTte4KQnJ0cVBvQ j-lDmOZ~Z%D_>pzRfxili&rjC}hAo4qtDnm{r-UW|;hw5d literal 0 HcmV?d00001 diff --git a/code/core/string.h b/code/core/string.h index 9eb73ea..14e813f 100644 --- a/code/core/string.h +++ b/code/core/string.h @@ -3,6 +3,7 @@ #define S(x) Str8_Wrap(sizeof(x) - sizeof(*(x)), (U8 *) (x)) #define Sz(x) Str8_WrapZ((U8 *) (x)) +#define Sl(x) { sizeof(x) - sizeof(*(x)), (U8 *) (x) } #define Sv(x) (int) (x).count, (x).data #define Sf(arena, fmt, ...) Str8_Format(arena, fmt, ##__VA_ARGS__) diff --git a/code/draw/core.c b/code/draw/core.c index 82d287b..e839afa 100644 --- a/code/draw/core.c +++ b/code/draw/core.c @@ -151,6 +151,8 @@ void _D_Rect(D_Context *draw, D_RectOpts *opts) { rect->texture = opts->texture; + F32 w, h; + rect->x = opts->p.x; rect->y = opts->p.y; @@ -177,11 +179,19 @@ void _D_Rect(D_Context *draw, D_RectOpts *opts) { } if (opts->flags & D_RECT_IGNORE_ASPECT) { - rect->w = opts->dim.w; - rect->h = opts->dim.h; + w = opts->dim.w; + h = opts->dim.h; } else { - Vk_Image *image = &draw->images[opts->texture].image; + Vk_Image *image = 0; + if (opts->texture >= draw->n_images) { + // @hack: first font texture + // + image = &draw->fonts->image; + } + else { + image = &draw->images[opts->texture].image; + } F32 width = cast(F32) image->width; F32 height = cast(F32) image->height; @@ -191,53 +201,42 @@ void _D_Rect(D_Context *draw, D_RectOpts *opts) { height *= (opts->uv.max.y - opts->uv.min.y); } - F32 aspect_w = (width > height) ? (width / height) : 1.0f; - F32 aspect_h = (width > height) ? 1.0f : (height / width); + F32 aspect_w = (width > height) ? 1.0f : (width / height); + F32 aspect_h = (width > height) ? (height / width) : 1.0f; - rect->w = opts->scale * aspect_w; - rect->h = opts->scale * aspect_h; + w = opts->scale * aspect_w; + h = opts->scale * aspect_h; } + if (opts->flags & D_RECT_FLIP_X) { w *= -1.0f; } + if (opts->flags & D_RECT_FLIP_Y) { h *= -1.0f; } + + rect->w = w; + rect->h = h; + draw->n_rects += 1; } } void D_Text(D_Context *draw, D_Font *font, Str8 text, F32 x, F32 y) { F32 xoff = x; - local_persist B32 done = 0; + + // @Todo: control scale + F32 scale = 1.0f / (font->ascent - font->descent); for (S64 it = 0; it < text.count; ++it) { if (text.data[it] >= ' ' && text.data[it] <= '~') { D_Glyph *glyph = &font->glyphs[text.data[it] - ' ']; - V2f size; - size.w = (glyph->box.max.x - glyph->box.min.x); - size.h = (glyph->box.max.y - glyph->box.min.y); + F32 image_scale = scale * Max(glyph->dim.w, glyph->dim.h); + F32 advance = scale * glyph->advance; - V2f dim; + V2f offset = V2f_Scale(glyph->offset, scale); - F32 scale = 150.0f / (font->ascent - font->descent); - - if (size.w > size.h) { - dim.w = scale * (size.w / size.h); - dim.h = scale; - } - else { - dim.w = scale; - dim.h = scale * (size.h / size.w); - } - - // @Hardcode: need font index in font struct - D_Rect(draw, xoff, y, .texture = 0, .c = V4F(0, 1, 1, 1), .dim = dim, .flags = D_RECT_IGNORE_ASPECT); - D_Rect(draw, xoff, y, .texture = draw->n_images, .uv = glyph->box, .dim = dim, .flags = D_RECT_IGNORE_ASPECT); - xoff += (1.05f * dim.w); // glyph->advance; //+ glyph->offset.x; - - if (!done) { printf(" %f (%f, %f)", xoff, dim.w, dim.h); } + D_Rect(draw, xoff + offset.x, y + offset.y, .texture = font->id, .uv = glyph->box, .scale = image_scale, .flags = D_RECT_UV_ASPECT); + xoff += advance; } } - - if (!done) { printf("\n"); } - done = true; } void D_FontLoad(D_Context *draw, Str8 name, F32 size) { @@ -252,7 +251,7 @@ void D_FontLoad(D_Context *draw, Str8 name, F32 size) { stbtt_fontinfo info = { 0 }; stbtt_InitFont(&info, font_data.data, 0); - F32 scale = stbtt_ScaleForPixelHeight(&info, 20); + F32 scale = stbtt_ScaleForPixelHeight(&info, 256); U32 w = 512; U32 h = 512; @@ -268,14 +267,12 @@ void D_FontLoad(D_Context *draw, Str8 name, F32 size) { D_Font *font = M_ArenaPush(draw->arena, D_Font); - font->px = size; - S32 asc, desc, line; stbtt_GetFontVMetrics(&info, &asc, &desc, &line); - font->line_advance = cast(F32) line; - font->ascent = cast(F32) asc; - font->descent = cast(F32) desc; + font->line_advance = cast(F32) (scale * line); + font->ascent = cast(F32) (scale * asc); + font->descent = cast(F32) (scale * desc); font->glyphs = M_ArenaPush(draw->arena, D_Glyph, .count = count); @@ -286,10 +283,14 @@ void D_FontLoad(D_Context *draw, Str8 name, F32 size) { S32 left, width; stbtt_GetCodepointHMetrics(&info, ' ' + it, &width, &left); - glyph->box = R2F(V2F(chr->x0 / (F32) w, chr->y0 / (F32) h), V2F(chr->x1 / (F32) w, chr->y1 / (F32) h)); + glyph->box.min = V2F(chr->x0 / (F32) w, chr->y0 / (F32) h); + glyph->box.max = V2F(chr->x1 / (F32) w, chr->y1 / (F32) h); - glyph->advance = glyph->box.max.x - glyph->box.min.x; //chr->xadvance * scale; - glyph->offset = V2F(chr->xoff * scale, chr->yoff * scale); + glyph->advance = chr->xadvance; + glyph->dim.w = cast(F32) (chr->x1 - chr->x0); + glyph->dim.h = cast(F32) (chr->y1 - chr->y0); + glyph->offset.x = (0.5f * glyph->dim.w) + chr->xoff; + glyph->offset.y = (0.5f * glyph->dim.h) + chr->yoff; } Vk_Buffer *staging = &draw->staging; @@ -302,6 +303,8 @@ void D_FontLoad(D_Context *draw, Str8 name, F32 size) { Vk_CommandBuffer *cmds = Vk_CommandBufferPush(); + font->id = draw->n_images + draw->n_fonts; + font->image.width = w; font->image.height = h; diff --git a/code/draw/core.h b/code/draw/core.h index c4756f6..8db0a49 100644 --- a/code/draw/core.h +++ b/code/draw/core.h @@ -6,7 +6,10 @@ typedef struct D_Glyph D_Glyph; struct D_Glyph { F32 advance; + V2f offset; + V2f dim; + R2f box; }; @@ -14,13 +17,13 @@ typedef struct D_Font D_Font; struct D_Font { D_Font *next; - F32 px; + U32 id; F32 line_advance; F32 ascent; F32 descent; - F32 *kerning; + F32 *kerning; // @incomplete: we don't load this D_Glyph *glyphs; Vk_Image image; @@ -108,6 +111,8 @@ enum D_RectFlags { D_RECT_IGNORE_ASPECT = (1 << 0), // by default only width is used as a "dimension" D_RECT_PER_VERTEX_COLOUR = (1 << 1), // split colours per vertex D_RECT_UV_ASPECT = (1 << 2), // get the aspect from the uv rect rather than the full image + D_RECT_FLIP_X = (1 << 3), + D_RECT_FLIP_Y = (1 << 4) }; typedef struct D_RectOpts D_RectOpts; diff --git a/code/first.c b/code/first.c index 6272ef7..f73d0e3 100644 --- a/code/first.c +++ b/code/first.c @@ -79,6 +79,8 @@ int main(int argc, char **argv) game->draw.arena = arena; G_ImagesLoad(game); + D_FontLoad(&game->draw, S("ubuntu"), 60); + G_PipelinesLoad(game); G_AudioLoad(game); @@ -87,7 +89,7 @@ int main(int argc, char **argv) camera->x = V3F(1, 0, 0); camera->y = V3F(0, 1, 0); camera->z = V3F(0, 0, 1); - camera->p = V3F(0, 0, 48); + camera->p = V3F(0, 0, 16); camera->fov = 60.0f; @@ -129,12 +131,9 @@ int main(int argc, char **argv) badman->pointsOfInterest[1] = 12; world->npcPOI[0] = 100; - world->player.world = world; - world->player.pos.x = 0; - world->player.pos.y = 0; - world->player.bulletsLoaded = PLAYER_BULLET_COUNT; - world->player.reloadTimer = 0; - world->player.currentArea = WORLD_AREA_OUTSIDE; + + PlayerInit(game, &world->player); + for(int i =0; i< 4200; i++) { world->map[i] = map[i]; } @@ -220,17 +219,8 @@ int main(int argc, char **argv) game->editor.mode = G_EDITOR_MODE_TILE; game->editor.currentLevel = WORLD_AREA_OUTSIDE; - - D_Animation animation; - { - U32 id = D_ImageHandle(&game->draw, S("npc_front_base_white")); - D_AnimationInit(&animation, id, 1, 4, 1.0f / 20.0f); - } - bool running = true; - printf("%zu size in bytes\n", sizeof(TestNavMesh)); - const int width = 1280; const int height = 720; @@ -243,6 +233,13 @@ int main(int argc, char **argv) { running = false; } + else if (e.type == SDL_EVENT_KEY_DOWN) { + Player *player = &game->world->player; + switch (e.key.key) { + case SDLK_R: { PlayerInit(game, player); } break; + } + } + V3f projection = G_CameraUnproject(&game->camera, V2f_Clip( V2F(e.button.x, e.button.y), V2F((F32) width, (F32) height) @@ -257,8 +254,8 @@ int main(int argc, char **argv) if(e.type==SDL_EVENT_MOUSE_BUTTON_DOWN && e.button.button == SDL_BUTTON_LEFT) { switch(game->editor.mode){ case G_EDITOR_MODE_TILE: { - F32 tilex = (S32)(game->editor.cursor.x+TILE_SIZE/2); - F32 tiley = (S32)(game->editor.cursor.y+TILE_SIZE/2); + F32 tilex = (F32) (S32)(game->editor.cursor.x+TILE_SIZE/2); + F32 tiley = (F32) (S32)(game->editor.cursor.y+TILE_SIZE/2); game->world->map[(S32)tilex + (S32)tiley * 96] = game->editor.currentAsset; break; } @@ -275,7 +272,7 @@ int main(int argc, char **argv) } } } else if(e.type==SDL_EVENT_MOUSE_BUTTON_UP && e.button.button == SDL_BUTTON_LEFT && game->editor.mode == G_EDITOR_MODE_HITBOX) { - // Add hitbox + // Add hitbox V2f topLeft = V2F(Min(game->editor.cursor.x, game->editor.dragStart.x), Min(game->editor.cursor.y, game->editor.dragStart.y)); game->world->hitboxes[game->world->hitboxCount].pos = topLeft; game->world->hitboxes[game->world->hitboxCount].size = V2F( @@ -345,8 +342,7 @@ int main(int argc, char **argv) UpdateWorld(1.0f / 60.0f, game->world); game->camera.p.x = game->world->player.pos.x; game->camera.p.y = game->world->player.pos.y; - } - D_AnimationUpdate(&animation, 1.0f / 250.0f); + } int w, h; SDL_GetWindowSizeInPixels(window, &w, &h); @@ -386,17 +382,16 @@ int main(int argc, char **argv) RenderWorld(game->world, &game->draw); - R2f aframe = D_AnimationFrame(&animation); - D_Rect(&game->draw, 0, 0, .texture = animation.id, .uv = aframe, .flags = D_RECT_UV_ASPECT); + D_Text(&game->draw, game->draw.fonts, S("Small Test"), 0, 0); if(game->editor.enabled) { G_Editor editor = game->editor; - F32 tilex = floor(editor.cursor.x+TILE_SIZE/2); - F32 tiley = floor(editor.cursor.y+TILE_SIZE/2); + F32 tilex = cast(F32) floor(editor.cursor.x+TILE_SIZE/2); + F32 tiley = cast(F32) floor(editor.cursor.y+TILE_SIZE/2); switch(game->editor.mode) { case G_EDITOR_MODE_TILE: { World_Tile asset = game->world->tileTypes[editor.currentAsset]; - D_Rect(&game->draw, tilex, tiley, .texture=asset.tile, .angle=asset.rotation); + D_Rect(&game->draw, tilex, tiley, .texture=asset.tile, .angle=(F32) asset.rotation); break; } case G_EDITOR_MODE_PROP: { @@ -405,7 +400,7 @@ int main(int argc, char **argv) break; } case G_EDITOR_MODE_HITBOX: { - for(int i = 0; i < game->world->hitboxCount; i++) { + for(U32 i = 0; i < game->world->hitboxCount; i++) { V2f centre = AABB_Centre(game->world->hitboxes[i]); D_Rect(&game->draw, centre.x, centre.y, .texture=0, .dim=game->world->hitboxes[i].size, .flags=D_RECT_IGNORE_ASPECT); } diff --git a/code/game/core.h b/code/game/core.h index 028266e..5b918ce 100644 --- a/code/game/core.h +++ b/code/game/core.h @@ -1,6 +1,7 @@ #if !defined(LD_GAME_CORE_H_) #define LD_GAME_CORE_H_ -#include "world.h" + +typedef struct World World; typedef struct G_Camera G_Camera; struct G_Camera { @@ -44,6 +45,48 @@ struct G_State { World *world; }; +typedef U32 G_OutfitDirection; +enum { + G_OUTFIT_DIR_FRONT = 0, + G_OUTFIT_DIR_SIDE, + G_OUTFIT_DIR_BACK, + + G_OUTFIT_DIR_FLIPPED = (1 << 16) +}; + +typedef union G_OutfitSet G_OutfitSet; +union G_OutfitSet { + struct { + U32 base; + U32 eyes; + U32 face; + U32 hair; + U32 hat; + U32 shirt; + U32 shoes; + U32 trousers; + }; + + U32 e[8]; +}; + +typedef struct G_Outfit G_Outfit; +struct G_Outfit { + D_Animation state; // .id in here isn't used for drawing + + G_OutfitDirection dir; + + union { + struct { + G_OutfitSet front; + G_OutfitSet side; + G_OutfitSet back; + }; + + G_OutfitSet e[3]; + }; +}; + function void G_ImagesLoad(G_State *game); function void G_PipelinesLoad(G_State *game); function void G_AudioLoad(G_State *game); @@ -56,6 +99,7 @@ function V3f G_CameraUnproject(G_Camera *camera, V2f clip); function R3f G_CameraBounds(G_Camera *camera); +#include "world.h" #include "aabb.h" #include "player.h" #include "nav.h" diff --git a/code/game/impl/player.c b/code/game/impl/player.c index 8375d1e..2c430fd 100644 --- a/code/game/impl/player.c +++ b/code/game/impl/player.c @@ -3,6 +3,75 @@ #include #include +// @Todo: move/extern these so the npc/bandit can use them +// +#define G_OUTFIT_COMPONENT_COUNT 8 + +global_var Str8 __outfit_names[] = { + Sl("npc_%s_base_%d"), + Sl("npc_%s_eyes_%d"), + Sl("npc_%s_face_%d"), + Sl("npc_%s_hair_%d"), + Sl("npc_%s_hat_%d"), + Sl("npc_%s_shirt_%d"), + Sl("npc_%s_shoes_%d"), + Sl("npc_%s_trousers_%d") +}; + +global_var U32 __outfit_counts[] = { + 2, // base + 3, // eyes + 5, // face + 4, // hair + 3, // hat + 2, // shirt + 1, // shoes + 2 // trousers +}; + +global_var U32 __outfit_back_counts[] = { + 2, // base + 0, // eyes + 3, // face + 4, // hair + 3, // hat + 2, // shirt + 1, // shoes + 2 // trousers +}; + +StaticAssert(ArraySize(__outfit_names) == ArraySize(__outfit_counts)); + +#define OUTFIT_IMG(dir, n) D_ImageHandle(&game->draw, Sf(temp.arena, (const char *) __outfit_names[it].data, #dir, n)) + +void PlayerInit(G_State *game, Player *player) { + World *world = game->world; + player->world = world; + + world->player.bulletsLoaded = PLAYER_BULLET_COUNT; + world->player.currentArea = WORLD_AREA_OUTSIDE; + + G_Outfit *outfit = &player->outfit; + + D_AnimationInit(&outfit->state, 0, 1, 4, 1.0f / 6.0f); + + M_TempScope(0, 0) { + for (U32 it = 0; it < G_OUTFIT_COMPONENT_COUNT; ++it) { + U32 idx = Random_Next(&world->random) % __outfit_counts[it]; + + // We just allow face, hair and hat to default to 0 meaning the player doesn't have one + if (idx != 0 || it < 2 || it > 4) { + outfit->front.e[it] = OUTFIT_IMG(front, idx); + outfit->side.e[it] = OUTFIT_IMG(side, idx); + + if ((idx + 1) <= __outfit_counts[it]) { + outfit->back.e[it] = OUTFIT_IMG(back, idx); + } + } + } + } +} + void PlayerInput(SDL_Event *event, Player *player) { SDL_KeyboardEvent key = event->key; @@ -34,7 +103,7 @@ void PlayerInput(SDL_Event *event, Player *player) } } if ( - event->type == SDL_EVENT_MOUSE_BUTTON_DOWN + event->type == SDL_EVENT_MOUSE_BUTTON_DOWN && mouseBtn.button == SDL_BUTTON_LEFT ) { if(player->bulletsLoaded > 0) { @@ -47,7 +116,7 @@ void PlayerInput(SDL_Event *event, Player *player) player->reloadTimer = PLAYER_RELOAD_TIME; printf("reloading\n"); }; - } + } } void PlayerUpdate(F32 delta, Player *player) { @@ -55,16 +124,28 @@ void PlayerUpdate(F32 delta, Player *player) { V2f dir = V2F(0, 0); if(player->controls.upDown) { dir.y -= 1; + player->outfit.dir = G_OUTFIT_DIR_BACK; } if(player->controls.downDown) { dir.y += 1; + player->outfit.dir = G_OUTFIT_DIR_FRONT; } if(player->controls.leftDown) { dir.x -= 1; + player->outfit.dir = G_OUTFIT_DIR_SIDE | G_OUTFIT_DIR_FLIPPED; } if(player->controls.rightDown) { dir.x += 1; + player->outfit.dir = G_OUTFIT_DIR_SIDE; } + + if (dir.x != 0 || dir.y != 0) { + D_AnimationUpdate(&player->outfit.state, delta); + } + else { + player->outfit.state.index = 0; + } + if(player->reloadTimer > 0) { player->reloadTimer-=delta; if(player->reloadTimer <= 0) { @@ -76,3 +157,20 @@ void PlayerUpdate(F32 delta, Player *player) { player->pos.x += dir.x; player->pos.y += dir.y; } + +void PlayerDraw(D_Context *draw, Player *player) { + G_Outfit *outfit = &player->outfit; + + R2f pframe = D_AnimationFrame(&outfit->state); + + for (U32 it = 0; it < G_OUTFIT_COMPONENT_COUNT; ++it) { + U32 flipped = (outfit->dir & G_OUTFIT_DIR_FLIPPED) != 0; + U32 dir = (outfit->dir & ~G_OUTFIT_DIR_FLIPPED); + + U32 tid = outfit->e[dir].e[it]; + if (tid != 0) { + U32 flags = D_RECT_UV_ASPECT | (flipped ? D_RECT_FLIP_X : 0); + D_Rect(draw, player->pos.x, player->pos.y, .texture = tid, .uv = pframe, .flags = flags); + } + } +} diff --git a/code/game/impl/world.c b/code/game/impl/world.c index 63757c3..14a7fd7 100644 --- a/code/game/impl/world.c +++ b/code/game/impl/world.c @@ -47,7 +47,7 @@ void RenderWorld(World *world, D_Context *draw) { ); } } - for (int i = 0; i < world->propCount; i++) { + for (U32 i = 0; i < world->propCount; i++) { if(world->props[i].area == world->player.currentArea) { D_Rect( draw, @@ -69,10 +69,13 @@ void RenderWorld(World *world, D_Context *draw) { V2f drawPos = AABB_Centre(world->bandit.collision); D_Rect(draw, drawPos.x, drawPos.y, .texture = 9); } - D_Rect(draw, world->player.pos.x, world->player.pos.y, .texture = 1); + + PlayerDraw(draw, &world->player); } void SaveWorld(M_Arena *arena, World *world) { + (void) arena; + printf("Saving world\n"); OS_Handle file = FS_FileOpen(S("world.sgdat"), FS_ACCESS_WRITE); FS_FileWrite(file, world, sizeof(World)+sizeof(NavMesh), 0); diff --git a/code/game/player.h b/code/game/player.h index a727453..1756166 100644 --- a/code/game/player.h +++ b/code/game/player.h @@ -29,9 +29,14 @@ struct Player ControlState controls; V2f shotPos; + G_Outfit outfit; + F32 reloadTimer; }; +function void PlayerInit(G_State *game, Player *player); +function void PlayerDraw(D_Context *draw, Player *player); + function void PlayerInput(SDL_Event *event, Player *player); function void PlayerUpdate(F32 delta, Player *player);