Removed dependency for FLTK completely (fix #217).

Keystroke for accessing startup screen was replaced with splash window, because SDL cannot check keyboard’s state without a window.
This commit is contained in:
yvt 2014-03-31 20:37:23 +09:00
parent d4518dd732
commit 8f04b4ddff
8 changed files with 168 additions and 43 deletions

View File

@ -29,17 +29,6 @@ if(NOT GLEW_FOUND)
message(FATAL_ERROR "GLEW not found, please install it and make sure CMake can find it (add it to the PATH)")
endif()
set(FLTK_SKIP_OPENGL TRUE)
set(FLTK_SKIP_FORMS TRUE)
set(FLTK_SKIP_FLUID TRUE)
set(FLTK_SKIP_IMAGES TRUE)
include(FindFLTK)
if(NOT FLTK_FOUND)
message(FATAL_ERROR "FLTK not found, manually set FLTK_INCLUDE_DIR in CMake")
endif()
set(FLTK_OS_LIBS ${FLTK_BASE_LIBRARY})
include(FindZLIB)
if(NOT ZLIB_FOUND)
@ -158,7 +147,6 @@ if(OPENGL_INCLUDE_DIR)
include_directories("${OPENGL_INCLUDE_DIR}")
endif()
include_directories("${GLEW_INCLUDE_DIR}")
include_directories("${FLTK_INCLUDE_DIR}")
include_directories("${ZLIB_INCLUDE_DIR}")
include_directories("${CURL_INCLUDE_DIRS}")

View File

@ -69,7 +69,6 @@
E849654D18E9487300B9706D /* FltkPreferenceImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E849654B18E9487300B9706D /* FltkPreferenceImporter.cpp */; };
E849655018E94F1200B9706D /* SdlFileStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E849654E18E94F1200B9706D /* SdlFileStream.cpp */; };
E84E221618BB4601001282B0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E8CF039B178EDAC9000683D4 /* libz.dylib */; };
E84E221718BB4B41001282B0 /* libfltk.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E8CF03E4178EF5FF000683D4 /* libfltk.a */; };
E84E221918BB4BA0001282B0 /* Credits.inc in Sources */ = {isa = PBXBuildFile; fileRef = E84E221818BB4BA0001282B0 /* Credits.inc */; };
E852337B1839B28C00F40541 /* VersionInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E85233791839B28C00F40541 /* VersionInfo.cpp */; };
E8567E571792B24D009D83E0 /* IAudioChunk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8567E551792B24D009D83E0 /* IAudioChunk.cpp */; };
@ -851,7 +850,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
E84E221718BB4B41001282B0 /* libfltk.a in Frameworks */,
E84E221618BB4601001282B0 /* libz.dylib in Frameworks */,
E87AB82518BB3A04006B7D73 /* SDL2_image.framework in Frameworks */,
E844888717D2669C005105D0 /* libcurl.dylib in Frameworks */,

View File

@ -87,7 +87,7 @@ source_group("ScriptBindings" FILES ${SCRIPTBINDING_FILES})
source_group("libs\\unzip" FILES ${UNZIP_FILES})
target_link_libraries(OpenSpades ${SDL2_LIBRARY} ${SDL2_IMAGE_LIBRARY} ${OPENGL_LIBRARIES} ${GLEW_LIBRARY} ${FLTK_OS_LIBS} ${ZLIB_LIBRARIES} ${CURL_LIBRARY} ${CMAKE_DL_LIBS} ${ANGELSCRIPT_LIBS})
target_link_libraries(OpenSpades ${SDL2_LIBRARY} ${SDL2_IMAGE_LIBRARY} ${OPENGL_LIBRARIES} ${GLEW_LIBRARY} ${ZLIB_LIBRARIES} ${CURL_LIBRARY} ${CMAKE_DL_LIBS} ${ANGELSCRIPT_LIBS})
#todo: MACOSX_BUNDLE_ICON_FILE ?

View File

@ -88,6 +88,35 @@ namespace spades {
}
}
Bitmap *Bitmap::Load(IStream *stream) {
std::vector<IBitmapCodec *>codecs = IBitmapCodec::GetAllCodecs();
auto pos = stream->GetPosition();
std::string errMsg;
for(size_t i = 0; i < codecs.size(); i++){
IBitmapCodec *codec = codecs[i];
if(codec->CanLoad()){
// give it a try.
// open error shouldn't be handled here
try{
stream->SetPosition(pos);
return codec->Load(stream);
}catch(const std::exception& ex){
errMsg += codec->GetName();
errMsg += ":\n";
errMsg += ex.what();
errMsg += "\n\n";
}
}
}
if(errMsg.empty()){
SPRaise("Bitmap codec not found for stream");
}else{
SPRaise("No bitmap codec could load file successfully: [stream]\n%s\n",
errMsg.c_str());
}
}
void Bitmap::Save(const std::string &filename) {
std::vector<IBitmapCodec *>codecs = IBitmapCodec::GetAllCodecs();
for(size_t i = 0; i < codecs.size(); i++){

View File

@ -38,6 +38,7 @@ namespace spades {
Bitmap(uint32_t *pixels, int w, int h);
static Bitmap *Load(const std::string&);
static Bitmap *Load(IStream *); // must be seekable
void Save(const std::string&);
uint32_t *GetPixels() { return pixels; }

View File

@ -43,7 +43,14 @@
#include <ScriptBindings/ScriptManager.h>
#include <algorithm> //std::sort
#include <FL/Fl.H>
#include <memory>
#include <Core/MemoryStream.h>
#include <Core/Bitmap.h>
static const unsigned char splashImage[] = {
#include "SplashImage.inc"
};
SPADES_SETTING(cl_showStartupWindow, "");
@ -135,10 +142,6 @@ class ThreadQuantumSetter {
#endif
#ifdef __APPLE__
#include <xmmintrin.h>
#endif
SPADES_SETTING(cg_lastQuickConnectHost, "");
SPADES_SETTING(cg_protocolVersion, "");
SPADES_SETTING(cg_playerName, "");
@ -197,32 +200,111 @@ namespace spades {
}
}
/** Thrown when user wants to exit the program while its initialization. */
class ExitRequestException: public std::exception {
public:
ExitRequestException() throw() {}
};
class SplashWindow {
SDL_Window *window;
SDL_Surface *surface;
spades::Handle<spades::Bitmap> bmp;
bool startupScreenRequested;
public:
SplashWindow():
window(nullptr),
surface(nullptr),
startupScreenRequested(false){
spades::MemoryStream stream(reinterpret_cast<const char*>(splashImage), sizeof(splashImage));
bmp.Set(spades::Bitmap::Load(&stream), false);
SDL_InitSubSystem(SDL_INIT_VIDEO|SDL_INIT_TIMER);
window = SDL_CreateWindow("OpenSpades Splash Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
bmp->GetWidth(), bmp->GetHeight(), SDL_WINDOW_BORDERLESS);
if(window == nullptr) {
SPLog("Creation of splash window failed.");
return;
}
surface = SDL_GetWindowSurface(window);
if(surface == nullptr) {
SPLog("Creation of splash window surface failed.");
SDL_DestroyWindow(window);
return;
}
// put splash image
auto *s = SDL_CreateRGBSurfaceFrom(bmp->GetPixels(), bmp->GetWidth(), bmp->GetHeight(),
32, bmp->GetWidth() * 4,
0xff, 0xff00, 0xff0000, 0);
SDL_BlitSurface(s, nullptr, surface, nullptr);
SDL_FreeSurface(s);
SDL_UpdateWindowSurface(window);
}
SDL_Window *GetWindow() {
return window;
}
void PumpEvents() {
SDL_PumpEvents();
SDL_Event e;
while(SDL_PollEvent(&e)) {
switch(e.type) {
case SDL_KEYDOWN:
switch(e.key.keysym.sym) {
case SDLK_ESCAPE: throw ExitRequestException();
case SDLK_SPACE:
startupScreenRequested = true;
break;
}
break;
case SDL_QUIT:
throw ExitRequestException();
}
}
}
bool IsStartupScreenRequested() {
return startupScreenRequested;
}
~SplashWindow() {
if(window) SDL_DestroyWindow(window);
}
};
int main(int argc, char ** argv)
{
#ifdef WIN32
SetUnhandledExceptionFilter( UnhandledExceptionProc );
#endif
// Enable FPE
#if 0
#ifdef __APPLE__
short fpflags = 0x1332; // Default FP flags, change this however you want.
__asm__("fnclex\n\tfldcw %0\n\t": "=m"(fpflags));
_MM_SET_EXCEPTION_MASK(_MM_GET_EXCEPTION_MASK() & ~_MM_MASK_INVALID);
#endif
std::unique_ptr<SplashWindow> splashWindow;
#endif
try{
// start recording backtrace
spades::reflection::Backtrace::StartBacktrace();
SPADES_MARK_FUNCTION();
// show splash window
// NOTE: splash window uses image loader, which assumes backtrace is already initialized.
splashWindow.reset(new SplashWindow());
auto showSplashWindowTime = SDL_GetTicks();
auto pumpEvents = [&splashWindow] { splashWindow->PumpEvents(); };
// initialize threads
spades::Thread::InitThreadSystem();
spades::DispatchQueue::GetThreadQueue()->MarkSDLVideoThread();
SPLog("Package: " PACKAGE_STRING);
// default resource directories
// setup user-specific default resource directories
#ifdef WIN32
static char buf[4096];
GetModuleFileName(NULL, buf, 4096);
@ -258,6 +340,7 @@ int main(int argc, char ** argv)
(new spades::DirectoryFileSystem(home+"/.openspades/Resources", true));
#endif
// start log output to SystemMessages.log
try{
spades::StartLog();
}catch(const std::exception& ex){
@ -267,15 +350,17 @@ int main(int argc, char ** argv)
"OpenSpades will continue to run, but any critical events are not logged.", ex.what());
if(SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_WARNING,
"OpenSpades Log System Failure",
msg.c_str(), nullptr)) {
msg.c_str(), splashWindow->GetWindow())) {
// showing dialog failed.
// TODO: do appropriate action?
}
}
SPLog("Log Started.");
// load preferences.
spades::Settings::GetInstance()->Load();
pumpEvents();
// dump CPU info (for debugging?)
{
spades::CpuID cpuid;
SPLog("---- CPU Information ----");
@ -299,15 +384,12 @@ int main(int argc, char ** argv)
SPLog("-------------------------");
}
// register resource directory specified by Makefile (or something)
#if defined(RESDIR_DEFINED) && !NDEBUG
spades::FileManager::AddFileSystem(new spades::DirectoryFileSystem(RESDIR, false));
#endif
/*
spades::FileManager::AddFileSystem
(new spades::DirectoryFileSystem("/Users/tcpp/Programs/MacPrograms2/OpenSpades/Resources", false));
*/
// add all zip files
// search current file system for .pak files
{
std::vector<spades::IFileSystem*> fss;
std::vector<spades::IFileSystem*> fssImportant;
@ -366,41 +448,64 @@ int main(int argc, char ** argv)
spades::FileManager::PrependFileSystem(fssImportant[i]);
}
}
pumpEvents();
// initialize localization system
SPLog("Initializing localization system");
spades::LoadCurrentLocale();
_Tr("Main", "Localization System Loaded");
pumpEvents();
// initialize AngelScript
SPLog("Initializing script engine");
spades::ScriptManager::GetInstance();
pumpEvents();
SPLog("Initializing window system");
int dum = 0;
Fl::args( argc, argv, dum, argsHandler );
ThreadQuantumSetter quantumSetter;
(void)quantumSetter; // suppress "unused variable" warning
SDL_InitSubSystem(SDL_INIT_VIDEO);
// we want to show splash window at least for some time...
pumpEvents();
auto ticks = SDL_GetTicks();
if(ticks < showSplashWindowTime + 1500) {
SDL_Delay(showSplashWindowTime + 1500 - ticks);
}
pumpEvents();
// everything is now ready!
if( !cg_autoConnect ) {
if(!((int)cl_showStartupWindow != 0 ||
Fl::get_key(FL_Shift_L) || Fl::get_key(FL_Shift_R))) {
// TODO: always show main window for first run
splashWindow->IsStartupScreenRequested())) {
splashWindow.reset();
SPLog("Starting main screen");
spades::StartMainScreen();
}else{
splashWindow.reset();
SPLog("Starting startup window");
::spades::gui::StartupScreen::Run();
}
} else {
splashWindow.reset();
spades::ServerAddress host(cg_lastQuickConnectHost.CString(), (int)cg_protocolVersion == 3 ? spades::ProtocolVersion::v075 : spades::ProtocolVersion::v076 );
spades::StartClient(host, cg_playerName);
}
spades::Settings::GetInstance()->Flush();
}catch(const ExitRequestException&){
// user changed his mind.
}catch(const std::exception& ex) {
try {
splashWindow.reset(nullptr);
}catch(...){
}
std::string msg = ex.what();
msg = _Tr("Main", "A serious error caused OpenSpades to stop working:\n\n{0}\n\nSee SystemMessages.log for more details.", msg);

View File

@ -0,0 +1,4 @@
#!/bin/sh
xxd -i < SplashImage.jpg > SplashImage.inc

BIN
Sources/Gui/SplashImage.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB