diff --git a/functions/crc32.py b/functions/crc32.py new file mode 100644 index 00000000..4dc8bf46 --- /dev/null +++ b/functions/crc32.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python +import os, sys +import zlib + +def crc32(fileName): + prev = 0 + for eachLine in open(fileName,"rb"): + prev = zlib.crc32(eachLine, prev) + return "%X"%(prev & 0xFFFFFFFF) + +print(crc32(sys.argv[1]).lower()) diff --git a/functions/game_downloader.sh b/functions/game_downloader.sh new file mode 100755 index 00000000..d85015da --- /dev/null +++ b/functions/game_downloader.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +game_downloader_setup() { + crc32_cmd="python3 /app/libexec/crc32.py" + + # "hacks" is the general name which includes ROM Hacks, Homebrew and Ports + hacks_repo_url="https://raw.githubusercontent.com/Libretto7/best-romhacks/main" + hacks_db_path="$HOME/.var/app/net.retrodeck.retrodeck/data/hacks_metadata.db" + + # set up hacks database + sqlite3 $hacks_db_path < <(curl -sL "$hacks_repo_url"/db_setup.sql) + + declare -g hacks_db_cmd="sqlite3 $hacks_db_path" +} + +collect_base_rom_crc32s() { + # Register all crc32 checksums of potential base ROMs and their paths into the dictionary "base_roms" + + declare -gA base_roms + + for rom in ${roms_folder}/*/*; do + if [[ "$(basename "$rom")" != "systeminfo.txt" ]]; then + crc32="$($crc32_cmd "$rom")" + base_roms["$crc32"]="$rom" + fi + done +} + +build_patches_array() { + # Set up array that contains the names of patches compatible with available base ROMs + + declare -ga compatible_romhack_patches=() + + for base_crc32 in "${!base_roms[@]}"; do + + current_base_compatible_patches="$($hacks_db_cmd "SELECT name FROM main WHERE base_crc32 = '""$base_crc32""'")" + + if [[ ! -z "$(printf "$current_base_compatible_patches")" ]]; then # if there are compatible patches for this base + # Add available patches to array + + # TODO: Remove redundancy within this line. Puts the patches names separated by newlines into an array + IFS='|' read -r -a array_of_compatible_patches <<< $(echo "$current_base_compatible_patches" | tr '\n' '|') + + for patch in "${array_of_compatible_patches[@]}"; do + compatible_romhack_patches+=("$patch") + done + fi + done +} + +get_compatible_romhacks() { + # Provide global array "compatible_romhack_patches" which contains names of available, compatible romhack patches + + game_downloader_setup + collect_base_rom_crc32s + build_patches_array +} diff --git a/tools/configurator.sh b/tools/configurator.sh index cebebeab..470343bf 100644 --- a/tools/configurator.sh +++ b/tools/configurator.sh @@ -97,6 +97,7 @@ source /app/libexec/global.sh # - Browse the wiki # - USB Import tool # - Install: RetroDECK Starter Pack +# - Game Downloader # DIALOG TREE FUNCTIONS @@ -1176,7 +1177,8 @@ configurator_developer_dialog() { "Change Update Channel" "Change between normal and cooker builds" \ "Browse the Wiki" "Browse the RetroDECK wiki online" \ "USB Import" "Prepare a USB device for ROMs or import an existing collection" \ - "Install RetroDECK Starter Pack" "Install the optional RetroDECK starter pack" ) + "Install RetroDECK Starter Pack" "Install the optional RetroDECK starter pack" \ + "Game Downloader" "Install ROM Hacks, Homebrew or Ports" ) case $choice in @@ -1204,6 +1206,10 @@ configurator_developer_dialog() { configurator_developer_dialog ;; + "Game Downloader" ) + configurator_game_downloader_dialog + ;; + "" ) # No selection made or Back button clicked configurator_welcome_dialog ;; @@ -1355,6 +1361,64 @@ configurator_usb_import_dialog() { } +configurator_game_downloader_dialog() { + choice=$(zenity --list --title="RetroDECK Configurator Utility - Game Downloader" --cancel-label="Back" \ + --window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" --width=1200 --height=720 \ + --column="Choice" --column="Description" \ + "ROM Hack Downloader" "Install ROM Hacks which are compatible with your ROMs (Right now: Only shows compatible ROMs with Super Mario World (USA) and Super Mario Bros. (World). Can't download.)" \ + "Homebrew Downloader" "Install Homebrew (Not yet functional)" \ + "Ports Downloader" "Install Ports (Not yet functional)" ) + + case $choice in + + "ROM Hack Downloader" ) + configurator_romhack_downloader_dialog + ;; + + "Homebrew Downloader" ) + configurator_developer_dialog + ;; + + "Ports Downloader" ) + configurator_developer_dialog + ;; + + "" ) # No selection made or Back button clicked + configurator_welcome_dialog + ;; + + esac +} + +configurator_romhack_downloader_dialog() { + + get_compatible_romhacks # creates compatible_romhack_patches array + + zenity_columns=() + for hack_name in "${compatible_romhack_patches[@]}"; do + + # Get romhack info + sanitized_name="$(echo "$hack_name" | sed -e "s/'/''/g")" + hack_info="$($hacks_db_cmd "SELECT released,retro_achievements,description FROM main WHERE name = '""$sanitized_name""'")" + IFS='|' read -r -a hack_info_array <<< "$hack_info" + + # Add row of hack info + zenity_columns+=("$hack_name") + for info in "${hack_info_array[@]}"; do + zenity_columns+=("$info") + done + done + + choice=$(zenity --list --title="RetroDECK Configurator Utility - Game Downloader: ROM Hacks" --cancel-label="Back" \ + --window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" --width=1200 --height=720 \ + --column="ROM Hack Name" --column="Released" --column="Retro Achievements" --column="Description" \ + "${zenity_columns[@]}" ) + + echo "$choice" + + configurator_welcome_dialog +} + # START THE CONFIGURATOR configurator_welcome_dialog