2006-03-20 17:12:09 +00:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Routines for displaying HUD messages...
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include "hudmsg.h"
|
|
|
|
#include "pstypes.h"
|
|
|
|
#include "u_mem.h"
|
|
|
|
#include "strutil.h"
|
|
|
|
#include "console.h"
|
|
|
|
#include "inferno.h"
|
|
|
|
#include "game.h"
|
|
|
|
#include "screens.h"
|
|
|
|
#include "gauges.h"
|
|
|
|
#include "physics.h"
|
|
|
|
#include "error.h"
|
|
|
|
#include "menu.h" // For the font.
|
|
|
|
#include "collide.h"
|
|
|
|
#include "newdemo.h"
|
|
|
|
#include "player.h"
|
|
|
|
#include "gamefont.h"
|
|
|
|
#include "wall.h"
|
|
|
|
#include "screens.h"
|
|
|
|
#include "text.h"
|
|
|
|
#include "laser.h"
|
|
|
|
#include "args.h"
|
2008-04-13 00:28:36 +00:00
|
|
|
#include "playsave.h"
|
2006-03-20 17:12:09 +00:00
|
|
|
|
2010-07-13 06:35:25 +00:00
|
|
|
typedef struct hudmsg
|
2006-03-20 17:12:09 +00:00
|
|
|
{
|
2010-07-13 06:35:25 +00:00
|
|
|
fix time;
|
|
|
|
char message[HUD_MESSAGE_LENGTH+1];
|
|
|
|
} hudmsg;
|
2006-03-20 17:12:09 +00:00
|
|
|
|
2010-07-13 06:35:25 +00:00
|
|
|
hudmsg HUD_messages[HUD_MAX_NUM_STOR];
|
2006-03-20 17:12:09 +00:00
|
|
|
|
|
|
|
|
2010-07-13 06:35:25 +00:00
|
|
|
static int HUD_nmessages = 0;
|
|
|
|
int HUD_toolong = 0;
|
|
|
|
static int HUD_color = -1;
|
2006-03-20 17:12:09 +00:00
|
|
|
|
|
|
|
void HUD_clear_messages()
|
|
|
|
{
|
|
|
|
HUD_nmessages = 0;
|
2010-07-13 06:35:25 +00:00
|
|
|
HUD_toolong = 0;
|
|
|
|
memset(&HUD_messages, 0, sizeof(struct hudmsg)*HUD_MAX_NUM_STOR);
|
|
|
|
HUD_color = -1;
|
2006-03-20 17:12:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Writes a message on the HUD and checks its timer.
|
|
|
|
void HUD_render_message_frame()
|
|
|
|
{
|
2010-07-13 06:35:25 +00:00
|
|
|
int i,j,y;
|
|
|
|
|
|
|
|
HUD_toolong = 0;
|
2006-03-20 17:12:09 +00:00
|
|
|
|
2010-07-13 06:35:25 +00:00
|
|
|
if (( HUD_nmessages < 0 ) || (HUD_nmessages > HUD_MAX_NUM_STOR))
|
2006-03-20 17:12:09 +00:00
|
|
|
Int3(); // Get Rob!
|
|
|
|
|
2008-02-24 14:41:27 +00:00
|
|
|
if (HUD_nmessages < 1 )
|
2006-03-20 17:12:09 +00:00
|
|
|
return;
|
|
|
|
|
2010-07-13 06:35:25 +00:00
|
|
|
for (i = 0; i < HUD_nmessages; i++)
|
|
|
|
{
|
|
|
|
HUD_messages[i].time -= FrameTime;
|
|
|
|
// message expired - remove
|
|
|
|
if (HUD_messages[i].time <= 0)
|
|
|
|
{
|
|
|
|
for (j = i; j < HUD_nmessages; j++)
|
|
|
|
{
|
|
|
|
if (j+1 < HUD_nmessages)
|
|
|
|
memcpy(&HUD_messages[j], &HUD_messages[j+1], sizeof(struct hudmsg));
|
|
|
|
else
|
|
|
|
memset(&HUD_messages[j], 0, sizeof(struct hudmsg));
|
|
|
|
}
|
2006-03-20 17:12:09 +00:00
|
|
|
HUD_nmessages--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-13 06:35:25 +00:00
|
|
|
// display last $HUD_MAX_NUM_DISP messages on the list
|
|
|
|
if (HUD_nmessages > 0 )
|
|
|
|
{
|
|
|
|
int startmsg = ((HUD_nmessages-HUD_MAX_NUM_DISP<0)?0:HUD_nmessages-HUD_MAX_NUM_DISP);
|
2006-03-20 17:12:09 +00:00
|
|
|
if (HUD_color == -1)
|
|
|
|
HUD_color = BM_XRGB(0,28,0);
|
|
|
|
|
2008-02-24 14:41:27 +00:00
|
|
|
gr_set_curfont( GAME_FONT );
|
|
|
|
y = FSPACY(1);
|
2007-06-14 20:52:14 +00:00
|
|
|
|
|
|
|
if (Guided_missile[Player_num] && Guided_missile[Player_num]->type==OBJ_WEAPON && Guided_missile[Player_num]->id==GUIDEDMISS_ID &&
|
2008-04-13 00:28:36 +00:00
|
|
|
Guided_missile[Player_num]->signature==Guided_missile_sig[Player_num] && PlayerCfg.GuidedInBigWindow)
|
2008-02-24 14:41:27 +00:00
|
|
|
y+=LINE_SPACING;
|
2007-06-14 20:52:14 +00:00
|
|
|
|
2010-07-13 06:35:25 +00:00
|
|
|
for (i=startmsg; i<HUD_nmessages; i++ ) {
|
2007-06-14 20:52:14 +00:00
|
|
|
gr_set_fontcolor( HUD_color, -1);
|
|
|
|
|
2010-07-13 06:35:25 +00:00
|
|
|
if (i == startmsg && strlen(HUD_messages[i].message) > 38)
|
|
|
|
HUD_toolong = 1;
|
|
|
|
gr_printf(0x8000,y, &HUD_messages[i].message[0] );
|
2008-02-24 14:41:27 +00:00
|
|
|
y += LINE_SPACING;
|
2006-03-20 17:12:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
gr_set_curfont( GAME_FONT );
|
|
|
|
}
|
|
|
|
|
|
|
|
// Call to flash a message on the HUD. Returns true if message drawn.
|
|
|
|
// (message might not be drawn if previous message was same)
|
2010-11-21 20:20:00 +00:00
|
|
|
int HUD_init_message_va(int class_flag, char * format, va_list args)
|
2006-03-20 17:12:09 +00:00
|
|
|
{
|
2010-07-13 06:35:25 +00:00
|
|
|
int i, j;
|
2010-10-10 10:48:24 +00:00
|
|
|
#ifndef macintosh
|
2010-07-13 06:35:25 +00:00
|
|
|
char message[HUD_MESSAGE_LENGTH+1] = "";
|
2010-10-10 10:48:24 +00:00
|
|
|
#else
|
|
|
|
char message[1024] = "";
|
|
|
|
#endif
|
2006-03-20 17:12:09 +00:00
|
|
|
|
2010-10-10 10:48:24 +00:00
|
|
|
#ifndef macintosh
|
2010-07-13 06:35:25 +00:00
|
|
|
vsnprintf(message, sizeof(char)*HUD_MESSAGE_LENGTH, format, args);
|
2010-10-10 10:48:24 +00:00
|
|
|
#else
|
|
|
|
vsprintf(message, format, args);
|
|
|
|
#endif
|
2006-03-20 17:12:09 +00:00
|
|
|
|
2010-11-21 20:20:00 +00:00
|
|
|
|
|
|
|
// check if message is already in list and bail out if so
|
|
|
|
if (HUD_nmessages > 0)
|
2010-07-13 06:35:25 +00:00
|
|
|
{
|
2011-04-11 19:27:31 +00:00
|
|
|
// if "normal" message, only check if it's the same at the most recent one, if marked as "may duplicate" check whole list
|
|
|
|
for (i = ((class_flag & HM_MAYDUPL)?0:HUD_nmessages-1); i < HUD_nmessages; i++)
|
2010-07-13 06:35:25 +00:00
|
|
|
{
|
2012-05-18 23:36:43 +00:00
|
|
|
if (!d_strnicmp(message, HUD_messages[i].message, sizeof(char)*HUD_MESSAGE_LENGTH))
|
2010-11-21 20:20:00 +00:00
|
|
|
{
|
|
|
|
HUD_messages[i].time = F1_0*2; // keep redundant message in list
|
|
|
|
if (i >= HUD_nmessages-HUD_MAX_NUM_DISP) // if redundant message on display, update them all
|
|
|
|
for (i = (HUD_nmessages-HUD_MAX_NUM_DISP<0?0:HUD_nmessages-HUD_MAX_NUM_DISP), j = 1; i < HUD_nmessages; i++, j++)
|
|
|
|
HUD_messages[i].time = F1_0*(j*2);
|
|
|
|
return 0;
|
|
|
|
}
|
2010-07-13 06:35:25 +00:00
|
|
|
}
|
|
|
|
}
|
2006-03-20 17:12:09 +00:00
|
|
|
|
2010-07-13 06:35:25 +00:00
|
|
|
// HACK!!!
|
2007-04-21 08:27:21 +00:00
|
|
|
// clean message if necessary.
|
|
|
|
// using placeholders may mess up message string and crash game(s).
|
|
|
|
// block them also to prevent attacks from other clients.
|
|
|
|
for (i = 0; i <= strlen(message); i++)
|
|
|
|
if (message[i] == '%')
|
|
|
|
message [i] = ' ';
|
|
|
|
|
2010-07-13 06:35:25 +00:00
|
|
|
if (HUD_nmessages >= HUD_MAX_NUM_STOR)
|
|
|
|
{
|
|
|
|
HUD_nmessages = HUD_MAX_NUM_STOR; // unnecessary but just in case it might be bigger... which is impossible
|
|
|
|
for (i = 0; i < HUD_nmessages-1; i++)
|
|
|
|
{
|
|
|
|
memcpy(&HUD_messages[i], &HUD_messages[i+1], sizeof(struct hudmsg));
|
|
|
|
}
|
2006-03-20 17:12:09 +00:00
|
|
|
}
|
2010-07-13 06:35:25 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
HUD_nmessages++;
|
2006-03-20 17:12:09 +00:00
|
|
|
}
|
2010-10-14 14:46:20 +00:00
|
|
|
snprintf(HUD_messages[HUD_nmessages-1].message, sizeof(char)*HUD_MESSAGE_LENGTH, "%s", message);
|
2010-07-13 06:35:25 +00:00
|
|
|
if (HUD_nmessages-HUD_MAX_NUM_DISP < 0)
|
|
|
|
HUD_messages[HUD_nmessages-1].time = F1_0*3; // one message - display 3 secs
|
|
|
|
else
|
|
|
|
for (i = HUD_nmessages-HUD_MAX_NUM_DISP, j = 1; i < HUD_nmessages; i++, j++) // multiple messages - display 2 seconds each
|
|
|
|
HUD_messages[i].time = F1_0*(j*2);
|
|
|
|
|
2007-01-14 01:55:59 +00:00
|
|
|
|
2007-08-26 11:46:10 +00:00
|
|
|
if (HUD_color == -1)
|
|
|
|
HUD_color = BM_XRGB(0,28,0);
|
2008-04-06 20:23:28 +00:00
|
|
|
con_printf(CON_HUD, "%s\n", message);
|
2007-08-26 11:46:10 +00:00
|
|
|
|
2006-03-20 17:12:09 +00:00
|
|
|
if (Newdemo_state == ND_STATE_RECORDING )
|
|
|
|
newdemo_record_hud_message( message );
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-07-13 06:35:25 +00:00
|
|
|
int HUD_init_message(int class_flag, char * format, ... )
|
2006-03-20 17:12:09 +00:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
va_list args;
|
|
|
|
|
2011-01-03 01:01:26 +00:00
|
|
|
if (PlayerCfg.NoRedundancy && class_flag & HM_REDUNDANT)
|
2010-07-13 06:35:25 +00:00
|
|
|
return 0;
|
|
|
|
|
2011-06-23 07:24:00 +00:00
|
|
|
if (PlayerCfg.MultiMessages && Game_mode & GM_MULTI && !(class_flag & HM_MULTI))
|
2010-07-13 06:35:25 +00:00
|
|
|
return 0;
|
|
|
|
|
2006-03-20 17:12:09 +00:00
|
|
|
va_start(args, format);
|
2010-11-21 20:20:00 +00:00
|
|
|
ret = HUD_init_message_va(class_flag, format, args);
|
2006-03-20 17:12:09 +00:00
|
|
|
va_end(args);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void player_dead_message(void)
|
|
|
|
{
|
2008-02-24 14:41:27 +00:00
|
|
|
if (Player_exploded) {
|
|
|
|
if ( Players[Player_num].lives < 2 ) {
|
|
|
|
int x, y, w, h, aw;
|
|
|
|
gr_set_curfont( HUGE_FONT );
|
|
|
|
gr_get_string_size( TXT_GAME_OVER, &w, &h, &aw );
|
|
|
|
w += 20;
|
|
|
|
h += 8;
|
|
|
|
x = (grd_curcanv->cv_bitmap.bm_w - w ) / 2;
|
|
|
|
y = (grd_curcanv->cv_bitmap.bm_h - h ) / 2;
|
|
|
|
|
2011-02-23 16:46:39 +00:00
|
|
|
gr_settransblend(14, GR_BLEND_NORMAL);
|
2008-02-24 14:41:27 +00:00
|
|
|
gr_setcolor( BM_XRGB(0,0,0) );
|
|
|
|
gr_rect( x, y, x+w, y+h );
|
2011-02-23 16:46:39 +00:00
|
|
|
gr_settransblend(GR_FADE_OFF, GR_BLEND_NORMAL);
|
2008-02-24 14:41:27 +00:00
|
|
|
|
|
|
|
gr_printf(0x8000, (GHEIGHT - h)/2 + h/8, TXT_GAME_OVER );
|
|
|
|
}
|
|
|
|
|
|
|
|
gr_set_curfont( GAME_FONT );
|
|
|
|
if (HUD_color == -1)
|
|
|
|
HUD_color = BM_XRGB(0,28,0);
|
|
|
|
gr_set_fontcolor( HUD_color, -1);
|
|
|
|
gr_printf(0x8000, GHEIGHT-LINE_SPACING, TXT_PRESS_ANY_KEY);
|
|
|
|
}
|
2006-03-20 17:12:09 +00:00
|
|
|
}
|