
// gfxddraw.cpp
//
// Copyright (c) 1995 by Toshiaki Tsuji, all rights reserved.

#include "stdgfx.h"
#include "gfxddraw.h"
#include "lgfxdib.h"

DDRAWDRIVER::DDRAWDRIVER ()
  {
    #if defined (__FORGDK__)
      lpDirectDraw = NULL;
      lpPrimarySurface = NULL;
      lpSecondarySurface = NULL;
			lpDirectDrawPalette = NULL;
      hMainWindow = NULL;
    #endif  
  } // End of Constructor for DDRAWDRIVER

DDRAWDRIVER::~DDRAWDRIVER ()
  {
    Reset ();  
  } // End of Destructor for DDRAWDRIVER

BOOLEAN DDRAWDRIVER::SetUp ( DISPLAYDATA *Data )
  {
     if (Data)
       {} 
     #if defined (__FORGDK__)
       HRESULT Result;
       
       Result = DirectDrawCreate ( NULL, &lpDirectDraw, NULL );
       if (Result!=DD_OK)
         return FAILURE;
       Result = lpDirectDraw->SetCooperativeLevel ( Data->hMainWindow,
                                                    DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
       if (Result!=DD_OK)
         {
           Reset ();  
           return FAILURE;                                              
         } // End if

       Result = lpDirectDraw->SetDisplayMode ( ModeTable[Data->Mode].Width,
                                               ModeTable[Data->Mode].Height,   
                                               ModeTable[Data->Mode].BitSize );
       if (Result!=DD_OK)
         {
           Reset ();  
           return FAILURE;                                              
         } // End if

       Width = ModeTable[Data->Mode].Width;
       Height = ModeTable[Data->Mode].Height;
       BitSize = ModeTable[Data->Mode].BitSize;
       BytesPerRow = Width*8 / BitSize;
       
       DDSURFACEDESC ddsdDesc;
       ddsdDesc.dwSize = sizeof(DDSURFACEDESC);
       ddsdDesc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
       ddsdDesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
       ddsdDesc.dwBackBufferCount = 1;
       Result = lpDirectDraw->CreateSurface ( &ddsdDesc, &lpPrimarySurface, NULL );
       if (Result!=DD_OK)
         {
           Reset ();  
           return FAILURE;                                              
         } // End if

       DDSCAPS ddscCaps;
       ddscCaps.dwCaps = DDSCAPS_BACKBUFFER;
       Result = lpPrimarySurface->GetAttachedSurface ( &ddscCaps, &lpSecondarySurface );                
       if (Result!=DD_OK)
         {
           Reset ();  
           return FAILURE;                                              
         } // End if

 			 PALETTEENTRY pePalette[256]; 
			 memset ( pePalette, 0, sizeof(PALETTEENTRY)*256 );
			 Result = lpDirectDraw->CreatePalette ( DDPCAPS_8BIT, pePalette, &lpDirectDrawPalette, NULL );
       if (Result!=DD_OK)
         {
           Reset ();  
           return FAILURE;                                              
         } // End if

       if (lpDirectDrawPalette==NULL)
         {
           Reset ();  
           return FAILURE;                                              
         } // End if

			 Result = lpPrimarySurface->SetPalette ( lpDirectDrawPalette );
       if (Result!=DD_OK)
         {
           Reset ();  
           return FAILURE;                                              
         } // End if

     #endif  
     return SUCCESS;
  } // End of SetUp for DDRAWDRIVER

VOID DDRAWDRIVER::Reset ()
  {
     #if defined (__FORGDK__)
       if (lpDirectDraw!=NULL)
         {
           lpDirectDraw->RestoreDisplayMode ();
           lpDirectDraw->Release ();
           lpDirectDraw = NULL;  
         } // End if
     #endif 
  } // End of Reset for DDRAWDRIVER

VOID DDRAWDRIVER::Clear ( HDISPLAY hDisplay, LONG Color )
  {
    if (hDisplay)
      {}
    if (Color)
      {}    
    #if defined (__FORGDK__)
      INT i;
      for (i=0;i<2;i++)
        {
          DDBLTFX ddbltfx;
          ddbltfx.dwSize = sizeof (DDBLTFX);
          ddbltfx.dwFillColor = Color;
          if (lpSecondarySurface->Blt ( NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL,
                                        &ddbltfx )!=DD_OK)
            return;                           
          if (lpPrimarySurface->Flip ( NULL, DDFLIP_WAIT )!=DD_OK)
            return;
        } // End for
    #else
      if (hDisplay)
        {}
      if (Color)
        {}
    #endif
  } // End of Clear for DDRAWDRIVER

LONG DDRAWDRIVER::GetWidth ( HDISPLAY hDisplay )
  {
    if (hDisplay)
      {}
    #if defined (__FORGDK__)
      return Width;
    #else
      return NULL;
    #endif
  } // End of GetWidth for DDRAWDRIVER

LONG DDRAWDRIVER::GetHeight ( HDISPLAY hDisplay )
  {
    if (hDisplay)
      {}
    #if defined (__FORGDK__)
      return Height;
    #else
      return NULL;
    #endif
  } // End of GetHeight for DDRAWDRIVER

VOID DDRAWDRIVER::DisplayImage ( IMAGE *Image, LONG Sx, LONG Sy,
                                 LONG Wd, LONG Ht, HDISPLAY Dest,
                                 LONG Cx, LONG Cy, LONG DestWd, LONG DestHt )
  {
     if (Image)
       {}
     if (Sx&Sy&Wd&Ht&Cx&Cy)
       {}
     if (DestWd&DestHt)
       {}  
     if (Dest)
       {}
     #if defined (__FORGDK__)
       HRESULT Result;
       DDSURFACEDESC ddsdDesc;
       INT i;
       
       ddsdDesc.dwSize = sizeof(DDSURFACEDESC);       
       Result = lpSecondarySurface->Lock ( NULL, &ddsdDesc, 0, NULL );

       if (Result==DDERR_SURFACELOST)
         {
           if (lpPrimarySurface->Restore()!=DD_OK)
             return;               
           Clear ( hMainWindow, 0 );
           Result = lpSecondarySurface->Lock ( NULL, &ddsdDesc, 0, NULL );           
         } // End if
       if (Result!=DD_OK)
         return;

       BYTE *DestBuffer = (BYTE*)ddsdDesc.lpSurface;
       DestBuffer += Cy*Width+Cx;
       LONG lDestPitch = ddsdDesc.lPitch;
         
       BYTE *SrcBuffer = Image->SetOffset ( Sx, Sy );    
       
       if ((MagH==DivH)&&(MagV==DivV))
         {
           for (i=0;i<Ht;i++)
            {
              memcpy ( DestBuffer, SrcBuffer, Wd );
              SrcBuffer = Image->GetNextRow ( ROW_DOWN );
              DestBuffer += BytesPerRow;
            } // End for
         } // End if
       else
         {    
           WORD Error = 0;
           DWORD AddError = (((LONG)DivH<<16)/MagH);

           INT i; 
           for (i=0;i<DestHt;i++)
             {
               ScaleBlt256To256 ( DestBuffer, SrcBuffer, DestWd, Error, AddError );
               SrcBuffer = Image->SetOffset ( Sx, Sy+(i*DivV)/MagV );
               DestBuffer += BytesPerRow;
             } // End for
          } // End else

			  Result = lpSecondarySurface->Unlock (NULL);
        if (Result!=DD_OK)
          {
					  return;
          } // End if  

        Result = lpPrimarySurface->Flip ( NULL, DDFLIP_WAIT );
        if (Result!=DD_OK)
          {
            if (Result==DDERR_SURFACELOST)
              {
                lpPrimarySurface->Restore ();                  
              } // End if  
          } // End if  
     #endif
  } // End of DisplayImage for DDRAWDRIVER

VOID DDRAWDRIVER::SetPalette ( HDISPLAY hDisplay, RGBPALETTE *Pal )
  {
     if (hDisplay)
       {}
     if (Pal)
       {}
     #if defined (__FORGDK__)
		   PALETTEENTRY pePalette[256];
			 RGBCOLOR *Entry;

			 Entry = Pal->GetEntry ();

			 INT i;
			 for (i=0;i<256;i++)
				 {
				   pePalette[i].peRed = Entry[i].Red;
				   pePalette[i].peGreen = Entry[i].Green;
				   pePalette[i].peBlue = Entry[i].Blue;
				 } // End for

		   lpDirectDrawPalette->SetEntries ( DDSETPAL_IMMEDIATE, 0, 256, pePalette );		   
     #endif
  } // End of SetPalette for DDRAWDRIVER

VOID DDRAWDRIVER::GetPalette ( HDISPLAY hDisplay, RGBPALETTE *Pal )
  {
     if (hDisplay)
       {}
     if (Pal)
       {}
     #if defined (__FORGDK__)
		   PALETTEENTRY pePalette[256];
			 RGBCOLOR *Entry;

			 Entry = Pal->GetEntry ();

		   lpDirectDrawPalette->SetEntries ( 0, 0, 256, pePalette );		   

			 INT i;
			 for (i=0;i<256;i++)
				 {
				   Entry[i].Red = pePalette[i].peRed;
				   Entry[i].Green = pePalette[i].peGreen;
				   Entry[i].Blue = pePalette[i].peBlue;
				 } // End for
     #endif
  } // End of GetPalette for DDRAWDRIVER

VOID DDRAWDRIVER::DrawLine ( HDISPLAY hDisplay, LONG x1, LONG y1, LONG x2, LONG y2,
                                COLOR  Color )
  {
     if (hDisplay)
       {}
     if (x1&y1&x2&y2)
       {}
     if (Color)
       {}
     #if defined (__FORGDK__)
     #endif
  } // End of DrawLine for DDRAWDRIVER

VOID DDRAWDRIVER::DrawRect ( HDISPLAY hDisplay, LONG x1, LONG y1, LONG x2, LONG y2,
                                 COLOR Color )
  {
     if (hDisplay)
       {}
     if (x1&y1&x2&y2)
       {}
     if (Color)
       {}
     #if defined (__FORGDK__)
     #endif
  } // End of DrawRect for DDRAWDRIVER

VOID DDRAWDRIVER::FillRect ( HDISPLAY hDisplay, LONG x1, LONG y1, LONG x2, LONG y2,
                               COLOR Color )
  {
     if (hDisplay)
       {}
     if (x1&y1&x2&y2)
       {}
     if (Color)
       {}
  } // End of FillRect for DDRAWDRIVER

VOID DDRAWDRIVER::DrawPixel ( HDISPLAY hDisplay, LONG x, LONG y,
                                  COLOR Color )
  {
     if (hDisplay)
       {}
     if (x&y)
       {}
     if (Color)
       {}
  } // End of DrawPixel for DDRAWDRIVER

VOID DDRAWDRIVER::DrawEllipse ( HDISPLAY hDisplay, LONG Cx, LONG Cy, LONG Rx, LONG Ry,
                                    COLOR Color )
  {
     if (hDisplay)
       {}
     if (Cx&Cy&Rx&Ry)
       {}
     if (Color)
       {}
  } // End of DrawEllipse for DDRAWDRIVER

VOID DDRAWDRIVER::FillEllipse ( HDISPLAY hDisplay, LONG Cx, LONG Cy, LONG Rx, LONG Ry,
                                  COLOR Color )
  {
     if (hDisplay)
       {}
     if (Cx&Cy&Rx&Ry)
       {}
     if (Color)
       {}
  } // End of FillEllipse for DDRAWDRIVER

VOID DDRAWDRIVER::DrawText ( HDISPLAY hDisplay, STRING Text, LONG x, LONG y,
                                 COLOR Color )
  {
     if (hDisplay)
       {}
     if (x&y)
       {}
     if (Color)
       {}
     if (Text)
       {}
  } // End of DrawText for DDRAWDRIVER

