summaryrefslogtreecommitdiff
path: root/edit.c
diff options
context:
space:
mode:
authorIan C <ianc@noddybox.co.uk>2011-06-09 13:46:28 +0000
committerIan C <ianc@noddybox.co.uk>2011-06-09 13:46:28 +0000
commita9022b5972dc49d86f617a27940fafe9c4d0e7e7 (patch)
tree61405aa4ade91ed1057f863ddf118ceb38e14f8e /edit.c
Initial import of (very old) vidoom sources.
Diffstat (limited to 'edit.c')
-rw-r--r--edit.c751
1 files changed, 751 insertions, 0 deletions
diff --git a/edit.c b/edit.c
new file mode 100644
index 0000000..27c700d
--- /dev/null
+++ b/edit.c
@@ -0,0 +1,751 @@
+/*
+
+ 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 main definitions
+
+*/
+static const char rcs_id[]="$Id$";
+
+#include "config.h"
+#include "globals.h"
+
+#include <ctype.h>
+
+#include "edit.h"
+#include "editvar.h"
+
+
+/* ---------------------------------------- EXPORTED FUNCTIONS
+*/
+
+void EditSetScreen(int w,int h)
+{
+ VIDOOM_TRACE;
+
+ SCRW=w;
+ SCRH=h;
+
+ FH=GFX_fh();
+
+ vertex=MapNew(sizeof(Object));
+ linedef=MapNew(sizeof(Object));
+ sidedef=MapNew(sizeof(Object));
+ thing=MapNew(sizeof(Object));
+ sector=MapNew(sizeof(Object));
+ selected=ListNew(sizeof(int));
+}
+
+void EditPreviewWadMap(char *name,WadMap *m)
+{
+ int min_x,min_y,cx,cy,scale;
+ int f;
+ Linedef *l;
+ Vertex *v1,*v2;
+ int done;
+ int redraw;
+ GFXKey key;
+ Thing *t;
+ int vertmode;
+ int linemode;
+ int things;
+
+ VIDOOM_TRACE;
+
+ scale=25;
+ cx=0;
+ cy=0;
+
+ done=FALSE;
+ redraw=TRUE;
+ linemode=TRUE;
+ vertmode=TRUE;
+ things=TRUE;
+
+ while(!done)
+ {
+ if (redraw)
+ {
+ min_x=cx-(SCRW/2)*scale;
+ min_y=cy-(SCRH/2)*scale;
+
+ GFX_clear(BLACK);
+
+ if (things)
+ for(f=0;f<MapSize(m->thing);f++)
+ {
+ t=MapElem(m->thing,f);
+
+ GFX_fcircle((t->x-min_x)/scale,
+ (-t->y-min_y)/scale,8/scale,V_RGB(200,0,0));
+ }
+
+ if (linemode)
+ for(f=0;f<MapSize(m->linedef);f++)
+ {
+ l=MapElem(m->linedef,f);
+ v1=MapElem(m->vertex,l->from);
+ v2=MapElem(m->vertex,l->to);
+
+ GFX_line((v1->x-min_x)/scale,
+ (-v1->y-min_y)/scale,
+ (v2->x-min_x)/scale,
+ (-v2->y-min_y)/scale,GREY(128));
+ }
+
+ if (vertmode)
+ for(f=0;f<MapSize(m->vertex);f++)
+ {
+ v1=MapElem(m->vertex,f);
+
+ GFX_plot((v1->x-min_x)/scale,
+ (-v1->y-min_y)/scale,WHITE);
+ }
+
+ GuiDrawInfoBox("Preview Map",1,1,FALSE,
+ "Map : %s|"
+ "Scale : %d|"
+ "X : %d|"
+ "Y : %d|"
+ "Linedefs : %s|"
+ "Vertexes : %s|"
+ "Things : %s|"
+ " |"
+ "Press F1 for help",name,scale,cx,cy,
+ YESNO(linemode),
+ YESNO(vertmode),
+ YESNO(things));
+
+ GFX_redraw();
+ }
+
+ GFX_waitkey(&key);
+
+ redraw=TRUE;
+
+ switch(key.code)
+ {
+ case GFX_ESC:
+ done=TRUE;
+ break;
+
+ case GFX_DOWN:
+ cy+=scale*(key.shift ? 20 : 1);
+ break;
+
+ case GFX_UP:
+ cy-=scale*(key.shift ? 20 : 1);
+ break;
+
+ case GFX_RIGHT:
+ cx+=scale*(key.shift ? 20 : 1);
+ break;
+
+ case GFX_LEFT:
+ cx-=scale*(key.shift ? 20 : 1);
+ break;
+
+ case GFX_PGUP:
+ if (++scale>32)
+ scale=32;
+ break;
+
+ case GFX_PGDN:
+ if (--scale==0)
+ scale=1;
+ break;
+
+ case GFX_ASCII:
+ switch(toupper(key.ascii))
+ {
+ case 'L':
+ linemode=!linemode;
+ break;
+ case 'V':
+ vertmode=!vertmode;
+ break;
+ case 'T':
+ things=!things;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case GFX_F1:
+ GuiInfoBox("HELP",
+ "Cursor keys - move map|"
+ "Cursor keys + shift - move map quickly|"
+ "Page Down - reduce scale|"
+ "Page Up - increase scale|"
+ "L (toggle) - draw linedefs|"
+ "V (toggle) - draw vertex points|"
+ "T (toggle) - draw things|"
+ "ESC - quit");
+ break;
+
+ default:
+ redraw=FALSE;
+ break;
+ }
+ }
+}
+
+
+void EditLoad(WadMap *map)
+{
+ int f;
+ Vertex *v;
+ Linedef *l;
+ Sector *s;
+ Thing *t;
+ EditVert *ev;
+ EditLine *el;
+ EditSect *es;
+ EditThing *et;
+ Object o;
+ int min_x=0,max_x=0,min_y=0,max_y=0;
+ int find;
+
+ VIDOOM_TRACE;
+
+ scale=MAX(0,MIN(32,default_scale));
+
+ if (MapSize(map->vertex))
+ {
+ min_x=99999;
+ min_y=99999;
+ max_x=-99999;
+ max_y=-99999;
+ find=TRUE;
+ }
+ else
+ {
+ find=FALSE;
+ ox=-scale*SCRW/2;
+ oy=scale*SCRH/2;
+ }
+
+ vertex=MapEmpty(vertex);
+ linedef=MapEmpty(linedef);
+ thing=MapEmpty(thing);
+ sector=MapEmpty(sector);
+ sidedef=MapEmpty(sidedef);
+ selected=ListEmpty(selected);
+
+ mapinfo=map->mapinfo;
+ behavior=map->behavior;
+ behavior_size=map->behavior_size;
+ scripts=map->scripts;
+ scripts_size=map->scripts_size;
+ hexen_mode=map->hexen;
+
+ switch(default_edit_mode)
+ {
+ case EDIT_SECTOR:
+ SetEditMode(SECTOR_MODE);
+ break;
+ case EDIT_VERTEX:
+ SetEditMode(VERTEX_MODE);
+ break;
+ case EDIT_LINEDEF:
+ SetEditMode(LINEDEF_MODE);
+ break;
+ case EDIT_THING:
+ SetEditMode(THING_MODE);
+ break;
+ case EDIT_MULTI:
+ SetEditMode(MULTI_MODE);
+ break;
+ default:
+ SetEditMode(SECTOR_MODE);
+ break;
+ }
+
+ /* Get vertex from WadMap
+ */
+ for(f=0;f<MapSize(map->vertex);f++)
+ {
+ v=MapElem(map->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);
+
+ 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,&o);
+ }
+
+ if (find)
+ {
+ if (min_x==max_y)
+ max_x++;
+
+ if (min_y==max_y)
+ max_y++;
+
+ ox=min_x+(max_x-min_x)/2;
+ oy=min_y+(max_y-min_y)/2;
+
+ ox-=scale*SCRW/2;
+ oy+=scale*SCRH/2;
+ }
+
+ /* Get sidedefs from WadMap
+ */
+ for(f=0;f<MapSize(map->sidedef);f++)
+ {
+ o.select=SELECT_NONE;
+ o.data=Copy(MapElem(map->sidedef,f),sizeof(Sidedef));
+ MapAdd(sidedef,f,&o);
+ }
+
+ /* Get linedefs from WadMap, associated sidedefs, vertex pointers and calc
+ bounding box
+ */
+ for(f=0;f<MapSize(map->linedef);f++)
+ {
+ l=MapElem(map->linedef,f);
+ el=Grab(sizeof(EditLine));
+
+ memcpy(&el->l,l,sizeof(Linedef));
+
+ el->no=f;
+ el->sr=GETSIDE(l->right);
+
+ if (l->left!=-1)
+ el->sl=GETSIDE(l->left);
+ else
+ el->sl=NULL;
+
+ el->v[0]=GETVERT(l->from);
+ el->v[1]=GETVERT(l->to);
+
+ IntListUniqAdd(el->v[0]->l,f);
+ IntListUniqAdd(el->v[1]->l,f);
+
+ LineCalcBounding(el);
+
+ if (hexen_mode)
+ SetHexenLinedefTag(el);
+
+ o.select=SELECT_NONE;
+ o.data=el;
+
+ MapAdd(linedef,f,&o);
+ }
+
+ /* Get sectors from WadMap
+ */
+ for(f=0;f<MapSize(map->sector);f++)
+ {
+ s=MapElem(map->sector,f);
+ es=Grab(sizeof(EditSect));
+
+ memcpy(&es->s,s,sizeof(Sector));
+
+ es->no=f;
+ 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;
+
+ SectorCalcContaining(f,es);
+ SectorCalcBounding(es);
+
+ MapAdd(sector,f,&o);
+ }
+
+ /* Get things from WadMap
+ */
+ for(f=0;f<MapSize(map->thing);f++)
+ {
+ t=MapElem(map->thing,f);
+ et=Grab(sizeof(EditThing));
+ memcpy(&et->t,t,sizeof(Thing));
+ o.select=SELECT_NONE;
+ o.data=et;
+ MapAdd(thing,f,&o);
+ }
+
+ /* Set up multi map if default mode is MULTI mode
+ */
+ if (default_edit_mode==EDIT_MULTI)
+ GenerateMultiMap();
+}
+
+
+void EditSave(WadMap *map)
+{
+ int f;
+ Object *o;
+ EditVert *v;
+ EditThing *t;
+ EditSect *s;
+ EditLine *l;
+
+ VIDOOM_TRACE;
+
+ MapEmpty(map->linedef);
+ MapEmpty(map->sidedef);
+ MapEmpty(map->thing);
+ MapEmpty(map->vertex);
+ MapEmpty(map->sector);
+
+ for(f=0;f<MapSize(vertex);f++)
+ {
+ v=GETVERT(f);
+ MapAdd(map->vertex,f,&(v->v));
+ }
+
+ /* Sidedefs are the only edit object stored fully in DOOM format
+ */
+ for(f=0;f<MapSize(sidedef);f++)
+ {
+ o=MapElem(sidedef,f);
+ MapAdd(map->sidedef,f,o->data);
+ }
+
+ for(f=0;f<MapSize(linedef);f++)
+ {
+ l=GETLINE(f);
+ MapAdd(map->linedef,f,&(l->l));
+ }
+
+ for(f=0;f<MapSize(thing);f++)
+ {
+ t=GETTHING(f);
+ MapAdd(map->thing,f,&(t->t));
+ }
+
+ for(f=0;f<MapSize(sector);f++)
+ {
+ s=GETSECT(f);
+ MapAdd(map->sector,f,&(s->s));
+ }
+
+ map->mapinfo=mapinfo;
+ map->behavior=behavior;
+ map->behavior_size=behavior_size;
+ map->scripts=scripts;
+ map->scripts_size=scripts_size;
+ map->hexen=hexen_mode;
+}
+
+
+void EditLoop(void)
+{
+ GFXEvent ev;
+
+ VIDOOM_TRACE;
+
+ GFX_bounce();
+ FullRedraw();
+ quit=FALSE;
+
+ while(!quit)
+ {
+ GFX_redraw();
+ GFX_await_input_full(&ev);
+
+ new_selection=FALSE;
+
+ switch(ev.type)
+ {
+ case GFX_KEY_EVENT:
+ HandleKey(ev.key);
+ break;
+
+ case GFX_MOUSE_EVENT:
+ HandleMouse(ev.mouse);
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+
+void EditCompact(void)
+{
+ Map new_t,new_v,new_l,new_s,new_si;
+ int f;
+ int r;
+ int i;
+ Object o;
+ Object *oo;
+ EditLine *l;
+ EditSect *s;
+ EditVert *v;
+ Sidedef *side;
+
+ VIDOOM_TRACE;
+
+ ClearSelection();
+
+ new_t=MapNew(sizeof(Object));
+ new_v=MapNew(sizeof(Object));
+ new_l=MapNew(sizeof(Object));
+ new_s=MapNew(sizeof(Object));
+ new_si=MapNew(sizeof(Object));
+
+ /* Compress linedef
+ */
+ i=0;
+ for(f=0;f<MapSize(linedef);f++)
+ {
+ memcpy(&o,MapElem(linedef,f),sizeof(Object));
+
+ if (o.data)
+ MapAdd(new_l,i++,&o);
+ }
+
+ /* Compress things
+ */
+ i=0;
+ for(f=0;f<MapSize(thing);f++)
+ {
+ memcpy(&o,MapElem(thing,f),sizeof(Object));
+
+ if (o.data)
+ MapAdd(new_t,i++,&o);
+ }
+
+ /* Compress sidedef
+ */
+ i=0;
+ for(f=0;f<MapSize(sidedef);f++)
+ if (GETSIDE(f))
+ i++;
+
+ if (i)
+ for(f=MapSize(sidedef)-1;f>=0;f--)
+ {
+ memcpy(&o,MapElem(sidedef,f),sizeof(Object));
+
+ if (o.data)
+ {
+ i--;
+ MapAdd(new_si,i,&o);
+ }
+ else
+ for(r=0;r<MapSize(new_l);r++)
+ {
+ oo=MapElem(new_l,r);
+ l=oo->data;
+
+ if (l->l.left>=f)
+ l->l.left--;
+
+ if (l->l.right>=f)
+ l->l.right--;
+ }
+ }
+
+ /* Compress sectors
+ */
+ i=0;
+ for(f=0;f<MapSize(sector);f++)
+ {
+ s=GETSECT(f);
+
+ if ((s)&&(ListSize(s->all)))
+ i++;
+ }
+
+ for(f=MapSize(sector)-1;f>=0;f--)
+ {
+ memcpy(&o,MapElem(sector,f),sizeof(Object));
+
+ s=o.data;
+
+ if ((o.data)&&(ListSize(s->all)))
+ {
+ i--;
+ MapAdd(new_s,i,&o);
+ }
+ else
+ {
+ if (o.data)
+ Release(o.data);
+
+ for(r=0;r<MapSize(new_si);r++)
+ {
+ side=SIDEFROM(new_si,r);
+
+ if (side->sector>=f)
+ side->sector--;
+ }
+ }
+ }
+
+ /* Compress vertexes (deleting unused ones first)
+ */
+ for(f=0;f<MapSize(vertex);f++)
+ {
+ oo=MapElem(vertex,f);
+
+ if (oo->data)
+ {
+ v=oo->data;
+
+ if (ListSize(v->l)==0)
+ {
+ ListClear(v->l);
+ Release(oo->data);
+ oo->data=NULL;
+ }
+ }
+ }
+
+ i=0;
+ for(f=0;f<MapSize(vertex);f++)
+ if (GETVERT(f))
+ i++;
+
+ if (i)
+ for(f=MapSize(vertex)-1;f>=0;f--)
+ {
+ memcpy(&o,MapElem(vertex,f),sizeof(Object));
+
+ if (o.data)
+ {
+ i--;
+ MapAdd(new_v,i,&o);
+ }
+ else
+ for(r=0;r<MapSize(new_l);r++)
+ {
+ oo=MapElem(new_l,r);
+ l=oo->data;
+
+ if (l->l.from>=f)
+ l->l.from--;
+
+ if (l->l.to>=f)
+ l->l.to--;
+ }
+ }
+
+ for(r=0;r<MapSize(new_l);r++)
+ {
+ oo=MapElem(new_l,r);
+ l=oo->data;
+
+ l->v[0]=VERTFROM(new_v,l->l.from);
+ l->v[1]=VERTFROM(new_v,l->l.to);
+ }
+
+ /* Renumber items that remember their own number
+ */
+ for(f=0;f<MapSize(new_s);f++)
+ {
+ oo=MapElem(new_s,f);
+ s=oo->data;
+ s->no=f;
+ }
+
+ for(f=0;f<MapSize(new_l);f++)
+ {
+ oo=MapElem(new_l,f);
+ l=oo->data;
+ l->no=f;
+ }
+
+ /* Save new maps
+ */
+ MapClear(vertex);
+ MapClear(linedef);
+ MapClear(sector);
+ MapClear(thing);
+ MapClear(sidedef);
+
+ vertex=new_v;
+ linedef=new_l;
+ sector=new_s;
+ thing=new_t;
+ sidedef=new_si;
+
+ /* Reset current edit set
+ */
+ switch(edit_mode)
+ {
+ case SECTOR_MODE:
+ map=sector;
+ break;
+ case LINEDEF_MODE:
+ map=linedef;
+ break;
+ case THING_MODE:
+ map=thing;
+ break;
+ case VERTEX_MODE:
+ map=vertex;
+ break;
+ }
+
+ /* Recalc sidedef pointers in linedefs
+ */
+ for(f=0;f<MapSize(linedef);f++)
+ {
+ l=GETLINE(f);
+
+ if (l->l.left!=-1)
+ l->sl=GETSIDE(l->l.left);
+ else
+ l->sl=NULL;
+
+ if (l->l.right!=-1)
+ l->sr=GETSIDE(l->l.right);
+ else
+ l->sr=NULL;
+ }
+
+ /* Recalc vertex containing lists
+ */
+ for(f=0;f<MapSize(vertex);f++)
+ ListEmpty(GETVERT(f)->l);
+
+ for(f=0;f<MapSize(linedef);f++)
+ {
+ l=GETLINE(f);
+ IntListUniqAdd(l->v[0]->l,f);
+ IntListUniqAdd(l->v[1]->l,f);
+ }
+
+ /* Recalc sector containing values
+ */
+ SectorCalcContainingAll();
+}
+
+
+/* END OF FILE */