home *** CD-ROM | disk | FTP | other *** search
/ PC Plus SuperCD (UK) 2000 May / PCP163A.iso / Runimage / Cbuilder4 / Examples / DDraw / DDraw1C / MAIN.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-26  |  8.8 KB  |  326 lines

  1. /*
  2.   This is a DirectDraw program. Read DirectDraw.htm before running this
  3.   program.
  4.   
  5.   This example demonstrates smooth animation of multiple objects using
  6.   DirectDraw. The program starts in normal windows mode. If you press
  7.   F3, the program switches to exclusive mode and begins drawing a series
  8.   of multicolored circles and squares to the screen. Each shape has its
  9.   own trajectory, and will bounce off the walls when it hits them. The end
  10.   result is a series of multi-colored shapes moving across the screen in
  11.   kaleidoscopic fashion.
  12.  
  13.   There are two main classes in the program:
  14.  
  15.   TDRAWSHAPE:
  16.     This class represents one of the shapes being drawn to the screen. Each
  17.     instance of the class has a location, a shape, direction, and color. Each
  18.     call to the objects Draw method will automatically move the shape further
  19.     in its trajectory. A constructor is provided that will allow you to
  20.     initialize all the key features of the object.
  21.  
  22.   TFORM1:
  23.     This object controls the flow of the program. It contains a TList object
  24.     on which each of the programs Shapes can be hung. If the user presses
  25.     F3, the program will automatically be placed in exclusive mode, and the
  26.     shapes will be draw to the screen.
  27.  
  28. */
  29.  
  30. // Includes and pragmas 
  31. #include <vcl.h>
  32. #include <ddraw.h>
  33. #pragma hdrstop
  34. #include "Main.h"
  35. #pragma resource "*.dfm"
  36.  
  37. // Global Variables
  38. TForm1 *Form1;
  39.  
  40. //------------------------------------------------------------------------------
  41. // --- TDrawShape --------------------------------------------------------------
  42. //------------------------------------------------------------------------------
  43.  
  44. ///////////////////////////////////////
  45. // Constructor
  46. ///////////////////////////////////////
  47. __fastcall TDrawShape::TDrawShape(int ValX, int ValY, int X, int Y,
  48.   int AType, TColor AColor)
  49. {
  50.   FMoveValX = ValX;
  51.   FMoveValY = ValY;
  52.   ShapeRect = Rect(X, Y, X+25, Y+25);
  53.   ShapeType = AType;
  54.   Color = AColor;
  55. }
  56.  
  57. ///////////////////////////////////////
  58. // Move
  59. ///////////////////////////////////////
  60. void TDrawShape::Move()
  61. {
  62.   FPrevRect2 = Rect(FPrevRect.left, FPrevRect.top, FPrevRect.right, FPrevRect.bottom);
  63.   FPrevRect = Rect(FX, FY, FX1, FY1);
  64.   FX += FMoveValX;
  65.   FY += FMoveValY;
  66.   FX1 += FMoveValX;
  67.   FY1 += FMoveValY;
  68.   if (FX1 > 637)
  69.     FMoveValX = -2;
  70.   if (FX < 3)
  71.     FMoveValX = 2;
  72.   if (FY1 > 477)
  73.     FMoveValY = - 2;
  74.   if (FY < 3)
  75.     FMoveValY = 2;
  76. }
  77.  
  78. ///////////////////////////////////////
  79. // Draw
  80. ///////////////////////////////////////
  81. void TDrawShape::Draw(HDC &DC)
  82. {
  83.   HBRUSH Brush, OldBrush;
  84.  
  85.   Brush = CreateSolidBrush(RGB(0, 0, 0));
  86.   OldBrush = (HBRUSH)SelectObject(DC, Brush);
  87.   if (FShapeType==CIRCLETYPE)
  88.     Ellipse(DC, FPrevRect2.left-1, FPrevRect2.top-1, FPrevRect2.right+1, FPrevRect2.bottom+1);
  89.   else if (FShapeType == RECTTYPE)
  90.     Rectangle(DC, FPrevRect2.left-1, FPrevRect2.top-1, FPrevRect2.right+1, FPrevRect2.bottom+1);
  91.   SelectObject(DC, OldBrush);
  92.   DeleteObject(Brush);
  93.  
  94.   Move();
  95.  
  96.   Brush = CreateSolidBrush(FColor);
  97.   OldBrush = (HBRUSH)SelectObject(DC, Brush);
  98.   if (FShapeType==CIRCLETYPE)
  99.     Ellipse(DC, FX, FY, FX1, FY1);
  100.   else if (FShapeType == RECTTYPE)
  101.     Rectangle(DC, FX, FY, FX1, FY1);
  102.  
  103.   SelectObject(DC, OldBrush);
  104.   DeleteObject(Brush);
  105. }
  106.  
  107. //------------------------------------------------------------------------------
  108. // --- TForm1 ------------------------------------------------------------------
  109. //------------------------------------------------------------------------------
  110.  
  111. ///////////////////////////////////////
  112. // Constructor
  113. ///////////////////////////////////////
  114. __fastcall TForm1::TForm1(TComponent* Owner)
  115.         : TForm(Owner)
  116. {
  117.   lpDD = NULL;
  118.   FPhase = 0;
  119.   FActive = False;
  120.   FShapeRect = Rect(25, 25, 50, 50);
  121.   FValueAdd = 2;
  122.   BuildList();
  123. }
  124.  
  125. ///////////////////////////////////////
  126. // BuildList
  127. ///////////////////////////////////////
  128. void TForm1::BuildList()
  129. {
  130.   FShapeList = new TList();
  131.  
  132.   FShapeList->Add(new TDrawShape(-2, 2, 175, 175, CIRCLETYPE, clLime));
  133.   FShapeList->Add(new TDrawShape(2, 2, 125, 125, RECTTYPE, clBlue));
  134.   FShapeList->Add(new TDrawShape(2, -2, 200, 200, RECTTYPE, clYellow));
  135.   FShapeList->Add(new TDrawShape(2, -2, 75, 75, CIRCLETYPE, clRed));
  136.   FShapeList->Add(new TDrawShape(-2, 2, 325, 350, RECTTYPE, clPurple));
  137.   FShapeList->Add(new TDrawShape(-2, -2, 275, 250, CIRCLETYPE, clFuchsia));
  138.   FShapeList->Add(new TDrawShape(-2, 2, 125, 325, CIRCLETYPE, clTeal));
  139.   FShapeList->Add(new TDrawShape(2, 2, 350, 175, RECTTYPE, clNavy));
  140.   FShapeList->Add(new TDrawShape(2, -2, 150, 250, CIRCLETYPE, clOlive));
  141.   FShapeList->Add(new TDrawShape(-2, 2, 225, 25, CIRCLETYPE, clSilver));
  142. }
  143.  
  144. ///////////////////////////////////////
  145. // WM_DESTROY messages
  146. ///////////////////////////////////////
  147. void __fastcall TForm1::FormDestroy(TObject *Sender)
  148. {
  149.   TDrawShape *Shape;
  150.   int i;
  151.   
  152.   for (i = 0; i < FShapeList->Count; i++)
  153.   {
  154.     Shape = (TDrawShape*)FShapeList->Items[i];
  155.     delete Shape;
  156.   }
  157.   delete FShapeList;
  158.   
  159.   if(lpDD != NULL)
  160.   {
  161.     if(lpDDSPrimary != NULL)
  162.     {
  163.       lpDDSPrimary->Release();
  164.       lpDDSPrimary = NULL;
  165.     }
  166.     lpDD->Release();
  167.     lpDD = NULL;
  168.   }
  169. }
  170.  
  171. ///////////////////////////////////////
  172. // Initialize DirectDraw
  173. ///////////////////////////////////////
  174. void __fastcall TForm1::Start()
  175. {
  176.   HRESULT ddrval;
  177.   DDSURFACEDESC ddsd;
  178.   DDSCAPS ddscaps;
  179.   char buf[256];
  180.  
  181.   ddrval = DirectDrawCreate(NULL, &lpDD, NULL);
  182.   if(ddrval == DD_OK)
  183.   {
  184.     // Get exclusive mode
  185.     ddrval = lpDD->SetCooperativeLevel(Handle,
  186.       DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
  187.     if(ddrval == DD_OK)
  188.     {
  189.       ddrval = lpDD->SetDisplayMode(640, 480, 8);
  190.       if(ddrval == DD_OK)
  191.       {
  192.         // Create the primary surface with 1 back buffer
  193.         ddsd.dwSize = sizeof(ddsd);
  194.         ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
  195.         ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
  196.                               DDSCAPS_FLIP |
  197.                               DDSCAPS_COMPLEX;
  198.         ddsd.dwBackBufferCount = 1;
  199.         ddrval = lpDD->CreateSurface(&ddsd, &lpDDSPrimary, NULL);
  200.         if(ddrval == DD_OK)
  201.         {
  202.           // Get a pointer to the back buffer
  203.           ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
  204.           ddrval = lpDDSPrimary->GetAttachedSurface(&ddscaps,
  205.                                                 &lpDDSBack);
  206.           if(ddrval == DD_OK)
  207.           {
  208.             PostMessage(Handle, WM_RUNAPP, 0, 0);
  209.             return;
  210.           }
  211.         }
  212.       }
  213.     }
  214.   }
  215.   wsprintf(buf, "Direct Draw Init Failed (%08lx)\n", ddrval);
  216.   MessageBox(Handle, buf, "ERROR", MB_OK);
  217.   Close();
  218. }
  219.  
  220. ///////////////////////////////////////
  221. // WM_KEYDOWN messages
  222. ///////////////////////////////////////
  223. void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
  224.         TShiftState Shift)
  225. {
  226.  
  227.    switch (Key)
  228.    {
  229.      case VK_F3:
  230.        FActive = True;
  231.        Start();
  232.        break;
  233.  
  234.      case VK_ESCAPE:
  235.      case VK_F12:
  236.        FActive = False;
  237.        Close();
  238.        break;
  239.    }
  240. }
  241.  
  242. ///////////////////////////////////////
  243. // WM_PAINT messages
  244. ///////////////////////////////////////
  245. void __fastcall TForm1::FormPaint(TObject *Sender)
  246. {
  247.   RECT rc;
  248.   SIZE size;
  249.   char szMsg[] = "Page Flipping Test: Press F3 to start, F12 or Esc to exit";
  250.   
  251.   if (!FActive)
  252.   {
  253.     HDC DC = GetDC(Handle);
  254.     rc = GetClientRect();
  255.     GetTextExtentPoint(DC, szMsg, lstrlen(szMsg), &size);
  256.     SetBkColor(DC, RGB(0, 0, 0));
  257.     SetTextColor(DC, RGB(255, 255, 0));
  258.     TextOut(DC, (rc.right - size.cx)/2, (rc.bottom - size.cy)/2,
  259.       szMsg, sizeof(szMsg)-1);
  260.     ReleaseDC(Handle, DC);
  261.   }
  262. }
  263.  
  264. ///////////////////////////////////////
  265. // Run the program
  266. ///////////////////////////////////////
  267. void TForm1::Run(TMessage &Message)
  268. {
  269.   do
  270.   {
  271.     PerformAction();
  272.     Application->ProcessMessages();
  273.   }
  274.   while (FActive);
  275. }
  276.  
  277. ///////////////////////////////////////
  278. // PerformAction
  279. ///////////////////////////////////////
  280. void TForm1::PerformAction()
  281. {
  282.   HDC DC;
  283.  
  284.   // Don't step through code that has lock on it!
  285.   // Getting a DC may put a lock on video memory.
  286.   if (lpDDSBack->GetDC(&DC) == DD_OK)
  287.   {
  288.     DrawShape(DC);
  289.     lpDDSBack->ReleaseDC(DC);
  290.   }
  291.  
  292.   while(1)
  293.   {
  294.     HRESULT ddrval;
  295.     ddrval = lpDDSPrimary->Flip(NULL, 0);
  296.  
  297.     if(ddrval == DD_OK)
  298.       break;
  299.  
  300.     if(ddrval == DDERR_SURFACELOST)
  301.     {
  302.       ddrval = lpDDSPrimary->Restore();
  303.       if(ddrval != DD_OK)
  304.         break;
  305.     }
  306.  
  307.     if(ddrval != DDERR_WASSTILLDRAWING)
  308.     {
  309.       FActive = False;
  310.       Close();
  311.     }
  312.   }
  313. }
  314.  
  315. void TForm1::DrawShape(HDC &DC)
  316. {
  317.   TDrawShape *Shape;
  318.   int i;
  319.  
  320.   for (i = 0; i < FShapeList->Count; i++)
  321.   {
  322.     Shape = (TDrawShape*)FShapeList->Items[i];
  323.     Shape->Draw(DC);
  324.   }
  325. }
  326.