/* 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 #include "edit.h" #include "editvar.h" /* ---------------------------------------- EXPORTED FUNCTIONS */ void EditSetScreen(int w,int h) { 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; 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;fthing);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;flinedef);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;fvertex);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; 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); 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;fvertex);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;fsidedef);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;flinedef);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); o.select=SELECT_NONE; o.data=el; MapAdd(linedef,f,&o); } /* Get sectors from WadMap */ for(f=0;fsector);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;fthing);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; TRACE; MapEmpty(map->linedef); MapEmpty(map->sidedef); MapEmpty(map->thing); MapEmpty(map->vertex); MapEmpty(map->sector); for(f=0;fvertex,f,&(v->v)); } /* Sidedefs are the only edit object stored fully in DOOM format */ for(f=0;fsidedef,f,o->data); } for(f=0;flinedef,f,&(l->l)); } for(f=0;fthing,f,&(t->t)); } for(f=0;fsector,f,&(s->s)); } } void EditLoop(void) { GFXEvent ev; 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; 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=0;f--) { memcpy(&o,MapElem(sidedef,f),sizeof(Object)); if (o.data) { i--; MapAdd(new_si,i,&o); } else for(r=0;rdata; if (l->l.left>=f) l->l.left--; if (l->l.right>=f) l->l.right--; } } /* Compress sectors */ i=0; for(f=0;fall))) 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;rsector>=f) side->sector--; } } } /* Compress vertexes (deleting unused ones first) */ for(f=0;fdata) { v=oo->data; if (ListSize(v->l)==0) { ListClear(v->l); Release(oo->data); oo->data=NULL; } } } i=0; for(f=0;f=0;f--) { memcpy(&o,MapElem(vertex,f),sizeof(Object)); if (o.data) { i--; MapAdd(new_v,i,&o); } else for(r=0;rdata; if (l->l.from>=f) l->l.from--; if (l->l.to>=f) l->l.to--; } } for(r=0;rdata; 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;fdata; s->no=f; } for(f=0;fdata; 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;fl.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;fl); for(f=0;fv[0]->l,f); IntListUniqAdd(l->v[1]->l,f); } /* Recalc sector containing values */ SectorCalcContainingAll(); } /* END OF FILE */