mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-09-05 01:26:17 -04:00
Use aurora::thp; remove libjpeg-turbo (#2386)
This commit is contained in:
+2
-74
@@ -72,6 +72,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL Linux)
|
||||
endif ()
|
||||
set(AURORA_ENABLE_DVD ON CACHE BOOL "Enable DVD API support" FORCE)
|
||||
set(AURORA_ENABLE_CARD ON CACHE BOOL "Enable CARD API support" FORCE)
|
||||
set(AURORA_ENABLE_THP ON CACHE BOOL "Enable THP decoder" FORCE)
|
||||
set(AURORA_ENABLE_RMLUI ON CACHE BOOL "Enable RmlUi UI support" FORCE)
|
||||
add_subdirectory(extern/aurora EXCLUDE_FROM_ALL)
|
||||
target_compile_definitions(aurora_mtx PRIVATE MTX_USE_PS=1)
|
||||
@@ -88,7 +89,6 @@ endif ()
|
||||
|
||||
option(DUSK_BUILD_WARNINGS "Enable compiler warnings (off by default)")
|
||||
option(DUSK_SELECTED_OPT "If on, selected parts of the project will be compiled with optimizations on Debug, intending to make the game run at 30 FPS. Note for MSVC: you will need to remove '/RTC1' from your debug flags in CMake.")
|
||||
option(DUSK_MOVIE_SUPPORT "If on, compile against libjpeg-turbo to enable THP file decoding" ON)
|
||||
option(DUSK_PACKAGE_INSTALL "Install Dusklight with a Linux-native file structure" OFF)
|
||||
option(DUSK_GFX_DEBUG_GROUPS "Report debug groups to the native graphics API" ${DUSK_GFX_DEBUG_GROUPS_DEFAULT})
|
||||
option(DUSK_ENABLE_CODE_MODS "Enable code mods" ON)
|
||||
@@ -133,69 +133,6 @@ if (MSVC)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (DUSK_MOVIE_SUPPORT)
|
||||
find_package(libjpeg-turbo 3.0 CONFIG QUIET)
|
||||
if (libjpeg-turbo_FOUND)
|
||||
message(STATUS "dusklight: Using system libjpeg-turbo")
|
||||
else ()
|
||||
message(STATUS "dusklight: Fetching libjpeg-turbo")
|
||||
include(ExternalProject)
|
||||
set(_jpeg_install_dir ${CMAKE_BINARY_DIR}/libjpeg-turbo-install)
|
||||
if (WIN32)
|
||||
set(_jpeg_lib ${_jpeg_install_dir}/lib/turbojpeg-static.lib)
|
||||
else ()
|
||||
set(_jpeg_lib ${_jpeg_install_dir}/lib/libturbojpeg.a)
|
||||
endif ()
|
||||
set(_jpeg_cmake_args
|
||||
-DCMAKE_INSTALL_PREFIX=${_jpeg_install_dir}
|
||||
-DCMAKE_PROJECT_INCLUDE=${CMAKE_CURRENT_SOURCE_DIR}/cmake/WindowsTargetProcessor.cmake
|
||||
-DENABLE_SHARED=OFF
|
||||
-DWITH_TURBOJPEG=ON
|
||||
-DWITH_JAVA=OFF
|
||||
-DCMAKE_INSTALL_LIBDIR=lib
|
||||
)
|
||||
if (CMAKE_TOOLCHAIN_FILE)
|
||||
get_filename_component(_jpeg_toolchain_file "${CMAKE_TOOLCHAIN_FILE}" ABSOLUTE BASE_DIR "${CMAKE_SOURCE_DIR}")
|
||||
list(APPEND _jpeg_cmake_args -DCMAKE_TOOLCHAIN_FILE=${_jpeg_toolchain_file})
|
||||
endif ()
|
||||
set(_jpeg_passthrough_vars
|
||||
ANDROID_ABI
|
||||
ANDROID_PLATFORM
|
||||
CMAKE_BUILD_TYPE
|
||||
CMAKE_C_COMPILER
|
||||
CMAKE_C_COMPILER_LAUNCHER
|
||||
CMAKE_MAKE_PROGRAM
|
||||
CMAKE_MSVC_RUNTIME_LIBRARY
|
||||
CMAKE_MSVC_DEBUG_INFORMATION_FORMAT
|
||||
CMAKE_OSX_ARCHITECTURES
|
||||
CMAKE_OSX_DEPLOYMENT_TARGET
|
||||
CMAKE_OSX_SYSROOT
|
||||
DEPLOYMENT_TARGET
|
||||
ENABLE_ARC
|
||||
ENABLE_BITCODE
|
||||
PLATFORM
|
||||
)
|
||||
foreach(_var IN LISTS _jpeg_passthrough_vars)
|
||||
if (DEFINED ${_var})
|
||||
list(APPEND _jpeg_cmake_args -D${_var}=${${_var}})
|
||||
endif ()
|
||||
endforeach ()
|
||||
ExternalProject_Add(libjpeg-turbo-ext
|
||||
URL https://github.com/libjpeg-turbo/libjpeg-turbo/archive/refs/tags/3.1.0.tar.gz
|
||||
URL_HASH SHA256=35fec2e1ddfb05ecf6d93e50bc57c1e54bc81c16d611ddf6eff73fff266d8285
|
||||
CMAKE_ARGS ${_jpeg_cmake_args}
|
||||
BUILD_BYPRODUCTS ${_jpeg_lib}
|
||||
)
|
||||
file(MAKE_DIRECTORY ${_jpeg_install_dir}/include)
|
||||
add_library(libjpeg-turbo::turbojpeg-static STATIC IMPORTED GLOBAL)
|
||||
set_target_properties(libjpeg-turbo::turbojpeg-static PROPERTIES
|
||||
IMPORTED_LOCATION ${_jpeg_lib}
|
||||
INTERFACE_INCLUDE_DIRECTORIES ${_jpeg_install_dir}/include
|
||||
)
|
||||
add_dependencies(libjpeg-turbo::turbojpeg-static libjpeg-turbo-ext)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU")
|
||||
# -Wno-multichar: Multi-character constants ('ABCD') are implementation-defined but all compilers
|
||||
# (CW, GCC, Clang, MSVC) encode them identically in big-endian order.
|
||||
@@ -303,7 +240,7 @@ include(cmake/GameABIConfig.cmake)
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
set(GAME_COMPILE_DEFS DUSK_BUILDING_GAME=1)
|
||||
set(GAME_LIBS aurora::core aurora::gx aurora::gd aurora::si aurora::vi aurora::pad aurora::mtx aurora::os aurora::dvd
|
||||
set(GAME_LIBS aurora::core aurora::gx aurora::gd aurora::si aurora::vi aurora::pad aurora::mtx aurora::os aurora::dvd aurora::thp
|
||||
aurora::card borealis::cli borealis::crash borealis::data borealis::disc borealis::discord borealis::file_select borealis::io borealis::log borealis::net borealis::presentation borealis::sentry borealis::update borealis::ws freeverb cxxopts::cxxopts absl::flat_hash_map nlohmann_json::nlohmann_json TracyClient fmt::fmt
|
||||
Threads::Threads zstd::libzstd dusklight_game_headers)
|
||||
if (DUSK_HAS_FUNCHOOK)
|
||||
@@ -314,15 +251,6 @@ if (WIN32)
|
||||
list(APPEND GAME_LIBS Ws2_32)
|
||||
endif ()
|
||||
|
||||
if (DUSK_MOVIE_SUPPORT)
|
||||
if (TARGET libjpeg-turbo::turbojpeg-static)
|
||||
list(APPEND GAME_LIBS libjpeg-turbo::turbojpeg-static)
|
||||
else ()
|
||||
list(APPEND GAME_LIBS libjpeg-turbo::turbojpeg)
|
||||
endif ()
|
||||
list(APPEND GAME_COMPILE_DEFS MOVIE_SUPPORT=1)
|
||||
endif ()
|
||||
|
||||
if (DUSK_ENABLE_CODE_MODS)
|
||||
list(APPEND GAME_COMPILE_DEFS DUSK_CODE_MODS=1)
|
||||
endif ()
|
||||
|
||||
Vendored
+1
-1
Submodule extern/aurora updated: f1189541e5...b6b0b34c4a
@@ -4,6 +4,7 @@
|
||||
#if !TARGET_PC
|
||||
#include <thp.h>
|
||||
#else
|
||||
#include <dolphin/thp.h>
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#endif
|
||||
@@ -17,29 +18,6 @@ struct daMP_THPReadBuffer {
|
||||
};
|
||||
|
||||
#if TARGET_PC
|
||||
// Copying here because thp.h is probably erroneous in the dolphin lib,
|
||||
// and it's kind of a problem being there (Aurora owns the headers).
|
||||
// TODO: Move this stuff in decomp?
|
||||
typedef struct THPAudioRecordHeader {
|
||||
BE(u32) offsetNextChannel;
|
||||
BE(u32) sampleSize;
|
||||
BE(s16) lCoef[8][2];
|
||||
BE(s16) rCoef[8][2];
|
||||
BE(s16) lYn1;
|
||||
BE(s16) lYn2;
|
||||
BE(s16) rYn1;
|
||||
BE(s16) rYn2;
|
||||
} THPAudioRecordHeader;
|
||||
|
||||
typedef struct THPAudioDecodeInfo {
|
||||
u8* encodeData;
|
||||
u32 offsetNibbles;
|
||||
u8 predictor;
|
||||
u8 scale;
|
||||
s16 yn1;
|
||||
s16 yn2;
|
||||
} THPAudioDecodeInfo;
|
||||
|
||||
typedef struct THPTextureSet {
|
||||
u8* ytexture;
|
||||
u8* utexture;
|
||||
@@ -86,10 +64,6 @@ typedef struct THPHeader {
|
||||
/* 0x2C */ BE(u32) finalFrameDataOffsets;
|
||||
} THPHeader;
|
||||
|
||||
static u32 THPAudioDecode(s16* audioBuffer, u8* audioFrame, s32 flag);
|
||||
static s32 __THPAudioGetNewSample(THPAudioDecodeInfo* info);
|
||||
static void __THPAudioInitialize(THPAudioDecodeInfo* info, u8* ptr);
|
||||
|
||||
#define THP_AUDIO_BUFFER_COUNT 3
|
||||
#define THP_READ_BUFFER_COUNT 10
|
||||
#define THP_TEXTURE_SET_COUNT 3
|
||||
|
||||
@@ -1103,14 +1103,8 @@ inline int daDemo00_c::execute() {
|
||||
case 2: {
|
||||
u16 sp0A = sp0E & 0x3FFF;
|
||||
if ((sp0E & 0xC000) == 0) {
|
||||
#if !MOVIE_SUPPORT
|
||||
// If movie support isn't available, automatically reset.
|
||||
// TPHD-esque. Maybe not the best solution, but it works.
|
||||
dComIfGp_event_reset();
|
||||
#else
|
||||
fopAcM_create(fpcNm_MOVIE_PLAYER_e, sp0A, NULL, fopAcM_GetRoomNo(this), NULL, NULL, 0xFF);
|
||||
mDoGph_gInf_c::fadeOut(1.0f);
|
||||
#endif
|
||||
} else {
|
||||
switch (sp0A) {
|
||||
case 0:
|
||||
|
||||
@@ -15,15 +15,12 @@
|
||||
#pragma optimize_for_size off
|
||||
|
||||
#include <cstring>
|
||||
#include <span>
|
||||
#include "JSystem/JAudio2/JASAiCtrl.h"
|
||||
#include "JSystem/JAudio2/JASDriverIF.h"
|
||||
#include "JSystem/JKernel/JKRExpHeap.h"
|
||||
#include "Z2AudioLib/Z2Instances.h"
|
||||
#include "d/actor/d_a_movie_player.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "f_op/f_op_overlap_mng.h"
|
||||
|
||||
#include "JSystem/JAudio2/JASCriticalSection.h"
|
||||
@@ -32,9 +29,6 @@
|
||||
#include "helpers/gx_helper.h"
|
||||
#include "dusk/os.h"
|
||||
#include "dusk/layout.hpp"
|
||||
#if MOVIE_SUPPORT
|
||||
#include "turbojpeg.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
inline s32 daMP_NEXT_READ_SIZE(daMP_THPReadBuffer* readBuf) {
|
||||
@@ -49,7 +43,8 @@ inline s32 daMP_NEXT_READ_SIZE(daMP_THPReadBuffer* readBuf) {
|
||||
#define OS_THREAD_ATTR OS_THREAD_ATTR_DETACH
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus) && !TARGET_PC
|
||||
#if !TARGET_PC
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@@ -217,7 +212,6 @@ static void __THPAudioInitialize(THPAudioDecodeInfo* info, u8* ptr) {
|
||||
info->encodeData++;
|
||||
}
|
||||
|
||||
#if !TARGET_PC
|
||||
ATTRIBUTE_ALIGN(32) static u8 THPStatistics[1120];
|
||||
|
||||
ATTRIBUTE_ALIGN(32) static THPHuffmanTab* Ydchuff;
|
||||
@@ -2587,104 +2581,9 @@ static void __THPHuffDecodeDCTCompV(__REGISTER THPFileInfo* info, THPCoeff* bloc
|
||||
#else // !TARGET_PC
|
||||
|
||||
static daMP_THPPlayer daMP_ActivePlayer;
|
||||
|
||||
#if MOVIE_SUPPORT
|
||||
static std::vector<u8> FixedJpegData;
|
||||
static tjhandle JpegDecompressHandle;
|
||||
|
||||
static const std::vector<u8>& FixJpeg(const std::span<u8> data) {
|
||||
FixedJpegData.resize(0);
|
||||
FixedJpegData.reserve(data.size());
|
||||
|
||||
size_t startOfScanLocation = 0;
|
||||
for (; startOfScanLocation < data.size() - 1; startOfScanLocation++) {
|
||||
if (data[startOfScanLocation] == 0xFF && data[startOfScanLocation + 1] == 0xDA) {
|
||||
goto sosFound;
|
||||
}
|
||||
}
|
||||
|
||||
CRASH("Unable to find SOS marker!");
|
||||
|
||||
sosFound:
|
||||
|
||||
startOfScanLocation += 2; // TODO: Skip entire SOS header?
|
||||
|
||||
size_t endOfImage = data.size() - 1;
|
||||
for (; endOfImage > startOfScanLocation; endOfImage--) {
|
||||
if (data[endOfImage] == 0xFF && data[endOfImage + 1] == 0xD9) {
|
||||
goto eoiFound;
|
||||
}
|
||||
}
|
||||
|
||||
CRASH("Unable to find EOI marker!");
|
||||
eoiFound:
|
||||
|
||||
// Copy data before SOS
|
||||
for (size_t i = 0; i < startOfScanLocation; i++) {
|
||||
FixedJpegData.push_back(data[i]);
|
||||
}
|
||||
|
||||
// Copy data inside SOS, fixing up lacking of "byte shuffling"
|
||||
for (size_t i = startOfScanLocation; i < endOfImage; i++) {
|
||||
u8 value = data[i];
|
||||
FixedJpegData.push_back(value);
|
||||
if (value == 0xFF) {
|
||||
FixedJpegData.push_back(0x00);
|
||||
}
|
||||
}
|
||||
|
||||
// Copy data after SOS.
|
||||
for (size_t i = endOfImage; i < data.size(); i++) {
|
||||
FixedJpegData.push_back(data[i]);
|
||||
}
|
||||
|
||||
return FixedJpegData;
|
||||
}
|
||||
|
||||
static s32 THPVideoDecode(void* file, size_t fileSize, void* tileY, void* tileU, void* tileV, void*) {
|
||||
assert(JpegDecompressHandle);
|
||||
|
||||
const auto handle = JpegDecompressHandle;
|
||||
const auto fixedData = FixJpeg(std::span(static_cast<u8*>(file), fileSize));
|
||||
|
||||
auto ret = tj3DecompressHeader(handle, fixedData.data(), fixedData.size());
|
||||
if (ret == -1) {
|
||||
OSReport_Error("Parsing JPEG header failed: %s", tj3GetErrorStr(handle));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (tj3Get(handle, TJPARAM_JPEGWIDTH) != daMP_ActivePlayer.videoInfo.xSize) {
|
||||
OSReport_Error("Invalid width in video frame!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (tj3Get(handle, TJPARAM_JPEGHEIGHT) != daMP_ActivePlayer.videoInfo.ySize) {
|
||||
OSReport_Error("Invalid height in video frame!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
ret = tj3Set(handle, TJPARAM_SUBSAMP, TJSAMP_420);
|
||||
if (ret != 0) {
|
||||
OSReport_Error("Failed to set subsampling mode: %s", tj3GetErrorStr(handle));
|
||||
return 1;
|
||||
}
|
||||
|
||||
u8* planes[3] = {static_cast<u8*>(tileY), static_cast<u8*>(tileU), static_cast<u8*>(tileV)};
|
||||
ret = tj3DecompressToYUVPlanes8(handle, fixedData.data(), fixedData.size(), planes, nullptr);
|
||||
if (ret != 0) {
|
||||
OSReport_Error("Image decompression failed: %s", tj3GetErrorStr(handle));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else // MOVIE_SUPPORT
|
||||
static s32 THPVideoDecode(void*, size_t, void*, void*, void*, void*) {
|
||||
return 1; // Immediate error.
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !TARGET_PC
|
||||
static BOOL THPInit() {
|
||||
#if !TARGET_PC
|
||||
u8* base;
|
||||
@@ -2712,9 +2611,10 @@ static BOOL THPInit() {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#if defined(__cplusplus) && !TARGET_PC
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif // !TARGET_PC
|
||||
|
||||
#if !TARGET_PC // Defined earlier in file.
|
||||
static daMP_THPPlayer daMP_ActivePlayer;
|
||||
@@ -2937,9 +2837,6 @@ static void daMP_VideoDecode(daMP_THPReadBuffer* readBuffer) {
|
||||
case 0: {
|
||||
if ((daMP_ActivePlayer.videoError = THPVideoDecode(
|
||||
tile,
|
||||
#if TARGET_PC
|
||||
*tileOffsets,
|
||||
#endif
|
||||
textureSet->ytexture, textureSet->utexture,
|
||||
textureSet->vtexture,
|
||||
daMP_ActivePlayer.thpWork))) {
|
||||
@@ -3434,26 +3331,19 @@ static void daMP_THPGXYuv2RgbDraw(u8* y_data, u8* u_data, u8* v_data, s16 x,
|
||||
TGXTexObj tobj0;
|
||||
TGXTexObj tobj1;
|
||||
TGXTexObj tobj2;
|
||||
#if TARGET_PC
|
||||
#define FMT (GXTexFmt)GX_TF_R8_PC
|
||||
#else
|
||||
#define FMT GX_TF_I8
|
||||
#endif
|
||||
|
||||
GXInitTexObj(&tobj0, y_data, textureWidth, textureHeight, FMT, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||
GXInitTexObj(&tobj0, y_data, textureWidth, textureHeight, GX_TF_I8, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||
GXInitTexObjLOD(&tobj0, GX_NEAR, GX_NEAR, 0.0f, 0.0f, 0.0f, 0, 0, GX_ANISO_1);
|
||||
GXLoadTexObj(&tobj0, GX_TEXMAP0);
|
||||
|
||||
GXInitTexObj(&tobj1, u_data, textureWidth >> 1, textureHeight >> 1, FMT, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||
GXInitTexObj(&tobj1, u_data, textureWidth >> 1, textureHeight >> 1, GX_TF_I8, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||
GXInitTexObjLOD(&tobj1, GX_NEAR, GX_NEAR, 0.0f, 0.0f, 0.0f, 0, 0, GX_ANISO_1);
|
||||
GXLoadTexObj(&tobj1, GX_TEXMAP1);
|
||||
|
||||
GXInitTexObj(&tobj2, v_data, textureWidth >> 1, textureHeight >> 1, FMT, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||
GXInitTexObj(&tobj2, v_data, textureWidth >> 1, textureHeight >> 1, GX_TF_I8, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||
GXInitTexObjLOD(&tobj2, GX_NEAR, GX_NEAR, 0.0f, 0.0f, 0.0f, 0, 0, GX_ANISO_1);
|
||||
GXLoadTexObj(&tobj2, GX_TEXMAP2);
|
||||
|
||||
#undef FMT
|
||||
|
||||
GXBegin(GX_QUADS, GX_VTXFMT7, 4);
|
||||
GXPosition3s16(x, y, 0);
|
||||
GXTexCoord2u16(0, 0);
|
||||
@@ -3774,13 +3664,6 @@ static BOOL daMP_THPPlayerOpen(char const* filename, BOOL onMemory) {
|
||||
}
|
||||
|
||||
static BOOL daMP_THPPlayerClose() {
|
||||
#if TARGET_PC && MOVIE_SUPPORT
|
||||
tj3Destroy(JpegDecompressHandle);
|
||||
JpegDecompressHandle = nullptr;
|
||||
|
||||
FixedJpegData.clear();
|
||||
#endif
|
||||
|
||||
if (daMP_ActivePlayer.open && daMP_ActivePlayer.state == 0) {
|
||||
daMP_ActivePlayer.open = 0;
|
||||
DVDClose(&daMP_ActivePlayer.fileInfo);
|
||||
@@ -3832,11 +3715,6 @@ static BOOL daMP_THPPlayerSetBuffer(u8* buffer) {
|
||||
|
||||
ysize = ALIGN_NEXT(daMP_ActivePlayer.videoInfo.xSize * daMP_ActivePlayer.videoInfo.ySize, 32);
|
||||
uvsize = ALIGN_NEXT(daMP_ActivePlayer.videoInfo.xSize * daMP_ActivePlayer.videoInfo.ySize / 4, 32);
|
||||
#if TARGET_PC
|
||||
assert(ysize >= tj3YUVPlaneSize(0, daMP_ActivePlayer.videoInfo.xSize, 0, daMP_ActivePlayer.videoInfo.ySize, TJSAMP_420));
|
||||
assert(uvsize >= tj3YUVPlaneSize(1, daMP_ActivePlayer.videoInfo.xSize, 0, daMP_ActivePlayer.videoInfo.ySize, TJSAMP_420));
|
||||
assert(uvsize >= tj3YUVPlaneSize(2, daMP_ActivePlayer.videoInfo.xSize, 0, daMP_ActivePlayer.videoInfo.ySize, TJSAMP_420));
|
||||
#endif
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(daMP_ActivePlayer.textureSet); i++) {
|
||||
daMP_ActivePlayer.textureSet[i].ytexture = ptr;
|
||||
@@ -4329,15 +4207,6 @@ static BOOL daMP_ActivePlayer_Init(char const* moviePath) {
|
||||
|
||||
daMP_THPPlayerSetBuffer((u8*)daMP_buffer);
|
||||
|
||||
#if TARGET_PC && MOVIE_SUPPORT
|
||||
assert(JpegDecompressHandle == nullptr);
|
||||
JpegDecompressHandle = tj3Init(TJINIT_DECOMPRESS);
|
||||
if (JpegDecompressHandle == nullptr) {
|
||||
OSReport_Error("Failed to create turbojpeg handle: %s", tj3GetErrorStr(nullptr));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!daMP_THPPlayerPrepare(0, 0, daMP_audioInfo.sndNumTracks != 1 ? OSGetTick() % daMP_audioInfo.sndNumTracks : 0)) {
|
||||
OSReport("Fail to prepare\n");
|
||||
#if DEBUG
|
||||
|
||||
Reference in New Issue
Block a user