Skip to content

Commit

Permalink
Frameskipping! Complete with GUI! Even my most naive approach resulte…
Browse files Browse the repository at this point in the history
…d 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
  • Loading branch information
tbennun committed Aug 8, 2009
1 parent 9cbfadb commit 51ddedf
Show file tree
Hide file tree
Showing 21 changed files with 123 additions and 16 deletions.
3 changes: 3 additions & 0 deletions Source/Core/Common/Src/PluginVideo.cpp
Expand Up @@ -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) &&
Expand All @@ -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;
}
Expand Down
3 changes: 3 additions & 0 deletions Source/Core/Common/Src/PluginVideo.h
Expand Up @@ -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);

Expand All @@ -51,6 +52,8 @@ class PluginVideo : public CPlugin
TVideo_AddMessage Video_AddMessage;
TVideo_Screenshot Video_Screenshot;

TVideo_SetRendering Video_SetRendering;

private:
bool validVideo;
};
Expand Down
10 changes: 5 additions & 5 deletions Source/Core/Core/Core.vcproj
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions Source/Core/Core/Src/Core.cpp
Expand Up @@ -56,7 +56,7 @@
#include "LogManager.h"

#include "State.h"
#include "Frame.h"
#include "OnFrame.h"

#ifndef _WIN32
#define WINAPI
Expand Down Expand Up @@ -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
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/Core/Src/HW/SI_DeviceGCController.cpp
Expand Up @@ -25,7 +25,7 @@
#include "EXI_Device.h"
#include "EXI_DeviceMic.h"

#include "../Frame.h"
#include "../OnFrame.h"

//////////////////////////////////////////////////////////////////////////
// --- standard gamecube controller ---
Expand Down
Expand Up @@ -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"

Expand All @@ -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) {
Expand Down Expand Up @@ -60,7 +77,6 @@ void SetFrameStepping(bool bEnabled) {
g_bFrameStep = bEnabled;
}


void ModifyController(SPADStatus *PadStatus) {
u32 keyToPress = (g_bFirstKey) ? g_autoFirstKey : g_autoSecondKey;

Expand Down Expand Up @@ -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);
}

};
Expand Up @@ -18,6 +18,9 @@
#ifndef __FRAME_H
#define __FRAME_H

#include "Common.h"
#include "pluginspecs_pad.h"

// Per-(video )Frame actions

namespace Frame {
Expand All @@ -33,6 +36,10 @@ void SetFrameStepping(bool bEnabled);

void ModifyController(SPADStatus *PadStatus);

void SetFrameSkipping(unsigned int framesToSkip);
int FrameSkippingFactor();
void FrameSkipping();

};

#endif // __FRAME_H
2 changes: 1 addition & 1 deletion Source/Core/Core/Src/SConscript
Expand Up @@ -11,7 +11,7 @@ files = ["ActionReplay.cpp",
"CoreParameter.cpp",
"CoreRerecording.cpp",
"CoreTiming.cpp",
"Frame.cpp",
"OnFrame.cpp",
"Host.cpp",
"MemTools.cpp",
"PatchEngine.cpp",
Expand Down
1 change: 1 addition & 0 deletions Source/Core/DolphinWX/Src/Frame.cpp
Expand Up @@ -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)
Expand Down
3 changes: 3 additions & 0 deletions Source/Core/DolphinWX/Src/Frame.h
Expand Up @@ -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);
Expand Down Expand Up @@ -210,6 +212,7 @@ class CFrame : public wxFrame
// Emulation
wxMenuItem* m_pSubMenuLoad;
wxMenuItem* m_pSubMenuSave;
wxMenuItem* m_pSubMenuFrameSkipping;

void BootGame();

Expand Down
15 changes: 15 additions & 0 deletions Source/Core/DolphinWX/Src/FrameTools.cpp
Expand Up @@ -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"
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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);
Expand Down
10 changes: 10 additions & 0 deletions Source/Core/DolphinWX/Src/Globals.h
Expand Up @@ -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,
Expand Down
5 changes: 5 additions & 0 deletions Source/Core/VideoCommon/Src/Fifo.cpp
Expand Up @@ -24,6 +24,7 @@

#include "Fifo.h"

volatile bool g_bSkipCurrentFrame = false;

extern u8* g_pVideoData;

Expand Down Expand Up @@ -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.
Expand Down
4 changes: 4 additions & 0 deletions Source/Core/VideoCommon/Src/Fifo.h
Expand Up @@ -25,6 +25,8 @@

#define FIFO_SIZE (1024*1024)

extern volatile bool g_bSkipCurrentFrame;

void Fifo_Init();
void Fifo_Shutdown();

Expand All @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/VideoCommon/Src/OpcodeDecoding.cpp
Expand Up @@ -197,6 +197,7 @@ bool FifoCommandRunnable()
static void Decode()
{
int Cmd = DataReadU8();

switch(Cmd)
{
case GX_NOP:
Expand Down Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions Source/Core/VideoCommon/Src/VertexLoaderManager.cpp
Expand Up @@ -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);
}
Expand Down
8 changes: 8 additions & 0 deletions Source/PluginSpecs/pluginspecs_video.h
Expand Up @@ -164,6 +164,14 @@ EXPORT void CALL Video_EnterLoop(void);
//
EXPORT void CALL Video_ExitLoop(void);

// __________________________________________________________________________________________________
// Function: Video_SetRendering
// Purpose: Sets video rendering on and off. Currently used for frame skipping
// input: Enabled toggle
// output: none
//
EXPORT void CALL Video_SetRendering(bool bEnabled);

// __________________________________________________________________________________________________
// Function: Video_AddMessage
// Purpose: Adds a message to the display queue, to be shown forthe specified time
Expand Down
3 changes: 3 additions & 0 deletions Source/Plugins/Plugin_VideoDX9/Src/main.cpp
Expand Up @@ -222,6 +222,9 @@ void Video_ExitLoop()
Fifo_ExitLoop();
}

void Video_SetRendering(bool bEnabled) {
Fifo_SetRendering(bEnabled);
}

void Video_Prepare(void)
{
Expand Down

0 comments on commit 51ddedf

Please sign in to comment.