diff --git a/.github/workflows/Linux_Build.yml b/.github/workflows/Linux_Build.yml index 71a318a8..d58c3c94 100644 --- a/.github/workflows/Linux_Build.yml +++ b/.github/workflows/Linux_Build.yml @@ -26,7 +26,7 @@ jobs: - name: Configure CMake # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type - run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ + run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DENABLE_USER_BUILD=ON - name: Build # Build your program with the given configuration diff --git a/.github/workflows/MacOS_Build.yml b/.github/workflows/MacOS_Build.yml index 4007e0e9..5e0de4bc 100644 --- a/.github/workflows/MacOS_Build.yml +++ b/.github/workflows/MacOS_Build.yml @@ -26,7 +26,7 @@ jobs: - name: Configure CMake # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type - run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} + run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DENABLE_USER_BUILD=ON - name: Build # Build your program with the given configuration diff --git a/.github/workflows/Windows_Build.yml b/.github/workflows/Windows_Build.yml index 0a4abe41..2e8a8562 100644 --- a/.github/workflows/Windows_Build.yml +++ b/.github/workflows/Windows_Build.yml @@ -26,7 +26,7 @@ jobs: - name: Configure CMake # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type - run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} + run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DENABLE_USER_BUILD=ON - name: Build # Build your program with the given configuration diff --git a/CMakeLists.txt b/CMakeLists.txt index b7310d95..cccd9e2c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.10) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED True) -if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 12) +if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 12) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fbracket-depth=4096") endif() @@ -13,8 +13,14 @@ endif() project(Alber) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) +if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-format-nonliteral -Wno-format-security") +endif() + +option(DISABLE_PANIC_DEV "Make a build with fewer and less intrusive asserts" OFF) option(GPU_DEBUG_INFO "Enable additional GPU debugging info" OFF) option(ENABLE_LTO "Enable link-time optimization" OFF) +option(ENABLE_USER_BUILD "Make a user-facing build. These builds have various assertions disabled, LTO, and more" OFF) include_directories(${PROJECT_SOURCE_DIR}/include/) include_directories(${PROJECT_SOURCE_DIR}/include/kernel) @@ -159,7 +165,7 @@ source_group("Source Files\\Third Party" FILES ${THIRD_PARTY_SOURCE_FILES}) add_executable(Alber ${SOURCE_FILES} ${FS_SOURCE_FILES} ${CRYPTO_SOURCE_FILES} ${KERNEL_SOURCE_FILES} ${LOADER_SOURCE_FILES} ${SERVICE_SOURCE_FILES} ${PICA_SOURCE_FILES} ${RENDERER_GL_SOURCE_FILES} ${THIRD_PARTY_SOURCE_FILES} ${HEADER_FILES}) -if(ENABLE_LTO) +if(ENABLE_LTO OR ENABLE_USER_BUILD) set_target_properties(Alber PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE) endif() @@ -167,4 +173,12 @@ target_link_libraries(Alber PRIVATE dynarmic SDL2-static glad cryptopp) if(GPU_DEBUG_INFO) target_compile_definitions(Alber PRIVATE GPU_DEBUG_INFO=1) -endif() \ No newline at end of file +endif() + +if(ENABLE_USER_BUILD) + target_compile_definitions(Alber PRIVATE PANDA3DS_USER_BUILD=1) +endif() + +if(ENABLE_USER_BUILD OR DISABLE_PANIC_DEV) + target_compile_definitions(Alber PRIVATE PANDA3DS_LIMITED_PANICS=1) +endif() diff --git a/include/helpers.hpp b/include/helpers.hpp index 53c57c7c..9830cc88 100644 --- a/include/helpers.hpp +++ b/include/helpers.hpp @@ -30,24 +30,31 @@ using s32 = std::int32_t; using s64 = std::int64_t; namespace Helpers { - [[noreturn]] static void panic(const char* fmt, ...) { - std::va_list args; - va_start(args, fmt); + // Unconditional panic, unlike panicDev which does not panic on user builds + template + [[noreturn]] static void panic(const char* fmt, Args&&... args) { std::cout << termcolor::on_red << "[FATAL] "; - std::vprintf(fmt, args); + std::printf(fmt, args...); std::cout << termcolor::reset << "\n"; - va_end(args); exit(1); } + +#ifdef PANDA3DS_LIMITED_PANICS + template + static void panicDev(const char* fmt, Args&&... args) {} +#else + template + [[noreturn]] static void panicDev(const char* fmt, Args&&... args) { + panic(fmt, args...); + } +#endif - static void warn(const char* fmt, ...) { - std::va_list args; - va_start(args, fmt); + template + static void warn(const char* fmt, Args&&... args) { std::cout << termcolor::on_red << "[Warning] "; - std::vprintf(fmt, args); + std::printf(fmt, args...); std::cout << termcolor::reset << "\n"; - va_end(args); } static constexpr bool buildingInDebugMode() { @@ -57,6 +64,13 @@ namespace Helpers { return true; } + static constexpr bool isUserBuild() { +#ifdef PANDA3DS_USER_BUILD + return true; +#endif + return false; + } + static void debug_printf(const char* fmt, ...) { if constexpr (buildingInDebugMode()) { std::va_list args; diff --git a/src/core/kernel/directory_operations.cpp b/src/core/kernel/directory_operations.cpp index 567d9cb8..fe4f58f4 100644 --- a/src/core/kernel/directory_operations.cpp +++ b/src/core/kernel/directory_operations.cpp @@ -33,7 +33,7 @@ void Kernel::readDirectory(u32 messagePointer, Handle directory) { const u32 entryCount = mem.read32(messagePointer + 4); const u32 outPointer = mem.read32(messagePointer + 12); logFileIO("Directory::Read (handle = %X, entry count = %d, out pointer = %08X)\n", directory, entryCount, outPointer); - Helpers::panic("Unimplemented FsDir::Read"); + Helpers::panicDev("Unimplemented FsDir::Read"); mem.write32(messagePointer + 4, Result::Success); mem.write32(messagePointer + 8, 0); diff --git a/src/core/renderer_gl/renderer_gl.cpp b/src/core/renderer_gl/renderer_gl.cpp index 0cbc9cbc..487c9db8 100644 --- a/src/core/renderer_gl/renderer_gl.cpp +++ b/src/core/renderer_gl/renderer_gl.cpp @@ -695,7 +695,9 @@ void Renderer::bindDepthBuffer() { tex = depthBufferCache.add(sampleBuffer).texture.m_handle; } - if (PICA::DepthFmt::Depth24Stencil8 != depthBufferFormat) Helpers::panic("TODO: Should we remove stencil attachment?"); + if (PICA::DepthFmt::Depth24Stencil8 != depthBufferFormat) { + Helpers::panicDev("TODO: Should we remove stencil attachment?"); + } auto attachment = depthBufferFormat == PICA::DepthFmt::Depth24Stencil8 ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT; glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, tex, 0); } diff --git a/src/core/services/apt.cpp b/src/core/services/apt.cpp index f2c7612d..becf637f 100644 --- a/src/core/services/apt.cpp +++ b/src/core/services/apt.cpp @@ -81,7 +81,10 @@ void APTService::handleSyncRequest(u32 messagePointer) { case APTCommands::SetApplicationCpuTimeLimit: setApplicationCpuTimeLimit(messagePointer); break; case APTCommands::SetScreencapPostPermission: setScreencapPostPermission(messagePointer); break; case APTCommands::TheSmashBrosFunction: theSmashBrosFunction(messagePointer); break; - default: Helpers::panic("APT service requested. Command: %08X\n", command); + default: + Helpers::panicDev("APT service requested. Command: %08X\n", command); + mem.write32(messagePointer + 4, Result::Success); + break; } } diff --git a/src/core/services/cecd.cpp b/src/core/services/cecd.cpp index f641e40d..dd9ccb2f 100644 --- a/src/core/services/cecd.cpp +++ b/src/core/services/cecd.cpp @@ -16,7 +16,10 @@ void CECDService::handleSyncRequest(u32 messagePointer) { const u32 command = mem.read32(messagePointer); switch (command) { case CECDCommands::GetInfoEventHandle: getInfoEventHandle(messagePointer); break; - default: Helpers::panic("CECD service requested. Command: %08X\n", command); + default: + Helpers::panicDev("CECD service requested. Command: %08X\n", command); + mem.write32(messagePointer + 4, Result::Success); + break; } }