diff --git a/emu-configs/defaults/retrodeck/presets/Duckstation_presets.cfg b/emu-configs/defaults/retrodeck/presets/Duckstation_presets.cfg
new file mode 100644
index 00000000..4c45a705
--- /dev/null
+++ b/emu-configs/defaults/retrodeck/presets/Duckstation_presets.cfg
@@ -0,0 +1,6 @@
+config_file_format^duckstation
+target_file^$duckstationconf
+defaults_file^$emuconfigs/duckstation/settings.ini
+change^cheevos^Enabled^true^Cheevos
+change^cheevos^Username^$cheevos_username^Cheevos
+change^cheevos^Token^$cheevos_token^Cheevos
diff --git a/emu-configs/defaults/retrodeck/presets/PCSX2_presets.cfg b/emu-configs/defaults/retrodeck/presets/PCSX2_presets.cfg
new file mode 100644
index 00000000..07e77854
--- /dev/null
+++ b/emu-configs/defaults/retrodeck/presets/PCSX2_presets.cfg
@@ -0,0 +1,6 @@
+config_file_format^pcsx2
+target_file^$pcsx2qtconf
+defaults_file^$emuconfigs/PCSX2/PCSX2.ini
+change^cheevos^Enabled^true^Achievements
+change^cheevos^Username^$cheevos_username^Achievements
+change^cheevos^Token^$cheevos_token^Achievements
diff --git a/emu-configs/defaults/retrodeck/presets/RetroArch_presets.cfg b/emu-configs/defaults/retrodeck/presets/RetroArch_presets.cfg
new file mode 100644
index 00000000..946db0b9
--- /dev/null
+++ b/emu-configs/defaults/retrodeck/presets/RetroArch_presets.cfg
@@ -0,0 +1,7 @@
+config_file_format^retroarch-all
+target_file^$raconf
+defaults_file^$emuconfigs/retroarch/retroarch.cfg
+change^cheevos^cheevos_enable^true
+change^cheevos^cheevos_token^$cheevos_token
+change^cheevos^cheevos_username^$cheevos_username
+change^cheevos_hardcore^cheevos_hardcore_mode_enable^true
diff --git a/emu-configs/defaults/retrodeck/presets/SNES_presets.cfg b/emu-configs/defaults/retrodeck/presets/SNES_presets.cfg
new file mode 100644
index 00000000..0255c489
--- /dev/null
+++ b/emu-configs/defaults/retrodeck/presets/SNES_presets.cfg
@@ -0,0 +1,7 @@
+config_file_format^retroarch
+target_file^/var/config/retroarch/config/Snes9x/snes.cfg
+defaults_file^$emuconfigs/retroarch/retroarch.cfg
+change^cheevos^cheevos_enable^true
+change^cheevos^cheevos_token^$cheevos_token
+change^cheevos^cheevos_username^$cheevos_username
+change^cheevos_hardcore^cheevos_hardcore_mode_enable^true
diff --git a/emu-configs/defaults/retrodeck/presets/example.txt b/emu-configs/defaults/retrodeck/presets/example.txt
new file mode 100644
index 00000000..5891ec7c
--- /dev/null
+++ b/emu-configs/defaults/retrodeck/presets/example.txt
@@ -0,0 +1,11 @@
+config_file_format^retroarch # This is the config file format, used in functions like get_setting_value and set_setting_value
+target_file^$examplefile # This is the target file that should be updated. This will be the actively-used config file by whatever emulator is being set up. This can be a variable name as well!
+defaults_file^$emuconfigs/retroarch/retroarch.cfg # This is the file that is referenced when presets are disabled. This should be the "shipped" config file for this emulator
+change^cheevos^Enabled^true^Cheevos # This is a preset configuration line. The syntax is <action>^<preset name (as defined in retrodeck.cfg)>^<setting name>^<setting value when enabled>^<setting section in emulator config file, if there is one>
+change^borders^overlay_file^/var/config/retroarch/borders/snes.cfg # This is another preset configuration line, for the preset section called "borders" in retrodeck.cfg. Also, there is no defined "setting section" on this line
+
+
+OTHER NOTES:
+- The name of the presets configuration file for any given system MUST be <system name>_presets.cfg
+- The <system name> is whatever name is given to this system in retrodeck.cfg, it is not tied to the actual emulator name.
+- Whatever name is given to a system in retrodeck.cfg is how it will appear in the dialogs, so make it look nice. It also must match exactly in any preset sections it appears in!
diff --git a/emu-configs/defaults/retrodeck/reference_lists/incompatible_presets.cfg b/emu-configs/defaults/retrodeck/reference_lists/incompatible_presets.cfg
new file mode 100644
index 00000000..417ab816
--- /dev/null
+++ b/emu-configs/defaults/retrodeck/reference_lists/incompatible_presets.cfg
@@ -0,0 +1,2 @@
+borders:widescreen
+widescreen:borders
diff --git a/emu-configs/defaults/retrodeck/retrodeck.cfg b/emu-configs/defaults/retrodeck/retrodeck.cfg
index 52553139..c0146ef7 100644
--- a/emu-configs/defaults/retrodeck/retrodeck.cfg
+++ b/emu-configs/defaults/retrodeck/retrodeck.cfg
@@ -18,6 +18,7 @@ sdcard=/run/media/mmcblk0p1
 [options]
 power_user_warning=true
 desktop_mode_warning=true
+low_space_warning=true
 update_check=false
 update_repo=RetroDECK
 update_ignore=
@@ -27,14 +28,16 @@ ask_default_user=true
 default_user=
 developer_options=false
 
+[cheevos]
+PCSX2=false
+Duckstation=false
+SNES=false
+
+[cheevos_hardcore]
+SNES=false
+
 [borders]
-snes=false
-genesis=false
-gb=false
-gba=false
+SNES=false
 
 [widescreen]
-snes=false
-genesis=false
-gb=false
-gba=false
+SNES=false
diff --git a/functions.sh b/functions.sh
index 5402b7ba..1802ec4b 100644
--- a/functions.sh
+++ b/functions.sh
@@ -159,25 +159,29 @@ validate_for_chd() {
 		local file_base_name=$(basename "$file")
 		local file_name=${file_base_name%.*}
 		if [[ "$normalized_filename" == *".cue" ]]; then # Validate .cue file
-			echo "Validating .cue associated .bin files" >> "$logs_folder/$chd_validation_log_file"
-			local cue_bin_files=$(grep -o -P "(?<=FILE \").*(?=\".*$)" "$file")
-			echo "Associated bin files read:" >> "$logs_folder/$chd_validation_log_file"
-			printf '%s\n' "$cue_bin_files" >> "$logs_folder/$chd_validation_log_file"
-			if [[ ! -z "$cue_bin_files" ]]; then
-        while IFS= read -r line
-        do
-          echo "looking for $file_path/$line" >> "$logs_folder/$chd_validation_log_file"
-          if [[ -f "$file_path/$line" ]]; then
-            echo ".bin file found at $file_path/$line" >> "$logs_folder/$chd_validation_log_file"
-            file_validated="true"
-          else
-            echo ".bin file NOT found at $file_path/$line" >> "$logs_folder/$chd_validation_log_file"
-            echo ".cue file could not be validated. Please verify your .cue file contains the correct corresponding .bin file information and retry." >> "$logs_folder/$chd_validation_log_file"
-            file_validated="false"
-            break
-          fi
-        done < <(printf '%s\n' "$cue_bin_files")
-			fi
+			if [[ ! "$file_path" == *"dreamcast"* ]]; then # .bin/.cue compression may not work for Dreamcast, only GDI or ISO # TODO: verify
+        echo "Validating .cue associated .bin files" >> "$logs_folder/$chd_validation_log_file"
+        local cue_bin_files=$(grep -o -P "(?<=FILE \").*(?=\".*$)" "$file")
+        echo "Associated bin files read:" >> "$logs_folder/$chd_validation_log_file"
+        printf '%s\n' "$cue_bin_files" >> "$logs_folder/$chd_validation_log_file"
+        if [[ ! -z "$cue_bin_files" ]]; then
+          while IFS= read -r line
+          do
+            echo "looking for $file_path/$line" >> "$logs_folder/$chd_validation_log_file"
+            if [[ -f "$file_path/$line" ]]; then
+              echo ".bin file found at $file_path/$line" >> "$logs_folder/$chd_validation_log_file"
+              file_validated="true"
+            else
+              echo ".bin file NOT found at $file_path/$line" >> "$logs_folder/$chd_validation_log_file"
+              echo ".cue file could not be validated. Please verify your .cue file contains the correct corresponding .bin file information and retry." >> "$logs_folder/$chd_validation_log_file"
+              file_validated="false"
+              break
+            fi
+          done < <(printf '%s\n' "$cue_bin_files")
+        fi
+      else
+        echo ".cue files not compatible with Dreamcast CHD compression" >> "$logs_folder/$chd_validation_log_file"
+      fi
       echo $file_validated
 		else # If file is a .iso or .gdi
       file_validated="true"
@@ -290,6 +294,7 @@ desktop_mode_warning() {
   # This function is a generic warning for issues that happen when running in desktop mode.
   # Running in desktop mode can be verified with the following command: if [[ ! $XDG_CURRENT_DESKTOP == "gamescope" ]]; then
   # This function will check if desktop mode is currently being used and if the warning has not been disabled, and show it if needed.
+  # USAGE: desktop_mode_warning
 
   if [[ ! $XDG_CURRENT_DESKTOP == "gamescope" ]]; then
     if [[ $desktop_mode_warning == "true" ]]; then
@@ -302,13 +307,31 @@ desktop_mode_warning() {
         if [[ $choice == "No" ]]; then
           exit 1
         elif [[ $choice == "Never show this again" ]]; then
-          set_setting_value $rd_conf "desktop_mode_warning" "false" retrodeck  "options" # Store desktop mode warning variable for future checks
+          set_setting_value $rd_conf "desktop_mode_warning" "false" retrodeck "options" # Store desktop mode warning variable for future checks
         fi
       fi
     fi
   fi
 }
 
+low_space_warning() {
+  # This function will verify that the drive with the $HOME path on it has at least 10% space free, so the user can be warned before it fills up
+  # USAGE: low_space_warning
+
+  if [[ $low_space_warning == "true" ]]; then
+    local used_percent=$(df --output=pcent "$HOME" | tail -1 | tr -d " " | tr -d "%")
+    if [[ "$used_percent" -ge 90 && -d "$HOME/retrodeck" ]]; then # If there is any RetroDECK data on the main drive to move
+      choice=$(zenity --icon-name=net.retrodeck.retrodeck --info --no-wrap --ok-label="OK" --extra-button="Never show this again" \
+      --window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
+      --title "RetroDECK Low Space Warning" \
+      --text="Your main drive is over 90% full!\n\nIf your drive fills completely this can lead to data loss or system crash.\n\nPlease consider moving some RetroDECK folders to other storage locations using the Configurator.")
+      if [[ $choice == "Never show this again" ]]; then
+          set_setting_value $rd_conf "low_space_warning" "false" retrodeck "options" # Store low space warning variable for future checks
+      fi
+    fi
+  fi
+}
+
 set_setting_value() {
   # Function for editing settings
   # USAGE: set_setting_value $setting_file "$setting_name" "$new_setting_value" $system $section_name(optional)
@@ -456,6 +479,46 @@ add_setting_line() {
   esac
 }
 
+add_setting() {
+  # This function will add a setting name and value to a file. This is useful for dynamically generated config files like Retroarch override files.
+  # USAGE: add_setting $setting_file $setting_name $setting_value $system $section (optional)
+
+  local current_setting_name=$(sed -e 's^\\^\\\\^g;s^`^\\`^g' <<< "$2")
+  local current_setting_value=$(sed -e 's^\\^\\\\^g;s^`^\\`^g' <<< "$3")
+  local current_section_name=$(sed -e 's/%/\\%/g' <<< "$5")
+
+  case $4 in
+
+  "retroarch" )
+    if [[ -z $current_section_name ]]; then
+      sed -i '$ a '"$current_setting_name"' = "'"$current_setting_value"'"' $1
+    else
+      sed -i '/^\s*?\['"$current_section_name"'\]|\b'"$current_section_name"':$/a '"$current_setting_name"' = "'"$current_setting_value"'"' $1
+    fi
+    ;;
+
+  esac
+}
+
+delete_setting() {
+  # This function will delete a setting line from a file. This is useful for dynamically generated config files like Retroarch override files
+  # USAGE: delete_setting $setting_file $setting_name $system $section (optional)
+
+  local current_setting_name=$(sed -e 's^\\^\\\\^g;s^`^\\`^g' <<< "$2")
+  local current_section_name=$(sed -e 's/%/\\%/g' <<< "$4")
+
+  case $3 in
+
+  "retroarch" )
+    if [[ -z $current_section_name ]]; then
+      sed -i '\^'"$current_setting_name"'^d' "$1"
+      sed -i '/^$/d' "$1" # Cleanup empty lines left behind
+    fi
+    ;;
+
+  esac
+}
+
 disable_setting() {
   # This function will add a '#' to the beginning of a defined setting line, disabling it.
   # USAGE: disable_setting $setting_file $setting_line $system $section (optional)
@@ -512,6 +575,100 @@ enable_file() {
   mv $(realpath $1.disabled) $(realpath $(echo $1 | sed -e 's/\.disabled//'))
 }
 
+build_preset_config(){
+  # This function will apply one or more presets for a given system, as listed in retrodeck.cfg
+  # USAGE: build_preset_config "system name" "preset class 1" "preset class 2" "preset class 3"
+  
+  local system_being_changed="$1"
+  shift
+  local presets_being_changed="$*"
+  for preset in $presets_being_changed
+  do
+    current_preset="$preset"
+    local preset_section=$(sed -n '/\['"$current_preset"'\]/, /\[/{ /\['"$current_preset"'\]/! { /\[/! p } }' $rd_conf | sed '/^$/d')
+    while IFS= read -r system_line
+    do
+      local read_system_name=$(get_setting_name "$system_line")
+      if [[ "$read_system_name" == "$system_being_changed" ]]; then
+        local read_system_enabled=$(get_setting_value "$rd_conf" "$read_system_name" "retrodeck" "$current_preset")
+        while IFS='^' read -r action read_preset read_setting_name new_setting_value section
+        do
+          case "$action" in
+
+          "config_file_format" )
+            local read_config_format="$read_preset"
+          ;;
+
+          "target_file" )
+            if [[ "$read_preset" = \$* ]]; then
+              eval read_preset=$read_preset
+            fi
+            local read_target_file="$read_preset"
+          ;;
+
+          "defaults_file" )
+            if [[ "$read_preset" = \$* ]]; then
+              eval read_preset=$read_preset
+            fi
+            local read_defaults_file="$read_preset"
+          ;;
+
+          "change" )
+            if [[ "$read_preset" == "$current_preset" ]]; then
+              if [[ "$read_system_enabled" == "true" ]]; then
+                if [[ "$new_setting_value" = \$* ]]; then
+                  eval new_setting_value=$new_setting_value
+                fi
+                if [[ "$read_config_format" == "retroarch" ]]; then # If this is a RetroArch core, generate the override file
+                  if [[ -z $(grep "$read_setting_name" "$read_target_file") ]]; then
+                    if [[ ! -f "$read_target_file" ]]; then
+                      mkdir -p "$(realpath $(dirname "$read_target_file"))"
+                      echo "$read_setting_name = ""$new_setting_value""" > "$read_target_file"
+                    else
+                      add_setting "$read_target_file" "$read_setting_name" "$new_setting_value" "$read_config_format" "$section"
+                    fi
+                  else
+                    set_setting_value "$read_target_file" "$read_setting_name" "$new_setting_value" "$read_config_format" "$section"
+                  fi
+                else
+                  if [[ "$read_config_format" == "retroarch-all" ]]; then
+                    read_config_format="retroarch"
+                  fi
+                  set_setting_value "$read_target_file" "$read_setting_name" "$new_setting_value" "$read_config_format" "$section"
+                fi
+              else
+                if [[ "$read_config_format" == "retroarch" ]]; then
+                  if [[ -f "$read_target_file" ]]; then
+                    delete_setting "$read_target_file" "$read_setting_name" "$read_config_format" "$section"
+                    if [[ -z $(cat "$read_target_file") ]]; then # If the override file is empty
+                      rm -f "$read_target_file"
+                    fi
+                    if [[ -z $(ls -1 $(dirname "$read_target_file")) ]]; then # If the override folder is empty
+                      rmdir "$(dirname $read_target_file)"
+                    fi
+                  fi
+                else
+                  if [[ "$read_config_format" == "retroarch-all" ]]; then
+                    read_config_format="retroarch"
+                  fi
+                  local default_setting_value=$(get_setting_value "$read_defaults_file" "$read_setting_name" "$read_config_format" "$section")
+                  set_setting_value "$read_target_file" "$read_setting_name" "$default_setting_value" "$read_config_format" "$section"
+                fi
+              fi
+            fi
+          ;;
+
+          * )
+            echo "Other data: $action $read_preset $read_setting_name $new_setting_value $section" # DEBUG
+          ;;
+
+          esac
+        done < <(eval cat "$presets_dir/$read_system_name"_presets.cfg)
+      fi
+    done < <(printf '%s\n' "$preset_section")
+  done
+}
+
 generate_single_patch() {
   # generate_single_patch $original_file $modified_file $patch_file $system
 
@@ -808,7 +965,7 @@ update_rd_conf() {
   cp $rd_defaults $rd_conf # Copy defaults file into place
   conf_write # Write old values into new default file
 
-  # STAGE 2: To handle feature sections that use duplicate setting names
+  # STAGE 2: To handle presets sections that use duplicate setting names
 
   mv -f $rd_conf $rd_conf_backup # Backup config file agiain before update but after Stage 1 expansion
   generate_single_patch $rd_defaults $rd_conf_backup $rd_update_patch retrodeck # Create a patch file for differences between defaults and current user settings
@@ -2390,12 +2547,116 @@ configurator_move_folder_dialog() {
 
 changelog_dialog() {
   # This function will pull the changelog notes from the version it is passed (which must match the appdata version tag) from the net.retrodeck.retrodeck.appdata.xml file
+  # The function also accepts "all" as a version, and will print the entire changelog
   # USAGE: changelog_dialog "version"
 
-  changelog=$(xml sel -t -m "//release[@version='$1']/description" -v . -n $rd_appdata | tr -s '\n' | sed 's/^\s*//')
+  if [[ "$1" == "all" ]]; then
+    xmlstarlet sel -t -m "//release" -v "concat('RetroDECK version: ', @version)" -n -v "description" -n $rd_appdata | awk '{$1=$1;print}' | sed -e '/./b' -e :n -e 'N;s/\n$//;tn' > "/var/config/retrodeck/changelog.txt"
 
-  zenity --icon-name=net.retrodeck.retrodeck --info --no-wrap \
-  --window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
-  --title "RetroDECK Changelogs" \
-  --text="Welcome to RetroDECK version $1!\n\nHere are the changes that were made in this version:\n$changelog"
+    zenity --icon-name=net.retrodeck.retrodeck --text-info --width=1200 --height=720 \
+    --window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
+    --title "RetroDECK Changelogs" \
+    --filename="/var/config/retrodeck/changelog.txt"
+  else
+    local version_changelog=$(xml sel -t -m "//release[@version='$1']/description" -v . -n $rd_appdata | tr -s '\n' | sed 's/^\s*//')
+
+    zenity --icon-name=net.retrodeck.retrodeck --info --no-wrap \
+    --window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
+    --title "RetroDECK Changelogs" \
+    --text="In RetroDECK version $1, the following changes were made:\n$version_changelog"
+    fi
+}
+
+get_cheevos_token_dialog() {
+  # This function will return a RetroAchvievements token from a valid username and password, will return "login failed" otherwise
+  # USAGE: get_cheevos_token_dialog
+
+  local cheevos_info=$(zenity --forms --title="Cheevos" \
+  --text="Username and password." \
+  --separator="^" \
+  --add-entry="Username" \
+  --add-password="Password")
+
+  IFS='^' read -r cheevos_username cheevos_password < <(printf '%s\n' "$cheevos_info")
+  cheevos_token=$(curl --silent --data "r=login&u=$cheevos_username&p=$cheevos_password" $RA_API_URL | jq .Token | tr -d '"')
+  if [[ ! "$cheevos_token" == "null" ]]; then
+    echo "$cheevos_username,$cheevos_token"
+  else
+    echo "failed"
+  fi
+}
+
+
+
+change_preset_dialog() {
+  # This function will build a list of all systems compatible with a given preset, their current enable/disabled state and allow the user to change one or more
+  # USAGE: change_preset_dialog "$preset"
+
+  local preset="$1"
+  pretty_preset_name=${preset//_/ } # Preset name prettification
+  pretty_preset_name=$(echo $pretty_preset_name | awk '{for(i=1;i<=NF;i++){$i=toupper(substr($i,1,1))substr($i,2)}}1') # Preset name prettification
+  local current_preset_settings=()
+  local current_enabled_systems=()
+  local current_disabled_systems=()
+  local changed_systems=()
+  local changed_presets=()
+  local section_results=$(sed -n '/\['"$preset"'\]/, /\[/{ /\['"$preset"'\]/! { /\[/! p } }' $rd_conf | sed '/^$/d')
+
+  while IFS= read -r config_line
+    do
+      system_name=$(get_setting_name "$config_line" "retrodeck")
+      all_systems=("${all_systems[@]}" "$system_name")
+      system_value=$(get_setting_value "$rd_conf" "$system_name" "retrodeck" "$preset")
+      if [[ "$system_value" == "true" ]]; then
+        current_enabled_systems=("${current_enabled_systems[@]}" "$system_name")
+      elif [[ "$system_value" == "false" ]]; then
+        current_disabled_systems=("${current_disabled_systems[@]}" "$system_name")
+      fi
+      current_preset_settings=("${current_preset_settings[@]}" "$system_value" "$system_name")
+  done < <(printf '%s\n' "$section_results")
+
+  choice=$(zenity \
+    --list --width=1200 --height=720 \
+    --checklist \
+    --separator="," \
+    --text="Enable $pretty_preset_name:" \
+    --column "Enabled" \
+    --column "Emulator" \
+    "${current_preset_settings[@]}")
+
+  local rc=$?
+
+  if [[ ! -z $choice || "$rc" == 0 ]]; then
+    IFS="," read -ra choices <<< "$choice"
+    for emulator in "${all_systems[@]}"; do
+      if [[ " ${choices[*]} " =~ " ${emulator} " && ! " ${current_enabled_systems[*]} " =~ " ${emulator} " ]]; then
+        changed_systems=("${changed_systems[@]}" "$emulator")
+        if [[ ! " ${changed_presets[*]} " =~ " ${preset} " ]]; then
+          changed_presets=("${changed_presets[@]}" "$preset")
+        fi
+        set_setting_value "$rd_conf" "$emulator" "true" "retrodeck" "$preset"
+        # Check for conflicting presets for this system
+        while IFS=: read -r preset_being_checked known_incompatible_preset; do
+          if [[ "$preset" == "$preset_being_checked" ]]; then
+            if [[ $(get_setting_value "$rd_conf" "$emulator" "retrodeck" "$known_incompatible_preset") == "true" ]]; then
+              changed_presets=("${changed_presets[@]}" "$known_incompatible_preset")
+              set_setting_value "$rd_conf" "$emulator" "false" "retrodeck" "$known_incompatible_preset"
+            fi
+          fi
+        done < "$incompatible_presets_reference_list"
+      fi
+      if [[ ! " ${choices[*]} " =~ " ${emulator} " && ! " ${current_disabled_systems[*]} " =~ " ${emulator} " ]]; then
+        changed_systems=("${changed_systems[@]}" "$emulator")
+        if [[ ! " ${changed_presets[*]} " =~ " ${preset} " ]]; then
+          changed_presets=("${changed_presets[@]}" "$preset")
+        fi
+        set_setting_value "$rd_conf" "$emulator" "false" "retrodeck" "$preset"
+      fi
+    done
+    for emulator in "${changed_systems[@]}"; do
+      build_preset_config $emulator ${changed_presets[*]}
+    done
+  else
+    echo "No choices made"
+  fi
 }
diff --git a/global.sh b/global.sh
index 1f8ca2fd..c520856e 100755
--- a/global.sh
+++ b/global.sh
@@ -33,6 +33,9 @@ helper_files_folder="$emuconfigs/defaults/retrodeck/helper_files"
 helper_files_list="$emuconfigs/defaults/retrodeck/reference_lists/helper_files_list.cfg"                              # The list of files to be deployed and where they go
 rd_appdata="/app/share/appdata/net.retrodeck.retrodeck.appdata.xml"                                                   # The shipped appdata XML file for this version
 rpcs3_firmware="http://dus01.ps3.update.playstation.net/update/ps3/image/us/2023_0228_05fe32f5dc8c78acbcd84d36ee7fdc5b/PS3UPDAT.PUP"
+RA_API_URL="https://retroachievements.org/dorequest.php"                                                              # API URL for RetroAchievements.org
+presets_dir="$emuconfigs/defaults/retrodeck/presets"
+incompatible_presets_reference_list="$emuconfigs/defaults/retrodeck/reference_lists/incompatible_presets.cfg"
 
 # Config files for emulators with single config files
 
diff --git a/rd-submodules/retroarch b/rd-submodules/retroarch
index 717b7809..0b1cfb79 160000
--- a/rd-submodules/retroarch
+++ b/rd-submodules/retroarch
@@ -1 +1 @@
-Subproject commit 717b78093797270877ec416e58082f1c71d435d8
+Subproject commit 0b1cfb79e591e10488a3262d6b38db843c39a409
diff --git a/rd-submodules/shared-modules b/rd-submodules/shared-modules
index a337dd0c..a2441b96 160000
--- a/rd-submodules/shared-modules
+++ b/rd-submodules/shared-modules
@@ -1 +1 @@
-Subproject commit a337dd0c6b7209a316dc6fa142323972e128c85d
+Subproject commit a2441b964afefd8cd1cebcdf562c7878670daf42
diff --git a/retrodeck.sh b/retrodeck.sh
index 9b7195aa..296ebb6a 100644
--- a/retrodeck.sh
+++ b/retrodeck.sh
@@ -154,9 +154,10 @@ if [[ $multi_user_mode == "true" ]]; then
   multi_user_determine_current_user
 fi
 
-# Check if running in Desktop mode and warn if true, unless desktop_mode_warning=false in retrodeck.cfg
+# Run optional startup checks
 
 desktop_mode_warning
+low_space_warning
 
 # Check if there is a new version of RetroDECK available, if update_check=true in retrodeck.cfg and there is network connectivity available.
 if [[ $(check_network_connectivity) == "true" ]] && [[ $update_check == "true" ]]; then
diff --git a/tools/configurator.sh b/tools/configurator.sh
index a002f62f..1b226be5 100644
--- a/tools/configurator.sh
+++ b/tools/configurator.sh
@@ -10,11 +10,13 @@ source /app/libexec/functions.sh
 # Configurator Option Tree
 
 # Welcome
+#     - RetroDECK Presets
+#       - Enable/Disable borders
+#       - Enable/Disable widescreen
+#       - Log in to RetroAchievements
 #     - RetroArch Presets
 #       - Change Rewind Setting
 #         - Enable/Disable Rewind
-#       - RetroAchivement Login
-#         - Login prompt
 #     - Dolphin Presets
 #       - Enable/Disable Custom Input Textures
 #     - Primehack Presets
@@ -35,14 +37,13 @@ source /app/libexec/functions.sh
 #     - Tools and Troubleshooting
 #       - Move RetroDECK or subfolders
 #       - Multi-file game check
-#       - Basic BIOS file check
-#       - Advanced BIOS file check
+#       - BIOS file check
 #       - Compress Games
 #         - Manual single-game selection
-#         - Multi-file compression (CHD)
-#       - Download ES themes
+#         - Multi-file compression
 #       - Download PS3 firmware
 #       - Install RetroDECK controller profile
+#       - Install RetroDECK Starter Pack
 #       - Backup RetroDECK userdata
 #     - Reset
 #       - Reset Specific Emulator
@@ -60,6 +61,15 @@ source /app/libexec/functions.sh
 #           - Reset Yuzu
 #       - Reset All Emulators
 #       - Reset RetroDECK
+#     - About RetroDECK
+#       - Version History
+#         - Full changelog
+#         - Version-specific changelogs
+#     - Developer Options (Hidden)
+#       - Change Multi-user mode
+#       - Change Update channel
+#       - Change Update check setting
+#       - Browse the wiki
 
 # DIALOG TREE FUNCTIONS
 
@@ -284,6 +294,50 @@ configurator_power_user_changes_dialog() {
   esac
 }
 
+configurator_retrodeck_presets_dialog() {
+  choice=$(zenity --list --title="RetroDECK Configurator Utility - RetroDECK Presets" --cancel-label="Back" \
+  --window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" --width=1200 --height=720 \
+  --column="Choice" --column="Action" \
+  "Enable/Disable Borders" "Enable or disable borders in supported systems" \
+  "Enable/Disable Widescreen" "Enable or disable widescreen in supported systems" \
+  "RetroAchievements Login" "Log into the RetroAchievements service in supported emulators" \
+  "RetroAchievements Hardcore Mode" "Enable RetroAchievements hardcore mode (no cheats, rewind, save states etc.) in supported emulators" )
+
+  case $choice in
+
+  "Enable/Disable Borders" )
+    change_preset_dialog "borders"
+    configurator_retrodeck_presets_dialog
+  ;;
+
+  "Enable/Disable Widescreen" )
+    change_preset_dialog "widescreen"
+    configurator_retrodeck_presets_dialog
+  ;;
+
+  "RetroAchievements Login" )
+    cheevos_response=$(get_cheevos_token_dialog)
+    if [[ ! "$cheevos_response" == "failed" ]]; then
+      IFS=',' read -r cheevos_username cheevos_token < <(printf '%s\n' "$cheevos_response")
+      change_preset "cheevos"
+    else
+      configurator_generic_dialog "RetroDECK Configurator Utility - RetroDECK Presets" "RetroAchievements login failed, please verify your username and password and try the process again."
+    fi
+    configurator_retrodeck_presets_dialog
+  ;;
+
+  "RetroAchievements Hardcore Mode" )
+    change_preset_dialog "cheevos_hardcore"
+    configurator_retrodeck_presets_dialog
+  ;;
+
+  "" ) # No selection made or Back button clicked
+    configurator_welcome_dialog
+  ;;
+
+  esac
+}
+
 configurator_retroarch_rewind_dialog() {
   if [[ $(get_setting_value $raconf rewind_enable retroarch) == "true" ]]; then
     zenity --question \
@@ -318,8 +372,7 @@ configurator_retroarch_presets_dialog() {
   choice=$(zenity --list --title="RetroDECK Configurator Utility - RetroArch Options" --cancel-label="Back" \
   --window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" --width=1200 --height=720 \
   --column="Choice" --column="Action" \
-  "Change Rewind Setting" "Enable or disable the Rewind function in RetroArch." \
-  "RetroAchievements Login" "Log into the RetroAchievements service in RetroArch." )
+  "Change Rewind Setting" "Enable or disable the Rewind function in RetroArch." )
 
   case $choice in
 
@@ -327,10 +380,6 @@ configurator_retroarch_presets_dialog() {
     configurator_retroarch_rewind_dialog
   ;;
 
-  "RetroAchievements Login" )
-    configurator_retroachivement_dialog
-  ;;
-
   "" ) # No selection made or Back button clicked
     configurator_welcome_dialog
   ;;
@@ -1061,10 +1110,59 @@ configurator_retrodeck_multiuser_dialog() {
   fi
 }
 
-configurator_developer_dialog() {
-  choice=$(zenity --list --title="RetroDECK Configurator Utility - Change Options" --cancel-label="Back" \
+configurator_version_history_dialog() {
+  local version_array=($(xmlstarlet sel -t -v '//component/releases/release/@version' -n $rd_appdata))
+  local all_versions_list=()
+
+  for rd_version in ${version_array[*]}; do
+    all_versions_list=("${all_versions_list[@]}" "RetroDECK $rd_version Changelog" "View the changes specific to version $rd_version")
+  done
+  
+  choice=$(zenity --list --title="RetroDECK Configurator Utility - RetroDECK Version History" --cancel-label="Back" \
   --window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" --width=1200 --height=720 \
-  --column="Choice" --column="Action" \
+  --column="Choice" --column="Description" \
+  "Full RetroDECK Changelog" "View the list of all changes that have ever been made to RetroDECK" \
+  "${all_versions_list[@]}")
+
+  case $choice in
+
+  "Full RetroDECK Changelog" )
+    changelog_dialog "all"
+  ;;
+
+  "RetroDECK"*"Changelog" )
+    local version=$(echo "$choice" | sed 's/^RetroDECK \(.*\) Changelog$/\1/')
+    changelog_dialog "$version"
+  ;;
+
+  esac
+
+  configurator_about_retrodeck_dialog
+}
+
+configurator_about_retrodeck_dialog() {
+  choice=$(zenity --list --title="RetroDECK Configurator Utility - About RetroDECK" --cancel-label="Back" \
+  --window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" --width=1200 --height=720 \
+  --column="Choice" --column="Description" \
+  "Version History" "View the version changelogs for RetroDECK" )
+
+  case $choice in
+
+  "Version History" )
+    configurator_version_history_dialog
+  ;;
+
+  "" ) # No selection made or Back button clicked
+    configurator_welcome_dialog
+  ;;
+
+  esac
+}
+
+configurator_developer_dialog() {
+  choice=$(zenity --list --title="RetroDECK Configurator Utility - Developer Options" --cancel-label="Back" \
+  --window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" --width=1200 --height=720 \
+  --column="Choice" --column="Description" \
   "Change Multi-user mode" "Enable or disable multi-user support" \
   "Change Update Channel" "Change between normal and cooker builds" \
   "Change Update Check Setting" "Enable or disable online checks for new versions of RetroDECK" \
@@ -1096,20 +1194,24 @@ configurator_developer_dialog() {
 
 configurator_welcome_dialog() {
   if [[ $developer_options == "true" ]]; then
-    welcome_menu_options=("RetroArch Presets" "Change RetroArch presets, log into RetroAchievements etc." \
+    welcome_menu_options=("RetroDECK Presets" "Change RetroDECK presets, log into RetroAchievements etc." \
+    "RetroArch Presets" "Change available RetroArch presets" \
     "Dolphin Presets" "Change available Dolphin presets" \
     "Primehack Presets" "Change available Primehack presets" \
     "Emulator Options" "Launch and configure each emulators settings (for advanced users)" \
     "Tools and Troubleshooting" "Move RetroDECK to a new location, compress games and perform basic troubleshooting" \
     "Reset" "Reset specific parts or all of RetroDECK" \
+    "About RetroDECK" "Show additional information about RetroDECK" \
     "Developer Options" "Welcome to the DANGER ZONE")
   else
-    welcome_menu_options=("RetroArch Presets" "Change RetroArch presets, log into RetroAchievements etc." \
+    welcome_menu_options=("RetroDECK Presets" "Change RetroDECK presets, log into RetroAchievements etc." \
+    "RetroArch Presets" "Change available RetroArch presets" \
     "Dolphin Presets" "Change available Dolphin presets" \
     "Primehack Presets" "Change available Primehack presets" \
     "Emulator Options" "Launch and configure each emulators settings (for advanced users)" \
     "Tools and Troubleshooting" "Move RetroDECK to a new location, compress games and perform basic troubleshooting" \
-    "Reset" "Reset specific parts or all of RetroDECK" )
+    "Reset" "Reset specific parts or all of RetroDECK" \
+    "About RetroDECK" "Show additional information about RetroDECK")
   fi
 
   choice=$(zenity --list --title="RetroDECK Configurator Utility" --cancel-label="Quit" \
@@ -1119,6 +1221,10 @@ configurator_welcome_dialog() {
 
   case $choice in
 
+  "RetroDECK Presets" )
+    configurator_retrodeck_presets_dialog
+  ;;
+
   "RetroArch Presets" )
     configurator_retroarch_presets_dialog
   ;;
@@ -1143,6 +1249,10 @@ configurator_welcome_dialog() {
     configurator_reset_dialog
   ;;
 
+  "About RetroDECK" )
+    configurator_about_retrodeck_dialog
+  ;;
+
   "Developer Options" )
     configurator_generic_dialog "RetroDECK Configurator - Developer Options" "The following features and options are potentially VERY DANGEROUS for your RetroDECK install!\n\nThey should be considered the bleeding-edge of upcoming RetroDECK features, and never used when you have important saves/states/roms that are not backed up!\n\nYOU HAVE BEEN WARNED!"
     configurator_developer_dialog