OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
C4MessageBoard.cpp
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 1998-2000, Matthes Bender
5  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
6  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
7  *
8  * Distributed under the terms of the ISC license; see accompanying file
9  * "COPYING" for details.
10  *
11  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
12  * See accompanying file "TRADEMARK" for details.
13  *
14  * To redistribute this file separately, substitute the full license texts
15  * for the above references.
16  */
17 
18 /* Fullscreen startup log and chat type-in */
19 
20 #include "C4Include.h"
21 #include "gui/C4MessageBoard.h"
22 
23 #include "game/C4Application.h"
24 #include "game/C4FullScreen.h"
25 #include "game/C4GraphicsSystem.h"
26 #include "graphics/C4Draw.h"
28 #include "gui/C4Gui.h"
29 #include "gui/C4LoaderScreen.h"
30 #include "gui/C4MessageInput.h"
31 #include "lib/StdColors.h"
32 #include "player/C4Player.h"
33 #include "player/C4PlayerList.h"
34 
35 const int C4LogSize=30000, C4LogMaxLines=1000;
36 
38 {
39  Delay = -1;
40  Fader = 0;
41  Speed = 2;
42  Output.Default();
43  Startup = false;
44  ScreenFader = 0;
45  iBackScroll = -1;
46  ScrollUpBinding = nullptr;
47  ScrollDownBinding = nullptr;
48 }
49 
51 {
52  LogBuffer.Clear();
53  LogBuffer.SetLBWidth(0);
54 }
55 
57 {
58  // Startup? draw only
59  if (Startup) { Draw(Output); return; }
60 
61  // typein or messages waiting? fade in
62  if (::MessageInput.IsTypeIn() || iBackScroll >= 0)
63  ScreenFader = std::max(ScreenFader - 0.20f, -1.0f);
64 
65  // no curr msg?
66  if (iBackScroll<0)
67  {
68  // draw anyway
69  Draw(Output);
70  if (!::MessageInput.IsTypeIn())
71  ScreenFader = std::min(ScreenFader + 0.05f, 1.0f);
72  return;
73  }
74 
75  // recalc fade/delay speed
76  Speed = std::max(1, iBackScroll / 5);
77  // fade msg in?
78  if (Fader > 0)
79  Fader = std::max(Fader - Speed, 0);
80  // hold curr msg? (delay)
81  if (Fader <= 0)
82  {
83  // no delay set yet?
84  if (Delay == -1)
85  {
86  // set delay based on msg length
87  const char *szCurrMsg = LogBuffer.GetLine(std::min(-iBackScroll, -1), nullptr, nullptr, nullptr);
88  if (szCurrMsg) Delay = strlen(szCurrMsg); else Delay = 0;
89  }
90  // wait...
91  if (Delay > 0) Delay = std::max(Delay - Speed, 0);
92  // end of delay
93  if (Delay == 0)
94  {
95  // set cursor to next msg (or at end of log)
96  iBackScroll = std::max(iBackScroll - 1, -1);
97  // reset fade
98  Fader = iLineHgt;
99  Delay = -1;
100  }
101  }
102 
103  // Draw
104  Draw(Output);
105 }
106 
107 void C4MessageBoard::Init(C4Facet &cgo, bool fStartup)
108 {
109  Output=cgo;
110  Startup=fStartup;
112  LogBuffer.SetLBWidth(Output.Wdt);
113 
114  if (!Startup)
115  {
116  // set cursor to end of log
117  iBackScroll = -1;
118  Fader = 0;
119  Speed = 2;
120  ScreenFader = 1.0f; // msgs faded out
121 
122  LogBuffer.SetLBWidth(Output.Wdt);
123  }
124 
125  // messageboard
126  ScrollUpBinding = std::make_unique<C4KeyBinding>(C4KeyCodeEx(K_UP, KEYS_Shift), "MsgBoardScrollUp", KEYSCOPE_Fullscreen, new C4KeyCB <C4MessageBoard>(*GraphicsSystem.MessageBoard, &C4MessageBoard::ControlScrollUp));
127  ScrollDownBinding = std::make_unique<C4KeyBinding>(C4KeyCodeEx(K_DOWN, KEYS_Shift), "MsgBoardScrollDown", KEYSCOPE_Fullscreen, new C4KeyCB <C4MessageBoard>(*GraphicsSystem.MessageBoard, &C4MessageBoard::ControlScrollDown));
128 }
129 
131 {
132  if (!Application.Active) return;
133 
134  // Startup: draw Loader
135  if (Startup)
136  {
139  else
140  // loader not yet loaded: black BG
141  pDraw->DrawBoxDw(cgo.Surface, 0,0, cgo.Wdt, cgo.Hgt, 0x00000000);
142  return;
143  }
144 
145  // Game running: message fader
146 
147  // draw messages
148  // how many "extra" messages should be shown?
149  int iMsgFader = C4MSGB_MaxMsgFading;
150  // check screenfader range
151  if (ScreenFader >= 1.0f)
152  {
153  return;
154  }
156  // show msgs
157  for (int iMsg = -iMsgFader; iMsg < 0; iMsg++)
158  {
159  // get message at pos
160  if (iMsg-iBackScroll >= 0) break;
161  const char *Message = LogBuffer.GetLine(iMsg-iBackScroll, nullptr, nullptr, nullptr);
162  if (!Message || !*Message) continue;
163  // calc target position (y)
164  int iMsgY = cgo.Y + cgo.Hgt + iMsg * iLineHgt + Fader;
165 
166  // player message color?
167  C4Player *pPlr = GetMessagePlayer(Message);
168 
169  DWORD dwColor;
170  if (pPlr)
171  dwColor = PlrClr2TxtClr(pPlr->ColorDw) & 0xffffff;
172  else
173  dwColor = 0xffffff;
174  // fade out (msg fade)
175  float fade = std::max(ScreenFader, 0.0f) + ((iMsg + 2.0f + float(Fader) / iLineHgt) / std::min(2-iMsgFader, -1));
176  DWORD dwFade = (0xff - Clamp(int(fade * 0xff), 0, 0xff)) << 24;
177  dwColor |= dwFade;
178  // Draw
179  pDraw->StringOut(Message,::GraphicsResource.FontRegular,1.0,cgo.Surface,cgo.X,iMsgY,dwColor);
180  }
181 }
182 
184 {
185  // Ingore if startup or typein
186  if (Startup) return;
187  // scroll until end of log
188  for (int i = 0; i < 100; i++)
189  {
191  Execute();
192  if (iBackScroll < 0) break;
193  Delay=0;
194  }
195 }
196 
197 void C4MessageBoard::AddLog(const char *szMessage)
198 {
199  // safety
200  if (!szMessage || !*szMessage) return;
201  // make sure new message will be drawn
202  ++iBackScroll;
203  // register message in standard messageboard font
204  LogBuffer.AppendLines(szMessage, &::GraphicsResource.FontRegular, 0, nullptr);
205 }
206 
208 {
209  LogBuffer.Clear();
210 }
211 
213 {
214  // do not show startup board if GUI is active
215  if (::pGUI->IsActive()) return;
216  // Reset
217  iBackScroll=0;
218  // Draw
219  if (pDraw)
220  {
221  Draw(Output);
222  // startup: Draw message board only and do page flip
223  if (Startup) FullScreen.pSurface->PageFlip();
224  }
225 }
226 
228 {
229  // Scan message text for heading player name
230  if (SEqual2(szMessage, "* "))
231  {
232  StdStrBuf str;
233  str.CopyUntil(szMessage + 2,' ');
235  }
236  if (SCharCount(':',szMessage))
237  {
238  StdStrBuf str;
239  str.CopyUntil(szMessage + 2,':');
241  }
242  return nullptr;
243 }
244 
246 {
247  Delay=-1; Fader=0;
248  iBackScroll++;
249  return true;
250 }
251 
253 {
254  Delay=-1; Fader=0;
255  if (iBackScroll > -1) iBackScroll--;
256  return true;
257 }
const char * getData() const
Definition: StdBuf.h:442
int GetLineHeight() const
Definition: C4FontLoader.h:125
float Y
Definition: C4Facet.h:118
const char * GetLine(int iLineIndex, CStdFont **ppFont, DWORD *pdwClr, bool *pNewParagraph) const
Definition: C4LogBuf.cpp:244
C4Game Game
Definition: C4Globals.cpp:52
void SetLBWidth(int iToWidth)
Definition: C4LogBuf.cpp:278
void Draw(C4Facet &cgo)
C4Surface * pSurface
Definition: C4Window.h:274
void AddLog(const char *szMessage)
void AppendLines(const char *szLine, CStdFont *pFont, DWORD dwClr, CStdFont *pFirstLineFont=nullptr)
Definition: C4LogBuf.cpp:170
C4FullScreen FullScreen
Definition: C4Globals.cpp:46
C4MessageInput MessageInput
const int C4MSGB_MaxMsgFading
bool IsActive()
Definition: C4Gui.h:2630
C4GraphicsResource GraphicsResource
unsigned int SCharCount(char cTarget, const char *szInStr, const char *cpUntil)
Definition: Standard.cpp:320
bool StringOut(const char *szText, CStdFont &rFont, float fZoom, C4Surface *sfcDest, float iTx, float iTy, DWORD dwFCol=0xffffffff, BYTE byForm=ALeft, bool fDoMarkup=true)
Definition: C4Draw.cpp:576
void Clear()
Definition: C4LogBuf.cpp:272
T Clamp(T bval, T lbound, T rbound)
Definition: Standard.h:44
uint32_t ColorDw
Definition: C4Player.h:89
const int C4LogMaxLines
int32_t InitProgress
Definition: C4Game.h:133
C4GUIScreen * pGUI
Definition: C4Gui.cpp:1191
bool Active
Definition: C4App.h:63
void Draw(C4Facet &cgo, int iProgress=0, class C4LogBuffer *pLog=nullptr, int Process=0)
bool PageFlip(C4Rect *pSrcRt=nullptr, C4Rect *pDstRt=nullptr)
Definition: C4Surface.cpp:310
void Default()
Definition: C4Facet.cpp:31
C4GraphicsSystem GraphicsSystem
Definition: C4Globals.cpp:51
void DrawBoxDw(C4Surface *sfcDest, int iX1, int iY1, int iX2, int iY2, DWORD dwClr)
Definition: C4Draw.cpp:846
C4PlayerList Players
C4Player * GetMessagePlayer(const char *szMessage)
C4Draw * pDraw
Definition: C4Draw.cpp:42
C4LoaderScreen * pLoaderScreen
const int C4LogSize
void Init(C4Facet &cgo, bool fStartup)
void CopyUntil(const char *szString, char cUntil)
Definition: StdBuf.h:613
float Hgt
Definition: C4Facet.h:118
std::unique_ptr< C4MessageBoard > MessageBoard
bool SEqual2(const char *szStr1, const char *szStr2)
Definition: Standard.cpp:198
C4Surface * Surface
Definition: C4Facet.h:117
C4Player * GetByName(const char *szName, int iExcluding=NO_OWNER) const
uint32_t DWORD
DWORD PlrClr2TxtClr(DWORD dwClr)
Definition: StdColors.h:104
float Wdt
Definition: C4Facet.h:118
float X
Definition: C4Facet.h:118
C4Application Application
Definition: C4Globals.cpp:44