Chore: Enable warnings as errors on MSVC (#6456)
* tests: add Sanity test for SplitFilename83 fix test fix test * disable `C4715:not all control paths return a value` for nihstro includes nihstro: no warn * Chore: Enable warnings as errors on msvc + fix warnings fixes some more warnings clang-format * more fixes * Externals: Add target_compile_options `/W0` nihstro-headers and ... Revert "disable `C4715:not all control paths return a value` for nihstro includes" This reverts commit 606d79b55d3044b744fb835025b8eb0f4ea5b757. * src\citra\config.cpp: ReadSetting: simplify type casting * settings.cpp: Get*Name: remove superflous logs
This commit is contained in:
parent
055a58f01e
commit
41f13456c0
|
@ -60,6 +60,8 @@ CMAKE_DEPENDENT_OPTION(ENABLE_FDK "Use FDK AAC decoder" OFF "NOT ENABLE_FFMPEG_A
|
||||||
|
|
||||||
CMAKE_DEPENDENT_OPTION(CITRA_BUNDLE_LIBRARIES "Bundle dependent libraries with the output executables" ON "APPLE" OFF)
|
CMAKE_DEPENDENT_OPTION(CITRA_BUNDLE_LIBRARIES "Bundle dependent libraries with the output executables" ON "APPLE" OFF)
|
||||||
|
|
||||||
|
option(CITRA_WARNINGS_AS_ERRORS "Enable warnings as errors" ON)
|
||||||
|
|
||||||
if (CITRA_USE_PRECOMPILED_HEADERS)
|
if (CITRA_USE_PRECOMPILED_HEADERS)
|
||||||
if (MSVC AND CCACHE)
|
if (MSVC AND CCACHE)
|
||||||
# buildcache does not properly cache PCH files, leading to compilation errors.
|
# buildcache does not properly cache PCH files, leading to compilation errors.
|
||||||
|
|
|
@ -103,7 +103,9 @@ target_include_directories(microprofile INTERFACE ./microprofile)
|
||||||
# Nihstro
|
# Nihstro
|
||||||
add_library(nihstro-headers INTERFACE)
|
add_library(nihstro-headers INTERFACE)
|
||||||
target_include_directories(nihstro-headers INTERFACE ./nihstro/include)
|
target_include_directories(nihstro-headers INTERFACE ./nihstro/include)
|
||||||
|
if (MSVC)
|
||||||
|
target_compile_options(nihstro-headers INTERFACE /W0)
|
||||||
|
endif()
|
||||||
# Open Source Archives
|
# Open Source Archives
|
||||||
add_subdirectory(open_source_archives)
|
add_subdirectory(open_source_archives)
|
||||||
|
|
||||||
|
|
|
@ -24,67 +24,62 @@ if (MSVC)
|
||||||
# /W3 - Level 3 warnings
|
# /W3 - Level 3 warnings
|
||||||
# /MP - Multi-threaded compilation
|
# /MP - Multi-threaded compilation
|
||||||
# /Zi - Output debugging information
|
# /Zi - Output debugging information
|
||||||
|
# /Zm - Specifies the precompiled header memory allocation limit
|
||||||
# /Zo - Enhanced debug info for optimized builds
|
# /Zo - Enhanced debug info for optimized builds
|
||||||
# /permissive- - Enables stricter C++ standards conformance checks
|
# /permissive- - Enables stricter C++ standards conformance checks
|
||||||
# /EHsc - C++-only exception handling semantics
|
# /EHsc - C++-only exception handling semantics
|
||||||
|
# /utf-8 - Set source and execution character sets to UTF-8
|
||||||
# /volatile:iso - Use strict standards-compliant volatile semantics.
|
# /volatile:iso - Use strict standards-compliant volatile semantics.
|
||||||
# /Zc:externConstexpr - Allow extern constexpr variables to have external linkage, like the standard mandates
|
# /Zc:externConstexpr - Allow extern constexpr variables to have external linkage, like the standard mandates
|
||||||
# /Zc:inline - Let codegen omit inline functions in object files
|
# /Zc:inline - Let codegen omit inline functions in object files
|
||||||
# /Zc:throwingNew - Let codegen assume `operator new` (without std::nothrow) will never return null
|
# /Zc:throwingNew - Let codegen assume `operator new` (without std::nothrow) will never return null
|
||||||
# /external:* - Suppress warnings from external headers
|
# /GT - Supports fiber safety for data allocated using static thread-local storage
|
||||||
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
|
||||||
# Ignore /Zc:externConstexpr /Zc:throwingNew /experimental:external when using clang-cl
|
|
||||||
add_compile_options(
|
|
||||||
/MP
|
|
||||||
/permissive-
|
|
||||||
/EHsc
|
|
||||||
/volatile:iso
|
|
||||||
/Zc:inline
|
|
||||||
/external:I "${CMAKE_SOURCE_DIR}/externals"
|
|
||||||
/external:anglebrackets
|
|
||||||
/external:W0
|
|
||||||
|
|
||||||
# Warnings
|
|
||||||
/W3
|
|
||||||
/we4062 # enumerator 'identifier' in a switch of enum 'enumeration' is not handled
|
|
||||||
/we4101 # 'identifier': unreferenced local variable
|
|
||||||
/we4265 # 'class': class has virtual functions, but destructor is not virtual
|
|
||||||
/we4267 # 'var': conversion from 'size_t' to 'type', possible loss of data
|
|
||||||
/we4388 # signed/unsigned mismatch
|
|
||||||
/we4547 # 'operator' : operator before comma has no effect; expected operator with side-effect
|
|
||||||
/we4549 # 'operator1': operator before comma has no effect; did you intend 'operator2'?
|
|
||||||
/we4555 # Expression has no effect; expected expression with side-effect
|
|
||||||
/we4834 # Discarding return value of function with 'nodiscard' attribute
|
|
||||||
/we5038 # data member 'member1' will be initialized after data member 'member2'
|
|
||||||
)
|
|
||||||
else()
|
|
||||||
add_compile_options(
|
add_compile_options(
|
||||||
/MP
|
/MP
|
||||||
|
/Zm200
|
||||||
/Zo
|
/Zo
|
||||||
/permissive-
|
/permissive-
|
||||||
/EHsc
|
/EHsc
|
||||||
|
/std:c++latest
|
||||||
|
/utf-8
|
||||||
/volatile:iso
|
/volatile:iso
|
||||||
/Zc:externConstexpr
|
/Zc:externConstexpr
|
||||||
/Zc:inline
|
/Zc:inline
|
||||||
/Zc:throwingNew
|
/Zc:throwingNew
|
||||||
/experimental:external
|
/GT
|
||||||
/external:I "${CMAKE_SOURCE_DIR}/externals"
|
|
||||||
/external:anglebrackets
|
# External headers diagnostics
|
||||||
/external:W0
|
/experimental:external # Enables the external headers options. This option isn't required in Visual Studio 2019 version 16.10 and later
|
||||||
|
/external:anglebrackets # Treats all headers included by #include <header>, where the header file is enclosed in angle brackets (< >), as external headers
|
||||||
|
/external:W0 # Sets the default warning level to 0 for external headers, effectively turning off warnings for external headers
|
||||||
|
|
||||||
# Warnings
|
# Warnings
|
||||||
/W3
|
/W3
|
||||||
/we4062 # enumerator 'identifier' in a switch of enum 'enumeration' is not handled
|
|
||||||
/we4101 # 'identifier': unreferenced local variable
|
/we4062 # Enumerator 'identifier' in a switch of enum 'enumeration' is not handled
|
||||||
|
/we4189 # 'identifier': local variable is initialized but not referenced
|
||||||
/we4265 # 'class': class has virtual functions, but destructor is not virtual
|
/we4265 # 'class': class has virtual functions, but destructor is not virtual
|
||||||
/we4267 # 'var': conversion from 'size_t' to 'type', possible loss of data
|
/we4388 # 'expression': signed/unsigned mismatch
|
||||||
/we4388 # signed/unsigned mismatch
|
/we4389 # 'operator': signed/unsigned mismatch
|
||||||
|
/we4456 # Declaration of 'identifier' hides previous local declaration
|
||||||
|
/we4457 # Declaration of 'identifier' hides function parameter
|
||||||
|
# /we4458 TODO: Enable me # Declaration of 'identifier' hides class member
|
||||||
|
/we4459 # Declaration of 'identifier' hides global declaration
|
||||||
|
/we4505 # 'function': unreferenced local function has been removed
|
||||||
/we4547 # 'operator': operator before comma has no effect; expected operator with side-effect
|
/we4547 # 'operator': operator before comma has no effect; expected operator with side-effect
|
||||||
/we4549 # 'operator1': operator before comma has no effect; did you intend 'operator2'?
|
/we4549 # 'operator1': operator before comma has no effect; did you intend 'operator2'?
|
||||||
/we4555 # Expression has no effect; expected expression with side-effect
|
/we4555 # Expression has no effect; expected expression with side-effect
|
||||||
/we4834 # Discarding return value of function with 'nodiscard' attribute
|
/we4826 # Conversion from 'type1' to 'type2' is sign-extended. This may cause unexpected runtime behavior.
|
||||||
/we5038 # data member 'member1' will be initialized after data member 'member2'
|
/we5038 # data member 'member1' will be initialized after data member 'member2'
|
||||||
|
/we5233 # explicit lambda capture 'identifier' is not used
|
||||||
|
/we5245 # 'function': unreferenced function with internal linkage has been removed
|
||||||
|
|
||||||
|
/wd4100 # 'identifier': unreferenced formal parameter
|
||||||
|
/wd4324 # 'struct_name': structure was padded due to __declspec(align())
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (CITRA_WARNINGS_AS_ERRORS)
|
||||||
|
add_compile_options(/WX)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Since MSVC's debugging information is not very deterministic, so we have to disable it
|
# Since MSVC's debugging information is not very deterministic, so we have to disable it
|
||||||
|
|
|
@ -138,9 +138,7 @@ std::optional<BinaryResponse> WMFDecoder::Impl::Initalize(const BinaryRequest& r
|
||||||
|
|
||||||
MFOutputState WMFDecoder::Impl::DecodingLoop(ADTSData adts_header,
|
MFOutputState WMFDecoder::Impl::DecodingLoop(ADTSData adts_header,
|
||||||
std::array<std::vector<u8>, 2>& out_streams) {
|
std::array<std::vector<u8>, 2>& out_streams) {
|
||||||
MFOutputState output_status = MFOutputState::OK;
|
|
||||||
std::optional<std::vector<f32>> output_buffer;
|
std::optional<std::vector<f32>> output_buffer;
|
||||||
unique_mfptr<IMFSample> output;
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
auto [output_status, output] = ReceiveSample(transform.get(), out_stream_id);
|
auto [output_status, output] = ReceiveSample(transform.get(), out_stream_id);
|
||||||
|
|
|
@ -450,7 +450,8 @@ void DspLle::SetServiceToInterrupt(std::weak_ptr<Service::DSP::DSP_DSP> dsp) {
|
||||||
return;
|
return;
|
||||||
if (pipe == 0) {
|
if (pipe == 0) {
|
||||||
// pipe 0 is for debug. 3DS automatically drains this pipe and discards the data
|
// pipe 0 is for debug. 3DS automatically drains this pipe and discards the data
|
||||||
impl->ReadPipe(static_cast<u8>(pipe), impl->GetPipeReadableSize(pipe));
|
impl->ReadPipe(static_cast<u8>(pipe),
|
||||||
|
impl->GetPipeReadableSize(static_cast<u8>(pipe)));
|
||||||
} else {
|
} else {
|
||||||
std::lock_guard lock(HLE::g_hle_lock);
|
std::lock_guard lock(HLE::g_hle_lock);
|
||||||
if (auto locked = dsp.lock()) {
|
if (auto locked = dsp.lock()) {
|
||||||
|
|
|
@ -368,6 +368,8 @@ int main(int argc, char** argv) {
|
||||||
case Settings::GraphicsAPI::Software:
|
case Settings::GraphicsAPI::Software:
|
||||||
return std::make_unique<EmuWindow_SDL2_SW>(fullscreen, is_secondary);
|
return std::make_unique<EmuWindow_SDL2_SW>(fullscreen, is_secondary);
|
||||||
}
|
}
|
||||||
|
LOG_ERROR(Frontend, "Invalid Graphics API, using OpenGL");
|
||||||
|
return std::make_unique<EmuWindow_SDL2_GL>(fullscreen, is_secondary);
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto emu_window{create_emu_window(fullscreen, false)};
|
const auto emu_window{create_emu_window(fullscreen, false)};
|
||||||
|
|
|
@ -88,7 +88,8 @@ void Config::ReadSetting(const std::string& group, Settings::Setting<bool>& sett
|
||||||
template <typename Type, bool ranged>
|
template <typename Type, bool ranged>
|
||||||
void Config::ReadSetting(const std::string& group, Settings::Setting<Type, ranged>& setting) {
|
void Config::ReadSetting(const std::string& group, Settings::Setting<Type, ranged>& setting) {
|
||||||
if constexpr (std::is_floating_point_v<Type>) {
|
if constexpr (std::is_floating_point_v<Type>) {
|
||||||
setting = sdl2_config->GetReal(group, setting.GetLabel(), setting.GetDefault());
|
setting = static_cast<Type>(
|
||||||
|
sdl2_config->GetReal(group, setting.GetLabel(), setting.GetDefault()));
|
||||||
} else {
|
} else {
|
||||||
setting = static_cast<Type>(sdl2_config->GetInteger(
|
setting = static_cast<Type>(sdl2_config->GetInteger(
|
||||||
group, setting.GetLabel(), static_cast<long>(setting.GetDefault())));
|
group, setting.GetLabel(), static_cast<long>(setting.GetDefault())));
|
||||||
|
|
|
@ -71,7 +71,7 @@ protected:
|
||||||
SDL_Window* render_window;
|
SDL_Window* render_window;
|
||||||
|
|
||||||
/// Internal SDL2 window ID
|
/// Internal SDL2 window ID
|
||||||
int render_window_id{};
|
u32 render_window_id{};
|
||||||
|
|
||||||
/// Fake hidden window for the core context
|
/// Fake hidden window for the core context
|
||||||
SDL_Window* dummy_window;
|
SDL_Window* dummy_window;
|
||||||
|
|
|
@ -67,9 +67,10 @@ void EmuWindow_SDL2_SW::Present() {
|
||||||
Core::kScreenTopWidth, Core::kScreenTopHeight + Core::kScreenBottomHeight, false, false)};
|
Core::kScreenTopWidth, Core::kScreenTopHeight + Core::kScreenBottomHeight, false, false)};
|
||||||
|
|
||||||
while (IsOpen()) {
|
while (IsOpen()) {
|
||||||
SDL_SetRenderDrawColor(renderer, Settings::values.bg_red.GetValue() * 255,
|
SDL_SetRenderDrawColor(renderer,
|
||||||
Settings::values.bg_green.GetValue() * 255,
|
static_cast<Uint8>(Settings::values.bg_red.GetValue() * 255),
|
||||||
Settings::values.bg_blue.GetValue() * 255, 0xFF);
|
static_cast<Uint8>(Settings::values.bg_green.GetValue() * 255),
|
||||||
|
static_cast<Uint8>(Settings::values.bg_blue.GetValue() * 255), 0xFF);
|
||||||
SDL_RenderClear(renderer);
|
SDL_RenderClear(renderer);
|
||||||
|
|
||||||
const auto draw_screen = [&](int fb_id) {
|
const auto draw_screen = [&](int fb_id) {
|
||||||
|
@ -121,6 +122,7 @@ SDL_Surface* EmuWindow_SDL2_SW::LoadFramebuffer(int fb_id) {
|
||||||
case GPU::Regs::PixelFormat::RGBA4:
|
case GPU::Regs::PixelFormat::RGBA4:
|
||||||
return Common::Color::DecodeRGBA4(pixel);
|
return Common::Color::DecodeRGBA4(pixel);
|
||||||
}
|
}
|
||||||
|
UNREACHABLE();
|
||||||
}();
|
}();
|
||||||
|
|
||||||
u8* dst_pixel = reinterpret_cast<u8*>(surface->pixels) + (y * width + x) * 4;
|
u8* dst_pixel = reinterpret_cast<u8*>(surface->pixels) + (y * width + x) * 4;
|
||||||
|
|
|
@ -338,6 +338,7 @@ struct SoftwareRenderWidget : public RenderWidget {
|
||||||
case GPU::Regs::PixelFormat::RGBA4:
|
case GPU::Regs::PixelFormat::RGBA4:
|
||||||
return Common::Color::DecodeRGBA4(pixel);
|
return Common::Color::DecodeRGBA4(pixel);
|
||||||
}
|
}
|
||||||
|
UNREACHABLE();
|
||||||
}();
|
}();
|
||||||
|
|
||||||
image.setPixel(x, y, qRgba(color.r(), color.g(), color.b(), color.a()));
|
image.setPixel(x, y, qRgba(color.r(), color.g(), color.b(), color.a()));
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
|
#include "common/assert.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
|
|
||||||
namespace ConfigurationShared {
|
namespace ConfigurationShared {
|
||||||
|
@ -91,6 +92,7 @@ Type GetComboboxSetting(int index, const Settings::SwitchableSetting<Type, range
|
||||||
return static_cast<Type>(index - ConfigurationShared::USE_GLOBAL_OFFSET);
|
return static_cast<Type>(index - ConfigurationShared::USE_GLOBAL_OFFSET);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given a Qt widget sets the background color to indicate whether the setting
|
/// Given a Qt widget sets the background color to indicate whether the setting
|
||||||
|
|
|
@ -623,8 +623,10 @@ void GameList::AddCustomDirPopup(QMenu& context_menu, QModelIndex selected) {
|
||||||
void GameList::AddPermDirPopup(QMenu& context_menu, QModelIndex selected) {
|
void GameList::AddPermDirPopup(QMenu& context_menu, QModelIndex selected) {
|
||||||
const int game_dir_index = selected.data(GameListDir::GameDirRole).toInt();
|
const int game_dir_index = selected.data(GameListDir::GameDirRole).toInt();
|
||||||
|
|
||||||
QAction* move_up = context_menu.addAction(tr("\u25b2 Move Up"));
|
QAction* move_up =
|
||||||
QAction* move_down = context_menu.addAction(tr("\u25bc Move Down "));
|
context_menu.addAction(tr("Move Up").prepend(QString::fromWCharArray(L"\u25b2 ")));
|
||||||
|
QAction* move_down =
|
||||||
|
context_menu.addAction(tr("Move Down").prepend(QString::fromWCharArray(L"\u25bc ")));
|
||||||
QAction* open_directory_location = context_menu.addAction(tr("Open Directory Location"));
|
QAction* open_directory_location = context_menu.addAction(tr("Open Directory Location"));
|
||||||
|
|
||||||
const int row = selected.row();
|
const int row = selected.row();
|
||||||
|
|
|
@ -2287,7 +2287,8 @@ void GMainWindow::UpdateBootHomeMenuState() {
|
||||||
for (u32 region = 0; region < Core::NUM_SYSTEM_TITLE_REGIONS; region++) {
|
for (u32 region = 0; region < Core::NUM_SYSTEM_TITLE_REGIONS; region++) {
|
||||||
const auto path = Core::GetHomeMenuNcchPath(region);
|
const auto path = Core::GetHomeMenuNcchPath(region);
|
||||||
ui->menu_Boot_Home_Menu->actions().at(region)->setEnabled(
|
ui->menu_Boot_Home_Menu->actions().at(region)->setEnabled(
|
||||||
(current_region == Settings::REGION_VALUE_AUTO_SELECT || current_region == region) &&
|
(current_region == Settings::REGION_VALUE_AUTO_SELECT ||
|
||||||
|
current_region == static_cast<int>(region)) &&
|
||||||
!path.empty() && FileUtil::Exists(path));
|
!path.empty() && FileUtil::Exists(path));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,6 +131,25 @@ add_library(citra_common STATIC
|
||||||
zstd_compression.h
|
zstd_compression.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (MSVC)
|
||||||
|
target_compile_definitions(citra_common PRIVATE
|
||||||
|
# The standard library doesn't provide any replacement for codecvt yet
|
||||||
|
# so we can disable this deprecation warning for the time being.
|
||||||
|
_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING
|
||||||
|
)
|
||||||
|
target_compile_options(citra_common PRIVATE
|
||||||
|
/W4
|
||||||
|
|
||||||
|
/we4242 # 'identifier': conversion from 'type1' to 'type2', possible loss of data
|
||||||
|
/we4254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data
|
||||||
|
/we4800 # Implicit conversion from 'type' to bool. Possible information loss
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
target_compile_options(citra_common PRIVATE
|
||||||
|
$<$<CXX_COMPILER_ID:Clang>:-fsized-deallocation>
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
create_target_directory_groups(citra_common)
|
create_target_directory_groups(citra_common)
|
||||||
|
|
||||||
target_link_libraries(citra_common PUBLIC fmt::fmt microprofile Boost::boost Boost::serialization Boost::iostreams)
|
target_link_libraries(citra_common PUBLIC fmt::fmt microprofile Boost::boost Boost::serialization Boost::iostreams)
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#define ASSERT(_a_) \
|
#define ASSERT(_a_) \
|
||||||
do \
|
do \
|
||||||
if (!(_a_)) [[unlikely]] { \
|
if (!(_a_)) [[unlikely]] { \
|
||||||
[]() CITRA_NO_INLINE { \
|
[]() CITRA_NO_INLINE CITRA_NO_RETURN { \
|
||||||
LOG_CRITICAL(Debug, "Assertion Failed!"); \
|
LOG_CRITICAL(Debug, "Assertion Failed!"); \
|
||||||
Crash(); \
|
Crash(); \
|
||||||
exit(1); \
|
exit(1); \
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
#define ASSERT_MSG(_a_, ...) \
|
#define ASSERT_MSG(_a_, ...) \
|
||||||
do \
|
do \
|
||||||
if (!(_a_)) [[unlikely]] { \
|
if (!(_a_)) [[unlikely]] { \
|
||||||
[&]() CITRA_NO_INLINE { \
|
[&]() CITRA_NO_INLINE CITRA_NO_RETURN { \
|
||||||
LOG_CRITICAL(Debug, "Assertion Failed!\n" __VA_ARGS__); \
|
LOG_CRITICAL(Debug, "Assertion Failed!\n" __VA_ARGS__); \
|
||||||
Crash(); \
|
Crash(); \
|
||||||
exit(1); \
|
exit(1); \
|
||||||
|
@ -35,14 +35,14 @@
|
||||||
while (0)
|
while (0)
|
||||||
|
|
||||||
#define UNREACHABLE() \
|
#define UNREACHABLE() \
|
||||||
([]() CITRA_NO_INLINE { \
|
([]() CITRA_NO_INLINE CITRA_NO_RETURN { \
|
||||||
LOG_CRITICAL(Debug, "Unreachable code!"); \
|
LOG_CRITICAL(Debug, "Unreachable code!"); \
|
||||||
Crash(); \
|
Crash(); \
|
||||||
exit(1); \
|
exit(1); \
|
||||||
}())
|
}())
|
||||||
|
|
||||||
#define UNREACHABLE_MSG(...) \
|
#define UNREACHABLE_MSG(...) \
|
||||||
([&]() CITRA_NO_INLINE { \
|
([&]() CITRA_NO_INLINE CITRA_NO_RETURN { \
|
||||||
LOG_CRITICAL(Debug, "Unreachable code!\n" __VA_ARGS__); \
|
LOG_CRITICAL(Debug, "Unreachable code!\n" __VA_ARGS__); \
|
||||||
Crash(); \
|
Crash(); \
|
||||||
exit(1); \
|
exit(1); \
|
||||||
|
|
|
@ -30,6 +30,12 @@
|
||||||
#define CITRA_NO_INLINE __attribute__((noinline))
|
#define CITRA_NO_INLINE __attribute__((noinline))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define CITRA_NO_RETURN __declspec(noreturn)
|
||||||
|
#else
|
||||||
|
#define CITRA_NO_RETURN __attribute__((noreturn))
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
extern "C" {
|
extern "C" {
|
||||||
__declspec(dllimport) void __stdcall DebugBreak(void);
|
__declspec(dllimport) void __stdcall DebugBreak(void);
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "common/common_paths.h"
|
#include "common/common_paths.h"
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
#include "common/string_util.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
@ -540,7 +541,8 @@ void GetAllFilesFromNestedEntries(FSTEntry& directory, std::vector<FSTEntry>& ou
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DeleteDirRecursively(const std::string& directory, unsigned int recursion) {
|
bool DeleteDirRecursively(const std::string& directory, unsigned int recursion) {
|
||||||
const auto callback = [recursion](u64* num_entries_out, const std::string& directory,
|
const auto callback = [recursion]([[maybe_unused]] u64* num_entries_out,
|
||||||
|
const std::string& directory,
|
||||||
const std::string& virtual_name) -> bool {
|
const std::string& virtual_name) -> bool {
|
||||||
std::string new_path = directory + DIR_SEP_CHR + virtual_name;
|
std::string new_path = directory + DIR_SEP_CHR + virtual_name;
|
||||||
|
|
||||||
|
@ -560,7 +562,8 @@ bool DeleteDirRecursively(const std::string& directory, unsigned int recursion)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CopyDir(const std::string& source_path, const std::string& dest_path) {
|
void CopyDir([[maybe_unused]] const std::string& source_path,
|
||||||
|
[[maybe_unused]] const std::string& dest_path) {
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
if (source_path == dest_path)
|
if (source_path == dest_path)
|
||||||
return;
|
return;
|
||||||
|
@ -900,14 +903,14 @@ void SplitFilename83(const std::string& filename, std::array<char, 9>& short_nam
|
||||||
short_name[7] = '1';
|
short_name[7] = '1';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
short_name[j++] = toupper(letter);
|
short_name[j++] = Common::ToUpper(letter);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get extension.
|
// Get extension.
|
||||||
if (point != std::string::npos) {
|
if (point != std::string::npos) {
|
||||||
j = 0;
|
j = 0;
|
||||||
for (char letter : filename.substr(point + 1, 3))
|
for (char letter : filename.substr(point + 1, 3))
|
||||||
extension[j++] = toupper(letter);
|
extension[j++] = Common::ToUpper(letter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -259,10 +259,10 @@ const char* GetLogClassName(Class log_class) {
|
||||||
#undef CLS
|
#undef CLS
|
||||||
#undef SUB
|
#undef SUB
|
||||||
case Class::Count:
|
case Class::Count:
|
||||||
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
return "Invalid";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* GetLevelName(Level log_level) {
|
const char* GetLevelName(Level log_level) {
|
||||||
|
@ -277,11 +277,11 @@ const char* GetLevelName(Level log_level) {
|
||||||
LVL(Error);
|
LVL(Error);
|
||||||
LVL(Critical);
|
LVL(Critical);
|
||||||
case Level::Count:
|
case Level::Count:
|
||||||
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#undef LVL
|
#undef LVL
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
return "Invalid";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddBackend(std::unique_ptr<Backend> backend) {
|
void AddBackend(std::unique_ptr<Backend> backend) {
|
||||||
|
|
|
@ -111,7 +111,7 @@ void PrintColoredMessage(const Entry& entry) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintMessageToLogcat(const Entry& entry) {
|
void PrintMessageToLogcat([[maybe_unused]] const Entry& entry) {
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
const auto str = FormatLogMessage(entry);
|
const auto str = FormatLogMessage(entry);
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <class Archive>
|
template <class Archive>
|
||||||
void serialize(Archive& ar, const unsigned int) {}
|
void serialize(Archive&, const unsigned int) {}
|
||||||
friend class boost::serialization::access;
|
friend class boost::serialization::access;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,10 @@ std::string_view GetAudioEmulationName(AudioEmulation emulation) {
|
||||||
return "LLE";
|
return "LLE";
|
||||||
case AudioEmulation::LLEMultithreaded:
|
case AudioEmulation::LLEMultithreaded:
|
||||||
return "LLE Multithreaded";
|
return "LLE Multithreaded";
|
||||||
|
default:
|
||||||
|
return "Invalid";
|
||||||
}
|
}
|
||||||
|
UNREACHABLE();
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string_view GetGraphicsAPIName(GraphicsAPI api) {
|
std::string_view GetGraphicsAPIName(GraphicsAPI api) {
|
||||||
|
@ -39,7 +42,10 @@ std::string_view GetGraphicsAPIName(GraphicsAPI api) {
|
||||||
return "Software";
|
return "Software";
|
||||||
case GraphicsAPI::OpenGL:
|
case GraphicsAPI::OpenGL:
|
||||||
return "OpenGL";
|
return "OpenGL";
|
||||||
|
default:
|
||||||
|
return "Invalid";
|
||||||
}
|
}
|
||||||
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string_view GetTextureFilterName(TextureFilter filter) {
|
std::string_view GetTextureFilterName(TextureFilter filter) {
|
||||||
|
@ -56,7 +62,10 @@ std::string_view GetTextureFilterName(TextureFilter filter) {
|
||||||
return "ScaleForce";
|
return "ScaleForce";
|
||||||
case TextureFilter::xBRZ:
|
case TextureFilter::xBRZ:
|
||||||
return "xBRZ";
|
return "xBRZ";
|
||||||
|
default:
|
||||||
|
return "Invalid";
|
||||||
}
|
}
|
||||||
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
|
@ -453,9 +453,9 @@ struct Values {
|
||||||
Setting<u16> custom_bottom_bottom{480, "custom_bottom_bottom"};
|
Setting<u16> custom_bottom_bottom{480, "custom_bottom_bottom"};
|
||||||
Setting<u16> custom_second_layer_opacity{100, "custom_second_layer_opacity"};
|
Setting<u16> custom_second_layer_opacity{100, "custom_second_layer_opacity"};
|
||||||
|
|
||||||
SwitchableSetting<double> bg_red{0.f, "bg_red"};
|
SwitchableSetting<float> bg_red{0.f, "bg_red"};
|
||||||
SwitchableSetting<double> bg_green{0.f, "bg_green"};
|
SwitchableSetting<float> bg_green{0.f, "bg_green"};
|
||||||
SwitchableSetting<double> bg_blue{0.f, "bg_blue"};
|
SwitchableSetting<float> bg_blue{0.f, "bg_blue"};
|
||||||
|
|
||||||
SwitchableSetting<StereoRenderOption> render_3d{StereoRenderOption::Off, "render_3d"};
|
SwitchableSetting<StereoRenderOption> render_3d{StereoRenderOption::Off, "render_3d"};
|
||||||
SwitchableSetting<u32> factor_3d{0, "factor_3d"};
|
SwitchableSetting<u32> factor_3d{0, "factor_3d"};
|
||||||
|
|
|
@ -20,17 +20,27 @@
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
||||||
|
/// Make a char lowercase
|
||||||
|
char ToLower(char c) {
|
||||||
|
return static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Make a char uppercase
|
||||||
|
char ToUpper(char c) {
|
||||||
|
return static_cast<char>(std::toupper(static_cast<unsigned char>(c)));
|
||||||
|
}
|
||||||
|
|
||||||
/// Make a string lowercase
|
/// Make a string lowercase
|
||||||
std::string ToLower(std::string str) {
|
std::string ToLower(std::string str) {
|
||||||
std::transform(str.begin(), str.end(), str.begin(),
|
std::transform(str.begin(), str.end(), str.begin(),
|
||||||
[](unsigned char c) { return std::tolower(c); });
|
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make a string uppercase
|
/// Make a string uppercase
|
||||||
std::string ToUpper(std::string str) {
|
std::string ToUpper(std::string str) {
|
||||||
std::transform(str.begin(), str.end(), str.begin(),
|
std::transform(str.begin(), str.end(), str.begin(),
|
||||||
[](unsigned char c) { return std::toupper(c); });
|
[](unsigned char c) { return static_cast<char>(std::toupper(c)); });
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,12 @@
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
||||||
|
/// Make a char lowercase
|
||||||
|
[[nodiscard]] char ToLower(char c);
|
||||||
|
|
||||||
|
/// Make a char uppercase
|
||||||
|
[[nodiscard]] char ToUpper(char c);
|
||||||
|
|
||||||
/// Make a string lowercase
|
/// Make a string lowercase
|
||||||
[[nodiscard]] std::string ToLower(std::string str);
|
[[nodiscard]] std::string ToLower(std::string str);
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,9 @@ constexpr u32 DepositBits(u32 val) {
|
||||||
u32 mask = mask_;
|
u32 mask = mask_;
|
||||||
u32 res = 0;
|
u32 res = 0;
|
||||||
for (u32 bb = 1; mask; bb += bb) {
|
for (u32 bb = 1; mask; bb += bb) {
|
||||||
|
u32 neg_mask = 0 - mask;
|
||||||
if (val & bb)
|
if (val & bb)
|
||||||
res |= mask & -mask;
|
res |= mask & neg_mask;
|
||||||
mask &= mask - 1;
|
mask &= mask - 1;
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
|
|
@ -242,10 +242,6 @@ public:
|
||||||
template <class Archive>
|
template <class Archive>
|
||||||
void serialize(Archive& ar, const unsigned int) {
|
void serialize(Archive& ar, const unsigned int) {
|
||||||
MoveEvents();
|
MoveEvents();
|
||||||
// NOTE: ts_queue should be empty now
|
|
||||||
// TODO(SaveState): Remove the next two lines when we break compatibility
|
|
||||||
s64 x;
|
|
||||||
ar& x; // to keep compatibility with old save states that stored global_timer
|
|
||||||
ar& event_queue;
|
ar& event_queue;
|
||||||
ar& event_fifo_id;
|
ar& event_fifo_id;
|
||||||
ar& slice_length;
|
ar& slice_length;
|
||||||
|
|
|
@ -383,7 +383,7 @@ void FFmpegAudioStream::ProcessFrame(const VariableAudioFrame& channel0,
|
||||||
LOG_ERROR(Render, "Audio frame dropped: Could not resample data");
|
LOG_ERROR(Render, "Audio frame dropped: Could not resample data");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (static_cast<u64>(resampled_count) < frame_size) {
|
if (resampled_count < frame_size) {
|
||||||
offset = resampled_count;
|
offset = resampled_count;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,14 +118,14 @@ private:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
u64 frame_size{};
|
int frame_size{};
|
||||||
u64 frame_count{};
|
u64 frame_count{};
|
||||||
|
|
||||||
std::unique_ptr<AVFrame, AVFrameDeleter> audio_frame{};
|
std::unique_ptr<AVFrame, AVFrameDeleter> audio_frame{};
|
||||||
std::unique_ptr<SwrContext, SwrContextDeleter> swr_context{};
|
std::unique_ptr<SwrContext, SwrContextDeleter> swr_context{};
|
||||||
|
|
||||||
u8** resampled_data{};
|
u8** resampled_data{};
|
||||||
u64 offset{}; // Number of output samples that are currently in resampled_data.
|
int offset{}; // Number of output samples that are currently in resampled_data.
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -85,6 +85,7 @@ std::u16string Path::AsU16Str() const {
|
||||||
return {};
|
return {};
|
||||||
case LowPathType::Invalid:
|
case LowPathType::Invalid:
|
||||||
case LowPathType::Binary:
|
case LowPathType::Binary:
|
||||||
|
default:
|
||||||
// TODO(yuriks): Add assert
|
// TODO(yuriks): Add assert
|
||||||
LOG_ERROR(Service_FS, "LowPathType cannot be converted to u16string!");
|
LOG_ERROR(Service_FS, "LowPathType cannot be converted to u16string!");
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -144,21 +144,21 @@ void LayeredFS::LoadRelocations() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const FileUtil::DirectoryEntryCallable callback = [this,
|
const FileUtil::DirectoryEntryCallable callback =
|
||||||
&callback](u64* /*num_entries_out*/,
|
[this, &callback]([[maybe_unused]] u64* num_entries_out, const std::string& directory,
|
||||||
const std::string& directory,
|
|
||||||
const std::string& virtual_name) {
|
const std::string& virtual_name) {
|
||||||
auto* parent = directory_path_map.at(directory.substr(patch_path.size() - 1));
|
auto* parent = directory_path_map.at(directory.substr(patch_path.size() - 1));
|
||||||
|
|
||||||
if (FileUtil::IsDirectory(directory + virtual_name + DIR_SEP)) {
|
if (FileUtil::IsDirectory(directory + virtual_name + DIR_SEP)) {
|
||||||
const auto path = (directory + virtual_name + DIR_SEP).substr(patch_path.size() - 1);
|
const auto path =
|
||||||
|
(directory + virtual_name + DIR_SEP).substr(patch_path.size() - 1);
|
||||||
if (!directory_path_map.count(path)) { // Add this directory
|
if (!directory_path_map.count(path)) { // Add this directory
|
||||||
auto directory = std::make_unique<Directory>();
|
auto child_dir = std::make_unique<Directory>();
|
||||||
directory->name = virtual_name;
|
child_dir->name = virtual_name;
|
||||||
directory->path = path;
|
child_dir->path = path;
|
||||||
directory->parent = parent;
|
child_dir->parent = parent;
|
||||||
directory_path_map.emplace(path, directory.get());
|
directory_path_map.emplace(path, child_dir.get());
|
||||||
parent->directories.emplace_back(std::move(directory));
|
parent->directories.emplace_back(std::move(child_dir));
|
||||||
LOG_INFO(Service_FS, "LayeredFS created directory {}", path);
|
LOG_INFO(Service_FS, "LayeredFS created directory {}", path);
|
||||||
}
|
}
|
||||||
return FileUtil::ForeachDirectoryEntry(nullptr, directory + virtual_name + DIR_SEP,
|
return FileUtil::ForeachDirectoryEntry(nullptr, directory + virtual_name + DIR_SEP,
|
||||||
|
|
|
@ -119,12 +119,12 @@ NCCHContainer::NCCHContainer(const std::string& filepath, u32 ncch_offset, u32 p
|
||||||
file = FileUtil::IOFile(filepath, "rb");
|
file = FileUtil::IOFile(filepath, "rb");
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader::ResultStatus NCCHContainer::OpenFile(const std::string& filepath, u32 ncch_offset,
|
Loader::ResultStatus NCCHContainer::OpenFile(const std::string& filepath_, u32 ncch_offset_,
|
||||||
u32 partition) {
|
u32 partition_) {
|
||||||
this->filepath = filepath;
|
filepath = filepath_;
|
||||||
this->ncch_offset = ncch_offset;
|
ncch_offset = ncch_offset_;
|
||||||
this->partition = partition;
|
partition = partition_;
|
||||||
file = FileUtil::IOFile(filepath, "rb");
|
file = FileUtil::IOFile(filepath_, "rb");
|
||||||
|
|
||||||
if (!file.IsOpen()) {
|
if (!file.IsOpen()) {
|
||||||
LOG_WARNING(Service_FS, "Failed to open {}", filepath);
|
LOG_WARNING(Service_FS, "Failed to open {}", filepath);
|
||||||
|
@ -597,12 +597,12 @@ Loader::ResultStatus NCCHContainer::ApplyCodePatch(std::vector<u8>& code) const
|
||||||
}};
|
}};
|
||||||
|
|
||||||
for (const PatchLocation& info : patch_paths) {
|
for (const PatchLocation& info : patch_paths) {
|
||||||
FileUtil::IOFile file{info.path, "rb"};
|
FileUtil::IOFile patch_file{info.path, "rb"};
|
||||||
if (!file)
|
if (!patch_file)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
std::vector<u8> patch(file.GetSize());
|
std::vector<u8> patch(patch_file.GetSize());
|
||||||
if (file.ReadBytes(patch.data(), patch.size()) != patch.size())
|
if (patch_file.ReadBytes(patch.data(), patch.size()) != patch.size())
|
||||||
return Loader::ResultStatus::Error;
|
return Loader::ResultStatus::Error;
|
||||||
|
|
||||||
LOG_INFO(Service_FS, "File {} patching code.bin", info.path);
|
LOG_INFO(Service_FS, "File {} patching code.bin", info.path);
|
||||||
|
|
|
@ -40,7 +40,7 @@ std::vector<HLE::Applets::MiiData> LoadMiis() {
|
||||||
std::array<u8, sizeof(mii)> mii_raw;
|
std::array<u8, sizeof(mii)> mii_raw;
|
||||||
file->Read(saved_miis_offset, sizeof(mii), mii_raw.data());
|
file->Read(saved_miis_offset, sizeof(mii), mii_raw.data());
|
||||||
std::memcpy(&mii, mii_raw.data(), sizeof(mii));
|
std::memcpy(&mii, mii_raw.data(), sizeof(mii));
|
||||||
if (mii.mii_id != 0) {
|
if (mii.mii_id != 0u) {
|
||||||
miis.push_back(mii);
|
miis.push_back(mii);
|
||||||
}
|
}
|
||||||
saved_miis_offset += sizeof(mii);
|
saved_miis_offset += sizeof(mii);
|
||||||
|
|
|
@ -31,8 +31,8 @@ struct MiiSelectorData {
|
||||||
class MiiSelector {
|
class MiiSelector {
|
||||||
public:
|
public:
|
||||||
virtual ~MiiSelector() = default;
|
virtual ~MiiSelector() = default;
|
||||||
virtual void Setup(const MiiSelectorConfig& config) {
|
virtual void Setup(const MiiSelectorConfig& config_) {
|
||||||
this->config = MiiSelectorConfig(config);
|
config = MiiSelectorConfig(config_);
|
||||||
}
|
}
|
||||||
|
|
||||||
const MiiSelectorData& ReceiveData() const {
|
const MiiSelectorData& ReceiveData() const {
|
||||||
|
|
|
@ -144,8 +144,8 @@ const KeyboardData& SoftwareKeyboard::ReceiveData() {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefaultKeyboard::Execute(const Frontend::KeyboardConfig& config) {
|
void DefaultKeyboard::Execute(const Frontend::KeyboardConfig& config_) {
|
||||||
SoftwareKeyboard::Execute(config);
|
SoftwareKeyboard::Execute(config_);
|
||||||
|
|
||||||
auto cfg = Service::CFG::GetModule(Core::System::GetInstance());
|
auto cfg = Service::CFG::GetModule(Core::System::GetInstance());
|
||||||
ASSERT_MSG(cfg, "CFG Module missing!");
|
ASSERT_MSG(cfg, "CFG Module missing!");
|
||||||
|
|
|
@ -85,8 +85,8 @@ public:
|
||||||
/**
|
/**
|
||||||
* Executes the software keyboard, configured with the given parameters.
|
* Executes the software keyboard, configured with the given parameters.
|
||||||
*/
|
*/
|
||||||
virtual void Execute(const KeyboardConfig& config) {
|
virtual void Execute(const KeyboardConfig& config_) {
|
||||||
this->config = config;
|
config = config_;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -173,9 +173,13 @@ void EmuWindow::TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y) {
|
||||||
void EmuWindow::UpdateCurrentFramebufferLayout(unsigned width, unsigned height,
|
void EmuWindow::UpdateCurrentFramebufferLayout(unsigned width, unsigned height,
|
||||||
bool is_portrait_mode) {
|
bool is_portrait_mode) {
|
||||||
Layout::FramebufferLayout layout;
|
Layout::FramebufferLayout layout;
|
||||||
const auto layout_option = Settings::values.layout_option;
|
|
||||||
const auto min_size = Layout::GetMinimumSizeFromLayout(
|
// If in portrait mode, only the MobilePortrait option really makes sense
|
||||||
layout_option.GetValue(), Settings::values.upright_screen.GetValue());
|
const Settings::LayoutOption layout_option = is_portrait_mode
|
||||||
|
? Settings::LayoutOption::MobilePortrait
|
||||||
|
: Settings::values.layout_option.GetValue();
|
||||||
|
const auto min_size =
|
||||||
|
Layout::GetMinimumSizeFromLayout(layout_option, Settings::values.upright_screen.GetValue());
|
||||||
|
|
||||||
if (Settings::values.custom_layout.GetValue() == true) {
|
if (Settings::values.custom_layout.GetValue() == true) {
|
||||||
layout = Layout::CustomFrameLayout(width, height, Settings::values.swap_screen.GetValue());
|
layout = Layout::CustomFrameLayout(width, height, Settings::values.swap_screen.GetValue());
|
||||||
|
@ -183,11 +187,6 @@ void EmuWindow::UpdateCurrentFramebufferLayout(unsigned width, unsigned height,
|
||||||
width = std::max(width, min_size.first);
|
width = std::max(width, min_size.first);
|
||||||
height = std::max(height, min_size.second);
|
height = std::max(height, min_size.second);
|
||||||
|
|
||||||
// If in portrait mode, only the MobilePortrait option really makes sense
|
|
||||||
const Settings::LayoutOption layout_option =
|
|
||||||
is_portrait_mode ? Settings::LayoutOption::MobilePortrait
|
|
||||||
: Settings::values.layout_option.GetValue();
|
|
||||||
|
|
||||||
switch (layout_option) {
|
switch (layout_option) {
|
||||||
case Settings::LayoutOption::SingleScreen:
|
case Settings::LayoutOption::SingleScreen:
|
||||||
layout =
|
layout =
|
||||||
|
|
|
@ -281,7 +281,8 @@ private:
|
||||||
* For the request to be honored, EmuWindow implementations will usually reimplement this
|
* For the request to be honored, EmuWindow implementations will usually reimplement this
|
||||||
* function.
|
* function.
|
||||||
*/
|
*/
|
||||||
virtual void OnMinimalClientAreaChangeRequest(std::pair<u32, u32> minimal_size) {
|
virtual void OnMinimalClientAreaChangeRequest(
|
||||||
|
[[maybe_unused]] std::pair<u32, u32> minimal_size) {
|
||||||
// By default, ignore this request and do nothing.
|
// By default, ignore this request and do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -421,28 +421,32 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar
|
||||||
if (Settings::values.upright_screen.GetValue()) {
|
if (Settings::values.upright_screen.GetValue()) {
|
||||||
if (Settings::values.swap_screen.GetValue()) {
|
if (Settings::values.swap_screen.GetValue()) {
|
||||||
width = Core::kScreenBottomHeight * res_scale;
|
width = Core::kScreenBottomHeight * res_scale;
|
||||||
height = (Core::kScreenBottomWidth +
|
height =
|
||||||
Core::kScreenTopWidth /
|
(Core::kScreenBottomWidth +
|
||||||
Settings::values.large_screen_proportion.GetValue()) *
|
static_cast<int>(Core::kScreenTopWidth /
|
||||||
|
Settings::values.large_screen_proportion.GetValue())) *
|
||||||
res_scale;
|
res_scale;
|
||||||
} else {
|
} else {
|
||||||
width = Core::kScreenTopHeight * res_scale;
|
width = Core::kScreenTopHeight * res_scale;
|
||||||
height = (Core::kScreenTopWidth +
|
height =
|
||||||
Core::kScreenBottomWidth /
|
(Core::kScreenTopWidth +
|
||||||
Settings::values.large_screen_proportion.GetValue()) *
|
static_cast<int>(Core::kScreenBottomWidth /
|
||||||
|
Settings::values.large_screen_proportion.GetValue())) *
|
||||||
res_scale;
|
res_scale;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (Settings::values.swap_screen.GetValue()) {
|
if (Settings::values.swap_screen.GetValue()) {
|
||||||
width = (Core::kScreenBottomWidth +
|
width = (Core::kScreenBottomWidth +
|
||||||
Core::kScreenTopWidth /
|
Core::kScreenTopWidth /
|
||||||
Settings::values.large_screen_proportion.GetValue()) *
|
static_cast<int>(
|
||||||
|
Settings::values.large_screen_proportion.GetValue())) *
|
||||||
res_scale;
|
res_scale;
|
||||||
height = Core::kScreenBottomHeight * res_scale;
|
height = Core::kScreenBottomHeight * res_scale;
|
||||||
} else {
|
} else {
|
||||||
width = (Core::kScreenTopWidth +
|
width = (Core::kScreenTopWidth +
|
||||||
Core::kScreenBottomWidth /
|
Core::kScreenBottomWidth /
|
||||||
Settings::values.large_screen_proportion.GetValue()) *
|
static_cast<int>(
|
||||||
|
Settings::values.large_screen_proportion.GetValue())) *
|
||||||
res_scale;
|
res_scale;
|
||||||
height = Core::kScreenTopHeight * res_scale;
|
height = Core::kScreenTopHeight * res_scale;
|
||||||
}
|
}
|
||||||
|
@ -470,10 +474,14 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar
|
||||||
break;
|
break;
|
||||||
case Settings::LayoutOption::MobileLandscape:
|
case Settings::LayoutOption::MobileLandscape:
|
||||||
if (Settings::values.swap_screen.GetValue()) {
|
if (Settings::values.swap_screen.GetValue()) {
|
||||||
width = (Core::kScreenBottomWidth + Core::kScreenTopWidth / 2.25f) * res_scale;
|
width =
|
||||||
|
(Core::kScreenBottomWidth + static_cast<int>(Core::kScreenTopWidth / 2.25f)) *
|
||||||
|
res_scale;
|
||||||
height = Core::kScreenBottomHeight * res_scale;
|
height = Core::kScreenBottomHeight * res_scale;
|
||||||
} else {
|
} else {
|
||||||
width = (Core::kScreenTopWidth + Core::kScreenBottomWidth / 2.25f) * res_scale;
|
width =
|
||||||
|
(Core::kScreenTopWidth + static_cast<int>(Core::kScreenBottomWidth / 2.25f)) *
|
||||||
|
res_scale;
|
||||||
height = Core::kScreenTopHeight * res_scale;
|
height = Core::kScreenTopHeight * res_scale;
|
||||||
}
|
}
|
||||||
layout = MobileLandscapeFrameLayout(
|
layout = MobileLandscapeFrameLayout(
|
||||||
|
@ -586,7 +594,7 @@ FramebufferLayout GetCardboardSettings(const FramebufferLayout& layout) {
|
||||||
|
|
||||||
std::pair<unsigned, unsigned> GetMinimumSizeFromLayout(Settings::LayoutOption layout,
|
std::pair<unsigned, unsigned> GetMinimumSizeFromLayout(Settings::LayoutOption layout,
|
||||||
bool upright_screen) {
|
bool upright_screen) {
|
||||||
unsigned min_width, min_height;
|
u32 min_width, min_height;
|
||||||
|
|
||||||
switch (layout) {
|
switch (layout) {
|
||||||
case Settings::LayoutOption::SingleScreen:
|
case Settings::LayoutOption::SingleScreen:
|
||||||
|
@ -597,12 +605,12 @@ std::pair<unsigned, unsigned> GetMinimumSizeFromLayout(Settings::LayoutOption la
|
||||||
min_height = Core::kScreenBottomHeight;
|
min_height = Core::kScreenBottomHeight;
|
||||||
break;
|
break;
|
||||||
case Settings::LayoutOption::LargeScreen:
|
case Settings::LayoutOption::LargeScreen:
|
||||||
min_width =
|
min_width = static_cast<u32>(
|
||||||
Settings::values.swap_screen
|
Settings::values.swap_screen
|
||||||
? Core::kScreenTopWidth / Settings::values.large_screen_proportion.GetValue() +
|
? Core::kScreenTopWidth / Settings::values.large_screen_proportion.GetValue() +
|
||||||
Core::kScreenBottomWidth
|
Core::kScreenBottomWidth
|
||||||
: Core::kScreenTopWidth + Core::kScreenBottomWidth /
|
: Core::kScreenTopWidth + Core::kScreenBottomWidth /
|
||||||
Settings::values.large_screen_proportion.GetValue();
|
Settings::values.large_screen_proportion.GetValue());
|
||||||
min_height = Core::kScreenBottomHeight;
|
min_height = Core::kScreenBottomHeight;
|
||||||
break;
|
break;
|
||||||
case Settings::LayoutOption::SideScreen:
|
case Settings::LayoutOption::SideScreen:
|
||||||
|
|
|
@ -24,8 +24,8 @@ public:
|
||||||
std::string GetName() const override {
|
std::string GetName() const override {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
void SetName(const std::string& name) {
|
void SetName(const std::string& name_) {
|
||||||
this->name = name;
|
name = name_;
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr HandleType HANDLE_TYPE = HandleType::Event;
|
static constexpr HandleType HANDLE_TYPE = HandleType::Event;
|
||||||
|
|
|
@ -238,13 +238,14 @@ ResultVal<VAddr> Process::HeapAllocate(VAddr target, u32 size, VMAPermission per
|
||||||
return ERR_INVALID_ADDRESS;
|
return ERR_INVALID_ADDRESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
{
|
||||||
auto vma = vm_manager.FindVMA(target);
|
auto vma = vm_manager.FindVMA(target);
|
||||||
if (vma->second.type != VMAType::Free || vma->second.base + vma->second.size < target + size) {
|
if (vma->second.type != VMAType::Free ||
|
||||||
|
vma->second.base + vma->second.size < target + size) {
|
||||||
LOG_ERROR(Kernel, "Trying to allocate already allocated memory");
|
LOG_ERROR(Kernel, "Trying to allocate already allocated memory");
|
||||||
return ERR_INVALID_ADDRESS_STATE;
|
return ERR_INVALID_ADDRESS_STATE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
auto allocated_fcram = memory_region->HeapAllocate(size);
|
auto allocated_fcram = memory_region->HeapAllocate(size);
|
||||||
if (allocated_fcram.empty()) {
|
if (allocated_fcram.empty()) {
|
||||||
LOG_ERROR(Kernel, "Not enough space");
|
LOG_ERROR(Kernel, "Not enough space");
|
||||||
|
|
|
@ -157,15 +157,17 @@ ResultCode SharedMemory::Map(Process& target_process, VAddr address, MemoryPermi
|
||||||
// APT:GetSharedFont for detail.
|
// APT:GetSharedFont for detail.
|
||||||
target_address = linear_heap_phys_offset + Memory::LINEAR_HEAP_VADDR;
|
target_address = linear_heap_phys_offset + Memory::LINEAR_HEAP_VADDR;
|
||||||
}
|
}
|
||||||
|
{
|
||||||
auto vma = target_process.vm_manager.FindVMA(target_address);
|
auto vma = target_process.vm_manager.FindVMA(target_address);
|
||||||
if (vma->second.type != VMAType::Free ||
|
if (vma->second.type != VMAType::Free ||
|
||||||
vma->second.base + vma->second.size < target_address + size) {
|
vma->second.base + vma->second.size < target_address + size) {
|
||||||
LOG_ERROR(Kernel,
|
LOG_ERROR(
|
||||||
|
Kernel,
|
||||||
"cannot map id={}, address=0x{:08X} name={}, mapping to already allocated memory",
|
"cannot map id={}, address=0x{:08X} name={}, mapping to already allocated memory",
|
||||||
GetObjectId(), address, name);
|
GetObjectId(), address, name);
|
||||||
return ERR_INVALID_ADDRESS_STATE;
|
return ERR_INVALID_ADDRESS_STATE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Map the memory block into the target process
|
// Map the memory block into the target process
|
||||||
VAddr interval_target = target_address;
|
VAddr interval_target = target_address;
|
||||||
|
|
|
@ -28,8 +28,8 @@ public:
|
||||||
std::string GetName() const override {
|
std::string GetName() const override {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
void SetName(std::string name) {
|
void SetName(std::string name_) {
|
||||||
this->name = std::move(name);
|
name = std::move(name_);
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr HandleType HANDLE_TYPE = HandleType::SharedMemory;
|
static constexpr HandleType HANDLE_TYPE = HandleType::SharedMemory;
|
||||||
|
|
|
@ -1962,7 +1962,7 @@ ResultCode SVC::GetProcessList(s32* process_count, VAddr out_process_array,
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 written = 0;
|
s32 written = 0;
|
||||||
for (const auto process : kernel.GetProcessList()) {
|
for (const auto& process : kernel.GetProcessList()) {
|
||||||
if (written >= out_process_array_count) {
|
if (written >= out_process_array_count) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,8 +115,8 @@ public:
|
||||||
*/
|
*/
|
||||||
const std::vector<std::shared_ptr<Thread>>& GetThreadList();
|
const std::vector<std::shared_ptr<Thread>>& GetThreadList();
|
||||||
|
|
||||||
void SetCPU(ARM_Interface& cpu) {
|
void SetCPU(ARM_Interface& cpu_) {
|
||||||
this->cpu = &cpu;
|
cpu = &cpu_;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<ARM_Interface::ThreadContext> NewContext() {
|
std::unique_ptr<ARM_Interface::ThreadContext> NewContext() {
|
||||||
|
|
|
@ -1197,8 +1197,8 @@ static void CaptureFrameBuffer(Core::System& system, u32 capture_offset, VAddr s
|
||||||
auto dst_vaddr = screen_capture_base_vaddr + capture_offset;
|
auto dst_vaddr = screen_capture_base_vaddr + capture_offset;
|
||||||
auto dst_ptr = system.Memory().GetPointer(dst_vaddr);
|
auto dst_ptr = system.Memory().GetPointer(dst_vaddr);
|
||||||
const auto src_ptr = system.Memory().GetPointer(src);
|
const auto src_ptr = system.Memory().GetPointer(src);
|
||||||
for (auto y = 0; y < height; y++) {
|
for (u32 y = 0; y < height; y++) {
|
||||||
for (auto x = 0; x < screen_width; x++) {
|
for (u32 x = 0; x < screen_width; x++) {
|
||||||
auto dst_offset =
|
auto dst_offset =
|
||||||
VideoCore::GetMortonOffset(x, y, bpp) + (y & ~7) * screen_width_pow2 * bpp;
|
VideoCore::GetMortonOffset(x, y, bpp) + (y & ~7) * screen_width_pow2 * bpp;
|
||||||
auto src_offset = bpp * (screen_width * y + x);
|
auto src_offset = bpp * (screen_width * y + x);
|
||||||
|
|
|
@ -929,7 +929,7 @@ void Module::APTInterface::StoreSysMenuArg(Kernel::HLERequestContext& ctx) {
|
||||||
|
|
||||||
void Module::APTInterface::SendCaptureBufferInfo(Kernel::HLERequestContext& ctx) {
|
void Module::APTInterface::SendCaptureBufferInfo(Kernel::HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp(ctx, 0x40, 1, 2); // 0x00400042
|
IPC::RequestParser rp(ctx, 0x40, 1, 2); // 0x00400042
|
||||||
const auto size = rp.Pop<u32>();
|
[[maybe_unused]] const auto size = rp.Pop<u32>();
|
||||||
const auto buffer = rp.PopStaticBuffer();
|
const auto buffer = rp.PopStaticBuffer();
|
||||||
|
|
||||||
LOG_DEBUG(Service_APT, "called");
|
LOG_DEBUG(Service_APT, "called");
|
||||||
|
|
|
@ -855,7 +855,7 @@ ResultVal<u16> FS_USER::GetSpecialContentIndexFromGameCard(u64 title_id, Special
|
||||||
case SpecialContentType::DLPChild:
|
case SpecialContentType::DLPChild:
|
||||||
return MakeResult(static_cast<u16>(NCSDContentIndex::DLP));
|
return MakeResult(static_cast<u16>(NCSDContentIndex::DLP));
|
||||||
default:
|
default:
|
||||||
ASSERT(false);
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1424,8 +1424,8 @@ void NWM_UDS::DecryptBeaconData(Kernel::HLERequestContext& ctx, u16 command_id)
|
||||||
auto& node = nodes.emplace_back();
|
auto& node = nodes.emplace_back();
|
||||||
node.friend_code_seed = info.friend_code_seed;
|
node.friend_code_seed = info.friend_code_seed;
|
||||||
node.network_node_id = info.network_node_id;
|
node.network_node_id = info.network_node_id;
|
||||||
for (std::size_t i = 0; i < info.username.size(); ++i) {
|
for (std::size_t j = 0; j < info.username.size(); ++j) {
|
||||||
node.username[i] = info.username[i];
|
node.username[j] = info.username[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,7 @@ static std::array<u8, CryptoPP::Weak::MD5::DIGESTSIZE> GetDataCryptoCTR(
|
||||||
* Generates the key used for encrypting the 802.11 data frames generated by UDS.
|
* Generates the key used for encrypting the 802.11 data frames generated by UDS.
|
||||||
* @returns The key used for data frames crypto.
|
* @returns The key used for data frames crypto.
|
||||||
*/
|
*/
|
||||||
static std::array<u8, CryptoPP::AES::BLOCKSIZE> GenerateDataCCMPKey(
|
[[maybe_unused]] static std::array<u8, CryptoPP::AES::BLOCKSIZE> GenerateDataCCMPKey(
|
||||||
const std::vector<u8>& passphrase, const NetworkInfo& network_info) {
|
const std::vector<u8>& passphrase, const NetworkInfo& network_info) {
|
||||||
// Calculate the MD5 hash of the input passphrase.
|
// Calculate the MD5 hash of the input passphrase.
|
||||||
std::array<u8, CryptoPP::Weak::MD5::DIGESTSIZE> passphrase_hash;
|
std::array<u8, CryptoPP::Weak::MD5::DIGESTSIZE> passphrase_hash;
|
||||||
|
@ -157,11 +157,10 @@ static std::vector<u8> GenerateCCMPAAD(const MacAddress& sender, const MacAddres
|
||||||
* Decrypts the payload of an encrypted 802.11 data frame using the specified key.
|
* Decrypts the payload of an encrypted 802.11 data frame using the specified key.
|
||||||
* @returns The decrypted payload.
|
* @returns The decrypted payload.
|
||||||
*/
|
*/
|
||||||
static std::vector<u8> DecryptDataFrame(const std::vector<u8>& encrypted_payload,
|
[[maybe_unused]] static std::vector<u8> DecryptDataFrame(
|
||||||
const std::array<u8, CryptoPP::AES::BLOCKSIZE>& ccmp_key,
|
const std::vector<u8>& encrypted_payload,
|
||||||
const MacAddress& sender, const MacAddress& receiver,
|
const std::array<u8, CryptoPP::AES::BLOCKSIZE>& ccmp_key, const MacAddress& sender,
|
||||||
const MacAddress& bssid, u16 sequence_number,
|
const MacAddress& receiver, const MacAddress& bssid, u16 sequence_number, u16 frame_control) {
|
||||||
u16 frame_control) {
|
|
||||||
|
|
||||||
// Reference: IEEE 802.11-2007
|
// Reference: IEEE 802.11-2007
|
||||||
|
|
||||||
|
@ -218,11 +217,10 @@ static std::vector<u8> DecryptDataFrame(const std::vector<u8>& encrypted_payload
|
||||||
* Encrypts the payload of an 802.11 data frame using the specified key.
|
* Encrypts the payload of an 802.11 data frame using the specified key.
|
||||||
* @returns The encrypted payload.
|
* @returns The encrypted payload.
|
||||||
*/
|
*/
|
||||||
static std::vector<u8> EncryptDataFrame(const std::vector<u8>& payload,
|
[[maybe_unused]] static std::vector<u8> EncryptDataFrame(
|
||||||
const std::array<u8, CryptoPP::AES::BLOCKSIZE>& ccmp_key,
|
const std::vector<u8>& payload, const std::array<u8, CryptoPP::AES::BLOCKSIZE>& ccmp_key,
|
||||||
const MacAddress& sender, const MacAddress& receiver,
|
const MacAddress& sender, const MacAddress& receiver, const MacAddress& bssid,
|
||||||
const MacAddress& bssid, u16 sequence_number,
|
u16 sequence_number, u16 frame_control) {
|
||||||
u16 frame_control) {
|
|
||||||
// Reference: IEEE 802.11-2007
|
// Reference: IEEE 802.11-2007
|
||||||
|
|
||||||
std::vector<u8> aad = GenerateCCMPAAD(sender, receiver, bssid, frame_control);
|
std::vector<u8> aad = GenerateCCMPAAD(sender, receiver, bssid, frame_control);
|
||||||
|
|
|
@ -99,7 +99,7 @@ void PLG_LDR::OnProcessRun(Kernel::Process& process, Kernel::KernelSystem& kerne
|
||||||
plugin_root + fmt::format("{:016X}", process.codeset->program_id);
|
plugin_root + fmt::format("{:016X}", process.codeset->program_id);
|
||||||
FileUtil::FSTEntry entry;
|
FileUtil::FSTEntry entry;
|
||||||
FileUtil::ScanDirectoryTree(plugin_tid, entry);
|
FileUtil::ScanDirectoryTree(plugin_tid, entry);
|
||||||
for (const auto child : entry.children) {
|
for (const auto& child : entry.children) {
|
||||||
if (!child.isDirectory && child.physicalName.ends_with(".3gx")) {
|
if (!child.isDirectory && child.physicalName.ends_with(".3gx")) {
|
||||||
plgldr_context.is_default_path = false;
|
plgldr_context.is_default_path = false;
|
||||||
plgldr_context.plugin_path = child.physicalName;
|
plgldr_context.plugin_path = child.physicalName;
|
||||||
|
|
|
@ -794,8 +794,6 @@ void SOC_U::Poll(Kernel::HLERequestContext& ctx) {
|
||||||
ret = TranslateError(GET_ERRNO);
|
ret = TranslateError(GET_ERRNO);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t test = platform_pollfd.size();
|
|
||||||
|
|
||||||
IPC::RequestBuilder rb = rp.MakeBuilder(2, 2);
|
IPC::RequestBuilder rb = rp.MakeBuilder(2, 2);
|
||||||
rb.Push(RESULT_SUCCESS);
|
rb.Push(RESULT_SUCCESS);
|
||||||
rb.Push(ret);
|
rb.Push(ret);
|
||||||
|
|
|
@ -298,13 +298,13 @@ void LoadSafeModeNativeFirmKeysOld3DS() {
|
||||||
std::vector<u8> firm_buffer(size);
|
std::vector<u8> firm_buffer(size);
|
||||||
firm->Read(0, firm_buffer.size(), firm_buffer.data());
|
firm->Read(0, firm_buffer.size(), firm_buffer.data());
|
||||||
firm->Close();
|
firm->Close();
|
||||||
|
{
|
||||||
AESKey key;
|
AESKey key;
|
||||||
constexpr std::size_t SLOT_0x31_KEY_Y_OFFSET = 817672;
|
constexpr std::size_t SLOT_0x31_KEY_Y_OFFSET = 817672;
|
||||||
std::memcpy(key.data(), firm_buffer.data() + SLOT_0x31_KEY_Y_OFFSET, sizeof(key));
|
std::memcpy(key.data(), firm_buffer.data() + SLOT_0x31_KEY_Y_OFFSET, sizeof(key));
|
||||||
key_slots.at(0x31).SetKeyY(key);
|
key_slots.at(0x31).SetKeyY(key);
|
||||||
LOG_DEBUG(HW_AES, "Loaded Slot0x31 KeyY: {}", KeyToString(key));
|
LOG_DEBUG(HW_AES, "Loaded Slot0x31 KeyY: {}", KeyToString(key));
|
||||||
|
}
|
||||||
auto LoadCommonKey = [&firm_buffer](std::size_t key_slot) -> AESKey {
|
auto LoadCommonKey = [&firm_buffer](std::size_t key_slot) -> AESKey {
|
||||||
constexpr std::size_t START_OFFSET = 836533;
|
constexpr std::size_t START_OFFSET = 836533;
|
||||||
constexpr std::size_t OFFSET = 0x14; // 0x10 bytes for key + 4 bytes between keys
|
constexpr std::size_t OFFSET = 0x14; // 0x10 bytes for key + 4 bytes between keys
|
||||||
|
@ -417,13 +417,13 @@ void LoadNativeFirmKeysNew3DS() {
|
||||||
d2.SetKeyWithIV(normal_key_slot0x15->data(), normal_key_slot0x15->size(),
|
d2.SetKeyWithIV(normal_key_slot0x15->data(), normal_key_slot0x15->size(),
|
||||||
arm9_header.CTR.data(), arm9_header.CTR.size());
|
arm9_header.CTR.data(), arm9_header.CTR.size());
|
||||||
d2.ProcessData(arm9_binary.data(), enc_arm9_binary.data(), enc_arm9_binary.size());
|
d2.ProcessData(arm9_binary.data(), enc_arm9_binary.data(), enc_arm9_binary.size());
|
||||||
|
{
|
||||||
AESKey key;
|
AESKey key;
|
||||||
constexpr std::size_t SLOT_0x31_KEY_Y_OFFSET = 517368;
|
constexpr std::size_t SLOT_0x31_KEY_Y_OFFSET = 517368;
|
||||||
std::memcpy(key.data(), arm9_binary.data() + SLOT_0x31_KEY_Y_OFFSET, sizeof(key));
|
std::memcpy(key.data(), arm9_binary.data() + SLOT_0x31_KEY_Y_OFFSET, sizeof(key));
|
||||||
key_slots.at(0x31).SetKeyY(key);
|
key_slots.at(0x31).SetKeyY(key);
|
||||||
LOG_DEBUG(HW_AES, "Loaded Slot0x31 KeyY: {}", KeyToString(key));
|
LOG_DEBUG(HW_AES, "Loaded Slot0x31 KeyY: {}", KeyToString(key));
|
||||||
|
}
|
||||||
auto LoadCommonKey = [&arm9_binary](std::size_t key_slot) -> AESKey {
|
auto LoadCommonKey = [&arm9_binary](std::size_t key_slot) -> AESKey {
|
||||||
constexpr std::size_t START_OFFSET = 541065;
|
constexpr std::size_t START_OFFSET = 541065;
|
||||||
constexpr std::size_t OFFSET = 0x14; // 0x10 bytes for key + 4 bytes between keys
|
constexpr std::size_t OFFSET = 0x14; // 0x10 bytes for key + 4 bytes between keys
|
||||||
|
|
|
@ -118,7 +118,7 @@ public:
|
||||||
* @returns A pair with the optional N3ds mode, and the status.
|
* @returns A pair with the optional N3ds mode, and the status.
|
||||||
*/
|
*/
|
||||||
virtual std::pair<std::optional<u8>, ResultStatus> LoadKernelN3dsMode() {
|
virtual std::pair<std::optional<u8>, ResultStatus> LoadKernelN3dsMode() {
|
||||||
return std::make_pair(0, ResultStatus::Success);
|
return std::make_pair(u8(0), ResultStatus::Success);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -136,7 +136,7 @@ public:
|
||||||
* @param buffer Reference to buffer to store data
|
* @param buffer Reference to buffer to store data
|
||||||
* @return ResultStatus result of function
|
* @return ResultStatus result of function
|
||||||
*/
|
*/
|
||||||
virtual ResultStatus ReadCode(std::vector<u8>& buffer) {
|
virtual ResultStatus ReadCode([[maybe_unused]] std::vector<u8>& buffer) {
|
||||||
return ResultStatus::ErrorNotImplemented;
|
return ResultStatus::ErrorNotImplemented;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ public:
|
||||||
* @param buffer Reference to buffer to store data
|
* @param buffer Reference to buffer to store data
|
||||||
* @return ResultStatus result of function
|
* @return ResultStatus result of function
|
||||||
*/
|
*/
|
||||||
virtual ResultStatus ReadIcon(std::vector<u8>& buffer) {
|
virtual ResultStatus ReadIcon([[maybe_unused]] std::vector<u8>& buffer) {
|
||||||
return ResultStatus::ErrorNotImplemented;
|
return ResultStatus::ErrorNotImplemented;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,7 +154,7 @@ public:
|
||||||
* @param buffer Reference to buffer to store data
|
* @param buffer Reference to buffer to store data
|
||||||
* @return ResultStatus result of function
|
* @return ResultStatus result of function
|
||||||
*/
|
*/
|
||||||
virtual ResultStatus ReadBanner(std::vector<u8>& buffer) {
|
virtual ResultStatus ReadBanner([[maybe_unused]] std::vector<u8>& buffer) {
|
||||||
return ResultStatus::ErrorNotImplemented;
|
return ResultStatus::ErrorNotImplemented;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@ public:
|
||||||
* @param buffer Reference to buffer to store data
|
* @param buffer Reference to buffer to store data
|
||||||
* @return ResultStatus result of function
|
* @return ResultStatus result of function
|
||||||
*/
|
*/
|
||||||
virtual ResultStatus ReadLogo(std::vector<u8>& buffer) {
|
virtual ResultStatus ReadLogo([[maybe_unused]] std::vector<u8>& buffer) {
|
||||||
return ResultStatus::ErrorNotImplemented;
|
return ResultStatus::ErrorNotImplemented;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,7 +172,7 @@ public:
|
||||||
* @param out_program_id Reference to store program id into
|
* @param out_program_id Reference to store program id into
|
||||||
* @return ResultStatus result of function
|
* @return ResultStatus result of function
|
||||||
*/
|
*/
|
||||||
virtual ResultStatus ReadProgramId(u64& out_program_id) {
|
virtual ResultStatus ReadProgramId([[maybe_unused]] u64& out_program_id) {
|
||||||
return ResultStatus::ErrorNotImplemented;
|
return ResultStatus::ErrorNotImplemented;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,7 +181,7 @@ public:
|
||||||
* @param out_extdata_id Reference to store extdata id into
|
* @param out_extdata_id Reference to store extdata id into
|
||||||
* @return ResultStatus result of function
|
* @return ResultStatus result of function
|
||||||
*/
|
*/
|
||||||
virtual ResultStatus ReadExtdataId(u64& out_extdata_id) {
|
virtual ResultStatus ReadExtdataId([[maybe_unused]] u64& out_extdata_id) {
|
||||||
return ResultStatus::ErrorNotImplemented;
|
return ResultStatus::ErrorNotImplemented;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,7 +191,8 @@ public:
|
||||||
* @param romfs_file The file containing the RomFS
|
* @param romfs_file The file containing the RomFS
|
||||||
* @return ResultStatus result of function
|
* @return ResultStatus result of function
|
||||||
*/
|
*/
|
||||||
virtual ResultStatus ReadRomFS(std::shared_ptr<FileSys::RomFSReader>& romfs_file) {
|
virtual ResultStatus ReadRomFS(
|
||||||
|
[[maybe_unused]] std::shared_ptr<FileSys::RomFSReader>& romfs_file) {
|
||||||
return ResultStatus::ErrorNotImplemented;
|
return ResultStatus::ErrorNotImplemented;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,7 +201,7 @@ public:
|
||||||
* @param target_path The target path to dump to
|
* @param target_path The target path to dump to
|
||||||
* @return ResultStatus result of function
|
* @return ResultStatus result of function
|
||||||
*/
|
*/
|
||||||
virtual ResultStatus DumpRomFS(const std::string& target_path) {
|
virtual ResultStatus DumpRomFS([[maybe_unused]] const std::string& target_path) {
|
||||||
return ResultStatus::ErrorNotImplemented;
|
return ResultStatus::ErrorNotImplemented;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,7 +211,8 @@ public:
|
||||||
* @param romfs_file The file containing the RomFS
|
* @param romfs_file The file containing the RomFS
|
||||||
* @return ResultStatus result of function
|
* @return ResultStatus result of function
|
||||||
*/
|
*/
|
||||||
virtual ResultStatus ReadUpdateRomFS(std::shared_ptr<FileSys::RomFSReader>& romfs_file) {
|
virtual ResultStatus ReadUpdateRomFS(
|
||||||
|
[[maybe_unused]] std::shared_ptr<FileSys::RomFSReader>& romfs_file) {
|
||||||
return ResultStatus::ErrorNotImplemented;
|
return ResultStatus::ErrorNotImplemented;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,7 +221,7 @@ public:
|
||||||
* @param target_path The target path to dump to
|
* @param target_path The target path to dump to
|
||||||
* @return ResultStatus result of function
|
* @return ResultStatus result of function
|
||||||
*/
|
*/
|
||||||
virtual ResultStatus DumpUpdateRomFS(const std::string& target_path) {
|
virtual ResultStatus DumpUpdateRomFS([[maybe_unused]] const std::string& target_path) {
|
||||||
return ResultStatus::ErrorNotImplemented;
|
return ResultStatus::ErrorNotImplemented;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,7 +230,7 @@ public:
|
||||||
* @param title Reference to store the application title into
|
* @param title Reference to store the application title into
|
||||||
* @return ResultStatus result of function
|
* @return ResultStatus result of function
|
||||||
*/
|
*/
|
||||||
virtual ResultStatus ReadTitle(std::string& title) {
|
virtual ResultStatus ReadTitle([[maybe_unused]] std::string& title) {
|
||||||
return ResultStatus::ErrorNotImplemented;
|
return ResultStatus::ErrorNotImplemented;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ std::pair<std::optional<u32>, ResultStatus> AppLoader_NCCH::LoadKernelSystemMode
|
||||||
if (!is_loaded) {
|
if (!is_loaded) {
|
||||||
ResultStatus res = base_ncch.Load();
|
ResultStatus res = base_ncch.Load();
|
||||||
if (res != ResultStatus::Success) {
|
if (res != ResultStatus::Success) {
|
||||||
return std::make_pair(std::optional<u32>{}, res);
|
return std::make_pair(std::nullopt, res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ std::pair<std::optional<u8>, ResultStatus> AppLoader_NCCH::LoadKernelN3dsMode()
|
||||||
if (!is_loaded) {
|
if (!is_loaded) {
|
||||||
ResultStatus res = base_ncch.Load();
|
ResultStatus res = base_ncch.Load();
|
||||||
if (res != ResultStatus::Success) {
|
if (res != ResultStatus::Success) {
|
||||||
return std::make_pair(std::optional<u8>{}, res);
|
return std::make_pair(std::nullopt, res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -178,7 +178,7 @@ int main(int argc, char** argv) {
|
||||||
std::string ban_list_file;
|
std::string ban_list_file;
|
||||||
std::string log_file = "citra-room.log";
|
std::string log_file = "citra-room.log";
|
||||||
u64 preferred_game_id = 0;
|
u64 preferred_game_id = 0;
|
||||||
u32 port = Network::DefaultRoomPort;
|
u16 port = Network::DefaultRoomPort;
|
||||||
u32 max_members = 16;
|
u32 max_members = 16;
|
||||||
bool enable_citra_mods = false;
|
bool enable_citra_mods = false;
|
||||||
|
|
||||||
|
@ -212,7 +212,7 @@ int main(int argc, char** argv) {
|
||||||
room_description.assign(optarg);
|
room_description.assign(optarg);
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
port = strtoul(optarg, &endarg, 0);
|
port = static_cast<u16>(strtoul(optarg, &endarg, 0));
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
max_members = strtoul(optarg, &endarg, 0);
|
max_members = strtoul(optarg, &endarg, 0);
|
||||||
|
|
|
@ -1007,14 +1007,14 @@ public:
|
||||||
// event was press and the second was release; This should handle most
|
// event was press and the second was release; This should handle most
|
||||||
// digital axes while deferring to the direction of travel for analog
|
// digital axes while deferring to the direction of travel for analog
|
||||||
// axes
|
// axes
|
||||||
event.jaxis.value = std::copysign(
|
event.jaxis.value = static_cast<Sint16>(std::copysign(
|
||||||
32767, axis_memory[event.jaxis.which][event.jaxis.axis]);
|
32767, axis_memory[event.jaxis.which][event.jaxis.axis]));
|
||||||
} else {
|
} else {
|
||||||
// There are more than two events, so this is likely a true analog axis,
|
// There are more than two events, so this is likely a true analog axis,
|
||||||
// check the direction it travelled
|
// check the direction it travelled
|
||||||
event.jaxis.value = std::copysign(
|
event.jaxis.value = static_cast<Sint16>(std::copysign(
|
||||||
32767, event.jaxis.value -
|
32767, event.jaxis.value -
|
||||||
axis_memory[event.jaxis.which][event.jaxis.axis]);
|
axis_memory[event.jaxis.which][event.jaxis.axis]));
|
||||||
}
|
}
|
||||||
axis_memory.clear();
|
axis_memory.clear();
|
||||||
axis_event_count.clear();
|
axis_event_count.clear();
|
||||||
|
|
|
@ -234,8 +234,6 @@ CalibrationConfigurationJob::CalibrationConfigurationJob(
|
||||||
std::function<void(u16, u16, u16, u16)> data_callback) {
|
std::function<void(u16, u16, u16, u16)> data_callback) {
|
||||||
|
|
||||||
std::thread([=, this] {
|
std::thread([=, this] {
|
||||||
constexpr u16 CALIBRATION_THRESHOLD = 100;
|
|
||||||
|
|
||||||
u16 min_x{UINT16_MAX};
|
u16 min_x{UINT16_MAX};
|
||||||
u16 min_y{UINT16_MAX};
|
u16 min_y{UINT16_MAX};
|
||||||
u16 max_x{};
|
u16 max_x{};
|
||||||
|
@ -244,6 +242,8 @@ CalibrationConfigurationJob::CalibrationConfigurationJob(
|
||||||
Status current_status{Status::Initialized};
|
Status current_status{Status::Initialized};
|
||||||
SocketCallback callback{[](Response::Version version) {}, [](Response::PortInfo info) {},
|
SocketCallback callback{[](Response::Version version) {}, [](Response::PortInfo info) {},
|
||||||
[&](Response::PadData data) {
|
[&](Response::PadData data) {
|
||||||
|
constexpr u16 CALIBRATION_THRESHOLD = 100;
|
||||||
|
|
||||||
if (current_status == Status::Initialized) {
|
if (current_status == Status::Initialized) {
|
||||||
// Receiving data means the communication is ready now
|
// Receiving data means the communication is ready now
|
||||||
current_status = Status::Ready;
|
current_status = Status::Ready;
|
||||||
|
|
|
@ -135,9 +135,9 @@ void AnnounceMultiplayerSession::AnnounceMultiplayerLoop() {
|
||||||
if (result.result_string == "404") {
|
if (result.result_string == "404") {
|
||||||
registered = false;
|
registered = false;
|
||||||
// Needs to register the room again
|
// Needs to register the room again
|
||||||
Common::WebResult result = Register();
|
Common::WebResult new_result = Register();
|
||||||
if (result.result_code != Common::WebResult::Code::Success) {
|
if (new_result.result_code != Common::WebResult::Code::Success) {
|
||||||
ErrorCallback(result);
|
ErrorCallback(new_result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,7 +158,7 @@ bool RoomMember::RoomMemberImpl::IsConnected() const {
|
||||||
void RoomMember::RoomMemberImpl::MemberLoop() {
|
void RoomMember::RoomMemberImpl::MemberLoop() {
|
||||||
// Receive packets while the connection is open
|
// Receive packets while the connection is open
|
||||||
while (IsConnected()) {
|
while (IsConnected()) {
|
||||||
std::lock_guard lock(network_mutex);
|
std::lock_guard network_lock(network_mutex);
|
||||||
ENetEvent event;
|
ENetEvent event;
|
||||||
if (enet_host_service(client, &event, 16) > 0) {
|
if (enet_host_service(client, &event, 16) > 0) {
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
|
@ -255,7 +255,7 @@ void RoomMember::RoomMemberImpl::MemberLoop() {
|
||||||
|
|
||||||
std::list<Packet> packets;
|
std::list<Packet> packets;
|
||||||
{
|
{
|
||||||
std::lock_guard lock(send_list_mutex);
|
std::lock_guard send_list_lock(send_list_mutex);
|
||||||
packets.swap(send_list);
|
packets.swap(send_list);
|
||||||
}
|
}
|
||||||
for (const auto& packet : packets) {
|
for (const auto& packet : packets) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
add_executable(tests
|
add_executable(tests
|
||||||
common/bit_field.cpp
|
common/bit_field.cpp
|
||||||
|
common/file_util.cpp
|
||||||
common/param_package.cpp
|
common/param_package.cpp
|
||||||
core/arm/arm_test_common.cpp
|
core/arm/arm_test_common.cpp
|
||||||
core/arm/arm_test_common.h
|
core/arm/arm_test_common.h
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
// Copyright 2023 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
|
||||||
|
#include "common/file_util.h"
|
||||||
|
#include "common/string_util.h"
|
||||||
|
|
||||||
|
TEST_CASE("SplitFilename83 Sanity", "[common]") {
|
||||||
|
std::string filename = "long_ass_file_name.3ds";
|
||||||
|
std::array<char, 9> short_name;
|
||||||
|
std::array<char, 4> extension;
|
||||||
|
|
||||||
|
FileUtil::SplitFilename83(filename, short_name, extension);
|
||||||
|
|
||||||
|
filename = Common::ToUpper(filename);
|
||||||
|
std::string expected_short_name = filename.substr(0, 6).append("~1");
|
||||||
|
std::string expected_extension = filename.substr(filename.find('.') + 1, 3);
|
||||||
|
|
||||||
|
REQUIRE(memcmp(short_name.data(), expected_short_name.data(), short_name.size()) == 0);
|
||||||
|
REQUIRE(memcmp(extension.data(), expected_extension.data(), extension.size()) == 0);
|
||||||
|
}
|
|
@ -81,10 +81,12 @@ TEST_CASE("Memory Basics", "[kernel][memory]") {
|
||||||
Kernel::MemoryState::Private);
|
Kernel::MemoryState::Private);
|
||||||
REQUIRE(result.Code() == RESULT_SUCCESS);
|
REQUIRE(result.Code() == RESULT_SUCCESS);
|
||||||
|
|
||||||
|
SECTION("reprotect memory range") {
|
||||||
ResultCode code =
|
ResultCode code =
|
||||||
manager->ReprotectRange(Memory::HEAP_VADDR, static_cast<u32>(block.GetSize()),
|
manager->ReprotectRange(Memory::HEAP_VADDR, static_cast<u32>(block.GetSize()),
|
||||||
Kernel::VMAPermission::ReadWrite);
|
Kernel::VMAPermission::ReadWrite);
|
||||||
REQUIRE(code == RESULT_SUCCESS);
|
REQUIRE(code == RESULT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
SECTION("with invalid address") {
|
SECTION("with invalid address") {
|
||||||
ResultCode code = manager->ChangeMemoryState(
|
ResultCode code = manager->ChangeMemoryState(
|
||||||
|
@ -146,7 +148,8 @@ TEST_CASE("Memory Basics", "[kernel][memory]") {
|
||||||
CHECK(vma->second.meminfo_state == Kernel::MemoryState::Private);
|
CHECK(vma->second.meminfo_state == Kernel::MemoryState::Private);
|
||||||
}
|
}
|
||||||
|
|
||||||
code = manager->UnmapRange(Memory::HEAP_VADDR, static_cast<u32>(block.GetSize()));
|
ResultCode code =
|
||||||
|
manager->UnmapRange(Memory::HEAP_VADDR, static_cast<u32>(block.GetSize()));
|
||||||
REQUIRE(code == RESULT_SUCCESS);
|
REQUIRE(code == RESULT_SUCCESS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -290,14 +290,14 @@ bool CustomTexManager::Decode(Material* material, std::function<bool()>&& upload
|
||||||
|
|
||||||
void CustomTexManager::ReadConfig(const std::string& load_path) {
|
void CustomTexManager::ReadConfig(const std::string& load_path) {
|
||||||
const std::string config_path = load_path + "pack.json";
|
const std::string config_path = load_path + "pack.json";
|
||||||
FileUtil::IOFile file{config_path, "r"};
|
FileUtil::IOFile config_file{config_path, "r"};
|
||||||
if (!file.IsOpen()) {
|
if (!config_file.IsOpen()) {
|
||||||
LOG_INFO(Render, "Unable to find pack config file, using legacy defaults");
|
LOG_INFO(Render, "Unable to find pack config file, using legacy defaults");
|
||||||
refuse_dds = true;
|
refuse_dds = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::string config(file.GetSize(), '\0');
|
std::string config(config_file.GetSize(), '\0');
|
||||||
const std::size_t read_size = file.ReadBytes(config.data(), config.size());
|
const std::size_t read_size = config_file.ReadBytes(config.data(), config.size());
|
||||||
if (!read_size) {
|
if (!read_size) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ void Zero(T& o) {
|
||||||
State::State() : geometry_pipeline(*this) {
|
State::State() : geometry_pipeline(*this) {
|
||||||
auto SubmitVertex = [this](const Shader::AttributeBuffer& vertex) {
|
auto SubmitVertex = [this](const Shader::AttributeBuffer& vertex) {
|
||||||
using Pica::Shader::OutputVertex;
|
using Pica::Shader::OutputVertex;
|
||||||
auto AddTriangle = [this](const OutputVertex& v0, const OutputVertex& v1,
|
auto AddTriangle = [](const OutputVertex& v0, const OutputVertex& v1,
|
||||||
const OutputVertex& v2) {
|
const OutputVertex& v2) {
|
||||||
VideoCore::g_renderer->Rasterizer()->AddTriangle(v0, v1, v2);
|
VideoCore::g_renderer->Rasterizer()->AddTriangle(v0, v1, v2);
|
||||||
};
|
};
|
||||||
|
|
|
@ -679,7 +679,8 @@ void RasterizerAccelerated::SyncProcTexBias() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerAccelerated::SyncAlphaTest() {
|
void RasterizerAccelerated::SyncAlphaTest() {
|
||||||
if (regs.framebuffer.output_merger.alpha_test.ref != uniform_block_data.data.alphatest_ref) {
|
if (regs.framebuffer.output_merger.alpha_test.ref !=
|
||||||
|
static_cast<u32>(uniform_block_data.data.alphatest_ref)) {
|
||||||
uniform_block_data.data.alphatest_ref = regs.framebuffer.output_merger.alpha_test.ref;
|
uniform_block_data.data.alphatest_ref = regs.framebuffer.output_merger.alpha_test.ref;
|
||||||
uniform_block_data.dirty = true;
|
uniform_block_data.dirty = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ enum class ScaleMatch {
|
||||||
};
|
};
|
||||||
|
|
||||||
class CustomTexManager;
|
class CustomTexManager;
|
||||||
struct CustomTexture;
|
class CustomTexture;
|
||||||
class RendererBase;
|
class RendererBase;
|
||||||
|
|
||||||
class RasterizerCache : NonCopyable {
|
class RasterizerCache : NonCopyable {
|
||||||
|
|
|
@ -161,7 +161,7 @@ constexpr void EncodePixel(const u8* source, u8* dest) {
|
||||||
} else if constexpr (format == PixelFormat::D24 && converted) {
|
} else if constexpr (format == PixelFormat::D24 && converted) {
|
||||||
float d32;
|
float d32;
|
||||||
std::memcpy(&d32, source, sizeof(d32));
|
std::memcpy(&d32, source, sizeof(d32));
|
||||||
EncodeD24(d32 * 0xFFFFFF, dest);
|
EncodeD24(static_cast<u32>(d32 * 0xFFFFFF), dest);
|
||||||
} else if constexpr (format == PixelFormat::D24S8) {
|
} else if constexpr (format == PixelFormat::D24S8) {
|
||||||
const u32 s8d24 = std::rotr(MakeInt<u32>(source), 8);
|
const u32 s8d24 = std::rotr(MakeInt<u32>(source), 8);
|
||||||
std::memcpy(dest, &s8d24, sizeof(u32));
|
std::memcpy(dest, &s8d24, sizeof(u32));
|
||||||
|
|
|
@ -59,34 +59,37 @@ public:
|
||||||
virtual void ClearAll(bool flush) = 0;
|
virtual void ClearAll(bool flush) = 0;
|
||||||
|
|
||||||
/// Attempt to use a faster method to perform a display transfer with is_texture_copy = 0
|
/// Attempt to use a faster method to perform a display transfer with is_texture_copy = 0
|
||||||
virtual bool AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config) {
|
virtual bool AccelerateDisplayTransfer(
|
||||||
|
[[maybe_unused]] const GPU::Regs::DisplayTransferConfig& config) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempt to use a faster method to perform a display transfer with is_texture_copy = 1
|
/// Attempt to use a faster method to perform a display transfer with is_texture_copy = 1
|
||||||
virtual bool AccelerateTextureCopy(const GPU::Regs::DisplayTransferConfig& config) {
|
virtual bool AccelerateTextureCopy(
|
||||||
|
[[maybe_unused]] const GPU::Regs::DisplayTransferConfig& config) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempt to use a faster method to fill a region
|
/// Attempt to use a faster method to fill a region
|
||||||
virtual bool AccelerateFill(const GPU::Regs::MemoryFillConfig& config) {
|
virtual bool AccelerateFill([[maybe_unused]] const GPU::Regs::MemoryFillConfig& config) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempt to use a faster method to display the framebuffer to screen
|
/// Attempt to use a faster method to display the framebuffer to screen
|
||||||
virtual bool AccelerateDisplay(const GPU::Regs::FramebufferConfig& config,
|
virtual bool AccelerateDisplay([[maybe_unused]] const GPU::Regs::FramebufferConfig& config,
|
||||||
PAddr framebuffer_addr, u32 pixel_stride,
|
[[maybe_unused]] PAddr framebuffer_addr,
|
||||||
OpenGL::ScreenInfo& screen_info) {
|
[[maybe_unused]] u32 pixel_stride,
|
||||||
|
[[maybe_unused]] OpenGL::ScreenInfo& screen_info) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempt to draw using hardware shaders
|
/// Attempt to draw using hardware shaders
|
||||||
virtual bool AccelerateDrawBatch(bool is_indexed) {
|
virtual bool AccelerateDrawBatch([[maybe_unused]] bool is_indexed) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void LoadDiskResources(const std::atomic_bool& stop_loading,
|
virtual void LoadDiskResources([[maybe_unused]] const std::atomic_bool& stop_loading,
|
||||||
const DiskResourceLoadCallback& callback) {}
|
[[maybe_unused]] const DiskResourceLoadCallback& callback) {}
|
||||||
|
|
||||||
virtual void SyncEntireState() {}
|
virtual void SyncEntireState() {}
|
||||||
};
|
};
|
||||||
|
|
|
@ -413,10 +413,10 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) {
|
||||||
|
|
||||||
// Sync the viewport
|
// Sync the viewport
|
||||||
const auto viewport = framebuffer.Viewport();
|
const auto viewport = framebuffer.Viewport();
|
||||||
state.viewport.x = viewport.x;
|
state.viewport.x = static_cast<GLint>(viewport.x);
|
||||||
state.viewport.y = viewport.y;
|
state.viewport.y = static_cast<GLint>(viewport.y);
|
||||||
state.viewport.width = viewport.width;
|
state.viewport.width = static_cast<GLsizei>(viewport.width);
|
||||||
state.viewport.height = viewport.height;
|
state.viewport.height = static_cast<GLsizei>(viewport.height);
|
||||||
|
|
||||||
// Viewport can have negative offsets or larger dimensions than our framebuffer sub-rect.
|
// Viewport can have negative offsets or larger dimensions than our framebuffer sub-rect.
|
||||||
// Enable scissor test to prevent drawing outside of the framebuffer region
|
// Enable scissor test to prevent drawing outside of the framebuffer region
|
||||||
|
@ -427,7 +427,7 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) {
|
||||||
state.scissor.width = draw_rect.GetWidth();
|
state.scissor.width = draw_rect.GetWidth();
|
||||||
state.scissor.height = draw_rect.GetHeight();
|
state.scissor.height = draw_rect.GetHeight();
|
||||||
|
|
||||||
const u32 res_scale = framebuffer.ResolutionScale();
|
const int res_scale = static_cast<int>(framebuffer.ResolutionScale());
|
||||||
if (uniform_block_data.data.framebuffer_scale != res_scale) {
|
if (uniform_block_data.data.framebuffer_scale != res_scale) {
|
||||||
uniform_block_data.data.framebuffer_scale = res_scale;
|
uniform_block_data.data.framebuffer_scale = res_scale;
|
||||||
uniform_block_data.dirty = true;
|
uniform_block_data.dirty = true;
|
||||||
|
|
|
@ -398,8 +398,8 @@ void DrawShadowMapPixel(int x, int y, u32 depth, u8 stencil) {
|
||||||
} else {
|
} else {
|
||||||
float16 constant = float16::FromRaw(shadow.constant);
|
float16 constant = float16::FromRaw(shadow.constant);
|
||||||
float16 linear = float16::FromRaw(shadow.linear);
|
float16 linear = float16::FromRaw(shadow.linear);
|
||||||
float16 x = float16::FromFloat32(static_cast<float>(depth) / ref_z);
|
float16 x_ = float16::FromFloat32(static_cast<float>(depth) / ref_z);
|
||||||
float16 stencil_new = float16::FromFloat32(stencil) / (constant + linear * x);
|
float16 stencil_new = float16::FromFloat32(stencil) / (constant + linear * x_);
|
||||||
stencil = static_cast<u8>(std::clamp(stencil_new.ToFloat32(), 0.0f, 255.0f));
|
stencil = static_cast<u8>(std::clamp(stencil_new.ToFloat32(), 0.0f, 255.0f));
|
||||||
|
|
||||||
if (stencil < ref_s)
|
if (stencil < ref_s)
|
||||||
|
|
|
@ -456,7 +456,7 @@ static void RunInterpreter(const ShaderSetup& setup, UnitState& state, DebugData
|
||||||
case OpCode::Type::MultiplyAdd: {
|
case OpCode::Type::MultiplyAdd: {
|
||||||
if ((instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MAD) ||
|
if ((instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MAD) ||
|
||||||
(instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI)) {
|
(instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI)) {
|
||||||
const SwizzlePattern& swizzle = *reinterpret_cast<const SwizzlePattern*>(
|
const SwizzlePattern& mad_swizzle = *reinterpret_cast<const SwizzlePattern*>(
|
||||||
&swizzle_data[instr.mad.operand_desc_id]);
|
&swizzle_data[instr.mad.operand_desc_id]);
|
||||||
|
|
||||||
bool is_inverted = (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI);
|
bool is_inverted = (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI);
|
||||||
|
@ -472,15 +472,15 @@ static void RunInterpreter(const ShaderSetup& setup, UnitState& state, DebugData
|
||||||
const float24* src3_ = LookupSourceRegister(instr.mad.GetSrc3(is_inverted) +
|
const float24* src3_ = LookupSourceRegister(instr.mad.GetSrc3(is_inverted) +
|
||||||
(is_inverted * address_offset));
|
(is_inverted * address_offset));
|
||||||
|
|
||||||
const bool negate_src1 = ((bool)swizzle.negate_src1 != false);
|
const bool negate_src1 = ((bool)mad_swizzle.negate_src1 != false);
|
||||||
const bool negate_src2 = ((bool)swizzle.negate_src2 != false);
|
const bool negate_src2 = ((bool)mad_swizzle.negate_src2 != false);
|
||||||
const bool negate_src3 = ((bool)swizzle.negate_src3 != false);
|
const bool negate_src3 = ((bool)mad_swizzle.negate_src3 != false);
|
||||||
|
|
||||||
float24 src1[4] = {
|
float24 src1[4] = {
|
||||||
src1_[(int)swizzle.src1_selector_0.Value()],
|
src1_[(int)mad_swizzle.src1_selector_0.Value()],
|
||||||
src1_[(int)swizzle.src1_selector_1.Value()],
|
src1_[(int)mad_swizzle.src1_selector_1.Value()],
|
||||||
src1_[(int)swizzle.src1_selector_2.Value()],
|
src1_[(int)mad_swizzle.src1_selector_2.Value()],
|
||||||
src1_[(int)swizzle.src1_selector_3.Value()],
|
src1_[(int)mad_swizzle.src1_selector_3.Value()],
|
||||||
};
|
};
|
||||||
if (negate_src1) {
|
if (negate_src1) {
|
||||||
src1[0] = -src1[0];
|
src1[0] = -src1[0];
|
||||||
|
@ -489,10 +489,10 @@ static void RunInterpreter(const ShaderSetup& setup, UnitState& state, DebugData
|
||||||
src1[3] = -src1[3];
|
src1[3] = -src1[3];
|
||||||
}
|
}
|
||||||
float24 src2[4] = {
|
float24 src2[4] = {
|
||||||
src2_[(int)swizzle.src2_selector_0.Value()],
|
src2_[(int)mad_swizzle.src2_selector_0.Value()],
|
||||||
src2_[(int)swizzle.src2_selector_1.Value()],
|
src2_[(int)mad_swizzle.src2_selector_1.Value()],
|
||||||
src2_[(int)swizzle.src2_selector_2.Value()],
|
src2_[(int)mad_swizzle.src2_selector_2.Value()],
|
||||||
src2_[(int)swizzle.src2_selector_3.Value()],
|
src2_[(int)mad_swizzle.src2_selector_3.Value()],
|
||||||
};
|
};
|
||||||
if (negate_src2) {
|
if (negate_src2) {
|
||||||
src2[0] = -src2[0];
|
src2[0] = -src2[0];
|
||||||
|
@ -501,10 +501,10 @@ static void RunInterpreter(const ShaderSetup& setup, UnitState& state, DebugData
|
||||||
src2[3] = -src2[3];
|
src2[3] = -src2[3];
|
||||||
}
|
}
|
||||||
float24 src3[4] = {
|
float24 src3[4] = {
|
||||||
src3_[(int)swizzle.src3_selector_0.Value()],
|
src3_[(int)mad_swizzle.src3_selector_0.Value()],
|
||||||
src3_[(int)swizzle.src3_selector_1.Value()],
|
src3_[(int)mad_swizzle.src3_selector_1.Value()],
|
||||||
src3_[(int)swizzle.src3_selector_2.Value()],
|
src3_[(int)mad_swizzle.src3_selector_2.Value()],
|
||||||
src3_[(int)swizzle.src3_selector_3.Value()],
|
src3_[(int)mad_swizzle.src3_selector_3.Value()],
|
||||||
};
|
};
|
||||||
if (negate_src3) {
|
if (negate_src3) {
|
||||||
src3[0] = -src3[0];
|
src3[0] = -src3[0];
|
||||||
|
@ -525,7 +525,7 @@ static void RunInterpreter(const ShaderSetup& setup, UnitState& state, DebugData
|
||||||
Record<DebugDataRecord::SRC3>(debug_data, iteration, src3);
|
Record<DebugDataRecord::SRC3>(debug_data, iteration, src3);
|
||||||
Record<DebugDataRecord::DEST_IN>(debug_data, iteration, dest);
|
Record<DebugDataRecord::DEST_IN>(debug_data, iteration, dest);
|
||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i) {
|
||||||
if (!swizzle.DestComponentEnabled(i))
|
if (!mad_swizzle.DestComponentEnabled(i))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
dest[i] = src1[i] * src2[i] + src3[i];
|
dest[i] = src1[i] * src2[i] + src3[i];
|
||||||
|
|
Reference in New Issue