home *** CD-ROM | disk | FTP | other *** search
/ Toolkit for DOOM / DOOMTOOL.ISO / editors / dme301.zip / SOURCE.ZIP / EDITS.C < prev    next >
C/C++ Source or Header  |  1994-08-03  |  62KB  |  2,858 lines

  1. /*
  2.     This is a DMapEdit source code module.  Though it is copyrighted, you
  3.     may modify it and use it for your own personal use, meaning that new
  4.     modified code and anything derived from it (such as exe files) doesn't
  5.     get distributed to anyone, unless you get my permission first.  Code
  6.     from this file, or code based on ideas from this file may be used with
  7.     other programs, provided that you give credit for it in the source code,
  8.     documentation, and 'about' windows or screens, if one exists, for the
  9.     programs using it.  Giving credit means something like this:
  10.  
  11.     Code from DMapEdit was used in this program
  12.  
  13.                               or
  14.  
  15.     Some code for this program was based on ideas presented in DMapEdit
  16.  
  17.     Whatever.  Just be sure to mention "DMapEdit" in such a way that it's
  18.     self-evident how it was useful to the new program, and be sure to have
  19.     "DMapEdit is a trademark of Jason Hoffoss" in the docs.  That's all..
  20. */
  21.  
  22. #include <stdio.h>
  23. #include <graphics.h>  
  24. #include <string.h>
  25. #include <math.h>
  26. #include <limits.h>
  27. #include <alloc.h>
  28. #include <stdlib.h>
  29. #include "dme.h"
  30. #include "dme2.h"
  31.  
  32. #define F_MIN -63
  33. #define F_MAX 63
  34. #define C_MIN -63
  35. #define C_MAX 63
  36.  
  37. void update_button(int num);
  38. int linetype_picklist(int num);
  39. void reprint_linetype(int num, int yy, int max);
  40. int select_fc_textr(char far *farname, int x, int y);
  41. int find_new_id(void);
  42. void add_num_to_list(int num, int *index);
  43. void change_sidedefs(void);
  44. int save_sidedef(int sd1, int sd2, int mask, int sector, int xoffset,
  45.     int yoffset, char *top_tx, char *mid_tx, char *bottom_tx);
  46. void mark_sector(int num);
  47. void mark_line_vertexes(void);
  48.  
  49. uint default_attrib=3;
  50. int default_linedef_type=0;
  51. int default_linedef_trig=0;
  52. int default_sidedef_sector=-1;
  53. int default_xoffset=0;
  54. int default_yoffset=0;
  55. char default_top[8]="-";
  56. char default_middle[8]="STARTAN3";
  57. char default_bottom[8]="-";
  58.  
  59. char default_floor_name[9]="FLOOR4_8";
  60. char default_ceiling_name[9]="CEIL3_5";
  61. int default_light=255;
  62. int default_sector_trig=0;
  63. int default_fheight=0;
  64. int default_cheight=72;
  65. int default_sector_type=0;
  66.  
  67. int lightc=0, lightv=255;
  68. int floorc=0, floorv=0;
  69. int ceilc=0, ceilv=72;
  70. int floortc=0, ceiltc=0;
  71. char floort[9] = "FLOOR4_8";
  72. char ceilt[9] = "CEIL3_5";
  73.  
  74. int cur_line;
  75. int *counts=0;
  76. char saved_image[125]; /* point image background save buffer */
  77.  
  78. int vertex_edit(void)
  79. {
  80.     char image[125], msg[61], count;
  81.     int i, dx, dy, x, y, color, num;
  82.     int cur_vertex=-1, new_vertex, dist, dist_min;
  83.  
  84.     mouse_on();
  85.     mark_mask = 1;
  86.     sync_time();
  87.     if (marked)
  88.     {
  89.         sprintf(msg, "%d vertexes marked", *mvertexes);
  90.         toptext2("", msg);
  91.     }
  92.  
  93.     while(1)
  94.     {
  95.         mouse_check();
  96.         dist_min = 10;
  97.         new_vertex = -1;
  98.         for (i=0; i<max_vertex; i++)
  99.         {
  100.             dx = adjvx[i];
  101.             dy = adjvy[i];
  102.  
  103.             if (dx < point_size ||
  104.                 dy < point_size ||
  105.                 dx > maxx-point_size ||
  106.                 dy > maxy-point_size) continue;
  107.             dx -= mousex;
  108.             dy -= mousey;
  109.             if ((dist = abs(dx) + abs(dy)) < dist_min)
  110.             {
  111.                 dist_min = dist;
  112.                 new_vertex = i;
  113.             }
  114.         }
  115.  
  116.         if (new_vertex != cur_vertex)
  117.         {
  118.             mouse_off();
  119.             if (cur_vertex != -1)
  120.                 putimage(x - point_size, y - point_size, saved_image, 0);
  121.  
  122.             if (new_vertex != -1)
  123.             {
  124.                 x = adjvx[new_vertex];
  125.                 y = adjvy[new_vertex];
  126.                 getimage(x - point_size, y - point_size, x + point_size,
  127.                     y + point_size, saved_image);
  128.                 for (i=0, num=0; i<l_size; i++)
  129.                     if (linedefs[i].v1 == new_vertex ||
  130.                         linedefs[i].v2 == new_vertex)
  131.                             num++;
  132.                 sprintf(msg, "Vertex #%d at (%d, %d), connecting %d line",
  133.                     new_vertex, vertexes[new_vertex].x, vertexes[new_vertex].y,
  134.                     num);
  135.                 if (num != 1)
  136.                     strcat(msg, "s");
  137.                 toptext(msg);
  138.             } else
  139.                 toptext("");
  140.  
  141.             mouse_on();
  142.             cur_vertex = new_vertex;
  143.         }
  144.  
  145.         if (wait(8))
  146.         {
  147.             if (*mvertexes)
  148.             {
  149.                 plot_marked(-1);
  150.                 if (cur_vertex != -1)
  151.                     color_num--;
  152.             }
  153.  
  154.             if (cur_vertex != -1)
  155.                 plot_colored_point(x, y, rand_color());
  156.         }
  157.  
  158.         if (button_status & 1)
  159.         {
  160.             if (*mvertexes)
  161.             {
  162.                 move_marked();
  163.                 return 0;
  164.             }
  165.  
  166.             if (cur_vertex != -1)
  167.                 cur_drag = cur_vertex;
  168.             else if ((cur_drag = add_vertex()) == -1)
  169.             {
  170.                 error("Maximum number of vertexes reached");
  171.                 draw_map();
  172.                 return 0;
  173.             }
  174.             edit_mode = 3;
  175.             mouse_off();
  176.             return 0;
  177.         }
  178.  
  179.         if (button_status & 2)
  180.         {
  181.             if (marked)
  182.             {
  183.                 sort_marked(mvertexes);
  184.                 i = *mvertexes;
  185.                 while (i--)
  186.                     del_vertex(mvertexes[i+2]);
  187.  
  188.                 unmark_all();
  189.                 cur_vertex = -1;
  190.                 draw_map();
  191.                 await_release_on();
  192.  
  193.             } else if (cur_vertex != -1) {
  194.                 del_vertex(cur_vertex);
  195.                 cur_vertex = -1;
  196.                 mouse_off();
  197.                 draw_map();
  198.                 await_release_on();
  199.             }
  200.         }
  201.  
  202.         if (button_status & 8)
  203.         {
  204.             if (cur_vertex != -1)
  205.                 putimage(x - point_size, y - point_size, saved_image, 0);
  206.             if (!boxmark(0) && cur_vertex != -1)
  207.                 mark_vertex(cur_vertex);
  208.  
  209.             toptext2("", "");
  210.             return 0;
  211.         }
  212.  
  213.         if (keypress)
  214.         {
  215.             mouse_off();
  216.             plot_marked(255);
  217.             if (cur_vertex != -1)
  218.                 putimage(x - point_size, y - point_size, saved_image, 0);
  219.             toptext2("", "");
  220.             return keypress;
  221.         }
  222.     }
  223. }
  224.  
  225. int vertex_drag(void)
  226. {
  227.     char image[125];
  228.     int i, x, y, num, color, count;
  229.  
  230.     x = adjvx[cur_drag];
  231.     y = adjvy[cur_drag];
  232.  
  233.     mouse_on();
  234.     while (1)
  235.     {
  236.         if (!(mouse_check() & 1))
  237.         {
  238.             vertexes[cur_drag].x = x = re_x();
  239.             vertexes[cur_drag].y = y = re_y();
  240.             for (i=0; i<max_vertex; i++)
  241.                 if (x == vertexes[i].x && y == vertexes[i].y && i != cur_drag)
  242.                 {
  243.                     for (num=0; num<l_size; num++)
  244.                     {
  245.                         if (linedefs[num].v1 == i)
  246.                             linedefs[num].v1 = cur_drag;
  247.                         if (linedefs[num].v2 == i)
  248.                             linedefs[num].v2 = cur_drag;
  249.                     }
  250.                     del_vertex(i);
  251.                     if (cur_drag > i)
  252.                         cur_drag--;
  253.                     i--;
  254.                 }
  255.  
  256.             mouse_off();
  257.             draw_map();
  258.             edit_mode = 2;
  259.             return 0;
  260.         }
  261.  
  262.         if (button_status & 2)
  263.         {
  264.             del_vertex(cur_drag);
  265.             mouse_off();
  266.             draw_map();
  267.             await_release();
  268.             edit_mode = 2;
  269.             return 0;
  270.         }
  271.  
  272.         if (wait(8))
  273.             plot_colored_point(x, y, rand_color());
  274.     }
  275. }
  276.  
  277. int line_edit(void)
  278. {
  279.     char msg[125], msg2[90], bitstr[17], top_texture[9], mid_texture[9];
  280.     char bottom_texture[9];
  281.     int i, j, line, dist, dist_min, new_line, counter, id;
  282.     int new_vertex, cur_vertex=-1, color, count, len;
  283.     int v1, v2, x, y, x1, x2, y1, y2, dx, dy;
  284.     int side, old_side=-1, sidedef, old_sd=-1;
  285.     uint angle, mask;
  286.  
  287.     char bits[] = "0123456789ABCDEF";
  288.     char *side_dir[] = { "Left", "Right" };
  289.     char *sides[] = { "0 sidedefs", "1 sidedef", "2 sidedefs" };
  290.  
  291.     cur_line = -1;
  292.     mark_mask = 3;
  293.     mouse_on();
  294.     sync_time();
  295.     while (1)
  296.     {
  297.         mouse_check();
  298.         dist_min = 15;
  299.         new_line = -1;
  300.         for (i=0; i<ll_size; i++) /* this loop finds the closest line */
  301.         {                         /* to the mouse cursor */
  302.             line = llines[i];
  303.             v1 = linedefs[line].v1;
  304.             v2 = linedefs[line].v2;
  305.             x1 = adjvx[v1];
  306.             x2 = adjvx[v2];
  307.             y1 = adjvy[v1];
  308.             y2 = adjvy[v2];
  309.             dist = line_dist(x1, y1, x2, y2);
  310.             if (dist < dist_min)
  311.             {
  312.                 dist_min = dist;
  313.                 new_line = line;
  314.                 if (side = (line_side(line, mouse_x, mouse_y) < 0))
  315.                     side = 1;
  316.             }
  317.         }
  318.         if (side)
  319.             sidedef = linedefs[new_line].sd1;
  320.         else
  321.             sidedef = linedefs[new_line].sd2;
  322.  
  323.         new_vertex = -1;
  324.         dist_min = 8;
  325.         for (i=0; i<max_vertex; i++)
  326.         {
  327.             dx = adjvx[i];
  328.             dy = adjvy[i];
  329.  
  330.             if (dx < point_size ||
  331.                 dy < point_size ||
  332.                 dx > maxx-point_size ||
  333.                 dy > maxy-point_size) continue;
  334.  
  335.             dx -= mousex;
  336.             dy -= mousey;
  337.  
  338.             if ((dist = abs(dx) + abs(dy)) < dist_min)
  339.             {
  340.                 dist_min = dist;
  341.                 new_vertex = i;
  342.             }
  343.         }
  344.  
  345.         if (new_vertex != cur_vertex)
  346.         {
  347.             mouse_off();
  348.             if (cur_vertex != -1)
  349.                 putimage(x - point_size, y - point_size, saved_image, 0);
  350.             if (new_vertex != -1)
  351.             {
  352.                 x = adjvx[new_vertex];
  353.                 y = adjvy[new_vertex];
  354.                 getimage(x - point_size, y - point_size, x + point_size,
  355.                     y + point_size, saved_image);
  356.             }
  357.             mouse_on();
  358.             cur_vertex = new_vertex;
  359.         }
  360.  
  361.         if (new_line != cur_line || sidedef != old_sd || side != old_side)
  362.         {
  363.             if (cur_line != -1)
  364.             {
  365.                 mouse_off();
  366.                 line_and_seg(cur_line);
  367.                 mouse_on();
  368.             }
  369.             cur_line = new_line;
  370.             old_sd = sidedef;
  371.             old_side = side;
  372.             if (new_line != -1)
  373.             {
  374.                 strcpy(bitstr, "................");
  375.                 for (i=0, mask=1; i<16; i++, mask <<= 1)
  376.                 {
  377.                     if (linedefs[new_line].attrib & mask)
  378.                         bitstr[i] = bits[i];
  379.                 }
  380.                 count = 0;
  381.                 if (linedefs[new_line].sd1 != -1)
  382.                     count++;
  383.                 if (linedefs[new_line].sd2 != -1)
  384.                     count++;
  385.                 dx = vertexes[linedefs[new_line].v1].x -
  386.                     vertexes[linedefs[new_line].v2].x;
  387.                 dy = vertexes[linedefs[new_line].v1].y -
  388.                     vertexes[linedefs[new_line].v2].y;
  389.                 len = sqrt((double) dx * dx + (double) dy * dy);
  390.                 sprintf(msg, "Line #%d: type: %d, attrib: %s, trig: %d, "
  391.                     "%s, len: %d", new_line, linedefs[new_line].type, bitstr,
  392.                     linedefs[new_line].trig, sides[count], len);
  393.                 if (sidedef == -1)
  394.                     sprintf(msg2, "%s (No Sidedef)", side_dir[side]);
  395.                 else {
  396.                     for (i=0; i<8; i++)
  397.                     {
  398.                         top_texture[i] = sidedefs[sidedef].top[i];
  399.                         mid_texture[i] = sidedefs[sidedef].middle[i];
  400.                         bottom_texture[i] = sidedefs[sidedef].bottom[i];
  401.                     }
  402.                     top_texture[8] = mid_texture[8] = bottom_texture[8] = 0;
  403.                     sprintf(msg2, "%s Sidedef #%d: sector: %d, textures: (%s) "
  404.                         "(%s) (%s), shift: (%d,%d)", side_dir[side], sidedef,
  405.                         sidedefs[sidedef].sector, top_texture, mid_texture,
  406.                         bottom_texture, sidedefs[sidedef].xoffset,
  407.                         sidedefs[sidedef].yoffset);
  408.                     if (strlen(msg2) * 8 > maxx)
  409.                         sprintf(msg2, "%s Sidef #%d: sec: %d, txtrs: (%s) (%s) "
  410.                             "(%s), sh: (%d,%d)", side_dir[side], sidedef,
  411.                             sidedefs[sidedef].sector, top_texture, mid_texture,
  412.                             bottom_texture, sidedefs[sidedef].xoffset,
  413.                             sidedefs[sidedef].yoffset);
  414.                 }
  415.                 setcolor(255);
  416.                 toptext2(msg, msg2);
  417.             } else toptext2("", "");
  418.         }
  419.  
  420.         if (wait(8))
  421.         {
  422.             if (marked)
  423.             {
  424.                 plot_marked(-1);
  425.                 color_num--;
  426.             }
  427.  
  428.             rand_color();
  429.             if (new_line != -1)
  430.             {
  431.                 draw_line(new_line, SOLID_LINE);
  432.                 mouse_redraw();
  433.                 if (id = linedefs[new_line].trig) /* is linked to a sector */
  434.                     for (i=0; i<sec_size; i++)
  435.                         if (sectors[i].trig == id) /* sector linked to */
  436.                             for (j=0; j<l_size; j++)
  437.                                 if (((line = linedefs[j].sd1) != -1 &&
  438.                                     sidedefs[line].sector == i) ||
  439.                                     ((line = linedefs[j].sd2) != -1 &&
  440.                                     sidedefs[line].sector == i))
  441.                                         draw_line(j, DOTTED_LINE);
  442.                 mouse_redraw();
  443.             }
  444.  
  445.             if (new_vertex != -1)
  446.                 plot_colored_point(x, y, stagger_color());
  447.         }
  448.  
  449.         if (button_status & 1)
  450.         {
  451.             if (*mvertexes)
  452.             {
  453.                 move_marked();
  454.                 return 0;
  455.             }
  456.  
  457.             if (l_size == l_max)
  458.             {
  459.                 void far *ptr;
  460.  
  461.                 if (!l_max)
  462.                     ptr = get_farmem(20 * sizeof(struct l_struct), "Linedefs");
  463.                 else
  464.                     ptr = resize_farmem(linedefs, (l_max+20) *
  465.                         sizeof(struct l_struct), "Linedefs");
  466.                 if (!ptr)
  467.                     return -1;
  468.                 linedefs = ptr;
  469.                 l_max += 20;
  470.             }
  471.  
  472.             if (cur_vertex != -1)
  473.             {
  474.                 edit_mode = 5;
  475.                 cur_drag = cur_vertex;
  476.             } else {
  477.                 if ((cur_drag = add_vertex()) == -1)
  478.                 {
  479.                     error("Maximum number of vertexes reached");
  480.                     draw_map();
  481.                     return 0;
  482.                 }
  483.  
  484.                 if (cur_line != -1)
  485.                     edit_mode = 6;
  486.                 else
  487.                     edit_mode = 5;
  488.             }
  489.             mouse_off();
  490.             if (cur_line != -1)
  491.                 line_and_seg(cur_line);
  492.             return 0;
  493.         }
  494.  
  495.         if (button_status & 2)
  496.         {
  497.             if (marked)
  498.             {
  499.                 sort_marked(mlinedefs);
  500.                 i = *mlinedefs;
  501.                 while (i--)
  502.                     del_line(mlinedefs[i+2]);
  503.  
  504.                 unmark_all();
  505.                 cur_line = cur_vertex = -1;
  506.                 mouse_off();
  507.                 draw_map();
  508.                 await_release_on();
  509.  
  510.             } else if (cur_line != -1) {
  511.                 del_line(cur_line);
  512.                 cur_line = cur_vertex = -1;
  513.                 mouse_off();
  514.                 draw_map();
  515.                 await_release_on();
  516.  
  517.             } else if (cur_vertex != -1) {
  518.                 del_vertex(cur_vertex);
  519.                 cur_line = cur_vertex = -1;
  520.                 mouse_off();
  521.                 draw_map();
  522.                 await_release_on();
  523.             }
  524.         }
  525.  
  526.         if ((button_status & 4) && (cur_line != -1 || *mlinedefs))
  527.         {
  528.             mouse_off();
  529.             if (cur_vertex != -1)
  530.                 putimage(x-point_size, y-point_size, saved_image, 0);
  531.             if (cur_line != -1)
  532.                 line_and_seg(cur_line);
  533.             i = 0;
  534.             if (sidedef == linedefs[new_line].sd1)
  535.                 i++;
  536.             change_line(new_line, i);
  537.             cur_vertex = -1;
  538.             cur_line = -1;
  539.         }
  540.  
  541.         if (button_status & 8)
  542.         {
  543.             mouse_off();
  544.             if (cur_vertex != -1)
  545.                 putimage(x-point_size, y-point_size, saved_image, 0);
  546.             if (cur_line != -1)
  547.                 line_and_seg(cur_line);
  548.  
  549.             if (!boxmark(1))
  550.             {
  551.                 if (cur_line != -1)
  552.                 {
  553.                     mark_line(cur_line);
  554.                     mark_line_vertexes();
  555.  
  556.                 } else if (cur_vertex != -1)
  557.                     mark_vertex(cur_vertex);
  558.             }
  559.             toptext2("", "");
  560.             return 0;
  561.         }
  562.  
  563.         if (keypress)
  564.         {
  565.             if (keypress == 1034)
  566.             {
  567.                 fix_sidedefs(new_line);
  568.                 continue;
  569.             }
  570.  
  571.             if (keypress == 'f')
  572.             {
  573.                 v1 = linedefs[new_line].v1;
  574.                 linedefs[new_line].v1 = linedefs[new_line].v2;
  575.                 linedefs[new_line].v2 = v1;
  576.  
  577.                 i = linedefs[new_line].sd1;
  578.                 linedefs[new_line].sd1 = linedefs[new_line].sd2;
  579.                 linedefs[new_line].sd2 = i;
  580.                 flip_line(new_line);
  581.                 cur_line = -1;
  582.                 continue;
  583.             }
  584.  
  585.             if (keypress == 1033)
  586.             {
  587.                 v1 = linedefs[new_line].v1;
  588.                 linedefs[new_line].v1 = linedefs[new_line].v2;
  589.                 linedefs[new_line].v2 = v1;
  590.                 cur_line = -1;
  591.                 continue;
  592.             }
  593.  
  594.             plot_marked(255);
  595.             if (cur_vertex != -1)
  596.                 putimage(x-point_size, y-point_size, saved_image, 0);
  597.             mouse_off();
  598.             if (cur_line != -1)
  599.                 line_and_seg(cur_line);
  600.             toptext2("", "");
  601.             return keypress;
  602.         }
  603.     }
  604. }
  605.  
  606. /* edit mode 5: Add line between 2 points (make second point if needed) */
  607.  
  608. int line_drag1(void)
  609. {
  610.     char image[125], image2[125], saved_point[125];
  611.     int i, num, color, xcolor, last_color, count, cur_vertex=-1, new_vertex;
  612.     int dx, dy, x1, y1, x2, y2, x3, y3, dist_min, dist, cross_status;
  613.  
  614.     x1 = x3 = adjvx[cur_drag];
  615.     y1 = y3 = adjvy[cur_drag];
  616.  
  617.     mouse_on();
  618.     while (1)
  619.     {
  620.         mouse_check();
  621.         dist_min = 10;
  622.         new_vertex = -1;
  623.         for (i=0; i<max_vertex; i++)
  624.         {
  625.             dx = adjvx[i];
  626.             dy = adjvy[i];
  627.  
  628.             if (dx < point_size ||
  629.                 dy < point_size ||
  630.                 dx > maxx-point_size ||
  631.                 dy > maxy-point_size) continue;
  632.             dx -= mousex;
  633.             dy -= mousey;
  634.             if ((dist = abs(dx) + abs(dy)) < dist_min)
  635.             {
  636.                 dist_min = dist;
  637.                 new_vertex = i;
  638.             }
  639.         }
  640.  
  641.         if (new_vertex != cur_vertex)
  642.         {
  643.             mouse_off();
  644.             if (cur_vertex != -1)
  645.                 putimage(x2 - point_size, y2 - point_size, saved_point, 0);
  646.             if (new_vertex != -1)
  647.             {
  648.                 x2 = adjvx[new_vertex];
  649.                 y2 = adjvy[new_vertex];
  650.                 getimage(x2 - point_size, y2 - point_size, x2 + point_size,
  651.                     y2 + point_size, saved_point);
  652.             }
  653.             mouse_on();
  654.             cur_vertex = new_vertex;
  655.         }
  656.  
  657.         if (new_vertex == -1)
  658.         {
  659.             x2 = crossx + 2;
  660.             y2 = crossy + 2;
  661.         }
  662.  
  663.         if (!(button_status & 1))
  664.         {
  665.             if (cur_vertex == cur_drag)
  666.             {
  667.                 mouse_off();
  668.                 edit_mode = 4;
  669.                 return 0;
  670.             }
  671.  
  672.             if (cur_vertex == -1)
  673.             {
  674.                 if ((cur_vertex = add_vertex()) == -1)
  675.                 {
  676.                     error("Maximum number of vertexes reached");
  677.                     draw_map();
  678.                     edit_mode = 4;
  679.                     return 0;
  680.                 }
  681.  
  682.             } else
  683.                 for (i=0; i<max_vertex; i++)
  684.                 {
  685.                     dx = linedefs[i].v1;
  686.                     dy = linedefs[i].v2;
  687.                     if ((cur_drag == dx && cur_vertex == dy) ||
  688.                         (cur_drag == dy && cur_vertex == dx)) /* check for overlap */
  689.                     {
  690.                         draw_map(); /* leave without creating it */
  691.                         edit_mode = 4;
  692.                         return 0;
  693.                     }
  694.                 }
  695.  
  696.             linedefs[l_size].v1 = cur_drag;
  697.             linedefs[l_size].v2 = cur_vertex;
  698.             linedefs[l_size].attrib = 3;
  699.             linedefs[l_size].type = 0;
  700.             linedefs[l_size].trig = 0;
  701.             linedefs[l_size].sd1 = -1;
  702.             linedefs[l_size].sd2 = -1;
  703.  
  704.             if (!match_line(cur_drag, cur_vertex))
  705.                 if (match_line(cur_vertex, cur_drag))
  706.                 {
  707.                     num = linedefs[l_size].sd1;
  708.                     linedefs[l_size].sd1 = linedefs[l_size].sd2;
  709.                     linedefs[l_size].sd2 = num;
  710.                 }
  711.             flip_line(l_size);
  712.             l_size++;
  713.  
  714.             mouse_off();
  715.             draw_map();
  716.             edit_mode = 4;
  717.             return 0;
  718.         }
  719.  
  720.         if (button_status & 2)
  721.         {
  722.             mouse_off();
  723.             draw_map();
  724.             await_release();
  725.             edit_mode = 4;
  726.             return 0;
  727.         }
  728.  
  729.         if (wait(8))
  730.         {
  731.             color = rand_color();
  732.             mouse_off();
  733.             setwritemode(XOR_PUT);
  734.             if (x2 == x3 && y2 == y3)
  735.                 setcolor(color ^ last_color);
  736.             else {
  737.                 if (x1 != x3 || y1 != y3)
  738.                 {
  739.                     setcolor(last_color);
  740.                     line(x1, y1, x3, y3);
  741.                 }
  742.                 x3 = x2;
  743.                 y3 = y2;
  744.                 setcolor(color);
  745.             }
  746.  
  747.             if (x1 != x2 || y1 != y2)
  748.                 line(x1, y1, x2, y2);
  749.  
  750.             setwritemode(COPY_PUT);
  751.             last_color = color;
  752.             color = stagger_color();
  753.  
  754.             for (i=0; i<4; i++)
  755.                 image[i] = image2[i] = point_ptr[point_size-1][i];
  756.             for (i=4; i<125; i++)
  757.             {
  758.                 if (point_ptr[point_size-1][i])
  759.                     image[i] = image2[i] = color;
  760.                 else {
  761.                     image[i] = saved_image[i];
  762.                     image2[i] = saved_point[i];
  763.                 }
  764.             }
  765.  
  766.             putimage(x1-point_size, y1-point_size, image, 0);
  767.             if (cur_vertex != -1)
  768.                 putimage(x2-point_size, y2-point_size, image2, 0);
  769.  
  770.             if ((crossx+2 == x1 && crossy+2 == y1) || (crossx+2 == x2 &&
  771.                 crossy+2 == y2))
  772.                     cross_on = 0;
  773.             mouse_on();
  774.         }
  775.     }
  776. }
  777.  
  778. /* edit mode 6: split existing line in half */
  779.  
  780. int line_drag2(void)
  781. {
  782.     char image[125], image2[125];
  783.     int i, num, color, last_color, count, cur_vertex=-1;
  784.     int dx, dy, x, y, xx, yy, x1, y1, x2, y2, xx1, yy1, xx2, yy2;
  785.     int dist_min, dist, vertex1;
  786.  
  787.     x1 = adjvx[linedefs[cur_line].v1];
  788.     x2 = adjvx[linedefs[cur_line].v2];
  789.     y1 = adjvy[linedefs[cur_line].v1];
  790.     y2 = adjvy[linedefs[cur_line].v2];
  791.  
  792.     setcolor(0);
  793.     line(x1, y1, x2, y2);
  794.  
  795.     vertex1 = max_vertex - 1;
  796.     x = xx = adjvx[vertex1];
  797.     y = yy = adjvy[vertex1];
  798.     getimage(x - point_size, y - point_size, x + point_size,
  799.         y + point_size, saved_image);
  800.  
  801.     setwritemode(XOR_PUT);
  802.     last_color = rand_color();
  803.     line(x, y, x1, y1);
  804.     line(x, y, x2, y2);
  805.     setwritemode(COPY_PUT);
  806.  
  807.     mouse_on();
  808.     while (1)
  809.     {
  810.         mouse_check();
  811.         dist_min = 10;
  812.         cur_vertex = -1;
  813.         for (i=0; i<max_vertex-1; i++)
  814.         {
  815.             dx = adjvx[i];
  816.             dy = adjvy[i];
  817.  
  818.             if (dx < point_size ||
  819.                 dy < point_size ||
  820.                 dx > maxx-point_size ||
  821.                 dy > maxy-point_size) continue;
  822.  
  823.             dx -= mousex;
  824.             dy -= mousey;
  825.             if ((dist = abs(dx) + abs(dy)) < dist_min)
  826.             {
  827.                 dist_min = dist;
  828.                 cur_vertex = i;
  829.             }
  830.         }
  831.  
  832.         if (cur_vertex == -1)
  833.         {
  834.             x = crossx + 2;
  835.             y = crossy + 2;
  836.         } else {
  837.             x = adjvx[cur_vertex];
  838.             y = adjvy[cur_vertex];
  839.         }
  840.  
  841.         if (!(button_status & 1))
  842.         {
  843.             if (cur_vertex == linedefs[cur_line].v1 ||
  844.                 cur_vertex == linedefs[cur_line].v2)
  845.             {
  846.                 mouse_off();
  847.                 putimage(xx - point_size, yy - point_size, saved_image, 0);
  848.                 max_vertex--;
  849.                 v_size--;
  850.                 edit_mode = 4;
  851.                 return 0;
  852.             }
  853.  
  854.             if (cur_vertex != -1)
  855.             {
  856.                 vertex1 = cur_vertex;
  857.                 max_vertex--;
  858.                 v_size--;
  859.  
  860.             } else {
  861.                 vertexes[vertex1].x = re_x();
  862.                 vertexes[vertex1].y = re_y();
  863.             }
  864.  
  865.             linedefs[l_size].v1 = vertex1;
  866.             linedefs[l_size].v2 = linedefs[cur_line].v2;
  867.             linedefs[l_size].attrib = linedefs[cur_line].attrib;
  868.             linedefs[l_size].type = linedefs[cur_line].type;
  869.             linedefs[l_size].trig = linedefs[cur_line].trig;
  870.  
  871.             if ((num = linedefs[cur_line].sd1) == -1)
  872.                 linedefs[l_size].sd1 = -1;
  873.             else if ((linedefs[l_size].sd1 = add_sidedef(num)) == -1)
  874.                     return 0;
  875.  
  876.             if ((num = linedefs[cur_line].sd2) == -1)
  877.                 linedefs[l_size].sd2 = -1;
  878.             else if ((linedefs[l_size].sd2 = add_sidedef(num)) == -1)
  879.                     return 0;
  880.  
  881.             flip_line(l_size);
  882.             l_size++;
  883.             linedefs[cur_line].v2 = vertex1;
  884.  
  885.             mouse_off();
  886.             draw_map();
  887.             edit_mode = 4;
  888.             return 0;
  889.         }
  890.  
  891.         if (button_status & 2)
  892.         {
  893.             mouse_off();
  894.             draw_map();
  895.             max_vertex--;
  896.             v_size--;
  897.             await_release();
  898.             edit_mode = 4;
  899.             return 0;
  900.         }
  901.  
  902.         if (wait(8))
  903.         {
  904.             color = rand_color();
  905.             mouse_off();
  906.  
  907.             if (x == xx && y == yy)
  908.                 setcolor(color ^ last_color);
  909.             else {
  910.                 setcolor(last_color);
  911.                 setwritemode(XOR_PUT);
  912.                 if (x1 != xx || y1 != yy)
  913.                     line(xx, yy, x1, y1);
  914.                 if (x2 != xx || y2 != yy)
  915.                     line(xx, yy, x2, y2);
  916.                 setwritemode(COPY_PUT);
  917.                 setcolor(color);
  918.  
  919.                 putimage(xx - point_size, yy - point_size, saved_image, 0);
  920.                 getimage(x - point_size, y - point_size, x + point_size,
  921.                     y + point_size, saved_image);
  922.                 xx = x;
  923.                 yy = y;
  924.             }
  925.  
  926.             setwritemode(XOR_PUT);
  927.             if (x != x1 || y != y1)
  928.                 line(x, y, x1, y1);
  929.             if (x != x2 || y != y2)
  930.                 line(x, y, x2, y2);
  931.             setwritemode(COPY_PUT);
  932.  
  933.             last_color = color;
  934.             mouse_on();
  935.             plot_colored_point(x, y, stagger_color());
  936.         }
  937.     }
  938. }
  939.  
  940. void line_and_seg(int num)
  941. {
  942.     int i, j, id, sd;
  943.  
  944.     wall_color(num);
  945.     draw_line(num, SOLID_LINE);
  946.     if (id = linedefs[num].trig) /* is linked to a sector */
  947.         for (i=0; i<sec_size; i++)
  948.             if (sectors[i].trig == id) /* sector linked to */
  949.                 for (j=0; j<l_size; j++)
  950.                     if (((sd = linedefs[j].sd1) != -1 &&
  951.                         sidedefs[sd].sector == i) ||
  952.                         ((sd = linedefs[j].sd2) != -1 &&
  953.                         sidedefs[sd].sector == i))
  954.                     {
  955.                         wall_color(j);
  956.                         draw_line(j, DOTTED_LINE);
  957.                     }
  958.     return;
  959. }
  960.  
  961. void change_line(int line_num, int cur_side)
  962. {
  963.     char msg[8192], name[9], top_tx1[9], mid_tx1[9], bottom_tx1[9];
  964.     char msg2[20], top_tx2[9], mid_tx2[9], bottom_tx2[9];
  965.     int i, j, sd1, sd2, type, trig, button, b2, sd, num, x=57, y=29;
  966.     int sector1, sector2, xoffset1, xoffset2, yoffset1, yoffset2;
  967.     int init=0;
  968.     uint attrib;
  969.  
  970.     int bits[] = { 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x100 };
  971.  
  972.     char *text1 = "%s\t\n"
  973.         "@  Sector facing: %d\n"
  974.         "@    Top texture: %s\n"
  975.         "@ Middle texture: %s\n"
  976.         "@ Bottom texture: %s\n"
  977.         "@    Horz. shift: %d\n"
  978.         "@    Vert. shift: %d\n\n"
  979.         "@ Delete this sidedef\n";
  980.  
  981.     if (line_num == -1)
  982.     {
  983.         attrib = default_attrib;
  984.         type = default_linedef_type;
  985.         trig = default_linedef_trig;
  986.         sd1 = sd2 = -1;
  987.  
  988.     } else {
  989.         attrib = linedefs[line_num].attrib;
  990.         type = linedefs[line_num].type;
  991.         trig = linedefs[line_num].trig;
  992.  
  993.         sd1 = linedefs[line_num].sd1;
  994.         if (sd1 != -1)
  995.         {
  996.             sector1 = sidedefs[sd1].sector;
  997.             xoffset1 = sidedefs[sd1].xoffset;
  998.             yoffset1 = sidedefs[sd1].yoffset;
  999.             for (i=0; i<8; i++)
  1000.             {
  1001.                 top_tx1[i] = sidedefs[sd1].top[i];
  1002.                 mid_tx1[i] = sidedefs[sd1].middle[i];
  1003.                 bottom_tx1[i] = sidedefs[sd1].bottom[i];
  1004.             }
  1005.         }
  1006.  
  1007.         sd2 = linedefs[line_num].sd2;
  1008.         if (sd2 != -1)
  1009.         {
  1010.             sector2 = sidedefs[sd2].sector;
  1011.             xoffset2 = sidedefs[sd2].xoffset;
  1012.             yoffset2 = sidedefs[sd2].yoffset;
  1013.             for (i=0; i<8; i++)
  1014.             {
  1015.                 top_tx2[i] = sidedefs[sd2].top[i];
  1016.                 mid_tx2[i] = sidedefs[sd2].middle[i];
  1017.                 bottom_tx2[i] = sidedefs[sd2].bottom[i];
  1018.             }
  1019.         }
  1020.     }
  1021.     top_tx1[8] = top_tx2[8] = mid_tx1[8] = mid_tx2[8] =
  1022.         bottom_tx1[8] = bottom_tx2[8] = 0;
  1023.  
  1024.     if (*mlinedefs)
  1025.         init = -2;
  1026.     set_button_statuses(init);
  1027.  
  1028. redraw:
  1029.     set_window(x, y, 1);
  1030.     strcpy(msg+4096, "^?? <Unknown effect> ??");
  1031.     for (i=0; i<linetype_max; i++)
  1032.         if (linetypes[i] == type)
  1033.             _fstrcpy(msg+2048, linetype_names[i]);
  1034.  
  1035.     strcpy(msg+4097, msg+2053);
  1036.     msg[4101+x] = 0;
  1037.     strcat(msg+4096, "\t");
  1038.     strcpy(msg+2052, ")");
  1039.  
  1040.     if (*mlinedefs)
  1041.         strcpy(msg, "Change marked Linedefs\t");
  1042.     else
  1043.         sprintf(msg, "Change Linedef #%d\t", line_num);
  1044.     text_to_window(0, 0, msg, x);
  1045.  
  1046.     sprintf(msg, "@ Type: %-3d (%-15s  @ Trigger id: %-4d @ Auto\t",
  1047.         type, msg+2048, trig);
  1048.     text_to_window(0, 3, msg, x);
  1049.     text_to_window(0, 5, msg+4096, x);
  1050.  
  1051.     text_to_window(1, 7,
  1052.         "@ Players and monster can't cross this line\n"
  1053.         "@ Monsters can't cross this line\n"
  1054.         "@ Transparent Sidedef textures allowed in line\n"
  1055.         "@ Top texture is not pegged\n"
  1056.         "@ Bottom texture is not pegged\n"
  1057.         "@ Show line as a wall on automap (Secret door)\n"
  1058.         "@ Sound doesn't cross this line\n"
  1059.         "@ Line never appears on the automap\n"
  1060.         "@ Line already discovered on the automap\n", 0);
  1061.  
  1062.     if (sd2 == -1)
  1063.         strcpy(msg, "Left Sidedef: none\t\n"
  1064.             "@ Add Sidedef\t");
  1065.     else
  1066.     {
  1067.         if (sd2 == -2)
  1068.             strcpy(msg2, "Left Sidedef: new");
  1069.         else
  1070.             sprintf(msg2, "Left Sidedef: %d", sd2);
  1071.  
  1072.         sprintf(msg, text1, msg2, sector2, top_tx2, mid_tx2,
  1073.             bottom_tx2, xoffset2, yoffset2);
  1074.     }
  1075.     text_to_window(1, 18, msg, 26);
  1076.  
  1077.     if (sd1 == -1)
  1078.         sprintf(msg, "Right Sidedef: none\t\n"
  1079.             "@ Add Sidedef\t");
  1080.     else
  1081.     {
  1082.         if (sd1 == -2)
  1083.             strcpy(msg2, "Right Sidedef: new");
  1084.         else
  1085.             sprintf(msg2, "Right Sidedef: %d", sd1);
  1086.  
  1087.         sprintf(msg, text1, msg2, sector1, top_tx1, mid_tx1,
  1088.             bottom_tx1, xoffset1, yoffset1);
  1089.     }
  1090.     text_to_window(30, 18, msg, 26);
  1091.  
  1092.     draw_buttons();
  1093.     set_window_bars();
  1094.     i = (win.left + win.right) / 2;
  1095.     j = win.top + 177;
  1096.     setcolor(82);
  1097.     line(win.left-1, j, win.right, j);
  1098.     setcolor(86);
  1099.     line(win.left, j+1, win.right, j+1);
  1100.     line(i, j+1, i, win.bottom);
  1101.     setcolor(82);
  1102.     line(i-1, j, i-1, win.bottom);
  1103.     setcolor(254);
  1104.     if (line_num != -1)
  1105.         outtextxy(win.left + cur_side*232 - cur_side, win.top + 179, "\x07");
  1106.  
  1107.     for (i=0; i<9; i++)
  1108.         if (attrib & bits[i])
  1109.             b.pos[i+3].on = 1;
  1110.  
  1111.     while (1)
  1112.     {
  1113.         draw_buttons();
  1114.         if ((button = b2 = window_check()) < 0)
  1115.             break;
  1116.  
  1117.         if (button_status & 4 && *mlinedefs && button != 2)
  1118.         {
  1119.             if (b.pos[button].status == -2)
  1120.                 b.pos[button].status = 0;
  1121.             else
  1122.                 b.pos[button].status = -2;
  1123.             continue;
  1124.         }
  1125.  
  1126.         if (button == 0)
  1127.         {
  1128.             update_button(0);
  1129.             if (true_button & 1)
  1130.             {
  1131.                 type = linetype_picklist(type);
  1132.                 draw_map();
  1133.                 goto redraw;
  1134.  
  1135.             } else {
  1136.                 type = get_number(9, 3, type, 999, 0);
  1137.                 strcpy(msg, "?? <Unknown effect> ??");
  1138.                 for (i=0; i<linetype_max; i++)
  1139.                     if (linetypes[i] == type)
  1140.                         _fstrcpy(msg+4096, linetype_names[i]);
  1141.  
  1142.                 strcpy(msg, msg+4101);
  1143.                 msg[x] = 0;
  1144.                 strcpy(msg+4099, ")");
  1145.  
  1146.                 erase_text(win.left + 116, win.top + 34, 15);
  1147.                 text(win.left + 116, win.top + 34, msg + 4096);
  1148.  
  1149.                 i = midx - strlen(msg) * 4;
  1150.                 erase_text(win.left + 4, win.top + 54, x);
  1151.                 text_color = 128;
  1152.                 text(i, win.top + 54, msg);
  1153.                 text_color = 255;
  1154.             }
  1155.             continue;
  1156.         }
  1157.  
  1158.         if (button == 1)
  1159.         {
  1160.             update_button(1);
  1161.             draw_buttons();
  1162.             trig = get_number(45, 3, trig, 9999, -999);
  1163.             continue;
  1164.         }
  1165.  
  1166.         if (button == 2)
  1167.         {
  1168.             trig = find_new_id();
  1169.             sprintf(msg, "%d", trig);
  1170.             erase_text(win.left + 364, win.top + 34, 4);
  1171.             text(win.left + 364, win.top + 34, msg);
  1172.             update_button(1);
  1173.             continue;
  1174.         }
  1175.  
  1176.         if (button > 2 && button < 12)
  1177.         {
  1178.             update_button(button);
  1179.             attrib ^= bits[button-3];
  1180.             b.pos[button].on ^= 1;
  1181.             continue;
  1182.         }
  1183.  
  1184.         button -= 12;
  1185.         i = 7;
  1186.         if (sd2 == -1)
  1187.             i = 1;
  1188.  
  1189.         if (button < i)
  1190.         {
  1191.             if (sd2 == -1)
  1192.             {
  1193.                 sd2 = -2;
  1194.                 sector2 = -1;
  1195.                 strncpy(top_tx2, default_top, 8);
  1196.                 strncpy(mid_tx2, default_middle, 8);
  1197.                 strncpy(bottom_tx2, default_bottom, 8);
  1198.                 xoffset2 = default_xoffset;
  1199.                 yoffset2 = default_yoffset;
  1200.  
  1201.                 i = 7;
  1202.                 while (i--)
  1203.                     b.pos[19+i].status = b.pos[13+i].status;
  1204.  
  1205.                 for (i=0; i<7; i++)
  1206.                     b.pos[12+i].status = init;
  1207.  
  1208.                 b.pos[18].status = 0;
  1209.                 goto redraw;
  1210.             }
  1211.  
  1212.             switch (button)
  1213.             {
  1214.                 case 0:
  1215.                     update_button(b2);
  1216.                     sector2 = get_number(19, 20, sector2, 32767, 0);
  1217.                     break;
  1218.  
  1219.                 case 1:
  1220.                     update_button(b2);
  1221.                     if (select_wall_textr(top_tx2, 156, 214))
  1222.                         goto redraw;
  1223.                     break;
  1224.  
  1225.                 case 2:
  1226.                     update_button(b2);
  1227.                     if (select_wall_textr(mid_tx2, 156, 224))
  1228.                         goto redraw;
  1229.                     break;
  1230.  
  1231.                 case 3:
  1232.                     update_button(b2);
  1233.                     if (select_wall_textr(bottom_tx2, 156, 234))
  1234.                         goto redraw;
  1235.                     break;
  1236.  
  1237.                 case 4:
  1238.                     update_button(b2);
  1239.                     xoffset2 = get_number(19, 24, xoffset2, 32767, 0);
  1240.                     break;
  1241.  
  1242.                 case 5:
  1243.                     update_button(b2);
  1244.                     yoffset2 = get_number(19, 25, yoffset2, 32767, 0);
  1245.                     break;
  1246.  
  1247.                 case 6:
  1248.                     sd2 = -1;
  1249.                     b.pos[12].status = 0;
  1250.                     for (i=0; i<7; i++)
  1251.                         b.pos[13+i].status = b.pos[19+i].status;
  1252.                     goto redraw;
  1253.             }
  1254.  
  1255.         } else {
  1256.             button -= i;
  1257.             if (sd1 == -1)
  1258.             {
  1259.                 sd1 = -2;
  1260.                 sector1 = -1;
  1261.                 strncpy(top_tx1, default_top, 8);
  1262.                 strncpy(mid_tx1, default_middle, 8);
  1263.                 strncpy(bottom_tx1, default_bottom, 8);
  1264.                 xoffset1 = default_xoffset;
  1265.                 yoffset1 = default_yoffset;
  1266.  
  1267.                 for (i=0; i<6; i++)
  1268.                     b.pos[b2 + i].status = init;
  1269.                 b.pos[b2 + 6].status = 0;
  1270.                 goto redraw;
  1271.             }
  1272.  
  1273.             j = linedefs[line_num].sd1;
  1274.             switch (button)
  1275.             {
  1276.                 case 0:
  1277.                     update_button(b2);
  1278.                     sector1 = get_number(48, 20, sector1, 32767, 0);
  1279.                     break;
  1280.  
  1281.                 case 1:
  1282.                     update_button(b2);
  1283.                     if (select_wall_textr(top_tx1, 388, 214))
  1284.                         goto redraw;
  1285.                     break;
  1286.  
  1287.                 case 2:
  1288.                     update_button(b2);
  1289.                     if (select_wall_textr(mid_tx1, 388, 224))
  1290.                         goto redraw;
  1291.                     break;
  1292.  
  1293.                 case 3:
  1294.                     update_button(b2);
  1295.                     if (select_wall_textr(bottom_tx1, 388, 234))
  1296.                         goto redraw;
  1297.                     break;
  1298.  
  1299.                 case 4:
  1300.                     update_button(b2);
  1301.                     xoffset1 = get_number(48, 24, xoffset1, 32767, 0);
  1302.                     break;
  1303.  
  1304.                 case 5:
  1305.                     update_button(b2);
  1306.                     yoffset1 = get_number(48, 25, yoffset1, 32767, 0);
  1307.                     break;
  1308.  
  1309.                 case 6:
  1310.                     sd1 = -1;
  1311.                     b.pos[b2 - 6].status = 0;
  1312.                     goto redraw;
  1313.             }
  1314.         }
  1315.     }
  1316.     draw_map();
  1317.     await_release_on();
  1318.  
  1319.     if (button == -99)
  1320.     {
  1321.         set_button_statuses(0);
  1322.         return;
  1323.     }
  1324.  
  1325.     if (*mlinedefs)
  1326.     {
  1327.         int mask=0, mask1=0, mask2=0;
  1328.  
  1329.         for (i=0; i<9; i++)
  1330.             if (b.pos[i+3].status == -2)
  1331.             {
  1332.                 mask |= bits[i];
  1333.                 attrib &= ~bits[i];
  1334.             }
  1335.         b2 = 13;
  1336.         if (sd2 != -1)
  1337.             b2 = 19;
  1338.  
  1339.         for (i=0; i<7; i++)
  1340.         {
  1341.             if (b.pos[i+12].status != -2)
  1342.                 mask2 |= bits[i];
  1343.             if (b.pos[i+b2].status != -2)
  1344.                 mask1 |= bits[i];
  1345.         }
  1346.  
  1347.         for (i=0; i<*mlinedefs; i++)
  1348.         {
  1349.             j = mlinedefs[i+2];
  1350.  
  1351.             if (!b.pos[0].status)
  1352.                 linedefs[j].type = type;
  1353.             if (!b.pos[1].status)
  1354.                 linedefs[j].trig = trig;
  1355.             linedefs[j].attrib &= mask;
  1356.             linedefs[j].attrib |= attrib;
  1357.  
  1358.             linedefs[j].sd1 = save_sidedef(linedefs[j].sd1, sd1, mask1,
  1359.                 sector1, xoffset1, yoffset1, top_tx1, mid_tx1, bottom_tx1);
  1360.             linedefs[j].sd2 = save_sidedef(linedefs[j].sd2, sd2, mask2,
  1361.                 sector2, xoffset2, yoffset2, top_tx2, mid_tx2, bottom_tx2);
  1362.             flip_line(j);
  1363.         }
  1364.  
  1365.     } else {
  1366.         linedefs[line_num].attrib = attrib;
  1367.         linedefs[line_num].type = type;
  1368.         linedefs[line_num].trig = trig;
  1369.         linedefs[line_num].sd1 = save_sidedef(linedefs[line_num].sd1, sd1,
  1370.             255, sector1, xoffset1, yoffset1, top_tx1, mid_tx1, bottom_tx1);
  1371.         linedefs[line_num].sd2 = save_sidedef(linedefs[line_num].sd2, sd2,
  1372.             255, sector2, xoffset2, yoffset2, top_tx2, mid_tx2, bottom_tx2);
  1373.         flip_line(line_num);
  1374.     }
  1375.  
  1376.     set_button_statuses(0);
  1377.     return;
  1378. }
  1379.  
  1380. int save_sidedef(int sd1, int sd2, int mask, int sector, int xoffset,
  1381.     int yoffset, char *top_tx, char *mid_tx, char *bottom_tx)
  1382. {
  1383.     int i;
  1384.  
  1385.     if (sd2 == -1)
  1386.     {
  1387.         if (sd1 != -1 && mask & 1)
  1388.         {
  1389.             del_sidedef(sd1);
  1390.             sd1 = -1;
  1391.         }
  1392.  
  1393.     } else {
  1394.         if (sd1 == -1)
  1395.         {
  1396.             if (!(mask & 64))
  1397.                 return -1;
  1398.             sd1 = add_sidedef(-1);
  1399.         }
  1400.  
  1401.         if (mask & 1)
  1402.             sidedefs[sd1].sector = sector;
  1403.         if (mask & 16)
  1404.             sidedefs[sd1].xoffset = xoffset;
  1405.         if (mask & 32)
  1406.             sidedefs[sd1].yoffset = yoffset;
  1407.  
  1408.         if (mask & 2)
  1409.             _fstrncpy(sidedefs[sd1].top, top_tx, 8);
  1410.         if (mask & 4)
  1411.             _fstrncpy(sidedefs[sd1].middle, mid_tx, 8);
  1412.         if (mask & 8)
  1413.             _fstrncpy(sidedefs[sd1].bottom, bottom_tx, 8);
  1414.     }
  1415.     return sd1;
  1416. }
  1417.  
  1418. void update_button(int num)
  1419. {
  1420.     b.pos[num].status = 0;
  1421.     setcolor(255);
  1422.     circle(b.pos[num].x, b.pos[num].y, 4);
  1423.     return;
  1424. }
  1425.  
  1426. int linetype_picklist(int num)
  1427. {
  1428.     char msg[80], spc[] = "  ", temp[6];
  1429.     int i, list_num, list_size, columns, rows, type;
  1430.     int old_num, new_num, cross_status;
  1431.     int index[50], x, y, shp;
  1432.  
  1433.     rows = (maxy / 20) * 2 - 3; /* make sure it's an odd number */
  1434.     columns = linetype_name_size + 5;
  1435.     list_size = (rows - 7) / 2;
  1436.     cross_status = cross_on;
  1437.     cross_on = 0;
  1438.  
  1439.     list_num = 0;
  1440.  
  1441. re_list:
  1442.     if (list_num < 0)
  1443.         list_num += linetype_max; /* wrap around */
  1444.  
  1445.     set_window(columns, rows, 0);
  1446.     text_to_window(0, 0, "Select type:\t\n\n[ Back ]\t", columns);
  1447.     text_to_window(0, rows-2, "[ More ]\t", columns);
  1448.     for (i=0; i<list_size; i++)
  1449.     {
  1450.         type = linetypes[list_num];
  1451.         sprintf(msg, "%s%d: %Fs\n", &spc[strlen(itoa(type, temp, 10))-1],
  1452.             type, linetype_names[list_num]);
  1453.         text_to_window(0, i*2+5, msg, 0);
  1454.         index[i] = list_num++;
  1455.         if (list_num >= linetype_max)
  1456.             list_num = 0;
  1457.     }
  1458.     draw_buttons();
  1459.     set_cancel_bar();
  1460.     mouse_on();
  1461.     old_num = -1;
  1462.  
  1463.     while (mouse_check()); /* wait for mouse button release */
  1464.     while (1)
  1465.     {
  1466.         while (!mouse_check() && !keypress)
  1467.         {
  1468.             new_num = -1;
  1469.             for (i=0; i<list_size; i++)
  1470.             {
  1471.                 if (mousex > win.left && abs(mousey - win.top - i*20 - 57) < 10)
  1472.                     new_num = i;
  1473.             }
  1474.             if (new_num != old_num)
  1475.             {
  1476.                 if (old_num != -1)
  1477.                 {
  1478.                     mouse_off();
  1479.                     setcolor(255);
  1480.                     reprint_linetype(index[old_num], old_num, columns);
  1481.                     mouse_on();
  1482.                 }
  1483.  
  1484.                 if (new_num != -1)
  1485.                 {
  1486.                     mouse_off();
  1487.                     setcolor(254);
  1488.                     reprint_linetype(index[new_num], new_num, columns);
  1489.                     mouse_on();
  1490.                 }
  1491.                 old_num = new_num;
  1492.             }
  1493.         }
  1494.  
  1495.         if (keypress)
  1496.         {
  1497.             if (keypress == 27)
  1498.             {
  1499.                 mouse_off();
  1500.                 cross_on = cross_status;
  1501.                 return num;
  1502.             }
  1503.  
  1504.             if (keypress == 13 && new_num != -1)
  1505.             {
  1506.                 mouse_off();
  1507.                 cross_on = cross_status;
  1508.                 return linetypes[index[new_num]];
  1509.             }
  1510.  
  1511.             if (keypress == 1073) /* page up */
  1512.             {
  1513.                 list_num -= list_size * 2;
  1514.                 mouse_off();
  1515.                 goto re_list;
  1516.             }
  1517.  
  1518.             if (keypress == 1081) /* page down */
  1519.             {
  1520.                 mouse_off();
  1521.                 goto re_list;
  1522.             }
  1523.  
  1524.             if (keypress == 1071) /* home */
  1525.             {
  1526.                 list_num = 0;
  1527.                 mouse_off();
  1528.                 goto re_list;
  1529.             }
  1530.             continue; /* end of key checks, below is mouse button pressed */
  1531.         }
  1532.  
  1533.         if (mousex < win.canbar + 47 &&
  1534.             mousex > win.canbar + 2 &&
  1535.             mousey < win.bottom + 9 &&
  1536.             mousey > win.bottom - 2)
  1537.         {
  1538.             mouse_off();
  1539.             cross_on = cross_status;
  1540.             return num;
  1541.         }
  1542.  
  1543.         if (line_dist(bigb.pos[0].x1, bigb.pos[0].y,
  1544.             bigb.pos[0].x2, bigb.pos[0].y) < 7)
  1545.         {
  1546.             list_num -= list_size * 2;
  1547.             mouse_off();
  1548.             goto re_list;
  1549.         }
  1550.  
  1551.         if (line_dist(bigb.pos[1].x1, bigb.pos[1].y,
  1552.             bigb.pos[1].x2, bigb.pos[1].y) < 7)
  1553.         {
  1554.             mouse_off();
  1555.             goto re_list;
  1556.         }
  1557.  
  1558.         if (new_num != -1)
  1559.         {
  1560.             mouse_off();
  1561.             cross_on = cross_status;
  1562.             return linetypes[index[new_num]];
  1563.         }
  1564.     }
  1565. }
  1566.  
  1567. void reprint_linetype(int num, int yy, int max)
  1568. {
  1569.     char msg[81], spc[] = "  ", temp[6];
  1570.     int x, y, type;
  1571.  
  1572.     x = win.left + 4;
  1573.     y = win.top + yy * 20 + 54;
  1574.     type = linetypes[num];
  1575.     sprintf(msg, "%s%d: %Fs", &spc[strlen(itoa(type, temp, 10))-1],
  1576.         type, linetype_names[num]);
  1577.     erase_text(x, y, max);
  1578.     outtextxy(x, y, msg);
  1579.     return;
  1580. }
  1581.  
  1582. int select_wall_textr(char far *farname, int x, int y)
  1583. {
  1584.     char name[9];
  1585.     int i, redraw=0;
  1586.  
  1587.     if (true_button & 1)
  1588.     {
  1589.         for (i=0; i<8; i++)
  1590.             name[i] = farname[i];
  1591.         name[8] = 0;
  1592.         wall_textr_pick(name);
  1593.         redraw = 1;
  1594.     } else
  1595.         get8(name, "-", win.left + x, win.top + y);
  1596.  
  1597.     for (i=0; i<8; i++)
  1598.         if (!(farname[i] = name[i]))
  1599.             break;
  1600.     while (i < 8)
  1601.         farname[i++] = 0;
  1602.     return redraw;
  1603. }
  1604.  
  1605. int sector_edit(void)
  1606. {
  1607.     char temp[41], msg[125], msg2[80], name1[9], name2[9];
  1608.     int i, j, dist, dist_min, old_sec=-2, sector, counter, id;
  1609.     int count, line;
  1610.     int v1, v2, x1, x2, y1, y2, dx, dy;
  1611.     uint mask;
  1612.  
  1613.    mark_mask = 2;
  1614.     sync_time();
  1615.     mouse_on();
  1616.     while (1)
  1617.     {
  1618.         mouse_check();
  1619.         dist_min = INT_MAX;
  1620.         sector = line = -1;
  1621.         for (i=0; i<l_size; i++)
  1622.         {
  1623.             v1 = linedefs[i].v1;
  1624.             v2 = linedefs[i].v2;
  1625.             x1 = adjvx[v1];
  1626.             x2 = adjvx[v2];
  1627.             y1 = adjvy[v1];
  1628.             y2 = adjvy[v2];
  1629.             if (x1 == x2)
  1630.                 continue; /* vertical line, so skip it */
  1631.             if ((x1 < mousex) && (x2 < mousex))
  1632.                 continue; /* doesn't cross line */
  1633.             if ((x1 > mousex) && (x2 > mousex))
  1634.                 continue; /* doesn't cross line either */
  1635.  
  1636.             dist = line_dist2(mousex, mousey, x1, y1, x2, y2);
  1637.             if (dist < 0)
  1638.                 continue; /* wrong direction now */
  1639.  
  1640.             if (dist > dist_min)
  1641.                 continue;
  1642.             if (dist == dist_min) /* time to decide which one we want.. */
  1643.                 if (line_least_angle(line, i, 16384) == line)
  1644.                     continue;
  1645.  
  1646.             dist_min = dist;
  1647.             line = i;
  1648.             if (x1 > x2)
  1649.                 id = linedefs[i].sd1;
  1650.             else
  1651.                 id = linedefs[i].sd2;
  1652.             sector = -1;
  1653.             if (id != -1)
  1654.                 sector = sidedefs[id].sector;
  1655.         }
  1656.         if (sector >= sec_size)
  1657.             sector = -1;
  1658.  
  1659.         if (sector != old_sec)
  1660.         {
  1661.             if (old_sec > -1)
  1662.             {
  1663.                 mouse_off();
  1664.                 redraw_sector(old_sec);
  1665.                 mouse_on();
  1666.             }
  1667.             old_sec = sector;
  1668.             if (edit_mode == 7)
  1669.             {
  1670.                 if (sector != -1)
  1671.                 {
  1672.                     for (i=0; i<8; i++)
  1673.                     {
  1674.                         name1[i] = sectors[sector].floor_name[i];
  1675.                         name2[i] = sectors[sector].ceiling_name[i];
  1676.                     }
  1677.                     name1[8] = name2[8] = 0;
  1678.                     sprintf(msg, "Sector #%d: light: %d, floor: %d (%s), "
  1679.                         "ceiling: %d (%s)", sector, (sectors[sector].light+8)/16,
  1680.                         round8(sectors[sector].floor), name1,
  1681.                         round8(sectors[sector].ceiling), name2);
  1682.                     sprintf(msg2, "effect: %d, trig: %d", sectors[sector].type,
  1683.                         sectors[sector].trig);
  1684.  
  1685.                     if (*msectors)
  1686.                     {
  1687.                         sprintf(temp, ", %d sectors marked", *msectors);
  1688.                         strcat(msg2, temp);
  1689.                     }
  1690.  
  1691.                     toptext2(msg, msg2);
  1692.                 } else toptext2("", "");
  1693.  
  1694.             } else {
  1695.                 *msg = *msg2 = 0;
  1696.                 if (lightc != -9)
  1697.                 {
  1698.                     sprintf(temp, "Light => %d <%+d>  ", (lightv + 8) / 16,
  1699.                         lightc);
  1700.                     strcat(msg, temp);
  1701.                 }
  1702.  
  1703.                 if (floorc != -9 || floortc)
  1704.                 {
  1705.                     strcat(msg, "Floor => ");
  1706.                     if (floorc != -9)
  1707.                     {
  1708.                         sprintf(temp, "%d <%+d> ",
  1709.                             round8(floorv), floorc);
  1710.                         strcat(msg, temp);
  1711.                     }
  1712.                     if (floortc)
  1713.                     {
  1714.                         sprintf(temp, "(%s) ", floort);
  1715.                         strcat(msg, temp);
  1716.                     }
  1717.                     strcat(msg, " ");
  1718.                 }
  1719.  
  1720.                 if (ceilc != -9 || ceiltc)
  1721.                 {
  1722.                     strcat(msg, "Ceiling => ");
  1723.                     if (ceilc != -9)
  1724.                     {
  1725.                         sprintf(temp, "%d <%+d>  ",
  1726.                             round8(ceilv), ceilc);
  1727.                         strcat(msg, temp);
  1728.                     }
  1729.                     if (ceiltc)
  1730.                     {
  1731.                         sprintf(temp, "(%s)", ceilt);
  1732.                         strcat(msg, temp);
  1733.                     }
  1734.                 }
  1735.  
  1736.                 if (sector != -1)
  1737.                 {
  1738.                     for (i=0; i<8; i++)
  1739.                     {
  1740.                         name1[i] = sectors[sector].floor_name[i];
  1741.                         name2[i] = sectors[sector].ceiling_name[i];
  1742.                     }
  1743.                     name1[8] = name2[8] = 0;
  1744.                     sprintf(msg2, "Sector #%d: light: %d, floor: %d (%s), "
  1745.                         "ceiling: %d (%s)", sector, (sectors[sector].light+8)/16,
  1746.                         round8(sectors[sector].floor), name1,
  1747.                         round8(sectors[sector].ceiling), name2);
  1748.                 }
  1749.                 toptext2(msg, msg2);
  1750.             }
  1751.         }
  1752.  
  1753.         if (wait(8))
  1754.         {
  1755.             if (marked)
  1756.             {
  1757.                 plot_marked(-1);
  1758.                 color_num--;
  1759.             }
  1760.  
  1761.             rand_color();
  1762.             if (sector != -1)
  1763.             {
  1764.                 for (i=0; i<ll_size; i++)
  1765.                 {
  1766.                     line = llines[i];
  1767.                     if ((j = linedefs[line].sd1) != -1 &&
  1768.                         sidedefs[j].sector == sector)
  1769.                         draw_line(line, SOLID_LINE);
  1770.                     if ((j = linedefs[line].sd2) != -1 &&
  1771.                         sidedefs[j].sector == sector)
  1772.                         draw_line(line, SOLID_LINE);
  1773.                 }
  1774.  
  1775.                 if (j = sectors[sector].trig)
  1776.                     for (i=0; i<ll_size; i++)
  1777.                     {
  1778.                         line = llines[i];
  1779.                         if (linedefs[line].trig == j)
  1780.                             draw_line(line, DOTTED_LINE);
  1781.                     }
  1782.                 mouse_redraw();
  1783.             }
  1784.         }
  1785.  
  1786.         if (edit_mode == 7)
  1787.         {
  1788.             if (button_status & 1)
  1789.             {
  1790.                 if (*mvertexes)
  1791.                 {
  1792.                     move_marked();
  1793.                     return 0;
  1794.                 }
  1795.  
  1796.                 mouse_off();
  1797.                 redraw_sector(sector);
  1798.                 if (make_sector(mouse_x, mouse_y, -1, 0, 0) == -1)
  1799.                     draw_map();
  1800.                 mouse_on();
  1801.                 old_sec = sec_size - 1;
  1802.             }
  1803.  
  1804.             if (button_status & 2)
  1805.             {
  1806.                 if (marked)
  1807.                 {
  1808.                     sort_marked(msectors);
  1809.                     i = *msectors;
  1810.                     while (i--)
  1811.                         del_sector(msectors[i+2]);
  1812.  
  1813.                     unmark_all();
  1814.                     draw_map();
  1815.                     await_release();
  1816.                     return 0;
  1817.                 }
  1818.  
  1819.                 if (sector != -1)
  1820.                 {
  1821.                     mouse_off();
  1822.                     redraw_sector(sector);
  1823.                     mouse_on();
  1824.                     i = s_size;
  1825.                     while (i--)
  1826.                     {
  1827.                         if ((j = linedefs[i].sd1) != -1)
  1828.                             if (sidedefs[j].sector == sector)
  1829.                             {
  1830.                                 del_sidedef(j);
  1831.                                 linedefs[i].sd1 = -1;
  1832.                             }
  1833.                         if ((j = linedefs[i].sd2) != -1)
  1834.                             if (sidedefs[j].sector == sector)
  1835.                             {
  1836.                                 del_sidedef(j);
  1837.                                 linedefs[i].sd2 = -1;
  1838.                             }
  1839.                     }
  1840.                     old_sec = -2;
  1841.                 }
  1842.             }
  1843.  
  1844.             if ((button_status & 4) && (sector != -1 || *msectors))
  1845.             {
  1846.                 mouse_off();
  1847.                 if (sector != -1)
  1848.                     redraw_sector(sector);
  1849.                 change_sector(sector);
  1850.             }
  1851.  
  1852.             if (button_status & 8)
  1853.             {
  1854.                 mouse_off();
  1855.                 if (sector != -1)
  1856.                     redraw_sector(sector);
  1857.  
  1858.                 if (!boxmark(5))
  1859.                     if (sector != -1)
  1860.                         mark_sector(sector);
  1861.  
  1862.                 draw_map();
  1863.                 return 0;
  1864.             }
  1865.  
  1866.         } else {
  1867.             if ((button_status & 9) && (sector != -1))
  1868.             {
  1869.                 if (lightc != -9)
  1870.                 {
  1871.                     sectors[sector].light = lightv;
  1872.                     if ((lightv += lightc * 16) > 255)
  1873.                         lightv = 255;
  1874.                     if (lightv < 0)
  1875.                         lightv = 0;
  1876.                 }
  1877.  
  1878.                 if (floorc != -9)
  1879.                 {
  1880.                     sectors[sector].floor = floorv;
  1881.                     floorv += floorc * 8;
  1882.                 }
  1883.  
  1884.                 if (ceilc != -9)
  1885.                 {
  1886.                     sectors[sector].ceiling = ceilv;
  1887.                     ceilv += ceilc * 8;
  1888.                 }
  1889.  
  1890.                 if (floortc)
  1891.                 {
  1892.                     for (i=0; i<8; i++)
  1893.                         if (!(sectors[sector].floor_name[i] = floort[i]))
  1894.                             break;
  1895.                     while (i++ < 7)
  1896.                         sectors[sector].floor_name[i] = 0;
  1897.                 }
  1898.  
  1899.                 if (ceiltc)
  1900.                 {
  1901.                     for (i=0; i<8; i++)
  1902.                         if (!(sectors[sector].ceiling_name[i] = ceilt[i]))
  1903.                             break;
  1904.                     while (i++ < 7)
  1905.                         sectors[sector].ceiling_name[i] = 0;
  1906.                 }
  1907.  
  1908.                 mouse_off();
  1909.                 redraw_sector(sector);
  1910.                 await_release_on();
  1911.                 old_sec = -2;
  1912.             }
  1913.  
  1914.             if (button_status & 6)
  1915.             {
  1916.                 mouse_off();
  1917.                 if (sector != -1)
  1918.                     redraw_sector(sector);
  1919.                 mouse_on();
  1920.                 edit_mode = 7;
  1921.                 old_sec = -1;
  1922.             }
  1923.         }
  1924.  
  1925.         if (keypress)
  1926.         {
  1927.             mouse_off();
  1928.             plot_marked(255);
  1929.             if (sector != -1)
  1930.                 redraw_sector(sector);
  1931.             if (keypress == 27 && edit_mode == 8)
  1932.             {
  1933.                 edit_mode = 7;
  1934.                 return 0;
  1935.             }
  1936.  
  1937.             if (keypress == 'b')
  1938.             {
  1939.                 blend_sector(sector);
  1940.                 return 0;
  1941.             }
  1942.  
  1943.             if (keypress == 'd')
  1944.             {
  1945.                 make_door(sector);
  1946.                 continue;
  1947.             }
  1948.             return keypress;
  1949.         }
  1950.     }
  1951. }
  1952.  
  1953. void redraw_sector(int num)
  1954. {
  1955.     int i, j, l;
  1956.  
  1957.     for (i=0; i<ll_size; i++)
  1958.     {
  1959.         l = llines[i];
  1960.         if (sidedefs[linedefs[l].sd1].sector == num ||
  1961.             sidedefs[linedefs[l].sd2].sector == num)
  1962.         {
  1963.             wall_color(l);
  1964.             draw_line(l, SOLID_LINE);
  1965.         }
  1966.     }
  1967.     if (j = sectors[num].trig)
  1968.         for (i=0; i<ll_size; i++)
  1969.         {
  1970.             l = llines[i];
  1971.             if (linedefs[l].trig == j)
  1972.             {
  1973.                 wall_color(l);
  1974.                 draw_line(l, SOLID_LINE);
  1975.             }
  1976.         }
  1977.     return;
  1978. }
  1979.  
  1980. int round8(int num)
  1981. {
  1982.     return ((num + 4) >> 3);
  1983. }
  1984.  
  1985. void make_door(int sector)
  1986. {
  1987.     int i, sd, temp;
  1988.  
  1989.     for (i=0; i<l_size; i++)
  1990.         if ((sd = linedefs[i].sd1) != -1)
  1991.             if (sidedefs[sd].sector == sector)
  1992.             {
  1993.                 temp = linedefs[i].v1;
  1994.                 linedefs[i].v1 = linedefs[i].v2;
  1995.                 linedefs[i].v2 = temp;
  1996.  
  1997.                 linedefs[i].sd1 = linedefs[i].sd2;
  1998.                 linedefs[i].sd2 = sd;
  1999.             }
  2000.     sectors[sector].ceiling = sectors[sector].floor;
  2001.     return;
  2002. }
  2003.  
  2004. void blend_sector(int sector)
  2005. {
  2006.     char floor_textr[9], ceil_textr[9];
  2007.     char msg[8192], desc[41], name[9];
  2008.     int i, button, num;
  2009.  
  2010.     if (sector != -1)
  2011.     {
  2012.         lightv = sectors[sector].light;
  2013.         floorv = sectors[sector].floor;
  2014.         ceilv = sectors[sector].ceiling;
  2015.         for (i=0; i<8; i++)
  2016.         {
  2017.             floort[i] = sectors[sector].floor_name[i];
  2018.             ceilt[i] = sectors[sector].ceiling_name[i];
  2019.         }
  2020.     }
  2021.     floort[8] = ceilt[8] = 0;
  2022.  
  2023. redraw:
  2024.     sprintf(msg, "Blend/Copy Sectors\t\n\n"
  2025.         "      Adjust values by: -2 -1 0 +1 +2 \n\n"
  2026.         " @ Light level: %-5d    @ @  @ @  @\n\n"
  2027.         " @ Floor height: %-5d   @ @  @ @  @\n\n"
  2028.         " @ Ceiling height: %-5d @ @  @ @  @\n\n"
  2029.         " @ Floor texture: %-8s    @\n\n"
  2030.         " @ Ceiling texture: %-8s  @\n\n"
  2031.         "[ Engage ]\t\n", (lightv + 8) / 16,
  2032.         round8(floorv), round8(ceilv), floort, ceilt);
  2033.  
  2034.     window_text1(msg, 1, 0, 4);
  2035.     b.pos[2].x += 4;
  2036.     b.pos[4].x += 4;
  2037.     b.pos[8].x += 4;
  2038.     b.pos[10].x += 4;
  2039.     b.pos[14].x += 4;
  2040.     b.pos[16].x += 4;
  2041.     draw_buttons();
  2042.     set_cancel_bar();
  2043.  
  2044.     if (lightc != -9)
  2045.         b.pos[3 + lightc].on = 1;
  2046.     if (floorc != -9)
  2047.         b.pos[9 + floorc].on = 1;
  2048.     if (ceilc != -9)
  2049.         b.pos[15 + ceilc].on = 1;
  2050.     b.pos[19].on = floortc;
  2051.     b.pos[21].on = ceiltc;
  2052.  
  2053.     while ((button = window_check()) > -1)
  2054.     {
  2055.         switch (button)
  2056.         {
  2057.             case 0:
  2058.                 num = get_number(16, 5, (lightv + 8) / 16, 16, 0) * 16;
  2059.                 if (num == 256)
  2060.                     num = 255;
  2061.                 lightv = num;
  2062.                 break;
  2063.  
  2064.             case 1:
  2065.                 lightc = change_adjust(3, -2);
  2066.                 break;
  2067.             case 2:
  2068.                 lightc = change_adjust(3, -1);
  2069.                 break;
  2070.             case 3:
  2071.                 lightc = change_adjust(3, 0);
  2072.                 break;
  2073.             case 4:
  2074.                 lightc = change_adjust(3, 1);
  2075.                 break;
  2076.             case 5:
  2077.                 lightc = change_adjust(3, 2);
  2078.                 break;
  2079.  
  2080.             case 6:
  2081.                 if ((num = get_number(17, 7, round8(floorv),
  2082.                     F_MAX, F_MIN) * 8) > ceilv)
  2083.                         ceilv = num;
  2084.                 floorv = num;
  2085.                 break;
  2086.  
  2087.             case 7:
  2088.                 floorc = change_adjust(9, -2);
  2089.                 break;
  2090.             case 8:
  2091.                 floorc = change_adjust(9, -1);
  2092.                 break;
  2093.             case 9:
  2094.                 floorc = change_adjust(9, 0);
  2095.                 break;
  2096.             case 10:
  2097.                 floorc = change_adjust(9, 1);
  2098.                 break;
  2099.             case 11:
  2100.                 floorc = change_adjust(9, 2);
  2101.                 break;
  2102.  
  2103.             case 12:
  2104.                 if ((num = get_number(19, 9, round8(ceilv),
  2105.                     C_MAX, C_MIN) * 8) < floorv)
  2106.                         floorv = num;
  2107.                 ceilv = num;
  2108.                 break;
  2109.  
  2110.             case 13:
  2111.                 ceilc = change_adjust(15, -2);
  2112.                 break;
  2113.             case 14:
  2114.                 ceilc = change_adjust(15, -1);
  2115.                 break;
  2116.             case 15:
  2117.                 ceilc = change_adjust(15, 0);
  2118.                 break;
  2119.             case 16:
  2120.                 ceilc = change_adjust(15, 1);
  2121.                 break;
  2122.             case 17:
  2123.                 ceilc = change_adjust(15, 2);
  2124.                 break;
  2125.  
  2126.             case 18:
  2127.                 if (select_fc_textr(floor_textr, 148, 114))
  2128.                     goto redraw;
  2129.                 break;
  2130.  
  2131.             case 19:
  2132.                 floortc = b.pos[19].on = !b.pos[19].on;
  2133.                 break;
  2134.  
  2135.             case 20:
  2136.                 if (select_fc_textr(ceil_textr, 164, 134))
  2137.                     goto redraw;
  2138.                 break;
  2139.  
  2140.             case 21:
  2141.                 ceiltc = b.pos[21].on = !b.pos[21].on;
  2142.                 break;
  2143.         }
  2144.     }
  2145.  
  2146.     if (button == -2)
  2147.     {
  2148.         edit_mode = 8;
  2149.         strcpy(floort, floor_textr);
  2150.         strcpy(ceilt, ceil_textr);
  2151.     }
  2152.  
  2153.     draw_map();
  2154.     await_release();
  2155.     return;
  2156. }
  2157.  
  2158. int change_adjust(int button, int value)
  2159. {
  2160.     int i, on;
  2161.  
  2162.     on = b.pos[button+value].on;
  2163.     for (i=-2; i<3; i++)
  2164.         b.pos[button+i].on = 0;
  2165.  
  2166.     if (on)
  2167.         return -9;
  2168.     b.pos[button+value].on = 1;
  2169.     return value;
  2170. }
  2171.  
  2172. void change_sector(int sector)
  2173. {
  2174.     char msg[8192], desc[41], fname[9], cname[9], name[9];
  2175.     int light, trig, fheight, cheight, type;
  2176.     int i, button, num, x=56, y=27, init=0;
  2177.  
  2178.     if (sector != -1)
  2179.     {
  2180.         for (i=0; i<8; i++)
  2181.         {
  2182.             fname[i] = sectors[sector].floor_name[i];
  2183.             cname[i] = sectors[sector].ceiling_name[i];
  2184.         }
  2185.         fname[8] = cname[8] = 0;
  2186.         light = sectors[sector].light;
  2187.         trig = sectors[sector].trig;
  2188.         fheight = sectors[sector].floor;
  2189.         cheight = sectors[sector].ceiling;
  2190.         type = sectors[sector].type;
  2191.  
  2192.     } else {
  2193.         for (i=0; i<8; i++)
  2194.         {
  2195.             fname[i] = default_floor_name[i];
  2196.             cname[i] = default_ceiling_name[i];
  2197.         }
  2198.         fname[8] = cname[8] = 0;
  2199.         light = default_light;
  2200.         trig = default_sector_trig;
  2201.         fheight = default_fheight;
  2202.         cheight = default_cheight;
  2203.         type = default_sector_type;
  2204.     }
  2205.  
  2206.     if (*msectors)
  2207.         init = -2;
  2208.     set_button_statuses(init);
  2209.  
  2210. redraw:
  2211.     set_window(x, y, 1);
  2212.     sprintf(msg, "Change sector #%d\t\n\n"
  2213.         " @ Light level: %-6d      @ Trigger id: %-5d @ Auto\n\n"
  2214.         " @ Floor height: %-6d     @ Ceiling height: %d\n\n"
  2215.         " @ Floor texture: %-8s  @ Ceiling texture: %s\n\n"
  2216.         "Special effects:\t",
  2217.         sector, (light + 8) / 16, trig, round8(fheight), round8(cheight),
  2218.         fname, cname);
  2219.  
  2220.     text_to_window(0, 0, msg, x);
  2221.     text_to_window(1, 11, "@ 00: None\n"
  2222.     "@ 01: Light level flickers, random period\n"
  2223.     "@ 02: Light level pulsates, 1/2 second period\n"
  2224.     "@ 03: Light level pulsates, 1 second period\n"
  2225.     "@ 04: Same as (02), also -20% health drop\n"
  2226.     "@ 05: -10% health drop (Blood3 floor)\n"
  2227.     "@ 07: -5% health drop (Nukage3 floor)\n"
  2228.     "@ 08: Light level oscillates\n"
  2229.     "@ 09: Secret area\n"
  2230.     "@ 10: Dropping ceiling?\n"
  2231.     "@ 11: -20% health drop, end episode when dead\n"
  2232.     "@ 12: Light level oscillates between normal and 0\n"
  2233.     "@ 13: Strobe light, 1/2 second period\n"
  2234.     "@ 14: Unknown as of yet\n"
  2235.     "@ 16: -20% health drop (Lava4/Fwater4 floor)\n", 0);
  2236.  
  2237.     draw_buttons();
  2238.     set_window_bars();
  2239.     while (1)
  2240.     {
  2241.         num = type;
  2242.         if (num == 16)
  2243.             num--;
  2244.         if (num > 6)
  2245.             num--;
  2246.         if (num >= 0 && num < 15)
  2247.             b.pos[num+7].on = 1;
  2248.  
  2249.         if ((button = window_check()) < 0)
  2250.             break;
  2251.  
  2252.         if (button_status & 4 && *msectors && button != 2)
  2253.         {
  2254.             if (b.pos[button].status == -2)
  2255.                 b.pos[button].status = 0;
  2256.             else
  2257.                 b.pos[button].status = -2;
  2258.  
  2259.             if (button > 6)
  2260.                 for (i=7; i<22; i++)
  2261.                     b.pos[i].status = b.pos[button].status;
  2262.  
  2263.             draw_buttons();
  2264.             continue;
  2265.         }
  2266.  
  2267.         if (button == 0)
  2268.         {
  2269.             update_button(0);
  2270.             num = get_number(16, 3, (light + 8) / 16, 16, 0) * 16;
  2271.             if (num == 256)
  2272.                 num = 255;
  2273.             light = num;
  2274.             continue;
  2275.         }
  2276.  
  2277.         if (button == 1)
  2278.         {
  2279.             update_button(1);
  2280.             trig = get_number(42, 3, trig, 32767, 0);
  2281.             continue;
  2282.         }
  2283.  
  2284.         if (button == 2)
  2285.         {
  2286.             trig = 0;
  2287.             trig = find_new_id();
  2288.             sprintf(msg, "%d", trig);
  2289.             erase_text(win.left + 340, win.top + 34, 5);
  2290.             text(win.left + 340, win.top + 34, msg);
  2291.             update_button(1);
  2292.             continue;
  2293.         }
  2294.  
  2295.         if (button == 3)
  2296.         {
  2297.             update_button(3);
  2298.             if ((num = get_number(17, 5, round8(fheight), F_MAX, F_MIN) * 8)
  2299.                 > cheight)
  2300.                     cheight = num;
  2301.             fheight = num;
  2302.             continue;
  2303.         }
  2304.  
  2305.         if (button == 4)
  2306.         {
  2307.             update_button(4);
  2308.             if ((num = get_number(46, 5, round8(cheight), C_MAX, C_MIN) * 8)
  2309.                 < fheight)
  2310.                     fheight = num;
  2311.             cheight = num;
  2312.             continue;
  2313.         }
  2314.  
  2315.         if (button == 5)
  2316.         {
  2317.             update_button(5);
  2318.             if (select_fc_textr(fname, 148, 74))
  2319.                 goto redraw;
  2320.             continue;
  2321.         }
  2322.  
  2323.         if (button == 6)
  2324.         {
  2325.             update_button(6);
  2326.             if (select_fc_textr(cname, 380, 74))
  2327.                 goto redraw;
  2328.             continue;
  2329.         }
  2330.  
  2331.         if (button > 6 && button < 13)
  2332.         {
  2333.             type = button - 7;
  2334.             for (i=7; i<22; i++)
  2335.                 b.pos[i].status = b.pos[i].on = 0;
  2336.             draw_buttons();
  2337.             continue;
  2338.         }
  2339.  
  2340.         if (button > 12 && button < 21)
  2341.         {
  2342.             type = button - 6;
  2343.             for (i=7; i<22; i++)
  2344.                 b.pos[i].status = b.pos[i].on = 0;
  2345.             draw_buttons();
  2346.             continue;
  2347.         }
  2348.  
  2349.         if (button == 21)
  2350.         {
  2351.             type = 16;
  2352.             for (i=7; i<22; i++)
  2353.                 b.pos[i].status = b.pos[i].on = 0;
  2354.             draw_buttons();
  2355.             continue;
  2356.         }
  2357.     }
  2358.  
  2359.     if (button == -1)
  2360.     {
  2361.         if (*msectors)
  2362.         {
  2363.             for (i=0; i<*msectors; i++)
  2364.             {
  2365.                 num = msectors[i+2];
  2366.                 if (!b.pos[0].status)
  2367.                     sectors[num].light = light;
  2368.                 if (!b.pos[1].status)
  2369.                     sectors[num].trig = trig;
  2370.                 if (!b.pos[3].status)
  2371.                     sectors[num].floor = fheight;
  2372.                 if (!b.pos[4].status)
  2373.                     sectors[num].ceiling = cheight;
  2374.                 if (!b.pos[5].status)
  2375.                     _fstrncpy(sectors[num].floor_name, fname, 8);
  2376.                 if (!b.pos[6].status)
  2377.                     _fstrncpy(sectors[num].ceiling_name, cname, 8);
  2378.                 if (b.pos[7].status > -1)
  2379.                     sectors[num].type = type;
  2380.             }
  2381.  
  2382.         } else {
  2383.             sectors[sector].light = light;
  2384.             sectors[sector].trig = trig;
  2385.             sectors[sector].floor = fheight;
  2386.             sectors[sector].ceiling = cheight;
  2387.             sectors[sector].type = type;
  2388.             _fstrncpy(sectors[sector].floor_name, fname, 8);
  2389.             _fstrncpy(sectors[sector].ceiling_name, cname, 8);
  2390.         }
  2391.     }
  2392.  
  2393.     draw_map();
  2394.     await_release_on();
  2395.     set_button_statuses(0);
  2396.     return;
  2397. }
  2398.  
  2399. int select_fc_textr(char far *farname, int x, int y)
  2400. {
  2401.     char name[9];
  2402.     int i, redraw=0;
  2403.  
  2404.     if (true_button & 1)
  2405.     {
  2406.         for (i=0; i<8; i++)
  2407.             name[i] = farname[i];
  2408.         name[8] = 0;
  2409.         fc_textr_pick(name);
  2410.         redraw = 1;
  2411.     } else
  2412.         get8(name, "FLOOR5_4", win.left + x, win.top + y);
  2413.  
  2414.     for (i=0; i<8; i++)
  2415.         if (!(farname[i] = name[i]))
  2416.             break;
  2417.     while (i < 8)
  2418.         farname[i++] = 0;
  2419.     return redraw;
  2420. }
  2421.  
  2422. void del_sector(int num)
  2423. {
  2424.     int i;
  2425.  
  2426.     sec_size--;
  2427.     for (i=num; i<sec_size; i++)
  2428.         sectors[i] = sectors[i+1];
  2429.  
  2430.     for (i=0; i<s_size; i++)
  2431.         if (sidedefs[i].sector == num)
  2432.             sidedefs[i].sector = -1;
  2433.     return;
  2434. }
  2435.  
  2436. int make_sector(int x, int y, int line, int side, int sector)
  2437. {
  2438.     char msg[60];
  2439.     int i, j, sec, max, orig_line, dir, size=0, temp, mode=0;
  2440.     int v1, v2, minv, xmin, ymin, xmax, ymax, x2, y2;
  2441.     uint angle;
  2442.  
  2443.     struct sec_struct deflt_sec = { 0, 72, "FLOOR4_8", "CEIL3_5", 255, 0, 0 };
  2444.  
  2445.     if (line != -1)
  2446.         mode = 1; /* recursed for donut fixing */
  2447.  
  2448.     else {
  2449.         if (sec_size == sec_max) /* allocate space for new sector */
  2450.         {
  2451.             void far *ptr;
  2452.  
  2453.             if (sec_max)
  2454.                 ptr = resize_farmem(sectors, (sec_max+20) *
  2455.                     sizeof(struct sec_struct), "Sectors");
  2456.             else
  2457.                 ptr = get_farmem(20 * sizeof(struct sec_struct), "Sectors");
  2458.  
  2459.             if (!ptr)
  2460.             {
  2461.                 error("Maximum sectors reached.  Can't add one");
  2462.                 return -1;
  2463.             }
  2464.             sectors = ptr;
  2465.             sec_max += 20;
  2466.         }
  2467.  
  2468.         sector = sec_size++;
  2469.         counts = get_mem(sec_size * 2, "counts");
  2470.         if (!counts)
  2471.             fatal_error("No memory");
  2472.  
  2473.         for (i=0; i<sec_size; i++)
  2474.             counts[i] = 0; /* reset sector count list */
  2475.  
  2476.         line = inside_poly(x, y, &side, testmode); /* get starting line */
  2477.         if (temp = outside_detect(line, side))
  2478.         {
  2479.             if (temp > 0)
  2480.                 error("The outside void region can't be a sector");
  2481.             goto return1;
  2482.         }
  2483.         xmax = ymax = INT_MIN; /* reset sector bounding box */
  2484.         xmin = ymin = INT_MAX;
  2485.         setcolor(96);
  2486.     }
  2487.  
  2488. recalc_outside_part:
  2489.     orig_line = line;
  2490.     v1 = minv = linedefs[line].v1;
  2491.     v2 = linedefs[line].v2;
  2492.     angle = calc_angle(vertexes[v1].x, vertexes[v1].y,
  2493.         vertexes[v2].x, vertexes[v2].y);
  2494.     dir = 0;
  2495.  
  2496.     do
  2497.     {
  2498.         if (dir != side)
  2499.         {
  2500.             if ((temp = linedefs[line].sd1) == -1) /* make sidedef if not one */
  2501.                 if ((temp = linedefs[line].sd1 = add_sidedef(-1)) == -1)
  2502.                     goto return1;
  2503.         } else
  2504.             if ((temp = linedefs[line].sd2) == -1)
  2505.                 if ((temp = linedefs[line].sd2 = add_sidedef(-1)) == -1)
  2506.                     goto return1;
  2507.  
  2508.         if (size + 1 < LL_MAX)
  2509.             llist[size++] = temp; /* build list of sidedefs in sector */
  2510.         else
  2511.         {
  2512.             error("Line list limit has been exceeded");
  2513.             goto return1;
  2514.         }
  2515.       draw_line(line, SOLID_LINE);
  2516.  
  2517.         if ((temp = vertexes[v2].y) < vertexes[minv].y)
  2518.             minv = v2; /* track lowest point */
  2519.  
  2520.         adjust_limit(vertexes[v2].x, temp, &xmin, &ymin, &xmax, &ymax);
  2521.  
  2522.         dir = find_next_line(&v2, &angle, &line, side);
  2523.         if (dir == -1)
  2524.         {
  2525.             deadend_error();
  2526.             goto return1;
  2527.         }
  2528.     } while (line != orig_line);
  2529.  
  2530.     for (i=0; i<size; i++)
  2531.     {
  2532.         if ((temp = sidedefs[llist[i]].sector) != -1)
  2533.         {
  2534.             if (temp >= sec_size || temp < 0)
  2535.                 continue; /* bad sector: out of limits */
  2536.             else
  2537.                 counts[temp]++; /* track majority sector */
  2538.         }
  2539.         sidedefs[llist[i]].sector = sector; /* make it the new sector */
  2540.     }
  2541.  
  2542.     if (mode)
  2543.         return 0; /* end of resursive part */
  2544.  
  2545. /* Now, we need to figure out if we are actually on an inside part.  If so,
  2546.     we need to try and find the outside part and then go back and recalculate
  2547.     it.
  2548. */
  2549.  
  2550.     if ((orig_line = downward_line(minv, &side, testmode)) != -1)
  2551.     {
  2552.         if (side)
  2553.             temp = linedefs[orig_line].sd1;
  2554.         else
  2555.             temp = linedefs[orig_line].sd2;
  2556.         if (temp != -1 && sidedefs[temp].sector == sector)
  2557.         {
  2558.             line = inside_poly(vertexes[minv].x, vertexes[minv].y,
  2559.                 &side, testmode);
  2560.             goto recalc_outside_part;
  2561.         }
  2562.     }
  2563.  
  2564. /* This loop runs through all the vertexes inside our new sector.  It then
  2565.     figures out if a line to this vertex is totally inside our sector.  If
  2566.     so, it creates a "donut" sector
  2567. */
  2568.  
  2569.     for (i=0; i<max_vertex; i++)
  2570.     {
  2571.         x = vertexes[i].x;
  2572.         y = vertexes[i].y;
  2573.  
  2574.         if (x > xmin && x < xmax && y > ymin && y < ymax)
  2575.         {
  2576.             if ((orig_line = downward_line(i, &side, testmode)) == -1)
  2577.             {
  2578.                 deadend_error();
  2579.                 goto return1;
  2580.             }
  2581.  
  2582.             if (side)
  2583.                 temp = linedefs[orig_line].sd1;
  2584.             else
  2585.                 temp = linedefs[orig_line].sd2;
  2586.             if (temp != -1 && sidedefs[temp].sector == sector)
  2587.                 continue;
  2588.  
  2589.             if ((v1 = linedefs[orig_line].v1) == i)
  2590.                 v1 = linedefs[orig_line].v2;
  2591.             x2 = vertexes[v1].x;
  2592.             y2 = vertexes[v1].y;
  2593.  
  2594.             if (x2 > xmin && x2 < xmax && y2 > ymin && y2 < ymax)
  2595.             {
  2596.                 if ((line = inside_poly(x, y, &temp, testmode)) != -1)
  2597.                 {
  2598.                     if (temp)
  2599.                         temp = linedefs[line].sd1;
  2600.                     else
  2601.                         temp = linedefs[line].sd2;
  2602.  
  2603.                     if (temp != -1 && sidedefs[temp].sector == sector)
  2604.                     { /* need to merge a donut in */
  2605.                         if (make_sector(x, y, orig_line, side, sector) == -1)
  2606.                             goto return1;
  2607.                         i = 0; /* need to recheck previous groups now */
  2608.                     }
  2609.                 }
  2610.             }
  2611.         }
  2612.     }
  2613.  
  2614. /* now, all the sidedefs are set up to our new sector.  Time to clean up.
  2615.     First, we set up the new sector definition
  2616. */
  2617.  
  2618.     max = 0;
  2619.     sec = -1;
  2620.     for (i=0; i<sec_size; i++)
  2621.     {
  2622.         if (counts[i] > max) /* find the majority sector # */
  2623.         {
  2624.             max = counts[i];
  2625.             sec = i;
  2626.         }
  2627.         counts[i] = 0; /* reset for use again by next part */
  2628.     }
  2629.  
  2630.     if (sec != -1)
  2631.         sectors[sector] = sectors[sec]; /* assume identity of that sector */
  2632.     else
  2633.         sectors[sector] = deflt_sec;
  2634.  
  2635. /* now, we go though and find out if any sectors are now not used by any
  2636.     sidedefs, and remove them if so.  This will happen if we overwrite all
  2637.     the sectors references with our new sector.  Always a good idea to clean
  2638.     up after ourselves..
  2639. */
  2640.  
  2641.     for (i=0; i<s_size; i++)
  2642.     {
  2643.         temp = sidedefs[i].sector;
  2644.         if (temp >= 0 && temp < sec_size)
  2645.             counts[temp]++;
  2646.         else
  2647.             sidedefs[i].sector = -1; /* out of limits, so fix */
  2648.     }
  2649.  
  2650.     i = sec_size;
  2651.     while (i--)
  2652.         if (!counts[i]) /* sector not used */
  2653.         {
  2654.             for (j=i; j<sec_size-1; j++) /* so eliminate it */
  2655.                 sectors[j] = sectors[j+1];
  2656.             for (j=0; j<s_size; j++)
  2657.                 if (sidedefs[j].sector > i)
  2658.                     sidedefs[j].sector--;
  2659.             sec_size--;
  2660.         }
  2661.  
  2662.     free_mem(counts, "counts");
  2663.     if (testmode > 1)
  2664.         return -1; /* cause a redraw of the map */
  2665.     return 0;
  2666.  
  2667. return1:
  2668.     if (counts)
  2669.         free_mem(counts, "counts");
  2670.     counts = 0;
  2671.     return -1;
  2672. }
  2673.  
  2674. void plot_colored_point(int x, int y, int color)
  2675. {
  2676.     char image[125];
  2677.     int i, cross_status;
  2678.  
  2679.     for (i=0; i<4; i++)
  2680.         image[i] = point_ptr[point_size-1][i];
  2681.     for (i=4; i<125; i++)
  2682.     {
  2683.         if (point_ptr[point_size-1][i])
  2684.             image[i] = color;
  2685.         else
  2686.             image[i] = saved_image[i];
  2687.     }
  2688.  
  2689.     mouse_off();
  2690.     putimage(x - point_size, y - point_size, image, 0);
  2691.  
  2692.     cross_status = cross_on;
  2693.     if (crossx+2 == x && crossy+2 == y)
  2694.         cross_on = 0;
  2695.     mouse_on();
  2696.     cross_on = cross_status;
  2697.     return;
  2698. }
  2699.  
  2700. void restore_point(int num)
  2701. {
  2702.     int x, y;
  2703.  
  2704.     x = adjvx[num] - point_size;
  2705.     y = adjvy[num] - point_size;
  2706.     putimage(x, y, saved_image, 0);
  2707.     return;
  2708. }
  2709.  
  2710. int find_new_id(void)
  2711. {
  2712.     int i, index=0, num;
  2713.  
  2714.     for (i=0; i<l_size; i++)
  2715.         if (num = linedefs[i].trig)
  2716.             add_num_to_list(num, &index);
  2717.  
  2718.     for (i=0; i<sec_size; i++)
  2719.         if (num = sectors[i].trig)
  2720.             add_num_to_list(num, &index);
  2721.  
  2722.     num=1;
  2723.     for (i=0; i<index; i++)
  2724.         if (num == llist[i])
  2725.         {
  2726.             num++;
  2727.             i = 0; /* start checking all over again */
  2728.         }
  2729.     return num;
  2730. }
  2731.  
  2732. void add_num_to_list(int num, int *index)
  2733. {
  2734.     int i;
  2735.  
  2736.     for (i=0; i<*index; i++)
  2737.         if (num == llist[i])
  2738.             return;
  2739.  
  2740.     if (*index < LL_MAX)
  2741.         llist[(*index)++] = num;
  2742.     return;
  2743. }
  2744.  
  2745. void change_sidedefs(void)
  2746. {
  2747.     char msg[8192], name[9], top_tx[9], mid_tx[9], bottom_tx[9];
  2748.     int i, j, type, button, sd, num;
  2749.     int sector, xoffset, yoffset;
  2750.  
  2751.     sector = default_sidedef_sector;
  2752.     xoffset = default_xoffset;
  2753.     yoffset = default_yoffset;
  2754.     for (i=0; i<8; i++)
  2755.     {
  2756.         top_tx[i] = default_top[i];
  2757.         mid_tx[i] = default_middle[i];
  2758.         bottom_tx[i] = default_bottom[i];
  2759.     }
  2760.     top_tx[8] = mid_tx[8] = bottom_tx[8] = 0;
  2761.  
  2762. redraw:
  2763.     sprintf(msg, "Change marked Sidedefs\t\n"
  2764.         "@  Sector facing: %d\n"
  2765.         "@    Top texture: %s\n"
  2766.         "@ Middle texture: %s\n"
  2767.         "@ Bottom texture: %s\n"
  2768.         "@    Horz. shift: %d\n"
  2769.         "@    Vert. shift: %d\n\n",
  2770.         sector, top_tx, mid_tx, bottom_tx, xoffset, yoffset);
  2771.  
  2772.     window_text1(msg, 1, 0, 0);
  2773.     draw_buttons();
  2774.     set_window_bars();
  2775.  
  2776.     while (1)
  2777.     {
  2778.         draw_buttons();
  2779.         if ((button = window_check()) < 0)
  2780.             break;
  2781.  
  2782.         if (button_status & 4)
  2783.         {
  2784.             if (b.pos[button].status == -2)
  2785.                 b.pos[button].status = 0;
  2786.             else
  2787.                 b.pos[button].status = -2;
  2788.             continue;
  2789.         }
  2790.  
  2791.         switch (button)
  2792.         {
  2793.             case 0:
  2794.                 update_button(0);
  2795.                 sidedefs[j].sector = get_number(19, 2, sector, 32767, 0);
  2796.                 break;
  2797.  
  2798.             case 1:
  2799.                 update_button(1);
  2800.                 if (select_wall_textr(top_tx, 156, 34))
  2801.                     goto redraw;
  2802.                 break;
  2803.  
  2804.             case 2:
  2805.                 update_button(2);
  2806.                 if (select_wall_textr(mid_tx, 156, 44))
  2807.                     goto redraw;
  2808.                 break;
  2809.  
  2810.             case 3:
  2811.                 update_button(3);
  2812.                 if (select_wall_textr(bottom_tx, 156, 54))
  2813.                     goto redraw;
  2814.                 break;
  2815.  
  2816.             case 4:
  2817.                 update_button(4);
  2818.                 xoffset = get_number(19, 6, xoffset, 32767, 0);
  2819.                 break;
  2820.  
  2821.             case 5:
  2822.                 update_button(5);
  2823.                 yoffset = get_number(19, 7, yoffset, 32767, 0);
  2824.         }
  2825.     }
  2826.  
  2827.     draw_map();
  2828.     await_release_on();
  2829.     if (button == -99)
  2830.         return;
  2831.  
  2832.     for (i=0; i<*msidedefs; i++)
  2833.     {
  2834.         if (!b.pos[0].status)
  2835.             sidedefs[i].sector = sector;
  2836.  
  2837.         if (!b.pos[1].status)
  2838.             for (j=0; j<8; j++)
  2839.                 sidedefs[i].top[j] = top_tx[j];
  2840.  
  2841.         if (!b.pos[2].status)
  2842.             for (j=0; j<8; j++)
  2843.                 sidedefs[i].middle[j] = mid_tx[j];
  2844.  
  2845.         if (!b.pos[3].status)
  2846.             for (j=0; j<8; j++)
  2847.                 sidedefs[i].bottom[j] = bottom_tx[j];
  2848.  
  2849.         if (!b.pos[4].status)
  2850.             sidedefs[i].xoffset = xoffset;
  2851.  
  2852.         if (!b.pos[5].status)
  2853.             sidedefs[i].yoffset = yoffset;
  2854.     }
  2855.     set_button_statuses(0);
  2856.     return;
  2857. }
  2858.