mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
DirtySDK (EA's Dirty Sockets library) will be used for the LiveAPI implementation, and depends on: EABase, EAThread.
424 lines
12 KiB
C
424 lines
12 KiB
C
/*H********************************************************************************/
|
|
/*!
|
|
|
|
\File dirtylibwin.c
|
|
|
|
\Description
|
|
Platform specific support library for network code. Suppplies
|
|
simple time, memory, and semaphore functions.
|
|
|
|
\Copyright
|
|
Copyright (c) Tiburon Entertainment / Electronic Arts 2002. ALL RIGHTS RESERVED.
|
|
|
|
\Version 1.0 01/02/02 (GWS) Initial version (ported from PS2 IOP)
|
|
|
|
*/
|
|
/********************************************************************************H*/
|
|
|
|
|
|
/*** Include files ****************************************************************/
|
|
|
|
#pragma warning(push,0)
|
|
#include <windows.h>
|
|
#pragma warning(pop)
|
|
|
|
#include "DirtySDK/platform.h"
|
|
|
|
#if !defined(DIRTYCODE_XBOXONE)
|
|
#include <timeapi.h>
|
|
#endif
|
|
|
|
#include <time.h>
|
|
#include <sys/types.h>
|
|
#include <sys/timeb.h>
|
|
|
|
#include <stdio.h>
|
|
#include "DirtySDK/dirtysock/dirtythread.h"
|
|
#include "DirtySDK/dirtysock/dirtylib.h"
|
|
|
|
/*** Defines **********************************************************************/
|
|
|
|
/*** Macros ***********************************************************************/
|
|
|
|
/*** Type Definitions *************************************************************/
|
|
|
|
/*** Function Prototypes **********************************************************/
|
|
|
|
static uint32_t _NetLibGetTickCount2(void);
|
|
|
|
/*** Variables ********************************************************************/
|
|
|
|
// Private variables
|
|
|
|
// idle thread state
|
|
static volatile int32_t g_idlelife = -1;
|
|
|
|
// queryperformancecounter frequency (static init so calls to NetTick() before NetLibCreate won't crash)
|
|
static LARGE_INTEGER _NetLib_lFreq = { 1 };
|
|
|
|
#if defined(DIRTYCODE_PC) || defined(DIRTYCODE_GDK)
|
|
uint32_t _NetLib_bUseHighResTimer = FALSE;
|
|
#else
|
|
uint32_t _NetLib_bUseHighResTimer = TRUE;
|
|
#endif
|
|
|
|
// selected timer function
|
|
static uint32_t (*_NetLib_pTimerFunc)(void) = _NetLibGetTickCount2;
|
|
|
|
// Public variables
|
|
|
|
|
|
/*** Private Functions ************************************************************/
|
|
|
|
|
|
/*F********************************************************************************/
|
|
/*!
|
|
\Function _NetLibThread
|
|
|
|
\Description
|
|
Thread to handle special library tasks
|
|
|
|
\Input _null - unused
|
|
|
|
\Version 01/02/2002 (gschaefer)
|
|
*/
|
|
/********************************************************************************F*/
|
|
static void _NetLibThread(void *_null)
|
|
{
|
|
char strThreadId[32];
|
|
|
|
// get the thread id
|
|
DirtyThreadGetThreadId(strThreadId, sizeof(strThreadId));
|
|
|
|
// show we are alive
|
|
NetPrintf(("dirtylibwin: idle thread running (thid=%s)\n", strThreadId));
|
|
g_idlelife = 1;
|
|
|
|
// run while we have sema
|
|
while (g_idlelife == 1)
|
|
{
|
|
// call idle functions
|
|
NetIdleCall();
|
|
// wait for next tick
|
|
Sleep(50);
|
|
}
|
|
|
|
// report termination
|
|
NetPrintf(("dirtylibwin: idle thread exiting\n"));
|
|
|
|
// show we are dead
|
|
g_idlelife = 0;
|
|
}
|
|
|
|
/*F********************************************************************************/
|
|
/*!
|
|
\Function _NetLibGetTickCount
|
|
|
|
\Description
|
|
Millisecond-accurate tick counter.
|
|
|
|
\Output
|
|
uint32_t - millisecond tick counter
|
|
|
|
\Version 11/02/2005 (jbrookes)
|
|
*/
|
|
/********************************************************************************F*/
|
|
static uint32_t _NetLibGetTickCount(void)
|
|
{
|
|
LARGE_INTEGER lCount;
|
|
QueryPerformanceCounter(&lCount);
|
|
return((uint32_t)((lCount.QuadPart*1000)/_NetLib_lFreq.QuadPart));
|
|
}
|
|
|
|
/*F********************************************************************************/
|
|
/*!
|
|
\Function _NetLibGetTickCount2
|
|
|
|
\Description
|
|
Millisecond tick counter, with variable precision.
|
|
|
|
\Output
|
|
uint32_t - millisecond tick counter
|
|
|
|
\Version 11/02/2005 (jbrookes)
|
|
*/
|
|
/********************************************************************************F*/
|
|
static uint32_t _NetLibGetTickCount2(void)
|
|
{
|
|
#if defined(DIRTYCODE_XBOXONE) || defined(DIRTYCODE_GDK)
|
|
return(_NetLibGetTickCount()); //$$TODO -- better method than querying high performance counter?
|
|
#else
|
|
return(timeGetTime());
|
|
#endif
|
|
}
|
|
|
|
|
|
/*** Public Functions *************************************************************/
|
|
|
|
|
|
/*F********************************************************************************/
|
|
/*!
|
|
\Function NetLibCreate
|
|
|
|
\Description
|
|
Initialize the network library functions
|
|
|
|
\Input iThreadPrio - priority to start the _NetLibThread with
|
|
\Input iThreadStackSize - stack size to start the _NetLibThread with (in bytes)
|
|
\Input iThreadCpuAffinity - cpu affinity to start the _NetLibThread with
|
|
|
|
\Version 01/02/2002 (gschaefer)
|
|
*/
|
|
/********************************************************************************F*/
|
|
void NetLibCreate(int32_t iThreadPrio, int32_t iThreadStackSize, int32_t iThreadCpuAffinity)
|
|
{
|
|
DirtyThreadConfigT ThreadConfig;
|
|
int32_t iResult;
|
|
|
|
// init common netlib functionality
|
|
NetLibCommonInit();
|
|
|
|
// configure thread parameters
|
|
ds_memclr(&ThreadConfig, sizeof(ThreadConfig));
|
|
ThreadConfig.pName = "NetLib";
|
|
ThreadConfig.iPriority = iThreadPrio;
|
|
ThreadConfig.iAffinity = iThreadCpuAffinity;
|
|
ThreadConfig.iVerbosity = 1;
|
|
|
|
// create a worker thread
|
|
if ((iResult = DirtyThreadCreate(_NetLibThread, NULL, &ThreadConfig)) != 0)
|
|
{
|
|
NetPrintf(("dirtylibwin: unable to create netidle thread (err=%d)\n", iResult));
|
|
g_idlelife = 0;
|
|
}
|
|
|
|
// set up high-performance timer, if available
|
|
if (QueryPerformanceFrequency(&_NetLib_lFreq) == 0)
|
|
{
|
|
NetPrintf(("dirtylibwin: high-frequency performance counter not available\n"));
|
|
}
|
|
// use high-performance timer for tick counter?
|
|
if (_NetLib_bUseHighResTimer)
|
|
{
|
|
_NetLib_pTimerFunc = _NetLibGetTickCount;
|
|
}
|
|
}
|
|
|
|
/*F********************************************************************************/
|
|
/*!
|
|
\Function NetLibDestroy
|
|
|
|
\Description
|
|
Destroy the network lib
|
|
|
|
\Input uShutdownFlags - NET_SHUTDOWN_* flags
|
|
|
|
\Version 01/02/02 (gschaefer)
|
|
*/
|
|
/********************************************************************************F*/
|
|
void NetLibDestroy(uint32_t uShutdownFlags)
|
|
{
|
|
// if the thread is running
|
|
if (g_idlelife == 1)
|
|
{
|
|
// signal a shutdown
|
|
g_idlelife = 2;
|
|
|
|
// wait for thread to terminate
|
|
while (g_idlelife > 0)
|
|
{
|
|
Sleep(1);
|
|
}
|
|
}
|
|
|
|
// shut down common functionality
|
|
NetLibCommonShutdown();
|
|
}
|
|
|
|
/*F********************************************************************************/
|
|
/*!
|
|
\Function NetTick
|
|
|
|
\Description
|
|
Return some kind of increasing tick count with millisecond scale (does
|
|
not need to have millisecond precision, but higher precision is better).
|
|
|
|
\Output
|
|
uint32_t - millisecond tick count
|
|
|
|
\Version 09/15/1999 (gschaefer)
|
|
*/
|
|
/********************************************************************************F*/
|
|
uint32_t NetTick(void)
|
|
{
|
|
return(_NetLib_pTimerFunc());
|
|
}
|
|
|
|
/*F********************************************************************************/
|
|
/*!
|
|
\Function NetTickUsec
|
|
|
|
\Description
|
|
Return increasing tick count in microseconds. Used for performance timing
|
|
purposes.
|
|
|
|
\Output
|
|
uint64_t - microsecond tick count
|
|
|
|
\Version 01/30/2015 (jbrookes)
|
|
*/
|
|
/********************************************************************************F*/
|
|
uint64_t NetTickUsec(void)
|
|
{
|
|
LARGE_INTEGER lCount;
|
|
QueryPerformanceCounter(&lCount);
|
|
return((uint64_t)((lCount.QuadPart*1000000)/_NetLib_lFreq.QuadPart));
|
|
}
|
|
|
|
/*F********************************************************************************/
|
|
/*!
|
|
\Function NetLocalTime
|
|
|
|
\Description
|
|
This converts the input GMT time to the local time as specified by the
|
|
system clock. This function follows the re-entrant localtime_r function
|
|
signature.
|
|
|
|
\Input *pTm - storage for localtime output
|
|
\Input uElap - GMT time
|
|
|
|
\Output
|
|
struct tm * - pointer to localtime result
|
|
|
|
\Version 04/23/2008 (jbrookes)
|
|
*/
|
|
/********************************************************************************F*/
|
|
struct tm *NetLocalTime(struct tm *pTm, uint64_t uElap)
|
|
{
|
|
time_t uTimeT = (time_t)uElap;
|
|
localtime_s(pTm, &uTimeT);
|
|
return(pTm);
|
|
}
|
|
|
|
/*F********************************************************************************/
|
|
/*!
|
|
\Function NetPlattimeToTime
|
|
|
|
\Description
|
|
This converts the input platform-specific time data structure to the
|
|
generic time data structure.
|
|
|
|
\Input *pTm - generic time data structure to be filled by the function
|
|
\Input *pPlatTime - pointer to the platform-specific data structure
|
|
|
|
\Output
|
|
struct tm * - NULL=failure; else pointer to user-provided generic time data structure
|
|
|
|
\Notes
|
|
pPlatTime is expected to point to a __timeb64 on PC platforms, and a
|
|
SYSTEMTIME on Xbox One.
|
|
|
|
\Version 05/08/2010 (mclouatre)
|
|
*/
|
|
/********************************************************************************F*/
|
|
struct tm *NetPlattimeToTime(struct tm *pTm, void *pPlatTime)
|
|
{
|
|
#if defined(DIRTYCODE_PC)
|
|
struct __timeb64 timebuffer = *(struct __timeb64 *)pPlatTime;
|
|
struct tm resultTm = *(_localtime64(&(timebuffer.time)));
|
|
|
|
pTm->tm_sec = resultTm.tm_sec;
|
|
pTm->tm_min = resultTm.tm_min;
|
|
pTm->tm_hour = resultTm.tm_hour;
|
|
pTm->tm_mday = resultTm.tm_mday;
|
|
pTm->tm_mon = resultTm.tm_mon;
|
|
pTm->tm_year = resultTm.tm_year;
|
|
pTm->tm_wday = resultTm.tm_wday;
|
|
pTm->tm_yday = resultTm.tm_yday;
|
|
pTm->tm_isdst =resultTm.tm_isdst;
|
|
#else // XBOXONE
|
|
SYSTEMTIME systemTime = *(SYSTEMTIME *)pPlatTime;
|
|
|
|
pTm->tm_sec = systemTime.wSecond;
|
|
pTm->tm_min = systemTime.wMinute;
|
|
pTm->tm_hour = systemTime.wHour;
|
|
pTm->tm_mday = systemTime.wDay;
|
|
pTm->tm_mon = systemTime.wMonth - 1;
|
|
pTm->tm_year = systemTime.wYear - 1900;
|
|
pTm->tm_wday = systemTime.wDayOfWeek;
|
|
pTm->tm_yday = 0;
|
|
pTm->tm_isdst = 0;
|
|
#endif
|
|
|
|
return(pTm);
|
|
}
|
|
|
|
/*F********************************************************************************/
|
|
/*!
|
|
\Function NetPlattimeToTimeMs
|
|
|
|
\Description
|
|
This function retrieves the current date time and fills in the
|
|
generic time data structure prrovided. It has the option of returning millisecond
|
|
which is not part of the generic time data structure
|
|
|
|
\Input *pTm - generic time data structure to be filled by the function
|
|
\Input *pImsec - output param for milisecond to be filled by the function (optional can be NULL)
|
|
|
|
\Output
|
|
struct tm * - NULL=failure; else pointer to user-provided generic time data structure
|
|
|
|
\Version 09/16/2014 (tcho)
|
|
*/
|
|
/********************************************************************************F*/
|
|
struct tm *NetPlattimeToTimeMs(struct tm *pTm , int32_t *pImsec)
|
|
{
|
|
void *pPlatTime;
|
|
int32_t iMsec;
|
|
|
|
#if defined(DIRTYCODE_PC)
|
|
struct __timeb64 timebuffer;
|
|
_ftime64_s(&timebuffer);
|
|
iMsec = timebuffer.millitm;
|
|
pPlatTime = (void *)&timebuffer;
|
|
#else // XBOXONE
|
|
SYSTEMTIME systemTime;
|
|
GetLocalTime( &systemTime );
|
|
iMsec = systemTime.wMilliseconds;
|
|
pPlatTime = (void *)&systemTime;
|
|
#endif
|
|
|
|
if (pImsec != NULL)
|
|
{
|
|
*pImsec = iMsec;
|
|
}
|
|
|
|
if (pTm == NULL)
|
|
{
|
|
return(NULL);
|
|
}
|
|
|
|
return(NetPlattimeToTime(pTm, pPlatTime));
|
|
}
|
|
|
|
/*F********************************************************************************/
|
|
/*!
|
|
\Function NetTime
|
|
|
|
\Description
|
|
This function replaces the standard library time() function. Main
|
|
differences are the missing pointer parameter (not needed) and the uint64_t
|
|
return value. The function returns 0 on unsupported platforms vs time which
|
|
returns -1.
|
|
|
|
\Output
|
|
uint64_t - number of elapsed seconds since Jan 1, 1970.
|
|
|
|
\Version 01/12/2005 (gschaefer)
|
|
*/
|
|
/********************************************************************************F*/
|
|
uint64_t NetTime(void)
|
|
{
|
|
return((uint64_t)time(NULL));
|
|
}
|