shithub: choc

Download patch

ref: 9e82bacdd27648d9494b8d1e13c3c7e7245ece8f
parent: 0c880455f09096938c08fd232bc417c87d388f8a
author: James Haley <[email protected]>
date: Sat Sep 18 23:39:59 EDT 2010

Massive work on the HUD. Multiline messages now work properly and are
wrapped at or near the screen boundary.

Subversion-branch: /branches/strife-branch
Subversion-revision: 2113

--- a/src/m_controls.c
+++ b/src/m_controls.c
@@ -256,6 +256,9 @@
 
 void M_BindStrifeControls(void)
 {
+    // These are shared with all games, but have different defaults:
+    key_message_refresh = '/';
+
     // These keys are shared with Heretic/Hexen but have different defaults:
     key_jump     = 'a';
     key_lookup   = KEY_PGUP;
--- a/src/strife/d_main.c
+++ b/src/strife/d_main.c
@@ -1225,7 +1225,7 @@
 // haleyjd 08/28/10: Clip patches to the framebuffer without errors.
 // Returns false if V_DrawPatch should return without drawing.
 //
-static boolean D_PatchClipCallback(patch_t *patch, int x, int y)
+boolean D_PatchClipCallback(patch_t *patch, int x, int y)
 {
     // note that offsets were already accounted for in V_DrawPatch
     return (x >= 0 && y >= 0 
--- a/src/strife/d_main.h
+++ b/src/strife/d_main.h
@@ -58,6 +58,5 @@
 extern  boolean         stonecold;      // villsa [STRIFE]
 extern  boolean         workparm;       // villsa [STRIFE]
 
-
 #endif
 
--- a/src/strife/hu_lib.c
+++ b/src/strife/hu_lib.c
@@ -35,6 +35,7 @@
 #include "hu_lib.h"
 #include "r_local.h"
 #include "r_draw.h"
+#include "hu_stuff.h" // [STRIFE]
 
 // boolean : whether the screen is always erased
 #define noterased viewwindowx
@@ -41,10 +42,75 @@
 
 extern boolean	automapactive;	// in AM_map.c
 
+extern boolean D_PatchClipCallback(patch_t *patch, int x, int y); // [STRIFE]
+
+extern patch_t* yfont[HU_FONTSIZE];   // haleyjd 09/18/10: [STRIFE]
+
+//
+// HUlib_drawYellowText
+//
+// haleyjd 09/18/10: [STRIFE] New function.
+//
+void HUlib_drawYellowText(int x, int y, char *text)
+{
+    int start_x = x;
+    char *rover = text;
+    char c;
+
+    while((c = *rover++))
+    {
+        if(c == '\n')
+        {
+            x = start_x;
+            y += 12;
+        }
+        else if(c == '_' || c != ' ' || x != start_x)
+        {
+            c = toupper(c) - HU_FONTSTART;
+
+            if(c >= 0 && c < HU_FONTSIZE)
+            {
+                patch_t *patch = yfont[c];
+                int      width = SHORT(patch->width);
+
+                if(x + width <= (SCREENWIDTH - 20))
+                {
+                    // haleyjd: STRIFE-TODO: bit different than the exe... for now
+                    if(!D_PatchClipCallback(patch, x + SHORT(patch->leftoffset),
+                                                   y + SHORT(patch->topoffset)))
+                        return;
+                    V_DrawPatchDirect(x, y, patch);
+                    x = x + width;
+                }
+                else
+                {
+                    x = start_x;
+                    --rover;
+                    y += 12;
+                }
+            }
+            else
+            {
+                x += 4;
+            }
+        }
+    }
+}
+
+//
+// HUlib_init
+//
+// [STRIFE] Verified unmodified.
+//
 void HUlib_init(void)
 {
 }
 
+//
+// HUlib_clearTextLine
+// 
+// [STRIFE] Verified unmodified.
+//
 void HUlib_clearTextLine(hu_textline_t* t)
 {
     t->len = 0;
@@ -52,13 +118,18 @@
     t->needsupdate = true;
 }
 
+//
+// HUlib_initTextLine
+//
+// [STRIFE] Verified unmodified
+//
 void
 HUlib_initTextLine
-( hu_textline_t*	t,
-  int			x,
-  int			y,
-  patch_t**		f,
-  int			sc )
+( hu_textline_t*        t,
+  int                   x,
+  int                   y,
+  patch_t**             f,
+  int                   sc )
 {
     t->x = x;
     t->y = y;
@@ -67,87 +138,101 @@
     HUlib_clearTextLine(t);
 }
 
+//
+// HUlib_addCharToTextLine
+//
+// [STRIFE] Verified unmodified.
+//
 boolean
 HUlib_addCharToTextLine
-( hu_textline_t*	t,
-  char			ch )
+( hu_textline_t*        t,
+  char                  ch )
 {
-
     if (t->len == HU_MAXLINELENGTH)
-	return false;
+        return false;
     else
     {
-	t->l[t->len++] = ch;
-	t->l[t->len] = 0;
-	t->needsupdate = 4;
-	return true;
+        t->l[t->len++] = ch;
+        t->l[t->len] = 0;
+        t->needsupdate = 4;
+        return true;
     }
-
 }
 
+//
+// HUlib_delCharFromTextLine
+//
+// [STRIFE] Verified unmodified.
+//
 boolean HUlib_delCharFromTextLine(hu_textline_t* t)
 {
-
     if (!t->len) return false;
     else
     {
-	t->l[--t->len] = 0;
-	t->needsupdate = 4;
-	return true;
+        t->l[--t->len] = 0;
+        t->needsupdate = 4;
+        return true;
     }
-
 }
 
+//
+// HUlib_drawTextLine
+//
+// haleyjd 09/18/10: [STRIFE] Modified to not draw underscores in text.
+//
 void
 HUlib_drawTextLine
-( hu_textline_t*	l,
-  boolean		drawcursor )
+( hu_textline_t*        l,
+  boolean               drawcursor )
 {
+    int                 i;
+    int                 w;
+    int                 x;
+    unsigned char       c;
 
-    int			i;
-    int			w;
-    int			x;
-    unsigned char	c;
-
     // draw the new stuff
     x = l->x;
-    for (i=0;i<l->len;i++)
+
+    for(i = 0; i < l->len; i++)
     {
-	c = toupper(l->l[i]);
-	if (c != ' '
-	    && c >= l->sc
-	    && c <= '_')
-	{
-	    w = SHORT(l->f[c - l->sc]->width);
-	    if (x+w > SCREENWIDTH)
-		break;
-	    V_DrawPatchDirect(x, l->y, l->f[c - l->sc]);
-	    x += w;
-	}
-	else
-	{
-	    x += 4;
-	    if (x >= SCREENWIDTH)
-		break;
-	}
+        c = toupper(l->l[i]);
+        if (c != ' ' && c >= l->sc && c < '_') // [STRIFE]: Underscores excluded
+        {
+            w = SHORT(l->f[c - l->sc]->width);
+            if (x+w > SCREENWIDTH)
+                break;
+            V_DrawPatchDirect(x, l->y, l->f[c - l->sc]);
+            x += w;
+        }
+        else
+        {
+            x += 4;
+            if (x >= SCREENWIDTH)
+                break;
+        }
     }
 
     // draw the cursor if requested
     if (drawcursor
-	&& x + SHORT(l->f['_' - l->sc]->width) <= SCREENWIDTH)
+        && x + SHORT(l->f['_' - l->sc]->width) <= SCREENWIDTH)
     {
-	V_DrawPatchDirect(x, l->y, l->f['_' - l->sc]);
+        V_DrawPatchDirect(x, l->y, l->f['_' - l->sc]);
     }
 }
 
-
+//
+// HUlib_eraseTextLine
+//
 // sorta called by HU_Erase and just better darn get things straight
+// 
+// [STRIFE] Verified unmodified.
+//
 void HUlib_eraseTextLine(hu_textline_t* l)
 {
-    int			lh;
-    int			y;
-    int			yoffset;
-    static boolean	lastautomapactive = true;
+    int                 lh;
+    int                 y;
+    int                 yoffset;
+    static boolean      lastautomapactive = true;
 
     // Only erases when NOT in automap and the screen is reduced,
     // and the text must either need updating or refreshing
@@ -154,38 +239,41 @@
     // (because of a recent change back from the automap)
 
     if (!automapactive &&
-	viewwindowx && l->needsupdate)
+        viewwindowx && l->needsupdate)
     {
-	lh = SHORT(l->f[0]->height) + 1;
-	for (y=l->y,yoffset=y*SCREENWIDTH ; y<l->y+lh ; y++,yoffset+=SCREENWIDTH)
-	{
-	    if (y < viewwindowy || y >= viewwindowy + viewheight)
-		R_VideoErase(yoffset, SCREENWIDTH); // erase entire line
-	    else
-	    {
-		R_VideoErase(yoffset, viewwindowx); // erase left border
-		R_VideoErase(yoffset + viewwindowx + viewwidth, viewwindowx);
-		// erase right border
-	    }
-	}
+        lh = SHORT(l->f[0]->height) + 1;
+        for (y=l->y,yoffset=y*SCREENWIDTH ; y<l->y+lh ; y++,yoffset+=SCREENWIDTH)
+        {
+            if (y < viewwindowy || y >= viewwindowy + viewheight)
+                R_VideoErase(yoffset, SCREENWIDTH); // erase entire line
+            else
+            {
+                R_VideoErase(yoffset, viewwindowx); // erase left border
+                R_VideoErase(yoffset + viewwindowx + viewwidth, viewwindowx);
+                // erase right border
+            }
+        }
     }
 
     lastautomapactive = automapactive;
     if (l->needsupdate) l->needsupdate--;
-
 }
 
+//
+// HUlib_initSText
+//
+// [STRIFE] Verified unmodified.
+//
 void
 HUlib_initSText
-( hu_stext_t*	s,
-  int		x,
-  int		y,
-  int		h,
-  patch_t**	font,
-  int		startchar,
-  boolean*	on )
+( hu_stext_t*   s,
+  int           x,
+  int           y,
+  int           h,
+  patch_t**     font,
+  int           startchar,
+  boolean*      on )
 {
-
     int i;
 
     s->h = h;
@@ -193,28 +281,37 @@
     s->laston = true;
     s->cl = 0;
     for (i=0;i<h;i++)
-	HUlib_initTextLine(&s->l[i],
-			   x, y - i*(SHORT(font[0]->height)+1),
-			   font, startchar);
-
+    {
+        HUlib_initTextLine(&s->l[i],
+                           x, y - i*(SHORT(font[0]->height)+1),
+                           font, startchar);
+    }
 }
 
+//
+// HUlib_addLineToSText
+//
+// [STRIFE] Verified unmodified.
+//
 void HUlib_addLineToSText(hu_stext_t* s)
 {
-
     int i;
 
     // add a clear line
     if (++s->cl == s->h)
-	s->cl = 0;
+        s->cl = 0;
     HUlib_clearTextLine(&s->l[s->cl]);
 
     // everything needs updating
     for (i=0 ; i<s->h ; i++)
-	s->l[i].needsupdate = 4;
-
+        s->l[i].needsupdate = 4;
 }
 
+//
+// HUlib_addMessageToSText
+//
+// [STRIFE] Verified unmodified.
+//
 void
 HUlib_addMessageToSText
 ( hu_stext_t*	s,
@@ -223,13 +320,18 @@
 {
     HUlib_addLineToSText(s);
     if (prefix)
-	while (*prefix)
-	    HUlib_addCharToTextLine(&s->l[s->cl], *(prefix++));
+        while (*prefix)
+            HUlib_addCharToTextLine(&s->l[s->cl], *(prefix++));
 
     while (*msg)
-	HUlib_addCharToTextLine(&s->l[s->cl], *(msg++));
+        HUlib_addCharToTextLine(&s->l[s->cl], *(msg++));
 }
 
+//
+// HUlib_drawSText
+//
+// [STRIFE] Verified unmodified.
+//
 void HUlib_drawSText(hu_stext_t* s)
 {
     int i, idx;
@@ -236,46 +338,53 @@
     hu_textline_t *l;
 
     if (!*s->on)
-	return; // if not on, don't draw
+        return; // if not on, don't draw
 
     // draw everything
     for (i=0 ; i<s->h ; i++)
     {
-	idx = s->cl - i;
-	if (idx < 0)
-	    idx += s->h; // handle queue of lines
-	
-	l = &s->l[idx];
+        idx = s->cl - i;
+        if (idx < 0)
+            idx += s->h; // handle queue of lines
 
-	// need a decision made here on whether to skip the draw
-	HUlib_drawTextLine(l, false); // no cursor, please
-    }
+        l = &s->l[idx];
 
+        // need a decision made here on whether to skip the draw
+        HUlib_drawTextLine(l, false); // no cursor, please
+    }
 }
 
+//
+// HUlib_eraseSText
+//
+// [STRIFE] Verified unmodified.
+//
 void HUlib_eraseSText(hu_stext_t* s)
 {
-
     int i;
 
     for (i=0 ; i<s->h ; i++)
     {
-	if (s->laston && !*s->on)
-	    s->l[i].needsupdate = 4;
-	HUlib_eraseTextLine(&s->l[i]);
+        if (s->laston && !*s->on)
+            s->l[i].needsupdate = 4;
+        HUlib_eraseTextLine(&s->l[i]);
     }
     s->laston = *s->on;
-
 }
 
+//
+// HUlib_initIText
+//
+// [STRIFE] Verified unmodified.
+//
 void
 HUlib_initIText
-( hu_itext_t*	it,
-  int		x,
-  int		y,
-  patch_t**	font,
-  int		startchar,
-  boolean*	on )
+( hu_itext_t*   it,
+  int           x,
+  int           y,
+  patch_t**     font,
+  int           startchar,
+  boolean*      on )
 {
     it->lm = 0; // default left margin is start of text
     it->on = on;
@@ -285,19 +394,22 @@
 
 
 // The following deletion routines adhere to the left margin restriction
+// [STRIFE] Verified unmodified.
 void HUlib_delCharFromIText(hu_itext_t* it)
 {
     if (it->l.len != it->lm)
-	HUlib_delCharFromTextLine(&it->l);
+        HUlib_delCharFromTextLine(&it->l);
 }
 
+// [STRIFE] Verified unmodified.
 void HUlib_eraseLineFromIText(hu_itext_t* it)
 {
     while (it->lm != it->l.len)
-	HUlib_delCharFromTextLine(&it->l);
+        HUlib_delCharFromTextLine(&it->l);
 }
 
 // Resets left margin as well
+// [STRIFE] Verified unmodified.
 void HUlib_resetIText(hu_itext_t* it)
 {
     it->lm = 0;
@@ -304,18 +416,24 @@
     HUlib_clearTextLine(&it->l);
 }
 
+//
+// HUlib_addPrefixToIText
+//
+// [STRIFE] Verified unmodified.
+//
 void
 HUlib_addPrefixToIText
-( hu_itext_t*	it,
-  char*		str )
+( hu_itext_t*   it,
+  char*         str )
 {
     while (*str)
-	HUlib_addCharToTextLine(&it->l, *(str++));
+        HUlib_addCharToTextLine(&it->l, *(str++));
     it->lm = it->l.len;
 }
 
 // wrapper function for handling general keyed input.
 // returns true if it ate the key
+// [STRIFE] Verified unmodified.
 boolean
 HUlib_keyInIText
 ( hu_itext_t*	it,
@@ -324,33 +442,38 @@
     ch = toupper(ch);
 
     if (ch >= ' ' && ch <= '_') 
-  	HUlib_addCharToTextLine(&it->l, (char) ch);
-    else 
-	if (ch == KEY_BACKSPACE) 
-	    HUlib_delCharFromIText(it);
-	else 
-	    if (ch != KEY_ENTER) 
-		return false; // did not eat key
+        HUlib_addCharToTextLine(&it->l, (char) ch);
+    else if (ch == KEY_BACKSPACE) 
+        HUlib_delCharFromIText(it);
+    else if (ch != KEY_ENTER) 
+        return false; // did not eat key
 
     return true; // ate the key
-
 }
 
+//
+// HUlib_drawIText
+//
+// [STRIFE] Verified unmodified.
+//
 void HUlib_drawIText(hu_itext_t* it)
 {
-
     hu_textline_t *l = &it->l;
 
     if (!*it->on)
-	return;
+        return;
     HUlib_drawTextLine(l, true); // draw the line w/ cursor
-
 }
 
+//
+// HUlib_eraseIText
+//
+// [STRIFE] Verified unmodified.
+//
 void HUlib_eraseIText(hu_itext_t* it)
 {
     if (it->laston && !*it->on)
-	it->l.needsupdate = 4;
+        it->l.needsupdate = 4;
     HUlib_eraseTextLine(&it->l);
     it->laston = *it->on;
 }
--- a/src/strife/hu_stuff.c
+++ b/src/strife/hu_stuff.c
@@ -51,21 +51,19 @@
 //
 // Locally used constants, shortcuts.
 //
-#define HU_TITLE	(mapnames[gamemap-1])
-#define HU_TITLEHEIGHT	1
-#define HU_TITLEX	0
+#define HU_TITLE        (mapnames[gamemap-1])
+#define HU_TITLEHEIGHT  1
+#define HU_TITLEX       0
 
 // haleyjd 09/01/10: [STRIFE] 167 -> 160 to move up level name
-#define HU_TITLEY	(160 - SHORT(hu_font[0]->height))
+#define HU_TITLEY       (160 - SHORT(hu_font[0]->height))
 
-#define HU_INPUTTOGGLE	't'
-#define HU_INPUTX	HU_MSGX
-#define HU_INPUTY	(HU_MSGY + HU_MSGHEIGHT*(SHORT(hu_font[0]->height) +1))
-#define HU_INPUTWIDTH	64
-#define HU_INPUTHEIGHT	1
+#define HU_INPUTTOGGLE  't'
+#define HU_INPUTX       HU_MSGX
+#define HU_INPUTY       (HU_MSGY + HU_MSGHEIGHT*(SHORT(hu_font[0]->height) +1))
+#define HU_INPUTWIDTH   64
+#define HU_INPUTHEIGHT  1
 
-
-
 char *chat_macros[10] =
 {
     HUSTR_CHATMACRO0,
@@ -81,7 +79,7 @@
 };
 
 // villsa [STRIFE]
-char* pnameprefixes[][16] =
+char pnameprefixes[8][16] =
 {
     "1: ",
     "2: ",
@@ -101,28 +99,31 @@
     HUSTR_PLRRED
 };
 
-char			chat_char; // remove later.
-static player_t*	plr;
-patch_t*		hu_font[HU_FONTSIZE];
-static hu_textline_t	w_title;
-boolean			chat_on;
-static hu_itext_t	w_chat;
-static boolean		always_off = false;
-static char		chat_dest[MAXPLAYERS];
-static hu_itext_t w_inputbuffer[MAXPLAYERS];
+char                    chat_char; // remove later.
+static player_t*        plr;
+patch_t*                hu_font[HU_FONTSIZE];
+patch_t*                yfont[HU_FONTSIZE];   // haleyjd 09/18/10: [STRIFE]
+static hu_textline_t    w_title;
+boolean                 chat_on;
+static hu_itext_t       w_chat;
+static boolean          always_off = false;
+static char             chat_dest[MAXPLAYERS];
+static hu_itext_t       w_inputbuffer[MAXPLAYERS];
 
-static boolean		message_on;
-boolean			message_dontfuckwithme;
-static boolean		message_nottobefuckedwith;
+static boolean          message_on;
+boolean                 message_dontfuckwithme;
+static boolean          message_nottobefuckedwith;
 
-static hu_stext_t	w_message;
-static int		message_counter;
+static hu_stext_t       w_message;
+static int              message_counter;
 
-extern int		showMessages;
-extern boolean		automapactive;
+extern int              showMessages;
+extern boolean          automapactive;
 
-static boolean		headsupactive = false;
+static boolean          headsupactive = false;
 
+static char *           nickname; // haleyjd 09/18/10: [STRIFE]
+
 //
 // Builtin map names.
 // The actual names can be found in DStrings.h.
@@ -180,9 +181,14 @@
     HUSTR_34
 };
 
+//
+// HU_Init
+//
+// haleyjd 09/18/10: [STRIFE]
+// * Modified to load yfont along with hu_font.
+//
 void HU_Init(void)
 {
-
     int		i;
     int		j;
     char	buffer[9];
@@ -191,25 +197,38 @@
     j = HU_FONTSTART;
     for (i=0;i<HU_FONTSIZE;i++)
     {
-	DEH_snprintf(buffer, 9, "STCFN%.3d", j++);
-	hu_font[i] = (patch_t *) W_CacheLumpName(buffer, PU_STATIC);
-    }
+        DEH_snprintf(buffer, 9, "STCFN%.3d", j++);
+        hu_font[i] = (patch_t *) W_CacheLumpName(buffer, PU_STATIC);
 
+        // haleyjd 09/18/10: load yfont as well; and yes, this is exactly
+        // how Rogue did it :P
+        buffer[2] = 'B';
+        yfont[i] = (patch_t *) W_CacheLumpName(buffer, PU_STATIC);
+    }
 }
 
+//
+// HU_Stop
+//
+// [STRIFE] Verified unmodified.
+//
 void HU_Stop(void)
 {
     headsupactive = false;
 }
 
+//
+// HU_Start
+//
+// haleyjd 09/18/10: [STRIFE] Added a hack for nickname at the end.
+//
 void HU_Start(void)
 {
+    int         i;
+    char*       s;
 
-    int		i;
-    char*	s;
-
     if (headsupactive)
-	HU_Stop();
+        HU_Stop();
 
     plr = &players[consoleplayer];
     message_on = false;
@@ -219,16 +238,15 @@
 
     // create the message widget
     HUlib_initSText(&w_message,
-		    HU_MSGX, HU_MSGY, HU_MSGHEIGHT,
-		    hu_font,
-		    HU_FONTSTART, &message_on);
+                    HU_MSGX, HU_MSGY, HU_MSGHEIGHT,
+                    hu_font,
+                    HU_FONTSTART, &message_on);
 
     // create the map title widget
     HUlib_initTextLine(&w_title,
-		       HU_TITLEX, HU_TITLEY,
-		       hu_font,
-		       HU_FONTSTART);
-    
+                       HU_TITLEX, HU_TITLEY,
+                       hu_font,
+                       HU_FONTSTART);
 
     // haleyjd 08/31/10: [STRIFE] Get proper map name.
     s = HU_TITLE;
@@ -239,113 +257,224 @@
     s = DEH_String(s);
     
     while (*s)
-	HUlib_addCharToTextLine(&w_title, *(s++));
+        HUlib_addCharToTextLine(&w_title, *(s++));
 
     // create the chat widget
     HUlib_initIText(&w_chat,
-		    HU_INPUTX, HU_INPUTY,
-		    hu_font,
-		    HU_FONTSTART, &chat_on);
+                    HU_INPUTX, HU_INPUTY,
+                    hu_font,
+                    HU_FONTSTART, &chat_on);
 
     // create the inputbuffer widgets
     for (i=0 ; i<MAXPLAYERS ; i++)
-	HUlib_initIText(&w_inputbuffer[i], 0, 0, 0, 0, &always_off);
+        HUlib_initIText(&w_inputbuffer[i], 0, 0, 0, 0, &always_off);
 
     headsupactive = true;
 
+    // haleyjd 09/18/10: [STRIFE] nickname weirdness. 
+
+    // STRIFE-TODO: This shit crashes the game.
+    /*
+    if(nickname != pnameprefixes[consoleplayer])
+    {
+        if(*nickname)
+        {
+            DEH_printf("have one\n");
+            nickname = pnameprefixes[consoleplayer];
+        }
+    }
+    */
 }
 
+//
+// HU_Drawer
+//
+// [STRIFE] Verified unmodified.
+//
 void HU_Drawer(void)
 {
-
     HUlib_drawSText(&w_message);
     HUlib_drawIText(&w_chat);
     if (automapactive)
-	HUlib_drawTextLine(&w_title, false);
-
+        HUlib_drawTextLine(&w_title, false);
 }
 
+//
+// HU_Erase
+//
+// [STRIFE] Verified unmodified.
+//
 void HU_Erase(void)
 {
-
     HUlib_eraseSText(&w_message);
     HUlib_eraseIText(&w_chat);
     HUlib_eraseTextLine(&w_title);
+}
 
+//
+// HU_addMessage
+//
+// haleyjd 09/18/10: [STRIFE] New function
+// See if you can tell whether or not I had trouble with this :P
+// Looks to be extremely buggy, hackish, and error-prone.
+//
+// <Markov> This is definitely not the best that Rogue had to offer. Markov.
+//
+//  Fastcall Registers:   edx          ebx
+//      Temp Registers:   esi          edi
+void HU_addMessage(char *prefix, char *message)
+{
+    char  c;         // eax
+    int   width = 0; // edx
+    char *rover1;    // ebx (in first loop)
+    char *rover2;    // ecx (in second loop)
+    char *bufptr;    // ebx (in second loop)
+    char buffer[HU_MAXLINELENGTH+2];  // esp+52h
+
+    // Loop 1: Total up width of prefix.
+    rover1 = prefix;
+    if(rover1)
+    {
+        while((c = *rover1))
+        {
+            c = toupper(c) - HU_FONTSTART;
+            ++rover1;
+
+            if(c < 0 || c >= HU_FONTSIZE)
+                width += 4;
+            else
+                width += SHORT(hu_font[c]->width);
+        }
+    }
+
+    // Loop 2: Copy as much of message into buffer as will fit on screen
+    bufptr = buffer;
+    rover2 = message;
+    while((c = *rover2))
+    {
+        if((c == ' ' || c == '-') && width > 285)
+            break;
+
+        *bufptr = c;
+        ++bufptr;       // BUG: No check for overflow.
+        ++rover2;
+        c = toupper(c);
+
+        if(c == ' ' || c < '!' || c >= '_')
+            width += 4;
+        else
+        {
+            c -= HU_FONTSTART;
+            width += SHORT(hu_font[c]->width);
+        }
+    }
+
+    // Too big to fit?
+    // BUG: doesn't consider by how much it's over.
+    if(width > 320) 
+    {
+        // backup a char... hell if I know why.
+        --bufptr;
+        --rover2;
+    }
+
+    // rover2 is not at the end?
+    if((c = *rover2))
+    {
+        // if not ON a space...
+        if(c != ' ')
+        {
+            // back up both pointers til one is found.
+            // BUG: no check against LHS of buffer. Hurr!
+            while(*bufptr != ' ')
+            {
+                --bufptr;
+                --rover2;
+            }
+        }
+    }
+
+    *bufptr = '\0';
+
+    // Add two message lines.
+    HUlib_addMessageToSText(&w_message, prefix, buffer);
+    HUlib_addMessageToSText(&w_message, NULL,   rover2);
 }
 
+//
+// HU_Ticker
+//
+// haleyjd 09/18/10: [STRIFE] Changes to split up message into two lines,
+// and support for player names (STRIFE-TODO: unfinished!)
+//
 void HU_Ticker(void)
 {
-
     int i, rc;
     char c;
+    //char *prefix;  STRIFE-TODO
 
     // tick down message counter if message is up
     if (message_counter && !--message_counter)
     {
-	message_on = false;
-	message_nottobefuckedwith = false;
+        message_on = false;
+        message_nottobefuckedwith = false;
     }
 
     if (showMessages || message_dontfuckwithme)
     {
-
-	// display message if necessary
-	if ((plr->message && !message_nottobefuckedwith)
-	    || (plr->message && message_dontfuckwithme))
-	{
-	    HUlib_addMessageToSText(&w_message, 0, plr->message);
-	    plr->message = 0;
-	    message_on = true;
-	    message_counter = HU_MSGTIMEOUT;
-	    message_nottobefuckedwith = message_dontfuckwithme;
-	    message_dontfuckwithme = 0;
-	}
-
+        // display message if necessary
+        if ((plr->message && !message_nottobefuckedwith)
+            || (plr->message && message_dontfuckwithme))
+        {
+            //HUlib_addMessageToSText(&w_message, 0, plr->message);
+            HU_addMessage(NULL, plr->message); // haleyjd [STRIFE]
+            plr->message = 0;
+            message_on = true;
+            message_counter = HU_MSGTIMEOUT;
+            message_nottobefuckedwith = message_dontfuckwithme;
+            message_dontfuckwithme = 0;
+        }
     } // else message_on = false;
 
     // check for incoming chat characters
     if (netgame)
     {
-	for (i=0 ; i<MAXPLAYERS; i++)
-	{
-	    if (!playeringame[i])
-		continue;
-	    if (i != consoleplayer
-		&& (c = players[i].cmd.chatchar))
-	    {
-		if (c <= HU_BROADCAST)
-		    chat_dest[i] = c;
-		else
-		{
-		    rc = HUlib_keyInIText(&w_inputbuffer[i], c);
-		    if (rc && c == KEY_ENTER)
-		    {
-			if (w_inputbuffer[i].l.len
-			    && (chat_dest[i] == consoleplayer+1
-				|| chat_dest[i] == HU_BROADCAST))
-			{
-			    HUlib_addMessageToSText(&w_message,
-						    DEH_String(player_names[i]),
-						    w_inputbuffer[i].l.l);
-			    
-			    message_nottobefuckedwith = true;
-			    message_on = true;
-			    message_counter = HU_MSGTIMEOUT;
-			    if ( gamemode == commercial )
-			      S_StartSound(0, sfx_radio);
-			    else
-			      S_StartSound(0, sfx_swish);   // villsa [STRIFE] TODO - fix sounds
-			}
-			HUlib_resetIText(&w_inputbuffer[i]);
-		    }
-		}
-		players[i].cmd.chatchar = 0;
-	    }
-	}
-    }
+        for (i=0 ; i<MAXPLAYERS; i++)
+        {
+            if (!playeringame[i])
+                continue;
+            if (i != consoleplayer
+                && (c = players[i].cmd.chatchar))
+            {
+                if (c <= HU_BROADCAST)
+                    chat_dest[i] = c;
+                else
+                {
+                    rc = HUlib_keyInIText(&w_inputbuffer[i], c);
+                    if (rc && c == KEY_ENTER)
+                    {
+                        if (w_inputbuffer[i].l.len
+                            && (chat_dest[i] == consoleplayer+1
+                             || chat_dest[i] == HU_BROADCAST))
+                        {
+                            // STRIFE-TODO: there is interaction with the player
+                            // name prefixes array here...
+                            HU_addMessage(DEH_String(player_names[i]),
+                                          w_inputbuffer[i].l.l);
 
-}
+                            message_nottobefuckedwith = true;
+                            message_on = true;
+                            message_counter = HU_MSGTIMEOUT;
+                            S_StartSound(0, sfx_radio);
+                        }
+                        HUlib_resetIText(&w_inputbuffer[i]);
+                    }
+                }
+                players[i].cmd.chatchar = 0;
+            }
+        }
+    }
+}
 
 #define QUEUESIZE		128
 
@@ -353,20 +482,26 @@
 static int	head = 0;
 static int	tail = 0;
 
-
+//
+// HU_queueChatChar
+//
+// haleyjd 09/18/10: [STRIFE]
+// * No message is given if a chat queue overflow occurs.
+//
 void HU_queueChatChar(char c)
 {
-    if (((head + 1) & (QUEUESIZE-1)) == tail)
+    chatchars[head] = c;
+    if (((head + 1) & (QUEUESIZE-1)) != tail)
     {
-	plr->message = DEH_String(HUSTR_MSGU);
+        head = (head + 1) & (QUEUESIZE-1);
     }
-    else
-    {
-	chatchars[head] = c;
-	head = (head + 1) & (QUEUESIZE-1);
-    }
 }
 
+//
+// HU_dequeueChatChar
+//
+// [STRIFE] Verified unmodified.
+//
 char HU_dequeueChatChar(void)
 {
     char c;
@@ -373,145 +508,155 @@
 
     if (head != tail)
     {
-	c = chatchars[tail];
-	tail = (tail + 1) & (QUEUESIZE-1);
+        c = chatchars[tail];
+        tail = (tail + 1) & (QUEUESIZE-1);
     }
     else
     {
-	c = 0;
+        c = 0;
     }
 
     return c;
 }
 
+//
+// HU_Responder
+//
+// haleyjd 09/18/10: [STRIFE]
+// * Mostly unmodified, except:
+//   - The default value of key_message_refresh is changed. That is handled
+//     elsewhere in Choco, however.
+//   - There is support for setting the player name through the chat
+//     mechanism. This is a STRIFE-TODO.
+//
 boolean HU_Responder(event_t *ev)
 {
-
-    static char		lastmessage[HU_MAXLINELENGTH+1];
-    char*		macromessage;
-    boolean		eatkey = false;
-    static boolean	shiftdown = false;
-    static boolean	altdown = false;
-    unsigned char 	c;
-    int			i;
-    int			numplayers;
+    static char         lastmessage[HU_MAXLINELENGTH+1];
+    char*               macromessage;
+    boolean             eatkey = false;
+    static boolean      shiftdown = false;
+    static boolean      altdown = false;
+    unsigned char       c;
+    int                 i;
+    int                 numplayers;
     
-    static int		num_nobrainers = 0;
+    static int          num_nobrainers = 0;
 
     numplayers = 0;
     for (i=0 ; i<MAXPLAYERS ; i++)
-	numplayers += playeringame[i];
+        numplayers += playeringame[i];
 
     if (ev->data1 == KEY_RSHIFT)
     {
-	shiftdown = ev->type == ev_keydown;
-	return false;
+        shiftdown = ev->type == ev_keydown;
+        return false;
     }
     else if (ev->data1 == KEY_RALT || ev->data1 == KEY_LALT)
     {
-	altdown = ev->type == ev_keydown;
-	return false;
+        altdown = ev->type == ev_keydown;
+        return false;
     }
 
     if (ev->type != ev_keydown)
-	return false;
+        return false;
 
     if (!chat_on)
     {
-	if (ev->data1 == key_message_refresh)
-	{
-	    message_on = true;
-	    message_counter = HU_MSGTIMEOUT;
-	    eatkey = true;
-	}
-	else if (netgame && ev->data2 == key_multi_msg)
-	{
-	    eatkey = chat_on = true;
-	    HUlib_resetIText(&w_chat);
-	    HU_queueChatChar(HU_BROADCAST);
-	}
-	else if (netgame && numplayers > 2)
-	{
-	    for (i=0; i<MAXPLAYERS ; i++)
-	    {
-		if (ev->data2 == key_multi_msgplayer[i])
-		{
-		    if (playeringame[i] && i!=consoleplayer)
-		    {
-			eatkey = chat_on = true;
-			HUlib_resetIText(&w_chat);
-			HU_queueChatChar(i+1);
-			break;
-		    }
-		    else if (i == consoleplayer)
-		    {
-			num_nobrainers++;
-			if (num_nobrainers < 3)
-			    plr->message = DEH_String(HUSTR_TALKTOSELF1);
-			else if (num_nobrainers < 6)
-			    plr->message = DEH_String(HUSTR_TALKTOSELF2);
-			else if (num_nobrainers < 9)
-			    plr->message = DEH_String(HUSTR_TALKTOSELF3);
-			else if (num_nobrainers < 32)
-			    plr->message = DEH_String(HUSTR_TALKTOSELF4);
-			else
-			    plr->message = DEH_String(HUSTR_TALKTOSELF5);
-		    }
-		}
-	    }
-	}
-    }
+        if (ev->data1 == key_message_refresh)
+        {
+            message_on = true;
+            message_counter = HU_MSGTIMEOUT;
+            eatkey = true;
+        }
+        else if (netgame && ev->data2 == key_multi_msg)
+        {
+            eatkey = chat_on = true;
+            HUlib_resetIText(&w_chat);
+            HU_queueChatChar(HU_BROADCAST);
+        }
+        else if (netgame && numplayers > 2)
+        {
+            // STRIFE-TODO: support for setting player names
+
+            for (i=0; i<MAXPLAYERS ; i++)
+            {
+                if (ev->data2 == key_multi_msgplayer[i])
+                {
+                    if (playeringame[i] && i!=consoleplayer)
+                    {
+                        eatkey = chat_on = true;
+                        HUlib_resetIText(&w_chat);
+                        HU_queueChatChar(i+1);
+                        break;
+                    }
+                    else if (i == consoleplayer)
+                    {
+                        num_nobrainers++;
+                        if (num_nobrainers < 3)
+                            plr->message = DEH_String(HUSTR_TALKTOSELF1);
+                        else if (num_nobrainers < 6)
+                            plr->message = DEH_String(HUSTR_TALKTOSELF2);
+                        else if (num_nobrainers < 9)
+                            plr->message = DEH_String(HUSTR_TALKTOSELF3);
+                        else if (num_nobrainers < 32)
+                            plr->message = DEH_String(HUSTR_TALKTOSELF4);
+                        else
+                            plr->message = DEH_String(HUSTR_TALKTOSELF5);
+                    }
+                }
+            }
+        }
+    }
     else
     {
-	c = ev->data2;
-	// send a macro
-	if (altdown)
-	{
-	    c = c - '0';
-	    if (c > 9)
-		return false;
-	    // fprintf(stderr, "got here\n");
-	    macromessage = chat_macros[c];
-	    
-	    // kill last message with a '\n'
-	    HU_queueChatChar(KEY_ENTER); // DEBUG!!!
-	    
-	    // send the macro message
-	    while (*macromessage)
-		HU_queueChatChar(*macromessage++);
-	    HU_queueChatChar(KEY_ENTER);
-	    
-	    // leave chat mode and notify that it was sent
-	    chat_on = false;
-	    strcpy(lastmessage, chat_macros[c]);
-	    plr->message = lastmessage;
-	    eatkey = true;
-	}
-	else
-	{
-	    eatkey = HUlib_keyInIText(&w_chat, c);
-	    if (eatkey)
-	    {
-		// static unsigned char buf[20]; // DEBUG
-		HU_queueChatChar(c);
-		
-		// sprintf(buf, "KEY: %d => %d", ev->data1, c);
-		//      plr->message = buf;
-	    }
-	    if (c == KEY_ENTER)
-	    {
-		chat_on = false;
-		if (w_chat.l.len)
-		{
-		    strcpy(lastmessage, w_chat.l.l);
-		    plr->message = lastmessage;
-		}
-	    }
-	    else if (c == KEY_ESCAPE)
-		chat_on = false;
-	}
+        c = ev->data2;
+        // send a macro
+        if (altdown)
+        {
+            c = c - '0';
+            if (c > 9)
+                return false;
+            // fprintf(stderr, "got here\n");
+            macromessage = chat_macros[c];
+
+            // kill last message with a '\n'
+            HU_queueChatChar(KEY_ENTER); // DEBUG!!!
+
+            // send the macro message
+            while (*macromessage)
+                HU_queueChatChar(*macromessage++);
+            HU_queueChatChar(KEY_ENTER);
+
+            // leave chat mode and notify that it was sent
+            chat_on = false;
+            strcpy(lastmessage, chat_macros[c]);
+            plr->message = lastmessage;
+            eatkey = true;
+        }
+        else
+        {
+            eatkey = HUlib_keyInIText(&w_chat, c);
+            if (eatkey)
+            {
+                // static unsigned char buf[20]; // DEBUG
+                HU_queueChatChar(c);
+
+                // sprintf(buf, "KEY: %d => %d", ev->data1, c);
+                //      plr->message = buf;
+            }
+            if (c == KEY_ENTER)
+            {
+                chat_on = false;
+                if (w_chat.l.len)
+                {
+                    strcpy(lastmessage, w_chat.l.l);
+                    plr->message = lastmessage;
+                }
+            }
+            else if (c == KEY_ESCAPE)
+                chat_on = false;
+        }
     }
 
     return eatkey;
-
 }
--- a/src/strife/hu_stuff.h
+++ b/src/strife/hu_stuff.h
@@ -31,21 +31,22 @@
 //
 // Globally visible constants.
 //
-#define HU_FONTSTART	'!'	// the first font characters
-#define HU_FONTEND	'_'	// the last font characters
+#define HU_FONTSTART    '!'     // the first font characters
+#define HU_FONTEND      '_'     // the last font characters
 
 // Calculate # of glyphs in font.
-#define HU_FONTSIZE	(HU_FONTEND - HU_FONTSTART + 1)	
+#define HU_FONTSIZE     (HU_FONTEND - HU_FONTSTART + 1)	
 
-#define HU_BROADCAST	5
+#define HU_BROADCAST    9       // haleyjd [STRIFE] Changed 5 -> 9
 
-#define HU_MSGX		0
-#define HU_MSGY		0
-#define HU_MSGWIDTH	64	// in characters
-#define HU_MSGHEIGHT	1	// in lines
+#define HU_MSGX         0
+#define HU_MSGY         (SHORT(hu_font[0]->height) + 1) // [STRIFE]: DOOM bug fix
+#define HU_MSGWIDTH     64      // in characters
+#define HU_MSGHEIGHT    2       // in lines
 
-#define HU_MSGTIMEOUT	(4*TICRATE)
+#define HU_MSGTIMEOUT   (8*TICRATE) // haleyjd [STRIFE] Doubled message timeout
 
+
 //
 // HEADS UP TEXT
 //
@@ -61,7 +62,7 @@
 void HU_Erase(void);
 
 extern char *chat_macros[10];
-extern char* pnameprefixes[][16];   // villsa [STRIFE]
+extern char pnameprefixes[8][16];   // villsa [STRIFE]
 
 // haleyjd [STRIFE] externalized:
 extern char *mapnames[];