diff options
Diffstat (limited to 'editmult.c')
-rw-r--r-- | editmult.c | 680 |
1 files changed, 680 insertions, 0 deletions
diff --git a/editmult.c b/editmult.c new file mode 100644 index 0000000..180b894 --- /dev/null +++ b/editmult.c @@ -0,0 +1,680 @@ +/* + + 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; + + 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) +{ + 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; + + 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; + + 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; + + 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; + + 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; + + 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) +{ + TRACE; + return; +} + + +void DrawObject_MULTI(void *data, int selmode) +{ + MultiObj *m; + + 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; + + 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) +{ + 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; + + 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; + + 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; + + 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) +{ + TRACE; +} + + +void LocateObject_MULTI(void *obj) +{ + MultiObj *m; + + TRACE; + + m=obj; + + ox=m->x-scale*SCRW/2; + oy=m->y+scale*SCRH/2; + +} + + +void ObjectInsert_MULTI(void) +{ + TRACE; +} + + +void ObjectDelete_MULTI(void) +{ + TRACE; +} + + +void ObjectMenu_MULTI(void) +{ + static double last_rot=0.0; + static double last_scale=0.0; + int cancel; + + TRACE; + + cancel=FALSE; + + switch(GUI_menu("Mutlimode",ms.x,ms.y,multi_popup,GUI_CANCEL)) + { + 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) +{ + TRACE; +} + + +int ObjectHasTag_MULTI(void *obj, int tag) +{ + TRACE; + return(FALSE); +} + + +void SetSelect_MULTI(int i, int mode) +{ + Object *o; + MultiObj *m; + Map om; + + 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; + + 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 */ |