|
|
1.1 ! root 1: /*----------------------------------------------------------------------*/ ! 2: /* */ ! 3: /* PACMAN for BBN BitGraphs */ ! 4: /* */ ! 5: /* File: pacman.c68 */ ! 6: /* Contents: Pacman control routines */ ! 7: /* Author: Bob Brown (rlb) */ ! 8: /* Purdue CS */ ! 9: /* Date: May, 1982 */ ! 10: /* Description: routines for initialization, movement, and */ ! 11: /* drawing. */ ! 12: /* */ ! 13: /*----------------------------------------------------------------------*/ ! 14: ! 15: #include "style.h" ! 16: #include "pacman.h" ! 17: ! 18: /* ! 19: ** Initialize the pacman ! 20: ** ! 21: ** pacnew - called a beginning of game. ! 22: ** pacinit - called at each board restart. ! 23: */ ! 24: ! 25: pacnew() ! 26: { ! 27: } ! 28: pacinit() ! 29: { ! 30: Pacman.dir = PACFACE; ! 31: Pacman.moving = FALSE; ! 32: Pacman.mouth = 0; ! 33: Pacman.font = FACECHAR; ! 34: Pacman.row = MZtoSC(PACROW); ! 35: Pacman.col = MZtoSC(PACCOL)-1; ! 36: Pacman.power = 0; ! 37: Pacman.alive = TRUE; ! 38: Pacman.adjusttime = 0; ! 39: paccomp(); ! 40: eladd(Pacman.time+STARTDELAY,pacmove); ! 41: } ! 42: /* ! 43: ** pacmove - move the pacman based on the description in ! 44: ** global Pacman - called by event-list manager. ! 45: ** ! 46: ** mouthfont is indexed by the direction the pacman is facing and ! 47: ** gives the font character to use for each mouth-step ! 48: */ ! 49: ! 50: char *mouthfont[] = { "abcdcb", "aefgfe", "ahijih", "aklmlk"}; ! 51: ! 52: int ! 53: pacmove() ! 54: { ! 55: ! 56: paccomp(); ! 57: if ( Pacman.moving ) { ! 58: /* ! 59: ** Check if next move is feasible ! 60: */ ! 61: if ( Pacman.pendcnt > 0 ) { ! 62: Pacman.pendcnt--; ! 63: if ( trymove(Pacman.pending) ) ! 64: Pacman.pendcnt = 0; ! 65: else ! 66: trymove(Pacman.dir); ! 67: } else ! 68: trymove(Pacman.dir); ! 69: } ! 70: /* ! 71: ** Now have a (potentially new) position ! 72: */ ! 73: if ( ++Pacman.mouth >= 6 ) Pacman.mouth = 0; ! 74: Pacman.font = mouthfont[Pacman.dir-1][Pacman.mouth]; ! 75: paccomp(); ! 76: /* ! 77: ** The routines that are called below rely on the maze coordinates ! 78: ** having already been computed. ! 79: */ ! 80: Pacman.mrow = SCtoMZ(Pacman.row+2); ! 81: Pacman.mcol = SCtoMZ(Pacman.col+2); ! 82: /* ! 83: ** Check for gobbling a dot ! 84: */ ! 85: if ( hasdot() ) { ! 86: Pacman.adjusttime = DOTDELAY; ! 87: Dotsrem--; ! 88: sounddot(); ! 89: addscore(VALGOLD); ! 90: } else ! 91: Pacman.adjusttime = 0; ! 92: /* ! 93: ** Check for swallowing a power pill, fruit, and in safe zone ! 94: */ ! 95: if ( haspill() ) ! 96: pacpower(NULL,ON); ! 97: if ( hasfruit() ) ! 98: hitfruit(); ! 99: Pacman.safe = issafe(); ! 100: /* ! 101: ** If powerful, detect collisions with monsters ! 102: */ ! 103: if ( Pacman.power > 0 ) { ! 104: register monster *mptr, *mptr2; ! 105: for ( mptr=Monster ; mptr < &Monster[MAXMONSTER] ; mptr++ ) { ! 106: if ( mptr->state==EDIBLE && collide(mptr) ) { ! 107: /* ! 108: ** Captured a monster... ! 109: */ ! 110: int crow, ccol; ! 111: addscore(Monvalue); ! 112: #ifdef V1_25 ! 113: settextop(INVERT|COMPL); ! 114: #endif ! 115: #if V1_76 | V2_0 ! 116: settextop(RASTSXD); ! 117: #endif ! 118: #ifdef BLIT ! 119: textmode = F_XOR; ! 120: #endif ! 121: crow = SCtoROW(mptr->row)+1; ! 122: ccol = SCtoCOL(min(mptr->col,Pacman.col))-6; ! 123: mvprintf(crow, ccol, "%4d",Monvalue); ! 124: if ( Silent ) ! 125: pause(750); ! 126: else ! 127: soundkill(); ! 128: mvprintf(crow, ccol, "%4d",Monvalue); ! 129: #ifdef V1_25 ! 130: settextop(REPLACE|COMPL); ! 131: #endif ! 132: #if V2_0 | V1_76 ! 133: settextop(RASTS); ! 134: #endif ! 135: #ifdef BLIT ! 136: textmode = F_STORE; ! 137: #endif ! 138: Monvalue *= 2; ! 139: mptr->state = DEAD; ! 140: monfont1(mptr,EYESCHAR); ! 141: mptr->movestate = HOMING; ! 142: for ( mptr2=Monster ; mptr2 < &Monster[MAXMONSTER]; mptr2++ ) ! 143: if ( mptr2->state == EDIBLE ) ! 144: mptr2->canreverse = TRUE; ! 145: } ! 146: } ! 147: } ! 148: eladd(Pacman.time+Pacman.adjusttime,pacmove); ! 149: } ! 150: paccomp() ! 151: { ! 152: blt40(Pacman.font,Pacman.row,Pacman.col,INVERT); ! 153: } ! 154: /* ! 155: ** pacpower - handle a transition in the Pacman's power ! 156: ** called from scheduler second & third time per pill. ! 157: ** ! 158: ** Parameters are set for 10 secs - 0.5 secs per wave, min 1 sec ! 159: */ ! 160: int ! 161: pacpower(junk,type) ! 162: char *junk; ! 163: int type; ! 164: { ! 165: register int powertime; ! 166: register monster *mptr; ! 167: powertime = max(POWERTIME-Wave*POWERDELTA,MINPOWERTIME); ! 168: switch ( type ) { ! 169: case ON: ! 170: /* soundpill(): */ ! 171: addscore(VALPILL); ! 172: Monvalue = VALMONSTER; ! 173: for ( mptr=Monster ; mptr<&Monster[MAXMONSTER] ; mptr++ ) { ! 174: mptr->canreverse = TRUE; ! 175: if ( mptr->state == DANGEROUS ) { ! 176: monfont1(mptr,GHOSTCHAR); ! 177: mptr->state = EDIBLE; ! 178: } ! 179: } ! 180: Pacman.power++; ! 181: eladd(3*powertime/4,pacpower,NULL,CLOSE); ! 182: break; ! 183: case CLOSE: ! 184: if ( Pacman.power == 1 ) { ! 185: for ( mptr=Monster ; mptr<&Monster[MAXMONSTER];mptr++ ) ! 186: if ( mptr->state == EDIBLE ) ! 187: monfont1(mptr,CLOSECHAR); ! 188: } ! 189: eladd(powertime/4,pacpower,NULL,OFF); ! 190: break; ! 191: case OFF: ! 192: if ( --Pacman.power <= 0 ) { ! 193: for ( mptr=Monster ; mptr<&Monster[MAXMONSTER];mptr++ ) { ! 194: if ( mptr->state == EDIBLE ) { ! 195: mptr->state = DANGEROUS; ! 196: monfont1(mptr,MONSTERCHAR[0]); ! 197: } ! 198: } ! 199: } ! 200: break; ! 201: } ! 202: } ! 203: /* ! 204: ** trymove - try to make a move ! 205: */ ! 206: trymove(newmove) ! 207: int newmove; ! 208: { ! 209: move try; ! 210: /* ! 211: ** If changing direction, row and col mod (FONTSIZE/BYTESIZE) must be 0 ! 212: */ ! 213: if ( ((newmove^Pacman.dir)&1) && !aligns(Pacman.row,Pacman.col)) { ! 214: return 0; ! 215: } ! 216: /* ! 217: ** Movement ok, compute next position ! 218: */ ! 219: onestep(Pacman.row, Pacman.col, newmove, &try); ! 220: if ( hitwall(try.row,try.col,newmove)) { ! 221: return 0; ! 222: } ! 223: Pacman.row = try.row; ! 224: Pacman.col = try.col; ! 225: Pacman.dir = newmove; ! 226: return 1; ! 227: } ! 228: /* ! 229: ** check if a screen coordinate hits a wall ! 230: */ ! 231: hitwall(row,col,dir) ! 232: { ! 233: bool wall; ! 234: if ( inslow(row,col) && (dir&1) ) ! 235: return(0); ! 236: wall = (Board[SCtoMZ(row+2)][SCtoMZ(col+2)] & TYPEMASK) <= WALLMAX; ! 237: return (wall || ((Board[SCtoMZ(row)][SCtoMZ(col)] & TYPEMASK) <= WALLMAX)); ! 238: } ! 239: hitdoor(row,col) ! 240: { ! 241: bool door; ! 242: door = (Board[SCtoMZ(row+2)][SCtoMZ(col+2)] & TYPEMASK) == DOOR; ! 243: return (door || ((Board[SCtoMZ(row)][SCtoMZ(col)] & TYPEMASK) == DOOR)); ! 244: } ! 245: hitblk(row,col) ! 246: { ! 247: int type; ! 248: bool blk; ! 249: type = (Board[SCtoMZ(row+2)][SCtoMZ(col+2)] & TYPEMASK); ! 250: blk = type == BLKDOT || type == BLKNODOT; ! 251: type = (Board[SCtoMZ(row)][SCtoMZ(col)] & TYPEMASK); ! 252: return (blk || (type == BLKDOT || type == BLKNODOT)); ! 253: } ! 254: inslow(row,col) ! 255: { ! 256: bool slow; ! 257: slow = (Board[SCtoMZ(row+2)][SCtoMZ(col+2)] & TYPEMASK) == SLOW; ! 258: return (slow || ((Board[SCtoMZ(row)][SCtoMZ(col)] & TYPEMASK) == SLOW)); ! 259: } ! 260: aligns(row,col) ! 261: { ! 262: int rowmod, colmod; ! 263: rowmod = row%(FONTSIZE/BYTESIZE); ! 264: colmod = col%(FONTSIZE/BYTESIZE); ! 265: return(rowmod==0 && colmod==0); ! 266: } ! 267: /* ! 268: ** Check of the pacman collided with a monster ! 269: */ ! 270: collide(mptr) ! 271: register monster *mptr; ! 272: { ! 273: return (iabs(mptr->row-Pacman.row)<3 && iabs(mptr->col-Pacman.col)<3 ); ! 274: } ! 275: /* ! 276: ** Check if the pacman has eaten a dot ! 277: */ ! 278: hasdot() ! 279: { ! 280: if (Board[Pacman.mrow][Pacman.mcol] & GOLD ) { ! 281: Board[Pacman.mrow][Pacman.mcol] &= ~GOLD; ! 282: blt24(GOLDCHAR,MZtoSC(Pacman.mrow),MZtoSC(Pacman.mcol),INVERT); ! 283: return TRUE; ! 284: } ! 285: return FALSE; ! 286: } ! 287: /* ! 288: ** Check if the pacman has eaten a pill ! 289: */ ! 290: haspill() ! 291: { ! 292: if (Board[Pacman.mrow][Pacman.mcol] & PILL ) { ! 293: Board[Pacman.mrow][Pacman.mcol] &= ~PILL; ! 294: blt24(PILLCHAR,MZtoSC(Pacman.mrow),MZtoSC(Pacman.mcol),INVERT); ! 295: return TRUE; ! 296: } ! 297: return FALSE; ! 298: } ! 299: /* ! 300: ** Check if the Pacman is in the safe corridor ! 301: */ ! 302: issafe() ! 303: { ! 304: return (Board[Pacman.mrow][Pacman.mcol]&TYPEMASK) == SAFE; ! 305: } ! 306: rempacface() ! 307: { ! 308: if (( Pacmen < MAXFACES ) && (Pacmen > 0)) ! 309: blt40(FACECHAR,MZtoSC(MAZEROWS+1),MZtoSC(Pacmen*2),INVERT); ! 310: } ! 311: /* ! 312: ** Handle the death of the pacman ! 313: */ ! 314: ! 315: char *pacdeath = "egstu"; /* font sequence */ ! 316: int pacdtop[] = {150,170,190,210,0}; ! 317: int pacdbot[] = {200,220,240,280,0}; ! 318: ! 319: pacdie() ! 320: { ! 321: int i; ! 322: Pacman.alive = FALSE; ! 323: soundoff(); ! 324: sleep(10); ! 325: moncomp(); ! 326: fruitcomp(); ! 327: elinit(); ! 328: for ( i=0 ; pacdeath[i]!='\0' ; i++ ) { ! 329: paccomp(); ! 330: Pacman.font = pacdeath[i]; ! 331: paccomp(); ! 332: #ifndef BLIT ! 333: rsetdead(); ! 334: #endif ! 335: if ( Silent ) ! 336: sleep(10); ! 337: else { ! 338: if ( pacdtop[i] ) { ! 339: tonegen(1,pacdtop[i],15-i*2); ! 340: psgsweep(0,pacdtop[i],pacdbot[i],10); ! 341: } else { ! 342: soundoff(); ! 343: sleep(10); ! 344: } ! 345: } ! 346: } ! 347: soundoff(); ! 348: paccomp(); ! 349: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.