shithub: choc

Download patch

ref: d78780cfc3f4c5c601bc19ae7976c2ae26ac9495
parent: 8a6bdf645f50726000d2491cb52d41b69acd87a4
author: Simon Howard <[email protected]>
date: Fri Jan 13 18:56:00 EST 2006

Add text-mode I/O functions.
Use text-mode screen for the waiting screen.

Subversion-branch: /trunk/chocolate-doom
Subversion-revision: 291

--- a/src/d_main.c
+++ b/src/d_main.c
@@ -1,7 +1,7 @@
 // Emacs style mode select   -*- C++ -*- 
 //-----------------------------------------------------------------------------
 //
-// $Id: d_main.c 280 2006-01-10 22:14:13Z fraggle $
+// $Id: d_main.c 291 2006-01-13 23:56:00Z fraggle $
 //
 // Copyright(C) 1993-1996 Id Software, Inc.
 // Copyright(C) 2005 Simon Howard
@@ -22,6 +22,10 @@
 // 02111-1307, USA.
 //
 // $Log$
+// Revision 1.38  2006/01/13 23:56:00  fraggle
+// Add text-mode I/O functions.
+// Use text-mode screen for the waiting screen.
+//
 // Revision 1.37  2006/01/10 22:14:13  fraggle
 // Shut up compiler warnings
 //
@@ -166,7 +170,7 @@
 //-----------------------------------------------------------------------------
 
 
-static const char rcsid[] = "$Id: d_main.c 280 2006-01-10 22:14:13Z fraggle $";
+static const char rcsid[] = "$Id: d_main.c 291 2006-01-13 23:56:00Z fraggle $";
 
 #define	BGCOLOR		7
 #define	FGCOLOR		8
@@ -220,7 +224,6 @@
 #include "st_stuff.h"
 #include "am_map.h"
 #include "net_client.h"
-#include "net_gui.h"
 
 #include "p_setup.h"
 #include "r_local.h"
@@ -544,7 +547,9 @@
 	printf ("debug output to: %s\n",filename);
 	debugfile = fopen (filename,"w");
     }
-	
+
+    I_InitGraphics ();
+
     while (1)
     {
 	// frame syncronous IO operations
@@ -1589,10 +1594,6 @@
 
     printf ("ST_Init: Init status bar.\n");
     ST_Init ();
-
-    I_InitGraphics ();
-
-    NET_WaitForStart();
 
     // start the apropriate game based on parms
     p = M_CheckParm ("-record");
--- a/src/d_net.c
+++ b/src/d_net.c
@@ -1,7 +1,7 @@
 // Emacs style mode select   -*- C++ -*- 
 //-----------------------------------------------------------------------------
 //
-// $Id: d_net.c 250 2006-01-02 21:04:10Z fraggle $
+// $Id: d_net.c 291 2006-01-13 23:56:00Z fraggle $
 //
 // Copyright(C) 1993-1996 Id Software, Inc.
 // Copyright(C) 2005 Simon Howard
@@ -22,6 +22,10 @@
 // 02111-1307, USA.
 //
 // $Log$
+// Revision 1.16  2006/01/13 23:56:00  fraggle
+// Add text-mode I/O functions.
+// Use text-mode screen for the waiting screen.
+//
 // Revision 1.15  2006/01/02 21:04:10  fraggle
 // Create NET_SV_Shutdown function to shut down the server.  Call it
 // when quitting the game.  Print the IP of the server correctly when
@@ -85,7 +89,7 @@
 //-----------------------------------------------------------------------------
 
 
-static const char rcsid[] = "$Id: d_net.c 250 2006-01-02 21:04:10Z fraggle $";
+static const char rcsid[] = "$Id: d_net.c 291 2006-01-13 23:56:00Z fraggle $";
 
 
 #include "d_main.h"
@@ -99,6 +103,7 @@
 #include "doomstat.h"
 
 #include "net_client.h"
+#include "net_gui.h"
 #include "net_io.h"
 #include "net_server.h"
 #include "net_sdl.h"
@@ -650,6 +655,8 @@
         if (NET_CL_Connect(addr))
         {
             printf("connected to %s\n", NET_AddrToString(addr));
+
+            NET_WaitForStart();
         }
         else
         {
--- a/src/g_game.c
+++ b/src/g_game.c
@@ -1,7 +1,7 @@
 // Emacs style mode select   -*- C++ -*- 
 //-----------------------------------------------------------------------------
 //
-// $Id: g_game.c 237 2006-01-01 23:53:15Z fraggle $
+// $Id: g_game.c 291 2006-01-13 23:56:00Z fraggle $
 //
 // Copyright(C) 1993-1996 Id Software, Inc.
 // Copyright(C) 2005 Simon Howard
@@ -22,6 +22,10 @@
 // 02111-1307, USA.
 //
 // $Log$
+// Revision 1.19  2006/01/13 23:56:00  fraggle
+// Add text-mode I/O functions.
+// Use text-mode screen for the waiting screen.
+//
 // Revision 1.18  2006/01/01 23:53:15  fraggle
 // Remove GS_WAITINGSTART gamestate.  This will be independent of the main
 // loop to avoid interfering with the main game code too much.
@@ -98,7 +102,7 @@
 
 
 static const char
-rcsid[] = "$Id: g_game.c 237 2006-01-01 23:53:15Z fraggle $";
+rcsid[] = "$Id: g_game.c 291 2006-01-13 23:56:00Z fraggle $";
 
 #include <string.h>
 #include <stdlib.h>
@@ -108,8 +112,6 @@
 
 #include "deh_main.h"
 #include "deh_misc.h"
-
-#include "net_gui.h"
 
 #include "z_zone.h"
 #include "f_finale.h"
--- a/src/net_gui.c
+++ b/src/net_gui.c
@@ -1,7 +1,7 @@
 // Emacs style mode select   -*- C++ -*- 
 //-----------------------------------------------------------------------------
 //
-// $Id: net_gui.c 284 2006-01-12 02:11:52Z fraggle $
+// $Id: net_gui.c 291 2006-01-13 23:56:00Z fraggle $
 //
 // Copyright(C) 2005 Simon Howard
 //
@@ -21,6 +21,10 @@
 // 02111-1307, USA.
 //
 // $Log$
+// Revision 1.9  2006/01/13 23:56:00  fraggle
+// Add text-mode I/O functions.
+// Use text-mode screen for the waiting screen.
+//
 // Revision 1.8  2006/01/12 02:11:52  fraggle
 // Game start packets
 //
@@ -59,233 +63,103 @@
 //    start the game.
 //   
 
+#include <ctype.h>
+
+#include "config.h"
 #include "doomstat.h"
 
+#include "i_system.h"
+
 #include "net_client.h"
 #include "net_gui.h"
 #include "net_server.h"
 
-#include "d_event.h"
-#include "d_main.h"
-#include "i_system.h"
-#include "i_video.h"
-#include "m_menu.h"
-#include "m_random.h"
-#include "r_defs.h"
-#include "s_sound.h"
-#include "sounds.h"
-#include "v_video.h"
-#include "w_wad.h"
-#include "z_zone.h"
+#include "txt_main.h"
+#include "txt_gui.h"
+#include "txt_io.h"
 
-static patch_t *player_face;
-static patch_t *player_backdrops[4];
-static boolean have_music;
-
-extern void M_WriteText(int x, int y, char *string);
-
-static void Drawer(void)
+static void ProcessEvents(void)
 {
-    patch_t *backdrop;
-    int backdrop_lumpnum;
-    int i, y;
-
-    // Use INTERPIC or TITLEPIC if we don't have it
-
-    backdrop_lumpnum = W_CheckNumForName("INTERPIC");
-
-    if (backdrop_lumpnum < 0)
-    {
-        backdrop_lumpnum = W_CheckNumForName("TITLEPIC");
-    }
-
-    backdrop = (patch_t *) W_CacheLumpNum(backdrop_lumpnum, PU_CACHE);
-
-    // draw the backdrop
+    int c;
     
-    V_DrawPatch(0, 0, 0, backdrop);
-
-    // draw players
-
-    y = 100 - 16 * net_clients_in_game - 24;
-    
-    M_WriteText(32, y, "Players currently waiting:");
-
-    y += 24;
-
-    for (i=0; i<net_clients_in_game; ++i)
+    while ((c = TXT_GetChar()) > 0)
     {
-        V_DrawPatch(32, y, 0, player_backdrops[i]);
-
-        // draw the face to indicate which one we are
-
-        if (i == net_player_number)
+        switch (tolower(c))
         {
-            V_DrawPatch(32, y, 0, player_face);
+            case 27:
+            case 'q':
+                I_Quit();
+                break;
+
+            case ' ':
+                NET_CL_StartGame();
+                break;
         }
-        M_WriteText(80, y+12, net_player_names[i]);
-        M_WriteText(200, y+12, net_player_addresses[i]);
-        y += 32;
     }
-
-    y += 16;
-
-    if (net_client_controller)
-    {
-        M_WriteText(32, y, "Press space to start the game...");
-    }
-    else
-    {
-        M_WriteText(32, y, "Waiting for the game to start...");
-    }
 }
 
-// play some random music
+#define WINDOW_X 15
+#define WINDOW_Y 5
+#define WINDOW_W 50
+#define WINDOW_H 12
 
-static void RandomMusic(void)
+static void DrawScreen(void)
 {
-    musicenum_t mus;
+    char buf[40];
+    int i;
 
-    if (gamemode == commercial)
-    {
-        mus = mus_runnin + M_Random() % 32;
-    }
-    else if (gamemode == shareware)
-    {
-        mus = mus_e1m1 + M_Random() % 9;
-    } 
-    else 
-    {
-        mus = mus_e1m1 + M_Random() % 27;
-    }
-    
-    S_ChangeMusic(mus, 0);
+    TXT_DrawDesktop(PACKAGE_STRING);
+    TXT_DrawWindow("Waiting for game start...", 
+                    WINDOW_X, WINDOW_Y, 
+                    WINDOW_W, WINDOW_H);
 
-    // If music is not playing straight away, it is turned off.  Don't
-    // try to play any more music.
+    TXT_BGColor(TXT_COLOR_BLUE, 0);
+    TXT_FGColor(TXT_COLOR_BRIGHT_WHITE);
 
-    have_music = S_MusicPlaying();
-}
-
-static void ProcessEvents(void)
-{
-    event_t *ev;
-
-    while ((ev = D_PopEvent()) != NULL)
+    for (i=0; i<MAXPLAYERS; ++i)
     {
-        if (M_Responder(ev))
-        {
-            continue;
-        }
+        snprintf(buf, 39, "%i. ", i + 1);
+        TXT_GotoXY(WINDOW_X + 2, WINDOW_Y + 4 + i);
+        TXT_Puts(buf);
 
-        // process event ...
-        
-        if (ev->type == ev_keydown && ev->data1 == 'm')
+        if (i < net_clients_in_game)
         {
-            // Music change
+            snprintf(buf, 15, "%s", net_player_names[i]);
+            TXT_GotoXY(WINDOW_X + 5, WINDOW_Y + 4 + i);
+            TXT_Puts(buf);
 
-            RandomMusic();
+            snprintf(buf, 16, "%s", net_player_addresses[i]);
+            TXT_GotoXY(WINDOW_X + 33, WINDOW_Y + 4 + i);
+            TXT_Puts(buf);
         }
-        else if (ev->type == ev_keydown && ev->data1 == ' ')
-        {
-            // Start game
-
-            NET_CL_StartGame();
-        }
     }
-}
 
-static void NET_InitGUI(void)
-{
-    char buf[8];
-    int i;
+    TXT_GotoXY(WINDOW_X + 2, WINDOW_Y + WINDOW_H - 2);
+    TXT_Puts("%brightgreen%SPACE%/%%brightcyan%=%/%Start game");
 
-    player_face = W_CacheLumpName("STFST01", PU_STATIC);
+    TXT_GotoXY(WINDOW_X + WINDOW_W - 11, WINDOW_Y + WINDOW_H - 2);
+    TXT_Puts("%brightgreen%ESC%/%%brightcyan%=%/%Abort");
+    
+    TXT_DrawSeparator(WINDOW_X, WINDOW_Y + WINDOW_H - 3, WINDOW_W);
 
-    for (i=0 ; i<MAXPLAYERS ; i++)
-    {
-        sprintf(buf, "STPB%d", i);
-        player_backdrops[i] = W_CacheLumpName(buf, PU_STATIC);
-    }
+    TXT_UpdateScreen();
 }
 
-// Displays a graphical screen while waiting for the game to start.
-
 void NET_WaitForStart(void)
 {
-    int last_tic_time;
-    int nowtime;
-    int runtics;
-    int i;
+    TXT_Init();
 
-    if (!net_client_connected || !net_waiting_for_start)
-    {
-        return;
-    }
-
-    NET_InitGUI();
-
-    M_ClearRandom();
-
-    // play some soothing music while we wait
-
-    RandomMusic();
-
-    // cheap hack: pretend to be on a demo screen so the mouse wont 
-    // be grabbed
-
-    gamestate = GS_DEMOSCREEN;
-    
-    last_tic_time = I_GetTime();
-
     while (net_waiting_for_start)
     {
-        // Keyboard/mouse events, etc.
- 
-        I_StartTic();
         ProcessEvents();
+        DrawScreen();
 
-        // Run the menu, etc.
-
-        nowtime = I_GetTime();
-        runtics = nowtime - last_tic_time;
-
-        if (runtics > 0) 
-        {
-            for (i=0; i<runtics; ++i)
-            {
-                M_Ticker();
-            }
-
-            last_tic_time = nowtime;
-
-            // Draw the screen
-          
-            Drawer();
-            M_Drawer();
-            I_FinishUpdate();
-
-            // check if the music has finished - start another track!
-
-            if (have_music && !S_MusicPlaying())
-            {
-                RandomMusic();
-            }
-        }
-
-        // Network stuff
-
         NET_CL_Run();
         NET_SV_Run();
 
-        if (!net_client_connected)
-        {
-            I_Error("Disconnected from server");
-        }
-
-        // Don't hog the CPU
-
-        I_Sleep(10);
+        I_Sleep(50);
     }
+    
+    TXT_Shutdown();
 }
 
--- a/textscreen/Makefile.am
+++ b/textscreen/Makefile.am
@@ -3,6 +3,10 @@
 
 noinst_LIBRARIES=libtextscreen.a
 
-libtextscreen_a_SOURCES = txt_main.c txt_main.h txt_font.h
+libtextscreen_a_SOURCES =              \
+	txt_gui.c     txt_gui.h        \
+	txt_io.c      txt_io.h         \
+	txt_main.c    txt_main.h       \
+	txt_font.h
 
 
--- /dev/null
+++ b/textscreen/txt_gui.c
@@ -1,0 +1,188 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: txt_gui.c 291 2006-01-13 23:56:00Z fraggle $
+//
+// Copyright(C) 1993-1996 Id Software, Inc.
+// Copyright(C) 2005 Simon Howard
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+// $Log$
+// Revision 1.1  2006/01/13 23:56:00  fraggle
+// Add text-mode I/O functions.
+// Use text-mode screen for the waiting screen.
+//
+//
+
+#include <string.h>
+
+#include "txt_io.h"
+#include "txt_main.h"
+
+// Array of border characters for drawing windows. The array looks like this:
+//
+// +-++
+// | ||
+// +-++
+// +-++
+
+static int borders[4][4] = 
+{
+    {0xda, 0xc4, 0xc2, 0xbf},
+    {0xb3, ' ',  0xb3, 0xb3},
+    {0xc3, 0xc4, 0xc5, 0xb4},
+    {0xc0, 0xc4, 0xc1, 0xd9},
+};
+
+void TXT_DrawDesktop(char *title)
+{
+    int i;
+    unsigned char *screendata;
+    unsigned char *p;
+
+    screendata = TXT_GetScreenData();
+    
+    // Fill the screen with gradient characters
+
+    p = screendata;
+    
+    for (i=0; i<TXT_SCREEN_W * TXT_SCREEN_H; ++i)
+    {
+        *p++ = 0xb1;
+        *p++ = TXT_COLOR_GREY | (TXT_COLOR_BLUE << 4);
+    }
+
+    // Draw the top and bottom banners
+
+    p = screendata;
+
+    for (i=0; i<TXT_SCREEN_W; ++i)
+    {
+        *p++ = ' ';
+        *p++ = TXT_COLOR_BLACK | (TXT_COLOR_GREY << 4);
+    }
+
+    p = screendata + (TXT_SCREEN_H - 1) * TXT_SCREEN_W * 2;
+
+    for (i=0; i<TXT_SCREEN_W; ++i)
+    {
+        *p++ = ' ';
+        *p++ = TXT_COLOR_BLACK | (TXT_COLOR_GREY << 4);
+    }
+
+    // Print the title
+
+    TXT_GotoXY(0, 0);
+    TXT_FGColor(TXT_COLOR_BLACK);
+    TXT_BGColor(TXT_COLOR_GREY, 0);
+
+    TXT_PutChar(' ');
+    TXT_Puts(title);
+}
+
+void TXT_DrawShadow(int x, int y, int w, int h)
+{
+    unsigned char *screendata;
+    unsigned char *p;
+    int x1, y1;
+
+    screendata = TXT_GetScreenData();
+
+    for (y1=y; y1<y+h; ++y1)
+    {
+        p = screendata + y1 * TXT_SCREEN_W * 2 + x * 2;
+
+        for (x1=0; x1<w; ++x1)
+        {
+            p[1] = TXT_COLOR_DARK_GREY;
+            p += 2;
+        }
+    }
+}
+
+void TXT_DrawWindow(char *title, int x, int y, int w, int h)
+{
+    int x1, y1;
+    int bx, by;
+
+    TXT_FGColor(TXT_COLOR_BRIGHT_CYAN);
+    TXT_BGColor(TXT_COLOR_BLUE, 0);
+
+    for (y1=y; y1<y+h; ++y1)
+    {
+        TXT_GotoXY(x, y1);
+
+        // Select the appropriate row and column in the borders
+        // array to pick the appropriate character to draw at
+        // this location.
+        //
+        // Draw a horizontal line on the third line down, so we
+        // draw a box around the title.
+
+        by = y1 == y ? 0 :
+             y1 == y + 2 ? 2 :
+             y1 == y + h - 1 ? 3 : 1;
+
+        for (x1=x; x1<x+w; ++x1)
+        {
+            bx = x1 == x ? 0 :
+                 x1 == x + w - 1 ? 3 : 1;
+                 
+            TXT_PutChar(borders[by][bx]);
+        }
+    }
+
+    // Draw the title
+
+    TXT_GotoXY(x + 1, y + 1);
+    TXT_BGColor(TXT_COLOR_GREY, 0);
+    TXT_FGColor(TXT_COLOR_BLUE);
+
+    for (x1=0; x1<w-2; ++x1)
+    {
+        TXT_PutChar(' ');
+    }
+
+    TXT_GotoXY(x + (w - strlen(title)) / 2, y + 1);
+    TXT_Puts(title);
+
+    // Draw the window's shadow.
+
+    TXT_DrawShadow(x + 2, y + h, w, 1);
+    TXT_DrawShadow(x + w, y + 1, 2, h);
+}
+
+void TXT_DrawSeparator(int x, int y, int w)
+{
+    int x1;
+    int c;
+
+    TXT_FGColor(TXT_COLOR_BRIGHT_CYAN);
+    TXT_BGColor(TXT_COLOR_BLUE, 0);
+
+    for (x1=x; x1<x+w; ++x1)
+    {
+        TXT_GotoXY(x1, y);
+
+        c = x1 == x ? borders[2][0] :
+            x1 == x + w - 1 ? borders[2][3] :
+            borders[2][1];
+
+        TXT_PutChar(c);
+    }
+}
+
--- /dev/null
+++ b/textscreen/txt_gui.h
@@ -1,0 +1,50 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: txt_gui.h 291 2006-01-13 23:56:00Z fraggle $
+//
+// Copyright(C) 1993-1996 Id Software, Inc.
+// Copyright(C) 2005 Simon Howard
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+// $Log$
+// Revision 1.1  2006/01/13 23:56:00  fraggle
+// Add text-mode I/O functions.
+// Use text-mode screen for the waiting screen.
+//
+// Revision 1.2  2006/01/13 18:23:28  fraggle
+// Textscreen getchar() function; remove SDL code from I_Endoom.
+//
+// Revision 1.1  2005/10/02 03:16:03  fraggle
+// Text mode emulation code
+//
+//
+//-----------------------------------------------------------------------------
+//
+// Text mode emulation in SDL
+//
+//-----------------------------------------------------------------------------
+
+#ifndef TXT_GUI_H
+#define TXT_GUI_H
+
+void TXT_DrawDesktop(char *title);
+void TXT_DrawWindow(char *title, int x, int y, int w, int h);
+void TXT_DrawSeparator(int x, int y, int w);
+
+#endif /* #ifndef TXT_GUI_H */
+
--- /dev/null
+++ b/textscreen/txt_io.c
@@ -1,0 +1,260 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: txt_io.c 291 2006-01-13 23:56:00Z fraggle $
+//
+// Copyright(C) 1993-1996 Id Software, Inc.
+// Copyright(C) 2005 Simon Howard
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+// $Log$
+// Revision 1.1  2006/01/13 23:56:00  fraggle
+// Add text-mode I/O functions.
+// Use text-mode screen for the waiting screen.
+//
+//
+//-----------------------------------------------------------------------------
+//
+// Text mode I/O functions, similar to C stdio
+//
+//-----------------------------------------------------------------------------
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "txt_io.h"
+#include "txt_main.h"
+
+static struct 
+{
+    txt_color_t color;
+    char *name;
+} colors[] = {
+    {TXT_COLOR_BLACK,           "black"},
+    {TXT_COLOR_BLUE,            "blue"},
+    {TXT_COLOR_GREEN,           "green"},
+    {TXT_COLOR_CYAN,            "cyan"},
+    {TXT_COLOR_RED,             "red"},
+    {TXT_COLOR_MAGENTA,         "magenta"},
+    {TXT_COLOR_BROWN,           "brown"},
+    {TXT_COLOR_GREY,            "grey"},
+    {TXT_COLOR_DARK_GREY,       "darkgrey"},
+    {TXT_COLOR_BRIGHT_BLUE,     "brightblue"},
+    {TXT_COLOR_BRIGHT_GREEN,    "brightgreen"},
+    {TXT_COLOR_BRIGHT_CYAN,     "brightcyan"},
+    {TXT_COLOR_BRIGHT_RED,      "brightred"},
+    {TXT_COLOR_BRIGHT_MAGENTA,  "brightmagenta"},
+    {TXT_COLOR_YELLOW,          "yellow"},
+    {TXT_COLOR_BRIGHT_WHITE,    "brightwhite"},
+};
+
+static int cur_x = 0, cur_y = 0;
+static txt_color_t fgcolor = TXT_COLOR_GREY;
+static txt_color_t bgcolor = TXT_COLOR_BLACK;
+
+static int GetColorForName(char *s)
+{
+    int i;
+
+    for (i=0; i<sizeof(colors) / sizeof(*colors); ++i)
+    {
+        if (!strcmp(s, colors[i].name))
+        {
+            return colors[i].color;
+        }
+    }
+
+    return -1;
+}
+
+static void NewLine(unsigned char *screendata)
+{
+    int i;
+    unsigned char *p;
+
+    cur_x = 0;
+    ++cur_y;
+
+    if (cur_y >= TXT_SCREEN_H)
+    {
+        // Scroll the screen up
+
+        cur_y = TXT_SCREEN_H - 1;
+
+        memcpy(screendata, screendata + TXT_SCREEN_W * 2,
+               TXT_SCREEN_W * 2 * (TXT_SCREEN_H -1));
+
+        // Clear the bottom line
+
+        p = screendata + (TXT_SCREEN_H - 1) * 2 * TXT_SCREEN_W;
+
+        for (i=0; i<TXT_SCREEN_W; ++i) 
+        {
+            *p++ = ' ';
+            *p++ = fgcolor | (bgcolor << 4);
+        }
+    }
+}
+
+static void PutChar(unsigned char *screendata, int c)
+{
+    unsigned char *p;
+   
+    p = screendata + cur_y * TXT_SCREEN_W * 2 +  cur_x * 2;
+
+    switch (c)
+    {
+        case '\n':
+            NewLine(screendata);
+            break;
+
+        case '\b':
+            // backspace
+            --cur_x;
+            if (cur_x < 0)
+                cur_x = 0;
+            break;
+
+        default:
+
+            // Add a new character to the buffer
+
+            p[0] = c;
+            p[1] = fgcolor | (bgcolor << 4);
+
+            ++cur_x;
+
+            if (cur_x >= TXT_SCREEN_W) 
+            {
+                NewLine(screendata);
+            }
+
+            break;
+    }
+}
+
+void TXT_PutChar(int c)
+{
+    unsigned char *screen;
+
+    screen = TXT_GetScreenData();
+
+    PutChar(screen, c);
+}
+
+void TXT_Puts(char *s)
+{
+    int previous_color = TXT_COLOR_BLACK;
+    unsigned char *screen;
+    char *p;
+    char colorname_buf[20];
+    char *ending;
+    int col;
+
+    screen = TXT_GetScreenData();
+
+    for (p=s; *p != '\0'; ++p)
+    {
+        if (*p == '%')
+        {
+            ++p;
+
+            if (*p == '%')
+            {
+                PutChar(screen, '%');
+            }
+            else
+            {
+                ending = strchr(p, '%');
+
+                if (ending == NULL)
+                {
+                    return;
+                }
+
+                strncpy(colorname_buf, p, 19);
+                colorname_buf[ending-p] = '\0';
+
+                if (!strcmp(colorname_buf, "/"))
+                {
+                    // End of color block
+
+                    col = previous_color;
+                }
+                else
+                {
+                    col = GetColorForName(colorname_buf);
+
+                    if (col < 0)
+                    {
+                        return;
+                    }
+
+                    // Save the color for the ending marker
+
+                    previous_color = fgcolor;
+                }
+
+                TXT_FGColor(col);
+                
+                p = ending;
+            }
+        }
+        else
+        {
+            PutChar(screen, *p);
+        }
+    }
+
+    PutChar(screen, '\n');
+}
+
+void TXT_GotoXY(int x, int y)
+{
+    cur_x = x;
+    cur_y = y;
+}
+
+void TXT_FGColor(txt_color_t color)
+{
+    fgcolor = color;
+}
+
+void TXT_BGColor(int color, int blinking)
+{
+    bgcolor = color;
+    if (blinking)
+        bgcolor |= TXT_COLOR_BLINKING;
+}
+
+void TXT_ClearScreen(void)
+{
+    unsigned char *screen;
+    int i;
+
+    screen = TXT_GetScreenData();
+
+    for (i=0; i<TXT_SCREEN_W * TXT_SCREEN_H; ++i)
+    {
+        screen[i * 2] = ' ';
+        screen[i * 2 +  1] = (bgcolor << 4) | fgcolor;
+    }
+
+    cur_x = 0;
+    cur_y = 0;
+}
+
--- /dev/null
+++ b/textscreen/txt_io.h
@@ -1,0 +1,55 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: txt_io.h 291 2006-01-13 23:56:00Z fraggle $
+//
+// Copyright(C) 1993-1996 Id Software, Inc.
+// Copyright(C) 2005 Simon Howard
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+// $Log$
+// Revision 1.1  2006/01/13 23:56:00  fraggle
+// Add text-mode I/O functions.
+// Use text-mode screen for the waiting screen.
+//
+// Revision 1.2  2006/01/13 18:23:28  fraggle
+// Textscreen getchar() function; remove SDL code from I_Endoom.
+//
+// Revision 1.1  2005/10/02 03:16:03  fraggle
+// Text mode emulation code
+//
+//
+//-----------------------------------------------------------------------------
+//
+// Text mode emulation in SDL
+//
+//-----------------------------------------------------------------------------
+
+#ifndef TXT_IO_H
+#define TXT_IO_H
+
+#include "txt_main.h"
+
+void TXT_PutChar(int c);
+void TXT_Puts(char *s);
+void TXT_GotoXY(int x, int y);
+void TXT_FGColor(txt_color_t color);
+void TXT_BGColor(int color, int blinking);
+void TXT_ClearScreen(void);
+
+#endif /* #ifndef TXT_IO_H */
+
--- a/textscreen/txt_main.c
+++ b/textscreen/txt_main.c
@@ -1,7 +1,7 @@
 // Emacs style mode select   -*- C++ -*- 
 //-----------------------------------------------------------------------------
 //
-// $Id: txt_main.c 289 2006-01-13 18:23:28Z fraggle $
+// $Id: txt_main.c 291 2006-01-13 23:56:00Z fraggle $
 //
 // Copyright(C) 1993-1996 Id Software, Inc.
 // Copyright(C) 2005 Simon Howard
@@ -22,6 +22,10 @@
 // 02111-1307, USA.
 //
 // $Log$
+// Revision 1.5  2006/01/13 23:56:00  fraggle
+// Add text-mode I/O functions.
+// Use text-mode screen for the waiting screen.
+//
 // Revision 1.4  2006/01/13 18:23:28  fraggle
 // Textscreen getchar() function; remove SDL code from I_Endoom.
 //
@@ -90,6 +94,7 @@
         return 0;
 
     SDL_SetColors(screen, ega_colors, 0, 16);
+    SDL_EnableUNICODE(1);
 
     screendata = malloc(TXT_SCREEN_W * TXT_SCREEN_H * 2);
     memset(screendata, 0, TXT_SCREEN_W * TXT_SCREEN_H * 2);