[BACK]Return to io.c CVS log [TXT][DIR] Up to [contributed] / early-roguelike / arogue5

Annotation of early-roguelike/arogue5/io.c, Revision 1.1.1.1

1.1       rubenllo    1: /*
                      2:  * Various input/output functions
                      3:  *
                      4:  * Advanced Rogue
                      5:  * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
                      6:  * All rights reserved.
                      7:  *
                      8:  * Based on "Rogue: Exploring the Dungeons of Doom"
                      9:  * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
                     10:  * All rights reserved.
                     11:  *
                     12:  * See the file LICENSE.TXT for full copyright and licensing information.
                     13:  */
                     14:
                     15: #include "curses.h"
                     16: #include <ctype.h>
                     17: #include <string.h>
                     18: #include <stdarg.h>
                     19: #include "rogue.h"
                     20:
                     21: void doadd(char *fmt, va_list ap);
                     22: void ministat(void);
                     23:
                     24: /*
                     25:  * msg:
                     26:  *     Display a message at the top of the screen.
                     27:  */
                     28:
                     29: static char msgbuf[BUFSIZ];
                     30: static int newpos = 0;
                     31:
                     32: /*VARARGS1*/
                     33: void
                     34: msg(char *fmt, ...)
                     35: {
                     36:     va_list ap;
                     37:     /*
                     38:      * if the string is "", just clear the line
                     39:      */
                     40:     if (*fmt == '\0')
                     41:     {
                     42:        overwrite(cw,msgw);
                     43:        wmove(msgw, 0, 0);
                     44:        clearok(msgw, FALSE);
                     45:        draw(msgw);
                     46:        mpos = 0;
                     47:        return;
                     48:     }
                     49:     /*
                     50:      * otherwise add to the message and flush it out
                     51:      */
                     52:     va_start(ap,fmt);
                     53:     doadd(fmt, ap);
                     54:     va_end(ap);
                     55:     endmsg();
                     56: }
                     57:
                     58: /*
                     59:  * add things to the current message
                     60:  */
                     61: void
                     62: addmsg(char *fmt, ...)
                     63: {
                     64:     va_list ap;
                     65:     va_start(ap,fmt);
                     66:     doadd(fmt, ap);
                     67:     va_end(ap);
                     68: }
                     69:
                     70: /*
                     71:  * Display a new msg (giving him a chance to see the previous one if it
                     72:  * is up there with the --More--)
                     73:  */
                     74: void
                     75: endmsg(void)
                     76: {
                     77:     strncpy(huh, msgbuf, sizeof(huh));
                     78:
                     79:     huh[ sizeof(huh) - 1 ] = 0;
                     80:
                     81:     if (mpos)
                     82:     {
                     83:        wmove(msgw, 0, mpos);
                     84:        waddstr(msgw, morestr);
                     85:        draw(cw);
                     86:        draw(msgw);
                     87:        wait_for(msgw,' ');
                     88:        overwrite(cw,msgw);
                     89:        wmove(msgw,0,0);
                     90:        touchwin(cw);
                     91:     }
                     92:     else {
                     93:        overwrite(cw,msgw);
                     94:        wmove(msgw,0,0);
                     95:     }
                     96:     waddstr(msgw, msgbuf);
                     97:     mpos = newpos;
                     98:     newpos = 0;
                     99:     msgbuf[0] = '\0';
                    100:     draw(cw);
                    101:     clearok(msgw, FALSE);
                    102:     draw(msgw);
                    103: }
                    104:
                    105: void
                    106: doadd(char *fmt, va_list ap)
                    107: {
                    108:     /*
                    109:      * Do the sprintf into newmsg and append to msgbuf
                    110:      */
                    111:
                    112:     vsnprintf(&msgbuf[newpos], sizeof(msgbuf)-newpos-1, fmt, ap);
                    113:
                    114:     newpos = strlen(msgbuf);
                    115: }
                    116:
                    117: /*
                    118:  * step_ok:
                    119:  *     returns true if it is ok for type to step on ch
                    120:  *     flgptr will be NULL if we don't know what the monster is yet!
                    121:  */
                    122:
                    123: bool
                    124: step_ok(int y, int x, int can_on_monst, struct thing *flgptr)
                    125: {
                    126:     /* can_on_monst = MONSTOK if all we care about are physical obstacles */
                    127:     register struct linked_list *item;
                    128:     char ch;
                    129:
                    130:     /* What is here?  Don't check monster window if MONSTOK is set */
                    131:     if (can_on_monst == MONSTOK) ch = CCHAR( mvinch(y, x) );
                    132:     else ch = CCHAR( winat(y, x) );
                    133:
                    134:     switch (ch)
                    135:     {
                    136:        case ' ':
                    137:        case '|':
                    138:        case '-':
                    139:        case SECRETDOOR:
                    140:            if (flgptr && on(*flgptr, CANINWALL)) return(TRUE);
                    141:            return FALSE;
                    142:        when SCROLL:
                    143:            if (can_on_monst == MONSTOK) return(TRUE); /* Not a real obstacle */
                    144:            /*
                    145:             * If it is a scroll, it might be a scare monster scroll
                    146:             * so we need to look it up to see what type it is.
                    147:             */
                    148:            if (flgptr && flgptr->t_ctype == C_MONSTER) {
                    149:                item = find_obj(y, x);
                    150:                if (item != NULL &&
                    151:                    (OBJPTR(item))->o_which==S_SCARE &&
                    152:                    (flgptr == NULL || flgptr->t_stats.s_intel < 16))
                    153:                        return(FALSE); /* All but smart ones are scared */
                    154:            }
                    155:            return(TRUE);
                    156:        otherwise:
                    157:            return (!isalpha(ch));
                    158:     }
                    159: }
                    160: /*
                    161:  * shoot_ok:
                    162:  *     returns true if it is ok for type to shoot over ch
                    163:  */
                    164:
                    165: bool
                    166: shoot_ok(char ch)
                    167: {
                    168:     switch (ch)
                    169:     {
                    170:        case ' ':
                    171:        case '|':
                    172:        case '-':
                    173:        case SECRETDOOR:
                    174:        case FOREST:
                    175:            return FALSE;
                    176:        default:
                    177:            return (!isalpha(ch));
                    178:     }
                    179: }
                    180:
                    181: /*
                    182:  * readchar:
                    183:  *     flushes stdout so that screen is up to date and then returns
                    184:  *     getchar.
                    185:  */
                    186:
                    187: int
                    188: readchar(void)
                    189: {
                    190:     int ch;
                    191:
                    192:     ch = md_readchar(cw);
                    193:
                    194:     if ((ch == 3) || (ch == 0))
                    195:     {
                    196:         quit(0);
                    197:         return(27);
                    198:     }
                    199:
                    200:     return(ch);
                    201: }
                    202:
                    203: /*
                    204:  * status:
                    205:  *     Display the important stats line.  Keep the cursor where it was.
                    206:  *     If display is TRUE, display unconditionally
                    207:  */
                    208:
                    209: void
                    210: status(bool display)
                    211: {
                    212:     register struct stats *stat_ptr, *max_ptr;
                    213:     register int oy = 0, ox = 0, temp;
                    214:     register char *pb;
                    215:     static char buf[LINELEN];
                    216:     static int hpwidth = 0, s_hungry = -1;
                    217:     static int s_lvl = -1, s_pur, s_hp = -1, s_str, maxs_str,
                    218:                s_ac = 0;
                    219:     static short s_intel, s_dext, s_wisdom, s_const, s_charisma;
                    220:     static short maxs_intel, maxs_dext, maxs_wisdom, maxs_const, maxs_charisma;
                    221:     static unsigned long s_exp = 0;
                    222:     static int s_carry, s_pack;
                    223:     bool first_line=FALSE;
                    224:
                    225:     /* Use a mini status version if we have a small window */
                    226:     if (COLS < 80) {
                    227:        ministat();
                    228:        return;
                    229:     }
                    230:
                    231:     stat_ptr = &pstats;
                    232:     max_ptr  = &max_stats;
                    233:
                    234:     /*
                    235:      * If nothing has changed in the first line, then skip it
                    236:      */
                    237:     if (!display                               &&
                    238:        s_lvl == level                          &&
                    239:        s_intel == stat_ptr->s_intel            &&
                    240:        s_wisdom == stat_ptr->s_wisdom          &&
                    241:        s_dext == dex_compute()                 &&
                    242:        s_const == stat_ptr->s_const            &&
                    243:        s_charisma == stat_ptr->s_charisma      &&
                    244:        s_str == str_compute()                  &&
                    245:        s_pack == stat_ptr->s_pack              &&
                    246:        s_carry == stat_ptr->s_carry            &&
                    247:        maxs_intel == max_ptr->s_intel          &&
                    248:        maxs_wisdom == max_ptr->s_wisdom        &&
                    249:        maxs_dext == max_ptr->s_dext            &&
                    250:        maxs_const == max_ptr->s_const          &&
                    251:        maxs_charisma == max_ptr->s_charisma    &&
                    252:        maxs_str == max_ptr->s_str              ) goto line_two;
                    253:
                    254:     /* Display the first line */
                    255:     first_line = TRUE;
                    256:     getyx(cw, oy, ox);
                    257:     sprintf(buf, "Int:%d(%d)  Str:%d", stat_ptr->s_intel,
                    258:        max_ptr->s_intel, str_compute());
                    259:
                    260:     /* Maximum strength */
                    261:     pb = &buf[strlen(buf)];
                    262:     sprintf(pb, "(%d)", max_ptr->s_str);
                    263:
                    264:     pb = &buf[strlen(buf)];
                    265:     sprintf(pb, "  Wis:%d(%d)  Dxt:%d(%d)  Const:%d(%d)  Carry:%d(%d)",
                    266:        stat_ptr->s_wisdom,max_ptr->s_wisdom,dex_compute(),max_ptr->s_dext,
                    267:        stat_ptr->s_const,max_ptr->s_const,stat_ptr->s_pack/10,
                    268:        stat_ptr->s_carry/10);
                    269:
                    270:     /* Update first line status */
                    271:     s_intel = stat_ptr->s_intel;
                    272:     s_wisdom = stat_ptr->s_wisdom;
                    273:     s_dext = dex_compute();
                    274:     s_const = stat_ptr->s_const;
                    275:     s_charisma = stat_ptr->s_charisma;
                    276:     s_str = str_compute();
                    277:     s_pack = stat_ptr->s_pack;
                    278:     s_carry = stat_ptr->s_carry;
                    279:     maxs_intel = max_ptr->s_intel;
                    280:     maxs_wisdom = max_ptr->s_wisdom;
                    281:     maxs_dext = max_ptr->s_dext;
                    282:     maxs_const = max_ptr->s_const;
                    283:     maxs_charisma = max_ptr->s_charisma;
                    284:     maxs_str = max_ptr->s_str;
                    285:
                    286:     /* Print the line */
                    287:     mvwaddstr(cw, LINES - 2, 0, buf);
                    288:     wclrtoeol(cw);
                    289:
                    290:     /*
                    291:      * If nothing has changed since the last status, don't
                    292:      * bother.
                    293:      */
                    294: line_two:
                    295:     if (!display                                       &&
                    296:        s_hp == stat_ptr->s_hpt                         &&
                    297:        s_exp == stat_ptr->s_exp                        &&
                    298:         s_pur == purse                                 &&
                    299:        s_ac == ac_compute() - dext_prot(s_dext)        &&
                    300:        s_lvl == level                                  &&
                    301:        s_hungry == hungry_state                        ) return;
                    302:
                    303:     if (!first_line) getyx(cw, oy, ox);
                    304:     if (s_hp != max_ptr->s_hpt)
                    305:     {
                    306:        temp = s_hp = max_ptr->s_hpt;
                    307:        for (hpwidth = 0; temp; hpwidth++)
                    308:            temp /= 10;
                    309:     }
                    310:     sprintf(buf, "Lvl:%d  Au:%d  Hp:%*d(%*d)  Ac:%d  Exp:%d/%lu  %s",
                    311:        level, purse, hpwidth, stat_ptr->s_hpt, hpwidth, max_ptr->s_hpt,
                    312:        ac_compute() - dext_prot(s_dext),stat_ptr->s_lvl, stat_ptr->s_exp,
                    313:        cnames[player.t_ctype][min(stat_ptr->s_lvl-1, 10)]);
                    314:
                    315:     /*
                    316:      * Save old status
                    317:      */
                    318:     s_lvl = level;
                    319:     s_pur = purse;
                    320:     s_hp = stat_ptr->s_hpt;
                    321:     s_exp = stat_ptr->s_exp;
                    322:     s_ac = ac_compute() - dext_prot(s_dext);
                    323:     mvwaddstr(cw, LINES - 1, 0, buf);
                    324:     switch (hungry_state)
                    325:     {
                    326:        case F_OKAY: ;
                    327:        when F_HUNGRY:
                    328:            waddstr(cw, "  Hungry");
                    329:        when F_WEAK:
                    330:            waddstr(cw, "  Weak");
                    331:        when F_FAINT:
                    332:            waddstr(cw, "  Fainting");
                    333:     }
                    334:     wclrtoeol(cw);
                    335:     s_hungry = hungry_state;
                    336:     wmove(cw, oy, ox);
                    337: }
                    338:
                    339: void
                    340: ministat(void)
                    341: {
                    342:     register int oy, ox, temp;
                    343:     static char buf[LINELEN];
                    344:     static int hpwidth = 0;
                    345:     static int s_lvl = -1, s_pur, s_hp = -1;
                    346:
                    347:     /*
                    348:      * If nothing has changed since the last status, don't
                    349:      * bother.
                    350:      */
                    351:     if (s_hp == pstats.s_hpt && s_pur == purse && s_lvl == level)
                    352:            return;
                    353:
                    354:     getyx(cw, oy, ox);
                    355:     if (s_hp != max_stats.s_hpt)
                    356:     {
                    357:        temp = s_hp = max_stats.s_hpt;
                    358:        for (hpwidth = 0; temp; hpwidth++)
                    359:            temp /= 10;
                    360:     }
                    361:     sprintf(buf, "Lv: %d  Au: %-5d  Hp: %*d(%*d)",
                    362:        level, purse, hpwidth, pstats.s_hpt, hpwidth, max_stats.s_hpt);
                    363:
                    364:     /*
                    365:      * Save old status
                    366:      */
                    367:     s_lvl = level;
                    368:     s_pur = purse;
                    369:     s_hp = pstats.s_hpt;
                    370:     mvwaddstr(cw, LINES - 1, 0, buf);
                    371:     wclrtoeol(cw);
                    372:     wmove(cw, oy, ox);
                    373: }
                    374:
                    375: /*
                    376:  * wait_for
                    377:  *     Sit around until the guy types the right key
                    378:  */
                    379:
                    380: void
                    381: wait_for(WINDOW *win, char ch)
                    382: {
                    383:     register char c;
                    384:
                    385:     if (ch == '\n')
                    386:         while ((c = wgetch(win)) != '\n' && c != '\r')
                    387:            continue;
                    388:     else
                    389:         while (wgetch(win) != ch)
                    390:            continue;
                    391: }
                    392:
                    393: /*
                    394:  * show_win:
                    395:  *     function used to display a window and wait before returning
                    396:  */
                    397:
                    398: void
                    399: show_win(WINDOW *scr, char *message)
                    400: {
                    401:     mvwaddstr(scr, 0, 0, message);
                    402:     touchwin(scr);
                    403:     wmove(scr, hero.y, hero.x);
                    404:     draw(scr);
                    405:     wait_for(scr,' ');
                    406:     clearok(cw, TRUE);
                    407:     touchwin(cw);
                    408: }
                    409:
                    410: /*
                    411:  * dbotline:
                    412:  *     Displays message on bottom line and waits for a space to return
                    413:  */
                    414: void
                    415: dbotline(WINDOW *scr, char *message)
                    416: {
                    417:        mvwaddstr(scr,LINES-1,0,message);
                    418:        draw(scr);
                    419:        wait_for(scr,' ');
                    420: }
                    421:
                    422:
                    423: /*
                    424:  * restscr:
                    425:  *     Restores the screen to the terminal
                    426:  */
                    427: void
                    428: restscr(WINDOW *scr)
                    429: {
                    430:        clearok(scr,TRUE);
                    431:        touchwin(scr);
                    432: }
                    433:
                    434: /*
                    435:  * netread:
                    436:  *     Read a byte, short, or long machine independently
                    437:  *     Always returns the value as an unsigned long.
                    438:  */
                    439:
                    440: unsigned long
                    441: netread(int *error, int size, FILE *stream)
                    442: {
                    443:     unsigned long result = 0L, /* What we read in */
                    444:                  partial;      /* Partial value */
                    445:     int nextc, /* The next byte */
                    446:        i;      /* To index through the result a byte at a time */
                    447:
                    448:     /* Be sure we have a right sized chunk */
                    449:     if (size < 1 || size > 4) {
                    450:        *error = 1;
                    451:        return(0L);
                    452:     }
                    453:
                    454:     for (i=0; i<size; i++) {
                    455:        nextc = getc(stream);
                    456:        if (nextc == EOF) {
                    457:            *error = 1;
                    458:            return(0L);
                    459:        }
                    460:        else {
                    461:            partial = (unsigned long) (nextc & 0xff);
                    462:            partial <<= 8*i;
                    463:            result |= partial;
                    464:        }
                    465:     }
                    466:
                    467:     *error = 0;
                    468:     return(result);
                    469: }
                    470:
                    471:
                    472:
                    473: /*
                    474:  * netwrite:
                    475:  *     Write out a byte, short, or long machine independently.
                    476:  * value:      What to write
                    477:  * size:       How much to write out
                    478:  * stream:     Where to write it
                    479:  */
                    480:
                    481: int
                    482: netwrite(unsigned long value, int size, FILE *stream)
                    483: {
                    484:     int i;     /* Goes through value one byte at a time */
                    485:     char outc; /* The next character to be written */
                    486:
                    487:     /* Be sure we have a right sized chunk */
                    488:     if (size < 1 || size > 4) return(0);
                    489:
                    490:     for (i=0; i<size; i++) {
                    491:        outc = (char) ((value >> (8 * i)) & 0xff);
                    492:        putc(outc, stream);
                    493:     }
                    494:     return(size);
                    495: }

CVSweb