home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / TOP / USR / SRC / larn.t.Z / larn.t / display.c < prev    next >
Text File  |  1988-11-13  |  12KB  |  432 lines

  1. /*    display.c        Larn is copyrighted 1986 by Noah Morgan. */
  2. #include "header.h"
  3. #define makecode(_a,_b,_c) (((_a)<<16) + ((_b)<<8) + (_c))
  4.  
  5. static int minx,maxx,miny,maxy,k,m;
  6. static char bot1f=0,bot2f=0,bot3f=0;
  7. char always=0;
  8. /*
  9.     bottomline()
  10.  
  11.     now for the bottom line of the display
  12.  */
  13. bottomline()
  14.     {    recalc();    bot1f=1;    }
  15. bottomhp()
  16.     {    bot2f=1;    }
  17. bottomspell()
  18.     {    bot3f=1;    }
  19. bottomdo()
  20.     {
  21.     if (bot1f) { bot3f=bot1f=bot2f=0; bot_linex(); return; }
  22.     if (bot2f) { bot2f=0; bot_hpx(); }
  23.     if (bot3f) { bot3f=0; bot_spellx(); }
  24.     }
  25.  
  26. bot_linex()
  27.     {
  28.     register int i;
  29.     if (cbak[SPELLS] <= -50 || (always))
  30.         {
  31.         cursor( 1,18);
  32.         if (c[SPELLMAX]>99)  lprintf("Spells:%3d(%3d)",(long)c[SPELLS],(long)c[SPELLMAX]);
  33.                         else lprintf("Spells:%3d(%2d) ",(long)c[SPELLS],(long)c[SPELLMAX]);
  34.         lprintf(" AC: %-3d  WC: %-3d  Level",(long)c[AC],(long)c[WCLASS]);
  35.         if (c[LEVEL]>99) lprintf("%3d",(long)c[LEVEL]);
  36.                     else lprintf(" %-2d",(long)c[LEVEL]);
  37.         lprintf(" Exp: %-9d %s\n",(long)c[EXPERIENCE],class[c[LEVEL]-1]);
  38.         lprintf("HP: %3d(%3d) STR=%-2d INT=%-2d ",
  39.             (long)c[HP],(long)c[HPMAX],(long)(c[STRENGTH]+c[STREXTRA]),(long)c[INTELLIGENCE]);
  40.         lprintf("WIS=%-2d CON=%-2d DEX=%-2d CHA=%-2d LV:",
  41.             (long)c[WISDOM],(long)c[CONSTITUTION],(long)c[DEXTERITY],(long)c[CHARISMA]);
  42.  
  43.         if ((level==0) || (wizard))  c[TELEFLAG]=0;
  44.         if (c[TELEFLAG])  lprcat(" ?");  else  lprcat(levelname[level]);
  45.         lprintf("  Gold: %-6d",(long)c[GOLD]);
  46.         always=1;  botside();
  47.         c[TMP] = c[STRENGTH]+c[STREXTRA];
  48.         for (i=0; i<100; i++) cbak[i]=c[i];
  49.         return;
  50.         }
  51.  
  52.     botsub(makecode(SPELLS,8,18),"%3d");
  53.     if (c[SPELLMAX]>99)  botsub(makecode(SPELLMAX,12,18),"%3d)");
  54.                     else botsub(makecode(SPELLMAX,12,18),"%2d) ");
  55.     botsub(makecode(HP,5,19),"%3d");
  56.     botsub(makecode(HPMAX,9,19),"%3d");
  57.     botsub(makecode(AC,21,18),"%-3d");
  58.     botsub(makecode(WCLASS,30,18),"%-3d");
  59.     botsub(makecode(EXPERIENCE,49,18),"%-9d");
  60.     if (c[LEVEL] != cbak[LEVEL])
  61.         { cursor(59,18);    lprcat(class[c[LEVEL]-1]);  }
  62.     if (c[LEVEL]>99) botsub(makecode(LEVEL,40,18),"%3d");
  63.                 else botsub(makecode(LEVEL,40,18)," %-2d");
  64.     c[TMP] = c[STRENGTH]+c[STREXTRA];    botsub(makecode(TMP,18,19),"%-2d");
  65.     botsub(makecode(INTELLIGENCE,25,19),"%-2d");
  66.     botsub(makecode(WISDOM,32,19),"%-2d");
  67.     botsub(makecode(CONSTITUTION,39,19),"%-2d");
  68.     botsub(makecode(DEXTERITY,46,19),"%-2d");
  69.     botsub(makecode(CHARISMA,53,19),"%-2d");
  70.     if ((level != cbak[CAVELEVEL]) || (c[TELEFLAG] != cbak[TELEFLAG]))
  71.         {
  72.         if ((level==0) || (wizard))  c[TELEFLAG]=0;
  73.         cbak[TELEFLAG] = c[TELEFLAG];
  74.         cbak[CAVELEVEL] = level;    cursor(59,19);
  75.         if (c[TELEFLAG])  lprcat(" ?");  else  lprcat(levelname[level]);
  76.         }
  77.     botsub(makecode(GOLD,69,19),"%-6d");
  78.     botside();
  79.     }
  80.  
  81. /*
  82.     special subroutine to update only the gold number on the bottomlines
  83.     called from ogold()
  84.  */
  85. bottomgold()
  86.     {
  87.     botsub(makecode(GOLD,69,19),"%-6d");
  88. /*    botsub(GOLD,"%-6d",69,19); */
  89.     }
  90.  
  91. /*
  92.     special routine to update hp and level fields on bottom lines
  93.     called in monster.c hitplayer() and spattack()
  94.  */
  95. bot_hpx()
  96.     {
  97.     if (c[EXPERIENCE] != cbak[EXPERIENCE])
  98.         {
  99.         recalc();     bot_linex();
  100.         }
  101.     else botsub(makecode(HP,5,19),"%3d");    
  102.     }
  103.  
  104. /*
  105.     special routine to update number of spells called from regen()
  106.  */
  107. bot_spellx()
  108.     {
  109.     botsub(makecode(SPELLS,9,18),"%2d");
  110.     }
  111.  
  112. /*
  113.     common subroutine for a more economical bottomline()
  114.  */
  115. static struct bot_side_def
  116.     {
  117.     int typ;
  118.     char *string;
  119.     }
  120.     bot_data[] =
  121.     {
  122.     STEALTH,"stealth",        UNDEADPRO,"undead pro",        SPIRITPRO,"spirit pro",
  123.     CHARMCOUNT,"Charm",        TIMESTOP,"Time Stop",        HOLDMONST,"Hold Monst",
  124.     GIANTSTR,"Giant Str",    FIRERESISTANCE,"Fire Resit", DEXCOUNT,"Dexterity",
  125.     STRCOUNT,"Strength",    SCAREMONST,"Scare",            HASTESELF,"Haste Self",
  126.     CANCELLATION,"Cancel",    INVISIBILITY,"Invisible",    ALTPRO,"Protect 3",
  127.     PROTECTIONTIME,"Protect 2", WTW,"Wall-Walk"
  128.     };
  129.  
  130. botside()
  131.     {
  132.     register int i,idx;
  133.     for (i=0; i<17; i++)
  134.         {
  135.         idx = bot_data[i].typ;
  136.         if ((always) || (c[idx] != cbak[idx]))
  137.            {
  138.            if ((always) || (cbak[idx] == 0))
  139.                 { if (c[idx]) { cursor(70,i+1); lprcat(bot_data[i].string); } }  else
  140.            if (c[idx]==0)     { cursor(70,i+1); lprcat("          "); }
  141.            cbak[idx]=c[idx];
  142.            }
  143.         }
  144.     always=0;
  145.     }
  146.  
  147. static botsub(idx,str)
  148.     register int idx;
  149.     char *str;
  150.     {
  151.     register int x,y;
  152.     y = idx & 0xff;        x = (idx>>8) & 0xff;      idx >>= 16;
  153.     if (c[idx] != cbak[idx])
  154.         { cbak[idx]=c[idx];  cursor(x,y);  lprintf(str,(long)c[idx]); }
  155.     }
  156.  
  157. /*
  158.  *    subroutine to draw only a section of the screen
  159.  *    only the top section of the screen is updated.  If entire lines are being
  160.  *    drawn, then they will be cleared first.
  161.  */
  162. int d_xmin=0,d_xmax=MAXX,d_ymin=0,d_ymax=MAXY;    /* for limited screen drawing */
  163. draws(xmin,xmax,ymin,ymax)
  164.     int xmin,xmax,ymin,ymax;
  165.     {
  166.     register int i,idx;
  167.     if (xmin==0 && xmax==MAXX) /* clear section of screen as needed */
  168.         {
  169.         if (ymin==0) cl_up(79,ymax);
  170.         else for (i=ymin; i<ymin; i++)  cl_line(1,i+1);
  171.         xmin = -1;
  172.         }
  173.     d_xmin=xmin;    d_xmax=xmax;    d_ymin=ymin;    d_ymax=ymax;    /* for limited screen drawing */
  174.     drawscreen();
  175.     if (xmin<=0 && xmax==MAXX) /* draw stuff on right side of screen as needed*/
  176.         {
  177.         for (i=ymin; i<ymax; i++)
  178.             {
  179.             idx = bot_data[i].typ;
  180.             if (c[idx])
  181.                 {
  182.                 cursor(70,i+1); lprcat(bot_data[i].string);
  183.                 }
  184.             cbak[idx]=c[idx];
  185.             }
  186.         }
  187.     }
  188.  
  189. /*
  190.     drawscreen()
  191.  
  192.     subroutine to redraw the whole screen as the player knows it
  193.  */
  194. char screen[MAXX][MAXY],d_flag;    /* template for the screen */
  195. drawscreen()
  196.     {
  197.     register int i,j,k;
  198.     int lastx,lasty;  /* variables used to optimize the object printing */
  199.     if (d_xmin==0 && d_xmax==MAXX && d_ymin==0 && d_ymax==MAXY)
  200.         {
  201.         d_flag=1;  clear(); /* clear the screen */
  202.         }
  203.     else 
  204.         {
  205.         d_flag=0;  cursor(1,1);
  206.         }
  207.     if (d_xmin<0)
  208.         d_xmin=0; /* d_xmin=-1 means display all without bottomline */
  209.  
  210.     for (i=d_ymin; i<d_ymax; i++)
  211.       for (j=d_xmin; j<d_xmax; j++)
  212.         if (know[j][i]==0)  screen[j][i] = ' ';  else
  213.         if (k=mitem[j][i])  screen[j][i] = monstnamelist[k];  else
  214.         if ((k=item[j][i])==OWALL) screen[j][i] = '#';
  215.         else screen[j][i] = ' ';
  216.  
  217.     for (i=d_ymin; i<d_ymax; i++)
  218.         {
  219.         j=d_xmin;  while ((screen[j][i]==' ') && (j<d_xmax)) j++;
  220.         /* was m=0 */
  221.         if (j >= d_xmax)  m=d_xmin; /* don't search backwards if blank line */
  222.         else
  223.             {    /* search backwards for end of line */
  224.             m=d_xmax-1;  while ((screen[m][i]==' ') && (m>d_xmin)) --m;
  225.             if (j<=m)  cursor(j+1,i+1);  else continue;
  226.             }
  227.         while (j <= m)
  228.             {
  229.             if (j <= m-3) 
  230.                 {
  231.                 for (k=j; k<=j+3; k++) if (screen[k][i] != ' ') k=1000;
  232.                 if (k < 1000)
  233.                     { while(screen[j][i]==' ' && j<=m) j++;  cursor(j+1,i+1); }
  234.                 }
  235.             lprc(screen[j++][i]);
  236.             }
  237.         }
  238.     setbold();        /* print out only bold objects now */
  239.  
  240.     for (lastx=lasty=127, i=d_ymin; i<d_ymax; i++)
  241.         for (j=d_xmin; j<d_xmax; j++)
  242.             {
  243.             if (k=item[j][i])
  244.                 if (k != OWALL)
  245.                     if ((know[j][i]) && (mitem[j][i]==0))
  246.                         if (objnamelist[k]!=' ')
  247.                             {
  248.                             if (lasty!=i+1 || lastx!=j)
  249.                                 cursor(lastx=j+1,lasty=i+1); else lastx++;
  250.                             lprc(objnamelist[k]);
  251.                             }
  252.             }
  253.  
  254.     resetbold();  if (d_flag)  { always=1; botside(); always=1; bot_linex(); }
  255.     oldx=99;
  256.     d_xmin = 0 , d_xmax = MAXX , d_ymin = 0 , d_ymax = MAXY; /* for limited screen drawing */
  257.     }
  258.  
  259. /*
  260.     showcell(x,y)
  261.  
  262.     subroutine to display a cell location on the screen
  263.  */
  264. showcell(x,y)
  265.     int x,y;
  266.     {
  267.     register int i,j,k,m;
  268.     if (c[BLINDCOUNT])  return;    /* see nothing if blind        */
  269.     if (c[AWARENESS]) { minx = x-3;    maxx = x+3;    miny = y-3;    maxy = y+3; }
  270.             else      { minx = x-1;    maxx = x+1;    miny = y-1;    maxy = y+1; }
  271.  
  272.     if (minx < 0) minx=0;        if (maxx > MAXX-1) maxx = MAXX-1;
  273.     if (miny < 0) miny=0;        if (maxy > MAXY-1) maxy = MAXY-1;
  274.  
  275.     for (j=miny; j<=maxy; j++)
  276.       for (m=minx; m<=maxx; m++)
  277.         if (know[m][j]==0)
  278.             {
  279.             cursor(m+1,j+1);
  280.             x=maxx;  while (know[x][j]) --x;
  281.             for (i=m; i<=x; i++)
  282.                 {
  283.                 if ((k=mitem[i][j]) != 0)  lprc(monstnamelist[k]);
  284.                 else switch(k=item[i][j])
  285.                     {
  286.                     case OWALL:  case 0: case OIVTELETRAP:  case OTRAPARROWIV:
  287.                     case OIVDARTRAP: case OIVTRAPDOOR:    
  288.                         lprc(objnamelist[k]);    break;
  289.  
  290.                     default: setbold(); lprc(objnamelist[k]); resetbold();
  291.                     };
  292.                 know[i][j]=1;
  293.                 }
  294.             m = maxx;
  295.             }
  296.     }
  297.  
  298. /*
  299.     this routine shows only the spot that is given it.  the spaces around
  300.     these coordinated are not shown
  301.     used in godirect() in monster.c for missile weapons display
  302.  */
  303. show1cell(x,y)
  304.     int x,y;
  305.     {
  306.     if (c[BLINDCOUNT])  return;    /* see nothing if blind        */
  307.     cursor(x+1,y+1);
  308.     if ((k=mitem[x][y]) != 0)  lprc(monstnamelist[k]);
  309.         else switch(k=item[x][y])
  310.             {
  311.             case OWALL:  case 0:  case OIVTELETRAP:  case OTRAPARROWIV: 
  312.             case OIVDARTRAP: case OIVTRAPDOOR:    
  313.                 lprc(objnamelist[k]);    break;
  314.  
  315.             default: setbold(); lprc(objnamelist[k]); resetbold();
  316.             };
  317.     know[x][y]|=1;    /* we end up knowing about it */
  318.     }
  319.  
  320. /*
  321.     showplayer()
  322.  
  323.     subroutine to show where the player is on the screen
  324.     cursor values start from 1 up
  325.  */
  326. showplayer()
  327.     {
  328.     cursor(playerx+1,playery+1);
  329.     oldx=playerx;  oldy=playery;
  330.     }
  331.  
  332. /*
  333.     moveplayer(dir)
  334.  
  335.     subroutine to move the player from one room to another
  336.     returns 0 if can't move in that direction or hit a monster or on an object
  337.     else returns 1
  338.     nomove is set to 1 to stop the next move (inadvertent monsters hitting
  339.     players when walking into walls) if player walks off screen or into wall
  340.  */
  341. short diroffx[] = { 0,  0, 1,  0, -1,  1, -1, 1, -1 };
  342. short diroffy[] = { 0,  1, 0, -1,  0, -1, -1, 1,  1 };
  343. moveplayer(dir)
  344.     int dir;            /*    from = present room #  direction = [1-north]
  345.                             [2-east] [3-south] [4-west] [5-northeast]
  346.                             [6-northwest] [7-southeast] [8-southwest]
  347.                         if direction=0, don't move--just show where he is */
  348.     {
  349.     register int k,m,i,j;
  350.     if (c[CONFUSE]) if (c[LEVEL]<rnd(30)) dir=rund(9); /*if confused any dir*/
  351.     k = playerx + diroffx[dir];        m = playery + diroffy[dir];
  352.     if (k<0 || k>=MAXX || m<0 || m>=MAXY) { nomove=1; return(yrepcount = 0); }
  353.     i = item[k][m];            j = mitem[k][m];
  354.     if (i==OWALL && c[WTW]==0) { nomove=1;  return(yrepcount = 0); }        /*    hit a wall    */
  355.     if (k==33 && m==MAXY-1 && level==1)
  356.         {
  357.         newcavelevel(0); for (k=0; k<MAXX; k++) for (m=0; m<MAXY; m++)
  358.         if (item[k][m]==OENTRANCE)
  359.           { playerx=k; playery=m; positionplayer();  drawscreen(); return(0); }
  360.         }
  361.     if (j>0)     { hitmonster(k,m);    return(yrepcount = 0); } /* hit a monster*/
  362.     lastpx = playerx;            lastpy = playery;
  363.     playerx = k;        playery = m;
  364.     if (i && i!=OTRAPARROWIV && i!=OIVTELETRAP && i!=OIVDARTRAP && i!=OIVTRAPDOOR) return(yrepcount = 0);  else return(1);
  365.     }
  366.  
  367. /*
  368.  *    function to show what magic items have been discovered thus far
  369.  *    enter with -1 for just spells, anything else will give scrolls & potions
  370.  */
  371. static int lincount,count;
  372. seemagic(arg)
  373.     int arg;
  374.     {
  375.     register int i,number;
  376.     count = lincount = 0;  nosignal=1;
  377.  
  378.     if (arg== -1) /* if display spells while casting one */
  379.         {
  380.         for (number=i=0; i<SPNUM; i++) if (spelknow[i]) number++;
  381.         number = (number+2)/3 + 4;    /* # lines needed to display */
  382.         cl_up(79,number);  cursor(1,1);
  383.         }
  384.     else
  385.         {
  386.         resetscroll();  clear();
  387.         }
  388.  
  389.     lprcat("The magic spells you have discovered thus far:\n\n");
  390.     for (i=0; i<SPNUM; i++)
  391.         if (spelknow[i])
  392.             { lprintf("%s %-20s ",spelcode[i],spelname[i]);  seepage(); }
  393.  
  394.     if (arg== -1)
  395.         {
  396.         seepage();  more();     nosignal=0;
  397.         draws(0,MAXX,0,number);  return;
  398.         }
  399.  
  400.     lincount += 3;  if (count!=0) { count=2;  seepage(); }
  401.  
  402.     lprcat("\nThe magic scrolls you have found to date are:\n\n");
  403.     count=0;
  404.     for (i=0; i<MAXSCROLL; i++)
  405.         if (scrollname[i][0])
  406.           if (scrollname[i][1]!=' ')
  407.             { lprintf("%-26s",&scrollname[i][1]);  seepage(); }
  408.  
  409.     lincount += 3;  if (count!=0) { count=2;  seepage(); }
  410.  
  411.     lprcat("\nThe magic potions you have found to date are:\n\n");
  412.     count=0;
  413.     for (i=0; i<MAXPOTION; i++)
  414.         if (potionname[i][0])
  415.           if (potionname[i][1]!=' ')
  416.             { lprintf("%-26s",&potionname[i][1]);  seepage(); }
  417.  
  418.     if (lincount!=0) more();    nosignal=0;  setscroll();    drawscreen();
  419.     }
  420.  
  421. /*
  422.  *    subroutine to paginate the seemagic function
  423.  */
  424. seepage()
  425.     {
  426.     if (++count==3)
  427.         {
  428.         lincount++;    count=0;    lprc('\n');
  429.         if (lincount>17) {    lincount=0;  more();  clear();    }
  430.         }
  431.     }
  432.