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

📄 overlay_hires.c

📁 大名鼎鼎的CE下播放软件,TCPPMP的源代码!!!2410下可以流畅的解QVGA的H264,MPEG4等格式.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************
 *
 * 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_hires.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_PALMOS)

#include "../palmos/pace.h"

#ifdef HAVE_PALMONE_SDK
#include <68K/System/PalmDisplayExtent.h>
static UInt16 DEX = sysInvalidRefNum;
#endif

#undef CPU_TYPE
#define CPU_TYPE CPU_68K
#include "RotationMgrLib.h"
static UInt16 RotM = sysInvalidRefNum;

typedef struct xscaledesc
{
	uint32_t Next;
	uint32_t Base;
	uint32_t Id;
	uint32_t Cmd;

} xscaledesc;

typedef struct hiresbuffer
{
	block Buffer;
	uint32_t DescPhy;
	xscaledesc* Desc;
	uint32_t SurfacePhy;
	uint8_t* Surface;

} hiresbuffer;

#define MAGIC		0xBABE0000

#define XSCALE_LCD_BASE	0x44000000

#define LCCR0		(0x000/4)
#define LCCR1		(0x004/4)
#define LCCR2		(0x008/4)
#define LCCR3		(0x00C/4)
#define LCCR4		(0x010/4)
#define LCCR5		(0x014/4)
#define LCSR0		(0x038/4)
#define LCSR1		(0x034/4)
#define FBR0		(0x020/4)
#define FDADR0		(0x200/4)
#define FSADR0		(0x204/4)
#define FIDR0		(0x208/4)

#define OMAP_LCD_BASE	0xfffec000
#define OMAP_DMA_BASE	0xfffedb00
#define OMAP_PAL_SIZE	32

#define OMAP_CONTROL 0
#define OMAP_TIMING0 1
#define OMAP_TIMING1 2
#define OMAP_TIMING2 3
#define OMAP_STATUS	 4

#define OMAP_DMA_CONTROL	0
#define OMAP_DMA_TOP_L		1
#define OMAP_DMA_TOP_U		2
#define OMAP_DMA_BOTTOM_L	3
#define OMAP_DMA_BOTTOM_U	4

typedef struct hires hires;
typedef	int (*hiresfunc)(hires* This);

struct hires
{
	overlay Overlay;
	bool_t UseLocking;
	bool_t Locked;
	char* Bits;
	int Offset;
	int BufferCount;
	hiresbuffer Buffer[3];
	int Next;
	int PhyWidth;
	int PhyHeight;
	int SurfaceSize;
	int SurfaceOffset;
	int OrigPitch;
	uint32_t OrigPhy;
	uint32_t OrigPhyEnd;
	int Border[4];
	volatile uint32_t* Regs;
	volatile uint16_t* Regs2;
	int Caps;
	int Model;
	bool_t UseBorder;
	bool_t TripleBuffer;
	bool_t LowLevelFailed;
	hiresfunc LowLevelAlloc;
	hiresfunc LowLevelGet;
	hiresfunc LowLevelGetOrig;
	hiresfunc LowLevelSetOrig;
	hiresfunc LowLevelFlip;
};

static char* GetBits()
{
	BitmapType* Bitmap;
	WinHandle Win = WinGetDisplayWindow();
	if (!Win)
		return NULL;

	Bitmap = WinGetBitmap(Win);
	if (!Bitmap)
		return NULL;

	return BmpGetBits(Bitmap);
}

static bool_t ProcessRawInfo(video* Video,char* Bits,char* RawBits,int Width,int Height,int Pitch,int* Offset,bool_t MovedSIP)
{
	int Dir = GetOrientation();

	Video->Pitch = Pitch;

	if (Width > Height) // native landscape device
		Dir = CombineDir(Dir,DIR_SWAPXY|DIR_MIRRORUPDOWN,0);

	// trust GetBits() if it's inside the Raw buffer
	if (Bits >= RawBits && Bits < RawBits + Height*Pitch) 
		return 0; 	

	if (!MovedSIP && Dir==0) // assuming working GetBits() with RotM in native mode
		return 0; 

	if (Dir & DIR_SWAPXY)
		SwapInt(&Video->Width,&Video->Height);

	if (Width > Height) // native landscape device
	{
		if ((Dir & DIR_SWAPXY)==0 ? GetHandedness() : (Dir & DIR_MIRRORLEFTRIGHT)!=0)
			*Offset = (Width-Video->Width)*(Video->Pixel.BitCount >> 3);
	}
	else 
	{
		// native portrait device
		if ((Dir & DIR_SWAPXY) && MovedSIP) // don't adjust for RotM (SIP stays on native bottom)
		{
			// assuming taskbar and SIP is in the upper part of the screen in landscape mode
			if (Height > 320+32 && Video->Height <= 320+32 && DIASupported() && !DIAGet(DIA_SIP))
				Height = 320+32; // closed slider on Tungsten T3
			*Offset = (Height-Video->Height)*Pitch;
		}
	}

	Video->Direction = Dir;
	return 1;
}

char* QueryScreen(video* Video,int* Offset,int* Mode)
{
	char* Bits = GetBits(); 
	QueryDesktop(Video);
	*Offset = 0;
	if (Mode) *Mode = 0;

#ifdef HAVE_PALMONE_SDK
	if (DEX != sysInvalidRefNum)
	{
		UInt16 Pitch;
		Coord Width,Height;
		char* RawBits = DexGetDisplayAddress(DEX);
		if (RawBits)
		{
			DexGetDisplayDimensions(DEX,&Width,&Height,&Pitch);
			if (ProcessRawInfo(Video,Bits,RawBits,Width,Height,Pitch,Offset,1))
			{
				if (Mode) *Mode = 1;
				return RawBits;
			}
		}
	}
#endif

	if (RotM != sysInvalidRefNum)
	{
		UInt32 RawBits;
		UInt32 Width,Height,Pitch;

		if (RotationMgrAttributeGet(RotM,kRotationMgrAttrDisplayAddress,&RawBits)==errNone && RawBits &&
			RotationMgrAttributeGet(RotM,kRotationMgrAttrDisplayWidth,&Width)==errNone &&
			RotationMgrAttributeGet(RotM,kRotationMgrAttrDisplayHeight,&Height)==errNone &&
			RotationMgrAttributeGet(RotM,kRotationMgrAttrDisplayRowBytes,&Pitch)==errNone &&
			ProcessRawInfo(Video,Bits,(char*)RawBits,Width,Height,Pitch,Offset,0))
		{
			if (Mode) *Mode = 2;
			return (char*)RawBits;
		}
	}

	if (Video->Pitch < Video->Width*(Video->Pixel.BitCount/8))
		return NULL;

	return Bits;
}

static int BufferFree(hires* p)
{
	int n;
	for (n=0;n<p->BufferCount;++n)
		FreeBlock(&p->Buffer[n].Buffer);
	p->BufferCount = 0;
	memset(&p->Buffer,0,sizeof(p->Buffer));
	return ERR_NONE;
}

static int Init(hires* p)
{
	int Mode;
	p->Overlay.SetFX = BLITFX_AVOIDTEARING;
	p->UseLocking = 0;

	if (QueryPlatform(PLATFORM_MODEL)==MODEL_ZODIAC)
	{
		int Dir = GetOrientation();
		if (Dir & DIR_SWAPXY)
		{
			p->Overlay.SetFX |= BLITFX_VMEMROTATED;
			if (Dir & DIR_MIRRORLEFTRIGHT)
				p->Overlay.SetFX |= BLITFX_VMEMUPDOWN;
		}
	}

	p->Bits = QueryScreen(&p->Overlay.Output.Format.Video,&p->Offset,&Mode);
	if (!p->Bits)
		return ERR_INVALID_PARAM;

	if (!Mode)
		p->Bits = NULL; // use GetBits() during Lock()

	p->OrigPitch = p->Overlay.Output.Format.Video.Pitch;
	p->Next = 0;
	p->LowLevelFailed = 0;
	return ERR_NONE;
}

static void Hide(hires* p)
{
	if (p->Overlay.Overlay)
	{
		p->LowLevelSetOrig(p);
		p->Overlay.Overlay = 0;
		p->Overlay.Output.Format.Video.Pitch = p->OrigPitch;
	}
}

static void Done(hires* p)
{
	Hide(p);
	BufferFree(p);
}

static int UpdateAlloc(hires* p)
{
	int MaxCount = 1;
	if (p->TripleBuffer)
		MaxCount = 3;

	if (p->UseBorder)
	{
		p->SurfaceSize = (p->PhyWidth+p->Border[0]+p->Border[1])*(p->PhyHeight+p->Border[2]+p->Border[3])*2;
		p->SurfaceOffset = ((p->PhyWidth+p->Border[0]+p->Border[1])*p->Border[2]+p->Border[0])*2;
	}
	else
	{
		p->SurfaceSize = p->PhyWidth*p->PhyHeight*2;
		p->SurfaceOffset = 0;
	}

	while (p->BufferCount<MaxCount)
		if (p->LowLevelAlloc(p) == ERR_NONE)
			++p->BufferCount;
		else
			break;

	if (p->BufferCount==2)
	{
		FreeBlock(&p->Buffer[1].Buffer);
		--p->BufferCount;
	}

	if (!p->BufferCount)
		return ERR_OUT_OF_MEMORY;
	return ERR_NONE;
}

static int Update(hires* p)
{
	if (p->Overlay.FullScreenViewport && (p->UseBorder || p->TripleBuffer) && 
		!p->LowLevelFailed && (p->Overlay.Overlay || (p->LowLevelGetOrig && p->LowLevelGetOrig(p)==ERR_NONE)))
	{
		p->Overlay.Overlay = 1;
		if (UpdateAlloc(p)!=ERR_NONE || (p->BufferCount<3 && !p->UseBorder))
		{
			Hide(p);
			p->LowLevelFailed = 1;
			BufferFree(p);
		}
		else
		{
			int n;
			for (n=0;n<p->BufferCount;++n)
				memset(p->Buffer[n].Surface,0,p->SurfaceSize);
		}
	}	
	else
		Hide(p);

	p->Overlay.DoPowerOff = p->Overlay.Overlay;
	return OverlayUpdateAlign(&p->Overlay);
}

static int Show(hires* p)
{
	if (!p->Overlay.Show && p->Overlay.Overlay)
	{
		p->LowLevelSetOrig(p);
		p->Next = 0;
	}
	return ERR_NONE;
}

static int Reset(hires* p)
{
	int Pitch = p->Overlay.Output.Format.Video.Pitch;
	Init(p);
	if (p->Overlay.Overlay)
		p->Overlay.Output.Format.Video.Pitch = Pitch;
	return ERR_NONE;
}

static int Lock(hires* p, planes Planes, bool_t OnlyAligned)
{
	if (p->Overlay.Overlay)
	{
		int Next = p->Next+1;
		if (Next == p->BufferCount) 
			Next = 0;

		// use new buffer only if it's not the current
		if (p->LowLevelGet(p) != Next) 
			p->Next = Next;

		Planes[0] = p->Buffer[p->Next].Surface + p->SurfaceOffset;
	}
	else
	if (p->UseLocking && p->Overlay.CurrTime>=0 &&  // don't use locking with benchmark
		(Planes[0] = WinScreenLock(p->Overlay.Dirty?winLockCopy:winLockDontCare)) != NULL)
		p->Locked = 1;
	else
	if (p->Bits)
		Planes[0] = p->Bits + p->Offset;
	else
	{
		char* Bits = GetBits();
		if (!Bits)
			return ERR_DEVICE_ERROR;
		Planes[0] = Bits;
	}
	return ERR_NONE;
}

static int Unlock(hires* p)
{
	if (p->Overlay.Overlay)
		return p->LowLevelFlip(p);
	else
	if (p->Locked)
		WinScreenUnlock();
	return ERR_NONE;
}

//-------------------------------------------------------------------------------

static int XScaleGetOrig(hires* p)
{
	int ReTry = 0;
	do
	{
		ThreadSleep(2);
		if (++ReTry == 5) return ERR_NOT_SUPPORTED;
	}
	while (!(p->Regs[LCCR0] & 1)); // again if lcd disabled

	p->PhyWidth = (p->Regs[LCCR1] & 0x3FF)+1;
	p->PhyHeight = (p->Regs[LCCR2] & 0x3FF)+1;

	if (p->Overlay.Output.Format.Video.Width > p->PhyWidth ||
		p->Overlay.Output.Format.Video.Height > p->PhyHeight)
		return ERR_NOT_SUPPORTED; // this shouldn't happen

	p->OrigPhy = p->Regs[FDADR0];
	if (!p->OrigPhy)
		return ERR_NOT_SUPPORTED; // this shouldn't happen

	// assuming physical direction and size is already correct
	p->Overlay.Output.Format.Video.Pitch = p->PhyWidth*2;
	if (p->UseBorder)
		p->Overlay.Output.Format.Video.Pitch += (p->Border[0]+p->Border[1])*2;
	
	return ERR_NONE;
}

static int XScaleAlloc(hires* p)
{
	hiresbuffer* Buffer = p->Buffer+p->BufferCount;
	if (!AllocBlock(16+sizeof(xscaledesc)+256+p->SurfaceSize,&Buffer->Buffer,0,HEAP_ANYWR))
		return ERR_OUT_OF_MEMORY;
	Buffer->Desc = (xscaledesc*)ALIGN16((uintptr_t)Buffer->Buffer.Ptr);
	Buffer->DescPhy = MemVirtToPhy(Buffer->Desc);
	if (!Buffer->DescPhy)
	{
		FreeBlock(&Buffer->Buffer);
		return ERR_NOT_SUPPORTED;
	}
	Buffer->Surface = (uint8_t*)Buffer->Desc+sizeof(xscaledesc)+256;
	Buffer->SurfacePhy = Buffer->DescPhy+sizeof(xscaledesc)+256; 
	Buffer->Desc->Base = Buffer->SurfacePhy;

⌨️ 快捷键说明

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