summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/app/app.cpp246
-rw-r--r--src/app/app.h1
-rw-r--r--src/common/logger.cpp82
-rw-r--r--src/common/logger.h131
-rw-r--r--src/graphics/opengl/gldevice.cpp25
-rw-r--r--src/graphics/opengl/gldevice.h14
-rw-r--r--test/unit/graphics/engine/lightman_test.cpp4
7 files changed, 327 insertions, 176 deletions
diff --git a/src/app/app.cpp b/src/app/app.cpp
index ae5ac88..cb1ac34 100644
--- a/src/app/app.cpp
+++ b/src/app/app.cpp
@@ -39,6 +39,7 @@
#include <stdlib.h>
#include <libintl.h>
#include <unistd.h>
+#include <getopt.h>
#ifdef OPENAL_SOUND
@@ -195,102 +196,131 @@ CEventQueue* CApplication::GetEventQueue()
CSoundInterface* CApplication::GetSound()
{
return m_sound;
+
+ for (int i = 0; i < PCNT_MAX; ++i)
+ {
+ DestroyTimeStamp(m_performanceCounters[i][0]);
+ DestroyTimeStamp(m_performanceCounters[i][1]);
+ }
}
ParseArgsStatus CApplication::ParseArguments(int argc, char *argv[])
{
- bool waitDataDir = false;
- bool waitLogLevel = false;
- bool waitLanguage = false;
-
- for (int i = 1; i < argc; ++i)
+ enum OptionType
{
- std::string arg = argv[i];
-
- if (waitDataDir)
- {
- waitDataDir = false;
- m_dataPath = arg;
- GetLogger()->Info("Using custom data dir: '%s'\n", m_dataPath.c_str());
- continue;
- }
-
- if (waitLogLevel)
+ OPT_HELP = 1,
+ OPT_DEBUG,
+ OPT_DATADIR,
+ OPT_LOGLEVEL,
+ OPT_LANGUAGE,
+ OPT_VBO
+ };
+
+ option options[] =
+ {
+ { "help", no_argument, nullptr, OPT_HELP },
+ { "debug", no_argument, nullptr, OPT_DEBUG },
+ { "datadir", required_argument, nullptr, OPT_DATADIR },
+ { "loglevel", required_argument, nullptr, OPT_LOGLEVEL },
+ { "language", required_argument, nullptr, OPT_LANGUAGE },
+ { "vbo", required_argument, nullptr, OPT_VBO }
+ };
+
+ opterr = 0;
+
+ int c = 0;
+ int index = -1;
+ while ((c = getopt_long_only(argc, argv, "", options, &index)) != -1)
+ {
+ if (c == '?')
{
- waitLogLevel = false;
- if (arg == "trace")
- GetLogger()->SetLogLevel(LOG_TRACE);
- else if (arg == "debug")
- GetLogger()->SetLogLevel(LOG_DEBUG);
- else if (arg == "info")
- GetLogger()->SetLogLevel(LOG_INFO);
- else if (arg == "warn")
- GetLogger()->SetLogLevel(LOG_WARN);
- else if (arg == "error")
- GetLogger()->SetLogLevel(LOG_ERROR);
- else if (arg == "none")
- GetLogger()->SetLogLevel(LOG_NONE);
+ if (optopt == 0)
+ GetLogger()->Error("Invalid argument: %s\n", argv[optind-1]);
else
- return PARSE_ARGS_FAIL;
- continue;
- }
+ GetLogger()->Error("Expected argument for option: %s\n", argv[optind-1]);
- if (waitLanguage)
- {
- waitLanguage = false;
- if (arg == "en")
- m_language = LANGUAGE_ENGLISH;
- else if (arg == "de")
- m_language = LANGUAGE_GERMAN;
- else if (arg == "fr")
- m_language = LANGUAGE_FRENCH;
- else if (arg == "pl")
- m_language = LANGUAGE_POLISH;
- else
- return PARSE_ARGS_FAIL;
- continue;
+ m_exitCode = 1;
+ return PARSE_ARGS_FAIL;
}
- if (arg == "-debug")
- {
- SetDebugMode(true);
- }
- else if (arg == "-loglevel")
- {
- waitLogLevel = true;
- }
- else if (arg == "-datadir")
- {
- waitDataDir = true;
- }
- else if (arg == "-language")
- {
- waitLanguage = true;
- }
- else if (arg == "-help")
- {
- GetLogger()->Message("\n");
- GetLogger()->Message("Colobot %s (%s)\n",COLOBOT_CODENAME,COLOBOT_VERSION);
- GetLogger()->Message("\n");
- GetLogger()->Message("List of available options:\n");
- GetLogger()->Message(" -help this help\n");
- GetLogger()->Message(" -datadir path set custom data directory path\n");
- GetLogger()->Message(" -debug enable debug mode (more info printed in logs)\n");
- GetLogger()->Message(" -loglevel level set log level to level (one of: trace, debug, info, warn, error, none)\n");
- GetLogger()->Message(" -language lang set language (one of: en, de, fr, pl)\n");
- return PARSE_ARGS_HELP;
- }
- else
+ index = -1;
+
+ switch (c)
{
- m_exitCode = 1;
- return PARSE_ARGS_FAIL;
+ case OPT_HELP:
+ {
+ GetLogger()->Message("\n");
+ GetLogger()->Message("Colobot %s (%s)\n", COLOBOT_CODENAME, COLOBOT_VERSION);
+ GetLogger()->Message("\n");
+ GetLogger()->Message("List of available options:\n");
+ GetLogger()->Message(" -help this help\n");
+ GetLogger()->Message(" -debug enable debug mode (more info printed in logs)\n");
+ GetLogger()->Message(" -datadir path set custom data directory path\n");
+ GetLogger()->Message(" -loglevel level set log level to level (one of: trace, debug, info, warn, error, none)\n");
+ GetLogger()->Message(" -language lang set language (one of: en, de, fr, pl)\n");
+ GetLogger()->Message(" -vbo mode set OpenGL VBO mode (one of: auto, enable, disable)\n");
+ return PARSE_ARGS_HELP;
+ }
+ case OPT_DEBUG:
+ {
+ SetDebugMode(true);
+ break;
+ }
+ case OPT_DATADIR:
+ {
+ m_dataPath = optarg;
+ GetLogger()->Info("Using custom data dir: '%s'\n", m_dataPath.c_str());
+ break;
+ }
+ case OPT_LOGLEVEL:
+ {
+ LogLevel logLevel;
+ if (! CLogger::ParseLogLevel(optarg, logLevel))
+ {
+ GetLogger()->Error("Invalid log level: \"%s\"\n", optarg);
+ return PARSE_ARGS_FAIL;
+ }
+
+ GetLogger()->Message("[*****] Log level changed to %s\n", optarg);
+ GetLogger()->SetLogLevel(logLevel);
+ break;
+ }
+ case OPT_LANGUAGE:
+ {
+ Language language;
+ if (! ParseLanguage(optarg, language))
+ {
+ GetLogger()->Error("Invalid language: \"%s\"\n", optarg);
+ return PARSE_ARGS_FAIL;
+ }
+
+ GetLogger()->Info("Using language %s\n", optarg);
+ m_language = language;
+ break;
+ }
+ case OPT_VBO:
+ {
+ std::string vbo;
+ vbo = optarg;
+ if (vbo == "auto")
+ m_deviceConfig.vboMode = Gfx::VBO_MODE_AUTO;
+ else if (vbo == "enable")
+ m_deviceConfig.vboMode = Gfx::VBO_MODE_ENABLE;
+ else if (vbo == "disable")
+ m_deviceConfig.vboMode = Gfx::VBO_MODE_DISABLE;
+ else
+ {
+ GetLogger()->Error("Invalid vbo mode: \"%s\"\n", optarg);
+ return PARSE_ARGS_FAIL;
+ }
+
+ break;
+ }
+ default:
+ assert(false); // should never get here
}
}
- // Args not given?
- if (waitDataDir || waitLogLevel || waitLanguage)
- return PARSE_ARGS_FAIL;
-
return PARSE_ARGS_OK;
}
@@ -336,7 +366,7 @@ bool CApplication::Create()
} else {
m_sound->CacheAll(GetDataSubdirPath(DIR_SOUND));
}
-
+
if (GetProfile().GetLocalProfileString("Resources", "Music", path)) {
m_sound->AddMusicFiles(path);
} else {
@@ -376,20 +406,22 @@ bool CApplication::Create()
m_exitCode = 3;
return false;
}
-
+
// load settings from profile
int iValue;
- if ( GetProfile().GetLocalProfileInt("Setup", "Resolution", iValue) ) {
- std::vector<Math::IntPoint> modes;
- GetVideoResolutionList(modes, true, true);
- if (static_cast<unsigned int>(iValue) < modes.size())
- m_deviceConfig.size = modes.at(iValue);
+ if ( GetProfile().GetLocalProfileInt("Setup", "Resolution", iValue) )
+ {
+ std::vector<Math::IntPoint> modes;
+ GetVideoResolutionList(modes, true, true);
+ if (static_cast<unsigned int>(iValue) < modes.size())
+ m_deviceConfig.size = modes.at(iValue);
}
-
- if ( GetProfile().GetLocalProfileInt("Setup", "Fullscreen", iValue) ) {
- m_deviceConfig.fullScreen = (iValue == 1);
+
+ if ( GetProfile().GetLocalProfileInt("Setup", "Fullscreen", iValue) )
+ {
+ m_deviceConfig.fullScreen = (iValue == 1);
}
-
+
if (! CreateVideoSurface())
return false; // dialog is in function
@@ -409,7 +441,7 @@ bool CApplication::Create()
// Don't generate joystick events
SDL_JoystickEventState(SDL_IGNORE);
-
+
// The video is ready, we can create and initalize the graphics device
m_device = new Gfx::CGLDevice(m_deviceConfig);
if (! m_device->Create() )
@@ -1503,6 +1535,32 @@ char CApplication::GetLanguageChar()
return langChar;
}
+bool CApplication::ParseLanguage(const std::string& str, Language& language)
+{
+ if (str == "en")
+ {
+ language = LANGUAGE_ENGLISH;
+ return true;
+ }
+ else if (str == "de")
+ {
+ language = LANGUAGE_GERMAN;
+ return true;
+ }
+ else if (str == "fr")
+ {
+ language = LANGUAGE_FRENCH;
+ return true;
+ }
+ else if (str == "pl")
+ {
+ language = LANGUAGE_POLISH;
+ return true;
+ }
+
+ return false;
+}
+
void CApplication::SetLanguage(Language language)
{
m_language = language;
diff --git a/src/app/app.h b/src/app/app.h
index f3f5601..71a3527 100644
--- a/src/app/app.h
+++ b/src/app/app.h
@@ -327,6 +327,7 @@ public:
Language GetLanguage();
char GetLanguageChar();
void SetLanguage(Language language);
+ static bool ParseLanguage(const std::string& str, Language& language);
//@}
//! Management of sleep in main loop (lowers CPU usage)
diff --git a/src/common/logger.cpp b/src/common/logger.cpp
index 3ec9746..8bc4cef 100644
--- a/src/common/logger.cpp
+++ b/src/common/logger.cpp
@@ -36,25 +36,37 @@ CLogger::~CLogger()
}
-void CLogger::Log(LogType type, const char *str, va_list args)
+void CLogger::Log(LogLevel type, const char* str, va_list args)
{
if (type < mLogLevel)
return;
- switch (type) {
- case LOG_TRACE: fprintf(IsOpened() ? mFile : stderr, "[TRACE]: "); break;
- case LOG_DEBUG: fprintf(IsOpened() ? mFile : stderr, "[DEBUG]: "); break;
- case LOG_WARN: fprintf(IsOpened() ? mFile : stderr, "[WARN]: "); break;
- case LOG_INFO: fprintf(IsOpened() ? mFile : stderr, "[INFO]: "); break;
- case LOG_ERROR: fprintf(IsOpened() ? mFile : stderr, "[ERROR]: "); break;
- default: break;
+ switch (type)
+ {
+ case LOG_TRACE:
+ fprintf(IsOpened() ? mFile : stderr, "[TRACE]: ");
+ break;
+ case LOG_DEBUG:
+ fprintf(IsOpened() ? mFile : stderr, "[DEBUG]: ");
+ break;
+ case LOG_WARN:
+ fprintf(IsOpened() ? mFile : stderr, "[WARN]: ");
+ break;
+ case LOG_INFO:
+ fprintf(IsOpened() ? mFile : stderr, "[INFO]: ");
+ break;
+ case LOG_ERROR:
+ fprintf(IsOpened() ? mFile : stderr, "[ERROR]: ");
+ break;
+ default:
+ break;
}
vfprintf(IsOpened() ? mFile : stderr, str, args);
}
-void CLogger::Trace(const char *str, ...)
+void CLogger::Trace(const char* str, ...)
{
va_list args;
va_start(args, str);
@@ -63,7 +75,7 @@ void CLogger::Trace(const char *str, ...)
}
-void CLogger::Debug(const char *str, ...)
+void CLogger::Debug(const char* str, ...)
{
va_list args;
va_start(args, str);
@@ -72,7 +84,7 @@ void CLogger::Debug(const char *str, ...)
}
-void CLogger::Info(const char *str, ...)
+void CLogger::Info(const char* str, ...)
{
va_list args;
va_start(args, str);
@@ -81,7 +93,7 @@ void CLogger::Info(const char *str, ...)
}
-void CLogger::Warn(const char *str, ...)
+void CLogger::Warn(const char* str, ...)
{
va_list args;
va_start(args, str);
@@ -90,7 +102,7 @@ void CLogger::Warn(const char *str, ...)
}
-void CLogger::Error(const char *str, ...)
+void CLogger::Error(const char* str, ...)
{
va_list args;
va_start(args, str);
@@ -99,7 +111,7 @@ void CLogger::Error(const char *str, ...)
}
-void CLogger::Message(const char *str, ...)
+void CLogger::Message(const char* str, ...)
{
va_list args;
va_start(args, str);
@@ -118,6 +130,7 @@ void CLogger::SetOutputFile(std::string filename)
void CLogger::Open()
{
mFile = fopen(mFilename.c_str(), "w");
+
if (mFile == NULL)
fprintf(stderr, "Could not create file %s\n", mFilename.c_str());
}
@@ -136,6 +149,45 @@ bool CLogger::IsOpened()
}
-void CLogger::SetLogLevel(LogType type) {
+void CLogger::SetLogLevel(LogLevel type)
+{
mLogLevel = type;
}
+
+
+bool CLogger::ParseLogLevel(const std::string& str, LogLevel& logLevel)
+{
+ if (str == "trace")
+ {
+ logLevel = LOG_TRACE;
+ return true;
+ }
+ else if (str == "debug")
+ {
+ logLevel = LOG_DEBUG;
+ return true;
+ }
+ else if (str == "info")
+ {
+ logLevel = LOG_INFO;
+ return true;
+ }
+ else if (str == "warn")
+ {
+ logLevel = LOG_WARN;
+ return true;
+ }
+ else if (str == "error")
+ {
+ logLevel = LOG_ERROR;
+ return true;
+ }
+ else if (str == "none")
+ {
+ logLevel = LOG_NONE;
+ return true;
+ }
+
+ return false;
+}
+
diff --git a/src/common/logger.h b/src/common/logger.h
index 198e5e5..769f548 100644
--- a/src/common/logger.h
+++ b/src/common/logger.h
@@ -31,10 +31,10 @@
/**
* \public
- * \enum LogType common/logger.h
+ * \enum LogLevel common/logger.h
* \brief Enum representing log level
**/
-enum LogType
+enum LogLevel
{
LOG_TRACE = 1, /*!< lowest level, execution tracing */
LOG_DEBUG = 2, /*!< debugging messages */
@@ -53,65 +53,74 @@ enum LogType
*/
class CLogger : public CSingleton<CLogger>
{
- public:
- CLogger();
- ~CLogger();
-
- /** Write message to console or file
- * \param str - message to write
- * \param ... - additional arguments
- */
- void Message(const char *str, ...);
-
- /** Write message to console or file with LOG_TRACE level
- * \param str - message to write
- * \param ... - additional arguments
- */
- void Trace(const char *str, ...);
-
- /** Write message to console or file with LOG_DEBUG level
- * \param str - message to write
- * \param ... - additional arguments
- */
- void Debug(const char *str, ...);
-
- /** Write message to console or file with LOG_INFO level
- * \param str - message to write
- * \param ... - additional arguments
- */
- void Info(const char *str, ...);
-
- /** Write message to console or file with LOG_WARN level
- * \param str - message to write
- * \param ... - additional arguments
- */
- void Warn(const char *str, ...);
-
- /** Write message to console or file with LOG_ERROR level
- * \param str - message to write
- * \param ... - additional arguments
- */
- void Error(const char *str, ...);
-
- /** Set output file to write logs to
- * \param filename - output file to write to
- */
- void SetOutputFile(std::string filename);
-
- /** Set log level. Logs with level below will not be shown
- * \param level - minimum log level to write
- */
- void SetLogLevel(LogType level);
-
- private:
- std::string mFilename;
- FILE *mFile;
- LogType mLogLevel;
-
- void Open();
- void Close();
- bool IsOpened();
- void Log(LogType type, const char* str, va_list args);
+public:
+ CLogger();
+ ~CLogger();
+
+ /** Write message to console or file
+ * \param str - message to write
+ * \param ... - additional arguments
+ */
+ void Message(const char *str, ...);
+
+ /** Write message to console or file with LOG_TRACE level
+ * \param str - message to write
+ * \param ... - additional arguments
+ */
+ void Trace(const char *str, ...);
+
+ /** Write message to console or file with LOG_DEBUG level
+ * \param str - message to write
+ * \param ... - additional arguments
+ */
+ void Debug(const char *str, ...);
+
+ /** Write message to console or file with LOG_INFO level
+ * \param str - message to write
+ * \param ... - additional arguments
+ */
+ void Info(const char *str, ...);
+
+ /** Write message to console or file with LOG_WARN level
+ * \param str - message to write
+ * \param ... - additional arguments
+ */
+ void Warn(const char *str, ...);
+
+ /** Write message to console or file with LOG_ERROR level
+ * \param str - message to write
+ * \param ... - additional arguments
+ */
+ void Error(const char *str, ...);
+
+ /** Set output file to write logs to
+ * \param filename - output file to write to
+ */
+ void SetOutputFile(std::string filename);
+
+ /** Set log level. Logs with level below will not be shown
+ * \param level - minimum log level to write
+ */
+ void SetLogLevel(LogLevel level);
+
+ /** Parses string as a log level
+ * \param str string to parse
+ * \param logLevel result log level
+ *
+ * Valid values are "trace", "debug", "info", "warn", "error" and "none".
+ * On invalid value, returns \c false.
+ */
+ static bool ParseLogLevel(const std::string& str, LogLevel& logLevel);
+
+private:
+ std::string mFilename;
+ FILE *mFile;
+ LogLevel mLogLevel;
+
+ void Open();
+ void Close();
+ bool IsOpened();
+ void Log(LogLevel type, const char* str, va_list args);
};
diff --git a/src/graphics/opengl/gldevice.cpp b/src/graphics/opengl/gldevice.cpp
index 80fa9a1..beeb85e 100644
--- a/src/graphics/opengl/gldevice.cpp
+++ b/src/graphics/opengl/gldevice.cpp
@@ -51,6 +51,8 @@ void GLDeviceConfig::LoadDefault()
greenSize = 8;
alphaSize = 8;
depthSize = 24;
+
+ vboMode = VBO_MODE_AUTO;
}
@@ -99,11 +101,26 @@ bool CGLDevice::Create()
if (!m_multitextureAvailable)
GetLogger()->Warn("GLEW reports multitexturing not supported - graphics quality will be degraded!\n");
- m_vboAvailable = glewIsSupported("GL_ARB_vertex_buffer_object");
- if (m_vboAvailable)
- GetLogger()->Info("Detected ARB_vertex_buffer_object extension - using VBOs\n");
+ if (m_config.vboMode == VBO_MODE_ENABLE)
+ {
+ GetLogger()->Info("VBO enabled by override - using VBOs\n");
+ m_vboAvailable = true;
+ }
+ else if (m_config.vboMode == VBO_MODE_DISABLE)
+ {
+ GetLogger()->Info("VBO disabled by override - using display lists\n");
+ m_vboAvailable = false;
+ }
else
- GetLogger()->Info("No ARB_vertex_buffer_object extension present - using display lists\n");
+ {
+ GetLogger()->Info("Auto-detecting VBO support\n");
+ m_vboAvailable = glewIsSupported("GL_ARB_vertex_buffer_object");
+
+ if (m_vboAvailable)
+ GetLogger()->Info("Detected ARB_vertex_buffer_object extension - using VBOs\n");
+ else
+ GetLogger()->Info("No ARB_vertex_buffer_object extension present - using display lists\n");
+ }
}
// This is mostly done in all modern hardware by default
diff --git a/src/graphics/opengl/gldevice.h b/src/graphics/opengl/gldevice.h
index 7137671..fe3f2a1 100644
--- a/src/graphics/opengl/gldevice.h
+++ b/src/graphics/opengl/gldevice.h
@@ -34,6 +34,17 @@
namespace Gfx {
/**
+ \enum VBOMode
+ \brief VBO autodetect/override
+ */
+enum VBOMode
+{
+ VBO_MODE_ENABLE, //! < override: enable
+ VBO_MODE_DISABLE, //! < override: disable
+ VBO_MODE_AUTO //! < autodetect
+};
+
+/**
\struct GLDeviceConfig
\brief Additional config with OpenGL-specific settings */
struct GLDeviceConfig : public DeviceConfig
@@ -52,6 +63,9 @@ struct GLDeviceConfig : public DeviceConfig
//! Force hardware acceleration (video mode set will fail on lack of hw accel)
bool hardwareAccel;
+ //! VBO override/autodetect
+ VBOMode vboMode;
+
//! Constructor calls LoadDefaults()
GLDeviceConfig();
diff --git a/test/unit/graphics/engine/lightman_test.cpp b/test/unit/graphics/engine/lightman_test.cpp
index b20b058..c955f0a 100644
--- a/test/unit/graphics/engine/lightman_test.cpp
+++ b/test/unit/graphics/engine/lightman_test.cpp
@@ -110,7 +110,7 @@ TEST_F(LightManagerUT, LightSorting_IncludeTypesAreIncluded)
AddLight(2, LIGHT_PRI_LOW, true, true, Math::Vector(0.0f, 0.0f, 0.0f), ENG_OBJTYPE_TERRAIN, ENG_OBJTYPE_NULL);
AddLight(3, LIGHT_PRI_LOW, true, true, Math::Vector(0.0f, 0.0f, 0.0f), ENG_OBJTYPE_QUARTZ, ENG_OBJTYPE_NULL);
- std::vector<int> expectedLights = { 2, 1 };
+ std::vector<int> expectedLights = { 1, 2 };
CheckLightSorting(ENG_OBJTYPE_TERRAIN, expectedLights);
}
@@ -124,7 +124,7 @@ TEST_F(LightManagerUT, LightSorting_ExcludeTypesAreExcluded)
AddLight(2, LIGHT_PRI_LOW, true, true, Math::Vector(0.0f, 0.0f, 0.0f), ENG_OBJTYPE_NULL, ENG_OBJTYPE_TERRAIN);
AddLight(3, LIGHT_PRI_LOW, true, true, Math::Vector(0.0f, 0.0f, 0.0f), ENG_OBJTYPE_NULL, ENG_OBJTYPE_QUARTZ);
- std::vector<int> expectedLights = { 3, 1 };
+ std::vector<int> expectedLights = { 1, 3 };
CheckLightSorting(ENG_OBJTYPE_TERRAIN, expectedLights);
}