CT_CHAT.C 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. //**************************************************************************
  2. //**
  3. //** ct_chat.c : Heretic 2 : Raven Software, Corp.
  4. //**
  5. //** $RCSfile: ct_chat.c,v $
  6. //** $Revision: 1.12 $
  7. //** $Date: 96/01/16 10:35:26 $
  8. //** $Author: bgokey $
  9. //**
  10. //**************************************************************************
  11. #include <string.h>
  12. #include <ctype.h>
  13. #include "h2def.h"
  14. #include "p_local.h"
  15. #include "soundst.h"
  16. #define NUMKEYS 256
  17. #define QUEUESIZE 128
  18. #define MESSAGESIZE 128
  19. #define MESSAGELEN 265
  20. // 8-player note: Change this stuff (CT_PLR_*, and the key mappings)
  21. enum
  22. {
  23. CT_PLR_BLUE = 1,
  24. CT_PLR_RED,
  25. CT_PLR_YELLOW,
  26. CT_PLR_GREEN,
  27. CT_PLR_PLAYER5,
  28. CT_PLR_PLAYER6,
  29. CT_PLR_PLAYER7,
  30. CT_PLR_PLAYER8,
  31. CT_PLR_ALL
  32. };
  33. #define CT_KEY_BLUE 'b'
  34. #define CT_KEY_RED 'r'
  35. #define CT_KEY_YELLOW 'y'
  36. #define CT_KEY_GREEN 'g'
  37. #define CT_KEY_PLAYER5 'j' // Jade
  38. #define CT_KEY_PLAYER6 'w' // White
  39. #define CT_KEY_PLAYER7 'h' // Hazel
  40. #define CT_KEY_PLAYER8 'p' // Purple
  41. #define CT_KEY_ALL 't'
  42. #define CT_ESCAPE 6
  43. // Public data
  44. void CT_Init(void);
  45. void CT_Drawer(void);
  46. boolean CT_Responder(event_t *ev);
  47. void CT_Ticker(void);
  48. char CT_dequeueChatChar(void);
  49. boolean chatmodeon;
  50. // Private data
  51. void CT_queueChatChar(char ch);
  52. void CT_ClearChatMessage(int player);
  53. void CT_AddChar(int player, char c);
  54. void CT_BackSpace(int player);
  55. int head;
  56. int tail;
  57. byte ChatQueue[QUEUESIZE];
  58. int chat_dest[MAXPLAYERS];
  59. char chat_msg[MAXPLAYERS][MESSAGESIZE];
  60. char plr_lastmsg[MAXPLAYERS][MESSAGESIZE+9];
  61. int msgptr[MAXPLAYERS];
  62. int msglen[MAXPLAYERS];
  63. boolean cheated;
  64. static int FontABaseLump;
  65. char *CT_FromPlrText[MAXPLAYERS] =
  66. {
  67. "BLUE: ",
  68. "RED: ",
  69. "YELLOW: ",
  70. "GREEN: ",
  71. "JADE: ",
  72. "WHITE: ",
  73. "HAZEL: ",
  74. "PURPLE: "
  75. };
  76. char *chat_macros[10];
  77. boolean altdown;
  78. boolean shiftdown;
  79. extern boolean usearti;
  80. //===========================================================================
  81. //
  82. // CT_Init
  83. //
  84. // Initialize chat mode data
  85. //===========================================================================
  86. void CT_Init(void)
  87. {
  88. int i;
  89. head = 0; //initialize the queue index
  90. tail = 0;
  91. chatmodeon = false;
  92. memset(ChatQueue, 0, QUEUESIZE);
  93. for(i = 0; i < MAXPLAYERS; i++)
  94. {
  95. chat_dest[i] = 0;
  96. msgptr[i] = 0;
  97. memset(plr_lastmsg[i], 0, MESSAGESIZE);
  98. memset(chat_msg[i], 0, MESSAGESIZE);
  99. }
  100. FontABaseLump = W_GetNumForName("FONTA_S")+1;
  101. return;
  102. }
  103. //===========================================================================
  104. //
  105. // CT_Stop
  106. //
  107. //===========================================================================
  108. void CT_Stop(void)
  109. {
  110. chatmodeon = false;
  111. return;
  112. }
  113. //===========================================================================
  114. //
  115. // CT_Responder
  116. //
  117. //===========================================================================
  118. boolean CT_Responder(event_t *ev)
  119. {
  120. char *macro;
  121. int sendto;
  122. if(!netgame)
  123. {
  124. return false;
  125. }
  126. if(ev->data1 == KEY_RALT)
  127. {
  128. altdown = (ev->type == ev_keydown);
  129. return false;
  130. }
  131. if(ev->data1 == KEY_RSHIFT)
  132. {
  133. shiftdown = (ev->type == ev_keydown);
  134. return false;
  135. }
  136. if(gamestate != GS_LEVEL || ev->type != ev_keydown)
  137. {
  138. return false;
  139. }
  140. if(!chatmodeon)
  141. {
  142. sendto = 0;
  143. if(ev->data1 == CT_KEY_ALL)
  144. {
  145. sendto = CT_PLR_ALL;
  146. }
  147. else if(ev->data1 == CT_KEY_GREEN)
  148. {
  149. sendto = CT_PLR_GREEN;
  150. }
  151. else if(ev->data1 == CT_KEY_YELLOW)
  152. {
  153. sendto = CT_PLR_YELLOW;
  154. }
  155. else if(ev->data1 == CT_KEY_RED)
  156. {
  157. sendto = CT_PLR_RED;
  158. }
  159. else if(ev->data1 == CT_KEY_BLUE)
  160. {
  161. sendto = CT_PLR_BLUE;
  162. }
  163. else if(ev->data1 == CT_KEY_PLAYER5)
  164. {
  165. sendto = CT_PLR_PLAYER5;
  166. }
  167. else if(ev->data1 == CT_KEY_PLAYER6)
  168. {
  169. sendto = CT_PLR_PLAYER6;
  170. }
  171. else if(ev->data1 == CT_KEY_PLAYER7)
  172. {
  173. sendto = CT_PLR_PLAYER7;
  174. }
  175. else if(ev->data1 == CT_KEY_PLAYER8)
  176. {
  177. sendto = CT_PLR_PLAYER8;
  178. }
  179. if(sendto == 0 || (sendto != CT_PLR_ALL && !playeringame[sendto-1])
  180. || sendto == consoleplayer+1)
  181. {
  182. return false;
  183. }
  184. CT_queueChatChar(sendto);
  185. chatmodeon = true;
  186. return true;
  187. }
  188. else
  189. {
  190. if(altdown)
  191. {
  192. if(ev->data1 >= '0' && ev->data1 <= '9')
  193. {
  194. if(ev->data1 == '0')
  195. { // macro 0 comes after macro 9
  196. ev->data1 = '9'+1;
  197. }
  198. macro = chat_macros[ev->data1-'1'];
  199. CT_queueChatChar(KEY_ENTER); //send old message
  200. CT_queueChatChar(chat_dest[consoleplayer]); // chose the dest.
  201. while(*macro)
  202. {
  203. CT_queueChatChar(toupper(*macro++));
  204. }
  205. CT_queueChatChar(KEY_ENTER); //send it off...
  206. CT_Stop();
  207. return true;
  208. }
  209. }
  210. if(ev->data1 == KEY_ENTER)
  211. {
  212. CT_queueChatChar(KEY_ENTER);
  213. usearti = false;
  214. CT_Stop();
  215. return true;
  216. }
  217. else if(ev->data1 == KEY_ESCAPE)
  218. {
  219. CT_queueChatChar(CT_ESCAPE);
  220. CT_Stop();
  221. return true;
  222. }
  223. else if(ev->data1 >= 'a' && ev->data1 <= 'z')
  224. {
  225. CT_queueChatChar(ev->data1-32);
  226. return true;
  227. }
  228. else if(shiftdown)
  229. {
  230. if(ev->data1 == '1')
  231. {
  232. CT_queueChatChar('!');
  233. return true;
  234. }
  235. else if(ev->data1 == '/')
  236. {
  237. CT_queueChatChar('?');
  238. return true;
  239. }
  240. }
  241. if(ev->data1 == ' ' || ev->data1 == ',' || ev->data1 == '.'
  242. || (ev->data1 >= '0' && ev->data1 <= '9') || ev->data1 == '\''
  243. || ev->data1 == KEY_BACKSPACE || ev->data1 == '-' || ev->data1 == '=')
  244. {
  245. CT_queueChatChar(ev->data1);
  246. return true;
  247. }
  248. }
  249. return false;
  250. }
  251. //===========================================================================
  252. //
  253. // CT_Ticker
  254. //
  255. //===========================================================================
  256. void CT_Ticker(void)
  257. {
  258. int i;
  259. int j;
  260. char c;
  261. int numplayers;
  262. for(i=0; i < MAXPLAYERS; i++)
  263. {
  264. if(!playeringame[i])
  265. {
  266. continue;
  267. }
  268. if((c = players[i].cmd.chatchar) != 0)
  269. {
  270. if(c <= CT_PLR_ALL)
  271. {
  272. chat_dest[i] = c;
  273. continue;
  274. }
  275. else if(c == CT_ESCAPE)
  276. {
  277. CT_ClearChatMessage(i);
  278. }
  279. else if(c == KEY_ENTER)
  280. {
  281. numplayers = 0;
  282. for(j = 0; j < MAXPLAYERS; j++)
  283. {
  284. numplayers += playeringame[j];
  285. }
  286. CT_AddChar(i, 0); // set the end of message character
  287. if(numplayers > 2)
  288. {
  289. strcpy(plr_lastmsg[i], CT_FromPlrText[i]);
  290. strcat(plr_lastmsg[i], chat_msg[i]);
  291. }
  292. else
  293. {
  294. strcpy(plr_lastmsg[i], chat_msg[i]);
  295. }
  296. if(i != consoleplayer && (chat_dest[i] == consoleplayer+1
  297. || chat_dest[i] == CT_PLR_ALL) && *chat_msg[i])
  298. {
  299. P_SetMessage(&players[consoleplayer], plr_lastmsg[i],
  300. true);
  301. S_StartSound(NULL, SFX_CHAT);
  302. }
  303. else if(i == consoleplayer && (*chat_msg[i]))
  304. {
  305. if(numplayers <= 1)
  306. {
  307. P_SetMessage(&players[consoleplayer],
  308. "THERE ARE NO OTHER PLAYERS IN THE GAME!", true);
  309. S_StartSound(NULL, SFX_CHAT);
  310. }
  311. }
  312. CT_ClearChatMessage(i);
  313. }
  314. else if(c == KEY_BACKSPACE)
  315. {
  316. CT_BackSpace(i);
  317. }
  318. else
  319. {
  320. CT_AddChar(i, c);
  321. }
  322. }
  323. }
  324. return;
  325. }
  326. //===========================================================================
  327. //
  328. // CT_Drawer
  329. //
  330. //===========================================================================
  331. void CT_Drawer(void)
  332. {
  333. int i;
  334. int x;
  335. patch_t *patch;
  336. if(chatmodeon)
  337. {
  338. x = 25;
  339. for(i = 0; i < msgptr[consoleplayer]; i++)
  340. {
  341. if(chat_msg[consoleplayer][i] < 33)
  342. {
  343. x += 6;
  344. }
  345. else
  346. {
  347. patch=W_CacheLumpNum(FontABaseLump+
  348. chat_msg[consoleplayer][i]-33, PU_CACHE);
  349. V_DrawPatch(x, 10, patch);
  350. x += patch->width;
  351. }
  352. }
  353. V_DrawPatch(x, 10, W_CacheLumpName("FONTA59", PU_CACHE));
  354. BorderTopRefresh = true;
  355. UpdateState |= I_MESSAGES;
  356. }
  357. }
  358. //===========================================================================
  359. //
  360. // CT_queueChatChar
  361. //
  362. //===========================================================================
  363. void CT_queueChatChar(char ch)
  364. {
  365. if((tail+1)&(QUEUESIZE-1) == head)
  366. { // the queue is full
  367. return;
  368. }
  369. ChatQueue[tail] = ch;
  370. tail = (tail+1)&(QUEUESIZE-1);
  371. }
  372. //===========================================================================
  373. //
  374. // CT_dequeueChatChar
  375. //
  376. //===========================================================================
  377. char CT_dequeueChatChar(void)
  378. {
  379. byte temp;
  380. if(head == tail)
  381. { // queue is empty
  382. return 0;
  383. }
  384. temp = ChatQueue[head];
  385. head = (head+1)&(QUEUESIZE-1);
  386. return temp;
  387. }
  388. //===========================================================================
  389. //
  390. // CT_AddChar
  391. //
  392. //===========================================================================
  393. void CT_AddChar(int player, char c)
  394. {
  395. patch_t *patch;
  396. if(msgptr[player]+1 >= MESSAGESIZE || msglen[player] >= MESSAGELEN)
  397. { // full.
  398. return;
  399. }
  400. chat_msg[player][msgptr[player]] = c;
  401. msgptr[player]++;
  402. if(c < 33)
  403. {
  404. msglen[player] += 6;
  405. }
  406. else
  407. {
  408. patch = W_CacheLumpNum(FontABaseLump+c-33, PU_CACHE);
  409. msglen[player] += patch->width;
  410. }
  411. }
  412. //===========================================================================
  413. //
  414. // CT_BackSpace
  415. //
  416. // Backs up a space, when the user hits (obviously) backspace
  417. //===========================================================================
  418. void CT_BackSpace(int player)
  419. {
  420. patch_t *patch;
  421. char c;
  422. if(msgptr[player] == 0)
  423. { // message is already blank
  424. return;
  425. }
  426. msgptr[player]--;
  427. c = chat_msg[player][msgptr[player]];
  428. if(c < 33)
  429. {
  430. msglen[player] -= 6;
  431. }
  432. else
  433. {
  434. patch = W_CacheLumpNum(FontABaseLump+c-33, PU_CACHE);
  435. msglen[player] -= patch->width;
  436. }
  437. chat_msg[player][msgptr[player]] = 0;
  438. }
  439. //===========================================================================
  440. //
  441. // CT_ClearChatMessage
  442. //
  443. // Clears out the data for the chat message, but the player's message
  444. // is still saved in plrmsg.
  445. //===========================================================================
  446. void CT_ClearChatMessage(int player)
  447. {
  448. memset(chat_msg[player], 0, MESSAGESIZE);
  449. msgptr[player] = 0;
  450. msglen[player] = 0;
  451. }