1#include "menus.h"
2
3#include <engine/graphics.h>
4#include <engine/textrender.h>
5
6#include <game/client/ui.h>
7#include <game/client/ui_scrollregion.h>
8
9void CMenus::RenderSettingsCredits(CUIRect MainView)
10{
11 static constexpr const char *const CREDITS =
12 "\n"
13 "Help and code by eeeee, HMH, east, CookieMichal, Learath2, "
14 "Savander, laxa, Tobii, BeaR, Wohoo, nuborn, timakro, Shiki, "
15 "trml, Soreu, hi_leute_gll, Lady Saavik, Chairn, heinrich5991, "
16 "swick, oy, necropotame, Ryozuki, Redix, d3fault, marcelherd, "
17 "BannZay, ACTom, SiuFuWong, PathosEthosLogos, TsFreddie, "
18 "Jupeyy, noby, ChillerDragon, ZombieToad, weez15, z6zzz, "
19 "Piepow, QingGo, RafaelFF, sctt, jao, daverck, fokkonaut, "
20 "Bojidar, FallenKN, ardadem, archimede67, sirius1242, Aerll, "
21 "trafilaw, Zwelf, Patiga, Konsti, ElXreno, MikiGamer, "
22 "Fireball, Banana090, axblk, yangfl, Kaffeine, Zodiac, "
23 "c0d3d3v, GiuCcc, Ravie, Robyt3, simpygirl, Tater, Cellegen, "
24 "srdante, Nouaa, Voxel, luk51, Vy0x2, Avolicious, louis, "
25 "Marmare314, hus3h, ArijanJ, tarunsamanta2k20, Possseidon, "
26 "+KZ, Teero, furo, dobrykafe, Moiman, JSaurusRex, "
27 "Steinchen, ewancg, gerdoe-jr, melon, KebsCS, bencie, "
28 "DynamoFox, MilkeeyCat, iMilchshake, SchrodingerZhu, "
29 "catseyenebulous, Rei-Tw, Matodor, Emilcha, art0007i, SollyBunny, "
30 "0xfaulty, AssassinTee, Pioooooo, ASKLL-STAR, K1nop1c0, "
31 "Bamcane, qxdFox, ZerolAcqua, swarfeya, Scrumplex, 12944qwerty, "
32 "Pointer31, ProfSapphire, 0xpixty, GlimmeR, horoni & others\n"
33 "\n"
34 "Based on DDRace by the DDRace developers,";
35 const float FontSize = 16.0f;
36
37 static CScrollRegion s_ScrollRegion;
38 CScrollRegionParams ScrollParams;
39 ScrollParams.m_ScrollUnit = 3.0f * FontSize;
40 s_ScrollRegion.Begin(pClipRect: &MainView, pParams: &ScrollParams);
41
42 const auto &&RenderCreditsLink = [&](const void *pLinkId, const char *pPrefix, const char *pLink, const char *pSuffix, const char *pUrl) {
43 const float LineHeight = TextRender()->TextBoundingBox(Size: FontSize, pText: pLink).m_H;
44 const float PrefixWidth = TextRender()->TextWidth(Size: FontSize, pText: pPrefix);
45 const bool PrefixOwnLine = PrefixWidth + TextRender()->TextWidth(Size: FontSize, pText: pLink) + TextRender()->TextWidth(Size: FontSize, pText: pSuffix) > MainView.w;
46
47 CUIRect Line, Prefix, LinkRect;
48 MainView.HSplitTop(Cut: LineHeight, pTop: &Line, pBottom: &MainView);
49 s_ScrollRegion.AddRect(Rect: Line);
50 if(PrefixOwnLine)
51 {
52 Ui()->DoLabel(pRect: &Line, pText: pPrefix, Size: FontSize, Align: TEXTALIGN_TL);
53 MainView.HSplitTop(Cut: LineHeight, pTop: &Line, pBottom: &MainView);
54 s_ScrollRegion.AddRect(Rect: Line);
55 }
56 else
57 {
58 Line.VSplitLeft(Cut: PrefixWidth, pLeft: &Prefix, pRight: &Line);
59 Ui()->DoLabel(pRect: &Prefix, pText: pPrefix, Size: FontSize, Align: TEXTALIGN_TL);
60 }
61
62 Line.VSplitLeft(Cut: TextRender()->TextWidth(Size: FontSize, pText: pLink), pLeft: &LinkRect, pRight: &Line);
63 const ColorRGBA LinkColor = Ui()->HotItem() == pLinkId ? ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f) : ColorRGBA(0.4f, 0.7f, 1.0f, 1.0f);
64 TextRender()->TextColor(Color: LinkColor);
65 Ui()->DoLabel(pRect: &LinkRect, pText: pLink, Size: FontSize, Align: TEXTALIGN_TL);
66 TextRender()->TextColor(Color: TextRender()->DefaultTextColor());
67
68 CUIRect Underline;
69 LinkRect.HSplitBottom(Cut: 1.0f, pTop: nullptr, pBottom: &Underline);
70 Underline.Draw(Color: LinkColor, Corners: IGraphics::CORNER_NONE, Rounding: 0.0f);
71
72 if(Ui()->DoButtonLogic(pId: pLinkId, Checked: 0, pRect: &LinkRect, Flags: BUTTONFLAG_LEFT))
73 {
74 Client()->ViewLink(pLink: pUrl);
75 }
76
77 Ui()->DoLabel(pRect: &Line, pText: pSuffix, Size: FontSize, Align: TEXTALIGN_TL);
78 };
79
80 static char s_StaffLinkId;
81 RenderCreditsLink(&s_StaffLinkId, "DDNet is run by the ", "DDNet staff", ".", "https://ddnet.org/staff");
82 static char s_MapsLinkId;
83 RenderCreditsLink(&s_MapsLinkId, "", "Great maps", " and many ideas from the community.", "https://ddnet.org/releases/");
84
85 CTextCursor Cursor;
86 Cursor.m_FontSize = FontSize;
87 Cursor.m_LineWidth = MainView.w;
88
89 const unsigned OldRenderFlags = TextRender()->GetRenderFlags();
90 TextRender()->SetRenderFlags(OldRenderFlags | TEXT_RENDER_FLAG_ONE_TIME_USE);
91 STextContainerIndex CreditsTextContainer;
92 TextRender()->CreateTextContainer(TextContainerIndex&: CreditsTextContainer, pCursor: &Cursor, pText: CREDITS);
93 TextRender()->SetRenderFlags(OldRenderFlags);
94 if(CreditsTextContainer.Valid())
95 {
96 CUIRect CreditsLabel;
97 MainView.HSplitTop(Cut: TextRender()->GetBoundingBoxTextContainer(TextContainerIndex: CreditsTextContainer).m_H, pTop: &CreditsLabel, pBottom: &MainView);
98 s_ScrollRegion.AddRect(Rect: CreditsLabel);
99 TextRender()->RenderTextContainer(TextContainerIndex: CreditsTextContainer, TextColor: TextRender()->DefaultTextColor(), TextOutlineColor: TextRender()->DefaultTextOutlineColor(), X: CreditsLabel.x, Y: CreditsLabel.y);
100 TextRender()->DeleteTextContainer(TextContainerIndex&: CreditsTextContainer);
101 }
102
103 static char s_TeeworldsLinkId;
104 RenderCreditsLink(&s_TeeworldsLinkId, "which is a mod of ", "Teeworlds", " by the Teeworlds developers.", "https://teeworlds.com/");
105
106 s_ScrollRegion.End();
107}
108