Files
fs2open.github.com/code/mission/missionload.cpp
T
2004-07-26 20:47:56 +00:00

573 lines
16 KiB
C++

/*
* 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.
*
*/
/*
* $Logfile: /Freespace2/code/Mission/MissionLoad.cpp $
* $Revision: 2.6 $
* $Date: 2004-07-26 20:47:37 $
* $Author: Kazan $
*
* C source module for mission loading
*
* $Log: not supported by cvs2svn $
* Revision 2.5 2004/07/12 16:32:54 Kazan
* MCD - define _MCD_CHECK to use memory tracking
*
* Revision 2.4 2004/03/05 09:02:06 Goober5000
* Uber pass at reducing #includes
* --Goober5000
*
* Revision 2.3 2003/03/18 10:07:03 unknownplayer
* The big DX/main line merge. This has been uploaded to the main CVS since I can't manage to get it to upload to the DX branch. Apologies to all who may be affected adversely, but I'll work to debug it as fast as I can.
*
* Revision 2.2 2002/12/02 23:53:49 Goober5000
* fixed misspelling
*
* Revision 2.1.2.1 2002/09/24 18:56:43 randomtiger
* DX8 branch commit
*
* This is the scub of UP's previous code with the more up to date RT code.
* For full details check previous dev e-mails
*
* Revision 2.1 2002/08/01 01:41:06 penguin
* The big include file move
*
* Revision 2.0 2002/06/03 04:02:25 penguin
* Warpcore CVS sync
*
* Revision 1.1 2002/05/02 18:03:10 mharris
* Initial checkin - converted filenames and includes to lower case
*
*
* 5 7/20/99 1:49p Dave
* Peter Drake build. Fixed some release build warnings.
*
* 4 10/13/98 9:28a Dave
* Started neatening up freespace.h. Many variables renamed and
* reorganized. Added AlphaColors.[h,cpp]
*
* 3 10/07/98 6:27p Dave
* Globalized mission and campaign file extensions. Removed Silent Threat
* special code. Moved \cache \players and \multidata into the \data
* directory.
*
* 2 10/07/98 10:53a Dave
* Initial checkin.
*
* 1 10/07/98 10:49a Dave
*
* 102 5/19/98 1:19p Allender
* new low level reliable socket reading code. Make all missions/campaign
* load/save to data missions folder (i.e. we are rid of the player
* missions folder)
*
* 101 5/10/98 10:05p Allender
* only show cutscenes which have been seen before. Made Fred able to
* write missions anywhere, defaulting to player misison folder, not data
* mission folder. Fix FreeSpace code to properly read missions from
* correct locations
*
* 100 4/30/98 4:53p John
* Restructured and cleaned up cfile code. Added capability to read off
* of CD-ROM drive and out of multiple pack files.
*
* 99 2/23/98 6:55p Lawrance
* Rip out obsolete code.
*
* 98 2/23/98 8:53a John
* String externalization
*
* 97 1/19/98 9:37p Allender
* Great Compiler Warning Purge of Jan, 1998. Used pragma's in a couple
* of places since I was unsure of what to do with code.
*
* 96 1/17/98 8:49p Hoffoss
* Fixed mission_load() calls to handle failure correctly.
*
* 95 12/28/97 1:34p John
* Fixed yet another mission filename bug
*
* 94 12/28/97 12:42p John
* Put in support for reading archive files; Made missionload use the
* cf_get_file_list function. Moved demos directory out of data tree.
*
* 93 12/27/97 2:39p John
* Took out the outdated ui_getfilelist functions. Made the mission load
* screen use cf_get_filelist instead. Fixed a bug in mission load that
* crashed the program if there are no missions available.
*
* 92 12/23/97 12:00p Allender
* change write_pilot_file to *not* take is_single as a default parameter.
* causing multiplayer pilots to get written to the single player folder
*
* 91 11/11/97 4:57p Dave
* Put in support for single vs. multiplayer pilots. Began work on
* multiplayer campaign saving. Put in initial player select screen
*
* 90 10/31/97 11:27a John
* appended path for j:\tmp missions
*
* 89 10/31/97 11:19a John
* added filter category for j:\tmp\*.fsm
*
* 88 10/12/97 5:22p Lawrance
* have ESC back out of mission load screen
*
* 87 9/18/97 10:19p Lawrance
* Add a mission campaign filter to the load screen
*
* 86 9/16/97 2:41p Allender
* beginning of code to change way player starts are handled. Reordered
* some code when missions loading since player ship is now created at
* mission load time instead of before misison load
*
* 85 8/25/97 5:47p Mike
* Increase number of missions supported in mission load list (outside
* campaign) to 256 and Assert() if there are more than 256.
*
* 84 8/20/97 5:19p Hoffoss
* Fixed bug where creating a new pilot causes the mission load mission
* list box to be empty.
*
* 83 7/28/97 10:53a Lawrance
* initialize a timestamp
*
* 82 7/17/97 4:25p John
* First, broken, stage of changing config stuff
*
* 81 7/05/97 1:47p Lawrance
* write pilot file when a mission is loaded
*
* 80 6/26/97 5:53p Lawrance
* save recently played missions, allow player to choose from list
*
* 79 6/12/97 12:39p John
* made ui use freespace colors
*
* 78 6/12/97 11:35a John
* more menu backgrounds
*
* 77 5/14/97 1:33p Allender
* remmoved extern declaration
*
* 76 5/12/97 4:59p Allender
* move the rest of the mission initialization functions into
* game_level_init(). All mission loading now going through this
* fucntion.
*
* 75 5/12/97 3:21p Allender
* re-ordered mission load code into single function in Freespace.
* Simulation part now runs as seperate thread
*
* 74 5/12/97 12:27p John
* Restructured Graphics Library to add support for multiple renderers.
*
* 73 4/28/97 5:43p Lawrance
* allow hotkey assignment screen to work from ship selection
*
* 72 4/25/97 11:31a Allender
* Campaign state now saved in campaign save file in player directory.
* Made some global variables follow naming convention. Solidified
* continuing campaigns based on new structure
*
* 71 4/23/97 4:46p Allender
* remove unused code
*
* 70 4/23/97 3:21p Allender
* more campaign stuff -- mission branching through campaign file now
* works!!!!
*
* 69 4/22/97 10:44a Allender
* more campaign stuff. Info about multiple campaigns now stored in
* player file -- not saving some player information in save games.
*
* 68 4/18/97 9:59a Allender
* more campaign stuff. All campaign related varaibles now stored in
* campaign structure
*
* 67 4/17/97 9:02p Allender
* new campaign stuff. all campaign related material stored in external
* file. Continuing campaign won't work at this time
*
* 66 4/15/97 4:37p Lawrance
* removed unused variables
*
*/
#include "mission/missionload.h"
#include "mission/missionparse.h"
#include "missionui/missionshipchoice.h"
#include "mission/missioncampaign.h"
#include "playerman/managepilot.h"
#include "freespace2/freespace.h"
#include "io/key.h"
#include "gamesequence/gamesequence.h"
#include "ui/ui.h"
#include "globalincs/alphacolors.h"
#include "cfile/cfilesystem.h"
extern mission The_mission; // need to send this info to the briefing
extern int shifted_ascii_table[];
extern int ascii_table[];
// -----------------------------------------------
// 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(char *filename)
{
char tmp[MAX_RECENT_MISSIONS][MAX_FILENAME_LEN], *p;
int i,j;
for ( i = 0; i < Num_recent_missions; i++ ) {
strcpy( tmp[i], Recent_missions[i] );
}
// get a pointer to just the basename of the filename (including extension)
p = strrchr(filename, '\\');
if ( p == NULL ) {
p = filename;
} else {
p++;
}
Assert(strlen(p) < MAX_FILENAME_LEN);
strcpy( Recent_missions[0], p );
j = 1;
for ( i = 0; i < Num_recent_missions; i++ ) {
if ( stricmp(Recent_missions[0], tmp[i]) ) {
strcpy(Recent_missions[j++], tmp[i]);
if ( j >= MAX_RECENT_MISSIONS ) {
break;
}
}
}
Num_recent_missions = j;
Assert(Num_recent_missions <= MAX_RECENT_MISSIONS);
}
// Mission_load takes no parameters.
// It expects the following global variables to be set correctly:
// Game_current_mission_filename
// returns -1 if failed, 0 if successful
int mission_load()
{
char filename[128], *ext;
mprintf(("MISSION LOAD: '%s'\n", Game_current_mission_filename));
strncpy(filename, Game_current_mission_filename, 127);
ext = strchr(filename, '.');
if (ext) {
mprintf(( "Hmmm... Extension passed to mission_load...\n" ));
*ext = 0; // remove any extension!
}
strcat(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 -1;
if (Select_default_ship) {
int ret;
ret = create_default_player_ship();
Assert(!ret);
}
ml_update_recent_missions(Game_current_mission_filename); // update recently played missions list
write_pilot_file();
return 0;
}
//====================================
// 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(wild_card, NOX("*"));
strcat(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(Campaign_name_list[i+1], Campaign_names[i]);
}
strcpy(Campaign_name_list[0], NOX("All campaigns"));
strcpy(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 = 0;
}
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(mission_name, mlm_missions[selected]);
} else if (Campaign_filter_index == 1 ) {
strcpy( mission_name, jtmp_missions[selected]);
} else {
strcpy(mission_name, Campaign_missions[selected]);
}
strncpy( mission_name_final, mission_name, MAX_FILENAME_LEN );
}
// go
#ifdef PD_BUILD
// if this valid
if((game_find_builtin_mission(mission_name_final) != NULL) || strstr(mission_name_final, "peterdrake")){
strcpy(Game_current_mission_filename, mission_name_final);
mprintf(( "Selected '%s'\n", Game_current_mission_filename ));
gameseq_post_event(GS_EVENT_START_GAME);
}
#else
strcpy(Game_current_mission_filename, mission_name_final);
mprintf(( "Selected '%s'\n", Game_current_mission_filename ));
gameseq_post_event(GS_EVENT_START_GAME);
#endif
}
gr_clear();
gr_set_color_fast( &Color_bright );
gr_printf( 0x8000, 10, NOX("Select Mission") );
gr_printf( 50, 135, NOX("Campaign Filter"));
gr_printf( 250, 135, NOX("Recently Played"));
gr_printf( 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<mlm_nfiles; i++ ) {
if (mlm_missions[i] ) {
free(mlm_missions[i]);
mlm_missions[i] = NULL;
}
}
for (i=0; i<jtmp_nfiles; i++ ) {
if (jtmp_missions[i] ) {
free(jtmp_missions[i]);
jtmp_missions[i] = NULL;
}
}
mlm_window.destroy();
}