Rewrite console writing

- Separate debug_msg and display_msg as separate Source
- Merge writing to one function with proper filtering
This commit is contained in:
phobos2077
2023-06-16 14:57:41 +02:00
parent ad6491d61e
commit 2cef5310e2
4 changed files with 50 additions and 29 deletions
+16 -15
View File
@@ -81,8 +81,8 @@ void ConsoleWindow::savePosition() {
IniReader::SetDefaultConfigString(IniSection, IniPositionKey, wndDataStr.c_str());
}
static void __fastcall PrintDebugLog(const char* a) {
ConsoleWindow::instance().falloutLog(a);
static void __fastcall WriteGameLog(const char* a) {
ConsoleWindow::instance().write(a, ConsoleWindow::Source::GAME);
}
static void __declspec(naked) debug_printf_hook() {
@@ -90,7 +90,7 @@ static void __declspec(naked) debug_printf_hook() {
call fo::funcoffs::vsprintf_;
pushadc;
lea ecx, [esp + 16];
call PrintDebugLog;
call WriteGameLog;
popadc;
retn;
}
@@ -108,13 +108,19 @@ void ConsoleWindow::init() {
freopen("CONOUT$", "w", stdout); // this allows to print to console via std::cout
if (_mode & ConsoleSource::GAME) {
if (_mode & Source::GAME) {
std::cout << "Displaying debug_printf output.\n";
HookCall(0x4C6F77, debug_printf_hook);
}
if (_mode & ConsoleSource::SFALL) {
if (_mode & Source::SFALL) {
std::cout << "Displaying sfall debug output.\n";
}
if (_mode & Source::DEBUG_MSG) {
std::cout << "Displaying debug_msg output.\n";
}
if (_mode & Source::DISPLAY_MSG) {
std::cout << "Displaying display_msg output.\n";
}
std::cout << std::endl;
loadPosition();
@@ -126,19 +132,14 @@ ConsoleWindow::~ConsoleWindow() {
savePosition();
}
void ConsoleWindow::falloutLog(const char* a) {
std::cout << a;
_lastSource = ConsoleSource::GAME;
}
void ConsoleWindow::write(const char* message, ConsoleWindow::Source source) {
if (!(_mode & source)) return;
void ConsoleWindow::sfallLog(const std::string& a, int type) {
if (!(_mode & ConsoleSource::SFALL)) return;
if (_lastSource == ConsoleSource::GAME) {
if (source == Source::SFALL && _lastSource != Source::SFALL) {
std::cout << "\n"; // To make logs prettier, because debug_msg places newline before the message.
}
std::cout << a;
_lastSource = ConsoleSource::SFALL;
std::cout << message;
_lastSource = source;
}
}
+10 -8
View File
@@ -21,13 +21,16 @@
namespace sfall
{
enum ConsoleSource : int {
GAME = 1,
SFALL = 2
};
class ConsoleWindow {
public:
enum Source : int {
GAME = 1,
SFALL = 2,
DEBUG_MSG = 4,
DISPLAY_MSG = 8,
};
static ConsoleWindow& instance() { return _instance; }
ConsoleWindow() {}
@@ -38,14 +41,13 @@ public:
void loadPosition();
void savePosition();
void sfallLog(const std::string& a, int type);
void falloutLog(const char* a);
void write(const char* message, Source source);
private:
static ConsoleWindow _instance;
int _mode = 0;
ConsoleSource _lastSource;
Source _lastSource;
bool tryGetWindow(HWND* wnd);
};
+1 -1
View File
@@ -44,7 +44,7 @@ static void OutLog(T a, int type, bool newLine = false) {
if (newLine) ss << "\n";
std::string str = ss.str();
ConsoleWindow::instance().sfallLog(str, type);
ConsoleWindow::instance().write(str.c_str(), ConsoleWindow::Source::SFALL);
Log << str;
Log.flush();
+23 -5
View File
@@ -395,10 +395,11 @@ static void __declspec(naked) combat_load_hack() {
}
}
static void __fastcall PrintLogToConsole(const char* a) {
static void __fastcall DuplicateLogToConsole(const char* a, unsigned long displayMsg) {
auto& console = ConsoleWindow::instance();
console.falloutLog("\n");
console.falloutLog(a);
auto source = displayMsg ? ConsoleWindow::Source::DISPLAY_MSG : ConsoleWindow::Source::DEBUG_MSG;
console.write("\n", source);
console.write(a, source);
}
static void __declspec(naked) op_display_debug_msg_hack() {
@@ -409,14 +410,30 @@ static void __declspec(naked) op_display_debug_msg_hack() {
call ds:[FO_VAR_debug_func];
pushadc;
mov ecx, esi;
call PrintLogToConsole; // duplicate messages to console window
mov edx, [esp + 12];
call DuplicateLogToConsole; // duplicate messages to console window
popadc;
add esp, 4; // eat displayMsg flag
pop eax;
add eax, 17; // skip to the end of functions
jmp eax;
}
}
static void __declspec(naked) op_display_msg_hack() {
__asm {
push 1; // displayMsg = true
jmp op_display_debug_msg_hack;
}
}
static void __declspec(naked) op_debug_msg_hack() {
__asm {
push 0; // displayMsg = false
jmp op_display_debug_msg_hack;
}
}
// Shifts the string one character to the right and inserts a newline control character at the beginning
static void MoveDebugString(char* messageAddr) {
int i = 0;
@@ -469,7 +486,8 @@ static void DebugModePatch() {
BlockCall(0x4C7044); // just nop code
}
// replace calling debug_printf_ with _debug_func, to avoid buffer overflow with messages longer than 260-bytes.
MakeCalls(op_display_debug_msg_hack, {0x45540F, 0x45CB4E}); // op_display_msg and op_debug_msg
MakeCall(0x45540F, op_display_msg_hack);
MakeCall(0x45CB4E, op_debug_msg_hack);
// set the position of the debug window
SafeWrite8(0x4DC34D, 15);