Add rayman2 source files

This commit is contained in:
2024-09-18 02:33:44 +08:00
parent bcc093f8ed
commit fb036c54fd
14339 changed files with 2596224 additions and 0 deletions

View 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

View 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);
}

View 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);
}

View 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);
}

View 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