update README
[rofl0r-gnuboy.git] / main.c
blobb5f4b7de3179b3cb4f606bd2dfd3c794c1d3495e
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"
17 #include "mem.h"
19 #include "Version"
22 static char *defaultconfig[] =
24 "bootrom_dmg \"\"",
25 "bootrom_gbc \"\"",
26 "bind esc quit",
27 "bind up +up",
28 "bind down +down",
29 "bind left +left",
30 "bind right +right",
31 "bind d +a",
32 "bind s +b",
33 "bind enter +start",
34 "bind space +select",
35 "bind tab +select",
36 "bind joyup +up",
37 "bind joydown +down",
38 "bind joyleft +left",
39 "bind joyright +right",
40 "bind joy0 +b",
41 "bind joy1 +a",
42 "bind joy2 +select",
43 "bind joy3 +start",
44 "bind 1 \"set saveslot 1\"",
45 "bind 2 \"set saveslot 2\"",
46 "bind 3 \"set saveslot 3\"",
47 "bind 4 \"set saveslot 4\"",
48 "bind 5 \"set saveslot 5\"",
49 "bind 6 \"set saveslot 6\"",
50 "bind 7 \"set saveslot 7\"",
51 "bind 8 \"set saveslot 8\"",
52 "bind 9 \"set saveslot 9\"",
53 "bind 0 \"set saveslot 0\"",
54 "bind ins savestate",
55 "bind del loadstate",
56 "source gnuboy.rc",
57 NULL
61 static void banner()
63 printf("\ngnuboy " VERSION "\n");
66 static void copyright()
68 banner();
69 printf(
70 "Copyright (C) 2000-2001 Laguna and Gilgamesh\n"
71 "Portions contributed by other authors; see CREDITS for details.\n"
72 "\n"
73 "This program is free software; you can redistribute it and/or modify\n"
74 "it under the terms of the GNU General Public License as published by\n"
75 "the Free Software Foundation; either version 2 of the License, or\n"
76 "(at your option) any later version.\n"
77 "\n"
78 "This program is distributed in the hope that it will be useful,\n"
79 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
80 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
81 "GNU General Public License for more details.\n"
82 "\n"
83 "You should have received a copy of the GNU General Public License\n"
84 "along with this program; if not, write to the Free Software\n"
85 "Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n"
86 "\n");
89 static void usage(char *name)
91 copyright();
92 printf("Type %s --help for detailed help.\n\n", name);
93 exit(1);
96 static void copying()
98 copyright();
99 exit(0);
102 static void joytest()
104 event_t e;
105 char *ename, *kname;
106 printf("press joystick buttons to see their name mappings\n");
107 joy_init();
108 while(1) {
109 ev_poll();
110 if(ev_getevent(&e)) {
111 switch(e.type) {
112 case EV_NONE: ename = "none"; break;
113 case EV_PRESS: ename = "press"; break;
114 case EV_RELEASE: ename = "release"; break;
115 case EV_REPEAT: ename = "repeat"; break;
116 case EV_MOUSE: ename = "mouse"; break;
117 default: ename = "unknown";
119 kname = k_keyname(e.code);
120 printf("%s: %s\n", ename, kname ? kname : "<null>");
121 } else {
122 sys_sleep(300);
125 joy_close();
126 exit(0);
129 static void help(char *name)
131 banner();
132 printf("Usage: %s [options] romfile\n", name);
133 printf("\n"
134 " --source FILE read rc commands from FILE\n"
135 " --bind KEY COMMAND bind KEY to perform COMMAND\n"
136 " --VAR=VALUE set rc variable VAR to VALUE\n"
137 " --VAR set VAR to 1 (turn on boolean options)\n"
138 " --no-VAR set VAR to 0 (turn off boolean options)\n"
139 " --showvars list all available rc variables\n"
140 " --help display this help and exit\n"
141 " --version output version information and exit\n"
142 " --copying show copying permissions\n"
143 " --joytest init joystick and show button names pressed\n"
144 " --rominfo show some info about the rom\n"
145 "");
146 exit(0);
149 static void rominfo(char* fn) {
150 extern int rom_load_simple(char *fn);
151 rom_load_simple(fn);
152 printf( "rom name:\t%s\n"
153 "mbc type:\t%s\n"
154 "rom size:\t%u KB\n"
155 "ram size:\t%u KB\n"
156 , rom.name, mbc_to_string(mbc.type), mbc.romsize*16, mbc.ramsize*8);
157 exit(0);
160 static void version(char *name)
162 printf("%s-" VERSION "\n", name);
163 exit(0);
167 void doevents()
169 event_t ev;
170 int st;
172 ev_poll();
173 while (ev_getevent(&ev))
175 if (ev.type != EV_PRESS && ev.type != EV_RELEASE)
176 continue;
177 st = (ev.type != EV_RELEASE);
178 rc_dokey(ev.code, st);
185 static void shutdown()
187 joy_close();
188 vid_close();
189 pcm_close();
192 void die(char *fmt, ...)
194 va_list ap;
196 va_start(ap, fmt);
197 vfprintf(stderr, fmt, ap);
198 va_end(ap);
199 exit(1);
202 static int bad_signals[] =
204 /* These are all standard, so no need to #ifdef them... */
205 SIGINT, SIGSEGV, SIGTERM, SIGFPE, SIGABRT, SIGILL,
206 #ifdef SIGQUIT
207 SIGQUIT,
208 #endif
209 #ifdef SIGPIPE
210 SIGPIPE,
211 #endif
215 static void fatalsignal(int s)
217 die("Signal %d\n", s);
220 static void catch_signals()
222 int i;
223 for (i = 0; bad_signals[i]; i++)
224 signal(bad_signals[i], fatalsignal);
229 static char *base(char *s)
231 char *p;
232 p = strrchr(s, '/');
233 if (p) return p+1;
234 return s;
238 int main(int argc, char *argv[])
240 int i, ri = 0, sv = 0;
241 char *opt, *arg, *cmd, *s, *rom = 0;
243 /* Avoid initializing video if we don't have to */
244 for (i = 1; i < argc; i++)
246 if (!strcmp(argv[i], "--help"))
247 help(base(argv[0]));
248 else if (!strcmp(argv[i], "--version"))
249 version(base(argv[0]));
250 else if (!strcmp(argv[i], "--copying"))
251 copying();
252 else if (!strcmp(argv[i], "--bind")) i += 2;
253 else if (!strcmp(argv[i], "--source")) i++;
254 else if (!strcmp(argv[i], "--showvars")) sv = 1;
255 else if (!strcmp(argv[i], "--joytest"))
256 joytest();
257 else if (!strcmp(argv[i], "--rominfo")) ri = 1;
258 else if (argv[i][0] == '-' && argv[i][1] == '-');
259 else if (argv[i][0] == '-' && argv[i][1]);
260 else rom = argv[i];
263 if (!rom && !sv) usage(base(argv[0]));
264 if (ri) rominfo(rom);
266 /* If we have special perms, drop them ASAP! */
267 vid_preinit();
269 init_exports();
271 s = strdup(argv[0]);
272 sys_sanitize(s);
273 sys_initpath(s);
275 for (i = 0; defaultconfig[i]; i++)
276 rc_command(defaultconfig[i]);
278 if (sv) {
279 show_exports();
280 exit(0);
283 cmd = malloc(strlen(rom) + 11);
284 sprintf(cmd, "source %s", rom);
285 s = strchr(cmd, '.');
286 if (s) *s = 0;
287 strcat(cmd, ".rc");
288 rc_command(cmd);
290 for (i = 1; i < argc; i++)
292 if (!strcmp(argv[i], "--bind"))
294 if (i + 2 >= argc) die("missing arguments to bind\n");
295 cmd = malloc(strlen(argv[i+1]) + strlen(argv[i+2]) + 9);
296 sprintf(cmd, "bind %s \"%s\"", argv[i+1], argv[i+2]);
297 rc_command(cmd);
298 free(cmd);
299 i += 2;
301 else if (!strcmp(argv[i], "--source"))
303 if (i + 1 >= argc) die("missing argument to source\n");
304 cmd = malloc(strlen(argv[i+1]) + 6);
305 sprintf(cmd, "source %s", argv[++i]);
306 rc_command(cmd);
307 free(cmd);
309 else if (!strncmp(argv[i], "--no-", 5))
311 opt = strdup(argv[i]+5);
312 while ((s = strchr(opt, '-'))) *s = '_';
313 cmd = malloc(strlen(opt) + 7);
314 sprintf(cmd, "set %s 0", opt);
315 rc_command(cmd);
316 free(cmd);
317 free(opt);
319 else if (argv[i][0] == '-' && argv[i][1] == '-')
321 opt = strdup(argv[i]+2);
322 if ((s = strchr(opt, '=')))
324 *s = 0;
325 arg = s+1;
327 else arg = "1";
328 while ((s = strchr(opt, '-'))) *s = '_';
329 while ((s = strchr(arg, ','))) *s = ' ';
331 cmd = malloc(strlen(opt) + strlen(arg) + 6);
332 sprintf(cmd, "set %s %s", opt, arg);
334 rc_command(cmd);
335 free(cmd);
336 free(opt);
338 /* short options not yet implemented */
339 else if (argv[i][0] == '-' && argv[i][1]);
342 /* FIXME - make interface modules responsible for atexit() */
343 atexit(shutdown);
344 catch_signals();
345 vid_init();
346 joy_init();
347 pcm_init();
349 rom = strdup(rom);
350 sys_sanitize(rom);
352 loader_init(rom);
354 emu_reset();
355 emu_run();
357 /* never reached */
358 return 0;