ONLY do IO output when we are running it from a console/terminal

This commit is contained in:
/nick haya 2022-02-11 12:16:42 +08:00
parent c6023cd642
commit 28cd1e0bfb
4 changed files with 100 additions and 4 deletions

View file

@ -18,6 +18,7 @@
#include <Windows.h>
#include <stdlib.h>
#include "argh.h"
#include "guicon.h"
using namespace std;
using namespace Render;
@ -150,6 +151,8 @@ int main(int argc, char* argv[])
return EXIT_FAILURE;
}
RedirectIOToConsole();
parser pa(argc, argv);
if (pa[{"-v", "--verbose"}])
log("", "Verbose mode enabled.", NORMAL, __FILENAME__, __LINE__);

View file

@ -204,8 +204,6 @@ void Render::Object::centerSelf(AXIS axis) {
}
bool Render::Init(string window_name) {
consoleD = GetConsoleWindow();
SetWindowTextA(consoleD, "Logging window");
std::ofstream logFile;
logFile.open("log.txt", std::ofstream::out | std::ofstream::trunc);
logFile.close();
@ -300,8 +298,6 @@ bool Render::Update() {
}
}
SetWindowTextA(consoleD, "Logging window");
int start = SDL_GetPerformanceCounter();
int current = SDL_GetTicks();
@ -357,6 +353,7 @@ bool Render::Update() {
music.deinit();
TTF_Quit();
SDL_Quit();
ReleaseConsole();
return false;
}

View file

@ -28,6 +28,8 @@
#include "toml.hpp"
#include <fstream>
#include "guicon.h"
#ifdef _WIN32 || WIN32
#define __FILENAME__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
#else

94
src/guicon.h Normal file
View file

@ -0,0 +1,94 @@
#ifndef __GUICON_H__
#define __GUICON_H__
#include <windows.h>
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <iostream>
#include <fstream>
#include <stdint.h>
using namespace std;
static const WORD MAX_CONSOLE_LINES = 500;
// Redirect IO calls (stdout, stderr, and others) to the console output (if available)
inline void RedirectIOToConsole() {
// make sure we actually HAVE a console to gawk at
if (AttachConsole(ATTACH_PARENT_PROCESS))
{
// Redirect CRT standard input, output and error handles to the console window.
FILE * pNewStdout = nullptr;
FILE * pNewStderr = nullptr;
FILE * pNewStdin = nullptr;
::freopen_s(&pNewStdout, "CONOUT$", "w", stdout);
::freopen_s(&pNewStderr, "CONOUT$", "w", stderr);
::freopen_s(&pNewStdin, "CONIN$", "r", stdin);
// Clear the error state for all of the C++ standard streams. Attempting to accessing the streams before they refer
// to a valid target causes the stream to enter an error state. Clearing the error state will fix this problem,
// which seems to occur in newer version of Visual Studio even when the console has not been read from or written
// to yet.
std::cout.clear();
std::cerr.clear();
std::cin.clear();
std::wcout.clear();
std::wcerr.clear();
std::wcin.clear();
COORD topLeft = { 0, 0 };
HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO screen;
DWORD written;
GetConsoleScreenBufferInfo(console, &screen);
FillConsoleOutputCharacterA(
console, ' ', screen.dwSize.X * screen.dwSize.Y, topLeft, &written
);
FillConsoleOutputAttribute(
console, FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE,
screen.dwSize.X * screen.dwSize.Y, topLeft, &written
);
SetConsoleCursorPosition(console, topLeft);
}
}
inline bool ReleaseConsole()
{
bool result = true;
FILE* fp;
// Just to be safe, redirect standard IO to NUL before releasing.
cout << "END OF OUTPUT, PRESS ENTER" << endl;
std::cout.flush();
// Redirect STDIN to NUL
if (freopen_s(&fp, "NUL:", "r", stdin) != 0)
result = false;
else
setvbuf(stdin, NULL, _IONBF, 0);
// Redirect STDOUT to NUL
if (freopen_s(&fp, "NUL:", "w", stdout) != 0)
result = false;
else
setvbuf(stdout, NULL, _IONBF, 0);
// Redirect STDERR to NUL
if (freopen_s(&fp, "NUL:", "w", stderr) != 0)
result = false;
else
setvbuf(stderr, NULL, _IONBF, 0);
// Detach from console
if (!FreeConsole())
result = false;
return result;
}
#endif