From ac7c249fd20d12fb3b8435f2b79abb06b7c04d67 Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Tue, 31 Jul 2018 11:10:02 +0200 Subject: [PATCH 01/19] SRB2chat test rework --- src/console.c | 24 +- src/d_main.c | 23 +- src/d_netcmd.c | 10 + src/dehacked.c | 28 +- src/doomdef.h | 1 + src/g_game.c | 37 +- src/g_game.h | 1 + src/hardware/hw_draw.c | 104 ++++ src/hardware/hw_main.h | 2 + src/hu_stuff.c | 1340 ++++++++++++++++++++++++++++++++++++---- src/hu_stuff.h | 14 +- src/lua_baselib.c | 55 +- src/m_menu.c | 40 +- src/v_video.c | 150 +++++ src/v_video.h | 3 + 15 files changed, 1687 insertions(+), 145 deletions(-) diff --git a/src/console.c b/src/console.c index 3c06561c..357f1ef8 100644 --- a/src/console.c +++ b/src/console.c @@ -844,7 +844,7 @@ boolean CON_Responder(event_t *ev) // ...why shouldn't it eat the key? if it doesn't, it just means you // can control Sonic from the console, which is silly - return true; //return false; + return true;//return false; } // command completion forward (tab) and backward (shift-tab) @@ -1037,16 +1037,26 @@ boolean CON_Responder(event_t *ev) } else if (key == KEY_KPADSLASH) key = '/'; - - if (shiftdown) + + // capslock + if (key == KEY_CAPSLOCK) // it's a toggle. + { + if (capslock) + capslock = false; + else + capslock = true; + return true; + } + + if (capslock ^ shiftdown) // gets capslock to work because capslock is cool key = shiftxform[key]; // enter a char into the command prompt if (key < 32 || key > 127) - return true; // even if key can't be printed, eat it anyway + return true; // add key to cmd line here - if (key >= 'A' && key <= 'Z' && !shiftdown) //this is only really necessary for dedicated servers + if (key >= 'A' && key <= 'Z' && !(shiftdown ^ capslock)) //this is only really necessary for dedicated servers key = key + 'a' - 'A'; if (input_sel != input_cur) @@ -1433,8 +1443,8 @@ static void CON_DrawHudlines(void) if (con_hudlines <= 0) return; - if (chat_on) - y = charheight; // leave place for chat input in the first row of text + if (chat_on && cv_consolechat.value) + y = charheight; // leave place for chat input in the first row of text (only do it if consolechat is on.) else y = 0; diff --git a/src/d_main.c b/src/d_main.c index fbec5f7d..159a2e3e 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -181,6 +181,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; // you'd never guess what this does. // // D_ModifierKeyResponder // Sets global shift/ctrl/alt variables, never actually eats events @@ -730,6 +731,11 @@ void D_StartTitle(void) CON_ToggleOff(); // Reset the palette +#ifdef HWRENDER + if (rendermode == render_opengl) + HWR_SetPaletteColor(0); + else +#endif if (rendermode != render_none) V_SetPaletteLump("PLAYPAL"); } @@ -1063,7 +1069,7 @@ void D_SRB2Main(void) // add any files specified on the command line with -file wadfile // to the wad list - if (!(M_CheckParm("-connect") && !M_CheckParm("-server"))) + if (!(M_CheckParm("-connect"))) { if (M_CheckParm("-file")) { @@ -1219,15 +1225,7 @@ void D_SRB2Main(void) R_Init(); // setting up sound - if (dedicated) - { - nosound = true; - nomidimusic = nodigimusic = true; - } - else - { - CONS_Printf("S_Init(): Setting up sound.\n"); - } + CONS_Printf("S_Init(): Setting up sound.\n"); if (M_CheckParm("-nosound")) nosound = true; if (M_CheckParm("-nomusic")) // combines -nomidimusic and -nodigmusic @@ -1326,7 +1324,7 @@ void D_SRB2Main(void) ultimatemode = true; } - if (autostart || netgame) + if (autostart || netgame || M_CheckParm("+connect") || M_CheckParm("-connect")) { gameaction = ga_nothing; @@ -1364,7 +1362,8 @@ void D_SRB2Main(void) } } - if (server && !M_CheckParm("+map")) + if (server && !M_CheckParm("+map") && !M_CheckParm("+connect") + && !M_CheckParm("-connect")) { // Prevent warping to nonexistent levels if (W_CheckNumForName(G_BuildMapName(pstartmap)) == LUMPERROR) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 673d64fd..dbd26a73 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -582,6 +582,7 @@ void D_RegisterServerCommands(void) */ void D_RegisterClientCommands(void) { + const char *username; INT32 i; for (i = 0; i < MAXSKINCOLORS; i++) @@ -638,6 +639,8 @@ void D_RegisterClientCommands(void) #endif // register these so it is saved to config + if ((username = I_GetUserName())) + cv_playername.defaultvalue = username; CV_RegisterVar(&cv_playername); CV_RegisterVar(&cv_playercolor); CV_RegisterVar(&cv_skin); // r_things.c (skin NAME) @@ -676,6 +679,13 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_usegamma); // m_menu.c + CV_RegisterVar(&cv_compactscoreboard); + CV_RegisterVar(&cv_chatheight); + CV_RegisterVar(&cv_chatwidth); + CV_RegisterVar(&cv_chattime); + CV_RegisterVar(&cv_chatspamprotection); + CV_RegisterVar(&cv_consolechat); + CV_RegisterVar(&cv_chatnotifications); CV_RegisterVar(&cv_crosshair); CV_RegisterVar(&cv_crosshair2); CV_RegisterVar(&cv_alwaysfreelook); diff --git a/src/dehacked.c b/src/dehacked.c index b7e874b1..ac2aa9a8 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8286,8 +8286,34 @@ static inline int lib_getenum(lua_State *L) } else if (fastcmp(word, "token")) { lua_pushinteger(L, token); return 1; + } else if (fastcmp(word,"consoleplayer")) { + if (!playeringame[consoleplayer]) + return 0; + LUA_PushUserdata(L, &players[consoleplayer], META_PLAYER); + return 1; + } else if (fastcmp(word,"displayplayer")) { + if (!playeringame[displayplayer]) + return 0; + LUA_PushUserdata(L, &players[displayplayer], META_PLAYER); + return 1; + } else if (fastcmp(word,"secondarydisplayplayer")) { + if (!playeringame[displayplayer]) + return 0; + LUA_PushUserdata(L, &players[secondarydisplayplayer], META_PLAYER); + return 1; + } else if (fastcmp(word, "timelimitintics")) { + lua_pushinteger(L, timelimitintics); + return 1; + } else if (fastcmp(word,"hidetime")) { + lua_pushinteger(L, hidetime); + return 1; + } else if (fastcmp(word, "pointlimit")) { + lua_pushinteger(L, cv_pointlimit.value); + return 1; + } else if (fastcmp(word,"allowjoin")) { + lua_pushboolean(L, cv_allownewplayer.value); + return 1; } - return 0; } diff --git a/src/doomdef.h b/src/doomdef.h index 7f641558..50e7c717 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -396,6 +396,7 @@ extern INT32 cv_debug; // Modifier key variables, accessible anywhere extern UINT8 shiftdown, ctrldown, altdown; +extern boolean capslock; // if we ever make our alloc stuff... #define ZZ_Alloc(x) Z_Malloc(x, PU_STATIC, NULL) diff --git a/src/g_game.c b/src/g_game.c index bcae69fd..d70a8a30 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -347,6 +347,32 @@ static CV_PossibleValue_t joyaxis_cons_t[] = {{0, "None"}, #endif #endif +// don't mind me putting these here, I was lazy to figure out where else I could put those without blowing up the compiler. + +// it automatically becomes compact with 20+ players, but if you like it, I guess you can turn that on! +consvar_t cv_compactscoreboard= {"compactscoreboard", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + +// chat timer thingy +static CV_PossibleValue_t chattime_cons_t[] = {{5, "MIN"}, {999, "MAX"}, {0, NULL}}; +consvar_t cv_chattime = {"chattime", "8", CV_SAVE, chattime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; + +// chatwidth +static CV_PossibleValue_t chatwidth_cons_t[] = {{64, "MIN"}, {150, "MAX"}, {0, NULL}}; +consvar_t cv_chatwidth = {"chatwidth", "150", CV_SAVE, chatwidth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; + +// chatheight +static CV_PossibleValue_t chatheight_cons_t[] = {{6, "MIN"}, {22, "MAX"}, {0, NULL}}; +consvar_t cv_chatheight= {"chatheight", "8", CV_SAVE, chatheight_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; + +// chat notifications (do you want to hear beeps? I'd understand if you didn't.) +consvar_t cv_chatnotifications= {"chatnotifications", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + +// chat spam protection (why would you want to disable that???) +consvar_t cv_chatspamprotection= {"chatspamprotection", "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}; + 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}; consvar_t cv_invertmouse = {"invertmouse", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -1240,6 +1266,10 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) if ((cmd->forwardmove || cmd->sidemove || cmd->buttons) && displayplayer != consoleplayer) displayplayer = consoleplayer; + + if (playeringame[consoleplayer]) // do not run on title screen. + LUAh_PlayerCmd(player, cmd); // run this hook after we've done everything. Why? Because that way we can check what buttons we're pressing and what we're doing in that frame rather than using last frame's info! + } // like the g_buildticcmd 1 but using mouse2, gamcontrolbis, ... @@ -1535,6 +1565,10 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics) localangle2 += (cmd->angleturn<<16); cmd->angleturn = (INT16)(localangle2 >> 16); } + + if (playeringame[consoleplayer]) // do not run on title screen. + LUAh_PlayerCmd(player, cmd); + } // User has designated that they want @@ -3588,8 +3622,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean unlocktriggers = 0; // clear itemfinder, just in case - if (!dedicated) // except in dedicated servers, where it is not registered and can actually I_Error debug builds - CV_StealthSetValue(&cv_itemfinder, 0); + CV_StealthSetValue(&cv_itemfinder, 0); } // internal game map diff --git a/src/g_game.h b/src/g_game.h index ada82404..cd0a71f2 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -54,6 +54,7 @@ extern tic_t timeinmap; // Ticker for time spent in level (used for levelcard di extern INT16 rw_maximums[NUM_WEAPONS]; // used in game menu +extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatspamprotection, cv_compactscoreboard; extern consvar_t cv_crosshair, cv_crosshair2; extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_mousemove; extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_fireaxis,cv_firenaxis; diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 84081dd2..e09b327e 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -791,6 +791,110 @@ void HWR_drawAMline(const fline_t *fl, INT32 color) HWD.pfnDraw2DLine(&v1, &v2, color_rgba); } +// -------------------+ +// HWR_DrawConsoleFill : draw flat coloured transparent rectangle because that's cool, and hw sucks less than sw for that. +// -------------------+ +void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32 options) +{ + FOutVector v[4]; + FSurfaceInfo Surf; + float fx, fy, fw, fh; + + if (w < 0 || h < 0) + return; // consistency w/ software + +// 3--2 +// | /| +// |/ | +// 0--1 + + fx = (float)x; + fy = (float)y; + fw = (float)w; + fh = (float)h; + + if (!(options & V_NOSCALESTART)) + { + float dupx = (float)vid.dupx, dupy = (float)vid.dupy; + + if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT) + { + RGBA_t rgbaColour = V_GetColor(color); + FRGBAFloat clearColour; + clearColour.red = (float)rgbaColour.s.red / 255; + clearColour.green = (float)rgbaColour.s.green / 255; + clearColour.blue = (float)rgbaColour.s.blue / 255; + clearColour.alpha = 1; + HWD.pfnClearBuffer(true, false, &clearColour); + return; + } + + fx *= dupx; + fy *= dupy; + fw *= dupx; + fh *= dupy; + + if (vid.width != BASEVIDWIDTH * vid.dupx) + { + if (options & V_SNAPTORIGHT) + fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)); + else if (!(options & V_SNAPTOLEFT)) + fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2; + } + if (vid.height != BASEVIDHEIGHT * dupy) + { + // same thing here + if (options & V_SNAPTOBOTTOM) + fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)); + else if (!(options & V_SNAPTOTOP)) + fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2; + } + } + + if (fx >= vid.width || fy >= vid.height) + return; + if (fx < 0) + { + fw += fx; + fx = 0; + } + if (fy < 0) + { + fh += fy; + fy = 0; + } + + if (fw <= 0 || fh <= 0) + return; + if (fx + fw > vid.width) + fw = (float)vid.width - fx; + if (fy + fh > vid.height) + fh = (float)vid.height - fy; + + fx = -1 + fx / (vid.width / 2); + fy = 1 - fy / (vid.height / 2); + fw = fw / (vid.width / 2); + fh = fh / (vid.height / 2); + + v[0].x = v[3].x = fx; + v[2].x = v[1].x = fx + fw; + v[0].y = v[1].y = fy; + v[2].y = v[3].y = fy - fh; + + //Hurdler: do we still use this argb color? if not, we should remove it + v[0].argb = v[1].argb = v[2].argb = v[3].argb = 0xff00ff00; //; + v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; + + v[0].sow = v[3].sow = 0.0f; + v[2].sow = v[1].sow = 1.0f; + v[0].tow = v[1].tow = 0.0f; + v[2].tow = v[3].tow = 1.0f; + + Surf.FlatColor.rgba = UINT2RGBA(color); + Surf.FlatColor.s.alpha = 0x80; + + HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); +} // -----------------+ // HWR_DrawFill : draw flat coloured rectangle, with no texture diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index b0a14d3b..ba809663 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -52,6 +52,7 @@ void HWR_CreatePlanePolygons(INT32 bspnum); void HWR_CreateStaticLightmaps(INT32 bspnum); void HWR_PrepLevelCache(size_t pnumtextures); void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color); +void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32 options); // Lat: separate flags from color since color needs to be an uint to work right. void HWR_DrawPic(INT32 x,INT32 y,lumpnum_t lumpnum); void HWR_AddCommands(void); @@ -70,6 +71,7 @@ void HWR_DrawScreenFinalTexture(int width, int height); // This stuff is put here so MD2's can use them UINT32 HWR_Lighting(INT32 light, UINT32 color, UINT32 fadecolor, boolean fogblockpoly, boolean plane); +UINT32 HWR_NoColormapLighting(INT32 light, UINT32 color, UINT32 fadecolor, boolean fogblockpoly, boolean plane); // do it like cv_grfog off for non colormap stuff FUNCMATH UINT8 LightLevelToLum(INT32 l); extern CV_PossibleValue_t granisotropicmode_cons_t[]; diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 646bdcba..43532576 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -73,6 +73,7 @@ patch_t *cred_font[CRED_FONTSIZE]; static player_t *plr; boolean chat_on; // entering a chat message? static char w_chat[HU_MAXMSGLEN]; +static INT32 c_input = 0; // let's try to make the chat input less shitty. static boolean headsupactive = false; boolean hu_showscores; // draw rankings static char hu_tick; @@ -319,6 +320,74 @@ void HU_Start(void) //====================================================================== #ifndef NONET + +// EVERY CHANGE IN THIS SCRIPT IS LOL XD! BY VINCYTM + +static UINT32 chat_nummsg_log = 0; +static UINT32 chat_nummsg_min = 0; +static UINT32 chat_scroll = 0; +static tic_t chat_scrolltime = 0; + +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. + +static char chat_log[CHAT_BUFSIZE][255]; // hold the last 48 or so messages in that log. +static char chat_mini[8][255]; // display up to 8 messages that will fade away / get overwritten +static tic_t chat_timers[8]; + +static boolean chat_scrollmedown = false; // force instant scroll down on the chat log. Happens when you open it / send a message. + +// remove text from minichat table + +static INT16 addy = 0; // use this to make the messages scroll smoothly when one fades away + +static void HU_removeChatText_Mini(void) +{ + // MPC: Don't create new arrays, just iterate through an existing one + int i; + for(i=0;i= CHAT_BUFSIZE) + 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++; +} + /** Runs a say command, sending an ::XD_SAY message. * A say command consists of a signed 8-bit integer for the target, an * unsigned 8-bit flag variable, and then the message itself. @@ -337,6 +406,8 @@ void HU_Start(void) * \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]; @@ -347,9 +418,9 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags) numwords = COM_Argc() - usedargs; I_Assert(numwords > 0); - if (cv_mute.value && !(server || adminplayer == consoleplayer)) + if (cv_mute.value && !(server || adminplayer == consoleplayer)) // TODO: Per Player mute. { - CONS_Alert(CONS_NOTICE, M_GetText("The chat is muted. You can't say anything at the moment.\n")); + HU_AddChatText(va("%s>ERROR: The chat is muted. You can't say anything.", "\x85")); return; } @@ -372,6 +443,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: + 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 \'."); + 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 + return; + } + buf[0] = target; + const char *newmsg = msg+5+spc; + memcpy(msg, newmsg, 255); + } SendNetXCmd(XD_SAY, buf, strlen(msg) + 1 + msg-buf); } @@ -457,6 +574,8 @@ 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. * \sa DoSayCommand * \author Graue @@ -469,7 +588,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) char *msg; boolean action = false; char *ptr; - + CONS_Debug(DBG_NETPLAY,"Received SAY cmd from Player %d (%s)\n", playernum+1, player_names[playernum]); target = READSINT8(*p); @@ -514,12 +633,32 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) } } } - -#ifdef HAVE_BLUA - if (LUAh_PlayerMsg(playernum, target, flags, msg)) + + 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 + if (LUAh_PlayerMsg(playernum, target, flags, msg, spam_eatmsg)) return; -#endif - +#endif*/ + // Kill PlayerMsg for now, it breaks the purpose of this EXE. + + 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) { @@ -559,18 +698,23 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) || target == 0 // To everyone || consoleplayer == target-1) // To you { - const char *cstart = "", *cend = "", *adminchar = "~", *remotechar = "@", *fmt; + const char *prefix = "", *cstart = "", *cend = "", *adminchar = "\x82~\x83", *remotechar = "\x82@\x83", *fmt, *fmt2; char *tempchar = NULL; - + // In CTF and team match, color the player's name. if (G_GametypeHasTeams()) { - cend = "\x80"; - if (players[playernum].ctfteam == 1) // red - cstart = "\x85"; + 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 // Give admins and remote admins their symbols. if (playernum == serverplayer) @@ -579,11 +723,11 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) tempchar = (char *)Z_Calloc(strlen(cstart) + strlen(remotechar) + 1, PU_STATIC, NULL); if (tempchar) { - strcat(tempchar, cstart); if (playernum == serverplayer) strcat(tempchar, adminchar); else strcat(tempchar, remotechar); + strcat(tempchar, cstart); cstart = tempchar; } @@ -592,21 +736,61 @@ 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 = "\4* %s%s%s \x82%s\n"; + { + 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%s%s> %s\n"; + { + fmt = "\3%s\x83<%s%s%s\x83>\x80 %s\n"; + fmt2 = "%s\x83<%s%s%s\x83>\x80 %s"; + } else if (target-1 == consoleplayer) // To you - fmt = "\3*%s%s%s* %s\n"; + { + 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"; + } else if (target > 0) // By you, to another player { // Use target's name. dispname = player_names[target-1]; - fmt = "\3->*%s%s%s* %s\n"; + /*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"; + } else // To your team - fmt = "\3>>%s%s%s<< (team) %s\n"; - - CONS_Printf(fmt, cstart, dispname, cend, msg); + { + 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 (cv_consolechat.value) + { + 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); + } + if (tempchar) Z_Free(tempchar); } @@ -633,19 +817,48 @@ static inline boolean HU_keyInChatString(char *s, char ch) l = strlen(s); if (l < HU_MAXMSGLEN - 1) { - s[l++] = ch; - s[l]=0; + if (c_input >= strlen(s)) // don't do anything complicated + { + 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--) + { + if (s[m]) + s[m+1] = (s[m]); + } + s[c_input] = ch; // and replace this. + } + c_input++; return true; } return false; } else if (ch == KEY_BACKSPACE) { - l = strlen(s); - if (l) - s[--l] = 0; - else + if (c_input <= 0) return false; + 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--; } else if (ch != KEY_ENTER) return false; // did not eat key @@ -669,29 +882,10 @@ void HU_Ticker(void) hu_showscores = false; } -#define QUEUESIZE 256 - static boolean teamtalk = false; -static char chatchars[QUEUESIZE]; -static INT32 head = 0, tail = 0; - -// -// HU_dequeueChatChar -// -char HU_dequeueChatChar(void) -{ - char c; - - if (head != tail) - { - c = chatchars[tail]; - tail = (tail + 1) & (QUEUESIZE-1); - } - else - c = 0; - - return c; -} +/*static char chatchars[QUEUESIZE]; +static INT32 head = 0, tail = 0;*/ +// WHY DO YOU OVERCOMPLICATE EVERYTHING????????? // // @@ -702,68 +896,118 @@ static void HU_queueChatChar(char c) { char buf[2+256]; size_t ci = 2; - + char *msg = &buf[2]; do { - c = HU_dequeueChatChar(); + c = w_chat[-2+ci++]; if (!c || (c >= ' ' && !(c & 0x80))) // copy printable characters and terminating '\0' only. - buf[ci++]=c; + buf[ci-1]=c; } while (c); - + size_t i = 0; + for (;(iERROR: The chat is muted. You can't say anything.", "\x85")); 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")); + 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 \'."); + 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 + 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] = 0; // target + buf[0] = target; + buf[1] = 0; // flags SendNetXCmd(XD_SAY, buf, 2 + strlen(&buf[2]) + 1); } return; } - - if (((head + 1) & (QUEUESIZE-1)) == tail) - CONS_Printf(M_GetText("[Message unsent]\n")); // message not sent - else - { - if (c == KEY_BACKSPACE) - { - if (tail != head) - head = (head - 1) & (QUEUESIZE-1); - } - else - { - chatchars[head] = c; - head = (head + 1) & (QUEUESIZE-1); - } - } } void HU_clearChatChars(void) { - while (tail != head) - HU_queueChatChar(KEY_BACKSPACE); + size_t i = 0; + for (;itype != ev_keydown) return false; // only KeyDown events now... - + if (!chat_on) { // enter chat mode @@ -775,6 +1019,7 @@ boolean HU_Responder(event_t *ev) chat_on = true; w_chat[0] = 0; teamtalk = false; + chat_scrollmedown = true; return true; } if ((ev->data1 == gamecontrol[gc_teamkey][0] || ev->data1 == gamecontrol[gc_teamkey][1]) @@ -785,11 +1030,13 @@ boolean HU_Responder(event_t *ev) chat_on = true; w_chat[0] = 0; teamtalk = true; + chat_scrollmedown = true; 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. @@ -799,18 +1046,95 @@ boolean HU_Responder(event_t *ev) return true; c = (UINT8)ev->data1; - - // use console translations - if (shiftdown) + + // capslock + if (c && c == KEY_CAPSLOCK) // it's a toggle. + { + if (capslock) + capslock = false; + else + capslock = true; + return true; + } + + // use console translations + if (shiftdown ^ capslock) c = shiftxform[c]; - + + // TODO: make chat behave like the console, so that we can go back and edit stuff when we fuck up. + + // pasting. pasting is cool. chat is a bit limited, though :( + if ((c == 'v' || c == 'V') && ctrldown) + { + const char *paste = I_ClipboardPaste(); + + // create a dummy string real quickly + + if (paste == NULL) + return true; + + size_t chatlen = strlen(w_chat); + size_t 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. + c_input += pastelen; + /*size_t i = 0; + 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)) + { 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) + { chat_on = false; - + c_input = 0; // reset input cursor + } + else if ((c == KEY_UPARROW || c == KEY_MOUSEWHEELUP) && chat_scroll > 0) // 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) + { + chat_scroll++; + justscrolleddown = true; + chat_scrolltime = 4; + } + else if (c == KEY_LEFTARROW && c_input != 0) // i said go back + c_input--; + else if (c == KEY_RIGHTARROW && c_input < strlen(w_chat)) + c_input++; return true; } return false; @@ -820,12 +1144,472 @@ boolean HU_Responder(event_t *ev) // 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. +// this one is simplified for the chat drawer. +char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string) +{ + int c; + size_t chw, i, lastusablespace = 0; + size_t slen; + char *newstring = Z_StrDup(string); + INT32 spacewidth = (vid.width < 640) ? 8 : 4, charwidth = (vid.width < 640) ? 8 : 4; + + slen = strlen(string); + x = 0; + + for (i = 0; i < slen; ++i) + { + c = newstring[i]; + if ((UINT8)c >= 0x80 && (UINT8)c <= 0x89) //color parsing! -Inuyasha 2.16.09 + continue; + + if (c == '\n') + { + x = 0; + lastusablespace = 0; + continue; + } + + if (!(option & V_ALLOWLOWERCASE)) + c = toupper(c); + c -= HU_FONTSTART; + + if (c < 0 || c >= HU_FONTSIZE || !hu_font[c]) + { + chw = spacewidth; + lastusablespace = i; + } + else + chw = charwidth; + + x += chw; + + if (lastusablespace != 0 && x > w) + { + //CONS_Printf("Wrap at index %d\n", i); + newstring[lastusablespace] = '\n'; + i = lastusablespace+1; + lastusablespace = 0; + x = 0; + } + } + return newstring; +} + +// 30/7/18: chaty is now the distance at which the lowest point of the chat will be drawn if that makes any sense. + +INT16 chatx = 160, chaty = 192; // let's use this as our coordinates, shh + +// chat stuff by VincyTM LOL XD! + +// HU_DrawMiniChat + +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 dx = 0, dy = 0; + size_t i = chat_nummsg_min; + + INT32 msglines = 0; + // process all messages once without rendering anything or doing anything fancy so that we know how many lines each message has... + + for (; i>0; i--) + { + const char *msg = CHAT_WordWrap(x, cv_chatwidth.value-charwidth, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]); + size_t j = 0; + INT32 linescount = 0; + + while(msg[j]) // iterate through msg + { + if (msg[j] < HU_FONTSTART) // don't draw + { + if (msg[j] == '\n') // get back down. + { + ++j; + linescount += 1; + dx = 0; + continue; + } + else if (msg[j] & 0x80) // stolen from video.c, nice. + { + ++j; + continue; + } + + ++j; + } + else + { + j++; + } + + dx += charwidth; + if (dx >= cv_chatwidth.value) + { + dx = 0; + linescount += 1; + } + } + dy = 0; + dx = 0; + msglines += linescount+1; + } + + INT32 y = chaty - charheight*(msglines+1); + dx = 0; + dy = 0; + i = 0; + + for (; i<=(chat_nummsg_min-1); i++) // iterate through our hot messages + { + + INT32 clrflag = 0; + 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, cv_chatwidth.value-charwidth, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it. + + while(msg[j]) // iterate through msg + { + if (msg[j] < HU_FONTSTART) // don't draw + { + if (msg[j] == '\n') // get back down. + { + ++j; + dy += charheight; + dx = 0; + continue; + } + else if (msg[j] & 0x80) // stolen from video.c, nice. + { + clrflag = ((msg[j] & 0x7f) << V_CHARCOLORSHIFT) & V_CHARCOLORMASK; + ++j; + continue; + } + + ++j; + } + else + { + UINT8 *colormap = CHAT_GetStringColormap(clrflag); + V_DrawChatCharacter(x + dx + 2, y+dy, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTORIGHT|transflag, !cv_allcaps.value, colormap); + } + + dx += charwidth; + if (dx >= cv_chatwidth.value) + { + dx = 0; + dy += charheight; + } + } + dy += charheight; + dx = 0; + } + + // decrement addy and make that shit smooth: + addy /= 2; + +} + +// 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. + +static void HU_DrawUpArrow(INT32 x, INT32 y, INT32 options) +{ + // Ok I'm super lazy so let's make this as the worst draw function: + 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); + V_DrawFill(x, y+3, 6, 1, 26|options); // that's the black part. no racism intended. i swear. +} + +// HU_DrawDownArrow +// Should we talk about anime waifus to pass the time? This feels retarded. + +static void HU_DrawDownArrow(INT32 x, INT32 y, INT32 options) +{ + // Ok I'm super lazy so let's make this as the worst draw function: + V_DrawFill(x, y, 6, 1, 26|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) +{ + + // before we do anything, make sure that our scroll position isn't "illegal"; + if (chat_scroll > chat_maxscroll) + chat_scroll = chat_maxscroll; + + INT32 charwidth = (vid.width < 640) ? 8 : 4, charheight = (vid.width < 640) ? 8 : 6; + INT32 x = chatx+2, y = chaty - offset*charheight - (chat_scroll*charheight) - cv_chatheight.value*charheight - 12, dx = 0, dy = 0; + size_t i = 0; + INT32 chat_topy = y + chat_scroll*charheight; + INT32 chat_bottomy = chat_topy + cv_chatheight.value*charheight; + boolean atbottom = false; + + V_DrawFillConsoleMap(chatx, chat_topy, cv_chatwidth.value, cv_chatheight.value*charheight +2, 239|V_SNAPTOBOTTOM|V_SNAPTORIGHT); // 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_SNAPTORIGHT, !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!!!! + { + dx = 0; + dy += charheight; + } + } + dy += charheight; + 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 + } + chat_scrollmedown = false; + + // getmaxscroll through a lazy hack. We do all these loops, so let's not do more loops that are gonna lag the game more. :P + chat_maxscroll = (dy/charheight)-cv_chatheight.value; // welcome to C, we don't know what min() and max() are. + if (chat_maxscroll < 0) + chat_maxscroll = 0; + + // if we're not bound by the time, autoscroll for next frame: + if (atbottom) + chat_scroll = chat_maxscroll; + + // draw arrows to indicate that we can (or not) scroll. + + if (chat_scroll > 0) + HU_DrawUpArrow(chatx-8, ((justscrolledup) ? (chat_topy-1) : (chat_topy)), V_SNAPTOBOTTOM | V_SNAPTORIGHT); + if (chat_scroll < chat_maxscroll) + HU_DrawDownArrow(chatx-8, chat_bottomy-((justscrolleddown) ? 3 : 4), V_SNAPTOBOTTOM | V_SNAPTORIGHT); + + justscrolleddown = false; + justscrolledup = false; +} + // // HU_DrawChat // // 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 = (vid.width < 640) ? 8 : 4, charheight = (vid.width < 640) ? 8 : 6; + INT32 t = 0, c = 0, y = chaty - ((vid.width < 640 ) ? (typelines*charheight+2) : (typelines*charheight)); + size_t i = 0; + const char *ntalk = "Say: ", *ttalk = "Team: "; + const char *talk = ntalk; + + if (teamtalk) + { + talk = ttalk; +#if 0 + if (players[consoleplayer].ctfteam == 1) + t = 0x500; // Red + else if (players[consoleplayer].ctfteam == 2) + t = 0x400; // Blue +#endif + } + + V_DrawFillConsoleMap(chatx, y-1, cv_chatwidth.value, (vid.width < 640 ) ? (typelines*charheight+2) : (typelines*charheight), 239 | V_SNAPTOBOTTOM | V_SNAPTORIGHT); + + while (talk[i]) + { + if (talk[i] < HU_FONTSTART) + ++i; + else + V_DrawChatCharacter(chatx + c + 2, y, talk[i++] |V_SNAPTOBOTTOM|V_SNAPTORIGHT, !cv_allcaps.value, NULL); + + c += charwidth; + } + + i = 0; + typelines = 1; + + if ((strlen(w_chat) == 0 || c_input == 0) && hu_tick < 4) + V_DrawChatCharacter(chatx + 2 + c, y+1, '_' |V_SNAPTOBOTTOM|V_SNAPTORIGHT|t, !cv_allcaps.value, NULL); + + while (w_chat[i]) + { + + if (c_input == (i+1) && hu_tick < 4) + { + int cursorx = (c+charwidth < cv_chatwidth.value-charwidth) ? (chatx + 2 + c+charwidth) : (chatx); // we may have to go down. + int cursory = (cursorx != chatx) ? (y) : (y+charheight); + V_DrawChatCharacter(cursorx, cursory+1, '_' |V_SNAPTOBOTTOM|V_SNAPTORIGHT|t, !cv_allcaps.value, NULL); + } + + //Hurdler: isn't it better like that? + if (w_chat[i] < HU_FONTSTART) + ++i; + else + V_DrawChatCharacter(chatx + c + 2, y, w_chat[i++] | V_SNAPTOBOTTOM|V_SNAPTORIGHT | t, !cv_allcaps.value, NULL); + + c += charwidth; + if (c > cv_chatwidth.value-charwidth) + { + c = 0; + y += charheight; + typelines += 1; + } + } + + // handle /pm list. + if (strnicmp(w_chat, "/pm", 3) == 0 && vid.width >= 400 && !teamtalk) // 320x200 unsupported kthxbai + { + i = 0; + int count = 0; + INT32 p_dispy = chaty - charheight -1; + 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); + strncpy(nodenum, w_chat+3, 4); + INT32 n = atoi((const char*) nodenum); // turn that into a number + // special cases: + + if ((n == 0) && !(w_chat[4] == '0')) + { + if (!(i<10)) + continue; + } + else if ((n == 1) && !(w_chat[3] == '0')) + { + if (!((i == 1) || ((i >= 10) && (i <= 19)))) + continue; + } + else if ((n == 2) && !(w_chat[3] == '0')) + { + if (!((i == 2) || ((i >= 20) && (i <= 29)))) + continue; + } + else if ((n == 3) && !(w_chat[3] == '0')) + { + if (!((i == 3) || ((i >= 30) && (i <= 31)))) + continue; + } + else // general case. + { + if (i != n) + continue; + } + } + + if (1 || (playeringame[i])) + { + char name[MAXPLAYERNAME+1]; + strlcpy(name, player_names[i], 7); // shorten name to 7 characters. + V_DrawFillConsoleMap(chatx-50, p_dispy- (6*count), 48, 6, 239 | V_SNAPTOBOTTOM | V_SNAPTORIGHT); // fill it like the chat so the text doesn't become hard to read because of the hud. + V_DrawSmallString(chatx-48, p_dispy- (6*count), V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_ALLOWLOWERCASE, va("\x82%d\x80 - %s", i, name)); + count++; + } + } + if (count == 0) // no results. + { + V_DrawFillConsoleMap(chatx-50, p_dispy- (6*count), 48, 6, 239 | V_SNAPTOBOTTOM | V_SNAPTORIGHT); // fill it like the chat so the text doesn't become hard to read because of the hud. + V_DrawSmallString(chatx-48, p_dispy- (6*count), V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_ALLOWLOWERCASE, "NO RESULT."); + } + } + + HU_drawChatLog(typelines-1); // typelines is the # of lines we're typing. If there's more than 1 then the log should scroll up to give us more space. + +} + +// why the fuck would you use this... + +static void HU_DrawChat_Old(void) { INT32 t = 0, c = 0, y = HU_INPUTY; size_t i = 0; @@ -833,7 +1617,6 @@ static void HU_DrawChat(void) const char *talk = ntalk; INT32 charwidth = 8 * con_scalefactor; //SHORT(hu_font['A'-HU_FONTSTART]->width) * con_scalefactor; INT32 charheight = 8 * con_scalefactor; //SHORT(hu_font['A'-HU_FONTSTART]->height) * con_scalefactor; - if (teamtalk) { talk = ttalk; @@ -859,10 +1642,21 @@ static void HU_DrawChat(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); + } + //Hurdler: isn't it better like that? if (w_chat[i] < HU_FONTSTART) { @@ -882,9 +1676,6 @@ static void HU_DrawChat(void) y += charheight; } } - - if (hu_tick < 4) - V_DrawCharacter(HU_INPUTX + c, y, '_' | cv_constextsize.value |V_NOSCALESTART|t, !cv_allcaps.value); } @@ -1057,7 +1848,45 @@ void HU_Drawer(void) { // draw chat string plus cursor if (chat_on) - HU_DrawChat(); + { + // count down the scroll timer. + if (chat_scrolltime > 0) + chat_scrolltime--; + if (!cv_consolechat.value && vid.width >= 640) // don't even bother with 200p + HU_DrawChat(); + else + HU_DrawChat_Old(); // why the fuck......................... + } + else + { + if (!cv_consolechat.value) + { + 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 + HU_removeChatText_Mini(); + } + } if (cechotimer) HU_DrawCEcho(); @@ -1153,9 +1982,9 @@ void HU_Erase(void) // clear the message lines that go away, so use _oldclearlines_ bottomline = oldclearlines; oldclearlines = con_clearlines; - if (chat_on) + if (chat_on && cv_consolechat.value) if (bottomline < 8) - bottomline = 8; + bottomline = 8; // only do it for consolechat. consolechat is gay. if (automapactive || viewwindowx == 0) // hud msgs don't need to be cleared return; @@ -1191,6 +2020,40 @@ void HU_Erase(void) // IN-LEVEL MULTIPLAYER RANKINGS //====================================================================== +// +// HU_drawPing +// +void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext) +{ + UINT8 numbars = 1; // how many ping bars do we draw? + UINT8 barcolor = 128; // color we use for the bars (green, yellow or red) + 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 // @@ -1208,7 +2071,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_DrawString(x + 20, y, ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) | ((players[tab[i].num].health > 0) ? 0 : V_60TRANS) @@ -1286,9 +2157,37 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I } // -// HU_DrawTeamTabRankings +// HU_Draw32Emeralds // -void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) +static void HU_Draw32Emeralds(INT32 x, INT32 y, INT32 pemeralds) +{ + //Draw the emeralds, in the CORRECT order, using tiny emerald sprites. + if (pemeralds & EMERALD1) + V_DrawSmallScaledPatch(x , y, 0, tinyemeraldpics[0]); + + if (pemeralds & EMERALD2) + V_DrawSmallScaledPatch(x+4, y, 0, tinyemeraldpics[1]); + + if (pemeralds & EMERALD3) + V_DrawSmallScaledPatch(x+8, y, 0, tinyemeraldpics[2]); + + if (pemeralds & EMERALD4) + V_DrawSmallScaledPatch(x+12 , y, 0, tinyemeraldpics[3]); + + if (pemeralds & EMERALD5) + V_DrawSmallScaledPatch(x+16, y, 0, tinyemeraldpics[4]); + + if (pemeralds & EMERALD6) + V_DrawSmallScaledPatch(x+20, y, 0, tinyemeraldpics[5]); + + if (pemeralds & EMERALD7) + V_DrawSmallScaledPatch(x+24, y, 0, tinyemeraldpics[6]); +} + +// +// HU_Draw32TeamTabRankings +// +static void HU_Draw32TeamTabRankings(playersort_t *tab, INT32 whiteplayer) { INT32 i,x,y; INT32 redplayers = 0, blueplayers = 0; @@ -1298,7 +2197,124 @@ void HU_DrawTeamTabRankings(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) + continue; //ignore them. + if (tab[i].color == skincolor_redteam) //red + { + redplayers++; + x = 14 + (BASEVIDWIDTH/2); + y = (redplayers * 9) + 20; + } + else if (tab[i].color == skincolor_blueteam) //blue + { + blueplayers++; + x = 14; + y = (blueplayers * 9) + 20; + } + else //er? not on red or blue, so ignore them + continue; + + strlcpy(name, tab[i].name, 8); + V_DrawString(x + 10, y, + ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) + | ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT) + | V_ALLOWLOWERCASE, name); + + if (gametype == GT_CTF) + { + if (players[tab[i].num].gotflag & GF_REDFLAG) // Red + V_DrawFixedPatch((x-10)*FRACUNIT, (y)*FRACUNIT, FRACUNIT/4, 0, rflagico, 0); + else if (players[tab[i].num].gotflag & GF_BLUEFLAG) // Blue + V_DrawFixedPatch((x-10)*FRACUNIT, (y)*FRACUNIT, FRACUNIT/4, 0, bflagico, 0); + } + + // Draw emeralds + if (!players[tab[i].num].powers[pw_super] + || ((leveltime/7) & 1)) + { + HU_Draw32Emeralds(x+60, y+2, tab[i].emeralds); + } + + if (players[tab[i].num].powers[pw_super]) + { + colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE); + V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT/4, 0, superprefix[players[tab[i].num].skin], colormap); + } + else + { + colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE); + if (players[tab[i].num].health <= 0) + V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT/4, V_HUDTRANSHALF, faceprefix[players[tab[i].num].skin], colormap); + else + V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT/4, 0, faceprefix[players[tab[i].num].skin], colormap); + } + 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"); + } + } +} + +// +// HU_DrawTeamTabRankings +// +void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) +{ + INT32 i,x,y; + INT32 redplayers = 0, blueplayers = 0; + boolean smol = false; + + // before we draw, we must count how many players are in each team. It makes an additional loop, but we need to know if we have to draw a big or a small ranking. + for (i = 0; i < MAXPLAYERS; i++) + { + if (players[tab[i].num].spectator) + continue; //ignore them. + + if (tab[i].color == skincolor_redteam) //red + { + if (redplayers++ > 8) + { + 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) @@ -1321,7 +2337,7 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) else //er? not on red or blue, so ignore them continue; - strlcpy(name, tab[i].name, 9); + strlcpy(name, tab[i].name, 7); V_DrawString(x + 20, y, ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) | ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT) @@ -1355,7 +2371,14 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) else V_DrawSmallMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap); } - V_DrawRightAlignedThinString(x+120, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); + 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"); + } } } @@ -1377,7 +2400,12 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline if (players[tab[i].num].spectator) continue; //ignore them. - strlcpy(name, tab[i].name, 9); + strlcpy(name, tab[i].name, 7); + 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_DrawString(x + 20, y, ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) | ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT) @@ -1432,15 +2460,15 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline if (circuitmap) { if (players[tab[i].num].exiting) - V_DrawRightAlignedThinString(x+156, y, 0, va("%i:%02i.%02i", G_TicsToMinutes(players[tab[i].num].realtime,true), G_TicsToSeconds(players[tab[i].num].realtime), G_TicsToCentiseconds(players[tab[i].num].realtime))); + V_DrawRightAlignedThinString(x+146, y, 0, va("%i:%02i.%02i", G_TicsToMinutes(players[tab[i].num].realtime,true), G_TicsToSeconds(players[tab[i].num].realtime), G_TicsToCentiseconds(players[tab[i].num].realtime))); else - V_DrawRightAlignedThinString(x+156, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); + V_DrawRightAlignedThinString(x+146, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); } else - V_DrawRightAlignedThinString(x+156, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count))); + V_DrawRightAlignedThinString(x+146, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count))); } else - V_DrawRightAlignedThinString(x+120, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); + V_DrawRightAlignedThinString(x+100, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); y += 16; if (y > 160) @@ -1451,6 +2479,107 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline } } +// +// HU_Draw32TabRankings +// +void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer) +{ + INT32 i; + const UINT8 *colormap; + char name[MAXPLAYERNAME+1]; + + V_DrawFill(160, 26, 1, 154, 0); //Draw a vertical line to separate the two sides. + 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 < scorelines; i++) + { + if (players[tab[i].num].spectator) + continue; //ignore them. + + strlcpy(name, tab[i].name, 7); + if (!splitscreen) // don't draw it on 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_DrawString(x + 10, y, + ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) + | ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT) + | V_ALLOWLOWERCASE, name); + + if (G_GametypeUsesLives()) //show lives + V_DrawRightAlignedThinString(x-1, y, V_ALLOWLOWERCASE, va("%d", players[tab[i].num].lives)); + else if (G_TagGametype() && players[tab[i].num].pflags & PF_TAGIT) + V_DrawFixedPatch((x-10)*FRACUNIT, (y)*FRACUNIT, FRACUNIT/4, 0, tagico, 0); + + // Draw emeralds + if (!players[tab[i].num].powers[pw_super] + || ((leveltime/7) & 1)) + { + HU_Draw32Emeralds(x+60, y+2, tab[i].emeralds); + //HU_DrawEmeralds(x-12,y+2,tab[i].emeralds); + } + + //V_DrawSmallScaledPatch (x, y-4, 0, livesback); + if (tab[i].color == 0) + { + colormap = colormaps; + if (players[tab[i].num].powers[pw_super]) + V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT/4, 0, superprefix[players[tab[i].num].skin], 0); + else + { + if (players[tab[i].num].health <= 0) + V_DrawFixedPatch(x*FRACUNIT, (y)*FRACUNIT, FRACUNIT/4, V_HUDTRANSHALF, faceprefix[players[tab[i].num].skin], 0); + else + V_DrawFixedPatch(x*FRACUNIT, (y)*FRACUNIT, FRACUNIT/4, 0, faceprefix[players[tab[i].num].skin], 0); + } + } + else + { + if (players[tab[i].num].powers[pw_super]) + { + colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE); + V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT/4, 0, superprefix[players[tab[i].num].skin], colormap); + } + else + { + colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE); + if (players[tab[i].num].health <= 0) + V_DrawFixedPatch(x*FRACUNIT, (y)*FRACUNIT, FRACUNIT/4, V_HUDTRANSHALF, faceprefix[players[tab[i].num].skin], colormap); + else + V_DrawFixedPatch(x*FRACUNIT, (y)*FRACUNIT, FRACUNIT/4, 0, faceprefix[players[tab[i].num].skin], colormap); + } + } + + // All data drawn with thin string for space. + if (gametype == GT_RACE) + { + if (circuitmap) + { + if (players[tab[i].num].exiting) + V_DrawRightAlignedThinString(x+128, y, 0, va("%i:%02i.%02i", G_TicsToMinutes(players[tab[i].num].realtime,true), G_TicsToSeconds(players[tab[i].num].realtime), G_TicsToCentiseconds(players[tab[i].num].realtime))); + else + V_DrawRightAlignedThinString(x+128, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); + } + else + V_DrawRightAlignedThinString(x+128, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count))); + } + else + V_DrawRightAlignedThinString(x+128, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); + + y += 9; + if (i == 16) + { + y = 32; + x += BASEVIDWIDTH/2; + } + } +} + // // HU_DrawEmeralds // @@ -1697,15 +2826,18 @@ static void HU_DrawRankings(void) scorelines++; } - if (scorelines > 20) - scorelines = 20; //dont draw past bottom of screen, show the best only + //if (scorelines > 20) + // scorelines = 20; //dont draw past bottom of screen, show the best only + // shush, we'll do it anyway. if (G_GametypeHasTeams()) HU_DrawTeamTabRankings(tab, whiteplayer); //separate function for Spazzo's silly request - else if (scorelines <= 9) + else if (scorelines <= 9 && !cv_compactscoreboard.value) HU_DrawTabRankings(40, 32, tab, scorelines, whiteplayer); - else + else if (scorelines <= 20 && !cv_compactscoreboard.value) HU_DrawDualTabRankings(32, 32, tab, scorelines, whiteplayer); + else + HU_Draw32TabRankings(14, 28, tab, scorelines, whiteplayer); // draw spectators in a ticker across the bottom if (!splitscreen && G_GametypeHasSpectators()) diff --git a/src/hu_stuff.h b/src/hu_stuff.h index 7b22f33f..c288b948 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -72,6 +72,18 @@ 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. + +// some functions +void HU_AddChatText(const char *text); + // set true when entering a chat message extern boolean chat_on; @@ -90,12 +102,12 @@ void HU_LoadGraphics(void); FUNCMATH void HU_Start(void); boolean HU_Responder(event_t *ev); - void HU_Ticker(void); void HU_Drawer(void); char HU_dequeueChatChar(void); void HU_Erase(void); void HU_clearChatChars(void); +void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext); // Lat': Ping drawer for scoreboard. void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer); void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer); void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index e8e8fd02..575b4452 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -20,6 +20,7 @@ #include "m_random.h" #include "s_sound.h" #include "g_game.h" +#include "hu_stuff.h" // HU_AddChatText #include "lua_script.h" #include "lua_libs.h" @@ -85,6 +86,51 @@ static int lib_print(lua_State *L) return 0; } +// Print stuff in the chat, or in the console if we can't. +static int lib_chatprint(lua_State *L) +{ + const char *str = luaL_checkstring(L, 1); // retrieve string + 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 (cv_consolechat.value || !netgame) + CONS_Printf("%s\n", str); + else + HU_AddChatText(str); + return 0; +} + +// Same as above, but do it for only one player. +static int lib_chatprintf(lua_State *L) +{ + int n = lua_gettop(L); /* number of arguments */ + 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 + 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 (cv_consolechat.value || !netgame) + CONS_Printf("%s\n", str); + else + HU_AddChatText(str); + return 0; +} + static int lib_evalMath(lua_State *L) { const char *word = luaL_checkstring(L, 1); @@ -1656,7 +1702,7 @@ static int lib_sStartSound(lua_State *L) const void *origin = NULL; sfxenum_t sound_id = luaL_checkinteger(L, 2); player_t *player = NULL; - NOHUD + //NOHUD // kys @whoever did this. if (sound_id >= NUMSFX) return luaL_error(L, "sfx %d out of range (0 - %d)", sound_id, NUMSFX-1); if (!lua_isnil(L, 1)) @@ -1672,7 +1718,12 @@ static int lib_sStartSound(lua_State *L) return LUA_ErrInvalid(L, "player_t"); } if (!player || P_IsLocalPlayer(player)) + { + 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; } @@ -1982,6 +2033,8 @@ static int lib_gTicsToMilliseconds(lua_State *L) static luaL_Reg lib[] = { {"print", lib_print}, + {"chatprint", lib_chatprint}, + {"chatprintf", lib_chatprintf}, {"EvalMath", lib_evalMath}, // m_random diff --git a/src/m_menu.c b/src/m_menu.c index 0ab77157..80172216 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -293,7 +293,7 @@ static void M_ToggleMIDI(void); //Misc menu_t OP_DataOptionsDef, OP_ScreenshotOptionsDef, OP_EraseDataDef; -menu_t OP_GameOptionsDef, OP_ServerOptionsDef; +menu_t OP_GameOptionsDef, OP_ChatOptionsDef, OP_ServerOptionsDef; menu_t OP_NetgameOptionsDef, OP_GametypeOptionsDef; menu_t OP_MonitorToggleDef; static void M_ScreenshotOptions(INT32 choice); @@ -1286,22 +1286,34 @@ static menuitem_t OP_GameOptionsMenu[] = {IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Master server", &cv_masterserver, 10}, #endif - {IT_STRING | IT_CVAR, NULL, "Show HUD", &cv_showhud, 40}, + {IT_STRING | IT_SUBMENU, NULL, "Chat Options...", &OP_ChatOptionsDef, 40}, + {IT_STRING | IT_CVAR, NULL, "Show HUD", &cv_showhud, 50}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "HUD Visibility", &cv_translucenthud, 50}, - {IT_STRING | IT_CVAR, NULL, "Timer Display", &cv_timetic, 60}, + NULL, "HUD Visibility", &cv_translucenthud, 60}, + {IT_STRING | IT_CVAR, NULL, "Timer Display", &cv_timetic, 70}, + {IT_STRING | IT_CVAR, NULL, "Always Compact Rankings", &cv_compactscoreboard, 80}, #ifdef SEENAMES - {IT_STRING | IT_CVAR, NULL, "HUD Player Names", &cv_seenames, 80}, + {IT_STRING | IT_CVAR, NULL, "HUD Player Names", &cv_seenames, 90}, #endif - {IT_STRING | IT_CVAR, NULL, "Log Hazard Damage", &cv_hazardlog, 90}, + {IT_STRING | IT_CVAR, NULL, "Log Hazard Damage", &cv_hazardlog, 100}, - {IT_STRING | IT_CVAR, NULL, "Console Back Color", &cons_backcolor, 100}, - {IT_STRING | IT_CVAR, NULL, "Console Text Size", &cv_constextsize,110}, - {IT_STRING | IT_CVAR, NULL, "Uppercase Console", &cv_allcaps, 120}, + {IT_STRING | IT_CVAR, NULL, "Console Back Color", &cons_backcolor, 110}, + {IT_STRING | IT_CVAR, NULL, "Console Text Size", &cv_constextsize,120}, + {IT_STRING | IT_CVAR, NULL, "Uppercase Console", &cv_allcaps, 130}, {IT_STRING | IT_CVAR, NULL, "Title Screen Demos", &cv_rollingdemos, 140}, }; +static menuitem_t OP_ChatOptionsMenu[] = +{ + {IT_STRING | IT_CVAR, NULL, "Chat Width", &cv_chatwidth, 10}, + {IT_STRING | IT_CVAR, NULL, "Chat Height", &cv_chatheight, 20}, + {IT_STRING | IT_CVAR, NULL, "Message Timer", &cv_chattime, 30}, + {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, "Old Console Chat", &cv_consolechat, 60}, +}; + static menuitem_t OP_ServerOptionsMenu[] = { {IT_STRING | IT_SUBMENU, NULL, "General netgame options...", &OP_NetgameOptionsDef, 10}, @@ -1697,6 +1709,7 @@ menu_t OP_ServerOptionsDef = DEFAULTMENUSTYLE("M_SERVER", OP_ServerOptionsMenu, menu_t OP_NetgameOptionsDef = DEFAULTMENUSTYLE("M_SERVER", OP_NetgameOptionsMenu, &OP_ServerOptionsDef, 30, 30); menu_t OP_GametypeOptionsDef = DEFAULTMENUSTYLE("M_SERVER", OP_GametypeOptionsMenu, &OP_ServerOptionsDef, 30, 30); +menu_t OP_ChatOptionsDef = DEFAULTMENUSTYLE("M_GAME", OP_ChatOptionsMenu, &OP_GameOptionsDef, 30, 30); menu_t OP_MonitorToggleDef = { "M_SERVER", @@ -2696,7 +2709,7 @@ void M_Init(void) CV_RegisterVar(&cv_newgametype); CV_RegisterVar(&cv_chooseskin); CV_RegisterVar(&cv_autorecord); - + if (dedicated) return; @@ -6295,13 +6308,6 @@ static void M_DrawConnectIPMenu(void) static void M_ConnectIP(INT32 choice) { (void)choice; - - if (*setupm_ip == 0) - { - M_StartMessage("You must specify an IP address.\n", NULL, MM_NOTHING); - return; - } - COM_BufAddText(va("connect \"%s\"\n", setupm_ip)); // A little "please wait" message. diff --git a/src/v_video.c b/src/v_video.c index 161c03d0..52397bba 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -834,6 +834,130 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) memset(dest, (UINT8)(c&255), w * vid.bpp); } +// 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; + + if (rendermode == render_none) + return; + +#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; + } + 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; + } +#endif + + if (!(c & V_NOSCALESTART)) + { + INT32 dupx = vid.dupx, dupy = vid.dupy; + + if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT) + { // Clear the entire screen, from dest to deststop. Yes, this really works. + memset(screens[0], (UINT8)(c&255), vid.width * vid.height * vid.bpp); + return; + } + + x *= dupx; + y *= dupy; + w *= dupx; + h *= dupy; + + // Center it if necessary + if (vid.width != BASEVIDWIDTH * dupx) + { + // dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx, + // so center this imaginary screen + if (c & V_SNAPTORIGHT) + x += (vid.width - (BASEVIDWIDTH * dupx)); + else if (!(c & V_SNAPTOLEFT)) + x += (vid.width - (BASEVIDWIDTH * dupx)) / 2; + } + if (vid.height != BASEVIDHEIGHT * dupy) + { + // same thing here + if (c & V_SNAPTOBOTTOM) + y += (vid.height - (BASEVIDHEIGHT * dupy)); + else if (!(c & V_SNAPTOTOP)) + y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2; + } + } + + if (x >= vid.width || y >= vid.height) + return; // off the screen + if (x < 0) { + w += x; + x = 0; + } + if (y < 0) { + h += y; + y = 0; + } + + if (w <= 0 || h <= 0) + return; // zero width/height wouldn't draw anything + if (x + w > vid.width) + w = vid.width-x; + if (y + h > vid.height) + h = vid.height-y; + + dest = screens[0] + y*vid.width + x; + + if ((alphalevel = ((c & V_ALPHAMASK) >> V_ALPHASHIFT))) + { + if (alphalevel == 13) + alphalevel = hudminusalpha[cv_translucenthud.value]; + else if (alphalevel == 14) + alphalevel = 10 - cv_translucenthud.value; + else if (alphalevel == 15) + alphalevel = hudplusalpha[cv_translucenthud.value]; + + if (alphalevel >= 10) + return; // invis + } + + c &= 255; + + if (!alphalevel) { + for (v = 0; v < h; v++, dest += vid.width) { + for (u = 0; u < w; u++) { + dest[u] = consolebgmap[dest[u]]; + } + } + } else { // mpc 12-04-2018 + const UINT8 *fadetable = ((UINT8 *)transtables + ((alphalevel-1)<y) ? y : x + w = clip(w,vid.width); + h = clip(h,vid.height); + for (v = 0; v < h; v++, dest += vid.width) { + for (u = 0; u < w; u++) { + dest[u] = fadetable[consolebgmap[dest[u]]]; + } + } + } +} + // // Fills a box of pixels using a flat texture as a pattern, scaled to screen size. // @@ -1054,6 +1178,32 @@ void V_DrawCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed) V_DrawScaledPatch(x, y, flags, hu_font[c]); } +// Writes a single character for the chat. (draw WHITE if bit 7 set) +// Essentially the same as the above but it's small or big depending on what resolution you've chosen to huge.. +// +void V_DrawChatCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed, UINT8 *colormap) +{ + INT32 w, flags; + //const UINT8 *colormap = V_GetStringColormap(c); + + flags = c & ~(V_CHARCOLORMASK | V_PARAMMASK); + c &= 0x7f; + if (lowercaseallowed) + c -= HU_FONTSTART; + else + c = toupper(c) - HU_FONTSTART; + if (c < 0 || c >= HU_FONTSIZE || !hu_font[c]) + return; + + 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. // This is a muuuch better method than V_WORDWRAP. char *V_WordWrap(INT32 x, INT32 w, INT32 option, const char *string) diff --git a/src/v_video.h b/src/v_video.h index 353f84c1..a8e8d6e6 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -139,6 +139,7 @@ void V_DrawScaledPic (INT32 px1, INT32 py1, INT32 scrn, INT32 lumpnum); // fill a box with a single color void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c); +void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c); // fill a box with a flat as a pattern void V_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatnum); @@ -149,6 +150,8 @@ void V_DrawFadeConsBack(INT32 plines); // draw a single character void V_DrawCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed); +// draw a single character, but for the chat +void V_DrawChatCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed, UINT8 *colormap); void V_DrawLevelTitle(INT32 x, INT32 y, INT32 option, const char *string); From ad187c26f0341e47cbe055f2dc9eca2b8c906755 Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Tue, 31 Jul 2018 15:57:19 +0200 Subject: [PATCH 02/19] Repositionning chat & bugfixes --- src/dehacked.c | 27 -------------------- src/g_game.c | 12 ++------- src/hardware/hw_main.h | 1 - src/hu_stuff.c | 58 ++++++++++++++++++++++++------------------ 4 files changed, 35 insertions(+), 63 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index ac2aa9a8..de563805 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8286,33 +8286,6 @@ static inline int lib_getenum(lua_State *L) } else if (fastcmp(word, "token")) { lua_pushinteger(L, token); return 1; - } else if (fastcmp(word,"consoleplayer")) { - if (!playeringame[consoleplayer]) - return 0; - LUA_PushUserdata(L, &players[consoleplayer], META_PLAYER); - return 1; - } else if (fastcmp(word,"displayplayer")) { - if (!playeringame[displayplayer]) - return 0; - LUA_PushUserdata(L, &players[displayplayer], META_PLAYER); - return 1; - } else if (fastcmp(word,"secondarydisplayplayer")) { - if (!playeringame[displayplayer]) - return 0; - LUA_PushUserdata(L, &players[secondarydisplayplayer], META_PLAYER); - return 1; - } else if (fastcmp(word, "timelimitintics")) { - lua_pushinteger(L, timelimitintics); - return 1; - } else if (fastcmp(word,"hidetime")) { - lua_pushinteger(L, hidetime); - return 1; - } else if (fastcmp(word, "pointlimit")) { - lua_pushinteger(L, cv_pointlimit.value); - return 1; - } else if (fastcmp(word,"allowjoin")) { - lua_pushboolean(L, cv_allownewplayer.value); - return 1; } return 0; } diff --git a/src/g_game.c b/src/g_game.c index d70a8a30..734b01f3 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -358,7 +358,7 @@ consvar_t cv_chattime = {"chattime", "8", CV_SAVE, chattime_cons_t, NULL, 0, NUL // chatwidth static CV_PossibleValue_t chatwidth_cons_t[] = {{64, "MIN"}, {150, "MAX"}, {0, NULL}}; -consvar_t cv_chatwidth = {"chatwidth", "150", CV_SAVE, chatwidth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_chatwidth = {"chatwidth", "128", CV_SAVE, chatwidth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // chatheight static CV_PossibleValue_t chatheight_cons_t[] = {{6, "MIN"}, {22, "MAX"}, {0, NULL}}; @@ -1266,10 +1266,6 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) if ((cmd->forwardmove || cmd->sidemove || cmd->buttons) && displayplayer != consoleplayer) displayplayer = consoleplayer; - - if (playeringame[consoleplayer]) // do not run on title screen. - LUAh_PlayerCmd(player, cmd); // run this hook after we've done everything. Why? Because that way we can check what buttons we're pressing and what we're doing in that frame rather than using last frame's info! - } // like the g_buildticcmd 1 but using mouse2, gamcontrolbis, ... @@ -1564,11 +1560,7 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics) { localangle2 += (cmd->angleturn<<16); cmd->angleturn = (INT16)(localangle2 >> 16); - } - - if (playeringame[consoleplayer]) // do not run on title screen. - LUAh_PlayerCmd(player, cmd); - + } } // User has designated that they want diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index ba809663..a03be132 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -71,7 +71,6 @@ void HWR_DrawScreenFinalTexture(int width, int height); // This stuff is put here so MD2's can use them UINT32 HWR_Lighting(INT32 light, UINT32 color, UINT32 fadecolor, boolean fogblockpoly, boolean plane); -UINT32 HWR_NoColormapLighting(INT32 light, UINT32 color, UINT32 fadecolor, boolean fogblockpoly, boolean plane); // do it like cv_grfog off for non colormap stuff FUNCMATH UINT8 LightLevelToLum(INT32 l); extern CV_PossibleValue_t granisotropicmode_cons_t[]; diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 43532576..310fdd17 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1225,7 +1225,7 @@ char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string) // 30/7/18: chaty is now the distance at which the lowest point of the chat will be drawn if that makes any sense. -INT16 chatx = 160, chaty = 192; // let's use this as our coordinates, shh +INT16 chatx = 16, chaty = 172; // let's use this as our coordinates, shh // chat stuff by VincyTM LOL XD! @@ -1325,7 +1325,7 @@ static void HU_drawMiniChat(void) else { UINT8 *colormap = CHAT_GetStringColormap(clrflag); - V_DrawChatCharacter(x + dx + 2, y+dy, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTORIGHT|transflag, !cv_allcaps.value, colormap); + V_DrawChatCharacter(x + dx + 2, y+dy, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag, !cv_allcaps.value, colormap); } dx += charwidth; @@ -1386,14 +1386,14 @@ static void HU_drawChatLog(INT32 offset) if (chat_scroll > chat_maxscroll) chat_scroll = chat_maxscroll; - INT32 charwidth = (vid.width < 640) ? 8 : 4, charheight = (vid.width < 640) ? 8 : 6; + 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; size_t i = 0; INT32 chat_topy = y + chat_scroll*charheight; INT32 chat_bottomy = chat_topy + cv_chatheight.value*charheight; boolean atbottom = false; - V_DrawFillConsoleMap(chatx, chat_topy, cv_chatwidth.value, cv_chatheight.value*charheight +2, 239|V_SNAPTOBOTTOM|V_SNAPTORIGHT); // log box + V_DrawFillConsoleMap(chatx, chat_topy, cv_chatwidth.value, cv_chatheight.value*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_SNAPTORIGHT, !cv_allcaps.value, colormap); + 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. @@ -1460,9 +1460,9 @@ static void HU_drawChatLog(INT32 offset) // draw arrows to indicate that we can (or not) scroll. if (chat_scroll > 0) - HU_DrawUpArrow(chatx-8, ((justscrolledup) ? (chat_topy-1) : (chat_topy)), V_SNAPTOBOTTOM | V_SNAPTORIGHT); + HU_DrawUpArrow(chatx-8, ((justscrolledup) ? (chat_topy-1) : (chat_topy)), V_SNAPTOBOTTOM | V_SNAPTOLEFT); if (chat_scroll < chat_maxscroll) - HU_DrawDownArrow(chatx-8, chat_bottomy-((justscrolleddown) ? 3 : 4), V_SNAPTOBOTTOM | V_SNAPTORIGHT); + HU_DrawDownArrow(chatx-8, chat_bottomy-((justscrolleddown) ? 3 : 4), V_SNAPTOBOTTOM | V_SNAPTOLEFT); justscrolleddown = false; justscrolledup = false; @@ -1477,8 +1477,8 @@ static void HU_drawChatLog(INT32 offset) 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 = (vid.width < 640) ? 8 : 4, charheight = (vid.width < 640) ? 8 : 6; - INT32 t = 0, c = 0, y = chaty - ((vid.width < 640 ) ? (typelines*charheight+2) : (typelines*charheight)); + INT32 charwidth = 4, charheight = 6; + INT32 t = 0, c = 0, y = chaty - (typelines*charheight); size_t i = 0; const char *ntalk = "Say: ", *ttalk = "Team: "; const char *talk = ntalk; @@ -1494,14 +1494,14 @@ static void HU_DrawChat(void) #endif } - V_DrawFillConsoleMap(chatx, y-1, cv_chatwidth.value, (vid.width < 640 ) ? (typelines*charheight+2) : (typelines*charheight), 239 | V_SNAPTOBOTTOM | V_SNAPTORIGHT); + V_DrawFillConsoleMap(chatx, y-1, cv_chatwidth.value, (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_SNAPTORIGHT, !cv_allcaps.value, NULL); + V_DrawChatCharacter(chatx + c + 2, y, talk[i++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT, !cv_allcaps.value, NULL); c += charwidth; } @@ -1510,26 +1510,34 @@ static void HU_DrawChat(void) typelines = 1; if ((strlen(w_chat) == 0 || c_input == 0) && hu_tick < 4) - V_DrawChatCharacter(chatx + 2 + c, y+1, '_' |V_SNAPTOBOTTOM|V_SNAPTORIGHT|t, !cv_allcaps.value, NULL); - + V_DrawChatCharacter(chatx + 2 + c, y+1, '_' |V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL); + while (w_chat[i]) { - - if (c_input == (i+1) && hu_tick < 4) + boolean skippedline = false; + if (c_input == (i+1)) { - int cursorx = (c+charwidth < cv_chatwidth.value-charwidth) ? (chatx + 2 + c+charwidth) : (chatx); // we may have to go down. - int cursory = (cursorx != chatx) ? (y) : (y+charheight); - V_DrawChatCharacter(cursorx, cursory+1, '_' |V_SNAPTOBOTTOM|V_SNAPTORIGHT|t, !cv_allcaps.value, NULL); + int cursorx = (c+charwidth < cv_chatwidth.value-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 + { + typelines += 1; + skippedline = true; + } + } //Hurdler: isn't it better like that? if (w_chat[i] < HU_FONTSTART) ++i; else - V_DrawChatCharacter(chatx + c + 2, y, w_chat[i++] | V_SNAPTOBOTTOM|V_SNAPTORIGHT | t, !cv_allcaps.value, NULL); + 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) + if (c > cv_chatwidth.value-(charwidth*2) && !skippedline) { c = 0; y += charheight; @@ -1587,19 +1595,19 @@ static void HU_DrawChat(void) } } - if (1 || (playeringame[i])) + if (playeringame[i]) { char name[MAXPLAYERNAME+1]; strlcpy(name, player_names[i], 7); // shorten name to 7 characters. - V_DrawFillConsoleMap(chatx-50, p_dispy- (6*count), 48, 6, 239 | V_SNAPTOBOTTOM | V_SNAPTORIGHT); // fill it like the chat so the text doesn't become hard to read because of the hud. - V_DrawSmallString(chatx-48, p_dispy- (6*count), V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_ALLOWLOWERCASE, va("\x82%d\x80 - %s", i, name)); + 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)); count++; } } if (count == 0) // no results. { - V_DrawFillConsoleMap(chatx-50, p_dispy- (6*count), 48, 6, 239 | V_SNAPTOBOTTOM | V_SNAPTORIGHT); // fill it like the chat so the text doesn't become hard to read because of the hud. - V_DrawSmallString(chatx-48, p_dispy- (6*count), V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_ALLOWLOWERCASE, "NO RESULT."); + V_DrawFillConsoleMap(chatx-50, 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-48, p_dispy- (6*count), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, "NO RESULT."); } } From 03dc4c968095dc6847fb4e68c1a4af31afb78728 Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Tue, 31 Jul 2018 23:56:23 +0200 Subject: [PATCH 03/19] Fixed sub 400p chat for console --- src/console.c | 2 +- src/hu_stuff.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/console.c b/src/console.c index 357f1ef8..0adde1d1 100644 --- a/src/console.c +++ b/src/console.c @@ -1443,7 +1443,7 @@ static void CON_DrawHudlines(void) if (con_hudlines <= 0) return; - if (chat_on && cv_consolechat.value) + if (chat_on && (cv_consolechat.value || vid.width < 640)) y = charheight; // leave place for chat input in the first row of text (only do it if consolechat is on.) else y = 0; diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 310fdd17..5544e075 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1860,7 +1860,7 @@ void HU_Drawer(void) // count down the scroll timer. if (chat_scrolltime > 0) chat_scrolltime--; - if (!cv_consolechat.value && vid.width >= 640) // don't even bother with 200p + if (!cv_consolechat.value && vid.width > 320) // don't even bother with 200p HU_DrawChat(); else HU_DrawChat_Old(); // why the fuck......................... From 8747a8529d60a074acacf8b6d8c858644309703f Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Sun, 19 Aug 2018 10:58:29 +0200 Subject: [PATCH 04/19] Changed chat position, Added chat back tint Fixed word wrapping glitches --- src/d_netcmd.c | 1 + src/g_game.c | 3 + src/g_game.h | 2 +- src/hu_stuff.c | 193 ++++++++++++++++++++++++++----------------------- src/m_menu.c | 13 ++-- 5 files changed, 116 insertions(+), 96 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index dbd26a73..895ad308 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -684,6 +684,7 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_chatwidth); CV_RegisterVar(&cv_chattime); CV_RegisterVar(&cv_chatspamprotection); + CV_RegisterVar(&cv_chatbacktint); CV_RegisterVar(&cv_consolechat); CV_RegisterVar(&cv_chatnotifications); CV_RegisterVar(&cv_crosshair); diff --git a/src/g_game.c b/src/g_game.c index 734b01f3..d0141b2b 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -370,6 +370,9 @@ consvar_t cv_chatnotifications= {"chatnotifications", "On", CV_SAVE, CV_OnOff, N // chat spam protection (why would you want to disable that???) 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}; + // 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}; diff --git a/src/g_game.h b/src/g_game.h index cd0a71f2..83e70b64 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -54,7 +54,7 @@ extern tic_t timeinmap; // Ticker for time spent in level (used for levelcard di extern INT16 rw_maximums[NUM_WEAPONS]; // used in game menu -extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatspamprotection, cv_compactscoreboard; +extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatbacktint, cv_chatspamprotection, cv_compactscoreboard; extern consvar_t cv_crosshair, cv_crosshair2; extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_mousemove; extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_fireaxis,cv_firenaxis; diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 5544e075..e8940a19 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1223,9 +1223,10 @@ char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string) return newstring; } + // 30/7/18: chaty is now the distance at which the lowest point of the chat will be drawn if that makes any sense. -INT16 chatx = 16, chaty = 172; // let's use this as our coordinates, shh +INT16 chatx = 13, chaty = 169; // let's use this as our coordinates, shh // chat stuff by VincyTM LOL XD! @@ -1233,34 +1234,37 @@ INT16 chatx = 16, chaty = 172; // 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 x = chatx+2; + INT32 charwidth = 4, charheight = 6; 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... - + for (; i>0; i--) - { - const char *msg = CHAT_WordWrap(x, cv_chatwidth.value-charwidth, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]); + { + const char *msg = CHAT_WordWrap(x+2, cv_chatwidth.value-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]); size_t j = 0; INT32 linescount = 0; - + while(msg[j]) // iterate through msg - { + { if (msg[j] < HU_FONTSTART) // don't draw - { + { if (msg[j] == '\n') // get back down. { ++j; - linescount += 1; - dx = 0; + if (!prev_linereturn) + { + linescount += 1; + dx = 0; + } + prev_linereturn = true; continue; } else if (msg[j] & 0x80) // stolen from video.c, nice. @@ -1268,14 +1272,14 @@ static void HU_drawMiniChat(void) ++j; continue; } - - ++j; + + ++j; } else { j++; } - + prev_linereturn = false; dx += charwidth; if (dx >= cv_chatwidth.value) { @@ -1287,30 +1291,34 @@ static void HU_drawMiniChat(void) dx = 0; msglines += linescount+1; } - + INT32 y = chaty - charheight*(msglines+1); - dx = 0; + dx = 0; dy = 0; i = 0; - + prev_linereturn = false; + for (; i<=(chat_nummsg_min-1); i++) // iterate through our hot messages { - INT32 clrflag = 0; - INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below... + 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, cv_chatwidth.value-charwidth, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it. - + 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. + while(msg[j]) // iterate through msg - { + { if (msg[j] < HU_FONTSTART) // don't draw - { + { if (msg[j] == '\n') // get back down. { ++j; - dy += charheight; - dx = 0; + if (!prev_linereturn) + { + dy += charheight; + dx = 0; + } + prev_linereturn = true; continue; } else if (msg[j] & 0x80) // stolen from video.c, nice. @@ -1319,16 +1327,21 @@ static void HU_drawMiniChat(void) ++j; continue; } - - ++j; + + ++j; } 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); + V_DrawChatCharacter(x + dx + 2, y+dy, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag, !cv_allcaps.value, colormap); } - + dx += charwidth; + prev_linereturn = false; if (dx >= cv_chatwidth.value) { dx = 0; @@ -1338,10 +1351,10 @@ static void HU_drawMiniChat(void) dy += charheight; dx = 0; } - + // decrement addy and make that shit smooth: addy /= 2; - + } // HU_DrawUpArrow @@ -1381,29 +1394,29 @@ static void HU_DrawDownArrow(INT32 x, INT32 y, INT32 options) static void HU_drawChatLog(INT32 offset) { - + // before we do anything, 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; - size_t i = 0; + UINT32 i = 0; INT32 chat_topy = y + chat_scroll*charheight; INT32 chat_bottomy = chat_topy + cv_chatheight.value*charheight; boolean atbottom = false; - + V_DrawFillConsoleMap(chatx, chat_topy, cv_chatwidth.value, cv_chatheight.value*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!!!! { @@ -1441,32 +1454,34 @@ static void HU_drawChatLog(INT32 offset) dy += charheight; 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 } chat_scrollmedown = false; - + // getmaxscroll through a lazy hack. We do all these loops, so let's not do more loops that are gonna lag the game more. :P - chat_maxscroll = (dy/charheight)-cv_chatheight.value; // welcome to C, we don't know what min() and max() are. - if (chat_maxscroll < 0) + chat_maxscroll = (dy/charheight); // welcome to C, we don't know what min() and max() are. + if (chat_maxscroll <= (UINT32)cv_chatheight.value) chat_maxscroll = 0; - + else + chat_maxscroll -= cv_chatheight.value; + // if we're not bound by the time, autoscroll for next frame: if (atbottom) chat_scroll = chat_maxscroll; - + // draw arrows to indicate that we can (or not) scroll. - + if (chat_scroll > 0) HU_DrawUpArrow(chatx-8, ((justscrolledup) ? (chat_topy-1) : (chat_topy)), V_SNAPTOBOTTOM | V_SNAPTOLEFT); if (chat_scroll < chat_maxscroll) HU_DrawDownArrow(chatx-8, chat_bottomy-((justscrolleddown) ? 3 : 4), V_SNAPTOBOTTOM | V_SNAPTOLEFT); - + justscrolleddown = false; justscrolledup = false; -} +} // // HU_DrawChat @@ -1476,13 +1491,13 @@ static void HU_drawChatLog(INT32 offset) 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 t = 0, c = 0, y = chaty - (typelines*charheight); - size_t i = 0; + UINT32 i = 0; const char *ntalk = "Say: ", *ttalk = "Team: "; const char *talk = ntalk; - + if (teamtalk) { talk = ttalk; @@ -1493,9 +1508,9 @@ static void HU_DrawChat(void) t = 0x400; // Blue #endif } - + V_DrawFillConsoleMap(chatx, y-1, cv_chatwidth.value, (typelines*charheight), 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT); - + while (talk[i]) { if (talk[i] < HU_FONTSTART) @@ -1505,13 +1520,13 @@ static void HU_DrawChat(void) c += charwidth; } - + i = 0; typelines = 1; - + if ((strlen(w_chat) == 0 || c_input == 0) && hu_tick < 4) V_DrawChatCharacter(chatx + 2 + c, y+1, '_' |V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL); - + while (w_chat[i]) { boolean skippedline = false; @@ -1520,16 +1535,16 @@ static void HU_DrawChat(void) int cursorx = (c+charwidth < cv_chatwidth.value-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); - + V_DrawChatCharacter(cursorx, cursory+1, '_' |V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL); + if (cursorx == chatx+1) // a weirdo hack { typelines += 1; skippedline = true; - } - - } - + } + + } + //Hurdler: isn't it better like that? if (w_chat[i] < HU_FONTSTART) ++i; @@ -1547,56 +1562,56 @@ static void HU_DrawChat(void) // handle /pm list. if (strnicmp(w_chat, "/pm", 3) == 0 && vid.width >= 400 && !teamtalk) // 320x200 unsupported kthxbai - { + { i = 0; - int count = 0; + INT32 count = 0; INT32 p_dispy = chaty - charheight -1; 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); strncpy(nodenum, w_chat+3, 4); - INT32 n = atoi((const char*) nodenum); // turn that into a number + UINT32 n = atoi((const char*) nodenum); // turn that into a number // special cases: - + if ((n == 0) && !(w_chat[4] == '0')) - { + { if (!(i<10)) - continue; + continue; } else if ((n == 1) && !(w_chat[3] == '0')) - { + { if (!((i == 1) || ((i >= 10) && (i <= 19)))) continue; } else if ((n == 2) && !(w_chat[3] == '0')) - { + { if (!((i == 2) || ((i >= 20) && (i <= 29)))) continue; } else if ((n == 3) && !(w_chat[3] == '0')) - { + { if (!((i == 3) || ((i >= 30) && (i <= 31)))) continue; } else // general case. - { + { if (i != n) continue; } } - + if (playeringame[i]) - { + { 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. @@ -1608,11 +1623,11 @@ static void HU_DrawChat(void) { V_DrawFillConsoleMap(chatx-50, 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-48, p_dispy- (6*count), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, "NO RESULT."); - } + } } - + HU_drawChatLog(typelines-1); // typelines is the # of lines we're typing. If there's more than 1 then the log should scroll up to give us more space. - + } // why the fuck would you use this... diff --git a/src/m_menu.c b/src/m_menu.c index 80172216..edc11ffe 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1306,12 +1306,13 @@ static menuitem_t OP_GameOptionsMenu[] = static menuitem_t OP_ChatOptionsMenu[] = { - {IT_STRING | IT_CVAR, NULL, "Chat Width", &cv_chatwidth, 10}, - {IT_STRING | IT_CVAR, NULL, "Chat Height", &cv_chatheight, 20}, - {IT_STRING | IT_CVAR, NULL, "Message Timer", &cv_chattime, 30}, - {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, "Old Console Chat", &cv_consolechat, 60}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Chat Box Width", &cv_chatwidth, 10}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Chat Box Height", &cv_chatheight, 20}, + {IT_STRING | IT_CVAR, NULL, "Message Fadeout Time", &cv_chattime, 30}, + {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}, }; static menuitem_t OP_ServerOptionsMenu[] = From b09019dc4a676227a31030672b86c8f2405b0d93 Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Sun, 19 Aug 2018 11:12:21 +0200 Subject: [PATCH 05/19] Fix old chat detection. --- src/console.c | 2 +- src/hu_stuff.c | 8 ++++---- src/hu_stuff.h | 1 + src/lua_baselib.c | 4 ++-- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/console.c b/src/console.c index 0adde1d1..505ab831 100644 --- a/src/console.c +++ b/src/console.c @@ -1443,7 +1443,7 @@ static void CON_DrawHudlines(void) if (con_hudlines <= 0) return; - if (chat_on && (cv_consolechat.value || vid.width < 640)) + if (chat_on && OLDCHAT) y = charheight; // leave place for chat input in the first row of text (only do it if consolechat is on.) else y = 0; diff --git a/src/hu_stuff.c b/src/hu_stuff.c index e8940a19..4142e8d8 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -778,7 +778,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) } - if (cv_consolechat.value) + 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. @@ -1875,14 +1875,14 @@ void HU_Drawer(void) // count down the scroll timer. if (chat_scrolltime > 0) chat_scrolltime--; - if (!cv_consolechat.value && vid.width > 320) // don't even bother with 200p + if (!OLDCHAT) HU_DrawChat(); else HU_DrawChat_Old(); // why the fuck......................... } else { - if (!cv_consolechat.value) + if (!OLDCHAT) { HU_drawMiniChat(); // draw messages in a cool fashion. chat_scrolltime = 0; // do scroll anyway. @@ -2005,7 +2005,7 @@ void HU_Erase(void) // clear the message lines that go away, so use _oldclearlines_ bottomline = oldclearlines; oldclearlines = con_clearlines; - if (chat_on && cv_consolechat.value) + if (chat_on && OLDCHAT) if (bottomline < 8) bottomline = 8; // only do it for consolechat. consolechat is gay. diff --git a/src/hu_stuff.h b/src/hu_stuff.h index c288b948..f8fcd375 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -80,6 +80,7 @@ extern patch_t *tallminus; } 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); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 575b4452..41bfd008 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -96,7 +96,7 @@ static int lib_chatprint(lua_State *L) if (len > 255) // string is too long!!! return luaL_error(L, "String exceeds the 255 characters limit of the chat buffer."); - if (cv_consolechat.value || !netgame) + if (OLDCHAT) CONS_Printf("%s\n", str); else HU_AddChatText(str); @@ -124,7 +124,7 @@ static int lib_chatprintf(lua_State *L) if (len > 255) // string is too long!!! return luaL_error(L, "String exceeds the 255 characters limit of the chat buffer."); - if (cv_consolechat.value || !netgame) + if (OLDCHAT) CONS_Printf("%s\n", str); else HU_AddChatText(str); From 40b4d63620a4f78994922bb323b01ae4dd631556 Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Sun, 19 Aug 2018 11:25:20 +0200 Subject: [PATCH 06/19] Fix capslock being wonky. --- src/console.c | 7 ++++++- src/hu_stuff.c | 14 +++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/console.c b/src/console.c index 505ab831..c9e3c357 100644 --- a/src/console.c +++ b/src/console.c @@ -1048,7 +1048,12 @@ boolean CON_Responder(event_t *ev) return true; } - if (capslock ^ shiftdown) // gets capslock to work because capslock is cool + if (key >= 'a' && key <= 'z') + { + if (capslock ^ shiftdown) + key = shiftxform[key]; + } + else if (shiftdown) key = shiftxform[key]; // enter a char into the command prompt diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 4142e8d8..d191874b 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1057,12 +1057,16 @@ boolean HU_Responder(event_t *ev) return true; } - // use console translations - if (shiftdown ^ capslock) + // use console translations + + if (c >= 'a' && c <= 'z') + { + if (capslock ^ shiftdown) + c = shiftxform[c]; + } + else if (shiftdown) c = shiftxform[c]; - - // TODO: make chat behave like the console, so that we can go back and edit stuff when we fuck up. - + // pasting. pasting is cool. chat is a bit limited, though :( if ((c == 'v' || c == 'V') && ctrldown) { From fa3cc130244b78a25c657863d4f7090abe48ff5f Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 14 Dec 2018 16:19:38 -0500 Subject: [PATCH 07/19] Add symlink to debian package for /usr/games/srb2 --- debian/rules | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/debian/rules b/debian/rules index 02e3dc78..ff80d50b 100755 --- a/debian/rules +++ b/debian/rules @@ -59,6 +59,7 @@ DBGNAME = debug/$(EXENAME) PKGDIR = usr/games/SRB2 DBGDIR = usr/lib/debug/$(PKGDIR) +LINKDIR = usr/games PIXMAPS_DIR = usr/share/pixmaps DESKTOP_DIR = usr/share/applications PREFIX = $(shell test "$(CROSS_COMPILE_BUILD)" != "$(CROSS_COMPILE_HOST)" && echo "PREFIX=$(CROSS_COMPILE_HOST)") @@ -133,7 +134,7 @@ binary-arch: # dh_installcron # dh_installinfo # dh_installman - # dh_link + dh_link $(PKGDIR)/$(EXENAME) $(LINKDIR)/$(EXENAME) dh_compress dh_fixperms # dh_perl From 45aba493c79d4df9e33ff537a77255d44389025b Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Mon, 17 Dec 2018 20:43:59 +0100 Subject: [PATCH 08/19] 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 b7ef6044..660a57e4 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 23835136..906906e5 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 1da546d2..1c37b3b7 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 a8f48051..0bf4fcd8 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 f61ecfbd..ba2b0270 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 41bc55ac..d8b8d24e 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 252960ed..324babdb 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 7e544ae9..697552ec 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 8fedbbbe..7647d72f 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 43883248..651418e6 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 430b7fd4..6bec258a 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); From ff957baae377fb0760c0dad893e68f08371dfec8 Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Mon, 17 Dec 2018 21:31:31 +0100 Subject: [PATCH 09/19] Don't overlap ringslinger HUD --- src/hu_stuff.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 0bf4fcd8..b9311601 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1325,14 +1325,13 @@ static void HU_drawMiniChat(void) y = chaty - charheight*(msglines+1); - if (splitscreen) + /*if (splitscreen) { y -= BASEVIDHEIGHT/2; if (splitscreen > 1) y += 16; - } - /*else - y -= (cv_kartspeedometer.value ? 16 : 0);*/ + }*/ + y -= (G_RingSlingerGametype() ? 16 : 0); dx = 0; dy = 0; @@ -1462,9 +1461,8 @@ static void HU_drawChatLog(INT32 offset) y -= BASEVIDHEIGHT/2; if (splitscreen > 1) y += 16; - } - else - y -= (cv_kartspeedometer.value ? 16 : 0);*/ + }*/ + y -= (G_RingSlingerGametype() ? 16 : 0); // Unused SRB2KART splitscreen stuff. I'll leave it here in case it ever happens in Vanilla? (x2) @@ -1574,9 +1572,8 @@ static void HU_DrawChat(void) y += 16; boxw = max(64, boxw/2); } - } - else - y -= (cv_kartspeedometer.value ? 16 : 0);*/ + }*/ + y -= (G_RingSlingerGametype() ? 16 : 0); // More unused SRB2KART stuff. @@ -1669,9 +1666,8 @@ static void HU_DrawChat(void) p_dispy -= BASEVIDHEIGHT/2; if (splitscreen > 1) p_dispy += 16; - } - else - p_dispy -= (cv_kartspeedometer.value ? 16 : 0);*/ + }*/ + y -= (G_RingSlingerGametype() ? 16 : 0); // more kart leftovers. From 2fdf27c5077a20bf12359188a5fdf9c1761041df Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Mon, 17 Dec 2018 21:39:49 +0100 Subject: [PATCH 10/19] make sure to change p_dispy and not y for /pm list. Also make MPC happy. --- src/hu_stuff.c | 2 +- src/v_video.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index b9311601..27144e50 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1667,7 +1667,7 @@ static void HU_DrawChat(void) if (splitscreen > 1) p_dispy += 16; }*/ - y -= (G_RingSlingerGametype() ? 16 : 0); + p_dispy -= (G_RingSlingerGametype() ? 16 : 0); // more kart leftovers. diff --git a/src/v_video.c b/src/v_video.c index 651418e6..796e6465 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -880,7 +880,7 @@ static UINT32 V_GetHWConsBackColor(void) void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) { UINT8 *dest; - INT32 u, v; + INT32 u, v; UINT32 alphalevel = 0; if (rendermode == render_none) From 82601e881b8296a0cb4ed6ae44c99976a5c30fda Mon Sep 17 00:00:00 2001 From: MPC Date: Mon, 17 Dec 2018 17:57:53 -0300 Subject: [PATCH 11/19] fix my fucking code --- src/v_video.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/src/v_video.c b/src/v_video.c index 796e6465..2a5eca9d 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -881,6 +881,7 @@ void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) { UINT8 *dest; INT32 u, v; + UINT8 *fadetable; UINT32 alphalevel = 0; if (rendermode == render_none) @@ -965,23 +966,20 @@ void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) c &= 255; - if (!alphalevel) { - for (v = 0; v < h; v++, dest += vid.width) { - for (u = 0; u < w; u++) { - dest[u] = consolebgmap[dest[u]]; - } - } - } else { // mpc 12-04-2018 - const UINT8 *fadetable = ((UINT8 *)transtables + ((alphalevel-1)<y) ? y : x - w = clip(w,vid.width); - h = clip(h,vid.height); - for (v = 0; v < h; v++, dest += vid.width) { - for (u = 0; u < w; u++) { - dest[u] = fadetable[consolebgmap[dest[u]]]; - } - } - } + // Jimita (12-04-2018) + w = min(w, vid.width); + h = min(h, vid.height); + if (alphalevel) // Use fadetable + fadetable = ((UINT8 *)transtables + ((alphalevel-1)< Date: Mon, 17 Dec 2018 18:09:29 -0300 Subject: [PATCH 12/19] fix the fucking warning --- src/v_video.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/v_video.c b/src/v_video.c index 2a5eca9d..cfe7d036 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -969,9 +969,7 @@ void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) // Jimita (12-04-2018) w = min(w, vid.width); h = min(h, vid.height); - if (alphalevel) // Use fadetable - fadetable = ((UINT8 *)transtables + ((alphalevel-1)< Date: Mon, 17 Dec 2018 18:55:21 -0500 Subject: [PATCH 13/19] Fix compile errors --- src/hu_stuff.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 27144e50..d99fe07a 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -73,7 +73,7 @@ patch_t *cred_font[CRED_FONTSIZE]; static player_t *plr; boolean chat_on; // entering a chat message? static char w_chat[HU_MAXMSGLEN]; -static INT32 c_input = 0; // let's try to make the chat input less shitty. +static size_t c_input = 0; // let's try to make the chat input less shitty. static boolean headsupactive = false; boolean hu_showscores; // draw rankings static char hu_tick; @@ -328,7 +328,7 @@ static UINT32 chat_nummsg_min = 0; static UINT32 chat_scroll = 0; static tic_t chat_scrolltime = 0; -static INT32 chat_maxscroll = 0; // how far can we scroll? +static UINT32 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. @@ -346,7 +346,7 @@ static INT16 addy = 0; // use this to make the messages scroll smoothly when one static void HU_removeChatText_Mini(void) { // MPC: Don't create new arrays, just iterate through an existing one - int i; + size_t i; for(i=0;i=c_input);m--) { if (s[m]) @@ -1199,7 +1199,7 @@ boolean HU_Responder(event_t *ev) // 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. // this one is simplified for the chat drawer. -char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string) +static char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string) { int c; size_t chw, i, lastusablespace = 0; @@ -2611,7 +2611,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline // // HU_Draw32TabRankings // -void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer) +static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer) { INT32 i; const UINT8 *colormap; From 7a92c9d3d04b4dee842dda8b9b149ddda75b7812 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Mon, 17 Dec 2018 19:02:22 -0500 Subject: [PATCH 14/19] Mixed D&C fixes; replace a couple int's with INT32 --- src/hu_stuff.c | 27 +++++++++++++++++---------- src/lua_baselib.c | 12 ++++++++---- src/m_menu.c | 15 ++++++++------- 3 files changed, 33 insertions(+), 21 deletions(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index d99fe07a..22e3aa3d 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -727,9 +727,10 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) } else { + const UINT8 color = players[playernum].skincolor; cstart = "\x83"; - const UINT8 color = players[playernum].skincolor; + if (color <= SKINCOLOR_SILVER) cstart = "\x80"; // White else if (color <= SKINCOLOR_BLACK) @@ -856,9 +857,11 @@ static inline boolean HU_keyInChatString(char *s, char ch) } else if (ch == KEY_BACKSPACE) { + size_t i = c_input; + if (c_input <= 0) return false; - size_t i = c_input; + if (!s[i-1]) return false; @@ -910,14 +913,17 @@ static void HU_queueChatChar(char c) if (c == KEY_ENTER) { char buf[2+256]; - size_t ci = 2; char *msg = &buf[2]; + size_t i = 0; + size_t ci = 2; + INT32 target = 0; + do { c = w_chat[-2+ci++]; if (!c || (c >= ' ' && !(c & 0x80))) // copy printable characters and terminating '\0' only. buf[ci-1]=c; } while (c); - size_t i = 0; + for (;(i 4 && strnicmp(msg, "/pm", 3) == 0) // used /pm { + INT32 spc = 1; // used if nodenum[1] is a space. + char *nodenum = (char*) malloc(3); + const char *newmsg = msg+5+spc; + // what we're gonna do now is check if the node exists // with that logic, characters 4 and 5 are our numbers: @@ -944,8 +952,6 @@ static void HU_queueChatChar(char c) 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'))) @@ -981,8 +987,8 @@ static void HU_queueChatChar(char c) 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. @@ -2158,6 +2164,8 @@ void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext) UINT8 barcolor = 128; // color we use for the bars (green, yellow or red) SINT8 i = 0; SINT8 yoffset = 6; + INT32 dx = x+1 - (V_SmallStringWidth(va("%dms", ping), V_ALLOWLOWERCASE)/2); + if (ping < 128) { numbars = 3; @@ -2169,7 +2177,6 @@ void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext) 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)); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index d8b8d24e..6b1456e9 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -96,9 +96,11 @@ 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 + int len = strlen(str); + 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."); @@ -110,7 +112,11 @@ static int lib_chatprint(lua_State *L) static int lib_chatprintf(lua_State *L) { int n = lua_gettop(L); /* number of arguments */ + const char *str = luaL_checkstring(L, 2); // retrieve string + boolean sound = luaL_checkboolean(L, 3); // sound? + int len = strlen(str); player_t *plr; + if (n < 2) return luaL_error(L, "chatprintf requires at least two arguments: player and text."); @@ -120,11 +126,9 @@ static int lib_chatprintf(lua_State *L) 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."); diff --git a/src/m_menu.c b/src/m_menu.c index 7647d72f..380ba266 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1315,13 +1315,14 @@ static menuitem_t OP_GameOptionsMenu[] = static menuitem_t OP_ChatOptionsMenu[] = { - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Chat Box Width", &cv_chatwidth, 10}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Chat Box Height", &cv_chatheight, 20}, - {IT_STRING | IT_CVAR, NULL, "Message Fadeout Time", &cv_chattime, 30}, - {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, "Chat Mode", &cv_consolechat, 70}, + {IT_STRING | IT_CVAR, NULL, "Chat Mode", &cv_consolechat, 10}, + + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Chat Box Width", &cv_chatwidth, 30}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Chat Box Height", &cv_chatheight, 40}, + {IT_STRING | IT_CVAR, NULL, "Message Fadeout Time", &cv_chattime, 50}, + {IT_STRING | IT_CVAR, NULL, "Chat Notifications", &cv_chatnotifications, 60}, + {IT_STRING | IT_CVAR, NULL, "Spam Protection", &cv_chatspamprotection, 70}, + {IT_STRING | IT_CVAR, NULL, "Chat background tint", &cv_chatbacktint, 80}, }; static menuitem_t OP_ServerOptionsMenu[] = From bf21b7c483a207412577e0786c98698cfcefd4b0 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Mon, 17 Dec 2018 19:03:09 -0500 Subject: [PATCH 15/19] Mixed D&C fixes for HU_DrawTeamTabRankings --- src/hu_stuff.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 22e3aa3d..b924cf78 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2407,6 +2407,8 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) INT32 i,x,y; INT32 redplayers = 0, blueplayers = 0; boolean smol = false; + const UINT8 *colormap; + char name[MAXPLAYERNAME+1]; // before we draw, we must count how many players are in each team. It makes an additional loop, but we need to know if we have to draw a big or a small ranking. for (i = 0; i < MAXPLAYERS; i++) @@ -2446,9 +2448,6 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) 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++) From 876ddd48f11a4e92c8d32b551819cf815ebecdb4 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Mon, 17 Dec 2018 19:09:05 -0500 Subject: [PATCH 16/19] Change int to INT32 --- src/hu_stuff.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index b924cf78..6d5fbfca 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -456,8 +456,9 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags) // 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); + INT32 spc = 1; // used if nodenum[1] is a space. + 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'))) @@ -595,7 +596,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) char *msg; boolean action = false; char *ptr; - int spam_eatmsg = 0; + INT32 spam_eatmsg = 0; CONS_Debug(DBG_NETPLAY,"Received SAY cmd from Player %d (%s)\n", playernum+1, player_names[playernum]); @@ -1207,7 +1208,7 @@ boolean HU_Responder(event_t *ev) // this one is simplified for the chat drawer. static char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string) { - int c; + INT32 c; size_t chw, i, lastusablespace = 0; size_t slen; char *newstring = Z_StrDup(string); @@ -1634,8 +1635,8 @@ static void HU_DrawChat(void) boolean skippedline = false; if (c_input == (i+1)) { - 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); + INT32 cursorx = (c+charwidth < boxw-charwidth) ? (chatx + 2 + c+charwidth) : (chatx+1); // we may have to go down. + INT32 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); @@ -1644,7 +1645,6 @@ static void HU_DrawChat(void) typelines += 1; skippedline = true; } - } //Hurdler: isn't it better like that? @@ -1789,8 +1789,8 @@ static void HU_DrawChat_Old(void) 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); + INT32 cursorx = (HU_INPUTX+c+charwidth < vid.width) ? (HU_INPUTX + c + charwidth) : (HU_INPUTX); // we may have to go down. + INT32 cursory = (cursorx != HU_INPUTX) ? (y) : (y+charheight); V_DrawCharacter(cursorx, cursory+2*con_scalefactor, '_' |cv_constextsize.value | V_NOSCALESTART|t, !cv_allcaps.value); } From 1fcf607b41ef3578efc4fb32e30f0cde7fb7dd55 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Mon, 17 Dec 2018 21:31:00 -0500 Subject: [PATCH 17/19] Fix strncpy nodenum length overflow --- src/hu_stuff.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 6d5fbfca..5941c68d 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -459,7 +459,7 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags) char *nodenum = (char*) malloc(3); INT32 spc = 1; // used if nodenum[1] is a space. - strncpy(nodenum, msg+3, 5); + strncpy(nodenum, msg+3, 3); // check for undesirable characters in our "number" if (((nodenum[0] < '0') || (nodenum[0] > '9')) || ((nodenum[1] < '0') || (nodenum[1] > '9'))) { @@ -953,7 +953,7 @@ static void HU_queueChatChar(char c) return; } - strncpy(nodenum, msg+3, 5); + strncpy(nodenum, msg+3, 3); // check for undesirable characters in our "number" if (((nodenum[0] < '0') || (nodenum[0] > '9')) || ((nodenum[1] < '0') || (nodenum[1] > '9'))) { @@ -1692,7 +1692,7 @@ static void HU_DrawChat(void) nodenum = (char*) malloc(3); - strncpy(nodenum, w_chat+3, 4); + strncpy(nodenum, w_chat+3, 3); n = atoi((const char*) nodenum); // turn that into a number // special cases: From a31b85e1244d836ace7d2287333e2ebba262dc8d Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Wed, 19 Dec 2018 16:44:57 +0100 Subject: [PATCH 18/19] Some messages relevant to discussions now go in the chat. --- src/d_clisrv.c | 30 ++++++++++++++++++------------ src/d_netcmd.c | 4 ++-- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index cd8367af..8477aac3 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2779,17 +2779,17 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) switch (msg) { case KICK_MSG_GO_AWAY: - CONS_Printf(M_GetText("has been kicked (Go away)\n")); + HU_AddChatText(va("\x82*%s has been kicked (Go away)", player_names[pnum]), false); kickreason = KR_KICK; break; #ifdef NEWPING case KICK_MSG_PING_HIGH: - CONS_Printf(M_GetText("left the game (Broke ping limit)\n")); + HU_AddChatText(va("\x82*%s left the game (Broke ping limit)", player_names[pnum]), false); kickreason = KR_PINGLIMIT; break; #endif case KICK_MSG_CON_FAIL: - CONS_Printf(M_GetText("left the game (Synch failure)\n")); + HU_AddChatText(va("\x82*%s left the game (Synch Failure)", player_names[pnum]), false); kickreason = KR_SYNCH; if (M_CheckParm("-consisdump")) // Helps debugging some problems @@ -2826,26 +2826,26 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) } break; case KICK_MSG_TIMEOUT: - CONS_Printf(M_GetText("left the game (Connection timeout)\n")); + HU_AddChatText(va("\x82*%s left the game (Connection timeout)", player_names[pnum]), false); kickreason = KR_TIMEOUT; break; case KICK_MSG_PLAYER_QUIT: if (netgame) // not splitscreen/bots - CONS_Printf(M_GetText("left the game\n")); + HU_AddChatText(va("\x82*%s left the game", player_names[pnum]), false); kickreason = KR_LEAVE; break; case KICK_MSG_BANNED: - CONS_Printf(M_GetText("has been banned (Don't come back)\n")); + HU_AddChatText(va("\x82*%s has been banned (Don't come back)", player_names[pnum]), false); kickreason = KR_BAN; break; case KICK_MSG_CUSTOM_KICK: READSTRINGN(*p, reason, MAX_REASONLENGTH+1); - CONS_Printf(M_GetText("has been kicked (%s)\n"), reason); + HU_AddChatText(va("\x82*%s has been kicked (%s)", player_names[pnum], reason), false); kickreason = KR_KICK; break; case KICK_MSG_CUSTOM_BAN: READSTRINGN(*p, reason, MAX_REASONLENGTH+1); - CONS_Printf(M_GetText("has been banned (%s)\n"), reason); + HU_AddChatText(va("\x82*%s has been banned (%s)", player_names[pnum], reason), false); kickreason = KR_BAN; break; } @@ -3143,11 +3143,17 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) D_SendPlayerConfig(); addedtogame = true; } - else if (server && netgame && cv_showjoinaddress.value) + + if (netgame) { - const char *address; - if (I_GetNodeAddress && (address = I_GetNodeAddress(node)) != NULL) - CONS_Printf(M_GetText("Player Address is %s\n"), address); + if (server && cv_showjoinaddress.value) + { + const char *address; + if (I_GetNodeAddress && (address = I_GetNodeAddress(node)) != NULL) + HU_AddChatText(va("\x82*Player %d has joined the game (node %d) (%s)", newplayernum+1, node, address), false); // merge join notification + IP to avoid clogging console/chat. + } + else + HU_AddChatText(va("\x82*Player %d has joined the game (node %d)", newplayernum+1, node), false); // if you don't wanna see the join address. } if (server && multiplayer && motd[0] != '\0') diff --git a/src/d_netcmd.c b/src/d_netcmd.c index a371be32..3ed50e0b 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -995,8 +995,8 @@ static void SetPlayerName(INT32 playernum, char *newname) if (strcasecmp(newname, player_names[playernum]) != 0) { if (netgame) - CONS_Printf(M_GetText("%s renamed to %s\n"), - player_names[playernum], newname); + HU_AddChatText(va("\x82*%s renamed to %s", player_names[playernum], newname), false); + strcpy(player_names[playernum], newname); } } From 06ff171e19f88db55f793e8acfb77f38d9369e3f Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 21 Dec 2018 09:38:28 -0500 Subject: [PATCH 19/19] Adjust vid.width floating point comparson for CHAT --- src/hardware/hw_draw.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 8aa92752..d3d237c4 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -845,14 +845,14 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32 fw *= dupx; fh *= dupy; - if (vid.width != BASEVIDWIDTH * vid.dupx) + if (fabsf((float)vid.width - ((float)BASEVIDWIDTH * dupx)) > 1.0E-36f) { if (options & V_SNAPTORIGHT) fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)); else if (!(options & V_SNAPTOLEFT)) fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2; } - if (vid.height != BASEVIDHEIGHT * dupy) + if (fabsf((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) > 1.0E-36f) { // same thing here if (options & V_SNAPTOBOTTOM) @@ -900,7 +900,7 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32 v[2].sow = v[1].sow = 1.0f; v[0].tow = v[1].tow = 0.0f; v[2].tow = v[3].tow = 1.0f; - + Surf.FlatColor.rgba = UINT2RGBA(color); Surf.FlatColor.s.alpha = 0x80;