diff --git a/platform/error.cpp b/platform/error.cpp index 8002e9e..f2d2018 100644 --- a/platform/error.cpp +++ b/platform/error.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "error.h" #include "platform.h" @@ -38,3 +39,18 @@ void send_log_impl(const char *format, ...) { void throw_exception(const char *text) { throw std::runtime_error(std::string("Invoked crash:") + text); } + +std::string exception_to_string(const std::exception& e) { + std::ostringstream oss; + oss << e.what(); + + try { + std::rethrow_if_nested(e); + } catch (const std::exception& nested) { + oss << " Reason: " << exception_to_string(nested); + } catch (...) { + oss << " Reason: unknown exception of crash"; + } + + return std::move(oss).str(); +} diff --git a/platform/error.h b/platform/error.h index 5d0e975..e88b2ea 100644 --- a/platform/error.h +++ b/platform/error.h @@ -2,6 +2,11 @@ #ifdef __cplusplus + +#include +#include +std::string exception_to_string(const std::exception& e); + extern "C" { #endif @@ -10,7 +15,8 @@ void send_log_impl(const char *format, ...); void display_error(const char *format, ...); void throw_exception(const char *text); - #ifdef __cplusplus + + } #endif diff --git a/platform/linux/app_start.cpp b/platform/linux/app_start.cpp index 7ec40d4..a0f1736 100644 --- a/platform/linux/app_start.cpp +++ b/platform/linux/app_start.cpp @@ -1,6 +1,7 @@ #include "../../game/skeldal.h" #include "../getopt.h" #include "../platform.h" +#include "../error.h" #include #include @@ -63,7 +64,7 @@ int main(int argc, char **argv) { } } catch (const std::exception &e) { - std::cerr << "ERROR: " << e.what() << std::endl; + std::cerr << "ERROR: " << exception_to_string(e) << std::endl; return 1; } diff --git a/platform/linux/map_file.cpp b/platform/linux/map_file.cpp index 89adbc3..24c3810 100644 --- a/platform/linux/map_file.cpp +++ b/platform/linux/map_file.cpp @@ -1,9 +1,7 @@ -extern "C" { #include "map_file.h" #include "../error.h" -} #include #include diff --git a/platform/linux/map_file.h b/platform/linux/map_file.h index e4495ed..2c4c27a 100644 --- a/platform/linux/map_file.h +++ b/platform/linux/map_file.h @@ -1,4 +1,13 @@ #include #include + +#ifdef __cplusplus +extern "C" { +#endif + void *map_file_to_memory(const char *name, size_t *sz); void unmap_file(void *ptr, size_t sz); + +#ifdef __cplusplus +} +#endif diff --git a/platform/sdl/BGraph2.cpp b/platform/sdl/BGraph2.cpp index e841088..51f0418 100644 --- a/platform/sdl/BGraph2.cpp +++ b/platform/sdl/BGraph2.cpp @@ -41,6 +41,7 @@ char game_display_init(const INI_CONFIG_SECTION *display_section, const char *ti else cfg.crt_filter = SDLContext::CrtFilterType::autoselect; cfg.cursor_size = ini_get_int(display_section, "cursor_size", 100)*0.01f; + cfg.hint_renderer = ini_get_string(display_section, "sdl_renderer_driver", NULL); screen_pitch = 640; get_sdl_global_context().init_video(cfg, title); diff --git a/platform/sdl/sdl_context.cpp b/platform/sdl/sdl_context.cpp index e0c59c7..58ea510 100644 --- a/platform/sdl/sdl_context.cpp +++ b/platform/sdl/sdl_context.cpp @@ -219,6 +219,9 @@ void SDLContext::init_video(const VideoConfig &config, const char *title) { _enable_crt = false; } + if (config.hint_renderer) { + SDL_SetHint(SDL_HINT_RENDER_DRIVER, config.hint_renderer); + } _fullscreen_mode = config.fullscreen; _mouse_size = config.cursor_size; @@ -294,7 +297,15 @@ void SDLContext::init_video(const VideoConfig &config, const char *title) { done.wait(false); if (e) { _render_thread.join(); - std::rethrow_exception(e); + try { + std::rethrow_exception(e); + } catch (...) { + std::throw_with_nested( + std::runtime_error("Oops! The app couldn't start properly (problem during SDL initialization). " + "This may be caused by outdated or missing graphics or audio drivers." + "To fix this, please try the following: Restart your computer and try again/" + "Make sure your graphics and sound drivers are up to date.")); + } } diff --git a/platform/sdl/sdl_context.h b/platform/sdl/sdl_context.h index 0e11bda..2cfa786 100644 --- a/platform/sdl/sdl_context.h +++ b/platform/sdl/sdl_context.h @@ -33,6 +33,7 @@ public: CrtFilterType crt_filter; int composer; const char *scale_quality; + const char *hint_renderer; bool fullscreen; int aspect_x; int aspect_y; @@ -238,8 +239,8 @@ protected: std::unique_ptr _crt_effect; std::unique_ptr _mouse; unique_value _audio; - SDL_Texture *_visible_texture; - SDL_Texture *_hidden_texture; + SDL_Texture *_visible_texture = nullptr; + SDL_Texture *_hidden_texture = nullptr; bool _fullscreen_mode = false; @@ -256,7 +257,7 @@ protected: std::queue _keyboard_queue; SDL_Rect _mouse_rect; SDL_Point _mouse_finger; - float _mouse_size; + float _mouse_size = 1; SpriteList _sprites; diff --git a/skeldal.ini b/skeldal.ini index 5e7be5f..cab6ad9 100644 --- a/skeldal.ini +++ b/skeldal.ini @@ -33,6 +33,10 @@ # composer = auto - choose best supported driver # hardware,hw - use hardware for composition # software,sw - use software for composition +# sdl_renderer_driver - help SDL to choose optimal rederer +# direct3d,direct3d11,direct3d12 +# opengl,opengles2,opengles +# metal,software # scale_quality = auto - best for hardware composer, nearest for software comporser # best - best scale quality (SDL = linear) # linear - use linear filtering (Direct3D and OpenGL) @@ -47,6 +51,7 @@ #crt_filter=auto #scale_quality=auto #composer=auto +#sdl_renderer_driver=software #aspect_ratio=4:3 #cursor_size=100