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

📄 my_directdraw.cpp

📁 斗地主源码
💻 CPP
字号:

#include "stdafx.h"
#include "MainFrm.h"

#include "Game.h"
#include "My_DirectInput.h"
#include "my_directdraw.h"

#include "Draw_Cards_Engine.h"

#include "Playing_Cards.h"


#include <io.h>

CMyDirectDraw::CMyDirectDraw()
{
	lpdd         = NULL;   // dd object
	lpddclipper  = NULL;   // dd clipper

	bitmap.buffer = NULL; //记住!!!!!!初始化!!!!!永远的伤
	start_clock_count = 0; // used for timing

	SCREEN_BPP = 32;

}


int CMyDirectDraw::Flip_Bitmap(UCHAR *image, int bytes_per_line, int height)
{
// 将数据读入表面

	UCHAR *buffer; // used to perform the image processing
	int index;  

	if (!(buffer = (UCHAR *)new UCHAR[bytes_per_line*height]) )
		return(0);

	memcpy(buffer,image,bytes_per_line*height);

	for (index=0; index < height; index++)
	{
	    memcpy(&image[((height-1) - index)*bytes_per_line],
			   &buffer[index*bytes_per_line], bytes_per_line);
	}

// release the memory
	delete(buffer);

	return(1);

} // end Flip_Bitmap

//读取位图的方法:

int CMyDirectDraw::Load_Bitmap_File(BITMAP_FILE_PTR bitmap, char *filename)
{
//
	int file_handle;  // the file handle
       
	UCHAR   *temp_buffer = NULL; 
	OFSTRUCT file_data;     

// 打开文件如果它存在;
	if ((file_handle = OpenFile(filename,&file_data,OF_READ))==-1)
	   return(0);


	_lread(file_handle, &bitmap->bitmapfileheader,sizeof(BITMAPFILEHEADER));


	if (bitmap->bitmapfileheader.bfType!=BITMAP_ID)
	{
		//如果不是位图,则关闭文件,返回;
	  _lclose(file_handle);
	  return(0);
    } // end if

// 发现是位图,继续;

// 读取文件头;
	_lread(file_handle, &bitmap->bitmapinfoheader,sizeof(BITMAPINFOHEADER));

//如果是8位位图,则返回;
	if (bitmap->bitmapinfoheader.biBitCount == 8)
	{
		AfxMessageBox("本游戏不能读取8位位图!");
		return 0;
	} // end if

	//从文件结尾反向搜位图数据字节大小的长度;
	_lseek(file_handle,(int)(sizeof(BITMAPFILEHEADER)+
	   sizeof(BITMAPINFOHEADER)),SEEK_SET);

	int Image_Size = bitmap->bitmapfileheader.bfSize-
		(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER));

	if (bitmap->bitmapinfoheader.biBitCount==8 || bitmap->bitmapinfoheader.biBitCount==16 || 
	    bitmap->bitmapinfoheader.biBitCount==24)
    {
//如果位图存在,则先释放;
	   if (bitmap->buffer)
	       free(bitmap->buffer);


	   if ( !(bitmap->buffer = (UCHAR *)new UCHAR [Image_Size]) )
	      {
 
			_lclose(file_handle);
			return(0);
	      } 
	   _lread(file_handle,bitmap->buffer,Image_Size);

	} 
	else
	{
   //见鬼了!
	   return(0);
    } 

	_lclose(file_handle);

// flip the bitmap
	Flip_Bitmap(bitmap->buffer, 
	            bitmap->bitmapinfoheader.biWidth*(bitmap->bitmapinfoheader.biBitCount/8), 
	            bitmap->bitmapinfoheader.biHeight);

	return(1);

} 

int CMyDirectDraw::Unload_Bitmap_File(BITMAP_FILE_PTR bitmap)
{
// this function releases all memory associated with "bitmap"
	if (bitmap->buffer)
	{
   // release memory
	   delete(bitmap->buffer);

	   bitmap->buffer = NULL;
    } 
	return(1);

} 

int CMyDirectDraw::Scan_Image_Bitmap(BITMAP_FILE_PTR bitmap,     // bitmap file to scan image data from
				                      LPDIRECTDRAWSURFACE7 lpdds, // surface to hold data
				                      int cx, int cy)             // cell to scan image from
{
//将位图像素写到表面去!
	DDSURFACEDESC2 ddsd;  //  direct draw surface description 
 
// set size of the structure
	ddsd.dwSize = sizeof(ddsd);

// lock the display surface
	lpdds->Lock(NULL,
	            &ddsd,
	            DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,
	            NULL);

	cx = cx*(ddsd.dwWidth+1) + 1;
	cy = cy*(ddsd.dwHeight+1) + 1;

	DWORD *dest_ptr;
	UCHAR blue,green,red;
	dest_ptr = (DWORD *)ddsd.lpSurface;

	for (DWORD index_y = 0; index_y < ddsd.dwHeight; index_y++)
	{
		for (DWORD index_x = 0; index_x < ddsd.dwWidth; index_x++)
		{
        // get BGR values;;;;
			int index = index_y*(bitmap->bitmapinfoheader.biWidth)*3 + index_x*3;

			blue  = bitmap->buffer[index + 0];
			green = bitmap->buffer[index + 1];
			red   = bitmap->buffer[index + 2];

        // 32位RGB数;
			DWORD pixel = _RGB32BIT(0,red,green,blue);

			dest_ptr[index_x + (index_y*ddsd.lPitch >> 2)] = pixel;
		} 
			
	} 

	// unlock the surface 
	lpdds->Unlock(NULL);

	return(1);
}

//填充表面的方法
int CMyDirectDraw::FillSurface(LPDIRECTDRAWSURFACE7 lpdds,int color)
{
	DDBLTFX ddbltfx;

//初始化ddbltfx结构;
	DDRAW_INIT_STRUCT(ddbltfx);

// 需要填空全屏的颜色值;
	ddbltfx.dwFillColor = color; 

// blt to surface
	lpdds->Blt(
			   NULL,       // ptr to dest rectangle
	           NULL,       // ptr to source surface, NA            
	           NULL,       // ptr to source rectangle, NA
	           DDBLT_COLORFILL | DDBLT_WAIT,   // fill and wait                   
		       &ddbltfx
			   );  // ptr to DDBLTFX structure


	return(1);
} // end FillSurface

//根据传入参数建立相应的表面
LPDIRECTDRAWSURFACE7 CMyDirectDraw::CreateSurface(
										  int width,
										  int height,
										  int mem_flags,
										  int color = 0)
{
// this function creates an offscreen plain surface

	DDSURFACEDESC2 ddsd;         // working description
	LPDIRECTDRAWSURFACE7 lpdds;  // temporary surface
    
// set to access caps, width, and height
	memset(&ddsd,0,sizeof(ddsd));
	ddsd.dwSize  = sizeof(ddsd);
	ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;

// set dimensions of the new bitmap surface
	ddsd.dwWidth  =  width;
	ddsd.dwHeight =  height;

// set surface to offscreen plain
	ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | mem_flags;

// create the surface
	if (FAILED(lpdd->CreateSurface(&ddsd,&lpdds,NULL)))
	   return(NULL);

// test if user wants a color key
	if (color >= 0)
    {
   // set color key to color 0
	   DDCOLORKEY color_key; // used to set color key
	   color_key.dwColorSpaceLowValue  = color;
	   color_key.dwColorSpaceHighValue = color;

   // now set the color key for source blitting
	   lpdds->SetColorKey(DDCKEY_SRCBLT, &color_key);
	}  // end if

// return surface
	return(lpdds);
} // end CreateSurface

int CMyDirectDraw::DrawSurface(
					  LPDIRECTDRAWSURFACE7 source, // source surface to draw
                      int x, int y,                 // position to draw at
                      int width, int height,        // size of source surface
                      LPDIRECTDRAWSURFACE7 dest,    // surface to draw the surface on
                      int transparent = 1)          // transparency flag
{
// draw a bob at the x,y defined in the BOB
// on the destination surface defined in dest

	RECT dest_rect,   // the destination rectangle
		 source_rect; // the source rectangle                             

// fill in the destination rect
	dest_rect.left   = x;
	dest_rect.top    = y;
	dest_rect.right  = x+width;
	dest_rect.bottom = y+height;

// fill in the source rect
	source_rect.left    = 0;
	source_rect.top     = 0;
	source_rect.right   = width;
	source_rect.bottom  = height;

// test transparency flag

	if (transparent)
    {
   // enable color key blit
   // blt to destination surface
	   if (FAILED(dest->Blt(&dest_rect, source,
                     &source_rect,(DDBLT_WAIT | DDBLT_KEYSRC),
                     NULL)))
            return(0);

	} // end if
	else
    {
   // perform blit without color key
   // blt to destination surface
		if (FAILED(dest->Blt(&dest_rect, source,
                     &source_rect,(DDBLT_WAIT),
                     NULL)))
           return(0);

	} // end if

// return success
	return(1);

} // end DrawSurface
//创建剪切的方法:
LPDIRECTDRAWCLIPPER CMyDirectDraw::AttachClipper(
										 LPDIRECTDRAWSURFACE7 lpdds,
                                         int num_rects,
                                         LPRECT clip_list)

{
// this function creates a clipper from the sent clip list and attaches
// it to the sent surface

	int index;                         // looping var
	LPDIRECTDRAWCLIPPER lpddclipper;   // pointer to the newly created dd clipper
	LPRGNDATA region_data;             // pointer to the region data that contains
                                   // the header and clip list

// first create the direct draw clipper
	if (FAILED(lpdd->CreateClipper(0,&lpddclipper,NULL)))
	   return(NULL);

// now create the clip list from the sent data

// first allocate memory for region data
	region_data = (LPRGNDATA)malloc(sizeof(RGNDATAHEADER)+num_rects*sizeof(RECT));

// now copy the rects into region data
	memcpy(region_data->Buffer, clip_list, sizeof(RECT)*num_rects);

// set up fields of header
	region_data->rdh.dwSize          = sizeof(RGNDATAHEADER);
	region_data->rdh.iType           = RDH_RECTANGLES;
	region_data->rdh.nCount          = num_rects;
	region_data->rdh.nRgnSize        = num_rects*sizeof(RECT);

	region_data->rdh.rcBound.left    =  64000;
	region_data->rdh.rcBound.top     =  64000;
	region_data->rdh.rcBound.right   = -64000;
	region_data->rdh.rcBound.bottom  = -64000;

// find bounds of all clipping regions
	for (index=0; index<num_rects; index++)
    {
    // test if the next rectangle unioned with the current bound is larger
	    if (clip_list[index].left < region_data->rdh.rcBound.left)
	        region_data->rdh.rcBound.left = clip_list[index].left;

	    if (clip_list[index].right > region_data->rdh.rcBound.right)
	        region_data->rdh.rcBound.right = clip_list[index].right;

	    if (clip_list[index].top < region_data->rdh.rcBound.top)
	        region_data->rdh.rcBound.top = clip_list[index].top;

	    if (clip_list[index].bottom > region_data->rdh.rcBound.bottom)
	        region_data->rdh.rcBound.bottom = clip_list[index].bottom;

    } // end for index

// now we have computed the bounding rectangle region and set up the data
// now let's set the clipping list

	if (FAILED(lpddclipper->SetClipList(region_data, 0)))
    {
   // release memory and return error
		free(region_data);
		return(NULL);
	} // end if

// now attach the clipper to the surface
	if (FAILED(lpdds->SetClipper(lpddclipper)))
    {
   // release memory and return error
	   free(region_data);
	   return(NULL);
	} // end if

// all is well, so release memory and send back the pointer to the new clipper
	free(region_data);
	return(lpddclipper);

} 
//调试用;
int CMyDirectDraw::DebugText(char* text,int time)
{
	HDC xdc; // the working dc


	if (FAILED(lpddsprimary->GetDC(&xdc)))
	   return(0);

	SetBkMode(xdc, TRANSPARENT);

	TextOut(xdc,140,500,text,strlen(text));

	lpddsprimary->ReleaseDC(xdc);

	::Sleep(time);

	return 1;
}

int CMyDirectDraw::TextGDI(
								char *text,
								int x,
								int y,
								COLORREF color,
								int size,
								char* type,
								LPDIRECTDRAWSURFACE7 lpdds)
{	
	HDC xdc; 
	if (FAILED(lpdds->GetDC(&xdc)))
	   return(0);

	LOGFONT my_font;
	memset(&my_font,0,sizeof(LOGFONT));

	my_font.lfCharSet = DEFAULT_CHARSET;
	my_font.lfHeight = size;
//	lstrcpyn(my_font.lfFaceName, type, _countof(my_font.lfFaceName));
	sprintf(my_font.lfFaceName,type);

	POINT pt;
	pt.y = ::GetDeviceCaps(xdc, LOGPIXELSY) * my_font.lfHeight;
	pt.y /= 720;    // 72 points/inch, 10 decipoints/point
	::DPtoLP(xdc, &pt, 1);
	POINT ptOrg = { 0, 0 };
	::DPtoLP(xdc, &ptOrg, 1);
	my_font.lfHeight = -abs(pt.y - ptOrg.y);


	HFONT hFont;
	hFont = ::CreateFontIndirect(&my_font);

//	dc.m_hDC  = xdc;
	//新字体对象及指针;
//	CFont my_font;
	//把新建字体选进描述中;
//	my_font.CreatePointFont(size,type,NULL);//创建自己的字体;
//	old_font = dc.SelectObject(&my_font);  //选择新的字体;


	SelectObject(xdc,hFont);
	SetTextColor(xdc,color);
	SetBkMode(xdc,TRANSPARENT);
	TextOut(xdc,x,y,text,strlen(text));

	//恢复原设备描述符表的字体;
	DeleteObject(hFont);
	lpdds->ReleaseDC(xdc);

	return 1;
}
//初始化DD平台;
int CMyDirectDraw::Init()
{
//	pCMainFrame = *)AfxGetMainWnd();

	if (FAILED(DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL)))
	{
		   return(0);
	}
// set cooperation to full screen
	if(FAILED(lpdd->SetCooperativeLevel(::pCMainFrame->m_hWnd, 
									 DDSCL_ALLOWMODEX | DDSCL_FULLSCREEN |
                                     DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)) )  // 
	{
		   return(0);
	}

	if (FAILED(lpdd->SetDisplayMode(Screen_Width, Screen_Height, SCREEN_BPP,0,0)))
	{
		   return(0);
	}

	DDRAW_INIT_STRUCT(ddsd);  //清零的宏;

	// enable valid fields
	ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;

// set the backbuffer count field to 1, use 2 for triple buffering
	ddsd.dwBackBufferCount = 1;

// request a complex, flippable
	ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;

// 创建主表面;
	if (FAILED(lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL)))
			return(0);

	ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;

	if (FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpddsback)))
		  return(0);

//设置后备缓冲区的剪裁区;
	RECT screen_rect= {0,0,Screen_Width,Screen_Height};
	lpddclipper = AttachClipper(lpddsback,1,&screen_rect);


	return 1;
} 

int CMyDirectDraw::BitmapToSurface(
						LPDIRECTDRAWSURFACE7 Dest_Surface,  //目的表面;
						int Dest_x,		//目的表面x座标;
						int Dest_y,		//目的表面y座标;
						char* filename,	//源位图文件名;	
						int Bitmap_Width,	//位图宽;
						int Bitmap_Height	//位图长;
						)
{
	HBITMAP hbitmap;
	HDC hdc;   //接受当前设备环境句柄;
	HDC dhdc;
	CString str;

	hdc = ::CreateCompatibleDC(NULL);

	hbitmap = (HBITMAP)::LoadImage(NULL,filename,IMAGE_BITMAP,Bitmap_Width,Bitmap_Height,LR_LOADFROMFILE); 

	if(hbitmap==NULL)
	{
		str.Format("无法载入位图%s",filename);
		AfxMessageBox(str);
		return 0;
	}

	::SelectObject(hdc,hbitmap);

	Dest_Surface->GetDC( &dhdc );
	::BitBlt( dhdc , Dest_x , Dest_y ,Bitmap_Width,Bitmap_Height, hdc , 0 , 0 , SRCCOPY );
	Dest_Surface->ReleaseDC(dhdc);

	return 1;
}

CMyDirectDraw::~CMyDirectDraw()
{
// now the primary surface
//	if (lpddsprimary)
 //   {
//		lpddsprimary->Release();
//		lpddsprimary = NULL;
//	} // end if
//后备缓冲
//	if(lpddsback)
//	{
//		lpddsback->Release();
//		lpddsback = NULL;
//	}
//离屏表面;
//	if(lpddsbackground)
//	{
//		lpddsbackground->Release();
//		lpddsbackground = NULL;
//	}	
// now blow away the IDirectDraw4 interface
	if (lpdd)
    {
		lpdd->Release();
		lpdd = NULL;
    } // end if
} 


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -