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