diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 069186f28..10735c900 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -4,6 +4,7 @@ D1X-Rebirth Changelog -------- main/menu.c, main/menu.h: Add hide_menus and show_menus (for later use in the case of D1X) main/titles.c: Make briefing into a window, allowing more flexibility with other windows and tidying code up +main/game.c, main/menu.c, main/mission.c, main/mission.h, main/net_ipx.c, main/net_ipx.h, main/net_udp.c, main/net_udp.h, main/newmenu.c, main/newmenu.h: Make all listboxes fall back to main event loop for flexibility 20100317 -------- diff --git a/main/game.c b/main/game.c index 3c1e2d0cc..9eac65587 100644 --- a/main/game.c +++ b/main/game.c @@ -1086,6 +1086,7 @@ int game_handler(window *wind, d_event *event, void *data) clear_warn_func(game_show_warning); //don't use this func anymore game_disable_cheats(); + show_menus(); Game_wind = NULL; return 0; // continue closing break; @@ -1105,6 +1106,7 @@ int game_handler(window *wind, d_event *event, void *data) // Initialise game, actually runs in main event loop void game() { + hide_menus(); Game_wind = game_setup(); } diff --git a/main/menu.c b/main/menu.c index 12ac1ffdf..a0fb5803b 100644 --- a/main/menu.c +++ b/main/menu.c @@ -118,7 +118,8 @@ static window *menus[16]; // Function Prototypes added after LINTING void do_option(int select); -void do_new_game_menu(void); +int do_new_game_menu(void); +int do_load_level_menu(void); void do_multi_player_menu(); extern void newmenu_close(); extern void ReorderPrimary(); @@ -494,7 +495,7 @@ void do_option ( int select) { switch (select) { case MENU_NEW_GAME: - do_new_game_menu(); + select_mission(0, "New Game\n\nSelect mission", do_new_game_menu); break; case MENU_GAME: break; @@ -552,22 +553,7 @@ void do_option ( int select) break; } case MENU_LOAD_LEVEL: - if (Current_mission || select_mission(0, "Load Level\n\nSelect mission")) - { - newmenu_item m; - char text[10]=""; - int new_level_num; - - m.type=NM_TYPE_INPUT; m.text_len = 10; m.text = text; - - newmenu_do( NULL, "Enter level to load", 1, &m, NULL, NULL ); - - new_level_num = atoi(m.text); - - if (new_level_num!=0 && new_level_num>=Last_secret_level && new_level_num<=Last_level) { - StartNewGame(new_level_num); - } - } + select_mission(0, "Load Level\n\nSelect mission", do_load_level_menu); break; #endif //ifndef RELEASE @@ -576,7 +562,7 @@ void do_option ( int select) #ifdef USE_UDP case MENU_START_UDP_NETGAME: multi_protocol = MULTI_PROTO_UDP; - net_udp_start_game(); + select_mission(1, TXT_MULTI_MISSION, net_udp_start_game); break; case MENU_JOIN_MANUAL_UDP_NETGAME: multi_protocol = MULTI_PROTO_UDP; @@ -591,7 +577,7 @@ void do_option ( int select) case MENU_START_IPX_NETGAME: multi_protocol = MULTI_PROTO_IPX; ipxdrv_set(NETPROTO_IPX); - net_ipx_start_game(); + select_mission(1, TXT_MULTI_MISSION, net_ipx_start_game); break; case MENU_JOIN_IPX_NETGAME: multi_protocol = MULTI_PROTO_IPX; @@ -601,7 +587,7 @@ void do_option ( int select) case MENU_START_KALI_NETGAME: multi_protocol = MULTI_PROTO_IPX; ipxdrv_set(NETPROTO_KALINIX); - net_ipx_start_game(); + select_mission(1, TXT_MULTI_MISSION, net_ipx_start_game); break; case MENU_JOIN_KALI_NETGAME: multi_protocol = MULTI_PROTO_IPX; @@ -785,13 +771,10 @@ int do_difficulty_menu() return 0; } -void do_new_game_menu() +int do_new_game_menu() { int new_level_num,player_highest_level; - if (!select_mission(0, "New Game\n\nSelect mission")) - return; - new_level_num = 1; player_highest_level = get_highest_level(); @@ -817,7 +800,7 @@ try_again: choice = newmenu_do( NULL, TXT_SELECT_START_LEV, n_items, m, NULL, NULL ); if (choice==-1 || m[1].text[0]==0) - return; + return 0; new_level_num = atoi(m[1].text); @@ -831,10 +814,31 @@ try_again: Difficulty_level = PlayerCfg.DefaultDifficulty; if (!do_difficulty_menu()) - return; + return 0; StartNewGame(new_level_num); + return 1; // exit mission listbox +} + +int do_load_level_menu(void) +{ + newmenu_item m; + char text[10]=""; + int new_level_num; + + m.type=NM_TYPE_INPUT; m.text_len = 10; m.text = text; + + newmenu_do( NULL, "Enter level to load", 1, &m, NULL, NULL ); + + new_level_num = atoi(m.text); + + if (new_level_num!=0 && new_level_num>=Last_secret_level && new_level_num<=Last_level) { + StartNewGame(new_level_num); + return 1; + } + + return 0; } void do_sound_menu(); @@ -1251,42 +1255,36 @@ void do_multi_player_menu() int menu_choice[12]; newmenu_item m[12]; int choice = 0, num_options = 0; - int old_game_mode; - do { - old_game_mode = Game_mode; - num_options = 0; + num_options = 0; #ifdef USE_UDP - m[num_options].type=NM_TYPE_TEXT; m[num_options].text="UDP:"; num_options++; - m[num_options].type=NM_TYPE_MENU; m[num_options].text="HOST GAME"; menu_choice[num_options]=MENU_START_UDP_NETGAME; num_options++; - m[num_options].type=NM_TYPE_MENU; m[num_options].text="FIND LAN GAMES"; menu_choice[num_options]=MENU_JOIN_LIST_UDP_NETGAME; num_options++; - //m[num_options].type=NM_TYPE_MENU; m[num_options].text="FIND LAN/ONLINE GAMES"; menu_choice[num_options]=MENU_JOIN_LIST_UDP_NETGAME; num_options++; - m[num_options].type=NM_TYPE_MENU; m[num_options].text="JOIN GAME MANUALLY"; menu_choice[num_options]=MENU_JOIN_MANUAL_UDP_NETGAME; num_options++; + m[num_options].type=NM_TYPE_TEXT; m[num_options].text="UDP:"; num_options++; + m[num_options].type=NM_TYPE_MENU; m[num_options].text="HOST GAME"; menu_choice[num_options]=MENU_START_UDP_NETGAME; num_options++; + m[num_options].type=NM_TYPE_MENU; m[num_options].text="FIND LAN GAMES"; menu_choice[num_options]=MENU_JOIN_LIST_UDP_NETGAME; num_options++; + //m[num_options].type=NM_TYPE_MENU; m[num_options].text="FIND LAN/ONLINE GAMES"; menu_choice[num_options]=MENU_JOIN_LIST_UDP_NETGAME; num_options++; + m[num_options].type=NM_TYPE_MENU; m[num_options].text="JOIN GAME MANUALLY"; menu_choice[num_options]=MENU_JOIN_MANUAL_UDP_NETGAME; num_options++; #endif #ifdef USE_IPX - m[num_options].type=NM_TYPE_TEXT; m[num_options].text=""; num_options++; - m[num_options].type=NM_TYPE_TEXT; m[num_options].text="IPX:"; num_options++; - m[num_options].type=NM_TYPE_MENU; m[num_options].text="HOST GAME"; menu_choice[num_options]=MENU_START_IPX_NETGAME; num_options++; - m[num_options].type=NM_TYPE_MENU; m[num_options].text="JOIN GAME"; menu_choice[num_options]=MENU_JOIN_IPX_NETGAME; num_options++; + m[num_options].type=NM_TYPE_TEXT; m[num_options].text=""; num_options++; + m[num_options].type=NM_TYPE_TEXT; m[num_options].text="IPX:"; num_options++; + m[num_options].type=NM_TYPE_MENU; m[num_options].text="HOST GAME"; menu_choice[num_options]=MENU_START_IPX_NETGAME; num_options++; + m[num_options].type=NM_TYPE_MENU; m[num_options].text="JOIN GAME"; menu_choice[num_options]=MENU_JOIN_IPX_NETGAME; num_options++; #ifdef __LINUX__ - m[num_options].type=NM_TYPE_TEXT; m[num_options].text=""; num_options++; - m[num_options].type=NM_TYPE_TEXT; m[num_options].text="XKALI:"; num_options++; - m[num_options].type=NM_TYPE_MENU; m[num_options].text="HOST GAME"; menu_choice[num_options]=MENU_START_KALI_NETGAME; num_options++; - m[num_options].type=NM_TYPE_MENU; m[num_options].text="JOIN GAME"; menu_choice[num_options]=MENU_JOIN_KALI_NETGAME; num_options++; + m[num_options].type=NM_TYPE_TEXT; m[num_options].text=""; num_options++; + m[num_options].type=NM_TYPE_TEXT; m[num_options].text="XKALI:"; num_options++; + m[num_options].type=NM_TYPE_MENU; m[num_options].text="HOST GAME"; menu_choice[num_options]=MENU_START_KALI_NETGAME; num_options++; + m[num_options].type=NM_TYPE_MENU; m[num_options].text="JOIN GAME"; menu_choice[num_options]=MENU_JOIN_KALI_NETGAME; num_options++; #endif #endif - choice = newmenu_do1( NULL, TXT_MULTIPLAYER, num_options, m, NULL, NULL, choice ); - - if ( choice > -1 ) - do_option(menu_choice[choice]); + choice = newmenu_do1( NULL, TXT_MULTIPLAYER, num_options, m, NULL, NULL, choice ); - if (old_game_mode != Game_mode) - break; // leave menu - - } while( choice > -1 ); + // 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]); } #endif diff --git a/main/mission.c b/main/mission.c index 79b406ef9..6e5d91022 100644 --- a/main/mission.c +++ b/main/mission.c @@ -622,17 +622,84 @@ int load_mission_by_name(char *mission_name) return found; } -int select_mission(int anarchy_mode, char *message) +typedef struct mission_menu +{ + mle *mission_list; + int (*when_selected)(void); +} mission_menu; + +int mission_menu_handler(listbox *lb, d_event *event, mission_menu *mm) +{ + char **list = listbox_get_items(lb); + int citem = listbox_get_citem(lb); + + switch (event->type) + { + case EVENT_NEWMENU_SELECTED: + if (citem >= 0) + { + // Chose a mission + strcpy(GameCfg.LastMission, list[citem]); + + 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 !(*mm->when_selected)(); + break; + + case EVENT_WINDOW_CLOSE: + free_mission_list(mm->mission_list); + d_free(list); + d_free(mm); + break; + + default: + break; + } + + return 0; +} + +int select_mission(int anarchy_mode, char *message, int (*when_selected)(void)) { mle *mission_list = build_mission_list(anarchy_mode); int new_mission_num; - if (num_missions <= 1) { + if (num_missions <= 1) + { new_mission_num = load_mission(mission_list) ? 0 : -1; - } else { + free_mission_list(mission_list); + (*when_selected)(); + + return (new_mission_num >= 0); + } + else + { + mission_menu *mm; int i, default_mission; - char * m[MAX_MISSIONS]; + char **m; + + MALLOC(m, char *, num_missions); + if (!m) + { + free_mission_list(mission_list); + return 0; + } + + MALLOC(mm, mission_menu, 1); + if (!mm) + { + d_free(m); + free_mission_list(mission_list); + return 0; + } + mm->mission_list = mission_list; + mm->when_selected = when_selected; + default_mission = 0; for (i = 0; i < num_missions; i++) { m[i] = mission_list[i].mission_name; @@ -640,19 +707,8 @@ int select_mission(int anarchy_mode, char *message) default_mission = i; } - new_mission_num = newmenu_listbox1( message, num_missions, m, 1, default_mission, NULL, NULL ); - - if (new_mission_num >= 0) { - // Chose a mission - strcpy(GameCfg.LastMission, m[new_mission_num] ); - - if (!load_mission(mission_list + new_mission_num)) { - nm_messagebox( NULL, 1, TXT_OK, TXT_MISSION_ERROR); - new_mission_num = -1; - } - } + newmenu_listbox1( message, num_missions, m, 1, default_mission, (int (*)(listbox *, d_event *, void *))mission_menu_handler, mm ); } - free_mission_list(mission_list); - return (new_mission_num >= 0); + return 1; // presume success } diff --git a/main/mission.h b/main/mission.h index 24dc05480..b6462a83d 100644 --- a/main/mission.h +++ b/main/mission.h @@ -84,7 +84,7 @@ int load_mission_by_name (char *mission_name); //Handles creating and selecting from the mission list. //Returns 1 if a mission was loaded. -int select_mission (int anarchy_mode, char *message); +int select_mission (int anarchy_mode, char *message, int (*when_selected)(void)); void free_mission(void); diff --git a/main/net_ipx.c b/main/net_ipx.c index 4dbf88c89..fa138aae2 100644 --- a/main/net_ipx.c +++ b/main/net_ipx.c @@ -2384,9 +2384,6 @@ int net_ipx_get_game_params() Netgame.AllowedItems = NETFLAG_DOPOWERUP; // enable all powerups Netgame.protocol.ipx.protocol_version = MULTI_PROTO_VERSION; - if (!select_mission(1, TXT_MULTI_MISSION)) - return -1; - strcpy(Netgame.mission_name, Current_mission_filename); strcpy(Netgame.mission_title, Current_mission_longname); @@ -2944,7 +2941,7 @@ abort: return(1); } -void net_ipx_start_game(void) +int net_ipx_start_game(void) { int i; @@ -2953,27 +2950,21 @@ void net_ipx_start_game(void) if ( !IPX_active ) { nm_messagebox(NULL, 1, TXT_OK, TXT_IPX_NOT_FOUND ); - return; + return 0; } - // FIXME: Keep multiplayer menu to go back to - //if (setjmp(LeaveGame)) { - // Game_mode = GM_GAME_OVER; - // return; - //} - net_ipx_init(); change_playernum_to(0); if (net_ipx_find_game()) { nm_messagebox(NULL, 1, TXT_OK, TXT_NET_FULL); - return; + return 0; } i = net_ipx_get_game_params(); - if (i<0) return; + if (i<0) return 0; if (IPX_Socket) { ipxdrv_change_default_socket( IPX_DEFAULT_SOCKET + IPX_Socket ); @@ -2996,6 +2987,7 @@ void net_ipx_start_game(void) else Game_mode = GM_GAME_OVER; + return 1; // FIXME: keep mission listbox for convenience. Need to keep main menu first } void restart_net_searching(newmenu_item * m) diff --git a/main/net_ipx.h b/main/net_ipx.h index e4d4127c8..90e3fbfb7 100644 --- a/main/net_ipx.h +++ b/main/net_ipx.h @@ -119,7 +119,7 @@ typedef struct IPX_netgame_info { char mission_title[MISSION_NAME_LEN+1]; } __pack__ IPX_netgame_info; -void net_ipx_start_game(); +int net_ipx_start_game(); void net_ipx_join_game(); void net_ipx_leave_game(); int net_ipx_endlevel(int *secret); diff --git a/main/net_udp.c b/main/net_udp.c index 4a8f4b00d..d148cdd12 100644 --- a/main/net_udp.c +++ b/main/net_udp.c @@ -2576,9 +2576,6 @@ int net_udp_get_game_params() Netgame.PacketLossPrevention = 1; - if (!select_mission(1, TXT_MULTI_MISSION)) - return -1; - strcpy(Netgame.mission_name, Current_mission_filename); strcpy(Netgame.mission_title, Current_mission_longname); @@ -3070,34 +3067,27 @@ abort: return(1); } -void net_udp_start_game(void) +int net_udp_start_game(void) { int i; - // FIXME: Keep multiplayer menu to go back to - //if (setjmp(LeaveGame)) - //{ - // Game_mode = GM_GAME_OVER; - // return; - //} - net_udp_init(); change_playernum_to(0); i = net_udp_get_game_params(); - if (i<0) return; + if (i<0) return 0; i = udp_open_socket(0, atoi(UDP_MyPort)); if (i != 0) - return; + return 0; if (atoi(UDP_MyPort) != UDP_PORT_DEFAULT) i = udp_open_socket(1, UDP_PORT_DEFAULT); // Default port open for Broadcasts if (i != 0) - return; + return 0; N_players = 0; @@ -3112,10 +3102,11 @@ void net_udp_start_game(void) if(net_udp_select_players()) { StartNewLevel(Netgame.levelnum); - } + } else Game_mode = GM_GAME_OVER; + return 1; // FIXME: keep mission listbox for convenience. Need to keep main menu first } int diff --git a/main/net_udp.h b/main/net_udp.h index 409f47e45..e6de8be57 100644 --- a/main/net_udp.h +++ b/main/net_udp.h @@ -7,7 +7,7 @@ #include "multi.h" // Exported functions -void net_udp_start_game(void); +int net_udp_start_game(void); void net_udp_manual_join_game(); int net_udp_objnum_is_past(int objnum); diff --git a/main/newmenu.c b/main/newmenu.c index 41bc0aa61..65d10a9bd 100644 --- a/main/newmenu.c +++ b/main/newmenu.c @@ -1686,7 +1686,7 @@ struct listbox char **item; int allow_abort_flag; int (*listbox_callback)(listbox *lb, d_event *event, void *userdata); - int done, citem, first_item; + int citem, first_item; int box_w, height, box_x, box_y, title_height; int mouse_state, omouse_state; void *userdata; @@ -1786,7 +1786,7 @@ int listbox_key_command(window *wind, d_event *event, listbox *lb) case KEY_ESC: if (lb->allow_abort_flag) { lb->citem = -1; - lb->done = 1; + window_close(wind); return 1; } break; @@ -1797,7 +1797,7 @@ int listbox_key_command(window *wind, d_event *event, listbox *lb) if (lb->listbox_callback && (*lb->listbox_callback)(lb, event, lb->userdata)) return 1; - lb->done = 1; + window_close(wind); return 1; break; @@ -1873,7 +1873,7 @@ int listbox_idle(window *wind, listbox *lb) if (lb->listbox_callback && (*lb->listbox_callback)(lb, &event, lb->userdata)) return 1; - lb->done = 1; + window_close(wind); return 1; break; } @@ -1938,15 +1938,7 @@ int listbox_handler(window *wind, d_event *event, listbox *lb) { int rval = (*lb->listbox_callback)(lb, event, lb->userdata); if (rval) - { - if (rval < -1) - { - lb->citem = rval; - lb->done = 1; - } - return 1; // event handled - } } switch (event->type) @@ -1973,13 +1965,6 @@ int listbox_handler(window *wind, d_event *event, listbox *lb) break; case EVENT_WINDOW_CLOSE: - if (!lb->done) - { - lb->citem = -1; - lb->done = 1; - return 1; // cancel close and do it in newmenu_listbox1 instead - } - d_free(lb); break; @@ -1990,22 +1975,21 @@ int listbox_handler(window *wind, d_event *event, listbox *lb) return 0; } -int newmenu_listbox( char * title, int nitems, char * items[], int allow_abort_flag, int (*listbox_callback)(listbox *lb, d_event *event, void *userdata), void *userdata ) +listbox *newmenu_listbox( char * title, int nitems, char * items[], int allow_abort_flag, int (*listbox_callback)(listbox *lb, d_event *event, void *userdata), void *userdata ) { return newmenu_listbox1( title, nitems, items, allow_abort_flag, 0, listbox_callback, userdata ); } -int newmenu_listbox1( char * title, int nitems, char * items[], int allow_abort_flag, int default_item, int (*listbox_callback)(listbox *lb, d_event *event, void *userdata), void *userdata ) +listbox *newmenu_listbox1( char * title, int nitems, char * items[], int allow_abort_flag, int default_item, int (*listbox_callback)(listbox *lb, d_event *event, void *userdata), void *userdata ) { listbox *lb; window *wind; - int i, rval = -1; - int done = 0; + int i; MALLOC(lb, listbox, 1); if (!lb) - return -1; + return NULL; memset(lb, 0, sizeof(listbox)); newmenu_close(); @@ -2048,10 +2032,9 @@ int newmenu_listbox1( char * title, int nitems, char * items[], int allow_abort_ { d_free(lb); - return -1; + return NULL; } - lb->done = 0; lb->citem = default_item; if ( lb->citem < 0 ) lb->citem = 0; if ( lb->citem >= nitems ) lb->citem = 0; @@ -2061,21 +2044,7 @@ int newmenu_listbox1( char * title, int nitems, char * items[], int allow_abort_ lb->mouse_state = lb->omouse_state = 0; //dblclick_flag = 0; - while(!done) - { - event_process(); - - if (lb->done) - { - rval = lb->citem; - if (!window_close(wind)) - lb->done = 0; // user aborted close - else - done = 1; - } - } - - return rval; + return lb; } //added on 10/14/98 by Victor Rachels to attempt a fixedwidth font messagebox diff --git a/main/newmenu.h b/main/newmenu.h index 5e81c83af..4849b4333 100644 --- a/main/newmenu.h +++ b/main/newmenu.h @@ -146,8 +146,8 @@ extern int listbox_get_nitems(listbox *lb); extern int listbox_get_citem(listbox *lb); extern void listbox_delete_item(listbox *lb, int item); -extern int newmenu_listbox(char *title, int nitems, char *items[], int allow_abort_flag, int (*listbox_callback)(listbox *lb, d_event *event, void *userdata), void *userdata); -extern int newmenu_listbox1(char *title, int nitems, char *items[], int allow_abort_flag, int default_item, int (*listbox_callback)(listbox *lb, d_event *event, void *userdata), void *userdata); +extern listbox *newmenu_listbox(char *title, int nitems, char *items[], int allow_abort_flag, int (*listbox_callback)(listbox *lb, d_event *event, void *userdata), void *userdata); +extern listbox *newmenu_listbox1(char *title, int nitems, char *items[], int allow_abort_flag, int default_item, int (*listbox_callback)(listbox *lb, d_event *event, void *userdata), void *userdata); //added on 10/14/98 by Victor Rachels to attempt a fixedwidth font messagebox int nm_messagebox_fixedfont(char *title, int nchoices, ...);