mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-07 16:18:19 -10:00
2336 lines
68 KiB
C++
2336 lines
68 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.
|
|
*
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "cfile/cfile.h"
|
|
#include "gamesnd/gamesnd.h"
|
|
#include "globalincs/alphacolors.h"
|
|
#include "graphics/font.h"
|
|
#include "io/key.h"
|
|
#include "io/timer.h"
|
|
#include "menuui/optionsmenu.h"
|
|
#include "menuui/optionsmenumulti.h"
|
|
#include "network/multi.h"
|
|
#include "network/multiui.h"
|
|
#include "network/multi_voice.h"
|
|
#include "options/OptionsManager.h"
|
|
#include "osapi/osregistry.h"
|
|
#include "parse/parselo.h"
|
|
#include "playerman/player.h"
|
|
#include "popup/popup.h"
|
|
#include "sound/ds.h"
|
|
#include "sound/rtvoice.h"
|
|
|
|
|
|
|
|
// general data section ------------------------------------------------
|
|
UI_WINDOW *Om_window = NULL;
|
|
|
|
static const char* Om_background_0_fname[GR_NUM_RESOLUTIONS] = {
|
|
"OptionsMultiGen", // GR_640
|
|
"2_OptionsMultiGen" // GR_1024
|
|
};
|
|
|
|
static const char* Om_background_0_mask_fname[GR_NUM_RESOLUTIONS] = {
|
|
"OptionsMultiGen-M", // GR_640
|
|
"2_OptionsMultiGen-M" // GR_1024
|
|
};
|
|
|
|
static const char* Om_background_1_fname[GR_NUM_RESOLUTIONS] = {
|
|
"OptionsMultiVox", // GR_640
|
|
"2_OptionsMultiVox" // GR_1024
|
|
};
|
|
|
|
static const char* Om_background_1_mask_fname[GR_NUM_RESOLUTIONS] = {
|
|
"OptionsMultiVox-M", // GR_640
|
|
"2_OptionsMultiVox-M" // GR_1024
|
|
};
|
|
|
|
int Om_background_0 = -1;
|
|
int Om_mask_0 = -1;
|
|
|
|
int Om_background_1 = -1;
|
|
int Om_mask_1 = -1;
|
|
|
|
#define OM_NOTIFICATION_LINE_LEN 255
|
|
|
|
// screen modes
|
|
#define OM_MODE_NONE -1 // no mode (unintialized)
|
|
#define OM_MODE_GENERAL 0 // general tab
|
|
#define OM_MODE_VOX 1 // voice tab
|
|
int Om_mode = OM_MODE_NONE;
|
|
|
|
// notification stuff
|
|
#define OM_NOTIFY_TIME 8000
|
|
#define OM_NOTIFY_Y 430
|
|
#define OM_NOTIFY_Y2 440
|
|
UI_TIMESTAMP Om_notify_stamp;
|
|
char Om_notify_string[255];
|
|
|
|
// load all background bitmaps
|
|
void options_multi_load_bmaps();
|
|
|
|
// unload all the background bitmaps
|
|
void options_multi_unload_bmaps();
|
|
|
|
// add a notification message
|
|
void options_multi_add_notify(const char *str);
|
|
|
|
// process and blit any notification messages
|
|
void options_multi_notify_process();
|
|
|
|
|
|
// protocol options section -------------------------------------------
|
|
#define OM_PRO_NUM_BUTTONS 10
|
|
|
|
#define OM_PRO_TCP 0
|
|
#define OM_PRO_IPX 1
|
|
#define OM_PRO_SCROLL_IP_UP 2
|
|
#define OM_PRO_SCROLL_IP_DOWN 3
|
|
#define OM_PRO_ADD_IP 4
|
|
#define OM_PRO_DELETE_IP 5
|
|
#define OM_PRO_LOCAL_BROADCAST 6
|
|
#define OM_PRO_VMT 7
|
|
#define OM_PRO_VOX_TAB 8
|
|
#define OM_PRO_GEN_TAB 9
|
|
|
|
ui_button_info Om_pro_buttons[GR_NUM_RESOLUTIONS][OM_PRO_NUM_BUTTONS] = {
|
|
{ // GR_640
|
|
ui_button_info("OMuB_07", 7, 66, -1, -1, 7),
|
|
ui_button_info("OMuB_08", 7, 84, -1, -1, 8),
|
|
ui_button_info("OMuB_09", 1, 124, -1, -1, 9),
|
|
ui_button_info("OMuB_10", 1, 157, -1, -1, 10),
|
|
ui_button_info("OMuB_11", 20, 207, -1, -1, 11),
|
|
ui_button_info("OMuB_12", 64, 207, -1, -1, 12),
|
|
ui_button_info("OMuB_13", 9, 251, -1, -1, 13),
|
|
ui_button_info("OMuB_14", 9, 282, -1, -1, 14),
|
|
ui_button_info("OMuB_15", 610, 53, -1, -1, 15),
|
|
ui_button_info("OMuB_16", 610, 72, -1, -1, 16),
|
|
},
|
|
{ // GR_1024
|
|
ui_button_info("2_OMuB_07", 12, 105, -1, -1, 7),
|
|
ui_button_info("2_OMuB_08", 12, 134, -1, -1, 8),
|
|
ui_button_info("2_OMuB_09", 2, 198, -1, -1, 9),
|
|
ui_button_info("2_OMuB_10", 2, 252, -1, -1, 10),
|
|
ui_button_info("2_OMuB_11", 32, 332, -1, -1, 11),
|
|
ui_button_info("2_OMuB_12", 103, 332, -1, -1, 12),
|
|
ui_button_info("2_OMuB_13", 14, 402, -1, -1, 13),
|
|
ui_button_info("2_OMuB_14", 14, 452, -1, -1, 14),
|
|
ui_button_info("2_OMuB_15", 976, 85, -1, -1, 15),
|
|
ui_button_info("2_OMuB_16", 976, 114, -1, -1, 16),
|
|
}
|
|
};
|
|
|
|
UI_GADGET Om_pro_bogus;
|
|
|
|
// test
|
|
#define OM_PRO_NUM_TEXT 12
|
|
UI_XSTR Om_pro_text[GR_NUM_RESOLUTIONS][OM_PRO_NUM_TEXT] = {
|
|
{ // GR_640
|
|
{ "TCP", 1378, 38, 70, UI_XSTR_COLOR_GREEN, -1, &Om_pro_buttons[0][OM_PRO_TCP].button },
|
|
{ "IPX", 1379, 38, 88, UI_XSTR_COLOR_GREEN, -1, &Om_pro_buttons[0][OM_PRO_IPX].button },
|
|
{ "IP Address", 1380, 30, 128, UI_XSTR_COLOR_GREEN, -1, &Om_pro_bogus },
|
|
{ "add", 1381, 22, 235, UI_XSTR_COLOR_GREEN, -1, &Om_pro_buttons[0][OM_PRO_ADD_IP].button },
|
|
{ "rem.", 1382, 68, 235, UI_XSTR_COLOR_GREEN, -1, &Om_pro_buttons[0][OM_PRO_DELETE_IP].button },
|
|
{ "Broadcast Locally", 1387, 42, 260, UI_XSTR_COLOR_GREEN, -1, &Om_pro_buttons[0][OM_PRO_LOCAL_BROADCAST].button },
|
|
{ "PXO", 1383, 42, 291, UI_XSTR_COLOR_GREEN, -1, &Om_pro_buttons[0][OM_PRO_VMT].button },
|
|
{ "Login", 1384, 14, 309, UI_XSTR_COLOR_GREEN, -1, &Om_pro_bogus },
|
|
{ "Password", 1385, 14, 336, UI_XSTR_COLOR_GREEN, -1, &Om_pro_bogus },
|
|
{ "Squadron", 1386, 14, 363, UI_XSTR_COLOR_GREEN, -1, &Om_pro_bogus },
|
|
{ "Voice", 1528, 557, 60, UI_XSTR_COLOR_GREEN, -1, &Om_pro_buttons[0][OM_PRO_VOX_TAB].button },
|
|
{ "General", 1388, 542, 77, UI_XSTR_COLOR_GREEN, -1, &Om_pro_buttons[0][OM_PRO_GEN_TAB].button },
|
|
},
|
|
{ // GR_1024
|
|
{ "TCP", 1378, 61, 113, UI_XSTR_COLOR_GREEN, -1, &Om_pro_buttons[1][OM_PRO_TCP].button },
|
|
{ "IPX", 1379, 61, 141, UI_XSTR_COLOR_GREEN, -1, &Om_pro_buttons[1][OM_PRO_IPX].button },
|
|
{ "IP Address", 1380, 47, 206, UI_XSTR_COLOR_GREEN, -1, &Om_pro_bogus },
|
|
{ "add", 1381, 36, 375, UI_XSTR_COLOR_GREEN, -1, &Om_pro_buttons[1][OM_PRO_ADD_IP].button },
|
|
{ "rem.", 1382, 109, 375, UI_XSTR_COLOR_GREEN, -1, &Om_pro_buttons[1][OM_PRO_DELETE_IP].button },
|
|
{ "Broadcast Locally", 1387, 68, 417, UI_XSTR_COLOR_GREEN, -1, &Om_pro_buttons[1][OM_PRO_LOCAL_BROADCAST].button },
|
|
{ "PXO", 1383, 68, 467, UI_XSTR_COLOR_GREEN, -1, &Om_pro_buttons[1][OM_PRO_VMT].button },
|
|
{ "Login", 1384, 23, 495, UI_XSTR_COLOR_GREEN, -1, &Om_pro_bogus },
|
|
{ "Password", 1385, 23, 538, UI_XSTR_COLOR_GREEN, -1, &Om_pro_bogus },
|
|
{ "Squadron", 1386, 23, 582, UI_XSTR_COLOR_GREEN, -1, &Om_pro_bogus },
|
|
{ "Voice", 1528, 921, 96, UI_XSTR_COLOR_GREEN, -1, &Om_pro_buttons[1][OM_PRO_VOX_TAB].button },
|
|
{ "General", 1388, 902, 123, UI_XSTR_COLOR_GREEN, -1, &Om_pro_buttons[1][OM_PRO_GEN_TAB].button },
|
|
}
|
|
};
|
|
|
|
// defines for the tracker input boxes
|
|
int Om_tracker_login_coords[GR_NUM_RESOLUTIONS][4] = {
|
|
{
|
|
19, 322, 226, -1 // GR_640
|
|
},
|
|
{
|
|
31, 518, 361, -1 // GR_1024
|
|
}
|
|
};
|
|
int Om_tracker_passwd_coords[GR_NUM_RESOLUTIONS][4] = {
|
|
{
|
|
19, 350, 226, -1 // GR_640
|
|
},
|
|
{
|
|
31, 562, 361, -1 // GR_1024
|
|
}
|
|
};
|
|
int Om_tracker_squad_name_coords[GR_NUM_RESOLUTIONS][4] = {
|
|
{
|
|
19, 378, 226, -1 // GR_640
|
|
},
|
|
{
|
|
31, 607, 361, -1 // GR_1024
|
|
}
|
|
};
|
|
|
|
// protocol section tracker login input box
|
|
UI_INPUTBOX Om_tracker_login;
|
|
|
|
// protocol section tracker passwd input box
|
|
UI_INPUTBOX Om_tracker_passwd;
|
|
|
|
// pxo squad name/password
|
|
UI_INPUTBOX Om_tracker_squad_name;
|
|
|
|
#define TRACKER_FOCUS_NONE 0
|
|
#define TRACKER_FOCUS_LOGIN 1
|
|
#define TRACKER_FOCUS_PASSWORD 2
|
|
#define TRACKER_FOCUS_SQUADRON 3
|
|
static int Om_tracker_focus = 0;
|
|
|
|
#define IP_CONFIG_FNAME NOX("Tcp.cfg")
|
|
|
|
#define IP_EMPTY_STRING ""
|
|
|
|
int Ip_list_coords[GR_NUM_RESOLUTIONS][4] = {
|
|
{
|
|
29, 137, 227, 67 // GR_640
|
|
},
|
|
{
|
|
46, 220, 364, 106 // GR_1024
|
|
}
|
|
};
|
|
|
|
|
|
int Ip_list_max_display[GR_NUM_RESOLUTIONS] = {
|
|
5,
|
|
5
|
|
};
|
|
|
|
static int Ip_input_coords[GR_NUM_RESOLUTIONS][4] = {
|
|
{
|
|
109, 128, 140, -1 // GR_640
|
|
},
|
|
{
|
|
132, 206, 261, -1 // GR_640
|
|
}
|
|
};
|
|
|
|
int Om_input_mode = 0;
|
|
int Om_ip_start; // index of the first element to be displayed in the list box
|
|
int Om_ip_selected; // the selected default IP address
|
|
int Om_ip_disp_count; // how many items are currently being displayed
|
|
int Om_num_ips; // # of ip addresses we have
|
|
char Om_ip_addrs[MAX_IP_ADDRS][IP_STRING_LEN]; // the ip addresses themselves
|
|
UI_BUTTON Om_ip_button; // button for detecting clicks on the ip address list
|
|
UI_INPUTBOX Om_ip_input; // input box for adding new ip addresses
|
|
|
|
// setting vars
|
|
bool Om_local_broadcast; // whether the player has local broadcast selected or not
|
|
bool Om_tracker_flag; // whether the player has the PXO tracker selected
|
|
int Om_protocol; // protocol in use
|
|
|
|
// load all the controls for the protocol section
|
|
void options_multi_load_protocol_controls();
|
|
|
|
// disable/hide all the controls for the protocol section
|
|
void options_multi_disable_protocol_controls();
|
|
|
|
// enable/unhide all the controls for the protocol section
|
|
void options_multi_enable_protocol_controls();
|
|
|
|
// intialize the protocol section vars
|
|
void options_multi_init_protocol_vars();
|
|
|
|
// do frame for the protocol section
|
|
void options_multi_protocol_do(int key);
|
|
|
|
// if the accept button was hit
|
|
void options_multi_protocol_accept();
|
|
|
|
// check for button presses
|
|
void options_multi_protocol_check_buttons();
|
|
|
|
// if a button was pressed
|
|
void options_multi_protocol_button_pressed(int n);
|
|
|
|
// load the ip address file
|
|
void options_multi_protocol_load_ip_file();
|
|
|
|
// save the ip address file
|
|
void options_multi_protocol_save_ip_file();
|
|
|
|
// draw the list of ip addresses
|
|
void options_multi_protocol_display_ips();
|
|
|
|
// scroll the list of ip addresses down
|
|
void options_multi_protocol_scroll_ip_down();
|
|
|
|
// scroll the list of ip addresses up
|
|
void options_multi_protocol_scroll_ip_up();
|
|
|
|
// check the ip list to see if the user has selected a new item
|
|
void options_multi_protocol_check_ip_list();
|
|
|
|
// delete the currently selected ip if any
|
|
void options_multi_protocol_delete_ip();
|
|
|
|
// attempt to add the currently entered ip address
|
|
void options_multi_protocol_add_current_ip();
|
|
|
|
|
|
// general options tab section -------------------------------------------
|
|
#define OM_GEN_NUM_BUTTONS 10
|
|
|
|
#define OM_GEN_OBJ_LOW 0
|
|
#define OM_GEN_OBJ_MED 1
|
|
#define OM_GEN_OBJ_HIGH 2
|
|
#define OM_GEN_OBJ_LAN 3
|
|
#define OM_GEN_PIX_YES 4
|
|
#define OM_GEN_PIX_NO 5
|
|
#define OM_GEN_XFER_MULTIDATA_YES 6
|
|
#define OM_GEN_XFER_MULTIDATA_NO 7
|
|
#define OM_GEN_FLUSH_NO 8
|
|
#define OM_GEN_FLUSH_YES 9
|
|
|
|
ui_button_info Om_gen_buttons[GR_NUM_RESOLUTIONS][OM_GEN_NUM_BUTTONS] = {
|
|
{ // GR_640
|
|
ui_button_info("OGB_17", 598, 117, -1, -1, 17),
|
|
ui_button_info("OGB_18", 598, 139, -1, -1, 18),
|
|
ui_button_info("OGB_19", 598, 161, -1, -1, 19),
|
|
ui_button_info("OGB_20", 598, 183, -1, -1, 20),
|
|
ui_button_info("OGB_21", 549, 229, -1, -1, 21),
|
|
ui_button_info("OGB_22", 598, 229, -1, -1, 22),
|
|
ui_button_info("OGB_23", 598, 286, -1, -1, 23),
|
|
ui_button_info("OGB_24", 598, 307, -1, -1, 24),
|
|
ui_button_info("OGB_25", 598, 347, -1, -1, 25),
|
|
ui_button_info("OGB_26", 598, 368, -1, -1, 26),
|
|
},
|
|
{ // GR_1024
|
|
ui_button_info("2_OGB_17", 957, 188, -1, -1, 17),
|
|
ui_button_info("2_OGB_18", 957, 223, -1, -1, 18),
|
|
ui_button_info("2_OGB_19", 957, 258, -1, -1, 19),
|
|
ui_button_info("2_OGB_20", 957, 293, -1, -1, 20),
|
|
ui_button_info("2_OGB_21", 879, 366, -1, -1, 21),
|
|
ui_button_info("2_OGB_22", 957, 366, -1, -1, 22),
|
|
ui_button_info("2_OGB_23", 957, 457, -1, -1, 23),
|
|
ui_button_info("2_OGB_24", 957, 491, -1, -1, 24),
|
|
ui_button_info("2_OGB_25", 957, 555, -1, -1, 25),
|
|
ui_button_info("2_OGB_26", 957, 589, -1, -1, 26),
|
|
}
|
|
};
|
|
|
|
UI_GADGET Om_gen_bogus;
|
|
|
|
// text
|
|
#define OM_GEN_NUM_TEXT 14
|
|
UI_XSTR Om_gen_text[GR_NUM_RESOLUTIONS][OM_GEN_NUM_TEXT] = {
|
|
{ // GR_640
|
|
{ "Object Update", 1391, 511, 104, UI_XSTR_COLOR_GREEN, -1, &Om_gen_bogus },
|
|
{ "Low", 1160, 558, 127, UI_XSTR_COLOR_GREEN, -1, &Om_gen_buttons[0][OM_GEN_OBJ_LOW].button },
|
|
{ "Medium", 1161, 538, 149, UI_XSTR_COLOR_GREEN, -1, &Om_gen_buttons[0][OM_GEN_OBJ_MED].button },
|
|
{ "High", 1162, 556, 171, UI_XSTR_COLOR_GREEN, -1, &Om_gen_buttons[0][OM_GEN_OBJ_HIGH].button },
|
|
{ "Lan", 1392, 561, 193, UI_XSTR_COLOR_GREEN, -1, &Om_gen_buttons[0][OM_GEN_OBJ_LAN].button },
|
|
{ "Pilot / Squad Images", 1393, 463, 214, UI_XSTR_COLOR_GREEN, -1, &Om_gen_bogus },
|
|
{ "Yes", 1394, 555, 257, UI_XSTR_COLOR_GREEN, -1, &Om_gen_buttons[0][OM_GEN_PIX_YES].button },
|
|
{ "No", 1395, 604, 257, UI_XSTR_COLOR_GREEN, -1, &Om_gen_buttons[0][OM_GEN_PIX_NO].button },
|
|
{ "Transfer Missions", 1396, 478, 271, UI_XSTR_COLOR_GREEN, -1, &Om_gen_bogus },
|
|
{ "/multidata", 1397, 519, 292, UI_XSTR_COLOR_GREEN, -1, &Om_gen_buttons[0][OM_GEN_XFER_MULTIDATA_YES].button },
|
|
{ "/missions", 1398, 527, 314, UI_XSTR_COLOR_GREEN, -1, &Om_gen_buttons[0][OM_GEN_XFER_MULTIDATA_NO].button },
|
|
{ "Flush Cache", 1399, 529, 334, UI_XSTR_COLOR_GREEN, -1, &Om_gen_bogus },
|
|
{ "Never", 1400, 548, 355, UI_XSTR_COLOR_GREEN, -1, &Om_gen_buttons[0][OM_GEN_FLUSH_NO].button },
|
|
{ "Before Game", 1401, 502, 377, UI_XSTR_COLOR_GREEN, -1, &Om_gen_buttons[0][OM_GEN_FLUSH_YES].button },
|
|
},
|
|
{ // GR_1024
|
|
{ "Object Update", 1391, 818, 166, UI_XSTR_COLOR_GREEN, -1, &Om_gen_bogus },
|
|
{ "Low", 1160, 913, 204, UI_XSTR_COLOR_GREEN, -1, &Om_gen_buttons[1][OM_GEN_OBJ_LOW].button },
|
|
{ "Medium", 1161, 892, 239, UI_XSTR_COLOR_GREEN, -1, &Om_gen_buttons[1][OM_GEN_OBJ_MED].button },
|
|
{ "High", 1162, 909, 274, UI_XSTR_COLOR_GREEN, -1, &Om_gen_buttons[1][OM_GEN_OBJ_HIGH].button },
|
|
{ "Lan", 1392, 916, 310, UI_XSTR_COLOR_GREEN, -1, &Om_gen_buttons[1][OM_GEN_OBJ_LAN].button },
|
|
{ "Pilot / Squad Images", 1393, 821, 345, UI_XSTR_COLOR_GREEN, -1, &Om_gen_bogus },
|
|
{ "Yes", 1394, 887, 411, UI_XSTR_COLOR_GREEN, -1, &Om_gen_buttons[1][OM_GEN_PIX_YES].button },
|
|
{ "No", 1395, 966, 411, UI_XSTR_COLOR_GREEN, -1, &Om_gen_buttons[1][OM_GEN_PIX_NO].button },
|
|
{ "Transfer Missions", 1396, 844, 435, UI_XSTR_COLOR_GREEN, -1, &Om_gen_bogus },
|
|
{ "/multidata", 1397, 858, 468, UI_XSTR_COLOR_GREEN, -1, &Om_gen_buttons[1][OM_GEN_XFER_MULTIDATA_YES].button },
|
|
{ "/missions", 1398, 870, 503, UI_XSTR_COLOR_GREEN, -1, &Om_gen_buttons[1][OM_GEN_XFER_MULTIDATA_NO].button },
|
|
{ "Flush Cache", 1399, 886, 533, UI_XSTR_COLOR_GREEN, -1, &Om_gen_bogus },
|
|
{ "Never", 1400, 897, 568, UI_XSTR_COLOR_GREEN, -1, &Om_gen_buttons[1][OM_GEN_FLUSH_NO].button },
|
|
{ "Before Game", 1401, 849, 603, UI_XSTR_COLOR_GREEN, -1, &Om_gen_buttons[1][OM_GEN_FLUSH_YES].button },
|
|
}
|
|
};
|
|
|
|
// setting vars
|
|
int Om_gen_obj_update; // object update level
|
|
bool Om_gen_pix; // accept pilot pix or not
|
|
bool Om_gen_xfer_multidata; // xfer missions to multidata or not
|
|
bool Om_gen_flush_cache; // flush multidata directory before every game
|
|
|
|
// load all the general tab controls
|
|
void options_multi_load_gen_controls();
|
|
|
|
// disable/hide all the general tab controls
|
|
void options_multi_disable_gen_controls();
|
|
|
|
// enable/unhide all the general tab controls
|
|
void options_multi_enable_gen_controls();
|
|
|
|
// initialize the general tab vars
|
|
void options_multi_init_gen_vars();
|
|
|
|
// accept function for the general tab
|
|
void options_multi_gen_accept();
|
|
|
|
// do frame for the general tab
|
|
void options_multi_gen_do();
|
|
|
|
// check for button presses
|
|
void options_multi_gen_check_buttons();
|
|
|
|
// a button was pressed
|
|
void options_multi_gen_button_pressed(int n);
|
|
|
|
|
|
// voice options tab section -------------------------------------------
|
|
#define OM_VOX_NUM_BUTTONS 6
|
|
|
|
#define OM_VOX_VOICE_TEST 0
|
|
#define OM_VOX_VOICE_YES 1
|
|
#define OM_VOX_VOICE_NO 2
|
|
#define OM_VOX_PLIST_UP 3
|
|
#define OM_VOX_PLIST_DOWN 4
|
|
#define OM_VOX_VOICE_MUTE 5
|
|
|
|
UI_GADGET Om_vox_bogus;
|
|
|
|
ui_button_info Om_vox_buttons[GR_NUM_RESOLUTIONS][OM_VOX_NUM_BUTTONS] = {
|
|
{ // GR_640
|
|
ui_button_info("OVB_17", 562, 118, -1, -1, 17),
|
|
ui_button_info("OVB_19", 551, 208, -1, -1, 19),
|
|
ui_button_info("OVB_20", 599, 208, -1, -1, 20),
|
|
ui_button_info("OVB_21", 614, 256, -1, -1, 21),
|
|
ui_button_info("OVB_22", 614, 290, -1, -1, 22),
|
|
ui_button_info("OVB_23", 599, 354, -1, -1, 23),
|
|
},
|
|
{ // GR_640
|
|
ui_button_info("2_OVB_17", 900, 189, -1, -1, 17),
|
|
ui_button_info("2_OVB_19", 882, 333, -1, -1, 19),
|
|
ui_button_info("2_OVB_20", 959, 333, -1, -1, 20),
|
|
ui_button_info("2_OVB_21", 983, 410, -1, -1, 21),
|
|
ui_button_info("2_OVB_22", 983, 464, -1, -1, 22),
|
|
ui_button_info("2_OVB_23", 959, 566, -1, -1, 23),
|
|
}
|
|
};
|
|
|
|
// text
|
|
#define OM_VOX_NUM_TEXT 6
|
|
UI_XSTR Om_vox_text[GR_NUM_RESOLUTIONS][OM_VOX_NUM_TEXT] = {
|
|
{ // GR_640
|
|
{ "Mic test", 1389, 567, 104, UI_XSTR_COLOR_GREEN, -1, &Om_vox_buttons[0][OM_VOX_VOICE_TEST].button },
|
|
{ "Voice Quality", 1531, 439, 149, UI_XSTR_COLOR_GREEN, -1, &Om_vox_bogus },
|
|
{ "Voice Transmission", 1530, 439, 193, UI_XSTR_COLOR_GREEN, -1, &Om_vox_bogus },
|
|
{ "On", 1285, 556, 233, UI_XSTR_COLOR_GREEN, -1, &Om_vox_buttons[0][OM_VOX_VOICE_YES].button },
|
|
{ "Off", 1286, 604, 233, UI_XSTR_COLOR_GREEN, -1, &Om_vox_buttons[0][OM_VOX_VOICE_NO].button },
|
|
{ "Mute", 1390, 594, 381, UI_XSTR_COLOR_GREEN, -1, &Om_vox_buttons[0][OM_VOX_VOICE_MUTE].button },
|
|
},
|
|
{ // GR_1024
|
|
{ "mic test", 1389, 908, 166, UI_XSTR_COLOR_GREEN, -1, &Om_vox_buttons[1][OM_VOX_VOICE_TEST].button },
|
|
{ "Voice Quality", 1531, 703, 239, UI_XSTR_COLOR_GREEN, -1, &Om_vox_bogus },
|
|
{ "Voice Transmission", 1530, 783, 310, UI_XSTR_COLOR_GREEN, -1, &Om_vox_bogus },
|
|
{ "On", 1285, 890, 373, UI_XSTR_COLOR_GREEN, -1, &Om_vox_buttons[1][OM_VOX_VOICE_YES].button },
|
|
{ "Off", 1286, 967, 373, UI_XSTR_COLOR_GREEN, -1, &Om_vox_buttons[1][OM_VOX_VOICE_NO].button },
|
|
{ "Mute", 1390, 950, 609, UI_XSTR_COLOR_GREEN, -1, &Om_vox_buttons[1][OM_VOX_VOICE_MUTE].button },
|
|
}
|
|
};
|
|
|
|
#define NUM_OM_VOX_SLIDERS 1
|
|
#define OM_VOX_QOS_SLIDER 0
|
|
|
|
op_sliders Om_vox_sliders[GR_NUM_RESOLUTIONS][NUM_OM_VOX_SLIDERS] = {
|
|
{ // GR_640
|
|
op_sliders("OVB_18", 429, 162, -1, -1, 18, 20, 10, NULL, -1, -1, -1, NULL, -1, -1, -1), // voice QOS
|
|
},
|
|
{ // GR_1024
|
|
op_sliders("2_OVB_18", 686, 259, -1, -1, 18, 31, 10, NULL, -1, -1, -1, NULL, -1, -1, -1), // voice QOS
|
|
}
|
|
};
|
|
|
|
// player list area
|
|
int Om_vox_plist_coords[GR_NUM_RESOLUTIONS][4] = {
|
|
{ // GR_640
|
|
377, 270, 232, 79
|
|
},
|
|
{ // GR_1024
|
|
604, 432, 371, 127
|
|
}
|
|
};
|
|
int Om_vox_plist_max_display[GR_NUM_RESOLUTIONS] = {
|
|
6,
|
|
6
|
|
};
|
|
|
|
int Om_vox_plist_start;
|
|
UI_BUTTON Om_vox_plist_button;
|
|
|
|
// voice test buffer
|
|
#define OM_VOX_BUF_SIZE (1<<12)
|
|
#define OM_VOX_COMP_SIZE ((1<<15) + (1<<14))
|
|
|
|
#define OM_VOX_WAVE_Y 240
|
|
#define OM_VOX_WAVE_WIDTH 300
|
|
|
|
#define OM_VOX_DROP_ICON_X 100
|
|
#define OM_VOX_DROP_ICON_Y 100
|
|
|
|
#define OM_VOX_RECORD_INT 175
|
|
|
|
unsigned char Om_vox_voice_buffer[OM_VOX_BUF_SIZE];
|
|
int Om_vox_voice_buffer_size = -1;
|
|
|
|
unsigned char Om_vox_comp_buffer[OM_VOX_COMP_SIZE];
|
|
int Om_vox_voice_comp_size = -1;
|
|
|
|
sound_handle Om_vox_playback_handle;
|
|
|
|
// status of any test voice recording
|
|
#define OM_VOX_TEST_NONE -1
|
|
#define OM_VOX_TEST_RECORDING 0
|
|
#define OM_VOX_TEST_PLAYBACK 1
|
|
int Om_vox_test_status = OM_VOX_TEST_NONE;
|
|
|
|
// setting vars
|
|
int Om_vox_accept_voice;
|
|
|
|
// simple list of players we are looking through
|
|
net_player *Om_vox_players[MAX_PLAYERS];
|
|
|
|
// selected player
|
|
net_player *Om_vox_player_select;
|
|
|
|
// mute or don't mute for each player
|
|
int Om_vox_player_flags[MAX_PLAYERS];
|
|
|
|
// the # of players
|
|
int Om_vox_num_players;
|
|
|
|
// load all the voice tab controls
|
|
void options_multi_load_vox_controls();
|
|
|
|
// disable/hide all the voice tab controls
|
|
void options_multi_disable_vox_controls();
|
|
|
|
// enable/unhide all the voice tab controls
|
|
void options_multi_enable_vox_controls();
|
|
|
|
// initialize the voice tab vars
|
|
void options_multi_init_vox_vars();
|
|
|
|
// accept function for the voice tab
|
|
void options_multi_vox_accept();
|
|
|
|
// do frame for the voice tab
|
|
void options_multi_vox_do();
|
|
|
|
// check for button presses
|
|
void options_multi_vox_check_buttons();
|
|
|
|
// a button was pressed
|
|
void options_multi_vox_button_pressed(int n);
|
|
|
|
// process/display the player list
|
|
void options_multi_vox_process_player_list();
|
|
|
|
// scroll the player list down
|
|
void options_multi_vox_plist_scroll_down();
|
|
|
|
// scroll the player list up
|
|
void options_multi_vox_plist_scroll_up();
|
|
|
|
// get the index into the player list of the passed netplayer
|
|
int options_multi_vox_plist_get(net_player *pl);
|
|
|
|
|
|
// general data section ------------------------------------------------
|
|
|
|
// load all background bitmaps
|
|
void options_multi_load_bmaps()
|
|
{
|
|
// load both background bitmaps
|
|
Om_background_0 = bm_load(Om_background_0_fname[gr_screen.res]);
|
|
if(Om_background_0 == -1){
|
|
nprintf(("Network","Error loading options background %s\n",Om_background_0_fname[gr_screen.res]));
|
|
}
|
|
|
|
Om_background_1 = bm_load(Om_background_1_fname[gr_screen.res]);
|
|
if(Om_background_1 == -1){
|
|
nprintf(("Network","Error loading options background %s\n",Om_background_1_fname[gr_screen.res]));
|
|
}
|
|
|
|
// load in both mask bitmaps
|
|
Om_mask_0 = bm_load(Om_background_0_mask_fname[gr_screen.res]);
|
|
if(Om_mask_0 == -1){
|
|
nprintf(("Network","Error loading options background mask %s\n",Om_background_0_mask_fname[gr_screen.res]));
|
|
}
|
|
|
|
Om_mask_1 = bm_load(Om_background_1_mask_fname[gr_screen.res]);
|
|
if(Om_mask_1 == -1){
|
|
nprintf(("Network","Error loading options background mask %s\n",Om_background_1_mask_fname[gr_screen.res]));
|
|
}
|
|
}
|
|
|
|
// unload all the background bitmaps
|
|
void options_multi_unload_bmaps()
|
|
{
|
|
// unload all background bitmaps
|
|
if(Om_background_0 != -1){
|
|
bm_release(Om_background_0);
|
|
Om_background_0 = -1;
|
|
}
|
|
if(Om_background_1 != -1){
|
|
bm_release(Om_background_1);
|
|
Om_background_1 = -1;
|
|
}
|
|
|
|
// unload all mask bitmaps
|
|
if(Om_mask_0 != -1){
|
|
bm_release(Om_mask_0);
|
|
Om_mask_0 = -1;
|
|
}
|
|
if(Om_mask_1 != -1){
|
|
bm_release(Om_mask_1);
|
|
Om_mask_1 = -1;
|
|
}
|
|
}
|
|
|
|
// add a notification message
|
|
void options_multi_add_notify(const char *str)
|
|
{
|
|
// copy the string
|
|
memset(Om_notify_string,0,255);
|
|
if(str != NULL){
|
|
strcpy_s(Om_notify_string,str);
|
|
}
|
|
|
|
// set the timestamp
|
|
Om_notify_stamp = ui_timestamp(OM_NOTIFY_TIME);
|
|
}
|
|
|
|
// process and blit any notification messages
|
|
void options_multi_notify_process()
|
|
{
|
|
int w;
|
|
const char *p_str[3];
|
|
int n_chars[3];
|
|
char line[OM_NOTIFICATION_LINE_LEN];
|
|
int line_count;
|
|
int y_start;
|
|
int idx;
|
|
int line_height;
|
|
|
|
// if there is no timestamp, do nothing
|
|
if (!Om_notify_stamp.isValid()){
|
|
return;
|
|
}
|
|
|
|
// otherwise, if it has elapsed, unset it
|
|
if (ui_timestamp_elapsed(Om_notify_stamp)){
|
|
Om_notify_stamp = UI_TIMESTAMP::invalid();
|
|
return;
|
|
}
|
|
|
|
// otherwise display the string
|
|
line_height = gr_get_font_height() + 1;
|
|
line_count = split_str(Om_notify_string, 600, n_chars, p_str, 3, OM_NOTIFICATION_LINE_LEN);
|
|
y_start = OM_NOTIFY_Y;
|
|
gr_set_color_fast(&Color_bright);
|
|
for(idx=0;idx<line_count;idx++){
|
|
memset(line, 0, OM_NOTIFICATION_LINE_LEN);
|
|
strncpy(line, p_str[idx], n_chars[idx]);
|
|
|
|
gr_get_string_size(&w,NULL,line);
|
|
gr_string((600 - w)/2,y_start,line,GR_RESIZE_MENU);
|
|
|
|
y_start += line_height;
|
|
}
|
|
}
|
|
|
|
|
|
// protocol section --------------------------------------------------------
|
|
|
|
// load all the controls for the protocol section
|
|
void options_multi_load_protocol_controls()
|
|
{
|
|
int idx;
|
|
|
|
Assert(Om_window != NULL);
|
|
|
|
// instantiate all the buttons
|
|
for(idx=0; idx<OM_PRO_NUM_BUTTONS; idx++){
|
|
// create the object
|
|
Om_pro_buttons[gr_screen.res][idx].button.create(Om_window, "", Om_pro_buttons[gr_screen.res][idx].x, Om_pro_buttons[gr_screen.res][idx].y, 1, 1, 0, 1);
|
|
|
|
// set the sound to play when highlighted
|
|
Om_pro_buttons[gr_screen.res][idx].button.set_highlight_action(common_play_highlight_sound);
|
|
|
|
// set the ani for the button
|
|
Om_pro_buttons[gr_screen.res][idx].button.set_bmaps(Om_pro_buttons[gr_screen.res][idx].filename);
|
|
|
|
// set the hotspot
|
|
Om_pro_buttons[gr_screen.res][idx].button.link_hotspot(Om_pro_buttons[gr_screen.res][idx].hotspot);
|
|
}
|
|
|
|
// text
|
|
for(idx=0; idx<OM_PRO_NUM_TEXT; idx++){
|
|
Om_window->add_XSTR(&Om_pro_text[gr_screen.res][idx]);
|
|
}
|
|
|
|
// create the tracker input boxes
|
|
Om_tracker_login.create(Om_window, Om_tracker_login_coords[gr_screen.res][0], Om_tracker_login_coords[gr_screen.res][1], Om_tracker_login_coords[gr_screen.res][2], LOGIN_LEN - 1, Multi_tracker_login, UI_INPUTBOX_FLAG_INVIS | UI_INPUTBOX_FLAG_ESC_CLR | UI_INPUTBOX_FLAG_KEYTHRU | UI_INPUTBOX_FLAG_NO_BACK);
|
|
Om_tracker_passwd.create(Om_window, Om_tracker_passwd_coords[gr_screen.res][0], Om_tracker_passwd_coords[gr_screen.res][1], Om_tracker_passwd_coords[gr_screen.res][2], LOGIN_LEN - 1, Multi_tracker_passwd, UI_INPUTBOX_FLAG_INVIS | UI_INPUTBOX_FLAG_ESC_CLR | UI_INPUTBOX_FLAG_PASSWD | UI_INPUTBOX_FLAG_KEYTHRU | UI_INPUTBOX_FLAG_NO_BACK);
|
|
Om_tracker_squad_name.create(Om_window, Om_tracker_squad_name_coords[gr_screen.res][0], Om_tracker_squad_name_coords[gr_screen.res][1], Om_tracker_squad_name_coords[gr_screen.res][2], LOGIN_LEN - 1, Multi_tracker_squad_name, UI_INPUTBOX_FLAG_INVIS | UI_INPUTBOX_FLAG_ESC_CLR | UI_INPUTBOX_FLAG_KEYTHRU | UI_INPUTBOX_FLAG_NO_BACK);
|
|
|
|
// create the invisible button for checking for clicks on the ip address list
|
|
Om_ip_button.create(Om_window, "", Ip_list_coords[gr_screen.res][0], Ip_list_coords[gr_screen.res][1], Ip_list_coords[gr_screen.res][2], Ip_list_coords[gr_screen.res][3], 0, 1);
|
|
Om_ip_button.hide();
|
|
|
|
// create the new ip address input box
|
|
Om_ip_input.create(Om_window, Ip_input_coords[gr_screen.res][0], Ip_input_coords[gr_screen.res][1], Ip_input_coords[gr_screen.res][2], IP_STRING_LEN, IP_EMPTY_STRING, UI_INPUTBOX_FLAG_INVIS | UI_INPUTBOX_FLAG_ESC_CLR | UI_INPUTBOX_FLAG_KEYTHRU);
|
|
Om_ip_input.hide();
|
|
Om_ip_input.disable();
|
|
|
|
// bogus control
|
|
Om_pro_bogus.base_create(Om_window, UI_KIND_ICON, 0, 0, 0, 0);
|
|
}
|
|
|
|
// disable/hide all the controls for the protocol section
|
|
void options_multi_disable_protocol_controls()
|
|
{
|
|
int idx;
|
|
|
|
// hide and disable all the protocol buttons
|
|
for(idx=0;idx<OM_PRO_NUM_BUTTONS;idx++){
|
|
// hide the button
|
|
Om_pro_buttons[gr_screen.res][idx].button.hide();
|
|
|
|
// disable the button
|
|
Om_pro_buttons[gr_screen.res][idx].button.disable();
|
|
}
|
|
|
|
// hide and disable the tracker input boxes
|
|
Om_tracker_login.hide();
|
|
Om_tracker_login.disable();
|
|
Om_tracker_passwd.hide();
|
|
Om_tracker_passwd.disable();
|
|
Om_tracker_squad_name.hide();
|
|
Om_tracker_squad_name.disable();
|
|
|
|
// disable the click detection button
|
|
Om_ip_button.disable();
|
|
|
|
// disable and hide the ip address inputbox
|
|
Om_ip_input.hide();
|
|
Om_ip_input.disable();
|
|
|
|
// undo input mode if necessary
|
|
Om_input_mode = 0;
|
|
|
|
// bogus control
|
|
Om_pro_bogus.hide();
|
|
Om_pro_bogus.disable();
|
|
}
|
|
|
|
// enable/unhide all the controls for the protocol section
|
|
void options_multi_enable_protocol_controls()
|
|
{
|
|
int idx;
|
|
|
|
// unhide and enable all the protocol buttons
|
|
for(idx=0;idx<OM_PRO_NUM_BUTTONS;idx++){
|
|
// enable the button
|
|
Om_pro_buttons[gr_screen.res][idx].button.enable();
|
|
|
|
// unhide the button
|
|
Om_pro_buttons[gr_screen.res][idx].button.unhide();
|
|
}
|
|
|
|
// unhide and enable the tracker input boxes
|
|
if(Om_tracker_flag){
|
|
Om_tracker_login.enable();
|
|
Om_tracker_passwd.enable();
|
|
Om_tracker_squad_name.enable();
|
|
}
|
|
Om_tracker_login.unhide();
|
|
Om_tracker_passwd.unhide();
|
|
Om_tracker_squad_name.unhide();
|
|
|
|
// enable the click detection button
|
|
Om_ip_button.enable();
|
|
|
|
// bogus control
|
|
Om_pro_bogus.enable();
|
|
Om_pro_bogus.unhide();
|
|
}
|
|
|
|
// intialize the protocol section vars
|
|
void options_multi_init_protocol_vars()
|
|
{
|
|
// current protocol
|
|
Om_protocol = Multi_options_g.protocol;
|
|
|
|
// whether or not the user has the local broadcast button selected
|
|
Om_local_broadcast = (Player->m_local_options.flags & MLO_FLAG_LOCAL_BROADCAST);
|
|
|
|
// whether or not we're playing on the tracker
|
|
Om_tracker_flag = Multi_options_g.pxo;
|
|
|
|
// load the ip address list
|
|
Om_ip_disp_count = 0;
|
|
options_multi_protocol_load_ip_file();
|
|
Om_ip_selected = Om_num_ips - 1;
|
|
Om_ip_start = Om_num_ips - 1;
|
|
}
|
|
|
|
// do frame for the protocol section
|
|
void options_multi_protocol_do(int key)
|
|
{
|
|
// check for button presses
|
|
options_multi_protocol_check_buttons();
|
|
|
|
// force draw the correct "local broadcast" button
|
|
if(Om_local_broadcast){
|
|
Om_pro_buttons[gr_screen.res][OM_PRO_LOCAL_BROADCAST].button.draw_forced(2);
|
|
}
|
|
|
|
// draw the "vmt" button if it is selected
|
|
if(Om_tracker_flag){
|
|
Om_pro_buttons[gr_screen.res][OM_PRO_VMT].button.draw_forced(2);
|
|
}
|
|
|
|
// see if he hit any interesting key presses
|
|
switch(key){
|
|
case KEY_ENTER:
|
|
// add a new ip string if we're in "input" mode
|
|
if(Om_input_mode){
|
|
options_multi_protocol_add_current_ip();
|
|
|
|
// clear the text control and input mode
|
|
Om_ip_input.set_text("");
|
|
Om_ip_input.clear_focus();
|
|
Om_ip_input.disable();
|
|
Om_input_mode = 0;
|
|
}
|
|
|
|
// if the tracker login inputbox has focus, lose it
|
|
if(Om_tracker_login.has_focus()){
|
|
Om_tracker_login.clear_focus();
|
|
gamesnd_play_iface(InterfaceSounds::COMMIT_PRESSED);
|
|
}
|
|
// if the tracker password inputbox has focus, lose it
|
|
if(Om_tracker_passwd.has_focus()){
|
|
Om_tracker_passwd.clear_focus();
|
|
gamesnd_play_iface(InterfaceSounds::COMMIT_PRESSED);
|
|
}
|
|
// if the tracker squad name inputbox has focus, lose it
|
|
if(Om_tracker_squad_name.has_focus()){
|
|
Om_tracker_squad_name.clear_focus();
|
|
gamesnd_play_iface(InterfaceSounds::COMMIT_PRESSED);
|
|
}
|
|
break;
|
|
|
|
case KEY_ESC:
|
|
// if we're in input mode, cancel out
|
|
if(Om_input_mode){
|
|
// clear the text control and input mode
|
|
Om_ip_input.set_text("");
|
|
Om_ip_input.clear_focus();
|
|
Om_ip_input.disable();
|
|
Om_input_mode = 0;
|
|
}
|
|
// otherwise quit the options screen altogether
|
|
else {
|
|
// reaching this section is unlikely because
|
|
// escape key detection is already executed
|
|
// within options_menu_do_frame(),
|
|
// which runs before options_multi_do()
|
|
// --wookieejedi
|
|
options_cancel_exit();
|
|
return;
|
|
}
|
|
break;
|
|
|
|
case KEY_TAB:
|
|
// tab through the tracker input controls
|
|
if(Om_tracker_login.has_focus()){
|
|
Om_tracker_passwd.set_focus();
|
|
} else if(Om_tracker_passwd.has_focus()){
|
|
Om_tracker_squad_name.set_focus();
|
|
} else if(Om_tracker_squad_name.has_focus()){
|
|
Om_tracker_login.set_focus();
|
|
}
|
|
break;
|
|
}
|
|
|
|
// force draw the proper protocol
|
|
Om_pro_buttons[gr_screen.res][OM_PRO_TCP].button.draw_forced(2);
|
|
|
|
// force draw the proper tab button
|
|
switch (Om_mode) {
|
|
case OM_MODE_GENERAL:
|
|
Om_pro_buttons[gr_screen.res][OM_PRO_GEN_TAB].button.draw_forced(2);
|
|
break;
|
|
|
|
case OM_MODE_VOX:
|
|
Om_pro_buttons[gr_screen.res][OM_PRO_VOX_TAB].button.draw_forced(2);
|
|
break;
|
|
}
|
|
|
|
// check to see if the user has clicked on the ip list and selected a new item
|
|
options_multi_protocol_check_ip_list();
|
|
|
|
// draw the list of ip addresses
|
|
options_multi_protocol_display_ips();
|
|
|
|
// hack to play sound when input boxes gain focus
|
|
if (Om_tracker_login.has_focus()) {
|
|
if (Om_tracker_focus != TRACKER_FOCUS_LOGIN) {
|
|
Om_tracker_focus = TRACKER_FOCUS_LOGIN;
|
|
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
|
}
|
|
} else if (Om_tracker_passwd.has_focus()) {
|
|
if (Om_tracker_focus != TRACKER_FOCUS_PASSWORD) {
|
|
Om_tracker_focus = TRACKER_FOCUS_PASSWORD;
|
|
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
|
}
|
|
} else if (Om_tracker_squad_name.has_focus()) {
|
|
if (Om_tracker_focus != TRACKER_FOCUS_SQUADRON) {
|
|
Om_tracker_focus = TRACKER_FOCUS_SQUADRON;
|
|
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
|
}
|
|
} else {
|
|
Om_tracker_focus = TRACKER_FOCUS_NONE;
|
|
}
|
|
}
|
|
|
|
// if the accept button was hit
|
|
void options_multi_protocol_accept()
|
|
{
|
|
// if the user has selected local broadcast write it into his options struct
|
|
Player->m_local_options.flags &= ~(MLO_FLAG_LOCAL_BROADCAST);
|
|
if (Om_local_broadcast) {
|
|
Player->m_local_options.flags |= MLO_FLAG_LOCAL_BROADCAST;
|
|
}
|
|
options::OptionsManager::instance()->set_ingame_binary_option("Multi.LocalBroadcast", Om_local_broadcast);
|
|
|
|
// active protocol
|
|
Multi_options_g.protocol = Om_protocol;
|
|
|
|
// VMT status
|
|
Multi_options_g.pxo = Om_tracker_flag;
|
|
options::OptionsManager::instance()->set_ingame_binary_option("Multi.TogglePXO", Om_tracker_flag);
|
|
|
|
// copy the VMT login, password and PXO squad name data
|
|
Om_tracker_login.get_text(Multi_tracker_login);
|
|
Om_tracker_passwd.get_text(Multi_tracker_passwd);
|
|
Om_tracker_squad_name.get_text(Multi_tracker_squad_name);
|
|
|
|
// write out the tracker login, passwd, and PXO squad name values to the registry
|
|
os_config_write_string( "PXO", "Login", Multi_tracker_login );
|
|
os_config_write_string( "PXO", "Password", Multi_tracker_passwd );
|
|
os_config_write_string( "PXO", "SquadName", Multi_tracker_squad_name );
|
|
|
|
// save the ip address list
|
|
options_multi_protocol_save_ip_file();
|
|
}
|
|
|
|
// check for button presses
|
|
void options_multi_protocol_check_buttons()
|
|
{
|
|
int idx;
|
|
|
|
// go through each button
|
|
for(idx=0;idx<OM_PRO_NUM_BUTTONS;idx++){
|
|
if(Om_pro_buttons[gr_screen.res][idx].button.pressed()){
|
|
options_multi_protocol_button_pressed(idx);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// if a button was pressed
|
|
void options_multi_protocol_button_pressed(int n)
|
|
{
|
|
switch(n){
|
|
// add an ip address
|
|
case OM_PRO_ADD_IP:
|
|
// don't process if we're in input mode
|
|
if(Om_input_mode){
|
|
break;
|
|
}
|
|
|
|
// setup the input mode
|
|
Om_input_mode = 1;
|
|
Om_ip_input.enable();
|
|
Om_ip_input.unhide();
|
|
Om_ip_input.set_text(IP_EMPTY_STRING);
|
|
Om_ip_input.set_focus();
|
|
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
|
break;
|
|
|
|
// delete the currently selected ip
|
|
case OM_PRO_DELETE_IP:
|
|
// don't process if we're in input mode
|
|
if(Om_input_mode){
|
|
break;
|
|
}
|
|
|
|
options_multi_protocol_delete_ip();
|
|
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
|
break;
|
|
|
|
// the "local" broadcast button - toggle
|
|
case OM_PRO_LOCAL_BROADCAST:
|
|
// don't process if we're in input mode
|
|
if(Om_input_mode){
|
|
break;
|
|
}
|
|
|
|
Om_local_broadcast = !Om_local_broadcast;
|
|
|
|
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
|
break;
|
|
|
|
// scroll ips down
|
|
case OM_PRO_SCROLL_IP_DOWN:
|
|
// don't process if we're in input mode
|
|
if(Om_input_mode){
|
|
break;
|
|
}
|
|
|
|
options_multi_protocol_scroll_ip_down();
|
|
break;
|
|
|
|
// scroll ips up
|
|
case OM_PRO_SCROLL_IP_UP:
|
|
// don't process if we're in input mode
|
|
if(Om_input_mode){
|
|
break;
|
|
}
|
|
|
|
options_multi_protocol_scroll_ip_up();
|
|
break;
|
|
|
|
// the vmt button
|
|
case OM_PRO_VMT:
|
|
// for the multiplayer beta, always force tracker mode
|
|
// don't process if we're in input mode
|
|
if(Om_input_mode){
|
|
break;
|
|
}
|
|
|
|
// toggle the stupid thing
|
|
Om_tracker_flag = !Om_tracker_flag;
|
|
|
|
// if the thing is toggled on - enable the inputbox controls, else diable them
|
|
if(Om_tracker_flag){
|
|
Om_tracker_login.enable();
|
|
Om_tracker_passwd.enable();
|
|
Om_tracker_squad_name.enable();
|
|
} else {
|
|
Om_tracker_login.disable();
|
|
Om_tracker_passwd.disable();
|
|
Om_tracker_squad_name.disable();
|
|
}
|
|
|
|
// play a sound
|
|
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
|
break;
|
|
|
|
// general tab button
|
|
case OM_PRO_GEN_TAB:
|
|
if(Om_mode != OM_MODE_GENERAL){
|
|
// set the general tab
|
|
Om_mode = OM_MODE_GENERAL;
|
|
|
|
// disable the voice controls
|
|
options_multi_disable_vox_controls();
|
|
|
|
// enable the general controls
|
|
options_multi_enable_gen_controls();
|
|
|
|
// set the general screen mask
|
|
Assert(Om_mask_0 >= 0);
|
|
Om_window->set_mask_bmap(Om_mask_0, Om_background_0_mask_fname[gr_screen.res]);
|
|
}
|
|
|
|
// play a sound
|
|
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
|
|
|
break;
|
|
|
|
// voice tab button
|
|
case OM_PRO_VOX_TAB:
|
|
if(Om_mode != OM_MODE_VOX){
|
|
// set the voice tab
|
|
Om_mode = OM_MODE_VOX;
|
|
|
|
// disable the general controls
|
|
options_multi_disable_gen_controls();
|
|
|
|
// enable the voice controls
|
|
options_multi_enable_vox_controls();
|
|
|
|
// set the voice screen mask
|
|
Assert(Om_mask_1 >= 0);
|
|
Om_window->set_mask_bmap(Om_mask_1, Om_background_1_mask_fname[gr_screen.res]);
|
|
}
|
|
// play a sound
|
|
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
|
|
|
break;
|
|
|
|
// tcp mode
|
|
case OM_PRO_TCP:
|
|
Om_protocol = NET_TCP;
|
|
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
|
break;
|
|
|
|
// ipx mode, no longer supported
|
|
case OM_PRO_IPX:
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, "The old IPX protocol is no longer supported.");
|
|
break;
|
|
}
|
|
}
|
|
|
|
// load the ip address file
|
|
void options_multi_protocol_load_ip_file()
|
|
{
|
|
// reset the ip address count
|
|
Om_num_ips = 0;
|
|
|
|
SCP_list<SCP_string> list;
|
|
multi_join_read_ip_address_file(list);
|
|
|
|
for (auto const &ip : list)
|
|
{
|
|
if (Om_num_ips < MAX_IP_ADDRS - 1) {
|
|
strcpy_s(Om_ip_addrs[Om_num_ips++], ip.c_str());
|
|
}
|
|
}
|
|
}
|
|
|
|
// save the ip address file
|
|
void options_multi_protocol_save_ip_file()
|
|
{
|
|
SCP_list<SCP_string> list;
|
|
|
|
// make a quick list
|
|
for(int idx=0;idx<Om_num_ips;idx++){
|
|
list.push_back(Om_ip_addrs[idx]);
|
|
}
|
|
|
|
multi_join_write_ip_address_file(list);
|
|
}
|
|
|
|
// draw the list of ip addresses
|
|
void options_multi_protocol_display_ips()
|
|
{
|
|
int idx;
|
|
int y_start = Ip_list_coords[gr_screen.res][1];
|
|
int line_height = gr_get_font_height() + 1;
|
|
|
|
// get the # of items we should be displaying based upon the # of addresses and the starting display point
|
|
if(Om_ip_start >= Ip_list_max_display[gr_screen.res]){
|
|
Om_ip_disp_count = Ip_list_max_display[gr_screen.res];
|
|
} else {
|
|
Om_ip_disp_count = Om_ip_start + 1;
|
|
}
|
|
|
|
// display the addresses
|
|
for(idx=Om_ip_start; idx >= Om_ip_start - Om_ip_disp_count + 1 ; idx--){
|
|
if(idx == Om_ip_selected){
|
|
gr_set_color_fast(&Color_bright);
|
|
} else {
|
|
gr_set_color_fast(&Color_white);
|
|
}
|
|
|
|
gr_printf_menu(Ip_list_coords[gr_screen.res][0], y_start, "%s", Om_ip_addrs[idx]);
|
|
y_start += line_height;
|
|
}
|
|
}
|
|
|
|
// scroll the list of ip addresses down
|
|
void options_multi_protocol_scroll_ip_down()
|
|
{
|
|
if(Om_ip_start >= Ip_list_max_display[gr_screen.res]){
|
|
gamesnd_play_iface(InterfaceSounds::SCROLL);
|
|
Om_ip_start--;
|
|
} else {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
}
|
|
}
|
|
|
|
// scroll the list of ip addresses up
|
|
void options_multi_protocol_scroll_ip_up()
|
|
{
|
|
if(Om_ip_start < Om_num_ips-1){
|
|
gamesnd_play_iface(InterfaceSounds::SCROLL);
|
|
Om_ip_start++;
|
|
} else {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
}
|
|
}
|
|
|
|
// check the ip list to see if the user has selected a new item
|
|
void options_multi_protocol_check_ip_list()
|
|
{
|
|
int click_y;
|
|
int item;
|
|
|
|
if(Om_ip_button.pressed()){
|
|
// determine which item he clicked on
|
|
Om_ip_button.get_mouse_pos(NULL, &click_y);
|
|
item = click_y / (gr_get_font_height() + 1);
|
|
|
|
// determine if there is an item in this location, and select it if so
|
|
if(item < Om_ip_disp_count){
|
|
Om_ip_selected = Om_ip_start - item;
|
|
}
|
|
}
|
|
}
|
|
|
|
// delete the currently selected ip if any
|
|
void options_multi_protocol_delete_ip()
|
|
{
|
|
int idx;
|
|
|
|
// attempt to delete the currently highlighted item
|
|
if(Om_ip_selected != -1){
|
|
|
|
// move down all the other items
|
|
for(idx=Om_ip_selected; idx < Om_num_ips; idx++){
|
|
strcpy_s(Om_ip_addrs[idx],Om_ip_addrs[idx+1]);
|
|
}
|
|
|
|
// make sure to decrement the starting index
|
|
Om_ip_start--;
|
|
|
|
// check to make sure that the selected item is valid
|
|
Om_num_ips--;
|
|
if(Om_num_ips <= 0){
|
|
Om_ip_selected = -1;
|
|
} else {
|
|
if(Om_ip_selected > 0){
|
|
Om_ip_selected--;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// return 10, if successflu
|
|
char Ip_str[IP_STRING_LEN+1];
|
|
int Ip_validated_already = 0;
|
|
int options_multi_verify_ip()
|
|
{
|
|
bool result;
|
|
|
|
if(!Ip_validated_already){
|
|
// see if its a valid ip address
|
|
result = psnet_is_valid_ip_string(Ip_str);
|
|
|
|
// if the result is a valid ip string, return immediately
|
|
if(result){
|
|
return 10;
|
|
}
|
|
|
|
// otherwise, change the popup text to indicate that it is invalid and wait for the user to click ok
|
|
popup_change_text(XSTR( "Ip string is invalid!", 386));
|
|
}
|
|
|
|
Ip_validated_already = 1;
|
|
|
|
// always wait for the user to hit the "cancel" button
|
|
return 0;
|
|
}
|
|
|
|
// attempt to add the currently entered ip address
|
|
void options_multi_protocol_add_current_ip()
|
|
{
|
|
// get the entered string
|
|
Om_ip_input.get_text(Ip_str);
|
|
|
|
// this popup wil do several things.
|
|
// 1.) It will display a popup so the user isn't left scratching his head
|
|
// 2.) If the address
|
|
Ip_validated_already = 0;
|
|
if(popup_till_condition(options_multi_verify_ip, XSTR( "Cancel", 387), XSTR( "Verifying ip address", 388)) == 10){
|
|
if(Om_num_ips < MAX_IP_ADDRS){
|
|
strcpy_s(Om_ip_addrs[Om_num_ips],Ip_str);
|
|
Om_ip_start = Om_num_ips;
|
|
Om_num_ips++;
|
|
|
|
// if this is the first item on the list, select it
|
|
if(Om_num_ips == 1){
|
|
Om_ip_selected = 0;
|
|
}
|
|
} else {
|
|
options_multi_add_notify(XSTR( "Max # of IP addresses reached!", 389));
|
|
}
|
|
}
|
|
}
|
|
|
|
// general options tab section -------------------------------------------
|
|
|
|
// load all the general tab controls
|
|
void options_multi_load_gen_controls()
|
|
{
|
|
int idx;
|
|
|
|
Assert(Om_window != NULL);
|
|
|
|
// instantiate all the buttons
|
|
for(idx=0; idx<OM_GEN_NUM_BUTTONS; idx++){
|
|
// create the object
|
|
Om_gen_buttons[gr_screen.res][idx].button.create(Om_window, "", Om_gen_buttons[gr_screen.res][idx].x, Om_gen_buttons[gr_screen.res][idx].y, 1, 1, 0, 1);
|
|
|
|
// set the sound to play when highlighted
|
|
Om_gen_buttons[gr_screen.res][idx].button.set_highlight_action(common_play_highlight_sound);
|
|
|
|
// set the ani for the button
|
|
Om_gen_buttons[gr_screen.res][idx].button.set_bmaps(Om_gen_buttons[gr_screen.res][idx].filename);
|
|
|
|
// set the hotspot
|
|
Om_gen_buttons[gr_screen.res][idx].button.link_hotspot(Om_gen_buttons[gr_screen.res][idx].hotspot);
|
|
}
|
|
|
|
// text
|
|
for(idx=0; idx<OM_GEN_NUM_TEXT; idx++){
|
|
Om_window->add_XSTR(&Om_gen_text[gr_screen.res][idx]);
|
|
}
|
|
|
|
// bogus control
|
|
Om_gen_bogus.base_create(Om_window, UI_KIND_ICON, 0, 0, 0, 0);
|
|
}
|
|
|
|
// disable/hide all the general tab controls
|
|
void options_multi_disable_gen_controls()
|
|
{
|
|
int idx;
|
|
|
|
// go through all the controls
|
|
for(idx=0;idx<OM_GEN_NUM_BUTTONS;idx++){
|
|
Om_gen_buttons[gr_screen.res][idx].button.hide();
|
|
Om_gen_buttons[gr_screen.res][idx].button.disable();
|
|
}
|
|
|
|
// bogus control
|
|
Om_gen_bogus.hide();
|
|
Om_gen_bogus.disable();
|
|
}
|
|
|
|
// enable/unhide all the general tab controls
|
|
void options_multi_enable_gen_controls()
|
|
{
|
|
int idx;
|
|
|
|
// go through all the controls
|
|
for(idx=0;idx<OM_GEN_NUM_BUTTONS;idx++){
|
|
Om_gen_buttons[gr_screen.res][idx].button.enable();
|
|
Om_gen_buttons[gr_screen.res][idx].button.unhide();
|
|
}
|
|
|
|
// bogus control
|
|
Om_gen_bogus.enable();
|
|
Om_gen_bogus.unhide();
|
|
}
|
|
|
|
// initialize the general tab vars
|
|
void options_multi_init_gen_vars()
|
|
{
|
|
// initialize the object update
|
|
Om_gen_obj_update = Player->m_local_options.obj_update_level;
|
|
|
|
// initialize the accept pix var
|
|
Om_gen_pix = (Player->m_local_options.flags & MLO_FLAG_ACCEPT_PIX);
|
|
|
|
// initialize the xfer_multidata var
|
|
Om_gen_xfer_multidata = (Player->m_local_options.flags & MLO_FLAG_XFER_MULTIDATA);
|
|
|
|
// initialize the flush cache var
|
|
Om_gen_flush_cache = (Player->m_local_options.flags & MLO_FLAG_FLUSH_CACHE);
|
|
}
|
|
|
|
// accept function for the general tab
|
|
void options_multi_gen_accept()
|
|
{
|
|
// apply the object update level
|
|
Player->m_local_options.obj_update_level = Om_gen_obj_update;
|
|
|
|
// apply the accept pix var
|
|
Player->m_local_options.flags &= ~(MLO_FLAG_ACCEPT_PIX);
|
|
if(Om_gen_pix){
|
|
Player->m_local_options.flags |= MLO_FLAG_ACCEPT_PIX;
|
|
}
|
|
|
|
// apply the xfer multidata var
|
|
Player->m_local_options.flags &= ~(MLO_FLAG_XFER_MULTIDATA);
|
|
if(Om_gen_xfer_multidata){
|
|
Player->m_local_options.flags |= MLO_FLAG_XFER_MULTIDATA;
|
|
}
|
|
options::OptionsManager::instance()->set_ingame_binary_option("Multi.TransferMissions", Om_gen_xfer_multidata);
|
|
|
|
// apply the flush cache var
|
|
Player->m_local_options.flags &= ~(MLO_FLAG_FLUSH_CACHE);
|
|
if(Om_gen_flush_cache){
|
|
Player->m_local_options.flags |= MLO_FLAG_FLUSH_CACHE;
|
|
}
|
|
options::OptionsManager::instance()->set_ingame_binary_option("Multi.FlushCache", Om_gen_flush_cache);
|
|
}
|
|
|
|
// do frame for the general tab
|
|
void options_multi_gen_do()
|
|
{
|
|
// check for button presses
|
|
options_multi_gen_check_buttons();
|
|
|
|
// draw the proper object update button
|
|
switch(Om_gen_obj_update){
|
|
case OBJ_UPDATE_LOW:
|
|
Om_gen_buttons[gr_screen.res][OM_GEN_OBJ_LOW].button.draw_forced(2);
|
|
break;
|
|
case OBJ_UPDATE_MEDIUM:
|
|
Om_gen_buttons[gr_screen.res][OM_GEN_OBJ_MED].button.draw_forced(2);
|
|
break;
|
|
case OBJ_UPDATE_HIGH:
|
|
Om_gen_buttons[gr_screen.res][OM_GEN_OBJ_HIGH].button.draw_forced(2);
|
|
break;
|
|
case OBJ_UPDATE_LAN:
|
|
Om_gen_buttons[gr_screen.res][OM_GEN_OBJ_LAN].button.draw_forced(2);
|
|
break;
|
|
default :
|
|
Int3();
|
|
}
|
|
|
|
// draw the proper pix button
|
|
if(Om_gen_pix){
|
|
Om_gen_buttons[gr_screen.res][OM_GEN_PIX_YES].button.draw_forced(2);
|
|
} else {
|
|
Om_gen_buttons[gr_screen.res][OM_GEN_PIX_NO].button.draw_forced(2);
|
|
}
|
|
|
|
// draw the proper xfer multidata button
|
|
if(Om_gen_xfer_multidata){
|
|
Om_gen_buttons[gr_screen.res][OM_GEN_XFER_MULTIDATA_YES].button.draw_forced(2);
|
|
} else {
|
|
Om_gen_buttons[gr_screen.res][OM_GEN_XFER_MULTIDATA_NO].button.draw_forced(2);
|
|
}
|
|
|
|
// draw the proper flush cache button
|
|
if(Om_gen_flush_cache){
|
|
Om_gen_buttons[gr_screen.res][OM_GEN_FLUSH_YES].button.draw_forced(2);
|
|
} else {
|
|
Om_gen_buttons[gr_screen.res][OM_GEN_FLUSH_NO].button.draw_forced(2);
|
|
}
|
|
}
|
|
|
|
// check for button presses
|
|
void options_multi_gen_check_buttons()
|
|
{
|
|
int idx;
|
|
|
|
// go through all the buttons
|
|
for(idx=0;idx<OM_GEN_NUM_BUTTONS;idx++){
|
|
if(Om_gen_buttons[gr_screen.res][idx].button.pressed()){
|
|
options_multi_gen_button_pressed(idx);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// a button was pressed
|
|
void options_multi_gen_button_pressed(int n)
|
|
{
|
|
switch(n){
|
|
// low object update level
|
|
case OM_GEN_OBJ_LOW:
|
|
if(Om_gen_obj_update != OBJ_UPDATE_LOW){
|
|
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
|
Om_gen_obj_update = OBJ_UPDATE_LOW;
|
|
} else {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
}
|
|
break;
|
|
|
|
// medium object update level
|
|
case OM_GEN_OBJ_MED:
|
|
if(Om_gen_obj_update != OBJ_UPDATE_MEDIUM){
|
|
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
|
Om_gen_obj_update = OBJ_UPDATE_MEDIUM;
|
|
} else {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
}
|
|
break;
|
|
|
|
// high object update level
|
|
case OM_GEN_OBJ_HIGH:
|
|
if(Om_gen_obj_update != OBJ_UPDATE_HIGH){
|
|
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
|
Om_gen_obj_update = OBJ_UPDATE_HIGH;
|
|
} else {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
}
|
|
break;
|
|
|
|
// lan object update level
|
|
case OM_GEN_OBJ_LAN:
|
|
if(Om_gen_obj_update != OBJ_UPDATE_LAN){
|
|
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
|
Om_gen_obj_update = OBJ_UPDATE_LAN;
|
|
} else {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
}
|
|
break;
|
|
|
|
// accept pix
|
|
case OM_GEN_PIX_YES:
|
|
if(!Om_gen_pix){
|
|
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
|
Om_gen_pix = true;
|
|
} else {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
}
|
|
break;
|
|
|
|
// don't accept pix
|
|
case OM_GEN_PIX_NO:
|
|
if(Om_gen_pix){
|
|
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
|
Om_gen_pix = false;
|
|
} else {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
}
|
|
break;
|
|
|
|
// put missions in the multidate directory
|
|
case OM_GEN_XFER_MULTIDATA_YES:
|
|
if(!Om_gen_xfer_multidata){
|
|
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
|
Om_gen_xfer_multidata = true;
|
|
} else {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
}
|
|
break;
|
|
|
|
// don't put missions in the multidata directory
|
|
case OM_GEN_XFER_MULTIDATA_NO:
|
|
if(Om_gen_xfer_multidata){
|
|
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
|
Om_gen_xfer_multidata = false;
|
|
} else {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
}
|
|
break;
|
|
|
|
// flush the cache before each mission
|
|
case OM_GEN_FLUSH_YES:
|
|
if(!Om_gen_flush_cache){
|
|
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
|
Om_gen_flush_cache = true;
|
|
} else {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
}
|
|
break;
|
|
|
|
// don't flush the cache before each mission
|
|
case OM_GEN_FLUSH_NO:
|
|
if(Om_gen_flush_cache){
|
|
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
|
Om_gen_flush_cache = false;
|
|
} else {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
// voice options tab section -------------------------------------------
|
|
|
|
// load all the voice tab controls
|
|
void options_multi_load_vox_controls()
|
|
{
|
|
int idx;
|
|
|
|
Assert(Om_window != NULL);
|
|
|
|
// instantiate all the buttons
|
|
for(idx=0; idx<OM_VOX_NUM_BUTTONS; idx++){
|
|
// create the object
|
|
Om_vox_buttons[gr_screen.res][idx].button.create(Om_window, "", Om_vox_buttons[gr_screen.res][idx].x, Om_vox_buttons[gr_screen.res][idx].y, 1, 1, 0, 1);
|
|
|
|
// set the sound to play when highlighted
|
|
Om_vox_buttons[gr_screen.res][idx].button.set_highlight_action(common_play_highlight_sound);
|
|
|
|
// set the ani for the button
|
|
Om_vox_buttons[gr_screen.res][idx].button.set_bmaps(Om_vox_buttons[gr_screen.res][idx].filename);
|
|
|
|
// set the hotspot
|
|
Om_vox_buttons[gr_screen.res][idx].button.link_hotspot(Om_vox_buttons[gr_screen.res][idx].hotspot);
|
|
}
|
|
|
|
// text
|
|
for(idx=0; idx<OM_VOX_NUM_TEXT; idx++){
|
|
Om_window->add_XSTR(&Om_vox_text[gr_screen.res][idx]);
|
|
}
|
|
|
|
// sliders
|
|
for ( idx = 0; idx < NUM_OM_VOX_SLIDERS; idx++ ) {
|
|
Om_vox_sliders[gr_screen.res][idx].slider.create(Om_window, Om_vox_sliders[gr_screen.res][idx].x, Om_vox_sliders[gr_screen.res][idx].y,
|
|
Om_vox_sliders[gr_screen.res][idx].dots, Om_vox_sliders[gr_screen.res][idx].filename,
|
|
Om_vox_sliders[gr_screen.res][idx].hotspot,
|
|
Om_vox_sliders[gr_screen.res][idx].left_filename, Om_vox_sliders[gr_screen.res][idx].left_mask, Om_vox_sliders[gr_screen.res][idx].left_x, Om_vox_sliders[gr_screen.res][idx].left_y,
|
|
Om_vox_sliders[gr_screen.res][idx].right_filename, Om_vox_sliders[gr_screen.res][idx].right_mask, Om_vox_sliders[gr_screen.res][idx].right_x, Om_vox_sliders[gr_screen.res][idx].right_y,
|
|
Om_vox_sliders[gr_screen.res][idx].dot_w);
|
|
}
|
|
|
|
// create the player list select button
|
|
Om_vox_plist_button.create(Om_window, "", Om_vox_plist_coords[gr_screen.res][0], Om_vox_plist_coords[gr_screen.res][1], Om_vox_plist_coords[gr_screen.res][2], Om_vox_plist_coords[gr_screen.res][3], 0, 1);
|
|
Om_vox_plist_button.hide();
|
|
|
|
// build a list of net players
|
|
Om_vox_num_players = 0;
|
|
for(idx=0;idx<MAX_PLAYERS;idx++){
|
|
Om_vox_players[idx] = NULL;
|
|
|
|
// if i'm not connected, do nothing
|
|
if((Net_player == NULL) || !(Net_player->flags & NETINFO_FLAG_CONNECTED)){
|
|
continue;
|
|
}
|
|
|
|
// add all players I know about
|
|
if(MULTI_CONNECTED(Net_players[idx]) && !MULTI_STANDALONE(Net_players[idx]) && (Net_player != &Net_players[idx])){
|
|
// set the netplayer pointer
|
|
Om_vox_players[Om_vox_num_players] = &Net_players[idx];
|
|
|
|
// set his mute flag
|
|
Om_vox_player_flags[Om_vox_num_players] = (Multi_voice_local_prefs & (1<<idx)) ? 1 : 0;
|
|
|
|
// increment the count
|
|
Om_vox_num_players++;
|
|
}
|
|
}
|
|
|
|
// bogus control
|
|
Om_vox_bogus.base_create(Om_window, UI_KIND_ICON, 0, 0, 0, 0);
|
|
}
|
|
|
|
// disable/hide all the voice tab controls
|
|
void options_multi_disable_vox_controls()
|
|
{
|
|
int idx;
|
|
|
|
// go through all the controls
|
|
for(idx=0; idx<OM_VOX_NUM_BUTTONS; idx++){
|
|
Om_vox_buttons[gr_screen.res][idx].button.hide();
|
|
Om_vox_buttons[gr_screen.res][idx].button.disable();
|
|
}
|
|
|
|
// hide the qos control
|
|
Om_vox_sliders[gr_screen.res][OM_VOX_QOS_SLIDER].slider.hide();
|
|
Om_vox_sliders[gr_screen.res][OM_VOX_QOS_SLIDER].slider.disable();
|
|
|
|
// unset the sound buffer size so we don't display any waveforms
|
|
Om_vox_voice_buffer_size = -1;
|
|
Om_vox_voice_comp_size = -1;
|
|
Om_vox_playback_handle = sound_handle::invalid();
|
|
Om_vox_test_status = OM_VOX_TEST_NONE;
|
|
|
|
// disable the player list select button
|
|
Om_vox_plist_button.disable();
|
|
|
|
// bogus controls
|
|
Om_vox_bogus.hide();
|
|
Om_vox_bogus.disable();
|
|
}
|
|
|
|
// enable/unhide all the voice tab controls
|
|
void options_multi_enable_vox_controls()
|
|
{
|
|
int idx;
|
|
|
|
// go through all the controls
|
|
for(idx=0; idx<OM_VOX_NUM_BUTTONS; idx++){
|
|
Om_vox_buttons[gr_screen.res][idx].button.enable();
|
|
Om_vox_buttons[gr_screen.res][idx].button.unhide();
|
|
}
|
|
|
|
// unhide the qos control
|
|
Om_vox_sliders[gr_screen.res][OM_VOX_QOS_SLIDER].slider.enable();
|
|
Om_vox_sliders[gr_screen.res][OM_VOX_QOS_SLIDER].slider.unhide();
|
|
|
|
// unset the sound buffer size so we don't display any waveforms
|
|
Om_vox_voice_buffer_size = -1;
|
|
Om_vox_voice_comp_size = -1;
|
|
Om_vox_playback_handle = sound_handle::invalid();
|
|
Om_vox_test_status = OM_VOX_TEST_NONE;
|
|
|
|
// select the first player on the list
|
|
Om_vox_player_select = Om_vox_players[0];
|
|
Om_vox_plist_start = 0;
|
|
|
|
// enable the player list select button
|
|
Om_vox_plist_button.enable();
|
|
|
|
// bogus controls
|
|
Om_vox_bogus.enable();
|
|
Om_vox_bogus.unhide();
|
|
}
|
|
|
|
// initialize the voice tab vars
|
|
void options_multi_init_vox_vars()
|
|
{
|
|
// intialize the accept voice var
|
|
if(Player->m_local_options.flags & MLO_FLAG_NO_VOICE){
|
|
Om_vox_accept_voice = 0;
|
|
} else {
|
|
Om_vox_accept_voice = 1;
|
|
}
|
|
}
|
|
|
|
// accept function for the voice tab
|
|
void options_multi_vox_accept()
|
|
{
|
|
int idx;
|
|
int voice_pref_flags;
|
|
|
|
// set the accept voice flag
|
|
Player->m_local_options.flags &= ~(MLO_FLAG_NO_VOICE);
|
|
if(!Om_vox_accept_voice){
|
|
Player->m_local_options.flags |= MLO_FLAG_NO_VOICE;
|
|
}
|
|
|
|
// build the voice preferences stuff
|
|
voice_pref_flags = 0xffffffff;
|
|
for(idx=0;idx<Om_vox_num_players;idx++){
|
|
// if this guy is muted
|
|
if(!Om_vox_player_flags[idx]){
|
|
voice_pref_flags &= ~(1 << NET_PLAYER_INDEX(Om_vox_players[idx]));
|
|
}
|
|
}
|
|
multi_voice_set_prefs(voice_pref_flags);
|
|
}
|
|
|
|
// do frame for the voice tab
|
|
void options_multi_vox_do()
|
|
{
|
|
int handle;
|
|
|
|
// check for button presses
|
|
options_multi_vox_check_buttons();
|
|
|
|
// draw the proper accept voice button
|
|
if(Om_vox_accept_voice){
|
|
Om_vox_buttons[gr_screen.res][OM_VOX_VOICE_YES].button.draw_forced(2);
|
|
} else {
|
|
Om_vox_buttons[gr_screen.res][OM_VOX_VOICE_NO].button.draw_forced(2);
|
|
}
|
|
|
|
// if the currently selected player is muted
|
|
if((Om_vox_player_select != NULL) && options_multi_vox_plist_get(Om_vox_player_select) > -1 && !Om_vox_player_flags[options_multi_vox_plist_get(Om_vox_player_select)]){
|
|
Om_vox_buttons[gr_screen.res][OM_VOX_VOICE_MUTE].button.draw_forced(2);
|
|
}
|
|
|
|
// process and display the player list
|
|
options_multi_vox_process_player_list();
|
|
|
|
// if we're currently doing a voice test recording, process some stuff
|
|
switch(Om_vox_test_status){
|
|
case OM_VOX_TEST_RECORDING:
|
|
multi_voice_test_process();
|
|
|
|
// force draw the mic test button
|
|
Om_vox_buttons[gr_screen.res][OM_VOX_VOICE_TEST].button.draw_forced(2);
|
|
|
|
// if we are no longer recording, switch to playback if possible
|
|
if(!multi_voice_test_recording()){
|
|
Om_vox_test_status = OM_VOX_TEST_PLAYBACK;
|
|
|
|
if(Om_vox_voice_comp_size != -1){
|
|
// stop any playing back sounds
|
|
rtvoice_stop_playback_all();
|
|
|
|
// attempt to get a playback handle
|
|
handle = multi_voice_test_get_playback_buffer();
|
|
if(handle != -1){
|
|
Om_vox_playback_handle = rtvoice_play(handle, Om_vox_comp_buffer, Om_vox_voice_comp_size);
|
|
|
|
// mark us as playing back
|
|
Om_vox_test_status = OM_VOX_TEST_PLAYBACK;
|
|
}
|
|
// on error, notify the user something is wrong
|
|
else {
|
|
options_multi_add_notify(XSTR( "Error trying to playback recorded voice! Check your hardware", 390));
|
|
|
|
// mark us as doing nothing
|
|
Om_vox_test_status = OM_VOX_TEST_NONE;
|
|
}
|
|
} else {
|
|
// mark us as doing nothing
|
|
Om_vox_test_status = OM_VOX_TEST_NONE;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case OM_VOX_TEST_PLAYBACK:
|
|
// if we were playing a sound back, but now the sound is done
|
|
if ((Om_vox_playback_handle.isValid()) && !ds_is_channel_playing(ds_get_channel(Om_vox_playback_handle))) {
|
|
// flush all playing sounds safely
|
|
rtvoice_stop_playback_all();
|
|
|
|
// null the sound handle
|
|
Om_vox_playback_handle = sound_handle::invalid();
|
|
|
|
// set this so we know not to display any more waveforms
|
|
Om_vox_voice_buffer_size = -1;
|
|
Om_vox_voice_comp_size = -1;
|
|
|
|
// free the status up
|
|
Om_vox_test_status = OM_VOX_TEST_NONE;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
// check for button presses
|
|
void options_multi_vox_check_buttons()
|
|
{
|
|
int idx;
|
|
|
|
// go through all the buttons
|
|
for(idx=0; idx<OM_VOX_NUM_BUTTONS; idx++){
|
|
if(Om_vox_buttons[gr_screen.res][idx].button.pressed()){
|
|
options_multi_vox_button_pressed(idx);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// a button was pressed
|
|
void options_multi_vox_button_pressed(int n)
|
|
{
|
|
switch(n){
|
|
// accept voice button
|
|
case OM_VOX_VOICE_YES:
|
|
if(!Om_vox_accept_voice){
|
|
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
|
Om_vox_accept_voice = 1;
|
|
} else {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
}
|
|
break;
|
|
|
|
// don't accept voice button
|
|
case OM_VOX_VOICE_NO:
|
|
if(Om_vox_accept_voice){
|
|
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
|
Om_vox_accept_voice = 0;
|
|
} else {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
}
|
|
break;
|
|
|
|
// mute/unmute button
|
|
case OM_VOX_VOICE_MUTE:
|
|
if(Om_vox_player_select != NULL){
|
|
int index = options_multi_vox_plist_get(Om_vox_player_select);
|
|
|
|
// there's already an assertion for this in options_multi_vox_plist_get, just ignore in release
|
|
if (index < 0){
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
break;
|
|
}
|
|
|
|
Om_vox_player_flags[index] = !Om_vox_player_flags[index];
|
|
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
|
} else {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
}
|
|
break;
|
|
|
|
// scroll the player list up
|
|
case OM_VOX_PLIST_UP:
|
|
options_multi_vox_plist_scroll_up();
|
|
break;
|
|
|
|
// scroll the player list down
|
|
case OM_VOX_PLIST_DOWN:
|
|
options_multi_vox_plist_scroll_down();
|
|
break;
|
|
|
|
// mic test button
|
|
case OM_VOX_VOICE_TEST:
|
|
// if in a multiplayer game, don't allow testing
|
|
if((Net_player != NULL) && (Net_player->flags & NETINFO_FLAG_CONNECTED)){
|
|
options_multi_add_notify(XSTR( "Cannot test mic while in a multiplayer game!", 391));
|
|
break;
|
|
}
|
|
|
|
// if this machine is not capable of playing
|
|
if(!Multi_voice_can_record){
|
|
options_multi_add_notify(XSTR( "DirectSoundCapture could not be initialized. To initialize DirectSoundCapture your sound card must be full duplex and your sound card drivers must support DirectSoundCapture", 392));
|
|
} else {
|
|
// if we're not already doing a record test
|
|
if(Om_vox_test_status == OM_VOX_TEST_NONE){
|
|
// set the quality of sound
|
|
rtvoice_set_qos(Om_vox_sliders[gr_screen.res][OM_VOX_QOS_SLIDER].slider.pos + 1);
|
|
|
|
// clear the comp buffer
|
|
memset(Om_vox_comp_buffer,128,OM_VOX_COMP_SIZE);
|
|
|
|
Om_vox_test_status = OM_VOX_TEST_RECORDING;
|
|
multi_voice_test_record_start();
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
// screen shader
|
|
extern shader Grey_shader;
|
|
|
|
// process and blit any voice waveform if necessary
|
|
void options_multi_vox_process_waveform()
|
|
{
|
|
int c_width = OM_VOX_WAVE_WIDTH;
|
|
int avg_len;
|
|
int buf_offset;
|
|
int idx,a_idx,running_avg;
|
|
|
|
// if we're not in recording or playback mode
|
|
if(Om_vox_test_status == OM_VOX_TEST_NONE){
|
|
return;
|
|
}
|
|
|
|
// grey the screen
|
|
gr_set_shader(&Grey_shader);
|
|
gr_shade(0,0,gr_screen.clip_width, gr_screen.clip_height, GR_RESIZE_NONE);
|
|
|
|
switch(Om_vox_test_status){
|
|
case OM_VOX_TEST_RECORDING:
|
|
// if we have no sound buffer size, do nothing
|
|
if(Om_vox_voice_buffer_size <= 0){
|
|
return;
|
|
}
|
|
|
|
// if we are not recording, do nothing
|
|
if(Om_vox_test_status != OM_VOX_TEST_RECORDING){
|
|
return;
|
|
}
|
|
|
|
// get the # of samples we'll average for one line
|
|
avg_len = Om_vox_voice_buffer_size / c_width;
|
|
|
|
// blit the waveform
|
|
gr_set_color_fast(&Color_green);
|
|
buf_offset = 0;
|
|
for(idx=0; idx < c_width; idx++){
|
|
// reset the running average
|
|
running_avg = 0;
|
|
for(a_idx = 0; a_idx < avg_len; a_idx++){
|
|
running_avg += (int)Om_vox_voice_buffer[buf_offset] - 128;
|
|
|
|
// increment the buffer offset
|
|
buf_offset++;
|
|
}
|
|
|
|
running_avg /= avg_len;
|
|
gr_line((gr_screen.max_w_unscaled - OM_VOX_WAVE_WIDTH)/2 + idx, OM_VOX_WAVE_Y, (gr_screen.max_w_unscaled - OM_VOX_WAVE_WIDTH)/2 + idx, OM_VOX_WAVE_Y + running_avg, GR_RESIZE_MENU);
|
|
}
|
|
|
|
// if this packet would have been dropped, notify the user
|
|
if(multi_voice_test_packet_tossed()){
|
|
gr_set_color_fast(&Color_bright);
|
|
gr_string(OM_VOX_DROP_ICON_X,OM_VOX_DROP_ICON_Y, XSTR( "Packet Overflow", 393), GR_RESIZE_MENU);
|
|
}
|
|
break;
|
|
|
|
case OM_VOX_TEST_PLAYBACK:
|
|
// get the offset into the playing direct sound buffer
|
|
buf_offset = ds_get_play_position(ds_get_channel(Om_vox_playback_handle));
|
|
|
|
// get the # of samples we'll average for one line
|
|
avg_len = (int)((float)OM_VOX_RECORD_INT * ((1024.0f * 11.0f) / 1000.0f)) / c_width;
|
|
|
|
// blit the waveform
|
|
gr_set_color_fast(&Color_red);
|
|
for(idx=0; idx < c_width; idx++){
|
|
// reset the running average
|
|
running_avg = 0;
|
|
for(a_idx = 0; a_idx < avg_len; a_idx++){
|
|
if(buf_offset < (OM_VOX_COMP_SIZE - 2)){
|
|
running_avg += (int)Om_vox_comp_buffer[buf_offset] - 128;
|
|
|
|
// increment the buffer offset
|
|
buf_offset++;
|
|
}
|
|
}
|
|
|
|
running_avg /= avg_len;
|
|
gr_line((gr_screen.max_w_unscaled - OM_VOX_WAVE_WIDTH)/2 + idx, OM_VOX_WAVE_Y, (gr_screen.max_w_unscaled - OM_VOX_WAVE_WIDTH)/2 + idx, OM_VOX_WAVE_Y + running_avg, GR_RESIZE_MENU);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
// process/display the player list
|
|
void options_multi_vox_process_player_list()
|
|
{
|
|
int idx;
|
|
int y_start,p_count;
|
|
int selected_index,click_y;
|
|
char str[CALLSIGN_LEN+2];
|
|
|
|
int line_height = gr_get_font_height() + 1;
|
|
|
|
// check for mouse clicks
|
|
if(Om_vox_plist_button.pressed()){
|
|
Om_vox_plist_button.get_mouse_pos(NULL,&click_y);
|
|
selected_index = (click_y / line_height) + Om_vox_plist_start;
|
|
|
|
// if he clicked on a valid player, select him
|
|
if(Om_vox_players[selected_index] != NULL){
|
|
Om_vox_player_select = Om_vox_players[selected_index];
|
|
|
|
nprintf(("Network","Selecting player %s\n",Om_vox_player_select->m_player->callsign));
|
|
}
|
|
}
|
|
|
|
// draw the list of players
|
|
p_count = 0;
|
|
y_start = Om_vox_plist_coords[gr_screen.res][1];
|
|
for(idx = Om_vox_plist_start; idx < Om_vox_num_players; idx++){
|
|
if(Om_vox_players[idx] != NULL){
|
|
// if he's the selected player, highlight him
|
|
if(Om_vox_players[idx] == Om_vox_player_select){
|
|
gr_set_color_fast(&Color_bright);
|
|
} else {
|
|
gr_set_color_fast(&Color_normal);
|
|
}
|
|
|
|
// force fit his callsign
|
|
strcpy_s(str,Om_vox_players[idx]->m_player->callsign);
|
|
font::force_fit_string(str, CALLSIGN_LEN+1, Om_vox_plist_coords[gr_screen.res][2]);
|
|
|
|
// blit the callsign
|
|
gr_string(Om_vox_plist_coords[gr_screen.res][0], y_start, str, GR_RESIZE_MENU);
|
|
|
|
// increment the y index
|
|
y_start += line_height;
|
|
|
|
// increment the player count
|
|
p_count++;
|
|
}
|
|
|
|
// if we've reached max display, break out
|
|
if(p_count >= Om_vox_plist_max_display[gr_screen.res]){
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// get the index into the player list of the passed netplayer
|
|
int options_multi_vox_plist_get(net_player *pl)
|
|
{
|
|
int idx;
|
|
|
|
for(idx=0;idx<Om_vox_num_players;idx++){
|
|
if(pl == Om_vox_players[idx]){
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Should never get a bad value here, but the places where this is called can now handle the negative return value, as it's not catastrophic.
|
|
// Still Assert to assist with bug tracking in debug.
|
|
Assertion(idx < Om_vox_num_players, "options_multi_vox_plist_get() could not find the correct net player. Please report to an SCP member!");
|
|
if (idx >= Om_vox_num_players)
|
|
return -1;
|
|
else
|
|
return idx;
|
|
}
|
|
|
|
// scroll the player list down
|
|
void options_multi_vox_plist_scroll_down()
|
|
{
|
|
if(Om_vox_num_players < Om_vox_plist_max_display[gr_screen.res]){
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
return;
|
|
}
|
|
|
|
if((Om_vox_num_players - Om_vox_plist_start) >= Om_vox_plist_max_display[gr_screen.res]){
|
|
Om_vox_plist_start++;
|
|
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
|
} else {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
}
|
|
}
|
|
|
|
// scroll the player list up
|
|
void options_multi_vox_plist_scroll_up()
|
|
{
|
|
if(Om_vox_plist_start > 0){
|
|
Om_vox_plist_start--;
|
|
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
|
} else {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
}
|
|
}
|
|
|
|
|
|
// extern functions -----------------------------------------------------
|
|
|
|
// called when the options screen is initialized, pass in the UI window
|
|
void options_multi_init(UI_WINDOW *options_window)
|
|
{
|
|
// assign the options window
|
|
Om_window = options_window;
|
|
|
|
// load the background bitmaps
|
|
options_multi_load_bmaps();
|
|
|
|
// load the controls for the protocol area
|
|
options_multi_load_protocol_controls();
|
|
|
|
// load the controls for the general tab
|
|
options_multi_load_gen_controls();
|
|
|
|
// load the controls for the voice tab
|
|
options_multi_load_vox_controls();
|
|
|
|
// disable all the protocol controls
|
|
options_multi_disable_protocol_controls();
|
|
|
|
// disable all the general tab controls
|
|
options_multi_disable_gen_controls();
|
|
|
|
// disable all the voice tab controls
|
|
options_multi_disable_vox_controls();
|
|
|
|
// intialize the protocol section vars
|
|
options_multi_init_protocol_vars();
|
|
|
|
// initialize the general tab vars
|
|
options_multi_init_gen_vars();
|
|
|
|
// initialize the voice tab vars
|
|
options_multi_init_vox_vars();
|
|
|
|
// intialize the multiplayer voice recording system
|
|
if( !((Net_player != NULL) && (Net_player->flags & NETINFO_FLAG_CONNECTED)) ){
|
|
multi_voice_init();
|
|
}
|
|
|
|
// set the default screen mode
|
|
Om_mode = OM_MODE_NONE;
|
|
}
|
|
|
|
// do frame for the multi options screen
|
|
void options_multi_do(int key)
|
|
{
|
|
// do frame for the protocol section
|
|
options_multi_protocol_do(key);
|
|
|
|
// process and blit any notification messages
|
|
options_multi_notify_process();
|
|
|
|
// process the proper tab control
|
|
switch(Om_mode){
|
|
case OM_MODE_GENERAL:
|
|
options_multi_gen_do();
|
|
break;
|
|
case OM_MODE_VOX:
|
|
options_multi_vox_do();
|
|
break;
|
|
default :
|
|
Int3();
|
|
}
|
|
}
|
|
|
|
// called when the entire options screen is closed
|
|
void options_multi_close()
|
|
{
|
|
// null out the window handle
|
|
Om_window = NULL;
|
|
|
|
// unload all background bitmaps
|
|
options_multi_unload_bmaps();
|
|
|
|
// stop any playing voice
|
|
rtvoice_stop_playback_all();
|
|
|
|
// unset the screen mode
|
|
Om_mode = OM_MODE_NONE;
|
|
}
|
|
|
|
/**
|
|
* Checks if the multiplayer config screen is in a legal state to exit
|
|
**/
|
|
bool options_multi_ok_to_accept()
|
|
{
|
|
// if PXO is turned on, do we have a username and password?
|
|
if (Multi_options_g.pxo) {
|
|
if (strlen(Multi_tracker_login) == 0) {
|
|
return false;
|
|
}
|
|
else if (strlen(Multi_tracker_passwd) == 0) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Called if the accept button on the main options screen was hit.
|
|
* Also allows saving PXO credentials as "".
|
|
**/
|
|
void options_multi_accept()
|
|
{
|
|
// is it legal to leave this screen?
|
|
// The following check has been commented out for the following reasons:
|
|
// 1) Retail never had such a check,
|
|
// 2) when starting PXO in multiplayer, the PXO lobby screen
|
|
// displays a warning if the login values are actually valid or not,
|
|
// 3) and not having this function be a bool allows for
|
|
// much more streamlined option managment, especially with in-game options.
|
|
// --wookieejedi and confirmed with taylor
|
|
//if (!options_multi_ok_to_accept()) {
|
|
//return false;
|
|
//}
|
|
|
|
// accept function for the protocol section
|
|
options_multi_protocol_accept();
|
|
|
|
// accept function for the general tab
|
|
options_multi_gen_accept();
|
|
|
|
// accept function for the voice tab
|
|
options_multi_vox_accept();
|
|
|
|
// if Net_player is not null, copy these new settings to him
|
|
if(Net_player != NULL){
|
|
multi_options_local_load(&Net_player->p_info.options, NULL);
|
|
}
|
|
multi_options_local_load(&Player->m_local_options, NULL);
|
|
|
|
// if we're connected to a game server, update our options on the server now
|
|
if((Net_player != NULL) && !(Net_player->flags & NETINFO_FLAG_AM_MASTER) && MULTI_CONNECTED(Net_players[MY_NET_PLAYER_NUM]) ){
|
|
multi_options_update_local();
|
|
}
|
|
|
|
// recall that in-game option values get persisted/saved to file within options_accept() in optionsmenu.cpp
|
|
}
|
|
|
|
// called when the multiplayer tab is hit - initializes/switches all necessary data.
|
|
// NOTE : this is different from the initialization function, which is called only when the options menu is started
|
|
void options_multi_select()
|
|
{
|
|
// set the windows mask bitmap
|
|
Assert(Om_mask_0 >= 0);
|
|
Om_window->set_mask_bmap(Om_mask_0, Om_background_0_mask_fname[gr_screen.res]);
|
|
|
|
// set the default screen mode
|
|
Om_mode = OM_MODE_GENERAL;
|
|
|
|
// clear any notification messages
|
|
Om_notify_stamp = UI_TIMESTAMP::invalid();
|
|
|
|
// enable all the protocol controls
|
|
options_multi_enable_protocol_controls();
|
|
|
|
// enable the general tab controls
|
|
options_multi_enable_gen_controls();
|
|
}
|
|
|
|
// return the bitmap handle of the current background bitmap, or -1 if the multiplayer tab is not active
|
|
int options_multi_background_bitmap()
|
|
{
|
|
// return the background bitmap mode based upon the current mode
|
|
switch(Om_mode){
|
|
case OM_MODE_GENERAL:
|
|
return Om_background_0;
|
|
|
|
case OM_MODE_VOX:
|
|
return Om_background_1;
|
|
}
|
|
|
|
// unknown mode of some kind
|
|
return -1;
|
|
}
|
|
|
|
// called when the multiplayer tab has been switched from
|
|
void options_multi_unselect()
|
|
{
|
|
// unset the mode
|
|
Om_mode = OM_MODE_NONE;
|
|
|
|
// disable all the protocol controls
|
|
options_multi_disable_protocol_controls();
|
|
|
|
// disable all the general tab controls
|
|
options_multi_disable_gen_controls();
|
|
|
|
// disable all the vox tab controls
|
|
options_multi_disable_vox_controls();
|
|
|
|
// stop any test voice recording
|
|
multi_voice_test_record_stop();
|
|
}
|
|
|
|
// set voice sound buffer for display
|
|
void options_multi_set_voice_data(unsigned char *sound_buf, int buf_size, double /*gain*/)
|
|
{
|
|
if ( (sound_buf == NULL) || (buf_size <= 0) ) {
|
|
return;
|
|
}
|
|
|
|
// copy the buffer to the vox tab data
|
|
Om_vox_voice_buffer_size = MIN(buf_size, OM_VOX_BUF_SIZE);
|
|
memcpy(Om_vox_voice_buffer, sound_buf, Om_vox_voice_buffer_size);
|
|
|
|
// copy and uncompress the compressed buffer
|
|
if(Om_vox_voice_comp_size == -1){
|
|
Om_vox_voice_comp_size = 0;
|
|
}
|
|
|
|
if ( (Om_vox_voice_comp_size + buf_size) < OM_VOX_COMP_SIZE ) {
|
|
memcpy(Om_vox_comp_buffer + Om_vox_voice_comp_size, sound_buf, buf_size);
|
|
Om_vox_voice_comp_size += buf_size;
|
|
}
|
|
}
|
|
|
|
// return whether we want to eat a tabbed keypress
|
|
int options_multi_eat_tab()
|
|
{
|
|
// do we want to eat the tab key or not
|
|
if(Om_tracker_passwd.has_focus() || Om_tracker_login.has_focus() || Om_tracker_squad_name.has_focus()){
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|