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