diff options
Diffstat (limited to 'ledit.c')
-rw-r--r-- | ledit.c | 547 |
1 files changed, 547 insertions, 0 deletions
@@ -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); +} |