瀏覽代碼

Added debug information to SDL-related crashes

Ivan Savenko 2 年之前
父節點
當前提交
5faaf175f9
共有 4 個文件被更改,包括 35 次插入1 次删除
  1. 11 0
      client/CMT.cpp
  2. 4 0
      client/CMT.h
  3. 11 0
      client/renderSDL/SDL_Extensions.cpp
  4. 9 1
      client/renderSDL/ScreenHandler.cpp

+ 11 - 0
client/CMT.cpp

@@ -38,6 +38,7 @@
 #include <vstd/StringUtils.h>
 
 #include <SDL_main.h>
+#include <SDL.h>
 
 #ifdef VCMI_ANDROID
 #include "../lib/CAndroidVMHelper.h"
@@ -510,3 +511,13 @@ void handleQuit(bool ask)
 		quitApplication();
 	}
 }
+
+void handleFatalError(const std::string & message)
+{
+	logGlobal->error("FATAL ERROR ENCOUTERED, VCMI WILL NOW TERMINATE");
+	logGlobal->error("Reason: %s", message);
+
+	SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal error", message.c_str(), nullptr);
+
+	throw std::runtime_error(message);
+}

+ 4 - 0
client/CMT.h

@@ -21,3 +21,7 @@ extern SDL_Surface *screen2;     // and hlp surface (used to store not-active in
 extern SDL_Surface *screenBuf; // points to screen (if only advmapint is present) or screen2 (else) - should be used when updating controls which are not regularly redrawed
 
 void handleQuit(bool ask = true);
+
+/// Notify user about encoutered fatal error and terminate the game
+/// TODO: decide on better location for this method
+[[noreturn]] void handleFatalError(const std::string & message);

+ 11 - 0
client/renderSDL/SDL_Extensions.cpp

@@ -80,6 +80,17 @@ SDL_Surface * CSDL_Ext::newSurface(int w, int h)
 SDL_Surface * CSDL_Ext::newSurface(int w, int h, SDL_Surface * mod) //creates new surface, with flags/format same as in surface given
 {
 	SDL_Surface * ret = SDL_CreateRGBSurface(0,w,h,mod->format->BitsPerPixel,mod->format->Rmask,mod->format->Gmask,mod->format->Bmask,mod->format->Amask);
+
+	if(ret == nullptr)
+	{
+		const char * error = SDL_GetError();
+
+		std::string messagePattern = "Failed to create SDL Surface of size %d x %d, %d bpp. Reason: %s";
+		std::string message = boost::str(boost::format(messagePattern) % w % h % mod->format->BitsPerPixel % error);
+
+		handleFatalError(message);
+	}
+
 	if (mod->format->palette)
 	{
 		assert(ret->format->palette);

+ 9 - 1
client/renderSDL/ScreenHandler.cpp

@@ -264,7 +264,15 @@ void ScreenHandler::initializeWindow()
 	mainWindow = createWindow();
 
 	if(mainWindow == nullptr)
-		throw std::runtime_error("Unable to create window\n");
+	{
+		const char * error = SDL_GetError();
+		Point dimensions = getPreferredWindowResolution();
+
+		std::string messagePattern = "Failed to create SDL Window of size %d x %d. Reason: %s";
+		std::string message = boost::str(boost::format(messagePattern) % dimensions.x % dimensions.y % error);
+
+		handleFatalError(message);
+	}
 
 	//create first available renderer if preferred not set. Use no flags, so HW accelerated will be preferred but SW renderer also will possible
 	mainRenderer = SDL_CreateRenderer(mainWindow, getPreferredRenderingDriver(), 0);