|
|
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.3 ! root 18: const char Main_rcsid[] = "Hatari $Id: options.c,v 1.49 2008/03/25 21:50:45 eerot Exp $";
1.1.1.2 root 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",
1.1.1.3 ! root 127: "<x>", "Force internal color bitdepth (x=8/15/16/32, 0=disable)" },
1.1.1.2 root 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]);
1.1.1.3 ! root 636: switch(planes)
1.1.1.2 root 637: {
1.1.1.3 ! root 638: case 32:
! 639: case 16:
! 640: case 15:
! 641: case 8:
! 642: break; /* supported */
! 643: case 24:
! 644: planes = 32; /* We do not support 24 bpp (yet) */
! 645: break;
! 646: default:
1.1.1.2 root 647: Opt_ShowExit(OPT_FORCEBPP, argv[i], "Invalid bit depth");
648: }
649: ConfigureParams.Screen.nForceBpp = planes;
650: break;
651:
652: case OPT_VDI_PLANES:
653: planes = atoi(argv[++i]);
654: switch(planes)
655: {
656: case 1:
657: ConfigureParams.Screen.nVdiColors = GEMCOLOR_2;
658: break;
659: case 2:
660: ConfigureParams.Screen.nVdiColors = GEMCOLOR_4;
661: break;
662: case 4:
663: ConfigureParams.Screen.nVdiColors = GEMCOLOR_16;
664: break;
665: default:
666: Opt_ShowExit(OPT_VDI_PLANES, argv[i], "Unsupported VDI bit-depth");
667: }
668: ConfigureParams.Screen.bUseExtVdiResolutions = TRUE;
669: bLoadAutoSave = FALSE;
670: break;
671:
672: case OPT_VDI_WIDTH:
673: ConfigureParams.Screen.nVdiWidth = atoi(argv[++i]);
674: ConfigureParams.Screen.bUseExtVdiResolutions = TRUE;
675: bLoadAutoSave = FALSE;
676: break;
677:
678: case OPT_VDI_HEIGHT:
679: ConfigureParams.Screen.nVdiHeight = atoi(argv[++i]);
680: ConfigureParams.Screen.bUseExtVdiResolutions = TRUE;
681: bLoadAutoSave = FALSE;
682: break;
683:
684: /* devices options */
685: case OPT_JOYSTICK:
686: i++;
687: if (strlen(argv[i]) != 1 ||
688: !Joy_SetCursorEmulation(argv[i][0] - '0'))
689: {
690: Opt_ShowExit(OPT_JOYSTICK, argv[i], "Invalid joystick port");
691: }
1.1 root 692: break;
693:
694: case OPT_PRINTER:
1.1.1.2 root 695: i += 1;
696: Opt_StrCpy(OPT_PRINTER, FALSE, ConfigureParams.Printer.szPrintToFileName,
697: argv[i], sizeof(ConfigureParams.Printer.szPrintToFileName),
698: &ConfigureParams.Printer.bEnablePrinting);
1.1 root 699: break;
700:
701: case OPT_MIDI:
702: i += 1;
1.1.1.2 root 703: Opt_StrCpy(OPT_MIDI, FALSE, ConfigureParams.Midi.szMidiOutFileName,
704: argv[i], sizeof(ConfigureParams.Midi.szMidiOutFileName),
705: &ConfigureParams.Midi.bEnableMidi);
1.1 root 706: break;
707:
708: case OPT_RS232:
709: i += 1;
1.1.1.2 root 710: if (Opt_StrCpy(OPT_RS232, TRUE, ConfigureParams.RS232.szInFileName,
711: argv[i], sizeof(ConfigureParams.RS232.szInFileName),
712: &ConfigureParams.RS232.bEnableRS232))
713: {
714: strncpy(ConfigureParams.RS232.szOutFileName, argv[i],
715: sizeof(ConfigureParams.RS232.szOutFileName));
1.1 root 716: }
717: break;
1.1.1.2 root 718:
719: /* disk options */
1.1 root 720: case OPT_HARDDRIVE:
721: i += 1;
1.1.1.2 root 722: if (Opt_StrCpy(OPT_HARDDRIVE, FALSE, ConfigureParams.HardDisk.szHardDiskDirectories[0],
723: argv[i], sizeof(ConfigureParams.HardDisk.szHardDiskDirectories[0]),
724: &ConfigureParams.HardDisk.bUseHardDiskDirectories))
725: {
1.1 root 726: ConfigureParams.HardDisk.bBootFromHardDisk = TRUE;
1.1.1.2 root 727: hdgiven = TRUE;
1.1 root 728: }
1.1.1.2 root 729: bLoadAutoSave = FALSE;
730: break;
731:
732: case OPT_ACSIHDIMAGE:
733: i += 1;
734: Opt_StrCpy(OPT_ACSIHDIMAGE, TRUE, ConfigureParams.HardDisk.szHardDiskImage,
735: argv[i], sizeof(ConfigureParams.HardDisk.szHardDiskImage),
736: &ConfigureParams.HardDisk.bUseHardDiskImage);
737: bLoadAutoSave = FALSE;
1.1 root 738: break;
739:
1.1.1.2 root 740: case OPT_IDEHDIMAGE:
1.1 root 741: i += 1;
1.1.1.2 root 742: Opt_StrCpy(OPT_IDEHDIMAGE, TRUE, ConfigureParams.HardDisk.szIdeHardDiskImage,
743: argv[i], sizeof(ConfigureParams.HardDisk.szIdeHardDiskImage),
744: &ConfigureParams.HardDisk.bUseIdeHardDiskImage);
745: bLoadAutoSave = FALSE;
746: break;
747:
748: case OPT_SLOWFDC:
749: ConfigureParams.System.bSlowFDC = Opt_Bool(argv[++i], OPT_SLOWFDC);
750: bLoadAutoSave = FALSE;
751: break;
752:
753: /* Memory options */
754: case OPT_MEMSIZE:
755: ConfigureParams.Memory.nMemorySize = atoi(argv[++i]);
756: if (ConfigureParams.Memory.nMemorySize < 0 ||
757: ConfigureParams.Memory.nMemorySize > 14)
758: {
759: Opt_ShowExit(OPT_MEMSIZE, argv[i], "Invalid memory size");
1.1 root 760: }
1.1.1.2 root 761: bLoadAutoSave = FALSE;
1.1 root 762: break;
763:
1.1.1.2 root 764: case OPT_TOS:
765: i += 1;
766: Opt_StrCpy(OPT_TOS, TRUE, ConfigureParams.Rom.szTosImageFileName,
767: argv[i], sizeof(ConfigureParams.Rom.szTosImageFileName),
768: NULL);
769: bLoadAutoSave = FALSE;
770: break;
771:
1.1 root 772: case OPT_CARTRIDGE:
773: i += 1;
1.1.1.2 root 774: Opt_StrCpy(OPT_CARTRIDGE, TRUE, ConfigureParams.Rom.szCartridgeImageFileName,
775: argv[i], sizeof(ConfigureParams.Rom.szCartridgeImageFileName),
776: NULL);
777: bLoadAutoSave = FALSE;
778: break;
779:
780: case OPT_MEMSTATE:
781: i += 1;
782: Opt_StrCpy(OPT_MEMSTATE, TRUE, ConfigureParams.Memory.szMemoryCaptureFileName,
783: argv[i], sizeof(ConfigureParams.Memory.szMemoryCaptureFileName),
784: NULL);
785: bLoadMemorySave = TRUE;
786: bLoadAutoSave = FALSE;
1.1 root 787: break;
788:
1.1.1.2 root 789: /* CPU options */
1.1 root 790: case OPT_CPULEVEL:
791: /* UAE core uses cpu_level variable */
1.1.1.2 root 792: ncpu = atoi(argv[++i]);
793: if(ncpu < 0 || ncpu > 4)
794: {
795: Opt_ShowExit(OPT_CPULEVEL, argv[i], "Invalid CPU level");
796: }
797: ConfigureParams.System.nCpuLevel = ncpu;
798: bLoadAutoSave = FALSE;
799: break;
800:
801: case OPT_CPUCLOCK:
802: cpuclock = atoi(argv[++i]);
803: if(cpuclock != 8 && cpuclock != 16 && cpuclock != 32)
804: {
805: Opt_ShowExit(OPT_CPUCLOCK, argv[i], "Invalid CPU clock");
1.1 root 806: }
1.1.1.2 root 807: ConfigureParams.System.nCpuFreq = cpuclock;
808: bLoadAutoSave = FALSE;
1.1 root 809: break;
810:
811: case OPT_COMPATIBLE:
1.1.1.2 root 812: ConfigureParams.System.bCompatibleCpu = Opt_Bool(argv[++i], OPT_COMPATIBLE);
813: bLoadAutoSave = FALSE;
1.1 root 814: break;
1.1.1.2 root 815:
816: /* system options */
817: case OPT_MACHINE:
818: i += 1;
819: if (strcasecmp(argv[i], "st") == 0)
820: {
821: ConfigureParams.System.nMachineType = MACHINE_ST;
822: ConfigureParams.System.nCpuLevel = 0;
823: ConfigureParams.System.nCpuFreq = 8;
824: }
825: else if (strcasecmp(argv[i], "ste") == 0)
826: {
827: ConfigureParams.System.nMachineType = MACHINE_STE;
828: ConfigureParams.System.nCpuLevel = 0;
829: ConfigureParams.System.nCpuFreq = 8;
830: }
831: else if (strcasecmp(argv[i], "tt") == 0)
832: {
833: ConfigureParams.System.nMachineType = MACHINE_TT;
834: ConfigureParams.System.nCpuLevel = 3;
835: ConfigureParams.System.nCpuFreq = 32;
836: }
837: else if (strcasecmp(argv[i], "falcon") == 0)
838: {
839: ConfigureParams.System.nMachineType = MACHINE_FALCON;
840: ConfigureParams.System.nCpuLevel = 3;
841: ConfigureParams.System.nCpuFreq = 16;
842: }
843: else
844: {
845: Opt_ShowExit(OPT_MACHINE, argv[i], "Unknown machine type");
846: }
847: bLoadAutoSave = FALSE;
1.1 root 848: break;
849:
1.1.1.2 root 850: case OPT_BLITTER:
851: ConfigureParams.System.bBlitter = Opt_Bool(argv[++i], OPT_BLITTER);
852: bLoadAutoSave = FALSE;
853: break;
854:
855: case OPT_DSP:
856: i += 1;
857: if (strcasecmp(argv[i], "none") == 0)
858: {
859: ConfigureParams.System.nDSPType = DSP_TYPE_NONE;
860: }
861: else if (strcasecmp(argv[i], "dummy") == 0)
862: {
863: ConfigureParams.System.nDSPType = DSP_TYPE_DUMMY;
864: }
865: else if (strcasecmp(argv[i], "emu") == 0)
866: {
867: #if ENABLE_DSP_EMU
868: ConfigureParams.System.nDSPType = DSP_TYPE_EMU;
869: #else
870: Opt_ShowExit(OPT_DSP, argv[i], "DSP type 'emu' support not compiled in");
871: #endif
872: }
873: else
874: {
875: Opt_ShowExit(OPT_DSP, argv[i], "Unknown DSP type");
1.1 root 876: }
1.1.1.2 root 877: bLoadAutoSave = FALSE;
1.1 root 878: break;
879:
1.1.1.2 root 880: case OPT_SOUND:
1.1 root 881: i += 1;
1.1.1.2 root 882: if (strcasecmp(argv[i], "off") == 0)
883: {
884: ConfigureParams.Sound.bEnableSound = FALSE;
885: }
886: else if (strcasecmp(argv[i], "low") == 0)
887: {
888: ConfigureParams.Sound.nPlaybackQuality = PLAYBACK_LOW;
889: ConfigureParams.Sound.bEnableSound = TRUE;
890: }
891: else if (strcasecmp(argv[i], "med") == 0)
892: {
893: ConfigureParams.Sound.nPlaybackQuality = PLAYBACK_MEDIUM;
894: ConfigureParams.Sound.bEnableSound = TRUE;
895: }
896: else if (strcasecmp(argv[i], "hi") == 0)
897: {
898: ConfigureParams.Sound.nPlaybackQuality = PLAYBACK_HIGH;
899: ConfigureParams.Sound.bEnableSound = TRUE;
900: }
901: else
902: {
903: Opt_ShowExit(OPT_SOUND, argv[i], "Unsupported sound quality");
1.1 root 904: }
905: break;
1.1.1.2 root 906:
1.1 root 907: case OPT_KEYMAPFILE:
908: i += 1;
1.1.1.2 root 909: Opt_StrCpy(OPT_KEYMAPFILE, TRUE, ConfigureParams.Keyboard.szMappingFileName,
910: argv[i], sizeof(ConfigureParams.Keyboard.szMappingFileName),
911: NULL);
912: ConfigureParams.Keyboard.nKeymapType = KEYMAP_LOADED;
1.1 root 913: break;
914:
1.1.1.2 root 915: /* debug options */
916: case OPT_DEBUG:
917: bEnableDebug = TRUE;
918: break;
919:
920: case OPT_LOG:
1.1 root 921: i += 1;
1.1.1.2 root 922: Opt_StrCpy(OPT_LOG, FALSE, ConfigureParams.Log.sLogFileName,
923: argv[i], sizeof(ConfigureParams.Log.sLogFileName),
924: NULL);
1.1 root 925: break;
926:
1.1.1.2 root 927: case OPT_TRACE:
928: i += 1;
929: if (ParseTraceOptions(argv[i]) == 0)
930: {
931: Opt_ShowExit(OPT_TRACE, argv[i], "Error parsing trace options (use --trace help for available list)!\n");
932: }
933: break;
934:
1.1 root 935: default:
1.1.1.2 root 936: Opt_ShowExit(OPT_NONE, argv[i], "Internal Hatari error, unhandled option");
1.1 root 937: }
938: }
1.1.1.2 root 939: if (*bootdisk && !hdgiven)
940: {
941: /* floppy image given without HD -> boot from floppy */
942: ConfigureParams.HardDisk.bBootFromHardDisk = FALSE;
943: }
1.1 root 944: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.