2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
11 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
15 * $Source: /cvs/cvsroot/d2x/main/hud.c,v $
18 * $Date: 2003-06-06 19:04:27 $
20 * Routines for displaying HUD messages...
22 * $Log: not supported by cvs2svn $
23 * Revision 1.5.2.1 2003/06/06 03:35:41 btb
24 * finish console conversion away from SDL
26 * Revision 1.5 2002/10/11 05:14:59 btb
27 * make hud_message work correctly
29 * Revision 1.4 2002/10/10 19:08:15 btb
32 * Revision 1.3 2001/11/04 09:00:25 bradleyb
33 * Enable d1x-style hud_message
60 #include "menu.h" // For the font.
77 int HUD_nmessages = 0;
78 fix HUD_message_timer = 0; // Time, relative to Players[Player_num].time (int.frac seconds.frac), at which to erase gauge message
79 char HUD_messages[HUD_MAX_NUM][HUD_MESSAGE_LENGTH+5];
81 extern void copy_background_rect(int left,int top,int right,int bot);
82 char Displayed_background_message[2][HUD_MESSAGE_LENGTH] = {"",""};
83 int Last_msg_ycrd = -1;
84 int Last_msg_height = 6;
87 int MSG_Playermessages = 0;
88 int MSG_Noredundancy = 0;
90 int Modex_hud_msg_count;
92 #define LHX(x) ((x)*(FontHires?2:1))
93 #define LHY(y) ((y)*(FontHires?2.4:1))
99 // -----------------------------------------------------------------------------
100 void clear_background_messages(void)
103 if (extra_clear == FrameCount) //don't do extra clear on same frame
108 if (((Cockpit_mode == CM_STATUS_BAR) || (Cockpit_mode == CM_FULL_SCREEN)) && (Last_msg_ycrd != -1) && (dd_VR_render_sub_buffer[0].yoff >= 6)) {
109 dd_grs_canvas *canv_save = dd_grd_curcanv;
111 if (((Cockpit_mode == CM_STATUS_BAR) || (Cockpit_mode == CM_FULL_SCREEN)) && (Last_msg_ycrd != -1) && (VR_render_sub_buffer[0].cv_bitmap.bm_y >= 6)) {
112 grs_canvas *canv_save = grd_curcanv;
115 WINDOS( dd_gr_set_current_canvas(get_current_game_screen()),
116 gr_set_current_canvas(get_current_game_screen())
119 PA_DFX (pa_set_frontbuffer_current());
120 PA_DFX (copy_background_rect(0, Last_msg_ycrd, grd_curcanv->cv_bitmap.bm_w, Last_msg_ycrd+Last_msg_height-1));
121 PA_DFX (pa_set_backbuffer_current());
122 copy_background_rect(0, Last_msg_ycrd, grd_curcanv->cv_bitmap.bm_w, Last_msg_ycrd+Last_msg_height-1);
125 dd_gr_set_current_canvas(canv_save),
126 gr_set_current_canvas(canv_save)
130 if (extra_clear || !GRMODEINFO(modex)) {
135 extra_clear = FrameCount;
141 Displayed_background_message[VR_current_page][0] = 0;
145 void HUD_clear_messages()
149 hud_first = hud_last = 0;
150 HUD_message_timer = 0;
151 clear_background_messages();
152 for (i = 0; i < HUD_MAX_NUM; i++)
153 sprintf(HUD_messages[i], "SlagelSlagel!!");
157 extern int Guided_in_big_window;
158 extern int max_window_h;
160 extern grs_canvas *print_to_canvas(char *s,grs_font *font, int fc, int bc, int double_flag);
162 // -----------------------------------------------------------------------------
163 // print to buffer, double heights, and blit bitmap to screen
164 void modex_hud_message(int x, int y, char *s, grs_font *font, int color)
166 grs_canvas *temp_canv;
168 temp_canv = print_to_canvas(s, font, color, -1, 1);
170 gr_bitmapm(x,y,&temp_canv->cv_bitmap);
172 gr_free_canvas(temp_canv);
175 extern int max_window_w;
177 // -----------------------------------------------------------------------------
178 // Writes a message on the HUD and checks its timer.
179 void HUD_render_message_frame()
184 if (( HUD_nmessages < 0 ) || (HUD_nmessages > HUD_MAX_NUM))
187 if ( (HUD_nmessages < 1 ) && (Modex_hud_msg_count == 0))
190 HUD_message_timer -= FrameTime;
194 clear_background_messages(); // If in status bar mode and no messages, then erase.
197 if ( HUD_message_timer < 0 ) {
198 // Timer expired... get rid of oldest message...
199 if (hud_last!=hud_first) {
202 //&HUD_messages[hud_first][0] is deing deleted...;
203 hud_first = (hud_first+1) % HUD_MAX_NUM;
204 HUD_message_timer = F1_0*2;
206 if (HUD_nmessages == 0)
207 Modex_hud_msg_count = 2;
208 temp = Last_msg_ycrd;
209 clear_background_messages(); // If in status bar mode and no messages, then erase.
210 if (Modex_hud_msg_count)
211 Last_msg_ycrd = temp;
215 if (HUD_nmessages > 0 ) {
218 HUD_color = BM_XRGB(0,28,0);
221 if ( (VR_render_mode==VR_NONE) && ((Cockpit_mode == CM_STATUS_BAR) || (Cockpit_mode == CM_FULL_SCREEN)) && (dd_VR_render_sub_buffer[0].yoff >= (max_window_h/8))) {
223 if ( (VR_render_mode==VR_NONE) && ((Cockpit_mode == CM_STATUS_BAR) || (Cockpit_mode == CM_FULL_SCREEN)) && (VR_render_sub_buffer[0].cv_bitmap.bm_y >= (max_window_h/8))) {
225 // Only display the most recent message in this mode
226 char *message = HUD_messages[(hud_first+HUD_nmessages-1) % HUD_MAX_NUM];
228 if (strcmp(Displayed_background_message[VR_current_page], message)) {
231 dd_grs_canvas *canv_save = dd_grd_curcanv,
232 grs_canvas *canv_save = grd_curcanv
237 FontHires=1; // always display hires font outside of display
241 ycrd = dd_grd_curcanv->yoff - (SMALL_FONT->ft_h+2),
242 ycrd = grd_curcanv->cv_bitmap.bm_y - (SMALL_FONT->ft_h+2)
249 dd_gr_set_current_canvas(get_current_game_screen()),
250 gr_set_current_canvas(get_current_game_screen())
253 gr_set_curfont( SMALL_FONT );
254 gr_get_string_size(message, &w, &h, &aw );
255 clear_background_messages();
258 if (grd_curcanv->cv_bitmap.bm_type == BM_MODEX) {
259 WIN(Int3()); // No no no no ....
262 modex_hud_message((grd_curcanv->cv_bitmap.bm_w-w)/2, ycrd, message, SMALL_FONT, HUD_color);
263 if (Modex_hud_msg_count > 0) {
264 Modex_hud_msg_count--;
265 Displayed_background_message[VR_current_page][0] = '!';
267 strcpy(Displayed_background_message[VR_current_page], message);
269 WIN(DDGRLOCK(dd_grd_curcanv));
270 gr_set_fontcolor( HUD_color, -1);
271 PA_DFX (pa_set_frontbuffer_current());
272 PA_DFX (gr_printf((grd_curcanv->cv_bitmap.bm_w-w)/2, ycrd, message ));
273 PA_DFX (pa_set_backbuffer_current());
274 gr_printf((grd_curcanv->cv_bitmap.bm_w-w)/2, ycrd, message );
275 strcpy(Displayed_background_message[VR_current_page], message);
276 WIN(DDGRUNLOCK(dd_grd_curcanv));
280 dd_gr_set_current_canvas(canv_save),
281 gr_set_current_canvas(canv_save)
284 Last_msg_ycrd = ycrd;
289 FontHires=0; // always display hires font outside of display
295 gr_set_curfont( SMALL_FONT );
297 if ( (Cockpit_mode == CM_FULL_SCREEN) || (Cockpit_mode == CM_LETTERBOX) ) {
298 if (Game_window_w == max_window_w)
299 y = SMALL_FONT->ft_h/2;
301 y= SMALL_FONT->ft_h * 2;
303 y = SMALL_FONT->ft_h/2;
305 if (Guided_missile[Player_num] && Guided_missile[Player_num]->type==OBJ_WEAPON && Guided_missile[Player_num]->id==GUIDEDMISS_ID &&
306 Guided_missile[Player_num]->signature==Guided_missile_sig[Player_num] && Guided_in_big_window)
307 y+=SMALL_FONT->ft_h+3;
309 WIN(DDGRLOCK(dd_grd_curcanv));
310 for (i=0; i<HUD_nmessages; i++ ) {
311 n = (hud_first+i) % HUD_MAX_NUM;
312 if ((n < 0) || (n >= HUD_MAX_NUM))
314 if (!strcmp(HUD_messages[n], "This is a bug."))
316 gr_get_string_size(&HUD_messages[n][0], &w, &h, &aw );
317 gr_set_fontcolor( HUD_color, -1);
319 PA_DFX (pa_set_frontbuffer_current());
320 PA_DFX(gr_string((grd_curcanv->cv_bitmap.bm_w-w)/2,y, &HUD_messages[n][0] ));
321 PA_DFX (pa_set_backbuffer_current());
322 gr_string((grd_curcanv->cv_bitmap.bm_w-w)/2,y, &HUD_messages[n][0] );
325 WIN(DDGRUNLOCK(dd_grd_curcanv));
329 else if (get_current_game_screen()->cv_bitmap.bm_type == BM_MODEX) {
330 if (Modex_hud_msg_count) {
331 int temp = Last_msg_ycrd;
332 Modex_hud_msg_count--;
333 clear_background_messages(); // If in status bar mode and no messages, then erase.
334 Last_msg_ycrd = temp;
339 gr_set_curfont( GAME_FONT );
345 // Call to flash a message on the HUD. Returns true if message drawn.
346 // (message might not be drawn if previous message was same)
347 int HUD_init_message_va(char * format, va_list args)
350 char *message = NULL;
351 char *last_message=NULL;
356 char con_message[HUD_MESSAGE_LENGTH + 3];
358 Modex_hud_msg_count = 2;
360 if ( (hud_last < 0) || (hud_last >= HUD_MAX_NUM))
363 // -- mprintf((0, "message timer: %7.3f\n", f2fl(HUD_message_timer)));
364 message = &HUD_messages[hud_last][0];
365 vsprintf(message,format,args);
368 /* Produce a sanitised version and send it to the console */
369 cleanmessage = d_strdup(message);
370 for (temp=0,temp2=0; message[temp]!=0; temp++)
372 if (isprint(message[temp])) cleanmessage[temp2++] = message[temp];
373 else temp++; /* Skip next character as well */
375 cleanmessage[temp2] = 0;
376 con_printf(CON_NORMAL, "%s\n", cleanmessage);
377 d_free(cleanmessage);
380 /* Produce a colorised version and send it to the console */
382 HUD_color = BM_XRGB(0,28,0);
383 con_message[0] = CC_COLOR;
384 con_message[1] = HUD_color;
385 con_message[2] = '\0';
386 strcat(con_message, message);
387 con_printf(CON_NORMAL, "%s\n", con_message);
391 if ((Game_mode & GM_MULTI) && FindArg("-noredundancy"))
392 if (!strnicmp ("You already",message,11))
395 if ((Game_mode & GM_MULTI) && FindArg("-PlayerMessages") && PlayerMessage==0)
398 if (HUD_nmessages > 0) {
400 last_message = &HUD_messages[HUD_MAX_NUM-1][0];
402 last_message = &HUD_messages[hud_last-1][0];
405 temp = (hud_last+1) % HUD_MAX_NUM;
407 if ( temp==hud_first ) {
408 // If too many messages, remove oldest message to make room
409 hud_first = (hud_first+1) % HUD_MAX_NUM;
413 if (last_message && (!strcmp(last_message, message))) {
414 HUD_message_timer = F1_0*3; // 1 second per 5 characters
415 return 0; // ignore since it is the same as the last one
419 // Check if memory has been overwritten at this point.
420 if (strlen(message) >= HUD_MESSAGE_LENGTH)
421 Error( "Your message to HUD is too long. Limit is %i characters.\n", HUD_MESSAGE_LENGTH);
423 if (Newdemo_state == ND_STATE_RECORDING )
424 newdemo_record_hud_message( message );
426 HUD_message_timer = F1_0*3; // 1 second per 5 characters
433 int HUD_init_message(char * format, ... )
438 va_start(args, format);
439 ret = HUD_init_message_va(format, args);
446 //@@void player_dead_message(void)
448 //@@ if (!Arcade_mode && Player_exploded) { //(ConsoleObject->flags & OF_EXPLODING)) {
449 //@@ gr_set_curfont( SMALL_FONT );
450 //@@ if (HUD_color == -1)
451 //@@ HUD_color = BM_XRGB(0,28,0);
452 //@@ gr_set_fontcolor( HUD_color, -1);
454 //@@ gr_printf(0x8000, grd_curcanv->cv_bitmap.bm_h-8, TXT_PRESS_ANY_KEY);
455 //@@ gr_set_curfont( GAME_FONT );
460 void player_dead_message(void)
462 if (Player_exploded) {
463 if ( Players[Player_num].lives < 2 ) {
465 gr_set_curfont( HUGE_FONT );
466 gr_get_string_size( TXT_GAME_OVER, &w, &h, &aw );
469 x = (grd_curcanv->cv_w - w ) / 2;
470 y = (grd_curcanv->cv_h - h ) / 2;
472 NO_DFX (Gr_scanline_darkening_level = 2*7);
473 NO_DFX (gr_setcolor( BM_XRGB(0,0,0) ));
474 NO_DFX (gr_rect( x, y, x+w, y+h ));
475 Gr_scanline_darkening_level = GR_FADE_LEVELS;
477 gr_string(0x8000, (grd_curcanv->cv_h - grd_curcanv->cv_font->ft_h)/2 + h/8, TXT_GAME_OVER );
480 // Automatically exit death after 10 secs
481 if ( GameTime > Player_time_of_death + F1_0*10 ) {
482 Function_mode = FMODE_MENU;
483 Game_mode = GM_GAME_OVER;
484 longjmp( LeaveGame, 1 ); // Exit out of game loop
489 gr_set_curfont( GAME_FONT );
491 HUD_color = BM_XRGB(0,28,0);
492 gr_set_fontcolor( HUD_color, -1);
493 gr_string(0x8000, grd_curcanv->cv_h-(grd_curcanv->cv_font->ft_h+3), TXT_PRESS_ANY_KEY);
497 // void say_afterburner_status(void)
499 // if (Players[Player_num].flags & PLAYER_FLAGS_AFTERBURNER)
500 // HUD_init_message("Afterburner engaged.");
502 // HUD_init_message("Afterburner disengaged.");
505 void hud_message(int class, char *format, ...)
509 va_start(vp, format);
510 if ((!MSG_Noredundancy || (class & MSGC_NOREDUNDANCY)) &&
511 (!MSG_Playermessages || !(Game_mode & GM_MULTI) ||
512 (class & MSGC_PLAYERMESSAGES)))
513 HUD_init_message_va(format, vp);