|
|
1.1 root 1: /*----------------------------------------------------------------------*/
2: /* */
3: /* PACMAN for BBN BitGraphs */
4: /* */
5: /* File: main.c68 */
6: /* Contents: controlling and utility routines */
7: /* Author: Bob Brown (rlb) */
8: /* Purdue CS */
9: /* Date: May, 1982 */
10: /* Description: routines for setting up and controlling the */
11: /* game, plus miscellaneous utilities. */
12: /* */
13: /*----------------------------------------------------------------------*/
14:
15: #include "style.h"
16: #include "pacman.h"
17: #include "host.h"
18:
19: /*
20: ** Instances of global variables not defined elsewhere
21: */
22: char *Board[];
23: bool Abort;
24: int Dotsrem;
25: int Game;
26: long Highscore[MAXGAMES];
27: int Monbase; /* Base scheduler delay for monsters */
28: bool Monseeking; /* TRUE=>they know where he is */
29: int Monvalue; /* value of captured monster */
30: bool Newgame;
31: int Pacmen; /* Number of Pacman remaining */
32: bool Running;
33: long Score;
34: long Nextbonus;
35: bool Silent;
36: int Timedelay;
37: int Wave;
38: int clock;
39: int Freeze; /* true if game frozen */
40:
41: /*
42: ** Game parameters
43: */
44: int Seekprob;
45: int Seekinc;
46:
47: /*
48: ** main - game logic control.
49: **
50: ** contortions are because there's no exit().
51: */
52: extern short Bits24[], Bits40[];
53: Bitmap Bitmap24;
54: Bitmap Bitmap40;
55:
56: main(argc,argv)
57: {
58: request(KBD|ALARM|MOUSE);
59: mousemotion();
60: initdisplay(argc,argv);
61: Bitmap24 = ToBitmap(Bits24,30, 0,0,240,24);
62: Bitmap40 = ToBitmap(Bits40,130, 0,0,1040,40);
63: init();
64: Running = TRUE;
65: Freeze = FALSE;
66: retxy(1);
67: /*
68: ** For each game played...
69: */
70: alarm(1);
71: while ( Running ) {
72: /*
73: ** For each new wave...
74: */
75: newgame();
76: while ( Pacmen > 0 && Running ) {
77: newwave();
78: /*
79: ** For each game scan...
80: */
81: while ( Dotsrem > 0 ) {
82: /*
83: ** If the Pacman died, start a new one.
84: */
85: if ( !Pacman.alive ) {
86: addmen(-1);
87: if ( Pacmen <= 0 )
88: break;
89: elinit();
90: pacinit();
91: moninit();
92: fruitinit(FALSE);
93: }
94: if (own()&ALARM) {
95: clock++;
96: alarm(1);
97: }
98: poll();
99: if ( Abort || Newgame )
100: break;
101: if(!Freeze)
102: elpoll();
103: }
104: soundoff();
105: if ( Abort || Newgame )
106: break;
107: paccomp();
108: moncomp();
109: fruitcomp();
110: soundoff();
111: }
112: alarm(300);
113: while (kbdchar()!=-1);
114: wait(ALARM|KBD);
115: alarm(1);
116: if (Game != 0) {
117: sndhost ("%s%s%d\n%s%d %d\n", SYNCSTRING,
118: GAMESTRING, Game,
119: SCORESTRING, encrypt (Score),
120: encrypt (KEY));
121: if ( Score > Highscore[Game-1] )
122: Highscore[Game-1] = Score;
123: }
124: if ( Abort )
125: break;
126: }
127: wrapup();
128: }
129:
130: /*
131: ** init - set up the terminal
132: */
133:
134: init()
135: {
136: extern int argc, arg0;
137: int i, *argp;
138:
139: #if V1_25 | V1_76
140: extern char screenmode;
141: do_push();
142: screenmode = 0;
143: setcontext();
144: #endif
145: /* For non-iconic mpx:
146: jinit();
147: */
148: #if BLIT
149: textmode = F_STORE;
150: #endif
151:
152: #ifdef V2_0
153: extern char screenm;
154: /*
155: dopush();
156: */
157: screenm = 0;
158: setcontext();
159: #endif
160: Abort = FALSE;
161: /*
162: ** High score processing - arguments are the high scores for the
163: ** games
164: */
165: /* Ghod only knows what to do with with these for the Blit
166:
167: getscores ();
168: argp = &arg0;
169: for ( i=0 ; i<MAXGAMES ; i++ )
170: if ( i < argc )
171: Highscore[i] = *argp++;
172: else
173: Highscore[i] = NOSCORE;
174: */
175: }
176:
177: /*
178: ** getscores - get the high score vector from the host.
179: **
180: ** Scores are transmitted as ESC : arg0;arg1;...CAN
181: ** where CAN is the ANSI standard cancel sequence.
182: ** The cancel ensures the BitGraph will do no processing
183: ** if the downloaded program doesn't read the arg vector.
184: ** This routine times out in two seconds in case the host
185: ** doesn't send the scores.
186: */
187:
188: getscores ()
189: {
190: #ifndef BLIT
191: register int c;
192: register int i;
193: extern long argc;
194: extern long arg0;
195: extern long arg1;
196:
197: argc = arg0 = arg1 = 0;
198: for (i = 0; i < 1000; i++)
199: {
200: sleep (2); /* Wait for max of 2 msec. */
201: if ((c = hstgetc ()) == '\033')
202: {
203: getchar (); /* Throw away the colon. */
204: #if V1_25 | V1_76
205: do_args (); /* Old style read arg list. */
206: #else
207: doargs (); /* Read the arg list. */
208: #endif
209: break;
210: }
211: }
212: #endif
213: }
214: /*
215: ** settextop - set text operation mode
216: */
217:
218: settextop(i)
219: {
220: #ifndef BLIT
221: extern long argc, arg0;
222: argc = 1;
223: arg0 = i;
224: setop();
225: #endif
226: }
227: wrapup()
228: {
229: sndhost ("%s", EXITSTRING);
230: #ifdef V1_25
231: do_pop();
232: #endif
233:
234: #ifdef V1_76
235: do_pop();
236: #endif
237:
238: #ifdef V2_0
239: dopop();
240: #endif
241: }
242:
243: /*
244: ** newgame - set up for a new game, with instructions.
245: */
246:
247: newgame()
248: {
249: instruct();
250: Game = 0;
251: Silent = TRUE;
252: #if BLIT
253: wait(KBD);
254: #else
255: while(kbdgetc()!=-1) ;
256: #endif
257: while (Game==0 && Running) {
258: wait(KBD);
259: poll();
260: }
261: if ( !Running )
262: return;
263: clear();
264:
265: switch ( Game ) {
266: case 1:
267: Seekprob = 40;
268: Seekinc = 10;
269: Monbase = 40;
270: Pacman.time = 43;
271: break;
272: case 2:
273: Seekprob = 80;
274: Seekinc = 2;
275: Monbase = 30;
276: Pacman.time = 35;
277: break;
278: case 3:
279: Seekprob = 100;
280: Seekinc = 0;
281: Monbase = MINMONTIME;
282: Pacman.time = MINPACTIME;
283: break;
284: case 4: /* Flat out, for testing and practice */
285: Seekprob = 100;
286: Seekinc = 0;
287: Monbase = 0;
288: Pacman.time = 0;
289: }
290: Newgame = FALSE;
291: Pacman.alive = TRUE;
292: Wave = 0;
293: Score = 0;
294: Nextbonus = (long) SCOREMOD;
295: mvprintf(SCOREROW,1,"S C O R E : ");
296: addscore(0);
297: if ( Highscore[Game-1] != NOSCORE )
298: mvprintf(SCOREROW,HIGHCOL,"H I G H S C O R E : %l",Highscore[Game-1]);
299: Pacmen = 1;
300: mvprintf(WAVEROW,WAVECOL,"W A V E : ");
301: addmen(PACMEN-1);
302: pacnew();
303: monnew();
304: }
305: /*
306: ** Display Game instructions
307: */
308: instruct()
309: {
310: clear();
311: /*cursinhibit();*/
312: mvprintf(11,1,"P A C M A N");
313: mvprintf(13,10,"use mouse to move");
314: mvprintf(14,10,"<f> to freeze game.");
315:
316: mvprintf(15,10,"<q> to quit.");
317: mvprintf(16,10,"<n> to start a new game.");
318: mvprintf(17,10,"<s> to toggle sound.");
319: mvprintf(19,10,"Select game 1, 2, 3, or 4.");
320: /*cursallow();*/
321: }
322: /*
323: ** start a new wave - also starts the first wave.
324: **
325: ** increase the speed on the monsters, but not too fast.
326: ** However, if already running faster than fastest, leave it there.
327: */
328:
329: newwave()
330: {
331: register monster *mptr;
332: Wave++;
333: mvprintf(WAVEROW,WAVECOL+10,"%d",Wave);
334: if ( Wave&1 ) {
335: for ( mptr=Monster ; mptr < &Monster[MAXMONSTER] ; mptr++ )
336: if ( mptr->time > MINMONTIME )
337: mptr->time = max(mptr->time-MONDELTA,MINMONTIME);
338: if ( Pacman.time > MINPACTIME )
339: Pacman.time = max(Pacman.time-PACDELTA,MINPACTIME);
340: }
341: newboard();
342: drawboard();
343: Dotsrem = DOTS;
344: Seekprob += Seekinc;
345: elinit();
346: pacinit();
347: moninit();
348: fruitinit(TRUE);
349: }
350: /*
351: ** Keyboard polling routine
352: */
353: poll()
354: {
355: register unsigned char c;
356: register int o;
357:
358: #if BLIT
359: if(button123()){
360: wait(KBD|ALARM|MOUSE);
361: }
362: if((o = own()) & KBD)
363: c = kbdchar();
364: else if(!Freeze && (o & MOUSE))
365: c = retxy(0);
366: else
367: c = 0;
368: if(c == 0)
369: wait(KBD|ALARM|MOUSE);
370: else
371: switch(c) {
372: #else
373: rsetdead();
374: switch ( (c=kbdgetc()) ) {
375: #endif
376: case GAME4:
377: case GAME3:
378: case GAME2:
379: case GAME1:
380: if ( Game ) return;
381: Game = c - '0';
382: break;
383: case LEFT:
384: case ALTLEFT:
385: Pacman.pending = MOVELEFT;
386: Pacman.pendcnt = PENDCOUNT;
387: Pacman.moving = TRUE;
388: break;
389: case RIGHT:
390: case ALTRIGHT:
391: Pacman.pending = MOVERIGHT;
392: Pacman.pendcnt = PENDCOUNT;
393: Pacman.moving = TRUE;
394: break;
395: case UP:
396: case ALTUP:
397: Pacman.pending = MOVEUP;
398: Pacman.pendcnt = PENDCOUNT;
399: Pacman.moving = TRUE;
400: break;
401: case DOWN:
402: case ALTDOWN:
403: case ALTALTDOWN:
404: Pacman.pending = MOVEDOWN;
405: Pacman.pendcnt = PENDCOUNT;
406: Pacman.moving = TRUE;
407: break;
408: case SILENT:
409: Silent = !Silent;
410: break;
411: case STOP:
412: case ALTSTOP:
413: Pacman.moving = FALSE;
414: Pacman.pendcnt = 0;
415: break;
416: case ABORT:
417: Running = FALSE;
418: Abort = TRUE;
419: break;
420: case NEWGAME:
421: Newgame = TRUE;
422: break;
423: case FREEZE:
424: Freeze = ! Freeze;
425: break;
426: case -1:
427: wait(KBD|ALARM|MOUSE);
428: break;
429: }
430: }
431:
432: /*
433: ** Update the score
434: */
435: addscore(inc)
436: register int inc;
437: {
438: long oldscore;
439: oldscore = Score;
440: Score += inc;
441: /*cursinhibit();*/
442: mvprintf(SCOREROW,SCORECOL,"%l",Score);
443: /*cursallow();*/
444: if ( oldscore<Nextbonus && Score>=Nextbonus ) {
445: addmen(1);
446: Nextbonus *= 2;
447: }
448: }
449: /*
450: ** Add multiple men or subtract just one.
451: */
452: addmen(inc)
453: register int inc;
454: {
455: register int i;
456: /*
457: ** Put another at the bottom of the screen
458: */
459: if ( inc > 0 ) {
460: for ( i=0 ; i<inc ; i++ ) {
461: rempacface();
462: Pacmen++;
463: }
464: } else {
465: Pacmen--;
466: rempacface();
467: }
468: }
469: mvprintf(row,col,f,p0,p1,p2,p3)
470: char *f;
471: int p0,p1,p2,p3;
472: {
473: #ifdef V1_25
474: extern long arg0, arg1;
475: arg0 = row;
476: arg1 = col;
477: movexy();
478: #endif
479: #ifdef V1_76
480: cmovey (row);
481: cmovex (col);
482: #endif
483: #ifdef V2_0
484: cmovey (row);
485: cmovex (col);
486: #endif
487: #ifdef BLIT
488: movexy(col,row);
489: #endif
490: printf(f,p0,p1,p2,p3);
491: }
492: #define PRIME 2131
493: grand(lb,ub)
494: int lb, ub;
495: {
496: return (rand() % PRIME) * (ub-lb+1) / PRIME + lb;
497: }
498: long randx = 1;
499:
500: srand(x)
501: unsigned x;
502: {
503: randx = x;
504: }
505:
506: rand()
507: {
508: return(((randx = randx*1103515245 + 12345)>>16) & 077777);
509: }
510:
511: pause(ms)
512: {
513: soundoff();
514: #ifdef BLIT
515: sleep((ms+8)/16);
516: #else
517: sleep(ms);
518: #endif
519: eladjust(ms);
520: }
521:
522: #ifdef BLIT
523: clear()
524: {
525: /*cursinhibit();*/
526: rectf(&display,Drect,F_CLR);
527: /*cursallow();*/
528: }
529: #endif
530:
531: #ifdef BLIT
532: retxy(init)
533: {
534: register ret;
535: Point p, dif;
536: static Point centre;
537: #define FUZZ 6
538:
539: if(init)
540: {
541: centre = div(add(Drect.origin, Drect.corner), 2);
542: cursset(centre);
543: return;
544: }
545: p = mouse.xy;
546: dif = sub(p, centre);
547: ret = 0;
548: if(abs(dif.y) > FUZZ) {
549: ret = (dif.y<0)? UP : DOWN;
550: cursset(Pt(p.x, centre.y));
551: } else if(abs(dif.x) > FUZZ) {
552: ret = (dif.x>0)? RIGHT : LEFT;
553: cursset(Pt(centre.x, p.y));
554: }
555: return(ret);
556: }
557: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.