diff --git a/build/win32/Cxbx.vcxproj b/build/win32/Cxbx.vcxproj index 7b473914a..68bde927f 100644 --- a/build/win32/Cxbx.vcxproj +++ b/build/win32/Cxbx.vcxproj @@ -76,7 +76,7 @@ Disabled ..\..\src\Common;..\..\src;..\..\src\Common\Win32;..\..\import\stb;%(AdditionalIncludeDirectories);..\..\import\OpenXDK\include;..\..\import\distorm\include;..\..\import\glew-2.0.0\include;..\..\src;..\..\src\Common;..\..\src\Common\Win32 - WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + _WIN32_WINNT=0x0601;WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebugDLL true @@ -92,7 +92,7 @@ Include\Win32\Cxbx;%(AdditionalIncludeDirectories) - legacy_stdio_definitions.lib;d3d8.lib;dinput8.lib;dxguid.lib;odbc32.lib;odbccp32.lib;Shlwapi.lib;dxerr8.lib;xinput.lib;ws2_32.lib;dsound.lib;winmm.lib;ddraw.lib;d3dx8.lib;dbghelp.lib;comctl32.lib;%(AdditionalDependencies) + legacy_stdio_definitions.lib;d3d8.lib;dinput8.lib;dxguid.lib;odbc32.lib;odbccp32.lib;Shlwapi.lib;dxerr8.lib;ws2_32.lib;dsound.lib;winmm.lib;ddraw.lib;d3dx8.lib;dbghelp.lib;comctl32.lib;XINPUT9_1_0.LIB;%(AdditionalDependencies) true $(Configuration)\;..\..\import\distorm\lib\Win32\;..\..\import\glew-2.0.0\lib\Release\Win32\;%(AdditionalLibraryDirectories) msvcrt;%(IgnoreSpecificDefaultLibraries) @@ -138,7 +138,7 @@ $(SOLUTIONDIR)Export.bat MaxSpeed OnlyExplicitInline ..\..\src;..\..\src\Common;..\..\src\Common\Win32\;..\..\import\stb;%(AdditionalIncludeDirectories);..\..\import\OpenXDK\include;..\..\import\distorm\include;..\..\import\glew-2.0.0\include;..\..\src;..\..\src\Common;..\..\src\Common\Win32 - WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + _WIN32_WINNT=0x0601;WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true MultiThreadedDLL true @@ -155,7 +155,7 @@ $(SOLUTIONDIR)Export.bat Include\Win32\Cxbx;%(AdditionalIncludeDirectories) - legacy_stdio_definitions.lib;d3d8.lib;dinput8.lib;dxguid.lib;odbc32.lib;odbccp32.lib;Shlwapi.lib;dxerr8.lib;xinput.lib;ws2_32.lib;dsound.lib;winmm.lib;ddraw.lib;d3dx8.lib;dbghelp.lib;comctl32.lib;%(AdditionalDependencies) + legacy_stdio_definitions.lib;d3d8.lib;dinput8.lib;dxguid.lib;odbc32.lib;odbccp32.lib;Shlwapi.lib;dxerr8.lib;ws2_32.lib;dsound.lib;winmm.lib;ddraw.lib;d3dx8.lib;dbghelp.lib;comctl32.lib;XINPUT9_1_0.LIB;%(AdditionalDependencies) true $(Configuration)\;..\..\import\distorm\lib\Win32\;..\..\import\glew-2.0.0\lib\Release\Win32\;%(AdditionalLibraryDirectories) %(IgnoreSpecificDefaultLibraries) diff --git a/resource/Cxbx.rc b/resource/Cxbx.rc index e29ac27cd..33a38969b 100644 --- a/resource/Cxbx.rc +++ b/resource/Cxbx.rc @@ -131,6 +131,8 @@ BEGIN MENUITEM "Config &Audio...", ID_SETTINGS_CONFIGURESOUND, GRAYED MENUITEM "Config &Video...", ID_SETTINGS_CONFIG_VIDEO MENUITEM SEPARATOR + MENUITEM "Use XInput", ID_SETTINGS_XINPUT + MENUITEM SEPARATOR POPUP "&HLE Cache" BEGIN MENUITEM "&Clear entire HLE Cache", ID_CACHE_CLEARHLECACHE_ALL diff --git a/src/Common/Win32/XBController.cpp b/src/Common/Win32/XBController.cpp index d1f92a03b..66f30c447 100644 --- a/src/Common/Win32/XBController.cpp +++ b/src/Common/Win32/XBController.cpp @@ -782,76 +782,76 @@ void XBController::ListenPoll(XTL::XINPUT_STATE *Controller) Controller->Gamepad.sThumbRX -= wValue; break; case XBCTRL_OBJECT_A: - Controller->Gamepad.bAnalogButtons[XINPUT_GAMEPAD_A] = (wValue / 128); + Controller->Gamepad.bAnalogButtons[XB_XINPUT_GAMEPAD_A] = (wValue / 128); break; case XBCTRL_OBJECT_B: - Controller->Gamepad.bAnalogButtons[XINPUT_GAMEPAD_B] = (wValue / 128); + Controller->Gamepad.bAnalogButtons[XB_XINPUT_GAMEPAD_B] = (wValue / 128); break; case XBCTRL_OBJECT_X: - Controller->Gamepad.bAnalogButtons[XINPUT_GAMEPAD_X] = (wValue / 128); + Controller->Gamepad.bAnalogButtons[XB_XINPUT_GAMEPAD_X] = (wValue / 128); break; case XBCTRL_OBJECT_Y: - Controller->Gamepad.bAnalogButtons[XINPUT_GAMEPAD_Y] = (wValue / 128); + Controller->Gamepad.bAnalogButtons[XB_XINPUT_GAMEPAD_Y] = (wValue / 128); break; case XBCTRL_OBJECT_WHITE: - Controller->Gamepad.bAnalogButtons[XINPUT_GAMEPAD_WHITE] = (wValue / 128); + Controller->Gamepad.bAnalogButtons[XB_XINPUT_GAMEPAD_WHITE] = (wValue / 128); break; case XBCTRL_OBJECT_BLACK: - Controller->Gamepad.bAnalogButtons[XINPUT_GAMEPAD_BLACK] = (wValue / 128); + Controller->Gamepad.bAnalogButtons[XB_XINPUT_GAMEPAD_BLACK] = (wValue / 128); break; case XBCTRL_OBJECT_LTRIGGER: - Controller->Gamepad.bAnalogButtons[XINPUT_GAMEPAD_LEFT_TRIGGER] = (wValue / 128); + Controller->Gamepad.bAnalogButtons[XB_XINPUT_GAMEPAD_LEFT_TRIGGER] = (wValue / 128); break; case XBCTRL_OBJECT_RTRIGGER: - Controller->Gamepad.bAnalogButtons[XINPUT_GAMEPAD_RIGHT_TRIGGER] = (wValue / 128); + Controller->Gamepad.bAnalogButtons[XB_XINPUT_GAMEPAD_RIGHT_TRIGGER] = (wValue / 128); break; case XBCTRL_OBJECT_DPADUP: if(wValue > 0) - Controller->Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_UP; + Controller->Gamepad.wButtons |= XB_XINPUT_GAMEPAD_DPAD_UP; else - Controller->Gamepad.wButtons &= ~XINPUT_GAMEPAD_DPAD_UP; + Controller->Gamepad.wButtons &= ~XB_XINPUT_GAMEPAD_DPAD_UP; break; case XBCTRL_OBJECT_DPADDOWN: if(wValue > 0) - Controller->Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_DOWN; + Controller->Gamepad.wButtons |= XB_XINPUT_GAMEPAD_DPAD_DOWN; else - Controller->Gamepad.wButtons &= ~XINPUT_GAMEPAD_DPAD_DOWN; + Controller->Gamepad.wButtons &= ~XB_XINPUT_GAMEPAD_DPAD_DOWN; break; case XBCTRL_OBJECT_DPADLEFT: if(wValue > 0) - Controller->Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_LEFT; + Controller->Gamepad.wButtons |= XB_XINPUT_GAMEPAD_DPAD_LEFT; else - Controller->Gamepad.wButtons &= ~XINPUT_GAMEPAD_DPAD_LEFT; + Controller->Gamepad.wButtons &= ~XB_XINPUT_GAMEPAD_DPAD_LEFT; break; case XBCTRL_OBJECT_DPADRIGHT: if(wValue > 0) - Controller->Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_RIGHT; + Controller->Gamepad.wButtons |= XB_XINPUT_GAMEPAD_DPAD_RIGHT; else - Controller->Gamepad.wButtons &= ~XINPUT_GAMEPAD_DPAD_RIGHT; + Controller->Gamepad.wButtons &= ~XB_XINPUT_GAMEPAD_DPAD_RIGHT; break; case XBCTRL_OBJECT_BACK: if(wValue > 0) - Controller->Gamepad.wButtons |= XINPUT_GAMEPAD_BACK; + Controller->Gamepad.wButtons |= XB_XINPUT_GAMEPAD_BACK; else - Controller->Gamepad.wButtons &= ~XINPUT_GAMEPAD_BACK; + Controller->Gamepad.wButtons &= ~XB_XINPUT_GAMEPAD_BACK; break; case XBCTRL_OBJECT_START: if(wValue > 0) - Controller->Gamepad.wButtons |= XINPUT_GAMEPAD_START; + Controller->Gamepad.wButtons |= XB_XINPUT_GAMEPAD_START; else - Controller->Gamepad.wButtons &= ~XINPUT_GAMEPAD_START; + Controller->Gamepad.wButtons &= ~XB_XINPUT_GAMEPAD_START; break; case XBCTRL_OBJECT_LTHUMB: if(wValue > 0) - Controller->Gamepad.wButtons |= XINPUT_GAMEPAD_LEFT_THUMB; + Controller->Gamepad.wButtons |= XB_XINPUT_GAMEPAD_LEFT_THUMB; else - Controller->Gamepad.wButtons &= ~XINPUT_GAMEPAD_LEFT_THUMB; + Controller->Gamepad.wButtons &= ~XB_XINPUT_GAMEPAD_LEFT_THUMB; break; case XBCTRL_OBJECT_RTHUMB: if(wValue > 0) - Controller->Gamepad.wButtons |= XINPUT_GAMEPAD_RIGHT_THUMB; + Controller->Gamepad.wButtons |= XB_XINPUT_GAMEPAD_RIGHT_THUMB; else - Controller->Gamepad.wButtons &= ~XINPUT_GAMEPAD_RIGHT_THUMB; + Controller->Gamepad.wButtons &= ~XB_XINPUT_GAMEPAD_RIGHT_THUMB; break; } } diff --git a/src/Cxbx/ResCxbx.h b/src/Cxbx/ResCxbx.h index ddd5b7ec5..3a69c20ed 100644 --- a/src/Cxbx/ResCxbx.h +++ b/src/Cxbx/ResCxbx.h @@ -93,6 +93,7 @@ #define ID_SETTINGS_CACHE 40083 #define ID_CACHE_CLEARHLECACHE_ALL 40084 #define ID_CACHE_CLEARHLECACHE_CURRENT 40085 +#define ID_SETTINGS_XINPUT 40086 #define IDC_STATIC -1 // Next default values for new objects @@ -100,7 +101,7 @@ #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 130 -#define _APS_NEXT_COMMAND_VALUE 40085 +#define _APS_NEXT_COMMAND_VALUE 40087 #define _APS_NEXT_CONTROL_VALUE 1058 #define _APS_NEXT_SYMED_VALUE 104 #endif diff --git a/src/Cxbx/WndMain.cpp b/src/Cxbx/WndMain.cpp index d96f42748..1064a2dbf 100644 --- a/src/Cxbx/WndMain.cpp +++ b/src/Cxbx/WndMain.cpp @@ -128,6 +128,9 @@ WndMain::WndMain(HINSTANCE x_hInstance) : dwType = REG_DWORD; dwSize = sizeof(DWORD); RegQueryValueEx(hKey, "LLEFLAGS", NULL, &dwType, (PBYTE)&m_FlagsLLE, &dwSize); + dwType = REG_DWORD; dwSize = sizeof(DWORD); + RegQueryValueEx(hKey, "XInputEnabled", NULL, &dwType, (PBYTE)&m_XInputEnabled, &dwSize); + dwType = REG_DWORD; dwSize = sizeof(DWORD); RegQueryValueEx(hKey, "CxbxDebug", NULL, &dwType, (PBYTE)&m_CxbxDebug, &dwSize); @@ -191,6 +194,9 @@ WndMain::~WndMain() dwType = REG_DWORD; dwSize = sizeof(DWORD); RegSetValueEx(hKey, "LLEFLAGS", 0, dwType, (PBYTE)&m_FlagsLLE, dwSize); + dwType = REG_DWORD; dwSize = sizeof(DWORD); + RegSetValueEx(hKey, "XInputEnabled", 0, dwType, (PBYTE)&m_XInputEnabled, dwSize); + dwType = REG_DWORD; dwSize = sizeof(DWORD); RegSetValueEx(hKey, "CxbxDebug", 0, dwType, (PBYTE)&m_CxbxDebug, dwSize); @@ -455,628 +461,633 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP case WM_COMMAND: { - switch(LOWORD(wParam)) - { - case ID_FILE_OPEN_XBE: - { - OPENFILENAME ofn = {0}; - - char filename[MAX_PATH] = {0}; - - ofn.lStructSize = sizeof(OPENFILENAME); - ofn.hwndOwner = m_hwnd; - ofn.lpstrFilter = "Xbox Executables (*.xbe)\0*.xbe\0"; - ofn.lpstrFile = filename; - ofn.nMaxFile = MAX_PATH; - ofn.nFilterIndex = 1; - ofn.lpstrFileTitle = NULL; - ofn.nMaxFileTitle = 0; - ofn.lpstrInitialDir = NULL; - ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; - - if(GetOpenFileName(&ofn) == TRUE) - { - if(m_Xbe != 0) - CloseXbe(); - - if(m_Xbe != 0) - break; - - OpenXbe(ofn.lpstrFile); - } - } - break; - - case ID_FILE_CLOSE_XBE: - CloseXbe(); - break; - - case ID_FILE_SAVEXBEFILE: - { - if(m_XbeFilename[0] == '\0') - SaveXbeAs(); - else - SaveXbe(m_XbeFilename); - } - break; - - case ID_FILE_SAVEXBEFILEAS: - SaveXbeAs(); - break; - - case ID_FILE_RXBE_0: - case ID_FILE_RXBE_1: - case ID_FILE_RXBE_2: - case ID_FILE_RXBE_3: - case ID_FILE_RXBE_4: - case ID_FILE_RXBE_5: - case ID_FILE_RXBE_6: - case ID_FILE_RXBE_7: - case ID_FILE_RXBE_8: - case ID_FILE_RXBE_9: - { - if(m_Xbe != 0) - CloseXbe(); - - if(m_Xbe != 0) - break; - - HMENU menu = GetMenu(m_hwnd); - HMENU file_menu = GetSubMenu(menu, 0); - HMENU rxbe_menu = GetSubMenu(file_menu, 6); - - char szBuffer[270]; - - GetMenuString(rxbe_menu, LOWORD(wParam), szBuffer, 269, MF_BYCOMMAND); - - char *szFilename = (char*)((uint32)szBuffer + 5); - - OpenXbe(szFilename); - } - break; - - case ID_FILE_EXIT: - SendMessage(hwnd, WM_CLOSE, 0, 0); - break; - - case ID_EDIT_LOGOBITMAP_EXPORT: - { - OPENFILENAME ofn = {0}; - - char filename[MAX_PATH] = "logo.bmp"; - - ofn.lStructSize = sizeof(OPENFILENAME); - ofn.hwndOwner = m_hwnd; - ofn.lpstrFilter = "Bitmap Image Files (*.bmp)\0*.bmp\0"; - ofn.lpstrFile = filename; - ofn.nMaxFile = MAX_PATH; - ofn.nFilterIndex = 1; - ofn.lpstrFileTitle = NULL; - ofn.nMaxFileTitle = 0; - ofn.lpstrInitialDir = NULL; - ofn.lpstrDefExt = "bmp"; - ofn.lpstrTitle = "Export Logo Bitmap"; - ofn.Flags = OFN_PATHMUSTEXIST; - - if(GetSaveFileName(&ofn) == TRUE) - { - // ask permission to overwrite if file already exists - if(_access(ofn.lpstrFile, 0) != -1) - { - if(MessageBox(m_hwnd, "Overwrite existing file?", "Cxbx-Reloaded", MB_ICONQUESTION | MB_YESNO) != IDYES) - return TRUE; - } - - // export logo bitmap - { - uint08 i_gray[100*17]; - - m_Xbe->ExportLogoBitmap(i_gray); - - if (false == m_Xbe->HasError()) - { - FILE *LogoBitmap = fopen(ofn.lpstrFile, "wb"); - - // write bitmap header - { - BITMAPFILEHEADER bmfh; - - bmfh.bfType = *(uint16*)"BM"; - bmfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFO) - sizeof(RGBQUAD) + (100*17)*sizeof(RGBTRIPLE) + 2; - bmfh.bfReserved1 = 0; - bmfh.bfReserved2 = 0; - bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFO) - sizeof(RGBQUAD); - - fwrite(&bmfh, sizeof(bmfh), 1, LogoBitmap); - } - - // write bitmap info - { - BITMAPINFO bmi; - - bmi.bmiHeader.biSize = sizeof(BITMAPINFO) - sizeof(RGBQUAD); - bmi.bmiHeader.biWidth = 100; - bmi.bmiHeader.biHeight = -17; - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = 24; - bmi.bmiHeader.biCompression = BI_RGB; - bmi.bmiHeader.biSizeImage = 0; - bmi.bmiHeader.biXPelsPerMeter = 0; - bmi.bmiHeader.biYPelsPerMeter = 0; - bmi.bmiHeader.biClrUsed = 0; - bmi.bmiHeader.biClrImportant = 0; - - fwrite(&bmi, sizeof(bmi) - 4, 1, LogoBitmap); - } - - // write bitmap data - { - RGBTRIPLE bmp_data[100*17]; - - for(uint32 v=0;v<100*17;v++) - { - bmp_data[v].rgbtRed = i_gray[v]; - bmp_data[v].rgbtGreen = i_gray[v]; - bmp_data[v].rgbtBlue = i_gray[v]; - } - - fwrite(bmp_data, 100*17*sizeof(RGBTRIPLE), 1, LogoBitmap); - } - - // write bitmap padding - { - uint16 pad = 0; - - fwrite(&pad, 2, 1, LogoBitmap); - } - - fclose(LogoBitmap); - } - - if(m_Xbe->HasError()) - MessageBox(m_hwnd, m_Xbe->GetError().c_str(), "Cxbx-Reloaded", MB_ICONSTOP | MB_OK); - else - { - char buffer[255]; - - sprintf(buffer, "%s's logo bitmap was successfully exported.", m_Xbe->m_szAsciiTitle); - - MessageBox(m_hwnd, buffer, "Cxbx-Reloaded", MB_ICONINFORMATION | MB_OK); - - printf("WndMain: %s\n", buffer); - } - } - } - } - break; - - case ID_EDIT_LOGOBITMAP_IMPORT: - { - OPENFILENAME ofn = {0}; - - char filename[MAX_PATH] = "*.bmp"; - - ofn.lStructSize = sizeof(OPENFILENAME); - ofn.hwndOwner = m_hwnd; - ofn.lpstrFilter = "Bitmap Image Files (*.bmp)\0*.bmp\0"; - ofn.lpstrFile = filename; - ofn.nMaxFile = MAX_PATH; - ofn.nFilterIndex = 1; - ofn.lpstrFileTitle = NULL; - ofn.nMaxFileTitle = 0; - ofn.lpstrInitialDir = NULL; - ofn.lpstrDefExt = "bmp"; - ofn.lpstrTitle = "Import Logo Bitmap"; - ofn.Flags = OFN_PATHMUSTEXIST; - - if(GetOpenFileName(&ofn) == TRUE) - { - // import logo bitmap - { - uint08 i_gray[100*17]; - - // read bitmap file - { - FILE *logo = fopen(ofn.lpstrFile, "rb"); - - char *bmp_err = 0; - - // read bitmap header - if(!bmp_err) - { - BITMAPFILEHEADER bmfh; - - fread(&bmfh, sizeof(bmfh), 1, logo); - - if(bmfh.bfType != *(uint16*)"BM") - bmp_err = "Invalid bitmap file...\n\nonly allows 24 bit bitmaps (100 by 17 pixels) with row order swapped"; - else if(bmfh.bfSize != sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFO) - sizeof(RGBQUAD) + (100*17)*sizeof(RGBTRIPLE) + 2) - bmp_err = "Invalid bitmap file...\n\nonly allows 24 bit bitmaps (100 by 17 pixels) with row order swapped"; - } - - // read bitmap info - if(!bmp_err) - { - BITMAPINFO bmi; - - fread(&bmi, sizeof(bmi) - 4, 1, logo); - - if(bmi.bmiHeader.biWidth != 100 || bmi.bmiHeader.biHeight != -17) - bmp_err = "Invalid bitmap file...\n\nonly allows 24 bit bitmaps (100 by 17 pixels) with row order swapped"; - } - - // read bitmap data - if(!bmp_err) - { - RGBTRIPLE bmp_data[100*17]; - - fread(bmp_data, 100*17*sizeof(RGBTRIPLE), 1, logo); - - for(uint32 c=0;c<100*17;c++) - i_gray[c] = (char)(((float)bmp_data[c].rgbtRed + (float)bmp_data[c].rgbtGreen + (float)bmp_data[c].rgbtBlue) / 3.0); - } - - fclose(logo); - - if(bmp_err != 0) - { - MessageBox(m_hwnd, bmp_err, "Cxbx-Reloaded", MB_OK | MB_ICONEXCLAMATION); - break; - } - } - - m_Xbe->ImportLogoBitmap(i_gray); - - if(m_Xbe->HasError()) - { - MessageBox(m_hwnd, m_Xbe->GetError().c_str(), "Cxbx-Reloaded", MB_ICONSTOP | MB_OK); - - if (m_Xbe->HasFatalError()) - { - CloseXbe(); - } - else - { - m_Xbe->ClearError(); - } - - } - else - { - m_bXbeChanged = true; - - LoadLogo(); - - char buffer[255]; - - sprintf(buffer, "%s's logo bitmap was successfully updated.", m_Xbe->m_szAsciiTitle); - - printf("WndMain: %s\n", buffer); - - MessageBox(m_hwnd, buffer, "Cxbx-Reloaded", MB_ICONINFORMATION | MB_OK); - } - } - } - } - break; - - case ID_EDIT_PATCH_ALLOW64MB: - { - m_bXbeChanged = true; - - m_Xbe->m_Header.dwInitFlags.bLimit64MB = !m_Xbe->m_Header.dwInitFlags.bLimit64MB; - - RefreshMenus(); - - if(m_Xbe->m_Header.dwInitFlags.bLimit64MB) - printf("WndMain: %s was patched to limit to 64MB of memory usage.\n", m_Xbe->m_szAsciiTitle); - else - printf("WndMain: %s was patched to allow >64MB of memory usage.\n", m_Xbe->m_szAsciiTitle); - } - break; - - case ID_EDIT_PATCH_DEBUGMODE: - { - m_bXbeChanged = true; - - // patch to/from debug mode - if((m_Xbe->m_Header.dwEntryAddr ^ XOR_EP_RETAIL) > 0x01000000) - { - // we're in debug mode, so switch over to retail - uint32 ep = m_Xbe->m_Header.dwEntryAddr ^ XOR_EP_RETAIL; // decode from debug mode - uint32 kt = m_Xbe->m_Header.dwKernelImageThunkAddr ^ XOR_KT_DEBUG; // decode from debug mode - - m_Xbe->m_Header.dwEntryAddr = ep ^ XOR_EP_DEBUG; // encode to retail mode - m_Xbe->m_Header.dwKernelImageThunkAddr = kt ^ XOR_KT_RETAIL; // encode to retail mode - } - else - { - // we're in retail mode, so switch to debug - uint32 ep = m_Xbe->m_Header.dwEntryAddr ^ XOR_EP_DEBUG; // decode from retail mode - uint32 kt = m_Xbe->m_Header.dwKernelImageThunkAddr ^ XOR_KT_RETAIL; // decode from retail mode - - m_Xbe->m_Header.dwEntryAddr = ep ^ XOR_EP_RETAIL; // encode to debug mode - m_Xbe->m_Header.dwKernelImageThunkAddr = kt ^ XOR_KT_DEBUG; // encode to debug mode - } - - RefreshMenus(); - - bool res = (m_Xbe->m_Header.dwEntryAddr ^ XOR_EP_RETAIL) > 0x01000000; - - if(res) - printf("WndMain: %s was converted to debug mode.\n", m_Xbe->m_szAsciiTitle); - else - printf("WndMain: %s was converted to retail mode.\n", m_Xbe->m_szAsciiTitle); - } - break; - - case ID_EDIT_DUMPXBEINFOTO_FILE: - { - OPENFILENAME ofn = {0}; - - char filename[MAX_PATH] = "Xbe.txt"; - - ofn.lStructSize = sizeof(OPENFILENAME); - ofn.hwndOwner = m_hwnd; - ofn.lpstrFilter = "Text Documents (*.txt)\0*.txt\0"; - ofn.lpstrFile = filename; - ofn.nMaxFile = MAX_PATH; - ofn.nFilterIndex = 1; - ofn.lpstrFileTitle = NULL; - ofn.nMaxFileTitle = 0; - ofn.lpstrInitialDir = NULL; - ofn.lpstrDefExt = "txt"; - ofn.Flags = OFN_PATHMUSTEXIST; - - if(GetSaveFileName(&ofn) == TRUE) - { - // ask permission to overwrite if file exists - if(_access(ofn.lpstrFile, 0) != -1) - { - if(MessageBox(m_hwnd, "Overwrite existing file?", "Cxbx-Reloaded", MB_ICONQUESTION | MB_YESNO) != IDYES) - return TRUE; - } - - // dump xbe information to file - { - FILE *TxtFile = fopen(ofn.lpstrFile, "wt"); - - // verify file was opened - if(TxtFile == 0) - MessageBox(m_hwnd, "Could not open text file.", "Cxbx-Reloaded", MB_ICONSTOP | MB_OK); - else - { - m_Xbe->DumpInformation(TxtFile); - - fclose(TxtFile); - - if(m_Xbe->HasError()) - { - MessageBox(m_hwnd, m_Xbe->GetError().c_str(), "Cxbx-Reloaded", MB_ICONSTOP | MB_OK); - } - else - { - char buffer[255]; - - sprintf(buffer, "%s's .xbe info was successfully dumped.", m_Xbe->m_szAsciiTitle); - - printf("WndMain: %s\n", buffer); - - MessageBox(m_hwnd, buffer, "Cxbx-Reloaded", MB_ICONINFORMATION | MB_OK); - } - } - } - } - } - break; - - case ID_EDIT_DUMPXBEINFOTO_DEBUGCONSOLE: - { - // dump xbe information to debug console - m_Xbe->DumpInformation(stdout); - - if(m_Xbe->HasError()) - { - MessageBox(m_hwnd, m_Xbe->GetError().c_str(), "Cxbx-Reloaded", MB_ICONSTOP | MB_OK); - } - else - { - char buffer[255]; - - sprintf(buffer, "%s's .xbe info was successfully dumped.", m_Xbe->m_szAsciiTitle); - - printf("WndMain: %s\n", buffer); - } - } - break; - - case ID_SETTINGS_CONFIG_CONTROLLER: - ShowControllerConfig(hwnd); - break; - - case ID_SETTINGS_CONFIG_VIDEO: - ShowVideoConfig(hwnd); - break; - - case ID_CACHE_CLEARHLECACHE_ALL: + switch (LOWORD(wParam)) + { + case ID_FILE_OPEN_XBE: + { + OPENFILENAME ofn = { 0 }; + + char filename[MAX_PATH] = { 0 }; + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = m_hwnd; + ofn.lpstrFilter = "Xbox Executables (*.xbe)\0*.xbe\0"; + ofn.lpstrFile = filename; + ofn.nMaxFile = MAX_PATH; + ofn.nFilterIndex = 1; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrInitialDir = NULL; + ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; + + if (GetOpenFileName(&ofn) == TRUE) { - ClearHLECache(); - MessageBox(m_hwnd, "The entire HLE Cache has been cleared.", "Cxbx-Reloaded", MB_OK); + if (m_Xbe != 0) + CloseXbe(); + + if (m_Xbe != 0) + break; + + OpenXbe(ofn.lpstrFile); } + } + break; + + case ID_FILE_CLOSE_XBE: + CloseXbe(); break; - case ID_CACHE_CLEARHLECACHE_CURRENT: + case ID_FILE_SAVEXBEFILE: + { + if (m_XbeFilename[0] == '\0') + SaveXbeAs(); + else + SaveXbe(m_XbeFilename); + } + break; + + case ID_FILE_SAVEXBEFILEAS: + SaveXbeAs(); + break; + + case ID_FILE_RXBE_0: + case ID_FILE_RXBE_1: + case ID_FILE_RXBE_2: + case ID_FILE_RXBE_3: + case ID_FILE_RXBE_4: + case ID_FILE_RXBE_5: + case ID_FILE_RXBE_6: + case ID_FILE_RXBE_7: + case ID_FILE_RXBE_8: + case ID_FILE_RXBE_9: + { + if (m_Xbe != 0) + CloseXbe(); + + if (m_Xbe != 0) + break; + + HMENU menu = GetMenu(m_hwnd); + HMENU file_menu = GetSubMenu(menu, 0); + HMENU rxbe_menu = GetSubMenu(file_menu, 6); + + char szBuffer[270]; + + GetMenuString(rxbe_menu, LOWORD(wParam), szBuffer, 269, MF_BYCOMMAND); + + char *szFilename = (char*)((uint32)szBuffer + 5); + + OpenXbe(szFilename); + } + break; + + case ID_FILE_EXIT: + SendMessage(hwnd, WM_CLOSE, 0, 0); + break; + + case ID_EDIT_LOGOBITMAP_EXPORT: + { + OPENFILENAME ofn = { 0 }; + + char filename[MAX_PATH] = "logo.bmp"; + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = m_hwnd; + ofn.lpstrFilter = "Bitmap Image Files (*.bmp)\0*.bmp\0"; + ofn.lpstrFile = filename; + ofn.nMaxFile = MAX_PATH; + ofn.nFilterIndex = 1; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrInitialDir = NULL; + ofn.lpstrDefExt = "bmp"; + ofn.lpstrTitle = "Export Logo Bitmap"; + ofn.Flags = OFN_PATHMUSTEXIST; + + if (GetSaveFileName(&ofn) == TRUE) { - std::string cacheDir = std::string(XTL::szFolder_CxbxReloadedData) + "\\HLECache\\"; + // ask permission to overwrite if file already exists + if (_access(ofn.lpstrFile, 0) != -1) + { + if (MessageBox(m_hwnd, "Overwrite existing file?", "Cxbx-Reloaded", MB_ICONQUESTION | MB_YESNO) != IDYES) + return TRUE; + } - // Hash the loaded XBE's header, use it as a filename - uint32_t uiHash = XXHash32::hash((void*)&m_Xbe->m_Header, sizeof(Xbe::Header), 0); - std::stringstream sstream; - sstream << cacheDir << std::hex << uiHash << ".ini"; - std::string fullpath = sstream.str(); + // export logo bitmap + { + uint08 i_gray[100 * 17]; - if (DeleteFile(fullpath.c_str())) { - MessageBox(m_hwnd, "This title's HLE Cache entry has been cleared.", "Cxbx-Reloaded", MB_OK); + m_Xbe->ExportLogoBitmap(i_gray); + + if (false == m_Xbe->HasError()) + { + FILE *LogoBitmap = fopen(ofn.lpstrFile, "wb"); + + // write bitmap header + { + BITMAPFILEHEADER bmfh; + + bmfh.bfType = *(uint16*)"BM"; + bmfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFO) - sizeof(RGBQUAD) + (100 * 17) * sizeof(RGBTRIPLE) + 2; + bmfh.bfReserved1 = 0; + bmfh.bfReserved2 = 0; + bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFO) - sizeof(RGBQUAD); + + fwrite(&bmfh, sizeof(bmfh), 1, LogoBitmap); + } + + // write bitmap info + { + BITMAPINFO bmi; + + bmi.bmiHeader.biSize = sizeof(BITMAPINFO) - sizeof(RGBQUAD); + bmi.bmiHeader.biWidth = 100; + bmi.bmiHeader.biHeight = -17; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 24; + bmi.bmiHeader.biCompression = BI_RGB; + bmi.bmiHeader.biSizeImage = 0; + bmi.bmiHeader.biXPelsPerMeter = 0; + bmi.bmiHeader.biYPelsPerMeter = 0; + bmi.bmiHeader.biClrUsed = 0; + bmi.bmiHeader.biClrImportant = 0; + + fwrite(&bmi, sizeof(bmi) - 4, 1, LogoBitmap); + } + + // write bitmap data + { + RGBTRIPLE bmp_data[100 * 17]; + + for (uint32 v = 0; v < 100 * 17; v++) + { + bmp_data[v].rgbtRed = i_gray[v]; + bmp_data[v].rgbtGreen = i_gray[v]; + bmp_data[v].rgbtBlue = i_gray[v]; + } + + fwrite(bmp_data, 100 * 17 * sizeof(RGBTRIPLE), 1, LogoBitmap); + } + + // write bitmap padding + { + uint16 pad = 0; + + fwrite(&pad, 2, 1, LogoBitmap); + } + + fclose(LogoBitmap); + } + + if (m_Xbe->HasError()) + MessageBox(m_hwnd, m_Xbe->GetError().c_str(), "Cxbx-Reloaded", MB_ICONSTOP | MB_OK); + else + { + char buffer[255]; + + sprintf(buffer, "%s's logo bitmap was successfully exported.", m_Xbe->m_szAsciiTitle); + + MessageBox(m_hwnd, buffer, "Cxbx-Reloaded", MB_ICONINFORMATION | MB_OK); + + printf("WndMain: %s\n", buffer); + } } } - break; + } + break; - case ID_EMULATION_DEBUGOUTPUTKERNEL_CONSOLE: - { - if(m_KrnlDebug == DM_NONE || m_KrnlDebug == DM_FILE) - m_KrnlDebug = DM_CONSOLE; - else - m_KrnlDebug = DM_NONE; + case ID_EDIT_LOGOBITMAP_IMPORT: + { + OPENFILENAME ofn = { 0 }; - MessageBox(m_hwnd, "This will not take effect until the next time emulation is started.\n", "Cxbx-Reloaded", MB_OK); + char filename[MAX_PATH] = "*.bmp"; - RefreshMenus(); + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = m_hwnd; + ofn.lpstrFilter = "Bitmap Image Files (*.bmp)\0*.bmp\0"; + ofn.lpstrFile = filename; + ofn.nMaxFile = MAX_PATH; + ofn.nFilterIndex = 1; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrInitialDir = NULL; + ofn.lpstrDefExt = "bmp"; + ofn.lpstrTitle = "Import Logo Bitmap"; + ofn.Flags = OFN_PATHMUSTEXIST; - UpdateDebugConsoles(); - } - break; - - case ID_EMULATION_DEBUGOUTPUTKERNEL_FILE: - { - if(m_KrnlDebug == DM_FILE) - { - m_KrnlDebug = DM_NONE; - - RefreshMenus(); - - UpdateDebugConsoles(); - } - else - { - OPENFILENAME ofn = {0}; - - char filename[MAX_PATH] = "KrnlDebug.txt"; - - ofn.lStructSize = sizeof(OPENFILENAME); - ofn.hwndOwner = m_hwnd; - ofn.lpstrFilter = "Text Documents (*.txt)\0*.txt\0"; - ofn.lpstrFile = filename; - ofn.nMaxFile = MAX_PATH; - ofn.nFilterIndex = 1; - ofn.lpstrFileTitle = NULL; - ofn.nMaxFileTitle = 0; - ofn.lpstrInitialDir = NULL; - ofn.lpstrDefExt = "txt"; - ofn.Flags = OFN_PATHMUSTEXIST; - - if(GetSaveFileName(&ofn) != FALSE) - { - MessageBox(m_hwnd, "This will not take effect until emulation is (re)started.\n", "Cxbx-Reloaded", MB_OK); - - strncpy(m_KrnlDebugFilename, ofn.lpstrFile, MAX_PATH-1); - - m_KrnlDebug = DM_FILE; - - RefreshMenus(); - - UpdateDebugConsoles(); - } - } - } - break; - - case ID_EMULATION_DEBUGOUTPUTGUI_CONSOLE: - { - if(m_CxbxDebug == DM_NONE || m_CxbxDebug == DM_FILE) - m_CxbxDebug = DM_CONSOLE; - else - m_CxbxDebug = DM_NONE; - - RefreshMenus(); - - UpdateDebugConsoles(); - } - break; - - case ID_EMULATION_DEBUGOUTPUTGUI_FILE: - { - if(m_CxbxDebug == DM_FILE) - { - m_CxbxDebug = DM_NONE; - - RefreshMenus(); - - UpdateDebugConsoles(); - } - else - { - OPENFILENAME ofn = {0}; - - char filename[MAX_PATH] = "CxbxDebug.txt"; - - ofn.lStructSize = sizeof(OPENFILENAME); - ofn.hwndOwner = m_hwnd; - ofn.lpstrFilter = "Text Documents (*.txt)\0*.txt\0"; - ofn.lpstrFile = filename; - ofn.nMaxFile = MAX_PATH; - ofn.nFilterIndex = 1; - ofn.lpstrFileTitle = NULL; - ofn.nMaxFileTitle = 0; - ofn.lpstrInitialDir = NULL; - ofn.lpstrDefExt = "txt"; - ofn.Flags = OFN_PATHMUSTEXIST; - - if(GetSaveFileName(&ofn) != FALSE) - { - strncpy(m_CxbxDebugFilename, ofn.lpstrFile, MAX_PATH-1); - - m_CxbxDebug = DM_FILE; - - RefreshMenus(); - - UpdateDebugConsoles(); - } - - } - } - break; - - case ID_EMULATION_LLE_JIT: + if (GetOpenFileName(&ofn) == TRUE) { - m_FlagsLLE = m_FlagsLLE ^ LLE_JIT; - ClearHLECache(); - RefreshMenus(); - } - break; + // import logo bitmap + { + uint08 i_gray[100 * 17]; - case ID_EMULATION_LLE_APU: + // read bitmap file + { + FILE *logo = fopen(ofn.lpstrFile, "rb"); + + char *bmp_err = 0; + + // read bitmap header + if (!bmp_err) + { + BITMAPFILEHEADER bmfh; + + fread(&bmfh, sizeof(bmfh), 1, logo); + + if (bmfh.bfType != *(uint16*)"BM") + bmp_err = "Invalid bitmap file...\n\nonly allows 24 bit bitmaps (100 by 17 pixels) with row order swapped"; + else if (bmfh.bfSize != sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFO) - sizeof(RGBQUAD) + (100 * 17) * sizeof(RGBTRIPLE) + 2) + bmp_err = "Invalid bitmap file...\n\nonly allows 24 bit bitmaps (100 by 17 pixels) with row order swapped"; + } + + // read bitmap info + if (!bmp_err) + { + BITMAPINFO bmi; + + fread(&bmi, sizeof(bmi) - 4, 1, logo); + + if (bmi.bmiHeader.biWidth != 100 || bmi.bmiHeader.biHeight != -17) + bmp_err = "Invalid bitmap file...\n\nonly allows 24 bit bitmaps (100 by 17 pixels) with row order swapped"; + } + + // read bitmap data + if (!bmp_err) + { + RGBTRIPLE bmp_data[100 * 17]; + + fread(bmp_data, 100 * 17 * sizeof(RGBTRIPLE), 1, logo); + + for (uint32 c = 0; c < 100 * 17; c++) + i_gray[c] = (char)(((float)bmp_data[c].rgbtRed + (float)bmp_data[c].rgbtGreen + (float)bmp_data[c].rgbtBlue) / 3.0); + } + + fclose(logo); + + if (bmp_err != 0) + { + MessageBox(m_hwnd, bmp_err, "Cxbx-Reloaded", MB_OK | MB_ICONEXCLAMATION); + break; + } + } + + m_Xbe->ImportLogoBitmap(i_gray); + + if (m_Xbe->HasError()) + { + MessageBox(m_hwnd, m_Xbe->GetError().c_str(), "Cxbx-Reloaded", MB_ICONSTOP | MB_OK); + + if (m_Xbe->HasFatalError()) + { + CloseXbe(); + } + else + { + m_Xbe->ClearError(); + } + + } + else + { + m_bXbeChanged = true; + + LoadLogo(); + + char buffer[255]; + + sprintf(buffer, "%s's logo bitmap was successfully updated.", m_Xbe->m_szAsciiTitle); + + printf("WndMain: %s\n", buffer); + + MessageBox(m_hwnd, buffer, "Cxbx-Reloaded", MB_ICONINFORMATION | MB_OK); + } + } + } + } + break; + + case ID_EDIT_PATCH_ALLOW64MB: + { + m_bXbeChanged = true; + + m_Xbe->m_Header.dwInitFlags.bLimit64MB = !m_Xbe->m_Header.dwInitFlags.bLimit64MB; + + RefreshMenus(); + + if (m_Xbe->m_Header.dwInitFlags.bLimit64MB) + printf("WndMain: %s was patched to limit to 64MB of memory usage.\n", m_Xbe->m_szAsciiTitle); + else + printf("WndMain: %s was patched to allow >64MB of memory usage.\n", m_Xbe->m_szAsciiTitle); + } + break; + + case ID_EDIT_PATCH_DEBUGMODE: + { + m_bXbeChanged = true; + + // patch to/from debug mode + if ((m_Xbe->m_Header.dwEntryAddr ^ XOR_EP_RETAIL) > 0x01000000) { - m_FlagsLLE = m_FlagsLLE ^ LLE_APU; - ClearHLECache(); - RefreshMenus(); - } - break; + // we're in debug mode, so switch over to retail + uint32 ep = m_Xbe->m_Header.dwEntryAddr ^ XOR_EP_RETAIL; // decode from debug mode + uint32 kt = m_Xbe->m_Header.dwKernelImageThunkAddr ^ XOR_KT_DEBUG; // decode from debug mode - case ID_EMULATION_LLE_GPU: + m_Xbe->m_Header.dwEntryAddr = ep ^ XOR_EP_DEBUG; // encode to retail mode + m_Xbe->m_Header.dwKernelImageThunkAddr = kt ^ XOR_KT_RETAIL; // encode to retail mode + } + else { - m_FlagsLLE = m_FlagsLLE ^ LLE_GPU; - ClearHLECache(); - RefreshMenus(); + // we're in retail mode, so switch to debug + uint32 ep = m_Xbe->m_Header.dwEntryAddr ^ XOR_EP_DEBUG; // decode from retail mode + uint32 kt = m_Xbe->m_Header.dwKernelImageThunkAddr ^ XOR_KT_RETAIL; // decode from retail mode + + m_Xbe->m_Header.dwEntryAddr = ep ^ XOR_EP_RETAIL; // encode to debug mode + m_Xbe->m_Header.dwKernelImageThunkAddr = kt ^ XOR_KT_DEBUG; // encode to debug mode } + + RefreshMenus(); + + bool res = (m_Xbe->m_Header.dwEntryAddr ^ XOR_EP_RETAIL) > 0x01000000; + + if (res) + printf("WndMain: %s was converted to debug mode.\n", m_Xbe->m_szAsciiTitle); + else + printf("WndMain: %s was converted to retail mode.\n", m_Xbe->m_szAsciiTitle); + } + break; + + case ID_EDIT_DUMPXBEINFOTO_FILE: + { + OPENFILENAME ofn = { 0 }; + + char filename[MAX_PATH] = "Xbe.txt"; + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = m_hwnd; + ofn.lpstrFilter = "Text Documents (*.txt)\0*.txt\0"; + ofn.lpstrFile = filename; + ofn.nMaxFile = MAX_PATH; + ofn.nFilterIndex = 1; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrInitialDir = NULL; + ofn.lpstrDefExt = "txt"; + ofn.Flags = OFN_PATHMUSTEXIST; + + if (GetSaveFileName(&ofn) == TRUE) + { + // ask permission to overwrite if file exists + if (_access(ofn.lpstrFile, 0) != -1) + { + if (MessageBox(m_hwnd, "Overwrite existing file?", "Cxbx-Reloaded", MB_ICONQUESTION | MB_YESNO) != IDYES) + return TRUE; + } + + // dump xbe information to file + { + FILE *TxtFile = fopen(ofn.lpstrFile, "wt"); + + // verify file was opened + if (TxtFile == 0) + MessageBox(m_hwnd, "Could not open text file.", "Cxbx-Reloaded", MB_ICONSTOP | MB_OK); + else + { + m_Xbe->DumpInformation(TxtFile); + + fclose(TxtFile); + + if (m_Xbe->HasError()) + { + MessageBox(m_hwnd, m_Xbe->GetError().c_str(), "Cxbx-Reloaded", MB_ICONSTOP | MB_OK); + } + else + { + char buffer[255]; + + sprintf(buffer, "%s's .xbe info was successfully dumped.", m_Xbe->m_szAsciiTitle); + + printf("WndMain: %s\n", buffer); + + MessageBox(m_hwnd, buffer, "Cxbx-Reloaded", MB_ICONINFORMATION | MB_OK); + } + } + } + } + } + break; + + case ID_EDIT_DUMPXBEINFOTO_DEBUGCONSOLE: + { + // dump xbe information to debug console + m_Xbe->DumpInformation(stdout); + + if (m_Xbe->HasError()) + { + MessageBox(m_hwnd, m_Xbe->GetError().c_str(), "Cxbx-Reloaded", MB_ICONSTOP | MB_OK); + } + else + { + char buffer[255]; + + sprintf(buffer, "%s's .xbe info was successfully dumped.", m_Xbe->m_szAsciiTitle); + + printf("WndMain: %s\n", buffer); + } + } + break; + + case ID_SETTINGS_CONFIG_CONTROLLER: + ShowControllerConfig(hwnd); break; - case ID_EMULATION_START: - StartEmulation(hwnd); - break; + case ID_SETTINGS_CONFIG_VIDEO: + ShowVideoConfig(hwnd); + break; - case ID_EMULATION_STOP: - StopEmulation(); - break; + case ID_CACHE_CLEARHLECACHE_ALL: + { + ClearHLECache(); + MessageBox(m_hwnd, "The entire HLE Cache has been cleared.", "Cxbx-Reloaded", MB_OK); + } + break; - case ID_HELP_ABOUT: - { - ShowAboutDialog(hwnd); - } + case ID_CACHE_CLEARHLECACHE_CURRENT: + { + std::string cacheDir = std::string(XTL::szFolder_CxbxReloadedData) + "\\HLECache\\"; + + // Hash the loaded XBE's header, use it as a filename + uint32_t uiHash = XXHash32::hash((void*)&m_Xbe->m_Header, sizeof(Xbe::Header), 0); + std::stringstream sstream; + sstream << cacheDir << std::hex << uiHash << ".ini"; + std::string fullpath = sstream.str(); + + if (DeleteFile(fullpath.c_str())) { + MessageBox(m_hwnd, "This title's HLE Cache entry has been cleared.", "Cxbx-Reloaded", MB_OK); + } + } + break; + + case ID_EMULATION_DEBUGOUTPUTKERNEL_CONSOLE: + { + if (m_KrnlDebug == DM_NONE || m_KrnlDebug == DM_FILE) + m_KrnlDebug = DM_CONSOLE; + else + m_KrnlDebug = DM_NONE; + + MessageBox(m_hwnd, "This will not take effect until the next time emulation is started.\n", "Cxbx-Reloaded", MB_OK); + + RefreshMenus(); + + UpdateDebugConsoles(); + } + break; + + case ID_EMULATION_DEBUGOUTPUTKERNEL_FILE: + { + if (m_KrnlDebug == DM_FILE) + { + m_KrnlDebug = DM_NONE; + + RefreshMenus(); + + UpdateDebugConsoles(); + } + else + { + OPENFILENAME ofn = { 0 }; + + char filename[MAX_PATH] = "KrnlDebug.txt"; + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = m_hwnd; + ofn.lpstrFilter = "Text Documents (*.txt)\0*.txt\0"; + ofn.lpstrFile = filename; + ofn.nMaxFile = MAX_PATH; + ofn.nFilterIndex = 1; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrInitialDir = NULL; + ofn.lpstrDefExt = "txt"; + ofn.Flags = OFN_PATHMUSTEXIST; + + if (GetSaveFileName(&ofn) != FALSE) + { + MessageBox(m_hwnd, "This will not take effect until emulation is (re)started.\n", "Cxbx-Reloaded", MB_OK); + + strncpy(m_KrnlDebugFilename, ofn.lpstrFile, MAX_PATH - 1); + + m_KrnlDebug = DM_FILE; + + RefreshMenus(); + + UpdateDebugConsoles(); + } + } + } + break; + + case ID_EMULATION_DEBUGOUTPUTGUI_CONSOLE: + { + if (m_CxbxDebug == DM_NONE || m_CxbxDebug == DM_FILE) + m_CxbxDebug = DM_CONSOLE; + else + m_CxbxDebug = DM_NONE; + + RefreshMenus(); + + UpdateDebugConsoles(); + } + break; + + case ID_EMULATION_DEBUGOUTPUTGUI_FILE: + { + if (m_CxbxDebug == DM_FILE) + { + m_CxbxDebug = DM_NONE; + + RefreshMenus(); + + UpdateDebugConsoles(); + } + else + { + OPENFILENAME ofn = { 0 }; + + char filename[MAX_PATH] = "CxbxDebug.txt"; + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = m_hwnd; + ofn.lpstrFilter = "Text Documents (*.txt)\0*.txt\0"; + ofn.lpstrFile = filename; + ofn.nMaxFile = MAX_PATH; + ofn.nFilterIndex = 1; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrInitialDir = NULL; + ofn.lpstrDefExt = "txt"; + ofn.Flags = OFN_PATHMUSTEXIST; + + if (GetSaveFileName(&ofn) != FALSE) + { + strncpy(m_CxbxDebugFilename, ofn.lpstrFile, MAX_PATH - 1); + + m_CxbxDebug = DM_FILE; + + RefreshMenus(); + + UpdateDebugConsoles(); + } + + } + } + break; + + case ID_EMULATION_LLE_JIT: + { + m_FlagsLLE = m_FlagsLLE ^ LLE_JIT; + ClearHLECache(); + RefreshMenus(); + } + break; + + case ID_EMULATION_LLE_APU: + { + m_FlagsLLE = m_FlagsLLE ^ LLE_APU; + ClearHLECache(); + RefreshMenus(); + } + break; + + case ID_EMULATION_LLE_GPU: + { + m_FlagsLLE = m_FlagsLLE ^ LLE_GPU; + ClearHLECache(); + RefreshMenus(); + } + break; + + case ID_SETTINGS_XINPUT: + m_XInputEnabled = !m_XInputEnabled; + RefreshMenus(); + break; + + case ID_EMULATION_START: + StartEmulation(hwnd); break; - case ID_HELP_HOMEPAGE: - ShellExecute(NULL, "open", "https://github.com/Cxbx-Reloaded/Cxbx-Reloaded", NULL, NULL, SW_SHOWNORMAL); - break; + case ID_EMULATION_STOP: + StopEmulation(); + break; + + case ID_HELP_ABOUT: + { + ShowAboutDialog(hwnd); + } + break; + + case ID_HELP_HOMEPAGE: + ShellExecute(NULL, "open", "https://github.com/Cxbx-Reloaded/Cxbx-Reloaded", NULL, NULL, SW_SHOWNORMAL); + break; } break; @@ -1303,12 +1314,15 @@ void WndMain::RefreshMenus() UINT chk_flag = (m_FlagsLLE & LLE_JIT) ? MF_CHECKED : MF_UNCHECKED; CheckMenuItem(settings_menu, ID_EMULATION_LLE_JIT, chk_flag); - + chk_flag = (m_FlagsLLE & LLE_APU) ? MF_CHECKED : MF_UNCHECKED; CheckMenuItem(settings_menu, ID_EMULATION_LLE_APU, chk_flag); chk_flag = (m_FlagsLLE & LLE_GPU) ? MF_CHECKED : MF_UNCHECKED; CheckMenuItem(settings_menu, ID_EMULATION_LLE_GPU, chk_flag); + + chk_flag = (m_XInputEnabled) ? MF_CHECKED : MF_UNCHECKED; + CheckMenuItem(settings_menu, ID_SETTINGS_XINPUT, chk_flag); } // emulation menu @@ -1587,6 +1601,9 @@ void WndMain::StartEmulation(HWND hwndParent) // register LLE flags with emulator process g_EmuShared->SetFlagsLLE(&m_FlagsLLE); + // register XInput flags with emulator process + g_EmuShared->SetXInputEnabled(&m_XInputEnabled); + // shell exe { GetModuleFileName(NULL, szBuffer, MAX_PATH); diff --git a/src/Cxbx/WndMain.h b/src/Cxbx/WndMain.h index 091558680..4921fdaf0 100644 --- a/src/Cxbx/WndMain.h +++ b/src/Cxbx/WndMain.h @@ -163,6 +163,11 @@ class WndMain : public Wnd // ****************************************************************** int m_FlagsLLE; + // ****************************************************************** + // * XInout Enabled Flag + // ****************************************************************** + int m_XInputEnabled; + // ****************************************************************** // * debug output filenames // ****************************************************************** diff --git a/src/CxbxKrnl/CxbxKrnl.cpp b/src/CxbxKrnl/CxbxKrnl.cpp index 75499e228..68634b562 100644 --- a/src/CxbxKrnl/CxbxKrnl.cpp +++ b/src/CxbxKrnl/CxbxKrnl.cpp @@ -666,6 +666,19 @@ void CxbxKrnlInit DbgPrintf("EmuMain : LLE enabled for JIT.\n"); } + // Process XInput Enabled flag + { + int XInputEnabled; + g_EmuShared->GetXInputEnabled(&XInputEnabled); + if (XInputEnabled) { + g_XInputEnabled = true; + printf("EmuMain : Using XInput\n"); + } else { + g_XInputEnabled = false; + printf("EmuMain : Using DirectInput\n"); + } + } + // Initialize devices : char szBuffer[MAX_PATH]; SHGetSpecialFolderPath(NULL, szBuffer, CSIDL_APPDATA, TRUE); diff --git a/src/CxbxKrnl/Emu.cpp b/src/CxbxKrnl/Emu.cpp index b37db4699..2835ed0b6 100644 --- a/src/CxbxKrnl/Emu.cpp +++ b/src/CxbxKrnl/Emu.cpp @@ -71,6 +71,7 @@ CHAR *g_strCurDrive= NULL; volatile bool g_bEmuException = false; volatile bool g_bEmuSuspended = false; volatile bool g_bPrintfOn = true; +bool g_XInputEnabled = false; // Delta added to host SystemTime, used in xboxkrnl::KeQuerySystemTime and xboxkrnl::NtSetSystemTime LARGE_INTEGER HostSystemTimeDelta = {}; diff --git a/src/CxbxKrnl/Emu.h b/src/CxbxKrnl/Emu.h index 134bd53f3..f30c06d9d 100644 --- a/src/CxbxKrnl/Emu.h +++ b/src/CxbxKrnl/Emu.h @@ -95,6 +95,7 @@ g_pXInputSetStateStatus[XINPUT_SETSTATE_SLOTS]; // 4 controllers #define XINPUT_HANDLE_SLOTS 4 +extern bool g_XInputEnabled; extern HANDLE g_hInputHandle[XINPUT_HANDLE_SLOTS]; extern void InitializeSectionStructures(void); diff --git a/src/CxbxKrnl/EmuDInput.h b/src/CxbxKrnl/EmuDInput.h index ea24eb568..13a3c0371 100644 --- a/src/CxbxKrnl/EmuDInput.h +++ b/src/CxbxKrnl/EmuDInput.h @@ -52,28 +52,4 @@ extern void EmuDInputCleanup(); // ****************************************************************** extern void EmuDInputPoll(PXINPUT_STATE Controller); -// ****************************************************************** -// * offsets into analog button array -// ****************************************************************** -#define XINPUT_GAMEPAD_A 0 -#define XINPUT_GAMEPAD_B 1 -#define XINPUT_GAMEPAD_X 2 -#define XINPUT_GAMEPAD_Y 3 -#define XINPUT_GAMEPAD_BLACK 4 -#define XINPUT_GAMEPAD_WHITE 5 -#define XINPUT_GAMEPAD_LEFT_TRIGGER 6 -#define XINPUT_GAMEPAD_RIGHT_TRIGGER 7 - -// ****************************************************************** -// * masks for digital buttons -// ****************************************************************** -#define XINPUT_GAMEPAD_DPAD_UP 0x00000001 -#define XINPUT_GAMEPAD_DPAD_DOWN 0x00000002 -#define XINPUT_GAMEPAD_DPAD_LEFT 0x00000004 -#define XINPUT_GAMEPAD_DPAD_RIGHT 0x00000008 -#define XINPUT_GAMEPAD_START 0x00000010 -#define XINPUT_GAMEPAD_BACK 0x00000020 -#define XINPUT_GAMEPAD_LEFT_THUMB 0x00000040 -#define XINPUT_GAMEPAD_RIGHT_THUMB 0x00000080 - #endif diff --git a/src/CxbxKrnl/EmuShared.h b/src/CxbxKrnl/EmuShared.h index 03d9bc6cd..8c72f32ee 100644 --- a/src/CxbxKrnl/EmuShared.h +++ b/src/CxbxKrnl/EmuShared.h @@ -91,6 +91,12 @@ class EmuShared : public Mutex void GetFlagsLLE( int *flags) { Lock(); *flags = m_FlagsLLE; Unlock(); } void SetFlagsLLE(const int *flags) { Lock(); m_FlagsLLE = *flags; Unlock(); } + // ****************************************************************** + // * XInput Flag Accessors + // ****************************************************************** + void GetXInputEnabled(int* value) { Lock(); *value = m_XInputEnabled; Unlock(); } + void SetXInputEnabled(int* value) { Lock(); m_XInputEnabled = *value; Unlock(); } + private: // ****************************************************************** // * Constructor / Deconstructor @@ -105,6 +111,7 @@ class EmuShared : public Mutex XBVideo m_XBVideo; char m_XbePath[MAX_PATH]; int m_FlagsLLE; + int m_XInputEnabled; }; // ****************************************************************** diff --git a/src/CxbxKrnl/EmuXInput.cpp b/src/CxbxKrnl/EmuXInput.cpp index 98ad6b740..0b190e000 100644 --- a/src/CxbxKrnl/EmuXInput.cpp +++ b/src/CxbxKrnl/EmuXInput.cpp @@ -41,24 +41,6 @@ #include "EmuShared.h" #include "EmuXInput.h" -// -// Prevent naming collisions -// -#undef XINPUT_GAMEPAD_DPAD_UP -#undef XINPUT_GAMEPAD_DPAD_DOWN -#undef XINPUT_GAMEPAD_DPAD_LEFT -#undef XINPUT_GAMEPAD_DPAD_RIGHT -#undef XINPUT_GAMEPAD_START -#undef XINPUT_GAMEPAD_BACK -#undef XINPUT_GAMEPAD_LEFT_THUMB -#undef XINPUT_GAMEPAD_RIGHT_THUMB -#undef XINPUT_GAMEPAD_LEFT_SHOULDER -#undef XINPUT_GAMEPAD_RIGHT_SHOULDER -#undef XINPUT_GAMEPAD_A -#undef XINPUT_GAMEPAD_B -#undef XINPUT_GAMEPAD_X -#undef XINPUT_GAMEPAD_Y - #include @@ -73,7 +55,7 @@ static BOOL g_bXInputInitialized = FALSE; // ****************************************************************** // * patch: XInputPCPoll // ****************************************************************** -/*void XTL::EMUPATCH(XInputPCPoll)( XTL::PXINPUT_STATE Controller ) +void XTL::EmuXInputPCPoll( XTL::PXINPUT_STATE Controller ) { // // Get the PC's XInput values @@ -85,20 +67,68 @@ static BOOL g_bXInputInitialized = FALSE; // // Now convert those values to Xbox XInput // - + // Analog Sticks Controller->Gamepad.sThumbLX = g_Controller.Gamepad.sThumbLX; Controller->Gamepad.sThumbLY = g_Controller.Gamepad.sThumbLY; Controller->Gamepad.sThumbRX = g_Controller.Gamepad.sThumbRX; Controller->Gamepad.sThumbRY = g_Controller.Gamepad.sThumbRY; - Controller->Gamepad.wButtons = g_Controller.Gamepad.wButtons & 0x00FF; + // Analog Buttons + Controller->Gamepad.bAnalogButtons[XB_XINPUT_GAMEPAD_A] = (g_Controller.Gamepad.wButtons & XINPUT_GAMEPAD_A) ? 255 : 0; + Controller->Gamepad.bAnalogButtons[XB_XINPUT_GAMEPAD_B] = (g_Controller.Gamepad.wButtons & XINPUT_GAMEPAD_B) ? 255 : 0; + Controller->Gamepad.bAnalogButtons[XB_XINPUT_GAMEPAD_X] = (g_Controller.Gamepad.wButtons & XINPUT_GAMEPAD_X) ? 255 : 0; + Controller->Gamepad.bAnalogButtons[XB_XINPUT_GAMEPAD_Y] = (g_Controller.Gamepad.wButtons & XINPUT_GAMEPAD_Y) ? 255 : 0; + Controller->Gamepad.bAnalogButtons[XB_XINPUT_GAMEPAD_WHITE] = (g_Controller.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) ? 255 : 0; + Controller->Gamepad.bAnalogButtons[XB_XINPUT_GAMEPAD_BLACK] = (g_Controller.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER) ? 255 : 0; + Controller->Gamepad.bAnalogButtons[XB_XINPUT_GAMEPAD_LEFT_TRIGGER] = g_Controller.Gamepad.bLeftTrigger; + Controller->Gamepad.bAnalogButtons[XB_XINPUT_GAMEPAD_RIGHT_TRIGGER] = g_Controller.Gamepad.bRightTrigger; - Controller->Gamepad.bAnalogButtons[0] = (g_Controller.Gamepad.wButtons & 0x1000) ? 1 : 0; - Controller->Gamepad.bAnalogButtons[1] = (g_Controller.Gamepad.wButtons & 0x2000) ? 1 : 0; - Controller->Gamepad.bAnalogButtons[2] = (g_Controller.Gamepad.wButtons & 0x4000) ? 1 : 0; - Controller->Gamepad.bAnalogButtons[3] = (g_Controller.Gamepad.wButtons & 0x8000) ? 1 : 0; - Controller->Gamepad.bAnalogButtons[4] = (g_Controller.Gamepad.wButtons & 0x0100) ? 1 : 0; - Controller->Gamepad.bAnalogButtons[5] = (g_Controller.Gamepad.wButtons & 0x0200) ? 1 : 0; - Controller->Gamepad.bAnalogButtons[6] = g_Controller.Gamepad.bLeftTrigger; - Controller->Gamepad.bAnalogButtons[7] = g_Controller.Gamepad.bRightTrigger; -}*/ + // Digital Buttons + if (g_Controller.Gamepad.wButtons & XINPUT_GAMEPAD_BACK) { + Controller->Gamepad.wButtons |= XB_XINPUT_GAMEPAD_BACK; + } else { + Controller->Gamepad.wButtons &= ~XB_XINPUT_GAMEPAD_BACK; + } + + if (g_Controller.Gamepad.wButtons & XINPUT_GAMEPAD_START) { + Controller->Gamepad.wButtons |= XB_XINPUT_GAMEPAD_START; + } else { + Controller->Gamepad.wButtons &= ~XB_XINPUT_GAMEPAD_START; + } + + if (g_Controller.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB) { + Controller->Gamepad.wButtons |= XB_XINPUT_GAMEPAD_LEFT_THUMB; + } else { + Controller->Gamepad.wButtons &= ~XB_XINPUT_GAMEPAD_LEFT_THUMB; + } + + if (g_Controller.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) { + Controller->Gamepad.wButtons |= XB_XINPUT_GAMEPAD_RIGHT_THUMB; + } else { + Controller->Gamepad.wButtons &= ~XB_XINPUT_GAMEPAD_RIGHT_THUMB; + } + + if (g_Controller.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP) { + Controller->Gamepad.wButtons |= XB_XINPUT_GAMEPAD_DPAD_UP; + } else { + Controller->Gamepad.wButtons &= ~XB_XINPUT_GAMEPAD_DPAD_UP; + } + + if (g_Controller.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN) { + Controller->Gamepad.wButtons |= XB_XINPUT_GAMEPAD_DPAD_DOWN; + } else { + Controller->Gamepad.wButtons &= ~XB_XINPUT_GAMEPAD_DPAD_DOWN; + } + + if (g_Controller.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) { + Controller->Gamepad.wButtons |= XB_XINPUT_GAMEPAD_DPAD_LEFT; + } else { + Controller->Gamepad.wButtons &= ~XB_XINPUT_GAMEPAD_DPAD_LEFT; + } + + if (g_Controller.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) { + Controller->Gamepad.wButtons |= XB_XINPUT_GAMEPAD_DPAD_RIGHT; + } else { + Controller->Gamepad.wButtons &= ~XB_XINPUT_GAMEPAD_DPAD_RIGHT; + } +} diff --git a/src/CxbxKrnl/EmuXInput.h b/src/CxbxKrnl/EmuXInput.h index 19ea97087..6d677b632 100644 --- a/src/CxbxKrnl/EmuXInput.h +++ b/src/CxbxKrnl/EmuXInput.h @@ -37,6 +37,6 @@ // ****************************************************************** // * patch: XInputPCPoll // ****************************************************************** -// void EmuXInputPCPoll( XTL::PXINPUT_STATE Controller ); +void EmuXInputPCPoll( XTL::PXINPUT_STATE Controller ); #endif \ No newline at end of file diff --git a/src/CxbxKrnl/EmuXapi.cpp b/src/CxbxKrnl/EmuXapi.cpp index ca35c439f..4136a314f 100644 --- a/src/CxbxKrnl/EmuXapi.cpp +++ b/src/CxbxKrnl/EmuXapi.cpp @@ -89,7 +89,6 @@ XFIBER g_Fibers[256]; // Number of fiber routines queued int g_FiberCount = 0; - // ****************************************************************** // * patch: XFormatUtilityDrive // ****************************************************************** @@ -462,8 +461,12 @@ DWORD WINAPI XTL::EMUPATCH(XInputGetState) if(dwPort == 0) { - EmuDInputPoll(pState); - // EmuXInputPCPoll(pState); + if (g_XInputEnabled) { + EmuXInputPCPoll(pState); + } else { + EmuDInputPoll(pState); + } + ret = ERROR_SUCCESS; } } diff --git a/src/CxbxKrnl/EmuXapi.h b/src/CxbxKrnl/EmuXapi.h index c8390b671..12f0d9eb9 100644 --- a/src/CxbxKrnl/EmuXapi.h +++ b/src/CxbxKrnl/EmuXapi.h @@ -229,6 +229,30 @@ typedef struct _XINPUT_STATE } XINPUT_STATE, *PXINPUT_STATE; +// ****************************************************************** +// * offsets into analog button array +// ****************************************************************** +#define XB_XINPUT_GAMEPAD_A 0 +#define XB_XINPUT_GAMEPAD_B 1 +#define XB_XINPUT_GAMEPAD_X 2 +#define XB_XINPUT_GAMEPAD_Y 3 +#define XB_XINPUT_GAMEPAD_BLACK 4 +#define XB_XINPUT_GAMEPAD_WHITE 5 +#define XB_XINPUT_GAMEPAD_LEFT_TRIGGER 6 +#define XB_XINPUT_GAMEPAD_RIGHT_TRIGGER 7 + +// ****************************************************************** +// * masks for digital buttons +// ****************************************************************** +#define XB_XINPUT_GAMEPAD_DPAD_UP 0x00000001 +#define XB_XINPUT_GAMEPAD_DPAD_DOWN 0x00000002 +#define XB_XINPUT_GAMEPAD_DPAD_LEFT 0x00000004 +#define XB_XINPUT_GAMEPAD_DPAD_RIGHT 0x00000008 +#define XB_XINPUT_GAMEPAD_START 0x00000010 +#define XB_XINPUT_GAMEPAD_BACK 0x00000020 +#define XB_XINPUT_GAMEPAD_LEFT_THUMB 0x00000040 +#define XB_XINPUT_GAMEPAD_RIGHT_THUMB 0x00000080 + // ****************************************************************** // * XINPUT_FEEDBACK_HEADER // ******************************************************************