]> icculus.org git repositories - taylor/freespace2.git/blob - src/popup/popupdead.cpp
SDL2 port - stage 2
[taylor/freespace2.git] / src / popup / popupdead.cpp
1 /*
2  * Copyright (C) Volition, Inc. 1999.  All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell 
5  * or otherwise commercially exploit the source or things you created based on
6  * the source.
7  */
8
9 /*
10  * $Logfile: /Freespace2/code/Popup/PopupDead.cpp $
11  * $Revision$
12  * $Date$
13  * $Author$
14  *
15  * C module for the death popup
16  *
17  * $Log$
18  * Revision 1.4  2003/05/25 02:30:43  taylor
19  * Freespace 1 support
20  *
21  * Revision 1.3  2002/06/09 04:41:25  relnev
22  * added copyright header
23  *
24  * Revision 1.2  2002/05/07 03:16:51  theoddone33
25  * The Great Newline Fix
26  *
27  * Revision 1.1.1.1  2002/05/03 03:28:10  root
28  * Initial import.
29  *
30  * 
31  * 14    9/14/99 4:35a Dave
32  * Argh. Added all kinds of code to handle potential crashes in debriefing
33  * code.
34  * 
35  * 13    9/14/99 12:51a Jefff
36  * sm3-09 no skip hack.
37  * 
38  * 12    9/11/99 1:09a Mikek
39  * Removed semi-bogus Int3() in popupdead code which seemed to get tripped
40  * by the supernova.
41  * 
42  * 11    9/10/99 6:49p Jefff
43  * changed skip popup to normal type popup
44  * 
45  * 10    9/09/99 7:17p Jefff
46  * 
47  * 9     9/07/99 4:44p Jefff
48  * fixed double counting of mission failures
49  * 
50  * 8     9/07/99 1:54p Jefff
51  * skip mission cleanup
52  * 
53  * 7     9/06/99 9:46p Jefff
54  * skip mission support
55  * 
56  * 6     8/11/99 5:47p Jefff
57  * fixed button bitmap loading
58  * 
59  * 5     7/24/99 1:54p Dave
60  * Hud text flash gauge. Reworked dead popup to use 4 buttons in red-alert
61  * missions.
62  * 
63  * 4     6/01/99 3:52p Dave
64  * View footage screen. Fixed xstrings to not display the & symbol. Popup,
65  * dead popup, pxo find player popup, pxo private room popup.
66  * 
67  * 3     10/13/98 9:29a Dave
68  * Started neatening up freespace.h. Many variables renamed and
69  * reorganized. Added AlphaColors.[h,cpp]
70  * 
71  * 2     10/07/98 10:53a Dave
72  * Initial checkin.
73  * 
74  * 1     10/07/98 10:51a Dave
75  * 
76  * 11    6/09/98 10:31a Hoffoss
77  * Created index numbers for all xstr() references.  Any new xstr() stuff
78  * added from here on out should be added to the end if the list.  The
79  * current list count can be found in FreeSpace.cpp (search for
80  * XSTR_SIZE).
81  * 
82  * 10    5/17/98 1:43a Dave
83  * Eradicated chatbox problems. Remove speed match for observers. Put in
84  * help screens for PXO. Fix messaging and end mission privelges. Fixed
85  * team select screen bugs. Misc UI fixes.
86  * 
87  * 9     5/01/98 4:24p Lawrance
88  * Change "Main Hall" to "Flight Deck"
89  * 
90  * 8     4/22/98 4:59p Allender
91  * new multiplayer dead popup.  big changes to the comm menu system for
92  * team vs. team.  Start of debriefing stuff for team vs. team  Make form
93  * on my wing work with individual ships who have high priority orders
94  * 
95  * 7     3/12/98 4:02p Lawrance
96  * Cleanup how pause works, fix couple pause-related bugs.
97  * 
98  * 6     3/05/98 12:35p Lawrance
99  * Fix bug where two options could be highlighted at once.
100  * 
101  * 5     2/22/98 4:30p John
102  * More string externalization classification
103  * 
104  * 4     2/22/98 2:48p John
105  * More String Externalization Classification
106  * 
107  * 3     2/22/98 12:19p John
108  * Externalized some strings
109  * 
110  * 2     2/10/98 11:20p Lawrance
111  * Implement separate dead popup system
112  * 
113  * 1     2/10/98 6:02p Lawrance
114  *
115  * $NoKeywords: $
116  */
117
118
119 #define POPUPDEAD_NUM_CHOICES                           3               // normal
120 #ifdef MAKE_FS1
121 #define POPUPDEAD_NUM_CHOICES_RA                        3               // Theres on 3 possible in FS1
122 #else
123 #define POPUPDEAD_NUM_CHOICES_RA                        4               // red alert
124 #endif
125 #define POPUPDEAD_NUM_CHOICES_SKIP              3               // skip mission menu
126
127 #ifdef MAKE_FS1
128 #define POPUPDEAD_NUM_CHOICES_MAX               3
129 #else
130 #define POPUPDEAD_NUM_CHOICES_MAX               4
131 #endif
132
133 #include "ui.h"
134 #include "key.h"
135 #include "mouse.h"
136 #include "freespace.h"
137 #include "gamesnd.h"
138 #include "keycontrol.h"
139 #include "player.h"
140 #include "multi.h"
141 #include "multiutil.h"
142 #include "popupdead.h"
143 #include "alphacolors.h"
144 #include "gamesequence.h"
145 #include "popup.h"
146
147 UI_WINDOW       Popupdead_window;
148 UI_BUTTON       Popupdead_buttons[POPUPDEAD_NUM_CHOICES_MAX];                           // actual lit buttons
149 UI_BUTTON       Popupdead_button_regions[POPUPDEAD_NUM_CHOICES_MAX];    // fake buttons used for mouse detection over text
150
151 int Popupdead_region_coords[GR_NUM_RESOLUTIONS][POPUPDEAD_NUM_CHOICES_MAX][4] =
152 {       
153         {       // GR_640
154 #ifdef MAKE_FS1
155                 {464, 402, 505, 421},           // upper right pixel of text, lower right pixel of button (for tiny popup)
156                 {464, 422, 505, 442},
157                 {464, 442, 505, 462},
158 #else
159                 {464, 389, 497, 403},           // upper right pixel of text, lower right pixel of button (for tiny popup)
160                 {464, 413, 497, 427},
161                 {464, 435, 497, 446},           
162                 {464, 457, 497, 466},
163 #endif
164         }, 
165         {       // GR_1024
166                 {745, 627, 809, 664},
167                 {745, 663, 809, 700},           // upper right pixel of text, lower right pixel of button (for tiny popup)
168                 {745, 699, 809, 736},           
169 #ifndef MAKE_FS1
170                 {745, 735, 809, 772},
171 #endif
172         }, 
173 };
174
175 int Popupdead_button_coords[GR_NUM_RESOLUTIONS][POPUPDEAD_NUM_CHOICES_MAX][2] =
176 {
177         {       // GR_640
178 #ifdef MAKE_FS1
179                 {474, 394},             // upper left pixel (tiny popup)
180                 {474, 415},
181                 {474, 435},
182 #else
183                 {478, 387},                                             // upper left pixel (tiny popup)
184                 {478, 410},
185                 {478, 432},
186                 {478, 455},
187 #endif
188         },
189         {       // GR_1024
190                 {760, 620},                                             // upper left pixel (tiny popup)
191                 {760, 656},
192                 {760, 692},
193 #ifndef MAKE_FS1
194                 {760, 728},
195 #endif
196         }
197 };
198
199 const char *Popupdead_background_filename[GR_NUM_RESOLUTIONS] = {
200         "PopDeath",             // GR_640
201         "2_PopDeath"    // GR-1024
202 };
203
204 int Popupdead_background_coords[GR_NUM_RESOLUTIONS][2] = 
205 {
206         { // GR_640
207                 131, 363
208         },
209         { // GR_1024
210                 205, 581
211         }
212 };
213
214 const char *Popupdead_button_filenames[GR_NUM_RESOLUTIONS][POPUPDEAD_NUM_CHOICES_MAX] = 
215 {
216         {       // GR_640
217                 "PopD_00",                              // first choice
218                 "PopD_01",                              // second choice
219                 "PopD_02",                              // third choice
220 #ifndef MAKE_FS1
221                 "PopD_03",                              // fourth choice
222 #endif
223         },
224         {       // GR_1024
225                 "2_PopD_00",                    // first choice
226                 "2_PopD_01",                    // second choice
227                 "2_PopD_02",                    // third choice
228 #ifndef MAKE_FS1
229                 "2_PopD_03",                    // fourth choice
230 #endif
231         }
232 };
233
234 int Popupdead_skip_message_y[GR_NUM_RESOLUTIONS] = { 
235                 96,     // GR_640
236                 160
237 };
238
239
240 static const char *Popupdead_button_text[POPUPDEAD_NUM_CHOICES_MAX];
241
242 // multiplayer specifics to help with return values since they can vary
243 #define POPUPDEAD_OBS_ONLY                      1
244 #define POPUPDEAD_OBS_QUIT                      2
245 #define POPUPDEAD_RESPAWN_ONLY  3
246 #define POPUPDEAD_RESPAWN_QUIT  4
247
248 int Popupdead_default_choice;           // What the default choice is (ie activated when Enter pressed)
249 int Popupdead_active    =       0;                      // A dead popup is active
250 int Popupdead_choice;                           // Index for choice picked (-1 if none picked)
251 int Popupdead_num_choices;                      // number of buttons
252 int Popupdead_multi_type;                       // what kind of popup is active for muliplayer
253 int Popupdead_skip_active = 0;  // The skip-misison popup is active
254 int Popupdead_skip_already_shown = 0;
255
256 // Initialize the dead popup data
257 void popupdead_start()
258 {
259         int                     i;
260         UI_BUTTON       *b;
261
262         if ( Popupdead_active ) {
263                 // Int3();
264                 return;
265         }
266
267         // increment number of deaths
268         Player->failures_this_session++;
269
270
271         // create base window
272         Popupdead_window.create(Popupdead_background_coords[gr_screen.res][0], Popupdead_background_coords[gr_screen.res][1], 1, 1, 0);
273         Popupdead_window.set_foreground_bmap(Popupdead_background_filename[gr_screen.res]);
274
275         Popupdead_num_choices = 0;
276         Popupdead_multi_type = -1;
277
278         if ( Game_mode & GM_NORMAL ) {
279                 // also do a campaign check here?
280                 if (0) { //((Player->show_skip_popup) && (!Popupdead_skip_already_shown) && (Game_mode & GM_CAMPAIGN_MODE) && (Game_mode & GM_NORMAL) && (Player->failures_this_session >= PLAYER_MISSION_FAILURE_LIMIT)) {
281                         // init the special preliminary death popup that gives the skip option
282                         Popupdead_button_text[0] = XSTR( "Do Not Skip This Mission", 1473);
283                         Popupdead_button_text[1] = XSTR( "Advance To The Next Mission", 1474);
284                         Popupdead_button_text[2] = XSTR( "Don't Show Me This Again", 1475);
285                         Popupdead_num_choices = POPUPDEAD_NUM_CHOICES_SKIP;
286                         Popupdead_skip_active = 1;
287                 } else if(The_mission.red_alert) {
288                         // We can't staticly declare these because they are externalized
289                         Popupdead_button_text[0] = XSTR( "Quick Start Mission", 105);
290                         Popupdead_button_text[1] = XSTR( "Return To Flight Deck", 106);
291                         Popupdead_button_text[2] = XSTR( "Return To Briefing", 107);
292 #ifndef MAKE_FS1
293                         Popupdead_button_text[3] = XSTR( "Replay previous mission", 1432);
294 #endif
295                         Popupdead_num_choices = POPUPDEAD_NUM_CHOICES_RA;
296                 } else {
297                         Popupdead_button_text[0] = XSTR( "Quick Start Mission", 105);
298                         Popupdead_button_text[1] = XSTR( "Return To Flight Deck", 106);
299                         Popupdead_button_text[2] = XSTR( "Return To Briefing", 107);
300                         Popupdead_num_choices = POPUPDEAD_NUM_CHOICES;
301                 }
302         } else {
303                 // in multiplayer, we have different choices depending on respawn mode, etc.
304
305                 // if the player has run out of respawns and must either quit and become an observer
306                 if(Net_player->flags & NETINFO_FLAG_LIMBO){
307
308                         // the master should not be able to quit the game
309                         if( ((Net_player->flags & NETINFO_FLAG_AM_MASTER) && (multi_num_players() > 1)) || (Net_player->flags & NETINFO_FLAG_TEAM_CAPTAIN) ) {
310                                 Popupdead_button_text[0] = XSTR( "Observer Mode", 108);
311                                 Popupdead_num_choices = 1;
312                                 Popupdead_multi_type = POPUPDEAD_OBS_ONLY;
313                         } else {
314                                 Popupdead_button_text[0] = XSTR( "Observer Mode", 108);
315                                 Popupdead_button_text[1] = XSTR( "Return To Flight Deck", 106);
316                                 Popupdead_num_choices = 2;
317                                 Popupdead_multi_type = POPUPDEAD_OBS_QUIT;
318                         }
319                 } else {
320                         // the master of the game should not be allowed to quit
321                         if ( ((Net_player->flags & NETINFO_FLAG_AM_MASTER) && (multi_num_players() > 1)) || (Net_player->flags & NETINFO_FLAG_TEAM_CAPTAIN) ) {
322                                 Popupdead_button_text[0] = XSTR( "Respawn", 109);
323                                 Popupdead_num_choices = 1;
324                                 Popupdead_multi_type = POPUPDEAD_RESPAWN_ONLY;
325                         } else {
326                                 Popupdead_button_text[0] = XSTR( "Respawn", 109);
327                                 Popupdead_button_text[1] = XSTR( "Return To Flight Deck", 106);
328                                 Popupdead_num_choices = 2;
329                                 Popupdead_multi_type = POPUPDEAD_RESPAWN_QUIT;
330                         }
331                 }
332         }
333
334         // create buttons
335         for (i=0; i < Popupdead_num_choices; i++) {
336                 b = &Popupdead_buttons[i];
337                 b->create(&Popupdead_window, "", Popupdead_button_coords[gr_screen.res][i][0], Popupdead_button_coords[gr_screen.res][i][1], 30, 20, 0, 1);
338                 b->set_bmaps(Popupdead_button_filenames[gr_screen.res][i], 3, 0);
339                 b->set_highlight_action(common_play_highlight_sound);
340
341                 // create invisible buttons to detect mouse presses... can't use mask since button region is dynamically sized
342                 int lx, w, h;
343                 gr_get_string_size(&w, &h, Popupdead_button_text[i]);
344                 lx = Popupdead_region_coords[gr_screen.res][i][0] - w;
345                 b = &Popupdead_button_regions[i];       
346                 b->create(&Popupdead_window, "", lx, Popupdead_region_coords[gr_screen.res][i][1], Popupdead_region_coords[gr_screen.res][i][2]-lx, Popupdead_region_coords[gr_screen.res][i][3]-Popupdead_region_coords[gr_screen.res][i][1], 0, 1);
347                 b->hide();
348         }
349         
350         Popupdead_default_choice = 0;
351         Popupdead_choice = -1;
352         Popupdead_active = 1;
353 }
354
355 // maybe play a sound when key up/down is pressed to switch default choice
356 void popupdead_play_default_change_sound()
357 {
358         int i, mouse_over=0;
359         UI_BUTTON *br, *b;
360
361         // only play if mouse not currently highlighting a choice
362         for ( i = 0; i < Popupdead_num_choices; i++ ) {
363                 br = &Popupdead_button_regions[i];
364                 b = &Popupdead_buttons[i];
365                 if ( br->button_down() ) {
366                         mouse_over=1;
367                         break;
368                 }
369
370                 if ( br->button_hilighted() && !b->button_down() ) {
371                         mouse_over=1;
372                         break;
373                 }
374
375                 if ( b->button_hilighted() ) {
376                         mouse_over=1;
377                 }
378         }
379
380         if (!mouse_over) {
381                 gamesnd_play_iface(SND_USER_SELECT);
382         }
383 }
384
385 // do any key processing here
386 // exit:        -1              =>      nothing was done
387 //                      >=0     => a choice was selected
388 int popupdead_process_keys(int k)
389 {
390         int masked_k;
391
392         if ( k <= 0 ) {
393                 return -1;
394         }
395         
396         switch(k) {
397
398         case SDLK_RETURN:
399                 return Popupdead_default_choice;        // select the current default choice
400                 break;
401
402         case SDLK_ESCAPE:
403                 if (Popupdead_skip_active) {
404                         return 0;                                                               // 0 mimics a "do not skip"
405                 } else {
406                         return 1;                                                               // do nothing here for now - 1 mimics a "return to flight deck"
407                 }
408                 break;
409
410         case SDLK_DOWN:
411         case SDLK_KP_2:
412         case SDLK_TAB:
413                 popupdead_play_default_change_sound();
414                 Popupdead_default_choice++;
415                 if ( Popupdead_default_choice >= Popupdead_num_choices ) {
416                         Popupdead_default_choice=0;
417                 }
418                 break;
419
420         case SDLK_UP:
421         case SDLK_KP_8:
422         case KEY_SHIFTED+SDLK_TAB:
423                 popupdead_play_default_change_sound();
424                 Popupdead_default_choice--;
425                 if ( Popupdead_default_choice < 0 ) {
426                         Popupdead_default_choice=Popupdead_num_choices-1;
427                 }
428                 break;
429
430         case SDLK_PAUSE:
431                 game_process_pause_key();
432                 break;
433
434         default:
435                 break;
436         } // end switch
437
438         // read the dead key set
439         masked_k = k & ~KEY_CTRLED;     // take out CTRL modifier only
440         process_set_of_keys(masked_k, Dead_key_set_size, Dead_key_set);
441         button_info_do(&Player->bi);    // call functions based on status of button_info bit vectors
442
443         return -1;
444 }
445
446
447 // see if any popup buttons have been pressed
448 // exit: -1                                             => no buttons pressed
449 //                      >=0                                     =>      button index that was pressed
450 int popupdead_check_buttons()
451 {
452         int                     i;
453         UI_BUTTON       *b;
454
455         for ( i = 0; i < Popupdead_num_choices; i++ ) {
456                 b = &Popupdead_button_regions[i];
457                 if ( b->pressed() ) {
458                         return i;
459                 }
460
461                 b = &Popupdead_buttons[i];
462                 if ( b->pressed() ) {
463                         return i;
464                 }
465         }
466
467         return -1;
468 }
469
470 // See if any of the button should change appearance based on mouse position
471 void popupdead_force_draw_buttons()
472 {
473         int i,mouse_is_highlighting=0;
474         UI_BUTTON *br, *b;
475
476         for ( i = 0; i < Popupdead_num_choices; i++ ) {
477                 br = &Popupdead_button_regions[i];
478                 b = &Popupdead_buttons[i];
479                 if ( br->button_down() ) {
480                         b->draw_forced(2);
481                         mouse_is_highlighting=1;
482                         continue;
483                 }
484
485                 if ( (b->button_hilighted()) || (br->button_hilighted() && !b->button_down()) ) {
486                         Popupdead_default_choice=i;
487                         mouse_is_highlighting=1;
488                         b->draw_forced(1);
489                 }
490         }
491
492         // Only if mouse is not highlighting an option, let the default choice be drawn highlighted
493         if ( (!mouse_is_highlighting) && (Popupdead_num_choices>1) ) {
494                 for ( i = 0; i < Popupdead_num_choices; i++ ) {
495                         b = &Popupdead_buttons[i];
496                         // highlight the default choice
497                         if ( i == Popupdead_default_choice ) {
498                                 b->draw_forced(1);
499                         }
500                 }
501         }
502 }
503
504 // Draw the button text nicely formatted in the popup
505 void popupdead_draw_button_text()
506 {
507         int w,h,i,sx,sy;
508
509         gr_set_color_fast(&Color_bright_blue);
510
511         for ( i=0; i < Popupdead_num_choices; i++ ) {
512                 gr_get_string_size(&w, &h, Popupdead_button_text[i]);
513                 sx = Popupdead_region_coords[gr_screen.res][i][0]-w;
514                 sy = Popupdead_region_coords[gr_screen.res][i][1]+4;
515                 gr_string(sx, sy, Popupdead_button_text[i]);
516         }
517 }
518
519 // reinits the death popup
520 // used for skip popup to death popup transition
521 void popupdead_restart() {
522         Popupdead_skip_already_shown = 1;
523         Popupdead_skip_active = 0;
524         Popupdead_active = 0;
525         Player->failures_this_session--;                // hacky correction for a double count when calling popupdead_start() twice
526         popupdead_start();
527 }
528
529 // do the "skip mission" version of the death popup
530 int popupdead_skip_do_frame()
531 {
532         int k = Popupdead_window.process();
533
534         // check for input
535         int choice = popupdead_process_keys(k);
536         if (choice < 0) {
537                 choice = popupdead_check_buttons();
538         }
539
540         // take appropriate options
541         switch (choice) {
542         case 0:
543                 // try this mission again, so proceed to normal death popup
544                 gamesnd_play_iface(SND_USER_SELECT);
545                 popupdead_restart();
546                 break;
547         case 1:
548                 // skip this mission
549                 mission_campaign_skip_to_next();
550
551                 gamesnd_play_iface(SND_USER_SELECT);
552                 break;
553         case 2:
554                 // dont show this again
555                 Player->show_skip_popup = 0;
556                 
557                 gamesnd_play_iface(SND_USER_SELECT);
558                 popupdead_restart();
559                 break;
560         }
561
562         // render
563         Popupdead_window.draw();
564         popupdead_force_draw_buttons();
565         popupdead_draw_button_text();
566
567         // render skip mission message
568         gr_set_color_fast(&Color_bright_white);
569         gr_string(0x8000, Popupdead_skip_message_y[gr_screen.res], XSTR("You have failed this mission five times.", 1470));
570         gr_string(0x8000, Popupdead_skip_message_y[gr_screen.res] + gr_get_font_height(), XSTR("If you like, you may advance to the next mission.", 1471));
571
572         return choice;
573 }
574
575
576 // Called once per frame to run the dead popup
577 int popupdead_do_frame(float frametime)
578 {
579         int k, choice;
580
581 /*
582         if (Popupdead_skip_active) {
583                 // do the skip mission popup, and thats all
584                 if (popupdead_skip_do_frame() == 1) {
585                         return 2;       // fake the "go to briefing" choice
586                 } else {
587                         return -1;      // fake no choice
588                 }
589         }
590 */
591         if ( !Popupdead_active ) {
592                 return -1;
593         }
594
595         // dont let dude skip 3-09.  hack.
596         if(Game_mode & GM_CAMPAIGN_MODE){
597                 if((Campaign.current_mission >= 0) && (Campaign.current_mission < MAX_CAMPAIGN_MISSIONS)){
598                         if ((Campaign.missions[Campaign.current_mission].name != NULL) && !stricmp(Campaign.missions[Campaign.current_mission].name, "sm3-09.fs2")) {
599                                 Popupdead_skip_already_shown = 1;
600                         }
601                 }
602         }
603
604         // maybe show skip mission popup
605         if ((!Popupdead_skip_already_shown) && (Player->show_skip_popup) && (Game_mode & GM_NORMAL) && (Game_mode & GM_CAMPAIGN_MODE) && (Player->failures_this_session >= PLAYER_MISSION_FAILURE_LIMIT)) {
606                 int popup_choice = popup(0, 3, XSTR("Do Not Skip This Mission", 1473),
607                                                                                                  XSTR("Advance To The Next Mission", 1474),
608                                                                                                  XSTR("Don't Show Me This Again", 1475),
609                                                                                                  XSTR("You have failed this mission five times.  If you like, you may advance to the next mission.", 1472) );
610                 switch (popup_choice) {
611                 case 0:
612                         // stay on this mission, so proceed to normal death popup
613                         // in other words, do nothing.
614                         break;
615                 case 1:
616                         // skip this mission
617                         Popupdead_active = 0;
618                         mission_campaign_skip_to_next();
619                         gameseq_post_event(GS_EVENT_START_GAME);
620                         return -1;
621                 case 2:
622                         // dont show this again
623                         Player->show_skip_popup = 0;
624                         break;
625                 }
626
627                 Popupdead_skip_already_shown = 1;
628         }
629
630         
631         k = Popupdead_window.process();
632
633         choice = popupdead_process_keys(k);
634         if ( choice >= 0 ) {
635                 // do something different for single/multiplayer
636                 if ( Game_mode & GM_NORMAL ) {
637                         Popupdead_choice=choice;
638                 } else {
639                         Assert( Popupdead_multi_type != -1 );
640                         switch ( Popupdead_multi_type ) {
641                                 
642                         case POPUPDEAD_OBS_ONLY:
643                         case POPUPDEAD_OBS_QUIT:
644                                 Popupdead_choice = POPUPDEAD_DO_OBSERVER;
645                                 if ( (Popupdead_multi_type == POPUPDEAD_OBS_QUIT) && (choice == 1) )
646                                         Popupdead_choice = POPUPDEAD_DO_MAIN_HALL;
647                                 break;
648
649                         case POPUPDEAD_RESPAWN_ONLY:
650                         case POPUPDEAD_RESPAWN_QUIT:
651                                 Popupdead_choice = POPUPDEAD_DO_RESPAWN;
652                                 if ( (Popupdead_multi_type == POPUPDEAD_RESPAWN_QUIT) && (choice == 1) )
653                                         Popupdead_choice = POPUPDEAD_DO_MAIN_HALL;
654                                 break;
655
656                         default:
657                                 Int3();
658                                 break;
659                         }
660                 }
661         }
662
663         choice = popupdead_check_buttons();
664         if ( choice >= 0 ) {
665                 // do something different for single/multiplayer
666                 if ( Game_mode & GM_NORMAL ) {
667                         Popupdead_choice=choice;
668                 } else {
669                         Assert( Popupdead_multi_type != -1 );
670                         switch ( Popupdead_multi_type ) {
671                                 
672                         case POPUPDEAD_OBS_ONLY:
673                         case POPUPDEAD_OBS_QUIT:
674                                 Popupdead_choice = POPUPDEAD_DO_OBSERVER;
675                                 if ( (Popupdead_multi_type == POPUPDEAD_OBS_QUIT) && (choice == 1) )
676                                         Popupdead_choice = POPUPDEAD_DO_MAIN_HALL;
677                                 break;
678
679                         case POPUPDEAD_RESPAWN_ONLY:
680                         case POPUPDEAD_RESPAWN_QUIT:
681                                 Popupdead_choice = POPUPDEAD_DO_RESPAWN;
682                                 if ( (Popupdead_multi_type == POPUPDEAD_RESPAWN_QUIT) && (choice == 1) )
683                                         Popupdead_choice = POPUPDEAD_DO_MAIN_HALL;
684                                 break;
685
686                         default:
687                                 Int3();
688                                 break;
689                         }
690                 }
691         }
692
693         Popupdead_window.draw();
694         popupdead_force_draw_buttons();
695         popupdead_draw_button_text();
696
697         return Popupdead_choice;
698 }
699
700 // Close down the dead popup
701 void popupdead_close()
702 {
703         if ( !Popupdead_active ) {
704                 return;
705         }
706
707         gamesnd_play_iface(SND_POPUP_DISAPPEAR);
708         Popupdead_window.destroy();
709         game_flush();
710
711         Popupdead_active = 0;
712         Popupdead_skip_active = 0;
713         Popupdead_skip_already_shown = 0;
714 }
715
716 // Is there a dead popup active?
717 int popupdead_is_active()
718 {
719         return Popupdead_active;
720
721