1/*
2 * LegacyClonk
3 *
4 * Copyright (c) RedWolf Design
5 * Copyright (c) 2017-2020, The LegacyClonk Team and contributors
6 *
7 * Distributed under the terms of the ISC license; see accompanying file
8 * "COPYING" for details.
9 *
10 * "Clonk" is a registered trademark of Matthes Bender, used with permission.
11 * See accompanying file "TRADEMARK" for details.
12 *
13 * To redistribute this file separately, substitute the full license texts
14 * for the above references.
15 */
16
17#include <C4Include.h>
18#include <C4UpperBoard.h>
19
20#include <C4Game.h>
21#include <C4Config.h>
22#include <C4Application.h>
23
24C4UpperBoard::C4UpperBoard()
25{
26 Default();
27}
28
29C4UpperBoard::~C4UpperBoard()
30{
31 Clear();
32}
33
34void C4UpperBoard::Default() {}
35
36void C4UpperBoard::Clear() {}
37
38void C4UpperBoard::Execute()
39{
40 if (Config.Graphics.UpperBoard == Hide) return;
41 // Make the time strings
42 FormatWithNull(buf&: cTimeString, fmt: "{:02}:{:02}:{:02}", args: Game.Time / 3600, args: (Game.Time % 3600) / 60, args: Game.Time % 60);
43 time_t t = time(timer: nullptr); strftime(s: cTimeString2, maxsize: sizeof(cTimeString2), format: "[%H:%M:%S]", tp: localtime(timer: &t));
44 Draw(cgo&: Output);
45}
46
47void C4UpperBoard::Draw(C4Facet &cgo)
48{
49 if (!cgo.Surface) return;
50 const auto mode = Config.Graphics.UpperBoard;
51 if (mode != Mini)
52 {
53 // Background
54 Application.DDraw->BlitSurfaceTile(sfcSurface: Game.GraphicsResource.fctUpperBoard.Surface, sfcTarget: Output.Surface, iToX: 0, iToY: 0, iToWdt: Output.Wdt, iToHgt: Output.Hgt, iOffsetX: 0, iOffsetY: 0, fSrcColKey: false, scale: mode == Small ? 0.5f : 1.f);
55 // Logo
56 C4Facet cgo2;
57 float fLogoZoom;
58 if (static_cast<float>(Game.GraphicsResource.fctLogo.Wdt) / Game.GraphicsResource.fctLogo.Hgt != 3.f)
59 {
60 // old logo factor
61 fLogoZoom = 0.25f;
62 }
63 else
64 {
65 fLogoZoom = 0.21f;
66 }
67 fLogoZoom *= 960.f / Game.GraphicsResource.fctLogo.Wdt;
68 if (mode == Small) fLogoZoom *= 8.f / 15.f;
69 cgo2.Set(nsfc: cgo.Surface, nx: static_cast<int32_t>(cgo.Wdt / 2 - (Game.GraphicsResource.fctLogo.Wdt / 2) * fLogoZoom), ny: 0,
70 nwdt: static_cast<int32_t>(Game.GraphicsResource.fctLogo.Wdt * fLogoZoom), nhgt: static_cast<int32_t>(Game.GraphicsResource.fctLogo.Hgt * fLogoZoom));
71 Game.GraphicsResource.fctLogo.Draw(cgo&: cgo2);
72 }
73
74 // Right text sections
75 int32_t iRightOff = 1;
76 // Playing time
77 Application.DDraw->TextOut(szText: cTimeString, rFont&: Game.GraphicsResource.FontRegular, fZoom: 1.0, sfcDest: cgo.Surface, iTx: Output.X + Output.Wdt - (iRightOff++) * TextWidth - 10, iTy: TextYPosition, dwFCol: 0xFFFFFFFF);
78 // Clock
79 if (Config.Graphics.ShowClock)
80 Application.DDraw->TextOut(szText: cTimeString2, rFont&: Game.GraphicsResource.FontRegular, fZoom: 1.0, sfcDest: cgo.Surface, iTx: Output.X + Output.Wdt - (iRightOff++) * TextWidth - 30, iTy: TextYPosition, dwFCol: 0xFFFFFFFF);
81 // FPS
82 if (Config.General.FPS)
83 {
84 FormatWithNull(buf&: cTimeString, fmt: "{} FPS", args&: Game.FPS);
85 Application.DDraw->TextOut(szText: cTimeString, rFont&: Game.GraphicsResource.FontRegular, fZoom: 1.0, sfcDest: cgo.Surface, iTx: Output.X + Output.Wdt - (iRightOff++) * TextWidth - 30, iTy: TextYPosition, dwFCol: 0xFFFFFFFF);
86 }
87 if (mode != Mini)
88 {
89 // Scenario title
90 Application.DDraw->TextOut(szText: Game.Parameters.ScenarioTitle.getData(), rFont&: Game.GraphicsResource.FontRegular, fZoom: 1.0, sfcDest: cgo.Surface, iTx: 10, iTy: cgo.Hgt / 2 - Game.GraphicsResource.FontRegular.GetLineHeight() / 2, dwFCol: 0xFFFFFFFF);
91 }
92}
93
94int C4UpperBoard::Height()
95{
96 const auto mode = Config.Graphics.UpperBoard;
97 if (mode == Hide || mode == Mini) return 0;
98 if (mode == Small) return C4UpperBoardHeight / 2;
99 return C4UpperBoardHeight;
100}
101
102void C4UpperBoard::Init(C4Facet &cgo, C4Facet &messageBoardCgo)
103{
104 FormatWithNull(buf&: cTimeString, fmt: "{:02}:{:02}:{:02}", args: Game.Time / 3600, args: (Game.Time % 3600) / 60, args: Game.Time % 60);
105 TextWidth = Game.GraphicsResource.FontRegular.GetTextWidth(szText: cTimeString);
106 if (Config.Graphics.UpperBoard == Mini)
107 {
108 const auto xStart = messageBoardCgo.Wdt - TextWidth * 3 - 30;
109 Output.Set(nsfc: messageBoardCgo.Surface, nx: xStart + messageBoardCgo.X, ny: messageBoardCgo.Y, nwdt: messageBoardCgo.Wdt - xStart, nhgt: messageBoardCgo.Hgt);
110 messageBoardCgo.Wdt -= Output.Wdt;
111
112 TextYPosition = Output.Y + Output.Hgt / 2 - Game.GraphicsResource.FontRegular.GetLineHeight() / 2;
113 }
114 else
115 {
116 // Save facet
117 Output = cgo;
118 if (!Game.GraphicsResource.fctUpperBoard.Surface) return;
119 // in newgfx, the upperboard may be larger and overlap the scene
120 Output.Hgt = (std::max)(a: Output.Hgt, b: Config.Graphics.UpperBoard == Small ? Game.GraphicsResource.fctUpperBoard.Hgt / 2 : Game.GraphicsResource.fctUpperBoard.Hgt);
121 // surface should not be too small
122 Game.GraphicsResource.fctUpperBoard.EnsureSize(iMinWdt: 128, iMinHgt: Output.Hgt);
123 // Generate textposition
124 TextYPosition = cgo.Hgt / 2 - Game.GraphicsResource.FontRegular.GetLineHeight() / 2;
125 }
126}
127