// CDIRDRAW.CPP -- Implementation file for our CDirDraw class

#include "cdirdraw.h"

// Our class constructor
CDirDraw::CDirDraw(HWND hWnd)
{
    m_pDirectDrawObj = NULL;
    m_pPrimarySurface = NULL;
    m_pBackBuffer = NULL;

// Create & initialize a DirectDraw object
    DirectDrawCreate(NULL, &m_pDirectDrawObj, NULL);
// Take control of video & set mode
    m_pDirectDrawObj->SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
    m_pDirectDrawObj->SetDisplayMode(640, 480, 8);
// Create Main Surfaces
    DDSURFACEDESC ddSurfaceDesc;
    memset(&ddSurfaceDesc, 0, sizeof(DDSURFACEDESC));
    ddSurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
    ddSurfaceDesc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
    ddSurfaceDesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
    ddSurfaceDesc.dwBackBufferCount = 1;
// Create the primary surface.
    m_pDirectDrawObj->CreateSurface(&ddSurfaceDesc, &m_pPrimarySurface, NULL);
// Retrieve a pointer to the back buffer.
    DDSCAPS ddsCaps;
    ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
    m_pPrimarySurface->GetAttachedSurface(&ddsCaps, &m_pBackBuffer);
}

// The class destructor--get rid of all CDirectDraw constructs    
CDirDraw::~CDirDraw()
{
    if (m_pBackBuffer != NULL)
        m_pBackBuffer->Release();
    if (m_pPrimarySurface != NULL)
        m_pPrimarySurface->Release();
    if (m_pDirectDrawObj != NULL)
        m_pDirectDrawObj->Release();
}

void CDirDraw::DrawLines()
{
    DDSURFACEDESC ddSurfaceDesc;
    int color, x;

    memset(&ddSurfaceDesc, 0, sizeof(DDSURFACEDESC));
    ddSurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
    // access the back surface--get its surface descriptor
    m_pBackBuffer->Lock(NULL,&ddSurfaceDesc,DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT,NULL);
    char* buf = (char*)ddSurfaceDesc.lpSurface; //ptr to start of surface
    memset(buf, 0, ddSurfaceDesc.lPitch*ddSurfaceDesc.dwHeight); //black
    for (color=0; color<256; color++)  //draw 256 lines by accessing 
        for (x=0; x<100; x++)          //the surface buffer directly
            buf[20*ddSurfaceDesc.lPitch+50 + color*ddSurfaceDesc.lPitch + x]=color;
    m_pBackBuffer->Unlock(ddSurfaceDesc.lpSurface);
}

// Change the color of the entire back buffer surface
void CDirDraw::ChangeColor(int color)
{
    DDSURFACEDESC ddSurfaceDesc;

    memset(&ddSurfaceDesc, 0, sizeof(DDSURFACEDESC));
    ddSurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
    m_pBackBuffer->Lock(NULL,&ddSurfaceDesc,DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT,NULL);
    // set surface buffer to 'color'
    UINT surfaceWidth = ddSurfaceDesc.lPitch;
    UINT surfaceHeight = ddSurfaceDesc.dwHeight;
    char* buf = (char*)ddSurfaceDesc.lpSurface;
    memset(buf, color, surfaceWidth * surfaceHeight);
    m_pBackBuffer->Unlock(ddSurfaceDesc.lpSurface);
}