home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / graphics / directx / duel / util.c < prev    next >
C/C++ Source or Header  |  1997-07-14  |  6KB  |  237 lines

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1995-1997 Microsoft Corporation. All Rights Reserved.
  4.  *
  5.  *  File:       util.c
  6.  *  Content:    miscellaneous functions
  7.  *
  8.  *
  9.  ***************************************************************************/
  10. #include "util.h"
  11.  
  12. /*
  13.  * Globals
  14.  */
  15. static const BYTE GuidMap[] = { 3, 2, 1, 0, '-', 5, 4, '-', 7, 6, '-',
  16.                                 8, 9, '-', 10, 11, 12, 13, 14, 15 };
  17. static const WCHAR wszDigits[] = L"0123456789ABCDEF";
  18.  
  19.  
  20. /*
  21.  * StringFromGUID
  22.  * 
  23.  * Converts a GUID into a wide string
  24.  */
  25. int StringFromGUID(LPGUID lpguid, LPWSTR lpwsz)
  26. {
  27.     int i;
  28.  
  29.     const BYTE * pBytes = (const BYTE *) lpguid;
  30.  
  31.     *lpwsz++ = L'{';
  32.  
  33.     for (i = 0; i < sizeof(GuidMap); i++)
  34.     {
  35.         if (GuidMap[i] == '-')
  36.         {
  37.             *lpwsz++ = L'-';
  38.         }
  39.         else
  40.         {
  41.             *lpwsz++ = wszDigits[ (pBytes[GuidMap[i]] & 0xF0) >> 4 ];
  42.             *lpwsz++ = wszDigits[ (pBytes[GuidMap[i]] & 0x0F) ];
  43.         }
  44.     }
  45.     *lpwsz++ = L'}';
  46.     *lpwsz   = L'\0';
  47.  
  48.     return GUIDSTR_MAX;
  49. }
  50.  
  51. /*
  52.  * IsEqualGuid
  53.  *
  54.  * Determines if two guids are equal
  55.  */
  56. BOOL  IsEqualGuid(GUID *lpguid1, GUID *lpguid2)
  57. {
  58.    return (
  59.       ((PLONG) lpguid1)[0] == ((PLONG) lpguid2)[0] &&
  60.       ((PLONG) lpguid1)[1] == ((PLONG) lpguid2)[1] &&
  61.       ((PLONG) lpguid1)[2] == ((PLONG) lpguid2)[2] &&
  62.       ((PLONG) lpguid1)[3] == ((PLONG) lpguid2)[3]);
  63. }
  64.  
  65.  
  66. // convert a hex char to an int - used by str to guid conversion
  67. // we wrote our own, since the ole one is slow, and requires ole32.dll
  68. // we use ansi strings here, since guids won't get internationalized
  69. int GetDigit(LPSTR lpstr)
  70. {
  71.     char ch = *lpstr;
  72.     
  73.     if (ch >= '0' && ch <= '9')
  74.         return(ch - '0');
  75.     if (ch >= 'a' && ch <= 'f')
  76.         return(ch - 'a' + 10);
  77.     if (ch >= 'A' && ch <= 'F')
  78.         return(ch - 'A' + 10);
  79.     return(0);
  80. }
  81. // walk the string, writing pairs of bytes into the byte stream (guid)
  82. // we need to write the bytes into the byte stream from right to left
  83. // or left to right as indicated by fRightToLeft
  84. void ConvertField(LPBYTE lpByte,LPSTR * ppStr,int iFieldSize,BOOL fRightToLeft)
  85. {
  86.     int i;
  87.  
  88.     for (i=0;i<iFieldSize ;i++ )
  89.     {
  90.         // don't barf on the field separators
  91.         if ('-' == **ppStr) (*ppStr)++; 
  92.         if (fRightToLeft == TRUE)
  93.         {
  94.             // work from right to left within the byte stream
  95.             *(lpByte + iFieldSize - (i+1)) = 16*GetDigit(*ppStr) + GetDigit((*ppStr)+1);
  96.         } 
  97.         else 
  98.         {
  99.             // work from  left to right within the byte stream
  100.             *(lpByte + i) = 16*GetDigit(*ppStr) + GetDigit((*ppStr)+1);
  101.         }
  102.         *ppStr+=2; // get next two digit pair
  103.     }
  104. } // ConvertField
  105.  
  106.  
  107. // convert the passed in string to a real GUID
  108. // walk the guid, setting each byte in the guid to the two digit hex pair in the
  109. // passed string
  110. HRESULT GUIDFromString(LPWSTR lpWStr, GUID * pGuid)
  111. {
  112.     BYTE * lpByte; // byte index into guid
  113.     int iFieldSize; // size of current field we're converting
  114.     // since its a guid, we can do a "brute force" conversion
  115.     char lpTemp[GUID_STRING_SIZE];
  116.     char *lpStr = lpTemp;
  117.  
  118.     WideToAnsi(lpStr,lpWStr,GUID_STRING_SIZE);
  119.     
  120.     // make sure we have a {xxxx-...} type guid
  121.     if ('{' !=  *lpStr) return E_FAIL;
  122.     lpStr++;
  123.     
  124.     lpByte = (BYTE *)pGuid;
  125.     // data 1
  126.     iFieldSize = sizeof(unsigned long);
  127.     ConvertField(lpByte,&lpStr,iFieldSize,TRUE);
  128.     lpByte += iFieldSize;
  129.  
  130.     // data 2
  131.     iFieldSize = sizeof(unsigned short);
  132.     ConvertField(lpByte,&lpStr,iFieldSize,TRUE);
  133.     lpByte += iFieldSize;
  134.  
  135.     // data 3
  136.     iFieldSize = sizeof(unsigned short);
  137.     ConvertField(lpByte,&lpStr,iFieldSize,TRUE);
  138.     lpByte += iFieldSize;
  139.  
  140.     // data 4
  141.     iFieldSize = 8*sizeof(unsigned char);
  142.     ConvertField(lpByte,&lpStr,iFieldSize,FALSE);
  143.     lpByte += iFieldSize;
  144.  
  145.     // make sure we ended in the right place
  146.     if ('}' != *lpStr) 
  147.     {
  148.         memset(pGuid,0,sizeof(GUID));
  149.         return E_FAIL;
  150.     }
  151.  
  152.     return S_OK;
  153. }// GUIDFromString
  154.  
  155. /*
  156.  ** WideToAnsi
  157.  *
  158.  *  CALLED BY:    everywhere
  159.  *
  160.  *  PARAMETERS: lpStr - destination string
  161.  *                lpWStr - string to convert
  162.  *                cchStr - size of dest buffer
  163.  *
  164.  *  DESCRIPTION:
  165.  *                converts unicode lpWStr to ansi lpStr.
  166.  *                fills in unconvertable chars w/ DPLAY_DEFAULT_CHAR "-"
  167.  *                
  168.  *
  169.  *  RETURNS:  if cchStr is 0, returns the size required to hold the string
  170.  *                otherwise, returns the number of chars converted
  171.  *
  172.  */
  173. int WideToAnsi(LPSTR lpStr,LPWSTR lpWStr,int cchStr)
  174. {
  175.  
  176.     int rval;
  177.     BOOL bDefault;
  178.  
  179.     // use the default code page (CP_ACP)
  180.     // -1 indicates WStr must be null terminated
  181.     rval = WideCharToMultiByte(CP_ACP,0,lpWStr,-1,lpStr,cchStr,"-",&bDefault);
  182.  
  183.     return rval;
  184.  
  185. } // WideToAnsi
  186.  
  187. /*
  188.  ** AnsiToWide
  189.  *
  190.  *  CALLED BY: everywhere
  191.  *
  192.  *  PARAMETERS: lpWStr - dest string
  193.  *                lpStr  - string to convert
  194.  *                cchWstr - size of dest buffer
  195.  *
  196.  *  DESCRIPTION: converts Ansi lpStr to Unicode lpWstr
  197.  *
  198.  *
  199.  *  RETURNS:  if cchStr is 0, returns the size required to hold the string
  200.  *                otherwise, returns the number of chars converted
  201.  *
  202.  */
  203. int AnsiToWide(LPWSTR lpWStr,LPSTR lpStr,int cchWStr)
  204. {
  205.     int rval;
  206.  
  207.     rval =  MultiByteToWideChar(CP_ACP,0,lpStr,-1,lpWStr,cchWStr);
  208.  
  209.     return rval;
  210. }  // AnsiToWide
  211.  
  212.  
  213. /* 
  214.  * randInt
  215.  *
  216.  * returns a random integer in the specified range
  217.  */
  218. int randInt( int low, int high )
  219. {
  220.     int range = high - low;
  221.     int num = rand() % range;
  222.     return( num + low );
  223. }
  224.  
  225. /*
  226.  * randDouble
  227.  *
  228.  * returns a random double in the specified range
  229.  */
  230. double randDouble( double low, double high )
  231. {
  232.     double range = high - low;
  233.     double num = range * (double)rand()/(double)RAND_MAX;
  234.     return( num + low );
  235. }
  236.  
  237.