If the DSP LLE can not find the needed ROM files exit the emulator without crashing the application. Also reimplement soren's revision 7195 in a way that works on linux and windows. (This makes it easier to clean up the video backend if the DSP emulator fails to initialize.)
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7271 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
6073600084
commit
3af93e8cf3
|
@ -203,8 +203,6 @@ bool Init()
|
||||||
Host_SetWaitCursor(true);
|
Host_SetWaitCursor(true);
|
||||||
Host_UpdateMainFrame(); // Disable any menus or buttons at boot
|
Host_UpdateMainFrame(); // Disable any menus or buttons at boot
|
||||||
|
|
||||||
emuThreadGoing.Init();
|
|
||||||
|
|
||||||
g_aspect_wide = _CoreParameter.bWii;
|
g_aspect_wide = _CoreParameter.bWii;
|
||||||
if (g_aspect_wide)
|
if (g_aspect_wide)
|
||||||
{
|
{
|
||||||
|
@ -221,14 +219,19 @@ bool Init()
|
||||||
g_pWindowHandle = Host_GetRenderHandle();
|
g_pWindowHandle = Host_GetRenderHandle();
|
||||||
if (!g_video_backend->Initialize(g_pWindowHandle))
|
if (!g_video_backend->Initialize(g_pWindowHandle))
|
||||||
{
|
{
|
||||||
emuThreadGoing.Shutdown();
|
|
||||||
Host_SetWaitCursor(false);
|
Host_SetWaitCursor(false);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
HW::Init();
|
HW::Init();
|
||||||
DSP::GetDSPEmulator()->Initialize(g_pWindowHandle,
|
if (!DSP::GetDSPEmulator()->Initialize(g_pWindowHandle,
|
||||||
_CoreParameter.bWii, _CoreParameter.bDSPThread);
|
_CoreParameter.bWii, _CoreParameter.bDSPThread))
|
||||||
|
{
|
||||||
|
HW::Shutdown();
|
||||||
|
g_video_backend->Shutdown();
|
||||||
|
Host_SetWaitCursor(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
Pad::Initialize(g_pWindowHandle);
|
Pad::Initialize(g_pWindowHandle);
|
||||||
// Load and Init Wiimotes - only if we are booting in wii mode
|
// Load and Init Wiimotes - only if we are booting in wii mode
|
||||||
if (g_CoreStartupParameter.bWii)
|
if (g_CoreStartupParameter.bWii)
|
||||||
|
@ -245,6 +248,8 @@ bool Init()
|
||||||
// The hardware is initialized.
|
// The hardware is initialized.
|
||||||
g_bHwInit = true;
|
g_bHwInit = true;
|
||||||
|
|
||||||
|
emuThreadGoing.Init();
|
||||||
|
|
||||||
// Start the emu thread
|
// Start the emu thread
|
||||||
g_EmuThread = std::thread(EmuThread);
|
g_EmuThread = std::thread(EmuThread);
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ static bool LoadRom(const char *fname, int size_in_words, u16 *rom)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
PanicAlertT("Failed to load DSP ROM: %s", fname);
|
PanicAlertT("Failed to load DSP ROM:\n%s\nThis file is required to use DSP LLE", fname);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,6 +87,14 @@ static bool VerifyRoms(const char *irom_filename, const char *coef_filename)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void DSPCore_FreeMemoryPages()
|
||||||
|
{
|
||||||
|
FreeMemoryPages(g_dsp.irom, DSP_IROM_BYTE_SIZE);
|
||||||
|
FreeMemoryPages(g_dsp.iram, DSP_IRAM_BYTE_SIZE);
|
||||||
|
FreeMemoryPages(g_dsp.dram, DSP_DRAM_BYTE_SIZE);
|
||||||
|
FreeMemoryPages(g_dsp.coef, DSP_COEF_BYTE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
bool DSPCore_Init(const char *irom_filename, const char *coef_filename,
|
bool DSPCore_Init(const char *irom_filename, const char *coef_filename,
|
||||||
bool bUsingJIT)
|
bool bUsingJIT)
|
||||||
{
|
{
|
||||||
|
@ -104,10 +112,13 @@ bool DSPCore_Init(const char *irom_filename, const char *coef_filename,
|
||||||
memset(g_dsp.coef, 0, DSP_COEF_BYTE_SIZE);
|
memset(g_dsp.coef, 0, DSP_COEF_BYTE_SIZE);
|
||||||
|
|
||||||
// Try to load real ROM contents.
|
// Try to load real ROM contents.
|
||||||
LoadRom(irom_filename, DSP_IROM_SIZE, g_dsp.irom);
|
if (!LoadRom(irom_filename, DSP_IROM_SIZE, g_dsp.irom) ||
|
||||||
LoadRom(coef_filename, DSP_COEF_SIZE, g_dsp.coef);
|
!LoadRom(coef_filename, DSP_COEF_SIZE, g_dsp.coef) ||
|
||||||
if (!VerifyRoms(irom_filename, coef_filename))
|
!VerifyRoms(irom_filename, coef_filename))
|
||||||
|
{
|
||||||
|
DSPCore_FreeMemoryPages();
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
memset(&g_dsp.r,0,sizeof(g_dsp.r));
|
memset(&g_dsp.r,0,sizeof(g_dsp.r));
|
||||||
|
|
||||||
|
@ -163,6 +174,9 @@ bool DSPCore_Init(const char *irom_filename, const char *coef_filename,
|
||||||
|
|
||||||
void DSPCore_Shutdown()
|
void DSPCore_Shutdown()
|
||||||
{
|
{
|
||||||
|
if (core_state == DSPCORE_STOP)
|
||||||
|
return;
|
||||||
|
|
||||||
core_state = DSPCORE_STOP;
|
core_state = DSPCORE_STOP;
|
||||||
|
|
||||||
if(dspjit) {
|
if(dspjit) {
|
||||||
|
@ -170,10 +184,7 @@ void DSPCore_Shutdown()
|
||||||
dspjit = NULL;
|
dspjit = NULL;
|
||||||
}
|
}
|
||||||
step_event.Shutdown();
|
step_event.Shutdown();
|
||||||
FreeMemoryPages(g_dsp.irom, DSP_IROM_BYTE_SIZE);
|
DSPCore_FreeMemoryPages();
|
||||||
FreeMemoryPages(g_dsp.iram, DSP_IRAM_BYTE_SIZE);
|
|
||||||
FreeMemoryPages(g_dsp.dram, DSP_DRAM_BYTE_SIZE);
|
|
||||||
FreeMemoryPages(g_dsp.coef, DSP_COEF_BYTE_SIZE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSPCore_Reset()
|
void DSPCore_Reset()
|
||||||
|
|
|
@ -28,7 +28,7 @@ public:
|
||||||
|
|
||||||
virtual bool IsLLE() = 0;
|
virtual bool IsLLE() = 0;
|
||||||
|
|
||||||
virtual void Initialize(void *hWnd, bool bWii, bool bDSPThread) = 0;
|
virtual bool Initialize(void *hWnd, bool bWii, bool bDSPThread) = 0;
|
||||||
virtual void Shutdown() = 0;
|
virtual void Shutdown() = 0;
|
||||||
|
|
||||||
virtual void DoState(PointerWrap &p) = 0;
|
virtual void DoState(PointerWrap &p) = 0;
|
||||||
|
|
|
@ -50,7 +50,7 @@ struct DSPState
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void DSPHLE::Initialize(void *hWnd, bool bWii, bool bDSPThread)
|
bool DSPHLE::Initialize(void *hWnd, bool bWii, bool bDSPThread)
|
||||||
{
|
{
|
||||||
m_hWnd = hWnd;
|
m_hWnd = hWnd;
|
||||||
m_bWii = bWii;
|
m_bWii = bWii;
|
||||||
|
@ -65,6 +65,8 @@ void DSPHLE::Initialize(void *hWnd, bool bWii, bool bDSPThread)
|
||||||
|
|
||||||
m_InitMixer = false;
|
m_InitMixer = false;
|
||||||
m_dspState.Reset();
|
m_dspState.Reset();
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSPHLE::DSP_StopSoundStream()
|
void DSPHLE::DSP_StopSoundStream()
|
||||||
|
|
|
@ -29,7 +29,7 @@ class DSPHLE : public DSPEmulator {
|
||||||
public:
|
public:
|
||||||
DSPHLE();
|
DSPHLE();
|
||||||
|
|
||||||
virtual void Initialize(void *hWnd, bool bWii, bool bDSPThread);
|
virtual bool Initialize(void *hWnd, bool bWii, bool bDSPThread);
|
||||||
virtual void Shutdown();
|
virtual void Shutdown();
|
||||||
virtual bool IsLLE() { return false; }
|
virtual bool IsLLE() { return false; }
|
||||||
|
|
||||||
|
|
|
@ -99,33 +99,26 @@ void DSPLLE::dsp_thread(DSPLLE *lpParameter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSPLLE::Initialize(void *hWnd, bool bWii, bool bDSPThread)
|
bool DSPLLE::Initialize(void *hWnd, bool bWii, bool bDSPThread)
|
||||||
{
|
{
|
||||||
m_hWnd = hWnd;
|
m_hWnd = hWnd;
|
||||||
m_bWii = bWii;
|
m_bWii = bWii;
|
||||||
m_bDSPThread = bDSPThread;
|
m_bDSPThread = bDSPThread;
|
||||||
m_InitMixer = false;
|
m_InitMixer = false;
|
||||||
bool bCanWork = true;
|
|
||||||
std::string irom_file = File::GetSysDirectory() + GC_SYS_DIR DIR_SEP DSP_IROM;
|
std::string irom_file = File::GetSysDirectory() + GC_SYS_DIR DIR_SEP DSP_IROM;
|
||||||
std::string coef_file = File::GetSysDirectory() + GC_SYS_DIR DIR_SEP DSP_COEF;
|
std::string coef_file = File::GetSysDirectory() + GC_SYS_DIR DIR_SEP DSP_COEF;
|
||||||
|
|
||||||
if (!File::Exists(irom_file))
|
if (!File::Exists(irom_file))
|
||||||
irom_file = File::GetUserPath(D_GCUSER_IDX) + DIR_SEP DSP_IROM;
|
irom_file = File::GetUserPath(D_GCUSER_IDX) + DSP_IROM;
|
||||||
if (!File::Exists(coef_file))
|
if (!File::Exists(coef_file))
|
||||||
coef_file = File::GetUserPath(D_GCUSER_IDX) + DIR_SEP DSP_COEF;
|
coef_file = File::GetUserPath(D_GCUSER_IDX) + DSP_COEF;
|
||||||
bCanWork = DSPCore_Init(irom_file.c_str(), coef_file.c_str(), AudioCommon::UseJIT());
|
if (!DSPCore_Init(irom_file.c_str(), coef_file.c_str(), AudioCommon::UseJIT()))
|
||||||
|
return false;
|
||||||
|
|
||||||
g_dsp.cpu_ram = Memory::GetPointer(0);
|
g_dsp.cpu_ram = Memory::GetPointer(0);
|
||||||
DSPCore_Reset();
|
DSPCore_Reset();
|
||||||
|
|
||||||
if (!bCanWork)
|
|
||||||
{
|
|
||||||
DSPCore_Shutdown();
|
|
||||||
// No way to shutdown Core from here? Hardcore shutdown!
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_bIsRunning = true;
|
m_bIsRunning = true;
|
||||||
|
|
||||||
InitInstructionTable();
|
InitInstructionTable();
|
||||||
|
@ -134,6 +127,8 @@ void DSPLLE::Initialize(void *hWnd, bool bWii, bool bDSPThread)
|
||||||
m_hDSPThread = std::thread(dsp_thread, this);
|
m_hDSPThread = std::thread(dsp_thread, this);
|
||||||
|
|
||||||
Host_RefreshDSPDebuggerWindow();
|
Host_RefreshDSPDebuggerWindow();
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSPLLE::DSP_StopSoundStream()
|
void DSPLLE::DSP_StopSoundStream()
|
||||||
|
|
|
@ -27,7 +27,7 @@ class DSPLLE : public DSPEmulator {
|
||||||
public:
|
public:
|
||||||
DSPLLE();
|
DSPLLE();
|
||||||
|
|
||||||
virtual void Initialize(void *hWnd, bool bWii, bool bDSPThread);
|
virtual bool Initialize(void *hWnd, bool bWii, bool bDSPThread);
|
||||||
virtual void Shutdown();
|
virtual void Shutdown();
|
||||||
virtual bool IsLLE() { return true; }
|
virtual bool IsLLE() { return true; }
|
||||||
|
|
||||||
|
|
|
@ -174,11 +174,6 @@ bool VideoBackend::Initialize(void *&window_handle)
|
||||||
OSD::AddMessage("Dolphin Direct3D11 Video Backend.", 5000);
|
OSD::AddMessage("Dolphin Direct3D11 Video Backend.", 5000);
|
||||||
s_BackendInitialized = true;
|
s_BackendInitialized = true;
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VideoBackend::Video_Prepare()
|
|
||||||
{
|
|
||||||
// Better be safe...
|
// Better be safe...
|
||||||
s_efbAccessRequested = FALSE;
|
s_efbAccessRequested = FALSE;
|
||||||
s_FifoShuttingDown = FALSE;
|
s_FifoShuttingDown = FALSE;
|
||||||
|
@ -203,6 +198,11 @@ void VideoBackend::Video_Prepare()
|
||||||
PixelEngine::Init();
|
PixelEngine::Init();
|
||||||
DLCache::Init();
|
DLCache::Init();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VideoBackend::Video_Prepare()
|
||||||
|
{
|
||||||
// Tell the host that the window is ready
|
// Tell the host that the window is ready
|
||||||
Core::Callback_CoreMessage(WM_USER_CREATE);
|
Core::Callback_CoreMessage(WM_USER_CREATE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,11 +159,6 @@ bool VideoBackend::Initialize(void *&window_handle)
|
||||||
OSD::AddMessage("Dolphin Direct3D9 Video Backend.", 5000);
|
OSD::AddMessage("Dolphin Direct3D9 Video Backend.", 5000);
|
||||||
s_BackendInitialized = true;
|
s_BackendInitialized = true;
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VideoBackend::Video_Prepare()
|
|
||||||
{
|
|
||||||
// Better be safe...
|
// Better be safe...
|
||||||
s_efbAccessRequested = FALSE;
|
s_efbAccessRequested = FALSE;
|
||||||
s_FifoShuttingDown = FALSE;
|
s_FifoShuttingDown = FALSE;
|
||||||
|
@ -184,6 +179,11 @@ void VideoBackend::Video_Prepare()
|
||||||
PixelEngine::Init();
|
PixelEngine::Init();
|
||||||
DLCache::Init();
|
DLCache::Init();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VideoBackend::Video_Prepare()
|
||||||
|
{
|
||||||
// Notify the core that the video backend is ready
|
// Notify the core that the video backend is ready
|
||||||
Core::Callback_CoreMessage(WM_USER_CREATE);
|
Core::Callback_CoreMessage(WM_USER_CREATE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,16 +117,10 @@ void VideoBackend::UpdateFPSDisplay(const char *text)
|
||||||
#if defined(HAVE_X11) && HAVE_X11
|
#if defined(HAVE_X11) && HAVE_X11
|
||||||
void XEventThread();
|
void XEventThread();
|
||||||
|
|
||||||
void CreateXWindow (void)
|
void CreateXWindow(void)
|
||||||
{
|
{
|
||||||
Atom wmProtocols[1];
|
Atom wmProtocols[1];
|
||||||
|
|
||||||
// use evdpy to create the window, so that connection gets the events
|
|
||||||
// the colormap needs to be created on the same display, because it
|
|
||||||
// is a client side structure, as well as wmProtocols(or so it seems)
|
|
||||||
// GLWin.win is a xserver global window handle, so it can be used by both
|
|
||||||
// display connections
|
|
||||||
|
|
||||||
// Setup window attributes
|
// Setup window attributes
|
||||||
GLWin.attr.colormap = XCreateColormap(GLWin.evdpy,
|
GLWin.attr.colormap = XCreateColormap(GLWin.evdpy,
|
||||||
GLWin.parent, GLWin.vi->visual, AllocNone);
|
GLWin.parent, GLWin.vi->visual, AllocNone);
|
||||||
|
@ -136,7 +130,8 @@ void CreateXWindow (void)
|
||||||
|
|
||||||
// Create the window
|
// Create the window
|
||||||
GLWin.win = XCreateWindow(GLWin.evdpy, GLWin.parent,
|
GLWin.win = XCreateWindow(GLWin.evdpy, GLWin.parent,
|
||||||
GLWin.x, GLWin.y, GLWin.width, GLWin.height, 0, GLWin.vi->depth, InputOutput, GLWin.vi->visual,
|
GLWin.x, GLWin.y, GLWin.width, GLWin.height, 0,
|
||||||
|
GLWin.vi->depth, InputOutput, GLWin.vi->visual,
|
||||||
CWBorderPixel | CWBackPixel | CWColormap | CWEventMask, &GLWin.attr);
|
CWBorderPixel | CWBackPixel | CWColormap | CWEventMask, &GLWin.attr);
|
||||||
wmProtocols[0] = XInternAtom(GLWin.evdpy, "WM_DELETE_WINDOW", True);
|
wmProtocols[0] = XInternAtom(GLWin.evdpy, "WM_DELETE_WINDOW", True);
|
||||||
XSetWMProtocols(GLWin.evdpy, GLWin.win, wmProtocols, 1);
|
XSetWMProtocols(GLWin.evdpy, GLWin.win, wmProtocols, 1);
|
||||||
|
@ -151,7 +146,8 @@ void DestroyXWindow(void)
|
||||||
{
|
{
|
||||||
XUnmapWindow(GLWin.dpy, GLWin.win);
|
XUnmapWindow(GLWin.dpy, GLWin.win);
|
||||||
GLWin.win = 0;
|
GLWin.win = 0;
|
||||||
GLWin.xEventThread.join();
|
if (GLWin.xEventThread.joinable())
|
||||||
|
GLWin.xEventThread.join();
|
||||||
XFreeColormap(GLWin.evdpy, GLWin.attr.colormap);
|
XFreeColormap(GLWin.evdpy, GLWin.attr.colormap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,11 +294,14 @@ void XEventThread()
|
||||||
s_backbuffer_height = GLWin.height;
|
s_backbuffer_height = GLWin.height;
|
||||||
break;
|
break;
|
||||||
case ClientMessage:
|
case ClientMessage:
|
||||||
if ((unsigned long) event.xclient.data.l[0] == XInternAtom(GLWin.evdpy, "WM_DELETE_WINDOW", False))
|
if ((unsigned long) event.xclient.data.l[0] ==
|
||||||
|
XInternAtom(GLWin.evdpy, "WM_DELETE_WINDOW", False))
|
||||||
Core::Callback_CoreMessage(WM_USER_STOP);
|
Core::Callback_CoreMessage(WM_USER_STOP);
|
||||||
if ((unsigned long) event.xclient.data.l[0] == XInternAtom(GLWin.evdpy, "RESIZE", False))
|
if ((unsigned long) event.xclient.data.l[0] ==
|
||||||
XMoveResizeWindow(GLWin.evdpy, GLWin.win, event.xclient.data.l[1],
|
XInternAtom(GLWin.evdpy, "RESIZE", False))
|
||||||
event.xclient.data.l[2], event.xclient.data.l[3], event.xclient.data.l[4]);
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -385,26 +384,26 @@ bool OpenGL_Create(void *&window_handle)
|
||||||
// Show the window
|
// Show the window
|
||||||
EmuWindow::Show();
|
EmuWindow::Show();
|
||||||
|
|
||||||
PIXELFORMATDESCRIPTOR pfd = // pfd Tells Windows How We Want Things To Be
|
PIXELFORMATDESCRIPTOR pfd = // pfd Tells Windows How We Want Things To Be
|
||||||
{
|
{
|
||||||
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
|
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
|
||||||
1, // Version Number
|
1, // Version Number
|
||||||
PFD_DRAW_TO_WINDOW | // Format Must Support Window
|
PFD_DRAW_TO_WINDOW | // Format Must Support Window
|
||||||
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
|
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
|
||||||
PFD_DOUBLEBUFFER, // Must Support Double Buffering
|
PFD_DOUBLEBUFFER, // Must Support Double Buffering
|
||||||
PFD_TYPE_RGBA, // Request An RGBA Format
|
PFD_TYPE_RGBA, // Request An RGBA Format
|
||||||
32, // Select Our Color Depth
|
32, // Select Our Color Depth
|
||||||
0, 0, 0, 0, 0, 0, // Color Bits Ignored
|
0, 0, 0, 0, 0, 0, // Color Bits Ignored
|
||||||
0, // 8bit Alpha Buffer
|
0, // 8bit Alpha Buffer
|
||||||
0, // Shift Bit Ignored
|
0, // Shift Bit Ignored
|
||||||
0, // No Accumulation Buffer
|
0, // No Accumulation Buffer
|
||||||
0, 0, 0, 0, // Accumulation Bits Ignored
|
0, 0, 0, 0, // Accumulation Bits Ignored
|
||||||
24, // 24Bit Z-Buffer (Depth Buffer)
|
24, // 24Bit Z-Buffer (Depth Buffer)
|
||||||
8, // 8bit Stencil Buffer
|
8, // 8bit Stencil Buffer
|
||||||
0, // No Auxiliary Buffer
|
0, // No Auxiliary Buffer
|
||||||
PFD_MAIN_PLANE, // Main Drawing Layer
|
PFD_MAIN_PLANE, // Main Drawing Layer
|
||||||
0, // Reserved
|
0, // Reserved
|
||||||
0, 0, 0 // Layer Masks Ignored
|
0, 0, 0 // Layer Masks Ignored
|
||||||
};
|
};
|
||||||
|
|
||||||
GLuint PixelFormat; // Holds The Results After Searching For A Match
|
GLuint PixelFormat; // Holds The Results After Searching For A Match
|
||||||
|
@ -413,7 +412,7 @@ bool OpenGL_Create(void *&window_handle)
|
||||||
PanicAlert("(1) Can't create an OpenGL Device context. Fail.");
|
PanicAlert("(1) Can't create an OpenGL Device context. Fail.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!(PixelFormat = ChoosePixelFormat(hDC,&pfd))) {
|
if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd))) {
|
||||||
PanicAlert("(2) Can't find a suitable PixelFormat.");
|
PanicAlert("(2) Can't find a suitable PixelFormat.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -475,7 +474,7 @@ bool OpenGL_Create(void *&window_handle)
|
||||||
GLWin.vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListSgl);
|
GLWin.vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListSgl);
|
||||||
if (GLWin.vi != NULL)
|
if (GLWin.vi != NULL)
|
||||||
{
|
{
|
||||||
ERROR_LOG(VIDEO, "Only Singlebuffered Visual!");
|
ERROR_LOG(VIDEO, "Only single buffered visual!");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -488,13 +487,13 @@ bool OpenGL_Create(void *&window_handle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
NOTICE_LOG(VIDEO, "Got Doublebuffered Visual!");
|
NOTICE_LOG(VIDEO, "Got double buffered visual!");
|
||||||
|
|
||||||
// Create a GLX context.
|
// Create a GLX context.
|
||||||
GLWin.ctx = glXCreateContext(GLWin.dpy, GLWin.vi, 0, GL_TRUE);
|
GLWin.ctx = glXCreateContext(GLWin.dpy, GLWin.vi, 0, GL_TRUE);
|
||||||
if (!GLWin.ctx)
|
if (!GLWin.ctx)
|
||||||
{
|
{
|
||||||
PanicAlert("Couldn't Create GLX context.Quit");
|
PanicAlert("Unable to create GLX context.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,17 +516,28 @@ bool OpenGL_MakeCurrent()
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
[GLWin.cocoaCtx makeCurrentContext];
|
[GLWin.cocoaCtx makeCurrentContext];
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
return wglMakeCurrent(hDC,hRC) ? true : false;
|
return wglMakeCurrent(hDC, hRC) ? true : false;
|
||||||
#elif defined(HAVE_X11) && HAVE_X11
|
#elif defined(HAVE_X11) && HAVE_X11
|
||||||
#if defined(HAVE_WX) && (HAVE_WX)
|
#if defined(HAVE_WX) && (HAVE_WX)
|
||||||
Core::Callback_VideoGetWindowSize(GLWin.x, GLWin.y, (int&)GLWin.width, (int&)GLWin.height);
|
Core::Callback_VideoGetWindowSize(GLWin.x, GLWin.y,
|
||||||
XMoveResizeWindow(GLWin.dpy, GLWin.win, GLWin.x, GLWin.y, GLWin.width, GLWin.height);
|
(int&)GLWin.width, (int&)GLWin.height);
|
||||||
|
XMoveResizeWindow(GLWin.dpy, GLWin.win, GLWin.x, GLWin.y,
|
||||||
|
GLWin.width, GLWin.height);
|
||||||
#endif
|
#endif
|
||||||
return glXMakeCurrent(GLWin.dpy, GLWin.win, GLWin.ctx);
|
return glXMakeCurrent(GLWin.dpy, GLWin.win, GLWin.ctx);
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OpenGL_ReleaseContext()
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
return wglMakeCurrent(NULL, NULL);
|
||||||
|
#elif defined(HAVE_X11) && HAVE_X11
|
||||||
|
return glXMakeCurrent(GLWin.dpy, None, NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// Update window width, size and etc. Called from Render.cpp
|
// Update window width, size and etc. Called from Render.cpp
|
||||||
void OpenGL_Update()
|
void OpenGL_Update()
|
||||||
{
|
{
|
||||||
|
@ -577,7 +587,9 @@ void OpenGL_Update()
|
||||||
int height = rcWindow.bottom - rcWindow.top;
|
int height = rcWindow.bottom - rcWindow.top;
|
||||||
|
|
||||||
// If we are rendering to a child window
|
// If we are rendering to a child window
|
||||||
if (EmuWindow::GetParentWnd() != 0 && (s_backbuffer_width != width || s_backbuffer_height != height) && width >= 4 && height >= 4)
|
if (EmuWindow::GetParentWnd() != 0 &&
|
||||||
|
(s_backbuffer_width != width || s_backbuffer_height != height) &&
|
||||||
|
width >= 4 && height >= 4)
|
||||||
{
|
{
|
||||||
::MoveWindow(EmuWindow::GetWnd(), 0, 0, width, height, FALSE);
|
::MoveWindow(EmuWindow::GetWnd(), 0, 0, width, height, FALSE);
|
||||||
s_backbuffer_width = width;
|
s_backbuffer_width = width;
|
||||||
|
@ -586,7 +598,6 @@ void OpenGL_Update()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Close backend
|
// Close backend
|
||||||
void OpenGL_Shutdown()
|
void OpenGL_Shutdown()
|
||||||
{
|
{
|
||||||
|
@ -599,27 +610,21 @@ void OpenGL_Shutdown()
|
||||||
[GLWin.cocoaCtx clearDrawable];
|
[GLWin.cocoaCtx clearDrawable];
|
||||||
[GLWin.cocoaCtx release];
|
[GLWin.cocoaCtx release];
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
if (hRC) // Do We Have A Rendering Context?
|
if (hRC)
|
||||||
{
|
{
|
||||||
if (!wglMakeCurrent(NULL,NULL)) // Are We Able To Release The DC And RC Contexts?
|
if (!wglMakeCurrent(NULL, NULL))
|
||||||
{
|
NOTICE_LOG(VIDEO, "Could not release drawing context.");
|
||||||
// [F|RES]: if this fails i dont see the message box and
|
|
||||||
// cant get out of the modal state so i disable it.
|
|
||||||
// This function fails only if i render to main window
|
|
||||||
// MessageBox(NULL,"Release Of DC And RC Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!wglDeleteContext(hRC)) // Are We Able To Delete The RC?
|
if (!wglDeleteContext(hRC))
|
||||||
{
|
|
||||||
ERROR_LOG(VIDEO, "Release Rendering Context Failed.");
|
ERROR_LOG(VIDEO, "Release Rendering Context Failed.");
|
||||||
}
|
|
||||||
hRC = NULL; // Set RC To NULL
|
hRC = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hDC && !ReleaseDC(EmuWindow::GetWnd(), hDC)) // Are We Able To Release The DC
|
if (hDC && !ReleaseDC(EmuWindow::GetWnd(), hDC))
|
||||||
{
|
{
|
||||||
ERROR_LOG(VIDEO, "Release Device Context Failed.");
|
ERROR_LOG(VIDEO, "Release Device Context Failed.");
|
||||||
hDC = NULL; // Set DC To NULL
|
hDC = NULL;
|
||||||
}
|
}
|
||||||
EmuWindow::Close();
|
EmuWindow::Close();
|
||||||
#elif defined(HAVE_X11) && HAVE_X11
|
#elif defined(HAVE_X11) && HAVE_X11
|
||||||
|
@ -641,7 +646,8 @@ GLuint OpenGL_ReportGLError(const char *function, const char *file, int line)
|
||||||
GLint err = glGetError();
|
GLint err = glGetError();
|
||||||
if (err != GL_NO_ERROR)
|
if (err != GL_NO_ERROR)
|
||||||
{
|
{
|
||||||
ERROR_LOG(VIDEO, "%s:%d: (%s) OpenGL error 0x%x - %s\n", file, line, function, err, gluErrorString(err));
|
ERROR_LOG(VIDEO, "%s:%d: (%s) OpenGL error 0x%x - %s\n",
|
||||||
|
file, line, function, err, gluErrorString(err));
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -667,15 +673,30 @@ bool OpenGL_ReportFBOError(const char *function, const char *file, int line)
|
||||||
const char *error = "-";
|
const char *error = "-";
|
||||||
switch (fbo_status)
|
switch (fbo_status)
|
||||||
{
|
{
|
||||||
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: error = "INCOMPLETE_ATTACHMENT_EXT"; break;
|
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
|
||||||
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: error = "INCOMPLETE_MISSING_ATTACHMENT_EXT"; break;
|
error = "INCOMPLETE_ATTACHMENT_EXT";
|
||||||
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: error = "INCOMPLETE_DIMENSIONS_EXT"; break;
|
break;
|
||||||
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: error = "INCOMPLETE_FORMATS_EXT"; break;
|
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
|
||||||
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: error = "INCOMPLETE_DRAW_BUFFER_EXT"; break;
|
error = "INCOMPLETE_MISSING_ATTACHMENT_EXT";
|
||||||
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: error = "INCOMPLETE_READ_BUFFER_EXT"; break;
|
break;
|
||||||
case GL_FRAMEBUFFER_UNSUPPORTED_EXT: error = "UNSUPPORTED_EXT"; break;
|
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
|
||||||
|
error = "INCOMPLETE_DIMENSIONS_EXT";
|
||||||
|
break;
|
||||||
|
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
|
||||||
|
error = "INCOMPLETE_FORMATS_EXT";
|
||||||
|
break;
|
||||||
|
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
|
||||||
|
error = "INCOMPLETE_DRAW_BUFFER_EXT";
|
||||||
|
break;
|
||||||
|
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
|
||||||
|
error = "INCOMPLETE_READ_BUFFER_EXT";
|
||||||
|
break;
|
||||||
|
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
|
||||||
|
error = "UNSUPPORTED_EXT";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
ERROR_LOG(VIDEO, "%s:%d: (%s) OpenGL FBO error - %s\n", file, line, function, error);
|
ERROR_LOG(VIDEO, "%s:%d: (%s) OpenGL FBO error - %s\n",
|
||||||
|
file, line, function, error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -64,9 +64,8 @@ typedef struct {
|
||||||
int screen;
|
int screen;
|
||||||
Window win;
|
Window win;
|
||||||
Window parent;
|
Window parent;
|
||||||
// dpy (mainly) used for glx stuff, evdpy for window events etc.
|
// dpy used for glx stuff, evdpy for window events etc.
|
||||||
// used to keep the two threads from eating each others events
|
// evdpy is to be used by XEventThread only
|
||||||
// evdpy is to be used by XEventThread only (when it is running)
|
|
||||||
Display *dpy, *evdpy;
|
Display *dpy, *evdpy;
|
||||||
XVisualInfo *vi;
|
XVisualInfo *vi;
|
||||||
GLXContext ctx;
|
GLXContext ctx;
|
||||||
|
@ -88,6 +87,7 @@ bool OpenGL_Create(void *&);
|
||||||
void OpenGL_Shutdown();
|
void OpenGL_Shutdown();
|
||||||
void OpenGL_Update();
|
void OpenGL_Update();
|
||||||
bool OpenGL_MakeCurrent();
|
bool OpenGL_MakeCurrent();
|
||||||
|
bool OpenGL_ReleaseContext();
|
||||||
void OpenGL_SwapBuffers();
|
void OpenGL_SwapBuffers();
|
||||||
|
|
||||||
// Get status
|
// Get status
|
||||||
|
|
|
@ -176,14 +176,12 @@ bool VideoBackend::Initialize(void *&window_handle)
|
||||||
OSD::AddMessage("Dolphin OpenGL Video Backend.", 5000);
|
OSD::AddMessage("Dolphin OpenGL Video Backend.", 5000);
|
||||||
s_BackendInitialized = true;
|
s_BackendInitialized = true;
|
||||||
|
|
||||||
return true;
|
if (!OpenGL_MakeCurrent())
|
||||||
}
|
{
|
||||||
|
ERROR_LOG(VIDEO, "Unable to connect to OpenGL context.");
|
||||||
// This is called after Initialize() from the Core
|
OpenGL_Shutdown();
|
||||||
// Run from the graphics thread
|
return false;
|
||||||
void VideoBackend::Video_Prepare()
|
}
|
||||||
{
|
|
||||||
OpenGL_MakeCurrent();
|
|
||||||
|
|
||||||
g_renderer = new Renderer;
|
g_renderer = new Renderer;
|
||||||
|
|
||||||
|
@ -210,6 +208,22 @@ void VideoBackend::Video_Prepare()
|
||||||
TextureConverter::Init();
|
TextureConverter::Init();
|
||||||
DLCache::Init();
|
DLCache::Init();
|
||||||
|
|
||||||
|
if (!OpenGL_ReleaseContext())
|
||||||
|
{
|
||||||
|
ERROR_LOG(VIDEO, "Unable to release OpenGL context.");
|
||||||
|
Shutdown();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is called after Initialize() from the Core
|
||||||
|
// Run from the graphics thread
|
||||||
|
void VideoBackend::Video_Prepare()
|
||||||
|
{
|
||||||
|
OpenGL_MakeCurrent();
|
||||||
|
|
||||||
// Notify the core that the video backend is ready
|
// Notify the core that the video backend is ready
|
||||||
Core::Callback_CoreMessage(WM_USER_CREATE);
|
Core::Callback_CoreMessage(WM_USER_CREATE);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue