summaryrefslogtreecommitdiff
path: root/ledit.c
diff options
context:
space:
mode:
Diffstat (limited to 'ledit.c')
-rw-r--r--ledit.c547
1 files changed, 547 insertions, 0 deletions
diff --git a/ledit.c b/ledit.c
new file mode 100644
index 0000000..1a5c26c
--- /dev/null
+++ b/ledit.c
@@ -0,0 +1,547 @@
+/*
+
+ lunar - Simple X11 Lunar Lander
+
+ Copyright (C) 2005 Ian Cowburn (ianc@noddybox.demon.co.uk)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ -------------------------------------------------------------------------
+
+*/
+static char rcs_id[]="$Id$";
+
+#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 "Xbit.h"
+
+#define WINX 100
+#define WINY 100
+#define WINW 640
+#define WINH 640
+
+#define RND(x) (rand()%(x))
+
+XSizeHints size_hints;
+int black,white;
+Display *disp;
+Window window;
+Colormap cm;
+XFontStruct *font;
+
+XFuncControl Key();
+XFuncControl Mouse();
+XFuncControl Motion();
+XFuncControl Process();
+
+XCallBack key[2]={{0,Key},{0,NULL}};
+XCallBack mouse[2]={{0,Mouse},{0,NULL}};
+XCallBack motion[2]={{0,Motion},{0,NULL}};
+
+
+#define NOCOL 7
+char *colnames[NOCOL]=
+ {"black","white","red","yellow","blue","green","cyan"};
+int pix[NOCOL];
+
+#define BLACK pix[0]
+#define WHITE pix[1]
+#define RED pix[2]
+#define YELLOW pix[3]
+#define BLUE pix[4]
+#define GREEN pix[5]
+#define CYAN pix[6]
+
+typedef struct
+ {
+ int x,y;
+ } Pt;
+
+#define MNT 1
+#define MINE 2
+#define ASTCW 3
+#define ASTACW 4
+#define PAD 5
+
+char *ty_type[]={"BUG?!","MNT","MINE","ASTCW","ASTACW","PAD"};
+char ty_code[]={'?','M','O','X','Y','P'};
+
+int CONST =3;
+#define STOMX(x) (((x)-WINW/2)*CONST+gx)
+#define STOMY(y) (((y)-WINH/2)*CONST+gy)
+
+#define MTOSX(x) (((x-gx)/CONST)+(WINW/2))
+#define MTOSY(y) (((y-gy)/CONST)+(WINH/2))
+
+#define MAXLINE 32
+typedef struct
+ {
+ int ty;
+ Pt o;
+ int no;
+ Pt p[MAXLINE];
+ } Obj;
+
+
+#define MAXOBJ 64
+
+Obj obj[MAXOBJ];
+int no;
+int cur;
+char *fname;
+char *title="LEVEL TITLE";
+int mx,my;
+int gx=0,gy=0;
+
+
+int main(argc,argv)
+int argc;
+char *argv[];
+
+{
+ unsigned long evmask;
+
+ srand(getpid());
+
+ 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=ButtonPressMask|ButtonReleaseMask|
+ KeyPressMask|KeyReleaseMask|PointerMotionMask;
+
+ motion[0].w=mouse[0].w=key[0].w=window=
+ OpenWin(argc,argv,argv[0],
+ WINX,WINY,WINW,WINH,
+ WINW,WINH,
+ evmask,
+ &size_hints,&black,&white);
+
+ if (argc>1)
+ {
+ fname=argv[1];
+ ReadFile();
+ }
+ else
+ {
+ fprintf(stderr,"Must supply a level file\n");
+ exit(1);
+ }
+
+ if (argc>2)
+ CONST=atoi(argv[2]);
+
+ DisableDoubleBuffer();
+
+ disp=GetDisplay();
+
+ AllocColors(NOCOL,pix,colnames);
+
+ XDoWindows(mouse,motion,key,Process);
+}
+
+
+XFuncControl Key(w,m,e)
+Window w;
+int m;
+XEvent *e;
+
+{
+ KeySym k;
+
+ if (m==XPRESS)
+ return;
+
+ switch(k=XLookupKeysym(e,ShiftMapIndex))
+ {
+ case XK_G: /* Set centre */
+ case XK_g:
+ gx=STOMX(e->xkey.x);
+ gy=STOMY(e->xkey.y);
+ break;
+
+ case XK_H: /* Clear centre */
+ case XK_h:
+ gx=0;
+ gy=0;
+ break;
+
+ case XK_C: /* Create poly */
+ case XK_c:
+ if (no<MAXOBJ-1)
+ {
+ obj[no].o.x=STOMX(e->xkey.x);
+ obj[no].o.y=STOMY(e->xkey.y);
+ cur=no++;
+ }
+ break;
+
+ case XK_O: /* Set origin */
+ case XK_o:
+ if (no)
+ {
+ obj[cur].o.x=STOMX(e->xkey.x);
+ obj[cur].o.y=STOMY(e->xkey.y);
+ }
+ break;
+
+ case XK_D: /* Delete poly */
+ case XK_d:
+ if (no)
+ if (cur==(--no))
+ cur--;
+ break;
+
+ case XK_Left: /* Prev poly */
+ if (no)
+ if (cur)
+ cur--;
+ break;
+
+ case XK_Right: /* Prev poly */
+ if (no)
+ if (cur<(no-1))
+ cur++;
+ break;
+
+ case XK_Up: /* Scale up */
+ if (CONST>1)
+ CONST--;
+ break;
+
+ case XK_Down: /* Scale down */
+ CONST++;
+ break;
+
+ case XK_S: /* Save */
+ case XK_s:
+ WriteFile();
+ break;
+
+ case XK_Q: /* Quit */
+ case XK_q:
+ return (XFUNCSTOP);
+ break;
+
+ case XK_1:
+ case XK_2:
+ case XK_3:
+ case XK_4:
+ case XK_5:
+ if (no)
+ obj[cur].ty=k-XK_0;
+ break;
+
+ default:
+ break;
+ }
+
+ return(XFUNCCONT);
+}
+
+
+XFuncControl Mouse(w,m,b,x,y)
+Window w;
+int m;
+int b,x,y;
+
+{
+ int mapx,mapy;
+
+ if ((m==XPRESS)||(cur==-1))
+ return (XFUNCCONT);
+
+ switch(b)
+ {
+ case 1: /* Add point */
+ if (obj[cur].no<MAXLINE)
+ {
+ /* Convert to map co-ords
+ */
+ mapx=STOMX(x);
+ mapy=STOMY(y);
+
+ /* Knock of origin
+ */
+ mapx-=obj[cur].o.x;
+ mapy-=obj[cur].o.y;
+
+ obj[cur].p[obj[cur].no].x=mapx;
+ obj[cur].p[obj[cur].no].y=mapy;
+ obj[cur].no++;
+ }
+ break;
+
+ case 2: /* Remove point */
+ if (obj[cur].no)
+ obj[cur].no--;
+ break;
+
+ default:
+ break;
+ }
+
+ return(XFUNCCONT);
+}
+
+
+XFuncControl Motion(w,x,y)
+Window w;
+int x,y;
+
+{
+ mx=x;
+ my=y;
+ return(XFUNCCONT);
+}
+
+
+MapLine(x1,y1,x2,y2,c)
+int x1,y1,x2,y2,c;
+
+{
+ XLine(MTOSX(x1),MTOSY(y1),MTOSX(x2),MTOSY(y2),c);
+}
+
+
+DrawLines(p,n,c)
+Pt p[];
+int n,c;
+
+{
+ int f;
+
+ for (f=0;f<n;f++)
+ MapLine(p[f].x,p[f].y,
+ p[(f+1)%n].x,p[(f+1)%n].y,c);
+}
+
+
+RedrawObj()
+
+{
+ Pt p[MAXLINE];
+ int f,r,c;
+
+ /* Draw pretend lander
+ */
+ XLine(MTOSX(0),MTOSY(0),MTOSX(RND(20)-10),MTOSY(RND(20)-10),WHITE);
+
+ if (!no)
+ return;
+
+ /* Draw current object's origin
+ */
+ XLine(MTOSX(obj[cur].o.x),0,MTOSX(obj[cur].o.x),WINH-1,CYAN);
+ XLine(0,MTOSY(obj[cur].o.y),WINW-1,MTOSY(obj[cur].o.y),CYAN);
+
+ /* Draw all objects
+ */
+ for(f=0;f<no;f++)
+ {
+ if (f==cur)
+ c=pix[RND(NOCOL)];
+ else
+ c=pix[obj[f].ty];
+
+ for(r=0;r<obj[f].no;r++)
+ {
+ p[r].x=obj[f].o.x+obj[f].p[r].x;
+ p[r].y=obj[f].o.y+obj[f].p[r].y;
+ }
+
+ DrawLines(p,obj[f].no,c);
+ }
+}
+
+
+RedrawText()
+
+{
+ Xprintf(0,WINH-2,WHITE,
+ "Pos : %5d,%5d Centre : %5d,%5d Scale : %3d Title : %s File : %s",
+ STOMX(mx),STOMY(my),
+ gx,gy,
+ CONST,
+ title,
+ fname);
+
+ if (no)
+ Xprintf(0,10,WHITE,"Obj : %3d/%3d Type:%s Orig:%5d,%5d No lines:%5d",
+ cur+1,no,
+ ty_type[obj[cur].ty],
+ obj[cur].o.x,obj[cur].o.y,
+ obj[cur].no);
+ else
+ Xprintf(0,10,WHITE,"No objects");
+}
+
+
+XFuncControl Process()
+
+{
+ XCls(BLACK);
+
+ RedrawObj();
+ RedrawText();
+
+ Redraw(0,0);
+
+ return (XFUNCCONT);
+}
+
+
+char *GetLine(fp)
+FILE *fp;
+
+{
+ static char s[1204];
+
+ fgets(s,1024,fp);
+
+ if (s[strlen(s)-1]=='\n')
+ s[strlen(s)-1]='\0';
+
+ return(s);
+}
+
+
+GetNum(fp,x,y)
+FILE *fp;
+int *x,*y;
+
+{
+ sscanf(GetLine(fp),"%d,%d",x,y);
+}
+
+
+ReadFile()
+{
+ FILE *fp;
+ int f,x,y;
+ char *p;
+ int poly_no,pt_no;
+
+ no=0;
+ cur=-1;
+
+ for(f=0;f<MAXOBJ;f++)
+ {
+ obj[f].no=0;
+ obj[f].ty=MNT;
+ }
+
+ if (!(fp=fopen(fname,"r")))
+ {
+ fprintf(stderr,"Couldn't open lunar level file '%s'\n",fname);
+ return;
+ }
+
+ title=strdup(GetLine(fp));
+
+ poly_no=0;
+
+ p=GetLine(fp);
+
+ while (!feof(fp))
+ {
+ switch(*p)
+ {
+ case 'M':
+ obj[poly_no].ty=MNT;
+ break;
+ case 'X':
+ obj[poly_no].ty=ASTCW;
+ break;
+ case 'Y':
+ obj[poly_no].ty=ASTACW;
+ break;
+ case 'P':
+ obj[poly_no].ty=PAD;
+ break;
+ case 'O':
+ obj[poly_no].ty=MINE;
+ break;
+ }
+
+ GetNum(fp,&x,&y);
+
+ obj[poly_no].o.x=x;
+ obj[poly_no].o.y=y;
+
+ GetNum(fp,&x,&y);
+
+ pt_no=0;
+
+ while((x!=-666)||(y!=-666))
+ {
+ obj[poly_no].p[pt_no].x=x;
+ obj[poly_no].p[pt_no].y=y;
+
+ pt_no++;
+ GetNum(fp,&x,&y);
+ }
+
+ obj[poly_no].no=pt_no;
+ poly_no++;
+ p=GetLine(fp);
+ }
+
+ no=poly_no;
+
+ if (no)
+ cur=0;
+
+ fclose(fp);
+}
+
+
+WriteFile()
+{
+ FILE *fp;
+ int f,r;
+
+ if (!(fp=fopen(fname,"w")))
+ {
+ fprintf(stderr,"Couldn't write lunar level file '%s'\n",fname);
+ exit(0);
+ }
+
+ fprintf(fp,"%s\n",title);
+
+ for(f=0;f<no;f++)
+ {
+ fprintf(fp,"%c Object #%d\n",ty_code[obj[f].ty],f);
+
+ fprintf(fp,"%d,%d\n",obj[f].o.x,obj[f].o.y);
+
+ for(r=0;r<obj[f].no;r++)
+ fprintf(fp,"%d,%d\n",obj[f].p[r].x,obj[f].p[r].y);
+
+ fprintf(fp,"-666,-666\n");
+ }
+ fclose(fp);
+}