home *** CD-ROM | disk | FTP | other *** search
/ ISV Strong Games / ISV_STRONG_GAMES.iso / desktop / polysaw / !PolySaw / source / c / dragging next >
Text File  |  1990-07-30  |  12KB  |  551 lines

  1. /* 
  2. herein are functions called in response to a left button drag
  3. or right click in window "board", in mode Play.
  4. */
  5.  
  6. #include "wimp.h"
  7. #include "wimpt.h"
  8. #include "win.h"
  9. #include "event.h"
  10. #include "werr.h"
  11. #include "bbc.h" 
  12. #include "coords.h" 
  13.  
  14. #include <stdlib.h>
  15.  
  16. #include "Polysaw.h"
  17.  
  18. /* data structures for dragging */
  19. static  DragState        drag;
  20. static  Polymo           dragged;
  21.  
  22.  
  23. /************************ FUNCTIONS ************************/
  24.  
  25.  
  26. static  void    flip_piece(void);
  27. static  void    set_drag_state(coords_pointstr w, coords_pointstr m);
  28. static  void    start_drag(void);
  29. static  void    start_move_drag(void);
  30. static  void    start_spin_drag(void);
  31. static  void    update_move_drag(void);
  32. static  void    update_spin_drag(void);
  33. static  void    put_down_after_move(int wrk_x, int wrk_y);
  34. static  void    put_down_after_spin(coords_pointstr mse);
  35. static  void    eor_draw_moving_piece(int x, int y);
  36. static  void    eor_draw_spinning_piece(coords_pointstr);
  37.  
  38. static  void    put_down_poly(void);
  39. static  BOOL    room_for_dragged(void);
  40. static  void    find_spin_angle(int *sin, int *cos, coords_pointstr origin,                                    coords_pointstr from, coords_pointstr to);
  41.  
  42.  
  43. /*_____________________________________________________________*/
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54. void deal_with_play_but(coords_pointstr wrk, coords_pointstr mse,                                           wimp_bbits mse_b, wimp_box box)
  55. {
  56. wimp_dragstr    dragstr;          
  57.  
  58. if (mse_b & wimp_BRIGHT)  
  59.    {
  60.    if (which_piece(wrk) < MAX_PIECES)
  61.      {
  62.      drag.piece = which_piece(wrk);
  63.      dragged = piece[which_piece(wrk)];                        
  64.      flip_piece();
  65.      }
  66.    }
  67.  
  68. if (mse_b & wimp_BDRAGLEFT)
  69.    {
  70.    set_drag_state(wrk, mse);
  71.  
  72.    dragstr.window = board_wh;
  73.    dragstr.type = 7;
  74.    dragstr.parent = box;
  75.    wimpt_noerr(wimp_drag_box(&dragstr));
  76.    start_drag();
  77.  
  78.    }
  79. }
  80.  
  81.  
  82. void flip_piece(void)
  83. {
  84. int i;
  85.  
  86. for (i=0; i<dragged.nofunits; i++) 
  87.   {
  88.   dragged.units[i].x = -dragged.units[i].x;
  89.   }
  90. dragged.rotflipstate = 9 - dragged.rotflipstate;
  91.  
  92. put_down_poly();
  93. }
  94.  
  95.  
  96.  
  97.  
  98. void set_drag_state(coords_pointstr w, coords_pointstr m)
  99. {
  100. int p, i;
  101. coords_pointstr pt;
  102.  
  103. drag.start = m;
  104. drag.old = m;
  105.  
  106. for (p=0; p < nofpieces; p++)
  107.   {
  108.   pt.x = w.x - piece[p].cog.x;
  109.   pt.y = w.y - piece[p].cog.y;
  110.   /* pt is offset to centre of piece, as all piece info is rel. cog */
  111.   if ( coords_withinbox(&pt, &piece[p].box) )   
  112.      {
  113.      for (i=0; i < piece[p].nofunits; i++)
  114.         {
  115.         if ( abs(pt.x - piece[p].units[i].x) <= HS   &&   
  116.              abs(pt.y - piece[p].units[i].y) <= HS )   
  117.              {
  118.              drag.piece = p;
  119.              dragged = piece[p];
  120.              if (  (pt.x)*(pt.x) + (pt.y)*(pt.y) < piece[p].movespin_rad  )
  121.                  drag.kind = 1; 
  122.              else
  123.                  drag.kind = -1;
  124.              return;
  125.              }
  126.         }
  127.      }
  128.   }
  129. drag.kind = 0;
  130. drag.piece = MAX_PIECES+1;
  131. return;
  132. }
  133.  
  134.  
  135. void start_drag(void)
  136. {
  137. event_setmask((wimp_emask)0);
  138. if (drag.kind ==  1) start_move_drag(); 
  139. if (drag.kind == -1) start_spin_drag();
  140. }
  141.  
  142.  
  143.  
  144. void start_move_drag(void)
  145. {
  146. wimp_redrawstr r;
  147. int more;
  148.  
  149. r.w = board_wh;
  150. r.box = board_windefn->ex;
  151. wimpt_noerr(wimp_update_wind(&r, &more));
  152.  
  153. while (more)
  154.   {
  155.   eor_draw_moving_piece(drag.old.x, drag.old.y);
  156.   wimpt_noerr(wimp_get_rectangle(&r, &more));
  157.   } 
  158.  
  159.  
  160.  
  161. void start_spin_drag(void)
  162. {
  163. wimp_redrawstr r;
  164. int more;
  165. int i;
  166.  
  167. /* fill in outline defns in drag.lines[]. */
  168.  
  169. for (i=0; i < piece[drag.piece].nofunits; i++)
  170.   {
  171.   drag.lines[4*i+0].x0 = piece[drag.piece].units[i].x + HS;
  172.   drag.lines[4*i+0].y0 = piece[drag.piece].units[i].y + HS;
  173.   drag.lines[4*i+0].x1 = piece[drag.piece].units[i].x + HS;
  174.   drag.lines[4*i+0].y1 = piece[drag.piece].units[i].y - HS;
  175.  
  176.   drag.lines[4*i+1].x0 = piece[drag.piece].units[i].x + HS;
  177.   drag.lines[4*i+1].y0 = piece[drag.piece].units[i].y - HS;
  178.   drag.lines[4*i+1].x1 = piece[drag.piece].units[i].x - HS;
  179.   drag.lines[4*i+1].y1 = piece[drag.piece].units[i].y - HS;
  180.  
  181.   drag.lines[4*i+2].x0 = piece[drag.piece].units[i].x - HS;
  182.   drag.lines[4*i+2].y0 = piece[drag.piece].units[i].y - HS;
  183.   drag.lines[4*i+2].x1 = piece[drag.piece].units[i].x - HS;
  184.   drag.lines[4*i+2].y1 = piece[drag.piece].units[i].y + HS;
  185.  
  186.   drag.lines[4*i+3].x0 = piece[drag.piece].units[i].x - HS;
  187.   drag.lines[4*i+3].y0 = piece[drag.piece].units[i].y + HS;
  188.   drag.lines[4*i+3].x1 = piece[drag.piece].units[i].x + HS;
  189.   drag.lines[4*i+3].y1 = piece[drag.piece].units[i].y + HS;
  190.   }
  191.  
  192.  
  193. r.w = board_wh;
  194. r.box.x0 = piece[drag.piece].cog.x + 3*piece[drag.piece].box.x0/2;
  195. r.box.y0 = piece[drag.piece].cog.y + 3*piece[drag.piece].box.y0/2;
  196. r.box.x1 = piece[drag.piece].cog.x + 3*piece[drag.piece].box.x1/2;
  197. r.box.y1 = piece[drag.piece].cog.y + 3*piece[drag.piece].box.y1/2;
  198.  
  199. wimpt_noerr(wimp_update_wind(&r, &more));
  200.  
  201. while (more)
  202.   {
  203.   eor_draw_spinning_piece(drag.start);
  204.   wimpt_noerr(wimp_get_rectangle(&r, &more));
  205.   } 
  206. }
  207.  
  208.  
  209. void update_drag(void)
  210. {
  211. if (drag.kind ==  1) update_move_drag();  
  212. if (drag.kind == -1) update_spin_drag();  
  213. }
  214.  
  215.  
  216.  
  217.  
  218. void  update_move_drag(void)
  219. {
  220. wimp_mousestr  m;
  221. wimp_redrawstr r;
  222. int more;
  223. int wrk_x, wrk_y;
  224.  
  225. wimpt_noerr(wimp_get_point_info(&m));
  226.  
  227. r.w = board_wh;
  228. r.box = board_windefn->ex;
  229.  
  230. if (m.bbits) 
  231.   {
  232.   drag.new.x = m.x;
  233.   drag.new.y = m.y;
  234.   
  235.   wimpt_noerr(wimp_update_wind(&r, &more));
  236.   while (more)
  237.     {
  238.     eor_draw_moving_piece(drag.old.x, drag.old.y);
  239.     eor_draw_moving_piece(drag.new.x, drag.new.y);
  240.  
  241.     wimpt_noerr(wimp_get_rectangle(&r, &more));
  242.     }
  243.   drag.old = drag.new;
  244.   }
  245. else
  246.   {        
  247.   wimpt_noerr(wimp_update_wind(&r, &more));
  248.  
  249.   while (more)
  250.     {
  251.     eor_draw_moving_piece(drag.old.x, drag.old.y);           
  252.     wimpt_noerr(wimp_get_rectangle(&r, &more));
  253.     }
  254.  
  255.   wrk_x = coords_x_toworkarea(drag.old.x, (coords_cvtstr *)&r.box);
  256.   wrk_y = coords_y_toworkarea(drag.old.y, (coords_cvtstr *)&r.box);
  257.  
  258.   put_down_after_move(wrk_x, wrk_y);
  259.   }
  260. }
  261.  
  262.  
  263.  
  264. void update_spin_drag(void)
  265. {
  266. wimp_mousestr  m;
  267. wimp_redrawstr r;
  268. int more;
  269. int wrk_x, wrk_y;
  270.  
  271. wimpt_noerr(wimp_get_point_info(&m));
  272.  
  273. r.w = board_wh;
  274. r.box.x0 = piece[drag.piece].cog.x + 3*piece[drag.piece].box.x0/2;
  275. r.box.y0 = piece[drag.piece].cog.y + 3*piece[drag.piece].box.y0/2;
  276. r.box.x1 = piece[drag.piece].cog.x + 3*piece[drag.piece].box.x1/2;
  277. r.box.y1 = piece[drag.piece].cog.y + 3*piece[drag.piece].box.y1/2;
  278.  
  279. if (m.bbits) 
  280.   {
  281.   drag.new.x = m.x;
  282.   drag.new.y = m.y;
  283.   
  284.   wimpt_noerr(wimp_update_wind(&r, &more));
  285.   while (more)
  286.     {
  287.     eor_draw_spinning_piece(drag.old);
  288.     eor_draw_spinning_piece(drag.new);
  289.  
  290.     wimpt_noerr(wimp_get_rectangle(&r, &more));
  291.     }
  292.   drag.old.x = drag.new.x;
  293.   drag.old.y = drag.new.y;
  294.   }
  295. else
  296.   {    
  297.   wimpt_noerr(wimp_update_wind(&r, &more));
  298.  
  299.   while (more)
  300.     {
  301.     eor_draw_spinning_piece(drag.old);           
  302.     wimpt_noerr(wimp_get_rectangle(&r, &more));
  303.     }
  304.  
  305.   wrk_x = coords_x_toworkarea(drag.old.x, (coords_cvtstr *)&r.box);
  306.   wrk_y = coords_y_toworkarea(drag.old.y, (coords_cvtstr *)&r.box);
  307.  
  308.   put_down_after_spin(drag.old);
  309.   }
  310. }
  311.  
  312.  
  313.  
  314.  
  315.  
  316.  
  317. void eor_draw_moving_piece(int x, int y)
  318. {
  319. int i;
  320.  
  321. wimpt_noerr(wimp_setcolour( (0<<7) | (3<<4) | 2));
  322.  
  323. for (i=0; i < piece[drag.piece].nofunits; i++)
  324.       {
  325.         wimpt_noerr(bbc_rectangle(x + piece[drag.piece].units[i].x - HS,  y + piece[drag.piece].units[i].y - HS,  2*HS-1,  2*HS-1));
  326.       }
  327.  
  328. }
  329.  
  330.  
  331. void eor_draw_spinning_piece(coords_pointstr mse)
  332. {
  333. int             sin, cos;       /* use binary point at bit 12 */
  334. int             a, b, x0, y0, x1, y1, i;
  335. coords_pointstr cog;
  336. wimp_wstate     winstate;
  337.  
  338. wimpt_noerr(wimp_get_wind_state(board_wh, &winstate));
  339.  
  340. cog = piece[drag.piece].cog;
  341. coords_point_toscreen(&cog, (coords_cvtstr *)&winstate.o.box);
  342.  
  343. /* now  cog, drag.start, mse are in screen coords */
  344.  
  345. find_spin_angle(&sin, &cos, cog, drag.start, mse); 
  346.  
  347. /* draw rotated lines */
  348. for (i = 0; i < 4*(piece[drag.piece].nofunits); i++)
  349.   {
  350.   a = drag.lines[i].x0;
  351.   b = drag.lines[i].y0;
  352.   x0 = (int) ( ((a*cos)>>12) - ((b*sin)>>12) ) + cog.x;
  353.   y0 = (int) ( ((a*sin)>>12) + ((b*cos)>>12) ) + cog.y;
  354.   a = drag.lines[i].x1;
  355.   b = drag.lines[i].y1;
  356.   x1 = (int) ( ((a*cos)>>12) - ((b*sin)>>12) ) + cog.x;
  357.   y1 = (int) ( ((a*sin)>>12) + ((b*cos)>>12) ) + cog.y;
  358.  
  359.   wimpt_noerr(wimp_setcolour( (0<<7) | (3<<4) | 2));
  360.   wimpt_noerr(bbc_move(x0, y0));
  361.   wimpt_noerr(bbc_draw(x1, y1));
  362.   }
  363.  
  364. }
  365.  
  366.  
  367.  
  368.  
  369.  
  370. void put_down_after_move(int wrk_x, int wrk_y)
  371. {
  372. int cogmodgrid;
  373.  
  374. cogmodgrid = dragged.cog.x % (2*HS);
  375.   dragged.cog.x  =  roundtonearest(wrk_x - cogmodgrid, 2*HS) +                                                               cogmodgrid;
  376. cogmodgrid = dragged.cog.y % (2*HS);
  377.   dragged.cog.y  =  roundtonearest(wrk_y - cogmodgrid, 2*HS) +                                                               cogmodgrid;
  378. put_down_poly();
  379. }
  380.  
  381.  
  382. void put_down_after_spin(coords_pointstr mse)
  383. {
  384. int             sin, cos;
  385. int               i, ang, qtsin, qtcos;
  386. coords_pointstr   cog;
  387. wimp_wstate       winstate;
  388.  
  389. wimpt_noerr(wimp_get_wind_state(board_wh, &winstate));
  390.  
  391. cog = dragged.cog;
  392. coords_point_toscreen(&cog, (coords_cvtstr *)&winstate.o.box);
  393.  
  394. find_spin_angle(&sin, &cos, cog, drag.start, mse); 
  395.  
  396. if (   abs(sin) < (int) (0.7*4096)   ) 
  397.   {
  398.   qtsin = 0;
  399.   if (cos < 0)
  400.      { 
  401.      qtcos = -1;
  402.      ang=4;
  403.      }
  404.   else
  405.      {
  406.      qtcos = 1;
  407.      ang=0;
  408.      }
  409.   }
  410. else
  411.   {
  412.   qtcos = 0;
  413.   if (sin < 0)
  414.      {
  415.      qtsin = -1;
  416.      ang=6;
  417.      }
  418.   else
  419.      {
  420.      qtsin = 1;
  421.      ang=2;
  422.      }
  423.   }
  424.  
  425. if (ang==2 || ang==6)
  426.   {
  427.   int xfidget, yfidget;
  428.   xfidget = dragged.cog.x % (2*HS);
  429.   yfidget = dragged.cog.y % (2*HS);
  430.   dragged.cog.x = roundtonearest(dragged.cog.x, 2*HS) + yfidget;
  431.   dragged.cog.y = roundtonearest(dragged.cog.y, 2*HS) + xfidget;
  432.   }
  433.  
  434.  
  435. dragged.rotflipstate += ang;
  436. dragged.rotflipstate &= 7;
  437. for (i=0; i < dragged.nofunits; i++)
  438.   {
  439.   int x, y;
  440.  
  441.   x = dragged.units[i].x;
  442.   y = dragged.units[i].y;
  443.   dragged.units[i].x = x*qtcos - y*qtsin;
  444.   dragged.units[i].y = x*qtsin + y*qtcos;
  445.  
  446.   }
  447.  
  448. put_down_poly();
  449. }
  450.  
  451.  
  452.  
  453. void put_down_poly(void)
  454. {
  455. int i, p, x, y;
  456.  
  457. p= drag.piece;      
  458.  
  459. event_setmask((wimp_emask)1);
  460.  
  461. /* delete poly from grid[][] */ 
  462. for (i=0; i<piece[p].nofunits; i++)
  463.   {
  464.     x = piece[p].cog.x + piece[p].units[i].x;
  465.     y = piece[p].cog.y + piece[p].units[i].y;
  466.     grid[(-y-HS)/(2*HS)][(x-HS)/(2*HS)] &= ~PIECE_BIT;
  467.   }
  468.  
  469. if (room_for_dragged())
  470.   {
  471.   force_piece_redraw(drag.piece);   /* clear old position */
  472.   piece[drag.piece] = dragged;
  473.   force_piece_redraw(drag.piece);   /* draw new posn */
  474.   }
  475. else
  476.   bbc_vdu(7);
  477.  
  478. /* put poly back in grid, in new or old posn */
  479.  
  480. for (i=0; i<piece[p].nofunits; i++)
  481.   {
  482.     x = piece[p].cog.x + piece[p].units[i].x;
  483.     y = piece[p].cog.y + piece[p].units[i].y;
  484.     grid[(-y-HS)/(2*HS)][(x-HS)/(2*HS)] |= PIECE_BIT;
  485.   }
  486. drag.kind = 0;
  487. }
  488.  
  489.  
  490. BOOL    room_for_dragged(void)
  491. {
  492. int x,y,g,i, row, col;
  493. for (i=0; i<dragged.nofunits; i++)
  494.   {
  495.     x = dragged.cog.x + dragged.units[i].x;
  496.     y = dragged.cog.y + dragged.units[i].y;
  497.     col = (x-HS)/(2*HS);
  498.     row = (-y-HS)/(2*HS);
  499.     if (col<0 || row<0 || col>=MAX_BOARD || row>=MAX_BOARD)
  500.            return FALSE;
  501.     g = grid[row][col];
  502.     if ( g & (PIECE_BIT | SQUARE_BIT) )
  503.            return FALSE;
  504.   }
  505. return TRUE;
  506. }
  507.  
  508.  
  509.  
  510. void  find_spin_angle(int *sin, int *cos, coords_pointstr origin,                                    coords_pointstr from, coords_pointstr to)
  511. {
  512. int c, d;
  513. int fx, fy, tx, ty;
  514.  
  515. /*  a bit of trig.
  516. *
  517. *        origin
  518. *           *---------------to
  519. *            \ angle
  520. *             \
  521. *              \
  522. *               \
  523. *                \
  524. *                 \from
  525. */ 
  526.  
  527. fx = from.x - origin.x;
  528. fy = from.y - origin.y;
  529. tx = to.x - origin.x;
  530. ty = to.y - origin.y;
  531.  
  532. c = integer_sqrt(tx*tx + ty*ty);
  533. d = integer_sqrt(fx*fx + fy*fy);
  534.  
  535. d = c*d;
  536. if (c <= 8)
  537.   {
  538.   *sin = 4096;
  539.   *cos = 0;
  540.   }
  541. else
  542.   { 
  543.   *sin = ((fx*ty - fy*tx)<<12)/d;
  544.   *cos = ((fx*tx + fy*ty)<<12)/d;
  545.   }
  546.  
  547.  
  548.  
  549.