diff options
Diffstat (limited to 'editmrg.c')
-rw-r--r-- | editmrg.c | 567 |
1 files changed, 567 insertions, 0 deletions
diff --git a/editmrg.c b/editmrg.c new file mode 100644 index 0000000..7aaa10b --- /dev/null +++ b/editmrg.c @@ -0,0 +1,567 @@ +/* + + 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 + + ------------------------------------------------------------------------- + + Merging of WAD maps + +*/ +static const char rcs_id[]="$Id$"; + +#include "config.h" +#include "globals.h" +#include "editvar.h" +#include "gui.h" +#include "wad.h" + + +/* ---------------------------------------- LOCAL DATA +*/ +static WadMap *wad; +static int min_x; +static int min_y; +static int max_x; +static int max_y; +static int cx; +static int cy; +static int ang; + + +/* ---------------------------------------- CO-ORD FUNCS +*/ +static void MergeCoord(int *x, int *y) +{ + if (ang) + { + Rotate(min_x,min_y,x,y,(double)ang); + + *x=cx-min_x+(*x); + *y=cy-min_y+(*y); + } + else + { + *x=cx-min_x+(*x); + *y=cy-min_y+(*y); + } +} + +/* ---------------------------------------- PickPoint() CALLBACKS +*/ +static void PickDraw(int *x,int *y) +{ + Map lm,vm; + Linedef *l; + Vertex *v1,*v2; + int x1,y1,x2,y2; + int f; + + cx=*x=SnapX(*x); + cy=*y=SnapY(*y); + + lm=wad->linedef; + vm=wad->vertex; + + for(f=0;f<MapSize(lm);f++) + { + l=MapElem(lm,f); + + v1=MapElem(vm,l->from); + v2=MapElem(vm,l->to); + + x1=v1->x; + y1=v1->y; + MergeCoord(&x1,&y1); + x1=MapToX(x1); + y1=MapToY(y1); + + x2=v2->x; + y2=v2->y; + MergeCoord(&x2,&y2); + x2=MapToX(x2); + y2=MapToY(y2); + + GFX_line(x1,y1,x2,y2,WHITE); + } +} + + +static void PickKey(GFXKey k) +{ + TRACE; + + if (k.code==GFX_ASCII) + switch(k.ascii) + { + case '.': + if (--ang<0) + ang=359; + break; + + case ',': + ang=(ang+1)%360; + break; + + case '>': + if ((ang-=10)<0) + ang+=360; + break; + + case '<': + ang=(ang+10)%360; + break; + + default: + break; + } +} + + +static void PickInfo(char *p) +{ + TRACE; + + GuiDrawInfoBox(p,GUI_FLUSH_RIGHT,GUI_FLUSH_LOWER,FALSE,"Angle : %3d|",ang); + + GuiDrawInfoBox(p,GUI_FLUSH_LEFT,GUI_FLUSH_LOWER,FALSE, + ", - rotate left 1 deg |" + ". - rotate right 1 deg |" + "< - rotate left 10 deg |" + "> - rotate right 10 deg|" + " |" + "Press left button to complete. ESC to cancel"); +} + + +/* ---------------------------------------- WAD MERGEING +*/ +void MergeWad(void) +{ + Object o; + Linedef *l; + Sector *s=NULL; + Thing *t; + Vertex *v; + Sidedef *si; + EditVert *ev; + EditLine *el; + EditSect *es; + EditThing *et; + char *name; + int f; + int unbound; + int n_thing; + int n_line; + int n_side; + int n_vert; + int n_sect; + int n_tag; + int tmp_wad; + char *tmp_n; + char *wadf; + int *secmap; + int x,y; + + if (level_style==DOOM_2_LEVELS) + tmp_n="MAP01"; + else + tmp_n="E1M1"; + + if ((tmp_wad=YesNo("Load a new PWAD and read %s from it?",tmp_n))) + { + if (!(wadf=GUI_fsel("Pick PWAD to merge map from",PWAD_dir,".WAD"))) + return; + + if (AddPWAD(wadf)!=WAD_OK) + { + GuiInfoBox("ERROR","AddPWAD(%s): %s",wadf,WadErrorString()); + FullRedraw(); + Release(wadf); + return; + } + + name=tmp_n; + } + else + { + wadf=NULL; + + if (!(name=GuiPickLevel("Pick map to merge"))) + return; + } + + GuiDrawInfoBox("Loading...",GUI_CENTRE,GUI_CENTRE,TRUE, + "Loading level %s",name); + if (!(wad=LoadMap(name))) + { + GuiInfoBox("ERROR","LoadMap(%s): %s",name,WadErrorString()); + FullRedraw(); + + if (tmp_wad) + { + if (CloseWad(wadf)!=WAD_OK) + GuiInfoBox("ERROR","CloseWad(%s)|%s",wadf,WadErrorString()); + + Release(wadf); + } + + return; + } + + if (MapSize(wad->linedef)==0) + { + GuiInfoBox("ERROR","No LINEDEFS in %s",name); + ClearMap(wad); + FullRedraw(); + + if (tmp_wad) + { + if (CloseWad(wadf)!=WAD_OK) + GuiInfoBox("ERROR","CloseWad(%s)|%s",wadf,WadErrorString()); + + Release(wadf); + } + + return; + } + + FullRedraw(); + + /* Get top left hand corner of map and see if there are unbound left + sidedefs + */ + ang=0; + min_x=99999; + min_y=99999; + max_x=-99999; + max_y=-99999; + + for(f=0;f<MapSize(wad->vertex);f++) + { + v=MapElem(wad->vertex,f); + + min_x=MIN(min_x,v->x); + min_y=MIN(min_y,v->y); + + max_x=MAX(max_x,v->x); + max_y=MAX(max_y,v->y); + } + + min_x=min_x+(max_x-min_x)/2; + min_y=min_y+(max_y-min_y)/2; + + unbound=FALSE; + + for(f=0;(f<MapSize(wad->linedef))&&(!unbound);f++) + { + l=MapElem(wad->linedef,f); + + if (l->left!=-1) + { + si=MapElem(wad->sidedef,l->left); + + if (si->sector==-1) + unbound=TRUE; + } + } + + /* Position + */ + if (!PickPoint("Position MAP",&cx,&cy,PickDraw,PickKey,PickInfo)) + { + ClearMap(wad); + + if (tmp_wad) + { + if (CloseWad(wadf)!=WAD_OK) + GuiInfoBox("ERROR","CloseWad(%s)|%s",wadf,WadErrorString()); + + Release(wadf); + } + + return; + } + + /* Adjust co-ords + */ + for(f=0;f<MapSize(wad->vertex);f++) + { + v=MapElem(wad->vertex,f); + x=v->x; + y=v->y; + MergeCoord(&x,&y); + v->x=x; + v->y=y; + } + + for(f=0;f<MapSize(wad->thing);f++) + { + t=MapElem(wad->thing,f); + x=t->x; + y=t->y; + MergeCoord(&x,&y); + t->x=x; + t->y=y; + } + + /* If the map is a structure with some unbound left sidedefs, calculate + which sectors the new linedefs appear in (taken from the line's + midpoint) + */ + if (unbound) + { + Vertex *v1,*v2; + int lcx,lcy; + + secmap=Grab(sizeof(int)*MapSize(wad->linedef)); + + for(f=0;f<MapSize(wad->linedef);f++) + { + l=MapElem(wad->linedef,f); + + v1=MapElem(wad->vertex,l->from); + v2=MapElem(wad->vertex,l->to); + + lcx=v1->x+((v2->x-v1->x)/2); + lcy=v1->y+((v2->y-v1->y)/2); + + secmap[f]=SectorHoldingPoint(lcx,lcy); + } + + /* See if floor and ceilings shold be adjusted + */ + if (YesNo("Adjust structure floor heights?")) + { + int t,min,diff; + + if ((t=SectorHoldingPoint(cx,cy))!=-1) + es=GETSECT(t); + else + es=NULL; + + if (es) + { + min=99999; + + for(f=0;f<MapSize(wad->sector);f++) + { + s=MapElem(wad->sector,f); + + if (min>s->floor) + min=s->floor; + } + + diff=min-es->s.floor; + + for(f=0;f<MapSize(wad->sector);f++) + { + s=MapElem(wad->sector,f); + s->floor-=diff; + s->ceiling-=diff; + } + } + } + + if (YesNo("Adjust structure ceiling heights?")) + { + int t; + + if ((t=SectorHoldingPoint(cx,cy))!=-1) + es=GETSECT(t); + else + es=NULL; + + if (es) + for(f=0;f<MapSize(wad->sector);f++) + { + s=MapElem(wad->sector,f); + + if ((s->ceiling!=es->s.ceiling)&&(s->floor<es->s.ceiling)) + s->ceiling=es->s.ceiling; + } + } + } + else + secmap=NULL; + + /* Renumber tags? + */ + n_tag=0; + + if (YesNo("Renumber tags?")) + { + for(f=0;f<MapSize(linedef);f++) + if ((el=GETLINE(f))) + n_tag=MAX(n_tag,el->l.tag); + + for(f=0;f<MapSize(sector);f++) + if ((es=GETSECT(f))) + n_tag=MAX(n_tag,es->s.tag); + } + + n_thing=MapSize(thing); + n_line=MapSize(linedef); + n_side=MapSize(sidedef); + n_sect=MapSize(sector); + n_vert=MapSize(vertex); + + /* Insert vertexes + */ + for(f=0;f<MapSize(wad->vertex);f++) + { + v=MapElem(wad->vertex,f); + + ev=Grab(sizeof(EditVert)); + memcpy(&ev->v,v,sizeof(Vertex)); + ev->l=ListNew(sizeof(int)); + + o.select=SELECT_NONE; + o.data=ev; + + MapAdd(vertex,f+n_vert,&o); + } + + /* Insert sidedefs + */ + for(f=0;f<MapSize(wad->sidedef);f++) + { + o.select=SELECT_NONE; + si=o.data=Copy(MapElem(wad->sidedef,f),sizeof(Sidedef)); + + if (si->sector!=-1) + si->sector+=n_sect; + + MapAdd(sidedef,f+n_side,&o); + } + + /* Insert linedefs and get associated sidedefs, vertex pointers and calc + bounding box + */ + for(f=0;f<MapSize(wad->linedef);f++) + { + l=MapElem(wad->linedef,f); + el=Grab(sizeof(EditLine)); + + memcpy(&el->l,l,sizeof(Linedef)); + + if (el->l.tag) + el->l.tag+=n_tag; + + el->l.from+=n_vert; + el->l.to+=n_vert; + + el->l.right+=n_side; + + if (el->l.left!=-1) + el->l.left+=n_side; + + el->no=f+n_line; + el->sr=GETSIDE(el->l.right); + + if (l->left!=-1) + { + el->sl=GETSIDE(el->l.left); + + if ((unbound)&&(el->sl->sector==-1)) + el->sl->sector=secmap[f]; + } + else + el->sl=NULL; + + el->v[0]=GETVERT(el->l.from); + el->v[1]=GETVERT(el->l.to); + + IntListUniqAdd(el->v[0]->l,f+n_line); + IntListUniqAdd(el->v[1]->l,f+n_line); + + LineCalcBounding(el); + + o.select=SELECT_NONE; + o.data=el; + + MapAdd(linedef,f+n_line,&o); + } + + /* Insert sectors + */ + for(f=0;f<MapSize(wad->sector);f++) + { + s=MapElem(wad->sector,f); + es=Grab(sizeof(EditSect)); + + memcpy(&es->s,s,sizeof(Sector)); + + es->no=f+n_sect; + + if (es->s.tag) + es->s.tag+=n_tag; + + es->v=ListNew(sizeof(Short)); + es->sr=ListNew(sizeof(EditLine *)); + es->sl=ListNew(sizeof(EditLine *)); + es->all=ListNew(sizeof(EditLine *)); + + o.select=SELECT_NONE; + o.data=es; + + MapAdd(sector,f+n_sect,&o); + } + + /* Insert things + */ + for(f=0;f<MapSize(wad->thing);f++) + { + t=MapElem(wad->thing,f); + et=Grab(sizeof(EditThing)); + memcpy(&et->t,t,sizeof(Thing)); + o.select=SELECT_NONE; + o.data=et; + MapAdd(thing,f+n_thing,&o); + } + + SectorCalcContainingAll(); + + GuiInfoBox("NOTICE","Vertexes adjusted by %d|" + "Linedefs adjusted by %d|" + "Sidedefs adjusted by %d|" + "Sectors adjusted by %d|" + "Things adjusted by %d|" + "Tags adjusted by %d", + n_vert,n_line,n_side,n_sect,n_thing,n_tag); + + FullRedraw(); + + /* Tidy up + */ + ClearMap(wad); + + if (unbound) + Release(secmap); + + if (tmp_wad) + { + if (CloseWad(wadf)!=WAD_OK) + GuiInfoBox("ERROR","CloseWad(%s)|%s",wadf,WadErrorString()); + + Release(wadf); + } +} + + +/* END OF FILE */ |