From 8235df7752c301f9ba08e64e2c3011d84d61ffaf Mon Sep 17 00:00:00 2001 From: Jupeyy Date: Fri, 18 Sep 2020 18:45:42 +0200 Subject: [PATCH 1/5] Add menu background map --- CMakeLists.txt | 15 + data/themes/auto.png | Bin 0 -> 10354 bytes data/themes/heavens.png | Bin 0 -> 3360 bytes data/themes/heavens_day.map | Bin 0 -> 5187 bytes data/themes/heavens_night.map | Bin 0 -> 4537 bytes data/themes/jungle.png | Bin 0 -> 3070 bytes data/themes/jungle_day.map | Bin 0 -> 3707 bytes data/themes/jungle_night.map | Bin 0 -> 3703 bytes data/themes/none.png | Bin 0 -> 989 bytes data/themes/rand.png | Bin 0 -> 8235 bytes data/themes/winter.png | Bin 0 -> 5561 bytes data/themes/winter_day.map | Bin 0 -> 7057 bytes data/themes/winter_night.map | Bin 0 -> 7045 bytes src/base/system.c | 40 ++ src/base/system.h | 26 ++ src/base/vmath.h | 11 + src/engine/shared/config_variables.h | 7 + src/engine/shared/map.cpp | 118 +++--- src/engine/shared/map.h | 43 ++ src/game/client/components/background.cpp | 16 +- src/game/client/components/background.h | 15 +- src/game/client/components/camera.h | 4 +- src/game/client/components/mapimages.h | 1 + src/game/client/components/maplayers.cpp | 115 +++--- src/game/client/components/maplayers.h | 13 +- .../client/components/menu_background.cpp | 368 ++++++++++++++++++ src/game/client/components/menu_background.h | 110 ++++++ src/game/client/components/menus.cpp | 112 +++++- src/game/client/components/menus.h | 5 + src/game/client/components/menus_settings.cpp | 44 ++- src/game/client/gameclient.cpp | 26 +- src/game/client/gameclient.h | 3 + 32 files changed, 976 insertions(+), 116 deletions(-) create mode 100644 data/themes/auto.png create mode 100644 data/themes/heavens.png create mode 100644 data/themes/heavens_day.map create mode 100644 data/themes/heavens_night.map create mode 100644 data/themes/jungle.png create mode 100644 data/themes/jungle_day.map create mode 100644 data/themes/jungle_night.map create mode 100644 data/themes/none.png create mode 100644 data/themes/rand.png create mode 100644 data/themes/winter.png create mode 100644 data/themes/winter_day.map create mode 100644 data/themes/winter_night.map create mode 100644 src/engine/shared/map.h create mode 100644 src/game/client/components/menu_background.cpp create mode 100644 src/game/client/components/menu_background.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 50e88beb8..e0cdf738f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1279,6 +1279,18 @@ set(EXPECTED_DATA skins/whis.png skins/x_ninja.png skins/x_spec.png + themes/auto.png + themes/heavens.png + themes/heavens_day.map + themes/heavens_night.map + themes/jungle.png + themes/jungle_day.map + themes/jungle_night.map + themes/none.png + themes/rand.png + themes/winter.png + themes/winter_day.map + themes/winter_night.map wordlist.txt ) @@ -1481,6 +1493,7 @@ set_src(ENGINE_SHARED GLOB src/engine/shared linereader.cpp linereader.h map.cpp + map.h masterserver.cpp memheap.cpp memheap.h @@ -1688,6 +1701,8 @@ if(CLIENT) components/maplayers.h components/mapsounds.cpp components/mapsounds.h + components/menu_background.cpp + components/menu_background.h components/menus.cpp components/menus.h components/menus_browser.cpp diff --git a/data/themes/auto.png b/data/themes/auto.png new file mode 100644 index 0000000000000000000000000000000000000000..a63f6bb0aa83f12b51b2615dade4b08fb1dda713 GIT binary patch literal 10354 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 literal 0 HcmV?d00001 diff --git a/data/themes/heavens_night.map b/data/themes/heavens_night.map new file mode 100644 index 0000000000000000000000000000000000000000..3f2fa2895aadd45f031d76da01302c8380f16515 GIT binary patch literal 4537 zcmd5=dr(wW7(aLKvY@-b%0m&z#XwjCl>|{s-Ni>5=0IsiqmwJBK;a{wYlE^XGFtea zM#^n8$JELhv2?P`0bL(7_#A8UIiiE6lST@T43EA2zI*rD^@_IpSDu;Qo^!wR{l4#a zzH|26h2iPr(zT4SuRAf;7{piyj1vI^kRQm{J`Dz*#-Ue&rU=C60UZ$Ld5-iv`=O5k z0zA)V^c2G_FxJyE7BGIvGe#%oPD1|%PzaO(yMS9j9LP4n37iMQARr4U1F8Wngjj(h zU_a0ZBtu{!uoI{QVjyZFumz|C%n)7(Q~-@YoIhjZfD&LYPzQuz0d`;~kc_%y0n|c( zI3Nue29VaHKq9o|16P4~=o$fZgk1*GvT_fS;X`A&H^)k2n8ey*8jWKS;wNK5JB@Zi zo)?RabxJ(RpL@zY`A|5GavoefihOk9Jg=Vj#7B9>c{%~95=}e{7&2O;;~9-6DL<#+ zQflH++-Fc7GFPMGVtYusS6p7frF^tE-g31HE@?IZ-fH$!af5xxt5a|(AHKF;YxY-h zLw(=|sJP)ia62ftRI4t4x3%i1;?lk1?H=hBT*?>i1J|J7lICuJx0(Z0-0nW)4N`C^ zU#t(@Un_W-=rY*ca0KIHAB;8H%i%e~#B5EVDc2X3f}+uH{&-K>M)PkP&H^4+PP zlkX(y{&_M+R}cu&z4kcUf%k|N?-ykZO*=YB7lCR>Xs;<_@X8pt%TEAwUI}y#)G=fo z59;r@zTeVNM}oA<7@mYv&=Vk8T#v{6Sa;*@wd16PV)!XzK*O(YL6Fyir9Tnl2z;m> zq+_o~2i^X3_WI<{oG$MT>8E@UAZl>Qo(KinVHSzf2o zpMQ!!<)JlEQ~GOF{<0p@MDHeQN`Jqn_!EzQi&3xi*TH`xY*Zh4U#U)gfnEUlNctR~Ya2iA zrnGkhcL$1h@Nh{_>h{}G%n25~XdeN4d_p|8?N4bPBZpoWq7Wt%c4Mc=h~bwwaeY(g zb!0EX9tXQW-;uUWJR7mlkN|W8ro+|)KSoKG(!L7MkqJ`#E|}B-LBK57sZssZxP=0% zZS+h{?xiQjX0tg=)+yWWec{J?vt;p6t>=H$xku8UF=M1G^^s2Xy0`$%56v)=ooYDX zTaLYhUK>_QKLwtsgSLY%yuCVTGTM%j|MOA@%V@K$J)J?f`^|iwbQZ7=+C5hVYzE1E zZt6+re`~4qJv}nTBx<7%`TVQT75N`a(}?Hi&cg2h>AwR3E^N?>{+X74)AS+h2e9P{o=h+-f0q&&nGvP9GWd zvA}bq0$!_JU7K?zGk0?JkSczAdh5fKcMlaA+ZucJUpB0J;>jyL4BN`rUG`(29Z7#3 zSw3=A)n-?_{+??}DNobf&%1KnuOWTz0&}Qq!rSkaE;1NqwVGCrNs^Y9WC(8#*2YA# z`KMmc+npO0H(e7xwd-^>6DC#dOLu41cF zDy#)YTe@xX&d-IcAJ-qK7fj9f9~Nia&r1%xUVqVTI^loz*jS6Z@~!*zmaqQGDY;lv zy|g0g=62zPaY3*A+>#oO#U7mUrrmj|UxP~+y!3=2$ZgI2a zT*>muCZ3NLM&^XpSd!5Y5~}GNJg@K4-yGZ6wyEaJcIVwgTp*6m;Vlm{ zrw9Afe>%k08Wn41oZWfAUDqItOe!?g1Q+?8`+Z64*v&Dho(vC26!-2BaD`Mvi| V5(YkSx9-??pyVueqFGnC`ya;h#cTio literal 0 HcmV?d00001 diff --git a/data/themes/jungle.png b/data/themes/jungle.png new file mode 100644 index 0000000000000000000000000000000000000000..c9a7bb8974d6532aaa4c13f074d0213765ea1b85 GIT binary patch literal 3070 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 literal 0 HcmV?d00001 diff --git a/data/themes/jungle_night.map b/data/themes/jungle_night.map new file mode 100644 index 0000000000000000000000000000000000000000..d8b09f21c3d9495d5482e4d50d435711bada68fe GIT binary patch literal 3703 zcma);3p~_W8^`~X`=xQ~LhKllONu78iye2GL=?T7mE@9imokioW^83t?zHI*mDp5j z8*<4dGK>_>hz;?UGSy(bieb`B<~>JdceYRMyU*wIbH`qqb!0T zVQ2*TAcr7|psxc^1=NE;ICRV!3bfM90b__f0BXQg*atEQkelhl@jL*WH!Vhx`Jj~n zh(TX_)(@JQ^_GFw1F#>E1Skfy0(gKGKp+xO2@nAsz``d0cK{r~JRnK}^Z^{eX4V6C z0}=s60BBl(Pq z^5NZw^QH4;K)yfl!M#XyVSgoH82}ob2k#mDMt~P<_Wk;Nmz2QxHE*y}vR^R#!>F@8 z*}qxCd^QKxGIy3Q*MRTa|64=ui#4FEqz?E!fpyR5O1Crj)21q zakt#C%p!%gv9&b>L39;mmymKEEp2mWxg~pT@ObQL`Ovb>JqTPbO$E6>BP}d1HxIL2 z2!ivHWBlQs6~U^>p8nI<=HVvMusT8-j9mKs;a74folRCL!94>#ewGi)=0uJ6E9NE zky`$1ajkB#s%3%f&E#y^-cAmobV~bk?GuyXf0n zBF_7p&+ljdc9(F1rgpFmUn4(?@jrxZ3_?8H@Clt5D#h*7yUu6cSIaa9R$QJ|bYd*t z|9jX?(W`eI-6M_y+7_V*;-X18-V5vQCB9HSi7HB(k zdpgFfwA|ZA1%t-O=rv^E_wzY(X&WnQK6&zn`G~_G{P154|a43XptlHb77K%S(6`RKtuC%^2CFL}AzxC2}Lzpk=$s2Kr z&mHrl3yiYS-rViV_qCnUsaZE5`qZpycdfLjbCVU%!{>)*7l%c4H71Ad86QTYLMmHUcajop{>w?ni9}WCMq3%JyUrCJ*n?xQpHZj@blF^;lq&Q0YTM2{ovP3 zs9+WkZ;O6`n@T-oI#Fck^ZnjU?oVwxub`55J6ZXWYUUr<9nIa`lD!3M@)1A$f%}{s zn(FaJzKTuFw>Frwhu&-<|CSS`9Za7klj{ zVmD9t8VY5r+7p9q3YH$#ZXT;w(f95rAlKGA+pJV~F)q<#GWG~FF_ix3i_@iS5&1kX zlk2Fpft&X0kbx)j#mF0LW6xd|N33N3F~>gSxAZvW+TH8SzI*b$Z7VLKH11KhNPXU` z)uQ9#pXnESuE&%)P43}eJ}C-)z@AuhWrSQJK3(@doE_t-^J9zs@naZrq+vu}>(`#DV^f@$-)!=@-SP>`xODF$ELq2oO_<(O+|6glrNkC6#*gsQJ*T~` zGiw+6ton|3H1-ms6u8#WG_BL?6f%9EM$)SvA7zzwcL47OTCjCSt*%x?WSTyiKr?yU zz1V?fXq{H4GJv)%9)B3iE2moy#KlLPUb!@sx?RPy$ov+lkJ4k$Uw=+3|{DGU6>Q@pSD60~| zPa|H|wdK0%e_YE%66V=-Gw{H!C*?><}X@^b4i`z zb&C!%8@YERFY$ztV1=jY+M)(If9CwYhB*AM9T)Zs(PP<3d-Zhd_Vlv_Bk5`bmAk6l zXk^lfF30F$2CrZ!!eKg&x8xE5-#fSDMU!*Q6F!@`EhF1DYAUejG9xO3tQ}HDJFvgs zrf0Mtb!4b;SHR%COl#jN?Q$;Njh1XASYs%(i@JS&LG>+SotYmwa_{51EA4it{7sl% z!OX2uAzOKVA0j*^Wq5}*=x6uX(|GrE7YQ!B-EqV-c}Y+%2fHxl0Rg3a;7!$#Kz5iI zs~GfXAE(Sf;MQq#%?VtFN5_UY{q~?pxPw@GLwHOxC4+3VH`l-3)!&K0ujO@ee!rq%=xT7Kc_R8BAIwX$;1d>?(^&>xx{j`O9?qaN&^mgN9|; zXuGkrGkWK2Zw2PX`8PR5QqFjL{wMs&*e8Q?TY5G!?-t}?h()e*r*3Qx?O^1%A6_t( zv$JiG|HIi{%yo;g_cks1PP7+?ZFQ2CP{N51!w7j{@A>SuwG8bk0`8UgkTE^h zyLn#t9hC6jbA4|9lzXektAnwp)wskf)=)r*ttZ>u8<>oG$9eCfXDLb+vQxH}lTX>a j5j)(fNCp1}@1x+4u7*njuLEid@b}$}iF6m6BB=iX;j$qD literal 0 HcmV?d00001 diff --git a/data/themes/none.png b/data/themes/none.png new file mode 100644 index 0000000000000000000000000000000000000000..e726eb265650edf35eea18f71a69334087f45011 GIT binary patch literal 989 zcmV<310wv1P)U4RYR>udh(LucTP-N^EXCA?JQ^e2$s?o)lYWv)FpJ zMv6T;ItnI0qqhJjJpcvR7r(xrkyo z4ND>~KthxxfDl?vKIR3GoX8lqAM*m(y%N_kZu`r_0@+@h6ivm9Fp^P zduv!-q6zTrzQ*PG8*=XXrN>z5wMntpU#9r@{*0D5pa6~D0z|JLmFzx^7C=oE1ZlVc zJYvu%0s&$ugBl_Ay0XgsRY=oQf1u53$ZC38% zlPgR{v=>wJvP;gLW#QJX`7;0uWnNQ=L=Hoj|zBuO3%Ig=qVQFXj6Fi-Q(TGIVm=z0Oq#mPvtMvI_j*yaT=dlR6<0P_MQcr;o7C5up$Mhn0u0)xy85J3$@F)u(AkL3tr zUjPo0|289+`VX2d029``flAI?<^|9(jdlsv44O`-*x%nL#ZD#@a^Bg_DcU8?^Ak^U!{|WP3K!V3lwMv{*Isy}l00000 LNkvXXu0mjf--WU@ literal 0 HcmV?d00001 diff --git a/data/themes/rand.png b/data/themes/rand.png new file mode 100644 index 0000000000000000000000000000000000000000..c09bbd94c9e38f6489766caaf5ebe41228138e14 GIT binary patch literal 8235 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 literal 0 HcmV?d00001 diff --git a/data/themes/winter.png b/data/themes/winter.png new file mode 100644 index 0000000000000000000000000000000000000000..9746dc6a643215c90cb86b109d0ac5db58ef8384 GIT binary patch literal 5561 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 Yr2NC-noz>vZ(^})Ggl$;(XZ_P1Nt%)1poj5 literal 0 HcmV?d00001 diff --git a/data/themes/winter_night.map b/data/themes/winter_night.map new file mode 100644 index 0000000000000000000000000000000000000000..550cc234ddb7e057c46249c55434bbe25936b282 GIT binary patch literal 7045 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 literal 0 HcmV?d00001 diff --git a/src/base/system.c b/src/base/system.c index 7314e923e..48d693c90 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -2267,6 +2267,46 @@ int time_timestamp(void) return time(0); } +int time_houroftheday(void) +{ + time_t time_data; + struct tm *time_info; + + time(&time_data); + time_info = localtime(&time_data); + return time_info->tm_hour; +} + +int time_season(void) +{ + time_t time_data; + struct tm *time_info; + + time(&time_data); + time_info = localtime(&time_data); + + switch(time_info->tm_mon) + { + case 11: + case 0: + case 1: + return SEASON_WINTER; + case 2: + case 3: + case 4: + return SEASON_SPRING; + case 5: + case 6: + case 7: + return SEASON_SUMMER; + case 8: + case 9: + case 10: + return SEASON_AUTUMN; + } + return SEASON_SPRING; // should never happen +} + void str_append(char *dst, const char *src, int dst_size) { int s = strlen(dst); diff --git a/src/base/system.h b/src/base/system.h index 8bb9dd5e7..a59301ae0 100644 --- a/src/base/system.h +++ b/src/base/system.h @@ -617,6 +617,32 @@ int64 time_freq(void); */ int time_timestamp(void); +/* + Function: time_houroftheday + Retrieves the hours since midnight (0..23) + + Returns: + The current hour of the day +*/ +int time_houroftheday(void); + +enum +{ + SEASON_SPRING = 0, + SEASON_SUMMER, + SEASON_AUTUMN, + SEASON_WINTER +}; + +/* + Function: time_season + Retrieves the current season of the year. + + Returns: + one of the SEASON_* enum literals +*/ +int time_season(void); + /* Function: time_get_microseconds Fetches a sample from a high resolution timer and converts it in microseconds. diff --git a/src/base/vmath.h b/src/base/vmath.h index 06862da55..64a51e88c 100644 --- a/src/base/vmath.h +++ b/src/base/vmath.h @@ -5,6 +5,8 @@ #include +#include "math.h" + // ------------------------------------ template @@ -132,6 +134,15 @@ inline T length(const vector3_base &a) return sqrtf(a.x*a.x + a.y*a.y + a.z*a.z); } +template +inline vector2_base rotate(const vector2_base &a, float angle) +{ + angle = angle * pi / 180.0f; + float s = sinf(angle); + float c = cosf(angle); + return vector2_base((T)(c * a.x - s * a.y), (T)(s * a.x + c * a.y)); +} + template inline T distance(const vector3_base &a, const vector3_base &b) { diff --git a/src/engine/shared/config_variables.h b/src/engine/shared/config_variables.h index 73683a33d..6dd16f471 100644 --- a/src/engine/shared/config_variables.h +++ b/src/engine/shared/config_variables.h @@ -295,6 +295,13 @@ MACRO_CONFIG_INT(ClZoomBackgroundLayers, cl_zoom_background_layers, 0, 0, 1, CFG MACRO_CONFIG_COL(ClBackgroundColor, cl_background_color, 128, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Background color") //0 0 128 MACRO_CONFIG_COL(ClBackgroundEntitiesColor, cl_background_entities_color, 128, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Background (entities) color") //0 0 128 MACRO_CONFIG_STR(ClBackgroundEntities, cl_background_entities, 100, "", CFGFLAG_CLIENT | CFGFLAG_SAVE, "Background (entities)") + +// menu background map +MACRO_CONFIG_STR(ClMenuMap, cl_menu_map, 100, "auto", CFGFLAG_CLIENT | CFGFLAG_SAVE, "Background map in the menu") +MACRO_CONFIG_INT(ClRotationRadius, cl_rotation_radius, 30, 1, 500, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Menu camera rotation radius") +MACRO_CONFIG_INT(ClRotationSpeed, cl_rotation_speed, 40, 1, 120, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Menu camera rotations in seconds") +MACRO_CONFIG_INT(ClCameraSpeed, cl_camera_speed, 5, 1, 40, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Menu camera speed") + MACRO_CONFIG_INT(ClBackgroundShowTilesLayers, cl_background_show_tiles_layers, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Whether draw tiles layers when using custom background (entities)") MACRO_CONFIG_INT(SvShowOthers, sv_show_others, 1, 0, 1, CFGFLAG_SERVER, "Whether players can use the command showothers or not") MACRO_CONFIG_INT(SvShowOthersDefault, sv_show_others_default, 0, 0, 2, CFGFLAG_SERVER, "Whether players see others by default (2 for own team)") diff --git a/src/engine/shared/map.cpp b/src/engine/shared/map.cpp index a6da6c98e..ff6ac5e1a 100644 --- a/src/engine/shared/map.cpp +++ b/src/engine/shared/map.cpp @@ -1,63 +1,85 @@ /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ /* If you are missing that file, acquire a complete release at teeworlds.com. */ -#include -#include +#include "map.h" #include -#include "datafile.h" -class CMap : public IEngineMap +CMap::CMap() { - CDataFileReader m_DataFile; -public: - CMap() {} +} - virtual void *GetData(int Index) { return m_DataFile.GetData(Index); } - virtual int GetDataSize(int Index) { return m_DataFile.GetDataSize(Index); } - virtual void *GetDataSwapped(int Index) { return m_DataFile.GetDataSwapped(Index); } - virtual void UnloadData(int Index) { m_DataFile.UnloadData(Index); } - virtual void *GetItem(int Index, int *pType, int *pID) { return m_DataFile.GetItem(Index, pType, pID); } - virtual int GetItemSize(int Index) { return m_DataFile.GetItemSize(Index); } - virtual void GetType(int Type, int *pStart, int *pNum) { m_DataFile.GetType(Type, pStart, pNum); } - virtual void *FindItem(int Type, int ID) { return m_DataFile.FindItem(Type, ID); } - virtual int NumItems() { return m_DataFile.NumItems(); } +void *CMap::GetData(int Index) +{ + return m_DataFile.GetData(Index); +} +int CMap::GetDataSize(int Index) +{ + return m_DataFile.GetDataSize(Index); +} +void *CMap::GetDataSwapped(int Index) +{ + return m_DataFile.GetDataSwapped(Index); +} +void CMap::UnloadData(int Index) +{ + m_DataFile.UnloadData(Index); +} +void *CMap::GetItem(int Index, int *pType, int *pID) +{ + return m_DataFile.GetItem(Index, pType, pID); +} +int CMap::GetItemSize(int Index) +{ + return m_DataFile.GetItemSize(Index); +} +void CMap::GetType(int Type, int *pStart, int *pNum) +{ + m_DataFile.GetType(Type, pStart, pNum); +} +void *CMap::FindItem(int Type, int ID) +{ + return m_DataFile.FindItem(Type, ID); +} +int CMap::NumItems() +{ + return m_DataFile.NumItems(); +} - virtual void Unload() - { - m_DataFile.Close(); - } +void CMap::Unload() +{ + m_DataFile.Close(); +} - virtual bool Load(const char *pMapName) - { - IStorage *pStorage = Kernel()->RequestInterface(); - if(!pStorage) - return false; - return m_DataFile.Open(pStorage, pMapName, IStorage::TYPE_ALL); - } +bool CMap::Load(const char *pMapName) +{ + IStorage *pStorage = Kernel()->RequestInterface(); + if(!pStorage) + return false; + return m_DataFile.Open(pStorage, pMapName, IStorage::TYPE_ALL); +} - virtual bool IsLoaded() - { - return m_DataFile.IsOpen(); - } +bool CMap::IsLoaded() +{ + return m_DataFile.IsOpen(); +} - virtual SHA256_DIGEST Sha256() - { - return m_DataFile.Sha256(); - } +SHA256_DIGEST CMap::Sha256() +{ + return m_DataFile.Sha256(); +} - virtual unsigned Crc() - { - return m_DataFile.Crc(); - } +unsigned CMap::Crc() +{ + return m_DataFile.Crc(); +} - virtual int MapSize() - { - return m_DataFile.MapSize(); - } +int CMap::MapSize() +{ + return m_DataFile.MapSize(); +} - virtual IOHANDLE File() - { - return m_DataFile.File(); - } -}; +IOHANDLE CMap::File() +{ + return m_DataFile.File(); +} extern IEngineMap *CreateEngineMap() { return new CMap; } diff --git a/src/engine/shared/map.h b/src/engine/shared/map.h new file mode 100644 index 000000000..ed6000ff3 --- /dev/null +++ b/src/engine/shared/map.h @@ -0,0 +1,43 @@ +/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ +/* If you are missing that file, acquire a complete release at teeworlds.com. */ +#ifndef ENGINE_SHARED_MAP_H +#define ENGINE_SHARED_MAP_H + +#include + +#include "datafile.h" +#include + +class CMap : public IEngineMap +{ + CDataFileReader m_DataFile; + +public: + CMap(); + + virtual void *GetData(int Index); + virtual int GetDataSize(int Index); + virtual void *GetDataSwapped(int Index); + virtual void UnloadData(int Index); + virtual void *GetItem(int Index, int *pType, int *pID); + virtual int GetItemSize(int Index); + virtual void GetType(int Type, int *pStart, int *pNum); + virtual void *FindItem(int Type, int ID); + virtual int NumItems(); + + virtual void Unload(); + + virtual bool Load(const char *pMapName); + + virtual bool IsLoaded(); + + virtual SHA256_DIGEST Sha256(); + + virtual unsigned Crc(); + + virtual int MapSize(); + + virtual IOHANDLE File(); +}; + +#endif diff --git a/src/game/client/components/background.cpp b/src/game/client/components/background.cpp index 40282a30b..7604af63c 100644 --- a/src/game/client/components/background.cpp +++ b/src/game/client/components/background.cpp @@ -10,14 +10,15 @@ #include "background.h" -CBackground::CBackground() : CMapLayers(CMapLayers::TYPE_BACKGROUND_FORCE) +CBackground::CBackground(int MapType, bool OnlineOnly) + : CMapLayers(MapType, OnlineOnly) { m_pLayers = new CLayers; m_pBackgroundLayers = m_pLayers; m_pImages = new CMapImages; m_pBackgroundImages = m_pImages; - m_pMap = CreateEngineMap(); - m_pBackgroundMap = m_pMap; + m_pBackgroundMap = CreateBGMap(); + m_pMap = m_pBackgroundMap; m_Loaded = false; m_aMapName[0] = '\0'; m_LastLoad = 0; @@ -29,10 +30,15 @@ CBackground::~CBackground() delete m_pBackgroundImages; } +CBackgroundEngineMap *CBackground::CreateBGMap() +{ + return new CBackgroundEngineMap; +} + void CBackground::OnInit() { m_pImages->m_pClient = GameClient(); - Kernel()->ReregisterInterface(m_pMap); + Kernel()->RegisterInterface(m_pBackgroundMap); if(g_Config.m_ClBackgroundEntities[0] != '\0' && str_comp(g_Config.m_ClBackgroundEntities, CURRENT)) LoadBackground(); } @@ -72,7 +78,7 @@ void CBackground::LoadBackground() m_Loaded = true; } } - + if(m_Loaded) { CMapLayers::OnMapLoad(); diff --git a/src/game/client/components/background.h b/src/game/client/components/background.h index ceca72397..941e09c4f 100644 --- a/src/game/client/components/background.h +++ b/src/game/client/components/background.h @@ -1,13 +1,20 @@ #ifndef GAME_CLIENT_COMPONENTS_BACKGROUND_H #define GAME_CLIENT_COMPONENTS_BACKGROUND_H +#include #include #include // Special value to use background of current map #define CURRENT "%current%" +class CBackgroundEngineMap : public CMap +{ + MACRO_INTERFACE("background_enginemap", 0) +}; + class CBackground : public CMapLayers { +protected: IEngineMap *m_pMap; bool m_Loaded; char m_aMapName[MAX_MAP_LENGTH]; @@ -16,13 +23,15 @@ class CBackground : public CMapLayers int64 m_LastLoad; //to avoid memory leak when switching to %current% - IEngineMap *m_pBackgroundMap; + CBackgroundEngineMap *m_pBackgroundMap; CLayers *m_pBackgroundLayers; CMapImages *m_pBackgroundImages; + virtual CBackgroundEngineMap *CreateBGMap(); + public: - CBackground(); - ~CBackground(); + CBackground(int MapType = CMapLayers::TYPE_BACKGROUND_FORCE, bool OnlineOnly = true); + virtual ~CBackground(); virtual void OnInit(); virtual void OnMapLoad(); diff --git a/src/game/client/components/camera.h b/src/game/client/components/camera.h index 4968f5301..927567b7d 100644 --- a/src/game/client/components/camera.h +++ b/src/game/client/components/camera.h @@ -8,9 +8,11 @@ class CCamera : public CComponent { + friend class CMenuBackground; + enum { - CAMTYPE_UNDEFINED=-1, + CAMTYPE_UNDEFINED = -1, CAMTYPE_SPEC, CAMTYPE_PLAYER, }; diff --git a/src/game/client/components/mapimages.h b/src/game/client/components/mapimages.h index 426ca6538..46c1f3ea0 100644 --- a/src/game/client/components/mapimages.h +++ b/src/game/client/components/mapimages.h @@ -31,6 +31,7 @@ enum EMapImageModType class CMapImages : public CComponent { friend class CBackground; + friend class CMenuBackground; IGraphics::CTextureHandle m_aTextures[64]; int m_aTextureUsedByTileOrQuadLayerFlag[64]; // 0: nothing, 1(as flag): tile layer, 2(as flag): quad layer diff --git a/src/game/client/components/maplayers.cpp b/src/game/client/components/maplayers.cpp index 9d46884b6..79ffc417d 100644 --- a/src/game/client/components/maplayers.cpp +++ b/src/game/client/components/maplayers.cpp @@ -19,13 +19,14 @@ #include "maplayers.h" -CMapLayers::CMapLayers(int t) +CMapLayers::CMapLayers(int t, bool OnlineOnly) { m_Type = t; m_pLayers = 0; m_CurrentLocalTick = 0; m_LastLocalTick = 0; m_EnvelopeUpdate = false; + m_OnlineOnly = OnlineOnly; } void CMapLayers::OnInit() @@ -34,6 +35,11 @@ void CMapLayers::OnInit() m_pImages = m_pClient->m_pMapimages; } +CCamera *CMapLayers::GetCurCamera() +{ + return m_pClient->m_pCamera; +} + void CMapLayers::EnvelopeUpdate() { if(Client()->State() == IClient::STATE_DEMOPLAYBACK) @@ -109,19 +115,27 @@ void CMapLayers::EnvelopeEval(float TimeOffset, int Env, float *pChannels, void } else { - if(pThis->m_pClient->m_Snap.m_pGameInfoObj) // && !(pThis->m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_PAUSED)) + if(pThis->m_OnlineOnly && (pItem->m_Version < 2 || pItem->m_Synchronized)) { - if(pItem->m_Version < 2 || pItem->m_Synchronized) + if(pThis->m_OnlineOnly && pThis->m_pClient->m_Snap.m_pGameInfoObj) // && !(pThis->m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_PAUSED)) { s_Time = mix((pThis->Client()->PrevGameTick(g_Config.m_ClDummy)-pThis->m_pClient->m_Snap.m_pGameInfoObj->m_RoundStartTick) / (float)pThis->Client()->GameTickSpeed(), (pThis->Client()->GameTick(g_Config.m_ClDummy)-pThis->m_pClient->m_Snap.m_pGameInfoObj->m_RoundStartTick) / (float)pThis->Client()->GameTickSpeed(), pThis->Client()->IntraGameTick(g_Config.m_ClDummy)); } - else - s_Time += pThis->LocalTime()-s_LastLocalTime; } - pThis->RenderTools()->RenderEvalEnvelope(pPoints+pItem->m_StartPoint, pItem->m_NumPoints, 4, s_Time+TimeOffset, pChannels); - s_LastLocalTime = pThis->LocalTime(); + else if(pThis->m_OnlineOnly) + { + s_Time += pThis->LocalTime() - s_LastLocalTime; + s_LastLocalTime = pThis->LocalTime(); + } + else + { + float CurTime = (float)((double)time_get_microseconds() / 1000000.0); + s_Time += CurTime - s_LastLocalTime; + s_LastLocalTime = CurTime; + } + pThis->RenderTools()->RenderEvalEnvelope(pPoints + pItem->m_StartPoint, pItem->m_NumPoints, 4, s_Time + TimeOffset, pChannels); } } @@ -1480,13 +1494,13 @@ void CMapLayers::LayersOfGroupCount(CMapItemGroup* pGroup, int& TileLayerCount, void CMapLayers::OnRender() { - if(Client()->State() != IClient::STATE_ONLINE && Client()->State() != IClient::STATE_DEMOPLAYBACK) + if(m_OnlineOnly && Client()->State() != IClient::STATE_ONLINE && Client()->State() != IClient::STATE_DEMOPLAYBACK) return; CUIRect Screen; Graphics()->GetScreen(&Screen.x, &Screen.y, &Screen.w, &Screen.h); - vec2 Center = m_pClient->m_pCamera->m_Center; + vec2 Center = GetCurCamera()->m_Center; bool PassedGameLayer = false; int TileLayerCounter = 0; @@ -1504,11 +1518,11 @@ void CMapLayers::OnRender() continue; } - if(!g_Config.m_GfxNoclip && pGroup->m_Version >= 2 && pGroup->m_UseClipping) + if((!g_Config.m_GfxNoclip || m_Type == TYPE_FULL_DESIGN) && pGroup->m_Version >= 2 && pGroup->m_UseClipping) { // set clipping float Points[4]; - MapScreenToGroup(Center.x, Center.y, m_pLayers->GameGroup(), m_pClient->m_pCamera->m_Zoom); + MapScreenToGroup(Center.x, Center.y, m_pLayers->GameGroup(), GetCurCamera()->m_Zoom); Graphics()->GetScreen(&Points[0], &Points[1], &Points[2], &Points[3]); float x0 = (pGroup->m_ClipX - Points[0]) / (Points[2]-Points[0]); float y0 = (pGroup->m_ClipY - Points[1]) / (Points[3]-Points[1]); @@ -1526,11 +1540,12 @@ void CMapLayers::OnRender() (int)((x1-x0)*Graphics()->ScreenWidth()), (int)((y1-y0)*Graphics()->ScreenHeight())); } - if(!g_Config.m_ClZoomBackgroundLayers && !pGroup->m_ParallaxX && !pGroup->m_ParallaxY) + if((!g_Config.m_ClZoomBackgroundLayers || m_Type == TYPE_FULL_DESIGN) && !pGroup->m_ParallaxX && !pGroup->m_ParallaxY) { MapScreenToGroup(Center.x, Center.y, pGroup, 1.0f); - } else - MapScreenToGroup(Center.x, Center.y, pGroup, m_pClient->m_pCamera->m_Zoom); + } + else + MapScreenToGroup(Center.x, Center.y, pGroup, GetCurCamera()->m_Zoom); for(int l = 0; l < pGroup->m_NumLayers; l++) { @@ -1579,11 +1594,16 @@ void CMapLayers::OnRender() continue; } } - else // TYPE_FOREGROUND + else if(m_Type == TYPE_FOREGROUND) { if(PassedGameLayer && !IsGameLayer) Render = true; } + else if(m_Type == TYPE_FULL_DESIGN) + { + if(!IsGameLayer) + Render = true; + } if(Render && pLayer->m_Type == LAYERTYPE_TILES && Input()->KeyIsPressed(KEY_LCTRL) && Input()->KeyIsPressed(KEY_LSHIFT) && Input()->KeyPress(KEY_KP_0)) { @@ -1661,10 +1681,14 @@ void CMapLayers::OnRender() } // skip rendering if detail layers if not wanted, or is entity layer and we are a background map - if((pLayer->m_Flags&LAYERFLAG_DETAIL && !g_Config.m_GfxHighDetail && !IsGameLayer) || (m_Type == TYPE_BACKGROUND_FORCE && IsEntityLayer)) + if((pLayer->m_Flags & LAYERFLAG_DETAIL && (!g_Config.m_GfxHighDetail && !(m_Type == TYPE_FULL_DESIGN)) && !IsGameLayer) || (m_Type == TYPE_BACKGROUND_FORCE && IsEntityLayer) || (m_Type == TYPE_FULL_DESIGN && IsEntityLayer)) continue; - if((Render && g_Config.m_ClOverlayEntities < 100 && !IsGameLayer && !IsFrontLayer && !IsSwitchLayer && !IsTeleLayer && !IsSpeedupLayer && !IsTuneLayer) || (g_Config.m_ClOverlayEntities && IsGameLayer) || (m_Type == TYPE_BACKGROUND_FORCE)) + int EntityOverlayVal = g_Config.m_ClOverlayEntities; + if(m_Type == TYPE_FULL_DESIGN) + EntityOverlayVal = 0; + + if((Render && EntityOverlayVal < 100 && !IsGameLayer && !IsFrontLayer && !IsSwitchLayer && !IsTeleLayer && !IsSpeedupLayer && !IsTuneLayer) || (EntityOverlayVal && IsGameLayer) || (m_Type == TYPE_BACKGROUND_FORCE)) { if(pLayer->m_Type == LAYERTYPE_TILES) { @@ -1684,11 +1708,11 @@ void CMapLayers::OnRender() if(Size >= pTMap->m_Width*pTMap->m_Height*sizeof(CTile)) { - ColorRGBA Color = ColorRGBA(pTMap->m_Color.r/255.0f, pTMap->m_Color.g/255.0f, pTMap->m_Color.b/255.0f, pTMap->m_Color.a/255.0f); - if(IsGameLayer && g_Config.m_ClOverlayEntities) - Color = ColorRGBA(pTMap->m_Color.r/255.0f, pTMap->m_Color.g/255.0f, pTMap->m_Color.b/255.0f, pTMap->m_Color.a/255.0f*g_Config.m_ClOverlayEntities/100.0f); - else if(!IsGameLayer && g_Config.m_ClOverlayEntities && !(m_Type == TYPE_BACKGROUND_FORCE)) - Color = ColorRGBA(pTMap->m_Color.r/255.0f, pTMap->m_Color.g/255.0f, pTMap->m_Color.b/255.0f, pTMap->m_Color.a/255.0f*(100-g_Config.m_ClOverlayEntities)/100.0f); + ColorRGBA Color = ColorRGBA(pTMap->m_Color.r / 255.0f, pTMap->m_Color.g / 255.0f, pTMap->m_Color.b / 255.0f, pTMap->m_Color.a / 255.0f); + if(IsGameLayer && EntityOverlayVal) + Color = ColorRGBA(pTMap->m_Color.r / 255.0f, pTMap->m_Color.g / 255.0f, pTMap->m_Color.b / 255.0f, pTMap->m_Color.a / 255.0f * EntityOverlayVal / 100.0f); + else if(!IsGameLayer && EntityOverlayVal && !(m_Type == TYPE_BACKGROUND_FORCE)) + Color = ColorRGBA(pTMap->m_Color.r / 255.0f, pTMap->m_Color.g / 255.0f, pTMap->m_Color.b / 255.0f, pTMap->m_Color.a / 255.0f * (100 - EntityOverlayVal) / 100.0f); if(!Graphics()->IsTileBufferingEnabled()) { Graphics()->BlendNone(); @@ -1739,9 +1763,9 @@ void CMapLayers::OnRender() Graphics()->TextureSet(m_pImages->Get(pQLayer->m_Image)); CQuad *pQuads = (CQuad *)m_pLayers->Map()->GetDataSwapped(pQLayer->m_Data); - if(m_Type == TYPE_BACKGROUND_FORCE) + if(m_Type == TYPE_BACKGROUND_FORCE || m_Type == TYPE_FULL_DESIGN) { - if(g_Config.m_ClShowQuads) + if(g_Config.m_ClShowQuads || m_Type == TYPE_FULL_DESIGN) { if(!Graphics()->IsQuadBufferingEnabled()) { @@ -1755,7 +1779,8 @@ void CMapLayers::OnRender() RenderQuadLayer(QuadLayerCounter-1, pQLayer, pGroup, true); } } - } else + } + else { if(!Graphics()->IsQuadBufferingEnabled()) { @@ -1771,7 +1796,7 @@ void CMapLayers::OnRender() } } } - else if(Render && g_Config.m_ClOverlayEntities && IsFrontLayer) + else if(Render && EntityOverlayVal && IsFrontLayer) { CMapItemLayerTilemap *pTMap = (CMapItemLayerTilemap *)pLayer; Graphics()->TextureSet(m_pImages->GetEntities(MAP_IMAGE_ENTITY_LAYER_TYPE_FRONT)); @@ -1781,7 +1806,7 @@ void CMapLayers::OnRender() if(Size >= pTMap->m_Width*pTMap->m_Height*sizeof(CTile)) { - ColorRGBA Color = ColorRGBA(pTMap->m_Color.r/255.0f, pTMap->m_Color.g/255.0f, pTMap->m_Color.b/255.0f, pTMap->m_Color.a/255.0f*g_Config.m_ClOverlayEntities/100.0f); + ColorRGBA Color = ColorRGBA(pTMap->m_Color.r / 255.0f, pTMap->m_Color.g / 255.0f, pTMap->m_Color.b / 255.0f, pTMap->m_Color.a / 255.0f * EntityOverlayVal / 100.0f); if(!Graphics()->IsTileBufferingEnabled()) { Graphics()->BlendNone(); @@ -1798,7 +1823,7 @@ void CMapLayers::OnRender() } } } - else if(Render && g_Config.m_ClOverlayEntities && IsSwitchLayer) + else if(Render && EntityOverlayVal && IsSwitchLayer) { CMapItemLayerTilemap *pTMap = (CMapItemLayerTilemap *)pLayer; Graphics()->TextureSet(m_pImages->GetEntities(MAP_IMAGE_ENTITY_LAYER_TYPE_SWITCH)); @@ -1808,14 +1833,14 @@ void CMapLayers::OnRender() if(Size >= pTMap->m_Width*pTMap->m_Height*sizeof(CSwitchTile)) { - ColorRGBA Color = ColorRGBA(pTMap->m_Color.r/255.0f, pTMap->m_Color.g/255.0f, pTMap->m_Color.b/255.0f, pTMap->m_Color.a/255.0f*g_Config.m_ClOverlayEntities/100.0f); + ColorRGBA Color = ColorRGBA(pTMap->m_Color.r / 255.0f, pTMap->m_Color.g / 255.0f, pTMap->m_Color.b / 255.0f, pTMap->m_Color.a / 255.0f * EntityOverlayVal / 100.0f); if(!Graphics()->IsTileBufferingEnabled()) { Graphics()->BlendNone(); RenderTools()->RenderSwitchmap(pSwitchTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, Color, TILERENDERFLAG_EXTEND|LAYERRENDERFLAG_OPAQUE); Graphics()->BlendNormal(); - RenderTools()->RenderSwitchmap(pSwitchTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, Color, TILERENDERFLAG_EXTEND|LAYERRENDERFLAG_TRANSPARENT); - RenderTools()->RenderSwitchOverlay(pSwitchTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, g_Config.m_ClOverlayEntities/100.0f); + RenderTools()->RenderSwitchmap(pSwitchTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, Color, TILERENDERFLAG_EXTEND | LAYERRENDERFLAG_TRANSPARENT); + RenderTools()->RenderSwitchOverlay(pSwitchTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, EntityOverlayVal / 100.0f); } else { @@ -1831,7 +1856,7 @@ void CMapLayers::OnRender() } } } - else if(Render && g_Config.m_ClOverlayEntities && IsTeleLayer) + else if(Render && EntityOverlayVal && IsTeleLayer) { CMapItemLayerTilemap *pTMap = (CMapItemLayerTilemap *)pLayer; Graphics()->TextureSet(m_pImages->GetEntities(MAP_IMAGE_ENTITY_LAYER_TYPE_TELE)); @@ -1841,14 +1866,14 @@ void CMapLayers::OnRender() if(Size >= pTMap->m_Width*pTMap->m_Height*sizeof(CTeleTile)) { - ColorRGBA Color = ColorRGBA(pTMap->m_Color.r/255.0f, pTMap->m_Color.g/255.0f, pTMap->m_Color.b/255.0f, pTMap->m_Color.a/255.0f*g_Config.m_ClOverlayEntities/100.0f); + ColorRGBA Color = ColorRGBA(pTMap->m_Color.r / 255.0f, pTMap->m_Color.g / 255.0f, pTMap->m_Color.b / 255.0f, pTMap->m_Color.a / 255.0f * EntityOverlayVal / 100.0f); if(!Graphics()->IsTileBufferingEnabled()) { Graphics()->BlendNone(); RenderTools()->RenderTelemap(pTeleTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, Color, TILERENDERFLAG_EXTEND|LAYERRENDERFLAG_OPAQUE); Graphics()->BlendNormal(); - RenderTools()->RenderTelemap(pTeleTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, Color, TILERENDERFLAG_EXTEND|LAYERRENDERFLAG_TRANSPARENT); - RenderTools()->RenderTeleOverlay(pTeleTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, g_Config.m_ClOverlayEntities/100.0f); + RenderTools()->RenderTelemap(pTeleTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, Color, TILERENDERFLAG_EXTEND | LAYERRENDERFLAG_TRANSPARENT); + RenderTools()->RenderTeleOverlay(pTeleTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, EntityOverlayVal / 100.0f); } else { @@ -1862,7 +1887,7 @@ void CMapLayers::OnRender() } } } - else if(Render && g_Config.m_ClOverlayEntities && IsSpeedupLayer) + else if(Render && EntityOverlayVal && IsSpeedupLayer) { CMapItemLayerTilemap *pTMap = (CMapItemLayerTilemap *)pLayer; Graphics()->TextureSet(m_pImages->GetEntities(MAP_IMAGE_ENTITY_LAYER_TYPE_SPEEDUP)); @@ -1872,14 +1897,14 @@ void CMapLayers::OnRender() if(Size >= pTMap->m_Width*pTMap->m_Height*sizeof(CSpeedupTile)) { - ColorRGBA Color = ColorRGBA(pTMap->m_Color.r/255.0f, pTMap->m_Color.g/255.0f, pTMap->m_Color.b/255.0f, pTMap->m_Color.a/255.0f*g_Config.m_ClOverlayEntities/100.0f); + ColorRGBA Color = ColorRGBA(pTMap->m_Color.r / 255.0f, pTMap->m_Color.g / 255.0f, pTMap->m_Color.b / 255.0f, pTMap->m_Color.a / 255.0f * EntityOverlayVal / 100.0f); if(!Graphics()->IsTileBufferingEnabled()) { Graphics()->BlendNone(); RenderTools()->RenderSpeedupmap(pSpeedupTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, Color, TILERENDERFLAG_EXTEND|LAYERRENDERFLAG_OPAQUE); Graphics()->BlendNormal(); - RenderTools()->RenderSpeedupmap(pSpeedupTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, Color, TILERENDERFLAG_EXTEND|LAYERRENDERFLAG_TRANSPARENT); - RenderTools()->RenderSpeedupOverlay(pSpeedupTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, g_Config.m_ClOverlayEntities/100.0f); + RenderTools()->RenderSpeedupmap(pSpeedupTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, Color, TILERENDERFLAG_EXTEND | LAYERRENDERFLAG_TRANSPARENT); + RenderTools()->RenderSpeedupOverlay(pSpeedupTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, EntityOverlayVal / 100.0f); } else { @@ -1900,7 +1925,7 @@ void CMapLayers::OnRender() } } } - else if(Render && g_Config.m_ClOverlayEntities && IsTuneLayer) + else if(Render && EntityOverlayVal && IsTuneLayer) { CMapItemLayerTilemap *pTMap = (CMapItemLayerTilemap *)pLayer; Graphics()->TextureSet(m_pImages->GetEntities(MAP_IMAGE_ENTITY_LAYER_TYPE_TUNE)); @@ -1910,14 +1935,14 @@ void CMapLayers::OnRender() if(Size >= pTMap->m_Width*pTMap->m_Height*sizeof(CTuneTile)) { - ColorRGBA Color = ColorRGBA(pTMap->m_Color.r/255.0f, pTMap->m_Color.g/255.0f, pTMap->m_Color.b/255.0f, pTMap->m_Color.a/255.0f*g_Config.m_ClOverlayEntities/100.0f); + ColorRGBA Color = ColorRGBA(pTMap->m_Color.r / 255.0f, pTMap->m_Color.g / 255.0f, pTMap->m_Color.b / 255.0f, pTMap->m_Color.a / 255.0f * EntityOverlayVal / 100.0f); if(!Graphics()->IsTileBufferingEnabled()) { Graphics()->BlendNone(); RenderTools()->RenderTunemap(pTuneTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, Color, TILERENDERFLAG_EXTEND|LAYERRENDERFLAG_OPAQUE); Graphics()->BlendNormal(); - RenderTools()->RenderTunemap(pTuneTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, Color, TILERENDERFLAG_EXTEND|LAYERRENDERFLAG_TRANSPARENT); - //RenderTools()->RenderTuneOverlay(pTuneTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, g_Config.m_ClOverlayEntities/100.0f); + RenderTools()->RenderTunemap(pTuneTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, Color, TILERENDERFLAG_EXTEND | LAYERRENDERFLAG_TRANSPARENT); + //RenderTools()->RenderTuneOverlay(pTuneTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, EntityOverlayVal/100.0f); } else { @@ -1927,11 +1952,11 @@ void CMapLayers::OnRender() } } } - if(!g_Config.m_GfxNoclip) + if(!g_Config.m_GfxNoclip || m_Type == TYPE_FULL_DESIGN) Graphics()->ClipDisable(); } - if(!g_Config.m_GfxNoclip) + if(!g_Config.m_GfxNoclip || m_Type == TYPE_FULL_DESIGN) Graphics()->ClipDisable(); // reset the screen like it was before diff --git a/src/game/client/components/maplayers.h b/src/game/client/components/maplayers.h index c0b737320..58ae1e6b5 100644 --- a/src/game/client/components/maplayers.h +++ b/src/game/client/components/maplayers.h @@ -19,6 +19,7 @@ typedef unsigned int offset_ptr32; class CMapLayers : public CComponent { friend class CBackground; + friend class CMenuBackground; CLayers *m_pLayers; class CMapImages *m_pImages; @@ -27,6 +28,8 @@ class CMapLayers : public CComponent int m_LastLocalTick; bool m_EnvelopeUpdate; + bool m_OnlineOnly; + void MapScreenToGroup(float CenterX, float CenterY, CMapItemGroup *pGroup, float Zoom = 1.0f); struct STileLayerVisuals @@ -114,18 +117,22 @@ class CMapLayers : public CComponent }; std::vector m_QuadLayerVisuals; - void LayersOfGroupCount(CMapItemGroup* pGroup, int& TileLayerCount, int& QuadLayerCount, bool& PassedGameLayer); + virtual class CCamera *GetCurCamera(); + + void LayersOfGroupCount(CMapItemGroup *pGroup, int &TileLayerCount, int &QuadLayerCount, bool &PassedGameLayer); void RenderTileBorderCornerTiles(int WidthOffsetToOrigin, int HeightOffsetToOrigin, int TileCountWidth, int TileCountHeight, int BufferContainerIndex, float *pColor, offset_ptr_size IndexBufferOffset, float *pOffset, float *pDir); public: enum { - TYPE_BACKGROUND=0, + TYPE_BACKGROUND = 0, TYPE_BACKGROUND_FORCE, TYPE_FOREGROUND, + TYPE_FULL_DESIGN, + TYPE_ALL = -1, }; - CMapLayers(int Type); + CMapLayers(int Type, bool OnlineOnly = true); virtual void OnInit(); virtual void OnRender(); virtual void OnMapLoad(); diff --git a/src/game/client/components/menu_background.cpp b/src/game/client/components/menu_background.cpp new file mode 100644 index 000000000..c748a1ed1 --- /dev/null +++ b/src/game/client/components/menu_background.cpp @@ -0,0 +1,368 @@ +#include + +#include + +#include +#include +#include + +#include +#include +#include + +#include "menu_background.h" + +CMenuBackground::CMenuBackground() + : CBackground(CMapLayers::TYPE_FULL_DESIGN, false) +{ + m_RotationCenter = vec2(0.0f, 0.0f); + m_AnimationStartPos = vec2(0.0f, 0.0f); + m_Camera.m_Center = vec2(0.0f, 0.0f); + m_Camera.m_PrevCenter = vec2(0.0f, 0.0f); + m_MenuCenter = vec2(0.0f, 0.0f); + + ResetPositions(); + + m_CurrentPosition = -1; + m_MoveTime = 0.0f; + + m_IsInit = false; +} + +CBackgroundEngineMap *CMenuBackground::CreateBGMap() +{ + return new CMenuMap; +} + +void CMenuBackground::OnInit() +{ + m_IsInit = true; + + m_pImages->m_pClient = GameClient(); + Kernel()->RegisterInterface((CMenuMap *)m_pBackgroundMap); + if(g_Config.m_ClMenuMap[0] != '\0') + LoadMenuBackground(); + + m_Camera.m_pClient = GameClient(); + m_Camera.m_ZoomSet = false; + m_Camera.m_ZoomSmoothingTarget = 0; +} + +void CMenuBackground::ResetPositions() +{ + m_Positions[POS_START] = vec2(500.0f, 500.0f); + m_Positions[POS_INTERNET] = vec2(1000.0f, 1000.0f); + m_Positions[POS_LAN] = vec2(1100.0f, 1000.0f); + m_Positions[POS_DEMOS] = vec2(900.0f, 100.0f); + m_Positions[POS_NEWS] = vec2(500.0f, 750.0f); + m_Positions[POS_FAVORITES] = vec2(1250.0f, 500.0f); + m_Positions[POS_SETTINGS_LANGUAGE] = vec2(500.0f, 1200.0f); + m_Positions[POS_SETTINGS_GENERAL] = vec2(500.0f, 1000.0f); + m_Positions[POS_SETTINGS_PLAYER] = vec2(600.0f, 1000.0f); + m_Positions[POS_SETTINGS_TEE] = vec2(700.0f, 1000.0f); + m_Positions[POS_SETTINGS_HUD] = vec2(200.0f, 1000.0f); + m_Positions[POS_SETTINGS_CONTROLS] = vec2(800.0f, 1000.0f); + m_Positions[POS_SETTINGS_GRAPHICS] = vec2(900.0f, 1000.0f); + m_Positions[POS_SETTINGS_SOUND] = vec2(1000.0f, 1000.0f); + m_Positions[POS_SETTINGS_DDNET] = vec2(1200.0f, 200.0f); + for(int i = 0; i < POS_CUSTOM_NUM; ++i) + m_Positions[POS_CUSTOM0 + i] = vec2(500.0f + (75.0f * (float)i), 1250.0f - (75.0f * (float)i)); +} + +int CMenuBackground::ThemeScan(const char *pName, int IsDir, int DirType, void *pUser) +{ + CMenuBackground *pSelf = (CMenuBackground *)pUser; + const char *pSuffix = str_endswith(pName, ".map"); + if(IsDir || !pSuffix) + return 0; + char aFullName[128]; + char aThemeName[128]; + str_truncate(aFullName, sizeof(aFullName), pName, pSuffix - pName); + + bool IsDay = false; + bool IsNight = false; + if((pSuffix = str_endswith(aFullName, "_day"))) + { + str_truncate(aThemeName, sizeof(aThemeName), pName, pSuffix - aFullName); + IsDay = true; + } + else if((pSuffix = str_endswith(aFullName, "_night"))) + { + str_truncate(aThemeName, sizeof(aThemeName), pName, pSuffix - aFullName); + IsNight = true; + } + else + str_copy(aThemeName, aFullName, sizeof(aThemeName)); + + if(str_comp(aThemeName, "none") == 0 || str_comp(aThemeName, "auto") == 0 || str_comp(aThemeName, "rand") == 0) // "none", "auto" and "rand" reserved, disallowed for maps + return 0; + + // try to edit an existing theme + for(int i = 0; i < (int)pSelf->m_lThemes.size(); i++) + { + if(str_comp(pSelf->m_lThemes[i].m_Name, aThemeName) == 0) + { + if(IsDay) + pSelf->m_lThemes[i].m_HasDay = true; + if(IsNight) + pSelf->m_lThemes[i].m_HasNight = true; + return 0; + } + } + + // make new theme + CTheme Theme(aThemeName, IsDay, IsNight); + char aBuf[512]; + str_format(aBuf, sizeof(aBuf), "added theme %s from themes/%s", aThemeName, pName); + pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "game", aBuf); + pSelf->m_lThemes.push_back(Theme); + return 0; +} + +int CMenuBackground::ThemeIconScan(const char *pName, int IsDir, int DirType, void *pUser) +{ + CMenuBackground *pSelf = (CMenuBackground *)pUser; + const char *pSuffix = str_endswith(pName, ".png"); + if(IsDir || !pSuffix) + return 0; + + char aThemeName[128]; + str_truncate(aThemeName, sizeof(aThemeName), pName, pSuffix - pName); + + // save icon for an existing theme + for(CTheme &Theme : pSelf->m_lThemes) // bit slow but whatever + { + if(str_comp(Theme.m_Name, aThemeName) == 0 || (!Theme.m_Name[0] && str_comp(aThemeName, "none") == 0)) + { + char aBuf[MAX_PATH_LENGTH]; + str_format(aBuf, sizeof(aBuf), "themes/%s", pName); + CImageInfo Info; + if(!pSelf->Graphics()->LoadPNG(&Info, aBuf, DirType)) + { + str_format(aBuf, sizeof(aBuf), "failed to load theme icon from %s", pName); + pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "game", aBuf); + return 0; + } + str_format(aBuf, sizeof(aBuf), "loaded theme icon %s", pName); + pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "game", aBuf); + + Theme.m_IconTexture = pSelf->Graphics()->LoadTextureRaw(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, Info.m_Format, 0); + return 0; + } + } + return 0; // no existing theme +} + +void CMenuBackground::LoadMenuBackground(bool HasDayHint, bool HasNightHint) +{ + if(!m_IsInit) + return; + + if(m_Loaded && m_pMap == m_pBackgroundMap) + m_pMap->Unload(); + + m_Loaded = false; + m_pMap = m_pBackgroundMap; + m_pLayers = m_pBackgroundLayers; + m_pImages = m_pBackgroundImages; + + ResetPositions(); + + bool NeedImageLoading = false; + + str_copy(m_aMapName, g_Config.m_ClMenuMap, sizeof(m_aMapName)); + + if(g_Config.m_ClMenuMap[0] != '\0') + { + const char *pMenuMap = g_Config.m_ClMenuMap; + if(str_comp(pMenuMap, "auto") == 0) + { + switch(time_season()) + { + case SEASON_SPRING: + pMenuMap = "heavens"; + break; + case SEASON_SUMMER: + pMenuMap = "jungle"; + break; + case SEASON_AUTUMN: + pMenuMap = "autumn"; + break; + case SEASON_WINTER: + pMenuMap = "winter"; + break; + } + } + else if(str_comp(pMenuMap, "rand") == 0) + { + //make sure to load themes + std::vector &ThemesRef = GetThemes(); + int RandomThemeIndex = rand() % (ThemesRef.size() - PREDEFINED_THEMES_COUNT); + if(RandomThemeIndex + PREDEFINED_THEMES_COUNT < (int)ThemesRef.size()) + pMenuMap = ThemesRef[RandomThemeIndex + PREDEFINED_THEMES_COUNT].m_Name.cstr(); + } + + char aBuf[128]; + + const int HourOfTheDay = time_houroftheday(); + const bool IsDaytime = HourOfTheDay >= 6 && HourOfTheDay < 18; + + if(!m_Loaded && ((HasDayHint && IsDaytime) || (HasNightHint && !IsDaytime))) + { + str_format(aBuf, sizeof(aBuf), "themes/%s_%s.map", pMenuMap, IsDaytime ? "day" : "night"); + if(m_pMap->Load(aBuf)) + { + m_Loaded = true; + } + } + + if(!m_Loaded) + { + str_format(aBuf, sizeof(aBuf), "themes/%s.map", pMenuMap); + if(m_pMap->Load(aBuf)) + { + m_Loaded = true; + } + } + + if(!m_Loaded && ((HasDayHint && !IsDaytime) || (HasNightHint && IsDaytime))) + { + str_format(aBuf, sizeof(aBuf), "themes/%s_%s.map", pMenuMap, IsDaytime ? "night" : "day"); + if(m_pMap->Load(aBuf)) + { + m_Loaded = true; + } + } + + if(m_Loaded) + { + m_pLayers->InitBackground(m_pMap); + RenderTools()->RenderTilemapGenerateSkip(m_pLayers); + NeedImageLoading = true; + + CMapLayers::OnMapLoad(); + if(NeedImageLoading) + m_pImages->LoadBackground(m_pLayers, m_pMap); + + // look for custom positions + CMapItemLayerTilemap *pTLayer = m_pLayers->GameLayer(); + if(pTLayer) + { + int DataIndex = pTLayer->m_Data; + unsigned int Size = m_pLayers->Map()->GetDataSize(DataIndex); + void *pTiles = m_pLayers->Map()->GetData(DataIndex); + unsigned int TileSize = sizeof(CTile); + + if(Size >= pTLayer->m_Width * pTLayer->m_Height * TileSize) + { + int x = 0; + int y = 0; + for(y = 0; y < pTLayer->m_Height; ++y) + { + for(x = 0; x < pTLayer->m_Width; ++x) + { + unsigned char Index = ((CTile *)pTiles)[y * pTLayer->m_Width + x].m_Index; + if(Index >= TILE_CHECKPOINT_FIRST && Index <= TILE_CHECKPOINT_LAST) + { + int ArrayIndex = clamp((Index - TILE_CHECKPOINT_FIRST), 0, NUM_POS); + m_Positions[ArrayIndex] = vec2(x * 32.0f + 16.0f, y * 32.0f + 16.0f); + } + + x += ((CTile *)pTiles)[y * pTLayer->m_Width + x].m_Skip; + } + } + } + } + } + + m_LastLoad = time_get(); + } +} + +void CMenuBackground::OnMapLoad() +{ + return; +} + +void CMenuBackground::OnRender() +{ + return; +} + +bool CMenuBackground::Render() +{ + if(!m_Loaded) + return false; + + if(Client()->State() >= IClient::STATE_ONLINE) + return false; + + m_Camera.m_Zoom = 0.7f; + static vec2 Dir = vec2(1.0f, 0.0f); + + if(distance(m_Camera.m_Center, m_RotationCenter) <= (float)g_Config.m_ClRotationRadius + 0.5f) + { + // do little rotation + float RotPerTick = 360.0f / (float)g_Config.m_ClRotationSpeed * clamp(Client()->RenderFrameTime(), 0.0f, 0.1f); + Dir = rotate(Dir, RotPerTick); + m_Camera.m_Center = m_RotationCenter + Dir * (float)g_Config.m_ClRotationRadius; + } + else + { + // positions for the animation + Dir = normalize(m_AnimationStartPos - m_RotationCenter); + vec2 TargetPos = m_RotationCenter + Dir * (float)g_Config.m_ClRotationRadius; + float Distance = distance(m_AnimationStartPos, TargetPos); + + // move time + m_MoveTime += clamp(Client()->RenderFrameTime(), 0.0f, 0.1f) * g_Config.m_ClCameraSpeed / 10.0f; + float XVal = 1 - m_MoveTime; + XVal = pow(XVal, 7.0f); + + m_Camera.m_Center = TargetPos + Dir * (XVal * Distance); + } + + CMapLayers::OnRender(); + + return true; +} + +CCamera *CMenuBackground::GetCurCamera() +{ + return &m_Camera; +} + +void CMenuBackground::ChangePosition(int PositionNumber) +{ + if(PositionNumber != m_CurrentPosition) + { + if(PositionNumber >= POS_START && PositionNumber < NUM_POS) + { + m_CurrentPosition = PositionNumber; + } + else + { + m_CurrentPosition = POS_START; + } + } + m_AnimationStartPos = m_Camera.m_Center; + m_RotationCenter = m_Positions[m_CurrentPosition]; + m_MoveTime = 0.0f; +} + +std::vector &CMenuBackground::GetThemes() +{ + if(m_lThemes.size() == 0) // not loaded yet + { + // when adding more here, make sure to change the value of PREDEFINED_THEMES_COUNT too + m_lThemes.push_back(CTheme("", true, true)); // no theme + m_lThemes.push_back(CTheme("auto", true, true)); // auto theme + m_lThemes.push_back(CTheme("rand", true, true)); // random theme + + Storage()->ListDirectory(IStorage::TYPE_ALL, "themes", ThemeScan, (CMenuBackground *)this); + Storage()->ListDirectory(IStorage::TYPE_ALL, "themes", ThemeIconScan, (CMenuBackground *)this); + + std::sort(m_lThemes.begin() + PREDEFINED_THEMES_COUNT, m_lThemes.end()); + } + return m_lThemes; +} diff --git a/src/game/client/components/menu_background.h b/src/game/client/components/menu_background.h new file mode 100644 index 000000000..e94ba8cd3 --- /dev/null +++ b/src/game/client/components/menu_background.h @@ -0,0 +1,110 @@ +#ifndef GAME_CLIENT_COMPONENTS_MENU_BACKGROUND_H +#define GAME_CLIENT_COMPONENTS_MENU_BACKGROUND_H + +#include +#include + +#include + +class CMenuMap : public CBackgroundEngineMap +{ + MACRO_INTERFACE("menu_enginemap", 0) +}; + +// themes +class CTheme +{ +public: + CTheme() {} + CTheme(const char *n, bool HasDay, bool HasNight) + : m_Name(n), m_HasDay(HasDay), m_HasNight(HasNight) {} + + string m_Name; + bool m_HasDay; + bool m_HasNight; + IGraphics::CTextureHandle m_IconTexture; + bool operator<(const CTheme &Other) const { return m_Name < Other.m_Name; } +}; + +class CMenuBackground : public CBackground +{ +public: + enum + { + POS_START = 0, + POS_INTERNET, + POS_LAN, + POS_DEMOS, + POS_NEWS, + POS_FAVORITES, + POS_SETTINGS_LANGUAGE, + POS_SETTINGS_GENERAL, + POS_SETTINGS_PLAYER, + POS_SETTINGS_TEE, + POS_SETTINGS_HUD, + POS_SETTINGS_CONTROLS, + POS_SETTINGS_GRAPHICS, + POS_SETTINGS_SOUND, + POS_SETTINGS_DDNET, + POS_CUSTOM, + POS_CUSTOM0 = POS_CUSTOM, // ddnet tab + POS_CUSTOM1, // kog tab + POS_CUSTOM2, + POS_CUSTOM3, + POS_CUSTOM4, + POS_CUSTOM5, + POS_CUSTOM6, + POS_CUSTOM7, + POS_CUSTOM8, + POS_CUSTOM9, + + NUM_POS, + + POS_CUSTOM_NUM = (POS_CUSTOM9 - POS_CUSTOM0) + 1, + }; + + enum + { + PREDEFINED_THEMES_COUNT = 3, + }; + + CCamera m_Camera; + + CBackgroundEngineMap *CreateBGMap() override; + + vec2 m_MenuCenter; + vec2 m_RotationCenter; + vec2 m_Positions[NUM_POS]; + int m_CurrentPosition; + vec2 m_AnimationStartPos; + float m_MoveTime; + + bool m_IsInit; + + void ResetPositions(); + + static int ThemeScan(const char *pName, int IsDir, int DirType, void *pUser); + static int ThemeIconScan(const char *pName, int IsDir, int DirType, void *pUser); + + std::vector m_lThemes; + +public: + CMenuBackground(); + ~CMenuBackground() override {} + + void OnInit() override; + void OnMapLoad() override; + void OnRender() override; + + void LoadMenuBackground(bool HasDayHint = true, bool HasNightHint = true); + + bool Render(); + + class CCamera *GetCurCamera() override; + + void ChangePosition(int PositionNumber); + + std::vector &GetThemes(); +}; + +#endif diff --git a/src/game/client/components/menus.cpp b/src/game/client/components/menus.cpp index b1302ebc7..515cb9786 100644 --- a/src/game/client/components/menus.cpp +++ b/src/game/client/components/menus.cpp @@ -1,6 +1,8 @@ /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ /* If you are missing that file, acquire a complete release at teeworlds.com. */ +#include + #include #include @@ -27,6 +29,7 @@ #include #include +#include #include #include #include @@ -1002,7 +1005,10 @@ void CMenus::RenderLoading() CUIRect Screen = *UI()->Screen(); Graphics()->MapScreen(Screen.x, Screen.y, Screen.w, Screen.h); - RenderBackground(); + if(!m_pBackground->Render()) + { + RenderBackground(); + } float w = 700; float h = 200; @@ -1164,7 +1170,10 @@ int CMenus::Render() } else { - RenderBackground(); + if(!m_pBackground->Render()) + { + RenderBackground(); + } ms_ColorTabbarInactive = ms_ColorTabbarInactiveOutgame; ms_ColorTabbarActive = ms_ColorTabbarActiveOutgame; ms_ColorTabbarHover = ms_ColorTabbarHoverOutgame; @@ -1187,7 +1196,10 @@ int CMenus::Render() if(m_Popup == POPUP_NONE) { if(m_ShowStart && Client()->State() == IClient::STATE_OFFLINE) + { + m_pBackground->ChangePosition(CMenuBackground::POS_START); RenderStartMenu(Screen); + } else { Screen.HSplitTop(24.0f, &TabBar, &MainView); @@ -1224,21 +1236,44 @@ int CMenus::Render() RenderSettings(MainView); } else if(m_MenuPage == PAGE_NEWS) + { + m_pBackground->ChangePosition(CMenuBackground::POS_NEWS); RenderNews(MainView); + } else if(m_MenuPage == PAGE_INTERNET) + { + m_pBackground->ChangePosition(CMenuBackground::POS_INTERNET); RenderServerbrowser(MainView); + } else if(m_MenuPage == PAGE_LAN) + { + m_pBackground->ChangePosition(CMenuBackground::POS_LAN); RenderServerbrowser(MainView); + } else if(m_MenuPage == PAGE_DEMOS) + { + m_pBackground->ChangePosition(CMenuBackground::POS_DEMOS); RenderDemoList(MainView); + } else if(m_MenuPage == PAGE_FAVORITES) + { + m_pBackground->ChangePosition(CMenuBackground::POS_FAVORITES); RenderServerbrowser(MainView); + } else if(m_MenuPage == PAGE_DDNET) + { + m_pBackground->ChangePosition(CMenuBackground::POS_CUSTOM0); RenderServerbrowser(MainView); + } else if(m_MenuPage == PAGE_KOG) + { + m_pBackground->ChangePosition(CMenuBackground::POS_CUSTOM0 + 1); RenderServerbrowser(MainView); + } else if(m_MenuPage == PAGE_SETTINGS) + { RenderSettings(MainView); + } // do tab bar RenderMenubar(TabBar); @@ -2013,6 +2048,79 @@ int CMenus::Render() return 0; } +void CMenus::RenderThemeSelection(CUIRect MainView, bool Header) +{ + std::vector &ThemesRef = m_pBackground->GetThemes(); + + int SelectedTheme = -1; + for(int i = 0; i < (int)ThemesRef.size(); i++) + { + if(str_comp(ThemesRef[i].m_Name, g_Config.m_ClMenuMap) == 0) + { + SelectedTheme = i; + break; + } + } + + static int s_ListBox = 0; + static float s_ScrollValue = 0.0f; + UiDoListboxStart(&s_ListBox, &MainView, 26.0f, Localize("Themes"), "", ThemesRef.size(), 1, -1, s_ScrollValue); + + for(int i = 0; i < (int)ThemesRef.size(); i++) + { + CListboxItem Item = UiDoListboxNextItem(&ThemesRef[i].m_Name, i == SelectedTheme); + + CTheme &Theme = ThemesRef[i]; + + if(!Item.m_Visible) + continue; + + CUIRect Icon; + Item.m_Rect.VSplitLeft(Item.m_Rect.h * 2.0f, &Icon, &Item.m_Rect); + + // draw icon if it exists + if(Theme.m_IconTexture != -1) + { + Icon.VMargin(6.0f, &Icon); + Icon.HMargin(3.0f, &Icon); + Graphics()->TextureSet(Theme.m_IconTexture); + Graphics()->QuadsBegin(); + Graphics()->SetColor(1.0f, 1.0f, 1.0f, 1.0f); + IGraphics::CQuadItem QuadItem(Icon.x, Icon.y, Icon.w, Icon.h); + Graphics()->QuadsDrawTL(&QuadItem, 1); + Graphics()->QuadsEnd(); + } + + char aName[128]; + if(!Theme.m_Name[0]) + str_copy(aName, "(none)", sizeof(aName)); + else if(str_comp(Theme.m_Name, "auto") == 0) + str_copy(aName, "(seasons)", sizeof(aName)); + else if(str_comp(Theme.m_Name, "rand") == 0) + str_copy(aName, "(random)", sizeof(aName)); + else if(Theme.m_HasDay && Theme.m_HasNight) + str_format(aName, sizeof(aName), "%s", Theme.m_Name.cstr()); + else if(Theme.m_HasDay && !Theme.m_HasNight) + str_format(aName, sizeof(aName), "%s (day)", Theme.m_Name.cstr()); + else if(!Theme.m_HasDay && Theme.m_HasNight) + str_format(aName, sizeof(aName), "%s (night)", Theme.m_Name.cstr()); + else // generic + str_format(aName, sizeof(aName), "%s", Theme.m_Name.cstr()); + + Item.m_Rect.y += 2.0f; + UI()->DoLabel(&Item.m_Rect, aName, Item.m_Rect.h * ms_FontmodHeight * 0.8f, -1); + } + + bool ItemActive = false; + int NewSelected = UiDoListboxEnd(&s_ScrollValue, 0, &ItemActive); + + if(ItemActive && NewSelected != SelectedTheme) + { + str_format(g_Config.m_ClMenuMap, sizeof(g_Config.m_ClMenuMap), "%s", ThemesRef[NewSelected].m_Name.cstr()); + m_pBackground->LoadMenuBackground(ThemesRef[NewSelected].m_HasDay, ThemesRef[NewSelected].m_HasNight); + } +} + void CMenus::SetActive(bool Active) { if(Active != m_MenuActive) diff --git a/src/game/client/components/menus.h b/src/game/client/components/menus.h index 5d3e53660..b2bbe8c60 100644 --- a/src/game/client/components/menus.h +++ b/src/game/client/components/menus.h @@ -326,6 +326,7 @@ class CMenus : public CComponent // found in menus_settings.cpp void RenderLanguageSelection(CUIRect MainView); + void RenderThemeSelection(CUIRect MainView, bool Header = true); void RenderSettingsGeneral(CUIRect MainView); void RenderSettingsPlayer(CUIRect MainView); void RenderSettingsDummyPlayer(CUIRect MainView); @@ -341,9 +342,13 @@ class CMenus : public CComponent bool CheckHotKey(int Key) const; + class CMenuBackground *m_pBackground; + public: void RenderBackground(); + void SetMenuBackground(class CMenuBackground *pBackground) { m_pBackground = pBackground; } + void UseMouseButtons(bool Use) { m_UseMouseButtons = Use; } static CMenusKeyBinder m_Binder; diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp index 64eda701a..275609eca 100644 --- a/src/game/client/components/menus_settings.cpp +++ b/src/game/client/components/menus_settings.cpp @@ -17,11 +17,12 @@ #include #include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include #include #include "binds.h" @@ -74,9 +75,8 @@ void CMenus::RenderSettingsGeneral(CUIRect MainView) #endif char aBuf[128]; - CUIRect Label, Button, Left, Right, Game, Client, AutoReconnect; + CUIRect Label, Button, Left, Right, Game, Client; MainView.HSplitTop(180.0f, &Game, &Client); - Client.HSplitTop(160.0f, &Client, &AutoReconnect); // game { @@ -217,12 +217,11 @@ void CMenus::RenderSettingsGeneral(CUIRect MainView) else str_format(aBuf, sizeof(aBuf), "%s: %s", Localize("Refresh Rate"), "∞"); UI()->DoLabelScaled(&Label, aBuf, 13.0f, -1); - Left.HSplitTop(20.0f, &Button, 0); + Left.HSplitTop(20.0f, &Button, &Left); Button.HMargin(2.0f, &Button); g_Config.m_ClRefreshRate= static_cast(DoScrollbarH(&g_Config.m_ClRefreshRate, &Button, g_Config.m_ClRefreshRate/10000.0f)*10000.0f+0.1f); #if defined(CONF_FAMILY_WINDOWS) - Left.HSplitTop(20.0f, 0, &Left); Left.HSplitTop(20.0f, &Button, &Left); if(DoButton_CheckBox(&g_Config.m_ClShowConsole, Localize("Show console window"), g_Config.m_ClShowConsole, &Button)) { @@ -234,6 +233,8 @@ void CMenus::RenderSettingsGeneral(CUIRect MainView) m_NeedRestartGeneral = s_ClShowConsole != g_Config.m_ClShowConsole; #endif + RenderThemeSelection(Left); + // auto statboard screenshot { Right.HSplitTop(20.0f, 0, &Right); // @@ -1398,23 +1399,50 @@ void CMenus::RenderSettings(CUIRect MainView) MainView.Margin(10.0f, &MainView); if(g_Config.m_UiSettingsPage == SETTINGS_LANGUAGE) + { + m_pBackground->ChangePosition(CMenuBackground::POS_SETTINGS_LANGUAGE); RenderLanguageSelection(MainView); + } else if(g_Config.m_UiSettingsPage == SETTINGS_GENERAL) + { + m_pBackground->ChangePosition(CMenuBackground::POS_SETTINGS_GENERAL); RenderSettingsGeneral(MainView); + } else if(g_Config.m_UiSettingsPage == SETTINGS_PLAYER) + { + m_pBackground->ChangePosition(CMenuBackground::POS_SETTINGS_PLAYER); RenderSettingsPlayer(MainView); + } else if(g_Config.m_UiSettingsPage == SETTINGS_TEE) + { + m_pBackground->ChangePosition(CMenuBackground::POS_SETTINGS_TEE); RenderSettingsTee(MainView); + } else if(g_Config.m_UiSettingsPage == SETTINGS_HUD) + { + m_pBackground->ChangePosition(CMenuBackground::POS_SETTINGS_HUD); RenderSettingsHUD(MainView); + } else if(g_Config.m_UiSettingsPage == SETTINGS_CONTROLS) + { + m_pBackground->ChangePosition(CMenuBackground::POS_SETTINGS_CONTROLS); RenderSettingsControls(MainView); + } else if(g_Config.m_UiSettingsPage == SETTINGS_GRAPHICS) + { + m_pBackground->ChangePosition(CMenuBackground::POS_SETTINGS_GRAPHICS); RenderSettingsGraphics(MainView); + } else if(g_Config.m_UiSettingsPage == SETTINGS_SOUND) + { + m_pBackground->ChangePosition(CMenuBackground::POS_SETTINGS_SOUND); RenderSettingsSound(MainView); + } else if(g_Config.m_UiSettingsPage == SETTINGS_DDNET) + { + m_pBackground->ChangePosition(CMenuBackground::POS_SETTINGS_DDNET); RenderSettingsDDNet(MainView); + } if(m_NeedRestartUpdate) { diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index aedca887a..a5dba6b62 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -50,11 +50,12 @@ #include "components/mapimages.h" #include "components/maplayers.h" #include "components/mapsounds.h" +#include "components/menu_background.h" #include "components/menus.h" #include "components/motd.h" +#include "components/nameplates.h" #include "components/particles.h" #include "components/players.h" -#include "components/nameplates.h" #include "components/scoreboard.h" #include "components/skins.h" #include "components/sounds.h" @@ -101,6 +102,7 @@ static CMapImages gs_MapImages; static CMapLayers gs_MapLayersBackGround(CMapLayers::TYPE_BACKGROUND); static CMapLayers gs_MapLayersForeGround(CMapLayers::TYPE_FOREGROUND); static CBackground gs_BackGround; +static CMenuBackground gs_MenuBackground; static CMapSounds gs_MapSounds; @@ -135,6 +137,7 @@ void CGameClient::OnConsoleInit() #endif // setup pointers + m_pMenuBackground = &::gs_MenuBackground; m_pBinds = &::gs_Binds; m_pGameConsole = &::gs_GameConsole; m_pParticles = &::gs_Particles; @@ -164,6 +167,8 @@ void CGameClient::OnConsoleInit() m_pRaceDemo = &::gs_RaceDemo; m_pGhost = &::gs_Ghost; + m_pMenus->SetMenuBackground(m_pMenuBackground); + gs_NamePlates.SetPlayers(m_pPlayers); // make a list of all the systems, make sure to add them in the correct render order @@ -207,6 +212,8 @@ void CGameClient::OnConsoleInit() m_All.Add(&m_pMenus->m_Binder); m_All.Add(m_pGameConsole); + m_All.Add(m_pMenuBackground); + // build the input stack m_Input.Add(&m_pMenus->m_Binder); // this will take over all input when we want to bind a key m_Input.Add(&m_pBinds->m_SpecialBinds); @@ -272,6 +279,8 @@ void CGameClient::OnConsoleInit() Console()->Chain("cl_dummy", ConchainSpecialDummy, this); Console()->Chain("cl_text_entities_size", ConchainClTextEntitiesSize, this); + Console()->Chain("cl_menu_map", ConchainMenuMap, this); + // m_SuppressEvents = false; } @@ -2536,3 +2545,18 @@ void CGameClient::ConTuneZone(IConsole::IResult *pResult, void *pUserData) if(List >= 0 && List < NUM_TUNEZONES) pSelf->TuningList()[List].Set(pParamName, NewValue); } + +void CGameClient::ConchainMenuMap(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData) +{ + CGameClient *pSelf = (CGameClient *)pUserData; + if(pResult->NumArguments()) + { + if(str_comp(g_Config.m_ClMenuMap, pResult->GetString(0)) != 0) + { + str_format(g_Config.m_ClMenuMap, sizeof(g_Config.m_ClMenuMap), "%s", pResult->GetString(0)); + pSelf->m_pMenuBackground->LoadMenuBackground(); + } + } + else + pfnCallback(pResult, pCallbackUserData); +} diff --git a/src/game/client/gameclient.h b/src/game/client/gameclient.h index a9d1d4333..447dcdaeb 100644 --- a/src/game/client/gameclient.h +++ b/src/game/client/gameclient.h @@ -122,6 +122,8 @@ class CGameClient : public IGameClient static void ConTuneZone(IConsole::IResult *pResult, void *pUserData); + static void ConchainMenuMap(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); + public: IKernel *Kernel() { return IInterface::Kernel(); } IEngine *Engine() const { return m_pEngine; } @@ -377,6 +379,7 @@ public: void SendKill(int ClientID); // pointers to all systems + class CMenuBackground *m_pMenuBackground; class CGameConsole *m_pGameConsole; class CBinds *m_pBinds; class CParticles *m_pParticles; From c0ca296c6313752f95736356bb137c6d93706c80 Mon Sep 17 00:00:00 2001 From: def Date: Sat, 19 Sep 2020 08:46:33 +0200 Subject: [PATCH 2/5] Add autumn theme by ChillerDragon based on heavens by Sonix- --- CMakeLists.txt | 3 +++ data/themes/autumn.png | Bin 0 -> 8520 bytes data/themes/autumn_day.map | Bin 0 -> 6995 bytes data/themes/autumn_night.map | Bin 0 -> 6792 bytes 4 files changed, 3 insertions(+) create mode 100644 data/themes/autumn.png create mode 100644 data/themes/autumn_day.map create mode 100644 data/themes/autumn_night.map diff --git a/CMakeLists.txt b/CMakeLists.txt index e0cdf738f..be46d54b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1280,6 +1280,9 @@ set(EXPECTED_DATA skins/x_ninja.png skins/x_spec.png themes/auto.png + themes/autumn.png + themes/autumn_day.map + themes/autumn_night.map themes/heavens.png themes/heavens_day.map themes/heavens_night.map diff --git a/data/themes/autumn.png b/data/themes/autumn.png new file mode 100644 index 0000000000000000000000000000000000000000..7dc7a596838e3b5492145fde1991c5e9d391c2fd GIT binary patch literal 8520 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 Jk}#+e{spofWJv%3 literal 0 HcmV?d00001 diff --git a/data/themes/autumn_night.map b/data/themes/autumn_night.map new file mode 100644 index 0000000000000000000000000000000000000000..46ba7d5e2b818928c4cf2c0226f992bd64ea9336 GIT binary patch literal 6792 zcmdUz4^&gv9mikt@=pjPVpS9>v54XT#fcOwRP4_t=;C)DN!;70i)BM($y+N)H*>>RKNjm-(QkPpU*_YIXh?DJ?E2m z^ZVW3zkBby?4&}^1cBB7hKZ4*<7yIIg-G$8PyrVBfB}H~ zy$DE7=3zh!6kq}%A3Yqy#NtY0IP@pGj)%YKBPxb^RHp0|a7D$7cr~}jnfk_|{ECQKe zGuQ?8gA@!A|f8PyC?M3Zb3?1G>wQWCvEzQ+n z;O+YQh-`7(dmYzTU`z3W`(UdU*iz1P=6IX4pU8H2AL9CpY(x8Cs}a~zu3>$!)rxFK z^})8k$aZueYy$+gG|v%$?uXXqh9*zJSZ=M?k~b!6Z&9vrg=T&*NcBQ^k?8wnj=wCiLM7 zn1(As&k0ZSaih86EagHzb;P0#fH18y;T7&^8(` z5sjyD{CGOwDW-6|R5Tvy-u3oFpX`O>Sr6lB9KE|x6ONaO#`F15PIQk@6ONaA7*BTe z9xKjAf$^`A6EuE*(L8+@L;)I)2m6y?&LDEk9X)%5dxx37DeAY2N+yz?TK&|=gO#G3 zNKUZ`dUd3$um;t0a>DQ@^P%sqoanuQo@s3j_ir^cU&ET-z3nciejZ{>gDurf?H0HW z62LLQ$B?1_0-zWzjfm0E*y1jRj~6lSz|UnsF@6VxG3fdFycoV-#3+ZKM<9#*6Rx?U zI_RDKc`?);V(@zeE zG4Y_E?F8N2;P;}4Em}2MXcd*eVPxwmWkiWUXhj|I|5iU8! zqkRyHk5OP4pnVdC4K9{%hkPg&g!~VNQUUzI8hoclaxvdv1Bhkxof?02esg~EdGfM* z@4F@k0&zb7)jSV7^G{kegHN^h>aMQG5R#ncFz!kzeB#&jeL_5|5Le<*J1qc-N>tPc2v8OU%~j{c&QS{wL|`r z8+ifzEOsNWfP9%7`5pLK>GyQK^nY3V$fxCZAs-m=bUw}r>*4tSY8>;2DMVO0{vAz% zfBASlo!QicdZ|E<>2oxpo)zh7PK0`yNRQH<(91=7dX5V16(T*=Ak-^GdOAggdc4we z^gcLfRM2G8#BGCz9{%z-b$;>nrjobLSJqU`j9NE3DcNRw1OF@zmWP;1W+g@bVD=9y zZF4IVXGhMejo4wFd0<}R{&}kNw(0{Z4D+eQ=K^du#-cBs$o!csb{fxDjh#I%4XdDM z*9s)5ki@g=1d?<}rm}BAVyvANbuM{_ZDvhWIHcd%BwqyS*rdoYJB(E}DXg$t@P1zKW? zY^{Y`Bv$36Jhj??zFIvuFfh=bw@^{Yv1`X_Z!w1hc7^y^Cm8+`bWXW)S)$ZFd(PzG zLuH3Q?9gk?1t~F1bpPR~_?_|x?d4hB<(z&)aiC%Sq@vvJkptL5&7R#~r>2DOcq665 zW*D-S9TXG$0;iM~X}2kuj=x4!no7p!bhqUGYtqK8Kabj`*8M|U`EqWp zZht*4uxEU<<=#5oN!DsK*980E97oXT@+LiRoK)f$!d4TdgtVawFc@fWTfmToWqwJN)xbaeWN zYzZ^IaY_PG`ALPPeqm)r>-v!K#j(=+8DHDwZSm`~!v|C>eszhWEV^Q?Zk5D7%Fq?k zFJ#*F(ka)MrW&M?%QM3V75H>3rCL9x<)6cfO(pMb?r7kCX;LVv7caGZ9#d2rTp>eA z6=zC&xWaTyh1s&(+%ZC1DzT5yEs_~``^ zZ^@rCf%|Y>SoSqe|KLUox2w^XGSqtQkKOuW&7SR_Z0^e4+juQEExR_|u;JE5-ANy7 zyZNZ5aDn7rmhPm=I=3uy`o0s}B2~wit$J)zul*uFcKXp^=BMwb9XFMHHKDD7`+k0n zI%)q>%Y!kx^7>bN;Wgv4&5!k$3f^vrV%dsKx(_7Qy@sy-g)P#x8trPyFQm-66XDZMCC#TKIIWn|W$nf+jgo#b zI9gXwXgDJ=l^pMBY~yA`W~!?-Ir2+izo_XAbr(w>Xue%Oixlw SPrBgt3&>BBFe$z-2K*aXu#wgP literal 0 HcmV?d00001 From d9719a3c1599c7b9edc8fc893ecca8ecc47c973b Mon Sep 17 00:00:00 2001 From: def Date: Sat, 19 Sep 2020 08:53:26 +0200 Subject: [PATCH 3/5] Fix spacing in themes selection --- src/game/client/components/menus.cpp | 5 ++--- src/game/client/components/menus_settings.cpp | 4 +++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/game/client/components/menus.cpp b/src/game/client/components/menus.cpp index 515cb9786..88ecf7e55 100644 --- a/src/game/client/components/menus.cpp +++ b/src/game/client/components/menus.cpp @@ -2064,7 +2064,7 @@ void CMenus::RenderThemeSelection(CUIRect MainView, bool Header) static int s_ListBox = 0; static float s_ScrollValue = 0.0f; - UiDoListboxStart(&s_ListBox, &MainView, 26.0f, Localize("Themes"), "", ThemesRef.size(), 1, -1, s_ScrollValue); + UiDoListboxStart(&s_ListBox, &MainView, 26.0f, Localize("Theme"), "", ThemesRef.size(), 1, -1, s_ScrollValue); for(int i = 0; i < (int)ThemesRef.size(); i++) { @@ -2107,8 +2107,7 @@ void CMenus::RenderThemeSelection(CUIRect MainView, bool Header) else // generic str_format(aName, sizeof(aName), "%s", Theme.m_Name.cstr()); - Item.m_Rect.y += 2.0f; - UI()->DoLabel(&Item.m_Rect, aName, Item.m_Rect.h * ms_FontmodHeight * 0.8f, -1); + UI()->DoLabel(&Item.m_Rect, aName, 16 * ms_FontmodHeight, -1); } bool ItemActive = false; diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp index 275609eca..dab56f1db 100644 --- a/src/game/client/components/menus_settings.cpp +++ b/src/game/client/components/menus_settings.cpp @@ -76,7 +76,7 @@ void CMenus::RenderSettingsGeneral(CUIRect MainView) char aBuf[128]; CUIRect Label, Button, Left, Right, Game, Client; - MainView.HSplitTop(180.0f, &Game, &Client); + MainView.HSplitTop(150.0f, &Game, &Client); // game { @@ -178,6 +178,7 @@ void CMenus::RenderSettingsGeneral(CUIRect MainView) if(DoButton_CheckBox(&g_Config.m_ClAutoDemoRecord, Localize("Automatically record demos"), g_Config.m_ClAutoDemoRecord, &Button)) g_Config.m_ClAutoDemoRecord ^= 1; + Right.HSplitTop(30.0f, 0, &Right); Right.HSplitTop(20.0f, &Button, &Right); if(DoButton_CheckBox(&g_Config.m_ClAutoScreenshot, Localize("Automatically take game over screenshot"), g_Config.m_ClAutoScreenshot, &Button)) g_Config.m_ClAutoScreenshot ^= 1; @@ -233,6 +234,7 @@ void CMenus::RenderSettingsGeneral(CUIRect MainView) m_NeedRestartGeneral = s_ClShowConsole != g_Config.m_ClShowConsole; #endif + Left.HSplitTop(20.0f, 0, &Left); RenderThemeSelection(Left); // auto statboard screenshot From 3e78bdc076b885ab7e3d84e15e05d7f424ec19e5 Mon Sep 17 00:00:00 2001 From: def Date: Wed, 23 Sep 2020 08:10:13 +0200 Subject: [PATCH 4/5] Remove flickering in autumn_night --- data/themes/autumn_night.map | Bin 6792 -> 6696 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/data/themes/autumn_night.map b/data/themes/autumn_night.map index 46ba7d5e2b818928c4cf2c0226f992bd64ea9336..bfcc73d885aa0077df03709bc282d4f866597e5c 100644 GIT binary patch delta 440 zcmeA$U11{Y;uzw{!oa{FA;rM(M1+BX6Uep)Vrd|ruu;~VQL#dhfnf#^?*QT(K>P!U zC4?9lEPyxyh$}XCG6u6Ta&NxN?$5-?G+CERA4tZ6$&K8?lNWHw0Qq~t{I_6ImK&tv zA-DMC6mCPAKVE!U1v@o>_JKiyl+qJ+237`;0Mq1+P^BK&lyL%;#ekLZ@=8xm;L*jV zhzmv05$uY%krZLIiU+QskQb{0Ubup**cI@>6@VQ3hg)WH0iPf?2lE3JLOeg0Pn%I- X^GUvJmdQTC5|e9$4L08qUc&|ei;r5S delta 558 zcmZ2s(qSs=;uzw{!oa{#A;rMpBFezP31r&?u{02W*eL7GsCYw=f#C-bO9(MASO9SZ z5LW>43?SYC#5Xo~G6u6T@^8M&?$5-?Fj<#NA4tZ6$&K8?lNWHw0Qq~t{I_6ImK&tv zA-DMC6mCPAuv*>4QFAPT_JP3z=U?LN46F6@VQ3hg)WH0iPf?2lE3JLOeg0Pn)q| z^GUvJ7LPVA1_nluS3z+F#kK4V3_V!HZ!j@1ti>XJ`v3p`lYN8@43xMr4Ql~PMq?2_ M3>4p7BfN$U09jyd8~^|S From 7fe7d1266837da70a9c7353f28824579c89ddea1 Mon Sep 17 00:00:00 2001 From: ChillerDragon Date: Wed, 23 Sep 2020 11:11:28 +0200 Subject: [PATCH 5/5] Remove tree from autumn icon --- data/themes/autumn.png | Bin 8520 -> 7733 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/data/themes/autumn.png b/data/themes/autumn.png index 7dc7a596838e3b5492145fde1991c5e9d391c2fd..f313b4fee772591870bb37dcc20f333c1d1c4b9e 100644 GIT binary patch delta 7720 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