summaryrefslogtreecommitdiff
path: root/spred.c
diff options
context:
space:
mode:
Diffstat (limited to 'spred.c')
-rw-r--r--spred.c1264
1 files changed, 1264 insertions, 0 deletions
diff --git a/spred.c b/spred.c
new file mode 100644
index 0000000..b1f36c8
--- /dev/null
+++ b/spred.c
@@ -0,0 +1,1264 @@
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xos.h>
+#include <X11/Xatom.h>
+#include <X11/keysym.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <math.h>
+
+#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;x<SPR_W;x++)
+ for(y=0;y<SPR_H;y++)
+ sprite[x][y]=(x*y)%256;
+
+ if (argc>1)
+ {
+ 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 (namelen<MAXSTRLEN-1)
+ {
+ name[namelen++]=keybuf[0];
+ name[namelen]=NULL;
+ RedrawStr();
+ Redraw(0,0);
+ }
+ break;
+ }
+ break;
+ }
+ break;
+
+ case ButtonPress:
+ if (!range)
+ ButtonPoll(butlist,NO_BUT,e.xbutton.x,e.xbutton.y);
+
+ if (!range)
+ SpritePress(e.xbutton.x,e.xbutton.y,e.xbutton.button);
+
+ if (range)
+ {
+ if (ColPress(e.xbutton.x,e.xbutton.y,&f))
+ {
+ RangeCols(selcol,f);
+ range=False;
+ RedrawCmap();
+ RedrawSel();
+ Redraw(0,0);
+ }
+ }
+ else
+ if(ColPress(e.xbutton.x,e.xbutton.y,&selcol))
+ {
+ RedrawCmap();
+ RedrawSel();
+ Redraw(0,0);
+ }
+
+ break;
+
+ case Expose:
+ if (e.xexpose.count)
+ break;
+ Redraw(0,0);
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+}
+
+
+/* Main Loop routines */
+
+NullStr()
+
+{
+ strcpy(name,"");
+ namelen=0;
+ RedrawStr();
+}
+
+
+RedrawAll()
+
+{
+ XCls(black);
+ RedrawButs();
+ RedrawCmap();
+ RedrawSel();
+ RedrawStr();
+ RedrawSpr();
+ Redraw(0,0);
+}
+
+RedrawButs()
+
+{
+ int f;
+
+ XCls(black);
+
+ for(f=0;f<NO_BUT;f++)
+ ButtonRedraw(&butlist[f]);
+}
+
+
+RedrawCmap()
+
+{
+ int x,y,f;
+
+ x=CMAP_X;
+ y=CMAP_Y;
+
+ for(f=0;f<256;f++,x+=CMAP_W)
+ {
+ if ((f)&&(!(f%CMAP_N)))
+ {
+ y+=CMAP_H;
+ x=CMAP_X;
+ }
+ XFillBox(x,y,CMAP_W,CMAP_H,f);
+ }
+}
+
+
+RedrawSel()
+
+{
+ XFillBox
+ (0,CMAP_Y-5-font->max_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;f<MAXSTRLEN;f++)
+ if (f<namelen)
+ s[f]=name[f];
+ else
+ s[f]='_';
+
+ s[MAXSTRLEN]=0;
+
+ XFillBox
+ (0,STR_Y-font->max_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;x++)
+ for(y=0;y<SPR_H;y++)
+ SprPlot(x,y,sprite[x][y]);
+}
+
+
+SpritePress(x,y,b)
+int x,y,b;
+
+{
+ int dx,dy;
+ int c;
+
+ x-=GRID_X;
+ y-=GRID_Y;
+ x/=GRID_W;
+ y/=GRID_W;
+
+ if (b==3)
+ c=black;
+ else
+ c=selcol;
+
+ if ((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)<ABS(last_y-y))
+ SprCircle(last_x,last_y,
+ ABS(last_y-y),ABS(last_y-y),selcol);
+ else
+ SprCircle(last_x,last_y,
+ ABS(last_x-x),ABS(last_x-x),selcol);
+
+ last_x=-1;
+ last_y=-1;
+ }
+ break;
+
+ case OVAL:
+ if (last_x==-1)
+ {
+ last_x=x;
+ last_y=y;
+ SprPlot(x,y,sprite[x][y]^255);
+ }
+ else
+ {
+ SprCircle(last_x,last_y,ABS(last_x-x),ABS(last_y-y),selcol);
+
+ last_x=-1;
+ last_y=-1;
+ }
+ break;
+
+ }
+
+ Redraw(0,0);
+}
+
+
+SprCircle(x,y,rx,ry,c)
+int x,y,rx,ry,c;
+
+{
+ int odx,ody,dy,dx,a;
+
+ SprPlot(x,y,sprite[x][y]);
+
+ odx=x+(int)(sin(RAD(a))*rx);
+ ody=y+(int)(cos(RAD(a))*ry);
+
+ for(a=0;a<360;a+=5)
+ {
+ dx=x+(int)(sin(RAD(a))*rx);
+ dy=y+(int)(cos(RAD(a))*ry);
+
+ SprLine(dx,dy,odx,ody,c);
+
+ odx=dx;
+ ody=dy;
+ }
+}
+
+
+SprLine(p1x,p1y,p2x,p2y,c)
+int p1x,p1y,p2x,p2y,c;
+
+{
+ int f;
+ int dx,dy,ix,iy,incrE,incrNE,d,x,y,ymode;
+
+ dx=p2x-p1x;
+ dy=p2y-p1y;
+
+ ix=SGN(dx);
+ iy=SGN(dy);
+
+ dx=ABS(dx);
+ dy=ABS(dy);
+
+ if (dy>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<n;f++)
+ {
+ xc[a+f].red=xc[a].red+(f*rc);
+ xc[a+f].green=xc[a].green+(f*gc);
+ xc[a+f].blue=xc[a].blue+(f*bc);
+ }
+ XStoreColors(disp,cm,xc,256);
+}
+
+
+/* Button Routines */
+
+isin(x,y,bx,by,bw,bh)
+int x,y,bx,by,bw,bh;
+
+{
+ if ((x>=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;f<n;f++)
+ if (isin(x,y,b[f].x,b[f].y,b[f].w,b[f].h))
+ {
+ (*b[f].callback)();
+ (*b[f].redraw)(&b[f]);
+ Redraw(0,0);
+ }
+}
+
+ButtonText(b)
+Button *b;
+
+{
+ XFillBox(b->x,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;y<SPR_H;y++)
+ for(x=0;x<SPR_W;x++)
+ write(fd,&sprite[x][y],sizeof(unsigned char));
+
+ close(fd);
+}
+
+
+int RdSprLoadBut(b)
+Button *b;
+
+{
+ ButtonText(b);
+}
+
+
+int SprLoadBut()
+
+{
+ int fd,x,y;
+ unsigned short s;
+ char m[11];
+
+ if ((fd=open(name,O_RDONLY))==-1)
+ {
+ fprintf(stderr,"Couldn't read sprite from %s!\n",name);
+ return;
+ }
+
+ read(fd,m,11);
+
+ if (strncmp("XbitSprite",m,10))
+ {
+ fprintf(stderr,"%s not a sprite!\n",name);
+ return;
+ }
+
+ read(fd,&s,sizeof(unsigned short));
+ SPR_W=ntohs(s);
+ read(fd,&s,sizeof(unsigned short));
+ SPR_H=ntohs(s);
+
+ GRID_W=SETGW(MAX_SPR_W,SPR_H);
+
+ for(y=0;y<SPR_H;y++)
+ for(x=0;x<SPR_W;x++)
+ read(fd,&sprite[x][y],sizeof(unsigned char));
+
+ close(fd);
+
+ RedrawAll();
+}
+
+
+int RdSetCol(b)
+Button *b;
+
+{
+ ButtonText(b);
+}
+
+
+int SetCol()
+
+{
+ static char *dum="0";
+ char *r,*g,*b,s[MAXSTRLEN];
+ int rc,gc,bc;
+
+ strcpy(s,name);
+
+ r=strtok(s," ");
+ g=strtok(NULL," ");
+ b=strtok(NULL," ");
+
+ if (!r)
+ r=dum;
+ if (!b)
+ b=dum;
+ if (!g)
+ g=dum;
+
+ xc[selcol].red=(int)strtol(r,NULL,0)*0xff;
+ xc[selcol].green=(int)strtol(g,NULL,0)*0xff;
+ xc[selcol].blue=(int)strtol(b,NULL,0)*0xff;
+
+ NullStr();
+
+ XStoreColors(disp,cm,xc,256);
+}
+
+
+int RdDrawMode(b)
+Button *b;
+
+{
+ switch(drawmode)
+ {
+ case PLOT:
+ b->text=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;x<SPR_W;x++)
+ for(y=0;y<SPR_H;y++)
+ SprSet(x,y,selcol);
+}
+
+
+int RdClearBut(b)
+Button *b;
+
+{
+ ButtonText(b);
+}
+
+
+int ClearBut()
+
+{
+ int x,y;
+
+ for(x=0;x<SPR_W;x++)
+ for(y=0;y<SPR_H;y++)
+ SprSet(x,y,black);
+}
+
+
+int RdSetSprBut(b)
+Button *b;
+
+{
+ ButtonText(b);
+}
+
+
+int SetSprBut()
+
+{
+ int n;
+
+ n=(int)strtol(name,NULL,0);
+
+ if (n<1)
+ n=2;
+
+ if (n>MAX_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;
+}