diff --git a/3rdparty/OpenAL/openal-soft.vcxproj b/3rdparty/OpenAL/openal-soft.vcxproj
index 2d5823ba2d..37945fdf01 100644
--- a/3rdparty/OpenAL/openal-soft.vcxproj
+++ b/3rdparty/OpenAL/openal-soft.vcxproj
@@ -48,21 +48,21 @@
call vsdevcmd.bat -arch=amd64
- cd $(SolutionDir)build\tmp\$(ProjectName)-$(Configuration)-$(Platform)
- cmake -G Ninja -DCMAKE_CXX_COMPILER="cl.exe" -DCMAKE_C_COMPILER="cl.exe" -DCMAKE_BUILD_TYPE="Release" -DCMAKE_INSTALL_PREFIX="./Release" -DCMAKE_SYSTEM_VERSION=6.1 -DLIBTYPE=STATIC -DFORCE_STATIC_VCRT=true -DALSOFT_UTILS=false -DALSOFT_EXAMPLES=false -DALSOFT_INSTALL=false -DALSOFT_INSTALL_CONFIG=false -DALSOFT_INSTALL_HRTF_DATA=false -DALSOFT_INSTALL_AMBDEC_PRESETS=false -DALSOFT_INSTALL_EXAMPLES=false -DALSOFT_INSTALL_UTILS=false $(SolutionDir)3rdparty\OpenAL\openal-soft
+ cd "$(SolutionDir)build\tmp\$(ProjectName)-$(Configuration)-$(Platform)"
+ cmake -G Ninja -DCMAKE_CXX_COMPILER="cl.exe" -DCMAKE_C_COMPILER="cl.exe" -DCMAKE_BUILD_TYPE="Release" -DCMAKE_INSTALL_PREFIX="./Release" -DCMAKE_SYSTEM_VERSION=6.1 -DLIBTYPE=STATIC -DFORCE_STATIC_VCRT=true -DALSOFT_UTILS=false -DALSOFT_EXAMPLES=false -DALSOFT_INSTALL=false -DALSOFT_INSTALL_CONFIG=false -DALSOFT_INSTALL_HRTF_DATA=false -DALSOFT_INSTALL_AMBDEC_PRESETS=false -DALSOFT_INSTALL_EXAMPLES=false -DALSOFT_INSTALL_UTILS=false "$(SolutionDir)3rdparty\OpenAL\openal-soft"
call vsdevcmd.bat -arch=amd64
- cd $(SolutionDir)build\tmp\$(ProjectName)-$(Configuration)-$(Platform)
- cmake -G Ninja -DCMAKE_CXX_COMPILER="cl.exe" -DCMAKE_C_COMPILER="cl.exe" -DCMAKE_BUILD_TYPE="Debug" -DCMAKE_INSTALL_PREFIX="./Debug" -DCMAKE_SYSTEM_VERSION=6.1 -DLIBTYPE=STATIC -DALSOFT_UTILS=false -DALSOFT_EXAMPLES=false -DALSOFT_INSTALL=false -DALSOFT_INSTALL_CONFIG=false -DALSOFT_INSTALL_HRTF_DATA=false -DALSOFT_INSTALL_AMBDEC_PRESETS=false -DALSOFT_INSTALL_EXAMPLES=false -DALSOFT_INSTALL_UTILS=false $(SolutionDir)3rdparty\OpenAL\openal-soft
+ cd "$(SolutionDir)build\tmp\$(ProjectName)-$(Configuration)-$(Platform)"
+ cmake -G Ninja -DCMAKE_CXX_COMPILER="cl.exe" -DCMAKE_C_COMPILER="cl.exe" -DCMAKE_BUILD_TYPE="Debug" -DCMAKE_INSTALL_PREFIX="./Debug" -DCMAKE_SYSTEM_VERSION=6.1 -DLIBTYPE=STATIC -DALSOFT_UTILS=false -DALSOFT_EXAMPLES=false -DALSOFT_INSTALL=false -DALSOFT_INSTALL_CONFIG=false -DALSOFT_INSTALL_HRTF_DATA=false -DALSOFT_INSTALL_AMBDEC_PRESETS=false -DALSOFT_INSTALL_EXAMPLES=false -DALSOFT_INSTALL_UTILS=false "$(SolutionDir)3rdparty\OpenAL\openal-soft"
echo Copying..
- copy $(SolutionDir)build\tmp\$(ProjectName)-$(Configuration)-$(Platform)\OpenAL32.lib $(SolutionDir)build\lib\$(Configuration)-$(Platform)
+ copy "$(SolutionDir)build\tmp\$(ProjectName)-$(Configuration)-$(Platform)\OpenAL32.lib" "$(SolutionDir)build\lib\$(Configuration)-$(Platform)"
echo Cleaning..
- del $(SolutionDir)build\lib\$(Configuration)-$(Platform)\OpenAL32.lib
- rmdir /s /q $(SolutionDir)build\tmp\$(ProjectName)-$(Configuration)-$(Platform)
+ del "$(SolutionDir)build\lib\$(Configuration)-$(Platform)\OpenAL32.lib"
+ rmdir /s /q "$(SolutionDir)build\tmp\$(ProjectName)-$(Configuration)-$(Platform)"
diff --git a/3rdparty/glslang/glslang.vcxproj b/3rdparty/glslang/glslang.vcxproj
index 0da04a3209..762fff7622 100644
--- a/3rdparty/glslang/glslang.vcxproj
+++ b/3rdparty/glslang/glslang.vcxproj
@@ -39,24 +39,24 @@
"Visual Studio $(VisualStudioVersion.Substring(0,2))"
call vsdevcmd.bat -arch=amd64
- cmake -G $(CmakeGenerator) -A x64 -DCMAKE_BUILD_TYPE="Release" -DLLVM_USE_CRT_DEBUG=MDd -DLLVM_USE_CRT_RELEASE=MT -DENABLE_OPT=OFF -S glslang -B $(SolutionDir)build\tmp\$(ProjectName)-$(Configuration)-$(Platform)
+ cmake -G $(CmakeGenerator) -A x64 -DCMAKE_BUILD_TYPE="Release" -DLLVM_USE_CRT_DEBUG=MDd -DLLVM_USE_CRT_RELEASE=MT -DENABLE_OPT=OFF -S glslang -B "$(SolutionDir)build\tmp\$(ProjectName)-$(Configuration)-$(Platform)"
call vsdevcmd.bat -arch=amd64
- cmake -G $(CmakeGenerator) -A x64 -DCMAKE_BUILD_TYPE="Debug" -DLLVM_USE_CRT_DEBUG=MDd -DLLVM_USE_CRT_RELEASE=MT -DENABLE_OPT=OFF -S glslang -B $(SolutionDir)build\tmp\$(ProjectName)-$(Configuration)-$(Platform)
+ cmake -G $(CmakeGenerator) -A x64 -DCMAKE_BUILD_TYPE="Debug" -DLLVM_USE_CRT_DEBUG=MDd -DLLVM_USE_CRT_RELEASE=MT -DENABLE_OPT=OFF -S glslang -B "$(SolutionDir)build\tmp\$(ProjectName)-$(Configuration)-$(Platform)"
echo Copying..
- mkdir $(SolutionDir)build\lib\$(Configuration)-$(Platform)\$(ProjectName)
- copy $(SolutionDir)build\tmp\$(ProjectName)-$(Configuration)-$(Platform)\hlsl\$(CONFIGURATION)\*.lib $(SolutionDir)build\lib\$(Configuration)-$(Platform)\$(ProjectName)
- copy $(SolutionDir)build\tmp\$(ProjectName)-$(Configuration)-$(Platform)\SPIRV\$(CONFIGURATION)\*.lib $(SolutionDir)build\lib\$(Configuration)-$(Platform)\$(ProjectName)
- copy $(SolutionDir)build\tmp\$(ProjectName)-$(Configuration)-$(Platform)\OGLCompilersDLL\$(CONFIGURATION)\*.lib $(SolutionDir)build\lib\$(Configuration)-$(Platform)\$(ProjectName)
- copy $(SolutionDir)build\tmp\$(ProjectName)-$(Configuration)-$(Platform)\glslang\OSDependent\Windows\$(CONFIGURATION)\*.lib $(SolutionDir)build\lib\$(Configuration)-$(Platform)\$(ProjectName)
- copy $(SolutionDir)build\tmp\$(ProjectName)-$(Configuration)-$(Platform)\glslang\$(CONFIGURATION)\*.lib $(SolutionDir)build\lib\$(Configuration)-$(Platform)\$(ProjectName)
+ mkdir "$(SolutionDir)build\lib\$(Configuration)-$(Platform)\$(ProjectName)"
+ copy "$(SolutionDir)build\tmp\$(ProjectName)-$(Configuration)-$(Platform)\hlsl\$(CONFIGURATION)\*.lib" "$(SolutionDir)build\lib\$(Configuration)-$(Platform)\$(ProjectName)"
+ copy "$(SolutionDir)build\tmp\$(ProjectName)-$(Configuration)-$(Platform)\SPIRV\$(CONFIGURATION)\*.lib" "$(SolutionDir)build\lib\$(Configuration)-$(Platform)\$(ProjectName)"
+ copy "$(SolutionDir)build\tmp\$(ProjectName)-$(Configuration)-$(Platform)\OGLCompilersDLL\$(CONFIGURATION)\*.lib" "$(SolutionDir)build\lib\$(Configuration)-$(Platform)\$(ProjectName)"
+ copy "$(SolutionDir)build\tmp\$(ProjectName)-$(Configuration)-$(Platform)\glslang\OSDependent\Windows\$(CONFIGURATION)\*.lib" "$(SolutionDir)build\lib\$(Configuration)-$(Platform)\$(ProjectName)"
+ copy "$(SolutionDir)build\tmp\$(ProjectName)-$(Configuration)-$(Platform)\glslang\$(CONFIGURATION)\*.lib" "$(SolutionDir)build\lib\$(Configuration)-$(Platform)\$(ProjectName)"
echo Cleaning..
- rmdir /s /q $(SolutionDir)build\lib\$(Configuration)-$(Platform)\$(ProjectName)
- rmdir /s /q $(SolutionDir)build\tmp\$(ProjectName)-$(Configuration)-$(Platform)
+ rmdir /s /q "$(SolutionDir)build\lib\$(Configuration)-$(Platform)\$(ProjectName)"
+ rmdir /s /q "$(SolutionDir)build\tmp\$(ProjectName)-$(Configuration)-$(Platform)"
$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\..\buildfiles\msvc\common_default.props'))
@@ -65,17 +65,17 @@
$(SolutionDir)build\tmp\$(ProjectName)-$(Configuration)-$(Platform)\
$(CmakeReleaseCLI)
- msbuild.exe $(IntDir)\ALL_BUILD.vcxproj /t:build /p:Configuration=Release /p:ForceImportBeforeCppTargets="$(PropsAbsPath)" /m
+ msbuild.exe "$(IntDir)\ALL_BUILD.vcxproj" /t:build /p:Configuration=Release /p:ForceImportBeforeCppTargets="$(PropsAbsPath)" /m
$(CmakeCopyCLI)
$(CmakeReleaseCLI)
- msbuild.exe $(IntDir)\ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Release /p:ForceImportBeforeCppTargets="$(PropsAbsPath)" /m
+ msbuild.exe "$(IntDir)\ALL_BUILD.vcxproj" /t:rebuild /p:Configuration=Release /p:ForceImportBeforeCppTargets="$(PropsAbsPath)" /m
$(CmakeCopyCLI)
$(CmakeReleaseCLI)
- msbuild.exe $(IntDir)\ALL_BUILD.vcxproj /t:clean /p:Configuration=Release /p:ForceImportBeforeCppTargets="$(PropsAbsPath)" /m
+ msbuild.exe "$(IntDir)\ALL_BUILD.vcxproj" /t:clean /p:Configuration=Release /p:ForceImportBeforeCppTargets="$(PropsAbsPath)" /m
$(CmakeCleanCLI)
@@ -84,17 +84,17 @@
$(SolutionDir)build\tmp\$(ProjectName)-$(Configuration)-$(Platform)\
$(CmakeDebugCLI)
- msbuild.exe $(IntDir)\ALL_BUILD.vcxproj /t:build /p:Configuration=Debug /p:ForceImportBeforeCppTargets="$(PropsAbsPath)" /m
+ msbuild.exe "$(IntDir)\ALL_BUILD.vcxproj" /t:build /p:Configuration=Debug /p:ForceImportBeforeCppTargets="$(PropsAbsPath)" /m
$(CmakeCopyCLI)
$(CmakeDebugCLI)
- msbuild.exe $(IntDir)\ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Debug /p:ForceImportBeforeCppTargets="$(PropsAbsPath)" /m
+ msbuild.exe "$(IntDir)\ALL_BUILD.vcxproj" /t:rebuild /p:Configuration=Debug /p:ForceImportBeforeCppTargets="$(PropsAbsPath)" /m
$(CmakeCopyCLI)
$(CmakeDebugCLI)
- msbuild.exe $(IntDir)\ALL_BUILD.vcxproj /t:clean /p:Configuration=Debug /p:ForceImportBeforeCppTargets="$(PropsAbsPath)" /m
+ msbuild.exe "$(IntDir)\ALL_BUILD.vcxproj" /t:clean /p:Configuration=Debug /p:ForceImportBeforeCppTargets="$(PropsAbsPath)" /m
$(CmakeCleanCLI)
diff --git a/3rdparty/llvm/llvm_build.vcxproj b/3rdparty/llvm/llvm_build.vcxproj
index fe3517a5d9..73a33db1a2 100644
--- a/3rdparty/llvm/llvm_build.vcxproj
+++ b/3rdparty/llvm/llvm_build.vcxproj
@@ -39,17 +39,17 @@
call vsdevcmd.bat -arch=amd64
- cd $(SolutionDir)build\tmp\llvm_build-$(Configuration)-$(Platform)
- cmake -G Ninja -DCMAKE_CXX_COMPILER="cl.exe" -DCMAKE_C_COMPILER="cl.exe" -DCMAKE_BUILD_TYPE="Release" -DCMAKE_INSTALL_PREFIX="$(SolutionDir)build\lib\$(Configuration)-$(Platform)\llvm_build" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_DEFAULT_TARGET_TRIPLE:STRING=x86_64-pc-windows-msvc -DLLVM_HOST_TRIPLE:STRING=x86_64-pc-windows-msvc -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_BENCHMARKS=OFF -DLLVM_INCLUDE_UTILS=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=$(WindowsTargetPlatformVersion) -DLLVM_USE_CRT_DEBUG=MDd -DLLVM_USE_CRT_RELEASE=MT -DLLVM_USE_INTEL_JITEVENTS=ON $(SolutionDir)3rdparty\llvm\llvm\llvm
+ cd "$(SolutionDir)build\tmp\llvm_build-$(Configuration)-$(Platform)"
+ cmake -G Ninja -DCMAKE_CXX_COMPILER="cl.exe" -DCMAKE_C_COMPILER="cl.exe" -DCMAKE_BUILD_TYPE="Release" -DCMAKE_INSTALL_PREFIX="$(SolutionDir)build\lib\$(Configuration)-$(Platform)\llvm_build" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_DEFAULT_TARGET_TRIPLE:STRING=x86_64-pc-windows-msvc -DLLVM_HOST_TRIPLE:STRING=x86_64-pc-windows-msvc -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_BENCHMARKS=OFF -DLLVM_INCLUDE_UTILS=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=$(WindowsTargetPlatformVersion) -DLLVM_USE_CRT_DEBUG=MDd -DLLVM_USE_CRT_RELEASE=MT -DLLVM_USE_INTEL_JITEVENTS=ON "$(SolutionDir)3rdparty\llvm\llvm\llvm"
call vsdevcmd.bat -arch=amd64
- cd $(SolutionDir)build\tmp\llvm_build-$(Configuration)-$(Platform)
- cmake -G Ninja -DCMAKE_CXX_COMPILER="cl.exe" -DCMAKE_C_COMPILER="cl.exe" -DCMAKE_BUILD_TYPE="Debug" -DCMAKE_INSTALL_PREFIX="$(SolutionDir)build\lib\$(Configuration)-$(Platform)\llvm_build" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_DEFAULT_TARGET_TRIPLE:STRING=x86_64-pc-windows-msvc -DLLVM_HOST_TRIPLE:STRING=x86_64-pc-windows-msvc -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_BENCHMARKS=OFF -DLLVM_INCLUDE_UTILS=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=$(WindowsTargetPlatformVersion) -DLLVM_USE_CRT_DEBUG=MDd -DLLVM_USE_CRT_RELEASE=MT -DLLVM_USE_INTEL_JITEVENTS=ON $(SolutionDir)3rdparty\llvm\llvm\llvm
+ cd "$(SolutionDir)build\tmp\llvm_build-$(Configuration)-$(Platform)"
+ cmake -G Ninja -DCMAKE_CXX_COMPILER="cl.exe" -DCMAKE_C_COMPILER="cl.exe" -DCMAKE_BUILD_TYPE="Debug" -DCMAKE_INSTALL_PREFIX="$(SolutionDir)build\lib\$(Configuration)-$(Platform)\llvm_build" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_DEFAULT_TARGET_TRIPLE:STRING=x86_64-pc-windows-msvc -DLLVM_HOST_TRIPLE:STRING=x86_64-pc-windows-msvc -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_BENCHMARKS=OFF -DLLVM_INCLUDE_UTILS=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=$(WindowsTargetPlatformVersion) -DLLVM_USE_CRT_DEBUG=MDd -DLLVM_USE_CRT_RELEASE=MT -DLLVM_USE_INTEL_JITEVENTS=ON "$(SolutionDir)3rdparty\llvm\llvm\llvm"
echo Cleaning..
- rmdir /s /q $(SolutionDir)build\lib\$(Configuration)-$(Platform)\llvm_build
- cd $(SolutionDir)build\tmp\llvm_build-$(Configuration)-$(Platform)
+ rmdir /s /q "$(SolutionDir)build\lib\$(Configuration)-$(Platform)\llvm_build"
+ cd "$(SolutionDir)build\tmp\llvm_build-$(Configuration)-$(Platform)"
for /F "delims= eol=|" %%f in ('
dir /b ^| findstr /V "[^.]*\build[^.]*\.vcxproj"') do (
echo Deleting .\%%f
diff --git a/3rdparty/llvm/llvm_build_clang_cl.vcxproj b/3rdparty/llvm/llvm_build_clang_cl.vcxproj
index a124b1a9a5..f9380e896d 100644
--- a/3rdparty/llvm/llvm_build_clang_cl.vcxproj
+++ b/3rdparty/llvm/llvm_build_clang_cl.vcxproj
@@ -39,17 +39,17 @@
call vsdevcmd.bat -arch=amd64
- cd $(SolutionDir)build\tmp\llvm_build-$(Configuration)-$(Platform)
- cmake -G Ninja -DCMAKE_CXX_COMPILER="clang-cl.exe" -DCMAKE_C_COMPILER="clang-cl.exe" -DCMAKE_BUILD_TYPE="Release" -DCMAKE_INSTALL_PREFIX="$(SolutionDir)build\lib\$(Configuration)-$(Platform)\llvm_build" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_DEFAULT_TARGET_TRIPLE:STRING=x86_64-pc-windows-msvc -DLLVM_HOST_TRIPLE:STRING=x86_64-pc-windows-msvc -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_BENCHMARKS=OFF -DLLVM_INCLUDE_UTILS=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=$(WindowsTargetPlatformVersion) -DLLVM_USE_CRT_DEBUG=MDd -DLLVM_USE_CRT_RELEASE=MT -DLLVM_USE_INTEL_JITEVENTS=ON $(SolutionDir)3rdparty\llvm\llvm\llvm
+ cd "$(SolutionDir)build\tmp\llvm_build-$(Configuration)-$(Platform)"
+ cmake -G Ninja -DCMAKE_CXX_COMPILER="clang-cl.exe" -DCMAKE_C_COMPILER="clang-cl.exe" -DCMAKE_BUILD_TYPE="Release" -DCMAKE_INSTALL_PREFIX="$(SolutionDir)build\lib\$(Configuration)-$(Platform)\llvm_build" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_DEFAULT_TARGET_TRIPLE:STRING=x86_64-pc-windows-msvc -DLLVM_HOST_TRIPLE:STRING=x86_64-pc-windows-msvc -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_BENCHMARKS=OFF -DLLVM_INCLUDE_UTILS=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=$(WindowsTargetPlatformVersion) -DLLVM_USE_CRT_DEBUG=MDd -DLLVM_USE_CRT_RELEASE=MT -DLLVM_USE_INTEL_JITEVENTS=ON "$(SolutionDir)3rdparty\llvm\llvm\llvm"
call vsdevcmd.bat -arch=amd64
- cd $(SolutionDir)build\tmp\llvm_build-$(Configuration)-$(Platform)
- cmake -G Ninja -DCMAKE_CXX_COMPILER="clang-cl.exe" -DCMAKE_C_COMPILER="clang-cl.exe" -DCMAKE_BUILD_TYPE="Debug" -DCMAKE_INSTALL_PREFIX="$(SolutionDir)build\lib\$(Configuration)-$(Platform)\llvm_build" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_DEFAULT_TARGET_TRIPLE:STRING=x86_64-pc-windows-msvc -DLLVM_HOST_TRIPLE:STRING=x86_64-pc-windows-msvc -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_BENCHMARKS=OFF -DLLVM_INCLUDE_UTILS=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=$(WindowsTargetPlatformVersion) -DLLVM_USE_CRT_DEBUG=MDd -DLLVM_USE_CRT_RELEASE=MT -DLLVM_USE_INTEL_JITEVENTS=ON $(SolutionDir)3rdparty\llvm\llvm\llvm
+ cd "$(SolutionDir)build\tmp\llvm_build-$(Configuration)-$(Platform)"
+ cmake -G Ninja -DCMAKE_CXX_COMPILER="clang-cl.exe" -DCMAKE_C_COMPILER="clang-cl.exe" -DCMAKE_BUILD_TYPE="Debug" -DCMAKE_INSTALL_PREFIX="$(SolutionDir)build\lib\$(Configuration)-$(Platform)\llvm_build" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_DEFAULT_TARGET_TRIPLE:STRING=x86_64-pc-windows-msvc -DLLVM_HOST_TRIPLE:STRING=x86_64-pc-windows-msvc -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_BENCHMARKS=OFF -DLLVM_INCLUDE_UTILS=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=$(WindowsTargetPlatformVersion) -DLLVM_USE_CRT_DEBUG=MDd -DLLVM_USE_CRT_RELEASE=MT -DLLVM_USE_INTEL_JITEVENTS=ON "$(SolutionDir)3rdparty\llvm\llvm\llvm"
echo Cleaning..
- rmdir /s /q $(SolutionDir)build\lib\$(Configuration)-$(Platform)\llvm_build
- cd $(SolutionDir)build\tmp\llvm_build-$(Configuration)-$(Platform)
+ rmdir /s /q "$(SolutionDir)build\lib\$(Configuration)-$(Platform)\llvm_build"
+ cd "$(SolutionDir)build\tmp\llvm_build-$(Configuration)-$(Platform)"
for /F "delims= eol=|" %%f in ('
dir /b ^| findstr /V "[^.]*\build[^.]*\.vcxproj"') do (
echo Deleting .\%%f
diff --git a/rpcs3/Emu/CMakeLists.txt b/rpcs3/Emu/CMakeLists.txt
index 35d7d91bd7..f4f67a4ea1 100644
--- a/rpcs3/Emu/CMakeLists.txt
+++ b/rpcs3/Emu/CMakeLists.txt
@@ -252,6 +252,7 @@ target_sources(rpcs3_emu PRIVATE
Cell/Modules/cellCrossController.cpp
Cell/Modules/cellDaisy.cpp
Cell/Modules/cellDmux.cpp
+ Cell/Modules/cellDmuxPamf.cpp
Cell/Modules/cellDtcpIpUtility.cpp
Cell/Modules/cellFiber.cpp
Cell/Modules/cellFont.cpp
diff --git a/rpcs3/Emu/Cell/Modules/cellAdec.cpp b/rpcs3/Emu/Cell/Modules/cellAdec.cpp
index 5eb80638f7..43c5f7989b 100644
--- a/rpcs3/Emu/Cell/Modules/cellAdec.cpp
+++ b/rpcs3/Emu/Cell/Modules/cellAdec.cpp
@@ -1,42 +1,57 @@
#include "stdafx.h"
-#include "Emu/System.h"
-#include "Emu/IdManager.h"
#include "Emu/Cell/PPUModule.h"
#include "Emu/Cell/lv2/sys_sync.h"
-#include "util/media_utils.h"
+#include "Emu/savestate_utils.hpp"
-#ifdef _MSC_VER
-#pragma warning(push, 0)
-#else
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wall"
-#pragma GCC diagnostic ignored "-Wextra"
-#pragma GCC diagnostic ignored "-Wold-style-cast"
-#endif
-extern "C"
-{
-#include "libavcodec/avcodec.h"
-#include "libavformat/avformat.h"
-#ifndef AV_INPUT_BUFFER_PADDING_SIZE
-#define AV_INPUT_BUFFER_PADDING_SIZE FF_INPUT_BUFFER_PADDING_SIZE
-#endif
-}
-#ifdef _MSC_VER
-#pragma warning(pop)
-#else
-#pragma GCC diagnostic pop
-#endif
-
-#include "cellPamf.h"
-#include "cellAtracXdec.h"
#include "cellAdec.h"
#include
-
-extern std::mutex g_mutex_avcodec_open2;
+#include "util/asm.hpp"
LOG_CHANNEL(cellAdec);
+// These need to be defined somewhere to access the LLE functions
+vm::gvar g_cell_adec_core_ops_ac3;
+vm::gvar g_cell_adec_core_ops_atrac3;
+vm::gvar g_cell_adec_core_ops_atrac3multi;
+vm::gvar g_cell_adec_core_ops_Celp8;
+vm::gvar g_cell_adec_core_ops_Celp;
+vm::gvar g_cell_adec_core_ops_Ddp;
+vm::gvar g_cell_adec_core_ops_DtsCore;
+vm::gvar g_cell_adec_core_ops_DtsHd_Core;
+vm::gvar g_cell_adec_core_ops_DtsHd;
+vm::gvar g_cell_adec_core_ops_DtsLbr;
+vm::gvar g_cell_adec_core_ops_Aac;
+vm::gvar g_cell_adec_core_ops_mpmc;
+vm::gvar g_cell_adec_core_ops_M4Aac;
+vm::gvar g_cell_adec_core_ops_M4Aac2ch;
+vm::gvar g_cell_adec_core_ops_M4Aac2chmod;
+vm::gvar g_cell_adec_core_ops_Mp3;
+vm::gvar g_cell_adec_core_ops_Mp3s;
+vm::gvar g_cell_adec_core_ops_mpmcl1;
+vm::gvar g_cell_adec_core_ops_truehd;
+vm::gvar g_cell_adec_core_ops_wma;
+vm::gvar g_cell_adec_core_ops_WmaLsl;
+vm::gvar g_cell_adec_core_ops_WmaPro;
+error_code _SceAdecCorrectPtsValue_Celp8(ppu_thread&, vm::ptr, vm::ptr){ UNIMPLEMENTED_FUNC(cellAdec); return CELL_OK; }
+error_code _SceAdecCorrectPtsValue_Celp(ppu_thread&, vm::ptr, vm::ptr){ UNIMPLEMENTED_FUNC(cellAdec); return CELL_OK; }
+error_code _SceAdecCorrectPtsValue_Ddp(ppu_thread&, vm::ptr, vm::ptr){ UNIMPLEMENTED_FUNC(cellAdec); return CELL_OK; }
+error_code _SceAdecCorrectPtsValue_DtsCore(ppu_thread&, vm::ptr, vm::ptr){ UNIMPLEMENTED_FUNC(cellAdec); return CELL_OK; }
+error_code _SceAdecCorrectPtsValue_DtsHd_Core(ppu_thread&, vm::ptr, vm::ptr){ UNIMPLEMENTED_FUNC(cellAdec); return CELL_OK; }
+error_code _SceAdecCorrectPtsValue_DtsHd(ppu_thread&, vm::ptr, vm::ptr){ UNIMPLEMENTED_FUNC(cellAdec); return CELL_OK; }
+error_code _SceAdecCorrectPtsValue_DtsLbr(ppu_thread&, vm::ptr, vm::ptr){ UNIMPLEMENTED_FUNC(cellAdec); return CELL_OK; }
+error_code _SceAdecCorrectPtsValue_Aac(ppu_thread&, vm::ptr, vm::ptr){ UNIMPLEMENTED_FUNC(cellAdec); return CELL_OK; }
+error_code _SceAdecCorrectPtsValue_mpmc(ppu_thread&, vm::ptr, vm::ptr){ UNIMPLEMENTED_FUNC(cellAdec); return CELL_OK; }
+error_code _SceAdecCorrectPtsValue_M4Aac(ppu_thread&, vm::ptr, vm::ptr){ UNIMPLEMENTED_FUNC(cellAdec); return CELL_OK; }
+error_code _SceAdecCorrectPtsValue_M4Aac2ch(ppu_thread&, vm::ptr, vm::ptr){ UNIMPLEMENTED_FUNC(cellAdec); return CELL_OK; }
+error_code _SceAdecCorrectPtsValue_M4Aac2chmod(ppu_thread&, vm::ptr, vm::ptr){ UNIMPLEMENTED_FUNC(cellAdec); return CELL_OK; }
+error_code _SceAdecCorrectPtsValue_Mp3s(ppu_thread&, vm::ptr, vm::ptr){ UNIMPLEMENTED_FUNC(cellAdec); return CELL_OK; }
+error_code _SceAdecCorrectPtsValue_mpmcl1(ppu_thread&, vm::ptr, vm::ptr){ UNIMPLEMENTED_FUNC(cellAdec); return CELL_OK; }
+error_code _SceAdecCorrectPtsValue_truehd(ppu_thread&, vm::ptr, vm::ptr){ UNIMPLEMENTED_FUNC(cellAdec); return CELL_OK; }
+error_code _SceAdecCorrectPtsValue_wma(ppu_thread&, vm::ptr, vm::ptr){ UNIMPLEMENTED_FUNC(cellAdec); return CELL_OK; }
+error_code _SceAdecCorrectPtsValue_WmaLsl(ppu_thread&, vm::ptr, vm::ptr){ UNIMPLEMENTED_FUNC(cellAdec); return CELL_OK; }
+error_code _SceAdecCorrectPtsValue_WmaPro(ppu_thread&, vm::ptr, vm::ptr){ UNIMPLEMENTED_FUNC(cellAdec); return CELL_OK; }
+
template <>
void fmt_class_string::format(std::string& out, u64 arg)
{
@@ -205,885 +220,946 @@ void fmt_class_string::format(std::string& out, u64 arg)
});
}
-class AudioDecoder : public ppu_thread
+
+// LPCM decoder (included in cellAdec/libadec.sprx)
+
+vm::gvar g_cell_adec_core_ops_lpcm;
+
+error_code _CellAdecCoreOpGetMemSize_lpcm(vm::ptr attr)
{
-public:
- squeue_t job;
- volatile bool is_closed = false;
- volatile bool is_finished = false;
- bool just_started = false;
- bool just_finished = false;
+ cellAdec.todo("_CellAdecCoreOpGetMemSize_lpcm(attr=*0x%x)", attr);
- const AVCodec* codec = nullptr;
-#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(59, 0, 0)
- const AVInputFormat* input_format = nullptr;
-#else
- AVInputFormat* input_format = nullptr;
-#endif
- AVCodecContext* ctx = nullptr;
- AVFormatContext* fmt = nullptr;
- u8* io_buf = nullptr;
-
- struct AudioReader
- {
- u32 addr{};
- u32 size{};
- bool init{};
- bool has_ats{};
-
- } reader;
-
- squeue_t frames;
-
- const s32 type;
- const u32 memAddr;
- const u32 memSize;
- const vm::ptr cbFunc;
- const u32 cbArg;
- u32 memBias = 0;
-
- AdecTask task;
- u64 last_pts{};
- u64 first_pts{};
-
- u32 ch_out{};
- u32 ch_cfg{};
- u32 frame_size{};
- u32 sample_rate{};
- bool use_ats_headers{};
-
- AudioDecoder(s32 type, u32 addr, u32 size, vm::ptr func, u32 arg)
- : ppu_thread({}, "", 0)
- , type(type)
- , memAddr(addr)
- , memSize(size)
- , cbFunc(func)
- , cbArg(arg)
- {
- switch (type)
- {
- case CELL_ADEC_TYPE_ATRACX:
- case CELL_ADEC_TYPE_ATRACX_2CH:
- case CELL_ADEC_TYPE_ATRACX_6CH:
- case CELL_ADEC_TYPE_ATRACX_8CH:
- {
- codec = avcodec_find_decoder(AV_CODEC_ID_ATRAC3P);
- input_format = av_find_input_format("oma");
- break;
- }
- case CELL_ADEC_TYPE_MP3:
- {
- codec = avcodec_find_decoder(AV_CODEC_ID_MP3);
- input_format = av_find_input_format("mp3");
- break;
- }
- default:
- {
- fmt::throw_exception("Unknown type (0x%x)", type);
- }
- }
-
- if (!codec)
- {
- fmt::throw_exception("avcodec_find_decoder() failed");
- }
- if (!input_format)
- {
- fmt::throw_exception("av_find_input_format() failed");
- }
- fmt = avformat_alloc_context();
- if (!fmt)
- {
- fmt::throw_exception("avformat_alloc_context() failed");
- }
- io_buf = static_cast(av_malloc(4096));
- fmt->pb = avio_alloc_context(io_buf, 256, 0, this, adecRead, nullptr, nullptr);
- if (!fmt->pb)
- {
- fmt::throw_exception("avio_alloc_context() failed");
- }
- }
-
- ~AudioDecoder()
- {
- // TODO: check finalization
- AdecFrame af;
- while (frames.try_pop(af))
- {
- av_frame_unref(af.data);
- av_frame_free(&af.data);
- }
- if (ctx)
- {
- avcodec_free_context(&ctx);
- }
- if (io_buf)
- {
- av_freep(&io_buf);
- }
- if (fmt)
- {
- if (fmt->pb) av_freep(&fmt->pb);
- avformat_close_input(&fmt);
- }
- }
-
- void non_task()
- {
- while (true)
- {
- if (Emu.IsStopped() || is_closed)
- {
- break;
- }
-
- if (!job.pop(task, &is_closed))
- {
- break;
- }
-
- switch (task.type)
- {
- case adecStartSeq:
- {
- // TODO: reset data
- cellAdec.warning("adecStartSeq:");
-
- reader.addr = 0;
- reader.size = 0;
- reader.init = false;
- reader.has_ats = false;
- just_started = true;
-
- if (adecIsAtracX(type))
- {
- ch_cfg = task.at3p.channel_config;
- ch_out = task.at3p.channels;
- frame_size = task.at3p.frame_size;
- sample_rate = task.at3p.sample_rate;
- use_ats_headers = task.at3p.ats_header == 1;
- }
- break;
- }
-
- case adecEndSeq:
- {
- // TODO: finalize
- cellAdec.warning("adecEndSeq:");
- cbFunc(*this, id, CELL_ADEC_MSG_TYPE_SEQDONE, CELL_OK, cbArg);
- lv2_obj::sleep(*this);
-
- just_finished = true;
- break;
- }
-
- case adecDecodeAu:
- {
- int err = 0;
-
- reader.addr = task.au.addr;
- reader.size = task.au.size;
- reader.has_ats = use_ats_headers;
- //cellAdec.notice("Audio AU: size = 0x%x, pts = 0x%llx", task.au.size, task.au.pts);
-
- if (just_started)
- {
- first_pts = task.au.pts;
- last_pts = task.au.pts;
- if (adecIsAtracX(type)) last_pts -= 0x10000; // hack
- }
-
- AVPacket* packet = av_packet_alloc();
- std::unique_ptr packet_(packet);
-
- if (just_started && just_finished)
- {
- avcodec_flush_buffers(ctx);
-
- reader.init = true; // wrong
- just_finished = false;
- just_started = false;
- }
- else if (just_started) // deferred initialization
- {
- AVDictionary* opts = nullptr;
- err = av_dict_set(&opts, "probesize", "96", 0);
- if (err < 0)
- {
- fmt::throw_exception("av_dict_set(probesize, 96) failed (err=0x%x='%s')", err, utils::av_error_to_string(err));
- }
- err = avformat_open_input(&fmt, nullptr, input_format, &opts);
- if (err || opts)
- {
- std::string dict_content;
- if (opts)
- {
- AVDictionaryEntry* tag = nullptr;
- while ((tag = av_dict_get(opts, "", tag, AV_DICT_IGNORE_SUFFIX)))
- {
- fmt::append(dict_content, "['%s': '%s']", tag->key, tag->value);
- }
- }
- fmt::throw_exception("avformat_open_input() failed (err=0x%x='%s', opts=%s)", err, utils::av_error_to_string(err), dict_content);
- }
- //err = avformat_find_stream_info(fmt, NULL);
- //if (err || !fmt->nb_streams)
- //{
- // fmt::throw_exception("avformat_find_stream_info() failed (err=0x%x='%s', nb_streams=%d)", err, utils::av_error_to_string(err), fmt->nb_streams);
- //}
- if (!avformat_new_stream(fmt, codec))
- {
- fmt::throw_exception("avformat_new_stream() failed");
- }
- //ctx = fmt->streams[0]->codec; // TODO: check data
-
- opts = nullptr;
-
- {
- std::lock_guard lock(g_mutex_avcodec_open2);
- // not multithread-safe (???)
- err = avcodec_open2(ctx, codec, &opts);
- }
-
- if (err || opts)
- {
- std::string dict_content;
- if (opts)
- {
- AVDictionaryEntry* tag = nullptr;
- while ((tag = av_dict_get(opts, "", tag, AV_DICT_IGNORE_SUFFIX)))
- {
- fmt::append(dict_content, "['%s': '%s']", tag->key, tag->value);
- }
- }
- fmt::throw_exception("avcodec_open2() failed (err=0x%x='%s', opts=%s)", err, utils::av_error_to_string(err), dict_content);
- }
- just_started = false;
- }
-
- while (true)
- {
- if (Emu.IsStopped() || is_closed)
- {
- if (Emu.IsStopped()) cellAdec.warning("adecDecodeAu: aborted");
- break;
- }
-
- av_read_frame(fmt, packet);
-
- struct AdecFrameHolder : AdecFrame
- {
- AdecFrameHolder()
- {
- data = av_frame_alloc();
- }
-
- ~AdecFrameHolder()
- {
- if (data)
- {
- av_frame_unref(data);
- av_frame_free(&data);
- }
- }
-
- } frame;
-
- if (!frame.data)
- {
- fmt::throw_exception("av_frame_alloc() failed");
- }
-
- int got_frame = 0;
-
- int decode = 0; //avcodec_decode_audio4(ctx, frame.data, &got_frame, &au);
-
- if (decode <= 0)
- {
- if (decode < 0)
- {
- cellAdec.error("adecDecodeAu: AU decoding error(0x%x)", decode);
- }
- if (!got_frame && reader.size == 0) break;
- }
-
- if (got_frame)
- {
- //u64 ts = av_frame_get_best_effort_timestamp(frame.data);
- //if (ts != AV_NOPTS_VALUE)
- //{
- // frame.pts = ts/* - first_pts*/;
- // last_pts = frame.pts;
- //}
- last_pts += frame.data->nb_samples * 90000ull / frame.data->sample_rate;
- frame.pts = last_pts;
-
- s32 nbps = av_get_bytes_per_sample(static_cast(frame.data->format));
- switch (frame.data->format)
- {
- case AV_SAMPLE_FMT_FLTP: break;
- case AV_SAMPLE_FMT_S16P: break;
- default:
- {
- fmt::throw_exception("Unsupported frame format(%d)", frame.data->format);
- }
- }
- frame.auAddr = task.au.addr;
- frame.auSize = task.au.size;
- frame.userdata = task.au.userdata;
- frame.size = frame.data->nb_samples * frame.data->ch_layout.nb_channels * nbps;
-
- //cellAdec.notice("got audio frame (pts=0x%llx, nb_samples=%d, ch=%d, sample_rate=%d, nbps=%d)",
- //frame.pts, frame.data->nb_samples, frame.data->ch_layout.nb_channels, frame.data->sample_rate, nbps);
-
- if (frames.push(frame, &is_closed))
- {
- frame.data = nullptr; // to prevent destruction
- cbFunc(*this, id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, cbArg);
- lv2_obj::sleep(*this);
- }
- }
- }
-
- cbFunc(*this, id, CELL_ADEC_MSG_TYPE_AUDONE, task.au.auInfo_addr, cbArg);
- lv2_obj::sleep(*this);
- break;
- }
-
- case adecClose:
- {
- break;
- }
-
- default:
- {
- fmt::throw_exception("Unknown task(%d)", +task.type);
- }
- }
- }
-
- is_finished = true;
- }
-};
-
-int adecRead(void* opaque, u8* buf, int buf_size)
-{
- AudioDecoder& adec = *static_cast(opaque);
-
- int res = 0;
-
-next:
- if (adecIsAtracX(adec.type) && adec.reader.has_ats)
- {
- u8 code1 = vm::read8(adec.reader.addr + 2);
- u8 code2 = vm::read8(adec.reader.addr + 3);
- adec.ch_cfg = (code1 >> 2) & 0x7;
- adec.frame_size = (((u32{code1} & 0x3) << 8) | code2) * 8 + 8;
- adec.sample_rate = at3freq[code1 >> 5];
-
- adec.reader.size -= 8;
- adec.reader.addr += 8;
- adec.reader.has_ats = false;
- }
-
- if (adecIsAtracX(adec.type) && !adec.reader.init)
- {
- OMAHeader oma(1 /* atrac3p id */, adec.sample_rate, adec.ch_cfg, adec.frame_size);
- if (buf_size + 0u < sizeof(oma))
- {
- cellAdec.fatal("adecRead(): OMAHeader writing failed");
- return 0;
- }
-
- memcpy(buf, &oma, sizeof(oma));
- buf += sizeof(oma);
- buf_size -= sizeof(oma);
- res += sizeof(oma);
-
- adec.reader.init = true;
- }
-
- if (adec.reader.size < static_cast(buf_size) /*&& !adec.just_started*/)
- {
- AdecTask task;
- if (!adec.job.peek(task, 0, &adec.is_closed))
- {
- if (Emu.IsStopped()) cellAdec.warning("adecRawRead() aborted");
- return 0;
- }
-
- switch (task.type)
- {
- case adecEndSeq:
- case adecClose:
- {
- buf_size = adec.reader.size;
- break;
- }
- case adecDecodeAu:
- {
- std::memcpy(buf, vm::base(adec.reader.addr), adec.reader.size);
-
- buf += adec.reader.size;
- buf_size -= adec.reader.size;
- res += adec.reader.size;
-
- adec.cbFunc(adec, adec.id, CELL_ADEC_MSG_TYPE_AUDONE, adec.task.au.auInfo_addr, adec.cbArg);
-
- adec.job.pop(adec.task);
-
- adec.reader.addr = adec.task.au.addr;
- adec.reader.size = adec.task.au.size;
- adec.reader.has_ats = adec.use_ats_headers;
- //cellAdec.notice("Audio AU: size = 0x%x, pts = 0x%llx", adec.task.au.size, adec.task.au.pts);
- break;
- }
- case adecStartSeq: // TODO ?
- default:
- {
- cellAdec.fatal("adecRawRead(): unknown task (%d)", +task.type);
- return -1;
- }
- }
-
- goto next;
- }
- else if (adec.reader.size < static_cast(buf_size) && 0)
- {
- buf_size = adec.reader.size;
- }
-
- if (!buf_size)
- {
- return res;
- }
-
- std::memcpy(buf, vm::base(adec.reader.addr), buf_size);
-
- adec.reader.addr += buf_size;
- adec.reader.size -= buf_size;
- return res + buf_size;
+ return CELL_OK;
}
-bool adecCheckType(s32 type)
+[[noreturn]] error_code _CellAdecCoreOpOpenExt_lpcm(vm::ptr handle, vm::ptr notifyAuDone, vm::ptr notifyAuDoneArg, vm::ptr notifyPcmOut, vm::ptr notifyPcmOutArg,
+ vm::ptr notifyError, vm::ptr notifyErrorArg, vm::ptr notifySeqDone, vm::ptr notifySeqDoneArg, vm::cptr res, vm::cptr spursRes)
+{
+ cellAdec.todo("_CellAdecCoreOpOpenExt_lpcm(handle=*0x%x, notifyAuDone=*0x%x, notifyAuDoneArg=0x%x, notifyPcmOut=*0x%x, notifyPcmOutArg=0x%x, notifyError=*0x%x, notifyErrorArg=0x%x, notifySeqDone=*0x%x, notifySeqDoneArg=0x%x, res=*0x%x, spursRes=*0x%x)",
+ handle, notifyAuDone, notifyAuDoneArg, notifyPcmOut, notifyPcmOutArg, notifyError, notifyErrorArg, notifySeqDone, notifySeqDoneArg, res, spursRes);
+
+ fmt::throw_exception("LPCM decoder not implemented, please disable HLE libadec.sprx");
+}
+
+[[noreturn]] error_code _CellAdecCoreOpOpen_lpcm(vm::ptr handle, vm::ptr notifyAuDone, vm::ptr notifyAuDoneArg, vm::ptr notifyPcmOut, vm::ptr notifyPcmOutArg,
+ vm::ptr notifyError, vm::ptr notifyErrorArg, vm::ptr notifySeqDone, vm::ptr notifySeqDoneArg, vm::cptr res)
+{
+ cellAdec.todo("_CellAdecCoreOpOpen_lpcm(handle=*0x%x, notifyAuDone=*0x%x, notifyAuDoneArg=*0x%x, notifyPcmOut=*0x%x, notifyPcmOutArg=*0x%x, notifyError=*0x%x, notifyErrorArg=*0x%x, notifySeqDone=*0x%x, notifySeqDoneArg=*0x%x, res=*0x%x)",
+ handle, notifyAuDone, notifyAuDoneArg, notifyPcmOut, notifyPcmOutArg, notifyError, notifyErrorArg, notifySeqDone, notifySeqDoneArg, res);
+
+ fmt::throw_exception("LPCM decoder not implemented, please disable HLE libadec.sprx");
+}
+
+error_code _CellAdecCoreOpClose_lpcm(vm::ptr handle)
+{
+ cellAdec.todo("_CellAdecCoreOpClose_lpcm(handle=*0x%x)", handle);
+
+ return CELL_OK;
+}
+
+error_code _CellAdecCoreOpStartSeq_lpcm(vm::ptr handle, vm::ptr lpcmParam)
+{
+ cellAdec.todo("_CellAdecCoreOpStartSeq_lpcm(handle=*0x%x, lpcmParam=*0x%x)", handle, lpcmParam);
+
+ return CELL_OK;
+}
+
+error_code _CellAdecCoreOpEndSeq_lpcm(vm::ptr handle)
+{
+ cellAdec.todo("_CellAdecCoreOpEndSeq_lpcm(handle=*0x%x)", handle);
+
+ return CELL_OK;
+}
+
+error_code _CellAdecCoreOpDecodeAu_lpcm(vm::ptr handle, s32 pcmHandle, vm::ptr auInfo)
+{
+ cellAdec.todo("_CellAdecCoreOpDecodeAu_lpcm(handle=*0x%x, pcmHandle=%d, auInfo=*0x%x)", handle, pcmHandle, auInfo);
+
+ return CELL_OK;
+}
+
+void _CellAdecCoreOpGetVersion_lpcm(vm::ptr> version)
+{
+ cellAdec.notice("_CellAdecCoreOpGetVersion_lpcm(version=*0x%x)", version);
+
+ *version = 0x20070323;
+}
+
+error_code _CellAdecCoreOpRealign_lpcm(vm::ptr handle, vm::ptr outBuffer, vm::cptr pcmStartAddr)
+{
+ cellAdec.todo("_CellAdecCoreOpRealign_lpcm(handle=*0x%x, outBuffer=*0x%x, pcmStartAddr=*0x%x)", handle, outBuffer, pcmStartAddr);
+
+ return CELL_OK;
+}
+
+error_code _CellAdecCoreOpReleasePcm_lpcm(vm::ptr handle, s32 pcmHandle, vm::ptr outBuffer)
+{
+ cellAdec.todo("_CellAdecCoreOpReleasePcm_lpcm(handle=*0x%x, pcmHandle=%d, outBuffer=*0x%x)", handle, pcmHandle, outBuffer);
+
+ return CELL_OK;
+}
+
+s32 _CellAdecCoreOpGetPcmHandleNum_lpcm()
+{
+ cellAdec.notice("_CellAdecCoreOpGetPcmHandleNum_lpcm()");
+
+ return 8;
+}
+
+u32 _CellAdecCoreOpGetBsiInfoSize_lpcm()
+{
+ cellAdec.notice("_CellAdecCoreOpGetBsiInfoSize_lpcm()");
+
+ return sizeof(CellAdecLpcmInfo);
+}
+
+
+// cellAdec abstraction layer, operates the individual decoders
+
+error_code AdecContext::get_new_pcm_handle(vm::ptr au_info) const
+{
+ for (s32 i = 0; i < frames_num; i++)
+ {
+ if (!frames[i].in_use)
+ {
+ frames[i].in_use = true;
+ frames[i].au_info = *au_info;
+ return not_an_error(i);
+ }
+ }
+
+ return CELL_ADEC_ERROR_BUSY;
+}
+
+error_code AdecContext::verify_pcm_handle(s32 pcm_handle) const
+{
+ ensure(pcm_handle >= 0 && pcm_handle < frames_num); // Not properly checked on LLE, see below
+
+ if ((pcm_handle < 0 && /* LLE uses && instead of || */ pcm_handle >= frames_num) || !frames[pcm_handle].in_use)
+ {
+ return CELL_ADEC_ERROR_FATAL;
+ }
+
+ return CELL_OK;
+}
+
+vm::ptr AdecContext::get_au_info(s32 pcm_handle) const
+{
+ if (verify_pcm_handle(pcm_handle) == static_cast(CELL_ADEC_ERROR_FATAL))
+ {
+ return vm::null;
+ }
+
+ return (frames + pcm_handle).ptr(&AdecFrame::au_info);
+}
+
+void AdecContext::set_state(s32 pcm_handle, u32 state) const
+{
+ if (state == 1u << 9)
+ {
+ frames[pcm_handle].au_done = true;
+ }
+ else if (state == 1u << 11)
+ {
+ frames[pcm_handle].pcm_out = true;
+ }
+}
+
+error_code AdecContext::get_pcm_item(s32 pcm_handle, vm::ptr& pcm_item) const
+{
+ if (verify_pcm_handle(pcm_handle) == static_cast(CELL_ADEC_ERROR_FATAL))
+ {
+ return CELL_ADEC_ERROR_FATAL;
+ }
+
+ pcm_item = (frames + pcm_handle).ptr(&AdecFrame::pcm_item);
+
+ return CELL_OK;
+}
+
+error_code AdecContext::set_pcm_item(s32 pcm_handle, vm::ptr pcm_addr, u32 pcm_size, vm::cpptr bitstream_info) const
+{
+ if (verify_pcm_handle(pcm_handle) == static_cast(CELL_ADEC_ERROR_FATAL))
+ {
+ return CELL_ADEC_ERROR_FATAL;
+ }
+
+ frames[pcm_handle].pcm_item.pcmHandle = pcm_handle;
+ frames[pcm_handle].pcm_item.status = CELL_OK;
+ frames[pcm_handle].pcm_item.startAddr = pcm_addr;
+ frames[pcm_handle].pcm_item.size = pcm_size;
+ frames[pcm_handle].pcm_item.auInfo = frames[pcm_handle].au_info;
+ std::memcpy(frames[pcm_handle].pcm_item.pcmAttr.bsiInfo.get_ptr(), bitstream_info->get_ptr(), bitstream_info_size);
+
+ return CELL_OK;
+}
+
+error_code AdecContext::link_frame(ppu_thread& ppu, s32 pcm_handle)
+{
+ ensure(sys_mutex_lock(ppu, mutex, 0) == CELL_OK); // Error code isn't checked on LLE
+
+ if (verify_pcm_handle(pcm_handle) == static_cast(CELL_ADEC_ERROR_FATAL))
+ {
+ ensure(sys_mutex_unlock(ppu, mutex) == CELL_OK); // Error code isn't checked on LLE
+ return CELL_ADEC_ERROR_FATAL;
+ }
+
+ if (frames_tail == -1 && frames_head == -1)
+ {
+ frames[pcm_handle].next = pcm_handle;
+ frames[pcm_handle].prev = pcm_handle;
+ frames_head = pcm_handle;
+ frames_tail = pcm_handle;
+ }
+ else if (frames_tail != -1 && frames_head != -1)
+ {
+ frames[pcm_handle].next = pcm_handle;
+ frames[pcm_handle].prev = frames_tail;
+ frames[frames_tail].next = pcm_handle;
+ frames_tail = pcm_handle;
+ }
+ else
+ {
+ ensure(sys_mutex_unlock(ppu, mutex) == CELL_OK); // Error code isn't checked on LLE
+ return CELL_ADEC_ERROR_FATAL;
+ }
+
+ ensure(sys_mutex_unlock(ppu, mutex) == CELL_OK); // Error code isn't checked on LLE
+ return CELL_OK;
+}
+
+error_code AdecContext::unlink_frame(ppu_thread& ppu, s32 pcm_handle)
+{
+ ensure(sys_mutex_lock(ppu, mutex, 0) == CELL_OK); // Error code isn't checked on LLE
+
+ if (verify_pcm_handle(pcm_handle) == static_cast(CELL_ADEC_ERROR_FATAL))
+ {
+ ensure(sys_mutex_unlock(ppu, mutex) == CELL_OK); // Error code isn't checked on LLE
+ return CELL_ADEC_ERROR_FATAL;
+ }
+
+ if (frames_head == -1 || frames_tail == -1)
+ {
+ ensure(sys_mutex_unlock(ppu, mutex) == CELL_OK); // Error code isn't checked on LLE
+ return CELL_ADEC_ERROR_FATAL;
+ }
+
+ const s32 next = frames[pcm_handle].next;
+ const s32 prev = frames[pcm_handle].prev;
+
+ if (frames_head == frames_tail)
+ {
+ if (pcm_handle != frames_tail)
+ {
+ ensure(sys_mutex_unlock(ppu, mutex) == CELL_OK); // Error code isn't checked on LLE
+ return CELL_ADEC_ERROR_FATAL;
+ }
+
+ frames_head = -1;
+ frames_tail = -1;
+ frames[pcm_handle].next = -1;
+ frames[pcm_handle].prev = -1;
+ }
+ else if (pcm_handle == frames_head)
+ {
+ frames_head = next;
+ frames[prev].next = next;
+ }
+ else if (pcm_handle == frames_tail)
+ {
+ frames_tail = prev;
+ frames[next].prev = prev;
+ }
+ else
+ {
+ frames[next].prev = prev;
+ frames[prev].next = next;
+ }
+
+ ensure(sys_mutex_unlock(ppu, mutex) == CELL_OK); // Error code isn't checked on LLE
+ return CELL_OK;
+}
+
+void AdecContext::reset_frame(s32 pcm_handle) const
+{
+ frames[pcm_handle].in_use = false;
+ frames[pcm_handle].au_done = false;
+ frames[pcm_handle].pcm_out = false;
+ frames[pcm_handle].next = -1;
+ frames[pcm_handle].prev = -1;
+}
+
+error_code AdecContext::correct_pts_value(ppu_thread& ppu, s32 pcm_handle, s8 correct_pts_type)
+{
+ if (verify_pcm_handle(pcm_handle) == static_cast(CELL_ADEC_ERROR_FATAL))
+ {
+ return CELL_ADEC_ERROR_FATAL;
+ }
+
+ const vm::ptr au_pts = (frames + pcm_handle).ptr(&AdecFrame::au_info).ptr(&CellAdecAuInfo::pts);
+
+ switch (correct_pts_type)
+ {
+ case ADEC_CORRECT_PTS_VALUE_TYPE_EAC3: return ppu_execute<&_SceAdecCorrectPtsValue_Ddp>(ppu, +core_handle, au_pts) != CELL_OK ? static_cast(CELL_ADEC_ERROR_FATAL) : static_cast(CELL_OK);
+ case ADEC_CORRECT_PTS_VALUE_TYPE_DTSHD: return ppu_execute<&_SceAdecCorrectPtsValue_DtsHd>(ppu, +core_handle, au_pts) != CELL_OK ? static_cast(CELL_ADEC_ERROR_FATAL) : static_cast(CELL_OK);
+ case ADEC_CORRECT_PTS_VALUE_TYPE_CELP: return ppu_execute<&_SceAdecCorrectPtsValue_Celp>(ppu, +core_handle, au_pts) != CELL_OK ? static_cast(CELL_ADEC_ERROR_FATAL) : static_cast(CELL_OK);
+ case ADEC_CORRECT_PTS_VALUE_TYPE_M2AAC: return ppu_execute<&_SceAdecCorrectPtsValue_Aac>(ppu, +core_handle, au_pts) != CELL_OK ? static_cast(CELL_ADEC_ERROR_FATAL) : static_cast(CELL_OK);
+ case ADEC_CORRECT_PTS_VALUE_TYPE_MPEG_L2: return ppu_execute<&_SceAdecCorrectPtsValue_mpmc>(ppu, +core_handle, au_pts) != CELL_OK ? static_cast(CELL_ADEC_ERROR_FATAL) : static_cast(CELL_OK);
+ case ADEC_CORRECT_PTS_VALUE_TYPE_TRUEHD: return ppu_execute<&_SceAdecCorrectPtsValue_truehd>(ppu, +core_handle, au_pts) != CELL_OK ? static_cast(CELL_ADEC_ERROR_FATAL) : static_cast(CELL_OK);
+ case ADEC_CORRECT_PTS_VALUE_TYPE_DTS: return ppu_execute<&_SceAdecCorrectPtsValue_DtsCore>(ppu, +core_handle, au_pts) != CELL_OK ? static_cast(CELL_ADEC_ERROR_FATAL) : static_cast(CELL_OK);
+ case ADEC_CORRECT_PTS_VALUE_TYPE_M4AAC:
+ switch (type.audioCodecType)
+ {
+ case CELL_ADEC_TYPE_M4AAC: return ppu_execute<&_SceAdecCorrectPtsValue_M4Aac>(ppu, +core_handle, au_pts) != CELL_OK ? static_cast(CELL_ADEC_ERROR_FATAL) : static_cast(CELL_OK);
+ case CELL_ADEC_TYPE_M4AAC_2CH: return ppu_execute<&_SceAdecCorrectPtsValue_M4Aac2ch>(ppu, +core_handle, au_pts) != CELL_OK ? static_cast(CELL_ADEC_ERROR_FATAL) : static_cast(CELL_OK);
+ case CELL_ADEC_TYPE_M4AAC_2CH_MOD: return ppu_execute<&_SceAdecCorrectPtsValue_M4Aac2chmod>(ppu, +core_handle, au_pts) != CELL_OK ? static_cast(CELL_ADEC_ERROR_FATAL) : static_cast(CELL_OK);
+ default: return CELL_OK;
+ }
+
+ case ADEC_CORRECT_PTS_VALUE_TYPE_WMA: return ppu_execute<&_SceAdecCorrectPtsValue_wma>(ppu, +core_handle, au_pts) != CELL_OK ? static_cast(CELL_ADEC_ERROR_FATAL) : static_cast(CELL_OK);
+ case ADEC_CORRECT_PTS_VALUE_TYPE_DTSLBR: return ppu_execute<&_SceAdecCorrectPtsValue_DtsLbr>(ppu, +core_handle, au_pts) != CELL_OK ? static_cast(CELL_ADEC_ERROR_FATAL) : static_cast(CELL_OK);
+ case ADEC_CORRECT_PTS_VALUE_TYPE_MPEG_L1: return ppu_execute<&_SceAdecCorrectPtsValue_mpmcl1>(ppu, +core_handle, au_pts) != CELL_OK ? static_cast(CELL_ADEC_ERROR_FATAL) : static_cast(CELL_OK);
+ case ADEC_CORRECT_PTS_VALUE_TYPE_MP3S: return ppu_execute<&_SceAdecCorrectPtsValue_Mp3s>(ppu, +core_handle, au_pts) != CELL_OK ? static_cast(CELL_ADEC_ERROR_FATAL) : static_cast(CELL_OK);
+ case ADEC_CORRECT_PTS_VALUE_TYPE_CELP8: return ppu_execute<&_SceAdecCorrectPtsValue_Celp8>(ppu, +core_handle, au_pts) != CELL_OK ? static_cast(CELL_ADEC_ERROR_FATAL) : static_cast(CELL_OK);
+ case ADEC_CORRECT_PTS_VALUE_TYPE_WMAPRO: return ppu_execute<&_SceAdecCorrectPtsValue_WmaPro>(ppu, +core_handle, au_pts) != CELL_OK ? static_cast(CELL_ADEC_ERROR_FATAL) : static_cast(CELL_OK);
+ case ADEC_CORRECT_PTS_VALUE_TYPE_WMALSL: return ppu_execute<&_SceAdecCorrectPtsValue_WmaLsl>(ppu, +core_handle, au_pts) != CELL_OK ? static_cast(CELL_ADEC_ERROR_FATAL) : static_cast(CELL_OK);
+ case ADEC_CORRECT_PTS_VALUE_TYPE_DTSHDCORE_UNK1: // Same as below
+ case ADEC_CORRECT_PTS_VALUE_TYPE_DTSHDCORE_UNK2: return ppu_execute<&_SceAdecCorrectPtsValue_DtsHd_Core>(ppu, +core_handle, au_pts) != CELL_OK ? static_cast(CELL_ADEC_ERROR_FATAL) : static_cast(CELL_OK);
+ }
+
+ // If the user didn't set a PTS, we need to interpolate from the previous PTS
+ if (au_pts->upper == CODEC_TS_INVALID)
+ {
+ if (au_pts->lower != CODEC_TS_INVALID)
+ {
+ return CELL_ADEC_ERROR_FATAL;
+ }
+
+ if (previous_pts.upper == CODEC_TS_INVALID && previous_pts.lower == CODEC_TS_INVALID)
+ {
+ return CELL_OK;
+ }
+
+ const u32 pts_adjust = [&]
+ {
+ switch (correct_pts_type)
+ {
+ case ADEC_CORRECT_PTS_VALUE_TYPE_LPCM: return 450;
+ case 1: return 150;
+ case ADEC_CORRECT_PTS_VALUE_TYPE_ATRACX_48000Hz: return 3840;
+ case ADEC_CORRECT_PTS_VALUE_TYPE_ATRACX_44100Hz: return 4180;
+ case ADEC_CORRECT_PTS_VALUE_TYPE_ATRACX_32000Hz: return 5760;
+ case ADEC_CORRECT_PTS_VALUE_TYPE_AC3: return 2880;
+ case ADEC_CORRECT_PTS_VALUE_TYPE_ATRAC3: return 4180;
+ case ADEC_CORRECT_PTS_VALUE_TYPE_MP3_48000Hz: return 2160;
+ case ADEC_CORRECT_PTS_VALUE_TYPE_MP3_44100Hz: return 2351;
+ case ADEC_CORRECT_PTS_VALUE_TYPE_MP3_32000Hz: return 3240;
+ case ADEC_CORRECT_PTS_VALUE_TYPE_ATRAC3MULTI: return 3840;
+ default: return 0;
+ }
+ }();
+
+ au_pts->upper = previous_pts.upper;
+ au_pts->lower = previous_pts.lower + pts_adjust;
+
+ if (au_pts->lower < previous_pts.lower) // overflow
+ {
+ au_pts->upper = (au_pts->upper + 1) & 1;
+ }
+
+ if (au_pts->upper == CODEC_TS_INVALID)
+ {
+ return CELL_ADEC_ERROR_FATAL;
+ }
+ }
+
+ if (au_pts->lower == CODEC_TS_INVALID)
+ {
+ return CELL_ADEC_ERROR_FATAL;
+ }
+
+ previous_pts = *au_pts;
+
+ return CELL_OK;
+}
+
+static vm::cptr get_core_ops(s32 type)
{
switch (type)
{
- case CELL_ADEC_TYPE_ATRACX: cellAdec.notice("adecCheckType(): ATRAC3plus"); break;
- case CELL_ADEC_TYPE_ATRACX_2CH: cellAdec.notice("adecCheckType(): ATRAC3plus 2ch"); break;
- case CELL_ADEC_TYPE_ATRACX_6CH: cellAdec.notice("adecCheckType(): ATRAC3plus 6ch"); break;
- case CELL_ADEC_TYPE_ATRACX_8CH: cellAdec.notice("adecCheckType(): ATRAC3plus 8ch"); break;
- case CELL_ADEC_TYPE_MP3: cellAdec.notice("adecCheckType(): MP3"); break;
-
- case CELL_ADEC_TYPE_LPCM_PAMF:
- case CELL_ADEC_TYPE_AC3:
- case CELL_ADEC_TYPE_ATRAC3:
- case CELL_ADEC_TYPE_MPEG_L2:
- case CELL_ADEC_TYPE_CELP:
- case CELL_ADEC_TYPE_M4AAC:
- case CELL_ADEC_TYPE_CELP8:
- {
- cellAdec.fatal("Unimplemented audio codec type (%d)", type);
- break;
+ case CELL_ADEC_TYPE_INVALID1: fmt::throw_exception("Invalid audio codec: CELL_ADEC_TYPE_INVALID1");
+ case CELL_ADEC_TYPE_LPCM_PAMF: return g_cell_adec_core_ops_lpcm;
+ case CELL_ADEC_TYPE_AC3: return vm::cptr::make(*ppu_module_manager::cell_libac3dec.variables.find(0xc58bb170)->second.export_addr);
+ case CELL_ADEC_TYPE_ATRACX: return vm::cptr::make(*ppu_module_manager::cellAtracXdec.variables.find(0x4944af9a)->second.export_addr);
+ case CELL_ADEC_TYPE_MP3: return vm::cptr::make(*ppu_module_manager::cellMP3dec.variables.find(0x84276a23)->second.export_addr);
+ case CELL_ADEC_TYPE_ATRAC3: return vm::cptr::make(*ppu_module_manager::cellAtrac3dec.variables.find(0x60487d65)->second.export_addr);
+ case CELL_ADEC_TYPE_MPEG_L2: return vm::cptr::make(*ppu_module_manager::cellM2BCdec.variables.find(0x300afe4d)->second.export_addr);
+ case CELL_ADEC_TYPE_M2AAC: return vm::cptr::make(*ppu_module_manager::cellM2AACdec.variables.find(0xac2f0831)->second.export_addr);
+ case CELL_ADEC_TYPE_EAC3: return vm::cptr::make(*ppu_module_manager::cellDDPdec.variables.find(0xf5e9c15c)->second.export_addr);
+ case CELL_ADEC_TYPE_TRUEHD: return vm::cptr::make(*ppu_module_manager::cellTRHDdec.variables.find(0xe88e381b)->second.export_addr);
+ case CELL_ADEC_TYPE_DTS: return vm::cptr::make(*ppu_module_manager::cellDTSdec.variables.find(0x15248ec5)->second.export_addr);
+ case CELL_ADEC_TYPE_CELP: return vm::cptr::make(*ppu_module_manager::cellCelpDec.variables.find(0xffe42c22)->second.export_addr);
+ case CELL_ADEC_TYPE_LPCM_BLURAY: return g_cell_adec_core_ops_lpcm;
+ case CELL_ADEC_TYPE_ATRACX_2CH: return vm::cptr::make(*ppu_module_manager::cellAtracXdec.variables.find(0x076b33ab)->second.export_addr);
+ case CELL_ADEC_TYPE_ATRACX_6CH: return vm::cptr::make(*ppu_module_manager::cellAtracXdec.variables.find(0x1d210eaa)->second.export_addr);
+ case CELL_ADEC_TYPE_ATRACX_8CH: return vm::cptr::make(*ppu_module_manager::cellAtracXdec.variables.find(0xe9a86e54)->second.export_addr);
+ case CELL_ADEC_TYPE_M4AAC: return vm::cptr::make(*ppu_module_manager::cellM4AacDec.variables.find(0xab61278d)->second.export_addr);
+ case CELL_ADEC_TYPE_LPCM_DVD: return g_cell_adec_core_ops_lpcm;
+ case CELL_ADEC_TYPE_WMA: return vm::cptr::make(*ppu_module_manager::cellWMAdec.variables.find(0x88320b10)->second.export_addr);
+ case CELL_ADEC_TYPE_DTSLBR: return vm::cptr::make(*ppu_module_manager::cellDTSLBRdec.variables.find(0x8c50af52)->second.export_addr);
+ case CELL_ADEC_TYPE_M4AAC_2CH: return vm::cptr::make(*ppu_module_manager::cellM4AacDec2ch.variables.find(0xe996c664)->second.export_addr);
+ case CELL_ADEC_TYPE_DTSHD: return vm::cptr::make(*ppu_module_manager::cellDTSHDdec.variables.find(0x51ac2b6c)->second.export_addr);
+ case CELL_ADEC_TYPE_MPEG_L1: return vm::cptr::make(*ppu_module_manager::cellMPL1dec.variables.find(0xbbc70551)->second.export_addr);
+ case CELL_ADEC_TYPE_MP3S: return vm::cptr::make(*ppu_module_manager::cellMP3Sdec.variables.find(0x292cdf0a)->second.export_addr);
+ case CELL_ADEC_TYPE_M4AAC_2CH_MOD: return vm::cptr::make(*ppu_module_manager::cellM4AacDec2chmod.variables.find(0xdbd26836)->second.export_addr);
+ case CELL_ADEC_TYPE_CELP8: return vm::cptr::make(*ppu_module_manager::cellCelp8Dec.variables.find(0xf0190c6c)->second.export_addr);
+ case CELL_ADEC_TYPE_INVALID2: fmt::throw_exception("Invalid audio codec: CELL_ADEC_TYPE_INVALID2");
+ case CELL_ADEC_TYPE_INVALID3: fmt::throw_exception("Invalid audio codec: CELL_ADEC_TYPE_INVALID3");
+ case CELL_ADEC_TYPE_RESERVED22: fmt::throw_exception("Invalid audio codec: CELL_ADEC_TYPE_RESERVED22");
+ case CELL_ADEC_TYPE_RESERVED23: fmt::throw_exception("Invalid audio codec: CELL_ADEC_TYPE_RESERVED23");
+ case CELL_ADEC_TYPE_DTSHDCORE: return vm::cptr::make(*ppu_module_manager::cellDTSHDCOREdec.variables.find(0x6c8f4f1c)->second.export_addr);
+ case CELL_ADEC_TYPE_ATRAC3MULTI: return vm::cptr::make(*ppu_module_manager::cellAtrac3multidec.variables.find(0xc20c6bd7)->second.export_addr);
+ default: fmt::throw_exception("Invalid audio codec: %d", type);
}
- default: return false;
- }
-
- return true;
}
-error_code cellAdecQueryAttr(vm::ptr type, vm::ptr attr)
+error_code adecNotifyAuDone(ppu_thread& ppu, s32 pcmHandle, vm::ptr handle)
{
- cellAdec.warning("cellAdecQueryAttr(type=*0x%x, attr=*0x%x)", type, attr);
+ // Block savestate creation during callbacks
+ std::unique_lock savestate_lock{g_fxo->get(), std::try_to_lock};
- if (!adecCheckType(type->audioCodecType))
+ if (!savestate_lock.owns_lock())
{
- return CELL_ADEC_ERROR_ARG;
+ ppu.state += cpu_flag::again;
+ return {};
}
- // TODO: check values
- attr->adecVerLower = 0x280000; // from dmux
- attr->adecVerUpper = 0x260000;
- attr->workMemSize = 256 * 1024; // 256 KB
+ cellAdec.trace("adecNotifyAuDone(pcmHandle=%d, handle=*0x%x)", pcmHandle, handle);
+
+ ensure(!!handle); // Not checked on LLE
+
+ const auto au_info = handle->get_au_info(pcmHandle);
+
+ if (!au_info)
+ {
+ return CELL_ADEC_ERROR_FATAL;
+ }
+
+ handle->set_state(pcmHandle, 1u << 9);
+
+ handle->callback.cbFunc(ppu, handle, CELL_ADEC_MSG_TYPE_AUDONE, static_cast(au_info.addr()), handle->callback.cbArg);
return CELL_OK;
}
-error_code cellAdecOpen(vm::ptr type, vm::ptr res, vm::ptr cb, vm::ptr handle)
+error_code adecNotifyPcmOut(ppu_thread& ppu, s32 pcmHandle, vm::ptr pcmAddr, u32 pcmSize, vm::ptr handle, vm::cpptr bsiInfo, s8 correctPtsValueType, s32 errorCode)
{
- cellAdec.warning("cellAdecOpen(type=*0x%x, res=*0x%x, cb=*0x%x, handle=*0x%x)", type, res, cb, handle);
+ // Block savestate creation during callbacks
+ std::unique_lock savestate_lock{g_fxo->get(), std::try_to_lock};
- if (!adecCheckType(type->audioCodecType))
+ if (!savestate_lock.owns_lock())
{
- return CELL_ADEC_ERROR_ARG;
+ ppu.state += cpu_flag::again;
+ return {};
}
- fmt::throw_exception("cellAdec disabled, use LLE.");
-}
+ cellAdec.trace("adecNotifyPcmOut(pcmHandle=%d, pcmAddr=*0x%x, pcmSize=0x%x, handle=*0x%x, bsiInfo=**0x%x, correctPtsValueType=%d, errorCode=0x%x)", pcmHandle, pcmAddr, pcmSize, handle, bsiInfo, correctPtsValueType, errorCode);
-error_code cellAdecOpenEx(vm::ptr type, vm::ptr res, vm::ptr cb, vm::ptr handle)
-{
- cellAdec.warning("cellAdecOpenEx(type=*0x%x, res=*0x%x, cb=*0x%x, handle=*0x%x)", type, res, cb, handle);
+ ensure(!!handle && !!bsiInfo && !!*bsiInfo); // Not checked on LLE
- if (!adecCheckType(type->audioCodecType))
+ if (!handle->get_au_info(pcmHandle))
{
- return CELL_ADEC_ERROR_ARG;
+ return CELL_ADEC_ERROR_FATAL;
}
- fmt::throw_exception("cellAdec disabled, use LLE.");
-}
-
-error_code cellAdecOpenExt(vm::ptr type, vm::ptr res, vm::ptr cb, vm::ptr handle)
-{
- cellAdec.warning("cellAdecOpenExt(type=*0x%x, res=*0x%x, cb=*0x%x, handle=*0x%x)", type, res, cb, handle);
-
- return cellAdecOpenEx(type, res, cb, handle);
-}
-
-error_code cellAdecClose(u32 handle)
-{
- cellAdec.warning("cellAdecClose(handle=0x%x)", handle);
-
- const auto adec = idm::get(handle);
-
- if (!adec)
+ if (error_code ret = handle->correct_pts_value(ppu, pcmHandle, correctPtsValueType); ret != CELL_OK)
{
- return CELL_ADEC_ERROR_ARG;
+ return ret;
}
- adec->is_closed = true;
- adec->job.try_push(AdecTask(adecClose));
-
- while (!adec->is_finished)
+ if (handle->link_frame(ppu, pcmHandle) == static_cast(CELL_ADEC_ERROR_FATAL))
{
- thread_ctrl::wait_for(1000); // hack
+ return CELL_ADEC_ERROR_FATAL;
}
- if (!idm::remove_verify(handle, std::move(adec)))
+ handle->set_state(pcmHandle, 1u << 11);
+
+ if (handle->set_pcm_item(pcmHandle, pcmAddr, pcmSize, bsiInfo) == static_cast(CELL_ADEC_ERROR_FATAL))
{
- // Removed by other thread beforehead
- return CELL_ADEC_ERROR_ARG;
+ return CELL_ADEC_ERROR_FATAL;
}
+ vm::ptr pcm_item{};
+
+ if (handle->get_pcm_item(pcmHandle, pcm_item) == static_cast(CELL_ADEC_ERROR_FATAL))
+ {
+ return CELL_ADEC_ERROR_FATAL;
+ }
+
+ if (handle->pcm_queue.push(ppu, pcm_item, pcmHandle) != CELL_OK)
+ {
+ return CELL_ADEC_ERROR_FATAL;
+ }
+
+ if (handle->pcm_item_queue.push(ppu, pcm_item, pcmHandle) != CELL_OK)
+ {
+ return CELL_ADEC_ERROR_FATAL;
+ }
+
+ handle->callback.cbFunc(ppu, handle, CELL_ADEC_MSG_TYPE_PCMOUT, errorCode, handle->callback.cbArg);
+
return CELL_OK;
}
-error_code cellAdecStartSeq(u32 handle, u32 param)
+error_code adecNotifyError(ppu_thread& ppu, s32 errorCode, vm::ptr handle)
{
- cellAdec.warning("cellAdecStartSeq(handle=0x%x, param=*0x%x)", handle, param);
+ // Block savestate creation during callbacks
+ std::unique_lock savestate_lock{g_fxo->get(), std::try_to_lock};
- const auto adec = idm::get(handle);
+ if (!savestate_lock.owns_lock())
+ {
+ ppu.state += cpu_flag::again;
+ return {};
+ }
- if (!adec)
+ cellAdec.error("adecNotifyError(errorCode=0x%x, handle=*0x%x)", errorCode, handle);
+
+ ensure(!!handle); // Not checked on LLE
+
+ handle->callback.cbFunc(ppu, handle, CELL_ADEC_MSG_TYPE_ERROR, errorCode, handle->callback.cbArg);
+
+ return CELL_OK;
+}
+
+error_code adecNotifySeqDone(ppu_thread& ppu, vm::ptr handle)
+{
+ // Block savestate creation during callbacks
+ std::unique_lock savestate_lock{g_fxo->get(), std::try_to_lock};
+
+ if (!savestate_lock.owns_lock())
+ {
+ ppu.state += cpu_flag::again;
+ return {};
+ }
+
+ cellAdec.notice("adecNotifySeqDone(handle=*0x%x)", handle);
+
+ ensure(!!handle); // Not checked on LLE
+
+ handle->callback.cbFunc(ppu, handle, CELL_ADEC_MSG_TYPE_SEQDONE, CELL_OK, handle->callback.cbArg);
+
+ return CELL_OK;
+}
+
+error_code cellAdecQueryAttr(ppu_thread& ppu, vm::ptr type, vm::ptr attr)
+{
+ // Block savestate creation during ppu_thread::fast_call()
+ std::unique_lock savestate_lock{g_fxo->get(), std::try_to_lock};
+
+ if (!savestate_lock.owns_lock())
+ {
+ ppu.state += cpu_flag::again;
+ return {};
+ }
+
+ cellAdec.notice("cellAdecQueryAttr(type=*0x%x, attr=*0x%x)", type, attr);
+
+ if (!type || type->audioCodecType >= 32 || type->audioCodecType == CELL_ADEC_TYPE_INVALID1 || type->audioCodecType == CELL_ADEC_TYPE_INVALID2 || type->audioCodecType == CELL_ADEC_TYPE_INVALID3 || !attr)
{
return CELL_ADEC_ERROR_ARG;
}
- AdecTask task(adecStartSeq);
+ const auto core_ops = get_core_ops(type->audioCodecType);
- switch (adec->type)
- {
- case CELL_ADEC_TYPE_ATRACX:
- case CELL_ADEC_TYPE_ATRACX_2CH:
- case CELL_ADEC_TYPE_ATRACX_6CH:
- case CELL_ADEC_TYPE_ATRACX_8CH:
- {
- const auto atx = vm::cptr::make(param);
+ core_ops->getMemSize(ppu, attr);
- task.at3p.sample_rate = atx->sampling_freq;
- task.at3p.channel_config = atx->ch_config_idx;
- task.at3p.channels = atx->nch_out;
- task.at3p.frame_size = atx->nbytes;
- task.at3p.extra_config = atx->extra_config_data;
- task.at3p.output = atx->bw_pcm;
- task.at3p.downmix = atx->downmix_flag;
- task.at3p.ats_header = atx->au_includes_ats_hdr_flg;
- cellAdec.todo("*** CellAdecParamAtracX: sr=%d, ch_cfg=%d(%d), frame_size=0x%x, extra=%u:%u:%u:%u, output=%d, downmix=%d, ats_header=%d",
- task.at3p.sample_rate, task.at3p.channel_config, task.at3p.channels, task.at3p.frame_size,
- task.at3p.extra_config[0], task.at3p.extra_config[1], task.at3p.extra_config[2], task.at3p.extra_config[3],
- task.at3p.output, task.at3p.downmix, task.at3p.ats_header);
- break;
- }
- case CELL_ADEC_TYPE_MP3:
- {
- const auto mp3 = vm::cptr::make(param);
+ const s32 pcm_handle_num = core_ops->getPcmHandleNum(ppu);
+ const u32 bitstream_info_size = core_ops->getBsiInfoSize(ppu);
+ attr->workMemSize += static_cast((bitstream_info_size + sizeof(AdecFrame)) * pcm_handle_num + sizeof(AdecContext) + 0x7f);
- cellAdec.todo("*** CellAdecParamMP3: bw_pcm=%d", mp3->bw_pcm);
- break;
- }
- default:
- {
- cellAdec.fatal("cellAdecStartSeq(): Unimplemented audio codec type(%d)", adec->type);
- return CELL_OK;
- }
- }
+ const vm::var> ver_lower;
+ core_ops->getVersion(ppu, ver_lower);
+
+ attr->adecVerUpper = 0x491000;
+ attr->adecVerLower = *ver_lower;
- adec->job.push(task, &adec->is_closed);
return CELL_OK;
}
-error_code cellAdecEndSeq(u32 handle)
+error_code adecOpen(ppu_thread& ppu, vm::ptr type, vm::cptr res, vm::cptr cb, vm::pptr handle, vm::cptr spursRes)
{
- cellAdec.warning("cellAdecEndSeq(handle=0x%x)", handle);
-
- const auto adec = idm::get(handle);
-
- if (!adec)
+ if (!type || type->audioCodecType >= 32 || !res || !res->startAddr || res->ppuThreadPriority >= 0xa00 || res->spuThreadPriority >= 0x100 || res->ppuThreadStackSize < 0x1000 || !cb || !cb->cbFunc || !handle)
{
return CELL_ADEC_ERROR_ARG;
}
- adec->job.push(AdecTask(adecEndSeq), &adec->is_closed);
- return CELL_OK;
+ if (vm::var attr; cellAdecQueryAttr(ppu, type, attr), res->totalMemSize < attr->workMemSize)
+ {
+ return CELL_ADEC_ERROR_FATAL;
+ }
+
+ const auto core_ops = get_core_ops(type->audioCodecType);
+
+ const s32 pcm_handle_num = core_ops->getPcmHandleNum(ppu);
+ const u32 bitstream_info_size = core_ops->getBsiInfoSize(ppu);
+
+ const auto _this = vm::ptr::make(utils::align(+res->startAddr, 0x80));
+ const auto frames = vm::ptr::make(_this.addr() + sizeof(AdecContext));
+ const u32 bitstream_infos_addr = frames.addr() + pcm_handle_num * sizeof(AdecFrame);
+ const auto core_handle = vm::ptr::make(utils::align(bitstream_infos_addr + bitstream_info_size * pcm_handle_num, 0x80));
+
+ if (type->audioCodecType == CELL_ADEC_TYPE_LPCM_DVD)
+ {
+ // TODO
+ }
+ else if (type->audioCodecType == CELL_ADEC_TYPE_LPCM_PAMF || type->audioCodecType == CELL_ADEC_TYPE_LPCM_BLURAY)
+ {
+ // TODO
+ }
+
+ _this->_this = _this;
+ _this->this_size = sizeof(AdecContext) + (bitstream_info_size + sizeof(AdecFrame)) * pcm_handle_num;
+ _this->unk = 0;
+ _this->sequence_state = AdecSequenceState::dormant;
+ _this->type = *type;
+ _this->res = *res;
+ _this->callback = *cb;
+ _this->core_handle = core_handle;
+ _this->core_ops = core_ops;
+ _this->previous_pts = { CODEC_TS_INVALID, CODEC_TS_INVALID };
+ _this->frames_num = pcm_handle_num;
+ _this->reserved1 = 0;
+ _this->frames_head = -1;
+ _this->frames_tail = -1;
+ _this->frames = frames;
+ _this->bitstream_info_size = bitstream_info_size;
+ _this->mutex_attribute = { SYS_SYNC_PRIORITY, SYS_SYNC_NOT_RECURSIVE, SYS_SYNC_NOT_PROCESS_SHARED, SYS_SYNC_NOT_ADAPTIVE, 0, 0, 0, { "_adem03"_u64 } };
+
+ _this->pcm_queue.init(ppu, _this.ptr(&AdecContext::pcm_queue));
+ _this->pcm_item_queue.init(ppu, _this.ptr(&AdecContext::pcm_item_queue));
+
+ for (s32 i = 0; i < pcm_handle_num; i++)
+ {
+ frames[i].in_use = false;
+ frames[i].this_index = i;
+ frames[i].au_done = false;
+ frames[i].unk1 = false;
+ frames[i].pcm_out = false;
+ frames[i].unk2 = false;
+ frames[i].pcm_item.pcmAttr.bsiInfo.set(bitstream_infos_addr + bitstream_info_size * i);
+ frames[i].reserved1 = 0;
+ frames[i].reserved2 = 0;
+ frames[i].next = 0;
+ frames[i].prev = 0;
+ }
+
+ ensure(sys_mutex_create(ppu, _this.ptr(&AdecContext::mutex), _this.ptr(&AdecContext::mutex_attribute)) == CELL_OK); // Error code isn't checked on LLE
+
+ *handle = _this;
+
+ const auto notifyAuDone = vm::ptr::make(g_fxo->get().func_addr(FIND_FUNC(adecNotifyAuDone)));
+ const auto notifyPcmOut = vm::ptr::make(g_fxo->get().func_addr(FIND_FUNC(adecNotifyPcmOut)));
+ const auto notifyError = vm::ptr::make(g_fxo->get().func_addr(FIND_FUNC(adecNotifyError)));
+ const auto notifySeqDone = vm::ptr::make(g_fxo->get().func_addr(FIND_FUNC(adecNotifySeqDone)));
+
+ // Block savestate creation during ppu_thread::fast_call()
+ std::unique_lock savestate_lock{g_fxo->get(), std::try_to_lock};
+
+ if (!savestate_lock.owns_lock())
+ {
+ ppu.state += cpu_flag::again;
+ return {};
+ }
+
+ if (spursRes)
+ {
+ return core_ops->openExt(ppu, _this->core_handle, notifyAuDone, _this, notifyPcmOut, _this, notifyError, _this, notifySeqDone, _this, res, spursRes);
+ }
+
+ return core_ops->open(ppu, _this->core_handle, notifyAuDone, _this, notifyPcmOut, _this, notifyError, _this, notifySeqDone, _this, res);
}
-error_code cellAdecDecodeAu(u32 handle, vm::ptr auInfo)
+error_code cellAdecOpen(ppu_thread& ppu, vm::ptr type, vm::ptr res, vm::ptr cb, vm::pptr handle)
{
- cellAdec.trace("cellAdecDecodeAu(handle=0x%x, auInfo=*0x%x)", handle, auInfo);
+ cellAdec.notice("cellAdecOpen(type=*0x%x, res=*0x%x, cb=*0x%x, handle=*0x%x)", type, res, cb, handle);
- const auto adec = idm::get(handle);
+ return adecOpen(ppu, type, res, cb, handle, vm::null);
+}
- if (!adec)
+error_code cellAdecOpenExt(ppu_thread& ppu, vm::ptr type, vm::ptr res, vm::ptr cb, vm::pptr handle)
+{
+ cellAdec.notice("cellAdecOpenExt(type=*0x%x, res=*0x%x, cb=*0x%x, handle=*0x%x)", type, res, cb, handle);
+
+ if (!res)
{
return CELL_ADEC_ERROR_ARG;
}
- AdecTask task(adecDecodeAu);
- task.au.auInfo_addr = auInfo.addr();
- task.au.addr = auInfo->startAddr.addr();
- task.au.size = auInfo->size;
- task.au.pts = (u64{auInfo->pts.upper} << 32) | u64{auInfo->pts.lower};
- task.au.userdata = auInfo->userData;
+ const vm::var _res{{ res->totalMemSize, res->startAddr, res->ppuThreadPriority, 0, res->ppuThreadStackSize }};
+ const vm::var spursRes{{ res->spurs_addr, res->priority, res->maxContention }};
+
+ return adecOpen(ppu, type, _res, cb, handle, spursRes);
+}
+
+error_code cellAdecOpenEx(ppu_thread& ppu, vm::ptr type, vm::ptr