|
|
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 root 16: */
17:
1.1.1.2 ! root 18: const char Main_rcsid[] = "Hatari $Id: options.c,v 1.48 2008/03/13 12:32:50 thothy Exp $";
! 19:
! 20: #include <ctype.h>
1.1 root 21: #include <stdio.h>
22: #include <stdlib.h>
23: #include <string.h>
24: #include <assert.h>
25:
26: #include "main.h"
27: #include "options.h"
28: #include "configuration.h"
29: #include "file.h"
30: #include "screen.h"
31: #include "video.h"
32: #include "vdi.h"
33: #include "joy.h"
1.1.1.2 ! root 34: #include "trace.h"
! 35:
! 36: #include "hatari-glue.h"
! 37:
1.1 root 38:
1.1.1.2 ! root 39: BOOL bLoadAutoSave; /* Load autosave memory snapshot at startup */
! 40: BOOL bLoadMemorySave; /* Load memory snapshot provided via option at startup */
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,
! 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,
! 57: OPT_SPEC512,
! 58: OPT_FORCEBPP,
! 59: OPT_VDI_PLANES, /* VDI options */
! 60: OPT_VDI_WIDTH,
! 61: OPT_VDI_HEIGHT,
! 62: OPT_JOYSTICK, /* device options */
1.1 root 63: OPT_PRINTER,
64: OPT_MIDI,
65: OPT_RS232,
1.1.1.2 ! root 66: OPT_HARDDRIVE, /* disk options */
! 67: OPT_ACSIHDIMAGE,
! 68: OPT_IDEHDIMAGE,
! 69: OPT_SLOWFDC,
! 70: OPT_MEMSIZE, /* memory options */
1.1 root 71: OPT_TOS,
72: OPT_CARTRIDGE,
1.1.1.2 ! root 73: OPT_MEMSTATE,
! 74: OPT_CPULEVEL, /* CPU options */
! 75: OPT_CPUCLOCK,
1.1 root 76: OPT_COMPATIBLE,
1.1.1.2 ! root 77: OPT_MACHINE, /* system options */
1.1 root 78: OPT_BLITTER,
1.1.1.2 ! root 79: OPT_DSP,
! 80: OPT_SOUND,
1.1 root 81: OPT_KEYMAPFILE,
1.1.1.2 ! root 82: OPT_DEBUG, /* debug options */
! 83: OPT_LOG,
! 84: OPT_TRACE,
1.1 root 85: OPT_NONE,
86: };
87:
88: typedef struct {
89: unsigned int id; /* option ID */
90: const char *chr; /* short option */
91: const char *str; /* long option */
1.1.1.2 ! root 92: const char *arg; /* type name for argument, if any */
1.1 root 93: const char *desc; /* option description */
94: } opt_t;
95:
1.1.1.2 ! root 96: /* it's easier to edit these if they are kept in the same order as the enums */
1.1 root 97: static const opt_t HatariOptions[] = {
1.1.1.2 ! root 98:
! 99: { OPT_HEADER, NULL, NULL, NULL, "General" },
1.1 root 100: { OPT_HELP, "-h", "--help",
101: NULL, "Print this help text and exit" },
102: { OPT_VERSION, "-v", "--version",
1.1.1.2 ! root 103: NULL, "Print version number and exit" },
! 104: { OPT_CONFIRMQUIT,NULL, "--confirm-quit",
! 105: "<bool>", "Whether Hatari confirms quit" },
! 106: { OPT_CONFIGFILE,"-c", "--configfile",
! 107: "<file>", "Use <file> instead of the ~/.hatari.cfg config file" },
! 108:
! 109: { OPT_HEADER, NULL, NULL, NULL, "Display" },
1.1 root 110: { OPT_MONO, "-m", "--mono",
111: NULL, "Start in monochrome mode instead of color" },
1.1.1.2 ! root 112: { OPT_MONITOR, NULL, "--monitor",
! 113: "<x>", "Select monitor type (x = mono/rgb/vga/tv)" },
1.1 root 114: { OPT_FULLSCREEN,"-f", "--fullscreen",
115: NULL, "Start emulator in fullscreen mode" },
116: { OPT_WINDOW, "-w", "--window",
117: NULL, "Start emulator in window mode" },
1.1.1.2 ! root 118: { OPT_ZOOM, "-z", "--zoom",
! 119: "<x>", "Double ST low resolution (1=no, 2=yes)" },
! 120: { OPT_FRAMESKIPS, NULL, "--frameskips",
! 121: "<x>", "Skip <x> frames after each displayed frame (0 <= x <= 8)" },
! 122: { OPT_BORDERS, NULL, "--borders",
! 123: "<bool>", "Show screen borders (for overscan demos etc)" },
! 124: { OPT_SPEC512, NULL, "--spec512",
! 125: "<x>", "Spec512 palette threshold (0 <= x <= 512, 0=disable)" },
! 126: { OPT_FORCEBPP, NULL, "--bpp",
! 127: "<x>", "Force internal color bitdepth (x=8/16/32, 0=disable)" },
! 128:
! 129: { OPT_HEADER, NULL, NULL, NULL, "VDI" },
! 130: { OPT_VDI_PLANES,NULL, "--vdi-planes",
! 131: "<x>", "VDI resolution bit-depth (x = 1/2/4)" },
! 132: { OPT_VDI_WIDTH, NULL, "--vdi-width",
! 133: "<w>", "Use VDI resolution with width w (320 < w <= 1024)" },
! 134: { OPT_VDI_HEIGHT, NULL, "--vdi-height",
! 135: "<h>", "VDI resolution with height h (200 < h <= 768)" },
! 136:
! 137: { OPT_HEADER, NULL, NULL, NULL, "Devices" },
1.1 root 138: { OPT_JOYSTICK, "-j", "--joystick",
1.1.1.2 ! root 139: "<port>", "Emulate joystick with cursor keys in given port (0-5)" },
1.1 root 140: { OPT_PRINTER, NULL, "--printer",
1.1.1.2 ! root 141: "<file>", "Enable printer support and write data to <file>" },
1.1 root 142: { OPT_MIDI, NULL, "--midi",
143: "<file>", "Enable midi support and write midi data to <file>" },
144: { OPT_RS232, NULL, "--rs232",
1.1.1.2 ! root 145: "<file>", "Enable serial port support and use <file> as the device" },
! 146:
! 147: { OPT_HEADER, NULL, NULL, NULL, "Disk" },
1.1 root 148: { OPT_HARDDRIVE, "-d", "--harddrive",
149: "<dir>", "Emulate an ST harddrive (<dir> = root directory)" },
1.1.1.2 ! root 150: { OPT_ACSIHDIMAGE, NULL, "--acsi",
! 151: "<file>", "Emulate an ACSI harddrive with an image <file>" },
! 152: { OPT_IDEHDIMAGE, NULL, "--ide",
! 153: "<file>", "Emulate an IDE harddrive using <file> (not working yet)" },
! 154: { OPT_SLOWFDC, NULL, "--slowfdc",
! 155: "<bool>", "Slow down FDC emulation (deprecated)" },
! 156:
! 157: { OPT_HEADER, NULL, NULL, NULL, "Memory" },
! 158: { OPT_MEMSIZE, "-s", "--memsize",
! 159: "<x>", "ST RAM size. x = size in MiB from 0 to 14, 0 for 512KiB" },
1.1 root 160: { OPT_TOS, "-t", "--tos",
161: "<file>", "Use TOS image <file>" },
162: { OPT_CARTRIDGE, NULL, "--cartridge",
163: "<file>", "Use ROM cartridge image <file>" },
1.1.1.2 ! root 164: { OPT_MEMSTATE, NULL, "--memstate",
! 165: "<file>", "Load memory snap-shot <file>" },
! 166:
! 167: { OPT_HEADER, NULL, NULL, NULL, "CPU" },
1.1 root 168: { OPT_CPULEVEL, NULL, "--cpulevel",
1.1.1.2 ! root 169: "<x>", "Set the CPU type (x => 680x0) (EmuTOS/TOS 2.06 only!)" },
! 170: { OPT_CPUCLOCK, NULL, "--cpuclock",
! 171: "<x>", "Set the CPU clock (8, 16 or 32)" },
1.1 root 172: { OPT_COMPATIBLE,NULL, "--compatible",
1.1.1.2 ! root 173: "<bool>", "Use a more compatible (but slower) 68000 CPU mode" },
! 174:
! 175: { OPT_HEADER, NULL, NULL, NULL, "Misc system" },
! 176: { OPT_MACHINE, NULL, "--machine",
! 177: "<x>", "Select machine type (x = st/ste/tt/falcon)" },
1.1 root 178: { OPT_BLITTER, NULL, "--blitter",
1.1.1.2 ! root 179: "<bool>", "Use blitter emulation (ST only)" },
! 180: { OPT_DSP, NULL, "--dsp",
! 181: "<x>", "DSP emulation (x=none/dummy/emu, for Falcon mode only)" },
! 182: { OPT_SOUND, NULL, "--sound",
! 183: "<x>", "Sound quality (off/low/med/hi (off=faster))" },
1.1 root 184: { OPT_KEYMAPFILE,"-k", "--keymap",
185: "<file>", "Read (additional) keyboard mappings from <file>" },
1.1.1.2 ! root 186:
! 187: { OPT_HEADER, NULL, NULL, NULL, "Debug" },
! 188: { OPT_DEBUG, "-D", "--debug",
! 189: NULL, "Allow debug interface" },
! 190: { OPT_LOG, NULL, "--log",
! 191: "<file>", "Save log to <file>" },
! 192: { OPT_TRACE, NULL, "--trace",
! 193: "<trace1,...>", "Activate debug traces, see --trace help for options" },
! 194:
1.1 root 195: { OPT_NONE, NULL, NULL, NULL, NULL }
196: };
197:
1.1.1.2 ! root 198:
! 199: /**
! 200: * Show version string and license.
1.1 root 201: */
1.1.1.2 ! root 202: static void Opt_ShowVersion(void)
! 203: {
! 204: printf("\nThis is %s - the Atari ST, STE, TT and Falcon emulator.\n\n",
! 205: PROG_NAME);
! 206: printf("Hatari is free software licensed under the GNU General"
! 207: " Public License.\n\n");
! 208: }
! 209:
! 210:
! 211: /**
! 212: * Calculate option + value len
! 213: */
! 214: static unsigned int Opt_OptionLen(const opt_t *opt)
! 215: {
! 216: unsigned int len;
! 217: len = strlen(opt->str);
! 218: if (opt->arg)
! 219: {
! 220: len += strlen(opt->arg);
! 221: len += 1;
! 222: /* with arg, short options go to another line */
! 223: }
! 224: else
! 225: {
! 226: if (opt->chr)
! 227: {
! 228: /* ' or -c' */
! 229: len += 6;
! 230: }
! 231: }
! 232: return len;
! 233: }
! 234:
! 235:
! 236: /**
! 237: * Show single option
! 238: */
! 239: static void Opt_ShowOption(const opt_t *opt, unsigned int maxlen)
1.1 root 240: {
241: char buf[64];
1.1.1.2 ! root 242: if (!maxlen)
! 243: {
! 244: maxlen = Opt_OptionLen(opt);
! 245: }
! 246: assert(maxlen < sizeof(buf));
! 247: if (opt->arg)
! 248: {
! 249: sprintf(buf, "%s %s", opt->str, opt->arg);
! 250: printf(" %-*s %s\n", maxlen, buf, opt->desc);
! 251: if (opt->chr)
! 252: {
! 253: printf(" or %s %s\n", opt->chr, opt->arg);
! 254: }
! 255: }
! 256: else
! 257: {
! 258: if (opt->chr)
! 259: {
! 260: sprintf(buf, "%s or %s", opt->str, opt->chr);
! 261: printf(" %-*s %s\n", maxlen, buf, opt->desc);
1.1 root 262: }
1.1.1.2 ! root 263: else
! 264: {
! 265: printf(" %-*s %s\n", maxlen, opt->str, opt->desc);
! 266: }
! 267: }
! 268: }
! 269:
! 270: /**
! 271: * Show options for section starting from 'start_opt',
! 272: * return next option after this section.
! 273: */
! 274: static const opt_t *Opt_ShowHelpSection(const opt_t *start_opt)
! 275: {
! 276: const opt_t *opt, *last;
! 277: unsigned int len, maxlen = 0;
! 278:
! 279: /* find longest option name and check option IDs */
! 280: for (opt = start_opt; opt->id != OPT_HEADER && opt->id != OPT_NONE; opt++)
! 281: {
! 282: len = Opt_OptionLen(opt);
! 283: if (len > maxlen)
! 284: {
1.1 root 285: maxlen = len;
286: }
287: }
1.1.1.2 ! root 288: last = opt;
1.1 root 289:
290: /* output all options */
1.1.1.2 ! root 291: for (opt = start_opt; opt != last; opt++)
! 292: {
! 293: Opt_ShowOption(opt, maxlen);
! 294: }
! 295: return last;
! 296: }
! 297:
! 298:
! 299: /**
! 300: * Show help text.
! 301: */
! 302: static void Opt_ShowHelp(void)
! 303: {
! 304: const opt_t *opt = HatariOptions;
! 305:
! 306: Opt_ShowVersion();
! 307: printf("Usage:\n hatari [options] [disk image name]\n");
! 308:
! 309: while(opt->id != OPT_NONE)
! 310: {
! 311: if (opt->id == OPT_HEADER)
! 312: {
! 313: assert(opt->desc);
! 314: printf("\n%s options:\n", opt->desc);
! 315: opt++;
1.1 root 316: }
1.1.1.2 ! root 317: opt = Opt_ShowHelpSection(opt);
1.1 root 318: }
1.1.1.2 ! root 319: printf("\nSpecial option values:\n");
! 320: printf("<bool>\tDisable by using 'n', 'no', 'off', 'false', or '0'\n");
! 321: printf("\tEnable by using 'y', 'yes', 'on', 'true' or '1'\n");
! 322: printf("<file>\tDevices accept also special 'stdout' and 'stderr' file names\n");
! 323: printf("\t(if you use stdout for midi or printer, set log to stderr).\n");
! 324: printf("\tSetting the file to 'none', disables given device or disk\n");
! 325: }
! 326:
! 327:
! 328: /* This function always exits */
! 329: static void Opt_ShowExit(unsigned int option, const char *value, const char *error)
! 330: __attribute__((noreturn));
! 331:
! 332: /**
! 333: * Show Hatari options and exit().
! 334: * If 'error' given, show that error message.
! 335: * If 'optid' != OPT_NONE, tells for which option the error is,
! 336: * otherwise 'value' is show as the option user gave.
! 337: */
! 338: static void Opt_ShowExit(unsigned int optid, const char *value, const char *error)
! 339: {
! 340: const opt_t *opt;
! 341:
! 342: Opt_ShowVersion();
! 343: printf("Usage:\n hatari [options] [disk image name]\n\n"
! 344: "Try option \"-h\" or \"--help\" to display more information.\n");
! 345:
! 346: if (error)
! 347: {
! 348: if (optid == OPT_NONE)
! 349: {
1.1 root 350: fprintf(stderr, "\nError: %s (%s)\n", error, value);
351: }
1.1.1.2 ! root 352: else
! 353: {
! 354: for (opt = HatariOptions; opt->id != OPT_NONE; opt++)
! 355: {
! 356: if (optid == opt->id)
! 357: break;
! 358: }
! 359: if (value != NULL)
! 360: {
! 361: fprintf(stderr, "\nError while parsing parameter for %s:\n"
! 362: " %s (%s)\n", opt->str, error, value);
! 363: }
! 364: else
! 365: {
! 366: fprintf(stderr, "\nError (%s): %s\n", opt->str, error);
! 367: }
! 368: Opt_ShowOption(opt, 0);
! 369: }
1.1 root 370: exit(1);
371: }
372: exit(0);
373: }
374:
1.1.1.2 ! root 375:
! 376: /**
! 377: * Return
! 378: * - TRUE if given option arg is y/yes/on/true/1
! 379: * - FALSE if given option arg is n/no/off/false/0
! 380: * Otherwise exit.
! 381: */
! 382: static int Opt_Bool(const char *arg, int optid)
! 383: {
! 384: const char *enablers[] = { "y", "yes", "on", "true", "1", NULL };
! 385: const char *disablers[] = { "n", "no", "off", "false", "0", NULL };
! 386: const char **bool_str, *orig = arg;
! 387: char *input, *str;
! 388:
! 389: input = strdup(arg);
! 390: str = input;
! 391: while (*str)
! 392: {
! 393: *str++ = tolower(*arg++);
! 394: }
! 395: for (bool_str = enablers; *bool_str; bool_str++)
! 396: {
! 397: if (strcmp(input, *bool_str) == 0)
! 398: {
! 399: free(input);
! 400: return TRUE;
! 401: }
! 402: }
! 403: for (bool_str = disablers; *bool_str; bool_str++)
! 404: {
! 405: if (strcmp(input, *bool_str) == 0)
! 406: {
! 407: free(input);
! 408: return FALSE;
! 409: }
! 410: }
! 411: free(input);
! 412: Opt_ShowExit(optid, orig, "Not a <bool> value");
! 413: }
! 414:
! 415:
! 416: /**
1.1 root 417: * matches string under given index in the argv against all Hatari
418: * short and long options. If match is found, returns ID for that,
419: * otherwise shows help.
420: *
421: * Checks also that if option is supposed to have argument,
422: * whether there's one.
423: */
424: static int Opt_WhichOption(int argc, char *argv[], int idx)
425: {
426: const opt_t *opt;
427: const char *str = argv[idx];
428:
1.1.1.2 ! root 429: for (opt = HatariOptions; opt->id != OPT_NONE; opt++)
! 430: {
! 431: if ((opt->str && !strcmp(str, opt->str)) ||
! 432: (opt->chr && !strcmp(str, opt->chr)))
! 433: {
! 434:
! 435: if (opt->arg)
! 436: {
! 437: if (idx+1 >= argc)
! 438: {
! 439: Opt_ShowExit(opt->id, NULL, "Missing argument");
! 440: }
! 441: /* early check for bools */
! 442: if (strcmp(opt->arg, "<bool>") == 0)
! 443: {
! 444: Opt_Bool(argv[idx+1], opt->id);
! 445: }
1.1 root 446: }
447: return opt->id;
448: }
449: }
450: Opt_ShowExit(OPT_NONE, argv[idx], "Unrecognized option");
451: return OPT_NONE;
452: }
453:
1.1.1.2 ! root 454:
! 455: /**
! 456: * Optionally test if file exists, then check string length,
! 457: * copy option src string to dst and return TRUE.
! 458: * If (bool) option pointer is given, set that option to TRUE.
! 459: * - However, if src is "none", leave dst unmodified, set option
! 460: * to FALSE and return FALSE.
! 461: * Return TRUE if dst set, Exits out on errors.
! 462: */
! 463: static BOOL Opt_StrCpy(int optid, BOOL checkexist, char *dst, char *src, size_t dstlen, BOOL *option)
! 464: {
! 465: if (option)
! 466: {
! 467: if(strcmp(src, "none") == 0)
! 468: {
! 469: *option = FALSE;
! 470: return FALSE;
! 471: }
! 472: else
! 473: {
! 474: *option = TRUE;
! 475: }
! 476: }
! 477: if (checkexist && !File_Exists(src))
! 478: {
! 479: Opt_ShowExit(optid, src, "Given file doesn't exist (or has wrong file permissions)!\n");
! 480: }
! 481: if (strlen(src) < dstlen)
! 482: {
! 483: strcpy(dst, src);
! 484: return TRUE;
! 485: }
! 486: else
! 487: {
! 488: Opt_ShowExit(optid, src, "File name too long!\n");
! 489: }
! 490: }
! 491:
! 492:
! 493: /**
! 494: * Check for any passed parameters, set boot disk (if given)
! 495: */
1.1 root 496: void Opt_ParseParameters(int argc, char *argv[],
497: char *bootdisk, size_t bootlen)
498: {
1.1.1.2 ! root 499: int i, ncpu, skips, zoom, planes, cpuclock, threshold;
! 500: int hdgiven = FALSE;
! 501:
! 502: /* Defaults for loading initial memory snap-shots */
! 503: bLoadMemorySave = FALSE;
! 504: bLoadAutoSave = ConfigureParams.Memory.bAutoSave;
! 505:
! 506: for(i = 1; i < argc; i++)
! 507: {
! 508: if (argv[i][0] != '-')
! 509: {
1.1 root 510: /* Possible passed disk image filename */
511: if (argv[i][0] && File_Exists(argv[i]) &&
1.1.1.2 ! root 512: strlen(argv[i]) < bootlen)
! 513: {
1.1 root 514: strcpy(bootdisk, argv[i]);
515: File_MakeAbsoluteName(bootdisk);
1.1.1.2 ! root 516: bLoadAutoSave = FALSE;
! 517: }
! 518: else
! 519: {
1.1 root 520: Opt_ShowExit(OPT_NONE, argv[i], "Not an option nor disk image");
521: }
522: continue;
523: }
524:
525: /* WhichOption() checks also that there is an argument,
526: * so we don't need to check that below
527: */
1.1.1.2 ! root 528: switch(Opt_WhichOption(argc, argv, i))
! 529: {
! 530:
! 531: /* general options */
1.1 root 532: case OPT_HELP:
1.1.1.2 ! root 533: Opt_ShowHelp();
! 534: exit(0);
1.1 root 535: break;
536:
537: case OPT_VERSION:
1.1.1.2 ! root 538: Opt_ShowVersion();
! 539: exit(0);
! 540: break;
! 541:
! 542: case OPT_CONFIRMQUIT:
! 543: ConfigureParams.Log.bConfirmQuit = Opt_Bool(argv[++i], OPT_CONFIRMQUIT);
1.1 root 544: break;
545:
1.1.1.2 ! root 546: case OPT_CONFIGFILE:
! 547: i += 1;
! 548: Opt_StrCpy(OPT_CONFIGFILE, TRUE, sConfigFileName,
! 549: argv[i], sizeof(sConfigFileName), NULL);
! 550: Configuration_Load(NULL);
! 551: bLoadAutoSave = ConfigureParams.Memory.bAutoSave;
! 552: break;
! 553:
! 554: /* display options */
1.1 root 555: case OPT_MONO:
1.1.1.2 ! root 556: ConfigureParams.Screen.MonitorType = MONITOR_TYPE_MONO;
! 557: bLoadAutoSave = FALSE;
! 558: break;
! 559:
! 560: case OPT_MONITOR:
! 561: i += 1;
! 562: if (strcasecmp(argv[i], "mono") == 0)
! 563: {
! 564: ConfigureParams.Screen.MonitorType = MONITOR_TYPE_MONO;
! 565: }
! 566: else if (strcasecmp(argv[i], "rgb") == 0)
! 567: {
! 568: ConfigureParams.Screen.MonitorType = MONITOR_TYPE_RGB;
! 569: }
! 570: else if (strcasecmp(argv[i], "vga") == 0)
! 571: {
! 572: ConfigureParams.Screen.MonitorType = MONITOR_TYPE_VGA;
! 573: }
! 574: else if (strcasecmp(argv[i], "tv") == 0)
! 575: {
! 576: ConfigureParams.Screen.MonitorType = MONITOR_TYPE_TV;
! 577: }
! 578: else
! 579: {
! 580: Opt_ShowExit(OPT_MONITOR, argv[i], "Unknown monitor type");
! 581: }
! 582: bLoadAutoSave = FALSE;
1.1 root 583: break;
584:
585: case OPT_FULLSCREEN:
586: ConfigureParams.Screen.bFullScreen = TRUE;
587: break;
588:
589: case OPT_WINDOW:
590: ConfigureParams.Screen.bFullScreen = FALSE;
591: break;
592:
1.1.1.2 ! root 593: case OPT_ZOOM:
! 594: zoom = atoi(argv[++i]);
! 595: if (zoom < 1)
! 596: {
! 597: Opt_ShowExit(OPT_ZOOM, argv[i], "Invalid zoom value");
! 598: }
! 599: if (zoom > 1)
! 600: {
! 601: /* TODO: only doubling supported for now */
! 602: ConfigureParams.Screen.bZoomLowRes = TRUE;
! 603: }
! 604: else
! 605: {
! 606: ConfigureParams.Screen.bZoomLowRes = FALSE;
1.1 root 607: }
608: break;
609:
1.1.1.2 ! root 610: case OPT_FRAMESKIPS:
! 611: skips = atoi(argv[++i]);
! 612: if (skips < 0 || skips > 8)
! 613: {
! 614: Opt_ShowExit(OPT_FRAMESKIPS, argv[i],
! 615: "Invalid frame skip value");
! 616: }
! 617: ConfigureParams.Screen.FrameSkips = skips;
1.1 root 618: break;
619:
1.1.1.2 ! root 620: case OPT_BORDERS:
! 621: ConfigureParams.Screen.bAllowOverscan = Opt_Bool(argv[++i], OPT_BORDERS);
1.1 root 622: break;
623:
1.1.1.2 ! root 624: case OPT_SPEC512:
! 625: threshold = atoi(argv[++i]);
! 626: if (threshold < 0 || threshold > 512)
! 627: {
! 628: Opt_ShowExit(OPT_SPEC512, argv[i],
! 629: "Invalid palette writes per line threshold for Spec512");
! 630: }
! 631: ConfigureParams.Screen.nSpec512Threshold = threshold;
! 632: break;
! 633:
! 634: case OPT_FORCEBPP:
! 635: planes = atoi(argv[++i]);
! 636: if ((planes % 8) || planes > 32)
! 637: {
! 638: Opt_ShowExit(OPT_FORCEBPP, argv[i], "Invalid bit depth");
! 639: }
! 640: if (planes == 24)
! 641: {
! 642: planes = 32; /* We do not support 24 bpp (yet) */
! 643: }
! 644: ConfigureParams.Screen.nForceBpp = planes;
! 645: break;
! 646:
! 647: case OPT_VDI_PLANES:
! 648: planes = atoi(argv[++i]);
! 649: switch(planes)
! 650: {
! 651: case 1:
! 652: ConfigureParams.Screen.nVdiColors = GEMCOLOR_2;
! 653: break;
! 654: case 2:
! 655: ConfigureParams.Screen.nVdiColors = GEMCOLOR_4;
! 656: break;
! 657: case 4:
! 658: ConfigureParams.Screen.nVdiColors = GEMCOLOR_16;
! 659: break;
! 660: default:
! 661: Opt_ShowExit(OPT_VDI_PLANES, argv[i], "Unsupported VDI bit-depth");
! 662: }
! 663: ConfigureParams.Screen.bUseExtVdiResolutions = TRUE;
! 664: bLoadAutoSave = FALSE;
! 665: break;
! 666:
! 667: case OPT_VDI_WIDTH:
! 668: ConfigureParams.Screen.nVdiWidth = atoi(argv[++i]);
! 669: ConfigureParams.Screen.bUseExtVdiResolutions = TRUE;
! 670: bLoadAutoSave = FALSE;
! 671: break;
! 672:
! 673: case OPT_VDI_HEIGHT:
! 674: ConfigureParams.Screen.nVdiHeight = atoi(argv[++i]);
! 675: ConfigureParams.Screen.bUseExtVdiResolutions = TRUE;
! 676: bLoadAutoSave = FALSE;
! 677: break;
! 678:
! 679: /* devices options */
! 680: case OPT_JOYSTICK:
! 681: i++;
! 682: if (strlen(argv[i]) != 1 ||
! 683: !Joy_SetCursorEmulation(argv[i][0] - '0'))
! 684: {
! 685: Opt_ShowExit(OPT_JOYSTICK, argv[i], "Invalid joystick port");
! 686: }
1.1 root 687: break;
688:
689: case OPT_PRINTER:
1.1.1.2 ! root 690: i += 1;
! 691: Opt_StrCpy(OPT_PRINTER, FALSE, ConfigureParams.Printer.szPrintToFileName,
! 692: argv[i], sizeof(ConfigureParams.Printer.szPrintToFileName),
! 693: &ConfigureParams.Printer.bEnablePrinting);
1.1 root 694: break;
695:
696: case OPT_MIDI:
697: i += 1;
1.1.1.2 ! root 698: Opt_StrCpy(OPT_MIDI, FALSE, ConfigureParams.Midi.szMidiOutFileName,
! 699: argv[i], sizeof(ConfigureParams.Midi.szMidiOutFileName),
! 700: &ConfigureParams.Midi.bEnableMidi);
1.1 root 701: break;
702:
703: case OPT_RS232:
704: i += 1;
1.1.1.2 ! root 705: if (Opt_StrCpy(OPT_RS232, TRUE, ConfigureParams.RS232.szInFileName,
! 706: argv[i], sizeof(ConfigureParams.RS232.szInFileName),
! 707: &ConfigureParams.RS232.bEnableRS232))
! 708: {
! 709: strncpy(ConfigureParams.RS232.szOutFileName, argv[i],
! 710: sizeof(ConfigureParams.RS232.szOutFileName));
1.1 root 711: }
712: break;
1.1.1.2 ! root 713:
! 714: /* disk options */
1.1 root 715: case OPT_HARDDRIVE:
716: i += 1;
1.1.1.2 ! root 717: if (Opt_StrCpy(OPT_HARDDRIVE, FALSE, ConfigureParams.HardDisk.szHardDiskDirectories[0],
! 718: argv[i], sizeof(ConfigureParams.HardDisk.szHardDiskDirectories[0]),
! 719: &ConfigureParams.HardDisk.bUseHardDiskDirectories))
! 720: {
1.1 root 721: ConfigureParams.HardDisk.bBootFromHardDisk = TRUE;
1.1.1.2 ! root 722: hdgiven = TRUE;
1.1 root 723: }
1.1.1.2 ! root 724: bLoadAutoSave = FALSE;
! 725: break;
! 726:
! 727: case OPT_ACSIHDIMAGE:
! 728: i += 1;
! 729: Opt_StrCpy(OPT_ACSIHDIMAGE, TRUE, ConfigureParams.HardDisk.szHardDiskImage,
! 730: argv[i], sizeof(ConfigureParams.HardDisk.szHardDiskImage),
! 731: &ConfigureParams.HardDisk.bUseHardDiskImage);
! 732: bLoadAutoSave = FALSE;
1.1 root 733: break;
734:
1.1.1.2 ! root 735: case OPT_IDEHDIMAGE:
1.1 root 736: i += 1;
1.1.1.2 ! root 737: Opt_StrCpy(OPT_IDEHDIMAGE, TRUE, ConfigureParams.HardDisk.szIdeHardDiskImage,
! 738: argv[i], sizeof(ConfigureParams.HardDisk.szIdeHardDiskImage),
! 739: &ConfigureParams.HardDisk.bUseIdeHardDiskImage);
! 740: bLoadAutoSave = FALSE;
! 741: break;
! 742:
! 743: case OPT_SLOWFDC:
! 744: ConfigureParams.System.bSlowFDC = Opt_Bool(argv[++i], OPT_SLOWFDC);
! 745: bLoadAutoSave = FALSE;
! 746: break;
! 747:
! 748: /* Memory options */
! 749: case OPT_MEMSIZE:
! 750: ConfigureParams.Memory.nMemorySize = atoi(argv[++i]);
! 751: if (ConfigureParams.Memory.nMemorySize < 0 ||
! 752: ConfigureParams.Memory.nMemorySize > 14)
! 753: {
! 754: Opt_ShowExit(OPT_MEMSIZE, argv[i], "Invalid memory size");
1.1 root 755: }
1.1.1.2 ! root 756: bLoadAutoSave = FALSE;
1.1 root 757: break;
758:
1.1.1.2 ! root 759: case OPT_TOS:
! 760: i += 1;
! 761: Opt_StrCpy(OPT_TOS, TRUE, ConfigureParams.Rom.szTosImageFileName,
! 762: argv[i], sizeof(ConfigureParams.Rom.szTosImageFileName),
! 763: NULL);
! 764: bLoadAutoSave = FALSE;
! 765: break;
! 766:
1.1 root 767: case OPT_CARTRIDGE:
768: i += 1;
1.1.1.2 ! root 769: Opt_StrCpy(OPT_CARTRIDGE, TRUE, ConfigureParams.Rom.szCartridgeImageFileName,
! 770: argv[i], sizeof(ConfigureParams.Rom.szCartridgeImageFileName),
! 771: NULL);
! 772: bLoadAutoSave = FALSE;
! 773: break;
! 774:
! 775: case OPT_MEMSTATE:
! 776: i += 1;
! 777: Opt_StrCpy(OPT_MEMSTATE, TRUE, ConfigureParams.Memory.szMemoryCaptureFileName,
! 778: argv[i], sizeof(ConfigureParams.Memory.szMemoryCaptureFileName),
! 779: NULL);
! 780: bLoadMemorySave = TRUE;
! 781: bLoadAutoSave = FALSE;
1.1 root 782: break;
783:
1.1.1.2 ! root 784: /* CPU options */
1.1 root 785: case OPT_CPULEVEL:
786: /* UAE core uses cpu_level variable */
1.1.1.2 ! root 787: ncpu = atoi(argv[++i]);
! 788: if(ncpu < 0 || ncpu > 4)
! 789: {
! 790: Opt_ShowExit(OPT_CPULEVEL, argv[i], "Invalid CPU level");
! 791: }
! 792: ConfigureParams.System.nCpuLevel = ncpu;
! 793: bLoadAutoSave = FALSE;
! 794: break;
! 795:
! 796: case OPT_CPUCLOCK:
! 797: cpuclock = atoi(argv[++i]);
! 798: if(cpuclock != 8 && cpuclock != 16 && cpuclock != 32)
! 799: {
! 800: Opt_ShowExit(OPT_CPUCLOCK, argv[i], "Invalid CPU clock");
1.1 root 801: }
1.1.1.2 ! root 802: ConfigureParams.System.nCpuFreq = cpuclock;
! 803: bLoadAutoSave = FALSE;
1.1 root 804: break;
805:
806: case OPT_COMPATIBLE:
1.1.1.2 ! root 807: ConfigureParams.System.bCompatibleCpu = Opt_Bool(argv[++i], OPT_COMPATIBLE);
! 808: bLoadAutoSave = FALSE;
1.1 root 809: break;
1.1.1.2 ! root 810:
! 811: /* system options */
! 812: case OPT_MACHINE:
! 813: i += 1;
! 814: if (strcasecmp(argv[i], "st") == 0)
! 815: {
! 816: ConfigureParams.System.nMachineType = MACHINE_ST;
! 817: ConfigureParams.System.nCpuLevel = 0;
! 818: ConfigureParams.System.nCpuFreq = 8;
! 819: }
! 820: else if (strcasecmp(argv[i], "ste") == 0)
! 821: {
! 822: ConfigureParams.System.nMachineType = MACHINE_STE;
! 823: ConfigureParams.System.nCpuLevel = 0;
! 824: ConfigureParams.System.nCpuFreq = 8;
! 825: }
! 826: else if (strcasecmp(argv[i], "tt") == 0)
! 827: {
! 828: ConfigureParams.System.nMachineType = MACHINE_TT;
! 829: ConfigureParams.System.nCpuLevel = 3;
! 830: ConfigureParams.System.nCpuFreq = 32;
! 831: }
! 832: else if (strcasecmp(argv[i], "falcon") == 0)
! 833: {
! 834: ConfigureParams.System.nMachineType = MACHINE_FALCON;
! 835: ConfigureParams.System.nCpuLevel = 3;
! 836: ConfigureParams.System.nCpuFreq = 16;
! 837: }
! 838: else
! 839: {
! 840: Opt_ShowExit(OPT_MACHINE, argv[i], "Unknown machine type");
! 841: }
! 842: bLoadAutoSave = FALSE;
1.1 root 843: break;
844:
1.1.1.2 ! root 845: case OPT_BLITTER:
! 846: ConfigureParams.System.bBlitter = Opt_Bool(argv[++i], OPT_BLITTER);
! 847: bLoadAutoSave = FALSE;
! 848: break;
! 849:
! 850: case OPT_DSP:
! 851: i += 1;
! 852: if (strcasecmp(argv[i], "none") == 0)
! 853: {
! 854: ConfigureParams.System.nDSPType = DSP_TYPE_NONE;
! 855: }
! 856: else if (strcasecmp(argv[i], "dummy") == 0)
! 857: {
! 858: ConfigureParams.System.nDSPType = DSP_TYPE_DUMMY;
! 859: }
! 860: else if (strcasecmp(argv[i], "emu") == 0)
! 861: {
! 862: #if ENABLE_DSP_EMU
! 863: ConfigureParams.System.nDSPType = DSP_TYPE_EMU;
! 864: #else
! 865: Opt_ShowExit(OPT_DSP, argv[i], "DSP type 'emu' support not compiled in");
! 866: #endif
! 867: }
! 868: else
! 869: {
! 870: Opt_ShowExit(OPT_DSP, argv[i], "Unknown DSP type");
1.1 root 871: }
1.1.1.2 ! root 872: bLoadAutoSave = FALSE;
1.1 root 873: break;
874:
1.1.1.2 ! root 875: case OPT_SOUND:
1.1 root 876: i += 1;
1.1.1.2 ! root 877: if (strcasecmp(argv[i], "off") == 0)
! 878: {
! 879: ConfigureParams.Sound.bEnableSound = FALSE;
! 880: }
! 881: else if (strcasecmp(argv[i], "low") == 0)
! 882: {
! 883: ConfigureParams.Sound.nPlaybackQuality = PLAYBACK_LOW;
! 884: ConfigureParams.Sound.bEnableSound = TRUE;
! 885: }
! 886: else if (strcasecmp(argv[i], "med") == 0)
! 887: {
! 888: ConfigureParams.Sound.nPlaybackQuality = PLAYBACK_MEDIUM;
! 889: ConfigureParams.Sound.bEnableSound = TRUE;
! 890: }
! 891: else if (strcasecmp(argv[i], "hi") == 0)
! 892: {
! 893: ConfigureParams.Sound.nPlaybackQuality = PLAYBACK_HIGH;
! 894: ConfigureParams.Sound.bEnableSound = TRUE;
! 895: }
! 896: else
! 897: {
! 898: Opt_ShowExit(OPT_SOUND, argv[i], "Unsupported sound quality");
1.1 root 899: }
900: break;
1.1.1.2 ! root 901:
1.1 root 902: case OPT_KEYMAPFILE:
903: i += 1;
1.1.1.2 ! root 904: Opt_StrCpy(OPT_KEYMAPFILE, TRUE, ConfigureParams.Keyboard.szMappingFileName,
! 905: argv[i], sizeof(ConfigureParams.Keyboard.szMappingFileName),
! 906: NULL);
! 907: ConfigureParams.Keyboard.nKeymapType = KEYMAP_LOADED;
1.1 root 908: break;
909:
1.1.1.2 ! root 910: /* debug options */
! 911: case OPT_DEBUG:
! 912: bEnableDebug = TRUE;
! 913: break;
! 914:
! 915: case OPT_LOG:
1.1 root 916: i += 1;
1.1.1.2 ! root 917: Opt_StrCpy(OPT_LOG, FALSE, ConfigureParams.Log.sLogFileName,
! 918: argv[i], sizeof(ConfigureParams.Log.sLogFileName),
! 919: NULL);
1.1 root 920: break;
921:
1.1.1.2 ! root 922: case OPT_TRACE:
! 923: i += 1;
! 924: if (ParseTraceOptions(argv[i]) == 0)
! 925: {
! 926: Opt_ShowExit(OPT_TRACE, argv[i], "Error parsing trace options (use --trace help for available list)!\n");
! 927: }
! 928: break;
! 929:
1.1 root 930: default:
1.1.1.2 ! root 931: Opt_ShowExit(OPT_NONE, argv[i], "Internal Hatari error, unhandled option");
1.1 root 932: }
933: }
1.1.1.2 ! root 934: if (*bootdisk && !hdgiven)
! 935: {
! 936: /* floppy image given without HD -> boot from floppy */
! 937: ConfigureParams.HardDisk.bBootFromHardDisk = FALSE;
! 938: }
1.1 root 939: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.