Advertisement
arezey

Untitled

Jan 5th, 2013
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 10.95 KB | None | 0 0
  1. diff -r 00065f166c52 src/chat.cpp
  2. --- a/src/chat.cpp  Sun Aug 19 22:11:18 2012 +0200
  3. +++ b/src/chat.cpp  Sat Jan 05 21:17:45 2013 +0200
  4. @@ -76,14 +76,22 @@
  5.  #include "sbar.h"
  6.  #include "st_hud.h"
  7.  #include "sectinfo.h"
  8. +#include "g_level.h"
  9.  
  10.  //*****************************************************************************
  11.  // VARIABLES
  12. +#define MAX_CHAT_ARCHIVE 10 + 1
  13. +
  14. +#define CHAT_DEBUG
  15.  
  16.  static ULONG   g_ulChatMode;
  17.  static char    g_szChatBuffer[MAX_CHATBUFFER_LENGTH];
  18.  static LONG    g_lStringLength;
  19.  static const char  *g_pszChatPrompt = "SAY: ";
  20. +static ULONG   g_ulStringCursor;
  21. +static ULONG   g_ulStringCursorBlinkTime;
  22. +static FString g_ChatArchive[MAX_CHAT_ARCHIVE];
  23. +static ULONG   g_ulChatArchiveCursor = MAX_CHAT_ARCHIVE - 1;
  24.  
  25.  //*****************************************************************************
  26.  // CONSOLE VARIABLES
  27. @@ -127,9 +135,12 @@
  28.  void   chat_SendMessage( ULONG ulMode, const char *pszString );
  29.  void   chat_ClearChatMessage( void );
  30.  void   chat_AddChar( char cChar );
  31. -void   chat_DeleteChar( void );
  32. +void   chat_DeleteChar( ULONG ulPosition );
  33.  void   chat_GetIgnoredPlayers( FString &Destination ); // [RC]
  34.  void   chat_DoSubstitution( FString &Input ); // [CW]
  35. +void   chat_MoveCursor( int delta ); // [Dusk]
  36. +void   chat_ArchiveChatString( FString chatstring ); // [Dusk]
  37. +void   chat_MoveArchiveCursor( int delta ); // [Dusk]
  38.  
  39.  // [BB] From ZDoom
  40.  //===========================================================================
  41. @@ -208,32 +219,55 @@
  42.     {
  43.         if ( pEvent->subtype == EV_GUI_KeyDown || pEvent->subtype == EV_GUI_KeyRepeat )
  44.         {
  45. -           if ( pEvent->data1 == '\r' )
  46. -           {
  47. -               chat_SendMessage( g_ulChatMode, g_szChatBuffer );
  48. -               chat_SetChatMode( CHATMODE_NONE );
  49. -               return ( true );
  50. -           }
  51. -           else if ( pEvent->data1 == GK_ESCAPE )
  52. -           {
  53. -               chat_SetChatMode( CHATMODE_NONE );
  54. -               return ( true );
  55. -           }
  56. -           else if ( pEvent->data1 == '\b' )
  57. -           {
  58. -               chat_DeleteChar( );
  59. -               return ( true );
  60. -           }
  61. -           // Ctrl+C.
  62. -           else if ( pEvent->data1 == 'C' && ( pEvent->data3 & GKM_CTRL ))
  63. -           {
  64. -               I_PutInClipboard(g_szChatBuffer );
  65. -               return ( true );
  66. -           }
  67. -           // Ctrl+V.
  68. -           else if ( pEvent->data1 == 'V' && ( pEvent->data3 & GKM_CTRL ))
  69. -           {
  70. -               CT_PasteChat(I_GetFromClipboard(false));
  71. +           // [Dusk] Added switch
  72. +           switch ( pEvent->data1 ) {
  73. +               case '\r':
  74. +                   chat_SendMessage( g_ulChatMode, g_szChatBuffer );
  75. +                   chat_SetChatMode( CHATMODE_NONE );
  76. +                   return ( true );
  77. +               case GK_ESCAPE:
  78. +                   chat_SetChatMode( CHATMODE_NONE );
  79. +                   return ( true );
  80. +               case '\b':
  81. +                   chat_DeleteChar( g_ulStringCursor );
  82. +                   return ( true );
  83. +               case 'C':
  84. +                   if ( pEvent->data3 & GKM_CTRL )
  85. +                   {
  86. +                       // Ctrl+C.
  87. +                       I_PutInClipboard(g_szChatBuffer );
  88. +                       return ( true );
  89. +                   }
  90. +                   break;
  91. +               case 'V':
  92. +                   // [Dusk] Why does this not return true?
  93. +                   if ( pEvent->data3 & GKM_CTRL )
  94. +                   {
  95. +                       CT_PasteChat(I_GetFromClipboard(false));
  96. +                   }
  97. +                   break;
  98. +               // [Dusk] Left/right arrows move the cursor
  99. +               case GK_LEFT:
  100. +               case GK_RIGHT:
  101. +                   chat_MoveCursor(( pEvent->data1 == GK_RIGHT ) ? 1 : -1 );
  102. +                   return ( true );
  103. +               // [Dusk] Home
  104. +               case GK_HOME:
  105. +                   chat_MoveCursor( -g_lStringLength );
  106. +                   return ( true );
  107. +               // [Dusk] End
  108. +               case GK_END:
  109. +                   chat_MoveCursor( g_lStringLength );
  110. +                   return ( true );
  111. +               // [Dusk] Delete
  112. +               case GK_DEL:
  113. +                   chat_DeleteChar( g_ulStringCursor + 1 );
  114. +                   return ( true );
  115. +               // [Dusk] Up and down fetch an archived message.
  116. +               case GK_UP:
  117. +               case GK_DOWN:
  118. +                   chat_MoveArchiveCursor(( pEvent->data1 == GK_UP ) ? -1 : 1 );
  119. +                   return ( true );
  120.             }
  121.         }
  122.         else if ( pEvent->subtype == EV_GUI_Char )
  123. @@ -314,9 +348,27 @@
  124.     else
  125.         lIdx = 0;
  126.  
  127. -   // Temporarily h4x0r the chat buffer string to include the cursor.
  128. -   g_szChatBuffer[g_lStringLength] = gameinfo.gametype == GAME_Doom ? '_' : '[';
  129. -   g_szChatBuffer[g_lStringLength+1] = 0;
  130. +   // [Dusk] Create display string from substrings
  131. +   FString displaychat = FString (g_szChatBuffer).Left (g_ulStringCursor);
  132. +
  133. +   // [Dusk] Add the cursor, but make it blink!
  134. +   bool bBlinking = (( level.time-g_ulStringCursorBlinkTime ) % TICRATE ) > ( TICRATE / 2 );
  135. +   if (bBlinking)
  136. +       displaychat += TEXTCOLOR_BLACK;
  137. +
  138. +   displaychat += (gameinfo.gametype == GAME_Doom) ? '_' : '[';
  139. +
  140. +   if (bBlinking)
  141. +       displaychat += TEXTCOLOR_NORMAL;
  142. +
  143. +   // [Dusk] Add right side
  144. +   displaychat += FString( g_szChatBuffer ).Right( g_lStringLength - g_ulStringCursor );
  145. +
  146. +#ifdef CHAT_DEBUG
  147. +   displaychat.AppendFormat (" \\cI[\\cF%lu\\cI]", g_ulChatArchiveCursor );
  148. +   V_ColorizeString( displaychat );
  149. +#endif
  150. +
  151.     if ( g_ulChatMode == CHATMODE_GLOBAL )
  152.     {
  153.         HUD_DrawText( SmallFont, CR_GREEN,
  154. @@ -327,7 +379,7 @@
  155.         HUD_DrawText( SmallFont, CR_GRAY,
  156.             SmallFont->StringWidth( g_pszChatPrompt ),
  157.             (LONG)( ulYPos * fYScale ),
  158. -           g_szChatBuffer + lIdx );
  159. +           displaychat.GetChars() + lIdx );
  160.     }
  161.     else
  162.     {
  163. @@ -339,7 +391,7 @@
  164.         HUD_DrawText( SmallFont, (TEAM_GetTextColor (players[consoleplayer].ulTeam)),
  165.             SmallFont->StringWidth( g_pszChatPrompt ),
  166.             (LONG)( ulYPos * fYScale ),
  167. -           g_szChatBuffer + lIdx );
  168. +           displaychat.GetChars() + lIdx );
  169.     }
  170.  
  171.     // [RC] Tell chatters about the iron curtain of LMS chat.
  172. @@ -508,6 +560,10 @@
  173.             // Tell the server we're beginning to chat.
  174.             if ( NETWORK_GetState( ) == NETSTATE_CLIENT )
  175.                 CLIENTCOMMANDS_StartChat( );
  176. +
  177. +           // [Dusk] Since we're opening the chat box here, also reset the
  178. +           // archive cursor so we won't be offset anywhere.
  179. +           g_ulChatArchiveCursor = MAX_CHAT_ARCHIVE - 1;
  180.         }
  181.         else
  182.         {
  183. @@ -530,6 +586,9 @@
  184.     // [CW] Substitute the message if necessary.
  185.     chat_DoSubstitution( ChatMessage );
  186.  
  187. +   // [Dusk] Archive it in chat history.
  188. +   chat_ArchiveChatString( pszString );
  189. +
  190.     // If we're the client, let the server handle formatting/sending the msg to other players.
  191.     if ( NETWORK_GetState( ) == NETSTATE_CLIENT )
  192.     {
  193. @@ -559,25 +618,132 @@
  194.  
  195.     // String buffer is of zero length.
  196.     g_lStringLength = 0;
  197. +
  198. +   // [Dusk] Reset the cursor
  199. +   g_ulStringCursor = 0;
  200. +   g_ulStringCursorBlinkTime = level.time;
  201.  }
  202.  
  203.  //*****************************************************************************
  204.  //
  205.  void chat_AddChar( char cChar )
  206.  {
  207. +   g_ulStringCursorBlinkTime = level.time;
  208. +
  209.     if ( g_lStringLength >= ( MAX_CHATBUFFER_LENGTH - 2 ))
  210.         return;
  211.  
  212. -   g_szChatBuffer[g_lStringLength++] = cChar;
  213. -   g_szChatBuffer[g_lStringLength] = 0;
  214. +   // [Dusk] FString::Insert doesn't seem to work properly with one char
  215. +   // input (it adds two if the string is empty), thus build the new string
  216. +   // from substrings.
  217. +   FString temp = (FString (g_szChatBuffer).Left (g_ulStringCursor));
  218. +   temp += cChar;
  219. +   temp += FString (g_szChatBuffer).Right(g_lStringLength - g_ulStringCursor);
  220. +   strcpy (g_szChatBuffer, temp.GetChars());
  221. +
  222. +   g_ulStringCursor++;
  223. +   g_lStringLength++;
  224.  }
  225.  
  226.  //*****************************************************************************
  227.  //
  228. -void chat_DeleteChar( void )
  229. +void chat_DeleteChar( ULONG ulPosition )
  230.  {
  231. -   if ( g_lStringLength )
  232. -       g_szChatBuffer[--g_lStringLength] = 0;
  233. +   g_ulStringCursorBlinkTime = level.time;
  234. +
  235. +   if ( g_lStringLength <= 0 || g_ulStringCursor <= 0 || ulPosition < 0 || (LONG)ulPosition > g_lStringLength )
  236. +       return;
  237. +
  238. +   // [Dusk] Create a new string from substrings that
  239. +   // leaves the undesired character out.
  240. +   FString temp = FString( g_szChatBuffer ).Left( ulPosition - 1 );
  241. +   temp += FString( g_szChatBuffer ).Right( g_lStringLength - ulPosition );
  242. +   strcpy ( g_szChatBuffer, temp.GetChars( ) );
  243. +
  244. +   if ( ulPosition <= g_ulStringCursor )
  245. +       g_ulStringCursor--;
  246. +
  247. +   g_lStringLength--;
  248. +}
  249. +
  250. +//*****************************************************************************
  251. +//
  252. +// [Dusk] Moves cursor by delta characters. Negative values means to left,
  253. +// positive ones mean to right
  254. +//
  255. +void chat_MoveCursor( int delta ) {
  256. +   g_ulStringCursorBlinkTime = level.time;
  257. +
  258. +   if( delta < 0 && -delta > (int)g_ulStringCursor )
  259. +   {
  260. +       // Cursor hits beginning
  261. +       g_ulStringCursor = 0;
  262. +   }
  263. +   else if ( delta > 0 && delta > (int)g_lStringLength - (int)g_ulStringCursor )
  264. +   {
  265. +       // Cursor hits end
  266. +       g_ulStringCursor = g_lStringLength;
  267. +   }
  268. +   else
  269. +   {
  270. +       g_ulStringCursor += delta;
  271. +   }
  272. +}
  273. +
  274. +//*****************************************************************************
  275. +// [Dusk] Add the current chat string to the archive
  276. +void chat_ArchiveChatString( FString chatstring )
  277. +{
  278. +   ULONG i = 0;
  279. +
  280. +   // [Dusk] If the archive is full, pop out the oldest entry to make room for the new one.
  281. +   // Note: MAX_CHAT_ARCHIVE - 1 is the index of the buffer of the current chat string,
  282. +   // we may not touch it.
  283. +   if ( g_ChatArchive[MAX_CHAT_ARCHIVE - 2].IsNotEmpty( ) ) {
  284. +       for ( i = 0; i < MAX_CHAT_ARCHIVE - 2; i++ )
  285. +           g_ChatArchive[i] = g_ChatArchive[i + 1];
  286. +   } else {
  287. +       // [Dusk] We know there's at least one free spot, find the first one.
  288. +       for ( i = 0; i < MAX_CHAT_ARCHIVE - 1; i++ )
  289. +           if ( g_ChatArchive[i].IsEmpty( ) )
  290. +               break;
  291. +       assert( i < MAX_CHAT_ARCHIVE - 1 );
  292. +   }
  293. +
  294. +   g_ChatArchive[i] = chatstring;
  295. +}
  296. +
  297. +//*****************************************************************************
  298. +//
  299. +// [Dusk] Find archived messages.
  300. +void chat_MoveArchiveCursor( int delta )
  301. +{
  302. +   // dest is where the cursor will move to.
  303. +   LONG dest = ( g_ulChatArchiveCursor + delta );
  304. +
  305. +   // Slide through anything empty
  306. +   while ( dest >= 0 && dest < (MAX_CHAT_ARCHIVE - 1) && g_ChatArchive[dest].IsEmpty( ) )
  307. +       dest += ( delta > 0 ) ? 1 : -1;
  308. +
  309. +   // We SHOULD be still inside the archive, but you never know..
  310. +   if ( dest < 0 || dest >= MAX_CHAT_ARCHIVE) // Out of range
  311. +       return;
  312. +
  313. +   // If we are leaving the initial chat string spot, store the current
  314. +   // buffer into MAX_CHAT_ARCHIVE - 1, which is a special index reserved
  315. +   // for this purpose.
  316. +   if (g_ulChatArchiveCursor == MAX_CHAT_ARCHIVE - 1)
  317. +       g_ChatArchive[MAX_CHAT_ARCHIVE - 1] = g_szChatBuffer;
  318. +
  319. +   // If the destination-to-be is an empty string, do nothing.
  320. +   // However, we should always be able to return to the special
  321. +   // chat buffer, even if it is empty.
  322. +   if ( g_ChatArchive[dest].IsEmpty( ) && dest != (MAX_CHAT_ARCHIVE - 1) )
  323. +       return;
  324. +
  325. +   strncpy( g_szChatBuffer, g_ChatArchive[dest].GetChars( ), MAX_CHATBUFFER_LENGTH );
  326. +   g_ulChatArchiveCursor = dest;
  327. +   g_ulStringCursor = g_lStringLength = strlen( g_szChatBuffer );
  328.  }
  329.  
  330.  //*****************************************************************************
  331. @@ -922,3 +1088,15 @@
  332.     chat_UnignorePlayer( argv, ulPlayer );
  333.  }
  334.  
  335. +// [Dusk] Debug function
  336. +CCMD( dumpchatarchive )
  337. +{
  338. +   Printf ("*** CHAT ARCHIVE:\n");
  339. +   for (ULONG u = 0; u < MAX_CHAT_ARCHIVE; u++) {
  340. +       const char* arrow = (u == MAX_CHAT_ARCHIVE - 1) ? "!! " : (u == g_ulChatArchiveCursor) ? "=> " : "   ";
  341. +       if (g_ChatArchive[u].IsEmpty( ))
  342. +           Printf ("%s%lu. ----\n", arrow, u);
  343. +       else
  344. +           Printf ("%s%lu. `%s`\n", arrow, u, g_ChatArchive[u].GetChars( ));
  345. +   }
  346. +}
  347. \ No newline at end of file
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement