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