Mercurial > hg > early-roguelike
view srogue/io.c @ 254:e940e6c00751
Add some braces to a loop in parse_opts().
A for loop had no braces around its body, which was a single if-else
statement. In Advanced Rogue 5, another statement had been added,
accidentally removing the if-else from the loop. This could have
resulted in an out-of-bounds access to the options array.
In the other games, the added braces are only for clarity.
author | John "Elwin" Edwards |
---|---|
date | Fri, 10 Feb 2017 09:02:58 -0500 |
parents | 94a0d9dd5ce1 |
children | 70aa5808c782 |
line wrap: on
line source
/* * Various input/output functions * * @(#)io.c 9.0 (rdk) 7/17/84 * * Super-Rogue * Copyright (C) 1984 Robert D. Kindelberger * 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 <stdarg.h> #include <ctype.h> #include <string.h> #include "rogue.h" #include "rogue.ext" void doadd(char *fmt, va_list ap); /* * msg: * Display a message at the top of the screen. */ static char msgbuf[BUFSIZ]; static int newpos = 0; void msg(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(); } /* * addmsg: * Add things to the current message */ void addmsg(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(huh, msgbuf); if (mpos > 0) { wmove(cw, 0, mpos); waddstr(cw, morestr); draw(cw); wait_for(cw, ' '); } mvwaddstr(cw, 0, 0, msgbuf); wclrtoeol(cw); mpos = newpos; newpos = 0; draw(cw); } /* * doadd: * Perform a printf into a buffer */ void doadd(char *fmt, va_list ap) { vsprintf(&msgbuf[newpos], fmt, ap); newpos = strlen(msgbuf); } /* * step_ok: * Returns TRUE if it is ok to step on ch */ bool step_ok(unsigned char ch) { if (dead_end(ch)) return FALSE; else if (ch >= 32 && ch <= 127 && !isalpha(ch)) return TRUE; return FALSE; } /* * dead_end: * Returns TRUE if you cant walk through that character */ bool dead_end(char ch) { if (ch == '-' || ch == '|' || ch == ' ' || ch == SECRETDOOR) return TRUE; else return FALSE; } /* * readchar: * flushes stdout so that screen is up to date and then returns * getchar. */ int readchar(void) { char c; fflush(stdout); return( md_readchar(cw) ); } char *hungstr[] = { "", " HUNGRY", " STARVING", " FAINTING", }; /* * status: * Display the important stats line. Keep the cursor where it was. */ void status(int fromfuse) { reg int totwght, carwght; reg struct real *stef, *stre, *stmx; reg char *pb; int oy, ox, ch; static char buf[LINLEN]; static char hwidth[] = { "%2d(%2d)" }; /* * If nothing has changed since the last time, then done */ if (nochange) return; nochange = TRUE; updpack(); /* get all weight info */ stef = &player.t_stats.s_ef; stre = &player.t_stats.s_re; stmx = &max_stats.s_re; totwght = him->s_carry / 10; carwght = him->s_pack / 10; getyx(cw, oy, ox); if (him->s_maxhp >= 100) { hwidth[1] = '3'; /* if hit point >= 100 */ hwidth[5] = '3'; /* change %2d to %3d */ } if (stre->a_str < stmx->a_str) ch = '*'; else ch = ' '; sprintf(buf, "Str: %2d(%c%2d)", stef->a_str, ch, stre->a_str); pb = &buf[strlen(buf)]; if (stre->a_dex < stmx->a_dex) ch = '*'; else ch = ' '; sprintf(pb, " Dex: %2d(%c%2d)", stef->a_dex, ch, stre->a_dex); pb = &buf[strlen(buf)]; if (stre->a_wis < stmx->a_wis) ch = '*'; else ch = ' '; sprintf(pb, " Wis: %2d(%c%2d)", stef->a_wis, ch, stre->a_wis); pb = &buf[strlen(buf)]; if (stre->a_con < stmx->a_con) ch = '*'; else ch = ' '; sprintf(pb, " Con: %2d(%c%2d)", stef->a_con, ch, stre->a_con); pb = &buf[strlen(buf)]; sprintf(pb, " Carry: %3d(%3d)", carwght, totwght); mvwaddstr(cw, LINES - 1, 0, buf); sprintf(buf, "Level: %d Gold: %5d Hp: ",level, purse); pb = &buf[strlen(buf)]; sprintf(pb, hwidth, him->s_hpt, him->s_maxhp); pb = &buf[strlen(buf)]; sprintf(pb," Ac: %-2d Exp: %d/%ld",cur_armor == NULL ? him->s_arm : cur_armor->o_ac, him->s_lvl, him->s_exp); carwght = (packvol * 100) / V_PACK; pb = &buf[strlen(buf)]; sprintf(pb, " Vol: %3d%%", carwght); mvwaddstr(cw, LINES - 2, 0, buf); waddstr(cw, hungstr[hungry_state]); wclrtoeol(cw); wmove(cw, oy, ox); } /* * dispmax: * Display the hero's maximum status */ void dispmax(void) { reg struct real *hmax; hmax = &max_stats.s_re; msg("Maximums: Str = %d Dex = %d Wis = %d Con = %d", hmax->a_str, hmax->a_dex, hmax->a_wis, hmax->a_con); } /* * illeg_ch: * Returns TRUE if a char shouldn't show on the screen */ bool illeg_ch(unsigned char ch) { if (ch < 32 || ch > 127) return TRUE; if (ch >= '0' && ch <= '9') return TRUE; return FALSE; } /* * wait_for: * Sit around until the guy types the right key */ void wait_for(WINDOW *win, char ch) { register char c; if (ch == '\n') while ((c = wgetch(win)) != '\n' && c != '\r') continue; else while (wgetch(win) != ch) continue; } #ifdef NEED_GETTIME #include <stdio.h> /* * gettime: * This routine returns the current time as a string */ #ifdef ATT #include <time.h> #endif #ifdef BSD #include <sys/time.h> #endif char * gettime() { register char *timeptr; char *ctime(); long int now, time(); time(&now); /* get current time */ timeptr = ctime(&now); /* convert to string */ return timeptr; /* return the string */ } #endif /* * dbotline: * Displays message on bottom line and waits for a space to return */ void dbotline(WINDOW *scr, char *message) { mvwaddstr(scr,LINES-1,0,message); draw(scr); wait_for(scr,' '); } /* * restscr: * Restores the screen to the terminal */ void restscr(WINDOW *scr) { clearok(scr,TRUE); touchwin(scr); } /* * npch: * Get the next char in line for inventories */ char npch(char ch) { reg char nch; if (ch >= 'z') nch = 'A'; else nch = ch + 1; return nch; }