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

📄 gp_avi.cpp

📁 圣剑二完整的游戏代码。附作者写的三篇文章。游戏的开发过程
💻 CPP
字号:
//********************************************
//	动画 相关函数
//  创建于2000年4月16日
//********************************************
#include <windows.h>
#include <ddraw.h>
#include <VFW.H>
#include "gp_init.h"
#include "gp_draw.h"
#include "gp_other.h"
#include "gp_avi.h"


//构造初始化
CAvi::CAvi()
{
	VideoStream=0;
	rawdata=NULL;
	VideoDataBuffer=NULL;
	decomp=0;

	AVIFileInit();
}

//打开音频流
void CAvi::OpenAudioStream(char *FileName)
{
	/*
	long res;

	if (AudioStream)
	{
		AVIStreamRelease(AudioStream);
		AudioStream = 0;
	}

	res = AVIStreamOpenFromFile(&AudioStream, FileName, streamtypeAUDIO, 0, OF_READ, 0);

	//成功
	if(res == 0)
	{
		res = AVIStreamFormatSize(AudioStream, 0, &fmtlen);
		if(res == 0 && fmtlen <= 16)
		{
			res = AVIStreamReadFormat(AudioStream, 0, &AudioSrcFmt, &fmtlen);
			if(res == 0)
			{
				if(AudioSrcFmt.wFormatTag==WAVE_FORMAT_PCM)
				{
					StartAudioFrame = AVIStreamStart(AudioStream);
					EndAudioFrame = AVIStreamEnd(AudioStream);
				
					AudioBufLen = (EndAudioFrame - StartAudioFrame) * AudioSrcFmt.nChannels * (AudioSrcFmt.wBitsPerSample/8);

					_RELEASE(lpAudioDataBuffer);
					if(CreateDirectSoundBuffer((LPBYTE)(&AudioSrcFmt), AudioBufLen, &lpAudioDataBuffer))
					{
						{
						    LPVOID		lpvPtr1; 
							DWORD		dwBytes1; 
							LPVOID		lpvPtr2; 
							DWORD		dwBytes2; 
							HRESULT		hres;

							hres = lpAudioDataBuffer->SetCurrentPosition(0);
							hres = lpAudioDataBuffer->Lock(0, AudioBufLen, &lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2, 0);

						    if(DSERR_BUFFERLOST == hres) 
							{
								lpAudioDataBuffer->Restore();
								hres = lpAudioDataBuffer->Lock(0, AudioBufLen, &lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2, 0);
							}

							if(DS_OK == hres) 
							{
								res = AVIStreamRead(AudioStream, StartAudioFrame, EndAudioFrame - StartAudioFrame, lpvPtr1, AudioBufLen, 0, 0);
								hres = lpAudioDataBuffer->Unlock(lpvPtr1, dwBytes1, lpvPtr2, dwBytes2);
							}
						}
					}
				}
			}
		}
	}
	if (AudioStream)
	{
		AVIStreamRelease(AudioStream);
		AudioStream = 0;
	}
	*/
}

//打开视频流文件
int CAvi::OpenVideoStream(char *FileName)
{	
	long res;

	LPBITMAPINFOHEADER	lpsrcfmt = (LPBITMAPINFOHEADER)VideoSrcFmt;
	LPBITMAPINFOHEADER	lpdstfmt = (LPBITMAPINFOHEADER)VideoDstFmt;

	//关闭先前打开的AVI文件流
	if( VideoStream )
	{
		AVIStreamRelease(VideoStream);
		VideoStream = 0;
	}

	//打开新的文件流
	res = AVIStreamOpenFromFile(&VideoStream, FileName, streamtypeVIDEO, 0, OF_READ, 0);

	//成功
	if(res == 0)
	{
		res = AVIStreamFormatSize(VideoStream, 0, &fmtlen);	//获取格式长度
		if(res == 0 && fmtlen <= 40)
		{
			//读取视频流格式
			res = AVIStreamReadFormat(VideoStream, 0, VideoSrcFmt, &fmtlen);
			if(res == 0)
			{
				//参数
				VideoWidth = lpsrcfmt->biWidth;
				VideoHeight = lpsrcfmt->biHeight;
				VideoBits = lpsrcfmt->biBitCount;

				//开始桢和结束桢
				StartVideoFrame = AVIStreamStart(VideoStream);
				EndVideoFrame = AVIStreamEnd(VideoStream);

				//目标流结构
				memcpy(VideoDstFmt, VideoSrcFmt, fmtlen);
				lpdstfmt->biBitCount = 32;
				lpdstfmt->biCompression = BI_RGB;
				lpdstfmt->biSizeImage = VideoWidth * VideoHeight * 4;

				if(VideoWidth <= ScreenWidth && VideoHeight <= ScreenHeight )
				{
					//获取一些视频的信息
					res = AVIStreamInfo(VideoStream, &VideoStreamInfo, sizeof(VideoStreamInfo));
					if(res == 0)
					{
						VideoBufLen = lpdstfmt->biSizeImage;
						VideoRate = VideoStreamInfo.dwRate;
						VideoScale = VideoStreamInfo.dwScale;

						//得到一个解压句柄
						if(decomp)
						{
							ICClose(decomp);
						}
						decomp = ICDecompressOpen(ICTYPE_VIDEO, VideoStreamInfo.fccHandler, lpsrcfmt, lpdstfmt);

						if(decomp==0)
						{
							ShowMessage("Can't create a ICDecompress for Avi file %s", FileName);
							return false;
						}
					}

					if( rawdata != NULL )
					{
						delete []rawdata;
					}
					rawdata=new DWORD[VideoBufLen];

					if( VideoDataBuffer != NULL )
					{
						delete []VideoDataBuffer;
					}
					VideoDataBuffer=new DWORD[VideoBufLen];

					return true;
				}
			}
		}
	}
	ShowMessage("Error open Avi file %s", FileName );
	return FALSE;
}

/*--------------------------------------*/

void CAvi::LoadVideoFrame(long num)
{
	long res;
	LPBITMAPINFOHEADER	lpsrcfmt = (LPBITMAPINFOHEADER)VideoSrcFmt;
	LPBITMAPINFOHEADER	lpdstfmt = (LPBITMAPINFOHEADER)VideoDstFmt;

	res = AVIStreamRead(VideoStream, num, 1, rawdata, VideoBufLen, 0, 0);
	ICDecompress(decomp, 0, lpsrcfmt, rawdata, lpdstfmt, VideoDataBuffer);
}

/*--------------------------------------*/

int CAvi::OpenVideoFile(char *FileName)
{
	if(OpenVideoStream(FileName))
	{
	//	OpenAudioStream(FileName);
		return TRUE;
	}
	return FALSE;
}

/*--------------------------------------*/

void CAvi::CloseVideoFile(void)
{	
//	_RELEASE(lpAudioDataBuffer);

	if(decomp)
	{
		ICClose(decomp);
		decomp = NULL;
	}

	/*
	if(AudioStream)
	{
		AVIStreamRelease(AudioStream);
		AudioStream = NULL;
	}
	*/

	if(VideoStream)
	{
		AVIStreamRelease(VideoStream);
		VideoStream = NULL;
	}
}

/*--------------------------------------*/

void CAvi::FilpWholeVideoBuffer(void)		// filp video image
{
	WORD *Dest;
	
	//取页面指针
	if( BeginDraw(lpDDSBack) )
	{
		Dest=(WORD *)GraphBuffer;
		EndDraw(lpDDSBack);
	}
	
	for( int i=0; i<VideoHeight; i++)
		for( int j=0; j<VideoWidth; j++)
		{
			Dest[ScreenWidth*i+j]=RGB16(VideoDataBuffer[VideoWidth*(VideoHeight-i)+j]);
		}

	/*
	for( int j=0; j<VideoHeight; j++)
	{
		memcpy(&Dest[ScreenWidth*j], &VideoDataBuffer[VideoWidth*(VideoHeight-j)], VideoWidth*2);
	}
	*/

	/*
	LPDWORD		lpSrc = (LPDWORD)VideoDataBuffer + VideoWidth * (VideoHeight - 1);
	DWORD		LineOff = (ScreenWidth - VideoWidth) / 2 * 4;
	DWORD		LineOff2 = VideoWidth * 4 * 2;
	DWORD		HighOff = (ScreenHeight - VideoHeight) * ScreenWidth / 2 * 4;

	_asm {
		MOV		ESI, lpSrc
		MOV		EDI, lpRenderBuffer
		ADD		EDI, HighOff

		MOV		EDX,VideoHeight

ExpandVideoBuffer_LoopY:
		ADD		EDI, LineOff

		MOV		ECX, VideoWidth
		REP		MOVSD

		ADD		EDI, LineOff

		SUB		ESI,LineOff2

		DEC		EDX
		JNZ		ExpandVideoBuffer_LoopY
	}
	*/
}

/*--------------------------------------*/
void CAvi::RefreshScreen(void)
{
}

void CAvi::PlayAVIFile(char *FileName)
{
	long		frame;
	long		time1, time2, time3;
    MSG			msg;
	double		temp;

	if(OpenVideoFile(FileName)==FALSE) return;

	frame = StartVideoFrame;

//	ClearRenderBuffer(0);

	time1 = timeGetTime();
	time2 = time1;
	time3 = 0;

	VideoPlayingFlag = TRUE;

	do
	{
        if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
        {
            if (!GetMessage(&msg, NULL, 0, 0)) return;// msg.wParam;
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
		else
		{
	        if(bActive)
		    {
				if(time3 > 0)
				{
					time2 += time3;
					time3 = 0;
				}

				time1 = timeGetTime();
				temp= (frame - StartVideoFrame) * VideoScale * 1000.0 / VideoRate;
				if((time1 - time2) >= (long)temp)
				{
					LoadVideoFrame(frame);
					frame++;
					if(frame >= EndVideoFrame)
					{
						VideoPlayingFlag = FALSE;
					}
					
					/*
					if(frame <= StartVideoFrame+1)
					{
						if(lpAudioDataBuffer)
							lpAudioDataBuffer->Play(NULL, NULL, 0);
					}
					*/

					FilpWholeVideoBuffer();
					//ShowMessage("continue");
				}
				_UpdateScreen();		//更新屏幕
			}
			else
			{
				time3 = timeGetTime() - time1;
			}
		}
	}	while(VideoPlayingFlag);

	CloseVideoFile();

	return;
}

/*--------------------------------------*/

void CAvi::LoopPlayAVIFile(char *FileName)
{
	long		frame;
	long		time1, time2, time3;
    MSG			msg;
	double		temp;

	if(OpenVideoFile(FileName)==FALSE) return;

	frame = StartVideoFrame;

//	ClearRenderBuffer(0);

	time1 = timeGetTime();
	time2 = time1;
	time3 = 0;

	VideoPlayingFlag = TRUE;

	do
	{
        if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
        {
            if (!GetMessage(&msg, NULL, 0, 0)) return;// msg.wParam;
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
		else
		{
	        if(bActive)
		    {
				if(time3 > 0)
				{
					time2 += time3;
					time3 = 0;
				}

				time1 = timeGetTime();
				temp= (frame - StartVideoFrame) * VideoScale * 1000.0 / VideoRate;
				if((time1 - time2) >= (long)temp)
				{
					LoadVideoFrame(frame);
					frame++;
					if(frame >= EndVideoFrame)
					{
						frame = StartVideoFrame;
						time1 = timeGetTime();
						time2 = time1;
						time3 = 0;

						if(lpAudioDataBuffer)
						{
							lpAudioDataBuffer->Stop();
							lpAudioDataBuffer->SetCurrentPosition(0);
							lpAudioDataBuffer->Play(NULL, NULL, 0);
						}
					}

					if(frame <= StartVideoFrame+1)
					{
						if(lpAudioDataBuffer)
							lpAudioDataBuffer->Play(NULL, NULL, 0);
					}
//SetRenderPage(BACKPAGE);
					FilpWholeVideoBuffer();
//SetRenderPage(MAINPAGE);
				}
//AddRipple(rand()%RENDER_WIDTH, rand()%RENDER_HEIGHT, 3,rand()&0x1FF);
//RippleSpread();
//RenderRipple();
				RefreshScreen();
			}
			else
			{
				time3 = timeGetTime() - time1;
			}
		}
	}	while(VideoPlayingFlag);

	CloseVideoFile();
	return;
}

⌨️ 快捷键说明

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