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