#include #include #include #include #include #include #include #include #include #include "Xbit.h" #define WINX 270 #define WINY 25 #define WINW 700 #define WINH 800 #define RND(x) (rand()%(x)) #define RAD(x) (M_PI/180.0*(double)(x)) #define ABS(x) ((x)<0 ? (-(x)) : (x)) #define SGN(x) ((x) ? ((x)/ABS(x)) : (0)) XSizeHints size_hints; int black,white; Display *disp; Window window; Colormap cm; XFontStruct *font; #define CMAP_R 4 #define CMAP_N (256/CMAP_R) #define CMAP_X 0 #define CMAP_Y 760 #define CMAP_W (640/CMAP_N) #define CMAP_H 10 #define MAX_SPR_W 48 #define MAX_SPR_H 48 #define GRID_X 0 #define GRID_Y 100 #define SETGW(w,h) (12+((w-h)/3)) #define SPR_X 640 #define SPR_Y 100 #define STR_Y 80 #define PLOT 0 #define FILL 1 #define LINE 2 #define RECT 3 #define BOX 4 #define CIRCLE 5 #define OVAL 6 #define ENDMODE 7 #define PLOT_TXT "Plot" #define FILL_TXT "Fill" #define LINE_TXT "Line" #define RECT_TXT "Rect" #define BOX_TXT "Box" #define CIRCLE_TXT "Circle" #define OVAL_TXT "Oval" #define ENDMODE_TXT "Bug?" #define W_MAX 1 #define W_MIN 40 #define R_MAX 41 #define R_MIN 80 #define B_MAX 81 #define B_MIN 120 #define G_MAX 121 #define G_MIN 160 #define RG_MAX 161 #define RG_MIN 180 #define RB_MAX 181 #define RB_MIN 200 #define BG_MAX 201 #define BG_MIN 220 #define RND_MAX 221 #define RND_MIN 255 typedef struct { int x,y,w,h; char *text; int (*redraw)(); int (*callback)(); } Button; int RdCmapBut(),CmapBut(); int RdSprSaveBut(),SprSaveBut(); int RdSprLoadBut(),SprLoadBut(); int RdSetCol(),SetCol(); int RdSpreadBut(),SpreadBut(); int RdLoadCmapBut(),LoadCmapBut(); int RdDrawMode(),DrawMode(); int RdClearToBut(),ClearToBut(); int RdClearBut(),ClearBut(); int RdSetSprBut(),SetSprBut(); int RdQuitBut(),QuitBut(); #define NO_BUT 11 Button butlist[NO_BUT]= { {1,10,90,20, "Save Cmap", RdCmapBut, CmapBut}, {101,10,90,20, "Save Sprite", RdSprSaveBut, SprSaveBut}, {201,10,90,20, "Load Sprite", RdSprLoadBut, SprLoadBut}, {301,10,90,20, "Set Color", RdSetCol, SetCol}, {401,10,90,20, "Spread", RdSpreadBut, SpreadBut}, {1,35,90,20, "Load Cmap", RdLoadCmapBut, LoadCmapBut}, {101,35,90,20, "DrawMode", RdDrawMode, DrawMode}, {201,35,90,20, "Clear To", RdClearToBut, ClearToBut}, {301,35,90,20, "Clear", RdClearBut, ClearBut}, {401,35,90,20, "Set Size", RdSetSprBut, SetSprBut}, {501,10,90,20, "Quit", RdQuitBut, QuitBut} }; #define MAXSTRLEN 64 int quit=False; int selcol; int range=False; int width=1; int drawmode=PLOT; int last_x=-1,last_y=-1; XColor xc[256]; int namelen=0; char name[MAXSTRLEN]; int SPR_W=MAX_SPR_W; int SPR_H=MAX_SPR_H; int GRID_W=SETGW(MAX_SPR_W,MAX_SPR_H); unsigned char sprite[MAX_SPR_W][MAX_SPR_H]; int main(argc,argv) int argc; char *argv[]; { XEvent event; unsigned long evmask; XFuncControl Process(); int f; size_hints.flags=PPosition|PSize|PMinSize|PMaxSize; size_hints.x=WINX; size_hints.y=WINY; size_hints.width=size_hints.min_width=WINW; size_hints.height=size_hints.min_height=WINH; size_hints.max_width=WINW; size_hints.max_height=WINH; evmask=ExposureMask|ButtonPressMask|StructureNotifyMask|KeyPressMask; window=OpenWin(argc,argv,argv[0], WINX,WINY,WINW,WINH,0,0, evmask, &size_hints,&black,&white); DisableDoubleBuffer(); disp=GetDisplay(); cm=XCreateColormap(disp,window,DefaultVisual(disp,0),AllocAll); XSetWindowColormap(disp,window,cm); font=XUseFont("fixed"); SetCmFade(W_MAX,W_MIN,xc,DoRed|DoBlue|DoGreen); SetCmFade(R_MAX,R_MIN,xc,DoRed); SetCmFade(B_MAX,B_MIN,xc,DoBlue); SetCmFade(G_MAX,G_MIN,xc,DoGreen); SetCmFade(RG_MAX,RG_MIN,xc,DoRed|DoGreen); SetCmFade(RB_MAX,RB_MIN,xc,DoRed|DoBlue); SetCmFade(BG_MAX,BG_MIN,xc,DoBlue|DoGreen); for(f=RND_MAX;f<=RND_MIN;f++) { xc[f].pixel=f; xc[f].flags=DoRed|DoBlue|DoGreen; xc[f].red=RND(0xff)*0xff; xc[f].green=RND(0xff)*0xff; xc[f].blue=RND(0xff)*0xff; } black=1; white=0; selcol=white; xc[black].pixel=black; xc[black].flags=DoRed|DoBlue|DoGreen; xc[black].red=xc[black].blue=xc[black].green=0; xc[white].pixel=white; xc[white].flags=DoRed|DoBlue|DoGreen; xc[white].red=xc[white].blue=xc[white].green=0xffff; XStoreColors(disp,cm,xc,256); MainLoop(argc,argv); } SetCmFade(c1,c2,xc,fl) int c1,c2; XColor xc[]; int fl; { int f,n,r; n=(c2-c1)+1; n=0xff/n; for(f=c1,r=0xff;f<=c2;f++,r-=n) { xc[f].pixel=f; xc[f].flags=DoRed|DoBlue|DoGreen; if (fl&DoRed) xc[f].red=r*0xff; else xc[f].red=0; if (fl&DoGreen) xc[f].green=r*0xff; else xc[f].green=0; if (fl&DoBlue) xc[f].blue=r*0xff; else xc[f].blue=0; } } /* Main Loop */ MainLoop(argc,argv) int argc; char *argv[]; { XEvent e; KeySym ks; char keybuf[10]; int f,x,y; name[0]=NULL; for(x=0;x1) { strcpy(name,argv[1]); namelen=strlen(name); } RedrawButs(); RedrawCmap(); RedrawSel(); RedrawStr(); RedrawSpr(); Redraw(0,0); while(!quit) { if(XPending(disp)) { XNextEvent(disp,&e); switch(e.type) { case KeyPress: XLookupString(&e,keybuf,10,&ks,NULL); switch(ks) { case XK_Delete: case XK_BackSpace: if (namelen) { name[--namelen]=NULL; RedrawStr(); Redraw(0,0); } break; default: switch(keybuf[0]) { case '': name[namelen=0]=NULL; RedrawStr(); Redraw(0,0); break; case '\n': case '\r': case '\t': break; default: if (namelenmax_bounds.ascent,WINW,font->max_bounds.ascent+2,black); Xprintf(0,CMAP_Y-5,white,"Colour selected : %4d",selcol); XBox(CMAP_X+(selcol%CMAP_N)*CMAP_W,CMAP_Y+(selcol/CMAP_N)*CMAP_H, CMAP_W,CMAP_H,white); } RedrawStr() { char s[MAXSTRLEN+1]; int f; for(f=0;fmax_bounds.ascent,WINW,font->max_bounds.ascent+2,black); Xprintf(0,STR_Y,white,"Name : %s",s); } RedrawSpr() { int x,y,f,r; for(f=0,x=GRID_X;f<=SPR_W;f++,x+=GRID_W) XLine(x,GRID_Y,x,GRID_Y+GRID_W*SPR_H,white); for(r=0,y=GRID_Y;r<=SPR_H;r++,y+=GRID_W) XLine(GRID_X,y,GRID_X+GRID_W*SPR_W,y,white); for(x=0;x=SPR_W)||(y<0)||(y>=SPR_H)) return; if(b==2) { selcol=sprite[x][y]; RedrawCmap(); RedrawSel(); } else switch(drawmode) { case PLOT: SprSet(x,y,c); break; case FILL: if (sprite[x][y]!=c) SprFill(x,y,c,sprite[x][y]); break; case LINE: if (last_x==-1) { last_x=x; last_y=y; SprPlot(x,y,sprite[x][y]^255); } else { SprLine(x,y,last_x,last_y,selcol); last_x=-1; last_y=-1; } break; case RECT: if (last_x==-1) { last_x=x; last_y=y; SprPlot(x,y,sprite[x][y]^255); } else { if (x>last_x) { dx=last_x; last_x=x; x=dx; } if (y>last_y) { dy=last_y; last_y=y; y=dy; } for(dx=x;dx<=last_x;dx++) { SprSet(dx,y,selcol); SprSet(dx,last_y,selcol); } for(dy=y;dy<=last_y;dy++) { SprSet(x,dy,selcol); SprSet(last_x,dy,selcol); } last_x=-1; last_y=-1; } break; case BOX: if (last_x==-1) { last_x=x; last_y=y; SprPlot(x,y,sprite[x][y]^255); } else { if (x>last_x) { dx=last_x; last_x=x; x=dx; } if (y>last_y) { dy=last_y; last_y=y; y=dy; } for(dx=x;dx<=last_x;dx++) for(dy=y;dy<=last_y;dy++) SprSet(dx,dy,selcol); last_x=-1; last_y=-1; } break; case CIRCLE: if (last_x==-1) { last_x=x; last_y=y; SprPlot(x,y,sprite[x][y]^255); } else { if (ABS(last_x-x)dx) { ymode=True; d=dx*2-dy; incrE=dx*2; incrNE=(dx-dy)*2; } else { ymode=False; d=dy*2-dx; incrE=dy*2; incrNE=(dy-dx)*2; } x=p1x; y=p1y; SprSet(x,y,c); if (ymode) while(y!=p2y) { if (d<=0) { d+=incrE; y+=iy; } else { d+=incrNE; y+=iy; x+=ix; } SprSet(x,y,c); } else while(x!=p2x) { if (d<=0) { d+=incrE; x+=ix; } else { d+=incrNE; y+=iy; x+=ix; } SprSet(x,y,c); } } SprSet(x,y,c) int x,y,c; { if ((x<0)||(x>=SPR_W)||(y<0)||(y>=SPR_H)) return; sprite[x][y]=c; SprPlot(x,y,c); } SprPlot(x,y,c) int x,y,c; { XPlot(SPR_X+x,SPR_Y+y,c); x=GRID_X+(x*GRID_W)+1; y=GRID_Y+(y*GRID_W)+1; XFillBox(x,y,GRID_W-1,GRID_W-1,c); } SprFill(x,y,c,bc) int x,y,c,bc; { if ((x<0)||(x>=SPR_W)||(y<0)||(y>=SPR_H)||(sprite[x][y]==c)|| (sprite[x][y]!=bc)) return; SprSet(x,y,c); SprFill(x-1,y,c,bc); SprFill(x+1,y,c,bc); SprFill(x,y-1,c,bc); SprFill(x,y+1,c,bc); } ColPress(x,y,c) int x,y,*c; { int lc; x-=CMAP_X; x/=CMAP_W; y-=CMAP_Y; y/=CMAP_H; lc=y*CMAP_N+x; if ((lc<0)||(lc>255)) return(False); else { *c=lc; return(True); } } RangeCols(a,b) int a,b; { int f,n,rc,gc,bc; if (a>b) { f=a; a=b; b=f; } n=(b-a); rc=((int)xc[b].red-(int)xc[a].red)/n; gc=((int)xc[b].green-(int)xc[a].green)/n; bc=((int)xc[b].blue-(int)xc[a].blue)/n; for(f=1;f=bx)&&(x<=bx+bw)&&(y>=by)&&(y<=by+bh)) return(True); else return(False); } ButtonPoll(b,n,x,y) Button b[]; int n; int x,y; { int f; for(f=0;fx,b->y,b->w,b->h,black); XBox(b->x,b->y,b->w,b->h,white); Xprintf( (b->x)+(b->w/2)-(strlen(b->text))*(font->max_bounds.width/2), (b->y)+(b->h/2)+(font->max_bounds.descent/2), white,"%s",b->text); } ButtonRedraw(b) Button *b; { XBox(b->x,b->y,b->w,b->h,white); if (b->redraw) (*b->redraw)(b); } /* Button Callbacks and redraws */ int RdCmapBut(b) Button *b; { ButtonText(b); } int CmapBut() { unsigned short us; int fd,f; if ((fd=open(name,O_WRONLY|O_CREAT|O_TRUNC,0666))==-1) { fprintf(stderr,"Couldn't save colormap to %s!\n",name); return; } for(f=0;f<256;f++) { us=htons(xc[f].red); write(fd,&us,sizeof(unsigned short)); us=htons(xc[f].green); write(fd,&us,sizeof(unsigned short)); us=htons(xc[f].blue); write(fd,&us,sizeof(unsigned short)); } close(fd); } int RdLoadCmapBut(b) Button *b; { ButtonText(b); } int LoadCmapBut() { unsigned short us; int fd,f; if ((fd=open(name,O_RDONLY))==-1) { fprintf(stderr,"Couldn't read colormap from %s!\n",name); return; } for(f=0;f<256;f++) { read(fd,&us,sizeof(unsigned short)); xc[f].red=ntohs(us); read(fd,&us,sizeof(unsigned short)); xc[f].green=ntohs(us); read(fd,&us,sizeof(unsigned short)); xc[f].blue=ntohs(us); } close(fd); XStoreColors(disp,cm,xc,256); } int RdSprSaveBut(b) Button *b; { ButtonText(b); } int SprSaveBut() { int fd,x,y; unsigned short s; if ((fd=open(name,O_WRONLY|O_CREAT,0666))==-1) { fprintf(stderr,"Couldn't save sprite to %s!\n",name); return; } write(fd,"XbitSprite",11); s=htons(SPR_W); write(fd,&s,sizeof(unsigned short)); s=htons(SPR_H); write(fd,&s,sizeof(unsigned short)); for(y=0;ytext=PLOT_TXT; break; case FILL: b->text=FILL_TXT; break; case LINE: b->text=LINE_TXT; break; case RECT: b->text=RECT_TXT; break; case BOX: b->text=BOX_TXT; break; case CIRCLE: b->text=CIRCLE_TXT; break; case OVAL: b->text=OVAL_TXT; break; default: b->text=ENDMODE_TXT; break; } ButtonText(b); } int DrawMode() { if(++drawmode==ENDMODE) drawmode=PLOT; if (last_x!=-1) RedrawSpr(); last_x=last_y=-1; } int RdSpreadBut(b) Button *b; { ButtonText(b); } int SpreadBut() { range=True; } int RdClearToBut(b) Button *b; { ButtonText(b); } int ClearToBut() { int x,y; for(x=0;xMAX_SPR_W) n=MAX_SPR_W; SPR_W=n; SPR_H=n; GRID_W=SETGW(MAX_SPR_W,n); NullStr(); RedrawAll(); } int RdQuitBut(b) Button *b; { ButtonText(b); } int QuitBut() { quit=True; }