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

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

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

CVSweb