2 //**************************************************************************
4 //** ct_chat.c : Heretic 2 : Raven Software, Corp.
11 //**************************************************************************
22 #define MESSAGESIZE 128
23 #define MESSAGELEN 265
25 // 8-player note: Change this stuff (CT_PLR_*, and the key mappings)
39 #define CT_KEY_BLUE 'b'
40 #define CT_KEY_RED 'r'
41 #define CT_KEY_YELLOW 'y'
42 #define CT_KEY_GREEN 'g'
43 #define CT_KEY_PLAYER5 'j' // Jade
44 #define CT_KEY_PLAYER6 'w' // White
45 #define CT_KEY_PLAYER7 'h' // Hazel
46 #define CT_KEY_PLAYER8 'p' // Purple
47 #define CT_KEY_ALL 't'
54 boolean CT_Responder(event_t *ev);
56 char CT_dequeueChatChar(void);
62 void CT_queueChatChar(char ch);
63 void CT_ClearChatMessage(int player);
64 void CT_AddChar(int player, char c);
65 void CT_BackSpace(int player);
69 byte ChatQueue[QUEUESIZE];
70 int chat_dest[MAXPLAYERS];
71 char chat_msg[MAXPLAYERS][MESSAGESIZE];
72 char plr_lastmsg[MAXPLAYERS][MESSAGESIZE+9];
73 int msgptr[MAXPLAYERS];
74 int msglen[MAXPLAYERS];
78 static int FontABaseLump;
80 char *CT_FromPlrText[MAXPLAYERS] =
92 char *chat_macros[10];
97 extern boolean usearti;
99 //===========================================================================
103 // Initialize chat mode data
104 //===========================================================================
110 head = 0; //initialize the queue index
113 memset(ChatQueue, 0, QUEUESIZE);
114 for(i = 0; i < MAXPLAYERS; i++)
118 memset(plr_lastmsg[i], 0, MESSAGESIZE);
119 memset(chat_msg[i], 0, MESSAGESIZE);
121 FontABaseLump = W_GetNumForName("FONTA_S")+1;
125 //===========================================================================
129 //===========================================================================
137 //===========================================================================
141 //===========================================================================
143 boolean CT_Responder(event_t *ev)
153 if(ev->data1 == KEY_RALT)
155 altdown = (ev->type == ev_keydown);
158 if(ev->data1 == KEY_RSHIFT)
160 shiftdown = (ev->type == ev_keydown);
163 if(gamestate != GS_LEVEL || ev->type != ev_keydown)
170 if(ev->data1 == CT_KEY_ALL)
174 else if(ev->data1 == CT_KEY_GREEN)
176 sendto = CT_PLR_GREEN;
178 else if(ev->data1 == CT_KEY_YELLOW)
180 sendto = CT_PLR_YELLOW;
182 else if(ev->data1 == CT_KEY_RED)
186 else if(ev->data1 == CT_KEY_BLUE)
188 sendto = CT_PLR_BLUE;
190 else if(ev->data1 == CT_KEY_PLAYER5)
192 sendto = CT_PLR_PLAYER5;
194 else if(ev->data1 == CT_KEY_PLAYER6)
196 sendto = CT_PLR_PLAYER6;
198 else if(ev->data1 == CT_KEY_PLAYER7)
200 sendto = CT_PLR_PLAYER7;
202 else if(ev->data1 == CT_KEY_PLAYER8)
204 sendto = CT_PLR_PLAYER8;
206 if(sendto == 0 || (sendto != CT_PLR_ALL && !playeringame[sendto-1])
207 || sendto == consoleplayer+1)
211 CT_queueChatChar(sendto);
219 if(ev->data1 >= '0' && ev->data1 <= '9')
222 { // macro 0 comes after macro 9
225 macro = chat_macros[ev->data1-'1'];
226 CT_queueChatChar(KEY_ENTER); //send old message
227 CT_queueChatChar(chat_dest[consoleplayer]); // chose the dest.
230 CT_queueChatChar(toupper(*macro++));
232 CT_queueChatChar(KEY_ENTER); //send it off...
237 if(ev->data1 == KEY_ENTER)
239 CT_queueChatChar(KEY_ENTER);
244 else if(ev->data1 == KEY_ESCAPE)
246 CT_queueChatChar(CT_ESCAPE);
250 else if(ev->data1 >= 'a' && ev->data1 <= 'z')
252 CT_queueChatChar(ev->data1-32);
259 CT_queueChatChar('!');
262 else if(ev->data1 == '/')
264 CT_queueChatChar('?');
268 if(ev->data1 == ' ' || ev->data1 == ',' || ev->data1 == '.'
269 || (ev->data1 >= '0' && ev->data1 <= '9') || ev->data1 == '\''
270 || ev->data1 == KEY_BACKSPACE || ev->data1 == '-' || ev->data1 == '=')
272 CT_queueChatChar(ev->data1);
279 //===========================================================================
283 //===========================================================================
292 for(i=0; i < MAXPLAYERS; i++)
298 if((c = players[i].cmd.chatchar) != 0)
305 else if(c == CT_ESCAPE)
307 CT_ClearChatMessage(i);
309 else if(c == KEY_ENTER)
312 for(j = 0; j < MAXPLAYERS; j++)
314 numplayers += playeringame[j];
316 CT_AddChar(i, 0); // set the end of message character
319 strcpy(plr_lastmsg[i], CT_FromPlrText[i]);
320 strcat(plr_lastmsg[i], chat_msg[i]);
324 strcpy(plr_lastmsg[i], chat_msg[i]);
326 if(i != consoleplayer && (chat_dest[i] == consoleplayer+1
327 || chat_dest[i] == CT_PLR_ALL) && *chat_msg[i])
329 P_SetMessage(&players[consoleplayer], plr_lastmsg[i],
331 S_StartSound(NULL, SFX_CHAT);
333 else if(i == consoleplayer && (*chat_msg[i]))
337 P_SetMessage(&players[consoleplayer],
338 "THERE ARE NO OTHER PLAYERS IN THE GAME!", true);
339 S_StartSound(NULL, SFX_CHAT);
342 CT_ClearChatMessage(i);
344 else if(c == KEY_BACKSPACE)
357 //===========================================================================
361 //===========================================================================
372 for(i = 0; i < msgptr[consoleplayer]; i++)
374 if(chat_msg[consoleplayer][i] < 33)
380 patch=W_CacheLumpNum(FontABaseLump+
381 chat_msg[consoleplayer][i]-33, PU_CACHE);
382 V_DrawPatch(x, 10, patch);
386 V_DrawPatch(x, 10, W_CacheLumpName("FONTA59", PU_CACHE));
387 BorderTopRefresh = true;
388 UpdateState |= I_MESSAGES;
392 //===========================================================================
396 //===========================================================================
398 void CT_queueChatChar(char ch)
401 * jim - don't like this at all; relies on QUEUESIZE's being a power of 2,
402 * and gcc's warning suggests that the precedence is wrong, but I don't
403 * keep track of C precedence and IDHK&RIFOM...
405 /* if((tail+1)&(QUEUESIZE-1) == head) */
406 if (((tail + 1) % QUEUESIZE) == head)
407 { // the queue is full
410 ChatQueue[tail] = ch;
411 /* tail = (tail+1)&(QUEUESIZE-1); */
412 tail = (tail + 1) % QUEUESIZE;
415 //===========================================================================
417 // CT_dequeueChatChar
419 //===========================================================================
421 char CT_dequeueChatChar(void)
429 temp = ChatQueue[head];
430 head = (head+1)&(QUEUESIZE-1);
434 //===========================================================================
438 //===========================================================================
440 void CT_AddChar(int player, char c)
444 if(msgptr[player]+1 >= MESSAGESIZE || msglen[player] >= MESSAGELEN)
448 chat_msg[player][msgptr[player]] = c;
456 patch = W_CacheLumpNum(FontABaseLump+c-33, PU_CACHE);
457 msglen[player] += patch->width;
461 //===========================================================================
465 // Backs up a space, when the user hits (obviously) backspace
466 //===========================================================================
468 void CT_BackSpace(int player)
473 if(msgptr[player] == 0)
474 { // message is already blank
478 c = chat_msg[player][msgptr[player]];
485 patch = W_CacheLumpNum(FontABaseLump+c-33, PU_CACHE);
486 msglen[player] -= patch->width;
488 chat_msg[player][msgptr[player]] = 0;
491 //===========================================================================
493 // CT_ClearChatMessage
495 // Clears out the data for the chat message, but the player's message
496 // is still saved in plrmsg.
497 //===========================================================================
499 void CT_ClearChatMessage(int player)
501 memset(chat_msg[player], 0, MESSAGESIZE);