/*
-Copyright (C) 1999-2006 Id Software, Inc. and contributors.
-For a list of contributors, see the accompanying CONTRIBUTORS file.
+ Copyright (C) 1999-2006 Id Software, Inc. and contributors.
+ For a list of contributors, see the accompanying CONTRIBUTORS file.
-This file is part of GtkRadiant.
+ This file is part of GtkRadiant.
-GtkRadiant is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+ GtkRadiant is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
-GtkRadiant is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GtkRadiant is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-You should have received a copy of the GNU General Public License
-along with GtkRadiant; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ You should have received a copy of the GNU General Public License
+ along with GtkRadiant; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
/*! \mainpage GtkRadiant Documentation Index
-\section intro_sec Introduction
+ \section intro_sec Introduction
-This documentation is generated from comments in the source code.
+ This documentation is generated from comments in the source code.
-\section links_sec Useful Links
+ \section links_sec Useful Links
-\link include/itextstream.h include/itextstream.h \endlink - Global output and error message streams, similar to std::cout and std::cerr. \n
+ \link include/itextstream.h include/itextstream.h \endlink - Global output and error message streams, similar to std::cout and std::cerr. \n
-FileInputStream - similar to std::ifstream (binary mode) \n
-FileOutputStream - similar to std::ofstream (binary mode) \n
-TextFileInputStream - similar to std::ifstream (text mode) \n
-TextFileOutputStream - similar to std::ofstream (text mode) \n
-StringOutputStream - similar to std::stringstream \n
+ FileInputStream - similar to std::ifstream (binary mode) \n
+ FileOutputStream - similar to std::ofstream (binary mode) \n
+ TextFileInputStream - similar to std::ifstream (text mode) \n
+ TextFileOutputStream - similar to std::ofstream (text mode) \n
+ StringOutputStream - similar to std::stringstream \n
-\link string/string.h string/string.h \endlink - C-style string comparison and memory management. \n
-\link os/path.h os/path.h \endlink - Path manipulation for radiant's standard path format \n
-\link os/file.h os/file.h \endlink - OS file-system access. \n
+ \link string/string.h string/string.h \endlink - C-style string comparison and memory management. \n
+ \link os/path.h os/path.h \endlink - Path manipulation for radiant's standard path format \n
+ \link os/file.h os/file.h \endlink - OS file-system access. \n
-::CopiedString - automatic string memory management \n
-Array - automatic array memory management \n
-HashTable - generic hashtable, similar to std::hash_map \n
+ ::CopiedString - automatic string memory management \n
+ Array - automatic array memory management \n
+ HashTable - generic hashtable, similar to std::hash_map \n
-\link math/vector.h math/vector.h \endlink - Vectors \n
-\link math/matrix.h math/matrix.h \endlink - Matrices \n
-\link math/quaternion.h math/quaternion.h \endlink - Quaternions \n
-\link math/plane.h math/plane.h \endlink - Planes \n
-\link math/aabb.h math/aabb.h \endlink - AABBs \n
+ \link math/vector.h math/vector.h \endlink - Vectors \n
+ \link math/matrix.h math/matrix.h \endlink - Matrices \n
+ \link math/quaternion.h math/quaternion.h \endlink - Quaternions \n
+ \link math/plane.h math/plane.h \endlink - Planes \n
+ \link math/aabb.h math/aabb.h \endlink - AABBs \n
-Callback MemberCaller FunctionCaller - callbacks similar to using boost::function with boost::bind \n
-SmartPointer SmartReference - smart-pointer and smart-reference similar to Loki's SmartPtr \n
+ Callback MemberCaller0 FunctionCaller - callbacks similar to using boost::function with boost::bind \n
+ SmartPointer SmartReference - smart-pointer and smart-reference similar to Loki's SmartPtr \n
-\link generic/bitfield.h generic/bitfield.h \endlink - Type-safe bitfield \n
-\link generic/enumeration.h generic/enumeration.h \endlink - Type-safe enumeration \n
+ \link generic/bitfield.h generic/bitfield.h \endlink - Type-safe bitfield \n
+ \link generic/enumeration.h generic/enumeration.h \endlink - Type-safe enumeration \n
-DefaultAllocator - Memory allocation using new/delete, compliant with std::allocator interface \n
+ DefaultAllocator - Memory allocation using new/delete, compliant with std::allocator interface \n
-\link debugging/debugging.h debugging/debugging.h \endlink - Debugging macros \n
+ \link debugging/debugging.h debugging/debugging.h \endlink - Debugging macros \n
-*/
+ */
+#include <igl.h>
#include "main.h"
+#include "globaldefs.h"
#include "version.h"
#include "iundo.h"
-#include <gtk/gtkmain.h>
+#include "uilib/uilib.h"
#include "cmdlib.h"
#include "os/file.h"
#include "referencecache.h"
#include "stacktrace.h"
+#if GDEF_OS_WINDOWS
+#include <windows.h>
+#endif
+
void show_splash();
+
void hide_splash();
-void error_redirect (const gchar *domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data)
+void error_redirect(const gchar *domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data)
{
- gboolean in_recursion;
- gboolean is_fatal;
- char buf[256];
-
- in_recursion = (log_level & G_LOG_FLAG_RECURSION) != 0;
- is_fatal = (log_level & G_LOG_FLAG_FATAL) != 0;
- log_level = (GLogLevelFlags) (log_level & G_LOG_LEVEL_MASK);
-
- if (!message)
- message = "(0) message";
-
- if (domain)
- strcpy (buf, domain);
- else
- strcpy (buf, "**");
- strcat (buf, "-");
-
- switch (log_level)
- {
- case G_LOG_LEVEL_ERROR:
- if (in_recursion)
- strcat (buf, "ERROR (recursed) **: ");
- else
- strcat (buf, "ERROR **: ");
- break;
- case G_LOG_LEVEL_CRITICAL:
- if (in_recursion)
- strcat (buf, "CRITICAL (recursed) **: ");
- else
- strcat (buf, "CRITICAL **: ");
- break;
- case G_LOG_LEVEL_WARNING:
- if (in_recursion)
- strcat (buf, "WARNING (recursed) **: ");
- else
- strcat (buf, "WARNING **: ");
- break;
- case G_LOG_LEVEL_MESSAGE:
- if (in_recursion)
- strcat (buf, "Message (recursed): ");
- else
- strcat (buf, "Message: ");
- break;
- case G_LOG_LEVEL_INFO:
- if (in_recursion)
- strcat (buf, "INFO (recursed): ");
- else
- strcat (buf, "INFO: ");
- break;
- case G_LOG_LEVEL_DEBUG:
- if (in_recursion)
- strcat (buf, "DEBUG (recursed): ");
- else
- strcat (buf, "DEBUG: ");
- break;
- default:
- /* we are used for a log level that is not defined by GLib itself,
- * try to make the best out of it.
- */
- if (in_recursion)
- strcat (buf, "LOG (recursed:");
- else
- strcat (buf, "LOG (");
- if (log_level)
- {
- gchar string[] = "0x00): ";
- gchar *p = string + 2;
- guint i;
-
- i = g_bit_nth_msf (log_level, -1);
- *p = i >> 4;
- p++;
- *p = '0' + (i & 0xf);
- if (*p > '9')
- *p += 'A' - '9' - 1;
-
- strcat (buf, string);
- } else
- strcat (buf, "): ");
- }
-
- strcat (buf, message);
- if (is_fatal)
- strcat (buf, "\naborting...\n");
- else
- strcat (buf, "\n");
-
- // spam it...
- globalErrorStream() << buf << "\n";
-
- // FIXME why are warnings is_fatal?
-#ifndef _DEBUG
- if(is_fatal)
-#endif
- ERROR_MESSAGE("GTK+ error: " << buf);
+ gboolean in_recursion;
+ gboolean is_fatal;
+ char buf[256];
+
+ in_recursion = (log_level & G_LOG_FLAG_RECURSION) != 0;
+ is_fatal = (log_level & G_LOG_FLAG_FATAL) != 0;
+ log_level = (GLogLevelFlags) (log_level & G_LOG_LEVEL_MASK);
+
+ if (!message) {
+ message = "(0) message";
+ }
+
+ if (domain) {
+ strcpy(buf, domain);
+ } else {
+ strcpy(buf, "**");
+ }
+ strcat(buf, "-");
+
+ switch (log_level) {
+ case G_LOG_LEVEL_ERROR:
+ if (in_recursion) {
+ strcat(buf, "ERROR (recursed) **: ");
+ } else {
+ strcat(buf, "ERROR **: ");
+ }
+ break;
+ case G_LOG_LEVEL_CRITICAL:
+ if (in_recursion) {
+ strcat(buf, "CRITICAL (recursed) **: ");
+ } else {
+ strcat(buf, "CRITICAL **: ");
+ }
+ break;
+ case G_LOG_LEVEL_WARNING:
+ if (in_recursion) {
+ strcat(buf, "WARNING (recursed) **: ");
+ } else {
+ strcat(buf, "WARNING **: ");
+ }
+ break;
+ case G_LOG_LEVEL_MESSAGE:
+ if (in_recursion) {
+ strcat(buf, "Message (recursed): ");
+ } else {
+ strcat(buf, "Message: ");
+ }
+ break;
+ case G_LOG_LEVEL_INFO:
+ if (in_recursion) {
+ strcat(buf, "INFO (recursed): ");
+ } else {
+ strcat(buf, "INFO: ");
+ }
+ break;
+ case G_LOG_LEVEL_DEBUG:
+ if (in_recursion) {
+ strcat(buf, "DEBUG (recursed): ");
+ } else {
+ strcat(buf, "DEBUG: ");
+ }
+ break;
+ default:
+ /* we are used for a log level that is not defined by GLib itself,
+ * try to make the best out of it.
+ */
+ if (in_recursion) {
+ strcat(buf, "LOG (recursed:");
+ } else {
+ strcat(buf, "LOG (");
+ }
+ if (log_level) {
+ gchar string[] = "0x00): ";
+ gchar *p = string + 2;
+ guint i;
+
+ i = g_bit_nth_msf(log_level, -1);
+ *p = i >> 4;
+ p++;
+ *p = '0' + (i & 0xf);
+ if (*p > '9') {
+ *p += 'A' - '9' - 1;
+ }
+
+ strcat(buf, string);
+ } else {
+ strcat(buf, "): ");
+ }
+ }
+
+ strcat(buf, message);
+ if (is_fatal) {
+ strcat(buf, "\naborting...\n");
+ } else {
+ strcat(buf, "\n");
+ }
+
+ // spam it...
+ globalErrorStream() << buf << "\n";
+
+ if (is_fatal) {
+ ERROR_MESSAGE("GTK+ error: " << buf);
+ }
}
-#if defined (_DEBUG) && defined (WIN32) && defined (_MSC_VER)
+#if GDEF_COMPILER_MSVC && GDEF_DEBUG
#include "crtdbg.h"
#endif
void crt_init()
{
-#if defined (_DEBUG) && defined (WIN32) && defined (_MSC_VER)
- _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
+#if GDEF_COMPILER_MSVC && GDEF_DEBUG
+ _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif
}
-class Lock
-{
- bool m_locked;
+class Lock {
+ bool m_locked;
public:
- Lock() : m_locked(false)
- {
- }
- void lock()
- {
- m_locked = true;
- }
- void unlock()
- {
- m_locked = false;
- }
- bool locked() const
- {
- return m_locked;
- }
+ Lock() : m_locked(false)
+ {
+ }
+
+ void lock()
+ {
+ m_locked = true;
+ }
+
+ void unlock()
+ {
+ m_locked = false;
+ }
+
+ bool locked() const
+ {
+ return m_locked;
+ }
};
-class ScopedLock
-{
- Lock& m_lock;
+class ScopedLock {
+ Lock &m_lock;
public:
- ScopedLock(Lock& lock) : m_lock(lock)
- {
- m_lock.lock();
- }
- ~ScopedLock()
- {
- m_lock.unlock();
- }
+ ScopedLock(Lock &lock) : m_lock(lock)
+ {
+ m_lock.lock();
+ }
+
+ ~ScopedLock()
+ {
+ m_lock.unlock();
+ }
};
-class LineLimitedTextOutputStream : public TextOutputStream
-{
- TextOutputStream& outputStream;
- std::size_t count;
+class LineLimitedTextOutputStream : public TextOutputStream {
+ TextOutputStream &outputStream;
+ std::size_t count;
public:
- LineLimitedTextOutputStream(TextOutputStream& outputStream, std::size_t count)
- : outputStream(outputStream), count(count)
- {
- }
- std::size_t write(const char* buffer, std::size_t length)
- {
- if(count != 0)
+ LineLimitedTextOutputStream(TextOutputStream &outputStream, std::size_t count)
+ : outputStream(outputStream), count(count)
{
- const char* p = buffer;
- const char* end = buffer+length;
- for(;;)
- {
- p = std::find(p, end, '\n');
- if(p == end)
- {
- break;
- }
- ++p;
- if(--count == 0)
- {
- length = p - buffer;
- break;
+ }
+
+ std::size_t write(const char *buffer, std::size_t length)
+ {
+ if (count != 0) {
+ const char *p = buffer;
+ const char *end = buffer + length;
+ for (;;) {
+ p = std::find(p, end, '\n');
+ if (p == end) {
+ break;
+ }
+ ++p;
+ if (--count == 0) {
+ length = p - buffer;
+ break;
+ }
+ }
+ outputStream.write(buffer, length);
}
- }
- outputStream.write(buffer, length);
+ return length;
}
- return length;
- }
};
-class PopupDebugMessageHandler : public DebugMessageHandler
-{
- StringOutputStream m_buffer;
- Lock m_lock;
+class PopupDebugMessageHandler : public DebugMessageHandler {
+ StringOutputStream m_buffer;
+ Lock m_lock;
public:
- TextOutputStream& getOutputStream()
- {
- if(!m_lock.locked())
+ TextOutputStream &getOutputStream()
{
- return m_buffer;
- }
- return globalErrorStream();
- }
- bool handleMessage()
- {
- getOutputStream() << "----------------\n";
- LineLimitedTextOutputStream outputStream(getOutputStream(), 24);
- write_stack_trace(outputStream);
- getOutputStream() << "----------------\n";
- globalErrorStream() << m_buffer.c_str();
- if(!m_lock.locked())
+ if (!m_lock.locked()) {
+ return m_buffer;
+ }
+ return globalErrorStream();
+ }
+
+ bool handleMessage()
{
- ScopedLock lock(m_lock);
-#if defined _DEBUG
- m_buffer << "Break into the debugger?\n";
- bool handled = gtk_MessageBox(0, m_buffer.c_str(), "Radiant - Runtime Error", eMB_YESNO, eMB_ICONERROR) == eIDNO;
- m_buffer.clear();
- return handled;
-#else
- m_buffer << "Please report this error to the developers\n";
- gtk_MessageBox(0, m_buffer.c_str(), "Radiant - Runtime Error", eMB_OK, eMB_ICONERROR);
- m_buffer.clear();
-#endif
+ getOutputStream() << "----------------\n";
+ LineLimitedTextOutputStream outputStream(getOutputStream(), 24);
+ write_stack_trace(outputStream);
+ getOutputStream() << "----------------\n";
+ globalErrorStream() << m_buffer.c_str();
+ if (!m_lock.locked()) {
+ ScopedLock lock(m_lock);
+ if (GDEF_DEBUG) {
+ m_buffer << "Break into the debugger?\n";
+ bool handled = ui::alert(ui::root, m_buffer.c_str(), "Radiant - Runtime Error", ui::alert_type::YESNO,
+ ui::alert_icon::Error) == ui::alert_response::NO;
+ m_buffer.clear();
+ return handled;
+ } else {
+ m_buffer << "Please report this error to the developers\n";
+ ui::alert(ui::root, m_buffer.c_str(), "Radiant - Runtime Error", ui::alert_type::OK,
+ ui::alert_icon::Error);
+ m_buffer.clear();
+ }
+ }
+ return true;
}
- return true;
- }
};
typedef Static<PopupDebugMessageHandler> GlobalPopupDebugMessageHandler;
void streams_init()
{
- GlobalErrorStream::instance().setOutputStream(getSysPrintErrorStream());
- GlobalOutputStream::instance().setOutputStream(getSysPrintOutputStream());
+ GlobalErrorStream::instance().setOutputStream(getSysPrintErrorStream());
+ GlobalOutputStream::instance().setOutputStream(getSysPrintOutputStream());
}
void paths_init()
{
- const char* home = environment_get_home_path();
- Q_mkdir(home);
+ g_strSettingsPath = environment_get_home_path();
- {
- StringOutputStream path(256);
- path << home << "1." << RADIANT_MAJOR_VERSION "." << RADIANT_MINOR_VERSION << '/';
- g_strSettingsPath = path.c_str();
- }
-
- Q_mkdir(g_strSettingsPath.c_str());
+ Q_mkdir(g_strSettingsPath.c_str());
- g_strAppPath = environment_get_app_path();
+ g_strAppPath = environment_get_app_path();
- // radiant is installed in the parent dir of "tools/"
- // NOTE: this is not very easy for debugging
- // maybe add options to lookup in several places?
- // (for now I had to create symlinks)
- {
- StringOutputStream path(256);
- path << g_strAppPath.c_str() << "bitmaps/";
- BitmapsPath_set(path.c_str());
- }
+ // radiant is installed in the parent dir of "tools/"
+ // NOTE: this is not very easy for debugging
+ // maybe add options to lookup in several places?
+ // (for now I had to create symlinks)
+ {
+ StringOutputStream path(256);
+ path << g_strAppPath.c_str() << "bitmaps/";
+ BitmapsPath_set(path.c_str());
+ }
- // we will set this right after the game selection is done
- g_strGameToolsPath = g_strAppPath;
+ // we will set this right after the game selection is done
+ g_strGameToolsPath = g_strAppPath;
}
-bool check_version_file(const char* filename, const char* version)
+bool check_version_file(const char *filename, const char *version)
{
- TextFileInputStream file(filename);
- if(!file.failed())
- {
- char buf[10];
- buf[file.read(buf, 9)] = '\0';
-
- // chomp it (the hard way)
- int chomp = 0;
- while(buf[chomp] >= '0' && buf[chomp] <= '9')
- chomp++;
- buf[chomp] = '\0';
-
- return string_equal(buf, version);
- }
- return false;
+ TextFileInputStream file(filename);
+ if (!file.failed()) {
+ char buf[10];
+ buf[file.read(buf, 9)] = '\0';
+
+ // chomp it (the hard way)
+ int chomp = 0;
+ while (buf[chomp] >= '0' && buf[chomp] <= '9') {
+ chomp++;
+ }
+ buf[chomp] = '\0';
+
+ return string_equal(buf, version);
+ }
+ return false;
}
bool check_version()
{
- // a safe check to avoid people running broken installations
- // (otherwise, they run it, crash it, and blame us for not forcing them hard enough to pay attention while installing)
- // make something idiot proof and someone will make better idiots, this may be overkill
- // let's leave it disabled in debug mode in any case
- // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=431
-#ifndef _DEBUG
-#define CHECK_VERSION
-#endif
-#ifdef CHECK_VERSION
- // locate and open RADIANT_MAJOR and RADIANT_MINOR
- bool bVerIsGood = true;
- {
- StringOutputStream ver_file_name(256);
- ver_file_name << AppPath_get() << "RADIANT_MAJOR";
- bVerIsGood = check_version_file(ver_file_name.c_str(), RADIANT_MAJOR_VERSION);
- }
- {
- StringOutputStream ver_file_name(256);
- ver_file_name << AppPath_get() << "RADIANT_MINOR";
- bVerIsGood = check_version_file(ver_file_name.c_str(), RADIANT_MINOR_VERSION);
- }
-
- if (!bVerIsGood)
- {
- StringOutputStream msg(256);
- msg << "This editor binary (" RADIANT_VERSION ") doesn't match what the latest setup has configured in this directory\n"
- "Make sure you run the right/latest editor binary you installed\n"
- << AppPath_get();
- gtk_MessageBox(0, msg.c_str(), "Radiant", eMB_OK, eMB_ICONDEFAULT);
- }
- return bVerIsGood;
-#else
- return true;
-#endif
+ // a safe check to avoid people running broken installations
+ // (otherwise, they run it, crash it, and blame us for not forcing them hard enough to pay attention while installing)
+ // make something idiot proof and someone will make better idiots, this may be overkill
+ // let's leave it disabled in debug mode in any case
+ // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=431
+ if (GDEF_DEBUG) {
+ return true;
+ }
+ // locate and open RADIANT_MAJOR and RADIANT_MINOR
+ bool bVerIsGood = true;
+ {
+ StringOutputStream ver_file_name(256);
+ ver_file_name << AppPath_get() << "RADIANT_MAJOR";
+ bVerIsGood = check_version_file(ver_file_name.c_str(), RADIANT_MAJOR_VERSION);
+ }
+ {
+ StringOutputStream ver_file_name(256);
+ ver_file_name << AppPath_get() << "RADIANT_MINOR";
+ bVerIsGood = check_version_file(ver_file_name.c_str(), RADIANT_MINOR_VERSION);
+ }
+
+ if (!bVerIsGood) {
+ StringOutputStream msg(256);
+ msg
+ << "This editor binary (" RADIANT_VERSION ") doesn't match what the latest setup has configured in this directory\n"
+ "Make sure you run the right/latest editor binary you installed\n"
+ << AppPath_get();
+ ui::alert(ui::root, msg.c_str(), "Radiant", ui::alert_type::OK, ui::alert_icon::Default);
+ }
+ return bVerIsGood;
}
void create_global_pid()
{
- /*!
- the global prefs loading / game selection dialog might fail for any reason we don't know about
- we need to catch when it happens, to cleanup the stateful prefs which might be killing it
- and to turn on console logging for lookup of the problem
- this is the first part of the two step .pid system
- http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=297
- */
- StringOutputStream g_pidFile(256); ///< the global .pid file (only for global part of the startup)
-
- g_pidFile << SettingsPath_get() << "radiant.pid";
-
- FILE *pid;
- pid = fopen (g_pidFile.c_str(), "r");
- if (pid != 0)
- {
- fclose (pid);
-
- if (remove (g_pidFile.c_str()) == -1)
- {
- StringOutputStream msg(256);
- msg << "WARNING: Could not delete " << g_pidFile.c_str();
- gtk_MessageBox (0, msg.c_str(), "Radiant", eMB_OK, eMB_ICONERROR );
- }
+ /*!
+ the global prefs loading / game selection dialog might fail for any reason we don't know about
+ we need to catch when it happens, to cleanup the stateful prefs which might be killing it
+ and to turn on console logging for lookup of the problem
+ this is the first part of the two step .pid system
+ http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=297
+ */
+ StringOutputStream g_pidFile(256); ///< the global .pid file (only for global part of the startup)
- // in debug, never prompt to clean registry, turn console logging auto after a failed start
-#if !defined(_DEBUG)
- StringOutputStream msg(256);
- msg << "Radiant failed to start properly the last time it was run.\n"
- "The failure may be related to current global preferences.\n"
- "Do you want to reset global preferences to defaults?";
+ g_pidFile << SettingsPath_get() << "radiant.pid";
- if (gtk_MessageBox (0, msg.c_str(), "Radiant - Startup Failure", eMB_YESNO, eMB_ICONQUESTION) == eIDYES)
- {
- g_GamesDialog.Reset();
- }
+ FILE *pid;
+ pid = fopen(g_pidFile.c_str(), "r");
+ if (pid != 0) {
+ fclose(pid);
- msg.clear();
- msg << "Logging console output to " << SettingsPath_get() << "radiant.log\nRefer to the log if Radiant fails to start again.";
+ if (remove(g_pidFile.c_str()) == -1) {
+ StringOutputStream msg(256);
+ msg << "WARNING: Could not delete " << g_pidFile.c_str();
+ ui::alert(ui::root, msg.c_str(), "Radiant", ui::alert_type::OK, ui::alert_icon::Error);
+ }
- gtk_MessageBox (0, msg.c_str(), "Radiant - Console Log", eMB_OK);
-#endif
+ // in debug, never prompt to clean registry, turn console logging auto after a failed start
+ if (!GDEF_DEBUG) {
+ StringOutputStream msg(256);
+ msg << "Radiant failed to start properly the last time it was run.\n"
+ "The failure may be related to current global preferences.\n"
+ "Do you want to reset global preferences to defaults?";
+
+ if (ui::alert(ui::root, msg.c_str(), "Radiant - Startup Failure", ui::alert_type::YESNO,
+ ui::alert_icon::Question) == ui::alert_response::YES) {
+ g_GamesDialog.Reset();
+ }
- // set without saving, the class is not in a coherent state yet
- // just do the value change and call to start logging, CGamesDialog will pickup when relevant
- g_GamesDialog.m_bForceLogConsole = true;
- Sys_LogFile(true);
- }
+ msg.clear();
+ msg << "Logging console output to " << SettingsPath_get()
+ << "radiant.log\nRefer to the log if Radiant fails to start again.";
- // create a primary .pid for global init run
- pid = fopen (g_pidFile.c_str(), "w");
- if (pid)
- fclose (pid);
+ ui::alert(ui::root, msg.c_str(), "Radiant - Console Log", ui::alert_type::OK);
+ }
+
+ // set without saving, the class is not in a coherent state yet
+ // just do the value change and call to start logging, CGamesDialog will pickup when relevant
+ g_GamesDialog.m_bForceLogConsole = true;
+ Sys_LogFile(true);
+ }
+
+ // create a primary .pid for global init run
+ pid = fopen(g_pidFile.c_str(), "w");
+ if (pid) {
+ fclose(pid);
+ }
}
void remove_global_pid()
{
- StringOutputStream g_pidFile(256);
- g_pidFile << SettingsPath_get() << "radiant.pid";
-
- // close the primary
- if (remove (g_pidFile.c_str()) == -1)
- {
- StringOutputStream msg(256);
- msg << "WARNING: Could not delete " << g_pidFile.c_str();
- gtk_MessageBox (0, msg.c_str(), "Radiant", eMB_OK, eMB_ICONERROR );
- }
+ StringOutputStream g_pidFile(256);
+ g_pidFile << SettingsPath_get() << "radiant.pid";
+
+ // close the primary
+ if (remove(g_pidFile.c_str()) == -1) {
+ StringOutputStream msg(256);
+ msg << "WARNING: Could not delete " << g_pidFile.c_str();
+ ui::alert(ui::root, msg.c_str(), "Radiant", ui::alert_type::OK, ui::alert_icon::Error);
+ }
}
/*!
-now the secondary game dependant .pid file
-http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=297
-*/
+ now the secondary game dependant .pid file
+ http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=297
+ */
void create_local_pid()
{
- StringOutputStream g_pidGameFile(256); ///< the game-specific .pid file
- g_pidGameFile << SettingsPath_get() << g_pGameDescription->mGameFile.c_str() << "/radiant-game.pid";
-
- FILE *pid = fopen (g_pidGameFile.c_str(), "r");
- if (pid != 0)
- {
- fclose (pid);
- if (remove (g_pidGameFile.c_str()) == -1)
- {
- StringOutputStream msg;
- msg << "WARNING: Could not delete " << g_pidGameFile.c_str();
- gtk_MessageBox (0, msg.c_str(), "Radiant", eMB_OK, eMB_ICONERROR );
- }
+ StringOutputStream g_pidGameFile(256); ///< the game-specific .pid file
+ g_pidGameFile << SettingsPath_get() << g_pGameDescription->mGameFile.c_str() << "/radiant-game.pid";
+
+ FILE *pid = fopen(g_pidGameFile.c_str(), "r");
+ if (pid != 0) {
+ fclose(pid);
+ if (remove(g_pidGameFile.c_str()) == -1) {
+ StringOutputStream msg;
+ msg << "WARNING: Could not delete " << g_pidGameFile.c_str();
+ ui::alert(ui::root, msg.c_str(), "Radiant", ui::alert_type::OK, ui::alert_icon::Error);
+ }
- // in debug, never prompt to clean registry, turn console logging auto after a failed start
-#if !defined(_DEBUG)
- StringOutputStream msg;
- msg << "Radiant failed to start properly the last time it was run.\n"
- "The failure may be caused by current preferences.\n"
- "Do you want to reset all preferences to defaults?";
+ // in debug, never prompt to clean registry, turn console logging auto after a failed start
+ if (!GDEF_DEBUG) {
+ StringOutputStream msg;
+ msg << "Radiant failed to start properly the last time it was run.\n"
+ "The failure may be caused by current preferences.\n"
+ "Do you want to reset all preferences to defaults?";
- if (gtk_MessageBox (0, msg.c_str(), "Radiant - Startup Failure", eMB_YESNO, eMB_ICONQUESTION) == eIDYES)
- {
- Preferences_Reset();
- }
+ if (ui::alert(ui::root, msg.c_str(), "Radiant - Startup Failure", ui::alert_type::YESNO,
+ ui::alert_icon::Question) == ui::alert_response::YES) {
+ Preferences_Reset();
+ }
- msg.clear();
- msg << "Logging console output to " << SettingsPath_get() << "radiant.log\nRefer to the log if Radiant fails to start again.";
+ msg.clear();
+ msg << "Logging console output to " << SettingsPath_get()
+ << "radiant.log\nRefer to the log if Radiant fails to start again.";
- gtk_MessageBox (0, msg.c_str(), "Radiant - Console Log", eMB_OK);
-#endif
+ ui::alert(ui::root, msg.c_str(), "Radiant - Console Log", ui::alert_type::OK);
+ }
- // force console logging on! (will go in prefs too)
- g_GamesDialog.m_bForceLogConsole = true;
- Sys_LogFile(true);
- }
- else
- {
- // create one, will remove right after entering message loop
- pid = fopen (g_pidGameFile.c_str(), "w");
- if (pid)
- fclose (pid);
- }
+ // force console logging on! (will go in prefs too)
+ g_GamesDialog.m_bForceLogConsole = true;
+ Sys_LogFile(true);
+ } else {
+ // create one, will remove right after entering message loop
+ pid = fopen(g_pidGameFile.c_str(), "w");
+ if (pid) {
+ fclose(pid);
+ }
+ }
}
/*!
-now the secondary game dependant .pid file
-http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=297
-*/
+ now the secondary game dependant .pid file
+ http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=297
+ */
void remove_local_pid()
{
- StringOutputStream g_pidGameFile(256);
- g_pidGameFile << SettingsPath_get() << g_pGameDescription->mGameFile.c_str() << "/radiant-game.pid";
- remove(g_pidGameFile.c_str());
+ StringOutputStream g_pidGameFile(256);
+ g_pidGameFile << SettingsPath_get() << g_pGameDescription->mGameFile.c_str() << "/radiant-game.pid";
+ remove(g_pidGameFile.c_str());
}
void user_shortcuts_init()
{
- StringOutputStream path(256);
- path << SettingsPath_get() << g_pGameDescription->mGameFile.c_str() << '/';
- LoadCommandMap(path.c_str());
- SaveCommandMap(path.c_str());
+ StringOutputStream path(256);
+ path << SettingsPath_get() << g_pGameDescription->mGameFile.c_str() << '/';
+ LoadCommandMap(path.c_str());
+ SaveCommandMap(path.c_str());
}
void user_shortcuts_save()
{
- StringOutputStream path(256);
- path << SettingsPath_get() << g_pGameDescription->mGameFile.c_str() << '/';
- SaveCommandMap(path.c_str());
+ StringOutputStream path(256);
+ path << SettingsPath_get() << g_pGameDescription->mGameFile.c_str() << '/';
+ SaveCommandMap(path.c_str());
}
-int main (int argc, char* argv[])
+int main(int argc, char *argv[])
{
- crt_init();
-
- streams_init();
-
- gtk_disable_setlocale();
- gtk_init(&argc, &argv);
-
- // redirect Gtk warnings to the console
- g_log_set_handler ("Gdk", (GLogLevelFlags)(G_LOG_LEVEL_ERROR|G_LOG_LEVEL_CRITICAL|G_LOG_LEVEL_WARNING|
- G_LOG_LEVEL_MESSAGE|G_LOG_LEVEL_INFO|G_LOG_LEVEL_DEBUG|G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION), error_redirect, 0);
- g_log_set_handler ("Gtk", (GLogLevelFlags)(G_LOG_LEVEL_ERROR|G_LOG_LEVEL_CRITICAL|G_LOG_LEVEL_WARNING|
- G_LOG_LEVEL_MESSAGE|G_LOG_LEVEL_INFO|G_LOG_LEVEL_DEBUG|G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION), error_redirect, 0);
- g_log_set_handler ("GtkGLExt", (GLogLevelFlags)(G_LOG_LEVEL_ERROR|G_LOG_LEVEL_CRITICAL|G_LOG_LEVEL_WARNING|
- G_LOG_LEVEL_MESSAGE|G_LOG_LEVEL_INFO|G_LOG_LEVEL_DEBUG|G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION), error_redirect, 0);
- g_log_set_handler ("GLib", (GLogLevelFlags)(G_LOG_LEVEL_ERROR|G_LOG_LEVEL_CRITICAL|G_LOG_LEVEL_WARNING|
- G_LOG_LEVEL_MESSAGE|G_LOG_LEVEL_INFO|G_LOG_LEVEL_DEBUG|G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION), error_redirect, 0);
- g_log_set_handler (0, (GLogLevelFlags)(G_LOG_LEVEL_ERROR|G_LOG_LEVEL_CRITICAL|G_LOG_LEVEL_WARNING|
- G_LOG_LEVEL_MESSAGE|G_LOG_LEVEL_INFO|G_LOG_LEVEL_DEBUG|G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION), error_redirect, 0);
+ crt_init();
- GlobalDebugMessageHandler::instance().setHandler(GlobalPopupDebugMessageHandler::instance());
+ streams_init();
- environment_init(argc, argv);
+#if GDEF_OS_WINDOWS
+ HMODULE lib;
+ lib = LoadLibrary( "dwmapi.dll" );
+ if ( lib != 0 ) {
+ void ( WINAPI *qDwmEnableComposition )( bool bEnable ) = ( void (WINAPI *) ( bool bEnable ) )GetProcAddress( lib, "DwmEnableComposition" );
+ if ( qDwmEnableComposition ) {
+ qDwmEnableComposition( FALSE );
+ }
+ FreeLibrary( lib );
+ }
+#endif
- paths_init();
+ const char *mapname = NULL;
+ char const *error = NULL;
+ if (!ui::init(&argc, &argv, "<filename.map>", &error)) {
+ g_print("%s\n", error);
+ return -1;
+ }
- if(!check_version())
- {
- return EXIT_FAILURE;
- }
+ // Gtk already removed parsed `--options`
+ if (argc == 2) {
+ if (strlen(argv[1]) > 1) {
+ if (g_str_has_suffix(argv[1], ".map")) {
+ if (g_path_is_absolute(argv[1])) {
+ mapname = argv[1];
+ } else {
+ mapname = g_build_filename(g_get_current_dir(), argv[1], NULL);
+ }
+ } else {
+ g_print("bad file name, will not load: %s\n", argv[1]);
+ }
+ }
+ } else if (argc > 2) {
+ g_print("%s\n", "too many arguments");
+ return -1;
+ }
- show_splash();
+ // redirect Gtk warnings to the console
+ g_log_set_handler("Gdk", (GLogLevelFlags) (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING |
+ G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG |
+ G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION), error_redirect, 0);
+ g_log_set_handler("Gtk", (GLogLevelFlags) (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING |
+ G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG |
+ G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION), error_redirect, 0);
+ g_log_set_handler("GtkGLExt", (GLogLevelFlags) (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING |
+ G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG |
+ G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION), error_redirect, 0);
+ g_log_set_handler("GLib", (GLogLevelFlags) (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING |
+ G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG |
+ G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION), error_redirect, 0);
+ g_log_set_handler(0, (GLogLevelFlags) (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING |
+ G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG |
+ G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION), error_redirect, 0);
+
+ GlobalDebugMessageHandler::instance().setHandler(GlobalPopupDebugMessageHandler::instance());
+
+ environment_init(argc, (char const **) argv);
+
+ paths_init();
+
+ if (!check_version()) {
+ return EXIT_FAILURE;
+ }
- create_global_pid();
+ show_splash();
- GlobalPreferences_Init();
+ create_global_pid();
- g_GamesDialog.Init();
+ GlobalPreferences_Init();
- g_strGameToolsPath = g_pGameDescription->mGameToolsPath;
-
- remove_global_pid();
+ g_GamesDialog.Init();
- g_Preferences.Init(); // must occur before create_local_pid() to allow preferences to be reset
+ g_strGameToolsPath = g_pGameDescription->mGameToolsPath;
- create_local_pid();
+ remove_global_pid();
- // in a very particular post-.pid startup
- // we may have the console turned on and want to keep it that way
- // so we use a latching system
- if (g_GamesDialog.m_bForceLogConsole)
- {
- Sys_LogFile(true);
- g_Console_enableLogging = true;
- g_GamesDialog.m_bForceLogConsole = false;
- }
+ g_Preferences.Init(); // must occur before create_local_pid() to allow preferences to be reset
+ create_local_pid();
- Radiant_Initialise();
+ // in a very particular post-.pid startup
+ // we may have the console turned on and want to keep it that way
+ // so we use a latching system
+ if (g_GamesDialog.m_bForceLogConsole) {
+ Sys_LogFile(true);
+ g_Console_enableLogging = true;
+ g_GamesDialog.m_bForceLogConsole = false;
+ }
- global_accel_init();
- user_shortcuts_init();
+ Radiant_Initialise();
- g_pParentWnd = 0;
- g_pParentWnd = new MainFrame();
+ user_shortcuts_init();
- hide_splash();
+ OpenGLBinding &GL = GlobalOpenGLModule::getTable();
+ g_pParentWnd = new MainFrame(GL);
- if (g_bLoadLastMap && !g_strLastMap.empty())
- {
- Map_LoadFile(g_strLastMap.c_str());
- }
- else
- {
- Map_New();
- }
+ hide_splash();
- // load up shaders now that we have the map loaded
- // eviltypeguy
- TextureBrowser_ShowStartupShaders(GlobalTextureBrowser());
+ if (mapname != NULL) {
+ Map_LoadFile(mapname);
+ } else if (g_bLoadLastMap && !g_strLastMap.empty()) {
+ Map_LoadFile(g_strLastMap.c_str());
+ } else {
+ Map_New();
+ }
+ // load up shaders now that we have the map loaded
+ // eviltypeguy
+ TextureBrowser_ShowStartupShaders(GlobalTextureBrowser());
- remove_local_pid();
- gtk_main();
+ remove_local_pid();
- // avoid saving prefs when the app is minimized
- if (g_pParentWnd->IsSleeping())
- {
- globalOutputStream() << "Shutdown while sleeping, not saving prefs\n";
- g_preferences_globals.disable_ini = true;
- }
+ ui::main();
- Map_Free();
+ // avoid saving prefs when the app is minimized
+ if (g_pParentWnd->IsSleeping()) {
+ globalOutputStream() << "Shutdown while sleeping, not saving prefs\n";
+ g_preferences_globals.disable_ini = true;
+ }
- if (!Map_Unnamed(g_map))
- {
- g_strLastMap = Map_Name(g_map);
- }
+ Map_Free();
- delete g_pParentWnd;
+ if (!Map_Unnamed(g_map)) {
+ g_strLastMap = Map_Name(g_map);
+ }
- user_shortcuts_save();
+ delete g_pParentWnd;
- global_accel_destroy();
+ user_shortcuts_save();
- Radiant_Shutdown();
+ Radiant_Shutdown();
- // close the log file if any
- Sys_LogFile(false);
+ // close the log file if any
+ Sys_LogFile(false);
- return EXIT_SUCCESS;
+ return EXIT_SUCCESS;
}
-