Make menus for hosting a netgame stack, make quitting work with newmenu_do2 and simpler

This commit is contained in:
kreatordxx 2010-04-04 09:41:53 +00:00
parent 76b0fb35ef
commit 90e3796f97
11 changed files with 348 additions and 256 deletions

View file

@ -1,12 +1,16 @@
D1X-Rebirth Changelog
20100404
--------
arch/include/event.h, arch/sdl/event.c, main/automap.c, main/game.c, main/gamecntl.c, main/gameseq.c, main/inferno.c, main/inferno.h, main/menu.c, main/multi.c, main/net_ipx.c, main/net_udp.c, main/newdemo.c, main/state.c, misc/error.c: Get rid of a heap of uses of Function_mode, quit properly (freeing all windows and asking for confirmation for game) when clicking close box
arch/include/window.h, arch/sdl/window.c, main/inferno.c, main/menu.c, main/mission.c, main/net_ipx.c, main/net_ipx.h, main/net_udp.c, main/net_udp.h, main/newmenu.c: Make menus for hosting a netgame stack, make quitting work with newmenu_do2 and simpler
20100403
--------
arch/sdl/mouse.c, main/game.c, main/net_ipx.c, main/net_ipx.h, main/newmenu.c, main/newmenu.h, main/state.c: Make newmenu_do3 and newmenu_dotiny return as soon as the newmenu is created, which will allow the main menu (and others) to persist
main/menu.c: Make main menu persist to streamline redrawing (later)
main/kconfig.c, main/menu.h, main/net_ipx.c, main/net_udp.c, main/newmenu.c, main/scores.c: Remove calls to nm_draw_background1 to show newmenus stacked
main/menu.c, main/newmenu.c, main/scores.c: Move copyright drawing to main menu's event handler for tidiness
arch/include/event.h, arch/sdl/event.c, main/automap.c, main/game.c, main/gamecntl.c, main/gameseq.c, main/inferno.c, main/inferno.h, main/menu.c, main/multi.c, main/net_ipx.c, main/net_udp.c, main/newdemo.c, main/state.c, misc/error.c: Get rid of a heap of uses of Function_mode, quit properly (freeing all windows and asking for confirmation for game) when clicking close box
20100402
--------

View file

@ -22,6 +22,7 @@ extern int window_exists(window *wind);
extern window *window_get_front(void);
extern window *window_get_first(void);
extern window *window_get_next(window *wind);
extern window *window_get_prev(window *wind);
extern void window_select(window *wind);
extern void window_set_visible(window *wind, int visible);
extern int window_is_visible(window *wind);

View file

@ -138,6 +138,11 @@ window *window_get_next(window *wind)
return wind->next;
}
window *window_get_prev(window *wind)
{
return wind->prev;
}
// Make wind the front window
void window_select(window *wind)
{

View file

@ -447,7 +447,7 @@ void quit_request()
{
window *wind;
while ((wind = window_get_front()))
for (wind = window_get_front(); wind != NULL; wind = window_get_prev(wind))
{
if (wind == Game_wind)
{

View file

@ -573,7 +573,7 @@ int do_option ( int select)
return 0;
case MENU_NEW_PLAYER:
RegisterPlayer(); //1 == allow escape out of menu
RegisterPlayer();
break;
#ifndef RELEASE
@ -598,7 +598,7 @@ int do_option ( int select)
#ifdef USE_UDP
case MENU_START_UDP_NETGAME:
multi_protocol = MULTI_PROTO_UDP;
select_mission(1, TXT_MULTI_MISSION, net_udp_start_game);
select_mission(1, TXT_MULTI_MISSION, net_udp_setup_game);
break;
case MENU_JOIN_MANUAL_UDP_NETGAME:
multi_protocol = MULTI_PROTO_UDP;
@ -613,7 +613,7 @@ int do_option ( int select)
case MENU_START_IPX_NETGAME:
multi_protocol = MULTI_PROTO_IPX;
ipxdrv_set(NETPROTO_IPX);
select_mission(1, TXT_MULTI_MISSION, net_ipx_start_game);
select_mission(1, TXT_MULTI_MISSION, net_ipx_setup_game);
break;
case MENU_JOIN_IPX_NETGAME:
multi_protocol = MULTI_PROTO_IPX;
@ -623,7 +623,7 @@ int do_option ( int select)
case MENU_START_KALI_NETGAME:
multi_protocol = MULTI_PROTO_IPX;
ipxdrv_set(NETPROTO_KALINIX);
select_mission(1, TXT_MULTI_MISSION, net_ipx_start_game);
select_mission(1, TXT_MULTI_MISSION, net_ipx_setup_game);
break;
case MENU_JOIN_KALI_NETGAME:
multi_protocol = MULTI_PROTO_IPX;
@ -909,8 +909,12 @@ int options_menuset(newmenu *menu, d_event *event, void *userdata)
break;
case EVENT_WINDOW_CLOSE:
{
newmenu_item *items = newmenu_get_items(menu);
d_free(items);
write_player_file();
break;
}
default:
break;
@ -1016,7 +1020,7 @@ void change_res()
init_cockpit();
game_init_render_buffers(SM_W(screen_mode), SM_H(screen_mode), VR_NONE);
window_close(window_get_front()); // close options dialog - it will be messy with a different resolution
//do_options_menu(); // reopen it. D'OH: Can't yet, not until we have a main event loop for it
do_options_menu(); // reopen it
}
int input_menuset(newmenu *menu, d_event *event, void *userdata)
@ -1286,13 +1290,44 @@ void do_misc_menu()
}
#if defined(USE_UDP) || defined(USE_IPX)
static int multi_player_menu_handler(newmenu *menu, d_event *event, int *menu_choice)
{
newmenu_item *items = newmenu_get_items(menu);
switch (event->type)
{
case EVENT_NEWMENU_SELECTED:
// stay in multiplayer menu, even after having played a game
return do_option(menu_choice[newmenu_get_citem(menu)]);
case EVENT_WINDOW_CLOSE:
d_free(menu_choice);
d_free(items);
break;
default:
break;
}
return 0;
}
void do_multi_player_menu()
{
int menu_choice[12];
newmenu_item m[12];
int choice = 0, num_options = 0;
int *menu_choice;
newmenu_item *m;
int num_options = 0;
num_options = 0;
MALLOC(menu_choice, int, 12);
if (!menu_choice)
return;
MALLOC(m, newmenu_item, 12);
if (!m)
{
d_free(menu_choice);
return;
}
#ifdef USE_UDP
m[num_options].type=NM_TYPE_TEXT; m[num_options].text="UDP:"; num_options++;
@ -1315,18 +1350,17 @@ void do_multi_player_menu()
#endif
#endif
choice = newmenu_do1( NULL, TXT_MULTIPLAYER, num_options, m, NULL, NULL, choice );
// FIXME: Stay in multiplayer menu for convenience. Must make newmenu_do's fall back to main loop first,
// due to LeaveEvents longjmp hack
if ( choice > -1 )
do_option(menu_choice[choice]);
newmenu_do3( NULL, TXT_MULTIPLAYER, num_options, m, (int (*)(newmenu *, d_event *, void *))multi_player_menu_handler, menu_choice, 0, NULL, -1, -1 );
}
#endif
void do_options_menu()
{
newmenu_item m[11];
newmenu_item *m;
MALLOC(m, newmenu_item, 11);
if (!m)
return;
m[ 0].type = NM_TYPE_MENU; m[ 0].text="Sound effects & music...";
m[ 1].type = NM_TYPE_TEXT; m[ 1].text="";
@ -1351,5 +1385,7 @@ void do_options_menu()
m[ 9].type = NM_TYPE_MENU; m[ 9].text="Secondary autoselect ordering...";
m[10].type = NM_TYPE_MENU; m[10].text="Misc Options...";
newmenu_do1( NULL, TXT_OPTIONS, sizeof(m)/sizeof(*m), m, options_menuset, NULL, 0 );
// Fall back to main event loop
// Allows clean closing and re-opening when resolution changes
newmenu_do3( NULL, TXT_OPTIONS, sizeof(m)/sizeof(*m), m, options_menuset, NULL, 0, NULL, -1, -1 );
}

View file

@ -649,7 +649,7 @@ int mission_menu_handler(listbox *lb, d_event *event, mission_menu *mm)
if (!load_mission(mm->mission_list + citem))
{
nm_messagebox( NULL, 1, TXT_OK, TXT_MISSION_ERROR);
return 0; // stay in listbox so user can select another one
return 1; // stay in listbox so user can select another one
}
}
return !(*mm->when_selected)();

View file

@ -2328,10 +2328,18 @@ int net_ipx_start_poll( newmenu *menu, d_event *event, void *userdata )
return 0;
}
static int opt_cinvul, opt_team_anarchy, opt_coop, opt_show_on_map, opt_closed, opt_refuse, opt_maxnet;
static int opt_cinvul, opt_show_on_map;
static int opt_show_on_map, opt_difficulty, opt_socket;
int net_ipx_game_param_handler( newmenu *menu, d_event *event, void *userdata )
typedef struct param_opt
{
int name, level, mode, moreopts;
int closed, refuse, maxnet, coop, team_anarchy;
} param_opt;
int net_ipx_start_game(void);
int net_ipx_game_param_handler( newmenu *menu, d_event *event, param_opt *opt )
{
newmenu_item *menus = newmenu_get_items(menu);
int citem = newmenu_get_citem(menu);
@ -2340,25 +2348,25 @@ int net_ipx_game_param_handler( newmenu *menu, d_event *event, void *userdata )
switch (event->type)
{
case EVENT_NEWMENU_CHANGED:
if (citem == opt_team_anarchy)
if (citem == opt->team_anarchy)
{
menus[opt_closed].value = 1;
menus[opt_closed-1].value = 0;
menus[opt_closed+1].value = 0;
menus[opt->closed].value = 1;
menus[opt->closed-1].value = 0;
menus[opt->closed+1].value = 0;
}
if (menus[opt_coop].value)
if (menus[opt->coop].value)
{
oldmaxnet=1;
if (menus[opt_maxnet].value>2)
if (menus[opt->maxnet].value>2)
{
menus[opt_maxnet].value=2;
menus[opt->maxnet].value=2;
}
if (menus[opt_maxnet].max_value>2)
if (menus[opt->maxnet].max_value>2)
{
menus[opt_maxnet].max_value=2;
menus[opt->maxnet].max_value=2;
}
if (!(Netgame.game_flags & NETGAME_FLAG_SHOW_MAP))
@ -2369,37 +2377,122 @@ int net_ipx_game_param_handler( newmenu *menu, d_event *event, void *userdata )
if (oldmaxnet)
{
oldmaxnet=0;
menus[opt_maxnet].value=6;
menus[opt_maxnet].max_value=6;
menus[opt->maxnet].value=6;
menus[opt->maxnet].max_value=6;
}
}
if (citem == opt_maxnet)
sprintf( menus[opt_maxnet].text, "Maximum players: %d", menus[opt_maxnet].value+2 );
if (citem == opt->level)
{
char *slevel = menus[opt->level].text;
Netgame.levelnum = atoi(slevel);
if (!strnicmp(slevel, "s", 1))
Netgame.levelnum = -atoi(slevel+1);
else
Netgame.levelnum = atoi(slevel);
if ((Netgame.levelnum < Last_secret_level) || (Netgame.levelnum > Last_level) || (Netgame.levelnum == 0))
{
nm_messagebox(TXT_ERROR, 1, TXT_OK, TXT_LEVEL_OUT_RANGE );
sprintf(slevel, "1");
return 0;
}
}
if (citem == opt->refuse)
Netgame.RefusePlayers=menus[opt->refuse].value;
if (citem == opt->maxnet)
{
sprintf( menus[opt->maxnet].text, "Maximum players: %d", menus[opt->maxnet].value+2 );
MaxNumNetPlayers = menus[opt->maxnet].value+2;
Netgame.max_numplayers=MaxNumNetPlayers;
}
if ((citem >= opt->mode) && (citem <= opt->mode + 3))
{
if ( menus[opt->mode].value )
Netgame.gamemode = NETGAME_ANARCHY;
else if (menus[opt->mode+1].value) {
Netgame.gamemode = NETGAME_TEAM_ANARCHY;
}
// else if (ANARCHY_ONLY_MISSION) {
// nm_messagebox(NULL, 1, TXT_OK, TXT_ANARCHY_ONLY_MISSION);
// menus[opt->mode+2].value = 0;
// menus[opt->mode+3].value = 0;
// menus[opt->mode].value = 1;
// goto menu;
// }
else if ( menus[opt->mode+2].value )
Netgame.gamemode = NETGAME_ROBOT_ANARCHY;
else if ( menus[opt->mode+3].value )
Netgame.gamemode = NETGAME_COOPERATIVE;
else Int3(); // Invalid mode -- see Rob
}
if (citem == opt->closed)
{
if (menus[opt->closed].value)
Netgame.game_flags |= NETGAME_FLAG_CLOSED;
else
Netgame.game_flags &= ~NETGAME_FLAG_CLOSED;
}
break;
case EVENT_NEWMENU_SELECTED:
if (citem==opt->moreopts)
{
if ( menus[opt->mode+3].value )
Game_mode=GM_MULTI_COOP;
net_ipx_more_game_options();
Game_mode=0;
return 1;
}
{
int j;
for (j = 0; j < num_active_ipx_games; j++)
if (!stricmp(Active_ipx_games[j].game_name, Netgame.game_name))
{
nm_messagebox(TXT_ERROR, 1, TXT_OK, TXT_DUPLICATE_NAME);
return 1;
}
}
return !net_ipx_start_game();
default:
break;
}
return 0;
}
int net_ipx_get_game_params()
int net_ipx_setup_game()
{
int i;
int opt, opt_name, opt_level, opt_mode,opt_moreopts;
int optnum;
param_opt opt;
newmenu_item m[20];
char slevel[5];
char level_text[32];
char srmaxnet[50];
net_ipx_init();
change_playernum_to(0);
for (i=0;i<MAX_PLAYERS;i++)
if (i!=Player_num)
Players[i].callsign[0]=0;
Netgame.RefusePlayers=0;
MaxNumNetPlayers = MAX_NUM_NET_PLAYERS;
Netgame.RefusePlayers=0;
sprintf( Netgame.game_name, "%s%s", Players[Player_num].callsign, TXT_S_GAME );
Netgame.difficulty=PlayerCfg.DefaultDifficulty;
Netgame.max_numplayers=MaxNumNetPlayers;
@ -2409,13 +2502,13 @@ int net_ipx_get_game_params()
strcpy(Netgame.mission_name, Current_mission_filename);
strcpy(Netgame.mission_title, Current_mission_longname);
sprintf( slevel, "1" );
sprintf( slevel, "1" ); Netgame.levelnum = 1;
opt = 0;
m[opt].type = NM_TYPE_TEXT; m[opt].text = TXT_DESCRIPTION; opt++;
optnum = 0;
m[optnum].type = NM_TYPE_TEXT; m[optnum].text = TXT_DESCRIPTION; optnum++;
opt_name = opt;
m[opt].type = NM_TYPE_INPUT; m[opt].text = Netgame.game_name; m[opt].text_len = NETGAME_NAME_LEN; opt++;
opt.name = optnum;
m[optnum].type = NM_TYPE_INPUT; m[optnum].text = Netgame.game_name; m[optnum].text_len = NETGAME_NAME_LEN; optnum++;
sprintf(level_text, "%s (1-%d)", TXT_LEVEL_, Last_level);
if (Last_secret_level < -1)
@ -2425,100 +2518,39 @@ int net_ipx_get_game_params()
Assert(strlen(level_text) < 32);
m[opt].type = NM_TYPE_TEXT; m[opt].text = level_text; opt++;
m[optnum].type = NM_TYPE_TEXT; m[optnum].text = level_text; optnum++;
opt_level = opt;
m[opt].type = NM_TYPE_INPUT; m[opt].text = slevel; m[opt].text_len=4; opt++;
m[opt].type = NM_TYPE_TEXT; m[opt].text = TXT_OPTIONS; opt++;
opt.level = optnum;
m[optnum].type = NM_TYPE_INPUT; m[optnum].text = slevel; m[optnum].text_len=4; optnum++;
m[optnum].type = NM_TYPE_TEXT; m[optnum].text = TXT_OPTIONS; optnum++;
opt_mode = opt;
m[opt].type = NM_TYPE_RADIO; m[opt].text = TXT_ANARCHY; m[opt].value=(Netgame.gamemode == NETGAME_ANARCHY); m[opt].group=0; opt++;
m[opt].type = NM_TYPE_RADIO; m[opt].text = TXT_TEAM_ANARCHY; m[opt].value=(Netgame.gamemode == NETGAME_TEAM_ANARCHY); m[opt].group=0; opt_team_anarchy=opt; opt++;
m[opt].type = NM_TYPE_RADIO; m[opt].text = TXT_ANARCHY_W_ROBOTS; m[opt].value=(Netgame.gamemode == NETGAME_ROBOT_ANARCHY); m[opt].group=0; opt++;
m[opt].type = NM_TYPE_RADIO; m[opt].text = TXT_COOPERATIVE; m[opt].value=(Netgame.gamemode == NETGAME_COOPERATIVE); m[opt].group=0; opt_coop=opt; opt++;
opt.mode = optnum;
m[optnum].type = NM_TYPE_RADIO; m[optnum].text = TXT_ANARCHY; m[optnum].value=(Netgame.gamemode == NETGAME_ANARCHY); m[optnum].group=0; optnum++;
m[optnum].type = NM_TYPE_RADIO; m[optnum].text = TXT_TEAM_ANARCHY; m[optnum].value=(Netgame.gamemode == NETGAME_TEAM_ANARCHY); m[optnum].group=0; opt.team_anarchy=optnum; optnum++;
m[optnum].type = NM_TYPE_RADIO; m[optnum].text = TXT_ANARCHY_W_ROBOTS; m[optnum].value=(Netgame.gamemode == NETGAME_ROBOT_ANARCHY); m[optnum].group=0; optnum++;
m[optnum].type = NM_TYPE_RADIO; m[optnum].text = TXT_COOPERATIVE; m[optnum].value=(Netgame.gamemode == NETGAME_COOPERATIVE); m[optnum].group=0; opt.coop=optnum; optnum++;
m[opt].type = NM_TYPE_TEXT; m[opt].text = ""; opt++;
m[optnum].type = NM_TYPE_TEXT; m[optnum].text = ""; optnum++;
m[opt].type = NM_TYPE_RADIO; m[opt].text = "Open game"; m[opt].group=1; m[opt].value=(!Netgame.RefusePlayers && !Netgame.game_flags & NETGAME_FLAG_CLOSED); opt++;
opt_closed = opt;
m[opt].type = NM_TYPE_RADIO; m[opt].text = TXT_CLOSED_GAME; m[opt].group=1; m[opt].value=Netgame.game_flags & NETGAME_FLAG_CLOSED; opt++;
opt_refuse = opt;
m[opt].type = NM_TYPE_RADIO; m[opt].text = "Restricted Game "; m[opt].group=1; m[opt].value=Netgame.RefusePlayers; opt++;
m[optnum].type = NM_TYPE_RADIO; m[optnum].text = "Open game"; m[optnum].group=1; m[optnum].value=(!Netgame.RefusePlayers && !Netgame.game_flags & NETGAME_FLAG_CLOSED); optnum++;
opt.closed = optnum;
m[optnum].type = NM_TYPE_RADIO; m[optnum].text = TXT_CLOSED_GAME; m[optnum].group=1; m[optnum].value=Netgame.game_flags & NETGAME_FLAG_CLOSED; optnum++;
opt.refuse = optnum;
m[optnum].type = NM_TYPE_RADIO; m[optnum].text = "Restricted Game "; m[optnum].group=1; m[optnum].value=Netgame.RefusePlayers; optnum++;
opt_maxnet = opt;
opt.maxnet = optnum;
sprintf( srmaxnet, "Maximum players: %d", MaxNumNetPlayers);
m[opt].type = NM_TYPE_SLIDER; m[opt].value=Netgame.max_numplayers-2; m[opt].text= srmaxnet; m[opt].min_value=0;
m[opt].max_value=MaxNumNetPlayers-2; opt++;
m[optnum].type = NM_TYPE_SLIDER; m[optnum].value=Netgame.max_numplayers-2; m[optnum].text= srmaxnet; m[optnum].min_value=0;
m[optnum].max_value=MaxNumNetPlayers-2; optnum++;
opt_moreopts=opt;
m[opt].type = NM_TYPE_MENU; m[opt].text = "Advanced options"; opt++;
opt.moreopts=optnum;
m[optnum].type = NM_TYPE_MENU; m[optnum].text = "Advanced options"; optnum++;
Assert(opt <= 20);
Assert(optnum <= 20);
menu:
i = newmenu_do1( NULL, NULL, opt, m, net_ipx_game_param_handler, NULL, 1 );
i = newmenu_do1( NULL, NULL, optnum, m, (int (*)( newmenu *, d_event *, void * ))net_ipx_game_param_handler, &opt, 1 );
if (i==opt_moreopts)
{
if ( m[opt_mode+3].value )
Game_mode=GM_MULTI_COOP;
net_ipx_more_game_options();
Game_mode=0;
goto menu;
}
Netgame.RefusePlayers=m[opt_refuse].value;
if ( i > -1 ) {
int j;
MaxNumNetPlayers = m[opt_maxnet].value+2;
Netgame.max_numplayers=MaxNumNetPlayers;
for (j = 0; j < num_active_ipx_games; j++)
if (!stricmp(Active_ipx_games[j].game_name, Netgame.game_name))
{
nm_messagebox(TXT_ERROR, 1, TXT_OK, TXT_DUPLICATE_NAME);
goto menu;
}
Netgame.levelnum = atoi(slevel);
if (!strnicmp(slevel, "s", 1))
Netgame.levelnum = -atoi(slevel+1);
else
Netgame.levelnum = atoi(slevel);
if ((Netgame.levelnum < Last_secret_level) || (Netgame.levelnum > Last_level) || (Netgame.levelnum == 0))
{
nm_messagebox(TXT_ERROR, 1, TXT_OK, TXT_LEVEL_OUT_RANGE );
sprintf(slevel, "1");
goto menu;
}
if ( m[opt_mode].value )
Netgame.gamemode = NETGAME_ANARCHY;
else if (m[opt_mode+1].value) {
Netgame.gamemode = NETGAME_TEAM_ANARCHY;
}
// else if (ANARCHY_ONLY_MISSION) {
// nm_messagebox(NULL, 1, TXT_OK, TXT_ANARCHY_ONLY_MISSION);
// m[opt_mode+2].value = 0;
// m[opt_mode+3].value = 0;
// m[opt_mode].value = 1;
// goto menu;
// }
else if ( m[opt_mode+2].value )
Netgame.gamemode = NETGAME_ROBOT_ANARCHY;
else if ( m[opt_mode+3].value )
Netgame.gamemode = NETGAME_COOPERATIVE;
else Int3(); // Invalid mode -- see Rob
if (m[opt_closed].value)
Netgame.game_flags |= NETGAME_FLAG_CLOSED;
else
Netgame.game_flags &= ~NETGAME_FLAG_CLOSED;
}
return i;
return i >= 0;
}
void
@ -2962,8 +2994,6 @@ abort:
int net_ipx_start_game(void)
{
int i;
Assert( sizeof(IPX_frame_info) < MAX_DATA_SIZE );
if ( !IPX_active )
@ -2972,19 +3002,12 @@ int net_ipx_start_game(void)
return 0;
}
net_ipx_init();
change_playernum_to(0);
if (net_ipx_find_game())
{
nm_messagebox(NULL, 1, TXT_OK, TXT_NET_FULL);
return 0;
}
i = net_ipx_get_game_params();
if (i<0) return 0;
if (IPX_Socket) {
ipxdrv_change_default_socket( IPX_DEFAULT_SOCKET + IPX_Socket );
}
@ -3002,11 +3025,14 @@ int net_ipx_start_game(void)
if(net_ipx_select_players())
{
StartNewLevel(Netgame.levelnum);
}
}
else
{
Game_mode = GM_GAME_OVER;
return 0; // see if we want to tweak the game we setup
}
return 1; // FIXME: keep mission listbox for convenience. Need to keep main menu first
return 1; // don't keep params menu or mission listbox (may want to join a game next time)
}
void restart_net_searching(newmenu_item * m)
@ -3453,9 +3479,6 @@ void net_ipx_join_game()
N_players = 0;
// FIXME: Keep browsing window to go back to
//setjmp(LeaveGame);
Network_send_objects = 0;
Network_rejoined=0;

View file

@ -119,7 +119,7 @@ typedef struct IPX_netgame_info {
char mission_title[MISSION_NAME_LEN+1];
} __pack__ IPX_netgame_info;
int net_ipx_start_game();
int net_ipx_setup_game();
void net_ipx_join_game();
void net_ipx_leave_game();
int net_ipx_endlevel(int *secret);

View file

@ -400,7 +400,7 @@ static int manual_join_game_handler(newmenu *menu, d_event *event, manual_join *
if (mj->connecting)
{
if (net_udp_game_connect(mj))
return -2; // Success! (Keep this menu in future)
return -2; // Success!
else if (!mj->connecting)
items[6].text = blank;
}
@ -471,9 +471,6 @@ void net_udp_manual_join_game()
mj->addrbuf[0] = '\0';
mj->portbuf[0] = '\0';
// FIXME: Keep manual join window to go back to
//setjmp(LeaveGame);
net_udp_init();
memset(&mj->addrbuf,'\0', sizeof(char)*128);
@ -2411,7 +2408,7 @@ int net_udp_start_poll( newmenu *menu, d_event *event, void *userdata )
return 0;
}
static int opt_cinvul, opt_team_anarchy, opt_coop, opt_show_on_map, opt_closed, opt_refuse, opt_maxnet;
static int opt_cinvul, opt_show_on_map;
static int opt_show_on_map, opt_difficulty, opt_setpower, opt_port, opt_packets, opt_plp;
void net_udp_set_power (void)
@ -2527,7 +2524,15 @@ int net_udp_more_options_handler( newmenu *menu, d_event *event, void *userdata
return 0;
}
int net_udp_game_param_handler( newmenu *menu, d_event *event, void *userdata )
typedef struct param_opt
{
int name, level, mode, moreopts;
int closed, refuse, maxnet, coop, team_anarchy;
} param_opt;
int net_udp_start_game(void);
int net_udp_game_param_handler( newmenu *menu, d_event *event, param_opt *opt )
{
newmenu_item *menus = newmenu_get_items(menu);
int citem = newmenu_get_citem(menu);
@ -2536,25 +2541,25 @@ int net_udp_game_param_handler( newmenu *menu, d_event *event, void *userdata )
switch (event->type)
{
case EVENT_NEWMENU_CHANGED:
if (citem == opt_team_anarchy)
if (citem == opt->team_anarchy)
{
menus[opt_closed].value = 1;
menus[opt_closed-1].value = 0;
menus[opt_closed+1].value = 0;
menus[opt->closed].value = 1;
menus[opt->closed-1].value = 0;
menus[opt->closed+1].value = 0;
}
if (menus[opt_coop].value)
if (menus[opt->coop].value)
{
oldmaxnet=1;
if (menus[opt_maxnet].value>2)
if (menus[opt->maxnet].value>2)
{
menus[opt_maxnet].value=2;
menus[opt->maxnet].value=2;
}
if (menus[opt_maxnet].max_value>2)
if (menus[opt->maxnet].max_value>2)
{
menus[opt_maxnet].max_value=2;
menus[opt->maxnet].max_value=2;
}
if (!(Netgame.game_flags & NETGAME_FLAG_SHOW_MAP))
@ -2565,15 +2570,83 @@ int net_udp_game_param_handler( newmenu *menu, d_event *event, void *userdata )
if (oldmaxnet)
{
oldmaxnet=0;
menus[opt_maxnet].value=6;
menus[opt_maxnet].max_value=6;
menus[opt->maxnet].value=6;
menus[opt->maxnet].max_value=6;
}
}
if (citem == opt_maxnet)
sprintf( menus[opt_maxnet].text, "Maximum players: %d", menus[opt_maxnet].value+2 );
if (citem == opt->level)
{
char *slevel = menus[opt->level].text;
Netgame.levelnum = atoi(slevel);
if (!strnicmp(slevel, "s", 1))
Netgame.levelnum = -atoi(slevel+1);
else
Netgame.levelnum = atoi(slevel);
if ((Netgame.levelnum < Last_secret_level) || (Netgame.levelnum > Last_level) || (Netgame.levelnum == 0))
{
nm_messagebox(TXT_ERROR, 1, TXT_OK, TXT_LEVEL_OUT_RANGE );
sprintf(slevel, "1");
return 0;
}
}
if (citem == opt->refuse)
Netgame.RefusePlayers=menus[opt->refuse].value;
if (citem == opt->maxnet)
{
sprintf( menus[opt->maxnet].text, "Maximum players: %d", menus[opt->maxnet].value+2 );
MaxNumNetPlayers = menus[opt->maxnet].value+2;
Netgame.max_numplayers=MaxNumNetPlayers;
}
if ((citem >= opt->mode) && (citem <= opt->mode + 3))
{
if ( menus[opt->mode].value )
Netgame.gamemode = NETGAME_ANARCHY;
else if (menus[opt->mode+1].value) {
Netgame.gamemode = NETGAME_TEAM_ANARCHY;
}
// else if (ANARCHY_ONLY_MISSION) {
// nm_messagebox(NULL, 1, TXT_OK, TXT_ANARCHY_ONLY_MISSION);
// menus[opt->mode+2].value = 0;
// menus[opt->mode+3].value = 0;
// menus[opt->mode].value = 1;
// goto menu;
// }
else if ( menus[opt->mode+2].value )
Netgame.gamemode = NETGAME_ROBOT_ANARCHY;
else if ( menus[opt->mode+3].value )
Netgame.gamemode = NETGAME_COOPERATIVE;
else Int3(); // Invalid mode -- see Rob
}
if (citem == opt->closed)
{
if (menus[opt->closed].value)
Netgame.game_flags |= NETGAME_FLAG_CLOSED;
else
Netgame.game_flags &= ~NETGAME_FLAG_CLOSED;
}
break;
case EVENT_NEWMENU_SELECTED:
if (citem==opt->moreopts)
{
if ( menus[opt->mode+3].value )
Game_mode=GM_MULTI_COOP;
net_udp_more_game_options();
Game_mode=0;
return 1;
}
return !net_udp_start_game();
default:
break;
}
@ -2581,15 +2654,20 @@ int net_udp_game_param_handler( newmenu *menu, d_event *event, void *userdata )
return 0;
}
int net_udp_get_game_params()
int net_udp_setup_game()
{
int i;
int opt, opt_name, opt_level, opt_mode,opt_moreopts;
int optnum;
param_opt opt;
newmenu_item m[20];
char slevel[5];
char level_text[32];
char srmaxnet[50];
net_udp_init();
change_playernum_to(0);
for (i=0;i<MAX_PLAYERS;i++)
if (i!=Player_num)
Players[i].callsign[0]=0;
@ -2611,13 +2689,13 @@ int net_udp_get_game_params()
strcpy(Netgame.mission_name, Current_mission_filename);
strcpy(Netgame.mission_title, Current_mission_longname);
sprintf( slevel, "1" );
sprintf( slevel, "1" ); Netgame.levelnum = 1;
opt = 0;
m[opt].type = NM_TYPE_TEXT; m[opt].text = TXT_DESCRIPTION; opt++;
optnum = 0;
m[optnum].type = NM_TYPE_TEXT; m[optnum].text = TXT_DESCRIPTION; optnum++;
opt_name = opt;
m[opt].type = NM_TYPE_INPUT; m[opt].text = Netgame.game_name; m[opt].text_len = NETGAME_NAME_LEN; opt++;
opt.name = optnum;
m[optnum].type = NM_TYPE_INPUT; m[optnum].text = Netgame.game_name; m[optnum].text_len = NETGAME_NAME_LEN; optnum++;
sprintf(level_text, "%s (1-%d)", TXT_LEVEL_, Last_level);
if (Last_secret_level < -1)
@ -2627,91 +2705,39 @@ int net_udp_get_game_params()
Assert(strlen(level_text) < 32);
m[opt].type = NM_TYPE_TEXT; m[opt].text = level_text; opt++;
m[optnum].type = NM_TYPE_TEXT; m[optnum].text = level_text; optnum++;
opt_level = opt;
m[opt].type = NM_TYPE_INPUT; m[opt].text = slevel; m[opt].text_len=4; opt++;
m[opt].type = NM_TYPE_TEXT; m[opt].text = TXT_OPTIONS; opt++;
opt.level = optnum;
m[optnum].type = NM_TYPE_INPUT; m[optnum].text = slevel; m[optnum].text_len=4; optnum++;
m[optnum].type = NM_TYPE_TEXT; m[optnum].text = TXT_OPTIONS; optnum++;
opt_mode = opt;
m[opt].type = NM_TYPE_RADIO; m[opt].text = TXT_ANARCHY; m[opt].value=(Netgame.gamemode == NETGAME_ANARCHY); m[opt].group=0; opt++;
m[opt].type = NM_TYPE_RADIO; m[opt].text = TXT_TEAM_ANARCHY; m[opt].value=(Netgame.gamemode == NETGAME_TEAM_ANARCHY); m[opt].group=0; opt_team_anarchy=opt; opt++;
m[opt].type = NM_TYPE_RADIO; m[opt].text = TXT_ANARCHY_W_ROBOTS; m[opt].value=(Netgame.gamemode == NETGAME_ROBOT_ANARCHY); m[opt].group=0; opt++;
m[opt].type = NM_TYPE_RADIO; m[opt].text = TXT_COOPERATIVE; m[opt].value=(Netgame.gamemode == NETGAME_COOPERATIVE); m[opt].group=0; opt_coop=opt; opt++;
opt.mode = optnum;
m[optnum].type = NM_TYPE_RADIO; m[optnum].text = TXT_ANARCHY; m[optnum].value=(Netgame.gamemode == NETGAME_ANARCHY); m[optnum].group=0; optnum++;
m[optnum].type = NM_TYPE_RADIO; m[optnum].text = TXT_TEAM_ANARCHY; m[optnum].value=(Netgame.gamemode == NETGAME_TEAM_ANARCHY); m[optnum].group=0; opt.team_anarchy=optnum; optnum++;
m[optnum].type = NM_TYPE_RADIO; m[optnum].text = TXT_ANARCHY_W_ROBOTS; m[optnum].value=(Netgame.gamemode == NETGAME_ROBOT_ANARCHY); m[optnum].group=0; optnum++;
m[optnum].type = NM_TYPE_RADIO; m[optnum].text = TXT_COOPERATIVE; m[optnum].value=(Netgame.gamemode == NETGAME_COOPERATIVE); m[optnum].group=0; opt.coop=optnum; optnum++;
m[opt].type = NM_TYPE_TEXT; m[opt].text = ""; opt++;
m[optnum].type = NM_TYPE_TEXT; m[optnum].text = ""; optnum++;
m[opt].type = NM_TYPE_RADIO; m[opt].text = "Open game"; m[opt].group=1; m[opt].value=(!Netgame.RefusePlayers && !Netgame.game_flags & NETGAME_FLAG_CLOSED); opt++;
opt_closed = opt;
m[opt].type = NM_TYPE_RADIO; m[opt].text = TXT_CLOSED_GAME; m[opt].group=1; m[opt].value=Netgame.game_flags & NETGAME_FLAG_CLOSED; opt++;
opt_refuse = opt;
m[opt].type = NM_TYPE_RADIO; m[opt].text = "Restricted Game "; m[opt].group=1; m[opt].value=Netgame.RefusePlayers; opt++;
m[optnum].type = NM_TYPE_RADIO; m[optnum].text = "Open game"; m[optnum].group=1; m[optnum].value=(!Netgame.RefusePlayers && !Netgame.game_flags & NETGAME_FLAG_CLOSED); optnum++;
opt.closed = optnum;
m[optnum].type = NM_TYPE_RADIO; m[optnum].text = TXT_CLOSED_GAME; m[optnum].group=1; m[optnum].value=Netgame.game_flags & NETGAME_FLAG_CLOSED; optnum++;
opt.refuse = optnum;
m[optnum].type = NM_TYPE_RADIO; m[optnum].text = "Restricted Game "; m[optnum].group=1; m[optnum].value=Netgame.RefusePlayers; optnum++;
opt_maxnet = opt;
opt.maxnet = optnum;
sprintf( srmaxnet, "Maximum players: %d", MaxNumNetPlayers);
m[opt].type = NM_TYPE_SLIDER; m[opt].value=Netgame.max_numplayers-2; m[opt].text= srmaxnet; m[opt].min_value=0;
m[opt].max_value=MaxNumNetPlayers-2; opt++;
m[optnum].type = NM_TYPE_SLIDER; m[optnum].value=Netgame.max_numplayers-2; m[optnum].text= srmaxnet; m[optnum].min_value=0;
m[optnum].max_value=MaxNumNetPlayers-2; optnum++;
opt_moreopts=opt;
m[opt].type = NM_TYPE_MENU; m[opt].text = "Advanced options"; opt++;
opt.moreopts=optnum;
m[optnum].type = NM_TYPE_MENU; m[optnum].text = "Advanced options"; optnum++;
Assert(opt <= 20);
Assert(optnum <= 20);
menu:
i = newmenu_do1( NULL, NULL, opt, m, net_udp_game_param_handler, NULL, 1 );
i = newmenu_do1( NULL, NULL, optnum, m, (int (*)( newmenu *, d_event *, void * ))net_udp_game_param_handler, &opt, 1 );
if (i==opt_moreopts)
{
if ( m[opt_mode+3].value )
Game_mode=GM_MULTI_COOP;
net_udp_more_game_options();
Game_mode=0;
goto menu;
}
Netgame.RefusePlayers=m[opt_refuse].value;
if ( i > -1 ) {
MaxNumNetPlayers = m[opt_maxnet].value+2;
Netgame.max_numplayers=MaxNumNetPlayers;
Netgame.levelnum = atoi(slevel);
if (!strnicmp(slevel, "s", 1))
Netgame.levelnum = -atoi(slevel+1);
else
Netgame.levelnum = atoi(slevel);
if ((Netgame.levelnum < Last_secret_level) || (Netgame.levelnum > Last_level) || (Netgame.levelnum == 0))
{
nm_messagebox(TXT_ERROR, 1, TXT_OK, TXT_LEVEL_OUT_RANGE );
sprintf(slevel, "1");
goto menu;
}
if ( m[opt_mode].value )
Netgame.gamemode = NETGAME_ANARCHY;
else if (m[opt_mode+1].value) {
Netgame.gamemode = NETGAME_TEAM_ANARCHY;
}
// else if (ANARCHY_ONLY_MISSION) {
// nm_messagebox(NULL, 1, TXT_OK, TXT_ANARCHY_ONLY_MISSION);
// m[opt_mode+2].value = 0;
// m[opt_mode+3].value = 0;
// m[opt_mode].value = 1;
// goto menu;
// }
else if ( m[opt_mode+2].value )
Netgame.gamemode = NETGAME_ROBOT_ANARCHY;
else if ( m[opt_mode+3].value )
Netgame.gamemode = NETGAME_COOPERATIVE;
else Int3(); // Invalid mode -- see Rob
if (m[opt_closed].value)
Netgame.game_flags |= NETGAME_FLAG_CLOSED;
else
Netgame.game_flags &= ~NETGAME_FLAG_CLOSED;
}
return i;
return i >= 0;
}
void
@ -3100,13 +3126,6 @@ int net_udp_start_game(void)
{
int i;
net_udp_init();
change_playernum_to(0);
i = net_udp_get_game_params();
if (i<0) return 0;
i = udp_open_socket(0, atoi(UDP_MyPort));
if (i != 0)
@ -3133,9 +3152,12 @@ int net_udp_start_game(void)
StartNewLevel(Netgame.levelnum);
}
else
{
Game_mode = GM_GAME_OVER;
return 0; // see if we want to tweak the game we setup
}
return 1; // FIXME: keep mission listbox for convenience. Need to keep main menu first
return 1; // don't keep params menu or mission listbox (may want to join a game next time)
}
int

View file

@ -7,7 +7,7 @@
#include "multi.h"
// Exported functions
int net_udp_start_game(void);
int net_udp_setup_game(void);
void net_udp_manual_join_game();
int net_udp_objnum_is_past(int objnum);

View file

@ -515,7 +515,7 @@ int newmenu_do2( char * title, char * subtitle, int nitems, newmenu_item * item,
if (menu->leave)
{
rval = menu->citem;
if (!window_close(wind))
if (window_exists(wind) && !window_close(wind))
menu->leave = 0; // user aborted close
}
}
@ -1301,7 +1301,8 @@ int newmenu_handler(window *wind, d_event *event, newmenu *menu)
return 1; // cancel close and do it in newmenu_do2 instead
}
d_free(menu);
if (window_exists(wind))
d_free(menu);
break;
default: