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 "controlconfig/controlsconfig.h"
14 #include "freespace.h"
15 #include "gamesequence/gamesequence.h"
16 #include "globalincs/alphacolors.h"
17 #include "graphics/font.h"
18 #include "hud/hud.h"
19 #include "hud/hudmessage.h"
20 #include "io/key.h"
21 #include "missionui/missionpause.h"
22 #include "network/multi_pause.h"
23 #include "object/object.h"
24 #include "popup/popup.h"
25 #include "sound/audiostr.h"
26 #include "ui/ui.h"
27 #include "weapon/weapon.h"
28
29
30
31
32 // ----------------------------------------------------------------------------------------------------------------
33 // PAUSE DEFINES/VARS
34 //
35
36 // pause bitmap name
37 const char *Pause_bmp_name[GR_NUM_RESOLUTIONS] = {
38 "PleaseWait",
39 "2_PleaseWait"
40 };
41
42 // pause bitmap display stuff
43 int Please_wait_coords[GR_NUM_RESOLUTIONS][4] = {
44 { // GR_640
45 152, 217, 316, 26
46 },
47 { // GR_1024
48 247, 346, 510, 36
49 }
50 };
51
52 // pause window objects
53 UI_WINDOW Pause_win;
54 UI_CHECKBOX Pause_single_step;
55 UI_CHECKBOX Pause_physics;
56 UI_CHECKBOX Pause_ai;
57 UI_CHECKBOX Pause_ai_render;
58 UI_CHECKBOX Pause_firing;
59 UI_CHECKBOX Pause_external_view_mode_check;
60 UI_BUTTON Pause_continue;
61 int Pause_type = PAUSE_TYPE_NORMAL;
62
63 // if we're already paused
64 int Paused = 0;
65
66 // background screen (for the chatbox)
67 int Pause_background_bitmap = -1;
68
69 // saved background screen
70 int Pause_saved_screen = -1;
71
72 // if we're in external vie wmode
73 int Pause_external_view_mode = 0;
74
75 // externs
76 extern int Ai_render_debug_flag;
77 extern int Ai_firing_enabled;
78 extern int physics_paused;
79 extern int ai_paused;
80 extern int last_single_step;
81 extern int game_single_step;
82
83 // ----------------------------------------------------------------------------------------------------------------
84 // PAUSE FUNCTIONS
85 //
86
pause_get_type()87 int pause_get_type()
88 {
89 return Pause_type;
90 }
91
pause_set_type(int type)92 void pause_set_type(int type)
93 {
94 Pause_type = type;
95 }
96
97 // initialize the pause screen
pause_init()98 void pause_init()
99 {
100 // if we're already paused. do nothing
101 if ( Paused ) {
102 return;
103 }
104
105 Assert( !(Game_mode & GM_MULTIPLAYER) );
106
107 // pause all weapon sounds
108 weapon_pause_sounds();
109
110 if (Pause_type == PAUSE_TYPE_NORMAL) {
111 Pause_saved_screen = gr_save_screen();
112 }
113
114 // pause all game music
115 audiostream_pause_all();
116
117 Pause_win.create(0, 0, gr_screen.max_w_unscaled, gr_screen.max_h_unscaled, 0);
118
119 Pause_background_bitmap = bm_load(Pause_bmp_name[gr_screen.res]);
120
121 io::mouse::CursorManager::get()->pushStatus();
122 io::mouse::CursorManager::get()->showCursor(true);
123
124 Paused = 1;
125 }
126
127 extern int button_function_demo_valid(int n);
128 extern int button_function(int n);
129
130 // pause do frame - will handle running multiplayer operations if necessary
pause_do()131 void pause_do()
132 {
133 int k;
134 const char *pause_str = XSTR("Paused", 767);
135 int str_w, str_h;
136 // next two are for view resetting
137 static int previous_Viewer_mode = -1;
138 static int previous_hud_state = -1;
139
140 Assert( !(Game_mode & GM_MULTIPLAYER) );
141
142 // RENDER A GAME FRAME HERE AS THE BACKGROUND (if normal pause)
143
144 if(Pause_type == PAUSE_TYPE_NORMAL) {
145 // Fall back to viewer just incase saved screen is invalid
146 if(Pause_saved_screen == -1){
147 Pause_type = PAUSE_TYPE_VIEWER;
148 }
149 else if(Pause_type == PAUSE_TYPE_NORMAL) {
150 gr_restore_screen(Pause_saved_screen);
151 }
152 }
153
154 if(Pause_type == PAUSE_TYPE_NORMAL){
155 if (Pause_background_bitmap >= 0) {
156 gr_set_bitmap(Pause_background_bitmap);
157
158 // draw the bitmap
159 gr_bitmap(Please_wait_coords[gr_screen.res][0], Please_wait_coords[gr_screen.res][1], GR_RESIZE_MENU);
160
161 // draw "Paused" on it
162 gr_set_color_fast(&Color_normal);
163 font::set_font(font::FONT2);
164 gr_get_string_size(&str_w, &str_h, pause_str);
165 gr_string((gr_screen.max_w_unscaled - str_w) / 2, (gr_screen.max_h_unscaled - str_h) / 2, pause_str, GR_RESIZE_MENU);
166 font::set_font(font::FONT1);
167 }
168 }
169
170 if (Pause_type == PAUSE_TYPE_VIEWER) {
171 if (previous_Viewer_mode < 0)
172 previous_Viewer_mode = Viewer_mode;
173
174 if (previous_hud_state < 0)
175 previous_hud_state = hud_disabled();
176 }
177
178 // process the ui window here
179 k = Pause_win.process() & ~KEY_DEBUGGED;
180 switch (k)
181 {
182 case KEY_TAB:
183 hud_toggle_draw();
184 break;
185
186 // view from outside of the ship
187 case KEY_ENTER:
188 if (Pause_type == PAUSE_TYPE_VIEWER) {
189 button_function_demo_valid(VIEW_EXTERNAL);
190 }
191 break;
192
193 // view from target
194 case KEY_PADDIVIDE:
195 if (Pause_type == PAUSE_TYPE_VIEWER) {
196 button_function_demo_valid(VIEW_OTHER_SHIP);
197 }
198 break;
199
200 // change target
201 case KEY_PADMULTIPLY:
202 if (Pause_type == PAUSE_TYPE_VIEWER) {
203 button_function(TARGET_NEXT);
204 }
205 break;
206
207 case KEY_ESC:
208 case KEY_ALTED + KEY_PAUSE:
209 case KEY_PAUSE:
210 // reset previous view if we happened to be playing around with it during pause
211 if (Pause_type == PAUSE_TYPE_VIEWER) {
212 if (previous_Viewer_mode >= 0) {
213 Viewer_mode = previous_Viewer_mode;
214 }
215
216 // NOTE remember that hud state is reversed here (0 == on, 1 == off)
217 if ( (previous_hud_state >= 0) && (hud_disabled() != previous_hud_state) ) {
218 hud_set_draw( !previous_hud_state );
219 }
220 }
221
222 gameseq_post_event(GS_EVENT_PREVIOUS_STATE);
223 break;
224 } // end switch
225
226 // draw the background window
227 Pause_win.draw();
228
229 // a very unique case where we shouldn't be doing the page flip because we're inside of popup code
230 if(!popup_active()){
231 if(Pause_type == PAUSE_TYPE_NORMAL) {
232 gr_flip();
233 }
234 } else {
235 // this should only be happening in a very unique multiplayer case
236 Int3();
237 }
238 }
239
240 // close the pause screen
pause_close()241 void pause_close()
242 {
243 // if we're not paused - do nothing
244 if ( !Paused ) {
245 return;
246 }
247
248 Assert( !(Game_mode & GM_MULTIPLAYER) );
249
250 // unpause all weapon sounds
251 weapon_unpause_sounds();
252
253 // deinit stuff
254 if(Pause_saved_screen != -1) {
255 gr_free_screen(Pause_saved_screen);
256 Pause_saved_screen = -1;
257 }
258
259 if (Pause_background_bitmap != -1){
260 bm_release(Pause_background_bitmap);
261 Pause_background_bitmap = -1;
262 }
263
264 Pause_win.destroy();
265 game_flush();
266
267 io::mouse::CursorManager::get()->popStatus();
268
269 // unpause all the music
270 audiostream_unpause_all();
271
272 Paused = 0;
273 }
274
275 // debug pause init
pause_debug_init()276 void pause_debug_init()
277 {
278 Pause_win.create( 100,100,400,300, WIN_DIALOG );
279
280 Pause_physics.create( &Pause_win, NOX("Physics Pause <P>"), 200, 150, physics_paused );
281 Pause_ai.create( &Pause_win, NOX("AI Pause <A>"), 200, 175, ai_paused );
282 #ifndef NDEBUG
283 Pause_ai_render.create( &Pause_win, NOX("AI Render Stuff <R>"), 200, 200, Ai_render_debug_flag);
284 #endif
285 Pause_firing.create( &Pause_win, NOX("AI firing <F>"), 200, 225, Ai_firing_enabled);
286 Pause_external_view_mode_check.create( &Pause_win, NOX("External View <E>"), 200, 250, Pause_external_view_mode);
287 Pause_single_step.create( &Pause_win, NOX("Single Step <S>"), 200, 290, game_single_step );
288 Pause_continue.create( &Pause_win, NOX("Leave Pause"), 200, 350, 200, 40 );
289
290 Pause_single_step.set_hotkey( KEY_S );
291 Pause_physics.set_hotkey( KEY_P );
292 Pause_ai.set_hotkey( KEY_A );
293 Pause_ai_render.set_hotkey( KEY_R );
294 Pause_firing.set_hotkey( KEY_F );
295 Pause_external_view_mode_check.set_hotkey( KEY_E );
296 Pause_continue.set_hotkey( KEY_ESC );
297
298 Pause_continue.set_focus();
299 }
300
301 // debug pause do frame
pause_debug_do()302 void pause_debug_do()
303 {
304 int key;
305
306 key = Pause_win.process();
307 if ( Pause_single_step.changed()) {
308 game_single_step = Pause_single_step.checked();
309 }
310
311 if ( Pause_physics.changed()) {
312 physics_paused = Pause_physics.checked();
313 }
314
315 if ( Pause_ai.changed()) {
316 ai_paused = Pause_ai.checked();
317 if (ai_paused){
318 obj_init_all_ships_physics();
319 }
320 }
321
322 if ( Pause_ai_render.changed()) {
323 Ai_render_debug_flag = Pause_ai_render.checked();
324 }
325
326 if ( Pause_firing.changed()) {
327 Ai_firing_enabled = Pause_firing.checked();
328 }
329
330 if ( Pause_external_view_mode_check.changed()) {
331 Pause_external_view_mode = Pause_external_view_mode_check.checked();
332 if (Pause_external_view_mode){
333 HUD_sourced_printf(HUD_SOURCE_HIDDEN, "%s", XSTR( "External view of player ship.", 182));
334 } else {
335 HUD_sourced_printf(HUD_SOURCE_HIDDEN, "%s", XSTR( "View from inside player ship.", 183));
336 }
337 }
338
339 if ( Pause_continue.pressed() || (key == KEY_PAUSE) ) { // Changed, MK, 11/9/97, only Pause break pause.
340 gameseq_post_event(GS_EVENT_PREVIOUS_STATE);
341 }
342
343 gr_clear();
344 Pause_win.draw();
345
346 gr_flip();
347 }
348
349 // debug pause close
pause_debug_close()350 void pause_debug_close()
351 {
352 last_single_step = 0; // Make so single step waits a frame before stepping
353 Pause_win.destroy();
354 game_flush();
355 }
356