diff rogue5/io.c @ 33:f502bf60e6e4

Import Rogue 5.4 from the Roguelike Restoration Project (r1490)
author elwin
date Mon, 24 May 2010 20:10:59 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue5/io.c	Mon May 24 20:10:59 2010 +0000
@@ -0,0 +1,294 @@
+/*
+ * Various input/output functions
+ *
+ * @(#)io.c	4.32 (Berkeley) 02/05/99
+ */
+
+#include <stdarg.h>
+#include <curses.h>
+#include <ctype.h>
+#include <string.h>
+#include "rogue.h"
+
+/*
+ * msg:
+ *	Display a message at the top of the screen.
+ */
+#define MAXMSG	(NUMCOLS - sizeof "--More--")
+
+static char msgbuf[2*MAXMSG+1];
+static int newpos = 0;
+
+/* VARARGS1 */
+int
+msg(const char *fmt, ...)
+{
+    va_list args;
+
+    /*
+     * if the string is "", just clear the line
+     */
+    if (*fmt == '\0')
+    {
+	move(0, 0);
+	clrtoeol();
+	mpos = 0;
+	return ~ESCAPE;
+    }
+    /*
+     * otherwise add to the message and flush it out
+     */
+    va_start(args, fmt);
+    doadd(fmt, args);
+    va_end(args);
+    return endmsg();
+}
+
+/*
+ * addmsg:
+ *	Add things to the current message
+ */
+/* VARARGS1 */
+void
+addmsg(const char *fmt, ...)
+{
+    va_list args;
+
+    va_start(args, fmt);
+    doadd(fmt, args);
+    va_end(args);
+}
+
+/*
+ * endmsg:
+ *	Display a new msg (giving him a chance to see the previous one
+ *	if it is up there with the --More--)
+ */
+int
+endmsg(void)
+{
+    int ch;
+
+    if (save_msg)
+	strcpy(huh, msgbuf);
+    if (mpos)
+    {
+	look(FALSE);
+	mvaddstr(0, mpos, "--More--");
+	refresh();
+	if (!msg_esc)
+	    wait_for(stdscr, ' ');
+	else
+	{
+	    while ((ch = readchar()) != ' ')
+		if (ch == ESCAPE)
+		{
+		    msgbuf[0] = '\0';
+		    mpos = 0;
+		    newpos = 0;
+		    msgbuf[0] = '\0';
+		    return ESCAPE;
+		}
+	}
+    }
+    /*
+     * All messages should start with uppercase, except ones that
+     * start with a pack addressing character
+     */
+    if (islower((int)msgbuf[0]) && !lower_msg && msgbuf[1] != ')')
+	msgbuf[0] = (char) toupper(msgbuf[0]);
+    mvaddstr(0, 0, msgbuf);
+    clrtoeol();
+    mpos = newpos;
+    newpos = 0;
+    msgbuf[0] = '\0';
+    refresh();
+    return ~ESCAPE;
+}
+
+/*
+ * doadd:
+ *	Perform an add onto the message buffer
+ */
+void
+doadd(const char *fmt, va_list args)
+{
+    static char buf[MAXSTR];
+
+    /*
+     * Do the printf into buf
+     */
+    vsprintf(buf, fmt, args);
+    if (strlen(buf) + newpos >= MAXMSG)
+        endmsg(); 
+    strcat(msgbuf, buf);
+    newpos = (int) strlen(msgbuf);
+}
+
+/*
+ * step_ok:
+ *	Returns true if it is ok to step on ch
+ */
+int
+step_ok(int ch)
+{
+    switch (ch)
+    {
+	case ' ':
+	case '|':
+	case '-':
+	    return FALSE;
+	default:
+	    return (!isalpha(ch));
+    }
+}
+
+/*
+ * readchar:
+ *	Reads and returns a character, checking for gross input errors
+ */
+
+int
+readchar(void)
+{
+    int ch;
+
+    ch = md_readchar(stdscr);
+
+    if (ch == 3)
+    {
+		quit(0);
+        return(27);
+    }
+
+    return(ch);
+}
+
+int
+wreadchar(WINDOW *win)
+{
+    int ch;
+
+    ch = md_readchar(win);
+
+    if (ch == 3)
+    {
+		quit(0);
+        return(27);
+    }
+
+    return(ch);
+}
+
+
+/*
+ * status:
+ *	Display the important stats line.  Keep the cursor where it was.
+ */
+void
+status(void)
+{
+    int oy, ox, temp;
+    static int hpwidth = 0;
+    static int s_hungry = 0;
+    static int s_lvl = 0;
+    static int s_pur = -1;
+    static int s_hp = 0;
+    static int s_arm = 0;
+    static int s_str = 0;
+    static int s_exp = 0;
+    static char *state_name[] =
+    {
+	"", "Hungry", "Weak", "Faint"
+    };
+
+    /*
+     * If nothing has changed since the last status, don't
+     * bother.
+     */
+    temp = (cur_armor != NULL ? cur_armor->o_arm : pstats.s_arm);
+    if (s_hp == pstats.s_hpt && s_exp == pstats.s_exp && s_pur == purse
+	&& s_arm == temp && s_str == pstats.s_str && s_lvl == level
+	&& s_hungry == hungry_state
+	&& !stat_msg
+	)
+	    return;
+
+    s_arm = temp;
+
+    getyx(stdscr, oy, ox);
+    if (s_hp != max_hp)
+    {
+	temp = max_hp;
+	s_hp = max_hp;
+	for (hpwidth = 0; temp; hpwidth++)
+	    temp /= 10;
+    }
+
+    /*
+     * Save current status
+     */
+    s_lvl = level;
+    s_pur = purse;
+    s_hp = pstats.s_hpt;
+    s_str = pstats.s_str;
+    s_exp = pstats.s_exp; 
+    s_hungry = hungry_state;
+
+    if (stat_msg)
+    {
+        move(0, 0);
+        msg("Level: %d  Gold: %-5d  Hp: %*d(%*d)  Str: %2d(%d)  Arm: %-2d  Exp: %d/%d  %s",
+        level, purse, hpwidth, pstats.s_hpt, hpwidth, max_hp, pstats.s_str,
+        max_stats.s_str, 10 - s_arm, pstats.s_lvl, pstats.s_exp,
+        state_name[hungry_state]);
+    }
+    else
+    {
+	move(STATLINE, 0);
+                
+        printw("Level: %d  Gold: %-5d  Hp: %*d(%*d)  Str: %2d(%d)  Arm: %-2d  Exp: %d/%d  %s",
+	    level, purse, hpwidth, pstats.s_hpt, hpwidth, max_hp, pstats.s_str,
+	    max_stats.s_str, 10 - s_arm, pstats.s_lvl, pstats.s_exp,
+	    state_name[hungry_state]);
+    }
+
+    clrtoeol();
+    move(oy, ox);
+}
+
+/*
+ * wait_for
+ *	Sit around until the guy types the right key
+ */
+void
+wait_for(WINDOW *win, int ch)
+{
+    int c;
+
+    if (ch == '\n')
+        while ((c = wreadchar(win)) != '\n' && c != '\r')
+	    continue;
+    else
+        while (wreadchar(win) != ch)
+	    continue;
+}
+
+/*
+ * show_win:
+ *	Function used to display a window and wait before returning
+ */
+void
+show_win(const char *message)
+{
+    WINDOW *win;
+
+    win = hw;
+    wmove(win, 0, 0);
+    waddstr(win, message);
+    touchwin(win);
+    wrefresh(win);
+    wait_for(win, ' ');
+    clearok(curscr, TRUE);
+    touchwin(stdscr);
+}