11#! /usr/bin/env bash
22# input_selection.sh
33# ####################
4- # Let the user choose what controller to use for Player 1-4.
4+ # Let the user choose what controller to use for RetroArch Player 1-4.
55#
6- # This program relies on the output of the jslist program. The jslist is
7- # a small program I wrote to detect and list the joysticks connected to the
8- # system and their respective indexes. The output format of jslist is
9- # index:Joystick Name
6+ # This program relies on the output of the jslist program.
107#
11- # Example:
12- # [prompt]$ jslist
13- # 0:Twin USB Joystick
14- # 1:Twin USB Joystick
15- # 2:ipega Extending Game Controller
16- # 3:8Bitdo Zero Game Pad
8+ # See the description at https://github.com/meleu/RetroPie-input-selection
179#
1810#
1911# TODO:
20- # - show the current config (with the joystick names) before start
21- # and let the user quit.
22- # - show the config at the end and let the user confirm.
12+ # - [robustness] alert the user if the Player 1 has no joystick.
2313# - [robustness] verify if the "#include ...input-selection.cfg" line
2414# is before any input_playerN_joypad_index in the retroarch.cfg.
2515# - [robustness] verify if the input-selection.cfg has all the 4
2616# input_playerN_joypad_index; if don't, create a default file.
2717#
2818# meleu, 2016/05
2919
30-
3120configdir=" /opt/retropie/configs"
3221
3322user=" $SUDO_USER "
@@ -37,7 +26,7 @@ home="$(eval echo ~$user)"
3726jslist_exe=" $home /bin/jslist"
3827
3928js_list_file=" /tmp/jslist-$$ "
40- temp_file=" ${js_list_file} _d "
29+ temp_file=" ${js_list_file} _deleteme "
4130retroarchcfg=" $configdir /all/retroarch.cfg"
4231inputcfg=" $configdir /all/input-selection.cfg"
4332
@@ -63,60 +52,149 @@ function stop_joy2key() {
6352# end of the borrowed code from runcommand.sh
6453# ##############################################################################
6554
66-
67- start_joy2key
68-
69- # checking if the "#include ..." line is in the retroarch.cfg
70- grep -q \
71- " ^#include \" $configdir /all/input-selection.cfg\" $" \
72- $retroarchcfg || {
73- dialog \
74- --title " Error" \
75- --yesno \
55+ # ##############################################################################
56+ # Checking the following:
57+ # - if retroarch.cfg has the "#include" line for input-selection.cfg, in
58+ # failure case let the user decide if we can add it to the file.
59+ # - if input-selection.cfg exists, create it if doesn't.
60+ # - if jslist exists and is executable
61+ #
62+ function check_files() {
63+ start_joy2key
64+ # checking if the "#include ..." line is in the retroarch.cfg
65+ grep -q \
66+ " ^#include \" $configdir /all/input-selection.cfg\" $" \
67+ $retroarchcfg || {
68+ dialog \
69+ --title " Error" \
70+ --yesno \
7671" Your retroarch.cfg isn't properly configured to work with this method of \
7772input selection. You need to put the following line on your \" $retroarchcfg \" \
7873(preferably at the beginning)\
7974\n\n#include \" $configdir /all/input-selection.cfg\" \n\n\
8075Do you want me to put it at the beginning of the retroarch.cfg now?\
8176\n(if you choose \" No\" , I will stop now)" \
82- 0 0 || {
83- stop_joy2key
84- exit 1;
85- }
77+ 0 0 || {
78+ stop_joy2key
79+ exit 1;
80+ }
8681
87- # Putting the "#include ..." at the beginning line of retroarch.cfg
88- sed -i " 1i\
82+ # Putting the "#include ..." at the beginning line of retroarch.cfg
83+ sed -i " 1i\
8984# $( date +%Y-%m-%d) : The following line was added to allow input selection\n\
9085#include \" $configdir /all/input-selection.cfg\" \n" $retroarchcfg
91- } # end of failed grep
86+ } # end of failed grep
9287
93- # if the input-selection.cfg doesn't exist or is empty, create it with
94- # default values
95- [[ -s " $inputcfg " ]] || {
96- cat << _EOF_ > $inputcfg
88+ # if the input-selection.cfg doesn't exist or is empty, create it with
89+ # default values
90+ [[ -s " $inputcfg " ]] || {
91+ cat << _EOF_ > $inputcfg
9792# This file is used to choose what controller to use for each player.
9893input_player1_joypad_index = "0"
9994input_player2_joypad_index = "1"
10095input_player3_joypad_index = "2"
10196input_player4_joypad_index = "3"
10297_EOF_
103- chown pi.pi $inputcfg
104- }
98+ } # end of failed inputcfg
99+ chown $user .$user " $inputcfg "
100+
101+ # checking if jslist exists and is executable
102+ [[ -x " $jslist_exe " ]] || {
103+ dialog \
104+ --title " Fail!"
105+ --msgbox " \" $jslist_exe \" not found or isn't executable!" \
106+ 5 40
107+ stop_joy2key
108+ exit 1
109+ } # end of failed jslist_exe
110+
111+ stop_joy2key
112+ } # end of check_files
113+
114+
115+
116+ # ##############################################################################
117+ # Show the input config file given and let the user decide if he/she
118+ # wants to continue.
119+ #
120+ # Globals:
121+ # js_list_file: js_list_file must be already filled with
122+ # joysticks' index and names.
123+ #
124+ # Arguments:
125+ # $1 : NEEDED. The input-selection.cfg file. It's just a
126+ # retroarch.cfg like file with the input_playerN_joypad_index variables.
127+ # $2 : OPTIONAL. Its a string with a question to ask in the yesno dialog.
128+ # Keep in mind that the "No" answer always exit.
129+ #
130+ # Returns:
131+ # None
132+ function show_input_config() {
133+ [[ -f " $1 " ]] || {
134+ echo " Error: show_input_config: invalid argument!" >&2
135+ exit 1
136+ }
137+
138+ local cfg_file
139+ cfg_file=" $1 "
140+
141+ local question
142+ question=${2:- " Would you like to continue?" }
143+
144+ local current_config_string
145+
146+ for i in $( seq 1 4) ; do
147+ js_index_p[$i ]=$(
148+ grep -m 1 " ^input_player${i} _joypad_index" " $cfg_file " \
149+ | cut -d= -f2 \
150+ | sed ' s/ *"\?\([0-9]\)*"\?.*/\1/' \
151+ )
152+ # the command sequence above takes the number after the = sign,
153+ # deleting the "double quotes" if they exist.
154+
155+ if [[ -z " ${js_index_p[$i]} " ]]; then
156+ js_name_p[$i ]=" ** NO JOYSTICK! **"
157+ else
158+ js_name_p[$i ]=$(
159+ grep " ^${js_index_p[$i]} " " $js_list_file " \
160+ | cut -d: -f2
161+ )
162+
163+ [[ -z " ${js_name_p[$i]} " ]] &&
164+ js_name_p[$i ]=" ** NO JOYSTICK! **"
165+ fi
166+
167+ current_config_string=" $current_config_string
168+ Player $i uses \" ${js_name_p[$i]} \" "
169+
170+ done
171+
172+ start_joy2key
105173
106- # checking if jslist exists and is executable
107- [[ -x " $jslist_exe " ]] || {
108174 dialog \
109- --title " Fail!"
110- --msgbox " \" $jslist_exe \" not found or isn't executable!" \
111- 5 40
175+ --title " Current config" \
176+ --yesno "
177+ $current_config_string
178+
179+ $question " \
180+ 0 0 || {
181+ stop_joy2key
182+ rm " $js_list_file "
183+ exit 0;
184+ }
185+
112186 stop_joy2key
113- exit 1
114- }
187+
188+ } # end of show_input_config
189+
190+
191+ check_files
115192
116193# the jslist returns a non-zero value if it doesn't find any joystick
117194$jslist_exe > $temp_file || {
195+ start_joy2key
118196 dialog --title " Fail!" --msgbox " No joystick found. :(" 5 40
119- rm -f $temp_file
197+ rm -f " $temp_file "
120198 stop_joy2key
121199 exit 1
122200}
@@ -129,9 +207,18 @@ awk -F: 'FNR==NR {count[$2]++; next}
129207 1' $temp_file $temp_file > $js_list_file
130208
131209# No need for this file anymore
132- rm -f $temp_file
210+ rm -f " $temp_file "
211+
212+
213+ show_input_config " $inputcfg " " Would you like to change it?"
214+
133215
134216temp_file=" /tmp/jstmp-$$ "
217+ temp_inputcfg=" /tmp/inputcfg-$$ "
218+
219+ cat " $inputcfg " > " $temp_inputcfg "
220+
221+ start_joy2key
135222
136223for i in $( seq 1 4) ; do
137224 # Obtaining the joystick list with the format
@@ -145,15 +232,22 @@ for i in $(seq 1 4); do
145232 --menu " Which controller you want to use for Player $i ?" \
146233 0 0 0 2> $temp_file
147234
148- js_index=$( cat $temp_file )
235+ js_index=$( sed ' s/.*[^0-9].*// ' $temp_file )
149236
150- # Here is the magic! Change the input_playerX_joypad_index in retroarch.cfg
151- sed \
152- " s/^input_player${i} _joypad_index.*/input_player${i} _joypad_index = \" $js_index \" /" \
153- $inputcfg > $temp_file
237+ # strings to be used with sed below
238+ old=" ^input_player${i} _joypad_index.*"
239+ new=" input_player${i} _joypad_index = $js_index "
154240
155- mv $temp_file $inputcfg
241+ sed " s/$old /$new /" $temp_inputcfg > $temp_file
242+
243+ mv " $temp_file " " $temp_inputcfg "
156244done
157245
246+
247+ show_input_config " $temp_inputcfg " " Do you accept this config?"
248+
249+ # If the script reaches the user accepted the config
250+ mv " $temp_inputcfg " " $inputcfg "
251+
158252stop_joy2key
159- rm -f $js_list_file
253+ rm -f " $js_list_file " " $temp_file " " $temp_inputcfg "
0 commit comments