mirror of
https://github.com/emu-russia/pureikyubu.git
synced 2025-04-02 10:42:15 -04:00
181 lines
4.6 KiB
C++
181 lines
4.6 KiB
C++
// Dolwin entrypoint (WinMain) and fail-safe application messages.
|
|
// WinMain() should never return.
|
|
#include "pch.h"
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// basic application output
|
|
|
|
namespace UI
|
|
{
|
|
|
|
// fatal error
|
|
void DolwinError(const TCHAR* title, const TCHAR* fmt, ...)
|
|
{
|
|
va_list arg;
|
|
TCHAR buf[0x1000];
|
|
|
|
va_start(arg, fmt);
|
|
_vstprintf_s(buf, _countof(buf) - 1, fmt, arg);
|
|
va_end(arg);
|
|
|
|
if (emu.doldebug)
|
|
{
|
|
char ansiText[0x1000] = { 0, }, * ansiPtr = ansiText;
|
|
|
|
TCHAR* tcharPtr = buf;
|
|
while (*tcharPtr)
|
|
{
|
|
*ansiPtr++ = (char)*tcharPtr++;
|
|
}
|
|
*ansiPtr++ = 0;
|
|
|
|
DBHalt(ansiPtr);
|
|
}
|
|
else
|
|
{
|
|
MessageBox(NULL, buf, title, MB_ICONHAND | MB_OK | MB_TOPMOST);
|
|
std::vector<std::string> cmd{ "exit" };
|
|
Debug::Hub.Execute(cmd);
|
|
}
|
|
}
|
|
|
|
// fatal error, if user answers no
|
|
// return TRUE if "yes", and FALSE if "no"
|
|
BOOL DolwinQuestion(const TCHAR* title, const TCHAR* fmt, ...)
|
|
{
|
|
va_list arg;
|
|
TCHAR buf[0x1000];
|
|
|
|
va_start(arg, fmt);
|
|
_vstprintf_s(buf, _countof(buf) - 1, fmt, arg);
|
|
va_end(arg);
|
|
|
|
int btn = MessageBox(
|
|
NULL,
|
|
buf,
|
|
title,
|
|
MB_RETRYCANCEL | MB_ICONHAND | MB_TOPMOST
|
|
);
|
|
if (btn == IDCANCEL)
|
|
{
|
|
SendMessage(wnd.hMainWindow, WM_COMMAND, ID_FILE_UNLOAD, 0);
|
|
return FALSE;
|
|
}
|
|
else return TRUE;
|
|
}
|
|
|
|
// application message
|
|
void DolwinReport(const TCHAR* fmt, ...)
|
|
{
|
|
va_list arg;
|
|
TCHAR buf[0x1000];
|
|
|
|
va_start(arg, fmt);
|
|
_vstprintf_s(buf, _countof(buf) - 1, fmt, arg);
|
|
va_end(arg);
|
|
|
|
MessageBox(NULL, buf, APPNAME _T(" Reports"), MB_ICONINFORMATION | MB_OK | MB_TOPMOST);
|
|
}
|
|
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// WinMain (very first run-time initialization and main loop)
|
|
|
|
// check for multiple instancies
|
|
static void LockMultipleCalls()
|
|
{
|
|
static HANDLE dolwinsem;
|
|
|
|
// mutex will fail if semephore already exists
|
|
dolwinsem = CreateMutex(NULL, 0, APPNAME);
|
|
if(dolwinsem == NULL)
|
|
{
|
|
UI::DolwinReport(_T("We are already running ") APPNAME _T("!!"));
|
|
exit(0); // return good
|
|
}
|
|
CloseHandle(dolwinsem);
|
|
|
|
dolwinsem = CreateSemaphore(NULL, 0, 1, APPNAME);
|
|
}
|
|
|
|
// set proper current working directory, create missing directories
|
|
static void InitFileSystem(HINSTANCE hInst)
|
|
{
|
|
// set current working directory relative to Dolwin executable
|
|
GetModuleFileName(hInst, ldat.cwd, sizeof(ldat.cwd));
|
|
*(_tcsrchr(ldat.cwd, _T('\\')) + 1) = 0;
|
|
SetCurrentDirectory(ldat.cwd);
|
|
|
|
// make sure, that Dolwin has data directory.
|
|
CreateDirectory(_T(".\\Data"), NULL);
|
|
}
|
|
|
|
// return file name without quotes
|
|
char * FixCommandLine(char *lpCmdLine)
|
|
{
|
|
if(*lpCmdLine == '\"' || *lpCmdLine == '\'')
|
|
{
|
|
lpCmdLine++;
|
|
}
|
|
size_t len = strlen(lpCmdLine);
|
|
if(lpCmdLine[len-1] == '\"' || lpCmdLine[len-1] == '\'')
|
|
{
|
|
lpCmdLine[len-1] = 0;
|
|
}
|
|
return lpCmdLine;
|
|
}
|
|
|
|
// keyboard accelerators (no need to be shared)
|
|
HACCEL hAccel;
|
|
|
|
// entrypoint
|
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
|
|
{
|
|
UNREFERENCED_PARAMETER(hPrevInstance);
|
|
UNREFERENCED_PARAMETER(nShowCmd);
|
|
|
|
// Required by HLE Subsystem
|
|
assert((uint64_t)hInstance <= 0x400000);
|
|
|
|
// prepare file system
|
|
InitFileSystem(hInstance);
|
|
|
|
// run Dolwin once ?
|
|
if(GetConfigBool(USER_RUNONCE, USER_UI))
|
|
{
|
|
LockMultipleCalls();
|
|
}
|
|
|
|
hAccel = LoadAccelerators(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_ACCELERATOR));
|
|
|
|
// init emu and user interface (emulator will be initialized
|
|
// during main window creation).
|
|
CreateMainWindow(hInstance);
|
|
|
|
// Idle loop
|
|
for(;;)
|
|
{
|
|
MSG msg;
|
|
|
|
while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) == 0)
|
|
{
|
|
UpdateProfiler();
|
|
Sleep(1);
|
|
}
|
|
|
|
// Idle loop
|
|
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
|
{
|
|
if (!TranslateAccelerator(wnd.hMainWindow, hAccel, &msg))
|
|
{
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
}
|
|
}
|
|
|
|
// should never reach this point. Dolwin always exit()'s.
|
|
UI::DolwinError(_T("ERROR"), APPNAME _T(" ERROR >>> SHOULD NEVER REACH HERE :)"));
|
|
return 1; // return bad
|
|
}
|