From 7b9e6265975092cd3899a4d058a1221ebf99e525 Mon Sep 17 00:00:00 2001 From: mtabachenko Date: Wed, 28 Aug 2013 20:33:46 +0000 Subject: [PATCH] winport: - fix bug on save console position; - add pause key handler in console; - add skip "Ctrl+C", "Ctrl+Break" events in console; --- desmume/src/windows/console.cpp | 113 ++++++++++++++++++++++++-------- desmume/src/windows/console.h | 1 + desmume/src/windows/main.cpp | 6 +- 3 files changed, 90 insertions(+), 30 deletions(-) diff --git a/desmume/src/windows/console.cpp b/desmume/src/windows/console.cpp index de09ce8fc..a314a5ce4 100644 --- a/desmume/src/windows/console.cpp +++ b/desmume/src/windows/console.cpp @@ -19,13 +19,15 @@ #include #include #include -#include "version.h" - +#include "../version.h" +#include "main.h" ///////////////////////////////////////////////////////////////// Console #define BUFFER_SIZE 100 -HANDLE hConsole = NULL; +HANDLE hConsoleOut = NULL; +HANDLE hConsoleIn = NULL; HWND gConsoleWnd = NULL; +DWORD oldmode = 0; void printlog(const char *fmt, ...); std::wstring SkipEverythingButProgramInCommandLine(wchar_t* cmdLine) @@ -65,13 +67,42 @@ std::wstring SkipEverythingButProgramInCommandLine(wchar_t* cmdLine) return path + L" " + remainder; } +BOOL WINAPI HandlerRoutine(DWORD dwCtrlType) +{ + return ((dwCtrlType == CTRL_C_EVENT) || (dwCtrlType == CTRL_BREAK_EVENT)); +} + +void readConsole() +{ + INPUT_RECORD buf[10]; + DWORD num = 0; + if (PeekConsoleInput(hConsoleIn, buf, 10, &num)) + { + if (num) + { + for (u32 i = 0; i < num; i++) + { + if ((buf[i].EventType == KEY_EVENT) && (buf[i].Event.KeyEvent.bKeyDown) && (buf[i].Event.KeyEvent.wVirtualKeyCode == 0x13)) + { + if (execute) + NDS_Pause(false); + else + NDS_UnPause(false); + break; + } + } + FlushConsoleInputBuffer(hConsoleIn); + } + } +} + void OpenConsole() { //dont do anything if we're already analyzed - if (hConsole) return; + if (hConsoleOut) return; - hConsole = GetStdHandle(STD_OUTPUT_HANDLE); - DWORD fileType = GetFileType(hConsole); + hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE); + DWORD fileType = GetFileType(hConsoleOut); //is FILE_TYPE_UNKNOWN (0) with no redirect //is FILE_TYPE_DISK (1) for redirect to file //is FILE_TYPE_PIPE (3) for pipe @@ -91,11 +122,11 @@ void OpenConsole() HMODULE lib = LoadLibrary("kernel32.dll"); if(lib) { - typedef BOOL (WINAPI *_TAttachConsole)(DWORD dwProcessId); - _TAttachConsole _AttachConsole = (_TAttachConsole)GetProcAddress(lib,"AttachConsole"); - if(_AttachConsole) + typedef BOOL (WINAPI *_TAttachConsoleOut)(DWORD dwProcessId); + _TAttachConsoleOut _AttachConsoleOut = (_TAttachConsoleOut)GetProcAddress(lib,"AttachConsoleOut"); + if(_AttachConsoleOut) { - if(!_AttachConsole(-1)) + if(!_AttachConsoleOut(-1)) { FreeLibrary(lib); return; @@ -120,42 +151,68 @@ void OpenConsole() freopen("CONIN$", "r", stdin); } + SetConsoleCtrlHandler(HandlerRoutine, TRUE); + hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE); + hConsoleIn = GetStdHandle(STD_INPUT_HANDLE); + GetConsoleMode(hConsoleIn, &oldmode); + SetConsoleMode(hConsoleIn, ENABLE_WINDOW_INPUT); + gConsoleWnd = GetConsoleWindow(); - if (gConsoleWnd) + RECT pos = {0}; + if (gConsoleWnd && GetWindowRect(gConsoleWnd, &pos)) { - RECT rc = {0}; - if (GetWindowRect(gConsoleWnd, &rc)) + LONG x = std::max((LONG)0, pos.left); + LONG y = std::max((LONG)0, pos.top); + LONG width = std::max((LONG)0, (pos.right - pos.left)); + LONG height = std::max((LONG)0, (pos.bottom - pos.top)); + + x = GetPrivateProfileInt("Console", "PosX", x, IniName); + y = GetPrivateProfileInt("Console", "PosY", y, IniName); + width = GetPrivateProfileInt("Console", "Width", width, IniName); + height = GetPrivateProfileInt("Console", "Height", height, IniName); + + if (x < 0) x = 0; + if (y < 0) y = 0; + if (width < 200) width = 200; + if (height < 100) height = 100; + + HWND desktop = GetDesktopWindow(); + if (desktop && GetClientRect(desktop, &pos)) { - rc.left = GetPrivateProfileInt("Console", "PosX", rc.left, IniName); - rc.top = GetPrivateProfileInt("Console", "PosY", rc.top, IniName); - rc.right = GetPrivateProfileInt("Console", "Width", (rc.right - rc.left), IniName); - rc.bottom = GetPrivateProfileInt("Console", "Height", (rc.bottom - rc.top), IniName); - SetWindowPos(gConsoleWnd, NULL, rc.left, rc.top, rc.right, rc.bottom, SWP_NOACTIVATE); + if (x >= pos.right) x = 0; + if (y >= pos.bottom) y = 0; } + + SetWindowPos(gConsoleWnd, NULL, x, y, width, height, SWP_NOACTIVATE); } - printlog("%s\n",EMU_DESMUME_NAME_AND_VERSION()); - printlog("- compiled: %s %s\n",__DATE__,__TIME__); - if(attached) printf("\nuse cmd /c desmume.exe to get more sensible console behaviour\n"); + printlog("%s\n", EMU_DESMUME_NAME_AND_VERSION()); + printlog("- compiled: %s %s\n", __DATE__, __TIME__); + if(attached) + printf("\nuse cmd /c desmume.exe to get more sensible console behaviour\n"); printlog("\n"); } void CloseConsole() { RECT pos = {0}; + SetConsoleMode(hConsoleIn, oldmode); - if (GetWindowRect(gConsoleWnd, &pos)) + if (gConsoleWnd && GetWindowRect(gConsoleWnd, &pos)) { - WritePrivateProfileInt("Console", "PosX", pos.left, IniName); - WritePrivateProfileInt("Console", "PosY", pos.top, IniName); - WritePrivateProfileInt("Console", "Width", (pos.right - pos.left), IniName); - WritePrivateProfileInt("Console", "Height", (pos.bottom - pos.top), IniName); + LONG width = std::max((LONG)0, (pos.right - pos.left)); + LONG height = std::max((LONG)0, (pos.bottom - pos.top)); + WritePrivateProfileInt("Console", "PosX", pos.left, IniName); + WritePrivateProfileInt("Console", "PosY", pos.top, IniName); + WritePrivateProfileInt("Console", "Width", width, IniName); + WritePrivateProfileInt("Console", "Height", height, IniName); } + FreeConsole(); - hConsole = NULL; + hConsoleOut = NULL; } -void ConsoleTop(bool top) +void ConsoleAlwaysTop(bool top) { if (!gConsoleWnd) return; SetWindowPos(gConsoleWnd, (top?HWND_TOPMOST:HWND_NOTOPMOST), 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); diff --git a/desmume/src/windows/console.h b/desmume/src/windows/console.h index 582652f47..f40a3d0cc 100644 --- a/desmume/src/windows/console.h +++ b/desmume/src/windows/console.h @@ -33,5 +33,6 @@ void OpenConsole(); void CloseConsole(); void ConsoleAlwaysTop(bool top); +void readConsole(); #endif \ No newline at end of file diff --git a/desmume/src/windows/main.cpp b/desmume/src/windows/main.cpp index 3e5ce8db7..4304b37b5 100644 --- a/desmume/src/windows/main.cpp +++ b/desmume/src/windows/main.cpp @@ -2080,6 +2080,8 @@ void CheckMessages() } } } + if (gShowConsole) + readConsole(); } static void InvokeOnMainThread(void (*function)(DWORD), DWORD argument) @@ -3544,7 +3546,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, if (gShowConsole) { OpenConsole(); // Init debug console - //ConsoleAlwaysTop(gConsoleTopmost); + ConsoleAlwaysTop(gConsoleTopmost); } //-------------------------------- @@ -6082,7 +6084,7 @@ DOKEYDOWN: case IDM_CONSOLE_ALWAYS_ON_TOP: { gConsoleTopmost = !gConsoleTopmost; - //ConsoleAlwaysTop(gConsoleTopmost); + ConsoleAlwaysTop(gConsoleTopmost); WritePrivateProfileBool("Console", "Always On Top", gConsoleTopmost, IniName); } return 0;