[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     ! 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