int MakeNewPlayerFile(int allow_abort) { int x; char filename[14]; newmenu_item m; char text[CALLSIGN_LEN+1]=""; FILE *fp; strncpy(text, Players[Player_num].callsign,CALLSIGN_LEN); try_again: m.type=NM_TYPE_INPUT; m.text_len = 8; m.text = text; Newmenu_allowed_chars = playername_allowed_chars; x = newmenu_do( NULL, TXT_ENTER_PILOT_NAME, 1, &m, NULL ); Newmenu_allowed_chars = NULL; if ( x < 0 ) { if ( allow_abort ) return 0; goto try_again; } if (text[0]==0) //null string goto try_again; sprintf( filename, "%s.plr", text ); fp = fopen( filename, "rb" ); //if the callsign is the name of a tty device, prepend a char if (fp && isatty(fileno(fp))) { fclose(fp); sprintf(filename,"$%.7s.plr",text); fp = fopen(filename,"rb"); } if ( fp ) { nm_messagebox(NULL, 1, TXT_OK, "%s '%s' %s", TXT_PLAYER, text, TXT_ALREADY_EXISTS ); fclose(fp); goto try_again; } if ( !new_player_config() ) goto try_again; // They hit Esc during New player config strncpy(Players[Player_num].callsign, text, CALLSIGN_LEN); init_game_list(); //init to defaults write_player_file(); return 1; }
int MakeNewPlayerFile(int allow_abort) { int x; char filename[14]; newmenu_item m; char text[CALLSIGN_LEN+1]=""; strncpy(text, Players[Player_num].callsign,CALLSIGN_LEN); try_again: m.type=NM_TYPE_INPUT; m.text_len = 8; m.text = text; Newmenu_allowed_chars = playername_allowed_chars; x = newmenu_do( NULL, TXT_ENTER_PILOT_NAME, 1, &m, NULL ); Newmenu_allowed_chars = NULL; if ( x < 0 ) { if ( allow_abort ) return 0; goto try_again; } if (text[0]==0) //null string goto try_again; strlwr(text); sprintf( filename, GameArg.SysUsePlayersDir? "Players/%s.plr" : "%s.plr", text ); if (PHYSFS_exists(filename)) { nm_messagebox(NULL, 1, TXT_OK, "%s '%s' %s", TXT_PLAYER, text, TXT_ALREADY_EXISTS ); goto try_again; } if ( !new_player_config() ) goto try_again; // They hit Esc during New player config strncpy(Players[Player_num].callsign, text, CALLSIGN_LEN); strlwr(Players[Player_num].callsign); write_player_file(); return 1; }
//read in the player's saved games. returns errno (0 == no error) int read_player_file() { char filename[PATH_MAX]; PHYSFS_file *file; int player_file_size, shareware_file = -1, id = 0; short saved_game_version, player_struct_version; Assert(Player_num>=0 && Player_num<MAX_PLAYERS); memset(filename, '\0', PATH_MAX); snprintf(filename, PATH_MAX, GameArg.SysUsePlayersDir? "Players/%.8s.plr" : "%.8s.plr", Players[Player_num].callsign); if (!PHYSFSX_exists(filename,0)) return ENOENT; file = PHYSFSX_openReadBuffered(filename); if (!file) goto read_player_file_failed; new_player_config(); // Set defaults! // Unfortunatly d1x has been writing both shareware and registered // player files with a saved_game_version of 7 and 8, whereas the // original decent used 4 for shareware games and 7 for registered // games. Because of this the player files didn't get properly read // when reading d1x shareware player files in d1x registered or // vica versa. The problem is that the sizeof of the taunt macros // differ between the share and registered versions, causing the // reading of the player file to go wrong. Thus we now determine the // sizeof the player file to determine what kinda player file we are // dealing with so that we can do the right thing PHYSFS_seek(file, 0); player_file_size = PHYSFS_fileLength(file); PHYSFS_readSLE32(file, &id); saved_game_version = PHYSFSX_readShort(file); player_struct_version = PHYSFSX_readShort(file); PlayerCfg.NHighestLevels = PHYSFSX_readInt(file); PlayerCfg.DefaultDifficulty = PHYSFSX_readInt(file); PlayerCfg.AutoLeveling = PHYSFSX_readInt(file); if (id!=SAVE_FILE_ID) { nm_messagebox(TXT_ERROR, 1, TXT_OK, "Invalid player file"); PHYSFS_close(file); return -1; } if (saved_game_version<COMPATIBLE_SAVED_GAME_VERSION || player_struct_version<COMPATIBLE_PLAYER_STRUCT_VERSION) { nm_messagebox(TXT_ERROR, 1, TXT_OK, TXT_ERROR_PLR_VERSION); PHYSFS_close(file); return -1; } /* determine if we're dealing with a shareware or registered playerfile */ switch (saved_game_version) { case 4: shareware_file = 1; break; case 5: case 6: shareware_file = 0; break; case 7: /* version 7 doesn't have the saved games array */ if ((player_file_size - (sizeof(hli)*PlayerCfg.NHighestLevels)) == (2212 - sizeof(saved_games))) shareware_file = 1; if ((player_file_size - (sizeof(hli)*PlayerCfg.NHighestLevels)) == (2252 - sizeof(saved_games))) shareware_file = 0; break; case 8: if ((player_file_size - (sizeof(hli)*PlayerCfg.NHighestLevels)) == 2212) shareware_file = 1; if ((player_file_size - (sizeof(hli)*PlayerCfg.NHighestLevels)) == 2252) shareware_file = 0; /* d1x-rebirth v0.31 to v0.42 broke things by adding stuff to the player struct without thinking (sigh) */ if ((player_file_size - (sizeof(hli)*PlayerCfg.NHighestLevels)) == (2212 + 2*sizeof(int))) { shareware_file = 1; /* skip the cruft added to the player_info struct */ PHYSFS_seek(file, PHYSFS_tell(file)+2*sizeof(int)); } if ((player_file_size - (sizeof(hli)*PlayerCfg.NHighestLevels)) == (2252 + 2*sizeof(int))) { shareware_file = 0; /* skip the cruft added to the player_info struct */ PHYSFS_seek(file, PHYSFS_tell(file)+2*sizeof(int)); } } if (shareware_file == -1) { nm_messagebox(TXT_ERROR, 1, TXT_OK, "Error invalid or unknown\nplayerfile-size"); PHYSFS_close(file); return -1; } if (saved_game_version <= 5) { //deal with old-style highest level info PlayerCfg.HighestLevels[0].Shortname[0] = 0; //no name for mission 0 PlayerCfg.HighestLevels[0].LevelNum = PlayerCfg.NHighestLevels; //was highest level in old struct //This hack allows the player to start on level 8 if he's made it to //level 7 on the shareware. We do this because the shareware didn't //save the information that the player finished level 7, so the most //we know is that he made it to level 7. if (PlayerCfg.NHighestLevels==7) PlayerCfg.HighestLevels[0].LevelNum = 8; } else { //read new highest level info if (PHYSFS_read(file,PlayerCfg.HighestLevels,sizeof(hli),PlayerCfg.NHighestLevels) != PlayerCfg.NHighestLevels) goto read_player_file_failed; } if ( saved_game_version != 7 ) { // Read old & SW saved games. if (PHYSFS_read(file,saved_games,sizeof(saved_games),1) != 1) goto read_player_file_failed; } //read taunt macros { int i; int len = shareware_file? 25:35; #ifdef NETWORK for (i = 0; i < 4; i++) if (PHYSFS_read(file, PlayerCfg.NetworkMessageMacro[i], len, 1) != 1) goto read_player_file_failed; #else i = 0; PHYSFS_seek( file, PHYSFS_tell(file)+4*len ); #endif } //read kconfig data { ubyte dummy_joy_sens; if (PHYSFS_read(file, &PlayerCfg.KeySettings[0], sizeof(PlayerCfg.KeySettings[0]),1)!=1) goto read_player_file_failed; if (PHYSFS_read(file, &PlayerCfg.KeySettings[1], sizeof(PlayerCfg.KeySettings[1]),1)!=1) goto read_player_file_failed; PHYSFS_seek( file, PHYSFS_tell(file)+(sizeof(ubyte)*MAX_CONTROLS*3) ); // Skip obsolete Flightstick/Thrustmaster/Gravis map fields if (PHYSFS_read(file, &PlayerCfg.KeySettings[2], sizeof(PlayerCfg.KeySettings[2]),1)!=1) goto read_player_file_failed; PHYSFS_seek( file, PHYSFS_tell(file)+(sizeof(ubyte)*MAX_CONTROLS) ); // Skip obsolete Cyberman map field if (PHYSFS_read(file, &PlayerCfg.ControlType, sizeof(ubyte), 1 )!=1) goto read_player_file_failed; else if (PHYSFS_read(file, &dummy_joy_sens, sizeof(ubyte), 1 )!=1) goto read_player_file_failed; } if ( saved_game_version != 7 ) { int i, found=0; Assert( N_SAVE_SLOTS == 10 ); for (i=0; i<N_SAVE_SLOTS; i++ ) { if ( saved_games[i].name[0] ) { state_save_old_game(i, saved_games[i].name, &saved_games[i].sg_player, saved_games[i].difficulty_level, saved_games[i].primary_weapon, saved_games[i].secondary_weapon, saved_games[i].next_level_num ); // make sure we do not do this again, which would possibly overwrite // a new newstyle savegame saved_games[i].name[0] = 0; found++; } } if (found) write_player_file(); } if (!PHYSFS_close(file)) goto read_player_file_failed; filename[strlen(filename) - 4] = 0; strcat(filename, ".plx"); read_player_d1x(filename); kc_set_controls(); return EZERO; read_player_file_failed: nm_messagebox(TXT_ERROR, 1, TXT_OK, "%s\n\n%s", "Error reading PLR file", PHYSFS_getLastError()); if (file) PHYSFS_close(file); return -1; }