unsigned int WINAPI TheThread(void *) { _InterlockedExchange(&emuThreadReady, THREAD_INIT); setCurrentThreadName("EmuThread"); // Native overwrites host. Can't allow that. Host *oldHost = host; UpdateScreenScale(); NativeInit(__argc, (const char **)__argv, "1234", "1234", "1234"); Host *nativeHost = host; host = oldHost; host->UpdateUI(); //Check Colour depth HDC dc = GetDC(NULL); u32 colour_depth = GetDeviceCaps(dc, BITSPIXEL); ReleaseDC(NULL, dc); if (colour_depth != 32) { MessageBoxA(0, "Please switch your display to 32-bit colour mode", "OpenGL Error", MB_OK); ExitProcess(1); } std::string error_string; if (!host->InitGL(&error_string)) { Reporting::ReportMessage("OpenGL init error: %s", error_string.c_str()); std::string full_error = StringFromFormat( "Failed initializing OpenGL. Try upgrading your graphics drivers.\n\nError message:\n\n%s", error_string.c_str()); MessageBoxA(0, full_error.c_str(), "OpenGL Error", MB_OK | MB_ICONERROR); ERROR_LOG(BOOT, full_error.c_str()); // No safe way out without OpenGL. ExitProcess(1); } NativeInitGraphics(); INFO_LOG(BOOT, "Done."); _dbg_update_(); if (coreState == CORE_POWERDOWN) { INFO_LOG(BOOT, "Exit before core loop."); goto shutdown; } _InterlockedExchange(&emuThreadReady, THREAD_CORE_LOOP); if (g_Config.bBrowse) PostMessage(MainWindow::GetHWND(), WM_COMMAND, ID_FILE_LOAD, 0); Core_EnableStepping(FALSE); while (globalUIState != UISTATE_EXIT) { // We're here again, so the game quit. Restart Core_Run() which controls the UI. // This way they can load a new game. if (!Core_IsActive()) UpdateUIState(UISTATE_MENU); Core_Run(); } shutdown: _InterlockedExchange(&emuThreadReady, THREAD_SHUTDOWN); NativeShutdownGraphics(); host->ShutdownSound(); host = nativeHost; NativeShutdown(); host = oldHost; host->ShutdownGL(); _InterlockedExchange(&emuThreadReady, THREAD_END); return 0; }
unsigned int WINAPI TheThread(void *) { _InterlockedExchange(&emuThreadReady, THREAD_INIT); setCurrentThreadName("Emu"); // And graphics... host = new WindowsHost(MainWindow::GetHInstance(), MainWindow::GetHWND(), MainWindow::GetDisplayHWND()); host->SetWindowTitle(nullptr); // Convert the command-line arguments to Unicode, then to proper UTF-8 // (the benefit being that we don't have to pollute the UI project with win32 ifdefs and lots of Convert<whatever>To<whatever>). // This avoids issues with PPSSPP inadvertently destroying paths with Unicode glyphs // (using the ANSI args resulted in Japanese/Chinese glyphs being turned into question marks, at least for me..). // -TheDax std::vector<std::wstring> wideArgs = GetWideCmdLine(); std::vector<std::string> argsUTF8; for (auto& string : wideArgs) { argsUTF8.push_back(ConvertWStringToUTF8(string)); } std::vector<const char *> args; for (auto& string : argsUTF8) { args.push_back(string.c_str()); } bool performingRestart = NativeIsRestarting(); NativeInit(static_cast<int>(args.size()), &args[0], "1234", "1234", nullptr); host->UpdateUI(); GraphicsContext *graphicsContext = nullptr; std::string error_string; if (!host->InitGraphics(&error_string, &graphicsContext)) { // Before anything: are we restarting right now? if (performingRestart) { // Okay, switching graphics didn't work out. Probably a driver bug - fallback to restart. // This happens on NVIDIA when switching OpenGL -> Vulkan. g_Config.Save(); W32Util::ExitAndRestart(); } I18NCategory *err = GetI18NCategory("Error"); Reporting::ReportMessage("Graphics init error: %s", error_string.c_str()); const char *defaultErrorVulkan = "Failed initializing graphics. Try upgrading your graphics drivers.\n\nWould you like to try switching to OpenGL?\n\nError message:"; const char *defaultErrorOpenGL = "Failed initializing graphics. Try upgrading your graphics drivers.\n\nWould you like to try switching to DirectX 9?\n\nError message:"; const char *defaultErrorDirect3D9 = "Failed initializing graphics. Try upgrading your graphics drivers and directx 9 runtime.\n\nWould you like to try switching to OpenGL?\n\nError message:"; const char *genericError; int nextBackend = GPU_BACKEND_DIRECT3D9; switch (g_Config.iGPUBackend) { case GPU_BACKEND_DIRECT3D9: nextBackend = GPU_BACKEND_OPENGL; genericError = err->T("GenericDirect3D9Error", defaultErrorDirect3D9); break; case GPU_BACKEND_VULKAN: nextBackend = GPU_BACKEND_OPENGL; genericError = err->T("GenericVulkanError", defaultErrorVulkan); break; case GPU_BACKEND_OPENGL: default: nextBackend = GPU_BACKEND_DIRECT3D9; genericError = err->T("GenericOpenGLError", defaultErrorOpenGL); break; } std::string full_error = StringFromFormat("%s\n\n%s", genericError, error_string.c_str()); std::wstring title = ConvertUTF8ToWString(err->T("GenericGraphicsError", "Graphics Error")); bool yes = IDYES == MessageBox(0, ConvertUTF8ToWString(full_error).c_str(), title.c_str(), MB_ICONERROR | MB_YESNO); ERROR_LOG(BOOT, full_error.c_str()); if (yes) { // Change the config to the alternative and restart. g_Config.iGPUBackend = nextBackend; g_Config.Save(); W32Util::ExitAndRestart(); } // No safe way out without graphics. ExitProcess(1); } NativeInitGraphics(graphicsContext); NativeResized(); INFO_LOG(BOOT, "Done."); _dbg_update_(); if (coreState == CORE_POWERDOWN) { INFO_LOG(BOOT, "Exit before core loop."); goto shutdown; } _InterlockedExchange(&emuThreadReady, THREAD_CORE_LOOP); if (g_Config.bBrowse) PostMessage(MainWindow::GetHWND(), WM_COMMAND, ID_FILE_LOAD, 0); Core_EnableStepping(FALSE); while (GetUIState() != UISTATE_EXIT) { // We're here again, so the game quit. Restart Core_Run() which controls the UI. // This way they can load a new game. if (!Core_IsActive()) UpdateUIState(UISTATE_MENU); Core_Run(graphicsContext); } shutdown: _InterlockedExchange(&emuThreadReady, THREAD_SHUTDOWN); NativeShutdownGraphics(); // NativeShutdown deletes the graphics context through host->ShutdownGraphics(). NativeShutdown(); _InterlockedExchange(&emuThreadReady, THREAD_END); return 0; }
unsigned int WINAPI TheThread(void *) { _InterlockedExchange(&emuThreadReady, THREAD_INIT); setCurrentThreadName("EmuThread"); std::string memstick, flash0; GetSysDirectories(memstick, flash0); // Native overwrites host. Can't allow that. Host *oldHost = host; UpdateScreenScale(); NativeInit(__argc, (const char **)__argv, memstick.c_str(), memstick.c_str(), "1234"); Host *nativeHost = host; host = oldHost; host->UpdateUI(); std::string error_string; if (!host->InitGL(&error_string)) { Reporting::ReportMessage("OpenGL init error: %s", error_string.c_str()); std::string full_error = StringFromFormat( "Failed initializing OpenGL. Try upgrading your graphics drivers.\n\nError message:\n\n%s", error_string.c_str()); MessageBoxA(0, full_error.c_str(), "OpenGL Error", MB_OK | MB_ICONERROR); ERROR_LOG(BOOT, full_error.c_str()); goto shutdown; } NativeInitGraphics(); INFO_LOG(BOOT, "Done."); _dbg_update_(); if (coreState == CORE_POWERDOWN) { INFO_LOG(BOOT, "Exit before core loop."); goto shutdown; } _InterlockedExchange(&emuThreadReady, THREAD_CORE_LOOP); if (g_Config.bBrowse) { PostMessage(MainWindow::GetHWND(), WM_COMMAND, ID_FILE_LOAD, 0); //MainWindow::BrowseAndBoot(""); } Core_EnableStepping(FALSE); while (globalUIState != UISTATE_EXIT) { Core_Run(); // We're here again, so the game quit. Restart Core_Run() which controls the UI. // This way they can load a new game. Core_UpdateState(CORE_RUNNING); } shutdown: _InterlockedExchange(&emuThreadReady, THREAD_SHUTDOWN); NativeShutdownGraphics(); host = nativeHost; NativeShutdown(); host = oldHost; host->ShutdownGL(); _InterlockedExchange(&emuThreadReady, THREAD_END); //The CPU should return when a game is stopped and cleanup should be done here, //so we can restart the plugins (or load new ones) for the next game return 0; }
void EmuThread::run() { running = true; setCurrentThreadName("EmuThread"); host->UpdateUI(); host->InitGL(); glWindow->makeCurrent(); #ifndef USING_GLES2 glewInit(); #endif NativeInitGraphics(); INFO_LOG(BOOT, "Starting up hardware."); QElapsedTimer timer; while(running) { //UpdateGamepad(*input_state); timer.start(); gameMutex.lock(); bool gRun = gameRunning; gameMutex.unlock(); if(gRun) { gameMutex.lock(); glWindow->makeCurrent(); if(needInitGame) { g_State.bEmuThreadStarted = true; CoreParameter coreParameter; coreParameter.fileToStart = fileToStart.toStdString(); coreParameter.enableSound = true; coreParameter.gpuCore = GPU_GLES; coreParameter.cpuCore = (CPUCore)g_Config.iCpuCore; coreParameter.enableDebugging = true; coreParameter.printfEmuLog = false; coreParameter.headLess = false; coreParameter.renderWidth = 480 * g_Config.iWindowZoom; coreParameter.renderHeight = 272 * g_Config.iWindowZoom; coreParameter.outputWidth = dp_xres; coreParameter.outputHeight = dp_yres; coreParameter.pixelWidth = pixel_xres; coreParameter.pixelHeight = pixel_yres; coreParameter.startPaused = !g_Config.bAutoRun; std::string error_string; if (!PSP_Init(coreParameter, &error_string)) { ERROR_LOG(BOOT, "Error loading: %s", error_string.c_str()); FinalShutdown(); return; } LayoutGamepad(dp_xres, dp_yres); _dbg_update_(); host->UpdateDisassembly(); Core_EnableStepping(coreParameter.startPaused ? TRUE : FALSE); g_State.bBooted = true; #ifdef _DEBUG host->UpdateMemView(); #endif host->BootDone(); needInitGame = false; } UpdateInputState(input_state); for (int i = 0; i < controllistCount; i++) { if (input_state->pad_buttons_down & controllist[i].emu_id) { __CtrlButtonDown(controllist[i].psp_id); } if (input_state->pad_buttons_up & controllist[i].emu_id) { __CtrlButtonUp(controllist[i].psp_id); } } __CtrlSetAnalog(input_state->pad_lstick_x, input_state->pad_lstick_y); EndInputState(input_state); glstate.Restore(); glViewport(0, 0, pixel_xres, pixel_yres); Matrix4x4 ortho; ortho.setOrtho(0.0f, dp_xres, dp_yres, 0.0f, -1.0f, 1.0f); glsl_bind(UIShader_Get()); glUniformMatrix4fv(UIShader_Get()->u_worldviewproj, 1, GL_FALSE, ortho.getReadPtr()); ReapplyGfxState(); Core_Run(); // Hopefully coreState is now CORE_NEXTFRAME if (coreState == CORE_NEXTFRAME) { // set back to running for the next frame coreState = CORE_RUNNING; qint64 time = timer.elapsed(); const int frameTime = (1.0f/60.0f) * 1000; gameMutex.unlock(); if(time < frameTime) { glWindow->doneCurrent(); msleep(frameTime-time); glWindow->makeCurrent(); } gameMutex.lock(); timer.start(); } fbo_unbind(); UIShader_Prepare(); uiTexture->Bind(0); glViewport(0, 0, pixel_xres, pixel_yres); ui_draw2d.Begin(DBMODE_NORMAL); //if (g_Config.bShowTouchControls) // DrawGamepad(ui_draw2d); glsl_bind(UIShader_Get()); ui_draw2d.End(); ui_draw2d.Flush(UIShader_Get()); // Tiled renderers like PowerVR should benefit greatly from this. However - seems I can't call it? #if defined(USING_GLES2) bool hasDiscard = false; // TODO if (hasDiscard) { //glDiscardFramebuffer(GL_COLOR_EXT | GL_DEPTH_EXT | GL_STENCIL_EXT); } #endif glWindow->swapBuffers(); glWindow->doneCurrent(); gameMutex.unlock(); } else { gameMutex.lock(); glWindow->makeCurrent(); glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); time_update(); float t = (float)frames_ / 60.0f; frames_++; float alpha = t; if (t > 1.0f) alpha = 1.0f; float alphaText = alpha; //if (t > 2.0f) alphaText = 3.0f - t; glstate.Restore(); glViewport(0, 0, pixel_xres, pixel_yres); Matrix4x4 ortho; ortho.setOrtho(0.0f, dp_xres, dp_yres, 0.0f, -1.0f, 1.0f); glsl_bind(UIShader_Get()); glUniformMatrix4fv(UIShader_Get()->u_worldviewproj, 1, GL_FALSE, ortho.getReadPtr()); ReapplyGfxState(); UIShader_Prepare(); UIBegin(); DrawBackground(alpha); ui_draw2d.SetFontScale(1.5f, 1.5f); ui_draw2d.DrawText(UBUNTU48, "PPSSPP", dp_xres / 2, dp_yres / 2 - 30, colorAlpha(0xFFFFFFFF, alphaText), ALIGN_CENTER); ui_draw2d.SetFontScale(1.0f, 1.0f); ui_draw2d.DrawText(UBUNTU24, "Created by Henrik Rydgard", dp_xres / 2, dp_yres / 2 + 40, colorAlpha(0xFFFFFFFF, alphaText), ALIGN_CENTER); ui_draw2d.DrawText(UBUNTU24, "Free Software under GPL 2.0", dp_xres / 2, dp_yres / 2 + 70, colorAlpha(0xFFFFFFFF, alphaText), ALIGN_CENTER); ui_draw2d.DrawText(UBUNTU24, "www.ppsspp.org", dp_xres / 2, dp_yres / 2 + 130, colorAlpha(0xFFFFFFFF, alphaText), ALIGN_CENTER); UIEnd(); glsl_bind(UIShader_Get()); ui_draw2d.Flush(UIShader_Get()); glWindow->swapBuffers(); glWindow->doneCurrent(); gameMutex.unlock(); qint64 time = timer.elapsed(); const int frameTime = (1.0f/60.0f) * 1000; if(time < frameTime) { msleep(frameTime-time); } timer.start(); } } if(gameRunning) { stopGame(); } }
unsigned int WINAPI TheThread(void *) { _InterlockedExchange(&emuThreadReady, THREAD_INIT); setCurrentThreadName("Emu"); // And graphics... // Native overwrites host. Can't allow that. Host *oldHost = host; // Convert the command-line arguments to Unicode, then to proper UTF-8 // (the benefit being that we don't have to pollute the UI project with win32 ifdefs and lots of Convert<whatever>To<whatever>). // This avoids issues with PPSSPP inadvertently destroying paths with Unicode glyphs // (using the ANSI args resulted in Japanese/Chinese glyphs being turned into question marks, at least for me..). // -TheDax std::vector<std::wstring> wideArgs = GetWideCmdLine(); std::vector<std::string> argsUTF8; for (auto& string : wideArgs) { argsUTF8.push_back(ConvertWStringToUTF8(string)); } std::vector<const char *> args; for (auto& string : argsUTF8) { args.push_back(string.c_str()); } NativeInit(static_cast<int>(args.size()), &args[0], "1234", "1234", "1234"); Host *nativeHost = host; host = oldHost; host->UpdateUI(); //Check Colour depth HDC dc = GetDC(NULL); u32 colour_depth = GetDeviceCaps(dc, BITSPIXEL); ReleaseDC(NULL, dc); if (colour_depth != 32){ MessageBox(0, L"Please switch your display to 32-bit colour mode", L"OpenGL Error", MB_OK); ExitProcess(1); } std::string error_string; if (!host->InitGraphics(&error_string)) { Reporting::ReportMessage("Graphics init error: %s", error_string.c_str()); std::string full_error = StringFromFormat( "Failed initializing OpenGL. Try upgrading your graphics drivers.\n\nError message:\n\n%s", error_string.c_str()); MessageBox(0, ConvertUTF8ToWString(full_error).c_str(), L"OpenGL Error", MB_OK | MB_ICONERROR); ERROR_LOG(BOOT, full_error.c_str()); // No safe way out without OpenGL. ExitProcess(1); } NativeInitGraphics(); NativeResized(); INFO_LOG(BOOT, "Done."); _dbg_update_(); if (coreState == CORE_POWERDOWN) { INFO_LOG(BOOT, "Exit before core loop."); goto shutdown; } _InterlockedExchange(&emuThreadReady, THREAD_CORE_LOOP); if (g_Config.bBrowse) PostMessage(MainWindow::GetHWND(), WM_COMMAND, ID_FILE_LOAD, 0); Core_EnableStepping(FALSE); while (GetUIState() != UISTATE_EXIT) { // We're here again, so the game quit. Restart Core_Run() which controls the UI. // This way they can load a new game. if (!Core_IsActive()) UpdateUIState(UISTATE_MENU); Core_Run(); } shutdown: _InterlockedExchange(&emuThreadReady, THREAD_SHUTDOWN); NativeShutdownGraphics(); host->ShutdownSound(); host = nativeHost; NativeShutdown(); host = oldHost; host->ShutdownGraphics(); _InterlockedExchange(&emuThreadReady, THREAD_END); return 0; }
DWORD TheThread(LPVOID x) { setCurrentThreadName("EmuThread"); g_State.bEmuThreadStarted = true; host->UpdateUI(); host->InitGL(); INFO_LOG(BOOT, "Starting up hardware."); CoreParameter coreParameter; coreParameter.fileToStart = fileToStart; coreParameter.enableSound = true; coreParameter.gpuCore = GPU_GLES; coreParameter.cpuCore = g_Config.bJIT ? CPU_JIT : CPU_INTERPRETER; coreParameter.enableDebugging = true; coreParameter.printfEmuLog = false; coreParameter.headLess = false; //true; std::string error_string; if (!PSP_Init(coreParameter, &error_string)) { ERROR_LOG(BOOT, "Error loading: %s", error_string.c_str()); goto shutdown; } INFO_LOG(BOOT, "Done."); _dbg_update_(); if (g_Config.bAutoRun) { #ifdef _DEBUG host->UpdateDisassembly(); #endif Core_EnableStepping(FALSE); } else { #ifdef _DEBUG host->UpdateDisassembly(); #endif Core_EnableStepping(TRUE); } g_State.bBooted = true; #ifdef _DEBUG host->UpdateMemView(); #endif host->BootDone(); Core_Run(); host->PrepareShutdown(); PSP_Shutdown(); shutdown: host->ShutdownGL(); //The CPU should return when a game is stopped and cleanup should be done here, //so we can restart the plugins (or load new ones) for the next game g_State.bEmuThreadStarted = false; _endthreadex(0); return 0; }
void EmuThread::run() { running = true; setCurrentThreadName("EmuThread"); g_State.bEmuThreadStarted = true; host->UpdateUI(); host->InitGL(); glWindow->makeCurrent(); #ifndef USING_GLES2 glewInit(); #endif NativeInitGraphics(); INFO_LOG(BOOT, "Starting up hardware."); CoreParameter coreParameter; coreParameter.fileToStart = fileToStart.toStdString(); coreParameter.enableSound = true; coreParameter.gpuCore = GPU_GLES; coreParameter.cpuCore = (CPUCore)g_Config.iCpuCore; coreParameter.enableDebugging = true; coreParameter.printfEmuLog = false; coreParameter.headLess = false; coreParameter.renderWidth = 480 * g_Config.iWindowZoom; coreParameter.renderHeight = 272 * g_Config.iWindowZoom; coreParameter.outputWidth = dp_xres; coreParameter.outputHeight = dp_yres; coreParameter.pixelWidth = pixel_xres; coreParameter.pixelHeight = pixel_yres; coreParameter.startPaused = !g_Config.bAutoRun; std::string error_string; if (!PSP_Init(coreParameter, &error_string)) { ERROR_LOG(BOOT, "Error loading: %s", error_string.c_str()); FinalShutdown(); return; } LayoutGamepad(dp_xres, dp_yres); _dbg_update_(); host->UpdateDisassembly(); Core_EnableStepping(coreParameter.startPaused ? TRUE : FALSE); g_State.bBooted = true; #ifdef _DEBUG host->UpdateMemView(); #endif host->BootDone(); QElapsedTimer timer; while(running) { //UpdateGamepad(*input_state); timer.start(); UpdateInputState(input_state); static const int mapping[12][2] = { {PAD_BUTTON_A, CTRL_CROSS}, {PAD_BUTTON_B, CTRL_CIRCLE}, {PAD_BUTTON_X, CTRL_SQUARE}, {PAD_BUTTON_Y, CTRL_TRIANGLE}, {PAD_BUTTON_UP, CTRL_UP}, {PAD_BUTTON_DOWN, CTRL_DOWN}, {PAD_BUTTON_LEFT, CTRL_LEFT}, {PAD_BUTTON_RIGHT, CTRL_RIGHT}, {PAD_BUTTON_LBUMPER, CTRL_LTRIGGER}, {PAD_BUTTON_RBUMPER, CTRL_RTRIGGER}, {PAD_BUTTON_START, CTRL_START}, {PAD_BUTTON_SELECT, CTRL_SELECT}, }; for (int i = 0; i < 12; i++) { if (input_state->pad_buttons_down & mapping[i][0]) { __CtrlButtonDown(mapping[i][1]); } if (input_state->pad_buttons_up & mapping[i][0]) { __CtrlButtonUp(mapping[i][1]); } } __CtrlSetAnalog(input_state->pad_lstick_x, input_state->pad_lstick_y); EndInputState(input_state); glstate.Restore(); glViewport(0, 0, pixel_xres, pixel_yres); Matrix4x4 ortho; ortho.setOrtho(0.0f, dp_xres, dp_yres, 0.0f, -1.0f, 1.0f); glsl_bind(UIShader_Get()); glUniformMatrix4fv(UIShader_Get()->u_worldviewproj, 1, GL_FALSE, ortho.getReadPtr()); ReapplyGfxState(); Core_Run(); // Hopefully coreState is now CORE_NEXTFRAME if (coreState == CORE_NEXTFRAME) { // set back to running for the next frame coreState = CORE_RUNNING; qint64 time = timer.elapsed(); const int frameTime = (1.0f/60.0f) * 1000; if(time < frameTime) { msleep(frameTime-time); } timer.start(); } fbo_unbind(); UIShader_Prepare(); uiTexture->Bind(0); glViewport(0, 0, pixel_xres, pixel_yres); ui_draw2d.Begin(DBMODE_NORMAL); //if (g_Config.bShowTouchControls) // DrawGamepad(ui_draw2d); glsl_bind(UIShader_Get()); ui_draw2d.End(); ui_draw2d.Flush(UIShader_Get()); // Tiled renderers like PowerVR should benefit greatly from this. However - seems I can't call it? #if defined(USING_GLES2) bool hasDiscard = false; // TODO if (hasDiscard) { //glDiscardFramebuffer(GL_COLOR_EXT | GL_DEPTH_EXT | GL_STENCIL_EXT); } #endif glWindow->swapBuffers(); } glWindow->doneCurrent(); }