home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / GAMES_C / DEU50.ZIP / SOURCE.ZIP / OBJECTS.C < prev    next >
C/C++ Source or Header  |  1994-03-30  |  21KB  |  763 lines

  1. /*
  2.    Doom Editor Utility, by Brendon Wyber and Raphaël Quinet.
  3.  
  4.    You are allowed to use any parts of this code in another program, as
  5.    long as you give credits to the authors in the documentation and in
  6.    the program itself.  Read the file README.1ST for more information.
  7.  
  8.    This program comes with absolutely no warranty.
  9.  
  10.    OBJECTS.C - object handling routines.
  11. */
  12.  
  13. /* the includes */
  14. #include "deu.h"
  15. #include "levels.h"
  16.  
  17.  
  18. /*
  19.    highlight the selected objects
  20. */
  21.  
  22. void HighlightSelection( int objtype, SelPtr list)
  23. {
  24.    SelPtr cur;
  25.  
  26.    if (list == NULL)
  27.       return;
  28.    for (cur = list; cur; cur = cur->next)
  29.       HighlightObject( objtype, cur->objnum, GREEN);
  30. }
  31.  
  32.  
  33.  
  34. /*
  35.    test if an object is in the selection list
  36. */
  37.  
  38. Bool IsSelected( SelPtr list, int objnum)
  39. {
  40.    SelPtr cur;
  41.  
  42.    for (cur = list; cur; cur = cur->next)
  43.       if (cur->objnum == objnum)
  44.      return TRUE;
  45.    return FALSE;
  46. }
  47.  
  48.  
  49.  
  50. /*
  51.    add an object to the selection list
  52. */
  53.  
  54. void SelectObject( SelPtr *list, int objnum)
  55. {
  56.    SelPtr cur;
  57.  
  58.  
  59.    if (objnum < 0)
  60.       ProgError( "SelectObject called with %d (BUG!)", objnum);
  61.    cur = GetMemory( sizeof( struct SelectionList));
  62.    cur->next = *list;
  63.    cur->objnum = objnum;
  64.    *list = cur;
  65. }
  66.  
  67.  
  68.  
  69. /*
  70.    remove an object from the selection list
  71. */
  72.  
  73. void UnSelectObject( SelPtr *list, int objnum)
  74. {
  75.    SelPtr cur, prev;
  76.  
  77.    if (objnum < 0)
  78.       ProgError( "UnSelectObject called with %d (BUG!)", objnum);
  79.    prev = NULL;
  80.    cur = *list;
  81.    while (cur)
  82.    {
  83.       if (cur->objnum == objnum)
  84.       {
  85.      if (prev)
  86.         prev->next = cur->next;
  87.      else
  88.         *list = cur->next;
  89.      free( cur);
  90.      if (prev)
  91.         cur = prev->next;
  92.      else
  93.         cur = NULL;
  94.       }
  95.       else
  96.       {
  97.      prev = cur;
  98.      cur = cur->next;
  99.       }
  100.    }
  101. }
  102.  
  103.  
  104.  
  105. /*
  106.    forget the selection list
  107. */
  108.  
  109. void ForgetSelection( SelPtr *list)
  110. {
  111.    SelPtr cur, prev;
  112.  
  113.    cur = *list;
  114.    while (cur)
  115.    {
  116.       prev = cur;
  117.       cur = cur->next;
  118.       free( prev);
  119.    }
  120.    *list = NULL;
  121. }
  122.  
  123.  
  124.  
  125. /*
  126.    get the number of objets of a given type minus one
  127. */
  128. int GetMaxObjectNum( int objtype)
  129. {
  130.    switch (objtype)
  131.    {
  132.    case OBJ_THINGS:
  133.       return NumThings - 1;
  134.    case OBJ_LINEDEFS:
  135.       return NumLineDefs - 1;
  136.    case OBJ_SIDEDEFS:
  137.       return NumSideDefs - 1;
  138.    case OBJ_VERTEXES:
  139.       return NumVertexes - 1;
  140.    case OBJ_SEGS:
  141.       return NumSegs - 1;
  142.    case OBJ_SSECTORS:
  143.       return NumSSectors - 1;
  144.    case OBJ_SECTORS:
  145.       return NumSectors - 1;
  146.    }
  147.    return -1;
  148. }
  149.  
  150.  
  151. /*
  152.    check if there is something of interest inside the given box
  153. */
  154.  
  155. int GetCurObject( int objtype, int x0, int y0, int x1, int y1)
  156. {
  157.    int n, m, cur, curx;
  158.    int lx0, ly0, lx1, ly1, yy;
  159.    int midx, midy;
  160.  
  161.    cur = -1;
  162.    if (x1 < x0)
  163.    {
  164.       n = x0;
  165.       x0 = x1;
  166.       x1 = n;
  167.    }
  168.    if (y1 < y0)
  169.    {
  170.       n = y0;
  171.       y0 = y1;
  172.       y1 = n;
  173.    }
  174.  
  175.    switch (objtype)
  176.    {
  177.    case OBJ_THINGS:
  178.       for (n = 0; n < NumThings; n++)
  179.      if (Things[ n].xpos >= x0 && Things[ n].xpos <= x1 && Things[ n].ypos >= y0 && Things[ n].ypos <= y1)
  180.      {
  181.         cur = n;
  182.         break;
  183.      }
  184.       break;
  185.    case OBJ_VERTEXES:
  186.       for (n = 0; n < NumVertexes; n++)
  187.      if (Vertexes[ n].x >= x0 && Vertexes[ n].x <= x1 && Vertexes[ n].y >= y0 && Vertexes[ n].y <= y1)
  188.      {
  189.         cur = n;
  190.         break;
  191.      }
  192.       break;
  193.    case OBJ_LINEDEFS:
  194.       for (n = 0; n < NumLineDefs; n++)
  195.       {
  196.      if (IsLineDefInside( n, x0, y0, x1, y1))
  197.      {
  198.         cur = n;
  199.         break;
  200.      }
  201.       }
  202.       break;
  203.    case OBJ_SECTORS:
  204.       /* hack, hack...  I look for the first LineDef crossing an horizontal half-line drawn from the cursor */
  205.       curx = MapMaxX + 1;
  206.       cur = -1;
  207.       midx = (x0 + x1) / 2;
  208.       midy = (y0 + y1) / 2;
  209.       for (n = 0; n < NumLineDefs; n++)
  210.      if ((Vertexes[ LineDefs[ n].start].y > midy != (Vertexes[ LineDefs[ n].end].y > midy)))
  211.      {
  212.         lx0 = Vertexes[ LineDefs[ n].start].x;
  213.         ly0 = Vertexes[ LineDefs[ n].start].y;
  214.         lx1 = Vertexes[ LineDefs[ n].end].x;
  215.         ly1 = Vertexes[ LineDefs[ n].end].y;
  216.         m = lx0 + (int) ((long) (midy - ly0) * (long) (lx1 - lx0) / (long) (ly1 - ly0));
  217.         if (m >= midx && m < curx)
  218.         {
  219.            curx = m;
  220.            cur = n;
  221.         }
  222.      }
  223.       /* now look if this LineDef has a SideDef bound to one sector */
  224.       if (cur >= 0)
  225.       {
  226.      if (Vertexes[ LineDefs[ cur].start].y > Vertexes[ LineDefs[ cur].end].y)
  227.      {
  228.         if (LineDefs[ cur].sidedef1 >= 0)
  229.            cur = SideDefs[ LineDefs[ cur].sidedef1].sector;
  230.         else
  231.            cur = -1;
  232.      }
  233.      else
  234.      {
  235.         if (LineDefs[ cur].sidedef2 >= 0)
  236.            cur = SideDefs[ LineDefs[ cur].sidedef2].sector;
  237.         else
  238.            cur = -1;
  239.      }
  240.       }
  241.       else
  242.      cur = -1;
  243.       break;
  244.    }
  245.    return cur;
  246. }
  247.  
  248.  
  249.  
  250. /*
  251.    select all objects inside a given box
  252. */
  253.  
  254. SelPtr SelectObjectsInBox( int objtype, int x0, int y0, int x1, int y1)
  255. {
  256.    int n, m;
  257.    SelPtr list;
  258.  
  259.    list = NULL;
  260.    if (x1 < x0)
  261.    {
  262.       n = x0;
  263.       x0 = x1;
  264.       x1 = n;
  265.    }
  266.    if (y1 < y0)
  267.    {
  268.       n = y0;
  269.       y0 = y1;
  270.       y1 = n;
  271.    }
  272.  
  273.    switch (objtype)
  274.    {
  275.    case OBJ_THINGS:
  276.       for (n = 0; n < NumThings; n++)
  277.      if (Things[ n].xpos >= x0 && Things[ n].xpos <= x1 && Things[ n].ypos >= y0 && Things[ n].ypos <= y1)
  278.         SelectObject( &list, n);
  279.       break;
  280.    case OBJ_VERTEXES:
  281.       for (n = 0; n < NumVertexes; n++)
  282.      if (Vertexes[ n].x >= x0 && Vertexes[ n].x <= x1 && Vertexes[ n].y >= y0 && Vertexes[ n].y <= y1)
  283.         SelectObject( &list, n);
  284.       break;
  285.    case OBJ_LINEDEFS:
  286.       for (n = 0; n < NumLineDefs; n++)
  287.       {
  288.      /* the two ends of the line must be in the box */
  289.      m = LineDefs[ n].start;
  290.      if (Vertexes[ m].x < x0 || Vertexes[ m].x > x1 || Vertexes[ m].y < y0 || Vertexes[ m].y > y1)
  291.         continue;
  292.      m = LineDefs[ n].end;
  293.      if (Vertexes[ m].x < x0 || Vertexes[ m].x > x1 || Vertexes[ m].y < y0 || Vertexes[ m].y > y1)
  294.         continue;
  295.      SelectObject( &list, n);
  296.       }
  297.       break;
  298.    case OBJ_SECTORS:
  299.       /* hack: select all sectors... */
  300.       for (n = 0; n < NumSectors; n++)
  301.      SelectObject( &list, n);
  302.       /* ... then remove the unwanted ones from the list */
  303.       for (n = 0; n < NumLineDefs; n++)
  304.       {
  305.      m = LineDefs[ n].start;
  306.      if (Vertexes[ m].x < x0 || Vertexes[ m].x > x1 || Vertexes[ m].y < y0 || Vertexes[ m].y > y1)
  307.      {
  308.         m = LineDefs[ n].sidedef1;
  309.         if (m >= 0 && SideDefs[ m].sector >= 0)
  310.            UnSelectObject( &list, SideDefs[ m].sector);
  311.         m = LineDefs[ n].sidedef2;
  312.         if (m >= 0 && SideDefs[ m].sector >= 0)
  313.            UnSelectObject( &list, SideDefs[ m].sector);
  314.         continue;
  315.      }
  316.      m = LineDefs[ n].end;
  317.      if (Vertexes[ m].x < x0 || Vertexes[ m].x > x1 || Vertexes[ m].y < y0 || Vertexes[ m].y > y1)
  318.      {
  319.         m = LineDefs[ n].sidedef1;
  320.         if (m >= 0 && SideDefs[ m].sector >= 0)
  321.            UnSelectObject( &list, SideDefs[ m].sector);
  322.         m = LineDefs[ n].sidedef2;
  323.         if (m >= 0 && SideDefs[ m].sector >= 0)
  324.            UnSelectObject( &list, SideDefs[ m].sector);
  325.         continue;
  326.      }
  327.       }
  328.       break;
  329.    }
  330.    return list;
  331. }
  332.  
  333.  
  334.  
  335. /*
  336.    highlight the selected object
  337. */
  338.  
  339. void HighlightObject( int objtype, int objnum, int color)
  340. {
  341.    int  n, m;
  342.  
  343.    /* use XOR mode : drawing any line twice erases it */
  344.    setwritemode( XOR_PUT);
  345.    SetColor( color);
  346.    switch ( objtype)
  347.    {
  348.    case OBJ_THINGS:
  349.       DrawMapLine( Things[ objnum].xpos - OBJSIZE * 2, Things[ objnum].ypos - OBJSIZE * 2, Things[ objnum].xpos - OBJSIZE * 2, Things[ objnum].ypos + OBJSIZE * 2);
  350.       DrawMapLine( Things[ objnum].xpos - OBJSIZE * 2, Things[ objnum].ypos + OBJSIZE * 2, Things[ objnum].xpos + OBJSIZE * 2, Things[ objnum].ypos + OBJSIZE * 2);
  351.       DrawMapLine( Things[ objnum].xpos + OBJSIZE * 2, Things[ objnum].ypos + OBJSIZE * 2, Things[ objnum].xpos + OBJSIZE * 2, Things[ objnum].ypos - OBJSIZE * 2);
  352.       DrawMapLine( Things[ objnum].xpos + OBJSIZE * 2, Things[ objnum].ypos - OBJSIZE * 2, Things[ objnum].xpos - OBJSIZE * 2, Things[ objnum].ypos - OBJSIZE * 2);
  353.       break;
  354.    case OBJ_LINEDEFS:
  355.       n = (Vertexes[ LineDefs[ objnum].start].x + Vertexes[ LineDefs[ objnum].end].x) / 2;
  356.       m = (Vertexes[ LineDefs[ objnum].start].y + Vertexes[ LineDefs[ objnum].end].y) / 2;
  357.       DrawMapLine( n, m, n + (Vertexes[ LineDefs[ objnum].end].y - Vertexes[ LineDefs[ objnum].start].y) / 3, m + (Vertexes[ LineDefs[ objnum].start].x - Vertexes[ LineDefs[ objnum].end].x) / 3);
  358.       setlinestyle(SOLID_LINE, 0, THICK_WIDTH);
  359.       DrawMapVector( Vertexes[ LineDefs[ objnum].start].x, Vertexes[ LineDefs[ objnum].start].y,
  360.              Vertexes[ LineDefs[ objnum].end].x, Vertexes[ LineDefs[ objnum].end].y);
  361.       if (color != LIGHTRED && LineDefs[ objnum].tag > 0)
  362.       {
  363.      for (m = 0; m < NumSectors; m++)
  364.         if (Sectors[ m].tag == LineDefs[ objnum].tag)
  365.            HighlightObject( OBJ_SECTORS, m, LIGHTRED);
  366.       }
  367.       setlinestyle(SOLID_LINE, 0, NORM_WIDTH);
  368.       break;
  369.    case OBJ_VERTEXES:
  370.       DrawMapLine( Vertexes[ objnum].x - OBJSIZE * 2, Vertexes[ objnum].y - OBJSIZE * 2, Vertexes[ objnum].x - OBJSIZE * 2, Vertexes[ objnum].y + OBJSIZE * 2);
  371.       DrawMapLine( Vertexes[ objnum].x - OBJSIZE * 2, Vertexes[ objnum].y + OBJSIZE * 2, Vertexes[ objnum].x + OBJSIZE * 2, Vertexes[ objnum].y + OBJSIZE * 2);
  372.       DrawMapLine( Vertexes[ objnum].x + OBJSIZE * 2, Vertexes[ objnum].y + OBJSIZE * 2, Vertexes[ objnum].x + OBJSIZE * 2, Vertexes[ objnum].y - OBJSIZE * 2);
  373.       DrawMapLine( Vertexes[ objnum].x + OBJSIZE * 2, Vertexes[ objnum].y - OBJSIZE * 2, Vertexes[ objnum].x - OBJSIZE * 2, Vertexes[ objnum].y - OBJSIZE * 2);
  374.       break;
  375.    case OBJ_SECTORS:
  376.       setlinestyle(SOLID_LINE, 0, THICK_WIDTH);
  377.       for (n = 0; n < NumLineDefs; n++)
  378.      if (SideDefs[ LineDefs[ n].sidedef1].sector == objnum || SideDefs[ LineDefs[ n].sidedef2].sector == objnum)
  379.         DrawMapLine( Vertexes[ LineDefs[ n].start].x, Vertexes[ LineDefs[ n].start].y,
  380.              Vertexes[ LineDefs[ n].end].x, Vertexes[ LineDefs[ n].end].y);
  381.       if (color != LIGHTRED && Sectors[ objnum].tag > 0)
  382.       {
  383.      for (m = 0; m < NumLineDefs; m++)
  384.         if (LineDefs[ m].tag == Sectors[ objnum].tag)
  385.            HighlightObject( OBJ_LINEDEFS, m, LIGHTRED);
  386.       }
  387.       setlinestyle(SOLID_LINE, 0, NORM_WIDTH);
  388.       break;
  389.    }
  390.    /* restore normal write mode */
  391.    setwritemode( COPY_PUT);
  392. }
  393.  
  394.  
  395.  
  396. /*
  397.    delete an object
  398. */
  399.  
  400. void DeleteObject( int objtype, int objnum)
  401. {
  402.    SelPtr list;
  403.  
  404.    list = NULL;
  405.    SelectObject( &list, objnum);
  406.    DeleteObjects( objtype, &list);
  407. }
  408.  
  409.  
  410.  
  411. /*
  412.    delete a group of objects (*recursive*)
  413. */
  414.  
  415. void DeleteObjects( int objtype, SelPtr *list)
  416. {
  417.    int    n, objnum;
  418.    SelPtr cur;
  419.  
  420.    MadeChanges = TRUE;
  421.    switch (objtype)
  422.    {
  423.    case OBJ_THINGS:
  424.       while (*list)
  425.       {
  426.      objnum = (*list)->objnum;
  427.      /* delete the Thing */
  428.      NumThings--;
  429.      if (NumThings > 0)
  430.      {
  431.         for (n = objnum; n < NumThings; n++)
  432.            Things[ n] = Things[ n + 1];
  433.         Things = ResizeFarMemory( Things, NumThings * sizeof( struct Thing));
  434.      }
  435.      else
  436.      {
  437.         farfree( Things);
  438.         Things = NULL;
  439.      }
  440.      for (cur = (*list)->next; cur; cur = cur->next)
  441.         if (cur->objnum > objnum)
  442.            cur->objnum--;
  443.      UnSelectObject( list, objnum);
  444.       }
  445.       break;
  446.    case OBJ_VERTEXES:
  447.       while (*list)
  448.       {
  449.      objnum = (*list)->objnum;
  450.      /* delete the LineDefs bound to this Vertex and change the references */
  451.      for (n = 0; n < NumLineDefs; n++)
  452.      {
  453.         if (LineDefs[ n].start == objnum || LineDefs[ n].end == objnum)
  454.            DeleteObject( OBJ_LINEDEFS, n--);
  455.         else
  456.         {
  457.            if (LineDefs[ n].start >= objnum)
  458.           LineDefs[ n].start--;
  459.            if (LineDefs[ n].end >= objnum)
  460.           LineDefs[ n].end--;
  461.         }
  462.      }
  463.      /* delete the Vertex */
  464.      NumVertexes--;
  465.      if (NumVertexes > 0)
  466.      {
  467.         for (n = objnum; n < NumVertexes; n++)
  468.            Vertexes[ n] = Vertexes[ n + 1];
  469.         Vertexes = ResizeFarMemory( Vertexes, NumVertexes * sizeof( struct Vertex));
  470.      }
  471.      else
  472.      {
  473.         farfree( Vertexes);
  474.         Vertexes = NULL;
  475.      }
  476.      for (cur = (*list)->next; cur; cur = cur->next)
  477.         if (cur->objnum > objnum)
  478.            cur->objnum--;
  479.      UnSelectObject( list, objnum);
  480.       }
  481.       break;
  482.    case OBJ_LINEDEFS:
  483.       while (*list)
  484.       {
  485.      objnum = (*list)->objnum;
  486.      /* delete the two SideDefs bound to this LineDef */
  487.      if (LineDefs[ objnum].sidedef1 >= 0)
  488.         DeleteObject( OBJ_SIDEDEFS, LineDefs[ objnum].sidedef1);
  489.      if (LineDefs[ objnum].sidedef2 >= 0)
  490.         DeleteObject( OBJ_SIDEDEFS, LineDefs[ objnum].sidedef2);
  491.      /* delete the LineDef */
  492.      NumLineDefs--;
  493.      if (NumLineDefs > 0)
  494.      {
  495.         for (n = objnum; n < NumLineDefs; n++)
  496.            LineDefs[ n] = LineDefs[ n + 1];
  497.         LineDefs = ResizeFarMemory( LineDefs, NumLineDefs * sizeof( struct LineDef));
  498.      }
  499.      else
  500.      {
  501.         farfree( LineDefs);
  502.         LineDefs = NULL;
  503.      }
  504.      for (cur = (*list)->next; cur; cur = cur->next)
  505.         if (cur->objnum > objnum)
  506.            cur->objnum--;
  507.      UnSelectObject( list, objnum);
  508.       }
  509.       break;
  510.    case OBJ_SIDEDEFS:
  511.       while (*list)
  512.       {
  513.      objnum = (*list)->objnum;
  514.      /* change the LineDefs references */
  515.      for (n = 0; n < NumLineDefs; n++)
  516.      {
  517.         if (LineDefs[ n].sidedef1 == objnum)
  518.            LineDefs[ n].sidedef1 = -1;
  519.         else if (LineDefs[ n].sidedef1 >= objnum)
  520.            LineDefs[ n].sidedef1--;
  521.         if (LineDefs[ n].sidedef2 == objnum)
  522.            LineDefs[ n].sidedef2 = -1;
  523.         else if (LineDefs[ n].sidedef2 >= objnum)
  524.            LineDefs[ n].sidedef2--;
  525.      }
  526.      /* delete the SideDef */
  527.      NumSideDefs--;
  528.      if (NumSideDefs > 0)
  529.      {
  530.         for (n = objnum; n < NumSideDefs; n++)
  531.            SideDefs[ n] = SideDefs[ n + 1];
  532.         SideDefs = ResizeFarMemory( SideDefs, NumSideDefs * sizeof( struct SideDef));
  533.      }
  534.      else
  535.      {
  536.         farfree( SideDefs);
  537.         SideDefs = NULL;
  538.      }
  539.      for (cur = (*list)->next; cur; cur = cur->next)
  540.         if (cur->objnum > objnum)
  541.            cur->objnum--;
  542.      UnSelectObject( list, objnum);
  543.       }
  544.       MadeMapChanges = TRUE;
  545.       break;
  546.    case OBJ_SECTORS:
  547.       while (*list)
  548.       {
  549.      objnum = (*list)->objnum;
  550.      /* delete the SideDefs bound to this Sector and change the references */
  551.      for (n = 0; n < NumLineDefs; n++)
  552.      {
  553.         if (SideDefs[ LineDefs[ n].sidedef1].sector == objnum)
  554.            DeleteObject( OBJ_SIDEDEFS, LineDefs[ n].sidedef1);
  555.         else if (SideDefs[ LineDefs[ n].sidedef1].sector >= objnum)
  556.            SideDefs[ LineDefs[ n].sidedef1].sector--;
  557.         if (SideDefs[ LineDefs[ n].sidedef2].sector == objnum)
  558.            DeleteObject( OBJ_SIDEDEFS, LineDefs[ n].sidedef2);
  559.         else if (SideDefs[ LineDefs[ n].sidedef2].sector >= objnum)
  560.            SideDefs[ LineDefs[ n].sidedef2].sector--;
  561.      }
  562.      /* delete the Sector */
  563.      NumSectors--;
  564.      if (NumSectors > 0)
  565.      {
  566.         for (n = objnum; n < NumSectors; n++)
  567.            Sectors[ n] = Sectors[ n + 1];
  568.         Sectors = ResizeFarMemory( Sectors, NumSectors * sizeof( struct Sector));
  569.      }
  570.      else
  571.      {
  572.         farfree( Sectors);
  573.         Sectors = NULL;
  574.      }
  575.      for (cur = (*list)->next; cur; cur = cur->next)
  576.         if (cur->objnum > objnum)
  577.            cur->objnum--;
  578.      UnSelectObject( list, objnum);
  579.       }
  580.       break;
  581.    default:
  582.       Beep();
  583.    }
  584. }
  585.  
  586.  
  587.  
  588. /*
  589.    insert a new object
  590. */
  591.  
  592. void InsertObject(int objtype, int copyfrom, int xpos, int ypos)
  593. {
  594.    int last;
  595.  
  596.    MadeChanges = TRUE;
  597.    switch (objtype)
  598.    {
  599.    case OBJ_THINGS:
  600.       last = NumThings++;
  601.       if (last > 0)
  602.      Things = ResizeFarMemory( Things, (unsigned long) NumThings * sizeof( struct Thing));
  603.       else
  604.      Things = GetFarMemory( sizeof( struct Thing));
  605.       Things[ last].xpos = xpos;
  606.       Things[ last].ypos = ypos;
  607.       if (copyfrom >= 0)
  608.       {
  609.      Things[ last].type  = Things[ copyfrom].type;
  610.      Things[ last].angle = Things[ copyfrom].angle;
  611.      Things[ last].when  = Things[ copyfrom].when;
  612.       }
  613.       else
  614.       {
  615.      Things[ last].type  = THING_TROOPER;
  616.      Things[ last].angle = 0;
  617.      Things[ last].when  = 0x07;
  618.       }
  619.       break;
  620.    case OBJ_LINEDEFS:
  621.       last = NumLineDefs++;
  622.       if (last > 0)
  623.      LineDefs = ResizeFarMemory( LineDefs, (unsigned long) NumLineDefs * sizeof( struct LineDef));
  624.       else
  625.      LineDefs = GetFarMemory( sizeof( struct LineDef));
  626.       if (copyfrom >= 0)
  627.       {
  628.      LineDefs[ last].start = LineDefs[ copyfrom].start;
  629.      LineDefs[ last].end = LineDefs[ copyfrom].end;
  630.      LineDefs[ last].flags = LineDefs[ copyfrom].flags;
  631.      LineDefs[ last].type = LineDefs[ copyfrom].type;
  632.      LineDefs[ last].tag = LineDefs[ copyfrom].tag;
  633.       }
  634.       else
  635.       {
  636.      LineDefs[ last].start = 0;
  637.      LineDefs[ last].end = NumVertexes - 1;
  638.      LineDefs[ last].flags = 1;
  639.      LineDefs[ last].type = 0;
  640.      LineDefs[ last].tag = 0;
  641.       }
  642.       LineDefs[ last].sidedef1 = -1;
  643.       LineDefs[ last].sidedef2 = -1;
  644.       break;
  645.    case OBJ_SIDEDEFS:
  646.       /* SideDefs are added from the LineDefs menu, so "copyfrom" should always be -1.  But I test it anyway. */
  647.       last = NumSideDefs++;
  648.       if (last > 0)
  649.      SideDefs = ResizeFarMemory( SideDefs, (unsigned long) NumSideDefs * sizeof( struct SideDef));
  650.       else
  651.      SideDefs = GetFarMemory( sizeof( struct SideDef));
  652.       if (copyfrom >= 0)
  653.       {
  654.      SideDefs[ last].xoff = SideDefs[ copyfrom].xoff;
  655.      SideDefs[ last].yoff = SideDefs[ copyfrom].yoff;
  656.      strncpy( SideDefs[ last].tex1, SideDefs[ copyfrom].tex1, 8);
  657.      strncpy( SideDefs[ last].tex2, SideDefs[ copyfrom].tex2, 8);
  658.      strncpy( SideDefs[ last].tex3, SideDefs[ copyfrom].tex3, 8);
  659.      SideDefs[ last].sector = SideDefs[ copyfrom].sector;
  660.       }
  661.       else
  662.       {
  663.      SideDefs[ last].xoff = 0;
  664.      SideDefs[ last].yoff = 0;
  665.      strcpy( SideDefs[ last].tex1, "-");
  666.      strcpy( SideDefs[ last].tex2, "-");
  667.      strcpy( SideDefs[ last].tex3, "STARTAN3");
  668.      SideDefs[ last].sector = NumSectors - 1;
  669.       }
  670.       MadeMapChanges = TRUE;
  671.       break;
  672.    case OBJ_VERTEXES:
  673.       last = NumVertexes++;
  674.       if (last > 0)
  675.      Vertexes = ResizeFarMemory( Vertexes, (unsigned long) NumVertexes * sizeof( struct Vertex));
  676.       else
  677.      Vertexes = GetFarMemory( sizeof( struct Vertex));
  678.       Vertexes[ last].x = xpos & ~7;
  679.       Vertexes[ last].y = ypos & ~7;
  680.       MadeMapChanges = TRUE;
  681.       break;
  682.    case OBJ_SECTORS:
  683.       last = NumSectors++;
  684.       if (last > 0)
  685.      Sectors = ResizeFarMemory( Sectors, (unsigned long) NumSectors * sizeof( struct Sector));
  686.       else
  687.      Sectors = GetFarMemory( sizeof( struct Sector));
  688.       if (copyfrom >= 0)
  689.       {
  690.      Sectors[ last].floorh = Sectors[ copyfrom].floorh;
  691.      Sectors[ last].ceilh = Sectors[ copyfrom].ceilh;
  692.      strncpy( Sectors[ last].floort, Sectors[ copyfrom].floort, 8);
  693.      strncpy( Sectors[ last].ceilt, Sectors[ copyfrom].ceilt, 8);
  694.      Sectors[ last].light = Sectors[ copyfrom].light;
  695.      Sectors[ last].special = Sectors[ copyfrom].special;
  696.      Sectors[ last].tag = Sectors[ copyfrom].tag;
  697.       }
  698.       else
  699.       {
  700.      Sectors[ last].floorh = 0;
  701.      Sectors[ last].ceilh = 400;
  702.      strcpy( Sectors[ last].floort,"FLOOR4_8");
  703.      strcpy( Sectors[ last].ceilt, "CEIL3_5");
  704.      Sectors[ last].light = 255;
  705.      Sectors[ last].special = 0;
  706.      Sectors[ last].tag = 0;
  707.       }
  708.       break;
  709.    default:
  710.       Beep();
  711.    }
  712. }
  713.  
  714.  
  715.  
  716. /*
  717.    check if a (part of a) LineDef is inside a given block
  718. */
  719.  
  720. Bool IsLineDefInside( int ldnum, int x0, int y0, int x1, int y1)
  721. {
  722.    int lx0 = Vertexes[ LineDefs[ ldnum].start].x;
  723.    int ly0 = Vertexes[ LineDefs[ ldnum].start].y;
  724.    int lx1 = Vertexes[ LineDefs[ ldnum].end].x;
  725.    int ly1 = Vertexes[ LineDefs[ ldnum].end].y;
  726.    int i;
  727.  
  728.    /* do you like mathematics? */
  729.    if (lx0 >= x0 && lx0 <= x1 && ly0 >= y0 && ly0 <= y1)
  730.       return TRUE; /* the LineDef start is entirely inside the square */
  731.    if (lx1 >= x0 && lx1 <= x1 && ly1 >= y0 && ly1 <= y1)
  732.       return TRUE; /* the LineDef end is entirely inside the square */
  733.    if ((ly0 > y0) != (ly1 > y0))
  734.    {
  735.       i = lx0 + (int) ( (long) (y0 - ly0) * (long) (lx1 - lx0) / (long) (ly1 - ly0));
  736.       if (i >= x0 && i <= x1)
  737.      return TRUE; /* the LineDef crosses the y0 side (left) */
  738.    }
  739.    if ((ly0 > y1) != (ly1 > y1))
  740.    {
  741.       i = lx0 + (int) ( (long) (y1 - ly0) * (long) (lx1 - lx0) / (long) (ly1 - ly0));
  742.       if (i >= x0 && i <= x1)
  743.      return TRUE; /* the LineDef crosses the y1 side (right) */
  744.    }
  745.    if ((lx0 > x0) != (lx1 > x0))
  746.    {
  747.       i = ly0 + (int) ( (long) (x0 - lx0) * (long) (ly1 - ly0) / (long) (lx1 - lx0));
  748.       if (i >= y0 && i <= y1)
  749.      return TRUE; /* the LineDef crosses the x0 side (down) */
  750.    }
  751.    if ((lx0 > x1) != (lx1 > x1))
  752.    {
  753.       i = ly0 + (int) ( (long) (x1 - lx0) * (long) (ly1 - ly0) / (long) (lx1 - lx0));
  754.       if (i >= y0 && i <= y1)
  755.      return TRUE; /* the LineDef crosses the x1 side (up) */
  756.    }
  757.    return FALSE;
  758. }
  759.  
  760.  
  761.  
  762. /* end of file */
  763.