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

📄 overlay_s1d13806.c

📁 大名鼎鼎的CE下播放软件,TCPPMP的源代码!!!2410下可以流畅的解QVGA的H264,MPEG4等格式.
💻 C
字号:
/*****************************************************************************
 *
 * This program is free software ; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 * $Id: overlay_s1d13806.c 543 2006-01-07 22:06:24Z picard $
 *
 * The Core Pocket Media Player
 * Copyright (c) 2004-2005 Gabor Kovacs
 *
 ****************************************************************************/

#include "../common.h"

#if defined(TARGET_WINCE) && defined(ARM)

#define WIN32_LEAN_AND_MEAN
#ifndef STRICT
#define STRICT
#endif
#include <windows.h>

extern int STDCALL IRQEnable();
extern int STDCALL IRQDisable();

typedef struct s1d13806
{
	overlay Overlay;
	planes Planes;
	bool_t KernelMode;
	void* Buffer;
	bool_t PhyAddr;
	volatile unsigned char* Regs;
	volatile unsigned short* FIFO;
	HBRUSH Brush;

} s1d13806;

static INLINE void Reg3(s1d13806* p,int i,int v)
{
	p->Regs[i+0] = (unsigned char)(v);
	p->Regs[i+1] = (unsigned char)(v >> 8);
	p->Regs[i+2] = (unsigned char)(v >> 16);
}

static INLINE void Reg2(s1d13806* p,int i,int v)
{
	p->Regs[i+0] = (unsigned char)(v);
	p->Regs[i+1] = (unsigned char)(v >> 8);
}

static int Blit(overlay* p, const constplanes Data, const constplanes DataLast)
{
	planes Planes;
	int Result = p->Lock(p,Planes,1);
	if (Result==ERR_NONE)
	{
		BlitImage(p->Soft,Planes,Data,DataLast,-1,-1);
		p->Unlock(p);
	}
	return Result;
}

static int Update(overlay* p)
{
	blitfx FX = p->FX;
	video Output = p->Output.Format.Video;
	rect OldGUI = p->GUIAlignedRect;
	rect Old = p->DstAlignedRect;

	VirtToPhy(&p->Viewport,&p->DstAlignedRect,&p->Output.Format.Video);
	VirtToPhy(NULL,&p->SrcAlignedRect,&p->Input.Format.Video);

	p->DstAlignedRect.Height >>= 1;
	p->DstAlignedRect.y >>= 1;
	Output.Height >>= 1;
	Output.Pitch <<= 1;
	if (FX.Direction & DIR_SWAPXY)
		FX.ScaleX >>= 1;
	else
		FX.ScaleY >>= 1;

	if (p->Output.Format.Video.Pixel.BitCount!=16)
		FX.Flags |= BLITFX_DITHER;

	BlitRelease(p->Soft);
	p->Soft = BlitCreate(&Output,&p->Input.Format.Video,&FX,&p->Caps);

	BlitAlign(p->Soft,&p->DstAlignedRect, &p->SrcAlignedRect);

	p->DstAlignedRect.Height <<= 1;
	p->DstAlignedRect.y <<= 1;

	if (p->Output.Format.Video.Pixel.BitCount!=16)
		p->Caps &= ~VC_DITHER;

	PhyToVirt(&p->DstAlignedRect,&p->GUIAlignedRect,&p->Output.Format.Video);

	if (!EqRect(&Old,&p->DstAlignedRect) && p->Show && p->Primary)
	{
		WinInvalidate(&OldGUI,0);
		WinInvalidate(&p->Viewport,1);
		WinValidate(&p->GUIAlignedRect);
	}

	if (p->Show && (p->FullScreenViewport || !p->Primary))
		OverlayClearBorder(p);

	return ERR_NONE;
}

static int Init(s1d13806* p)
{
	HKEY Key;
	video* Output = &p->Overlay.Output.Format.Video;

	QueryDesktop(Output);
	DefaultPitch(Output);

	p->Regs = NULL;
	p->Buffer = NULL;

	if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, T("Drivers\\Display\\S1D13806"), 0, KEY_READ, &Key) == ERROR_SUCCESS)
	{
		DWORD Value;
		DWORD RegSize;
		DWORD RegType;

		RegSize = sizeof(Value);
		if (RegQueryValueEx(Key, T("RegBase"), 0, &RegType, (LPBYTE)&Value, &RegSize) == ERROR_SUCCESS)
			p->Regs = (unsigned char*)Value;

		RegSize = sizeof(Value);
		if (RegQueryValueEx(Key, T("MemBase"), 0, &RegType, (LPBYTE)&Value, &RegSize) == ERROR_SUCCESS)
			p->Buffer = (void*)Value;

		RegCloseKey(Key);
	}

	if (!p->Regs || !p->Buffer)
		return ERR_NOT_SUPPORTED;

	p->PhyAddr = (uint32_t)p->Regs < 0x80000000;

	if (p->PhyAddr)
	{
		p->Regs = PhyMemBegin((uint32_t)p->Regs,2*1024*1024,0);
		if (!p->Regs)
			return ERR_NOT_SUPPORTED;

		p->Buffer = PhyMemBegin((uint32_t)p->Buffer,2*1024*1024,1);
		if (!p->Buffer)
		{
			PhyMemEnd((void*)p->Regs);
			p->Regs = NULL;
			return ERR_NOT_SUPPORTED;
		}
	}

	p->FIFO = (unsigned short*)(p->Regs+1024*1024);

	if (((int)p->Buffer & 15)==0 && (Output->Pitch & 15)==0)
		Output->Pixel.Flags |= PF_16ALIGNED;

	p->Planes[0] = p->Buffer;
	AdjustOrientation(Output,0);
	p->Overlay.SetFX = BLITFX_AVOIDTEARING;

	p->Brush = (HBRUSH)GetStockObject(BLACK_BRUSH);

	return ERR_NONE;
}

static void Done(s1d13806* p)
{
	if (p->PhyAddr)
	{
		if (p->Buffer)
			PhyMemEnd(p->Buffer);
		if (p->Regs)
			PhyMemEnd((void*)p->Regs);
	}
	p->Buffer = NULL;
	p->Regs = NULL;
}

static int Reset(s1d13806* p)
{
	Done(p);
	Init(p);
	return ERR_NONE;
}

static int Lock(s1d13806* p, planes Planes, bool_t OnlyAligned)
{
	p->KernelMode = KernelMode(1);
	Planes[0] = p->Planes[0];
	return ERR_NONE;
}

static int Unlock(s1d13806* p)
{
	if (p->Regs && p->Overlay.DstAlignedRect.Width>0 && p->Overlay.DstAlignedRect.Height>1)
	{
		int ReTry;
		HDC DC = GetDC(NULL);

		for (ReTry=0;ReTry<32;++ReTry)
		{
			// we have to make sure not to interfere with the GDI driver
			// use FillRect to make the GDI driver use the epson chip
			// disable the interrupt and verify we still in our FillRect blitting
			// wait until it's finished and start our own blitting

			RECT R;
			R.left = 0;
			R.top = 0;
			R.right = 1;
			R.bottom = p->Overlay.Output.Format.Video.Height-1;
			FillRect(DC,&R,p->Brush);

			IRQDisable();

			if ((p->Regs[0x100] & 128)==0 ||
				p->Regs[0x110] != 0 || p->Regs[0x111] != 0 ||
				p->Regs[0x112] != ((R.bottom-1) & 255) || p->Regs[0x113] != ((R.bottom-1) >> 8))
			{
				IRQEnable();
			}
			else
			{
				int Ofs = p->Overlay.DstAlignedRect.x*(p->Overlay.Output.Format.Video.Pixel.BitCount>>3) + 
					p->Overlay.DstAlignedRect.y*p->Overlay.Output.Format.Video.Pitch;

				while ((p->Regs[0x100] & 128)!=0);
				ReTry += p->FIFO[0];

				Reg3(p,0x104,Ofs);
				Reg3(p,0x108,Ofs + p->Overlay.Output.Format.Video.Pitch);

				Reg2(p,0x110,p->Overlay.DstAlignedRect.Width-1);
				Reg2(p,0x112,(p->Overlay.DstAlignedRect.Height/2)-1);
				p->Regs[0x103] = 2;
				p->Regs[0x102] = 0x0C;
				p->Regs[0x101] = (char)(p->Overlay.Output.Format.Video.Pixel.BitCount==16?1:0);
				Reg2(p,0x10C,p->Overlay.Output.Format.Video.Pitch);

				p->Regs[0x100] = 0x80;

				while ((p->Regs[0x100] & 128)==0);
				IRQEnable();
				break;
			}
		}

		ReleaseDC(NULL,DC);
	}

	KernelMode(p->KernelMode);
	return ERR_NONE;
}

static int Create(s1d13806* p)
{
	if (Init(p) != ERR_NONE) // check if supported
		return ERR_NOT_SUPPORTED;
	Done(p);

	p->Overlay.Init = (ovlfunc)Init;
	p->Overlay.Done = (ovldone)Done;
	p->Overlay.Reset = (ovlfunc)Reset;
	p->Overlay.Lock = (ovllock)Lock;
	p->Overlay.Unlock = (ovlfunc)Unlock;
	p->Overlay.Blit = (ovlblit)Blit;
	p->Overlay.Update = (ovlfunc)Update;
	return ERR_NONE;
}

static const nodedef S1D13806 = 
{
	sizeof(s1d13806)|CF_GLOBAL,
	S1D13806_ID,
	OVERLAY_CLASS,
	PRI_DEFAULT+92,
	(nodecreate)Create,
};

void OverlayS1D13806_Init()
{ 
	NodeRegisterClass(&S1D13806);
}

void OverlayS1D13806_Done()
{
	NodeUnRegisterClass(S1D13806_ID);
}

#else
void OverlayS1D13806_Init() {}
void OverlayS1D13806_Done() {}
#endif

⌨️ 快捷键说明

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