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

📄 puthz.cpp

📁 这是一个游戏程序源码
💻 CPP
字号:
/////////////
//	putHZ.h			:	v0011
//	Written by		:	Liu Gang
//	Compiler		:	Microsoft Visual C++ 4.0 & DirectX
//	Library			:	DDraw.Lib
//	Copyright (C)	:	1996 WayAhead Corporation 
//	v0010			:	Oct.4.1996
//	v0011			:	Apr.9.1997, change the name of GetSurface() to GetDDSurface()
//	v0012			:	Sep.2.1997, add an English version of PloyTextOut()
/////////////
// implementation file


#include "stdafx.h"
#include <stdio.h>

#include "putHZ.h"

//#define ENGLISH
//#define COMPLEX
//#define JAPANESE
#define SIMPLE

FILE *HZ_fp = NULL;

CDDText::CDDText()
{
	myhdc=NULL;
	//bmpsize;
	m_bmpsize.cx = m_bmpsize.cy = 0;
	m_mybytes=NULL;
	myhbmpsec=NULL;
	oldbmp=NULL;

	m_rcClient.left = m_rcClient.top = 0;
	m_rcClient.bottom = m_rcClient.right = 0;
	m_textcolor=RGB(255,255,255);
	m_dwColorCaps=DDBLTFAST_SRCCOLORKEY;
	m_nCol = 0;
	m_nRow = 0;
	m_nLineDist = 4;	// line distance
	//m_Face;
}

CDDText::~CDDText()
{
	EndText();
};

//prepare dc for MyDrawText and MyTextOut
BOOL CDDText::BeginText( int nCol, int nRow/*=1*/, BOOL bColorKey/*=TRUE*/)
{
//	ASSERT(!myhdc);
	if(myhdc)	return FALSE;

	//m_bmpsize.cx = m_rcClient.right-m_rcClient.left;
	//m_bmpsize.cy = m_rcClient.bottom-m_rcClient.top;
	m_bmpsize.cx=800, m_bmpsize.cy=CHAR_HEIGHT;

	//line may over 800
	myhdc=::CreateCompatibleDC(NULL);
	LPBITMAPINFOHEADER header=(LPBITMAPINFOHEADER)new BYTE[(sizeof(BITMAPINFOHEADER)+8)];
	if(header==NULL)	return FALSE;
	header->biSize=sizeof(BITMAPINFOHEADER);
	header->biWidth=m_bmpsize.cx;
	header->biHeight=-m_bmpsize.cy;
	header->biPlanes=1;
	header->biBitCount=1;
	header->biCompression=BI_RGB;
	header->biSizeImage=0;
	header->biXPelsPerMeter=0;
	header->biYPelsPerMeter=0;
	header->biClrUsed=0;
	header->biClrImportant=0;
	DWORD *rgb=(DWORD*)(header+1);
	rgb[0]=0;
	rgb[1]=0xffffff00;

	myhbmpsec=CreateDIBSection(myhdc, (LPBITMAPINFO)header, DIB_RGB_COLORS, (void**)&m_mybytes, NULL, 0);
	if( !myhbmpsec ) return FALSE;

	oldbmp=::SelectObject(myhdc, myhbmpsec);
	delete header;

	// prepare surface object
	m_rcClient.right = nCol*CHAR_WIDTH, m_rcClient.bottom = nRow*(CHAR_HEIGHT+m_nLineDist);
	m_nCol = nCol;
	m_nRow = nRow;
	if( bColorKey )
		m_dwColorCaps = DDBLTFAST_SRCCOLORKEY;
	else
		m_dwColorCaps = DDBLTFAST_NOCOLORKEY;
	// in system memory
	if( m_Face.Create( m_rcClient.right, m_rcClient.bottom, bColorKey, FALSE ) )
	{
		m_Face.Erase();	return TRUE;
	}
	return FALSE;
}

//delete objects used by MyDrawText and MyTextOut
void CDDText::EndText()
{			
	if(!myhdc)	return;
	::SelectObject(myhdc, oldbmp);
	::DeleteObject(myhbmpsec);
	::DeleteDC(myhdc);
	myhdc=NULL;

	// can be omitted
	m_Face.Release();
}
/////////////////

/////////////////
// read text data from charactor library
#ifdef	SIMPLE
inline int CDDText::ReadData( LPCTSTR String, int len )
{
	SIZE bmpsize;
	BYTE *mybytes;
	mybytes=m_mybytes;
	bmpsize.cx = m_bmpsize.cx, bmpsize.cy = m_bmpsize.cy;
/*
	// read from hz lib file
	FILE *HZ_fp;
	HZ_fp=fopen("hzk\\complex.exp", "rb");
	if( !HZ_fp ) return 0;
*/

	//Assert(HZ_fp);
	int xsize=len*CHAR_WIDTH;
	//ASSERT(xsize+16<bmpsize.cx);
	BYTE *strp=(BYTE*)String;
	for(int i=0;i<xsize/CHAR_WIDTH;i++){
	  BYTE c=*strp++;
	  if(c<(BYTE)0x81){
		fseek(HZ_fp, (9*94+c-0x20-1)*32, SEEK_SET);
		WORD buf[16];
		fread(buf, 1, 32, HZ_fp);
		__asm{
		  lea esi, buf
		  mov edi, mybytes
		  add edi, i
		  lea eax, bmpsize
		  mov eax, [eax]	//load bmpsize.cx
		  shr eax, 3
		  sub eax, 2
		  mov ecx, 16
rep3:
		  movsw
		  add edi, eax
//		  inc esi
		  loop rep3
		  }
	    }
	  else
	  if(c>=(BYTE)0xa1 && c<=(BYTE)0xf7 &&	*strp>=(BYTE)0xa1 && *strp<=(BYTE)0xff){
//	    fseek(HZ_fp, ((c-(c>=(BYTE)0xe0?0xc1:0x81))*0xbc+*strp-(*strp>(BYTE)0x7f?0x41:0x40))*32, SEEK_SET);
	    fseek(HZ_fp, ((c-0xa1)*94+*strp-0xa1)*32, SEEK_SET);
//	  	WORD* off=(WORD*)(mybytes+i);
//		int add=bmpsize.cx/8/2;
//		WORD* end=off+bmpsize.cx;
//	  	for(;off<end;off+=add)fread(off, 2, 1, HZ_fp);
	  	
		WORD buf[16];
		fread(buf, 32, 1, HZ_fp);
		__asm{
		  lea esi, buf
		  mov edi, mybytes
		  add edi, i
		  lea eax, bmpsize
		  mov eax, [eax]	//load bmpsize.cx
		  shr eax, 3
		  sub eax, 2
		  mov ecx, 16
rep1:
		  movsw
		  add edi, eax
		  loop rep1
		  }
	    
	    i++;strp++;
	    }
	  else {
		static WORD scancode[]={0x8FAA,0xE041,0x90AA,0xAC72,0xD867,0xEB68,0xEE84,0xAB64,0xAB95,0x8379};
	  	int fileoffset=sizeof(scancode)/sizeof(WORD);
		_asm{
		  lea edi, scancode[0]
		  mov ecx, fileoffset
		  mov eax, strp
		  mov al,  [eax]
		  mov ah,  c
		  repne scasw 
		  mov fileoffset, ecx
		  }
	  	if(fileoffset)fileoffset=(10*94+sizeof(scancode)/2-fileoffset-1)*32;
	    fseek(HZ_fp, fileoffset, SEEK_SET);

		WORD buf[16];
		fread(buf, 1, 32, HZ_fp);
		__asm{
		  lea esi, buf
		  mov edi, mybytes
		  add edi, i
		  lea eax, bmpsize
		  mov eax, [eax]	//load bmpsize.cx
		  shr eax, 3
		  sub eax, 2
		  mov ecx, 16
rep2:
		  movsw
		  add edi, eax
		  loop rep2
		  }
//	  	TRACE("%02X%02X%c%c\n", c, *strp, c, *strp);
	    i++;strp++;
		}
	  }
//	fclose(HZ_fp);
	return xsize;
}
#endif

#ifdef	ENGLISH
inline int CDDText::ReadData( LPCTSTR string, int nLen )
{
	return 0;
}
#endif

#ifdef	COMPLEX
inline int CDDText::ReadData( LPCTSTR string, int nLen )
{
	return 0;
}
#endif

#ifdef	JAPANESE
inline int CDDText::ReadData( LPCTSTR string, int len )
{
	SIZE bmpsize;
	BYTE *mybytes;
	mybytes=m_mybytes;
	bmpsize.cx = m_bmpsize.cx, bmpsize.cy = m_bmpsize.cy;
/*
	FILE *HZ_fp;
	HZ_fp=fopen("hzk\\jisexp.16", "rb");
	if( !HZ_fp ) return 0;
*/

	//Assert(HZ_fp);
	int xsize=len*CHAR_WIDTH;
	BYTE *strp=(BYTE*)string;
	for(int i=0;i<xsize/CHAR_WIDTH;i++){
	  BYTE c=*strp++;
	  if(c<(BYTE)0x80){
		fseek(HZ_fp, (3*0xbc+(BYTE)0xdc-(BYTE)0x41+c)*32, SEEK_SET);
	  	BYTE* off=mybytes+i;
		BYTE buf[32];
		BYTE* bufp=buf;
		fread(buf, 32, 1, HZ_fp);
		__asm{
		  lea esi, buf
		  mov edi, mybytes
		  add edi, i
		  lea eax, bmpsize
		  mov eax, [eax]	//load bmpsize.cx
		  shr eax, 3
		  sub eax, 2
		  mov ecx, 16
rep3:
		  movsw
		  add edi, eax
		  loop rep3
		  }
	    }
	  else if(c<(BYTE)0xdf && c>=(BYTE)0xa0){
		fseek(HZ_fp, (4*0xbc+(BYTE)0x9e-(BYTE)0x41+c-(BYTE)0xa0)*32, SEEK_SET);
	  	BYTE* off=mybytes+i;
		BYTE buf[32];
		BYTE* bufp=buf;
		fread(buf, 32, 1, HZ_fp);
		__asm{
		  lea esi, buf
		  mov edi, mybytes
		  add edi, i
		  lea eax, bmpsize
		  mov eax, [eax]	//load bmpsize.cx
		  shr eax, 3
		  sub eax, 2
		  mov ecx, 16
rep1:
		  movsw
		  add edi, eax
		  loop rep1
		  }
	    
	    i++;strp++;
	    }
	  else
	  if(c>=(BYTE)0x81 && c<=(BYTE)0xea 
	  		&& *strp>=(BYTE)0x40 && *strp!=(BYTE)0x7f && *strp<=(BYTE)0xfc){
	    fseek(HZ_fp, ((c-(c>=(BYTE)0xe0?0xc1:0x81))*0xbc+
	      *strp-(*strp>(BYTE)0x7f?0x41:0x40))*32, SEEK_SET);
	    
		WORD buf[16];
		fread(buf, 1, 32, HZ_fp);
		__asm{
		  lea esi, buf
		  mov edi, mybytes
		  add edi, i
		  lea eax, bmpsize
		  mov eax, [eax]	//load bmpsize.cx
		  shr eax, 3
		  sub eax, 2
		  mov ecx, 16
rep2:
		  movsw
		  add edi, eax
		  loop rep2
		  }
	    i++;strp++;
	    }
	  }
//	fclose(HZ_fp);
	return xsize;
}
#endif
/////////////////

/////////////////
// draw text
BOOL CDDText::MyTextOut(LPDIRECTDRAWSURFACE2 pSurface, int x, int y, LPCTSTR String)
{
	return MyTextOut(pSurface, x, y, String, strlen(String));
}

#ifdef	ENGLISH
// english
BOOL CDDText::MyTextOut(LPDIRECTDRAWSURFACE2 pSurface, int x, int y, LPCTSTR String, int len)
{
	HDC hdc=NULL;
	if( pSurface->GetDC( &hdc ) == DD_OK )
	{
		if( m_dwColorCaps==DDBLTFAST_SRCCOLORKEY )
			::SetBkMode( hdc, TRANSPARENT );
		else
		{
			::SetBkColor( hdc, RGB(0,0,0) );
			::SetBkMode( hdc, OPAQUE );
		}
		::SetTextColor( hdc, RGB(10,10,10) );
		::TextOut( hdc, x+2,y+2, String, len );
		::SetTextColor( hdc, m_textcolor );
		::TextOut( hdc, x, y, String, len );
		pSurface->ReleaseDC( hdc );
		return TRUE;
	}
	return FALSE;
}

#else
// other language
BOOL CDDText::MyTextOut(LPDIRECTDRAWSURFACE2 pSurface, int x, int y, LPCTSTR String, int len)
{
	if(!myhdc)	return FALSE;
	if( len<0 )	len = strlen( String );
	if( len>m_nCol ) len = m_nCol;

	// read data
	int xsize = ReadData( String, len );

	// draw to my surface
	//COLORREF color=::GetTextColor( hdc );
	HDC hdc=0;
	if( m_Face.GetSurface()->GetDC( &hdc ) == DD_OK )
	{
		RGBQUAD rgb[2]={{0,0,0,0}, 
			{GetBValue(m_textcolor),
			GetGValue(m_textcolor),
			GetRValue(m_textcolor),0}};
		::SetDIBColorTable(myhdc, 0, 2, (RGBQUAD*)rgb);
		::BitBlt(hdc, 0,0,xsize,m_bmpsize.cy,myhdc,0,0,SRCCOPY);
		m_Face.GetSurface()->ReleaseDC( hdc );
	}

	// draw to output surface
	RECT rect;
	rect.left=rect.top=0;
	if( m_rcClient.right < xsize )	rect.right=xsize;
	else							rect.right=m_rcClient.right;
	rect.bottom = m_bmpsize.cy;
	if( rect.right+x > SCREEN_WIDTH )	rect.right = SCREEN_WIDTH-x;
	if( rect.bottom+y > SCREEN_HEIGHT )	rect.bottom = SCREEN_HEIGHT-y;
	POINT pt;
	pt.x = x, pt.y = y;
	::DD_BltSurface( pt, pSurface, 
		&rect, m_Face.GetSurface(), m_dwColorCaps );
	m_Face.Erase();
/*
	if( pSurface->GetSurface()->GetDC( &hdc ) == DD_OK )
	{
		RGBQUAD rgb[2]={{0,0,0,0}, {GetBValue(color),GetGValue(color),GetRValue(color),0}};
		RGBQUAD rgb2[2]={{255,255,255,0},{0,0,0,0}};
		::SetDIBColorTable(myhdc, 0, 2, (RGBQUAD*)rgb2);
		::BitBlt(hdc, x,y,xsize,bmpsize.cy,myhdc,0,0,SRCAND);
		pSurface->GetSurface()->ReleaseDC( hdc );
	}
*/
	return TRUE;
}
#endif

BOOL CDDText::MyDrawText(LPDIRECTDRAWSURFACE2 pSurface, LPCTSTR String, int len, LPRECT prect, UINT nFormat)
{
	if(len<0)len=strlen(String);
	if(nFormat & DT_CENTER)
	  return(MyTextOut(pSurface, prect->left+(prect->right-prect->left-len*CHAR_WIDTH)/2,
	    prect->top+(prect->bottom-prect->top-CHAR_HEIGHT)/2,String, len));
	else 
	  return(MyTextOut(pSurface,0,0,String, len));
}

BOOL CDDText::MyDrawText(LPDIRECTDRAWSURFACE2 pSurface, LPCTSTR String, LPRECT prect, UINT nFormat)
{
	int len=strlen( String );
	if(nFormat & DT_CENTER)
	  return(MyTextOut(pSurface, prect->left+(prect->right-prect->left-len*CHAR_WIDTH)/2,
	    prect->top+(prect->bottom-prect->top-CHAR_HEIGHT)/2,String, len));
	else 
	  return(MyTextOut(pSurface,0,0,String));
}

#ifdef	ENGLISH
BOOL CDDText::PolyTextOut( LPDIRECTDRAWSURFACE2 pSurface, int x, int y, const char *String )
{
	if( !myhdc )	return FALSE;
	int	len = strlen( String );
	int xsize=0;

	char Str[1024], *pStr;
	strcpy( Str, String ); pStr=Str;
	int nCol = m_nCol; // chinese charactor number
	int nRow = len/nCol+1;
	if( nRow>m_nRow ) nRow = m_nRow;

	// read data
	COLORREF color=m_textcolor;
	HDC hdc=0;
	if( m_Face.GetSurface()->GetDC( &hdc ) == DD_OK )
	{
		int nCounter = len;
		int nLineCounter = 0;
		while( nCounter > 0 )
		{
			int nLineCol = nCol;
			if( nCounter < nCol )
			{
				nLineCol = nCounter;	// 不够满行
			}
			else
			{
				// 判断是否把一个词分开了
				while( *(pStr+nLineCol) != ' ' )
				{
					nLineCol--;
					if( nLineCol == 0 )
					{	// 如果没有空格,则断行写
						nLineCol = nCol;
						if( nCounter < nCol )
							nLineCol = nCounter;	// 不够满行
						break;
					}
				}
			}
			// my text
			if( m_dwColorCaps==DDBLTFAST_SRCCOLORKEY )
				::SetBkMode( hdc, TRANSPARENT );
			else
			{
				::SetBkColor( hdc, RGB(0,0,0) );
				::SetBkMode( hdc, OPAQUE );
			}
			::SetTextColor( hdc, RGB(10,10,10) );
			::TextOut( hdc, 2,nLineCounter*(CHAR_HEIGHT+m_nLineDist)+2, pStr, nLineCol );
			::SetTextColor( hdc, color );
			::TextOut( hdc, 0,nLineCounter*(CHAR_HEIGHT+m_nLineDist), pStr, nLineCol );
			pStr += nLineCol;
			nCounter -= nLineCol;
			nLineCounter ++;
			if( nLineCounter > nRow )
				break;
		}
		m_Face.GetSurface()->ReleaseDC( hdc );
	}

	// draw to output surface
	RECT rect;
	rect.left=rect.top=0;
	if( m_rcClient.right < xsize )	rect.right=xsize;
	else							rect.right=m_rcClient.right;
	rect.bottom = m_rcClient.bottom;
	if( rect.right+x > SCREEN_WIDTH )	rect.right = SCREEN_WIDTH-x;
	if( rect.bottom+y > SCREEN_HEIGHT )	rect.bottom = SCREEN_HEIGHT-y;
	POINT pt;
	pt.x = x, pt.y = y;
	::DD_BltSurface( pt, pSurface, 
		&rect, m_Face.GetSurface(), m_dwColorCaps );
	return TRUE;
}
#else
// for other languages
BOOL CDDText::PolyTextOut( LPDIRECTDRAWSURFACE2 pSurface, int x, int y, const char *String )
{
	if( !myhdc )	return FALSE;
	int	len = strlen( String );
	int xsize=0;

	char Str[1024], *pStr;
	strcpy( Str, String ); pStr=Str;
	int nCol = m_nCol; // chinese charactor number
	int nRow = len/nCol+1;
	if( nRow>m_nRow ) nRow = m_nRow;

	// read data
	COLORREF color=m_textcolor;
	HDC hdc=0;
	if( m_Face.GetSurface()->GetDC( &hdc ) == DD_OK )
	{
		for( int i=0; i< nRow; i++ )
		{
			int linelen = strlen( pStr )/nCol;
			if( linelen > 0 )	linelen = nCol;
			else				linelen = strlen(pStr)%nCol;
			xsize = ReadData( pStr, linelen );

			// draw to my surface
			RGBQUAD rgb[2]={{0,0,0,0}, {GetBValue(color),GetGValue(color),GetRValue(color),0}};
			::SetDIBColorTable(myhdc, 0, 2, (RGBQUAD*)rgb);
			::BitBlt(hdc, 0,i*(CHAR_HEIGHT+m_nLineDist),xsize,m_bmpsize.cy,
				myhdc,0,0,SRCCOPY);

			// read next line
			pStr += nCol;
		}
		m_Face.GetSurface()->ReleaseDC( hdc );
	}

	// draw to output surface
	RECT rect;
	rect.left=rect.top=0;
	if( m_rcClient.right < xsize )	rect.right=xsize;
	else							rect.right=m_rcClient.right;
	rect.bottom = m_rcClient.bottom;
	if( rect.right+x > SCREEN_WIDTH )	rect.right = SCREEN_WIDTH-x;
	if( rect.bottom+y > SCREEN_HEIGHT )	rect.bottom = SCREEN_HEIGHT-y;
	POINT pt;
	pt.x = x, pt.y = y;
	::DD_BltSurface( pt, pSurface, 
		&rect, m_Face.GetSurface(), m_dwColorCaps );
	return TRUE;
}
#endif


// 打开和关闭字库
int HZ_OpenLib( char *filename)
{
#ifdef	ENGLISH
	return 1;	// 对于英语无作用
#endif

	HZ_fp=fopen( filename, "rb");
	if( !HZ_fp ) return 0;
	return 1;
}
void HZ_CloseLib()
{
#ifdef	ENGLISH
	return;		// 对于英语无作用
#endif
	fclose( HZ_fp );
}

/////////////////

⌨️ 快捷键说明

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