commit 8309dc1
chld
·
2026-10-27 12:53:16 +0000 UTC
parent 359d262
replace main with simpler main, remove scripts and unix stuff
1 files changed,
+83,
-297
M
uxn.c
M
uxn.c
+83,
-297
1@@ -978,81 +978,30 @@ static void run_audio(void) {
2 }
3 }
4
5-static void do_extension_by_uuid(Uint16 addr) {
6- static const Uint8 uuid_8color[]="\x80\x17\x51\x32\xE2\x63\x11\xED\xB8\xC9\x00\x26\x18\x74\x54\x16";
7- static const Uint8 uuid_screencompat[]="\x97\x0B\x5A\x0C\x2C\x44\x11\xEE\xAC\x3B\x00\x26\x18\x74\x54\x16";
8- static const Uint8 uuid_subprocess[]="\x9C\x5F\x13\x56\x6B\xC5\x11\xEF\xA6\xC9\x00\x26\x18\x74\x54\x16";
9- static const Uint8 uuid_random[]="\x41\x05\x25\x9C\xE0\x61\x11\xF0\x96\x3F\x00\x26\x18\x74\x54\x16";
10- int i;
11- if(mem[addr+1]==0x00 && use_screen && !memcmp(mem+addr+2,uuid_8color,16)) {
12- for(i=0;i<8;i++) {
13- colors[i+070].r=(mem[addr+19+i+i]>>4)*0x11;
14- colors[i+070].g=(mem[addr+19+i+i]&15)*0x11;
15- colors[i+070].b=(mem[addr+20+i+i]>>4)*0x11;
16- }
17- if(palet==7) {
18- SDL_SetColors(screen,colors+palet*8,0,8);
19- picture_changed=1;
20- }
21- mem[addr+18]=1;
22- } else if(mem[addr+1]==0x20 && use_screen && !memcmp(mem+addr+2,uuid_screencompat,16)) {
23- screencompat=mem[addr+19];
24- blend[0][0]=(screencompat&0x01?4:0);
25- mem[addr+18]=1;
26- } else if(mem[addr+1]==0x10 && use_thread && use_console && allow_write && !memcmp(mem+addr+2,uuid_subprocess,16)) {
27- device[1].in=subprocess_console_in;
28- enable_subprocess=mem[addr+18]=1;
29- } else if(device[mem[addr+1]>>4].in==default_in && mem[addr+19]<2 && mem[addr+20]>=4 && !memcmp(mem+addr+2,uuid_random,16)) {
30- if(randomfd==-1) randomfd=open("/dev/urandom",O_RDONLY|O_NOCTTY|O_CLOEXEC);
31- if(randomfd>=0) {
32- mem[addr+18]=1;
33- device[mem[addr+1]>>4].in=random_in;
34- i=(mem[addr+21]<<8)|mem[addr+22];
35- mem[i]=0x80;
36- mem[i+1]=mem[addr+1];
37- mem[i+2]=0x16+(mem[addr+19]<<5);
38- mem[i+3]=0x6C;
39- } else {
40- warn("Cannot open /dev/urandom");
41- }
42- }
43-}
44-
45-static void system_exp(Device*dev,Uint16 addr) {
46- Uint32 src,dst;
47- Uint16 len,n;
48- switch(mem[addr]) {
49+static void system_exp(Device *dev, Uint16 addr)
50+{
51+ Uint32 src, dst;
52+ Uint16 len, n;
53+ switch (mem[addr]) {
54 case 0x00:
55- len=GET16(mem+addr+1);
56- dst=(GET16(mem+addr+3)<<16L)|(GET16(mem+addr+5));
57- if(dst<MEMSIZE && dst+len<=MEMSIZE) {
58- memset(mem+dst,mem[addr+7],len);
59- } else {
60- if(use_debug) fprintf(stderr,"! Access expanded memory out of range\n");
61- }
62+ len = GET16(mem + addr + 1);
63+ dst = (GET16(mem + addr + 3) << 16L) | GET16(mem + addr + 5);
64+ if (dst < MEMSIZE && dst + len <= MEMSIZE)
65+ memset(mem + dst, mem[addr + 7], len);
66 break;
67 case 0x01: case 0x02:
68- len=GET16(mem+addr+1);
69- src=(GET16(mem+addr+3)<<16L)|(GET16(mem+addr+5));
70- dst=(GET16(mem+addr+7)<<16L)|(GET16(mem+addr+9));
71- if(dst<MEMSIZE && src+len<=MEMSIZE && dst+len<=MEMSIZE) {
72- if(mem[addr]==0x01) {
73- for(n=0;n<len;n++) mem[dst+n]=mem[src+n];
74- } else {
75- for(n=len;n;n--) mem[dst+n-1]=mem[src+n-1];
76- }
77- } else {
78- if(use_debug) fprintf(stderr,"! Access expanded memory out of range\n");
79+ len = GET16(mem + addr + 1);
80+ src = (GET16(mem + addr + 3) << 16L) | GET16(mem + addr + 5);
81+ dst = (GET16(mem + addr + 7) << 16L) | GET16(mem + addr + 9);
82+ if (dst < MEMSIZE && src + len <= MEMSIZE && dst + len <= MEMSIZE) {
83+ if (mem[addr] == 0x01)
84+ for (n = 0; n < len; n++) mem[dst + n] = mem[src + n];
85+ else
86+ for (n = len; n; n--) mem[dst + n - 1] = mem[src + n - 1];
87 }
88 break;
89- case 0x03:
90- if(!use_extension) break;
91- mem[addr+18]=0;
92- do_extension_by_uuid(addr);
93- break;
94 case 0x04:
95- if(!use_extension) break;
96- PUT16(mem+addr+1,EXPANDED_MEMORY);
97+ if (use_extension) PUT16(mem + addr + 1, EXPANDED_MEMORY);
98 break;
99 }
100 }
101@@ -1643,33 +1592,6 @@ static void set_joystick(char*s) {
102 }
103 }
104
105-static void set_other_program(const char*s) {
106- int pf[4];
107- pid_t pi;
108- if(pipe(pf) || pipe(pf+2)) err(1,"Pipe failed");
109- pi=fork();
110- if(pi==(pid_t)(-1)) err(1,"Fork failed");
111- if(pi) {
112- // Parent
113- close(pf[1]);
114- close(pf[2]);
115- inf=fdopen(pf[0],"r");
116- if(!inf) err(1,"Cannot open pipe for input");
117- outf=fdopen(pf[3],"w");
118- if(!outf) err(1,"Cannot open pipe for output");
119- } else {
120- // Child
121- close(pf[0]);
122- close(pf[3]);
123- if(dup2(pf[1],1)<0 || dup2(pf[2],0)<0) err(1,"Cannot duplicate file descriptors");
124- close(pf[1]);
125- close(pf[2]);
126- execl("/bin/sh","/bin/sh","-c",s,(char*)0);
127- fprintf(stderr,"Cannot exec\n");
128- _exit(1);
129- }
130-}
131-
132 static void set_palette(char*s) {
133 int p=palet<<3;
134 FILE*f=fmemopen(s,strlen(s),"r");
135@@ -1681,100 +1603,6 @@ static void set_palette(char*s) {
136 fclose(f);
137 }
138
139-static void set_script(char*s) {
140- static size_t siz;
141- Script o={0,0,0,0,0};
142- if(!scriptf) {
143- scriptf=open_memstream((char**)&scriptv,&siz);
144- if(!scriptf) err(1,"Error with open_memstream during parsing command-line arguments");
145- }
146- if(*s=='@') {
147- char*line=0;
148- size_t line_size=0;
149- FILE*fp=fopen(s+1,"r");
150- if(!fp) err(1,"Cannot open file");
151- while(getline(&line,&line_size,fp)>0) {
152- s=line+strlen(line);
153- while(s>line && (s[-1]=='\r' || s[-1]=='\n' || s[-1]==' ' || s[-1]=='\t')) *--s=0;
154- if(*s=='@') err(1,"Nested file in -m not allowed");
155- if(*s && *s!='#') set_script(s);
156- }
157- fclose(fp);
158- free(line);
159- } else {
160- Uint8 b;
161- if(*s=='.') o.stage=1,s++;
162- if(*s>'f') o.kind=*s++;
163- o.addr=strtoll(s,&s,16);
164- if(*s=='=') {
165- s++;
166- if(strlen(s)>=0x1FFFF) err(1,"Argument too long");
167- o.data=malloc(strlen(s)/2+1);
168- if(!o.data) err(1,"Allocation failed");
169- while(*s && s[1]) {
170- if(!sscanf(s,"%2hhX",&b)) break;
171- o.data[o.len++]=b;
172- s+=2;
173- }
174- if(*s) err(1,"Syntax error in -m");
175- } else if(*s) {
176- err(1,"Syntax error in -m");
177- }
178- if(o.kind || o.len) {
179- if(!fwrite(&o,sizeof(Script),1,scriptf)) err(1,"Cannot write to memory stream");
180- ++scriptc;
181- }
182- }
183-}
184-
185-static void do_script(Uint8 stage) {
186- Uint8 u=use_extension;
187- Uint16 n,i,j;
188- Script*o;
189- use_extension=1;
190- for(n=0;n<scriptc;n++) if(scriptv[n].stage==stage) {
191- o=scriptv+n;
192- switch(o->kind) {
193- case 0: // Memory write
194- memcpy(mem+o->addr,o->data,o->len);
195- break;
196- case 'p': // Device port (including trigger)
197- j=o->addr;
198- for(i=0;i<o->len;i++) {
199- device[(j>>4)&15].d[j&15]=o->data[i];
200- device[(j>>4)&15].out(device+((j>>4)&15),j&15);
201- j++;
202- }
203- break;
204- case 's': // Device port (set only)
205- j=o->addr;
206- for(i=0;i<o->len;i++) {
207- device[(j>>4)&15].d[j&15]=o->data[i];
208- j++;
209- }
210- break;
211- case 'u': // Extension set
212- mem[o->addr]=3;
213- memcpy(mem+o->addr+1,o->data,o->len);
214- do_extension_by_uuid(o->addr);
215- break;
216- case 'x': // Execute
217- run(o->addr);
218- break;
219- case 'z': // Others
220- if(o->addr==2) {
221- if(o->len) screencompat=o->data[0];
222- blend[0][0]=(screencompat&0x01?4:0);
223- } else {
224- err(1,"Unrecognized command");
225- }
226- break;
227- default: err(1,"Unrecognized command");
228- }
229- }
230- use_extension=u;
231-}
232-
233 static void set_full_screen_size(void) {
234 SDL_Rect**m=SDL_ListModes(0,scrflags);
235 int i;
236@@ -1783,121 +1611,79 @@ static void set_full_screen_size(void) {
237 default_height=m[0]->h/zoom;
238 }
239
240-int main(int argc,char**argv) {
241- int i,j;
242- for(i=0;i<16;i++) {
243- device[i].in=default_in;
244- device[i].out=default_out;
245- device[i].exp=default_exp;
246- }
247- device[0].in=system_in;
248- device[0].out=system_out;
249- device[0].exp=system_exp;
250- device[10].aux=&uxnfile0;
251- device[11].aux=&uxnfile1;
252- device[12].in=datetime_in;
253- inf=stdin; outf=stdout;
254- while((i=getopt(argc,argv,"+ADFIJ:NOQST:YZa:de:h:ijm:np:qs:t:w:xyz:"))>0) switch(i) {
255- case 'D': scrflags|=SDL_DOUBLEBUF; break;
256- case 'F': scrflags|=SDL_FULLSCREEN; default_width=default_height=0; break;
257- case 'I': use_thread=1; break;
258- case 'J': set_joystick(optarg); break;
259- case 'N': scrflags|=SDL_NOFRAME; break;
260- case 'O': touch_mode=1; device[9].d[2]=device[9].d[4]=0x80; break;
261- case 'Q': use_mouse=0; break;
262- case 'S': disallow_size_change=1; break;
263- case 'T': device[12].in=default_in; set_datetime(optarg); break;
264- case 'Y': allow_write=1; device[10].out=device[11].out=files_out; device[10].in=device[11].in=files_in; device[10].exp=device[11].exp=files_exp; break;
265- case 'Z': use_utc=1; break;
266- case 'a': set_audio(optarg); break;
267- case 'd': use_debug=1; break;
268- case 'e': set_other_program(optarg); break;
269- case 'h': default_height=strtol(optarg,0,10); break;
270- case 'i': hide_cursor=1; break;
271- case 'j': joypad_repeat=1; break;
272- case 'm': set_script(optarg); break;
273- case 'n': use_screen=0; break;
274- case 'p': palet=strtol(optarg,0,10)&7; if(*optarg && optarg[1]=='=') set_palette(optarg+2); break;
275- case 'q': use_console=0; break;
276- case 's': scroll_size=strtol(optarg,0,10); break;
277- case 't': timer_rate=strtol(optarg,0,10); break;
278- case 'w': default_width=strtol(optarg,0,10); break;
279- case 'x': use_extension=1; break;
280- case 'y': allow_write=0; device[10].out=device[11].out=files_out; device[10].in=device[11].in=files_in; device[10].exp=device[11].exp=files_exp; break;
281- case 'z': zoom=strtol(optarg,0,10); break;
282- default: return 1;
283- }
284- if(optind==argc) err(1,"Required argument missing");
285- rom_name=argv[optind];
286- if(use_console) device[1].out=console_out;
287- if(scriptf) {
288- fclose(scriptf);
289- if(!scriptv) err(1,"Allocation failed");
290- do_script(0);
291+int main(int argc, char **argv)
292+{
293+ int i;
294+
295+ /* seed RNG */
296+ srand(SDL_GetTicks() ^ (unsigned)time(NULL));
297+
298+ /* initialise devices */
299+ for (i = 0; i < 16; i++) {
300+ device[i].in = default_in;
301+ device[i].out = default_out;
302+ device[i].exp = default_exp;
303 }
304+ device[0].in = system_in;
305+ device[0].out = system_out;
306+ device[0].exp = system_exp;
307+ device[10].aux = &uxnfile0;
308+ device[11].aux = &uxnfile1;
309+ device[10].out = files_out;
310+ device[10].in = files_in;
311+ device[10].exp = files_exp;
312+ device[11].out = files_out;
313+ device[11].in = files_in;
314+ device[11].exp = files_exp;
315+ device[12].in = datetime_in;
316+
317+ /* optional random device on port 0xE */
318+ device[0xE].in = random_in;
319+
320+ if (use_console) device[1].out = console_out;
321+
322+ use_screen = 1;
323+ use_console = 0;
324+ use_mouse = 0;
325+ allow_write = 0;
326+ zoom = 1;
327+ disallow_size_change = 1;
328+ timer_rate = 16;
329+ scr_w = 320;
330+ scr_h = 240;
331+
332+ if (argc > 1) rom_name = argv[1];
333+
334 load_rom();
335- if(use_screen) {
336- if(zoom<1) err(1,"Zoom out of range");
337- if((default_height<1 || default_width<1) && !(scrflags&SDL_FULLSCREEN)) err(1,"Screen size out of range");
338- if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|(audio_option?SDL_INIT_AUDIO:0)|(joy_mask?SDL_INIT_JOYSTICK:0))) err(1,"Cannot initialize SDL");
339+
340+ if (use_screen) {
341+ if (SDL_Init(SDL_INIT_VIDEO) < 0)
342+ err(1, "SDL_Init failed");
343 atexit(SDL_Quit);
344- device[2].out=screen_out;
345- if(!default_width && !default_height && (scrflags&SDL_FULLSCREEN)) set_full_screen_size();
346- scr_w=default_width;
347- scr_h=default_height;
348- PUT16(device[2].d+2,scr_w);
349- PUT16(device[2].d+4,scr_h);
350- size_changed=1;
351- if(joy_mask) {
352- if((joy_mask&1) && !SDL_JoystickOpen(joy_player[0])) err(1,"Cannot open joystick for player I");
353- if((joy_mask&2) && !SDL_JoystickOpen(joy_player[1])) err(1,"Cannot open joystick for player II");
354- if((joy_mask&4) && !SDL_JoystickOpen(joy_player[2])) err(1,"Cannot open joystick for player III");
355- if((joy_mask&8) && !SDL_JoystickOpen(joy_player[3])) err(1,"Cannot open joystick for player IV");
356- SDL_JoystickEventState(SDL_ENABLE);
357- }
358+
359+ device[2].out = screen_out;
360+ PUT16(device[2].d + 2, scr_w);
361+ PUT16(device[2].d + 4, scr_h);
362+ size_changed = 1;
363+ set_screen_mode(scr_w, scr_h);
364 }
365- if(optind+1<argc) strncpy(uxnfile0.name,argv[optind+1],4095);
366- if(optind+2<argc) strncpy(uxnfile1.name,argv[optind+2],4095);
367- restart:
368- size_changed=1;
369- ds.p=rs.p=0;
370- device[1].d[7]=(optind+1==argc)?0:1;
371- if(scriptc) do_script(1);
372+
373+restart:
374+ size_changed = 1;
375+ ds.p = rs.p = 0;
376+ memset(device[1].d, 0, 16);
377 run(0x0100);
378- if(device[1].d[0] || device[1].d[1]) for(i=optind+1;i<argc;i++) {
379- for(j=0;argv[i][j];j++) {
380- device[1].d[2]=argv[i][j];
381- device[1].d[7]=2;
382- run(GET16(device[1].d));
383- }
384- device[1].d[2]='\n';
385- device[1].d[7]=(i==argc-1?4:3);
386- run(GET16(device[1].d));
387- }
388- if(use_screen) {
389- if(size_changed) set_screen_mode(scr_w,scr_h);
390- if(use_thread) {
391- stdin_cond=SDL_CreateCond();
392- SDL_CreateThread(stdin_thread_fn,0);
393- }
394- while(run_screen()) {
395- for(i=0;i<15;i++) for(j=0;j<16;j++) device[i].d[j]=0;
396- if(scriptc) do_script(0);
397+
398+ if (use_screen) {
399+ while (run_screen()) {
400+ /* restart requested (F9) */
401+ for (i = 0; i < 15; i++)
402+ memset(device[i].d, 0, 16);
403 load_rom();
404 goto restart;
405 }
406- } else if(audio_option) {
407- run_audio();
408- } else {
409- device[1].d[7]=1;
410- while((device[1].d[0] || device[1].d[1]) && ((i=fgetc(inf))>=0)) {
411- device[1].d[2]=i;
412- run(GET16(device[1].d));
413- }
414- if(use_extension && (device[1].d[6]&1)) {
415- device[1].d[2]=device[1].d[7]=0;
416- run(GET16(device[1].d));
417- }
418+ SDL_Quit();
419 }
420+
421 return 0;
422 }