/* * Piece editor for plumb */ #include #include #include #include #define SIZE 48 #define MAG 10 #define BORDER 4 #define NVAL 4 struct{ char *name; Bitmap *bitmap; }piece[]={ " 0 N/E", 0, " 1 N/S", 0, " 2 N/W", 0, " 3 E/S", 0, " 4 E/W", 0, " 5 S/W", 0, " 6 N/S+E/W", 0, " 7 N/E one way", 0, " 8 N/S one way", 0, " 9 N/W one way", 0, "10 E/N one way", 0, "11 E/S one way", 0, "12 E/W one way", 0, "13 S/N one way", 0, "14 S/E one way", 0, "15 S/W one way", 0, "16 W/N one way", 0, "17 W/E one way", 0, "18 W/S one way", 0, "19 start N", 0, "20 start E", 0, "21 start S", 0, "22 start W", 0, "23 finish N", 0, "24 finish E", 0, "25 finish S", 0, "26 finish W", 0, "27 N/S reservoir", 0, "28 E/W reservoir", 0, "29 N/S bonus", 0, "30 E/W bonus", 0, "31 obstacle", 0, "32 empty", 0, }; #define NPIECE (sizeof piece/sizeof piece[0]) Bitmap *flat[NVAL]; char pix[SIZE][SIZE]; char curval=3; enum{ Paint, Fill, Relief}mode=Paint; Rectangle bigr, smallr; rectf(Bitmap *b, Rectangle r, Fcode f){ bitblt(b, r.min, b, r, f); } myborder(Bitmap *b, Rectangle r, int n, Fcode f){ if(n<0) border(b, inset(r, n), -n, f); else border(b, r, n, f); } show(Point p){ int v=pix[p.y][p.x]; bitblt(&screen, add(bigr.min, mul(p, MAG)), flat[v], flat[v]->r, S); point(&screen, add(smallr.min, p), v, S); } char pattern[16][16]={ 3,0,0,0,3,0,0,0,3,0,0,0,3,0,0,0, 0,3,0,0,0,0,0,0,0,3,0,0,0,0,0,0, 0,0,3,0,0,0,0,0,0,0,3,0,0,0,0,0, 0,0,0,3,0,0,0,0,0,0,0,3,0,0,0,0, 3,0,0,0,3,0,0,0,3,0,0,0,3,0,0,0, 0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,3, 0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,0, 0,0,0,0,0,3,0,0,0,0,0,0,0,3,0,0, 3,0,0,0,3,0,0,0,3,0,0,0,3,0,0,0, 0,3,0,0,0,0,0,0,0,3,0,0,0,0,0,0, 0,0,3,0,0,0,0,0,0,0,3,0,0,0,0,0, 0,0,0,3,0,0,0,0,0,0,0,3,0,0,0,0, 3,0,0,0,3,0,0,0,3,0,0,0,3,0,0,0, 0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,3, 0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,0, 0,0,0,0,0,3,0,0,0,0,0,0,0,3,0,0, }; set(Point p, char v){ if(v==4) v=pattern[p.y%16][p.x%16]; if(pix[p.y][p.x]!=v){ pix[p.y][p.x]=v; show(p); } } char region[SIZE][SIZE]; getregion1(Point p, char v){ if(pix[p.y][p.x]!=v || region[p.y][p.x]) return; region[p.y][p.x]=1; if(p.x!=SIZE-1) getregion1(Pt(p.x+1, p.y), v); if(p.x!=0) getregion1(Pt(p.x-1, p.y), v); if(p.y!=SIZE-1) getregion1(Pt(p.x, p.y+1), v); if(p.y!=0) getregion1(Pt(p.x, p.y-1), v); } getregion(Point p){ int x, y; for(y=0;y!=SIZE;y++) for(x=0;x!=SIZE;x++) region[y][x]=0; getregion1(p, pix[p.y][p.x]); } fill(Point p, char v){ int x, y; getregion(p); for(y=0;y!=SIZE;y++) for(x=0;x!=SIZE;x++) if(region[y][x]) set(Pt(x, y), v); } inregion(int x, int y){ return 0<=x && x>(6-x%4*2))&3); } save(Bitmap *b){ bitblt(b, b->r.min, &screen, smallr, S); } input(char *name){ int i; Bitmap *b; int fd=open(name, OREAD); if(fd<0){ Bad: fprintf(stderr, "Bad input %s\n", name); exits("bad input"); } for(i=0;i!=NPIECE;i++){ b=rdbitmapfile(fd); if(!b || !eqrect(b->r, Rect(0, 0, SIZE, SIZE)) || b->ldepth!=1) goto Bad; piece[i].bitmap=b; } close(fd); } output(char *name){ int i; Bitmap *b; int fd=create(name, OWRITE, 0666); if(fd<0){ fprintf(stderr, "Can't create %s\n", name); exits("bad output"); } for(i=0;i!=NPIECE;i++) wrbitmapfile(fd, piece[i].bitmap); close(fd); } main(int argc, char *argv[]){ Mouse m; int i=0; if(argc!=3){ fprintf(stderr, "Usage: %s input output\n", argv[0]); exit(1); } binit((void (*)(char *))0, (char *)0); einit(); initflats(); ereshaped(screen.r); input(argv[1]); see(piece[i].bitmap); for(;;){ m=emouse(); switch(m.buttons){ case 1: if(ptinrect(m.xy, bigr)){ switch(mode){ case Fill: fill(div(sub(m.xy, bigr.min), MAG), curval); do m=emouse(); while(m.buttons); break; case Paint: set(div(sub(m.xy, bigr.min), MAG), curval); break; case Relief: relief(div(sub(m.xy, bigr.min), MAG)); do m=emouse(); while(m.buttons); break; } } break; case 2: switch(menuhit(2, &m, &menu2)){ case 0: curval=0; break; case 1: curval=1; break; case 2: curval=2; break; case 3: curval=3; break; case 4: curval=4; break; case 5: mode=Paint; break; case 6: mode=Fill; break; case 7: mode=Relief; break; } break; case 4: switch(menuhit(3, &m, &menu3)){ case 0: if(i0){ save(piece[i].bitmap); see(piece[--i].bitmap); } break; case 2: save(piece[i].bitmap); output(argv[2]); break; case 3: save(piece[i].bitmap); output(argv[2]); exits(""); } break; } } }