home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mnth0106.zip / Timur / HEXES.C < prev    next >
Text File  |  1992-06-27  |  8KB  |  219 lines

  1. /* HEXES.C - Hex map routines
  2.  
  3. Copyright (c) 1992 Timur Tabi                                                     
  4. Copyright (c) 1992 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. This module contains all the code pertaining to the hexagonal grid of the 
  11. combat map.  This includes drawing and interpreting mouse input.  Hexes are
  12. identified by a column/row index passed as two integers.  X,Y coordinates
  13. are identified with a POINTL structure.
  14. */
  15.  
  16. #define HEXES_C
  17. #define INCL_DOSPROCESS
  18. #define INCL_GPILOGCOLORTABLE
  19. #define INCL_GPIPRIMITIVES
  20. #include <os2.h>
  21. #include <string.h>
  22. #include "game.h"
  23. #include "hexes.h"
  24.  
  25. POINTL HexCoord(HEXINDEX hi) {
  26. /* This function returns the X,Y coordinate of the lower-left vertex for a given hex
  27.    index.
  28. */
  29.    POINTL ptl;
  30.  
  31. // Odd numbered columns are drawn a little to the right of even columns
  32. // HEX_SIDE+HEX_EXT is the X-coordinate of column #1
  33.    if (hi.c & 1)                      
  34.       ptl.x=(LONG) HEX_EXT+(HEX_SIDE+HEX_EXT)+(HEX_SIDE+HEX_DIAM)*(hi.c-1)/2;
  35.    else
  36.       ptl.x=(LONG) HEX_EXT+(HEX_SIDE+HEX_DIAM)*hi.c/2;
  37.    ptl.y=(LONG) hi.r*(HEX_HEIGHT/2);
  38.    return ptl;
  39. }
  40.  
  41. POINTL HexMidpoint(HEXINDEX hi) {
  42. /* This function is identical to HexCoord(), except that it returns the coordinates of
  43.    the midpoint (centerpoint) of the hexagon.
  44. */
  45.    POINTL ptl;
  46.  
  47.    if (hi.c & 1)
  48.       ptl.x=(LONG) (HEX_SIDE/2)+HEX_EXT+(HEX_SIDE+HEX_EXT)+(HEX_SIDE+HEX_DIAM)*(hi.c-1)/2;
  49.    else
  50.       ptl.x=(LONG) (HEX_SIDE/2)+HEX_EXT+(HEX_SIDE+HEX_DIAM)*hi.c/2;
  51.    ptl.y=(LONG) (HEX_HEIGHT/2)+hi.r*(HEX_HEIGHT/2);
  52.    return ptl;
  53. }
  54.  
  55. void HexDraw(HPS hps, HEXINDEX hi) {
  56. /* This function draws a the hexagon at index 'hi'.  'ptlHex' is a series of
  57.    X,Y positions of the vertices, relative to the lower-left vertex.  The
  58.    actual X,Y coordinate of the lower-left vertex is calculated and stored
  59.    in the last element of 'ptlHex'.  This value is then added to the remaining
  60.    5 elements in the array.
  61. */
  62.   POINTL ptlHex[]={ {HEX_SIDE,0},
  63.                     {HEX_SIDE+HEX_EXT,HEX_HEIGHT/2},
  64.                     {HEX_SIDE,HEX_HEIGHT},
  65.                     {0,HEX_HEIGHT},
  66.                     {-HEX_EXT,HEX_HEIGHT/2},
  67.                     {0,0}                         };
  68.   int i=0;
  69.  
  70.   ptlHex[5]=HexCoord(hi);
  71.   GpiMove(hps,&ptlHex[5]);
  72.   for (;i<5;i++) {
  73.     ptlHex[i].x+=ptlHex[5].x;
  74.     ptlHex[i].y+=ptlHex[5].y;
  75.   }
  76.   GpiPolyLine(hps,6L,&ptlHex[0]);
  77. }
  78.  
  79. void HexFillDraw(HEXINDEX hi) {
  80. /* This function is identical to HexDraw() except that it draws the terrain inside the
  81.    hexagon and always uses hpsHex.
  82. */
  83.   GpiSetColor(hpsHex,HexTerrainColor(amap[hi.c][hi.r].bTerrain));
  84.   GpiSetPattern(hpsHex,HexTerrainPattern(amap[hi.c][hi.r].bTerrain));
  85.   GpiBeginArea(hpsHex,BA_NOBOUNDARY);
  86.   HexDraw(hpsHex,hi);
  87.   GpiEndArea(hpsHex);
  88.   GpiSetColor(hpsHex,HEX_COLOR);
  89.   HexDraw(hpsHex,hi);
  90. }
  91.  
  92. BYTE HexTerrainColor(USHORT usTerrain) {
  93. /* This routine returns the color for a given terrain type.  The value returned is 
  94.    a parameter to the GpiSetColor() function.
  95. */
  96.   switch (usTerrain) {
  97.     case IDM_TER_CLEAR_GROUND:  return CLR_BROWN;
  98.     case IDM_TER_ROUGH_GROUND:  return CLR_DARKGRAY;
  99.     case IDM_TER_WATER:         return CLR_DARKBLUE;
  100.     case IDM_TER_LIGHT_WOODS:   return CLR_GREEN;
  101.     case IDM_TER_HEAVY_WOODS:   return CLR_DARKGREEN;
  102.     case IDM_TER_PAVEMENT:      return CLR_PALEGRAY;
  103.     case IDM_TER_BRIDGE:        return CLR_BROWN;
  104.     case IDM_TER_LIGHT_BLDG:
  105.     case IDM_TER_MEDIUM_BLDG:
  106.     case IDM_TER_HEAVY_BLDG:
  107.     case IDM_TER_HARD_BLDG:     return CLR_DARKPINK;
  108.   }
  109.   return 0;
  110. }
  111.  
  112. BYTE HexTerrainPattern(USHORT usTerrain) {
  113. /* This routine returns the pattern for a given terrain type.  The value returned is
  114.    a parameter to the GpiSetPattern() function.
  115. */
  116.   switch (usTerrain) {
  117.     case IDM_TER_CLEAR_GROUND:  return PATSYM_DENSE5;
  118.     case IDM_TER_ROUGH_GROUND:  return PATSYM_DENSE6;
  119.     case IDM_TER_WATER:         return PATSYM_DEFAULT;
  120.     case IDM_TER_HEAVY_WOODS:   return PATSYM_DENSE3;
  121.     case IDM_TER_LIGHT_WOODS:   return PATSYM_DENSE5;
  122.     case IDM_TER_PAVEMENT:      return PATSYM_DEFAULT;
  123.     case IDM_TER_BRIDGE:        return PATSYM_DIAG4;
  124.     case IDM_TER_LIGHT_BLDG:    return PATSYM_DENSE8;
  125.     case IDM_TER_MEDIUM_BLDG:   return PATSYM_DENSE7;
  126.     case IDM_TER_HEAVY_BLDG:    return PATSYM_DENSE6;
  127.     case IDM_TER_HARD_BLDG:     return PATSYM_DENSE5;
  128.   }
  129.   return 0;
  130. }
  131. void HexInitMap(void) {
  132. /* This routine sets the default terrain type, configures the map presentation space
  133.    paramters, and initializes the 'amap' array.  Assumes that hpsHex has already been
  134.    initialized.
  135. */
  136.   int c,r;
  137.  
  138.   mapDefault.bTerrain=IDM_TER_CLEAR_GROUND;
  139.   GpiSetBackMix(hpsHex,BM_OVERPAINT);
  140.   for (c=0;c<NUM_COLUMNS;c++)
  141.     for (r=c & 1;r<NUM_ROWS-(c & 1);r+=2)
  142.        amap[c][r]=mapDefault;
  143. }
  144.  
  145. BOOL HexInPoint(POINTL ptl, HEXINDEX hi) {
  146. /* This function returns TRUE if the point 'ptl' is inside hex 'hi'.
  147.    Currently it only checks the rectangle bounded by the two upper vertices
  148.    and the two lower vertices.  If anyone knows of a quick and easy algorithm
  149.    that checks the entire hexagon, please let me know.
  150. */
  151.    POINTL ptlHex=ptlHex=HexCoord(hi);
  152.  
  153.    if (ptl.x < ptlHex.x) return FALSE;
  154.    if (ptl.x > ptlHex.x+HEX_SIDE) return FALSE;
  155.    if (ptl.y < ptlHex.y) return FALSE;
  156.    if (ptl.y > ptlHex.y+HEX_HEIGHT) return FALSE;
  157.    return TRUE;
  158. }
  159.  
  160. BOOL HexLocate(POINTL ptl, HEXINDEX *phi) {
  161. /* This function attempts to locate the hex to which 'ptl' points.  It scans
  162.    each hex on the map until it finds a match.  A future version will be more
  163.    efficient.
  164. */
  165.    HEXINDEX hi;
  166.  
  167.    for (hi.c=0;hi.c<NUM_COLUMNS;hi.c++)
  168.       for (hi.r=hi.c & 1;hi.r<NUM_ROWS-(hi.c & 1);hi.r+=2)
  169.          if (HexInPoint(ptl,hi)) {
  170.             phi->c=hi.c;
  171.             phi->r=hi.r;
  172.             return TRUE;
  173.          }
  174.    return FALSE;
  175. }
  176.  
  177. extern LONG lNumColors;
  178.  
  179. VOID APIENTRY HexHighlight(ULONG ulThreadArg) {
  180. /* This function changes the color of the origin hex during targetting.  It 
  181.    is started as a background thread and continues until target.fActive
  182.    becomes FALSE.  If there are more than 16 colors, then a routine which cycles
  183.    through 256 shades of red is chosen.  Otherwise, the hex simply blinks red.
  184.    At termination, the color is set back and the hex is redrawn.
  185.  
  186.    For the color cycling, 'i' is a byte because the "i++" statement will
  187.    automatically cycle from 0-255.
  188.  
  189.    At this writing the code for color-cycling has NOT been tested on a
  190.    monitor with 256-colors.  It has been tested on a 16-color monitor and
  191.    looks stupid.
  192. */
  193.    BYTE i;        
  194.  
  195.    if (lNumColors>16) {
  196.      GpiCreateLogColorTable(target.hpsHighlight,0,LCOLF_RGB,0,0,NULL);
  197.  
  198.      for (i=0; target.fActive; i++) {
  199.        GpiSetColor(target.hpsHighlight,(LONG) i<<16);
  200.        HexDraw(target.hpsHighlight,target.hiStart);
  201.      }
  202.      GpiCreateLogColorTable(target.hpsHighlight,LCOL_RESET,0,0,0,NULL);
  203.    } else
  204.      while (target.fActive) {
  205.        GpiSetColor(target.hpsHighlight,CLR_BLACK);
  206.        HexDraw(target.hpsHighlight,target.hiStart);
  207.        DosSleep(300L);
  208.        if (!target.fActive) break;
  209.        GpiSetColor(target.hpsHighlight,CLR_RED);
  210.        HexDraw(target.hpsHighlight,target.hiStart);
  211.        DosSleep(300L);
  212.      }
  213.  
  214.  
  215. // Redraw the starting hex before exiting
  216.    GpiSetColor(target.hpsHighlight,HEX_COLOR);
  217.    HexDraw(target.hpsHighlight,target.hiStart);
  218. }
  219.