summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorXTra.KrazzY <XTra.KrazzY@gmail.com>2009-08-08 01:39:56 +0000
committerXTra.KrazzY <XTra.KrazzY@gmail.com>2009-08-08 01:39:56 +0000
commit51ddedf512a3795193fb809281beb5d5453bc73a (patch)
treed6f2c2dfb5e9afe3b29f84aff2f788890d358294 /Source/Core
parent9cbfadb885b585ecbd1e93c885edeb27bbf830e7 (diff)
Frameskipping! Complete with GUI! Even my most naive approach resulted in great speeds, even with graphic-intensive games such as Pikmin.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3949 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Common/Src/PluginVideo.cpp3
-rw-r--r--Source/Core/Common/Src/PluginVideo.h3
-rw-r--r--Source/Core/Core/Core.vcproj10
-rw-r--r--Source/Core/Core/Src/Core.cpp6
-rw-r--r--Source/Core/Core/Src/HW/SI_DeviceGCController.cpp2
-rw-r--r--Source/Core/Core/Src/OnFrame.cpp (renamed from Source/Core/Core/Src/Frame.cpp)26
-rw-r--r--Source/Core/Core/Src/OnFrame.h (renamed from Source/Core/Core/Src/Frame.h)7
-rw-r--r--Source/Core/Core/Src/SConscript2
-rw-r--r--Source/Core/DolphinWX/Src/Frame.cpp1
-rw-r--r--Source/Core/DolphinWX/Src/Frame.h3
-rw-r--r--Source/Core/DolphinWX/Src/FrameTools.cpp15
-rw-r--r--Source/Core/DolphinWX/Src/Globals.h10
-rw-r--r--Source/Core/VideoCommon/Src/Fifo.cpp5
-rw-r--r--Source/Core/VideoCommon/Src/Fifo.h4
-rw-r--r--Source/Core/VideoCommon/Src/OpcodeDecoding.cpp2
-rw-r--r--Source/Core/VideoCommon/Src/VertexLoaderManager.cpp1
16 files changed, 89 insertions, 11 deletions
diff --git a/Source/Core/Common/Src/PluginVideo.cpp b/Source/Core/Common/Src/PluginVideo.cpp
index b35d62a805..159f72f261 100644
--- a/Source/Core/Common/Src/PluginVideo.cpp
+++ b/Source/Core/Common/Src/PluginVideo.cpp
@@ -50,6 +50,8 @@ PluginVideo::PluginVideo(const char *_Filename) : CPlugin(_Filename), validVideo
(LoadSymbol("Video_AddMessage"));
Video_AccessEFB = reinterpret_cast<TVideo_AccessEFB>
(LoadSymbol("Video_AccessEFB"));
+ Video_SetRendering = reinterpret_cast<TVideo_SetRendering>
+ (LoadSymbol("Video_SetRendering"));
if ((Video_Prepare != 0) &&
(Video_SendFifoData != 0) &&
@@ -59,6 +61,7 @@ PluginVideo::PluginVideo(const char *_Filename) : CPlugin(_Filename), validVideo
(Video_ExitLoop != 0) &&
(Video_Screenshot != 0) &&
(Video_AddMessage != 0) &&
+ (Video_SetRendering != 0) &&
(Video_AccessEFB != 0))
validVideo = true;
}
diff --git a/Source/Core/Common/Src/PluginVideo.h b/Source/Core/Common/Src/PluginVideo.h
index 25e1582d4e..85af93f907 100644
--- a/Source/Core/Common/Src/PluginVideo.h
+++ b/Source/Core/Common/Src/PluginVideo.h
@@ -30,6 +30,7 @@ typedef void (__cdecl* TVideo_EndField)();
typedef bool (__cdecl* TVideo_Screenshot)(const char* filename);
typedef void (__cdecl* TVideo_EnterLoop)();
typedef void (__cdecl* TVideo_ExitLoop)();
+typedef void (__cdecl* TVideo_SetRendering)(bool bEnabled);
typedef void (__cdecl* TVideo_AddMessage)(const char* pstr, unsigned int milliseconds);
typedef u32 (__cdecl* TVideo_AccessEFB)(EFBAccessType, u32, u32);
@@ -51,6 +52,8 @@ public:
TVideo_AddMessage Video_AddMessage;
TVideo_Screenshot Video_Screenshot;
+ TVideo_SetRendering Video_SetRendering;
+
private:
bool validVideo;
};
diff --git a/Source/Core/Core/Core.vcproj b/Source/Core/Core/Core.vcproj
index cf4947f50c..1a190287cd 100644
--- a/Source/Core/Core/Core.vcproj
+++ b/Source/Core/Core/Core.vcproj
@@ -2245,23 +2245,23 @@
>
</File>
<File
- RelativePath=".\Src\Frame.cpp"
+ RelativePath=".\Src\Host.h"
>
</File>
<File
- RelativePath=".\Src\Frame.h"
+ RelativePath=".\Src\MemTools.cpp"
>
</File>
<File
- RelativePath=".\Src\Host.h"
+ RelativePath=".\Src\MemTools.h"
>
</File>
<File
- RelativePath=".\Src\MemTools.cpp"
+ RelativePath=".\Src\OnFrame.cpp"
>
</File>
<File
- RelativePath=".\Src\MemTools.h"
+ RelativePath=".\Src\OnFrame.h"
>
</File>
<File
diff --git a/Source/Core/Core/Src/Core.cpp b/Source/Core/Core/Src/Core.cpp
index 9124d9e881..d456c300b3 100644
--- a/Source/Core/Core/Src/Core.cpp
+++ b/Source/Core/Core/Src/Core.cpp
@@ -56,7 +56,7 @@
#include "LogManager.h"
#include "State.h"
-#include "Frame.h"
+#include "OnFrame.h"
#ifndef _WIN32
#define WINAPI
@@ -604,9 +604,9 @@ void Callback_VideoCopiedToXFB(bool video_update)
static u32 videoupd = 0;
if (video_update)
- videoupd++;
+ videoupd += Frame::FrameSkippingFactor() + 1;
else
- frames++;
+ frames += Frame::FrameSkippingFactor() + 1;
// Custom frame limiter
// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
diff --git a/Source/Core/Core/Src/HW/SI_DeviceGCController.cpp b/Source/Core/Core/Src/HW/SI_DeviceGCController.cpp
index 0afc84b7db..f8e3885b84 100644
--- a/Source/Core/Core/Src/HW/SI_DeviceGCController.cpp
+++ b/Source/Core/Core/Src/HW/SI_DeviceGCController.cpp
@@ -25,7 +25,7 @@
#include "EXI_Device.h"
#include "EXI_DeviceMic.h"
-#include "../Frame.h"
+#include "../OnFrame.h"
//////////////////////////////////////////////////////////////////////////
// --- standard gamecube controller ---
diff --git a/Source/Core/Core/Src/Frame.cpp b/Source/Core/Core/Src/OnFrame.cpp
index 0cb636cf2c..62a1225137 100644
--- a/Source/Core/Core/Src/Frame.cpp
+++ b/Source/Core/Core/Src/OnFrame.cpp
@@ -15,6 +15,8 @@
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
+#include "OnFrame.h"
+
#include "Core.h"
#include "PluginManager.h"
@@ -25,12 +27,27 @@ bool g_bAutoFire = false;
u32 g_autoFirstKey = 0, g_autoSecondKey = 0;
bool g_bFirstKey = true;
+int g_framesToSkip = 1, g_frameSkipCounter = 0;
+
void FrameUpdate() {
if(g_bFrameStep)
Core::SetState(Core::CORE_PAUSE);
if(g_bAutoFire)
g_bFirstKey = !g_bFirstKey;
+
+ if(g_framesToSkip)
+ FrameSkipping();
+
+}
+
+void SetFrameSkipping(unsigned int framesToSkip) {
+ g_framesToSkip = (int)framesToSkip;
+ g_frameSkipCounter = 0;
+}
+
+int FrameSkippingFactor() {
+ return g_framesToSkip;
}
void SetAutoHold(bool bEnabled, u32 keyToHold) {
@@ -60,7 +77,6 @@ void SetFrameStepping(bool bEnabled) {
g_bFrameStep = bEnabled;
}
-
void ModifyController(SPADStatus *PadStatus) {
u32 keyToPress = (g_bFirstKey) ? g_autoFirstKey : g_autoSecondKey;
@@ -90,4 +106,12 @@ void ModifyController(SPADStatus *PadStatus) {
}
+void FrameSkipping() {
+ g_frameSkipCounter++;
+ if(g_frameSkipCounter > g_framesToSkip)
+ g_frameSkipCounter = 0;
+
+ CPluginManager::GetInstance().GetVideo()->Video_SetRendering(!g_frameSkipCounter);
+}
+
};
diff --git a/Source/Core/Core/Src/Frame.h b/Source/Core/Core/Src/OnFrame.h
index e60e806c8d..070ba27a0c 100644
--- a/Source/Core/Core/Src/Frame.h
+++ b/Source/Core/Core/Src/OnFrame.h
@@ -18,6 +18,9 @@
#ifndef __FRAME_H
#define __FRAME_H
+#include "Common.h"
+#include "pluginspecs_pad.h"
+
// Per-(video )Frame actions
namespace Frame {
@@ -33,6 +36,10 @@ void SetFrameStepping(bool bEnabled);
void ModifyController(SPADStatus *PadStatus);
+void SetFrameSkipping(unsigned int framesToSkip);
+int FrameSkippingFactor();
+void FrameSkipping();
+
};
#endif // __FRAME_H
diff --git a/Source/Core/Core/Src/SConscript b/Source/Core/Core/Src/SConscript
index 26bc7a4887..13dd14dc3e 100644
--- a/Source/Core/Core/Src/SConscript
+++ b/Source/Core/Core/Src/SConscript
@@ -11,7 +11,7 @@ files = ["ActionReplay.cpp",
"CoreParameter.cpp",
"CoreRerecording.cpp",
"CoreTiming.cpp",
- "Frame.cpp",
+ "OnFrame.cpp",
"Host.cpp",
"MemTools.cpp",
"PatchEngine.cpp",
diff --git a/Source/Core/DolphinWX/Src/Frame.cpp b/Source/Core/DolphinWX/Src/Frame.cpp
index 722f2336c8..2304d40e8f 100644
--- a/Source/Core/DolphinWX/Src/Frame.cpp
+++ b/Source/Core/DolphinWX/Src/Frame.cpp
@@ -278,6 +278,7 @@ EVT_MENU(IDM_SAVESTATEFILE, CFrame::OnSaveStateToFile)
EVT_MENU_RANGE(IDM_LOADSLOT1, IDM_LOADSLOT8, CFrame::OnLoadState)
EVT_MENU_RANGE(IDM_SAVESLOT1, IDM_SAVESLOT8, CFrame::OnSaveState)
+EVT_MENU_RANGE(IDM_FRAMESKIP0, IDM_FRAMESKIP9, CFrame::OnFrameSkip)
EVT_MENU_RANGE(IDM_DRIVE1, IDM_DRIVE24, CFrame::OnBootDrive)
EVT_SIZE(CFrame::OnResize)
diff --git a/Source/Core/DolphinWX/Src/Frame.h b/Source/Core/DolphinWX/Src/Frame.h
index 7abf7337e0..ccaa24aef3 100644
--- a/Source/Core/DolphinWX/Src/Frame.h
+++ b/Source/Core/DolphinWX/Src/Frame.h
@@ -170,6 +170,8 @@ class CFrame : public wxFrame
void OnUndoLoadState(wxCommandEvent& event);
void OnUndoSaveState(wxCommandEvent& event);
+ void OnFrameSkip(wxCommandEvent& event);
+
void OnConfigMain(wxCommandEvent& event); // Options
void OnPluginGFX(wxCommandEvent& event);
void OnPluginDSP(wxCommandEvent& event);
@@ -210,6 +212,7 @@ class CFrame : public wxFrame
// Emulation
wxMenuItem* m_pSubMenuLoad;
wxMenuItem* m_pSubMenuSave;
+ wxMenuItem* m_pSubMenuFrameSkipping;
void BootGame();
diff --git a/Source/Core/DolphinWX/Src/FrameTools.cpp b/Source/Core/DolphinWX/Src/FrameTools.cpp
index f390cfb4c2..f3d8880a9c 100644
--- a/Source/Core/DolphinWX/Src/FrameTools.cpp
+++ b/Source/Core/DolphinWX/Src/FrameTools.cpp
@@ -59,6 +59,7 @@ Core::GetWindowHandle().
#include "ConfigManager.h" // Core
#include "Core.h"
+#include "OnFrame.h"
#include "HW/DVDInterface.h"
#include "State.h"
#include "VolumeHandler.h"
@@ -130,6 +131,12 @@ void CFrame::CreateMenu()
emulationMenu->Append(IDM_PLAY, _T("&Play\tF10"));
emulationMenu->Append(IDM_CHANGEDISC, _T("Change &Disc"));
emulationMenu->Append(IDM_STOP, _T("&Stop"));
+
+ wxMenu *skippingMenu = new wxMenu;
+ m_pSubMenuFrameSkipping = emulationMenu->AppendSubMenu(skippingMenu, _T("&Frame Skipping"));
+ for(int i = 0; i < 10; i++)
+ skippingMenu->Append(IDM_FRAMESKIP0 + i, wxString::Format(_T("%i"), i), wxEmptyString, wxITEM_RADIO);
+
emulationMenu->AppendSeparator();
emulationMenu->Append(IDM_SCREENSHOT, _T("Take S&creenshot\tF9"));
emulationMenu->AppendSeparator();
@@ -713,6 +720,13 @@ void CFrame::OnSaveState(wxCommandEvent& event)
State_Save(slot);
}
+void CFrame::OnFrameSkip(wxCommandEvent& event)
+{
+ int amount = event.GetId() - IDM_FRAMESKIP0;
+
+ Frame::SetFrameSkipping((unsigned int)amount);
+}
+
void CFrame::OnResize(wxSizeEvent& event)
{
FitInside();
@@ -817,6 +831,7 @@ void CFrame::UpdateGUI()
GetMenuBar()->FindItem(IDM_SCREENSHOT)->Enable(running || paused);
m_pSubMenuLoad->Enable(initialized);
m_pSubMenuSave->Enable(initialized);
+ m_pSubMenuFrameSkipping->Enable(initialized);
// Misc
GetMenuBar()->FindItem(IDM_CHANGEDISC)->Enable(initialized);
diff --git a/Source/Core/DolphinWX/Src/Globals.h b/Source/Core/DolphinWX/Src/Globals.h
index 5f7a078520..bfebcd4ac5 100644
--- a/Source/Core/DolphinWX/Src/Globals.h
+++ b/Source/Core/DolphinWX/Src/Globals.h
@@ -51,6 +51,16 @@ enum
IDM_LOADSLOT6,
IDM_LOADSLOT7,
IDM_LOADSLOT8,
+ IDM_FRAMESKIP0,
+ IDM_FRAMESKIP1,
+ IDM_FRAMESKIP2,
+ IDM_FRAMESKIP3,
+ IDM_FRAMESKIP4,
+ IDM_FRAMESKIP5,
+ IDM_FRAMESKIP6,
+ IDM_FRAMESKIP7,
+ IDM_FRAMESKIP8,
+ IDM_FRAMESKIP9,
IDM_PLAY,
IDM_STOP,
IDM_SCREENSHOT,
diff --git a/Source/Core/VideoCommon/Src/Fifo.cpp b/Source/Core/VideoCommon/Src/Fifo.cpp
index 649dabc5e2..9be1bd2288 100644
--- a/Source/Core/VideoCommon/Src/Fifo.cpp
+++ b/Source/Core/VideoCommon/Src/Fifo.cpp
@@ -24,6 +24,7 @@
#include "Fifo.h"
+volatile bool g_bSkipCurrentFrame = false;
extern u8* g_pVideoData;
@@ -77,6 +78,10 @@ u8* FAKE_GetFifoEndPtr()
return &videoBuffer[size];
}
+void Fifo_SetRendering(bool bEnabled) {
+ g_bSkipCurrentFrame = !bEnabled;
+}
+
// Executed from another thread, no the graphics thread!
// Basically, all it does is set a flag so that the loop will eventually exit, then
// waits for the event to be set, which happens when the loop does exit.
diff --git a/Source/Core/VideoCommon/Src/Fifo.h b/Source/Core/VideoCommon/Src/Fifo.h
index b682dcbb5f..fa0e0539ed 100644
--- a/Source/Core/VideoCommon/Src/Fifo.h
+++ b/Source/Core/VideoCommon/Src/Fifo.h
@@ -25,6 +25,8 @@
#define FIFO_SIZE (1024*1024)
+extern volatile bool g_bSkipCurrentFrame;
+
void Fifo_Init();
void Fifo_Shutdown();
@@ -37,6 +39,8 @@ void Fifo_ExitLoopNonBlocking();
void Fifo_DoState(PointerWrap &f);
+void Fifo_SetRendering(bool bEnabled);
+
// Implemented by the Video Plugin
void VideoFifo_CheckSwapRequest();
void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight);
diff --git a/Source/Core/VideoCommon/Src/OpcodeDecoding.cpp b/Source/Core/VideoCommon/Src/OpcodeDecoding.cpp
index 95def571a6..138cc93fd7 100644
--- a/Source/Core/VideoCommon/Src/OpcodeDecoding.cpp
+++ b/Source/Core/VideoCommon/Src/OpcodeDecoding.cpp
@@ -197,6 +197,7 @@ bool FifoCommandRunnable()
static void Decode()
{
int Cmd = DataReadU8();
+
switch(Cmd)
{
case GX_NOP:
@@ -268,6 +269,7 @@ static void Decode()
{
// load vertices (use computed vertex size from FifoCommandRunnable above)
u16 numVertices = DataReadU16();
+
VertexLoaderManager::RunVertices(
Cmd & GX_VAT_MASK, // Vertex loader index (0 - 7)
(Cmd & GX_PRIMITIVE_MASK) >> GX_PRIMITIVE_SHIFT,
diff --git a/Source/Core/VideoCommon/Src/VertexLoaderManager.cpp b/Source/Core/VideoCommon/Src/VertexLoaderManager.cpp
index d7380c42e4..a7db50e420 100644
--- a/Source/Core/VideoCommon/Src/VertexLoaderManager.cpp
+++ b/Source/Core/VideoCommon/Src/VertexLoaderManager.cpp
@@ -115,6 +115,7 @@ void RunVertices(int vtx_attr_group, int primitive, int count)
{
if (!count)
return;
+
RefreshLoader(vtx_attr_group);
g_VertexLoaders[vtx_attr_group]->RunVertices(vtx_attr_group, primitive, count);
}