Files
dolphin/Source/Core/Core/ConfigLoaders/MovieConfigLoader.cpp
T
JosJuice dcf9ca05db Core: Fix controllers resetting when starting input recording
200e26c added controller handling to MovieConfigLayerLoader's
LoadFromDTM but not SaveToDTM. This caused a regression. When starting a
new input recording, MovieManager::BeginRecordingInput calls SaveToDTM,
which doesn't set the controller values in the DTM header to anything.
Then it loads the newly created movie config layer, causing LoadFromDTM
to be called, which in turn causes zeroed out controller values to be
loaded from the DTM header. This leaves the player with all controllers
set to None, making it impossible to control the game.

To fix this, let's move the saving of controllers from
MovieManager::SaveRecording to ConfigLoaders::SaveToDTM.
2026-08-24 18:45:27 +02:00

167 lines
5.9 KiB
C++

// Copyright 2016 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "Core/ConfigLoaders/MovieConfigLoader.h"
#include <cstring>
#include <memory>
#include <string>
#include "Common/CommonTypes.h"
#include "Common/Config/Config.h"
#include "Core/Config/GraphicsSettings.h"
#include "Core/Config/MainSettings.h"
#include "Core/Config/SYSCONFSettings.h"
#include "Core/Config/SessionSettings.h"
#include "Core/Config/WiimoteSettings.h"
#include "Core/HW/SI/SI.h"
#include "Core/HW/SI/SI_Device.h"
#include "Core/HW/Wiimote.h"
#include "Core/Movie.h"
namespace PowerPC
{
enum class CPUCore;
}
namespace ConfigLoaders
{
static void LoadFromDTM(Config::Layer* config_layer, Movie::DTMHeader* dtm)
{
config_layer->Set(Config::MAIN_CPU_THREAD, dtm->bDualCore);
config_layer->Set(Config::MAIN_DSP_HLE, dtm->bDSPHLE);
config_layer->Set(Config::MAIN_FAST_DISC_SPEED, dtm->bFastDiscSpeed);
config_layer->Set(Config::MAIN_CPU_CORE, static_cast<PowerPC::CPUCore>(dtm->CPUCore));
config_layer->Set(Config::MAIN_SYNC_GPU, dtm->bSyncGPU);
config_layer->Set(Config::MAIN_GFX_BACKEND, dtm->videoBackend.data());
config_layer->Set(Config::SYSCONF_PROGRESSIVE_SCAN, dtm->bProgressive);
config_layer->Set(Config::SYSCONF_PAL60, dtm->bPAL60);
if (dtm->bWii)
config_layer->Set(Config::SYSCONF_LANGUAGE, static_cast<u32>(dtm->language));
else
config_layer->Set(Config::MAIN_GC_LANGUAGE, static_cast<int>(dtm->language));
config_layer->Set(Config::SYSCONF_WIDESCREEN, dtm->bWidescreen);
config_layer->Set(Config::SYSCONF_COUNTRY, dtm->countryCode);
config_layer->Set(Config::GFX_HACK_EFB_ACCESS_ENABLE, dtm->bEFBAccessEnable);
config_layer->Set(Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM, dtm->bSkipEFBCopyToRam);
config_layer->Set(Config::GFX_HACK_EFB_EMULATE_FORMAT_CHANGES, dtm->bEFBEmulateFormatChanges);
config_layer->Set(Config::GFX_HACK_IMMEDIATE_XFB, dtm->bImmediateXFB);
config_layer->Set(Config::GFX_HACK_SKIP_XFB_COPY_TO_RAM, dtm->bSkipXFBCopyToRam);
config_layer->Set(Config::SESSION_USE_FMA, dtm->bUseFMA);
config_layer->Set(Config::MAIN_JIT_FOLLOW_BRANCH, dtm->bFollowBranch);
for (int i = 0; i < SerialInterface::MAX_SI_CHANNELS; ++i)
{
SerialInterface::SIDevices device = SerialInterface::SIDEVICE_NONE;
const auto config_info = Config::GetInfoForSIDevice(i);
if (dtm->GBAControllers & (1 << i))
{
device = SerialInterface::SIDEVICE_GC_GBA_EMULATED;
}
else if (dtm->controllers & (1 << i))
{
const SerialInterface::SIDevices si_device = Config::Get(config_info);
if (SerialInterface::SIDevice_IsGCController(si_device))
{
device = si_device;
}
else
{
device = (dtm->bongos & (1 << i)) != 0 ? SerialInterface::SIDEVICE_GC_TARUKONGA :
SerialInterface::SIDEVICE_GC_CONTROLLER;
}
}
config_layer->Set(config_info, device);
}
for (int i = 0; i < MAX_WIIMOTES; ++i)
{
const bool is_using_wiimote = (dtm->controllers & (1 << (i + 4))) != 0;
config_layer->Set(Config::GetInfoForWiimoteSource(i),
is_using_wiimote ? WiimoteSource::Emulated : WiimoteSource::None);
}
}
void SaveToDTM(Movie::DTMHeader* dtm)
{
dtm->bDualCore = Config::Get(Config::MAIN_CPU_THREAD);
dtm->bDSPHLE = Config::Get(Config::MAIN_DSP_HLE);
dtm->bFastDiscSpeed = Config::Get(Config::MAIN_FAST_DISC_SPEED);
dtm->CPUCore = static_cast<u8>(Config::Get(Config::MAIN_CPU_CORE));
dtm->bSyncGPU = Config::Get(Config::MAIN_SYNC_GPU);
const std::string video_backend = Config::Get(Config::MAIN_GFX_BACKEND);
dtm->bProgressive = Config::Get(Config::SYSCONF_PROGRESSIVE_SCAN);
dtm->bPAL60 = Config::Get(Config::SYSCONF_PAL60);
if (dtm->bWii)
dtm->language = Config::Get(Config::SYSCONF_LANGUAGE);
else
dtm->language = Config::Get(Config::MAIN_GC_LANGUAGE);
dtm->bWidescreen = Config::Get(Config::SYSCONF_WIDESCREEN);
dtm->countryCode = Config::Get(Config::SYSCONF_COUNTRY);
dtm->bEFBAccessEnable = Config::Get(Config::GFX_HACK_EFB_ACCESS_ENABLE);
dtm->bSkipEFBCopyToRam = Config::Get(Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM);
dtm->bEFBEmulateFormatChanges = Config::Get(Config::GFX_HACK_EFB_EMULATE_FORMAT_CHANGES);
dtm->bImmediateXFB = Config::Get(Config::GFX_HACK_IMMEDIATE_XFB);
dtm->bSkipXFBCopyToRam = Config::Get(Config::GFX_HACK_SKIP_XFB_COPY_TO_RAM);
dtm->bUseFMA = Config::Get(Config::SESSION_USE_FMA);
dtm->bFollowBranch = Config::Get(Config::MAIN_JIT_FOLLOW_BRANCH);
dtm->controllers = 0;
dtm->bongos = 0;
dtm->GBAControllers = 0;
for (int i = 0; i < SerialInterface::MAX_SI_CHANNELS; ++i)
{
const SerialInterface::SIDevices si_device = Config::Get(Config::GetInfoForSIDevice(i));
if (si_device != SerialInterface::SIDEVICE_NONE)
dtm->controllers |= 1 << i;
if (si_device == SerialInterface::SIDEVICE_GC_GBA_EMULATED)
dtm->GBAControllers |= 1 << i;
else if (si_device == SerialInterface::SIDEVICE_GC_TARUKONGA)
dtm->bongos |= 1 << i;
}
if (dtm->bWii)
{
for (int i = 0; i < MAX_WIIMOTES; ++i)
{
if (Config::Get(Config::GetInfoForWiimoteSource(i)) != WiimoteSource::None)
dtm->controllers |= 1 << (i + 4);
}
}
// Settings which only existed in old Dolphin versions
dtm->bSkipIdle = true;
dtm->bEFBCopyEnable = true;
dtm->bEFBCopyCacheEnable = false;
strncpy(dtm->videoBackend.data(), video_backend.c_str(), dtm->videoBackend.size());
}
// TODO: Future project, let this support all the configuration options.
// This will require a large break to the DTM format
void MovieConfigLayerLoader::Load(Config::Layer* config_layer)
{
LoadFromDTM(config_layer, m_header);
}
void MovieConfigLayerLoader::Save(Config::Layer* config_layer)
{
}
// Loader generation
std::unique_ptr<Config::ConfigLayerLoader> GenerateMovieConfigLoader(Movie::DTMHeader* header)
{
return std::make_unique<MovieConfigLayerLoader>(header);
}
} // namespace ConfigLoaders