Created
July 16, 2025 12:56
-
-
Save joeynotjoe/23dadb5f397ff650790bdd56a7e32b47 to your computer and use it in GitHub Desktop.
Convert CHD to BIN/CUE
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env zsh | |
| # CHD to BIN/CUE Converter | |
| VERSION="1.1" | |
| DEFAULT_EXTENSIONS=("chd") | |
| # Colors for output | |
| RED='\033[0;31m' | |
| GREEN='\033[0;32m' | |
| YELLOW='\033[1;33m' | |
| BLUE='\033[0;34m' | |
| NC='\033[0m' # No Color | |
| # Help function | |
| show_help() { | |
| cat <<EOF | |
| ${GREEN}CHD to BIN/CUE Converter ${VERSION}${NC} | |
| Usage: ${0:t} [options] [file|directory] | |
| Options: | |
| -h, --help Show this help message | |
| -v, --version Show version information | |
| -r, --recursive Process directories recursively (default) | |
| -e, --ext Specify alternate extensions (comma-separated) | |
| -q, --quiet Suppress non-error output | |
| -d, --dry-run Show what would be done without actually converting | |
| Examples: | |
| ${0:t} # Convert all CHD files in current directory | |
| ${0:t} /path/to/game.chd # Convert single file | |
| ${0:t} /path/to/directory # Convert all CHDs in directory | |
| ${0:t} -e gdi,chd # Convert both GDI and CHD files | |
| EOF | |
| } | |
| # Initialize variables | |
| QUIET=0 | |
| DRY_RUN=0 | |
| EXTENSIONS=($DEFAULT_EXTENSIONS) | |
| TOTAL_FILES=0 | |
| SUCCESS_COUNT=0 | |
| FAIL_COUNT=0 | |
| START_TIME=$SECONDS | |
| # Parse arguments | |
| while [[ $# -gt 0 ]]; do | |
| case "$1" in | |
| -h|--help) | |
| show_help | |
| exit 0 | |
| ;; | |
| -v|--version) | |
| echo "${0:t} version ${VERSION}" | |
| exit 0 | |
| ;; | |
| -q|--quiet) | |
| QUIET=1 | |
| shift | |
| ;; | |
| -d|--dry-run) | |
| DRY_RUN=1 | |
| shift | |
| ;; | |
| -e|--ext) | |
| EXTENSIONS=(${(s:,:)2}) | |
| shift 2 | |
| ;; | |
| -*) | |
| echo "${RED}Error: Unknown option $1${NC}" >&2 | |
| show_help | |
| exit 1 | |
| ;; | |
| *) | |
| TARGET="$1" | |
| shift | |
| ;; | |
| esac | |
| done | |
| # Build find pattern | |
| pattern="*.(${(j:|:)EXTENSIONS})" | |
| # Find files | |
| if [[ -n "$TARGET" ]]; then | |
| if [[ -f "$TARGET" ]]; then | |
| files=("$TARGET") | |
| elif [[ -d "$TARGET" ]]; then | |
| files=("$TARGET"/**/$~pattern) | |
| else | |
| echo "${RED}Error: '$TARGET' is neither a file nor directory${NC}" >&2 | |
| exit 1 | |
| fi | |
| else | |
| files=(**/$~pattern) | |
| fi | |
| TOTAL_FILES=${#files[@]} | |
| # Exit if no files found | |
| if [[ $TOTAL_FILES -eq 0 ]]; then | |
| [[ $QUIET -eq 0 ]] && echo "${YELLOW}No files found with extensions: ${EXTENSIONS}${NC}" | |
| exit 0 | |
| fi | |
| # Processing function | |
| process_file() { | |
| local file="$1" | |
| local dir="${file:r}" | |
| local base="${file:t:r}" | |
| local cue="${dir}.cue" | |
| local bin="${dir}.bin" | |
| [[ $QUIET -eq 0 ]] && echo "${BLUE}Processing: ${file}${NC}" | |
| if [[ $DRY_RUN -eq 1 ]]; then | |
| [[ $QUIET -eq 0 ]] && echo " [DRY RUN] Would create: ${dir}/{${base}.cue,${base}.bin}" | |
| return 0 | |
| fi | |
| # Create directory | |
| if ! mkdir -p "$dir" 2>/dev/null; then | |
| echo "${RED}Error: Failed to create directory ${dir}${NC}" >&2 | |
| return 1 | |
| fi | |
| # Convert file | |
| if chdman extractcd -i "$file" -o "$cue" -ob "$bin"; then | |
| if mv "${cue}" "${bin}" "$dir/"; then | |
| [[ $QUIET -eq 0 ]] && echo "${GREEN} Success: Created ${dir}/{${base}.cue,${base}.bin}${NC}" | |
| return 0 | |
| else | |
| echo "${RED} Error: Failed to move output files to ${dir}${NC}" >&2 | |
| return 1 | |
| fi | |
| else | |
| echo "${RED} Error: CHDMAN conversion failed for ${file}${NC}" >&2 | |
| # Clean up partial files | |
| [[ -f "$cue" ]] && rm -f "$cue" | |
| [[ -f "$bin" ]] && rm -f "$bin" | |
| return 1 | |
| fi | |
| } | |
| # Main processing loop | |
| for file in $files; do | |
| if process_file "$file"; then | |
| ((SUCCESS_COUNT++)) | |
| else | |
| ((FAIL_COUNT++)) | |
| fi | |
| done | |
| # Summary | |
| if [[ $QUIET -eq 0 ]]; then | |
| echo "\n${BLUE}Conversion Summary:${NC}" | |
| echo " Total files: $TOTAL_FILES" | |
| echo " Successful: $SUCCESS_COUNT" | |
| echo " Failed: $FAIL_COUNT" | |
| echo " Time elapsed: $((SECONDS - START_TIME)) seconds" | |
| fi | |
| exit $((FAIL_COUNT > 0)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment