home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mnth0109.zip / Timur / target.c < prev    next >
Text File  |  1993-06-07  |  6KB  |  188 lines

  1. /* TARGET.C - Targeting routines
  2.  
  3. Copyright (c) 1992-1993 Timur Tabi
  4. Copyright (c) 1992-1993 Fasa Corporation
  5.  
  6. The following trademarks are the property of Fasa Corporation:
  7. BattleTech, CityTech, AeroTech, MechWarrior, BattleMech, and 'Mech.
  8. The use of these trademarks should not be construed as a challenge to these marks.
  9.  
  10. */
  11.  
  12. #define TARGET_C
  13. #define INCL_DOS
  14. #define INCL_GPIPRIMITIVES
  15. #define INCL_WINWINDOWMGR
  16. #define INCL_WININPUT
  17. #define INCL_GPIBITMAPS
  18. #include <os2.h>
  19. #include <math.h>
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22.  
  23. #include "header.h"
  24. #include "errors.h"
  25. #include "hexes.h"
  26. #include "target.h"
  27. #include "target0.h"
  28. #include "terrain.h"
  29. #include "dialog.h"
  30. #include "window.h"
  31.  
  32. TARGET target={FALSE,NULLHANDLE,NULLHANDLE};
  33.  
  34. void TgtInit(void) {
  35. /* Loads, displays, and positions the targetting box.  Then sets the focus back to the main window.
  36. */
  37.   RECTL rclBox,rclFrame;
  38.   LONG lx,ly;
  39.  
  40. /*  target.fActive=FALSE;
  41.   target.hpsLine=NULLHANDLE;
  42.   target.hpsPath=NULLHANDLE;
  43. */
  44.   hwndInfoBox=WinLoadDlg(HWND_DESKTOP,HWND_DESKTOP,NULL,NULLHANDLE,IDD_TARGETTING,NULL);
  45.   WinQueryWindowRect(hwndFrame,&rclFrame);
  46.   WinQueryWindowRect(hwndInfoBox,&rclBox);
  47.   lx=rclFrame.xRight+10;
  48.   ly=rclFrame.yTop-(rclBox.yTop-rclBox.yBottom);
  49.   WinSetWindowPos(hwndInfoBox,HWND_BOTTOM,lx,ly,0,0,SWP_MOVE | SWP_SHOW);
  50.   WinSetFocus(HWND_DESKTOP,hwndFrame);
  51. }
  52.  
  53. void TgtStart(HEXINDEX hi) {
  54. /* This function activates the targeting mechanism.  It also spanws the thread that
  55.    performs the color cycling of the source hexagon
  56. */
  57.   TID tid;
  58.  
  59.   target.fActive=TRUE;
  60.   target.hiStart=hi;
  61.   target.hiEnd=hi;
  62.   target.ptlStart=HexMidpoint(hi);
  63.   target.ptlEnd=target.ptlStart;
  64.  
  65.   target.hpsLine=WinGetPS(hwndClient);
  66.   target.hpsPath=WinGetPS(hwndClient);
  67.   GpiSetColor(target.hpsLine,CLR_WHITE);
  68.   GpiSetMix(target.hpsLine,FM_XOR);
  69.   GpiSetColor(target.hpsPath,CLR_RED);
  70.   GpiSetMix(target.hpsPath,FM_XOR);
  71.  
  72.   WinSetCapture(HWND_DESKTOP,hwndClient);
  73.   DosCreateThread(&tid,Highlight,0UL,0UL,4096UL);
  74. }
  75.  
  76. static void TgtInitPath(void) {
  77. /* This function is used to initialize various field in 'target' that are constant for a given
  78.    targetting line.  This makes sure that we don't waste any time calculating the targeting path.
  79. */
  80.   int dx=target.hiEnd.c-target.hiStart.c;
  81.   int dy=target.hiEnd.r-target.hiStart.r;             // always even
  82.   int d=abs(dy)-abs(dx);                              // always even if d>0
  83.  
  84.   target.range = (d <= 0) ? abs(dx) : abs(dx)+d/2;
  85.   target.angle = (int) (0.5+atan2(target.ptlEnd.y-target.ptlStart.y,target.ptlEnd.x-target.ptlStart.x)*180.0/pi);
  86.   target.iVis = 0;
  87.  
  88.   target.dx=target.ptlEnd.x-target.ptlStart.x;    // x-delta for targeting line
  89.  
  90.   if (target.dx != 0) {
  91.     target.m=(float) (target.ptlEnd.y - target.ptlStart.y) / target.dx;
  92.     target.b=target.ptlStart.y-target.m*target.ptlStart.x;
  93.   }
  94. }
  95.  
  96. static void TgtShowPath(void) {
  97. /* This function a series of line segments that connect the midpoints of the
  98.    targeting path.  Since it uses the FM_XOR mix-mode, it erases the line
  99.    every other time it's called.
  100.    Assumes that target.hiStart != target.hiEnd
  101.  
  102.    iTrueSide is the alternate exit side.  For each iteration, iTrueSide equals the side that
  103.    Future enhancement: support for vertex angles.
  104. */
  105.   HEXINDEX hi;
  106.   POINTL ptl;
  107.   int iSide;
  108.  
  109. // Draw the first segment
  110.   hi=target.hiStart;                                  // Start at the beginning
  111.   iSide=FirstSide(hi,target.hiEnd);                   // Which way first?
  112.   if (iSide<0) return;                                // Don't draw a line if it's through a vertex
  113.   ptl=HexMidpoint(hi);
  114.   GpiMove(target.hpsPath,&ptl);
  115.  
  116.   hi=HexFromSide(hi,iSide);                           // Update to the next hex
  117.   ptl=HexMidpoint(hi);
  118.   GpiLine(target.hpsPath,&ptl);                       // Draw the first segment
  119.  
  120. // If there are any more segments, draw them too
  121.  
  122.   while (!HI_EQUAL(hi,target.hiEnd)) {                // while we're not at the end
  123.     iSide=ExitSide(hi);                               // Find the exit side
  124.     if (iSide<0) return;                              // Couldn't find one? Just exit
  125.  
  126.     hi=HexFromSide(hi,iSide);
  127.     ptl=HexMidpoint(hi);
  128.     target.iVis+=ater[amap[hi.c][hi.r].iTerrain].iVisibility;
  129.     GpiLine(target.hpsPath,&ptl);
  130.     if (HI_EQUAL(hi,target.hiStart))        // Infinite loop?
  131.       return;                               //  Then get out of here!
  132.   }
  133. }
  134.  
  135. void TgtMove(HEXINDEX hi) {
  136. /* Performs all the necessary updates whenever the targeting line is moved.
  137.    Called every time target.fActive is TRUE, and a WM_MOUSEMOVE message is received.
  138.    First determines if the pointer has moved to a new hexagon.  If not, it
  139.    simply exists.
  140.    Otherwise, it erases the existing targeting line and targeting path, draws
  141.    the new ones, and updates the info box.
  142. */
  143.   char sz[33];                                          // temp string
  144.  
  145. // If the target hex hasn't moved, just exit
  146.   if HI_EQUAL(target.hiEnd,hi) return;
  147.  
  148. // Erase any existing line
  149.   if (!HI_EQUAL(target.hiStart,target.hiEnd)) {
  150.     GpiMove(target.hpsLine,&target.ptlStart);
  151.     GpiLine(target.hpsLine,&target.ptlEnd);
  152.     TgtShowPath();
  153.   }
  154.  
  155. // Set the new endpoint
  156.   target.ptlEnd=HexMidpoint(target.hiEnd=hi);
  157.   TgtInitPath();
  158.  
  159. // Draw the new line if it exists
  160.   if (!HI_EQUAL(target.hiStart,target.hiEnd)) {
  161.     GpiMove(target.hpsLine,&target.ptlStart);
  162.     GpiLine(target.hpsLine,&target.ptlEnd);
  163.     TgtShowPath();
  164.   }
  165.  
  166.   WinSetDlgItemText(hwndInfoBox,IDD_ANGLE,_itoa(target.angle,sz,10));
  167.   WinSetDlgItemText(hwndInfoBox,IDD_RANGE,_itoa(target.range,sz,10));
  168.   WinSetDlgItemText(hwndInfoBox,IDD_VISIBILITY,_itoa(target.iVis,sz,10));
  169.   sprintf(sz,"(%i,%i)",target.hiEnd.c,target.hiEnd.r);
  170.   WinSetDlgItemText(hwndInfoBox,IDD_TARGETPOS,sz);
  171. }
  172.  
  173. void TgtEnd(void) {
  174. /* Cancels the current targeting session
  175. */
  176.   target.fActive=FALSE;                           // Automatically terminates HexHighlight
  177.   if (!HI_EQUAL(target.hiStart,target.hiEnd)) {   // Erase the line if it exists
  178.     GpiMove(target.hpsLine,&target.ptlStart);
  179.     GpiLine(target.hpsLine,&target.ptlEnd);
  180.     TgtShowPath();
  181.   }
  182.  
  183.   WinSetDlgItemText(hwndInfoBox,IDD_TARGETPOS,"");
  184.   WinSetCapture(HWND_DESKTOP,NULLHANDLE);
  185.   WinReleasePS(target.hpsLine);
  186.   WinReleasePS(target.hpsPath);
  187. }
  188.