mirror of
https://github.com/ondra-novak/gates_of_skeldal.git
synced 2025-08-31 23:25:59 -04:00
SLD context now running in main thread (for better compatibility)
This commit is contained in:
parent
96eaeb4851
commit
e0aa5096ba
16 changed files with 259 additions and 275 deletions
|
@ -339,7 +339,7 @@ static char *transfer_text(const char *source,char *target)
|
|||
if (source==NULL)
|
||||
{
|
||||
char buff[256];
|
||||
closemode();
|
||||
|
||||
sprintf(buff,"%s\r\nChybny rod nebo maly pocet tvaru od jednoho slova",orgn);
|
||||
error(buff);
|
||||
exit(-1);
|
||||
|
@ -353,7 +353,7 @@ static char *transfer_text(const char *source,char *target)
|
|||
if (source==NULL)
|
||||
{
|
||||
char buff[256];
|
||||
closemode();
|
||||
|
||||
sprintf(buff,"%s\r\nOcekava se ]",orgn);
|
||||
error(buff);
|
||||
exit(-1);
|
||||
|
|
|
@ -243,7 +243,7 @@ static void register_mob_graphics(int num,char *name_part,const char *anims,cons
|
|||
if (*seq=='\r')
|
||||
{
|
||||
char buff[256];
|
||||
closemode();
|
||||
|
||||
sprintf(buff,"Soubor sekvence %s obsahuje chybne udaje nebo je sekvence je moc kratka\n", fulname);
|
||||
display_error(buff);
|
||||
exit(0);
|
||||
|
@ -387,7 +387,7 @@ void load_enemies(short *data,int size,int *grptr,const TMOB *template,int32_t t
|
|||
if (mobs[i].speed<1)
|
||||
{
|
||||
char buff[256];
|
||||
closemode();
|
||||
|
||||
sprintf(buff,"Nestvura cislo #%d (%s) je spatne definovana (rychlost)",i,mobs[i].name);
|
||||
display_error(buff);
|
||||
exit(1);
|
||||
|
@ -1464,7 +1464,7 @@ void mob_strelba(TMOB *p)
|
|||
for(i=0;i<item_count;i++) if (glob_items[i].umisteni==PL_SIP && glob_items[i].druh==TYP_VRHACI) break;
|
||||
if (i==item_count)
|
||||
{
|
||||
closemode();
|
||||
|
||||
display_error("Nestvura nemuze strilet. Neni nadefinovan obekt sipu");
|
||||
exit(1);
|
||||
}
|
||||
|
@ -1640,7 +1640,7 @@ void mobs_live(int num)
|
|||
if (p->sector>=mapsize)
|
||||
{
|
||||
char buff[256];
|
||||
closemode();
|
||||
|
||||
sprintf(buff,"Potvora v neexistujicim sektoru (%d, %d) ",num,p->sector);
|
||||
display_error(buff);
|
||||
exit(1);
|
||||
|
|
|
@ -93,7 +93,6 @@ static int unable_open_temp(char *c)
|
|||
char d[]="Unable to open the file : ",*e;
|
||||
|
||||
concat(e,d,c);
|
||||
closemode();
|
||||
display_error(e);
|
||||
SEND_LOG("(SAVELOAD) Open temp error detected (%s)",c);
|
||||
exit(1);
|
||||
|
@ -104,7 +103,6 @@ static void unable_write_temp(char *c)
|
|||
char d[]="Unable to write to the temp file : ",*e;
|
||||
|
||||
concat(e,d,c);
|
||||
closemode();
|
||||
display_error(e);
|
||||
SEND_LOG("(SAVELOAD) Open temp error detected (%s)",c);
|
||||
exit(1);
|
||||
|
|
|
@ -172,7 +172,7 @@ static void error(const char *text)
|
|||
|
||||
sprintf(popis,"Chyba v souboru "GLOBMAP" na radce %d.\r\n%s",linecounter,text);
|
||||
SEND_LOG("(ERROR) %s : %s",popis,text);
|
||||
closemode();
|
||||
|
||||
display_error(popis);
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
@ -130,7 +130,7 @@ void init_item_sounds(int *ptr)
|
|||
c=(char *)ablock(H_SOUND_DAT)+sound_table[glob_items[i].sound-1];
|
||||
if (c==NULL || c[0]==0)
|
||||
{
|
||||
closemode();
|
||||
|
||||
puts("Invalid Sound Table integrity - rebuild SOUND.DAT using MapEdit");
|
||||
exit(1);
|
||||
}
|
||||
|
@ -171,7 +171,7 @@ void load_items()
|
|||
f=fopen_icase(name,"rb");
|
||||
if (f==NULL)
|
||||
{
|
||||
closemode();
|
||||
|
||||
display_error("Selhalo otevreni souboru ITEMS.DAT. Zkotroluj zda vubec existuje.");
|
||||
exit(0);
|
||||
}
|
||||
|
@ -955,7 +955,7 @@ void definuj_postavy()
|
|||
}
|
||||
if (r!=1)
|
||||
{
|
||||
closemode();
|
||||
|
||||
display_error("Error in file POSTAVY.DAT. May be missing a parameter in some definition.");
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
@ -526,7 +526,6 @@ static void seek_section(TMPFILE_RD *txt,int sect_number)
|
|||
c=0;
|
||||
}
|
||||
while (i!=EOF);
|
||||
closemode();
|
||||
{
|
||||
char buff[256];
|
||||
sprintf(buff,"Nemohu najit odstavec s cislem %d.",sect_number);
|
||||
|
|
|
@ -407,7 +407,7 @@ char *get_next_title(signed char control,const char *filename)
|
|||
if (titles==NULL)
|
||||
{
|
||||
char popis[300];
|
||||
closemode();
|
||||
|
||||
sprintf(popis,"Soubor nenalezen: %s nebo %s\n",path,path2);
|
||||
display_error(popis);
|
||||
exit(1);
|
||||
|
|
|
@ -417,7 +417,6 @@ int load_map(const char *filename)
|
|||
for(r=0;r<mapsize*4;r++) flag_map[r]=(char)map_sides[r].flags;
|
||||
if (!doNotLoadMapState && load_map_state()==-2)
|
||||
{
|
||||
closemode();
|
||||
display_error("Bug in temp file. Please purge some status blocks in last load savegame file.");
|
||||
exit(0);
|
||||
}
|
||||
|
|
200
game/skeldal.c
200
game/skeldal.c
|
@ -809,7 +809,7 @@ void cti_texty(void)
|
|||
if ((err=load_string_list_ex(&texty,path))!=0)
|
||||
{
|
||||
char buff[256];
|
||||
closemode();
|
||||
|
||||
switch (err)
|
||||
{
|
||||
case -1:sprintf(buff,"Can't load string table. File %s has not been found\n",path);break;
|
||||
|
@ -870,7 +870,7 @@ void error_exception(EVENT_MSG *msg,void **unused)
|
|||
SEND_LOG("(ERROR) Log: Sector %d Direction %d",viewsector,viewdir);
|
||||
|
||||
SEND_LOG("(ERROR) Log: Battle: %d Select_player %d",battle,select_player);
|
||||
closemode();
|
||||
|
||||
display_error("error_exception called");
|
||||
|
||||
}
|
||||
|
@ -983,11 +983,96 @@ void show_loading_picture(char *filename)
|
|||
ablock_free(p);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
va_list _args;
|
||||
} Args ;
|
||||
|
||||
void init_skeldal(const INI_CONFIG *cfg)
|
||||
int init_skeldal_thread(va_list args) {
|
||||
|
||||
const INI_CONFIG *cfg = va_arg(args, const INI_CONFIG *);
|
||||
int (*game_thread)(va_list) = va_arg(args, int (*)(va_list));
|
||||
va_list *game_args = va_arg(args, va_list *);
|
||||
|
||||
showview = game_display_update_rect;
|
||||
game_display_set_icon(getWindowIcon(), getWindowIconSize());
|
||||
init_joystick(ini_section_open(cfg, "controller"));
|
||||
|
||||
general_engine_init();
|
||||
atexit(done_skeldal);
|
||||
|
||||
init_DDL_manager();
|
||||
show_loading_picture("LOADING.HI");
|
||||
|
||||
if (lang_get_folder()) {
|
||||
texty_knihy = build_pathname(2, lang_get_folder(), "book.txt");
|
||||
if (!check_file_exists(texty_knihy)) {
|
||||
texty_knihy=strdup(build_pathname(2,gpathtable[SR_MAP],"kniha.txt"));
|
||||
} else {
|
||||
texty_knihy=strdup(texty_knihy);
|
||||
}
|
||||
} else {
|
||||
texty_knihy=strdup(build_pathname(2,gpathtable[SR_MAP],"kniha.txt"));
|
||||
}
|
||||
|
||||
install_gui();
|
||||
if (is_joystick_enabled()) {
|
||||
show_joystick_info();
|
||||
}
|
||||
|
||||
|
||||
|
||||
send_message(E_DONE,E_WATCH,timer);
|
||||
send_message(E_DONE,E_IDLE,redraw_desktop_call);
|
||||
send_message(E_ADD,E_TIMER,timming);
|
||||
|
||||
send_message(E_ADD,E_WATCH,user_timer);
|
||||
|
||||
send_message(E_ADD,E_MOUSE,ms_clicker);
|
||||
|
||||
send_message(E_ADD,E_KEYBOARD,global_kbd);
|
||||
|
||||
send_message(E_ADD,E_PRGERROR,error_exception);
|
||||
|
||||
add_to_timer(TM_BACK_MUSIC,5,-1,back_music);
|
||||
|
||||
add_game_window();
|
||||
|
||||
game_sound_init_device(ini_section_open(cfg, "audio"));
|
||||
start_mixing();
|
||||
|
||||
int verr;
|
||||
if ((verr=init_mysky())!=0)
|
||||
{
|
||||
|
||||
puts(texty[174-verr]);
|
||||
SEND_LOG("(ERROR) %s (%d)",texty[174-verr],verr);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// hranice_mysky(0,0,639,479);
|
||||
|
||||
mouse_set_default(H_MS_DEFAULT);
|
||||
ukaz_mysku();
|
||||
set_end_of_song_callback(end_of_song_callback, NULL);
|
||||
|
||||
kouzla_init();
|
||||
|
||||
load_items();
|
||||
|
||||
load_shops();
|
||||
memset(&loadlevel,0,sizeof(loadlevel));
|
||||
loadlevel.eflags = 0xFF;
|
||||
|
||||
int r = game_thread(*game_args);
|
||||
va_end(args);
|
||||
return r;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int init_skeldal(const INI_CONFIG *cfg, void (*game_thread)(va_list), ...)
|
||||
{
|
||||
|
||||
|
||||
boldcz=LoadDefaultFont();
|
||||
|
||||
cti_texty();
|
||||
|
@ -995,84 +1080,19 @@ void init_skeldal(const INI_CONFIG *cfg)
|
|||
init_events();
|
||||
|
||||
steam_init();
|
||||
va_list args;
|
||||
va_start(args,game_thread);
|
||||
|
||||
char verr = game_display_init(ini_section_open(cfg, "video"), "Skeldal");
|
||||
if (!verr)
|
||||
int verr = game_display_init(ini_section_open(cfg, "video"), "Skeldal",
|
||||
init_skeldal_thread, cfg, game_thread, &args);
|
||||
if (verr < 0)
|
||||
{
|
||||
display_error("Error game_display_init %d", verr);
|
||||
exit(1);
|
||||
return 1;
|
||||
}
|
||||
showview = game_display_update_rect;
|
||||
game_display_set_icon(getWindowIcon(), getWindowIconSize());
|
||||
init_joystick(ini_section_open(cfg, "controller"));
|
||||
|
||||
general_engine_init();
|
||||
atexit(done_skeldal);
|
||||
|
||||
init_DDL_manager();
|
||||
show_loading_picture("LOADING.HI");
|
||||
|
||||
if (lang_get_folder()) {
|
||||
texty_knihy = build_pathname(2, lang_get_folder(), "book.txt");
|
||||
if (!check_file_exists(texty_knihy)) {
|
||||
texty_knihy=strdup(build_pathname(2,gpathtable[SR_MAP],"kniha.txt"));
|
||||
} else {
|
||||
texty_knihy=strdup(texty_knihy);
|
||||
}
|
||||
} else {
|
||||
texty_knihy=strdup(build_pathname(2,gpathtable[SR_MAP],"kniha.txt"));
|
||||
return verr;
|
||||
}
|
||||
|
||||
install_gui();
|
||||
if (is_joystick_enabled()) {
|
||||
show_joystick_info();
|
||||
}
|
||||
|
||||
|
||||
|
||||
send_message(E_DONE,E_WATCH,timer);
|
||||
send_message(E_DONE,E_IDLE,redraw_desktop_call);
|
||||
send_message(E_ADD,E_TIMER,timming);
|
||||
|
||||
send_message(E_ADD,E_WATCH,user_timer);
|
||||
|
||||
send_message(E_ADD,E_MOUSE,ms_clicker);
|
||||
|
||||
send_message(E_ADD,E_KEYBOARD,global_kbd);
|
||||
|
||||
send_message(E_ADD,E_PRGERROR,error_exception);
|
||||
|
||||
add_to_timer(TM_BACK_MUSIC,5,-1,back_music);
|
||||
|
||||
add_game_window();
|
||||
|
||||
game_sound_init_device(ini_section_open(cfg, "audio"));
|
||||
start_mixing();
|
||||
|
||||
if ((verr=init_mysky())!=0)
|
||||
{
|
||||
closemode();
|
||||
puts(texty[174-verr]);
|
||||
SEND_LOG("(ERROR) %s (%d)",texty[174-verr],verr);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// hranice_mysky(0,0,639,479);
|
||||
|
||||
mouse_set_default(H_MS_DEFAULT);
|
||||
ukaz_mysku();
|
||||
set_end_of_song_callback(end_of_song_callback, NULL);
|
||||
|
||||
kouzla_init();
|
||||
|
||||
load_items();
|
||||
|
||||
load_shops();
|
||||
memset(&loadlevel,0,sizeof(loadlevel));
|
||||
loadlevel.eflags = 0xFF;
|
||||
|
||||
}
|
||||
|
||||
void wire_main_functs();
|
||||
void unwire_main_functs(void)
|
||||
|
@ -1376,7 +1396,7 @@ static void game_big_circle(char enforced)
|
|||
if (err)
|
||||
{
|
||||
char buff[256];
|
||||
closemode();
|
||||
|
||||
switch (err)
|
||||
{
|
||||
case -1: sprintf(buff,"Error while loading map (%s) ....file not found\n",s);break;
|
||||
|
@ -1713,6 +1733,15 @@ int skeldal_gen_string_table_entry_point(const SKELDAL_CONFIG *start_cfg, const
|
|||
return 0;
|
||||
}
|
||||
|
||||
void skeldal_entry_point_thread() {
|
||||
int start_task = add_task(65536,start);
|
||||
|
||||
escape();
|
||||
|
||||
term_task_wait(start_task);
|
||||
return;
|
||||
}
|
||||
|
||||
int skeldal_entry_point(const SKELDAL_CONFIG *start_cfg)
|
||||
{
|
||||
def_mman_group_table(gpathtable);
|
||||
|
@ -1758,20 +1787,11 @@ int skeldal_entry_point(const SKELDAL_CONFIG *start_cfg)
|
|||
purge_temps(1);
|
||||
clrscr();
|
||||
|
||||
init_skeldal(cfg);
|
||||
|
||||
int start_task = add_task(65536,start);
|
||||
|
||||
escape();
|
||||
|
||||
term_task_wait(start_task);
|
||||
|
||||
closemode();
|
||||
|
||||
|
||||
int r = init_skeldal(cfg, skeldal_entry_point_thread);
|
||||
ini_close(cfg);
|
||||
return r;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@ int cur_event_number;
|
|||
static void event_error(char *text,int number)
|
||||
{
|
||||
char buff[256];
|
||||
closemode();
|
||||
sprintf(buff,"%s\n Specproc num: %d\n",text,number);
|
||||
display_error(buff);
|
||||
exit(1);
|
||||
|
|
|
@ -100,17 +100,6 @@ void showview_lo(word x,word y,word xs,word ys);
|
|||
void outtext(const char *text);
|
||||
void outtext_ex(const char *text, int space);
|
||||
void outtext_w_nl(const char *text);
|
||||
int initmode(const INI_CONFIG_SECTION *, const char *app_name);
|
||||
int initmode32(void);
|
||||
int initmode32b(void);
|
||||
int initmode256(void *paletefile);
|
||||
int initmode256b(void *paletefile);
|
||||
int initmode_lo(void *paletefile);
|
||||
int initmode16(void *paletefile);
|
||||
int initmode64(void *paletefile);
|
||||
int initmode64b(void *paletefile);
|
||||
void *create_hixlat(void);
|
||||
void closemode(void);
|
||||
void line32(word x1,word y1, word x2, word y2);
|
||||
void position(word x,word y);
|
||||
void show_ms_cursor(integer x,integer y);
|
||||
|
|
|
@ -328,14 +328,6 @@ void switchvesabank(word bank)
|
|||
}
|
||||
|
||||
*/
|
||||
int initmode(const INI_CONFIG_SECTION *display_config, const char *app_name)
|
||||
{
|
||||
if (!game_display_init(display_config, app_name)) return -1;
|
||||
showview=game_display_update_rect;
|
||||
screenstate=1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
int initmode256(void *paletefile)
|
||||
|
@ -435,15 +427,6 @@ int initmode_lo(void *paletefile)
|
|||
}
|
||||
*/
|
||||
|
||||
void closemode()
|
||||
{
|
||||
if (screenstate)
|
||||
{
|
||||
game_display_close();
|
||||
}
|
||||
screenstate=0;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
static void showview64b(word x,word y,word xs,word ys)
|
||||
|
|
|
@ -10,7 +10,12 @@ static std::unique_ptr<uint16_t[]> buffer2nd;
|
|||
static uint16_t *render_target;
|
||||
static uint16_t screen_pitch = 640;
|
||||
|
||||
char game_display_init(const INI_CONFIG_SECTION *display_section, const char *title) {
|
||||
int game_display_init(const INI_CONFIG_SECTION *display_section,
|
||||
const char *title,
|
||||
int (*game_thread)(va_list), ...) {
|
||||
|
||||
va_list args;
|
||||
va_start(args,game_thread);
|
||||
|
||||
SDLContext::VideoConfig cfg = {};
|
||||
const char *aspect_str;
|
||||
|
@ -43,19 +48,19 @@ char game_display_init(const INI_CONFIG_SECTION *display_section, const char *ti
|
|||
cfg.cursor_size = ini_get_int(display_section, "cursor_size", 100)*0.01f;
|
||||
|
||||
screen_pitch = 640;
|
||||
get_sdl_global_context().init_video(cfg, title);
|
||||
screen_buffer = std::make_unique<uint16_t[]>(screen_pitch*480);
|
||||
buffer2nd = std::make_unique<uint16_t[]>(screen_pitch*480);
|
||||
std::fill(screen_buffer.get(), screen_buffer.get()+screen_pitch*480,0);
|
||||
render_target = screen_buffer.get();
|
||||
|
||||
return 1;
|
||||
|
||||
|
||||
return get_sdl_global_context().init_window(cfg, title, [&]{
|
||||
screen_buffer = std::make_unique<uint16_t[]>(screen_pitch*480);
|
||||
buffer2nd = std::make_unique<uint16_t[]>(screen_pitch*480);
|
||||
std::fill(screen_buffer.get(), screen_buffer.get()+screen_pitch*480,0);
|
||||
render_target = screen_buffer.get();
|
||||
return game_thread(args);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
void game_display_close(void) {
|
||||
get_sdl_global_context().close_video();
|
||||
}
|
||||
|
||||
uint16_t *GetScreenAdr() {
|
||||
return render_target;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include "../config.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
@ -19,8 +20,11 @@ void RedirectScreen(uint16_t *newaddr);
|
|||
void RestoreScreen(void);
|
||||
void RedirectScreenBufferSecond(void);
|
||||
|
||||
char game_display_init(const INI_CONFIG_SECTION *display_section, const char *title);
|
||||
void game_display_close(void);
|
||||
|
||||
///Initializes display - in current thread (main thread), starts game thread. Display is closed when thread finishes
|
||||
int game_display_init(const INI_CONFIG_SECTION *display_section,
|
||||
const char *title,
|
||||
int (*game_thread)(va_list), ...);
|
||||
void game_display_update_rect(unsigned short x,unsigned short y,unsigned short xs,unsigned short ys);
|
||||
char game_display_is_quit_requested();
|
||||
void game_display_cancel_quit_request();
|
||||
|
|
|
@ -268,14 +268,12 @@ static Uint32 find_best_rgba_like_format(SDL_Renderer* renderer) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void SDLContext::init_video(const VideoConfig &config, const char *title) {
|
||||
int SDLContext::init_window(const VideoConfig &config, const char *title, std::function<int()> game_thread) {
|
||||
static Uint32 update_request_event = SDL_RegisterEvents(1);
|
||||
static Uint32 refresh_request_event = SDL_RegisterEvents(1);
|
||||
_update_request_event = update_request_event;
|
||||
_refresh_request = refresh_request_event;
|
||||
|
||||
assert(!_render_thread.joinable());
|
||||
|
||||
|
||||
int width = config.window_width;
|
||||
int height = config.window_height;
|
||||
|
@ -294,142 +292,132 @@ void SDLContext::init_video(const VideoConfig &config, const char *title) {
|
|||
std::exception_ptr e;
|
||||
std::string_view stage;
|
||||
std::string rname;
|
||||
_render_thread = std::jthread([&](std::stop_token stp){
|
||||
bool err = false;
|
||||
try {
|
||||
stage = "window";
|
||||
SDL_Window *window = SDL_CreateWindow(title,
|
||||
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
||||
width, height, SDL_WINDOW_RESIZABLE|(_fullscreen_mode?SDL_WINDOW_FULLSCREEN_DESKTOP:0));
|
||||
int exit_code = 0;
|
||||
try {
|
||||
stage = "window";
|
||||
SDL_Window *window = SDL_CreateWindow(title,
|
||||
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
||||
width, height, SDL_WINDOW_RESIZABLE|(_fullscreen_mode?SDL_WINDOW_FULLSCREEN_DESKTOP:0));
|
||||
|
||||
if (!window) {
|
||||
handle_sdl_error("SDL Error create window");
|
||||
}
|
||||
|
||||
_window.reset(window);
|
||||
|
||||
auto composer = config.composer;
|
||||
|
||||
stage = "renderer";
|
||||
|
||||
while (true) {
|
||||
|
||||
SDL_Renderer *renderer = SDL_CreateRenderer(_window.get(), -1, composer);
|
||||
if (!renderer) {
|
||||
if (config.composer & SDL_RENDERER_SOFTWARE) {
|
||||
handle_sdl_error("Failed to create composer");
|
||||
} else {
|
||||
composer |= SDL_RENDERER_SOFTWARE;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
_texture_render_format = find_best_rgba_like_format(renderer);
|
||||
if (_texture_render_format == 0) {
|
||||
if (composer & SDL_RENDERER_SOFTWARE) {
|
||||
throw std::runtime_error("Failed to create composer, failed software fallback");
|
||||
} else {
|
||||
SDL_DestroyRenderer(renderer);
|
||||
composer |= SDL_RENDERER_SOFTWARE;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
_renderer.reset(renderer);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
SDL_RendererInfo rinfo;
|
||||
SDL_GetRendererInfo(_renderer.get(), &rinfo);
|
||||
|
||||
rname = rinfo.name;
|
||||
|
||||
stage = "pixel format";
|
||||
|
||||
_main_pixel_format.reset(SDL_AllocFormat(_texture_render_format));
|
||||
if (!_main_pixel_format) {
|
||||
handle_sdl_error("Failed to create texture format");
|
||||
}
|
||||
|
||||
if (istrcmp(config.scale_quality, "auto") == 0) {
|
||||
if (rinfo.flags & SDL_RENDERER_ACCELERATED) {
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "best");
|
||||
}
|
||||
} else {
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, config.scale_quality);
|
||||
}
|
||||
|
||||
|
||||
|
||||
stage = "main render target";
|
||||
|
||||
|
||||
SDL_Texture *texture = SDL_CreateTexture(_renderer.get(), _texture_render_format, SDL_TEXTUREACCESS_STREAMING, 640, 480);
|
||||
if (!texture) {
|
||||
handle_sdl_error("Failed to create render target");
|
||||
}
|
||||
|
||||
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
|
||||
_texture.reset(texture);
|
||||
|
||||
stage = "secondary render target";
|
||||
|
||||
texture = SDL_CreateTexture(_renderer.get(), _texture_render_format, SDL_TEXTUREACCESS_STREAMING, 640, 480);
|
||||
if (!texture) {
|
||||
handle_sdl_error("Failed to create second render target");
|
||||
}
|
||||
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
|
||||
_texture2.reset(texture);
|
||||
|
||||
stage = "all done";
|
||||
|
||||
_visible_texture = _texture.get();
|
||||
_hidden_texture = _texture2.get();
|
||||
} catch (...) {
|
||||
e = std::current_exception();
|
||||
err = true;
|
||||
if (!window) {
|
||||
handle_sdl_error("SDL Error create window");
|
||||
}
|
||||
done = true;
|
||||
done.notify_all();
|
||||
|
||||
if (!err) {
|
||||
_window.reset(window);
|
||||
|
||||
auto composer = config.composer;
|
||||
|
||||
stage = "renderer";
|
||||
|
||||
while (true) {
|
||||
|
||||
SDL_Renderer *renderer = SDL_CreateRenderer(_window.get(), -1, composer);
|
||||
if (!renderer) {
|
||||
if (config.composer & SDL_RENDERER_SOFTWARE) {
|
||||
handle_sdl_error("Failed to create composer");
|
||||
} else {
|
||||
composer |= SDL_RENDERER_SOFTWARE;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
_texture_render_format = find_best_rgba_like_format(renderer);
|
||||
if (_texture_render_format == 0) {
|
||||
if (composer & SDL_RENDERER_SOFTWARE) {
|
||||
throw std::runtime_error("Failed to create composer, failed software fallback");
|
||||
} else {
|
||||
SDL_DestroyRenderer(renderer);
|
||||
composer |= SDL_RENDERER_SOFTWARE;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
_renderer.reset(renderer);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
SDL_RendererInfo rinfo;
|
||||
SDL_GetRendererInfo(_renderer.get(), &rinfo);
|
||||
|
||||
rname = rinfo.name;
|
||||
|
||||
stage = "pixel format";
|
||||
|
||||
_main_pixel_format.reset(SDL_AllocFormat(_texture_render_format));
|
||||
if (!_main_pixel_format) {
|
||||
handle_sdl_error("Failed to create texture format");
|
||||
}
|
||||
|
||||
if (istrcmp(config.scale_quality, "auto") == 0) {
|
||||
if (rinfo.flags & SDL_RENDERER_ACCELERATED) {
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "best");
|
||||
}
|
||||
} else {
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, config.scale_quality);
|
||||
}
|
||||
|
||||
|
||||
|
||||
stage = "main render target";
|
||||
|
||||
|
||||
SDL_Texture *texture = SDL_CreateTexture(_renderer.get(), _texture_render_format, SDL_TEXTUREACCESS_STREAMING, 640, 480);
|
||||
if (!texture) {
|
||||
handle_sdl_error("Failed to create render target");
|
||||
}
|
||||
|
||||
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
|
||||
_texture.reset(texture);
|
||||
|
||||
stage = "secondary render target";
|
||||
|
||||
texture = SDL_CreateTexture(_renderer.get(), _texture_render_format, SDL_TEXTUREACCESS_STREAMING, 640, 480);
|
||||
if (!texture) {
|
||||
handle_sdl_error("Failed to create second render target");
|
||||
}
|
||||
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
|
||||
_texture2.reset(texture);
|
||||
|
||||
stage = "all done";
|
||||
|
||||
_visible_texture = _texture.get();
|
||||
_hidden_texture = _texture2.get();
|
||||
|
||||
std::stop_source stop_src;
|
||||
|
||||
std::thread main_thrd([&]{
|
||||
try {
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
event_loop(stp);
|
||||
exit_code = game_thread();
|
||||
} catch (...) {
|
||||
SDL_ShowCursor(SDL_ENABLE);
|
||||
crash_sdl_exception();
|
||||
e = std::current_exception();
|
||||
}
|
||||
}
|
||||
_texture.reset();
|
||||
_texture2.reset();
|
||||
_renderer.reset();
|
||||
_window.reset();
|
||||
});
|
||||
stop_src.request_stop();
|
||||
});
|
||||
main_thrd.detach();
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
event_loop(stop_src.get_token());
|
||||
SDL_ShowCursor(SDL_ENABLE);
|
||||
|
||||
done.wait(false);
|
||||
if (e) {
|
||||
_render_thread.join();
|
||||
try {
|
||||
std::rethrow_exception(e);
|
||||
} catch (...) {
|
||||
std::throw_with_nested(
|
||||
std::runtime_error(std::string("Oops! The application couldn't start properly (problem during SDL initialization). Stage: [")
|
||||
.append(stage).append("]\n\n"
|
||||
"Renderer: ").append(rname).append("\n\n"
|
||||
"This may be caused by outdated or missing graphics or audio drivers."
|
||||
"To fix this, please try the following:\n- Restart your computer and try again\n- "
|
||||
"Make sure your graphics and sound drivers are up to date.")));
|
||||
}
|
||||
} catch (...) {
|
||||
crash_sdl_exception();
|
||||
return -1;
|
||||
}
|
||||
_texture.reset();
|
||||
_texture2.reset();
|
||||
_renderer.reset();
|
||||
_window.reset();
|
||||
|
||||
if (e) {
|
||||
std::rethrow_exception(e);
|
||||
}
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
void SDLContext::init_video(const VideoConfig &config, const char *title) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
void SDLContext::close_video() {
|
||||
_render_thread.request_stop();
|
||||
_render_thread.join();
|
||||
}
|
||||
|
||||
int SDLContext::check_axis_dir(int &cooldown, int value) {
|
||||
int range = 0x8000-_jcontrol_map.walk_deadzone;
|
||||
|
|
|
@ -98,13 +98,14 @@ public:
|
|||
int freq;
|
||||
};
|
||||
|
||||
int init_window(const VideoConfig &config, const char *title, std::function<int()> game_thread);
|
||||
|
||||
void init_video(const VideoConfig &config, const char *title);
|
||||
|
||||
void set_window_icon(const void *icon_data, size_t icon_size);
|
||||
|
||||
void configure_controller(const JoystickConfig &cfg);
|
||||
|
||||
void close_video();
|
||||
|
||||
AudioInfo init_audio(const AudioConfig &config, SDL_AudioCallback cb, void *cb_ctx);
|
||||
void pause_audio(bool pause);
|
||||
|
@ -272,7 +273,6 @@ protected:
|
|||
Uint32 _update_request_event;
|
||||
Uint32 _refresh_request;
|
||||
|
||||
std::jthread _render_thread;
|
||||
|
||||
|
||||
void event_loop(std::stop_token stp);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue