summaryrefslogtreecommitdiff
path: root/editmrg.c
diff options
context:
space:
mode:
Diffstat (limited to 'editmrg.c')
-rw-r--r--editmrg.c567
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 */