|
|
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.