/* * 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/MenuUI/ReadyRoom.cpp $ * $Revision: 2.14 $ * $Date: 2005-02-23 04:51:56 $ * $Author: taylor $ * * Ready Room code, which is the UI screen for selecting Campaign/mission to play next mainly. * * $Log: not supported by cvs2svn $ * Revision 2.13 2005/02/18 20:50:40 wmcoolmon * Fixed line misalignment at nonstandard res in the campaign room * * Revision 2.12 2004/10/31 21:53:24 taylor * new pilot code support, no-multiplayer and compiler warning fixes, center mouse cursor for redalert missions * * Revision 2.11 2004/07/26 20:47:37 Kazan * remove MCD complete * * Revision 2.10 2004/07/12 16:32:53 Kazan * MCD - define _MCD_CHECK to use memory tracking * * Revision 2.9 2004/04/10 16:55:45 Goober5000 * quashed the slider bug! * --Goober5000 * * Revision 2.8 2004/03/05 09:01:53 Goober5000 * Uber pass at reducing #includes * --Goober5000 * * Revision 2.7 2003/09/05 04:25:28 Goober5000 * well, let's see here... * * * persistent variables * * rotating gun barrels * * positive/negative numbers fixed * * sexps to trigger whether the player is controlled by AI * * sexp for force a subspace jump * * I think that's it :) * --Goober5000 * * Revision 2.6 2003/04/06 03:56:54 Goober5000 * fixed some scrolling issues; added scroll bar to mission select * --Goober5000 * * Revision 2.5 2003/04/05 11:09:22 Goober5000 * fixed some fiddly bits with scrolling and ui stuff * --Goober5000 * * Revision 2.4 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.3 2003/03/03 04:28:37 Goober5000 * fixed the tech room bug! yay! * --Goober5000 * * Revision 2.2 2002/10/19 03:50:29 randomtiger * Added special pause mode for easier action screenshots. * Added new command line parameter for accessing all single missions in tech room. - RT * * Revision 2.1.2.2 2002/11/04 21:25:00 randomtiger * * When running in D3D all ani's are memory mapped for speed, this takes up more memory but stops gametime locking of textures which D3D8 hates. * Added new command line tag Cmdline_d3dlowmem for people who dont want to make use of this because they have no memory. * Cleaned up some more texture stuff enabled console debug for D3D. * * 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:24 penguin * Warpcore CVS sync * * Revision 1.2 2002/05/04 04:52:22 mharris * 1st draft at porting * * Revision 1.1 2002/05/02 18:03:09 mharris * Initial checkin - converted filenames and includes to lower case * * * 20 9/30/99 5:59p Jefff * fixed compile error in OEM ver * * 19 9/08/99 12:28p Jefff * * 18 9/06/99 6:38p Dave * Improved CD detection code. * * 17 9/02/99 2:33p Jefff * column heading coordinate changes * * 16 8/22/99 4:16p Jefff * scroll button coord fixes * * 15 7/20/99 1:49p Dave * Peter Drake build. Fixed some release build warnings. * * 14 7/19/99 2:13p Dave * Added some new strings for Heiko. * * 13 7/15/99 9:20a Andsager * FS2_DEMO initial checkin * * 12 7/09/99 5:54p Dave * Seperated cruiser types into individual types. Added tons of new * briefing icons. Campaign screen. * * 11 2/01/99 5:55p Dave * Removed the idea of explicit bitmaps for buttons. Fixed text * highlighting for disabled gadgets. * * 10 1/30/99 9:01p Dave * Coord fixes. * * 9 1/30/99 5:08p Dave * More new hi-res stuff.Support for nice D3D textures. * * 8 1/29/99 12:47a Dave * Put in sounds for beam weapon. A bunch of interface screens (tech * database stuff). * * 7 12/11/98 4:35p Andsager * Fix sim room bug when no standalone missions * * 6 12/07/98 5:02p Dan * Removed improper use of bitmap filename with extension, * * 5 10/13/98 9:28a Dave * Started neatening up freespace.h. Many variables renamed and * reorganized. Added AlphaColors.[h,cpp] * * * $NoKeywords: $ */ #include #include "menuui/readyroom.h" #include "graphics/font.h" #include "ui/ui.h" #include "ui/uidefs.h" #include "io/key.h" #include "gamesequence/gamesequence.h" #include "mission/missioncampaign.h" #include "gamesnd/gamesnd.h" #include "missionui/missionscreencommon.h" #include "freespace2/freespace.h" #include "playerman/player.h" #include "playerman/managepilot.h" #include "popup/popup.h" #include "gamehelp/contexthelp.h" #include "globalincs/alphacolors.h" #include "cmdline/cmdline.h" #include "menuui/techmenu.h" // for tech menu reset stuff #include "cfile/cfile.h" #include "parse/parselo.h" #define MAX_MISSIONS 1024 int Mission_list_coords[GR_NUM_RESOLUTIONS][4] = { { // GR_640 33, 108, 402, 279 }, { // GR_1024 43, 175, 402, 459 } }; int Campaign_list_coords[GR_NUM_RESOLUTIONS][4] = { { // GR_640 491, 108, 115, 279 }, { // GR_1024 491, 175, 115, 459 } }; #define C_SUBTEXT_X 19 // x coordinate offsets for data when campaign tab active #define C_TEXT_X 0 // x coordinate offsets for data when mission tab active #define M_TEXT_X 0 #define MODE_CAMPAIGNS 0 #define MODE_MISSIONS 1 #define MAX_LINES 200 #define MAX_DESC_LINES 200 #define NUM_BUTTONS 11 #define LIST_BUTTONS_MAX 42 #define SCROLL_UP_BUTTON 0 #define SCROLL_DOWN_BUTTON 1 #define MISSION_TAB 2 #define CAMPAIGN_TAB 3 #define HELP_BUTTON 4 #define COMMIT_BUTTON 5 #define OPTIONS_BUTTON 6 #define TECH_DATABASE_BUTTON 7 #define SIMULATOR_BUTTON 8 #define CUTSCENES_BUTTON 9 #define CREDITS_BUTTON 10 #define X_COORD 0 #define Y_COORD 1 #define W_COORD 2 #define H_COORD 3 #define CAMPAIGN_MISSION_HASH_SIZE 307 struct sim_room_buttons { char *filename; int x, y, xt, yt; int hotspot; UI_BUTTON button; // because we have a class inside this struct, we need the constructor below.. sim_room_buttons(char *name, int x1, int y1, int xt1, int yt1, int h) : filename(name), x(x1), y(y1), xt(xt1), yt(yt1), hotspot(h) {} }; static sim_room_buttons Buttons[GR_NUM_RESOLUTIONS][NUM_BUTTONS] = { //XSTR:OFF { // GR_640 sim_room_buttons("LMB_04", 1, 99, -1, -1, 4), sim_room_buttons("LMB_05", 1, 381, -1, -1, 5), sim_room_buttons("LMB_06", 6, 438, 40, 445, 6), sim_room_buttons("LMB_07", 6, 457, 40, 462, 7), sim_room_buttons("LMB_08", 534, 426, 500, 440, 8), sim_room_buttons("LMB_09", 571, 426, 572, 413, 9), sim_room_buttons("LMB_10", 534, 455, 480, 462, 10), sim_room_buttons("TDB_00", 7, 3, 37, 7, 0), sim_room_buttons("TDB_01", 7, 18, 37, 23, 1), sim_room_buttons("TDB_02", 7, 34, 37, 38, 2), sim_room_buttons("TDB_03", 7, 49, 37, 54, 3), }, { // GR_1024 sim_room_buttons("2_LMB_04", 2, 159, -1, -1, 4), sim_room_buttons("2_LMB_05", 2, 609, -1, -1, 5), sim_room_buttons("2_LMB_06", 10, 701, 64, 712, 6), sim_room_buttons("2_LMB_07", 10, 732, 64, 739, 7), sim_room_buttons("2_LMB_08", 854, 681, 800, 704, 8), sim_room_buttons("2_LMB_09", 914, 681, 915, 660, 9), sim_room_buttons("2_LMB_10", 854, 728, 800, 728, 10), sim_room_buttons("2_TDB_00", 12, 5, 59, 12, 0), sim_room_buttons("2_TDB_01", 12, 31, 59, 37, 1), sim_room_buttons("2_TDB_02", 12, 56, 59, 62, 2), sim_room_buttons("2_TDB_03", 12, 81, 59, 88, 3), } //XSTR:ON }; char *Sim_filename[GR_NUM_RESOLUTIONS] = { "LoadMission", "2_LoadMission" }; char *Sim_mask_filename[GR_NUM_RESOLUTIONS] = { "LoadMission-m", "2_LoadMission-m" }; char *Campaign_filename[GR_NUM_RESOLUTIONS] = { "Campaign", "2_Campaign" }; char *Campaign_mask_filename[GR_NUM_RESOLUTIONS] = { "Campaign-m", "2_Campaign-m" }; char *Sim_room_slider_filename[GR_NUM_RESOLUTIONS] = { "slider", "2_slider" }; // misc text. ("Mission" and "Filename" #define NUM_SIM_MISC_TEXT 2 #define SIM_MISC_TEXT_MISSION 0 #define SIM_MISC_TEXT_FILENAME 1 int Sim_misc_text_coords[GR_NUM_RESOLUTIONS][NUM_SIM_MISC_TEXT][2] = { { // GR_640 {33, 95}, {491, 95} }, { // GR_1024 {43, 155}, {491, 155} } }; int Sim_room_slider_coords[GR_NUM_RESOLUTIONS][4] = { { // GR_640 4, 131, 20, 245 }, { // GR_1024 5, 209, 32, 392 } }; // readyroom text line stuff #define READYROOM_LINE_CAMPAIGN 1 #define READYROOM_LINE_CMISSION 2 #define READYROOM_LINE_MISSION 3 #define READYROOM_FLAG_FROM_VOLITION (1<<0) // volition made static struct { int type; // see READYROOM_LINE_* defines above char *name; char *filename; int x; // X coordinate of line int y; // Y coordinate of line int flags; // special flags, see READYROOM_FLAG_* defines above } sim_room_lines[MAX_LINES]; static char Cur_campaign[MAX_FILENAME_LEN]; static char *Mission_filenames[MAX_MISSIONS]; static char *Standalone_mission_names[MAX_MISSIONS]; static int Standalone_mission_flags[MAX_MISSIONS]; static char *Campaign_missions[MAX_MISSIONS]; static char *Campaign_mission_names[MAX_CAMPAIGN_MISSIONS]; static int Campaign_mission_flags[MAX_MISSIONS]; static char *Campaign_descs[MAX_CAMPAIGNS]; static char *Campaign_descs_temp[MAX_CAMPAIGNS]; static char *Campaign_file_names_temp[MAX_CAMPAIGNS]; static int Standalone_mission_names_inited = 0; static int Campaign_names_inited = 0; static int Campaign_mission_names_inited = 0; static int Num_standalone_missions; static int Num_campaign_missions; //static int Num_player_missions; static int Scroll_offset; static int Selected_line; static int Num_lines; static int Num_campaign_missions_with_info = 0; static int Num_standalone_missions_with_info = 0; static int list_x1; static int list_x2; static int list_y; static int list_w1; static int list_w2; static int list_h; static int Background_bitmap; static UI_WINDOW Ui_window; static UI_BUTTON List_buttons[LIST_BUTTONS_MAX]; // buttons for each line of text in list // slider stuff static UI_SLIDER2 Sim_room_slider; typedef struct hash_node { hash_node *next; char *filename; } hash_node; static hash_node *Campaign_mission_hash_table[CAMPAIGN_MISSION_HASH_SIZE]; static int Hash_table_inited; // special icons (1.04 + stuff) #define NUM_MISSION_ICONS 1 #define MISSION_ICON_VOLITION 0 // mini volition death's head :) // icon offsets (see LIST_ defines above //#define MISSION_ICON_VOLITION_X (46) #define MISSION_ICON_VOLITION_Y_OFFSET (-1) // icon offsets static int Sim_volition_icon_x[GR_NUM_RESOLUTIONS] = { 38, 49 }; // special icons themselves int Mission_icon_bitmaps[NUM_MISSION_ICONS]; //XSTR:OFF char *Mission_icon_bitmap_filenames[NUM_MISSION_ICONS] = { "icon-volition" }; //XSTR:ON void sim_room_load_mission_icons(); void sim_room_unload_mission_icons(); void sim_room_blit_icons(int line_index, int y_start, fs_builtin_mission *fb = NULL, int is_md = 0); // Finds a hash value for mission filename // // returns hash value int hash_filename(char *filename) { ulonglong hash_val = 0; char *ptr = filename; // Dont hash .fsm extension, convert all to upper case for (int i=0; i < ((signed int)(strlen(filename)) - 4); i++) { hash_val = (hash_val << 4) + toupper(*ptr++); } return int(hash_val % CAMPAIGN_MISSION_HASH_SIZE); } // insert filename into Campaign_mission_hash_table // // returns 1 if successful, 0 if could not allocate memory int hash_insert(char *filename) { int hash_val = hash_filename(filename); hash_node *cur_node; // Check if table empty if (Campaign_mission_hash_table[hash_val] == NULL) { Campaign_mission_hash_table[hash_val] = new hash_node; cur_node = Campaign_mission_hash_table[hash_val]; if (cur_node == NULL) { // Unable to allocate memory return 0; } } else { // Walk down list to first empty node cur_node = Campaign_mission_hash_table[hash_val]; while (cur_node->next != NULL) { cur_node = cur_node->next; } // Create new node cur_node->next = new hash_node; if (cur_node->next == NULL) { // unable to allocate memory return 0; } else { cur_node = cur_node->next; } } // Initialize data cur_node->next = NULL; cur_node->filename = filename; // Return successs return 1; } // Checks if a filename already exitst in the hash table // // returns 1 if found (collision), 0 if no collision int campaign_mission_hash_collision(char *filename) { int hash_val = hash_filename(filename); hash_node *cur_node = Campaign_mission_hash_table[hash_val]; if (cur_node == NULL) { return 0; } do { if (!stricmp(filename, cur_node->filename)) { return 1; } cur_node = cur_node->next; } while (cur_node != NULL); // Ran out of stuff to check return 0; } // builds hash table of campaign mission filenames // // returns 1 if successful, 0 if not successful int build_campaign_mission_filename_hash_table() { int rval; // Go through all campaign missions for (int i=0; inext != NULL) { hash_node *temp = cur_node->next; delete cur_node; cur_node = temp; } // Delete last node delete cur_node; Campaign_mission_hash_table[i] = NULL; } } } // add a line of sim_room smuck to end of list int sim_room_line_add(int type, char *name, char *filename, int x, int y, int flags) { if (Num_lines >= MAX_LINES) return 0; sim_room_lines[Num_lines].type = type; sim_room_lines[Num_lines].name = name; sim_room_lines[Num_lines].filename = filename; sim_room_lines[Num_lines].x = x; sim_room_lines[Num_lines].y = y; sim_room_lines[Num_lines].flags = flags; return Num_lines++; } // filter out all multiplayer campaigns int campaign_room_campaign_filter(char *filename) { int type, max_players; char name[NAME_LENGTH], *desc = NULL; #ifdef OEM_BUILD // also need to check if this is the builtin campaign if ( game_find_builtin_mission(filename) && mission_campaign_get_info(filename, name, &type, &max_players, &desc) ) { #else if ( mission_campaign_get_info(filename, name, &type, &max_players, &desc) ) { #endif if ( type == CAMPAIGN_TYPE_SINGLE ) { Campaign_file_names_temp[Num_campaigns] = strdup(filename); Campaign_descs_temp[Num_campaigns++] = desc; return 1; } } if (desc){ free(desc); } return 0; } // build up a list of all missions in all campaigns. int sim_room_campaign_mission_filter(char *filename) { int num; num = mission_campaign_get_mission_list(filename, &Campaign_missions[Num_campaign_missions], MAX_CAMPAIGN_MISSIONS - Num_campaign_missions); if (num < 0) return 0; Num_campaign_missions += num; return 1; } // filter out all missions already used in existing campaigns int sim_room_standalone_mission_filter(char *filename) { int type; char mission_name[255]; // Check if a campaign mission (single and multi) if (campaign_mission_hash_collision(filename)) { return 0; } // Check if a standalone multi mission OR Mdisk mission with data type = mission_parse_is_multi(filename, mission_name); if (type && !(type & MISSION_TYPE_SINGLE)) return 0; return 1; } // builds up list of standalone missions and adds them to missions simulator // processes one mission per frame // // returns 1 if finished with all missions, 0 otherwise // int build_standalone_mission_list_do_frame() { int font_height = gr_get_font_height(); char filename[MAX_FILENAME_LEN]; char str[256]; // When no standalone missions in data directory if (Num_standalone_missions == 0) { Standalone_mission_names_inited = 1; return 1; } // Set global variable so we we'll have list available next time Standalone_mission_names[Num_standalone_missions_with_info] = NULL; Standalone_mission_flags[Num_standalone_missions_with_info] = 0; if (Num_standalone_missions > 0) { // sanity check if (strlen(Mission_filenames[Num_standalone_missions_with_info]) < MAX_FILENAME_LEN - 4) { // sanity check? strcpy(filename, Mission_filenames[Num_standalone_missions_with_info]); // update popup memset(str, 0, 256); sprintf(str, XSTR("Single Mission\n\n%s",989), filename); popup_change_text(str); // tack on an extension strcat(filename, FS_MISSION_FILE_EXT); if (!get_mission_info(filename)) { Standalone_mission_names[Num_standalone_missions_with_info] = strdup(The_mission.name); Standalone_mission_flags[Num_standalone_missions_with_info] = The_mission.game_type; int y = Num_lines * (font_height + 2); // determine some extra information int flags = 0; fs_builtin_mission *fb = game_find_builtin_mission(filename); if((fb != NULL) && (fb->flags & FSB_FROM_VOLITION)){ flags |= READYROOM_FLAG_FROM_VOLITION; } // add the line sim_room_line_add(READYROOM_LINE_MISSION, Standalone_mission_names[Num_standalone_missions_with_info], Mission_filenames[Num_standalone_missions_with_info], list_x1 + M_TEXT_X, y, flags); } } Num_standalone_missions_with_info++; } if (Num_standalone_missions_with_info == Num_standalone_missions) { Standalone_mission_names_inited = 1; return 1; } else { return 0; } } // builds up list of already played missions in a campaign and adds them to missions simulator // processes one mission per frame // // returns 1 if finished with all missions, 0 otherwise // int build_campaign_mission_list_do_frame() { int font_height = gr_get_font_height(); char str[256]; // When no campaign files in data directory if (Campaign.num_missions == 0) { Campaign_mission_names_inited = 1; return 1; } // change popup memset(str, 0, 256); sprintf(str, XSTR("Campaign Mission\n\n%s",990), Campaign.missions[Num_campaign_missions_with_info].name); popup_change_text(str); // Set global variable so we we'll have list available next time Campaign_mission_names[Num_campaign_missions_with_info] = NULL; Campaign_mission_flags[Num_campaign_missions_with_info] = 0; // Only allow missions already completed if (Campaign.missions[Num_campaign_missions_with_info].completed || Cmdline_allslev) { if (!get_mission_info(Campaign.missions[Num_campaign_missions_with_info].name)) { // add to list Campaign_mission_names[Num_campaign_missions_with_info] = strdup(The_mission.name); Campaign_mission_flags[Num_campaign_missions_with_info] = The_mission.game_type; int y = Num_campaign_missions_with_info * (font_height + 2); // determine some extra information int flags = 0; fs_builtin_mission *fb = game_find_builtin_mission(Campaign.missions[Num_campaign_missions_with_info].name); if((fb != NULL) && (fb->flags & FSB_FROM_VOLITION)) { flags |= READYROOM_FLAG_FROM_VOLITION; } sim_room_line_add(READYROOM_LINE_CMISSION, Campaign_mission_names[Num_campaign_missions_with_info], Campaign.missions[Num_campaign_missions_with_info].name, list_x1 + C_SUBTEXT_X, y, flags); } } Num_campaign_missions_with_info++; if (Num_campaign_missions_with_info == Campaign.num_missions) { Campaign_mission_names_inited = 1; return 1; } else { return 0; } } // Builds list of either (1) standalone missions or (2) already played missions in current campaign // First time through, it builds list, next time it uses precompiled list void sim_room_build_listing() { int i, y, max_num_entries_viewable; int font_height = gr_get_font_height(); char full_filename[256]; Num_lines = y = 0; list_y = Mission_list_coords[gr_screen.res][1]; list_h = Mission_list_coords[gr_screen.res][3]; // Stand alone single player missions. if (Player->readyroom_listing_mode == MODE_MISSIONS) { if (Hash_table_inited) { if (!Standalone_mission_names_inited) { // Is this the first time through // build_list_do_frame builds list and adds sim room line and sets Standalone_mission_names_inited popup_till_condition(build_standalone_mission_list_do_frame, POPUP_CANCEL, XSTR("Loading missions", 991) ); } else { for (i=0; iflags & FSB_FROM_VOLITION)){ flags |= READYROOM_FLAG_FROM_VOLITION; } sim_room_line_add(READYROOM_LINE_MISSION, Standalone_mission_names[i], Mission_filenames[i], list_x1 + M_TEXT_X, y, flags); y += font_height + 2; } } } } } else { // Campaign missions list_y += font_height + 2; list_h -= font_height - 2; if (!Campaign_mission_names_inited) { // Is this the first time through // builds list, adds sim room line and sets Campaign_mission_names_inited popup_till_condition(build_campaign_mission_list_do_frame, POPUP_CANCEL, XSTR("Loading campaign missions",992)); } else { for (i=0; iflags & FSB_FROM_VOLITION)){ flags |= READYROOM_FLAG_FROM_VOLITION; } sim_room_line_add(READYROOM_LINE_CMISSION, Campaign_mission_names[i], Campaign.missions[i].name, list_x1 + C_SUBTEXT_X, y, flags); y += font_height + 2; // Goober5000 - added +2 to conform with above } } } } // set appropriate slider size max_num_entries_viewable = list_h / (font_height + 2); Sim_room_slider.set_numberItems((Num_lines > max_num_entries_viewable) ? (Num_lines - max_num_entries_viewable) : 0); } int sim_room_line_query_visible(int n) { int y; if ((n < 0) || (n >= Num_lines)) return 0; y = sim_room_lines[n].y - sim_room_lines[Scroll_offset].y; if ((y < 0) || (y + gr_get_font_height() > list_h)) return 0; return 1; } void sim_room_scroll_screen_up() { if (Scroll_offset > 0) { Scroll_offset--; if (Player->readyroom_listing_mode == MODE_MISSIONS) { Assert(Selected_line > Scroll_offset); while (!sim_room_line_query_visible(Selected_line)) { Selected_line--; } } gamesnd_play_iface(SND_SCROLL); } else gamesnd_play_iface(SND_GENERAL_FAIL); } void sim_room_scroll_line_up() { if (Selected_line) { Selected_line--; if (Selected_line < Scroll_offset) { Scroll_offset = Selected_line; Sim_room_slider.forceUp(); } gamesnd_play_iface(SND_SCROLL); } else gamesnd_play_iface(SND_GENERAL_FAIL); } void sim_room_scroll_screen_down() { if (sim_room_lines[Num_lines - 1].y + gr_get_font_height() > sim_room_lines[Scroll_offset].y + list_h) { Scroll_offset++; if (Player->readyroom_listing_mode == MODE_MISSIONS) { while (!sim_room_line_query_visible(Selected_line)) { Selected_line++; Assert(Selected_line < Num_lines); } } gamesnd_play_iface(SND_SCROLL); } else gamesnd_play_iface(SND_GENERAL_FAIL); } void sim_room_scroll_line_down() { if (Selected_line < Num_lines - 1) { Selected_line++; Assert(Selected_line > Scroll_offset); while (!sim_room_line_query_visible(Selected_line)) { Scroll_offset++; Sim_room_slider.forceDown(); } gamesnd_play_iface(SND_SCROLL); } else gamesnd_play_iface(SND_GENERAL_FAIL); } /* Goober5000 - why are there two nearly identical functions? (campaign_room_reset_campaign and sim_room_reset_campaign) Looks like this function should be deprecated... // returns: 0 = success, !0 = aborted or failed int sim_room_reset_campaign() { int z, rval = 1; z = popup(PF_TITLE_BIG | PF_TITLE_RED, 2, POPUP_CANCEL, POPUP_OK, XSTR( "Warning\nThis will cause all progress in your\ncurrent campaign to be lost", 110) ); if (z) { mission_campaign_savefile_delete(Campaign.filename); mission_campaign_load(Campaign.filename); rval = 0; } return rval; } */ // Decide if we should offer choice to resume this savegame int sim_room_can_resume_savegame(char *savegame_filename) { #ifdef FREESPACE_SAVERESTORE_SYSTEM char savegame_mission[MAX_FILENAME_LEN]; if (state_read_description(savegame_filename, NULL, savegame_mission)) { return 0; } if (stricmp(Game_current_mission_filename, savegame_mission)) { return 0; } return 1; #else return 0; #endif } // Decide wether to resume a save game or not // exit: 1 => savegame has been restored // 0 => no restore, proceed to briefing // -1 => don't start mission at all int sim_room_maybe_resume_savegame() { // MWA -- 3/26/98 -- removed all savegame references in game return 0; /* char savegame_filename[_MAX_FNAME]; int popup_rval = -1, resume_savegame = 0; // Generate the save-game filename for this campaign memset(savegame_filename, 0, _MAX_FNAME); mission_campaign_savefile_generate_root(savegame_filename); strcat(savegame_filename, NOX("svg")); // Decide if we should offer choice to resume this savegame if ( sim_room_can_resume_savegame(savegame_filename) ) { popup_rval = popup(0, 3, XSTR("&Cancel",-1), XSTR("&Overwrite",-1), XSTR("&Resume",-1), XSTR("A save game for this mission exists.", -1)); switch ( popup_rval ) { case 0: case -1: resume_savegame = -1; break; case 1: resume_savegame = 0; break; case 2: resume_savegame = 1; break; default: Int3(); resume_savegame = -1; break; } } else { resume_savegame = 0; } if (resume_savegame == 1) { if ( state_restore_all(savegame_filename) == -1 ) { popup_rval = popup(PF_TITLE_BIG | PF_TITLE_RED, 2, POPUP_NO, POPUP_YES, XSTR("Error\nSaved misison could not be loaded.\nDo you wish to start this mission from the beginning?", -1)); if (popup_rval == 1) { resume_savegame = 0; } else { resume_savegame = -1; } } else { resume_savegame = 1; } } // If we are resuming this savegame, then delete the file if (resume_savegame == 1) { cf_delete(savegame_filename); } return resume_savegame; */ } int readyroom_continue_campaign() { if (mission_campaign_next_mission()) { // is campaign and next mission valid? #ifdef FS2_DEMO int reset_campaign = 0; reset_campaign = popup(PF_BODY_BIG, 2, POPUP_NO, POPUP_YES, XSTR( "Demo Campaign Is Over. Would you like to play the campaign again?", 111) ); if ( reset_campaign == 1 ) { mission_campaign_savefile_delete(Campaign.filename); mission_campaign_load(Campaign.filename); mission_campaign_next_mission(); } else { return -1; } #else gamesnd_play_iface(SND_GENERAL_FAIL); popup(0, 1, POPUP_OK, XSTR( "The campaign is over. To replay the campaign, either create a new pilot or restart the campaign in the campaign room.", 112) ); return -1; #endif } // CD CHECK if(!game_do_cd_mission_check(Game_current_mission_filename)){ return -1; } // set the bit for campaign mode Game_mode |= GM_CAMPAIGN_MODE; gameseq_post_event( GS_EVENT_START_GAME ); return 0; } void sim_room_commit() { if ((Selected_line >= Num_lines) || !sim_room_lines[Selected_line].filename) { gamesnd_play_iface(SND_GENERAL_FAIL); return; } strncpy(Game_current_mission_filename, sim_room_lines[Selected_line].filename, MAX_FILENAME_LEN); Game_mode &= ~(GM_CAMPAIGN_MODE); // be sure this bit is clear // CD CHECK if(game_do_cd_mission_check(Game_current_mission_filename)){ // don't resume savegame, proceed to briefing gameseq_post_event(GS_EVENT_START_GAME); gamesnd_play_iface(SND_COMMIT_PRESSED); } } int sim_room_button_pressed(int n) { switch (n) { case SCROLL_UP_BUTTON: sim_room_scroll_screen_up(); Sim_room_slider.forceUp(); break; case SCROLL_DOWN_BUTTON: sim_room_scroll_screen_down(); Sim_room_slider.forceDown(); break; case MISSION_TAB: #ifdef OEM_BUILD game_feature_not_in_demo_popup(); // gamesnd_play_iface(SND_GENERAL_FAIL); break; #else Player->readyroom_listing_mode = MODE_MISSIONS; Selected_line = Scroll_offset = 0; gamesnd_play_iface(SND_USER_SELECT); sim_room_build_listing(); break; #endif case CAMPAIGN_TAB: Player->readyroom_listing_mode = MODE_CAMPAIGNS; Scroll_offset = 0; gamesnd_play_iface(SND_USER_SELECT); sim_room_build_listing(); break; case COMMIT_BUTTON: sim_room_commit(); break; case HELP_BUTTON: launch_context_help(); gamesnd_play_iface(SND_HELP_PRESSED); break; case OPTIONS_BUTTON: gamesnd_play_iface(SND_SWITCH_SCREENS); gameseq_post_event(GS_EVENT_OPTIONS_MENU); return 1; case TECH_DATABASE_BUTTON: gamesnd_play_iface(SND_SWITCH_SCREENS); gameseq_post_event(GS_EVENT_TECH_MENU); return 1; case CUTSCENES_BUTTON: gamesnd_play_iface(SND_SWITCH_SCREENS); gameseq_post_event(GS_EVENT_GOTO_VIEW_CUTSCENES_SCREEN); return 1; case CREDITS_BUTTON: gamesnd_play_iface(SND_SWITCH_SCREENS); gameseq_post_event(GS_EVENT_CREDITS); return 1; } return 0; } // do nothing void sim_room_scroll_capture() { } // --------------------------------------------------------------------- // mission_sim_room_init() // // Initialize the sim_room assignment screen system. Called when GS_STATE_sim_room_SCREEN // is entered. // void sim_room_init() { int i; sim_room_buttons *b; char wild_card[256]; list_x1 = Mission_list_coords[gr_screen.res][0]; list_x2 = Campaign_list_coords[gr_screen.res][0]; list_y = Mission_list_coords[gr_screen.res][1]; list_w1 = Mission_list_coords[gr_screen.res][2]; list_w2 = Campaign_list_coords[gr_screen.res][2]; list_h = Mission_list_coords[gr_screen.res][3]; // force mode to valid range. I once had a bogus value here. Don't know how that happened, though. if (Player->readyroom_listing_mode != MODE_MISSIONS) Player->readyroom_listing_mode = MODE_CAMPAIGNS; *Game_current_mission_filename = 0; common_set_interface_palette("InterfacePalette"); // set the interface palette Ui_window.create(0, 0, gr_screen.max_w, gr_screen.max_h, 0); Ui_window.set_mask_bmap(Sim_mask_filename[gr_screen.res]); for (i=0; ibutton.create(&Ui_window, "", b->x, b->y, 60, 30, (i < 2), 1); // set up callback for when a mouse first goes over a button b->button.set_highlight_action(common_play_highlight_sound); b->button.set_bmaps(b->filename); b->button.link_hotspot(b->hotspot); } // screen/button specific text Ui_window.add_XSTR("Single Missions", 1060, Buttons[gr_screen.res][MISSION_TAB].xt, Buttons[gr_screen.res][MISSION_TAB].yt, &Buttons[gr_screen.res][MISSION_TAB].button, UI_XSTR_COLOR_GREEN); Ui_window.add_XSTR("Campaign Missions", 1061, Buttons[gr_screen.res][CAMPAIGN_TAB].xt, Buttons[gr_screen.res][CAMPAIGN_TAB].yt, &Buttons[gr_screen.res][CAMPAIGN_TAB].button, UI_XSTR_COLOR_GREEN); Ui_window.add_XSTR("Help", 928, Buttons[gr_screen.res][HELP_BUTTON].xt, Buttons[gr_screen.res][HELP_BUTTON].yt, &Buttons[gr_screen.res][HELP_BUTTON].button, UI_XSTR_COLOR_GREEN); Ui_window.add_XSTR("Commit", 1062, Buttons[gr_screen.res][COMMIT_BUTTON].xt, Buttons[gr_screen.res][COMMIT_BUTTON].yt, &Buttons[gr_screen.res][COMMIT_BUTTON].button, UI_XSTR_COLOR_PINK); Ui_window.add_XSTR("Options", 1036, Buttons[gr_screen.res][OPTIONS_BUTTON].xt, Buttons[gr_screen.res][OPTIONS_BUTTON].yt, &Buttons[gr_screen.res][OPTIONS_BUTTON].button, UI_XSTR_COLOR_GREEN); // common tab button text Ui_window.add_XSTR("Technical Database", 1055, Buttons[gr_screen.res][TECH_DATABASE_BUTTON].xt, Buttons[gr_screen.res][TECH_DATABASE_BUTTON].yt, &Buttons[gr_screen.res][TECH_DATABASE_BUTTON].button, UI_XSTR_COLOR_GREEN); Ui_window.add_XSTR("Mission Simulator", 1056, Buttons[gr_screen.res][SIMULATOR_BUTTON].xt, Buttons[gr_screen.res][SIMULATOR_BUTTON].yt, &Buttons[gr_screen.res][SIMULATOR_BUTTON].button, UI_XSTR_COLOR_GREEN); Ui_window.add_XSTR("Cutscenes", 1057, Buttons[gr_screen.res][CUTSCENES_BUTTON].xt, Buttons[gr_screen.res][CUTSCENES_BUTTON].yt, &Buttons[gr_screen.res][CUTSCENES_BUTTON].button, UI_XSTR_COLOR_GREEN); Ui_window.add_XSTR("Credits", 1058, Buttons[gr_screen.res][CREDITS_BUTTON].xt, Buttons[gr_screen.res][CREDITS_BUTTON].yt, &Buttons[gr_screen.res][CREDITS_BUTTON].button, UI_XSTR_COLOR_GREEN); // misc text - not associated with any buttons Ui_window.add_XSTR("Mission", 1063, Sim_misc_text_coords[gr_screen.res][SIM_MISC_TEXT_MISSION][0], Sim_misc_text_coords[gr_screen.res][SIM_MISC_TEXT_MISSION][1], NULL, UI_XSTR_COLOR_GREEN); Ui_window.add_XSTR("Filename", 1064, Sim_misc_text_coords[gr_screen.res][SIM_MISC_TEXT_FILENAME][0], Sim_misc_text_coords[gr_screen.res][SIM_MISC_TEXT_FILENAME][1], NULL, UI_XSTR_COLOR_GREEN); for (i=0; icurrent_campaign); mission_load_up_campaign(); mission_campaign_next_mission(); Num_campaigns = Num_campaign_missions = 0; Get_file_list_filter = sim_room_campaign_mission_filter; memset(wild_card, 0, 256); strcpy(wild_card, NOX("*")); strcat(wild_card, FS_CAMPAIGN_FILE_EXT); Num_campaigns = cf_get_file_list(MAX_CAMPAIGNS, Campaign_file_names, CF_TYPE_MISSIONS, wild_card, CF_SORT_NAME); Hash_table_inited = 0; if (build_campaign_mission_filename_hash_table()) { Hash_table_inited = 1; } // HACK GR_MAYBE_CLEAR_RES(Background_bitmap); if(Background_bitmap != -1){ gr_set_bitmap(Background_bitmap); gr_bitmap(0, 0); } Ui_window.draw(); gr_flip(); Get_file_list_filter = sim_room_standalone_mission_filter; memset(wild_card, 0, 256); strcpy(wild_card, NOX("*")); strcat(wild_card, FS_MISSION_FILE_EXT); Num_standalone_missions = cf_get_file_list(MAX_MISSIONS, Mission_filenames, CF_TYPE_MISSIONS, wild_card, CF_SORT_NAME); // set up slider with 0 items to start Sim_room_slider.create(&Ui_window, Sim_room_slider_coords[gr_screen.res][X_COORD], Sim_room_slider_coords[gr_screen.res][Y_COORD], Sim_room_slider_coords[gr_screen.res][W_COORD], Sim_room_slider_coords[gr_screen.res][H_COORD], 0, Sim_room_slider_filename[gr_screen.res], &sim_room_scroll_screen_up, &sim_room_scroll_screen_down, &sim_room_scroll_capture); Num_campaign_missions_with_info = Num_standalone_missions_with_info = Standalone_mission_names_inited = Campaign_names_inited = Campaign_mission_names_inited = 0; sim_room_build_listing(); // load special mission icons sim_room_load_mission_icons(); } // --------------------------------------------------------------------- // sim_room_close() // // Cleanup the sim_room assignment screen system. Called when GS_STATE_sim_room_SCREEN // is left. // void sim_room_close() { int i; for (i=0; i= 0) bm_release(Background_bitmap); if (Standalone_mission_names_inited){ for (i=0; i 0) || B1_JUST_RELEASED ) { if ( help_overlay_active(SIM_ROOM_OVERLAY) ) { help_overlay_set_state(SIM_ROOM_OVERLAY, 0); Ui_window.set_ignore_gadgets(0); k = 0; } } if ( !help_overlay_active(SIM_ROOM_OVERLAY) ) { Ui_window.set_ignore_gadgets(0); } switch (k) { case KEY_DOWN: // scroll list down sim_room_scroll_line_down(); break; case KEY_UP: // scroll list up sim_room_scroll_line_up(); break; case KEY_ESC: gameseq_post_event(GS_EVENT_MAIN_MENU); break; case KEY_CTRLED | KEY_UP: sim_room_button_pressed(TECH_DATABASE_BUTTON); break; case KEY_CTRLED | KEY_DOWN: sim_room_button_pressed(CUTSCENES_BUTTON); break; case KEY_TAB: if (Player->readyroom_listing_mode == MODE_CAMPAIGNS) Player->readyroom_listing_mode = MODE_MISSIONS; else Player->readyroom_listing_mode = MODE_CAMPAIGNS; Selected_line = Scroll_offset = 0; gamesnd_play_iface(SND_USER_SELECT); sim_room_build_listing(); break; case KEY_F2: gamesnd_play_iface(SND_SWITCH_SCREENS); gameseq_post_event(GS_EVENT_OPTIONS_MENU); break; } // end switch for (i=0; i= 0) { gr_set_bitmap(Background_bitmap); gr_bitmap(0, 0); } Ui_window.draw(); for (i=TECH_DATABASE_BUTTON; i<=CREDITS_BUTTON; i++){ if (Buttons[gr_screen.res][i].button.button_down()){ break; } } if (i > CREDITS_BUTTON){ Buttons[gr_screen.res][SIMULATOR_BUTTON].button.draw_forced(2); } if (!Buttons[gr_screen.res][CAMPAIGN_TAB].button.button_down() && !Buttons[gr_screen.res][MISSION_TAB].button.button_down()) { if (Player->readyroom_listing_mode == MODE_CAMPAIGNS){ Buttons[gr_screen.res][CAMPAIGN_TAB].button.draw_forced(2); } else if (Player->readyroom_listing_mode == MODE_MISSIONS){ Buttons[gr_screen.res][MISSION_TAB].button.draw_forced(2); } } gr_set_font(FONT1); if (Player->readyroom_listing_mode == MODE_CAMPAIGNS) { gr_set_color_fast(&Color_text_heading); strcpy(buf, Campaign.name); gr_force_fit_string(buf, 255, list_w1); gr_printf(list_x1, Mission_list_coords[gr_screen.res][1], buf); if (Campaign.filename) { sprintf(buf, NOX("%s%s"), Campaign.filename, FS_CAMPAIGN_FILE_EXT); gr_force_fit_string(buf, 255, list_w2); gr_printf(list_x2, Mission_list_coords[gr_screen.res][1], buf); // blit the proper icons if necessary char full_name[256]; memset(full_name, 0, 256); strcpy(full_name, cf_add_ext(Campaign.filename,FS_CAMPAIGN_FILE_EXT)); fs_builtin_mission *fb = game_find_builtin_mission(full_name); if(fb != NULL){ // sim_room_blit_icons(0, Mission_list_coords[gr_screen.res][1], fb, 0); } } } line = Scroll_offset; while (sim_room_line_query_visible(line)) { y = list_y + sim_room_lines[line].y - sim_room_lines[Scroll_offset].y; if (sim_room_lines[line].type != READYROOM_LINE_CAMPAIGN) { List_buttons[line - Scroll_offset].update_dimensions(list_x1, y, list_x2 + list_w2 - list_x1, font_height); List_buttons[line - Scroll_offset].enable(); } else List_buttons[line - Scroll_offset].disable(); if (line == Selected_line) gr_set_color_fast(&Color_text_selected); else if (line == select_tease_line) gr_set_color_fast(&Color_text_subselected); else gr_set_color_fast(&Color_text_normal); strcpy(buf, sim_room_lines[line].name); gr_force_fit_string(buf, 255, list_x1 + list_w1 - sim_room_lines[line].x); gr_printf(sim_room_lines[line].x, y, buf); if (sim_room_lines[line].filename) { strcpy(buf, sim_room_lines[line].filename); gr_force_fit_string(buf, 255, list_w2); gr_printf(list_x2, y, buf); } // blit additional icon information sim_room_blit_icons(line, y); line++; } i = line - Scroll_offset; while (i < LIST_BUTTONS_MAX) List_buttons[i++].disable(); // blit help overlay if active help_overlay_maybe_blit(SIM_ROOM_OVERLAY); gr_flip(); } void sim_room_blit_icons(int line_index, int y_start, fs_builtin_mission *fb, int is_md) { int is_from_volition = 0; // determine icon status if(fb == NULL){ is_from_volition = (sim_room_lines[line_index].flags & READYROOM_FLAG_FROM_VOLITION) ? 1 : 0; } else { is_from_volition = (fb->flags & FSB_FROM_VOLITION) ? 1 : 0; } // if the line is flagged as a volition file if(is_from_volition && (Mission_icon_bitmaps[MISSION_ICON_VOLITION] >= 0)){ gr_set_bitmap(Mission_icon_bitmaps[MISSION_ICON_VOLITION]); gr_bitmap(Sim_volition_icon_x[gr_screen.res], y_start + MISSION_ICON_VOLITION_Y_OFFSET); } } /// Campaign room stuff below int Cr_list_coords[GR_NUM_RESOLUTIONS][4] = { { // GR_640 47, 21, 565, 233 }, { // GR_1024 64, 34, 916, 459 } }; int Cr_info_coords[GR_NUM_RESOLUTIONS][4] = { { // GR_640 28, 267, 476, 103 }, { // GR_1024 45, 427, 761, 165 }, }; #define CR_NUM_BUTTONS 6 #define CR_SCROLL_UP_BUTTON 0 #define CR_SCROLL_DOWN_BUTTON 1 #define CR_SCROLL_INFO_UP_BUTTON 2 #define CR_SCROLL_INFO_DOWN_BUTTON 3 #define CR_RESET_BUTTON 4 #define CR_COMMIT_BUTTON 5 #define MAX_INFO_LINES 20 #define MAX_INFO_LINE_LEN 256 ui_button_info Cr_buttons[GR_NUM_RESOLUTIONS][CR_NUM_BUTTONS] = { { // GR_640 ui_button_info("CAB_00", 2, 42, -1, -1, 0), ui_button_info("CAB_01", 2, 89, -1, -1, 1), ui_button_info("CAB_02", 2, 279, -1, -1, 2), ui_button_info("CAB_03", 2, 325, -1, -1, 3), ui_button_info("CAB_04", 579, 353, -1, -1, 4), ui_button_info("CAB_05", 575, 434, -1, -1, 5), }, { // GR_1024 ui_button_info("2_CAB_00", 3, 68, -1, -1, 0), ui_button_info("2_CAB_01", 3, 142, -1, -1, 1), ui_button_info("2_CAB_02", 3, 446, -1, -1, 2), ui_button_info("2_CAB_03", 3, 520, -1, -1, 3), ui_button_info("2_CAB_04", 927, 565, -1, -1, 4), ui_button_info("2_CAB_05", 920, 694, -1, -1, 5), } }; // text #define CR_NUM_TEXT 3 UI_XSTR Cr_text[GR_NUM_RESOLUTIONS][CR_NUM_TEXT] = { { // GR_640 { "Restart", 1403, 569, 326, UI_XSTR_COLOR_GREEN, -1, &Cr_buttons[0][CR_RESET_BUTTON].button }, { "Campaign", 1404, 569, 337, UI_XSTR_COLOR_GREEN, -1, &Cr_buttons[0][CR_RESET_BUTTON].button }, { "Select", 1409, 568, 413, UI_XSTR_COLOR_PINK, -1, &Cr_buttons[0][CR_COMMIT_BUTTON].button }, }, { // GR_1024 { "Restart", 1403, 922, 523, UI_XSTR_COLOR_GREEN, -1, &Cr_buttons[1][CR_RESET_BUTTON].button }, { "Campaign", 1404, 922, 538, UI_XSTR_COLOR_GREEN, -1, &Cr_buttons[1][CR_RESET_BUTTON].button }, { "Select", 1409, 921, 665, UI_XSTR_COLOR_PINK, -1, &Cr_buttons[1][CR_COMMIT_BUTTON].button }, } }; /* static struct { char *text; int len; } campaign_desc_lines[MAX_DESC_LINES]; */ static int Num_desc_lines; static int Desc_scroll_offset; static int Selected_campaign_index; static int Active_campaign_index; char *Info_text_ptrs[MAX_INFO_LINES]; int Num_info_lines, Info_text_line_size[MAX_INFO_LINES]; void campaign_room_build_listing() { int c, i, y, type, max_players; int font_height = gr_get_font_height(); char name[NAME_LENGTH]; Num_lines = y = 0; if (!Campaign_names_inited) { for (i=0; iflags & FSB_FROM_VOLITION){ flags |= READYROOM_FLAG_FROM_VOLITION; } } sim_room_line_add(READYROOM_LINE_CAMPAIGN, Campaign_names[c], Campaign_file_names[c], Cr_list_coords[gr_screen.res][0], y, flags); y += font_height + 2; } } } void set_new_campaign_line(int n) { char *str; Selected_campaign_index = n; str = Campaign_descs[Selected_campaign_index]; Num_info_lines = 0; if (str) { Num_info_lines = split_str(str, Cr_info_coords[gr_screen.res][2], Info_text_line_size, Info_text_ptrs, MAX_INFO_LINES); Assert(Num_info_lines >= 0); } Desc_scroll_offset = 0; } void campaign_room_scroll_info_up() { if (Desc_scroll_offset) { Desc_scroll_offset--; gamesnd_play_iface(SND_SCROLL); } else gamesnd_play_iface(SND_GENERAL_FAIL); } void campaign_room_scroll_info_down() { if ( (Num_info_lines - Desc_scroll_offset) * gr_get_font_height() > Cr_info_coords[gr_screen.res][3]) { Desc_scroll_offset++; gamesnd_play_iface(SND_SCROLL); } else gamesnd_play_iface(SND_GENERAL_FAIL); } // returns: 0 = success, !0 = aborted or failed int campaign_room_reset_campaign(int n) { char *filename; int z; // z = popup(PF_TITLE_BIG | PF_TITLE_RED, 2, POPUP_CANCEL, POPUP_OK, XSTR( "Warning\nThis will cause all progress in your\ncurrent campaign to be lost", 110), Campaign_names[n]); z = popup(PF_TITLE_BIG | PF_TITLE_RED, 2, POPUP_CANCEL, POPUP_OK, XSTR( "Warning\nThis will cause all progress in your\ncurrent campaign to be lost", 110)); if (z == 1) { filename = (char *) malloc(strlen(Campaign_file_names[n]) + 5); strcpy(filename, Campaign_file_names[n]); strcat(filename, FS_CAMPAIGN_FILE_EXT); mission_campaign_savefile_delete(filename); mission_campaign_load(filename); mission_campaign_next_mission(); return 0; } return 1; } void campaign_room_commit() { if (Selected_campaign_index < 0) { gamesnd_play_iface(SND_GENERAL_FAIL); return; } if (stricmp(Campaign_file_names[Selected_campaign_index], Campaign.filename)) { // new campaign selected /* This is all that's stopping us from switching campaigns without restarting - taylor if ((Active_campaign_index >= 0) && campaign_room_reset_campaign(Active_campaign_index)) { gamesnd_play_iface(SND_GENERAL_FAIL); return; } mission_campaign_savefile_delete(Campaign_file_names[Selected_campaign_index]); */ mission_campaign_load(Campaign_file_names[Selected_campaign_index]); strcpy(Player->current_campaign, Campaign.filename); // track new campaign for player // Goober5000 - reinitialize tech database if needed if ( (Campaign.flags & CF_CUSTOM_TECH_DATABASE) || !stricmp(Campaign.filename, "freespace2") ) { // reset tech database to what's in the tables tech_reset_to_default(); } // Goober5000 - reset player-persistent variables Player->num_variables = 0; } if (mission_campaign_next_mission()) { // is campaign and next mission valid? gamesnd_play_iface(SND_GENERAL_FAIL); return; } gameseq_post_event(GS_EVENT_MAIN_MENU); gamesnd_play_iface(SND_COMMIT_PRESSED); } int campaign_room_button_pressed(int n) { switch (n) { case CR_SCROLL_UP_BUTTON: sim_room_scroll_screen_up(); break; case CR_SCROLL_DOWN_BUTTON: sim_room_scroll_screen_down(); break; case CR_SCROLL_INFO_UP_BUTTON: campaign_room_scroll_info_up(); break; case CR_SCROLL_INFO_DOWN_BUTTON: campaign_room_scroll_info_down(); break; case CR_COMMIT_BUTTON: campaign_room_commit(); break; /* case CR_HELP_BUTTON: launch_context_help(); gamesnd_play_iface(SND_HELP_PRESSED); break; case CR_OPTIONS_BUTTON: gamesnd_play_iface(SND_SWITCH_SCREENS); gameseq_post_event(GS_EVENT_OPTIONS_MENU); return 1; */ case CR_RESET_BUTTON: if ( (Active_campaign_index < 0) || (Active_campaign_index >= Num_campaigns) ) gamesnd_play_iface(SND_GENERAL_FAIL); else if (campaign_room_reset_campaign(Active_campaign_index)) gamesnd_play_iface(SND_GENERAL_FAIL); else { gamesnd_play_iface(SND_USER_SELECT); // Goober5000 - reinitialize tech database if needed if ( (Campaign.flags & CF_CUSTOM_TECH_DATABASE) || !stricmp(Campaign.filename, "freespace2") ) { // reset tech database to what's in the tables tech_reset_to_default(); } // Goober5000 - reset player-persistent variables Player->num_variables = 0; } break; } return 0; } void campaign_room_init() { int i, j, load_failed; ui_button_info *b; char wild_card[256]; list_h = Mission_list_coords[gr_screen.res][3]; // common_set_interface_palette("InterfacePalette"); // set the interface palette Ui_window.create(0, 0, gr_screen.max_w, gr_screen.max_h, 0); Ui_window.set_mask_bmap(Campaign_mask_filename[gr_screen.res]); for (i=0; ibutton.create(&Ui_window, "", b->x, b->y, 60, 30, (i < 2), 1); // set up callback for when a mouse first goes over a button b->button.set_highlight_action(common_play_highlight_sound); b->button.set_bmaps(b->filename); b->button.link_hotspot(b->hotspot); } for (i=0; i= 0) bm_release(Background_bitmap); if (Campaign_names_inited) for (i=0; i 0) || B1_JUST_RELEASED ) { if ( help_overlay_active(CAMPAIGN_ROOM_OVERLAY) ) { help_overlay_set_state(CAMPAIGN_ROOM_OVERLAY, 0); Ui_window.set_ignore_gadgets(0); k = 0; } } if ( !help_overlay_active(CAMPAIGN_ROOM_OVERLAY) ) { Ui_window.set_ignore_gadgets(0); } switch (k) { case KEY_DOWN: // scroll list down if (Selected_campaign_index < Num_campaigns - 1) { set_new_campaign_line(Selected_campaign_index + 1); gamesnd_play_iface(SND_SCROLL); } else gamesnd_play_iface(SND_GENERAL_FAIL); break; case KEY_UP: // scroll list up if (Selected_campaign_index < 0) Selected_campaign_index = 1; if (Selected_campaign_index) { set_new_campaign_line(Selected_campaign_index - 1); gamesnd_play_iface(SND_SCROLL); } else gamesnd_play_iface(SND_GENERAL_FAIL); break; case KEY_ESC: gameseq_post_event(GS_EVENT_MAIN_MENU); break; } // end switch for (i=0; i= 0) { gr_set_bitmap(Background_bitmap); gr_bitmap(0, 0); } Ui_window.draw(); gr_set_font(FONT1); line = Scroll_offset; while (sim_room_line_query_visible(line)) { y = Cr_list_coords[gr_screen.res][1] + sim_room_lines[line].y - sim_room_lines[Scroll_offset].y; List_buttons[line - Scroll_offset].update_dimensions(Cr_list_coords[gr_screen.res][0], y, Cr_list_coords[gr_screen.res][2], font_height); List_buttons[line - Scroll_offset].enable(); if (!stricmp(sim_room_lines[line].filename, Campaign.filename)) { gr_set_color_fast(&Color_white); i = y + font_height / 2 - 1; gr_circle(Cr_list_coords[gr_screen.res][0] - 6, i, 5); gr_set_color_fast(&Color_bright_white); gr_line(Cr_list_coords[gr_screen.res][0] - 10, i, Cr_list_coords[gr_screen.res][0] - 8, i, true); gr_line(Cr_list_coords[gr_screen.res][0] - 6, i - 4, Cr_list_coords[gr_screen.res][0] - 6, i - 2, true); gr_line(Cr_list_coords[gr_screen.res][0] - 4, i, Cr_list_coords[gr_screen.res][0] - 2, i, true); gr_line(Cr_list_coords[gr_screen.res][0] - 6, i + 2, Cr_list_coords[gr_screen.res][0] - 6, i + 4, true); } if (line == Selected_campaign_index) gr_set_color_fast(&Color_text_selected); else if (line == select_tease_line) gr_set_color_fast(&Color_text_subselected); else gr_set_color_fast(&Color_text_normal); strcpy(buf, sim_room_lines[line].name); gr_force_fit_string(buf, 255, Cr_list_coords[gr_screen.res][0] + Cr_list_coords[gr_screen.res][2] - sim_room_lines[line].x); gr_printf(sim_room_lines[line].x, y, buf); line++; } i = line - Scroll_offset; while (i < LIST_BUTTONS_MAX) List_buttons[i++].disable(); y = 0; i = Desc_scroll_offset; gr_set_color_fast(&Color_text_normal); while (y + font_height <= Cr_info_coords[gr_screen.res][3]) { if (i >= Num_info_lines) break; Assert(Info_text_line_size[i] < MAX_INFO_LINE_LEN); strncpy(line_text, Info_text_ptrs[i], Info_text_line_size[i]); line_text[Info_text_line_size[i]] = 0; drop_white_space(line_text); gr_string(Cr_info_coords[gr_screen.res][0], Cr_info_coords[gr_screen.res][1] + y, line_text); y += font_height; i++; } // blit help overlay if active help_overlay_maybe_blit(CAMPAIGN_ROOM_OVERLAY); gr_flip(); } void sim_room_load_mission_icons() { int idx; // load all bitmaps for(idx=0; idx= 0){ // don't bm_release() here, used in multiple places - taylor bm_unload(Mission_icon_bitmaps[idx]); Mission_icon_bitmaps[idx] = -1; } } }