diff options
author | Ian C <ianc@noddybox.co.uk> | 2011-06-09 13:46:28 +0000 |
---|---|---|
committer | Ian C <ianc@noddybox.co.uk> | 2011-06-09 13:46:28 +0000 |
commit | a9022b5972dc49d86f617a27940fafe9c4d0e7e7 (patch) | |
tree | 61405aa4ade91ed1057f863ddf118ceb38e14f8e /editvert.c |
Initial import of (very old) vidoom sources.
Diffstat (limited to 'editvert.c')
-rw-r--r-- | editvert.c | 834 |
1 files changed, 834 insertions, 0 deletions
diff --git a/editvert.c b/editvert.c new file mode 100644 index 0000000..361aa00 --- /dev/null +++ b/editvert.c @@ -0,0 +1,834 @@ +/* + + 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 VERTEX definitions + +*/ +static const char rcs_id[]="$Id$"; + +#include "config.h" +#include "globals.h" + +#include "editvar.h" + + +/* ---------------------------------------- PRIVATE UTILS +*/ +static void VertexSelectionCentre(int *x,int *y) +{ + int *f; + EditVert *v; + 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); + v=GETVERT(*f); + + min_x=MIN(v->v.x,min_x); + min_y=MIN(v->v.y,min_y); + max_x=MAX(v->v.x,max_x); + max_y=MAX(v->v.y,max_y); + + i=IteratorNext(i); + } + + *x=min_x+(max_x-min_x)/2; + *y=min_y+(max_y-min_y)/2; +} + + +static void MergeVertex(int new,int old) +{ + Object *o; + EditVert *v; + EditLine *l; + int f; + + o=MapElem(vertex,old); + v=o->data; + ListClear(v->l); + Release(o->data); + o->data=NULL; + o->select=SELECT_NONE; + + v=GETVERT(new); + + for(f=0;f<MapSize(linedef);f++) + if ((l=GETLINE(f))) + { + if (l->l.from==old) + { + l->l.from=new; + l->v[0]=v; + IntListUniqAdd(v->l,f); + } + + if (l->l.to==old) + { + l->l.to=new; + l->v[1]=v; + IntListUniqAdd(v->l,f); + } + } + + if (merge_linedef!=MERGE_NEVER) + { + v=GETVERT(new); + CheckMergeLinedef(v); + } +} + +/* ---------------------------------------- GENERIC VERTEX FUNCS +*/ +int PositionOnObject_VERTEX(int x,int y,void *data) +{ + EditVert *v; + + VIDOOM_TRACE; + + v=data; + return (RADBOUND(x,y,v->v.x,v->v.y,vertex_rad)); +} + + +void SelectBox_VERTEX(int x1,int y1,int x2,int y2) +{ + Object *o; + EditVert *v; + int f; + + VIDOOM_TRACE; + + for(f=0;f<MapSize(vertex);f++) + { + o=MapElem(vertex,f); + + if ((v=o->data)) + { + if ((o->select!=SELECT_SELECTED)&& + (BOXBOUND(v->v.x,v->v.y,x1,y1,x2,y2))) + { + SetSelect(f,SELECT_SELECTED); + ListAppend(selected,&f); + } + } + } +} + + +void SelectByType_VERTEX(void) +{ + return; +} + + +void DrawObject_VERTEX(void *data, int selmode) +{ + EditVert *v; + int col; + + VIDOOM_TRACE; + v=data; + + MapPlot(v->v.x,v->v.y,VERTCOL); + + switch(selmode) + { + case SELECT_OVER: + col=OVERCOL; + break; + case SELECT_SELECTED: + col=SELCOL; + break; + default: + col=VERTBOXCOL; + break; + } + + MapRect(v->v.x-vertex_rad,v->v.y+vertex_rad,vertex_rad*2,vertex_rad*2,col); +} + + +void DrawObjectInfo_VERTEX(void) +{ + EditVert *v; + + VIDOOM_TRACE; + + if (!draw_current_info) + return; + + if ((current!=-1)&&((v=GETVERT(current)))) + GuiDrawInfoBox("VERTEX",GUI_FLUSH_LEFT,GUI_FLUSH_LOWER,FALSE, + "Vertex No : %10d|" + "X : %10d|" + "Y : %10d", + current, + v->v.x,v->v.y); + else + GuiDrawInfoBox("VERTEX",GUI_FLUSH_LEFT,GUI_FLUSH_LOWER,FALSE, + "Vertex No : - |" + "X : - |" + "Y : - "); +} + + +void DrawObjectHeader_VERTEX(void) +{ +} + + +void MoveObject_VERTEX(void) +{ + GFXEvent ev; + int omx,omy; + int dmx,dmy; + int done; + Iterator i; + Iterator i2; + EditVert *v,*v2; + List orig; + int *f; + int r; + Point p; + int cancel; + int done_merge; + + VIDOOM_TRACE; + + omx=SnapX(XToMap(ms.x)); + omy=SnapY(YToMap(ms.y)); + GFX_bounce(); + + done=FALSE; + cancel=FALSE; + done_merge=FALSE; + orig=ListNew(sizeof(Point)); + + i=ListIterator(selected); + + while(i) + { + f=IteratorData(i); + v=GETVERT(*f); + p.x=v->v.x; + p.y=v->v.y; + ListAppend(orig,&p); + i=IteratorNext(i); + } + + while(!done) + { + GuiDrawInfoBox("Move VERTEX",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)); + v=GETVERT(*f); + v->v.x=p.x; + v->v.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); + + v=GETVERT(*f); + + v->v.x+=dmx; + v->v.y+=dmy; + + i=IteratorNext(i); + } + + omx=SnapX(XToMap(ms.x)); + omy=SnapY(YToMap(ms.y)); + + FullRedraw(); + } + } + + ListClear(orig); + + if (!cancel) + { + int ask; + int ok; + + ask=TRUE; + ok=TRUE; + + i=ListIterator(selected); + + while(i) + { + f=IteratorData(i); + + for(r=0;(r<MapSize(vertex))&&(ok);r++) + if (r!=*f) + { + v=GETVERT(*f); + v2=GETVERT(r); + + if ((v)&&(v2)) + if ((v->v.x==v2->v.x)&&(v->v.y==v2->v.y)) + { + if (ask) + { + ok=YesNo("Merge overlapping vertexes?"); + ask=FALSE; + } + + if (ok) + { + MergeVertex(*f,r); + done_merge=TRUE; + } + } + } + + i=IteratorNext(i); + } + + if (done_merge) + SectorCalcContainingAll(); + } + + if ((clear_on_move)&&(!cancel)) + ClearSelection(); + + FullRedraw(); +} + + +void RotateObject_VERTEX(double angle) +{ + int cx,cy; + int x,y; + int *f; + Iterator i; + EditVert *v; + + VIDOOM_TRACE; + + VertexSelectionCentre(&cx,&cy); + + i=ListIterator(selected); + + while(i) + { + f=IteratorData(i); + v=GETVERT(*f); + + x=v->v.x; + y=v->v.y; + + Rotate(cx,cy,&x,&y,angle); + + v->v.x=x; + v->v.y=y; + + i=IteratorNext(i); + } +} + + +void ScaleObject_VERTEX(double scale) +{ + int cx,cy; + int x,y; + int *f; + Iterator i; + EditVert *v; + + VIDOOM_TRACE; + + VertexSelectionCentre(&cx,&cy); + + i=ListIterator(selected); + + while(i) + { + f=IteratorData(i); + v=GETVERT(*f); + + x=v->v.x; + y=v->v.y; + + Scale(cx,cy,&x,&y,scale); + + v->v.x=x; + v->v.y=y; + + i=IteratorNext(i); + } +} + + +void SetTagObject_VERTEX(int tag) +{ + VIDOOM_TRACE; +} + + +void LocateObject_VERTEX(void *obj) +{ + EditVert *v; + + VIDOOM_TRACE; + + v=obj; + + ox=v->v.x-scale*SCRW/2; + oy=v->v.y+scale*SCRH/2; +} + + +void ObjectInsert_VERTEX(void) +{ + Object o; + EditVert *v; + int f; + + VIDOOM_TRACE; + + v=Grab(sizeof(EditVert)); + v->v.x=SnapX(XToMap(ms.x)); + v->v.y=SnapY(YToMap(ms.y)); + v->l=ListNew(sizeof(int)); + + f=MapSize(vertex); + + switch(insert_select) + { + case HOVER_NONE: + o.select=SELECT_NONE; + break; + case HOVER_ADD: + case HOVER_SINGLE: + o.select=SELECT_SELECTED; + break; + } + + o.data=v; + DrawObject_VERTEX(v,o.select); + MapAdd(vertex,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_VERTEX(void) +{ + Iterator i; + Object *o; + EditVert *v; + int *f; + int bound; + + VIDOOM_TRACE; + + i=ListIterator(selected); + bound=FALSE; + + while(i) + { + f=IteratorData(i); + + o=MapElem(vertex,*f); + v=o->data; + + if (ListSize(v->l)) + bound=TRUE; + else + { + Release(o->data); + o->data=NULL; + o->select=SELECT_NONE; + } + + i=IteratorNext(i); + } + + ClearSelection(); + FullRedraw(); + + if (bound) + GuiInfoBox("WARNING","1 or more VERTEX found still bound to LINEDEF|" + "These have not been deleted"); +} + + +void ObjectMenu_VERTEX(void) +{ + Iterator i; + int from; + int to; + int first; + int type; + int flag; + int two; + int wr,wl; + int oxr,oxl; + DirName sr_upper,sr_middle,sr_lower; + DirName sl_upper,sl_middle,sl_lower; + EditVert *v1=NULL,*v2=NULL; + int cancel=FALSE; + int redraw=FALSE; + int in_sector; + int loop; + int nl; + + VIDOOM_TRACE; + + GFX_redraw(); + + switch(GUI_menu("Vertex",ms.x,ms.y,vertex_popup,GUI_CANCEL)) + { + case TM_CHAIN: + cancel=TRUE; + + if (ListSize(selected)<2) + GuiInfoBox("ERROR","Need 2 or more vertices|to chain a line"); + else + { + if (GetLinedefValues(TRUE,0,0,0,0, + &type,&flag,&two, + sr_upper,sr_middle,sr_lower, + sl_upper,sl_middle,sl_lower)) + { + if (ListSize(selected)>2) + loop=YesNo("Join last vertex to first one?"); + else + loop=FALSE; + + oxr=0; + oxl=0; + + wr=CalcTextureWidth(sr_upper,sr_middle,sr_lower); + + if (two) + wl=CalcTextureWidth(sl_upper,sl_middle,sl_lower); + else + wl=0; + + i=ListIterator(selected); + + memcpy(&to,IteratorData(i),sizeof(int)); + i=IteratorNext(i); + first=to; + + while(i) + { + from=to; + memcpy(&to,IteratorData(i),sizeof(int)); + i=IteratorNext(i); + + v1=GETVERT(from); + v2=GETVERT(to); + + in_sector=SectorHoldingPoint(v1->v.x,v1->v.y); + + nl=CreateNewLinedef(from,to, + flag,type,0,two, + oxr,0,in_sector, + sr_upper,sr_middle,sr_lower, + oxl,0,in_sector, + sl_upper,sl_middle,sl_lower); + + IntListUniqAdd(v1->l,nl); + IntListUniqAdd(v2->l,nl); + + if (wr) + oxr=(oxr+Len(v1->v.x,v1->v.y,v2->v.x,v2->v.y))%wr; + + if ((two)&&(wl)) + oxl=(oxl+Len(v1->v.x,v1->v.y,v2->v.x,v2->v.y))%wl; + } + + in_sector=SectorHoldingPoint(v2->v.x,v2->v.y); + + if (loop) + { + v1=GETVERT(to); + v2=GETVERT(first); + + nl=CreateNewLinedef(to,first, + flag,type,0,two, + oxr,0,in_sector, + sr_upper,sr_middle,sr_lower, + oxl,0,in_sector, + sl_upper,sl_middle,sl_lower); + + IntListUniqAdd(v1->l,nl); + IntListUniqAdd(v2->l,nl); + } + + cancel=FALSE; + redraw=TRUE; + + SectorCalcContainingAll(); + } + } + + break; + + case TM_CHAIN_SECTOR: + if (CreateSector(selected)) + redraw=TRUE; + else + cancel=TRUE; + break; + + case TM_MERGE: + if (ListSize(selected)<2) + { + GuiInfoBox("ERROR","Need 2 or more vertices|to merge them"); + cancel=TRUE; + } + else + { + redraw=TRUE; + i=ListIterator(selected); + memcpy(&first,IteratorData(i),sizeof(int)); + i=IteratorNext(i); + + while(i) + { + memcpy(&to,IteratorData(i),sizeof(int)); + MergeVertex(first,to); + i=IteratorNext(i); + } + + SectorCalcContainingAll(); + } + break; + + case TM_SNAP: + { + int orig_lock; + int *f; + EditVert *v; + + orig_lock=grid_lock; + grid_lock=TRUE; + + i=ListIterator(selected); + + while(i) + { + f=IteratorData(i); + v=GETVERT(*f); + + v->v.x=SnapX(v->v.x); + v->v.y=SnapX(v->v.y); + + i=IteratorNext(i); + } + + grid_lock=orig_lock; + redraw=TRUE; + + break; + } + + case TM_DELETE: + ObjectDelete_VERTEX(); + break; + + case TM_MOVE: + MoveObject_VERTEX(); + break; + + default: + cancel=TRUE; + break; + } + + if ((!cancel)&&(clear_on_menu)) + { + ClearSelection(); + FullRedraw(); + } + else if (redraw) + FullRedraw(); +} + + +void ObjectKey_VERTEX(GFXKey k) +{ + int f; + int n; + Object *o; + EditVert *v; + + switch(k.code) + { + case GFX_F12: + ClearSelection(); + n=0; + + for(f=0;f<MapSize(vertex);f++) + { + o=MapElem(vertex,f); + + if (o->data) + { + v=o->data; + + if (ListSize(v->l)==0) + { + ListClear(v->l); + Release(o->data); + o->data=NULL; + n++; + } + } + } + + FullRedraw(); + GFX_redraw(); + + GuiInfoBox("NOTICE","Deleted %d vertices",n); + + break; + + default: + break; + } +} + + +int ObjectHasTag_VERTEX(void *obj, int tag) +{ + return(FALSE); +} + + +ObjDesc *ObjectOverlaid_VERTEX(int x, int y, int *no) +{ + int n; + EditVert *v; + ObjDesc *od; + int f; + + VIDOOM_TRACE; + + od=NULL; + + n=0; + + for(f=0;f<MapSize(vertex);f++) + { + v=GETVERT(f); + + if ((v)&&(PositionOnObject_VERTEX(x,y,v))) + { + n++; + od=ReGrab(od,sizeof(ObjDesc)*n); + od[n-1].no=f; + sprintf(od[n-1].detail,"%5d - %d,%d",f,v->v.x,v->v.y); + } + } + + *no=n; + return(od); +} + + +/* END OF FILE */ |