int extract_iso(uniso_status_t *s, struct archive *iso, const char *dst, distro_filter_f filter, uniso_progress_t total, uniso_progress_cb cb, void *cb_data) { struct archive_entry *e; uniso_progress_t current = 0; make_dir_parents(dst); if(cb) cb(current, total, cb_data); while(archive_read_next_header(iso, &e) == ARCHIVE_OK) { char *name = unix_path(strdup2(archive_entry_pathname(e))); if(archive_entry_filetype(e) == AE_IFDIR || !filter(name)) { free(name); continue; } s->files = new_string_node_t(name, s->files); char *dest = unix_path(create_dest(dst, "/", name)); if(!extract_file(s, iso, dest)) { free(dest); return 0; } ++current; if(cb) cb(current, total, cb_data); free(dest); } return 1; }
int install_grub2(lickdir_t *lick) { char *grub_cfg_lick = unix_path(concat_strs(2, lick->drive, "/lickgrub.cfg")); if(!path_exists(grub_cfg_lick)) { char *grub_cfg_header = unix_path(concat_strs(2, lick->res, "/lickgrub.cfg")); if(!copy_file(grub_cfg_lick, grub_cfg_header)) { free(grub_cfg_lick); free(grub_cfg_header); if(!lick->err) lick->err = strdup2("Error writing to grub menu."); return 0; } free(grub_cfg_header); } free(grub_cfg_lick); return 1; }
char *open_file_dialog(void) { OPENFILENAME ofn; static char szFile[MAX_PATH]; static char szOldDir[MAX_PATH]; static int old_dir_set = 0; ZeroMemory( &ofn , sizeof( ofn)); ofn.lStructSize = sizeof ( ofn ); ofn.hwndOwner = NULL ; ofn.lpstrFile = szFile ; ofn.lpstrFile[0] = '\0'; ofn.nMaxFile = sizeof( szFile ); ofn.lpstrFilter = "*.*\0*.*\0main.lua;*.zip;*.idf\0main.lua;*.zip;*.idf\0\0"; ofn.nFilterIndex = 2; ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0; if (!old_dir_set) ofn.lpstrInitialDir = NULL; else ofn.lpstrInitialDir = szOldDir; ofn.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_READONLY; if (!GetOpenFileName(&ofn)) return NULL; old_dir_set = 1; strcpy(szOldDir, ofn.lpstrFile); dirname(szOldDir); unix_path(ofn.lpstrFile); return ofn.lpstrFile; }
int uninstall_grub2(lickdir_t *lick) { char drive = mount_uefi_partition(); if(drive == '\0') { if(!lick->err) lick->err = strdup2("Could not mount EFI partition."); return 0; } if(!fix_grub2_inner(lick, GRUB2_FIX_UNINSTALL, drive)) { unmount_uefi_partition(drive); if(!lick->err) lick->err = strdup2("Could not revert boot fix."); return 0; } char *grub_cfg = unix_path(concat_strs(2, lick->drive, "/lickgrub.cfg")); if(!has_valuable_info(grub_cfg)) { unlink_file(grub_cfg); } free(grub_cfg); char *lick_cert = strdup2("?:/lick.cer"); lick_cert[0] = drive; unlink_file(lick_cert); free(lick_cert); char lick_dir[] = "?:/EFI/LICK"; lick_dir[0] = drive; unlink_recursive(lick_dir); unmount_uefi_partition(drive); return 1; }
char *sdl_path(char *p) { char *r = mbs2utf8(p); if (p) free(p); unix_path(r); return r; }
uniso_status_t *undir(const char *src, const char *dst, distro_filter_f filter, uniso_progress_cb cb, void *cb_data) { uniso_status_t *s = new_status(); make_dir_parents(dst); struct dirent **e; const int len = scandir2(src, &e, NULL, NULL); if (len == -1) return s; int failed = 0; if(cb) cb(0, len, cb_data); for(uniso_progress_t i = 0; i < (unsigned int)len; /* Updated in loop. */) { if(!failed) { char *path = unix_path(concat_strs(3, src, "/", e[i]->d_name)); if(file_type(path) != FILE_TYPE_DIR && filter(e[i]->d_name)) { char *dst_path = unix_path(concat_strs(3, dst, "/", e[i]->d_name)); if(copy_file(dst_path, path)) { s->files = new_string_node_t(strdup(e[i]->d_name), s->files); // If we are copying directly from a CD, the file will be // read-only. This causes problems when we try to delete // the files. attrib_open(dst_path); } else { failed = 1; } free(dst_path); } free(path); } free(e[i]); ++i; if(cb) cb(i, len, cb_data); } free(e); s->finished = 1; return s; }
char *dirpath(const char *path) { static char fp[PATH_MAX * 4]; if (path[0] == '/') return (char*)path; snprintf(fp, sizeof(fp), "%s/%s", curdir, path); fp[sizeof(fp) - 1] = 0; unix_path(fp); return fp; }
char *home_dir( void ) { static char homedir[PATH_MAX]=""; SHGetFolderPath( NULL, CSIDL_FLAG_CREATE | CSIDL_PROFILE, NULL, 0, (LPTSTR)homedir ); unix_path(homedir); return homedir; }
char *game_tmp_path(void) { DWORD dwRetVal = 0; static TCHAR lpTempPathBuffer[MAX_PATH]; // Gets the temp path env string (no guarantee it's a valid path). dwRetVal = GetTempPath(MAX_PATH, // length of the buffer lpTempPathBuffer); // buffer for path if (dwRetVal > MAX_PATH || (dwRetVal == 0)) { return NULL; } strcat((char*)lpTempPathBuffer, "/instead-games"); if (mkdir((char*)lpTempPathBuffer) && errno != EEXIST) return NULL; unix_path((char*)lpTempPathBuffer); return (char*)lpTempPathBuffer; }
char *getfilepath(const char *d, const char *n) { int i = ((d)?strlen(d):0) + ((n)?strlen(n):0) + 3; char *p = malloc(i); if (p) { p[0] = 0; if (d && d[0]) { /* non empty string */ strcpy(p, d); if (p[strlen(d) - 1] != '/') strcat(p, "/"); } if (n) strcat(p, n); unix_path(p); } return p; }
static int run_game(const char *path) { char *p, *ep, *d; static char gp[PATH_MAX + 1]; static char *cd = "./"; if (!path) return -1; if (!path[0]) return -1; if (strlen(path) >= PATH_MAX) return -1; strcpy(gp, path); p = gp; unix_path(p); ep = p + strlen(p) - 1; while (*ep == '/' && ep != p) *ep-- = 0; if (!p[0]) return -1; ep = p + strlen(p) - 1; while (ep != p) { if (*ep == '/') { *ep ++ = 0; break; } ep --; } if (ep == p) d = cd; else d = p; if (!is_game(d, ep)) { fprintf(stderr, "%s/%s is not a game path.\n", d, ep); return -1; } game_sw = ep; games_sw = d; return 0; }
char *app_dir( void ) { static char appdir[PATH_MAX]=""; #ifdef _LOCAL_APPDATA if (appdata_sw) strcpy(appdir, appdata_sw); else { strcpy(appdir, game_cwd); strcat(appdir, "/appdata"); } if (!access(appdir, W_OK)) return appdir; #endif SHGetFolderPath( NULL, CSIDL_FLAG_CREATE | CSIDL_LOCAL_APPDATA, NULL, 0, (LPTSTR)appdir ); unix_path(appdir); strcat(appdir, "/instead"); return appdir; }
int remove_grub2(const char *id, lickdir_t *lick) { char *menu_path = unix_path(concat_strs(2, lick->drive, "/lickgrub.cfg")); int ret = flat_remove_section(menu_path, id, lick); free(menu_path); return ret; }
void wince_init(char *path) { unix_path(path); strcpy(game_cwd, getcurdir(path)); }
char *getrealpath(const char *path, char *resolved) { const char *q; char *p, *fres; size_t len; #if defined(unix) && !defined(S60) struct stat sb; ssize_t n; int idx = 0, nlnk = 0; char wbuf[2][PATH_MAX]; #endif /* POSIX sez we must test for this */ if (path == NULL) { return NULL; } if (resolved == NULL) { fres = resolved = malloc(PATH_MAX); if (resolved == NULL) return NULL; } else fres = NULL; /* * Build real path one by one with paying an attention to ., * .. and symbolic link. */ /* * `p' is where we'll put a new component with prepending * a delimiter. */ p = resolved; if (*path == '\0') { *p = '\0'; goto out; } /* If relative path, start from current working directory. */ if (!is_absolute_path(path)) { /* check for resolved pointer to appease coverity */ if (getdir(resolved, PATH_MAX) == NULL) { p[0] = '.'; p[1] = '\0'; goto out; } unix_path(resolved); len = strlen(resolved); if (len > 1) p += len; } loop: /* Skip any slash. */ while (*path == '/') path++; if (*path == '\0') { if (p == resolved) *p++ = '/'; *p = '\0'; return resolved; } /* Find the end of this component. */ q = path; do q++; while (*q != '/' && *q != '\0'); /* Test . or .. */ if (path[0] == '.') { if (q - path == 1) { path = q; goto loop; } if (path[1] == '.' && q - path == 2) { /* Trim the last component. */ if (p != resolved) while (*--p != '/' && p != resolved) continue; path = q; goto loop; } } /* Append this component. */ if (p - resolved + 1 + q - path + 1 > PATH_MAX) { if (p == resolved) *p++ = '/'; *p = '\0'; goto out; } if (p == resolved && is_absolute_path(path) && path[0] != '/') { /* win? */ memcpy(&p[0], path, q - path); p[q - path] = '\0'; p += q - path; path = q; goto loop; } else { p[0] = '/'; memcpy(&p[1], path, /* LINTED We know q > path. */ q - path); p[1 + q - path] = '\0'; } #if defined(unix) && !defined(S60) /* * If this component is a symlink, toss it and prepend link * target to unresolved path. */ if (lstat(resolved, &sb) != -1 && S_ISLNK(sb.st_mode)) { if (nlnk++ >= 16) { goto out; } n = readlink(resolved, wbuf[idx], sizeof(wbuf[0]) - 1); if (n < 0) goto out; if (n == 0) { goto out; } /* Append unresolved path to link target and switch to it. */ if (n + (len = strlen(q)) + 1 > sizeof(wbuf[0])) { goto out; } memcpy(&wbuf[idx][n], q, len + 1); path = wbuf[idx]; idx ^= 1; /* If absolute symlink, start from root. */ if (*path == '/') p = resolved; goto loop; } #endif /* Advance both resolved and unresolved path. */ p += 1 + q - path; path = q; goto loop; out: free(fres); return NULL; }
int fix_grub2_inner(lickdir_t *lick, grub2_fix_function function, char original_drive) { char drive = original_drive; if(!drive) { drive = mount_uefi_partition(); if(!drive) { lick->err = strdup2("Could not mount UEFI partition."); return 0; } } char *lick_grub = strdup2("?:/efi/lick/" GRUB2_EFI); char *lick_shim = strdup2("?:/efi/lick/shim.efi"); char *lick_mokmanager = strdup2("?:/efi/lick/" MOKMANAGER_EFI); char *boot_grub = strdup2("?:/efi/boot/" GRUB2_EFI); char *boot_shim = strdup2("?:/efi/boot/shim.efi"); char *boot_mokmanager = strdup2("?:/efi/boot/" MOKMANAGER_EFI); char *boot_file = strdup("?:/efi/boot/bootx64.efi"); char *boot_file_backup = strdup2("?:/efi/boot/bootx64-orig.efi"); char *ms_loader = strdup2("?:/efi/microsoft/boot/bootmgfw.efi"); char *ms_loader_backup = strdup2("?:/efi/microsoft/boot/bootmgfw-backup.efi"); char *grub_cfg = unix_path(concat_strs(2, lick->drive, "/lickgrub.cfg")); char *grub_menu = NULL; lick_grub[0] = drive; lick_shim[0] = drive; lick_mokmanager[0] = drive; boot_grub[0] = drive; boot_shim[0] = drive; boot_mokmanager[0] = drive; ms_loader[0] = drive; ms_loader_backup[0] = drive; boot_file[0] = drive; boot_file_backup[0] = drive; const char *fatal_warning = "WARNING! The fix has only been half applied.\n" "The system may not boot when rebooted.\n" "Find out why renaming files on the UEFI partition is not working,\n" "then move `/EFI/Microsoft` to `/EFI/Microsoft-backup`."; grub2_fix_status status = GRUB2_FIX_UNINSTALLED; if(path_exists(boot_grub) || path_exists(boot_mokmanager) || path_exists(ms_loader_backup) || path_exists(boot_file_backup)) { if(path_exists(boot_grub) && path_exists(boot_mokmanager) && path_exists(ms_loader_backup) && path_exists(boot_file_backup)) status = GRUB2_FIX_INSTALLED; else status = GRUB2_FIX_PARTLY_INSTALLED; } int ret = 0; if(function == GRUB2_FIX_CHECK) { if(status == GRUB2_FIX_INSTALLED) ret = 1; } else if(status == GRUB2_FIX_PARTLY_INSTALLED) lick->err = strdup2("Partial boot fix applied."); else if(function == GRUB2_FIX_INSTALL && status == GRUB2_FIX_INSTALLED) lick->err = strdup2("Boot fix already applied!"); else if(function == GRUB2_FIX_UNINSTALL && status == GRUB2_FIX_UNINSTALLED) ret = 1; else if(function == GRUB2_FIX_INSTALL) { /* Steps: * 1) Copy `/EFI/LICK/{grubx64,shim,MokManager}.efi` to `/EFI/Boot/` * 2) Rename `/EFI/Boot/bootx64.efi` to `bootx64-orig.efi` * 3) Rename `/EFI/Boot/shim.efi` to `bootx64.efi` * 4) Rename `/EFI/Microsoft/Boot/bootmgfw.efi` to `bootmgfw-backup.efi` */ do { int fail = 1; do { if(!copy_file(boot_grub, lick_grub)) break; if(!copy_file(boot_shim, lick_shim)) break; if(!copy_file(boot_mokmanager, lick_mokmanager)) break; if(!copy_file(boot_file_backup, boot_file)) break; attrib_t boot_attrs = attrib_open(boot_file); if(!replace_file(boot_file, boot_shim)) { attrib_save(boot_file, boot_attrs); lick->err = strdup2("Could not overwrite boot file."); break; } if(!rename_file(ms_loader_backup, ms_loader)) { // Try to restore the backup. if(!replace_file(boot_file, boot_file_backup)) { // At this point we are stuck with the fix being // half applied. Realistically, this should never occur. attrib_save(boot_file, boot_attrs); lick->err = strdup2(fatal_warning); fail = 0; break; } lick->err = strdup2("Could not rename directory."); break; } attrib_save(boot_file_backup, boot_attrs); fail = 0; } while(0); if(fail) { unlink_file(boot_grub); unlink_file(boot_shim); unlink_file(boot_mokmanager); unlink_file(boot_file_backup); if(!lick->err) lick->err = strdup2("Could not copy files on EFI partition."); break; } // Edit grub menu. FILE *f = fopen(grub_cfg, "r"); if(!f) { if(!lick->err) lick->err = strdup2("Successfully installed, but could not modify configuration file."); break; } grub_menu = file_to_str(f); fclose(f); char *grub_menu_lower = lower_str(strdup2(grub_menu)); // Search for `/efi/microsoft` (case insensitive) // and replace with `/efi/microsoft-backup` // First, find the number of `/efi/microsoft` size_t cnt = 0; const char *str = grub_menu_lower; const char *needle = "/efi/microsoft/boot/bootmgfw.efi"; const char *replacement = "/efi/microsoft/boot/bootmgfw-backup.efi"; for(;;) { str = strstr(str, needle); if(!str) break; ++cnt; ++str; // Increment string to find the next occurrance. } if(cnt > 0) { /* Here, there are 3 strings: * - The original menu, grub_menu. * This is pointed to by start and str_normal. * - The lowercase menu, grub_menu_lower. * This is pointed to by str. * - The new menu, new_grub_menu. * This is pointed to by dst. */ size_t newsize = strlen(grub_menu) + cnt * (strlen(replacement) - strlen(needle)) + 1; char *new_grub_menu = malloc(newsize); char *dst = new_grub_menu; const char *start = grub_menu; str = grub_menu_lower; for(size_t i = 0; i < cnt; ++i) { str = strstr(str, needle); const char *str_normal = str - grub_menu_lower + grub_menu; // Print everything from start to str. size_t len = str_normal - start; memcpy(dst, start, len); dst += len; strcpy(dst, replacement); str += strlen(needle); dst += strlen(replacement); start = str_normal + strlen(needle); } strcpy(dst, start); grub_menu[newsize - 1] = '\0'; f = fopen(grub_cfg, "w"); if(!f) { if(!lick->err) lick->err = strdup2("Successfully installed, but could not modify configuration file."); free(new_grub_menu); free(grub_menu_lower); break; } fprintf(f, "%s", new_grub_menu); fclose(f); free(new_grub_menu); free(grub_menu_lower); } ret = 1; } while(0); } else { /* Steps: * 1) Rename `/EFI/Microsoft/Boot/bootmgfw-backup.efi` to `bootmgfw.efi` * 2) Rename `/EFI/Boot/bootx64-orig.efi` to `bootx64.efi` * 3) Delete `/EFI/Boot/{grubx64,MokManager}.efi` */ do { if(!rename_file(ms_loader, ms_loader_backup)) { lick->err = strdup2("Could not rename directory."); break; } attrib_t boot_attrs = attrib_open(boot_file_backup); if(!replace_file(boot_file, boot_file_backup)) { attrib_save(boot_file_backup, boot_attrs); if(!rename_file(ms_loader_backup, ms_loader)) { lick->err = strdup2(fatal_warning); break; } lick->err = strdup2("Could not replace boot file."); break; } attrib_save(boot_file, boot_attrs); unlink_file(boot_grub); unlink_file(boot_mokmanager); ret = 1; } while(0); } if(!original_drive) unmount_uefi_partition(drive); free(lick_grub); free(lick_shim); free(lick_mokmanager); free(boot_grub); free(boot_shim); free(boot_mokmanager); free(ms_loader); free(ms_loader_backup); free(boot_file); free(boot_file_backup); free(grub_cfg); free(grub_menu); return ret; }
char *boot_ini_path_with_drive(const char *boot_drive) { return unix_path(concat_strs(3, boot_drive, "/", BOOT_FILE)); }
int main(int argc, char *argv[]) { #ifdef _USE_UNPACK int clean_tmp = 0; #endif int err = 0; int i; #ifdef __APPLE__ macosx_init(); #endif #ifndef S60 putenv("SDL_MOUSE_RELATIVE=0"); /* test this! */ #endif #ifdef _WIN32_WCE libwince_init(argv[0], 1); wince_init(argv[0]); #else #ifdef S60 extern char s60_data[]; strcpy(game_cwd, s60_data); #else #ifdef _WIN32 strcpy(game_cwd, dirname(argv[0])); #else if (!getcwd(game_cwd, sizeof(game_cwd))) fprintf(stderr,"Warning: can not get current dir\n."); #endif #endif #endif unix_path(game_cwd); setdir(game_cwd); for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-vsync")) vsync_sw = 1; else if (!strcmp(argv[i], "-nosound")) nosound_sw = 1; else if (!strcmp(argv[i], "-fullscreen")) fullscreen_sw = 1; else if (!strcmp(argv[i], "-mode")) { if ((i + 1) < argc) mode_sw = argv[++i]; else mode_sw = "-1x-1"; } else if (!strcmp(argv[i], "-window")) window_sw = 1; else if (!strcmp(argv[i], "-debug")) { if (!debug_sw) debug_init(); debug_sw = 1; } else if (!strcmp(argv[i], "-owntheme")) owntheme_sw = 1; else if (!strcmp(argv[i], "-noautosave")) noauto_sw = 1; else if (!strcmp(argv[i], "-game")) { if ((i + 1) < argc) game_sw = argv[++i]; else game_sw = ""; } else if (!strcmp(argv[i], "-theme")) { if ((i + 1) < argc) theme_sw = argv[++i]; else theme_sw = ""; } else if (!strcmp(argv[i], "-nostdgames")) { nostdgames_sw = 1; #ifdef _LOCAL_APPDATA } else if (!strcmp(argv[i], "-appdata")) { if ((i + 1) < argc) appdata_sw = argv[++i]; else appdata_sw = ""; #endif } else if (!strcmp(argv[i], "-chunksize")) { if ((i + 1) < argc) chunksize_sw = atoi(argv[++i]); else chunksize_sw = DEFAULT_CHUNKSIZE; } else if (!strcmp(argv[i], "-gamespath")) { if ((i + 1) < argc) games_sw = argv[++i]; else games_sw = ""; } else if (!strcmp(argv[i], "-themespath")) { if ((i + 1) < argc) themes_sw = argv[++i]; else themes_sw = ""; } else if (!strcmp(argv[i], "-idf")) { if ((i + 1) < argc) idf_sw = argv[++i]; else { fprintf(stderr,"No data directory specified.\n"); err = 1; goto out; } } else if (!strcmp(argv[i], "-encode")) { if ((i + 1) < argc) encode_sw = argv[++i]; else { fprintf(stderr,"No lua file specified.\n"); err = 1; goto out; } if ((i + 1) < argc) encode_output = argv[++i]; else encode_output = "lua.enc"; } else if (!strcmp(argv[i], "-version")) { version_sw = 1; } else if (!strcmp(argv[i], "-nopause")) { nopause_sw = 1; } else if (!strcmp(argv[i], "-software")) { software_sw = 1; #ifdef _USE_UNPACK } else if (!strcmp(argv[i], "-install")) { if ((i + 1) < argc) { char *file = argv[++i]; char *p; if (games_sw) p = games_sw; else p = game_local_games_path(1); if (setup_zip(file, p)) { err = 1; goto out; } } #endif } else if (!strcmp(argv[i], "-quit")) { exit(0); } else if (!strcmp(argv[i], "-hinting")) { if ((i + 1) < argc) hinting_sw = atoi(argv[++i]); else hinting_sw = 1; } else if (!strcmp(argv[i], "-lua") || !strcmp(argv[i], "-luac")) { if ((i + 1) < argc) { lua_exec = !strcmp(argv[i], "-lua"); lua_sw = argv[++ i]; opt_index = i + 1; break; } else { fprintf(stderr, "No lua script.\n"); err = 1; goto out; } } else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "-help") || !strcmp(argv[i], "--help")) { usage(); goto out; } else if (argv[i][0] == '-') { fprintf(stderr,"Unknown option: %s\n", argv[i]); usage(); err = 1; goto out; } else if (!start_idf(argv[i])) { fprintf(stderr, "Adding idf: %s\n", argv[i]); } else if (!run_game(argv[i])) { fprintf(stderr, "Opening game: %s\n", argv[i]); } #ifdef _USE_UNPACK else { char *p; if (games_sw) p = games_sw; else p = game_tmp_path(); if (setup_zip(argv[i], p)) { err = 1; goto out; } clean_tmp = 1; } #endif } cfg_load(); if (opt_debug == 1 && debug_sw == 0) { debug_sw = 1; debug_init(); } if (opt_vsync == 1 && vsync_sw == 0) vsync_sw = 1; if (version_sw) { fprintf(stdout, VERSION"\n"); goto out; } if (lua_sw) { err = instead_init_lua(dirname(lua_sw)); if (err) goto out; if (!err) err = instead_loadscript(lua_sw, argc - opt_index, argv + opt_index, lua_exec); instead_done(); goto out; } if (encode_sw) { err = instead_encode(encode_sw, encode_output); goto out; } if (idf_sw) { char *p = malloc(strlen(idf_sw) + 5); if (p) { char *b; strcpy(p, idf_sw); b = basename(p); strcat(b, ".idf"); idf_create(b, idf_sw); free(p); } else idf_create("data.idf", idf_sw); goto out; } menu_langs_lookup(dirpath(LANG_PATH)); if (!langs_nr) { fprintf(stderr, "No languages found in: %s.\n", dirpath(LANG_PATH)); err = 1; goto out; } if (!opt_lang || !opt_lang[0]) opt_lang = game_locale(); if (menu_lang_select(opt_lang) && menu_lang_select(LANG_DEF)) { fprintf(stderr, "Can not load default language.\n"); err = 1; goto out; } if (games_sw) games_lookup(games_sw); if (owntheme_sw && !opt_owntheme) { opt_owntheme = 2; } if (!nostdgames_sw && games_lookup(dirpath(GAMES_PATH))) fprintf(stderr, "No games found in: %s.\n", GAMES_PATH); if (themes_sw) themes_lookup(themes_sw); if (!nostdthemes_sw) { themes_lookup(dirpath(THEMES_PATH)); themes_lookup(game_local_themes_path()); } if (!nostdgames_sw) games_lookup(game_local_games_path(0)); if (start_idf_sw) { char *d, *b; char *dd, *bb; static char idf_game[255]; d = strdup(start_idf_sw); b = strdup(start_idf_sw); if (d && b) { dd = dirname(d); bb = basename(b); if (!games_replace(dirpath(dd), bb)) { game_sw = idf_game; strncpy(idf_game, bb, sizeof(idf_game) - 1); idf_game[sizeof(idf_game) - 1] = 0; } } if (d) free(d); if (b) free(b); } if (noauto_sw && opt_autosave) opt_autosave = 2; if (window_sw) opt_fs = 0; if (fullscreen_sw) opt_fs = 1; if (mode_sw) parse_mode(mode_sw, opt_mode); if (game_sw) { FREE(opt_game); opt_game = game_sw; } if (theme_sw) { FREE(opt_theme); opt_theme = theme_sw; } if (opt_theme) game_theme_select(opt_theme); if (!curtheme_dir) game_theme_select(DEFAULT_THEME); /* Initialize SDL */ if (gfx_init() < 0) return -1; #ifdef _USE_GTK gtk_init(&argc, &argv); /* must be called AFTER SDL_Init when using SDL2 */ #endif if (gfx_video_init() || input_init()) return -1; if (game_init(opt_game)) { game_error(); } game_loop(); cfg_save(); game_done(0); gfx_video_done(); #ifndef ANDROID gfx_done(); #endif out: if (debug_sw) debug_done(); #ifdef _USE_GTK /* gtk_main_quit (); */ #endif #ifdef _USE_UNPACK if (clean_tmp) remove_dir(game_tmp_path()); #endif #if defined(ANDROID) || defined(IOS) exit(err); #endif return err; }