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 }