|
|
1.1 root 1: /* Copyright Massachusetts Institute of Technology 1984, 1985 */
2:
3: #include <X/Xlib.h>
4: #include <stdio.h>
5: #include <sgtty.h>
6: #define MAZE_SIZE 36
7: #define PIXSIZE 768
8: #define SCANSIZE (PIXSIZE/16)
9: #define HALFSIZE (SCANSIZE/2)
10: #define CENTER (PIXSIZE/2)
11: #define SIDE (PIXSIZE/3)
12: #define MASK_SIZE ((PIXSIZE*PIXSIZE)/16)
13: #define STRIP_SIZE (((PIXSIZE/6)*PIXSIZE)/16)
14:
15: struct room {
16: struct room *north;
17: struct room *south;
18: struct room *east;
19: struct room *west;
20: };
21:
22: struct room *front(dir, rm)
23: int dir;
24: struct room *rm;
25: {
26: if(rm == NULL) {
27: printf("NULL room\n");
28: exit(1);
29: }
30: switch (dir) {
31: case 2: return(rm->south);
32: case 1: return(rm->east);
33: case 0: return(rm->north);
34: case 3: return(rm->west);
35: default: printf("dir = %d\n",dir);
36: exit(1);
37: }
38: }
39:
40: struct room *left(dir, rm)
41: int dir;
42: struct room *rm;
43: {
44: return(front((dir + 3) % 4, rm));
45: }
46:
47: struct room *right(dir, rm)
48: int dir;
49: struct room *rm;
50: {
51: return(front((dir + 1) % 4, rm));
52: }
53:
54: Window win;
55: int forepix, backpix;
56: Bitmap pat[20];
57:
58: main(argc,argv)
59: int argc;
60: char **argv;
61: {
62: int dir,i,fd,moved;
63: struct room m[MAZE_SIZE],*this_room,*next_room;
64: char c;
65: XEvent ev;
66: char *str, *prog;
67: char *maze_file = NULL;
68: char *display = NULL;
69: int nbytes;
70: int bwidth;
71: char *fore_color, *back_color, *brdr_color;
72: Pixmap bground, border;
73: int reverse = 0;
74: ColorDef cdef;
75: WindowInfo info;
76:
77: prog = *argv;
78: if ((str = XGetDefault(prog, "ReverseVideo")) && strcmp(str, "on") == 0)
79: reverse = 1;
80: bwidth = 2;
81: if (str = XGetDefault(prog, "BorderWidth"))
82: bwidth = atoi(str);
83: fore_color = XGetDefault(prog, "ForeGround");
84: back_color = XGetDefault(prog, "BackGround");
85: brdr_color = XGetDefault(prog, "Border");
86: for (argv++; --argc; argv++) {
87: if (!strcmp(*argv, "-rv")) {
88: reverse = 1;
89: } else if (!strcmp(*argv, "-fg") && argc) {
90: argv++;
91: argc--;
92: fore_color = *argv;
93: } else if (!strcmp(*argv, "-bg") && argc) {
94: argv++;
95: argc--;
96: back_color = *argv;
97: } else if (!strcmp(*argv, "-bd") && argc) {
98: argv++;
99: argc--;
100: brdr_color = *argv;
101: } else if (index(*argv, ':')) {
102: display = *argv;
103: } else if (**argv == '-' || maze_file != NULL) {
104: printf("usage: maze [-rv] [-fg <color>] [-bg <color>] [-bd <color>] [host:display] [file]\n");
105: exit(1);
106: } else {
107: maze_file = *argv;
108: }
109: }
110: if (!XOpenDisplay(display)) {
111: perror(prog);
112: exit(1);
113: }
114: if (reverse) {
115: forepix = BlackPixel;
116: backpix = WhitePixel;
117: bground = WhitePixmap;
118: border = BlackPixmap;
119: } else {
120: forepix = WhitePixel;
121: backpix = BlackPixel;
122: bground = BlackPixmap;
123: border = WhitePixmap;
124: }
125: if (DisplayCells() > 2) {
126: if (fore_color && XParseColor(fore_color, &cdef) &&
127: XGetHardwareColor(&cdef))
128: forepix = cdef.pixel;
129: if (back_color && XParseColor(back_color, &cdef) &&
130: XGetHardwareColor(&cdef))
131: bground = XMakeTile(backpix = cdef.pixel);
132: if (brdr_color && XParseColor(brdr_color, &cdef) &&
133: XGetHardwareColor(&cdef))
134: border = XMakeTile(cdef.pixel);
135: }
136:
137: get_maze(m, maze_file);
138: this_room = &m[0];
139: next_room = NULL;
140: dir = 1;
141: XQueryWindow(RootWindow, &info);
142: win = XCreateWindow(RootWindow,
143: (info.width - PIXSIZE - (bwidth<<1))>>1,
144: (info.height - PIXSIZE - (bwidth<<1))>>1,
145: PIXSIZE,PIXSIZE,bwidth,border,bground);
146: XMapWindow(win);
147: XSelectInput(win, ButtonPressed|KeyPressed|ExposeWindow);
148: set_up_maze();
149: while (1) {
150: XClear(win);
151: next_room = this_room;
152: for(i=0;i<9;i++){
153: if(right(dir,next_room) != NULL) draw_pass(i-1,1);
154: else draw_wall(i-1,1);
155: if(left(dir,next_room) != NULL) draw_pass(i-1,-1);
156: else draw_wall(i-1,-1);
157: if((next_room = front(dir,next_room)) == NULL){
158: draw_block(i);
159: break;
160: }
161: }
162: if(i==9) XPixSet(win,CENTER-1,0,2,PIXSIZE,backpix);
163: moved = 0;
164: while(!moved){
165: XNextEvent(&ev);
166: switch(ev.type){
167: case ButtonPressed:
168: switch(((XButtonPressedEvent *)&ev)->detail & ValueMask) {
169: case LeftButton:
170: str = "l";
171: break;
172: case MiddleButton:
173: if (((XButtonPressedEvent *)&ev)->detail & ShiftMask)
174: str = "b";
175: else
176: str = "f";
177: break;
178: case RightButton:
179: str = "r";
180: break;
181: }
182: nbytes = 1;
183: break;
184: case KeyPressed:
185: str = XLookupMapping (&ev, &nbytes);
186: break;
187: case ExposeWindow:
188: XSync(0);
189: while (QLength()) {
190: XPeekEvent(&ev);
191: if (ev.type != ExposeWindow)
192: break;
193: XNextEvent(&ev);
194: }
195: nbytes = 0;
196: moved++;
197: }
198: if (nbytes == 1)
199: switch (*str) {
200: case 'r':
201: dir = (dir + 1) % 4;
202: moved++;
203: break;
204: case 'l':
205: dir = (dir + 3) % 4;
206: moved++;
207: break;
208: case 'f':
209: next_room = front(dir,this_room);
210: if(next_room != NULL){
211: this_room = next_room;
212: moved++;
213: }
214: break;
215: case 'b':
216: next_room = front((dir+2)%4,this_room);
217: if(next_room != NULL){
218: this_room = next_room;
219: moved++;
220: }
221: break;
222: case 'q':
223: exit(0);
224: default:
225: break;
226: }
227: }
228: }
229: }
230:
231: #ifdef notdef
232: #define MAZE_SIDE 6
233: print_maze(m)
234: struct room m[MAZE_SIZE];
235: {
236: register int x, y;
237:
238: for(x=0;x<MAZE_SIDE;x++){
239: for(y=0;y<MAZE_SIDE;y++){
240: if(m[6*x+y].north == NULL){
241: printf("+--+");
242: }
243: else printf("+ +");
244: }
245: printf("\n");
246: for(y=0;y<MAZE_SIDE;y++){
247: if(m[6*x+y].west == NULL){
248: printf("| ");
249: }
250: else printf(" ");
251: if(m[6*x+y].east == NULL){
252: printf("|");
253: }
254: else printf(" ");
255: }
256: printf("\n");
257: for(y=0;y<MAZE_SIDE;y++){
258: if(m[6*x+y].south == NULL){
259: printf("+--+");
260: }
261: else printf("+ +");
262: }
263: printf("\n");
264: }
265: }
266: #endif
267:
268: draw_wall(dist,side)
269: int dist,side;
270: {
271: int x3,x4;
272:
273: x3 = SIDE>>dist;
274: x4 = SIDE>>(dist+1);
275:
276: if (x3>CENTER) {
277: x4 >>= 1;
278: if (side < 0) {
279: XPixFill(win,0,0,x4,PIXSIZE,forepix,pat[0],GXcopy,AllPlanes);
280: } else {
281: XPixFill(win,PIXSIZE-x4+1,0,x4-1,PIXSIZE,forepix,pat[19-dist-1],GXcopy,AllPlanes);
282: }
283: } else {
284: if(side<0) {
285: XPixFill(win,CENTER-x3+1,0,x4-1,PIXSIZE,forepix,pat[dist+1],GXcopy,AllPlanes);
286: } else {
287: XPixFill(win,CENTER+x4+1,0,x4-1,PIXSIZE,forepix,pat[19-dist-1],GXcopy,AllPlanes);
288: }
289: }
290: }
291:
292: draw_pass(dist,side)
293: int dist,side;
294: {
295: int x3,x4,i;
296:
297: x3 = SIDE>>dist;
298: x4 = SIDE>>(dist+1);
299:
300: if(side < 0){
301: XPixSet(win,CENTER-x3,CENTER-x4,x4,x3,forepix);
302: XPixSet(win,CENTER-x3,0,1,PIXSIZE,backpix);
303: XPixSet(win,CENTER-x4,0,1,PIXSIZE,backpix);
304: }
305: else {
306: XPixSet(win,CENTER+x4,CENTER-x4,x4,x3,forepix);
307: XPixSet(win,CENTER+x4,0,1,PIXSIZE,backpix);
308: XPixSet(win,CENTER+x3,0,1,PIXSIZE,backpix);
309: }
310: }
311:
312: draw_block(dist)
313: int dist;
314: {
315: int x3,x4,i;
316: Vertex verts[5];
317:
318: x3 = SIDE>>dist;
319: x4 = SIDE>>(dist+1);
320:
321: XPixSet(win,CENTER-x3+1,CENTER-x3,2*x3-1,2*x3,forepix);
322: }
323:
324: int default_maze[] = {-1,-1,6,-1,
325: -1,2,-1,-1,
326: -1,-1,8,1,
327: -1,4,9,-1,
328: -1,5,-1,3,
329: -1,-1,-1,4,
330: 0,7,12,11,
331: -1,8,-1,6,
332: 2,9,-1,7,
333: 3,10,-1,8,
334: -1,11,16,9,
335: -1,6,-1,10,
336: 6,-1,18,-1,
337: -1,14,19,-1,
338: -1,15,20,13,
339: -1,-1,21,-1,
340: 10,17,-1,-1,
341: -1,-1,-1,16,
342: 12,19,-1,-1,
343: 13,-1,-1,18,
344: 14,-1,26,-1,
345: 15,22,27,-1,
346: -1,23,28,21,
347: -1,-1,-1,22,
348: -1,25,30,-1,
349: -1,-1,31,24,
350: 20,27,-1,-1,
351: 21,-1,-1,26,
352: 22,29,34,-1,
353: -1,-1,-1,28,
354: 24,-1,-1,-1,
355: 25,32,-1,-1,
356: -1,33,-1,31,
357: -1,34,-1,32,
358: 28,35,-1,33,
359: -1,-1,-1,34};
360:
361: get_maze(m, maze_file)
362: struct room m[MAZE_SIZE];
363: char *maze_file;
364: {
365: FILE *fp;
366: int i,j,n,e,s,w;
367:
368: if (maze_file == NULL) {
369: for (i=0,j=0;i<MAZE_SIZE;i++){
370: n=default_maze[j++];
371: e=default_maze[j++];
372: s=default_maze[j++];
373: w=default_maze[j++];
374: if(n == -1) m[i].north = NULL;
375: else m[i].north = &m[n];
376: if(s == -1) m[i].south = NULL;
377: else m[i].south = &m[s];
378: if(e == -1) m[i].east = NULL;
379: else m[i].east = &m[e];
380: if(w == -1) m[i].west = NULL;
381: else m[i].west = &m[w];
382: }
383: return;
384: }
385: if((fp = fopen(maze_file,"r")) == NULL){
386: perror("maze");
387: exit(1);
388: }
389: for(i=0;i<MAZE_SIZE;i++){
390: fscanf(fp,"%d,%d,%d,%d\n",&n,&e,&s,&w);
391: if(n == -1) m[i].north = NULL;
392: else m[i].north = &m[n];
393: if(s == -1) m[i].south = NULL;
394: else m[i].south = &m[s];
395: if(e == -1) m[i].east = NULL;
396: else m[i].east = &m[e];
397: if(w == -1) m[i].west = NULL;
398: else m[i].west = &m[w];
399: }
400: fclose(fp);
401: }
402:
403: set_up_maze()
404: {
405: Bitmap b;
406: int i,bound[21],top[21],k,j,x;
407: short *strips[21],*mask;
408:
409: bound[0] = 0;
410: bound[10] = CENTER;
411: bound[20] = PIXSIZE;
412: for(i=1;i<10;i++){
413: bound[10-i]=CENTER-(SIDE/(1<<(9-i)));
414: bound[10+i]=CENTER+(SIDE/(1<<(9-i)));
415: }
416: for(i=0;i<21;i++)
417: top[i] = 0;
418: mask = (short *)calloc(MASK_SIZE, sizeof(short));
419: for (i=0;i<21;i++)
420: strips[i]=(short *)malloc(STRIP_SIZE * sizeof(short));
421: for(i=0;i<HALFSIZE;i++){
422: for(j=0;j<16;j++){
423: mask[SCANSIZE*(16*i+j)+i] = 0xaaaa>>(15-j);
424: mask[SCANSIZE*(16*i+j)+SCANSIZE-1-i] = 0xaaaa<<(15-j);
425: mask[SCANSIZE*(PIXSIZE-1-16*i-j)+i] = 0x5555>>(15-j);
426: mask[SCANSIZE*(PIXSIZE-1-16*i-j)+SCANSIZE-1-i] = 0x5555<<(15-j);
427: }
428: }
429: for(i=0;i<(HALFSIZE-1);i++){
430: for(j=(i+1)*16;j<CENTER;j++){
431: if((j % 2) == 1){
432: mask[SCANSIZE*j+i] = 0xaaaa;
433: mask[SCANSIZE*j+SCANSIZE-1-i] = 0xaaaa;
434: mask[SCANSIZE*(PIXSIZE-1-j)+i] = 0x5555;
435: mask[SCANSIZE*(PIXSIZE-1-j)+SCANSIZE-1-i] = 0x5555;
436: }
437: else {
438: mask[SCANSIZE*j+i] = 0x5555;
439: mask[SCANSIZE*j+SCANSIZE-1-i] = 0x5555;
440: mask[SCANSIZE*(PIXSIZE-1-j)+i] = 0xaaaa;
441: mask[SCANSIZE*(PIXSIZE-1-j)+SCANSIZE-1-i] = 0xaaaa;
442: }
443: }
444: }
445: for(j=0;j<PIXSIZE;j++){
446: for(i=0;i<SCANSIZE;i++){
447: for(k=1;k<21;k++){
448: if((i*16) < bound[k]) {
449: strips[k-1][top[k-1]++] = mask[SCANSIZE*j+i];
450: break;
451: }
452: }
453: }
454: }
455: for(i=5;i<15;i++)
456: top[i] = 0;
457: for(i=0;i<PIXSIZE;i++){
458: strips[5][top[5]++] = mask[SCANSIZE*i+HALFSIZE-1];
459: strips[6][top[6]++] = mask[SCANSIZE*i+HALFSIZE-1]>>8;
460: strips[7][top[7]++] = mask[SCANSIZE*i+HALFSIZE-1]>>12;
461: strips[8][top[8]++] = mask[SCANSIZE*i+HALFSIZE-1]>>14;
462: strips[9][top[9]++] = mask[SCANSIZE*i+HALFSIZE-1]>>15;
463: strips[10][top[10]++] = mask[SCANSIZE*i+HALFSIZE];
464: strips[11][top[11]++] = mask[SCANSIZE*i+HALFSIZE]>>1;
465: strips[12][top[12]++] = mask[SCANSIZE*i+HALFSIZE]>>2;
466: strips[13][top[13]++] = mask[SCANSIZE*i+HALFSIZE]>>4;
467: strips[14][top[14]++] = mask[SCANSIZE*i+HALFSIZE]>>8;
468: }
469: for(k=1;k<21;k++){
470: if (bound[k] != bound[k-1]) {
471: pat[k-1] = XStoreBitmap(bound[k]-bound[k-1],PIXSIZE,strips[k-1]);
472: if (pat[k-1] == NULL)
473: exit(1);
474: } else
475: pat[k-1] = NULL;
476: }
477: free(mask);
478: for (i=0;i<21;i++)
479: free(strips[i]);
480: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.