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

Annotation of early-roguelike/xrogue/io.c, Revision 1.1

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

CVSweb