From 640bf2a6d4f878a0262bfa28e77d5b003311d834 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sun, 6 Nov 2016 17:07:44 -0500 Subject: [PATCH 1/8] - Fixed: SBarInfo didn't support animated images in some places. --- src/g_shared/sbarinfo_commands.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/g_shared/sbarinfo_commands.cpp b/src/g_shared/sbarinfo_commands.cpp index d105ab818..b3aecb0b5 100644 --- a/src/g_shared/sbarinfo_commands.cpp +++ b/src/g_shared/sbarinfo_commands.cpp @@ -241,7 +241,7 @@ class CommandDrawImage : public SBarInfoCommandFlowControl applyscale = false; } if(type == PLAYERICON) - texture = TexMan[statusBar->CPlayer->mo->ScoreIcon]; + texture = TexMan(statusBar->CPlayer->mo->ScoreIcon); else if(type == AMMO1) { AAmmo *ammo = statusBar->ammo1; @@ -270,7 +270,7 @@ class CommandDrawImage : public SBarInfoCommandFlowControl { AInventory *item = statusBar->CPlayer->mo->FindInventory(); if (item != NULL) - texture = TexMan[item->Icon]; + texture = TexMan(item->Icon); } else if(type == HEXENARMOR_ARMOR || type == HEXENARMOR_SHIELD || type == HEXENARMOR_HELM || type == HEXENARMOR_AMULET) { @@ -290,7 +290,7 @@ class CommandDrawImage : public SBarInfoCommandFlowControl } } else if(type == INVENTORYICON) - texture = TexMan[sprite]; + texture = TexMan(sprite); else if(type == SELECTEDINVENTORYICON && statusBar->CPlayer->mo->InvSel != NULL) texture = TexMan(statusBar->CPlayer->mo->InvSel->Icon); else if(image >= 0) @@ -312,7 +312,7 @@ class CommandDrawImage : public SBarInfoCommandFlowControl spawnScaleY = item->Scale.Y; } - texture = TexMan[icon]; + texture = TexMan(icon); } enum ImageType @@ -2436,22 +2436,22 @@ class CommandDrawKeyBar : public SBarInfoCommand { if(!vertical) { - statusBar->DrawGraphic(TexMan[item->Icon], x+slotOffset, y+rowOffset, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets()); - rowWidth = rowIconSize == -1 ? TexMan[item->Icon]->GetScaledHeight()+2 : rowIconSize; + statusBar->DrawGraphic(TexMan(item->Icon), x+slotOffset, y+rowOffset, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets()); + rowWidth = rowIconSize == -1 ? TexMan(item->Icon)->GetScaledHeight()+2 : rowIconSize; } else { - statusBar->DrawGraphic(TexMan[item->Icon], x+rowOffset, y+slotOffset, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets()); - rowWidth = rowIconSize == -1 ? TexMan[item->Icon]->GetScaledWidth()+2 : rowIconSize; + statusBar->DrawGraphic(TexMan(item->Icon), x+rowOffset, y+slotOffset, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets()); + rowWidth = rowIconSize == -1 ? TexMan(item->Icon)->GetScaledWidth()+2 : rowIconSize; } // If cmd.special is -1 then the slot size is auto detected if(iconSize == -1) { if(!vertical) - slotOffset += (reverse ? -1 : 1) * (TexMan[item->Icon]->GetScaledWidth() + 2); + slotOffset += (reverse ? -1 : 1) * (TexMan(item->Icon)->GetScaledWidth() + 2); else - slotOffset += (reverse ? -1 : 1) * (TexMan[item->Icon]->GetScaledHeight() + 2); + slotOffset += (reverse ? -1 : 1) * (TexMan(item->Icon)->GetScaledHeight() + 2); } else slotOffset += (reverse ? -iconSize : iconSize); From fd31c8474589464cf2c51da97609373d6c86deb6 Mon Sep 17 00:00:00 2001 From: nashmuhandes Date: Fri, 11 Nov 2016 17:18:39 +0800 Subject: [PATCH 2/8] Added a slider to control the intensity of underwater screen blending. --- src/g_shared/shared_sbar.cpp | 6 +++++- wadsrc/static/language.enu | 1 + wadsrc/static/menudef.txt | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp index a3bb76b7f..5e76b422f 100644 --- a/src/g_shared/shared_sbar.cpp +++ b/src/g_shared/shared_sbar.cpp @@ -119,6 +119,7 @@ CUSTOM_CVAR(Int, am_showmaplabel, 2, CVAR_ARCHIVE) } CVAR (Bool, idmypos, false, 0); +CVAR(Float, underwater_fade_scalar, 1.0f, CVAR_ARCHIVE) // [Nash] user-settable underwater blend intensity //--------------------------------------------------------------------------- // @@ -1544,7 +1545,10 @@ void DBaseStatusBar::DrawPowerups () void DBaseStatusBar::BlendView (float blend[4]) { - V_AddBlend (BaseBlendR / 255.f, BaseBlendG / 255.f, BaseBlendB / 255.f, BaseBlendA, blend); + // [Nash] Allow user to set blend intensity + float cnt = (BaseBlendA * underwater_fade_scalar); + + V_AddBlend (BaseBlendR / 255.f, BaseBlendG / 255.f, BaseBlendB / 255.f, cnt, blend); V_AddPlayerBlend(CPlayer, blend, 1.0f, 228); if (screen->Accel2D || (CPlayer->camera != NULL && menuactive == MENU_Off && ConsoleState == c_up)) diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index 01eb692b8..28db40e64 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -1784,6 +1784,7 @@ DSPLYMNU_WIPETYPE = "Screen wipe style"; DSPLYMNU_SHOWENDOOM = "Show ENDOOM screen"; DSPLYMNU_BLOODFADE = "Blood Flash Intensity"; DSPLYMNU_PICKUPFADE = "Pickup Flash Intensity"; +DSPLYMNU_WATERFADE = "Underwater Blend Intensity"; DSPLYMNU_PALLETEHACK = "DirectDraw palette hack"; // Not used DSPLYMNU_ATTACHEDSURFACES = "Use attached surfaces"; // Not used DSPLYMNU_SKYMODE = "Sky render mode"; diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index dac933af8..30cad4dd2 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -669,6 +669,7 @@ OptionMenu "VideoOptions" Option "$DSPLYMNU_CAPFPS", "cl_capfps", "OffOn" Slider "$DSPLYMNU_BLOODFADE", "blood_fade_scalar", 0.0, 1.0, 0.05, 2 Slider "$DSPLYMNU_PICKUPFADE", "pickup_fade_scalar", 0.0, 1.0, 0.05, 2 + Slider "$DSPLYMNU_WATERFADE", "underwater_fade_scalar", 0.0, 1.0, 0.05, 2 Option "$DSPLYMNU_COLUMNMETHOD", "r_columnmethod", "ColumnMethods" StaticText " " From 3926ca13b0b32d3f5936241005e51d60041d4967 Mon Sep 17 00:00:00 2001 From: Marisa Heit Date: Fri, 11 Nov 2016 22:31:49 -0600 Subject: [PATCH 3/8] Fix console input not scrolling when you hit the side of the screen - Also changed the console input buffer into a struct instead of a frankenstein buffer. --- src/c_console.cpp | 529 +++++++++++++++++++++++----------------------- src/v_video.cpp | 2 - src/zstring.cpp | 97 ++++++--- src/zstring.h | 1 + 4 files changed, 340 insertions(+), 289 deletions(-) diff --git a/src/c_console.cpp b/src/c_console.cpp index 2d164c478..2be93a239 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -100,7 +100,7 @@ extern bool advancedemo; extern FBaseCVar *CVars; extern FConsoleCommand *Commands[FConsoleCommand::HASH_SIZE]; -int ConCols, PhysRows; +unsigned ConCols, PhysRows; int ConWidth; bool vidactive = false; bool cursoron = false; @@ -112,7 +112,6 @@ constate_e ConsoleState = c_up; static int TopLine, InsertLine; static void ClearConsole (); -static void C_PasteText(FString clip, BYTE *buffer, int len); struct GameAtExit { @@ -139,27 +138,9 @@ static bool ConsoleDrawing; static char *work = NULL; static int worklen = 0; - -struct History -{ - struct History *Older; - struct History *Newer; - char String[1]; -}; - -// CmdLine[0] = # of chars on command line -// CmdLine[1] = cursor position -// CmdLine[2+] = command line (max 255 chars + NULL) -// CmdLine[259]= offset from beginning of cmdline to display -static BYTE CmdLine[260]; - -#define MAXHISTSIZE 50 -static struct History *HistHead = NULL, *HistTail = NULL, *HistPos = NULL; -static int HistSize; - -CVAR (Float, con_notifytime, 3.f, CVAR_ARCHIVE) -CVAR (Bool, con_centernotify, false, CVAR_ARCHIVE) -CUSTOM_CVAR (Int, con_scaletext, 1, CVAR_ARCHIVE) // Scale notify text at high resolutions? +CVAR(Float, con_notifytime, 3.f, CVAR_ARCHIVE) +CVAR(Bool, con_centernotify, false, CVAR_ARCHIVE) +CUSTOM_CVAR(Int, con_scaletext, 1, CVAR_ARCHIVE) // Scale notify text at high resolutions? { if (self < 0) self = 0; if (self > 3) self = 3; @@ -172,10 +153,16 @@ CUSTOM_CVAR(Int, con_scale, 0, CVAR_ARCHIVE) int active_con_scale() { - if (con_scale == 0) - return uiscale; - else - return con_scale; + int scale = con_scale; + if (scale == 0) + { + scale = uiscale; + if (scale == 0) + { + scale = CleanXfac; + } + } + return scale; } int active_con_scaletext() @@ -197,7 +184,195 @@ CUSTOM_CVAR(Float, con_alpha, 0.75f, CVAR_ARCHIVE) } // Command to run when Ctrl-D is pressed at start of line -CVAR (String, con_ctrl_d, "", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +CVAR(String, con_ctrl_d, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG) + + +struct History +{ + struct History *Older; + struct History *Newer; + FString String; +}; + +struct FCommandBuffer +{ + FString Text; // The actual command line text + unsigned CursorPos; + unsigned StartPos; // First character to display + + FCommandBuffer() + { + CursorPos = StartPos = 0; + } + + FCommandBuffer(const FCommandBuffer &o) + { + Text = o.Text; + CursorPos = o.CursorPos; + StartPos = o.StartPos; + } + + void Draw(int x, int y, int scale, bool cursor) + { + if (scale == 1) + { + screen->DrawChar(ConFont, CR_ORANGE, x, y, '\x1c', TAG_DONE); + screen->DrawText(ConFont, CR_ORANGE, x + ConFont->GetCharWidth(0x1c), y, + &Text[StartPos], TAG_DONE); + + if (cursor) + { + screen->DrawChar(ConFont, CR_YELLOW, + x + ConFont->GetCharWidth(0x1c) + (CursorPos - StartPos) * ConFont->GetCharWidth(0xb), + y, '\xb', TAG_DONE); + } + } + else + { + screen->DrawChar(ConFont, CR_ORANGE, x, y, '\x1c', + DTA_VirtualWidth, screen->GetWidth() / scale, + DTA_VirtualHeight, screen->GetHeight() / scale, + DTA_KeepRatio, true, TAG_DONE); + + screen->DrawText(ConFont, CR_ORANGE, x + ConFont->GetCharWidth(0x1c), y, + &Text[StartPos], + DTA_VirtualWidth, screen->GetWidth() / scale, + DTA_VirtualHeight, screen->GetHeight() / scale, + DTA_KeepRatio, true, TAG_DONE); + + if (cursor) + { + screen->DrawChar(ConFont, CR_YELLOW, + x + ConFont->GetCharWidth(0x1c) + (CursorPos - StartPos) * ConFont->GetCharWidth(0xb), + y, '\xb', + DTA_VirtualWidth, screen->GetWidth() / scale, + DTA_VirtualHeight, screen->GetHeight() / scale, + DTA_KeepRatio, true, TAG_DONE); + } + } + } + + void MakeStartPosGood() + { + int n = StartPos; + unsigned cols = ConCols / active_con_scale(); + + if (StartPos >= Text.Len()) + { // Start of visible line is beyond end of line + n = CursorPos - cols + 2; + } + if ((CursorPos - StartPos) >= cols - 2) + { // The cursor is beyond the visible part of the line + n = CursorPos - cols + 2; + } + if (StartPos > CursorPos) + { // The cursor is in front of the visible part of the line + n = CursorPos; + } + StartPos = MAX(0, n); + } + + void CursorStart() + { + CursorPos = 0; + StartPos = 0; + } + + void CursorEnd() + { + CursorPos = Text.Len(); + StartPos = 0; + MakeStartPosGood(); + } + + void CursorLeft() + { + if (CursorPos > 0) + { + CursorPos--; + MakeStartPosGood(); + } + } + + void CursorRight() + { + if (CursorPos < Text.Len()) + { + CursorPos++; + MakeStartPosGood(); + } + } + + void DeleteLeft() + { + if (CursorPos > 0) + { + Text.Remove(CursorPos - 1, 1); + CursorPos--; + MakeStartPosGood(); + } + } + + void DeleteRight() + { + if (CursorPos < Text.Len()) + { + Text.Remove(CursorPos, 1); + MakeStartPosGood(); + } + } + + void AddChar(int character) + { + ///FIXME: Not Unicode-aware + if (CursorPos == Text.Len()) + { + Text += char(character); + } + else + { + char foo = char(character); + Text.Insert(CursorPos, &foo, 1); + } + CursorPos++; + MakeStartPosGood(); + } + + void AddString(FString clip) + { + if (clip.IsNotEmpty()) + { + // Only paste the first line. + long brk = clip.IndexOfAny("\r\n\b"); + if (brk >= 0) + { + clip.Truncate(brk); + } + if (Text.IsEmpty()) + { + Text = clip; + } + else + { + Text.Insert(CursorPos, clip); + } + CursorPos += clip.Len(); + MakeStartPosGood(); + } + } + + void SetString(FString str) + { + Text = str; + CursorPos = Text.Len(); + MakeStartPosGood(); + } +}; +static FCommandBuffer CmdLine; + +#define MAXHISTSIZE 50 +static struct History *HistHead = NULL, *HistTail = NULL, *HistPos = NULL; +static int HistSize; #define NUMNOTIFIES 4 #define NOTIFYFADETIME 6 @@ -860,8 +1035,6 @@ void C_DrawConsole (bool hw2d) int lines, left, offset; int textScale = active_con_scale(); - if (textScale == 0) - textScale = CleanXfac; left = LEFTMARGIN; lines = (ConBottom/textScale-ConFont->GetHeight()*2)/ConFont->GetHeight(); @@ -1037,44 +1210,8 @@ void C_DrawConsole (bool hw2d) { // Make a copy of the command line, in case an input event is handled // while we draw the console and it changes. - CmdLine[2+CmdLine[0]] = 0; - FString command((char *)&CmdLine[2+CmdLine[259]]); - int cursorpos = CmdLine[1] - CmdLine[259]; - - if (textScale == 1) - { - screen->DrawChar(ConFont, CR_ORANGE, left, bottomline, '\x1c', TAG_DONE); - screen->DrawText(ConFont, CR_ORANGE, left + ConFont->GetCharWidth(0x1c), bottomline, - command, TAG_DONE); - - if (cursoron) - { - screen->DrawChar(ConFont, CR_YELLOW, left + ConFont->GetCharWidth(0x1c) + cursorpos * ConFont->GetCharWidth(0xb), - bottomline, '\xb', TAG_DONE); - } - } - else - { - screen->DrawChar(ConFont, CR_ORANGE, left, bottomline, '\x1c', - DTA_VirtualWidth, screen->GetWidth() / textScale, - DTA_VirtualHeight, screen->GetHeight() / textScale, - DTA_KeepRatio, true, TAG_DONE); - - screen->DrawText(ConFont, CR_ORANGE, left + ConFont->GetCharWidth(0x1c), bottomline, - command, - DTA_VirtualWidth, screen->GetWidth() / textScale, - DTA_VirtualHeight, screen->GetHeight() / textScale, - DTA_KeepRatio, true, TAG_DONE); - - if (cursoron) - { - screen->DrawChar(ConFont, CR_YELLOW, left + ConFont->GetCharWidth(0x1c) + cursorpos * ConFont->GetCharWidth(0xb), - bottomline, '\xb', - DTA_VirtualWidth, screen->GetWidth() / textScale, - DTA_VirtualHeight, screen->GetHeight() / textScale, - DTA_KeepRatio, true, TAG_DONE); - } - } + FCommandBuffer command(CmdLine); + command.Draw(left, bottomline, textScale, cursoron); } if (RowAdjust && ConBottom >= ConFont->GetHeight()*7/2) { @@ -1146,35 +1283,8 @@ void C_HideConsole () } } -static void makestartposgood () +static bool C_HandleKey (event_t *ev, FCommandBuffer &buffer) { - int n; - int pos = CmdLine[259]; - int curs = CmdLine[1]; - int len = CmdLine[0]; - - n = pos; - - if (pos >= len) - { // Start of visible line is beyond end of line - n = curs - ConCols + 2; - } - if ((curs - pos) >= ConCols - 2) - { // The cursor is beyond the visible part of the line - n = curs - ConCols + 2; - } - if (pos > curs) - { // The cursor is in front of the visible part of the line - n = curs; - } - if (n < 0) - n = 0; - CmdLine[259] = n; -} - -static bool C_HandleKey (event_t *ev, BYTE *buffer, int len) -{ - int i; int data1 = ev->data1; switch (ev->subtype) @@ -1184,29 +1294,8 @@ static bool C_HandleKey (event_t *ev, BYTE *buffer, int len) case EV_GUI_Char: // Add keypress to command line - if (buffer[0] < len) - { - if (buffer[1] == buffer[0]) - { - buffer[buffer[0] + 2] = BYTE(ev->data1); - } - else - { - char *c, *e; - - e = (char *)&buffer[buffer[0] + 1]; - c = (char *)&buffer[buffer[1] + 2]; - - for (; e >= c; e--) - *(e + 1) = *e; - - *c = char(ev->data1); - } - buffer[0]++; - buffer[1]++; - makestartposgood (); - HistPos = NULL; - } + buffer.AddChar(ev->data1); + HistPos = NULL; TabbedLast = false; TabbedList = false; break; @@ -1289,7 +1378,7 @@ static bool C_HandleKey (event_t *ev, BYTE *buffer, int len) } else { // Move cursor to start of line - buffer[1] = buffer[len+4] = 0; + buffer.CursorStart(); } break; @@ -1300,66 +1389,30 @@ static bool C_HandleKey (event_t *ev, BYTE *buffer, int len) } else { // Move cursor to end of line - buffer[1] = buffer[0]; - makestartposgood (); + buffer.CursorEnd(); } break; case GK_LEFT: // Move cursor left one character - if (buffer[1]) - { - buffer[1]--; - makestartposgood (); - } + buffer.CursorLeft(); break; case GK_RIGHT: // Move cursor right one character - if (buffer[1] < buffer[0]) - { - buffer[1]++; - makestartposgood (); - } + buffer.CursorRight(); break; case '\b': // Erase character to left of cursor - if (buffer[0] && buffer[1]) - { - char *c, *e; - - e = (char *)&buffer[buffer[0] + 2]; - c = (char *)&buffer[buffer[1] + 2]; - - for (; c < e; c++) - *(c - 1) = *c; - - buffer[0]--; - buffer[1]--; - if (buffer[len+4]) - buffer[len+4]--; - makestartposgood (); - } + buffer.DeleteLeft(); TabbedLast = false; TabbedList = false; break; case GK_DEL: // Erase character under cursor - if (buffer[1] < buffer[0]) - { - char *c, *e; - - e = (char *)&buffer[buffer[0] + 2]; - c = (char *)&buffer[buffer[1] + 3]; - - for (; c < e; c++) - *(c - 1) = *c; - - buffer[0]--; - makestartposgood (); - } + buffer.DeleteRight(); TabbedLast = false; TabbedList = false; break; @@ -1377,10 +1430,7 @@ static bool C_HandleKey (event_t *ev, BYTE *buffer, int len) if (HistPos) { - strcpy ((char *)&buffer[2], HistPos->String); - buffer[0] = buffer[1] = (BYTE)strlen ((char *)&buffer[2]); - buffer[len+4] = 0; - makestartposgood(); + buffer.SetString(HistPos->String); } TabbedLast = false; @@ -1392,17 +1442,13 @@ static bool C_HandleKey (event_t *ev, BYTE *buffer, int len) if (HistPos && HistPos->Newer) { HistPos = HistPos->Newer; - - strcpy ((char *)&buffer[2], HistPos->String); - buffer[0] = buffer[1] = (BYTE)strlen ((char *)&buffer[2]); + buffer.SetString(HistPos->String); } else { HistPos = NULL; - buffer[0] = buffer[1] = 0; + buffer.SetString(""); } - buffer[len+4] = 0; - makestartposgood(); TabbedLast = false; TabbedList = false; break; @@ -1410,24 +1456,19 @@ static bool C_HandleKey (event_t *ev, BYTE *buffer, int len) case 'X': if (ev->data3 & GKM_CTRL) { - buffer[1] = buffer[0] = 0; + buffer.SetString(""); TabbedLast = TabbedList = false; } break; case 'D': - if (ev->data3 & GKM_CTRL && buffer[0] == 0) + if (ev->data3 & GKM_CTRL && buffer.Text.Len() == 0) { // Control-D pressed on an empty line - int replen = (int)strlen (con_ctrl_d); - - if (replen == 0) + if (strlen(con_ctrl_d) == 0) + { break; // Replacement is empty, so do nothing - - if (replen > len) - replen = len; - - memcpy (&buffer[2], con_ctrl_d, replen); - buffer[0] = buffer[1] = replen; + } + buffer.SetString(*con_ctrl_d); } else { @@ -1438,16 +1479,16 @@ static bool C_HandleKey (event_t *ev, BYTE *buffer, int len) case '\r': // Execute command line (ENTER) - buffer[2 + buffer[0]] = 0; + buffer.Text.StripLeftRight(); + Printf(127, TEXTCOLOR_WHITE "]%s\n", buffer.Text.GetChars()); + AddCommandString(buffer.Text.LockBuffer()); + buffer.Text.UnlockBuffer(); - for (i = 0; i < buffer[0] && isspace(buffer[2+i]); ++i) - { - } - if (i == buffer[0]) + if (buffer.Text.Len() == 0) { // Command line is empty, so do nothing to the history } - else if (HistHead && stricmp (HistHead->String, (char *)&buffer[2]) == 0) + else if (HistHead && HistHead->String.CompareNoCase(buffer.Text) == 0) { // Command line was the same as the previous one, // so leave the history list alone @@ -1458,9 +1499,8 @@ static bool C_HandleKey (event_t *ev, BYTE *buffer, int len) // or there is nothing in the history list, // so add it to the history list. - History *temp = (History *)M_Malloc (sizeof(struct History) + buffer[0]); - - strcpy (temp->String, (char *)&buffer[2]); + History *temp = new History; + temp->String = buffer.Text; temp->Older = HistHead; if (HistHead) { @@ -1477,7 +1517,7 @@ static bool C_HandleKey (event_t *ev, BYTE *buffer, int len) if (HistSize == MAXHISTSIZE) { HistTail = HistTail->Newer; - M_Free (HistTail->Older); + delete HistTail->Older; HistTail->Older = NULL; } else @@ -1486,9 +1526,7 @@ static bool C_HandleKey (event_t *ev, BYTE *buffer, int len) } } HistPos = NULL; - Printf (127, TEXTCOLOR_WHITE "]%s\n", &buffer[2]); - buffer[0] = buffer[1] = buffer[len+4] = 0; - AddCommandString ((char *)&buffer[2]); + buffer.SetString(""); TabbedLast = false; TabbedList = false; break; @@ -1514,7 +1552,7 @@ static bool C_HandleKey (event_t *ev, BYTE *buffer, int len) } else { - buffer[0] = buffer[1] = buffer[len+4] = 0; + buffer.SetString(""); HistPos = NULL; C_ToggleConsole (); } @@ -1532,15 +1570,15 @@ static bool C_HandleKey (event_t *ev, BYTE *buffer, int len) { if (data1 == 'C') { // copy to clipboard - if (buffer[0] > 0) + if (buffer.Text.IsNotEmpty()) { - buffer[2 + buffer[0]] = 0; - I_PutInClipboard ((char *)&buffer[2]); + I_PutInClipboard(buffer.Text); } } else { // paste from clipboard - C_PasteText(I_GetFromClipboard(false), buffer, len); + buffer.AddString(I_GetFromClipboard(false)); + HistPos = NULL; } break; } @@ -1550,7 +1588,8 @@ static bool C_HandleKey (event_t *ev, BYTE *buffer, int len) #ifdef __unix__ case EV_GUI_MButtonDown: - C_PasteText(I_GetFromClipboard(true), buffer, len); + buffer.AddString(I_GetFromClipboard(true)); + HistPos = NULL; break; #endif } @@ -1560,36 +1599,6 @@ static bool C_HandleKey (event_t *ev, BYTE *buffer, int len) return true; } -static void C_PasteText(FString clip, BYTE *buffer, int len) -{ - if (clip.IsNotEmpty()) - { - // Only paste the first line. - long brk = clip.IndexOfAny("\r\n\b"); - int cliplen = brk >= 0 ? brk : (int)clip.Len(); - - // Make sure there's room for the whole thing. - if (buffer[0] + cliplen > len) - { - cliplen = len - buffer[0]; - } - - if (cliplen > 0) - { - if (buffer[1] < buffer[0]) - { - memmove (&buffer[2 + buffer[1] + cliplen], - &buffer[2 + buffer[1]], buffer[0] - buffer[1]); - } - memcpy (&buffer[2 + buffer[1]], clip, cliplen); - buffer[0] += cliplen; - buffer[1] += cliplen; - makestartposgood (); - HistPos = NULL; - } - } -} - bool C_Responder (event_t *ev) { if (ev->type != EV_GUI_Event || @@ -1600,7 +1609,7 @@ bool C_Responder (event_t *ev) return false; } - return C_HandleKey (ev, CmdLine, 255); + return C_HandleKey(ev, CmdLine); } CCMD (history) @@ -1793,7 +1802,7 @@ static int FindDiffPoint (FName name1, const char *str2) static void C_TabComplete (bool goForward) { - int i; + unsigned i; int diffpoint; if (!TabbedLast) @@ -1801,25 +1810,20 @@ static void C_TabComplete (bool goForward) bool cancomplete; // Skip any spaces at beginning of command line - if (CmdLine[2] == ' ') + for (i = 0; i < CmdLine.Text.Len(); ++i) { - for (i = 0; i < CmdLine[0]; i++) - if (CmdLine[2+i] != ' ') - break; - - TabStart = i + 2; + if (CmdLine.Text[i] != ' ') + break; } - else - { - TabStart = 2; + if (i == CmdLine.Text.Len()) + { // Line was nothing but spaces + return; } + TabStart = i; - if (TabStart == CmdLine[0] + 2) - return; // Line was nothing but spaces + TabSize = CmdLine.Text.Len() - TabStart; - TabSize = CmdLine[0] - TabStart + 2; - - if (!FindTabCommand ((char *)(CmdLine + TabStart), &TabPos, TabSize)) + if (!FindTabCommand(&CmdLine.Text[TabStart], &TabPos, TabSize)) return; // No initial matches // Show a list of possible completions, if more than one. @@ -1842,7 +1846,7 @@ static void C_TabComplete (bool goForward) { // Find the last matching tab, then go one past it. while (++TabPos < (int)TabCommands.Size()) { - if (FindDiffPoint (TabCommands[TabPos].TabName, (char *)(CmdLine + TabStart)) < TabSize) + if (FindDiffPoint(TabCommands[TabPos].TabName, &CmdLine.Text[TabStart]) < TabSize) { break; } @@ -1859,27 +1863,26 @@ static void C_TabComplete (bool goForward) (!goForward && --TabPos < 0)) { TabbedLast = false; - CmdLine[0] = CmdLine[1] = TabSize; + CmdLine.Text.Truncate(TabSize); } else { - diffpoint = FindDiffPoint (TabCommands[TabPos].TabName, (char *)(CmdLine + TabStart)); + diffpoint = FindDiffPoint(TabCommands[TabPos].TabName, &CmdLine.Text[TabStart]); if (diffpoint < TabSize) { // No more matches TabbedLast = false; - CmdLine[0] = CmdLine[1] = TabSize + TabStart - 2; + CmdLine.Text.Truncate(TabSize - TabStart); } else - { - strcpy ((char *)(CmdLine + TabStart), TabCommands[TabPos].TabName.GetChars()); - CmdLine[0] = CmdLine[1] = (BYTE)strlen ((char *)(CmdLine + 2)) + 1; - CmdLine[CmdLine[0] + 1] = ' '; + { + CmdLine.Text.Truncate(TabStart); + CmdLine.Text << TabCommands[TabPos].TabName << ' '; } } - - makestartposgood (); + CmdLine.CursorPos = CmdLine.Text.Len(); + CmdLine.MakeStartPosGood(); } static bool C_TabCompleteList () @@ -1893,7 +1896,7 @@ static bool C_TabCompleteList () for (i = TabPos; i < (int)TabCommands.Size(); ++i) { - if (FindDiffPoint (TabCommands[i].TabName, (char *)(CmdLine + TabStart)) < TabSize) + if (FindDiffPoint (TabCommands[i].TabName, &CmdLine.Text[TabStart]) < TabSize) { break; } @@ -1918,7 +1921,7 @@ static bool C_TabCompleteList () { size_t x = 0; maxwidth += 3; - Printf (TEXTCOLOR_BLUE "Completions for %s:\n", CmdLine+2); + Printf (TEXTCOLOR_BLUE "Completions for %s:\n", CmdLine.Text.GetChars()); for (i = TabPos; nummatches > 0; ++i, --nummatches) { // [Dusk] Print console commands blue, CVars green, aliases red. @@ -1936,7 +1939,7 @@ static bool C_TabCompleteList () Printf ("%s%-*s", colorcode, int(maxwidth), TabCommands[i].TabName.GetChars()); x += maxwidth; - if (x > ConCols - maxwidth) + if (x > ConCols / active_con_scale() - maxwidth) { x = 0; Printf ("\n"); @@ -1950,9 +1953,9 @@ static bool C_TabCompleteList () if (TabSize != commonsize) { TabSize = commonsize; - strncpy ((char *)CmdLine + TabStart, TabCommands[TabPos].TabName.GetChars(), commonsize); - CmdLine[0] = TabStart + commonsize - 2; - CmdLine[1] = CmdLine[0]; + CmdLine.Text.Truncate(TabStart); + CmdLine.Text.AppendCStrPart(TabCommands[TabPos].TabName.GetChars(), commonsize); + CmdLine.CursorPos = CmdLine.Text.Len(); } return false; } diff --git a/src/v_video.cpp b/src/v_video.cpp index b1f1ced9c..37cfdd480 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -877,8 +877,6 @@ void DFrameBuffer::DrawRateStuff () int rate_x; int textScale = active_con_scale(); - if (textScale == 0) - textScale = CleanXfac; chars = mysnprintf (fpsbuff, countof(fpsbuff), "%2u ms (%3u fps)", howlong, LastCount); rate_x = Width / textScale - ConFont->StringWidth(&fpsbuff[0]); diff --git a/src/zstring.cpp b/src/zstring.cpp index f4a3a1fbb..63fdf6428 100644 --- a/src/zstring.cpp +++ b/src/zstring.cpp @@ -343,28 +343,74 @@ FString &FString::operator += (char tail) FString &FString::AppendCStrPart (const char *tail, size_t tailLen) { - size_t len1 = Len(); - ReallocBuffer (len1 + tailLen); - StrCopy (Chars + len1, tail, tailLen); + if (tailLen > 0) + { + size_t len1 = Len(); + ReallocBuffer(len1 + tailLen); + StrCopy(Chars + len1, tail, tailLen); + } return *this; } FString &FString::CopyCStrPart(const char *tail, size_t tailLen) { - ReallocBuffer(tailLen); - StrCopy(Chars, tail, tailLen); + if (tailLen > 0) + { + ReallocBuffer(tailLen); + StrCopy(Chars, tail, tailLen); + } + else + { + Data()->Release(); + NullString.RefCount++; + Chars = &NullString.Nothing[0]; + } return *this; } void FString::Truncate(long newlen) { - if (newlen >= 0 && newlen < (long)Len()) + if (newlen <= 0) + { + Data()->Release(); + NullString.RefCount++; + Chars = &NullString.Nothing[0]; + } + else if (newlen < (long)Len()) { ReallocBuffer (newlen); Chars[newlen] = '\0'; } } +void FString::Remove(size_t index, size_t remlen) +{ + if (index < Len()) + { + if (index + remlen >= Len()) + { + Truncate((long)index); + } + else + { + remlen = Len() - remlen < remlen ? Len() - remlen : remlen; + if (Data()->RefCount == 1) + { // Can do this in place + memmove(Chars + index, Chars + index + remlen, Len() - index - remlen); + Data()->Len -= remlen; + } + else + { // Must do it in a copy + FStringData *old = Data(); + AllocBuffer(old->Len - remlen); + StrCopy(Chars, old->Chars(), index); + StrCopy(Chars + index, old->Chars() + index + remlen, old->Len - index - remlen); + old->Release(); + } + } + } +} + FString FString::Left (size_t numChars) const { size_t len = Len(); @@ -768,25 +814,28 @@ void FString::Insert (size_t index, const char *instr) void FString::Insert (size_t index, const char *instr, size_t instrlen) { - size_t mylen = Len(); - if (index > mylen) + if (instrlen > 0) { - index = mylen; - } - if (Data()->RefCount <= 1) - { - ReallocBuffer (mylen + instrlen); - memmove (Chars + index + instrlen, Chars + index, (mylen - index + 1)*sizeof(char)); - memcpy (Chars + index, instr, instrlen*sizeof(char)); - } - else - { - FStringData *old = Data(); - AllocBuffer (mylen + instrlen); - StrCopy (Chars, old->Chars(), index); - StrCopy (Chars + index, instr, instrlen); - StrCopy (Chars + index + instrlen, old->Chars() + index, mylen - index); - old->Release(); + size_t mylen = Len(); + if (index >= mylen) + { + AppendCStrPart(instr, instrlen); + } + else if (Data()->RefCount <= 1) + { + ReallocBuffer(mylen + instrlen); + memmove(Chars + index + instrlen, Chars + index, (mylen - index + 1) * sizeof(char)); + memcpy(Chars + index, instr, instrlen * sizeof(char)); + } + else + { + FStringData *old = Data(); + AllocBuffer(mylen + instrlen); + StrCopy(Chars, old->Chars(), index); + StrCopy(Chars + index, instr, instrlen); + StrCopy(Chars + index + instrlen, old->Chars() + index, mylen - index); + old->Release(); + } } } diff --git a/src/zstring.h b/src/zstring.h index 00f373b59..ba9208719 100644 --- a/src/zstring.h +++ b/src/zstring.h @@ -268,6 +268,7 @@ public: bool IsNotEmpty() const { return Len() != 0; } void Truncate (long newlen); + void Remove(size_t index, size_t remlen); int Compare (const FString &other) const { return strcmp (Chars, other.Chars); } int Compare (const char *other) const { return strcmp (Chars, other); } From 4dce07762bd05bed6eb35a19f32926176097e5b8 Mon Sep 17 00:00:00 2001 From: Marisa Heit Date: Fri, 11 Nov 2016 22:43:42 -0600 Subject: [PATCH 4/8] Change con_scale behavior for value 0 - Do not use uiscale for con_scale default. A 40 column console when everything is defaults is maddening. The default is now CleanXfac minus 1. --- src/c_console.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/c_console.cpp b/src/c_console.cpp index 2be93a239..180898cc5 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -154,12 +154,12 @@ CUSTOM_CVAR(Int, con_scale, 0, CVAR_ARCHIVE) int active_con_scale() { int scale = con_scale; - if (scale == 0) + if (scale <= 0) { - scale = uiscale; - if (scale == 0) + scale = CleanXfac - 1; + if (scale <= 0) { - scale = CleanXfac; + scale = 1; } } return scale; From c5eb28d360d8fe6b61fc8f4afbfff236d462accd Mon Sep 17 00:00:00 2001 From: Marisa Heit Date: Fri, 11 Nov 2016 22:56:19 -0600 Subject: [PATCH 5/8] Fix console scrolling too far when page scrolling with scaled text --- src/c_console.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/c_console.cpp b/src/c_console.cpp index 180898cc5..d4377682d 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -100,7 +100,7 @@ extern bool advancedemo; extern FBaseCVar *CVars; extern FConsoleCommand *Commands[FConsoleCommand::HASH_SIZE]; -unsigned ConCols, PhysRows; +unsigned ConCols; int ConWidth; bool vidactive = false; bool cursoron = false; @@ -533,7 +533,6 @@ void C_InitConsole (int width, int height, bool ingame) } ConWidth = (width - LEFTMARGIN - RIGHTMARGIN); ConCols = ConWidth / cwidth; - PhysRows = height / cheight; if (conbuffer == NULL) conbuffer = new FConsoleBuffer; } @@ -1324,7 +1323,7 @@ static bool C_HandleKey (event_t *ev, FCommandBuffer &buffer) case GK_PGUP: if (ev->data3 & (GKM_SHIFT|GKM_CTRL)) { // Scroll console buffer up one page - RowAdjust += (SCREENHEIGHT-4) / + RowAdjust += (SCREENHEIGHT-4)/active_con_scale() / ((gamestate == GS_FULLCONSOLE || gamestate == GS_STARTUP) ? ConFont->GetHeight() : ConFont->GetHeight()*2) - 3; } else if (RowAdjust < conbuffer->GetFormattedLineCount()) @@ -1347,7 +1346,7 @@ static bool C_HandleKey (event_t *ev, FCommandBuffer &buffer) case GK_PGDN: if (ev->data3 & (GKM_SHIFT|GKM_CTRL)) { // Scroll console buffer down one page - const int scrollamt = (SCREENHEIGHT-4) / + const int scrollamt = (SCREENHEIGHT-4)/active_con_scale() / ((gamestate == GS_FULLCONSOLE || gamestate == GS_STARTUP) ? ConFont->GetHeight() : ConFont->GetHeight()*2) - 3; if (RowAdjust < scrollamt) { From 513ad7f75ff39c9fc065a56d39ae89d03a82e9be Mon Sep 17 00:00:00 2001 From: Marisa Heit Date: Fri, 11 Nov 2016 23:01:29 -0600 Subject: [PATCH 6/8] Use FString to store console atexit commands --- src/c_console.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/c_console.cpp b/src/c_console.cpp index d4377682d..2f86228b7 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -115,8 +115,10 @@ static void ClearConsole (); struct GameAtExit { + GameAtExit(FString str) : Command(str) {} + GameAtExit *Next; - char Command[1]; + FString Command; }; static GameAtExit *ExitCmdList; @@ -551,16 +553,14 @@ CCMD (atexit) GameAtExit *record = ExitCmdList; while (record != NULL) { - Printf ("%s\n", record->Command); + Printf ("%s\n", record->Command.GetChars()); record = record->Next; } return; } for (int i = 1; i < argv.argc(); ++i) { - GameAtExit *record = (GameAtExit *)M_Malloc ( - sizeof(GameAtExit)+strlen(argv[i])); - strcpy (record->Command, argv[i]); + GameAtExit *record = new GameAtExit(argv[i]); record->Next = ExitCmdList; ExitCmdList = record; } @@ -582,8 +582,8 @@ void C_DeinitConsole () while (cmd != NULL) { GameAtExit *next = cmd->Next; - AddCommandString (cmd->Command); - M_Free (cmd); + AddCommandString (cmd->Command.LockBuffer()); + delete cmd; cmd = next; } From 1e497e0b3e1eec847fbc2d17aabd2954b6a358e3 Mon Sep 17 00:00:00 2001 From: Marisa Heit Date: Fri, 11 Nov 2016 23:55:02 -0600 Subject: [PATCH 7/8] Fixed: FString::StripLeftRight() lost the right character when copying to a new buffer - Also, some minor improvements to the strip functions to avoid doing extra work. --- src/zstring.cpp | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/src/zstring.cpp b/src/zstring.cpp index 63fdf6428..29270b970 100644 --- a/src/zstring.cpp +++ b/src/zstring.cpp @@ -635,6 +635,10 @@ void FString::StripLeft () if (!isspace(Chars[i])) break; } + if (i == 0) + { // Nothing to strip. + return; + } if (Data()->RefCount <= 1) { for (j = 0; i <= max; ++j, ++i) @@ -666,6 +670,10 @@ void FString::StripLeft (const char *charset) if (!strchr (charset, Chars[i])) break; } + if (i == 0) + { // Nothing to strip. + return; + } if (Data()->RefCount <= 1) { for (j = 0; i <= max; ++j, ++i) @@ -686,11 +694,16 @@ void FString::StripLeft (const char *charset) void FString::StripRight () { size_t max = Len(), i; - for (i = max; i-- > 0; ) + if (max == 0) return; + for (i = --max; i-- > 0; ) { if (!isspace(Chars[i])) break; } + if (i == max) + { // Nothing to strip. + return; + } if (Data()->RefCount <= 1) { Chars[i+1] = '\0'; @@ -714,11 +727,15 @@ void FString::StripRight (const char *charset) { size_t max = Len(), i; if (max == 0) return; - for (i = max; i-- > 0; ) + for (i = --max; i-- > 0; ) { if (!strchr (charset, Chars[i])) break; } + if (i == max) + { // Nothing to strip. + return; + } if (Data()->RefCount <= 1) { Chars[i+1] = '\0'; @@ -747,6 +764,10 @@ void FString::StripLeftRight () if (!isspace(Chars[j])) break; } + if (i == 0 && j == max - 1) + { // Nothing to strip. + return; + } if (Data()->RefCount <= 1) { for (k = 0; i <= j; ++i, ++k) @@ -759,8 +780,8 @@ void FString::StripLeftRight () else { FStringData *old = Data(); - AllocBuffer (j - i); - StrCopy (Chars, old->Chars(), j - i); + AllocBuffer(j - i + 1); + StrCopy(Chars, old->Chars(), j - i + 1); old->Release(); } } From c69394fa40901ce51c37e411efb6bb3c2d717aba Mon Sep 17 00:00:00 2001 From: Marisa Heit Date: Sat, 12 Nov 2016 00:30:38 -0600 Subject: [PATCH 8/8] Add con_numnotify cvar to control number of lines of notification text - If con_numnotify < 0, then there is no limit on the number of lines of text. - If con_numnotify == 0, then any text that would normally be shown in the notification area is discarded. - If con_numnotify > 0, then that is the maximum number of lines of notification text to display. --- src/c_console.cpp | 192 ++++++++++++++++++++++++++++------------------ 1 file changed, 117 insertions(+), 75 deletions(-) diff --git a/src/c_console.cpp b/src/c_console.cpp index 2f86228b7..8292624cb 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -379,14 +379,36 @@ static int HistSize; #define NUMNOTIFIES 4 #define NOTIFYFADETIME 6 -static struct NotifyText +struct FNotifyText { int TimeOut; int PrintLevel; FString Text; -} NotifyStrings[NUMNOTIFIES]; +}; + +struct FNotifyBuffer +{ +public: + FNotifyBuffer(); + void AddString(int printlevel, FString source); + void Shift(int maxlines); + void Clear() { Text.Clear(); } + void Tick(); + void Draw(); + +private: + TArray Text; + int Top; + int TopGoal; + enum { NEWLINE, APPENDLINE, REPLACELINE } AddType; +}; +static FNotifyBuffer NotifyStrings; + +CUSTOM_CVAR(Int, con_numnotify, NUMNOTIFIES, CVAR_GLOBALCONFIG | CVAR_ARCHIVE) +{ + NotifyStrings.Shift(con_numnotify); +} -static int NotifyTop, NotifyTopGoal; int PrintColors[PRINTLEVELS+2] = { CR_RED, CR_GOLD, CR_GRAY, CR_GREEN, CR_GREEN, CR_GOLD }; @@ -394,8 +416,6 @@ static void setmsgcolor (int index, int color); FILE *Logfile = NULL; -void C_AddNotifyString (int printlevel, const char *source); - FIntCVar msglevel ("msg", 0, CVAR_ARCHIVE); @@ -489,7 +509,7 @@ void DequeueConsoleText () TextQueue *next = queued->Next; if (queued->bNotify) { - C_AddNotifyString (queued->PrintLevel, queued->Text); + NotifyStrings.AddString(queued->PrintLevel, queued->Text); } else { @@ -668,22 +688,30 @@ static void setmsgcolor (int index, int color) extern int DisplayWidth; -void C_AddNotifyString (int printlevel, const char *source) +FNotifyBuffer::FNotifyBuffer() { - static enum - { - NEWLINE, - APPENDLINE, - REPLACELINE - } addtype = NEWLINE; + Top = TopGoal = 0; + AddType = NEWLINE; +} +void FNotifyBuffer::Shift(int maxlines) +{ + if (maxlines >= 0 && Text.Size() > (unsigned)maxlines) + { + Text.Delete(0, Text.Size() - maxlines); + } +} + +void FNotifyBuffer::AddString(int printlevel, FString source) +{ FBrokenLines *lines; - int i, len, width; + int i, width; if ((printlevel != 128 && !show_messages) || - !(len = (int)strlen (source)) || + source.IsEmpty() || gamestate == GS_FULLCONSOLE || - gamestate == GS_DEMOSCREEN) + gamestate == GS_DEMOSCREEN || + con_numnotify == 0) return; if (ConsoleDrawing) @@ -701,15 +729,18 @@ void C_AddNotifyString (int printlevel, const char *source) width = DisplayWidth / active_con_scaletext(); } - if (addtype == APPENDLINE && NotifyStrings[NUMNOTIFIES-1].PrintLevel == printlevel) + if (AddType == APPENDLINE && Text.Size() > 0 && Text[Text.Size() - 1].PrintLevel == printlevel) { - FString str = NotifyStrings[NUMNOTIFIES-1].Text + source; + FString str = Text[Text.Size() - 1].Text + source; lines = V_BreakLines (SmallFont, width, str); } else { lines = V_BreakLines (SmallFont, width, source); - addtype = (addtype == APPENDLINE) ? NEWLINE : addtype; + if (AddType == APPENDLINE) + { + AddType = NEWLINE; + } } if (lines == NULL) @@ -717,30 +748,37 @@ void C_AddNotifyString (int printlevel, const char *source) for (i = 0; lines[i].Width >= 0; i++) { - if (addtype == NEWLINE) + FNotifyText newline; + + newline.Text = lines[i].Text; + newline.TimeOut = gametic + int(con_notifytime * TICRATE); + newline.PrintLevel = printlevel; + if (AddType == NEWLINE || Text.Size() == 0) { - for (int j = 0; j < NUMNOTIFIES-1; ++j) + if (con_numnotify > 0) { - NotifyStrings[j] = NotifyStrings[j+1]; + Shift(con_numnotify - 1); } + Text.Push(newline); } - NotifyStrings[NUMNOTIFIES-1].Text = lines[i].Text; - NotifyStrings[NUMNOTIFIES-1].TimeOut = gametic + (int)(con_notifytime * TICRATE); - NotifyStrings[NUMNOTIFIES-1].PrintLevel = printlevel; - addtype = NEWLINE; + else + { + Text[Text.Size() - 1] = newline; + } + AddType = NEWLINE; } V_FreeBrokenLines (lines); lines = NULL; - switch (source[len-1]) + switch (source[source.Len()-1]) { - case '\r': addtype = REPLACELINE; break; - case '\n': addtype = NEWLINE; break; - default: addtype = APPENDLINE; break; + case '\r': AddType = REPLACELINE; break; + case '\n': AddType = NEWLINE; break; + default: AddType = APPENDLINE; break; } - NotifyTopGoal = 0; + TopGoal = 0; } void AddToConsole (int printlevel, const char *text) @@ -763,7 +801,7 @@ int PrintString (int printlevel, const char *outline) AddToConsole (printlevel, outline); if (vidactive && screen && SmallFont) { - C_AddNotifyString (printlevel, outline); + NotifyStrings.AddString(printlevel, outline); maybedrawnow (false, false); } } @@ -831,10 +869,7 @@ int DPrintf (int level, const char *format, ...) void C_FlushDisplay () { - int i; - - for (i = 0; i < NUMNOTIFIES; i++) - NotifyStrings[i].TimeOut = 0; + NotifyStrings.Clear(); } void C_AdjustBottom () @@ -853,7 +888,7 @@ void C_NewModeAdjust () } int consoletic = 0; -void C_Ticker () +void C_Ticker() { static int lasttic = 0; consoletic++; @@ -895,28 +930,43 @@ void C_Ticker () } lasttic = consoletic; + NotifyStrings.Tick(); +} - if (NotifyTopGoal > NotifyTop) +void FNotifyBuffer::Tick() +{ + if (TopGoal > Top) { - NotifyTop++; + Top++; } - else if (NotifyTopGoal < NotifyTop) + else if (TopGoal < Top) { - NotifyTop--; + Top--; + } + + // Remove lines from the beginning that have expired. + unsigned i; + for (i = 0; i < Text.Size(); ++i) + { + if (Text[i].TimeOut != 0 && Text[i].TimeOut > gametic) + break; + } + if (i > 0) + { + Text.Delete(0, i); } } -static void C_DrawNotifyText () +void FNotifyBuffer::Draw() { bool center = (con_centernotify != 0.f); - int i, line, lineadv, color, j, skip; + int line, lineadv, color, j; bool canskip; if (gamestate == GS_FULLCONSOLE || gamestate == GS_DEMOSCREEN/* || menuactive != MENU_Off*/) return; - line = NotifyTop; - skip = 0; + line = Top; canskip = true; lineadv = SmallFont->GetHeight (); @@ -927,67 +977,60 @@ static void C_DrawNotifyText () BorderTopRefresh = screen->GetPageCount (); - for (i = 0; i < NUMNOTIFIES; i++) + for (unsigned i = 0; i < Text.Size(); ++ i) { - if (NotifyStrings[i].TimeOut == 0) + FNotifyText ¬ify = Text[i]; + + if (notify.TimeOut == 0) continue; - j = NotifyStrings[i].TimeOut - gametic; + j = notify.TimeOut - gametic; if (j > 0) { - if (!show_messages && NotifyStrings[i].PrintLevel != 128) + if (!show_messages && notify.PrintLevel != 128) continue; - double alpha; + double alpha = (j < NOTIFYFADETIME) ? 1. * j / NOTIFYFADETIME : 1; - if (j < NOTIFYFADETIME) - { - alpha = 1. * j / NOTIFYFADETIME; - } - else - { - alpha = 1; - } - - if (NotifyStrings[i].PrintLevel >= PRINTLEVELS) + if (notify.PrintLevel >= PRINTLEVELS) color = CR_UNTRANSLATED; else - color = PrintColors[NotifyStrings[i].PrintLevel]; + color = PrintColors[notify.PrintLevel]; if (active_con_scaletext() == 0) { if (!center) - screen->DrawText (SmallFont, color, 0, line, NotifyStrings[i].Text, + screen->DrawText (SmallFont, color, 0, line, notify.Text, DTA_CleanNoMove, true, DTA_AlphaF, alpha, TAG_DONE); else screen->DrawText (SmallFont, color, (SCREENWIDTH - - SmallFont->StringWidth (NotifyStrings[i].Text)*CleanXfac)/2, - line, NotifyStrings[i].Text, DTA_CleanNoMove, true, + SmallFont->StringWidth (notify.Text)*CleanXfac)/2, + line, notify.Text, DTA_CleanNoMove, true, DTA_AlphaF, alpha, TAG_DONE); } else if (active_con_scaletext() == 1) { if (!center) - screen->DrawText (SmallFont, color, 0, line, NotifyStrings[i].Text, + screen->DrawText (SmallFont, color, 0, line, notify.Text, DTA_AlphaF, alpha, TAG_DONE); else screen->DrawText (SmallFont, color, (SCREENWIDTH - - SmallFont->StringWidth (NotifyStrings[i].Text))/2, - line, NotifyStrings[i].Text, + SmallFont->StringWidth (notify.Text))/2, + line, notify.Text, DTA_AlphaF, alpha, TAG_DONE); } else { if (!center) - screen->DrawText (SmallFont, color, 0, line, NotifyStrings[i].Text, + screen->DrawText (SmallFont, color, 0, line, notify.Text, DTA_VirtualWidth, screen->GetWidth() / active_con_scaletext(), DTA_VirtualHeight, screen->GetHeight() / active_con_scaletext(), DTA_KeepRatio, true, DTA_AlphaF, alpha, TAG_DONE); else screen->DrawText (SmallFont, color, (screen->GetWidth() - - SmallFont->StringWidth (NotifyStrings[i].Text) * active_con_scaletext()) / 2 / active_con_scaletext(), - line, NotifyStrings[i].Text, + SmallFont->StringWidth (notify.Text) * active_con_scaletext()) / 2 / active_con_scaletext(), + line, notify.Text, DTA_VirtualWidth, screen->GetWidth() / active_con_scaletext(), DTA_VirtualHeight, screen->GetHeight() / active_con_scaletext(), DTA_KeepRatio, true, @@ -1000,16 +1043,15 @@ static void C_DrawNotifyText () { if (canskip) { - NotifyTop += lineadv; + Top += lineadv; line += lineadv; - skip++; } - NotifyStrings[i].TimeOut = 0; + notify.TimeOut = 0; } } if (canskip) { - NotifyTop = NotifyTopGoal; + Top = TopGoal; } } @@ -1059,7 +1101,7 @@ void C_DrawConsole (bool hw2d) if (ConsoleState == c_up) { - C_DrawNotifyText (); + NotifyStrings.Draw(); return; } else if (ConBottom)