undo push-model SDL2 sound backend, use SDL1 approach
[rofl0r-gnuboy.git] / main.c
blobb0c2e75cb8c2c5de8035afb075285dd14fc1539d
1 #undef _GNU_SOURCE
2 #define _GNU_SOURCE
3 #include <string.h>
4 #include <stdio.h>
5 #include <stdlib.h>
7 #include <stdarg.h>
8 #include <signal.h>
10 #include "input.h"
11 #include "rc.h"
12 #include "sys.h"
13 #include "rckeys.h"
14 #include "emu.h"
15 #include "exports.h"
16 #include "loader.h"
18 #include "Version"
21 static char *defaultconfig[] =
23 "bind esc quit",
24 "bind up +up",
25 "bind down +down",
26 "bind left +left",
27 "bind right +right",
28 "bind d +a",
29 "bind s +b",
30 "bind enter +start",
31 "bind space +select",
32 "bind tab +select",
33 "bind joyup +up",
34 "bind joydown +down",
35 "bind joyleft +left",
36 "bind joyright +right",
37 "bind joy0 +b",
38 "bind joy1 +a",
39 "bind joy2 +select",
40 "bind joy3 +start",
41 "bind 1 \"set saveslot 1\"",
42 "bind 2 \"set saveslot 2\"",
43 "bind 3 \"set saveslot 3\"",
44 "bind 4 \"set saveslot 4\"",
45 "bind 5 \"set saveslot 5\"",
46 "bind 6 \"set saveslot 6\"",
47 "bind 7 \"set saveslot 7\"",
48 "bind 8 \"set saveslot 8\"",
49 "bind 9 \"set saveslot 9\"",
50 "bind 0 \"set saveslot 0\"",
51 "bind ins savestate",
52 "bind del loadstate",
53 "source gnuboy.rc",
54 NULL
58 static void banner()
60 printf("\ngnuboy " VERSION "\n");
63 static void copyright()
65 banner();
66 printf(
67 "Copyright (C) 2000-2001 Laguna and Gilgamesh\n"
68 "Portions contributed by other authors; see CREDITS for details.\n"
69 "\n"
70 "This program is free software; you can redistribute it and/or modify\n"
71 "it under the terms of the GNU General Public License as published by\n"
72 "the Free Software Foundation; either version 2 of the License, or\n"
73 "(at your option) any later version.\n"
74 "\n"
75 "This program is distributed in the hope that it will be useful,\n"
76 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
77 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
78 "GNU General Public License for more details.\n"
79 "\n"
80 "You should have received a copy of the GNU General Public License\n"
81 "along with this program; if not, write to the Free Software\n"
82 "Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n"
83 "\n");
86 static void usage(char *name)
88 copyright();
89 printf("Type %s --help for detailed help.\n\n", name);
90 exit(1);
93 static void copying()
95 copyright();
96 exit(0);
99 static void joytest()
101 event_t e;
102 char *ename, *kname;
103 printf("press joystick buttons to see their name mappings\n");
104 joy_init();
105 while(1) {
106 ev_poll();
107 if(ev_getevent(&e)) {
108 switch(e.type) {
109 case EV_NONE: ename = "none"; break;
110 case EV_PRESS: ename = "press"; break;
111 case EV_RELEASE: ename = "release"; break;
112 case EV_REPEAT: ename = "repeat"; break;
113 case EV_MOUSE: ename = "mouse"; break;
114 default: ename = "unknown";
116 kname = k_keyname(e.code);
117 printf("%s: %s\n", ename, kname ? kname : "<null>");
118 } else {
119 sys_sleep(300);
122 joy_close();
123 exit(0);
126 static void help(char *name)
128 banner();
129 printf("Usage: %s [options] romfile\n", name);
130 printf("\n"
131 " --source FILE read rc commands from FILE\n"
132 " --bind KEY COMMAND bind KEY to perform COMMAND\n"
133 " --VAR=VALUE set rc variable VAR to VALUE\n"
134 " --VAR set VAR to 1 (turn on boolean options)\n"
135 " --no-VAR set VAR to 0 (turn off boolean options)\n"
136 " --showvars list all available rc variables\n"
137 " --help display this help and exit\n"
138 " --version output version information and exit\n"
139 " --copying show copying permissions\n"
140 " --joytest init joystick and show button names pressed\n"
141 "");
142 exit(0);
146 static void version(char *name)
148 printf("%s-" VERSION "\n", name);
149 exit(0);
153 void doevents()
155 event_t ev;
156 int st;
158 ev_poll();
159 while (ev_getevent(&ev))
161 if (ev.type != EV_PRESS && ev.type != EV_RELEASE)
162 continue;
163 st = (ev.type != EV_RELEASE);
164 rc_dokey(ev.code, st);
171 static void shutdown()
173 joy_close();
174 vid_close();
175 pcm_close();
178 void die(char *fmt, ...)
180 va_list ap;
182 va_start(ap, fmt);
183 vfprintf(stderr, fmt, ap);
184 va_end(ap);
185 exit(1);
188 static int bad_signals[] =
190 /* These are all standard, so no need to #ifdef them... */
191 SIGINT, SIGSEGV, SIGTERM, SIGFPE, SIGABRT, SIGILL,
192 #ifdef SIGQUIT
193 SIGQUIT,
194 #endif
195 #ifdef SIGPIPE
196 SIGPIPE,
197 #endif
201 static void fatalsignal(int s)
203 die("Signal %d\n", s);
206 static void catch_signals()
208 int i;
209 for (i = 0; bad_signals[i]; i++)
210 signal(bad_signals[i], fatalsignal);
215 static char *base(char *s)
217 char *p;
218 p = strrchr(s, '/');
219 if (p) return p+1;
220 return s;
224 int main(int argc, char *argv[])
226 int i;
227 char *opt, *arg, *cmd, *s, *rom = 0;
229 /* Avoid initializing video if we don't have to */
230 for (i = 1; i < argc; i++)
232 if (!strcmp(argv[i], "--help"))
233 help(base(argv[0]));
234 else if (!strcmp(argv[i], "--version"))
235 version(base(argv[0]));
236 else if (!strcmp(argv[i], "--copying"))
237 copying();
238 else if (!strcmp(argv[i], "--bind")) i += 2;
239 else if (!strcmp(argv[i], "--source")) i++;
240 else if (!strcmp(argv[i], "--showvars"))
242 show_exports();
243 exit(0);
245 else if (!strcmp(argv[i], "--joytest"))
246 joytest();
247 else if (argv[i][0] == '-' && argv[i][1] == '-');
248 else if (argv[i][0] == '-' && argv[i][1]);
249 else rom = argv[i];
252 if (!rom) usage(base(argv[0]));
254 /* If we have special perms, drop them ASAP! */
255 vid_preinit();
257 init_exports();
259 s = strdup(argv[0]);
260 sys_sanitize(s);
261 sys_initpath(s);
263 for (i = 0; defaultconfig[i]; i++)
264 rc_command(defaultconfig[i]);
266 cmd = malloc(strlen(rom) + 11);
267 sprintf(cmd, "source %s", rom);
268 s = strchr(cmd, '.');
269 if (s) *s = 0;
270 strcat(cmd, ".rc");
271 rc_command(cmd);
273 for (i = 1; i < argc; i++)
275 if (!strcmp(argv[i], "--bind"))
277 if (i + 2 >= argc) die("missing arguments to bind\n");
278 cmd = malloc(strlen(argv[i+1]) + strlen(argv[i+2]) + 9);
279 sprintf(cmd, "bind %s \"%s\"", argv[i+1], argv[i+2]);
280 rc_command(cmd);
281 free(cmd);
282 i += 2;
284 else if (!strcmp(argv[i], "--source"))
286 if (i + 1 >= argc) die("missing argument to source\n");
287 cmd = malloc(strlen(argv[i+1]) + 6);
288 sprintf(cmd, "source %s", argv[++i]);
289 rc_command(cmd);
290 free(cmd);
292 else if (!strncmp(argv[i], "--no-", 5))
294 opt = strdup(argv[i]+5);
295 while ((s = strchr(opt, '-'))) *s = '_';
296 cmd = malloc(strlen(opt) + 7);
297 sprintf(cmd, "set %s 0", opt);
298 rc_command(cmd);
299 free(cmd);
300 free(opt);
302 else if (argv[i][0] == '-' && argv[i][1] == '-')
304 opt = strdup(argv[i]+2);
305 if ((s = strchr(opt, '=')))
307 *s = 0;
308 arg = s+1;
310 else arg = "1";
311 while ((s = strchr(opt, '-'))) *s = '_';
312 while ((s = strchr(arg, ','))) *s = ' ';
314 cmd = malloc(strlen(opt) + strlen(arg) + 6);
315 sprintf(cmd, "set %s %s", opt, arg);
317 rc_command(cmd);
318 free(cmd);
319 free(opt);
321 /* short options not yet implemented */
322 else if (argv[i][0] == '-' && argv[i][1]);
325 /* FIXME - make interface modules responsible for atexit() */
326 atexit(shutdown);
327 catch_signals();
328 vid_init();
329 joy_init();
330 pcm_init();
332 rom = strdup(rom);
333 sys_sanitize(rom);
335 loader_init(rom);
337 emu_reset();
338 emu_run();
340 /* never reached */
341 return 0;