/* * Copyright (C) Volition, Inc. 1999. All rights reserved. * * All source code herein is the property of Volition, Inc. You may not sell * or otherwise commercially exploit the source or things you created based on the * source. * */ #include "cfile/cfilesystem.h" #include "freespace.h" #include "gamesequence/gamesequence.h" #include "globalincs/alphacolors.h" #include "hud/hudparse.h" #include "io/key.h" #include "events/events.h" #include "mission/missioncampaign.h" #include "mission/missionload.h" #include "mission/missionparse.h" #include "missionui/missionshipchoice.h" #include "playerman/managepilot.h" #include "ui/ui.h" #include "tracing/tracing.h" extern mission The_mission; // need to send this info to the briefing extern int shifted_ascii_table[]; extern int ascii_table[]; SCP_vector Ignored_missions; // ----------------------------------------------- // For recording most recent missions played // ----------------------------------------------- char Recent_missions[MAX_RECENT_MISSIONS][MAX_FILENAME_LEN]; int Num_recent_missions; // ----------------------------------------------------- // ml_update_recent_missions() // // Update the Recent_missions[][] array // void ml_update_recent_missions(const char* filename) { char tmp[MAX_RECENT_MISSIONS][MAX_FILENAME_LEN]; int i,j; for ( i = 0; i < Num_recent_missions; i++ ) { strcpy_s( tmp[i], Recent_missions[i] ); } // get a pointer to just the basename of the filename (including extension) const char* p = strrchr(filename, DIR_SEPARATOR_CHAR); if ( p == NULL ) { p = filename; } else { p++; } Assert(strlen(p) < MAX_FILENAME_LEN); strcpy_s( Recent_missions[0], p ); j = 1; for ( i = 0; i < Num_recent_missions; i++ ) { if ( stricmp(Recent_missions[0], tmp[i]) != 0 ) { strcpy_s(Recent_missions[j++], tmp[i]); if ( j >= MAX_RECENT_MISSIONS ) { break; } } } Num_recent_missions = j; Assert(Num_recent_missions <= MAX_RECENT_MISSIONS); } bool mission_is_ignored(const char *filename) { SCP_string filename_no_ext = filename; drop_extension(filename_no_ext); SCP_tolower(filename_no_ext); for (auto &ii: Ignored_missions) { if (ii == filename_no_ext) { return true; } } return false; } // Mission_load takes no parameters. // It sets the following global variables // Game_current_mission_filename // returns true successful, false if failed bool mission_load(const char* filename_ext) { TRACE_SCOPE(tracing::LoadMissionLoad); char filename[MAX_PATH_LEN], *ext; if ( (filename_ext != NULL) && (Game_current_mission_filename != filename_ext) ) strncpy(Game_current_mission_filename, filename_ext, MAX_FILENAME_LEN-1); mprintf(("MISSION LOAD: '%s'\n", filename_ext)); events::GameMissionLoad(filename_ext); strcpy_s( filename, filename_ext ); ext = strrchr(filename, '.'); if (ext) { mprintf(( "Hmmm... Extension passed to mission_load...\n" )); *ext = 0; // remove any extension! } if (mission_is_ignored(filename)) { mprintf(("MISSION LOAD: Tried to load an ignored mission! Aborting...\n")); return false; } strcat_s(filename, FS_MISSION_FILE_EXT); // does the magical mission parsing // creates all objects, except for the player object // save the player object later since the player may get // to choose the type of ship that he is to fly // return value of 0 indicates success, other is failure. if ( !parse_main(filename) ) return false; if (Select_default_ship) { // no last flown ship (new pilot, or its ship isn't in this mod): the popup says so, the mission's ship is kept create_default_player_ship(); } ml_update_recent_missions(filename_ext); // update recently played missions list (save the csg later) control_reset_hook(); init_hud(); return true; } //==================================== // Mission Load Menu stuff #define MLM_MAX_MISSIONS 256 int mlm_active=0; UI_WINDOW mlm_window; UI_LISTBOX mlm_mission_list; UI_LISTBOX recent_mission_list; UI_LISTBOX campaign_filter; UI_BUTTON mlm_ok, mlm_cancel; char * mlm_missions[MLM_MAX_MISSIONS]; char * recent_missions[MAX_RECENT_MISSIONS]; char * campaign_names[MAX_CAMPAIGNS+2]; char * campaign_missions[MAX_CAMPAIGN_MISSIONS]; int mlm_nfiles = 0; static int last_recent_current = -1; static int last_mlm_current = -1; static int Campaign_filter_index; char * jtmp_missions[MLM_MAX_MISSIONS]; int jtmp_nfiles = 0; void ml_change_listbox() { if ( !Num_recent_missions || !mlm_nfiles ) return; if ( mlm_mission_list.current() != -1 ) { mlm_mission_list.set_current(-1); last_mlm_current = -1; recent_mission_list.set_focus(); recent_mission_list.set_current(0); return; } if ( recent_mission_list.current() != -1 ) { recent_mission_list.set_current(-1); last_recent_current = -1; mlm_mission_list.set_focus(); mlm_mission_list.set_current(0); return; } } static char Campaign_missions[MAX_CAMPAIGN_MISSIONS][NAME_LENGTH]; static char Campaign_name_list[MAX_CAMPAIGNS+2][NAME_LENGTH]; static int Num_campaign_missions; // get the mission filenames that make up a campaign extern int mission_campaign_get_filenames(char *filename, char dest[][NAME_LENGTH], int *num); void mission_load_menu_init() { int i; char wild_card[256]; Assert( mlm_active == 0 ); mlm_active = 1; memset(wild_card, 0, 256); strcpy_s(wild_card, NOX("*")); strcat_s(wild_card, FS_MISSION_FILE_EXT); mlm_nfiles = cf_get_file_list( MLM_MAX_MISSIONS, mlm_missions, CF_TYPE_MISSIONS, wild_card, CF_SORT_NAME ); jtmp_nfiles = 0; Assert(mlm_nfiles <= MLM_MAX_MISSIONS); mlm_window.create( 100,100,500,300, 0 ); //WIN_DIALOG mlm_ok.create( &mlm_window, NOX("Ok"), 125, 420, 80, 40 ); mlm_cancel.create( &mlm_window, NOX("Cancel"), 250, 420, 80, 40 ); mlm_cancel.set_hotkey( KEY_ESC ); mlm_mission_list.create( &mlm_window, 450, 150, 150, 200, mlm_nfiles, mlm_missions ); for ( i = 0; i < Num_recent_missions; i++ ) { recent_missions[i] = Recent_missions[i]; } recent_mission_list.create( &mlm_window, 250, 150, 150, 200, Num_recent_missions, recent_missions ); mlm_mission_list.set_focus(); mlm_mission_list.set_current(0); mission_campaign_build_list(0); for ( i = 0; i < Num_campaigns; i++ ) { strcpy_s(Campaign_name_list[i+1], Campaign_names[i]); } strcpy_s(Campaign_name_list[0], NOX("All campaigns")); strcpy_s(Campaign_name_list[1], NOX("Player Missions")); for ( i = 0; i < Num_campaigns+2; i++ ) { campaign_names[i] = Campaign_name_list[i]; } campaign_filter.create( &mlm_window, 50, 150, 150, 200, Num_campaigns+2, campaign_names ); Campaign_filter_index = 0; campaign_filter.set_current(Campaign_filter_index); } void mission_load_menu_do() { int selected, key_in, recent_current, mlm_current, use_recent_flag, i; Assert( mlm_active == 1 ); key_in = mlm_window.process(); if ( key_in ) { switch ( key_in & KEY_MASK ) { case KEY_UP: case KEY_DOWN: case KEY_HOME: case KEY_END: case KEY_PAGEUP: case KEY_PAGEDOWN: case KEY_ENTER: break; case KEY_RIGHT: case KEY_LEFT: ml_change_listbox(); break; case KEY_ESC: gameseq_post_event(GS_EVENT_MAIN_MENU); break; default: break; } // end switch } if ( campaign_filter.current() != Campaign_filter_index ) { Campaign_filter_index = campaign_filter.current(); if ( Campaign_filter_index > 1 ) { mission_campaign_get_filenames(Campaign_file_names[Campaign_filter_index-2], Campaign_missions, &Num_campaign_missions); for ( i = 0; i < Num_campaign_missions; i++ ) { campaign_missions[i] = Campaign_missions[i]; } mlm_mission_list.set_new_list(Num_campaign_missions, campaign_missions); } else if ( Campaign_filter_index == 0 ) { mlm_mission_list.set_new_list(mlm_nfiles, mlm_missions); } else if ( Campaign_filter_index == 1 ) { mlm_mission_list.set_new_list(jtmp_nfiles, jtmp_missions); } } mlm_current = mlm_mission_list.current(); recent_current = recent_mission_list.current(); if ( mlm_current != last_mlm_current ) { recent_mission_list.set_current(-1); last_recent_current = -1; } last_mlm_current = mlm_current; if ( recent_current != last_recent_current ) { mlm_mission_list.set_current(-1); last_mlm_current = -1; } last_recent_current = recent_current; if (mlm_cancel.pressed()) gameseq_post_event(GS_EVENT_MAIN_MENU); // Check if they hit OK, if so, use the current listbox // selection. selected = -1; use_recent_flag = 0; if (mlm_ok.pressed()) { selected = mlm_mission_list.current(); if ( selected == -1 ) { selected = recent_mission_list.current(); use_recent_flag = 1; } } else { // If they didn't hit OK, then check for a double-click on // a list box item. selected = mlm_mission_list.selected(); if ( selected == -1 ) { selected = recent_mission_list.selected(); use_recent_flag = 1; } } char mission_name_final[512] = ""; if ( selected > -1 ) { Campaign.current_mission = -1; if ( use_recent_flag ) { strncpy( mission_name_final, recent_missions[selected], MAX_FILENAME_LEN ); } else { char mission_name[NAME_LENGTH]; if ( Campaign_filter_index == 0 ) { strcpy_s(mission_name, mlm_missions[selected]); } else if (Campaign_filter_index == 1 ) { strcpy_s( mission_name, jtmp_missions[selected]); } else { strcpy_s(mission_name, Campaign_missions[selected]); } strncpy( mission_name_final, mission_name, MAX_FILENAME_LEN ); } // go strcpy_s(Game_current_mission_filename, mission_name_final); mprintf(( "Selected '%s'\n", Game_current_mission_filename )); gameseq_post_event(GS_EVENT_START_GAME); } gr_clear(); gr_set_color_fast( &Color_bright ); int w; gr_get_string_size(&w, NULL, NOX("Select Mission")); gr_printf_menu( (gr_screen.clip_width_unscaled - w) / 2, 10, NOX("Select Mission") ); gr_printf_menu( 50, 135, NOX("Campaign Filter")); gr_printf_menu( 250, 135, NOX("Recently Played")); gr_printf_menu( 450, 135, NOX("Mission List")); mlm_window.draw(); gr_flip(); } void mission_load_menu_close() { int i; Assert( mlm_active == 1 ); mlm_active = 0; for (i=0; i