Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions neo/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -875,6 +875,7 @@ elseif(APPLE)
sys/sys_local.cpp
sys/posix/posix_net.cpp
sys/posix/posix_main.cpp
sys/posix/posix_shared.cpp
)

set(src_sys_core
Expand Down Expand Up @@ -927,6 +928,7 @@ else()
sys/sys_local.cpp
sys/posix/posix_net.cpp
sys/posix/posix_main.cpp
sys/posix/posix_shared.cpp
sys/linux/main.cpp
)

Expand Down
121 changes: 92 additions & 29 deletions neo/framework/Common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ idCVar com_timestampPrints( "com_timestampPrints", "0", CVAR_SYSTEM, "print time
idCVar com_timescale( "timescale", "1", CVAR_SYSTEM | CVAR_FLOAT, "scales the time", 0.1f, 10.0f );
idCVar com_makingBuild( "com_makingBuild", "0", CVAR_BOOL | CVAR_SYSTEM, "1 when making a build" );
idCVar com_updateLoadSize( "com_updateLoadSize", "0", CVAR_BOOL | CVAR_SYSTEM | CVAR_NOCHEAT, "update the load size after loading a map" );
idCVar com_asyncClient ( "com_asyncClient", "0", CVAR_BOOL | CVAR_SYSTEM | CVAR_ARCHIVE, "run client and renderer asynchronous" );
idCVar com_renderFPS( "com_renderFPS", "300", CVAR_INTEGER | CVAR_SYSTEM | CVAR_ARCHIVE, "frames per second to render" );
idCVar com_clientFPS( "com_clientFPS", "60", CVAR_INTEGER | CVAR_SYSTEM | CVAR_ARCHIVE, "times per second the game is called" );

idCVar com_product_lang_ext( "com_product_lang_ext", "1", CVAR_INTEGER | CVAR_SYSTEM | CVAR_ARCHIVE, "Extension to use when creating language files." );

Expand Down Expand Up @@ -2385,52 +2388,112 @@ idCommonLocal::Frame
=================
*/
void idCommonLocal::Frame( void ) {
try {
// Slow things a little bit down.
unsigned long long spintime = Sys_Microseconds();

while ( 1 ) {
#if defined (__GNUC__) && (__i386 || __x86_64__)
asm("pause");
#elif defined(__aarch64__) || (defined(__ARM_ARCH) && __ARM_ARCH >= 7) || defined(__ARM_ARCH_6K__)
asm("yield");
#endif

if ( Sys_Microseconds() >= ( spintime - 5 ) ) {
break;
}
}

// Calculate timings.
static unsigned long long oldframetime;
unsigned long long newframetime = Sys_Microseconds();
unsigned long long frametime = newframetime - oldframetime;
oldframetime = newframetime;

// pump all the events
Sys_GenerateEvents();
static int clientdelta = 1000000;
static int renderdelta = 1000000;

// write config file if anything changed
WriteConfiguration();
bool clientframe = true;
bool renderframe = true;

// change SIMD implementation if required
if ( com_forceGenericSIMD.IsModified() ) {
InitSIMD();
if ( cvarSystem->GetCVarBool( "com_asyncClient" ) == true ) {
clientdelta += frametime;
renderdelta += frametime;

if ( clientdelta < ( 1000000 / cvarSystem->GetCVarInteger( "com_clientFPS" ) ) ) {
clientframe = false;
} else {
clientdelta = 0;
}

eventLoop->RunEventLoop();
if ( renderdelta < ( 1000000 / cvarSystem->GetCVarInteger( "com_renderFPS" ) ) ) {
renderframe = false;
} else {
renderdelta = 0;
}
}

com_frameTime = com_ticNumber * USERCMD_MSEC;
// Early return if no work has to be done.
if ( !clientframe && !renderframe ) {
return;
}

idAsyncNetwork::RunFrame();
// Rund the game.
try {
if ( clientframe ) {
// Pump the events.
Sys_GenerateEvents();

// Write config file (if anything changed).
WriteConfiguration();

// Change SIMD implementation if required.
if ( com_forceGenericSIMD.IsModified() ) {
InitSIMD();
}

eventLoop->RunEventLoop();
com_frameTime = com_ticNumber * USERCMD_MSEC;
idAsyncNetwork::RunFrame();
}

if ( idAsyncNetwork::IsActive() ) {
if ( idAsyncNetwork::serverDedicated.GetInteger() != 1 ) {
session->GuiFrameEvents();
session->UpdateScreen( false );
if ( clientframe ) {
session->GuiFrameEvents();
}

if ( renderframe ) {
session->UpdateScreen( false );
}
}
} else {
session->Frame();
if ( clientframe ) {
session->Frame();
}

// normal, in-sequence screen update
session->UpdateScreen( false );
if ( renderframe ) {
// normal, in-sequence screen update
session->UpdateScreen( false );
}
}

// report timing information
if ( com_speeds.GetBool() ) {
static int lastTime;
int nowTime = Sys_Milliseconds();
int com_frameMsec = nowTime - lastTime;
lastTime = nowTime;
Printf( "frame:%i all:%3i gfr:%3i rf:%3i bk:%3i\n", com_frameNumber, com_frameMsec, time_gameFrame, time_frontend, time_backend );
time_gameFrame = 0;
time_gameDraw = 0;
}
if ( clientframe ) {
// report timing information
if ( com_speeds.GetBool() ) {
static int lastTime;
int nowTime = Sys_Milliseconds();
int com_frameMsec = nowTime - lastTime;
lastTime = nowTime;
Printf( "frame:%i all:%3i gfr:%3i rf:%3i bk:%3i\n", com_frameNumber, com_frameMsec, time_gameFrame, time_frontend, time_backend );
time_gameFrame = 0;
time_gameDraw = 0;
}

com_frameNumber++;
com_frameNumber++;

// set idLib frame number for frame based memory dumps
idLib::frameNumber = com_frameNumber;
// set idLib frame number for frame based memory dumps
idLib::frameNumber = com_frameNumber;
}
}

catch( idException & ) {
Expand Down
3 changes: 3 additions & 0 deletions neo/framework/Common.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ extern idCVar com_showAsyncStats;
extern idCVar com_showSoundDecoders;
extern idCVar com_makingBuild;
extern idCVar com_updateLoadSize;
extern idCVar com_asyncClient;
extern idCVar com_renderFPS;
extern idCVar com_clientFPS;

extern int time_gameFrame; // game logic time
extern int time_gameDraw; // game present time
Expand Down
12 changes: 8 additions & 4 deletions neo/framework/Session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2606,12 +2606,16 @@ void idSessionLocal::Frame() {
minTic = latchedTicNumber;
}

while( 1 ) {
if ( cvarSystem->GetCVarBool( "com_asyncClient" ) == true ) {
latchedTicNumber = com_ticNumber;
if ( latchedTicNumber >= minTic ) {
break;
} else {
while( 1 ) {
latchedTicNumber = com_ticNumber;
if ( latchedTicNumber >= minTic ) {
break;
}
Sys_WaitForEvent( TRIGGER_EVENT_ONE );
}
Sys_WaitForEvent( TRIGGER_EVENT_ONE );
}

if ( authEmitTimeout ) {
Expand Down
98 changes: 98 additions & 0 deletions neo/sys/posix/posix_shared.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
===========================================================================

Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.

This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").

Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.

In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.

If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.

===========================================================================
*/

#include <time.h>
#include <sys/time.h>

/*
================
Sys_Microseconds
================
*/
unsigned long long Sys_Microseconds() {
#ifdef __APPLE__
// OSX didn't have clock_gettime() until recently, so use Mach's clock_get_time()
// instead. fortunately its mach_timespec_t seems identical to POSIX struct timespec
// so lots of code can be shared
clock_serv_t cclock;
mach_timespec_t now;
static mach_timespec_t first;

host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
clock_get_time(cclock, &now);
mach_port_deallocate(mach_task_self(), cclock);

#else // not __APPLE__ - other Unix-likes will hopefully support clock_gettime()

struct timespec now;
static struct timespec first;
#ifdef _POSIX_MONOTONIC_CLOCK
clock_gettime(CLOCK_MONOTONIC, &now);
#else
clock_gettime(CLOCK_REALTIME, &now);
#endif

#endif // not __APPLE__

if(first.tv_sec == 0)
{
long long nsec = now.tv_nsec;
long long sec = now.tv_sec;
// set back first by 1ms so neither this function nor Sys_Milliseconds()
// (which calls this) will ever return 0
nsec -= 1000000;
if(nsec < 0)
{
nsec += 1000000000ll; // 1s in ns => definitely positive now
--sec;
}

first.tv_sec = sec;
first.tv_nsec = nsec;
}

long long sec = now.tv_sec - first.tv_sec;
long long nsec = now.tv_nsec - first.tv_nsec;

if(nsec < 0)
{
nsec += 1000000000ll; // 1s in ns
--sec;
}

return sec*1000000ll + nsec/1000ll;
}

/*
================
Sys_Milliseconds
================
*/
unsigned int Sys_Milliseconds() {
return (int)(Sys_Microseconds()/1000ll);
}
8 changes: 5 additions & 3 deletions neo/sys/sys_public.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,11 @@ void Sys_DebugVPrintf( const char *fmt, va_list arg );
// NOTE: due to SDL_TIMESLICE this is very bad portability karma, and should be completely removed
void Sys_Sleep( int msec );

// Sys_Milliseconds should only be used for profiling purposes,
// any game related timing information should come from event timestamps
unsigned int Sys_Milliseconds( void );
// Sys_Milliseconds and Sys_Microseconds are used in the main loop and fpr
// profiling purposes. any game related timing information should come from
// event timestamps
unsigned long long Sys_Microseconds( void );
unsigned int Sys_Milliseconds( void );

// returns a selection of the CPUID_* flags
int Sys_GetProcessorId( void );
Expand Down
9 changes: 0 additions & 9 deletions neo/sys/threads.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,6 @@ void Sys_Sleep(int msec) {
SDL_Delay(msec);
}

/*
================
Sys_Milliseconds
================
*/
unsigned int Sys_Milliseconds() {
return SDL_GetTicks();
}

/*
==================
Sys_InitThreads
Expand Down
35 changes: 35 additions & 0 deletions neo/sys/win32/win_shared.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,38 @@ Sys_SetPhysicalWorkMemory
void Sys_SetPhysicalWorkMemory( int minBytes, int maxBytes ) {
::SetProcessWorkingSetSize( GetCurrentProcess(), minBytes, maxBytes );
}

/*
================
Sys_Microseconds
================
*/
unsigned long long Sys_Microseconds() {
static LARGE_INTEGER freq = { 0 };
static LARGE_INTEGER base = { 0 };

if (!freq.QuadPart)
{
QueryPerformanceFrequency(&freq);
}

if (!base.QuadPart)
{
QueryPerformanceCounter(&base);
base.QuadPart -= 1001;
}

LARGE_INTEGER cur;
QueryPerformanceCounter(&cur);

return (cur.QuadPart - base.QuadPart) * 1000000 / freq.QuadPart;
}

/*
================
Sys_Milliseconds
================
*/
unsigned int Sys_Milliseconds() {
return (int)(Sys_Microseconds()/1000ll);
}