]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - warp/term.c
1 /* Header: term.c,v 7.0.1.2 86/12/12 17:04:09 lwall Exp */
4 * Revision 7.0.1.2 86/12/12 17:04:09 lwall
5 * Baseline for net release.
7 * Revision 7.0.1.1 86/10/16 10:53:20 lwall
8 * Added Damage. Fixed random bugs.
10 * Revision 7.0 86/10/08 15:14:02 lwall
11 * Split into separate files. Added amoebas and pirates.
29 int typeahead
= false;
31 char tcarea
[TCSIZE
]; /* area for "compiled" termcap strings */
33 /* guarantee capability pointer != NULL */
34 /* (I believe terminfo will ignore the &tmpaddr argument.) */
36 #define Tgetstr(key) ((tstr = tgetstr(key,&tmpaddr)) ? tstr : nullstr)
56 typedef struct keymap KEYMAP
;
58 KEYMAP
*topmap
INIT(NULL
);
60 void mac_init(char *);
61 static KEYMAP
*newkeymap(void);
62 void pushstring(char *);
65 /* terminal initialization */
70 savetty(); /* remember current tty state */
72 #if defined(TERMIO) || defined(TERMIOS)
73 ospeed
= cfgetospeed(&_tty
);
74 ERASECH
= _tty
.c_cc
[VERASE
]; /* for finish_command() */
75 KILLCH
= _tty
.c_cc
[VKILL
]; /* for finish_command() */
77 ospeed
= _tty
.sg_ospeed
; /* for tputs() */
78 ERASECH
= _tty
.sg_erase
; /* for finish_command() */
79 KILLCH
= _tty
.sg_kill
; /* for finish_command() */
82 /* The following could be a table but I can't be sure that there isn't */
83 /* some degree of sparsity out there in the world. */
85 switch (ospeed
) { /* 1 second of padding */
87 case BEXTA
: just_a_sec
= 1920; break;
90 case B19200
: just_a_sec
= 1920; break;
93 case B9600
: just_a_sec
= 960; break;
94 case B4800
: just_a_sec
= 480; break;
95 case B2400
: just_a_sec
= 240; break;
96 case B1800
: just_a_sec
= 180; break;
97 case B1200
: just_a_sec
= 120; break;
98 case B600
: just_a_sec
= 60; break;
99 case B300
: just_a_sec
= 30; break;
100 /* do I really have to type the rest of this??? */
101 case B200
: just_a_sec
= 20; break;
102 case B150
: just_a_sec
= 15; break;
103 case B134
: just_a_sec
= 13; break;
104 case B110
: just_a_sec
= 11; break;
105 case B75
: just_a_sec
= 8; break;
106 case B50
: just_a_sec
= 5; break;
107 default: just_a_sec
= 960; break;
108 /* if we are running detached I */
109 } /* don't want to know about it! */
112 /* set terminal characteristics */
115 term_set(char *tcbuf
) /* temp area for "uncompiled" termcap entry */
117 char *tmpaddr
; /* must not be register */
125 /* do no delay reads on something that always gets closed on exit */
127 devtty
= open("/dev/tty",0);
129 printf(cantopen
,"/dev/tty");
132 fcntl(devtty
,F_SETFL
,O_NDELAY
);
137 /* get all that good termcap stuff */
139 retval
= tgetent(tcbuf
,getenv("TERM")); /* get termcap entry */
142 printf("No termcap %s found.\n", retval
? "file" : "entry");
144 fputs("Termcap botch\n",stdout
);
148 tmpaddr
= tcarea
; /* set up strange tgetstr pointer */
149 s
= Tgetstr("pc"); /* get pad character */
150 PC
= *s
; /* get it where tputs wants it */
151 if (!tgetflag("bs")) { /* is backspace not used? */
152 BC
= Tgetstr("bc"); /* find out what is */
153 if (BC
== nullstr
) /* terminfo grok's 'bs' but not 'bc' */
156 BC
= __UNCONST("\b"); /* make a backspace handy */
157 UP
= Tgetstr("up"); /* move up a line */
158 ND
= Tgetstr("nd"); /* non-destructive move cursor right */
159 DO
= Tgetstr("do"); /* move cursor down */
162 CL
= Tgetstr("cl"); /* get clear string */
163 CE
= Tgetstr("ce"); /* clear to end of line string */
164 CM
= Tgetstr("cm"); /* cursor motion - PWP */
165 HO
= Tgetstr("ho"); /* home cursor if no CM - PWP */
166 CD
= Tgetstr("cd"); /* clear to end of display - PWP */
167 SO
= Tgetstr("so"); /* begin standout */
168 SE
= Tgetstr("se"); /* end standout */
169 if ((SG
= tgetnum("sg"))<0)
170 SG
= 0; /* blanks left by SG, SE */
171 US
= Tgetstr("us"); /* start underline */
172 UE
= Tgetstr("ue"); /* end underline */
173 if ((UG
= tgetnum("ug"))<0)
174 UG
= 0; /* blanks left by US, UE */
176 UC
= nullstr
; /* UC must not be NULL */
178 UC
= Tgetstr("uc"); /* underline a character */
179 if (!*US
&& !*UC
) { /* no underline mode? */
180 US
= SO
; /* substitute standout mode */
184 LINES
= tgetnum("li"); /* lines per page */
185 COLS
= tgetnum("co"); /* columns on page */
186 AM
= tgetflag("am"); /* terminal wraps automatically? */
187 XN
= tgetflag("xn"); /* then eats next newline? */
190 VB
= __UNCONST("\007");
193 if (tgetflag("nc") && *UP
) {
194 size_t l
= strlen(UP
) + 2;
196 snprintf(CR
, l
, "%s\r",UP
);
199 CR
= __UNCONST("\r");
206 BCsize
= comp_tc(bsptr
,BC
,1);
209 if (!*ND
) /* not defined? */
210 NDsize
= 1000; /* force cursor addressing */
212 NDsize
= comp_tc(cmbuffer
,ND
,1);
213 myND
= malloc((unsigned)NDsize
);
214 movc3(NDsize
,cmbuffer
,myND
);
219 for (scr
=0; scr
<NDsize
; scr
++)
220 printf(" %d",myND
[scr
]);
225 if (!*UP
) /* not defined? */
226 UPsize
= 1000; /* force cursor addressing */
228 UPsize
= comp_tc(cmbuffer
,UP
,1);
229 myUP
= malloc((unsigned)UPsize
);
230 movc3(UPsize
,cmbuffer
,myUP
);
235 for (scr
=0; scr
<UPsize
; scr
++)
236 printf(" %d",myUP
[scr
]);
241 if (!*DO
) { /* not defined? */
242 myDO
= DO
= __UNCONST("\n"); /* assume a newline */
246 DOsize
= comp_tc(cmbuffer
,DO
,1);
247 myDO
= malloc((unsigned)DOsize
);
248 movc3(DOsize
,cmbuffer
,myDO
);
253 for (scr
=0; scr
<DOsize
; scr
++)
254 printf(" %d",myDO
[scr
]);
259 fgets(cmbuffer
,(sizeof cmbuffer
),stdin
);
261 CMsize
= comp_tc(cmbuffer
,tgoto(CM
,20,20),0);
265 for (p
=filler
+(sizeof filler
)-1;!*p
;--p
)
268 charsperhalfsec
= (speed_t
)ospeed
>= B9600
? (speed_t
)480 :
269 (speed_t
)ospeed
== B4800
? (speed_t
)240 :
270 (speed_t
)ospeed
== B2400
? (speed_t
)120 :
271 (speed_t
)ospeed
== B1200
? (speed_t
)60 :
272 (speed_t
)ospeed
== B600
? (speed_t
)30 :
273 /* speed is 300 (?) */ (speed_t
)15;
275 gfillen
= (speed_t
)ospeed
>= B9600
? (speed_t
)(sizeof filler
) :
276 (speed_t
)ospeed
== B4800
? (speed_t
)13 :
277 (speed_t
)ospeed
== B2400
? (speed_t
)7 :
278 (speed_t
)ospeed
== B1200
? (speed_t
)4 :
280 if ((speed_t
)ospeed
< B2400
)
283 strcpy(term
,ttyname(2));
287 if (!scorespec
&& (LINES
< 24 || COLS
< 80))
290 // no_can_do("humongous");
294 noecho(); /* turn off echo */
304 mac_init(char *tcbuf
)
308 tmpfp
= fopen(filexp(getval("WARPMACRO",WARPMACRO
)),"r");
310 while (fgets(tcbuf
,1024,tmpfp
) != NULL
) {
311 mac_line(tcbuf
,tmpbuf
,(sizeof tmpbuf
));
318 mac_line(char *line
, char *tmpbuf
, size_t tbsize
)
325 static const char override
[] = "\r\nkeymap overrides string\r\n";
328 topmap
= newkeymap();
329 if (*line
== '#' || *line
== '\n')
331 if (line
[ch
= strlen(line
)-1] == '\n')
333 m
= dointerp(tmpbuf
,tbsize
,line
," \t");
336 while (*m
== ' ' || *m
== '\t') m
++;
337 for (s
=tmpbuf
,curmap
=topmap
; *s
; s
++) {
339 if (s
[1] == '+' && isdigit((unsigned char)s
[2])) {
341 garbage
= (*s
& KM_GMASK
) << KM_GSHIFT
;
346 if ((curmap
->km_type
[ch
] & KM_TMASK
) == KM_STRING
) {
348 free(curmap
->km_ptr
[ch
].km_str
);
349 curmap
->km_ptr
[ch
].km_str
= NULL
;
351 curmap
->km_type
[ch
] = KM_KEYMAP
+ garbage
;
352 if (curmap
->km_ptr
[ch
].km_km
== NULL
)
353 curmap
->km_ptr
[ch
].km_km
= newkeymap();
354 curmap
= curmap
->km_ptr
[ch
].km_km
;
357 if ((curmap
->km_type
[ch
] & KM_TMASK
) == KM_KEYMAP
)
360 curmap
->km_type
[ch
] = KM_STRING
+ garbage
;
361 curmap
->km_ptr
[ch
].km_str
= savestr(m
);
374 map
= (KEYMAP
*)safemalloc(sizeof(KEYMAP
));
378 for (i
=127; i
>=0; --i
) {
379 map
->km_ptr
[i
].km_km
= NULL
;
380 map
->km_type
[i
] = KM_NOTHIN
;
387 /* print out a file, stopping at form feeds */
390 page(const char *filename
, size_t num
)
394 tmpfp
= fopen(filename
,"r");
396 while (fgets(spbuf
,(sizeof spbuf
),tmpfp
) != NULL
) {
397 if (*spbuf
== '\f') {
398 printf("[Type anything to continue] ");
402 if (*spbuf
== INTRCH
)
404 if (*spbuf
== 'q' || *spbuf
== 'Q')
409 printf("%3d %s\r",linenum
++,spbuf
);
411 printf("%s\r",spbuf
);
419 move(int y
, int x
, int chadd
)
428 i
= ydist
* (ydist
< 0 ? -UPsize
: DOsize
) +
429 xdist
* (xdist
< 0 ? -BCsize
: NDsize
);
433 for (; ydist
; ydist
++)
434 for (i
=UPsize
,s
=myUP
; i
; i
--)
437 for (; ydist
; ydist
--)
438 for (i
=DOsize
,s
=myDO
; i
; i
--)
441 for (; xdist
; xdist
++)
442 for (i
=BCsize
,s
=BC
; i
; i
--)
445 for (; xdist
; xdist
--)
446 for (i
=NDsize
,s
=myND
; i
; i
--)
450 tputs(tgoto(CM
,x
,y
),0,cmstore
);
457 if (maxcmstring
!= cmbuffer
)
462 do_tc(const char *s
, int l
)
470 comp_tc(char *dest
, const char *s
, int l
)
474 return(maxcmstring
-dest
);
481 mvaddstr(0,4,"h or 4 left");
482 mvaddstr(1,4,"j or 2 down Use with SHIFT to fire torpedoes.");
483 mvaddstr(2,4,"k or 8 up Use with CTRL or FUNCT to fire");
484 mvaddstr(3,4,"l or 6 right phasers or turbolasers.");
485 mvaddstr(4,4,"b or 1 down and left Use preceded by 'a' or 'r' for");
486 mvaddstr(5,4,"n or 3 down and right attractors or repulsors.");
487 mvaddstr(6,4,"y or 7 up and left Use normally for E or B motion.");
488 mvaddstr(7,4,"u or 9 up and right");
490 mvaddstr(9,4,"del or % fire photon torpedoes in every (reasonable) direction.");
491 mvaddstr(10,4,"s stop all torpedoes.");
492 mvaddstr(11,4,"S or 0 stop the Enterprise when in warp mode.");
493 mvaddstr(12,4,"d/D destruct all torpedoes/current vessel.");
494 mvaddstr(13,4,"i/w switch to Enterprise & put into impulse/warp mode.");
495 mvaddstr(14,4,"c/v switch to Enterprise & make cloaked/visible.");
496 mvaddstr(15,4,"p switch to Base.");
497 mvaddstr(16,4,"o toggle to other vessel (from E to B, or vice versa.)");
498 mvaddstr(17,4,"z zap (suppress) blasts near Enterprise next cycle");
500 mvaddstr(19,4,"^R refresh the screen. ^Z suspend the game.");
501 mvaddstr(20,4,"q exit this round (if you haven't typed q within 10 cycles).");
502 mvaddstr(21,4,"Q exit this game.");
504 mvaddstr(23,4," [Hit space to continue]");
508 } while (*spbuf
!= ' ');
521 for (y
=0; y
<YSIZE
; y
++) {
522 for (x
=0; x
<XSIZE
; x
++) {
523 if (numamoebas
&& amb
[y
][x
] != ' ')
524 mvaddc(y
+1,x
*2,amb
[y
][x
]);
525 if ((obj
= occupant
[y
][x
]) != NULL
) {
526 if (obj
->image
!= ' ')
527 mvaddc(y
+1,x
*2,obj
->image
);
531 snprintf(spbuf
, sizeof(spbuf
),
532 "%-4s E: %4d %2d B: %5d %3d Enemies: %-3d Stars: %-3d Stardate%5d.%1d %9ld",
533 " ", 0, 0, 0, 0, 0, 0, timer
/10+smarts
*100, timer%10
, 0L);
535 oldeenergy
= oldbenergy
= oldcurscore
=
536 oldstatus
= oldetorp
= oldbtorp
= oldstrs
= oldenemies
= -1;
537 /* force everything to fill in */
554 /* discard any characters typed ahead */
560 if (!typeahead
&& nextin
==nextout
) /* cancel only keyboard stuff */
566 while (input_pending())
567 read_tty(buf
,sizeof(buf
));
568 #else /* this is probably v7, with no rdchk() */
569 ioctl(_tty_ch
,TIOCSETP
,&_tty
);
581 nextout
= nextin
; /* empty circlebuf */
587 /* read a character from the terminal, with multi-character pushback */
590 read_tty(char *addr
, ssize_t size
) /* ignored for now */
592 if (nextout
!= nextin
) {
593 *addr
= circlebuf
[nextout
++];
598 size
= read(0,addr
,1);
603 pushchar(*addr
& 0177);
622 assert (nextin
== nextout
);
623 howmany
= read(devtty
,circlebuf
+nextin
,metakey
?1:PUSHSIZE
-nextin
);
626 if (circlebuf
[nextin
] & 0200) {
627 circlebuf
[nextin
] &= 0177;
632 for (i
= howmany
+nextin
-1; i
>= nextin
; i
--)
633 circlebuf
[i
] &= 0177;
635 nextin
%= PUSHSIZE
; /* may end up 1 if metakey */
640 #endif /* FIONREAD */
648 nextout
= PUSHSIZE
- 1;
649 if (nextout
== nextin
) {
650 fputs("\r\npushback buffer overflow\r\n",stdout
);
653 circlebuf
[nextout
] = ch
;
658 /* read a character from the terminal, with hacks for O_NDELAY reads */
671 size
= read(0,addr
,size
);
676 pending_ch
= *addr
& 0177;
686 #endif /* read_tty */
687 #endif /* PUSHBACK */
690 read_nd(char *buff
, size_t siz
)
692 if (!input_pending())
699 /* get a character into a buffer */
708 int times
= 0; /* loop detector */
710 unsigned char *whatbuf
= (void *)wbuf
;
714 /* no_macros = (whatbuf != buf && nextin == nextout); */
719 if (read_tty(wbuf
,1) < 0 && !errno
)
723 if (*whatbuf
& 0200) {
724 *what_buf
&= 037; /* punt and hope they don't notice */
729 #endif /* read_tty */
730 if (errno
&& errno
!= EINTR
) {
735 if (*whatbuf
& 0200 || no_macros
) {
741 for (i
= (curmap
->km_type
[*whatbuf
] >> KM_GSHIFT
) & KM_GMASK
; i
; --i
){
742 read_tty(&scrchar
,1);
744 switch (curmap
->km_type
[*whatbuf
] & KM_TMASK
) {
745 case KM_NOTHIN
: /* no entry? */
746 if (curmap
== topmap
) /* unmapped canonical */
750 case KM_KEYMAP
: /* another keymap? */
751 curmap
= curmap
->km_ptr
[*whatbuf
].km_km
;
752 assert(curmap
!= NULL
);
754 case KM_STRING
: /* a string? */
755 pushstring(curmap
->km_ptr
[*whatbuf
].km_str
);
756 if (++times
> 20) { /* loop? */
757 fputs("\r\nmacro loop?\r\n",stdout
);
770 #if !defined(TERMIO) && !defined(TERMIOS)
771 if (*whatbuf
== '\r')
775 whatbuf
[1] = FINISHCMD
; /* tell finish_command to work */
780 pushstring(char *str
)
783 char tmpbuf
[PUSHSIZE
];
787 interp(s
,PUSHSIZE
,str
);
788 for (i
= strlen(s
)-1; i
>= 0; --i
) {