Rerecording: Added frame step function and status bar for the input recording. Turn on frame stepping with Ctrl, step with Space. Build the Rerecording version with the setting in Setup.h.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2273 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
John Peterson 2009-02-16 06:18:18 +00:00
parent 7d3e84c182
commit 718aa585e2
18 changed files with 624 additions and 310 deletions

View File

@ -46,6 +46,9 @@
// This may remove sound artifacts in Wario Land Shake It and perhaps other games // This may remove sound artifacts in Wario Land Shake It and perhaps other games
//#define SETUP_AVOID_SOUND_ARTIFACTS //#define SETUP_AVOID_SOUND_ARTIFACTS
// Build with playback rerecording options
//#define RERECORDING
// Build with music modification // Build with music modification
//#define MUSICMOD //#define MUSICMOD

View File

@ -405,13 +405,12 @@ int ChooseStringFrom(const char* str, const char* * items)
// Thousand separator. Turns 12345678 into 12,345,678. // Thousand separator. Turns 12345678 into 12,345,678.
std::string ThS(int a, bool b) std::string ThS(int Integer, bool Unsigned)
{ {
// Create storage space
char cbuf[20]; char cbuf[20];
// Determine treatment of signed or unsigned
// determine treatment of signed or unsigned if(Unsigned) sprintf(cbuf, "%u", Integer); else sprintf(cbuf, "%i", Integer);
if(b) sprintf(cbuf, "%u", a); else sprintf(cbuf, "%i", a);
std::string sbuf = cbuf; std::string sbuf = cbuf;
for (u32 i = 0; i < sbuf.length(); ++i) for (u32 i = 0; i < sbuf.length(); ++i)

View File

@ -25,6 +25,7 @@
#include "Common.h" #include "Common.h"
#include "Timer.h" #include "Timer.h"
#include "StringUtil.h"
#ifdef __GNUC__ #ifdef __GNUC__
u32 timeGetTime() u32 timeGetTime()
@ -38,8 +39,15 @@ u32 timeGetTime()
namespace Common namespace Common
{ {
//////////////////////////////////////////////////////////////////////////////////////////
// Initiate, Start, Stop, and Update the time
// ---------------
// Set initial values for the class
Timer::Timer(void) Timer::Timer(void)
: m_LastTime(0) : m_LastTime(0), m_StartTime(0), m_Running(false)
{ {
Update(); Update();
@ -48,20 +56,90 @@ Timer::Timer(void)
#endif #endif
} }
// Write the starting time
void Timer::Start()
{
m_StartTime = timeGetTime();
m_Running = true;
}
// Stop the timer
void Timer::Stop()
{
// Write the final time
m_LastTime = timeGetTime();
m_Running = false;
}
// Update the last time variable
void Timer::Update(void) void Timer::Update(void)
{ {
m_LastTime = timeGetTime(); m_LastTime = timeGetTime();
//TODO(ector) - QPF //TODO(ector) - QPF
} }
/////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Get time difference and elapsed time
// ---------------
// Get the number of milliseconds since the last Update()
s64 Timer::GetTimeDifference(void) s64 Timer::GetTimeDifference(void)
{ {
return(timeGetTime() - m_LastTime); return(timeGetTime() - m_LastTime);
} }
// Add the time difference since the last Update() to the starting time
void Timer::AddTimeDifference()
{
m_StartTime += GetTimeDifference();
}
// Get the time elapsed since the Start()
u64 Timer::GetTimeElapsed(void)
{
/* If we have not started yet return 1 (because then I don't have to change the FPS
calculation in CoreRerecording.cpp */
if (m_StartTime == 0) return 1;
// Rrturn the final timer time if the timer is stopped
if (!m_Running) return (m_LastTime - m_StartTime);
return (timeGetTime() - m_StartTime);
}
// Get the formattet time elapsed since the Start()
std::string Timer::GetTimeElapsedFormatted(void)
{
// If we have not started yet, return zero
if(m_StartTime == 0) return "00:00:00:000";
// The number of milliseconds since the start, use a different value if the timer is stopped
u32 Milliseconds;
if(m_Running)
Milliseconds = timeGetTime() - m_StartTime;
else
Milliseconds = m_LastTime - m_StartTime;
// Seconds
u32 Seconds = Milliseconds / 1000;
// Minutes
u32 Minutes = Seconds / 60;
// Hours
u32 Hours = Minutes / 60;
std::string TmpStr = StringFromFormat("%02i:%02i:%02i:%03i", Hours, Minutes % 60, Seconds % 60, Milliseconds % 1000);
return TmpStr;
}
/////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Get current time
// ---------------
void Timer::IncreaseResolution() void Timer::IncreaseResolution()
{ {
#ifdef _WIN32 #ifdef _WIN32
@ -86,6 +164,7 @@ void _time64(u64* t)
#endif #endif
// Get the number of seconds since January 1 1970
u64 Timer::GetTimeSinceJan1970(void) u64 Timer::GetTimeSinceJan1970(void)
{ {
time_t ltime; time_t ltime;
@ -106,6 +185,7 @@ u64 Timer::GetLocalTimeSinceJan1970(void)
return (u64)(sysTime + tzDiff); return (u64)(sysTime + tzDiff);
} }
// Return the current time formatted as Minutes:Seconds:Milliseconds in the form 00:00:000
std::string Timer::GetTimeFormatted(void) std::string Timer::GetTimeFormatted(void)
{ {
struct timeb tp; struct timeb tp;
@ -115,4 +195,7 @@ std::string Timer::GetTimeFormatted(void)
return std::string(temp); return std::string(temp);
} }
/////////////////////////////////////
} // end of namespace Common } // end of namespace Common

View File

@ -29,11 +29,13 @@ class Timer
Timer(); Timer();
void Start();
void Stop();
void Update(); void Update();
// The time difference is always returned in milliseconds, regardless of alternative internal representation
// Always in milliseconds, regardless of alternative internal representation
s64 GetTimeDifference(void); s64 GetTimeDifference(void);
void AddTimeDifference();
static void IncreaseResolution(); static void IncreaseResolution();
static void RestoreResolution(); static void RestoreResolution();
@ -41,12 +43,15 @@ class Timer
static u64 GetLocalTimeSinceJan1970(); static u64 GetLocalTimeSinceJan1970();
static std::string GetTimeFormatted(); static std::string GetTimeFormatted();
std::string GetTimeElapsedFormatted();
u64 Timer::GetTimeElapsed();
public: public:
u64 m_LastTime; u64 m_LastTime;
u64 m_StartTime;
u64 m_frequency; u64 m_frequency;
bool m_Running;
}; };
} // end of namespace Common } // end of namespace Common

View File

@ -1433,20 +1433,6 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration
Name="Release_JITIL|Win32"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release_JITIL|x64"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath=".\Src\PowerPC\Jit64IL\IR.h" RelativePath=".\Src\PowerPC\Jit64IL\IR.h"
@ -1503,20 +1489,6 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration
Name="Release_JITIL|Win32"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release_JITIL|x64"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath=".\Src\PowerPC\Jit64IL\Jit.h" RelativePath=".\Src\PowerPC\Jit64IL\Jit.h"
@ -1573,20 +1545,6 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration
Name="Release_JITIL|Win32"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release_JITIL|x64"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath=".\Src\PowerPC\Jit64IL\Jit_FloatingPoint.cpp" RelativePath=".\Src\PowerPC\Jit64IL\Jit_FloatingPoint.cpp"
@ -1639,20 +1597,6 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration
Name="Release_JITIL|Win32"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release_JITIL|x64"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath=".\Src\PowerPC\Jit64IL\Jit_Integer.cpp" RelativePath=".\Src\PowerPC\Jit64IL\Jit_Integer.cpp"
@ -1705,20 +1649,6 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration
Name="Release_JITIL|Win32"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release_JITIL|x64"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath=".\Src\PowerPC\Jit64IL\Jit_LoadStore.cpp" RelativePath=".\Src\PowerPC\Jit64IL\Jit_LoadStore.cpp"
@ -1771,20 +1701,6 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration
Name="Release_JITIL|Win32"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release_JITIL|x64"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath=".\Src\PowerPC\Jit64IL\Jit_LoadStoreFloating.cpp" RelativePath=".\Src\PowerPC\Jit64IL\Jit_LoadStoreFloating.cpp"
@ -1837,20 +1753,6 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration
Name="Release_JITIL|Win32"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release_JITIL|x64"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath=".\Src\PowerPC\Jit64IL\Jit_LoadStorePaired.cpp" RelativePath=".\Src\PowerPC\Jit64IL\Jit_LoadStorePaired.cpp"
@ -1903,20 +1805,6 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration
Name="Release_JITIL|Win32"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release_JITIL|x64"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath=".\Src\PowerPC\Jit64IL\Jit_Paired.cpp" RelativePath=".\Src\PowerPC\Jit64IL\Jit_Paired.cpp"
@ -1969,20 +1857,6 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration
Name="Release_JITIL|Win32"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release_JITIL|x64"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath=".\Src\PowerPC\Jit64IL\Jit_SystemRegisters.cpp" RelativePath=".\Src\PowerPC\Jit64IL\Jit_SystemRegisters.cpp"
@ -2035,20 +1909,6 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration
Name="Release_JITIL|Win32"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release_JITIL|x64"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath=".\Src\PowerPC\Jit64IL\Jit_Util.cpp" RelativePath=".\Src\PowerPC\Jit64IL\Jit_Util.cpp"
@ -2101,20 +1961,6 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration
Name="Release_JITIL|Win32"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release_JITIL|x64"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath=".\Src\PowerPC\Jit64IL\JitAsm.cpp" RelativePath=".\Src\PowerPC\Jit64IL\JitAsm.cpp"
@ -2167,20 +2013,6 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration
Name="Release_JITIL|Win32"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release_JITIL|x64"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath=".\Src\PowerPC\Jit64IL\JitAsm.h" RelativePath=".\Src\PowerPC\Jit64IL\JitAsm.h"
@ -2237,20 +2069,6 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration
Name="Release_JITIL|Win32"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release_JITIL|x64"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath=".\Src\PowerPC\Jit64IL\JitCache.cpp" RelativePath=".\Src\PowerPC\Jit64IL\JitCache.cpp"
@ -2303,20 +2121,6 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration
Name="Release_JITIL|Win32"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release_JITIL|x64"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath=".\Src\PowerPC\Jit64IL\JitCache.h" RelativePath=".\Src\PowerPC\Jit64IL\JitCache.h"
@ -2373,20 +2177,6 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration
Name="Release_JITIL|Win32"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release_JITIL|x64"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath=".\Src\PowerPC\Jit64IL\JitRegCache.h" RelativePath=".\Src\PowerPC\Jit64IL\JitRegCache.h"
@ -2646,6 +2436,10 @@
RelativePath=".\Src\CoreParameter.h" RelativePath=".\Src\CoreParameter.h"
> >
</File> </File>
<File
RelativePath=".\Src\CoreRerecording.cpp"
>
</File>
<File <File
RelativePath=".\Src\CoreTiming.cpp" RelativePath=".\Src\CoreTiming.cpp"
> >

View File

@ -78,7 +78,7 @@ namespace Core
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Declarations and definitions // Declarations and definitions
// // ------------
// Function forwarding // Function forwarding
//void Callback_VideoRequestWindowSize(int _iWidth, int _iHeight, BOOL _bFullscreen); //void Callback_VideoRequestWindowSize(int _iWidth, int _iHeight, BOOL _bFullscreen);
@ -587,6 +587,10 @@ void Callback_VideoLog(const TCHAR *_szMessage, int _bDoBreak)
// We do not touch anything outside this function here // We do not touch anything outside this function here
void Callback_VideoCopiedToXFB() void Callback_VideoCopiedToXFB()
{ {
#ifdef RERECORDING
FrameUpdate();
#endif
SCoreStartupParameter& _CoreParameter = SConfig::GetInstance().m_LocalCoreStartupParameter; SCoreStartupParameter& _CoreParameter = SConfig::GetInstance().m_LocalCoreStartupParameter;
//count FPS //count FPS
static Common::Timer Timer; static Common::Timer Timer;

View File

@ -55,7 +55,6 @@ namespace Core
const SCoreStartupParameter& GetStartupParameter(); const SCoreStartupParameter& GetStartupParameter();
extern SCoreStartupParameter g_CoreStartupParameter; extern SCoreStartupParameter g_CoreStartupParameter;
// Make a screen shot // Make a screen shot
bool MakeScreenshot(const std::string& _rFilename); bool MakeScreenshot(const std::string& _rFilename);
void* GetWindowHandle(); void* GetWindowHandle();
@ -73,6 +72,18 @@ namespace Core
int SyncTrace(); int SyncTrace();
void SetBlockStart(u32 addr); void SetBlockStart(u32 addr);
void StopTrace(); void StopTrace();
#ifdef RERECORDING
void FrameUpdate();
void FrameAdvance();
void FrameStepOnOff();
void WriteStatus();
void RerecordingStart();
void RerecordingStop();
extern int g_FrameCounter;
extern bool g_FrameStep;
#endif
} // namespace } // namespace
#endif #endif

View File

@ -0,0 +1,211 @@
// Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "Setup.h"
#ifdef RERECORDING
//////////////////////////////////////////////////////////////////////////////////////////
// Include
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
#ifdef _WIN32
#include <windows.h>
#endif
#include "Thread.h" // Common
#include "Timer.h"
#include "Common.h"
#include "ConsoleWindow.h"
#include "Console.h"
#include "Core.h"
#include "CPUDetect.h"
#include "CoreTiming.h"
#include "Boot/Boot.h"
#include "PatchEngine.h"
#include "HW/Memmap.h"
#include "HW/PeripheralInterface.h"
#include "HW/GPFifo.h"
#include "HW/CPU.h"
#include "HW/CPUCompare.h"
#include "HW/HW.h"
#include "HW/DSP.h"
#include "HW/GPFifo.h"
#include "HW/AudioInterface.h"
#include "HW/VideoInterface.h"
#include "HW/CommandProcessor.h"
#include "HW/PixelEngine.h"
#include "HW/SystemTimers.h"
#include "PowerPC/PowerPC.h"
#include "PluginManager.h"
#include "ConfigManager.h"
#include "MemTools.h"
#include "Host.h"
#include "LogManager.h"
////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
// File description: Rerecording Functions
/* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
How the timer works: We measure the time between drawn frames, not when the game is paused. So time
should be a fairly comparable measure of the time it took to play the game. However the time it takes
to draw a frame will be lower on a fast computer. Therefore we could perhaps measure time as an
internal game time that is adjusted by the average time it takes to draw a frame. Also if it only takes
ten or twenty milliseconds to draw a frame I'm not certain about how accurate the mmsystem timers are for
such short periods.
//////////////////////////////////////*/
namespace Core
{
///////////////////////////////////////////////////////////////////////////////////////////
// Declarations and definitions
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
int g_FrameCounter = 0;
bool g_FrameStep = false;
Common::Timer ReRecTimer;
////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
// Control Run, Pause, Stop and the Timer.
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
// Subtract the paused time when we run again
void Run()
{
ReRecTimer.AddTimeDifference();
}
// Update the time
void Pause()
{
ReRecTimer.Update();
}
// Start the timer when a game is booted
void RerecordingStart()
{
g_FrameCounter == 0;
ReRecTimer.Start();
}
// Reset the frame counter
void RerecordingStop()
{
// Write the final time and Stop the timer
ReRecTimer.Stop();
// Update status bar
WriteStatus();
}
////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
// Frame advance
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
void FrameAdvance()
{
// Update status bar
WriteStatus();
// If a game is not started, return
if(Core::GetState() == Core::CORE_UNINITIALIZED) return;
// Play to the next frame
if(g_FrameStep)
{
Run();
Core::SetState(Core::CORE_RUN);
}
}
// Turn on frame stepping
void FrameStepOnOff()
{
/* Turn frame step on or off. If a game is running and we turn this on it means that the game
will pause after the next frame update */
g_FrameStep = !g_FrameStep;
// Update status bar
WriteStatus();
// If a game is not started, return
if(Core::GetState() == Core::CORE_UNINITIALIZED) return;
// Run the emulation if we turned off framestepping
if (!g_FrameStep)
{
Run();
Core::SetState(Core::CORE_RUN);
}
}
////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
// General functions
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
// Write to the status bar
void WriteStatus()
{
std::string TmpStr = "Time: " + ReRecTimer.GetTimeElapsedFormatted();
TmpStr += StringFromFormat(" Frame: %s", ThS(g_FrameCounter).c_str());
// The FPS is the total average since the game was booted
TmpStr += StringFromFormat(" FPS: %i", (g_FrameCounter * 1000) / ReRecTimer.GetTimeElapsed());
TmpStr += StringFromFormat(" FrameStep: %s", g_FrameStep ? "On" : "Off");
Host_UpdateStatusBar(TmpStr.c_str(), 1);
}
// When a new frame is drawn
void FrameUpdate()
{
// Write to the status bar
WriteStatus();
// Pause if frame stepping is on
if(g_FrameStep)
{
Pause();
Core::SetState(Core::CORE_PAUSE);
}
// Count one frame
g_FrameCounter++;
}
////////////////////////////////////////
} // Core
#endif // RERECORDING

View File

@ -46,7 +46,7 @@ void Host_SetDebugMode(bool enable);
void Host_SetWaitCursor(bool enable); void Host_SetWaitCursor(bool enable);
void Host_UpdateStatusBar(const char* _pText); void Host_UpdateStatusBar(const char* _pText, int Filed = 0);
void Host_SysMessage(const char *fmt, ...); void Host_SysMessage(const char *fmt, ...);
void Host_SetWiiMoteConnectionState(int _State); void Host_SetWiiMoteConnectionState(int _State);

View File

@ -47,6 +47,8 @@ be accessed from Core::GetWindowHandle().
#include "Common.h" // Common #include "Common.h" // Common
#include "FileUtil.h" #include "FileUtil.h"
#include "Timer.h" #include "Timer.h"
#include "Setup.h"
#include "ConsoleWindow.h"
#include "ConfigManager.h" // Core #include "ConfigManager.h" // Core
#include "Core.h" #include "Core.h"
@ -352,6 +354,13 @@ CFrame::CFrame(wxFrame* parent,
// ---------- // ----------
UpdateGUI(); UpdateGUI();
// If we are rerecording create the status bar now instead of later when a game starts
#ifdef RERECORDING
ModifyStatusBar();
// It's to early for the OnHostMessage(), we will update the status when Ctrl or Space is pressed
//Core::WriteStatus();
#endif
} }
// Destructor // Destructor
@ -439,18 +448,27 @@ void CFrame::OnKeyDown(wxKeyEvent& event)
UpdateGUI(); UpdateGUI();
} }
#ifdef _WIN32 #ifdef _WIN32
else if(event.GetKeyCode() == 'E') // Send this to the video plugin WndProc if(event.GetKeyCode() == 'E') // Send this to the video plugin WndProc
{ {
PostMessage((HWND)Core::GetWindowHandle(), WM_KEYDOWN, event.GetKeyCode(), 0); PostMessage((HWND)Core::GetWindowHandle(), WM_KEYDOWN, event.GetKeyCode(), 0);
event.Skip(); // Don't block the E key event.Skip(); // Don't block the E key
} }
#endif #endif
else
{ #ifdef RERECORDING
// Turn on or off frame advance
if (event.GetKeyCode() == WXK_CONTROL) Core::FrameStepOnOff();
// Step forward
if (event.GetKeyCode() == WXK_SPACE) Core::FrameAdvance();
#endif
// Send the keyboard status to the Input plugin
if(Core::GetState() != Core::CORE_UNINITIALIZED) if(Core::GetState() != Core::CORE_UNINITIALIZED)
CPluginManager::GetInstance().GetPad(0)->PAD_Input(event.GetKeyCode(), 1); // 1 = Down CPluginManager::GetInstance().GetPad(0)->PAD_Input(event.GetKeyCode(), 1); // 1 = Down
// Don't block other events
event.Skip(); event.Skip();
}
} }
void CFrame::OnKeyUp(wxKeyEvent& event) void CFrame::OnKeyUp(wxKeyEvent& event)

View File

@ -219,7 +219,6 @@ class CFrame : public wxFrame
wxToolBarToolBase* m_pToolPlay; wxToolBarToolBase* m_pToolPlay;
void UpdateGUI(); void UpdateGUI();
void BootGame(); void BootGame();
// Double click and mouse move options // Double click and mouse move options

View File

@ -49,6 +49,7 @@ be accessed from Core::GetWindowHandle().
#include "FileUtil.h" #include "FileUtil.h"
#include "Timer.h" #include "Timer.h"
#include "ConsoleWindow.h" #include "ConsoleWindow.h"
#include "Setup.h"
#include "ConfigManager.h" // Core #include "ConfigManager.h" // Core
#include "Core.h" #include "Core.h"
@ -327,12 +328,21 @@ void CFrame::InitBitmaps()
if (GetToolBar() != NULL) RecreateToolbar(); if (GetToolBar() != NULL) RecreateToolbar();
} }
//////////////////////////////////////////////////////////////////////////////////////
// Start the game or change the disc
// -------------
void CFrame::BootGame() void CFrame::BootGame()
{ {
#ifdef MUSICMOD // Music modification // Music modification
#ifdef MUSICMOD
MM_OnPlay(); MM_OnPlay();
#endif #endif
// Rerecording
#ifdef RERECORDING
Core::RerecordingStart();
#endif
// shuffle2: wxBusyInfo is meant to be created on the stack // shuffle2: wxBusyInfo is meant to be created on the stack
// and only stay around for the life of the scope it's in. // and only stay around for the life of the scope it's in.
@ -447,8 +457,16 @@ void CFrame::OnChangeDisc(wxCommandEvent& WXUNUSED (event))
DVDInterface::SetLidOpen(false); DVDInterface::SetLidOpen(false);
} }
void CFrame::OnPlay(wxCommandEvent& WXUNUSED (event))
{
BootGame();
}
////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
// Refresh the file list and browse for a favorites directory
// -------------
void CFrame::OnRefresh(wxCommandEvent& WXUNUSED (event)) void CFrame::OnRefresh(wxCommandEvent& WXUNUSED (event))
{ {
if (m_GameListCtrl) if (m_GameListCtrl)
@ -462,18 +480,24 @@ void CFrame::OnBrowse(wxCommandEvent& WXUNUSED (event))
{ {
m_GameListCtrl->BrowseForDirectory(); m_GameListCtrl->BrowseForDirectory();
} }
////////////////////////////////////////////////////
void CFrame::OnPlay(wxCommandEvent& WXUNUSED (event))
{
BootGame();
}
//////////////////////////////////////////////////////////////////////////////////////
// Stop the emulation
// -------------
void CFrame::DoStop() void CFrame::DoStop()
{ {
#ifdef MUSICMOD // Music modification // Music modification
#ifdef MUSICMOD
MM_OnStop(); MM_OnStop();
#endif #endif
// Rerecording
#ifdef RERECORDING
Core::RerecordingStop();
#endif
if (Core::GetState() != Core::CORE_UNINITIALIZED) if (Core::GetState() != Core::CORE_UNINITIALIZED)
{ {
Core::Stop(); Core::Stop();
@ -506,6 +530,7 @@ void CFrame::OnStop(wxCommandEvent& WXUNUSED (event))
if (answer) DoStop(); if (answer) DoStop();
} }
////////////////////////////////////////////////////
void CFrame::OnConfigMain(wxCommandEvent& WXUNUSED (event)) void CFrame::OnConfigMain(wxCommandEvent& WXUNUSED (event))

View File

@ -16,15 +16,20 @@
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
////////////////////////////////////////////////////////////////////////////////////////
// Include
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
#include "Globals.h" #include "Globals.h"
#include "Frame.h" #include "Frame.h"
#include "FileUtil.h" #include "FileUtil.h"
#include "StringUtil.h" #include "StringUtil.h"
#include "ConsoleWindow.h"
#include "GameListCtrl.h" #include "GameListCtrl.h"
#include "BootManager.h" #include "BootManager.h"
#include "Common.h" #include "Common.h"
#include "Setup.h"
#include "ConfigManager.h" #include "ConfigManager.h"
#include "Core.h" #include "Core.h"
#include "State.h" #include "State.h"
@ -35,6 +40,7 @@
#include "AboutDolphin.h" #include "AboutDolphin.h"
#include <wx/statusbr.h> #include <wx/statusbr.h>
/////////////////////////////////////////
namespace WiimoteLeds namespace WiimoteLeds
@ -50,10 +56,18 @@ namespace WiimoteLeds
int SpIconMargin = 11; int SpIconMargin = 11;
int LedIconMargin = 11; int LedIconMargin = 11;
// The necessary recording status width, allow Frame to be at last of the form 100,000
#ifdef RERECORDING
static const int RerecordingStatusWidth = 340;
#endif
// Leds only // Leds only
static const int LdWidthsOn[] = static const int LdWidthsOn[] =
{ {
-1, -1,
#ifdef RERECORDING
RerecordingStatusWidth,
#endif
ConnectionStatusWidth, ConnectionStatusWidth,
(LedIconMargin + LED_SIZE_X) * 4 + RightmostMargin (LedIconMargin + LED_SIZE_X) * 4 + RightmostMargin
}; };
@ -63,32 +77,61 @@ namespace WiimoteLeds
static const int SpWidthsOn[] = static const int SpWidthsOn[] =
{ {
-1, -1,
#ifdef RERECORDING
RerecordingStatusWidth,
#endif
ConnectionStatusWidth, ConnectionStatusWidth,
( SpIconMargin + SPEAKER_SIZE_X ) * 3 + RightmostMargin ( SpIconMargin + SPEAKER_SIZE_X ) * 3 + RightmostMargin
}; };
static const int SpStylesFieldOn[] = { wxSB_NORMAL, wxSB_NORMAL, wxSB_NORMAL }; static const int SpStylesFieldOn[] = { wxSB_NORMAL,
#ifdef RERECORDING
wxSB_NORMAL,
#endif
wxSB_NORMAL, wxSB_NORMAL };
// Both // Both
static const int LdSpWidthsOn[] = static const int LdSpWidthsOn[] =
{ {
-1, -1,
#ifdef RERECORDING
RerecordingStatusWidth,
#endif
ConnectionStatusWidth, ConnectionStatusWidth,
(SpIconMargin + SPEAKER_SIZE_X) * 3, (SpIconMargin + SPEAKER_SIZE_X) * 3,
(LedIconMargin + LED_SIZE_X) * 4 + RightmostMargin (LedIconMargin + LED_SIZE_X) * 4 + RightmostMargin
}; };
static const int LdSpStylesFieldOn[] = { wxSB_NORMAL, wxSB_NORMAL, wxSB_NORMAL }; static const int LdSpStylesFieldOn[] = { wxSB_NORMAL,
#ifdef RERECORDING
wxSB_NORMAL,
#endif
wxSB_NORMAL, wxSB_NORMAL };
// Only the Wiimote connection Status // Only the Wiimote connection Status
static const int WidthsOff[] = static const int WidthsOff[] =
{ {
-1, -1,
#ifdef RERECORDING
RerecordingStatusWidth,
#endif
ConnectionStatusWidth + ConnectionStatusOnlyAdj + RightmostMargin ConnectionStatusWidth + ConnectionStatusOnlyAdj + RightmostMargin
}; };
static const int StylesFieldOff[] = { wxSB_NORMAL, wxSB_NORMAL }; static const int StylesFieldOff[] = { wxSB_NORMAL,
#ifdef RERECORDING
wxSB_NORMAL,
#endif
wxSB_NORMAL };
// GC mode // GC mode
static const int WidthsOffGC[] = { -1 }; static const int WidthsOffGC[] = { -1
static const int StylesFieldOffGC[] = { wxSB_NORMAL }; #ifdef RERECORDING
, RerecordingStatusWidth
#endif
};
static const int StylesFieldOffGC[] = { wxSB_NORMAL
#ifdef RERECORDING
, wxSB_NORMAL
#endif
};
}; };
// ======================================================= // =======================================================
@ -154,6 +197,11 @@ void CFrame::ModifyStatusBar()
} }
} }
// Add a filed for the rerecording status
#ifdef RERECORDING
Fields++;
#endif
// Update the settings // Update the settings
m_pStatusBar->SetFieldsCount(Fields); m_pStatusBar->SetFieldsCount(Fields);
m_pStatusBar->SetStatusWidths(Fields, Widths); m_pStatusBar->SetStatusWidths(Fields, Widths);
@ -352,13 +400,49 @@ void CFrame::DoMoveIcons()
{ {
if(HaveLeds) MoveLeds(); if(HaveLeds) MoveLeds();
if(HaveSpeakers) MoveSpeakers(); if(HaveSpeakers) MoveSpeakers();
// If there is not room for the led icons hide them
if(m_pStatusBar->GetFieldsCount() >= 2 && HaveLeds)
{
wxRect Rect;
#ifdef RERECORDING
m_pStatusBar->GetFieldRect((HaveLeds && HaveSpeakers) ? 4 : 3, Rect);
#else
m_pStatusBar->GetFieldRect((HaveLeds && HaveSpeakers) ? 3 : 2, Rect);
#endif
if(Rect.GetWidth() < 20)
for (int i = 0; i < 4; i++) m_StatBmp[i]->Hide();
else // if(!m_StatBmp[0]->IsShown())
for (int i = 0; i < 4; i++) m_StatBmp[i]->Show();
//Console::Print("LED: %i ", Rect.GetWidth());
}
// If there is not room for the speaker icons hide them
if(m_pStatusBar->GetFieldsCount() >= 2 && HaveSpeakers)
{
wxRect Rect;
#ifdef RERECORDING
m_pStatusBar->GetFieldRect(3, Rect);
#else
m_pStatusBar->GetFieldRect(2, Rect);
#endif
if(Rect.GetWidth() < 20)
for(int i = 0; i < 3; i++) m_StatBmp[i + 4]->Hide();
else // if(!m_StatBmp[4]->IsShown())
for (int i = 0; i < 3; i++) m_StatBmp[i + 4]->Show();
//Console::Print("Speaker: %i\n", Rect.GetWidth());
}
} }
void CFrame::MoveLeds() void CFrame::MoveLeds()
{ {
wxRect Rect; wxRect Rect;
// Get the bitmap field coordinates // Get the bitmap field coordinates
#ifdef RERECORDING
m_pStatusBar->GetFieldRect((HaveLeds && HaveSpeakers) ? 4 : 3, Rect);
#else
m_pStatusBar->GetFieldRect((HaveLeds && HaveSpeakers) ? 3 : 2, Rect); m_pStatusBar->GetFieldRect((HaveLeds && HaveSpeakers) ? 3 : 2, Rect);
#endif
wxSize Size = m_StatBmp[0]->GetSize(); // Get the bitmap size wxSize Size = m_StatBmp[0]->GetSize(); // Get the bitmap size
//wxMessageBox(wxString::Format("%i", Rect.x)); //wxMessageBox(wxString::Format("%i", Rect.x));
@ -376,7 +460,12 @@ void CFrame::MoveLeds()
void CFrame::MoveSpeakers() void CFrame::MoveSpeakers()
{ {
wxRect Rect; wxRect Rect;
m_pStatusBar->GetFieldRect(2, Rect); // Get the bitmap field coordinates // Get the bitmap field coordinates
#ifdef RERECORDING
m_pStatusBar->GetFieldRect(3, Rect);
#else
m_pStatusBar->GetFieldRect(2, Rect);
#endif
// Get the actual bitmap size, currently it's the same as SPEAKER_SIZE_Y // Get the actual bitmap size, currently it's the same as SPEAKER_SIZE_Y
wxSize Size = m_StatBmp[4]->GetSize(); wxSize Size = m_StatBmp[4]->GetSize();
@ -389,7 +478,7 @@ void CFrame::MoveSpeakers()
for(int i = 0; i < 3; i++) for(int i = 0; i < 3; i++)
{ {
if(i > 0) x = m_StatBmp[i-1+4]->GetPosition().x + Dist; if(i > 0) x = m_StatBmp[i-1+4]->GetPosition().x + Dist;
m_StatBmp[i+4]->Move(x, y); m_StatBmp[i + 4]->Move(x, y);
} }
} }
// ============== // ==============

View File

@ -38,6 +38,7 @@
#include "CPUDetect.h" #include "CPUDetect.h"
#include "IniFile.h" #include "IniFile.h"
#include "FileUtil.h" #include "FileUtil.h"
#include "ConsoleWindow.h"
#include "Main.h" // Local #include "Main.h" // Local
#include "Frame.h" #include "Frame.h"
@ -92,10 +93,12 @@ LONG WINAPI MyUnhandledExceptionFilter(LPEXCEPTION_POINTERS e) {
///////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////
/* The `main program' equivalent that creates the mai nwindow and return the main frame */ /* The `main program' equivalent that creates the main window and return the main frame */
// ¯¯¯¯¯¯¯¯¯ // ¯¯¯¯¯¯¯¯¯
bool DolphinApp::OnInit() bool DolphinApp::OnInit()
{ {
//Console::Open();
// Declarations and definitions // Declarations and definitions
bool UseDebugger = false; bool UseDebugger = false;
bool UseLogger = false; bool UseLogger = false;
@ -442,15 +445,16 @@ void Host_SetWaitCursor(bool enable)
SetCursor(LoadCursor(NULL, IDC_ARROW)); SetCursor(LoadCursor(NULL, IDC_ARROW));
} }
#endif #endif
} }
void Host_UpdateStatusBar(const char* _pText) void Host_UpdateStatusBar(const char* _pText, int Field)
{ {
wxCommandEvent event(wxEVT_HOST_COMMAND, IDM_UPDATESTATUSBAR); wxCommandEvent event(wxEVT_HOST_COMMAND, IDM_UPDATESTATUSBAR);
// Set the event string
event.SetString(wxString::FromAscii(_pText)); event.SetString(wxString::FromAscii(_pText));
event.SetInt(0); // Update statusbar field
event.SetInt(Field);
// Post message
wxPostEvent(main_frame, event); wxPostEvent(main_frame, event);
} }
@ -482,8 +486,12 @@ void Host_SetWiiMoteConnectionState(int _State)
case 1: event.SetString(wxString::FromAscii("Connecting...")); break; case 1: event.SetString(wxString::FromAscii("Connecting...")); break;
case 2: event.SetString(wxString::FromAscii("Wiimote Connected")); break; case 2: event.SetString(wxString::FromAscii("Wiimote Connected")); break;
} }
// Update field 1 or 2
#ifdef RERECORDING
event.SetInt(2);
#else
event.SetInt(1); event.SetInt(1);
#endif
wxPostEvent(main_frame, event); wxPostEvent(main_frame, event);
} }

View File

@ -351,7 +351,6 @@ Global
{D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}.Release JITIL|x64.ActiveCfg = Release|x64 {D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}.Release JITIL|x64.ActiveCfg = Release|x64
{D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}.Release JITIL|x64.Build.0 = Release|x64 {D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}.Release JITIL|x64.Build.0 = Release|x64
{D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}.Release|Win32.ActiveCfg = Release|Win32 {D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}.Release|Win32.ActiveCfg = Release|Win32
{D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}.Release|Win32.Build.0 = Release|Win32
{D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}.Release|x64.ActiveCfg = Release|x64 {D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}.Release|x64.ActiveCfg = Release|x64
{33546D62-7F34-4EA6-A88E-D538B36E16BF}.Debug|Win32.ActiveCfg = Debug|Win32 {33546D62-7F34-4EA6-A88E-D538B36E16BF}.Debug|Win32.ActiveCfg = Debug|Win32
{33546D62-7F34-4EA6-A88E-D538B36E16BF}.Debug|x64.ActiveCfg = Debug|x64 {33546D62-7F34-4EA6-A88E-D538B36E16BF}.Debug|x64.ActiveCfg = Debug|x64
@ -454,7 +453,6 @@ Global
{95CCAABC-7062-47C4-B8C1-A064DD5F16FF}.Release JITIL|x64.ActiveCfg = Release|x64 {95CCAABC-7062-47C4-B8C1-A064DD5F16FF}.Release JITIL|x64.ActiveCfg = Release|x64
{95CCAABC-7062-47C4-B8C1-A064DD5F16FF}.Release JITIL|x64.Build.0 = Release|x64 {95CCAABC-7062-47C4-B8C1-A064DD5F16FF}.Release JITIL|x64.Build.0 = Release|x64
{95CCAABC-7062-47C4-B8C1-A064DD5F16FF}.Release|Win32.ActiveCfg = Release|Win32 {95CCAABC-7062-47C4-B8C1-A064DD5F16FF}.Release|Win32.ActiveCfg = Release|Win32
{95CCAABC-7062-47C4-B8C1-A064DD5F16FF}.Release|Win32.Build.0 = Release|Win32
{95CCAABC-7062-47C4-B8C1-A064DD5F16FF}.Release|x64.ActiveCfg = Release|x64 {95CCAABC-7062-47C4-B8C1-A064DD5F16FF}.Release|x64.ActiveCfg = Release|x64
{95CCAABC-7062-47C4-B8C1-A064DD5F16FF}.Release|x64.Build.0 = Release|x64 {95CCAABC-7062-47C4-B8C1-A064DD5F16FF}.Release|x64.Build.0 = Release|x64
{0B72B5D6-5D72-4391-84A7-9CCA5392668A}.Debug|Win32.ActiveCfg = Debug|Win32 {0B72B5D6-5D72-4391-84A7-9CCA5392668A}.Debug|Win32.ActiveCfg = Debug|Win32
@ -469,7 +467,6 @@ Global
{0B72B5D6-5D72-4391-84A7-9CCA5392668A}.Release JITIL|x64.ActiveCfg = Release|x64 {0B72B5D6-5D72-4391-84A7-9CCA5392668A}.Release JITIL|x64.ActiveCfg = Release|x64
{0B72B5D6-5D72-4391-84A7-9CCA5392668A}.Release JITIL|x64.Build.0 = Release|x64 {0B72B5D6-5D72-4391-84A7-9CCA5392668A}.Release JITIL|x64.Build.0 = Release|x64
{0B72B5D6-5D72-4391-84A7-9CCA5392668A}.Release|Win32.ActiveCfg = Release|Win32 {0B72B5D6-5D72-4391-84A7-9CCA5392668A}.Release|Win32.ActiveCfg = Release|Win32
{0B72B5D6-5D72-4391-84A7-9CCA5392668A}.Release|Win32.Build.0 = Release|Win32
{0B72B5D6-5D72-4391-84A7-9CCA5392668A}.Release|x64.ActiveCfg = Release|x64 {0B72B5D6-5D72-4391-84A7-9CCA5392668A}.Release|x64.ActiveCfg = Release|x64
{0B72B5D6-5D72-4391-84A7-9CCA5392668A}.Release|x64.Build.0 = Release|x64 {0B72B5D6-5D72-4391-84A7-9CCA5392668A}.Release|x64.Build.0 = Release|x64
{0D14F1E9-490B-4A2D-A4EF-0535E8B3C718}.Debug|Win32.ActiveCfg = Debug|Win32 {0D14F1E9-490B-4A2D-A4EF-0535E8B3C718}.Debug|Win32.ActiveCfg = Debug|Win32
@ -484,7 +481,6 @@ Global
{0D14F1E9-490B-4A2D-A4EF-0535E8B3C718}.Release JITIL|x64.ActiveCfg = Release|x64 {0D14F1E9-490B-4A2D-A4EF-0535E8B3C718}.Release JITIL|x64.ActiveCfg = Release|x64
{0D14F1E9-490B-4A2D-A4EF-0535E8B3C718}.Release JITIL|x64.Build.0 = Release|x64 {0D14F1E9-490B-4A2D-A4EF-0535E8B3C718}.Release JITIL|x64.Build.0 = Release|x64
{0D14F1E9-490B-4A2D-A4EF-0535E8B3C718}.Release|Win32.ActiveCfg = Release|Win32 {0D14F1E9-490B-4A2D-A4EF-0535E8B3C718}.Release|Win32.ActiveCfg = Release|Win32
{0D14F1E9-490B-4A2D-A4EF-0535E8B3C718}.Release|Win32.Build.0 = Release|Win32
{0D14F1E9-490B-4A2D-A4EF-0535E8B3C718}.Release|x64.ActiveCfg = Release|x64 {0D14F1E9-490B-4A2D-A4EF-0535E8B3C718}.Release|x64.ActiveCfg = Release|x64
{0D14F1E9-490B-4A2D-A4EF-0535E8B3C718}.Release|x64.Build.0 = Release|x64 {0D14F1E9-490B-4A2D-A4EF-0535E8B3C718}.Release|x64.Build.0 = Release|x64
EndGlobalSection EndGlobalSection

View File

@ -36,10 +36,13 @@ BEGIN_EVENT_TABLE(ConfigDialog,wxDialog)
EVT_CHOICE(ID_X360PAD_CHOICE,ConfigDialog::ControllerSettingsChanged) EVT_CHOICE(ID_X360PAD_CHOICE,ConfigDialog::ControllerSettingsChanged)
EVT_CHECKBOX(ID_RUMBLE,ConfigDialog::ControllerSettingsChanged) EVT_CHECKBOX(ID_RUMBLE,ConfigDialog::ControllerSettingsChanged)
EVT_CHECKBOX(ID_DISABLE,ConfigDialog::ControllerSettingsChanged) EVT_CHECKBOX(ID_DISABLE,ConfigDialog::ControllerSettingsChanged)
//Recording
// Input recording
#ifdef RERECORDING
EVT_CHECKBOX(ID_RECORDING,ConfigDialog::ControllerSettingsChanged) EVT_CHECKBOX(ID_RECORDING,ConfigDialog::ControllerSettingsChanged)
EVT_CHECKBOX(ID_PLAYBACK,ConfigDialog::ControllerSettingsChanged) EVT_CHECKBOX(ID_PLAYBACK,ConfigDialog::ControllerSettingsChanged)
EVT_BUTTON(ID_SAVE_RECORDING,ConfigDialog::ControllerSettingsChanged) EVT_BUTTON(ID_SAVE_RECORDING,ConfigDialog::ControllerSettingsChanged)
#endif
EVT_BUTTON(CTL_A,ConfigDialog::OnButtonClick) EVT_BUTTON(CTL_A,ConfigDialog::OnButtonClick)
EVT_BUTTON(CTL_B,ConfigDialog::OnButtonClick) EVT_BUTTON(CTL_B,ConfigDialog::OnButtonClick)
@ -182,36 +185,9 @@ void ConfigDialog::CreateGUIControls()
m_SizeXInput[i]->Add(m_X360PadC[i], 0, wxEXPAND | wxALL, 1); m_SizeXInput[i]->Add(m_X360PadC[i], 0, wxEXPAND | wxALL, 1);
m_SizeXInput[i]->Add(m_Rumble[i], 0, wxEXPAND | wxALL, 1); m_SizeXInput[i]->Add(m_Rumble[i], 0, wxEXPAND | wxALL, 1);
#endif #endif
m_SizeRecording[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Input Recording"));
m_CheckRecording[i] = new wxCheckBox(m_Controller[i], ID_RECORDING, wxT("Record input"));
m_CheckPlayback[i] = new wxCheckBox(m_Controller[i], ID_PLAYBACK, wxT("Play back input"));
m_BtnSaveRecording[i] = new wxButton(m_Controller[i], ID_SAVE_RECORDING, wxT("Save recording"), wxDefaultPosition, wxDefaultSize);
// Tool tips
m_CheckRecording[i]->SetToolTip(wxT("Your recording will be saved to pad-record.bin in the Dolphin dir when you stop the game"));
m_CheckPlayback[i]->SetToolTip(wxT("Play back the pad-record.bin file from the Dolphin dir"));
m_BtnSaveRecording[i]->SetToolTip(wxT(
"This will save the current recording to pad-record.bin. Your recording will\n"
"also be automatically saved every 60 * 10 frames. And when you shut down the\n"
"game."));
m_SizeRecording[i]->Add(m_CheckRecording[i], 0, wxEXPAND | wxALL, 1);
m_SizeRecording[i]->Add(m_CheckPlayback[i], 0, wxEXPAND | wxALL, 1);
m_SizeRecording[i]->Add(m_BtnSaveRecording[i], 0, wxEXPAND | wxALL, 1);
// Set values // Set values
m_Attached[i]->SetValue(pad[i].bAttached); m_Attached[i]->SetValue(pad[i].bAttached);
m_Disable[i]->SetValue(pad[i].bDisable); m_Disable[i]->SetValue(pad[i].bDisable);
m_CheckRecording[i]->SetValue(pad[i].bRecording);
m_CheckPlayback[i]->SetValue(pad[i].bPlayback);
// Only enable these options for pad 0
m_CheckRecording[i]->Enable(false); m_CheckRecording[0]->Enable(true);
m_CheckPlayback[i]->Enable(false); m_CheckPlayback[0]->Enable(true);
m_BtnSaveRecording[i]->Enable(false); m_BtnSaveRecording[0]->Enable(true);
// Don't allow saving when we are not recording
m_BtnSaveRecording[i]->Enable(g_EmulatorRunning && pad[0].bRecording);
#ifdef _WIN32 #ifdef _WIN32
// Check if any XInput pad was found // Check if any XInput pad was found
@ -239,12 +215,50 @@ void ConfigDialog::CreateGUIControls()
//sDevice[i]->AddStretchSpacer(); //sDevice[i]->AddStretchSpacer();
#ifdef _WIN32 #ifdef _WIN32
sDevice[i]->Add(m_SizeXInput[i], 0, wxEXPAND | wxALL, 1); sDevice[i]->Add(m_SizeXInput[i], 0, wxEXPAND | wxALL, 1);
sDevice[i]->Add(m_SizeRecording[i], 0, wxEXPAND | wxALL, 1);
#endif #endif
// ----------------------------------- // -----------------------------------
/////////////////////////////////////////////////////////////////////////////////////
// Rerecording
// ¯¯¯¯¯¯¯¯¯
#ifdef RERECORDING
// Create controls
m_SizeRecording[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Input Recording"));
m_CheckRecording[i] = new wxCheckBox(m_Controller[i], ID_RECORDING, wxT("Record input"));
m_CheckPlayback[i] = new wxCheckBox(m_Controller[i], ID_PLAYBACK, wxT("Play back input"));
m_BtnSaveRecording[i] = new wxButton(m_Controller[i], ID_SAVE_RECORDING, wxT("Save recording"), wxDefaultPosition, wxDefaultSize);
// Tool tips
m_CheckRecording[i]->SetToolTip(wxT("Your recording will be saved to pad-record.bin in the Dolphin dir when you stop the game"));
m_CheckPlayback[i]->SetToolTip(wxT("Play back the pad-record.bin file from the Dolphin dir"));
m_BtnSaveRecording[i]->SetToolTip(wxT(
"This will save the current recording to pad-record.bin. Your recording will\n"
"also be automatically saved every 60 * 10 frames. And when you shut down the\n"
"game."));
// Sizers
m_SizeRecording[i]->Add(m_CheckRecording[i], 0, wxEXPAND | wxALL, 1);
m_SizeRecording[i]->Add(m_CheckPlayback[i], 0, wxEXPAND | wxALL, 1);
m_SizeRecording[i]->Add(m_BtnSaveRecording[i], 0, wxEXPAND | wxALL, 1);
// Only enable these options for pad 0
m_CheckRecording[i]->Enable(false); m_CheckRecording[0]->Enable(true);
m_CheckPlayback[i]->Enable(false); m_CheckPlayback[0]->Enable(true);
m_BtnSaveRecording[i]->Enable(false); m_BtnSaveRecording[0]->Enable(true);
// Don't allow saving when we are not recording
m_BtnSaveRecording[i]->Enable(g_EmulatorRunning && pad[0].bRecording);
sDevice[i]->Add(m_SizeRecording[i], 0, wxEXPAND | wxALL, 1);
// Set values
m_CheckRecording[0]->SetValue(pad[0].bRecording);
m_CheckPlayback[0]->SetValue(pad[0].bPlayback);
Console::Print("m_CheckRecording: %i\n", pad[0].bRecording, pad[0].bPlayback);
#endif
//////////////////////////////////////
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// Buttons // Buttons
// ----------------------------- // -----------------------------
@ -400,6 +414,8 @@ void ConfigDialog::ControllerSettingsChanged(wxCommandEvent& event)
pad[page].bRumble = m_Rumble[page]->GetValue(); pad[page].bRumble = m_Rumble[page]->GetValue();
break; break;
// Input recording
#ifdef RERECORDING
case ID_RECORDING: case ID_RECORDING:
pad[page].bRecording = m_CheckRecording[page]->GetValue(); pad[page].bRecording = m_CheckRecording[page]->GetValue();
// Turn off the other option // Turn off the other option
@ -414,7 +430,7 @@ void ConfigDialog::ControllerSettingsChanged(wxCommandEvent& event)
// Double check again that we are still running a game // Double check again that we are still running a game
if (g_EmulatorRunning) SaveRecord(); if (g_EmulatorRunning) SaveRecord();
break; break;
#endif
} }
} }

View File

@ -28,6 +28,7 @@
#include "IniFile.h" #include "IniFile.h"
#include "ConsoleWindow.h" #include "ConsoleWindow.h"
#include "StringUtil.h" #include "StringUtil.h"
#include "FileUtil.h"
#include "ChunkFile.h" #include "ChunkFile.h"
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
@ -617,7 +618,10 @@ void DllConfig(HWND _hParent)
{ {
//Console::Open(70, 5000); //Console::Open(70, 5000);
// Load configuration
LoadConfig(); LoadConfig();
// Show wxDialog
#ifdef _WIN32 #ifdef _WIN32
wxWindow win; wxWindow win;
win.SetHWND(_hParent); win.SetHWND(_hParent);
@ -628,6 +632,8 @@ void DllConfig(HWND _hParent)
ConfigDialog frame(NULL); ConfigDialog frame(NULL);
frame.ShowModal(); frame.ShowModal();
#endif #endif
// Save configuration
SaveConfig(); SaveConfig();
} }
@ -643,8 +649,29 @@ void Initialize(void *init)
// Load configuration // Load configuration
LoadConfig(); LoadConfig();
// -------------------------------------------
// Rerecording
// ----------------------
#ifdef RERECORDING
/* Check if we are starting the pad to record the input, and an old file exists. In that case ask
if we really want to start the recording and eventually overwrite the file */
if (pad[0].bRecording && File::Exists("pad-record.bin"))
{
if (!AskYesNo("An old version of '%s' aleady exists in your Dolphin directory. You can"
" now make a copy of it before you start a new recording and overwrite the file."
" Select Yes to continue and overwrite the file. Select No to turn off the input"
" recording and continue without recording anything.",
"pad-record.bin"))
{
// Turn off recording and continue
pad[0].bRecording = false;
}
}
// Load recorded input if we are to play it back, otherwise begin with a blank recording // Load recorded input if we are to play it back, otherwise begin with a blank recording
if (pad[0].bPlayback) LoadRecord(); if (pad[0].bPlayback) LoadRecord();
#endif
// ----------------------
g_PADInitialize = *(SPADInitialize*)init; g_PADInitialize = *(SPADInitialize*)init;
@ -668,10 +695,17 @@ void Shutdown()
{ {
//Console::Print("ShutDown()\n"); //Console::Print("ShutDown()\n");
// -------------------------------------------
// Play back input instead of accepting any user input
// ----------------------
#ifdef RERECORDING
// Save recording // Save recording
if (pad[0].bRecording) SaveRecord(); if (pad[0].bRecording) SaveRecord();
// Reset the counter // Reset the counter
count = 0; count = 0;
#endif
// ----------------------
// We have stopped the game // We have stopped the game
g_EmulatorRunning = false; g_EmulatorRunning = false;
@ -699,12 +733,17 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
// Check if all is okay // Check if all is okay
if (_pPADStatus == NULL) return; if (_pPADStatus == NULL) return;
// -------------------------------------------
// Play back input instead of accepting any user input // Play back input instead of accepting any user input
// ----------------------
#ifdef RERECORDING
if (pad[0].bPlayback) if (pad[0].bPlayback)
{ {
*_pPADStatus = PlayRecord(); *_pPADStatus = PlayRecord();
return; return;
} }
#endif
// ----------------------
const int base = 0x80; const int base = 0x80;
// Clear pad // Clear pad
@ -736,8 +775,14 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
cocoa_Read(_numPAD, _pPADStatus); cocoa_Read(_numPAD, _pPADStatus);
#endif #endif
// -------------------------------------------
// Rerecording
// ----------------------
#ifdef RERECORDING
// Record input // Record input
if (pad[0].bRecording) RecordInput(*_pPADStatus); if (pad[0].bRecording) RecordInput(*_pPADStatus);
#endif
// ----------------------
} }
@ -891,8 +936,11 @@ void LoadConfig()
file.Get(SectionName, "Rumble", &pad[i].bRumble, true); file.Get(SectionName, "Rumble", &pad[i].bRumble, true);
file.Get(SectionName, "XPad#", &pad[i].XPadPlayer); file.Get(SectionName, "XPad#", &pad[i].XPadPlayer);
file.Get(SectionName, "Recording", &pad[i].bRecording, false); // Recording
file.Get(SectionName, "Playback", &pad[i].bPlayback, false); #ifdef RERECORDING
file.Get(SectionName, "Recording", &pad[0].bRecording, false);
file.Get(SectionName, "Playback", &pad[0].bPlayback, false);
#endif
for (int x = 0; x < NUMCONTROLS; x++) for (int x = 0; x < NUMCONTROLS; x++)
{ {
@ -924,8 +972,10 @@ void SaveConfig()
file.Set(SectionName, "Rumble", pad[i].bRumble); file.Set(SectionName, "Rumble", pad[i].bRumble);
file.Set(SectionName, "XPad#", pad[i].XPadPlayer); file.Set(SectionName, "XPad#", pad[i].XPadPlayer);
// Recording // Recording
file.Set(SectionName, "Recording", pad[i].bRecording); #ifdef RERECORDING
file.Set(SectionName, "Playback", pad[i].bPlayback); file.Set(SectionName, "Recording", pad[0].bRecording);
file.Set(SectionName, "Playback", pad[0].bPlayback);
#endif
for (int x = 0; x < NUMCONTROLS; x++) for (int x = 0; x < NUMCONTROLS; x++)
{ {

View File

@ -18,6 +18,9 @@
#ifndef __PADSIMPLE_H__ #ifndef __PADSIMPLE_H__
#define __PADSIMPLE_H__ #define __PADSIMPLE_H__
#include "Setup.h" // Common
#include "ConsoleWindow.h"
// Controls // Controls
enum enum
{ {