Mercurial > hg > early-roguelike
diff urogue/io.c @ 256:c495a4f288c6
Import UltraRogue from the Roguelike Restoration Project (r1490)
author | John "Elwin" Edwards |
---|---|
date | Tue, 31 Jan 2017 19:56:04 -0500 |
parents | |
children | 0250220d8cdd |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/urogue/io.c Tue Jan 31 19:56:04 2017 -0500 @@ -0,0 +1,471 @@ +/* + io.c - Various input/output functions + + UltraRogue: The Ultimate Adventure in the Dungeons of Doom + Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong + All rights reserved. + + Based on "Advanced Rogue" + Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka + All rights reserved. + + Based on "Rogue: Exploring the Dungeons of Doom" + Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman + All rights reserved. + + See the file LICENSE.TXT for full copyright and licensing information. +*/ + +#include <string.h> +#include <ctype.h> +#include <stdarg.h> +#include "rogue.h" + +char prbuf[2 * LINELEN]; /* Buffer for sprintfs */ +static char mbuf[2*LINELEN]; /* Current message buffer */ +static int newpos = 0; /* index in mbuf to end of msg */ + +int mpos = 0; /* 0 = Overwrite existing message */ + /* >0 = print --More-- at this pos */ + /* and wait for key */ + +int line_cnt = 0; +int newpage = FALSE; + +/* + msg() + Display a message at the top of the screen. +*/ + +void +msg(const char *fmt, ...) +{ + va_list ap; + + /* if the string is "", just clear the line */ + + if (*fmt == '\0') + { + wmove(cw, 0, 0); + wclrtoeol(cw); + mpos = 0; + return; + } + + /* otherwise add to the message and flush it out */ + + va_start(ap, fmt); + doadd(fmt, ap); + va_end(ap); + + endmsg(); +} + +void +vmsg(const char *fmt, va_list ap) +{ + /* if the string is "", just clear the line */ + + if (*fmt == '\0') + { + wmove(cw, 0, 0); + wclrtoeol(cw); + mpos = 0; + return; + } + + /* otherwise add to the message and flush it out */ + + doadd(fmt, ap); + endmsg(); +} + + +/* + addmsg() + add things to the current message +*/ + +void +addmsg(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + doadd(fmt,ap); + va_end(ap); +} + +/* + endmsg() + Display a new msg (giving him a chance to see the previous one + if it is up there with the --More--) +*/ + +void +endmsg(void) +{ + strcpy(msgbuf[msg_index], mbuf); + + msg_index = ++msg_index % 10; + + if (mpos) + { + wmove(cw, 0, mpos); + wprintw(cw, (char *) morestr); + wrefresh(cw); + wait_for(' '); + } + + mvwprintw(cw, 0, 0, mbuf); + wclrtoeol(cw); + + mpos = newpos; + newpos = 0; + + wrefresh(cw); +} + +void +doadd(const char *fmt, va_list ap) +{ + vsprintf(&mbuf[newpos], fmt, ap); + newpos = (int) strlen(mbuf); +} + +/* + status() + Display the important stats line. Keep the cursor where it was. +*/ + +void +status(int display) +{ + static char buf[1024]; /* Temporary buffer */ + struct stats *stat_ptr, *max_ptr; + int oy, ox; + + stat_ptr = &pstats; + max_ptr = &max_stats; + + getyx(cw, oy, ox); + sprintf(buf, + "Int:%d(%d) Str:%d(%d) Wis:%d(%d) Dex:%d(%d) Con:%d(%d) Carry:%d(%d) %d", + stat_ptr->s_intel, max_ptr->s_intel, + stat_ptr->s_str, max_ptr->s_str, + stat_ptr->s_wisdom, max_ptr->s_wisdom, + stat_ptr->s_dext, max_ptr->s_dext, + stat_ptr->s_const, max_ptr->s_const, + stat_ptr->s_pack / 10, stat_ptr->s_carry / 10, foodlev ); + + mvwaddstr(cw, LINES - 2, 0, buf); + wclrtoeol(cw); + + sprintf(buf, "Lvl:%d Au:%d Hpt:%3d(%3d) Pow:%d(%d) Ac:%d Exp:%d+%ld %s", + level, + purse, + stat_ptr->s_hpt, max_ptr->s_hpt, + stat_ptr->s_power, max_ptr->s_power, + (cur_armor != NULL ? (cur_armor->o_ac - 10 + stat_ptr->s_arm) + : stat_ptr->s_arm) - ring_value(R_PROTECT), + stat_ptr->s_lvl, + stat_ptr->s_exp, + cnames[player.t_ctype][min(stat_ptr->s_lvl - 1, 14)]); + + mvwaddstr(cw, LINES - 1, 0, buf); + + switch(hungry_state) + { + case F_OK: break; + case F_HUNGRY: waddstr(cw, " Hungry"); + break; + case F_WEAK: waddstr(cw, " Weak"); + break; + case F_FAINT: waddstr(cw, " Fainting"); + break; + } + + wclrtoeol(cw); + wmove(cw, oy, ox); + + if (display) + wrefresh(cw); +} + +/* + * readchar: + * Flushes stdout so that screen is up to date and then returns + * getchar(). + */ + +char +readcharw(WINDOW *win) +{ + char ch; + + ch = (char) md_readchar(win); + + if ((ch == 3) || (ch == 0)) + { + quit(); + return(27); + } + + return(ch); +} + +char +readchar() +{ + return( readcharw(cw) ); +} + +/* + wait_for() + Sit around until the guy types the right key +*/ + +void +w_wait_for(WINDOW *w, int ch) +{ + char c; + + if (ch == '\n') + while ((c = readcharw(w)) != '\n' && c != '\r') + continue; + else + while (readcharw(w) != ch) + continue; +} + +void +wait_for(int ch) +{ + w_wait_for(cw, ch); +} + +/* + show_win() + function used to display a window and wait before returning +*/ + +void +show_win(WINDOW *scr, char *message) +{ + mvwaddstr(scr, 0, 0, message); + touchwin(scr); + wmove(scr, hero.y, hero.x); + wrefresh(scr); + wait_for(' '); + clearok(cw, TRUE); + touchwin(cw); +} + +/* + restscr() + Restores the screen to the terminal +*/ + +void +restscr(WINDOW *scr) +{ + clearok(scr, TRUE); + touchwin(scr); +} + +/* + add_line() + Add a line to the list of discoveries +*/ + +void +add_line(const char *fmt, ...) +{ + WINDOW *tw; + va_list ap; + + va_start(ap, fmt); + + if (line_cnt == 0) + { + wclear(hw); + + if (inv_type == INV_SLOW) + mpos = 0; + } + + if (inv_type == INV_SLOW) + { + if ( (fmt != NULL) && (*fmt != '\0') ) + vmsg(fmt, ap); + line_cnt++; + } + else + { + if ( (line_cnt >= LINES - 2) || (fmt == NULL)) /* end 'o page */ + { + if (fmt == NULL && !newpage && inv_type == INV_OVER) + { + tw = newwin(line_cnt + 2, COLS, 0, 0); + overwrite(hw, tw); + wstandout(tw); + mvwaddstr(tw, line_cnt, 0, spacemsg); + wstandend(tw); + touchwin(tw); + wrefresh(tw); + wait_for(' '); + delwin(tw); + touchwin(cw); + } + else + { + wstandout(hw); + mvwaddstr(hw, LINES - 1, 0, spacemsg); + wstandend(hw); + wrefresh(hw); + w_wait_for(hw, ' '); + touchwin(cw); + wclear(hw); + } + newpage = TRUE; + line_cnt = 0; + } + + /* draw line */ + if (fmt != NULL && !(line_cnt == 0 && *fmt == '\0')) + { + static char tmpbuf[1024]; + + vsprintf(tmpbuf, fmt, ap); + mvwprintw(hw, line_cnt++, 0, tmpbuf); + } + } +} + +/* + end_line() + End the list of lines +*/ + +void +end_line(void) +{ + if (inv_type != INV_SLOW) + add_line(NULL); + + line_cnt = 0; + newpage = FALSE; +} + +/* + hearmsg() + Call msg() only if you are not deaf +*/ + +void +hearmsg(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + + if (off(player, ISDEAF)) + vmsg(fmt, ap); + else if (wizard) + { + msg("Couldn't hear: "); + vmsg(fmt, ap); + } + + va_end(ap); +} + +/* + seemsg() + Call msg() only if you are not blind +*/ + +void +seemsg(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + + if (off(player, ISBLIND)) + vmsg(fmt, ap); + else if (wizard) + { + msg("Couldn't see: "); + vmsg(fmt, ap); + } + + va_end(ap); +} + +int +get_string(char *buffer, WINDOW *win) +{ + char *sp, c; + int oy, ox; + char buf[2 * LINELEN]; + + wrefresh(win); + getyx(win, oy, ox); + + /* loop reading in the string, and put it in a temporary buffer */ + + for (sp = buf; (c = readcharw(win)) != '\n' && + c != '\r' && + c != '\033' && + c != '\007' && + sp < &buf[LINELEN - 1]; + wclrtoeol(win), wrefresh(win)) + { + if ((c == '\b') || (c == 0x7f)) + { + if (sp > buf) + { + size_t i; + + sp--; + + for (i = strlen(unctrl(*sp)); i; i--) + waddch(win, '\b'); + } + continue; + } + else if (c == '\0') + { + sp = buf; + wmove(win, oy, ox); + continue; + } + else if (sp == buf && c == '-' && win == hw) + break; + + *sp++ = c; + waddstr(win, unctrl(c)); + } + + *sp = '\0'; + + if (sp > buf) /* only change option if something has been typed */ + strncpy(buffer, buf, strlen(buf)+1); + + wmove(win, oy, ox); + waddstr(win, buffer); + waddch(win, '\n'); + wrefresh(win); + + if (win == cw) + mpos += (int)(sp - buf); + + if (c == '-') + return(MINUS); + else if (c == '\033' || c == '\007') + return(QUIT); + else + return(NORM); +} +