summaryrefslogtreecommitdiff
path: root/editmult.c
diff options
context:
space:
mode:
Diffstat (limited to 'editmult.c')
-rw-r--r--editmult.c708
1 files changed, 708 insertions, 0 deletions
diff --git a/editmult.c b/editmult.c
new file mode 100644
index 0000000..c3165ca
--- /dev/null
+++ b/editmult.c
@@ -0,0 +1,708 @@
+/*
+
+ 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
+
+ -------------------------------------------------------------------------
+
+ Editor MULTIMODE definitions
+
+*/
+static const char rcs_id[]="$Id$";
+
+#include "config.h"
+#include "globals.h"
+#include "util.h"
+
+#include "editvar.h"
+
+#define VERTEX 1
+#define THING 2
+
+
+/* ---------------------------------------- PRIVATE UTILS
+*/
+static int GetIterType(Iterator *i,MultiObj **mr,EditVert **v,EditThing **t)
+{
+ int *f;
+ MultiObj *m;
+
+ VIDOOM_TRACE;
+
+ f=IteratorData(*i);
+ m=GETMULTI(*f);
+
+ switch(m->type)
+ {
+ case VERTEX:
+ *v=GETVERT(m->i);
+ break;
+ case THING:
+ *t=GETTHING(m->i);
+ break;
+ }
+
+ *i=IteratorNext(*i);
+
+ if (mr)
+ *mr=m;
+
+ return(m->type);
+}
+
+
+static int GetType(MultiObj *m,EditVert **v,EditThing **t)
+{
+ VIDOOM_TRACE;
+
+ switch(m->type)
+ {
+ case VERTEX:
+ *v=GETVERT(m->i);
+ break;
+ case THING:
+ *t=GETTHING(m->i);
+ break;
+ }
+
+ return(m->type);
+}
+
+
+static void SelectionCentre(int *x,int *y)
+{
+ int *f;
+ MultiObj *m;
+ Iterator i;
+ int min_x,min_y,max_x,max_y;
+
+ VIDOOM_TRACE;
+
+ i=ListIterator(selected);
+
+ min_x=99999;
+ min_y=99999;
+ max_x=-99999;
+ max_y=-99999;
+
+ while(i)
+ {
+ f=IteratorData(i);
+ m=GETMULTI(*f);
+
+ min_x=MIN(m->x,min_x);
+ min_y=MIN(m->y,min_y);
+ max_x=MAX(m->x,max_x);
+ max_y=MAX(m->y,max_y);
+
+ i=IteratorNext(i);
+ }
+
+ *x=min_x+(max_x-min_x)/2;
+ *y=min_y+(max_y-min_y)/2;
+}
+
+
+static void ApplySelectionCoords(void)
+{
+ MultiObj *m;
+ Iterator i;
+ EditVert *v;
+ EditThing *t;
+
+ VIDOOM_TRACE;
+
+ i=ListIterator(selected);
+
+ while(i)
+ switch(GetIterType(&i,&m,&v,&t))
+ {
+ case THING:
+ t->t.x=m->x;
+ t->t.y=m->y;
+ break;
+
+ case VERTEX:
+ v->v.x=m->x;
+ v->v.y=m->y;
+ break;
+ }
+}
+
+
+/* ---------------------------------------- EXPORTED UTILS
+*/
+void GenerateMultiMap(void)
+{
+ MultiObj *m;
+ EditVert *v;
+ EditThing *t;
+ Object o;
+ int f;
+
+ VIDOOM_TRACE;
+
+ if (!multimap)
+ multimap=MapNew(sizeof(MultiObj));
+ else
+ {
+ for(f=0;f<MapSize(multimap);f++)
+ {
+ memcpy(&o,MapElem(multimap,f),sizeof(Object));
+
+ if (o.data)
+ Release(o.data);
+ }
+
+ multimap=MapEmpty(multimap);
+ }
+
+ for(f=0;f<MapSize(vertex);f++)
+ if ((v=GETVERT(f)))
+ {
+ m=Grab(sizeof(MultiObj));
+ m->type=VERTEX;
+ m->i=f;
+ m->x=v->v.x;
+ m->y=v->v.y;
+ o.data=m;
+ o.select=SELECT_NONE;
+ MapAdd(multimap,-1,&o);
+ }
+
+ for(f=0;f<MapSize(thing);f++)
+ if ((t=GETTHING(f)))
+ {
+ m=Grab(sizeof(MultiObj));
+ m->type=THING;
+ m->i=f;
+ m->x=t->t.x;
+ m->y=t->t.y;
+ o.data=m;
+ o.select=SELECT_NONE;
+ MapAdd(multimap,-1,&o);
+ }
+}
+
+/* ---------------------------------------- GENERIC THING FUNCS
+*/
+int PositionOnObject_MULTI(int x,int y,void *data)
+{
+ EditVert *v;
+ EditThing *t;
+
+ VIDOOM_TRACE;
+
+ switch(GetType(data,&v,&t))
+ {
+ case VERTEX:
+ return (PositionOnObject_VERTEX(x,y,v));
+ break;
+ case THING:
+ return (PositionOnObject_THING(x,y,t));
+ break;
+ }
+
+ return (FALSE);
+}
+
+
+void SelectBox_MULTI(int x1,int y1,int x2,int y2)
+{
+ Object *o;
+ MultiObj *m;
+ int f;
+
+ VIDOOM_TRACE;
+
+ for(f=0;f<MapSize(multimap);f++)
+ {
+ o=MapElem(multimap,f);
+
+ if ((m=o->data))
+ {
+ if ((o->select!=SELECT_SELECTED)&&
+ (BOXBOUND(m->x,m->y,x1,y1,x2,y2)))
+ {
+ SetSelect(f,SELECT_SELECTED);
+ ListAppend(selected,&f);
+ }
+ }
+ }
+}
+
+
+void SelectByType_MULTI(void)
+{
+ VIDOOM_TRACE;
+ return;
+}
+
+
+void DrawObject_MULTI(void *data, int selmode)
+{
+ MultiObj *m;
+
+ VIDOOM_TRACE;
+ m=data;
+
+ switch(m->type)
+ {
+ case VERTEX:
+ DrawObject_VERTEX(GETVERT(m->i),selmode);
+ break;
+ case THING:
+ DrawObject_THING(GETTHING(m->i),selmode);
+ break;
+ default:
+ break;
+ }
+}
+
+
+void DrawObjectInfo_MULTI(void)
+{
+ MultiObj *m;
+
+ VIDOOM_TRACE;
+
+ if (!draw_current_info)
+ return;
+
+ if ((current!=-1)&&((m=GETMULTI(current))))
+ GuiDrawInfoBox("MULTI MODE",GUI_FLUSH_LEFT,GUI_FLUSH_LOWER,FALSE,
+ "Object type : %s|"
+ "Number : %d",
+ (m->type == VERTEX ? "VERTEX" : "THING "),
+ m->i);
+ else
+ GuiDrawInfoBox("MULTI MODE",GUI_FLUSH_LEFT,GUI_FLUSH_LOWER,FALSE,
+ "Object type : |"
+ "Number : -");
+}
+
+
+void DrawObjectHeader_MULTI(void)
+{
+ VIDOOM_TRACE;
+}
+
+
+void MoveObject_MULTI(void)
+{
+ GFXEvent ev;
+ int omx,omy;
+ int dmx,dmy;
+ int done;
+ Iterator i;
+ Iterator i2;
+ MultiObj *m;
+ List orig;
+ int *f;
+ Point p;
+ int cancel=FALSE;
+
+ VIDOOM_TRACE;
+
+ omx=SnapX(XToMap(ms.x));
+ omy=SnapY(YToMap(ms.y));
+ GFX_bounce();
+
+ done=FALSE;
+ cancel=FALSE;
+ orig=ListNew(sizeof(Point));
+
+ i=ListIterator(selected);
+
+ while(i)
+ {
+ f=IteratorData(i);
+ m=GETMULTI(*f);
+ p.x=m->x;
+ p.y=m->y;
+ ListAppend(orig,&p);
+ i=IteratorNext(i);
+ }
+
+ while(!done)
+ {
+ GuiDrawInfoBox("Move Multiple Objects",
+ GUI_FLUSH_RIGHT,GUI_FLUSH_LOWER,FALSE,
+ "Left mouse button to place|ESC to cancel");
+
+ GFX_redraw();
+ GFX_await_input_full(&ev);
+
+ switch(ev.type)
+ {
+ case GFX_KEY_EVENT:
+ HandleMoveKey(ev.key,FALSE);
+
+ /* Cancel the move
+ */
+ if (ev.key.code==GFX_ESC)
+ {
+ cancel=TRUE;
+
+ i=ListIterator(selected);
+ i2=ListIterator(orig);
+
+ while(i2)
+ {
+ f=IteratorData(i);
+ memcpy(&p,IteratorData(i2),sizeof(Point));
+ m=GETMULTI(*f);
+ m->x=p.x;
+ m->y=p.y;
+
+ i=IteratorNext(i);
+ i2=IteratorNext(i2);
+ }
+
+ ApplySelectionCoords();
+
+ done=TRUE;
+ dmx=0;
+ dmy=0;
+ }
+ else
+ {
+ dmx=SnapX(XToMap(ms.x))-omx;
+ dmy=SnapY(YToMap(ms.y))-omy;
+ }
+
+ break;
+
+ case GFX_MOUSE_EVENT:
+ memcpy(&ms,&ev.mouse,sizeof(ev.mouse));
+
+ if (ms.b&GFX_BUTLEFT)
+ done=TRUE;
+
+ dmx=SnapX(XToMap(ms.x))-omx;
+ dmy=SnapY(YToMap(ms.y))-omy;
+ break;
+
+ default:
+ dmx=0;
+ dmy=0;
+ break;
+ }
+
+ if ((dmx)||(dmy))
+ {
+ i=ListIterator(selected);
+ while(i)
+ {
+ f=IteratorData(i);
+
+ m=GETMULTI(*f);
+
+ m->x+=dmx;
+ m->y+=dmy;
+
+ i=IteratorNext(i);
+ }
+
+ ApplySelectionCoords();
+
+ omx=SnapX(XToMap(ms.x));
+ omy=SnapY(YToMap(ms.y));
+
+ FullRedraw();
+ }
+ }
+
+ ListClear(orig);
+
+ if ((clear_on_move)&&(!cancel))
+ ClearSelection();
+
+ FullRedraw();
+}
+
+
+void RotateObject_MULTI(double angle)
+{
+ int cx,cy;
+ int x,y;
+ int *f;
+ Iterator i;
+ MultiObj *m;
+
+ VIDOOM_TRACE;
+
+ SelectionCentre(&cx,&cy);
+
+ i=ListIterator(selected);
+
+ while(i)
+ {
+ f=IteratorData(i);
+ m=GETMULTI(*f);
+
+ x=m->x;
+ y=m->y;
+
+ Rotate(cx,cy,&x,&y,angle);
+
+ m->x=x;
+ m->y=y;
+
+ i=IteratorNext(i);
+ }
+
+ ApplySelectionCoords();
+}
+
+
+void ScaleObject_MULTI(double scale)
+{
+ int cx,cy;
+ int x,y;
+ int *f;
+ Iterator i;
+ MultiObj *m;
+
+ VIDOOM_TRACE;
+
+ SelectionCentre(&cx,&cy);
+
+ i=ListIterator(selected);
+
+ while(i)
+ {
+ f=IteratorData(i);
+ m=GETMULTI(*f);
+
+ x=m->x;
+ y=m->y;
+
+ Scale(cx,cy,&x,&y,scale);
+
+ m->x=x;
+ m->y=y;
+
+ i=IteratorNext(i);
+ }
+
+ ApplySelectionCoords();
+}
+
+
+void SetTagObject_MULTI(int tag)
+{
+ VIDOOM_TRACE;
+}
+
+
+void LocateObject_MULTI(void *obj)
+{
+ MultiObj *m;
+
+ VIDOOM_TRACE;
+
+ m=obj;
+
+ ox=m->x-scale*SCRW/2;
+ oy=m->y+scale*SCRH/2;
+
+}
+
+
+void ObjectInsert_MULTI(void)
+{
+ VIDOOM_TRACE;
+}
+
+
+void ObjectDelete_MULTI(void)
+{
+ VIDOOM_TRACE;
+}
+
+
+void ObjectMenu_MULTI(void)
+{
+ static double last_rot=0.0;
+ static double last_scale=0.0;
+ int cancel;
+
+ VIDOOM_TRACE;
+
+ cancel=FALSE;
+
+ switch(GUI_menu("Mutlimode",ms.x,ms.y,multi_popup,GUI_CANCEL))
+ {
+ case TM_SNAP:
+ {
+ Iterator i;
+ MultiObj *m;
+ int orig_lock;
+ int *s;
+
+ orig_lock=grid_lock;
+ grid_lock=TRUE;
+
+ i=ListIterator(selected);
+
+ while(i)
+ {
+ s=IteratorData(i);
+ m=GETMULTI(*s);
+ m->x=SnapX(m->x);
+ m->y=SnapX(m->y);
+ i=IteratorNext(i);
+ }
+
+ grid_lock=orig_lock;
+ ApplySelectionCoords();
+ FullRedraw();
+
+ break;
+ }
+
+ case TM_MOVE:
+ MoveObject_MULTI();
+ break;
+
+ case TM_ROTATE:
+ rotate_dialog[D_ROTATE].data.d=last_rot;
+
+ if (GUI_dialog("Rotate",D_ROTATE_NO,rotate_dialog))
+ {
+ last_rot=rotate_dialog[D_ROTATE].data.d;
+ RotateObject_MULTI(-last_rot);
+ FullRedraw();
+ }
+ else
+ cancel=TRUE;
+
+ break;
+
+ case TM_SCALE:
+ scale_dialog[D_SCALE].data.d=last_scale;
+
+ if (GUI_dialog("Scale",D_SCALE_NO,scale_dialog))
+ {
+ ScaleObject_MULTI(last_scale=scale_dialog[D_SCALE].data.d);
+ FullRedraw();
+ }
+ else
+ cancel=TRUE;
+
+ break;
+
+ default:
+ cancel=TRUE;
+ break;
+ }
+
+ if ((!cancel)&&(clear_on_menu))
+ {
+ ClearSelection();
+ FullRedraw();
+ }
+}
+
+
+void ObjectKey_MULTI(GFXKey k)
+{
+ VIDOOM_TRACE;
+}
+
+
+int ObjectHasTag_MULTI(void *obj, int tag)
+{
+ VIDOOM_TRACE;
+ return(FALSE);
+}
+
+
+void SetSelect_MULTI(int i, int mode)
+{
+ Object *o;
+ MultiObj *m;
+ Map om;
+
+ VIDOOM_TRACE;
+ o=MapElem(multimap,i);
+
+ if ((m=o->data))
+ {
+ o->select=mode;
+
+ if (m->type==VERTEX)
+ om=vertex;
+ else
+ om=thing;
+
+ o=MapElem(om,m->i);
+ o->select=mode;
+ }
+}
+
+
+
+ObjDesc *ObjectOverlaid_MULTI(int x, int y, int *no)
+{
+ int n;
+ MultiObj *m;
+ EditThing *t;
+ EditVert *v;
+ ObjDesc *od;
+ int f;
+
+ VIDOOM_TRACE;
+
+ od=NULL;
+
+ n=0;
+
+ for(f=0;f<MapSize(multimap);f++)
+ {
+ m=GETMULTI(f);
+
+ if ((m)&&(PositionOnObject_MULTI(x,y,m)))
+ {
+ n++;
+ od=ReGrab(od,sizeof(ObjDesc)*n);
+ od[n-1].no=f;
+
+ switch(GetType(m,&v,&t))
+ {
+ case VERTEX:
+ sprintf(od[n-1].detail,"Vertex %-5d - %d,%d",
+ f,v->v.x,v->v.y);
+ break;
+
+ case THING:
+ sprintf(od[n-1].detail,"Thing %-5d - %s",f,
+ TrimStr(ThingName(t->t.type),29));
+ break;
+ }
+ }
+ }
+
+ *no=n;
+ return(od);
+}
+
+
+
+/* END OF FILE */