commit 6615d46
zzo38
·
2023-05-18 20:38:50 +0000 UTC
parent c438658
Add -e switch to execute and connect this uxn instance to another program.
2 files changed,
+42,
-6
M
main.c
+5,
-0
1@@ -48,6 +48,11 @@
2 -d
3 Enable some debugging features. (Some will work even without this.)
4
5+-e #
6+ Execute another program (with "sh -c"), which will be connected to this
7+ one using the standard I/O. For example, it can be used with nc to make
8+ remote two players.
9+
10 -h #
11 Set default screen height.
12
M
main.c
+37,
-6
1@@ -196,6 +196,8 @@ static Uint8*bglayer;
2 static Uint8*fglayer;
3 static UxnFile uxnfile0;
4 static UxnFile uxnfile1;
5+static FILE*inf;
6+static FILE*outf;
7
8 static const char*rom_name;
9 static Uint8 use_console=1;
10@@ -260,7 +262,7 @@ static void debug(int i) {
11
12 static void uxnerr(int n,int pc) {
13 if(use_debug) debug(-1);
14- fflush(stdout);
15+ fflush(outf);
16 fflush(stderr);
17 errx(2,"Uxn error %d at 0x%04X",n,pc);
18 }
19@@ -353,7 +355,7 @@ static void run(Uint16 pc) {
20 paused=debugger=picture_changed=1;
21 break_pc=pc-1;
22 }
23- fflush(stdout);
24+ fflush(outf);
25 return;
26 error:
27 uxnerr(v,pc);
28@@ -404,7 +406,7 @@ static void system_out(Device*dev,Uint8 id) {
29
30 static void console_out(Device*dev,Uint8 id) {
31 switch(id) {
32- case 8: putchar(dev->d[8]); break;
33+ case 8: fputc(dev->d[8],outf); break;
34 case 9: fputc(dev->d[9],stderr); break;
35 }
36 }
37@@ -1352,7 +1354,7 @@ static int stdin_thread_fn(void*unused) {
38 int c;
39 SDL_Event e;
40 e.type=SDL_USEREVENT+1;
41- while((c=getchar())>=0) {
42+ while((c=fgetc(inf))>=0) {
43 e.user.code=c;
44 SDL_PushEvent(&e);
45 }
46@@ -1459,6 +1461,33 @@ static void set_joystick(char*s) {
47 }
48 }
49
50+static void set_other_program(const char*s) {
51+ int pf[4];
52+ pid_t pi;
53+ if(pipe(pf) || pipe(pf+2)) err(1,"Pipe failed");
54+ pi=fork();
55+ if(pi==(pid_t)(-1)) err(1,"Fork failed");
56+ if(pi) {
57+ // Parent
58+ close(pf[1]);
59+ close(pf[2]);
60+ inf=fdopen(pf[0],"r");
61+ if(!inf) err(1,"Cannot open pipe for input");
62+ outf=fdopen(pf[3],"w");
63+ if(!outf) err(1,"Cannot open pipe for output");
64+ } else {
65+ // Child
66+ close(pf[0]);
67+ close(pf[3]);
68+ if(dup2(pf[1],1)<0 || dup2(pf[2],0)<0) err(1,"Cannot duplicate file descriptors");
69+ close(pf[1]);
70+ close(pf[2]);
71+ execl("/bin/sh","/bin/sh","-c",s,(char*)0);
72+ fprintf(stderr,"Cannot exec\n");
73+ _exit(1);
74+ }
75+}
76+
77 int main(int argc,char**argv) {
78 int i,j;
79 for(i=0;i<16;i++) {
80@@ -1471,7 +1500,8 @@ int main(int argc,char**argv) {
81 device[10].aux=&uxnfile0;
82 device[11].aux=&uxnfile1;
83 device[12].in=datetime_in;
84- while((i=getopt(argc,argv,"+ADFIJ:NOQST:YZa:dh:ijnp:qs:t:w:xyz:"))>0) switch(i) {
85+ inf=stdin; outf=stdout;
86+ while((i=getopt(argc,argv,"+ADFIJ:NOQST:YZa:de:h:ijnp:qs:t:w:xyz:"))>0) switch(i) {
87 case 'D': scrflags|=SDL_DOUBLEBUF; break;
88 case 'F': scrflags|=SDL_FULLSCREEN; break;
89 case 'I': use_thread=1; break;
90@@ -1485,6 +1515,7 @@ int main(int argc,char**argv) {
91 case 'Z': use_utc=1; break;
92 case 'a': set_audio(optarg); break;
93 case 'd': use_debug=1; break;
94+ case 'e': set_other_program(optarg); break;
95 case 'h': default_height=strtol(optarg,0,10); break;
96 case 'i': hide_cursor=1; break;
97 case 'j': joypad_repeat=1; break;
98@@ -1552,7 +1583,7 @@ int main(int argc,char**argv) {
99 run_audio();
100 } else {
101 device[1].d[7]=1;
102- while((device[1].d[0] || device[1].d[1]) && ((i=getchar())>=0)) {
103+ while((device[1].d[0] || device[1].d[1]) && ((i=fgetc(inf))>=0)) {
104 device[1].d[2]=i;
105 run(GET16(device[1].d));
106 }