#include "TZR.h" #include "TZR_globals.h" #include "sdl_error.h" #include #include #include #include #include #include static int _sdl_error(void) { sdl_error(-1); TZR_Quit(); return -1; } int _TZR_Init(const TZR_Config *config) { memcpy(&___tzr_config, config, sizeof(TZR_Config)); if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) return _sdl_error(); if (___tzr_config.mixer == TZR_MIXER_FLAC && Mix_Init(MIX_INIT_FLAC) != MIX_INIT_FLAC) { TZR_Log("%s", Mix_GetError()); ___tzr_config.mixer = TZR_MIXER_OFF; } int chdir_rv; if (___tzr_config.basepath == NULL) { char *const basepath = SDL_GetBasePath(); if (basepath == NULL) return _sdl_error(); chdir_rv = chdir(basepath); SDL_free(basepath); } else chdir_rv = chdir(___tzr_config.basepath); if (chdir_rv < 0) return TZR_Log("%s", strerror(errno)), TZR_Quit(), -1; ___tzr_window = SDL_CreateWindow(config->title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, ___tzr_config.width * ___tzr_config.ratio * ___tzr_config.scale, ___tzr_config.height * ___tzr_config.scale, SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL); if (___tzr_window == NULL) { ___tzr_window = SDL_CreateWindow(config->title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, ___tzr_config.width * ___tzr_config.ratio * ___tzr_config.scale, ___tzr_config.height * ___tzr_config.scale, SDL_WINDOW_RESIZABLE ); } if (___tzr_window == NULL) return _sdl_error(); #ifdef TZR_OPENGL ___tzr_gl_ctx = SDL_GL_CreateContext(___tzr_window); if (___tzr_gl_ctx == NULL) { TZR_Log("%s", SDL_GetError()); ___tzr_config.mipmaps = false; } else if (___tzr_config.mipmaps) do { const char *gl_version = (const char *)glGetString(GL_VERSION); if (gl_version == NULL || strlen(gl_version) < 3) { ___tzr_config.mipmaps = false; break; } const int major = atoi(gl_version); const int minor = atoi(gl_version + 2); if (major < 3) ___tzr_config.mipmaps = false; } while (0); #endif /* TZR_OPENGL */ #ifdef __EMSCRIPTEN__ /* TODO: verify than this is unneeded */ ___tzr_renderer = SDL_CreateRenderer(___tzr_window, -1, SDL_RENDERER_SOFTWARE); #else ___tzr_renderer = SDL_CreateRenderer(___tzr_window, -1, SDL_RENDERER_ACCELERATED); if (___tzr_renderer == NULL) { TZR_Log("%s", SDL_GetError()); ___tzr_renderer = SDL_CreateRenderer(___tzr_window, -1, SDL_RENDERER_SOFTWARE); } #endif /* __EMSCRIPTEN__ */ if (___tzr_renderer == NULL) return _sdl_error(); if (TZR_SetViewportSize(___tzr_config.width, ___tzr_config.height)) { TZR_Quit(); return -1; } SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, ___tzr_config.scale_linear ? "1" : "0"); ___tzr_tick = 0; if (___tzr_config.target_fps > 0) { ___tzr_min_dt = 1000 / ___tzr_config.target_fps; ___tzr_next_time = SDL_GetTicks64(); } if (!___tzr_config.show_cursor) SDL_ShowCursor(SDL_FALSE); ___tzr_mouse_x = ___tzr_config.width / 2; ___tzr_mouse_y = ___tzr_config.height / 2; /* Setup audio. */ do if (___tzr_config.mixer) { if (Mix_OpenAudio(48000, MIX_DEFAULT_FORMAT, 8, 1024) < 0) { sdl_error(0); Mix_Quit(); ___tzr_config.mixer = false; break; } #ifdef TZR_SOLOUD ___tzr_soloud = Soloud_create(); if (___tzr_soloud == NULL) { TZR_Log("Soloud_create failed"); Mix_Quit(); ___tzr_config.mixer = false; break; } if (Soloud_init(___tzr_soloud)) { TZR_Log("Soloud_init failed"); Soloud_destroy(___tzr_soloud); ___tzr_soloud = NULL; Mix_Quit(); ___tzr_config.mixer = false; break; } #endif /* TZR_SOLOUD */ } while (0); return 0; }