@@ -72,7 +72,9 @@ char* getSystemOutput(char* inputCommand) {
72
72
// Main function
73
73
int main (int argc , char * * argv ) {
74
74
75
+
75
76
// Read game file argument to execute
77
+ system ("clear" );
76
78
char * game = "" ;
77
79
char * options = "" ;
78
80
if (argc == 2 ) {
@@ -86,92 +88,164 @@ int main(int argc, char** argv) {
86
88
}
87
89
88
90
91
+ // Check for nomap option
89
92
if (!strcmp (options , "nomap" )) {
90
- printf ("%s, %s\n" , game , options );
93
+ printf ("%s argument detected,\nStarting %s with no automatic gamepad mappings...\n" , options , game );
94
+ sleep (1 );
91
95
} else {
92
- // Determine the number of connected gamepads
93
- printf ("%s\n" , game );
94
- char eventPaths [100 ];
95
- memset (eventPaths , 0 , sizeof (eventPaths ));
96
- int numberOfPads = 0 ;
97
- int numberOfEvents = 1 + atoi (getSystemOutput ("ls /dev/input | sed 's/event//' | sort -n | tail -1" ));
98
- for (int i = 0 ; i < numberOfEvents ; i ++ ) {
99
- if (numberOfPads < 2 ) {
100
- char processCommand [120 ];
101
- snprintf (processCommand , 120 , "/home/pi/McAirpos/McAirpos/uinput-mapper/input-read -vp /dev/input/event%d | grep -e BTN_SOUTH -e BTN_PINKIE" , i );
102
- char * event = getSystemOutput (processCommand );
103
- if (strcmp (event , "" )) {
104
- printf ("%s, Output:%s\n" , processCommand , getSystemOutput (processCommand ));
105
- printf ("%d Possible gamepads\n" , numberOfEvents );
106
- char iString [20 ];
107
- sprintf (iString , "%d" , i );
108
- strcat (strcat (strcat (eventPaths , "/dev/input/event" ), iString ), " " );
109
- strcat (strcat (strcat (eventPaths , "/dev/input/event" ), iString ), " " );
110
- numberOfPads ++ ;
111
- }
112
- }
113
- }
114
-
115
-
116
- // Set up MakeCode Arcade and uinput-mapper with keyboard, 1 or 2 gamepads
117
- printf ("\n%s\n" , eventPaths );
118
- char defaultEvent [67 ];
119
- memset (defaultEvent , 0 , sizeof (defaultEvent ));
120
- strcat (defaultEvent , "SCAN_CODES=/dev/input/" );
121
- char sedCommand [100 ];
122
- char * tempString = getSystemOutput ("cat /proc/bus/input/devices | grep -B 7 EV=12001 | tr ' ' '\n' | grep event" );
123
- if ((numberOfPads == 1 ) || (numberOfPads == 2 )) {
124
- if (numberOfPads == 1 ) {
125
- strcat (strcat (eventPaths , "/dev/input/" ), tempString );
126
- eventPaths [strlen (eventPaths )- 1 ] = 0 ;
127
- strcat (eventPaths , " " );
128
- }
129
- char newEventNo [20 ];
130
- sprintf (newEventNo , "%d" , numberOfEvents );
131
- strcat (strcat (defaultEvent , "event" ), newEventNo );
132
- char uiMapCommand [400 ];
133
- memset (uiMapCommand , 0 , sizeof (uiMapCommand ));
134
- sprintf (newEventNo , "%d.py)&" ,numberOfPads );
135
- strcat (strcat (strcat (strcat (uiMapCommand , "(/home/pi/McAirpos/McAirpos/uinput-mapper/input-read -C -D " ), eventPaths ), "| sudo /home/pi/McAirpos/McAirpos/uinput-mapper/input-create -C -S /home/pi/McAirpos/McAirpos/uinput-mapper/configs/arcade" ), newEventNo );
136
- printf ("%s\n" , uiMapCommand );
137
- /*if (!fork()) {
138
- setpgid(0, 0);
139
- system(uiMapCommand);
140
- }else {}*/
141
- system (uiMapCommand );
142
- }
143
- if (numberOfPads == 0 ) {
144
- strcat (defaultEvent , tempString );
145
- defaultEvent [strlen (defaultEvent )- 1 ] = 0 ;
146
- }
147
- snprintf (sedCommand , 100 , "sed -i \"1s&.*&\"%s\"&\" /sd/arcade.cfg" , defaultEvent );
148
- system (sedCommand );
149
- }
150
- system ("stty -ixon" );
96
+ // Determine the number of connected gamepads
97
+ printf ("Starting %s with automatic gamepad mappings...\n\n" , game );
98
+ char eventPaths [100 ];
99
+ memset (eventPaths , 0 , sizeof (eventPaths ));
100
+ int numberOfPads = 0 ;
101
+ int numberOfEvents = 1 + atoi (getSystemOutput ("ls /dev/input | sed 's/event//' | sort -n | tail -1" ));
102
+ printf ("\nHighest found input event number: %d\n\n" , numberOfEvents );
103
+ char padEvent [2 ][20 ];
104
+ for (int i = 0 ; i < numberOfEvents ; i ++ ) {
105
+ if (numberOfPads < 2 ) {
106
+ char padCommand [150 ];
107
+ snprintf (padCommand , 150 , "/home/pi/McAirpos/McAirpos/uinput-mapper/input-read -vp /dev/input/event%d 2>&1 | grep -e BTN_SOUTH -e BTN_PINKIE" , i );
108
+ char * event = getSystemOutput (padCommand );
109
+ if (strcmp (event , "" )) {
110
+ if (numberOfPads == 0 ) {
111
+ printf ("\nGamepad search hits:\n" );
112
+ }
113
+ printf ("%s, Output:%s" , padCommand , getSystemOutput (padCommand ));
114
+ char iString [20 ];
115
+ sprintf (iString , "%d" , i );
116
+ strcat (strcat (strcat (eventPaths , "/dev/input/event" ), iString ), " " );
117
+ strcat (strcat (strcat (eventPaths , "/dev/input/event" ), iString ), " " );
118
+ memset (padEvent [numberOfPads ], 0 , sizeof (padEvent [numberOfPads ]));
119
+ strcat (strcat (padEvent [numberOfPads ], "/dev/input/event" ), iString );
120
+ numberOfPads ++ ;
121
+ }
122
+ }
123
+ }
124
+
125
+ // Determine if keyboard is connected
126
+ char keybCommand [] = "cat /proc/bus/input/devices | grep -B 7 EV=12001 | tr ' ' '\\n' | grep event" ;
127
+ char * keybEvent = getSystemOutput (keybCommand );
128
+ if (strcmp (keybEvent , "" )) {
129
+ printf ("\nKeyboard search hit:\n" );
130
+ printf ("%s, Output:%s" , keybCommand , getSystemOutput (keybCommand ));
131
+ }
132
+
133
+
134
+ // Automatically set up uinput-mapper with keyboard, 1 or 2 gamepads
135
+ // printf("\n%s\n", eventPaths);
136
+ char stringNumberOfPads [20 ];
137
+ char uiMapCommand [400 ];
138
+ memset (uiMapCommand , 0 , sizeof (uiMapCommand ));
139
+ char uinputMapperOrKeyboard [20 ];
140
+ memset (uinputMapperOrKeyboard , 0 , sizeof (uinputMapperOrKeyboard ));
141
+ char defaultEvent [67 ];
142
+ memset (defaultEvent , 0 , sizeof (defaultEvent ));
143
+ strcat (defaultEvent , "SCAN_CODES=/dev/input/" );
144
+ printf ("\n" );
145
+ if ((numberOfPads == 0 ) && !strcmp (keybEvent , "" )) {
146
+ printf ("\nFound no gamepads or keyboards to configure...\n" );
147
+ printf ("\nPlease try the \"nomap\" option and configure /sd/arcade.cfg manually. If stuck, please read or open a related issue at https://github.com/Vegz78/McAirpos.\n" );
148
+ sleep (1 );
149
+ exit (1 );
150
+ }
151
+ else if (numberOfPads == 2 ) {
152
+ printf ("\nFound %d gamepads to configure on:\n%s, and\n%s\n\n" , numberOfPads , padEvent [0 ], padEvent [1 ]);
153
+ sprintf (stringNumberOfPads , "%d.py)&" ,numberOfPads );
154
+ }
155
+ else if ((numberOfPads == 1 ) && strcmp (keybEvent , "" )) {
156
+ printf ("\nFound %d gamepad to configure on:\n%s\n" , numberOfPads , padEvent [0 ]);
157
+ printf ("\nFound 1 keyboard to configure on:\n/dev/input/%s\n\n" , keybEvent );
158
+ strcat (strcat (eventPaths , "/dev/input/" ), keybEvent );
159
+ eventPaths [strlen (eventPaths )- 1 ] = 0 ;
160
+ strcat (eventPaths , " " );
161
+ sprintf (stringNumberOfPads , "%d.py)&" ,numberOfPads );
162
+ }
163
+ else if (strcmp (keybEvent , "" )) {
164
+ printf ("\nFound 1 keyboard to configure on:\n/dev/input/%s\n\n" , keybEvent );
165
+ strcat (defaultEvent , keybEvent );
166
+ defaultEvent [strlen (defaultEvent )- 1 ] = 0 ;
167
+ strcat (uinputMapperOrKeyboard , "keyboard" );
168
+ }
169
+ else if (numberOfPads == 1 ) {
170
+ printf ("\nFound %d gamepad to configure on:\n%s\n\n" , numberOfPads , padEvent [0 ]);
171
+ sprintf (stringNumberOfPads , "%d.py)&" ,numberOfPads );
172
+ }
173
+ else {
174
+ printf ("\nSomething went wrong, exiting...\n" );
175
+ printf ("If stuck, please read or open a related issue at https://github.com/Vegz78/McAirpos.\n" );
176
+ sleep (1 );
177
+ exit (1 );
178
+ }
179
+
180
+
181
+ // Launching uinput-mapper
182
+ if (numberOfPads > 0 ) {
183
+ strcat (strcat (strcat (strcat (uiMapCommand , "(/home/pi/McAirpos/McAirpos/uinput-mapper/input-read -C -D " ), eventPaths ), "| sudo /home/pi/McAirpos/McAirpos/uinput-mapper/input-create -C -S /home/pi/McAirpos/McAirpos/uinput-mapper/configs/arcade" ), stringNumberOfPads );
184
+ if (system (uiMapCommand ) == 0 ) {
185
+ printf ("\nStarting UInput-Mapper with command:\n%s\n" , uiMapCommand );
186
+ int whileCount = 0 ;
187
+ while (!strcmp ("" , getSystemOutput ("cat /proc/bus/input/devices | grep -A 8 \"UInputMapper: MakeCode_Arcade\" | tr ' ' '\n' | grep event" ))) {
188
+ if (whileCount > 500 ) {
189
+ printf ("\nTimed out trying to set up UInput-Mapper...\n" );
190
+ printf ("If stuck, please read or open a related issue at https://github.com/Vegz78/McAirpos.\n" );
191
+ exit (1 );
192
+ }
193
+ whileCount ++ ;
194
+ }
195
+ char * uinputEvent = getSystemOutput ("cat /proc/bus/input/devices | grep -A 8 \"UInputMapper: MakeCode_Arcade\" | tr ' ' '\n' | grep event" );
196
+ strcat (defaultEvent , uinputEvent );
197
+ defaultEvent [strlen (defaultEvent )- 1 ] = 0 ;
198
+ strcat (uinputMapperOrKeyboard , "UInputMapper" );
199
+ } else {
200
+ printf ("\nUInput-Mapper failed to start...\n" );
201
+ printf ("If stuck, please read or open a related issue at https://github.com/Vegz78/McAirpos.\n" );
202
+ exit (1 );
203
+ }
204
+ // Alternative way to launch uinput-mapper
205
+ /*if (!fork()) {
206
+ setpgid(0, 0);
207
+ system(uiMapCommand);
208
+ }else {}*/
209
+ }
210
+
211
+
212
+ // Set default default event for MakeCode Arcade elf game file
213
+ char sedCommand [100 ];
214
+ snprintf (sedCommand , 100 , "sed -i \"1s&.*&\"%s\"&\" /sd/arcade.cfg" , defaultEvent );
215
+ if (system (sedCommand ) == 0 ) {
216
+ printf ("\n\nSetting up %s in MakeCode Arcade game's /sd/arcade.cfg with:\n%s\n\n" , uinputMapperOrKeyboard , defaultEvent );
217
+ } else {
218
+ printf ("\n\nPlease check path or write permissions for /sd/arcade.cfg and try again.\n\n" );
219
+ goto cleanup ;
220
+ }
221
+ }
222
+ system ("stty -ixon" ); //Disable pause in terminal with key combo CTRL+S
151
223
152
224
153
225
// Fork game execution on launch, so that it is executed
154
226
// the same way it's done in-game on reset and finish
227
+ char * path = "/dev/tty" ;
228
+ int fd = open (path , O_RDWR , 0 );
155
229
if (!fork ()) {
156
- sleep (1 );
157
- system (game );
158
- //execl(game, game, NULL);
159
- }else {
160
- sleep (2 ); // Wait for fork/game to launch and get pid
161
-
162
230
//Switch console to graphics mode to avoid disturbing text output in borders
163
- char * path = "/dev/tty" ;
164
- int fd = open (path , O_RDWR , 0 );
165
231
if (fd < 0 ) {
166
232
perror ("unable to open tty" );
167
233
return 1 ;
168
234
}
169
- system ("clear" );
170
235
if (ioctl (fd , KDSETMODE , KD_GRAPHICS ) < 0 ) {
171
236
perror ("warn: ioctl KDSETMODE failed" );
172
237
}
173
238
close (fd );
174
- system ("clear" );
239
+ system ("sudo killall pulseaudio" );
240
+ if (system (game ) == 36608 ) {
241
+ printf ("\n\n%s was exited by the user\n\n\n" , game );
242
+ } else {
243
+ printf ("\n\nPlease check path to and executable permissions for game_file.elf and try again.\n\n\n" );
244
+ }
245
+ //Alternative way to launch game
246
+ //execl(game, game, NULL);
247
+ }else {
248
+ sleep (1 ); // Wait for fork/game to launch and get pid
175
249
176
250
// Get running game's process name
177
251
char * processID = getSystemOutput ("head -1 /tmp/pxt-pid" );
@@ -185,7 +259,7 @@ int main(int argc, char** argv) {
185
259
// Busy waiting to continue and cleanup when game is exited
186
260
// Why does this not work without the printf?!?
187
261
besure :
188
- while (0 == system (processCheckCmd )) {
262
+ while (0 == system (processCheckCmd )) {
189
263
printf ("%s\n" , getSystemOutput (processCheckCmd ));
190
264
sleep (2 );
191
265
}
@@ -194,11 +268,13 @@ int main(int argc, char** argv) {
194
268
sleep (1 );
195
269
if (0 == system (processCheckCmd )) {goto besure ;}
196
270
271
+
197
272
// Kill any remaining/orphaned game processes before exit
198
273
char killAllCmd [100 ];
199
- snprintf (killAllCmd , 100 , "killall %s" , processName );
274
+ snprintf (killAllCmd , 100 , "killall %s 2>&1 " , processName );
200
275
system (killAllCmd );
201
- system ("sudo killall input-create&&sudo killall input-read" );
276
+ cleanup :
277
+ system ("sudo killall input-create 2>&1 & sudo killall input-read 2>&1" );
202
278
203
279
204
280
// The following code is borrowed from https://github.com/hobbitalistair/termfix:
@@ -213,7 +289,7 @@ int main(int argc, char** argv) {
213
289
// This one fails without sudo, but doesn't seem needed for
214
290
// MakeCode Arcade games(comment out or leave as and option?).
215
291
if (ioctl (fd , VT_UNLOCKSWITCH , 1 ) < 0 ) {
216
- perror ("warn: ioctl VT_UNLOCKSWITCH failed" );
292
+ // perror("warn: ioctl VT_UNLOCKSWITCH failed");
217
293
}
218
294
219
295
if (ioctl (fd , KDSETMODE , KD_TEXT ) < 0 ) {
@@ -225,7 +301,7 @@ int main(int argc, char** argv) {
225
301
}
226
302
227
303
system ("stty ixon" );
228
- system ("clear" );
304
+ // system("clear");
229
305
}
230
306
231
307
return 0 ;
0 commit comments