Core/Movie: Refactor to class, move to System.
A bit of global state remains (the `header` in `BeginRecordingInput()`) due to unclear lifetime requirements.
This commit is contained in:
parent
c76dee7807
commit
95cba6be2b
|
@ -66,11 +66,13 @@ bool BootCore(std::unique_ptr<BootParameters> boot, const WindowSystemInfo& wsi)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Movie settings
|
// Movie settings
|
||||||
if (Movie::IsPlayingInput() && Movie::IsConfigSaved())
|
auto& system = Core::System::GetInstance();
|
||||||
|
auto& movie = system.GetMovie();
|
||||||
|
if (movie.IsPlayingInput() && movie.IsConfigSaved())
|
||||||
{
|
{
|
||||||
for (ExpansionInterface::Slot slot : ExpansionInterface::MEMCARD_SLOTS)
|
for (ExpansionInterface::Slot slot : ExpansionInterface::MEMCARD_SLOTS)
|
||||||
{
|
{
|
||||||
if (Movie::IsUsingMemcard(slot) && Movie::IsStartingFromClearSave() && !StartUp.bWii)
|
if (movie.IsUsingMemcard(slot) && movie.IsStartingFromClearSave() && !StartUp.bWii)
|
||||||
{
|
{
|
||||||
const auto raw_path =
|
const auto raw_path =
|
||||||
File::GetUserPath(D_GCUSER_IDX) +
|
File::GetUserPath(D_GCUSER_IDX) +
|
||||||
|
@ -142,7 +144,6 @@ bool BootCore(std::unique_ptr<BootParameters> boot, const WindowSystemInfo& wsi)
|
||||||
if (!boot->riivolution_patches.empty())
|
if (!boot->riivolution_patches.empty())
|
||||||
Config::SetCurrent(Config::MAIN_FAST_DISC_SPEED, true);
|
Config::SetCurrent(Config::MAIN_FAST_DISC_SPEED, true);
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
|
||||||
system.Initialize();
|
system.Initialize();
|
||||||
|
|
||||||
Core::UpdateWantDeterminism(/*initial*/ true);
|
Core::UpdateWantDeterminism(/*initial*/ true);
|
||||||
|
|
|
@ -564,8 +564,8 @@ static void EmuThread(Core::System& system, std::unique_ptr<BootParameters> boot
|
||||||
system.GetCustomAssetLoader().Init();
|
system.GetCustomAssetLoader().Init();
|
||||||
Common::ScopeGuard asset_loader_guard([&system] { system.GetCustomAssetLoader().Shutdown(); });
|
Common::ScopeGuard asset_loader_guard([&system] { system.GetCustomAssetLoader().Shutdown(); });
|
||||||
|
|
||||||
Movie::Init(*boot);
|
system.GetMovie().Init(*boot);
|
||||||
Common::ScopeGuard movie_guard{&Movie::Shutdown};
|
Common::ScopeGuard movie_guard([&system] { system.GetMovie().Shutdown(); });
|
||||||
|
|
||||||
AudioCommon::InitSoundStream(system);
|
AudioCommon::InitSoundStream(system);
|
||||||
Common::ScopeGuard audio_guard([&system] { AudioCommon::ShutdownSoundStream(system); });
|
Common::ScopeGuard audio_guard([&system] { AudioCommon::ShutdownSoundStream(system); });
|
||||||
|
@ -1019,7 +1019,8 @@ void UpdateWantDeterminism(bool initial)
|
||||||
// For now, this value is not itself configurable. Instead, individual
|
// For now, this value is not itself configurable. Instead, individual
|
||||||
// settings that depend on it, such as GPU determinism mode. should have
|
// settings that depend on it, such as GPU determinism mode. should have
|
||||||
// override options for testing,
|
// override options for testing,
|
||||||
bool new_want_determinism = Movie::IsMovieActive() || NetPlay::IsNetPlayRunning();
|
auto& system = Core::System::GetInstance();
|
||||||
|
bool new_want_determinism = system.GetMovie().IsMovieActive() || NetPlay::IsNetPlayRunning();
|
||||||
if (new_want_determinism != s_wants_determinism || initial)
|
if (new_want_determinism != s_wants_determinism || initial)
|
||||||
{
|
{
|
||||||
NOTICE_LOG_FMT(COMMON, "Want determinism <- {}", new_want_determinism ? "true" : "false");
|
NOTICE_LOG_FMT(COMMON, "Want determinism <- {}", new_want_determinism ? "true" : "false");
|
||||||
|
@ -1030,7 +1031,6 @@ void UpdateWantDeterminism(bool initial)
|
||||||
if (ios)
|
if (ios)
|
||||||
ios->UpdateWantDeterminism(new_want_determinism);
|
ios->UpdateWantDeterminism(new_want_determinism);
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
|
||||||
system.GetFifo().UpdateWantDeterminism(new_want_determinism);
|
system.GetFifo().UpdateWantDeterminism(new_want_determinism);
|
||||||
|
|
||||||
// We need to clear the cache because some parts of the JIT depend on want_determinism,
|
// We need to clear the cache because some parts of the JIT depend on want_determinism,
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "Core/HW/GCPad.h"
|
#include "Core/HW/GCPad.h"
|
||||||
#include "Core/Movie.h"
|
#include "Core/Movie.h"
|
||||||
#include "Core/NetPlayProto.h"
|
#include "Core/NetPlayProto.h"
|
||||||
|
#include "Core/System.h"
|
||||||
#include "InputCommon/GCAdapter.h"
|
#include "InputCommon/GCAdapter.h"
|
||||||
#include "InputCommon/InputConfig.h"
|
#include "InputCommon/InputConfig.h"
|
||||||
#include "VideoCommon/VideoBackendBase.h"
|
#include "VideoCommon/VideoBackendBase.h"
|
||||||
|
@ -417,7 +418,7 @@ void DolphinAnalytics::MakePerGameBuilder()
|
||||||
|
|
||||||
// NetPlay / recording.
|
// NetPlay / recording.
|
||||||
builder.AddData("netplay", NetPlay::IsNetPlayRunning());
|
builder.AddData("netplay", NetPlay::IsNetPlayRunning());
|
||||||
builder.AddData("movie", Movie::IsMovieActive());
|
builder.AddData("movie", Core::System::GetInstance().GetMovie().IsMovieActive());
|
||||||
|
|
||||||
// Controller information
|
// Controller information
|
||||||
// We grab enough to tell what percentage of our users are playing with keyboard/mouse, some kind
|
// We grab enough to tell what percentage of our users are playing with keyboard/mouse, some kind
|
||||||
|
|
|
@ -476,7 +476,7 @@ void DVDInterface::ChangeDisc(const std::string& new_path)
|
||||||
m_disc_path_to_insert = new_path;
|
m_disc_path_to_insert = new_path;
|
||||||
m_system.GetCoreTiming().ScheduleEvent(m_system.GetSystemTimers().GetTicksPerSecond(),
|
m_system.GetCoreTiming().ScheduleEvent(m_system.GetSystemTimers().GetTicksPerSecond(),
|
||||||
m_insert_disc);
|
m_insert_disc);
|
||||||
Movie::SignalDiscChange(new_path);
|
m_system.GetMovie().SignalDiscChange(new_path);
|
||||||
|
|
||||||
for (size_t i = 0; i < m_auto_disc_change_paths.size(); ++i)
|
for (size_t i = 0; i < m_auto_disc_change_paths.size(); ++i)
|
||||||
{
|
{
|
||||||
|
@ -1087,7 +1087,7 @@ void DVDInterface::ExecuteCommand(ReplyType reply_type)
|
||||||
|
|
||||||
const bool force_eject = eject && !kill;
|
const bool force_eject = eject && !kill;
|
||||||
|
|
||||||
if (Config::Get(Config::MAIN_AUTO_DISC_CHANGE) && !Movie::IsPlayingInput() &&
|
if (Config::Get(Config::MAIN_AUTO_DISC_CHANGE) && !m_system.GetMovie().IsPlayingInput() &&
|
||||||
m_system.GetDVDThread().IsInsertedDiscRunning() && !m_auto_disc_change_paths.empty())
|
m_system.GetDVDThread().IsInsertedDiscRunning() && !m_auto_disc_change_paths.empty())
|
||||||
{
|
{
|
||||||
m_system.GetCoreTiming().ScheduleEvent(
|
m_system.GetCoreTiming().ScheduleEvent(
|
||||||
|
|
|
@ -36,9 +36,11 @@ ExpansionInterfaceManager::~ExpansionInterfaceManager() = default;
|
||||||
void ExpansionInterfaceManager::AddMemoryCard(Slot slot)
|
void ExpansionInterfaceManager::AddMemoryCard(Slot slot)
|
||||||
{
|
{
|
||||||
EXIDeviceType memorycard_device;
|
EXIDeviceType memorycard_device;
|
||||||
if (Movie::IsPlayingInput() && Movie::IsConfigSaved())
|
|
||||||
|
auto& movie = m_system.GetMovie();
|
||||||
|
if (movie.IsPlayingInput() && movie.IsConfigSaved())
|
||||||
{
|
{
|
||||||
if (Movie::IsUsingMemcard(slot))
|
if (movie.IsUsingMemcard(slot))
|
||||||
{
|
{
|
||||||
memorycard_device = Config::Get(Config::GetInfoForEXIDevice(slot));
|
memorycard_device = Config::Get(Config::GetInfoForEXIDevice(slot));
|
||||||
if (memorycard_device != EXIDeviceType::MemoryCardFolder &&
|
if (memorycard_device != EXIDeviceType::MemoryCardFolder &&
|
||||||
|
|
|
@ -264,7 +264,7 @@ void CEXIChannel::DoState(PointerWrap& p)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == EXIDeviceType::MemoryCardFolder && old_header_data != m_memcard_header_data &&
|
if (type == EXIDeviceType::MemoryCardFolder && old_header_data != m_memcard_header_data &&
|
||||||
!Movie::IsMovieActive())
|
!m_system.GetMovie().IsMovieActive())
|
||||||
{
|
{
|
||||||
// We have loaded a savestate that has a GCI folder memcard that is different to the virtual
|
// We have loaded a savestate that has a GCI folder memcard that is different to the virtual
|
||||||
// card that is currently active. In order to prevent the game from recognizing this card as a
|
// card that is currently active. In order to prevent the game from recognizing this card as a
|
||||||
|
|
|
@ -406,9 +406,10 @@ u32 CEXIIPL::GetEmulatedTime(Core::System& system, u32 epoch)
|
||||||
{
|
{
|
||||||
u64 ltime = 0;
|
u64 ltime = 0;
|
||||||
|
|
||||||
if (Movie::IsMovieActive())
|
auto& movie = system.GetMovie();
|
||||||
|
if (movie.IsMovieActive())
|
||||||
{
|
{
|
||||||
ltime = Movie::GetRecordingStartTime();
|
ltime = movie.GetRecordingStartTime();
|
||||||
|
|
||||||
// let's keep time moving forward, regardless of what it starts at
|
// let's keep time moving forward, regardless of what it starts at
|
||||||
ltime += system.GetCoreTiming().GetTicks() / system.GetSystemTimers().GetTicksPerSecond();
|
ltime += system.GetCoreTiming().GetTicks() / system.GetSystemTimers().GetTicksPerSecond();
|
||||||
|
|
|
@ -149,7 +149,8 @@ CEXIMemoryCard::CEXIMemoryCard(Core::System& system, const Slot slot, bool gci_f
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<std::string /* path */, bool /* migrate */>
|
std::pair<std::string /* path */, bool /* migrate */>
|
||||||
CEXIMemoryCard::GetGCIFolderPath(Slot card_slot, AllowMovieFolder allow_movie_folder)
|
CEXIMemoryCard::GetGCIFolderPath(Slot card_slot, AllowMovieFolder allow_movie_folder,
|
||||||
|
Movie::MovieManager& movie)
|
||||||
{
|
{
|
||||||
std::string path_override = Config::Get(Config::GetInfoForGCIPathOverride(card_slot));
|
std::string path_override = Config::Get(Config::GetInfoForGCIPathOverride(card_slot));
|
||||||
|
|
||||||
|
@ -157,9 +158,8 @@ CEXIMemoryCard::GetGCIFolderPath(Slot card_slot, AllowMovieFolder allow_movie_fo
|
||||||
return {std::move(path_override), false};
|
return {std::move(path_override), false};
|
||||||
|
|
||||||
const bool use_movie_folder = allow_movie_folder == AllowMovieFolder::Yes &&
|
const bool use_movie_folder = allow_movie_folder == AllowMovieFolder::Yes &&
|
||||||
Movie::IsPlayingInput() && Movie::IsConfigSaved() &&
|
movie.IsPlayingInput() && movie.IsConfigSaved() &&
|
||||||
Movie::IsUsingMemcard(card_slot) &&
|
movie.IsUsingMemcard(card_slot) && movie.IsStartingFromClearSave();
|
||||||
Movie::IsStartingFromClearSave();
|
|
||||||
|
|
||||||
const DiscIO::Region region = Config::ToGameCubeRegion(SConfig::GetInstance().m_region);
|
const DiscIO::Region region = Config::ToGameCubeRegion(SConfig::GetInstance().m_region);
|
||||||
if (use_movie_folder)
|
if (use_movie_folder)
|
||||||
|
@ -182,7 +182,8 @@ void CEXIMemoryCard::SetupGciFolder(const Memcard::HeaderData& header_data)
|
||||||
current_game_id = Common::swap32(reinterpret_cast<const u8*>(game_id.c_str()));
|
current_game_id = Common::swap32(reinterpret_cast<const u8*>(game_id.c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto [dir_path, migrate] = GetGCIFolderPath(m_card_slot, AllowMovieFolder::Yes);
|
const auto [dir_path, migrate] =
|
||||||
|
GetGCIFolderPath(m_card_slot, AllowMovieFolder::Yes, m_system.GetMovie());
|
||||||
|
|
||||||
const File::FileInfo file_info(dir_path);
|
const File::FileInfo file_info(dir_path);
|
||||||
if (!file_info.Exists())
|
if (!file_info.Exists())
|
||||||
|
@ -219,8 +220,9 @@ void CEXIMemoryCard::SetupGciFolder(const Memcard::HeaderData& header_data)
|
||||||
void CEXIMemoryCard::SetupRawMemcard(u16 size_mb)
|
void CEXIMemoryCard::SetupRawMemcard(u16 size_mb)
|
||||||
{
|
{
|
||||||
std::string filename;
|
std::string filename;
|
||||||
if (Movie::IsPlayingInput() && Movie::IsConfigSaved() && Movie::IsUsingMemcard(m_card_slot) &&
|
auto& movie = m_system.GetMovie();
|
||||||
Movie::IsStartingFromClearSave())
|
if (movie.IsPlayingInput() && movie.IsConfigSaved() && movie.IsUsingMemcard(m_card_slot) &&
|
||||||
|
movie.IsStartingFromClearSave())
|
||||||
{
|
{
|
||||||
filename = File::GetUserPath(D_GCUSER_IDX) +
|
filename = File::GetUserPath(D_GCUSER_IDX) +
|
||||||
fmt::format("Movie{}.raw", s_card_short_names[m_card_slot]);
|
fmt::format("Movie{}.raw", s_card_short_names[m_card_slot]);
|
||||||
|
@ -501,7 +503,7 @@ void CEXIMemoryCard::DoState(PointerWrap& p)
|
||||||
// otherwise, we'll assume the user wants to keep their memcards and saves separate,
|
// otherwise, we'll assume the user wants to keep their memcards and saves separate,
|
||||||
// unless we're loading (in which case we let the savestate contents decide, in order to stay
|
// unless we're loading (in which case we let the savestate contents decide, in order to stay
|
||||||
// aligned with them).
|
// aligned with them).
|
||||||
bool storeContents = (Movie::IsMovieActive());
|
bool storeContents = m_system.GetMovie().IsMovieActive();
|
||||||
p.Do(storeContents);
|
p.Do(storeContents);
|
||||||
|
|
||||||
if (storeContents)
|
if (storeContents)
|
||||||
|
|
|
@ -26,6 +26,10 @@ namespace Memcard
|
||||||
{
|
{
|
||||||
struct HeaderData;
|
struct HeaderData;
|
||||||
}
|
}
|
||||||
|
namespace Movie
|
||||||
|
{
|
||||||
|
class MovieManager;
|
||||||
|
}
|
||||||
|
|
||||||
namespace ExpansionInterface
|
namespace ExpansionInterface
|
||||||
{
|
{
|
||||||
|
@ -58,7 +62,7 @@ public:
|
||||||
static void Shutdown();
|
static void Shutdown();
|
||||||
|
|
||||||
static std::pair<std::string /* path */, bool /* migrate */>
|
static std::pair<std::string /* path */, bool /* migrate */>
|
||||||
GetGCIFolderPath(Slot card_slot, AllowMovieFolder allow_movie_folder);
|
GetGCIFolderPath(Slot card_slot, AllowMovieFolder allow_movie_folder, Movie::MovieManager& movie);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetupGciFolder(const Memcard::HeaderData& header_data);
|
void SetupGciFolder(const Memcard::HeaderData& header_data);
|
||||||
|
|
|
@ -265,19 +265,20 @@ void SerialInterfaceManager::Init()
|
||||||
m_channel[i].in_lo.hex = 0;
|
m_channel[i].in_lo.hex = 0;
|
||||||
m_channel[i].has_recent_device_change = false;
|
m_channel[i].has_recent_device_change = false;
|
||||||
|
|
||||||
if (Movie::IsMovieActive())
|
auto& movie = m_system.GetMovie();
|
||||||
|
if (movie.IsMovieActive())
|
||||||
{
|
{
|
||||||
m_desired_device_types[i] = SIDEVICE_NONE;
|
m_desired_device_types[i] = SIDEVICE_NONE;
|
||||||
|
|
||||||
if (Movie::IsUsingGBA(i))
|
if (movie.IsUsingGBA(i))
|
||||||
{
|
{
|
||||||
m_desired_device_types[i] = SIDEVICE_GC_GBA_EMULATED;
|
m_desired_device_types[i] = SIDEVICE_GC_GBA_EMULATED;
|
||||||
}
|
}
|
||||||
else if (Movie::IsUsingPad(i))
|
else if (movie.IsUsingPad(i))
|
||||||
{
|
{
|
||||||
SIDevices current = Config::Get(Config::GetInfoForSIDevice(i));
|
SIDevices current = Config::Get(Config::GetInfoForSIDevice(i));
|
||||||
// GC pad-compatible devices can be used for both playing and recording
|
// GC pad-compatible devices can be used for both playing and recording
|
||||||
if (Movie::IsUsingBongo(i))
|
if (movie.IsUsingBongo(i))
|
||||||
m_desired_device_types[i] = SIDEVICE_GC_TARUKONGA;
|
m_desired_device_types[i] = SIDEVICE_GC_TARUKONGA;
|
||||||
else if (SIDevice_IsGCController(current))
|
else if (SIDevice_IsGCController(current))
|
||||||
m_desired_device_types[i] = current;
|
m_desired_device_types[i] = current;
|
||||||
|
|
|
@ -125,7 +125,8 @@ bool CSIDevice_GBAEmu::GetData(u32& hi, u32& low)
|
||||||
GCPadStatus pad_status{};
|
GCPadStatus pad_status{};
|
||||||
if (!NetPlay::IsNetPlayRunning())
|
if (!NetPlay::IsNetPlayRunning())
|
||||||
pad_status = Pad::GetGBAStatus(m_device_number);
|
pad_status = Pad::GetGBAStatus(m_device_number);
|
||||||
SerialInterface::CSIDevice_GCController::HandleMoviePadStatus(m_device_number, &pad_status);
|
SerialInterface::CSIDevice_GCController::HandleMoviePadStatus(m_system.GetMovie(),
|
||||||
|
m_device_number, &pad_status);
|
||||||
|
|
||||||
static constexpr std::array<PadButton, 10> buttons_map = {
|
static constexpr std::array<PadButton, 10> buttons_map = {
|
||||||
PadButton::PAD_BUTTON_A, // A
|
PadButton::PAD_BUTTON_A, // A
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "Core/Core.h"
|
#include "Core/Core.h"
|
||||||
#include "Core/HW/GCPad.h"
|
#include "Core/HW/GCPad.h"
|
||||||
#include "Core/NetPlayProto.h"
|
#include "Core/NetPlayProto.h"
|
||||||
|
#include "Core/System.h"
|
||||||
#include "InputCommon/GCAdapter.h"
|
#include "InputCommon/GCAdapter.h"
|
||||||
|
|
||||||
namespace SerialInterface
|
namespace SerialInterface
|
||||||
|
@ -38,7 +39,7 @@ GCPadStatus CSIDevice_GCAdapter::GetPadStatus()
|
||||||
pad_status = GCAdapter::Input(m_device_number);
|
pad_status = GCAdapter::Input(m_device_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
HandleMoviePadStatus(m_device_number, &pad_status);
|
HandleMoviePadStatus(m_system.GetMovie(), m_device_number, &pad_status);
|
||||||
|
|
||||||
// Our GCAdapter code sets PAD_GET_ORIGIN when a new device has been connected.
|
// Our GCAdapter code sets PAD_GET_ORIGIN when a new device has been connected.
|
||||||
// Watch for this to calibrate real controllers on connection.
|
// Watch for this to calibrate real controllers on connection.
|
||||||
|
|
|
@ -120,25 +120,26 @@ int CSIDevice_GCController::RunBuffer(u8* buffer, int request_length)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSIDevice_GCController::HandleMoviePadStatus(int device_number, GCPadStatus* pad_status)
|
void CSIDevice_GCController::HandleMoviePadStatus(Movie::MovieManager& movie, int device_number,
|
||||||
|
GCPadStatus* pad_status)
|
||||||
{
|
{
|
||||||
Movie::SetPolledDevice();
|
movie.SetPolledDevice();
|
||||||
if (NetPlay_GetInput(device_number, pad_status))
|
if (NetPlay_GetInput(device_number, pad_status))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
else if (Movie::IsPlayingInput())
|
else if (movie.IsPlayingInput())
|
||||||
{
|
{
|
||||||
Movie::PlayController(pad_status, device_number);
|
movie.PlayController(pad_status, device_number);
|
||||||
Movie::InputUpdate();
|
movie.InputUpdate();
|
||||||
}
|
}
|
||||||
else if (Movie::IsRecordingInput())
|
else if (movie.IsRecordingInput())
|
||||||
{
|
{
|
||||||
Movie::RecordInput(pad_status, device_number);
|
movie.RecordInput(pad_status, device_number);
|
||||||
Movie::InputUpdate();
|
movie.InputUpdate();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Movie::CheckPadStatus(pad_status, device_number);
|
movie.CheckPadStatus(pad_status, device_number);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,7 +154,7 @@ GCPadStatus CSIDevice_GCController::GetPadStatus()
|
||||||
pad_status = Pad::GetStatus(m_device_number);
|
pad_status = Pad::GetStatus(m_device_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
HandleMoviePadStatus(m_device_number, &pad_status);
|
HandleMoviePadStatus(m_system.GetMovie(), m_device_number, &pad_status);
|
||||||
|
|
||||||
// Our GCAdapter code sets PAD_GET_ORIGIN when a new device has been connected.
|
// Our GCAdapter code sets PAD_GET_ORIGIN when a new device has been connected.
|
||||||
// Watch for this to calibrate real controllers on connection.
|
// Watch for this to calibrate real controllers on connection.
|
||||||
|
|
|
@ -9,6 +9,11 @@
|
||||||
#include "Core/HW/SI/SI_Device.h"
|
#include "Core/HW/SI/SI_Device.h"
|
||||||
#include "InputCommon/GCPadStatus.h"
|
#include "InputCommon/GCPadStatus.h"
|
||||||
|
|
||||||
|
namespace Movie
|
||||||
|
{
|
||||||
|
class MovieManager;
|
||||||
|
}
|
||||||
|
|
||||||
namespace SerialInterface
|
namespace SerialInterface
|
||||||
{
|
{
|
||||||
class CSIDevice_GCController : public ISIDevice
|
class CSIDevice_GCController : public ISIDevice
|
||||||
|
@ -78,7 +83,8 @@ public:
|
||||||
// Direct rumble to the right GC Controller
|
// Direct rumble to the right GC Controller
|
||||||
static void Rumble(int pad_num, ControlState strength, SIDevices device);
|
static void Rumble(int pad_num, ControlState strength, SIDevices device);
|
||||||
|
|
||||||
static void HandleMoviePadStatus(int device_number, GCPadStatus* pad_status);
|
static void HandleMoviePadStatus(Movie::MovieManager& movie, int device_number,
|
||||||
|
GCPadStatus* pad_status);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void SetOrigin(const GCPadStatus& pad_status);
|
void SetOrigin(const GCPadStatus& pad_status);
|
||||||
|
|
|
@ -852,7 +852,7 @@ void VideoInterfaceManager::Update(u64 ticks)
|
||||||
// in case frame counter display is enabled
|
// in case frame counter display is enabled
|
||||||
|
|
||||||
if (m_half_line_count == 0 || m_half_line_count == GetHalfLinesPerEvenField())
|
if (m_half_line_count == 0 || m_half_line_count == GetHalfLinesPerEvenField())
|
||||||
Movie::FrameUpdate();
|
m_system.GetMovie().FrameUpdate();
|
||||||
|
|
||||||
// If this half-line is at some boundary of the "active video lines" in either field, we either
|
// If this half-line is at some boundary of the "active video lines" in either field, we either
|
||||||
// need to (a) send a request to the GPU thread to actually render the XFB, or (b) increment
|
// need to (a) send a request to the GPU thread to actually render the XFB, or (b) increment
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "Core/IOS/USB/Bluetooth/WiimoteDevice.h"
|
#include "Core/IOS/USB/Bluetooth/WiimoteDevice.h"
|
||||||
#include "Core/Movie.h"
|
#include "Core/Movie.h"
|
||||||
#include "Core/NetPlayClient.h"
|
#include "Core/NetPlayClient.h"
|
||||||
|
#include "Core/System.h"
|
||||||
#include "Core/WiiUtils.h"
|
#include "Core/WiiUtils.h"
|
||||||
|
|
||||||
#include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h"
|
#include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h"
|
||||||
|
@ -192,8 +193,9 @@ void Initialize(InitializeMode init_mode)
|
||||||
WiimoteReal::Initialize(init_mode);
|
WiimoteReal::Initialize(init_mode);
|
||||||
|
|
||||||
// Reload Wiimotes with our settings
|
// Reload Wiimotes with our settings
|
||||||
if (Movie::IsMovieActive())
|
auto& movie = Core::System::GetInstance().GetMovie();
|
||||||
Movie::ChangeWiiPads();
|
if (movie.IsMovieActive())
|
||||||
|
movie.ChangeWiiPads();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResetAllWiimotes()
|
void ResetAllWiimotes()
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "Core/Core.h"
|
#include "Core/Core.h"
|
||||||
#include "Core/HW/Wiimote.h"
|
#include "Core/HW/Wiimote.h"
|
||||||
#include "Core/Movie.h"
|
#include "Core/Movie.h"
|
||||||
|
#include "Core/System.h"
|
||||||
|
|
||||||
#include "Core/HW/WiimoteCommon/WiimoteConstants.h"
|
#include "Core/HW/WiimoteCommon/WiimoteConstants.h"
|
||||||
#include "Core/HW/WiimoteCommon/WiimoteHid.h"
|
#include "Core/HW/WiimoteCommon/WiimoteHid.h"
|
||||||
|
@ -552,7 +553,8 @@ void Wiimote::Update(const WiimoteEmu::DesiredWiimoteState& target_state)
|
||||||
|
|
||||||
void Wiimote::SendDataReport(const DesiredWiimoteState& target_state)
|
void Wiimote::SendDataReport(const DesiredWiimoteState& target_state)
|
||||||
{
|
{
|
||||||
Movie::SetPolledDevice();
|
auto& movie = Core::System::GetInstance().GetMovie();
|
||||||
|
movie.SetPolledDevice();
|
||||||
|
|
||||||
if (InputReportID::ReportDisabled == m_reporting_mode)
|
if (InputReportID::ReportDisabled == m_reporting_mode)
|
||||||
{
|
{
|
||||||
|
@ -569,9 +571,8 @@ void Wiimote::SendDataReport(const DesiredWiimoteState& target_state)
|
||||||
|
|
||||||
DataReportBuilder rpt_builder(m_reporting_mode);
|
DataReportBuilder rpt_builder(m_reporting_mode);
|
||||||
|
|
||||||
if (Movie::IsPlayingInput() &&
|
if (movie.IsPlayingInput() && movie.PlayWiimote(m_bt_device_index, rpt_builder,
|
||||||
Movie::PlayWiimote(m_bt_device_index, rpt_builder, m_active_extension,
|
m_active_extension, GetExtensionEncryptionKey()))
|
||||||
GetExtensionEncryptionKey()))
|
|
||||||
{
|
{
|
||||||
// Update buttons in status struct from movie:
|
// Update buttons in status struct from movie:
|
||||||
rpt_builder.GetCoreData(&m_status.buttons);
|
rpt_builder.GetCoreData(&m_status.buttons);
|
||||||
|
@ -640,8 +641,8 @@ void Wiimote::SendDataReport(const DesiredWiimoteState& target_state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Movie::CheckWiimoteStatus(m_bt_device_index, rpt_builder, m_active_extension,
|
movie.CheckWiimoteStatus(m_bt_device_index, rpt_builder, m_active_extension,
|
||||||
GetExtensionEncryptionKey());
|
GetExtensionEncryptionKey());
|
||||||
|
|
||||||
// Send the report:
|
// Send the report:
|
||||||
InterruptDataInputCallback(rpt_builder.GetDataPtr(), rpt_builder.GetDataSize());
|
InterruptDataInputCallback(rpt_builder.GetDataPtr(), rpt_builder.GetDataSize());
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "Core/IOS/ES/ES.h"
|
#include "Core/IOS/ES/ES.h"
|
||||||
#include "Core/IOS/IOS.h"
|
#include "Core/IOS/IOS.h"
|
||||||
#include "Core/Movie.h"
|
#include "Core/Movie.h"
|
||||||
|
#include "Core/System.h"
|
||||||
#include "Core/WiiRoot.h"
|
#include "Core/WiiRoot.h"
|
||||||
|
|
||||||
namespace IOS::HLE::FS
|
namespace IOS::HLE::FS
|
||||||
|
@ -391,8 +392,9 @@ void HostFileSystem::DoState(PointerWrap& p)
|
||||||
// then a call to p.DoExternal() will be used to skip over reading the contents of the "/"
|
// then a call to p.DoExternal() will be used to skip over reading the contents of the "/"
|
||||||
// directory (it skips over the number of bytes specified by size_of_nand_folder_saved)
|
// directory (it skips over the number of bytes specified by size_of_nand_folder_saved)
|
||||||
|
|
||||||
|
auto& movie = Core::System::GetInstance().GetMovie();
|
||||||
bool original_save_state_made_during_movie_recording =
|
bool original_save_state_made_during_movie_recording =
|
||||||
Movie::IsMovieActive() && Core::WiiRootIsTemporary();
|
movie.IsMovieActive() && Core::WiiRootIsTemporary();
|
||||||
p.Do(original_save_state_made_during_movie_recording);
|
p.Do(original_save_state_made_during_movie_recording);
|
||||||
|
|
||||||
u32 temp_val = 0;
|
u32 temp_val = 0;
|
||||||
|
@ -414,17 +416,17 @@ void HostFileSystem::DoState(PointerWrap& p)
|
||||||
else // case where we're in read mode.
|
else // case where we're in read mode.
|
||||||
{
|
{
|
||||||
DoStateRead(p, "/tmp");
|
DoStateRead(p, "/tmp");
|
||||||
if (!Movie::IsMovieActive() || !original_save_state_made_during_movie_recording ||
|
if (!movie.IsMovieActive() || !original_save_state_made_during_movie_recording ||
|
||||||
!Core::WiiRootIsTemporary() ||
|
!Core::WiiRootIsTemporary() ||
|
||||||
(original_save_state_made_during_movie_recording !=
|
(original_save_state_made_during_movie_recording !=
|
||||||
(Movie::IsMovieActive() && Core::WiiRootIsTemporary())))
|
(movie.IsMovieActive() && Core::WiiRootIsTemporary())))
|
||||||
{
|
{
|
||||||
(void)p.DoExternal(temp_val);
|
(void)p.DoExternal(temp_val);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
p.Do(temp_val);
|
p.Do(temp_val);
|
||||||
if (Movie::IsMovieActive() && Core::WiiRootIsTemporary())
|
if (movie.IsMovieActive() && Core::WiiRootIsTemporary())
|
||||||
DoStateRead(p, "/");
|
DoStateRead(p, "/");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -5,9 +5,11 @@
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <mutex>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
|
||||||
|
@ -16,6 +18,11 @@ struct BootParameters;
|
||||||
struct GCPadStatus;
|
struct GCPadStatus;
|
||||||
class PointerWrap;
|
class PointerWrap;
|
||||||
|
|
||||||
|
namespace Core
|
||||||
|
{
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
namespace ExpansionInterface
|
namespace ExpansionInterface
|
||||||
{
|
{
|
||||||
enum class Slot : int;
|
enum class Slot : int;
|
||||||
|
@ -137,68 +144,137 @@ static_assert(sizeof(DTMHeader) == 256, "DTMHeader should be 256 bytes");
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
void FrameUpdate();
|
enum class PlayMode
|
||||||
void InputUpdate();
|
{
|
||||||
void Init(const BootParameters& boot);
|
None = 0,
|
||||||
|
Recording,
|
||||||
|
Playing,
|
||||||
|
};
|
||||||
|
|
||||||
void SetPolledDevice();
|
class MovieManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit MovieManager(Core::System& system);
|
||||||
|
MovieManager(const MovieManager& other) = delete;
|
||||||
|
MovieManager(MovieManager&& other) = delete;
|
||||||
|
MovieManager& operator=(const MovieManager& other) = delete;
|
||||||
|
MovieManager& operator=(MovieManager&& other) = delete;
|
||||||
|
~MovieManager();
|
||||||
|
|
||||||
bool IsRecordingInput();
|
void FrameUpdate();
|
||||||
bool IsRecordingInputFromSaveState();
|
void InputUpdate();
|
||||||
bool IsJustStartingRecordingInputFromSaveState();
|
void Init(const BootParameters& boot);
|
||||||
bool IsJustStartingPlayingInputFromSaveState();
|
|
||||||
bool IsPlayingInput();
|
|
||||||
bool IsMovieActive();
|
|
||||||
bool IsReadOnly();
|
|
||||||
u64 GetRecordingStartTime();
|
|
||||||
|
|
||||||
u64 GetCurrentFrame();
|
void SetPolledDevice();
|
||||||
u64 GetTotalFrames();
|
|
||||||
u64 GetCurrentInputCount();
|
|
||||||
u64 GetTotalInputCount();
|
|
||||||
u64 GetCurrentLagCount();
|
|
||||||
u64 GetTotalLagCount();
|
|
||||||
|
|
||||||
void SetClearSave(bool enabled);
|
bool IsRecordingInput() const;
|
||||||
void SignalDiscChange(const std::string& new_path);
|
bool IsRecordingInputFromSaveState() const;
|
||||||
void SetReset(bool reset);
|
bool IsJustStartingRecordingInputFromSaveState() const;
|
||||||
|
bool IsJustStartingPlayingInputFromSaveState() const;
|
||||||
|
bool IsPlayingInput() const;
|
||||||
|
bool IsMovieActive() const;
|
||||||
|
bool IsReadOnly() const;
|
||||||
|
u64 GetRecordingStartTime() const;
|
||||||
|
|
||||||
bool IsConfigSaved();
|
u64 GetCurrentFrame() const;
|
||||||
bool IsStartingFromClearSave();
|
u64 GetTotalFrames() const;
|
||||||
bool IsUsingMemcard(ExpansionInterface::Slot slot);
|
u64 GetCurrentInputCount() const;
|
||||||
void SetGraphicsConfig();
|
u64 GetTotalInputCount() const;
|
||||||
bool IsNetPlayRecording();
|
u64 GetCurrentLagCount() const;
|
||||||
|
u64 GetTotalLagCount() const;
|
||||||
|
|
||||||
bool IsUsingPad(int controller);
|
void SetClearSave(bool enabled);
|
||||||
bool IsUsingWiimote(int wiimote);
|
void SignalDiscChange(const std::string& new_path);
|
||||||
bool IsUsingBongo(int controller);
|
void SetReset(bool reset);
|
||||||
bool IsUsingGBA(int controller);
|
|
||||||
void ChangePads();
|
|
||||||
void ChangeWiiPads(bool instantly = false);
|
|
||||||
|
|
||||||
void SetReadOnly(bool bEnabled);
|
bool IsConfigSaved() const;
|
||||||
|
bool IsStartingFromClearSave() const;
|
||||||
|
bool IsUsingMemcard(ExpansionInterface::Slot slot) const;
|
||||||
|
void SetGraphicsConfig();
|
||||||
|
bool IsNetPlayRecording() const;
|
||||||
|
|
||||||
bool BeginRecordingInput(const ControllerTypeArray& controllers,
|
bool IsUsingPad(int controller) const;
|
||||||
const WiimoteEnabledArray& wiimotes);
|
bool IsUsingWiimote(int wiimote) const;
|
||||||
void RecordInput(const GCPadStatus* PadStatus, int controllerID);
|
bool IsUsingBongo(int controller) const;
|
||||||
void RecordWiimote(int wiimote, const u8* data, u8 size);
|
bool IsUsingGBA(int controller) const;
|
||||||
|
void ChangePads();
|
||||||
|
void ChangeWiiPads(bool instantly = false);
|
||||||
|
|
||||||
bool PlayInput(const std::string& movie_path, std::optional<std::string>* savestate_path);
|
void SetReadOnly(bool bEnabled);
|
||||||
void LoadInput(const std::string& movie_path);
|
|
||||||
void ReadHeader();
|
|
||||||
void PlayController(GCPadStatus* PadStatus, int controllerID);
|
|
||||||
bool PlayWiimote(int wiimote, WiimoteCommon::DataReportBuilder& rpt,
|
|
||||||
WiimoteEmu::ExtensionNumber ext, const WiimoteEmu::EncryptionKey& key);
|
|
||||||
void EndPlayInput(bool cont);
|
|
||||||
void SaveRecording(const std::string& filename);
|
|
||||||
void DoState(PointerWrap& p);
|
|
||||||
void Shutdown();
|
|
||||||
void CheckPadStatus(const GCPadStatus* PadStatus, int controllerID);
|
|
||||||
void CheckWiimoteStatus(int wiimote, const WiimoteCommon::DataReportBuilder& rpt,
|
|
||||||
WiimoteEmu::ExtensionNumber ext, const WiimoteEmu::EncryptionKey& key);
|
|
||||||
|
|
||||||
std::string GetInputDisplay();
|
bool BeginRecordingInput(const ControllerTypeArray& controllers,
|
||||||
std::string GetRTCDisplay();
|
const WiimoteEnabledArray& wiimotes);
|
||||||
std::string GetRerecords();
|
void RecordInput(const GCPadStatus* PadStatus, int controllerID);
|
||||||
|
void RecordWiimote(int wiimote, const u8* data, u8 size);
|
||||||
|
|
||||||
|
bool PlayInput(const std::string& movie_path, std::optional<std::string>* savestate_path);
|
||||||
|
void LoadInput(const std::string& movie_path);
|
||||||
|
void ReadHeader();
|
||||||
|
void PlayController(GCPadStatus* PadStatus, int controllerID);
|
||||||
|
bool PlayWiimote(int wiimote, WiimoteCommon::DataReportBuilder& rpt,
|
||||||
|
WiimoteEmu::ExtensionNumber ext, const WiimoteEmu::EncryptionKey& key);
|
||||||
|
void EndPlayInput(bool cont);
|
||||||
|
void SaveRecording(const std::string& filename);
|
||||||
|
void DoState(PointerWrap& p);
|
||||||
|
void Shutdown();
|
||||||
|
void CheckPadStatus(const GCPadStatus* PadStatus, int controllerID);
|
||||||
|
void CheckWiimoteStatus(int wiimote, const WiimoteCommon::DataReportBuilder& rpt,
|
||||||
|
WiimoteEmu::ExtensionNumber ext, const WiimoteEmu::EncryptionKey& key);
|
||||||
|
|
||||||
|
std::string GetInputDisplay();
|
||||||
|
std::string GetRTCDisplay();
|
||||||
|
std::string GetRerecords();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void GetSettings();
|
||||||
|
void CheckInputEnd();
|
||||||
|
|
||||||
|
void CheckMD5();
|
||||||
|
void GetMD5();
|
||||||
|
|
||||||
|
bool m_read_only = true;
|
||||||
|
u32 m_rerecords = 0;
|
||||||
|
PlayMode m_play_mode = PlayMode::None;
|
||||||
|
|
||||||
|
std::array<ControllerType, 4> m_controllers{};
|
||||||
|
std::array<bool, 4> m_wiimotes{};
|
||||||
|
ControllerState m_pad_state{};
|
||||||
|
DTMHeader m_temp_header{};
|
||||||
|
std::vector<u8> m_temp_input;
|
||||||
|
u64 m_current_byte = 0;
|
||||||
|
u64 m_current_frame = 0;
|
||||||
|
u64 m_total_frames = 0; // VI
|
||||||
|
u64 m_current_lag_count = 0;
|
||||||
|
u64 m_total_lag_count = 0;
|
||||||
|
u64 m_current_input_count = 0;
|
||||||
|
u64 m_total_input_count = 0;
|
||||||
|
u64 m_total_tick_count = 0;
|
||||||
|
u64 m_tick_count_at_last_input = 0;
|
||||||
|
u64 m_recording_start_time = 0; // seconds since 1970 that recording started
|
||||||
|
bool m_save_config = false;
|
||||||
|
bool m_net_play = false;
|
||||||
|
bool m_clear_save = false;
|
||||||
|
bool m_has_disc_change = false;
|
||||||
|
bool m_reset = false;
|
||||||
|
std::string m_author;
|
||||||
|
std::string m_disc_change_filename;
|
||||||
|
std::array<u8, 16> m_md5{};
|
||||||
|
u8 m_bongos = 0;
|
||||||
|
u8 m_memcards = 0;
|
||||||
|
std::array<u8, 20> m_revision{};
|
||||||
|
u32 m_dsp_irom_hash = 0;
|
||||||
|
u32 m_dsp_coef_hash = 0;
|
||||||
|
|
||||||
|
bool m_recording_from_save_state = false;
|
||||||
|
bool m_polled = false;
|
||||||
|
|
||||||
|
std::string m_current_file_name;
|
||||||
|
|
||||||
|
// m_input_display is used by both CPU and GPU (is mutable).
|
||||||
|
std::mutex m_input_display_lock;
|
||||||
|
std::array<std::string, 8> m_input_display;
|
||||||
|
|
||||||
|
Core::System& m_system;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace Movie
|
} // namespace Movie
|
||||||
|
|
|
@ -1763,8 +1763,9 @@ bool NetPlayClient::StartGame(const std::string& path)
|
||||||
|
|
||||||
if (m_dialog->IsRecording())
|
if (m_dialog->IsRecording())
|
||||||
{
|
{
|
||||||
if (Movie::IsReadOnly())
|
auto& movie = Core::System::GetInstance().GetMovie();
|
||||||
Movie::SetReadOnly(false);
|
if (movie.IsReadOnly())
|
||||||
|
movie.SetReadOnly(false);
|
||||||
|
|
||||||
Movie::ControllerTypeArray controllers{};
|
Movie::ControllerTypeArray controllers{};
|
||||||
Movie::WiimoteEnabledArray wiimotes{};
|
Movie::WiimoteEnabledArray wiimotes{};
|
||||||
|
@ -1778,7 +1779,7 @@ bool NetPlayClient::StartGame(const std::string& path)
|
||||||
controllers[i] = Movie::ControllerType::None;
|
controllers[i] = Movie::ControllerType::None;
|
||||||
wiimotes[i] = m_wiimote_map[i] > 0;
|
wiimotes[i] = m_wiimote_map[i] > 0;
|
||||||
}
|
}
|
||||||
Movie::BeginRecordingInput(controllers, wiimotes);
|
movie.BeginRecordingInput(controllers, wiimotes);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < 4; ++i)
|
for (unsigned int i = 0; i < 4; ++i)
|
||||||
|
@ -2114,14 +2115,15 @@ bool NetPlayClient::GetNetPads(const int pad_nb, const bool batching, GCPadStatu
|
||||||
|
|
||||||
m_pad_buffer[pad_nb].Pop(*pad_status);
|
m_pad_buffer[pad_nb].Pop(*pad_status);
|
||||||
|
|
||||||
if (Movie::IsRecordingInput())
|
auto& movie = Core::System::GetInstance().GetMovie();
|
||||||
|
if (movie.IsRecordingInput())
|
||||||
{
|
{
|
||||||
Movie::RecordInput(pad_status, pad_nb);
|
movie.RecordInput(pad_status, pad_nb);
|
||||||
Movie::InputUpdate();
|
movie.InputUpdate();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Movie::CheckPadStatus(pad_status, pad_nb);
|
movie.CheckPadStatus(pad_status, pad_nb);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -171,7 +171,7 @@ static void DoState(PointerWrap& p)
|
||||||
|
|
||||||
// Movie must be done before the video backend, because the window is redrawn in the video backend
|
// Movie must be done before the video backend, because the window is redrawn in the video backend
|
||||||
// state load, and the frame number must be up-to-date.
|
// state load, and the frame number must be up-to-date.
|
||||||
Movie::DoState(p);
|
system.GetMovie().DoState(p);
|
||||||
p.DoMarker("Movie");
|
p.DoMarker("Movie");
|
||||||
|
|
||||||
// Begin with video backend, so that it gets a chance to clear its caches and writeback modified
|
// Begin with video backend, so that it gets a chance to clear its caches and writeback modified
|
||||||
|
@ -443,9 +443,10 @@ static void CompressAndDumpState(CompressAndDumpState_args& save_args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((Movie::IsMovieActive()) && !Movie::IsJustStartingRecordingInputFromSaveState())
|
auto& movie = Core::System::GetInstance().GetMovie();
|
||||||
Movie::SaveRecording(dtmname);
|
if ((movie.IsMovieActive()) && !movie.IsJustStartingRecordingInputFromSaveState())
|
||||||
else if (!Movie::IsMovieActive())
|
movie.SaveRecording(dtmname);
|
||||||
|
else if (!movie.IsMovieActive())
|
||||||
File::Delete(dtmname);
|
File::Delete(dtmname);
|
||||||
|
|
||||||
// Move written state to final location.
|
// Move written state to final location.
|
||||||
|
@ -867,13 +868,14 @@ void LoadAs(const std::string& filename)
|
||||||
Core::RunOnCPUThread(
|
Core::RunOnCPUThread(
|
||||||
[&] {
|
[&] {
|
||||||
// Save temp buffer for undo load state
|
// Save temp buffer for undo load state
|
||||||
if (!Movie::IsJustStartingRecordingInputFromSaveState())
|
auto& movie = Core::System::GetInstance().GetMovie();
|
||||||
|
if (!movie.IsJustStartingRecordingInputFromSaveState())
|
||||||
{
|
{
|
||||||
std::lock_guard lk2(s_undo_load_buffer_mutex);
|
std::lock_guard lk2(s_undo_load_buffer_mutex);
|
||||||
SaveToBuffer(s_undo_load_buffer);
|
SaveToBuffer(s_undo_load_buffer);
|
||||||
const std::string dtmpath = File::GetUserPath(D_STATESAVES_IDX) + "undo.dtm";
|
const std::string dtmpath = File::GetUserPath(D_STATESAVES_IDX) + "undo.dtm";
|
||||||
if (Movie::IsMovieActive())
|
if (movie.IsMovieActive())
|
||||||
Movie::SaveRecording(dtmpath);
|
movie.SaveRecording(dtmpath);
|
||||||
else if (File::Exists(dtmpath))
|
else if (File::Exists(dtmpath))
|
||||||
File::Delete(dtmpath);
|
File::Delete(dtmpath);
|
||||||
}
|
}
|
||||||
|
@ -904,10 +906,10 @@ void LoadAs(const std::string& filename)
|
||||||
Core::DisplayMessage(
|
Core::DisplayMessage(
|
||||||
fmt::format("Loaded State from {}", tempfilename.filename().string()), 2000);
|
fmt::format("Loaded State from {}", tempfilename.filename().string()), 2000);
|
||||||
if (File::Exists(filename + ".dtm"))
|
if (File::Exists(filename + ".dtm"))
|
||||||
Movie::LoadInput(filename + ".dtm");
|
movie.LoadInput(filename + ".dtm");
|
||||||
else if (!Movie::IsJustStartingRecordingInputFromSaveState() &&
|
else if (!movie.IsJustStartingRecordingInputFromSaveState() &&
|
||||||
!Movie::IsJustStartingPlayingInputFromSaveState())
|
!movie.IsJustStartingPlayingInputFromSaveState())
|
||||||
Movie::EndPlayInput(false);
|
movie.EndPlayInput(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1015,13 +1017,14 @@ void UndoLoadState()
|
||||||
std::lock_guard lk(s_undo_load_buffer_mutex);
|
std::lock_guard lk(s_undo_load_buffer_mutex);
|
||||||
if (!s_undo_load_buffer.empty())
|
if (!s_undo_load_buffer.empty())
|
||||||
{
|
{
|
||||||
if (Movie::IsMovieActive())
|
auto& movie = Core::System::GetInstance().GetMovie();
|
||||||
|
if (movie.IsMovieActive())
|
||||||
{
|
{
|
||||||
const std::string dtmpath = File::GetUserPath(D_STATESAVES_IDX) + "undo.dtm";
|
const std::string dtmpath = File::GetUserPath(D_STATESAVES_IDX) + "undo.dtm";
|
||||||
if (File::Exists(dtmpath))
|
if (File::Exists(dtmpath))
|
||||||
{
|
{
|
||||||
LoadFromBuffer(s_undo_load_buffer);
|
LoadFromBuffer(s_undo_load_buffer);
|
||||||
Movie::LoadInput(dtmpath);
|
movie.LoadInput(dtmpath);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "Core/HW/SystemTimers.h"
|
#include "Core/HW/SystemTimers.h"
|
||||||
#include "Core/HW/VideoInterface.h"
|
#include "Core/HW/VideoInterface.h"
|
||||||
#include "Core/HW/WII_IPC.h"
|
#include "Core/HW/WII_IPC.h"
|
||||||
|
#include "Core/Movie.h"
|
||||||
#include "Core/PowerPC/Interpreter/Interpreter.h"
|
#include "Core/PowerPC/Interpreter/Interpreter.h"
|
||||||
#include "Core/PowerPC/JitInterface.h"
|
#include "Core/PowerPC/JitInterface.h"
|
||||||
#include "Core/PowerPC/PowerPC.h"
|
#include "Core/PowerPC/PowerPC.h"
|
||||||
|
@ -52,7 +53,7 @@ struct System::Impl
|
||||||
m_mmu(system, m_memory, m_power_pc), m_processor_interface(system),
|
m_mmu(system, m_memory, m_power_pc), m_processor_interface(system),
|
||||||
m_serial_interface(system), m_system_timers(system), m_video_interface(system),
|
m_serial_interface(system), m_system_timers(system), m_video_interface(system),
|
||||||
m_interpreter(system, m_power_pc.GetPPCState(), m_mmu), m_jit_interface(system),
|
m_interpreter(system, m_power_pc.GetPPCState(), m_mmu), m_jit_interface(system),
|
||||||
m_fifo_player(system), m_fifo_recorder(system)
|
m_fifo_player(system), m_fifo_recorder(system), m_movie(system)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,6 +94,7 @@ struct System::Impl
|
||||||
VideoCommon::CustomAssetLoader m_custom_asset_loader;
|
VideoCommon::CustomAssetLoader m_custom_asset_loader;
|
||||||
FifoPlayer m_fifo_player;
|
FifoPlayer m_fifo_player;
|
||||||
FifoRecorder m_fifo_recorder;
|
FifoRecorder m_fifo_recorder;
|
||||||
|
Movie::MovieManager m_movie;
|
||||||
};
|
};
|
||||||
|
|
||||||
System::System() : m_impl{std::make_unique<Impl>(*this)}
|
System::System() : m_impl{std::make_unique<Impl>(*this)}
|
||||||
|
@ -248,6 +250,11 @@ PowerPC::MMU& System::GetMMU() const
|
||||||
return m_impl->m_mmu;
|
return m_impl->m_mmu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Movie::MovieManager& System::GetMovie() const
|
||||||
|
{
|
||||||
|
return m_impl->m_movie;
|
||||||
|
}
|
||||||
|
|
||||||
PixelEngine::PixelEngineManager& System::GetPixelEngine() const
|
PixelEngine::PixelEngineManager& System::GetPixelEngine() const
|
||||||
{
|
{
|
||||||
return m_impl->m_pixel_engine;
|
return m_impl->m_pixel_engine;
|
||||||
|
|
|
@ -74,6 +74,10 @@ namespace MemoryInterface
|
||||||
{
|
{
|
||||||
class MemoryInterfaceManager;
|
class MemoryInterfaceManager;
|
||||||
};
|
};
|
||||||
|
namespace Movie
|
||||||
|
{
|
||||||
|
class MovieManager;
|
||||||
|
}
|
||||||
namespace PixelEngine
|
namespace PixelEngine
|
||||||
{
|
{
|
||||||
class PixelEngineManager;
|
class PixelEngineManager;
|
||||||
|
@ -161,6 +165,7 @@ public:
|
||||||
Memory::MemoryManager& GetMemory() const;
|
Memory::MemoryManager& GetMemory() const;
|
||||||
MemoryInterface::MemoryInterfaceManager& GetMemoryInterface() const;
|
MemoryInterface::MemoryInterfaceManager& GetMemoryInterface() const;
|
||||||
PowerPC::MMU& GetMMU() const;
|
PowerPC::MMU& GetMMU() const;
|
||||||
|
Movie::MovieManager& GetMovie() const;
|
||||||
PixelEngine::PixelEngineManager& GetPixelEngine() const;
|
PixelEngine::PixelEngineManager& GetPixelEngine() const;
|
||||||
PixelShaderManager& GetPixelShaderManager() const;
|
PixelShaderManager& GetPixelShaderManager() const;
|
||||||
PowerPC::PowerPCManager& GetPowerPC() const;
|
PowerPC::PowerPCManager& GetPowerPC() const;
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "Core/Movie.h"
|
#include "Core/Movie.h"
|
||||||
#include "Core/NetPlayClient.h"
|
#include "Core/NetPlayClient.h"
|
||||||
#include "Core/SysConf.h"
|
#include "Core/SysConf.h"
|
||||||
|
#include "Core/System.h"
|
||||||
|
|
||||||
namespace Core
|
namespace Core
|
||||||
{
|
{
|
||||||
|
@ -127,24 +128,25 @@ static bool CopyNandFile(FS::FileSystem* source_fs, const std::string& source_fi
|
||||||
static void InitializeDeterministicWiiSaves(FS::FileSystem* session_fs,
|
static void InitializeDeterministicWiiSaves(FS::FileSystem* session_fs,
|
||||||
const BootSessionData& boot_session_data)
|
const BootSessionData& boot_session_data)
|
||||||
{
|
{
|
||||||
|
auto& movie = Core::System::GetInstance().GetMovie();
|
||||||
const u64 title_id = SConfig::GetInstance().GetTitleID();
|
const u64 title_id = SConfig::GetInstance().GetTitleID();
|
||||||
const auto configured_fs = FS::MakeFileSystem(FS::Location::Configured);
|
const auto configured_fs = FS::MakeFileSystem(FS::Location::Configured);
|
||||||
if (Movie::IsRecordingInput())
|
if (movie.IsRecordingInput())
|
||||||
{
|
{
|
||||||
if (NetPlay::IsNetPlayRunning() && !SConfig::GetInstance().bCopyWiiSaveNetplay)
|
if (NetPlay::IsNetPlayRunning() && !SConfig::GetInstance().bCopyWiiSaveNetplay)
|
||||||
{
|
{
|
||||||
Movie::SetClearSave(true);
|
movie.SetClearSave(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TODO: Check for the actual save data
|
// TODO: Check for the actual save data
|
||||||
const std::string path = Common::GetTitleDataPath(title_id) + "/banner.bin";
|
const std::string path = Common::GetTitleDataPath(title_id) + "/banner.bin";
|
||||||
Movie::SetClearSave(!configured_fs->GetMetadata(IOS::PID_KERNEL, IOS::PID_KERNEL, path));
|
movie.SetClearSave(!configured_fs->GetMetadata(IOS::PID_KERNEL, IOS::PID_KERNEL, path));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((NetPlay::IsNetPlayRunning() && SConfig::GetInstance().bCopyWiiSaveNetplay) ||
|
if ((NetPlay::IsNetPlayRunning() && SConfig::GetInstance().bCopyWiiSaveNetplay) ||
|
||||||
(Movie::IsMovieActive() && !Movie::IsStartingFromClearSave()))
|
(movie.IsMovieActive() && !movie.IsStartingFromClearSave()))
|
||||||
{
|
{
|
||||||
auto* sync_fs = boot_session_data.GetWiiSyncFS();
|
auto* sync_fs = boot_session_data.GetWiiSyncFS();
|
||||||
auto& sync_titles = boot_session_data.GetWiiSyncTitles();
|
auto& sync_titles = boot_session_data.GetWiiSyncTitles();
|
||||||
|
@ -154,7 +156,7 @@ static void InitializeDeterministicWiiSaves(FS::FileSystem* session_fs,
|
||||||
sync_fs ? "sync_fs" : "configured_fs");
|
sync_fs ? "sync_fs" : "configured_fs");
|
||||||
|
|
||||||
// Copy the current user's save to the Blank NAND
|
// Copy the current user's save to the Blank NAND
|
||||||
if (Movie::IsMovieActive() && !NetPlay::IsNetPlayRunning())
|
if (movie.IsMovieActive() && !NetPlay::IsNetPlayRunning())
|
||||||
{
|
{
|
||||||
INFO_LOG_FMT(CORE, "Wii Save Init: Copying {0:016x}.", title_id);
|
INFO_LOG_FMT(CORE, "Wii Save Init: Copying {0:016x}.", title_id);
|
||||||
CopySave(source_fs, session_fs, title_id);
|
CopySave(source_fs, session_fs, title_id);
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "Core/Config/MainSettings.h"
|
#include "Core/Config/MainSettings.h"
|
||||||
#include "Core/Core.h"
|
#include "Core/Core.h"
|
||||||
#include "Core/Movie.h"
|
#include "Core/Movie.h"
|
||||||
|
#include "Core/System.h"
|
||||||
|
|
||||||
#include "DolphinQt/Config/ControllerInterface/ControllerInterfaceWindow.h"
|
#include "DolphinQt/Config/ControllerInterface/ControllerInterfaceWindow.h"
|
||||||
#include "DolphinQt/Config/ToolTipControls/ToolTipCheckBox.h"
|
#include "DolphinQt/Config/ToolTipControls/ToolTipCheckBox.h"
|
||||||
|
@ -197,9 +198,9 @@ void AchievementSettingsWidget::LoadSettings()
|
||||||
SignalBlocking(m_common_hardcore_enabled_input)
|
SignalBlocking(m_common_hardcore_enabled_input)
|
||||||
->setChecked(Config::Get(Config::RA_HARDCORE_ENABLED));
|
->setChecked(Config::Get(Config::RA_HARDCORE_ENABLED));
|
||||||
SignalBlocking(m_common_hardcore_enabled_input)
|
SignalBlocking(m_common_hardcore_enabled_input)
|
||||||
->setEnabled(enabled &&
|
->setEnabled(enabled && (hardcore_enabled ||
|
||||||
(hardcore_enabled ||
|
(Core::GetState() == Core::State::Uninitialized &&
|
||||||
(Core::GetState() == Core::State::Uninitialized && !Movie::IsPlayingInput())));
|
!Core::System::GetInstance().GetMovie().IsPlayingInput())));
|
||||||
|
|
||||||
SignalBlocking(m_common_progress_enabled_input)
|
SignalBlocking(m_common_progress_enabled_input)
|
||||||
->setChecked(Config::Get(Config::RA_PROGRESS_ENABLED));
|
->setChecked(Config::Get(Config::RA_PROGRESS_ENABLED));
|
||||||
|
|
|
@ -365,7 +365,7 @@ void GBAWidget::SaveSettings()
|
||||||
|
|
||||||
bool GBAWidget::CanControlCore()
|
bool GBAWidget::CanControlCore()
|
||||||
{
|
{
|
||||||
return !Movie::IsMovieActive() && !NetPlay::IsNetPlayRunning();
|
return !Core::System::GetInstance().GetMovie().IsMovieActive() && !NetPlay::IsNetPlayRunning();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GBAWidget::CanResetCore()
|
bool GBAWidget::CanResetCore()
|
||||||
|
|
|
@ -277,7 +277,7 @@ MainWindow::MainWindow(std::unique_ptr<BootParameters> boot_parameters,
|
||||||
if (!movie_path.empty())
|
if (!movie_path.empty())
|
||||||
{
|
{
|
||||||
std::optional<std::string> savestate_path;
|
std::optional<std::string> savestate_path;
|
||||||
if (Movie::PlayInput(movie_path, &savestate_path))
|
if (Core::System::GetInstance().GetMovie().PlayInput(movie_path, &savestate_path))
|
||||||
{
|
{
|
||||||
m_pending_boot->boot_session_data.SetSavestateData(std::move(savestate_path),
|
m_pending_boot->boot_session_data.SetSavestateData(std::move(savestate_path),
|
||||||
DeleteSavestateAfterBoot::No);
|
DeleteSavestateAfterBoot::No);
|
||||||
|
@ -646,8 +646,9 @@ void MainWindow::ConnectHotkeys()
|
||||||
connect(m_hotkey_scheduler, &HotkeyScheduler::ConnectWiiRemote, this,
|
connect(m_hotkey_scheduler, &HotkeyScheduler::ConnectWiiRemote, this,
|
||||||
&MainWindow::OnConnectWiiRemote);
|
&MainWindow::OnConnectWiiRemote);
|
||||||
connect(m_hotkey_scheduler, &HotkeyScheduler::ToggleReadOnlyMode, [this] {
|
connect(m_hotkey_scheduler, &HotkeyScheduler::ToggleReadOnlyMode, [this] {
|
||||||
bool read_only = !Movie::IsReadOnly();
|
auto& movie = Core::System::GetInstance().GetMovie();
|
||||||
Movie::SetReadOnly(read_only);
|
bool read_only = !movie.IsReadOnly();
|
||||||
|
movie.SetReadOnly(read_only);
|
||||||
emit ReadOnlyModeChanged(read_only);
|
emit ReadOnlyModeChanged(read_only);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1011,9 +1012,10 @@ void MainWindow::ForceStop()
|
||||||
|
|
||||||
void MainWindow::Reset()
|
void MainWindow::Reset()
|
||||||
{
|
{
|
||||||
if (Movie::IsRecordingInput())
|
|
||||||
Movie::SetReset(true);
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = Core::System::GetInstance();
|
||||||
|
auto& movie = system.GetMovie();
|
||||||
|
if (movie.IsRecordingInput())
|
||||||
|
movie.SetReset(true);
|
||||||
system.GetProcessorInterface().ResetButton_Tap();
|
system.GetProcessorInterface().ResetButton_Tap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1853,15 +1855,16 @@ void MainWindow::OnPlayRecording()
|
||||||
if (dtm_file.isEmpty())
|
if (dtm_file.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!Movie::IsReadOnly())
|
auto& movie = Core::System::GetInstance().GetMovie();
|
||||||
|
if (!movie.IsReadOnly())
|
||||||
{
|
{
|
||||||
// let's make the read-only flag consistent at the start of a movie.
|
// let's make the read-only flag consistent at the start of a movie.
|
||||||
Movie::SetReadOnly(true);
|
movie.SetReadOnly(true);
|
||||||
emit ReadOnlyModeChanged(true);
|
emit ReadOnlyModeChanged(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::string> savestate_path;
|
std::optional<std::string> savestate_path;
|
||||||
if (Movie::PlayInput(dtm_file.toStdString(), &savestate_path))
|
if (movie.PlayInput(dtm_file.toStdString(), &savestate_path))
|
||||||
{
|
{
|
||||||
emit RecordingStatusChanged(true);
|
emit RecordingStatusChanged(true);
|
||||||
|
|
||||||
|
@ -1871,14 +1874,17 @@ void MainWindow::OnPlayRecording()
|
||||||
|
|
||||||
void MainWindow::OnStartRecording()
|
void MainWindow::OnStartRecording()
|
||||||
{
|
{
|
||||||
if ((!Core::IsRunningAndStarted() && Core::IsRunning()) || Movie::IsRecordingInput() ||
|
auto& movie = Core::System::GetInstance().GetMovie();
|
||||||
Movie::IsPlayingInput())
|
if ((!Core::IsRunningAndStarted() && Core::IsRunning()) || movie.IsRecordingInput() ||
|
||||||
|
movie.IsPlayingInput())
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (Movie::IsReadOnly())
|
if (movie.IsReadOnly())
|
||||||
{
|
{
|
||||||
// The user just chose to record a movie, so that should take precedence
|
// The user just chose to record a movie, so that should take precedence
|
||||||
Movie::SetReadOnly(false);
|
movie.SetReadOnly(false);
|
||||||
emit ReadOnlyModeChanged(true);
|
emit ReadOnlyModeChanged(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1897,7 +1903,7 @@ void MainWindow::OnStartRecording()
|
||||||
wiimotes[i] = Config::Get(Config::GetInfoForWiimoteSource(i)) != WiimoteSource::None;
|
wiimotes[i] = Config::Get(Config::GetInfoForWiimoteSource(i)) != WiimoteSource::None;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Movie::BeginRecordingInput(controllers, wiimotes))
|
if (movie.BeginRecordingInput(controllers, wiimotes))
|
||||||
{
|
{
|
||||||
emit RecordingStatusChanged(true);
|
emit RecordingStatusChanged(true);
|
||||||
|
|
||||||
|
@ -1908,10 +1914,11 @@ void MainWindow::OnStartRecording()
|
||||||
|
|
||||||
void MainWindow::OnStopRecording()
|
void MainWindow::OnStopRecording()
|
||||||
{
|
{
|
||||||
if (Movie::IsRecordingInput())
|
auto& movie = Core::System::GetInstance().GetMovie();
|
||||||
|
if (movie.IsRecordingInput())
|
||||||
OnExportRecording();
|
OnExportRecording();
|
||||||
if (Movie::IsMovieActive())
|
if (movie.IsMovieActive())
|
||||||
Movie::EndPlayInput(false);
|
movie.EndPlayInput(false);
|
||||||
emit RecordingStatusChanged(false);
|
emit RecordingStatusChanged(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1921,7 +1928,7 @@ void MainWindow::OnExportRecording()
|
||||||
QString dtm_file = DolphinFileDialog::getSaveFileName(
|
QString dtm_file = DolphinFileDialog::getSaveFileName(
|
||||||
this, tr("Save Recording File As"), QString(), tr("Dolphin TAS Movies (*.dtm)"));
|
this, tr("Save Recording File As"), QString(), tr("Dolphin TAS Movies (*.dtm)"));
|
||||||
if (!dtm_file.isEmpty())
|
if (!dtm_file.isEmpty())
|
||||||
Movie::SaveRecording(dtm_file.toStdString());
|
Core::System::GetInstance().GetMovie().SaveRecording(dtm_file.toStdString());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -146,7 +146,8 @@ void MenuBar::OnEmulationStateChanged(Core::State state)
|
||||||
#else // USE_RETRO_ACHIEVEMENTS
|
#else // USE_RETRO_ACHIEVEMENTS
|
||||||
m_recording_play->setEnabled(m_game_selected && !running);
|
m_recording_play->setEnabled(m_game_selected && !running);
|
||||||
#endif // USE_RETRO_ACHIEVEMENTS
|
#endif // USE_RETRO_ACHIEVEMENTS
|
||||||
m_recording_start->setEnabled((m_game_selected || running) && !Movie::IsPlayingInput());
|
m_recording_start->setEnabled((m_game_selected || running) &&
|
||||||
|
!Core::System::GetInstance().GetMovie().IsPlayingInput());
|
||||||
|
|
||||||
// JIT
|
// JIT
|
||||||
m_jit_interpreter_core->setEnabled(running);
|
m_jit_interpreter_core->setEnabled(running);
|
||||||
|
@ -775,8 +776,9 @@ void MenuBar::AddMovieMenu()
|
||||||
|
|
||||||
m_recording_read_only = movie_menu->addAction(tr("&Read-Only Mode"));
|
m_recording_read_only = movie_menu->addAction(tr("&Read-Only Mode"));
|
||||||
m_recording_read_only->setCheckable(true);
|
m_recording_read_only->setCheckable(true);
|
||||||
m_recording_read_only->setChecked(Movie::IsReadOnly());
|
m_recording_read_only->setChecked(Core::System::GetInstance().GetMovie().IsReadOnly());
|
||||||
connect(m_recording_read_only, &QAction::toggled, [](bool value) { Movie::SetReadOnly(value); });
|
connect(m_recording_read_only, &QAction::toggled,
|
||||||
|
[](bool value) { Core::System::GetInstance().GetMovie().SetReadOnly(value); });
|
||||||
|
|
||||||
movie_menu->addAction(tr("TAS Input"), this, [this] { emit ShowTASInput(); });
|
movie_menu->addAction(tr("TAS Input"), this, [this] { emit ShowTASInput(); });
|
||||||
|
|
||||||
|
@ -1231,7 +1233,8 @@ void MenuBar::OnSelectionChanged(std::shared_ptr<const UICommon::GameFile> game_
|
||||||
m_game_selected = !!game_file;
|
m_game_selected = !!game_file;
|
||||||
|
|
||||||
m_recording_play->setEnabled(m_game_selected && !Core::IsRunning());
|
m_recording_play->setEnabled(m_game_selected && !Core::IsRunning());
|
||||||
m_recording_start->setEnabled((m_game_selected || Core::IsRunning()) && !Movie::IsPlayingInput());
|
m_recording_start->setEnabled((m_game_selected || Core::IsRunning()) &&
|
||||||
|
!Core::System::GetInstance().GetMovie().IsPlayingInput());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuBar::OnRecordingStatusChanged(bool recording)
|
void MenuBar::OnRecordingStatusChanged(bool recording)
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
|
|
||||||
#include "Core/Movie.h"
|
#include "Core/Movie.h"
|
||||||
|
#include "Core/System.h"
|
||||||
#include "DolphinQt/QtUtils/QueueOnObject.h"
|
#include "DolphinQt/QtUtils/QueueOnObject.h"
|
||||||
#include "DolphinQt/TAS/TASInputWindow.h"
|
#include "DolphinQt/TAS/TASInputWindow.h"
|
||||||
|
|
||||||
|
@ -23,7 +24,8 @@ bool TASCheckBox::GetValue() const
|
||||||
|
|
||||||
if (check_state == Qt::PartiallyChecked)
|
if (check_state == Qt::PartiallyChecked)
|
||||||
{
|
{
|
||||||
const u64 frames_elapsed = Movie::GetCurrentFrame() - m_frame_turbo_started;
|
const u64 frames_elapsed =
|
||||||
|
Core::System::GetInstance().GetMovie().GetCurrentFrame() - m_frame_turbo_started;
|
||||||
return static_cast<int>(frames_elapsed % m_turbo_total_frames) < m_turbo_press_frames;
|
return static_cast<int>(frames_elapsed % m_turbo_total_frames) < m_turbo_press_frames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +52,7 @@ void TASCheckBox::mousePressEvent(QMouseEvent* event)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_frame_turbo_started = Movie::GetCurrentFrame();
|
m_frame_turbo_started = Core::System::GetInstance().GetMovie().GetCurrentFrame();
|
||||||
m_turbo_press_frames = m_parent->GetTurboPressFrames();
|
m_turbo_press_frames = m_parent->GetTurboPressFrames();
|
||||||
m_turbo_total_frames = m_turbo_press_frames + m_parent->GetTurboReleaseFrames();
|
m_turbo_total_frames = m_turbo_press_frames + m_parent->GetTurboReleaseFrames();
|
||||||
setCheckState(Qt::PartiallyChecked);
|
setCheckState(Qt::PartiallyChecked);
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "Core/Config/MainSettings.h"
|
#include "Core/Config/MainSettings.h"
|
||||||
#include "Core/Config/NetplaySettings.h"
|
#include "Core/Config/NetplaySettings.h"
|
||||||
#include "Core/Movie.h"
|
#include "Core/Movie.h"
|
||||||
|
#include "Core/System.h"
|
||||||
|
|
||||||
#include "VideoCommon/AbstractGfx.h"
|
#include "VideoCommon/AbstractGfx.h"
|
||||||
#include "VideoCommon/AbstractPipeline.h"
|
#include "VideoCommon/AbstractPipeline.h"
|
||||||
|
@ -284,26 +285,27 @@ void OnScreenUI::DrawDebugText()
|
||||||
ImGui::GetIO().DisplaySize);
|
ImGui::GetIO().DisplaySize);
|
||||||
if (ImGui::Begin("Movie", nullptr, ImGuiWindowFlags_NoFocusOnAppearing))
|
if (ImGui::Begin("Movie", nullptr, ImGuiWindowFlags_NoFocusOnAppearing))
|
||||||
{
|
{
|
||||||
if (Movie::IsPlayingInput())
|
auto& movie = Core::System::GetInstance().GetMovie();
|
||||||
|
if (movie.IsPlayingInput())
|
||||||
{
|
{
|
||||||
ImGui::Text("Frame: %" PRIu64 " / %" PRIu64, Movie::GetCurrentFrame(),
|
ImGui::Text("Frame: %" PRIu64 " / %" PRIu64, movie.GetCurrentFrame(),
|
||||||
Movie::GetTotalFrames());
|
movie.GetTotalFrames());
|
||||||
ImGui::Text("Input: %" PRIu64 " / %" PRIu64, Movie::GetCurrentInputCount(),
|
ImGui::Text("Input: %" PRIu64 " / %" PRIu64, movie.GetCurrentInputCount(),
|
||||||
Movie::GetTotalInputCount());
|
movie.GetTotalInputCount());
|
||||||
}
|
}
|
||||||
else if (Config::Get(Config::MAIN_SHOW_FRAME_COUNT))
|
else if (Config::Get(Config::MAIN_SHOW_FRAME_COUNT))
|
||||||
{
|
{
|
||||||
ImGui::Text("Frame: %" PRIu64, Movie::GetCurrentFrame());
|
ImGui::Text("Frame: %" PRIu64, movie.GetCurrentFrame());
|
||||||
ImGui::Text("Input: %" PRIu64, Movie::GetCurrentInputCount());
|
ImGui::Text("Input: %" PRIu64, movie.GetCurrentInputCount());
|
||||||
}
|
}
|
||||||
if (Config::Get(Config::MAIN_SHOW_LAG))
|
if (Config::Get(Config::MAIN_SHOW_LAG))
|
||||||
ImGui::Text("Lag: %" PRIu64 "\n", Movie::GetCurrentLagCount());
|
ImGui::Text("Lag: %" PRIu64 "\n", movie.GetCurrentLagCount());
|
||||||
if (Config::Get(Config::MAIN_MOVIE_SHOW_INPUT_DISPLAY))
|
if (Config::Get(Config::MAIN_MOVIE_SHOW_INPUT_DISPLAY))
|
||||||
ImGui::TextUnformatted(Movie::GetInputDisplay().c_str());
|
ImGui::TextUnformatted(movie.GetInputDisplay().c_str());
|
||||||
if (Config::Get(Config::MAIN_MOVIE_SHOW_RTC))
|
if (Config::Get(Config::MAIN_MOVIE_SHOW_RTC))
|
||||||
ImGui::TextUnformatted(Movie::GetRTCDisplay().c_str());
|
ImGui::TextUnformatted(movie.GetRTCDisplay().c_str());
|
||||||
if (Config::Get(Config::MAIN_MOVIE_SHOW_RERECORD))
|
if (Config::Get(Config::MAIN_MOVIE_SHOW_RERECORD))
|
||||||
ImGui::TextUnformatted(Movie::GetRerecords().c_str());
|
ImGui::TextUnformatted(movie.GetRerecords().c_str());
|
||||||
}
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,8 +47,9 @@ static bool IsVSyncActive(bool enabled)
|
||||||
|
|
||||||
void UpdateActiveConfig()
|
void UpdateActiveConfig()
|
||||||
{
|
{
|
||||||
if (Movie::IsPlayingInput() && Movie::IsConfigSaved())
|
auto& movie = Core::System::GetInstance().GetMovie();
|
||||||
Movie::SetGraphicsConfig();
|
if (movie.IsPlayingInput() && movie.IsConfigSaved())
|
||||||
|
movie.SetGraphicsConfig();
|
||||||
g_ActiveConfig = g_Config;
|
g_ActiveConfig = g_Config;
|
||||||
g_ActiveConfig.bVSyncActive = IsVSyncActive(g_ActiveConfig.bVSync);
|
g_ActiveConfig.bVSyncActive = IsVSyncActive(g_ActiveConfig.bVSync);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue