diff --git a/Core/Host.h b/Core/Host.h index 01573a1e65..747a8037c2 100644 --- a/Core/Host.h +++ b/Core/Host.h @@ -21,7 +21,6 @@ #include #include "../Globals.h" - class PMixer { public: @@ -30,8 +29,6 @@ public: virtual int Mix(short *stereoout, int numSamples) {memset(stereoout,0,numSamples*2*sizeof(short)); return numSamples;} }; - - class Host { public: @@ -44,7 +41,7 @@ public: virtual void SetDebugMode(bool mode) { } - virtual void InitGL() = 0; + virtual bool InitGL(std::string *error_string) = 0; virtual void BeginFrame() {} virtual void ShutdownGL() = 0; diff --git a/Windows/EmuThread.cpp b/Windows/EmuThread.cpp index ed65398786..88c0eb20a4 100644 --- a/Windows/EmuThread.cpp +++ b/Windows/EmuThread.cpp @@ -2,6 +2,7 @@ #include "base/threadutil.h" #include "Log.h" +#include "StringUtil.h" #include "../Globals.h" #include "EmuThread.h" #include "../Core/MemMap.h" @@ -53,18 +54,25 @@ char *GetCurrentFilename() return fileToStart; } -DWORD TheThread(LPVOID x) -{ +DWORD TheThread(LPVOID x) { setCurrentThreadName("EmuThread"); g_State.bEmuThreadStarted = true; + CoreParameter coreParameter; + host->UpdateUI(); - host->InitGL(); + + std::string error_string; + if (!host->InitGL(&error_string)) { + std::string full_error = StringFromFormat( "Failed initializing OpenGL. Try upgrading your graphics drivers.\n\nError message:\n\n%s", error_string.c_str()); + MessageBoxA(0, full_error.c_str(), "OpenGL Error", MB_OK | MB_ICONERROR); + ERROR_LOG(BOOT, full_error.c_str()); + goto shutdown; + } INFO_LOG(BOOT, "Starting up hardware."); - CoreParameter coreParameter; coreParameter.fileToStart = fileToStart; coreParameter.enableSound = true; coreParameter.gpuCore = GPU_GLES; @@ -81,7 +89,7 @@ DWORD TheThread(LPVOID x) coreParameter.startPaused = !g_Config.bAutoRun; coreParameter.useMediaEngine = false; - std::string error_string; + error_string = ""; if (!PSP_Init(coreParameter, &error_string)) { ERROR_LOG(BOOT, "Error loading: %s", error_string.c_str()); diff --git a/Windows/OpenGLBase.cpp b/Windows/OpenGLBase.cpp index 92d4af4c14..a1e5fdf62b 100644 --- a/Windows/OpenGLBase.cpp +++ b/Windows/OpenGLBase.cpp @@ -30,37 +30,32 @@ void setVSync(int interval=1) wglSwapIntervalEXT(interval); } -void GL_Resized() // Resize And Initialize The GL Window -{ +// Resize And Initialize The GL Window +void GL_Resized() { if (!hWnd) return; RECT rc; GetWindowRect(hWnd,&rc); - xres=rc.right-rc.left; //account for border :P - yres=rc.bottom-rc.top; + xres = rc.right - rc.left; //account for border :P + yres = rc.bottom - rc.top; //swidth=width; // Set Scissor Width To Window Width //sheight=height; // Set Scissor Height To Window Height - if (yres==0) // Prevent A Divide By Zero By - { - yres=1; // Making Height Equal One - } + if (yres == 0) + yres = 1; glstate.viewport.set(0, 0, xres, yres); glstate.viewport.restore(); } -void GL_SwapBuffers() -{ +void GL_SwapBuffers() { SwapBuffers(hDC); } void FormatDebugOutputARB(char outStr[], size_t outStrSize, GLenum source, GLenum type, - GLuint id, GLenum severity, const char *msg) -{ + GLuint id, GLenum severity, const char *msg) { char sourceStr[32]; const char *sourceFmt = "UNDEFINED(0x%04X)"; - switch(source) - { + switch(source) { case GL_DEBUG_SOURCE_API_ARB: sourceFmt = "API"; break; case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB: sourceFmt = "WINDOW_SYSTEM"; break; case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB: sourceFmt = "SHADER_COMPILER"; break; @@ -72,8 +67,7 @@ void FormatDebugOutputARB(char outStr[], size_t outStrSize, GLenum source, GLenu char typeStr[32]; const char *typeFmt = "UNDEFINED(0x%04X)"; - switch(type) - { + switch(type) { case GL_DEBUG_TYPE_ERROR_ARB: typeFmt = "ERROR"; break; case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB: typeFmt = "DEPRECATED_BEHAVIOR"; break; case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB: typeFmt = "UNDEFINED_BEHAVIOR"; break; @@ -98,8 +92,7 @@ void FormatDebugOutputARB(char outStr[], size_t outStrSize, GLenum source, GLenu } void DebugCallbackARB(GLenum source, GLenum type, GLuint id, GLenum severity, - GLsizei length, const GLchar *message, GLvoid *userParam) -{ + GLsizei length, const GLchar *message, GLvoid *userParam) { (void)length; FILE *outFile = (FILE*)userParam; char finalMessage[256]; @@ -107,15 +100,13 @@ void DebugCallbackARB(GLenum source, GLenum type, GLuint id, GLenum severity, ERROR_LOG(HLE, "GL: %s", finalMessage); } -bool GL_Init(HWND window) -{ +bool GL_Init(HWND window, std::string *error_message) { + *error_message = "ok"; hWnd = window; - GLuint PixelFormat; // Holds The Results After Searching For A Match + GLuint PixelFormat; - hInstance = GetModuleHandle(NULL); // Grab An Instance For Our Window - - static PIXELFORMATDESCRIPTOR pfd= // pfd Tells Windows How We Want Things To Be - { + hInstance = GetModuleHandle(NULL); + static const PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor 1, // Version Number PFD_DRAW_TO_WINDOW | // Format Must Support Window @@ -127,65 +118,68 @@ bool GL_Init(HWND window) 0, // No Alpha Buffer 0, // Shift Bit Ignored 0, // No Accumulation Buffer - 0, 0, 0, 0, // Accumulation Bits Ignored + 0, 0, 0, 0, // Accumulation Bits Ignored 16, // 16Bit Z-Buffer (Depth Buffer) 0, // No Stencil Buffer 0, // No Auxiliary Buffer - PFD_MAIN_PLANE, // Main Drawing Layer + PFD_MAIN_PLANE, // Main Drawing Layer 0, // Reserved - 0, 0, 0 // Layer Masks Ignored + 0, 0, 0 // Layer Masks Ignored }; - if (!(hDC = GetDC(hWnd))) // Did We Get A Device Context? - { - MessageBox(NULL,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION); + hDC = GetDC(hWnd); + + if (!hDC) { + *error_message = "Failed to get a device context."; return false; // Return FALSE } - if (!(PixelFormat = ChoosePixelFormat(hDC,&pfd))) // Did Windows Find A Matching Pixel Format? + // Did Windows Find A Matching Pixel Format? + if (!(PixelFormat = ChoosePixelFormat(hDC,&pfd))) { - MessageBox(NULL,"Can't Find A Suitable PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION); + *error_message = "Can't Find A Suitable PixelFormat."; return false; } - if(!SetPixelFormat(hDC,PixelFormat,&pfd)) // Are We Able To Set The Pixel Format? - { - MessageBox(NULL,"Can't Set The PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION); + // Are We Able To Set The Pixel Format? + if (!SetPixelFormat(hDC,PixelFormat,&pfd)) { + *error_message = "Can't Set The PixelFormat."; return false; } - if (!(hRC = wglCreateContext(hDC))) // Are We Able To Get A Rendering Context? - { - MessageBox(NULL,"Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION); + // Are We Able To Get A Rendering Context? + if (!(hRC = wglCreateContext(hDC))) { + *error_message = "Can't Create A GL Rendering Context."; return false; } - if(!wglMakeCurrent(hDC,hRC)) // Try To Activate The Rendering Context - { - MessageBox(NULL,"Can't Activate The GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION); + // Try To Activate The Rendering Context + if (!wglMakeCurrent(hDC,hRC)) { + *error_message = "Can't activate the GL Rendering Context."; + return false; + } + + if (GLEW_OK != glewInit()) { + *error_message = "Failed to initialize GLEW."; return false; } - glewInit(); // Alright, now for the modernity. - int attribs[] = - { + static const int attribs[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 1, WGL_CONTEXT_FLAGS_ARB, enableGLDebug ? WGL_CONTEXT_DEBUG_BIT_ARB : 0, 0 }; - HGLRC m_hrc; - if(wglewIsSupported("WGL_ARB_create_context") == 1) - { + HGLRC m_hrc; + if(wglewIsSupported("WGL_ARB_create_context") == 1) { m_hrc = wglCreateContextAttribsARB(hDC,0, attribs); wglMakeCurrent(NULL,NULL); wglDeleteContext(hRC); wglMakeCurrent(hDC, m_hrc); - } - else - { //It's not possible to make a GL 3.x context. Use the old style context (GL 2.1 and before) + } else { + // We can't make a GL 3.x context. Use an old style context (GL 2.1 and before) m_hrc = hRC; } @@ -197,43 +191,41 @@ bool GL_Init(HWND window) glGetIntegerv(GL_MAJOR_VERSION, &OpenGLVersion[0]); glGetIntegerv(GL_MINOR_VERSION, &OpenGLVersion[1]); - if (!m_hrc) return false; + if (!m_hrc) { + *error_message = "No m_hrc"; + return false; + } hRC = m_hrc; glstate.Initialize(); setVSync(0); - if (enableGLDebug && glewIsSupported("GL_ARB_debug_output")) - { + if (enableGLDebug && glewIsSupported("GL_ARB_debug_output")) { glDebugMessageCallbackARB((GLDEBUGPROCARB)&DebugCallbackARB, 0); // print debug output to stderr glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); } GL_Resized(); // Set Up Our Perspective GL Screen - return true; // Success } -void GL_Shutdown() -{ - if (hRC) // Do We Have A Rendering Context? - { - if (!wglMakeCurrent(NULL,NULL)) // Are We Able To Release The DC And RC Contexts? - { +void GL_Shutdown() { + if (hRC) { + // Are We Able To Release The DC And RC Contexts? + if (!wglMakeCurrent(NULL,NULL)) { MessageBox(NULL,"Release Of DC And RC Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); } - if (!wglDeleteContext(hRC)) // Are We Able To Delete The RC? - { + // Are We Able To Delete The RC? + if (!wglDeleteContext(hRC)) { MessageBox(NULL,"Release Rendering Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); } - hRC=NULL; // Set RC To NULL + hRC = NULL; } - if (hDC && !ReleaseDC(hWnd,hDC)) // Are We Able To Release The DC - { + if (hDC && !ReleaseDC(hWnd,hDC)) { MessageBox(NULL,"Release Device Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); - hDC=NULL; // Set DC To NULL + hDC = NULL; } hWnd = NULL; } diff --git a/Windows/OpenGLBase.h b/Windows/OpenGLBase.h index b26ed0ebfd..bf19199b49 100644 --- a/Windows/OpenGLBase.h +++ b/Windows/OpenGLBase.h @@ -5,7 +5,7 @@ #define WIN32_LEAN_AND_MEAN #include -bool GL_Init(HWND window); +bool GL_Init(HWND window, std::string *error_message); void GL_Shutdown(); void GL_Resized(); void GL_SwapBuffers(); diff --git a/Windows/WindowsHost.cpp b/Windows/WindowsHost.cpp index 73d16a5bf7..720d77b043 100644 --- a/Windows/WindowsHost.cpp +++ b/Windows/WindowsHost.cpp @@ -1,3 +1,20 @@ +// Copyright (c) 2012- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + #include "Core/Core.h" #include "Core/Config.h" #include "EmuThread.h" @@ -26,9 +43,9 @@ int MyMix(short *buffer, int numSamples, int bits, int rate, int channels) } } -void WindowsHost::InitGL() +bool WindowsHost::InitGL(std::string *error_message) { - GL_Init(MainWindow::GetDisplayHWND()); + return GL_Init(MainWindow::GetDisplayHWND(), error_message); } void WindowsHost::ShutdownGL() diff --git a/Windows/WindowsHost.h b/Windows/WindowsHost.h index 923acf10b8..06ac8b9fdf 100644 --- a/Windows/WindowsHost.h +++ b/Windows/WindowsHost.h @@ -1,3 +1,20 @@ +// Copyright (c) 2012- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + #include "../Core/Host.h" #include "InputDevice.h" #include @@ -19,7 +36,7 @@ public: void AddSymbol(std::string name, u32 addr, u32 size, int type); - void InitGL(); + bool InitGL(std::string *error_message); void BeginFrame(); void ShutdownGL(); diff --git a/android/jni/NativeApp.cpp b/android/jni/NativeApp.cpp index 1d1e9a4872..e8928ea768 100644 --- a/android/jni/NativeApp.cpp +++ b/android/jni/NativeApp.cpp @@ -99,7 +99,7 @@ public: virtual void SetDebugMode(bool mode) { } - virtual void InitGL() {} + virtual bool InitGL(std::string *error_message) {} virtual void BeginFrame() {} virtual void ShutdownGL() {} diff --git a/headless/Headless.cpp b/headless/Headless.cpp index 96ddf00612..b4f1699ac5 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -137,7 +137,9 @@ int main(int argc, const char* argv[]) HeadlessHost *headlessHost = useGraphics ? new HEADLESSHOST_CLASS() : new HeadlessHost(); host = headlessHost; - host->InitGL(); + + std::string error_string; + host->InitGL(&error_string); LogManager::Init(); LogManager *logman = LogManager::GetInstance(); @@ -176,7 +178,6 @@ int main(int argc, const char* argv[]) g_Config.flashDirectory = g_Config.memCardDirectory+"/flash/"; #endif - std::string error_string; if (!PSP_Init(coreParameter, &error_string)) { fprintf(stderr, "Failed to start %s. Error: %s\n", coreParameter.fileToStart.c_str(), error_string.c_str()); diff --git a/headless/StubHost.h b/headless/StubHost.h index 19e71c3b68..fd85de2ca1 100644 --- a/headless/StubHost.h +++ b/headless/StubHost.h @@ -33,7 +33,7 @@ public: virtual void SetDebugMode(bool mode) { } - virtual void InitGL() {} + virtual bool InitGL(std::string *error_message) {return true;} virtual void BeginFrame() {} virtual void ShutdownGL() {}