openclonk/src/gui/C4MessageBoard.cpp

259 lines
6.3 KiB
C++
Raw Normal View History

2009-05-08 13:28:41 +00:00
/*
* OpenClonk, http://www.openclonk.org
*
* Copyright (c) 1998-2000, Matthes Bender
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
2016-04-03 18:18:29 +00:00
* Copyright (c) 2009-2016, The OpenClonk Team and contributors
2009-05-08 13:28:41 +00:00
*
* Distributed under the terms of the ISC license; see accompanying file
* "COPYING" for details.
2009-05-08 13:28:41 +00:00
*
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
* See accompanying file "TRADEMARK" for details.
2009-05-08 13:28:41 +00:00
*
* To redistribute this file separately, substitute the full license texts
* for the above references.
2009-05-08 13:28:41 +00:00
*/
/* Fullscreen startup log and chat type-in */
#include "C4Include.h"
#include "gui/C4MessageBoard.h"
2009-05-08 13:28:41 +00:00
#include "game/C4Application.h"
#include "game/C4FullScreen.h"
#include "game/C4GraphicsSystem.h"
#include "graphics/C4Draw.h"
#include "graphics/C4GraphicsResource.h"
#include "gui/C4Gui.h"
#include "gui/C4LoaderScreen.h"
#include "gui/C4MessageInput.h"
#include "lib/StdColors.h"
#include "player/C4Player.h"
#include "player/C4PlayerList.h"
2009-05-08 13:28:41 +00:00
const int C4LogSize=30000, C4LogMaxLines=1000;
C4MessageBoard::C4MessageBoard() : LogBuffer(C4LogSize, C4LogMaxLines, 0, " ", false)
2010-03-28 18:58:01 +00:00
{
Delay = -1;
Fader = 0;
Speed = 2;
2009-05-08 13:28:41 +00:00
Output.Default();
Startup = false;
ScreenFader = 0;
2009-05-08 13:28:41 +00:00
iBackScroll = -1;
ScrollUpBinding = nullptr;
ScrollDownBinding = nullptr;
iLineHgt = 1; // Prevent unitialized access with USE_CONSOLE
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
C4MessageBoard::~C4MessageBoard()
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
LogBuffer.Clear();
LogBuffer.SetLBWidth(0);
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MessageBoard::Execute()
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Startup? draw only
2010-03-28 18:58:01 +00:00
if (Startup) { Draw(Output); return; }
2009-05-08 13:28:41 +00:00
// typein or messages waiting? fade in
if (::MessageInput.IsTypeIn() || iBackScroll >= 0)
ScreenFader = std::max(ScreenFader - 0.20f, -1.0f);
2009-05-08 13:28:41 +00:00
// no curr msg?
if (iBackScroll<0)
{
// draw anyway
Draw(Output);
if (!::MessageInput.IsTypeIn())
ScreenFader = std::min(ScreenFader + 0.05f, 1.0f);
return;
}
2009-05-08 13:28:41 +00:00
// recalc fade/delay speed
Speed = std::max(1, iBackScroll / 5);
// fade msg in?
if (Fader > 0)
Fader = std::max(Fader - Speed, 0);
// hold curr msg? (delay)
if (Fader <= 0)
{
// no delay set yet?
if (Delay == -1)
2009-05-08 13:28:41 +00:00
{
// set delay based on msg length
const char *szCurrMsg = LogBuffer.GetLine(std::min(-iBackScroll, -1), nullptr, nullptr, nullptr);
if (szCurrMsg) Delay = strlen(szCurrMsg); else Delay = 0;
2009-05-08 13:28:41 +00:00
}
// wait...
if (Delay > 0) Delay = std::max(Delay - Speed, 0);
// end of delay
if (Delay == 0)
2009-05-08 13:28:41 +00:00
{
// set cursor to next msg (or at end of log)
iBackScroll = std::max(iBackScroll - 1, -1);
2009-05-08 13:28:41 +00:00
// reset fade
Fader = iLineHgt;
Delay = -1;
2009-05-08 13:28:41 +00:00
}
}
// Draw
Draw(Output);
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MessageBoard::Init(C4Facet &cgo, bool fStartup)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
Output=cgo;
Startup=fStartup;
2013-10-18 16:49:21 +00:00
iLineHgt=::GraphicsResource.FontRegular.GetLineHeight();
2009-05-08 13:28:41 +00:00
LogBuffer.SetLBWidth(Output.Wdt);
2010-03-28 18:58:01 +00:00
if (!Startup)
2009-05-08 13:28:41 +00:00
{
// set cursor to end of log
iBackScroll = -1;
Fader = 0;
Speed = 2;
ScreenFader = 1.0f; // msgs faded out
LogBuffer.SetLBWidth(Output.Wdt);
2009-05-08 13:28:41 +00:00
}
// messageboard
ScrollUpBinding = std::make_unique<C4KeyBinding>(C4KeyCodeEx(K_UP, KEYS_Shift), "MsgBoardScrollUp", KEYSCOPE_Fullscreen, new C4KeyCB <C4MessageBoard>(*GraphicsSystem.MessageBoard, &C4MessageBoard::ControlScrollUp));
ScrollDownBinding = std::make_unique<C4KeyBinding>(C4KeyCodeEx(K_DOWN, KEYS_Shift), "MsgBoardScrollDown", KEYSCOPE_Fullscreen, new C4KeyCB <C4MessageBoard>(*GraphicsSystem.MessageBoard, &C4MessageBoard::ControlScrollDown));
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MessageBoard::Draw(C4Facet &cgo)
2010-03-28 18:58:01 +00:00
{
if (!Application.Active) return;
2009-05-08 13:28:41 +00:00
// Startup: draw Loader
if (Startup)
2010-03-28 18:58:01 +00:00
{
if (::GraphicsSystem.pLoaderScreen)
2017-08-26 23:12:56 +00:00
::GraphicsSystem.pLoaderScreen->Draw(cgo, C4LoaderScreen::Flag::ALL, Game.InitProgress, &LogBuffer);
2009-05-08 13:28:41 +00:00
else
// loader not yet loaded: black BG
2011-10-03 14:30:18 +00:00
pDraw->DrawBoxDw(cgo.Surface, 0,0, cgo.Wdt, cgo.Hgt, 0x00000000);
2009-05-08 13:28:41 +00:00
return;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Game running: message fader
// draw messages
// how many "extra" messages should be shown?
int iMsgFader = C4MSGB_MaxMsgFading;
// check screenfader range
if (ScreenFader >= 1.0f)
2010-03-28 18:58:01 +00:00
{
return;
}
::GraphicsSystem.OverwriteBg();
// show msgs
for (int iMsg = -iMsgFader; iMsg < 0; iMsg++)
{
// get message at pos
if (iMsg-iBackScroll >= 0) break;
const char *Message = LogBuffer.GetLine(iMsg-iBackScroll, nullptr, nullptr, nullptr);
if (!Message || !*Message) continue;
// calc target position (y)
int iMsgY = cgo.Y + cgo.Hgt + iMsg * iLineHgt + Fader;
// player message color?
C4Player *pPlr = GetMessagePlayer(Message);
DWORD dwColor;
if (pPlr)
dwColor = PlrClr2TxtClr(pPlr->ColorDw) & 0xffffff;
else
dwColor = 0xffffff;
// fade out (msg fade)
float fade = std::max(ScreenFader, 0.0f) + ((iMsg + 2.0f + float(Fader) / iLineHgt) / std::min(2-iMsgFader, -1));
DWORD dwFade = (0xff - Clamp(int(fade * 0xff), 0, 0xff)) << 24;
dwColor |= dwFade;
// Draw
2011-10-03 14:30:18 +00:00
pDraw->StringOut(Message,::GraphicsResource.FontRegular,1.0,cgo.Surface,cgo.X,iMsgY,dwColor);
2009-05-08 13:28:41 +00:00
}
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MessageBoard::EnsureLastMessage()
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Ingore if startup or typein
if (Startup) return;
// scroll until end of log
2009-05-08 13:28:41 +00:00
for (int i = 0; i < 100; i++)
2010-03-28 18:58:01 +00:00
{
::GraphicsSystem.Execute();
2009-05-08 13:28:41 +00:00
Execute();
if (iBackScroll < 0) break;
Delay=0;
}
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MessageBoard::AddLog(const char *szMessage)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// safety
if (!szMessage || !*szMessage) return;
// make sure new message will be drawn
++iBackScroll;
// register message in standard messageboard font
LogBuffer.AppendLines(szMessage, &::GraphicsResource.FontRegular, 0, nullptr);
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MessageBoard::ClearLog()
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
LogBuffer.Clear();
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4MessageBoard::LogNotify()
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// do not show startup board if GUI is active
if (::pGUI->IsActive()) return;
2009-05-08 13:28:41 +00:00
// Reset
iBackScroll=0;
// Draw
if (pDraw)
{
Draw(Output);
// startup: Draw message board only and do page flip
if (Startup) FullScreen.pSurface->PageFlip();
}
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
C4Player* C4MessageBoard::GetMessagePlayer(const char *szMessage)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Scan message text for heading player name
2010-03-28 18:58:01 +00:00
if (SEqual2(szMessage, "* "))
{
2009-05-11 13:09:53 +00:00
StdStrBuf str;
str.CopyUntil(szMessage + 2,' ');
2009-06-12 23:09:32 +00:00
return ::Players.GetByName(str.getData());
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
if (SCharCount(':',szMessage))
2010-03-28 18:58:01 +00:00
{
2009-05-11 13:09:53 +00:00
StdStrBuf str;
str.CopyUntil(szMessage + 2,':');
2009-06-12 23:09:32 +00:00
return ::Players.GetByName(str.getData());
2009-05-08 13:28:41 +00:00
}
return nullptr;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4MessageBoard::ControlScrollUp()
2010-03-28 18:58:01 +00:00
{
Delay=-1; Fader=0;
2009-05-08 13:28:41 +00:00
iBackScroll++;
return true;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4MessageBoard::ControlScrollDown()
2010-03-28 18:58:01 +00:00
{
Delay=-1; Fader=0;
2009-05-08 13:28:41 +00:00
if (iBackScroll > -1) iBackScroll--;
return true;
2010-03-28 18:58:01 +00:00
}