xref: /plan9/sys/src/games/memo.c (revision 3039af76362cf40de5148fe2f6aaa092d1b7d350)
13d156f8aSDavid du Colombier /* Federico Benavento <benavento@gmail.com> */
23d156f8aSDavid du Colombier #include <u.h>
33d156f8aSDavid du Colombier #include <libc.h>
43d156f8aSDavid du Colombier #include <draw.h>
53d156f8aSDavid du Colombier #include <event.h>
63d156f8aSDavid du Colombier 
7*3039af76SDavid du Colombier enum {
8*3039af76SDavid du Colombier 	Facesize = 48
9*3039af76SDavid du Colombier };
10*3039af76SDavid du Colombier 
11*3039af76SDavid du Colombier 
12312a1df1SDavid du Colombier void memoinit(void);
13312a1df1SDavid du Colombier void redraw(void);
143d156f8aSDavid du Colombier void eresized(int);
153d156f8aSDavid du Colombier void resize(int i);
163d156f8aSDavid du Colombier void afaces(void);
173d156f8aSDavid du Colombier void allocblocks(void);
183d156f8aSDavid du Colombier Image *openface(char *path);
193d156f8aSDavid du Colombier 
203d156f8aSDavid du Colombier Image *face[18];
213d156f8aSDavid du Colombier char buf[100];
223d156f8aSDavid du Colombier ushort winflag, level;
23312a1df1SDavid du Colombier Image *back;
24312a1df1SDavid du Colombier Image *fore;
253d156f8aSDavid du Colombier 
26312a1df1SDavid du Colombier enum
273d156f8aSDavid du Colombier {
28312a1df1SDavid du Colombier 	Eninit,
29312a1df1SDavid du Colombier 	Eshow,
30312a1df1SDavid du Colombier 	Ehide,
31312a1df1SDavid du Colombier 	Edisc,
32312a1df1SDavid du Colombier };
33312a1df1SDavid du Colombier 
34312a1df1SDavid du Colombier struct
35312a1df1SDavid du Colombier {
36312a1df1SDavid du Colombier 	Image *face;
37312a1df1SDavid du Colombier 	Rectangle r;
38312a1df1SDavid du Colombier 	int	flag;
393d156f8aSDavid du Colombier }block[36];
403d156f8aSDavid du Colombier 
413d156f8aSDavid du Colombier char *buttons[] =
423d156f8aSDavid du Colombier {
433d156f8aSDavid du Colombier 	"restart",
443d156f8aSDavid du Colombier 	"easy",
453d156f8aSDavid du Colombier 	"hard",
463d156f8aSDavid du Colombier 	"exit",
473d156f8aSDavid du Colombier 	0
483d156f8aSDavid du Colombier };
493d156f8aSDavid du Colombier 
503d156f8aSDavid du Colombier Menu menu =
513d156f8aSDavid du Colombier {
523d156f8aSDavid du Colombier 	buttons
533d156f8aSDavid du Colombier };
543d156f8aSDavid du Colombier 
553d156f8aSDavid du Colombier void
main(int argc,char * argv[])563d156f8aSDavid du Colombier main(int argc, char *argv[])
573d156f8aSDavid du Colombier {
583d156f8aSDavid du Colombier 	Mouse m;
593d156f8aSDavid du Colombier 	int i, j;
60312a1df1SDavid du Colombier 	ushort ran, score, attempt, prev, br[2];
61312a1df1SDavid du Colombier 	Image *c[2];
623d156f8aSDavid du Colombier 	char *fmt;
633d156f8aSDavid du Colombier 
643d156f8aSDavid du Colombier 	level = 16;
65312a1df1SDavid du Colombier 	fmt = "win in %d attempts!";
66312a1df1SDavid du Colombier 
673d156f8aSDavid du Colombier 	ARGBEGIN{
683d156f8aSDavid du Colombier 	default:
693d156f8aSDavid du Colombier 		goto Usage;
703d156f8aSDavid du Colombier 	case 'h':
713d156f8aSDavid du Colombier 		level=36;
723d156f8aSDavid du Colombier 		break;
733d156f8aSDavid du Colombier 	}ARGEND
74312a1df1SDavid du Colombier 
753d156f8aSDavid du Colombier 	if(argc){
763d156f8aSDavid du Colombier     Usage:
773d156f8aSDavid du Colombier 		fprint(2, "usage: %s [-h]\n", argv0);
783d156f8aSDavid du Colombier 		exits("usage");
793d156f8aSDavid du Colombier 	}
803d156f8aSDavid du Colombier 	if(initdraw(0,0,"memo") < 0)
813d156f8aSDavid du Colombier 		sysfatal("initdraw failed: %r");
823d156f8aSDavid du Colombier 	srand(time(0));
83312a1df1SDavid du Colombier 	memoinit();
843d156f8aSDavid du Colombier 	einit(Emouse);
853d156f8aSDavid du Colombier 
863d156f8aSDavid du Colombier     Start:
873d156f8aSDavid du Colombier 	afaces();
883d156f8aSDavid du Colombier 	winflag=0;
893d156f8aSDavid du Colombier 	prev=level+1;
903d156f8aSDavid du Colombier 	score=attempt=0;
91312a1df1SDavid du Colombier 	for(i=0;i!=level;i++)
92312a1df1SDavid du Colombier 		block[i].flag = Eninit;
93312a1df1SDavid du Colombier 
943d156f8aSDavid du Colombier 	for(i=0;i!=level/2;i++){
953d156f8aSDavid du Colombier 		for(j=0;j!=2;){
963d156f8aSDavid du Colombier 			ran = rand()%level;
97312a1df1SDavid du Colombier 			if(block[ran].flag == Eninit){
98312a1df1SDavid du Colombier 				block[ran].face = face[i];
99312a1df1SDavid du Colombier 				block[ran].flag = Eshow;
1003d156f8aSDavid du Colombier 				j++;
1013d156f8aSDavid du Colombier 			}
1023d156f8aSDavid du Colombier 		}
1033d156f8aSDavid du Colombier 	}
1043d156f8aSDavid du Colombier 	eresized(0);
105312a1df1SDavid du Colombier 	for(;;m=emouse())
1063d156f8aSDavid du Colombier 		if(m.buttons)
1073d156f8aSDavid du Colombier 			break;
108312a1df1SDavid du Colombier 
1093d156f8aSDavid du Colombier 	for(i=0;i!=level;i++)
110312a1df1SDavid du Colombier 		block[i].flag = Ehide;
111312a1df1SDavid du Colombier 
112312a1df1SDavid du Colombier 	redraw();
1133d156f8aSDavid du Colombier 	j = 0;
1143d156f8aSDavid du Colombier 	for(;; m=emouse()){
1153d156f8aSDavid du Colombier 		switch(m.buttons){
1163d156f8aSDavid du Colombier 		case 1:
1173d156f8aSDavid du Colombier 			while(m.buttons){
1183d156f8aSDavid du Colombier 				for(i=0;i!=level;i++){
119312a1df1SDavid du Colombier 					if(i!=prev && ptinrect(m.xy,block[i].r)){
120312a1df1SDavid du Colombier 						if(block[i].flag==Ehide  && j<2){
121312a1df1SDavid du Colombier 							block[i].flag = Eshow;
122312a1df1SDavid du Colombier 							draw(screen, block[i].r, block[i].face, nil, ZP);
123312a1df1SDavid du Colombier 							c[j] = block[i].face;
124312a1df1SDavid du Colombier 							br[j] = prev = i;
1253d156f8aSDavid du Colombier 							j++;
1263d156f8aSDavid du Colombier 						}
1273d156f8aSDavid du Colombier 						break;
1283d156f8aSDavid du Colombier 					}
1293d156f8aSDavid du Colombier 				}
1303d156f8aSDavid du Colombier 				m=emouse();
1313d156f8aSDavid du Colombier 			}
1323d156f8aSDavid du Colombier 			break;
1333d156f8aSDavid du Colombier 		case 4:
1343d156f8aSDavid du Colombier 			switch(emenuhit(3, &m, &menu)) {
1353d156f8aSDavid du Colombier 			case 0:	/* restart */
1363d156f8aSDavid du Colombier 				goto Start;
1373d156f8aSDavid du Colombier 				break;
1383d156f8aSDavid du Colombier 			case 1:
1393d156f8aSDavid du Colombier 				level=16;
1403d156f8aSDavid du Colombier 				goto Start;
1413d156f8aSDavid du Colombier 				break;
1423d156f8aSDavid du Colombier 			case 2:
1433d156f8aSDavid du Colombier 				level=36;
1443d156f8aSDavid du Colombier 				goto Start;
1453d156f8aSDavid du Colombier 				break;
1463d156f8aSDavid du Colombier 			case 3:
1473d156f8aSDavid du Colombier 				exits(0);
1483d156f8aSDavid du Colombier 				break;
1493d156f8aSDavid du Colombier 			}
1503d156f8aSDavid du Colombier 		}
1513d156f8aSDavid du Colombier 		if(j==2){
1523d156f8aSDavid du Colombier 			attempt++;
1533d156f8aSDavid du Colombier 			prev = level+1;
1543d156f8aSDavid du Colombier 			j = 0;
1553d156f8aSDavid du Colombier 			if(c[0] == c[1]){
1563d156f8aSDavid du Colombier 				score++;
157312a1df1SDavid du Colombier 				block[br[0]].flag = Edisc;
158312a1df1SDavid du Colombier 				block[br[1]].flag = Edisc;
1593d156f8aSDavid du Colombier 			} else{
160312a1df1SDavid du Colombier 				block[br[0]].flag = Ehide;
161312a1df1SDavid du Colombier 				block[br[1]].flag = Ehide;
1623d156f8aSDavid du Colombier 			}
163312a1df1SDavid du Colombier 			redraw();
164312a1df1SDavid du Colombier 			continue;
1653d156f8aSDavid du Colombier 		}
1663d156f8aSDavid du Colombier 		if(score == level/2){
1673d156f8aSDavid du Colombier 			winflag = 1;
1683d156f8aSDavid du Colombier 			sprint(buf, fmt, attempt);
169312a1df1SDavid du Colombier 			redraw();
170312a1df1SDavid du Colombier 			for(;;m=emouse())
171312a1df1SDavid du Colombier 				if(m.buttons&1 || m.buttons&4)
1723d156f8aSDavid du Colombier 					break;
1733d156f8aSDavid du Colombier 			goto Start;
1743d156f8aSDavid du Colombier 		}
1753d156f8aSDavid du Colombier 	}
1763d156f8aSDavid du Colombier }
1773d156f8aSDavid du Colombier 
1783d156f8aSDavid du Colombier void
memoinit(void)179312a1df1SDavid du Colombier memoinit(void)
180312a1df1SDavid du Colombier {
181312a1df1SDavid du Colombier 	back = allocimagemix(display, DPalebluegreen,DWhite);
182312a1df1SDavid du Colombier 	fore = allocimagemix(display, 0x00DDDDFF, 0x00DDDDFF);
183312a1df1SDavid du Colombier }
184312a1df1SDavid du Colombier 
185312a1df1SDavid du Colombier void
eresized(int new)1863d156f8aSDavid du Colombier eresized(int new)
1873d156f8aSDavid du Colombier {
188*3039af76SDavid du Colombier 	double sq;
189*3039af76SDavid du Colombier 	Point p;
190*3039af76SDavid du Colombier 
1913d156f8aSDavid du Colombier 	if(new && getwindow(display, Refnone) < 0){
1923d156f8aSDavid du Colombier 		fprint(2, "can't reattach to window");
1933d156f8aSDavid du Colombier 		exits("resized");
1943d156f8aSDavid du Colombier 	}
195*3039af76SDavid du Colombier 
196*3039af76SDavid du Colombier 	sq = sqrt(level);
197*3039af76SDavid du Colombier 	p = Pt(Dx(screen->r)+8, Dy(screen->r)+8);
198*3039af76SDavid du Colombier 	if(!new || !eqpt(p, Pt(Facesize*sq+sq*4+17, Facesize*sq+sq*4+17)))
199*3039af76SDavid du Colombier 		resize(Facesize*sq+sq*4+17);
200*3039af76SDavid du Colombier 
2013d156f8aSDavid du Colombier 	allocblocks();
202312a1df1SDavid du Colombier 	draw(screen, screen->r, back, nil, ZP);
203312a1df1SDavid du Colombier 	redraw();
204312a1df1SDavid du Colombier }
205312a1df1SDavid du Colombier 
206312a1df1SDavid du Colombier void
redraw(void)207312a1df1SDavid du Colombier redraw(void)
208312a1df1SDavid du Colombier {
209*3039af76SDavid du Colombier 	int i;
210312a1df1SDavid du Colombier 	Rectangle r;
211312a1df1SDavid du Colombier 	Point p;
212312a1df1SDavid du Colombier 
2133d156f8aSDavid du Colombier 	if(winflag == 1){
214312a1df1SDavid du Colombier 		p = Pt(Dx(screen->r)/8, Dy(screen->r)/4);
215312a1df1SDavid du Colombier 		r = screen->r;
216312a1df1SDavid du Colombier 		r.min = addpt(r.min, p);
217312a1df1SDavid du Colombier 		r.max = subpt(r.max, p);
218312a1df1SDavid du Colombier 		draw(screen, r, fore, nil, ZP);
219312a1df1SDavid du Colombier 		p=addpt(r.min, Pt(5,5));
2203d156f8aSDavid du Colombier 		string(screen,p,display->black,ZP,font,buf);
221312a1df1SDavid du Colombier 		return;
222312a1df1SDavid du Colombier 	}
223312a1df1SDavid du Colombier 
2243d156f8aSDavid du Colombier 	for(i=0;i!=level;i++){
225312a1df1SDavid du Colombier 		r = block[i].r;
2263d156f8aSDavid du Colombier 		switch(block[i].flag){
227312a1df1SDavid du Colombier 		case Eshow:
228312a1df1SDavid du Colombier 			draw(screen, r,block[i].face,nil,ZP);
2293d156f8aSDavid du Colombier 			break;
230312a1df1SDavid du Colombier 		case Edisc:
231312a1df1SDavid du Colombier 			draw(screen, r, back, nil, ZP);
2323d156f8aSDavid du Colombier 			break;
233312a1df1SDavid du Colombier 		case Ehide:
234312a1df1SDavid du Colombier 			draw(screen, r, fore, nil, ZP);
2353d156f8aSDavid du Colombier 			break;
2363d156f8aSDavid du Colombier 		default:
2373d156f8aSDavid du Colombier 			fprint(2, "something went wrong!");
2383d156f8aSDavid du Colombier 			exits("wrong");
2393d156f8aSDavid du Colombier 			break;
2403d156f8aSDavid du Colombier 		}
2413d156f8aSDavid du Colombier 	}
2423d156f8aSDavid du Colombier }
2433d156f8aSDavid du Colombier 
2443d156f8aSDavid du Colombier char *facepaths[] = {
2453d156f8aSDavid du Colombier 	/* logos */
2463d156f8aSDavid du Colombier 	"/lib/face/48x48x4/g/glenda.1",
2473d156f8aSDavid du Colombier 	"/lib/face/48x48x2/p/pjw+9ball.2",
2483d156f8aSDavid du Colombier 
2493d156f8aSDavid du Colombier 	/* /sys/doc/9.ms authors */
2503d156f8aSDavid du Colombier 	"/lib/face/48x48x2/k/ken.1",
2513d156f8aSDavid du Colombier 	"/lib/face/48x48x4/b/bobf.1",
2523d156f8aSDavid du Colombier 	"/lib/face/48x48x4/p/philw.1",
2533d156f8aSDavid du Colombier 	"/lib/face/48x48x4/p/presotto.1",
2543d156f8aSDavid du Colombier 	"/lib/face/48x48x4/r/rob.1",
2553d156f8aSDavid du Colombier 	"/lib/face/48x48x4/s/sean.1",
2563d156f8aSDavid du Colombier 
2573d156f8aSDavid du Colombier 	/* additional authors and luminaries for harder levels */
2583d156f8aSDavid du Colombier 	"/lib/face/48x48x4/b/bwk.1",
2593d156f8aSDavid du Colombier 	"/lib/face/48x48x4/c/cyoung.1",
2603d156f8aSDavid du Colombier 	"/lib/face/48x48x4/d/dmr.1",
2613d156f8aSDavid du Colombier 	"/lib/face/48x48x4/d/doug.1",
2623d156f8aSDavid du Colombier 	"/lib/face/48x48x4/h/howard.1",
2633d156f8aSDavid du Colombier 	"/lib/face/48x48x4/j/jmk.1",
2643d156f8aSDavid du Colombier 	"/lib/face/48x48x4/s/sape.1",
2653d156f8aSDavid du Colombier 	"/lib/face/48x48x4/s/seanq.1",
2663d156f8aSDavid du Colombier 	"/lib/face/48x48x4/t/td.1",
2673d156f8aSDavid du Colombier 	"/lib/face/48x48x8/l/lucent.1",
2683d156f8aSDavid du Colombier };
2693d156f8aSDavid du Colombier 
2703d156f8aSDavid du Colombier void
afaces(void)2713d156f8aSDavid du Colombier afaces(void)
2723d156f8aSDavid du Colombier {
2733d156f8aSDavid du Colombier 	int i;
2743d156f8aSDavid du Colombier 
2753d156f8aSDavid du Colombier 	for(i=0; i<18; i++)
2763d156f8aSDavid du Colombier 		face[i] = openface(facepaths[i]);
2773d156f8aSDavid du Colombier }
2783d156f8aSDavid du Colombier 
2793d156f8aSDavid du Colombier void
resize(int i)2803d156f8aSDavid du Colombier resize(int i)
2813d156f8aSDavid du Colombier {
2823d156f8aSDavid du Colombier 	int fd;
2833d156f8aSDavid du Colombier 
2843d156f8aSDavid du Colombier 	fd = open("/dev/wctl", OWRITE);
2853d156f8aSDavid du Colombier 	if(fd >= 0){
2863d156f8aSDavid du Colombier 		fprint(fd, "resize -dx %d -dy %d", i, i);
2873d156f8aSDavid du Colombier 		close(fd);
2883d156f8aSDavid du Colombier 	}
2893d156f8aSDavid du Colombier }
2903d156f8aSDavid du Colombier 
2913d156f8aSDavid du Colombier Image *
openimage(char * path)2923d156f8aSDavid du Colombier openimage(char *path)
2933d156f8aSDavid du Colombier {
2943d156f8aSDavid du Colombier 	Image *i;
2953d156f8aSDavid du Colombier 	int fd;
2963d156f8aSDavid du Colombier 
2973d156f8aSDavid du Colombier 	fd = open(path, OREAD);
2983d156f8aSDavid du Colombier 	if(fd < 0)
2993d156f8aSDavid du Colombier 		sysfatal("open %s: %r", path);
3003d156f8aSDavid du Colombier 	i = readimage(display, fd, 0);
3013d156f8aSDavid du Colombier 	if(i == nil)
3023d156f8aSDavid du Colombier 		sysfatal("readimage %s: %r", path);
3033d156f8aSDavid du Colombier 	close(fd);
3043d156f8aSDavid du Colombier 	return i;
3053d156f8aSDavid du Colombier }
3063d156f8aSDavid du Colombier 
307312a1df1SDavid du Colombier void
allocblocks(void)308312a1df1SDavid du Colombier allocblocks(void)
309312a1df1SDavid du Colombier {
310312a1df1SDavid du Colombier 	Rectangle r, b;
311312a1df1SDavid du Colombier 	ushort i, x, y, sq;
312312a1df1SDavid du Colombier 
313312a1df1SDavid du Colombier 	sq = sqrt(level);
314312a1df1SDavid du Colombier 	r = insetrect(screen->r, 5);
315312a1df1SDavid du Colombier 	r.max.x = r.min.x+Facesize*sq+sq*4-1;
316312a1df1SDavid du Colombier 	r.max.y = r.min.y+Facesize*sq+sq*4-1;
317312a1df1SDavid du Colombier 	b.max.y = r.min.y;
318312a1df1SDavid du Colombier 	for(i=level-1, y=0; y!=sq; y++){
319312a1df1SDavid du Colombier 		b.min.y = b.max.y;
320312a1df1SDavid du Colombier 		b.max.y = r.min.y+Dy(r)*(y+1)/sq;
321312a1df1SDavid du Colombier 		b.max.x = r.min.x;
322312a1df1SDavid du Colombier 		for(x=0; x!=sq; x++, i--){
323312a1df1SDavid du Colombier 			b.min.x = b.max.x;
324312a1df1SDavid du Colombier 			b.max.x = r.min.x+Dx(r)*(x+1)/sq;
325312a1df1SDavid du Colombier 			block[i].r = insetrect(b, 2 );
326312a1df1SDavid du Colombier 		}
327312a1df1SDavid du Colombier 	}
328312a1df1SDavid du Colombier }
3293d156f8aSDavid du Colombier 
3303d156f8aSDavid du Colombier Image*
readbit(int fd,ulong chan,char * path)3313d156f8aSDavid du Colombier readbit(int fd, ulong chan, char *path)
3323d156f8aSDavid du Colombier {
3333d156f8aSDavid du Colombier 	char buf[4096], hx[4], *p;
3343d156f8aSDavid du Colombier 	uchar data[Facesize*Facesize];	/* more than enough */
3353d156f8aSDavid du Colombier 	int nhx, i, n, ndata, nbit;
3363d156f8aSDavid du Colombier 	Image *img;
3373d156f8aSDavid du Colombier 
3383d156f8aSDavid du Colombier 	n = readn(fd, buf, sizeof buf);
3393d156f8aSDavid du Colombier 	if(n <= 0)
3403d156f8aSDavid du Colombier 		return nil;
3413d156f8aSDavid du Colombier 	if(n >= sizeof buf)
3423d156f8aSDavid du Colombier 		n = sizeof(buf)-1;
3433d156f8aSDavid du Colombier 	buf[n] = '\0';
3443d156f8aSDavid du Colombier 
3453d156f8aSDavid du Colombier 	n = 0;
3463d156f8aSDavid du Colombier 	nhx = 0;
3473d156f8aSDavid du Colombier 	nbit = chantodepth(chan);
3483d156f8aSDavid du Colombier 	ndata = (Facesize*Facesize*nbit)/8;
3493d156f8aSDavid du Colombier 	p = buf;
3503d156f8aSDavid du Colombier 	while(n < ndata) {
3513d156f8aSDavid du Colombier 		p = strpbrk(p+1, "0123456789abcdefABCDEF");
3523d156f8aSDavid du Colombier 		if(p == nil)
3533d156f8aSDavid du Colombier 			break;
3543d156f8aSDavid du Colombier 		if(p[0] == '0' && p[1] == 'x')
3553d156f8aSDavid du Colombier 			continue;
3563d156f8aSDavid du Colombier 
3573d156f8aSDavid du Colombier 		hx[nhx] = *p;
3583d156f8aSDavid du Colombier 		if(++nhx == 2) {
3593d156f8aSDavid du Colombier 			hx[nhx] = 0;
3603d156f8aSDavid du Colombier 			i = strtoul(hx, 0, 16);
3613d156f8aSDavid du Colombier 			data[n++] = ~i;
3623d156f8aSDavid du Colombier 			nhx = 0;
3633d156f8aSDavid du Colombier 		}
3643d156f8aSDavid du Colombier 	}
3653d156f8aSDavid du Colombier 	if(n < ndata)
3663d156f8aSDavid du Colombier 		sysfatal("short face %s", path);
3673d156f8aSDavid du Colombier 
3683d156f8aSDavid du Colombier 	img = allocimage(display, Rect(0,0,Facesize,Facesize), chan, 0, 0);
3693d156f8aSDavid du Colombier 	if(img == nil)
3703d156f8aSDavid du Colombier 		return nil;
371312a1df1SDavid du Colombier 
3723d156f8aSDavid du Colombier 	loadimage(img, img->r, data, ndata);
3733d156f8aSDavid du Colombier 	return img;
3743d156f8aSDavid du Colombier }
3753d156f8aSDavid du Colombier 
3763d156f8aSDavid du Colombier Image*
openface(char * path)3773d156f8aSDavid du Colombier openface(char *path)
3783d156f8aSDavid du Colombier {
3793d156f8aSDavid du Colombier 	char *p;
3803d156f8aSDavid du Colombier 	int fd, n;
3813d156f8aSDavid du Colombier 
3823d156f8aSDavid du Colombier 	p = strstr(path, "48x48x");
3833d156f8aSDavid du Colombier 	if(p == nil)
3843d156f8aSDavid du Colombier 		return openimage(path);
3853d156f8aSDavid du Colombier 	n = atoi(p+6);
3863d156f8aSDavid du Colombier 	if(n < 4){
3873d156f8aSDavid du Colombier 		if((fd = open(path, OREAD)) < 0)
3883d156f8aSDavid du Colombier 			sysfatal("open %s: %r", path);
3893d156f8aSDavid du Colombier 		return readbit(fd, n==1 ? GREY1 : GREY2, path);
3903d156f8aSDavid du Colombier 	}
3913d156f8aSDavid du Colombier 	return openimage(path);
3923d156f8aSDavid du Colombier }
393