|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - downloadIndex: ┃ T m ┃
Length: 10903 (0x2a97) Types: TextFile Names: »maze.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─ ⟦526ad3590⟧ »EUUGD11/gnu-31mar87/X.V10.R4.tar.Z« └─⟦2109abc41⟧ └─ ⟦this⟧ »./X.V10R4/hacks/maze/maze.c«
/* Copyright Massachusetts Institute of Technology 1984, 1985 */ #include <X/Xlib.h> #include <stdio.h> #include <sgtty.h> #define MAZE_SIZE 36 #define PIXSIZE 768 #define SCANSIZE (PIXSIZE/16) #define HALFSIZE (SCANSIZE/2) #define CENTER (PIXSIZE/2) #define SIDE (PIXSIZE/3) #define MASK_SIZE ((PIXSIZE*PIXSIZE)/16) #define STRIP_SIZE (((PIXSIZE/6)*PIXSIZE)/16) struct room { struct room *north; struct room *south; struct room *east; struct room *west; }; struct room *front(dir, rm) int dir; struct room *rm; { if(rm == NULL) { printf("NULL room\n"); exit(1); } switch (dir) { case 2: return(rm->south); case 1: return(rm->east); case 0: return(rm->north); case 3: return(rm->west); default: printf("dir = %d\n",dir); exit(1); } } struct room *left(dir, rm) int dir; struct room *rm; { return(front((dir + 3) % 4, rm)); } struct room *right(dir, rm) int dir; struct room *rm; { return(front((dir + 1) % 4, rm)); } Window win; int forepix, backpix; Bitmap pat[20]; main(argc,argv) int argc; char **argv; { int dir,i,fd,moved; struct room m[MAZE_SIZE],*this_room,*next_room; char c; XEvent ev; char *str, *prog; char *maze_file = NULL; char *display = NULL; int nbytes; int bwidth; char *fore_color, *back_color, *brdr_color; Pixmap bground, border; int reverse = 0; ColorDef cdef; WindowInfo info; prog = *argv; if ((str = XGetDefault(prog, "ReverseVideo")) && strcmp(str, "on") == 0) reverse = 1; bwidth = 2; if (str = XGetDefault(prog, "BorderWidth")) bwidth = atoi(str); fore_color = XGetDefault(prog, "ForeGround"); back_color = XGetDefault(prog, "BackGround"); brdr_color = XGetDefault(prog, "Border"); for (argv++; --argc; argv++) { if (!strcmp(*argv, "-rv")) { reverse = 1; } else if (!strcmp(*argv, "-fg") && argc) { argv++; argc--; fore_color = *argv; } else if (!strcmp(*argv, "-bg") && argc) { argv++; argc--; back_color = *argv; } else if (!strcmp(*argv, "-bd") && argc) { argv++; argc--; brdr_color = *argv; } else if (index(*argv, ':')) { display = *argv; } else if (**argv == '-' || maze_file != NULL) { printf("usage: maze [-rv] [-fg <color>] [-bg <color>] [-bd <color>] [host:display] [file]\n"); exit(1); } else { maze_file = *argv; } } if (!XOpenDisplay(display)) { perror(prog); exit(1); } if (reverse) { forepix = BlackPixel; backpix = WhitePixel; bground = WhitePixmap; border = BlackPixmap; } else { forepix = WhitePixel; backpix = BlackPixel; bground = BlackPixmap; border = WhitePixmap; } if (DisplayCells() > 2) { if (fore_color && XParseColor(fore_color, &cdef) && XGetHardwareColor(&cdef)) forepix = cdef.pixel; if (back_color && XParseColor(back_color, &cdef) && XGetHardwareColor(&cdef)) bground = XMakeTile(backpix = cdef.pixel); if (brdr_color && XParseColor(brdr_color, &cdef) && XGetHardwareColor(&cdef)) border = XMakeTile(cdef.pixel); } get_maze(m, maze_file); this_room = &m[0]; next_room = NULL; dir = 1; XQueryWindow(RootWindow, &info); win = XCreateWindow(RootWindow, (info.width - PIXSIZE - (bwidth<<1))>>1, (info.height - PIXSIZE - (bwidth<<1))>>1, PIXSIZE,PIXSIZE,bwidth,border,bground); XMapWindow(win); XSelectInput(win, ButtonPressed|KeyPressed|ExposeWindow); set_up_maze(); while (1) { XClear(win); next_room = this_room; for(i=0;i<9;i++){ if(right(dir,next_room) != NULL) draw_pass(i-1,1); else draw_wall(i-1,1); if(left(dir,next_room) != NULL) draw_pass(i-1,-1); else draw_wall(i-1,-1); if((next_room = front(dir,next_room)) == NULL){ draw_block(i); break; } } if(i==9) XPixSet(win,CENTER-1,0,2,PIXSIZE,backpix); moved = 0; while(!moved){ XNextEvent(&ev); switch(ev.type){ case ButtonPressed: switch(((XButtonPressedEvent *)&ev)->detail & ValueMask) { case LeftButton: str = "l"; break; case MiddleButton: if (((XButtonPressedEvent *)&ev)->detail & ShiftMask) str = "b"; else str = "f"; break; case RightButton: str = "r"; break; } nbytes = 1; break; case KeyPressed: str = XLookupMapping (&ev, &nbytes); break; case ExposeWindow: XSync(0); while (QLength()) { XPeekEvent(&ev); if (ev.type != ExposeWindow) break; XNextEvent(&ev); } nbytes = 0; moved++; } if (nbytes == 1) switch (*str) { case 'r': dir = (dir + 1) % 4; moved++; break; case 'l': dir = (dir + 3) % 4; moved++; break; case 'f': next_room = front(dir,this_room); if(next_room != NULL){ this_room = next_room; moved++; } break; case 'b': next_room = front((dir+2)%4,this_room); if(next_room != NULL){ this_room = next_room; moved++; } break; case 'q': exit(0); default: break; } } } } #ifdef notdef #define MAZE_SIDE 6 print_maze(m) struct room m[MAZE_SIZE]; { register int x, y; for(x=0;x<MAZE_SIDE;x++){ for(y=0;y<MAZE_SIDE;y++){ if(m[6*x+y].north == NULL){ printf("+--+"); } else printf("+ +"); } printf("\n"); for(y=0;y<MAZE_SIDE;y++){ if(m[6*x+y].west == NULL){ printf("| "); } else printf(" "); if(m[6*x+y].east == NULL){ printf("|"); } else printf(" "); } printf("\n"); for(y=0;y<MAZE_SIDE;y++){ if(m[6*x+y].south == NULL){ printf("+--+"); } else printf("+ +"); } printf("\n"); } } #endif draw_wall(dist,side) int dist,side; { int x3,x4; x3 = SIDE>>dist; x4 = SIDE>>(dist+1); if (x3>CENTER) { x4 >>= 1; if (side < 0) { XPixFill(win,0,0,x4,PIXSIZE,forepix,pat[0],GXcopy,AllPlanes); } else { XPixFill(win,PIXSIZE-x4+1,0,x4-1,PIXSIZE,forepix,pat[19-dist-1],GXcopy,AllPlanes); } } else { if(side<0) { XPixFill(win,CENTER-x3+1,0,x4-1,PIXSIZE,forepix,pat[dist+1],GXcopy,AllPlanes); } else { XPixFill(win,CENTER+x4+1,0,x4-1,PIXSIZE,forepix,pat[19-dist-1],GXcopy,AllPlanes); } } } draw_pass(dist,side) int dist,side; { int x3,x4,i; x3 = SIDE>>dist; x4 = SIDE>>(dist+1); if(side < 0){ XPixSet(win,CENTER-x3,CENTER-x4,x4,x3,forepix); XPixSet(win,CENTER-x3,0,1,PIXSIZE,backpix); XPixSet(win,CENTER-x4,0,1,PIXSIZE,backpix); } else { XPixSet(win,CENTER+x4,CENTER-x4,x4,x3,forepix); XPixSet(win,CENTER+x4,0,1,PIXSIZE,backpix); XPixSet(win,CENTER+x3,0,1,PIXSIZE,backpix); } } draw_block(dist) int dist; { int x3,x4,i; Vertex verts[5]; x3 = SIDE>>dist; x4 = SIDE>>(dist+1); XPixSet(win,CENTER-x3+1,CENTER-x3,2*x3-1,2*x3,forepix); } int default_maze[] = {-1,-1,6,-1, -1,2,-1,-1, -1,-1,8,1, -1,4,9,-1, -1,5,-1,3, -1,-1,-1,4, 0,7,12,11, -1,8,-1,6, 2,9,-1,7, 3,10,-1,8, -1,11,16,9, -1,6,-1,10, 6,-1,18,-1, -1,14,19,-1, -1,15,20,13, -1,-1,21,-1, 10,17,-1,-1, -1,-1,-1,16, 12,19,-1,-1, 13,-1,-1,18, 14,-1,26,-1, 15,22,27,-1, -1,23,28,21, -1,-1,-1,22, -1,25,30,-1, -1,-1,31,24, 20,27,-1,-1, 21,-1,-1,26, 22,29,34,-1, -1,-1,-1,28, 24,-1,-1,-1, 25,32,-1,-1, -1,33,-1,31, -1,34,-1,32, 28,35,-1,33, -1,-1,-1,34}; get_maze(m, maze_file) struct room m[MAZE_SIZE]; char *maze_file; { FILE *fp; int i,j,n,e,s,w; if (maze_file == NULL) { for (i=0,j=0;i<MAZE_SIZE;i++){ n=default_maze[j++]; e=default_maze[j++]; s=default_maze[j++]; w=default_maze[j++]; if(n == -1) m[i].north = NULL; else m[i].north = &m[n]; if(s == -1) m[i].south = NULL; else m[i].south = &m[s]; if(e == -1) m[i].east = NULL; else m[i].east = &m[e]; if(w == -1) m[i].west = NULL; else m[i].west = &m[w]; } return; } if((fp = fopen(maze_file,"r")) == NULL){ perror("maze"); exit(1); } for(i=0;i<MAZE_SIZE;i++){ fscanf(fp,"%d,%d,%d,%d\n",&n,&e,&s,&w); if(n == -1) m[i].north = NULL; else m[i].north = &m[n]; if(s == -1) m[i].south = NULL; else m[i].south = &m[s]; if(e == -1) m[i].east = NULL; else m[i].east = &m[e]; if(w == -1) m[i].west = NULL; else m[i].west = &m[w]; } fclose(fp); } set_up_maze() { Bitmap b; int i,bound[21],top[21],k,j,x; short *strips[21],*mask; bound[0] = 0; bound[10] = CENTER; bound[20] = PIXSIZE; for(i=1;i<10;i++){ bound[10-i]=CENTER-(SIDE/(1<<(9-i))); bound[10+i]=CENTER+(SIDE/(1<<(9-i))); } for(i=0;i<21;i++) top[i] = 0; mask = (short *)calloc(MASK_SIZE, sizeof(short)); for (i=0;i<21;i++) strips[i]=(short *)malloc(STRIP_SIZE * sizeof(short)); for(i=0;i<HALFSIZE;i++){ for(j=0;j<16;j++){ mask[SCANSIZE*(16*i+j)+i] = 0xaaaa>>(15-j); mask[SCANSIZE*(16*i+j)+SCANSIZE-1-i] = 0xaaaa<<(15-j); mask[SCANSIZE*(PIXSIZE-1-16*i-j)+i] = 0x5555>>(15-j); mask[SCANSIZE*(PIXSIZE-1-16*i-j)+SCANSIZE-1-i] = 0x5555<<(15-j); } } for(i=0;i<(HALFSIZE-1);i++){ for(j=(i+1)*16;j<CENTER;j++){ if((j % 2) == 1){ mask[SCANSIZE*j+i] = 0xaaaa; mask[SCANSIZE*j+SCANSIZE-1-i] = 0xaaaa; mask[SCANSIZE*(PIXSIZE-1-j)+i] = 0x5555; mask[SCANSIZE*(PIXSIZE-1-j)+SCANSIZE-1-i] = 0x5555; } else { mask[SCANSIZE*j+i] = 0x5555; mask[SCANSIZE*j+SCANSIZE-1-i] = 0x5555; mask[SCANSIZE*(PIXSIZE-1-j)+i] = 0xaaaa; mask[SCANSIZE*(PIXSIZE-1-j)+SCANSIZE-1-i] = 0xaaaa; } } } for(j=0;j<PIXSIZE;j++){ for(i=0;i<SCANSIZE;i++){ for(k=1;k<21;k++){ if((i*16) < bound[k]) { strips[k-1][top[k-1]++] = mask[SCANSIZE*j+i]; break; } } } } for(i=5;i<15;i++) top[i] = 0; for(i=0;i<PIXSIZE;i++){ strips[5][top[5]++] = mask[SCANSIZE*i+HALFSIZE-1]; strips[6][top[6]++] = mask[SCANSIZE*i+HALFSIZE-1]>>8; strips[7][top[7]++] = mask[SCANSIZE*i+HALFSIZE-1]>>12; strips[8][top[8]++] = mask[SCANSIZE*i+HALFSIZE-1]>>14; strips[9][top[9]++] = mask[SCANSIZE*i+HALFSIZE-1]>>15; strips[10][top[10]++] = mask[SCANSIZE*i+HALFSIZE]; strips[11][top[11]++] = mask[SCANSIZE*i+HALFSIZE]>>1; strips[12][top[12]++] = mask[SCANSIZE*i+HALFSIZE]>>2; strips[13][top[13]++] = mask[SCANSIZE*i+HALFSIZE]>>4; strips[14][top[14]++] = mask[SCANSIZE*i+HALFSIZE]>>8; } for(k=1;k<21;k++){ if (bound[k] != bound[k-1]) { pat[k-1] = XStoreBitmap(bound[k]-bound[k-1],PIXSIZE,strips[k-1]); if (pat[k-1] == NULL) exit(1); } else pat[k-1] = NULL; } free(mask); for (i=0;i<21;i++) free(strips[i]); }