From 3ba90f69e0af4b02a2f4d1f6126fa5e99ec8dbb2 Mon Sep 17 00:00:00 2001 From: kreatordxx <> Date: Sat, 3 Apr 2010 07:24:50 +0000 Subject: [PATCH] Make newmenu_do3 and newmenu_dotiny return as soon as the newmenu is created, which will allow the main menu (and others) to persist --- CHANGELOG.txt | 6 +- arch/sdl/mouse.c | 2 +- main/game.c | 39 +++- main/net_ipx.c | 466 ++++++++++++++++++++++++++--------------------- main/net_ipx.h | 2 +- main/newmenu.c | 112 +++++++----- main/newmenu.h | 7 +- main/state.c | 2 +- 8 files changed, 375 insertions(+), 261 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 8fe5514f9..cf75fae26 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,6 +1,10 @@ D1X-Rebirth Changelog -20100401 +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 + +20100402 -------- arch/include/event.h, arch/sdl/event.c, arch/sdl/key.c, arch/sdl/mouse.c, main/automap.c, main/credits.c, main/game.c, main/gamecntl.c, main/inferno.c, main/kconfig.c, main/kmatrix.c, main/net_ipx.c, main/net_udp.c, main/newmenu.c, main/scores.c, main/titles.c: Add a default event handler for screenshots, entering debugger, Redbook repeating etc main/menu.c, main/newmenu.c: Keep demo selector just after playing one, for convenience diff --git a/arch/sdl/mouse.c b/arch/sdl/mouse.c index 410856338..567c861e0 100644 --- a/arch/sdl/mouse.c +++ b/arch/sdl/mouse.c @@ -129,7 +129,7 @@ void mouse_flush() // clears all mice events... //======================================================================== void mouse_get_pos( int *x, int *y, int *z ) { - event_poll(); + //event_poll(); // Have to assume this is called in event_process, because event_poll can cause a window to close (depending on what the user does) *x=Mouse.x; *y=Mouse.y; *z=Mouse.z; diff --git a/main/game.c b/main/game.c index 19b876134..3e5bd9191 100644 --- a/main/game.c +++ b/main/game.c @@ -731,10 +731,27 @@ extern int Death_sequence_aborted; #define EXT_MUSIC_TEXT "Audio CD" #endif +static int free_help(newmenu *menu, d_event *event, void *userdata) +{ + userdata = userdata; + + if (event->type == EVENT_WINDOW_CLOSE) + { + newmenu_item *items = newmenu_get_items(menu); + d_free(items); + } + + return 0; +} + void show_help() { int nitems = 0; - newmenu_item m[26]; + newmenu_item *m; + + MALLOC(m, newmenu_item, 26); + if (!m) + return; m[nitems].type = NM_TYPE_TEXT; m[nitems++].text = TXT_HELP_ESC; m[nitems].type = NM_TYPE_TEXT; m[nitems++].text = "SHIFT-ESC\t SHOW GAME LOG"; @@ -771,14 +788,19 @@ void show_help() m[nitems].type = NM_TYPE_TEXT; m[nitems++].text = ""; m[nitems].type = NM_TYPE_TEXT; m[nitems++].text = "(Use \x85-# for F#. e.g. \x85-1 for F1)"; #endif - newmenu_dotiny( NULL, TXT_KEYS, nitems, m, NULL, NULL ); + + newmenu_dotiny( NULL, TXT_KEYS, nitems, m, free_help, NULL ); } void show_netgame_help() { int nitems = 0; - newmenu_item m[13]; + newmenu_item *m; + MALLOC(m, newmenu_item, 13); + if (!m) + return; + m[nitems].type = NM_TYPE_TEXT; m[nitems++].text = "F1\t THIS SCREEN"; m[nitems].type = NM_TYPE_TEXT; m[nitems++].text = "ALT-F4\t SHOW RETICLE NAMES"; m[nitems].type = NM_TYPE_TEXT; m[nitems++].text = "F7\t TOGGLE KILL LIST"; @@ -797,14 +819,18 @@ void show_netgame_help() m[nitems].type = NM_TYPE_TEXT; m[nitems++].text = "kick: (*)\t KICK PLAYER (*) FROM GAME (Host-only)"; m[nitems].type = NM_TYPE_TEXT; m[nitems++].text = "KillReactor\t BLOW UP THE MINE (Host-only)"; - newmenu_dotiny( NULL, TXT_KEYS, nitems, m, NULL, NULL ); + newmenu_dotiny( NULL, TXT_KEYS, nitems, m, free_help, NULL ); } void show_newdemo_help() { - newmenu_item m[15]; + newmenu_item *m; int nitems = 0; + MALLOC(m, newmenu_item, 15); + if (!m) + return; + m[nitems].type = NM_TYPE_TEXT; m[nitems++].text = "ESC\t QUIT DEMO PLAYBACK"; m[nitems].type = NM_TYPE_TEXT; m[nitems++].text = "F1\t THIS SCREEN"; m[nitems].type = NM_TYPE_TEXT; m[nitems++].text = TXT_HELP_F2; @@ -822,7 +848,8 @@ void show_newdemo_help() m[nitems].type = NM_TYPE_TEXT; m[nitems++].text = ""; m[nitems].type = NM_TYPE_TEXT; m[nitems++].text = "(Use \x85-# for F#. e.g. \x85-1 for F1)"; #endif - newmenu_dotiny( NULL, "DEMO PLAYBACK CONTROLS", nitems, m, NULL, NULL ); + + newmenu_dotiny( NULL, "DEMO PLAYBACK CONTROLS", nitems, m, free_help, NULL ); } //temp function until Matt cleans up game sequencing diff --git a/main/net_ipx.c b/main/net_ipx.c index 5e62e5e83..f653e4da6 100644 --- a/main/net_ipx.c +++ b/main/net_ipx.c @@ -612,7 +612,9 @@ int net_ipx_change_socket(int new_socket) #define ENDLEVEL_SEND_INTERVAL F1_0*2 #define ENDLEVEL_IDLE_TIME F1_0*10 -int net_ipx_endlevel_poll( newmenu *menu, d_event *event, void *userdata ) +int net_ipx_endlevel_poll2( newmenu *menu, d_event *event, int *secret ); + +int net_ipx_endlevel_poll( newmenu *menu, d_event *event, int *secret ) { // Polling loop for End-of-level menu @@ -626,79 +628,119 @@ int net_ipx_endlevel_poll( newmenu *menu, d_event *event, void *userdata ) int previous_seconds_left; newmenu_item *menus = newmenu_get_items(menu); - userdata = userdata; - - if (event->type != EVENT_IDLE) - return 0; - - // Send our endlevel packet at regular intervals - - if (timer_get_fixed_seconds() > t1+ENDLEVEL_SEND_INTERVAL) + switch (event->type) { - net_ipx_send_endlevel_packet(); - t1 = timer_get_fixed_seconds(); - } + case EVENT_KEY_COMMAND: + if (((d_event_keycommand *)event)->keycode != KEY_ESC) + return 0; - for (i = 0; i < N_players; i++) - previous_state[i] = Players[i].connected; - - previous_seconds_left = Countdown_seconds_left; - - net_ipx_listen(); - - for (i = 0; i < N_players; i++) - { - if (previous_state[i] != Players[i].connected) - { - sprintf(menus[i].text, "%s %s", Players[i].callsign, CONNECT_STATES(Players[i].connected)); - } - if (Players[i].connected == CONNECT_PLAYING) - { - // Check timeout for idle players - if (timer_get_fixed_seconds() > Netgame.players[i].LastPacketTime+ENDLEVEL_IDLE_TIME) { - Players[i].connected = CONNECT_DISCONNECTED; - net_ipx_send_endlevel_sub(i); - } - } + newmenu_item m2[2]; + int choice; + + m2[0].type = m2[1].type = NM_TYPE_MENU; + m2[0].text = TXT_YES; m2[1].text = TXT_NO; + choice = newmenu_do1(NULL, TXT_SURE_LEAVE_GAME, 2, m2, (int (*)( newmenu *, d_event *, void * ))net_ipx_endlevel_poll2, secret, 1); + if (choice == 0) + { + Players[Player_num].connected = CONNECT_DISCONNECTED; + window_close(newmenu_get_window(menu)); + if (Game_wind) + window_close(Game_wind); // exit game + return 0; + } + if (choice > -2) + return 1; // stay in endlevel screen + else + return 0; // go to next level + } + + + case EVENT_IDLE: + // Send our endlevel packet at regular intervals - if ((Players[i].connected != CONNECT_PLAYING) && (Players[i].connected != CONNECT_ESCAPE_TUNNEL) && (Players[i].connected != CONNECT_END_MENU)) - num_ready++; - if (Players[i].connected != CONNECT_PLAYING) - num_escaped++; - if (Players[i].connected == CONNECT_FOUND_SECRET) - goto_secret = 1; - } + if (timer_get_fixed_seconds() > t1+ENDLEVEL_SEND_INTERVAL) + { + net_ipx_send_endlevel_packet(); + t1 = timer_get_fixed_seconds(); + } - if (num_escaped == N_players) // All players are out of the mine - { - Countdown_seconds_left = -1; - } + for (i = 0; i < N_players; i++) + previous_state[i] = Players[i].connected; - if (previous_seconds_left != Countdown_seconds_left) - { - if (Countdown_seconds_left < 0) - { - sprintf(menus[N_players].text, TXT_REACTOR_EXPLODED); - } - else - { - sprintf(menus[N_players].text, "%s: %d %s ", TXT_TIME_REMAINING, Countdown_seconds_left, TXT_SECONDS); - } - } + previous_seconds_left = Countdown_seconds_left; - if (num_ready == N_players) // All players have checked in or are disconnected - { - if (goto_secret) - return -3; - else - return -2; + net_ipx_listen(); + + for (i = 0; i < N_players; i++) + { + if (previous_state[i] != Players[i].connected) + { + sprintf(menus[i].text, "%s %s", Players[i].callsign, CONNECT_STATES(Players[i].connected)); + } + if (Players[i].connected == CONNECT_PLAYING) + { + // Check timeout for idle players + if (timer_get_fixed_seconds() > Netgame.players[i].LastPacketTime+ENDLEVEL_IDLE_TIME) + { + Players[i].connected = CONNECT_DISCONNECTED; + net_ipx_send_endlevel_sub(i); + } + } + + if ((Players[i].connected != CONNECT_PLAYING) && (Players[i].connected != CONNECT_ESCAPE_TUNNEL) && (Players[i].connected != CONNECT_END_MENU)) + num_ready++; + if (Players[i].connected != CONNECT_PLAYING) + num_escaped++; + if (Players[i].connected == CONNECT_FOUND_SECRET) + goto_secret = 1; + } + + if (num_escaped == N_players) // All players are out of the mine + { + Countdown_seconds_left = -1; + } + + if (previous_seconds_left != Countdown_seconds_left) + { + if (Countdown_seconds_left < 0) + { + sprintf(menus[N_players].text, TXT_REACTOR_EXPLODED); + } + else + { + sprintf(menus[N_players].text, "%s: %d %s ", TXT_TIME_REMAINING, Countdown_seconds_left, TXT_SECONDS); + } + } + + if (num_ready == N_players) // All players have checked in or are disconnected + { + if (goto_secret) + *secret = 1; // If any player went to the secret level, we go to the secret level + + return -2; + } + break; + + case EVENT_WINDOW_CLOSE: + net_ipx_send_endlevel_packet(); + net_ipx_send_endlevel_packet(); + MySyncPackInitialized = 0; + + net_ipx_update_netgame(); + + d_free(menus[0].text); // frees all text + d_free(menus); + break; + + default: + break; } return 0; } -int net_ipx_endlevel_poll2( newmenu *menu, d_event *event, void *userdata ) +int net_ipx_endlevel_poll2( newmenu *menu, d_event *event, int *secret ) { // Polling loop for End-of-level menu @@ -708,7 +750,6 @@ int net_ipx_endlevel_poll2( newmenu *menu, d_event *event, void *userdata ) int goto_secret = 0; menu = menu; - userdata = userdata; if (event->type != EVENT_IDLE) return 0; @@ -734,9 +775,9 @@ int net_ipx_endlevel_poll2( newmenu *menu, d_event *event, void *userdata ) if (num_ready == N_players) // All players have checked in or are disconnected { if (goto_secret) - return -3; - else - return -2; + *secret = 1; + + return -2; } return 0; @@ -786,18 +827,28 @@ int net_ipx_kmatrix_poll1( newmenu *menu, d_event *event, void *userdata ) return 0; } -int -net_ipx_endlevel(int *secret) +int net_ipx_endlevel(int *secret) { // Do whatever needs to be done between levels - newmenu_item m[MAX_NUM_NET_PLAYERS+1]; - char menu_text[MAX_NUM_NET_PLAYERS+1][80]; - int i, choice; + newmenu *menu; + window *wind; + newmenu_item *m; + char *menu_text; + char *title; + int i; + + MALLOC(m, newmenu_item, MAX_NUM_NET_PLAYERS+1); + if (!m) + return 0; + MALLOC(menu_text, char, (MAX_NUM_NET_PLAYERS+2)*80); + if (!menu_text) + { + d_free(m); + return 0; + } - char text[80]; - - Function_mode = FMODE_MENU; + Function_mode = FMODE_MENU; net_ipx_flush(); @@ -807,58 +858,32 @@ net_ipx_endlevel(int *secret) net_ipx_send_endlevel_packet(); -newmenu: // Setup menu text pointers and zero them for (i=0; i -2) - goto newmenu; - } - - if (choice > -2) - goto menu; - - if (choice == -3) - *secret = 1; // If any player went to the secret level, we go to the secret level - - net_ipx_send_endlevel_packet(); - net_ipx_send_endlevel_packet(); - MySyncPackInitialized = 0; - - net_ipx_update_netgame(); + // Stay here until finished + wind = newmenu_get_window(menu); + while (window_exists(wind)) + event_process(); return(0); } @@ -3006,67 +3031,30 @@ void restart_net_searching(newmenu_item * m) num_active_ipx_changed = 1; } -int net_ipx_join_poll( newmenu *menu, d_event *event, void *userdata ) +void net_ipx_join_listen(newmenu *menu) { - // Polling loop for Join Game menu newmenu_item *menus = newmenu_get_items(menu); static fix t1 = 0; - int i, osocket,join_status,temp; - int key = 0; - int rval = 0; - - if (event->type == EVENT_KEY_COMMAND) - key = ((d_event_keycommand *)event)->keycode; - else if (event->type != EVENT_IDLE) - return 0; - - userdata = userdata; - - if ( IPX_allow_socket_changes ) { - osocket = IPX_Socket; - - if ( key==KEY_PAGEDOWN ) { IPX_Socket--; rval = 1; } - if ( key==KEY_PAGEUP ) { IPX_Socket++; rval = 1; } - - if (IPX_Socket>99) - IPX_Socket=99; - if (IPX_Socket<-99) - IPX_Socket=-99; - - if ( IPX_Socket+IPX_DEFAULT_SOCKET > 0x8000 ) - IPX_Socket = 0x8000 - IPX_DEFAULT_SOCKET; - - if ( IPX_Socket+IPX_DEFAULT_SOCKET < 0 ) - IPX_Socket = IPX_DEFAULT_SOCKET; - - if (IPX_Socket != osocket ) { - sprintf( menus[0].text, "\t%s %+d (PgUp/PgDn to change)", TXT_CURRENT_IPX_SOCKET, IPX_Socket ); - net_ipx_listen(); - ipxdrv_change_default_socket( IPX_DEFAULT_SOCKET + IPX_Socket ); - restart_net_searching(menus); - net_ipx_send_game_list_request(); - return rval; - } - } + int i,join_status,temp; // send a request for game info every 3 seconds if (timer_get_fixed_seconds() > t1+F1_0*3) { t1 = timer_get_fixed_seconds(); net_ipx_send_game_list_request(); } - + temp=num_active_ipx_games; - + net_ipx_listen(); - + if (!num_active_ipx_changed) - return rval; - + return; + if (temp!=num_active_ipx_games) digi_play_sample (SOUND_HUD_MESSAGE,F1_0); - + num_active_ipx_changed = 0; - + // Copy the active games data into the menu options for (i = 0; i < num_active_ipx_games; i++) { @@ -3074,35 +3062,35 @@ int net_ipx_join_poll( newmenu *menu, d_event *event, void *userdata ) int j,x, k,tx,ty,ta,nplayers = 0; char levelname[8],MissName[25],GameName[25],thold[2]; thold[1]=0; - + // These next two loops protect against menu skewing // if missiontitle or gamename contain a tab - + for (x=0,tx=0,k=0,j=0;j<15;j++) { if (Active_ipx_games[i].mission_title[j]=='\t') continue; thold[0]=Active_ipx_games[i].mission_title[j]; gr_get_string_size (thold,&tx,&ty,&ta); - + if ((x+=tx)>=FSPACX(55)) { MissName[k]=MissName[k+1]=MissName[k+2]='.'; k+=3; break; } - + MissName[k++]=Active_ipx_games[i].mission_title[j]; } MissName[k]=0; - + for (x=0,tx=0,k=0,j=0;j<15;j++) { if (Active_ipx_games[i].game_name[j]=='\t') continue; thold[0]=Active_ipx_games[i].game_name[j]; gr_get_string_size (thold,&tx,&ty,&ta); - + if ((x+=tx)>=FSPACX(55)) { GameName[k]=GameName[k+1]=GameName[k+2]='.'; @@ -3112,17 +3100,17 @@ int net_ipx_join_poll( newmenu *menu, d_event *event, void *userdata ) GameName[k++]=Active_ipx_games[i].game_name[j]; } GameName[k]=0; - - + + for (j = 0; j < Active_ipx_games[i].numplayers; j++) if (Active_ipx_games[i].players[j].connected) nplayers++; - + if (Active_ipx_games[i].levelnum < 0) sprintf(levelname, "S%d", -Active_ipx_games[i].levelnum); else sprintf(levelname, "%d", Active_ipx_games[i].levelnum); - + if (game_status == NETSTAT_STARTING) { sprintf (menus[i+2].text,"%d.\t%s \t%s \t %d/%d \t%s \t %s \t%s", @@ -3132,7 +3120,7 @@ int net_ipx_join_poll( newmenu *menu, d_event *event, void *userdata ) else if (game_status == NETSTAT_PLAYING) { join_status=net_ipx_can_join_netgame(&Active_ipx_games[i]); - + if (join_status==1) sprintf (menus[i+2].text,"%d.\t%s \t%s \t %d/%d \t%s \t %s \t%s", i+1,GameName,MODE_NAMES(Active_ipx_games[i].gamemode),nplayers, @@ -3149,23 +3137,105 @@ int net_ipx_join_poll( newmenu *menu, d_event *event, void *userdata ) sprintf (menus[i+2].text,"%d.\t%s \t%s \t %d/%d \t%s \t %s \t%s", i+1,GameName,MODE_NAMES(Active_ipx_games[i].gamemode),nplayers, Active_ipx_games[i].max_numplayers,MissName,levelname,"Closed"); - + } else sprintf (menus[i+2].text,"%d.\t%s \t%s \t %d/%d \t%s \t %s \t%s", i+1,GameName,MODE_NAMES(Active_ipx_games[i].gamemode),nplayers, Active_ipx_games[i].max_numplayers,MissName,levelname,"Between"); - - + + Assert(strlen(menus[i+2].text) < 100); } - + for (i = num_active_ipx_games; i < IPX_MAX_NETGAMES; i++) { sprintf(menus[i+2].text, "%d. ",i+1); } - - return rval; +} + +int net_ipx_do_join_game(int choice); + +int net_ipx_join_poll( newmenu *menu, d_event *event, void *menu_text ) +{ + // Polling loop for Join Game menu + newmenu_item *menus = newmenu_get_items(menu); + int citem = newmenu_get_citem(menu); + int key = 0; + + switch (event->type) + { + case EVENT_KEY_COMMAND: + key = ((d_event_keycommand *)event)->keycode; + + if ( IPX_allow_socket_changes ) { + int osocket; + int rval = 0; + + osocket = IPX_Socket; + + if ( key==KEY_PAGEDOWN ) { IPX_Socket--; rval = 1; } + if ( key==KEY_PAGEUP ) { IPX_Socket++; rval = 1; } + + if (IPX_Socket>99) + IPX_Socket=99; + if (IPX_Socket<-99) + IPX_Socket=-99; + + if ( IPX_Socket+IPX_DEFAULT_SOCKET > 0x8000 ) + IPX_Socket = 0x8000 - IPX_DEFAULT_SOCKET; + + if ( IPX_Socket+IPX_DEFAULT_SOCKET < 0 ) + IPX_Socket = IPX_DEFAULT_SOCKET; + + if (IPX_Socket != osocket ) { + sprintf( menus[0].text, "\t%s %+d (PgUp/PgDn to change)", TXT_CURRENT_IPX_SOCKET, IPX_Socket ); + net_ipx_listen(); + ipxdrv_change_default_socket( IPX_DEFAULT_SOCKET + IPX_Socket ); + restart_net_searching(menus); + net_ipx_send_game_list_request(); + return rval; + } + } + break; + + case EVENT_IDLE: + net_ipx_join_listen(menu); + break; + + case EVENT_NEWMENU_SELECTED: + citem-=2; + + if (citem >=num_active_ipx_games) + { + nm_messagebox(TXT_SORRY, 1, TXT_OK, TXT_INVALID_CHOICE); + return 1; + } + + if (net_ipx_show_game_stats(citem)==0) + return 1; + + // Choice has been made and looks legit + if (net_ipx_do_join_game(citem)==0) + return 1; + + // look ma, we're in a game!!! + break; + + case EVENT_WINDOW_CLOSE: + SurfingNet=0; + d_free(menu_text); + d_free(menu); + + if (!Game_wind) + Network_status = NETSTAT_MENU; // they cancelled + break; + + default: + break; + } + + return 0; } int @@ -3368,16 +3438,25 @@ int net_ipx_do_join_game(int choice) void net_ipx_join_game() { - int choice, i; - char menu_text[(IPX_MAX_NETGAMES*2)+1][70]; - - newmenu_item m[((IPX_MAX_NETGAMES)*2)+1]; + int i; + char *menu_text; + newmenu_item *m; if ( !IPX_active ) { nm_messagebox(NULL, 1, TXT_OK, TXT_IPX_NOT_FOUND); return; } + + MALLOC(m, newmenu_item, ((IPX_MAX_NETGAMES)*2)+1); + if (!m) + return; + MALLOC(menu_text, char, (((IPX_MAX_NETGAMES)*2)+1)*70); + if (!menu_text) + { + d_free(m); + return; + } net_ipx_init(); @@ -3403,51 +3482,26 @@ void net_ipx_join_game() gr_set_fontcolor(BM_XRGB(15,15,23),-1); - m[0].text = menu_text[0]; + m[0].text = menu_text; m[0].type = NM_TYPE_TEXT; if (IPX_allow_socket_changes) sprintf( m[0].text, "\tCurrent IPX Socket is default %+d (PgUp/PgDn to change)", IPX_Socket ); else strcpy( m[0].text, "" ); //sprintf( m[0].text, "" ); - m[1].text=menu_text[1]; + m[1].text=menu_text + 70*1; m[1].type=NM_TYPE_TEXT; sprintf (m[1].text,"\tGAME \tMODE \t#PLYRS \tMISSION \tLEV \tSTATUS"); for (i = 0; i < IPX_MAX_NETGAMES; i++) { - m[i+2].text = menu_text[i+2]; + m[i+2].text = menu_text + 70*(i+2); m[i+2].type = NM_TYPE_MENU; sprintf(m[i+2].text, "%d. ", i+1); } num_active_ipx_changed = 1; -remenu: SurfingNet=1; - nm_draw_background1(Menu_pcx_name); //load this here so if we abort after loading level, we restore the palette - gr_palette_load(gr_palette); - choice=newmenu_dotiny("NETGAMES", NULL,IPX_MAX_NETGAMES+2, m, net_ipx_join_poll, NULL); - SurfingNet=0; - - if (choice==-1) { - Network_status = NETSTAT_MENU; - return; // they cancelled - } - choice-=2; - - if (choice >=num_active_ipx_games) - { - nm_messagebox(TXT_SORRY, 1, TXT_OK, TXT_INVALID_CHOICE); - goto remenu; - } - - if (net_ipx_show_game_stats(choice)==0) - goto remenu; - - // Choice has been made and looks legit - if (net_ipx_do_join_game(choice)==0) - goto remenu; - - return; // look ma, we're in a game!!! + newmenu_dotiny("NETGAMES", NULL,IPX_MAX_NETGAMES+2, m, net_ipx_join_poll, menu_text); } void net_ipx_leave_game() diff --git a/main/net_ipx.h b/main/net_ipx.h index 90e3fbfb7..94130ce81 100644 --- a/main/net_ipx.h +++ b/main/net_ipx.h @@ -123,7 +123,7 @@ int net_ipx_start_game(); void net_ipx_join_game(); void net_ipx_leave_game(); int net_ipx_endlevel(int *secret); -int net_ipx_endlevel_poll2( newmenu *menu, d_event *event, void *userdata ); +int net_ipx_endlevel_poll2( newmenu *menu, d_event *event, int *secret ); int net_ipx_kmatrix_poll1( newmenu *menu, d_event *event, void *userdata ); int net_ipx_level_sync(); void net_ipx_send_endlevel_packet(); diff --git a/main/newmenu.c b/main/newmenu.c index dfe616260..747556677 100644 --- a/main/newmenu.c +++ b/main/newmenu.c @@ -73,6 +73,7 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. struct newmenu { + window *wind; int x,y,w,h; char *title; char *subtitle; @@ -87,7 +88,7 @@ struct newmenu int is_scroll_box; // Is this a scrolling box? Set to false at init int max_on_menu; int mouse_state, dblclick_flag; - int done; + int leave; // Leave newmenu_doX function void *userdata; // For whatever - like with window system }; @@ -97,7 +98,7 @@ ubyte MenuReordering=0; ubyte SurfingNet=0; static int draw_copyright=0; -int newmenu_do4( char * title, char * subtitle, int nitems, newmenu_item * item, int (*subfunction)(newmenu *menu, d_event *event, void *userdata), void *userdata, int citem, char * filename, int width, int height, int TinyMode ); +newmenu *newmenu_do4( char * title, char * subtitle, int nitems, newmenu_item * item, int (*subfunction)(newmenu *menu, d_event *event, void *userdata), void *userdata, int citem, char * filename, int width, int height, int TinyMode ); void newmenu_close() { if (nm_background.bm_data) @@ -501,10 +502,10 @@ void strip_end_whitespace( char * text ) int newmenu_do( char * title, char * subtitle, int nitems, newmenu_item * item, int (*subfunction)(newmenu *menu, d_event *event, void *userdata), void *userdata ) { - return newmenu_do3( title, subtitle, nitems, item, subfunction, userdata, 0, NULL, -1, -1 ); + return newmenu_do2( title, subtitle, nitems, item, subfunction, userdata, 0, NULL ); } -int newmenu_dotiny( char * title, char * subtitle, int nitems, newmenu_item * item, int (*subfunction)(newmenu *menu, d_event *event, void *userdata), void *userdata ) +newmenu *newmenu_dotiny( char * title, char * subtitle, int nitems, newmenu_item * item, int (*subfunction)(newmenu *menu, d_event *event, void *userdata), void *userdata ) { return newmenu_do4( title, subtitle, nitems, item, subfunction, userdata, 0, NULL, -1, -1, 1 ); } @@ -512,21 +513,46 @@ int newmenu_dotiny( char * title, char * subtitle, int nitems, newmenu_item * it int newmenu_do1( char * title, char * subtitle, int nitems, newmenu_item * item, int (*subfunction)(newmenu *menu, d_event *event, void *userdata), void *userdata, int citem ) { - return newmenu_do3( title, subtitle, nitems, item, subfunction, userdata, citem, NULL, -1, -1 ); + return newmenu_do2( title, subtitle, nitems, item, subfunction, userdata, citem, NULL ); } int newmenu_do2( char * title, char * subtitle, int nitems, newmenu_item * item, int (*subfunction)(newmenu *menu, d_event *event, void *userdata), void *userdata, int citem, char * filename ) { - return newmenu_do3( title, subtitle, nitems, item, subfunction, userdata, citem, filename, -1, -1 ); + newmenu *menu; + window *wind; + int rval = -1; + + menu = newmenu_do3( title, subtitle, nitems, item, subfunction, userdata, citem, filename, -1, -1 ); + + if (!menu) + return -1; + menu->leave = 0; // no leaving this function until we're finished + wind = menu->wind; // avoid dereferencing a freed 'menu' + + // newmenu_do2 and simpler get their own event loop + // This is so the caller doesn't have to provide a callback that responds to EVENT_NEWMENU_SELECTED + while (window_exists(wind)) + { + event_process(); + + if (menu->leave) + { + rval = menu->citem; + if (!window_close(wind)) + menu->leave = 0; // user aborted close + } + } + + return rval; } -int newmenu_do3( char * title, char * subtitle, int nitems, newmenu_item * item, int (*subfunction)(newmenu *menu, d_event *event, void *userdata), void *userdata, int citem, char * filename, int width, int height ) +newmenu *newmenu_do3( char * title, char * subtitle, int nitems, newmenu_item * item, int (*subfunction)(newmenu *menu, d_event *event, void *userdata), void *userdata, int citem, char * filename, int width, int height ) { set_screen_mode(SCREEN_MENU);//hafta set the screen mode before calling or fonts might get changed/freed up if screen res changes return newmenu_do4( title, subtitle, nitems, item, subfunction, userdata, citem, filename, width, height, 0 ); } -int newmenu_do_fixedfont( char * title, char * subtitle, int nitems, newmenu_item * item, int (*subfunction)(newmenu *menu, d_event *event, void *userdata), void *userdata, int citem, char * filename, int width, int height){ +newmenu *newmenu_do_fixedfont( char * title, char * subtitle, int nitems, newmenu_item * item, int (*subfunction)(newmenu *menu, d_event *event, void *userdata), void *userdata, int citem, char * filename, int width, int height){ set_screen_mode(SCREEN_MENU);//hafta set the screen mode before calling or fonts might get changed/freed up if screen res changes return newmenu_do4( title, subtitle, nitems, item, subfunction, userdata, citem, filename, width, height, 0); } @@ -551,6 +577,24 @@ int newmenu_get_citem(newmenu *menu) return menu->citem; } +window *newmenu_get_window(newmenu *menu) +{ + return menu->wind; +} + +// The 'softer' version of window_close, +// this leaves citem alone +int newmenu_close_window(newmenu *menu) +{ + if (!menu->leave) + { + menu->leave = 1; + return 1; + } + + return window_close(newmenu_get_window(menu)); +} + int newmenu_mouse(window *wind, d_event *event, newmenu *menu) { int old_choice, i; @@ -609,7 +653,7 @@ int newmenu_mouse(window *wind, d_event *event, newmenu *menu) if (menu->mouse_state && menu->all_text) { - menu->done = 1; + newmenu_close_window(menu); gr_set_current_canvas(save_canvas); return 1; } @@ -741,7 +785,7 @@ int newmenu_mouse(window *wind, d_event *event, newmenu *menu) if (menu->subfunction && (*menu->subfunction)(menu, event, menu->userdata)) return 1; - menu->done = 1; + newmenu_close_window(menu); gr_set_current_canvas(save_canvas); return 1; } @@ -754,7 +798,7 @@ int newmenu_mouse(window *wind, d_event *event, newmenu *menu) if (menu->subfunction && (*menu->subfunction)(menu, event, menu->userdata)) return 1; - menu->done = 1; + newmenu_close_window(menu); gr_set_current_canvas(save_canvas); return 1; } @@ -970,7 +1014,7 @@ int newmenu_key_command(window *wind, d_event *event, newmenu *menu) if (menu->subfunction && (*menu->subfunction)(menu, event, menu->userdata)) return 1; - menu->done = 1; + newmenu_close_window(menu); return 1; } break; @@ -981,8 +1025,8 @@ int newmenu_key_command(window *wind, d_event *event, newmenu *menu) strcpy(item->text, item->saved_text ); item->value = -1; } else { - menu->done = 1; menu->citem = -1; + newmenu_close_window(menu); return 1; } break; @@ -1232,7 +1276,7 @@ int newmenu_handler(window *wind, d_event *event, newmenu *menu) if (rval < -1) { menu->citem = rval; - menu->done = 1; + newmenu_close_window(menu); } return 1; // event handled @@ -1274,11 +1318,11 @@ int newmenu_handler(window *wind, d_event *event, newmenu *menu) break; case EVENT_WINDOW_CLOSE: - if (!menu->done) + if (!menu->leave) { menu->citem = -1; - menu->done = 1; - return 1; // cancel close and do it in newmenu_do4 instead + menu->leave = 1; + return 1; // cancel close and do it in newmenu_do2 instead } d_free(menu); @@ -1291,7 +1335,7 @@ int newmenu_handler(window *wind, d_event *event, newmenu *menu) return 0; } -int newmenu_do4( char * title, char * subtitle, int nitems, newmenu_item * item, int (*subfunction)(newmenu *menu, d_event *event, void *userdata), void *userdata, int citem, char * filename, int width, int height, int TinyMode ) +newmenu *newmenu_do4( char * title, char * subtitle, int nitems, newmenu_item * item, int (*subfunction)(newmenu *menu, d_event *event, void *userdata), void *userdata, int citem, char * filename, int width, int height, int TinyMode ) { window *wind = NULL; newmenu *menu; @@ -1300,13 +1344,11 @@ int newmenu_do4( char * title, char * subtitle, int nitems, newmenu_item * item, grs_font * save_font; int string_width, string_height, average_width; grs_canvas *menu_canvas, *save_canvas; - int rval = -1; - int done = 0; MALLOC(menu, newmenu, 1); if (!menu) - return -1; + return NULL; memset(menu, 0, sizeof(newmenu)); menu->citem = citem; @@ -1323,7 +1365,7 @@ int newmenu_do4( char * title, char * subtitle, int nitems, newmenu_item * item, menu->items = item; menu->filename = filename; menu->tiny_mode = TinyMode; - menu->done = 0; + menu->leave = 1; // Default to leaving newmenu_doX function menu->userdata = userdata; newmenu_close(); @@ -1331,7 +1373,7 @@ int newmenu_do4( char * title, char * subtitle, int nitems, newmenu_item * item, if (nitems < 1 ) { d_free(menu); - return -1; + return NULL; } menu->max_displayable=nitems; @@ -1514,9 +1556,10 @@ int newmenu_do4( char * title, char * subtitle, int nitems, newmenu_item * item, { d_free(menu); - return -1; + return NULL; } + menu->wind = wind; menu_canvas = window_get_canvas(wind); gr_set_curfont(save_font); gr_set_current_canvas(menu_canvas); @@ -1568,23 +1611,8 @@ int newmenu_do4( char * title, char * subtitle, int nitems, newmenu_item * item, menu->mouse_state = 0; gr_set_current_canvas(save_canvas); - - // All newmenus get their own event loop, for now. - while (!done) - { - event_process(); - - if (menu->done) - { - rval = menu->citem; - if (!window_close(wind)) - menu->done = 0; // user aborted close - else - done = 1; - } - } - - return rval; + + return menu; } @@ -2037,7 +2065,7 @@ listbox *newmenu_listbox1( char * title, int nitems, char * items[], int allow_a } //added on 10/14/98 by Victor Rachels to attempt a fixedwidth font messagebox -int nm_messagebox_fixedfont( char *title, int nchoices, ... ) +newmenu *nm_messagebox_fixedfont( char *title, int nchoices, ... ) { int i; char * format; diff --git a/main/newmenu.h b/main/newmenu.h index 4849b4333..813decae0 100644 --- a/main/newmenu.h +++ b/main/newmenu.h @@ -76,10 +76,10 @@ extern int newmenu_do1(char *title, char *subtitle, int nitems, newmenu_item *it extern int newmenu_do2(char *title, char *subtitle, int nitems, newmenu_item *item, int (*subfunction)(newmenu *menu, d_event *event, void *userdata), void *userdata, int citem, char *filename); // Same as above, only you can pass through the width and height -extern int newmenu_do3(char *title, char *subtitle, int nitems, newmenu_item *item, int (*subfunction)(newmenu *menu, d_event *event, void *userdata), void *userdata, int citem, char *filename, int width, int height); +extern newmenu *newmenu_do3(char *title, char *subtitle, int nitems, newmenu_item *item, int (*subfunction)(newmenu *menu, d_event *event, void *userdata), void *userdata, int citem, char *filename, int width, int height); // Tiny menu with GAME_FONT -extern int newmenu_dotiny(char * title, char * subtitle, int nitems, newmenu_item * item, int (*subfunction)(newmenu *menu, d_event *event, void *userdata), void *userdata); +extern newmenu *newmenu_dotiny(char * title, char * subtitle, int nitems, newmenu_item * item, int (*subfunction)(newmenu *menu, d_event *event, void *userdata), void *userdata); // Sample Code: /* @@ -115,6 +115,7 @@ int nm_messagebox1(char *title, int (*subfunction)(newmenu *menu, d_event *event newmenu_item *newmenu_get_items(newmenu *menu); int newmenu_get_nitems(newmenu *menu); int newmenu_get_citem(newmenu *menu); +struct window *newmenu_get_window(newmenu *menu); void nm_draw_background(int x1, int y1, int x2, int y2); void nm_restore_background(int x, int y, int w, int h); @@ -150,7 +151,7 @@ extern listbox *newmenu_listbox(char *title, int nitems, char *items[], int allo 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, ...); +newmenu *nm_messagebox_fixedfont(char *title, int nchoices, ...); //end this section addition //should be called whenever the palette changes diff --git a/main/state.c b/main/state.c index 3e00f7008..4e3aa83bd 100644 --- a/main/state.c +++ b/main/state.c @@ -221,7 +221,7 @@ int state_get_savegame_filename(char * fname, char * dsc, char * caption, int bl if (blind_save) choice = state_default_item + 1; else - choice = newmenu_do3( NULL, caption, NUM_SAVES+1, m, (int (*)(newmenu *, d_event *, void *))state_callback, sc_bmp, state_default_item + 1, NULL, -1, -1 ); + choice = newmenu_do2( NULL, caption, NUM_SAVES+1, m, (int (*)(newmenu *, d_event *, void *))state_callback, sc_bmp, state_default_item + 1, NULL ); for (i=0; i