home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible / OpenGL_Superbible_Waite_Group_Press_1996.iso / book / chapt10 / tank / microsoft / radarwnd.c < prev    next >
C/C++ Source or Header  |  1996-07-05  |  5KB  |  169 lines

  1. // RadarWnd.c
  2. // This file contains the window procedure and code related to the
  3. // radar window. The radar indicates the relative position of the
  4. // tank or robot.
  5.  
  6. #include <windows.h>    // Normal Windows stuff
  7. #include <math.h>        // sine and cosine functions
  8. #include <gl\gl.h>
  9. #include <gl\glu.h>
  10. #include "glutils.h"    
  11. #include "externs.h"    // Data shared between files
  12.  
  13. // Local functions
  14. void DrawBlip(HDC hDC, int nCenterX, int nCenterY);
  15.  
  16. static int nRadarRadius[4] = { 70, 50, 30, 10 };
  17.  
  18.  
  19. ////////////////////////////////////////////////////////////
  20. ////////////////////////////////////////////////////////////
  21. // Window procedure, handles all messages for this window
  22. LRESULT CALLBACK WndProcRadar(HWND    hWnd,
  23.                             UINT    message,
  24.                             WPARAM  wParam,
  25.                             LPARAM  lParam)
  26.     {
  27.     switch (message)
  28.         {
  29.         // Variables that need persistent storage
  30.         static double dSweepAngle = 0.0f;
  31.         static HPEN hPen = NULL;
  32.         static HBRUSH hBrush = NULL;
  33.  
  34.         // Window creation, setup here
  35.         case WM_CREATE:
  36.             // Create a bright green drawing pen, and a darker green
  37.             // for the background of the radar
  38.             hPen = CreatePen(PS_SOLID,2,RGB(0,255,0));
  39.             hBrush = CreateSolidBrush(RGB(0,128,0));
  40.  
  41.             // Set a timer, this timer moves the radar arm around in circles.
  42.             SetTimer(hWnd,101,125,NULL);
  43.  
  44.             break;
  45.  
  46.         // Window is being destroyed, cleanup
  47.         case WM_DESTROY:
  48.             // First get rid of the timer
  49.             KillTimer(hWnd, 101);
  50.  
  51.             // Delete the window objects we created (pen and brush)
  52.             DeleteObject(hPen);
  53.             DeleteObject(hBrush);
  54.             break;
  55.  
  56.  
  57.         // Draw the radar screen, if the tank/robot is in proximity, 
  58.         // put a blip in the appropriate position.
  59.         case WM_PAINT:
  60.             {
  61.             PAINTSTRUCT ps;
  62.             RECT    rect;            // Dimensions of the window
  63.             int nCenterX,nCenterY;    // Coordinates of center of radar    
  64.             int i;                    // Loop index
  65.             HPEN hOldPen;            // Holder for deselected pen
  66.             HBRUSH hOldBrush;        // Holder for deselected brush
  67.  
  68.             // Get the dimensions of the window and calculate center
  69.             GetClientRect(hWnd, &rect);
  70.             nCenterX = rect.right/2;
  71.             nCenterY = rect.bottom/2;
  72.  
  73.             // Start drawing
  74.             BeginPaint(hWnd,&ps);
  75.             
  76.             // Use our new pen and brush
  77.             hOldPen = SelectObject(ps.hdc,hPen);
  78.             hOldBrush = SelectObject(ps.hdc,hBrush);
  79.  
  80.             // Rings of Radar Screen
  81.             for(i = 0; i < 4; i++)
  82.                 Ellipse(ps.hdc,
  83.                     nCenterX-nRadarRadius[i],    // nLeftRect
  84.                     nCenterY+nRadarRadius[i],    // nTopRect
  85.                     nCenterX+nRadarRadius[i],    // nRightRect
  86.                     nCenterY-nRadarRadius[i]);    // nBottomRect
  87.  
  88.             // Draw Sweeper
  89.             MoveToEx(ps.hdc,nCenterX,nCenterY,NULL);
  90.             LineTo(ps.hdc,nCenterX+(int)((double)nRadarRadius[0]*sin(dSweepAngle)),
  91.                           nCenterY+(int)((double)nRadarRadius[0]*cos(dSweepAngle)));
  92.  
  93.  
  94.             DrawBlip(ps.hdc, nCenterX, nCenterY);
  95.  
  96.             // Deselect the pen and brush
  97.             SelectObject(ps.hdc,hOldPen);
  98.             SelectObject(ps.hdc,hOldBrush);
  99.     
  100.             // Done painting
  101.             EndPaint(hWnd, &ps);
  102.  
  103.             // Advance Sweeper for next timer pulse
  104.             dSweepAngle -= PI/90.0f;
  105.             if(dSweepAngle < 0.0f)
  106.                 dSweepAngle = 2.0f*PI;
  107.             }
  108.             break;
  109.  
  110.         // Just invalidate. WM_PAINT does all the work
  111.         case WM_TIMER:
  112.             InvalidateRect(hWnd,NULL,FALSE);
  113.             break;
  114.  
  115.         default:   // Passes it on if unproccessed
  116.             return (DefWindowProc(hWnd, message, wParam, lParam));
  117.  
  118.         }
  119.  
  120.     return (0L);
  121.     }
  122.  
  123.  
  124. ///////////////////////////////////////////////////////////////////////////
  125. // Draw a blip on the radar screen if we are within 700 units of the other object
  126. // The 700 comes from the radar outer radius and can be changed by changing it.
  127. void DrawBlip(HDC hDC, int nCenterX, int nCenterY)
  128.     {
  129.     double dDistance;
  130.     struct _POSITION *pOtherObject;
  131.     double xDelta, zDelta;
  132.     double dAngle;
  133.         
  134.     // Who are WE and who is the "other" object
  135.     if(bTank)                        
  136.         pOtherObject = &robotPos;    // We are the tank
  137.     else
  138.         pOtherObject = &tankPos;    // We are the robot
  139.  
  140.     // Calculate change in x and z coordinates to get to the other object
  141.     xDelta = pOtherObject->xPos - pObject->xPos;
  142.     zDelta = pOtherObject->zPos - pObject->zPos;
  143.     
  144.     // Calculate the distance
  145.     dDistance = sqrt((xDelta*xDelta) + (zDelta*zDelta))/10.0;
  146.  
  147.     // Is it in range?
  148.     if(dDistance > (nRadarRadius[0]-6))    // Bring in a little to keep off edge
  149.         return;
  150.  
  151.     // Adjust position by rotating the coordinates.
  152.     dAngle = atan2(zDelta,xDelta);    // This is the angle from direct east
  153.  
  154.     // Offset by rotation
  155.     dAngle += pObject->radsFromEast-(PI/2.0);
  156.         
  157.     nCenterX += (int)(cos(dAngle)*dDistance);
  158.     nCenterY += (int)(sin(dAngle)*dDistance);
  159.  
  160.     // Setup text parameters and draw an asterisk '*'
  161.     SetBkMode(hDC,TRANSPARENT);
  162.     SetTextColor(hDC,RGB(255,255,255));
  163.     // Try to adjust center of * to match desired coordinate
  164.     TextOut(hDC,nCenterX-3, nCenterY-3, "*",1);
  165.     }
  166.  
  167.  
  168.  
  169.