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 /editsect.c |
Initial import of (very old) vidoom sources.
Diffstat (limited to 'editsect.c')
-rw-r--r-- | editsect.c | 1735 |
1 files changed, 1735 insertions, 0 deletions
diff --git a/editsect.c b/editsect.c new file mode 100644 index 0000000..3a13300 --- /dev/null +++ b/editsect.c @@ -0,0 +1,1735 @@ +/* + + 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 SECTOR definitions + +*/ +static const char rcs_id[]="$Id$"; + +#include "config.h" +#include "globals.h" +#include "sectors.h" +#include "editvar.h" +#include "gensect.h" +#include "util.h" + +#include <ctype.h> +#include <math.h> + + +/* This is the data shared between the PickPoint() callback functions and the + Create function +*/ +typedef struct + { + int cx; + int cy; + Point p[64]; + int dx; + int dy; + int r; + double ai; + int sides; + } PickData; + +static PickData pick; + +/* This shows which LINEDEFs are drawn tagged +*/ +static List hilite=NULL; + + +/* ---------------------------------------- PickPoint() CALLBACKS +*/ +static void DrawVertSet(int *x, int *y) +{ + double ang; + int dx,dy; + int f; + + VIDOOM_TRACE; + + pick.dx=*x; + pick.dy=*y; + + dx=pick.cx-pick.dx; + dy=pick.cy-pick.dy; + + /* Calc angle that the line is at + */ + if (dx==0) + if (dy<0) + ang=RAD(0); + else + ang=RAD(180); + else if (dy==0) + if (dx<0) + ang=RAD(90); + else + ang=RAD(270); + else + { + ang=atan((double)dx/(double)dy); + + if (dy>0) + ang-=RAD(180); + } + + /* Calc line len + */ + pick.r=Len(pick.cx,pick.cy,pick.dx,pick.dy); + + for(f=0;f<pick.sides;f++) + { + pick.p[f].x=(int)(pick.cx+(pick.r*sin(ang))); + pick.p[f].y=(int)(pick.cy+(pick.r*cos(ang))); + pick.p[f].x=SnapX(pick.p[f].x); + pick.p[f].y=SnapY(pick.p[f].y); + ang+=pick.ai; + } + + for(f=0;f<pick.sides;f++) + GFX_line(MapToX(pick.p[f].x),MapToY(pick.p[f].y), + MapToX(pick.p[(f+1)%pick.sides].x), + MapToY(pick.p[(f+1)%pick.sides].y),WHITE); +} + + +/* ---------------------------------------- GENERATE VERTEX LIST FROM PICKDATA +*/ +static List GenVertList(void) +{ + Object o; + EditVert *v; + List l; + int f,r,n; + int match; + + for(f=0;f<pick.sides;f++) + { + match=TRUE; + + while(match) + for(match=FALSE,r=0;(r<pick.sides)&&(!match);r++) + if (r!=f) + if ((pick.p[r].x==pick.p[f].x)&& + (pick.p[r].y==pick.p[f].y)) + { + for(n=r;n<(pick.sides-1);n++) + { + pick.p[n].x=pick.p[n+1].x; + pick.p[n].y=pick.p[n+1].y; + } + + pick.sides=MAX(pick.sides-1,0); + + match=TRUE; + } + } + + if (pick.sides<3) + return(NULL); + + l=ListNew(sizeof(int)); + + for(f=0;f<pick.sides;f++) + { + v=Grab(sizeof(EditVert)); + v->v.x=pick.p[f].x; + v->v.y=pick.p[f].y; + v->l=ListNew(sizeof(int)); + + n=MapSize(vertex); + + o.select=SELECT_NONE; + o.data=v; + + MapAdd(vertex,n,&o); + ListAppend(l,&n); + } + + return(l); +} + + +/* ---------------------------------------- PRIVATE UTILS +*/ +static int SelectColour(int selmode) +{ + VIDOOM_TRACE; + + switch(selmode) + { + case SELECT_OVER: + return(OVERCOL); + break; + case SELECT_SELECTED: + return(SELCOL); + break; + default: + return(SECTCOL); + break; + } +} + + +void DrawSector(EditSect *s, int col, int check_tag) +{ + Iterator i; + EditLine *l; + + VIDOOM_TRACE; + + i=ListIterator(s->all); + + while(i) + { + memcpy(&l,IteratorData(i),sizeof(l)); + + if (!(check_tag)||(!tag_highlight)||(!InIntList(hilite,l->no))) + MapLineD(l,col); + + i=IteratorNext(i); + } +} + + +static void RemoveHighlights(void) +{ + Iterator i; + Object *o; + EditLine *l; + int *n; + + i=ListIterator(hilite); + + while(i) + { + n=IteratorData(i); + + if ((l=GETLINE(*n))) + { + if (l->sr->sector>=0) + if ((o=MapElem(sector,l->sr->sector))) + DrawSector(o->data,SelectColour(o->select),FALSE); + + if ((l->sl)&&(l->sl->sector>=0)) + if ((o=MapElem(sector,l->sl->sector))) + DrawSector(o->data,SelectColour(o->select),FALSE); + } + + i=IteratorNext(i); + } +} + + +static void SectorSelectionCentre(int *x,int *y) +{ + int *f; + EditSect *s; + 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); + s=GETSECT(*f); + + min_x=MIN(s->min_x,min_x); + min_y=MIN(s->min_y,min_y); + max_x=MAX(s->max_x,max_x); + max_y=MAX(s->max_y,max_y); + + i=IteratorNext(i); + } + + *x=min_x+(max_x-min_x)/2; + *y=min_y+(max_y-min_y)/2; +} + + +/* ---------------------------------------- SECTOR VECTOR MAP UTILS +*/ +static int vno=0; +static char *vmap=NULL; + +static void InitVMAP(void) +{ + if (vno<MapSize(vertex)) + vmap=ReGrab(vmap,MapSize(vertex)); + + memset(vmap,FALSE,MapSize(vertex)); +} + + +/* ---------------------------------------- SECTOR LINEDEF MAP UTILS +*/ +static int lno=0; +static char *lmap=NULL; + +static void InitLMAP(void) +{ + if (lno<MapSize(linedef)) + lmap=ReGrab(lmap,MapSize(linedef)); + + memset(lmap,FALSE,MapSize(linedef)); +} + + +/* ---------------------------------------- SECTOR CONTAINER ROUTINES +*/ + +/* Returns -1 for no sector +*/ +int SectorHoldingPoint(int x,int y) +{ + Object *o; + int f; + + VIDOOM_TRACE; + + for(f=0;f<MapSize(sector);f++) + { + o=MapElem(sector,f); + + if ((o->data)&&(PositionOnObject_SECTOR(x,y,o->data))) + return(f); + } + + return(-1); +} + + +void SectorCalcContaining(int no,EditSect *s) +{ + int f; + EditLine *l; + int match; + + VIDOOM_TRACE; + + ListEmpty(s->v); + ListEmpty(s->sr); + ListEmpty(s->sl); + ListEmpty(s->all); + InitVMAP(); + + for(f=0;f<MapSize(linedef);f++) + { + match=FALSE; + l=GETLINE(f); + + if (l) + { + if ((l->sr)&&(l->sr->sector==no)) + { + ListAppend(s->sr,&l); + ListAppend(s->all,&l); + match=TRUE; + } + + if ((l->sl)&&(l->sl->sector==no)) + { + if (!match) + ListAppend(s->all,&l); + + ListAppend(s->sl,&l); + match=TRUE; + } + + if (match) + { + if (!vmap[l->l.from]) + { + ListAppend(s->v,&(l->l.from)); + vmap[l->l.from]=TRUE; + } + + if (!vmap[l->l.to]) + { + ListAppend(s->v,&(l->l.to)); + vmap[l->l.to]=TRUE; + } + } + } + } +} + + +void SectorCalcContainingAll(void) +{ + int f; + EditSect *s; + + VIDOOM_TRACE; + + for(f=0;f<MapSize(sector);f++) + { + s=GETSECT(f); + SectorCalcContaining(f,s); + } +} + + +/* ---------------------------------------- SECTOR STYLING FUNCS +*/ +static void ApplySectorStyle(EditSect *s, int flag, + DirName upper, DirName middle, DirName lower, + DirName floor, DirName ceiling) +{ + EditLine *l; + List track; + Iterator i,ti; + int ox,tw; + int *n; + + VIDOOM_TRACE; + + tw=CalcTextureWidth(upper,middle,lower); + + InitLMAP(); + + /* Dispose of two-sided linedefs wholly within the sector + */ + i=ListIterator(s->all); + + while(i) + { + memcpy(&l,IteratorData(i),sizeof(l)); + + if ((l->sl)&&(l->sl->sector==s->no)&&(l->sr->sector==s->no)) + lmap[l->no]=TRUE; + + i=IteratorNext(i); + } + + /* Set the floor and ceiling + */ + strcpy(s->s.floor_t,floor); + strcpy(s->s.ceiling_t,ceiling); + + /* Now draw a trail through the linedefs, aligning textures as we go along + */ + i=ListIterator(s->all); + + while(i) + { + memcpy(&l,IteratorData(i),sizeof(l)); + + if (!lmap[l->no]) + { + track=TrackLinedef(l->no); + ox=0; + ti=ListIterator(track); + + while(ti) + { + n=IteratorData(ti); + + l=GETLINE(*n); + + if (((l->sr->sector==s->no)&&(flag&SSTYLE_FACING_IN))|| + ((l->sr->sector!=s->no)&&(flag&SSTYLE_FACING_OUT))) + { + if (strcmp(l->sr->upper,empty_texture)) + { + strcpy(l->sr->upper,upper); + + if (flag&SSTYLE_UPPER_PEG) + l->l.flags|=upper_peg_mask; + else if (!(flag&SSTYLE_LEAVE_PEG)) + l->l.flags&=~upper_peg_mask; + } + + if (strcmp(l->sr->middle,empty_texture)) + strcpy(l->sr->middle,middle); + + if (strcmp(l->sr->lower,empty_texture)) + { + strcpy(l->sr->lower,lower); + + if (flag&SSTYLE_LOWER_PEG) + l->l.flags|=lower_peg_mask; + else if (!(flag&SSTYLE_LEAVE_PEG)) + l->l.flags&=~lower_peg_mask; + } + + l->sr->x=ox; + lmap[l->no]=TRUE; + } + + if ((l->sl)&& + (((l->sl->sector==s->no)&&(flag&SSTYLE_FACING_IN))|| + ((l->sl->sector!=s->no)&&(flag&SSTYLE_FACING_OUT)))) + { + if (strcmp(l->sl->upper,empty_texture)) + { + strcpy(l->sl->upper,upper); + + if (flag&SSTYLE_UPPER_PEG) + l->l.flags|=upper_peg_mask; + else if (!(flag&SSTYLE_LEAVE_PEG)) + l->l.flags&=~upper_peg_mask; + } + + if (strcmp(l->sl->middle,empty_texture)) + strcpy(l->sl->middle,middle); + + if (strcmp(l->sl->lower,empty_texture)) + { + strcpy(l->sl->lower,lower); + + if (flag&SSTYLE_LOWER_PEG) + l->l.flags|=lower_peg_mask; + else if (!(flag&SSTYLE_LEAVE_PEG)) + l->l.flags&=~lower_peg_mask; + } + + l->sl->x=ox; + lmap[l->no]=TRUE; + } + + ox=(ox+Len(l->v[0]->v.x,l->v[0]->v.y, + l->v[1]->v.x,l->v[1]->v.y))%tw; + + ti=IteratorNext(ti); + } + + ListClear(track); + } + + i=IteratorNext(i); + } +} + + +/* ---------------------------------------- GENERIC SECTOR FUNCS +*/ +int PositionOnObject_SECTOR(int x,int y,void *data) +{ + int cross; + EditSect *s; + EditLine *l; + Vertex *vi,*vj; + Iterator i; + + VIDOOM_TRACE; + + s=data; + + if (BOXBOUND(x,y,s->min_x,s->min_y,s->max_x,s->max_y)) + { + cross=FALSE; + + i=ListIterator(s->all); + + while(i) + { + memcpy(&l,IteratorData(i),sizeof(l)); + + /* Linedefs that have a right and left sidedef pointing at the + same sector are not counted + */ + if (!((l->sr)&&(l->sl)&&(l->sl->sector==l->sr->sector))) + { + vi=&(l->v[0]->v); + vj=&(l->v[1]->v); + + /* This code is taken from comp.graphics.algorithms FAQ 2.03 + */ + if ((((vi->y<=y) && (y<vj->y)) || + ((vj->y<=y) && (y<vi->y))) && + (x < (vj->x - vi->x) * (y - vi->y) / + (vj->y - vi->y) + vi->x)) + cross=!cross; + } + + i=IteratorNext(i); + } + + return(cross); + } + else + return(FALSE); +} + + +void SelectBox_SECTOR(int x1,int y1,int x2,int y2) +{ + Object *o; + EditSect *s; + int f; + + VIDOOM_TRACE; + + for(f=0;f<MapSize(sector);f++) + { + o=MapElem(sector,f); + + if ((s=o->data)) + { + if ((o->select!=SELECT_SELECTED)&& + (BOXBOUND(s->min_x,s->min_y,x1,y1,x2,y2))&& + (BOXBOUND(s->max_x,s->max_y,x1,y1,x2,y2))) + { + SetSelect(f,SELECT_SELECTED); + ListAppend(selected,&f); + } + } + } +} + + +void SelectByType_SECTOR(void) +{ + Object *o; + EditSect *s; + int id; + int f; + + if ((id=SelectSector(hexen_mode))!=SECTOR_NULLID) + { + ClearSelection(); + + for(f=0;f<MapSize(sector);f++) + if ((o=MapElem(sector,f))) + if ((s=o->data)&&(s->s.special==id)) + { + SetSelect(f,SELECT_SELECTED); + ListAppend(selected,&f); + } + } +} + + +void DrawObject_SECTOR(void *data, int selmode) +{ + static int drawn=FALSE; + Object *o; + EditSect *s; + EditLine *l; + int sel; + int f; + + VIDOOM_TRACE; + + if (!hilite) + hilite=ListNew(sizeof(int)); + + s=data; + + /* If the current object has changed, remove the highlighted tag objects + */ + if ((current==-1)&&(drawn)) + { + drawn=FALSE; + RemoveHighlights(); + ListEmpty(hilite); + } + + /* Draw tagged linedefs + */ + if ((tag_highlight)&&(current==s->no)) + { + RemoveHighlights(); + ListEmpty(hilite); + + if (s->s.tag) + { + drawn=TRUE; + + for(f=0;f<MapSize(linedef);f++) + if ((l=GETLINE(f))) + if ((l->l.tag==s->s.tag)&&(LineOnDisplay(l))) + { + sel=FALSE; + + if (l->sr->sector>=0) + if ((o=MapElem(sector,l->sr->sector))) + sel=(o->select!=SELECT_NONE); + + if ((l->sl)&&(l->sl->sector>=0)) + if ((o=MapElem(sector,l->sl->sector))) + sel|=(o->select!=SELECT_NONE); + + if (!sel) + { + IntListUniqAdd(hilite,f); + MapLineD(l,TAGCOL); + } + } + } + + } + + DrawSector(s,SelectColour(selmode),TRUE); +} + + +void DrawObjectInfo_SECTOR(void) +{ + EditSect *s; + + VIDOOM_TRACE; + + if (!draw_current_info) + return; + + if ((current!=-1)&&((s=GETSECT(current)))) + { + if (GenSectName(hexen_mode,s->s.special,SectorName)) + GuiDrawInfoBox("SECTOR",GUI_FLUSH_LEFT,GUI_FLUSH_LOWER,FALSE, + "Sector Number : %-5d|" + "Floor : %-5d|" + "Ceiling : %-5d|" + "Height : %-5d|" + "Light : %-5d|" + "Floor texture : %-10s|" + "Ceiling texture : %-10s|" + "Sector Type : %-30.30s[Gen]|" + "Tag : %-5d", + current, + s->s.floor, + s->s.ceiling, + s->s.ceiling-s->s.floor, + s->s.light, + s->s.floor_t, + s->s.ceiling_t, + GenSectName(hexen_mode, + s->s. + special,SectorName), + s->s.tag); + else + GuiDrawInfoBox("SECTOR",GUI_FLUSH_LEFT,GUI_FLUSH_LOWER,FALSE, + "Sector Number : %-5d|" + "Floor : %-5d|" + "Ceiling : %-5d|" + "Height : %-5d|" + "Light : %-5d|" + "Floor texture : %-10s|" + "Ceiling texture : %-10s|" + "Sector Type : %-35.35s|" + "Tag : %-5d", + current, + s->s.floor, + s->s.ceiling, + s->s.ceiling-s->s.floor, + s->s.light, + s->s.floor_t, + s->s.ceiling_t, + SectorName(hexen_mode,s->s.special), + s->s.tag); + } + else + GuiDrawInfoBox("SECTOR",GUI_FLUSH_LEFT,GUI_FLUSH_LOWER,FALSE, + "Sector Number : -|" + "Floor : -|" + "Ceiling : -|" + "Height : -|" + "Light : -|" + "Floor texture : -|" + "Ceiling texture : -|" + "Sector Type : %-35s|" + "Tag : -","-"); +} + + +void DrawObjectHeader_SECTOR(void) +{ + if (tag_highlight) + GFX_print(0,FH,WHITE,"Tag highlight: ON"); + else + GFX_print(0,FH,WHITE,"Tag highlight: OFF"); + + switch(sector_move) + { + case MOVE_ALL: + GFX_print(SCRW/2,FH,WHITE,"Move mode: ALL"); + break; + case MOVE_LEFT: + GFX_print(SCRW/2,FH,WHITE,"Move mode: LEFT"); + break; + case MOVE_RIGHT: + GFX_print(SCRW/2,FH,WHITE,"Move mode: RIGHT"); + break; + } +} + + +void MoveObject_SECTOR(void) +{ + GFXEvent ev; + int omx,omy; + int dmx,dmy; + int done; + Iterator i; + Iterator i2; + EditSect *s; + EditLine *l; + EditVert *v; + List orig; + int *f; + Point p; + List vert; + int cancel; + + VIDOOM_TRACE; + + omx=SnapX(XToMap(ms.x)); + omy=SnapY(YToMap(ms.y)); + GFX_bounce(); + + done=FALSE; + cancel=FALSE; + orig=ListNew(sizeof(Point)); + vert=ListNew(sizeof(EditVert *)); + + InitVMAP(); + + i=ListIterator(selected); + + while(i) + { + f=IteratorData(i); + s=GETSECT(*f); + + switch(sector_move) + { + case MOVE_ALL: + i2=ListIterator(s->all); + break; + + case MOVE_LEFT: + i2=ListIterator(s->sl); + break; + + case MOVE_RIGHT: + default: + i2=ListIterator(s->sr); + break; + } + + while(i2) + { + memcpy(&l,IteratorData(i2),sizeof(l)); + + if (!vmap[l->l.from]) + { + v=GETVERT(l->l.from); + ListAppend(vert,&v); + p.x=l->v[0]->v.x; + p.y=l->v[0]->v.y; + ListAppend(orig,&p); + vmap[l->l.from]=TRUE; + } + + if (!vmap[l->l.to]) + { + v=GETVERT(l->l.to); + ListAppend(vert,&v); + p.x=l->v[1]->v.x; + p.y=l->v[1]->v.y; + ListAppend(orig,&p); + vmap[l->l.to]=TRUE; + } + + i2=IteratorNext(i2); + } + + i=IteratorNext(i); + } + + while(!done) + { + GuiDrawInfoBox("Move SECTOR",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(vert); + i2=ListIterator(orig); + + while(i2) + { + memcpy(&v,IteratorData(i),sizeof(v)); + + memcpy(&p,IteratorData(i2),sizeof(Point)); + v->v.x=p.x; + v->v.y=p.y; + + i2=IteratorNext(i2); + i=IteratorNext(i); + } + + 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(vert); + while(i) + { + memcpy(&v,IteratorData(i),sizeof(v)); + + v->v.x+=dmx; + v->v.y+=dmy; + + i=IteratorNext(i); + } + + omx=SnapX(XToMap(ms.x)); + omy=SnapY(YToMap(ms.y)); + + FullRedraw(); + } + } + + ListClear(orig); + ListClear(vert); + + if ((clear_on_move)&&(!cancel)) + ClearSelection(); + + FullRedraw(); +} + + +void RotateObject_SECTOR(double angle) +{ + int cx,cy; + int x,y; + int *f; + Short *r; + Iterator i,i2; + EditSect *s; + EditVert *v; + + VIDOOM_TRACE; + + InitVMAP(); + + SectorSelectionCentre(&cx,&cy); + + i=ListIterator(selected); + + while(i) + { + f=IteratorData(i); + s=GETSECT(*f); + + i2=ListIterator(s->v); + + while(i2) + { + r=IteratorData(i2); + v=GETVERT(*r); + + if (!vmap[*r]) + { + vmap[*r]=TRUE; + + x=v->v.x; + y=v->v.y; + + Rotate(cx,cy,&x,&y,angle); + + v->v.x=x; + v->v.y=y; + } + + i2=IteratorNext(i2); + } + + i=IteratorNext(i); + } +} + + +void ScaleObject_SECTOR(double scale) +{ + int cx,cy; + int x,y; + int *f; + Short *r; + Iterator i,i2; + EditSect *s; + EditVert *v; + + VIDOOM_TRACE; + + InitVMAP(); + + SectorSelectionCentre(&cx,&cy); + + i=ListIterator(selected); + + while(i) + { + f=IteratorData(i); + s=GETSECT(*f); + + i2=ListIterator(s->v); + + while(i2) + { + r=IteratorData(i2); + v=GETVERT(*r); + + if (!vmap[*r]) + { + vmap[*r]=TRUE; + + x=v->v.x; + y=v->v.y; + + Scale(cx,cy,&x,&y,scale); + + v->v.x=x; + v->v.y=y; + } + + i2=IteratorNext(i2); + } + + i=IteratorNext(i); + } +} + + +void SetTagObject_SECTOR(int tag) +{ + int *f; + Iterator i; + EditSect *s; + + VIDOOM_TRACE; + + i=ListIterator(selected); + + while(i) + { + f=IteratorData(i); + s=GETSECT(*f); + s->s.tag=tag; + i=IteratorNext(i); + } +} + + +void LocateObject_SECTOR(void *obj) +{ + int cx,cy; + EditSect *s; + + VIDOOM_TRACE; + + s=obj; + cx=s->min_x+(s->max_x-s->min_x)/2; + cy=s->min_y+(s->max_y-s->min_y)/2; + ox=cx-scale*SCRW/2; + oy=cy+scale*SCRH/2; +} + + +void ObjectInsert_SECTOR(void) +{ +# define SM_UNBOUND 1 +# define SM_POLY 2 + + static PLAT_MENU sector_insert_menu[]= + { + {"Create unbound sector",SM_UNBOUND}, + {"Create polygon",SM_POLY}, + {NULL,GUI_CANCEL} + }; + + VIDOOM_TRACE; + + switch(GUI_menu("Sector",ms.x,ms.y,sector_insert_menu,GUI_CANCEL)) + { + case SM_UNBOUND: + { + int sec; + + sec=CreateUnboundSector(normal_sector,default_floor_height, + default_ceiling_height,default_light_level, + 0,empty_texture,empty_texture); + + GuiInfoBox("NOTICE","A sector number %d has been created.|" + "SIDEDEFS will have to bound to the sector " + "before it|becomes visible and editable.",sec); + break; + } + + case SM_POLY: + { + static int last_sides=4; + List sel; + + nosides_dialog[D_NOSIDES].data.i=last_sides; + + if (GUI_dialog("Create sector",D_NOSIDES_NO,nosides_dialog)) + { + pick.sides=nosides_dialog[D_NOSIDES].data.i; + + if ((pick.sides<3)||(pick.sides>64)) + { + GuiInfoBox("ERROR","Only enter a value between 3 and 64"); + break; + } + else + if (PickPoint("Select centre of new sector", + &pick.cx,&pick.cy,NULL,NULL,NULL)) + { + pick.ai=RAD(360.0/pick.sides); + + if (PickPoint("Select the width and rotation " + "of the sector",&pick.dx,&pick.dy, + DrawVertSet,NULL,NULL)) + { + /* Merge identical vertices from the list and + check that the vertices will not be dubious + */ + if ((sel=GenVertList())) + { + if (!CreateSector(sel)) + { + Iterator i; + Object *o; + EditVert *v; + int *n; + + i=ListIterator(sel); + + while(i) + { + n=IteratorData(i); + o=MapElem(vertex,*n); + v=o->data; + + ListClear(v->l); + Release(v); + o->data=NULL; + + i=IteratorNext(i); + } + } + else + { + FullRedraw(); + last_sides=pick.sides; + } + + ListClear(sel); + } + else + { + GuiInfoBox("ERROR","Shape makes no sense"); + FullRedraw(); + break; + } + } + } + } + + break; + } + + default: + break; + } +} + + +void ObjectDelete_SECTOR(void) +{ + VIDOOM_TRACE; + + GuiInfoBox("NOTICE","Sector cannot be deleted| |" + "Sectors are automatically deleted|" + "when saving the map if no LINEDEFs|" + "are bound to it."); +} + + +void ObjectMenu_SECTOR(void) +{ + Iterator i; + EditSect *s; + int *f; + int cancel; + + VIDOOM_TRACE; + + cancel=FALSE; + + switch(GUI_menu("Sector",ms.x,ms.y,sector_popup,GUI_CANCEL)) + { + case TM_FLOOR: + s=SelHead(); + sector_fl_dialog[D_SECTOR_FLOOR].data.i=s->s.floor; + + if (GUI_dialog("Floor height",D_SECTOR_FL_NO,sector_fl_dialog)) + { + i=ListIterator(selected); + + while(i) + { + f=IteratorData(i); + s=GETSECT(*f); + s->s.floor=sector_fl_dialog[D_SECTOR_FLOOR].data.i; + i=IteratorNext(i); + } + + i=IteratorClear(i); + FullRedraw(); + } + break; + + case TM_CEILING: + s=SelHead(); + sector_ce_dialog[D_SECTOR_CEILING].data.i=s->s.ceiling; + + if (GUI_dialog("Ceiling height",D_SECTOR_CE_NO,sector_ce_dialog)) + { + i=ListIterator(selected); + + while(i) + { + f=IteratorData(i); + s=GETSECT(*f); + s->s.ceiling=sector_ce_dialog[D_SECTOR_CEILING].data.i; + i=IteratorNext(i); + } + + i=IteratorClear(i); + FullRedraw(); + } + break; + + case TM_LIGHT: + { + int sweep; + + s=SelHead(); + + if (ListSize(selected)<3) + sweep=FALSE; + else + sweep=YesNo("%d sectors selected. Do lighting sweep?", + ListSize(selected)); + + if (!sweep) + { + sector_li_dialog[D_SECTOR_LIGHT].data.i=s->s.light; + + if (GUI_dialog("Light level",D_SECTOR_LI_NO,sector_li_dialog)) + { + i=ListIterator(selected); + + sector_li_dialog[D_SECTOR_LIGHT].data.i= + MIN(255,MAX(sector_li_dialog[D_SECTOR_LIGHT].data.i,0)); + + while(i) + { + f=IteratorData(i); + s=GETSECT(*f); + s->s.light=sector_li_dialog[D_SECTOR_LIGHT].data.i; + i=IteratorNext(i); + } + + i=IteratorClear(i); + FullRedraw(); + } + } + else + { + static int min=0; + static int max=255; + static int bounce=FALSE; + int t_min=0,t_max=0; + int start; + int inc; + int ok; + int valid; + + start=s->s.light; + + l_range_dialog[D_L_RANGE_START].data.i=start; + l_range_dialog[D_L_RANGE_MIN].data.i=min; + l_range_dialog[D_L_RANGE_MAX].data.i=max; + + if (start<128) + { + inc=(int)((double)(max-start)/ + (double)(ListSize(selected)-2)+0.5); + + if (inc==0) + inc=SGN(max-start); + } + else + { + inc=(int)((double)(min-start)/ + (double)(ListSize(selected)-2)+0.5); + + if (inc==0) + inc=SGN(min-start); + } + + l_range_dialog[D_L_RANGE_INC].data.i=inc; + SET_YESNO_DIAL(l_range_dialog[D_L_RANGE_PULSE],bounce); + + do { + if ((ok=GUI_dialog("Lighting sweep", + D_L_RANGE_NO,l_range_dialog))) + { + inc=l_range_dialog[D_L_RANGE_INC].data.i; + start=l_range_dialog[D_L_RANGE_START].data.i; + t_min=l_range_dialog[D_L_RANGE_MIN].data.i; + t_max=l_range_dialog[D_L_RANGE_MAX].data.i; + + valid=FALSE; + + if ((t_min<0)||(t_min>255)||(t_max<0)|| + (t_max>255)||(start<0)||(start>255)) + GuiInfoBox("ERROR","Light levels must be|" + "in range 0 to 255"); + else if ((t_min>=t_max)||(t_max<=t_min)) + GuiInfoBox("ERROR","min and max make no sense"); + else if (ABS(inc)>(t_max-t_min)) + GuiInfoBox("ERROR", + "There must be enough inbetween|" + "min and max for the adjustment"); + else if ((start<t_min)||(start>t_max)) + GuiInfoBox("ERROR", + "Start must inbetween min and max"); + else + valid=TRUE; + } + else + valid=TRUE; + + } while((ok)&&(!valid)); + + if (ok) + { + min=t_min; + max=t_max; + bounce=l_range_dialog[D_L_RANGE_PULSE].data.pl.current; + + i=ListIterator(selected); + + while(i) + { + f=IteratorData(i); + s=GETSECT(*f); + s->s.light=start; + + start+=inc; + + start=MIN(start,max); + start=MAX(start,min); + + if (((start==min)||(start==max))&&(bounce)) + inc=-inc; + + i=IteratorNext(i); + } + + i=IteratorClear(i); + FullRedraw(); + } + } + + break; + } + + case TM_TAG: + s=SelHead(); + tag_dialog[D_TAG].data.i=s->s.tag; + + if (GUI_dialog("Tag",D_TAG_NO,tag_dialog)) + { + i=ListIterator(selected); + + while(i) + { + f=IteratorData(i); + s=GETSECT(*f); + s->s.tag=tag_dialog[D_TAG].data.i; + i=IteratorNext(i); + } + + i=IteratorClear(i); + FullRedraw(); + } + break; + + case TM_FLOOR_T: + { + DirName d; + + if ((GetFlat("Floor texture",d))) + { + i=ListIterator(selected); + + while(i) + { + f=IteratorData(i); + s=GETSECT(*f); + strcpy(s->s.floor_t,d); + i=IteratorNext(i); + } + + FullRedraw(); + } + + break; + } + + case TM_CEILING_T: + { + DirName d; + + if ((GetFlat("Ceiling texture",d))) + { + i=ListIterator(selected); + + while(i) + { + f=IteratorData(i); + s=GETSECT(*f); + strcpy(s->s.ceiling_t,d); + i=IteratorNext(i); + } + + FullRedraw(); + } + + break; + } + + case TM_TYPE: + { + int id; + + id=SelectSector(hexen_mode); + + if (id!=SECTOR_NULLID) + { + i=ListIterator(selected); + + while(i) + { + f=IteratorData(i); + s=GETSECT(*f); + s->s.special=id; + i=IteratorNext(i); + } + + FullRedraw(); + } + break; + } + + case TM_GEN_TYPE: + if (GenSectNoClasses(hexen_mode)) + { + int id; + + s=SelHead(); + id=SelectGenSect(hexen_mode,s->s.special); + + if (id!=GENSECT_NULLID) + { + i=ListIterator(selected); + + while(i) + { + f=IteratorData(i); + s=GETSECT(*f); + s->s.special=id; + i=IteratorNext(i); + } + + FullRedraw(); + } + } + else + GuiInfoBox("ERROR","No generalised sectors defined|in config"); + break; + + case TM_VAL: + { + static int id; + + if (GetNumber("Enter SECTOR type",&id)) + { + i=ListIterator(selected); + + while(i) + { + f=IteratorData(i); + s=GETSECT(*f); + s->s.special=id; + i=IteratorNext(i); + } + + FullRedraw(); + } + } + break; + + case TM_STYLE: + { + int flag; + DirName upper,middle,lower,floor,ceiling; + + if (ChooseSectorStyle(&flag,upper,middle,lower,floor,ceiling)) + { + i=ListIterator(selected); + + while(i) + { + f=IteratorData(i); + s=GETSECT(*f); + ApplySectorStyle(s,flag,upper,middle,lower,floor,ceiling); + i=IteratorNext(i); + } + } + + break; + } + + case TM_MOVE: + MoveObject_SECTOR(); + break; + + case TM_DELETE: + ObjectDelete_SECTOR(); + break; + + default: + cancel=TRUE; + break; + } + + if ((!cancel)&&(clear_on_menu)) + { + ClearSelection(); + FullRedraw(); + } +} + + +void ObjectKey_SECTOR(GFXKey k) +{ + Iterator i; + EditSect *s; + int tmpsel; + int *f; + + /* Check keys that need no objects + */ + if (k.code==GFX_ASCII) + switch(toupper(k.ascii)) + { + case 'H': + tag_highlight=!tag_highlight; + FullRedraw(); + break; + + case 'M': + if (sector_move==MOVE_ALL) + sector_move=MOVE_RIGHT; + else if (sector_move==MOVE_RIGHT) + sector_move=MOVE_LEFT; + else if (sector_move==MOVE_LEFT) + sector_move=MOVE_ALL; + + DrawHeader(); + GFX_redraw(); + break; + + default: + break; + } + + tmpsel=TmpAddCurrent(); + + if (ListSize(selected)==0) + return; + + if (k.code!=GFX_ASCII) + switch(k.code) + { + default: + break; + } + else + { + i=ListIterator(selected); + + while(i) + { + f=IteratorData(i); + s=GETSECT(*f); + + switch(toupper(k.ascii)) + { + case ',': + s->s.floor-=8; + if (s->s.floor>s->s.ceiling) + s->s.floor+=8; + break; + + case '.': + s->s.floor+=8; + if (s->s.floor>s->s.ceiling) + s->s.floor-=8; + break; + + case '<': + s->s.ceiling-=8; + if (s->s.ceiling<s->s.floor) + s->s.ceiling+=8; + break; + + case '>': + s->s.ceiling+=8; + if (s->s.ceiling<s->s.floor) + s->s.ceiling-=8; + break; + + case '-': + s->s.light=MAX(0,s->s.light-16); + break; + + case '+': + s->s.light=MIN(255,s->s.light+16); + break; + + default: + break; + } + + i=IteratorNext(i); + } + + FullRedraw(); + } + + if (tmpsel) + ListEmpty(selected); +} + + +int ObjectHasTag_SECTOR(void *obj, int tag) +{ + EditSect *s; + + return ((s=obj)&&(s->s.tag==tag)); +} + + +ObjDesc *ObjectOverlaid_SECTOR(int x, int y, int *no) +{ + int n; + EditSect *s; + ObjDesc *od; + int f; + + VIDOOM_TRACE; + + od=NULL; + + n=0; + + for(f=0;f<MapSize(sector);f++) + { + s=GETSECT(f); + + if ((s)&&(PositionOnObject_SECTOR(x,y,s))) + { + n++; + od=ReGrab(od,sizeof(ObjDesc)*n); + od[n-1].no=f; + + sprintf(od[n-1].detail,"%5d - %s (Tag %d)",f, + TrimStr(SectorName + (hexen_mode,s->s.special),50), + s->s.tag); + } + } + + *no=n; + return(od); +} + + +/* END OF FILE */ |