summaryrefslogtreecommitdiff
path: root/editthng.c
diff options
context:
space:
mode:
Diffstat (limited to 'editthng.c')
-rw-r--r--editthng.c636
1 files changed, 636 insertions, 0 deletions
diff --git a/editthng.c b/editthng.c
new file mode 100644
index 0000000..ecc9dc6
--- /dev/null
+++ b/editthng.c
@@ -0,0 +1,636 @@
+/*
+
+ 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 THING definitions
+
+*/
+static const char rcs_id[]="$Id$";
+
+#include "config.h"
+#include "globals.h"
+
+#include "editvar.h"
+
+
+/* ---------------------------------------- PRIVATE UTILS
+*/
+static void ThingSelectionCentre(int *x,int *y)
+{
+ int *f;
+ EditThing *t;
+ Iterator i;
+ int min_x,min_y,max_x,max_y;
+
+ TRACE;
+
+ i=ListIterator(selected);
+
+ min_x=99999;
+ min_y=99999;
+ max_x=-99999;
+ max_y=-99999;
+
+ while(i)
+ {
+ f=IteratorData(i);
+ t=GETTHING(*f);
+
+ min_x=MIN(t->t.x,min_x);
+ min_y=MIN(t->t.y,min_y);
+ max_x=MAX(t->t.x,max_x);
+ max_y=MAX(t->t.y,max_y);
+
+ i=IteratorNext(i);
+ }
+
+ *x=min_x+(max_x-min_x)/2;
+ *y=min_y+(max_y-min_y)/2;
+}
+
+
+/* ---------------------------------------- GENERIC THING FUNCS
+*/
+int PositionOnObject_THING(int x,int y,void *data)
+{
+ EditThing *t;
+ int r;
+
+ TRACE;
+
+ t=data;
+ r=ThingRadius(t->t.type,NULL);
+
+ return (RADBOUND(x,y,t->t.x,t->t.y,r));
+}
+
+
+void SelectBox_THING(int x1,int y1,int x2,int y2)
+{
+ Object *o;
+ EditThing *t;
+ int f;
+
+ TRACE;
+
+ for(f=0;f<MapSize(thing);f++)
+ {
+ o=MapElem(thing,f);
+
+ if ((t=o->data))
+ {
+ if ((o->select!=SELECT_SELECTED)&&
+ (BOXBOUND(t->t.x,t->t.y,x1,y1,x2,y2)))
+ {
+ SetSelect(f,SELECT_SELECTED);
+ ListAppend(selected,&f);
+ }
+ }
+ }
+}
+
+
+void SelectByType_THING(void)
+{
+ Object *o;
+ EditThing *t;
+ int id;
+ int f;
+
+ if ((id=SelectThing())!=THING_NULLID)
+ {
+ ClearSelection();
+
+ for(f=0;f<MapSize(thing);f++)
+ if ((o=MapElem(thing,f)))
+ if ((t=o->data)&&(t->t.type==id))
+ {
+ SetSelect(f,SELECT_SELECTED);
+ ListAppend(selected,&f);
+ }
+ }
+}
+
+
+void DrawObject_THING(void *data, int selmode)
+{
+ EditThing *t;
+ int a;
+ int lx,ly;
+ int r;
+ int col;
+
+ TRACE;
+ t=data;
+
+ a=((t->t.ang+22)/45%8);
+ r=ThingRadius(t->t.type,&col);
+
+ switch(selmode)
+ {
+ case SELECT_OVER:
+ col=OVERCOL;
+ break;
+ case SELECT_SELECTED:
+ col=SELCOL;
+ break;
+ default:
+ break;
+ }
+
+ lx=t->t.x+(t_arrow[a].x*r);
+ ly=t->t.y+(t_arrow[a].y*r);
+
+ MapCircle(t->t.x,t->t.y,r,col);
+ DrawArrow(t->t.x,t->t.y,lx,ly,col);
+}
+
+
+void DrawObjectInfo_THING(void)
+{
+ EditThing *ti;
+
+ TRACE;
+
+ if (!draw_current_info)
+ return;
+
+ if ((current!=-1)&&((ti=GETTHING(current))))
+ GuiDrawInfoBox("THING",GUI_FLUSH_LEFT,GUI_FLUSH_LOWER,FALSE,
+ "Thing No : %d|"
+ "Thing Id : %d|"
+ "Angle : %s (%d)|"
+ "Flags : %s (0x%.2x)|"
+ "Name : %-60s",
+ current,
+ ti->t.type,
+ ANGLESTR(ti->t.ang),ti->t.ang,
+ ThingFlagText((int)ti->t.opt),ti->t.opt,
+ ThingName(ti->t.type));
+ else
+ GuiDrawInfoBox("THING",GUI_FLUSH_LEFT,GUI_FLUSH_LOWER,FALSE,
+ "Thing No : -|"
+ "Thing Id : -|"
+ "Angle : -|"
+ "Flags : - (-)|"
+ "Name : %-60s","");
+}
+
+
+void DrawObjectHeader_THING(void)
+{
+}
+
+
+void MoveObject_THING(void)
+{
+ GFXEvent ev;
+ int omx,omy;
+ int dmx,dmy;
+ int done;
+ Iterator i;
+ Iterator i2;
+ EditThing *t;
+ List orig;
+ int *f;
+ Point p;
+ int cancel=FALSE;
+
+ 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);
+ t=GETTHING(*f);
+ p.x=t->t.x;
+ p.y=t->t.y;
+ ListAppend(orig,&p);
+ i=IteratorNext(i);
+ }
+
+ while(!done)
+ {
+ GuiDrawInfoBox("Move THING",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));
+ t=GETTHING(*f);
+ t->t.x=p.x;
+ t->t.y=p.y;
+
+ i=IteratorNext(i);
+ i2=IteratorNext(i2);
+ }
+
+ 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);
+
+ t=GETTHING(*f);
+
+ t->t.x+=dmx;
+ t->t.y+=dmy;
+
+ i=IteratorNext(i);
+ }
+
+ omx=SnapX(XToMap(ms.x));
+ omy=SnapY(YToMap(ms.y));
+
+ FullRedraw();
+ }
+ }
+
+ ListClear(orig);
+
+ if ((clear_on_move)&&(!cancel))
+ ClearSelection();
+
+ FullRedraw();
+}
+
+
+void RotateObject_THING(double angle)
+{
+ int cx,cy;
+ int x,y;
+ int *f;
+ Iterator i;
+ EditThing *t;
+
+ TRACE;
+
+ ThingSelectionCentre(&cx,&cy);
+
+ i=ListIterator(selected);
+
+ while(i)
+ {
+ f=IteratorData(i);
+ t=GETTHING(*f);
+
+ x=t->t.x;
+ y=t->t.y;
+
+ Rotate(cx,cy,&x,&y,angle);
+
+ t->t.x=x;
+ t->t.y=y;
+
+ i=IteratorNext(i);
+ }
+}
+
+
+void ScaleObject_THING(double scale)
+{
+ int cx,cy;
+ int x,y;
+ int *f;
+ Iterator i;
+ EditThing *t;
+
+ TRACE;
+
+ ThingSelectionCentre(&cx,&cy);
+
+ i=ListIterator(selected);
+
+ while(i)
+ {
+ f=IteratorData(i);
+ t=GETTHING(*f);
+
+ x=t->t.x;
+ y=t->t.y;
+
+ Scale(cx,cy,&x,&y,scale);
+
+ t->t.x=x;
+ t->t.y=y;
+
+ i=IteratorNext(i);
+ }
+}
+
+
+void SetTagObject_THING(int tag)
+{
+ TRACE;
+}
+
+
+void LocateObject_THING(void *obj)
+{
+ EditThing *t;
+
+ TRACE;
+
+ t=obj;
+
+ ox=t->t.x-scale*SCRW/2;
+ oy=t->t.y+scale*SCRH/2;
+}
+
+
+void ObjectInsert_THING(void)
+{
+ Object o;
+ EditThing *t;
+ int f;
+
+ TRACE;
+
+ t=Grab(sizeof(EditThing));
+ memcpy(&t->t,&ed_thing,sizeof(Thing));
+ t->t.x=SnapX(XToMap(ms.x));
+ t->t.y=SnapY(YToMap(ms.y));
+
+ f=MapSize(thing);
+
+ switch(insert_select)
+ {
+ case HOVER_NONE:
+ o.select=SELECT_NONE;
+ break;
+ case HOVER_ADD:
+ case HOVER_SINGLE:
+ o.select=SELECT_SELECTED;
+ break;
+ }
+
+ o.data=t;
+ DrawObject_THING(t,o.select);
+ MapAdd(thing,f,&o);
+
+ switch(insert_select)
+ {
+ case HOVER_NONE:
+ break;
+ case HOVER_ADD:
+ ListAppend(selected,&f);
+ break;
+ case HOVER_SINGLE:
+ ClearSelection();
+ ListAppend(selected,&f);
+ FullRedraw();
+ break;
+ }
+}
+
+
+void ObjectDelete_THING(void)
+{
+ Iterator i;
+ Object *o;
+ int *f;
+
+ TRACE;
+
+ i=ListIterator(selected);
+
+ while(i)
+ {
+ f=IteratorData(i);
+
+ o=MapElem(thing,*f);
+
+ Release(o->data);
+ o->data=NULL;
+ o->select=SELECT_NONE;
+
+ i=IteratorNext(i);
+ }
+
+ ClearSelection();
+ FullRedraw();
+}
+
+
+void ObjectMenu_THING(void)
+{
+ EditThing *t;
+ int f,*s;
+ Iterator i;
+ int cancel;
+ int redraw=FALSE;
+
+ TRACE;
+
+ cancel=FALSE;
+ GFX_redraw();
+
+ switch(GUI_menu("Thing",ms.x,ms.y,thing_popup,GUI_CANCEL))
+ {
+ case TM_TYPE:
+ {
+ Short id;
+
+ id=(Short)SelectThing();
+
+ if (id!=THING_NULLID)
+ {
+ ed_thing.type=id;
+
+ i=ListIterator(selected);
+
+ while(i)
+ {
+ s=IteratorData(i);
+ t=GETTHING(*s);
+ t->t.type=id;
+ i=IteratorNext(i);
+ }
+
+ redraw=TRUE;
+ }
+ }
+ break;
+
+ case TM_ANGLE:
+ {
+ int a;
+
+ t=SelHead();
+ a=t->t.ang;
+
+ if ((a=GUI_radio_box
+ ("Angle",thing_angle,a,GUI_CANCEL))!=GUI_CANCEL)
+ {
+ ed_thing.ang=a;
+
+ i=ListIterator(selected);
+
+ while(i)
+ {
+ s=IteratorData(i);
+ t=GETTHING(*s);
+ t->t.ang=a;
+ i=IteratorNext(i);
+ }
+ }
+
+ redraw=TRUE;
+ }
+ break;
+
+ case TM_FLAGS:
+ i=ListIterator(selected);
+ s=IteratorData(i);
+ t=GETTHING(*s);
+ f=t->t.opt;
+
+ if (GUI_multi_box("Flags",ThingFlagArray(),&f))
+ {
+ ed_thing.opt=f;
+
+ while(i)
+ {
+ s=IteratorData(i);
+ t=GETTHING(*s);
+ t->t.opt=ed_thing.opt;
+ i=IteratorNext(i);
+ }
+
+ redraw=TRUE;
+ }
+ break;
+
+ case TM_SNAP:
+ {
+ int orig_lock;
+
+ orig_lock=grid_lock;
+ grid_lock=TRUE;
+
+ i=ListIterator(selected);
+
+ while(i)
+ {
+ s=IteratorData(i);
+ t=GETTHING(*s);
+ t->t.x=SnapX(t->t.x);
+ t->t.y=SnapX(t->t.y);
+ i=IteratorNext(i);
+ }
+
+ grid_lock=orig_lock;
+ redraw=TRUE;
+
+ break;
+ }
+
+ case TM_DELETE:
+ ObjectDelete_THING();
+ break;
+
+ case TM_MOVE:
+ MoveObject_THING();
+ break;
+
+ default:
+ cancel=TRUE;
+ break;
+ }
+
+ if ((!cancel)&&(clear_on_menu))
+ {
+ ClearSelection();
+ FullRedraw();
+ }
+ else if (redraw)
+ FullRedraw();
+}
+
+
+void ObjectKey_THING(GFXKey k)
+{
+}
+
+
+int ObjectHasTag_THING(void *obj, int tag)
+{
+ return(FALSE);
+}
+
+
+/* END OF FILE */