1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
/**
* @file Main.cpp
* @brief Main class
*
* Main application class that launches
* everything else
*/
#ifdef _MSC_VER
#include "StdAfx.h"
#endif
#include <sstream>
#include <boost/system/system_error.hpp>
#include <boost/asio.hpp>
#include <boost/version.hpp>
#include "Platform/errorhandler.h"
#ifndef _MSC_VER
#include "StdAfx.h"
#endif
#include "lib/gml/gml.h"
#include "LogOutput.h"
#include "Exceptions.h"
#include "SpringApp.h"
#include <SDL.h> // Must come after Game/UI/MouseHandler.h for ButtonPressEvt
#ifdef WIN32
#include "Platform/Win/win32.h"
#include <winreg.h>
#include <direct.h>
#include "Platform/Win/seh.h"
#endif
// On msvc main() is declared as a non-throwing function.
// Moving the catch clause to a seperate function makes it possible to re-throw the exception for the installed crash reporter
int Run(int argc, char* argv[])
{
#ifdef __MINGW32__
// For the MinGW backtrace() implementation we need to know the stack end.
{
extern void* stack_end;
char here;
stack_end = (void*) &here;
}
#endif
#ifdef USE_GML
set_threadnum(0);
# if GML_ENABLE_TLS_CHECK
if (gmlThreadNumber != 0) {
handleerror(NULL, "Thread Local Storage test failed", "GML error:", MBF_OK | MBF_EXCL);
}
# endif
#endif
// It's nice to be able to disable catching when you're debugging
#ifndef NO_CATCH_EXCEPTIONS
try {
SpringApp app;
return app.Run(argc, argv);
}
catch (const content_error& e) {
SDL_Quit();
logOutput.RemoveAllSubscribers();
logOutput.Print("Content error: %s\n", e.what());
handleerror(NULL, e.what(), "Incorrect/Missing content:", MBF_OK | MBF_EXCL);
return -1;
}
catch (const boost::system::system_error& e) {
logOutput.Print("Fatal system error: %d: %s", e.code().value(), e.what());
#ifdef _MSC_VER
throw;
#else
std::stringstream ss;
ss << e.code().value() << ": " << e.what();
std::string tmp = ss.str();
handleerror(NULL, tmp.c_str(), "Fatal Error", MBF_OK | MBF_EXCL);
return -1;
#endif
}
catch (const std::exception& e) {
SDL_Quit();
#ifdef _MSC_VER
logOutput.Print("Fatal error: %s\n", e.what());
logOutput.RemoveAllSubscribers();
throw; // let the error handler catch it
#else
logOutput.RemoveAllSubscribers();
handleerror(NULL, e.what(), "Fatal Error", MBF_OK | MBF_EXCL);
return -1;
#endif
}
catch (const char* e) {
SDL_Quit();
#ifdef _MSC_VER
logOutput.Print("Fatal error: %s\n", e);
logOutput.RemoveAllSubscribers();
throw; // let the error handler catch it
#else
logOutput.RemoveAllSubscribers();
handleerror(NULL, e, "Fatal Error", MBF_OK | MBF_EXCL);
return -1;
#endif
}
#else
SpringApp app;
return app.Run(argc, argv);
#endif
}
/**
* @brief main
* @return exit code
* @param argc argument count
* @param argv array of argument strings
*
* Main entry point function
*/
int main(int argc, char* argv[])
{
return Run(argc, argv);
}
#ifdef WIN32
int WINAPI WinMain(HINSTANCE hInstanceIn, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
return Run(__argc, __argv);
}
#endif
|