Files

1 line
11 KiB
C++

//
// Heads-up displays
//
#include <ctype.h>
#include "doomdef.h"
#include "hu_stuff.h"
#include "hu_lib.h"
char *chat_macros[] =
{
HUSTR_CHATMACRO0,
HUSTR_CHATMACRO1,
HUSTR_CHATMACRO2,
HUSTR_CHATMACRO3,
HUSTR_CHATMACRO4,
HUSTR_CHATMACRO5,
HUSTR_CHATMACRO6,
HUSTR_CHATMACRO7,
HUSTR_CHATMACRO8,
HUSTR_CHATMACRO9
};
char *player_names[] =
{
HUSTR_PLRGREEN,
HUSTR_PLRINDIGO,
HUSTR_PLRBROWN,
HUSTR_PLRRED
};
char chat_char; // remove later.
static player_t *plr;
patch_t *hu_font[HU_FONTSIZE];
static hu_textline_t w_title;
boolean chat_on;
static hu_itext_t w_chat;
static boolean always_off = false;
static char chat_dest[MAXPLAYERS];
static hu_itext_t w_inputbuffer[MAXPLAYERS];
static boolean message_on;
boolean message_dontfuckwithme;
static boolean message_nottobefuckedwith;
static hu_stext_t w_message;
static int message_counter;
extern int showMessages;
extern boolean automapactive;
static boolean headsupactive = false;
// the actual names can be found in DStrings.h
char *mapnames[] =
{
HUSTR_E1M1,
HUSTR_E1M2,
HUSTR_E1M3,
HUSTR_E1M4,
HUSTR_E1M5,
HUSTR_E1M6,
HUSTR_E1M7,
HUSTR_E1M8,
HUSTR_E1M9,
HUSTR_E2M1,
HUSTR_E2M2,
HUSTR_E2M3,
HUSTR_E2M4,
HUSTR_E2M5,
HUSTR_E2M6,
HUSTR_E2M7,
HUSTR_E2M8,
HUSTR_E2M9,
HUSTR_E3M1,
HUSTR_E3M2,
HUSTR_E3M3,
HUSTR_E3M4,
HUSTR_E3M5,
HUSTR_E3M6,
HUSTR_E3M7,
HUSTR_E3M8,
HUSTR_E3M9,
"NEWLEVEL",
"NEWLEVEL",
"NEWLEVEL",
"NEWLEVEL",
"NEWLEVEL",
"NEWLEVEL",
"NEWLEVEL",
"NEWLEVEL",
"NEWLEVEL",
"NEWLEVEL",
"NEWLEVEL",
"NEWLEVEL",
"NEWLEVEL",
"NEWLEVEL",
"NEWLEVEL",
"NEWLEVEL",
"NEWLEVEL",
"NEWLEVEL",
"NEWLEVEL"
};
char *mapnames2[] =
{
HUSTR_1,
HUSTR_2,
HUSTR_3,
HUSTR_4,
HUSTR_5,
HUSTR_6,
HUSTR_7,
HUSTR_8,
HUSTR_9,
HUSTR_10,
HUSTR_11,
HUSTR_12,
HUSTR_13,
HUSTR_14,
HUSTR_15,
HUSTR_16,
HUSTR_17,
HUSTR_18,
HUSTR_19,
HUSTR_20,
HUSTR_21,
HUSTR_22,
HUSTR_23,
HUSTR_24,
HUSTR_25,
HUSTR_26,
HUSTR_27,
HUSTR_28,
HUSTR_29,
HUSTR_30,
HUSTR_31,
HUSTR_32
};
char *shiftxform;
const char french_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-/
'0', // shift-0
'1', // shift-1
'2', // shift-2
'3', // shift-3
'4', // shift-4
'5', // shift-5
'6', // shift-6
'7', // shift-7
'8', // shift-8
'9', // 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
};
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
};
char frenchKeyMap[128]=
{
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,
' ','!','"','#','$','%','&','%','(',')','*','+',';','-',':','!',
'0','1','2','3','4','5','6','7','8','9',':','M','<','=','>','?',
'@','Q','B','C','D','E','F','G','H','I','J','K','L',',','N','O',
'P','A','R','S','T','U','V','Z','X','Y','W','^','\\','$','^','_',
'@','Q','B','C','D','E','F','G','H','I','J','K','L',',','N','O',
'P','A','R','S','T','U','V','Z','X','Y','W','^','\\','$','^',127
};
char ForeignTranslation(unsigned char ch)
{
return ch < 128 ? frenchKeyMap[ch] : ch;
}
void HU_Init(void)
{
int i, j;
char buffer[9];
if (french)
shiftxform = french_shiftxform;
else
shiftxform = english_shiftxform;
// load the heads-up font
j = HU_FONTSTART;
for (i=0;i<HU_FONTSIZE;i++)
{
sprintf(buffer, "STCFN%.3d", j++);
hu_font[i] = (patch_t *) W_CacheLumpName(buffer, PU_STATIC);
}
}
void HU_Stop(void)
{
headsupactive = false;
}
void HU_Start(void)
{
int i;
char *s;
if (headsupactive) HU_Stop();
plr = &players[consoleplayer];
message_on = false;
message_dontfuckwithme = false;
message_nottobefuckedwith = false;
chat_on = false;
// create the message widget
HUlib_initSText(&w_message, HU_MSGX, HU_MSGY, HU_MSGHEIGHT, hu_font,
HU_FONTSTART, &message_on);
// create the map title widget
HUlib_initTextLine(&w_title, HU_TITLEX, HU_TITLEY, hu_font, HU_FONTSTART);
if (comercial)
s = HU_TITLE2;
else
s = HU_TITLE;
while (*s) HUlib_addCharToTextLine(&w_title, *(s++));
// create the chat widget
HUlib_initIText(&w_chat, HU_INPUTX, HU_INPUTY, hu_font, HU_FONTSTART,
&chat_on);
// create the inputbuffer widgets
for (i=0 ; i<MAXPLAYERS ; i++)
HUlib_initIText(&w_inputbuffer[i], 0, 0, 0, 0, &always_off);
headsupactive = true;
}
void HU_Drawer(void)
{
HUlib_drawSText(&w_message);
HUlib_drawIText(&w_chat);
if (automapactive) HUlib_drawTextLine(&w_title, false);
}
void HU_Erase(void)
{
HUlib_eraseSText(&w_message);
HUlib_eraseIText(&w_chat);
HUlib_eraseTextLine(&w_title);
}
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 (showMessages || message_dontfuckwithme)
{
// display message if necessary
if ((plr->message && !message_nottobefuckedwith)
|| (plr->message && message_dontfuckwithme))
{
HUlib_addMessageToSText(&w_message, 0, plr->message);
plr->message = 0;
message_on = true;
message_counter = HU_MSGTIMEOUT;
message_nottobefuckedwith = message_dontfuckwithme;
message_dontfuckwithme = 0;
}
} // else message_on = false;
// 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;
commercial ? S_StartSound(0, sfx_radio): 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, tail = 0;
void HU_queueChatChar(char c)
{
if (((head + 1) & (QUEUESIZE-1)) == tail)
{
plr->message = HUSTR_MSGU;
} else {
chatchars[head] = c;
head = (head + 1) & (QUEUESIZE-1);
}
}
char HU_dequeueChatChar(void)
{
char c;
if (head != tail)
{
c = chatchars[tail];
tail = (tail + 1) & (QUEUESIZE-1);
} else {
c = 0;
}
return c;
}
boolean HU_Responder(event_t *ev)
{
static char lastmessage[HU_MAXLINELENGTH+1];
char *macromessage;
boolean eatkey = false;
static boolean shiftdown = false;
static boolean altdown = false;
unsigned char c;
int i, numplayers;
static char destination_keys[MAXPLAYERS] =
{
HUSTR_KEYGREEN,
HUSTR_KEYINDIGO,
HUSTR_KEYBROWN,
HUSTR_KEYRED
};
static int num_nobrainers = 0;
numplayers = 0;
for (i=0 ; i<MAXPLAYERS ; i++) numplayers += playeringame[i];
if (ev->data1 == KEY_RSHIFT)
{
shiftdown = ev->type == ev_keydown;
return false;
} else if (ev->data1 == KEY_RALT || ev->data1 == KEY_LALT)
{
altdown = ev->type == ev_keydown;
return false;
}
if (ev->type != ev_keydown) return false;
if (!chat_on)
{
if (ev->data1 == HU_MSGREFRESH)
{
message_on = true;
message_counter = HU_MSGTIMEOUT;
eatkey = true;
} else if (netgame && ev->data1 == HU_INPUTTOGGLE)
{
eatkey = chat_on = true;
HUlib_resetIText(&w_chat);
HU_queueChatChar(HU_BROADCAST);
} else if (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(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;
}
}
}
}
} else
{
c = ev->data1;
// send a macro
if (altdown)
{
c = c - '0';
if (c > 9) return false;
// fprintf(stderr, "got here\n");
macromessage = chat_macros[c];
// kill last message with a '\n'
HU_queueChatChar(KEY_ENTER); // DEBUG!!!
// send the macro message
while (*macromessage)
HU_queueChatChar(*macromessage++);
HU_queueChatChar(KEY_ENTER);
// leave chat mode and notify that it was sent
chat_on = false;
strcpy(lastmessage, chat_macros[c]);
plr->message = lastmessage;
eatkey = true;
} else
{
if (french)
c = ForeignTranslation(c);
if (shiftdown || (c >= 'a' && c <= 'z')) c = shiftxform[c];
eatkey = HUlib_keyInIText(&w_chat, c);
if (eatkey)
{
// static unsigned char buf[20]; // DEBUG
HU_queueChatChar(c);
// sprintf(buf, "KEY: %d => %d", ev->data1, c);
// plr->message = buf;
}
if (c == KEY_ENTER)
{
chat_on = false;
if (w_chat.l.len)
{
strcpy(lastmessage, w_chat.l.l);
plr->message = lastmessage;
}
} else if (c == KEY_ESCAPE) chat_on = false;
}
}
return eatkey;
}