home *** CD-ROM | disk | FTP | other *** search
- /* savebsp.m */
-
- #include "idbsp.h"
-
- /*
- id secstore_i;
- id mapvertexstore_i;
- id subsecstore_i;
- id maplinestore_i;
- id nodestore_i;
- id mapthingstore_i;
- id ldefstore_i;
- id sdefstore_i;
- */
-
- STORAGE *secstore_i;
- STORAGE *mapvertexstore_i;
- STORAGE *subsecstore_i;
- STORAGE *maplinestore_i;
- STORAGE *nodestore_i;
- STORAGE *mapthingstore_i;
- STORAGE *ldefstore_i;
- STORAGE *sdefstore_i;
-
- /*
- ===============================================================================
-
- the output functions byte swap and write lumps
-
- ===============================================================================
- */
-
-
- /*
- ================
- =
- = WriteStorage
- =
- ================
- */
-
- /*void WriteStorage (char *name, id store, int esize) */
- void WriteStorage(char *name, STORAGE *store, int esize)
- {
- int count, len;
-
- /* count = [store count]; */
- count = store->count;
- len = esize*count;
- /* [wad_i addName: name data:[store elementAt:0] size:len]; */
- addName(name, store->data, len);
- printf ("%s (%i): %i\n",name,count,len);
- }
-
-
- /*
- =================
- =
- = OutputSectors
- =
- =================
- */
-
- void OutputSectors (void)
- {
- int i, count;
- mapsector_t *p;
- /*
- count = [secstore_i count];
- p = [secstore_i elementAt:0];
- */
- count = secstore_i->count;
- p = secstore_i->data;
-
- /*
- for (i=0 ; i<count ; i++, p++)
- {
- p->floorheight = SHORT(p->floorheight);
- p->ceilingheight = SHORT(p->ceilingheight);
- p->lightlevel = SHORT(p->lightlevel);
- p->special = SHORT(p->special);
- p->tag = SHORT(p->tag);
- }
- */
-
- WriteStorage ("sectors", secstore_i, sizeof(mapsector_t));
- }
-
-
- /*
- =================
- =
- = OutputSegs
- =
- =================
- */
-
- void OutputSegs (void)
- {
- int i, count;
- mapseg_t *p;
- /*
- count = [maplinestore_i count];
- p = [maplinestore_i elementAt:0];
- */
- count = maplinestore_i->count;
- p = maplinestore_i->data;
- /*
- for (i=0 ; i<count ; i++, p++)
- {
- p->v1 = SHORT(p->v1);
- p->v2 = SHORT(p->v2);
- p->angle = SHORT(p->angle);
- p->linedef = SHORT(p->linedef);
- p->side = SHORT(p->side);
- p->offset = SHORT(p->offset);
- }
- */
- WriteStorage ("segs",maplinestore_i, sizeof(mapseg_t));
- }
-
-
- /*
- =================
- =
- = OutputSubsectors
- =
- =================
- */
-
- void OutputSubsectors (void)
- {
- int i, count;
- mapsubsector_t *p;
- /*
- count = [subsecstore_i count];
- p = [subsecstore_i elementAt:0];
- */
- count = subsecstore_i->count;
- p = subsecstore_i->data;
- /*
- for (i=0 ; i<count ; i++, p++)
- {
- p->numsegs = SHORT(p->numsegs);
- p->firstseg = SHORT(p->firstseg);
- }
- */
- WriteStorage ("ssectors", subsecstore_i, sizeof(mapsubsector_t));
- }
-
-
- /*
- =================
- =
- = OutputVertexes
- =
- =================
- */
-
- void OutputVertexes (void)
- {
- int i, count;
- mapvertex_t *p;
- /*
- count = [mapvertexstore_i count];
- p = [mapvertexstore_i elementAt:0];
- */
- count = mapvertexstore_i->count;
- p = mapvertexstore_i->data;
- /*
- for (i=0 ; i<count ; i++, p++)
- {
- p->x = SHORT(p->x);
- p->y = SHORT(p->y);
- }
- */
- WriteStorage ("vertexes",mapvertexstore_i, sizeof(mapvertex_t));
- }
-
-
- /*
- =================
- =
- = OutputThings
- =
- =================
- */
-
- void OutputThings (void)
- {
- int i, count;
- mapthing_t *p;
- /*
- count = [mapthingstore_i count];
- p = [mapthingstore_i elementAt:0];
- */
- count = mapthingstore_i->count;
- p = mapthingstore_i->data;
- /*
- for (i=0 ; i<count ; i++, p++)
- {
- p->x = SHORT(p->x);
- p->y = SHORT(p->y);
- p->angle = SHORT(p->angle);
- p->type = SHORT(p->type);
- p->options = SHORT(p->options);
- }
- */
- WriteStorage ("things", mapthingstore_i, sizeof(mapthing_t));
- }
-
-
- /*
- =================
- =
- = OutputLineDefs
- =
- =================
- */
-
- void OutputLineDefs (void)
- {
- int i, count;
- maplinedef_t *p;
- /*
- count = [ldefstore_i count];
- p = [ldefstore_i elementAt:0];
- */
- count = ldefstore_i->count;
- p = ldefstore_i->data;
- #if 0
- for (i=0 ; i<count ; i++, p++)
- {
- p->v1 = SHORT(p->v1);
- p->v2 = SHORT(p->v2);
- /* some ancient version of DoomEd left ML_MAPPED flags in some of the levels */
- p->flags = SHORT(p->flags&~ML_MAPPED);
- p->special = SHORT(p->special);
- p->tag = SHORT(p->tag);
- p->sidenum[0] = SHORT(p->sidenum[0]);
- p->sidenum[1] = SHORT(p->sidenum[1]);
- }
- #endif
- WriteStorage ("linedefs", ldefstore_i, sizeof(maplinedef_t));
- }
-
-
- /*
- =================
- =
- = OutputSideDefs
- =
- =================
- */
-
- void OutputSideDefs (void)
- {
- int i, count;
- mapsidedef_t *p;
- /*
- count = [sdefstore_i count];
- p = [sdefstore_i elementAt:0];
- */
- count = sdefstore_i->count;
- p = sdefstore_i->data;
- /*
- for (i=0 ; i<count ; i++, p++)
- {
- p->textureoffset = SHORT(p->textureoffset);
- p->rowoffset = SHORT(p->rowoffset);
- p->sector = SHORT(p->sector);
- }
- */
- WriteStorage ("sidedefs", sdefstore_i, sizeof(mapsidedef_t));
- }
-
-
- /*
- =================
- =
- = OutputNodes
- =
- =================
- */
-
- void OutputNodes (void)
- {
- int i, j, count;
- mapnode_t *p;
- /*
- count = [nodestore_i count];
- p = [nodestore_i elementAt:0];
- */
- count = nodestore_i->count;
- p = nodestore_i->data;
- /*
- for (i=0 ; i<count ; i++, p++)
- {
- for (j=0 ; j<sizeof(mapnode_t)/2 ; j++)
- ((short *)p)[j] = SHORT(((short *)p)[j]);
- }
- */
- WriteStorage ("nodes", nodestore_i, sizeof(mapnode_t));
- }
-
-
- /*
- ===============================================================================
-
- PROCESSING
-
- ===============================================================================
- */
-
-
- /*
- =================
- =
- = UniqueVertex
- =
- = Returns the vertex number, adding a new vertex if needed
- =================
- */
-
- int UniqueVertex (int x, int y)
- {
- int i, count;
- mapvertex_t mv, *mvp;
-
- mv.x = x;
- mv.y = y;
-
- /* see if an identical vertex already exists */
- /*
- count = [mapvertexstore_i count];
- mvp = [mapvertexstore_i elementAt:0];
- */
- count = mapvertexstore_i->count;
- mvp = mapvertexstore_i->data;
- for (i=0 ; i<count ; i++, mvp++)
- if (mvp->x == mv.x && mvp->y == mv.y)
- return i;
-
- /* [mapvertexstore_i addElement: &mv]; */
- memcpy((mapvertex_t *)mapvertexstore_i->data + mapvertexstore_i->count, &mv,
- sizeof(mapvertex_t));
- mapvertexstore_i->count += 1;
- mapvertexstore_i->data = (mapvertex_t *)realloc(mapvertexstore_i->data,
- sizeof(mapvertex_t) * (mapvertexstore_i->count + 1));
-
- return count;
- }
-
-
- /*
- =============================================================================
- */
-
- float bbox[4];
-
- /*
- =================
- =
- = AddPointToBBox
- =
- =================
- */
-
- void AddPointToBBox (NXPoint *pt)
- {
- if (pt->x < bbox[BOXLEFT])
- bbox[BOXLEFT] = pt->x;
- if (pt->x > bbox[BOXRIGHT])
- bbox[BOXRIGHT] = pt->x;
-
- if (pt->y > bbox[BOXTOP])
- bbox[BOXTOP] = pt->y;
- if (pt->y < bbox[BOXBOTTOM])
- bbox[BOXBOTTOM] = pt->y;
- }
-
-
- /*
- =================
- =
- = ProcessLines
- =
- = Adds the lines in a subsector to the mapline storage
- =================
- */
-
- /* void ProcessLines (id store_i) */
- void ProcessLines(STORAGE *store_i)
- {
- int i,count;
- line_t *wline;
- mapseg_t line;
- short angle;
- float fangle;
-
- bbox[BOXLEFT] = INT_MAX;
- bbox[BOXRIGHT] = INT_MIN;
- bbox[BOXTOP] = INT_MIN;
- bbox[BOXBOTTOM] = INT_MAX;
-
- /* count = [store_i count]; */
- count = store_i->count;
- for (i=0 ; i<count ; i++)
- {
- /* wline = [store_i elementAt: i]; */
- wline = (line_t *)store_i->data + i;
- if (wline->grouped)
- printf ("ERROR: line regrouped\n");
- wline->grouped = true;
-
- memset (&line, 0, sizeof(line));
- AddPointToBBox (&wline->p1);
- AddPointToBBox (&wline->p2);
- line.v1 = UniqueVertex (wline->p1.x, wline->p1.y);
- line.v2 = UniqueVertex (wline->p2.x, wline->p2.y);
- line.linedef = wline->linedef;
- line.side = wline->side;
- line.offset = wline->offset;
- fangle = atan2 (wline->p2.y - wline->p1.y, wline->p2.x - wline->p1.x);
- angle = (short)(fangle/(PI*2)*0x10000);
- line.angle = angle;
- /* [maplinestore_i addElement: &line]; */
- memcpy((mapseg_t *)maplinestore_i->data + maplinestore_i->count, &line,
- sizeof(line));
- maplinestore_i->count += 1;
- maplinestore_i->data = (mapseg_t *)realloc(maplinestore_i->data,
- sizeof(mapseg_t) * (maplinestore_i->count + 1));
- }
- }
-
-
- /*
- =================
- =
- = ProcessSubsector
- =
- =================
- */
-
- /* int ProcessSubsector (id wmaplinestore_i) */
- int ProcessSubsector(STORAGE *wmaplinestore_i)
- {
- int count;
- worldline_t *linedef;
- line_t *wline;
- mapsubsector_t sub;
-
- memset (&sub,0,sizeof(sub));
-
- /* count = [wmaplinestore_i count]; */
- count = wmaplinestore_i->count;
- if (count < 1)
- Error ("ProcessSubsector: count = %i",count);
-
- /* wline = [wmaplinestore_i elementAt: 0]; */
- wline = wmaplinestore_i->data;
-
- /* linedef = [linestore_i elementAt: wline->linedef]; */
- linedef = (worldline_t *)linestore_i->data + wline->linedef;
- sub.numsegs = count;
- /* sub.firstseg = [maplinestore_i count]; */
- sub.firstseg = maplinestore_i->count;
- ProcessLines (wmaplinestore_i);
-
- /* add the new subsector
- [subsecstore_i addElement: &sub];
- */
- memcpy((mapsubsector_t *)subsecstore_i->data + subsecstore_i->count, &sub,
- sizeof(mapsubsector_t));
- subsecstore_i->count += 1;
- subsecstore_i->data = (mapsubsector_t *)realloc(subsecstore_i->data,
- sizeof(mapsubsector_t) * (subsecstore_i->count + 1));
-
- /* return [subsecstore_i count]-1; */
- return subsecstore_i->count - 1;
- }
-
- /*
- =================
- =
- = ProcessNode
- =
- =================
- */
-
- int ProcessNode (bspnode_t *node, short *totalbox)
- {
- short subbox[2][4];
- int i, r;
- mapnode_t mnode;
-
- memset (&mnode,0,sizeof(mnode));
-
- if (node->lines_i) /* NF_SUBSECTOR flags a subsector */
- {
- r = ProcessSubsector (node->lines_i);
- for (i=0 ; i<4 ; i++)
- totalbox[i] = bbox[i];
- return r | NF_SUBSECTOR;
- }
-
- mnode.x =node->divline.pt.x;
- mnode.y =node->divline.pt.y;
- mnode.dx =node->divline.dx;
- mnode.dy =node->divline.dy;
-
- r = ProcessNode(node->side[0], subbox[0]);
- mnode.children[0] =r;
- for (i=0 ; i<4 ; i++)
- mnode.bbox[0][i] =subbox[0][i];
-
- r = ProcessNode (node->side[1],subbox[1]);
- mnode.children[1] =r;
- for (i=0 ; i<4 ; i++)
- mnode.bbox[1][i] =subbox[1][i];
-
- totalbox[BOXLEFT] = MIN(subbox[0][BOXLEFT], subbox[1][BOXLEFT]);
- totalbox[BOXTOP] = MAX(subbox[0][BOXTOP], subbox[1][BOXTOP]);
- totalbox[BOXRIGHT] = MAX(subbox[0][BOXRIGHT], subbox[1][BOXRIGHT]);
- totalbox[BOXBOTTOM] = MIN(subbox[0][BOXBOTTOM], subbox[1][BOXBOTTOM]);
-
- /* [nodestore_i addElement: &mnode]; */
- memcpy((mapnode_t *)nodestore_i->data + nodestore_i->count, &mnode, sizeof(mapnode_t));
- nodestore_i->count += 1;
- nodestore_i->data = (mapnode_t *)realloc(nodestore_i->data,
- sizeof(mapnode_t) * (nodestore_i->count + 1));
-
- /* return [nodestore_i count] - 1; */
- return nodestore_i->count - 1;
- }
-
-
- /*
- =================
- =
- = ProcessNodes
- =
- = Recursively builds the nodes, subsectors, and line lists,
- = then writes the lumps
- =================
- */
-
- void ProcessNodes (void)
- {
- short worldbounds[4];
- /*
- subsecstore_i = [[Storage alloc]
- initCount: 0
- elementSize: sizeof(mapsubsector_t)
- description: NULL];
- maplinestore_i = [[Storage alloc]
- initCount: 0
- elementSize: sizeof(mapseg_t)
- description: NULL];
- nodestore_i = [[Storage alloc]
- initCount: 0
- elementSize: sizeof(mapnode_t)
- description: NULL];
- */
- subsecstore_i = (STORAGE *)SafeMalloc(sizeof(STORAGE));
- subsecstore_i->data = (mapsubsector_t *)SafeMalloc(sizeof(mapsubsector_t));
- subsecstore_i->count = 0;
- subsecstore_i->size = sizeof(mapsubsector_t);
-
- maplinestore_i = (STORAGE *)SafeMalloc(sizeof(STORAGE));
- maplinestore_i->data = (mapseg_t *)SafeMalloc(sizeof(mapseg_t));
- maplinestore_i->count = 0;
- maplinestore_i->size = sizeof(mapseg_t);
-
- nodestore_i = (STORAGE *)SafeMalloc(sizeof(STORAGE));
- nodestore_i->data = (mapnode_t *)SafeMalloc(sizeof(mapnode_t));
- nodestore_i->count = 0;
- nodestore_i->size = sizeof(mapnode_t);
-
- ProcessNode (startnode, worldbounds);
-
- }
-
-
- /*
- =================
- =
- = ProcessThings
- =
- =================
- */
-
- void ProcessThings (void)
- {
- worldthing_t *wt;
- mapthing_t mt;
- int count;
-
- /*
- mapthingstore_i = [[Storage alloc]
- initCount: 0
- elementSize: sizeof(mapthing_t)
- description: NULL];
- */
- mapthingstore_i = (STORAGE *)SafeMalloc(sizeof(STORAGE));
- mapthingstore_i->data = (mapthing_t *)SafeMalloc(sizeof(mapthing_t));
- mapthingstore_i->count = 0;
- mapthingstore_i->size = sizeof(mapthing_t);
-
- /*
- count = [thingstore_i count];
- wt = [thingstore_i elementAt: 0];
- */
- count = thingstore_i->count;
- wt = thingstore_i->data;
- while (count--)
- {
- memset (&mt,0,sizeof(mt));
- mt.x =wt->origin.x;
- mt.y =wt->origin.y;
- mt.angle =wt->angle;
- mt.type =wt->type;
- mt.options =wt->options;
- /* [mapthingstore_i addElement: &mt]; */
- memcpy((mapthing_t *)mapthingstore_i->data + mapthingstore_i->count, &mt,
- sizeof(mapthing_t));
- mapthingstore_i->count += 1;
- mapthingstore_i->data = (mapthing_t *)realloc(mapthingstore_i->data,
- sizeof(mapthing_t) * (mapthingstore_i->count + 1));
- wt++;
- }
-
- }
-
- /*
- =============================================================================
- */
-
- /*
- ==================
- =
- = ProcessSidedef
- =
- ==================
- */
-
- int ProcessSidedef (worldside_t *ws)
- {
- mapsidedef_t ms;
-
- ms.textureoffset = ws->firstcollumn;
- ms.rowoffset = ws->firstrow;
- memcpy (ms.toptexture, ws->toptexture, 8);
- memcpy (ms.bottomtexture, ws->bottomtexture, 8);
- memcpy (ms.midtexture, ws->midtexture, 8);
- ms.sector = ws->sector;
-
- /* [sdefstore_i addElement: &ms]; */
- memcpy((mapsidedef_t *)sdefstore_i->data + sdefstore_i->count, &ms, sizeof(mapsidedef_t));
- sdefstore_i->count += 1;
- sdefstore_i->data = (mapsidedef_t *)realloc(sdefstore_i->data,
- sizeof(mapsidedef_t) * (sdefstore_i->count + 1));
-
- /* return [sdefstore_i count]-1; */
- return sdefstore_i->count - 1;
- }
-
- /*
- ==================
- =
- = ProcessLineSideDefs
- =
- = Must be called after BuildSectors
- ==================
- */
-
- void ProcessLineSideDefs (void)
- {
- int i, count;
- maplinedef_t ld;
- worldline_t *wl;
- /*
- mapvertexstore_i = [[Storage alloc]
- initCount: 0
- elementSize: sizeof(mapvertex_t)
- description: NULL];
- ldefstore_i = [[Storage alloc]
- initCount: 0
- elementSize: sizeof(maplinedef_t)
- description: NULL];
- sdefstore_i = [[Storage alloc]
- initCount: 0
- elementSize: sizeof(mapsidedef_t)
- description: NULL];
- */
- mapvertexstore_i = (STORAGE *)SafeMalloc(sizeof(STORAGE));
- mapvertexstore_i->data = (mapvertex_t *)SafeMalloc(sizeof(mapvertex_t));
- mapvertexstore_i->count = 0;
- mapvertexstore_i->size = sizeof(mapvertex_t);
-
- ldefstore_i = (STORAGE *)SafeMalloc(sizeof(STORAGE));
- ldefstore_i->data = (maplinedef_t *)SafeMalloc(sizeof(maplinedef_t));
- ldefstore_i->count = 0;
- ldefstore_i->size = sizeof(maplinedef_t);
-
- sdefstore_i = (STORAGE *)SafeMalloc(sizeof(STORAGE));
- sdefstore_i->data = (mapsidedef_t *)SafeMalloc(sizeof(mapsidedef_t));
- sdefstore_i->count = 0;
- sdefstore_i->size = sizeof(mapsidedef_t);
-
- /*
- count = [linestore_i count];
- wl = [linestore_i elementAt:0];
- */
- count = linestore_i->count;
- wl = linestore_i->data;
- for (i=0 ; i<count ; i++, wl++)
- {
- ld.v1 = UniqueVertex(wl->p1.x,wl->p1.y);
- ld.v2 =UniqueVertex(wl->p2.x,wl->p2.y);
- ld.flags =wl->flags;
- ld.special =wl->special;
- ld.tag =wl->tag;
- ld.sidenum[0] =ProcessSidedef(&wl->side[0]);
- if (wl->flags & ML_TWOSIDED)
- ld.sidenum[1] =ProcessSidedef(&wl->side[1]);
- else
- ld.sidenum[1] =-1;
- /* [ldefstore_i addElement: &ld]; */
-
- memcpy((maplinedef_t *)ldefstore_i->data + ldefstore_i->count, &ld, sizeof(maplinedef_t));
- ldefstore_i->count += 1;
- ldefstore_i->data = (maplinedef_t *)realloc(ldefstore_i->data,
- sizeof(maplinedef_t) * (ldefstore_i->count + 1));
- }
-
- }
-
- /*
- =============================================================================
- */
-
- /*
- ==================
- =
- = SaveDoomMap
- =
- ==================
- */
-
- void SaveDoomMap (void)
- {
- printf("\nBuildSectordefs\n");
- BuildSectordefs ();
-
- printf("ProcessThings\n");
- ProcessThings ();
-
- printf("ProcessLineSideDefs\n");
- ProcessLineSideDefs ();
-
- printf("ProcessNodes\n");
- ProcessNodes ();
-
- printf("ProcessSectors\n");
- ProcessSectors ();
-
- printf("\nProcessConnections\n");
- ProcessConnections ();
-
- /* all processing is complete, write everything out */
- OutputThings ();
- OutputLineDefs ();
- OutputSideDefs ();
- OutputVertexes ();
- OutputSegs ();
- OutputSubsectors ();
- OutputNodes ();
- OutputSectors ();
- OutputConnections ();
- }
-