home *** CD-ROM | disk | FTP | other *** search
/ Cutting-Edge 3D Game Programming with C++ / CE3DC++.ISO / BOOK / CHAP09 / VWALK2.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-17  |  7.3 KB  |  279 lines

  1. //
  2. // File name: Vwalk2.CPP
  3. //
  4. // Description: The main file for a virtual walk-through using 
  5. //              Gouraud shaded polygons
  6. //
  7. // Author: John De Goes
  8. //
  9. // Project: Cutting Edge 3D Game Programming
  10. //
  11.  
  12. // ------------------------------------------------------------
  13. // | Global include files:                                    |
  14. // ------------------------------------------------------------
  15.  
  16. #include <Dos.H>
  17. #include <Math.H>
  18. #include <Conio.H>
  19. #include <Time.H>
  20. #include <Stdio.H>
  21. #include <Iostream.H>
  22.  
  23. // ------------------------------------------------------------
  24. // | Local include files:                                     |
  25. // ------------------------------------------------------------
  26.  
  27. #include "32Bit.HPP"
  28. #include "MouseLib.HPP"
  29. #include "Palette.HPP"
  30. #include "3Dclass.HPP"
  31. #include "LineType.HPP"
  32.  
  33. // ------------------------------------------------------------
  34. // | Global variables/constants:                              |
  35. // ------------------------------------------------------------
  36.  
  37. // Create an image of a cross for the mouse:
  38. unsigned char Cursor [ ] = {
  39.                      0, 0, 0, 0, 0,17,17, 0, 0, 0, 0, 0,
  40.                      0, 0, 0, 0, 0,18,18, 0, 0, 0, 0, 0,
  41.                      0, 0, 0, 0, 0,19,19, 0, 0, 0, 0, 0,
  42.                      0, 0, 0, 0, 0,20,20, 0, 0, 0, 0, 0,
  43.                      0, 0, 0, 0, 0,21,21, 0, 0, 0, 0, 0,
  44.                      17,18,19,20,21,22,22,21,20,19,18,17,
  45.                      17,18,19,20,21,22,22,21,20,19,18,17,
  46.                      0, 0, 0, 0, 0,21,21, 0, 0, 0, 0, 0,
  47.                      0, 0, 0, 0, 0,20,20, 0, 0, 0, 0, 0,
  48.                      0, 0, 0, 0, 0,19,19, 0, 0, 0, 0, 0,
  49.                      0, 0, 0, 0, 0,18,18, 0, 0, 0, 0, 0,
  50.                      0, 0, 0, 0, 0,17,17, 0, 0, 0, 0, 0,
  51.                      };
  52.  
  53. // ------------------------------------------------------------
  54. // | Local structs/classes:                                   |
  55. // ------------------------------------------------------------
  56.  
  57. struct View {
  58. int XRot, YRot, ZRot;
  59. double ZPos;
  60. View () { XRot = YRot = ZRot = 0; ZPos = 0.0F; }
  61. void Clear () { XRot = YRot = ZRot = 0; ZPos = 0.0F; }
  62. };
  63.  
  64. // ------------------------------------------------------------
  65. // | Function section:                                        |
  66. // ------------------------------------------------------------
  67.  
  68. int InitZBuffer ()
  69.   {
  70.   // Allocate memory for Z-buffer:
  71.   if ( ( ZBuffer = new long [ 64000 ] ) == 0 )
  72.      return 0;
  73.   return 1;
  74.   }
  75.  
  76. int DestZBuffer ()
  77.   {
  78.   // Deallocate Z-buffer's memory:
  79.   delete [] ZBuffer;
  80.   if ( ZBuffer )
  81.      return 0;
  82.   return 1;
  83.   }
  84.  
  85. void ClearBuffer ()
  86.    {
  87.    // Clear the Z-buffer:
  88.    long *ZPtr = ZBuffer;
  89.    for ( unsigned int Index = 0; Index < 6400; Index++ )
  90.        {
  91.        *ZPtr++ = 0;
  92.        *ZPtr++ = 0;
  93.  
  94.        *ZPtr++ = 0;
  95.        *ZPtr++ = 0;
  96.  
  97.        *ZPtr++ = 0;
  98.        *ZPtr++ = 0;
  99.  
  100.        *ZPtr++ = 0;
  101.        *ZPtr++ = 0;
  102.  
  103.        *ZPtr++ = 0;
  104.        *ZPtr++ = 0;
  105.        }
  106.    }
  107.  
  108. // Create a virtual track-ball:
  109. void UpdatePos ( MousePtr &Mouse, View &V )
  110.    {
  111.    // Get the mouse coordinates and map them to a suitable
  112.    // range:
  113.    int X = ( Mouse.GetX () - 50 ) >> 2;
  114.    int Y = ( Mouse.GetY () - 50 ) >> 2;
  115.  
  116.    // If the left button is pressed:
  117.    if ( ( Mouse.GetLb () ) && ( !Mouse.GetRb () ) )
  118.       {
  119.       // Do the translations and rotations:
  120.       V.ZPos -= ( double ) Y * 3.0F;
  121.       V.YRot += X;
  122.       }
  123.  
  124.    // Else if the right button is pressed:   
  125.    else if ( ( Mouse.GetRb () ) && ( ! Mouse.GetLb () ) )
  126.            {
  127.            V.XRot += Y;
  128.            V.ZRot -= X;
  129.            }
  130.    }
  131.  
  132. double RunWorld ( unsigned char *VidMem, unsigned char *VidBuf,
  133.                   PanelObject *World )
  134.    {
  135.    // Enter the main loop, updating view as necessary:
  136.  
  137.    VidMem; VidBuf; World;
  138.    MousePtr Mouse;
  139.    Matrix3D M; View V;
  140.    long QuitFlag = 0, StartTime, EndTime, FrameCount = 0, MaxWait;
  141.    double FramesPerSecond;
  142.    ZTrans = 0;
  143.  
  144.    // Initialize the mouse driver:
  145.    Mouse.Init ();
  146.  
  147.    // Hide the pointer:   
  148.    Mouse.Hide ();
  149.  
  150.    // Re-map the cursor's coordinates:
  151.    Mouse.MappingRange ( 100, 100 );
  152.  
  153.    // Clip the cursor to a rectangular region:
  154.    Mouse.Clip ( 5, 5, 95, 95 );
  155.  
  156.    // Give the cursor a face-lift:
  157.    Mouse.ChangeCursor ( Cursor, 12, 12 );
  158.  
  159.    // Allocate memory for Z-buffer:
  160.    InitZBuffer ();
  161.  
  162.    // Raise the viewer:
  163.    M.Initialize ();
  164.    M.Translate ( 0, -600, 0 );
  165.    ClearBuffer ();
  166.    World->Display ( M, VidBuf );
  167.    MaxWait = ( long ) pow ( 2, 31 - ZSTEP_PREC  );
  168.  
  169.    StartTime = clock ();
  170.  
  171.    // Loop until ESC pressed:
  172.    while ( !QuitFlag )
  173.          {
  174.          UpdatePos ( Mouse, V );
  175.  
  176.          M.Translate ( 0, 0, -V.ZPos );
  177.          M.Rotate ( -V.XRot, -V.YRot, -V.ZRot );
  178.          V.Clear ();
  179.  
  180.          setmem ( VidBuf, 64000, 1 );
  181.  
  182.          // Clear the Z-buffer (if necessary):
  183.          ZTrans += ( 1 << ZSTEP_PREC );
  184.          if ( ( FrameCount % MaxWait ) == 0 )
  185.             {
  186.             ZTrans = 0;
  187.             ClearBuffer ();
  188.             }
  189.  
  190.          World->Display ( M, VidBuf );
  191.          Mouse.Display ( VidBuf );
  192.  
  193.          memmove ( VidMem, VidBuf, 64000 );
  194.          if ( kbhit () )
  195.             {
  196.             if ( getch () == 27 )
  197.                QuitFlag = 1;
  198.             }
  199.          ++FrameCount;
  200.          }
  201.    EndTime = clock ();
  202.  
  203.    DestZBuffer ();
  204.  
  205.    // Calculate the frames per second:
  206.    FramesPerSecond = ( double ) FrameCount * 
  207.                      ( double )  CLK_TCK /
  208.                      ( double ) ( EndTime - StartTime ); 
  209.    return FramesPerSecond;
  210.    }
  211.  
  212.  
  213. void SetPalette ()
  214.    {
  215.    
  216.    short int Scale;
  217.    for ( short int N = 0; N < 256; N++ )
  218.        {
  219.        Scale = N >> 2;
  220.        SetPalReg ( N, Scale, Scale, Scale );
  221.        }
  222.    }
  223.  
  224. // ------------------------------------------------------------
  225. // | Program entry:                                           |
  226. // ------------------------------------------------------------
  227.  
  228. void main ( int ArgCount, char *Arg[] )
  229.    {
  230.    // Declare/initialize variables and allocate memory:
  231.    unsigned char *VidMem, *VidBuf;
  232.    VidMem = VideoAddress ();
  233.    double FramesPerSecond;
  234.  
  235.    // Allocate buffer memory - abort if error:
  236.    if ( ( VidBuf = new unsigned char [ 64000 ] ) == NULL )
  237.       return;
  238.  
  239.    // Allocate memory for a panel object:
  240.    PanelObject *World = new PanelObject;
  241.  
  242.    if ( ( ArgCount > 1 ) && 
  243.         ( !strcmp ( strupr ( Arg [ 1 ] ), "WRITEBINARY" ) ) )
  244.       {
  245.       World->LoadDXF ( "Test.DXF" );
  246.       World->WriteBIN ( "Test.BIN" );
  247.       }
  248.  
  249.    else {
  250.         World->ReadBIN ( "Test.BIN" );
  251.  
  252.         // Set video mode:
  253.         SetVideo ( 0x13 );
  254.  
  255.         // Set the palette to shades of gray:
  256.         SetPalette ();
  257.  
  258.         // Enter main loop:
  259.         FramesPerSecond = RunWorld ( VidMem, VidBuf, World );
  260.  
  261.         // Set video mode:
  262.         SetVideo ( 0x03 );
  263.  
  264.         // Display FPS:
  265.         cout << "\nFrames per second: " << FramesPerSecond;
  266.         }
  267.  
  268.    // Deallocate memory/prepare to shut down:
  269.    cout << "\nDeallocating memory...";
  270.    delete [] VidBuf;
  271.       
  272.    // Deallocate memory for panel object:
  273.    delete World;
  274.  
  275.    cout << "\nReturning control to OS...";
  276.  
  277.    // Exit program:
  278.    return;
  279.    }