From ca12b10ec3bae4c7bd44bb72f0f7d12d5ae39267 Mon Sep 17 00:00:00 2001 From: Nils Gaitzsch Date: Fri, 1 May 2020 20:42:17 +0200 Subject: [PATCH] Added Debug Console Window Added Script function that handles standalone script commands --- TR5Main/Scripting/GameLogicScript.cpp | 19 ++++++-- TR5Main/Scripting/GameLogicScript.h | 5 +- TR5Main/Specific/winmain.cpp | 67 ++++++++++++++++++++++++--- 3 files changed, 79 insertions(+), 12 deletions(-) diff --git a/TR5Main/Scripting/GameLogicScript.cpp b/TR5Main/Scripting/GameLogicScript.cpp index cf6a281f1..1c0282b7f 100644 --- a/TR5Main/Scripting/GameLogicScript.cpp +++ b/TR5Main/Scripting/GameLogicScript.cpp @@ -1033,7 +1033,7 @@ void GameScript::FreeLevelScripts() */ } -string GameScript::loadScriptFromFile(char* luaFilename) +string GameScript::loadScriptFromFile(const char* luaFilename) { ifstream ifs(luaFilename, ios::in | ios::binary | ios::ate); @@ -1046,10 +1046,9 @@ string GameScript::loadScriptFromFile(char* luaFilename) return string(bytes.data(), fileSize); } -bool GameScript::ExecuteScript(char* luaFilename, string* message) +bool GameScript::ExecuteScript(const char* luaFilename, string* message) { sol::protected_function_result result; - result = m_lua->safe_script_file(luaFilename, sol::environment(m_lua->lua_state(), sol::create, m_lua->globals()), sol::script_pass_on_error); if (!result.valid()) { @@ -1061,6 +1060,20 @@ bool GameScript::ExecuteScript(char* luaFilename, string* message) return true; } +bool GameScript::ExecuteString(const char* command, string* message) +{ + sol::protected_function_result result; + result = m_lua->safe_script(command); + if (!result.valid()) + { + sol::error error = result; + *message = error.what(); + return false; + } + message->clear(); + return true; +} + bool GameScript::ExecuteTrigger(short index) { return true; diff --git a/TR5Main/Scripting/GameLogicScript.h b/TR5Main/Scripting/GameLogicScript.h index 8cc3c88cb..ae7f6b22f 100644 --- a/TR5Main/Scripting/GameLogicScript.h +++ b/TR5Main/Scripting/GameLogicScript.h @@ -136,12 +136,13 @@ private: map m_itemsMapName; vector m_triggers; - string loadScriptFromFile(char* luaFilename); + string loadScriptFromFile(const char* luaFilename); public: GameScript(sol::state* lua); - bool ExecuteScript(char* luaFilename, string* message); + bool ExecuteScript(const char* luaFilename, string* message); + bool ExecuteString(const char* command, string* message); void FreeLevelScripts(); void AddTrigger(LuaFunction* function); void AddLuaId(int luaId, short itemNumber); diff --git a/TR5Main/Specific/winmain.cpp b/TR5Main/Specific/winmain.cpp index b6476bbec..e4befc558 100644 --- a/TR5Main/Specific/winmain.cpp +++ b/TR5Main/Specific/winmain.cpp @@ -19,7 +19,10 @@ #include "..\Specific\level.h" #include "configuration.h" - +#include +#include +#include +#include WINAPP App; unsigned int threadId; uintptr_t hThread; @@ -28,12 +31,13 @@ byte receivedWmClose = false; bool Debug = false; HWND WindowsHandle; int App_Unk00D9ABFD; - +extern string LuaMessage; extern int IsLevelLoading; extern GameFlow* g_GameFlow; extern GameScript* g_GameScript; extern GameConfiguration g_Configuration; - +DWORD DebugConsoleThreadID; +DWORD MainThreadID; int lua_exception_handler(lua_State *L, sol::optional maybe_exception, sol::string_view description) { return luaL_error(L, description.data()); @@ -89,8 +93,32 @@ void __stdcall HandleWmCommand(unsigned short wParam) } } +void HandleScriptMessage(WPARAM wParam) +{ + string message = *(string*)(wParam); + const string luafileSuffix(".lua"); + //check whether line starts with "lua " + if (message.rfind("lua ", 0) == 0) { + string scriptSubstring = message.substr(4); + //check whether the string ends with .lua, if yes execute from file, otherwise execute directly + if (scriptSubstring.rfind(luafileSuffix) == (scriptSubstring.size() - luafileSuffix.size())) { + g_GameScript->ExecuteScript(scriptSubstring.c_str(),&LuaMessage); + } + else { + g_GameScript->ExecuteString(scriptSubstring.c_str(), &LuaMessage); + } + + } + +} + LRESULT CALLBACK WinAppProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { + if (msg == WM_USER + 0) { + HandleScriptMessage(wParam); + + return 0; + } // Disables ALT + SPACE if (msg == WM_SYSCOMMAND && wParam == SC_KEYMENU) { return 0; @@ -184,7 +212,6 @@ int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdL if (wcscmp(argv[i], L"/debug") == 0) Debug = true; } - LocalFree(argv); // Clear Application Structure @@ -280,7 +307,6 @@ int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdL } WindowsHandle = App.WindowHandle; - // Initialise the renderer g_Renderer->Initialise(g_Configuration.Width, g_Configuration.Height, g_Configuration.RefreshRate, g_Configuration.Windowed, App.WindowHandle); @@ -298,7 +324,34 @@ int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdL UpdateWindow(WindowsHandle); ShowWindow(WindowsHandle, nShowCmd); - + //Create debug script terminal + if (Debug) { + MainThreadID = GetWindowThreadProcessId(WindowsHandle, NULL); + AllocConsole(); + HANDLE handle_in = GetStdHandle(STD_INPUT_HANDLE); + DWORD consoleModeIn; + int hCrt = _open_osfhandle((long)handle_in, _O_BINARY); + FILE* hf_in = _fdopen(hCrt, "r"); + setvbuf(hf_in, NULL, _IONBF, 512); + *stdin = *hf_in; + GetConsoleMode(handle_in, &consoleModeIn); + consoleModeIn = consoleModeIn | ENABLE_LINE_INPUT; + SetConsoleMode(handle_in, consoleModeIn); + LPTHREAD_START_ROUTINE readConsoleLoop = [](LPVOID params) -> DWORD { + DWORD read; + CHAR buffer[4096]; + while (true) { + BOOL success = ReadFile(params, &buffer, 4096, &read, NULL); + if (success) { + //Only send the actual written message minus \r\n + string msg(buffer, read-2); + SendMessageA(WindowsHandle, WM_USER + 0, (WPARAM)&msg, NULL); + } + }; + return 0; + }; + CreateThread(NULL, 0, readConsoleLoop, handle_in, 0, &DebugConsoleThreadID); + } SetCursor(0); ShowCursor(0); hAccTable = LoadAcceleratorsA(hInstance, (LPCSTR)0x65); @@ -337,4 +390,4 @@ int WinClose() SaveGame::End(); return 0; -} +} \ No newline at end of file