fix the auto frameskip bug which made throttling explode and cause the emu to run slow!!!

This commit is contained in:
zeromus 2008-09-14 01:22:34 +00:00
parent b00df5e746
commit c0b228007b
5 changed files with 123 additions and 26 deletions

View File

@ -11,6 +11,9 @@
- Make matrix 4x4 multiply routines use W-coordinate. [zeromus] - Make matrix 4x4 multiply routines use W-coordinate. [zeromus]
- Add many matrix and vector functions to matrix.c [zeromus] - Add many matrix and vector functions to matrix.c [zeromus]
- Convert to c++! - Convert to c++!
- Added gfx3d module which emulates the whole GE as part of the core emu.
This is step 1 of making every platform share the same 3d code.
Step 2 will be to bring down the windows/cocoa OGLRenderer and make it act as the ogl_collector did. [zeromus]
Mac OS X port: Mac OS X port:
- Fixed: Filenames and paths with unicode characters now work. [Jeff] - Fixed: Filenames and paths with unicode characters now work. [Jeff]
- Fixed: Load state from file button works again. [Jeff] - Fixed: Load state from file button works again. [Jeff]
@ -53,9 +56,7 @@
- Added a bunch of crazy templates to the cpu and mmu which speed up a the emu little by optimizing variable accesses [zeromus] - Added a bunch of crazy templates to the cpu and mmu which speed up a the emu little by optimizing variable accesses [zeromus]
- Add an arm8 cpu load average calculator [zeromus] - Add an arm8 cpu load average calculator [zeromus]
? Fix a bug in texture transformation mode 1 [zeromus] ? Fix a bug in texture transformation mode 1 [zeromus]
- Added gfx3d module which emulates the whole GE as part of the core emu. - Fix the buggy auto frameskip logic which made the emu slow to a crawl. Now it runs fast! [zeromus]
This is step 1 of making every platform share the same 3d code.
Step 2 will be to bring down the windows/cocoa OGLRenderer and make it act as the ogl_collector did. [zeromus]
0.7.3 -> 0.8 0.7.3 -> 0.8

View File

@ -848,6 +848,10 @@
RelativePath="..\SPU.cpp" RelativePath="..\SPU.cpp"
> >
</File> </File>
<File
RelativePath=".\throttle.cpp"
>
</File>
<File <File
RelativePath="..\thumb_instructions.cpp" RelativePath="..\thumb_instructions.cpp"
> >
@ -1054,6 +1058,10 @@
RelativePath="..\SPU.h" RelativePath="..\SPU.h"
> >
</File> </File>
<File
RelativePath=".\throttle.h"
>
</File>
<File <File
RelativePath="..\thumb_instructions.h" RelativePath="..\thumb_instructions.h"
> >

View File

@ -55,6 +55,7 @@
#include "../gdbstub.h" #include "../gdbstub.h"
#include "colorctrl.h" #include "colorctrl.h"
#include "console.h" #include "console.h"
#include "throttle.h"
#include "snddx.h" #include "snddx.h"
@ -401,6 +402,8 @@ DWORD WINAPI run( LPVOID lpParameter)
DDCAPS hw_caps, sw_caps; DDCAPS hw_caps, sw_caps;
InitSpeedThrottle();
if (DirectDrawCreateEx(NULL, (LPVOID*)&lpDDraw, IID_IDirectDraw7, NULL) != DD_OK) if (DirectDrawCreateEx(NULL, (LPVOID*)&lpDDraw, IID_IDirectDraw7, NULL) != DD_OK)
{ {
MessageBox(hwnd,"Unable to initialize DirectDraw","Error",MB_OK); MessageBox(hwnd,"Unable to initialize DirectDraw","Error",MB_OK);
@ -419,7 +422,7 @@ DWORD WINAPI run( LPVOID lpParameter)
return -1; return -1;
} }
//NDS_3D_SetDriver (GPU3D_OPENGL); NDS_3D_SetDriver (GPU3D_OPENGL);
if (!gpu3D->NDS_3D_Init ()) if (!gpu3D->NDS_3D_Init ())
{ {
@ -578,6 +581,10 @@ DWORD WINAPI run( LPVOID lpParameter)
framesskipped++; framesskipped++;
} }
while(SpeedThrottle())
{
}
if (autoframeskipenab) if (autoframeskipenab)
{ {
framecount++; framecount++;
@ -591,26 +598,11 @@ DWORD WINAPI run( LPVOID lpParameter)
QueryPerformanceCounter((LARGE_INTEGER *)&curticks); QueryPerformanceCounter((LARGE_INTEGER *)&curticks);
diffticks = curticks-lastticks; diffticks = curticks-lastticks;
if ((onesecondticks+diffticks) > (OneFrameTime * (u64)framecount) && if(ThrottleIsBehind() && framesskipped < 9)
framesskipped < 9)
{ {
// Skip the next frame
skipnextframe = 1; skipnextframe = 1;
// How many frames should we skip?
framestoskip = 1; framestoskip = 1;
} }
else if ((onesecondticks+diffticks) < (OneFrameTime * (u64)framecount))
{
// Check to see if we need to limit speed at all
for (;;)
{
QueryPerformanceCounter((LARGE_INTEGER *)&curticks);
diffticks = curticks-lastticks;
if ((onesecondticks+diffticks) >= (OneFrameTime * (u64)framecount))
break;
}
}
onesecondticks += diffticks; onesecondticks += diffticks;
lastticks = curticks; lastticks = curticks;

View File

@ -0,0 +1,88 @@
//THIS SPEED THROTTLE IS TAKEN FROM FCEUX.
//Copyright (C) 2002 Xodnizel
#include "../types.h"
#include "../debug.h"
#include "../console.h"
#include <windows.h>
static u64 tmethod,tfreq;
static u64 desiredfps = 3920763; //59.8261
static u64 GetCurTime(void)
{
if(tmethod)
{
u64 tmp;
/* Practically, LARGE_INTEGER and u64 differ only by signness and name. */
QueryPerformanceCounter((LARGE_INTEGER*)&tmp);
return(tmp);
}
else
return((u64)GetTickCount());
}
void InitSpeedThrottle(void)
{
tmethod=0;
if(QueryPerformanceFrequency((LARGE_INTEGER*)&tfreq))
{
tmethod=1;
}
else
tfreq=1000;
tfreq<<=16; /* Adjustment for fps returned from FCEUI_GetDesiredFPS(). */
}
static bool behind=false;
bool ThrottleIsBehind() {
return behind;
}
int SpeedThrottle(void)
{
static u64 ttime,ltime;
behind = false;
waiter:
ttime=GetCurTime();
if( (ttime-ltime) < (tfreq/desiredfps) )
{
u64 sleepy;
sleepy=(tfreq/desiredfps)-(ttime-ltime);
sleepy*=1000;
if(tfreq>=65536)
sleepy/=tfreq>>16;
else
sleepy=0;
if(sleepy>100)
{
// block for a max of 100ms to
// keep the gui responsive
Sleep(100);
return 1;
}
Sleep(sleepy);
goto waiter;
}
if( (ttime-ltime) >= (tfreq*4/desiredfps))
ltime=ttime;
else
{
ltime+=tfreq/desiredfps;
if( (ttime-ltime) >= (tfreq/desiredfps) ) // Oops, we're behind!
{
behind = true;
return(1);
}
}
return(0);
}

View File

@ -0,0 +1,8 @@
#ifndef _THROTTLE_H_
#define _THROTTLE_H_
void InitSpeedThrottle();
int SpeedThrottle();
bool ThrottleIsBehind();
#endif