rockbox/apps/plugins/doom/hu_stuff.c
Michael Sevakis aced667f48 Undo hacks to meant to get around string formatting limitations
The new vuprintf makes unnecessary workarounds due to formatting
limitations. I checked grep output for whatever appeared to fit
but it's possible I missed some instances because they weren't
so obvious.

Also, this means sound settings can dynamically work with any
number of decimals rather than the current assumption of one or
two. Add an ipow() function to help and take advantage of dynamic
field width and precision. Consolidate string formatting of sound
settings.

Change-Id: I46caf534859dfd1916cd440cd25e5206b192fcd8
2017-11-21 05:01:14 -05:00

1590 lines
49 KiB
C

/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION: Heads-up displays
*
*-----------------------------------------------------------------------------
*/
// killough 5/3/98: remove unnecessary headers
#include "doomstat.h"
#include "hu_stuff.h"
#include "hu_lib.h"
#include "st_stuff.h" /* jff 2/16/98 need loc of status bar */
#include "w_wad.h"
#include "s_sound.h"
#include "dstrings.h"
#include "sounds.h"
//#include "d_deh.h" /* Ty 03/27/98 - externalization of mapnamesx arrays */
#include "g_game.h"
#include "m_swap.h"
// global heads up display controls
int hud_active; //jff 2/17/98 controls heads-up display mode
int hud_displayed; //jff 2/23/98 turns heads-up display on/off
int hud_nosecrets; //jff 2/18/98 allows secrets line to be disabled in HUD
int hud_distributed; //jff 3/4/98 display HUD in different places on screen
int hud_graph_keys=1; //jff 3/7/98 display HUD keys as graphics
//
// Locally used constants, shortcuts.
//
// Ty 03/28/98 -
// These four shortcuts modifed to reflect char ** of mapnamesx[]
#define HU_TITLE (*mapnames[(gameepisode-1)*9+gamemap-1])
#define HU_TITLE2 (*mapnames2[gamemap-1])
#define HU_TITLEP (*mapnamesp[gamemap-1])
#define HU_TITLET (*mapnamest[gamemap-1])
#define HU_TITLEHEIGHT 1
#define HU_TITLEX 0
//jff 2/16/98 change 167 to ST_Y-1
// CPhipps - changed to ST_TY
// proff - changed to 200-ST_HEIGHT for stretching
#define HU_TITLEY ((200-ST_HEIGHT) - 1 - SHORT(hu_font[0].height))
//jff 2/16/98 add coord text widget coordinates
// proff - changed to SCREENWIDTH to 320 for stretching
#define HU_COORDX (320 - 13*SHORT(hu_font2['A'-HU_FONTSTART].width))
//jff 3/3/98 split coord widget into three lines in upper right of screen
#define HU_COORDX_Y (1 + 0*SHORT(hu_font['A'-HU_FONTSTART].height))
#define HU_COORDY_Y (2 + 1*SHORT(hu_font['A'-HU_FONTSTART].height))
#define HU_COORDZ_Y (3 + 2*SHORT(hu_font['A'-HU_FONTSTART].height))
//jff 2/16/98 add ammo, health, armor widgets, 2/22/98 less gap
#define HU_GAPY 8
#define HU_HUDHEIGHT (6*HU_GAPY)
#define HU_HUDX 2
#define HU_HUDY (200-HU_HUDHEIGHT-1)
#define HU_MONSECX (HU_HUDX)
#define HU_MONSECY (HU_HUDY+0*HU_GAPY)
#define HU_KEYSX (HU_HUDX)
//jff 3/7/98 add offset for graphic key widget
#define HU_KEYSGX (HU_HUDX+4*SHORT(hu_font2['A'-HU_FONTSTART].width))
#define HU_KEYSY (HU_HUDY+1*HU_GAPY)
#define HU_WEAPX (HU_HUDX)
#define HU_WEAPY (HU_HUDY+2*HU_GAPY)
#define HU_AMMOX (HU_HUDX)
#define HU_AMMOY (HU_HUDY+3*HU_GAPY)
#define HU_HEALTHX (HU_HUDX)
#define HU_HEALTHY (HU_HUDY+4*HU_GAPY)
#define HU_ARMORX (HU_HUDX)
#define HU_ARMORY (HU_HUDY+5*HU_GAPY)
//jff 3/4/98 distributed HUD positions
#define HU_HUDX_LL 2
#define HU_HUDY_LL (200-2*HU_GAPY-1)
// proff/nicolas 09/20/98: Changed for high-res
#define HU_HUDX_LR (320-120)
#define HU_HUDY_LR (200-2*HU_GAPY-1)
// proff/nicolas 09/20/98: Changed for high-res
#define HU_HUDX_UR (320-96)
#define HU_HUDY_UR 2
#define HU_MONSECX_D (HU_HUDX_LL)
#define HU_MONSECY_D (HU_HUDY_LL+0*HU_GAPY)
#define HU_KEYSX_D (HU_HUDX_LL)
#define HU_KEYSGX_D (HU_HUDX_LL+4*SHORT(hu_font2['A'-HU_FONTSTART].width))
#define HU_KEYSY_D (HU_HUDY_LL+1*HU_GAPY)
#define HU_WEAPX_D (HU_HUDX_LR)
#define HU_WEAPY_D (HU_HUDY_LR+0*HU_GAPY)
#define HU_AMMOX_D (HU_HUDX_LR)
#define HU_AMMOY_D (HU_HUDY_LR+1*HU_GAPY)
#define HU_HEALTHX_D (HU_HUDX_UR)
#define HU_HEALTHY_D (HU_HUDY_UR+0*HU_GAPY)
#define HU_ARMORX_D (HU_HUDX_UR)
#define HU_ARMORY_D (HU_HUDY_UR+1*HU_GAPY)
//#define HU_INPUTTOGGLE 't' // not used // phares
#define HU_INPUTX HU_MSGX
#define HU_INPUTY (HU_MSGY + HU_MSGHEIGHT*(SHORT(hu_font[0].height) +1))
#define HU_INPUTWIDTH 64
#define HU_INPUTHEIGHT 1
#define key_alt KEY_RALT
#define key_shift KEY_RSHIFT
const char* chat_macros[] =
// Ty 03/27/98 - *not* externalized
// CPhipps - const char*
{
HUSTR_CHATMACRO1,
HUSTR_CHATMACRO1,
HUSTR_CHATMACRO1,
HUSTR_CHATMACRO1,
HUSTR_CHATMACRO1,
HUSTR_CHATMACRO1,
HUSTR_CHATMACRO1,
HUSTR_CHATMACRO1,
HUSTR_CHATMACRO1,
HUSTR_CHATMACRO1
};
const char* player_names[] =
// Ty 03/27/98 - *not* externalized
// CPhipps - const char*
{
HUSTR_PLRGREEN,
HUSTR_PLRINDIGO,
HUSTR_PLRBROWN,
HUSTR_PLRRED
};
//jff 3/17/98 translate player colmap to text color ranges
int plyrcoltran[MAXPLAYERS]={CR_GREEN,CR_GRAY,CR_BROWN,CR_RED};
char chat_char; // remove later.
static player_t* plr;
// font sets
patchnum_t hu_font[HU_FONTSIZE];
patchnum_t *hu_font2;
patchnum_t *hu_fontk;//jff 3/7/98 added for graphic key indicators
patchnum_t hu_msgbg[9]; //jff 2/26/98 add patches for message background
// widgets
static hu_textline_t w_title;
static hu_stext_t w_message;
static hu_itext_t w_chat;
static hu_itext_t w_inputbuffer[MAXPLAYERS];
static hu_textline_t w_coordx; //jff 2/16/98 new coord widget for automap
static hu_textline_t w_coordy; //jff 3/3/98 split coord widgets automap
static hu_textline_t w_coordz; //jff 3/3/98 split coord widgets automap
static hu_textline_t w_ammo; //jff 2/16/98 new ammo widget for hud
static hu_textline_t w_health; //jff 2/16/98 new health widget for hud
static hu_textline_t w_armor; //jff 2/16/98 new armor widget for hud
static hu_textline_t w_weapon; //jff 2/16/98 new weapon widget for hud
static hu_textline_t w_keys; //jff 2/16/98 new keys widget for hud
static hu_textline_t w_gkeys; //jff 3/7/98 graphic keys widget for hud
static hu_textline_t w_monsec; //jff 2/16/98 new kill/secret widget for hud
static hu_mtext_t w_rtext; //jff 2/26/98 text message refresh widget
static boolean always_off = false;
static char chat_dest[MAXPLAYERS];
boolean chat_on;
static boolean message_on;
static boolean message_list; //2/26/98 enable showing list of messages
boolean message_dontfuckwithme;
static boolean message_nottobefuckedwith;
static int message_counter;
extern int showMessages;
extern boolean automapactive;
static boolean headsupactive = false;
//jff 2/16/98 hud supported automap colors added
int hudcolor_titl; // color range of automap level title
int hudcolor_xyco; // color range of new coords on automap
//jff 2/16/98 hud text colors, controls added
int hudcolor_mesg; // color range of scrolling messages
int hudcolor_chat; // color range of chat lines
int hud_msg_lines; // number of message lines in window
//jff 2/26/98 hud text colors, controls added
int hudcolor_list; // list of messages color
int hud_list_bgon; // enable for solid window background for message list
//jff 2/16/98 initialization strings for ammo, health, armor widgets
static char *hud_coordstrx;
static char *hud_coordstry;
static char *hud_coordstrz;
static char *hud_ammostr;
static char *hud_healthstr;
static char *hud_armorstr;
static char *hud_weapstr;
static char *hud_keysstr;
static char *hud_gkeysstr; //jff 3/7/98 add support for graphic key display
static char *hud_monsecstr;
//jff 2/16/98 declaration of color switch points
extern int ammo_red;
extern int ammo_yellow;
extern int health_red;
extern int health_yellow;
extern int health_green;
extern int armor_red;
extern int armor_yellow;
extern int armor_green;
// key tables
// jff 5/10/98 french support removed,
// as it was not being used and couldn't be easily tested
//
const char* shiftxform;
const char english_shiftxform[] =
{
0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31,
' ', '!', '"', '#', '$', '%', '&',
'"', // shift-'
'(', ')', '*', '+',
'<', // shift-,
'_', // shift--
'>', // shift-.
'?', // shift-/
')', // shift-0
'!', // shift-1
'@', // shift-2
'#', // shift-3
'$', // shift-4
'%', // shift-5
'^', // shift-6
'&', // shift-7
'*', // shift-8
'(', // shift-9
':',
':', // shift-;
'<',
'+', // shift-=
'>', '?', '@',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'[', // shift-[
'!', // shift-backslash - OH MY GOD DOES WATCOM SUCK
']', // shift-]
'"', '_',
'\'', // shift-`
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'{', '|', '}', '~', 127
};
//
// HU_Init()
//
// Initialize the heads-up display, text that overwrites the primary display
//
// Passed nothing, returns nothing
//
void HU_Init(void)
{
int i;
int j;
char buffer[9];
shiftxform = english_shiftxform;
// malloc all the strings, trying to get size down
hud_ammostr=malloc(80*sizeof(char));
hud_healthstr=malloc(80*sizeof(char));
hud_armorstr=malloc(80*sizeof(char));
hud_weapstr=malloc(80*sizeof(char));
hud_keysstr=malloc(80*sizeof(char));
hud_gkeysstr=malloc(80*sizeof(char));
hud_monsecstr=malloc(80*sizeof(char));
hud_coordstrx=malloc(32*sizeof(char));
hud_coordstry=malloc(32*sizeof(char));
hud_coordstrz=malloc(32*sizeof(char));
hu_fontk=malloc(HU_FONTSIZE*sizeof(patchnum_t));
hu_font2=malloc(HU_FONTSIZE*sizeof(patchnum_t));
// load the heads-up font
j = HU_FONTSTART;
for (i=0;i<HU_FONTSIZE;i++,j++)
{
if ('0'<=j && j<='9')
{
snprintf(buffer, sizeof(buffer), "DIG%d",j-48);
R_SetPatchNum(hu_font2 +i, buffer);
snprintf(buffer, sizeof(buffer), "STCFN%.3d", j);
R_SetPatchNum(&hu_font[i], buffer);
}
else if ('A'<=j && j<='Z')
{
snprintf(buffer, sizeof(buffer), "DIG%c",j);
R_SetPatchNum(hu_font2 +i, buffer);
snprintf(buffer, sizeof(buffer), "STCFN%.3d", j);
R_SetPatchNum(&hu_font[i], buffer);
}
else if (j=='-')
{
R_SetPatchNum(hu_font2 +i, "DIG45");
R_SetPatchNum(&hu_font[i], "STCFN045");
}
else if (j=='/')
{
R_SetPatchNum(hu_font2 +i, "DIG47");
R_SetPatchNum(&hu_font[i], "STCFN047");
}
else if (j==':')
{
R_SetPatchNum(hu_font2 +i, "DIG58");
R_SetPatchNum(&hu_font[i], "STCFN058");
}
else if (j=='[')
{
R_SetPatchNum(hu_font2 +i, "DIG91");
R_SetPatchNum(&hu_font[i], "STCFN091");
}
else if (j==']')
{
R_SetPatchNum(hu_font2 +i, "DIG93");
R_SetPatchNum(&hu_font[i], "STCFN093");
}
else if (j<97)
{
snprintf(buffer, sizeof(buffer), "STCFN%.3d", j);
R_SetPatchNum(hu_font2 +i, buffer);
R_SetPatchNum(&hu_font[i], buffer);
//jff 2/23/98 make all font chars defined, useful or not
}
else if (j>122)
{
snprintf(buffer, sizeof(buffer), "STBR%.3d", j);
R_SetPatchNum(hu_font2 +i, buffer);
R_SetPatchNum(&hu_font[i], buffer);
}
else
hu_font[i] = hu_font[0]; //jff 2/16/98 account for gap
}
// CPhipps - load patches for message background
for (i=0; i<9; i++) {
snprintf(buffer, sizeof(buffer), "BOX%c%c", "UCL"[i/3], "LCR"[i%3]);
R_SetPatchNum(&hu_msgbg[i], buffer);
}
// CPhipps - load patches for keys and double keys
for (i=0; i<6; i++) {
snprintf(buffer, sizeof(buffer), "STKEYS%d", i);
R_SetPatchNum(hu_fontk+i, buffer);
}
}
//
// HU_Stop()
//
// Make the heads-up displays inactive
//
// Passed nothing, returns nothing
//
void HU_Stop(void)
{
headsupactive = false;
}
//
// HU_Start(void)
//
// Create and initialize the heads-up widgets, software machines to
// maintain, update, and display information over the primary display
//
// This routine must be called after any change to the heads up configuration
// in order for the changes to take effect in the actual displays
//
// Passed nothing, returns nothing
//
void HU_Start(void)
{
int i;
const char* s; /* cph - const */
if (headsupactive) // stop before starting
HU_Stop();
plr = &players[displayplayer]; // killough 3/7/98
message_on = false;
message_dontfuckwithme = false;
message_nottobefuckedwith = false;
chat_on = false;
// create the message widget
// messages to player in upper-left of screen
HUlib_initSText
(
&w_message,
HU_MSGX,
HU_MSGY,
HU_MSGHEIGHT,
hu_font,
HU_FONTSTART,
hudcolor_mesg,
&message_on
);
//jff 2/16/98 added some HUD widgets
// create the map title widget - map title display in lower left of automap
HUlib_initTextLine
(
&w_title,
HU_TITLEX,
HU_TITLEY,
hu_font,
HU_FONTSTART,
hudcolor_titl
);
// create the hud health widget
// bargraph and number for amount of health,
// lower left or upper right of screen
HUlib_initTextLine
(
&w_health,
hud_distributed? HU_HEALTHX_D : HU_HEALTHX, //3/4/98 distribute
hud_distributed? HU_HEALTHY_D : HU_HEALTHY,
hu_font2,
HU_FONTSTART,
CR_GREEN
);
// create the hud armor widget
// bargraph and number for amount of armor,
// lower left or upper right of screen
HUlib_initTextLine
(
&w_armor,
hud_distributed? HU_ARMORX_D : HU_ARMORX, //3/4/98 distribute
hud_distributed? HU_ARMORY_D : HU_ARMORY,
hu_font2,
HU_FONTSTART,
CR_GREEN
);
// create the hud ammo widget
// bargraph and number for amount of ammo for current weapon,
// lower left or lower right of screen
HUlib_initTextLine
(
&w_ammo,
hud_distributed? HU_AMMOX_D : HU_AMMOX, //3/4/98 distribute
hud_distributed? HU_AMMOY_D : HU_AMMOY,
hu_font2,
HU_FONTSTART,
CR_GOLD
);
// create the hud weapons widget
// list of numbers of weapons possessed
// lower left or lower right of screen
HUlib_initTextLine
(
&w_weapon,
hud_distributed? HU_WEAPX_D : HU_WEAPX, //3/4/98 distribute
hud_distributed? HU_WEAPY_D : HU_WEAPY,
hu_font2,
HU_FONTSTART,
CR_GRAY
);
// create the hud keys widget
// display of key letters possessed
// lower left of screen
HUlib_initTextLine
(
&w_keys,
hud_distributed? HU_KEYSX_D : HU_KEYSX, //3/4/98 distribute
hud_distributed? HU_KEYSY_D : HU_KEYSY,
hu_font2,
HU_FONTSTART,
CR_GRAY
);
// create the hud graphic keys widget
// display of key graphics possessed
// lower left of screen
HUlib_initTextLine
(
&w_gkeys,
hud_distributed? HU_KEYSGX_D : HU_KEYSGX, //3/4/98 distribute
hud_distributed? HU_KEYSY_D : HU_KEYSY,
hu_fontk,
HU_FONTSTART,
CR_RED
);
// create the hud monster/secret widget
// totals and current values for kills, items, secrets
// lower left of screen
HUlib_initTextLine
(
&w_monsec,
hud_distributed? HU_MONSECX_D : HU_MONSECX, //3/4/98 distribute
hud_distributed? HU_MONSECY_D : HU_MONSECY,
hu_font2,
HU_FONTSTART,
CR_GRAY
);
// create the hud text refresh widget
// scrolling display of last hud_msg_lines messages received
if (hud_msg_lines>HU_MAXMESSAGES)
hud_msg_lines=HU_MAXMESSAGES;
//jff 4/21/98 if setup has disabled message list while active, turn it off
message_list = hud_msg_lines > 1; //jff 8/8/98 initialize both ways
//jff 2/26/98 add the text refresh widget initialization
HUlib_initMText
(
&w_rtext,
0,
0,
320,
// SCREENWIDTH,
(hud_msg_lines+2)*HU_REFRESHSPACING,
hu_font,
HU_FONTSTART,
hudcolor_list,
hu_msgbg,
&message_list
);
// initialize the automap's level title widget
if (gamestate == GS_LEVEL) /* cph - stop SEGV here when not in level */
switch (gamemode)
{
case shareware:
case registered:
case retail:
s = HU_TITLE;
break;
case commercial:
default: // Ty 08/27/98 - modified to check mission for TNT/Plutonia
s = (gamemission==pack_tnt) ? HU_TITLET :
(gamemission==pack_plut) ? HU_TITLEP : HU_TITLE2;
break;
} else s = "";
while (*s)
HUlib_addCharToTextLine(&w_title, *(s++));
// create the automaps coordinate widget
// jff 3/3/98 split coord widget into three lines: x,y,z
// jff 2/16/98 added
HUlib_initTextLine
(
&w_coordx,
HU_COORDX,
HU_COORDX_Y,
hu_font,
HU_FONTSTART,
hudcolor_xyco
);
HUlib_initTextLine
(
&w_coordy,
HU_COORDX,
HU_COORDY_Y,
hu_font,
HU_FONTSTART,
hudcolor_xyco
);
HUlib_initTextLine
(
&w_coordz,
HU_COORDX,
HU_COORDZ_Y,
hu_font,
HU_FONTSTART,
hudcolor_xyco
);
// initialize the automaps coordinate widget
//jff 3/3/98 split coordstr widget into 3 parts
snprintf(hud_coordstrx,32*sizeof(char),"X: %d",0); //jff 2/22/98 added z
s = hud_coordstrx;
while (*s)
HUlib_addCharToTextLine(&w_coordx, *(s++));
snprintf(hud_coordstry,32*sizeof(char),"Y: %d",0); //jff 3/3/98 split x,y,z
s = hud_coordstry;
while (*s)
HUlib_addCharToTextLine(&w_coordy, *(s++));
snprintf(hud_coordstrz,32*sizeof(char),"Z: %d",0); //jff 3/3/98 split x,y,z
s = hud_coordstrz;
while (*s)
HUlib_addCharToTextLine(&w_coordz, *(s++));
//jff 2/16/98 initialize ammo widget
strcpy(hud_ammostr,"AMM ");
s = hud_ammostr;
while (*s)
HUlib_addCharToTextLine(&w_ammo, *(s++));
//jff 2/16/98 initialize health widget
strcpy(hud_healthstr,"HEL ");
s = hud_healthstr;
while (*s)
HUlib_addCharToTextLine(&w_health, *(s++));
//jff 2/16/98 initialize armor widget
strcpy(hud_armorstr,"ARM ");
s = hud_armorstr;
while (*s)
HUlib_addCharToTextLine(&w_armor, *(s++));
//jff 2/17/98 initialize weapons widget
strcpy(hud_weapstr,"WEA ");
s = hud_weapstr;
while (*s)
HUlib_addCharToTextLine(&w_weapon, *(s++));
//jff 2/17/98 initialize keys widget
if (!deathmatch) //jff 3/17/98 show frags in deathmatch mode
strcpy(hud_keysstr,"KEY ");
else
strcpy(hud_keysstr,"FRG ");
s = hud_keysstr;
while (*s)
HUlib_addCharToTextLine(&w_keys, *(s++));
//jff 2/17/98 initialize graphic keys widget
strcpy(hud_gkeysstr," ");
s = hud_gkeysstr;
while (*s)
HUlib_addCharToTextLine(&w_gkeys, *(s++));
//jff 2/17/98 initialize kills/items/secret widget
strcpy(hud_monsecstr,"STS ");
s = hud_monsecstr;
while (*s)
HUlib_addCharToTextLine(&w_monsec, *(s++));
// create the chat widget
HUlib_initIText
(
&w_chat,
HU_INPUTX,
HU_INPUTY,
hu_font,
HU_FONTSTART,
hudcolor_chat,
&chat_on
);
// create the inputbuffer widgets, one per player
for (i=0 ; i<MAXPLAYERS ; i++)
HUlib_initIText
(
&w_inputbuffer[i],
0,
0,
0,
0,
hudcolor_chat,
&always_off
);
// now allow the heads-up display to run
headsupactive = true;
}
//
// HU_MoveHud()
//
// Move the HUD display from distributed to compact mode or vice-versa
//
// Passed nothing, returns nothing
//
//jff 3/9/98 create this externally callable to avoid glitch
// when menu scatter's HUD due to delay in change of position
//
void HU_MoveHud(void)
{
static int ohud_distributed=-1;
//jff 3/4/98 move displays around on F5 changing hud_distributed
if (hud_distributed!=ohud_distributed)
{
w_ammo.x = hud_distributed? HU_AMMOX_D : HU_AMMOX;
w_ammo.y = hud_distributed? HU_AMMOY_D : HU_AMMOY;
w_weapon.x = hud_distributed? HU_WEAPX_D : HU_WEAPX;
w_weapon.y = hud_distributed? HU_WEAPY_D : HU_WEAPY;
w_keys.x = hud_distributed? HU_KEYSX_D : HU_KEYSX;
w_keys.y = hud_distributed? HU_KEYSY_D : HU_KEYSY;
w_gkeys.x = hud_distributed? HU_KEYSGX_D : HU_KEYSGX;
w_gkeys.y = hud_distributed? HU_KEYSY_D : HU_KEYSY;
w_monsec.x = hud_distributed? HU_MONSECX_D : HU_MONSECX;
w_monsec.y = hud_distributed? HU_MONSECY_D : HU_MONSECY;
w_health.x = hud_distributed? HU_HEALTHX_D : HU_HEALTHX;
w_health.y = hud_distributed? HU_HEALTHY_D : HU_HEALTHY;
w_armor.x = hud_distributed? HU_ARMORX_D : HU_ARMORX;
w_armor.y = hud_distributed? HU_ARMORY_D : HU_ARMORY;
}
ohud_distributed = hud_distributed;
}
//
// HU_Drawer()
//
// Draw all the pieces of the heads-up display
//
// Passed nothing, returns nothing
//
void HU_Drawer(void)
{
char *s;
player_t *plr;
char ammostr[80]; //jff 3/8/98 allow plenty room for dehacked mods
char healthstr[80];//jff
char armorstr[80]; //jff
int i,doit;
plr = &players[displayplayer]; // killough 3/7/98
// draw the automap widgets if automap is displayed
if (automapmode & am_active)
{
// map title
HUlib_drawTextLine(&w_title, false);
//jff 2/16/98 output new coord display
// x-coord
snprintf(hud_coordstrx,32*sizeof(char),"X: %d", (plr->mo->x)>>FRACBITS);
HUlib_clearTextLine(&w_coordx);
s = hud_coordstrx;
while (*s)
HUlib_addCharToTextLine(&w_coordx, *(s++));
HUlib_drawTextLine(&w_coordx, false);
//jff 3/3/98 split coord display into x,y,z lines
// y-coord
snprintf(hud_coordstry,32*sizeof(char),"Y: %d", (plr->mo->y)>>FRACBITS);
HUlib_clearTextLine(&w_coordy);
s = hud_coordstry;
while (*s)
HUlib_addCharToTextLine(&w_coordy, *(s++));
HUlib_drawTextLine(&w_coordy, false);
//jff 3/3/98 split coord display into x,y,z lines
//jff 2/22/98 added z
// z-coord
snprintf(hud_coordstrz,32*sizeof(char),"Z: %d", (plr->mo->z)>>FRACBITS);
HUlib_clearTextLine(&w_coordz);
s = hud_coordstrz;
while (*s)
HUlib_addCharToTextLine(&w_coordz, *(s++));
HUlib_drawTextLine(&w_coordz, false);
}
// draw the weapon/health/ammo/armor/kills/keys displays if optioned
//jff 2/17/98 allow new hud stuff to be turned off
// killough 2/21/98: really allow new hud stuff to be turned off COMPLETELY
if
(
hud_active>0 && // hud optioned on
hud_displayed && // hud on from fullscreen key
viewheight==SCREENHEIGHT && // fullscreen mode is active
!(automapmode & am_active) // automap is not active
)
{
doit = !(gametic&1); //jff 3/4/98 speed update up for slow systems
if (doit) //jff 8/7/98 update every time, avoid lag in update
{
HU_MoveHud(); // insure HUD display coords are correct
// do the hud ammo display
// clear the widgets internal line
HUlib_clearTextLine(&w_ammo);
strcpy(hud_ammostr,"AMM ");
if (weaponinfo[plr->readyweapon].ammo == am_noammo)
{ // special case for weapon with no ammo selected - blank bargraph + N/A
strcat(hud_ammostr,"\x7f\x7f\x7f\x7f\x7f\x7f\x7f N/A");
w_ammo.cm = CR_GRAY;
}
else
{
int ammo = plr->ammo[weaponinfo[plr->readyweapon].ammo];
int fullammo = plr->maxammo[weaponinfo[plr->readyweapon].ammo];
int ammopct = (100*ammo)/fullammo;
int ammobars = ammopct/4;
// build the numeric amount init string
snprintf(ammostr,sizeof(ammostr),"%d/%d",ammo,fullammo);
// build the bargraph string
// full bargraph chars
for (i=4;i<4+ammobars/4;)
hud_ammostr[i++] = 123;
// plus one last character with 0,1,2,3 bars
switch(ammobars%4)
{
case 0:
break;
case 1:
hud_ammostr[i++] = 126;
break;
case 2:
hud_ammostr[i++] = 125;
break;
case 3:
hud_ammostr[i++] = 124;
break;
}
// pad string with blank bar characters
while(i<4+7)
hud_ammostr[i++] = 127;
hud_ammostr[i] = '\0';
strcat(hud_ammostr,ammostr);
// set the display color from the percentage of total ammo held
if (ammopct<ammo_red)
w_ammo.cm = CR_RED;
else if (ammopct<ammo_yellow)
w_ammo.cm = CR_GOLD;
else
w_ammo.cm = CR_GREEN;
}
// transfer the init string to the widget
s = hud_ammostr;
while (*s)
HUlib_addCharToTextLine(&w_ammo, *(s++));
}
// display the ammo widget every frame
HUlib_drawTextLine(&w_ammo, false);
// do the hud health display
if (doit)
{
int health = plr->health;
int healthbars = health>100? 25 : health/4;
// clear the widgets internal line
HUlib_clearTextLine(&w_health);
// build the numeric amount init string
snprintf(healthstr,sizeof(healthstr),"%3d",health);
// build the bargraph string
// full bargraph chars
for (i=4;i<4+healthbars/4;)
hud_healthstr[i++] = 123;
// plus one last character with 0,1,2,3 bars
switch(healthbars%4)
{
case 0:
break;
case 1:
hud_healthstr[i++] = 126;
break;
case 2:
hud_healthstr[i++] = 125;
break;
case 3:
hud_healthstr[i++] = 124;
break;
}
// pad string with blank bar characters
while(i<4+7)
hud_healthstr[i++] = 127;
hud_healthstr[i] = '\0';
strcat(hud_healthstr,healthstr);
// set the display color from the amount of health posessed
if (health<health_red)
w_health.cm = CR_RED;
else if (health<health_yellow)
w_health.cm = CR_GOLD;
else if (health<=health_green)
w_health.cm = CR_GREEN;
else
w_health.cm = CR_BLUE;
// transfer the init string to the widget
s = hud_healthstr;
while (*s)
HUlib_addCharToTextLine(&w_health, *(s++));
}
// display the health widget every frame
HUlib_drawTextLine(&w_health, false);
// do the hud armor display
if (doit)
{
int armor = plr->armorpoints;
int armorbars = armor>100? 25 : armor/4;
// clear the widgets internal line
HUlib_clearTextLine(&w_armor);
// build the numeric amount init string
snprintf(armorstr,sizeof(armorstr),"%3d",armor);
// build the bargraph string
// full bargraph chars
for (i=4;i<4+armorbars/4;)
hud_armorstr[i++] = 123;
// plus one last character with 0,1,2,3 bars
switch(armorbars%4)
{
case 0:
break;
case 1:
hud_armorstr[i++] = 126;
break;
case 2:
hud_armorstr[i++] = 125;
break;
case 3:
hud_armorstr[i++] = 124;
break;
}
// pad string with blank bar characters
while(i<4+7)
hud_armorstr[i++] = 127;
hud_armorstr[i] = '\0';
strcat(hud_armorstr,armorstr);
// set the display color from the amount of armor posessed
if (armor<armor_red)
w_armor.cm = CR_RED;
else if (armor<armor_yellow)
w_armor.cm = CR_GOLD;
else if (armor<=armor_green)
w_armor.cm = CR_GREEN;
else
w_armor.cm = CR_BLUE;
// transfer the init string to the widget
s = hud_armorstr;
while (*s)
HUlib_addCharToTextLine(&w_armor, *(s++));
}
// display the armor widget every frame
HUlib_drawTextLine(&w_armor, false);
// do the hud weapon display
if (doit)
{
int w;
int ammo,fullammo,ammopct;
// clear the widgets internal line
HUlib_clearTextLine(&w_weapon);
i=4; hud_weapstr[i] = '\0'; //jff 3/7/98 make sure ammo goes away
// do each weapon that exists in current gamemode
for (w=0;w<=wp_supershotgun;w++) //jff 3/4/98 show fists too, why not?
{
int ok=1;
//jff avoid executing for weapons that do not exist
switch (gamemode)
{
case shareware:
if (w>=wp_plasma && w!=wp_chainsaw)
ok=0;
break;
case retail:
case registered:
if (w>=wp_supershotgun)
ok=0;
break;
default:
case commercial:
break;
}
if (!ok) continue;
ammo = plr->ammo[weaponinfo[w].ammo];
fullammo = plr->maxammo[weaponinfo[w].ammo];
ammopct=0;
// skip weapons not currently posessed
if (!plr->weaponowned[w])
continue;
ammopct = fullammo? (100*ammo)/fullammo : 100;
// display each weapon number in a color related to the ammo for it
hud_weapstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths
if (weaponinfo[w].ammo==am_noammo) //jff 3/14/98 show berserk on HUD
hud_weapstr[i++] = plr->powers[pw_strength]? '0'+CR_GREEN : '0'+CR_GRAY;
else if (ammopct<ammo_red)
hud_weapstr[i++] = '0'+CR_RED;
else if (ammopct<ammo_yellow)
hud_weapstr[i++] = '0'+CR_GOLD;
else
hud_weapstr[i++] = '0'+CR_GREEN;
hud_weapstr[i++] = '0'+w+1;
hud_weapstr[i++] = ' ';
hud_weapstr[i] = '\0';
}
// transfer the init string to the widget
s = hud_weapstr;
while (*s)
HUlib_addCharToTextLine(&w_weapon, *(s++));
}
// display the weapon widget every frame
HUlib_drawTextLine(&w_weapon, false);
if (doit && hud_active>1)
{
int k;
hud_keysstr[4] = '\0'; //jff 3/7/98 make sure deleted keys go away
//jff add case for graphic key display
if (!deathmatch && hud_graph_keys)
{
i=0;
hud_gkeysstr[i] = '\0'; //jff 3/7/98 init graphic keys widget string
// build text string whose characters call out graphic keys from fontk
for (k=0;k<6;k++)
{
// skip keys not possessed
if (!plr->cards[k])
continue;
hud_gkeysstr[i++] = '!'+k; // key number plus '!' is char for key
hud_gkeysstr[i++] = ' '; // spacing
hud_gkeysstr[i++] = ' ';
}
hud_gkeysstr[i]='\0';
}
else // not possible in current code, unless deathmatching,
{
i=4;
hud_keysstr[i] = '\0'; //jff 3/7/98 make sure deleted keys go away
// if deathmatch, build string showing top four frag counts
if (deathmatch) //jff 3/17/98 show frags, not keys, in deathmatch
{
int top1=-999,top2=-999,top3=-999,top4=-999;
int idx1=-1,idx2=-1,idx3=-1,idx4=-1;
int fragcount,m;
char numbuf[32];
// scan thru players
for (k=0;k<MAXPLAYERS;k++)
{
// skip players not in game
if (!playeringame[k])
continue;
fragcount = 0;
// compute number of times they've fragged each player
// minus number of times they've been fragged by them
for (m=0;m<MAXPLAYERS;m++)
{
if (!playeringame[m]) continue;
fragcount += (m!=k)? players[k].frags[m] : -players[k].frags[m];
}
// very primitive sort of frags to find top four
if (fragcount>top1)
{
top4=top3; top3=top2; top2 = top1; top1=fragcount;
idx4=idx3; idx3=idx2; idx2 = idx1; idx1=k;
}
else if (fragcount>top2)
{
top4=top3; top3=top2; top2=fragcount;
idx4=idx3; idx3=idx2; idx2=k;
}
else if (fragcount>top3)
{
top4=top3; top3=fragcount;
idx4=idx3; idx3=k;
}
else if (fragcount>top4)
{
top4=fragcount;
idx4=k;
}
}
// if the biggest number exists, put it in the init string
if (idx1>-1)
{
snprintf(numbuf,sizeof(numbuf),"%5d",top1);
// make frag count in player's color via escape code
hud_keysstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths
hud_keysstr[i++] = '0'+plyrcoltran[idx1&3];
s = numbuf;
while (*s)
hud_keysstr[i++] = *(s++);
}
// if the second biggest number exists, put it in the init string
if (idx2>-1)
{
snprintf(numbuf,sizeof(numbuf),"%5d",top2);
// make frag count in player's color via escape code
hud_keysstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths
hud_keysstr[i++] = '0'+plyrcoltran[idx2&3];
s = numbuf;
while (*s)
hud_keysstr[i++] = *(s++);
}
// if the third biggest number exists, put it in the init string
if (idx3>-1)
{
snprintf(numbuf,sizeof(numbuf),"%5d",top3);
// make frag count in player's color via escape code
hud_keysstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths
hud_keysstr[i++] = '0'+plyrcoltran[idx3&3];
s = numbuf;
while (*s)
hud_keysstr[i++] = *(s++);
}
// if the fourth biggest number exists, put it in the init string
if (idx4>-1)
{
snprintf(numbuf,sizeof(numbuf),"%5d",top4);
// make frag count in player's color via escape code
hud_keysstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths
hud_keysstr[i++] = '0'+plyrcoltran[idx4&3];
s = numbuf;
while (*s)
hud_keysstr[i++] = *(s++);
}
hud_keysstr[i] = '\0';
} //jff 3/17/98 end of deathmatch clause
else // build alphabetical key display (not used currently)
{
// scan the keys
for (k=0;k<6;k++)
{
// skip any not possessed by the displayed player's stats
if (!plr->cards[k])
continue;
// use color escapes to make text in key's color
hud_keysstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths
switch(k)
{
case 0:
hud_keysstr[i++] = '0'+CR_BLUE;
hud_keysstr[i++] = 'B';
hud_keysstr[i++] = 'C';
hud_keysstr[i++] = ' ';
break;
case 1:
hud_keysstr[i++] = '0'+CR_GOLD;
hud_keysstr[i++] = 'Y';
hud_keysstr[i++] = 'C';
hud_keysstr[i++] = ' ';
break;
case 2:
hud_keysstr[i++] = '0'+CR_RED;
hud_keysstr[i++] = 'R';
hud_keysstr[i++] = 'C';
hud_keysstr[i++] = ' ';
break;
case 3:
hud_keysstr[i++] = '0'+CR_BLUE;
hud_keysstr[i++] = 'B';
hud_keysstr[i++] = 'S';
hud_keysstr[i++] = ' ';
break;
case 4:
hud_keysstr[i++] = '0'+CR_GOLD;
hud_keysstr[i++] = 'Y';
hud_keysstr[i++] = 'S';
hud_keysstr[i++] = ' ';
break;
case 5:
hud_keysstr[i++] = '0'+CR_RED;
hud_keysstr[i++] = 'R';
hud_keysstr[i++] = 'S';
hud_keysstr[i++] = ' ';
break;
}
hud_keysstr[i]='\0';
}
}
}
}
// display the keys/frags line each frame
if (hud_active>1)
{
HUlib_clearTextLine(&w_keys); // clear the widget strings
HUlib_clearTextLine(&w_gkeys);
// transfer the built string (frags or key title) to the widget
s = hud_keysstr; //jff 3/7/98 display key titles/key text or frags
while (*s)
HUlib_addCharToTextLine(&w_keys, *(s++));
HUlib_drawTextLine(&w_keys, false);
//jff 3/17/98 show graphic keys in non-DM only
if (!deathmatch) //jff 3/7/98 display graphic keys
{
// transfer the graphic key text to the widget
s = hud_gkeysstr;
while (*s)
HUlib_addCharToTextLine(&w_gkeys, *(s++));
// display the widget
HUlib_drawTextLine(&w_gkeys, false);
}
}
// display the hud kills/items/secret display if optioned
if (!hud_nosecrets)
{
if (hud_active>1 && doit)
{
// clear the internal widget text buffer
HUlib_clearTextLine(&w_monsec);
//jff 3/26/98 use ESC not '\' for paths
// build the init string with fixed colors
snprintf
(
hud_monsecstr,80*sizeof(char),
"STS \x1b\x36K \x1b\x33%d \x1b\x36M \x1b\x33%d \x1b\x37I \x1b\x33%d/%d \x1b\x35S \x1b\x33%d/%d",
plr->killcount,totallive,
plr->itemcount,totalitems,
plr->secretcount,totalsecret
);
// transfer the init string to the widget
s = hud_monsecstr;
while (*s)
HUlib_addCharToTextLine(&w_monsec, *(s++));
}
// display the kills/items/secrets each frame, if optioned
if (hud_active>1)
HUlib_drawTextLine(&w_monsec, false);
}
}
//jff 3/4/98 display last to give priority
HU_Erase(); // jff 4/24/98 Erase current lines before drawing current
// needed when screen not fullsize
//jff 4/21/98 if setup has disabled message list while active, turn it off
if (hud_msg_lines<=1)
message_list = false;
// if the message review not enabled, show the standard message widget
if (!message_list)
HUlib_drawSText(&w_message);
// if the message review is enabled show the scrolling message review
if (hud_msg_lines>1 && message_list)
HUlib_drawMText(&w_rtext);
// display the interactive buffer for chat entry
HUlib_drawIText(&w_chat);
}
//
// HU_Erase()
//
// Erase hud display lines that can be trashed by small screen display
//
// Passed nothing, returns nothing
//
void HU_Erase(void)
{
// erase the message display or the message review display
if (!message_list)
HUlib_eraseSText(&w_message);
else
HUlib_eraseMText(&w_rtext);
// erase the interactive text buffer for chat entry
HUlib_eraseIText(&w_chat);
// erase the automap title
HUlib_eraseTextLine(&w_title);
}
//
// HU_Ticker()
//
// Update the hud displays once per frame
//
// Passed nothing, returns nothing
//
static boolean bsdown; // Is backspace down?
static int bscounter;
void HU_Ticker(void)
{
int i, rc;
char c;
// tick down message counter if message is up
if (message_counter && !--message_counter)
{
message_on = false;
message_nottobefuckedwith = false;
}
if (bsdown && bscounter++ > 9) {
HUlib_keyInIText(&w_chat, (unsigned char)key_backspace);
bscounter = 8;
}
// if messages on, or "Messages Off" is being displayed
// this allows the notification of turning messages off to be seen
if (showMessages || message_dontfuckwithme)
{
// display message if necessary
if ((plr->message && !message_nottobefuckedwith)
|| (plr->message && message_dontfuckwithme))
{
//post the message to the message widget
HUlib_addMessageToSText(&w_message, 0, plr->message);
//jff 2/26/98 add message to refresh text widget too
HUlib_addMessageToMText(&w_rtext, 0, plr->message);
// clear the message to avoid posting multiple times
plr->message = 0;
// note a message is displayed
message_on = true;
// start the message persistence counter
message_counter = HU_MSGTIMEOUT;
// transfer "Messages Off" exception to the "being displayed" variable
message_nottobefuckedwith = message_dontfuckwithme;
// clear the flag that "Messages Off" is being posted
message_dontfuckwithme = 0;
}
}
// check for incoming chat characters
if (netgame)
{
for (i=0; i<MAXPLAYERS; i++)
{
if (!playeringame[i])
continue;
if (i != consoleplayer
&& (c = players[i].cmd.chatchar))
{
if (c <= HU_BROADCAST)
chat_dest[i] = c;
else
{
if (c >= 'a' && c <= 'z')
c = (char) shiftxform[(unsigned char) c];
rc = HUlib_keyInIText(&w_inputbuffer[i], c);
if (rc && c == KEY_ENTER)
{
if (w_inputbuffer[i].l.len
&& (chat_dest[i] == consoleplayer+1
|| chat_dest[i] == HU_BROADCAST))
{
HUlib_addMessageToSText(&w_message,
player_names[i],
w_inputbuffer[i].l.l);
message_nottobefuckedwith = true;
message_on = true;
message_counter = HU_MSGTIMEOUT;
if ( gamemode == commercial )
S_StartSound(0, sfx_radio);
else
S_StartSound(0, sfx_tink);
}
HUlib_resetIText(&w_inputbuffer[i]);
}
}
players[i].cmd.chatchar = 0;
}
}
}
}
#define QUEUESIZE 128
static char chatchars[QUEUESIZE];
static int head = 0;
static int tail = 0;
//
// HU_queueChatChar()
//
// Add an incoming character to the circular chat queue
//
// Passed the character to queue, returns nothing
//
void HU_queueChatChar(char c)
{
if (((head + 1) & (QUEUESIZE-1)) == tail)
{
plr->message = HUSTR_MSGU;
}
else
{
chatchars[head] = c;
head = (head + 1) & (QUEUESIZE-1);
}
}
//
// HU_dequeueChatChar()
//
// Remove the earliest added character from the circular chat queue
//
// Passed nothing, returns the character dequeued
//
char HU_dequeueChatChar(void)
{
char c;
if (head != tail)
{
c = chatchars[tail];
tail = (tail + 1) & (QUEUESIZE-1);
}
else
{
c = 0;
}
return c;
}
//
// HU_Responder()
//
// Responds to input events that affect the heads up displays
//
// Passed the event to respond to, returns true if the event was handled
//
boolean HU_Responder(event_t *ev)
{
static char lastmessage[HU_MAXLINELENGTH+1];
const char* macromessage; // CPhipps - const char*
boolean eatkey = false;
static boolean shiftdown = false;
static boolean altdown = false;
unsigned char c;
int i;
int numplayers;
static int num_nobrainers = 0;
numplayers = 0;
for (i=0 ; i<MAXPLAYERS ; i++)
numplayers += playeringame[i];
if (ev->data1 == key_shift)
{
shiftdown = ev->type == ev_keydown;
return false;
}
else if (ev->data1 == key_alt)
{
altdown = ev->type == ev_keydown;
return false;
}
else if (ev->data1 == key_backspace)
{
bsdown = ev->type == ev_keydown;
bscounter = 0;
}
if (ev->type != ev_keydown)
return false;
if (!chat_on)
{
if (ev->data1 == key_enter) // phares
{
#ifndef INSTRUMENTED // never turn on message review if INSTRUMENTED defined
if (hud_msg_lines>1) // it posts multi-line messages that will trash
{
if (message_list) HU_Erase(); //jff 4/28/98 erase behind messages
message_list = !message_list; //jff 2/26/98 toggle list of messages
}
#endif
if (!message_list) // if not message list, refresh message
{
message_on = true;
message_counter = HU_MSGTIMEOUT;
}
eatkey = true;
}//jff 2/26/98 no chat if message review is displayed
else if (!message_list && netgame && ev->data1 == key_chat)
{
eatkey = chat_on = true;
HUlib_resetIText(&w_chat);
HU_queueChatChar(HU_BROADCAST);
}//jff 2/26/98 no chat if message review is displayed
// killough 10/02/98: no chat if demo playback
else if (!demoplayback && !message_list && netgame && numplayers > 2)
{
for (i=0; i<MAXPLAYERS ; i++)
{
if (ev->data1 == destination_keys[i])
{
if (playeringame[i] && i!=consoleplayer)
{
eatkey = chat_on = true;
HUlib_resetIText(&w_chat);
HU_queueChatChar((char)(i+1));
break;
}
else if (i == consoleplayer)
{
num_nobrainers++;
if (num_nobrainers < 3)
plr->message = HUSTR_TALKTOSELF1;
else if (num_nobrainers < 6)
plr->message = HUSTR_TALKTOSELF2;
else if (num_nobrainers < 9)
plr->message = HUSTR_TALKTOSELF3;
else if (num_nobrainers < 32)
plr->message = HUSTR_TALKTOSELF4;
else
plr->message = HUSTR_TALKTOSELF5;
}
}
}
}
}//jff 2/26/98 no chat functions if message review is displayed
else if (!message_list)
{
c = ev->data1;
// send a macro
if (altdown)
{
c = c - '0';
if (c > 9)
return false;
macromessage = chat_macros[c];
// kill last message with a '\n'
HU_queueChatChar((char)key_enter); // DEBUG!!! // phares
// send the macro message
while (*macromessage)
HU_queueChatChar(*macromessage++);
HU_queueChatChar((char)key_enter); // phares
// leave chat mode and notify that it was sent
chat_on = false;
strcpy(lastmessage, chat_macros[c]);
plr->message = lastmessage;
eatkey = true;
}
else
{
if (shiftdown || (c >= 'a' && c <= 'z'))
c = shiftxform[c];
eatkey = HUlib_keyInIText(&w_chat, c);
if (eatkey)
HU_queueChatChar(c);
if (c == key_enter) // phares
{
chat_on = false;
if (w_chat.l.len)
{
strcpy(lastmessage, w_chat.l.l);
plr->message = lastmessage;
}
}
else if (c == key_escape) // phares
chat_on = false;
}
}
return eatkey;
}