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