void CFrame::OnRenderWindowSizeRequest(int width, int height) { if (Core::GetState() == Core::CORE_UNINITIALIZED || !SConfig::GetInstance().m_LocalCoreStartupParameter.bRenderWindowAutoSize || RendererIsFullscreen() || m_RenderFrame->IsMaximized()) return; int old_width, old_height, log_width = 0, log_height = 0; m_RenderFrame->GetClientSize(&old_width, &old_height); // Add space for the log/console/debugger window if (SConfig::GetInstance().m_LocalCoreStartupParameter.bRenderToMain && (SConfig::GetInstance().m_InterfaceLogWindow || SConfig::GetInstance().m_InterfaceConsole || SConfig::GetInstance().m_InterfaceLogConfigWindow) && !m_Mgr->GetPane(wxT("Pane 1")).IsFloating()) { switch (m_Mgr->GetPane(wxT("Pane 1")).dock_direction) { case wxAUI_DOCK_LEFT: case wxAUI_DOCK_RIGHT: log_width = m_Mgr->GetPane(wxT("Pane 1")).rect.GetWidth(); break; case wxAUI_DOCK_TOP: case wxAUI_DOCK_BOTTOM: log_height = m_Mgr->GetPane(wxT("Pane 1")).rect.GetHeight(); break; } } if (old_width != width + log_width || old_height != height + log_height) m_RenderFrame->SetClientSize(width + log_width, height + log_height); }
void CFrame::OnRenderParentMove(wxMoveEvent& event) { if (Core::GetState() != Core::CORE_UNINITIALIZED && !RendererIsFullscreen() && !m_RenderFrame->IsMaximized() && !m_RenderFrame->IsIconized()) { SConfig::GetInstance().iRenderWindowXPos = m_RenderFrame->GetPosition().x; SConfig::GetInstance().iRenderWindowYPos = m_RenderFrame->GetPosition().y; } event.Skip(); }
void CFrame::OnMove(wxMoveEvent& event) { event.Skip(); if (!IsMaximized() && !(SConfig::GetInstance().m_LocalCoreStartupParameter.bRenderToMain && RendererIsFullscreen())) { SConfig::GetInstance().m_LocalCoreStartupParameter.iPosX = GetPosition().x; SConfig::GetInstance().m_LocalCoreStartupParameter.iPosY = GetPosition().y; } }
void CFrame::OnResize(wxSizeEvent& event) { event.Skip(); if (!IsMaximized() && !(SConfig::GetInstance().m_LocalCoreStartupParameter.bRenderToMain && RendererIsFullscreen()) && !(Core::GetState() != Core::CORE_UNINITIALIZED && SConfig::GetInstance().m_LocalCoreStartupParameter.bRenderToMain && SConfig::GetInstance().m_LocalCoreStartupParameter.bRenderWindowAutoSize)) { SConfig::GetInstance().m_LocalCoreStartupParameter.iWidth = GetSize().GetWidth(); SConfig::GetInstance().m_LocalCoreStartupParameter.iHeight = GetSize().GetHeight(); } // Make sure the logger pane is a sane size if (!g_pCodeWindow && m_LogWindow && m_Mgr->GetPane(_T("Pane 1")).IsShown() && !m_Mgr->GetPane(_T("Pane 1")).IsFloating() && (m_LogWindow->x > GetClientRect().GetWidth() || m_LogWindow->y > GetClientRect().GetHeight())) ShowResizePane(); }
void CFrame::OnRenderParentResize(wxSizeEvent& event) { if (Core::GetState() != Core::CORE_UNINITIALIZED) { int width, height; if (!SConfig::GetInstance().bRenderToMain && !RendererIsFullscreen() && !m_RenderFrame->IsMaximized() && !m_RenderFrame->IsIconized()) { m_RenderFrame->GetClientSize(&width, &height); SConfig::GetInstance().iRenderWindowWidth = width; SConfig::GetInstance().iRenderWindowHeight = height; } m_LogWindow->Refresh(); m_LogWindow->Update(); // We call Renderer::ChangeSurface here to indicate the size has changed, // but pass the same window handle. This is needed for the Vulkan backend, // otherwise it cannot tell that the window has been resized on some drivers. if (g_renderer) g_renderer->ChangeSurface(GetRenderHandle()); } event.Skip(); }
void CFrame::OnKeyDown(wxKeyEvent& event) { if(Core::GetState() != Core::CORE_UNINITIALIZED && (RendererHasFocus() || g_TASInputDlg->HasFocus())) { int WiimoteId = -1; // Toggle fullscreen if (IsHotkey(event, HK_FULLSCREEN)) DoFullscreen(!RendererIsFullscreen()); // Send Debugger keys to CodeWindow else if (g_pCodeWindow && (event.GetKeyCode() >= WXK_F9 && event.GetKeyCode() <= WXK_F11)) event.Skip(); // Pause and Unpause else if (IsHotkey(event, HK_PLAY_PAUSE)) DoPause(); // Stop else if (IsHotkey(event, HK_STOP)) DoStop(); // Screenshot hotkey else if (IsHotkey(event, HK_SCREENSHOT)) Core::SaveScreenShot(); // Wiimote connect and disconnect hotkeys else if (IsHotkey(event, HK_WIIMOTE1_CONNECT)) WiimoteId = 0; else if (IsHotkey(event, HK_WIIMOTE2_CONNECT)) WiimoteId = 1; else if (IsHotkey(event, HK_WIIMOTE3_CONNECT)) WiimoteId = 2; else if (IsHotkey(event, HK_WIIMOTE4_CONNECT)) WiimoteId = 3; // State save and state load hotkeys /*else if (event.GetKeyCode() >= WXK_F1 && event.GetKeyCode() <= WXK_F8) { int slot_number = event.GetKeyCode() - WXK_F1 + 1; if (event.GetModifiers() == wxMOD_NONE) State::Load(slot_number); else if (event.GetModifiers() == wxMOD_SHIFT) State::Save(slot_number); else event.Skip(); }*/ else if (event.GetKeyCode() == WXK_F11 && event.GetModifiers() == wxMOD_NONE) State::LoadLastSaved(); else if (event.GetKeyCode() == WXK_F12) { if (event.GetModifiers() == wxMOD_NONE) State::UndoSaveState(); else if (event.GetModifiers() == wxMOD_SHIFT) State::UndoLoadState(); else event.Skip(); } else { unsigned int i = NUM_HOTKEYS; if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bRenderToMain || g_TASInputDlg->HasFocus()) { for (i = 0; i < NUM_HOTKEYS; i++) { if (IsHotkey(event, i)) { int cmd = GetCmdForHotkey(i); if (cmd >= 0) { wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED, cmd); wxMenuItem *item = GetMenuBar()->FindItem(cmd); if (item && item->IsCheckable()) { item->wxMenuItemBase::Toggle(); evt.SetInt(item->IsChecked()); } GetEventHandler()->AddPendingEvent(evt); break; } } } } // On OS X, we claim all keyboard events while // emulation is running to avoid wxWidgets sounding // the system beep for unhandled key events when // receiving pad/wiimote keypresses which take an // entirely different path through the HID subsystem. #ifndef __APPLE__ // On other platforms, we leave the key event alone // so it can be passed on to the windowing system. if (i == NUM_HOTKEYS) event.Skip(); #endif } // Actually perform the wiimote connection or disconnection if (WiimoteId >= 0) { bool connect = !GetMenuBar()->IsChecked(IDM_CONNECT_WIIMOTE1 + WiimoteId); ConnectWiimote(WiimoteId, connect); } // Send the OSD hotkeys to the video backend if (event.GetKeyCode() >= '3' && event.GetKeyCode() <= '7' && event.GetModifiers() == wxMOD_NONE) { #ifdef _WIN32 PostMessage((HWND)Core::GetWindowHandle(), WM_USER, WM_USER_KEYDOWN, event.GetKeyCode()); #elif defined(HAVE_X11) && HAVE_X11 X11Utils::SendKeyEvent(X11Utils::XDisplayFromHandle(GetHandle()), event.GetKeyCode()); #endif } // Send the freelook hotkeys to the video backend if ((event.GetKeyCode() == ')' || event.GetKeyCode() == '(' || event.GetKeyCode() == '0' || event.GetKeyCode() == '9' || event.GetKeyCode() == 'W' || event.GetKeyCode() == 'S' || event.GetKeyCode() == 'A' || event.GetKeyCode() == 'D' || event.GetKeyCode() == 'R') && event.GetModifiers() == wxMOD_SHIFT) { #ifdef _WIN32 PostMessage((HWND)Core::GetWindowHandle(), WM_USER, WM_USER_KEYDOWN, event.GetKeyCode()); #elif defined(HAVE_X11) && HAVE_X11 X11Utils::SendKeyEvent(X11Utils::XDisplayFromHandle(GetHandle()), event.GetKeyCode()); #endif } } else event.Skip(); }
// Stop the emulation void CFrame::DoStop() { if (!Core::IsRunningAndStarted()) return; if (m_confirmStop) return; // don't let this function run again until it finishes, or is aborted. m_confirmStop = true; m_bGameLoading = false; if (Core::GetState() != Core::CORE_UNINITIALIZED || m_RenderParent != nullptr) { #if defined __WXGTK__ wxMutexGuiLeave(); std::lock_guard<std::recursive_mutex> lk(keystate_lock); wxMutexGuiEnter(); #endif // Ask for confirmation in case the user accidentally clicked Stop / Escape if (SConfig::GetInstance().bConfirmStop) { // Exit fullscreen to ensure it does not cover the stop dialog. DoFullscreen(false); // Pause the state during confirmation and restore it afterwards Core::EState state = Core::GetState(); // Do not pause if netplay is running as CPU thread might be blocked // waiting on inputs bool should_pause = !NetPlayDialog::GetNetPlayClient(); // If exclusive fullscreen is not enabled then we can pause the emulation // before we've exited fullscreen. If not then we need to exit fullscreen first. should_pause = should_pause && (!RendererIsFullscreen() || !g_Config.ExclusiveFullscreenEnabled() || SConfig::GetInstance().bRenderToMain); if (should_pause) { Core::SetState(Core::CORE_PAUSE); } wxMessageDialog m_StopDlg( this, !m_tried_graceful_shutdown ? _("Do you want to stop the current emulation?") : _("A shutdown is already in progress. Unsaved data " "may be lost if you stop the current emulation " "before it completes. Force stop?"), _("Please confirm..."), wxYES_NO | wxSTAY_ON_TOP | wxICON_EXCLAMATION, wxDefaultPosition); HotkeyManagerEmu::Enable(false); int Ret = m_StopDlg.ShowModal(); HotkeyManagerEmu::Enable(true); if (Ret != wxID_YES) { if (should_pause) Core::SetState(state); m_confirmStop = false; return; } } const auto& stm = WII_IPC_HLE_Interface::GetDeviceByName("/dev/stm/eventhook"); if (!m_tried_graceful_shutdown && stm && std::static_pointer_cast<CWII_IPC_HLE_Device_stm_eventhook>(stm)->HasHookInstalled()) { Core::DisplayMessage("Shutting down", 30000); // Unpause because gracefully shutting down needs the game to actually request a shutdown if (Core::GetState() == Core::CORE_PAUSE) DoPause(); ProcessorInterface::PowerButton_Tap(); m_confirmStop = false; m_tried_graceful_shutdown = true; return; } if (UseDebugger && g_pCodeWindow) { if (g_pCodeWindow->HasPanel<CWatchWindow>()) g_pCodeWindow->GetPanel<CWatchWindow>()->SaveAll(); PowerPC::watches.Clear(); if (g_pCodeWindow->HasPanel<CBreakPointWindow>()) g_pCodeWindow->GetPanel<CBreakPointWindow>()->SaveAll(); PowerPC::breakpoints.Clear(); PowerPC::memchecks.Clear(); if (g_pCodeWindow->HasPanel<CBreakPointWindow>()) g_pCodeWindow->GetPanel<CBreakPointWindow>()->NotifyUpdate(); g_symbolDB.Clear(); Host_NotifyMapLoaded(); } // TODO: Show the author/description dialog here if (Movie::IsRecordingInput()) DoRecordingSave(); if (Movie::IsMovieActive()) Movie::EndPlayInput(false); if (NetPlayDialog::GetNetPlayClient()) NetPlayDialog::GetNetPlayClient()->Stop(); Core::Stop(); UpdateGUI(); } }
// Toggle fullscreen. In Windows the fullscreen mode is accomplished by expanding the m_Panel to // cover // the entire screen (when we render to the main window). void CFrame::OnToggleFullscreen(wxCommandEvent& WXUNUSED(event)) { DoFullscreen(!RendererIsFullscreen()); }