Skip to content

Commit c4a8963

Browse files
committed
Add CHD disc image format support via vendored libchdr
Vendors libchdr (https://github.com/rtissera/libchdr) with its dependencies (lzma, miniz, zstd) to support loading Jaguar CD games from CHD (MAME Compressed Hunks of Data) format, the preferred format for distribution in libretro. Changes: - deps/libchdr/: Vendored libchdr library with lzma, miniz, zstd deps - Makefile.common: Add libchdr sources and include paths, define HAVE_CHD - src/cdintf.c: Add ParseCHD() that reads CHTR/CHTR2 track metadata, CDIntfReadBlockCHD() that reads sectors via hunk-based access with single-hunk caching, updated CDIntfOpenImage/CloseImage/IsImageLoaded to handle CHD alongside CUE/BIN - libretro.c: Add .chd to valid_extensions, detect CHD in load_game The CHD reader extracts track layout from CHD metadata tags, handles both CDROM_TRACK_METADATA and CDROM_TRACK_METADATA2 formats (with pregap/postgap), and reads raw 2352-byte audio sectors from the compressed hunk data. All existing cartridge regression tests pass. https://claude.ai/code/session_017594R2HVUZmGUxyQp9328w
1 parent ccc30c7 commit c4a8963

65 files changed

Lines changed: 61082 additions & 7 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Makefile.common

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
LIBRETRO_COMM_DIR = $(CORE_DIR)/libretro-common
2+
LIBCHDR_DIR = $(CORE_DIR)/deps/libchdr
23

34
INCFLAGS := -I$(CORE_DIR) \
45
-I$(CORE_DIR)/src \
@@ -9,6 +10,13 @@ ifneq (,$(findstring msvc2003,$(platform)))
910
INCFLAGS += -I$(LIBRETRO_COMM_DIR)/include/compat/msvc
1011
endif
1112

13+
# libchdr (CHD disc image support)
14+
INCFLAGS += -I$(LIBCHDR_DIR)/include \
15+
-I$(LIBCHDR_DIR)/deps/lzma-25.01/include \
16+
-I$(LIBCHDR_DIR)/deps/miniz-3.1.1 \
17+
-I$(LIBCHDR_DIR)/deps/zstd-1.5.7
18+
FLAGS += -DHAVE_CHD -DMINIZ_NO_STDIO -DWANT_SUBCODE=1 -DWANT_RAW_DATA_SECTOR=0
19+
1220
SOURCES_CXX :=
1321

1422
SOURCES_C := \
@@ -48,6 +56,26 @@ SOURCES_C := \
4856
$(CORE_DIR)/src/universalhdr.c \
4957
$(CORE_DIR)/src/wavetable.c
5058

59+
# libchdr sources
60+
SOURCES_C += \
61+
$(LIBCHDR_DIR)/src/libchdr_bitstream.c \
62+
$(LIBCHDR_DIR)/src/libchdr_cdrom.c \
63+
$(LIBCHDR_DIR)/src/libchdr_chd.c \
64+
$(LIBCHDR_DIR)/src/libchdr_codec_cdfl.c \
65+
$(LIBCHDR_DIR)/src/libchdr_codec_cdlz.c \
66+
$(LIBCHDR_DIR)/src/libchdr_codec_cdzl.c \
67+
$(LIBCHDR_DIR)/src/libchdr_codec_cdzs.c \
68+
$(LIBCHDR_DIR)/src/libchdr_codec_flac.c \
69+
$(LIBCHDR_DIR)/src/libchdr_codec_huff.c \
70+
$(LIBCHDR_DIR)/src/libchdr_codec_lzma.c \
71+
$(LIBCHDR_DIR)/src/libchdr_codec_zlib.c \
72+
$(LIBCHDR_DIR)/src/libchdr_codec_zstd.c \
73+
$(LIBCHDR_DIR)/src/libchdr_flac.c \
74+
$(LIBCHDR_DIR)/src/libchdr_huffman.c \
75+
$(LIBCHDR_DIR)/deps/lzma-25.01/src/LzmaDec.c \
76+
$(LIBCHDR_DIR)/deps/miniz-3.1.1/miniz.c \
77+
$(LIBCHDR_DIR)/deps/zstd-1.5.7/zstddeclib.c
78+
5179
ifneq ($(STATIC_LINKING), 1)
5280
SOURCES_C += \
5381
$(LIBRETRO_COMM_DIR)/compat/compat_strcasestr.c \
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: CMake
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
build:
7+
runs-on: ${{ matrix.os }}
8+
strategy:
9+
matrix:
10+
os: [macos-latest, ubuntu-latest, windows-latest]
11+
12+
steps:
13+
- uses: actions/checkout@v6
14+
15+
- name: Configure CMake
16+
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=Release
17+
18+
- name: Build
19+
run: cmake --build ${{github.workspace}}/build --config Release
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: BSD, Haiku, OmniOS
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
build:
7+
runs-on: ubuntu-latest
8+
strategy:
9+
matrix:
10+
operating_system: [ freebsd, haiku, netbsd, omnios, openbsd ]
11+
architecture: [ arm64, x86-64 ]
12+
include:
13+
- operating_system: freebsd
14+
version: '15.0'
15+
pkginstall: sudo pkg update && sudo pkg install -y cmake git ninja
16+
- operating_system: haiku
17+
version: 'r1beta5'
18+
pkginstall: pkgman refresh && pkgman install -y cmake git ninja
19+
- operating_system: netbsd
20+
version: '10.1'
21+
pkginstall: sudo pkgin update && sudo pkgin -y install clang cmake git ninja-build
22+
- operating_system: omnios
23+
version: 'r151056'
24+
pkginstall: sudo pkg refresh && sudo pkg install build-essential cmake git ninja
25+
- operating_system: openbsd
26+
version: '7.8'
27+
pkginstall: sudo pkg_add -u && sudo pkg_add cmake git ninja
28+
exclude:
29+
- operating_system: haiku
30+
architecture: arm64
31+
- operating_system: omnios
32+
architecture: arm64
33+
34+
steps:
35+
- uses: actions/checkout@v6
36+
37+
- uses: cross-platform-actions/[email protected]
38+
with:
39+
operating_system: ${{ matrix.operating_system }}
40+
architecture: ${{ matrix.architecture }}
41+
version: ${{ matrix.version }}
42+
run: |
43+
${{ matrix.pkginstall }}
44+
cmake -B build -DCMAKE_BUILD_TYPE=Release -G Ninja
45+
cmake --build build --config Release
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: MSYS2
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
build:
7+
runs-on: ${{ matrix.os }}
8+
strategy:
9+
matrix:
10+
include:
11+
- { os: windows-latest, sys: mingw32 }
12+
- { os: windows-latest, sys: mingw64 }
13+
- { os: windows-latest, sys: ucrt64 }
14+
- { os: windows-latest, sys: clang64 }
15+
- { os: windows-11-arm, sys: clangarm64 }
16+
defaults:
17+
run:
18+
shell: msys2 {0}
19+
20+
steps:
21+
- uses: actions/checkout@v6
22+
23+
- uses: msys2/setup-msys2@v2
24+
with:
25+
msystem: ${{matrix.sys}}
26+
update: true
27+
install: make
28+
pacboy: >-
29+
cmake:p
30+
toolchain:p
31+
32+
- name: Configure CMake
33+
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=Release
34+
35+
- name: Build
36+
run: cmake --build ${{github.workspace}}/build --config Release
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
name: Nintendo Switch
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
build:
7+
runs-on: ubuntu-latest
8+
container: devkitpro/devkita64:latest
9+
10+
steps:
11+
- uses: actions/checkout@v6
12+
13+
- name: Configure CMake
14+
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=${DEVKITPRO}/cmake/Switch.cmake
15+
16+
- name: Build
17+
run: cmake --build ${{github.workspace}}/build --config Release
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
name: PlayStation Vita
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
build:
7+
runs-on: ubuntu-latest
8+
container: vitasdk/vitasdk:latest
9+
10+
steps:
11+
- uses: actions/checkout@v6
12+
13+
- name: Configure CMake
14+
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=${VITASDK}/share/vita.toolchain.cmake
15+
16+
- name: Build
17+
run: cmake --build ${{github.workspace}}/build --config Release

deps/libchdr/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
*.o
2+
*.d
3+
build/

deps/libchdr/CMakeLists.txt

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
cmake_minimum_required(VERSION 3.10)
2+
3+
project(chdr VERSION 0.2 LANGUAGES C)
4+
5+
if(CMAKE_PROJECT_NAME STREQUAL "chdr")
6+
option(BUILD_SHARED_LIBS "Build libchdr also as a shared library" ON)
7+
endif()
8+
option(INSTALL_STATIC_LIBS "Install static libraries" OFF)
9+
option(WITH_SYSTEM_ZLIB "Use system provided zlib library" OFF)
10+
option(WITH_SYSTEM_ZSTD "Use system provided zstd library" OFF)
11+
option(CHDR_WANT_RAW_DATA_SECTOR "Output ECC data and sync header" ON)
12+
option(CHDR_WANT_SUBCODE "Output CD subchannel data" ON)
13+
option(CHDR_VERIFY_BLOCK_CRC "Verify integrity of decoded data" ON)
14+
15+
option(BUILD_LTO "Compile libchdr with link-time optimization if supported" OFF)
16+
if(BUILD_LTO)
17+
include(CheckIPOSupported)
18+
check_ipo_supported(RESULT HAVE_IPO)
19+
if(HAVE_IPO)
20+
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
21+
endif()
22+
endif()
23+
24+
option(BUILD_FUZZER "Build instrumented binary for fuzzing with libfuzzer, requires clang")
25+
if(BUILD_FUZZER)
26+
# Override CFLAGS early for instrumentation. Disable shared libs for instrumentation.
27+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address,fuzzer-no-link")
28+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address,fuzzer-no-link")
29+
set(BUILD_SHARED_LIBS OFF)
30+
endif()
31+
32+
include(GNUInstallDirs)
33+
34+
#--------------------------------------------------
35+
# dependencies
36+
#--------------------------------------------------
37+
38+
# lzma
39+
if(NOT TARGET chdr-lzma)
40+
add_subdirectory(deps/lzma-25.01 EXCLUDE_FROM_ALL)
41+
endif()
42+
list(APPEND CHDR_LIBS chdr-lzma)
43+
44+
# zlib
45+
if (WITH_SYSTEM_ZLIB)
46+
find_package(ZLIB REQUIRED)
47+
list(APPEND PLATFORM_LIBS ZLIB::ZLIB)
48+
list(APPEND CHDR_DEFINES CHDR_SYSTEM_ZLIB)
49+
else()
50+
if(NOT TARGET miniz)
51+
add_subdirectory(deps/miniz-3.1.1 EXCLUDE_FROM_ALL)
52+
endif()
53+
list(APPEND CHDR_LIBS miniz)
54+
endif()
55+
56+
# zstd
57+
if (WITH_SYSTEM_ZSTD)
58+
find_package(zstd REQUIRED)
59+
if(TARGET zstd::libzstd_shared)
60+
list(APPEND PLATFORM_LIBS zstd::libzstd_shared)
61+
else()
62+
list(APPEND PLATFORM_LIBS zstd::libzstd_static)
63+
endif()
64+
list(APPEND CHDR_DEFINES CHDR_SYSTEM_ZSTD)
65+
else()
66+
if(NOT TARGET zstd)
67+
add_subdirectory(deps/zstd-1.5.7 EXCLUDE_FROM_ALL)
68+
endif()
69+
list(APPEND CHDR_LIBS zstd)
70+
endif()
71+
72+
#--------------------------------------------------
73+
# options
74+
#--------------------------------------------------
75+
76+
if(CHDR_WANT_RAW_DATA_SECTOR)
77+
list(APPEND CHDR_DEFINES WANT_RAW_DATA_SECTOR=1)
78+
else()
79+
list(APPEND CHDR_DEFINES WANT_RAW_DATA_SECTOR=0)
80+
endif()
81+
82+
if(CHDR_WANT_SUBCODE)
83+
list(APPEND CHDR_DEFINES WANT_SUBCODE=1)
84+
else()
85+
list(APPEND CHDR_DEFINES WANT_SUBCODE=0)
86+
endif()
87+
88+
if(CHDR_VERIFY_BLOCK_CRC)
89+
list(APPEND CHDR_DEFINES VERIFY_BLOCK_CRC=1)
90+
else()
91+
list(APPEND CHDR_DEFINES VERIFY_BLOCK_CRC=0)
92+
endif()
93+
94+
#--------------------------------------------------
95+
# chdr
96+
#--------------------------------------------------
97+
98+
set(CHDR_SOURCES
99+
src/libchdr_bitstream.c
100+
src/libchdr_cdrom.c
101+
src/libchdr_chd.c
102+
src/libchdr_codec_cdfl.c
103+
src/libchdr_codec_cdlz.c
104+
src/libchdr_codec_cdzl.c
105+
src/libchdr_codec_cdzs.c
106+
src/libchdr_codec_flac.c
107+
src/libchdr_codec_huff.c
108+
src/libchdr_codec_lzma.c
109+
src/libchdr_codec_zlib.c
110+
src/libchdr_codec_zstd.c
111+
src/libchdr_flac.c
112+
src/libchdr_huffman.c
113+
)
114+
115+
add_library(chdr-static STATIC ${CHDR_SOURCES})
116+
target_include_directories(chdr-static INTERFACE include)
117+
target_link_libraries(chdr-static PRIVATE ${CHDR_LIBS} ${PLATFORM_LIBS})
118+
target_compile_definitions(chdr-static PRIVATE ${CHDR_DEFINES})
119+
120+
if(MSVC)
121+
target_compile_definitions(chdr-static PRIVATE _CRT_SECURE_NO_WARNINGS)
122+
endif()
123+
124+
if (INSTALL_STATIC_LIBS)
125+
install(TARGETS chdr-static ${CHDR_LIBS}
126+
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
127+
)
128+
endif()
129+
130+
if (BUILD_SHARED_LIBS)
131+
add_library(chdr SHARED ${CHDR_SOURCES})
132+
target_include_directories(chdr INTERFACE include)
133+
target_link_libraries(chdr PRIVATE ${CHDR_LIBS} ${PLATFORM_LIBS})
134+
target_compile_definitions(chdr PRIVATE ${CHDR_DEFINES})
135+
136+
if(MSVC)
137+
target_compile_definitions(chdr PUBLIC "CHD_DLL")
138+
target_compile_definitions(chdr PRIVATE "CHD_DLL_EXPORTS")
139+
target_compile_definitions(chdr PRIVATE _CRT_SECURE_NO_WARNINGS)
140+
elseif(APPLE)
141+
target_link_libraries(chdr PRIVATE -Wl,-dead_strip -Wl,-exported_symbol,_chd_*)
142+
else()
143+
include(CheckLinkerFlag)
144+
check_linker_flag(C "LINKER:--version-script=${CMAKE_CURRENT_SOURCE_DIR}/src/link.T" LINKER_VERSION_SCRIPT_SUPPORTED)
145+
if(LINKER_VERSION_SCRIPT_SUPPORTED)
146+
target_link_options(chdr PRIVATE "LINKER:--version-script=${CMAKE_CURRENT_SOURCE_DIR}/src/link.T")
147+
endif()
148+
if(NOT CMAKE_SYSTEM_NAME STREQUAL OpenBSD)
149+
target_link_libraries(chdr PRIVATE -Wl,--no-undefined)
150+
endif()
151+
endif()
152+
153+
set_target_properties(chdr PROPERTIES C_VISIBILITY_PRESET hidden)
154+
set_target_properties(chdr PROPERTIES VISIBILITY_INLINES_HIDDEN 1)
155+
set_target_properties(chdr PROPERTIES PUBLIC_HEADER "include/libchdr/bitstream.h;include/libchdr/cdrom.h;include/libchdr/chd.h;include/libchdr/chdconfig.h;include/libchdr/coretypes.h;include/libchdr/flac.h;include/libchdr/huffman.h;include/libchdr/macros.h")
156+
set_target_properties(chdr PROPERTIES VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}" SOVERSION ${PROJECT_VERSION_MAJOR})
157+
158+
if (CMAKE_BUILD_TYPE MATCHES Release)
159+
#add_custom_command(TARGET chdr POST_BUILD COMMAND ${CMAKE_STRIP} libchdr.so)
160+
endif (CMAKE_BUILD_TYPE MATCHES Release)
161+
162+
install(TARGETS chdr
163+
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
164+
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
165+
PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/libchdr"
166+
)
167+
168+
configure_file(pkg-config.pc.in ${CMAKE_BINARY_DIR}/libchdr.pc @ONLY)
169+
install(FILES ${CMAKE_BINARY_DIR}/libchdr.pc DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
170+
endif()
171+
172+
add_subdirectory(tests)

deps/libchdr/LICENSE.txt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
Copyright Romain Tisserand
2+
All rights reserved.
3+
4+
Redistribution and use in source and binary forms, with or without
5+
modification, are permitted provided that the following conditions are met:
6+
* Redistributions of source code must retain the above copyright
7+
notice, this list of conditions and the following disclaimer.
8+
* Redistributions in binary form must reproduce the above copyright
9+
notice, this list of conditions and the following disclaimer in the
10+
documentation and/or other materials provided with the distribution.
11+
* Neither the name of the <organization> nor the
12+
names of its contributors may be used to endorse or promote products
13+
derived from this software without specific prior written permission.
14+
15+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18+
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
19+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

deps/libchdr/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# libchdr
2+
3+
libchdr is a standalone library for reading MAME's CHDv1-v5 formats.
4+
5+
The code is based off of MAME's old C codebase which read up to CHDv4 with OS-dependent features removed, and CHDv5 support backported from MAME's current C++ codebase.
6+
7+
libchdr is licensed under the BSD 3-Clause (see [LICENSE.txt](LICENSE.txt)) and uses third party libraries that are each distributed under their own terms (see each library's license in [deps/](deps/)).

0 commit comments

Comments
 (0)