519 changes: 518 additions & 1 deletion Externals/fmt/ChangeLog.rst

Large diffs are not rendered by default.

10 changes: 6 additions & 4 deletions Externals/fmt/README.rst
Expand Up @@ -12,9 +12,6 @@
.. image:: https://github.com/fmtlib/fmt/workflows/windows/badge.svg
:target: https://github.com/fmtlib/fmt/actions?query=workflow%3Awindows

.. image:: https://ci.appveyor.com/api/projects/status/ehjkiefde6gucy1v?svg=true
:target: https://ci.appveyor.com/project/vitaut/fmt

.. image:: https://oss-fuzz-build-logs.storage.googleapis.com/badges/fmt.svg
:alt: fmt is continuously fuzzed at oss-fuzz
:target: https://bugs.chromium.org/p/oss-fuzz/issues/list?\
Expand All @@ -33,6 +30,8 @@ help victims of the war in Ukraine: https://www.stopputin.net/.

`Documentation <https://fmt.dev>`__

`Cheat Sheets <https://hackingcpp.com/cpp/libs/fmt.html>`__

Q&A: ask questions on `StackOverflow with the tag fmt
<https://stackoverflow.com/questions/tagged/fmt>`_.

Expand Down Expand Up @@ -342,9 +341,12 @@ Projects using this library

* `Folly <https://github.com/facebook/folly>`_: Facebook open-source library

* `GemRB <https://gemrb.org/>`_: a portable open-source implementation of
Bioware’s Infinity Engine

* `Grand Mountain Adventure
<https://store.steampowered.com/app/1247360/Grand_Mountain_Adventure/>`_:
A beautiful open-world ski & snowboarding game
a beautiful open-world ski & snowboarding game

* `HarpyWar/pvpgn <https://github.com/pvpgn/pvpgn-server>`_:
Player vs Player Gaming Network with tweaks
Expand Down
2 changes: 1 addition & 1 deletion Externals/fmt/fmt.vcxproj
Expand Up @@ -32,11 +32,11 @@
<ClInclude Include="include/fmt/core.h" />
<ClInclude Include="include/fmt/format-inl.h" />
<ClInclude Include="include/fmt/format.h" />
<ClInclude Include="include/fmt/locale.h" />
<ClInclude Include="include/fmt/os.h" />
<ClInclude Include="include/fmt/ostream.h" />
<ClInclude Include="include/fmt/printf.h" />
<ClInclude Include="include/fmt/ranges.h" />
<ClInclude Include="include/fmt/std.h" />
<ClInclude Include="include/fmt/xchar.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
Expand Down
54 changes: 21 additions & 33 deletions Externals/fmt/include/fmt/chrono.h
Expand Up @@ -203,7 +203,7 @@ To safe_duration_cast(std::chrono::duration<FromRep, FromPeriod> from,
}
const auto min1 =
(std::numeric_limits<IntermediateRep>::min)() / Factor::num;
if (count < min1) {
if (!std::is_unsigned<IntermediateRep>::value && count < min1) {
ec = 1;
return {};
}
Expand Down Expand Up @@ -345,7 +345,7 @@ auto write_encoded_tm_str(OutputIt out, string_view in, const std::locale& loc)
if (detail::is_utf8() && loc != get_classic_locale()) {
// char16_t and char32_t codecvts are broken in MSVC (linkage errors) and
// gcc-4.
#if FMT_MSC_VER != 0 || \
#if FMT_MSC_VERSION != 0 || \
(defined(__GLIBCXX__) && !defined(_GLIBCXX_USE_DUAL_ABI))
// The _GLIBCXX_USE_DUAL_ABI macro is always defined in libstdc++ from gcc-5
// and newer.
Expand Down Expand Up @@ -469,7 +469,7 @@ inline std::tm localtime(std::time_t time) {

bool fallback(int res) { return res == 0; }

#if !FMT_MSC_VER
#if !FMT_MSC_VERSION
bool fallback(detail::null<>) {
using namespace fmt::detail;
std::tm* tm = std::localtime(&time_);
Expand Down Expand Up @@ -515,7 +515,7 @@ inline std::tm gmtime(std::time_t time) {

bool fallback(int res) { return res == 0; }

#if !FMT_MSC_VER
#if !FMT_MSC_VERSION
bool fallback(detail::null<>) {
std::tm* tm = std::gmtime(&time_);
if (tm) tm_ = *tm;
Expand Down Expand Up @@ -1396,7 +1396,8 @@ inline bool isfinite(T) {
// Converts value to Int and checks that it's in the range [0, upper).
template <typename T, typename Int, FMT_ENABLE_IF(std::is_integral<T>::value)>
inline Int to_nonnegative_int(T value, Int upper) {
FMT_ASSERT(value >= 0 && to_unsigned(value) <= to_unsigned(upper),
FMT_ASSERT(std::is_unsigned<Int>::value ||
(value >= 0 && to_unsigned(value) <= to_unsigned(upper)),
"invalid value");
(void)upper;
return static_cast<Int>(value);
Expand Down Expand Up @@ -1466,8 +1467,7 @@ inline std::chrono::duration<Rep, std::milli> get_milliseconds(
// C++20 spec. If more than 18 fractional digits are required then returns 6 for
// microseconds precision.
template <long long Num, long long Den, int N = 0,
bool Enabled =
(N < 19) && (Num <= std::numeric_limits<long long>::max() / 10)>
bool Enabled = (N < 19) && (Num <= max_value<long long>() / 10)>
struct count_fractional_digits {
static constexpr int value =
Num % Den == 0 ? N : count_fractional_digits<Num * 10, Den, N + 1>::value;
Expand Down Expand Up @@ -1777,7 +1777,7 @@ struct chrono_formatter {
format_to(std::back_inserter(buf), runtime("{:.{}f}"),
std::fmod(val * static_cast<rep>(Period::num) /
static_cast<rep>(Period::den),
60),
static_cast<rep>(60)),
num_fractional_digits);
if (negative) *out++ = '-';
if (buf.size() < 2 || buf[1] == '.') *out++ = '0';
Expand Down Expand Up @@ -2002,29 +2002,18 @@ template <typename Char, typename Duration>
struct formatter<std::chrono::time_point<std::chrono::system_clock, Duration>,
Char> : formatter<std::tm, Char> {
FMT_CONSTEXPR formatter() {
this->do_parse(default_specs,
default_specs + sizeof(default_specs) / sizeof(Char));
}

template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
return this->do_parse(ctx.begin(), ctx.end(), true);
basic_string_view<Char> default_specs =
detail::string_literal<Char, '%', 'F', ' ', '%', 'T'>{};
this->do_parse(default_specs.begin(), default_specs.end());
}

template <typename FormatContext>
auto format(std::chrono::time_point<std::chrono::system_clock> val,
FormatContext& ctx) const -> decltype(ctx.out()) {
return formatter<std::tm, Char>::format(localtime(val), ctx);
}

static constexpr const Char default_specs[] = {'%', 'F', ' ', '%', 'T'};
};

template <typename Char, typename Duration>
constexpr const Char
formatter<std::chrono::time_point<std::chrono::system_clock, Duration>,
Char>::default_specs[];

template <typename Char> struct formatter<std::tm, Char> {
private:
enum class spec {
Expand All @@ -2036,13 +2025,18 @@ template <typename Char> struct formatter<std::tm, Char> {
basic_string_view<Char> specs;

protected:
template <typename It>
FMT_CONSTEXPR auto do_parse(It begin, It end, bool with_default = false)
-> It {
template <typename It> FMT_CONSTEXPR auto do_parse(It begin, It end) -> It {
if (begin != end && *begin == ':') ++begin;
end = detail::parse_chrono_format(begin, end, detail::tm_format_checker());
if (!with_default || end != begin)
specs = {begin, detail::to_unsigned(end - begin)};
// Replace default spec only if the new spec is not empty.
if (end != begin) specs = {begin, detail::to_unsigned(end - begin)};
return end;
}

public:
FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx)
-> decltype(ctx.begin()) {
auto end = this->do_parse(ctx.begin(), ctx.end());
// basic_string_view<>::compare isn't constexpr before C++17.
if (specs.size() == 2 && specs[0] == Char('%')) {
if (specs[1] == Char('F'))
Expand All @@ -2053,12 +2047,6 @@ template <typename Char> struct formatter<std::tm, Char> {
return end;
}

public:
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
return this->do_parse(ctx.begin(), ctx.end());
}

template <typename FormatContext>
auto format(const std::tm& tm, FormatContext& ctx) const
-> decltype(ctx.out()) {
Expand Down
61 changes: 9 additions & 52 deletions Externals/fmt/include/fmt/color.h
Expand Up @@ -10,13 +10,6 @@

#include "format.h"

// __declspec(deprecated) is broken in some MSVC versions.
#if FMT_MSC_VER
# define FMT_DEPRECATED_NONMSVC
#else
# define FMT_DEPRECATED_NONMSVC FMT_DEPRECATED
#endif

FMT_BEGIN_NAMESPACE
FMT_MODULE_EXPORT_BEGIN

Expand Down Expand Up @@ -270,16 +263,6 @@ class text_style {
return lhs |= rhs;
}

FMT_DEPRECATED_NONMSVC FMT_CONSTEXPR text_style& operator&=(
const text_style& rhs) {
return and_assign(rhs);
}

FMT_DEPRECATED_NONMSVC friend FMT_CONSTEXPR text_style
operator&(text_style lhs, const text_style& rhs) {
return lhs.and_assign(rhs);
}

FMT_CONSTEXPR bool has_foreground() const noexcept {
return set_foreground_color;
}
Expand Down Expand Up @@ -315,36 +298,9 @@ class text_style {
}
}

// DEPRECATED!
FMT_CONSTEXPR text_style& and_assign(const text_style& rhs) {
if (!set_foreground_color) {
set_foreground_color = rhs.set_foreground_color;
foreground_color = rhs.foreground_color;
} else if (rhs.set_foreground_color) {
if (!foreground_color.is_rgb || !rhs.foreground_color.is_rgb)
FMT_THROW(format_error("can't AND a terminal color"));
foreground_color.value.rgb_color &= rhs.foreground_color.value.rgb_color;
}

if (!set_background_color) {
set_background_color = rhs.set_background_color;
background_color = rhs.background_color;
} else if (rhs.set_background_color) {
if (!background_color.is_rgb || !rhs.background_color.is_rgb)
FMT_THROW(format_error("can't AND a terminal color"));
background_color.value.rgb_color &= rhs.background_color.value.rgb_color;
}

ems = static_cast<emphasis>(static_cast<uint8_t>(ems) &
static_cast<uint8_t>(rhs.ems));
return *this;
}

friend FMT_CONSTEXPR_DECL text_style
fg(detail::color_type foreground) noexcept;
friend FMT_CONSTEXPR text_style fg(detail::color_type foreground) noexcept;

friend FMT_CONSTEXPR_DECL text_style
bg(detail::color_type background) noexcept;
friend FMT_CONSTEXPR text_style bg(detail::color_type background) noexcept;

detail::color_type foreground_color;
detail::color_type background_color;
Expand Down Expand Up @@ -527,7 +483,7 @@ template <typename S, typename Char = char_t<S>>
void vprint(std::FILE* f, const text_style& ts, const S& format,
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
basic_memory_buffer<Char> buf;
detail::vformat_to(buf, ts, to_string_view(format), args);
detail::vformat_to(buf, ts, detail::to_string_view(format), args);
if (detail::is_utf8()) {
detail::print(f, basic_string_view<Char>(buf.begin(), buf.size()));
} else {
Expand Down Expand Up @@ -577,7 +533,7 @@ inline std::basic_string<Char> vformat(
const text_style& ts, const S& format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
basic_memory_buffer<Char> buf;
detail::vformat_to(buf, ts, to_string_view(format_str), args);
detail::vformat_to(buf, ts, detail::to_string_view(format_str), args);
return fmt::to_string(buf);
}

Expand All @@ -596,7 +552,7 @@ inline std::basic_string<Char> vformat(
template <typename S, typename... Args, typename Char = char_t<S>>
inline std::basic_string<Char> format(const text_style& ts, const S& format_str,
const Args&... args) {
return fmt::vformat(ts, to_string_view(format_str),
return fmt::vformat(ts, detail::to_string_view(format_str),
fmt::make_format_args<buffer_context<Char>>(args...));
}

Expand Down Expand Up @@ -631,7 +587,7 @@ template <typename OutputIt, typename S, typename... Args,
inline auto format_to(OutputIt out, const text_style& ts, const S& format_str,
Args&&... args) ->
typename std::enable_if<enable, OutputIt>::type {
return vformat_to(out, ts, to_string_view(format_str),
return vformat_to(out, ts, detail::to_string_view(format_str),
fmt::make_format_args<buffer_context<char_t<S>>>(args...));
}

Expand Down Expand Up @@ -678,8 +634,9 @@ struct formatter<detail::styled_arg<T>, Char> : formatter<T, Char> {
**Example**::
fmt::print("Elapsed time: {s:.2f} seconds",
fmt::styled(1.23, fmt::fg(fmt::color::green) | fmt::bg(fmt::color::blue)));
fmt::print("Elapsed time: {0:.2f} seconds",
fmt::styled(1.23, fmt::fg(fmt::color::green) |
fmt::bg(fmt::color::blue)));
\endrst
*/
template <typename T>
Expand Down
33 changes: 21 additions & 12 deletions Externals/fmt/include/fmt/compile.h
Expand Up @@ -14,8 +14,8 @@ FMT_BEGIN_NAMESPACE
namespace detail {

template <typename Char, typename InputIt>
inline counting_iterator copy_str(InputIt begin, InputIt end,
counting_iterator it) {
FMT_CONSTEXPR inline counting_iterator copy_str(InputIt begin, InputIt end,
counting_iterator it) {
return it + (end - begin);
}

Expand Down Expand Up @@ -123,7 +123,7 @@ struct is_compiled_string : std::is_base_of<compiled_string, S> {};
# define FMT_COMPILE(s) FMT_STRING(s)
#endif

#if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS
#if FMT_USE_NONTYPE_TEMPLATE_ARGS
template <typename Char, size_t N,
fmt::detail_exported::fixed_string<Char, N> Str>
struct udl_compiled_string : compiled_string {
Expand Down Expand Up @@ -337,10 +337,11 @@ template <typename T, typename Char>
constexpr parse_specs_result<T, Char> parse_specs(basic_string_view<Char> str,
size_t pos, int next_arg_id) {
str.remove_prefix(pos);
auto ctx = basic_format_parse_context<Char>(str, {}, next_arg_id);
auto ctx = compile_parse_context<Char>(str, max_value<int>(), nullptr, {},
next_arg_id);
auto f = formatter<T, Char>();
auto end = f.parse(ctx);
return {f, pos + fmt::detail::to_unsigned(end - str.data()) + 1,
return {f, pos + fmt::detail::to_unsigned(end - str.data()),
next_arg_id == 0 ? manual_indexing_id : ctx.next_arg_id()};
}

Expand Down Expand Up @@ -396,13 +397,20 @@ constexpr auto parse_replacement_field_then_tail(S format_str) {
return parse_tail<Args, END_POS + 1, NEXT_ID>(
field<char_type, typename field_type<T>::type, ARG_INDEX>(),
format_str);
} else if constexpr (c == ':') {
} else if constexpr (c != ':') {
FMT_THROW(format_error("expected ':'"));
} else {
constexpr auto result = parse_specs<typename field_type<T>::type>(
str, END_POS + 1, NEXT_ID == manual_indexing_id ? 0 : NEXT_ID);
return parse_tail<Args, result.end, result.next_arg_id>(
spec_field<char_type, typename field_type<T>::type, ARG_INDEX>{
result.fmt},
format_str);
if constexpr (result.end >= str.size() || str[result.end] != '}') {
FMT_THROW(format_error("expected '}'"));
return 0;
} else {
return parse_tail<Args, result.end + 1, result.next_arg_id>(
spec_field<char_type, typename field_type<T>::type, ARG_INDEX>{
result.fmt},
format_str);
}
}
}

Expand Down Expand Up @@ -567,7 +575,8 @@ format_to_n_result<OutputIt> format_to_n(OutputIt out, size_t n,

template <typename S, typename... Args,
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
size_t formatted_size(const S& format_str, const Args&... args) {
FMT_CONSTEXPR20 size_t formatted_size(const S& format_str,
const Args&... args) {
return fmt::format_to(detail::counting_iterator(), format_str, args...)
.count();
}
Expand All @@ -586,7 +595,7 @@ void print(const S& format_str, const Args&... args) {
print(stdout, format_str, args...);
}

#if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS
#if FMT_USE_NONTYPE_TEMPLATE_ARGS
inline namespace literals {
template <detail_exported::fixed_string Str> constexpr auto operator""_cf() {
using char_t = remove_cvref_t<decltype(Str.data[0])>;
Expand Down
611 changes: 320 additions & 291 deletions Externals/fmt/include/fmt/core.h

Large diffs are not rendered by default.

919 changes: 24 additions & 895 deletions Externals/fmt/include/fmt/format-inl.h

Large diffs are not rendered by default.

1,295 changes: 1,034 additions & 261 deletions Externals/fmt/include/fmt/format.h

Large diffs are not rendered by default.

2 changes: 0 additions & 2 deletions Externals/fmt/include/fmt/locale.h

This file was deleted.

5 changes: 1 addition & 4 deletions Externals/fmt/include/fmt/os.h
Expand Up @@ -260,10 +260,7 @@ class buffered_file {
// Returns the pointer to a FILE object representing this file.
FILE* get() const noexcept { return file_; }

// We place parentheses around fileno to workaround a bug in some versions
// of MinGW that define fileno as a macro.
// DEPRECATED! Rename to descriptor to avoid issues with macros.
FMT_API int(fileno)() const;
FMT_API int descriptor() const;

void vprint(string_view format_str, format_args args) {
fmt::vprint(file_, format_str, args);
Expand Down
134 changes: 89 additions & 45 deletions Externals/fmt/include/fmt/ostream.h
Expand Up @@ -10,6 +10,12 @@

#include <fstream>
#include <ostream>
#if defined(_WIN32) && defined(__GLIBCXX__)
# include <ext/stdio_filebuf.h>
# include <ext/stdio_sync_filebuf.h>
#elif defined(_WIN32) && defined(_LIBCPP_VERSION)
# include <__std_stream>
#endif

#include "format.h"

Expand Down Expand Up @@ -51,52 +57,57 @@ struct is_streamable<
(std::is_convertible<T, int>::value && !std::is_enum<T>::value)>>
: std::false_type {};

template <typename Char> FILE* get_file(std::basic_filebuf<Char>&) {
return nullptr;
}

struct dummy_filebuf {
FILE* _Myfile;
};
template <typename T, typename U = int> struct ms_filebuf {
using type = dummy_filebuf;
};
template <typename T> struct ms_filebuf<T, decltype(T::_Myfile, 0)> {
using type = T;
};
using filebuf_type = ms_filebuf<std::filebuf>::type;

FILE* get_file(filebuf_type& buf);

// Generate a unique explicit instantion in every translation unit using a tag
// type in an anonymous namespace.
namespace {
struct filebuf_access_tag {};
struct file_access_tag {};
} // namespace
template <typename Tag, typename FileMemberPtr, FileMemberPtr file>
class filebuf_access {
friend FILE* get_file(filebuf_type& buf) { return buf.*file; }
template <class Tag, class BufType, FILE* BufType::*FileMemberPtr>
class file_access {
friend auto get_file(BufType& obj) -> FILE* { return obj.*FileMemberPtr; }
};
template class filebuf_access<filebuf_access_tag,
decltype(&filebuf_type::_Myfile),
&filebuf_type::_Myfile>;

inline bool write(std::filebuf& buf, fmt::string_view data) {
print(get_file(buf), data);
return true;
#if FMT_MSC_VERSION
template class file_access<file_access_tag, std::filebuf,
&std::filebuf::_Myfile>;
auto get_file(std::filebuf&) -> FILE*;
#elif defined(_WIN32) && defined(_LIBCPP_VERSION)
template class file_access<file_access_tag, std::__stdoutbuf<char>,
&std::__stdoutbuf<char>::__file_>;
auto get_file(std::__stdoutbuf<char>&) -> FILE*;
#endif

inline bool write_ostream_unicode(std::ostream& os, fmt::string_view data) {
#if FMT_MSC_VERSION
if (auto* buf = dynamic_cast<std::filebuf*>(os.rdbuf()))
if (FILE* f = get_file(*buf)) return write_console(f, data);
#elif defined(_WIN32) && defined(__GLIBCXX__)
auto* rdbuf = os.rdbuf();
FILE* c_file;
if (auto* fbuf = dynamic_cast<__gnu_cxx::stdio_sync_filebuf<char>*>(rdbuf))
c_file = fbuf->file();
else if (auto* fbuf = dynamic_cast<__gnu_cxx::stdio_filebuf<char>*>(rdbuf))
c_file = fbuf->file();
else
return false;
if (c_file) return write_console(c_file, data);
#elif defined(_WIN32) && defined(_LIBCPP_VERSION)
if (auto* buf = dynamic_cast<std::__stdoutbuf<char>*>(os.rdbuf()))
if (FILE* f = get_file(*buf)) return write_console(f, data);
#else
ignore_unused(os, data);
#endif
return false;
}
inline bool write(std::wfilebuf&, fmt::basic_string_view<wchar_t>) {
inline bool write_ostream_unicode(std::wostream&,
fmt::basic_string_view<wchar_t>) {
return false;
}

// Write the content of buf to os.
// It is a separate function rather than a part of vprint to simplify testing.
template <typename Char>
void write_buffer(std::basic_ostream<Char>& os, buffer<Char>& buf) {
if (const_check(FMT_MSC_VER)) {
auto filebuf = dynamic_cast<std::basic_filebuf<Char>*>(os.rdbuf());
if (filebuf && write(*filebuf, {buf.data(), buf.size()})) return;
}
const Char* buf_data = buf.data();
using unsigned_streamsize = std::make_unsigned<std::streamsize>::type;
unsigned_streamsize size = buf.size();
Expand All @@ -120,11 +131,16 @@ void format_value(buffer<Char>& buf, const T& value,
output << value;
output.exceptions(std::ios_base::failbit | std::ios_base::badbit);
}

template <typename T> struct streamed_view { const T& value; };

} // namespace detail

// Formats an object of type T that has an overloaded ostream operator<<.
template <typename Char>
struct basic_ostream_formatter : formatter<basic_string_view<Char>, Char> {
void set_debug_format() = delete;

template <typename T, typename OutputIt>
auto format(const T& value, basic_format_context<OutputIt, Char>& ctx) const
-> OutputIt {
Expand All @@ -137,31 +153,56 @@ struct basic_ostream_formatter : formatter<basic_string_view<Char>, Char> {

using ostream_formatter = basic_ostream_formatter<char>;

template <typename T, typename Char>
struct formatter<detail::streamed_view<T>, Char>
: basic_ostream_formatter<Char> {
template <typename OutputIt>
auto format(detail::streamed_view<T> view,
basic_format_context<OutputIt, Char>& ctx) const -> OutputIt {
return basic_ostream_formatter<Char>::format(view.value, ctx);
}
};

/**
\rst
Returns a view that formats `value` via an ostream ``operator<<``.
**Example**::
fmt::print("Current thread id: {}\n",
fmt::streamed(std::this_thread::get_id()));
\endrst
*/
template <typename T>
auto streamed(const T& value) -> detail::streamed_view<T> {
return {value};
}

namespace detail {

// Formats an object of type T that has an overloaded ostream operator<<.
template <typename T, typename Char>
struct fallback_formatter<T, Char, enable_if_t<is_streamable<T, Char>::value>>
: basic_ostream_formatter<Char> {
using basic_ostream_formatter<Char>::format;
// DEPRECATED!
template <typename OutputIt>
auto format(const T& value, basic_printf_context<OutputIt, Char>& ctx) const
-> OutputIt {
auto buffer = basic_memory_buffer<Char>();
format_value(buffer, value, ctx.locale());
return std::copy(buffer.begin(), buffer.end(), ctx.out());
}
};

inline void vprint_directly(std::ostream& os, string_view format_str,
format_args args) {
auto buffer = memory_buffer();
detail::vformat_to(buffer, format_str, args);
detail::write_buffer(os, buffer);
}

} // namespace detail

FMT_MODULE_EXPORT
template <typename Char>
FMT_MODULE_EXPORT template <typename Char>
void vprint(std::basic_ostream<Char>& os,
basic_string_view<type_identity_t<Char>> format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
auto buffer = basic_memory_buffer<Char>();
detail::vformat_to(buffer, format_str, args);
if (detail::write_ostream_unicode(os, {buffer.data(), buffer.size()})) return;
detail::write_buffer(os, buffer);
}

Expand All @@ -174,10 +215,13 @@ void vprint(std::basic_ostream<Char>& os,
fmt::print(cerr, "Don't {}!", "panic");
\endrst
*/
FMT_MODULE_EXPORT
template <typename... T>
FMT_MODULE_EXPORT template <typename... T>
void print(std::ostream& os, format_string<T...> fmt, T&&... args) {
vprint(os, fmt, fmt::make_format_args(args...));
const auto& vargs = fmt::make_format_args(args...);
if (detail::is_utf8())
vprint(os, fmt, vargs);
else
detail::vprint_directly(os, fmt, vargs);
}

FMT_MODULE_EXPORT
Expand Down
31 changes: 7 additions & 24 deletions Externals/fmt/include/fmt/printf.h
Expand Up @@ -10,7 +10,6 @@

#include <algorithm> // std::max
#include <limits> // std::numeric_limits
#include <ostream>

#include "format.h"

Expand Down Expand Up @@ -561,7 +560,7 @@ inline auto vsprintf(
basic_format_args<basic_printf_context_t<type_identity_t<Char>>> args)
-> std::basic_string<Char> {
basic_memory_buffer<Char> buffer;
vprintf(buffer, to_string_view(fmt), args);
vprintf(buffer, detail::to_string_view(fmt), args);
return to_string(buffer);
}

Expand All @@ -578,7 +577,8 @@ template <typename S, typename... T,
typename Char = enable_if_t<detail::is_string<S>::value, char_t<S>>>
inline auto sprintf(const S& fmt, const T&... args) -> std::basic_string<Char> {
using context = basic_printf_context_t<Char>;
return vsprintf(to_string_view(fmt), fmt::make_format_args<context>(args...));
return vsprintf(detail::to_string_view(fmt),
fmt::make_format_args<context>(args...));
}

template <typename S, typename Char = char_t<S>>
Expand All @@ -587,7 +587,7 @@ inline auto vfprintf(
basic_format_args<basic_printf_context_t<type_identity_t<Char>>> args)
-> int {
basic_memory_buffer<Char> buffer;
vprintf(buffer, to_string_view(fmt), args);
vprintf(buffer, detail::to_string_view(fmt), args);
size_t size = buffer.size();
return std::fwrite(buffer.data(), sizeof(Char), size, f) < size
? -1
Expand All @@ -606,7 +606,7 @@ inline auto vfprintf(
template <typename S, typename... T, typename Char = char_t<S>>
inline auto fprintf(std::FILE* f, const S& fmt, const T&... args) -> int {
using context = basic_printf_context_t<Char>;
return vfprintf(f, to_string_view(fmt),
return vfprintf(f, detail::to_string_view(fmt),
fmt::make_format_args<context>(args...));
}

Expand All @@ -615,7 +615,7 @@ inline auto vprintf(
const S& fmt,
basic_format_args<basic_printf_context_t<type_identity_t<Char>>> args)
-> int {
return vfprintf(stdout, to_string_view(fmt), args);
return vfprintf(stdout, detail::to_string_view(fmt), args);
}

/**
Expand All @@ -630,27 +630,10 @@ inline auto vprintf(
template <typename S, typename... T, FMT_ENABLE_IF(detail::is_string<S>::value)>
inline auto printf(const S& fmt, const T&... args) -> int {
return vprintf(
to_string_view(fmt),
detail::to_string_view(fmt),
fmt::make_format_args<basic_printf_context_t<char_t<S>>>(args...));
}

template <typename S, typename Char = char_t<S>>
FMT_DEPRECATED auto vfprintf(
std::basic_ostream<Char>& os, const S& fmt,
basic_format_args<basic_printf_context_t<type_identity_t<Char>>> args)
-> int {
basic_memory_buffer<Char> buffer;
vprintf(buffer, to_string_view(fmt), args);
os.write(buffer.data(), static_cast<std::streamsize>(buffer.size()));
return static_cast<int>(buffer.size());
}
template <typename S, typename... T, typename Char = char_t<S>>
FMT_DEPRECATED auto fprintf(std::basic_ostream<Char>& os, const S& fmt,
const T&... args) -> int {
return vfprintf(os, to_string_view(fmt),
fmt::make_format_args<basic_printf_context_t<Char>>(args...));
}

FMT_MODULE_EXPORT_END
FMT_END_NAMESPACE

Expand Down
310 changes: 223 additions & 87 deletions Externals/fmt/include/fmt/ranges.h

Large diffs are not rendered by default.

171 changes: 171 additions & 0 deletions Externals/fmt/include/fmt/std.h
@@ -0,0 +1,171 @@
// Formatting library for C++ - formatters for standard library types
//
// Copyright (c) 2012 - present, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.

#ifndef FMT_STD_H_
#define FMT_STD_H_

#include <thread>
#include <type_traits>
#include <utility>

#include "ostream.h"

#if FMT_HAS_INCLUDE(<version>)
# include <version>
#endif
// Checking FMT_CPLUSPLUS for warning suppression in MSVC.
#if FMT_CPLUSPLUS >= 201703L
# if FMT_HAS_INCLUDE(<filesystem>)
# include <filesystem>
# endif
# if FMT_HAS_INCLUDE(<variant>)
# include <variant>
# endif
#endif

#ifdef __cpp_lib_filesystem
FMT_BEGIN_NAMESPACE

namespace detail {

template <typename Char>
void write_escaped_path(basic_memory_buffer<Char>& quoted,
const std::filesystem::path& p) {
write_escaped_string<Char>(std::back_inserter(quoted), p.string<Char>());
}
# ifdef _WIN32
template <>
inline void write_escaped_path<char>(basic_memory_buffer<char>& quoted,
const std::filesystem::path& p) {
auto s = p.u8string();
write_escaped_string<char>(
std::back_inserter(quoted),
string_view(reinterpret_cast<const char*>(s.c_str()), s.size()));
}
# endif
template <>
inline void write_escaped_path<std::filesystem::path::value_type>(
basic_memory_buffer<std::filesystem::path::value_type>& quoted,
const std::filesystem::path& p) {
write_escaped_string<std::filesystem::path::value_type>(
std::back_inserter(quoted), p.native());
}

} // namespace detail

template <typename Char>
struct formatter<std::filesystem::path, Char>
: formatter<basic_string_view<Char>> {
template <typename FormatContext>
auto format(const std::filesystem::path& p, FormatContext& ctx) const ->
typename FormatContext::iterator {
basic_memory_buffer<Char> quoted;
detail::write_escaped_path(quoted, p);
return formatter<basic_string_view<Char>>::format(
basic_string_view<Char>(quoted.data(), quoted.size()), ctx);
}
};
FMT_END_NAMESPACE
#endif

FMT_BEGIN_NAMESPACE
template <typename Char>
struct formatter<std::thread::id, Char> : basic_ostream_formatter<Char> {};
FMT_END_NAMESPACE

#ifdef __cpp_lib_variant
FMT_BEGIN_NAMESPACE
template <typename Char> struct formatter<std::monostate, Char> {
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
return ctx.begin();
}

template <typename FormatContext>
auto format(const std::monostate&, FormatContext& ctx) const
-> decltype(ctx.out()) {
auto out = ctx.out();
out = detail::write<Char>(out, "monostate");
return out;
}
};

namespace detail {

template <typename T>
using variant_index_sequence =
std::make_index_sequence<std::variant_size<T>::value>;

// variant_size and variant_alternative check.
template <typename T, typename U = void>
struct is_variant_like_ : std::false_type {};
template <typename T>
struct is_variant_like_<T, std::void_t<decltype(std::variant_size<T>::value)>>
: std::true_type {};

// formattable element check
template <typename T, typename C> class is_variant_formattable_ {
template <std::size_t... I>
static std::conjunction<
is_formattable<std::variant_alternative_t<I, T>, C>...>
check(std::index_sequence<I...>);

public:
static constexpr const bool value =
decltype(check(variant_index_sequence<T>{}))::value;
};

template <typename Char, typename OutputIt, typename T>
auto write_variant_alternative(OutputIt out, const T& v) -> OutputIt {
if constexpr (is_string<T>::value)
return write_escaped_string<Char>(out, detail::to_string_view(v));
else if constexpr (std::is_same_v<T, Char>)
return write_escaped_char(out, v);
else
return write<Char>(out, v);
}

} // namespace detail

template <typename T> struct is_variant_like {
static constexpr const bool value = detail::is_variant_like_<T>::value;
};

template <typename T, typename C> struct is_variant_formattable {
static constexpr const bool value =
detail::is_variant_formattable_<T, C>::value;
};

template <typename Variant, typename Char>
struct formatter<
Variant, Char,
std::enable_if_t<std::conjunction_v<
is_variant_like<Variant>, is_variant_formattable<Variant, Char>>>> {
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
return ctx.begin();
}

template <typename FormatContext>
auto format(const Variant& value, FormatContext& ctx) const
-> decltype(ctx.out()) {
auto out = ctx.out();

out = detail::write<Char>(out, "variant(");
std::visit(
[&](const auto& v) {
out = detail::write_variant_alternative<Char>(out, v);
},
value);
*out++ = ')';
return out;
}
};
FMT_END_NAMESPACE
#endif

#endif // FMT_STD_H_
45 changes: 19 additions & 26 deletions Externals/fmt/include/fmt/xchar.h
Expand Up @@ -9,7 +9,6 @@
#define FMT_XCHAR_H_

#include <cwchar>
#include <tuple>

#include "format.h"

Expand All @@ -30,9 +29,11 @@ using wmemory_buffer = basic_memory_buffer<wchar_t>;
#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
// Workaround broken conversion on older gcc.
template <typename... Args> using wformat_string = wstring_view;
inline auto runtime(wstring_view s) -> wstring_view { return s; }
#else
template <typename... Args>
using wformat_string = basic_format_string<wchar_t, type_identity_t<Args>...>;
inline auto runtime(wstring_view s) -> basic_runtime<wchar_t> { return {{s}}; }
#endif

template <> struct is_char<wchar_t> : std::true_type {};
Expand All @@ -47,12 +48,7 @@ constexpr format_arg_store<wformat_context, Args...> make_wformat_args(
}

inline namespace literals {
constexpr auto operator"" _format(const wchar_t* s, size_t n)
-> detail::udl_formatter<wchar_t> {
return {{s, n}};
}

#if FMT_USE_USER_DEFINED_LITERALS && !FMT_USE_NONTYPE_TEMPLATE_PARAMETERS
#if FMT_USE_USER_DEFINED_LITERALS && !FMT_USE_NONTYPE_TEMPLATE_ARGS
constexpr detail::udl_arg<wchar_t> operator"" _a(const wchar_t* s, size_t) {
return {s};
}
Expand Down Expand Up @@ -87,12 +83,18 @@ auto vformat(basic_string_view<Char> format_str,
return to_string(buffer);
}

template <typename... T>
auto format(wformat_string<T...> fmt, T&&... args) -> std::wstring {
return vformat(fmt::wstring_view(fmt), fmt::make_wformat_args(args...));
}

// Pass char_t as a default template parameter instead of using
// std::basic_string<char_t<S>> to reduce the symbol size.
template <typename S, typename... Args, typename Char = char_t<S>,
FMT_ENABLE_IF(!std::is_same<Char, char>::value)>
FMT_ENABLE_IF(!std::is_same<Char, char>::value &&
!std::is_same<Char, wchar_t>::value)>
auto format(const S& format_str, Args&&... args) -> std::basic_string<Char> {
return vformat(to_string_view(format_str),
return vformat(detail::to_string_view(format_str),
fmt::make_format_args<buffer_context<Char>>(args...));
}

Expand All @@ -103,7 +105,7 @@ inline auto vformat(
const Locale& loc, const S& format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args)
-> std::basic_string<Char> {
return detail::vformat(loc, to_string_view(format_str), args);
return detail::vformat(loc, detail::to_string_view(format_str), args);
}

template <typename Locale, typename S, typename... Args,
Expand All @@ -112,7 +114,7 @@ template <typename Locale, typename S, typename... Args,
detail::is_exotic_char<Char>::value)>
inline auto format(const Locale& loc, const S& format_str, Args&&... args)
-> std::basic_string<Char> {
return detail::vformat(loc, to_string_view(format_str),
return detail::vformat(loc, detail::to_string_view(format_str),
fmt::make_format_args<buffer_context<Char>>(args...));
}

Expand All @@ -123,7 +125,7 @@ auto vformat_to(OutputIt out, const S& format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args)
-> OutputIt {
auto&& buf = detail::get_buffer<Char>(out);
detail::vformat_to(buf, to_string_view(format_str), args);
detail::vformat_to(buf, detail::to_string_view(format_str), args);
return detail::get_iterator(buf);
}

Expand All @@ -132,20 +134,10 @@ template <typename OutputIt, typename S, typename... Args,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
detail::is_exotic_char<Char>::value)>
inline auto format_to(OutputIt out, const S& fmt, Args&&... args) -> OutputIt {
return vformat_to(out, to_string_view(fmt),
return vformat_to(out, detail::to_string_view(fmt),
fmt::make_format_args<buffer_context<Char>>(args...));
}

template <typename S, typename... Args, typename Char, size_t SIZE,
typename Allocator, FMT_ENABLE_IF(detail::is_string<S>::value)>
FMT_DEPRECATED auto format_to(basic_memory_buffer<Char, SIZE, Allocator>& buf,
const S& format_str, Args&&... args) ->
typename buffer_context<Char>::iterator {
detail::vformat_to(buf, to_string_view(format_str),
fmt::make_format_args<buffer_context<Char>>(args...), {});
return detail::buffer_appender<Char>(buf);
}

template <typename Locale, typename S, typename OutputIt, typename... Args,
typename Char = char_t<S>,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
Expand All @@ -155,7 +147,8 @@ inline auto vformat_to(
OutputIt out, const Locale& loc, const S& format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) -> OutputIt {
auto&& buf = detail::get_buffer<Char>(out);
vformat_to(buf, to_string_view(format_str), args, detail::locale_ref(loc));
vformat_to(buf, detail::to_string_view(format_str), args,
detail::locale_ref(loc));
return detail::get_iterator(buf);
}

Expand Down Expand Up @@ -190,15 +183,15 @@ template <typename OutputIt, typename S, typename... Args,
detail::is_exotic_char<Char>::value)>
inline auto format_to_n(OutputIt out, size_t n, const S& fmt,
const Args&... args) -> format_to_n_result<OutputIt> {
return vformat_to_n(out, n, to_string_view(fmt),
return vformat_to_n(out, n, detail::to_string_view(fmt),
fmt::make_format_args<buffer_context<Char>>(args...));
}

template <typename S, typename... Args, typename Char = char_t<S>,
FMT_ENABLE_IF(detail::is_exotic_char<Char>::value)>
inline auto formatted_size(const S& fmt, Args&&... args) -> size_t {
detail::counting_buffer<Char> buf;
detail::vformat_to(buf, to_string_view(fmt),
detail::vformat_to(buf, detail::to_string_view(fmt),
fmt::make_format_args<buffer_context<Char>>(args...));
return buf.count();
}
Expand Down
90 changes: 16 additions & 74 deletions Externals/fmt/src/format.cc
Expand Up @@ -10,96 +10,38 @@
FMT_BEGIN_NAMESPACE
namespace detail {

// DEPRECATED!
template <typename T = void> struct basic_data {
FMT_API static constexpr const char digits[100][2] = {
{'0', '0'}, {'0', '1'}, {'0', '2'}, {'0', '3'}, {'0', '4'}, {'0', '5'},
{'0', '6'}, {'0', '7'}, {'0', '8'}, {'0', '9'}, {'1', '0'}, {'1', '1'},
{'1', '2'}, {'1', '3'}, {'1', '4'}, {'1', '5'}, {'1', '6'}, {'1', '7'},
{'1', '8'}, {'1', '9'}, {'2', '0'}, {'2', '1'}, {'2', '2'}, {'2', '3'},
{'2', '4'}, {'2', '5'}, {'2', '6'}, {'2', '7'}, {'2', '8'}, {'2', '9'},
{'3', '0'}, {'3', '1'}, {'3', '2'}, {'3', '3'}, {'3', '4'}, {'3', '5'},
{'3', '6'}, {'3', '7'}, {'3', '8'}, {'3', '9'}, {'4', '0'}, {'4', '1'},
{'4', '2'}, {'4', '3'}, {'4', '4'}, {'4', '5'}, {'4', '6'}, {'4', '7'},
{'4', '8'}, {'4', '9'}, {'5', '0'}, {'5', '1'}, {'5', '2'}, {'5', '3'},
{'5', '4'}, {'5', '5'}, {'5', '6'}, {'5', '7'}, {'5', '8'}, {'5', '9'},
{'6', '0'}, {'6', '1'}, {'6', '2'}, {'6', '3'}, {'6', '4'}, {'6', '5'},
{'6', '6'}, {'6', '7'}, {'6', '8'}, {'6', '9'}, {'7', '0'}, {'7', '1'},
{'7', '2'}, {'7', '3'}, {'7', '4'}, {'7', '5'}, {'7', '6'}, {'7', '7'},
{'7', '8'}, {'7', '9'}, {'8', '0'}, {'8', '1'}, {'8', '2'}, {'8', '3'},
{'8', '4'}, {'8', '5'}, {'8', '6'}, {'8', '7'}, {'8', '8'}, {'8', '9'},
{'9', '0'}, {'9', '1'}, {'9', '2'}, {'9', '3'}, {'9', '4'}, {'9', '5'},
{'9', '6'}, {'9', '7'}, {'9', '8'}, {'9', '9'}};
FMT_API static constexpr const char hex_digits[] = "0123456789abcdef";
FMT_API static constexpr const char signs[4] = {0, '-', '+', ' '};
FMT_API static constexpr const char left_padding_shifts[5] = {31, 31, 0, 1,
0};
FMT_API static constexpr const char right_padding_shifts[5] = {0, 31, 0, 1,
0};
FMT_API static constexpr const unsigned prefixes[4] = {0, 0, 0x1000000u | '+',
0x1000000u | ' '};
};

#ifdef FMT_SHARED
// Required for -flto, -fivisibility=hidden and -shared to work
extern template struct basic_data<void>;
#endif

#if __cplusplus < 201703L
// DEPRECATED! These are here only for ABI compatiblity.
template <typename T> constexpr const char basic_data<T>::digits[][2];
template <typename T> constexpr const char basic_data<T>::hex_digits[];
template <typename T> constexpr const char basic_data<T>::signs[];
template <typename T> constexpr const char basic_data<T>::left_padding_shifts[];
template <typename T>
constexpr const char basic_data<T>::right_padding_shifts[];
template <typename T> constexpr const unsigned basic_data<T>::prefixes[];
#endif

template FMT_API dragonbox::decimal_fp<float> dragonbox::to_decimal(
float x) noexcept;
template FMT_API dragonbox::decimal_fp<double> dragonbox::to_decimal(
double x) noexcept;
} // namespace detail

// Workaround a bug in MSVC2013 that prevents instantiation of format_float.
int (*instantiate_format_float)(double, int, detail::float_specs,
detail::buffer<char>&) = detail::format_float;
template FMT_API auto dragonbox::to_decimal(float x) noexcept
-> dragonbox::decimal_fp<float>;
template FMT_API auto dragonbox::to_decimal(double x) noexcept
-> dragonbox::decimal_fp<double>;

#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
template FMT_API detail::locale_ref::locale_ref(const std::locale& loc);
template FMT_API std::locale detail::locale_ref::get<std::locale>() const;
template FMT_API locale_ref::locale_ref(const std::locale& loc);
template FMT_API auto locale_ref::get<std::locale>() const -> std::locale;
#endif

// Explicit instantiations for char.

template FMT_API auto detail::thousands_sep_impl(locale_ref)
template FMT_API auto thousands_sep_impl(locale_ref)
-> thousands_sep_result<char>;
template FMT_API char detail::decimal_point_impl(locale_ref);
template FMT_API auto decimal_point_impl(locale_ref) -> char;

template FMT_API void detail::buffer<char>::append(const char*, const char*);
template FMT_API void buffer<char>::append(const char*, const char*);

// DEPRECATED!
// There is no correspondent extern template in format.h because of
// incompatibility between clang and gcc (#2377).
template FMT_API void detail::vformat_to(
detail::buffer<char>&, string_view,
basic_format_args<FMT_BUFFER_CONTEXT(char)>, detail::locale_ref);

template FMT_API int detail::format_float(double, int, detail::float_specs,
detail::buffer<char>&);
template FMT_API int detail::format_float(long double, int, detail::float_specs,
detail::buffer<char>&);
template FMT_API void vformat_to(buffer<char>&, string_view,
basic_format_args<FMT_BUFFER_CONTEXT(char)>,
locale_ref);

// Explicit instantiations for wchar_t.

template FMT_API auto detail::thousands_sep_impl(locale_ref)
template FMT_API auto thousands_sep_impl(locale_ref)
-> thousands_sep_result<wchar_t>;
template FMT_API wchar_t detail::decimal_point_impl(locale_ref);
template FMT_API auto decimal_point_impl(locale_ref) -> wchar_t;

template FMT_API void detail::buffer<wchar_t>::append(const wchar_t*,
const wchar_t*);

template struct detail::basic_data<void>;
template FMT_API void buffer<wchar_t>::append(const wchar_t*, const wchar_t*);

} // namespace detail
FMT_END_NAMESPACE
13 changes: 3 additions & 10 deletions Externals/fmt/src/os.cc
Expand Up @@ -51,10 +51,6 @@
# include <windows.h>
#endif

#ifdef fileno
# undef fileno
#endif

namespace {
#ifdef _WIN32
// Return type of read and write functions.
Expand Down Expand Up @@ -173,7 +169,7 @@ void detail::format_windows_error(detail::buffer<char>& out, int error_code,
if (msg) {
utf16_to_utf8 utf8_message;
if (utf8_message.convert(msg) == ERROR_SUCCESS) {
format_to(buffer_appender<char>(out), "{}: {}", message, utf8_message);
fmt::format_to(buffer_appender<char>(out), "{}: {}", message, utf8_message);
return;
}
}
Expand Down Expand Up @@ -206,11 +202,8 @@ void buffered_file::close() {
if (result != 0) FMT_THROW(system_error(errno, "cannot close file"));
}

// A macro used to prevent expansion of fileno on broken versions of MinGW.
#define FMT_ARGS

int buffered_file::fileno() const {
int fd = FMT_POSIX_CALL(fileno FMT_ARGS(file_));
int buffered_file::descriptor() const {
int fd = FMT_POSIX_CALL(fileno(file_));
if (fd == -1) FMT_THROW(system_error(errno, "cannot get file descriptor"));
return fd;
}
Expand Down
43 changes: 0 additions & 43 deletions Externals/fmt/support/appveyor-build.py

This file was deleted.

31 changes: 0 additions & 31 deletions Externals/fmt/support/appveyor.yml

This file was deleted.

2 changes: 1 addition & 1 deletion Externals/fmt/support/bazel/.bazelversion
@@ -1 +1 @@
5.0.0
5.1.1
7 changes: 3 additions & 4 deletions Externals/fmt/support/bazel/BUILD.bazel
Expand Up @@ -11,18 +11,17 @@ cc_library(
"include/fmt/color.h",
"include/fmt/compile.h",
"include/fmt/core.h",
"include/fmt/format.h",
"include/fmt/format-inl.h",
"include/fmt/locale.h",
"include/fmt/format.h",
"include/fmt/os.h",
"include/fmt/ostream.h",
"include/fmt/printf.h",
"include/fmt/ranges.h",
"include/fmt/std.h",
"include/fmt/xchar.h",
],
includes = [
"include",
"src",
"include",
],
strip_include_prefix = "include",
visibility = ["//visibility:public"],
Expand Down
5 changes: 4 additions & 1 deletion Externals/fmt/support/cmake/fmt-config.cmake.in
@@ -1,4 +1,7 @@
@PACKAGE_INIT@

include(${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake)
if (NOT TARGET fmt::fmt)
include(${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake)
endif ()

check_required_components(fmt)
6 changes: 6 additions & 0 deletions Externals/fmt/support/manage.py
Expand Up @@ -183,6 +183,12 @@ def update_site(env):
with rewrite(index) as b:
b.data = b.data.replace(
'doc/latest/index.html#format-string-syntax', 'syntax.html')
# Fix issues in syntax.rst.
index = os.path.join(target_doc_dir, 'syntax.rst')
with rewrite(index) as b:
b.data = b.data.replace(
'..productionlist:: sf\n', '.. productionlist:: sf\n ')
b.data = b.data.replace('Examples:\n', 'Examples::\n')
# Build the docs.
html_dir = os.path.join(env.build_dir, 'html')
if os.path.exists(html_dir):
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/Core/DSP/DSPDisassembler.cpp
Expand Up @@ -132,7 +132,7 @@ std::string DSPDisassembler::DisassembleParameters(const DSPOPCTemplate& opc, u1
break;

default:
ERROR_LOG_FMT(DSPLLE, "Unknown parameter type: {:x}", opc.params[j].type);
ERROR_LOG_FMT(DSPLLE, "Unknown parameter type: {:x}", static_cast<u32>(opc.params[j].type));
break;
}
}
Expand Down
55 changes: 35 additions & 20 deletions Source/Core/Core/DSP/Jit/x64/DSPJitRegCache.cpp
Expand Up @@ -365,24 +365,39 @@ void DSPJitRegCache::FlushRegs()
ASSERT_MSG(DSPLLE, !m_regs[i].loc.IsSimpleReg(), "register {} is still a simple reg", i);
}

ASSERT_MSG(DSPLLE, m_xregs[RSP].guest_reg == DSP_REG_STATIC, "wrong xreg state for {}", RSP);
ASSERT_MSG(DSPLLE, m_xregs[RBX].guest_reg == DSP_REG_STATIC, "wrong xreg state for {}", RBX);
ASSERT_MSG(DSPLLE, m_xregs[RBP].guest_reg == DSP_REG_NONE, "wrong xreg state for {}", RBP);
ASSERT_MSG(DSPLLE, m_xregs[RSI].guest_reg == DSP_REG_NONE, "wrong xreg state for {}", RSI);
ASSERT_MSG(DSPLLE, m_xregs[RDI].guest_reg == DSP_REG_NONE, "wrong xreg state for {}", RDI);
ASSERT_MSG(DSPLLE, m_xregs[RSP].guest_reg == DSP_REG_STATIC, "wrong xreg state for {}",
static_cast<u32>(RSP));
ASSERT_MSG(DSPLLE, m_xregs[RBX].guest_reg == DSP_REG_STATIC, "wrong xreg state for {}",
static_cast<u32>(RBX));
ASSERT_MSG(DSPLLE, m_xregs[RBP].guest_reg == DSP_REG_NONE, "wrong xreg state for {}",
static_cast<u32>(RBP));
ASSERT_MSG(DSPLLE, m_xregs[RSI].guest_reg == DSP_REG_NONE, "wrong xreg state for {}",
static_cast<u32>(RSI));
ASSERT_MSG(DSPLLE, m_xregs[RDI].guest_reg == DSP_REG_NONE, "wrong xreg state for {}",
static_cast<u32>(RDI));
#ifdef STATIC_REG_ACCS
ASSERT_MSG(DSPLLE, m_xregs[R8].guest_reg == DSP_REG_STATIC, "wrong xreg state for {}", R8);
ASSERT_MSG(DSPLLE, m_xregs[R9].guest_reg == DSP_REG_STATIC, "wrong xreg state for {}", R9);
ASSERT_MSG(DSPLLE, m_xregs[R8].guest_reg == DSP_REG_STATIC, "wrong xreg state for {}",
static_cast<u32>(R8));
ASSERT_MSG(DSPLLE, m_xregs[R9].guest_reg == DSP_REG_STATIC, "wrong xreg state for {}",
static_cast<u32>(R9));
#else
ASSERT_MSG(DSPLLE, m_xregs[R8].guest_reg == DSP_REG_NONE, "wrong xreg state for {}", R8);
ASSERT_MSG(DSPLLE, m_xregs[R9].guest_reg == DSP_REG_NONE, "wrong xreg state for {}", R9);
ASSERT_MSG(DSPLLE, m_xregs[R8].guest_reg == DSP_REG_NONE, "wrong xreg state for {}",
static_cast<u32>(R8));
ASSERT_MSG(DSPLLE, m_xregs[R9].guest_reg == DSP_REG_NONE, "wrong xreg state for {}",
static_cast<u32>(R9));
#endif
ASSERT_MSG(DSPLLE, m_xregs[R10].guest_reg == DSP_REG_NONE, "wrong xreg state for {}", R10);
ASSERT_MSG(DSPLLE, m_xregs[R11].guest_reg == DSP_REG_NONE, "wrong xreg state for {}", R11);
ASSERT_MSG(DSPLLE, m_xregs[R12].guest_reg == DSP_REG_NONE, "wrong xreg state for {}", R12);
ASSERT_MSG(DSPLLE, m_xregs[R13].guest_reg == DSP_REG_NONE, "wrong xreg state for {}", R13);
ASSERT_MSG(DSPLLE, m_xregs[R14].guest_reg == DSP_REG_NONE, "wrong xreg state for {}", R14);
ASSERT_MSG(DSPLLE, m_xregs[R15].guest_reg == DSP_REG_STATIC, "wrong xreg state for {}", R15);
ASSERT_MSG(DSPLLE, m_xregs[R10].guest_reg == DSP_REG_NONE, "wrong xreg state for {}",
static_cast<u32>(R10));
ASSERT_MSG(DSPLLE, m_xregs[R11].guest_reg == DSP_REG_NONE, "wrong xreg state for {}",
static_cast<u32>(R11));
ASSERT_MSG(DSPLLE, m_xregs[R12].guest_reg == DSP_REG_NONE, "wrong xreg state for {}",
static_cast<u32>(R12));
ASSERT_MSG(DSPLLE, m_xregs[R13].guest_reg == DSP_REG_NONE, "wrong xreg state for {}",
static_cast<u32>(R13));
ASSERT_MSG(DSPLLE, m_xregs[R14].guest_reg == DSP_REG_NONE, "wrong xreg state for {}",
static_cast<u32>(R14));
ASSERT_MSG(DSPLLE, m_xregs[R15].guest_reg == DSP_REG_STATIC, "wrong xreg state for {}",
static_cast<u32>(R15));

m_use_ctr = 0;
}
Expand Down Expand Up @@ -968,15 +983,15 @@ void DSPJitRegCache::SpillXReg(X64Reg reg)
if (m_xregs[reg].guest_reg <= DSP_REG_MAX_MEM_BACKED)
{
ASSERT_MSG(DSPLLE, !m_regs[m_xregs[reg].guest_reg].used,
"to be spilled host reg {:#x} (guest reg {:#x}) still in use!", reg,
m_xregs[reg].guest_reg);
"to be spilled host reg {:#x} (guest reg {:#x}) still in use!",
static_cast<u32>(reg), m_xregs[reg].guest_reg);

MovToMemory(m_xregs[reg].guest_reg);
}
else
{
ASSERT_MSG(DSPLLE, m_xregs[reg].guest_reg == DSP_REG_NONE,
"to be spilled host reg {:#x} still in use!", reg);
"to be spilled host reg {:#x} still in use!", static_cast<u32>(reg));
}
}

Expand Down Expand Up @@ -1021,7 +1036,7 @@ void DSPJitRegCache::GetXReg(X64Reg reg)
{
if (m_xregs[reg].guest_reg == DSP_REG_STATIC)
{
ERROR_LOG_FMT(DSPLLE, "Trying to get statically used XReg {}", reg);
ERROR_LOG_FMT(DSPLLE, "Trying to get statically used XReg {}", static_cast<u32>(reg));
return;
}

Expand All @@ -1037,7 +1052,7 @@ void DSPJitRegCache::PutXReg(X64Reg reg)
{
if (m_xregs[reg].guest_reg == DSP_REG_STATIC)
{
ERROR_LOG_FMT(DSPLLE, "Trying to put statically used XReg {}", reg);
ERROR_LOG_FMT(DSPLLE, "Trying to put statically used XReg {}", static_cast<u32>(reg));
return;
}

Expand Down
15 changes: 6 additions & 9 deletions Source/Core/Core/FifoPlayer/FifoDataFile.cpp
Expand Up @@ -14,15 +14,12 @@
#include "Core/Config/MainSettings.h"
#include "Core/HW/Memmap.h"

enum
{
FILE_ID = 0x0d01f1f0,
VERSION_NUMBER = 5,
MIN_LOADER_VERSION = 1,
// This value is only used if the DFF file was created with overridden RAM sizes.
// If the MIN_LOADER_VERSION ever exceeds this, it's alright to remove it.
MIN_LOADER_VERSION_FOR_RAM_OVERRIDE = 5,
};
constexpr u32 FILE_ID = 0x0d01f1f0;
constexpr u32 VERSION_NUMBER = 5;
constexpr u32 MIN_LOADER_VERSION = 1;
// This value is only used if the DFF file was created with overridden RAM sizes.
// If the MIN_LOADER_VERSION ever exceeds this, it's alright to remove it.
constexpr u32 MIN_LOADER_VERSION_FOR_RAM_OVERRIDE = 5;

#pragma pack(push, 1)

Expand Down
2 changes: 1 addition & 1 deletion Source/Core/Core/HW/WiimoteEmu/EmuSubroutines.cpp
Expand Up @@ -210,7 +210,7 @@ void Wiimote::HandleExtensionSwap(ExtensionNumber desired_extension_number,
else
{
INFO_LOG_FMT(WIIMOTE, "Switching to Extension {} (Wiimote {} in slot {})",
desired_extension_number, m_index, m_bt_device_index);
static_cast<u8>(desired_extension_number), m_index, m_bt_device_index);

m_active_extension = desired_extension_number;
}
Expand Down
15 changes: 9 additions & 6 deletions Source/Core/Core/IOS/ES/ES.cpp
Expand Up @@ -91,7 +91,7 @@ ESDevice::ESDevice(Kernel& ios, const std::string& device_name) : Device(ios, de
if (result != FS::ResultCode::Success && result != FS::ResultCode::AlreadyExists)
{
ERROR_LOG_FMT(IOS_ES, "Failed to create {}: error {}", directory.path,
FS::ConvertResult(result));
static_cast<s32>(FS::ConvertResult(result)));
}

// Now update the UID/GID and other attributes.
Expand Down Expand Up @@ -1060,7 +1060,8 @@ ReturnCode ESDevice::VerifyContainer(VerifyContainerType type, VerifyMode mode,
ret = iosc.ImportCertificate(ca_cert, IOSC::HANDLE_ROOT_KEY, ca_handle, PID_ES);
if (ret != IPC_SUCCESS)
{
ERROR_LOG_FMT(IOS_ES, "VerifyContainer: IOSC_ImportCertificate(ca) failed with error {}", ret);
ERROR_LOG_FMT(IOS_ES, "VerifyContainer: IOSC_ImportCertificate(ca) failed with error {}",
static_cast<s32>(ret));
return ret;
}

Expand All @@ -1075,7 +1076,7 @@ ReturnCode ESDevice::VerifyContainer(VerifyContainerType type, VerifyMode mode,
if (ret != IPC_SUCCESS)
{
ERROR_LOG_FMT(IOS_ES, "VerifyContainer: IOSC_ImportCertificate(issuer) failed with error {}",
ret);
static_cast<s32>(ret));
return ret;
}

Expand All @@ -1084,7 +1085,8 @@ ReturnCode ESDevice::VerifyContainer(VerifyContainerType type, VerifyMode mode,
ret = iosc.VerifyPublicKeySign(signed_blob.GetSha1(), issuer_handle, signature, PID_ES);
if (ret != IPC_SUCCESS)
{
ERROR_LOG_FMT(IOS_ES, "VerifyContainer: IOSC_VerifyPublicKeySign failed with error {}", ret);
ERROR_LOG_FMT(IOS_ES, "VerifyContainer: IOSC_VerifyPublicKeySign failed with error {}",
static_cast<s32>(ret));
return ret;
}

Expand All @@ -1094,12 +1096,13 @@ ReturnCode ESDevice::VerifyContainer(VerifyContainerType type, VerifyMode mode,
if (ret != IPC_SUCCESS)
{
ERROR_LOG_FMT(IOS_ES, "VerifyContainer: Writing the issuer cert failed with return code {}",
ret);
static_cast<s32>(ret));
}

ret = WriteNewCertToStore(ca_cert);
if (ret != IPC_SUCCESS)
ERROR_LOG_FMT(IOS_ES, "VerifyContainer: Writing the CA cert failed with return code {}", ret);
ERROR_LOG_FMT(IOS_ES, "VerifyContainer: Writing the CA cert failed with return code {}",
static_cast<s32>(ret));
}

if (ret == IPC_SUCCESS && issuer_handle_out)
Expand Down
12 changes: 8 additions & 4 deletions Source/Core/Core/IOS/ES/Identity.cpp
Expand Up @@ -146,14 +146,16 @@ ReturnCode ESDevice::VerifySign(const std::vector<u8>& hash, const std::vector<u
certs_bytes, ng_cert);
if (ret != IPC_SUCCESS)
{
ERROR_LOG_FMT(IOS_ES, "VerifySign: VerifyContainer(ng) failed with error {}", ret);
ERROR_LOG_FMT(IOS_ES, "VerifySign: VerifyContainer(ng) failed with error {}",
static_cast<s32>(ret));
return ret;
}

ret = iosc.VerifyPublicKeySign(ap.GetSha1(), ng_cert, ap.GetSignatureData(), PID_ES);
if (ret != IPC_SUCCESS)
{
ERROR_LOG_FMT(IOS_ES, "VerifySign: IOSC_VerifyPublicKeySign(ap) failed with error {}", ret);
ERROR_LOG_FMT(IOS_ES, "VerifySign: IOSC_VerifyPublicKeySign(ap) failed with error {}",
static_cast<s32>(ret));
return ret;
}

Expand All @@ -166,15 +168,17 @@ ReturnCode ESDevice::VerifySign(const std::vector<u8>& hash, const std::vector<u
ret = iosc.ImportPublicKey(ap_cert, ap.GetPublicKey().data(), nullptr, PID_ES);
if (ret != IPC_SUCCESS)
{
ERROR_LOG_FMT(IOS_ES, "VerifySign: IOSC_ImportPublicKey(ap) failed with error {}", ret);
ERROR_LOG_FMT(IOS_ES, "VerifySign: IOSC_ImportPublicKey(ap) failed with error {}",
static_cast<s32>(ret));
return ret;
}

const auto hash_digest = Common::SHA1::CalculateDigest(hash);
ret = iosc.VerifyPublicKeySign(hash_digest, ap_cert, ecc_signature, PID_ES);
if (ret != IPC_SUCCESS)
{
ERROR_LOG_FMT(IOS_ES, "VerifySign: IOSC_VerifyPublicKeySign(data) failed with error {}", ret);
ERROR_LOG_FMT(IOS_ES, "VerifySign: IOSC_VerifyPublicKeySign(data) failed with error {}",
static_cast<s32>(ret));
return ret;
}

Expand Down
6 changes: 3 additions & 3 deletions Source/Core/Core/IOS/ES/TitleManagement.cpp
Expand Up @@ -71,7 +71,7 @@ ReturnCode ESDevice::ImportTicket(const std::vector<u8>& ticket_bytes,
if (ret < 0)
{
ERROR_LOG_FMT(IOS_ES, "ImportTicket: Failed to unpersonalise ticket for {:016x} ({})",
ticket.GetTitleId(), ret);
ticket.GetTitleId(), static_cast<s32>(ret));
return ret;
}
}
Expand Down Expand Up @@ -156,7 +156,7 @@ ReturnCode ESDevice::ImportTmd(Context& context, const std::vector<u8>& tmd_byte
context.title_import_export.tmd, cert_store);
if (ret != IPC_SUCCESS)
{
ERROR_LOG_FMT(IOS_ES, "ImportTmd: VerifyContainer failed with error {}", ret);
ERROR_LOG_FMT(IOS_ES, "ImportTmd: VerifyContainer failed with error {}", static_cast<s32>(ret));
return ret;
}

Expand All @@ -170,7 +170,7 @@ ReturnCode ESDevice::ImportTmd(Context& context, const std::vector<u8>& tmd_byte
&context.title_import_export.key_handle);
if (ret != IPC_SUCCESS)
{
ERROR_LOG_FMT(IOS_ES, "ImportTmd: InitBackupKey failed with error {}", ret);
ERROR_LOG_FMT(IOS_ES, "ImportTmd: InitBackupKey failed with error {}", static_cast<s32>(ret));
return ret;
}

Expand Down
2 changes: 1 addition & 1 deletion Source/Core/Core/IOS/FS/FileSystemProxy.cpp
Expand Up @@ -109,7 +109,7 @@ static void LogResult(ResultCode code, fmt::format_string<Args...> format, Args&
code == ResultCode::Success ? Common::Log::LogLevel::LINFO : Common::Log::LogLevel::LERROR;

GENERIC_LOG_FMT(Common::Log::LogType::IOS_FS, type, "Command: {}: Result {}", command,
ConvertResult(code));
static_cast<s32>(ConvertResult(code)));
}

template <typename T, typename... Args>
Expand Down
5 changes: 3 additions & 2 deletions Source/Core/Core/IOS/IOS.cpp
Expand Up @@ -616,7 +616,8 @@ std::shared_ptr<Device> EmulationKernel::GetDeviceByName(std::string_view device
std::optional<IPCReply> Kernel::OpenDevice(OpenRequest& request)
{
const s32 new_fd = GetFreeDeviceID();
INFO_LOG_FMT(IOS, "Opening {} (mode {}, fd {})", request.path, request.flags, new_fd);
INFO_LOG_FMT(IOS, "Opening {} (mode {}, fd {})", request.path, static_cast<u32>(request.flags),
new_fd);
if (new_fd < 0 || new_fd >= IPC_MAX_FDS)
{
ERROR_LOG_FMT(IOS, "Couldn't get a free fd, too many open files");
Expand Down Expand Up @@ -694,7 +695,7 @@ std::optional<IPCReply> Kernel::HandleIPCCommand(const Request& request)
ret = device->IOCtlV(IOCtlVRequest{request.address});
break;
default:
ASSERT_MSG(IOS, false, "Unexpected command: {:#x}", request.command);
ASSERT_MSG(IOS, false, "Unexpected command: {:#x}", static_cast<u32>(request.command));
ret = IPCReply{IPC_EINVAL, 978_tbticks};
break;
}
Expand Down
3 changes: 2 additions & 1 deletion Source/Core/Core/IOS/Network/KD/VFF/VFFUtil.cpp
Expand Up @@ -210,7 +210,8 @@ static ErrorCode WriteFile(const std::string& filename, const std::vector<u8>& t
f_write(&dst, tmp_buffer.data() + offset, chunk_size, &written_size);
if (write_error_code != FR_OK)
{
ERROR_LOG_FMT(IOS_WC24, "Failed to write file {} to VFF {}", filename, write_error_code);
ERROR_LOG_FMT(IOS_WC24, "Failed to write file {} to VFF: {}", filename,
static_cast<u32>(write_error_code));
return WC24_ERR_FILE_WRITE;
}

Expand Down
2 changes: 1 addition & 1 deletion Source/Core/Core/IOS/Network/Socket.h
Expand Up @@ -284,7 +284,7 @@ class WiiSockMan
if (socket_entry == WiiSockets.end())
{
ERROR_LOG_FMT(IOS_NET, "DoSock: Error, fd not found ({:08x}, {:08X}, {:08X})", sock,
request.address, type);
request.address, static_cast<u32>(type));
GetIOS()->EnqueueIPCReply(request, -SO_EBADF);
}
else
Expand Down
6 changes: 4 additions & 2 deletions Source/Core/Core/IOS/USB/Bluetooth/BTReal.cpp
Expand Up @@ -666,7 +666,8 @@ void BluetoothRealDevice::HandleCtrlTransfer(libusb_transfer* tr)

if (tr->status != LIBUSB_TRANSFER_COMPLETED && tr->status != LIBUSB_TRANSFER_NO_DEVICE)
{
ERROR_LOG_FMT(IOS_WIIMOTE, "libusb command transfer failed, status: {:#04x}", tr->status);
ERROR_LOG_FMT(IOS_WIIMOTE, "libusb command transfer failed, status: {:#04x}",
static_cast<u32>(tr->status));
if (!m_showed_failed_transfer.IsSet())
{
Core::DisplayMessage("Failed to send a command to the Bluetooth adapter.", 10000);
Expand All @@ -693,7 +694,8 @@ void BluetoothRealDevice::HandleBulkOrIntrTransfer(libusb_transfer* tr)
if (tr->status != LIBUSB_TRANSFER_COMPLETED && tr->status != LIBUSB_TRANSFER_TIMED_OUT &&
tr->status != LIBUSB_TRANSFER_NO_DEVICE)
{
ERROR_LOG_FMT(IOS_WIIMOTE, "libusb transfer failed, status: {:#04x}", tr->status);
ERROR_LOG_FMT(IOS_WIIMOTE, "libusb transfer failed, status: {:#04x}",
static_cast<u32>(tr->status));
if (!m_showed_failed_transfer.IsSet())
{
Core::DisplayMessage("Failed to transfer to or from to the Bluetooth adapter.", 10000);
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/Core/IOS/WFS/WFSI.cpp
Expand Up @@ -138,7 +138,7 @@ std::optional<IPCReply> WFSIDevice::IOCtl(const IOCtlRequest& request)
m_continue_install = Memory::Read_U32(request.buffer_in + 36);

INFO_LOG_FMT(IOS_WFS, "IOCTL_WFSI_IMPORT_TITLE_INIT: patch type {}, continue install: {}",
m_patch_type, m_continue_install ? "true" : "false");
static_cast<u32>(m_patch_type), m_continue_install ? "true" : "false");

if (m_patch_type == PatchType::PATCH_TYPE_2)
{
Expand Down
12 changes: 6 additions & 6 deletions Source/Core/Core/PowerPC/Jit64/RegCache/JitRegCache.cpp
Expand Up @@ -389,7 +389,7 @@ void RegCache::Discard(BitSet32 pregs)
for (preg_t i : pregs)
{
ASSERT_MSG(DYNA_REC, !m_regs[i].IsLocked(), "Someone forgot to unlock PPC reg {} (X64 reg {}).",
i, RX(i));
i, static_cast<u32>(RX(i)));
ASSERT_MSG(DYNA_REC, !m_regs[i].IsRevertable(), "Register transaction is in progress for {}!",
i);

Expand All @@ -413,7 +413,7 @@ void RegCache::Flush(BitSet32 pregs)
for (preg_t i : pregs)
{
ASSERT_MSG(DYNA_REC, !m_regs[i].IsLocked(), "Someone forgot to unlock PPC reg {} (X64 reg {}).",
i, RX(i));
i, static_cast<u32>(RX(i)));
ASSERT_MSG(DYNA_REC, !m_regs[i].IsRevertable(), "Register transaction is in progress for {}!",
i);

Expand Down Expand Up @@ -497,7 +497,7 @@ BitSet32 RegCache::RegistersInUse() const

void RegCache::FlushX(X64Reg reg)
{
ASSERT_MSG(DYNA_REC, reg < m_xregs.size(), "Flushing non-existent reg {}", reg);
ASSERT_MSG(DYNA_REC, reg < m_xregs.size(), "Flushing non-existent reg {}", static_cast<u32>(reg));
ASSERT(!m_xregs[reg].IsLocked());
if (!m_xregs[reg].IsFree())
{
Expand All @@ -521,7 +521,7 @@ void RegCache::BindToRegister(preg_t i, bool doLoad, bool makeDirty)
{
X64Reg xr = GetFreeXReg();

ASSERT_MSG(DYNA_REC, !m_xregs[xr].IsDirty(), "Xreg {} already dirty", xr);
ASSERT_MSG(DYNA_REC, !m_xregs[xr].IsDirty(), "Xreg {} already dirty", static_cast<u32>(xr));
ASSERT_MSG(DYNA_REC, !m_xregs[xr].IsLocked(), "GetFreeXReg returned locked register");
ASSERT_MSG(DYNA_REC, !m_regs[i].IsRevertable(), "Invalid transaction state");

Expand All @@ -538,7 +538,7 @@ void RegCache::BindToRegister(preg_t i, bool doLoad, bool makeDirty)
[xr](const auto& r) {
return r.Location().has_value() && r.Location()->IsSimpleReg(xr);
}),
"Xreg {} already bound", xr);
"Xreg {} already bound", static_cast<u32>(xr));

m_regs[i].SetBoundTo(xr);
}
Expand All @@ -551,7 +551,7 @@ void RegCache::BindToRegister(preg_t i, bool doLoad, bool makeDirty)
}

ASSERT_MSG(DYNA_REC, !m_xregs[RX(i)].IsLocked(),
"WTF, this reg ({} -> {}) should have been flushed", i, RX(i));
"WTF, this reg ({} -> {}) should have been flushed", i, static_cast<u32>(RX(i)));
}

void RegCache::StoreFromRegister(preg_t i, FlushMode mode)
Expand Down
6 changes: 4 additions & 2 deletions Source/Core/Core/PowerPC/Jit64Common/Jit64AsmCommon.cpp
Expand Up @@ -369,7 +369,8 @@ const u8* CommonAsmRoutines::GenQuantizedStoreRuntime(bool single, EQuantizeType
const u8* load = AlignCode4();
GenQuantizedStore(single, type, -1);
RET();
JitRegister::Register(start, GetCodePtr(), "JIT_QuantizedStore_{}_{}", type, single);
JitRegister::Register(start, GetCodePtr(), "JIT_QuantizedStore_{}_{}", static_cast<u32>(type),
single);

return load;
}
Expand Down Expand Up @@ -400,7 +401,8 @@ const u8* CommonAsmRoutines::GenQuantizedLoadRuntime(bool single, EQuantizeType
const u8* load = AlignCode4();
GenQuantizedLoad(single, type, -1);
RET();
JitRegister::Register(start, GetCodePtr(), "JIT_QuantizedLoad_{}_{}", type, single);
JitRegister::Register(start, GetCodePtr(), "JIT_QuantizedLoad_{}_{}", static_cast<u32>(type),
single);

return load;
}
Expand Down
10 changes: 5 additions & 5 deletions Source/Core/Core/WiiUtils.cpp
Expand Up @@ -76,7 +76,7 @@ static bool ImportWAD(IOS::HLE::Kernel& ios, const DiscIO::VolumeWAD& wad,
if (ret != IOS::HLE::IOSC_FAIL_CHECKVALUE)
{
PanicAlertFmtT("WAD installation failed: Could not initialise title import (error {0}).",
ret);
static_cast<u32>(ret));
}
return false;
}
Expand Down Expand Up @@ -548,7 +548,7 @@ UpdateResult OnlineSystemUpdater::InstallTitleFromNUS(const std::string& prefix_
const auto es = m_ios.GetES();
if ((ret = es->ImportTicket(ticket.first, ticket.second)) < 0)
{
ERROR_LOG_FMT(CORE, "Failed to import ticket: error {}", ret);
ERROR_LOG_FMT(CORE, "Failed to import ticket: error {}", static_cast<u32>(ret));
return UpdateResult::ImportFailed;
}

Expand Down Expand Up @@ -580,7 +580,7 @@ UpdateResult OnlineSystemUpdater::InstallTitleFromNUS(const std::string& prefix_
IOS::HLE::ESDevice::Context context;
if ((ret = es->ImportTitleInit(context, tmd.first.GetBytes(), tmd.second)) < 0)
{
ERROR_LOG_FMT(CORE, "Failed to initialise title import: error {}", ret);
ERROR_LOG_FMT(CORE, "Failed to initialise title import: error {}", static_cast<u32>(ret));
return UpdateResult::ImportFailed;
}

Expand All @@ -601,7 +601,7 @@ UpdateResult OnlineSystemUpdater::InstallTitleFromNUS(const std::string& prefix_
if ((ret = es->ImportContentBegin(context, title.id, content.id)) < 0)
{
ERROR_LOG_FMT(CORE, "Failed to initialise import for content {:08x}: error {}", content.id,
ret);
static_cast<u32>(ret));
return UpdateResult::ImportFailed;
}

Expand All @@ -626,7 +626,7 @@ UpdateResult OnlineSystemUpdater::InstallTitleFromNUS(const std::string& prefix_
if ((all_contents_imported && (ret = es->ImportTitleDone(context)) < 0) ||
(!all_contents_imported && (ret = es->ImportTitleCancel(context)) < 0))
{
ERROR_LOG_FMT(CORE, "Failed to finalise title import: error {}", ret);
ERROR_LOG_FMT(CORE, "Failed to finalise title import: error {}", static_cast<u32>(ret));
return UpdateResult::ImportFailed;
}

Expand Down
80 changes: 21 additions & 59 deletions Source/Core/VideoBackends/D3D/D3DNativeVertexFormat.cpp
Expand Up @@ -103,69 +103,18 @@ D3DVertexFormat::D3DVertexFormat(const PortableVertexDeclaration& vtx_decl)
: NativeVertexFormat(vtx_decl)

{
const AttributeFormat* format = &vtx_decl.position;
if (format->enable)
{
m_elems[m_num_elems].SemanticName = "TEXCOORD";
m_elems[m_num_elems].SemanticIndex = SHADER_POSITION_ATTRIB;
m_elems[m_num_elems].AlignedByteOffset = format->offset;
m_elems[m_num_elems].Format = VarToD3D(format->type, format->components, format->integer);
m_elems[m_num_elems].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
++m_num_elems;
}
AddAttribute(vtx_decl.position, ShaderAttrib::Position);

for (int i = 0; i < 3; i++)
{
format = &vtx_decl.normals[i];
if (format->enable)
{
m_elems[m_num_elems].SemanticName = "TEXCOORD";
m_elems[m_num_elems].SemanticIndex = SHADER_NORMAL_ATTRIB + i;
m_elems[m_num_elems].AlignedByteOffset = format->offset;
m_elems[m_num_elems].Format = VarToD3D(format->type, format->components, format->integer);
m_elems[m_num_elems].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
++m_num_elems;
}
}
for (u32 i = 0; i < 3; i++)
AddAttribute(vtx_decl.normals[i], ShaderAttrib::Normal + i);

for (int i = 0; i < 2; i++)
{
format = &vtx_decl.colors[i];
if (format->enable)
{
m_elems[m_num_elems].SemanticName = "TEXCOORD";
m_elems[m_num_elems].SemanticIndex = SHADER_COLOR0_ATTRIB + i;
m_elems[m_num_elems].AlignedByteOffset = format->offset;
m_elems[m_num_elems].Format = VarToD3D(format->type, format->components, format->integer);
m_elems[m_num_elems].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
++m_num_elems;
}
}
for (u32 i = 0; i < 2; i++)
AddAttribute(vtx_decl.colors[i], ShaderAttrib::Color0 + i);

for (int i = 0; i < 8; i++)
{
format = &vtx_decl.texcoords[i];
if (format->enable)
{
m_elems[m_num_elems].SemanticName = "TEXCOORD";
m_elems[m_num_elems].SemanticIndex = SHADER_TEXTURE0_ATTRIB + i;
m_elems[m_num_elems].AlignedByteOffset = format->offset;
m_elems[m_num_elems].Format = VarToD3D(format->type, format->components, format->integer);
m_elems[m_num_elems].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
++m_num_elems;
}
}
for (u32 i = 0; i < 8; i++)
AddAttribute(vtx_decl.texcoords[i], ShaderAttrib::TexCoord0 + i);

format = &vtx_decl.posmtx;
if (format->enable)
{
m_elems[m_num_elems].SemanticName = "TEXCOORD";
m_elems[m_num_elems].SemanticIndex = SHADER_POSMTX_ATTRIB;
m_elems[m_num_elems].AlignedByteOffset = format->offset;
m_elems[m_num_elems].Format = VarToD3D(format->type, format->components, format->integer);
m_elems[m_num_elems].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
++m_num_elems;
}
AddAttribute(vtx_decl.posmtx, ShaderAttrib::PositionMatrix);
}

D3DVertexFormat::~D3DVertexFormat()
Expand Down Expand Up @@ -201,4 +150,17 @@ ID3D11InputLayout* D3DVertexFormat::GetInputLayout(const void* vs_bytecode, size
return layout;
}

void D3DVertexFormat::AddAttribute(const AttributeFormat& format, ShaderAttrib semantic_index)
{
if (format.enable)
{
m_elems[m_num_elems].SemanticName = "TEXCOORD";
m_elems[m_num_elems].SemanticIndex = static_cast<u32>(semantic_index);
m_elems[m_num_elems].AlignedByteOffset = format.offset;
m_elems[m_num_elems].Format = VarToD3D(format.type, format.components, format.integer);
m_elems[m_num_elems].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
++m_num_elems;
}
}

} // namespace DX11
4 changes: 4 additions & 0 deletions Source/Core/VideoBackends/D3D/D3DVertexManager.h
Expand Up @@ -12,6 +12,8 @@
#include "VideoCommon/NativeVertexFormat.h"
#include "VideoCommon/VertexManagerBase.h"

enum class ShaderAttrib : u32;

namespace DX11
{
class D3DVertexFormat : public NativeVertexFormat
Expand All @@ -22,6 +24,8 @@ class D3DVertexFormat : public NativeVertexFormat
ID3D11InputLayout* GetInputLayout(const void* vs_bytecode, size_t vs_bytecode_size);

private:
void AddAttribute(const AttributeFormat& format, ShaderAttrib semantic_index);

std::array<D3D11_INPUT_ELEMENT_DESC, 32> m_elems{};
UINT m_num_elems = 0;

Expand Down
20 changes: 10 additions & 10 deletions Source/Core/VideoBackends/D3D12/DX12VertexFormat.cpp
Expand Up @@ -59,14 +59,14 @@ void DXVertexFormat::GetInputLayoutDesc(D3D12_INPUT_LAYOUT_DESC* desc) const
desc->NumElements = m_num_attributes;
}

void DXVertexFormat::AddAttribute(const char* semantic_name, u32 semantic_index, u32 slot,
void DXVertexFormat::AddAttribute(const char* semantic_name, ShaderAttrib semantic_index, u32 slot,
DXGI_FORMAT format, u32 offset)
{
ASSERT(m_num_attributes < MAX_VERTEX_ATTRIBUTES);

auto* attr_desc = &m_attribute_descriptions[m_num_attributes];
attr_desc->SemanticName = semantic_name;
attr_desc->SemanticIndex = semantic_index;
attr_desc->SemanticIndex = static_cast<u32>(semantic_index);
attr_desc->Format = format;
attr_desc->InputSlot = slot;
attr_desc->AlignedByteOffset = offset;
Expand All @@ -83,38 +83,38 @@ void DXVertexFormat::MapAttributes()
if (m_decl.position.enable)
{
AddAttribute(
"TEXCOORD", SHADER_POSITION_ATTRIB, 0,
"TEXCOORD", ShaderAttrib::Position, 0,
VarToDXGIFormat(m_decl.position.type, m_decl.position.components, m_decl.position.integer),
m_decl.position.offset);
}

for (uint32_t i = 0; i < 3; i++)
for (u32 i = 0; i < 3; i++)
{
if (m_decl.normals[i].enable)
{
AddAttribute("TEXCOORD", SHADER_NORMAL_ATTRIB + i, 0,
AddAttribute("TEXCOORD", ShaderAttrib::Normal + i, 0,
VarToDXGIFormat(m_decl.normals[i].type, m_decl.normals[i].components,
m_decl.normals[i].integer),
m_decl.normals[i].offset);
}
}

for (uint32_t i = 0; i < 2; i++)
for (u32 i = 0; i < 2; i++)
{
if (m_decl.colors[i].enable)
{
AddAttribute("TEXCOORD", SHADER_COLOR0_ATTRIB + i, 0,
AddAttribute("TEXCOORD", ShaderAttrib::Color0 + i, 0,
VarToDXGIFormat(m_decl.colors[i].type, m_decl.colors[i].components,
m_decl.colors[i].integer),
m_decl.colors[i].offset);
}
}

for (uint32_t i = 0; i < 8; i++)
for (u32 i = 0; i < 8; i++)
{
if (m_decl.texcoords[i].enable)
{
AddAttribute("TEXCOORD", SHADER_TEXTURE0_ATTRIB + i, 0,
AddAttribute("TEXCOORD", ShaderAttrib::TexCoord0 + i, 0,
VarToDXGIFormat(m_decl.texcoords[i].type, m_decl.texcoords[i].components,
m_decl.texcoords[i].integer),
m_decl.texcoords[i].offset);
Expand All @@ -124,7 +124,7 @@ void DXVertexFormat::MapAttributes()
if (m_decl.posmtx.enable)
{
AddAttribute(
"TEXCOORD", SHADER_POSMTX_ATTRIB, 0,
"TEXCOORD", ShaderAttrib::PositionMatrix, 0,
VarToDXGIFormat(m_decl.posmtx.type, m_decl.posmtx.components, m_decl.posmtx.integer),
m_decl.posmtx.offset);
}
Expand Down
6 changes: 4 additions & 2 deletions Source/Core/VideoBackends/D3D12/DX12VertexFormat.h
Expand Up @@ -9,6 +9,8 @@
#include "Common/CommonTypes.h"
#include "VideoCommon/NativeVertexFormat.h"

enum class ShaderAttrib : u32;

namespace DX12
{
class DXVertexFormat : public NativeVertexFormat
Expand All @@ -22,8 +24,8 @@ class DXVertexFormat : public NativeVertexFormat
void GetInputLayoutDesc(D3D12_INPUT_LAYOUT_DESC* desc) const;

private:
void AddAttribute(const char* semantic_name, u32 semantic_index, u32 slot, DXGI_FORMAT format,
u32 offset);
void AddAttribute(const char* semantic_name, ShaderAttrib semantic_index, u32 slot,
DXGI_FORMAT format, u32 offset);
void MapAttributes();

std::array<D3D12_INPUT_ELEMENT_DESC, MAX_VERTEX_ATTRIBUTES> m_attribute_descriptions = {};
Expand Down
18 changes: 10 additions & 8 deletions Source/Core/VideoBackends/Metal/MTLVertexFormat.mm
Expand Up @@ -113,18 +113,20 @@ static MTLVertexFormat ConvertFormat(ComponentFormat format, int count, bool int
// clang-format on
}

static void SetAttribute(MTLVertexDescriptor* desc, u32 attribute, const AttributeFormat& format)
static void SetAttribute(MTLVertexDescriptor* desc, ShaderAttrib attribute,
const AttributeFormat& format)
{
if (!format.enable)
return;
MTLVertexAttributeDescriptor* attr_desc = [[desc attributes] objectAtIndexedSubscript:attribute];
MTLVertexAttributeDescriptor* attr_desc =
[[desc attributes] objectAtIndexedSubscript:(u32)attribute];
[attr_desc setFormat:ConvertFormat(format.type, format.components, format.integer)];
[attr_desc setOffset:format.offset];
[attr_desc setBufferIndex:0];
}

template <size_t N>
static void SetAttributes(MTLVertexDescriptor* desc, u32 attribute,
static void SetAttributes(MTLVertexDescriptor* desc, ShaderAttrib attribute,
const std::array<AttributeFormat, N>& format)
{
for (size_t i = 0; i < N; ++i)
Expand All @@ -135,9 +137,9 @@ static void SetAttributes(MTLVertexDescriptor* desc, u32 attribute,
: NativeVertexFormat(vtx_decl), m_desc(MRCTransfer([MTLVertexDescriptor new]))
{
[[[m_desc layouts] objectAtIndexedSubscript:0] setStride:vtx_decl.stride];
SetAttribute(m_desc, SHADER_POSITION_ATTRIB, vtx_decl.position);
SetAttributes(m_desc, SHADER_NORMAL_ATTRIB, vtx_decl.normals);
SetAttributes(m_desc, SHADER_COLOR0_ATTRIB, vtx_decl.colors);
SetAttributes(m_desc, SHADER_TEXTURE0_ATTRIB, vtx_decl.texcoords);
SetAttribute(m_desc, SHADER_POSMTX_ATTRIB, vtx_decl.posmtx);
SetAttribute(m_desc, ShaderAttrib::Position, vtx_decl.position);
SetAttributes(m_desc, ShaderAttrib::Normal, vtx_decl.normals);
SetAttributes(m_desc, ShaderAttrib::Color0, vtx_decl.colors);
SetAttributes(m_desc, ShaderAttrib::TexCoord0, vtx_decl.texcoords);
SetAttribute(m_desc, ShaderAttrib::PositionMatrix, vtx_decl.posmtx);
}
28 changes: 14 additions & 14 deletions Source/Core/VideoBackends/OGL/OGLNativeVertexFormat.cpp
Expand Up @@ -32,18 +32,18 @@ static inline GLuint VarToGL(ComponentFormat t)
return lookup[t];
}

static void SetPointer(u32 attrib, u32 stride, const AttributeFormat& format)
static void SetPointer(ShaderAttrib attrib, u32 stride, const AttributeFormat& format)
{
if (!format.enable)
return;

glEnableVertexAttribArray(attrib);
glEnableVertexAttribArray(static_cast<GLuint>(attrib));
if (format.integer)
glVertexAttribIPointer(attrib, format.components, VarToGL(format.type), stride,
(u8*)nullptr + format.offset);
glVertexAttribIPointer(static_cast<GLuint>(attrib), format.components, VarToGL(format.type),
stride, (u8*)nullptr + format.offset);
else
glVertexAttribPointer(attrib, format.components, VarToGL(format.type), true, stride,
(u8*)nullptr + format.offset);
glVertexAttribPointer(static_cast<GLuint>(attrib), format.components, VarToGL(format.type),
true, stride, (u8*)nullptr + format.offset);
}

GLVertexFormat::GLVertexFormat(const PortableVertexDeclaration& vtx_decl)
Expand All @@ -65,18 +65,18 @@ GLVertexFormat::GLVertexFormat(const PortableVertexDeclaration& vtx_decl)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vm->GetIndexBufferHandle());
glBindBuffer(GL_ARRAY_BUFFER, vm->GetVertexBufferHandle());

SetPointer(SHADER_POSITION_ATTRIB, vertex_stride, vtx_decl.position);
SetPointer(ShaderAttrib::Position, vertex_stride, vtx_decl.position);

for (int i = 0; i < 3; i++)
SetPointer(SHADER_NORMAL_ATTRIB + i, vertex_stride, vtx_decl.normals[i]);
for (u32 i = 0; i < 3; i++)
SetPointer(ShaderAttrib::Normal + i, vertex_stride, vtx_decl.normals[i]);

for (int i = 0; i < 2; i++)
SetPointer(SHADER_COLOR0_ATTRIB + i, vertex_stride, vtx_decl.colors[i]);
for (u32 i = 0; i < 2; i++)
SetPointer(ShaderAttrib::Color0 + i, vertex_stride, vtx_decl.colors[i]);

for (int i = 0; i < 8; i++)
SetPointer(SHADER_TEXTURE0_ATTRIB + i, vertex_stride, vtx_decl.texcoords[i]);
for (u32 i = 0; i < 8; i++)
SetPointer(ShaderAttrib::TexCoord0 + i, vertex_stride, vtx_decl.texcoords[i]);

SetPointer(SHADER_POSMTX_ATTRIB, vertex_stride, vtx_decl.posmtx);
SetPointer(ShaderAttrib::PositionMatrix, vertex_stride, vtx_decl.posmtx);
}

GLVertexFormat::~GLVertexFormat()
Expand Down
17 changes: 9 additions & 8 deletions Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp
Expand Up @@ -133,23 +133,24 @@ void SHADER::SetProgramBindings(bool is_compute)
glBindFragDataLocationIndexed(glprogid, 0, 1, "ocol1");
}
// Need to set some attribute locations
glBindAttribLocation(glprogid, SHADER_POSITION_ATTRIB, "rawpos");
glBindAttribLocation(glprogid, static_cast<GLuint>(ShaderAttrib::Position), "rawpos");

glBindAttribLocation(glprogid, SHADER_POSMTX_ATTRIB, "posmtx");
glBindAttribLocation(glprogid, static_cast<GLuint>(ShaderAttrib::PositionMatrix), "posmtx");

glBindAttribLocation(glprogid, SHADER_COLOR0_ATTRIB, "rawcolor0");
glBindAttribLocation(glprogid, SHADER_COLOR1_ATTRIB, "rawcolor1");
glBindAttribLocation(glprogid, static_cast<GLuint>(ShaderAttrib::Color0), "rawcolor0");
glBindAttribLocation(glprogid, static_cast<GLuint>(ShaderAttrib::Color1), "rawcolor1");

glBindAttribLocation(glprogid, SHADER_NORMAL_ATTRIB, "rawnormal");
glBindAttribLocation(glprogid, SHADER_TANGENT_ATTRIB, "rawtangent");
glBindAttribLocation(glprogid, SHADER_BINORMAL_ATTRIB, "rawbinormal");
glBindAttribLocation(glprogid, static_cast<GLuint>(ShaderAttrib::Normal), "rawnormal");
glBindAttribLocation(glprogid, static_cast<GLuint>(ShaderAttrib::Tangent), "rawtangent");
glBindAttribLocation(glprogid, static_cast<GLuint>(ShaderAttrib::Binormal), "rawbinormal");
}

for (int i = 0; i < 8; i++)
{
// Per documentation: OpenGL copies the name string when glBindAttribLocation is called, so an
// application may free its copy of the name string immediately after the function returns.
glBindAttribLocation(glprogid, SHADER_TEXTURE0_ATTRIB + i, fmt::format("rawtex{}", i).c_str());
glBindAttribLocation(glprogid, static_cast<GLuint>(ShaderAttrib::TexCoord0 + i),
fmt::format("rawtex{}", i).c_str());
}
}

Expand Down
6 changes: 4 additions & 2 deletions Source/Core/VideoBackends/Vulkan/VKRenderer.cpp
Expand Up @@ -310,13 +310,15 @@ void Renderer::BindBackbuffer(const ClearColor& clear_color)
}
else
{
ERROR_LOG_FMT(VIDEO, "Unknown present error {:#010X}, please report.", res);
ERROR_LOG_FMT(VIDEO, "Unknown present error {:#010X} {}, please report.",
static_cast<u32>(res), VkResultToString(res));
m_swap_chain->RecreateSwapChain();
}

res = m_swap_chain->AcquireNextImage();
if (res != VK_SUCCESS)
PanicAlertFmt("Failed to grab image from swap chain: {:#010X}", res);
PanicAlertFmt("Failed to grab image from swap chain: {:#010X} {}", static_cast<u32>(res),
VkResultToString(res));
}

// Transition from undefined (or present src, but it can be substituted) to
Expand Down
14 changes: 7 additions & 7 deletions Source/Core/VideoBackends/Vulkan/VKVertexFormat.cpp
Expand Up @@ -66,14 +66,14 @@ void VertexFormat::MapAttributes()

if (m_decl.position.enable)
AddAttribute(
SHADER_POSITION_ATTRIB, 0,
ShaderAttrib::Position, 0,
VarToVkFormat(m_decl.position.type, m_decl.position.components, m_decl.position.integer),
m_decl.position.offset);

for (uint32_t i = 0; i < 3; i++)
{
if (m_decl.normals[i].enable)
AddAttribute(SHADER_NORMAL_ATTRIB + i, 0,
AddAttribute(ShaderAttrib::Normal + i, 0,
VarToVkFormat(m_decl.normals[i].type, m_decl.normals[i].components,
m_decl.normals[i].integer),
m_decl.normals[i].offset);
Expand All @@ -82,7 +82,7 @@ void VertexFormat::MapAttributes()
for (uint32_t i = 0; i < 2; i++)
{
if (m_decl.colors[i].enable)
AddAttribute(SHADER_COLOR0_ATTRIB + i, 0,
AddAttribute(ShaderAttrib::Color0 + i, 0,
VarToVkFormat(m_decl.colors[i].type, m_decl.colors[i].components,
m_decl.colors[i].integer),
m_decl.colors[i].offset);
Expand All @@ -91,14 +91,14 @@ void VertexFormat::MapAttributes()
for (uint32_t i = 0; i < 8; i++)
{
if (m_decl.texcoords[i].enable)
AddAttribute(SHADER_TEXTURE0_ATTRIB + i, 0,
AddAttribute(ShaderAttrib::TexCoord0 + i, 0,
VarToVkFormat(m_decl.texcoords[i].type, m_decl.texcoords[i].components,
m_decl.texcoords[i].integer),
m_decl.texcoords[i].offset);
}

if (m_decl.posmtx.enable)
AddAttribute(SHADER_POSMTX_ATTRIB, 0,
AddAttribute(ShaderAttrib::PositionMatrix, 0,
VarToVkFormat(m_decl.posmtx.type, m_decl.posmtx.components, m_decl.posmtx.integer),
m_decl.posmtx.offset);
}
Expand All @@ -118,12 +118,12 @@ void VertexFormat::SetupInputState()
m_input_state_info.pVertexAttributeDescriptions = m_attribute_descriptions.data();
}

void VertexFormat::AddAttribute(uint32_t location, uint32_t binding, VkFormat format,
void VertexFormat::AddAttribute(ShaderAttrib location, uint32_t binding, VkFormat format,
uint32_t offset)
{
ASSERT(m_num_attributes < MAX_VERTEX_ATTRIBUTES);

m_attribute_descriptions[m_num_attributes].location = location;
m_attribute_descriptions[m_num_attributes].location = static_cast<uint32_t>(location);
m_attribute_descriptions[m_num_attributes].binding = binding;
m_attribute_descriptions[m_num_attributes].format = format;
m_attribute_descriptions[m_num_attributes].offset = offset;
Expand Down
4 changes: 3 additions & 1 deletion Source/Core/VideoBackends/Vulkan/VKVertexFormat.h
Expand Up @@ -8,6 +8,8 @@
#include "VideoBackends/Vulkan/Constants.h"
#include "VideoCommon/NativeVertexFormat.h"

enum class ShaderAttrib : u32;

namespace Vulkan
{
class VertexFormat : public ::NativeVertexFormat
Expand All @@ -23,7 +25,7 @@ class VertexFormat : public ::NativeVertexFormat
void SetupInputState();

private:
void AddAttribute(uint32_t location, uint32_t binding, VkFormat format, uint32_t offset);
void AddAttribute(ShaderAttrib location, uint32_t binding, VkFormat format, uint32_t offset);

VkVertexInputBindingDescription m_binding_description = {};

Expand Down
8 changes: 4 additions & 4 deletions Source/Core/VideoCommon/CPMemory.cpp
Expand Up @@ -107,7 +107,7 @@ void CPState::LoadCPReg(u8 sub_cmd, u32 value)
WARN_LOG_FMT(VIDEO,
"CP MATINDEX_A: an exact value of {:02x} was expected "
"but instead a value of {:02x} was seen",
MATINDEX_A, sub_cmd);
static_cast<u16>(MATINDEX_A), sub_cmd);
}

matrix_index_a.Hex = value;
Expand All @@ -120,7 +120,7 @@ void CPState::LoadCPReg(u8 sub_cmd, u32 value)
WARN_LOG_FMT(VIDEO,
"CP MATINDEX_B: an exact value of {:02x} was expected "
"but instead a value of {:02x} was seen",
MATINDEX_B, sub_cmd);
static_cast<u16>(MATINDEX_B), sub_cmd);
}

matrix_index_b.Hex = value;
Expand All @@ -133,7 +133,7 @@ void CPState::LoadCPReg(u8 sub_cmd, u32 value)
WARN_LOG_FMT(VIDEO,
"CP VCD_LO: an exact value of {:02x} was expected "
"but instead a value of {:02x} was seen",
VCD_LO, sub_cmd);
static_cast<u16>(VCD_LO), sub_cmd);
}

vtx_desc.low.Hex = value;
Expand All @@ -146,7 +146,7 @@ void CPState::LoadCPReg(u8 sub_cmd, u32 value)
WARN_LOG_FMT(VIDEO,
"CP VCD_HI: an exact value of {:02x} was expected "
"but instead a value of {:02x} was seen",
VCD_HI, sub_cmd);
static_cast<u16>(VCD_HI), sub_cmd);
}

vtx_desc.high.Hex = value;
Expand Down
10 changes: 5 additions & 5 deletions Source/Core/VideoCommon/FramebufferShaderGen.cpp
Expand Up @@ -98,16 +98,16 @@ void EmitVertexMainDeclaration(ShaderCode& code, u32 num_tex_inputs, u32 num_col
{
for (u32 i = 0; i < num_tex_inputs; i++)
{
const auto attribute = SHADER_TEXTURE0_ATTRIB + i;
code.Write("ATTRIBUTE_LOCATION({}) in float3 rawtex{};\n", attribute, i);
const auto attribute = ShaderAttrib::TexCoord0 + i;
code.Write("ATTRIBUTE_LOCATION({:s}) in float3 rawtex{};\n", attribute, i);
}
for (u32 i = 0; i < num_color_inputs; i++)
{
const auto attribute = SHADER_COLOR0_ATTRIB + i;
code.Write("ATTRIBUTE_LOCATION({}) in float4 rawcolor{};\n", attribute, i);
const auto attribute = ShaderAttrib::Color0 + i;
code.Write("ATTRIBUTE_LOCATION({:s}) in float4 rawcolor{};\n", attribute, i);
}
if (position_input)
code.Write("ATTRIBUTE_LOCATION({}) in float4 rawpos;\n", SHADER_POSITION_ATTRIB);
code.Write("ATTRIBUTE_LOCATION({:s}) in float4 rawpos;\n", ShaderAttrib::Position);

if (g_ActiveConfig.backend_info.bSupportsGeometryShaders)
{
Expand Down
6 changes: 4 additions & 2 deletions Source/Core/VideoCommon/UberShaderCommon.cpp
Expand Up @@ -118,10 +118,12 @@ void WriteVertexLighting(ShaderCode& out, APIType api_type, std::string_view wor

out.Write(" if ({} != 0u) {{\n", BitfieldExtract<&LitChannel::enablelighting>("alphareg"));
out.Write(" if ({} != 0u) {{\n", BitfieldExtract<&LitChannel::ambsource>("alphareg"));
out.Write(" if ((components & ({}u << chan)) != 0u) // VB_HAS_COL0\n", VB_HAS_COL0);
out.Write(" if ((components & ({}u << chan)) != 0u) // VB_HAS_COL0\n",
static_cast<u32>(VB_HAS_COL0));
out.Write(" lacc.w = int(round(((chan == 0u) ? {}.w : {}.w) * 255.0));\n", in_color_0_var,
in_color_1_var);
out.Write(" else if ((components & {}u) != 0u) // VB_HAS_COLO0\n", VB_HAS_COL0);
out.Write(" else if ((components & {}u) != 0u) // VB_HAS_COLO0\n",
static_cast<u32>(VB_HAS_COL0));
out.Write(" lacc.w = int(round({}.w * 255.0));\n", in_color_0_var);
out.Write(" else\n"
" lacc.w = 255;\n"
Expand Down
44 changes: 22 additions & 22 deletions Source/Core/VideoCommon/UberShaderVertex.cpp
Expand Up @@ -147,15 +147,15 @@ float3 load_input_float3_rawtex(uint vtx_offset, uint attr_offset) {{
}
else
{
out.Write("ATTRIBUTE_LOCATION({}) in float4 rawpos;\n", SHADER_POSITION_ATTRIB);
out.Write("ATTRIBUTE_LOCATION({}) in uint4 posmtx;\n", SHADER_POSMTX_ATTRIB);
out.Write("ATTRIBUTE_LOCATION({}) in float3 rawnormal;\n", SHADER_NORMAL_ATTRIB);
out.Write("ATTRIBUTE_LOCATION({}) in float3 rawtangent;\n", SHADER_TANGENT_ATTRIB);
out.Write("ATTRIBUTE_LOCATION({}) in float3 rawbinormal;\n", SHADER_BINORMAL_ATTRIB);
out.Write("ATTRIBUTE_LOCATION({}) in float4 rawcolor0;\n", SHADER_COLOR0_ATTRIB);
out.Write("ATTRIBUTE_LOCATION({}) in float4 rawcolor1;\n", SHADER_COLOR1_ATTRIB);
for (int i = 0; i < 8; ++i)
out.Write("ATTRIBUTE_LOCATION({}) in float3 rawtex{};\n", SHADER_TEXTURE0_ATTRIB + i, i);
out.Write("ATTRIBUTE_LOCATION({:s}) in float4 rawpos;\n", ShaderAttrib::Position);
out.Write("ATTRIBUTE_LOCATION({:s}) in uint4 posmtx;\n", ShaderAttrib::PositionMatrix);
out.Write("ATTRIBUTE_LOCATION({:s}) in float3 rawnormal;\n", ShaderAttrib::Normal);
out.Write("ATTRIBUTE_LOCATION({:s}) in float3 rawtangent;\n", ShaderAttrib::Tangent);
out.Write("ATTRIBUTE_LOCATION({:s}) in float3 rawbinormal;\n", ShaderAttrib::Binormal);
out.Write("ATTRIBUTE_LOCATION({:s}) in float4 rawcolor0;\n", ShaderAttrib::Color0);
out.Write("ATTRIBUTE_LOCATION({:s}) in float4 rawcolor1;\n", ShaderAttrib::Color1);
for (u32 i = 0; i < 8; ++i)
out.Write("ATTRIBUTE_LOCATION({:s}) in float3 rawtex{};\n", ShaderAttrib::TexCoord0 + i, i);
}

if (host_config.backend_geometry_shaders)
Expand Down Expand Up @@ -223,7 +223,7 @@ float3 load_input_float3_rawtex(uint vtx_offset, uint attr_offset) {{
"float3 N2;\n"
"\n"
"if ((components & {}u) != 0u) {{ // VB_HAS_POSMTXIDX\n",
VB_HAS_POSMTXIDX);
static_cast<u32>(VB_HAS_POSMTXIDX));
LoadVertexAttribute(out, host_config, 2, "posmtx", "uint4", "ubyte4");
out.Write(" // Vertex format has a per-vertex matrix\n"
" int posidx = int(posmtx.r);\n"
Expand Down Expand Up @@ -258,7 +258,7 @@ float3 load_input_float3_rawtex(uint vtx_offset, uint attr_offset) {{
"float3 _normal = float3(0.0, 0.0, 0.0);\n"
"if ((components & {}u) != 0u) // VB_HAS_NORMAL\n"
"{{\n",
VB_HAS_NORMAL);
static_cast<u32>(VB_HAS_NORMAL));
LoadVertexAttribute(out, host_config, 2, "rawnormal", "float3", "float3");
out.Write(" _normal = normalize(float3(dot(N0, rawnormal), dot(N1, rawnormal), dot(N2, "
"rawnormal)));\n"
Expand All @@ -267,7 +267,7 @@ float3 load_input_float3_rawtex(uint vtx_offset, uint attr_offset) {{
"float3 _tangent = float3(0.0, 0.0, 0.0);\n"
"if ((components & {}u) != 0u) // VB_HAS_TANGENT\n"
"{{\n",
VB_HAS_TANGENT);
static_cast<u32>(VB_HAS_TANGENT));
LoadVertexAttribute(out, host_config, 2, "rawtangent", "float3", "float3");
out.Write(" _tangent = float3(dot(N0, rawtangent), dot(N1, rawtangent), dot(N2, rawtangent));\n"
"}}\n"
Expand All @@ -280,7 +280,7 @@ float3 load_input_float3_rawtex(uint vtx_offset, uint attr_offset) {{
"float3 _binormal = float3(0.0, 0.0, 0.0);\n"
"if ((components & {}u) != 0u) // VB_HAS_BINORMAL\n"
"{{\n",
VB_HAS_BINORMAL);
static_cast<u32>(VB_HAS_BINORMAL));
LoadVertexAttribute(out, host_config, 2, "rawbinormal", "float3", "float3");
out.Write(" _binormal = float3(dot(N0, rawbinormal), dot(N1, rawbinormal), dot(N2, "
"rawbinormal));\n"
Expand All @@ -301,26 +301,26 @@ float3 load_input_float3_rawtex(uint vtx_offset, uint attr_offset) {{
out.Write("// To use color 1, the vertex descriptor must have color 0 and 1.\n"
"// If color 1 is present but not color 0, it is used for lighting channel 0.\n"
"bool use_color_1 = ((components & {0}u) == {0}u); // VB_HAS_COL0 | VB_HAS_COL1\n",
VB_HAS_COL0 | VB_HAS_COL1);
static_cast<u32>(VB_HAS_COL0 | VB_HAS_COL1));

out.Write("if ((components & {0}u) == {0}u) // VB_HAS_COL0 | VB_HAS_COL1\n"
"{{\n",
VB_HAS_COL0 | VB_HAS_COL1);
static_cast<u32>(VB_HAS_COL0 | VB_HAS_COL1));
LoadVertexAttribute(out, host_config, 2, "rawcolor0", "float4", "ubyte4");
LoadVertexAttribute(out, host_config, 2, "rawcolor1", "float4", "ubyte4");
out.Write(" vertex_color_0 = rawcolor0;\n"
" vertex_color_1 = rawcolor1;\n"
"}}\n"
"else if ((components & {}u) != 0u) // VB_HAS_COL0\n"
"{{\n",
VB_HAS_COL0);
static_cast<u32>(VB_HAS_COL0));
LoadVertexAttribute(out, host_config, 2, "rawcolor0", "float4", "ubyte4");
out.Write(" vertex_color_0 = rawcolor0;\n"
" vertex_color_1 = rawcolor0;\n"
"}}\n"
"else if ((components & {}u) != 0u) // VB_HAS_COL1\n"
"{{\n",
VB_HAS_COL1);
static_cast<u32>(VB_HAS_COL1));
LoadVertexAttribute(out, host_config, 2, "rawcolor1", "float4", "ubyte4");
out.Write(" vertex_color_0 = rawcolor1;\n"
" vertex_color_1 = rawcolor1;\n"
Expand Down Expand Up @@ -355,7 +355,7 @@ float3 load_input_float3_rawtex(uint vtx_offset, uint attr_offset) {{
" float4 other_p1 = P1;\n"
" float4 other_p2 = P2;\n"
" if ((components & {}u) != 0u) {{ // VB_HAS_POSMTXIDX\n",
VB_HAS_POSMTXIDX);
static_cast<u32>(VB_HAS_POSMTXIDX));
out.Write(" uint other_posidx = load_input_uint4_ubyte4(other_base_offset, "
"vertex_offset_posmtx).r;\n"
" other_p0 = " I_TRANSFORMMATRICES "[other_posidx];\n"
Expand Down Expand Up @@ -545,23 +545,23 @@ static void GenVertexShaderTexGens(APIType api_type, const ShaderHostConfig& hos
out.Write(" case {:s}:\n", SourceRow::Normal);
out.Write(" if ((components & {}u) != 0u) // VB_HAS_NORMAL\n"
" {{\n",
VB_HAS_NORMAL);
static_cast<u32>(VB_HAS_NORMAL));
LoadVertexAttribute(out, host_config, 6, "rawnormal", "float3", "float3");
out.Write(" coord.xyz = rawnormal.xyz;\n"
" }}\n"
" break;\n\n");
out.Write(" case {:s}:\n", SourceRow::BinormalT);
out.Write(" if ((components & {}u) != 0u) // VB_HAS_TANGENT\n"
" {{\n",
VB_HAS_TANGENT);
static_cast<u32>(VB_HAS_TANGENT));
LoadVertexAttribute(out, host_config, 6, "rawtangent", "float3", "float3");
out.Write(" coord.xyz = rawtangent.xyz;\n"
" }}\n"
" break;\n\n");
out.Write(" case {:s}:\n", SourceRow::BinormalB);
out.Write(" if ((components & {}u) != 0u) // VB_HAS_BINORMAL\n"
" {{\n",
VB_HAS_BINORMAL);
static_cast<u32>(VB_HAS_BINORMAL));
LoadVertexAttribute(out, host_config, 6, "rawbinormal", "float3", "float3");
out.Write(" coord.xyz = rawbinormal.xyz;\n"
" }}\n"
Expand Down Expand Up @@ -625,7 +625,7 @@ static void GenVertexShaderTexGens(APIType api_type, const ShaderHostConfig& hos
out.Write(" default:\n"
" {{\n");
out.Write(" if ((components & ({}u /* VB_HAS_TEXMTXIDX0 */ << texgen)) != 0u) {{\n",
VB_HAS_TEXMTXIDX0);
static_cast<u32>(VB_HAS_TEXMTXIDX0));
if (host_config.backend_dynamic_vertex_loader || host_config.backend_vs_point_line_expand)
{
out.Write(" int tmp = int(load_input_float3_rawtex(vertex_base_offset, "
Expand Down
16 changes: 8 additions & 8 deletions Source/Core/VideoCommon/VertexShaderGen.cpp
Expand Up @@ -118,28 +118,28 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho

if (uid_data->vs_expand == VSExpand::None)
{
out.Write("ATTRIBUTE_LOCATION({}) in float4 rawpos;\n", SHADER_POSITION_ATTRIB);
out.Write("ATTRIBUTE_LOCATION({:s}) in float4 rawpos;\n", ShaderAttrib::Position);
if ((uid_data->components & VB_HAS_POSMTXIDX) != 0)
out.Write("ATTRIBUTE_LOCATION({}) in uint4 posmtx;\n", SHADER_POSMTX_ATTRIB);
out.Write("ATTRIBUTE_LOCATION({:s}) in uint4 posmtx;\n", ShaderAttrib::PositionMatrix);
if ((uid_data->components & VB_HAS_NORMAL) != 0)
out.Write("ATTRIBUTE_LOCATION({}) in float3 rawnormal;\n", SHADER_NORMAL_ATTRIB);
out.Write("ATTRIBUTE_LOCATION({:s}) in float3 rawnormal;\n", ShaderAttrib::Normal);
if ((uid_data->components & VB_HAS_TANGENT) != 0)
out.Write("ATTRIBUTE_LOCATION({}) in float3 rawtangent;\n", SHADER_TANGENT_ATTRIB);
out.Write("ATTRIBUTE_LOCATION({:s}) in float3 rawtangent;\n", ShaderAttrib::Tangent);
if ((uid_data->components & VB_HAS_BINORMAL) != 0)
out.Write("ATTRIBUTE_LOCATION({}) in float3 rawbinormal;\n", SHADER_BINORMAL_ATTRIB);
out.Write("ATTRIBUTE_LOCATION({:s}) in float3 rawbinormal;\n", ShaderAttrib::Binormal);

if ((uid_data->components & VB_HAS_COL0) != 0)
out.Write("ATTRIBUTE_LOCATION({}) in float4 rawcolor0;\n", SHADER_COLOR0_ATTRIB);
out.Write("ATTRIBUTE_LOCATION({:s}) in float4 rawcolor0;\n", ShaderAttrib::Color0);
if ((uid_data->components & VB_HAS_COL1) != 0)
out.Write("ATTRIBUTE_LOCATION({}) in float4 rawcolor1;\n", SHADER_COLOR1_ATTRIB);
out.Write("ATTRIBUTE_LOCATION({:s}) in float4 rawcolor1;\n", ShaderAttrib::Color1);

for (u32 i = 0; i < 8; ++i)
{
const u32 has_texmtx = (uid_data->components & (VB_HAS_TEXMTXIDX0 << i));

if ((uid_data->components & (VB_HAS_UV0 << i)) != 0 || has_texmtx != 0)
{
out.Write("ATTRIBUTE_LOCATION({}) in float{} rawtex{};\n", SHADER_TEXTURE0_ATTRIB + i,
out.Write("ATTRIBUTE_LOCATION({:s}) in float{} rawtex{};\n", ShaderAttrib::TexCoord0 + i,
has_texmtx != 0 ? 3 : 2, i);
}
}
Expand Down
48 changes: 32 additions & 16 deletions Source/Core/VideoCommon/VertexShaderGen.h
Expand Up @@ -4,6 +4,8 @@
#pragma once

#include "Common/CommonTypes.h"
#include "Common/EnumFormatter.h"

#include "VideoCommon/LightingShaderGen.h"
#include "VideoCommon/ShaderGenCommon.h"

Expand All @@ -14,25 +16,39 @@ enum class SourceRow : u32;
enum class VSExpand : u32;

// TODO should be reordered
enum : int
enum class ShaderAttrib : u32
{
SHADER_POSITION_ATTRIB = 0,
SHADER_POSMTX_ATTRIB = 1,
SHADER_NORMAL_ATTRIB = 2,
SHADER_TANGENT_ATTRIB = 3,
SHADER_BINORMAL_ATTRIB = 4,
SHADER_COLOR0_ATTRIB = 5,
SHADER_COLOR1_ATTRIB = 6,
Position = 0,
PositionMatrix = 1,
Normal = 2,
Tangent = 3,
Binormal = 4,
Color0 = 5,
Color1 = 6,

SHADER_TEXTURE0_ATTRIB = 8,
SHADER_TEXTURE1_ATTRIB = 9,
SHADER_TEXTURE2_ATTRIB = 10,
SHADER_TEXTURE3_ATTRIB = 11,
SHADER_TEXTURE4_ATTRIB = 12,
SHADER_TEXTURE5_ATTRIB = 13,
SHADER_TEXTURE6_ATTRIB = 14,
SHADER_TEXTURE7_ATTRIB = 15
TexCoord0 = 8,
TexCoord1 = 9,
TexCoord2 = 10,
TexCoord3 = 11,
TexCoord4 = 12,
TexCoord5 = 13,
TexCoord6 = 14,
TexCoord7 = 15
};
template <>
struct fmt::formatter<ShaderAttrib> : EnumFormatter<ShaderAttrib::TexCoord7>
{
static constexpr array_type names = {
"Position", "Position Matrix", "Normal", "Tangent", "Binormal", "Color 0",
"Color 1", nullptr, "Tex Coord 0", "Tex Coord 1", "Tex Coord 2", "Tex Coord 3",
"Tex Coord 4", "Tex Coord 5", "Tex Coord 6", "Tex Coord 7"};
constexpr formatter() : EnumFormatter(names) {}
};
// Intended for offsetting from Color0/TexCoord0
constexpr ShaderAttrib operator+(ShaderAttrib attrib, int offset)
{
return static_cast<ShaderAttrib>(static_cast<u8>(attrib) + offset);
}

#pragma pack(1)

Expand Down