/* * 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; void rectf(Bitmap *b, Rectangle r, Fcode f){ bitblt(b, r.min, b, r, f); } void 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); } void show(Point p){ int v=pix[p.y][p.x]; bitblt(&screen, add(bigr.min, mul(p, MAG)), flat[v], flat[v]->r, S); bitblt(&screen, add(smallr.min, p), flat[v], Rect(1,1,2,2), 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, }; void 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]; void 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); } void 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]); } void 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); } int inregion(int x, int y){ return 0<=x && x>(6-x%4*2))&3); } void save(Bitmap *b){ bitblt(b, b->r.min, &screen, smallr, S); } void 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); } void output(char *name){ int i; 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); } void main(int argc, char *argv[]){ Mouse m; int i=0; if(argc!=3){ fprintf(stderr, "Usage: %s input output\n", argv[0]); exits("usage"); } binit(0, 0, 0); einit(Emouse|Ekeyboard); 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(0); } break; } } }