commit:     c223bdee183d7b36006bbbbc91f268fa0b54bc18
Author:     Michał Górny <mgorny <AT> gentoo <DOT> org>
AuthorDate: Thu Sep 18 11:28:54 2025 +0000
Commit:     Michał Górny <mgorny <AT> gentoo <DOT> org>
CommitDate: Thu Sep 18 11:29:28 2025 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=c223bdee

games-emulation/dolphin: Backport libfmt-12 fix

Closes: https://bugs.gentoo.org/963023
Signed-off-by: Michał Górny <mgorny <AT> gentoo.org>

 games-emulation/dolphin/dolphin-2506.ebuild        |   2 +
 .../dolphin/files/dolphin-2506-fmt-12.patch        | 244 +++++++++++++++++++++
 2 files changed, 246 insertions(+)

diff --git a/games-emulation/dolphin/dolphin-2506.ebuild 
b/games-emulation/dolphin/dolphin-2506.ebuild
index 0ed5b3c00468..6b7f6e3d4aea 100644
--- a/games-emulation/dolphin/dolphin-2506.ebuild
+++ b/games-emulation/dolphin/dolphin-2506.ebuild
@@ -157,6 +157,8 @@ declare -A KEEP_BUNDLED=(
 
 PATCHES=(
        "${FILESDIR}"/dolphin-2407-minizip.patch
+       # https://github.com/dolphin-emu/dolphin/pull/13727
+       "${FILESDIR}/${P}-fmt-12.patch"
 )
 
 add_bundled_licenses() {

diff --git a/games-emulation/dolphin/files/dolphin-2506-fmt-12.patch 
b/games-emulation/dolphin/files/dolphin-2506-fmt-12.patch
new file mode 100644
index 000000000000..dc4dd058312a
--- /dev/null
+++ b/games-emulation/dolphin/files/dolphin-2506-fmt-12.patch
@@ -0,0 +1,244 @@
+From 4b65cc9a4c51af4308f748b3e7bf25d80db83860 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Joshua=20Vanda=C3=ABle?= <[email protected]>
+Date: Wed, 4 Jun 2025 13:12:50 +0200
+Subject: [PATCH] fmt: Replace deprecated `fmt::localtime` usage with
+ `Common::LocalTime`
+
+---
+ Source/Core/AudioCommon/AudioCommon.cpp     |  8 ++++++--
+ Source/Core/Common/FatFsUtil.cpp            |  8 ++------
+ Source/Core/Common/SettingsHandler.cpp      |  3 +--
+ Source/Core/Common/TimeUtil.cpp             | 12 +++++++-----
+ Source/Core/Common/TimeUtil.h               |  2 +-
+ Source/Core/Core/Core.cpp                   | 14 ++++++++++----
+ Source/Core/Core/NetworkCaptureLogger.cpp   |  3 ++-
+ Source/Core/Core/State.cpp                  |  2 +-
+ Source/Core/VideoCommon/FrameDumpFFMpeg.cpp |  7 ++++++-
+ 9 files changed, 36 insertions(+), 23 deletions(-)
+
+diff --git a/Source/Core/AudioCommon/AudioCommon.cpp 
b/Source/Core/AudioCommon/AudioCommon.cpp
+index de046a9aab7d..1258e0fd7e02 100644
+--- a/Source/Core/AudioCommon/AudioCommon.cpp
++++ b/Source/Core/AudioCommon/AudioCommon.cpp
+@@ -16,6 +16,7 @@
+ #include "AudioCommon/WASAPIStream.h"
+ #include "Common/FileUtil.h"
+ #include "Common/Logging/Log.h"
++#include "Common/TimeUtil.h"
+ #include "Core/Config/MainSettings.h"
+ #include "Core/ConfigManager.h"
+ #include "Core/System.h"
+@@ -218,8 +219,11 @@ void StartAudioDump(Core::System& system)
+ 
+   std::string path_prefix = File::GetUserPath(D_DUMPAUDIO_IDX) + 
SConfig::GetInstance().GetGameID();
+ 
+-  std::string base_name =
+-      fmt::format("{}_{:%Y-%m-%d_%H-%M-%S}", path_prefix, 
fmt::localtime(start_time));
++  const auto local_time = Common::LocalTime(start_time);
++  if (!local_time)
++    return;
++
++  std::string base_name = fmt::format("{}_{:%Y-%m-%d_%H-%M-%S}", path_prefix, 
*local_time);
+ 
+   const std::string audio_file_name_dtk = fmt::format("{}_dtkdump.wav", 
base_name);
+   const std::string audio_file_name_dsp = fmt::format("{}_dspdump.wav", 
base_name);
+diff --git a/Source/Core/Common/FatFsUtil.cpp 
b/Source/Core/Common/FatFsUtil.cpp
+index 9c513d5e42b0..80e2c424b44a 100644
+--- a/Source/Core/Common/FatFsUtil.cpp
++++ b/Source/Core/Common/FatFsUtil.cpp
+@@ -25,6 +25,7 @@
+ #include "Common/Logging/Log.h"
+ #include "Common/ScopeGuard.h"
+ #include "Common/StringUtil.h"
++#include "Common/TimeUtil.h"
+ 
+ #include "Core/Config/MainSettings.h"
+ 
+@@ -95,12 +96,7 @@ int SDCardDiskIOCtl(File::IOFile* image, u8 pdrv, u8 cmd, 
void* buff)
+ u32 GetSystemTimeFAT()
+ {
+   const std::time_t time = std::time(nullptr);
+-  std::tm tm;
+-#ifdef _WIN32
+-  localtime_s(&tm, &time);
+-#else
+-  localtime_r(&time, &tm);
+-#endif
++  std::tm tm = *Common::LocalTime(time);
+ 
+   DWORD fattime = 0;
+   fattime |= (tm.tm_year - 80) << 25;
+diff --git a/Source/Core/Common/SettingsHandler.cpp 
b/Source/Core/Common/SettingsHandler.cpp
+index 6cc9f5a8fe34..b0faf6f6f03f 100644
+--- a/Source/Core/Common/SettingsHandler.cpp
++++ b/Source/Core/Common/SettingsHandler.cpp
+@@ -122,7 +122,6 @@ std::string SettingsWriter::GenerateSerialNumber()
+ 
+   // Must be 9 characters at most; otherwise the serial number will be 
rejected by SDK libraries,
+   // as there is a check to ensure the string length is strictly lower than 
10.
+-  // 3 for %j, 2 for %H, 2 for %M, 2 for %S.
+-  return fmt::format("{:%j%H%M%S}", fmt::localtime(t));
++  return fmt::format("{:09}", t % 1000000000);
+ }
+ }  // namespace Common
+diff --git a/Source/Core/Common/TimeUtil.cpp b/Source/Core/Common/TimeUtil.cpp
+index 39d989fb3fe4..93327e9136ce 100644
+--- a/Source/Core/Common/TimeUtil.cpp
++++ b/Source/Core/Common/TimeUtil.cpp
+@@ -2,23 +2,25 @@
+ // SPDX-License-Identifier: GPL-2.0-or-later
+ 
+ #include "Common/TimeUtil.h"
++#include "Common/Logging/Log.h"
+ 
+ #include <ctime>
+ #include <optional>
+ 
+ namespace Common
+ {
+-std::optional<std::tm> Localtime(std::time_t time)
++std::optional<std::tm> LocalTime(std::time_t time)
+ {
+   std::tm local_time;
+ #ifdef _MSC_VER
+   if (localtime_s(&local_time, &time) != 0)
+-    return std::nullopt;
+ #else
+-  std::tm* result = localtime_r(&time, &local_time);
+-  if (result != &local_time)
+-    return std::nullopt;
++  if (localtime_r(&time, &local_time) == NULL)
+ #endif
++  {
++    ERROR_LOG_FMT(COMMON, "Failed to convert time to local time: {}", 
std::strerror(errno));
++    return std::nullopt;
++  }
+   return local_time;
+ }
+ }  // Namespace Common
+diff --git a/Source/Core/Common/TimeUtil.h b/Source/Core/Common/TimeUtil.h
+index ff9ca02a12b7..3abb525e5eb8 100644
+--- a/Source/Core/Common/TimeUtil.h
++++ b/Source/Core/Common/TimeUtil.h
+@@ -9,5 +9,5 @@
+ namespace Common
+ {
+ // Threadsafe and error-checking variant of std::localtime()
+-std::optional<std::tm> Localtime(std::time_t time);
++std::optional<std::tm> LocalTime(std::time_t time);
+ }  // Namespace Common
+diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp
+index e80e382930d2..8fe5e3d353a9 100644
+--- a/Source/Core/Core/Core.cpp
++++ b/Source/Core/Core/Core.cpp
+@@ -8,6 +8,7 @@
+ #include <cstring>
+ #include <functional>
+ #include <mutex>
++#include <optional>
+ #include <queue>
+ #include <utility>
+ #include <variant>
+@@ -34,6 +35,7 @@
+ #include "Common/ScopeGuard.h"
+ #include "Common/StringUtil.h"
+ #include "Common/Thread.h"
++#include "Common/TimeUtil.h"
+ #include "Common/Version.h"
+ 
+ #include "Core/AchievementManager.h"
+@@ -737,15 +739,17 @@ static std::string GenerateScreenshotFolderPath()
+   return path;
+ }
+ 
+-static std::string GenerateScreenshotName()
++static std::optional<std::string> GenerateScreenshotName()
+ {
+   // append gameId, path only contains the folder here.
+   const std::string path_prefix =
+       GenerateScreenshotFolderPath() + SConfig::GetInstance().GetGameID();
+ 
+   const std::time_t cur_time = std::time(nullptr);
+-  const std::string base_name =
+-      fmt::format("{}_{:%Y-%m-%d_%H-%M-%S}", path_prefix, 
fmt::localtime(cur_time));
++  const auto local_time = Common::LocalTime(cur_time);
++  if (!local_time)
++    return std::nullopt;
++  const std::string base_name = fmt::format("{}_{:%Y-%m-%d_%H-%M-%S}", 
path_prefix, *local_time);
+ 
+   // First try a filename without any suffixes, if already exists then append 
increasing numbers
+   std::string name = fmt::format("{}.png", base_name);
+@@ -761,7 +765,9 @@ static std::string GenerateScreenshotName()
+ void SaveScreenShot()
+ {
+   const Core::CPUThreadGuard guard(Core::System::GetInstance());
+-  g_frame_dumper->SaveScreenshot(GenerateScreenshotName());
++  std::optional<std::string> name = GenerateScreenshotName();
++  if (name)
++    g_frame_dumper->SaveScreenshot(*name);
+ }
+ 
+ void SaveScreenShot(std::string_view name)
+diff --git a/Source/Core/Core/NetworkCaptureLogger.cpp 
b/Source/Core/Core/NetworkCaptureLogger.cpp
+index bc645a05c450..b6706fc59f95 100644
+--- a/Source/Core/Core/NetworkCaptureLogger.cpp
++++ b/Source/Core/Core/NetworkCaptureLogger.cpp
+@@ -16,6 +16,7 @@
+ #include "Common/Network.h"
+ #include "Common/PcapFile.h"
+ #include "Common/ScopeGuard.h"
++#include "Common/TimeUtil.h"
+ #include "Core/Config/MainSettings.h"
+ #include "Core/ConfigManager.h"
+ 
+@@ -82,7 +83,7 @@ PCAPSSLCaptureLogger::PCAPSSLCaptureLogger()
+ {
+   const std::string filepath =
+       fmt::format("{}{} {:%Y-%m-%d %Hh%Mm%Ss}.pcap", 
File::GetUserPath(D_DUMPSSL_IDX),
+-                  SConfig::GetInstance().GetGameID(), 
fmt::localtime(std::time(nullptr)));
++                  SConfig::GetInstance().GetGameID(), 
*Common::LocalTime(std::time(nullptr)));
+   m_file = std::make_unique<Common::PCAP>(
+       new File::IOFile(filepath, "wb", File::SharedAccess::Read), 
Common::PCAP::LinkType::Ethernet);
+ }
+diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp
+index 556aff170a93..f508fd202d45 100644
+--- a/Source/Core/Core/State.cpp
++++ b/Source/Core/Core/State.cpp
+@@ -281,7 +281,7 @@ static std::string SystemTimeAsDoubleToString(double time)
+ {
+   // revert adjustments from GetSystemTimeAsDouble() to get a normal Unix 
timestamp again
+   const time_t seconds = static_cast<time_t>(time) + DOUBLE_TIME_OFFSET;
+-  const auto local_time = Common::Localtime(seconds);
++  const auto local_time = Common::LocalTime(seconds);
+   if (!local_time)
+     return "";
+ 
+diff --git a/Source/Core/VideoCommon/FrameDumpFFMpeg.cpp 
b/Source/Core/VideoCommon/FrameDumpFFMpeg.cpp
+index 44ec0a6a27f7..e0e61529f732 100644
+--- a/Source/Core/VideoCommon/FrameDumpFFMpeg.cpp
++++ b/Source/Core/VideoCommon/FrameDumpFFMpeg.cpp
+@@ -2,6 +2,7 @@
+ // SPDX-License-Identifier: GPL-2.0-or-later
+ 
+ #include "VideoCommon/FrameDumpFFMpeg.h"
++#include "Common/TimeUtil.h"
+ 
+ #if defined(__FreeBSD__)
+ #define __STDC_CONSTANT_MACROS 1
+@@ -124,11 +125,15 @@ std::string GetDumpPath(const std::string& extension, 
std::time_t time, u32 inde
+   if (!dump_path.empty())
+     return dump_path;
+ 
++  const auto local_time = Common::LocalTime(time);
++  if (!local_time)
++    return "";
++
+   const std::string path_prefix =
+       File::GetUserPath(D_DUMPFRAMES_IDX) + 
SConfig::GetInstance().GetGameID();
+ 
+   const std::string base_name =
+-      fmt::format("{}_{:%Y-%m-%d_%H-%M-%S}_{}", path_prefix, 
fmt::localtime(time), index);
++      fmt::format("{}_{:%Y-%m-%d_%H-%M-%S}_{}", path_prefix, *local_time, 
index);
+ 
+   const std::string path = fmt::format("{}.{}", base_name, extension);
+ 

Reply via email to