mirror of
https://github.com/ondra-novak/gates_of_skeldal.git
synced 2025-07-04 21:50:38 -04:00
add some cheks and error reporting, enable catch SEH in windows
This commit is contained in:
parent
8faba63219
commit
c9d0e86344
8 changed files with 88 additions and 34 deletions
|
@ -5,7 +5,7 @@ project(skeldal)
|
|||
find_package(SDL2 REQUIRED)
|
||||
|
||||
if (MSVC)
|
||||
add_compile_options(/W4 /EHsc /DNOMINMAX /J)
|
||||
add_compile_options(/W4 /EHa /DNOMINMAX /J)
|
||||
set(STANDARD_LIBRARIES "")
|
||||
else()
|
||||
add_compile_options(-Wall -Wextra -Werror -Wno-unused-result -Wno-unused-parameter -Wno-unused-value -Wno-extern-c-compat -funsigned-char)
|
||||
|
|
|
@ -1375,7 +1375,6 @@ void redraw_scene()
|
|||
ukaz_mysku();
|
||||
global_anim_counter++;
|
||||
send_message(E_KOUZLO_ANM);
|
||||
|
||||
}
|
||||
|
||||
void refresh_scene(THE_TIMER *t)
|
||||
|
|
|
@ -996,7 +996,8 @@ void init_skeldal(const INI_CONFIG *cfg)
|
|||
char verr = game_display_init(ini_section_open(cfg, "video"), "Skeldal");
|
||||
if (!verr)
|
||||
{
|
||||
exit(1);
|
||||
display_error("Error game_display_init %d", verr);
|
||||
exit(1);
|
||||
}
|
||||
showview = game_display_update_rect;
|
||||
game_display_set_icon(getWindowIcon(), getWindowIconSize());
|
||||
|
|
|
@ -7,6 +7,8 @@ extern "C" {
|
|||
|
||||
|
||||
void send_log_impl(const char *format, ...);
|
||||
void display_error(const char *format, ...);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "legacy_coroutines.h"
|
||||
|
||||
#include "error.h"
|
||||
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
|
@ -116,6 +116,17 @@ static void broadcast_message(EVENT_MSG *msg) {
|
|||
clean_task_table();
|
||||
}
|
||||
|
||||
static void crash_task_exception() {
|
||||
try {
|
||||
throw;
|
||||
} catch (std::exception &e) {
|
||||
display_error("Unhandled exception in task %d: %s",q_current_task(), e.what());
|
||||
} catch (...) {
|
||||
display_error("Unhandled exception in task %d: unknown/crash",q_current_task());
|
||||
}
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
int add_task(int stack,TaskerFunctionName fcname,...) {
|
||||
int id = get_new_task_id();
|
||||
|
@ -126,8 +137,12 @@ int add_task(int stack,TaskerFunctionName fcname,...) {
|
|||
new_task->thr = std::thread([&]{
|
||||
new_task->resume_flag.wait(false);
|
||||
new_task->resume_flag = false;
|
||||
fcname(args);
|
||||
clean_up_current_task();
|
||||
try {
|
||||
fcname(args);
|
||||
clean_up_current_task();
|
||||
} catch (...) {
|
||||
crash_task_exception();
|
||||
}
|
||||
});
|
||||
switch_to_task(new_task);
|
||||
return id;
|
||||
|
|
|
@ -63,6 +63,12 @@ SDLContext::SDLContext() {
|
|||
if (!init_context.inited) throw std::runtime_error("SDL not inited");
|
||||
|
||||
}
|
||||
void handle_sdl_error(const char *msg) {
|
||||
char buff[512];
|
||||
|
||||
snprintf(buff, sizeof(buff), "SDL critical error (check video driver): %s %s",msg, SDL_GetError());
|
||||
throw std::runtime_error(buff);
|
||||
}
|
||||
|
||||
|
||||
void SDLContext::generateCRTTexture(SDL_Renderer* renderer, SDL_Texture** texture, int width, int height, CrtFilterType type) {
|
||||
|
@ -78,20 +84,27 @@ void SDLContext::generateCRTTexture(SDL_Renderer* renderer, SDL_Texture** textur
|
|||
}
|
||||
// Vytvoř novou texturu ve správné velikosti
|
||||
*texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, width, height);
|
||||
if (!*texture) {
|
||||
type = CrtFilterType::none;
|
||||
return; //crt filter failed to create, do not use filter
|
||||
}
|
||||
SDL_SetTextureBlendMode(*texture, SDL_BLENDMODE_MUL);
|
||||
|
||||
|
||||
// Zamkni texturu pro přímý přístup k pixelům
|
||||
void* pixels;
|
||||
int pitch;
|
||||
SDL_LockTexture(*texture, nullptr, &pixels, &pitch);
|
||||
if (SDL_LockTexture(*texture, nullptr, &pixels, &pitch)<0) {
|
||||
SDL_DestroyTexture(*texture);
|
||||
*texture = nullptr;
|
||||
type = CrtFilterType::none;
|
||||
return;
|
||||
}
|
||||
|
||||
Uint32* pixelArray = (Uint32*)pixels;
|
||||
|
||||
if (type == CrtFilterType::scanlines) {
|
||||
|
||||
|
||||
|
||||
Uint32 darkPixel = 0xA0A0A0FF;
|
||||
Uint32 transparentPixel = 0xFFFFFFC0;
|
||||
|
||||
|
@ -152,10 +165,19 @@ void SDLContext::generateCRTTexture(SDL_Renderer* renderer, SDL_Texture** textur
|
|||
SDL_UnlockTexture(*texture);
|
||||
}
|
||||
|
||||
static void crash_sdl_exception() {
|
||||
try {
|
||||
throw;
|
||||
} catch (std::exception &e) {
|
||||
display_error("Display server - unhandled exception: %s", e.what());
|
||||
} catch (...) {
|
||||
display_error("Display server - unhandled unknown exception (probably crash)");
|
||||
}
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
void SDLContext::init_video(const VideoConfig &config, const char *title) {
|
||||
char buff[256];
|
||||
static Uint32 update_request_event = SDL_RegisterEvents(1);
|
||||
static Uint32 refresh_request_event = SDL_RegisterEvents(1);
|
||||
_update_request_event = update_request_event;
|
||||
|
@ -187,15 +209,13 @@ void SDLContext::init_video(const VideoConfig &config, const char *title) {
|
|||
width, height, SDL_WINDOW_RESIZABLE|(_fullscreen_mode?SDL_WINDOW_FULLSCREEN_DESKTOP:0));
|
||||
|
||||
if (!window) {
|
||||
snprintf(buff, sizeof(buff), "SDL Error create window: %s\n", SDL_GetError());
|
||||
throw std::runtime_error(buff);
|
||||
handle_sdl_error("SDL Error create window");
|
||||
}
|
||||
|
||||
_window.reset(window);
|
||||
SDL_Renderer *renderer = SDL_CreateRenderer(_window.get(), -1, config.composer);
|
||||
if (!renderer) {
|
||||
snprintf(buff,sizeof(buff), "Failed to create composer: %s\n", SDL_GetError());
|
||||
throw std::runtime_error(buff);
|
||||
handle_sdl_error("Failed to create composer");
|
||||
}
|
||||
|
||||
SDL_RendererInfo rinfo;
|
||||
|
@ -212,15 +232,14 @@ void SDLContext::init_video(const VideoConfig &config, const char *title) {
|
|||
_renderer.reset(renderer);
|
||||
SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB1555, SDL_TEXTUREACCESS_STREAMING, 640, 480);
|
||||
if (!texture) {
|
||||
snprintf(buff, sizeof(buff), "Chyba při vytváření textury: %s\n", SDL_GetError());
|
||||
throw std::runtime_error(buff);
|
||||
handle_sdl_error("Failed to create render target");
|
||||
}
|
||||
|
||||
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
|
||||
_texture.reset(texture);
|
||||
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB1555, SDL_TEXTUREACCESS_STREAMING, 640, 480);
|
||||
if (!texture) {
|
||||
snprintf(buff, sizeof(buff), "Chyba při vytváření textury: %s\n", SDL_GetError());
|
||||
throw std::runtime_error(buff);
|
||||
handle_sdl_error("Failed to create second render target");
|
||||
}
|
||||
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
|
||||
_texture2.reset(texture);
|
||||
|
@ -232,8 +251,16 @@ void SDLContext::init_video(const VideoConfig &config, const char *title) {
|
|||
}
|
||||
done = true;
|
||||
done.notify_all();
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
if (!err) event_loop(stp);
|
||||
|
||||
if (!err) {
|
||||
try {
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
event_loop(stp);
|
||||
} catch (...) {
|
||||
SDL_ShowCursor(SDL_ENABLE);
|
||||
crash_sdl_exception();
|
||||
}
|
||||
}
|
||||
_texture.reset();
|
||||
_texture2.reset();
|
||||
_renderer.reset();
|
||||
|
@ -648,7 +675,7 @@ void SDLContext::update_screen(bool force_refresh) {
|
|||
SDL_Rect r;
|
||||
pop_item(iter, r);
|
||||
std::string_view data = pop_data(iter, r.w*r.h*2);
|
||||
SDL_UpdateTexture(_texture.get(), &r, data.data(), r.w*2);
|
||||
if (SDL_UpdateTexture(_texture.get(), &r, data.data(), r.w*2)<0) handle_sdl_error("Update of render target failed");
|
||||
}
|
||||
break;
|
||||
case DisplayRequest::show_mouse_cursor: {
|
||||
|
@ -656,10 +683,11 @@ void SDLContext::update_screen(bool force_refresh) {
|
|||
pop_item(iter, r);
|
||||
std::string_view data = pop_data(iter, r.w*r.h*2);
|
||||
_mouse.reset(SDL_CreateTexture(_renderer.get(), SDL_PIXELFORMAT_ARGB1555,SDL_TEXTUREACCESS_STATIC, r.w, r.h));
|
||||
if (!_mouse) handle_sdl_error("Failed to create surface for mouse cursor");
|
||||
SDL_SetTextureBlendMode(_mouse.get(), SDL_BLENDMODE_BLEND);
|
||||
_mouse_rect.w = r.w;
|
||||
_mouse_rect.h = r.h;
|
||||
SDL_UpdateTexture(_mouse.get(), NULL, data.data(), r.w*2);
|
||||
if (SDL_UpdateTexture(_mouse.get(), NULL, data.data(), r.w*2)<0) handle_sdl_error("Update of mouse cursor failed");
|
||||
}
|
||||
break;
|
||||
case DisplayRequest::hide_mouse_cursor: {
|
||||
|
@ -697,8 +725,9 @@ void SDLContext::update_screen(bool force_refresh) {
|
|||
iter = _sprites.insert(iter,{id});
|
||||
}
|
||||
iter->_txtr.reset(SDL_CreateTexture(_renderer.get(), SDL_PIXELFORMAT_ARGB1555, SDL_TEXTUREACCESS_STATIC,r.w, r.h));
|
||||
if (!iter->_txtr) handle_sdl_error("Failed to create compositor sprite");
|
||||
SDL_SetTextureBlendMode(iter->_txtr.get(), SDL_BLENDMODE_BLEND);
|
||||
SDL_UpdateTexture(iter->_txtr.get(), NULL, data.data(), r.w*2);
|
||||
if (SDL_UpdateTexture(iter->_txtr.get(), NULL, data.data(), r.w*2)<0) handle_sdl_error("Update of sprite failed");
|
||||
iter->_rect = r;
|
||||
update_zindex();
|
||||
} break;
|
||||
|
@ -947,13 +976,7 @@ void SDLContext::close_audio() {
|
|||
|
||||
void SDLContext::set_window_icon(const void *icon_data, size_t icon_size) {
|
||||
SDL_Surface *surface = SDL_LoadBMP_RW(SDL_RWFromConstMem(icon_data, icon_size), 1);
|
||||
if (surface == 0) {
|
||||
char buff[256];
|
||||
snprintf(buff,sizeof(buff),"Can't load icon: %s", SDL_GetError());
|
||||
display_error(buff);
|
||||
std::ofstream x("test.dat", std::ios::out|std::ios::binary|std::ios::trunc);
|
||||
x.write(reinterpret_cast<const char *>(icon_data), icon_size);
|
||||
} else {
|
||||
if (surface) {
|
||||
SDL_SetWindowIcon(_window.get(), surface);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,10 +50,20 @@ void game_sound_init_device(const INI_CONFIG_SECTION *audio_section) {
|
|||
}
|
||||
|
||||
static void SDLCALL mixing_callback(void *userdata, Uint8 * stream, int len) {
|
||||
float *s = reinterpret_cast<float *>(stream);
|
||||
int samples = len/8;
|
||||
std::fill(s, s+2*samples, 0.0f);
|
||||
sound_mixer.mix_to_buffer(s, samples);
|
||||
static char crashed = 0;
|
||||
float *s = reinterpret_cast<float *>(stream);
|
||||
int samples = len/8;
|
||||
std::fill(s, s+2*samples, 0.0f);
|
||||
if (crashed) return;
|
||||
try {
|
||||
sound_mixer.mix_to_buffer(s, samples);
|
||||
} catch (std::exception &e) {
|
||||
crashed = 1;
|
||||
display_error("Unhandled exception in sound mixer: %s", e.what());
|
||||
} catch (...) {
|
||||
crashed = 1;
|
||||
display_error("Crash in sound mixer: %s");
|
||||
}
|
||||
}
|
||||
|
||||
char start_mixing() {
|
||||
|
|
|
@ -85,6 +85,10 @@ int main(int argc, char **argv) {
|
|||
cfg.show_error(e.what());
|
||||
return 1;
|
||||
}
|
||||
catch (...) {
|
||||
cfg.show_error("Uknown error or crash");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue