some bug fixes, code cleanup. fgb Reference: /n/sources/patch/applied/memo-fixes Date: Wed Aug 31 02:42:08 CES 2005 --- /sys/src/games/memo.c Wed Aug 31 02:41:16 2005 +++ /sys/src/games/memo.c Wed Aug 31 02:41:11 2005 @@ -4,6 +4,8 @@ #include #include +void memoinit(void); +void redraw(void); void eresized(int); void resize(int i); void afaces(void); @@ -11,22 +13,25 @@ Image *openface(char *path); Image *face[18]; -Rectangle brect[36]; char buf[100]; ushort winflag, level; +Image *back; +Image *fore; -typedef enum{ - ninit, - hide, - disc -}bflag; - -struct Block -{ - ushort nr; - ushort nc; - bflag flag; -} block[36]; +enum +{ + Eninit, + Eshow, + Ehide, + Edisc, +}; + +struct +{ + Image *face; + Rectangle r; + int flag; +}block[36]; char *buttons[] = { @@ -47,11 +52,13 @@ { Mouse m; int i, j; - ushort ran, score, attempt, prev, br[2], c[2]; + ushort ran, score, attempt, prev, br[2]; + Image *c[2]; char *fmt; - level=16; - fmt = "you win in %d attempts!"; + level = 16; + fmt = "win in %d attempts!"; + ARGBEGIN{ default: goto Usage; @@ -59,14 +66,16 @@ level=36; break; }ARGEND + if(argc){ - Usage: + Usage: fprint(2, "usage: %s [-h]\n", argv0); exits("usage"); } if(initdraw(0,0,"memo") < 0) sysfatal("initdraw failed: %r"); srand(time(0)); + memoinit(); einit(Emouse); Start: @@ -74,46 +83,41 @@ winflag=0; prev=level+1; score=attempt=0; - for(i=0;i!=level;i++){ - block[i].nr=i; - block[i].nc=20; - block[i].flag=ninit; - } + for(i=0;i!=level;i++) + block[i].flag = Eninit; + for(i=0;i!=level/2;i++){ for(j=0;j!=2;){ - ran=rand()%level; - if(block[ran].nc==20){ - block[ran].nc=i; + ran = rand()%level; + if(block[ran].flag == Eninit){ + block[ran].face = face[i]; + block[ran].flag = Eshow; j++; } } } eresized(0); - for(;;){ - m=emouse(); + for(;;m=emouse()) if(m.buttons) break; - } + for(i=0;i!=level;i++) - block[i].flag=hide; - eresized(0); - j=0; + block[i].flag = Ehide; + + redraw(); + j = 0; for(;; m=emouse()){ switch(m.buttons){ case 1: while(m.buttons){ for(i=0;i!=level;i++){ - if(i!=prev && ptinrect(m.xy,brect[i])){ - if(block[i].flag == hide && j<2){ - draw( screen, - brect[i], - face[block[i].nc], - nil, - ZP); - c[j]=block[i].nc; - br[j]=i; + if(i!=prev && ptinrect(m.xy,block[i].r)){ + if(block[i].flag==Ehide && j<2){ + block[i].flag = Eshow; + draw(screen, block[i].r, block[i].face, nil, ZP); + c[j] = block[i].face; + br[j] = prev = i; j++; - prev=i; } break; } @@ -123,120 +127,102 @@ break; case 4: switch(emenuhit(3, &m, &menu)) { - case 0: /* restart */ - goto Start; - break; - case 1: - level=16; - goto Start; - break; - case 2: - level=36; - goto Start; - break; - case 3: - exits(0); - break; + case 0: /* restart */ + goto Start; + break; + case 1: + level=16; + goto Start; + break; + case 2: + level=36; + goto Start; + break; + case 3: + exits(0); + break; } } if(j==2){ attempt++; - prev=level+1; - j=0; - if(c[0]==c[1]){ + prev = level+1; + j = 0; + if(c[0] == c[1]){ score++; - block[br[0]].flag=disc; - block[br[1]].flag=disc; - draw( screen, - brect[br[0]], - allocimagemix(display,DPalebluegreen,DWhite), - nil, - ZP); - draw( screen, - brect[br[1]], - allocimagemix(display,DPalebluegreen,DWhite), - nil, - ZP); - }else{ - draw( screen, - brect[br[0]], - allocimagemix(display, 0x00DDDDFF, 0x00DDDDFF), - nil, - ZP); - draw( screen, - brect[br[1]], - allocimagemix(display, 0x00DDDDFF, 0x00DDDDFF), - nil, - ZP); + block[br[0]].flag = Edisc; + block[br[1]].flag = Edisc; + } else{ + block[br[0]].flag = Ehide; + block[br[1]].flag = Ehide; } + redraw(); + continue; } - if(score==level/2){ - winflag=1; + if(score == level/2){ + winflag = 1; sprint(buf, fmt, attempt); - eresized(0); - for(;;){ - m=emouse(); - if((m.buttons & 1) || (m.buttons & 4)) - break; - } + redraw(); + for(;;m=emouse()) + if(m.buttons&1 || m.buttons&4) + break; goto Start; } } } void -eresized(int new) +memoinit(void) { - ushort i, nx, ny; - Point p; - Rectangle wr; + back = allocimagemix(display, DPalebluegreen,DWhite); + fore = allocimagemix(display, 0x00DDDDFF, 0x00DDDDFF); +} +void +eresized(int new) +{ if(new && getwindow(display, Refnone) < 0){ fprint(2, "can't reattach to window"); exits("resized"); } - allocblocks(); - draw(screen, screen->r, allocimagemix(display, DPalebluegreen,DWhite), nil, ZP); + draw(screen, screen->r, back, nil, ZP); + redraw(); +} + +void +redraw(void) +{ + int i, nx, ny; + Rectangle r; + Point p; + if(winflag == 1){ - nx=screen->r.max.x/8; - ny=screen->r.max.y/4; - wr=Rect(screen->r.min.x+nx, - screen->r.min.y+ny, - screen->r.max.x-nx, - screen->r.max.y-ny); - draw(screen, wr, allocimagemix(display, 0x00DDDDFF, 0x00DDDDFF), nil, ZP); - p=addpt(wr.min, Pt(5,5)); - draw(screen, - Rpt(p, addpt(p, stringsize(font,buf))), - allocimagemix(display,0x00DDDDFF,0x00DDDDFFF), - nil,p); + p = Pt(Dx(screen->r)/8, Dy(screen->r)/4); + r = screen->r; + r.min = addpt(r.min, p); + r.max = subpt(r.max, p); + draw(screen, r, fore, nil, ZP); + p=addpt(r.min, Pt(5,5)); string(screen,p,display->black,ZP,font,buf); - }else{ - for(i=0;i!=level;i++){ - switch(block[i].flag){ - case ninit: - draw(screen,brect[i],face[block[i].nc],nil,ZP); - break; - case disc: - draw( screen, - brect[i], - allocimagemix(display,DPalebluegreen,DWhite), - nil, - ZP); - break; - case hide: - draw( screen, - brect[i], - allocimagemix(display, 0x00DDDDFF, 0x00DDDDFF), - nil, - ZP); - break; - default: - fprint(2, "something went wrong!"); - exits("wrong"); - break; - } + return; + } + + for(i=0;i!=level;i++){ + r = block[i].r; + switch(block[i].flag){ + case Eshow: + draw(screen, r,block[i].face,nil,ZP); + break; + case Edisc: + draw(screen, r, back, nil, ZP); + break; + case Ehide: + draw(screen, r, fore, nil, ZP); + break; + default: + fprint(2, "something went wrong!"); + exits("wrong"); + break; } } } @@ -245,7 +231,7 @@ /* logos */ "/lib/face/48x48x4/g/glenda.1", "/lib/face/48x48x2/p/pjw+9ball.2", - + /* /sys/doc/9.ms authors */ "/lib/face/48x48x2/k/ken.1", "/lib/face/48x48x4/b/bobf.1", @@ -253,7 +239,7 @@ "/lib/face/48x48x4/p/presotto.1", "/lib/face/48x48x4/r/rob.1", "/lib/face/48x48x4/s/sean.1", - + /* additional authors and luminaries for harder levels */ "/lib/face/48x48x4/b/bwk.1", "/lib/face/48x48x4/c/cyoung.1", @@ -271,40 +257,17 @@ afaces(void) { int i; - + for(i=0; i<18; i++) face[i] = openface(facepaths[i]); } void -allocblocks(void) -{ - Rectangle r, b; - ushort i, x, y, sq; - - sq=sqrt(level); - resize(48*sq+sq*4+17); - r=insetrect(screen->r, 5); - r=Rect(r.min.x, r.min.y, r.min.x+48*sq+sq*4-1, r.min.y+48*sq+sq*4-1); - b.max.y=r.min.y; - for(i=level-1, y=0; y!=sq; y++){ - b.min.y=b.max.y; - b.max.y=r.min.y+(r.max.y-r.min.y)*(y+1)/sq; - b.max.x=r.min.x; - for(x=0; x!=sq; x++, i--){ - b.min.x=b.max.x; - b.max.x=r.min.x+(r.max.x-r.min.x)*(x+1)/sq; - brect[i]=insetrect(b, 2 ); - } - } -} - -void resize(int i) { int fd; - fd=open("/dev/wctl", OWRITE); + fd = open("/dev/wctl", OWRITE); if(fd >= 0){ fprint(fd, "resize -dx %d -dy %d", i, i); close(fd); @@ -317,17 +280,42 @@ Image *i; int fd; - fd=open(path, OREAD); + fd = open(path, OREAD); if(fd < 0) sysfatal("open %s: %r", path); - i=readimage(display, fd, 0); + i = readimage(display, fd, 0); if(i == nil) sysfatal("readimage %s: %r", path); close(fd); return i; } -enum { Facesize = 48 }; +enum { + Facesize = 48 }; + +void +allocblocks(void) +{ + Rectangle r, b; + ushort i, x, y, sq; + + sq = sqrt(level); + resize(Facesize*sq+sq*4+17); + r = insetrect(screen->r, 5); + r.max.x = r.min.x+Facesize*sq+sq*4-1; + r.max.y = r.min.y+Facesize*sq+sq*4-1; + b.max.y = r.min.y; + for(i=level-1, y=0; y!=sq; y++){ + b.min.y = b.max.y; + b.max.y = r.min.y+Dy(r)*(y+1)/sq; + b.max.x = r.min.x; + for(x=0; x!=sq; x++, i--){ + b.min.x = b.max.x; + b.max.x = r.min.x+Dx(r)*(x+1)/sq; + block[i].r = insetrect(b, 2 ); + } + } +} Image* readbit(int fd, ulong chan, char *path) @@ -370,6 +358,7 @@ img = allocimage(display, Rect(0,0,Facesize,Facesize), chan, 0, 0); if(img == nil) return nil; + loadimage(img, img->r, data, ndata); return img; } @@ -379,7 +368,7 @@ { char *p; int fd, n; - + p = strstr(path, "48x48x"); if(p == nil) return openimage(path); @@ -391,4 +380,3 @@ } return openimage(path); } -