/* @(#) maze.c version 2.1 (Blit) of 9/13/83 12:57:30 Last Delta: 7/22/83 14:07:34 to /usr/jerq/sccs/src/maze/s.maze.c */ #include "maze.h" #define getchar() (Cauxin() & 0x7f) #define WT 2 /* wall thickness / 2 */ #define WL 20 /* wall length */ #ifdef ATARIST #define LLX (MIDDLE - (WID*WL)/2) #endif #ifdef DMD #define LLX ((XMAX - WID*WL)/2) #endif #define LLY (DOWN + HT*WL + 20) #define NUMBER_OF_SHOTS 3 #define DELAY_TIME 600 #define ALARM_DELAY 30 int seed = 33; short inc[] = { 1,WID,-1,-WID}; char forw[] = { 1,2,4,8}; char back[] = { 4,8,1,2}; char right[] = { 8,1,2,4}; char left[] = { 2,4,8,1}; char maze[HT][WID] = { {12,10,10,8,10,10,10,8,10,9}, {5,12,9,5,12,10,9,5,13,5}, {7,5,5,5,5,13,5,5,4,3}, {14,1,4,0,1,5,4,1,4,9}, {13,5,7,5,6,2,1,6,3,5}, {6,2,10,2,10,10,2,10,10,3}, }; char *nullpos = &maze[HT][WID]; unsigned long current_time; unsigned long shot_time[NUMBER_OF_SHOTS] = {0,0}; showscore(p) register State *p; { register int i; char s[40]; i = p - player; if (p->id == -1) sprintf(s," "); else sprintf(s,"%s%s%4d%s ",(p->vis)?"p":"",p->name,p->score, (p->vis)?"q":""); gotoxy(0,i+1); Cconws(s); } extern long clock(); int whoami; main(argc,argv) char **argv; { int i,j; current_time = clock(); seed = current_time & 0x7fff; if (argc > 1) { sscanf(argv[1],"%d",&whoami); if (whoami > 15 || whoami < 0) whoami = 0; } else { whoami = 0; } #ifndef ATARIST request(KBD|MOUSE|RCV|SEND); #endif dispinit(); N = 16; /* number of players */ me = player; me->pos = maze[0]; nameinit(); YSIZE = Drect.corner.y - Drect.origin.y; XSIZE = Drect.corner.x - Drect.origin.x; for (i = 0; i < WID; i++) for (j = 0; j < HT; j++) box(i,j); for (i = 0; i < N; i++) player[i].id = -1; viewinit(); iconinit(); play(); } char name[40]; nameinit() { register c; register char *p = name; register n = 0; #ifdef ATARIST gotoxy(0,0); printf("Ename? "); while ((c = Cconin()) != '\r') if (c >= ' ' && c <= '~' && c != '^') { *p++ = c; n++; } Cconws("\r\n"); #else showtype(name); while ((c= kbdchar()) != '\r') { switch (c) { case -1: wait(KBD); continue; case 8: /* backspace */ showtype(name); if (n > 0) { --p; --n; } break; default: showtype(name); if (n < 20 && c != '^') { *p++ = c; n++; } } *p = 0; showtype(name); } #endif while (n < 20) { *p++ = ' '; n++; } *p = 0; #ifndef ATARIST cursinhibit(); #ifdef OLDDMD stipple(Drect); #endif cursallow(); #endif } copy(s,d) register char *s,*d; { while (*d++ = *s++) ; } #ifndef ATARIST mess(s) char *s; { static int y = 40; jmoveto(Pt(0,y)); jstring(s); y += 20; } #endif play() { register int e,i; /* not normal>>> */ int x,y; ME = whoami; me = player+ME; x = seed % WID; y = seed % HT; me->id = 1; me->vis = 0; me->dir = seed & 3; me->pos = &maze[y][x]; me->score = 0; showself(); view(me,F_STORE); showem(me); copy(name,me->name); showscore(me); myname(); /* hello, my name is... */ move(); /* and I live here */ outchar('w'); /* who are you ? */ /* << back from abnormality */ for (;;) { #ifdef ATARIST if (Cauxis()) getinfo(me); else if (Cconis()) domove(); else /* no event skip pip checking */ continue; #else e = wait(RCV|MOUSE|KBD); if (e & RCV) getinfo(me); else if (e & KBD) domove(); else if (bttn1()) peek(1,4); else if (bttn3()) peek(-1,1); else if (bttn2()) shoot(); #endif current_time = clock(); for (i = 0; i < NUMBER_OF_SHOTS; i++) { if (current_time > shot_time[i]) { #ifdef ATARIST /* FIX ! */ jdisc(LLX + (i*16), LLY + 20, 5, F_STORE); #else jdisc(Pt(LLX + (i*16), LLY + 20), 5, F_STORE); #endif } } } } getinfo(here) State *here; { register c,i; register State *p; char *s,str[100]; int x,y; switch (c = getchar()) { case '\n': case 4: /* quit to the umpire, ignore it */ break; case 'y': /* YOU - get my number */ ME = getnum(); me = player+ME; x = seed % WID; y = seed % HT; me->dir = seed & 3; me->pos = &maze[y][x]; me->score = 0; showself(); view(me,F_STORE); showem(me); copy(name,me->name); outchar('w'); /* who is everyone? */ break; case 'q': /* QUIT - n is quitting */ p = player+getnum(); p->pos = nullpos; showscore(p); p->id = -1; /* non-person */ showscore(p); break; case 'n': /* NAME - bind name to player index */ i = getnum(); p = player+i; p->id = i; p->score = getnum() << 12; p->score |= getnum() << 6; p->score |= getnum(); s = p->name; do { *s++ = (c = getchar()); } while (c != '^'); *(s-1) = '\0'; p->vis = 0; showscore(p); break; case 'w': /* WHO - are you? */ myname(); /* hello, my name is... */ move(); /* and I live here */ break; case 'm': /* MOVE */ if ((i = getnum()) == ME) { /* I move locally */ inflush(3); return(0); } p = player+i; p->dir = getnum(); x = getnum(); y = getnum(); p->pos = &maze[y][x]; view(me,F_STORE); showem(here); break; case 'f': /* FIRE - see if I am in danger */ if ((i = getnum()) == ME) { /* not from myself */ return(0); } p = player+i; if (danger(p)) { /* am I hit? */ kill(i); /* move(); */ jrectf(&Drect, F_XOR); #if ATARIST nap(10); #else sleep(30); #endif jrectf(&Drect, F_XOR); showself(); view(here,F_CLR); seed = ((clock() & 0x7f) <<8) | (clock() & 0xff); x = seed % WID; y = seed % HT; me->dir = seed & 3; me->pos = &maze[y][x]; showself(); view(me,F_STORE); showem(me); /* sleep(60); */ move(); /* FUNCY >> */ p->score += 2; showscore(p); me->score -= 1; showscore(me); /* << END FUNC */ return(1); /* to override peeking */ } break; case 'k': /* KILL - p killed q */ p = player+getnum(); p->score += 2; showscore(p); p = player+getnum(); p->score -= 1; showscore(p); break; default: sprintf(str,"say what? %o",c); #ifdef ATARIST gotoxy(0,0); Cconws(str); #else /* mess(str); */ showtype(str); #endif } return(0); } domove() { showself(); view(me,F_CLR); #ifdef ATARIST while (Cconis()) { switch (Crawcin()) { #else while (own()&KBD) { switch (kbdchar()) { #endif case 'q': iconclean(); gotoxy(0,25); quit(); exit(); break; case 'h': case 'a': me->dir = (me->dir + 2)&3; break; case 'j': case 's': me->dir = (me->dir + 1)&3; break; case 'k': case 'd': if ((*me->pos & forw[me->dir]) == 0) me->pos += inc[me->dir]; break; case ';': case 'g': if ((*me->pos & back[me->dir]) == 0) me->pos -= inc[me->dir]; break; case 'l': case 'f': me->dir = (me->dir - 1)&3; break; case ' ': shoot(); break; default: break; } } move(); showself(); view(me,F_STORE); showem(me); } Point pointer[] = { 2*WT, 0, 0, -2*WT, -2*WT, 0, 0, 2*WT }; showself() { Point *p,d; d.x = LLX + ((me->pos - maze[0]) % WID)*WL + WL/2; d.y = LLY - ((me->pos - maze[0]) / WID)*WL - WL/2; p = &pointer[me->dir]; jsegment(d.x + p->x,d.y + p->y,d.x - p->x,d.y - p->y,F_XOR); jsegment(d.x + p->x,d.y + p->y,d.x - p->y,d.y + p->x,F_XOR); jsegment(d.x + p->x,d.y + p->y,d.x + p->y,d.y - p->x,F_XOR); } peek(way,mask) /* wrong - show view but don't place oneself in danger */ int way,mask; { #ifdef ATARIST #else int shot = 0; State temp,*t = &temp; if ((*me->pos & forw[me->dir]) == 0) { view(me,F_CLR); t->pos = me->pos + inc[me->dir]; t->dir = (me->dir + way)&3; view(t,F_STORE); showem(t); while (!shot && (mouse.buttons & mask)) { wait(CPU); if (own()&RCV) shot = getinfo(t); } if (!shot) { view(t,F_CLR); view(me,F_STORE); showem(me); } else { while (mouse.buttons & mask) ; } } #endif } shoot() { int i; /* * This was added to slow down the rate of firing. * The algorithm is as follows: * Each player gets NUMBER_OF_SHOTS shots. * Each shot regenerates DELAY_TIME after firing. */ /* Determine if we can shoot */ current_time = clock(); for (i = 0; i < NUMBER_OF_SHOTS; i++) { if (current_time > shot_time[i]) { shot_time[i] = current_time + DELAY_TIME; fire(); /* erase_pip(i); */ #ifdef ATARIST /* FIX ! */ jdisc(LLX + (i*16), LLY + 20, 5, F_CLR); #else jdisc(Pt(LLX + (i*16), LLY + 20), 5, F_CLR); #endif break; } } #ifndef ATARIST while (wait(MOUSE) && bttn2()) { wait(CPU); if (own()&RCV) getinfo(me); } #endif } box(i,j) int i,j; { register int x,y; register char c; Rectangle rr; c = maze[j][i]; x = LLX + WL*i; y = LLY - WL*j; if (c & 1) { #if 0 Pt(rr.origin,x+(WL-WT),y-(WL+WT)); Pt(rr.corner,x+(WL+WT),y+WT); #else Rect(rr, x+(WL-WT), y-(WL+WT), x+(WL+WT), y+WT); #endif jrectf(&rr,F_STORE); } if (c & 2) { #if 0 Pt(rr.origin,x-WT,y-(WL+WT)); Pt(rr.corner,x+(WL+WT),y-(WL-WT)); #else Rect(rr, x-WT, y-(WL+WT), x+(WL+WT), y-(WL-WT)); #endif jrectf(&rr,F_STORE); } if (c & 4) { #if 0 Pt(rr.origin,x-WT,y-(WL+WT)); Pt(rr.corner,x+WT,y+WT); #else Rect(rr, x-WT, y-(WL+WT), x+WT, y+WT); #endif jrectf(&rr,F_STORE); } if (c & 8) { #if 0 Pt(rr.origin,x-WT,y-WT); Pt(rr.corner,x+(WL+WT),y+WT); #else Rect(rr, x-WT, y-WT, x+(WL+WT), y+WT); #endif jrectf(&rr,F_STORE); } }