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

📄 direct~2.cpp

📁 一个简单的rpg游戏
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		else
			ncolors=bmpinfohdr.biClrUsed;

		RGBQUAD* quad=new RGBQUAD[ncolors];
		bmp.read( (char*)quad, sizeof(RGBQUAD)*ncolors );
		if (installpalette)
			CreatePalette( quad, ncolors );
		delete [] quad;
	}

	BYTE* buf=new BYTE[imagesize];
	bmp.read( buf, imagesize );

	if (!Copy_Bmp_Surface( surf, &bmpinfohdr, buf ))
	{
		TRACE("copy failed\n");
		delete [] buf;
		surf->Release();
		return 0;
	}

	delete [] buf;

	return surf;
}

LPDIRECTDRAWSURFACE DirectDrawWin::CreateSurface( DWORD w, DWORD h )
{
	DWORD bytes=w*h*(displaydepth/8);

	DDSURFACEDESC desc;
	ZeroMemory( &desc, sizeof(desc) );
	desc.dwSize = sizeof(desc);
	desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
	desc.dwWidth = w;
	desc.dwHeight = h;
	desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;

	LPDIRECTDRAWSURFACE surf;
	HRESULT r=ddraw2->CreateSurface( &desc, &surf, 0 );
	if (r==DD_OK)
	{
		TRACE("CreateSurface(%d,%d) created in video memory (%d bytes)\n", w, h, bytes);
		return surf;
	}

	desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
	r=ddraw2->CreateSurface( &desc, &surf, 0 );
	if (r==DD_OK)
	{
		TRACE("CreateSurface(%d,%d) allocated in system memory (%d bytes)\n", w, h, bytes);
		return surf;
	}

	TRACE("CreateSurface(%d,%d) failed\n", w, h);
	return 0;
}


DirectDrawWin::DirectDrawWin()
{
	thisptr=this;

	totaldrivers=0;
	totaldisplaymodes=0;
	curdisplaymode=-1;

	ddraw2=0;
	primsurf=0;
	backsurf=0;
	palette=0;

	window_active=TRUE;


    DirectDrawApp* pApp = (DirectDrawApp*)AfxGetApp();
    pApp->ddwin = this;
}

HRESULT WINAPI DirectDrawWin::DisplayModeAvailable( LPDDSURFACEDESC desc, LPVOID p )
{
	DirectDrawWin* win=(DirectDrawWin*)p;

	int& count=win->totaldisplaymodes;
	if (count==MAXDISPLAYMODES)
		return DDENUMRET_CANCEL;

	win->displaymode[count].width  = desc->dwWidth;
	win->displaymode[count].height = desc->dwHeight;
	win->displaymode[count].depth  = desc->ddpfPixelFormat.dwRGBBitCount;

	count++;

	return DDENUMRET_OK;
}

BOOL WINAPI DirectDrawWin::DriverAvailable(LPGUID guid, LPSTR desc, LPSTR name, LPVOID p )
{
	DirectDrawWin* win=(DirectDrawWin*)p;

	if (win->totaldrivers >= MAXDRIVERS)
		return DDENUMRET_CANCEL;

	DriverInfo& info=win->driver[win->totaldrivers];

	if (guid)
	{
		info.guid=(GUID*)new BYTE[sizeof(GUID)];
		memcpy( info.guid, guid, sizeof(GUID) );
	}
	else
		info.guid=0;

	info.desc=strdup( desc );
	info.name=strdup( name );

	win->totaldrivers++;

    return DDENUMRET_OK;
}

BOOL DirectDrawWin::GetBmpDimensions( LPCTSTR filename, int& w, int& h)
{
	ifstream bmp( filename, ios::binary | ios::nocreate );
	if (!bmp.is_open())
	{
		TRACE("GetBmpDimensions: cannot open file\n");
		return FALSE;
	}

	BITMAPFILEHEADER bmpfilehdr;
	bmp.read( (char*)&bmpfilehdr, sizeof(bmpfilehdr) );

	char* ptr=(char*)&bmpfilehdr.bfType;
	if (*ptr!='B' || *++ptr!='M')
	{
		TRACE("GetBmpDimensions: invalid bitmap\n");
		return FALSE;
	}

	BITMAPINFOHEADER bmpinfohdr;
	bmp.read( (char*)&bmpinfohdr, sizeof(bmpinfohdr) );

	w=bmpinfohdr.biWidth;
	h=bmpinfohdr.biHeight;

	return TRUE;
}

BOOL DirectDrawWin::GetDisplayModeDimensions( int mode, DWORD& width, DWORD& height, DWORD& depth )
{
	if ( mode < 0 || mode > totaldisplaymodes )
		return FALSE;

	width  = displaymode[mode].width;
	height = displaymode[mode].height;
	depth  = displaymode[mode].depth;

	return TRUE;
}

int DirectDrawWin::GetDisplayModeIndex( DWORD w, DWORD h, DWORD d )
{
	for (int i=0;i<totaldisplaymodes;i++)
	{
		DisplayModeInfo& m=displaymode[i];
		if (m.width==w && m.height==h && m.depth==d)
			return i;
	}
	return -1;
}

BOOL DirectDrawWin::GetDriverInfo( int index, LPGUID* guid, LPSTR* desc, LPSTR* name )
{
	if (index<0 || index>totaldrivers)
		return FALSE;

	if (name)
		*name=driver[index].name;
	if (desc)
		*desc=driver[index].desc;
	if (guid)
		*guid=driver[index].guid;

	return TRUE;
}

BOOL DirectDrawWin::GetSurfaceDimensions( LPDIRECTDRAWSURFACE surf, DWORD& w, DWORD& h )
{
	if (surf==0)
		return FALSE;

	DDSURFACEDESC desc;
	ZeroMemory( &desc, sizeof(desc) );
	desc.dwSize=sizeof(desc);
	desc.dwFlags=DDSD_WIDTH | DDSD_HEIGHT;

	if (surf->GetSurfaceDesc( &desc )!=DD_OK)
		return FALSE;

	w=desc.dwWidth;
	h=desc.dwHeight;

	return TRUE;
}

BOOL DirectDrawWin::GetSurfaceRect( LPDIRECTDRAWSURFACE surf, RECT& rect)
{
	if (surf==0)
		return FALSE;

	DDSURFACEDESC desc;
	desc.dwSize=sizeof(desc);
	desc.dwFlags=DDSD_WIDTH | DDSD_HEIGHT;

	if (surf->GetSurfaceDesc( &desc )!=DD_OK)
		return FALSE;

	rect.left=0;
	rect.top=0;
	rect.right=desc.dwWidth;
	rect.bottom=desc.dwHeight;

	return TRUE;
}

WORD DirectDrawWin::HighBitPos( DWORD dword )
{
	DWORD test=1;
	test<<=31;
	for (WORD i=0;i<32;i++)
	{
		if ( dword & test )
			return (WORD)(31-i);
		test>>=1;
	}
	return 0;
}

BOOL DirectDrawWin::LoadSurface( LPDIRECTDRAWSURFACE surf, LPCTSTR filename)
{
	ifstream bmp( filename, ios::binary | ios::nocreate );
	if (!bmp.is_open())
	{
		TRACE("LoadSurface: cannot open Bmp file\n");
		return FALSE;
	}

	BITMAPFILEHEADER bmpfilehdr;
	bmp.read( (char*)&bmpfilehdr, sizeof(bmpfilehdr) );

	char* ptr=(char*)&bmpfilehdr.bfType;
	if (*ptr!='B' || *++ptr!='M')
	{
		TRACE("LoadSurface: invalid bitmap\n");
		return FALSE;
	}
	
	BITMAPINFOHEADER bmpinfohdr;
	bmp.read( (char*)&bmpinfohdr, sizeof(bmpinfohdr) );
	bmp.seekg( sizeof(bmpfilehdr)+bmpinfohdr.biSize, ios::beg );

	int imagew=bmpinfohdr.biWidth;
	int imageh=bmpinfohdr.biHeight;
	int imagebitdepth=bmpinfohdr.biBitCount;

	int imagesize=bmpinfohdr.biSizeImage;
	if (imagesize==0)
		imagesize=((imagew*(imagebitdepth/8)+3) & ~3)*imageh;

	if (bmpinfohdr.biCompression!=BI_RGB)
	{
		TRACE("compressed BMP format\n");
		return 0;
	}

	TRACE("loading '%s': width=%d height=%d depth=%d\n", filename, imagew, imageh, imagebitdepth);

	if (imagebitdepth==8)
	{
		// skip over palette info...
		int ncolors = (bmpinfohdr.biClrUsed==0) ? 256 : bmpinfohdr.biClrUsed;
		bmp.seekg( sizeof(RGBQUAD)*ncolors, ios::cur );
	}

	BYTE* buf=new BYTE[imagesize];
	bmp.read( buf, imagesize );

	if (!Copy_Bmp_Surface( surf, &bmpinfohdr, buf ))
	{
		TRACE("copy failed\n");
		delete [] buf;
		return 0;
	}

	delete [] buf;

	return TRUE;
}

WORD DirectDrawWin::LowBitPos( DWORD dword )
{
	DWORD test=1;
	for (WORD i=0;i<32;i++)
	{
		if ( dword & test )
			return i;
		test<<=1;
	}
	return 0;
}

void DirectDrawWin::OnActivateApp(BOOL bActive, HTASK hTask) 
{
	CWnd::OnActivateApp(bActive, hTask);

	window_active = bActive;
}

int DirectDrawWin::OnCreate(LPCREATESTRUCT)
{
	DirectDrawEnumerate( DriverAvailable, this );

	if (totaldrivers==0)
	{
		AfxMessageBox("No DirectDraw drivers detected");
		return -1;
	}

	// insure the first entry is the primary display driver
	if (driver[0].guid!=0 && totaldrivers>1)
	{
		for (int i=1;i<totaldrivers;i++)
			if (driver[i].guid==0)
			{
				DriverInfo tmp;

				tmp.guid=0;
				tmp.desc=driver[i].desc;
				tmp.name=driver[i].name;

				driver[i].guid=driver[0].guid;
				driver[i].desc=driver[0].desc;
				driver[i].name=driver[0].name;

				driver[0].guid=0;
				driver[0].desc=tmp.desc;
				driver[0].name=tmp.name;
			}
	}

	int driverindex=SelectDriver();
	if (driverindex<0)
	{
		TRACE("No DirectDraw driver selected\n");
		return -1;
	}
	else if (driverindex>totaldrivers-1)
	{
		AfxMessageBox("Invalid DirectDraw driver selected\n");
		return -1;
	}

	LPDIRECTDRAW ddraw1;
	//DirectDrawCreate( driver[driverindex].guid, &ddraw1, 0 );
	DirectDrawCreate( NULL, &ddraw1, 0 );
	HRESULT r;
	r=ddraw1->QueryInterface( IID_IDirectDraw2, (void**)&ddraw2 );
	if (r!=S_OK)
	{
		AfxMessageBox("DirectDraw2 interface not supported");
		return -1;
	}
	ddraw1->Release(), ddraw1=0;

	ddraw2->SetCooperativeLevel( GetSafeHwnd(), DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX );

	ddraw2->EnumDisplayModes( 0, 0, this, DisplayModeAvailable );
	qsort( displaymode, totaldisplaymodes, sizeof(DisplayModeInfo), CompareModes );
	
	CDC* dc=GetDC();
	displaydepth=dc->GetDeviceCaps( BITSPIXEL );
	displayrect.left=0;
	displayrect.top=0;
	displayrect.right=dc->GetDeviceCaps( HORZRES );
	displayrect.bottom=dc->GetDeviceCaps( VERTRES );
	dc->DeleteDC();	

	int initmode=SelectInitialDisplayMode();
	if (ActivateDisplayMode( initmode )==FALSE)
		return -1;

	return 0;
}

void DirectDrawWin::OnDestroy()
{
	if (primsurf)
		primsurf->Release(), primsurf=0;

	if (palette)
		palette->Release(), palette=0;

	if (ddraw2)
		ddraw2->Release(), ddraw2=0;

	for (int i=0;i<totaldrivers;i++)
	{
		if (driver[i].guid)
			delete [] driver[i].guid;
		free( driver[i].desc );
		free( driver[i].name );
	}
}

BOOL DirectDrawWin::OnEraseBkgnd(CDC* pDC) 
{
	CBrush br( RGB(0,0,0) );
	CRect rc;
	CWnd::GetClientRect( &rc );
	pDC->FillRect( &rc, &br );

	return TRUE;
}

void DirectDrawWin::OnMouseMove( UINT state, CPoint point )
{
	mousestate = state;
	mousex = point.x;
	mousey = point.y;
}

BOOL DirectDrawWin::PreDrawScene()
{
	if (window_active && primsurf->IsLost())
	{
		HRESULT r;
		r=primsurf->Restore();
		if (r!=DD_OK)
			TRACE("can't restore primsurf\n");

		if (backsurf)
		{
			r=backsurf->Restore();
			if (r!=DD_OK)
				TRACE("can't restore backsurf\n");
		}

		RestoreSurfaces();
	}

	return window_active;
}

void DirectDrawWin::PrintSurfaceInfo(LPDIRECTDRAWSURFACE surf, LPCTSTR name)
{
	ASSERT(surf);
	ASSERT(name);

	DDSURFACEDESC desc;
	ZeroMemory( &desc, sizeof(desc) );
	desc.dwSize=sizeof(desc);
	surf->GetSurfaceDesc( &desc );
	
	TRACE("Description for surface '%s':\n", name );

	if (desc.ddsCaps.dwCaps & DDSCAPS_COMPLEX)
		TRACE("  Complex\n");

	if (desc.ddsCaps.dwCaps & DDSCAPS_FLIP)
		TRACE("  Flipable\n");

	if (desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
		TRACE("  Primary surface\n");

	if (desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER)
		TRACE("  Front buffer\n");

	if (desc.ddsCaps.dwCaps & DDSCAPS_BACKBUFFER)
		TRACE("  Back buffer\n");
	
	if (desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)
		TRACE("  Video memory\n");

	if (desc.ddsCaps.dwCaps & DDSCAPS_LOCALVIDMEM)
		TRACE("  Local Video memory\n");
	
	if (desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)
		TRACE("  System memory\n");

	if (desc.ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN)
		TRACE("  Offscreen/plain\n");

	if (desc.ddsCaps.dwCaps & DDSCAPS_MODEX)
		TRACE("  Mode X\n");
}

DWORD DirectDrawWin::RGBtoPixel(DWORD r, DWORD g, DWORD b)
{
	if (displaydepth==8 && palette)
	{
		static PALETTEENTRY pal[256];
		palette->GetEntries( 0, 0, 256, pal);
		DWORD bestmatch=0;
		DWORD bestscore=30000;
		for (int i=0;i<256;i++)
		{
			DWORD pr=pal[i].peRed;
			DWORD pg=pal[i].peGreen;
			DWORD pb=pal[i].peBlue;

			DWORD rdif = abs((int)(pr - r));
			DWORD gdif = abs((int)(pg - g));
			DWORD bdif = abs((int)(pb - b));

			DWORD score=rdif+gdif+bdif;
			if (score==0)
				return i;
			if (score<bestscore)
			{
				bestscore=score;
				bestmatch=i;
			}
		}
		return bestmatch;
	}
	else if (displaydepth==16)
	{
		int REDdiv=256/(int)pow( 2, numREDbits );
		int GREENdiv=256/(int)pow( 2, numGREENbits );
		int BLUEdiv=256/(int)pow( 2, numBLUEbits );
	
		float rf=(float)r/(float)REDdiv;
		float gf=(float)g/(float)GREENdiv;
		float bf=(float)b/(float)BLUEdiv;

		DWORD rt=((DWORD)rf<<loREDbit);
		DWORD gt=((DWORD)gf<<loGREENbit);
		DWORD bt=((DWORD)bf<<loBLUEbit);

		return rt|gt|bt;
	}
	else if (displaydepth==24 || displaydepth==32)
		return (r<<loREDbit) | (g<<loGREENbit) | (b<<loBLUEbit);

	return 0;
}

BOOL DirectDrawWin::SaveSurface(LPDIRECTDRAWSURFACE surf, LPCTSTR filename)
{
	DDSURFACEDESC desc;
	ZeroMemory( &desc, sizeof(desc) );
	desc.dwSize = sizeof(desc);
	desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
	surf->GetSurfaceDesc( &desc );

	DWORD width  = desc.dwWidth;
	DWORD height = desc.dwHeight;
	DWORD depth  = desc.ddpfPixelFormat.dwRGBBitCount;

	BITMAPFILEHEADER filehdr;
	BITMAPINFOHEADER infohdr;
	RGBQUAD quads[256];
	PALETTEENTRY pe[256];

	ZeroMemory( &filehdr, sizeof(filehdr) );
	*((char*)&filehdr.bfType)='B';
	*(((char*)&filehdr.bfType)+1)='M';
	filehdr.bfOffBits=sizeof(filehdr)+sizeof(infohdr);
	
	if (depth==8)
		filehdr.bfOffBits+=sizeof(quads);

	ZeroMemory( &infohdr, sizeof(infohdr) );
	infohdr.biSize=sizeof(infohdr);
	infohdr.biWidth    = width;
	infohdr.biHeight   = height;
	infohdr.biPlanes   = 1;
	infohdr.biBitCount = depth==8 ? 8 : 24;
	infohdr.biCompression=BI_RGB;
	infohdr.biSizeImage = 0;
	if (depth==8)
		infohdr.biClrUsed = 256;
	else
		infohdr.biClrUsed = 0;

	LPDIRECTDRAWPALETTE palette;

⌨️ 快捷键说明

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