FS2_Open
Open source remastering of the Freespace 2 engine
multi_pause.cpp
Go to the documentation of this file.
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 the
6  * source.
7  *
8 */
9 
10 
11 
12 
13 #include "network/multi_pause.h"
14 #include "missionui/chatbox.h"
15 #include "io/key.h"
16 #include "popup/popup.h"
18 #include "network/stand_gui.h"
19 #include "gamesnd/gamesnd.h"
20 #include "network/multiutil.h"
21 #include "network/multiui.h"
22 #include "network/multimsgs.h"
23 #include "network/multi_endgame.h"
24 #include "network/multi_pmsg.h"
25 #include "playerman/player.h"
26 #include "network/multi.h"
27 #include "globalincs/alphacolors.h"
28 #include "io/timer.h"
29 
30 
31 
32 // ----------------------------------------------------------------------------------
33 // PAUSE DEFINES/VARS
34 //
35 
36 // state of the game (paused or not) on _my_ machine. Obviously this is important for the server
37 // call multi_pause_reset() to reinitialize
39 
40 // who paused the game
42 
43 // timestamp for eating keypresses for a while after
44 float Multi_pause_eat = -1.0f;
45 
46 // pause ui screen stuff
47 #define MULTI_PAUSED_NUM_BUTTONS 3
48 
49 // button defs
50 #define MP_SCROLL_UP 0
51 #define MP_SCROLL_DOWN 1
52 #define MP_EXIT_MISSION 2
53 
55  "MPPause",
56  "2_MPPause"
57 };
58 
60  "MPPause-m",
61  "2_MPPause-m"
62 };
63 
64 // where to place the pauser's callsign
66  { // GR_640
67  110, 132
68  },
69  { // GR_1024
70  171, 218
71  }
72 };
73 
75  { // GR_640
76  ui_button_info("PB00", 519, 212, -1, -1, 0),
77  ui_button_info("PB01", 519, 252, -1, -1, 1),
78  ui_button_info("PB02", 488, 321, -1, -1, 2),
79  },
80  { // GR_1024
81  ui_button_info("2_PB00", 831, 339, -1, -1, 0),
82  ui_button_info("2_PB01", 831, 403, -1, -1, 1),
83  ui_button_info("2_PB02", 781, 514, -1, -1, 2),
84  }
85 };
86 
87 // text
88 #define MULTI_PAUSED_NUM_TEXT 3
90  { // GR_640
91  { "Exit", 1059, 493, 297, UI_XSTR_COLOR_PINK, -1, &Multi_paused_buttons[0][MP_EXIT_MISSION].button },
92  { "Mission", 1063, 482, 306, UI_XSTR_COLOR_PINK, -1, &Multi_paused_buttons[0][MP_EXIT_MISSION].button },
93  { "Mission Paused", 1440, 107, 356, UI_XSTR_COLOR_PINK, -1, NULL },
94  },
95  { // GR_1024
96  { "Exit", 1059, 787, 478, UI_XSTR_COLOR_PINK, -1, &Multi_paused_buttons[1][MP_EXIT_MISSION].button },
97  { "Mission", 1063, 778, 490, UI_XSTR_COLOR_PINK, -1, &Multi_paused_buttons[1][MP_EXIT_MISSION].button },
98  { "Mission Paused", 1440, 171, 567, UI_XSTR_COLOR_PINK, -1, NULL },
99  }
100 };
101 
102 
104 int Multi_paused_screen_id = -1; // backed up screen data
105 int Multi_paused_background = -1; // pause background
106 
108 void multi_pause_button_pressed(int n);
109 
110 // (server) evaluate a pause request from the given player (should call for himself as well)
111 void multi_pause_server_eval_request(net_player *pl, int pause);
112 
113 // if this player can unpause
115 
116 // render the callsign of the guy who paused
118 
119 int Multi_paused = 0;
120 
121 // ----------------------------------------------------------------------------------
122 // EXTERNAL FUNCTIONS/VARIABLES
123 //
124 
125 extern void game_flush();
126 
127 extern void weapon_pause_sounds();
128 extern void weapon_unpause_sounds();
129 
130 extern void audiostream_pause_all(bool via_sexp_or_script = false);
131 extern void audiostream_unpause_all(bool via_sexp_or_script = false);
132 
133 // ----------------------------------------------------------------------------------
134 // PAUSE FUNCTIONS
135 //
136 
137 // re-initializes the pause system. call before entering the mission to reset
139 {
140  // set the pause status to 0
141  Multi_pause_status = 0;
142 
143  // null out the pause pointer
144  Multi_pause_pauser = NULL;
145 
146  // eat keys timestamp
147  Multi_pause_eat = -1.0f;
148 }
149 
150 // (client) call when receiving a packet indicating we should pause
152 {
153  int idx;
154 
155  // if we're already paused, don't do anything
156  if(Multi_pause_status){
157  return;
158  }
159 
160  // sanity check
162 
163  // mark the game as being paused
164  Multi_pause_status = 1;
165 
166  // if we're not already in the pause state
168  // jump into the paused state
170 
171  // mark the netgame state
173  }
174 
175  // if we're the server of the game, send a packet which will pause the clients in the game now
177  for(idx=0;idx<MAX_PLAYERS;idx++){
178  if(MULTI_CONNECTED(Net_players[idx]) && (Net_player != &Net_players[idx])){
180  }
181  }
182  }
183 }
184 
185 // (client) call when receiving a packet indicating we should unpause
187 {
188  int idx;
189 
190  // if we're already unpaused, don't do anything
191  if(!Multi_pause_status){
192  return;
193  }
194 
195  // sanity check
197 
198  // mark the game as being unpaused
199  Multi_pause_status = 0;
200 
201  // pop us out of any necessary states (including the pause state !!)
203 
204  // mark the netgame state
206 
207  // if we're the server of the game, send a packet which will unpause the clients in the game now
208  // if we're the server of the game, send a packet which will pause the clients in the game now
210  for(idx=0;idx<MAX_PLAYERS;idx++){
211  if(MULTI_CONNECTED(Net_players[idx]) && (Net_player != &Net_players[idx])){
213  }
214  }
215  }
216 }
217 
218 // send a request to pause or unpause a game (all players should use this function)
219 void multi_pause_request(int pause)
220 {
221  // if i'm the server, run it through the eval function right now
224  }
225  // otherwise, send a reliable request packet to the server
226  else {
227  send_multi_pause_packet(pause);
228  }
229 }
230 
231 // (server) evaluate a pause request from the given player (should call for himself as well)
233 {
234  int cur_state;
235 
236  // if this is a pause request and we're already in the pause state, do nothing
237  if(pause && Multi_pause_status){
238  return;
239  }
240 
241  // if this is an unpause request and we're already unpaused, do nothing
242  if(!pause && !Multi_pause_status){
243  return;
244  }
245 
246  // get the current state (don't allow pausing from certain states
247  cur_state = gameseq_get_state();
248  if((cur_state == GS_STATE_DEBRIEF) || (cur_state == GS_STATE_MULTI_MISSION_SYNC) || (cur_state == GS_STATE_BRIEFING) ||
249  (cur_state == GS_STATE_STANDALONE_POSTGAME) || (cur_state == GS_STATE_MULTI_STD_WAIT) || (cur_state == GS_STATE_WEAPON_SELECT) ||
250  (cur_state == GS_STATE_TEAM_SELECT) || (cur_state == GS_STATE_MULTI_DOGFIGHT_DEBRIEF)){
251  return;
252  }
253 
254  // if this is a pause request
255  if(pause){
256  // record who the pauser is
257  Multi_pause_pauser = pl;
258 
259  // pause the game
261  }
262  // if this is an unpause request
263  else {
264  // if this guy is allowed to unpause the game, do so
265  if(multi_pause_can_unpause(pl)){
266  // unmark the "pauser"
267  Multi_pause_pauser = NULL;
268 
269  // unpause the game
271  }
272  }
273 }
274 
275 // if this player can unpause
277 {
278  if(!(p->flags & NETINFO_FLAG_GAME_HOST) && (p != Multi_pause_pauser)){
279  return 0;
280  }
281 
282  return 1;
283 }
284 
285 // if we still want to eat keys
287 {
288  // if the eat timestamp is negative, don't eat keys
289  if(Multi_pause_eat < 0.0f){
290  return 0;
291  }
292 
293  // if less than 1 second has passed, continue eating keys
295  nprintf(("Network","PAUSE EATING KEYS\n"));
296 
298  key_flush();
299 
300  return 1;
301  }
302 
303  // otherwise, disable the timestamp
304  Multi_pause_eat = -1.0f;
305 
306  return 0;
307 }
308 
309 
310 // ----------------------------------------------------------------------------------
311 // PAUSE UI FUNCTIONS
312 //
313 
315 {
316  int i;
317 
318  // if we're already paused. do nothing
319  if ( Multi_paused ) {
320  return;
321  }
322 
324 
325  if ( !(Game_mode & GM_MULTIPLAYER) )
326  return;
327 
328  // pause all beam weapon sounds
330 
331  // standalone shouldn't be doing any freespace interface stuff
333  std_debug_set_standalone_state_string("Multi paused do");
334  }
335  // everyone else should be doing UI stuff
336  else {
337  // pause all game music
339 
340  // switch off the text messaging system if it is active
342 
343  if ( Multi_paused_screen_id == -1 )
345 
346  // create ui window
347  Multi_paused_window.create(0, 0, gr_screen.max_w_unscaled, gr_screen.max_h_unscaled, 0);
348  Multi_paused_window.set_mask_bmap(Multi_paused_bg_mask[gr_screen.res]);
350 
351  for (i=0; i<MULTI_PAUSED_NUM_BUTTONS; i++) {
352  // create the button
353  Multi_paused_buttons[gr_screen.res][i].button.create(&Multi_paused_window, "", Multi_paused_buttons[gr_screen.res][i].x, Multi_paused_buttons[gr_screen.res][i].y, 1, 1, 0, 1);
354 
355  // set the highlight action
357 
358  // set the ani
359  Multi_paused_buttons[gr_screen.res][i].button.set_bmaps(Multi_paused_buttons[gr_screen.res][i].filename);
360 
361  // set the hotspot
362  Multi_paused_buttons[gr_screen.res][i].button.link_hotspot(Multi_paused_buttons[gr_screen.res][i].hotspot);
363  }
364 
365  // add text
366  for(i=0; i<MULTI_PAUSED_NUM_TEXT; i++){
367  Multi_paused_window.add_XSTR(&Multi_paused_text[gr_screen.res][i]);
368  }
369 
370  // close any instances of a chatbox
371  chatbox_close();
372 
373  // intialize our custom chatbox
375  }
376 
377  Multi_paused = 1;
378 
379  // reset timestamps
381 }
382 
384 {
385  int k;
386 
387  // make sure we don't enter this state unless we're in the mission itself
389 
390  // server of the game should periodically be sending pause packets for good measure
392  }
393 
394  if (!(Game_mode & GM_STANDALONE_SERVER)) {
395  // restore saved screen data if any
396  if (Multi_paused_screen_id >= 0) {
398  }
399 
400  // set the background image
401  if (Multi_paused_background >= 0) {
403  gr_bitmap(0, 0, GR_RESIZE_MENU);
404  }
405 
406  // if we're inside of popup code right now, don't process the window
407  if(!popup_active()){
408  // process chatbox and window stuff
409  k = chatbox_process();
410  k = Multi_paused_window.process(k);
411 
412  switch (k) {
413  case KEY_ESC:
414  case KEY_PAUSE:
416  break;
417  }
418  }
419 
420  // check for any button presses
422 
423  // render the callsign of the guy who paused
425 
426  // render the chatbox
427  chatbox_render();
428 
429  // draw tooltips
430  // Multi_paused_window.draw_tooltip();
431  Multi_paused_window.draw();
432 
433  // display the voice status indicator
435 
436  // don't flip screen if we are in the popup code right now
437  if (!popup_active()) {
438  gr_flip();
439  }
440  }
441  // standalone pretty much does nothing here
442  else {
443  Sleep(1);
444  }
445 }
446 
447 void multi_pause_close(int end_mission)
448 {
449  if ( !Multi_paused )
450  return;
451 
452  // set the standalonest
455  } else {
456  // free the screen up
457  if ( end_mission && (Multi_paused_screen_id >= 0) ) {
460  }
461 
462  if (Multi_paused_background >= 0) {
465  }
466 
467  Multi_paused_window.destroy();
468  game_flush();
469 
470  // unpause all the music
472  }
473 
474  // unpause beam weapon sounds
476 
477  // eat keys timestamp
479 
480  // reset timestamps
482 
483  // clear out control config and keypress info
485  key_flush();
486 
487  Multi_paused = 0;
488 }
489 
491 {
492  int idx;
493 
494  // process any pause buttons which may have been pressed
495  for (idx=0; idx<MULTI_PAUSED_NUM_BUTTONS; idx++){
496  if (Multi_paused_buttons[gr_screen.res][idx].button.pressed()){
498  }
499  }
500 }
501 
503 {
504  switch (n) {
505  // the scroll up button
506  case MP_SCROLL_UP :
508  break;
509 
510  // the scroll down button
511  case MP_SCROLL_DOWN :
513  break;
514 
515  // the exit mission
516  case MP_EXIT_MISSION :
518  break;
519  }
520 }
521 
522 // render the callsign of the guy who paused
524 {
525  char pause_str[100];
526 
527  // write out the callsign of the player who paused the game
528  if((Multi_pause_pauser != NULL) && (Multi_pause_pauser->m_player != NULL)){
529  memset(pause_str,0,100);
530  strcpy_s(pause_str,Multi_pause_pauser->m_player->callsign);
531 
532  // blit it
535  }
536 }
void set_highlight_action(void(*_user_function)(void))
Definition: button.cpp:375
int i
Definition: multi_pxo.cpp:466
int chatbox_create(int mode_flags)
Definition: chatbox.cpp:495
void add_XSTR(char *string, int _xstr_id, int _x, int _y, UI_GADGET *_assoc, int _color_type, int _font_id=-1)
Definition: window.cpp:476
void multi_pause_reset()
int Game_mode
Definition: systemvars.cpp:24
void gr_flip()
Definition: 2d.cpp:2113
int x
Definition: ui.h:658
#define NETGAME_STATE_PAUSED
Definition: multi.h:668
#define GR_RESIZE_MENU
Definition: 2d.h:684
net_player * Net_player
Definition: multi.cpp:94
int Multi_pause_status
Definition: multi_pause.cpp:38
int multi_pause_can_unpause(net_player *p)
int y
Definition: ui.h:658
player * m_player
Definition: multi.h:459
UI_WINDOW Multi_paused_window
void multi_reset_timestamps()
Definition: multi.cpp:1741
#define gr_restore_screen
Definition: 2d.h:826
int gameseq_get_state(void)
Definition: fredstubs.cpp:60
Assert(pm!=NULL)
void multi_pause_do()
#define MULTI_PAUSED_NUM_BUTTONS
Definition: multi_pause.cpp:47
#define GR_NUM_RESOLUTIONS
Definition: 2d.h:651
__inline void gr_string(int x, int y, const char *string, int resize_mode=GR_RESIZE_FULL)
Definition: 2d.h:769
ui_button_info Multi_paused_buttons[GR_NUM_RESOLUTIONS][MULTI_PAUSED_NUM_BUTTONS]
Definition: multi_pause.cpp:74
int res
Definition: 2d.h:370
int max_h_unscaled
Definition: 2d.h:361
GLclampf f
Definition: Glext.h:7097
int chatbox_scroll_down()
Definition: chatbox.cpp:724
#define f2fl(fx)
Definition: floating.h:37
net_player * Multi_pause_pauser
Definition: multi_pause.cpp:41
void key_flush()
Definition: key.cpp:356
void gr_set_color_fast(color *dst)
Definition: 2d.cpp:1197
int flags
Definition: multi.h:463
void gr_set_bitmap(int bitmap_num, int alphablend_mode, int bitblt_mode, float alpha)
Definition: 2d.cpp:2105
int max_w_unscaled
Definition: 2d.h:361
void multi_msg_text_flush()
Definition: multi_pmsg.cpp:329
int bm_release(int handle, int clear_render_targets)
Frees both a bitmap's data and it's associated slot.
Definition: bmpman.cpp:2603
char callsign[CALLSIGN_LEN+1]
Definition: player.h:91
int game_state
Definition: multi.h:498
void destroy()
Definition: window.cpp:189
void set_mask_bmap(char *fname)
Definition: window.cpp:75
int Multi_paused
int set_bmaps(char *ani_filename, int nframes=3, int start_frame=1)
Definition: gadget.cpp:71
void chatbox_render()
Definition: chatbox.cpp:683
void multi_pause_close(int end_mission)
void weapon_pause_sounds()
Definition: weapons.cpp:7248
void multi_pause_check_buttons()
#define NETINFO_FLAG_AM_MASTER
Definition: multi.h:599
color Color_bright
Definition: alphacolors.cpp:28
#define nprintf(args)
Definition: pstypes.h:239
#define GM_MULTIPLAYER
Definition: systemvars.h:18
void send_client_update_packet(net_player *pl)
Definition: multimsgs.cpp:6975
int Multi_paused_screen_id
#define MP_SCROLL_DOWN
Definition: multi_pause.cpp:51
#define gr_save_screen
Definition: 2d.h:825
netgame_info Netgame
Definition: multi.cpp:97
int hotspot
Definition: ui.h:659
int pressed()
Definition: button.cpp:325
#define KEY_PAUSE
Definition: key.h:185
#define MULTI_PAUSED_NUM_TEXT
Definition: multi_pause.cpp:88
void multi_pause_button_pressed(int n)
#define MAX_PLAYERS
Definition: pstypes.h:32
#define NETINFO_FLAG_GAME_HOST
Definition: multi.h:603
UI_BUTTON button
Definition: ui.h:660
void send_multi_pause_packet(int pause)
Definition: multimsgs.cpp:3709
int idx
Definition: multiui.cpp:761
GLclampd n
Definition: Glext.h:7286
float Multi_pause_eat
Definition: multi_pause.cpp:44
void std_debug_set_standalone_state_string(char *str)
int Multi_paused_background
#define GM_STANDALONE_SERVER
Definition: systemvars.h:27
#define NETGAME_STATE_IN_MISSION
Definition: multi.h:666
void weapon_unpause_sounds()
Definition: weapons.cpp:7257
int bm_load(const char *real_filename)
Loads a bitmap so we can draw with it later.
Definition: bmpman.cpp:1119
int multi_quit_game(int prompt, int notify_code, int err_code, int wsa_error)
#define MP_SCROLL_UP
Definition: multi_pause.cpp:50
void chatbox_close()
Definition: chatbox.cpp:634
void multi_pause_server_eval_request(net_player *pl, int pause)
void multi_pause_unpause()
char * Multi_paused_bg_fname[GR_NUM_RESOLUTIONS]
Definition: multi_pause.cpp:54
void game_flush()
Definition: fredstubs.cpp:83
void link_hotspot(int num)
Definition: gadget.cpp:50
void create(UI_WINDOW *wnd, char *_text, int _x, int _y, int _w, int _h, int do_repeat=0, int ignore_focus=0)
Definition: button.cpp:26
#define KEY_ESC
Definition: key.h:124
#define UI_XSTR_COLOR_PINK
Definition: ui.h:161
#define MULTI_CONNECTED(np)
Definition: multi.h:136
void create(int _x, int _y, int _w, int _h, int _flags, int _f_id=-1)
Definition: window.cpp:140
#define MP_EXIT_MISSION
Definition: multi_pause.cpp:52
fix timer_get_fixed_seconds()
Definition: timer.cpp:116
void audiostream_unpause_all(bool via_sexp_or_script=false)
Definition: audiostr.cpp:1990
Definition: ui.h:584
void multi_handle_state_special()
Definition: multiutil.cpp:2253
screen gr_screen
Definition: 2d.cpp:46
Definition: ui.h:162
void multi_pause_render_callsign()
void multi_pause_pause()
GLfloat GLfloat p
Definition: Glext.h:8373
void Sleep(int mili)
void common_play_highlight_sound()
Definition: gamesnd.cpp:1151
void multi_common_voice_display_status()
Definition: multiui.cpp:369
UI_XSTR Multi_paused_text[GR_NUM_RESOLUTIONS][MULTI_PAUSED_NUM_BUTTONS]
Definition: multi_pause.cpp:89
int Mp_callsign_coords[GR_NUM_RESOLUTIONS][2]
Definition: multi_pause.cpp:65
int chatbox_process(int key_in)
Definition: chatbox.cpp:575
#define PROMPT_ALL
Definition: multi_endgame.h:29
#define gr_free_screen
Definition: 2d.h:827
char * filename
Definition: ui.h:657
void gr_bitmap(int _x, int _y, int resize_mode)
Definition: 2d.cpp:1303
char * Multi_paused_bg_mask[GR_NUM_RESOLUTIONS]
Definition: multi_pause.cpp:59
void multi_pause_init()
int chatbox_scroll_up()
Definition: chatbox.cpp:708
void audiostream_pause_all(bool via_sexp_or_script=false)
Definition: audiostr.cpp:1978
void draw()
Definition: window.cpp:220
struct ui_button_info ui_button_info
void control_config_clear_used_status()
int process(int key_in=-1, int process_mouse=1)
Definition: window.cpp:401
#define CHATBOX_FLAG_MULTI_PAUSED
Definition: chatbox.h:23
net_player Net_players[MAX_PLAYERS]
Definition: multi.cpp:93
void gameseq_post_event(int event)
int multi_pause_eat_keys()
void multi_pause_request(int pause)
#define strcpy_s(...)
Definition: safe_strings.h:67