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