Netplay: Simplify save data options.
This commit is contained in:
parent
39314ac162
commit
0d095b4d9b
|
@ -91,7 +91,7 @@ bool BootCore(std::unique_ptr<BootParameters> boot, const WindowSystemInfo& wsi)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Config::AddLayer(ConfigLoaders::GenerateNetPlayConfigLoader(*netplay_settings));
|
Config::AddLayer(ConfigLoaders::GenerateNetPlayConfigLoader(*netplay_settings));
|
||||||
StartUp.bCopyWiiSaveNetplay = netplay_settings->copy_wii_save;
|
StartUp.bCopyWiiSaveNetplay = netplay_settings->savedata_load;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Override out-of-region languages/countries to prevent games from crashing or behaving oddly
|
// Override out-of-region languages/countries to prevent games from crashing or behaving oddly
|
||||||
|
|
|
@ -45,16 +45,15 @@ const Info<u32> NETPLAY_CHUNKED_UPLOAD_LIMIT{{System::Main, "NetPlay", "ChunkedU
|
||||||
const Info<u32> NETPLAY_BUFFER_SIZE{{System::Main, "NetPlay", "BufferSize"}, 5};
|
const Info<u32> NETPLAY_BUFFER_SIZE{{System::Main, "NetPlay", "BufferSize"}, 5};
|
||||||
const Info<u32> NETPLAY_CLIENT_BUFFER_SIZE{{System::Main, "NetPlay", "BufferSizeClient"}, 1};
|
const Info<u32> NETPLAY_CLIENT_BUFFER_SIZE{{System::Main, "NetPlay", "BufferSizeClient"}, 1};
|
||||||
|
|
||||||
const Info<bool> NETPLAY_WRITE_SAVE_DATA{{System::Main, "NetPlay", "WriteSaveData"}, true};
|
const Info<bool> NETPLAY_SAVEDATA_LOAD{{System::Main, "NetPlay", "SyncSaves"}, true};
|
||||||
const Info<bool> NETPLAY_LOAD_WII_SAVE{{System::Main, "NetPlay", "LoadWiiSave"}, false};
|
const Info<bool> NETPLAY_SAVEDATA_WRITE{{System::Main, "NetPlay", "WriteSaveData"}, true};
|
||||||
const Info<bool> NETPLAY_SYNC_SAVES{{System::Main, "NetPlay", "SyncSaves"}, true};
|
const Info<bool> NETPLAY_SAVEDATA_SYNC_ALL_WII{{System::Main, "NetPlay", "SyncAllWiiSaves"}, false};
|
||||||
const Info<bool> NETPLAY_SYNC_CODES{{System::Main, "NetPlay", "SyncCodes"}, true};
|
const Info<bool> NETPLAY_SYNC_CODES{{System::Main, "NetPlay", "SyncCodes"}, true};
|
||||||
const Info<bool> NETPLAY_RECORD_INPUTS{{System::Main, "NetPlay", "RecordInputs"}, false};
|
const Info<bool> NETPLAY_RECORD_INPUTS{{System::Main, "NetPlay", "RecordInputs"}, false};
|
||||||
const Info<bool> NETPLAY_STRICT_SETTINGS_SYNC{{System::Main, "NetPlay", "StrictSettingsSync"},
|
const Info<bool> NETPLAY_STRICT_SETTINGS_SYNC{{System::Main, "NetPlay", "StrictSettingsSync"},
|
||||||
false};
|
false};
|
||||||
const Info<std::string> NETPLAY_NETWORK_MODE{{System::Main, "NetPlay", "NetworkMode"},
|
const Info<std::string> NETPLAY_NETWORK_MODE{{System::Main, "NetPlay", "NetworkMode"},
|
||||||
"fixeddelay"};
|
"fixeddelay"};
|
||||||
const Info<bool> NETPLAY_SYNC_ALL_WII_SAVES{{System::Main, "NetPlay", "SyncAllWiiSaves"}, false};
|
|
||||||
const Info<bool> NETPLAY_GOLF_MODE_OVERLAY{{System::Main, "NetPlay", "GolfModeOverlay"}, true};
|
const Info<bool> NETPLAY_GOLF_MODE_OVERLAY{{System::Main, "NetPlay", "GolfModeOverlay"}, true};
|
||||||
const Info<bool> NETPLAY_HIDE_REMOTE_GBAS{{System::Main, "NetPlay", "HideRemoteGBAs"}, false};
|
const Info<bool> NETPLAY_HIDE_REMOTE_GBAS{{System::Main, "NetPlay", "HideRemoteGBAs"}, false};
|
||||||
|
|
||||||
|
|
|
@ -41,14 +41,13 @@ extern const Info<u32> NETPLAY_CHUNKED_UPLOAD_LIMIT;
|
||||||
extern const Info<u32> NETPLAY_BUFFER_SIZE;
|
extern const Info<u32> NETPLAY_BUFFER_SIZE;
|
||||||
extern const Info<u32> NETPLAY_CLIENT_BUFFER_SIZE;
|
extern const Info<u32> NETPLAY_CLIENT_BUFFER_SIZE;
|
||||||
|
|
||||||
extern const Info<bool> NETPLAY_WRITE_SAVE_DATA;
|
extern const Info<bool> NETPLAY_SAVEDATA_LOAD;
|
||||||
extern const Info<bool> NETPLAY_LOAD_WII_SAVE;
|
extern const Info<bool> NETPLAY_SAVEDATA_WRITE;
|
||||||
extern const Info<bool> NETPLAY_SYNC_SAVES;
|
extern const Info<bool> NETPLAY_SAVEDATA_SYNC_ALL_WII;
|
||||||
extern const Info<bool> NETPLAY_SYNC_CODES;
|
extern const Info<bool> NETPLAY_SYNC_CODES;
|
||||||
extern const Info<bool> NETPLAY_RECORD_INPUTS;
|
extern const Info<bool> NETPLAY_RECORD_INPUTS;
|
||||||
extern const Info<bool> NETPLAY_STRICT_SETTINGS_SYNC;
|
extern const Info<bool> NETPLAY_STRICT_SETTINGS_SYNC;
|
||||||
extern const Info<std::string> NETPLAY_NETWORK_MODE;
|
extern const Info<std::string> NETPLAY_NETWORK_MODE;
|
||||||
extern const Info<bool> NETPLAY_SYNC_ALL_WII_SAVES;
|
|
||||||
extern const Info<bool> NETPLAY_GOLF_MODE_OVERLAY;
|
extern const Info<bool> NETPLAY_GOLF_MODE_OVERLAY;
|
||||||
extern const Info<bool> NETPLAY_HIDE_REMOTE_GBAS;
|
extern const Info<bool> NETPLAY_HIDE_REMOTE_GBAS;
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ public:
|
||||||
for (ExpansionInterface::Slot slot : ExpansionInterface::SLOTS)
|
for (ExpansionInterface::Slot slot : ExpansionInterface::SLOTS)
|
||||||
layer->Set(Config::GetInfoForEXIDevice(slot), m_settings.exi_device[slot]);
|
layer->Set(Config::GetInfoForEXIDevice(slot), m_settings.exi_device[slot]);
|
||||||
layer->Set(Config::MAIN_MEMORY_CARD_SIZE, m_settings.memcard_size_override);
|
layer->Set(Config::MAIN_MEMORY_CARD_SIZE, m_settings.memcard_size_override);
|
||||||
layer->Set(Config::SESSION_SAVE_DATA_WRITABLE, m_settings.write_to_memcard);
|
layer->Set(Config::SESSION_SAVE_DATA_WRITABLE, m_settings.savedata_write);
|
||||||
layer->Set(Config::MAIN_RAM_OVERRIDE_ENABLE, m_settings.ram_override_enable);
|
layer->Set(Config::MAIN_RAM_OVERRIDE_ENABLE, m_settings.ram_override_enable);
|
||||||
layer->Set(Config::MAIN_MEM1_SIZE, m_settings.mem1_size);
|
layer->Set(Config::MAIN_MEM1_SIZE, m_settings.mem1_size);
|
||||||
layer->Set(Config::MAIN_MEM2_SIZE, m_settings.mem2_size);
|
layer->Set(Config::MAIN_MEM2_SIZE, m_settings.mem2_size);
|
||||||
|
@ -120,7 +120,7 @@ public:
|
||||||
layer->Set(Config::GFX_SSAA, false);
|
layer->Set(Config::GFX_SSAA, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_settings.sync_save_data)
|
if (m_settings.savedata_load)
|
||||||
{
|
{
|
||||||
if (!m_settings.is_hosting)
|
if (!m_settings.is_hosting)
|
||||||
{
|
{
|
||||||
|
|
|
@ -812,13 +812,11 @@ void NetPlayClient::OnStartGame(sf::Packet& packet)
|
||||||
packet >> m_net_settings.override_region_settings;
|
packet >> m_net_settings.override_region_settings;
|
||||||
packet >> m_net_settings.dsp_enable_jit;
|
packet >> m_net_settings.dsp_enable_jit;
|
||||||
packet >> m_net_settings.dsp_hle;
|
packet >> m_net_settings.dsp_hle;
|
||||||
packet >> m_net_settings.write_to_memcard;
|
|
||||||
packet >> m_net_settings.ram_override_enable;
|
packet >> m_net_settings.ram_override_enable;
|
||||||
packet >> m_net_settings.mem1_size;
|
packet >> m_net_settings.mem1_size;
|
||||||
packet >> m_net_settings.mem2_size;
|
packet >> m_net_settings.mem2_size;
|
||||||
packet >> m_net_settings.fallback_region;
|
packet >> m_net_settings.fallback_region;
|
||||||
packet >> m_net_settings.allow_sd_writes;
|
packet >> m_net_settings.allow_sd_writes;
|
||||||
packet >> m_net_settings.copy_wii_save;
|
|
||||||
packet >> m_net_settings.oc_enable;
|
packet >> m_net_settings.oc_enable;
|
||||||
packet >> m_net_settings.oc_factor;
|
packet >> m_net_settings.oc_factor;
|
||||||
|
|
||||||
|
@ -873,14 +871,20 @@ void NetPlayClient::OnStartGame(sf::Packet& packet)
|
||||||
packet >> m_net_settings.defer_efb_copies;
|
packet >> m_net_settings.defer_efb_copies;
|
||||||
packet >> m_net_settings.efb_access_tile_size;
|
packet >> m_net_settings.efb_access_tile_size;
|
||||||
packet >> m_net_settings.efb_access_defer_invalidation;
|
packet >> m_net_settings.efb_access_defer_invalidation;
|
||||||
|
packet >> m_net_settings.savedata_load;
|
||||||
|
packet >> m_net_settings.savedata_write;
|
||||||
|
packet >> m_net_settings.savedata_sync_all_wii;
|
||||||
|
if (!m_net_settings.savedata_load)
|
||||||
|
{
|
||||||
|
m_net_settings.savedata_write = false;
|
||||||
|
m_net_settings.savedata_sync_all_wii = false;
|
||||||
|
}
|
||||||
packet >> m_net_settings.strict_settings_sync;
|
packet >> m_net_settings.strict_settings_sync;
|
||||||
|
|
||||||
m_initial_rtc = Common::PacketReadU64(packet);
|
m_initial_rtc = Common::PacketReadU64(packet);
|
||||||
|
|
||||||
packet >> m_net_settings.sync_save_data;
|
|
||||||
packet >> m_net_settings.save_data_region;
|
packet >> m_net_settings.save_data_region;
|
||||||
packet >> m_net_settings.sync_codes;
|
packet >> m_net_settings.sync_codes;
|
||||||
packet >> m_net_settings.sync_all_wii_saves;
|
|
||||||
|
|
||||||
for (int& extension : m_net_settings.wiimote_extension)
|
for (int& extension : m_net_settings.wiimote_extension)
|
||||||
packet >> extension;
|
packet >> extension;
|
||||||
|
@ -2576,16 +2580,6 @@ void SendPowerButtonEvent()
|
||||||
netplay_client->SendPowerButtonEvent();
|
netplay_client->SendPowerButtonEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsSyncingAllWiiSaves()
|
|
||||||
{
|
|
||||||
std::lock_guard lk(crit_netplay_client);
|
|
||||||
|
|
||||||
if (netplay_client)
|
|
||||||
return netplay_client->GetNetSettings().sync_all_wii_saves;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupWiimotes()
|
void SetupWiimotes()
|
||||||
{
|
{
|
||||||
ASSERT(IsNetPlayRunning());
|
ASSERT(IsNetPlayRunning());
|
||||||
|
@ -2617,7 +2611,7 @@ std::string GetGBASavePath(int pad_num)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!netplay_client->GetNetSettings().sync_save_data)
|
if (!netplay_client->GetNetSettings().savedata_load)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
return fmt::format("{}{}{}.sav", File::GetUserPath(D_GBAUSER_IDX), GBA_SAVE_NETPLAY, pad_num + 1);
|
return fmt::format("{}{}{}.sav", File::GetUserPath(D_GBAUSER_IDX), GBA_SAVE_NETPLAY, pad_num + 1);
|
||||||
|
|
|
@ -38,13 +38,11 @@ struct NetSettings
|
||||||
bool override_region_settings = false;
|
bool override_region_settings = false;
|
||||||
bool dsp_hle = false;
|
bool dsp_hle = false;
|
||||||
bool dsp_enable_jit = false;
|
bool dsp_enable_jit = false;
|
||||||
bool write_to_memcard = false;
|
|
||||||
bool ram_override_enable = false;
|
bool ram_override_enable = false;
|
||||||
u32 mem1_size = 0;
|
u32 mem1_size = 0;
|
||||||
u32 mem2_size = 0;
|
u32 mem2_size = 0;
|
||||||
DiscIO::Region fallback_region{};
|
DiscIO::Region fallback_region{};
|
||||||
bool allow_sd_writes = false;
|
bool allow_sd_writes = false;
|
||||||
bool copy_wii_save = false;
|
|
||||||
bool oc_enable = false;
|
bool oc_enable = false;
|
||||||
float oc_factor = 0;
|
float oc_factor = 0;
|
||||||
Common::EnumMap<ExpansionInterface::EXIDeviceType, ExpansionInterface::MAX_SLOT> exi_device{};
|
Common::EnumMap<ExpansionInterface::EXIDeviceType, ExpansionInterface::MAX_SLOT> exi_device{};
|
||||||
|
@ -96,11 +94,13 @@ struct NetSettings
|
||||||
int efb_access_tile_size = 0;
|
int efb_access_tile_size = 0;
|
||||||
bool efb_access_defer_invalidation = false;
|
bool efb_access_defer_invalidation = false;
|
||||||
|
|
||||||
|
bool savedata_load = false;
|
||||||
|
bool savedata_write = false;
|
||||||
|
bool savedata_sync_all_wii = false;
|
||||||
|
|
||||||
bool strict_settings_sync = false;
|
bool strict_settings_sync = false;
|
||||||
bool sync_save_data = false;
|
|
||||||
bool sync_codes = false;
|
bool sync_codes = false;
|
||||||
std::string save_data_region;
|
std::string save_data_region;
|
||||||
bool sync_all_wii_saves = false;
|
|
||||||
std::array<int, 4> wiimote_extension{};
|
std::array<int, 4> wiimote_extension{};
|
||||||
bool golf_mode = false;
|
bool golf_mode = false;
|
||||||
bool use_fma = false;
|
bool use_fma = false;
|
||||||
|
@ -260,7 +260,6 @@ std::string GetPlayerMappingString(PlayerId pid, const PadMappingArray& pad_map,
|
||||||
bool IsNetPlayRunning();
|
bool IsNetPlayRunning();
|
||||||
void SetSIPollBatching(bool state);
|
void SetSIPollBatching(bool state);
|
||||||
void SendPowerButtonEvent();
|
void SendPowerButtonEvent();
|
||||||
bool IsSyncingAllWiiSaves();
|
|
||||||
void SetupWiimotes();
|
void SetupWiimotes();
|
||||||
std::string GetGBASavePath(int pad_num);
|
std::string GetGBASavePath(int pad_num);
|
||||||
PadDetails GetPadDetails(int pad_num);
|
PadDetails GetPadDetails(int pad_num);
|
||||||
|
|
|
@ -1261,13 +1261,11 @@ bool NetPlayServer::SetupNetSettings()
|
||||||
settings.override_region_settings = Config::Get(Config::MAIN_OVERRIDE_REGION_SETTINGS);
|
settings.override_region_settings = Config::Get(Config::MAIN_OVERRIDE_REGION_SETTINGS);
|
||||||
settings.dsp_hle = Config::Get(Config::MAIN_DSP_HLE);
|
settings.dsp_hle = Config::Get(Config::MAIN_DSP_HLE);
|
||||||
settings.dsp_enable_jit = Config::Get(Config::MAIN_DSP_JIT);
|
settings.dsp_enable_jit = Config::Get(Config::MAIN_DSP_JIT);
|
||||||
settings.write_to_memcard = Config::Get(Config::NETPLAY_WRITE_SAVE_DATA);
|
|
||||||
settings.ram_override_enable = Config::Get(Config::MAIN_RAM_OVERRIDE_ENABLE);
|
settings.ram_override_enable = Config::Get(Config::MAIN_RAM_OVERRIDE_ENABLE);
|
||||||
settings.mem1_size = Config::Get(Config::MAIN_MEM1_SIZE);
|
settings.mem1_size = Config::Get(Config::MAIN_MEM1_SIZE);
|
||||||
settings.mem2_size = Config::Get(Config::MAIN_MEM2_SIZE);
|
settings.mem2_size = Config::Get(Config::MAIN_MEM2_SIZE);
|
||||||
settings.fallback_region = Config::Get(Config::MAIN_FALLBACK_REGION);
|
settings.fallback_region = Config::Get(Config::MAIN_FALLBACK_REGION);
|
||||||
settings.allow_sd_writes = Config::Get(Config::MAIN_ALLOW_SD_WRITES);
|
settings.allow_sd_writes = Config::Get(Config::MAIN_ALLOW_SD_WRITES);
|
||||||
settings.copy_wii_save = Config::Get(Config::NETPLAY_LOAD_WII_SAVE);
|
|
||||||
settings.oc_enable = Config::Get(Config::MAIN_OVERCLOCK_ENABLE);
|
settings.oc_enable = Config::Get(Config::MAIN_OVERCLOCK_ENABLE);
|
||||||
settings.oc_factor = Config::Get(Config::MAIN_OVERCLOCK);
|
settings.oc_factor = Config::Get(Config::MAIN_OVERCLOCK);
|
||||||
|
|
||||||
|
@ -1344,11 +1342,13 @@ bool NetPlayServer::SetupNetSettings()
|
||||||
settings.efb_access_tile_size = Config::Get(Config::GFX_HACK_EFB_ACCESS_TILE_SIZE);
|
settings.efb_access_tile_size = Config::Get(Config::GFX_HACK_EFB_ACCESS_TILE_SIZE);
|
||||||
settings.efb_access_defer_invalidation = Config::Get(Config::GFX_HACK_EFB_DEFER_INVALIDATION);
|
settings.efb_access_defer_invalidation = Config::Get(Config::GFX_HACK_EFB_DEFER_INVALIDATION);
|
||||||
|
|
||||||
|
settings.savedata_load = Config::Get(Config::NETPLAY_SAVEDATA_LOAD);
|
||||||
|
settings.savedata_write = settings.savedata_load && Config::Get(Config::NETPLAY_SAVEDATA_WRITE);
|
||||||
|
settings.savedata_sync_all_wii =
|
||||||
|
settings.savedata_load && Config::Get(Config::NETPLAY_SAVEDATA_SYNC_ALL_WII);
|
||||||
|
|
||||||
settings.strict_settings_sync = Config::Get(Config::NETPLAY_STRICT_SETTINGS_SYNC);
|
settings.strict_settings_sync = Config::Get(Config::NETPLAY_STRICT_SETTINGS_SYNC);
|
||||||
settings.sync_save_data = Config::Get(Config::NETPLAY_SYNC_SAVES);
|
|
||||||
settings.sync_codes = Config::Get(Config::NETPLAY_SYNC_CODES);
|
settings.sync_codes = Config::Get(Config::NETPLAY_SYNC_CODES);
|
||||||
settings.sync_all_wii_saves =
|
|
||||||
Config::Get(Config::NETPLAY_SYNC_ALL_WII_SAVES) && Config::Get(Config::NETPLAY_SYNC_SAVES);
|
|
||||||
settings.golf_mode = Config::Get(Config::NETPLAY_NETWORK_MODE) == "golf";
|
settings.golf_mode = Config::Get(Config::NETPLAY_NETWORK_MODE) == "golf";
|
||||||
settings.use_fma = DoAllPlayersHaveHardwareFMA();
|
settings.use_fma = DoAllPlayersHaveHardwareFMA();
|
||||||
settings.hide_remote_gbas = Config::Get(Config::NETPLAY_HIDE_REMOTE_GBAS);
|
settings.hide_remote_gbas = Config::Get(Config::NETPLAY_HIDE_REMOTE_GBAS);
|
||||||
|
@ -1382,7 +1382,7 @@ bool NetPlayServer::RequestStartGame()
|
||||||
|
|
||||||
bool start_now = true;
|
bool start_now = true;
|
||||||
|
|
||||||
if (m_settings.sync_save_data && m_players.size() > 1)
|
if (m_settings.savedata_load && m_players.size() > 1)
|
||||||
{
|
{
|
||||||
start_now = false;
|
start_now = false;
|
||||||
m_start_pending = true;
|
m_start_pending = true;
|
||||||
|
@ -1451,13 +1451,11 @@ bool NetPlayServer::StartGame()
|
||||||
spac << m_settings.override_region_settings;
|
spac << m_settings.override_region_settings;
|
||||||
spac << m_settings.dsp_enable_jit;
|
spac << m_settings.dsp_enable_jit;
|
||||||
spac << m_settings.dsp_hle;
|
spac << m_settings.dsp_hle;
|
||||||
spac << m_settings.write_to_memcard;
|
|
||||||
spac << m_settings.ram_override_enable;
|
spac << m_settings.ram_override_enable;
|
||||||
spac << m_settings.mem1_size;
|
spac << m_settings.mem1_size;
|
||||||
spac << m_settings.mem2_size;
|
spac << m_settings.mem2_size;
|
||||||
spac << m_settings.fallback_region;
|
spac << m_settings.fallback_region;
|
||||||
spac << m_settings.allow_sd_writes;
|
spac << m_settings.allow_sd_writes;
|
||||||
spac << m_settings.copy_wii_save;
|
|
||||||
spac << m_settings.oc_enable;
|
spac << m_settings.oc_enable;
|
||||||
spac << m_settings.oc_factor;
|
spac << m_settings.oc_factor;
|
||||||
|
|
||||||
|
@ -1512,12 +1510,13 @@ bool NetPlayServer::StartGame()
|
||||||
spac << m_settings.defer_efb_copies;
|
spac << m_settings.defer_efb_copies;
|
||||||
spac << m_settings.efb_access_tile_size;
|
spac << m_settings.efb_access_tile_size;
|
||||||
spac << m_settings.efb_access_defer_invalidation;
|
spac << m_settings.efb_access_defer_invalidation;
|
||||||
|
spac << m_settings.savedata_load;
|
||||||
|
spac << m_settings.savedata_write;
|
||||||
|
spac << m_settings.savedata_sync_all_wii;
|
||||||
spac << m_settings.strict_settings_sync;
|
spac << m_settings.strict_settings_sync;
|
||||||
spac << initial_rtc;
|
spac << initial_rtc;
|
||||||
spac << m_settings.sync_save_data;
|
|
||||||
spac << region;
|
spac << region;
|
||||||
spac << m_settings.sync_codes;
|
spac << m_settings.sync_codes;
|
||||||
spac << m_settings.sync_all_wii_saves;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < m_settings.wiimote_extension.size(); i++)
|
for (size_t i = 0; i < m_settings.wiimote_extension.size(); i++)
|
||||||
{
|
{
|
||||||
|
@ -1582,7 +1581,7 @@ bool NetPlayServer::SyncSaveData()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wii_save = false;
|
bool wii_save = false;
|
||||||
if (m_settings.copy_wii_save && (game->GetPlatform() == DiscIO::Platform::WiiDisc ||
|
if (m_settings.savedata_load && (game->GetPlatform() == DiscIO::Platform::WiiDisc ||
|
||||||
game->GetPlatform() == DiscIO::Platform::WiiWAD ||
|
game->GetPlatform() == DiscIO::Platform::WiiWAD ||
|
||||||
game->GetPlatform() == DiscIO::Platform::ELFOrDOL))
|
game->GetPlatform() == DiscIO::Platform::ELFOrDOL))
|
||||||
{
|
{
|
||||||
|
@ -1695,7 +1694,7 @@ bool NetPlayServer::SyncSaveData()
|
||||||
const auto configured_fs = IOS::HLE::FS::MakeFileSystem(IOS::HLE::FS::Location::Configured);
|
const auto configured_fs = IOS::HLE::FS::MakeFileSystem(IOS::HLE::FS::Location::Configured);
|
||||||
|
|
||||||
std::vector<std::pair<u64, WiiSave::StoragePointer>> saves;
|
std::vector<std::pair<u64, WiiSave::StoragePointer>> saves;
|
||||||
if (m_settings.sync_all_wii_saves)
|
if (m_settings.savedata_sync_all_wii)
|
||||||
{
|
{
|
||||||
IOS::HLE::Kernel ios;
|
IOS::HLE::Kernel ios;
|
||||||
for (const u64 title : ios.GetES()->GetInstalledTitles())
|
for (const u64 title : ios.GetES()->GetInstalledTitles())
|
||||||
|
|
|
@ -170,19 +170,11 @@ static void InitializeDeterministicWiiSaves(FS::FileSystem* session_fs,
|
||||||
{
|
{
|
||||||
INFO_LOG_FMT(CORE, "Wii Save Init: Copying from configured_fs to session_fs.");
|
INFO_LOG_FMT(CORE, "Wii Save Init: Copying from configured_fs to session_fs.");
|
||||||
|
|
||||||
if (NetPlay::IsSyncingAllWiiSaves())
|
|
||||||
{
|
|
||||||
for (const u64 title : sync_titles)
|
for (const u64 title : sync_titles)
|
||||||
{
|
{
|
||||||
INFO_LOG_FMT(CORE, "Wii Save Init: Copying {0:016x}.", title);
|
INFO_LOG_FMT(CORE, "Wii Save Init: Copying {0:016x}.", title);
|
||||||
CopySave(configured_fs.get(), session_fs, title);
|
CopySave(configured_fs.get(), session_fs, title);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
INFO_LOG_FMT(CORE, "Wii Save Init: Copying {0:016x}.", title_id);
|
|
||||||
CopySave(configured_fs.get(), session_fs, title_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy Mii data
|
// Copy Mii data
|
||||||
if (!CopyNandFile(configured_fs.get(), Common::GetMiiDatabasePath(), session_fs,
|
if (!CopyNandFile(configured_fs.get(), Common::GetMiiDatabasePath(), session_fs,
|
||||||
|
@ -382,17 +374,20 @@ void InitializeWiiFileSystemContents(
|
||||||
|
|
||||||
void CleanUpWiiFileSystemContents(const BootSessionData& boot_session_data)
|
void CleanUpWiiFileSystemContents(const BootSessionData& boot_session_data)
|
||||||
{
|
{
|
||||||
|
// In TAS mode, copy back always.
|
||||||
|
// In Netplay, only copy back when we're the host and writing back is enabled.
|
||||||
const bool wii_root_is_temporary = WiiRootIsTemporary();
|
const bool wii_root_is_temporary = WiiRootIsTemporary();
|
||||||
const bool session_save_data_writable = Config::Get(Config::SESSION_SAVE_DATA_WRITABLE);
|
const auto* netplay_settings = boot_session_data.GetNetplaySettings();
|
||||||
const bool has_wii_sync_fs = !!boot_session_data.GetWiiSyncFS();
|
const bool is_netplay_write = netplay_settings && netplay_settings->savedata_write;
|
||||||
|
const bool is_netplay_host = netplay_settings && netplay_settings->is_hosting;
|
||||||
const bool cleanup_required =
|
const bool cleanup_required =
|
||||||
wii_root_is_temporary && session_save_data_writable && !has_wii_sync_fs;
|
wii_root_is_temporary && (!netplay_settings || (is_netplay_write && is_netplay_host));
|
||||||
|
|
||||||
INFO_LOG_FMT(CORE,
|
INFO_LOG_FMT(CORE,
|
||||||
"Wii FS Cleanup: cleanup_required = {} (wii_root_is_temporary = {}, "
|
"Wii FS Cleanup: cleanup_required = {} (wii_root_is_temporary = {}, "
|
||||||
"session_save_data_writable = {}, has_wii_sync_fs = {})",
|
"is netplay = {}, is_netplay_write = {}, is_netplay_host = {})",
|
||||||
cleanup_required, wii_root_is_temporary, session_save_data_writable,
|
cleanup_required, wii_root_is_temporary, !!netplay_settings, is_netplay_write,
|
||||||
has_wii_sync_fs);
|
is_netplay_host);
|
||||||
|
|
||||||
if (!cleanup_required)
|
if (!cleanup_required)
|
||||||
return;
|
return;
|
||||||
|
@ -418,7 +413,13 @@ void CleanUpWiiFileSystemContents(const BootSessionData& boot_session_data)
|
||||||
WARN_LOG_FMT(CORE, "Failed to copy Mii database to the NAND");
|
WARN_LOG_FMT(CORE, "Failed to copy Mii database to the NAND");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const u64 title_id : ios->GetES()->GetInstalledTitles())
|
// If we started by copying only certain saves, we also only want to copy back those exact saves.
|
||||||
|
// This prevents a situation where you change game and create a new save that was not loaded from
|
||||||
|
// the real NAND during netplay, and that then overwrites your existing local save during this
|
||||||
|
// cleanup process.
|
||||||
|
const bool copy_all = !netplay_settings || netplay_settings->savedata_sync_all_wii;
|
||||||
|
for (const u64 title_id :
|
||||||
|
(copy_all ? ios->GetES()->GetInstalledTitles() : boot_session_data.GetWiiSyncTitles()))
|
||||||
{
|
{
|
||||||
INFO_LOG_FMT(CORE, "Wii FS Cleanup: Copying {0:016x}.", title_id);
|
INFO_LOG_FMT(CORE, "Wii FS Cleanup: Copying {0:016x}.", title_id);
|
||||||
|
|
||||||
|
|
|
@ -137,16 +137,41 @@ void NetPlayDialog::CreateMainLayout()
|
||||||
|
|
||||||
m_data_menu = m_menu_bar->addMenu(tr("Data"));
|
m_data_menu = m_menu_bar->addMenu(tr("Data"));
|
||||||
m_data_menu->setToolTipsVisible(true);
|
m_data_menu->setToolTipsVisible(true);
|
||||||
m_write_save_data_action = m_data_menu->addAction(tr("Write Save Data"));
|
|
||||||
m_write_save_data_action->setCheckable(true);
|
m_savedata_none_action = m_data_menu->addAction(tr("No Save Data"));
|
||||||
m_load_wii_action = m_data_menu->addAction(tr("Load Wii Save"));
|
m_savedata_none_action->setToolTip(
|
||||||
m_load_wii_action->setCheckable(true);
|
tr("Netplay will start without any save data, and any created save data will be discarded at "
|
||||||
m_sync_save_data_action = m_data_menu->addAction(tr("Sync Saves"));
|
"the end of the Netplay session."));
|
||||||
m_sync_save_data_action->setCheckable(true);
|
m_savedata_none_action->setCheckable(true);
|
||||||
|
m_savedata_load_only_action = m_data_menu->addAction(tr("Load Host's Save Data Only"));
|
||||||
|
m_savedata_load_only_action->setToolTip(tr(
|
||||||
|
"Netplay will start using the Host's save data, but any save data created or modified during "
|
||||||
|
"the Netplay session will be discarded at the end of the session."));
|
||||||
|
m_savedata_load_only_action->setCheckable(true);
|
||||||
|
m_savedata_load_and_write_action = m_data_menu->addAction(tr("Load and Write Host's Save Data"));
|
||||||
|
m_savedata_load_and_write_action->setToolTip(
|
||||||
|
tr("Netplay will start using the Host's save data, and any save data created or modified "
|
||||||
|
"during the Netplay session will remain in the Host's local saves."));
|
||||||
|
m_savedata_load_and_write_action->setCheckable(true);
|
||||||
|
|
||||||
|
m_savedata_style_group = new QActionGroup(this);
|
||||||
|
m_savedata_style_group->setExclusive(true);
|
||||||
|
m_savedata_style_group->addAction(m_savedata_none_action);
|
||||||
|
m_savedata_style_group->addAction(m_savedata_load_only_action);
|
||||||
|
m_savedata_style_group->addAction(m_savedata_load_and_write_action);
|
||||||
|
|
||||||
|
m_data_menu->addSeparator();
|
||||||
|
|
||||||
|
m_savedata_all_wii_saves_action = m_data_menu->addAction(tr("Use All Wii Save Data"));
|
||||||
|
m_savedata_all_wii_saves_action->setToolTip(tr(
|
||||||
|
"If checked, all Wii saves will be used instead of only the save of the game being started. "
|
||||||
|
"Useful when switching games mid-session. Has no effect if No Save Data is selected."));
|
||||||
|
m_savedata_all_wii_saves_action->setCheckable(true);
|
||||||
|
|
||||||
|
m_data_menu->addSeparator();
|
||||||
|
|
||||||
m_sync_codes_action = m_data_menu->addAction(tr("Sync AR/Gecko Codes"));
|
m_sync_codes_action = m_data_menu->addAction(tr("Sync AR/Gecko Codes"));
|
||||||
m_sync_codes_action->setCheckable(true);
|
m_sync_codes_action->setCheckable(true);
|
||||||
m_sync_all_wii_saves_action = m_data_menu->addAction(tr("Sync All Wii Saves"));
|
|
||||||
m_sync_all_wii_saves_action->setCheckable(true);
|
|
||||||
m_strict_settings_sync_action = m_data_menu->addAction(tr("Strict Settings Sync"));
|
m_strict_settings_sync_action = m_data_menu->addAction(tr("Strict Settings Sync"));
|
||||||
m_strict_settings_sync_action->setToolTip(
|
m_strict_settings_sync_action->setToolTip(
|
||||||
tr("This will sync additional graphics settings, and force everyone to the same internal "
|
tr("This will sync additional graphics settings, and force everyone to the same internal "
|
||||||
|
@ -210,7 +235,7 @@ void NetPlayDialog::CreateMainLayout()
|
||||||
m_game_button->setDefault(false);
|
m_game_button->setDefault(false);
|
||||||
m_game_button->setAutoDefault(false);
|
m_game_button->setAutoDefault(false);
|
||||||
|
|
||||||
m_sync_save_data_action->setChecked(true);
|
m_savedata_load_only_action->setChecked(true);
|
||||||
m_sync_codes_action->setChecked(true);
|
m_sync_codes_action->setChecked(true);
|
||||||
|
|
||||||
m_main_layout->setMenuBar(m_menu_bar);
|
m_main_layout->setMenuBar(m_menu_bar);
|
||||||
|
@ -383,21 +408,18 @@ void NetPlayDialog::ConnectWidgets()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(m_sync_save_data_action, &QAction::toggled, this,
|
|
||||||
[this](bool checked) { m_sync_all_wii_saves_action->setEnabled(checked); });
|
|
||||||
|
|
||||||
// SaveSettings() - Save Hosting-Dialog Settings
|
// SaveSettings() - Save Hosting-Dialog Settings
|
||||||
|
|
||||||
connect(m_buffer_size_box, qOverload<int>(&QSpinBox::valueChanged), this,
|
connect(m_buffer_size_box, qOverload<int>(&QSpinBox::valueChanged), this,
|
||||||
&NetPlayDialog::SaveSettings);
|
&NetPlayDialog::SaveSettings);
|
||||||
connect(m_write_save_data_action, &QAction::toggled, this, &NetPlayDialog::SaveSettings);
|
connect(m_savedata_none_action, &QAction::toggled, this, &NetPlayDialog::SaveSettings);
|
||||||
connect(m_load_wii_action, &QAction::toggled, this, &NetPlayDialog::SaveSettings);
|
connect(m_savedata_load_only_action, &QAction::toggled, this, &NetPlayDialog::SaveSettings);
|
||||||
connect(m_sync_save_data_action, &QAction::toggled, this, &NetPlayDialog::SaveSettings);
|
connect(m_savedata_load_and_write_action, &QAction::toggled, this, &NetPlayDialog::SaveSettings);
|
||||||
|
connect(m_savedata_all_wii_saves_action, &QAction::toggled, this, &NetPlayDialog::SaveSettings);
|
||||||
connect(m_sync_codes_action, &QAction::toggled, this, &NetPlayDialog::SaveSettings);
|
connect(m_sync_codes_action, &QAction::toggled, this, &NetPlayDialog::SaveSettings);
|
||||||
connect(m_record_input_action, &QAction::toggled, this, &NetPlayDialog::SaveSettings);
|
connect(m_record_input_action, &QAction::toggled, this, &NetPlayDialog::SaveSettings);
|
||||||
connect(m_strict_settings_sync_action, &QAction::toggled, this, &NetPlayDialog::SaveSettings);
|
connect(m_strict_settings_sync_action, &QAction::toggled, this, &NetPlayDialog::SaveSettings);
|
||||||
connect(m_host_input_authority_action, &QAction::toggled, this, &NetPlayDialog::SaveSettings);
|
connect(m_host_input_authority_action, &QAction::toggled, this, &NetPlayDialog::SaveSettings);
|
||||||
connect(m_sync_all_wii_saves_action, &QAction::toggled, this, &NetPlayDialog::SaveSettings);
|
|
||||||
connect(m_golf_mode_action, &QAction::toggled, this, &NetPlayDialog::SaveSettings);
|
connect(m_golf_mode_action, &QAction::toggled, this, &NetPlayDialog::SaveSettings);
|
||||||
connect(m_golf_mode_overlay_action, &QAction::toggled, this, &NetPlayDialog::SaveSettings);
|
connect(m_golf_mode_overlay_action, &QAction::toggled, this, &NetPlayDialog::SaveSettings);
|
||||||
connect(m_fixed_delay_action, &QAction::toggled, this, &NetPlayDialog::SaveSettings);
|
connect(m_fixed_delay_action, &QAction::toggled, this, &NetPlayDialog::SaveSettings);
|
||||||
|
@ -828,14 +850,14 @@ void NetPlayDialog::SetOptionsEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
m_start_button->setEnabled(enabled);
|
m_start_button->setEnabled(enabled);
|
||||||
m_game_button->setEnabled(enabled);
|
m_game_button->setEnabled(enabled);
|
||||||
m_load_wii_action->setEnabled(enabled);
|
m_savedata_none_action->setEnabled(enabled);
|
||||||
m_write_save_data_action->setEnabled(enabled);
|
m_savedata_load_only_action->setEnabled(enabled);
|
||||||
m_sync_save_data_action->setEnabled(enabled);
|
m_savedata_load_and_write_action->setEnabled(enabled);
|
||||||
|
m_savedata_all_wii_saves_action->setEnabled(enabled);
|
||||||
m_sync_codes_action->setEnabled(enabled);
|
m_sync_codes_action->setEnabled(enabled);
|
||||||
m_assign_ports_button->setEnabled(enabled);
|
m_assign_ports_button->setEnabled(enabled);
|
||||||
m_strict_settings_sync_action->setEnabled(enabled);
|
m_strict_settings_sync_action->setEnabled(enabled);
|
||||||
m_host_input_authority_action->setEnabled(enabled);
|
m_host_input_authority_action->setEnabled(enabled);
|
||||||
m_sync_all_wii_saves_action->setEnabled(enabled && m_sync_save_data_action->isChecked());
|
|
||||||
m_golf_mode_action->setEnabled(enabled);
|
m_golf_mode_action->setEnabled(enabled);
|
||||||
m_fixed_delay_action->setEnabled(enabled);
|
m_fixed_delay_action->setEnabled(enabled);
|
||||||
}
|
}
|
||||||
|
@ -1097,24 +1119,28 @@ std::string NetPlayDialog::FindGBARomPath(const std::array<u8, 20>& hash, std::s
|
||||||
void NetPlayDialog::LoadSettings()
|
void NetPlayDialog::LoadSettings()
|
||||||
{
|
{
|
||||||
const int buffer_size = Config::Get(Config::NETPLAY_BUFFER_SIZE);
|
const int buffer_size = Config::Get(Config::NETPLAY_BUFFER_SIZE);
|
||||||
const bool write_save_data = Config::Get(Config::NETPLAY_WRITE_SAVE_DATA);
|
const bool savedata_load = Config::Get(Config::NETPLAY_SAVEDATA_LOAD);
|
||||||
const bool load_wii_save = Config::Get(Config::NETPLAY_LOAD_WII_SAVE);
|
const bool savedata_write = Config::Get(Config::NETPLAY_SAVEDATA_WRITE);
|
||||||
const bool sync_saves = Config::Get(Config::NETPLAY_SYNC_SAVES);
|
const bool sync_all_wii_saves = Config::Get(Config::NETPLAY_SAVEDATA_SYNC_ALL_WII);
|
||||||
const bool sync_codes = Config::Get(Config::NETPLAY_SYNC_CODES);
|
const bool sync_codes = Config::Get(Config::NETPLAY_SYNC_CODES);
|
||||||
const bool record_inputs = Config::Get(Config::NETPLAY_RECORD_INPUTS);
|
const bool record_inputs = Config::Get(Config::NETPLAY_RECORD_INPUTS);
|
||||||
const bool strict_settings_sync = Config::Get(Config::NETPLAY_STRICT_SETTINGS_SYNC);
|
const bool strict_settings_sync = Config::Get(Config::NETPLAY_STRICT_SETTINGS_SYNC);
|
||||||
const bool sync_all_wii_saves = Config::Get(Config::NETPLAY_SYNC_ALL_WII_SAVES);
|
|
||||||
const bool golf_mode_overlay = Config::Get(Config::NETPLAY_GOLF_MODE_OVERLAY);
|
const bool golf_mode_overlay = Config::Get(Config::NETPLAY_GOLF_MODE_OVERLAY);
|
||||||
const bool hide_remote_gbas = Config::Get(Config::NETPLAY_HIDE_REMOTE_GBAS);
|
const bool hide_remote_gbas = Config::Get(Config::NETPLAY_HIDE_REMOTE_GBAS);
|
||||||
|
|
||||||
m_buffer_size_box->setValue(buffer_size);
|
m_buffer_size_box->setValue(buffer_size);
|
||||||
m_write_save_data_action->setChecked(write_save_data);
|
|
||||||
m_load_wii_action->setChecked(load_wii_save);
|
if (!savedata_load)
|
||||||
m_sync_save_data_action->setChecked(sync_saves);
|
m_savedata_none_action->setChecked(true);
|
||||||
|
else if (!savedata_write)
|
||||||
|
m_savedata_load_only_action->setChecked(true);
|
||||||
|
else
|
||||||
|
m_savedata_load_and_write_action->setChecked(true);
|
||||||
|
m_savedata_all_wii_saves_action->setChecked(sync_all_wii_saves);
|
||||||
|
|
||||||
m_sync_codes_action->setChecked(sync_codes);
|
m_sync_codes_action->setChecked(sync_codes);
|
||||||
m_record_input_action->setChecked(record_inputs);
|
m_record_input_action->setChecked(record_inputs);
|
||||||
m_strict_settings_sync_action->setChecked(strict_settings_sync);
|
m_strict_settings_sync_action->setChecked(strict_settings_sync);
|
||||||
m_sync_all_wii_saves_action->setChecked(sync_all_wii_saves);
|
|
||||||
m_golf_mode_overlay_action->setChecked(golf_mode_overlay);
|
m_golf_mode_overlay_action->setChecked(golf_mode_overlay);
|
||||||
m_hide_remote_gbas_action->setChecked(hide_remote_gbas);
|
m_hide_remote_gbas_action->setChecked(hide_remote_gbas);
|
||||||
|
|
||||||
|
@ -1148,13 +1174,16 @@ void NetPlayDialog::SaveSettings()
|
||||||
else
|
else
|
||||||
Config::SetBase(Config::NETPLAY_BUFFER_SIZE, m_buffer_size_box->value());
|
Config::SetBase(Config::NETPLAY_BUFFER_SIZE, m_buffer_size_box->value());
|
||||||
|
|
||||||
Config::SetBase(Config::NETPLAY_WRITE_SAVE_DATA, m_write_save_data_action->isChecked());
|
const bool write_savedata = m_savedata_load_and_write_action->isChecked();
|
||||||
Config::SetBase(Config::NETPLAY_LOAD_WII_SAVE, m_load_wii_action->isChecked());
|
const bool load_savedata = write_savedata || m_savedata_load_only_action->isChecked();
|
||||||
Config::SetBase(Config::NETPLAY_SYNC_SAVES, m_sync_save_data_action->isChecked());
|
Config::SetBase(Config::NETPLAY_SAVEDATA_LOAD, load_savedata);
|
||||||
|
Config::SetBase(Config::NETPLAY_SAVEDATA_WRITE, write_savedata);
|
||||||
|
|
||||||
|
Config::SetBase(Config::NETPLAY_SAVEDATA_SYNC_ALL_WII,
|
||||||
|
m_savedata_all_wii_saves_action->isChecked());
|
||||||
Config::SetBase(Config::NETPLAY_SYNC_CODES, m_sync_codes_action->isChecked());
|
Config::SetBase(Config::NETPLAY_SYNC_CODES, m_sync_codes_action->isChecked());
|
||||||
Config::SetBase(Config::NETPLAY_RECORD_INPUTS, m_record_input_action->isChecked());
|
Config::SetBase(Config::NETPLAY_RECORD_INPUTS, m_record_input_action->isChecked());
|
||||||
Config::SetBase(Config::NETPLAY_STRICT_SETTINGS_SYNC, m_strict_settings_sync_action->isChecked());
|
Config::SetBase(Config::NETPLAY_STRICT_SETTINGS_SYNC, m_strict_settings_sync_action->isChecked());
|
||||||
Config::SetBase(Config::NETPLAY_SYNC_ALL_WII_SAVES, m_sync_all_wii_saves_action->isChecked());
|
|
||||||
Config::SetBase(Config::NETPLAY_GOLF_MODE_OVERLAY, m_golf_mode_overlay_action->isChecked());
|
Config::SetBase(Config::NETPLAY_GOLF_MODE_OVERLAY, m_golf_mode_overlay_action->isChecked());
|
||||||
Config::SetBase(Config::NETPLAY_HIDE_REMOTE_GBAS, m_hide_remote_gbas_action->isChecked());
|
Config::SetBase(Config::NETPLAY_HIDE_REMOTE_GBAS, m_hide_remote_gbas_action->isChecked());
|
||||||
|
|
||||||
|
|
|
@ -142,14 +142,17 @@ private:
|
||||||
QPushButton* m_start_button;
|
QPushButton* m_start_button;
|
||||||
QLabel* m_buffer_label;
|
QLabel* m_buffer_label;
|
||||||
QSpinBox* m_buffer_size_box;
|
QSpinBox* m_buffer_size_box;
|
||||||
QAction* m_write_save_data_action;
|
|
||||||
QAction* m_load_wii_action;
|
QActionGroup* m_savedata_style_group;
|
||||||
QAction* m_sync_save_data_action;
|
QAction* m_savedata_none_action;
|
||||||
|
QAction* m_savedata_load_only_action;
|
||||||
|
QAction* m_savedata_load_and_write_action;
|
||||||
|
QAction* m_savedata_all_wii_saves_action;
|
||||||
|
|
||||||
QAction* m_sync_codes_action;
|
QAction* m_sync_codes_action;
|
||||||
QAction* m_record_input_action;
|
QAction* m_record_input_action;
|
||||||
QAction* m_strict_settings_sync_action;
|
QAction* m_strict_settings_sync_action;
|
||||||
QAction* m_host_input_authority_action;
|
QAction* m_host_input_authority_action;
|
||||||
QAction* m_sync_all_wii_saves_action;
|
|
||||||
QAction* m_golf_mode_action;
|
QAction* m_golf_mode_action;
|
||||||
QAction* m_golf_mode_overlay_action;
|
QAction* m_golf_mode_overlay_action;
|
||||||
QAction* m_fixed_delay_action;
|
QAction* m_fixed_delay_action;
|
||||||
|
|
Loading…
Reference in New Issue