#include #include #include #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)) static XSizeHints size_hints; static ulong black,white; static Display *disp; static Window window; static Colormap cm; static 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 Button { int x,y,w,h; char *text; void (*redraw)(struct Button *b); void (*callback)(void); } Button; static void RdCmapBut(Button *b); static void CmapBut(); static void RdSprSaveBut(Button *b); static void SprSaveBut(); static void RdSprLoadBut(Button *b); static void SprLoadBut(); static void RdSetCol(Button *b); static void SetCol(); static void RdSpreadBut(Button *b); static void SpreadBut(); static void RdLoadCmapBut(Button *b); static void LoadCmapBut(); static void RdDrawMode(Button *b); static void DrawMode(); static void RdClearToBut(Button *b); static void ClearToBut(); static void RdClearBut(Button *b); static void ClearBut(); static void RdSetSprBut(Button *b); static void SetSprBut(); static void RdQuitBut(Button *b); static void QuitBut(); #define NO_BUT 11 static 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} }; static void SetCmFade(int c1, int c2, XColor xc[], int fl); static void MainLoop(int argc, char *argv[]); static void NullStr(void); static void RedrawAll(void); static void RedrawButs(void); static void RedrawCmap(void); static void RedrawSel(void); static void RedrawStr(void); static void RedrawSpr(void); static void SpritePress(int x, int y, int b); static void SprCircle(int x, int y, int rx, int ry, int c); static void SprLine(int p1x,int p1y,int p2x,int p2y,int c); static void SprSet(int x,int y,int c); static void SprPlot(int x,int y,int c); static void SprFill(int x, int y, int c, int bc); static void RangeCols(int a, int b); static void ButtonPoll(Button *b, int n, int x, int y); static void ButtonText(const Button *b); static void ButtonRedraw(Button *b); static int ColPress(int x,int y, int *c); #define MAXSTRLEN 64 static int quit=False; static int selcol; static int range=False; static int width=1; static int drawmode=PLOT; static int last_x=-1,last_y=-1; static XColor xc[256]; static int namelen=0; static char name[MAXSTRLEN]; static int SPR_W=MAX_SPR_W; static int SPR_H=MAX_SPR_H; static int GRID_W=SETGW(MAX_SPR_W,MAX_SPR_H); static unsigned char sprite[MAX_SPR_W][MAX_SPR_H]; int main(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(); font=XUseFont("fixed"); cm = DefaultColormap(disp, DefaultScreen(disp)); 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; XAllocColor(disp, cm, &xc[f]); } selcol=1; xc[0].pixel=black; xc[0].flags=DoRed|DoBlue|DoGreen; xc[0].red=xc[0].blue=xc[0].green=0; xc[1].pixel=white; xc[1].flags=DoRed|DoBlue|DoGreen; xc[1].red=xc[1].blue=xc[1].green=0xffff; /* XStoreColors(disp,cm,xc,256); */ MainLoop(argc,argv); } static void SetCmFade(int c1, int 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].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; XAllocColor(disp, cm, &xc[f]); } } /* Main Loop */ static void MainLoop(int argc, char *argv[]) { XEvent e; KeySym ks; char keybuf[10]; int f,x,y; name[0]=0; 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((XKeyEvent *)&e,keybuf,10,&ks,NULL); switch(ks) { case XK_Delete: case XK_BackSpace: if (namelen) { name[--namelen]=0; RedrawStr(); Redraw(0,0); } break; default: switch(keybuf[0]) { case '': name[namelen=0]=0; 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); } static void RedrawStr(void) { 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); } static void RedrawSpr(void) { 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); } } static void SprSet(int x,int y,int c) { if ((x<0)||(x>=SPR_W)||(y<0)||(y>=SPR_H)) return; sprite[x][y]=c; SprPlot(x,y,c); } static void SprPlot(int x,int y,int c) { XPlot(SPR_X+x,SPR_Y+y,xc[c].pixel); x=GRID_X+(x*GRID_W)+1; y=GRID_Y+(y*GRID_W)+1; XFillBox(x,y,GRID_W-1,GRID_W-1,xc[c].pixel); } static void SprFill(int x, int y, int c, int 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); } static int ColPress(int x,int y, int *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); } } static void RangeCols(int a, int 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); } static void ButtonPoll(Button *b, int n, int x, int 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); } static void ButtonRedraw(Button *b) { XBox(b->x,b->y,b->w,b->h,white); if (b->redraw) (*b->redraw)(b); } /* Button Callbacks and redraws */ static void RdCmapBut(Button *b) { ButtonText(b); } static void CmapBut(void) { 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); } static void RdLoadCmapBut(Button *b) { ButtonText(b); } static void LoadCmapBut(void) { 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); XAllocColor(disp, cm, &xc[f]); } close(fd); /* XStoreColors(disp,cm,xc,256); */ RedrawAll(); } static void RdSprSaveBut(Button *b) { ButtonText(b); } static void SprSaveBut(void) { 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); } static void DrawMode(void) { if(++drawmode==ENDMODE) drawmode=PLOT; if (last_x!=-1) RedrawSpr(); last_x=last_y=-1; } static void RdSpreadBut(Button *b) { ButtonText(b); } static void SpreadBut(void) { range=True; } static void RdClearToBut(Button *b) { ButtonText(b); } static void ClearToBut(void) { 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(); } static void RdQuitBut(Button *b) { ButtonText(b); } static void QuitBut(void) { quit=True; }