home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / gnustuff / tos / progut~1 / stdwin.zoo / bed / mouse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-10-18  |  7.6 KB  |  458 lines

  1. #include "bed.h"
  2. #include "menu.h"
  3.  
  4. #ifndef ABS
  5. #define ABS(var)    ((var) >= 0 ? (var) : -(var))
  6. #endif
  7.  
  8. extern int    sqrsize ;
  9.  
  10. extern int    map_width ;
  11. extern int    map_height ;
  12.  
  13. extern char    *raster ;
  14. extern int    raster_lenght ;
  15. extern int    stride ;
  16.  
  17. extern WINDOW    *win ;
  18.  
  19. extern bool    changed ;
  20.  
  21. extern int    state ;
  22.  
  23. bool    drawline = FALSE ;
  24. int    beg_h ;
  25. int    beg_v ;
  26. int    end_h ;
  27. int    end_v ;
  28.  
  29. bool    drawcircle = FALSE ;
  30. int    cent_h ;
  31. int    cent_v ;
  32. int    c_dh ;
  33. int    c_dv ;
  34.  
  35. bool    selrect = FALSE ;
  36. int    sr_left ;
  37. int    sr_top ;
  38. int    sr_right ;
  39. int    sr_bottom ;
  40.  
  41. void
  42. wxorrect (left, top, right, bottom)
  43.     int    left ;
  44.     int    top ;
  45.     int    right ;
  46.     int    bottom ;
  47. {
  48.     wxorline (left, top, right - 1, top) ;
  49.     wxorline (right - 1, top, right -1, bottom - 1) ;
  50.     wxorline (left, bottom - 1, right -1, bottom - 1) ;
  51.     wxorline (left, top, left, bottom - 1) ;
  52.  
  53.     if (right - left <= bottom - top) {
  54.         wxorline (left, top, right - 1, top + (right - left) - 1) ;
  55.         wxorline (right - 1, top, left, top + (right - left) - 1) ;
  56.     }
  57.     else {
  58.         wxorline (left, top, left + (bottom - top) - 1, bottom - 1) ;
  59.         wxorline (right - 1, top, right - (bottom - top) - 1, bottom -1) ;
  60.     }
  61. }
  62.     
  63. void
  64. drawselrect ()
  65. {
  66.     int    l = sr_left * sqrsize ;
  67.     int    t = sr_top * sqrsize ;
  68.     int    r = sr_right * sqrsize ;
  69.     int    b = sr_bottom * sqrsize ;
  70.  
  71.     wbegindrawing (win) ;
  72.  
  73.     wxorrect (l, t, r, b) ;
  74.  
  75.     wenddrawing (win) ;
  76. }
  77.  
  78. int
  79. getbit(col, row)
  80. {
  81.     char    *byte ;
  82.     int    rc ;
  83.  
  84.     if (row >= 0 && row < map_height && col >= 0 && col < map_width) {
  85.         byte = raster + (row * stride) + (col / 8) ;
  86.         rc = (*byte & (1 << (col % 8))) ? 1 : 0 ;
  87.     }
  88.     else
  89.         rc = 0 ;
  90.  
  91.     return (rc) ;
  92. }
  93.  
  94. void
  95. setbit(col, row, value)
  96. {
  97.     char    *byte ;
  98.  
  99.     if (row >= 0 && row < map_height && col >= 0 && col < map_width) {
  100.         changed = 1 ;
  101.         byte = raster + (row * stride) + (col / 8) ;
  102.         *byte = (*byte & ~(1 << (col %8))) | (value << (col % 8)) ;
  103.         wchange (win, col * sqrsize, row * sqrsize,
  104.             (col+1) * sqrsize, (row+1) * sqrsize);
  105.     }
  106. }
  107.  
  108. void
  109. do_pencil (ep)
  110.     EVENT    *ep ;
  111. {
  112.     static int    value ;
  113.  
  114.     if (ep->type == WE_MOUSE_DOWN)
  115.         value = !getbit (ep->u.where.h / sqrsize,
  116.                  ep->u.where.v / sqrsize) ;
  117.     setbit (ep->u.where.h / sqrsize,
  118.         ep->u.where.v / sqrsize, value) ;
  119. }
  120.  
  121. void
  122. invertbit (h, v, value)
  123.     int    h ;
  124.     int    v ;
  125.     bool    value ;
  126. {
  127.     if (h < 0 || v < 0 || h >= map_width || v >= map_height)
  128.         return ;
  129.  
  130.     winvert (h * sqrsize, v * sqrsize,
  131.                     (h + 1) * sqrsize, (v + 1) * sqrsize) ;
  132. }
  133.  
  134. void
  135. plotline (fp, value)
  136.     void    (*fp) () ;
  137.     bool    value ;
  138. {
  139.     int    d_h = end_h - beg_h ;
  140.     int    d_v = end_v - beg_v ;
  141.     int    e ;
  142.     int    h = 0 ;
  143.     int    v = 0 ;
  144.     int    hsign = 1 ;
  145.     int    vsign = 1 ;
  146.     int    i ;
  147.  
  148.     if (d_h < 0) {
  149.         d_h = -d_h ;
  150.         hsign = -1 ;
  151.     }
  152.  
  153.     if (d_v < 0) {
  154.         d_v = -d_v ;
  155.         vsign = -1 ;
  156.     }
  157.  
  158.     wbegindrawing (win) ;
  159.  
  160.     if (d_v <= d_h) {
  161.         for (i = 0, e = 2 * d_v - d_h ; i <= d_h ; ++i) {
  162.             (*fp) (beg_h + (hsign * h), beg_v + (vsign * v), value) ;
  163.  
  164.             if (e > 0) {
  165.                 ++v ;
  166.                 e -= (2 * d_h) ;
  167.             }
  168.  
  169.             e += (2 * d_v) ;
  170.             ++h ;
  171.         }
  172.     }
  173.     else {
  174.         for (i = 0, e = 2 * d_h - d_v ; i <= d_v ; ++i) {
  175.             (*fp) (beg_h + (hsign * h), beg_v + (vsign * v), value) ;
  176.  
  177.             if (e > 0) {
  178.                 ++h ;
  179.                 e -= (2 * d_v) ;
  180.             }
  181.  
  182.             e += (2 * d_h) ;
  183.             ++v ;
  184.         }
  185.     }
  186.  
  187.     wenddrawing (win) ;
  188. }
  189.  
  190. void
  191. plotcircle (fp, value)
  192.     void    (*fp) () ;
  193.     bool    value ;
  194. {
  195.     long    h_sqr = c_dh * c_dh ;
  196.     long    v_sqr = c_dv * c_dv ;
  197.     long    r_sqr = h_sqr * v_sqr ;
  198.     long    prev_r = r_sqr ;
  199.     long    min_h ;
  200.     long    min_v ;
  201.     long    min_hv ;
  202.     int    h = c_dh ;
  203.     int    v = 0 ;
  204.  
  205.     wbegindrawing (win) ;
  206.  
  207.     while (h >= 0 && v <= c_dv) {
  208.         (*fp) (cent_h + h, cent_v + v, value) ;
  209.         if (v)
  210.             (*fp) (cent_h + h, cent_v - v, value) ;
  211.         if (h)
  212.             (*fp) (cent_h - h, cent_v + v, value) ;
  213.         if (h && v)
  214.             (*fp) (cent_h - h, cent_v - v, value) ;
  215.  
  216.         min_h = (long) (2 * h - 1) * v_sqr ;
  217.         min_v = (long) (2 * v + 1) * -h_sqr ;
  218.         min_hv = min_h + min_v ;
  219.  
  220.         if (ABS (r_sqr - (prev_r - min_h)) <=
  221.                     ABS (r_sqr - (prev_r - min_v))) {
  222.             if (ABS (r_sqr - (prev_r - min_hv)) <=
  223.                     ABS (r_sqr - (prev_r - min_h))) {
  224.                 prev_r = prev_r - min_hv ;
  225.                 --h ;
  226.                 ++v ;
  227.             }
  228.             else {
  229.                 prev_r = prev_r - min_h ;
  230.                 --h ;
  231.             }
  232.         }
  233.         else {
  234.             if (ABS (r_sqr - (prev_r - min_hv)) <=
  235.                     ABS (r_sqr - (prev_r - min_v))) {
  236.                 prev_r = prev_r - min_hv ;
  237.                 --h ;
  238.                 ++v ;
  239.             }
  240.             else {
  241.                 prev_r = prev_r - min_v ;
  242.                 ++v ;
  243.             }
  244.         }
  245.     }
  246.  
  247.     wenddrawing (win) ;
  248. }
  249.  
  250. void
  251. do_line (ep)
  252.     EVENT    *ep ;
  253. {
  254.     int    curr_h = ep->u.where.h / sqrsize ;
  255.     int    curr_v = ep->u.where.v / sqrsize ;
  256.  
  257.     if (curr_h > map_height - 1)
  258.         curr_h = map_height - 1 ;
  259.     if (curr_v > map_width - 1)
  260.         curr_v = map_width - 1 ;
  261.  
  262.     switch (ep->type) {
  263.     case WE_MOUSE_DOWN :
  264.         if (drawline) {
  265.             plotline (invertbit, FALSE) ;
  266.             drawline = FALSE ;
  267.         }
  268.  
  269.         drawline = TRUE ;
  270.  
  271.         beg_h = end_h = curr_h ;
  272.         beg_v = end_v = curr_v ;
  273.  
  274.         plotline (invertbit, TRUE) ;
  275.         break ;
  276.     case WE_MOUSE_MOVE :
  277.         if (drawline) {
  278.             if (curr_h == end_h && curr_v == end_v)
  279.                 return ;
  280.  
  281.             plotline (invertbit, FALSE) ;
  282.  
  283.             end_h = curr_h ;
  284.             end_v = curr_v ;
  285.  
  286.             plotline (invertbit, TRUE) ;
  287.         }
  288.         break ;
  289.     case WE_MOUSE_UP :
  290.         if (drawline) {
  291.             if (curr_h != end_h || curr_v != end_v) {
  292.                 plotline (invertbit, FALSE) ;
  293.  
  294.                 end_h = curr_h ;
  295.                 end_v = curr_v ;
  296.  
  297.                 plotline (invertbit, TRUE) ;
  298.             }
  299.  
  300.             plotline (setbit, TRUE) ;
  301.  
  302.             drawline = FALSE ;
  303.         }
  304.         break ;
  305.     }
  306. }
  307.  
  308. void
  309. do_circle (ep)
  310.     EVENT    *ep ;
  311. {
  312.     int    curr_h = ep->u.where.h / sqrsize ;
  313.     int    curr_v = ep->u.where.v / sqrsize ;
  314.  
  315.     if (curr_h > map_height - 1)
  316.         curr_h = map_height - 1 ;
  317.     if (curr_v > map_width - 1)
  318.         curr_v = map_width - 1 ;
  319.  
  320.     switch (ep->type) {
  321.     case WE_MOUSE_DOWN :
  322.         if (drawcircle) {
  323.             plotcircle (invertbit, FALSE) ;
  324.             drawcircle = FALSE ;
  325.         }
  326.  
  327.         drawcircle = TRUE ;
  328.  
  329.         cent_h = curr_h ;
  330.         cent_v = curr_v ;
  331.         c_dh = c_dv = 0 ;
  332.  
  333.         plotcircle (invertbit, TRUE) ;
  334.         break ;
  335.     case WE_MOUSE_MOVE :
  336.         if (drawcircle) {
  337.             if (ABS ((curr_h - cent_h) + 1) == c_dh &&
  338.                     ABS ((curr_v - cent_v) + 1) == c_dv)
  339.                 return ;
  340.  
  341.             plotcircle (invertbit, FALSE) ;
  342.  
  343.             c_dh = ABS (curr_h - cent_h) ;
  344.             c_dv = ABS (curr_v - cent_v) ;
  345.  
  346.             plotcircle (invertbit, TRUE) ;
  347.         }
  348.         break ;
  349.     case WE_MOUSE_UP :
  350.         if (drawcircle) {
  351.             if (ABS ((curr_h - cent_h) + 1) != c_dh ||
  352.                     ABS ((curr_v - cent_v) + 1) != c_dv) {
  353.                 plotcircle (invertbit, FALSE) ;
  354.  
  355.                 c_dh = ABS (curr_h - cent_h) ;
  356.                 c_dv = ABS (curr_v - cent_v) ;
  357.  
  358.                 plotcircle (invertbit, TRUE) ;
  359.             }
  360.  
  361.             plotcircle (setbit, TRUE) ;
  362.  
  363.             drawcircle = FALSE ;
  364.         }
  365.         break ;
  366.     }
  367. }
  368.  
  369. void
  370. do_select (ep)
  371.     EVENT    *ep ;
  372. {
  373.     static int    sr_h ;    /* coord. of mouse down */
  374.     static int    sr_v ;
  375.     int    curr_h = ep->u.where.h / sqrsize ;
  376.     int    curr_v = ep->u.where.v / sqrsize ;
  377.  
  378.     switch (ep->type) {
  379.     case WE_MOUSE_DOWN :
  380.         if (selrect) {
  381.             drawselrect () ;
  382.             selrect = FALSE ;
  383.         }
  384.  
  385.         if (curr_h >= map_width || curr_v >= map_height)
  386.             return ;
  387.  
  388.         selrect = TRUE ;
  389.         sr_h = curr_h ;
  390.         sr_v = curr_v ;
  391.  
  392.         sr_left = curr_h ;
  393.         sr_top = curr_v ;
  394.         sr_right = sr_left + 1 ;
  395.         sr_bottom = sr_top + 1 ;
  396.  
  397.         drawselrect () ;
  398.         break ;
  399.     case WE_MOUSE_MOVE :
  400.         if (selrect) {
  401.             if (curr_h >= map_width)
  402.                 curr_h = map_width - 1 ;
  403.             if (curr_v >= map_height)
  404.                 curr_v = map_height - 1 ;
  405.  
  406.             if (curr_h < 0)
  407.                 curr_h = 0 ;
  408.             if (curr_v < 0)
  409.                 curr_v = 0 ;
  410.  
  411.             drawselrect () ;
  412.  
  413.             if (curr_h < sr_h) {
  414.                 sr_left = curr_h ;
  415.                 sr_right = sr_h + 1 ;
  416.             }
  417.             else {
  418.                 sr_left = sr_h ;
  419.                 sr_right = curr_h + 1 ;
  420.             }
  421.  
  422.             if (curr_v < sr_v) {
  423.                 sr_top = curr_v ;
  424.                 sr_bottom = sr_v + 1 ;
  425.             }
  426.             else {
  427.                 sr_top = sr_v ;
  428.                 sr_bottom = curr_v + 1 ;
  429.             }
  430.  
  431.             drawselrect () ;
  432.         }
  433.         break ;
  434.     case WE_MOUSE_UP :
  435.             break ;
  436.     }
  437. }
  438.  
  439. void
  440. do_mouse (ep)
  441.     EVENT    *ep ;
  442. {
  443.     switch (state) {
  444.     case PENCIL_ITEM :
  445.         do_pencil (ep) ;
  446.         break ;
  447.     case LINE_ITEM :
  448.         do_line (ep) ;
  449.         break ;
  450.     case CIRCLE_ITEM :
  451.         do_circle (ep) ;
  452.         break ;
  453.     case SELECT_ITEM :
  454.         do_select (ep) ;
  455.         break ;    
  456.     }
  457. }
  458.