summaryrefslogtreecommitdiff
path: root/genlines.c
diff options
context:
space:
mode:
Diffstat (limited to 'genlines.c')
-rw-r--r--genlines.c460
1 files changed, 460 insertions, 0 deletions
diff --git a/genlines.c b/genlines.c
new file mode 100644
index 0000000..98ca1dd
--- /dev/null
+++ b/genlines.c
@@ -0,0 +1,460 @@
+/*
+
+ viDOOM - level editor for DOOM
+
+ Copyright (C) 2000 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
+
+ -------------------------------------------------------------------------
+
+ Handles definition and storage of the supported generalised LINEDEFs
+
+*/
+static const char rcs_id[]="$Id$";
+
+#include "config.h"
+#include "globals.h"
+
+#include "platgui.h"
+#include "gfx.h"
+#include "platgui.h"
+#include "genlines.h"
+#include "mem.h"
+#include "map.h"
+#include "linedefs.h"
+
+
+/* ---------------------------------------- TYPES AND VARS
+*/
+typedef struct
+ {
+ char *name;
+ char *abbrev;
+ int val;
+ } gl_BitField;
+
+typedef struct
+ {
+ int i;
+
+ char *name;
+ int no;
+ gl_BitField *bf;
+ } gl_BitMask;
+
+typedef struct
+ {
+ int mask;
+ int shift;
+ gl_BitMask *bm;
+ } gl_ClassBitMask;
+
+typedef struct
+ {
+ int i;
+
+ char *name;
+ int hi;
+ int lo;
+ int no;
+ int mask;
+ gl_ClassBitMask *bm;
+
+ PLAT_DIALOG *dial;
+ } gl_Class;
+
+
+static Map mask_map=NULL;
+static Map class_map[2]={NULL,NULL};
+
+
+/* ---------------------------------------- PRIVATE FUNCTIONS
+*/
+static int Index(int for_hexen)
+{
+ if (for_hexen)
+ return(1);
+ else
+ return(0);
+}
+
+
+static gl_BitMask *GetMask(char *class)
+{
+ gl_BitMask *m;
+ int f;
+
+ for(f=0;f<MapSize(mask_map);f++)
+ {
+ m=MapElem(mask_map,f);
+
+ if ((m)&&(STREQ(class,m->name)))
+ return(m);
+ }
+
+ return(NULL);
+}
+
+
+static gl_Class *GetClass(int i,char *class)
+{
+ gl_Class *c;
+ int f;
+
+ for(f=0;f<MapSize(class_map[i]);f++)
+ {
+ c=MapElem(class_map[i],f);
+
+ if ((c)&&(STREQ(class,c->name)))
+ return(c);
+ }
+
+ return(NULL);
+}
+
+
+static gl_Class *ClassMenu(int i)
+{
+ static PLAT_MENU *menu[2]={NULL,NULL};
+ gl_Class *cl;
+ int f,x,y;
+
+ if (!menu[i])
+ {
+ menu[i]=Grab(sizeof(PLAT_MENU)*(MapSize(class_map[i])+1));
+
+ for(f=0;f<MapSize(class_map[i]);f++)
+ {
+ cl=MapElem(class_map[i],f);
+
+ menu[i][f].text=cl->name;
+ menu[i][f].client_index=f;
+ menu[i][f].child=NULL;
+ }
+
+ menu[i][f].text=NULL;
+ }
+
+ GFX_mouse(&x,&y);
+ f=GUI_menu("Generalised LINEDEF type",x,y,menu[i],GENLINE_NULLID);
+
+ if (f==GENLINE_NULLID)
+ return(NULL);
+ else
+ return(MapElem(class_map[i],f));
+}
+
+
+static void InitDialog(gl_Class *cl, int type)
+{
+ int f,r;
+ int mask;
+
+ /* Create the dialog if not already done so
+ */
+ if (!cl->dial)
+ {
+ if (cl->i!=cl->no)
+ GFX_exit(EXIT_FAILURE,
+ "Not all bitfields defined for class:\n %s\n",cl->name);
+
+ cl->dial=Grab(sizeof(PLAT_DIALOG)*cl->no);
+
+ for(f=0;f<cl->no;f++)
+ {
+ cl->dial[f].text=cl->bm[f].bm->name;
+ cl->dial[f].type=PLAT_DIAL_PICKLIST;
+
+ cl->dial[f].data.pl.no=cl->bm[f].bm->no;
+ cl->dial[f].data.pl.current=0;
+ cl->dial[f].data.pl.text=Grab(cl->bm[f].bm->no*sizeof(char *));
+
+ for(r=0;r<cl->bm[f].bm->no;r++)
+ cl->dial[f].data.pl.text[r]=Strdup(cl->bm[f].bm->bf[r].name);
+ }
+ }
+
+ /* Set the flags from the current value
+ */
+ for(f=0;f<cl->no;f++)
+ {
+ cl->dial[f].data.pl.current=0;
+
+ mask=(type>>cl->bm[f].shift)&cl->bm[f].mask;
+
+ for(r=0;r<cl->bm[f].bm->no;r++)
+ if (cl->bm[f].bm->bf[r].val==mask)
+ cl->dial[f].data.pl.current=r;
+ }
+}
+
+
+/* ---------------------------------------- EXPORTED FUNCTIONS
+*/
+
+void GenLineNewBitClass(char *class, int no_fields)
+{
+ gl_BitMask *bm;
+
+ bm=Grab(sizeof(gl_BitMask));
+
+ if (!mask_map)
+ mask_map=MapNew(sizeof(gl_BitMask));
+
+ bm->name=Strdup(class);
+ bm->no=no_fields;
+ bm->i=0;
+ bm->bf=Grab(sizeof(gl_BitField)*bm->no);
+
+ MapAdd(mask_map,-1,bm);
+}
+
+
+void GenLineAddBitmask(char *class, char *name, char *abbrev, int mask)
+{
+ gl_BitField *bf;
+ gl_BitMask *bm;
+
+ if (!(bm=GetMask(class)))
+ GFX_exit(EXIT_FAILURE,"Adding bit field:\n%s\n\nfailed as "
+ "there is no bitmask:\n%s\n",name,class);
+
+ if (bm->i==bm->no)
+ GFX_exit(EXIT_FAILURE,"Adding bit field:\n%s\n\n "
+ "overflows bitmask:\n%s\n",name,class);
+
+ bf=&(bm->bf[bm->i++]);
+
+ bf->name=Strdup(name);
+ bf->abbrev=Strdup(abbrev);
+ bf->val=mask;
+}
+
+
+void GenLineNewClass(int for_hexen, char *class,
+ int lo, int hi, int mask, int no_bitmasks)
+{
+ gl_Class *cl;
+ int i;
+
+ i=Index(for_hexen);
+
+ cl=Grab(sizeof(gl_Class));
+
+ if (!class_map[i])
+ class_map[i]=MapNew(sizeof(gl_Class));
+
+ cl->name=Strdup(class);
+ cl->hi=hi;
+ cl->lo=lo;
+ cl->mask=mask;
+ cl->no=no_bitmasks;
+ cl->i=0;
+ cl->bm=Grab(sizeof(gl_ClassBitMask)*cl->no);
+ cl->dial=NULL;
+
+ MapAdd(class_map[i],-1,cl);
+}
+
+
+void GenLineAdd(int for_hexen, char *class, char *bitmask, int shift)
+{
+ gl_Class *cl;
+ gl_BitMask *bm;
+ int f;
+ int i;
+
+ i=Index(for_hexen);
+
+ if (!(bm=GetMask(bitmask)))
+ GFX_exit(EXIT_FAILURE,"Adding bitmask:\n%s\n\nto class:\n%s\n\n"
+ "failed as there is no such bitmask class\n\n",
+ bitmask,class);
+
+ if (bm->i!=bm->no)
+ GFX_exit(EXIT_FAILURE,"Adding bitmask:\n%s\n\nto class:\n%s\n\n"
+ "failed as not all fields have been defined "
+ "in the bitmask\n\n",
+ bitmask,class);
+
+ if (!(cl=GetClass(i,class)))
+ GFX_exit(EXIT_FAILURE,"Adding bitmask:\n%s\n\nto class:\n%s\n\n"
+ "failed as there is no such class\n\n",
+ bitmask,class);
+
+ if (cl->i==cl->no)
+ GFX_exit(EXIT_FAILURE,"Adding bitmask:\n%s\n\nto class:\n%s\n\n"
+ "overflows class\n\n",
+ bitmask,class);
+
+ cl->bm[cl->i].bm=bm;
+ cl->bm[cl->i].shift=shift;
+ cl->bm[cl->i].mask=0;
+
+ for(f=0;f<cl->bm[cl->i].bm->no;f++)
+ cl->bm[cl->i].mask|=cl->bm[cl->i].bm->bf[f].val;
+
+ cl->i++;
+}
+
+
+int SelectGenLine(int for_hexen, int current_type)
+{
+ gl_Class *cl;
+ int n;
+ int f;
+ int i;
+
+ i=Index(for_hexen);
+
+ if (MapSize(class_map[i])==0)
+ return(GENLINE_NULLID);
+
+ if (MapSize(class_map[i])==1)
+ cl=MapElem(class_map[i],0);
+ else
+ if (!(cl=ClassMenu(i)))
+ return(GENLINE_NULLID);
+
+ InitDialog(cl,current_type);
+
+ if (GUI_dialog(cl->name,cl->no,cl->dial))
+ {
+ if (cl->mask!=-1)
+ n=cl->mask;
+ else
+ {
+ n=current_type;
+
+ for(f=0;f<cl->no;f++)
+ n&=~(cl->bm[f].mask<<cl->bm[f].shift);
+ }
+
+ for(f=0;f<cl->no;f++)
+ n|=(cl->bm[f].bm->bf[cl->dial[f].data.pl.current].val)
+ <<cl->bm[f].shift;
+ }
+ else
+ n=GENLINE_NULLID;
+
+ return(n);
+}
+
+
+char *GenLineName(int for_hexen, int id,char *(*GetName)(int id))
+{
+ static char s[512];
+ gl_Class *cl;
+ int f,r,i;
+ int got;
+ int mask;
+ int index;
+
+ index=Index(for_hexen);
+
+ for(f=0;f<MapSize(class_map[index]);f++)
+ {
+ cl=MapElem(class_map[index],f);
+
+ if ((id>=cl->lo)&&(id<=cl->hi))
+ {
+ s[0]=0;
+
+ for(r=0;r<cl->no;r++)
+ {
+ if (r)
+ strcat(s,"/");
+
+ mask=(id>>cl->bm[r].shift)&cl->bm[r].mask;
+
+ got=FALSE;
+
+ for(i=0;(i<cl->bm[r].bm->no)&&(!got);i++)
+ if (mask==cl->bm[r].bm->bf[i].val)
+ {
+ strcat(s,cl->bm[r].bm->bf[i].abbrev);
+ got=TRUE;
+ }
+
+ if (!got)
+ strcat(s,"???");
+ }
+
+ if (cl->mask==-1)
+ {
+ for(f=0;f<cl->no;f++)
+ id&=~(cl->bm[f].mask<<cl->bm[f].shift);
+
+ if (GetName(id))
+ {
+ strcat(s," & ");
+ strcat(s,GetName(id));
+ }
+ }
+
+ return(s);
+ }
+ }
+
+ return(NULL);
+}
+
+
+char *GenLineClass(int for_hexen, int id,char *(*GetClass)(int id))
+{
+ static char s[512];
+ gl_Class *cl;
+ int f;
+ int i;
+
+ i=Index(for_hexen);
+
+ for(f=0;f<MapSize(class_map[i]);f++)
+ {
+ cl=MapElem(class_map[i],f);
+
+ if ((id>=cl->lo)&&(id<=cl->hi))
+ {
+ strcpy(s,cl->name);
+
+ if (cl->mask==-1)
+ {
+ for(f=0;f<cl->no;f++)
+ id&=~(cl->bm[f].mask<<cl->bm[f].shift);
+
+ if (GetClass(id))
+ {
+ strcat(s," & ");
+ strcat(s,GetClass(id));
+ }
+ }
+
+ return(s);
+ }
+ }
+
+ return(NULL);
+}
+
+
+
+int GenLineNoClasses(int for_hexen)
+{
+ return(MapSize(class_map[Index(for_hexen)]));
+}
+
+
+/* END OF FILE */