home *** CD-ROM | disk | FTP | other *** search
/ Doom 2 Explosion / Doom2Explosion.bin / doom2exp / programs / ibsp101s / savebsp.c < prev    next >
C/C++ Source or Header  |  1994-07-10  |  19KB  |  809 lines

  1. /* savebsp.m */
  2.  
  3. #include "idbsp.h"
  4.  
  5. /*
  6.    id              secstore_i;
  7.    id              mapvertexstore_i;
  8.    id              subsecstore_i;
  9.    id              maplinestore_i;
  10.    id              nodestore_i;
  11.    id              mapthingstore_i;
  12.    id              ldefstore_i;
  13.    id              sdefstore_i;
  14.  */
  15.  
  16. STORAGE            *secstore_i;
  17. STORAGE            *mapvertexstore_i;
  18. STORAGE            *subsecstore_i;
  19. STORAGE            *maplinestore_i;
  20. STORAGE            *nodestore_i;
  21. STORAGE            *mapthingstore_i;
  22. STORAGE            *ldefstore_i;
  23. STORAGE            *sdefstore_i;
  24.  
  25. /*
  26.    ===============================================================================
  27.  
  28.    the output functions byte swap and write lumps
  29.  
  30.    ===============================================================================
  31.  */
  32.  
  33.  
  34. /*
  35.    ================
  36.    =
  37.    = WriteStorage
  38.    =
  39.    ================
  40.  */
  41.  
  42. /*void WriteStorage (char *name, id store, int esize) */
  43. void                WriteStorage(char *name, STORAGE * store, int esize)
  44. {
  45.     int                 count,
  46.                         len;
  47.  
  48. /*      count = [store count]; */
  49.     count = store -> count;
  50.     len = esize * count;
  51. /*      [wad_i addName: name data:[store elementAt:0] size:len]; */
  52.     addName(name, store -> data, len);
  53.     printf("%s (%i): %i\n", name, count, len);
  54. }
  55.  
  56.  
  57. /*
  58.    =================
  59.    =
  60.    = OutputSectors
  61.    =
  62.    =================
  63.  */
  64.  
  65. void                OutputSectors(void)
  66. {
  67.     int                 i,
  68.                         count;
  69.     mapsector_t        *p;
  70.  
  71. /*
  72.    count = [secstore_i count];
  73.    p = [secstore_i elementAt:0];
  74.  */
  75.     count = secstore_i -> count;
  76.     p = secstore_i -> data;
  77.  
  78. /*
  79.    for (i=0 ; i<count ; i++, p++)
  80.    {
  81.    p->floorheight = SHORT(p->floorheight);
  82.    p->ceilingheight = SHORT(p->ceilingheight);
  83.    p->lightlevel = SHORT(p->lightlevel);
  84.    p->special = SHORT(p->special);
  85.    p->tag = SHORT(p->tag);
  86.    }
  87.  */
  88.  
  89.     WriteStorage("sectors", secstore_i, sizeof(mapsector_t));
  90. }
  91.  
  92.  
  93. /*
  94.    =================
  95.    =
  96.    = OutputSegs
  97.    =
  98.    =================
  99.  */
  100.  
  101. void                OutputSegs(void)
  102. {
  103.     int                 i,
  104.                         count;
  105.     mapseg_t           *p;
  106.  
  107. /*
  108.    count = [maplinestore_i count];
  109.    p = [maplinestore_i elementAt:0];
  110.  */
  111.     count = maplinestore_i -> count;
  112.     p = maplinestore_i -> data;
  113. /*
  114.    for (i=0 ; i<count ; i++, p++)
  115.    {
  116.    p->v1 = SHORT(p->v1);
  117.    p->v2 = SHORT(p->v2);
  118.    p->angle = SHORT(p->angle);
  119.    p->linedef = SHORT(p->linedef);
  120.    p->side = SHORT(p->side);
  121.    p->offset = SHORT(p->offset);
  122.    }
  123.  */
  124.     WriteStorage("segs", maplinestore_i, sizeof(mapseg_t));
  125. }
  126.  
  127.  
  128. /*
  129.    =================
  130.    =
  131.    = OutputSubsectors
  132.    =
  133.    =================
  134.  */
  135.  
  136. void                OutputSubsectors(void)
  137. {
  138.     int                 i,
  139.                         count;
  140.     mapsubsector_t     *p;
  141.  
  142. /*
  143.    count = [subsecstore_i count];
  144.    p = [subsecstore_i elementAt:0];
  145.  */
  146.     count = subsecstore_i -> count;
  147.     p = subsecstore_i -> data;
  148. /*
  149.    for (i=0 ; i<count ; i++, p++)
  150.    {
  151.    p->numsegs = SHORT(p->numsegs);
  152.    p->firstseg = SHORT(p->firstseg);
  153.    }
  154.  */
  155.     WriteStorage("ssectors", subsecstore_i, sizeof(mapsubsector_t));
  156. }
  157.  
  158.  
  159. /*
  160.    =================
  161.    =
  162.    = OutputVertexes
  163.    =
  164.    =================
  165.  */
  166.  
  167. void                OutputVertexes(void)
  168. {
  169.     int                 i,
  170.                         count;
  171.     mapvertex_t        *p;
  172.  
  173. /*
  174.    count = [mapvertexstore_i count];
  175.    p = [mapvertexstore_i elementAt:0];
  176.  */
  177.     count = mapvertexstore_i -> count;
  178.     p = mapvertexstore_i -> data;
  179. /*
  180.    for (i=0 ; i<count ; i++, p++)
  181.    {
  182.    p->x = SHORT(p->x);
  183.    p->y = SHORT(p->y);
  184.    }
  185.  */
  186.     WriteStorage("vertexes", mapvertexstore_i, sizeof(mapvertex_t));
  187. }
  188.  
  189.  
  190. /*
  191.    =================
  192.    =
  193.    = OutputThings
  194.    =
  195.    =================
  196.  */
  197.  
  198. void                OutputThings(void)
  199. {
  200.     int                 i,
  201.                         count;
  202.     mapthing_t         *p;
  203.  
  204. /*
  205.    count = [mapthingstore_i count];
  206.    p = [mapthingstore_i elementAt:0];
  207.  */
  208.     count = mapthingstore_i -> count;
  209.     p = mapthingstore_i -> data;
  210. /*
  211.    for (i=0 ; i<count ; i++, p++)
  212.    {
  213.    p->x = SHORT(p->x);
  214.    p->y = SHORT(p->y);
  215.    p->angle = SHORT(p->angle);
  216.    p->type = SHORT(p->type);
  217.    p->options = SHORT(p->options);
  218.    }
  219.  */
  220.     WriteStorage("things", mapthingstore_i, sizeof(mapthing_t));
  221. }
  222.  
  223.  
  224. /*
  225.    =================
  226.    =
  227.    = OutputLineDefs
  228.    =
  229.    =================
  230.  */
  231.  
  232. void                OutputLineDefs(void)
  233. {
  234.     int                 i,
  235.                         count;
  236.     maplinedef_t       *p;
  237.  
  238. /*
  239.    count = [ldefstore_i count];
  240.    p = [ldefstore_i elementAt:0];
  241.  */
  242.     count = ldefstore_i -> count;
  243.     p = ldefstore_i -> data;
  244.  
  245. #if 0
  246.     for (i = 0; i < count; i++, p++)
  247.         {
  248.         p -> v1 = SHORT(p -> v1);
  249.         p -> v2 = SHORT(p -> v2);
  250. /* some ancient version of DoomEd left ML_MAPPED flags in some of the levels */
  251.         p -> flags = SHORT(p -> flags & ~ML_MAPPED);
  252.         p -> special = SHORT(p -> special);
  253.         p -> tag = SHORT(p -> tag);
  254.         p -> sidenum[0] = SHORT(p -> sidenum[0]);
  255.         p -> sidenum[1] = SHORT(p -> sidenum[1]);
  256.         }
  257. #endif
  258.  
  259.     WriteStorage("linedefs", ldefstore_i, sizeof(maplinedef_t));
  260. }
  261.  
  262.  
  263. /*
  264.    =================
  265.    =
  266.    = OutputSideDefs
  267.    =
  268.    =================
  269.  */
  270.  
  271. void                OutputSideDefs(void)
  272. {
  273.     int                 i,
  274.                         count;
  275.     mapsidedef_t       *p;
  276.  
  277. /*
  278.    count = [sdefstore_i count];
  279.    p = [sdefstore_i elementAt:0];
  280.  */
  281.     count = sdefstore_i -> count;
  282.     p = sdefstore_i -> data;
  283. /*
  284.    for (i=0 ; i<count ; i++, p++)
  285.    {
  286.    p->textureoffset = SHORT(p->textureoffset);
  287.    p->rowoffset = SHORT(p->rowoffset);
  288.    p->sector = SHORT(p->sector);
  289.    }
  290.  */
  291.     WriteStorage("sidedefs", sdefstore_i, sizeof(mapsidedef_t));
  292. }
  293.  
  294.  
  295. /*
  296.    =================
  297.    =
  298.    = OutputNodes
  299.    =
  300.    =================
  301.  */
  302.  
  303. void                OutputNodes(void)
  304. {
  305.     int                 i,
  306.                         j,
  307.                         count;
  308.     mapnode_t          *p;
  309.  
  310. /*
  311.    count = [nodestore_i count];
  312.    p = [nodestore_i elementAt:0];
  313.  */
  314.     count = nodestore_i -> count;
  315.     p = nodestore_i -> data;
  316. /*
  317.    for (i=0 ; i<count ; i++, p++)
  318.    {
  319.    for (j=0 ; j<sizeof(mapnode_t)/2 ; j++)
  320.    ((short *)p)[j] = SHORT(((short *)p)[j]);
  321.    }
  322.  */
  323.     WriteStorage("nodes", nodestore_i, sizeof(mapnode_t));
  324. }
  325.  
  326.  
  327. /*
  328.    ===============================================================================
  329.  
  330.    PROCESSING
  331.  
  332.    ===============================================================================
  333.  */
  334.  
  335.  
  336. /*
  337.    =================
  338.    =
  339.    = UniqueVertex
  340.    =
  341.    = Returns the vertex number, adding a new vertex if needed
  342.    =================
  343.  */
  344.  
  345. int                 UniqueVertex(int x, int y)
  346. {
  347.     int                 i,
  348.                         count;
  349.     mapvertex_t         mv,
  350.                        *mvp;
  351.  
  352.     mv.x = x;
  353.     mv.y = y;
  354.  
  355. /* see if an identical vertex already exists */
  356. /*
  357.    count = [mapvertexstore_i count];
  358.    mvp = [mapvertexstore_i elementAt:0];
  359.  */
  360.     count = mapvertexstore_i -> count;
  361.     mvp = mapvertexstore_i -> data;
  362.     for (i = 0; i < count; i++, mvp++)
  363.         if (mvp -> x == mv.x && mvp -> y == mv.y)
  364.             return i;
  365.  
  366. /*      [mapvertexstore_i addElement: &mv]; */
  367.     memcpy((mapvertex_t *) mapvertexstore_i -> data + mapvertexstore_i -> count, &mv,
  368.         sizeof(mapvertex_t));
  369.     mapvertexstore_i -> count += 1;
  370.     mapvertexstore_i -> data = (mapvertex_t *) realloc(mapvertexstore_i -> data,
  371.         sizeof(mapvertex_t) * (mapvertexstore_i -> count + 1));
  372.  
  373.     return count;
  374. }
  375.  
  376.  
  377. /*
  378.    =============================================================================
  379.  */
  380.  
  381. float               bbox[4];
  382.  
  383. /*
  384.    =================
  385.    =
  386.    = AddPointToBBox
  387.    =
  388.    =================
  389.  */
  390.  
  391. void                AddPointToBBox(NXPoint * pt)
  392. {
  393.     if (pt -> x < bbox[BOXLEFT])
  394.         bbox[BOXLEFT] = pt -> x;
  395.     if (pt -> x > bbox[BOXRIGHT])
  396.         bbox[BOXRIGHT] = pt -> x;
  397.  
  398.     if (pt -> y > bbox[BOXTOP])
  399.         bbox[BOXTOP] = pt -> y;
  400.     if (pt -> y < bbox[BOXBOTTOM])
  401.         bbox[BOXBOTTOM] = pt -> y;
  402. }
  403.  
  404.  
  405. /*
  406.    =================
  407.    =
  408.    = ProcessLines
  409.    =
  410.    = Adds the lines in a subsector to the mapline storage
  411.    =================
  412.  */
  413.  
  414. /* void ProcessLines (id store_i) */
  415. void                ProcessLines(STORAGE * store_i)
  416. {
  417.     int                 i,
  418.                         count;
  419.     line_t             *wline;
  420.     mapseg_t            line;
  421.     short               angle;
  422.     float               fangle;
  423.  
  424.     bbox[BOXLEFT] = INT_MAX;
  425.     bbox[BOXRIGHT] = INT_MIN;
  426.     bbox[BOXTOP] = INT_MIN;
  427.     bbox[BOXBOTTOM] = INT_MAX;
  428.  
  429. /*      count = [store_i count]; */
  430.     count = store_i -> count;
  431.     for (i = 0; i < count; i++)
  432.         {
  433. /*              wline = [store_i elementAt: i]; */
  434.         wline = (line_t *) store_i -> data + i;
  435.         if (wline -> grouped)
  436.             printf("ERROR: line regrouped\n");
  437.         wline -> grouped = true;
  438.  
  439.         memset(&line, 0, sizeof(line));
  440.         AddPointToBBox(&wline -> p1);
  441.         AddPointToBBox(&wline -> p2);
  442.         line.v1 = UniqueVertex(wline -> p1.x, wline -> p1.y);
  443.         line.v2 = UniqueVertex(wline -> p2.x, wline -> p2.y);
  444.         line.linedef = wline -> linedef;
  445.         line.side = wline -> side;
  446.         line.offset = wline -> offset;
  447.         fangle = atan2(wline -> p2.y - wline -> p1.y, wline -> p2.x - wline -> p1.x);
  448.         angle = (short)(fangle / (PI * 2) * 0x10000);
  449.         line.angle = angle;
  450. /*              [maplinestore_i addElement: &line]; */
  451.         memcpy((mapseg_t *) maplinestore_i -> data + maplinestore_i -> count, &line,
  452.             sizeof(line));
  453.         maplinestore_i -> count += 1;
  454.         maplinestore_i -> data = (mapseg_t *) realloc(maplinestore_i -> data,
  455.             sizeof(mapseg_t) * (maplinestore_i -> count + 1));
  456.         }
  457. }
  458.  
  459.  
  460. /*
  461.    =================
  462.    =
  463.    = ProcessSubsector
  464.    =
  465.    =================
  466.  */
  467.  
  468. /* int ProcessSubsector (id wmaplinestore_i) */
  469. int                 ProcessSubsector(STORAGE * wmaplinestore_i)
  470. {
  471.     int                 count;
  472.     worldline_t        *linedef;
  473.     line_t             *wline;
  474.     mapsubsector_t      sub;
  475.  
  476.     memset(&sub, 0, sizeof(sub));
  477.  
  478. /*      count = [wmaplinestore_i count]; */
  479.     count = wmaplinestore_i -> count;
  480.     if (count < 1)
  481.         Error("ProcessSubsector: count = %i", count);
  482.  
  483. /*      wline = [wmaplinestore_i elementAt: 0]; */
  484.     wline = wmaplinestore_i -> data;
  485.  
  486. /*      linedef = [linestore_i elementAt: wline->linedef]; */
  487.     linedef = (worldline_t *) linestore_i -> data + wline -> linedef;
  488.     sub.numsegs = count;
  489. /*      sub.firstseg = [maplinestore_i count]; */
  490.     sub.firstseg = maplinestore_i -> count;
  491.     ProcessLines(wmaplinestore_i);
  492.  
  493. /* add the new subsector
  494.    [subsecstore_i addElement: &sub];
  495.  */
  496.     memcpy((mapsubsector_t *) subsecstore_i -> data + subsecstore_i -> count, &sub,
  497.         sizeof(mapsubsector_t));
  498.     subsecstore_i -> count += 1;
  499.     subsecstore_i -> data = (mapsubsector_t *) realloc(subsecstore_i -> data,
  500.         sizeof(mapsubsector_t) * (subsecstore_i -> count + 1));
  501.  
  502. /*      return [subsecstore_i count]-1; */
  503.     return subsecstore_i -> count - 1;
  504. }
  505.  
  506. /*
  507.    =================
  508.    =
  509.    = ProcessNode
  510.    =
  511.    =================
  512.  */
  513.  
  514. int                 ProcessNode(bspnode_t * node, short *totalbox)
  515. {
  516.     short               subbox[2][4];
  517.     int                 i,
  518.                         r;
  519.     mapnode_t           mnode;
  520.  
  521.     memset(&mnode, 0, sizeof(mnode));
  522.  
  523.     if (node -> lines_i)               /* NF_SUBSECTOR flags a subsector */
  524.         {
  525.         r = ProcessSubsector(node -> lines_i);
  526.         for (i = 0; i < 4; i++)
  527.             totalbox[i] = bbox[i];
  528.         return r | NF_SUBSECTOR;
  529.         }
  530.  
  531.     mnode.x = node -> divline.pt.x;
  532.     mnode.y = node -> divline.pt.y;
  533.     mnode.dx = node -> divline.dx;
  534.     mnode.dy = node -> divline.dy;
  535.  
  536.     r = ProcessNode(node -> side[0], subbox[0]);
  537.     mnode.children[0] = r;
  538.     for (i = 0; i < 4; i++)
  539.         mnode.bbox[0][i] = subbox[0][i];
  540.  
  541.     r = ProcessNode(node -> side[1], subbox[1]);
  542.     mnode.children[1] = r;
  543.     for (i = 0; i < 4; i++)
  544.         mnode.bbox[1][i] = subbox[1][i];
  545.  
  546.     totalbox[BOXLEFT] = MIN(subbox[0][BOXLEFT], subbox[1][BOXLEFT]);
  547.     totalbox[BOXTOP] = MAX(subbox[0][BOXTOP], subbox[1][BOXTOP]);
  548.     totalbox[BOXRIGHT] = MAX(subbox[0][BOXRIGHT], subbox[1][BOXRIGHT]);
  549.     totalbox[BOXBOTTOM] = MIN(subbox[0][BOXBOTTOM], subbox[1][BOXBOTTOM]);
  550.  
  551. /*      [nodestore_i addElement: &mnode]; */
  552.     memcpy((mapnode_t *) nodestore_i -> data + nodestore_i -> count, &mnode, sizeof(mapnode_t));
  553.     nodestore_i -> count += 1;
  554.     nodestore_i -> data = (mapnode_t *) realloc(nodestore_i -> data,
  555.         sizeof(mapnode_t) * (nodestore_i -> count + 1));
  556.  
  557. /*      return [nodestore_i count] - 1; */
  558.     return nodestore_i -> count - 1;
  559. }
  560.  
  561.  
  562. /*
  563.    =================
  564.    =
  565.    = ProcessNodes
  566.    =
  567.    = Recursively builds the nodes, subsectors, and line lists,
  568.    = then writes the lumps
  569.    =================
  570.  */
  571.  
  572. void                ProcessNodes(void)
  573. {
  574.     short               worldbounds[4];
  575.  
  576. /*
  577.    subsecstore_i = [[Storage alloc]
  578.    initCount:              0
  579.    elementSize:    sizeof(mapsubsector_t)
  580.    description:    NULL];
  581.    maplinestore_i = [[Storage alloc]
  582.    initCount:              0
  583.    elementSize:    sizeof(mapseg_t)
  584.    description:    NULL];
  585.    nodestore_i = [[Storage alloc]
  586.    initCount:              0
  587.    elementSize:    sizeof(mapnode_t)
  588.    description:    NULL];
  589.  */
  590.     subsecstore_i = (STORAGE *) SafeMalloc(sizeof(STORAGE));
  591.     subsecstore_i -> data = (mapsubsector_t *) SafeMalloc(sizeof(mapsubsector_t));
  592.     subsecstore_i -> count = 0;
  593.     subsecstore_i -> size = sizeof(mapsubsector_t);
  594.  
  595.     maplinestore_i = (STORAGE *) SafeMalloc(sizeof(STORAGE));
  596.     maplinestore_i -> data = (mapseg_t *) SafeMalloc(sizeof(mapseg_t));
  597.     maplinestore_i -> count = 0;
  598.     maplinestore_i -> size = sizeof(mapseg_t);
  599.  
  600.     nodestore_i = (STORAGE *) SafeMalloc(sizeof(STORAGE));
  601.     nodestore_i -> data = (mapnode_t *) SafeMalloc(sizeof(mapnode_t));
  602.     nodestore_i -> count = 0;
  603.     nodestore_i -> size = sizeof(mapnode_t);
  604.  
  605.     ProcessNode(startnode, worldbounds);
  606.  
  607. }
  608.  
  609.  
  610. /*
  611.    =================
  612.    =
  613.    = ProcessThings
  614.    =
  615.    =================
  616.  */
  617.  
  618. void                ProcessThings(void)
  619. {
  620.     worldthing_t       *wt;
  621.     mapthing_t          mt;
  622.     int                 count;
  623.  
  624. /*
  625.    mapthingstore_i = [[Storage alloc]
  626.    initCount:              0
  627.    elementSize:    sizeof(mapthing_t)
  628.    description:    NULL];
  629.  */
  630.     mapthingstore_i = (STORAGE *) SafeMalloc(sizeof(STORAGE));
  631.     mapthingstore_i -> data = (mapthing_t *) SafeMalloc(sizeof(mapthing_t));
  632.     mapthingstore_i -> count = 0;
  633.     mapthingstore_i -> size = sizeof(mapthing_t);
  634.  
  635. /*
  636.    count = [thingstore_i count];
  637.    wt = [thingstore_i elementAt: 0];
  638.  */
  639.     count = thingstore_i -> count;
  640.     wt = thingstore_i -> data;
  641.     while (count--)
  642.         {
  643.         memset(&mt, 0, sizeof(mt));
  644.         mt.x = wt -> origin.x;
  645.         mt.y = wt -> origin.y;
  646.         mt.angle = wt -> angle;
  647.         mt.type = wt -> type;
  648.         mt.options = wt -> options;
  649. /*              [mapthingstore_i addElement: &mt]; */
  650.         memcpy((mapthing_t *) mapthingstore_i -> data + mapthingstore_i -> count, &mt,
  651.             sizeof(mapthing_t));
  652.         mapthingstore_i -> count += 1;
  653.         mapthingstore_i -> data = (mapthing_t *) realloc(mapthingstore_i -> data,
  654.             sizeof(mapthing_t) * (mapthingstore_i -> count + 1));
  655.         wt++;
  656.         }
  657.  
  658. }
  659.  
  660. /*
  661.    =============================================================================
  662.  */
  663.  
  664. /*
  665.    ==================
  666.    =
  667.    = ProcessSidedef
  668.    =
  669.    ==================
  670.  */
  671.  
  672. int                 ProcessSidedef(worldside_t * ws)
  673. {
  674.     mapsidedef_t        ms;
  675.  
  676.     ms.textureoffset = ws -> firstcollumn;
  677.     ms.rowoffset = ws -> firstrow;
  678.     memcpy(ms.toptexture, ws -> toptexture, 8);
  679.     memcpy(ms.bottomtexture, ws -> bottomtexture, 8);
  680.     memcpy(ms.midtexture, ws -> midtexture, 8);
  681.     ms.sector = ws -> sector;
  682.  
  683. /*      [sdefstore_i addElement: &ms]; */
  684.     memcpy((mapsidedef_t *) sdefstore_i -> data + sdefstore_i -> count, &ms, sizeof(mapsidedef_t));
  685.     sdefstore_i -> count += 1;
  686.     sdefstore_i -> data = (mapsidedef_t *) realloc(sdefstore_i -> data,
  687.         sizeof(mapsidedef_t) * (sdefstore_i -> count + 1));
  688.  
  689. /*      return [sdefstore_i count]-1; */
  690.     return sdefstore_i -> count - 1;
  691. }
  692.  
  693. /*
  694.    ==================
  695.    =
  696.    = ProcessLineSideDefs
  697.    =
  698.    = Must be called after BuildSectors
  699.    ==================
  700.  */
  701.  
  702. void                ProcessLineSideDefs(void)
  703. {
  704.     int                 i,
  705.                         count;
  706.     maplinedef_t        ld;
  707.     worldline_t        *wl;
  708.  
  709. /*
  710.    mapvertexstore_i = [[Storage alloc]
  711.    initCount:              0
  712.    elementSize:    sizeof(mapvertex_t)
  713.    description:    NULL];
  714.    ldefstore_i = [[Storage alloc]
  715.    initCount:              0
  716.    elementSize:    sizeof(maplinedef_t)
  717.    description:    NULL];
  718.    sdefstore_i = [[Storage alloc]
  719.    initCount:              0
  720.    elementSize:    sizeof(mapsidedef_t)
  721.    description:    NULL];
  722.  */
  723.     mapvertexstore_i = (STORAGE *) SafeMalloc(sizeof(STORAGE));
  724.     mapvertexstore_i -> data = (mapvertex_t *) SafeMalloc(sizeof(mapvertex_t));
  725.     mapvertexstore_i -> count = 0;
  726.     mapvertexstore_i -> size = sizeof(mapvertex_t);
  727.  
  728.     ldefstore_i = (STORAGE *) SafeMalloc(sizeof(STORAGE));
  729.     ldefstore_i -> data = (maplinedef_t *) SafeMalloc(sizeof(maplinedef_t));
  730.     ldefstore_i -> count = 0;
  731.     ldefstore_i -> size = sizeof(maplinedef_t);
  732.  
  733.     sdefstore_i = (STORAGE *) SafeMalloc(sizeof(STORAGE));
  734.     sdefstore_i -> data = (mapsidedef_t *) SafeMalloc(sizeof(mapsidedef_t));
  735.     sdefstore_i -> count = 0;
  736.     sdefstore_i -> size = sizeof(mapsidedef_t);
  737.  
  738. /*
  739.    count = [linestore_i count];
  740.    wl = [linestore_i elementAt:0];
  741.  */
  742.     count = linestore_i -> count;
  743.     wl = linestore_i -> data;
  744.     for (i = 0; i < count; i++, wl++)
  745.         {
  746.         ld.v1 = UniqueVertex(wl -> p1.x, wl -> p1.y);
  747.         ld.v2 = UniqueVertex(wl -> p2.x, wl -> p2.y);
  748.         ld.flags = wl -> flags;
  749.         ld.special = wl -> special;
  750.         ld.tag = wl -> tag;
  751.         ld.sidenum[0] = ProcessSidedef(&wl -> side[0]);
  752.         if (wl -> flags & ML_TWOSIDED)
  753.             ld.sidenum[1] = ProcessSidedef(&wl -> side[1]);
  754.         else
  755.             ld.sidenum[1] = -1;
  756. /*              [ldefstore_i addElement: &ld]; */
  757.  
  758.         memcpy((maplinedef_t *) ldefstore_i -> data + ldefstore_i -> count, &ld, sizeof(maplinedef_t));
  759.         ldefstore_i -> count += 1;
  760.         ldefstore_i -> data = (maplinedef_t *) realloc(ldefstore_i -> data,
  761.             sizeof(maplinedef_t) * (ldefstore_i -> count + 1));
  762.         }
  763.  
  764. }
  765.  
  766. /*
  767.    =============================================================================
  768.  */
  769.  
  770. /*
  771.    ==================
  772.    =
  773.    = SaveDoomMap
  774.    =
  775.    ==================
  776.  */
  777.  
  778. void                SaveDoomMap(void)
  779. {
  780.     printf("\nBuildSectordefs\n");
  781.     BuildSectordefs();
  782.  
  783.     printf("ProcessThings\n");
  784.     ProcessThings();
  785.  
  786.     printf("ProcessLineSideDefs\n");
  787.     ProcessLineSideDefs();
  788.  
  789.     printf("ProcessNodes\n");
  790.     ProcessNodes();
  791.  
  792.     printf("ProcessSectors\n");
  793.     ProcessSectors();
  794.  
  795.     printf("\nProcessConnections\n");
  796.     ProcessConnections();
  797.  
  798. /* all processing is complete, write everything out */
  799.     OutputThings();
  800.     OutputLineDefs();
  801.     OutputSideDefs();
  802.     OutputVertexes();
  803.     OutputSegs();
  804.     OutputSubsectors();
  805.     OutputNodes();
  806.     OutputSectors();
  807.     OutputConnections();
  808. }
  809.