home *** CD-ROM | disk | FTP | other *** search
/ Cutting-Edge 3D Game Programming with C++ / CE3DC++.ISO / BOOK / CHAP10 / PERSP / TEXTED.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-19  |  9.6 KB  |  362 lines

  1. //
  2. // File name: TextEd.CPP
  3. //
  4. // Description: The main file for a simple texture editor
  5. //
  6. // Author: John De Goes
  7. //
  8. // Project: Cutting Edge 3D Game Programming
  9. //
  10.  
  11. // ------------------------------------------------------------
  12. // | Global include files:                                    |
  13. // ------------------------------------------------------------
  14.  
  15. #include <Dos.H>
  16. #include <Math.H>
  17. #include <Conio.H>
  18. #include <Time.H>
  19. #include <Stdio.H>
  20. #include <Windows.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 "TextType.HPP"
  31. #include "3Dclass.HPP"
  32. #include "LineType.HPP"
  33.  
  34. // ------------------------------------------------------------
  35. // | Global variables/constants:                              |
  36. // ------------------------------------------------------------
  37.  
  38. // Create an image of a cross for the mouse:
  39. unsigned char Cursor [ ] = {
  40.                      0, 0, 0, 0, 0,10,10, 0, 0, 0, 0, 0,
  41.                      0, 0, 0, 0, 0,10,10, 0, 0, 0, 0, 0,
  42.                      0, 0, 0, 0, 0,10,10, 0, 0, 0, 0, 0,
  43.                      0, 0, 0, 0, 0,10,10, 0, 0, 0, 0, 0,
  44.                      0, 0, 0, 0, 0,10,10, 0, 0, 0, 0, 0,
  45.                      10,10,10,10,10,11,11,10,10,10,10,10,
  46.                      10,10,10,10,10,11,11,10,10,10,10,10,
  47.                      0, 0, 0, 0, 0,10,10, 0, 0, 0, 0, 0,
  48.                      0, 0, 0, 0, 0,10,10, 0, 0, 0, 0, 0,
  49.                      0, 0, 0, 0, 0,10,10, 0, 0, 0, 0, 0,
  50.                      0, 0, 0, 0, 0,10,10, 0, 0, 0, 0, 0,
  51.                      0, 0, 0, 0, 0,10,10, 0, 0, 0, 0, 0,
  52.                      };
  53.  
  54. // ------------------------------------------------------------
  55. // | Local structs/classes:                                   |
  56. // ------------------------------------------------------------
  57.  
  58. struct View {
  59. int XRot, YRot, ZRot;
  60. double ZPos;
  61. View () { XRot = YRot = ZRot = 0; ZPos = 0.0F; }
  62. void Clear () { XRot = YRot = ZRot = 0; ZPos = 0.0F; }
  63. };
  64.  
  65. // ------------------------------------------------------------
  66. // | Function section:                                        |
  67. // ------------------------------------------------------------
  68.  
  69. int InitZBuffer ()
  70.   {
  71.   // Allocate memory for Z-buffer:
  72.   if ( ( ZBuffer = new long [ 64000 ] ) == 0 )
  73.      return 0;
  74.   return 1;
  75.   }
  76.  
  77. int DestZBuffer ()
  78.   {
  79.   // Deallocate Z-buffer's memory:
  80.   delete [] ZBuffer;
  81.   if ( ZBuffer )
  82.      return 0;
  83.   return 1;
  84.   }
  85.  
  86. void ClearBuffer ()
  87.    {
  88.    // Clear the Z-buffer:
  89.    long *ZPtr = ZBuffer;
  90.    for ( unsigned int Index = 0; Index < 6400; Index++ )
  91.        {
  92.        *ZPtr++ = 0;
  93.        *ZPtr++ = 0;
  94.  
  95.        *ZPtr++ = 0;
  96.        *ZPtr++ = 0;
  97.  
  98.        *ZPtr++ = 0;
  99.        *ZPtr++ = 0;
  100.  
  101.        *ZPtr++ = 0;
  102.        *ZPtr++ = 0;
  103.  
  104.        *ZPtr++ = 0;
  105.        *ZPtr++ = 0;
  106.        }
  107.    }
  108.  
  109. // Create a virtual track-ball:
  110. void UpdatePos ( PanelObject *World, MousePtr &Mouse, View &V )
  111.    {
  112.    int X, Y;
  113.    static int Px = 0, Py = 0, Pressed = 0, Lx, Ly;
  114.  
  115.    // Get the mouse coordinates and map them to a suitable
  116.    // range:
  117.    X = ( Mouse.GetX () - 50 ) >> 2;
  118.    Y = ( Mouse.GetY () - 50 ) >> 2;
  119.  
  120.    // If the left button is pressed:
  121.    if ( ( Mouse.GetLb () ) && ( !Mouse.GetRb () ) )
  122.       {
  123.       // Do the translations and rotations:
  124.       V.ZPos -= ( double ) Y * 3.0F;
  125.       V.YRot += X;
  126.       Pressed = 0;
  127.       }
  128.  
  129.    // Else if the right button is pressed:   
  130.    else if ( ( Mouse.GetRb () ) && ( ! Mouse.GetLb () ) )
  131.            {
  132.            V.XRot += Y;
  133.            //V.ZRot -= X;
  134.            Pressed = 0;
  135.            }
  136.  
  137.    // Else if both buttons are pressed:
  138.    else if ( Mouse.GetRb () && Mouse.GetLb () )
  139.            {
  140.            if ( Pressed == 0 )
  141.               {
  142.               Pressed = 1;
  143.               // Record the actual screen coordinates of the 
  144.               // mouse pointer:
  145.               Px = Mouse.GetSx ();
  146.               Py = Mouse.GetSy ();
  147.  
  148.               Lx = Mouse.GetSx ();
  149.               Ly = Mouse.GetSy ();
  150.               }
  151.            else {
  152.                 World->MoveText ( Px, Py, 
  153.                                   ( Lx - Mouse.GetSx () ) >> 2, 
  154.                                   ( Ly - Mouse.GetSy () ) >> 2 );
  155.                 Lx = Mouse.GetSx ();
  156.                 Ly = Mouse.GetSy ();
  157.                 }
  158.            }
  159.  
  160.    // Else no buttons are pressed:
  161.    else Pressed = 0;
  162.    }
  163.  
  164. void HandleKey ( PanelObject *World, long Key )
  165.    {
  166.    switch ( Key )
  167.           {
  168.           case ('\t'):
  169.                {
  170.                World->SelNext ();
  171.                break;
  172.                }
  173.           case ('t'):
  174.           case ('T'):
  175.                {
  176.                World->NexText ();
  177.                break;
  178.                }
  179.           case ('r'):
  180.           case ('R'):
  181.                {
  182.                World->RotText ();
  183.                break;
  184.                }
  185.           default: break;
  186.           }
  187.    }
  188.  
  189. double RunWorld ( unsigned char *VidMem, unsigned char *VidBuf,
  190.                   PanelObject *World )
  191.    {
  192.    // Enter the main loop, updating view as necessary:
  193.  
  194.    VidMem; VidBuf; World;
  195.    MousePtr Mouse;
  196.    Matrix3D M; View V;
  197.    long QuitFlag = 0, StartTime, EndTime, FrameCount = 0, 
  198.         MaxWait, Input, BackC;
  199.    double FramesPerSecond;
  200.    ZTrans = 0;
  201.  
  202.    // Initialize the mouse driver:
  203.    Mouse.Init ();
  204.  
  205.    // Hide the pointer:   
  206.    Mouse.Hide ();
  207.  
  208.    // Re-map the cursor's coordinates:
  209.    Mouse.MappingRange ( 100, 100 );
  210.  
  211.    // Clip the cursor to a rectangular region:
  212.    Mouse.Clip ( 5, 5, 95, 95 );
  213.  
  214.    // Give the cursor a face-lift:
  215.    Mouse.ChangeCursor ( Cursor, 12, 12 );
  216.  
  217.    // Allocate memory for Z-buffer:
  218.    InitZBuffer ();
  219.  
  220.    // Raise the viewer:
  221.    M.Initialize ();
  222.    M.Translate ( 0, -500, 0 );
  223.    ClearBuffer ();
  224.    World->Display ( M, VidBuf );
  225.    MaxWait = ( long ) pow ( 2, 31 - ZSTEP_PREC  );
  226.  
  227.    // Record the time:
  228.    StartTime = clock ();
  229.  
  230.    BackC = 0;
  231.  
  232.    // Loop until ESC pressed:
  233.    while ( !QuitFlag )
  234.          {
  235.          UpdatePos ( World, Mouse, V );
  236.  
  237.          M.Translate ( 0, 0, -V.ZPos );
  238.          M.Rotate ( -V.XRot, -V.YRot, -V.ZRot );
  239.          V.Clear ();
  240.  
  241.          setmem ( VidBuf, 64000, BackC );
  242.  
  243.          // Clear the Z-buffer (if necessary):
  244.          ZTrans += ( 1 << ZSTEP_PREC );
  245.          if ( ( FrameCount % MaxWait ) == 0 )
  246.             {
  247.             ZTrans = 0;
  248.             ClearBuffer ();
  249.             }
  250.  
  251.          World->Display ( M, VidBuf );
  252.          Mouse.Display ( VidBuf );
  253.  
  254.          memmove ( VidMem, VidBuf, 64000 );
  255.          if ( kbhit () )
  256.             {
  257.             Input = getch ();
  258.             if ( Input == 27 )
  259.                QuitFlag = 1;
  260.             else HandleKey ( World, Input );
  261.             }
  262.          ++FrameCount;
  263.          }
  264.    EndTime = clock ();
  265.  
  266.    DestZBuffer ();
  267.  
  268.    // Calculate the frames per second:
  269.    FramesPerSecond = ( double ) FrameCount * 
  270.                      ( double )  CLK_TCK /
  271.                      ( double ) ( EndTime - StartTime ); 
  272.    return FramesPerSecond;
  273.    }
  274.  
  275. void SetPalette ( RGBQUAD *Palette )
  276.    {
  277.    short Index, Red, Green, Blue;
  278.    for ( Index = 0; Index < 256; Index++ )
  279.        {
  280.        Red    = ( short ) ( Palette [ Index ].rgbRed   >> 2 );
  281.        Green  = ( short ) ( Palette [ Index ].rgbGreen >> 2 );
  282.        Blue   = ( short ) ( Palette [ Index ].rgbBlue  >> 2 );
  283.        setpalreg ( Index, Green, Blue, Red );
  284.        }
  285.    }
  286.  
  287.  
  288. // ------------------------------------------------------------
  289. // | Program entry:                                           |
  290. // ------------------------------------------------------------
  291.  
  292. void main ( int ArgCount, char *Arg[] )
  293.    {
  294.    // Declare/initialize variables and allocate memory:
  295.    unsigned char *VidMem, *VidBuf;
  296.    VidMem = VideoAddress ();
  297.    double FramesPerSecond;
  298.  
  299.    // Allocate buffer memory - abort if error:
  300.    if ( ( VidBuf = new unsigned char [ 64000 ] ) == NULL )
  301.       return;
  302.  
  303.    // Allocate memory for a panel object:
  304.    PanelObject *World = new PanelObject;
  305.  
  306.    if ( ( ArgCount > 1 ) && 
  307.         ( !strcmp ( strupr ( Arg [ 1 ] ), "WRITEBINARY" ) ) )
  308.       {
  309.       World->LoadDXF ( "Test.DXF" );
  310.       World->WriteBIN ( "Test.BIN" );
  311.       }
  312.  
  313.    else {
  314.         // Read the panel data:
  315.         World->ReadBIN ( "Test.BIN" );
  316.  
  317.         // Read -- if possible -- the texture data:
  318.         if ( World->ReadText ( "Text.BT" ) == 0 )
  319.            {
  320.            if ( TextDat.LoadINI ( "Text.INI" ) == 0 )
  321.               {
  322.               cout << "\nError loading Text.INI\n";
  323.               delete [] VidBuf;
  324.               delete World;
  325.               return;
  326.               }
  327.            // Initialize default texture coords:
  328.            World->InitDefText ();
  329.            }
  330.  
  331.         // Set video mode:
  332.         SetVideo ( 0x13 );
  333.  
  334.         // Set the palette:
  335.         SetPalette ( TextDat.TMap [ 0 ].Palette );
  336.  
  337.         // Enter main loop:
  338.         FramesPerSecond = RunWorld ( VidMem, VidBuf, World );
  339.  
  340.         // Set video mode:
  341.         SetVideo ( 0x03 );
  342.  
  343.         // Display FPS:
  344.         cout << "\nFrames per second: " << FramesPerSecond;
  345.  
  346.         // Save the texture data:
  347.         World->WriteText ( "Text.BT" );
  348.         }
  349.  
  350.    // Deallocate memory for buffer:
  351.    cout << "\nDeallocating memory...";
  352.    delete [] VidBuf;
  353.       
  354.    // Deallocate memory for panel object:
  355.    delete World;
  356.  
  357.    cout << "\nReturning control to OS...";
  358.  
  359.    // Exit program:
  360.    return;
  361.    }
  362.