⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ddrawsystem.cpp

📁 本原码主要介绍了如何在arm处理器上针对24位真彩位图的处理的方法
💻 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 + -