/** * @brief Player death menu, appears when player got creamed. */ void menu_death (void) { unsigned int wid; wid = window_create( "Death", -1, -1, DEATH_WIDTH, DEATH_HEIGHT ); /* Propose the player to continue if the samegame exist, if not, propose to restart */ char path[PATH_MAX]; snprintf(path, PATH_MAX, "%ssaves/%s.ns", nfile_basePath(), player_name); if (nfile_fileExists(path)) window_addButton( wid, 20, 20 + BUTTON_HEIGHT*2 + 20*2, BUTTON_WIDTH, BUTTON_HEIGHT, "btnContinue", "Continue", menu_death_continue ); else window_addButton( wid, 20, 20 + BUTTON_HEIGHT*2 + 20*2, BUTTON_WIDTH, BUTTON_HEIGHT, "btnRestart", "Restart", menu_death_restart ); window_addButton( wid, 20, 20 + (BUTTON_HEIGHT+20), BUTTON_WIDTH, BUTTON_HEIGHT, "btnMain", "Main Menu", menu_death_main ); window_addButton( wid, 20, 20, BUTTON_WIDTH, BUTTON_HEIGHT, "btnExit", "Exit Game", menu_exit ); menu_Open(MENU_DEATH); /* Makes it all look cooler since everything still goes on. */ unpause_game(); }
/** * @brief Opens the load game menu. */ void load_game_menu (void) { unsigned int wid; char **files; int nfiles, i, len; /* window */ wid = window_create( "Load Game", -1, -1, LOAD_WIDTH, LOAD_HEIGHT ); window_setCancel( wid, load_menu_close ); /* load the saves */ files = nfile_readDir( &nfiles, "%ssaves", nfile_basePath() ); for (i=0; i<nfiles; i++) { len = strlen(files[i]); /* no save extension */ if ((len < 5) || strcmp(&files[i][len-3],".ns")) { free(files[i]); memmove( &files[i], &files[i+1], sizeof(char*) * (nfiles-i-1) ); nfiles--; i--; } else /* remove the extension */ files[i][len-3] = '\0'; } /* case there are no files */ if (files == NULL) { files = malloc(sizeof(char*)); files[0] = strdup("None"); nfiles = 1; } window_addList( wid, 20, -50, LOAD_WIDTH-BUTTON_WIDTH-50, LOAD_HEIGHT-110, "lstSaves", files, nfiles, 0, NULL ); /* buttons */ window_addButton( wid, -20, 20, BUTTON_WIDTH, BUTTON_HEIGHT, "btnBack", "Back", load_menu_close ); window_addButton( wid, -20, 30 + BUTTON_HEIGHT, BUTTON_WIDTH, BUTTON_HEIGHT, "btnLoad", "Load", load_menu_load ); window_addButton( wid, 20, 20, BUTTON_WIDTH, BUTTON_HEIGHT, "btnDelete", "Del", load_menu_delete ); /* default action */ window_setAccept( wid, load_menu_load ); }
/** * @brief Deletes an old game. * @param wdw Window to delete. * @param str Unused. */ static void load_menu_delete( unsigned int wdw, char *str ) { (void)str; char *save, path[PATH_MAX]; int wid; wid = window_get( "Load Game" ); save = toolkit_getList( wid, "lstSaves" ); if (strcmp(save,"None") == 0) return; if (dialogue_YesNo( "Permanently Delete?", "Are you sure you want to permanently delete '%s'?", save) == 0) return; snprintf( path, PATH_MAX, "%ssaves/%s.ns", nfile_basePath(), save ); remove(path); /* remove is portable and will call unlink on linux. */ /* need to reload the menu */ load_menu_close(wdw, NULL); load_game_menu(); }
/** * @brief Loads a new game. * @param wdw Window triggering function. * @param str Unused. */ static void load_menu_load( unsigned int wdw, char *str ) { (void)str; char *save, path[PATH_MAX]; int wid; wid = window_get( "Load Game" ); save = toolkit_getList( wid, "lstSaves" ); if (strcmp(save,"None") == 0) return; snprintf( path, PATH_MAX, "%ssaves/%s.ns", nfile_basePath(), save ); /* Close menus before loading for proper rendering. */ load_menu_close(wdw, NULL); menu_main_close(); if (load_game( path )) { menu_main(); load_game_menu(); } }
/** * @brief Reload the current savegame. */ void reload (void) { char path[PATH_MAX]; snprintf(path, PATH_MAX, "%ssaves/%s.ns", nfile_basePath(), player_name); load_game( path ); }
/** * @brief Saves the current game. * * @return 0 on success. */ int save_all (void) { char file[PATH_MAX]; xmlDocPtr doc; xmlTextWriterPtr writer; /* Create the writer. */ writer = xmlNewTextWriterDoc(&doc, conf.save_compress); if (writer == NULL) { ERR("testXmlwriterDoc: Error creating the xml writer"); return -1; } /* Set the writer parameters. */ xmlTextWriterSetIndentString(writer, (const xmlChar*)" "); xmlTextWriterSetIndent(writer, 1); /* Start element. */ xmlw_start(writer); xmlw_startElem(writer,"naev_save"); /* Save the version and such. */ xmlw_startElem(writer,"version"); xmlw_elem( writer, "naev", "%d.%d.%d", VMAJOR, VMINOR, VREV ); xmlw_elem( writer, "data", "%s", ndata_name() ); xmlw_endElem(writer); /* "version" */ /* Save the data. */ if (save_data(writer) < 0) { ERR("Trying to save game data"); goto err_writer; } /* Finish element. */ xmlw_endElem(writer); /* "naev_save" */ xmlw_done(writer); /* Write to file. */ if (nfile_dirMakeExist("%ssaves", nfile_basePath()) < 0) { WARN("Aborting save..."); goto err_writer; } snprintf(file, PATH_MAX, "%ssaves/%s.ns", nfile_basePath(), player_name); /* Back up old savegame. */ if (nfile_backupIfExists(file) < 0) { WARN("Aborting save..."); goto err_writer; } /* Critical section, if crashes here player's game gets corrupted. * Luckily we have a copy just in case... */ xmlFreeTextWriter(writer); if (xmlSaveFileEnc(file, doc, "UTF-8") < 0) { WARN("Failed to write savegame! You'll most likely have to restore it by copying your backup savegame over your current savegame."); goto err; } xmlFreeDoc(doc); return 0; err_writer: xmlFreeTextWriter(writer); err: xmlFreeDoc(doc); return -1; }
/** * @brief The entry point of NAEV. * * @param[in] argc Number of arguments. * @param[in] argv Array of argc arguments. * @return EXIT_SUCCESS on success. */ int main( int argc, char** argv ) { char buf[PATH_MAX]; /* Save the binary path. */ binary_path = argv[0]; /* Print the version */ LOG( " "APPNAME" v%s", naev_version(0) ); #ifdef GIT_COMMIT DEBUG( " git HEAD at " GIT_COMMIT ); #endif /* GIT_COMMIT */ /* Initializes SDL for possible warnings. */ SDL_Init(0); /* Set up debug signal handlers. */ debug_sigInit(); /* Create the home directory if needed. */ if (nfile_dirMakeExist("%s", nfile_basePath())) WARN("Unable to create naev directory '%s'", nfile_basePath()); /* Must be initialized before input_init is called. */ if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) { WARN("Unable to initialize SDL Video: %s", SDL_GetError()); return -1; } /* Get desktop dimensions. */ #if SDL_VERSION_ATLEAST(1,2,10) const SDL_VideoInfo *vidinfo = SDL_GetVideoInfo(); gl_screen.desktop_w = vidinfo->current_w; gl_screen.desktop_h = vidinfo->current_h; #else /* #elif SDL_VERSION_ATLEAST(1,2,10) */ gl_screen.desktop_w = 0; gl_screen.desktop_h = 0; #endif /* #elif SDL_VERSION_ATLEAST(1,2,10) */ /* We'll be parsing XML. */ LIBXML_TEST_VERSION xmlInitParser(); /* Input must be initialized for config to work. */ input_init(); /* Set the configuration. */ snprintf(buf, PATH_MAX, "%s"CONF_FILE, nfile_basePath()); conf_setDefaults(); /* set the default config values */ conf_loadConfig(buf); /* Lua to parse the configuration file */ conf_parseCLI( argc, argv ); /* parse CLI arguments */ /* Enable FPU exceptions. */ #if !(HAS_WIN32) && defined(DEBUGGING) if (conf.fpu_except) feenableexcept( FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW ); #endif /* DEBUGGING */ /* Open data. */ if (ndata_open() != 0) ERR("Failed to open ndata."); /* Load the data basics. */ LOG(" %s", ndata_name()); DEBUG(); /* Display the SDL Version. */ print_SDLversion(); DEBUG(); /* random numbers */ rng_init(); /* * OpenGL */ if (gl_init()) { /* initializes video output */ ERR("Initializing video output failed, exiting..."); SDL_Quit(); exit(EXIT_FAILURE); } window_caption(); gl_fontInit( NULL, NULL, FONT_SIZE ); /* initializes default font to size */ gl_fontInit( &gl_smallFont, NULL, FONT_SIZE_SMALL ); /* small font */ /* Display the load screen. */ loadscreen_load(); loadscreen_render( 0., "Initializing subsystems..." ); time = SDL_GetTicks(); /* * Input */ if ((conf.joystick_ind >= 0) || (conf.joystick_nam != NULL)) { if (joystick_init()) WARN("Error initializing joystick input"); if (conf.joystick_nam != NULL) { /* use the joystick name to find a joystick */ if (joystick_use(joystick_get(conf.joystick_nam))) { WARN("Failure to open any joystick, falling back to default keybinds"); input_setDefault(); } free(conf.joystick_nam); } else if (conf.joystick_ind >= 0) /* use a joystick id instead */ if (joystick_use(conf.joystick_ind)) { WARN("Failure to open any joystick, falling back to default keybinds"); input_setDefault(); } } /* * OpenAL - Sound */ if (conf.nosound) { LOG("Sound is disabled!"); sound_disabled = 1; music_disabled = 1; } if (sound_init()) WARN("Problem setting up sound!"); music_choose("load"); /* Misc graphics init */ if (nebu_init() != 0) { /* Initializes the nebula */ /* An error has happened */ ERR("Unable to initialize the Nebula subsystem!"); /* Weirdness will occur... */ } gui_init(); /* initializes the GUI graphics */ toolkit_init(); /* initializes the toolkit */ map_init(); /* initializes the map. */ cond_init(); /* Initialize conditional subsystem. */ /* Data loading */ load_all(); /* Unload load screen. */ loadscreen_unload(); /* Start menu. */ menu_main(); /* Force a minimum delay with loading screen */ if ((SDL_GetTicks() - time) < NAEV_INIT_DELAY) SDL_Delay( NAEV_INIT_DELAY - (SDL_GetTicks() - time) ); time = SDL_GetTicks(); /* initializes the time */ /* * main loop */ SDL_Event event; /* flushes the event loop since I noticed that when the joystick is loaded it * creates button events that results in the player starting out acceling */ while (SDL_PollEvent(&event)); /* primary loop */ while (!quit) { while (SDL_PollEvent(&event)) { /* event loop */ if (event.type == SDL_QUIT) quit = 1; /* quit is handled here */ input_handle(&event); /* handles all the events and player keybinds */ } main_loop(); } /* Save configuration. */ conf_saveConfig(buf); /* cleanup some stuff */ player_cleanup(); /* cleans up the player stuff */ gui_free(); /* cleans up the player's GUI */ weapon_exit(); /* destroys all active weapons */ pilots_free(); /* frees the pilots, they were locked up :( */ cond_exit(); /* destroy conditional subsystem. */ land_exit(); /* Destroys landing vbo and friends. */ /* data unloading */ unload_all(); /* cleanup opengl fonts */ gl_freeFont(NULL); gl_freeFont(&gl_smallFont); /* Close data. */ ndata_close(); /* Destroy conf. */ conf_cleanup(); /* Frees some memory the configuration allocated. */ /* exit subsystems */ map_exit(); /* destroys the map. */ toolkit_exit(); /* kills the toolkit */ ai_exit(); /* stops the Lua AI magic */ joystick_exit(); /* releases joystick */ input_exit(); /* cleans up keybindings */ nebu_exit(); /* destroys the nebula */ gl_exit(); /* kills video output */ sound_exit(); /* kills the sound */ news_exit(); /* destroys the news. */ /* Free the icon. */ if (naev_icon) free(naev_icon); SDL_Quit(); /* quits SDL */ /* all is well */ exit(EXIT_SUCCESS); }