r1171 - in trunk: . code/sys

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Fri Sep 7 17:27:03 EDT 2007


Author: tjw
Date: 2007-09-07 17:27:01 -0400 (Fri, 07 Sep 2007)
New Revision: 1171

Modified:
   trunk/Makefile
   trunk/code/sys/con_win32.c
Log:
* Adds preliminary support for win32 dedicated server console.
  Functionality is still quite limited (no tab completion, history, etc.),
  but at least with this console you can scroll without locking up
  your server.


Modified: trunk/Makefile
===================================================================
--- trunk/Makefile	2007-09-06 22:42:06 UTC (rev 1170)
+++ trunk/Makefile	2007-09-07 21:27:01 UTC (rev 1171)
@@ -429,8 +429,8 @@
 
   BINEXT=.exe
 
-  LDFLAGS= -mwindows -lwsock32 -lwinmm
-  CLIENT_LDFLAGS = -lgdi32 -lole32 -lopengl32
+  LDFLAGS= -lwsock32 -lwinmm
+  CLIENT_LDFLAGS = -mwindows -lgdi32 -lole32 -lopengl32
 
   ifeq ($(USE_CURL),1)
     ifneq ($(USE_CURL_DLOPEN),1)

Modified: trunk/code/sys/con_win32.c
===================================================================
--- trunk/code/sys/con_win32.c	2007-09-06 22:42:06 UTC (rev 1170)
+++ trunk/code/sys/con_win32.c	2007-09-07 21:27:01 UTC (rev 1171)
@@ -22,7 +22,20 @@
 
 #include "../qcommon/q_shared.h"
 #include "../qcommon/qcommon.h"
+#include "windows.h"
 
+#define QCONSOLE_WIDTH 80
+#define QCONSOLE_HEIGHT 30
+
+#define QCONSOLE_THEME FOREGROUND_RED | \
+                       BACKGROUND_RED | \
+                       BACKGROUND_GREEN | \
+                       BACKGROUND_BLUE
+
+#define QCONSOLE_INPUT_RECORDS 1024
+
+static int qconsole_chars = 0;
+
 /*
 ==================
 CON_Hide
@@ -57,6 +70,31 @@
 */
 void CON_Init( void )
 {
+  SMALL_RECT win = { 0, 0, QCONSOLE_WIDTH-1, QCONSOLE_HEIGHT-1 };
+  HANDLE hout;
+  COORD screen = { 0, 0 };
+  DWORD written;
+  CONSOLE_SCREEN_BUFFER_INFO binfo;
+  SMALL_RECT rect;
+
+  SetConsoleTitle("ioquake3 Dedicated Server Console");
+
+  hout = GetStdHandle( STD_OUTPUT_HANDLE );
+
+  SetConsoleWindowInfo( hout, TRUE, &win );
+  SetConsoleTextAttribute( hout, QCONSOLE_THEME );
+  FillConsoleOutputAttribute( hout, QCONSOLE_THEME, 63999, screen, &written ); 
+  
+  // adjust console scroll to match up with cursor position  
+  GetConsoleScreenBufferInfo( hout, &binfo );
+  rect.Top = binfo.srWindow.Top;
+  rect.Left = binfo.srWindow.Left;
+  rect.Bottom = binfo.srWindow.Bottom;
+  rect.Right = binfo.srWindow.Right;
+  rect.Top += ( binfo.dwCursorPosition.Y - binfo.srWindow.Bottom ); 
+  rect.Bottom = binfo.dwCursorPosition.Y; 
+  SetConsoleWindowInfo( hout, TRUE, &rect );
+
 }
 
 /*
@@ -66,5 +104,161 @@
 */
 char *CON_ConsoleInput( void )
 {
-  return NULL;
+  HANDLE hin, hout;
+  INPUT_RECORD buff[ QCONSOLE_INPUT_RECORDS ];
+  DWORD count = 0;
+  int i;
+  static char input[ 1024 ] = { "" };
+  int inputlen;
+  int newlinepos = -1;
+  CHAR_INFO line[ QCONSOLE_WIDTH ];
+  int linelen = 0;
+
+  inputlen = 0;
+  input[ 0 ] = '\0';
+
+  hin = GetStdHandle( STD_INPUT_HANDLE );
+  if( hin == INVALID_HANDLE_VALUE )
+    return NULL;
+  hout = GetStdHandle( STD_OUTPUT_HANDLE );
+  if( hout == INVALID_HANDLE_VALUE )
+    return NULL;
+
+  if( !PeekConsoleInput( hin, buff, QCONSOLE_INPUT_RECORDS, &count ) )
+    return NULL;
+
+  // if we have overflowed, start dropping oldest input events
+  if( count == QCONSOLE_INPUT_RECORDS )
+  {
+    ReadConsoleInput( hin, buff, 1, &count );
+    return NULL;
+  } 
+
+  for( i = 0; i < count; i++ )
+  {
+    if( buff[ i ].EventType == KEY_EVENT &&
+        buff[ i ].Event.KeyEvent.bKeyDown )
+    {
+      if( buff[ i ].Event.KeyEvent.wVirtualKeyCode == VK_RETURN )
+      {
+        newlinepos = i;
+        break;
+      }
+
+      if( linelen < QCONSOLE_WIDTH &&
+          buff[ i ].Event.KeyEvent.uChar.AsciiChar )
+      {
+        if( buff[ i ].Event.KeyEvent.wVirtualKeyCode == VK_BACK )
+        {
+          if( linelen > 0 )
+            linelen--;
+            
+        }
+        else
+        {
+          line[ linelen ].Attributes =  QCONSOLE_THEME;
+          line[ linelen++ ].Char.AsciiChar =
+            buff[ i ].Event.KeyEvent.uChar.AsciiChar;
+        }
+      }
+    }
+  }
+
+  // provide visual feedback for incomplete commands
+  if( linelen != qconsole_chars )
+  {
+    CONSOLE_SCREEN_BUFFER_INFO binfo;
+    COORD writeSize = { QCONSOLE_WIDTH, 1 };
+    COORD writePos = { 0, 0 };
+    SMALL_RECT writeArea = { 0, 0, 0, 0 };
+    int i;
+
+    // keep track of this so we don't need to re-write to console every frame
+    qconsole_chars = linelen;
+
+    GetConsoleScreenBufferInfo( hout, &binfo );
+
+    // adjust scrolling to cursor when typing
+    if( binfo.dwCursorPosition.Y > binfo.srWindow.Bottom )
+    {
+      SMALL_RECT rect;
+
+      rect.Top = binfo.srWindow.Top;
+      rect.Left = binfo.srWindow.Left;
+      rect.Bottom = binfo.srWindow.Bottom;
+      rect.Right = binfo.srWindow.Right;
+
+      rect.Top += ( binfo.dwCursorPosition.Y - binfo.srWindow.Bottom ); 
+      rect.Bottom = binfo.dwCursorPosition.Y; 
+      
+      SetConsoleWindowInfo( hout, TRUE, &rect );
+      GetConsoleScreenBufferInfo( hout, &binfo );
+    }
+    
+    writeArea.Left = 0;
+    writeArea.Top = binfo.srWindow.Bottom; 
+    writeArea.Bottom = binfo.srWindow.Bottom; 
+    writeArea.Right = QCONSOLE_WIDTH;
+
+    // pad line with ' ' to handle VK_BACK
+    for( i = linelen; i < QCONSOLE_WIDTH; i++ )
+    {
+      line[ i ].Char.AsciiChar = ' '; 
+      line[ i ].Attributes =  QCONSOLE_THEME;
+    }
+
+    WriteConsoleOutput( hout, line, writeSize, writePos, &writeArea );
+
+    if( binfo.dwCursorPosition.X != linelen )
+    {
+      COORD cursorPos = { 0, 0 };
+
+      cursorPos.X = linelen;
+      cursorPos.Y = binfo.srWindow.Bottom;
+      SetConsoleCursorPosition( hout, cursorPos );
+    }
+  }
+
+  // don't touch the input buffer if this is an incomplete command
+  if( newlinepos < 0)
+  {
+    return NULL;
+  }
+  else
+  {
+    // add a newline
+    COORD cursorPos = { 0, 0 };
+    CONSOLE_SCREEN_BUFFER_INFO binfo;
+
+    GetConsoleScreenBufferInfo( hout, &binfo );
+    cursorPos.Y = binfo.srWindow.Bottom + 1;
+    SetConsoleCursorPosition( hout, cursorPos );
+  }
+
+
+  if( !ReadConsoleInput( hin, buff, newlinepos+1, &count ) )
+    return NULL;
+
+  for( i = 0; i < count; i++ )
+  {
+    if( buff[ i ].EventType == KEY_EVENT &&
+        buff[ i ].Event.KeyEvent.bKeyDown )
+    {
+      if( buff[ i ].Event.KeyEvent.wVirtualKeyCode == VK_BACK )
+      {
+        if( inputlen > 0 )
+          input[ --inputlen ] = '\0';
+        continue;
+      }
+      if( inputlen < ( sizeof( input ) - 1 ) &&
+          buff[ i ].Event.KeyEvent.uChar.AsciiChar )
+      {
+        input[ inputlen++ ] = buff[ i ].Event.KeyEvent.uChar.AsciiChar;
+        input[ inputlen ] = '\0'; 
+      }
+    }
+  }
+  if( !inputlen )
+    return NULL;
+  return input;
 }




More information about the quake3-commits mailing list