forked from Mirrors/openclonk
195 lines
6.0 KiB
C++
195 lines
6.0 KiB
C++
/*
|
|
* OpenClonk, http://www.openclonk.org
|
|
*
|
|
* Copyright (c) 2003-2009, RedWolf Design GmbH, http://www.clonk.de/
|
|
* Copyright (c) 2009-2016, The OpenClonk Team and contributors
|
|
*
|
|
* Distributed under the terms of the ISC license; see accompanying file
|
|
* "COPYING" for details.
|
|
*
|
|
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
|
|
* See accompanying file "TRADEMARK" for details.
|
|
*
|
|
* To redistribute this file separately, substitute the full license texts
|
|
* for the above references.
|
|
*/
|
|
// startup screen
|
|
|
|
#include "C4Include.h"
|
|
#include "gui/C4LoaderScreen.h"
|
|
|
|
#include "c4group/C4Components.h"
|
|
#include "c4group/C4GroupSet.h"
|
|
#include "graphics/C4Draw.h"
|
|
#include "graphics/C4GraphicsResource.h"
|
|
#include "lib/C4LogBuf.h"
|
|
#include "lib/C4Random.h"
|
|
|
|
|
|
C4LoaderScreen::C4LoaderScreen()
|
|
{
|
|
// zero fields
|
|
szInfo=nullptr;
|
|
fBlackScreen = false;
|
|
}
|
|
|
|
C4LoaderScreen::~C4LoaderScreen()
|
|
{
|
|
// clear fields
|
|
if (szInfo) delete [] szInfo;
|
|
}
|
|
|
|
bool C4LoaderScreen::Init(std::string loaderSpec)
|
|
{
|
|
// Determine loader specification
|
|
if (loaderSpec.empty())
|
|
loaderSpec = "Loader*";
|
|
|
|
C4Group *pGroup = nullptr;
|
|
// query groups of equal priority in set
|
|
while ((pGroup=Game.GroupSet.FindGroup(C4GSCnt_Loaders, pGroup, true)))
|
|
{
|
|
SeekLoaderScreens(*pGroup, loaderSpec);
|
|
}
|
|
// nothing found? seek in main gfx grp
|
|
C4Group GfxGrp;
|
|
if (loaders.empty())
|
|
{
|
|
// open it
|
|
GfxGrp.Close();
|
|
if (!Reloc.Open(GfxGrp, C4CFN_Graphics))
|
|
{
|
|
LogFatal(FormatString(LoadResStr("IDS_PRC_NOGFXFILE"),C4CFN_Graphics,GfxGrp.GetError()).getData());
|
|
return false;
|
|
}
|
|
// seek for loaders
|
|
SeekLoaderScreens(GfxGrp, loaderSpec);
|
|
|
|
// Still nothing found: fall back to general loader spec in main graphics group
|
|
if (loaders.empty())
|
|
{
|
|
SeekLoaderScreens(GfxGrp, "Loader*");
|
|
}
|
|
// Not even default loaders available? Fail.
|
|
if (loaders.empty())
|
|
{
|
|
LogFatal(FormatString("No loaders found for loader specification: %s", loaderSpec.c_str()).getData());
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// choose random loader
|
|
auto entry = loaders.begin();
|
|
std::advance(entry, UnsyncedRandom(loaders.size()));
|
|
|
|
// load loader
|
|
fctBackground.GetFace().SetBackground();
|
|
if (!fctBackground.Load(*(entry->first), entry->second.c_str(), C4FCT_Full, C4FCT_Full, true, 0)) return false;
|
|
|
|
// load info
|
|
if (szInfo) { delete [] szInfo; szInfo=nullptr; }
|
|
|
|
// done, success!
|
|
return true;
|
|
}
|
|
|
|
void C4LoaderScreen::SetBlackScreen(bool fIsBlack)
|
|
{
|
|
// enabled/disables drawing of loader screen
|
|
fBlackScreen = fIsBlack;
|
|
// will be updated when drawn next time
|
|
}
|
|
|
|
void C4LoaderScreen::SeekLoaderScreens(C4Group &rFromGrp, const std::string &wildcard)
|
|
{
|
|
// seek for png, jpg, jpeg, bmp
|
|
char filename[_MAX_PATH + 1];
|
|
for (bool found = rFromGrp.FindEntry(wildcard.c_str(), filename); found; found = rFromGrp.FindNextEntry(wildcard.c_str(), filename))
|
|
{
|
|
// potential candidate - check file extension
|
|
std::string extension{ GetExtension(filename) };
|
|
std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
|
|
if (extension == "png" || extension == "jpg" || extension == "jpeg" || extension == "bmp") {
|
|
loaders.emplace(&rFromGrp, std::string(filename));
|
|
}
|
|
}
|
|
}
|
|
|
|
void C4LoaderScreen::Draw(C4Facet &cgo, Flag options, int iProgress, C4LogBuffer *pLog, int Process)
|
|
{
|
|
// simple black screen loader?
|
|
if (fBlackScreen || options == Flag::BLACK)
|
|
{
|
|
pDraw->FillBG();
|
|
return;
|
|
}
|
|
// cgo.X/Y is assumed 0 here...
|
|
// fixed positions for now
|
|
int iHIndent=20;
|
|
int iVIndent=20;
|
|
int iLogBoxHgt=84;
|
|
int iLogBoxMargin=2;
|
|
int iVMargin=5;
|
|
int iProgressBarHgt=15;
|
|
CStdFont &LogFont=::GraphicsResource.FontTiny, &rProgressBarFont=::GraphicsResource.FontRegular;
|
|
CStdFont &TitleFont = ::GraphicsResource.FontTitle;
|
|
float fLogBoxFontZoom=1.0f;
|
|
|
|
if (options & Flag::BACKGROUND) {
|
|
// Background (loader)
|
|
fctBackground.DrawFullScreen(cgo);
|
|
}
|
|
|
|
if (options & Flag::TITLE) {
|
|
// draw scenario title
|
|
pDraw->StringOut(Game.ScenarioTitle.getData(), TitleFont, 1.0f, cgo.Surface, cgo.Wdt - iHIndent, cgo.Hgt - iVIndent - iLogBoxHgt - iVMargin - iProgressBarHgt - iVMargin - TitleFont.GetLineHeight(), 0xdddddddd, ARight, false);
|
|
}
|
|
|
|
if (options & Flag::PROGRESS) {
|
|
// draw progress bar
|
|
pDraw->DrawBoxDw(cgo.Surface, iHIndent, cgo.Hgt - iVIndent - iLogBoxHgt - iVMargin - iProgressBarHgt, cgo.Wdt - iHIndent, cgo.Hgt - iVIndent - iLogBoxHgt - iVMargin, 0xb0000000);
|
|
int iProgressBarWdt = cgo.Wdt - iHIndent * 2 - 2;
|
|
if (::GraphicsResource.fctProgressBar.Surface)
|
|
{
|
|
::GraphicsResource.fctProgressBar.DrawX(cgo.Surface, iHIndent + 1, cgo.Hgt - iVIndent - iLogBoxHgt - iVMargin - iProgressBarHgt + 1, iProgressBarWdt*iProgress / 100, iProgressBarHgt - 2);
|
|
}
|
|
else
|
|
{
|
|
pDraw->DrawBoxDw(cgo.Surface, iHIndent + 1, cgo.Hgt - iVIndent - iLogBoxHgt - iVMargin - iProgressBarHgt + 1, iHIndent + 1 + iProgressBarWdt*iProgress / 100, cgo.Hgt - iVIndent - iLogBoxHgt - iVMargin - 1, 0xb0ff0000);
|
|
}
|
|
pDraw->StringOut(FormatString("%i%%", iProgress).getData(), rProgressBarFont, 1.0f, cgo.Surface,
|
|
cgo.Wdt / 2, cgo.Hgt - iVIndent - iLogBoxHgt - iVMargin - rProgressBarFont.GetLineHeight() / 2 - iProgressBarHgt / 2, 0xffffffff,
|
|
ACenter, true);
|
|
}
|
|
|
|
if (options & Flag::LOG) {
|
|
// draw log box
|
|
if (pLog)
|
|
{
|
|
pDraw->DrawBoxDw(cgo.Surface, iHIndent, cgo.Hgt - iVIndent - iLogBoxHgt, cgo.Wdt - iHIndent, cgo.Hgt - iVIndent, 0x7f000000);
|
|
int iLineHgt = int(fLogBoxFontZoom*LogFont.GetLineHeight()); if (!iLineHgt) iLineHgt = 5;
|
|
int iLinesVisible = (iLogBoxHgt - 2 * iLogBoxMargin) / iLineHgt;
|
|
int iX = iHIndent + iLogBoxMargin;
|
|
int iY = cgo.Hgt - iVIndent - iLogBoxHgt + iLogBoxMargin;
|
|
int32_t w, h;
|
|
for (int i = -iLinesVisible; i < 0; ++i)
|
|
{
|
|
const char *szLine = pLog->GetLine(i, nullptr, nullptr, nullptr);
|
|
if (!szLine || !*szLine) continue;
|
|
LogFont.GetTextExtent(szLine, w, h, true);
|
|
pDraw->TextOut(szLine, LogFont, fLogBoxFontZoom, cgo.Surface, iX, iY);
|
|
iY += h;
|
|
}
|
|
|
|
if (options & Flag::PROCESS) {
|
|
// append process text
|
|
if (Process)
|
|
{
|
|
iY -= h; iX += w;
|
|
pDraw->TextOut(FormatString("%i%%", (int)Process).getData(), LogFont, fLogBoxFontZoom, cgo.Surface, iX, iY);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|