Dashboard fatal error + fix issue #878
This commit is contained in:
parent
81b1d75b4a
commit
753d9d89c2
|
@ -1271,6 +1271,18 @@ typedef struct _LAUNCH_DATA_PAGE
|
|||
}
|
||||
LAUNCH_DATA_PAGE, *PLAUNCH_DATA_PAGE;
|
||||
|
||||
// ******************************************************************
|
||||
// * DASH_LAUNCH_DATA
|
||||
// ******************************************************************
|
||||
typedef struct _DASH_LAUNCH_DATA
|
||||
{
|
||||
DWORD dwReason;
|
||||
DWORD dwContext;
|
||||
DWORD dwParameter1;
|
||||
DWORD dwParameter2;
|
||||
BYTE Reserved[3072 - 16];
|
||||
} DASH_LAUNCH_DATA, *PDASH_LAUNCH_DATA;
|
||||
|
||||
// ******************************************************************
|
||||
// * DISPATCHER_HEADER
|
||||
// ******************************************************************
|
||||
|
|
BIN
resource/Cxbx.rc
BIN
resource/Cxbx.rc
Binary file not shown.
|
@ -33,15 +33,28 @@
|
|||
// * All rights reserved
|
||||
// *
|
||||
// ******************************************************************
|
||||
#define _XBOXKRNL_DEFEXTRN_
|
||||
|
||||
// prevent name collisions
|
||||
namespace xboxkrnl
|
||||
{
|
||||
#include <xboxkrnl/xboxkrnl.h>
|
||||
};
|
||||
|
||||
#include "Xbe.h"
|
||||
#include "CxbxUtil.h" // For RoundUp
|
||||
|
||||
#include <experimental/filesystem> // filesystem related functions available on C++ 17
|
||||
#include <locale> // For ctime
|
||||
#include "devices\LED.h" // For LED::Sequence
|
||||
#include "CxbxKrnl/CxbxKrnl.h" // For CxbxKrnlPrintUEM
|
||||
#include "CxbxKrnl/EmuShared.h" // Include this to avoid including EmuXapi.h and EmuD3D8.h
|
||||
|
||||
namespace fs = std::experimental::filesystem;
|
||||
|
||||
|
||||
#define PAGE_SIZE 0x1000
|
||||
|
||||
// construct via Xbe file
|
||||
Xbe::Xbe(const char *x_szFilename)
|
||||
Xbe::Xbe(const char *x_szFilename, bool bFromGUI)
|
||||
{
|
||||
char szBuffer[MAX_PATH];
|
||||
|
||||
|
@ -54,8 +67,38 @@ Xbe::Xbe(const char *x_szFilename)
|
|||
// verify Xbe file was opened successfully
|
||||
if(XbeFile == 0)
|
||||
{
|
||||
SetFatalError("Could not open Xbe file.");
|
||||
return;
|
||||
using namespace fs; // limit its scope inside here
|
||||
|
||||
std::string XbeName = path(x_szFilename).filename().string(); // recover the xbe name
|
||||
|
||||
// NOTE: the check for the existence of the child window is necessary because the user could have previously loaded the dashboard,
|
||||
// removed/changed the path and attempt to load it again from the recent list, which will crash CxbxInitWindow below
|
||||
// Note that GetHwnd(), CxbxKrnl_hEmuParent and HalReturnToFirmware are all not suitable here for various reasons
|
||||
if (XbeName.compare(std::string("xboxdash.xbe")) == 0 && !bFromGUI)
|
||||
{
|
||||
// The dashboard could not be found on partition2. This is a fatal error on the Xbox so we display the UEM. The
|
||||
// error code is different if we have a launch data page
|
||||
|
||||
XTL::CxbxInitWindow(false);
|
||||
|
||||
ULONG FatalErrorCode = FATAL_ERROR_XBE_DASH_GENERIC;
|
||||
|
||||
if (xboxkrnl::LaunchDataPage && xboxkrnl::LaunchDataPage->Header.dwLaunchDataType == LDT_FROM_DASHBOARD)
|
||||
{
|
||||
xboxkrnl::PDASH_LAUNCH_DATA pLaunchDashboard = (xboxkrnl::PDASH_LAUNCH_DATA)&(xboxkrnl::LaunchDataPage->LaunchData[0]);
|
||||
FatalErrorCode += pLaunchDashboard->dwReason;
|
||||
}
|
||||
SetLEDSequence(0xE1); // green, red, red, red
|
||||
CxbxKrnlPrintUEM(FatalErrorCode); // won't return
|
||||
|
||||
// TODO: FATAL_ERROR_XBE_DASH_X2_PASS (requires DVD drive authentication emulation...)
|
||||
}
|
||||
else
|
||||
{
|
||||
// Report which xbe could not be found
|
||||
SetFatalError(std::string("Could not open the Xbe file ") + XbeName);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
printf("OK\n");
|
||||
|
|
|
@ -51,7 +51,7 @@ class Xbe : public Error
|
|||
{
|
||||
public:
|
||||
// construct via Xbe file
|
||||
Xbe(const char *x_szFilename);
|
||||
Xbe(const char *x_szFilename, bool bFromGUI);
|
||||
|
||||
// deconstructor
|
||||
~Xbe();
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#define IDD_ABOUT 119
|
||||
#define IDR_CONTRIBUTORS 121
|
||||
#define IDR_COPYING 122
|
||||
#define IDS_UEM 123
|
||||
#define IDC_SET_X 1000
|
||||
#define IDC_SET_Y 1001
|
||||
#define IDC_SET_A 1002
|
||||
|
|
|
@ -1786,7 +1786,7 @@ void WndMain::OpenXbe(const char *x_filename)
|
|||
|
||||
strcpy(m_XbeFilename, x_filename);
|
||||
|
||||
m_Xbe = new Xbe(m_XbeFilename);
|
||||
m_Xbe = new Xbe(m_XbeFilename, true);
|
||||
|
||||
if(m_Xbe->HasError())
|
||||
{
|
||||
|
|
|
@ -571,6 +571,9 @@ void CxbxKrnlMain(int argc, char* argv[])
|
|||
}
|
||||
}
|
||||
|
||||
// We must save this handle now to keep the child window working in the case we need to display the UEM
|
||||
CxbxKrnl_hEmuParent = IsWindow(hWnd) ? hWnd : NULL;
|
||||
|
||||
g_CurrentProcessHandle = GetCurrentProcess(); // OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
|
||||
|
||||
// Write a header to the log
|
||||
|
@ -600,6 +603,7 @@ void CxbxKrnlMain(int argc, char* argv[])
|
|||
g_IsWine = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Now we got the arguments, start by initializing the Xbox memory map :
|
||||
// PrepareXBoxMemoryMap()
|
||||
{
|
||||
|
@ -670,7 +674,7 @@ void CxbxKrnlMain(int argc, char* argv[])
|
|||
{
|
||||
// Load Xbe (this one will reside above WinMain's virtual_memory_placeholder)
|
||||
g_EmuShared->SetXbePath(xbePath.c_str());
|
||||
CxbxKrnl_Xbe = new Xbe(xbePath.c_str()); // TODO : Instead of using the Xbe class, port Dxbx _ReadXbeBlock()
|
||||
CxbxKrnl_Xbe = new Xbe(xbePath.c_str(), false); // TODO : Instead of using the Xbe class, port Dxbx _ReadXbeBlock()
|
||||
|
||||
if (CxbxKrnl_Xbe->HasFatalError()) {
|
||||
CxbxKrnlCleanup(CxbxKrnl_Xbe->GetError().c_str());
|
||||
|
@ -740,7 +744,6 @@ void CxbxKrnlMain(int argc, char* argv[])
|
|||
EntryPoint ^= XOR_EP_KEY[g_XbeType];
|
||||
// Launch XBE
|
||||
CxbxKrnlInit(
|
||||
hWnd,
|
||||
XbeTlsData,
|
||||
XbeTls,
|
||||
CxbxKrnl_Xbe->m_LibraryVersion,
|
||||
|
@ -790,7 +793,6 @@ void LoadXboxKeys(std::string path)
|
|||
|
||||
__declspec(noreturn) void CxbxKrnlInit
|
||||
(
|
||||
HWND hwndParent,
|
||||
void *pTLSData,
|
||||
Xbe::TLS *pTLS,
|
||||
Xbe::LibraryVersion *pLibraryVersion,
|
||||
|
@ -804,7 +806,6 @@ __declspec(noreturn) void CxbxKrnlInit
|
|||
CxbxKrnl_TLS = pTLS;
|
||||
CxbxKrnl_TLSData = pTLSData;
|
||||
CxbxKrnl_XbeHeader = pXbeHeader;
|
||||
CxbxKrnl_hEmuParent = IsWindow(hwndParent) ? hwndParent : NULL;
|
||||
CxbxKrnl_DebugMode = DbgMode;
|
||||
CxbxKrnl_DebugFileName = (char*)szDebugFilename;
|
||||
|
||||
|
@ -837,7 +838,7 @@ __declspec(noreturn) void CxbxKrnlInit
|
|||
" pXBEHeaderSize : 0x%.08X\n"
|
||||
" Entry : 0x%.08X\n"
|
||||
");\n",
|
||||
GetCurrentThreadId(), hwndParent, pTLSData, pTLS, pLibraryVersion, DbgMode, szDebugFilename, pXbeHeader, dwXbeHeaderSize, Entry);
|
||||
GetCurrentThreadId(), CxbxKrnl_hEmuParent, pTLSData, pTLS, pLibraryVersion, DbgMode, szDebugFilename, pXbeHeader, dwXbeHeaderSize, Entry);
|
||||
#else
|
||||
printf("[0x%X] INIT: Debug Trace Disabled.\n", GetCurrentThreadId());
|
||||
#endif
|
||||
|
@ -1008,7 +1009,7 @@ __declspec(noreturn) void CxbxKrnlInit
|
|||
|
||||
// initialize grapchics
|
||||
DbgPrintf("INIT: Initializing render window.\n");
|
||||
XTL::CxbxInitWindow(pXbeHeader, dwXbeHeaderSize);
|
||||
XTL::CxbxInitWindow(true);
|
||||
|
||||
// Now process the boot flags to see if there are any special conditions to handle
|
||||
int BootFlags = 0;
|
||||
|
@ -1296,6 +1297,11 @@ void CxbxKrnlPrintUEM(ULONG ErrorCode)
|
|||
xboxkrnl::XBOX_EEPROM Eeprom;
|
||||
ULONG ResultSize;
|
||||
|
||||
int BootFlags;
|
||||
g_EmuShared->GetBootFlags(&BootFlags);
|
||||
BootFlags &= ~BOOT_FATAL_ERROR; // clear the fatal error flag to avoid looping here endlessly
|
||||
g_EmuShared->SetBootFlags(&BootFlags);
|
||||
|
||||
NTSTATUS status = xboxkrnl::ExQueryNonVolatileSetting(xboxkrnl::XC_MAX_ALL, &Type, &Eeprom, sizeof(Eeprom), &ResultSize);
|
||||
|
||||
if (status == STATUS_SUCCESS)
|
||||
|
@ -1329,11 +1335,6 @@ void CxbxKrnlPrintUEM(ULONG ErrorCode)
|
|||
g_CxbxFatalErrorCode = ErrorCode;
|
||||
g_CxbxPrintUEM = true; // print the UEM
|
||||
|
||||
int BootFlags;
|
||||
g_EmuShared->GetBootFlags(&BootFlags);
|
||||
BootFlags ^= BOOT_FATAL_ERROR; // clear the fatal error flag to avoid looping here endlessly
|
||||
g_EmuShared->SetBootFlags(&BootFlags);
|
||||
|
||||
// Sleep forever to prevent continuing the initialization
|
||||
Sleep(INFINITE);
|
||||
}
|
||||
|
|
|
@ -177,7 +177,7 @@ bool CxbxKrnlVerifyVersion(const char *szVersion);
|
|||
void CxbxKrnlMain(int argc, char* argv[]);
|
||||
|
||||
/*! initialize emulation */
|
||||
__declspec(noreturn) void CxbxKrnlInit(HWND hwndParent, void *pTLSData, Xbe::TLS *pTLS, Xbe::LibraryVersion *LibraryVersion, DebugMode DbgMode, const char *szDebugFilename, Xbe::Header *XbeHeader, uint32 XbeHeaderSize, void (*Entry)());
|
||||
__declspec(noreturn) void CxbxKrnlInit(void *pTLSData, Xbe::TLS *pTLS, Xbe::LibraryVersion *LibraryVersion, DebugMode DbgMode, const char *szDebugFilename, Xbe::Header *XbeHeader, uint32 XbeHeaderSize, void (*Entry)());
|
||||
|
||||
/*! cleanup emulation */
|
||||
__declspec(noreturn) void CxbxKrnlCleanup(const char *szErrorMessage, ...);
|
||||
|
|
|
@ -57,6 +57,7 @@ namespace xboxkrnl
|
|||
#include "Logging.h"
|
||||
#include "EmuD3D8Logging.h"
|
||||
#include "HLEIntercept.h" // for bLLE_GPU
|
||||
#include "Cxbx\\ResCxbx.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <process.h>
|
||||
|
@ -97,8 +98,6 @@ static XTL::DDCAPS g_DriverCaps = { 0 };
|
|||
static DWORD g_dwOverlayW = 640; // Cached Overlay Width
|
||||
static DWORD g_dwOverlayH = 480; // Cached Overlay Height
|
||||
static DWORD g_dwOverlayP = 640; // Cached Overlay Pitch
|
||||
static Xbe::Header *g_XbeHeader = NULL; // XbeHeader
|
||||
static uint32 g_XbeHeaderSize = 0; // XbeHeaderSize
|
||||
static HBRUSH g_hBgBrush = NULL; // Background Brush
|
||||
static volatile bool g_bRenderWindowActive = false;
|
||||
static XBVideo g_XBVideo;
|
||||
|
@ -452,18 +451,15 @@ const char *D3DErrorString(HRESULT hResult)
|
|||
return buffer;
|
||||
}
|
||||
|
||||
VOID XTL::CxbxInitWindow(Xbe::Header *XbeHeader, uint32 XbeHeaderSize)
|
||||
VOID XTL::CxbxInitWindow(bool bFullInit)
|
||||
{
|
||||
g_EmuShared->GetXBVideo(&g_XBVideo);
|
||||
|
||||
if(g_XBVideo.GetFullscreen())
|
||||
CxbxKrnl_hEmuParent = NULL;
|
||||
|
||||
// cache XbeHeader and size of XbeHeader
|
||||
g_XbeHeader = XbeHeader;
|
||||
g_XbeHeaderSize = XbeHeaderSize;
|
||||
|
||||
// create timing thread
|
||||
if (bFullInit)
|
||||
{
|
||||
DWORD dwThreadId;
|
||||
|
||||
|
@ -499,7 +495,8 @@ VOID XTL::CxbxInitWindow(Xbe::Header *XbeHeader, uint32 XbeHeaderSize)
|
|||
|
||||
// Ported from Dxbx :
|
||||
// If possible, assign this thread to another core than the one that runs Xbox1 code :
|
||||
SetThreadAffinityMask(hRenderWindowThread, g_CPUOthers);
|
||||
if (bFullInit)
|
||||
SetThreadAffinityMask(hRenderWindowThread, g_CPUOthers);
|
||||
|
||||
while(!g_bRenderWindowActive)
|
||||
SwitchToThread();
|
||||
|
@ -510,6 +507,70 @@ VOID XTL::CxbxInitWindow(Xbe::Header *XbeHeader, uint32 XbeHeaderSize)
|
|||
SetFocus(g_hEmuWindow);
|
||||
}
|
||||
|
||||
void DrawUEM(HWND hWnd)
|
||||
{
|
||||
// Draw the universal error message (UEM)
|
||||
// See http://xboxdevwiki.net/Fatal_Error
|
||||
// Only call this from WM_PAINT message!
|
||||
|
||||
PAINTSTRUCT ps;
|
||||
|
||||
BeginPaint(hWnd, &ps);
|
||||
|
||||
HDC hDC = GetDC(hWnd);
|
||||
HDC hMemDC = CreateCompatibleDC(hDC);
|
||||
HBITMAP hUEMBmp = CreateCompatibleBitmap(hDC, 640, 480);
|
||||
HBITMAP hOriUEMBmp = (HBITMAP)SelectObject(hMemDC, hUEMBmp);
|
||||
|
||||
|
||||
int nHeight = -MulDiv(8, GetDeviceCaps(hMemDC, LOGPIXELSY), 72);
|
||||
|
||||
HFONT hFont = CreateFont(nHeight, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, FF_ROMAN, "Verdana");
|
||||
|
||||
HGDIOBJ tmpObj = SelectObject(hMemDC, hFont);
|
||||
|
||||
SetBkColor(hMemDC, RGB(0, 0, 0));
|
||||
|
||||
SetTextColor(hMemDC, RGB(0, 204, 0));
|
||||
|
||||
wchar_t buff[500];
|
||||
LoadStringW(GetModuleHandle(NULL), IDS_UEM, buff, sizeof(buff) / sizeof(wchar_t));
|
||||
std::wstring wstr(buff);
|
||||
|
||||
// Unfortunately, DrawTextW doesn't support vertical alignemnt, so we have to do the calculation
|
||||
// ourselves. See here: https://social.msdn.microsoft.com/Forums/vstudio/en-US/abd89aae-16a0-41c6-8db6-b119ea90b42a/win32-drawtext-how-center-in-vertical-with-new-lines-and-tabs?forum=vclanguage
|
||||
|
||||
RECT rect = { 0, 0, 640, 480 };
|
||||
RECT textrect = { 0, 0, 640, 480 };
|
||||
DrawTextW(hMemDC, wstr.c_str(), wstr.length(), &textrect, DT_CALCRECT);
|
||||
rect.top = (rect.bottom - textrect.bottom) / 2;
|
||||
DrawTextW(hMemDC, wstr.c_str(), wstr.length(), &rect, DT_CENTER);
|
||||
|
||||
|
||||
// Draw the Xbox error code
|
||||
|
||||
SetTextColor(hMemDC, RGB(255, 255, 255));
|
||||
std::string err_str(std::to_string(g_CxbxFatalErrorCode));
|
||||
rect.left = 20;
|
||||
DrawText(hMemDC, err_str.c_str(), err_str.length(), &rect, DT_LEFT);
|
||||
|
||||
GetClientRect(hWnd, &rect);
|
||||
SetStretchBltMode(hDC, COLORONCOLOR);
|
||||
StretchBlt(hDC, rect.left, rect.top, rect.right, rect.bottom, hMemDC, 0, 0, 640, 480, SRCCOPY);
|
||||
|
||||
SelectObject(hMemDC, hOriUEMBmp);
|
||||
SelectObject(hDC, tmpObj);
|
||||
|
||||
DeleteObject(hUEMBmp);
|
||||
DeleteObject(hFont);
|
||||
DeleteObject(hMemDC);
|
||||
|
||||
if (hDC != NULL)
|
||||
ReleaseDC(hWnd, hDC);
|
||||
|
||||
EndPaint(hWnd, &ps);
|
||||
}
|
||||
|
||||
inline DWORD GetXboxCommonResourceType(const XTL::X_D3DResource *pXboxResource)
|
||||
{
|
||||
// Don't pass in unassigned Xbox resources
|
||||
|
@ -1369,75 +1430,7 @@ static LRESULT WINAPI EmuMsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPar
|
|||
{
|
||||
if (g_CxbxPrintUEM)
|
||||
{
|
||||
// Draw the universal error message (UEM)
|
||||
// See http://xboxdevwiki.net/Fatal_Error
|
||||
|
||||
PAINTSTRUCT ps;
|
||||
|
||||
BeginPaint(hWnd, &ps);
|
||||
|
||||
HDC hDC = GetDC(hWnd);
|
||||
HDC hMemDC = CreateCompatibleDC(hDC);
|
||||
HBITMAP hUEMBmp = CreateCompatibleBitmap(hDC, 640, 480);
|
||||
HBITMAP hOriUEMBmp = (HBITMAP)SelectObject(hMemDC, hUEMBmp);
|
||||
|
||||
|
||||
int nHeight = -MulDiv(8, GetDeviceCaps(hMemDC, LOGPIXELSY), 72);
|
||||
|
||||
HFONT hFont = CreateFont(nHeight, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, FF_ROMAN, "Verdana");
|
||||
|
||||
HGDIOBJ tmpObj = SelectObject(hMemDC, hFont);
|
||||
|
||||
SetBkColor(hMemDC, RGB(0, 0, 0));
|
||||
|
||||
SetTextColor(hMemDC, RGB(0, 204, 0));
|
||||
|
||||
std::wstring wstr(
|
||||
L"Your Xbox requires service.\n\n\
|
||||
Please call Xbox Customer Support.\n\n\n\
|
||||
Ihre Xbox muss gewartet werden.\n\n\
|
||||
Bitte den Xbox-Kundendienst anrufen.\n\n\n\
|
||||
La consola Xbox requiere asistencia técnica.\n\n\
|
||||
Llame al servicio de soporte al cliente de la Xbox.\n\n\n\
|
||||
Xbox ha bisogno di manutenzione.\n\n\
|
||||
Chiamare l'Assistenza Clienti di Xbox.\n\n\n\
|
||||
Votre Xbox ne fonctionne pas correctement.\n\n\
|
||||
Veuillez contacter le Support à la clientèle Xbox.\n\n\n\
|
||||
不具合が生じました。お手数ですが、\n\n\
|
||||
Xboxカスタマー サポートにお問い合わせください。");
|
||||
|
||||
// Unfortunately, DrawTextW doesn't support vertical alignemnt, so we have to do the calculation
|
||||
// ourselves. See here: https://social.msdn.microsoft.com/Forums/vstudio/en-US/abd89aae-16a0-41c6-8db6-b119ea90b42a/win32-drawtext-how-center-in-vertical-with-new-lines-and-tabs?forum=vclanguage
|
||||
|
||||
RECT rect = { 0, 0, 640, 480 };
|
||||
RECT textrect = { 0, 0, 640, 480 };
|
||||
DrawTextW(hMemDC, wstr.c_str(), wstr.length(), &textrect, DT_CALCRECT);
|
||||
rect.top = (rect.bottom - textrect.bottom) / 2;
|
||||
DrawTextW(hMemDC, wstr.c_str(), wstr.length(), &rect, DT_CENTER);
|
||||
|
||||
|
||||
// Draw the Xbox error code
|
||||
|
||||
SetTextColor(hMemDC, RGB(255, 255, 255));
|
||||
std::string err_str(std::to_string(g_CxbxFatalErrorCode));
|
||||
rect.left = 20;
|
||||
DrawText(hMemDC, err_str.c_str(), err_str.length(), &rect, DT_LEFT);
|
||||
|
||||
GetClientRect(hWnd, &rect);
|
||||
SetStretchBltMode(hDC, COLORONCOLOR);
|
||||
StretchBlt(hDC, rect.left, rect.top, rect.right, rect.bottom, hMemDC, 0, 0, 640, 480, SRCCOPY);
|
||||
|
||||
SelectObject(hMemDC, hOriUEMBmp);
|
||||
SelectObject(hDC, tmpObj);
|
||||
|
||||
DeleteObject(hUEMBmp);
|
||||
DeleteObject(hFont);
|
||||
DeleteObject(hMemDC);
|
||||
|
||||
if (hDC != NULL)
|
||||
ReleaseDC(hWnd, hDC);
|
||||
|
||||
EndPaint(hWnd, &ps);
|
||||
DrawUEM(hWnd);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
#include <ddraw.h>
|
||||
|
||||
// initialize render window
|
||||
extern VOID CxbxInitWindow(Xbe::Header *XbeHeader, uint32 XbeHeaderSize);
|
||||
extern VOID CxbxInitWindow(bool bFullInit);
|
||||
|
||||
extern VOID CxbxSetPixelContainerHeader
|
||||
(
|
||||
|
|
|
@ -507,7 +507,11 @@ XBSYSAPI EXPORTNUM(49) xboxkrnl::VOID DECLSPEC_NORETURN NTAPI xboxkrnl::HalRetur
|
|||
g_EmuShared->GetXbePath(szWorkingDirectoy);
|
||||
snprintf(szArgsBuffer, 4096, "/load \"%s\" %u %d \"%s\"", szWorkingDirectoy, CxbxKrnl_hEmuParent, CxbxKrnl_DebugMode, CxbxKrnl_DebugFileName.c_str());
|
||||
if ((int)ShellExecute(NULL, "open", szFilePath_CxbxReloaded_Exe, szArgsBuffer, szWorkingDirectoy, SW_SHOWDEFAULT) <= 32)
|
||||
{
|
||||
int BootFlags = 0;
|
||||
g_EmuShared->SetBootFlags(&BootFlags); // clear all boot flags in the case of failure
|
||||
CxbxKrnlCleanup("Could not reboot");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue