platform_win32.c

来自「betaplayer_0.096源码 tcpmp老版本」· C语言 代码 · 共 2,601 行 · 第 1/5 页

C
2,601
字号
/*****************************************************************************
 *
 * 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: platform_win32.c 178 2005-01-10 07:34:30Z picard $
 *
 * BetaPlayer Core
 * Copyright (c) 2004 Gabor Kovacs
 *
 ****************************************************************************/

#include "../stdafx.h"

#if defined(_WIN32)

int DebugMask = DEBUG_SYS;//|DEBUG_FORMAT|DEBUG_PLAYER;//|DEBUG_VIDEO;//|DEBUG_AUDIO|DEBUG_VIDEO|DEBUG_PLAYER;//|DEBUG_VIDEO;//DEBUG_TEST;//|DEBUG_FORMAT|DEBUG_PLAYER;

// before including <windows.h> because it can override STDCALL
extern int STDCALL CheckARM5E();
extern int STDCALL CheckARMXScale();
extern void STDCALL GetCpuId(int,uint32_t*);
extern int64_t STDCALL CPUSpeedClk(int);

#if !defined(MIPS) && !defined(ARM) && !defined(_M_IX86)
void STDCALL GetCpuId(int Id,uint32_t* Val) {}
#if !defined(SH3)
int64_t STDCALL CPUSpeedClk(int v) { return 0; }
#endif
#endif

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

#if defined(_MSC_VER) && !defined(_WIN32_WCE)
#include <crtdbg.h>
#endif

static const datadef PlatformParams[] = 
{
	{ PLATFORM_ID,			TYPE_CLASS },
	{ PLATFORM_LANG,		TYPE_INT, DF_SETUP|DF_ENUMSTRING|DF_RESTART, LANG_ID },
	{ PLATFORM_TYPE,		TYPE_STRING, DF_SETUP|DF_RDONLY|DF_GAP },
	{ PLATFORM_VER,			TYPE_INT, DF_SETUP|DF_RDONLY|DF_HIDDEN },
	{ PLATFORM_VERSION,		TYPE_STRING, DF_SETUP|DF_RDONLY },
	{ PLATFORM_OEMINFO,		TYPE_STRING, DF_SETUP|DF_RDONLY },
	{ PLATFORM_TYPENO,		TYPE_INT, DF_SETUP|DF_RDONLY|DF_HIDDEN },
	{ PLATFORM_MODEL,		TYPE_INT, DF_SETUP|DF_RDONLY|DF_HIDDEN },
	{ PLATFORM_CAPS,		TYPE_INT, DF_SETUP|DF_RDONLY|DF_HIDDEN|DF_HEX },
	{ PLATFORM_CPU,			TYPE_STRING, DF_SETUP|DF_RDONLY },
	{ PLATFORM_MHZ,			TYPE_INT, DF_SETUP|DF_RDONLY|DF_MHZ },
	{ PLATFORM_ICACHE,		TYPE_INT, DF_SETUP|DF_RDONLY|DF_HIDDEN },
	{ PLATFORM_DCACHE,		TYPE_INT, DF_SETUP|DF_RDONLY|DF_HIDDEN },
	DATADEF_END
};

typedef struct platform
{
	node VMT;
	int Model;
	int Caps;
	int ICache;
	int DCache;
	int Type;
	int Ver;
	tchar_t OemInfo[256];
	tchar_t PlatformType[256];
	tchar_t CPU[64];
	int64_t Tick0;

} platform;

#if defined(_WIN32_WCE)

#ifndef DISP_CHANGE_SUCCESSFUL
#define DISP_CHANGE_SUCCESSFUL 0
#endif
#ifndef CDS_TEST
#define CDS_TEST            0x00000002
#endif
#ifndef DM_DISPLAYORIENTATION
#define DM_DISPLAYORIENTATION 0x00800000L
#endif
#ifndef DM_DISPLAYQUERYORIENTATION 
#define DM_DISPLAYQUERYORIENTATION 0x01000000L
#endif
#ifndef DMDO_0
#define DMDO_0      0
#endif
#ifndef DMDO_90
#define DMDO_90     1
#endif
#ifndef DMDO_180
#define DMDO_180    2
#endif
#ifndef DMDO_270
#define DMDO_270    4
#endif

#define SPI_GETOEMINFO				258
#define SPI_GETPLATFORMTYPE			257
#define CACHE_SYNC_INSTRUCTIONS		2
#define LOCKFLAG_WRITE				1
#define TBL_CACHE	0x08
#define TBL_BUFFER	0x04

static BOOL (WINAPI* FuncVirtualSetAttributes)( LPVOID lpvAddress, DWORD cbSize, DWORD dwNewFlags, DWORD dwMask, LPDWORD lpdwOldFlags ) = NULL;
static BOOL (WINAPI* FuncFreePhysMem)( LPVOID ) = NULL;
static BOOL (WINAPI* FuncLockPages)(LPVOID lpvAddress,DWORD cbSize,PDWORD pPFNs,int fOptions ) = NULL;
static BOOL (WINAPI* FuncUnlockPages)(LPVOID lpvAddress,DWORD cbSize ) = NULL;
static LPVOID (WINAPI* FuncAllocPhysMem)( DWORD cbSize, DWORD fdwProtect, DWORD dwAlignmentMask, DWORD dwFlags, PULONG pPhysicalAddress ) = NULL;
static HANDLE (WINAPI* FuncSetPowerRequirement)(PVOID,int,ULONG,PVOID,ULONG) = NULL;
static DWORD (WINAPI* FuncReleasePowerRequirement)(HANDLE) = NULL;
static BOOL (WINAPI* FuncSHGetDocumentsFolder)(LPCTSTR,LPTSTR) = NULL;
static BOOL (WINAPI* FuncSHGetSpecialFolderPath)(HWND,LPTSTR,int,BOOL) = NULL;
static LONG (WINAPI* FuncChangeDisplaySettingsEx)(LPCTSTR,LPDEVMODE,HWND,DWORD,LPVOID) = NULL;
static void (WINAPI* FuncCacheSync)(DWORD) = NULL;
static BOOL (WINAPI* FuncVirtualCopy)(LPVOID, LPVOID, DWORD, DWORD) = NULL;
static BOOL (WINAPI* FuncCeSetThreadQuantum)(HANDLE, DWORD ) = NULL;
static BOOL (WINAPI* FuncSetKMode)(BOOL) = NULL;
static BOOL (WINAPI* FuncRedrawWindow)(HWND,CONST RECT*,HRGN,UINT) = NULL;
static void (WINAPI* FuncSHIdleTimerReset)() = NULL;

static HMODULE CoreDLL = NULL;
static HMODULE CEShellDLL = NULL;
static HANDLE BacklightEvent = NULL;

#define ACCESS_LOAD		0
#define ACCESS_SAVE		0 

#define MAXPHY		16

typedef struct phymem
{
	char* Virt;
	uint32_t Phy; 
	uint32_t Length;
	uint32_t RefCount;
	phymemblock* Blocks;
	int BlockCount;

} phymem;

static phymem PhyMem[MAXPHY] = { 0 };

#else

#define ACCESS_LOAD		KEY_READ
#define ACCESS_SAVE		KEY_READ | KEY_WRITE | KEY_SET_VALUE 

#endif

static HMODULE AygShellDLL = NULL;
static tchar_t DocPath[MAXPATH] = T("");
static tchar_t SysPath[MAXPATH] = T("");

static const tchar_t RegBacklight[] = T("ControlPanel\\Backlight");
static const tchar_t RegBatteryTimeout[] = T("BatteryTimeout");
static const tchar_t RegACTimeout[] = T("ACTimeout");
static const tchar_t RegScreenSaver[] = T("ControlPanel\\ScreenSaver");
static const tchar_t RegMode[] = T("Mode");
static const tchar_t RegPower[] = T("ControlPanel\\Power");
static const tchar_t RegDisplay[] = T("Display");

static const tchar_t RegPowerTimouts[] = T("SYSTEM\\CurrentControlSet\\Control\\Power\\Timeouts");
static const tchar_t RegBattUserIdle[] = T("BattUserIdle");
static const tchar_t RegACUserIdle[] = T("ACUserIdle");
static const tchar_t RegBattSystemIdle[] = T("BattSystemIdle");
static const tchar_t RegACSystemIdle[] = T("ACSystemIdle");
static const tchar_t RegBattSuspend[] = T("BattSuspend");
static const tchar_t RegACSuspend[] = T("ACSuspend");

static const tchar_t RegCASIOBacklight[] = T("Drivers\\CASIO\\BackLight");
static const tchar_t RegTimeoutBattery[] = T("TimeoutBattery");
static const tchar_t RegTimeoutExPower[] = T("TimeoutExPower");

#define GETVFRAMEPHYSICAL			6144
#define GETVFRAMELEN				6145
#define DBGDRIVERSTAT				6146
#define SETPOWERMANAGEMENT			6147
#define GETPOWERMANAGEMENT			6148

typedef struct VIDEO_POWER_MANAGEMENT {
    ULONG Length;
    ULONG DPMSVersion;
    ULONG PowerState;
} VIDEO_POWER_MANAGEMENT;

static rgb Palette[256];

static int PageSize = 4096;
static bool_t WaitCursor = 0;
static bool_t DisplayPower = 1;
static int Orientation = -1;
static void* PhyFrameBuffer = NULL;

#ifndef NDEBUG
static int BlockCount = 0;
#endif

#if defined( MIPS)
int GetTime()
{
	SYSTEMTIME t;
	GetSystemTime(&t);
	return (t.wDay*24+t.wHour)*60*60*1000+(t.wMinute*60+t.wSecond)*1000+t.wMilliseconds;
}
void GetTimeCycle(int* p)
{
	SYSTEMTIME i,j;
	int n=0;
	GetSystemTime(&i);
	do
	{
		++n;
		GetSystemTime(&j);
	}
	while (j.wMilliseconds==i.wMilliseconds);
	p[0] = (j.wDay*24+j.wHour)*60*60*1000+(j.wMinute*60+j.wSecond)*1000+j.wMilliseconds;
	p[1] = n;
}
#elif defined(_WIN32_WCE)
int GetTime()
{
	return GetTickCount();
}
void GetTimeCycle(int* p)
{
	int n=1;
	int j;
	int i = GetTickCount();
	while ((j = GetTickCount())==i)
		++n;
	p[0] = j;
	p[1] = n;
}
#else
int GetTime()
{
	return timeGetTime();
}
void GetTimeCycle(int* p)
{
	int n=1;
	int j;
	int i = timeGetTime();
	while ((j = timeGetTime())==i)
		++n;
	p[0] = j;
	p[1] = n;
}
#endif

static platform Platform;

static int Enum( platform* p, int No, datadef* Param )
{
	return NodeEnumType(&No,Param,NodeParams,PlatformParams,NULL);
}

int CPUSpeed()
{
	//int64_t Freq;
	int64_t Clk,Best = 0;
	int BestCount = 0;
	int n,Count;
	int Speed = 0;
	HANDLE Thread = GetCurrentThread();
	int Priority = GetThreadPriority(Thread);
	SetThreadPriority(Thread,THREAD_PRIORITY_TIME_CRITICAL);
#if defined(_WIN32_WCE)
	if (FuncCeSetThreadQuantum)
		FuncCeSetThreadQuantum(Thread,250);
#endif

	Count = 800;
	{
		int Sub=1,SubTime=8;
		int c0[2];
		int c1[2];
		int t;

		for (n=0;n<16;++n)
		{
			GetTimeCycle(c0);
			GetTimeCycle(c1);
			if (c1[1]*SubTime > Sub*(c1[0]-c0[0]))
			{
				Sub = c1[1];
				SubTime = c1[0]-c0[0];
			}
			if (n>6 && SubTime >= 4)
				break;
		}

		if (SubTime < 4)
		{
			// Sub = approx number of possbile GetTime() calls per SubTime ms

			for (n=0;n<64;++n)
			{
				CPUSpeedClk(1); // load instruction cache
				GetTimeCycle(c0);
				Clk = CPUSpeedClk(Count);
				GetTimeCycle(c1);

				t = c1[0]-c0[0];
#if !defined(_WIN32_WCE)
				// we are assuming a 1ms timer interrupt with 
				// minimum 6500 cycles interrupt handler
				Clk += t*6500;
#else
				if (Platform.Type == TYPE_SMARTPHONE)
					Clk += t*2000;
#endif
				t *= 100000; 
				t -=(c1[1] * 100000 * SubTime)/Sub; // adjust with subtime

				if (t < 25000) 
					Count *= 2;
				else
				if (t < 50000) // at least 0.5ms
					Count += Count/8;
				else
				{
#ifdef ARM
					Clk = (Clk *  99600000) / t;
#else
					Clk = (Clk * 100000000) / t;
#endif
					if (Best < Clk)
					{
						Best = Clk;
						BestCount = 1;
					}
					else
					if ((Best * 127)/128 < Clk && ++BestCount>16)
						break;
				}
			}
		}
	}

	Speed = (int)((Best + 500000)/1000000);

	//rounding
	if ((Speed % 104)==1 || Speed==207) --Speed;
	else if ((Speed % 104)==103 || Speed==205) ++Speed;
	else if ((Speed % 10)==1) --Speed;
	else if ((Speed % 10)==9) ++Speed;
	else if (((Speed % 100)%33)==1) --Speed;
	else if (((Speed % 100)%33)==32) ++Speed;

#if defined(_WIN32_WCE)
	if (FuncCeSetThreadQuantum)
		FuncCeSetThreadQuantum(Thread,25);
#endif
	SetThreadPriority(Thread,Priority);
	return Speed;
}

static int Get( platform* p, int No, void* Data, int Size )
{
	int Result = ERR_INVALID_PARAM;
	switch (No)
	{
	case NODE_ID: GETVALUE(PLATFORM_ID,int); break;
	case PLATFORM_LANG: GETVALUE(StringLang,int); break;
	case PLATFORM_TYPE:	GETSTRING(p->PlatformType[0] ? p->PlatformType : T("Windows")); break;
	case PLATFORM_CPU: GETSTRING(p->CPU); break;
	case PLATFORM_OEMINFO: if (p->OemInfo[0]) GETSTRING(p->OemInfo); break;
	case PLATFORM_VER: GETVALUE(p->Ver,int); break;
	case PLATFORM_TYPENO: GETVALUE(p->Type,int); break;
	case PLATFORM_MODEL: GETVALUE(p->Model,int); break;
	case PLATFORM_CAPS: GETVALUE(p->Caps,int); break;
	case PLATFORM_ICACHE: GETVALUECOND(p->ICache,int,p->ICache>0); break;
	case PLATFORM_DCACHE: GETVALUECOND(p->DCache,int,p->DCache>0); break;
	case PLATFORM_VERSION: 
		stprintf((tchar_t*)Data,T("%d.%02d"),p->Ver/100,p->Ver%100);
		Result = ERR_NONE;
		break;
	case PLATFORM_MHZ: 
		if (Size==sizeof(int))
		{
			int Speed = CPUSpeed();
			if (Speed)
			{
				*(int*)Data = Speed;
				Result = ERR_NONE;
			}
		}
		break;
	}
	return Result;
}

static int Set( platform* p, int No, const void* Data, int Size )
{
	int Result = ERR_INVALID_PARAM;
	switch (No)
	{
	case PLATFORM_LANG: SETVALUE(StringLang,int,ERR_NONE); break;
	}
	return ERR_INVALID_PARAM;
}

int QueryPlatform( int Param )
{
	int Value;
	Platform.VMT.Get(&Platform,Param,&Value,sizeof(Value));
	return Value;
}

void SafeGetCpuId( int Id, uint32_t* p )
{
	memset(p,0,4*sizeof(uint32_t));
	TRY_BEGIN
	{
		bool_t Mode = KernelMode(1);
		GetCpuId(Id,p); 
		KernelMode(Mode);
	}
	TRY_END
}

void GetProc(void** Module,void* Ptr,const tchar_t* ProcName,int Optional)
{
	FARPROC* Func = (FARPROC*)Ptr;
	if (*Module)
	{
#if !defined(_WIN32_WCE) && defined(UNICODE)
		char ProcName8[256];
		wcstombs(ProcName8,ProcName,sizeof(ProcName8));
		*Func = GetProcAddress(*Module,ProcName8);
#else
		*Func = GetProcAddress(*Module,ProcName);
#endif
		if (!*Func && !Optional)
		{
			FreeLibrary(*Module);
			*Module = NULL;
		}
	}
	else
		*Func = NULL;
}

void Platform_Init()
{
#if defined(_WIN32_WCE)
	tchar_t OemUpper[256];
	RECT WorkArea;
#endif

	char Lang8[16];
	tchar_t Lang[16];
	SYSTEM_INFO SysInfo;
	OSVERSIONINFO Ver;
	platform* p = &Platform;
#ifndef SH3
	uint32_t CpuId[4];
#endif

#if defined(_DEBUG) && defined(_MSC_VER) && !defined(_WIN32_WCE)
	int Flag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
	Flag |= _CRTDBG_LEAK_CHECK_DF;
	//Flag |= _CRTDBG_CHECK_ALWAYS_DF;
	_CrtSetDbgFlag( Flag );
#endif

	NodeFill(&p->VMT,sizeof(platform),Enum,Get,Set);

	Ver.dwOSVersionInfoSize = sizeof(Ver);
	GetVersionEx(&Ver);

	GetSystemInfo(&SysInfo);
	PageSize = SysInfo.dwPageSize;

	p->Type = TYPE_UNKNOWN;
	p->Ver = Ver.dwMajorVersion*100 + Ver.dwMinorVersion;
	p->OemInfo[0] = 0;
	p->PlatformType[0] = 0;

#if defined(_WIN32_WCE)
	AygShellDLL = LoadLibrary(T("aygshell.dll"));
	if (AygShellDLL)
		*(FARPROC*)&FuncSHIdleTimerReset = GetProcAddress(AygShellDLL,MAKEINTRESOURCE(2006));

	CoreDLL = LoadLibrary(T("coredll.dll"));
	if (CoreDLL)
	{
		*(FARPROC*)&FuncChangeDisplaySettingsEx = GetProcAddress(CoreDLL,T("ChangeDisplaySettingsEx"));
		*(FARPROC*)&FuncCacheSync = GetProcAddress(CoreDLL,T("CacheSync"));
		*(FARPROC*)&FuncVirtualCopy = GetProcAddress(CoreDLL,T("VirtualCopy"));
		*(FARPROC*)&FuncCeSetThreadQuantum = GetProcAddress(CoreDLL,T("CeSetThreadQuantum"));
		*(FARPROC*)&FuncSetKMode = GetProcAddress(CoreDLL,T("SetKMode"));
		*(FARPROC*)&FuncRedrawWindow = GetProcAddress(CoreDLL,T("RedrawWindow"));
		*(FARPROC*)&FuncSHGetSpecialFolderPath = GetProcAddress(CoreDLL,T("SHGetSpecialFolderPath"));
		*(FARPROC*)&FuncSetPowerRequirement = GetProcAddress(CoreDLL,T("SetPowerRequirement"));
		*(FARPROC*)&FuncReleasePowerRequirement = GetProcAddress(CoreDLL,T("ReleasePowerRequirement"));
		*(FARPROC*)&FuncVirtualSetAttributes = GetProcAddress(CoreDLL,T("VirtualSetAttributes"));
		*(FARPROC*)&FuncFreePhysMem = GetProcAddress(CoreDLL,T("FreePhysMem"));
		*(FARPROC*)&FuncAllocPhysMem = GetProcAddress(CoreDLL,T("AllocPhysMem"));
		*(FARPROC*)&FuncLockPages = GetProcAddress(CoreDLL,T("LockPages"));
		*(FARPROC*)&FuncUnlockPages = GetProcAddress(CoreDLL,T("UnlockPages"));
	}
	CEShellDLL = LoadLibrary(T("ceshell.dll"));
	if (CEShellDLL)

⌨️ 快捷键说明

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