Batch of adjustments and add features

* FIXED: Use existing WM_PARENTNOTIFY instead of GUI's.
* Put each status feature into their own function.
* IMPROVED: Use RefreshAllStatus when emulation is running.
  * UpdateCaption is not require for constant update menu status.
  * DrawMenuBar is necessary to get proper update status. (Without it, you have to move your mouse over it to get new update status shown.)
* NEW: Log indicator for both GUI and kernel process is shown on right side of LED icon.
* NEW: Log file now perform appand to file instead of overwrite it base on boot status.
This commit is contained in:
RadWolfie 2018-08-16 15:31:54 -05:00
parent 732d35b1f7
commit cb871d8957
10 changed files with 162 additions and 95 deletions

View File

@ -46,6 +46,7 @@ typedef enum class _IPC_UPDATE_GUI {
LLE_FLAGS = 0
, XBOX_LED_COLOUR
, LOG_ENABLED
, KRNL_IS_READY
} IPC_UPDATE_GUI;
void ipc_send_gui_update(IPC_UPDATE_GUI command, const unsigned int value);

View File

@ -622,7 +622,8 @@ void Settings::Delete()
void Settings::SyncToEmulator()
{
// register Core settings
g_EmuShared->SetCoreSettings(&m_core);
g_EmuShared->SetCoreSettings(&m_core);
g_EmuShared->SetIsKrnlLogEnabled(m_core.KrnlDebugMode != DebugMode::DM_NONE);
// register Video settings
g_EmuShared->SetVideoSettings(&m_video);

View File

@ -143,11 +143,13 @@ EmuShared::EmuShared()
m_bFirstLaunch = false;
// Reserve space (default to 0)
m_bReserved1 = false;
m_bReserved2 = false;
m_bReserved3 = false;
m_bReserved4 = false;
memset(m_Reserved99, 0, sizeof(m_Reserved99));
m_Reserved5 = 0;
m_Reserved6 = 0.0f;
std::memset(m_Reserved7, 0, sizeof(m_Reserved7));
std::memset(m_Reserved99, 0, sizeof(m_Reserved99));
}
// ******************************************************************

View File

@ -70,6 +70,10 @@ void ipc_send_gui_update(IPC_UPDATE_GUI command, const unsigned int value)
cmdParam = ID_GUI_STATUS_LOG_ENABLED;
break;
case IPC_UPDATE_GUI::KRNL_IS_READY:
cmdParam = ID_GUI_STATUS_KRNL_IS_READY;
break;
default:
cmdParam = 0;
break;
@ -77,7 +81,7 @@ void ipc_send_gui_update(IPC_UPDATE_GUI command, const unsigned int value)
// Verify command parameter is valid
if (cmdParam != 0) {
SendMessage(CxbxKrnl_hEmuParent, WM_COMMAND, MAKEWPARAM(cmdParam, 0), value);
SendMessage(CxbxKrnl_hEmuParent, WM_PARENTNOTIFY, MAKEWPARAM(cmdParam, 0), value);
}
}

View File

@ -181,7 +181,10 @@
#define IDC_EE_480P 1093
#define IDC_EE_720P 1094
#define IDC_EE_1080I 1095
#define ID_KRNL_IS_READY 1096
#define ID_GUI_STATUS_KRNL_IS_READY 4096
#define ID_GUI_STATUS_LLE_FLAGS 4097
#define ID_GUI_STATUS_XBOX_LED_COLOUR 4098
#define ID_GUI_STATUS_LOG_ENABLED 4099
#define IDC_XBOX_PORT_0 1158
#define IDC_HOST_NOTCONNECT_0_0 1159
#define IDC_HOST_XINPUT_0_0 1160
@ -352,9 +355,7 @@
#define ID_SETTINGS_ALLOWADMINPRIVILEGE 40107
#define ID_SETTINGS_CONFIG_LOGGING 40108
#define ID_SYNC_CONFIG_LOGGING 40109
#define ID_GUI_STATUS_LLE_FLAGS 40110
#define ID_GUI_STATUS_XBOX_LED_COLOUR 40111
#define ID_GUI_STATUS_LOG_ENABLED 40112
#define ID_LOG 40110
#define IDC_STATIC -1
// Next default values for new objects
@ -362,7 +363,7 @@
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 135
#define _APS_NEXT_COMMAND_VALUE 40113
#define _APS_NEXT_COMMAND_VALUE 40111
#define _APS_NEXT_CONTROL_VALUE 1256
#define _APS_NEXT_SYMED_VALUE 104
#endif

View File

@ -109,7 +109,7 @@ void WndMain::InitializeSettings()
g_SaveOnExit = false;
}
#define TIMERID_FPS 0
#define TIMERID_ACTIVE_EMULATION 0
#define TIMERID_LED 1
void WndMain::ResizeWindow(HWND hwnd, bool bForGUI)
@ -166,15 +166,16 @@ void WndMain::ResizeWindow(HWND hwnd, bool bForGUI)
}
WndMain::WndMain(HINSTANCE x_hInstance) :
Wnd(x_hInstance),
m_bCreated(false),
m_Xbe(nullptr),
m_bXbeChanged(false),
m_bIsStarted(false),
m_hwndChild(nullptr),
m_hDebuggerProc(nullptr),
m_hDebuggerMonitorThread(),
m_prevWindowLoc({ -1, -1 })
Wnd(x_hInstance)
, m_bCreated(false)
, m_Xbe(nullptr)
, m_bXbeChanged(false)
, m_bIsStarted(false)
, m_hwndChild(nullptr)
, m_hDebuggerProc(nullptr)
, m_hDebuggerMonitorThread()
, m_prevWindowLoc({ -1, -1 })
, m_LogKrnl_status(false)
{
// initialize members
{
@ -291,13 +292,13 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
}
break;
// NOTE: WM_PARENTNOTIFY was triggered by kernel process' graphic window creation.
case WM_PARENTNOTIFY:
{
switch(LOWORD(wParam))
{
case WM_CREATE:
{
// NOTE: WM_PARENTNOTIFY was triggered by kernel process' graphic window creation.
case WM_PARENTNOTIFY:
{
switch(LOWORD(wParam))
{
case WM_CREATE:
{
if (m_hwndChild == NULL) {
m_FPS_status = 0.0f;
m_MSpF_status = 0.0f;
@ -305,7 +306,7 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
(XBOX_LED_COLOUR_GREEN << 16) |
(XBOX_LED_COLOUR_GREEN << 8) |
(XBOX_LED_COLOUR_GREEN);
SetTimer(hwnd, TIMERID_FPS, 1000, (TIMERPROC)NULL);
SetTimer(hwnd, TIMERID_ACTIVE_EMULATION, 1000, (TIMERPROC)NULL);
SetTimer(hwnd, TIMERID_LED, XBOX_LED_FLASH_PERIOD, (TIMERPROC)NULL);
m_hwndChild = GetWindow(hwnd, GW_CHILD);
UpdateCaption();
@ -314,38 +315,49 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
else {
m_hwndChild = GetWindow(hwnd, GW_CHILD);
}
}
break;
}
break;
case WM_DESTROY:
{
case WM_DESTROY:
{
// (HWND)HIWORD(wParam) seems to be NULL, so we can't compare to m_hwndChild
if (m_hwndChild != NULL) { // Let's hope this signal originated from the only child window
KillTimer(hwnd, TIMERID_FPS);
KillTimer(hwnd, TIMERID_ACTIVE_EMULATION);
KillTimer(hwnd, TIMERID_LED);
m_hwndChild = NULL;
StopEmulation();
DrawLedBitmap(hwnd, true);
}
}
break;
case WM_USER: {
switch(HIWORD(wParam)) {
// NOTE: If anything need to set before kernel process start do anything, do it here.
case ID_KRNL_IS_READY: {
Crash_Manager_Data* pCMD = (Crash_Manager_Data*)malloc(sizeof(Crash_Manager_Data));
pCMD->pWndMain = this;
pCMD->dwChildProcID = lParam; // lParam is process ID.
std::thread(CrashMonitorWrapper, pCMD).detach();
g_EmuShared->SetIsEmulating(true); // NOTE: Putting in here raise to low or medium risk due to debugger will launch itself. (Current workaround)
g_EmuShared->SetIsReady(true);
break;
}
}
break;
}
case WM_COMMAND:
{
case ID_GUI_STATUS_LLE_FLAGS:
m_FlagsLLE_status = static_cast<UINT>(lParam);
break;
case ID_GUI_STATUS_XBOX_LED_COLOUR:
m_LedSeq_status_block = static_cast<UINT>(lParam);
break;
case ID_GUI_STATUS_LOG_ENABLED:
m_LogKrnl_status = static_cast<bool>(lParam);
UpdateLogStatus();
break;
// NOTE: If anything need to set before kernel process start do anything, do it here.
case ID_GUI_STATUS_KRNL_IS_READY: {
Crash_Manager_Data* pCMD = (Crash_Manager_Data*)malloc(sizeof(Crash_Manager_Data));
pCMD->pWndMain = this;
pCMD->dwChildProcID = lParam; // lParam is process ID.
std::thread(CrashMonitorWrapper, pCMD).detach();
g_EmuShared->SetIsEmulating(true); // NOTE: Putting in here raise to low or medium risk due to debugger will launch itself. (Current workaround)
g_EmuShared->SetIsReady(true);
break;
}
}
break;
}
};
break; // added per PVS suggestion.
@ -354,9 +366,9 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
{
switch (wParam)
{
case TIMERID_FPS:
case TIMERID_ACTIVE_EMULATION:
{
UpdateCaption();
RefreshAllStatus();
}
break;
@ -1278,17 +1290,6 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
ShellExecute(NULL, "open", "https://github.com/Cxbx-Reloaded/Cxbx-Reloaded", NULL, NULL, SW_SHOWNORMAL);
break;
case ID_GUI_STATUS_LLE_FLAGS:
m_FlagsLLE_status = static_cast<UINT>(lParam);
break;
case ID_GUI_STATUS_XBOX_LED_COLOUR:
m_LedSeq_status_block = static_cast<UINT>(lParam);
break;
case ID_GUI_STATUS_LOG_ENABLED:
// TODO: Add support for log indication status.
break;
}
break;
@ -1680,6 +1681,7 @@ void WndMain::RefreshMenus()
CheckMenuItem(emul_debg, ID_EMULATION_DEBUGOUTPUTGUI_FILE, MF_UNCHECKED);
break;
}
UpdateLogStatus();
}
// settings menu
@ -1757,6 +1759,8 @@ void WndMain::RefreshMenus()
EnableMenuItem(emul_menu, ID_EMULATION_STOP, MF_BYCOMMAND | MF_WhenXbeLoadedAndRunning);
}
}
// NOTE: Must force draw menu bar since sometime status doesn't show the new change.
DrawMenuBar(m_hwnd);
}
// update debug consoles
@ -1851,33 +1855,70 @@ void WndMain::UpdateCaption()
i += sprintf(AsciiTitle + i, "%s v1.%02d (%s)", FormatTitleId(m_Xbe->m_Certificate.dwTitleId).c_str(), m_Xbe->m_Certificate.dwVersion, m_Xbe->m_szAsciiTitle);
// Append FPS menu text
HMENU hMenu = GetMenu(m_hwnd);
MENUITEMINFO mii;
mii.cbSize = sizeof mii;
mii.fMask = MIIM_STRING;
char sMenu[32];
mii.dwTypeData = &sMenu[0];
UpdateFpsStatus();
UpdateLogStatus();
if (m_bIsStarted) {
if (g_EmuShared != nullptr) {
g_EmuShared->GetCurrentFPS(&m_FPS_status);
m_MSpF_status = (float)(1000.0 / (m_FPS_status == 0 ? 0.001 : m_FPS_status));
sprintf(sMenu, "FPS: %.2f MS / F : %.2f", m_FPS_status, m_MSpF_status);
}
}
else {
// Hide FPS if we're not currently emulating
sprintf(sMenu, " ");
}
SetMenuItemInfo(hMenu, ID_FPS, FALSE, &mii);
}
SetWindowText(m_hwnd, AsciiTitle);
}
void WndMain::UpdateFpsStatus()
{
// Append FPS menu text
HMENU hMenu = GetMenu(m_hwnd);
MENUITEMINFO mii;
mii.cbSize = sizeof mii;
mii.fMask = MIIM_STRING;
char sMenu[32];
mii.dwTypeData = &sMenu[0];
if (m_bIsStarted) {
if (g_EmuShared != nullptr) {
g_EmuShared->GetCurrentFPS(&m_FPS_status);
m_MSpF_status = (float)(1000.0 / (m_FPS_status == 0 ? 0.001 : m_FPS_status));
std::sprintf(sMenu, "FPS: %.2f MS / F : %.2f", m_FPS_status, m_MSpF_status);
}
}
else {
// Hide FPS if we're not currently emulating
std::sprintf(sMenu, " ");
}
SetMenuItemInfo(hMenu, ID_FPS, FALSE, &mii);
}
void WndMain::UpdateLogStatus()
{
// Append FPS menu text
char sMenu[32];
HMENU hMenu = GetMenu(m_hwnd);
MENUITEMINFO mii;
mii.cbSize = sizeof mii;
mii.fMask = MIIM_STRING;
mii.dwTypeData = &sMenu[0];
std::strcpy(sMenu, "LOG:");
if (g_Settings->m_gui.CxbxDebugMode != DebugMode::DM_NONE) {
std::strcat(sMenu, "G");
}
if (m_bIsStarted && m_LogKrnl_status) {
std::strcat(sMenu, "K");
}
SetMenuItemInfo(hMenu, ID_LOG, FALSE, &mii);
}
void WndMain::RefreshAllStatus()
{
UpdateFpsStatus();
UpdateLogStatus();
DrawMenuBar(m_hwnd);
}
// open an xbe file
void WndMain::OpenXbe(const char *x_filename)
{
@ -2103,6 +2144,7 @@ void WndMain::StartEmulation(HWND hwndParent, DebuggerState LocalDebuggerState /
m_FPS_status = 0.0f;
m_MSpF_status = 0.0f;
m_FlagsLLE_status = g_Settings->m_core.FlagsLLE;
m_LogKrnl_status = g_Settings->m_core.KrnlDebugMode != DebugMode::DM_NONE;
// register all emulator settings to kernel process
g_Settings->SyncToEmulator();
@ -2249,7 +2291,7 @@ void WndMain::CrashMonitor(DWORD dwChildProcID)
// Crash clean up.
KillTimer(m_hwnd, TIMERID_FPS);
KillTimer(m_hwnd, TIMERID_ACTIVE_EMULATION);
KillTimer(m_hwnd, TIMERID_LED);
m_hwndChild = NULL;
m_bIsStarted = false;

View File

@ -133,6 +133,9 @@ class WndMain : public Wnd
// * update title bar caption with xbe name and FPS/MSF
// ******************************************************************
void UpdateCaption();
void RefreshAllStatus();
void UpdateFpsStatus();
void UpdateLogStatus();
// ******************************************************************
// * crash monitoring wrapper function
@ -231,7 +234,8 @@ class WndMain : public Wnd
UINT m_LedSeq_status_block;
UCHAR m_LedSeq_status[4];
};
UINT m_FlagsLLE_status;
UINT m_FlagsLLE_status;
bool m_LogKrnl_status;
};
#endif

View File

@ -886,6 +886,9 @@ void CxbxKrnlMain(int argc, char* argv[])
DebugFileName = argv[5];
}
int BootFlags;
g_EmuShared->GetBootFlags(&BootFlags);
// debug console allocation (if configured)
if (DbgMode == DM_CONSOLE)
{
@ -906,10 +909,11 @@ void CxbxKrnlMain(int argc, char* argv[])
else
{
FreeConsole();
if (DbgMode == DM_FILE)
freopen(DebugFileName.c_str(), "wt", stdout);
else
{
if (DbgMode == DM_FILE) {
// Peform clean write to kernel log for first boot. Unless multi-xbe boot occur then perform append to existing log.
freopen(DebugFileName.c_str(), ((BootFlags == DebugMode::DM_NONE) ? "wt" : "at"), stdout);
}
else {
char buffer[16];
if (GetConsoleTitle(buffer, 16) != NULL)
freopen("nul", "w", stdout);
@ -932,7 +936,7 @@ void CxbxKrnlMain(int argc, char* argv[])
}
if (CxbxKrnl_hEmuParent != NULL) {
SendMessage(CxbxKrnl_hEmuParent, WM_PARENTNOTIFY, MAKELONG(WM_USER, ID_KRNL_IS_READY), GetCurrentProcessId());
ipc_send_gui_update(IPC_UPDATE_GUI::KRNL_IS_READY, static_cast<UINT>(GetCurrentProcessId()));
// Force wait until GUI process is ready
do {
@ -983,8 +987,9 @@ void CxbxKrnlMain(int argc, char* argv[])
CxbxKrnlShutDown();
}
int BootFlags = BOOT_NONE;
g_EmuShared->GetBootFlags(&BootFlags);
bool isLogEnabled;
g_EmuShared->GetIsKrnlLogEnabled(&isLogEnabled);
g_bPrintfOn = isLogEnabled;
g_EmuShared->ResetKrnl();

View File

@ -1640,6 +1640,7 @@ static LRESULT WINAPI EmuMsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPar
else if(wParam == VK_F8)
{
g_bPrintfOn = !g_bPrintfOn;
ipc_send_gui_update(IPC_UPDATE_GUI::LOG_ENABLED, static_cast<UINT>(g_bPrintfOn));
}
else if(wParam == VK_F10)
{

View File

@ -161,7 +161,13 @@ class EmuShared : public Mutex
// * FPS/Benchmark values Accessors
// ******************************************************************
void GetCurrentFPS(float *value) { Lock(); *value = m_FPS_status; Unlock(); }
void SetCurrentFPS(const float *value) { Lock(); m_FPS_status = *value; Unlock(); }
void SetCurrentFPS(const float *value) { Lock(); m_FPS_status = *value; Unlock(); }
// ******************************************************************
// * FPS/Benchmark values Accessors
// ******************************************************************
void GetIsKrnlLogEnabled(bool *value) { Lock(); *value = m_Krnl_Log_enabled; Unlock(); }
void SetIsKrnlLogEnabled(const bool value) { Lock(); m_Krnl_Log_enabled = value; Unlock(); }
// ******************************************************************
// * Debugging flag Accessors
@ -240,7 +246,7 @@ class EmuShared : public Mutex
unsigned int m_Reserved5;
float m_Reserved6;
float m_FPS_status; // NOTE: If move into ipc_send_gui_update will spam GUI's message system (one message per frame)
bool m_bReserved1;
bool m_Krnl_Log_enabled; // Is require in order to preserve previous set for support multi-xbe.
bool m_bDebugging;
bool m_bReady_status;
bool m_bEmulating_status;