Skip to content

Commit

Permalink
fix #5659
Browse files Browse the repository at this point in the history
  • Loading branch information
rt committed Jul 21, 2017
1 parent 0f10be0 commit 849611a
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 53 deletions.
7 changes: 5 additions & 2 deletions doc/changelog.txt
Expand Up @@ -36,7 +36,7 @@ Misc:
- turn LoadDefs content_error exceptions into clean exits
- set modType to an integer (not string) value in base-content modinfo.lua's
- do not auto-add springcontent dependency to non-game "mod" archives
- downgrade non-writeable springsettings files to a warning
- downgrade non-writeable springsettings.cfg's to a warning
- allow maps to not supply a type-map; one fewer exception to worry about
- improve RNG statistical quality; sampled ints can now also exceed 0x7fff
- make the *nix CrashHandler compile on ARM; do not use cpuid on non-x86 builds
Expand Down Expand Up @@ -210,6 +210,9 @@ Rendering
- outsource vsync regulation to SDL2

UI:
- show a splash-screen while initializing VFS; randomly chosen from any
.png images found under SplashScreenDir defined in springsettings.cfg
(if SplashScreenDir is a relative path, Spring's CWD will be prepended)
- Add FPSClampPos config for whether the engine should verify the camera doesn't hit ground/go too far
this and other FPS camera configs can be changed midgame and will affect the next frame drawn.
- Add OverheadMaxHeightFactor config - a float multiplier for maximum overhead camera height.
Expand Down Expand Up @@ -279,7 +282,7 @@ Bugfixes:
- fix #3515 (better error-messages for the /team command)
- fix #5200 (broken ctrl+mousewheel tilt transitions with 'Spring' camera)
- fix #5258 (custom selection volumes)
- fix #5632 (show a slightly more interesting black screen on startup)
- fix #5632 (don't show just a black screen on startup)
- fix #5629 (make footprint-terraforming respect buildee's actual facing)
- fix #4447 (FPS-mode locking onto out-of-LOS units)
- fix #4074 (equalize UnitDamaged parameters for LuaUI and LuaRules)
Expand Down
10 changes: 5 additions & 5 deletions rts/Rendering/Textures/Bitmap.cpp
Expand Up @@ -228,7 +228,7 @@ bool CBitmap::Load(std::string const& filename, unsigned char defaultAlpha)
channels = 4;

CFileHandler file(filename);
if (file.FileExists() == false) {
if (!file.FileExists()) {
AllocDummy();
return false;
}
Expand All @@ -255,7 +255,7 @@ bool CBitmap::Load(std::string const& filename, unsigned char defaultAlpha)

ilDisable(IL_ORIGIN_SET);

if (success == false) {
if (!success) {
AllocDummy();
return false;
}
Expand All @@ -281,9 +281,9 @@ bool CBitmap::Load(std::string const& filename, unsigned char defaultAlpha)
ilDeleteImages(1, &imageID);

if (noAlpha) {
for (int y=0; y < ysize; ++y) {
for (int x=0; x < xsize; ++x) {
mem[((y*xsize+x) * 4) + 3] = defaultAlpha;
for (int y = 0; y < ysize; ++y) {
for (int x = 0; x < xsize; ++x) {
mem[((y * xsize + x) * 4) + 3] = defaultAlpha;
}
}
}
Expand Down
20 changes: 11 additions & 9 deletions rts/System/FileSystem/FileSystemInitializer.cpp
Expand Up @@ -11,8 +11,8 @@



volatile bool FileSystemInitializer::initialized = false;
volatile bool FileSystemInitializer::abortedInit = false;
volatile bool FileSystemInitializer::initSuccess = false;
volatile bool FileSystemInitializer::initFailure = false;

void FileSystemInitializer::PreInitializeConfigHandler(const std::string& configSource, const bool safemode)
{
Expand All @@ -33,7 +33,7 @@ void FileSystemInitializer::InitializeLogOutput(const std::string& filename)

bool FileSystemInitializer::Initialize()
{
if (initialized)
if (initSuccess)
return true;

try {
Expand All @@ -45,28 +45,30 @@ bool FileSystemInitializer::Initialize()
archiveScanner = new CArchiveScanner();
vfsHandler = new CVFSHandler();

initialized = true;
initSuccess = true;
} catch (const std::exception& ex) {
// even if we end up here, do not clean up configHandler yet
// since it can already have early observers registered that
// do not remove themselves until exit
logOutput.LogExceptionInfo("FileSystemInit", ex.what());
Cleanup(false);
abortedInit = true;
initFailure = true;
} catch (...) {
Cleanup(false);
abortedInit = true;
initFailure = true;
}

return (initialized && !abortedInit);
return (initSuccess && !initFailure);
}

void FileSystemInitializer::Cleanup(bool deallocConfigHandler)
{
if (initialized) {
if (initSuccess) {
spring::SafeDelete(archiveScanner);
spring::SafeDelete(vfsHandler);
initialized = false;

initSuccess = false;
initFailure = false;
}

if (deallocConfigHandler) {
Expand Down
9 changes: 4 additions & 5 deletions rts/System/FileSystem/FileSystemInitializer.h
Expand Up @@ -14,13 +14,12 @@ class FileSystemInitializer {
static void InitializeThr(bool* retPtr) { *retPtr = Initialize(); }
static void Cleanup(bool deallocConfigHandler = true);

static bool Initialized() { return initialized; }
static bool AbortedInit() { return abortedInit; }
static bool DoneIniting() { return (Initialized() || AbortedInit()); }
// either result counts
static bool Initialized() { return (initSuccess || initFailure); }

private:
static volatile bool initialized;
static volatile bool abortedInit;
static volatile bool initSuccess;
static volatile bool initFailure;
};

#endif // FILE_SYSTEM_INITIALIZER_H
122 changes: 90 additions & 32 deletions rts/System/SpringApp.cpp
Expand Up @@ -44,10 +44,10 @@
#include "Rendering/GlobalRendering.h"
#include "Rendering/Fonts/glFont.h"
#include "Rendering/GL/FBO.h"
#include "Rendering/Textures/Bitmap.h"
#include "Rendering/Textures/NamedTextures.h"
#include "Rendering/Textures/TextureAtlas.h"
#include "Sim/Misc/DefinitionTag.h"
#include "Sim/Misc/GlobalConstants.h"
#include "Sim/Misc/GlobalSynced.h"
#include "Sim/Misc/ModInfo.h"
#include "Sim/Projectiles/ExplosionGenerator.h"
Expand All @@ -66,6 +66,7 @@
#include "System/creg/creg_runtime_tests.h"
#include "System/FileSystem/ArchiveScanner.h"
#include "System/FileSystem/DataDirLocater.h"
#include "System/FileSystem/DataDirsAccess.h"
#include "System/FileSystem/FileHandler.h"
#include "System/FileSystem/FileSystem.h"
#include "System/FileSystem/FileSystemInitializer.h"
Expand Down Expand Up @@ -107,6 +108,7 @@ CONFIG(float, SmallFontOutlineWeight).defaultValue(10.0f).description("see FontO

CONFIG(std::string, name).defaultValue(UnnamedPlayerName).description("Sets your name in the game. Since this is overridden by lobbies with your lobby username when playing, it usually only comes up when viewing replays or starting the engine directly for testing purposes.");
CONFIG(std::string, DefaultStartScript).defaultValue("").description("filename of script.txt to use when no command line parameters are specified.");
CONFIG(std::string, SplashScreenDir).defaultValue(".");



Expand Down Expand Up @@ -148,6 +150,80 @@ static unsigned int numShutDowns = 0;



// initialize basic systems for command line help / output
static void ConsolePrintInitialize(const std::string& configSource, bool safemode)
{
spring_clock::PushTickRate(false);
spring_time::setstarttime(spring_time::gettime(true));

LOG_DISABLE();
FileSystemInitializer::PreInitializeConfigHandler(configSource, safemode);
FileSystemInitializer::InitializeLogOutput();
LOG_ENABLE();
}

#ifndef HEADLESS
static void ShowSplashScreen(const std::string& splashScreenFile)
{
CVertexArray* va = GetVertexArray();
CBitmap bmp;

if (bmp.Load(splashScreenFile)) {
bmp.ReverseYAxis();
} else {
bmp.AllocDummy({0, 0, 0, 0});
}

constexpr const char* fmtStrs[3] = {
"[Initializing Virtual File System]",
"* archives scanned: %u",
"* scantime elapsed: %.1fms",
};

const unsigned int splashTex = bmp.CreateTexture();
const unsigned int fontFlags = FONT_NORM | FONT_SCALE;

const float4 color = {1.0f, 1.0f, 1.0f, 1.0f};
const float4 coors = {0.5f, 0.1f, 0.8f, 0.04f};

const float textWidth = font->GetTextWidth(fmtStrs[0]);
const float normWidth = textWidth * globalRendering->pixelX * font->GetSize() * coors.z;

glPushAttrib(GL_ENABLE_BIT);
glEnable(GL_TEXTURE_2D);

for (spring_time t0 = spring_now(), t1 = t0; !FileSystemInitializer::Initialized(); t1 = spring_now()) {
glClear(GL_COLOR_BUFFER_BIT);

glBindTexture(GL_TEXTURE_2D, splashTex);
va->Initialize();
va->AddVertex2dT({ZeroVector.x, ZeroVector.y}, {0.0f, 0.0f});
va->AddVertex2dT({ UpVector.x, UpVector.y}, {0.0f, 1.0f});
va->AddVertex2dT({ XYVector.x, XYVector.y}, {1.0f, 1.0f});
va->AddVertex2dT({ RgtVector.x, RgtVector.y}, {1.0f, 0.0f});
va->DrawArray2dT(GL_QUADS);

font->Begin();
font->SetTextColor(color.x, color.y, color.z, color.w);
font->glFormat(coors.x - normWidth * 0.500f, coors.y , coors.z, fontFlags, fmtStrs[0]);
font->glFormat(coors.x - normWidth * 0.475f, coors.y - coors.w * coors.z * 1.0f, coors.z, fontFlags, fmtStrs[1], CArchiveScanner::GetNumScannedArchives());
font->glFormat(coors.x - normWidth * 0.475f, coors.y - coors.w * coors.z * 2.0f, coors.z, fontFlags, fmtStrs[2], (t1 - t0).toMilliSecsf());
font->End();

globalRendering->SwapBuffers(true, true);

// prevent WM's from assuming the window is unresponsive and
// (in recent versions of Windows) generating a kill-request
SDL_PollEvent(nullptr);
}

glPopAttrib();
glDeleteTextures(1, &splashTex);
}
#endif



/**
* Initializes SpringApp variables
*
Expand All @@ -168,6 +244,9 @@ SpringApp::SpringApp(int argc, char** argv)
// be done before SDL_Init, we are not using SDL_GetTicks
// as our clock anymore)
spring_time::setstarttime(spring_time::gettime(true));

// gu does not exist yet, pre-seed for ShowSplashScreen
guRNG.Seed(CGlobalUnsyncedRNG::rng_val_type(&argc));
}

/**
Expand Down Expand Up @@ -300,30 +379,20 @@ bool SpringApp::InitFileSystem()
#ifndef HEADLESS
// threaded initialization s.t. the window gets CPU time
// FileSystem is mostly self-contained, don't need locks
spring::thread fsInitThread(FileSystemInitializer::InitializeThr, &ret);
// (at this point neither the platform CWD nor data-dirs
// have been set yet by FSI, can only use absolute paths)
const std::string cwd = std::move(FileSystem::EnsurePathSepAtEnd(FileSystemAbstraction::GetCwd()));
const std::string ssd = std::move(FileSystem::EnsurePathSepAtEnd(configHandler->GetString("SplashScreenDir")));

std::vector<std::string> splashScreenFiles(dataDirsAccess.FindFiles(FileSystem::IsAbsolutePath(ssd)? ssd: cwd + ssd, "*.png", 0));
spring::thread fsInitThread(FileSystemInitializer::InitializeThr, &ret);

const float4 color = {1.0f, 0.0f, 0.0f, 1.0f};
const float4 coors = {0.5f, 0.5f, 25.0f, 0.04f};

for (spring_time t0 = spring_now(), t1 = t0; !FileSystemInitializer::DoneIniting(); t1 = spring_now()) {
glClear(GL_COLOR_BUFFER_BIT);

font->Begin();
font->SetTextColor(color.x, color.y, color.z, color.w);
font->glFormat(coors.x - 0.125f, coors.y , coors.z, FONT_NORM, "[Initializing Virtual File System]");
font->glFormat(coors.x - 0.120f, coors.y - coors.w * 1.0f, coors.z, FONT_NORM, "* archives scanned: %u", CArchiveScanner::GetNumScannedArchives());
font->glFormat(coors.x - 0.120f, coors.y - coors.w * 2.0f, coors.z, FONT_NORM, "* scantime elapsed: %.1fms", (t1 - t0).toMilliSecsf());
font->End();

globalRendering->SwapBuffers(true, true);

// prevent WM's from assuming the window is unresponsive and
// (in recent versions of Windows) generating a kill-request
SDL_PollEvent(nullptr);
if (!splashScreenFiles.empty()) {
ShowSplashScreen(splashScreenFiles[ guRNG.NextInt(splashScreenFiles.size()) ]);
} else {
ShowSplashScreen("");
}


fsInitThread.join();
#else
FileSystemInitializer::InitializeThr(&ret);
Expand Down Expand Up @@ -411,17 +480,6 @@ void SpringApp::LoadFonts()

}

// initialize basic systems for command line help / output
static void ConsolePrintInitialize(const std::string& configSource, bool safemode)
{
spring_clock::PushTickRate(false);
spring_time::setstarttime(spring_time::gettime(true));
LOG_DISABLE();
FileSystemInitializer::PreInitializeConfigHandler(configSource, safemode);
FileSystemInitializer::InitializeLogOutput();
LOG_ENABLE();
}


/**
* @return whether commandline parsing was successful
Expand Down

2 comments on commit 849611a

@ashdnazg
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice!

@cleanrock
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This cause assert. Most likely thread race between DataDirLocater::LocateDataDirs() and DataDirLocater::GetDataDirs(). LocateDataDirs() runs multiple times and clears dataDirs.

spring: /home/johanr/my_projects/spring/rts/System/FileSystem/DataDirLocater.cpp:105: const std::vector& DataDirLocater::GetDataDirs() const: Assertion `!dataDirs.empty()' failed.

Please sign in to comment.