Removed the hackery that was being done with the plugin configuration dialogs on...
[dolphin.git] / Source / Plugins / Plugin_VideoDX9 / Src / main.cpp
blob94d01611c4254caea8ce5bd3bacd277f2abb019d
1 // Copyright (C) 2003 Dolphin Project.
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, version 2.0.
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 // GNU General Public License 2.0 for more details.
12 // A copy of the GPL 2.0 should have been included with the program.
13 // If not, see http://www.gnu.org/licenses/
15 // Official SVN repository and contact information can be found at
16 // http://code.google.com/p/dolphin-emu/
18 #include "Common.h"
19 #include "Atomic.h"
20 #include "Thread.h"
21 #include "LogManager.h"
22 #include "debugger/debugger.h"
24 #if defined(HAVE_WX) && HAVE_WX
25 #include "DlgSettings.h"
26 GFXConfigDialogDX *m_ConfigFrame = NULL;
27 #endif // HAVE_WX
29 #if defined(HAVE_WX) && HAVE_WX
30 #include "Debugger/Debugger.h"
31 #endif // HAVE_WX
33 #include "main.h"
34 #include "VideoConfig.h"
35 #include "Fifo.h"
36 #include "OpcodeDecoding.h"
37 #include "TextureCache.h"
38 #include "BPStructs.h"
39 #include "VertexManager.h"
40 #include "VertexLoaderManager.h"
41 #include "VertexShaderManager.h"
42 #include "PixelShaderManager.h"
43 #include "VertexShaderCache.h"
44 #include "PixelShaderCache.h"
45 #include "CommandProcessor.h"
46 #include "PixelEngine.h"
47 #include "OnScreenDisplay.h"
48 #include "DlgSettings.h"
49 #include "D3DTexture.h"
50 #include "D3DUtil.h"
51 #include "EmuWindow.h"
52 #include "VideoState.h"
53 #include "XFBConvert.h"
54 #include "render.h"
56 HINSTANCE g_hInstance = NULL;
57 SVideoInitialize g_VideoInitialize;
58 PLUGIN_GLOBALS* globals = NULL;
59 static bool s_PluginInitialized = false;
61 volatile u32 s_swapRequested = FALSE;
62 static u32 s_efbAccessRequested = FALSE;
63 static volatile u32 s_FifoShuttingDown = FALSE;
65 static volatile struct
67 u32 xfbAddr;
68 FieldType field;
69 u32 fbWidth;
70 u32 fbHeight;
71 } s_beginFieldArgs;
73 static volatile EFBAccessType s_AccessEFBType;
75 bool HandleDisplayList(u32 address, u32 size)
77 return false;
80 bool IsD3D()
82 return true;
85 // This is used for the functions right below here which use wxwidgets
86 #if defined(HAVE_WX) && HAVE_WX
87 WXDLLIMPEXP_BASE void wxSetInstance(HINSTANCE hInst);
88 #endif
90 void *DllDebugger(void *_hParent, bool Show)
92 #if defined(HAVE_WX) && HAVE_WX
93 return new GFXDebuggerDX9((wxWindow *)_hParent);
94 #else
95 return NULL;
96 #endif
99 #if defined(HAVE_WX) && HAVE_WX
100 class wxDLLApp : public wxApp
102 bool OnInit()
104 return true;
107 IMPLEMENT_APP_NO_MAIN(wxDLLApp)
108 WXDLLIMPEXP_BASE void wxSetInstance(HINSTANCE hInst);
109 #endif
111 BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
113 switch (dwReason)
115 case DLL_PROCESS_ATTACH:
117 #if defined(HAVE_WX) && HAVE_WX
118 wxSetInstance((HINSTANCE)hinstDLL);
119 wxInitialize();
120 #endif
122 break;
123 case DLL_PROCESS_DETACH:
124 #if defined(HAVE_WX) && HAVE_WX
125 wxUninitialize();
126 #endif
127 break;
130 g_hInstance = hinstDLL;
131 return TRUE;
134 unsigned int Callback_PeekMessages()
136 MSG msg;
137 while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
139 if (msg.message == WM_QUIT)
140 return FALSE;
141 TranslateMessage(&msg);
142 DispatchMessage(&msg);
144 return TRUE;
148 void UpdateFPSDisplay(const char *text)
150 TCHAR temp[512];
151 swprintf_s(temp, 512, _T("SVN R%s: DX9: %hs"), svn_rev_str, text);
152 SetWindowText(EmuWindow::GetWnd(), temp);
155 void GetDllInfo (PLUGIN_INFO* _PluginInfo)
157 _PluginInfo->Version = 0x0100;
158 _PluginInfo->Type = PLUGIN_TYPE_VIDEO;
159 #ifdef DEBUGFAST
160 sprintf_s(_PluginInfo->Name, 100, "Dolphin Direct3D9 (DebugFast)");
161 #else
162 #ifndef _DEBUG
163 sprintf_s(_PluginInfo->Name, 100, "Dolphin Direct3D9");
164 #else
165 sprintf_s(_PluginInfo->Name, 100, "Dolphin Direct3D9 (Debug)");
166 #endif
167 #endif
170 void SetDllGlobals(PLUGIN_GLOBALS* _pPluginGlobals)
172 globals = _pPluginGlobals;
173 LogManager::SetInstance((LogManager*)globals->logManager);
176 void DllAbout(HWND _hParent)
178 //DialogBox(g_hInstance,(LPCTSTR)IDD_ABOUT,_hParent,(DLGPROC)AboutProc);
181 void DllConfig(void *_hParent)
183 // If not initialized, only init D3D so we can enumerate resolutions.
184 if (!s_PluginInitialized)
185 D3D::Init();
186 g_Config.Load((std::string(File::GetUserPath(D_CONFIG_IDX)) + "gfx_dx9.ini").c_str());
187 g_Config.GameIniLoad(globals->game_ini);
188 UpdateActiveConfig();
189 #if defined(HAVE_WX) && HAVE_WX
190 m_ConfigFrame = new GFXConfigDialogDX((wxWindow *)_hParent);
192 m_ConfigFrame->CreateGUIControls();
193 m_ConfigFrame->ShowModal();
194 m_ConfigFrame->Destroy();
195 #endif
196 if (!s_PluginInitialized)
197 D3D::Shutdown();
200 void Initialize(void *init)
202 frameCount = 0;
203 SVideoInitialize *_pVideoInitialize = (SVideoInitialize*)init;
204 g_VideoInitialize = *_pVideoInitialize;
205 InitXFBConvTables();
207 g_Config.Load((std::string(File::GetUserPath(D_CONFIG_IDX)) + "gfx_dx9.ini").c_str());
208 g_Config.GameIniLoad(globals->game_ini);
209 UpdateProjectionHack(g_Config.iPhackvalue); // DX9 projection hack could be disabled by commenting out this line
210 UpdateActiveConfig();
212 g_VideoInitialize.pWindowHandle = (void*)EmuWindow::Create((HWND)g_VideoInitialize.pWindowHandle, g_hInstance, _T("Loading - Please wait."));
213 if (g_VideoInitialize.pWindowHandle == NULL)
215 ERROR_LOG(VIDEO, "An error has occurred while trying to create the window.");
216 return;
218 else if (FAILED(D3D::Init()))
220 MessageBox(GetActiveWindow(), _T("Unable to initialize Direct3D. Please make sure that you have the latest version of DirectX 9.0c correctly installed."), _T("Fatal Error"), MB_ICONERROR|MB_OK);
221 return;
224 g_VideoInitialize.pPeekMessages = &Callback_PeekMessages;
225 g_VideoInitialize.pUpdateFPSDisplay = &UpdateFPSDisplay;
227 _pVideoInitialize->pPeekMessages = g_VideoInitialize.pPeekMessages;
228 _pVideoInitialize->pUpdateFPSDisplay = g_VideoInitialize.pUpdateFPSDisplay;
229 _pVideoInitialize->pWindowHandle = g_VideoInitialize.pWindowHandle;
231 OSD::AddMessage("Dolphin Direct3D9 Video Plugin.", 5000);
232 s_PluginInitialized = true;
235 void Video_Prepare()
237 // Better be safe...
238 s_efbAccessRequested = FALSE;
239 s_FifoShuttingDown = FALSE;
240 s_swapRequested = FALSE;
241 Renderer::Init();
242 TextureCache::Init();
243 BPInit();
244 VertexManager::Init();
245 Fifo_Init();
246 VertexLoaderManager::Init();
247 OpcodeDecoder_Init();
248 VertexShaderManager::Init();
249 PixelShaderManager::Init();
250 CommandProcessor::Init();
251 PixelEngine::Init();
253 // Tell the host the window is ready
254 g_VideoInitialize.pCoreMessage(WM_USER_CREATE);
257 void Shutdown()
259 s_efbAccessRequested = FALSE;
260 s_FifoShuttingDown = FALSE;
261 s_swapRequested = FALSE;
262 Fifo_Shutdown();
263 CommandProcessor::Shutdown();
264 VertexManager::Shutdown();
265 VertexLoaderManager::Shutdown();
266 VertexShaderManager::Shutdown();
267 PixelShaderManager::Shutdown();
268 TextureCache::Shutdown();
269 OpcodeDecoder_Shutdown();
270 Renderer::Shutdown();
271 D3D::Shutdown();
272 EmuWindow::Close();
273 s_PluginInitialized = false;
276 void DoState(unsigned char **ptr, int mode) {
277 // Clear texture cache because it might have written to RAM
278 CommandProcessor::FifoCriticalEnter();
279 TextureCache::Invalidate(false);
280 CommandProcessor::FifoCriticalLeave();
281 // No need to clear shader caches.
282 PointerWrap p(ptr, mode);
283 VideoCommon_DoState(p);
286 void EmuStateChange(PLUGIN_EMUSTATE newState)
288 Fifo_RunLoop((newState == PLUGIN_EMUSTATE_PLAY) ? true : false);
291 void Video_EnterLoop()
293 Fifo_EnterLoop(g_VideoInitialize);
296 void Video_ExitLoop()
298 Fifo_ExitLoop();
300 s_FifoShuttingDown = TRUE;
303 void Video_SetRendering(bool bEnabled) {
304 Fifo_SetRendering(bEnabled);
307 // Run from the graphics thread (from Fifo.cpp)
308 void VideoFifo_CheckSwapRequest()
310 if(g_ActiveConfig.bUseXFB)
312 if (Common::AtomicLoadAcquire(s_swapRequested))
314 EFBRectangle rc;
315 Renderer::Swap(s_beginFieldArgs.xfbAddr, s_beginFieldArgs.field, s_beginFieldArgs.fbWidth, s_beginFieldArgs.fbHeight,rc);
316 Common::AtomicStoreRelease(s_swapRequested, FALSE);
321 inline bool addrRangesOverlap(u32 aLower, u32 aUpper, u32 bLower, u32 bUpper)
323 return !((aLower >= bUpper) || (bLower >= aUpper));
326 // Run from the graphics thread (from Fifo.cpp)
327 void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight)
329 if (g_ActiveConfig.bUseXFB)
331 if(Common::AtomicLoadAcquire(s_swapRequested))
333 u32 aLower = xfbAddr;
334 u32 aUpper = xfbAddr + 2 * fbWidth * fbHeight;
335 u32 bLower = s_beginFieldArgs.xfbAddr;
336 u32 bUpper = s_beginFieldArgs.xfbAddr + 2 * s_beginFieldArgs.fbWidth * s_beginFieldArgs.fbHeight;
338 if (addrRangesOverlap(aLower, aUpper, bLower, bUpper))
339 VideoFifo_CheckSwapRequest();
344 // Run from the CPU thread (from VideoInterface.cpp)
345 void Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight)
347 if (s_PluginInitialized && g_ActiveConfig.bUseXFB)
349 if (g_VideoInitialize.bOnThread)
351 while (Common::AtomicLoadAcquire(s_swapRequested) && !s_FifoShuttingDown)
352 //Common::SleepCurrentThread(1);
353 Common::YieldCPU();
355 else
356 VideoFifo_CheckSwapRequest();
357 s_beginFieldArgs.xfbAddr = xfbAddr;
358 s_beginFieldArgs.field = field;
359 s_beginFieldArgs.fbWidth = fbWidth;
360 s_beginFieldArgs.fbHeight = fbHeight;
362 Common::AtomicStoreRelease(s_swapRequested, TRUE);
366 void Video_EndField()
370 void Video_AddMessage(const char* pstr, u32 milliseconds)
372 OSD::AddMessage(pstr,milliseconds);
375 HRESULT ScreenShot(const char *File)
377 Renderer::SetScreenshot(File);
378 return S_OK;
381 void Video_Screenshot(const char *_szFilename)
383 if (ScreenShot(_szFilename) != S_OK)
384 PanicAlert("Error while capturing screen");
385 else {
386 std::string message = "Saved ";
387 message += _szFilename;
388 OSD::AddMessage(message.c_str(), 2000);
392 static struct
394 EFBAccessType type;
395 u32 x;
396 u32 y;
397 u32 Data;
398 } s_accessEFBArgs;
400 static u32 s_AccessEFBResult = 0;
402 void VideoFifo_CheckEFBAccess()
404 if (Common::AtomicLoadAcquire(s_efbAccessRequested))
406 s_AccessEFBResult = Renderer::AccessEFB(s_accessEFBArgs.type, s_accessEFBArgs.x, s_accessEFBArgs.y);
408 Common::AtomicStoreRelease(s_efbAccessRequested, FALSE);
412 u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y,u32 InputData)
414 if (s_PluginInitialized)
416 s_accessEFBArgs.type = type;
417 s_accessEFBArgs.x = x;
418 s_accessEFBArgs.y = y;
419 s_accessEFBArgs.Data = InputData;
421 Common::AtomicStoreRelease(s_efbAccessRequested, TRUE);
423 if (g_VideoInitialize.bOnThread)
425 while (Common::AtomicLoadAcquire(s_efbAccessRequested) && !s_FifoShuttingDown)
426 //Common::SleepCurrentThread(1);
427 Common::YieldCPU();
429 else
430 VideoFifo_CheckEFBAccess();
432 return s_AccessEFBResult;
435 return 0;
439 void Video_CommandProcessorRead16(u16& _rReturnValue, const u32 _Address)
441 CommandProcessor::Read16(_rReturnValue, _Address);
444 void Video_CommandProcessorWrite16(const u16 _Data, const u32 _Address)
446 CommandProcessor::Write16(_Data, _Address);
449 void Video_PixelEngineRead16(u16& _rReturnValue, const u32 _Address)
451 PixelEngine::Read16(_rReturnValue, _Address);
454 void Video_PixelEngineWrite16(const u16 _Data, const u32 _Address)
456 PixelEngine::Write16(_Data, _Address);
459 void Video_PixelEngineWrite32(const u32 _Data, const u32 _Address)
461 PixelEngine::Write32(_Data, _Address);
464 inline void Video_GatherPipeBursted(void)
466 CommandProcessor::GatherPipeBursted();
469 void Video_WaitForFrameFinish(void)
471 CommandProcessor::WaitForFrameFinish();
474 bool Video_IsFifoBusy(void)
476 return CommandProcessor::isFifoBusy;