f8f8a80a21
New ASSET_LOADER_TYPE_MP3 (hand-rolled MPEG-1/2/2.5 Layer III header parser - no third-party dependency needed just for metadata, since PSP's hardware path doesn't need one at all) plus a shared audiostreammp3.c stream layer mirroring audiostreampcm.c's shape. Generalized the stream dispatch (hoisted sampleRate/channels onto audiostream_t, added audioStreamGetTotalFrames()/Seek()/Read()) so all three platform audio backends keep working unchanged, just calling the generic names instead of PCM-specific ones. Two decoder backends behind one interface: PSP uses the real sceMp3 hardware decoder (firmware-offloaded, lazily initialized on first use); Linux and Dolphin share one minimp3-based software decoder (public domain, vendored via CMake FetchContent) - libogc's own MP3Player wraps libmad (GPL) and drives its own output pipeline, not a fit for the ansnd-based architecture already in place, so skipped in favor of the shared minimp3 path. Fixed three real bugs found via hardware/runtime testing along the way: - LAME's Xing header counts its own placeholder frame in the declared total, which made playback stall permanently one frame short of the declared end (looked like "never loops") - fixed by subtracting it. - sceMp3Decode() can return more PCM than one MPEG frame's worth in a single call (PSP's pcmBuf is provisioned for 2x), overflowing the shared per-frame decode buffer with no bound check - very intermittent corruption/clicking on real hardware. Widened the buffer to the real worst case and added an assertion. - sceMp3ResetPlayPosition()'s exact internal reset semantics aren't documented precisely enough to trust for looping - occasionally disagreed with the fresh stream position fed right after, clicking at the loop boundary about 1 in 3-4 loops. Rewind now fully tears down and recreates the decoder instead, the same path already proven correct at first Init. Also widened the PSP ring buffer to absorb that now-heavier operation, capping each top-up call's own work so the bigger buffer doesn't turn into one long blocking decode burst instead. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
124 lines
3.8 KiB
CMake
124 lines
3.8 KiB
CMake
set(CMAKE_AR "$ENV{PSPDEV}/bin/psp-ar" CACHE FILEPATH "" FORCE)
|
|
set(CMAKE_RANLIB "$ENV{PSPDEV}/bin/psp-ranlib" CACHE FILEPATH "" FORCE)
|
|
set(CMAKE_C_COMPILER_AR "$ENV{PSPDEV}/bin/psp-ar" CACHE FILEPATH "" FORCE)
|
|
set(CMAKE_C_COMPILER_RANLIB "$ENV{PSPDEV}/bin/psp-ranlib" CACHE FILEPATH "" FORCE)
|
|
set(CMAKE_C_ARCHIVE_CREATE "$ENV{PSPDEV}/bin/psp-ar qc <TARGET> <LINK_FLAGS> <OBJECTS>")
|
|
set(CMAKE_C_ARCHIVE_APPEND "$ENV{PSPDEV}/bin/psp-ar q <TARGET> <LINK_FLAGS> <OBJECTS>")
|
|
set(CMAKE_C_ARCHIVE_FINISH "$ENV{PSPDEV}/bin/psp-ranlib <TARGET>")
|
|
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION OFF CACHE BOOL "" FORCE)
|
|
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_C OFF CACHE BOOL "" FORCE)
|
|
|
|
find_package(SDL2 REQUIRED)
|
|
find_package(OpenGL REQUIRED)
|
|
target_link_libraries(${DUSK_BINARY_TARGET_NAME} PUBLIC
|
|
${SDL2_LIBRARIES}
|
|
SDL2
|
|
pthread
|
|
OpenGL::GL
|
|
zip
|
|
bz2
|
|
z
|
|
mbedtls
|
|
mbedcrypto
|
|
lzma
|
|
m
|
|
|
|
pspdebug
|
|
pspdisplay
|
|
pspge
|
|
pspctrl
|
|
pspgu
|
|
pspaudio
|
|
pspaudiolib
|
|
pspmp3
|
|
psputility
|
|
pspvfpu
|
|
pspvram
|
|
psphprm
|
|
pspnet
|
|
pspnet_inet
|
|
pspnet_apctl
|
|
psphttp
|
|
pspssl
|
|
)
|
|
|
|
target_include_directories(${DUSK_BINARY_TARGET_NAME} PRIVATE
|
|
${SDL2_INCLUDE_DIRS}
|
|
)
|
|
|
|
target_compile_definitions(${DUSK_BINARY_TARGET_NAME} PUBLIC
|
|
DUSK_SDL2
|
|
DUSK_OPENGL
|
|
DUSK_PSP
|
|
DUSK_INPUT_GAMEPAD
|
|
DUSK_PLATFORM_ENDIAN_LITTLE
|
|
DUSK_OPENGL_LEGACY
|
|
DUSK_DISPLAY_WIDTH=480
|
|
DUSK_DISPLAY_HEIGHT=272
|
|
DUSK_THREAD_PTHREAD
|
|
DUSK_TIME_DYNAMIC
|
|
DUSK_DISPLAY_OVERSCAN=6
|
|
)
|
|
|
|
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
target_compile_definitions(${DUSK_BINARY_TARGET_NAME} PUBLIC
|
|
DUSK_ASSERTIONS_FAKED
|
|
)
|
|
endif()
|
|
|
|
# Generate PARAM.SFO as a normal tracked build output (instead of letting
|
|
# create_pbp_file() auto-generate + delete it) so it can be reused below by
|
|
# a properly dependency-tracked EBOOT.PBP repack step.
|
|
set(DUSK_PSP_PARAM_SFO "${DUSK_BUILD_DIR}/PARAM.SFO")
|
|
add_custom_command(
|
|
OUTPUT "${DUSK_PSP_PARAM_SFO}"
|
|
COMMAND "$ENV{PSPDEV}/bin/mksfoex" "-d" "MEMSIZE=1" "-s" "APP_VER=01.00"
|
|
"${DUSK_BINARY_TARGET_NAME}" "${DUSK_PSP_PARAM_SFO}"
|
|
COMMENT "Generating PARAM.SFO for ${DUSK_BINARY_TARGET_NAME}"
|
|
VERBATIM
|
|
)
|
|
add_custom_target(DuskPspParamSfo DEPENDS "${DUSK_PSP_PARAM_SFO}")
|
|
|
|
# create_pbp_file()'s own POST_BUILD chain (below) also consumes
|
|
# DUSK_PSP_PARAM_SFO, so make sure it exists before that chain runs.
|
|
add_dependencies(${DUSK_BINARY_TARGET_NAME} DuskPspParamSfo)
|
|
|
|
# Postbuild, create .pbp file for PSP.
|
|
create_pbp_file(
|
|
TARGET "${DUSK_BINARY_TARGET_NAME}"
|
|
ICON_PATH NULL
|
|
BACKGROUND_PATH NULL
|
|
PREVIEW_PATH NULL
|
|
TITLE "${DUSK_BINARY_TARGET_NAME}"
|
|
PSAR_PATH ${DUSK_ASSETS_ZIP}
|
|
VERSION 01.00
|
|
SFO_PATH "${DUSK_PSP_PARAM_SFO}"
|
|
OUTPUT_DIR "${DUSK_BUILD_DIR}"
|
|
)
|
|
|
|
# CreatePBP.cmake's pack-pbp step is a POST_BUILD command tied to the
|
|
# executable target, so it only reruns when the ELF itself relinks. That
|
|
# means regenerating dusk.dsk (assets) alone, without touching any C
|
|
# source, silently leaves EBOOT.PBP embedding a stale asset pak. Repack it
|
|
# here as a normal file-tracked custom command depending on both the
|
|
# executable and the asset zip, so EBOOT.PBP always reflects the current
|
|
# assets even when nothing else about the build changed.
|
|
set(DUSK_PSP_EBOOT "${DUSK_BUILD_DIR}/EBOOT.PBP")
|
|
if(BUILD_PRX)
|
|
set(DUSK_PSP_EXECUTABLE "$<TARGET_FILE:${DUSK_BINARY_TARGET_NAME}>.prx")
|
|
else()
|
|
set(DUSK_PSP_EXECUTABLE "$<TARGET_FILE:${DUSK_BINARY_TARGET_NAME}>")
|
|
endif()
|
|
add_custom_command(
|
|
OUTPUT "${DUSK_PSP_EBOOT}"
|
|
COMMAND "$ENV{PSPDEV}/bin/pack-pbp" "${DUSK_PSP_EBOOT}" "${DUSK_PSP_PARAM_SFO}"
|
|
"NULL" "NULL" "NULL" "NULL" "NULL"
|
|
"${DUSK_PSP_EXECUTABLE}" "${DUSK_ASSETS_ZIP}"
|
|
DEPENDS
|
|
"$<TARGET_FILE:${DUSK_BINARY_TARGET_NAME}>"
|
|
"${DUSK_PSP_PARAM_SFO}"
|
|
"${DUSK_ASSETS_ZIP}"
|
|
COMMENT "Repacking EBOOT.PBP (tracks executable + asset pak freshness)"
|
|
VERBATIM
|
|
)
|
|
add_custom_target(DuskPspEbootRepack ALL DEPENDS "${DUSK_PSP_EBOOT}") |