From 45aba493c79d4df9e33ff537a77255d44389025b Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Mon, 17 Dec 2018 20:43:59 +0100 Subject: [PATCH] 2.1.21 and all of the kart additions. Woo. --- src/console.c | 55 ++-- src/d_main.c | 1 + src/g_game.c | 8 +- src/hu_stuff.c | 736 ++++++++++++++++++++++++++-------------------- src/hu_stuff.h | 26 +- src/lua_baselib.c | 28 +- src/lua_hook.h | 2 +- src/lua_hooklib.c | 20 +- src/m_menu.c | 4 +- src/v_video.c | 73 ++--- src/v_video.h | 1 + 11 files changed, 534 insertions(+), 420 deletions(-) diff --git a/src/console.c b/src/console.c index b7ef60444..660a57e45 100644 --- a/src/console.c +++ b/src/console.c @@ -131,11 +131,16 @@ static CV_PossibleValue_t backpic_cons_t[] = {{0, "translucent"}, {1, "picture"} // whether to use console background picture, or translucent mode static consvar_t cons_backpic = {"con_backpic", "translucent", CV_SAVE, backpic_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t backcolor_cons_t[] = {{0, "White"}, {1, "Gray"}, {2, "Brown"}, - {3, "Red"}, {4, "Orange"}, {5, "Yellow"}, - {6, "Green"}, {7, "Blue"}, {8, "Cyan"}, +static CV_PossibleValue_t backcolor_cons_t[] = {{0, "White"}, {1, "Black"}, {2, "Sepia"}, + {3, "Brown"}, {4, "Pink"}, {5, "Raspberry"}, + {6, "Red"}, {7, "Creamsicle"}, {8, "Orange"}, + {9, "Gold"}, {10,"Yellow"}, {11,"Emerald"}, + {12,"Green"}, {13,"Cyan"}, {14,"Steel"}, + {15,"Periwinkle"}, {16,"Blue"}, {17,"Purple"}, + {18,"Lavender"}, {0, NULL}}; -consvar_t cons_backcolor = {"con_backcolor", "Green", CV_CALL|CV_SAVE, backcolor_cons_t, CONS_backcolor_Change, 0, NULL, NULL, 0, 0, NULL}; + +consvar_t cons_backcolor = {"con_backcolor", "Black", CV_CALL|CV_SAVE, backcolor_cons_t, CONS_backcolor_Change, 0, NULL, NULL, 0, 0, NULL}; static void CON_Print(char *msg); @@ -241,29 +246,41 @@ void CON_SetupBackColormap(void) UINT16 i, palsum; UINT8 j, palindex; UINT8 *pal = W_CacheLumpName(GetPalette(), PU_CACHE); + INT32 shift = 6; if (!consolebgmap) consolebgmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); switch (cons_backcolor.value) { - case 0: palindex = 15; break; // White - case 1: palindex = 31; break; // Gray - case 2: palindex = 63; break; // Brown - case 3: palindex = 143; break; // Red - case 4: palindex = 95; break; // Orange - case 5: palindex = 111; break; // Yellow - case 6: palindex = 175; break; // Green - case 7: palindex = 239; break; // Blue - case 8: palindex = 219; break; // Cyan + case 0: palindex = 15; break; // White + case 1: palindex = 31; break; // Gray + case 2: palindex = 47; break; // Sepia + case 3: palindex = 63; break; // Brown + case 4: palindex = 150; shift = 7; break; // Pink + case 5: palindex = 127; shift = 7; break; // Raspberry + case 6: palindex = 143; break; // Red + case 7: palindex = 86; shift = 7; break; // Creamsicle + case 8: palindex = 95; break; // Orange + case 9: palindex = 119; shift = 7; break; // Gold + case 10: palindex = 111; break; // Yellow + case 11: palindex = 191; shift = 7; break; // Emerald + case 12: palindex = 175; break; // Green + case 13: palindex = 219; break; // Cyan + case 14: palindex = 207; shift = 7; break; // Steel + case 15: palindex = 230; shift = 7; break; // Periwinkle + case 16: palindex = 239; break; // Blue + case 17: palindex = 199; shift = 7; break; // Purple + case 18: palindex = 255; shift = 7; break; // Lavender // Default green default: palindex = 175; break; + } // setup background colormap for (i = 0, j = 0; i < 768; i += 3, j++) { - palsum = (pal[i] + pal[i+1] + pal[i+2]) >> 6; + palsum = (pal[i] + pal[i+1] + pal[i+2]) >> shift; consolebgmap[j] = (UINT8)(palindex - palsum); } } @@ -1035,17 +1052,17 @@ boolean CON_Responder(event_t *ev) } else if (key == KEY_KPADSLASH) key = '/'; - + // capslock if (key == KEY_CAPSLOCK) // it's a toggle. - { + { if (capslock) capslock = false; - else + else capslock = true; return true; - } - + } + if (key >= 'a' && key <= 'z') { if (capslock ^ shiftdown) diff --git a/src/d_main.c b/src/d_main.c index 23835136a..906906e52 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -178,6 +178,7 @@ void D_PostEvent_end(void) {}; UINT8 shiftdown = 0; // 0x1 left, 0x2 right UINT8 ctrldown = 0; // 0x1 left, 0x2 right UINT8 altdown = 0; // 0x1 left, 0x2 right +boolean capslock = 0; // gee i wonder what this does. // // D_ModifierKeyResponder // Sets global shift/ctrl/alt variables, never actually eats events diff --git a/src/g_game.c b/src/g_game.c index 1da546d28..1c37b3b71 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -371,10 +371,12 @@ consvar_t cv_chatnotifications= {"chatnotifications", "On", CV_SAVE, CV_OnOff, N consvar_t cv_chatspamprotection= {"chatspamprotection", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; // minichat text background -consvar_t cv_chatbacktint = {"chatbacktint", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_chatbacktint = {"chatbacktint", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; // old shit console chat. (mostly exists for stuff like terminal, not because I cared if anyone liked the old chat.) -consvar_t cv_consolechat= {"consolechat", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t consolechat_cons_t[] = {{0, "Window"}, {1, "Console"}, {2, "Window (Hidden)"}, {0, NULL}}; +consvar_t cv_consolechat = {"chatmode", "Window", CV_SAVE, consolechat_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; + consvar_t cv_crosshair = {"crosshair", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_crosshair2 = {"crosshair2", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -1583,7 +1585,7 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics) { localangle2 += (cmd->angleturn<<16); cmd->angleturn = (INT16)(localangle2 >> 16); - } + } } // User has designated that they want diff --git a/src/hu_stuff.c b/src/hu_stuff.c index a8f48051e..0bf4fcd89 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -325,10 +325,10 @@ void HU_Start(void) static UINT32 chat_nummsg_log = 0; static UINT32 chat_nummsg_min = 0; -static UINT32 chat_scroll = 0; +static UINT32 chat_scroll = 0; static tic_t chat_scrolltime = 0; -static INT32 chat_maxscroll = 0; // how far can we scroll? +static INT32 chat_maxscroll = 0; // how far can we scroll? //static chatmsg_t chat_mini[CHAT_BUFSIZE]; // Display the last few messages sent. //static chatmsg_t chat_log[CHAT_BUFSIZE]; // Keep every message sent to us in memory so we can scroll n shit, it's cool. @@ -341,7 +341,7 @@ static boolean chat_scrollmedown = false; // force instant scroll down on the ch // remove text from minichat table -static INT16 addy = 0; // use this to make the messages scroll smoothly when one fades away +static INT16 addy = 0; // use this to make the messages scroll smoothly when one fades away static void HU_removeChatText_Mini(void) { @@ -368,25 +368,32 @@ static void HU_removeChatText_Log(void) } chat_nummsg_log--; // lost 1 msg. } - -void HU_AddChatText(const char *text) + +void HU_AddChatText(const char *text, boolean playsound) { - - // TODO: check if we're oversaturating the log (we can only log CHAT_BUFSIZE messages.) - - if (chat_nummsg_log >= CHAT_BUFSIZE) + if (playsound && cv_consolechat.value != 2) // Don't play the sound if we're using hidden chat. + S_StartSound(NULL, sfx_radio); + // reguardless of our preferences, put all of this in the chat buffer in case we decide to change from oldchat mid-game. + + if (chat_nummsg_log >= CHAT_BUFSIZE) // too many messages! HU_removeChatText_Log(); - + strcpy(chat_log[chat_nummsg_log], text); chat_nummsg_log++; - + if (chat_nummsg_min >= 8) HU_removeChatText_Mini(); - + strcpy(chat_mini[chat_nummsg_min], text); chat_timers[chat_nummsg_min] = TICRATE*cv_chattime.value; chat_nummsg_min++; -} + + if (OLDCHAT) // if we're using oldchat, print directly in console + CONS_Printf("%s\n", text); + else // if we aren't, still save the message to log.txt + CON_LogMessage(va("%s\n", text)); +} + /** Runs a say command, sending an ::XD_SAY message. * A say command consists of a signed 8-bit integer for the target, an @@ -406,8 +413,8 @@ void HU_AddChatText(const char *text) * \sa Command_Say_f, Command_Sayteam_f, Command_Sayto_f, Got_Saycmd * \author Graue */ - - + + static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags) { XBOXSTATIC char buf[254]; @@ -418,18 +425,14 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags) numwords = COM_Argc() - usedargs; I_Assert(numwords > 0); -<<<<<<< HEAD - if (cv_mute.value && !(server || adminplayer == consoleplayer)) // TODO: Per Player mute. -======= - if (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer))) ->>>>>>> master + if (CHAT_MUTE) // TODO: Per Player mute. { - HU_AddChatText(va("%s>ERROR: The chat is muted. You can't say anything.", "\x85")); + HU_AddChatText(va("%s>ERROR: The chat is muted. You can't say anything.", "\x85"), false); return; } // Only servers/admins can CSAY. - if(!server && IsPlayerAdmin(consoleplayer)) + if(!server && !(IsPlayerAdmin(consoleplayer))) flags &= ~HU_CSAY; // We handle HU_SERVER_SAY, not the caller. @@ -447,51 +450,52 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags) strlcat(msg, " ", msgspace); strlcat(msg, COM_Argv(ix + usedargs), msgspace); } - + if (strlen(msg) > 4 && strnicmp(msg, "/pm", 3) == 0) // used /pm { // what we're gonna do now is check if the node exists // with that logic, characters 4 and 5 are our numbers: + const char *newmsg; int spc = 1; // used if nodenum[1] is a space. char *nodenum = (char*) malloc(3); strncpy(nodenum, msg+3, 5); // check for undesirable characters in our "number" if (((nodenum[0] < '0') || (nodenum[0] > '9')) || ((nodenum[1] < '0') || (nodenum[1] > '9'))) - { + { // check if nodenum[1] is a space if (nodenum[1] == ' ') spc = 0; // let it slide else - { - HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm \'."); + { + HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm \'.", false); return; - } + } } // I'm very bad at C, I swear I am, additional checks eww! if (spc != 0) - { + { if (msg[5] != ' ') { - HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm \'."); + HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm \'.", false); return; } } - + target = atoi((const char*) nodenum); // turn that into a number //CONS_Printf("%d\n", target); - + // check for target player, if it doesn't exist then we can't send the message! if (playeringame[target]) // player exists target++; // even though playernums are from 0 to 31, target is 1 to 32, so up that by 1 to have it work! else { - HU_AddChatText(va("\x82NOTICE: \x80Player %d does not exist.", target)); // same + HU_AddChatText(va("\x82NOTICE: \x80Player %d does not exist.", target), false); // same return; } buf[0] = target; - const char *newmsg = msg+5+spc; - memcpy(msg, newmsg, 255); + newmsg = msg+5+spc; + memcpy(msg, newmsg, 252); } SendNetXCmd(XD_SAY, buf, strlen(msg) + 1 + msg-buf); @@ -577,7 +581,6 @@ static void Command_CSay_f(void) DoSayCommand(0, 1, HU_CSAY); } - static tic_t stop_spamming_you_cunt[MAXPLAYERS]; /** Receives a message, processing an ::XD_SAY command. @@ -592,7 +595,8 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) char *msg; boolean action = false; char *ptr; - + int spam_eatmsg = 0; + CONS_Debug(DBG_NETPLAY,"Received SAY cmd from Player %d (%s)\n", playernum+1, player_names[playernum]); target = READSINT8(*p); @@ -600,7 +604,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) msg = (char *)*p; SKIPSTRING(*p); - if ((cv_mute.value || flags & (HU_CSAY|HU_SERVER_SAY)) && playernum != serverplayer && !IsPlayerAdmin(playernum)) + if ((cv_mute.value || flags & (HU_CSAY|HU_SERVER_SAY)) && playernum != serverplayer && !(IsPlayerAdmin(playernum))) { CONS_Alert(CONS_WARNING, cv_mute.value ? M_GetText("Illegal say command received from %s while muted\n") : M_GetText("Illegal csay command received from non-admin %s\n"), @@ -637,32 +641,29 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) } } } - - int spam_eatmsg = 0; - + // before we do anything, let's verify the guy isn't spamming, get this easier on us. - + //if (stop_spamming_you_cunt[playernum] != 0 && cv_chatspamprotection.value && !(flags & HU_CSAY)) if (stop_spamming_you_cunt[playernum] != 0 && consoleplayer != playernum && cv_chatspamprotection.value && !(flags & HU_CSAY)) - { + { CONS_Debug(DBG_NETPLAY,"Received SAY cmd too quickly from Player %d (%s), assuming as spam and blocking message.\n", playernum+1, player_names[playernum]); stop_spamming_you_cunt[playernum] = 4; spam_eatmsg = 1; } else stop_spamming_you_cunt[playernum] = 4; // you can hold off for 4 tics, can you? - + // run the lua hook even if we were supposed to eat the msg, netgame consistency goes first. - -/*#ifdef HAVE_BLUA + +#ifdef HAVE_BLUA if (LUAh_PlayerMsg(playernum, target, flags, msg, spam_eatmsg)) return; -#endif*/ - // Kill PlayerMsg for now, it breaks the purpose of this EXE. - +#endif + if (spam_eatmsg) return; // don't proceed if we were supposed to eat the message. - + // If it's a CSAY, just CECHO and be done with it. if (flags & HU_CSAY) { @@ -702,23 +703,55 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) || target == 0 // To everyone || consoleplayer == target-1) // To you { - const char *prefix = "", *cstart = "", *cend = "", *adminchar = "\x82~\x83", *remotechar = "\x82@\x83", *fmt, *fmt2; + const char *prefix = "", *cstart = "", *cend = "", *adminchar = "\x82~\x83", *remotechar = "\x82@\x83", *fmt2, *textcolor = "\x80"; char *tempchar = NULL; - - // In CTF and team match, color the player's name. - if (G_GametypeHasTeams()) - { - cend = ""; - if (players[playernum].ctfteam == 1) // red - cstart = "\x85"; - else if (players[playernum].ctfteam == 2) // blue - cstart = "\x84"; - - } - + // player is a spectator? - if (players[playernum].spectator) - cstart = "\x86"; // grey name + if (players[playernum].spectator) + { + cstart = "\x86"; // grey name + textcolor = "\x86"; + } + else if (target == -1) // say team + { + if (players[playernum].ctfteam == 1) // red + { + cstart = "\x85"; + textcolor = "\x85"; + } + else // blue + { + cstart = "\x84"; + textcolor = "\x84"; + } + } + else + { + + cstart = "\x83"; + const UINT8 color = players[playernum].skincolor; + if (color <= SKINCOLOR_SILVER) + cstart = "\x80"; // White + else if (color <= SKINCOLOR_BLACK) + cstart = "\x86"; // Grey + else if (color <= SKINCOLOR_BLUE) + cstart = "\x84"; // Blue + else if (color <= SKINCOLOR_PEACH) + cstart = "\x87"; //... Orange??? + else if (color == SKINCOLOR_PINK) + cstart = "\x85"; // Red. + else if (color <= SKINCOLOR_PURPLE) + cstart = "\x81"; // Purple + else if (color <= SKINCOLOR_ROSEWOOD) + cstart = "\x87"; // Orange + else if (color <= SKINCOLOR_DARKRED) + cstart = "\x85"; // Red + else if (color <= SKINCOLOR_OLIVE) + cstart = "\x83"; // green + else if (color <= SKINCOLOR_GOLD) + cstart = "\x82"; // Yellow + } + prefix = cstart; // Give admins and remote admins their symbols. if (playernum == serverplayer) @@ -740,61 +773,39 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) // name, color end, and the message itself. // '\4' makes the message yellow and beeps; '\3' just beeps. if (action) - { - fmt = "\3* %s%s%s%s \x82%s\n"; // don't make /me yellow, yellow will be for mentions and PMs! - fmt2 = "* %s%s%s%s \x82%s"; - } - else if (target == 0) // To everyone - { - fmt = "\3%s\x83<%s%s%s\x83>\x80 %s\n"; - fmt2 = "%s\x83<%s%s%s\x83>\x80 %s"; - } + fmt2 = "* %s%s%s%s \x82%s%s"; else if (target-1 == consoleplayer) // To you { prefix = "\x82[PM]"; cstart = "\x82"; - fmt = "\4%s<%s%s>%s\x80 %s\n"; // make this yellow, however. - fmt2 = "%s<%s%s>%s\x80 %s"; + textcolor = "\x82"; + fmt2 = "%s<%s%s>%s\x80 %s%s"; } else if (target > 0) // By you, to another player { // Use target's name. dispname = player_names[target-1]; - /*fmt = "\3\x82[TO]\x80%s%s%s* %s\n"; - fmt2 = "\x82[TO]\x80%s%s%s* %s";*/ prefix = "\x82[TO]"; cstart = "\x82"; - fmt = "\4%s<%s%s>%s\x80 %s\n"; // make this yellow, however. - fmt2 = "%s<%s%s>%s\x80 %s"; - + fmt2 = "%s<%s%s>%s\x80 %s%s"; + } + else if (target == 0) // To everyone + fmt2 = "%s<%s%s%s>\x80 %s%s"; else // To your team { - if (players[playernum].ctfteam == 1) // red - prefix = "\x85[TEAM]"; + if (players[playernum].ctfteam == 1) // red + prefix = "\x85[TEAM]"; else if (players[playernum].ctfteam == 2) // blue prefix = "\x84[TEAM]"; else prefix = "\x83"; // makes sure this doesn't implode if you sayteam on non-team gamemodes - - fmt = "\3%s<%s%s>\x80%s %s\n"; - fmt2 = "%s<%s%s>\x80%s %s"; - - } - - if OLDCHAT - { - CONS_Printf(fmt, prefix, cstart, dispname, cend, msg); - HU_AddChatText(va(fmt2, prefix, cstart, dispname, cend, msg)); // add it reguardless, in case we decide to change our mind about our chat type. - } - else - { - HU_AddChatText(va(fmt2, prefix, cstart, dispname, cend, msg)); - CON_LogMessage(va(fmt, prefix, cstart, dispname, cend, msg)); // save to log.txt - if (cv_chatnotifications.value) - S_StartSound(NULL, sfx_radio); - } - + + fmt2 = "%s<%s%s>\x80%s %s%s"; + } + + HU_AddChatText(va(fmt2, prefix, cstart, dispname, cend, textcolor, msg), cv_chatnotifications.value); // add to chat + if (tempchar) Z_Free(tempchar); } @@ -825,10 +836,10 @@ static inline boolean HU_keyInChatString(char *s, char ch) { s[l++] = ch; s[l]=0; - } + } else - { - + { + // move everything past c_input for new characters: INT32 m = HU_MAXMSGLEN-1; for (;(m>=c_input);m--) @@ -850,16 +861,16 @@ static inline boolean HU_keyInChatString(char *s, char ch) size_t i = c_input; if (!s[i-1]) return false; - + if (i >= strlen(s)-1) - { + { s[strlen(s)-1] = 0; c_input--; return false; - } - + } + for (; (i < HU_MAXMSGLEN); i++) - { + { s[i-1] = s[i]; } c_input--; @@ -909,78 +920,78 @@ static void HU_queueChatChar(char c) size_t i = 0; for (;(iERROR: The chat is muted. You can't say anything.", "\x85")); + HU_AddChatText(va("%s>ERROR: The chat is muted. You can't say anything.", "\x85"), false); return; } - + INT32 target = 0; - + if (strlen(msg) > 4 && strnicmp(msg, "/pm", 3) == 0) // used /pm { // what we're gonna do now is check if the node exists // with that logic, characters 4 and 5 are our numbers: - + // teamtalk can't send PMs, just don't send it, else everyone would be able to see it, and no one wants to see your sex RP sicko. if (teamtalk) { - HU_AddChatText(va("%sCannot send sayto in Say-Team.", "\x85")); + HU_AddChatText(va("%sCannot send sayto in Say-Team.", "\x85"), false); return; - } - + } + int spc = 1; // used if nodenum[1] is a space. char *nodenum = (char*) malloc(3); strncpy(nodenum, msg+3, 5); // check for undesirable characters in our "number" if (((nodenum[0] < '0') || (nodenum[0] > '9')) || ((nodenum[1] < '0') || (nodenum[1] > '9'))) - { + { // check if nodenum[1] is a space if (nodenum[1] == ' ') spc = 0; // let it slide else - { - HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm \'."); - return; - } - } - // I'm very bad at C, I swear I am, additional checks eww! - if (spc != 0) - { - if (msg[5] != ' ') { - HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm \'."); + HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm \'.", false); return; } } - + // I'm very bad at C, I swear I am, additional checks eww! + if (spc != 0) + { + if (msg[5] != ' ') + { + HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm \'.", false); + return; + } + } + target = atoi((const char*) nodenum); // turn that into a number //CONS_Printf("%d\n", target); - + // check for target player, if it doesn't exist then we can't send the message! if (playeringame[target]) // player exists target++; // even though playernums are from 0 to 31, target is 1 to 32, so up that by 1 to have it work! else { - HU_AddChatText(va("\x82NOTICE: \x80Player %d does not exist.", target)); // same + HU_AddChatText(va("\x82NOTICE: \x80Player %d does not exist.", target), false); // same return; } // we need to get rid of the /pm const char *newmsg = msg+5+spc; memcpy(msg, newmsg, 255); - } + } if (ci > 3) // don't send target+flags+empty message. { if (teamtalk) buf[0] = -1; // target else buf[0] = target; - + buf[1] = 0; // flags SendNetXCmd(XD_SAY, buf, 2 + strlen(&buf[2]) + 1); } @@ -999,53 +1010,81 @@ void HU_clearChatChars(void) static boolean justscrolleddown; static boolean justscrolledup; +static INT16 typelines = 1; // number of drawfill lines we need when drawing the chat. it's some weird hack and might be one frame off but I'm lazy to make another loop. +// It's up here since it has to be reset when we open the chat. + // // Returns true if key eaten // boolean HU_Responder(event_t *ev) { - UINT8 c=0; - + INT32 c=0; + if (ev->type != ev_keydown) return false; // only KeyDown events now... - + + /*// Shoot, to prevent P1 chatting from ruining the game for everyone else, it's either: + // A. completely disallow opening chat entirely in online splitscreen + // or B. iterate through all controls to make sure it's bound to player 1 before eating + // You can see which one I chose. + // (Unless if you're sharing a keyboard, since you probably establish when you start chatting that you have dibs on it...) + // (Ahhh, the good ol days when I was a kid who couldn't afford an extra USB controller...) + + if (ev->data1 >= KEY_MOUSE1) + { + INT32 i; + for (i = 0; i < num_gamecontrols; i++) + { + if (gamecontrol[i][0] == ev->data1 || gamecontrol[i][1] == ev->data1) + break; + } + + if (i == num_gamecontrols) + return false; + }*/ //We don't actually care about that unless we get splitscreen netgames. :V + + c = (INT32)ev->data1; + + // capslock (now handled outside of chat on so that it works everytime......) + if (c && c == KEY_CAPSLOCK) // it's a toggle. + { + if (capslock) + capslock = false; + else + capslock = true; + return true; + } + if (!chat_on) { // enter chat mode if ((ev->data1 == gamecontrol[gc_talkkey][0] || ev->data1 == gamecontrol[gc_talkkey][1]) - && netgame && (!cv_mute.value || server || IsPlayerAdmin(consoleplayer))) + && netgame && !OLD_MUTE) // check for old chat mute, still let the players open the chat incase they want to scroll otherwise. { - if (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer))) - return false; chat_on = true; w_chat[0] = 0; teamtalk = false; chat_scrollmedown = true; + typelines = 1; return true; } if ((ev->data1 == gamecontrol[gc_teamkey][0] || ev->data1 == gamecontrol[gc_teamkey][1]) - && netgame && (!cv_mute.value || server || (IsPlayerAdmin(consoleplayer)))) + && netgame && !OLD_MUTE) { -<<<<<<< HEAD - if (cv_mute.value && !(server || adminplayer == consoleplayer)) -======= - if (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer))) ->>>>>>> master - return false; chat_on = true; w_chat[0] = 0; - teamtalk = true; -<<<<<<< HEAD + teamtalk = G_GametypeHasTeams(); // Don't teamtalk if we don't have teams. chat_scrollmedown = true; + typelines = 1; return true; } } else // if chat_on { - + // Ignore modifier keys // Note that we do this here so users can still set // their chat keys to one of these, if they so desire. @@ -1054,43 +1093,38 @@ boolean HU_Responder(event_t *ev) || ev->data1 == KEY_LALT || ev->data1 == KEY_RALT) return true; - c = (UINT8)ev->data1; - - // capslock - if (c && c == KEY_CAPSLOCK) // it's a toggle. - { - if (capslock) - capslock = false; - else - capslock = true; - return true; - } - - // use console translations + c = (INT32)ev->data1; - if (c >= 'a' && c <= 'z') + // I know this looks very messy but this works. If it ain't broke, don't fix it! + // shift LETTERS to uppercase if we have capslock or are holding shift + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { - if (capslock ^ shiftdown) + if (shiftdown ^ capslock) c = shiftxform[c]; } - else if (shiftdown) - c = shiftxform[c]; - + else // if we're holding shift we should still shift non letter symbols + { + if (shiftdown) + c = shiftxform[c]; + } + // pasting. pasting is cool. chat is a bit limited, though :( - if ((c == 'v' || c == 'V') && ctrldown) + if (((c == 'v' || c == 'V') && ctrldown) && !CHAT_MUTE) { const char *paste = I_ClipboardPaste(); - + size_t chatlen; + size_t pastelen; + // create a dummy string real quickly - + if (paste == NULL) return true; - - size_t chatlen = strlen(w_chat); - size_t pastelen = strlen(paste); + + chatlen = strlen(w_chat); + pastelen = strlen(paste); if (chatlen+pastelen > HU_MAXMSGLEN) return true; // we can't paste this!! - + if (c_input >= strlen(w_chat)) // add it at the end of the string. { memcpy(&w_chat[chatlen], paste, pastelen); // copy all of that. @@ -1103,85 +1137,64 @@ boolean HU_Responder(event_t *ev) return true; } else // otherwise, we need to shift everything and make space, etc etc - { + { size_t i = HU_MAXMSGLEN-1; for (; i>=c_input;i--) { if (w_chat[i]) w_chat[i+pastelen] = w_chat[i]; - + } memcpy(&w_chat[c_input], paste, pastelen); // copy all of that. c_input += pastelen; return true; } } - - if (HU_keyInChatString(w_chat,c)) - { + + if (!CHAT_MUTE && HU_keyInChatString(w_chat,c)) + { HU_queueChatChar(c); - } + } if (c == KEY_ENTER) - { + { chat_on = false; c_input = 0; // reset input cursor chat_scrollmedown = true; // you hit enter, so you might wanna autoscroll to see what you just sent. :) - } - else if (c == KEY_ESCAPE) - { + } + else if (c == KEY_ESCAPE + || ((c == gamecontrol[gc_talkkey][0] || c == gamecontrol[gc_talkkey][1] + || c == gamecontrol[gc_teamkey][0] || c == gamecontrol[gc_teamkey][1]) + && c >= KEY_MOUSE1)) // If it's not a keyboard key, then the chat button is used as a toggle. + { chat_on = false; c_input = 0; // reset input cursor - } - else if ((c == KEY_UPARROW || c == KEY_MOUSEWHEELUP) && chat_scroll > 0) // CHAT SCROLLING YAYS! + } + else if ((c == KEY_UPARROW || c == KEY_MOUSEWHEELUP) && chat_scroll > 0 && !OLDCHAT) // CHAT SCROLLING YAYS! { chat_scroll--; justscrolledup = true; chat_scrolltime = 4; - } - else if ((c == KEY_DOWNARROW || c == KEY_MOUSEWHEELDOWN) && chat_scroll < chat_maxscroll && chat_maxscroll > 0) - { + } + else if ((c == KEY_DOWNARROW || c == KEY_MOUSEWHEELDOWN) && chat_scroll < chat_maxscroll && chat_maxscroll > 0 && !OLDCHAT) + { chat_scroll++; justscrolleddown = true; chat_scrolltime = 4; } - else if (c == KEY_LEFTARROW && c_input != 0) // i said go back + else if (c == KEY_LEFTARROW && c_input != 0 && !OLDCHAT) // i said go back c_input--; - else if (c == KEY_RIGHTARROW && c_input < strlen(w_chat)) - c_input++; + else if (c == KEY_RIGHTARROW && c_input < strlen(w_chat) && !OLDCHAT) // don't need to check for admin or w/e here since the chat won't ever contain anything if it's muted. + c_input++; return true; } return false; } + //====================================================================== // HEADS UP DRAWING //====================================================================== -// Gets string colormap, used for 0x80 color codes -// -static UINT8 *CHAT_GetStringColormap(INT32 colorflags) // pasted from video.c, sorry for the mess. -{ - switch ((colorflags & V_CHARCOLORMASK) >> V_CHARCOLORSHIFT) - { - case 1: // 0x81, purple - return purplemap; - case 2: // 0x82, yellow - return yellowmap; - case 3: // 0x83, lgreen - return lgreenmap; - case 4: // 0x84, blue - return bluemap; - case 5: // 0x85, red - return redmap; - case 6: // 0x86, gray - return graymap; - case 7: // 0x87, orange - return orangemap; - default: // reset - return NULL; - } -} - // Precompile a wordwrapped string to any given width. // This is a muuuch better method than V_WORDWRAP. // again stolen and modified a bit from video.c, don't mind me, will need to rearrange this one day. @@ -1190,7 +1203,7 @@ char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string) { int c; size_t chw, i, lastusablespace = 0; - size_t slen; + size_t slen; char *newstring = Z_StrDup(string); INT32 spacewidth = (vid.width < 640) ? 8 : 4, charwidth = (vid.width < 640) ? 8 : 4; @@ -1228,7 +1241,7 @@ char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string) { //CONS_Printf("Wrap at index %d\n", i); newstring[lastusablespace] = '\n'; - i = lastusablespace+1; + i = lastusablespace+1; lastusablespace = 0; x = 0; } @@ -1247,21 +1260,26 @@ INT16 chatx = 13, chaty = 169; // let's use this as our coordinates, shh static void HU_drawMiniChat(void) { - if (!chat_nummsg_min) - return; // needless to say it's useless to do anything if we don't have anything to draw. - INT32 x = chatx+2; INT32 charwidth = 4, charheight = 6; + INT32 boxw = cv_chatwidth.value; INT32 dx = 0, dy = 0; size_t i = chat_nummsg_min; boolean prev_linereturn = false; // a hack to prevent double \n while I have no idea why they happen in the first place. INT32 msglines = 0; // process all messages once without rendering anything or doing anything fancy so that we know how many lines each message has... + INT32 y; + + if (!chat_nummsg_min) + return; // needless to say it's useless to do anything if we don't have anything to draw. + + /*if (splitscreen > 1) + boxw = max(64, boxw/2);*/ for (; i>0; i--) { - const char *msg = CHAT_WordWrap(x+2, cv_chatwidth.value-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]); + const char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]); size_t j = 0; INT32 linescount = 0; @@ -1273,10 +1291,10 @@ static void HU_drawMiniChat(void) { ++j; if (!prev_linereturn) - { + { linescount += 1; dx = 0; - } + } prev_linereturn = true; continue; } @@ -1294,7 +1312,7 @@ static void HU_drawMiniChat(void) } prev_linereturn = false; dx += charwidth; - if (dx >= cv_chatwidth.value) + if (dx >= boxw) { dx = 0; linescount += 1; @@ -1305,7 +1323,17 @@ static void HU_drawMiniChat(void) msglines += linescount+1; } - INT32 y = chaty - charheight*(msglines+1); + y = chaty - charheight*(msglines+1); + + if (splitscreen) + { + y -= BASEVIDHEIGHT/2; + if (splitscreen > 1) + y += 16; + } + /*else + y -= (cv_kartspeedometer.value ? 16 : 0);*/ + dx = 0; dy = 0; i = 0; @@ -1317,7 +1345,8 @@ static void HU_drawMiniChat(void) INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below... INT32 transflag = (timer >= 0 && timer <= 9) ? (timer*V_10TRANS) : 0; // you can make bad jokes out of this one. size_t j = 0; - const char *msg = CHAT_WordWrap(x+2, cv_chatwidth.value-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it. + const char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it. + UINT8 *colormap = NULL; while(msg[j]) // iterate through msg { @@ -1327,16 +1356,17 @@ static void HU_drawMiniChat(void) { ++j; if (!prev_linereturn) - { + { dy += charheight; dx = 0; - } + } prev_linereturn = true; continue; } else if (msg[j] & 0x80) // stolen from video.c, nice. { clrflag = ((msg[j] & 0x7f) << V_CHARCOLORSHIFT) & V_CHARCOLORMASK; + colormap = V_GetStringColormap(clrflag); ++j; continue; } @@ -1345,8 +1375,6 @@ static void HU_drawMiniChat(void) } else { - UINT8 *colormap = CHAT_GetStringColormap(clrflag); - if (cv_chatbacktint.value) // on request of wolfy V_DrawFillConsoleMap(x + dx + 2, y+dy, charwidth, charheight, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT); @@ -1355,7 +1383,7 @@ static void HU_drawMiniChat(void) dx += charwidth; prev_linereturn = false; - if (dx >= cv_chatwidth.value) + if (dx >= boxw) { dx = 0; dy += charheight; @@ -1370,6 +1398,7 @@ static void HU_drawMiniChat(void) } + // HU_DrawUpArrow // You see, we don't have arrow graphics in 2.1 and I'm too lazy to include a 2 bytes file for it. @@ -1379,7 +1408,7 @@ static void HU_DrawUpArrow(INT32 x, INT32 y, INT32 options) V_DrawFill(x+2, y, 1, 1, 103|options); V_DrawFill(x+1, y+1, 3, 1, 103|options); V_DrawFill(x, y+2, 5, 1, 103|options); // that's the yellow part, I swear - + V_DrawFill(x+3, y, 1, 1, 26|options); V_DrawFill(x+4, y+1, 1, 1, 26|options); V_DrawFill(x+5, y+2, 1, 1, 26|options); @@ -1396,36 +1425,61 @@ static void HU_DrawDownArrow(INT32 x, INT32 y, INT32 options) V_DrawFill(x, y+1, 5, 1, 26|options); V_DrawFill(x+1, y+2, 3, 1, 26|options); V_DrawFill(x+2, y+3, 1, 1, 26|options); // that's the black part. no racism intended. i swear. - + V_DrawFill(x, y, 5, 1, 103|options); V_DrawFill(x+1, y+1, 3, 1, 103|options); V_DrawFill(x+2, y+2, 1, 1, 103|options); // that's the yellow part, I swear -} +} // HU_DrawChatLog -// TODO: fix dumb word wrapping issues static void HU_drawChatLog(INT32 offset) { + INT32 charwidth = 4, charheight = 6; + INT32 boxw = cv_chatwidth.value, boxh = cv_chatheight.value; + INT32 x = chatx+2, y, dx = 0, dy = 0; + UINT32 i = 0; + INT32 chat_topy, chat_bottomy; + boolean atbottom = false; - // before we do anything, make sure that our scroll position isn't "illegal"; + // make sure that our scroll position isn't "illegal"; if (chat_scroll > chat_maxscroll) chat_scroll = chat_maxscroll; - INT32 charwidth = 4, charheight = 6; - INT32 x = chatx+2, y = chaty - offset*charheight - (chat_scroll*charheight) - cv_chatheight.value*charheight - 12, dx = 0, dy = 0; - UINT32 i = 0; - INT32 chat_topy = y + chat_scroll*charheight; - INT32 chat_bottomy = chat_topy + cv_chatheight.value*charheight; - boolean atbottom = false; + /*if (splitscreen) + { + boxh = max(6, boxh/2); + if (splitscreen > 1) + boxw = max(64, boxw/2); + }*/ - V_DrawFillConsoleMap(chatx, chat_topy, cv_chatwidth.value, cv_chatheight.value*charheight +2, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT); // log box + // Unused SRB2KART splitscreen stuff. I'll leave it here in case it ever happens in Vanilla? + + y = chaty - offset*charheight - (chat_scroll*charheight) - boxh*charheight - 12; + + /*if (splitscreen) + { + y -= BASEVIDHEIGHT/2; + if (splitscreen > 1) + y += 16; + } + else + y -= (cv_kartspeedometer.value ? 16 : 0);*/ + + // Unused SRB2KART splitscreen stuff. I'll leave it here in case it ever happens in Vanilla? (x2) + + + chat_topy = y + chat_scroll*charheight; + chat_bottomy = chat_topy + boxh*charheight; + + V_DrawFillConsoleMap(chatx, chat_topy, boxw, boxh*charheight +2, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT); // log box for (i=0; i= chat_topy) && (y+dy < (chat_bottomy))) - { - UINT8 *colormap = CHAT_GetStringColormap(clrflag); V_DrawChatCharacter(x + dx + 2, y+dy+2, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT, !cv_allcaps.value, colormap); - } else j++; // don't forget to increment this or we'll get stuck in the limbo. } dx += charwidth; - if (dx >= cv_chatwidth.value-charwidth-2 && i= HU_FONTSTART) // end of message shouldn't count, nor should invisible characters!!!! + if (dx >= boxw-charwidth-2 && i= HU_FONTSTART) // end of message shouldn't count, nor should invisible characters!!!! { dx = 0; dy += charheight; @@ -1468,6 +1520,7 @@ static void HU_drawChatLog(INT32 offset) dx = 0; } + if (((chat_scroll >= chat_maxscroll) || (chat_scrollmedown)) && !(justscrolleddown || justscrolledup || chat_scrolltime)) // was already at the bottom of the page before new maxscroll calculation and was NOT scrolling. { atbottom = true; // we should scroll @@ -1502,14 +1555,30 @@ static void HU_drawChatLog(INT32 offset) // Draw chat input // -static INT16 typelines = 1; // number of drawfill lines we need. it's some weird hack and might be one frame off but I'm lazy to make another loop. static void HU_DrawChat(void) { INT32 charwidth = 4, charheight = 6; + INT32 boxw = cv_chatwidth.value; INT32 t = 0, c = 0, y = chaty - (typelines*charheight); - UINT32 i = 0; + UINT32 i = 0, saylen = strlen(w_chat); // You learn new things everyday! + INT32 cflag = 0; const char *ntalk = "Say: ", *ttalk = "Team: "; const char *talk = ntalk; + const char *mute = "Chat has been muted."; + + /*if (splitscreen) + { + y -= BASEVIDHEIGHT/2; + if (splitscreen > 1) + { + y += 16; + boxw = max(64, boxw/2); + } + } + else + y -= (cv_kartspeedometer.value ? 16 : 0);*/ + + // More unused SRB2KART stuff. if (teamtalk) { @@ -1522,18 +1591,35 @@ static void HU_DrawChat(void) #endif } - V_DrawFillConsoleMap(chatx, y-1, cv_chatwidth.value, (typelines*charheight), 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT); + if (CHAT_MUTE) + { + talk = mute; + typelines = 1; + cflag = V_GRAYMAP; // set text in gray if chat is muted. + } + + V_DrawFillConsoleMap(chatx, y-1, boxw, (typelines*charheight), 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT); while (talk[i]) { if (talk[i] < HU_FONTSTART) ++i; else - V_DrawChatCharacter(chatx + c + 2, y, talk[i++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT, !cv_allcaps.value, NULL); + { + V_DrawChatCharacter(chatx + c + 2, y, talk[i] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|cflag, !cv_allcaps.value, V_GetStringColormap(talk[i]|cflag)); + i++; + } c += charwidth; } + // if chat is muted, just draw the log and get it over with, no need to draw anything else. + if (CHAT_MUTE) + { + HU_drawChatLog(0); + return; + } + i = 0; typelines = 1; @@ -1545,12 +1631,12 @@ static void HU_DrawChat(void) boolean skippedline = false; if (c_input == (i+1)) { - int cursorx = (c+charwidth < cv_chatwidth.value-charwidth) ? (chatx + 2 + c+charwidth) : (chatx+1); // we may have to go down. + int cursorx = (c+charwidth < boxw-charwidth) ? (chatx + 2 + c+charwidth) : (chatx+1); // we may have to go down. int cursory = (cursorx != chatx+1) ? (y) : (y+charheight); if (hu_tick < 4) V_DrawChatCharacter(cursorx, cursory+1, '_' |V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL); - if (cursorx == chatx+1) // a weirdo hack + if (cursorx == chatx+1 && saylen == i) // a weirdo hack { typelines += 1; skippedline = true; @@ -1565,38 +1651,47 @@ static void HU_DrawChat(void) V_DrawChatCharacter(chatx + c + 2, y, w_chat[i++] | V_SNAPTOBOTTOM|V_SNAPTOLEFT | t, !cv_allcaps.value, NULL); c += charwidth; - if (c > cv_chatwidth.value-(charwidth*2) && !skippedline) + if (c > boxw-(charwidth*2) && !skippedline) { c = 0; y += charheight; typelines += 1; -======= - return true; ->>>>>>> master } } - // handle /pm list. + // handle /pm list. It's messy, horrible and I don't care. if (strnicmp(w_chat, "/pm", 3) == 0 && vid.width >= 400 && !teamtalk) // 320x200 unsupported kthxbai { - i = 0; INT32 count = 0; INT32 p_dispy = chaty - charheight -1; + /*if (splitscreen) + { + p_dispy -= BASEVIDHEIGHT/2; + if (splitscreen > 1) + p_dispy += 16; + } + else + p_dispy -= (cv_kartspeedometer.value ? 16 : 0);*/ + + // more kart leftovers. + + i = 0; for(i=0; (i '9'))) || ((w_chat[4] != 0) && (((w_chat[4] < '0') || (w_chat[4] > '9'))))) && (w_chat[4] != ' ')) break; - char *nodenum = (char*) malloc(3); + nodenum = (char*) malloc(3); strncpy(nodenum, w_chat+3, 4); - UINT32 n = atoi((const char*) nodenum); // turn that into a number + n = atoi((const char*) nodenum); // turn that into a number // special cases: if ((n == 0) && !(w_chat[4] == '0')) @@ -1630,8 +1725,8 @@ static void HU_DrawChat(void) { char name[MAXPLAYERNAME+1]; strlcpy(name, player_names[i], 7); // shorten name to 7 characters. - V_DrawFillConsoleMap(chatx+ cv_chatwidth.value + 2, p_dispy- (6*count), 48, 6, 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT); // fill it like the chat so the text doesn't become hard to read because of the hud. - V_DrawSmallString(chatx+ cv_chatwidth.value + 4, p_dispy- (6*count), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, va("\x82%d\x80 - %s", i, name)); + V_DrawFillConsoleMap(chatx+ boxw + 2, p_dispy- (6*count), 48, 6, 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT); // fill it like the chat so the text doesn't become hard to read because of the hud. + V_DrawSmallString(chatx+ boxw + 4, p_dispy- (6*count), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, va("\x82%d\x80 - %s", i, name)); count++; } } @@ -1646,7 +1741,8 @@ static void HU_DrawChat(void) } -// why the fuck would you use this... + +// For anyone who, for some godforsaken reason, likes oldchat. static void HU_DrawChat_Old(void) { @@ -1681,21 +1777,21 @@ static void HU_DrawChat_Old(void) } c += charwidth; } - + if ((strlen(w_chat) == 0 || c_input == 0) && hu_tick < 4) V_DrawCharacter(HU_INPUTX+c, y+2*con_scalefactor, '_' |cv_constextsize.value | V_NOSCALESTART|t, !cv_allcaps.value); - + i = 0; while (w_chat[i]) { - + if (c_input == (i+1) && hu_tick < 4) { int cursorx = (HU_INPUTX+c+charwidth < vid.width) ? (HU_INPUTX + c + charwidth) : (HU_INPUTX); // we may have to go down. int cursory = (cursorx != HU_INPUTX) ? (y) : (y+charheight); - V_DrawCharacter(cursorx, cursory+2*con_scalefactor, '_' |cv_constextsize.value | V_NOSCALESTART|t, !cv_allcaps.value); - } - + V_DrawCharacter(cursorx, cursory+2*con_scalefactor, '_' |cv_constextsize.value | V_NOSCALESTART|t, !cv_allcaps.value); + } + //Hurdler: isn't it better like that? if (w_chat[i] < HU_FONTSTART) { @@ -1887,8 +1983,8 @@ void HU_Drawer(void) { // draw chat string plus cursor if (chat_on) - { - // count down the scroll timer. + { + // count down the scroll timer. if (chat_scrolltime > 0) chat_scrolltime--; if (!OLDCHAT) @@ -1898,28 +1994,26 @@ void HU_Drawer(void) } else { - if (!OLDCHAT) - { + typelines = 1; + chat_scrolltime = 0; + if (!OLDCHAT && cv_consolechat.value < 2) // Don't display minimized chat if you set the mode to Window (Hidden) HU_drawMiniChat(); // draw messages in a cool fashion. - chat_scrolltime = 0; // do scroll anyway. - typelines = 0; // make sure that the chat doesn't have a weird blinking huge ass square if we typed a lot last time. - } } if (netgame) // would handle that in hu_drawminichat, but it's actually kinda awkward when you're typing a lot of messages. (only handle that in netgames duh) { size_t i = 0; - + // handle spam while we're at it: for(; (i 0) stop_spamming_you_cunt[i]--; - } - + } + // handle chat timers for (i=0; (i 0) chat_timers[i]--; else @@ -2069,29 +2163,29 @@ void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext) SINT8 i = 0; SINT8 yoffset = 6; if (ping < 128) - { + { numbars = 3; barcolor = 184; - } + } else if (ping < 256) - { + { numbars = 2; // Apparently ternaries w/ multiple statements don't look good in C so I decided against it. barcolor = 103; - } - + } + INT32 dx = x+1 - (V_SmallStringWidth(va("%dms", ping), V_ALLOWLOWERCASE)/2); if (!notext || vid.width >= 640) // how sad, we're using a shit resolution. V_DrawSmallString(dx, y+4, V_ALLOWLOWERCASE, va("%dms", ping)); - + for (i=0; (i<3); i++) // Draw the ping bar - { + { V_DrawFill(x+2 *(i-1), y+yoffset-4, 2, 8-yoffset, 31); if (i < numbars) V_DrawFill(x+2 *(i-1), y+yoffset-3, 1, 8-yoffset-1, barcolor); - + yoffset -= 2; } -} +} // // HU_DrawTabRankings @@ -2110,15 +2204,15 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I { if (players[tab[i].num].spectator) continue; //ignore them. - + if (!splitscreen) // don't draw it on splitscreen, { if (!(tab[i].num == serverplayer)) HU_drawPing(x+ 253, y+2, playerpingtable[tab[i].num], false); //else - // V_DrawSmallString(x+ 246, y+4, V_YELLOWMAP, "SERVER"); - } - + // V_DrawSmallString(x+ 246, y+4, V_YELLOWMAP, "SERVER"); + } + V_DrawString(x + 20, y, ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) | ((players[tab[i].num].health > 0) ? 0 : V_60TRANS) @@ -2236,7 +2330,7 @@ static void HU_Draw32TeamTabRankings(playersort_t *tab, INT32 whiteplayer) V_DrawFill(160, 26, 1, 154, 0); //Draw a vertical line to separate the two teams. V_DrawFill(1, 26, 318, 1, 0); //And a horizontal line to make a T. V_DrawFill(1, 180, 318, 1, 0); //And a horizontal line near the bottom. - + for (i = 0; i < MAXPLAYERS; i++) { if (players[tab[i].num].spectator) @@ -2293,11 +2387,11 @@ static void HU_Draw32TeamTabRankings(playersort_t *tab, INT32 whiteplayer) } V_DrawRightAlignedThinString(x+128, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); if (!splitscreen) - { + { if (!(tab[i].num == serverplayer)) HU_drawPing(x+ 135, y+3, playerpingtable[tab[i].num], true); //else - //V_DrawSmallString(x+ 129, y+4, V_YELLOWMAP, "HOST"); + //V_DrawSmallString(x+ 129, y+4, V_YELLOWMAP, "HOST"); } } } @@ -2323,37 +2417,37 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) { smol = true; break; // don't make more loops than we need to. - } + } } else if (tab[i].color == skincolor_blueteam) //blue { if (blueplayers++ > 8) - { + { smol = true; break; - } + } } else //er? not on red or blue, so ignore them continue; - + } - + // I'll be blunt with you, this may add more lines, but I'm not adding weird cases for this, so we're executing a separate function. if (smol == true || cv_compactscoreboard.value) - { + { HU_Draw32TeamTabRankings(tab, whiteplayer); return; - } - + } + V_DrawFill(160, 26, 1, 154, 0); //Draw a vertical line to separate the two teams. V_DrawFill(1, 26, 318, 1, 0); //And a horizontal line to make a T. V_DrawFill(1, 180, 318, 1, 0); //And a horizontal line near the bottom. - + const UINT8 *colormap; char name[MAXPLAYERNAME+1]; - + i=0, redplayers=0, blueplayers=0; - + for (i = 0; i < MAXPLAYERS; i++) { if (players[tab[i].num].spectator) @@ -2412,11 +2506,11 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) } V_DrawRightAlignedThinString(x+100, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); if (!splitscreen) - { + { if (!(tab[i].num == serverplayer)) HU_drawPing(x+ 113, y+2, playerpingtable[tab[i].num], false); //else - // V_DrawSmallString(x+ 94, y+4, V_YELLOWMAP, "SERVER"); + // V_DrawSmallString(x+ 94, y+4, V_YELLOWMAP, "SERVER"); } } } @@ -2443,8 +2537,8 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline if (!(tab[i].num == serverplayer)) HU_drawPing(x+ 113, y+2, playerpingtable[tab[i].num], false); //else - // V_DrawSmallString(x+ 94, y+4, V_YELLOWMAP, "SERVER"); - + // V_DrawSmallString(x+ 94, y+4, V_YELLOWMAP, "SERVER"); + V_DrawString(x + 20, y, ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) | ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT) @@ -2542,9 +2636,9 @@ void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, if (!(tab[i].num == serverplayer)) HU_drawPing(x+ 135, y+3, playerpingtable[tab[i].num], true); //else - // V_DrawSmallString(x+ 129, y+4, V_YELLOWMAP, "HOST"); + // V_DrawSmallString(x+ 129, y+4, V_YELLOWMAP, "HOST"); } - + V_DrawString(x + 10, y, ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) | ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT) diff --git a/src/hu_stuff.h b/src/hu_stuff.h index f61ecfbd8..ba2b02700 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -57,6 +57,16 @@ typedef struct // chat stuff //------------------------------------ #define HU_MAXMSGLEN 224 +#define CHAT_BUFSIZE 64 // that's enough messages, right? We'll delete the older ones when that gets out of hand. +#define OLDCHAT (cv_consolechat.value == 1 || dedicated || vid.width < 640) +#define CHAT_MUTE (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer))) // this still allows to open the chat but not to type. That's used for scrolling and whatnot. +#define OLD_MUTE (OLDCHAT && cv_mute.value && !(server || IsPlayerAdmin(consoleplayer))) // this is used to prevent oldchat from opening when muted. + +// some functions +void HU_AddChatText(const char *text, boolean playsound); + +// set true when entering a chat message +extern boolean chat_on; extern patch_t *hu_font[HU_FONTSIZE], *tny_font[HU_FONTSIZE]; extern patch_t *tallnum[10]; @@ -72,22 +82,6 @@ extern patch_t *bmatcico; extern patch_t *tagico; extern patch_t *tallminus; -/*typedef struct -{ - const char *msg; // The final message we display on the HUD - tic_t time; // how much time do we still keep the message around for in the mini chat? - boolean hasmention; // make the message yellow if it has a mention because that's pretty cool. -} chatmsg_t;*/ - -#define CHAT_BUFSIZE 64 // that's enough messages, right? We'll delete the older ones when that gets out of hand. -#define OLDCHAT (cv_consolechat.value || dedicated || !netgame || vid.width < 640) - -// some functions -void HU_AddChatText(const char *text); - -// set true when entering a chat message -extern boolean chat_on; - // set true whenever the tab rankings are being shown for any reason extern boolean hu_showscores; diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 41bc55ac0..d8b8d24eb 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -23,13 +23,9 @@ #include "m_random.h" #include "s_sound.h" #include "g_game.h" -<<<<<<< HEAD #include "hu_stuff.h" // HU_AddChatText -======= -#include "hu_stuff.h" #include "console.h" #include "d_netcmd.h" // IsPlayerAdmin ->>>>>>> master #include "lua_script.h" #include "lua_libs.h" @@ -99,16 +95,14 @@ static int lib_print(lua_State *L) static int lib_chatprint(lua_State *L) { const char *str = luaL_checkstring(L, 1); // retrieve string + boolean sound = luaL_checkboolean(L, 2); // retrieve sound boolean if (str == NULL) // error if we don't have a string! return luaL_error(L, LUA_QL("tostring") " must return a string to " LUA_QL("chatprint")); int len = strlen(str); if (len > 255) // string is too long!!! return luaL_error(L, "String exceeds the 255 characters limit of the chat buffer."); - - if (OLDCHAT) - CONS_Printf("%s\n", str); - else - HU_AddChatText(str); + + HU_AddChatText(str, sound); return 0; } @@ -119,24 +113,22 @@ static int lib_chatprintf(lua_State *L) player_t *plr; if (n < 2) return luaL_error(L, "chatprintf requires at least two arguments: player and text."); - + plr = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); // retrieve player if (!plr) return LUA_ErrInvalid(L, "player_t"); if (plr != &players[consoleplayer]) return 0; - + const char *str = luaL_checkstring(L, 2); // retrieve string + boolean sound = luaL_checkboolean(L, 3); // sound? if (str == NULL) // error if we don't have a string! return luaL_error(L, LUA_QL("tostring") " must return a string to " LUA_QL("chatprintf")); int len = strlen(str); if (len > 255) // string is too long!!! return luaL_error(L, "String exceeds the 255 characters limit of the chat buffer."); - - if (OLDCHAT) - CONS_Printf("%s\n", str); - else - HU_AddChatText(str); + + HU_AddChatText(str, sound); return 0; } @@ -1758,9 +1750,9 @@ static int lib_sStartSound(lua_State *L) { if (hud_running) origin = NULL; // HUD rendering startsound shouldn't have an origin, just remove it instead of having a retarded error. - + S_StartSound(origin, sound_id); - } + } return 0; } diff --git a/src/lua_hook.h b/src/lua_hook.h index 252960edf..324babdb5 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -75,7 +75,7 @@ boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source); // Ho boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd); // Hook for B_BuildTiccmd boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd); // Hook for B_BuildTailsTiccmd by skin name boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector); // Hook for linedef executors -boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg); // Hook for chat messages +boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg, int mute); // Hook for chat messages boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source); // Hook for hurt messages #define LUAh_PlayerSpawn(player) LUAh_PlayerHook(player, hook_PlayerSpawn) // Hook for G_SpawnPlayer void LUAh_PlayerQuit(player_t *plr, int reason); // Hook for player quitting diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 7e544ae99..697552ec3 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -953,7 +953,9 @@ boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector) } // Hook for player chat -boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg) +// Added the "mute" field. It's set to true if the message was supposed to be eaten by spam protection. +// But for netgame consistency purposes, this hook is ran first reguardless, so this boolean allows for modders to adapt if they so desire. +boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg, int mute) { hook_p hookp; boolean hooked = false; @@ -982,14 +984,19 @@ boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg) LUA_PushUserdata(gL, &players[target-1], META_PLAYER); // target } lua_pushstring(gL, msg); // msg + if (mute) + lua_pushboolean(gL, true); // the message was supposed to be eaten by spamprotecc. + else + lua_pushboolean(gL, false); } lua_pushfstring(gL, FMT_HOOKID, hookp->id); lua_gettable(gL, LUA_REGISTRYINDEX); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - if (lua_pcall(gL, 4, 1, 0)) { + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + if (lua_pcall(gL, 5, 1, 0)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -1005,6 +1012,7 @@ boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg) return hooked; } + // Hook for hurt messages boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source) { diff --git a/src/m_menu.c b/src/m_menu.c index 8fedbbbe8..7647d72fc 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1321,7 +1321,7 @@ static menuitem_t OP_ChatOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Chat Notifications", &cv_chatnotifications, 40}, {IT_STRING | IT_CVAR, NULL, "Spam Protection", &cv_chatspamprotection, 50}, {IT_STRING | IT_CVAR, NULL, "Chat background tint", &cv_chatbacktint, 60}, - {IT_STRING | IT_CVAR, NULL, "Old Console Chat", &cv_consolechat, 70}, + {IT_STRING | IT_CVAR, NULL, "Chat Mode", &cv_consolechat, 70}, }; static menuitem_t OP_ServerOptionsMenu[] = @@ -2744,7 +2744,7 @@ void M_Init(void) CV_RegisterVar(&cv_newgametype); CV_RegisterVar(&cv_chooseskin); CV_RegisterVar(&cv_autorecord); - + if (dedicated) return; diff --git a/src/v_video.c b/src/v_video.c index 438832489..651418e68 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -841,12 +841,45 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) memset(dest, c, w * vid.bpp); } +#ifdef HWRENDER +// This is now a function since it's otherwise repeated 2 times and honestly looks retarded: +static UINT32 V_GetHWConsBackColor(void) +{ + UINT32 hwcolor; + switch (cons_backcolor.value) + { + case 0: hwcolor = 0xffffff00; break; // White + case 1: hwcolor = 0x80808000; break; // Gray + case 2: hwcolor = 0xdeb88700; break; // Sepia + case 3: hwcolor = 0x40201000; break; // Brown + case 4: hwcolor = 0xfa807200; break; // Pink + case 5: hwcolor = 0xff69b400; break; // Raspberry + case 6: hwcolor = 0xff000000; break; // Red + case 7: hwcolor = 0xffd68300; break; // Creamsicle + case 8: hwcolor = 0xff800000; break; // Orange + case 9: hwcolor = 0xdaa52000; break; // Gold + case 10: hwcolor = 0x80800000; break; // Yellow + case 11: hwcolor = 0x00ff0000; break; // Emerald + case 12: hwcolor = 0x00800000; break; // Green + case 13: hwcolor = 0x4080ff00; break; // Cyan + case 14: hwcolor = 0x4682b400; break; // Steel + case 15: hwcolor = 0x1e90ff00; break; // Periwinkle + case 16: hwcolor = 0x0000ff00; break; // Blue + case 17: hwcolor = 0xff00ff00; break; // Purple + case 18: hwcolor = 0xee82ee00; break; // Lavender + // Default green + default: hwcolor = 0x00800000; break; + } + return hwcolor; +} +#endif + + // THANK YOU MPC!!! void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) { UINT8 *dest; - const UINT8 *deststop; INT32 u, v; UINT32 alphalevel = 0; @@ -856,21 +889,7 @@ void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) #ifdef HWRENDER if (rendermode != render_soft && rendermode != render_none) { - UINT32 hwcolor; - switch (cons_backcolor.value) - { - case 0: hwcolor = 0xffffff00; break; // White - case 1: hwcolor = 0x80808000; break; // Gray - case 2: hwcolor = 0x40201000; break; // Brown - case 3: hwcolor = 0xff000000; break; // Red - case 4: hwcolor = 0xff800000; break; // Orange - case 5: hwcolor = 0x80800000; break; // Yellow - case 6: hwcolor = 0x00800000; break; // Green - case 7: hwcolor = 0x0000ff00; break; // Blue - case 8: hwcolor = 0x4080ff00; break; // Cyan - // Default green - default: hwcolor = 0x00800000; break; - } + UINT32 hwcolor = V_GetHWConsBackColor(); HWR_DrawConsoleFill(x, y, w, h, hwcolor, c); // we still use the regular color stuff but only for flags. actual draw color is "hwcolor" for this. return; } @@ -1107,21 +1126,7 @@ void V_DrawFadeConsBack(INT32 plines) #ifdef HWRENDER // not win32 only 19990829 by Kin if (rendermode != render_soft && rendermode != render_none) { - UINT32 hwcolor; - switch (cons_backcolor.value) - { - case 0: hwcolor = 0xffffff00; break; // White - case 1: hwcolor = 0x80808000; break; // Gray - case 2: hwcolor = 0x40201000; break; // Brown - case 3: hwcolor = 0xff000000; break; // Red - case 4: hwcolor = 0xff800000; break; // Orange - case 5: hwcolor = 0x80800000; break; // Yellow - case 6: hwcolor = 0x00800000; break; // Green - case 7: hwcolor = 0x0000ff00; break; // Blue - case 8: hwcolor = 0x4080ff00; break; // Cyan - // Default green - default: hwcolor = 0x00800000; break; - } + UINT32 hwcolor = V_GetHWConsBackColor(); HWR_DrawConsoleBack(hwcolor, plines); return; } @@ -1136,7 +1141,7 @@ void V_DrawFadeConsBack(INT32 plines) // Gets string colormap, used for 0x80 color codes // -static const UINT8 *V_GetStringColormap(INT32 colorflags) +UINT8 *V_GetStringColormap(INT32 colorflags) { switch ((colorflags & V_CHARCOLORMASK) >> V_CHARCOLORSHIFT) { @@ -1205,10 +1210,10 @@ void V_DrawChatCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed, UI w = (vid.width < 640 ) ? (SHORT(hu_font[c]->width)/2) : (SHORT(hu_font[c]->width)); // use normal sized characters if we're using a terribly low resolution. if (x + w > vid.width) return; - + V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, (vid.width < 640) ? (FRACUNIT) : (FRACUNIT/2), flags, hu_font[c], colormap); - + } // Precompile a wordwrapped string to any given width. diff --git a/src/v_video.h b/src/v_video.h index 430b7fd47..6bec258a4 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -157,6 +157,7 @@ void V_DrawLevelTitle(INT32 x, INT32 y, INT32 option, const char *string); // wordwrap a string using the hu_font char *V_WordWrap(INT32 x, INT32 w, INT32 option, const char *string); +UINT8 *V_GetStringColormap(INT32 colorflags); // draw a string using the hu_font void V_DrawString(INT32 x, INT32 y, INT32 option, const char *string);