term.c revision 1.1
11.1Skamil/* $Header: /tank/opengrok/rsync2/NetBSD/src/games/warp/term.c,v 1.1 2020/11/09 23:37:05 kamil Exp $ */ 21.1Skamil 31.1Skamil/* $Log: term.c,v $ 41.1Skamil/* Revision 1.1 2020/11/09 23:37:05 kamil 51.1Skamil/* Add Warp Kit, Version 7.0 by Larry Wall 61.1Skamil/* 71.1Skamil/* Warp is a real-time space war game that doesn't get boring very quickly. 81.1Skamil/* Read warp.doc and the manual page for more information. 91.1Skamil/* 101.1Skamil/* games/warp originally distributed with 4.3BSD-Reno, is back to the BSD 111.1Skamil/* world via NetBSD. Its remnants were still mentioned in games/Makefile. 121.1Skamil/* 131.1Skamil/* Larry Wall, the original author and the copyright holder, generously 141.1Skamil/* donated the game and copyright to The NetBSD Foundation, Inc. 151.1Skamil/* 161.1Skamil/* Import the game sources as-is from 4.3BSD-Reno, with the cession 171.1Skamil/* of the copyright and license to BSD-2-clause NetBSD-style. 181.1Skamil/* 191.1Skamil/* Signed-off-by: Larry Wall <larry@wall.org> 201.1Skamil/* Signed-off-by: Kamil Rytarowski <kamil@netbsd.org> 211.1Skamil/* 221.1Skamil * Revision 7.0.1.2 86/12/12 17:04:09 lwall 231.1Skamil * Baseline for net release. 241.1Skamil * 251.1Skamil * Revision 7.0.1.1 86/10/16 10:53:20 lwall 261.1Skamil * Added Damage. Fixed random bugs. 271.1Skamil * 281.1Skamil * Revision 7.0 86/10/08 15:14:02 lwall 291.1Skamil * Split into separate files. Added amoebas and pirates. 301.1Skamil * 311.1Skamil */ 321.1Skamil 331.1Skamil#include "EXTERN.h" 341.1Skamil#include "warp.h" 351.1Skamil#include "bang.h" 361.1Skamil#include "intrp.h" 371.1Skamil#include "object.h" 381.1Skamil#include "play.h" 391.1Skamil#include "score.h" 401.1Skamil#include "sig.h" 411.1Skamil#include "us.h" 421.1Skamil#include "util.h" 431.1Skamil#include "weapon.h" 441.1Skamil#include "INTERN.h" 451.1Skamil#include "term.h" 461.1Skamil 471.1Skamilint typeahead = FALSE; 481.1Skamil 491.1Skamilchar tcarea[TCSIZE]; /* area for "compiled" termcap strings */ 501.1Skamil 511.1Skamil/* guarantee capability pointer != Nullch */ 521.1Skamil/* (I believe terminfo will ignore the &tmpaddr argument.) */ 531.1Skamil 541.1Skamil#define Tgetstr(key) ((tstr = tgetstr(key,&tmpaddr)) ? tstr : nullstr) 551.1Skamil 561.1Skamil#ifdef PUSHBACK 571.1Skamilstruct keymap { 581.1Skamil char km_type[128]; 591.1Skamil union km_union { 601.1Skamil struct keymap *km_km; 611.1Skamil char *km_str; 621.1Skamil } km_ptr[128]; 631.1Skamil}; 641.1Skamil 651.1Skamil#define KM_NOTHIN 0 661.1Skamil#define KM_STRING 1 671.1Skamil#define KM_KEYMAP 2 681.1Skamil#define KM_BOGUS 3 691.1Skamil 701.1Skamil#define KM_TMASK 3 711.1Skamil#define KM_GSHIFT 4 721.1Skamil#define KM_GMASK 7 731.1Skamil 741.1Skamiltypedef struct keymap KEYMAP; 751.1Skamil 761.1SkamilKEYMAP *topmap INIT(Null(KEYMAP*)); 771.1Skamil 781.1Skamilvoid mac_init(); 791.1SkamilKEYMAP *newkeymap(); 801.1Skamilvoid pushstring(); 811.1Skamil#endif 821.1Skamil 831.1Skamil/* terminal initialization */ 841.1Skamil 851.1Skamilvoid 861.1Skamilterm_init() 871.1Skamil{ 881.1Skamil savetty(); /* remember current tty state */ 891.1Skamil 901.1Skamil#ifdef TERMIO 911.1Skamil ospeed = _tty.c_cflag & CBAUD; /* for tputs() */ 921.1Skamil ERASECH = _tty.c_cc[VERASE]; /* for finish_command() */ 931.1Skamil KILLCH = _tty.c_cc[VKILL]; /* for finish_command() */ 941.1Skamil#else 951.1Skamil ospeed = _tty.sg_ospeed; /* for tputs() */ 961.1Skamil ERASECH = _tty.sg_erase; /* for finish_command() */ 971.1Skamil KILLCH = _tty.sg_kill; /* for finish_command() */ 981.1Skamil#endif 991.1Skamil 1001.1Skamil /* The following could be a table but I can't be sure that there isn't */ 1011.1Skamil /* some degree of sparsity out there in the world. */ 1021.1Skamil 1031.1Skamil switch (ospeed) { /* 1 second of padding */ 1041.1Skamil#ifdef BEXTA 1051.1Skamil case BEXTA: just_a_sec = 1920; break; 1061.1Skamil#else 1071.1Skamil#ifdef B19200 1081.1Skamil case B19200: just_a_sec = 1920; break; 1091.1Skamil#endif 1101.1Skamil#endif 1111.1Skamil case B9600: just_a_sec = 960; break; 1121.1Skamil case B4800: just_a_sec = 480; break; 1131.1Skamil case B2400: just_a_sec = 240; break; 1141.1Skamil case B1800: just_a_sec = 180; break; 1151.1Skamil case B1200: just_a_sec = 120; break; 1161.1Skamil case B600: just_a_sec = 60; break; 1171.1Skamil case B300: just_a_sec = 30; break; 1181.1Skamil /* do I really have to type the rest of this??? */ 1191.1Skamil case B200: just_a_sec = 20; break; 1201.1Skamil case B150: just_a_sec = 15; break; 1211.1Skamil case B134: just_a_sec = 13; break; 1221.1Skamil case B110: just_a_sec = 11; break; 1231.1Skamil case B75: just_a_sec = 8; break; 1241.1Skamil case B50: just_a_sec = 5; break; 1251.1Skamil default: just_a_sec = 960; break; 1261.1Skamil /* if we are running detached I */ 1271.1Skamil } /* don't want to know about it! */ 1281.1Skamil} 1291.1Skamil 1301.1Skamil/* set terminal characteristics */ 1311.1Skamil 1321.1Skamilvoid 1331.1Skamilterm_set(tcbuf) 1341.1Skamilchar *tcbuf; /* temp area for "uncompiled" termcap entry */ 1351.1Skamil{ 1361.1Skamil char *tmpaddr; /* must not be register */ 1371.1Skamil Reg1 char *tstr; 1381.1Skamil char *tgetstr(); 1391.1Skamil char *s; 1401.1Skamil int retval; 1411.1Skamil 1421.1Skamil#ifdef PENDING 1431.1Skamil#ifndef FIONREAD 1441.1Skamil#ifndef RDCHK 1451.1Skamil /* do no delay reads on something that always gets closed on exit */ 1461.1Skamil 1471.1Skamil devtty = open("/dev/tty",0); 1481.1Skamil if (devtty < 0) { 1491.1Skamil printf(cantopen,"/dev/tty"); 1501.1Skamil finalize(1); 1511.1Skamil } 1521.1Skamil fcntl(devtty,F_SETFL,O_NDELAY); 1531.1Skamil#endif 1541.1Skamil#endif 1551.1Skamil#endif 1561.1Skamil 1571.1Skamil /* get all that good termcap stuff */ 1581.1Skamil 1591.1Skamil retval = tgetent(tcbuf,getenv("TERM")); /* get termcap entry */ 1601.1Skamil if (retval < 1) { 1611.1Skamil#ifdef VERBOSE 1621.1Skamil printf("No termcap %s found.\n", retval ? "file" : "entry"); 1631.1Skamil#else 1641.1Skamil fputs("Termcap botch\n",stdout); 1651.1Skamil#endif 1661.1Skamil finalize(1); 1671.1Skamil } 1681.1Skamil tmpaddr = tcarea; /* set up strange tgetstr pointer */ 1691.1Skamil s = Tgetstr("pc"); /* get pad character */ 1701.1Skamil PC = *s; /* get it where tputs wants it */ 1711.1Skamil if (!tgetflag("bs")) { /* is backspace not used? */ 1721.1Skamil BC = Tgetstr("bc"); /* find out what is */ 1731.1Skamil if (BC == nullstr) /* terminfo grok's 'bs' but not 'bc' */ 1741.1Skamil BC = Tgetstr("le"); 1751.1Skamil } else 1761.1Skamil BC = "\b"; /* make a backspace handy */ 1771.1Skamil UP = Tgetstr("up"); /* move up a line */ 1781.1Skamil ND = Tgetstr("nd"); /* non-destructive move cursor right */ 1791.1Skamil DO = Tgetstr("do"); /* move cursor down */ 1801.1Skamil if (!*DO) 1811.1Skamil DO = Tgetstr("nl"); 1821.1Skamil CL = Tgetstr("cl"); /* get clear string */ 1831.1Skamil CE = Tgetstr("ce"); /* clear to end of line string */ 1841.1Skamil CM = Tgetstr("cm"); /* cursor motion - PWP */ 1851.1Skamil HO = Tgetstr("ho"); /* home cursor if no CM - PWP */ 1861.1Skamil CD = Tgetstr("cd"); /* clear to end of display - PWP */ 1871.1Skamil SO = Tgetstr("so"); /* begin standout */ 1881.1Skamil SE = Tgetstr("se"); /* end standout */ 1891.1Skamil if ((SG = tgetnum("sg"))<0) 1901.1Skamil SG = 0; /* blanks left by SG, SE */ 1911.1Skamil US = Tgetstr("us"); /* start underline */ 1921.1Skamil UE = Tgetstr("ue"); /* end underline */ 1931.1Skamil if ((UG = tgetnum("ug"))<0) 1941.1Skamil UG = 0; /* blanks left by US, UE */ 1951.1Skamil if (*US) 1961.1Skamil UC = nullstr; /* UC must not be NULL */ 1971.1Skamil else 1981.1Skamil UC = Tgetstr("uc"); /* underline a character */ 1991.1Skamil if (!*US && !*UC) { /* no underline mode? */ 2001.1Skamil US = SO; /* substitute standout mode */ 2011.1Skamil UE = SE; 2021.1Skamil UG = SG; 2031.1Skamil } 2041.1Skamil LINES = tgetnum("li"); /* lines per page */ 2051.1Skamil COLS = tgetnum("co"); /* columns on page */ 2061.1Skamil AM = tgetflag("am"); /* terminal wraps automatically? */ 2071.1Skamil XN = tgetflag("xn"); /* then eats next newline? */ 2081.1Skamil VB = Tgetstr("vb"); 2091.1Skamil if (!*VB) 2101.1Skamil VB = "\007"; 2111.1Skamil CR = Tgetstr("cr"); 2121.1Skamil if (!*CR) { 2131.1Skamil if (tgetflag("nc") && *UP) { 2141.1Skamil CR = safemalloc((MEM_SIZE)strlen(UP)+2); 2151.1Skamil Sprintf(CR,"%s\r",UP); 2161.1Skamil } 2171.1Skamil else 2181.1Skamil CR = "\r"; 2191.1Skamil } 2201.1Skamil if (LINES <= 0) 2211.1Skamil LINES = 24; 2221.1Skamil if (COLS <= 0) 2231.1Skamil COLS = 80; 2241.1Skamil 2251.1Skamil BCsize = comp_tc(bsptr,BC,1); 2261.1Skamil BC = bsptr; 2271.1Skamil 2281.1Skamil if (!*ND) /* not defined? */ 2291.1Skamil NDsize = 1000; /* force cursor addressing */ 2301.1Skamil else { 2311.1Skamil NDsize = comp_tc(cmbuffer,ND,1); 2321.1Skamil myND = malloc((unsigned)NDsize); 2331.1Skamil movc3(NDsize,cmbuffer,myND); 2341.1Skamil if (debugging) { 2351.1Skamil int scr; 2361.1Skamil 2371.1Skamil printf("ND"); 2381.1Skamil for (scr=0; scr<NDsize; scr++) 2391.1Skamil printf(" %d",myND[scr]); 2401.1Skamil printf("\n"); 2411.1Skamil } 2421.1Skamil } 2431.1Skamil 2441.1Skamil if (!*UP) /* not defined? */ 2451.1Skamil UPsize = 1000; /* force cursor addressing */ 2461.1Skamil else { 2471.1Skamil UPsize = comp_tc(cmbuffer,UP,1); 2481.1Skamil myUP = malloc((unsigned)UPsize); 2491.1Skamil movc3(UPsize,cmbuffer,myUP); 2501.1Skamil if (debugging) { 2511.1Skamil int scr; 2521.1Skamil 2531.1Skamil printf("UP"); 2541.1Skamil for (scr=0; scr<UPsize; scr++) 2551.1Skamil printf(" %d",myUP[scr]); 2561.1Skamil printf("\n"); 2571.1Skamil } 2581.1Skamil } 2591.1Skamil 2601.1Skamil if (!*DO) { /* not defined? */ 2611.1Skamil myDO = DO = "\n"; /* assume a newline */ 2621.1Skamil DOsize = 1; 2631.1Skamil } 2641.1Skamil else { 2651.1Skamil DOsize = comp_tc(cmbuffer,DO,1); 2661.1Skamil myDO = malloc((unsigned)DOsize); 2671.1Skamil movc3(DOsize,cmbuffer,myDO); 2681.1Skamil if (debugging) { 2691.1Skamil int scr; 2701.1Skamil 2711.1Skamil printf("DO"); 2721.1Skamil for (scr=0; scr<DOsize; scr++) 2731.1Skamil printf(" %d",myDO[scr]); 2741.1Skamil printf("\n"); 2751.1Skamil } 2761.1Skamil } 2771.1Skamil if (debugging) 2781.1Skamil Fgets(cmbuffer,(sizeof cmbuffer),stdin); 2791.1Skamil 2801.1Skamil CMsize = comp_tc(cmbuffer,tgoto(CM,20,20),0); 2811.1Skamil if (PC != '\0') { 2821.1Skamil char *p; 2831.1Skamil 2841.1Skamil for (p=filler+(sizeof filler)-1;!*p;--p) 2851.1Skamil *p = PC; 2861.1Skamil } 2871.1Skamil charsperhalfsec = ospeed >= B9600 ? 480 : 2881.1Skamil ospeed == B4800 ? 240 : 2891.1Skamil ospeed == B2400 ? 120 : 2901.1Skamil ospeed == B1200 ? 60 : 2911.1Skamil ospeed == B600 ? 30 : 2921.1Skamil /* speed is 300 (?) */ 15; 2931.1Skamil 2941.1Skamil gfillen = ospeed >= B9600 ? (sizeof filler) : 2951.1Skamil ospeed == B4800 ? 13 : 2961.1Skamil ospeed == B2400 ? 7 : 2971.1Skamil ospeed == B1200 ? 4 : 2981.1Skamil 1+BCsize; 2991.1Skamil if (ospeed < B2400) 3001.1Skamil lowspeed = TRUE; 3011.1Skamil 3021.1Skamil strcpy(term,ttyname(2)); 3031.1Skamil 3041.1Skamil if (!*CM || !BCsize) 3051.1Skamil no_can_do("dumb"); 3061.1Skamil if (!scorespec && (LINES < 24 || COLS < 80)) 3071.1Skamil no_can_do("puny"); 3081.1Skamil 3091.1Skamil crmode(); 3101.1Skamil raw(); 3111.1Skamil noecho(); /* turn off echo */ 3121.1Skamil nonl(); 3131.1Skamil 3141.1Skamil#ifdef PUSHBACK 3151.1Skamil mac_init(tcbuf); 3161.1Skamil#endif 3171.1Skamil} 3181.1Skamil 3191.1Skamil#ifdef PUSHBACK 3201.1Skamilvoid 3211.1Skamilmac_init(tcbuf) 3221.1Skamilchar *tcbuf; 3231.1Skamil{ 3241.1Skamil char tmpbuf[1024]; 3251.1Skamil 3261.1Skamil tmpfp = fopen(filexp(getval("WARPMACRO",WARPMACRO)),"r"); 3271.1Skamil if (tmpfp != Nullfp) { 3281.1Skamil while (fgets(tcbuf,1024,tmpfp) != Nullch) { 3291.1Skamil mac_line(tcbuf,tmpbuf,(sizeof tmpbuf)); 3301.1Skamil } 3311.1Skamil Fclose(tmpfp); 3321.1Skamil } 3331.1Skamil} 3341.1Skamil 3351.1Skamilvoid 3361.1Skamilmac_line(line,tmpbuf,tbsize) 3371.1Skamilchar *line; 3381.1Skamilchar *tmpbuf; 3391.1Skamilint tbsize; 3401.1Skamil{ 3411.1Skamil Reg1 char *s; 3421.1Skamil Reg2 char *m; 3431.1Skamil Reg3 KEYMAP *curmap; 3441.1Skamil Reg4 int ch; 3451.1Skamil Reg5 int garbage = 0; 3461.1Skamil static char override[] = "\r\nkeymap overrides string\r\n"; 3471.1Skamil 3481.1Skamil if (topmap == Null(KEYMAP*)) 3491.1Skamil topmap = newkeymap(); 3501.1Skamil if (*line == '#' || *line == '\n') 3511.1Skamil return; 3521.1Skamil if (line[ch = strlen(line)-1] == '\n') 3531.1Skamil line[ch] = '\0'; 3541.1Skamil m = dointerp(tmpbuf,tbsize,line," \t"); 3551.1Skamil if (!*m) 3561.1Skamil return; 3571.1Skamil while (*m == ' ' || *m == '\t') m++; 3581.1Skamil for (s=tmpbuf,curmap=topmap; *s; s++) { 3591.1Skamil ch = *s & 0177; 3601.1Skamil if (s[1] == '+' && isdigit(s[2])) { 3611.1Skamil s += 2; 3621.1Skamil garbage = (*s & KM_GMASK) << KM_GSHIFT; 3631.1Skamil } 3641.1Skamil else 3651.1Skamil garbage = 0; 3661.1Skamil if (s[1]) { 3671.1Skamil if ((curmap->km_type[ch] & KM_TMASK) == KM_STRING) { 3681.1Skamil puts(override); 3691.1Skamil free(curmap->km_ptr[ch].km_str); 3701.1Skamil curmap->km_ptr[ch].km_str = Nullch; 3711.1Skamil } 3721.1Skamil curmap->km_type[ch] = KM_KEYMAP + garbage; 3731.1Skamil if (curmap->km_ptr[ch].km_km == Null(KEYMAP*)) 3741.1Skamil curmap->km_ptr[ch].km_km = newkeymap(); 3751.1Skamil curmap = curmap->km_ptr[ch].km_km; 3761.1Skamil } 3771.1Skamil else { 3781.1Skamil if ((curmap->km_type[ch] & KM_TMASK) == KM_KEYMAP) 3791.1Skamil puts(override); 3801.1Skamil else { 3811.1Skamil curmap->km_type[ch] = KM_STRING + garbage; 3821.1Skamil curmap->km_ptr[ch].km_str = savestr(m); 3831.1Skamil } 3841.1Skamil } 3851.1Skamil } 3861.1Skamil} 3871.1Skamil 3881.1SkamilKEYMAP* 3891.1Skamilnewkeymap() 3901.1Skamil{ 3911.1Skamil Reg1 int i; 3921.1Skamil Reg2 KEYMAP *map; 3931.1Skamil 3941.1Skamil#ifndef lint 3951.1Skamil map = (KEYMAP*)safemalloc(sizeof(KEYMAP)); 3961.1Skamil#else 3971.1Skamil map = Null(KEYMAP*); 3981.1Skamil#endif /* lint */ 3991.1Skamil for (i=127; i>=0; --i) { 4001.1Skamil map->km_ptr[i].km_km = Null(KEYMAP*); 4011.1Skamil map->km_type[i] = KM_NOTHIN; 4021.1Skamil } 4031.1Skamil return map; 4041.1Skamil} 4051.1Skamil 4061.1Skamil#endif 4071.1Skamil 4081.1Skamil/* print out a file, stopping at form feeds */ 4091.1Skamil 4101.1Skamilvoid 4111.1Skamilpage(filename,num) 4121.1Skamilchar *filename; 4131.1Skamilbool num; 4141.1Skamil{ 4151.1Skamil int linenum = 1; 4161.1Skamil 4171.1Skamil tmpfp = fopen(filename,"r"); 4181.1Skamil if (tmpfp != NULL) { 4191.1Skamil while (fgets(spbuf,(sizeof spbuf),tmpfp) != NULL) { 4201.1Skamil if (*spbuf == '\f') { 4211.1Skamil printf("[Type anything to continue] "); 4221.1Skamil Fflush(stdout); 4231.1Skamil getcmd(spbuf); 4241.1Skamil printf("\r\n"); 4251.1Skamil if (*spbuf == INTRCH) 4261.1Skamil finalize(0); 4271.1Skamil if (*spbuf == 'q' || *spbuf == 'Q') 4281.1Skamil break; 4291.1Skamil } 4301.1Skamil else { 4311.1Skamil if (num) 4321.1Skamil printf("%3d %s\r",linenum++,spbuf); 4331.1Skamil else 4341.1Skamil printf("%s\r",spbuf); 4351.1Skamil } 4361.1Skamil } 4371.1Skamil Fclose(tmpfp); 4381.1Skamil } 4391.1Skamil} 4401.1Skamil 4411.1Skamilvoid 4421.1Skamilmove(y, x, chadd) 4431.1Skamilint y, x; 4441.1Skamilint chadd; 4451.1Skamil{ 4461.1Skamil Reg1 int ydist; 4471.1Skamil Reg2 int xdist; 4481.1Skamil Reg3 int i; 4491.1Skamil Reg4 char *s; 4501.1Skamil 4511.1Skamil ydist = y - real_y; 4521.1Skamil xdist = x - real_x; 4531.1Skamil i = ydist * (ydist < 0 ? -UPsize : DOsize) + 4541.1Skamil xdist * (xdist < 0 ? -BCsize : NDsize); 4551.1Skamil beg_qwrite(); 4561.1Skamil if (i <= CMsize) { 4571.1Skamil if (ydist < 0) 4581.1Skamil for (; ydist; ydist++) 4591.1Skamil for (i=UPsize,s=myUP; i; i--) 4601.1Skamil qaddch(*s++); 4611.1Skamil else 4621.1Skamil for (; ydist; ydist--) 4631.1Skamil for (i=DOsize,s=myDO; i; i--) 4641.1Skamil qaddch(*s++); 4651.1Skamil if (xdist < 0) 4661.1Skamil for (; xdist; xdist++) 4671.1Skamil for (i=BCsize,s=BC; i; i--) 4681.1Skamil qaddch(*s++); 4691.1Skamil else 4701.1Skamil for (; xdist; xdist--) 4711.1Skamil for (i=NDsize,s=myND; i; i--) 4721.1Skamil qaddch(*s++); 4731.1Skamil } 4741.1Skamil else { 4751.1Skamil tputs(tgoto(CM,x,y),0,cmstore); 4761.1Skamil } 4771.1Skamil real_y = y; 4781.1Skamil real_x = x; 4791.1Skamil if (chadd) { 4801.1Skamil qaddch(chadd); 4811.1Skamil } 4821.1Skamil if (maxcmstring != cmbuffer) 4831.1Skamil end_qwrite(); 4841.1Skamil} 4851.1Skamil 4861.1Skamilvoid 4871.1Skamildo_tc(s,l) 4881.1Skamilchar *s; 4891.1Skamilint l; 4901.1Skamil{ 4911.1Skamil beg_qwrite(); 4921.1Skamil tputs(s,l,cmstore); 4931.1Skamil end_qwrite(); 4941.1Skamil} 4951.1Skamil 4961.1Skamilint 4971.1Skamilcomp_tc(dest,s,l) 4981.1Skamilchar *dest; 4991.1Skamilchar *s; 5001.1Skamilint l; 5011.1Skamil{ 5021.1Skamil maxcmstring = dest; 5031.1Skamil tputs(s,l,cmstore); 5041.1Skamil return(maxcmstring-dest); 5051.1Skamil} 5061.1Skamil 5071.1Skamilvoid 5081.1Skamilhelper() 5091.1Skamil{ 5101.1Skamil clear(); 5111.1Skamil mvaddstr(0,4,"h or 4 left"); 5121.1Skamil mvaddstr(1,4,"j or 2 down Use with SHIFT to fire torpedoes."); 5131.1Skamil mvaddstr(2,4,"k or 8 up Use with CTRL or FUNCT to fire"); 5141.1Skamil mvaddstr(3,4,"l or 6 right phasers or turbolasers."); 5151.1Skamil mvaddstr(4,4,"b or 1 down and left Use preceded by 'a' or 'r' for"); 5161.1Skamil mvaddstr(5,4,"n or 3 down and right attractors or repulsors."); 5171.1Skamil mvaddstr(6,4,"y or 7 up and left Use normally for E or B motion."); 5181.1Skamil mvaddstr(7,4,"u or 9 up and right"); 5191.1Skamil mvaddstr(8,4,""); 5201.1Skamil mvaddstr(9,4,"del or % fire photon torpedoes in every (reasonable) direction."); 5211.1Skamil mvaddstr(10,4,"s stop all torpedoes."); 5221.1Skamil mvaddstr(11,4,"S or 0 stop the Enterprise when in warp mode."); 5231.1Skamil mvaddstr(12,4,"d/D destruct all torpedoes/current vessel."); 5241.1Skamil mvaddstr(13,4,"i/w switch to Enterprise & put into impulse/warp mode."); 5251.1Skamil mvaddstr(14,4,"c/v switch to Enterprise & make cloaked/visible."); 5261.1Skamil mvaddstr(15,4,"p switch to Base."); 5271.1Skamil mvaddstr(16,4,"o toggle to other vessel (from E to B, or vice versa.)"); 5281.1Skamil mvaddstr(17,4,"z zap (suppress) blasts near Enterprise next cycle"); 5291.1Skamil mvaddstr(18,4,""); 5301.1Skamil mvaddstr(19,4,"^R refresh the screen. ^Z suspend the game."); 5311.1Skamil mvaddstr(20,4,"q exit this round (if you haven't typed q within 10 cycles)."); 5321.1Skamil mvaddstr(21,4,"Q exit this game."); 5331.1Skamil mvaddstr(22,4,""); 5341.1Skamil mvaddstr(23,4," [Hit space to continue]"); 5351.1Skamil Fflush(stdout); 5361.1Skamil do { 5371.1Skamil getcmd(spbuf); 5381.1Skamil } while (*spbuf != ' '); 5391.1Skamil rewrite(); 5401.1Skamil 5411.1Skamil} 5421.1Skamil 5431.1Skamilvoid 5441.1Skamilrewrite() 5451.1Skamil{ 5461.1Skamil Reg1 int x; 5471.1Skamil Reg2 int y; 5481.1Skamil Reg3 OBJECT *obj; 5491.1Skamil 5501.1Skamil clear(); 5511.1Skamil for (y=0; y<YSIZE; y++) { 5521.1Skamil for (x=0; x<XSIZE; x++) { 5531.1Skamil if (numamoebas && amb[y][x] != ' ') 5541.1Skamil mvaddc(y+1,x*2,amb[y][x]); 5551.1Skamil if (obj=occupant[y][x]) { 5561.1Skamil if (obj->image != ' ') 5571.1Skamil mvaddc(y+1,x*2,obj->image); 5581.1Skamil } 5591.1Skamil } 5601.1Skamil } 5611.1Skamil Sprintf(spbuf, 5621.1Skamil "%-4s E: %4d %2d B: %5d %3d Enemies: %-3d Stars: %-3d Stardate%5d.%1d %9ld", 5631.1Skamil " ", 0, 0, 0, 0, 0, 0, timer/10+smarts*100, timer%10, 0L); 5641.1Skamil mvaddstr(0,0,spbuf); 5651.1Skamil oldeenergy = oldbenergy = oldcurscore = 5661.1Skamil oldstatus = oldetorp = oldbtorp = oldstrs = oldenemies = -1; 5671.1Skamil /* force everything to fill in */ 5681.1Skamil if (damage) 5691.1Skamil olddamage = 0; 5701.1Skamil if (!ent) 5711.1Skamil etorp = 0; 5721.1Skamil if (!base) 5731.1Skamil btorp = 0; 5741.1Skamil display_status(); 5751.1Skamil} 5761.1Skamil 5771.1Skamilchar 5781.1Skamilcmstore(ch) 5791.1SkamilReg1 char ch; 5801.1Skamil{ 5811.1Skamil *maxcmstring++ = ch; 5821.1Skamil} 5831.1Skamil 5841.1Skamil/* discard any characters typed ahead */ 5851.1Skamil 5861.1Skamilvoid 5871.1Skamileat_typeahead() 5881.1Skamil{ 5891.1Skamil#ifdef PUSHBACK 5901.1Skamil if (!typeahead && nextin==nextout) /* cancel only keyboard stuff */ 5911.1Skamil#else 5921.1Skamil if (!typeahead) 5931.1Skamil#endif 5941.1Skamil { 5951.1Skamil#ifdef PENDING 5961.1Skamil while (input_pending()) 5971.1Skamil Read_tty(buf,sizeof(buf)); 5981.1Skamil#else /* this is probably v7, with no rdchk() */ 5991.1Skamil ioctl(_tty_ch,TIOCSETP,&_tty); 6001.1Skamil#endif 6011.1Skamil } 6021.1Skamil} 6031.1Skamil 6041.1Skamilvoid 6051.1Skamilsettle_down() 6061.1Skamil{ 6071.1Skamil dingaling(); 6081.1Skamil Fflush(stdout); 6091.1Skamil sleep(1); 6101.1Skamil#ifdef PUSHBACK 6111.1Skamil nextout = nextin; /* empty circlebuf */ 6121.1Skamil#endif 6131.1Skamil eat_typeahead(); 6141.1Skamil} 6151.1Skamil 6161.1Skamil#ifdef PUSHBACK 6171.1Skamil/* read a character from the terminal, with multi-character pushback */ 6181.1Skamil 6191.1Skamilint 6201.1Skamilread_tty(addr,size) 6211.1Skamilchar *addr; 6221.1Skamilint size; /* ignored for now */ 6231.1Skamil{ 6241.1Skamil#ifdef lint 6251.1Skamil size = size; 6261.1Skamil#endif 6271.1Skamil if (nextout != nextin) { 6281.1Skamil *addr = circlebuf[nextout++]; 6291.1Skamil nextout %= PUSHSIZE; 6301.1Skamil return 1; 6311.1Skamil } 6321.1Skamil else { 6331.1Skamil size = read(0,addr,1); 6341.1Skamil if (size < 0) 6351.1Skamil sig_catcher(SIGHUP); 6361.1Skamil if (metakey) { 6371.1Skamil if (*addr & 0200) { 6381.1Skamil pushchar(*addr & 0177); 6391.1Skamil *addr = '\001'; 6401.1Skamil } 6411.1Skamil } 6421.1Skamil else 6431.1Skamil *addr &= 0177; 6441.1Skamil return 1; 6451.1Skamil } 6461.1Skamil} 6471.1Skamil 6481.1Skamil#ifdef PENDING 6491.1Skamil#ifndef FIONREAD 6501.1Skamil#ifndef RDCHK 6511.1Skamilint 6521.1Skamilcircfill() 6531.1Skamil{ 6541.1Skamil Reg1 int howmany; 6551.1Skamil Reg2 int i; 6561.1Skamil 6571.1Skamil assert (nextin == nextout); 6581.1Skamil howmany = read(devtty,circlebuf+nextin,metakey?1:PUSHSIZE-nextin); 6591.1Skamil if (howmany > 0) { 6601.1Skamil if (metakey) { 6611.1Skamil if (circlebuf[nextin] & 0200) { 6621.1Skamil circlebuf[nextin] &= 0177; 6631.1Skamil pushchar('\001'); 6641.1Skamil } 6651.1Skamil } 6661.1Skamil else 6671.1Skamil for (i = howmany+nextin-1; i >= nextin; i--) 6681.1Skamil circlebuf[i] &= 0177; 6691.1Skamil nextin += howmany; 6701.1Skamil nextin %= PUSHSIZE; /* may end up 1 if metakey */ 6711.1Skamil } 6721.1Skamil return howmany; 6731.1Skamil} 6741.1Skamil#endif /* RDCHK */ 6751.1Skamil#endif /* FIONREAD */ 6761.1Skamil#endif /* PENDING */ 6771.1Skamil 6781.1Skamilvoid 6791.1Skamilpushchar(ch) 6801.1Skamilchar ch; 6811.1Skamil{ 6821.1Skamil nextout--; 6831.1Skamil if (nextout < 0) 6841.1Skamil nextout = PUSHSIZE - 1; 6851.1Skamil if (nextout == nextin) { 6861.1Skamil fputs("\r\npushback buffer overflow\r\n",stdout); 6871.1Skamil sig_catcher(0); 6881.1Skamil } 6891.1Skamil circlebuf[nextout] = ch; 6901.1Skamil} 6911.1Skamil 6921.1Skamil#else /* PUSHBACK */ 6931.1Skamil#ifndef read_tty 6941.1Skamil/* read a character from the terminal, with hacks for O_NDELAY reads */ 6951.1Skamil 6961.1Skamilint 6971.1Skamilread_tty(addr,size) 6981.1Skamilchar *addr; 6991.1Skamilint size; 7001.1Skamil{ 7011.1Skamil if (is_input) { 7021.1Skamil *addr = pending_ch; 7031.1Skamil is_input = FALSE; 7041.1Skamil return 1; 7051.1Skamil } 7061.1Skamil else { 7071.1Skamil size = read(0,addr,size); 7081.1Skamil if (size < 0) 7091.1Skamil sig_catcher(SIGHUP); 7101.1Skamil if (metakey) { 7111.1Skamil if (*addr & 0200) { 7121.1Skamil pending_ch = *addr & 0177; 7131.1Skamil is_input = TRUE; 7141.1Skamil *addr = '\001'; 7151.1Skamil } 7161.1Skamil } 7171.1Skamil else 7181.1Skamil *addr &= 0177; 7191.1Skamil return size; 7201.1Skamil } 7211.1Skamil} 7221.1Skamil#endif /* read_tty */ 7231.1Skamil#endif /* PUSHBACK */ 7241.1Skamil 7251.1Skamilint 7261.1Skamilread_nd(buff, siz) 7271.1Skamilchar *buff; 7281.1Skamilint siz; 7291.1Skamil{ 7301.1Skamil if (!input_pending()) 7311.1Skamil return 0; 7321.1Skamil 7331.1Skamil getcmd(buff); 7341.1Skamil return 1; 7351.1Skamil} 7361.1Skamil 7371.1Skamil/* get a character into a buffer */ 7381.1Skamil 7391.1Skamilvoid 7401.1Skamilgetcmd(whatbuf) 7411.1SkamilReg3 char *whatbuf; 7421.1Skamil{ 7431.1Skamil#ifdef PUSHBACK 7441.1Skamil Reg1 KEYMAP *curmap; 7451.1Skamil Reg2 int i; 7461.1Skamil bool no_macros; 7471.1Skamil int times = 0; /* loop detector */ 7481.1Skamil char scrchar; 7491.1Skamil 7501.1Skamiltryagain: 7511.1Skamil curmap = topmap; 7521.1Skamil/* no_macros = (whatbuf != buf && nextin == nextout); */ 7531.1Skamil no_macros = FALSE; 7541.1Skamil#endif 7551.1Skamil for (;;) { 7561.1Skamil errno = 0; 7571.1Skamil if (read_tty(whatbuf,1) < 0 && !errno) 7581.1Skamil errno = EINTR; 7591.1Skamil#ifdef read_tty 7601.1Skamil if (metakey) { 7611.1Skamil if (*whatbuf & 0200) { 7621.1Skamil *what_buf &= 037; /* punt and hope they don't notice */ 7631.1Skamil } 7641.1Skamil } 7651.1Skamil else 7661.1Skamil *whatbuf &= 0177; 7671.1Skamil#endif /* read_tty */ 7681.1Skamil if (errno && errno != EINTR) { 7691.1Skamil perror(readerr); 7701.1Skamil sig_catcher(0); 7711.1Skamil } 7721.1Skamil#ifdef PUSHBACK 7731.1Skamil if (*whatbuf & 0200 || no_macros) { 7741.1Skamil *whatbuf &= 0177; 7751.1Skamil goto got_canonical; 7761.1Skamil } 7771.1Skamil if (curmap == Null(KEYMAP*)) 7781.1Skamil goto got_canonical; 7791.1Skamil for (i = (curmap->km_type[*whatbuf] >> KM_GSHIFT) & KM_GMASK; i; --i){ 7801.1Skamil Read_tty(&scrchar,1); 7811.1Skamil } 7821.1Skamil switch (curmap->km_type[*whatbuf] & KM_TMASK) { 7831.1Skamil case KM_NOTHIN: /* no entry? */ 7841.1Skamil if (curmap == topmap) /* unmapped canonical */ 7851.1Skamil goto got_canonical; 7861.1Skamil settle_down(); 7871.1Skamil goto tryagain; 7881.1Skamil case KM_KEYMAP: /* another keymap? */ 7891.1Skamil curmap = curmap->km_ptr[*whatbuf].km_km; 7901.1Skamil assert(curmap != Null(KEYMAP*)); 7911.1Skamil break; 7921.1Skamil case KM_STRING: /* a string? */ 7931.1Skamil pushstring(curmap->km_ptr[*whatbuf].km_str); 7941.1Skamil if (++times > 20) { /* loop? */ 7951.1Skamil fputs("\r\nmacro loop?\r\n",stdout); 7961.1Skamil settle_down(); 7971.1Skamil } 7981.1Skamil no_macros = FALSE; 7991.1Skamil goto tryagain; 8001.1Skamil } 8011.1Skamil#else 8021.1Skamil *whatbuf &= 0177; 8031.1Skamil break; 8041.1Skamil#endif 8051.1Skamil } 8061.1Skamil 8071.1Skamilgot_canonical: 8081.1Skamil#ifndef TERMIO 8091.1Skamil if (*whatbuf == '\r') 8101.1Skamil *whatbuf = '\n'; 8111.1Skamil#endif 8121.1Skamil if (whatbuf == buf) 8131.1Skamil whatbuf[1] = FINISHCMD; /* tell finish_command to work */ 8141.1Skamil} 815 816#ifdef PUSHBACK 817void 818pushstring(str) 819char *str; 820{ 821 Reg1 int i; 822 char tmpbuf[PUSHSIZE]; 823 Reg2 char *s = tmpbuf; 824 825 assert(str != Nullch); 826 interp(s,PUSHSIZE,str); 827 for (i = strlen(s)-1; i >= 0; --i) { 828 s[i] ^= 0200; 829 pushchar(s[i]); 830 } 831} 832#endif 833