📄 ddrawsystem.cpp
字号:
// DDrawSystem.cpp: implementation of the CDDrawSystem class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "DDrawSystem.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CDDrawSystem::CDDrawSystem()
{
m_pDD = NULL;
m_pddsFrontBuffer = NULL;
m_pddsStoreBuffer = NULL;
pcClipper = NULL;
}
CDDrawSystem::~CDDrawSystem()
{
Terminate();
}
// old DirectDraw Initialization stuff. Set a window mode DirectDraw Display.
BOOL CDDrawSystem::Init(HWND hWnd)
{
TRACE0("1 What the fuck!!!\n");
HRESULT hRet;
this->hWnd = hWnd;
hRet = DirectDrawCreateEx(NULL, (VOID**)&m_pDD, IID_IDirectDraw7, NULL);
if(hRet != DD_OK)
{
AfxMessageBox("Failed to create directdraw object.");
return FALSE;
}
hRet = m_pDD->SetCooperativeLevel(hWnd, DDSCL_NORMAL);
if(hRet != DD_OK)
{
AfxMessageBox("Failed to set directdraw display behavior.");
return FALSE;
}
HRESULT hr;
DDSURFACEDESC2 ddsd;
ZeroMemory( &ddsd, sizeof( ddsd ) );
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
if(FAILED(hr = m_pDD->CreateSurface(&ddsd, &m_pddsFrontBuffer, NULL)))
{
AfxMessageBox("Failed to create primary surface.");
return FALSE;
}
// Create the backbuffer surface
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
ddsd.dwWidth = WINDOW_SIZE_X;
ddsd.dwHeight = WINDOW_SIZE_Y;
if(FAILED(hr = m_pDD->CreateSurface(&ddsd, &m_pddsStoreBuffer, NULL)))
{
AfxMessageBox("Failed to create back buffer surface.");
return FALSE;
}
if(FAILED(hr = m_pDD->CreateClipper(0, &pcClipper, NULL)))
{
AfxMessageBox("Failed to create clipper.");
return FALSE;
}
if(FAILED(hr = pcClipper->SetHWnd(0, hWnd)))
{
pcClipper->Release();
AfxMessageBox("Failed to create primary surface.");
return FALSE;
}
if(FAILED(hr = m_pddsFrontBuffer->SetClipper(pcClipper)))
{
pcClipper->Release();
AfxMessageBox("Failed to create primary surface.");
return FALSE;
}
TRACE0("2 What the fuck!!!\n");
return TRUE;
}
// make sure all stuff are terminated. and set to NULL when application ends.
void CDDrawSystem::Terminate()
{
if (m_pDD != NULL)
{
if (m_pddsFrontBuffer != NULL)
{
if (m_pddsStoreBuffer != NULL)
{
m_pddsStoreBuffer->Release();
m_pddsStoreBuffer = NULL;
}
if (pcClipper != NULL)
{
pcClipper->Release();
pcClipper = NULL;
}
m_pddsFrontBuffer->Release();
m_pddsFrontBuffer = NULL;
}
m_pDD->Release();
m_pDD = NULL;
}
}
// clear both off csreen buffer and primary buffer.
void CDDrawSystem::Clear()
{
DDSURFACEDESC2 ddsd;
WORD * surface_data;
int x, y;
ddsd.dwSize = sizeof (DDSURFACEDESC2);
if (FAILED(m_pddsStoreBuffer->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL)))
{
// do something here
TRACE0("failed to lock.\n");
return;
}
surface_data = (WORD *)ddsd.lpSurface;
for (y = 0; y < (int)ddsd.dwHeight; y++)
{
for (x = 0; x < (int)ddsd.lPitch; x++)
{
*surface_data = 0x0000;
surface_data++;
}
}
if(FAILED(m_pddsStoreBuffer->Unlock(NULL)))
{
TRACE0("failed to lock.\n");
return;
}
}
void CDDrawSystem::Render1(POINT & dst, WORD * src_arr, int size_x, int size_y)
{
DDSURFACEDESC2 ddsd;
WORD * surface_data;
int x, y;
ddsd.dwSize = sizeof (DDSURFACEDESC2);
TRACE0("Enter render1\n");
if (FAILED(m_pddsStoreBuffer->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL)))
{
// do something here
TRACE0("failed to lock.\n");
return;
}
for (y = 0; y < size_y; y++)
{
surface_data = (WORD*) ((BYTE *)ddsd.lpSurface + ((dst.y + y) * ddsd.lPitch) + (dst.x * 2));
for (x = 0; x < size_x; x++)
{
*surface_data = *src_arr;
surface_data++;
src_arr++;
}
}
if(FAILED(m_pddsStoreBuffer->Unlock(NULL)))
{
TRACE0("failed to lock.\n");
return;
}
TRACE0("End of Render1\n");
}
void CDDrawSystem::Render2(POINT & dst, WORD src_col, int size_x, int size_y)
{
DDSURFACEDESC2 ddsd;
WORD * surface_data;
int x, y;
ddsd.dwSize = sizeof (DDSURFACEDESC2);
TRACE0("Enter render2\n");
if (FAILED(m_pddsStoreBuffer->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL)))
{
// do something here
TRACE0("failed to lock.\n");
return;
}
for (y = 0; y < size_y; y++)
{
surface_data = (WORD*) ((BYTE *)ddsd.lpSurface + ((dst.y + y) * ddsd.lPitch) + (dst.x * 2));
for (x = 0; x < size_x; x++)
{
*surface_data = src_col;
surface_data++;
}
}
if(FAILED(m_pddsStoreBuffer->Unlock(NULL)))
{
TRACE0("failed to lock.\n");
return;
}
TRACE0("End of render2\n");
}
// This is a function that draw a dot at a specific point. Hopefully, this function will not be used
// at all. It is a very inefficient algorithm. Should not be used in really game design.
void CDDrawSystem::DrawPoint(POINT & dst, WORD src_col)
{
DDSURFACEDESC2 ddsd;
WORD * surface_data;
ddsd.dwSize = sizeof (DDSURFACEDESC2);
TRACE0("Enter DrawPoint\n");
if (FAILED(m_pddsStoreBuffer->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL)))
{
// do something here
TRACE0("failed to lock.\n");
return;
}
surface_data = (WORD*) ((BYTE *)ddsd.lpSurface + (dst.y * ddsd.lPitch) + (dst.x * 2));
*surface_data = src_col;
if(FAILED(m_pddsStoreBuffer->Unlock(NULL)))
{
TRACE0("failed to lock.\n");
return;
}
TRACE0("End of DrawPoint\n");
} // This function should not be used!
void CDDrawSystem::AlphaBlend_Render(POINT & dst, WORD * src_arr, int size_x, int size_y, int percent)
{
DDSURFACEDESC2 ddsd;
WORD * surface_data;
WORD temp_data;
WORD temp_red;
WORD temp_green;
WORD temp_blue;
WORD perc = percent;
WORD absol = 256;
WORD temp_data2;
WORD temp_red2;
WORD temp_green2;
WORD temp_blue2;
WORD dst_col;
BYTE dst_red;
BYTE dst_green;
BYTE dst_blue;
int x, y;
ddsd.dwSize = sizeof (DDSURFACEDESC2);
TRACE0("Enter render2\n");
if (FAILED(m_pddsStoreBuffer->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL)))
{
// do something here
TRACE0("failed to lock.\n");
return;
}
for (y = 0; y < size_y; y++)
{
surface_data = (WORD*) ((BYTE *)ddsd.lpSurface + ((dst.y + y) * ddsd.lPitch) + (dst.x * 2));
for (x = 0; x < size_x; x++)
{
temp_data = *surface_data;
temp_red = GetRed(temp_data);
temp_green = GetGreen(temp_data);
temp_blue = GetBlue(temp_data);
temp_data2 = *src_arr;
temp_red2 = GetRed(temp_data2);
temp_green2 = GetGreen(temp_data2);
temp_blue2 = GetBlue(temp_data2);
dst_red = CalcAlphaBlendVal(temp_red2, temp_red, percent);
dst_green = CalcAlphaBlendVal(temp_green2, temp_green, percent);
dst_blue = CalcAlphaBlendVal(temp_blue2, temp_blue, percent);
dst_col = MakeRGB16(dst_red, dst_green, dst_blue);
*surface_data = dst_col;
surface_data++;
src_arr++;
}
}
if(FAILED(m_pddsStoreBuffer->Unlock(NULL)))
{
TRACE0("failed to lock.\n");
return;
}
TRACE0("End of render2\n");
}
// Load images from offscteen buffer to primary buffer and for display.
void CDDrawSystem::Display()
{
HRESULT hRet;
RECT rt;
POINT p = {0, 0};
ClientToScreen(hWnd, &p);
rt.left = p.x; rt.top = p.y; rt.right = WINDOW_SIZE_X + p.x; rt.bottom = WINDOW_SIZE_Y + p.y;
while( 1 )
{
hRet = m_pddsFrontBuffer->Blt(&rt, m_pddsStoreBuffer, NULL, DDBLT_WAIT, NULL);
if (hRet == DD_OK)
break;
else if(hRet == DDERR_SURFACELOST)
{
m_pddsFrontBuffer->Restore();
m_pddsStoreBuffer->Restore();
}
else if(hRet != DDERR_WASSTILLDRAWING)
return;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -