From 64fce8d321463e3170b0d2e9a9ee7a1d3547122e Mon Sep 17 00:00:00 2001 From: Jan Borsodi Date: Sun, 19 Sep 2010 02:01:01 +0200 Subject: [PATCH] Added an option (USE_DEBUG_CONSOLE) to cmake file to disable the console for debug builds on windows. If set to false all debug output is redirect to the debug output of Visual Studio. --- CMakeLists.txt | 25 +++++++++++++ apps/openmw/main.cpp | 85 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 01ca18540..6f1b6a2cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,10 @@ option(USE_MPG123 "use mpg123 + libsndfile for sound" ON) set(MORROWIND_DATA_FILES "data" CACHE PATH "location of Morrowind data files") +if (WIN32) + option(USE_DEBUG_CONSOLE "whether a debug console should be enabled for debug builds, if false debug output is redirected to Visual Studio output" ON) +endif() + # We probably support older versions than this. cmake_minimum_required(VERSION 2.6) @@ -299,3 +303,24 @@ option(BUILD_ESMTOOL "build ESM inspector" ON) if (BUILD_ESMTOOL) add_subdirectory( apps/esmtool ) endif() + +if (WIN32) + if (USE_DEBUG_CONSOLE) + set_target_properties(openmw PROPERTIES LINK_FLAGS_DEBUG "/SUBSYSTEM:CONSOLE") + set_target_properties(openmw PROPERTIES LINK_FLAGS_RELWITHDEBINFO "/SUBSYSTEM:CONSOLE") + set_target_properties(openmw PROPERTIES COMPILE_DEFINITIONS_DEBUG "_CONSOLE") + else() + # Turn off debug console, debug output will be written to visual studio output instead + set_target_properties(openmw PROPERTIES LINK_FLAGS_DEBUG "/SUBSYSTEM:WINDOWS") + set_target_properties(openmw PROPERTIES LINK_FLAGS_RELWITHDEBINFO "/SUBSYSTEM:WINDOWS") + endif() + + # Release builds use the debug console + set_target_properties(openmw PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:CONSOLE") + set_target_properties(openmw PROPERTIES COMPILE_DEFINITIONS_RELEASE "_CONSOLE") + set_target_properties(openmw PROPERTIES LINK_FLAGS_MINSIZEREL "/SUBSYSTEM:CONSOLE") + + # TODO: At some point release builds should not use the console but rather write to a log file + #set_target_properties(openmw PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS") + #set_target_properties(openmw PROPERTIES LINK_FLAGS_MINSIZEREL "/SUBSYSTEM:WINDOWS") +endif() diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index b622b1f27..76eea1107 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -8,6 +8,22 @@ #include #include "engine.hpp" +#if defined(_WIN32) && !defined(_CONSOLE) +#include +#include + +# if !defined(_DEBUG) +# include +# include +# endif + +// For OutputDebugString +#include +// makes __argc and __argv available on windows +#include + +#endif + using namespace std; /// Parse command line options and openmw.cfg file (if one exists). Results are directly @@ -80,6 +96,7 @@ bool parseOptions (int argc, char**argv, OMW::Engine& engine) int main(int argc, char**argv) { + try { OMW::Engine engine; @@ -97,3 +114,71 @@ int main(int argc, char**argv) return 0; } + +// Platform specific for Windows when there is no console built into the executable. +// Windows will call the WinMain function instead of main in this case, the normal +// main function is then called with the __argc and __argv parameters. +// In addition if it is a debug build it will redirect cout to the debug console in Visual Studio +#if defined(_WIN32) && !defined(_CONSOLE) + +#if defined(_DEBUG) +class DebugOutput : public boost::iostreams::sink +{ +public: + std::streamsize write(const char *str, std::streamsize size) + { + // Make a copy for null termination + std::string tmp (str, size); + // Write string to Visual Studio Debug output + OutputDebugString (tmp.c_str ()); + return size; + } +}; +#else +class Logger : public boost::iostreams::sink +{ +public: + Logger(std::ofstream &stream) + : out(stream) + { + } + + std::streamsize write(const char *str, std::streamsize size) + { + out.write (str, size); + out.flush(); + return size; + } + +private: + std::ofstream &out; +}; +#endif + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) +{ + std::streambuf* old_rdbuf = std::cout.rdbuf (); + + int ret = 0; +#if defined(_DEBUG) + // Redirect cout to VS debug output when running in debug mode + { + boost::iostreams::stream_buffer sb; + sb.open(DebugOutput()); +#else + // Redirect cout to openmw.log + std::ofstream logfile ("openmw.log"); + { + boost::iostreams::stream_buffer sb; + sb.open (Logger (logfile)); +#endif + std::cout.rdbuf (&sb); + + ret = main (__argc, __argv); + + std::cout.rdbuf(old_rdbuf); + } + return ret; +} + +#endif