Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff -r 00065f166c52 src/chat.cpp
- --- a/src/chat.cpp Sun Aug 19 22:11:18 2012 +0200
- +++ b/src/chat.cpp Sat Jan 05 21:17:45 2013 +0200
- @@ -76,14 +76,22 @@
- #include "sbar.h"
- #include "st_hud.h"
- #include "sectinfo.h"
- +#include "g_level.h"
- //*****************************************************************************
- // VARIABLES
- +#define MAX_CHAT_ARCHIVE 10 + 1
- +
- +#define CHAT_DEBUG
- static ULONG g_ulChatMode;
- static char g_szChatBuffer[MAX_CHATBUFFER_LENGTH];
- static LONG g_lStringLength;
- static const char *g_pszChatPrompt = "SAY: ";
- +static ULONG g_ulStringCursor;
- +static ULONG g_ulStringCursorBlinkTime;
- +static FString g_ChatArchive[MAX_CHAT_ARCHIVE];
- +static ULONG g_ulChatArchiveCursor = MAX_CHAT_ARCHIVE - 1;
- //*****************************************************************************
- // CONSOLE VARIABLES
- @@ -127,9 +135,12 @@
- void chat_SendMessage( ULONG ulMode, const char *pszString );
- void chat_ClearChatMessage( void );
- void chat_AddChar( char cChar );
- -void chat_DeleteChar( void );
- +void chat_DeleteChar( ULONG ulPosition );
- void chat_GetIgnoredPlayers( FString &Destination ); // [RC]
- void chat_DoSubstitution( FString &Input ); // [CW]
- +void chat_MoveCursor( int delta ); // [Dusk]
- +void chat_ArchiveChatString( FString chatstring ); // [Dusk]
- +void chat_MoveArchiveCursor( int delta ); // [Dusk]
- // [BB] From ZDoom
- //===========================================================================
- @@ -208,32 +219,55 @@
- {
- if ( pEvent->subtype == EV_GUI_KeyDown || pEvent->subtype == EV_GUI_KeyRepeat )
- {
- - if ( pEvent->data1 == '\r' )
- - {
- - chat_SendMessage( g_ulChatMode, g_szChatBuffer );
- - chat_SetChatMode( CHATMODE_NONE );
- - return ( true );
- - }
- - else if ( pEvent->data1 == GK_ESCAPE )
- - {
- - chat_SetChatMode( CHATMODE_NONE );
- - return ( true );
- - }
- - else if ( pEvent->data1 == '\b' )
- - {
- - chat_DeleteChar( );
- - return ( true );
- - }
- - // Ctrl+C.
- - else if ( pEvent->data1 == 'C' && ( pEvent->data3 & GKM_CTRL ))
- - {
- - I_PutInClipboard(g_szChatBuffer );
- - return ( true );
- - }
- - // Ctrl+V.
- - else if ( pEvent->data1 == 'V' && ( pEvent->data3 & GKM_CTRL ))
- - {
- - CT_PasteChat(I_GetFromClipboard(false));
- + // [Dusk] Added switch
- + switch ( pEvent->data1 ) {
- + case '\r':
- + chat_SendMessage( g_ulChatMode, g_szChatBuffer );
- + chat_SetChatMode( CHATMODE_NONE );
- + return ( true );
- + case GK_ESCAPE:
- + chat_SetChatMode( CHATMODE_NONE );
- + return ( true );
- + case '\b':
- + chat_DeleteChar( g_ulStringCursor );
- + return ( true );
- + case 'C':
- + if ( pEvent->data3 & GKM_CTRL )
- + {
- + // Ctrl+C.
- + I_PutInClipboard(g_szChatBuffer );
- + return ( true );
- + }
- + break;
- + case 'V':
- + // [Dusk] Why does this not return true?
- + if ( pEvent->data3 & GKM_CTRL )
- + {
- + CT_PasteChat(I_GetFromClipboard(false));
- + }
- + break;
- + // [Dusk] Left/right arrows move the cursor
- + case GK_LEFT:
- + case GK_RIGHT:
- + chat_MoveCursor(( pEvent->data1 == GK_RIGHT ) ? 1 : -1 );
- + return ( true );
- + // [Dusk] Home
- + case GK_HOME:
- + chat_MoveCursor( -g_lStringLength );
- + return ( true );
- + // [Dusk] End
- + case GK_END:
- + chat_MoveCursor( g_lStringLength );
- + return ( true );
- + // [Dusk] Delete
- + case GK_DEL:
- + chat_DeleteChar( g_ulStringCursor + 1 );
- + return ( true );
- + // [Dusk] Up and down fetch an archived message.
- + case GK_UP:
- + case GK_DOWN:
- + chat_MoveArchiveCursor(( pEvent->data1 == GK_UP ) ? -1 : 1 );
- + return ( true );
- }
- }
- else if ( pEvent->subtype == EV_GUI_Char )
- @@ -314,9 +348,27 @@
- else
- lIdx = 0;
- - // Temporarily h4x0r the chat buffer string to include the cursor.
- - g_szChatBuffer[g_lStringLength] = gameinfo.gametype == GAME_Doom ? '_' : '[';
- - g_szChatBuffer[g_lStringLength+1] = 0;
- + // [Dusk] Create display string from substrings
- + FString displaychat = FString (g_szChatBuffer).Left (g_ulStringCursor);
- +
- + // [Dusk] Add the cursor, but make it blink!
- + bool bBlinking = (( level.time-g_ulStringCursorBlinkTime ) % TICRATE ) > ( TICRATE / 2 );
- + if (bBlinking)
- + displaychat += TEXTCOLOR_BLACK;
- +
- + displaychat += (gameinfo.gametype == GAME_Doom) ? '_' : '[';
- +
- + if (bBlinking)
- + displaychat += TEXTCOLOR_NORMAL;
- +
- + // [Dusk] Add right side
- + displaychat += FString( g_szChatBuffer ).Right( g_lStringLength - g_ulStringCursor );
- +
- +#ifdef CHAT_DEBUG
- + displaychat.AppendFormat (" \\cI[\\cF%lu\\cI]", g_ulChatArchiveCursor );
- + V_ColorizeString( displaychat );
- +#endif
- +
- if ( g_ulChatMode == CHATMODE_GLOBAL )
- {
- HUD_DrawText( SmallFont, CR_GREEN,
- @@ -327,7 +379,7 @@
- HUD_DrawText( SmallFont, CR_GRAY,
- SmallFont->StringWidth( g_pszChatPrompt ),
- (LONG)( ulYPos * fYScale ),
- - g_szChatBuffer + lIdx );
- + displaychat.GetChars() + lIdx );
- }
- else
- {
- @@ -339,7 +391,7 @@
- HUD_DrawText( SmallFont, (TEAM_GetTextColor (players[consoleplayer].ulTeam)),
- SmallFont->StringWidth( g_pszChatPrompt ),
- (LONG)( ulYPos * fYScale ),
- - g_szChatBuffer + lIdx );
- + displaychat.GetChars() + lIdx );
- }
- // [RC] Tell chatters about the iron curtain of LMS chat.
- @@ -508,6 +560,10 @@
- // Tell the server we're beginning to chat.
- if ( NETWORK_GetState( ) == NETSTATE_CLIENT )
- CLIENTCOMMANDS_StartChat( );
- +
- + // [Dusk] Since we're opening the chat box here, also reset the
- + // archive cursor so we won't be offset anywhere.
- + g_ulChatArchiveCursor = MAX_CHAT_ARCHIVE - 1;
- }
- else
- {
- @@ -530,6 +586,9 @@
- // [CW] Substitute the message if necessary.
- chat_DoSubstitution( ChatMessage );
- + // [Dusk] Archive it in chat history.
- + chat_ArchiveChatString( pszString );
- +
- // If we're the client, let the server handle formatting/sending the msg to other players.
- if ( NETWORK_GetState( ) == NETSTATE_CLIENT )
- {
- @@ -559,25 +618,132 @@
- // String buffer is of zero length.
- g_lStringLength = 0;
- +
- + // [Dusk] Reset the cursor
- + g_ulStringCursor = 0;
- + g_ulStringCursorBlinkTime = level.time;
- }
- //*****************************************************************************
- //
- void chat_AddChar( char cChar )
- {
- + g_ulStringCursorBlinkTime = level.time;
- +
- if ( g_lStringLength >= ( MAX_CHATBUFFER_LENGTH - 2 ))
- return;
- - g_szChatBuffer[g_lStringLength++] = cChar;
- - g_szChatBuffer[g_lStringLength] = 0;
- + // [Dusk] FString::Insert doesn't seem to work properly with one char
- + // input (it adds two if the string is empty), thus build the new string
- + // from substrings.
- + FString temp = (FString (g_szChatBuffer).Left (g_ulStringCursor));
- + temp += cChar;
- + temp += FString (g_szChatBuffer).Right(g_lStringLength - g_ulStringCursor);
- + strcpy (g_szChatBuffer, temp.GetChars());
- +
- + g_ulStringCursor++;
- + g_lStringLength++;
- }
- //*****************************************************************************
- //
- -void chat_DeleteChar( void )
- +void chat_DeleteChar( ULONG ulPosition )
- {
- - if ( g_lStringLength )
- - g_szChatBuffer[--g_lStringLength] = 0;
- + g_ulStringCursorBlinkTime = level.time;
- +
- + if ( g_lStringLength <= 0 || g_ulStringCursor <= 0 || ulPosition < 0 || (LONG)ulPosition > g_lStringLength )
- + return;
- +
- + // [Dusk] Create a new string from substrings that
- + // leaves the undesired character out.
- + FString temp = FString( g_szChatBuffer ).Left( ulPosition - 1 );
- + temp += FString( g_szChatBuffer ).Right( g_lStringLength - ulPosition );
- + strcpy ( g_szChatBuffer, temp.GetChars( ) );
- +
- + if ( ulPosition <= g_ulStringCursor )
- + g_ulStringCursor--;
- +
- + g_lStringLength--;
- +}
- +
- +//*****************************************************************************
- +//
- +// [Dusk] Moves cursor by delta characters. Negative values means to left,
- +// positive ones mean to right
- +//
- +void chat_MoveCursor( int delta ) {
- + g_ulStringCursorBlinkTime = level.time;
- +
- + if( delta < 0 && -delta > (int)g_ulStringCursor )
- + {
- + // Cursor hits beginning
- + g_ulStringCursor = 0;
- + }
- + else if ( delta > 0 && delta > (int)g_lStringLength - (int)g_ulStringCursor )
- + {
- + // Cursor hits end
- + g_ulStringCursor = g_lStringLength;
- + }
- + else
- + {
- + g_ulStringCursor += delta;
- + }
- +}
- +
- +//*****************************************************************************
- +// [Dusk] Add the current chat string to the archive
- +void chat_ArchiveChatString( FString chatstring )
- +{
- + ULONG i = 0;
- +
- + // [Dusk] If the archive is full, pop out the oldest entry to make room for the new one.
- + // Note: MAX_CHAT_ARCHIVE - 1 is the index of the buffer of the current chat string,
- + // we may not touch it.
- + if ( g_ChatArchive[MAX_CHAT_ARCHIVE - 2].IsNotEmpty( ) ) {
- + for ( i = 0; i < MAX_CHAT_ARCHIVE - 2; i++ )
- + g_ChatArchive[i] = g_ChatArchive[i + 1];
- + } else {
- + // [Dusk] We know there's at least one free spot, find the first one.
- + for ( i = 0; i < MAX_CHAT_ARCHIVE - 1; i++ )
- + if ( g_ChatArchive[i].IsEmpty( ) )
- + break;
- + assert( i < MAX_CHAT_ARCHIVE - 1 );
- + }
- +
- + g_ChatArchive[i] = chatstring;
- +}
- +
- +//*****************************************************************************
- +//
- +// [Dusk] Find archived messages.
- +void chat_MoveArchiveCursor( int delta )
- +{
- + // dest is where the cursor will move to.
- + LONG dest = ( g_ulChatArchiveCursor + delta );
- +
- + // Slide through anything empty
- + while ( dest >= 0 && dest < (MAX_CHAT_ARCHIVE - 1) && g_ChatArchive[dest].IsEmpty( ) )
- + dest += ( delta > 0 ) ? 1 : -1;
- +
- + // We SHOULD be still inside the archive, but you never know..
- + if ( dest < 0 || dest >= MAX_CHAT_ARCHIVE) // Out of range
- + return;
- +
- + // If we are leaving the initial chat string spot, store the current
- + // buffer into MAX_CHAT_ARCHIVE - 1, which is a special index reserved
- + // for this purpose.
- + if (g_ulChatArchiveCursor == MAX_CHAT_ARCHIVE - 1)
- + g_ChatArchive[MAX_CHAT_ARCHIVE - 1] = g_szChatBuffer;
- +
- + // If the destination-to-be is an empty string, do nothing.
- + // However, we should always be able to return to the special
- + // chat buffer, even if it is empty.
- + if ( g_ChatArchive[dest].IsEmpty( ) && dest != (MAX_CHAT_ARCHIVE - 1) )
- + return;
- +
- + strncpy( g_szChatBuffer, g_ChatArchive[dest].GetChars( ), MAX_CHATBUFFER_LENGTH );
- + g_ulChatArchiveCursor = dest;
- + g_ulStringCursor = g_lStringLength = strlen( g_szChatBuffer );
- }
- //*****************************************************************************
- @@ -922,3 +1088,15 @@
- chat_UnignorePlayer( argv, ulPlayer );
- }
- +// [Dusk] Debug function
- +CCMD( dumpchatarchive )
- +{
- + Printf ("*** CHAT ARCHIVE:\n");
- + for (ULONG u = 0; u < MAX_CHAT_ARCHIVE; u++) {
- + const char* arrow = (u == MAX_CHAT_ARCHIVE - 1) ? "!! " : (u == g_ulChatArchiveCursor) ? "=> " : " ";
- + if (g_ChatArchive[u].IsEmpty( ))
- + Printf ("%s%lu. ----\n", arrow, u);
- + else
- + Printf ("%s%lu. `%s`\n", arrow, u, g_ChatArchive[u].GetChars( ));
- + }
- +}
- \ No newline at end of file
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement