void VideoBackend::Video_Prepare() { // Better be safe... s_efbAccessRequested = FALSE; s_FifoShuttingDown = FALSE; s_swapRequested = FALSE; // internal interfaces g_renderer = new Renderer(m_window_handle); g_texture_cache = new TextureCache; g_vertex_manager = new VertexManager; g_perf_query = new PerfQuery; VertexShaderCache::Init(); PixelShaderCache::Init(); D3D::InitUtils(); // VideoCommon BPInit(); Fifo_Init(); IndexGenerator::Init(); VertexLoaderManager::Init(); OpcodeDecoder_Init(); VertexShaderManager::Init(); PixelShaderManager::Init(); CommandProcessor::Init(); PixelEngine::Init(); // Tell the host that the window is ready Host_Message(WM_USER_CREATE); }
void VideoBackend::Video_Prepare() { // internal interfaces g_renderer = std::make_unique<Renderer>(m_window_handle); g_texture_cache = std::make_unique<TextureCache>(); g_vertex_manager = std::make_unique<VertexManager>(); g_perf_query = std::make_unique<PerfQuery>(); g_xfb_encoder = std::make_unique<XFBEncoder>(); ShaderCache::Init(); ShaderConstantsManager::Init(); StaticShaderCache::Init(); StateCache::Init(); // PSO cache is populated here, after constituent shaders are loaded. D3D::InitUtils(); // VideoCommon BPInit(); Fifo::Init(); IndexGenerator::Init(); VertexLoaderManager::Init(); OpcodeDecoder::Init(); VertexShaderManager::Init(); PixelShaderManager::Init(true); GeometryShaderManager::Init(); CommandProcessor::Init(); PixelEngine::Init(); BBox::Init(); // Tell the host that the window is ready Host_Message(WM_USER_CREATE); }
// This is called after Video_Initialize() from the Core void VideoSoftware::Video_Prepare() { g_renderer = std::make_unique<SWRenderer>(); CommandProcessor::Init(); PixelEngine::Init(); BPInit(); g_vertex_manager = std::make_unique<SWVertexLoader>(); g_perf_query = std::make_unique<PerfQuery>(); Fifo::Init(); // must be done before OpcodeDecoder::Init() OpcodeDecoder::Init(); IndexGenerator::Init(); VertexShaderManager::Init(); PixelShaderManager::Init(); g_texture_cache = std::make_unique<TextureCache>(); SWRenderer::Init(); VertexLoaderManager::Init(); g_framebuffer_manager = std::make_unique<FramebufferManager>(); // Notify the core that the video backend is ready Host_Message(WM_USER_CREATE); INFO_LOG(VIDEO, "Video backend initialized."); }
// This is called after Initialize() from the Core // Run from the graphics thread void VideoBackend::Video_Prepare() { GLInterface->MakeCurrent(); g_renderer = new Renderer; s_efbAccessRequested = false; s_FifoShuttingDown = false; s_swapRequested = false; CommandProcessor::Init(); PixelEngine::Init(); g_texture_cache = new TextureCache; BPInit(); g_vertex_manager = new VertexManager; Fifo_Init(); // must be done before OpcodeDecoder_Init() OpcodeDecoder_Init(); VertexShaderCache::Init(); VertexShaderManager::Init(); PixelShaderCache::Init(); PixelShaderManager::Init(); PostProcessing::Init(); GL_REPORT_ERRORD(); VertexLoaderManager::Init(); TextureConverter::Init(); DLCache::Init(); // Notify the core that the video backend is ready Host_Message(WM_USER_CREATE); }
// This is called after Initialize() from the Core // Run from the graphics thread void VideoBackend::Video_Prepare() { GLInterface->MakeCurrent(); g_renderer = new Renderer; CommandProcessor::Init(); PixelEngine::Init(); BPInit(); g_vertex_manager = new VertexManager; g_perf_query = new PerfQuery; Fifo_Init(); // must be done before OpcodeDecoder_Init() OpcodeDecoder_Init(); IndexGenerator::Init(); VertexShaderManager::Init(); PixelShaderManager::Init(); ProgramShaderCache::Init(); g_texture_cache = new TextureCache(); g_sampler_cache = new SamplerCache(); Renderer::Init(); VertexLoaderManager::Init(); TextureConverter::Init(); // Notify the core that the video backend is ready Host_Message(WM_USER_CREATE); }
// This is called after Initialize() from the Core // Run from the graphics thread void VideoBackend::Video_Prepare() { GLInterface->MakeCurrent(); g_renderer = std::make_unique<Renderer>(); CommandProcessor::Init(); PixelEngine::Init(); BPInit(); g_vertex_manager = std::make_unique<VertexManager>(); g_perf_query = GetPerfQuery(); Fifo_Init(); // must be done before OpcodeDecoder_Init() OpcodeDecoder_Init(); IndexGenerator::Init(); VertexShaderManager::Init(); PixelShaderManager::Init(); GeometryShaderManager::Init(); ProgramShaderCache::Init(); g_texture_cache = std::make_unique<TextureCache>(); g_sampler_cache = std::make_unique<SamplerCache>(); Renderer::Init(); VertexLoaderManager::Init(); TextureConverter::Init(); BoundingBox::Init(); // Notify the core that the video backend is ready Host_Message(WM_USER_CREATE); }
void VideoBackend::Video_Prepare() { // internal interfaces g_renderer = new Renderer(m_window_handle); g_texture_cache = new TextureCache; g_vertex_manager = new VertexManager; g_perf_query = new PerfQuery; VertexShaderCache::Init(); PixelShaderCache::Init(); GeometryShaderCache::Init(); D3D::InitUtils(); // VideoCommon BPInit(); Fifo_Init(); IndexGenerator::Init(); VertexLoaderManager::Init(); OpcodeDecoder_Init(); VertexShaderManager::Init(); PixelShaderManager::Init(); GeometryShaderManager::Init(); CommandProcessor::Init(); PixelEngine::Init(); BBox::Init(); // Tell the host that the window is ready Host_Message(WM_USER_CREATE); }
bool VideoBackend::Initialize(void* window_handle) { InitializeShared(); InitBackendInfo(); // Load Configs g_Config.Load(File::GetUserPath(D_CONFIG_IDX) + "GFX.ini"); g_Config.GameIniLoad(); g_Config.UpdateProjectionHack(); g_Config.VerifyValidity(); UpdateActiveConfig(); // Do our OSD callbacks OSD::DoCallbacks(OSD::CallbackType::Initialization); // Initialize VideoCommon CommandProcessor::Init(); PixelEngine::Init(); BPInit(); Fifo::Init(); OpcodeDecoder::Init(); IndexGenerator::Init(); VertexShaderManager::Init(); PixelShaderManager::Init(); VertexLoaderManager::Init(); Host_Message(WM_USER_CREATE); return true; }
void VideoBackend::Video_Prepare() { // Better be safe... s_efbAccessRequested = FALSE; s_FifoShuttingDown = FALSE; s_swapRequested = FALSE; // internal interfaces g_vertex_manager = new VertexManager; g_renderer = new Renderer; g_texture_cache = new TextureCache; // VideoCommon BPInit(); Fifo_Init(); VertexLoaderManager::Init(); OpcodeDecoder_Init(); VertexShaderManager::Init(); PixelShaderManager::Init(); CommandProcessor::Init(); PixelEngine::Init(); DLCache::Init(); // Notify the core that the video backend is ready Host_Message(WM_USER_CREATE); }
void cX11Window::XEventThread() #endif { while (GLWin.win) { XEvent event; for (int num_events = XPending(GLWin.evdpy); num_events > 0; num_events--) { XNextEvent(GLWin.evdpy, &event); switch(event.type) { case ConfigureNotify: GLInterface->SetBackBufferDimensions(event.xconfigure.width, event.xconfigure.height); break; case ClientMessage: if ((unsigned long) event.xclient.data.l[0] == XInternAtom(GLWin.evdpy, "WM_DELETE_WINDOW", False)) Host_Message(WM_USER_STOP); break; default: break; } } Common::SleepCurrentThread(20); } }
bool FifoPlayer::Play() { if (!m_File) return false; if (m_File->GetFrameCount() == 0) return false; IsPlayingBackFifologWithBrokenEFBCopies = m_File->HasBrokenEFBCopies(); m_CurrentFrame = m_FrameRangeStart; LoadMemory(); // This loop replaces the CPU loop that occurs when a game is run while (PowerPC::GetState() != PowerPC::CPU_POWERDOWN) { if (PowerPC::GetState() == PowerPC::CPU_RUNNING) { if (m_CurrentFrame >= m_FrameRangeEnd) { if (m_Loop) { m_CurrentFrame = m_FrameRangeStart; PowerPC::ppcState.downcount = 0; CoreTiming::Advance(); } else { PowerPC::Stop(); Host_Message(WM_USER_STOP); } } else { if (m_FrameWrittenCb) m_FrameWrittenCb(); if (m_EarlyMemoryUpdates && m_CurrentFrame == m_FrameRangeStart) WriteAllMemoryUpdates(); WriteFrame(m_File->GetFrame(m_CurrentFrame), m_FrameInfo[m_CurrentFrame]); ++m_CurrentFrame; } } } IsPlayingBackFifologWithBrokenEFBCopies = false; return true; }
static void FifoPlayerThread() { DeclareAsCPUThread(); const SConfig& _CoreParameter = SConfig::GetInstance(); if (_CoreParameter.bCPUThread) { Common::SetCurrentThreadName("FIFO player thread"); } else { g_video_backend->Video_Prepare(); Common::SetCurrentThreadName("FIFO-GPU thread"); } // Enter CPU run loop. When we leave it - we are done. if (FifoPlayer::GetInstance().Open(_CoreParameter.m_strFilename)) { if (auto cpu_core = FifoPlayer::GetInstance().GetCPUCore()) { PowerPC::InjectExternalCPUCore(cpu_core.get()); s_is_started = true; CPUSetInitialExecutionState(); CPU::Run(); s_is_started = false; PowerPC::InjectExternalCPUCore(nullptr); } FifoPlayer::GetInstance().Close(); } // If we did not enter the CPU Run Loop above then run a fake one instead. // We need to be IsRunningAndStarted() for DolphinWX to stop us. if (CPU::GetState() != CPU::CPU_POWERDOWN) { s_is_started = true; Host_Message(WM_USER_STOP); while (CPU::GetState() != CPU::CPU_POWERDOWN) { if (!_CoreParameter.bCPUThread) g_video_backend->PeekMessages(); std::this_thread::sleep_for(std::chrono::milliseconds(20)); } s_is_started = false; } if (!_CoreParameter.bCPUThread) g_video_backend->Video_Cleanup(); return; }
void QueueHostJob(std::function<void()> job, bool run_during_stop) { if (!job) return; bool send_message = false; { std::lock_guard<std::mutex> guard(s_host_jobs_lock); send_message = s_host_jobs_queue.empty(); s_host_jobs_queue.emplace(HostJob{std::move(job), run_during_stop}); } // If the the queue was empty then kick the Host to come and get this job. if (send_message) Host_Message(WM_USER_JOB_DISPATCH); }
void Run() override { while (CPU::GetState() == CPU::CPU_RUNNING) { switch (m_parent->AdvanceFrame()) { case CPU::CPU_POWERDOWN: CPU::Break(); Host_Message(WM_USER_STOP); break; case CPU::CPU_STEPPING: CPU::Break(); Host_UpdateMainFrame(); break; } } }
void Run() override { while (CPU::GetState() == CPU::State::Running) { switch (m_parent->AdvanceFrame()) { case CPU::State::PowerDown: CPU::Break(); Host_Message(WM_USER_STOP); break; case CPU::State::Stepping: CPU::Break(); Host_UpdateMainFrame(); break; case CPU::State::Running: break; } } }
void VideoBackendBase::InitializeShared() { memset(&g_main_cp_state, 0, sizeof(g_main_cp_state)); memset(&g_preprocess_cp_state, 0, sizeof(g_preprocess_cp_state)); memset(texMem, 0, TMEM_SIZE); // Do our OSD callbacks OSD::DoCallbacks(OSD::CallbackType::Initialization); // do not initialize again for the config window m_initialized = true; s_FifoShuttingDown.Clear(); memset((void*)&s_beginFieldArgs, 0, sizeof(s_beginFieldArgs)); m_invalid = false; frameCount = 0; CommandProcessor::Init(); Fifo::Init(); OpcodeDecoder::Init(); PixelEngine::Init(); BPInit(); VertexLoaderManager::Init(); IndexGenerator::Init(); VertexShaderManager::Init(); GeometryShaderManager::Init(); PixelShaderManager::Init(); g_Config.Load(File::GetUserPath(D_CONFIG_IDX) + "GFX.ini"); g_Config.GameIniLoad(); g_Config.UpdateProjectionHack(); g_Config.VerifyValidity(); UpdateActiveConfig(); // Notify the core that the video backend is ready Host_Message(WM_USER_CREATE); }
// Initalize and create emulation thread // Call browser: Init():g_EmuThread(). // See the BootManager.cpp file description for a complete call schedule. void EmuThread() { const SCoreStartupParameter& _CoreParameter = SConfig::GetInstance().m_LocalCoreStartupParameter; Common::SetCurrentThreadName("Emuthread - Starting"); DisplayMessage(cpu_info.brand_string, 8000); DisplayMessage(cpu_info.Summarize(), 8000); DisplayMessage(_CoreParameter.m_strFilename, 3000); if (cpu_info.IsUnsafe() && (NetPlay::IsNetPlayRunning() || Movie::IsRecordingInput() || Movie::IsPlayingInput())) { PanicAlertT("Warning: Netplay/movies will desync because your CPU does not support DAZ and Dolphin does not emulate it anymore."); } Movie::Init(); HW::Init(); if (!g_video_backend->Initialize(g_pWindowHandle)) { PanicAlert("Failed to initialize video backend!"); Host_Message(WM_USER_STOP); return; } OSD::AddMessage("Dolphin " + g_video_backend->GetName() + " Video Backend.", 5000); if (!DSP::GetDSPEmulator()->Initialize(g_pWindowHandle, _CoreParameter.bWii, _CoreParameter.bDSPThread)) { HW::Shutdown(); g_video_backend->Shutdown(); PanicAlert("Failed to initialize DSP emulator!"); Host_Message(WM_USER_STOP); return; } Pad::Initialize(g_pWindowHandle); // Load and Init Wiimotes - only if we are booting in wii mode if (g_CoreStartupParameter.bWii) { Wiimote::Initialize(g_pWindowHandle, !g_stateFileName.empty()); // Activate wiimotes which don't have source set to "None" for (unsigned int i = 0; i != MAX_BBMOTES; ++i) if (g_wiimote_sources[i]) GetUsbPointer()->AccessWiiMote(i | 0x100)->Activate(true); } AudioCommon::InitSoundStream(g_pWindowHandle); // The hardware is initialized. g_bHwInit = true; // Boot to pause or not Core::SetState(_CoreParameter.bBootToPause ? Core::CORE_PAUSE : Core::CORE_RUN); // Load GCM/DOL/ELF whatever ... we boot with the interpreter core PowerPC::SetMode(PowerPC::MODE_INTERPRETER); CBoot::BootUp(); // Setup our core, but can't use dynarec if we are compare server if (_CoreParameter.iCPUCore && (!_CoreParameter.bRunCompareServer || _CoreParameter.bRunCompareClient)) PowerPC::SetMode(PowerPC::MODE_JIT); else PowerPC::SetMode(PowerPC::MODE_INTERPRETER); // Update the window again because all stuff is initialized Host_UpdateDisasmDialog(); Host_UpdateMainFrame(); // Determine the cpu thread function void (*cpuThreadFunc)(void); if (_CoreParameter.m_BootType == SCoreStartupParameter::BOOT_DFF) cpuThreadFunc = FifoPlayerThread; else cpuThreadFunc = CpuThread; // ENTER THE VIDEO THREAD LOOP if (_CoreParameter.bCPUThread) { // This thread, after creating the EmuWindow, spawns a CPU // thread, and then takes over and becomes the video thread Common::SetCurrentThreadName("Video thread"); g_video_backend->Video_Prepare(); // Spawn the CPU thread g_cpu_thread = std::thread(cpuThreadFunc); // become the GPU thread g_video_backend->Video_EnterLoop(); // We have now exited the Video Loop INFO_LOG(CONSOLE, "%s", StopMessage(false, "Video Loop Ended").c_str()); } else // SingleCore mode { // The spawned CPU Thread also does the graphics. // The EmuThread is thus an idle thread, which sleeps while // waiting for the program to terminate. Without this extra // thread, the video backend window hangs in single core mode // because noone is pumping messages. Common::SetCurrentThreadName("Emuthread - Idle"); // Spawn the CPU+GPU thread g_cpu_thread = std::thread(cpuThreadFunc); while (PowerPC::GetState() != PowerPC::CPU_POWERDOWN) { g_video_backend->PeekMessages(); Common::SleepCurrentThread(20); } } // Wait for g_cpu_thread to exit INFO_LOG(CONSOLE, "%s", StopMessage(true, "Stopping CPU-GPU thread ...").c_str()); #ifdef USE_GDBSTUB INFO_LOG(CONSOLE, "%s", StopMessage(true, "Stopping GDB ...").c_str()); gdb_deinit(); INFO_LOG(CONSOLE, "%s", StopMessage(true, "GDB stopped.").c_str()); #endif g_cpu_thread.join(); INFO_LOG(CONSOLE, "%s", StopMessage(true, "CPU thread stopped.").c_str()); if (_CoreParameter.bCPUThread) g_video_backend->Video_Cleanup(); VolumeHandler::EjectVolume(); FileMon::Close(); // Stop audio thread - Actually this does nothing when using HLE // emulation, but stops the DSP Interpreter when using LLE emulation. DSP::GetDSPEmulator()->DSP_StopSoundStream(); // We must set up this flag before executing HW::Shutdown() g_bHwInit = false; INFO_LOG(CONSOLE, "%s", StopMessage(false, "Shutting down HW").c_str()); HW::Shutdown(); INFO_LOG(CONSOLE, "%s", StopMessage(false, "HW shutdown").c_str()); Pad::Shutdown(); Wiimote::Shutdown(); g_video_backend->Shutdown(); AudioCommon::ShutdownSoundStream(); }
// Initialize and create emulation thread // Call browser: Init():s_emu_thread(). // See the BootManager.cpp file description for a complete call schedule. void EmuThread() { const SCoreStartupParameter& core_parameter = SConfig::GetInstance().m_LocalCoreStartupParameter; Common::SetCurrentThreadName("Emuthread - Starting"); if (SConfig::GetInstance().m_OCEnable) DisplayMessage("WARNING: running at non-native CPU clock! Game may not be stable.", 8000); DisplayMessage(cpu_info.brand_string, 8000); DisplayMessage(cpu_info.Summarize(), 8000); DisplayMessage(core_parameter.m_strFilename, 3000); Movie::Init(); HW::Init(); if (!g_video_backend->Initialize(s_window_handle)) { PanicAlert("Failed to initialize video backend!"); Host_Message(WM_USER_STOP); return; } OSD::AddMessage("Dolphin " + g_video_backend->GetName() + " Video Backend.", 5000); if (cpu_info.HTT) SConfig::GetInstance().m_LocalCoreStartupParameter.bDSPThread = cpu_info.num_cores > 4; else SConfig::GetInstance().m_LocalCoreStartupParameter.bDSPThread = cpu_info.num_cores > 2; if (!DSP::GetDSPEmulator()->Initialize(core_parameter.bWii, core_parameter.bDSPThread)) { HW::Shutdown(); g_video_backend->Shutdown(); PanicAlert("Failed to initialize DSP emulator!"); Host_Message(WM_USER_STOP); return; } Keyboard::Initialize(s_window_handle); Pad::Initialize(s_window_handle); // Load and Init Wiimotes - only if we are booting in Wii mode if (core_parameter.bWii) { Wiimote::Initialize(s_window_handle, !s_state_filename.empty()); // Activate Wiimotes which don't have source set to "None" for (unsigned int i = 0; i != MAX_BBMOTES; ++i) if (g_wiimote_sources[i]) GetUsbPointer()->AccessWiiMote(i | 0x100)->Activate(true); } AudioCommon::InitSoundStream(); // The hardware is initialized. s_hardware_initialized = true; // Boot to pause or not Core::SetState(core_parameter.bBootToPause ? Core::CORE_PAUSE : Core::CORE_RUN); // Load GCM/DOL/ELF whatever ... we boot with the interpreter core PowerPC::SetMode(PowerPC::MODE_INTERPRETER); CBoot::BootUp(); // Setup our core, but can't use dynarec if we are compare server if (core_parameter.iCPUCore != SCoreStartupParameter::CORE_INTERPRETER && (!core_parameter.bRunCompareServer || core_parameter.bRunCompareClient)) { PowerPC::SetMode(PowerPC::MODE_JIT); } else { PowerPC::SetMode(PowerPC::MODE_INTERPRETER); } // Update the window again because all stuff is initialized Host_UpdateDisasmDialog(); Host_UpdateMainFrame(); // Determine the CPU thread function void (*cpuThreadFunc)(void); if (core_parameter.m_BootType == SCoreStartupParameter::BOOT_DFF) cpuThreadFunc = FifoPlayerThread; else cpuThreadFunc = CpuThread; // ENTER THE VIDEO THREAD LOOP if (core_parameter.bCPUThread) { // This thread, after creating the EmuWindow, spawns a CPU // thread, and then takes over and becomes the video thread Common::SetCurrentThreadName("Video thread"); g_video_backend->Video_Prepare(); // Spawn the CPU thread s_cpu_thread = std::thread(cpuThreadFunc); // become the GPU thread g_video_backend->Video_EnterLoop(); // We have now exited the Video Loop INFO_LOG(CONSOLE, "%s", StopMessage(false, "Video Loop Ended").c_str()); } else // SingleCore mode { // The spawned CPU Thread also does the graphics. // The EmuThread is thus an idle thread, which sleeps while // waiting for the program to terminate. Without this extra // thread, the video backend window hangs in single core mode // because no one is pumping messages. Common::SetCurrentThreadName("Emuthread - Idle"); // Spawn the CPU+GPU thread s_cpu_thread = std::thread(cpuThreadFunc); while (PowerPC::GetState() != PowerPC::CPU_POWERDOWN) { g_video_backend->PeekMessages(); Common::SleepCurrentThread(20); } } INFO_LOG(CONSOLE, "%s", StopMessage(true, "Stopping Emu thread ...").c_str()); // Wait for s_cpu_thread to exit INFO_LOG(CONSOLE, "%s", StopMessage(true, "Stopping CPU-GPU thread ...").c_str()); #ifdef USE_GDBSTUB INFO_LOG(CONSOLE, "%s", StopMessage(true, "Stopping GDB ...").c_str()); gdb_deinit(); INFO_LOG(CONSOLE, "%s", StopMessage(true, "GDB stopped.").c_str()); #endif s_cpu_thread.join(); INFO_LOG(CONSOLE, "%s", StopMessage(true, "CPU thread stopped.").c_str()); if (core_parameter.bCPUThread) g_video_backend->Video_Cleanup(); VolumeHandler::EjectVolume(); FileMon::Close(); // Stop audio thread - Actually this does nothing when using HLE // emulation, but stops the DSP Interpreter when using LLE emulation. DSP::GetDSPEmulator()->DSP_StopSoundStream(); // We must set up this flag before executing HW::Shutdown() s_hardware_initialized = false; INFO_LOG(CONSOLE, "%s", StopMessage(false, "Shutting down HW").c_str()); HW::Shutdown(); INFO_LOG(CONSOLE, "%s", StopMessage(false, "HW shutdown").c_str()); Wiimote::Shutdown(); Keyboard::Shutdown(); Pad::Shutdown(); g_video_backend->Shutdown(); AudioCommon::ShutdownSoundStream(); INFO_LOG(CONSOLE, "%s", StopMessage(true, "Main Emu thread stopped").c_str()); // Clear on screen messages that haven't expired g_video_backend->Video_ClearMessages(); // Reload sysconf file in order to see changes committed during emulation if (core_parameter.bWii) SConfig::GetInstance().m_SYSCONF->Reload(); INFO_LOG(CONSOLE, "Stop [Video Thread]\t\t---- Shutdown complete ----"); Movie::Shutdown(); PatchEngine::Shutdown(); s_is_stopping = false; if (s_on_stopped_callback) s_on_stopped_callback(); }
void cX11Window::XEventThread() { // Free look variables static bool mouseLookEnabled = false; static bool mouseMoveEnabled = false; static float lastMouse[2]; while (GLWin.win) { XEvent event; KeySym key; for (int num_events = XPending(GLWin.evdpy); num_events > 0; num_events--) { XNextEvent(GLWin.evdpy, &event); switch(event.type) { case KeyPress: key = XLookupKeysym((XKeyEvent*)&event, 0); if (g_Config.bOSDHotKey) { switch (key) { case XK_3: OSDChoice = 1; // Toggle native resolution g_Config.iEFBScale = g_Config.iEFBScale + 1; if (g_Config.iEFBScale > 7) g_Config.iEFBScale = 0; break; case XK_4: OSDChoice = 2; // Toggle aspect ratio g_Config.iAspectRatio = (g_Config.iAspectRatio + 1) & 3; break; case XK_5: OSDChoice = 3; // Toggle EFB copy if (!g_Config.bEFBCopyEnable || g_Config.bCopyEFBToTexture) { g_Config.bEFBCopyEnable ^= true; g_Config.bCopyEFBToTexture = false; } else { g_Config.bCopyEFBToTexture = !g_Config.bCopyEFBToTexture; } break; case XK_6: OSDChoice = 4; g_Config.bDisableFog = !g_Config.bDisableFog; break; default: break; } } if (g_Config.bFreeLook) { static float debugSpeed = 1.0f; switch (key) { case XK_parenleft: debugSpeed /= 2.0f; break; case XK_parenright: debugSpeed *= 2.0f; break; case XK_w: VertexShaderManager::TranslateView(0.0f, debugSpeed); break; case XK_s: VertexShaderManager::TranslateView(0.0f, -debugSpeed); break; case XK_a: VertexShaderManager::TranslateView(debugSpeed, 0.0f); break; case XK_d: VertexShaderManager::TranslateView(-debugSpeed, 0.0f); break; case XK_r: VertexShaderManager::ResetView(); break; } } break; case ButtonPress: if (g_Config.bFreeLook) { switch (event.xbutton.button) { case 2: // Middle button lastMouse[0] = event.xbutton.x; lastMouse[1] = event.xbutton.y; mouseMoveEnabled = true; break; case 3: // Right button lastMouse[0] = event.xbutton.x; lastMouse[1] = event.xbutton.y; mouseLookEnabled = true; break; } } break; case ButtonRelease: if (g_Config.bFreeLook) { switch (event.xbutton.button) { case 2: // Middle button mouseMoveEnabled = false; break; case 3: // Right button mouseLookEnabled = false; break; } } break; case MotionNotify: if (g_Config.bFreeLook) { if (mouseLookEnabled) { VertexShaderManager::RotateView((event.xmotion.x - lastMouse[0]) / 200.0f, (event.xmotion.y - lastMouse[1]) / 200.0f); lastMouse[0] = event.xmotion.x; lastMouse[1] = event.xmotion.y; } if (mouseMoveEnabled) { VertexShaderManager::TranslateView((event.xmotion.x - lastMouse[0]) / 50.0f, (event.xmotion.y - lastMouse[1]) / 50.0f); lastMouse[0] = event.xmotion.x; lastMouse[1] = event.xmotion.y; } } break; case ConfigureNotify: Window winDummy; unsigned int borderDummy, depthDummy; XGetGeometry(GLWin.evdpy, GLWin.win, &winDummy, &GLWin.x, &GLWin.y, &GLWin.width, &GLWin.height, &borderDummy, &depthDummy); GLInterface->SetBackBufferDimensions(GLWin.width, GLWin.height); break; case ClientMessage: if ((unsigned long) event.xclient.data.l[0] == XInternAtom(GLWin.evdpy, "WM_DELETE_WINDOW", False)) Host_Message(WM_USER_STOP); if ((unsigned long) event.xclient.data.l[0] == XInternAtom(GLWin.evdpy, "RESIZE", False)) XMoveResizeWindow(GLWin.evdpy, GLWin.win, event.xclient.data.l[1], event.xclient.data.l[2], event.xclient.data.l[3], event.xclient.data.l[4]); break; default: break; } } Common::SleepCurrentThread(20); } }
void HBReload() { // There isn't much we can do. Just stop cleanly. PowerPC::Pause(); Host_Message(WM_USER_STOP); }