Attempting to build Quake and Doom for ARM. Let's see what happens.
[AROS-Contrib.git] / fish / sunmaze / sunmaze.c
blob9e7828f2d196b5f3f4cf3e994241fdf1934026f9
1 /*
2 * DWR: This file has been changed to implement shadow in the
3 * 3d presentation of the maze.
4 * This is the original file from Fish 171: Maze/3DDemo.c
5 * All modifications are marked with "DWR:".
6 */
8 #include <aros/oldprograms.h>
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <libraries/dosextens.h>
13 #include <intuition/intuition.h>
14 #include <exec/memory.h>
15 #include <graphics/gfxmacros.h>
17 #define BITMAP
19 #include "maze.h" /* This is our maze generator */
21 #define MENUITEMS 6
23 struct IntuiText item[MENUITEMS*2]=
24 { {6,0,JAM2,0,0,NULL,NULL,NULL} };
26 struct IntuiText abouttxt5= /* Yes, this game needs lots of credits */
27 { 7,0,JAM2,32,60,NULL,"keys to move",NULL}; /* DWR: changed */
28 struct IntuiText abouttxt4=
29 { 7,0,JAM2,12,50,NULL,"Use keypad cursor",&abouttxt5}; /* DWR: changed */
30 struct IntuiText abouttxt3=
31 { 4,0,JAM2,0,40,NULL,"Freely distributable",&abouttxt4}; /* DWR: changed */
33 struct IntuiText abouttxt3b=
34 { 2,0,JAM2,36,30,NULL,"Dirk Reisig",&abouttxt3}; /* DWR: inserted */
35 struct IntuiText abouttxt3a=
36 { 1,0,JAM2,40,20,NULL,"Shadows by",&abouttxt3b}; /* DWR: inserted */
38 struct IntuiText abouttxt2=
39 { 6,0,JAM2,24,10,NULL,"Werner Gunther",&abouttxt3a}; /* DWR: changed */
40 struct IntuiText abouttxt1=
41 { 6,0,JAM2,40,0,NULL,"Written by",&abouttxt2};
44 struct MenuItem mi[MENUITEMS] = /* main menu structures */
47 NULL,0,0,70,11,
48 ITEMTEXT|ITEMENABLED|HIGHCOMP,
49 0, 0, 0, 0, 0, 0
52 struct MenuItem sizemenu[MENUITEMS] = /* sub menu for sizes */
55 NULL,60,0,90,11,
56 ITEMTEXT|ITEMENABLED|HIGHCOMP|CHECKIT,
57 0, 0, 0, 0, 0, 0
60 struct MenuItem about = /* about, credits & help */
62 NULL,60,0,160,70,
63 ITEMTEXT|ITEMENABLED,
64 0,(APTR)&abouttxt1,0,0,0,0
67 struct Menu menu=
69 NULL,0,0,70,11,
70 MENUENABLED,
71 "Options",
75 struct NewScreen ns= /* screen low-rez, 8 colors */
77 0,0,320,200,3,
78 1,0,
80 CUSTOMSCREEN,
81 0, 0, 0, 0,
84 struct NewWindow nw= /* window for menus & gadgets */
86 0,1,286,199,
87 1,0,
88 CLOSEWINDOW|GADGETUP|MENUPICK|MENUVERIFY|VANILLAKEY,
89 BORDERLESS|NOCAREREFRESH|WINDOWCLOSE|ACTIVATE,
90 0, 0,
91 "Maze 3D Demo",
92 0, 0, 0, 0, 0, 0,
93 CUSTOMSCREEN
96 struct Image mazeimage={0,0,0,0,1,0,4,4,0}; /* Image to display the maze */
98 char mtxt[MENUITEMS][9]= /* menu text */
100 "Map","New Maze","Size","Demo","Quit","About"
102 char sizetxt[MENUITEMS][11]= /* text for size menu */
104 "Trivial","Simple","Normal","Advanced","Difficult","Impossible"
107 struct GfxBase *GfxBase = NULL;
108 struct IntuitionBase *IntuitionBase = NULL;
109 struct Screen *screen = NULL;
110 struct Window *window = NULL;
111 struct BitMap *bm;
112 struct IntuiMessage *msg;
113 struct AreaInfo areainfo;
114 struct TmpRas tmpras;
115 struct RastPort *rp;
117 ULONG class,code;
118 BOOL WorkBench=FALSE,demomode=FALSE,forward();
119 void right(),left(),demo(),newmaze(),leave(),show3d(),showmaze();
120 void statusline();
121 short i,j,xsize,ysize,mazesize=2,x,y,wayout,moves;
122 char *mymaze=NULL,areapts[7*5],*raster=NULL,buffer[20];
123 short dirincs[4][2]={{0,-1},{1,0},{0,1},{-1,0}};
124 char heading[][7]={"North"," East ","South"," West "};
126 int IsPassage(short, short);
128 int main(argc,argv)
129 int argc;
130 char argv[];
132 if (!argc) WorkBench=TRUE; /* open stuff */
133 if (!(IntuitionBase = (struct IntuitionBase*)
134 OpenLibrary("intuition.library",0L)))
135 leave("No Intuition Library");
136 if (!(GfxBase = (struct GfxBase*) OpenLibrary("graphics.library",0L)))
137 leave("No Graphics Library");
139 for(i=0;i<MENUITEMS;i++) /* set menu-strip */
140 { /* could have be done on declaration */
141 sizemenu[i]=sizemenu[0];
142 sizemenu[i].NextItem=&sizemenu[i+1];
143 sizemenu[i].ItemFill=(APTR)&item[i+MENUITEMS];
144 sizemenu[i].TopEdge=i*11;
145 item[i]=item[0];
146 item[i+MENUITEMS]=item[0];
147 item[i+MENUITEMS].IText=sizetxt[i];
148 item[i+MENUITEMS].LeftEdge=11;
149 item[i].IText=mtxt[i];
150 mi[i]=mi[0];
151 mi[i].NextItem=&mi[i+1];
152 mi[i].ItemFill=(APTR)&item[i];
153 mi[i].TopEdge=i*11;
155 mi[MENUITEMS-1].NextItem=NULL;
156 sizemenu[MENUITEMS-1].NextItem=NULL;
157 mi[2].SubItem=&sizemenu[0];
158 mi[5].SubItem=&about;
159 sizemenu[mazesize].Flags|=CHECKED;
161 if (!(screen = (struct Screen*) OpenScreen(&ns))) /* open screen & window */
162 leave ("Can't open Screen");
163 bm = screen->ViewPort.RasInfo->BitMap;
164 rp = &screen->RastPort;
166 nw.Screen=screen;
167 if (!(window = (struct Window*) OpenWindow(&nw))) leave("Can't open Window");
168 SetMenuStrip(window,&menu);
171 * DWR: Following eight statements replace the original color setting.
174 SetRGB4(&screen->ViewPort,0, 0, 0, 0); /* Background, black */
175 SetRGB4(&screen->ViewPort,1, 1, 5, 2); /* Floor, in shadow, dark green */
176 SetRGB4(&screen->ViewPort,2, 2, 7, 1); /* Floor, in sun, light green */
177 SetRGB4(&screen->ViewPort,3, 8, 8, 8); /* Side wall, in shadow, dark grey */
178 SetRGB4(&screen->ViewPort,4,12,12,12); /* Side wall, in sun, light grey */
179 SetRGB4(&screen->ViewPort,5,10,10,10); /* Front wall, in shadow, dark white */
180 SetRGB4(&screen->ViewPort,6,14,14,14); /* Front wall, in sun, light white */
181 SetRGB4(&screen->ViewPort,7, 8, 8,15); /* Sky, blue */
183 /* stuff needed by FloodFill, AreaFill */
184 if(!(raster=(char *)AllocRaster(192,188))) leave("Can't allocate TmpRaster");
185 InitTmpRas(&tmpras,raster,4512);
186 rp->TmpRas=&tmpras;
187 InitArea(&areainfo,areapts,7);
188 rp->AreaInfo=&areainfo;
189 BNDRYOFF(rp);
191 for(i=0;i<3;i++) /* Draw status-display box */
193 SetAPen(rp,i+3);
194 AreaMove(rp,190+5*i,12+5*i);
195 AreaDraw(rp,319-5*i,12+5*i);
196 AreaDraw(rp,319-5*i,125-5*i);
197 AreaDraw(rp,319-5*i-5,125-5*i-5);
198 AreaDraw(rp,319-5*i-5,12+i*5+5);
199 AreaDraw(rp,190+5*i+5,12+i*5+5);
200 AreaEnd(rp);
201 SetAPen(rp,i+2);
202 AreaMove(rp,190+5*i,12+5*i);
203 AreaDraw(rp,190+5*i,125-5*i);
204 AreaDraw(rp,319-5*i,125-5*i);
205 AreaDraw(rp,319-5*i-5,125-5*i-5);
206 AreaDraw(rp,319-5*i-5,12+i*5+5);
207 AreaDraw(rp,190+5*i+5,12+i*5+5);
208 AreaEnd(rp);
211 newmaze();
213 for(;;) /* main loop, wait for a message if not in demo-mode */
215 if (!demomode) WaitPort(window->UserPort);
216 else demo();
217 if(NULL != (msg=(struct IntuiMessage*)GetMsg(window->UserPort)))
219 demomode=FALSE;
220 class=msg->Class;
221 code=msg->Code;
222 ReplyMsg((struct Message *)msg);
223 switch(class)
225 case CLOSEWINDOW:
226 leave("");
227 case VANILLAKEY:
228 if(y!=wayout || x!=xsize-3)
229 switch(code) /* we check numbers 6/4/8, these are arrows on the */
230 { /* num pad keys, so we don't need RawKeyConvert */
231 case '8':
232 forward();
233 break;
234 case '4':
235 left();
236 break;
237 case '6':
238 right();
239 break;
241 break;
242 case MENUPICK:
243 switch(ITEMNUM(code))
245 case 0: /* map */
246 showmaze();
247 moves+=30;
248 break; /* New Maze */
249 case 1:
250 newmaze();
251 break;
252 case 2:
253 if(SUBNUM(code)==mazesize) break;
254 sizemenu[mazesize].Flags&=~CHECKED;
255 mazesize=SUBNUM(code);
256 sizemenu[mazesize].Flags|=CHECKED;
257 newmaze();
258 break;
259 case 3: /* Demo */
260 demomode=TRUE;
261 break;
262 case 4: /* Quit */
263 leave("");
264 case 5: /* About */
265 ; /* Inserted ; to make Aztec happy -- PDS(1) -- 31-jul-88 */
272 void leave(error)
273 char *error;
275 BPTR file;
276 /* Free Resouces & Exit */
277 if(window) CloseWindow(window);
278 if(screen) CloseScreen(screen);
279 if(IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
280 if(GfxBase) CloseLibrary((struct Library *)GfxBase);
281 if (mymaze) FreeMem(mymaze,(xsize>>3)*ysize);
282 if (raster) FreeRaster(raster,192,188);
284 if (*error && WorkBench &&
285 (file=Open("con:20/70/400/60/Maze 3D Demo",MODE_OLDFILE)))
287 Write(file,error,strlen(error));
288 Delay(200L);
289 Close(file);
291 else if (*error) printf("%s\n",error);
292 exit(0);
295 void newmaze()
297 if (mymaze) FreeMem(mymaze,(xsize>>3)*ysize); /* Free old maze */
298 xsize=32+mazesize*16; /* get new dimension */
299 ysize=12+mazesize*12;
300 if (!(mymaze=(char*) AllocMem((xsize>>3)*ysize,MEMF_CHIP|MEMF_CLEAR)))
301 leave("Out of chip memory"); /* allocate new one */
302 SetAPen(rp,6); /* clear status display */
303 RectFill(rp,205,27,304,110);
304 SetAPen(rp,1);
305 statusline(10,"Moves:");
306 statusline(30,"Looking");
307 statusline(60,"Size:");
308 sprintf(buffer,"%ld*%ld",(long)xsize,(long)ysize);
309 statusline(70,buffer);
311 maze(xsize,ysize,mymaze); /* genarate a new maze */
312 seed = FastRand(seed);
313 y= ((seed & 0x7ffe) % (ysize-4)+2) & 0x7ffe; /* random start point */
314 x= 2;
316 seed = FastRand(seed);
317 wayout = ((seed & 0x7ffe) % (ysize-4)+2) & 0x7ffe; /* random exit */
318 MAZESET(xsize-3,wayout,xsize,mymaze); /* open exit */
319 direction=1; /* heading right (east) */
320 statusline(40,heading[direction]);
321 moves=0;
322 show3d();
323 showmaze();
326 void statusline(y,text)
327 short y;
328 char *text;
329 { /* Write text, centered, into */
330 Move(rp,255-strlen(text)*4,27+y); /* status-display */
331 SetAPen(rp,1);
332 SetBPen(rp,6);
333 Text(rp,text,strlen(text));
336 void showmaze() /* show the maze */
338 mazeimage.Width=xsize; /* we define a Image-structure on our */
339 mazeimage.Height=ysize; /* bitmapped maze */
340 mazeimage.ImageData=(short*)mymaze;
341 DrawImage(rp,&mazeimage,255-(xsize/2),127);
342 /* wait for a message */
343 while(! window->UserPort->mp_MsgList.lh_Head->ln_Succ)
345 SetAPen(rp,++i&7); /* exit and current position */
346 WritePixel(rp,255-(xsize/2)+x,127+y); /* are blinking */
347 WritePixel(rp,253-(xsize/2)+xsize,127+wayout);
348 Delay(6L);
350 SetAPen(rp,0);
351 RectFill(rp,191,127,319,199);
356 * DWR: The original 3d function is replaced by the one
357 * at the end of this file..
361 void demo() /* demo mode: follow the left-hand wall until we get to */
362 { /* the exit */
363 long delay;
364 /* be fast if the exit is far away, slow if it gets nearer */
365 delay=19-18*(xsize-3-x+((wayout-y)<0?-(wayout-y):(wayout-y)))/
366 ((wayout<ysize/2? ysize-wayout:wayout)+xsize-3);
368 if(y==wayout && x==xsize-3) /* did we reach the exit ?*/
370 demomode=FALSE; /* stop if we did */
371 return;
372 } /* is it possible to turn left ? */
373 if(MAZETEST(x+dirincs[(direction-1)&3][0],y+dirincs[(direction-1)&3][1],
374 xsize,mymaze))
376 left(); /* yes, turn left */
377 Delay(delay);
378 forward(); /* and one step forward */
380 else if(!forward()) right(); /* if not try to move forward, if everything */
381 /* fails, turn right */
382 Delay(delay);
385 BOOL forward() /* move one step forward if possible */
387 if(!(MAZETEST(x+dirincs[direction][0],
388 y+dirincs[direction][1],xsize,mymaze))) return(FALSE);
390 x+=dirincs[direction][0];
391 y+=dirincs[direction][1];
392 moves++;
393 sprintf(buffer," %ld/%ld ",
394 (long)moves,(long)(xsize-3-x+((wayout-y)<0?-(wayout-y):(wayout-y))));
395 statusline(20,buffer);
396 show3d();
398 if(y==wayout && x==xsize-3) /* has the exit been reached ?*/
400 SetAPen(rp,1); /* yes, write some stupid text */
401 SetBPen(rp,7);
402 Move(rp,58,102); /* DWR: changed */
403 Text(rp,"Solved in",9);
404 SetAPen(rp,6);
405 SetBPen(rp,2); /* DWR: changed */
406 sprintf(buffer,"%ld moves.",(long)moves);
407 Move(rp,94-strlen(buffer)*4,116);
408 Text(rp,buffer,strlen(buffer));
410 return(TRUE);
413 void left() /* turn left */
415 direction--;
416 direction=direction & 3;
417 show3d();
418 statusline(40,heading[direction]);
421 void right() /* turn right */
423 direction++;
424 direction=direction & 3;
425 show3d();
426 statusline(40,heading[direction]);
431 * DWR: The new 3d fucntion and its support.
432 * The basic form of the display is a number of (not drawn) paralel
433 * squares.
434 * Starting at the middle of the display (roughly 200*200) the
435 * smallest square has a side of one dot. The next square two dots.
436 * This increments via 4, 8, 16, 32, 64 to 128 dots. This way
437 * we can see 8 squares deep.
438 * By drawing diagonals we separate walls from the floor and the
439 * sky. When there is a cross-passage, we donot draw these
440 * diagonals but extent the square in the direction of the cross
441 * path until we reach the nearer square.
442 * The shadows are based on a sun at 60 degrees above the horizon
443 * and in the south-west (3 o'clock). This way we have shadow-patterns
444 * which can be expressed in the number system of the squares. (You
445 * remember the 30-60-90 triangle?)
446 * The order of drawing is chosen to mask away some bad drawn shadows
447 * and irregularities in conjunction with edges.
451 #define MAXDEPTH 8 /* 8 squares deep */
453 #define SHADOW 1 /* The value you must subtract from a */
454 /* wall or floor to get it shaded */
455 #define SKY 7
456 #define FLOOR 2 /* 2 -> light green, 1 -> dark green */
457 #define SIDE 4 /* 4 -> light grey, 3-> dark grey */
458 #define FRONT 6 /* 6 -> light white, 5-> dark white (grey of course) */
460 #define HMID 94 /* The horizontal middle of the display */
461 #define VMID 105 /* The vertical middle */
462 /* This was 106, which was wrong */
464 #define LEFT -1 /* Factors which define the direction */
465 #define RIGHT 1 /* from the horizontal middle */
468 short Shadow[]={ 0,0,SHADOW,SHADOW }; /* Change this to reposition the sun */
471 void show3d()
474 short Side; /* Can be "LEFT" or "RIGHT" */
475 short Wall; /* Actual distance we can see */
476 short Depth; /* Level we are drawing in */
477 short Inner; /* Size of the wall in the square we are */
478 short Outer; /* Size of the wall one level nearer */
479 short Middle; /* Size of the wall between those two */
480 short InMid; /* Size of shadow far from us */
481 short OutMid; /* Size of shadow near to us */
482 short Minim; /* The minimal size we use with drawing shadows */
483 short MazeExit; /* Flag set if we are looking at the exit */
486 WaitBOVP(rp);
490 * First we draw the pampas. It consists of floor and
491 * the sky, separated by the horizon.
492 * All floor under the horizon is light green (in the sun),
493 * and all above is blue sky.
496 SetAPen(rp,SKY);
497 RectFill(rp,0,VMID-HMID,2*HMID,VMID);
498 SetAPen(rp,FLOOR);
499 RectFill(rp,0,VMID+1,2*HMID,VMID+HMID);
503 * Find out how far we can see in the maze.
504 * That is howmuch squares is the opposite wall
505 * from us away. If further than we can draw, this
506 * value represents the deepest square we can draw (8).
509 for (Depth=1; Depth<MAXDEPTH; Depth++){
510 if (!(MAZETEST(x+Depth*dirincs[direction][0],
511 y+Depth*dirincs[direction][1],
512 xsize,mymaze)))
513 break;
517 * Keep this value for later when we draw the opposite wall.
518 * Determine the smallest value we use with drawing shades.
519 * And perhaps we are looking at the exit.
522 Wall=Depth-1;
523 Minim=1<<((MAXDEPTH-1)-Depth);
524 MazeExit= ((y==wayout)&&((x+Wall*dirincs[direction][0])==xsize-2));
527 * Draw first the left side of the view, followed
528 * by the right side.
531 for (Side=LEFT; Side<=RIGHT; Side+=2){
534 * Loop for drawing in all squares, beginning at
535 * the farrest level, ending at our present position.
538 for (Depth=Wall; Depth>=0; Depth--){
541 * Detemine some values we use in this square.
544 Inner=1<<((MAXDEPTH-2)-Depth); /* Half size of this square */
545 Outer=Inner<<1; /* Half size on one square nearer */
546 Middle=(Outer+Inner)/2; /* The same size of a square between */
547 if (Outer>HMID) Outer=HMID; /* If too near (larger than display */
548 if (Middle>HMID) Middle=HMID; /* clip it to a useful size */
551 * Are we dealing with a wall or a cross-passage?
554 if (!IsPassage(Side,Depth)){
557 * We draw a wall and its shadow if visable.
558 * The shadow is visable if the surface of the
559 * wall is in the shadow.
562 if (Shadow[(direction+Side)&3]){
564 /* The shadow is on our path, now is
565 * it directed toward us or from us away?
568 if (Shadow[direction]){ /* To us */
569 InMid=Middle;
570 OutMid=Middle<<1;
571 if (OutMid>HMID) OutMid=HMID;
572 } else{ /* From us */
573 InMid=Middle/2+1;
574 if (InMid<Minim) InMid=Minim;
575 OutMid=Middle;
579 * Draw this shadow of the side wall on out path
582 SetAPen(rp,FLOOR-SHADOW);
583 AreaMove(rp,HMID,VMID+InMid);
584 AreaDraw(rp,HMID,VMID+OutMid);
585 AreaDraw(rp,HMID+Side*Outer,VMID+Outer);
586 AreaDraw(rp,HMID+Side*Inner,VMID+Inner);
587 AreaEnd(rp);
589 /* End of drawing shadow on our path */
592 * Draw the side wall itself using the color of
593 * a side wall, but modify it by a possible
594 * shade correction.
597 SetAPen(rp,SIDE-Shadow[(direction+Side)&3]);
598 AreaMove(rp,HMID+Side*Inner,VMID-Inner);
599 AreaDraw(rp,HMID+Side*Inner,VMID+Inner);
600 AreaDraw(rp,HMID+Side*Outer,VMID+Outer);
601 AreaDraw(rp,HMID+Side*Outer,VMID-Outer);
602 AreaEnd(rp);
605 * If we are the first time in this loop,
606 * and the opposite wall is in the shadow,
607 * and the just drawn side wall is in the sun,
608 * draw the shadow from the opposite wall on it.
611 if ((Depth==Wall)&& Shadow[direction]&& !Shadow[(direction+Side)&3]){
612 SetAPen(rp,SIDE-SHADOW);
613 AreaMove(rp,HMID+Side*Inner,VMID-Inner);
614 AreaDraw(rp,HMID+Side*Inner,VMID+Inner);
615 AreaDraw(rp,HMID+Side*Middle,VMID+Middle);
616 AreaEnd(rp);
619 /* End of dealing with a side wall */
621 else{
624 * Here we are dealing with a cross passage,
625 * We first draw some shadows on the floor,
626 * as well on our path, as on the cross passage.
629 SetAPen(rp,FLOOR-SHADOW);
632 * Is the shadow in the direction of our path?
635 if (Shadow[(direction+Side)&3]){
638 * The shadow is in the direction of our path,
639 * now is it directed from us away?
642 if (Shadow[direction]){
645 * The crosswall is in the shade.
646 * Draw the shadow on the coss path.
647 * The distiction between the sides is to meet
648 * the RectFill() form.
651 if (Side==LEFT)
652 RectFill(rp,HMID-Outer,VMID+Inner,HMID,VMID+Middle);
653 else
654 RectFill(rp,HMID,VMID+Inner,HMID+Outer,VMID+Middle);
656 else{
659 * The cross wall is in the sun.
660 * Draw the shadow of the other side.
663 if (Side==LEFT)
664 RectFill(rp,HMID-Outer,VMID+Middle,HMID,VMID+Outer);
665 else
666 RectFill(rp,HMID,VMID+Middle,HMID+Outer,VMID+Outer);
669 /* End of shadow directed to our path */
671 else{
674 * The shadow is directed from our path away.
675 * Now draw the shadow on the cross path if
676 * the cross wall is in the shade.
679 if (Shadow[direction]){
680 AreaMove(rp,HMID+Side*Inner,VMID+Inner);
681 AreaDraw(rp,HMID+Side*Outer,VMID+Inner);
682 AreaDraw(rp,HMID+Side*Outer,VMID+(Inner+Outer)/2);
683 AreaEnd(rp);
688 * If we are here for the first time,
689 * and the opposite wall is visable,
690 * and it is in the shade,
691 * extent the shadow of the opposite wall to
692 * the one from the cross wall. (A tiny triangle)
695 if ((Depth==Wall)&&(Depth<MAXDEPTH)&&(Shadow[direction])){
696 AreaMove(rp,HMID+Side*Inner,VMID+Inner);
697 AreaDraw(rp,HMID+Side*Middle,VMID+Middle);
698 AreaDraw(rp,HMID+Side*Outer,VMID+Middle);
699 AreaDraw(rp,HMID+Side*Outer,VMID+Inner);
700 AreaEnd(rp);
704 * If we are not dealing with the exit's cross path
705 * draw the cross wall itself.
708 if (!(MazeExit&&(Depth>(Wall-1)))){
709 SetAPen(rp,FRONT-Shadow[direction]);
710 if (Side==RIGHT)
711 RectFill(rp,HMID+Inner,VMID-Inner,HMID+Outer,VMID+Inner);
712 else
713 RectFill(rp,HMID-Outer,VMID-Inner,HMID-Inner,VMID+Inner);
717 /* End of drawing a cross passage (or side wall) */
719 /* End of drawing in subsequent squares */
721 /* End of drawing the left and right side ot the picture */
724 * Now we have to draw the opposite wall
725 * or the exit if not too far away
728 Depth=Wall;
730 if (Depth<MAXDEPTH-1){
733 * It is not too far away.
734 * Fill in again those sizes.
737 Inner=1<<((MAXDEPTH-2)-Depth);
738 Outer=Inner<<1;
739 Middle=(Outer+Inner)/2;
740 if (Outer>HMID) Outer=HMID;
741 if (Middle>HMID) Middle=HMID;
744 * Are we not looking at the exit?
747 if (!MazeExit){
750 * We are looking at an opposite wall.
751 * Draw its shadow on the floor if it is in the shade.
754 if (Shadow[direction]){
755 SetAPen(rp,FLOOR-SHADOW);
756 AreaMove(rp,HMID+1-Inner,VMID+Inner);
757 AreaDraw(rp,HMID+1-Middle,VMID+Middle);
758 AreaDraw(rp,HMID-1+Middle,VMID+Middle);
759 AreaDraw(rp,HMID-1+Inner,VMID+Inner);
760 AreaEnd(rp);
764 * Draw the opposite wall itself.
767 SetAPen(rp,FRONT-Shadow[direction]);
768 RectFill(rp,HMID-Inner,VMID-Inner,HMID+Inner,VMID+Inner);
771 * If the opposite wall is bounded to a side wall,
772 * and this side wall is in the shadow,
773 * and the opposite wall is in the sun,
774 * draw the shadow of the side wall on the opposite wall.
777 for (Side=LEFT; Side<=RIGHT; Side+=2){
778 if (
779 (!IsPassage(Side,Depth))&&
780 (Shadow[(direction+Side)&3])&&
781 (!Shadow[direction])
783 SetAPen(rp,FRONT-SHADOW);
784 AreaMove(rp,HMID+Side*Inner,VMID-Inner);
785 AreaDraw(rp,HMID+Side*Inner,VMID+Inner);
786 AreaDraw(rp,HMID,VMID+Inner);
787 AreaEnd(rp);
797 * This was original in line, but it disturbed the view over the
798 * code. Placing it in a function made the clearity of the show3d()
799 * function better.
800 * This function returns the presence of a cross passage at <Side>'s
801 * side and <Depth> from us away.
804 int IsPassage(Side,Depth)
805 short Side,Depth;
807 register int xx,yy;
808 xx=x+dirincs[(direction+Side)&3][0]+Depth*dirincs[direction][0];
809 yy=y+dirincs[(direction+Side)&3][1]+Depth*dirincs[direction][1];
810 return(MAZETEST(xx,yy, xsize,mymaze));