diff --git a/desmume/ChangeLog b/desmume/ChangeLog
index cbf51f587..5664059e1 100644
--- a/desmume/ChangeLog
+++ b/desmume/ChangeLog
@@ -11,6 +11,9 @@
- Make matrix 4x4 multiply routines use W-coordinate. [zeromus]
- Add many matrix and vector functions to matrix.c [zeromus]
- 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:
- Fixed: Filenames and paths with unicode characters now work. [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]
- Add an arm8 cpu load average calculator [zeromus]
? Fix a bug in texture transformation mode 1 [zeromus]
- - 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]
+ - Fix the buggy auto frameskip logic which made the emu slow to a crawl. Now it runs fast! [zeromus]
0.7.3 -> 0.8
diff --git a/desmume/src/windows/DeSmuME_2005.vcproj b/desmume/src/windows/DeSmuME_2005.vcproj
index d99e01710..1ad61bb44 100644
--- a/desmume/src/windows/DeSmuME_2005.vcproj
+++ b/desmume/src/windows/DeSmuME_2005.vcproj
@@ -848,6 +848,10 @@
RelativePath="..\SPU.cpp"
>
+
+
@@ -1054,6 +1058,10 @@
RelativePath="..\SPU.h"
>
+
+
diff --git a/desmume/src/windows/main.cpp b/desmume/src/windows/main.cpp
index f49059463..ca83154ea 100644
--- a/desmume/src/windows/main.cpp
+++ b/desmume/src/windows/main.cpp
@@ -55,6 +55,7 @@
#include "../gdbstub.h"
#include "colorctrl.h"
#include "console.h"
+#include "throttle.h"
#include "snddx.h"
@@ -401,6 +402,8 @@ DWORD WINAPI run( LPVOID lpParameter)
DDCAPS hw_caps, sw_caps;
+ InitSpeedThrottle();
+
if (DirectDrawCreateEx(NULL, (LPVOID*)&lpDDraw, IID_IDirectDraw7, NULL) != DD_OK)
{
MessageBox(hwnd,"Unable to initialize DirectDraw","Error",MB_OK);
@@ -419,7 +422,7 @@ DWORD WINAPI run( LPVOID lpParameter)
return -1;
}
- //NDS_3D_SetDriver (GPU3D_OPENGL);
+ NDS_3D_SetDriver (GPU3D_OPENGL);
if (!gpu3D->NDS_3D_Init ())
{
@@ -577,8 +580,12 @@ DWORD WINAPI run( LPVOID lpParameter)
framesskipped++;
}
-
- if (autoframeskipenab)
+
+ while(SpeedThrottle())
+ {
+ }
+
+ if (autoframeskipenab)
{
framecount++;
@@ -591,26 +598,11 @@ DWORD WINAPI run( LPVOID lpParameter)
QueryPerformanceCounter((LARGE_INTEGER *)&curticks);
diffticks = curticks-lastticks;
- if ((onesecondticks+diffticks) > (OneFrameTime * (u64)framecount) &&
- framesskipped < 9)
- {
- // Skip the next frame
- skipnextframe = 1;
-
- // How many frames should we skip?
- 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;
- }
- }
+ if(ThrottleIsBehind() && framesskipped < 9)
+ {
+ skipnextframe = 1;
+ framestoskip = 1;
+ }
onesecondticks += diffticks;
lastticks = curticks;
diff --git a/desmume/src/windows/throttle.cpp b/desmume/src/windows/throttle.cpp
new file mode 100644
index 000000000..1939debec
--- /dev/null
+++ b/desmume/src/windows/throttle.cpp
@@ -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
+
+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);
+}
diff --git a/desmume/src/windows/throttle.h b/desmume/src/windows/throttle.h
new file mode 100644
index 000000000..781737d12
--- /dev/null
+++ b/desmume/src/windows/throttle.h
@@ -0,0 +1,8 @@
+#ifndef _THROTTLE_H_
+#define _THROTTLE_H_
+
+void InitSpeedThrottle();
+int SpeedThrottle();
+bool ThrottleIsBehind();
+
+#endif
\ No newline at end of file