|
|
1.1 root 1: /*
2: Hatari - options.c
3:
4: This file is distributed under the GNU Public License, version 2 or at
5: your option any later version. Read the file gpl.txt for details.
6:
7: Functions for showing and parsing all of Hatari's command line options.
8:
9: To add a new option:
10: - Add option ID to the enum
1.1.1.2 root 11: - Add the option information to HatariOptions[]
1.1 root 12: - Add required actions for that ID to switch in Opt_ParseParameters()
13: */
1.1.1.5 ! root 14: const char Options_fileid[] = "Hatari options.c : " __DATE__ " " __TIME__;
1.1.1.2 root 15:
16: #include <ctype.h>
1.1 root 17: #include <stdio.h>
18: #include <stdlib.h>
19: #include <string.h>
20: #include <assert.h>
21:
22: #include "main.h"
23: #include "options.h"
24: #include "configuration.h"
1.1.1.4 root 25: #include "control.h"
1.1 root 26: #include "file.h"
1.1.1.4 root 27: #include "floppy.h"
1.1 root 28: #include "screen.h"
29: #include "video.h"
30: #include "vdi.h"
31: #include "joy.h"
1.1.1.4 root 32: #include "log.h"
1.1.1.2 root 33:
34: #include "hatari-glue.h"
35:
1.1 root 36:
1.1.1.4 root 37: bool bLoadAutoSave; /* Load autosave memory snapshot at startup */
38: bool bLoadMemorySave; /* Load memory snapshot provided via option at startup */
39: bool bBiosIntercept; /* whether UAE should intercept Bios & XBios calls */
1.1 root 40:
41:
42: /* List of supported options. */
43: enum {
1.1.1.2 root 44: OPT_HEADER, /* options section header */
45: OPT_HELP, /* general options */
1.1 root 46: OPT_VERSION,
1.1.1.2 root 47: OPT_CONFIRMQUIT,
48: OPT_CONFIGFILE,
1.1.1.4 root 49: OPT_FASTFORWARD,
1.1.1.2 root 50: OPT_MONO, /* display options */
51: OPT_MONITOR,
1.1 root 52: OPT_FULLSCREEN,
53: OPT_WINDOW,
1.1.1.2 root 54: OPT_ZOOM,
55: OPT_FRAMESKIPS,
56: OPT_BORDERS,
1.1.1.4 root 57: OPT_STATUSBAR,
58: OPT_DRIVE_LED,
1.1.1.2 root 59: OPT_SPEC512,
60: OPT_FORCEBPP,
1.1.1.4 root 61: OPT_VDI, /* VDI options */
62: OPT_VDI_PLANES,
1.1.1.2 root 63: OPT_VDI_WIDTH,
64: OPT_VDI_HEIGHT,
65: OPT_JOYSTICK, /* device options */
1.1.1.4 root 66: OPT_JOYSTICK0,
67: OPT_JOYSTICK1,
68: OPT_JOYSTICK2,
69: OPT_JOYSTICK3,
70: OPT_JOYSTICK4,
71: OPT_JOYSTICK5,
1.1 root 72: OPT_PRINTER,
1.1.1.5 ! root 73: OPT_MIDI_IN,
! 74: OPT_MIDI_OUT,
! 75: OPT_RS232_IN,
! 76: OPT_RS232_OUT,
1.1.1.4 root 77: OPT_DISKA, /* disk options */
78: OPT_DISKB,
79: OPT_HARDDRIVE,
1.1.1.2 root 80: OPT_ACSIHDIMAGE,
81: OPT_IDEHDIMAGE,
82: OPT_SLOWFDC,
83: OPT_MEMSIZE, /* memory options */
1.1 root 84: OPT_TOS,
85: OPT_CARTRIDGE,
1.1.1.2 root 86: OPT_MEMSTATE,
87: OPT_CPULEVEL, /* CPU options */
88: OPT_CPUCLOCK,
1.1 root 89: OPT_COMPATIBLE,
1.1.1.2 root 90: OPT_MACHINE, /* system options */
1.1 root 91: OPT_BLITTER,
1.1.1.2 root 92: OPT_DSP,
93: OPT_SOUND,
1.1 root 94: OPT_KEYMAPFILE,
1.1.1.2 root 95: OPT_DEBUG, /* debug options */
1.1.1.4 root 96: OPT_BIOSINTERCEPT,
1.1.1.2 root 97: OPT_TRACE,
1.1.1.4 root 98: OPT_TRACEFILE,
99: OPT_CONTROLSOCKET,
100: OPT_LOGFILE,
101: OPT_LOGLEVEL,
102: OPT_ALERTLEVEL,
103: OPT_ERROR,
104: OPT_CONTINUE
1.1 root 105: };
106:
107: typedef struct {
108: unsigned int id; /* option ID */
109: const char *chr; /* short option */
110: const char *str; /* long option */
1.1.1.2 root 111: const char *arg; /* type name for argument, if any */
1.1 root 112: const char *desc; /* option description */
113: } opt_t;
114:
1.1.1.2 root 115: /* it's easier to edit these if they are kept in the same order as the enums */
1.1 root 116: static const opt_t HatariOptions[] = {
1.1.1.2 root 117:
118: { OPT_HEADER, NULL, NULL, NULL, "General" },
1.1 root 119: { OPT_HELP, "-h", "--help",
120: NULL, "Print this help text and exit" },
121: { OPT_VERSION, "-v", "--version",
1.1.1.2 root 122: NULL, "Print version number and exit" },
1.1.1.4 root 123: { OPT_CONFIRMQUIT, NULL, "--confirm-quit",
1.1.1.2 root 124: "<bool>", "Whether Hatari confirms quit" },
1.1.1.4 root 125: { OPT_CONFIGFILE, "-c", "--configfile",
126: "<file>", "Use <file> instead of the default hatari config file" },
127: { OPT_FASTFORWARD, NULL, "--fast-forward",
128: "<bool>", "Help skipping stuff on fast machine" },
129:
1.1.1.2 root 130: { OPT_HEADER, NULL, NULL, NULL, "Display" },
1.1 root 131: { OPT_MONO, "-m", "--mono",
132: NULL, "Start in monochrome mode instead of color" },
1.1.1.2 root 133: { OPT_MONITOR, NULL, "--monitor",
134: "<x>", "Select monitor type (x = mono/rgb/vga/tv)" },
1.1 root 135: { OPT_FULLSCREEN,"-f", "--fullscreen",
136: NULL, "Start emulator in fullscreen mode" },
137: { OPT_WINDOW, "-w", "--window",
138: NULL, "Start emulator in window mode" },
1.1.1.2 root 139: { OPT_ZOOM, "-z", "--zoom",
140: "<x>", "Double ST low resolution (1=no, 2=yes)" },
141: { OPT_FRAMESKIPS, NULL, "--frameskips",
1.1.1.4 root 142: "<x>", "Skip <x> frames after each shown frame (0=off, >4=auto/max)" },
1.1.1.2 root 143: { OPT_BORDERS, NULL, "--borders",
144: "<bool>", "Show screen borders (for overscan demos etc)" },
1.1.1.4 root 145: { OPT_STATUSBAR, NULL, "--statusbar",
146: "<bool>", "Show statusbar (floppy leds etc)" },
147: { OPT_DRIVE_LED, NULL, "--drive-led",
148: "<bool>", "Show overlay drive led when statusbar isn't shown" },
1.1.1.2 root 149: { OPT_SPEC512, NULL, "--spec512",
150: "<x>", "Spec512 palette threshold (0 <= x <= 512, 0=disable)" },
151: { OPT_FORCEBPP, NULL, "--bpp",
1.1.1.4 root 152: "<x>", "Force internal bitdepth (x = 8/15/16/32, 0=disable)" },
1.1.1.2 root 153:
154: { OPT_HEADER, NULL, NULL, NULL, "VDI" },
1.1.1.4 root 155: { OPT_VDI, NULL, "--vdi",
156: "<bool>", "Whether to use VDI screen mode" },
1.1.1.2 root 157: { OPT_VDI_PLANES,NULL, "--vdi-planes",
1.1.1.4 root 158: "<x>", "VDI mode bit-depth (x = 1/2/4)" },
1.1.1.2 root 159: { OPT_VDI_WIDTH, NULL, "--vdi-width",
1.1.1.4 root 160: "<w>", "VDI mode width (320 < w <= 1024)" },
1.1.1.2 root 161: { OPT_VDI_HEIGHT, NULL, "--vdi-height",
1.1.1.4 root 162: "<h>", "VDI mode height (200 < h <= 768)" },
1.1.1.2 root 163:
164: { OPT_HEADER, NULL, NULL, NULL, "Devices" },
1.1 root 165: { OPT_JOYSTICK, "-j", "--joystick",
1.1.1.2 root 166: "<port>", "Emulate joystick with cursor keys in given port (0-5)" },
1.1.1.4 root 167: /* these have to be exactly the same as I'm relying compiler giving
168: * them the same same string pointer when strings are identical
169: */
170: { OPT_JOYSTICK0, NULL, "--joy<port>",
171: "<type>", "Set joystick type (none/keys/real) for given port" },
172: { OPT_JOYSTICK1, NULL, "--joy<port>",
173: "<type>", "Set joystick type (none/keys/real) for given port" },
174: { OPT_JOYSTICK2, NULL, "--joy<port>",
175: "<type>", "Set joystick type (none/keys/real) for given port" },
176: { OPT_JOYSTICK3, NULL, "--joy<port>",
177: "<type>", "Set joystick type (none/keys/real) for given port" },
178: { OPT_JOYSTICK4, NULL, "--joy<port>",
179: "<type>", "Set joystick type (none/keys/real) for given port" },
180: { OPT_JOYSTICK5, NULL, "--joy<port>",
181: "<type>", "Set joystick type (none/keys/real) for given port" },
1.1 root 182: { OPT_PRINTER, NULL, "--printer",
1.1.1.2 root 183: "<file>", "Enable printer support and write data to <file>" },
1.1.1.5 ! root 184: { OPT_MIDI_IN, NULL, "--midi-in",
! 185: "<file>", "Enable MIDI and use <file> as the input device" },
! 186: { OPT_MIDI_OUT, NULL, "--midi-out",
! 187: "<file>", "Enable MIDI and use <file> as the output device" },
! 188: { OPT_RS232_IN, NULL, "--rs232-in",
! 189: "<file>", "Enable serial port and use <file> as the input device" },
! 190: { OPT_RS232_OUT, NULL, "--rs232-out",
! 191: "<file>", "Enable serial port and use <file> as the output device" },
1.1.1.2 root 192:
193: { OPT_HEADER, NULL, NULL, NULL, "Disk" },
1.1.1.4 root 194: { OPT_DISKA, NULL, "--disk-a",
195: "<file>", "Set disk image for floppy drive A" },
196: { OPT_DISKB, NULL, "--disk-b",
197: "<file>", "Set disk image for floppy drive B" },
1.1 root 198: { OPT_HARDDRIVE, "-d", "--harddrive",
199: "<dir>", "Emulate an ST harddrive (<dir> = root directory)" },
1.1.1.2 root 200: { OPT_ACSIHDIMAGE, NULL, "--acsi",
201: "<file>", "Emulate an ACSI harddrive with an image <file>" },
202: { OPT_IDEHDIMAGE, NULL, "--ide",
203: "<file>", "Emulate an IDE harddrive using <file> (not working yet)" },
204: { OPT_SLOWFDC, NULL, "--slowfdc",
205: "<bool>", "Slow down FDC emulation (deprecated)" },
206:
207: { OPT_HEADER, NULL, NULL, NULL, "Memory" },
208: { OPT_MEMSIZE, "-s", "--memsize",
1.1.1.4 root 209: "<x>", "ST RAM size (x = size in MiB from 0 to 14, 0 = 512KiB)" },
1.1 root 210: { OPT_TOS, "-t", "--tos",
211: "<file>", "Use TOS image <file>" },
212: { OPT_CARTRIDGE, NULL, "--cartridge",
213: "<file>", "Use ROM cartridge image <file>" },
1.1.1.2 root 214: { OPT_MEMSTATE, NULL, "--memstate",
215: "<file>", "Load memory snap-shot <file>" },
216:
217: { OPT_HEADER, NULL, NULL, NULL, "CPU" },
1.1 root 218: { OPT_CPULEVEL, NULL, "--cpulevel",
1.1.1.2 root 219: "<x>", "Set the CPU type (x => 680x0) (EmuTOS/TOS 2.06 only!)" },
220: { OPT_CPUCLOCK, NULL, "--cpuclock",
1.1.1.4 root 221: "<x>", "Set the CPU clock (x = 8/16/32)" },
222: { OPT_COMPATIBLE, NULL, "--compatible",
1.1.1.2 root 223: "<bool>", "Use a more compatible (but slower) 68000 CPU mode" },
224:
225: { OPT_HEADER, NULL, NULL, NULL, "Misc system" },
226: { OPT_MACHINE, NULL, "--machine",
227: "<x>", "Select machine type (x = st/ste/tt/falcon)" },
1.1 root 228: { OPT_BLITTER, NULL, "--blitter",
1.1.1.2 root 229: "<bool>", "Use blitter emulation (ST only)" },
230: { OPT_DSP, NULL, "--dsp",
1.1.1.4 root 231: "<x>", "DSP emulation (x = none/dummy/emu, Falcon only)" },
1.1.1.2 root 232: { OPT_SOUND, NULL, "--sound",
1.1.1.4 root 233: "<x>", "Sound quality (x = off/low/med/hi, off=faster)" },
234: { OPT_KEYMAPFILE, "-k", "--keymap",
1.1 root 235: "<file>", "Read (additional) keyboard mappings from <file>" },
1.1.1.2 root 236:
237: { OPT_HEADER, NULL, NULL, NULL, "Debug" },
238: { OPT_DEBUG, "-D", "--debug",
1.1.1.4 root 239: NULL, "Enable Hatari debugger console interface" },
240: { OPT_BIOSINTERCEPT, NULL, "--bios-intercept",
241: NULL, "Enable Bios/XBios interception (experimental)" },
1.1.1.2 root 242: { OPT_TRACE, NULL, "--trace",
1.1.1.4 root 243: "<trace1,...>", "Activate emulation tracing, see '--trace help'" },
244: { OPT_TRACEFILE, NULL, "--trace-file",
245: "<file>", "Save trace output to <file> (default=stderr)" },
246: #if HAVE_UNIX_DOMAIN_SOCKETS
247: { OPT_CONTROLSOCKET, NULL, "--control-socket",
248: "<file>", "Hatari reads options from given socket at run-time" },
249: #endif
250: { OPT_LOGFILE, NULL, "--log-file",
251: "<file>", "Save log output to <file> (default=stderr)" },
252: { OPT_LOGLEVEL, NULL, "--log-level",
253: "<x>", "Log output level (x=debug/todo/info/warn/error/fatal)" },
254: { OPT_ALERTLEVEL, NULL, "--alert-level",
255: "<x>", "Show dialog for log messages above given level" },
256:
257: { OPT_ERROR, NULL, NULL, NULL, NULL }
1.1 root 258: };
259:
1.1.1.2 root 260:
261: /**
262: * Show version string and license.
1.1 root 263: */
1.1.1.2 root 264: static void Opt_ShowVersion(void)
265: {
1.1.1.4 root 266: printf("\n" PROG_NAME
267: " - the Atari ST, STE, TT and Falcon emulator.\n\n");
1.1.1.2 root 268: printf("Hatari is free software licensed under the GNU General"
269: " Public License.\n\n");
270: }
271:
272:
273: /**
274: * Calculate option + value len
275: */
276: static unsigned int Opt_OptionLen(const opt_t *opt)
277: {
278: unsigned int len;
279: len = strlen(opt->str);
280: if (opt->arg)
281: {
282: len += strlen(opt->arg);
283: len += 1;
284: /* with arg, short options go to another line */
285: }
286: else
287: {
288: if (opt->chr)
289: {
290: /* ' or -c' */
291: len += 6;
292: }
293: }
294: return len;
295: }
296:
297:
298: /**
299: * Show single option
300: */
301: static void Opt_ShowOption(const opt_t *opt, unsigned int maxlen)
1.1 root 302: {
303: char buf[64];
1.1.1.2 root 304: if (!maxlen)
305: {
306: maxlen = Opt_OptionLen(opt);
307: }
308: assert(maxlen < sizeof(buf));
309: if (opt->arg)
310: {
311: sprintf(buf, "%s %s", opt->str, opt->arg);
312: printf(" %-*s %s\n", maxlen, buf, opt->desc);
313: if (opt->chr)
314: {
315: printf(" or %s %s\n", opt->chr, opt->arg);
316: }
317: }
318: else
319: {
320: if (opt->chr)
321: {
322: sprintf(buf, "%s or %s", opt->str, opt->chr);
323: printf(" %-*s %s\n", maxlen, buf, opt->desc);
1.1 root 324: }
1.1.1.2 root 325: else
326: {
327: printf(" %-*s %s\n", maxlen, opt->str, opt->desc);
328: }
329: }
330: }
331:
332: /**
333: * Show options for section starting from 'start_opt',
334: * return next option after this section.
335: */
336: static const opt_t *Opt_ShowHelpSection(const opt_t *start_opt)
337: {
338: const opt_t *opt, *last;
339: unsigned int len, maxlen = 0;
1.1.1.4 root 340: const char *previous = NULL;
1.1.1.2 root 341:
342: /* find longest option name and check option IDs */
1.1.1.4 root 343: for (opt = start_opt; opt->id != OPT_HEADER && opt->id != OPT_ERROR; opt++)
1.1.1.2 root 344: {
345: len = Opt_OptionLen(opt);
346: if (len > maxlen)
347: {
1.1 root 348: maxlen = len;
349: }
350: }
1.1.1.2 root 351: last = opt;
1.1 root 352:
353: /* output all options */
1.1.1.2 root 354: for (opt = start_opt; opt != last; opt++)
355: {
1.1.1.4 root 356: if (previous != opt->str)
357: {
358: Opt_ShowOption(opt, maxlen);
359: }
360: previous = opt->str;
1.1.1.2 root 361: }
362: return last;
363: }
364:
365:
366: /**
367: * Show help text.
368: */
369: static void Opt_ShowHelp(void)
370: {
371: const opt_t *opt = HatariOptions;
372:
373: Opt_ShowVersion();
374: printf("Usage:\n hatari [options] [disk image name]\n");
375:
1.1.1.4 root 376: while(opt->id != OPT_ERROR)
1.1.1.2 root 377: {
378: if (opt->id == OPT_HEADER)
379: {
380: assert(opt->desc);
381: printf("\n%s options:\n", opt->desc);
382: opt++;
1.1 root 383: }
1.1.1.2 root 384: opt = Opt_ShowHelpSection(opt);
1.1 root 385: }
1.1.1.2 root 386: printf("\nSpecial option values:\n");
387: printf("<bool>\tDisable by using 'n', 'no', 'off', 'false', or '0'\n");
388: printf("\tEnable by using 'y', 'yes', 'on', 'true' or '1'\n");
389: printf("<file>\tDevices accept also special 'stdout' and 'stderr' file names\n");
390: printf("\t(if you use stdout for midi or printer, set log to stderr).\n");
391: printf("\tSetting the file to 'none', disables given device or disk\n");
392: }
393:
394:
395: /**
1.1.1.4 root 396: * Show Hatari version and usage.
1.1.1.2 root 397: * If 'error' given, show that error message.
1.1.1.4 root 398: * If 'optid' != OPT_ERROR, tells for which option the error is,
1.1.1.2 root 399: * otherwise 'value' is show as the option user gave.
1.1.1.4 root 400: * Return FALSE if error string was given, otherwise TRUE
1.1.1.2 root 401: */
1.1.1.4 root 402: static bool Opt_ShowError(unsigned int optid, const char *value, const char *error)
1.1.1.2 root 403: {
404: const opt_t *opt;
405:
406: Opt_ShowVersion();
407: printf("Usage:\n hatari [options] [disk image name]\n\n"
408: "Try option \"-h\" or \"--help\" to display more information.\n");
409:
410: if (error)
411: {
1.1.1.4 root 412: if (optid == OPT_ERROR)
1.1.1.2 root 413: {
1.1 root 414: fprintf(stderr, "\nError: %s (%s)\n", error, value);
415: }
1.1.1.2 root 416: else
417: {
1.1.1.4 root 418: for (opt = HatariOptions; opt->id != OPT_ERROR; opt++)
1.1.1.2 root 419: {
420: if (optid == opt->id)
421: break;
422: }
423: if (value != NULL)
424: {
425: fprintf(stderr, "\nError while parsing parameter for %s:\n"
426: " %s (%s)\n", opt->str, error, value);
427: }
428: else
429: {
430: fprintf(stderr, "\nError (%s): %s\n", opt->str, error);
431: }
432: Opt_ShowOption(opt, 0);
433: }
1.1.1.4 root 434: return FALSE;
1.1 root 435: }
1.1.1.4 root 436: return TRUE;
1.1 root 437: }
438:
1.1.1.2 root 439:
440: /**
1.1.1.4 root 441: * If 'conf' given, set it:
442: * - TRUE if given option 'arg' is y/yes/on/true/1
443: * - FALSE if given option 'arg' is n/no/off/false/0
444: * Return FALSE for any other value, otherwise TRUE
1.1.1.2 root 445: */
1.1.1.4 root 446: static bool Opt_Bool(const char *arg, int optid, bool *conf)
1.1.1.2 root 447: {
448: const char *enablers[] = { "y", "yes", "on", "true", "1", NULL };
449: const char *disablers[] = { "n", "no", "off", "false", "0", NULL };
450: const char **bool_str, *orig = arg;
451: char *input, *str;
452:
453: input = strdup(arg);
454: str = input;
455: while (*str)
456: {
457: *str++ = tolower(*arg++);
458: }
459: for (bool_str = enablers; *bool_str; bool_str++)
460: {
461: if (strcmp(input, *bool_str) == 0)
462: {
463: free(input);
1.1.1.4 root 464: if (conf)
465: {
466: *conf = TRUE;
467: }
1.1.1.2 root 468: return TRUE;
469: }
470: }
471: for (bool_str = disablers; *bool_str; bool_str++)
472: {
473: if (strcmp(input, *bool_str) == 0)
474: {
475: free(input);
1.1.1.4 root 476: if (conf)
477: {
478: *conf = FALSE;
479: }
480: return TRUE;
1.1.1.2 root 481: }
482: }
483: free(input);
1.1.1.4 root 484: return Opt_ShowError(optid, orig, "Not a <bool> value");
485: }
486:
487:
488: /**
489: * checks str argument agaist options of type "--option<digit>".
490: * If match is found, returns ID for that, otherwise OPT_CONTINUE
491: * and OPT_ERROR for errors.
492: */
493: static int Opt_CheckBracketValue(const opt_t *opt, const char *str)
494: {
495: const char *bracket, *optstr;
496: size_t offset;
497: int digit, i;
498:
499: if (!opt->str)
500: {
501: return OPT_CONTINUE;
502: }
503: bracket = strchr(opt->str, '<');
504: if (!bracket)
505: {
506: return OPT_CONTINUE;
507: }
508: offset = bracket - opt->str;
509: if (strlen(str) != offset + 1)
510: {
511: return OPT_CONTINUE;
512: }
513: digit = str[offset] - '0';
514: if (digit < 0 || digit > 9)
515: {
516: return OPT_CONTINUE;
517: }
518: optstr = opt->str;
519: for (i = 0; opt->str == optstr; opt++, i++)
520: {
521: if (i == digit)
522: {
523: return opt->id;
524: }
525: }
526: /* fprintf(stderr, "opt: %s (%d), str: %s (%d), digit: %d\n",
527: opt->str, offset+1, str, strlen(str), digit);
528: */
529: return OPT_ERROR;
1.1.1.2 root 530: }
531:
532:
533: /**
1.1 root 534: * matches string under given index in the argv against all Hatari
535: * short and long options. If match is found, returns ID for that,
1.1.1.4 root 536: * otherwise shows help and returns OPT_ERROR.
1.1 root 537: *
538: * Checks also that if option is supposed to have argument,
539: * whether there's one.
540: */
1.1.1.4 root 541: static int Opt_WhichOption(int argc, const char *argv[], int idx)
1.1 root 542: {
543: const opt_t *opt;
544: const char *str = argv[idx];
1.1.1.4 root 545: int id;
1.1 root 546:
1.1.1.4 root 547: for (opt = HatariOptions; opt->id != OPT_ERROR; opt++)
1.1.1.2 root 548: {
549: if ((opt->str && !strcmp(str, opt->str)) ||
550: (opt->chr && !strcmp(str, opt->chr)))
551: {
552:
553: if (opt->arg)
554: {
555: if (idx+1 >= argc)
556: {
1.1.1.4 root 557: Opt_ShowError(opt->id, NULL, "Missing argument");
558: return OPT_ERROR;
1.1.1.2 root 559: }
560: /* early check for bools */
561: if (strcmp(opt->arg, "<bool>") == 0)
562: {
1.1.1.4 root 563: if (!Opt_Bool(argv[idx+1], opt->id, NULL))
564: {
565: return OPT_ERROR;
566: }
1.1.1.2 root 567: }
1.1 root 568: }
569: return opt->id;
570: }
1.1.1.4 root 571: id = Opt_CheckBracketValue(opt, str);
572: if (id == OPT_ERROR)
573: {
574: break;
575: }
576: if (id != OPT_CONTINUE)
577: {
578: return id;
579: }
1.1 root 580: }
1.1.1.4 root 581: Opt_ShowError(OPT_ERROR, argv[idx], "Unrecognized option");
582: return OPT_ERROR;
1.1 root 583: }
584:
1.1.1.2 root 585:
586: /**
1.1.1.4 root 587: * If 'checkexits' is TRUE, assume 'src' is a file and check whether it
588: * exists before copying 'src' to 'dst'. Otherwise just copy option src
589: * string to dst.
590: * If a pointer to (bool) 'option' is given, set that option to TRUE.
591: * - However, if src is "none", leave dst unmodified & set option to FALSE.
592: * ("none" is used to disable options related to file arguments)
593: * Return FALSE if there were errors, otherwise TRUE
1.1.1.2 root 594: */
1.1.1.4 root 595: static bool Opt_StrCpy(int optid, bool checkexist, char *dst, const char *src, size_t dstlen, bool *option)
1.1.1.2 root 596: {
1.1.1.4 root 597: if (strlen(src) >= dstlen)
598: {
599: return Opt_ShowError(optid, src, "File name too long!");
600: }
601: if (checkexist && !File_Exists(src))
602: {
603: return Opt_ShowError(optid, src, "Given file doesn't exist (or has wrong file permissions)!");
604: }
1.1.1.2 root 605: if (option)
606: {
607: if(strcmp(src, "none") == 0)
608: {
609: *option = FALSE;
1.1.1.4 root 610: return TRUE;
1.1.1.2 root 611: }
612: else
613: {
614: *option = TRUE;
615: }
616: }
1.1.1.4 root 617: strcpy(dst, src);
618: return TRUE;
1.1.1.2 root 619: }
620:
621:
622: /**
1.1.1.4 root 623: * parse all Hatari command line options and set Hatari state accordingly.
624: * Returns TRUE if everything was OK, FALSE otherwise.
1.1.1.2 root 625: */
1.1.1.4 root 626: bool Opt_ParseParameters(int argc, const char *argv[])
1.1 root 627: {
1.1.1.4 root 628: int ncpu, skips, zoom, planes, cpuclock, threshold, memsize, port;
629: const char *errstr;
630: int i, ok = TRUE;
1.1.1.2 root 631:
632: /* Defaults for loading initial memory snap-shots */
633: bLoadMemorySave = FALSE;
634: bLoadAutoSave = ConfigureParams.Memory.bAutoSave;
635:
636: for(i = 1; i < argc; i++)
1.1.1.4 root 637: {
1.1.1.2 root 638: if (argv[i][0] != '-')
639: {
1.1.1.4 root 640: if (Floppy_SetDiskFileName(0, argv[i], NULL))
1.1.1.2 root 641: {
1.1.1.4 root 642: ConfigureParams.HardDisk.bBootFromHardDisk = FALSE;
1.1.1.2 root 643: bLoadAutoSave = FALSE;
644: }
645: else
1.1.1.4 root 646: return Opt_ShowError(OPT_ERROR, argv[i], "Not an option nor disk image");
1.1 root 647: continue;
648: }
649:
650: /* WhichOption() checks also that there is an argument,
651: * so we don't need to check that below
652: */
1.1.1.2 root 653: switch(Opt_WhichOption(argc, argv, i))
654: {
655:
656: /* general options */
1.1 root 657: case OPT_HELP:
1.1.1.2 root 658: Opt_ShowHelp();
1.1.1.4 root 659: return FALSE;
1.1 root 660:
661: case OPT_VERSION:
1.1.1.2 root 662: Opt_ShowVersion();
1.1.1.4 root 663: return FALSE;
1.1.1.2 root 664:
665: case OPT_CONFIRMQUIT:
1.1.1.4 root 666: ok = Opt_Bool(argv[++i], OPT_CONFIRMQUIT, &ConfigureParams.Log.bConfirmQuit);
667: break;
668:
669: case OPT_FASTFORWARD:
670: ok = Opt_Bool(argv[++i], OPT_FASTFORWARD, &ConfigureParams.System.bFastForward);
1.1 root 671: break;
672:
1.1.1.2 root 673: case OPT_CONFIGFILE:
674: i += 1;
1.1.1.4 root 675: ok = Opt_StrCpy(OPT_CONFIGFILE, TRUE, sConfigFileName,
676: argv[i], sizeof(sConfigFileName), NULL);
677: if (ok)
678: {
679: Configuration_Load(NULL);
680: bLoadAutoSave = ConfigureParams.Memory.bAutoSave;
681: }
1.1.1.2 root 682: break;
683:
684: /* display options */
1.1 root 685: case OPT_MONO:
1.1.1.4 root 686: ConfigureParams.Screen.nMonitorType = MONITOR_TYPE_MONO;
1.1.1.2 root 687: bLoadAutoSave = FALSE;
688: break;
689:
690: case OPT_MONITOR:
691: i += 1;
692: if (strcasecmp(argv[i], "mono") == 0)
693: {
1.1.1.4 root 694: ConfigureParams.Screen.nMonitorType = MONITOR_TYPE_MONO;
1.1.1.2 root 695: }
696: else if (strcasecmp(argv[i], "rgb") == 0)
697: {
1.1.1.4 root 698: ConfigureParams.Screen.nMonitorType = MONITOR_TYPE_RGB;
1.1.1.2 root 699: }
700: else if (strcasecmp(argv[i], "vga") == 0)
701: {
1.1.1.4 root 702: ConfigureParams.Screen.nMonitorType = MONITOR_TYPE_VGA;
1.1.1.2 root 703: }
704: else if (strcasecmp(argv[i], "tv") == 0)
705: {
1.1.1.4 root 706: ConfigureParams.Screen.nMonitorType = MONITOR_TYPE_TV;
1.1.1.2 root 707: }
708: else
709: {
1.1.1.4 root 710: return Opt_ShowError(OPT_MONITOR, argv[i], "Unknown monitor type");
1.1.1.2 root 711: }
712: bLoadAutoSave = FALSE;
1.1 root 713: break;
714:
715: case OPT_FULLSCREEN:
716: ConfigureParams.Screen.bFullScreen = TRUE;
717: break;
718:
719: case OPT_WINDOW:
720: ConfigureParams.Screen.bFullScreen = FALSE;
721: break;
722:
1.1.1.2 root 723: case OPT_ZOOM:
724: zoom = atoi(argv[++i]);
725: if (zoom < 1)
726: {
1.1.1.4 root 727: return Opt_ShowError(OPT_ZOOM, argv[i], "Invalid zoom value");
1.1.1.2 root 728: }
729: if (zoom > 1)
730: {
731: /* TODO: only doubling supported for now */
732: ConfigureParams.Screen.bZoomLowRes = TRUE;
733: }
734: else
735: {
736: ConfigureParams.Screen.bZoomLowRes = FALSE;
1.1 root 737: }
738: break;
739:
1.1.1.2 root 740: case OPT_FRAMESKIPS:
741: skips = atoi(argv[++i]);
742: if (skips < 0 || skips > 8)
743: {
1.1.1.4 root 744: return Opt_ShowError(OPT_FRAMESKIPS, argv[i],
745: "Invalid frame skip value");
1.1.1.2 root 746: }
1.1.1.4 root 747: ConfigureParams.Screen.nFrameSkips = skips;
1.1 root 748: break;
749:
1.1.1.2 root 750: case OPT_BORDERS:
1.1.1.4 root 751: ok = Opt_Bool(argv[++i], OPT_BORDERS, &ConfigureParams.Screen.bAllowOverscan);
752: break;
753:
754: case OPT_STATUSBAR:
755: ok = Opt_Bool(argv[++i], OPT_STATUSBAR, &ConfigureParams.Screen.bShowStatusbar);
756: break;
757:
758: case OPT_DRIVE_LED:
759: ok = Opt_Bool(argv[++i], OPT_DRIVE_LED, &ConfigureParams.Screen.bShowDriveLed);
1.1 root 760: break;
761:
1.1.1.2 root 762: case OPT_SPEC512:
763: threshold = atoi(argv[++i]);
764: if (threshold < 0 || threshold > 512)
765: {
1.1.1.4 root 766: return Opt_ShowError(OPT_SPEC512, argv[i],
767: "Invalid palette writes per line threshold for Spec512");
1.1.1.2 root 768: }
769: ConfigureParams.Screen.nSpec512Threshold = threshold;
770: break;
771:
772: case OPT_FORCEBPP:
773: planes = atoi(argv[++i]);
1.1.1.3 root 774: switch(planes)
1.1.1.2 root 775: {
1.1.1.3 root 776: case 32:
777: case 16:
778: case 15:
779: case 8:
780: break; /* supported */
781: case 24:
782: planes = 32; /* We do not support 24 bpp (yet) */
783: break;
784: default:
1.1.1.4 root 785: return Opt_ShowError(OPT_FORCEBPP, argv[i], "Invalid bit depth");
1.1.1.2 root 786: }
787: ConfigureParams.Screen.nForceBpp = planes;
788: break;
789:
1.1.1.4 root 790: /* VDI options */
791: case OPT_VDI:
792: ok = Opt_Bool(argv[++i], OPT_VDI, &ConfigureParams.Screen.bUseExtVdiResolutions);
793: if (ok)
794: {
795: bLoadAutoSave = FALSE;
796: }
797: break;
798:
1.1.1.2 root 799: case OPT_VDI_PLANES:
800: planes = atoi(argv[++i]);
801: switch(planes)
802: {
803: case 1:
804: ConfigureParams.Screen.nVdiColors = GEMCOLOR_2;
805: break;
806: case 2:
807: ConfigureParams.Screen.nVdiColors = GEMCOLOR_4;
808: break;
809: case 4:
810: ConfigureParams.Screen.nVdiColors = GEMCOLOR_16;
811: break;
812: default:
1.1.1.4 root 813: return Opt_ShowError(OPT_VDI_PLANES, argv[i], "Unsupported VDI bit-depth");
1.1.1.2 root 814: }
815: ConfigureParams.Screen.bUseExtVdiResolutions = TRUE;
816: bLoadAutoSave = FALSE;
817: break;
818:
819: case OPT_VDI_WIDTH:
820: ConfigureParams.Screen.nVdiWidth = atoi(argv[++i]);
821: ConfigureParams.Screen.bUseExtVdiResolutions = TRUE;
822: bLoadAutoSave = FALSE;
823: break;
824:
825: case OPT_VDI_HEIGHT:
826: ConfigureParams.Screen.nVdiHeight = atoi(argv[++i]);
827: ConfigureParams.Screen.bUseExtVdiResolutions = TRUE;
828: bLoadAutoSave = FALSE;
829: break;
830:
831: /* devices options */
832: case OPT_JOYSTICK:
833: i++;
834: if (strlen(argv[i]) != 1 ||
835: !Joy_SetCursorEmulation(argv[i][0] - '0'))
836: {
1.1.1.4 root 837: return Opt_ShowError(OPT_JOYSTICK, argv[i], "Invalid joystick port");
838: }
839: break;
840:
841: case OPT_JOYSTICK0:
842: case OPT_JOYSTICK1:
843: case OPT_JOYSTICK2:
844: case OPT_JOYSTICK3:
845: case OPT_JOYSTICK4:
846: case OPT_JOYSTICK5:
847: port = argv[i][strlen(argv[i])-1] - '0';
848: assert(port >= 0 && port < JOYSTICK_COUNT);
849: i += 1;
850: if (strcasecmp(argv[i], "none") == 0)
851: {
852: ConfigureParams.Joysticks.Joy[port].nJoystickMode = JOYSTICK_DISABLED;
853: }
854: else if (strcasecmp(argv[i], "keys") == 0)
855: {
856: ConfigureParams.Joysticks.Joy[port].nJoystickMode = JOYSTICK_KEYBOARD;
857: }
858: else if (strcasecmp(argv[i], "real") == 0)
859: {
860: ConfigureParams.Joysticks.Joy[port].nJoystickMode = JOYSTICK_REALSTICK;
861: }
862: else
863: {
864: return Opt_ShowError(OPT_JOYSTICK0+port, argv[i], "Invalid joystick type");
1.1.1.2 root 865: }
1.1 root 866: break;
867:
868: case OPT_PRINTER:
1.1.1.2 root 869: i += 1;
1.1.1.4 root 870: ok = Opt_StrCpy(OPT_PRINTER, FALSE, ConfigureParams.Printer.szPrintToFileName,
871: argv[i], sizeof(ConfigureParams.Printer.szPrintToFileName),
872: &ConfigureParams.Printer.bEnablePrinting);
1.1 root 873: break;
874:
1.1.1.5 ! root 875: case OPT_MIDI_IN:
! 876: i += 1;
! 877: /* FALSE: "" can be used to disable midi input */
! 878: ok = Opt_StrCpy(OPT_MIDI_IN, FALSE, ConfigureParams.Midi.sMidiInFileName,
! 879: argv[i], sizeof(ConfigureParams.Midi.sMidiInFileName),
! 880: &ConfigureParams.Midi.bEnableMidi);
! 881: break;
! 882:
! 883: case OPT_MIDI_OUT:
1.1 root 884: i += 1;
1.1.1.5 ! root 885: ok = Opt_StrCpy(OPT_MIDI_OUT, TRUE, ConfigureParams.Midi.sMidiOutFileName,
! 886: argv[i], sizeof(ConfigureParams.Midi.sMidiOutFileName),
1.1.1.4 root 887: &ConfigureParams.Midi.bEnableMidi);
1.1 root 888: break;
889:
1.1.1.5 ! root 890: case OPT_RS232_IN:
1.1 root 891: i += 1;
1.1.1.5 ! root 892: ok = Opt_StrCpy(OPT_RS232_IN, TRUE, ConfigureParams.RS232.szInFileName,
1.1.1.4 root 893: argv[i], sizeof(ConfigureParams.RS232.szInFileName),
894: &ConfigureParams.RS232.bEnableRS232);
1.1.1.5 ! root 895: break;
! 896:
! 897: case OPT_RS232_OUT:
! 898: i += 1;
! 899: ok = Opt_StrCpy(OPT_RS232_OUT, TRUE, ConfigureParams.RS232.szOutFileName,
! 900: argv[i], sizeof(ConfigureParams.RS232.szOutFileName),
! 901: &ConfigureParams.RS232.bEnableRS232);
1.1 root 902: break;
1.1.1.2 root 903:
904: /* disk options */
1.1.1.4 root 905: case OPT_DISKA:
906: i += 1;
907: if (Floppy_SetDiskFileName(0, argv[i], NULL))
908: {
909: ConfigureParams.HardDisk.bBootFromHardDisk = FALSE;
910: bLoadAutoSave = FALSE;
911: }
912: else
913: return Opt_ShowError(OPT_ERROR, argv[i], "Not a disk image");
914: break;
915:
916: case OPT_DISKB:
917: i += 1;
918: if (Floppy_SetDiskFileName(1, argv[i], NULL))
919: bLoadAutoSave = FALSE;
920: else
921: return Opt_ShowError(OPT_ERROR, argv[i], "Not a disk image");
922: break;
923:
1.1 root 924: case OPT_HARDDRIVE:
925: i += 1;
1.1.1.4 root 926: ok = Opt_StrCpy(OPT_HARDDRIVE, FALSE, ConfigureParams.HardDisk.szHardDiskDirectories[0],
927: argv[i], sizeof(ConfigureParams.HardDisk.szHardDiskDirectories[0]),
928: &ConfigureParams.HardDisk.bUseHardDiskDirectories);
929: if (ok && ConfigureParams.HardDisk.bUseHardDiskDirectories)
1.1.1.2 root 930: {
1.1 root 931: ConfigureParams.HardDisk.bBootFromHardDisk = TRUE;
932: }
1.1.1.2 root 933: bLoadAutoSave = FALSE;
934: break;
935:
936: case OPT_ACSIHDIMAGE:
937: i += 1;
1.1.1.4 root 938: ok = Opt_StrCpy(OPT_ACSIHDIMAGE, TRUE, ConfigureParams.HardDisk.szHardDiskImage,
939: argv[i], sizeof(ConfigureParams.HardDisk.szHardDiskImage),
940: &ConfigureParams.HardDisk.bUseHardDiskImage);
941: if (ok)
942: {
943: bLoadAutoSave = FALSE;
944: }
1.1 root 945: break;
946:
1.1.1.2 root 947: case OPT_IDEHDIMAGE:
1.1 root 948: i += 1;
1.1.1.4 root 949: ok = Opt_StrCpy(OPT_IDEHDIMAGE, TRUE, ConfigureParams.HardDisk.szIdeHardDiskImage,
950: argv[i], sizeof(ConfigureParams.HardDisk.szIdeHardDiskImage),
951: &ConfigureParams.HardDisk.bUseIdeHardDiskImage);
952: if (ok)
953: {
954: bLoadAutoSave = FALSE;
955: }
1.1.1.2 root 956: break;
957:
958: case OPT_SLOWFDC:
1.1.1.4 root 959: ok = Opt_Bool(argv[++i], OPT_SLOWFDC, &ConfigureParams.System.bSlowFDC);
960: if (ok)
961: {
962: bLoadAutoSave = FALSE;
963: }
1.1.1.2 root 964: break;
965:
966: /* Memory options */
967: case OPT_MEMSIZE:
1.1.1.4 root 968: memsize = atoi(argv[++i]);
969: if (memsize < 0 || memsize > 14)
1.1.1.2 root 970: {
1.1.1.4 root 971: return Opt_ShowError(OPT_MEMSIZE, argv[i], "Invalid memory size");
1.1 root 972: }
1.1.1.4 root 973: ConfigureParams.Memory.nMemorySize = memsize;
1.1.1.2 root 974: bLoadAutoSave = FALSE;
1.1 root 975: break;
976:
1.1.1.2 root 977: case OPT_TOS:
978: i += 1;
1.1.1.4 root 979: ok = Opt_StrCpy(OPT_TOS, TRUE, ConfigureParams.Rom.szTosImageFileName,
980: argv[i], sizeof(ConfigureParams.Rom.szTosImageFileName),
981: NULL);
982: if (ok)
983: {
984: bLoadAutoSave = FALSE;
985: }
1.1.1.2 root 986: break;
987:
1.1 root 988: case OPT_CARTRIDGE:
989: i += 1;
1.1.1.4 root 990: ok = Opt_StrCpy(OPT_CARTRIDGE, TRUE, ConfigureParams.Rom.szCartridgeImageFileName,
991: argv[i], sizeof(ConfigureParams.Rom.szCartridgeImageFileName),
992: NULL);
993: if (ok)
994: {
995: bLoadAutoSave = FALSE;
996: }
1.1.1.2 root 997: break;
998:
999: case OPT_MEMSTATE:
1000: i += 1;
1.1.1.4 root 1001: ok = Opt_StrCpy(OPT_MEMSTATE, TRUE, ConfigureParams.Memory.szMemoryCaptureFileName,
1002: argv[i], sizeof(ConfigureParams.Memory.szMemoryCaptureFileName),
1003: NULL);
1004: if (ok)
1005: {
1006: bLoadMemorySave = TRUE;
1007: bLoadAutoSave = FALSE;
1008: }
1.1 root 1009: break;
1010:
1.1.1.2 root 1011: /* CPU options */
1.1 root 1012: case OPT_CPULEVEL:
1013: /* UAE core uses cpu_level variable */
1.1.1.2 root 1014: ncpu = atoi(argv[++i]);
1015: if(ncpu < 0 || ncpu > 4)
1016: {
1.1.1.4 root 1017: return Opt_ShowError(OPT_CPULEVEL, argv[i], "Invalid CPU level");
1.1.1.2 root 1018: }
1019: ConfigureParams.System.nCpuLevel = ncpu;
1020: bLoadAutoSave = FALSE;
1021: break;
1022:
1023: case OPT_CPUCLOCK:
1024: cpuclock = atoi(argv[++i]);
1025: if(cpuclock != 8 && cpuclock != 16 && cpuclock != 32)
1026: {
1.1.1.4 root 1027: return Opt_ShowError(OPT_CPUCLOCK, argv[i], "Invalid CPU clock");
1.1 root 1028: }
1.1.1.2 root 1029: ConfigureParams.System.nCpuFreq = cpuclock;
1030: bLoadAutoSave = FALSE;
1.1 root 1031: break;
1032:
1033: case OPT_COMPATIBLE:
1.1.1.4 root 1034: ok = Opt_Bool(argv[++i], OPT_COMPATIBLE, &ConfigureParams.System.bCompatibleCpu);
1035: if (ok)
1036: {
1037: bLoadAutoSave = FALSE;
1038: }
1.1 root 1039: break;
1.1.1.2 root 1040:
1041: /* system options */
1042: case OPT_MACHINE:
1043: i += 1;
1044: if (strcasecmp(argv[i], "st") == 0)
1045: {
1046: ConfigureParams.System.nMachineType = MACHINE_ST;
1047: ConfigureParams.System.nCpuLevel = 0;
1048: ConfigureParams.System.nCpuFreq = 8;
1049: }
1050: else if (strcasecmp(argv[i], "ste") == 0)
1051: {
1052: ConfigureParams.System.nMachineType = MACHINE_STE;
1053: ConfigureParams.System.nCpuLevel = 0;
1054: ConfigureParams.System.nCpuFreq = 8;
1055: }
1056: else if (strcasecmp(argv[i], "tt") == 0)
1057: {
1058: ConfigureParams.System.nMachineType = MACHINE_TT;
1059: ConfigureParams.System.nCpuLevel = 3;
1060: ConfigureParams.System.nCpuFreq = 32;
1061: }
1062: else if (strcasecmp(argv[i], "falcon") == 0)
1063: {
1064: ConfigureParams.System.nMachineType = MACHINE_FALCON;
1065: ConfigureParams.System.nCpuLevel = 3;
1066: ConfigureParams.System.nCpuFreq = 16;
1067: }
1068: else
1069: {
1.1.1.4 root 1070: return Opt_ShowError(OPT_MACHINE, argv[i], "Unknown machine type");
1.1.1.2 root 1071: }
1072: bLoadAutoSave = FALSE;
1.1 root 1073: break;
1074:
1.1.1.2 root 1075: case OPT_BLITTER:
1.1.1.4 root 1076: ok = Opt_Bool(argv[++i], OPT_BLITTER, &ConfigureParams.System.bBlitter);
1077: if (ok)
1078: {
1079: bLoadAutoSave = FALSE;
1080: }
1.1.1.2 root 1081: break;
1082:
1083: case OPT_DSP:
1084: i += 1;
1085: if (strcasecmp(argv[i], "none") == 0)
1086: {
1087: ConfigureParams.System.nDSPType = DSP_TYPE_NONE;
1088: }
1089: else if (strcasecmp(argv[i], "dummy") == 0)
1090: {
1091: ConfigureParams.System.nDSPType = DSP_TYPE_DUMMY;
1092: }
1093: else if (strcasecmp(argv[i], "emu") == 0)
1094: {
1095: #if ENABLE_DSP_EMU
1096: ConfigureParams.System.nDSPType = DSP_TYPE_EMU;
1097: #else
1.1.1.4 root 1098: return Opt_ShowError(OPT_DSP, argv[i], "DSP type 'emu' support not compiled in");
1.1.1.2 root 1099: #endif
1100: }
1101: else
1102: {
1.1.1.4 root 1103: return Opt_ShowError(OPT_DSP, argv[i], "Unknown DSP type");
1.1 root 1104: }
1.1.1.2 root 1105: bLoadAutoSave = FALSE;
1.1 root 1106: break;
1107:
1.1.1.2 root 1108: case OPT_SOUND:
1.1 root 1109: i += 1;
1.1.1.2 root 1110: if (strcasecmp(argv[i], "off") == 0)
1111: {
1112: ConfigureParams.Sound.bEnableSound = FALSE;
1113: }
1114: else if (strcasecmp(argv[i], "low") == 0)
1115: {
1116: ConfigureParams.Sound.nPlaybackQuality = PLAYBACK_LOW;
1117: ConfigureParams.Sound.bEnableSound = TRUE;
1118: }
1119: else if (strcasecmp(argv[i], "med") == 0)
1120: {
1121: ConfigureParams.Sound.nPlaybackQuality = PLAYBACK_MEDIUM;
1122: ConfigureParams.Sound.bEnableSound = TRUE;
1123: }
1124: else if (strcasecmp(argv[i], "hi") == 0)
1125: {
1126: ConfigureParams.Sound.nPlaybackQuality = PLAYBACK_HIGH;
1127: ConfigureParams.Sound.bEnableSound = TRUE;
1128: }
1129: else
1130: {
1.1.1.4 root 1131: return Opt_ShowError(OPT_SOUND, argv[i], "Unsupported sound quality");
1.1 root 1132: }
1133: break;
1.1.1.2 root 1134:
1.1 root 1135: case OPT_KEYMAPFILE:
1136: i += 1;
1.1.1.4 root 1137: ok = Opt_StrCpy(OPT_KEYMAPFILE, TRUE, ConfigureParams.Keyboard.szMappingFileName,
1138: argv[i], sizeof(ConfigureParams.Keyboard.szMappingFileName),
1139: NULL);
1140: if (ok)
1141: {
1142: ConfigureParams.Keyboard.nKeymapType = KEYMAP_LOADED;
1143: }
1.1 root 1144: break;
1145:
1.1.1.2 root 1146: /* debug options */
1147: case OPT_DEBUG:
1.1.1.4 root 1148: if (bEnableDebug)
1149: {
1150: /* called at run time (e.g. from debugger) */
1151: fprintf(stderr, "Debug mode disabled.\n");
1152: bEnableDebug = FALSE;
1153: }
1154: else
1155: {
1156: bEnableDebug = TRUE;
1157: }
1.1.1.2 root 1158: break;
1.1.1.4 root 1159:
1160: case OPT_BIOSINTERCEPT:
1161: bBiosIntercept = TRUE;
1.1 root 1162: break;
1163:
1.1.1.2 root 1164: case OPT_TRACE:
1165: i += 1;
1.1.1.4 root 1166: if (Log_SetTraceOptions(argv[i]) == 0)
1167: {
1168: return Opt_ShowError(OPT_TRACE, argv[i], "Error parsing trace options (use --trace help for available list)!");
1169: }
1170: break;
1171:
1172: case OPT_TRACEFILE:
1173: i += 1;
1174: ok = Opt_StrCpy(OPT_TRACEFILE, FALSE, ConfigureParams.Log.sTraceFileName,
1175: argv[i], sizeof(ConfigureParams.Log.sTraceFileName),
1176: NULL);
1177: break;
1178:
1179: case OPT_CONTROLSOCKET:
1180: i += 1;
1181: errstr = Control_SetSocket(argv[i]);
1182: if (errstr)
1.1.1.2 root 1183: {
1.1.1.4 root 1184: return Opt_ShowError(OPT_CONTROLSOCKET, argv[i], errstr);
1.1.1.2 root 1185: }
1186: break;
1187:
1.1.1.4 root 1188: case OPT_LOGFILE:
1189: i += 1;
1190: ok = Opt_StrCpy(OPT_LOGFILE, FALSE, ConfigureParams.Log.sLogFileName,
1191: argv[i], sizeof(ConfigureParams.Log.sLogFileName),
1192: NULL);
1193: break;
1194:
1195: case OPT_LOGLEVEL:
1196: i += 1;
1197: ConfigureParams.Log.nTextLogLevel = Log_ParseOptions(argv[i]);
1198: if (ConfigureParams.Log.nTextLogLevel == LOG_NONE)
1199: {
1200: return Opt_ShowError(OPT_LOGLEVEL, argv[i], "Unknown log level!");
1201: }
1202: break;
1203:
1204: case OPT_ALERTLEVEL:
1205: i += 1;
1206: ConfigureParams.Log.nAlertDlgLogLevel = Log_ParseOptions(argv[i]);
1207: if (ConfigureParams.Log.nAlertDlgLogLevel == LOG_NONE)
1208: {
1209: return Opt_ShowError(OPT_ALERTLEVEL, argv[i], "Unknown alert level!");
1210: }
1211: break;
1212:
1213: case OPT_ERROR:
1214: /* unknown option or missing option parameter */
1215: return FALSE;
1216:
1.1 root 1217: default:
1.1.1.4 root 1218: return Opt_ShowError(OPT_ERROR, argv[i], "Internal Hatari error, unhandled option");
1219: }
1220: if (!ok)
1221: {
1222: /* Opt_Bool() or Opt_StrCpy() failed */
1223: return FALSE;
1.1 root 1224: }
1225: }
1.1.1.4 root 1226:
1227: return TRUE;
1.1 root 1228: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.