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

📄 vesavcd.c

📁 超级解霸源代码。纯c语言写的。适合有一定编程基础的开发人员用来学习提高
💻 C
📖 第 1 页 / 共 5 页
字号:
//////////////////////////////////////////////////////////
//			Soft VCD Player
//	These code MUST Compiler by BC3.1,Not others.
//	SMALL Mode,386 Instructions,DOS Stack Code,
//		    FASTEST Optimizations.
//	  Main Program with Video Control & WndProc.
//			Southern.Liang
//			  1996.5.25
//////////////////////////////////////////////////////////
#pragma	option	-zCOTHER_TEXT
#include <windows.h>
#include <mmsystem.h>
#include "DOS.H"
#include "DCI.H"
#include "VCDAPI.H"

#define	WM_DEBUG	WM_USER+800
#define	WM_CDROMOPEN	WM_USER+890
#define	VIDEONUMBER	30
//////////////// New feature Message ///////////////
#define	WM_RESUME	WM_USER+900
#define	WM_STEPVIDEO	WM_USER+901
#define	WM_STOPVIDEO	WM_USER+902
#define	WM_CUTPICTURE	WM_USER+903
#define	WM_STATEDISPLAY	WM_USER+904
#define	WM_PLAYNEXTFILE	WM_USER+905
#define	WM_PLAYPREVFILE	WM_USER+906

////////////////////////////////////
void huge TurnOffEscape(void);
void huge TurnOnEscape(void);
////////////////////Screen/////////////////
#define DAC_WRITE_ADDR  0x3C8   // VGA DAC Write Addr Register
#define DAC_READ_ADDR   0x3C7   // VGA DAC Read Addr Register
#define PEL_DATA_REG    0x3C9   // VGA DAC/PEL data Register R/W
static	void    ReadDAC(void far *DAC,WORD Start,WORD Number)
{
	// Determine register #'s, size to copy, etc
	asm     les     DI, dword ptr DAC       // ES:DI -> Palette Buffer
	asm     mov     DX, DAC_READ_ADDR       // DAC register # selector
	asm     mov     AX, Start       // Get Start Register
	asm     mov     BX, Number      // BX = # of DAC registers
	asm     mov     CX, BX          // CX = # of DAC registers
	asm     add     CX, BX          // CX =  "   " * 2
	asm     add     CX, BX          // CX =  "   " * 3
	asm     cld                     // Block INs forward
	// Read a block of DAC Registers
	asm     out     DX, AL          // set up correct register #
	asm     mov     DX, PEL_DATA_REG// Dac Data Register
	asm     rep     insb            // block read DAC registers
}
static	void    LoadDAC(void far *DAC,WORD Start,WORD Number)
{
	asm     push    ds
	Wait:
	asm	mov	dx,0x3DA
	asm	in	al,dx
	asm	test	al,8
	asm	jz	short	Wait
	asm	mov	dx,0x3C6
	asm	mov	al,0xFF
	asm	out	dx,al
	asm     lds     SI,dword ptr DAC	// DS:SI -> Palette Data
	asm     mov     DX, DAC_WRITE_ADDR	// DAC register # selector
	asm     mov     BX, Number		// Get Number Register
	asm	mov	cx, Start
	asm     cld			// Block OUTs forward
	LOOPOUT:
	asm	mov	al,cl
	asm     out     DX,AL		// set up correct register #
	asm	inc	dx
	asm     outsb			// block set DAC registers
	asm	outsb
	asm	outsb
	asm	dec	dx
	asm	inc	cx
	asm	cmp	cx,bx
	asm	jbe	short	LOOPOUT
	asm     pop     ds
}
BYTE    Palette[256*3];
void PASCAL FAR	ComputePalette(void)
{
	int	i;
	for(i=0;i<256;i++)
		Palette[i*3+2]=Palette[i*3+1]=Palette[i*3]=i/4;
}
static	void	ReadAllDAC(void)
{
	ReadDAC(Palette,0,256);
}
static	void	SetAllDAC(void)
{	int	i;
	//LoadDAC(Palette,0,256);//This Load too fast on some fast machine error.
	outportb(0x3C6,0xFF);
	outportb(0x3C8,0);
	for(i=0;i<256*3;i++)	//Load Slowly make on fast machine success.
		outportb(0x3C9,Palette[i]);
	outport(0x3C4,0x0003);
}
///////////////////////////////////////////
void FAR PASCAL Death(HDC hdc);
void FAR PASCAL Resurrection(HDC hdc,WORD,WORD,WORD,WORD,WORD,WORD);
int	VESASupportFlags=0;
int	VESAColor=0;
HDC	DeathhDC;
int	Old3CF6;
void	RestoreVideoState(void);
static	void	NormalWindow(void)
{
	int 	Port;
	//////// Restore Old ////////
	outportb(0x3CE,0x06);
	outportb(0x3CF,Old3CF6);	//128K Screen Buffer
	//////////////////
	_AX=3;
	geninterrupt(0x10);		//This is very importion
	RestoreVideoState();
	//////////////////
	_AX=3;
	geninterrupt(0x10);		//This is very importion
	//////////////////////////////////
	Resurrection(DeathhDC,0,0,0,0,0,0);
	ReleaseDC(NULL,DeathhDC);
	ShowCursor(1);
	InvalidateRect(NULL,NULL,0);
}
extern	int	VideoCardType;
extern	int	SubType;
extern	DWORD	VideoPhysBase;
int	BankingFlags=0;		//No 128K Buffer use banking.
int	OtherDecoder=0;		//Use internal MPEG decoder.
char	OtherDecoderName[24];
void	SetVideoBufferBase(DWORD Base);
int	LinearFlags=0;
extern	WORD	Linear;
static	int	TestNo128KVideo(void)
{
	int	Ret;
	WORD	Selector;
	DWORD	Limit;
	DWORD 	far *Ptr;
	DWORD	Data,tmp;
	if(LinearFlags==0) return 1;	//No 128K
	//Screen Buffer as B800 Segment.
	asm	mov	es,Linear
	_EDI=0x18000;
	__emit__(0x26,0x67,0x66,0x8B,0x07);//asm  mov	eax,es:[edi]
	__emit__(0x66,0x26,0x67,0x83,0x37,0xFF);//asm 	xor es:[edi],0xFFFFFFFF
	__emit__(0x26,0x67,0x66,0x3B,0x07);//asm  cmp	eax,es:[edi]
	__emit__(0x26,0x67,0x66,0x89,0x07);//asm  mov	es:[edi],eax
	asm	je	ROM
	return 	0;
	ROM:
	return  1;
}
int	GetBankSize(int Mode);
int	BankSize=1;	//K
int	BankGranUnit=64;
void	SaveVideoState(void);
void	PASCAL	FAR	GetBankingWay(void)
{
	outportb(0x3CE,0x06);outportb(0x3CF,Old3CF6);//64K Screen Buffer
	if(VideoCardType==0)
		BankGranUnit=GetBankSize(VESAColor==16 ? 0x10E:0x10D);
	else BankGranUnit=GetBankSize(0x101);
	if(BankGranUnit==0) BankGranUnit=64;
	BankSize=64/BankGranUnit;
	if(BankSize==0) BankSize=1;
}
static	void	Set320x20064KC(void)
{
	ShowCursor(0);
	DeathhDC=GetDC(NULL);
	Death(DeathhDC);
	////////////////
	SaveVideoState();
	////////////////
	_AX=0x13;	//Some VGA card must call this first.
	geninterrupt(0x10);	//In Graphics mode first.
	///////////////////////////
	if(VideoCardType==0)
		{//VESA Support
		if(VESAColor==64)
			{//640x480 64KC
			_BX=0x111;
			_AX=0x4F02;
			geninterrupt(0x10);
			}
		if(VESAColor==32)
			{//640x480 32KC
			_BX=0x110;
			_AX=0x4F02;
			geninterrupt(0x10);
			}
		if(VESAColor==16)//64K Color
			{
			_BX=0x10E;
			_AX=0x4F02;
			geninterrupt(0x10);
			}
		if(VESAColor==15)//32K Color
			{
			_BX=0x10D;
			_AX=0x4F02;
			geninterrupt(0x10);
			}
		if(VESAColor==8)//256 Color
			{
			_AX=0x13;
			geninterrupt(0x10);
			}
		}
	else	{//S3 or GD542x,myself support
		if(VESAColor==8)
			{
			_AX=0x13;
			geninterrupt(0x10);
			}
		else	SetVideoMode();
		}
	if(VESASupportFlags)//Set Video Memory Bank & Display start
		{
		_AX=0x4F05;
		_BX=0;_DX=0;//Select Bank 0
		geninterrupt(0x10);
		_AX=0x4F07;
		_BX=0;_CX=0;_DX=0;//Start display at (0,0)
		geninterrupt(0x10);
		}
	if(VESAColor==64 || VESAColor==32)
		{//Set 640x240 mode
		int	Port;
		outportb(0x3D4,9);
		Port=inportb(0x3D5);
		if((Port&1)) Port|=0x80;
		else	Port|=1;
		outportb(0x3D5,Port);
		if(VESAColor==64) BankGranUnit=GetBankSize(0x111);
		else	BankGranUnit=GetBankSize(0x110);
		if(BankGranUnit==0) BankGranUnit=64;
		BankSize=64/BankGranUnit;
		if(BankSize==0) BankSize=1;
		}
	else	{
		if(VESAColor==16||VESAColor==15)
			{
			//////// Set 128K Buffer ////////
			outportb(0x3CE,0x06);Old3CF6=inportb(0x3CF);
			outportb(0x3CE,0x06);outportb(0x3CF,Old3CF6&0xF3);//128K Screen Buffer
			if(BankingFlags==0)	//Force use banking
				BankingFlags=TestNo128KVideo();
			if(BankingFlags)
				{//Normal VGA,use banking.
				GetBankingWay();
				}
			}
		}
}
///////////////////// VESA //////////////////////
typedef	struct	VESAtag
	{
	DWORD	VESAFlags;
	WORD	Version;
	char far * OEMPtr;
	DWORD	Size;
	int far *  ModePtr;
	}VESA;
VESA far *VESAPtr;
WORD	DOSSel;
WORD	DOSSeg;
typedef	struct	Stacktag
	{
	DWORD	DI;
	DWORD	SI;
	DWORD	BP;
	DWORD	Resever;//
	DWORD	BX;
	DWORD	DX;
	DWORD	CX;
	DWORD	AX;
	WORD	FLAGS;//
	WORD	ES;
	WORD	DS;
	WORD	FS;
	WORD	GS;
	WORD	IP;//
	WORD	CS;//
	WORD	SP;
	WORD	SS;
	}STACK;
STACK	Stack;
////////////////////////////////////////////
WORD	VideoStateSel=0;
WORD	VideoStateSeg=0;
void PASCAL FAR	AllocateVideoStateBuffer(void)
{
	DWORD	Size;

	if(VESASupportFlags==0) return;//VESA Call not support.
//	_AX=0x4F04;
//	_DL=0;
//	_CX=0xFF;
//	geninterrupt(0x10);	//This call in Win95 & S3 Trio32/64 driver
//	if(_AX!=0x004F)	return;	//will make GDI error.
//	Size=_BX;		//Always the size = 1024 bytes
//	Size*=64;
	Size=4096;		//Now set 4096 bytes buffer for all Video card
	GlobalDosAlloc(Size);
	VideoStateSel=_AX;
	VideoStateSeg=_DX;
}
void PASCAL FAR	FreeVideoStateBuffer(void)
{
	if(VideoStateSel==NULL) return;
	GlobalDosFree(VideoStateSel);
}
int	SupperVESAState=0;
static	void	SaveVideoState(void)
{
	if(VideoStateSel==NULL) return;
	Stack.ES=VideoStateSeg;
	Stack.AX=0x4F04;
	Stack.DX=1;	//The Supper VGA state on Windows95 VIEWTOP 64V+ error
	Stack.CX=0x7;	//VESA Restore Video hardware,BIOS data,DAC state
	Stack.CX|=SupperVESAState;
	////////// Call Real INT //////////
	_ES=FP_SEG(&Stack);
	_DI=FP_OFF(&Stack);
	_CX=0;
	_BH=0;
	_BL=0x10;
	_AX=0x300;
	geninterrupt(0x31);
}
static	void	RestoreVideoState(void)
{
	if(VideoStateSel==NULL) return;
	Stack.ES=VideoStateSeg;
	Stack.AX=0x4F04;
	Stack.DX=2;	//The Supper VGA state on Windows95 VIEWTOP 64V+ error
	Stack.CX=0x7;	//VESA Restore Video hardware,BIOS data,DAC state
	Stack.CX|=SupperVESAState;
	////////// Call Real INT //////////
	_ES=FP_SEG(&Stack);
	_DI=FP_OFF(&Stack);
	_CX=0;
	_BH=0;
	_BL=0x10;
	_AX=0x300;
	geninterrupt(0x31);
}
int  far *  ModePtr;
static	int	VESAModeTest(int Mode)
{
	////////// Stack Registers ////////
	Stack.DI=0;
	Stack.ES=0xC000;	//BIOS ROM area C000:0
	Stack.AX=0x4F01;
	Stack.CX=Mode;		//VESA Mode;
	////////// Call Real INT //////////
	_ES=FP_SEG(&Stack);
	_DI=FP_OFF(&Stack);
	_CX=0;
	_BH=0;
	_BL=0x10;
	_AX=0x300;
	geninterrupt(0x31);
	asm	jnc	short	NEXT2;
	return 0;
	NEXT2:			//VESA Support 64K Color
	if((Stack.AX&0xFF)!=0x4F) return 0;//Not Support VESA
	if((Stack.AX&0xFF00)!=0 ) return 0;//Not Success
	return 1;
}
int	VESACanUse=0;
int	M640x48064KC=0;
int	M640x48032KC=0;
int	PASCAL FAR	TestVESASupport(void)
{
	int	Mode;
	/////////// Must be VGA //////////
	if((inportb(0x3CC)&1)==0) return 0;
	/////////// Allocate DOS Memory //////////
	GlobalDosAlloc(256);
	DOSSel=_AX;
	DOSSeg=_DX;
	if(DOSSel==0)	//Can't Allocate DOS Memory.
		{
		if(VESAModeTest(0x111)==1) M640x48064KC=1;
		if(VESAModeTest(0x110)==1) M640x48032KC=1;
		if(VESAModeTest(0x10E)==1) return 16;
		if(VESAModeTest(0x10D)==1) return 15;
		return 8;
		}
	////////////////VESA Info////////////////
	Stack.DI=0;
	Stack.ES=DOSSeg;
	Stack.AX=0x4F00;
	////////// Call Real INT //////////
	_ES=FP_SEG(&Stack);
	_DI=FP_OFF(&Stack);
	_CX=0;
	_BH=0;
	_BL=0x10;
	_AX=0x300;
	geninterrupt(0x31);
	asm	jnc	short	NEXT2;
	// DPMI or VESA Call Error,Directly test mode.
	DIRTESTMODE:
	GlobalDosFree(DOSSel);
	if(VESAModeTest(0x10E)==1) return 16;
	if(VESAModeTest(0x10D)==1) return 15;
	return 8;
	NEXT2:			//VESA Support 64K Color
	if((Stack.AX&0xFF)!=0x4F) goto DIRTESTMODE;//Not Support VESA
	if((Stack.AX&0xFF00)!=0 ) goto DIRTESTMODE;//Not Success
	VESASupportFlags=VESACanUse=1;
	///////////////Read VESA info/////////////
	VESAPtr=MK_FP(DOSSel,0);
	if(VESAPtr->VESAFlags!=0x41534556) goto DIRTESTMODE;//'VESA'
	ModePtr=VESAPtr->ModePtr;
	////////// Segment -> Selector ///////////
	_BX=FP_SEG(ModePtr);
	_AX=2;
	geninterrupt(0x31);	//DOS Segment to Selector.
	asm	jnc	short	NEXT3;
	goto	DIRTESTMODE;
	NEXT3:
	*((WORD *)&ModePtr+1)=_AX;	//High WORD = Selector.
	/////////// Mode Info ////////////
	Mode=8;
	while(*ModePtr!=-1)
		{
		if(*ModePtr==0x111) M640x48064KC=1;
		if(*ModePtr==0x110) M640x48032KC=1;
		if(*ModePtr==0x10E)
			{
			if(Mode==8||Mode==15)
				Mode=16;	//64 K Colors
			}
		if(*ModePtr==0x10D)
			{
			if(Mode==8) Mode=15;	//32 K Colors
			}
		ModePtr++;	//Next VESA mode.
		if(*ModePtr==0) break;
		}
	if(Mode==8)	SearchVESAType(VESAPtr->OEMPtr);
	///////////////Free DOS Memory ///////////
	GlobalDosFree(DOSSel);
	//////////////////////////////////////////
	return Mode;
}
typedef	struct	VESAINFOtag
	{
	WORD	ModeAttrib;
	BYTE	WindowAAttrib;
	BYTE	WindowBAttrib;
	WORD	GranUnit;
	WORD	WinSize;
	WORD	WindowASegment;
	WORD	WindowBSegment;
	void far *BankSwitchProc;
	WORD	LineBytes;
	WORD	WidthBytes;
	WORD	HeightBytes;
	}VESAINFO;
static	HadGetBankSize=0;
static	int	GetBankSize(int Mode)
{
	VESAINFO far *Ptr;
	if(HadGetBankSize==1) return BankGranUnit;
	HadGetBankSize=1;
	GlobalDosAlloc(256);
	DOSSel=_AX;
	DOSSeg=_DX;
	if(DOSSel==0)	//Can't Allocate DOS Memory.
		return	64;
	////////////////VESA Info////////////////
	Stack.DI=0;

⌨️ 快捷键说明

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