diff --git a/CHANGELOG.md b/CHANGELOG.md index 1923e52377..63bd551843 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -79,6 +79,7 @@ Feature #3276: Editor: Search- Show number of (remaining) search results and indicate a search without any results Feature #3641: Editor: Limit FPS in 3d preview window Feature #3703: Ranged sneak attack criticals + Feature #4012: OpenMW-CS: Create log file like with OpenMW Feature #4222: 360° screenshots Feature #4256: Implement ToggleBorders (TB) console command Feature #4324: Add CFBundleIdentifier in Info.plist to allow for macOS function key shortcuts diff --git a/apps/opencs/main.cpp b/apps/opencs/main.cpp index d599f1f961..7b138169bc 100644 --- a/apps/opencs/main.cpp +++ b/apps/opencs/main.cpp @@ -8,10 +8,13 @@ #include #include -#include "model/doc/messages.hpp" +#include +#include "model/doc/messages.hpp" #include "model/world/universalid.hpp" +#include + #ifdef Q_OS_MAC #include #endif @@ -47,8 +50,43 @@ int main(int argc, char *argv[]) setenv("OSG_GL_TEXTURE_STORAGE", "OFF", 0); #endif + // Some objects used to redirect cout and cerr + // Scope must be here, so this still works inside the catch block for logging exceptions + std::streambuf* cout_rdbuf = std::cout.rdbuf (); + std::streambuf* cerr_rdbuf = std::cerr.rdbuf (); + +#if !(defined(_WIN32) && defined(_DEBUG)) + boost::iostreams::stream_buffer coutsb; + boost::iostreams::stream_buffer cerrsb; +#endif + + std::ostream oldcout(cout_rdbuf); + std::ostream oldcerr(cerr_rdbuf); + + boost::filesystem::ofstream logfile; + + int ret = 0; try - { + { + Files::ConfigurationManager cfgMgr; + +#if defined(_WIN32) && defined(_DEBUG) + // Redirect cout and cerr to VS debug output when running in debug mode + boost::iostreams::stream_buffer sb; + sb.open(Misc::DebugOutput()); + std::cout.rdbuf (&sb); + std::cerr.rdbuf (&sb); +#else + // Redirect cout and cerr to openmw.log + logfile.open (boost::filesystem::path(cfgMgr.getLogPath() / "/openmw-cs.log")); + + coutsb.open (Misc::Tee(logfile, oldcout)); + cerrsb.open (Misc::Tee(logfile, oldcerr)); + + std::cout.rdbuf (&coutsb); + std::cerr.rdbuf (&cerrsb); +#endif + // To allow background thread drawing in OSG QApplication::setAttribute(Qt::AA_X11InitThreads, true); @@ -74,12 +112,23 @@ int main(int argc, char *argv[]) editor.connectToIPCServer(); return 0; } - return editor.run(); + ret = editor.run(); } catch (std::exception& e) { - std::cerr << "ERROR: " << e.what() << std::endl; - return 0; +#if (defined(__APPLE__) || defined(__linux) || defined(__unix) || defined(__posix)) + if (!isatty(fileno(stdin))) +#endif + SDL_ShowSimpleMessageBox(0, "OpenMW-CS: Fatal error", e.what(), NULL); + + std::cerr << "\nERROR: " << e.what() << std::endl; + + ret = 1; } + // Restore cout and cerr + std::cout.rdbuf(cout_rdbuf); + std::cerr.rdbuf(cerr_rdbuf); + + return ret; } diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index d13a731279..ed76726946 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include "engine.hpp" @@ -241,44 +242,6 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat return true; } -#if defined(_WIN32) && 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, static_cast(size)); - // Write string to Visual Studio Debug output - OutputDebugString (tmp.c_str ()); - return size; - } -}; -#else -class Tee : public boost::iostreams::sink -{ -public: - Tee(std::ostream &stream, std::ostream &stream2) - : out(stream), out2(stream2) - { - } - - std::streamsize write(const char *str, std::streamsize size) - { - out.write (str, size); - out.flush(); - out2.write (str, size); - out2.flush(); - return size; - } - -private: - std::ostream &out; - std::ostream &out2; -}; -#endif - #ifdef ANDROID extern "C" int SDL_main(int argc, char**argv) #else @@ -295,8 +258,8 @@ int main(int argc, char**argv) std::streambuf* cerr_rdbuf = std::cerr.rdbuf (); #if !(defined(_WIN32) && defined(_DEBUG)) - boost::iostreams::stream_buffer coutsb; - boost::iostreams::stream_buffer cerrsb; + boost::iostreams::stream_buffer coutsb; + boost::iostreams::stream_buffer cerrsb; #endif std::ostream oldcout(cout_rdbuf); @@ -313,16 +276,16 @@ int main(int argc, char**argv) #if defined(_WIN32) && defined(_DEBUG) // Redirect cout and cerr to VS debug output when running in debug mode - boost::iostreams::stream_buffer sb; - sb.open(DebugOutput()); + boost::iostreams::stream_buffer sb; + sb.open(Misc::DebugOutput()); std::cout.rdbuf (&sb); std::cerr.rdbuf (&sb); #else // Redirect cout and cerr to openmw.log logfile.open (boost::filesystem::path(cfgMgr.getLogPath() / "/openmw.log")); - coutsb.open (Tee(logfile, oldcout)); - cerrsb.open (Tee(logfile, oldcerr)); + coutsb.open (Misc::Tee(logfile, oldcout)); + cerrsb.open (Misc::Tee(logfile, oldcerr)); std::cout.rdbuf (&coutsb); std::cerr.rdbuf (&cerrsb); diff --git a/components/misc/debugging.hpp b/components/misc/debugging.hpp new file mode 100644 index 0000000000..b367f09123 --- /dev/null +++ b/components/misc/debugging.hpp @@ -0,0 +1,47 @@ +#ifndef MISC_DEBUGGING_H +#define MISC_DEBUGGING_H + +#include + +namespace Misc +{ + #if defined(_WIN32) && 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, static_cast(size)); + // Write string to Visual Studio Debug output + OutputDebugString (tmp.c_str ()); + return size; + } + }; + #else + class Tee : public boost::iostreams::sink + { + public: + Tee(std::ostream &stream, std::ostream &stream2) + : out(stream), out2(stream2) + { + } + + std::streamsize write(const char *str, std::streamsize size) + { + out.write (str, size); + out.flush(); + out2.write (str, size); + out2.flush(); + return size; + } + + private: + std::ostream &out; + std::ostream &out2; + }; + #endif +} + +#endif