mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-27 22:33:17 +00:00
- Ported frame rate limiting code to SDL.
SVN r3891 (trunk)
This commit is contained in:
parent
441f633983
commit
1907983ab7
4 changed files with 116 additions and 30 deletions
|
@ -33,6 +33,8 @@
|
|||
*/
|
||||
|
||||
#include <SDL.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "hardware.h"
|
||||
#include "i_video.h"
|
||||
|
@ -175,10 +177,89 @@ void I_ClosestResolution (int *width, int *height, int bits)
|
|||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SetFPSLimit
|
||||
//
|
||||
// Initializes an event timer to fire at a rate of <limit>/sec. The video
|
||||
// update will wait for this timer to trigger before updating.
|
||||
//
|
||||
// Pass 0 as the limit for unlimited.
|
||||
// Pass a negative value for the limit to use the value of vid_maxfps.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
EXTERN_CVAR(Int, vid_maxfps);
|
||||
EXTERN_CVAR(Bool, cl_capfps);
|
||||
|
||||
Semaphore FPSLimitSemaphore;
|
||||
|
||||
static void FPSLimitNotify(sigval val)
|
||||
{
|
||||
SEMAPHORE_SIGNAL(FPSLimitSemaphore)
|
||||
}
|
||||
|
||||
void I_SetFPSLimit(int limit)
|
||||
{
|
||||
static sigevent FPSLimitEvent;
|
||||
static timer_t FPSLimitTimer;
|
||||
static bool FPSLimitTimerEnabled = false;
|
||||
static bool EventSetup = false;
|
||||
if(!EventSetup)
|
||||
{
|
||||
EventSetup = true;
|
||||
FPSLimitEvent.sigev_notify = SIGEV_THREAD;
|
||||
FPSLimitEvent.sigev_signo = 0;
|
||||
FPSLimitEvent.sigev_value.sival_int = 0;
|
||||
FPSLimitEvent.sigev_notify_function = FPSLimitNotify;
|
||||
FPSLimitEvent.sigev_notify_attributes = NULL;
|
||||
|
||||
SEMAPHORE_INIT(FPSLimitSemaphore, 0, 0)
|
||||
}
|
||||
|
||||
if (limit < 0)
|
||||
{
|
||||
limit = vid_maxfps;
|
||||
}
|
||||
// Kill any leftover timer.
|
||||
if (FPSLimitTimerEnabled)
|
||||
{
|
||||
timer_delete(FPSLimitTimer);
|
||||
FPSLimitTimerEnabled = false;
|
||||
}
|
||||
if (limit == 0)
|
||||
{ // no limit
|
||||
DPrintf("FPS timer disabled\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
FPSLimitTimerEnabled = true;
|
||||
if(timer_create(CLOCK_REALTIME, &FPSLimitEvent, &FPSLimitTimer) == -1)
|
||||
Printf("Failed to create FPS limitter event\n");
|
||||
itimerspec period = { {0, 0}, {0, 0} };
|
||||
period.it_value.tv_nsec = period.it_interval.tv_nsec = 1000000000 / limit;
|
||||
if(timer_settime(FPSLimitTimer, 0, &period, NULL) == -1)
|
||||
Printf("Failed to set FPS limitter timer\n");
|
||||
DPrintf("FPS timer set to %u ms\n", (unsigned int) period.it_interval.tv_nsec / 1000000);
|
||||
}
|
||||
}
|
||||
|
||||
CUSTOM_CVAR (Int, vid_maxfps, 200, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
{
|
||||
if (vid_maxfps < TICRATE && vid_maxfps != 0)
|
||||
{
|
||||
vid_maxfps = TICRATE;
|
||||
}
|
||||
else if (vid_maxfps > 1000)
|
||||
{
|
||||
vid_maxfps = 1000;
|
||||
}
|
||||
else if (cl_capfps == 0)
|
||||
{
|
||||
I_SetFPSLimit(vid_maxfps);
|
||||
}
|
||||
}
|
||||
|
||||
extern int NewWidth, NewHeight, NewBits, DisplayBits;
|
||||
|
|
|
@ -37,6 +37,29 @@
|
|||
#include "i_video.h"
|
||||
#include "v_video.h"
|
||||
|
||||
// Semaphores
|
||||
#ifdef __APPLE__
|
||||
#include <mach/mach_init.h>
|
||||
#include <mach/semaphore.h>
|
||||
#include <mach/task.h>
|
||||
typedef semaphore_t Semaphore;
|
||||
#define SEMAPHORE_WAIT(sem) \
|
||||
while(semaphore_wait(sem) != KERN_SUCCESS){}
|
||||
#define SEMAPHORE_SIGNAL(sem) \
|
||||
semaphore_signal(sem)
|
||||
#define SEMAPHORE_INIT(sem, shared, value) \
|
||||
semaphore_create(mach_task_self(), &sem, shared, value);
|
||||
#else
|
||||
#include <semaphore.h>
|
||||
typedef sem_t Semaphore;
|
||||
#define SEMAPHORE_WAIT(sem) \
|
||||
while(sem_wait(&sem) != 0);
|
||||
#define SEMAPHORE_SIGNAL(sem) \
|
||||
sem_post(&sem);
|
||||
#define SEMAPHORE_INIT(sem, shared, value) \
|
||||
sem_init(&sem, shared, value);
|
||||
#endif
|
||||
|
||||
class IVideo
|
||||
{
|
||||
public:
|
||||
|
@ -59,6 +82,7 @@ void I_InitGraphics ();
|
|||
void I_ShutdownGraphics ();
|
||||
void I_CreateRenderer();
|
||||
|
||||
extern Semaphore FPSLimitSemaphore;
|
||||
void I_SetFPSLimit(int limit);
|
||||
|
||||
extern IVideo *Video;
|
||||
|
|
|
@ -38,14 +38,6 @@
|
|||
#include <gdk/gdkkeysyms.h>
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <mach/mach_init.h>
|
||||
#include <mach/semaphore.h>
|
||||
#include <mach/task.h>
|
||||
#else
|
||||
#include <semaphore.h>
|
||||
#endif
|
||||
|
||||
#include "doomerrors.h"
|
||||
#include <math.h>
|
||||
|
||||
|
@ -144,11 +136,7 @@ static DWORD BaseTime;
|
|||
static int TicFrozen;
|
||||
|
||||
// Signal based timer.
|
||||
#ifdef __APPLE__
|
||||
static semaphore_t timerWait;
|
||||
#else
|
||||
static sem_t timerWait;
|
||||
#endif
|
||||
static Semaphore timerWait;
|
||||
static int tics;
|
||||
static DWORD sig_start, sig_next;
|
||||
|
||||
|
@ -221,12 +209,7 @@ int I_WaitForTicSignaled (int prevtic)
|
|||
|
||||
while(tics <= prevtic)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
while(semaphore_wait(timerWait) != KERN_SUCCESS)
|
||||
;
|
||||
#else
|
||||
while(sem_wait(&timerWait) != 0);
|
||||
#endif
|
||||
SEMAPHORE_WAIT(timerWait)
|
||||
}
|
||||
|
||||
return tics;
|
||||
|
@ -276,11 +259,7 @@ void I_HandleAlarm (int sig)
|
|||
tics++;
|
||||
sig_start = SDL_GetTicks();
|
||||
sig_next = Scale((Scale (sig_start, TICRATE, 1000) + 1), 1000, TICRATE);
|
||||
#ifdef __APPLE__
|
||||
semaphore_signal(timerWait);
|
||||
#else
|
||||
sem_post(&timerWait);
|
||||
#endif
|
||||
SEMAPHORE_SIGNAL(timerWait)
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -290,11 +269,7 @@ void I_HandleAlarm (int sig)
|
|||
//
|
||||
void I_SelectTimer()
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
semaphore_create(mach_task_self(), &timerWait, 0, 0);
|
||||
#else
|
||||
sem_init(&timerWait, 0, 0);
|
||||
#endif
|
||||
SEMAPHORE_INIT(timerWait, 0, 0)
|
||||
signal(SIGALRM, I_HandleAlarm);
|
||||
|
||||
struct itimerval itv;
|
||||
|
|
|
@ -80,6 +80,7 @@ extern SDL_Rect cursorBlit;
|
|||
extern bool GUICapture;
|
||||
|
||||
EXTERN_CVAR (Float, Gamma)
|
||||
EXTERN_CVAR (Int, vid_maxfps)
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
|
@ -374,6 +375,11 @@ void SDLFB::Update ()
|
|||
|
||||
DrawRateStuff ();
|
||||
|
||||
if(vid_maxfps)
|
||||
{
|
||||
SEMAPHORE_WAIT(FPSLimitSemaphore)
|
||||
}
|
||||
|
||||
Buffer = NULL;
|
||||
LockCount = 0;
|
||||
UpdatePending = false;
|
||||
|
|
Loading…
Reference in a new issue