1 // Copyright 2015 Dolphin Emulator Project
2 // Licensed under GPLv2+
3 // Refer to the license.txt file included.
4 
5 #include "DolphinQt/Host.h"
6 
7 #include <QAbstractEventDispatcher>
8 #include <QApplication>
9 
10 #include <imgui.h>
11 
12 #include "Common/Common.h"
13 
14 #include "Core/Config/MainSettings.h"
15 #include "Core/ConfigManager.h"
16 #include "Core/Core.h"
17 #include "Core/Debugger/PPCDebugInterface.h"
18 #include "Core/Host.h"
19 #include "Core/NetPlayProto.h"
20 #include "Core/PowerPC/PowerPC.h"
21 #include "Core/State.h"
22 
23 #include "DolphinQt/QtUtils/QueueOnObject.h"
24 #include "DolphinQt/Settings.h"
25 
26 #include "InputCommon/ControllerInterface/ControllerInterface.h"
27 
28 #include "UICommon/DiscordPresence.h"
29 
30 #include "VideoCommon/RenderBase.h"
31 #include "VideoCommon/VideoConfig.h"
32 
Host()33 Host::Host()
34 {
35   State::SetOnAfterLoadCallback([this] { Host_UpdateDisasmDialog(); });
36 }
37 
~Host()38 Host::~Host()
39 {
40   State::SetOnAfterLoadCallback(nullptr);
41 }
42 
GetInstance()43 Host* Host::GetInstance()
44 {
45   static Host* s_instance = new Host();
46   return s_instance;
47 }
48 
SetRenderHandle(void * handle)49 void Host::SetRenderHandle(void* handle)
50 {
51   if (m_render_handle == handle)
52     return;
53 
54   m_render_handle = handle;
55   if (g_renderer)
56   {
57     g_renderer->ChangeSurface(handle);
58     if (g_controller_interface.IsInit())
59       g_controller_interface.ChangeWindow(handle);
60   }
61 }
62 
GetRenderFocus()63 bool Host::GetRenderFocus()
64 {
65   return m_render_focus;
66 }
67 
SetRenderFocus(bool focus)68 void Host::SetRenderFocus(bool focus)
69 {
70   m_render_focus = focus;
71   if (g_renderer && m_render_fullscreen && g_ActiveConfig.ExclusiveFullscreenEnabled())
72     Core::RunAsCPUThread([focus] {
73       if (!Config::Get(Config::MAIN_RENDER_TO_MAIN))
74         g_renderer->SetFullscreen(focus);
75     });
76 }
77 
GetRenderFullscreen()78 bool Host::GetRenderFullscreen()
79 {
80   return m_render_fullscreen;
81 }
82 
SetRenderFullscreen(bool fullscreen)83 void Host::SetRenderFullscreen(bool fullscreen)
84 {
85   m_render_fullscreen = fullscreen;
86 
87   if (g_renderer && g_renderer->IsFullscreen() != fullscreen &&
88       g_ActiveConfig.ExclusiveFullscreenEnabled())
89     Core::RunAsCPUThread([fullscreen] { g_renderer->SetFullscreen(fullscreen); });
90 }
91 
ResizeSurface(int new_width,int new_height)92 void Host::ResizeSurface(int new_width, int new_height)
93 {
94   if (g_renderer)
95     g_renderer->ResizeSurface();
96 }
97 
Host_Message(HostMessageID id)98 void Host_Message(HostMessageID id)
99 {
100   if (id == HostMessageID::WMUserStop)
101   {
102     emit Host::GetInstance()->RequestStop();
103   }
104   else if (id == HostMessageID::WMUserJobDispatch)
105   {
106     // Just poke the main thread to get it to wake up, job dispatch
107     // will happen automatically before it goes back to sleep again.
108     QAbstractEventDispatcher::instance(qApp->thread())->wakeUp();
109   }
110 }
111 
Host_UpdateTitle(const std::string & title)112 void Host_UpdateTitle(const std::string& title)
113 {
114   emit Host::GetInstance()->RequestTitle(QString::fromStdString(title));
115 }
116 
Host_RendererHasFocus()117 bool Host_RendererHasFocus()
118 {
119   return Host::GetInstance()->GetRenderFocus();
120 }
121 
Host_RendererIsFullscreen()122 bool Host_RendererIsFullscreen()
123 {
124   return Host::GetInstance()->GetRenderFullscreen();
125 }
126 
Host_YieldToUI()127 void Host_YieldToUI()
128 {
129   qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
130 }
131 
Host_UpdateDisasmDialog()132 void Host_UpdateDisasmDialog()
133 {
134   QueueOnObject(QApplication::instance(), [] { emit Host::GetInstance()->UpdateDisasmDialog(); });
135 }
136 
RequestNotifyMapLoaded()137 void Host::RequestNotifyMapLoaded()
138 {
139   QueueOnObject(QApplication::instance(), [this] { emit NotifyMapLoaded(); });
140 }
141 
Host_NotifyMapLoaded()142 void Host_NotifyMapLoaded()
143 {
144   Host::GetInstance()->RequestNotifyMapLoaded();
145 }
146 
147 // We ignore these, and their purpose should be questioned individually.
148 // In particular, RequestRenderWindowSize, RequestFullscreen, and
149 // UpdateMainFrame should almost certainly be removed.
Host_UpdateMainFrame()150 void Host_UpdateMainFrame()
151 {
152 }
153 
Host_RequestRenderWindowSize(int w,int h)154 void Host_RequestRenderWindowSize(int w, int h)
155 {
156   emit Host::GetInstance()->RequestRenderSize(w, h);
157 }
158 
Host_UIBlocksControllerState()159 bool Host_UIBlocksControllerState()
160 {
161   return ImGui::GetCurrentContext() && ImGui::GetIO().WantCaptureKeyboard;
162 }
163 
Host_RefreshDSPDebuggerWindow()164 void Host_RefreshDSPDebuggerWindow()
165 {
166 }
167 
Host_TitleChanged()168 void Host_TitleChanged()
169 {
170 #ifdef USE_DISCORD_PRESENCE
171   // TODO: Not sure if the NetPlay check is needed.
172   if (!NetPlay::IsNetPlayRunning())
173     Discord::UpdateDiscordPresence();
174 #endif
175 }
176