From fd53c7da8c5f2b79b87f624e313ff508072361ad Mon Sep 17 00:00:00 2001 From: Xavier Del Campo Romero Date: Sun, 28 Jan 2024 03:01:13 +0100 Subject: [PATCH] Big rushed update --- README.md | 2 + jancity.png | Bin 0 -> 9735 bytes res/CMakeLists.txt | 144 +++++++++ res/btn_left.bmp | Bin 586 -> 0 bytes res/btn_left_24.bmp | Bin 2358 -> 1590 bytes res/btn_mid.bmp | Bin 542 -> 0 bytes res/btn_mid_24.bmp | Bin 2358 -> 1590 bytes res/btn_right.bmp | Bin 586 -> 0 bytes res/btn_right_24.bmp | Bin 2358 -> 1590 bytes res/btn_small.bmp | Bin 0 -> 490 bytes res/btn_small_24.bmp | Bin 0 -> 1782 bytes res/car1_24.bmp | Bin 0 -> 9270 bytes res/car2_24.bmp | Bin 0 -> 9270 bytes res/checkbox_24.bmp | Bin 0 -> 1998 bytes res/city1.txt | 44 ++- res/font.bmp | Bin 0 -> 8206 bytes res/font_24.bmp | Bin 0 -> 48438 bytes res/functions.cmake | 2 + res/line_edit_left_24.bmp | Bin 0 -> 1590 bytes res/line_edit_mid_24.bmp | Bin 0 -> 1590 bytes res/line_edit_right_24.bmp | Bin 0 -> 1590 bytes res/sel_down_left_24.bmp | Bin 0 -> 822 bytes res/sel_down_right_24.bmp | Bin 0 -> 822 bytes res/sel_mid_down_24.bmp | Bin 0 -> 822 bytes res/sel_mid_top_24.bmp | Bin 0 -> 150 bytes res/sel_mid_v_24.bmp | Bin 0 -> 182 bytes res/sel_up_left_24.bmp | Bin 0 -> 822 bytes res/sel_up_right_24.bmp | Bin 0 -> 822 bytes res/unit5_24.bmp | Bin 9270 -> 9270 bytes src/building/inc/building.h | 2 +- src/building/src/building.c | 2 +- src/camera/inc/camera.h | 3 +- src/camera/src/camera.c | 25 +- src/camera/src/mouse.c | 52 ++- src/camera/src/pad.c | 2 +- src/game/src/res.c | 96 ++++++ src/gui/inc/gui/rounded_rect.h | 5 +- src/gui/src/rounded_rect.c | 30 +- src/instance/CMakeLists.txt | 2 +- src/instance/src/instance.c | 55 +--- src/menu/src/gamecfg_menu.c | 5 +- src/menu/src/main_menu.c | 50 +++ src/menu/src/menu.c | 20 +- src/mouse/inc/mouse.h | 1 + src/mouse/sdl-1.2/src/mouse.c | 8 + src/peripheral/inc/peripheral.h | 2 +- src/player/CMakeLists.txt | 3 +- src/player/inc/human_player.h | 12 + src/player/inc/player.h | 2 +- src/player/src/human_player.c | 23 +- src/player/src/human_player_gui.c | 170 +++++++++- src/player/src/player.c | 17 + src/terrain/inc/terrain.h | 4 +- src/terrain/privinc/terrain_tiles.h | 114 ++++++- src/terrain/src/init.c | 2 + src/terrain/src/render.c | 10 +- src/unit/inc/unit.h | 21 +- src/unit/inc/unit_type.h | 9 + src/unit/src/unit.c | 469 +++++++++++++++------------- 59 files changed, 1033 insertions(+), 375 deletions(-) create mode 100644 jancity.png delete mode 100644 res/btn_left.bmp delete mode 100644 res/btn_mid.bmp delete mode 100644 res/btn_right.bmp create mode 100644 res/btn_small.bmp create mode 100644 res/btn_small_24.bmp create mode 100644 res/car1_24.bmp create mode 100644 res/car2_24.bmp create mode 100644 res/checkbox_24.bmp create mode 100644 res/font.bmp create mode 100644 res/font_24.bmp create mode 100644 res/line_edit_left_24.bmp create mode 100644 res/line_edit_mid_24.bmp create mode 100644 res/line_edit_right_24.bmp create mode 100644 res/sel_down_left_24.bmp create mode 100644 res/sel_down_right_24.bmp create mode 100644 res/sel_mid_down_24.bmp create mode 100644 res/sel_mid_top_24.bmp create mode 100644 res/sel_mid_v_24.bmp create mode 100644 res/sel_up_left_24.bmp create mode 100644 res/sel_up_right_24.bmp diff --git a/README.md b/README.md index cf7032d..f0ee3ac 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ `jancity` is a cross-platform, tile-based sandbox video game. +![Screenshot](jancity.png) + Mostly written during the Global Game Jam 2024 event, reusing its engine from [`rts`](https://gitea.privatedns.org/xavi/rts). diff --git a/jancity.png b/jancity.png new file mode 100644 index 0000000000000000000000000000000000000000..26d04ddd01cbb69e9c19d927ea7d4b11c3343b49 GIT binary patch literal 9735 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 MRc)0LWmwSv0m#FnTmS$7 literal 0 HcmV?d00001 diff --git a/res/CMakeLists.txt b/res/CMakeLists.txt index 65f1ccd..e063d17 100644 --- a/res/CMakeLists.txt +++ b/res/CMakeLists.txt @@ -128,10 +128,143 @@ sprite(NAME unit6 CY 48 TRANSPARENT TRUE) +sprite(NAME sel_down_left + X 384 + Y 0 + BPP 4 + CX 0 + CY 0 + TRANSPARENT TRUE) + +sprite(NAME sel_down_right + X 384 + Y 0 + BPP 4 + CX 0 + CY 0 + TRANSPARENT TRUE) + +sprite(NAME sel_mid_down + X 384 + Y 0 + BPP 4 + CX 0 + CY 0 + TRANSPARENT TRUE) + +sprite(NAME sel_mid_top + X 384 + Y 0 + BPP 4 + CX 0 + CY 0 + TRANSPARENT TRUE) + +sprite(NAME sel_mid_v + X 384 + Y 0 + BPP 4 + CX 0 + CY 0 + TRANSPARENT TRUE) + +sprite(NAME sel_up_left + X 384 + Y 0 + BPP 4 + CX 0 + CY 0 + TRANSPARENT TRUE) + +sprite(NAME sel_up_right + X 384 + Y 0 + BPP 4 + CX 0 + CY 0 + TRANSPARENT TRUE) + +sprite(NAME checkbox + X 384 + Y 0 + BPP 4 + CX 0 + CY 0 + TRANSPARENT TRUE) + +sprite(NAME line_edit_left + X 0 + Y 0 + BPP 4 + CX 0 + CY 0 + TRANSPARENT TRUE) + +sprite(NAME line_edit_mid + X 0 + Y 0 + BPP 4 + CX 0 + CY 0 + TRANSPARENT FALSE) + +sprite(NAME line_edit_right + X 0 + Y 0 + BPP 4 + CX 0 + CY 0 + TRANSPARENT TRUE) + +sprite(NAME car1 + X 0 + Y 0 + BPP 4 + CX 0 + CY 0 + TRANSPARENT TRUE) + +sprite(NAME pavement + X 0 + Y 0 + BPP 4 + CX 0 + CY 0 + TRANSPARENT FALSE) + +sprite(NAME car2 + X 0 + Y 0 + BPP 4 + CX 0 + CY 0 + TRANSPARENT TRUE) + +sprite(NAME building1 + X 0 + Y 0 + BPP 4 + CX 0 + CY 0 + TRANSPARENT TRUE) + +sprite(NAME building2 + X 0 + Y 0 + BPP 4 + CX 0 + CY 0 + TRANSPARENT TRUE) + level(NAME city1) container(NAME jancity SPRITES + building1 + building2 + car1 + car2 + checkbox grass sidewalk roof1 @@ -148,4 +281,15 @@ container(NAME jancity unit4 unit5 unit6 + sel_down_left + sel_down_right + sel_mid_down + sel_mid_top + sel_mid_v + sel_up_left + sel_up_right + line_edit_left + line_edit_mid + line_edit_right + pavement ) diff --git a/res/btn_left.bmp b/res/btn_left.bmp deleted file mode 100644 index 7d8ee4e9a4e2b9d6e23ec45cb3c7a6de67a8f380..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 586 zcmZ?r^2nNZ4FayJX7y|R0+=Gh23=#;a zwQwDOfo4w57i5@M!ojepLYQG?y&}VoPG*KJEiw#ydIT6AtzcldGEa@++5#hHtx!7#IX0fDuY#P-dZEAOfL6Ripodf$Mq*o%$X^hyMT30RjV0 f|Gf(Wp%7>NA1FE;X8(R@_(YxoGgzVF$N;4QE&U~q diff --git a/res/btn_left_24.bmp b/res/btn_left_24.bmp index 36e237095a6d04aa2e02673397aef301406c0c25..2ab8bf0240a97e65ce97a305364c35948a4387ed 100644 GIT binary patch delta 54 xcmdlcw2eo_$=8gH0SwH5qy`WR0I>oPGcrg3Ng!a`sM5&1S(SAO<77{cw*a&n2h#um delta 60 zcmdnSvrS0F$=8gN0SwH5qy`WR0I>lOGcrg3Ng&|dsM5&1S(QnJdGk-^0LIOdtg?&% D=LZOe diff --git a/res/btn_mid.bmp b/res/btn_mid.bmp deleted file mode 100644 index 801e0d5dc26b5a1ca08f4433084ddafaa3f1f3e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 542 zcmZ?rm1AN6gLy!*28acK*Z_zb8CZZM149EN1H%S>2xbNHL70KzKMa9+PVPa)U@~ diff --git a/res/btn_mid_24.bmp b/res/btn_mid_24.bmp index f7a0ca09e8449528cc76cd25b639c5f1cbac1a28..fb2e82fc88989e0270437b946d11b4ca0ef63afa 100644 GIT binary patch delta 54 xcmdlcw2eo_$=8gH0SwH5qy`WR0I>oPGcrg3Ng!a`s8YndS&Y?zY4SCW1OTzb2T}k4 delta 64 zcmdnSvrS0F$=8gN0SwH5qy`WR0I>lOGcrg3Ng&|ds8YndS%9g5aq~202d2#*m>U=; IUt>)G02HDNPyhe` diff --git a/res/btn_right.bmp b/res/btn_right.bmp deleted file mode 100644 index ae7cc856040ea4f6e98f33d66f2f10d2c3e2dc15..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 586 zcmZ?r^2nNZ4FayJX7y|R0+=Gh23=#;a zwQwDOfo4w57i5@M!ojepLYQGiodUzE24#jFoy-hdT4Wd=tzcldGEa@++5#hHtx!7z7~zMhigsa4HQ9iUlEbn&W>k*p>vLf2Bg`f9V|{(EmSe dpy|6HaQ}ZA#9f1h{ta=@nQ72qOiO?=7yyZpB?tfj diff --git a/res/btn_right_24.bmp b/res/btn_right_24.bmp index 26da50ff193129151fccf34099bc10cbf328bb5f..c56b308c75b334b4b55a9df583a69cadde9206f2 100644 GIT binary patch delta 54 xcmdlcw2eo_$=8gH0SwH5qy`WR0I>oPGcrg3Ng!a`s8YndS&WsPY4Ti-nElOGcrg3Ng&|ds8YndS&XTjd9y5wBohF-hX%_4 diff --git a/res/btn_small.bmp b/res/btn_small.bmp new file mode 100644 index 0000000000000000000000000000000000000000..43dacf641e220043d4a37d77eb7c59c3013a4abb GIT binary patch literal 490 zcmZ?reZ|NC2B&~z4G>E}F(U&DSX==pzkwfu1%M(T%)sy;hQK^0_n=}hg9L&JP3>Qx znUnJc8RnI6Ff6JNW>{IT$grc6nPE$d48xut0fxsb7#Ob1Q)9TcK#Sq#Vts~3Yc&~O zZMGhr^ZsFAd!f-s24+A~1BfM{m=VlkU^oDj-@p&SV1+>9Kf`|@nw%#_HiDQyp&=04sbUD( z9>Jq=L529{R*4;*k|ZIZ7NADBv8(FDNz#s{7^od+)SMDAi1^JV8lQKWl7xU-AbNp@ ztZ4vw=juXrl1zXr25JOq2O0time-pN;Zh_qfEt13z{3`<_t6UZhs)&%BA_z37Kqm% zBwUc732+5)EhEaDR~s~mMEJu8E=xQEYd90H9j@^HiU#)dM18oCHw`)B@KIETZ9TvKjCygKQIk8X<-N03BJ6dH?_b literal 0 HcmV?d00001 diff --git a/res/car1_24.bmp b/res/car1_24.bmp new file mode 100644 index 0000000000000000000000000000000000000000..cb7475f27b2aa07e951d1042bdaa9e8e9e603af0 GIT binary patch literal 9270 zcmeH|KZ_MX5X7IKz|_#dz`#toOXcztgNsDr^fL&GpT)pHb5lcw3luIe^-m}Uf`W3Q2T``DMrK4ypBnd+MA+Mc_k9f>pZ7CS9vaNt}yds|Mg`(TG(tZ zHWxP!4;ci-h?p2prF1a@cy4*T)un24S?Q*C0j34{^wIt90H&0=cppTdQ*PaO49T67 zlY6J9%*3pu(E^kk+1hv?{0M{g!}Ay4-=8z5p+x||q-QQZR-uEA@4kZsbKabtF%z?r zMhid~>5;9C_rZ^n+efdu1DO5kf&myGt3W@7vx^(@=hxSdtw^nC z%k>f<{=vg9#Q#lKY06^eD{aj%Uov0hV zpg$snJRUT{PZbOje}6k?{Q3Fm$LF^mTI5yrMt@XDF%SA9bxN z#3TIlB)OPSSOmcTJLckJ3$^_(krE$gln?6PH^1vGEZXYNAik^L9g>2j{7JNa9pu;j zir;Q)?E5ko{~!1huc7UY0f6YwEPV3k<&$S-)+N#_v4(fk_a)JHJaWbuz!X2U>4-so z3b&*pi2exX<5Hkq9#=_hf-pDBK5ty4z~^4lM$r$B73cP>8qLrgmS zy21oqe~h$%M3`Qu_^15o^3SRl@Hif15-)#5!aU-S!CTqJ`KSEp@&izZq_**E>>t1w zu9bQQR#(LCpg*k%BP)p?wW%WAuUe!&D2a8k0K~(rb4T#?(TOUFS2@CrxY1$~f9sEm zszu5l-NAY`4?&I8uJNsMuYmEVnexZr9fHU|>0yAfZ+fZamTD1DS7ad2zj{DU%fhSgT@OzXsb^ZTGRSRGg$SRGg$SRGg$ NSRGg$SRGg$_zO>Ty&C`k literal 0 HcmV?d00001 diff --git a/res/car2_24.bmp b/res/car2_24.bmp new file mode 100644 index 0000000000000000000000000000000000000000..6ca8f3d22c6d2efd2061d12675b4ab317ccca3ba GIT binary patch literal 9270 zcmeH~ziJjy5XILgu(c8k3mYrpOP|6{8v_Bc_^|T{)I5a`U?Ic@u(eE)B7qdPiltZx z3O1JUhX)SB+&{Yu3HZScvzM9OGiPSby}KXTf3&$f{rlUn-s9SG-Ql`1-D2gB=O1qB z(v4}loGu^i?O`|_i|YrvGU7Vknhs`Bv3 zZAcy;96a4_S@F4(tOO`GvX%aI@Y5Ky=WpMAKf7Q}rkenOsh_p@IE4zmc(Z{7aXy}& zvf^_mSqY#q(j!~xUk5*(93I`DHDK0Q0*VV$pzr^Q)MdwBrehC%K5c@zrKEI zjm)DsFZkET`?F>}qe|Le3Xu+{48JU00+yejtL0xi?^=9SpHh(7JFE1WWh((yeuiB> zFGz+Jp0}f8?7qNJ9DIKt%J$607m24SOvDYuE&?h8~#|m7`+I z0Ce<$Dwzox2Tr;bvqSL9^#LpfrJK+pza7F$lhzvXaRj|zZb=TU zVy4n|rx0YT|0=)r5l;$LF}2a+*Ss*aB;rw=S9tAjYmNA7|FO6KTp!*Sx@Dq{0np3E zu)=$P?N}@BMEpX1luj;=wj0MGgsuIp^83JuHifIskLDFmYmM_-AA>ECorq8Uzkhke z(`f2eY!)Pi;7R1@Mz+!iApRss3ak3G_%$yLKvFf$0!;k~&&SI8l;3kwjE_^$KbER2 zdA~?eZe%O{$WMFTFVbVEim8njzvk7(dDl`H=M}#7vC>CA;?oqQW9|(kFAfd!52=hE z?Bgix5SILaooK2^OF4=Ha~tX^Q7P2Cmb&V=J@JUSB@so12i&SC9Rk3$|Ykxou)1t122r2rzd41iNyXh$7J?)-B3k@Z=QSIUmc;{`4F?XIJd`)i!8kJQtMAO28aC@>Tl3Je8?0z-kJz))Z)FccUH3?UzTCWr-DW55g$mRaJRd{YbLuu?KQmJBKEn0PIxXObh4NrsdRIT9n+a literal 0 HcmV?d00001 diff --git a/res/city1.txt b/res/city1.txt index 35aa10f..88ec6cc 100644 --- a/res/city1.txt +++ b/res/city1.txt @@ -1,21 +1,31 @@ -24 16 +24 24 -0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 -0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 -0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 -0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 +0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 +0009 0009 0009 0009 0009 0009 0009 0009 0009 0009 0009 0009 0009 0009 0009 0009 0009 0009 0009 0009 0009 0009 0009 0009 +0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 -0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 -0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 -0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 -0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +0053 0054 0054 0054 0054 0054 0054 0054 0053 0054 0054 0054 0054 0054 0054 0054 0054 0054 0054 0053 0054 0054 0054 0054 +0048 0049 0049 0049 0049 0049 0049 0049 0048 0049 0049 0049 0049 0049 0049 0049 0049 0049 0049 0048 0049 0049 0049 0049 +0055 0056 0056 0056 0056 0056 0056 0056 0055 0056 0056 0056 0056 0056 0056 0056 0050 005e 0051 0055 0056 0056 0056 0056 +0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0001 0002 004a 004b 004c 0000 0001 0001 0001 0001 -0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 -0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 -0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 -0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +0009 0009 0009 0009 0009 0009 0009 0009 0009 0009 0009 0009 0009 0009 0009 000a 0057 0058 0059 0008 0000 0000 0000 0000 +0030 0031 0031 0032 0000 0000 0000 0000 0030 0031 0031 0032 0000 0000 0009 000a 0057 0058 0059 0008 0000 0000 0000 0000 +0038 0039 0039 003a 0000 0000 0000 0000 0038 0039 0039 003a 0000 0000 0009 000a 0057 0058 0059 0008 0000 0000 0000 0000 +0040 0041 0041 0042 0000 0000 0000 0000 0040 0041 0041 0042 0000 0000 0009 000a 0057 0058 0059 0008 0000 0000 0000 0000 -0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 -0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 -0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 -0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +0062 0063 0064 0062 0a00 0a00 0a00 0a00 0062 0063 0064 0062 0a00 0a00 0a00 0a00 0057 0058 0059 0008 0a00 0a00 0a00 0a00 +0069 006a 006c 0069 0a00 0a00 0a00 0a00 0069 006a 006c 0069 0a00 0a00 0a00 0a00 0057 0058 0059 0008 0a00 0a00 0a00 0a00 +0070 0071 0073 0070 0a00 0a00 0a00 0a00 0070 0071 0073 0070 0a00 0a00 0a00 0a00 0057 0058 0059 0008 0a00 0a00 0a00 0a00 +0077 0078 007a 0077 0a00 0a00 0a00 0a00 0077 0078 007a 0077 0a00 0a00 0a00 0a00 0057 0058 0059 0008 0a00 0a00 0a00 0a00 + +0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 +0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 +0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 +0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 + +0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 +0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 +0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 +0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 0a00 diff --git a/res/font.bmp b/res/font.bmp new file mode 100644 index 0000000000000000000000000000000000000000..7fc1c361b742a4519fe0a1613ced71afeb768a02 GIT binary patch literal 8206 zcmd6sL6YOR5k)CV-r6o+z!b>?D7v_qr9xtaSKjypeE=^U;S2Z#K8Ke+!W_xV-r4W} z4^U85S9>NLV>f0B0uvtzAoC-UWZ(Yq>#=kB8}*;~`^?|p`8#wc>aP3i@4D_EzscXP zc-G(T_kaA0`hHI7-+(Va{LuZ2|2}{IbNA05f9$?|`O>|NUH7t=u{+QnUAejU?2UQ5 zsM}>Y-qoI6-5WinUq93IN(Zx059{TOXc2x|FY10*hHjx_-ZtuC>(y`kuw36^B^cL@ zj`=!G!b@}TFCXCNt2(@>m+=|T;IV(Z?Zx&zBj==v`Z7#e1@0(!Sb)07%f`**>O4csSpL+>UU5Si2MW@F)0jEqJz5EvUv>xQuG4{iE8gk?B803|K zCy4#)T1)peX4djzpJ7p-zmY#Aql@6I{SR1zRsM$+$Sx}E3 zxdFwpR)vhRe|>l$(=tAZRe=mAc=c`k>;qTuqtnn2^yfAwyM`x$MEytla|YoFdkjA6 zzlI;tN#3H}Iej<2s1JTT2vf>%r0uhYGfy^?7UdkJOt$pGl;Vk#QB?cG_5s6EhEDnR zbWI9wiOp6r3Vy&e97uauWZINEaeW5gu)VaW^WI%1-k*P&hNI$soBMQ&u|&(XWij3i z$r8H*9lUZKKao52NAkd9;;0yZ}+tLj8g8AeDw*xt{S&yXSe^HOyKw z@j>gwlU=ag!dU0P$%LDl{_m^6Lwi;y(L5A0u}^mp8(oL1w6*eB zBRnw=xi>d#+t?($MIt`mskctjZsd2p_h*#_t7>wBkE4v-<0S zpUz^)R^G6T57Um@1D_KIP$hWfw-#_BPC}Z=MgQCUnO;Swf)DcUQCY3Cpmgv0v2DSB z^2#qf?dw;M*;v=3vsv)>eipJY`6T;zclGWgD8%N;1_*vrmB8Db!~5Mg;RW*$3DXh$ z{J&WG#9`UyJ1Uij_T8wOy9T4G?!-^66}j7DY>A5UUEv|g8l!yUgpjrr*rHKdNv*@Z$_nY1?`m)4-b)$fQ&3h?XJP$Sr#Yj{ z6FsuP)<2>yv+wJF!UvgAz1QhgJws8{ap(1xOTQ<0&kz zX`O#^F7PjHoLAU_Q?14Bbd~Sv0o}et!)L-fT??q!Lo4haM*TrS04P(m}&f`N*VrEp9 zoi;Yiw+_clIEkVXGYj7LY{N!A?eI@E!|MrN!ATU=nCSr~X6vKy2Ufr=lwO5;AWLZ!5TNtkOoQL&v#4_7KoLsx$wFyG1 z>RjQMnZdEY<0LUr?>l*;$GX<+b8ptow-tQO)HJjHQpzElZ`S-+8}c2Kf8VSl{A-=4 HJHPxJ1&IRM literal 0 HcmV?d00001 diff --git a/res/font_24.bmp b/res/font_24.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b12a8ce933e6003c499680f3aaeff2e7198b82ca GIT binary patch literal 48438 zcmeH~F_I+7aYdIWpvogqqy&RZop;zH@K_Xi0h-}R6sds^`+#rXJR&1=x_WwMfojW5 z^YD1_{kvyY)$G6j#~=RZm*4*W!2MtO?^pi&FaGxVqdVLn4=EAo{|{MfI~*GC`2zrAIDxvdO_J#O#B zS1pKL%}1SjByp~0h{-E*=snmIW_2SN2c(ebLruEyf6nLc~lyB+oM5u=6(7=NppPT10ku2yVler&0D7cy=&-C}@? zIK~F!*0!TTK4ip@?c>HI*K5UI&#YCS5p~U(%PanQzzCh|cqIIIZ)Ocm3QRt&I_F&&nL8*TVtciu_KK zjwttS7Y}#EwhBKgi6tJZ*N^h>GuLH4yxV?z{LDVT*jv9g+h2_auDmsKegg-&3Jzea zHkctYcDEmjW;i~U5j5{tqQl{iU;xkFzE|i(#5Zt=L@=aS@&>D)6>DZ&Ym|UlF`0;u zWn4vyfa~i0+2$ic;PHs0ZZpPRWt}0rob?$s**akiw!OzNyXp)}5y{)dk-^wkq}0*d z@Drx<9dnjK=u57J0$)`T=-rNUoFI7u<54aEmhjWd=y;Zco=q?w85moLI7R~b=(Hc1 z-bx&uD3Hl+2jpS+8%|_;x8o~?Ez?Qb>E+PLmVQ=C09=j;#^I0|I)CZsZ@b$mMa11L zgC-bTzlr_ziF6@>>;flltn(d*=_GM4o52bFIzWT1Z58?+5d*fOgJEKHRz}Q@whTvZ znbe|0$6c=T9fujou@p0jTMMzgYAv!?0cY21g`YEdSR5HTtB9G#ZkYx+IF?G0j18Gy zcDXN(w{E}Kg9C|^b@}yv-WA^ycu(MJ0(?~c?aTd&{2k@HsaI^P!`FNNb~C6~G=GM( z^!4yJ>paQUA>RHwp%pq_=Wy5^TVoli&UYNZptpSOSHLHp55?6(N9r(1cKeEEmurQN zn~CkKTI1kYMym522OuC%v*&jn#$LPwZ^x+Gw(G8F9L+K6&Kq0qxx%o4ervW)=Q|#Z z!vT<4{p9R{Q8VP|x+|W^R=|m7NIqA993s7Joz8dsJs35ws&vIO8HK!uSECNO0=o4XLGqBelw;Xu?7jWyd|;WIyH|aI zDHSto@6l(=YxVO)rpERIG<6=_8S9;2kUZgz&Kk8217nNW2=`ro}hP) zvvtsH#(3zMjHNBZkyVFGORZhvBdD|5lymU-YIWy5l3`)#4B17d@m3I=Pa3 zF|ff8&s;woXGE`vaQ4H;U!1`Ccm_^zCa-o|;bS7La8>1ZT5=(Zzkoj+FbcB>ZhQv$th z-wnI=fo4Q&Q53j(M1whZq=ARSLHVGjl)ZF3{5)SOLTlUk;5oJvM?3~N>$Nh%kXKs( z>}r4@;)md%<`!lMxNrM9D32{gGJ$m${Wwn?jN>G2Ja_pp2HLielWc%puTE}bu-gY= zEilWm+)CXht#uFq*j`cI?wSl^Kr)lu4sh^S%O^S-IP`TTKJwOL&IDuY)0cYg`^QSO zg7H=-*mn0}@>4_})_PzG7bkt~~GmposX{t@dcOaeq!1$U$WH<`=-=?l57GD_%8OIJ3= zk@&GGcXegy)-kUWdG27%kl~Wy&JmYk5^ykrNgBk4I+Cjnc>waM!m_2hgi>q8W;i>R z@soo9GQ&?Fj3tt7$+O;3W-GF7do4P4yB1qxnd9i|#3~vdetIkLV9b;B;)qglH4Kbp z{8%e@Fa@JSkmOaZz}qUL79wg|)MXg^;*M0}!NhF`gYmdC;chUPHn4S`B!Pk)QL0-; zmSoHbz=uf?!FH0~pZnoB*H$gb_-Wa8f$B$bqE1GnF$YL8tqlNd%QUtEsx{N)MlFxq7jc#? zlBAkhelDX2N{q`YsWo<8HnY_kz?KwIcu_e#70V|4iP_t)g=HwFD>{IMVzHAV6xBA;brU5I!v zLuV}8a1LHE-|9IgM}WSU&XIK)Oats@Yui_ja}ctZEtP!g5^MpIY=z%40NYyR86al~ zyofVWrO2=1sWO5C%ofTK-;yJ_^-RTq4G$}@Zi55NR<0+t z@acRq(o{TDk!b*tUT#G)oEPV#XYVQ0!PZFwiMM1Yse)~XLp}!y8tZ)G22@x-0%6?B zow{3{tGcU>6g!TM}70it8jd^5K*^k9x`b=dWymV#}`c&o5t zWVU1{@j#XBvuNxr&T(Mwhxu4yt2vTmxovsN*e@M%#fi(UfBBGMTAbLW{=;0IU4b-? zjw8ZSux%|Y4JHR|2VnSVohwGqO4;?Q6JrK?UTcv_a?7Mvu%R3Pwe zkETeb=m64qGx0!jT+tapW7!(XvAn{PPmqI8GQeOt;&MIsO~4R|+B zzqWX572a{`O!4#LW=v8QTOQo3YTj_aVFLcswFkwQ_I-?dN%|@gT-Q`|{r9x)w1a z*d9`0x-a5GUpca6*!4Qp>Vs`~^tCR9+kjnrZ>ccpYcxK@W7{B7(Xm7?n{l==bKCos zj&4&cf?X>NNr2m0Iom-SNELzu(_4vKhvZm_k>p}TK7s@!w>tXS_T`+_0gKd?PJnZ* zOyEi<06{auPq1eCd10fMjX9!p-G;%k>+vlHGcX6$Qn$diR?4+udyk(jGs zc4`?Q)z^79NmiG7L!I-39n+I&W z^~%|;;33(y)-U-!*ktEBhVd)zJSC<2>#;>{W2-zbw0#QQP8v@T57x?W!J%lo%JC7v ztiKd1gAEEG)AFyI7q<+(2Nu4Dqj_)|+ge@sW3g^yfaR(~a(i8ohZ%At73rv(BJX@0jum5!Ksd(*JeA$m(u_b|JTPm0gxzLuV9K$FseaSaGm3le#O(*7iyXf*j8TdUpjdL!mJrmL%6& zO}Z;dK3n8RMT`F=-NZBt_Qorx9Np zU<7PA0gLvQyDfguS>aX6T89zk2qbdO0I0vl{SkK|ak0$c8GtFWb?eq>t` z%|n$~RZxX~=&=M~Ef_H}y-Sj@z;wC6#I3=0&dxUE%500mCr?1#*iewWnvEHU93o9B znBG?szzJ*%jpJGxBCQ~>owHlHuS{%P6jCO6g4B}XzQrW*X}MuIyX3hJBJ$flM7qzZ~`chfH=z+5(oNGx43@L-2>Y{g`& zjY8dTu$4J`j*Td6`)bc?*S)Lrh@ih(3KOguV-D(VEf>$x*)jv$G9)8nFtFGNCP4nm zvq#RmGOI}PBUshQG}A!mJ8oti57tbQYjBG-@Q$BMfFb8INbuyyD~#n{QTXDs81~cZ z2k?83$Z|fBS32#-`ijo&SqhC2-5$9Do_L1gD{*{VUI`xZdVW!-4If?%Fm2=ffF0br z^~Ce16r$Wghpi{?r`W^K&ckx&(g%^u7A9Ac9|$5sFpiVC{jPvvh7QMJo{zx$FM;*_ zNx5ha#=KP`;&PCqk?*v`50{^XD+2%yCm4Yv+PYFucmQ24YRz;lfczcG_3@68%3wQa z=1JV1w<7`=K3#5MDu&+z=W^`kS)?ez$L2GnJ|N-%Z$0-w=(?BdBRI^5Esx6(j~VL3 zyHz@~);eVRV8@3ehpkxJdd@)liHz1Fj#T(04cPJ_TJG>b4t*XIo*Cm7 zxJ|Y~$9*t)e+7JG4LppalZXC_?H&%wTMy*Hw7msxldaHk4w9q`&GbJux;2?(vP=fG zCpsy58=#hd)ev9tY~{LQ4tdVfLJE!8gD`mnkTTJ_`ZvAGVDq;v82YB}M>~r@tB=@YS*lbsU}~y`&J9tVKSI0T~sX zz}4<=ZTJsW?D{6yL$Kx`qR3ACS z9E{Z~EX*x=P|&jqx%XpDmCT30E3z;g@f5K~Rwh0Lx=N%T1}Y#(m8&B#l(6WbR(vLi zAPQY*#A2z!as5zhlV(F?#2WV#7i#d)HW3C?pt+`6v(! z+W;~?2=0L+CF4DHdr8tIXVqCnq85eWqyf~Fk~xoPIEhX~60AC&UGEVg$Znb<)4;vJ-&Qit?}eMF@gxF zc;}*Ag390uZeQ2}XA{HNJTsmcWpFjqOO=4^1r_3(TP1dMN)kjs#jEPX2`Ymtm{TGK zVc%S$@p+diLA0g;jF$dL>3M}V;^5!4oPws=cztfs|Q37 gyKs@f^7i89T!(iA;h aE;ousLtr!nhG+=Tv~U0#PSe5-XgB~5V<%() literal 0 HcmV?d00001 diff --git a/res/line_edit_right_24.bmp b/res/line_edit_right_24.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f9cf4e02bab9f2fec74d5daa033ff1b7777491cb GIT binary patch literal 1590 zcmZ?rHDhA{12Z700mK48tN_G}3=%*R2!Qe%_#qe~z`!s$PmCa%S8IIr`11b@|AC00 zVz`2xi*iX)57hYR=3%&YVi=oe#_#BqB#1V*N-U@l2O2oNREeNsxPn!6AT6JFnG!@d zmuNtA%_$*DJeZ`BQV&tQYuB#x=g(gy0&Ll`<;amEL@0zRIez>&garvGf+WNl W1eL)RkYqSe*Qk1U&|zhe8a@EIbsEzE literal 0 HcmV?d00001 diff --git a/res/sel_down_right_24.bmp b/res/sel_down_right_24.bmp new file mode 100644 index 0000000000000000000000000000000000000000..01db4c23031e14dc446ad2867b3369f788de7a8a GIT binary patch literal 822 zcmZ?rHDhJ~12Z700mK4O%*Y@C7H0s;Z{UYuhyVk_Dk8w9O`GoCz5AcxKM)b29IE8R zi4!EL2Worq;sx>M163Y6bm%G(;QaaXyLRmYs$ac&H4)08N{$>k0@MQWH9-=hXUmo? j1XaQn0JR)HejLsv$N;JbdW4`dxB`fi;9P=?k*OX44tpC6 literal 0 HcmV?d00001 diff --git a/res/sel_mid_down_24.bmp b/res/sel_mid_down_24.bmp new file mode 100644 index 0000000000000000000000000000000000000000..20a2f7144267af859e53da7b9cb633478bfd21eb GIT binary patch literal 822 zcmZ?rHDhJ~12Z700mK4O%*Y@C7H0s;Z{UYuhyVk_sv!=p(ir?__&kaa9a2BEf diff --git a/src/building/inc/building.h b/src/building/inc/building.h index 7c7d45f..88840f5 100644 --- a/src/building/inc/building.h +++ b/src/building/inc/building.h @@ -33,7 +33,7 @@ void building_set_alive_cb(void (*f)(const struct util_rect *dim, bool alive, vo int building_render(const struct building *b, const struct camera *cam, bool sel); const char *building_str(const struct building *b); -extern struct sprite building_sprites[MAX_BUILDING_TYPES]; +extern struct sprite building_sprites[1]; #ifdef __cplusplus } diff --git a/src/building/src/building.c b/src/building/src/building.c index 826ebe1..ee1ee84 100644 --- a/src/building/src/building.c +++ b/src/building/src/building.c @@ -4,7 +4,7 @@ #include #include -struct sprite building_sprites[MAX_BUILDING_TYPES]; +struct sprite building_sprites[1]; int building_render(const struct building *const b, const struct camera *const cam, const bool sel) diff --git a/src/camera/inc/camera.h b/src/camera/inc/camera.h index 27efe2e..96a64d5 100644 --- a/src/camera/inc/camera.h +++ b/src/camera/inc/camera.h @@ -18,7 +18,7 @@ struct camera long w, h; } dim; - int x, y, x_speed, y_speed; + long x, y, x_speed, y_speed; unsigned xt, yt; bool pan; @@ -28,6 +28,7 @@ struct camera enum { CURSOR_STATE_IDLE, + CURSOR_STATE_HOVERING, CURSOR_STATE_PRESSED } state; struct diff --git a/src/camera/src/camera.c b/src/camera/src/camera.c index 9d3d062..5e658a5 100644 --- a/src/camera/src/camera.c +++ b/src/camera/src/camera.c @@ -55,9 +55,13 @@ int cursor_render(const struct cursor *const c) case CURSOR_STATE_IDLE: break; - case CURSOR_STATE_PRESSED: + case CURSOR_STATE_HOVERING: s->u += CAMERA_CURSOR_WIDTH; break; + + case CURSOR_STATE_PRESSED: + s->u += CAMERA_CURSOR_WIDTH * 2; + break; } const int ret = sprite_sort(s); @@ -89,23 +93,24 @@ void cursor_init(struct cursor *const c) void camera_update_pos(struct camera *const cam) { - const int x = cam->x + cam->x_speed; + const struct camera_dim *const d = &cam->dim; - cam->x = x; + if (!d->w || !d->h) + return; + + cam->x += cam->x_speed; if (cam->x > 0) cam->x = 0; - else if (cam->x < -cam->dim.w) - cam->x = -cam->dim.w; + else if (cam->x < -d->w + screen_w) + cam->x = -d->w + screen_w; - const int y = cam->y + cam->y_speed; - - cam->y = y; + cam->y += cam->y_speed; if (cam->y > 0) cam->y = 0; - else if (cam->y < -cam->dim.h) - cam->y = -cam->dim.h; + else if (cam->y < -d->h + screen_h) + cam->y = -d->h + screen_h; } bool camera_translate(const struct camera *const cam, const struct util_rect *const dim, diff --git a/src/camera/src/mouse.c b/src/camera/src/mouse.c index 30fedb9..e7b144b 100644 --- a/src/camera/src/mouse.c +++ b/src/camera/src/mouse.c @@ -13,9 +13,14 @@ static void cursor_update(struct cursor *const c, const struct mouse *const m) c->x = m->x; c->y = m->y; - c->state = mouse_pressed(m, MOUSE_BUTTON_LEFT) || - mouse_pressed(m, MOUSE_BUTTON_RIGHT) ? - CURSOR_STATE_PRESSED: CURSOR_STATE_IDLE; + + if (mouse_pressed(m, MOUSE_BUTTON_LEFT) + || mouse_pressed(m, MOUSE_BUTTON_RIGHT)) + c->state = CURSOR_STATE_PRESSED; + else if (m->hovering) + c->state = CURSOR_STATE_HOVERING; + else + c->state = CURSOR_STATE_IDLE; } static void update_speed(struct camera *const cam, const struct mouse *const m) @@ -24,34 +29,55 @@ static void update_speed(struct camera *const cam, const struct mouse *const m) { MAX_SPEED = 10, STEP = 1, - THRESHOLD_X = CAMERA_CURSOR_WIDTH / 2, - THRESHOLD_Y = CAMERA_CURSOR_HEIGHT / 2 + T_STEP = 10, + THRESHOLD_X = CAMERA_CURSOR_WIDTH, + THRESHOLD_Y = CAMERA_CURSOR_HEIGHT }; const struct cursor *const c = &cam->cursor; if (c->x >= screen_w - THRESHOLD_X) { - if (cam->x_speed - STEP > -MAX_SPEED) - cam->x_speed -= STEP; + if (++cam->xt >= T_STEP) + { + cam->xt = 0; + + if (cam->x_speed - STEP > -MAX_SPEED) + cam->x_speed -= STEP; + } } else if (c->x < THRESHOLD_X) { - if (cam->x_speed + STEP < MAX_SPEED) - cam->x_speed += STEP; + if (++cam->xt >= T_STEP) + { + cam->xt = 0; + + if (cam->x_speed + STEP < MAX_SPEED) + cam->x_speed += STEP; + } } else cam->x_speed = 0; if (c->y >= screen_h - THRESHOLD_Y) { - if (cam->y_speed - STEP > -MAX_SPEED) - cam->y_speed -= STEP; + if (++cam->yt >= T_STEP) + { + cam->yt = 0; + + if (cam->y_speed - STEP > -MAX_SPEED) + cam->y_speed -= STEP; + } } else if (c->y < THRESHOLD_Y) { - if (cam->y_speed + STEP < MAX_SPEED) - cam->y_speed += STEP; + if (++cam->yt >= T_STEP) + { + cam->yt = 0; + + if (cam->y_speed + STEP < MAX_SPEED) + cam->y_speed += STEP; + } } else cam->y_speed = 0; diff --git a/src/camera/src/pad.c b/src/camera/src/pad.c index f3af527..b5dac1a 100644 --- a/src/camera/src/pad.c +++ b/src/camera/src/pad.c @@ -48,7 +48,7 @@ static void update_speed(struct camera *const cam, { MAX_SPEED = 10, STEP = 1, - T_STEP = 3 + T_STEP = 2 }; const struct cursor *const c = &cam->cursor; diff --git a/src/game/src/res.c b/src/game/src/res.c index dead212..acbe174 100644 --- a/src/game/src/res.c +++ b/src/game/src/res.c @@ -108,6 +108,102 @@ static const struct container c[] = .path = "unit6", .type = CONTAINER_TYPE_SPRITE, .data.sprite = &unit_sprites[UNIT_6_SPRITE] + }, + + { + .path = "sel_down_left", + .type = CONTAINER_TYPE_SPRITE, + .data.sprite = &gui_rounded_rect_sprites[GUI_ROUNDED_RECT_DOWN_LEFT] + }, + + { + .path = "sel_down_right", + .type = CONTAINER_TYPE_SPRITE, + .data.sprite = &gui_rounded_rect_sprites[GUI_ROUNDED_RECT_DOWN_RIGHT] + }, + + { + .path = "sel_mid_down", + .type = CONTAINER_TYPE_SPRITE, + .data.sprite = &gui_rounded_rect_sprites[GUI_ROUNDED_RECT_MID_DOWN] + }, + + { + .path = "sel_mid_top", + .type = CONTAINER_TYPE_SPRITE, + .data.sprite = &gui_rounded_rect_sprites[GUI_ROUNDED_RECT_MID_TOP] + }, + + { + .path = "sel_mid_v", + .type = CONTAINER_TYPE_SPRITE, + .data.sprite = &gui_rounded_rect_sprites[GUI_ROUNDED_RECT_MID_VERT] + }, + + { + .path = "sel_up_left", + .type = CONTAINER_TYPE_SPRITE, + .data.sprite = &gui_rounded_rect_sprites[GUI_ROUNDED_RECT_UP_LEFT] + }, + + { + .path = "sel_up_right", + .type = CONTAINER_TYPE_SPRITE, + .data.sprite = &gui_rounded_rect_sprites[GUI_ROUNDED_RECT_UP_RIGHT] + }, + + { + .path = "checkbox", + .type = CONTAINER_TYPE_SPRITE, + .data.sprite = &gui_checkbox_sprite + }, + + { + .path = "line_edit_left", + .type = CONTAINER_TYPE_SPRITE, + .data.sprite = &gui_line_edit_sprites[GUI_LINE_EDIT_LEFT] + }, + + { + .path = "line_edit_mid", + .type = CONTAINER_TYPE_SPRITE, + .data.sprite = &gui_line_edit_sprites[GUI_LINE_EDIT_MID] + }, + + { + .path = "line_edit_right", + .type = CONTAINER_TYPE_SPRITE, + .data.sprite = &gui_line_edit_sprites[GUI_LINE_EDIT_RIGHT] + }, + + { + .path = "car1", + .type = CONTAINER_TYPE_SPRITE, + .data.sprite = &unit_sprites[UNIT_CAR_1_SPRITE] + }, + + { + .path = "pavement", + .type = CONTAINER_TYPE_SPRITE, + .data.sprite = &terrain_sprites[PAVEMENT] + }, + + { + .path = "car2", + .type = CONTAINER_TYPE_SPRITE, + .data.sprite = &unit_sprites[UNIT_CAR_2_SPRITE] + }, + + { + .path = "building1", + .type = CONTAINER_TYPE_SPRITE, + .data.sprite = &terrain_sprites[BUILDING1], + }, + + { + .path = "building2", + .type = CONTAINER_TYPE_SPRITE, + .data.sprite = &terrain_sprites[BUILDING2], } }; diff --git a/src/gui/inc/gui/rounded_rect.h b/src/gui/inc/gui/rounded_rect.h index 13242f4..b027b67 100644 --- a/src/gui/inc/gui/rounded_rect.h +++ b/src/gui/inc/gui/rounded_rect.h @@ -15,6 +15,7 @@ struct gui_rounded_rect { struct gui_common common; unsigned short w, h; + unsigned char r, g, b; bool adjust; }; @@ -27,13 +28,15 @@ enum GUI_ROUNDED_RECT_MID_VERT, GUI_ROUNDED_RECT_DOWN_LEFT, GUI_ROUNDED_RECT_DOWN_RIGHT, - GUI_ROUNDED_RECT_MID, + GUI_ROUNDED_RECT_MID_TOP, + GUI_ROUNDED_RECT_MID_DOWN, MAX_GUI_ROUNDED_RECT_SPRITES }; extern struct sprite gui_rounded_rect_sprites[MAX_GUI_ROUNDED_RECT_SPRITES]; +/* Pad one line to avoid redefinition. */ UTIL_STATIC_ASSERT(!offsetof(struct gui_rounded_rect, common), "unexpected offset for struct gui_rounded_rect"); diff --git a/src/gui/src/rounded_rect.c b/src/gui/src/rounded_rect.c index 4ae3780..f37dcae 100644 --- a/src/gui/src/rounded_rect.c +++ b/src/gui/src/rounded_rect.c @@ -134,30 +134,36 @@ static int render_rect(const struct gui_rounded_rect *const r, rect_get_or_ret(sel, -1); semitrans_rect_init(sel); - const struct sprite *const mid = &refs[GUI_ROUNDED_RECT_MID], + const struct sprite *const mid = &refs[GUI_ROUNDED_RECT_MID_TOP], *const vert = &refs[GUI_ROUNDED_RECT_MID_VERT]; sel->x = x + vert->w; sel->y = y + mid->h; sel->w = r->w - (vert->w * 2); sel->h = r->h - (mid->h * 2); - sel->r = 72; - sel->g = 66; - sel->b = 56; + sel->r = r->r; + sel->g = r->g; + sel->b = r->b; rect_sort(sel); return 0; } static int render_mid(const struct gui_rounded_rect *const r, - const short x, const short y) + const short x, const short y, const struct sprite *const s) { - const short mid_w = refs[GUI_ROUNDED_RECT_MID].w, + const short mid_w = s->w, top_w = refs[GUI_ROUNDED_RECT_UP_LEFT].w, w = r->w - (top_w * 2), rem_mid = w % mid_w, whole_mid = w / mid_w, n_mid = rem_mid ? whole_mid + 1 : whole_mid; + if (n_mid < 0) + { + fprintf(stderr, "%s: invalid dimensions\n", __func__); + return -1; + } + for (struct { size_t i; @@ -166,7 +172,7 @@ static int render_mid(const struct gui_rounded_rect *const r, { sprite_get_or_ret(m, -1); - if (sprite_clone(&refs[GUI_ROUNDED_RECT_MID], m)) + if (sprite_clone(s, m)) return -1; m->x = a.x; @@ -186,13 +192,15 @@ static int render_mid(const struct gui_rounded_rect *const r, static int render_midtop(const struct gui_rounded_rect *const r, const short x, const short y) { - return render_mid(r, x, y); + return render_mid(r, x, y, &refs[GUI_ROUNDED_RECT_MID_TOP]); } static int render_middown(const struct gui_rounded_rect *const r, const short x, const short y) { - return render_mid(r, x, y + r->h - refs[GUI_ROUNDED_RECT_MID].h); + const struct sprite *const s = &refs[GUI_ROUNDED_RECT_MID_DOWN]; + + return render_mid(r, x, y + r->h - s->h, s); } static int render(const struct gui_common *const g) @@ -242,8 +250,8 @@ static void add_child(struct gui_common *const parent, short w, h; const short ref_w = refs[GUI_ROUNDED_RECT_MID_VERT].w, - ref_h = refs[GUI_ROUNDED_RECT_MID].h, - min_w = ref_w * 2 + refs[GUI_ROUNDED_RECT_MID].w, + ref_h = refs[GUI_ROUNDED_RECT_MID_TOP].h, + min_w = ref_w * 2 + refs[GUI_ROUNDED_RECT_MID_TOP].w, min_h = ref_h * 2 + refs[GUI_ROUNDED_RECT_MID_VERT].h; child->cb->get_dim(child, &w, &h); diff --git a/src/instance/CMakeLists.txt b/src/instance/CMakeLists.txt index 2e777a9..3651400 100644 --- a/src/instance/CMakeLists.txt +++ b/src/instance/CMakeLists.txt @@ -1,3 +1,3 @@ add_library(instance "src/instance.c") target_include_directories(instance PUBLIC "inc") -target_link_libraries(instance PUBLIC camera gfx util) +target_link_libraries(instance PUBLIC camera gfx util PRIVATE gui) diff --git a/src/instance/src/instance.c b/src/instance/src/instance.c index 1e9e039..91683f5 100644 --- a/src/instance/src/instance.c +++ b/src/instance/src/instance.c @@ -19,47 +19,18 @@ void instance_cyclic(void) line_g_flip ^= true; } -static int draw_sel(const struct instance *const i, const short x, const short y) -{ - enum {R = 0, G = 255, B = 0}; - - stp_4line_get_or_ret(l, -1); - stp_4line_init(l); - l->x = l->vertices[2].x = l->vertices[3].x = x; - l->y = l->vertices[0].y = l->vertices[3].y = y; - l->vertices[0].x = l->vertices[1].x = x + i->r.w; - l->vertices[1].y = l->vertices[2].y = y + i->r.h; - l->r = R; - l->g = line_g; - l->b = B >> 2; - - for (size_t i = 0; i < sizeof l->vertices / sizeof *l->vertices; i++) - { - struct stp_4line_vtx *const v = &l->vertices[i]; - - v->r = R; - v->b = B; - } - - l->vertices[0].g = l->vertices[2].g = UCHAR_MAX - line_g; - l->vertices[1].g = l->vertices[3].g = line_g; - stp_4line_sort(l); - stp_4line_get_or_ret(ll, -1); - *ll = *l; - ll->x = ll->vertices[2].x = ll->vertices[3].x = l->x ? l->x - 1 : 0; - ll->y = ll->vertices[0].y = ll->vertices[3].y = l->y ? l->y - 1 : 0; - ll->vertices[0].x = ll->vertices[1].x = l->vertices[0].x + 1; - ll->vertices[1].y = ll->vertices[2].y = l->vertices[1].y + 1; - stp_4line_sort(ll); - return 0; -} - -static void render_sprite(struct sprite *const s, +static int render_sprite(struct sprite *const s, const struct instance_render_off *const off, const short x, const short y) { s->x = off ? x + off->x : x; s->y = off ? y + off->y : y; - sprite_sort(s); + + const int ret = sprite_sort(s); + + if (ret) + fprintf(stderr, "%s: sprite_sort failed\n", __func__); + + return ret; } static void render_quad(const struct instance_render_quad *const rq, @@ -99,9 +70,6 @@ int instance_render(const struct instance_render_cfg *const cfg) { const struct instance_render_off *const off = cfg->off; - if (cfg->sel && draw_sel(i, x, y)) - return -1; - switch (cfg->prim_type) { case INSTANCE_RENDER_CFG_SPRITE: @@ -120,10 +88,5 @@ int instance_render(const struct instance_render_cfg *const cfg) int instance_render_target(const struct instance *const i, const struct camera *const cam) { - short x, y; - - if (camera_translate(cam, &i->r, &x, &y)) - return draw_sel(i, x, y); - - return -1; + return 0; } diff --git a/src/menu/src/gamecfg_menu.c b/src/menu/src/gamecfg_menu.c index 85a99d2..d85e7f6 100644 --- a/src/menu/src/gamecfg_menu.c +++ b/src/menu/src/gamecfg_menu.c @@ -736,9 +736,10 @@ int menu_gamecfg(struct menu_common *const c, struct net_host *const h, if (start) { - struct game_cfg cfg = + const struct game_cfg cfg = { - .p = &c->p + .p = &c->p, + .map = "city1.txt" }; return game(&cfg); diff --git a/src/menu/src/main_menu.c b/src/menu/src/main_menu.c index a7b9e73..8beed92 100644 --- a/src/menu/src/main_menu.c +++ b/src/menu/src/main_menu.c @@ -4,14 +4,27 @@ #include #include #include +#include #include #include +enum role +{ + CREDITS_NAME_COPYRIGHT, + CREDITS_ROLE_GFX, + CREDITS_ROLE_PROGRAMMING, + CREDITS_ROLE_ENGINE, + CREDITS_ROLE_LANGUAGE, + + MAX_CREDIT_ROLES +}; + struct main_menu { bool start, settings, exit; struct gui_button play, settings_btn, exit_btn; struct gui_container cnt; + struct gui_label title, roles[MAX_CREDIT_ROLES]; }; static int update(struct menu_common *const c, void *const arg) @@ -34,6 +47,32 @@ static int render(const struct menu_common *const c, void *const arg) return 0; } +static void update_roles(struct main_menu *const m) +{ + static const char *const roles[] = + { + [CREDITS_NAME_COPYRIGHT] = "(C) 2024 Xavier Del Campo Romero", + [CREDITS_ROLE_GFX] = "Gfx: Kenney, Ivan Voirol", + [CREDITS_ROLE_PROGRAMMING] = "Coding: me", + [CREDITS_ROLE_ENGINE] = "Engine: also me lol", + [CREDITS_ROLE_LANGUAGE] = "Written in good old C" + }; + + UTIL_STATIC_ASSERT(sizeof roles / sizeof *roles + == sizeof m->roles / sizeof *m->roles, + "unexpected sizes"); + + for (size_t i = 0; i < sizeof roles / sizeof *roles; i++) + { + struct gui_label *const l = &m->roles[i]; + + gui_label_init(l); + l->common.hcentered = true; + l->text = roles[i]; + gui_add_child(&m->cnt.common, &l->common); + } +} + int menu_main(struct menu_common *const c) { do @@ -50,6 +89,15 @@ int menu_main(struct menu_common *const c) c->spacing = 4; } + { + struct gui_label *const l = &m.title; + + gui_label_init(l); + l->common.hcentered = true; + l->text = "Jancity, a city sandbox"; + gui_add_child(&m.cnt.common, &l->common); + } + { struct gui_button *const b = &m.play; @@ -87,6 +135,8 @@ int menu_main(struct menu_common *const c) gui_add_child(&m.cnt.common, &b->common); } + update_roles(&m); + while (!m.start && !m.settings && !c->p.common.exit) { if (menu_update(c, update, render, &m)) diff --git a/src/menu/src/menu.c b/src/menu/src/menu.c index cc508e7..682c7f2 100644 --- a/src/menu/src/menu.c +++ b/src/menu/src/menu.c @@ -34,9 +34,15 @@ int menu_update(struct menu_common *const c, rect_sort(r); if (render && render(c, arg)) + { + fprintf(stderr, "%s: render cb failed\n", __func__); return -1; + } else if (input_render(&c->in, &c->p)) + { + fprintf(stderr, "%s: input_render failed\n", __func__); return -1; + } switch (c->p.common.type) { @@ -53,7 +59,10 @@ int menu_update(struct menu_common *const c, } if (gfx_draw()) + { + fprintf(stderr, "%s: gfx_draw failed\n", __func__); return -1; + } return 0; } @@ -72,11 +81,16 @@ int menu(void) peripheral_init(&cfg, &c.p); settings_load("settings.ini", &c.s); - const struct game_cfg gcfg = +#if 1 + + struct game_cfg gcfg = { - .p = &c.p, - .map = "city1.txt" + .map = "city1.txt", + .p = &c.p }; return game(&gcfg); +#else + return menu_main(&c); +#endif } diff --git a/src/mouse/inc/mouse.h b/src/mouse/inc/mouse.h index 55d0227..44c4f5c 100644 --- a/src/mouse/inc/mouse.h +++ b/src/mouse/inc/mouse.h @@ -18,6 +18,7 @@ struct mouse { short x, y, dx, dy; int mask, oldmask; + bool first_clicked, hovering; }; void mouse_init(struct mouse *m); diff --git a/src/mouse/sdl-1.2/src/mouse.c b/src/mouse/sdl-1.2/src/mouse.c index 35fc030..dc10b0b 100644 --- a/src/mouse/sdl-1.2/src/mouse.c +++ b/src/mouse/sdl-1.2/src/mouse.c @@ -3,13 +3,21 @@ #include #include #include +#include #include +#include static void mouse_click(const SDL_MouseButtonEvent *const ev, struct mouse *const m) { int mask; + if (!m->first_clicked) + { + srand(time(NULL)); + m->first_clicked = true; + } + switch (ev->button) { case 1: diff --git a/src/peripheral/inc/peripheral.h b/src/peripheral/inc/peripheral.h index b686eba..c4156db 100644 --- a/src/peripheral/inc/peripheral.h +++ b/src/peripheral/inc/peripheral.h @@ -25,7 +25,7 @@ union peripheral struct peripheral_common { enum peripheral_type type; - bool exit; + bool init, exit; } common; struct peripheral_pad diff --git a/src/player/CMakeLists.txt b/src/player/CMakeLists.txt index 3297619..b6c645a 100644 --- a/src/player/CMakeLists.txt +++ b/src/player/CMakeLists.txt @@ -18,4 +18,5 @@ target_link_libraries(player util PRIVATE pad - gui) + gui + terrain) diff --git a/src/player/inc/human_player.h b/src/player/inc/human_player.h index 9cfd498..19c4670 100644 --- a/src/player/inc/human_player.h +++ b/src/player/inc/human_player.h @@ -2,6 +2,9 @@ #define HUMAN_PLAYER_H #include +#include +#include +#include #include #include #include @@ -34,6 +37,15 @@ struct human_player union peripheral *periph; struct input in; + struct human_player_item + { + bool show; + struct gui_button show_btn; + struct gui_rounded_rect rr; + struct gui_container topcnt; + struct gui_button add_walker, add_car, exit; + } item; + struct sel_instance { enum sel_type diff --git a/src/player/inc/player.h b/src/player/inc/player.h index cc191ca..06463f9 100644 --- a/src/player/inc/player.h +++ b/src/player/inc/player.h @@ -18,7 +18,7 @@ typedef unsigned player_team; enum { - PLAYER_MAX_UNITS = 5, + PLAYER_MAX_UNITS = 10, PLAYER_MAX_BUILDINGS = 5 }; diff --git a/src/player/src/human_player.c b/src/player/src/human_player.c index 6083ef3..b47f4dc 100644 --- a/src/player/src/human_player.c +++ b/src/player/src/human_player.c @@ -279,8 +279,7 @@ static void update_selected(struct human_player *const h) { struct sel_instance *const si = &h->sel[i]; - if (si->d.i - && (!si->d.i->alive || si->type == INSTANCE_TYPE_UNIT)) + if (si->d.i && !si->d.i->alive) { si->d.i = NULL; h->n_sel--; @@ -357,10 +356,26 @@ static void update_from_touch(struct human_player *const h, } } +static bool hovering_units(const struct human_player *const h) +{ + const struct player *const pl = &h->pl; + + for (size_t i = 0; i < sizeof pl->units / sizeof *pl->units; i++) + { + const struct unit *const u = &pl->units[i]; + const struct instance *const in = &u->instance; + + if (in->alive && cursor_collision(&h->cam, &in->r)) + return true; + } + + return false; +} + static void update_from_keyboard_mouse(struct human_player *const h, struct player_others *const o) { - const struct mouse *const m = &h->periph->kbm.mouse; + struct mouse *const m = &h->periph->kbm.mouse; const struct keyboard *const k = &h->periph->kbm.keyboard; const struct input *const in = &h->in; @@ -377,6 +392,8 @@ static void update_from_keyboard_mouse(struct human_player *const h, } else if (input_mouse_justreleased(in, m, MOUSE_BUTTON_RIGHT)) move_units(h, o); + else + m->hovering = hovering_units(h); } void human_player_update(struct human_player *const h, diff --git a/src/player/src/human_player_gui.c b/src/player/src/human_player_gui.c index e985d9c..ce995c1 100644 --- a/src/player/src/human_player_gui.c +++ b/src/player/src/human_player_gui.c @@ -10,16 +10,146 @@ #include #include #include +#include #include #include #include #include #include -enum {X_OFF = 8, Y_OFF = 8, HP_Y = 32}; +enum {X_OFF = 8, Y_OFF = 8}; + +static void on_item_pressed(void *const arg) +{ + bool *const show = arg; + + *show ^= true; +} + +static void on_add_car(void *const arg) +{ + struct human_player *const h = arg; + struct human_player_item *const it = &h->item; + const struct unit_cfg cfg = + { + .type = UNIT_CFG_TYPE_CAR, + .x = rand() % (MAP_W - 32), + .y = rand() % (MAP_H - 32), + }; + + player_create_unit(&cfg, &h->pl); + it->show = false; +} + +static void on_add_walker(void *const arg) +{ + struct human_player *const h = arg; + struct human_player_item *const it = &h->item; + const struct unit_cfg cfg = + { + .type = UNIT_CFG_TYPE_WALKER, + .x = rand() % (MAP_W - 32), + .y = rand() % (MAP_H - 32), + }; + + player_create_unit(&cfg, &h->pl); + it->show = false; +} + +static void on_exit(void *const arg) +{ + struct human_player *const h = arg; + + h->periph->common.exit = true; +} + +static void update_items(struct human_player *const h) +{ + struct human_player_item *const it = &h->item; + + { + struct gui_rounded_rect *const r = &it->rr; + + gui_rounded_rect_init(r); + r->common.hcentered = r->common.vcentered = true; + r->adjust = true; + } + + { + struct gui_container *const c = &it->topcnt; + + gui_container_init(c); + c->common.vcentered = true; + c->common.hcentered = true; + c->mode = GUI_CONTAINER_MODE_V; + c->spacing = 4; + gui_add_child(&it->rr.common, &c->common); + } + + { + struct gui_button *const b = &it->add_car; + + gui_button_init(b, GUI_BUTTON_TYPE_1); + b->common.hcentered = true; + b->u.type1.w = 80; + b->u.type1.label.text = "Add car"; + b->on_pressed = on_add_car; + b->arg = h; + gui_add_child(&it->topcnt.common, &b->common); + } + + { + struct gui_button *const b = &it->add_walker; + + gui_button_init(b, GUI_BUTTON_TYPE_1); + b->u.type1.w = 80; + b->common.hcentered = true; + b->u.type1.label.text = "Add walker"; + b->on_pressed = on_add_walker; + b->arg = h; + gui_add_child(&it->topcnt.common, &b->common); + } + + { + struct gui_button *const b = &it->exit; + + gui_button_init(b, GUI_BUTTON_TYPE_1); + b->u.type1.w = 80; + b->common.hcentered = true; + b->u.type1.label.text = "Exit"; + b->on_pressed = on_exit; + b->arg = h; + gui_add_child(&it->topcnt.common, &b->common); + } + + struct camera cam = + { + .cursor = h->cam.cursor + }; + + gui_update(&it->rr.common, h->periph, &cam, &h->in); +} void human_player_gui_update(struct human_player *const h) { + struct human_player_item *const it = &h->item; + struct gui_button *const b = &it->show_btn; + + gui_button_init(b, GUI_BUTTON_TYPE_SPRITE); + b->on_pressed = on_item_pressed; + b->arg = &it->show; + b->u.sprite.s = &gui_button_sprites[GUI_BUTTON_SMALL]; + b->common.x = screen_w - b->u.sprite.s->w; + + if (it->show) + update_items(h); + + struct camera cam = + { + .cursor = h->cam.cursor + }; + + gui_update(&b->common, h->periph, &cam, &h->in); } static int render_sel_single_building(const struct human_player *const h, @@ -41,14 +171,13 @@ static int render_sel_single_unit(const struct human_player *const h, const struct sel_instance *const sel, struct gui_common *const r) { const struct unit *const u = sel->d.u; - enum {CARRY_X = 96, CARRY_Y = 8}; struct gui_label ul; gui_label_init(&ul); - ul.common.x = X_OFF; - ul.common.y = Y_OFF; - ul.text = unit_str(u); + ul.common.hcentered = true; + ul.common.vcentered = true; + ul.text = u->name; gui_add_child(r, &ul.common); return gui_render(r); @@ -99,37 +228,44 @@ static int render_sel_multiple(const struct human_player *const h, static int render_top(const struct human_player *const h) { - struct gui_button b; - - gui_button_init(&b, GUI_BUTTON_TYPE_SPRITE); - b.on_pressed = NULL; - b.arg = NULL; - b.u.sprite.s = &gui_button_sprites[GUI_BUTTON_SMALL]; - b.common.x = screen_w - b.u.sprite.s->w; - - return gui_render(&b.common); + return gui_render(&h->item.show_btn.common); } static int render_sel(const struct human_player *const h) { + const short wlim = 120; struct gui_rounded_rect r; + short exp_w; gui_rounded_rect_init(&r); - r.common.x = 16; - r.w = screen_w - (r.common.x * 2); - r.h = screen_h / 4; + r.common.hcentered = true; + exp_w = screen_w - 32; + r.w = exp_w > wlim ? wlim : exp_w; + r.h = 40; + r.r = 10; + r.g = 137; + r.b = 225; r.common.y = screen_h - r.h; return h->n_sel == 1 ? render_sel_single(h, &r.common) : render_sel_multiple(h, &r.common); } +static int render_items(const struct human_player *const h) +{ + const struct human_player_item *const it = &h->item; + + return gui_render(&it->rr.common); +} + int human_player_gui_render(const struct human_player *const h) { if (render_top(h)) return -1; else if (h->n_sel && render_sel(h)) return -1; + else if (h->item.show && render_items(h)) + return -1; return 0; } diff --git a/src/player/src/player.c b/src/player/src/player.c index 5a69763..a3b0a52 100644 --- a/src/player/src/player.c +++ b/src/player/src/player.c @@ -1,6 +1,7 @@ #include #include #include +#include #include void player_update(struct player *const p) @@ -61,6 +62,22 @@ int player_create_building(const struct building_cfg *const cfg, struct player * int player_init(const struct player_cfg *const cfg, struct player *const pl) { + for (size_t i = 0; i < sizeof pl->units / sizeof *pl->units; i++) + { + const struct unit_cfg ucfg = + { + .type = rand() & 1 ? UNIT_CFG_TYPE_WALKER : UNIT_CFG_TYPE_CAR, + .x = rand() % (MAP_W - 32), + .y = rand() % (MAP_H - 32), + }; + + if (player_create_unit(&ucfg, pl)) + { + fprintf(stderr, "%s: player_create_unit failed\n", __func__); + return -1; + } + } + pl->alive = true; pl->color = cfg->color; pl->team = cfg->team; diff --git a/src/terrain/inc/terrain.h b/src/terrain/inc/terrain.h index 7997025..dc29883 100644 --- a/src/terrain/inc/terrain.h +++ b/src/terrain/inc/terrain.h @@ -13,7 +13,7 @@ extern "C" enum { - MAP_TILES = 120, + MAP_TILES = 24, TERRAIN_SZ = 16, MAP_W = MAP_TILES * TERRAIN_SZ, MAP_H = MAP_TILES * TERRAIN_SZ @@ -39,7 +39,9 @@ enum GRASS, ROOF1, ROOF2, + PAVEMENT, BUILDING1, + BUILDING2, MAX_TERRAIN_SPRITES }; diff --git a/src/terrain/privinc/terrain_tiles.h b/src/terrain/privinc/terrain_tiles.h index 962bafe..89b8457 100644 --- a/src/terrain/privinc/terrain_tiles.h +++ b/src/terrain/privinc/terrain_tiles.h @@ -15,7 +15,6 @@ enum SIDEWALK_2_NW, SIDEWALK_2_NE, SIDEWALK_3_NW, - SIDEWALK_3_N, SIDEWALK_3_NE, SIDEWALK_4_N, @@ -25,7 +24,6 @@ enum SIDEWALK_2_SW, SIDEWALK_2_SE, SIDEWALK_3_SW, - SIDEWALK_3_S, SIDEWALK_3_SE, SIDEWALK_4_C, @@ -49,7 +47,6 @@ enum ROOF1_2_NE, ROOF1_3_NW, ROOF1_3_N, - ROOF1_3_NE, ROOF1_4_N, ROOF1_1_W, @@ -58,7 +55,6 @@ enum ROOF1_2_SW, ROOF1_2_SE, ROOF1_3_SW, - ROOF1_3_S, ROOF1_3_SE, ROOF1_4_C, @@ -82,7 +78,6 @@ enum ROOF2_2_NE, ROOF2_3_NW, ROOF2_3_N, - ROOF2_3_NE, ROOF2_4_N, ROOF2_1_W, @@ -91,7 +86,6 @@ enum ROOF2_2_SW, ROOF2_2_SE, ROOF2_3_SW, - ROOF2_3_S, ROOF2_3_SE, ROOF2_4_C, @@ -105,7 +99,111 @@ enum ROOF2_4_S, ROOF2_START = ROOF2_1_NW, - ROOF2_END = ROOF2_4_S + ROOF2_END = ROOF2_4_S, + + /* PAVEMENT */ + PAVEMENT_CW_H_MID, + PAVEMENT_STR_MID_H_1, + PAVEMENT_CW_V_LEFT, + PAVEMENT_CW_V_MID, + PAVEMENT_CW_V_RIGHT, + PAVEMENT_RND_NW, + PAVEMENT_RND_NE, + PAVEMENT_SP_NW, + PAVEMENT_SP_NE, + PAVEMENT_1, + PAVEMENT_P, + PAVEMENT_CW_H_TOP, + PAVEMENT_STR_H_TOP, + + PAVEMENT_CW_H_DOWN, + PAVEMENT_STR_H_DOWN, + PAVEMENT_STR_V_LEFT, + PAVEMENT_STR_V_MID, + PAVEMENT_STR_V_RIGHT, + PAVEMENT_RND_SW, + PAVEMENT_RND_SE, + PAVEMENT_SP_SW, + PAVEMENT_SP_SE, + PAVEMENT_2, + PAVEMENT_BIKE, + PAVEMENT_PLUS, + PAVEMENT_EMPTY, + + PAVEMENT_START = PAVEMENT_CW_H_MID, + PAVEMENT_END = PAVEMENT_EMPTY, + + /* BUILDING1 */ + BUILDING1_1_N, + BUILDING1_2_NW, + BUILDING1_2_N, + BUILDING1_2_NE, + BUILDING1_3_NW, + BUILDING1_3_N, + BUILDING1_3_NE, + + BUILDING1_1_C_1, + BUILDING1_2_W_1, + BUILDING1_2_C_1, + BUILDING1_2_E_1, + BUILDING1_3_W_1, + BUILDING1_3_C_1, + BUILDING1_3_E_1, + + BUILDING1_1_C_2, + BUILDING1_2_W_2, + BUILDING1_2_C_2, + BUILDING1_2_E_2, + BUILDING1_3_W_2, + BUILDING1_3_C_2, + BUILDING1_3_E_2, + + BUILDING1_1_S, + BUILDING1_2_SW, + BUILDING1_2_S, + BUILDING1_2_SE, + BUILDING1_3_SW, + BUILDING1_3_S, + BUILDING1_3_SE, + + BUILDING1_START = BUILDING1_1_N, + BUILDING1_END = BUILDING1_2_SE, + + /* BUILDING2 */ + BUILDING2_1_N, + BUILDING2_2_NW, + BUILDING2_2_N, + BUILDING2_2_NE, + BUILDING2_3_NW, + BUILDING2_3_N, + BUILDING2_3_NE, + + BUILDING2_1_C_1, + BUILDING2_2_W_1, + BUILDING2_2_C_1, + BUILDING2_2_E_1, + BUILDING2_3_W_1, + BUILDING2_3_C_1, + BUILDING2_3_E_1, + + BUILDING2_1_C_2, + BUILDING2_2_W_2, + BUILDING2_2_C_2, + BUILDING2_2_E_2, + BUILDING2_3_W_2, + BUILDING2_3_C_2, + BUILDING2_3_E_2, + + BUILDING2_1_S, + BUILDING2_2_SW, + BUILDING2_2_S, + BUILDING2_2_SE, + BUILDING2_3_SW, + BUILDING2_3_S, + BUILDING2_3_SE, + + BUILDING2_START = BUILDING2_1_N, + BUILDING2_END = BUILDING2_3_SE }; enum @@ -119,7 +217,6 @@ enum GRASS_2_NW, GRASS_2_NE, GRASS_3_NW, - GRASS_3_N, GRASS_3_NE, GRASS_4_N, @@ -129,7 +226,6 @@ enum GRASS_2_SW, GRASS_2_SE, GRASS_3_SW, - GRASS_3_S, GRASS_3_SE, GRASS_4_C, diff --git a/src/terrain/src/init.c b/src/terrain/src/init.c index 88140d8..c16859c 100644 --- a/src/terrain/src/init.c +++ b/src/terrain/src/init.c @@ -133,6 +133,8 @@ int terrain_init(const char *const path, struct terrain_map *const map) FILE *const f = fopen(path, "rb"); unsigned w, h; + *map = (const struct terrain_map){0}; + if (!f) { fprintf(stderr, "%s: fopen(3): %s\n", __func__, strerror(errno)); diff --git a/src/terrain/src/render.c b/src/terrain/src/render.c index 8b35d95..bfa1e74 100644 --- a/src/terrain/src/render.c +++ b/src/terrain/src/render.c @@ -22,7 +22,7 @@ struct tile static int render_tile(const unsigned char id, const short x, const short y, const struct tile *const tiles, const size_t n) { - for (size_t i = 0; i < n / n; i++) + for (size_t i = 0; i < n; i++) { const struct tile *const rt = &tiles[i]; @@ -37,7 +37,8 @@ static int render_tile(const unsigned char id, const short x, } const unsigned char pos = id - rt->start; - const short tx = pos % TERRAIN_SZ, ty = pos / TERRAIN_SZ; + const short tx = pos % (s->w / TERRAIN_SZ), + ty = (pos * TERRAIN_SZ) / s->w; s->x = x; s->y = y; @@ -67,7 +68,10 @@ static int render_ground(const struct terrain_tile *const t, const short x, #define TILE(t) {.s = &terrain_sprites[t], .start = t##_START, .end = t##_END} TILE(SIDEWALK), TILE(ROOF1), - TILE(ROOF2) + TILE(ROOF2), + TILE(PAVEMENT), + TILE(BUILDING1), + TILE(BUILDING2) #undef TILE }; diff --git a/src/unit/inc/unit.h b/src/unit/inc/unit.h index 8d3e1bf..c9abafe 100644 --- a/src/unit/inc/unit.h +++ b/src/unit/inc/unit.h @@ -33,17 +33,14 @@ struct unit { struct instance instance; enum unit_type type; + const char *name; enum unit_dir { - UNIT_DIR_N, - UNIT_DIR_NE, - UNIT_DIR_E, - UNIT_DIR_SE, - UNIT_DIR_S, - UNIT_DIR_SW, UNIT_DIR_W, - UNIT_DIR_NW + UNIT_DIR_S, + UNIT_DIR_N, + UNIT_DIR_E } dir; enum unit_state state; @@ -61,7 +58,12 @@ UTIL_STATIC_ASSERT(!offsetof(struct unit, instance), "must be at offset zero"); struct unit_cfg { - enum unit_type type; + enum + { + UNIT_CFG_TYPE_WALKER, + UNIT_CFG_TYPE_CAR + } type; + unsigned long x, y; }; @@ -72,7 +74,6 @@ bool unit_target_valid(const struct unit *u, const struct unit_target *t); void unit_set_target(struct unit *u, const struct unit_target *t); void unit_move_to(struct unit *u, unsigned long x, unsigned long y); void unit_update(struct unit *u); -const char *unit_str(const struct unit *u); enum { @@ -82,6 +83,8 @@ enum UNIT_4_SPRITE, UNIT_5_SPRITE, UNIT_6_SPRITE, + UNIT_CAR_1_SPRITE, + UNIT_CAR_2_SPRITE, MAX_UNIT_SPRITES }; diff --git a/src/unit/inc/unit_type.h b/src/unit/inc/unit_type.h index f023784..ea59856 100644 --- a/src/unit/inc/unit_type.h +++ b/src/unit/inc/unit_type.h @@ -3,6 +3,15 @@ enum unit_type { + UNIT_TYPE_1, + UNIT_TYPE_2, + UNIT_TYPE_3, + UNIT_TYPE_4, + UNIT_TYPE_5, + UNIT_TYPE_6, + UNIT_TYPE_CAR_1, + UNIT_TYPE_CAR_2, + MAX_UNIT_TYPES }; diff --git a/src/unit/src/unit.c b/src/unit/src/unit.c index 1bb1e0f..43dcc86 100644 --- a/src/unit/src/unit.c +++ b/src/unit/src/unit.c @@ -11,7 +11,7 @@ struct sprite unit_sprites[MAX_UNIT_SPRITES]; struct sound unit_sounds[MAX_UNIT_SOUNDS]; -enum {N_FRAMES = 5}; +static const unsigned char anim[] = {0, 1, 0, 2}; static void move_unit(struct unit *const u, const fix16_t sx, const fix16_t sy) { @@ -21,38 +21,18 @@ static void move_unit(struct unit *const u, const fix16_t sx, const fix16_t sy) u->ry -= sy; break; - case UNIT_DIR_NE: - u->rx += sx; - u->ry -= sy; - break; - case UNIT_DIR_E: u->rx += sx; break; - case UNIT_DIR_SE: - u->rx += sx; - u->ry += sy; - break; - case UNIT_DIR_S: u->ry += sy; break; - case UNIT_DIR_SW: - u->rx -= sx; - u->ry += sy; - break; - case UNIT_DIR_W: u->rx -= sx; break; - case UNIT_DIR_NW: - u->rx -= sx; - u->ry -= sy; - break; - default: break; } @@ -61,17 +41,51 @@ static void move_unit(struct unit *const u, const fix16_t sx, const fix16_t sy) static void get_speed(const struct unit *const u, fix16_t *const x, fix16_t *const y) { - static const struct speed + struct speed { fix16_t x, y; - } speed[1]; + } s; + + switch (u->type) + { + case UNIT_TYPE_1: + case UNIT_TYPE_2: + case UNIT_TYPE_3: + case UNIT_TYPE_4: + case UNIT_TYPE_5: + case UNIT_TYPE_6: + { + static const struct speed ref = + { + .x = FIX16_C_FROM_FLOAT(0.4), + .y = FIX16_C_FROM_FLOAT(0.4) + }; + + s = ref; + } + break; + + case UNIT_TYPE_CAR_1: + case UNIT_TYPE_CAR_2: + { + static const struct speed ref = + { + .x = FIX16_C_FROM_FLOAT(1.5), + .y = FIX16_C_FROM_FLOAT(1.5) + }; + + s = ref; + } + + case MAX_UNIT_TYPES: + break; + } - const struct speed *const s = &speed[u->type]; const int dx = abs(u->rx - u->tx); const int dy = abs(u->ry - u->ty); - *x = dx < s->x ? dx : s->x; - *y = dy < s->y ? dy : s->y; + *x = dx < s.x ? dx : s.x; + *y = dy < s.y ? dy : s.y; } static enum unit_dir get_direction(const struct unit *const u) @@ -79,18 +93,7 @@ static enum unit_dir get_direction(const struct unit *const u) const fix16_t x = u->rx, y = u->ry, tx = u->tx, ty = u->ty; enum unit_dir dir = 0; - if (x != tx && y != ty) - { - if (x > tx && y > ty) - dir = UNIT_DIR_NW; - else if (x < tx && y > ty) - dir = UNIT_DIR_NE; - else if (x < tx && y < ty) - dir = UNIT_DIR_SE; - else - dir = UNIT_DIR_SW; - } - else if (x != tx) + if (x != tx) { if (x > tx) dir = UNIT_DIR_W; @@ -155,7 +158,7 @@ static bool must_move(const struct unit *const u) void unit_update(struct unit *const u) { - const struct instance *const i = &u->instance; + struct instance *const i = &u->instance; if (!i->alive) return; @@ -170,13 +173,13 @@ void unit_update(struct unit *const u) get_speed(u, &x_step, &y_step); move_unit(u, x_step, y_step); - enum {FRAME_RATE = 6}; + enum {FRAME_RATE = 10}; if (++u->frame.t >= FRAME_RATE) { u->frame.t = 0; - if (++u->frame.i >= N_FRAMES) + if (++u->frame.i >= sizeof anim / sizeof *anim) u->frame.i = 0; } @@ -185,8 +188,8 @@ void unit_update(struct unit *const u) else u->frame.i = 0; - u->instance.r.x = fix16_to_int(u->rx); - u->instance.r.y = fix16_to_int(u->ry); + i->r.x = fix16_to_int(u->rx); + i->r.y = fix16_to_int(u->ry); } void unit_set_target(struct unit *const u, const struct unit_target *const t) @@ -209,198 +212,101 @@ void unit_move_to(struct unit *const u, const unsigned long x, const unsigned lo u->ty = y > y_off ? fix16_from_int(y - y_off) : 0; } -static int get_ux(const struct unit *const u) +static void adjust_walker(const struct unit *const u, struct sprite *const s, + struct instance_render_off *const off) +{ + s->w = u->instance.r.w; + s->h = u->instance.r.h; + s->u += u->dir * s->w; + s->v += anim[u->frame.i] * s->h; + off->x = 0; + off->y = -2; +} + +static void adjust_car(const struct unit *const u, struct sprite *const s, + struct instance_render_off *const off) { switch (u->dir) { - case UNIT_DIR_N: - return 0; - - case UNIT_DIR_NE: - /* Fall through. */ - case UNIT_DIR_NW: - return 1; - - case UNIT_DIR_E: - /* Fall through. */ case UNIT_DIR_W: - return 2; - - case UNIT_DIR_SE: - /* Fall through. */ - case UNIT_DIR_SW: - return 3; + s->w = s->h = 32; + s->u += 32; + off->x = -5; + break; case UNIT_DIR_S: - return 4; + s->w = 16; + s->h = 32; + off->x = 2; + break; - default: + case UNIT_DIR_N: + s->u += 16; + s->w = 16; + s->h = 32; + off->x = 2; + break; + + case UNIT_DIR_E: + s->w = s->h = 32; + s->u += 64; + off->x = -5; break; } - return -1; + off->y = -10; } -typedef const struct +static void adjust_sprite(const struct unit *const u, struct sprite *const s, + struct instance_render_off *const off) { - const struct sprite *s; - char xo, x[N_FRAMES], w[N_FRAMES]; - short y; - short h; -} anim_dim; - -static anim_dim *peasant_anim(const struct unit *const u) -{ -#if 0 - static anim_dim t[] = + switch (u->type) { - { - .s = &unit_sprites[UNIT_SPRITE_N], - .xo = 5, - .x = {0, 1, 1, 2, 1}, - .w = {25, 22, 24, 22, 24}, - .y = 2, - .h = 31 - }, - - { - .s = &unit_sprites[UNIT_SPRITE_NE], - .xo = 11, - .x = {0, -4, -1, -4, -2}, - .w = {18, 26, 22, 23, 20}, - .y = 2, - .h = 31 - }, - - { - .s = &unit_sprites[UNIT_SPRITE_E], - .xo = 10, - .x = {0, -6, -1, -6, -3}, - .w = {14, 26, 17, 24, 19}, - .y = 2, - .h = 33 - }, - - { - .s = &unit_sprites[UNIT_SPRITE_SE], - .xo = 6, - .x = {0, 1, 2, 0, 0}, - .w = {20, 22, 18, 21, 21}, - .y = 2, - .h = 31 - }, - - { - .s = &unit_sprites[UNIT_SPRITE_S], - .xo = 7, - .x = {0, 1, 0, 0, 0}, - .w = {24, 23, 24, 23, 24}, - .y = 2, - .h = 33 - } - }; - - const int ux = get_ux(u); - - if (ux < 0) - return NULL; - - return &t[ux]; -#else - return NULL; -#endif -} - -struct render_cfg -{ - struct instance_render_off off; - struct instance_render_quad qcfg; -}; - -static anim_dim *peasant_quad(const struct unit *const u) -{ - return peasant_anim(u); -} - -static void adjust_quad(const struct unit *const u, anim_dim *const dim, - struct render_cfg *const rcfg) -{ - const unsigned char n = u->frame.i; - short u_off = 0; - - for (unsigned char i = 0; i < n; i++) - u_off += dim->w[i]; - - struct instance_render_quad *const qcfg = &rcfg->qcfg; - - qcfg->u = u_off; - qcfg->w = dim->w[n]; - qcfg->h = dim->h; - - struct instance_render_off *const off = &rcfg->off; - - off->x = dim->xo; - off->y = dim->y; - - switch (u->dir) - { - case UNIT_DIR_SW: - /* Fall through. */ - case UNIT_DIR_W: - /* Fall through. */ - case UNIT_DIR_NW: - qcfg->xflip = true; - off->x += dim->x[n]; + case UNIT_TYPE_1: + case UNIT_TYPE_2: + case UNIT_TYPE_3: + case UNIT_TYPE_4: + case UNIT_TYPE_5: + case UNIT_TYPE_6: + adjust_walker(u, s, off); break; - default: - qcfg->xflip = false; - off->x += dim->x[n]; + case UNIT_TYPE_CAR_1: + case UNIT_TYPE_CAR_2: + adjust_car(u, s, off); + break; + + case MAX_UNIT_TYPES: break; } } -static int unit_quad(const struct unit *const u, struct render_cfg *const rcfg) -{ - struct instance_render_quad *const qcfg = &rcfg->qcfg; - - static anim_dim *(*const f[1])(const struct unit *); - - anim_dim *const dim = f[u->type](u); - - if (!dim) - return -1; - - adjust_quad(u, dim, rcfg); - - if (quad_from_sprite(dim->s, qcfg->q)) - return -1; - - return 0; -} - int unit_render(const struct unit *const u, const struct camera *const cam, const bool sel) { if (!u->instance.alive) return 0; - struct render_cfg rcfg; + sprite_get_or_ret(s, -1); - quad_get_or_ret(q, -1); - rcfg.qcfg.q = q; + struct instance_render_off off; - if (unit_quad(u, &rcfg)) + if (sprite_clone(&unit_sprites[u->type], s)) + { + fprintf(stderr, "%s: sprite_clone failed\n", __func__); return -1; + } + + adjust_sprite(u, s, &off); const struct instance_render_cfg cfg = { .i = &u->instance, - .prim_type = INSTANCE_RENDER_CFG_QUAD, - .prim = {.quad = &rcfg.qcfg}, + .prim_type = INSTANCE_RENDER_CFG_SPRITE, + .prim.s = s, + .off = &off, .cam = cam, - .sel = sel, - .off = &rcfg.off + .sel = sel }; return instance_render(&cfg); @@ -409,40 +315,159 @@ int unit_render(const struct unit *const u, const struct camera *const cam, static void get_dimensions(const enum unit_type type, short *const w, short *const h) { - static const struct dim + switch (type) { - short w, h; - } dim[1]; + case UNIT_TYPE_1: + case UNIT_TYPE_2: + case UNIT_TYPE_3: + case UNIT_TYPE_4: + case UNIT_TYPE_5: + case UNIT_TYPE_6: + *w = *h = 16; + break; - const struct dim *const d = &dim[type]; - *w = d->w; - *h = d->h; + case UNIT_TYPE_CAR_1: + case UNIT_TYPE_CAR_2: + *w = *h = 22; + break; + + case MAX_UNIT_TYPES: + break; + } +} + +static const char *get_walker_name(const enum unit_type type) +{ + enum {FEMALE, MALE} gender = 0; + + switch (type) + { + case UNIT_TYPE_2: + case UNIT_TYPE_5: + gender = FEMALE; + break; + + case UNIT_TYPE_1: + case UNIT_TYPE_3: + case UNIT_TYPE_4: + case UNIT_TYPE_6: + gender = MALE; + break; + + default: + return NULL; + } + + static const char *const female[] = + { + "Amelia", + "Asher", + "Aurora", + "Ava", + "Charlotte", + "Dana", + "Ellie", + "Emma", + "Ezra", + "Haley", + "Harper", + "Isabella", + "Luna", + "Mire", + "Olivia", + "Sophia", + }; + + static const char *const male[] = + { + "Oliver", + "Xavi", + "Benjamin", + "Elijah", + "Ethan", + "Jack", + "James", + "Jan", + "Kyte", + "Leo", + "Levi", + "Liam", + "Luca", + "Lucas", + "Michael", + "Noah", + }; + + switch (gender) + { + case FEMALE: + { + const size_t i = rand() % (sizeof female / sizeof *female); + + return female[i]; + } + + case MALE: + { + const size_t i = rand() % (sizeof male / sizeof *male); + + return male[i]; + } + } + + return NULL; +} + +static const char *get_name(const enum unit_type type) +{ + switch (type) + { + case UNIT_TYPE_1: + case UNIT_TYPE_2: + case UNIT_TYPE_3: + case UNIT_TYPE_4: + case UNIT_TYPE_5: + case UNIT_TYPE_6: + return get_walker_name(type); + + case UNIT_TYPE_CAR_1: + case UNIT_TYPE_CAR_2: + return "Car"; + + case MAX_UNIT_TYPES: + break; + } + + return NULL; } void unit_create(const struct unit_cfg *const cfg, struct unit *const u) { struct instance *const i = &u->instance; + enum unit_type type = 0; + + switch (cfg->type) + { + case UNIT_CFG_TYPE_WALKER: + type = UNIT_TYPE_1 + (rand() % (UNIT_TYPE_6 + 1)); + break; + + case UNIT_CFG_TYPE_CAR: + type = UNIT_TYPE_CAR_1 + (rand() + % (UNIT_TYPE_CAR_2 - UNIT_TYPE_CAR_1 + 1)); + break; + } *u = (const struct unit) { - .instance = - { - .alive = true, - }, - - .type = cfg->type, + .instance.alive = true, .dir = UNIT_DIR_S, .rx = fix16_from_int(cfg->x), - .ry = fix16_from_int(cfg->y) + .ry = fix16_from_int(cfg->y), + .type = type, + .name = get_name(type) }; - get_dimensions(cfg->type, &i->r.w, &i->r.h); + get_dimensions(u->type, &i->r.w, &i->r.h); unit_stop(u); } - -const char *unit_str(const struct unit *const u) -{ - static const char *const str[1]; - - return str[u->type]; -}