Add rayman2 source files
This commit is contained in:
177
Rayman_X/cpa/tempgrp/Tmr/TMR.dsp
Normal file
177
Rayman_X/cpa/tempgrp/Tmr/TMR.dsp
Normal file
@@ -0,0 +1,177 @@
|
||||
# Microsoft Developer Studio Project File - Name="TMR" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 5.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||
|
||||
CFG=TMR - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "TMR.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "TMR.mak" CFG="TMR - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "TMR - Win32 Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "TMR - Win32 Debug" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "TMR - Win32 Retail" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP Scc_ProjName ""$/cpa/tempgrp/Tmr", ADFAAAAA"
|
||||
# PROP Scc_LocalPath "."
|
||||
CPP=cl.exe
|
||||
|
||||
!IF "$(CFG)" == "TMR - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "x:\cpa\lib"
|
||||
# PROP Intermediate_Dir "Tmp\Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
|
||||
# ADD CPP /nologo /G5 /W3 /GX /O2 /I "X:\CPA\Public" /I "T:\DXSDK\SDK\Inc" /I "X:\CPA\TempGrp\Tmr\specif" /D "NDEBUG" /D "VISUAL" /D "WIN32" /D "USE_PROFILER" /FD /c
|
||||
# SUBTRACT CPP /Fr /YX
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo /out:"X:\CPA\Lib\TMRP5_vr.lib"
|
||||
|
||||
!ELSEIF "$(CFG)" == "TMR - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "X:\CPA\Lib"
|
||||
# PROP Intermediate_Dir "Tmp\Debug"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
|
||||
# ADD CPP /nologo /G5 /W3 /GX /Z7 /Od /I "X:\CPA\Public" /I "T:\DXSDK\SDK\Inc" /I "X:\CPA\TempGrp\Tmr\specif" /D "_DEBUG" /D "VISUAL" /D "WIN32" /D "USE_PROFILER" /D "MTH_CHECK" /D "CPA_WANTS_EXPORT" /FD /c
|
||||
# SUBTRACT CPP /Fr /YX
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo /out:"X:\CPA\Lib\TMRP5_vd.lib"
|
||||
|
||||
!ELSEIF "$(CFG)" == "TMR - Win32 Retail"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "TMR___Wi"
|
||||
# PROP BASE Intermediate_Dir "TMR___Wi"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "x:\cpa\lib"
|
||||
# PROP Intermediate_Dir "tmp\retail"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /G5 /W3 /GX /O2 /I "X:\CPA\Public" /I "T:\DXSDK\SDK\Inc" /I "X:\CPA\TempGrp\Tmr\specif" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "CPA_WANTS_EXPORT VISUAL" /FD /c
|
||||
# SUBTRACT BASE CPP /Fr /YX
|
||||
# ADD CPP /nologo /G5 /W3 /GX /O2 /I "X:\CPA\Public" /I "T:\DXSDK\SDK\Inc" /I "X:\CPA\TempGrp\Tmr\specif" /D "NDEBUG" /D "VISUAL" /D "WIN32" /D "RETAIL" /FD /c
|
||||
# SUBTRACT CPP /Fr /YX
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo /out:"X:\CPA\Lib\TMRP5_vr.lib"
|
||||
# ADD LIB32 /nologo /out:"X:\CPA\Lib\TMRP5_vf.lib"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "TMR - Win32 Release"
|
||||
# Name "TMR - Win32 Debug"
|
||||
# Name "TMR - Win32 Retail"
|
||||
# Begin Group "src"
|
||||
|
||||
# PROP Default_Filter "*.c;*.cpp;*.cxx"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\specif\Detect.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Timer.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\specif\Timer.cxx
|
||||
|
||||
!IF "$(CFG)" == "TMR - Win32 Release"
|
||||
|
||||
# PROP Exclude_From_Build 1
|
||||
|
||||
!ELSEIF "$(CFG)" == "TMR - Win32 Debug"
|
||||
|
||||
# PROP Exclude_From_Build 1
|
||||
|
||||
!ELSEIF "$(CFG)" == "TMR - Win32 Retail"
|
||||
|
||||
# PROP BASE Exclude_From_Build 1
|
||||
# PROP Exclude_From_Build 1
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\specif\TimerPrv.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "inc"
|
||||
|
||||
# PROP Default_Filter "*.h;*.hpp"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\public\TMR\specif\counter.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\specif\DETECT.H
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\public\TMR\errTmr.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\public\TMR\Struct.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\public\TMR\Timer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\specif\TimerPrv.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\public\TMR.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\TMR.mak
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
314
Rayman_X/cpa/tempgrp/Tmr/TMR.vcproj
Normal file
314
Rayman_X/cpa/tempgrp/Tmr/TMR.vcproj
Normal file
@@ -0,0 +1,314 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="TMR"
|
||||
ProjectGUID="{8981D00F-1E2E-4A24-ADD8-58632B012E02}"
|
||||
SccProjectName=""$/cpa/tempgrp/Tmr", ADFAAAAA"
|
||||
SccAuxPath=""
|
||||
SccLocalPath="."
|
||||
SccProvider="MSSCCI:NXN alienbrain">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="X:\CPA\Libd"
|
||||
IntermediateDirectory=".\Tmp\Debug"
|
||||
ConfigurationType="4"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
OptimizeForProcessor="1"
|
||||
AdditionalIncludeDirectories="X:\CPA\Public,T:\DXSDK\SDK\Inc,X:\CPA\TempGrp\Tmr\specif"
|
||||
PreprocessorDefinitions="_DEBUG;VISUAL;WIN32;USE_PROFILER;MTH_CHECK;CPA_WANTS_EXPORT"
|
||||
RuntimeLibrary="3"
|
||||
PrecompiledHeaderFile=".\Tmp\Debug/TMR.pch"
|
||||
AssemblerListingLocation=".\Tmp\Debug/"
|
||||
ObjectFile=".\Tmp\Debug/"
|
||||
ProgramDataBaseFileName=".\Tmp\Debug/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
DebugInformationFormat="1"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="X:\CPA\Libd\TMRP5_vd.lib"
|
||||
SuppressStartupBanner="TRUE"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Retail|Win32"
|
||||
OutputDirectory="x:\cpa\lib"
|
||||
IntermediateDirectory=".\tmp\retail"
|
||||
ConfigurationType="4"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
OptimizeForProcessor="1"
|
||||
AdditionalIncludeDirectories="X:\CPA\Public,T:\DXSDK\SDK\Inc,X:\CPA\TempGrp\Tmr\specif"
|
||||
PreprocessorDefinitions="NDEBUG;VISUAL;WIN32;RETAIL"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="4"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
PrecompiledHeaderFile=".\tmp\retail/TMR.pch"
|
||||
AssemblerListingLocation=".\tmp\retail/"
|
||||
ObjectFile=".\tmp\retail/"
|
||||
ProgramDataBaseFileName=".\tmp\retail/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="X:\CPA\Lib\TMRP5_vf.lib"
|
||||
SuppressStartupBanner="TRUE"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="x:\cpa\lib"
|
||||
IntermediateDirectory=".\Tmp\Release"
|
||||
ConfigurationType="4"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
OptimizeForProcessor="1"
|
||||
AdditionalIncludeDirectories="X:\CPA\Public,T:\DXSDK\SDK\Inc,X:\CPA\TempGrp\Tmr\specif"
|
||||
PreprocessorDefinitions="NDEBUG;VISUAL;WIN32;USE_PROFILER"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="4"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
PrecompiledHeaderFile=".\Tmp\Release/TMR.pch"
|
||||
AssemblerListingLocation=".\Tmp\Release/"
|
||||
ObjectFile=".\Tmp\Release/"
|
||||
ProgramDataBaseFileName=".\Tmp\Release/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="X:\CPA\Lib\TMRP5_vr.lib"
|
||||
SuppressStartupBanner="TRUE"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="src"
|
||||
Filter="*.c;*.cpp;*.cxx">
|
||||
<File
|
||||
RelativePath="specif\Detect.c">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Retail|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Timer.c">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Retail|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="specif\Timer.cxx">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Retail|Win32"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="specif\TimerPrv.c">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Retail|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="inc"
|
||||
Filter="*.h;*.hpp">
|
||||
<File
|
||||
RelativePath="..\..\public\TMR\specif\counter.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="specif\DETECT.H">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\public\TMR\errTmr.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\public\TMR\Struct.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\public\TMR\Timer.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="specif\TimerPrv.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\public\TMR.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath="TMR.mak">
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
674
Rayman_X/cpa/tempgrp/Tmr/Timer.c
Normal file
674
Rayman_X/cpa/tempgrp/Tmr/Timer.c
Normal file
@@ -0,0 +1,674 @@
|
||||
/***************************************************************************/
|
||||
/* Description: CPA Timer.lib. */
|
||||
/* */
|
||||
/* Author: F. Jentey. */
|
||||
/* Last Update : 04/03/97 */
|
||||
/* 14/04/97 Change prototype using TMR_fn_xxxx */
|
||||
/* 16/04/97 Include CPA_std.h */
|
||||
/* MT 30/04/98 Take PSX account */
|
||||
/* Translate functions into Timer.cxx specific file*/
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include "CPA_std.h"
|
||||
|
||||
#ifdef PSX
|
||||
#include "PSX.h"
|
||||
#endif /* PSX */
|
||||
|
||||
/* CPA errors */
|
||||
#include "ERM.h"
|
||||
#define __DeclareGlobalVariableErrTmr_h__
|
||||
#include "TMR/errTmr.h"
|
||||
#undef __DeclareGlobalVariableErrTmr_h__
|
||||
|
||||
#include "TMR/Timer.h"
|
||||
#include "Specif/TimerPrv.h"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
To store the frequency of each timer type. If a type of timer isn't
|
||||
available, the corresponding entry is null. It's the case for event timer
|
||||
fro the medium and high frequency.
|
||||
*/
|
||||
u_long a3_ulTimerFrequency[3];
|
||||
u_long a3_ulEventFrequency[3];
|
||||
|
||||
|
||||
/* Info variables */
|
||||
tdstTimer a_stTimerTab[C_uwTimerMaxCount];
|
||||
short wTimerCount = 0;
|
||||
short TimerLibOk = 0; /* Equals to the actual number of user */
|
||||
short TMR_g_wErmOK = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
/************************************************/
|
||||
/* Private functions */
|
||||
/************************************************/
|
||||
|
||||
/*
|
||||
Add, Sub stTimerCount value
|
||||
stOp1 is always greater than stOp2
|
||||
*/
|
||||
void fn_vAddTimerValues(stTimerCount* stOp1, stTimerCount* stOp2)
|
||||
{
|
||||
u_long ulTmpValue;
|
||||
|
||||
ulTmpValue = stOp1->m_ulLowPart + stOp2->m_ulLowPart;
|
||||
if ( ulTmpValue < stOp1->m_ulLowPart )
|
||||
stOp1->m_ulHighPart++;
|
||||
stOp1->m_ulLowPart = ulTmpValue;
|
||||
|
||||
stOp1->m_ulHighPart += stOp2->m_ulHighPart;
|
||||
}
|
||||
void fn_vSubTimerValues(stTimerCount* stOp1, stTimerCount* stOp2)
|
||||
{
|
||||
if ( stOp1->m_ulHighPart == stOp2->m_ulHighPart )
|
||||
{
|
||||
stOp1->m_ulLowPart -= stOp2->m_ulLowPart;
|
||||
stOp1->m_ulHighPart = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( stOp1->m_ulLowPart >= stOp2->m_ulLowPart )
|
||||
stOp1->m_ulLowPart -= stOp2->m_ulLowPart;
|
||||
else
|
||||
{
|
||||
stOp1->m_ulLowPart += 0xffffffff - stOp2->m_ulLowPart + 1;
|
||||
stOp1->m_ulHighPart--;
|
||||
}
|
||||
stOp1->m_ulHighPart -= stOp2->m_ulHighPart;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/************************************************/
|
||||
/* Public functions */
|
||||
/************************************************/
|
||||
|
||||
/*
|
||||
short __stdcall TMR_fn_wInitLibrary( void )
|
||||
and
|
||||
short __stdcall TMR_fn_wExitLibrary( void )
|
||||
translated into the Timer.cxx specific file
|
||||
*/
|
||||
|
||||
#include "Specif\Timer.cxx"
|
||||
|
||||
/*
|
||||
This fonction create a timer and return an handle to this timer.
|
||||
The parameter wTimerType define the resolution of the timer and must
|
||||
set to one of the C_wTimerType Flag.
|
||||
*/
|
||||
short __stdcall TMR_fn_wCreateTimer( short wTimerType )
|
||||
{
|
||||
short i;
|
||||
|
||||
if ( TimerLibOk == 0 )
|
||||
{
|
||||
Erm_M_UpdateLastError(Tmr, C_ucErmDefaultChannel, E_uwTmrLibraryNotInitialized, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
if ( wTimerCount == C_uwTimerMaxCount )
|
||||
{
|
||||
Erm_M_UpdateLastError(Tmr, C_ucErmDefaultChannel, E_uwTmrMaxTimerCountReached, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
if ( wTimerType > C_wTimerFrequencyHigh )
|
||||
{
|
||||
Erm_M_UpdateLastError(Tmr, C_ucErmDefaultChannel, E_uwTmrInvalidType, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
if ( a3_ulTimerFrequency[wTimerType] == 0 )
|
||||
{
|
||||
Erm_M_UpdateLastError(Tmr, C_ucErmDefaultChannel, E_uwTmrTypeNotAvailable, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
|
||||
for ( i = 0 ; i < C_uwTimerMaxCount ; i++ )
|
||||
if ( a_stTimerTab[i].m_wTimerState == C_wTimerUnused ) break;
|
||||
if ( i == C_uwTimerMaxCount )
|
||||
{
|
||||
Erm_M_UpdateLastError(Tmr, C_ucErmDefaultChannel, E_uwTmrMaxTimerCountReached, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
|
||||
a_stTimerTab[i].m_wTimerType = wTimerType;
|
||||
a_stTimerTab[i].m_wTimerState = C_wTimerReady;
|
||||
wTimerCount++;
|
||||
|
||||
return (i);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Start a timer.
|
||||
*/
|
||||
short __stdcall TMR_fn_wStartTimer( short wTimerHandle )
|
||||
{
|
||||
short wTimerType;
|
||||
stTimerCount stValue;
|
||||
|
||||
if ( TimerLibOk == 0 )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrLibraryNotInitialized, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
if ( wTimerHandle >= C_uwTimerMaxCount )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrInvalidHandle, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
if ( a_stTimerTab[wTimerHandle].m_wTimerState == C_wTimerUnused )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrInvalidHandle, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
if ( a_stTimerTab[wTimerHandle].m_wTimerType > C_wTimerFrequencyHigh )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrInvalidForEventTimer, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
/*if ( (a_stTimerTab[wTimerHandle].m_wTimerState != C_wTimerReady) &&
|
||||
(a_stTimerTab[wTimerHandle].m_wTimerState != C_wTimerPaused) )
|
||||
{
|
||||
ulTimerErrorCode = C_ErrTimerNotReady;
|
||||
return (C_wTimerError);
|
||||
}*/
|
||||
|
||||
wTimerType = a_stTimerTab[wTimerHandle].m_wTimerType;
|
||||
fn_vTimerGetCounter(wTimerType,&stValue);
|
||||
|
||||
a_stTimerTab[wTimerHandle].m_stTimerCount_InitValue.m_ulLowPart = stValue.m_ulLowPart;
|
||||
a_stTimerTab[wTimerHandle].m_stTimerCount_InitValue.m_ulHighPart = stValue.m_ulHighPart;
|
||||
|
||||
if ( a_stTimerTab[wTimerHandle].m_wTimerState != C_wTimerPaused )
|
||||
{
|
||||
a_stTimerTab[wTimerHandle].m_stTimerCount_TotalValue.m_ulLowPart = 0;
|
||||
a_stTimerTab[wTimerHandle].m_stTimerCount_TotalValue.m_ulHighPart = 0;
|
||||
}
|
||||
|
||||
a_stTimerTab[wTimerHandle].m_wTimerState = C_wTimerRunning;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Stop a Timer.
|
||||
*/
|
||||
short __stdcall TMR_fn_wStopTimer( short wTimerHandle )
|
||||
{
|
||||
short wTimerType;
|
||||
stTimerCount stValue;
|
||||
|
||||
if ( TimerLibOk == 0 )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrLibraryNotInitialized, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
if ( wTimerHandle >= C_uwTimerMaxCount )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrInvalidHandle, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
if ( a_stTimerTab[wTimerHandle].m_wTimerState == C_wTimerUnused )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrInvalidHandle, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
if ( a_stTimerTab[wTimerHandle].m_wTimerType > C_wTimerFrequencyHigh )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrInvalidForEventTimer, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
/*if (a_stTimerTab[wTimerHandle].m_wTimerState < C_wTimerRunning )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrStartTimerFirst, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}*/
|
||||
|
||||
wTimerType = a_stTimerTab[wTimerHandle].m_wTimerType;
|
||||
|
||||
if ( a_stTimerTab[wTimerHandle].m_wTimerState == C_wTimerRunning )
|
||||
{
|
||||
fn_vTimerGetCounter(wTimerType,&stValue);
|
||||
a_stTimerTab[wTimerHandle].m_stTimerCount_LastValue.m_ulLowPart = stValue.m_ulLowPart;
|
||||
a_stTimerTab[wTimerHandle].m_stTimerCount_LastValue.m_ulHighPart = stValue.m_ulHighPart;
|
||||
}
|
||||
|
||||
if ( a_stTimerTab[wTimerHandle].m_wTimerState == C_wTimerPaused )
|
||||
{
|
||||
a_stTimerTab[wTimerHandle].m_stTimerCount_LastValue.m_ulLowPart =
|
||||
a_stTimerTab[wTimerHandle].m_stTimerCount_TotalValue.m_ulLowPart;
|
||||
a_stTimerTab[wTimerHandle].m_stTimerCount_LastValue.m_ulHighPart =
|
||||
a_stTimerTab[wTimerHandle].m_stTimerCount_TotalValue.m_ulHighPart;
|
||||
|
||||
a_stTimerTab[wTimerHandle].m_stTimerCount_TotalValue.m_ulLowPart = 0;
|
||||
a_stTimerTab[wTimerHandle].m_stTimerCount_TotalValue.m_ulHighPart = 0;
|
||||
a_stTimerTab[wTimerHandle].m_stTimerCount_InitValue.m_ulLowPart = 0;
|
||||
a_stTimerTab[wTimerHandle].m_stTimerCount_InitValue.m_ulHighPart = 0;
|
||||
}
|
||||
|
||||
a_stTimerTab[wTimerHandle].m_wTimerState = C_wTimerStop;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Pause a Timer.
|
||||
*/
|
||||
|
||||
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
|
||||
short __stdcall TMR_fn_wPauseTimer( short wTimerHandle )
|
||||
{
|
||||
short wTimerType;
|
||||
stTimerCount stValue, stTempCount;
|
||||
|
||||
if ( TimerLibOk == 0 )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrLibraryNotInitialized, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
if ( wTimerHandle >= C_uwTimerMaxCount )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrInvalidHandle, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
if ( a_stTimerTab[wTimerHandle].m_wTimerState == C_wTimerUnused )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrInvalidHandle, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
if ( a_stTimerTab[wTimerHandle].m_wTimerType > C_wTimerFrequencyHigh )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrInvalidForEventTimer, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
/*
|
||||
if (a_stTimerTab[wTimerHandle].m_wTimerState < C_wTimerRunning )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrStartTimerFirst, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}*/
|
||||
|
||||
wTimerType = a_stTimerTab[wTimerHandle].m_wTimerType;
|
||||
|
||||
/* If the timer is running, Add the elapsed time to the total count */
|
||||
if ( a_stTimerTab[wTimerHandle].m_wTimerState == C_wTimerRunning )
|
||||
{
|
||||
fn_vTimerGetCounter(wTimerType,&stTempCount);
|
||||
|
||||
stValue.m_ulLowPart = a_stTimerTab[wTimerHandle].m_stTimerCount_InitValue.m_ulLowPart;
|
||||
stValue.m_ulHighPart = a_stTimerTab[wTimerHandle].m_stTimerCount_InitValue.m_ulHighPart;
|
||||
fn_vSubTimerValues(&stTempCount,&stValue);
|
||||
|
||||
stValue.m_ulLowPart = a_stTimerTab[wTimerHandle].m_stTimerCount_TotalValue.m_ulLowPart;
|
||||
stValue.m_ulHighPart = a_stTimerTab[wTimerHandle].m_stTimerCount_TotalValue.m_ulHighPart;
|
||||
fn_vAddTimerValues(&stTempCount,&stValue);
|
||||
a_stTimerTab[wTimerHandle].m_stTimerCount_TotalValue.m_ulLowPart = stTempCount.m_ulLowPart;
|
||||
a_stTimerTab[wTimerHandle].m_stTimerCount_TotalValue.m_ulHighPart = stTempCount.m_ulHighPart;
|
||||
}
|
||||
|
||||
a_stTimerTab[wTimerHandle].m_wTimerState = C_wTimerPaused;
|
||||
|
||||
return (0);
|
||||
}
|
||||
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Set timer current value. The timer is paused
|
||||
*/
|
||||
short __stdcall TMR_fn_wSetTimerValue( short wTimerHandle, stTimerCount *p_stValue )
|
||||
{
|
||||
short wTimerType;
|
||||
|
||||
if ( TimerLibOk == 0 )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrLibraryNotInitialized, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
if ( wTimerHandle >= C_uwTimerMaxCount )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrInvalidHandle, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
if ( a_stTimerTab[wTimerHandle].m_wTimerType > C_wTimerFrequencyHigh )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrInvalidForEventTimer, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
|
||||
wTimerType = a_stTimerTab[wTimerHandle].m_wTimerType;
|
||||
|
||||
a_stTimerTab[wTimerHandle].m_stTimerCount_TotalValue.m_ulLowPart = p_stValue->m_ulLowPart;
|
||||
a_stTimerTab[wTimerHandle].m_stTimerCount_TotalValue.m_ulHighPart = p_stValue->m_ulHighPart;
|
||||
|
||||
a_stTimerTab[wTimerHandle].m_wTimerState = C_wTimerPaused;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Return the timer count tdsTimerCount structure pointed by p_tdsTimerCount.
|
||||
*/
|
||||
short __stdcall TMR_fn_wReadTimer( short wTimerHandle, stTimerCount *p_stTimerCount)
|
||||
{
|
||||
short wTimerState;
|
||||
stTimerCount stValue;
|
||||
|
||||
/* p_stTimerCount->m_ulLowPart = 0;
|
||||
p_stTimerCount->m_ulHighPart = 0;
|
||||
*/
|
||||
if ( TimerLibOk == 0 )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrLibraryNotInitialized, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
if ( wTimerHandle >= C_uwTimerMaxCount )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrInvalidHandle, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
if ( a_stTimerTab[wTimerHandle].m_wTimerState == C_wTimerUnused )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrInvalidHandle, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
if ( a_stTimerTab[wTimerHandle].m_wTimerType > C_wTimerFrequencyHigh )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrInvalidForEventTimer, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
/*
|
||||
if ( a_stTimerTab[wTimerHandle].m_wTimerState < C_wTimerRunning )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrStartTimerFirst, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}*/
|
||||
|
||||
wTimerState = a_stTimerTab[wTimerHandle].m_wTimerState;
|
||||
|
||||
switch ( wTimerState )
|
||||
{
|
||||
|
||||
/* If the timer is running */
|
||||
case C_wTimerRunning:
|
||||
fn_vTimerGetCounter(a_stTimerTab[wTimerHandle].m_wTimerType,p_stTimerCount);
|
||||
stValue.m_ulLowPart = a_stTimerTab[wTimerHandle].m_stTimerCount_InitValue.m_ulLowPart;
|
||||
stValue.m_ulHighPart = a_stTimerTab[wTimerHandle].m_stTimerCount_InitValue.m_ulHighPart;
|
||||
fn_vSubTimerValues(p_stTimerCount,&stValue);
|
||||
break;
|
||||
|
||||
/* If the timer is stoped */
|
||||
case C_wTimerStop:
|
||||
p_stTimerCount->m_ulLowPart = a_stTimerTab[wTimerHandle].m_stTimerCount_LastValue.m_ulLowPart;
|
||||
p_stTimerCount->m_ulHighPart = a_stTimerTab[wTimerHandle].m_stTimerCount_LastValue.m_ulHighPart;
|
||||
stValue.m_ulLowPart = a_stTimerTab[wTimerHandle].m_stTimerCount_InitValue.m_ulLowPart;
|
||||
stValue.m_ulHighPart = a_stTimerTab[wTimerHandle].m_stTimerCount_InitValue.m_ulHighPart;
|
||||
fn_vSubTimerValues(p_stTimerCount,&stValue);
|
||||
break;
|
||||
|
||||
/* If the timer is paused or ready */
|
||||
case C_wTimerReady:
|
||||
case C_wTimerPaused:
|
||||
p_stTimerCount->m_ulHighPart = 0;
|
||||
p_stTimerCount->m_ulLowPart = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Add the total count */
|
||||
stValue.m_ulLowPart = a_stTimerTab[wTimerHandle].m_stTimerCount_TotalValue.m_ulLowPart;
|
||||
stValue.m_ulHighPart = a_stTimerTab[wTimerHandle].m_stTimerCount_TotalValue.m_ulHighPart;
|
||||
fn_vAddTimerValues(p_stTimerCount,&stValue);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Reset a timer.
|
||||
*/
|
||||
short __stdcall TMR_fn_wResetTimer( short wTimerHandle )
|
||||
{
|
||||
if ( TimerLibOk == 0 )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrLibraryNotInitialized, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
if ( wTimerHandle >= C_uwTimerMaxCount )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrInvalidHandle, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
if ( a_stTimerTab[wTimerHandle].m_wTimerState == C_wTimerUnused )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrInvalidHandle, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
if ( a_stTimerTab[wTimerHandle].m_wTimerType > C_wTimerFrequencyHigh )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrInvalidForEventTimer, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
|
||||
a_stTimerTab[wTimerHandle].m_wTimerState = C_wTimerReady;
|
||||
|
||||
a_stTimerTab[wTimerHandle].m_stTimerCount_InitValue.m_ulLowPart = 0;
|
||||
a_stTimerTab[wTimerHandle].m_stTimerCount_InitValue.m_ulHighPart = 0;
|
||||
a_stTimerTab[wTimerHandle].m_stTimerCount_LastValue.m_ulLowPart = 0;
|
||||
a_stTimerTab[wTimerHandle].m_stTimerCount_LastValue.m_ulHighPart = 0;
|
||||
a_stTimerTab[wTimerHandle].m_stTimerCount_TotalValue.m_ulLowPart = 0;
|
||||
a_stTimerTab[wTimerHandle].m_stTimerCount_TotalValue.m_ulHighPart = 0;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Destroy a timer.
|
||||
*/
|
||||
|
||||
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
|
||||
short __stdcall TMR_fn_wDestroyTimer( short wTimerHandle )
|
||||
{
|
||||
if ( TimerLibOk == 0 )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrLibraryNotInitialized, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
if ( (wTimerHandle >= C_uwTimerMaxCount) ||
|
||||
(a_stTimerTab[wTimerHandle].m_wTimerState == C_wTimerUnused) )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrInvalidHandle, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
|
||||
a_stTimerTab[wTimerHandle].m_wTimerState = C_wTimerUnused;
|
||||
|
||||
/* If the timer is an event timer, destroy the event*/
|
||||
if ( a_stTimerTab[wTimerHandle].m_wTimerType > C_wTimerFrequencyHigh )
|
||||
{
|
||||
fn_wTimerDestroyEvent( a_stTimerTab[wTimerHandle].m_ulEventId );
|
||||
a_stTimerTab[wTimerHandle].m_ulEventId = 0;
|
||||
a_stTimerTab[wTimerHandle].m_p_fn_vEventCallback = NULL;
|
||||
}
|
||||
|
||||
wTimerCount--;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This function fills the p_ulFrequency with the frequency of the
|
||||
specified timer type.
|
||||
*/
|
||||
short __stdcall TMR_fn_wGetTimerFrequency( short wTimerHandle , u_long *p_ulFrequency )
|
||||
{
|
||||
short wTimerType;
|
||||
|
||||
if ( TimerLibOk == 0 )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrLibraryNotInitialized, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
if ( a_stTimerTab[wTimerHandle].m_wTimerState == C_wTimerUnused )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrInvalidHandle, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
if ( a_stTimerTab[wTimerHandle].m_wTimerState == C_wTimerUnused )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrInvalidHandle, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
|
||||
wTimerType = a_stTimerTab[wTimerHandle].m_wTimerType;
|
||||
if ( wTimerType <= C_wTimerFrequencyHigh )
|
||||
*p_ulFrequency = a3_ulTimerFrequency[wTimerType];
|
||||
else
|
||||
*p_ulFrequency = a3_ulEventFrequency[wTimerType - C_wTimerEvent];
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This function wait The time unit is system dependant but should be
|
||||
1000 ticks per second.
|
||||
*/
|
||||
short __stdcall TMR_fn_wWait( u_long ulTimeToWait )
|
||||
{
|
||||
|
||||
if ( TimerLibOk == 0 )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrLibraryNotInitialized, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
fn_vTimerWait(ulTimeToWait);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Return the number of ticks pre second for the fn_wTimerDelay function
|
||||
*/
|
||||
short __stdcall TMR_fn_wGetWaitTickPerSecond(u_long *p_ulDelayFrequency)
|
||||
{
|
||||
if ( TimerLibOk == 0 )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrLibraryNotInitialized, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
*p_ulDelayFrequency = fn_ulTimerWaitTicksPerSecond();
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This function create a callback timer. Parameters are the timer ncy,
|
||||
a pointer to the callback function (returning void) and the timer type.
|
||||
ulPeriod defines the interval between two call of the callback function.
|
||||
The C_wTimerFrequencyLow is the only timer type available for event timer.
|
||||
*/
|
||||
short __stdcall TMR_fn_wCreateEvent(
|
||||
u_long ulPeriod ,
|
||||
td_p_fn_vTimerEventCallback p_fn_vEventCallback ,
|
||||
short wTimerType ,
|
||||
u_long ulTimerEventType
|
||||
)
|
||||
{
|
||||
short wCreateEventResult;
|
||||
u_long ulEventId;
|
||||
int i;
|
||||
|
||||
if ( TimerLibOk == 0 )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrLibraryNotInitialized, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
if ( wTimerType > C_wTimerFrequencyLow )
|
||||
{
|
||||
Erm_M_UpdateLastError(Tmr, C_ucErmDefaultChannel, E_uwTmrTypeNotAvailable, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
for ( i = 0 ; i < C_uwTimerMaxCount ; i++ )
|
||||
if ( (a_stTimerTab[i].m_wTimerState == C_wTimerUnused) || (i>=C_uwTimerMaxCount) ) break;
|
||||
if ( i == C_uwTimerMaxCount )
|
||||
{
|
||||
Erm_M_UpdateLastError(Tmr, C_ucErmDefaultChannel, E_uwTmrMaxTimerCountReached, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
|
||||
a_stTimerTab[i].m_wTimerType = wTimerType + C_wTimerEvent;
|
||||
a_stTimerTab[i].m_wTimerState = C_wTimerReady;
|
||||
|
||||
wCreateEventResult = fn_wTimerNewEvent(
|
||||
ulPeriod,
|
||||
a3_ulEventFrequency[wTimerType],
|
||||
p_fn_vEventCallback,
|
||||
ulTimerEventType,
|
||||
&ulEventId
|
||||
);
|
||||
if ( wCreateEventResult == C_wTimerError )
|
||||
{
|
||||
a_stTimerTab[i].m_wTimerState = C_wTimerUnused;
|
||||
Erm_M_UpdateLastError(Tmr, C_ucErmDefaultChannel, E_uwTmrCreateEventFailed, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
a_stTimerTab[i].m_ulEventId = ulEventId;
|
||||
a_stTimerTab[i].m_p_fn_vEventCallback = p_fn_vEventCallback;
|
||||
|
||||
wTimerCount++;
|
||||
|
||||
return (i);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This function return vertical refresh rate in Hz * 100.
|
||||
*/
|
||||
u_long __stdcall TMR_fn_ulMonitorFrequency( void )
|
||||
{
|
||||
u_long ulFrequency;
|
||||
|
||||
if ( TimerLibOk == 0 )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrLibraryNotInitialized, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
|
||||
ulFrequency = fn_ulTimerVerticalRefreshRate(a3_ulTimerFrequency[C_wTimerFrequencyHigh]);
|
||||
|
||||
return (ulFrequency);
|
||||
}
|
||||
|
||||
/*
|
||||
This function return the length of a frame. The units length is the tick
|
||||
of a C_wTimerFrequencyHigh timer type (so the return value is the number CPU cycle)
|
||||
*/
|
||||
u_long __stdcall TMR_fn_ulFrameCycleNumber( void )
|
||||
{
|
||||
u_long ulFrequency;
|
||||
|
||||
if ( TimerLibOk == 0 )
|
||||
{
|
||||
Erm_M_UpdateLastError (Tmr, C_ucErmDefaultChannel, E_uwTmrLibraryNotInitialized, C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, NULL);
|
||||
return (C_wTimerError);
|
||||
}
|
||||
|
||||
ulFrequency = fn_ulTimerFrameLength();
|
||||
|
||||
return (ulFrequency);
|
||||
}
|
||||
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
|
||||
|
5
Rayman_X/cpa/tempgrp/Tmr/mssccprj.scc
Normal file
5
Rayman_X/cpa/tempgrp/Tmr/mssccprj.scc
Normal file
@@ -0,0 +1,5 @@
|
||||
SCC = This is a source code control file
|
||||
|
||||
[TMR.vcproj]
|
||||
SCC_Aux_Path = "P4SCC#srvperforce-ma:1666##raymandata##Editor"
|
||||
SCC_Project_Name = Perforce Project
|
29
Rayman_X/cpa/tempgrp/Tmr/specif/DETECT.H
Normal file
29
Rayman_X/cpa/tempgrp/Tmr/specif/DETECT.H
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef _DETECT_H
|
||||
#define _DETECT_H
|
||||
|
||||
|
||||
/* CPU Types*/
|
||||
#define UNKNOWN 0x00000000
|
||||
#define PENTIUM 0x00000001
|
||||
#define PENT_MMX 0x00000002
|
||||
#define PENTIUM2 0x00000003
|
||||
#define PENTIUM_PRO 0x00000004
|
||||
#define CX_6X86 0x00000005
|
||||
#define CX_6x86MX 0x00000006
|
||||
#define AMD_K5 0x00000007
|
||||
#define AMD_K6 0x00000009
|
||||
#define iDX2 0x0000000A
|
||||
#define iDX4 0x0000000B
|
||||
#define Am5x86 0x0000000C
|
||||
#define MediaGX 0x0000000D
|
||||
#define GXm 0x0000000E
|
||||
#define IDT_C6 0x0000000F
|
||||
|
||||
extern long fn_lIsRdtscAvailable();
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
276
Rayman_X/cpa/tempgrp/Tmr/specif/Detect.c
Normal file
276
Rayman_X/cpa/tempgrp/Tmr/specif/Detect.c
Normal file
@@ -0,0 +1,276 @@
|
||||
#include "string.h"
|
||||
#include "detect.h"
|
||||
|
||||
|
||||
long CPUINFO;
|
||||
char cIDENT[13];
|
||||
|
||||
|
||||
/***********************************/
|
||||
/* VISUAL 5 CPU detection function */
|
||||
/***********************************/
|
||||
#ifndef WATCOM
|
||||
|
||||
#define CPUID __asm _emit 0x0F __asm _emit 0x0a2
|
||||
#define RDTSC __asm _emit 0x0F __asm _emit 0x31
|
||||
|
||||
long gIsCpuidSupported(void)
|
||||
{
|
||||
long retour;
|
||||
|
||||
_asm{
|
||||
pushfd
|
||||
pop eax
|
||||
test eax,0x00200000
|
||||
jz bit21
|
||||
and eax,0xffdfffff
|
||||
push eax
|
||||
popfd
|
||||
pushfd
|
||||
pop eax
|
||||
test eax,0x00200000
|
||||
jz ok
|
||||
jmp no_ok
|
||||
bit21:
|
||||
or eax,0x00200000
|
||||
push eax
|
||||
popfd
|
||||
pushfd
|
||||
pop eax
|
||||
test eax,0x00200000
|
||||
jnz ok
|
||||
jmp no_ok
|
||||
ok:
|
||||
mov eax,1
|
||||
jmp done
|
||||
no_ok:
|
||||
mov eax,0
|
||||
done:
|
||||
mov retour,eax
|
||||
}
|
||||
return retour;
|
||||
}
|
||||
|
||||
|
||||
long gCPUInfo()
|
||||
{
|
||||
long retour;
|
||||
_asm{
|
||||
mov eax,1
|
||||
CPUID
|
||||
mov retour, eax
|
||||
}
|
||||
return retour;
|
||||
}
|
||||
|
||||
|
||||
void gBuilderIdent(void)
|
||||
{
|
||||
_asm{
|
||||
mov eax,0
|
||||
CPUID
|
||||
mov word ptr[cIDENT],bx
|
||||
shr ebx,16
|
||||
mov word ptr[cIDENT+2],bx
|
||||
mov word ptr[cIDENT+4],dx
|
||||
shr edx,16
|
||||
mov word ptr[cIDENT+6],dx
|
||||
mov word ptr[cIDENT+8],cx
|
||||
shr ecx,16
|
||||
mov word ptr[cIDENT+10],cx
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
/***********************************/
|
||||
/* WATCOM CPU detection function */
|
||||
/***********************************/
|
||||
|
||||
long gIsCpuidSupported();
|
||||
#pragma aux gIsCpuidSupported = \
|
||||
"pushfd"\
|
||||
"pop eax"\
|
||||
"test eax,0x00200000"\
|
||||
"jz bit21"\
|
||||
"and eax,0xffdfffff"\
|
||||
"push eax"\
|
||||
"popfd"\
|
||||
"pushfd"\
|
||||
"pop eax"\
|
||||
"test eax,0x00200000"\
|
||||
"jz ok"\
|
||||
"jmp no_ok"\
|
||||
"bit21:"\
|
||||
"or eax,0x00200000"\
|
||||
"push eax"\
|
||||
"popfd"\
|
||||
"pushfd"\
|
||||
"pop eax"\
|
||||
"test eax,0x00200000"\
|
||||
"jnz ok"\
|
||||
"jmp no_ok"\
|
||||
"ok:"\
|
||||
"mov eax,1"\
|
||||
"jmp done"\
|
||||
"no_ok:"\
|
||||
"mov eax,0"\
|
||||
"done:"\
|
||||
value [eax]\
|
||||
modify [eax ebx ecx edx esi edi];
|
||||
|
||||
long gCPUInfo();
|
||||
#pragma aux gCPUInfo = \
|
||||
"mov eax,1"\
|
||||
"db 0x0F, 0xa2"\
|
||||
value [eax]\
|
||||
modify [eax ebx ecx edx];
|
||||
|
||||
|
||||
void gBuilderIdent();
|
||||
#pragma aux gBuilderIdent=\
|
||||
"mov eax,0"\
|
||||
"db 0x0F, 0xa2"\
|
||||
"mov word ptr[cIDENT],bx"\
|
||||
"shr ebx,16"\
|
||||
"mov word ptr[cIDENT+2],bx"\
|
||||
"mov word ptr[cIDENT+4],dx"\
|
||||
"shr edx,16"\
|
||||
"mov word ptr[cIDENT+6],dx"\
|
||||
"mov word ptr[cIDENT+8],cx"\
|
||||
"shr ecx,16"\
|
||||
"mov word ptr[cIDENT+10],cx"\
|
||||
modify [eax ebx ecx edx];
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/**********************************/
|
||||
/* Return 1 if RDTSC is available */
|
||||
/**********************************/
|
||||
long fn_lIsRdtscAvailable()
|
||||
{
|
||||
long Cpu_Type = UNKNOWN;
|
||||
char cModel = (char)0xFF;
|
||||
long lRdtscOk = 0;
|
||||
|
||||
if (gIsCpuidSupported())
|
||||
{
|
||||
CPUINFO = gCPUInfo();
|
||||
gBuilderIdent();
|
||||
if ( strcmp(cIDENT, "GenuineIntel") ==0 )
|
||||
{
|
||||
/* Family*/
|
||||
switch ((CPUINFO&0xF00)>>8)
|
||||
{
|
||||
case 4:
|
||||
if ( ((CPUINFO&0xF0)>>4) == 7)
|
||||
Cpu_Type = iDX2;
|
||||
else if ( ((CPUINFO&0xF0)>>4) == 8)
|
||||
Cpu_Type = iDX4;
|
||||
else
|
||||
Cpu_Type = UNKNOWN;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
Cpu_Type = PENTIUM;
|
||||
if ( ((CPUINFO&0xF0)>>4) == 4) Cpu_Type = PENT_MMX;
|
||||
lRdtscOk = 1;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
case 15:
|
||||
Cpu_Type = PENTIUM_PRO;
|
||||
if ( ((CPUINFO&0xF0)>>4) == 3) Cpu_Type = PENTIUM2;
|
||||
lRdtscOk = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
Cpu_Type = UNKNOWN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ( strcmp(cIDENT, "AuthenticAMD") ==0 )
|
||||
{
|
||||
switch (CPUINFO & 0x00000FF0)
|
||||
{
|
||||
case 0x0500 :
|
||||
case 0x0510 :
|
||||
Cpu_Type = AMD_K5;
|
||||
cModel = (CPUINFO & 0x030) >> 4;
|
||||
break;
|
||||
|
||||
case 0x0520 :
|
||||
case 0x0530 :
|
||||
Cpu_Type = AMD_K5;
|
||||
cModel = (CPUINFO & 0x030) >> 4;
|
||||
lRdtscOk = 1;
|
||||
break;
|
||||
|
||||
case 0x0560 :
|
||||
case 0x0570 :
|
||||
case 0x0580 :
|
||||
case 0x0590 :
|
||||
Cpu_Type = AMD_K6;
|
||||
cModel = (CPUINFO & 0x0F0) >> 4;
|
||||
lRdtscOk = 1;
|
||||
break;
|
||||
|
||||
case 0x06A0 :
|
||||
// Athlon! But pretend it's a K6 so the timers work...
|
||||
Cpu_Type = AMD_K6;
|
||||
cModel = (CPUINFO & 0x0F0) >> 4;
|
||||
lRdtscOk = 1;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
if ( (CPUINFO&0xF00) == 0x400)
|
||||
Cpu_Type = Am5x86;
|
||||
else
|
||||
Cpu_Type = UNKNOWN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (strcmp(cIDENT, "CyrixInstead") ==0 ) /* CYRIX */
|
||||
{
|
||||
switch ((CPUINFO&0xF00)>>8) /* Family */
|
||||
{
|
||||
case 4:
|
||||
if ( ((CPUINFO&0xF0)>>4) == 4 )
|
||||
Cpu_Type = MediaGX;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
switch ((CPUINFO&0xF0)>>4) /* Model */
|
||||
{
|
||||
case 2:
|
||||
Cpu_Type = CX_6X86;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
Cpu_Type = GXm;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
Cpu_Type = CX_6x86MX;
|
||||
lRdtscOk = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
Cpu_Type = UNKNOWN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (strcmp(cIDENT, "CentaurHauls")==0) /* IDT */
|
||||
{
|
||||
Cpu_Type = IDT_C6;
|
||||
}
|
||||
}
|
||||
|
||||
return (lRdtscOk);
|
||||
}
|
||||
|
73
Rayman_X/cpa/tempgrp/Tmr/specif/Timer.cxx
Normal file
73
Rayman_X/cpa/tempgrp/Tmr/specif/Timer.cxx
Normal file
@@ -0,0 +1,73 @@
|
||||
/***************************************************************************/
|
||||
/* Description: Timer.cxx */
|
||||
/* */
|
||||
/* Author: M. Trabucato */
|
||||
/* Last Update : 30/04/98 Take PSX account */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
/* this file is included by Timer.c*/
|
||||
|
||||
/*
|
||||
Makes some internal initializations.
|
||||
*/
|
||||
short __stdcall TMR_fn_wInitLibrary( void )
|
||||
{
|
||||
/* Test if the library has already been initialized */
|
||||
if (TimerLibOk != 0) return (0);
|
||||
|
||||
memset((unsigned char*)a_stTimerTab,0,sizeof(tdstTimer)*C_uwTimerMaxCount);
|
||||
wTimerCount = 0;
|
||||
|
||||
/* Set the low frequency timer number of ticks per second */
|
||||
a3_ulTimerFrequency[C_wTimerFrequencyLow] = fn_ulTimerTickPerSecond(C_wTimerFrequencyLow);
|
||||
|
||||
/* Set the medium frequency timer number of ticks per second */
|
||||
a3_ulTimerFrequency[C_wTimerFrequencyMedium] = fn_ulTimerTickPerSecond(C_wTimerFrequencyMedium);
|
||||
|
||||
/* Set the high frequency timer number of ticks per second */
|
||||
a3_ulTimerFrequency[C_wTimerFrequencyHigh] = fn_ulTimerTickPerSecond(C_wTimerFrequencyHigh);
|
||||
|
||||
/* Define the Timer event resolution */
|
||||
a3_ulEventFrequency[C_wTimerFrequencyLow] = fn_ulTimerEventTickPerSecond(C_wTimerFrequencyLow);
|
||||
|
||||
/* Define the Timer event resolution */
|
||||
a3_ulEventFrequency[C_wTimerFrequencyMedium] = fn_ulTimerEventTickPerSecond(C_wTimerFrequencyMedium);
|
||||
|
||||
/* Define the Timer event resolution */
|
||||
a3_ulEventFrequency[C_wTimerFrequencyHigh] = fn_ulTimerEventTickPerSecond(C_wTimerFrequencyHigh);
|
||||
|
||||
/* Init CPA errors */
|
||||
if (!TMR_g_wErmOK)
|
||||
{
|
||||
Erm_M_InitErrMsg(Tmr);
|
||||
TMR_g_wErmOK = 1;
|
||||
}
|
||||
|
||||
TimerLibOk++;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Makes some internal initializations.
|
||||
*/
|
||||
short __stdcall TMR_fn_wExitLibrary( void )
|
||||
{
|
||||
short wTimerNum;
|
||||
|
||||
if (TimerLibOk > 0)
|
||||
{
|
||||
/* Destroy all Timer*/
|
||||
for (wTimerNum=0 ; wTimerNum < C_uwTimerMaxCount ; wTimerNum++)
|
||||
if (a_stTimerTab[wTimerNum].m_wTimerState != C_wTimerUnused)
|
||||
TMR_fn_wDestroyTimer(wTimerNum);
|
||||
fn_wTimerReleaseEvents();
|
||||
wTimerCount = 0;
|
||||
|
||||
TimerLibOk = 0;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
443
Rayman_X/cpa/tempgrp/Tmr/specif/TimerPrv.c
Normal file
443
Rayman_X/cpa/tempgrp/Tmr/specif/TimerPrv.c
Normal file
@@ -0,0 +1,443 @@
|
||||
/****************************************************************************
|
||||
Description: CPA Timer.lib. Window specific part.
|
||||
|
||||
Author: F. Jentey.
|
||||
Last Update : 03/03/97
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "TimerPrv.h"
|
||||
#include "Detect.h"
|
||||
|
||||
#include <ddraw.h>
|
||||
|
||||
|
||||
extern tdstTimer a_stTimerTab[];
|
||||
short g_wTimerPeriodOk = 0;
|
||||
u_long g_ulPeriodMin;
|
||||
|
||||
|
||||
#ifndef WATCOM
|
||||
/******** VISUAL 5 ************/
|
||||
|
||||
#define RDTSC __asm _emit 0x0F __asm _emit 0x31
|
||||
|
||||
void fn_vTimerPentiumCounter(stTimerCount *p_stTimerCount)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
RDTSC
|
||||
mov ebx,dword ptr p_stTimerCount
|
||||
mov [ebx],eax
|
||||
mov [ebx+4],edx
|
||||
}
|
||||
}
|
||||
|
||||
void fn_vTimerWaitVBL(void)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
push edx
|
||||
mov dx,03dah
|
||||
Wait_VBLStart:
|
||||
in al,dx
|
||||
and ax,08h
|
||||
jz Wait_VBLStart
|
||||
|
||||
Wait_VBLEnd:
|
||||
in al,dx
|
||||
and ax,08h
|
||||
jnz Wait_VBLEnd
|
||||
|
||||
pop edx
|
||||
pop eax
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
/******** WATCOM ************/
|
||||
|
||||
void fn_vTimerPentiumCounter(stTimerCount *p_stTimerCount);
|
||||
#pragma aux fn_vTimerPentiumCounter = \
|
||||
"db 0x0F,0x31" \
|
||||
"mov [ebx],eax" \
|
||||
"mov 4[ebx],edx" \
|
||||
parm [ebx] \
|
||||
modify [eax edx]
|
||||
|
||||
void fn_vTimerWaitVBL(void);
|
||||
#pragma aux fn_vWaitVBL = \
|
||||
"mov dx,03dah" \
|
||||
"Wait_VBLStart:" \
|
||||
"in al,dx" \
|
||||
"and al,08h" \
|
||||
"jz Wait_VBLStart" \
|
||||
"Wait_VBLEnd:" \
|
||||
"in al,dx" \
|
||||
"and al,08h" \
|
||||
"jnz Wait_VBLEnd" \
|
||||
modify [eax edx]
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/****************************************/
|
||||
/* Get the clock frequency of the CPU. */
|
||||
/****************************************/
|
||||
u_long fn_ulTimerCpuClock()
|
||||
{
|
||||
stTimerCount count1, count2;
|
||||
u_long t, ulresult;
|
||||
|
||||
t = timeGetTime();
|
||||
fn_vTimerPentiumCounter(&count1);
|
||||
while (timeGetTime()-t < 1000);
|
||||
fn_vTimerPentiumCounter(&count2);
|
||||
if (count2.m_ulLowPart > count1.m_ulLowPart)
|
||||
ulresult = count2.m_ulLowPart - count1.m_ulLowPart;
|
||||
else
|
||||
ulresult = count2.m_ulLowPart + 4294967295 - count1.m_ulLowPart;
|
||||
|
||||
if ( ulresult < 63000000 ) return 60000000;
|
||||
if ( ulresult < 68000000 ) return 66600000;
|
||||
if ( ulresult < 80000000 ) return 75000000;
|
||||
if ( ulresult < 94000000 ) return 90000000;
|
||||
if ( ulresult < 106000000 ) return 100000000;
|
||||
if ( ulresult < 125000000 ) return 120000000;
|
||||
if ( ulresult < 138000000 ) return 133300000;
|
||||
if ( ulresult < 155000000 ) return 150000000;
|
||||
if ( ulresult < 170000000 ) return 166600000;
|
||||
if ( ulresult < 185000000 ) return 180000000;
|
||||
if ( ulresult < 205000000 ) return 200000000;
|
||||
if ( ulresult < 240000000 ) return 233300000;
|
||||
if ( ulresult < 272000000 ) return 266600000;
|
||||
if ( ulresult < 310000000 ) return 300000000;
|
||||
if ( ulresult < 340000000 ) return 333300000;
|
||||
if ( ulresult < 356000000 ) return 350000000;
|
||||
if ( ulresult < 380000000 ) return 366600000;
|
||||
/* ANNECY AV*/
|
||||
if ( ulresult < 425000000 ) return 400000000;
|
||||
if ( ulresult < 475000000 ) return 450000000;
|
||||
if ( ulresult < 525000000 ) return 500000000;
|
||||
if ( ulresult < 575000000 ) return 550000000;
|
||||
if ( ulresult < 625000000 ) return 600000000;
|
||||
return ulresult;
|
||||
/* END ANNECY AV*/
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************/
|
||||
/* This function return the number of CPU cycle of a frame. */
|
||||
/***************************************************************/
|
||||
u_long fn_ulTimerFrameLength()
|
||||
{
|
||||
LPDIRECTDRAW lpDD;
|
||||
HRESULT ddrval;
|
||||
stTimerCount stBefore, stAfter;
|
||||
u_long ulTime,ulSomme = 0;
|
||||
long i;
|
||||
|
||||
if (!fn_lIsRdtscAvailable()) return (0);
|
||||
|
||||
ddrval = DirectDrawCreate(NULL, &lpDD, NULL);
|
||||
if (ddrval != DD_OK) lpDD = NULL;
|
||||
|
||||
ulTime = 0;
|
||||
fn_vTimerPentiumCounter(&stBefore); /* La fonction Direct Draw WaitForVerticalBlank */
|
||||
for (i=0; i<64; i++) /* ne fonctionne pas correctement sous 95 !? */
|
||||
{
|
||||
unsigned long ulNewTime;
|
||||
ddrval = IDirectDraw_WaitForVerticalBlank(lpDD,DDWAITVB_BLOCKBEGIN, NULL);
|
||||
if (ddrval != DD_OK) return (0);
|
||||
ulNewTime = timeGetTime();
|
||||
if (ulNewTime-ulTime < 5) return (0);
|
||||
ulTime = ulNewTime;
|
||||
}
|
||||
fn_vTimerPentiumCounter(&stAfter);
|
||||
if (stAfter.m_ulLowPart > stBefore.m_ulLowPart )
|
||||
ulSomme = stAfter.m_ulLowPart - stBefore.m_ulLowPart;
|
||||
else
|
||||
ulSomme = stAfter.m_ulLowPart + 4294967295 - stBefore.m_ulLowPart;
|
||||
stBefore.m_ulLowPart = stAfter.m_ulLowPart;
|
||||
|
||||
if (lpDD) IDirectDraw_Release(lpDD);
|
||||
|
||||
return (ulSomme >> 6);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************/
|
||||
/* Set the precision (in millisecond) of the timeGetTime and */
|
||||
/* setEvent function */
|
||||
/******************************************************************/
|
||||
void fn_vSetTimePeriod()
|
||||
{
|
||||
TIMECAPS tc;
|
||||
MMRESULT err;
|
||||
|
||||
if (!g_wTimerPeriodOk)
|
||||
{
|
||||
err = timeGetDevCaps(&tc, sizeof(TIMECAPS));
|
||||
if (err != TIMERR_NOERROR)
|
||||
g_ulPeriodMin = 0;
|
||||
else
|
||||
{
|
||||
g_ulPeriodMin = min( max( tc.wPeriodMin, 1 ), tc.wPeriodMax);
|
||||
/* TO DO: Test the result */
|
||||
timeBeginPeriod(g_ulPeriodMin);
|
||||
}
|
||||
g_wTimerPeriodOk = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* Return the frequency of the specified timer type in tick per second */
|
||||
/**************************************************************************/
|
||||
u_long fn_ulTimerTickPerSecond(short wTimerType)
|
||||
{
|
||||
LARGE_INTEGER perf;
|
||||
u_long ulTicksPerSecond;
|
||||
|
||||
switch (wTimerType)
|
||||
{
|
||||
case C_wTimerFrequencyLow:
|
||||
fn_vSetTimePeriod();
|
||||
ulTicksPerSecond = 1000;
|
||||
break;
|
||||
|
||||
case C_wTimerFrequencyMedium:
|
||||
if ( QueryPerformanceFrequency(&perf) == TRUE )
|
||||
ulTicksPerSecond = perf.LowPart;
|
||||
else
|
||||
ulTicksPerSecond = 0;
|
||||
break;
|
||||
|
||||
case C_wTimerFrequencyHigh:
|
||||
if (fn_lIsRdtscAvailable())
|
||||
ulTicksPerSecond = fn_ulTimerCpuClock();
|
||||
else
|
||||
ulTicksPerSecond = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
ulTicksPerSecond = 0;
|
||||
}
|
||||
|
||||
return (ulTicksPerSecond);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* Return the frequency of the specified event type in tick per second */
|
||||
/*************************************************************************/
|
||||
u_long fn_ulTimerEventTickPerSecond(short wTimerType)
|
||||
{
|
||||
/* TIMECAPS tc;
|
||||
MMRESULT err;*/
|
||||
u_long ulTicksPerSecond;
|
||||
|
||||
switch (wTimerType)
|
||||
{
|
||||
case C_wTimerFrequencyLow:
|
||||
/*err = timeGetDevCaps(&tc, sizeof(TIMECAPS));
|
||||
if ( err != TIMERR_NOERROR )
|
||||
ulTicksPerSecond = 0;
|
||||
else
|
||||
{ UINT
|
||||
ulTicksPerSecond = min( max( tc.wPeriodMin, 1 ), tc.wPeriodMax);
|
||||
TO DO Test the result*/
|
||||
/* timeBeginPeriod(ulTicksPerSecond);*/
|
||||
fn_vSetTimePeriod();
|
||||
ulTicksPerSecond = 1000;
|
||||
break;
|
||||
|
||||
case C_wTimerFrequencyMedium: /* Not Available */
|
||||
ulTicksPerSecond = 0;
|
||||
break;
|
||||
|
||||
case C_wTimerFrequencyHigh: /* Not Available */
|
||||
ulTicksPerSecond = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
ulTicksPerSecond = 0;
|
||||
}
|
||||
|
||||
return ulTicksPerSecond;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************/
|
||||
/* Some operation to release event */
|
||||
/*********************************************************/
|
||||
short fn_wTimerReleaseEvents(/*u_long* p_EventFreqTab*/)
|
||||
{
|
||||
/* short wTimerNum;*/
|
||||
/* First, kill all events */
|
||||
/* for (wTimerNum=0 ; wTimerNum < C_uwTimerMaxCount ; wTimerNum++ )
|
||||
{
|
||||
if ( (a_stTimerTab[wTimerNum].m_wTimerType >= C_wTimerEvent)
|
||||
&& (a_stTimerTab[wTimerNum].m_wTimerState != C_wTimerUnused) )
|
||||
{
|
||||
timeKillEvent( a_stTimerTab[wTimerNum].m_ulEventId );
|
||||
}
|
||||
}
|
||||
*/
|
||||
/* TO DO */
|
||||
/* Test if timeBeginPeriod succed before */
|
||||
timeEndPeriod(g_ulPeriodMin);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*******************************/
|
||||
/* Destroy an event */
|
||||
/*******************************/
|
||||
short fn_wTimerDestroyEvent(u_long ulEventId)
|
||||
{
|
||||
/* TO DO */
|
||||
/* Test if timeBeginPeriod succed before */
|
||||
if (timeKillEvent(ulEventId) != TIMERR_NOERROR)
|
||||
return (0);
|
||||
else
|
||||
return (1);
|
||||
}
|
||||
|
||||
/***************************************************/
|
||||
/* Get the current value of the specified counter */
|
||||
/***************************************************/
|
||||
void fn_vTimerGetCounter(short wTimerType, stTimerCount* p_stValue)
|
||||
{
|
||||
u_long ulTemp;
|
||||
|
||||
switch ( wTimerType )
|
||||
{
|
||||
case C_wTimerFrequencyLow:
|
||||
ulTemp = timeGetTime();
|
||||
p_stValue->m_ulLowPart = ulTemp;
|
||||
p_stValue->m_ulHighPart = 0;
|
||||
break;
|
||||
|
||||
case C_wTimerFrequencyMedium:
|
||||
QueryPerformanceCounter((LARGE_INTEGER*)p_stValue);
|
||||
break;
|
||||
|
||||
case C_wTimerFrequencyHigh:
|
||||
fn_vTimerPentiumCounter(p_stValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/********************************/
|
||||
/* Wait during ulTicksToWait */
|
||||
/********************************/
|
||||
void fn_vTimerWait(u_long ulTicksToWait)
|
||||
{
|
||||
u_long ulTick;
|
||||
|
||||
ulTick = timeGetTime();
|
||||
while ( timeGetTime() - ulTick < ulTicksToWait );
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
/* Return the number of ticks per second for the fn_wTimerDelay function */
|
||||
/***************************************************************************/
|
||||
u_long fn_ulTimerWaitTicksPerSecond()
|
||||
{
|
||||
return (1000);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
/* This is the event server */
|
||||
/* This function call the callback function associated with the event */
|
||||
/* corresponding to the parameter uTimerID */
|
||||
/***************************************************************************/
|
||||
void PASCAL fn_vTimerEventsCallback(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
|
||||
{
|
||||
short wTimerNum;
|
||||
|
||||
/* First, finf the timer corrsponding to uTimerID */
|
||||
for (wTimerNum=0 ; wTimerNum < C_uwTimerMaxCount ; wTimerNum++ )
|
||||
{
|
||||
if ( a_stTimerTab[wTimerNum].m_wTimerType >= C_wTimerEvent )
|
||||
{
|
||||
if ( (a_stTimerTab[wTimerNum].m_ulEventId == uTimerID) &&
|
||||
(a_stTimerTab[wTimerNum].m_p_fn_vEventCallback) )
|
||||
{
|
||||
a_stTimerTab[wTimerNum].m_p_fn_vEventCallback();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************/
|
||||
/* Create an event */
|
||||
/* ulPeriod is the period of the event in ticks */
|
||||
/* p_fn_vEventCallback is a pointer to the callback function of the event */
|
||||
/* ulEventType must be set with C_ulTimerEventOneTime or C_ulTimerEventPeriodic */
|
||||
/***********************************************************************************/
|
||||
short fn_wTimerNewEvent(
|
||||
u_long ulPeriod,
|
||||
u_long ulResolution,
|
||||
td_p_fn_vTimerEventCallback p_fn_vEventCallback,
|
||||
u_long ulTimerEventType,
|
||||
u_long* p_ulEventId
|
||||
)
|
||||
{
|
||||
MMRESULT Id;
|
||||
Id = timeSetEvent(
|
||||
ulPeriod,
|
||||
ulResolution,
|
||||
(LPTIMECALLBACK)fn_vTimerEventsCallback,
|
||||
0,
|
||||
ulTimerEventType
|
||||
);
|
||||
if (Id == 0L) return (C_wTimerError);
|
||||
|
||||
*p_ulEventId = Id;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************/
|
||||
/* This function return vertical refresh rate. The result is multiple by 100. */
|
||||
/* Actualy return 0 if not Intel Pentium */
|
||||
/*******************************************************************************/
|
||||
u_long fn_ulTimerVerticalRefreshRate(u_long ulCpuClock)
|
||||
{
|
||||
LPDIRECTDRAW lpDD = NULL;
|
||||
HRESULT ddrval;
|
||||
u_long ulFrequency;
|
||||
float fTempFreq;
|
||||
|
||||
ddrval = DirectDrawCreate(NULL, &lpDD, NULL);
|
||||
if(ddrval == DD_OK)
|
||||
{
|
||||
ddrval = IDirectDraw_GetMonitorFrequency(lpDD,&ulFrequency);
|
||||
IDirectDraw_Release(lpDD);
|
||||
if (ddrval == DD_OK)
|
||||
{ /* DDraw do not return in Hz*100 */
|
||||
if (ulFrequency < 1000) ulFrequency *= 100;
|
||||
return (ulFrequency);
|
||||
}
|
||||
}
|
||||
|
||||
ulFrequency = fn_ulTimerFrameLength();
|
||||
if (ulFrequency==0) return (0);
|
||||
|
||||
/* Use a float to avoid overflow */
|
||||
fTempFreq = (float)ulFrequency;
|
||||
fTempFreq = (float)ulCpuClock * (float)100.0 / fTempFreq;
|
||||
ulFrequency = (u_long)fTempFreq;
|
||||
|
||||
return (ulFrequency);
|
||||
}
|
||||
|
91
Rayman_X/cpa/tempgrp/Tmr/specif/TimerPrv.h
Normal file
91
Rayman_X/cpa/tempgrp/Tmr/specif/TimerPrv.h
Normal file
@@ -0,0 +1,91 @@
|
||||
/***********************************************************************************/
|
||||
/* TimerWin.h : Private header file for the CPA Timer library. Pentium Version */
|
||||
/* Author : JENTEY F. */
|
||||
/* Last update : 03/03/97 */
|
||||
/***********************************************************************************/
|
||||
|
||||
|
||||
#ifndef _TIMER_PENTIUM_H
|
||||
#define _TIMER_PENTIUM_H
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
|
||||
#include "TMR/Timer.h"
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Return the frequency of the specified timer type in tick per second
|
||||
*/
|
||||
extern u_long fn_ulTimerTickPerSecond(short wTimerType);
|
||||
|
||||
|
||||
/*
|
||||
Return the frequency of the specified event type in tick per second
|
||||
*/
|
||||
extern u_long fn_ulTimerEventTickPerSecond(short wTimerType);
|
||||
|
||||
|
||||
/*
|
||||
Some operation to release event
|
||||
*/
|
||||
extern short fn_wTimerReleaseEvents();
|
||||
|
||||
/*
|
||||
Destroy an event
|
||||
*/
|
||||
extern short fn_wTimerDestroyEvent(u_long ulEventId);
|
||||
|
||||
|
||||
/*
|
||||
Get the current value of the specified counter
|
||||
*/
|
||||
extern void fn_vTimerGetCounter(short wTimerType, stTimerCount* p_stValue);
|
||||
|
||||
|
||||
/*
|
||||
Wait during ulTicksToWait
|
||||
*/
|
||||
extern void fn_vTimerWait(u_long ulTicksToWait);
|
||||
|
||||
|
||||
/*
|
||||
Return the number of ticks per second for the fn_wTimerDelay function
|
||||
*/
|
||||
extern u_long fn_ulTimerWaitTicksPerSecond();
|
||||
|
||||
|
||||
/*
|
||||
Create an event
|
||||
ulPeriod is the period of the event in ticks
|
||||
p_fn_vEventCallback is a pointer to the callback function of the event
|
||||
ulEventType must be set with C_ulTimerEventOneTime or C_ulTimerEventPeriodic
|
||||
*/
|
||||
|
||||
extern short fn_wTimerNewEvent(
|
||||
u_long ulPeriod,
|
||||
u_long ulResolution,
|
||||
td_p_fn_vTimerEventCallback p_fn_vEventCallback,
|
||||
u_long ulTimerEventType,
|
||||
u_long* p_ulEventId
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
This function return vertical refresh rate. The result is multiple by 100.
|
||||
*/
|
||||
extern u_long fn_ulTimerVerticalRefreshRate(u_long ulCpuClock);
|
||||
|
||||
|
||||
/*
|
||||
This function return the length of a frame. The units length is the tick
|
||||
of a C_wTimerFrequencyHigh timer type (so the return value is the number CPU cycle)
|
||||
*/
|
||||
extern u_long fn_ulTimerFrameLength();
|
||||
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user