|
|
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>
1.1.1.7 root 21: #include <SDL.h>
1.1 root 22:
23: #include "main.h"
24: #include "options.h"
25: #include "configuration.h"
1.1.1.4 root 26: #include "control.h"
1.1.1.6 root 27: #include "debugui.h"
1.1 root 28: #include "file.h"
1.1.1.4 root 29: #include "floppy.h"
1.1 root 30: #include "screen.h"
1.1.1.8 ! root 31: #include "sound.h"
1.1 root 32: #include "video.h"
33: #include "vdi.h"
34: #include "joy.h"
1.1.1.4 root 35: #include "log.h"
1.1.1.8 ! root 36: #include "tos.h"
! 37: #include "paths.h"
1.1.1.7 root 38: #include "avi_record.h"
1.1.1.2 root 39:
40: #include "hatari-glue.h"
41:
1.1 root 42:
1.1.1.4 root 43: bool bLoadAutoSave; /* Load autosave memory snapshot at startup */
44: bool bLoadMemorySave; /* Load memory snapshot provided via option at startup */
45: bool bBiosIntercept; /* whether UAE should intercept Bios & XBios calls */
1.1.1.7 root 46: bool AviRecordOnStartup; /* Start avi recording at startup */
1.1 root 47:
1.1.1.7 root 48: static bool bNoSDLParachute;
1.1 root 49:
50: /* List of supported options. */
51: enum {
1.1.1.2 root 52: OPT_HEADER, /* options section header */
53: OPT_HELP, /* general options */
1.1 root 54: OPT_VERSION,
1.1.1.2 root 55: OPT_CONFIRMQUIT,
56: OPT_CONFIGFILE,
1.1.1.8 ! root 57: OPT_KEYMAPFILE,
1.1.1.4 root 58: OPT_FASTFORWARD,
1.1.1.8 ! root 59: OPT_MONO, /* common display options */
1.1.1.2 root 60: OPT_MONITOR,
1.1 root 61: OPT_FULLSCREEN,
62: OPT_WINDOW,
1.1.1.6 root 63: OPT_GRAB,
1.1.1.7 root 64: OPT_FRAMESKIPS,
1.1.1.4 root 65: OPT_STATUSBAR,
66: OPT_DRIVE_LED,
1.1.1.2 root 67: OPT_FORCEBPP,
1.1.1.8 ! root 68: OPT_BORDERS, /* ST/STE display options */
! 69: OPT_SPEC512,
! 70: OPT_ZOOM,
! 71: OPT_RESOLUTION, /* Falcon/TT display options */
! 72: OPT_MAXWIDTH,
! 73: OPT_MAXHEIGHT,
! 74: OPT_ASPECT,
1.1.1.4 root 75: OPT_VDI, /* VDI options */
76: OPT_VDI_PLANES,
1.1.1.2 root 77: OPT_VDI_WIDTH,
78: OPT_VDI_HEIGHT,
1.1.1.8 ! root 79: OPT_SCREEN_CROP, /* screen capture options */
! 80: OPT_AVIRECORD,
1.1.1.7 root 81: OPT_AVIRECORD_VCODEC,
82: OPT_AVIRECORD_FPS,
83: OPT_AVIRECORD_FILE,
1.1.1.2 root 84: OPT_JOYSTICK, /* device options */
1.1.1.4 root 85: OPT_JOYSTICK0,
86: OPT_JOYSTICK1,
87: OPT_JOYSTICK2,
88: OPT_JOYSTICK3,
89: OPT_JOYSTICK4,
90: OPT_JOYSTICK5,
1.1 root 91: OPT_PRINTER,
1.1.1.5 root 92: OPT_MIDI_IN,
93: OPT_MIDI_OUT,
94: OPT_RS232_IN,
95: OPT_RS232_OUT,
1.1.1.4 root 96: OPT_DISKA, /* disk options */
97: OPT_DISKB,
1.1.1.6 root 98: OPT_SLOWFLOPPY,
1.1.1.7 root 99: OPT_WRITEPROT_FLOPPY,
100: OPT_WRITEPROT_HD,
1.1.1.4 root 101: OPT_HARDDRIVE,
1.1.1.2 root 102: OPT_ACSIHDIMAGE,
1.1.1.7 root 103: OPT_IDEMASTERHDIMAGE,
104: OPT_IDESLAVEHDIMAGE,
1.1.1.2 root 105: OPT_MEMSIZE, /* memory options */
1.1 root 106: OPT_TOS,
107: OPT_CARTRIDGE,
1.1.1.2 root 108: OPT_MEMSTATE,
109: OPT_CPULEVEL, /* CPU options */
110: OPT_CPUCLOCK,
1.1 root 111: OPT_COMPATIBLE,
1.1.1.8 ! root 112: #if ENABLE_WINUAE_CPU
! 113: OPT_CPU_CYCLE_EXACT, /* WinUAE CPU/FPU/bus options */
! 114: OPT_CPU_ADDR24,
! 115: OPT_FPU_TYPE,
! 116: OPT_FPU_COMPATIBLE,
! 117: OPT_MMU,
! 118: #endif
1.1.1.2 root 119: OPT_MACHINE, /* system options */
1.1 root 120: OPT_BLITTER,
1.1.1.2 root 121: OPT_DSP,
1.1.1.8 ! root 122: OPT_MICROPHONE,
1.1.1.2 root 123: OPT_SOUND,
1.1.1.7 root 124: OPT_SOUNDBUFFERSIZE,
1.1.1.8 ! root 125: OPT_YM_MIXING,
! 126: OPT_TIMERD,
! 127: OPT_RTC,
1.1.1.2 root 128: OPT_DEBUG, /* debug options */
1.1.1.4 root 129: OPT_BIOSINTERCEPT,
1.1.1.2 root 130: OPT_TRACE,
1.1.1.4 root 131: OPT_TRACEFILE,
1.1.1.7 root 132: OPT_PARSE,
133: OPT_SAVECONFIG,
134: OPT_PARACHUTE,
1.1.1.4 root 135: OPT_CONTROLSOCKET,
136: OPT_LOGFILE,
137: OPT_LOGLEVEL,
138: OPT_ALERTLEVEL,
1.1.1.6 root 139: OPT_RUNVBLS,
1.1.1.4 root 140: OPT_ERROR,
141: OPT_CONTINUE
1.1 root 142: };
143:
144: typedef struct {
145: unsigned int id; /* option ID */
146: const char *chr; /* short option */
147: const char *str; /* long option */
1.1.1.2 root 148: const char *arg; /* type name for argument, if any */
1.1 root 149: const char *desc; /* option description */
150: } opt_t;
151:
1.1.1.2 root 152: /* it's easier to edit these if they are kept in the same order as the enums */
1.1 root 153: static const opt_t HatariOptions[] = {
1.1.1.2 root 154:
155: { OPT_HEADER, NULL, NULL, NULL, "General" },
1.1 root 156: { OPT_HELP, "-h", "--help",
157: NULL, "Print this help text and exit" },
158: { OPT_VERSION, "-v", "--version",
1.1.1.2 root 159: NULL, "Print version number and exit" },
1.1.1.4 root 160: { OPT_CONFIRMQUIT, NULL, "--confirm-quit",
1.1.1.2 root 161: "<bool>", "Whether Hatari confirms quit" },
1.1.1.4 root 162: { OPT_CONFIGFILE, "-c", "--configfile",
163: "<file>", "Use <file> instead of the default hatari config file" },
1.1.1.8 ! root 164: { OPT_KEYMAPFILE, "-k", "--keymap",
! 165: "<file>", "Read (additional) keyboard mappings from <file>" },
1.1.1.4 root 166: { OPT_FASTFORWARD, NULL, "--fast-forward",
167: "<bool>", "Help skipping stuff on fast machine" },
168:
1.1.1.8 ! root 169: { OPT_HEADER, NULL, NULL, NULL, "Common display" },
1.1 root 170: { OPT_MONO, "-m", "--mono",
171: NULL, "Start in monochrome mode instead of color" },
1.1.1.2 root 172: { OPT_MONITOR, NULL, "--monitor",
173: "<x>", "Select monitor type (x = mono/rgb/vga/tv)" },
1.1 root 174: { OPT_FULLSCREEN,"-f", "--fullscreen",
175: NULL, "Start emulator in fullscreen mode" },
176: { OPT_WINDOW, "-w", "--window",
177: NULL, "Start emulator in window mode" },
1.1.1.6 root 178: { OPT_GRAB, NULL, "--grab",
179: NULL, "Grab mouse (also) in window mode" },
1.1.1.2 root 180: { OPT_FRAMESKIPS, NULL, "--frameskips",
1.1.1.4 root 181: "<x>", "Skip <x> frames after each shown frame (0=off, >4=auto/max)" },
182: { OPT_STATUSBAR, NULL, "--statusbar",
183: "<bool>", "Show statusbar (floppy leds etc)" },
184: { OPT_DRIVE_LED, NULL, "--drive-led",
185: "<bool>", "Show overlay drive led when statusbar isn't shown" },
1.1.1.2 root 186: { OPT_FORCEBPP, NULL, "--bpp",
1.1.1.4 root 187: "<x>", "Force internal bitdepth (x = 8/15/16/32, 0=disable)" },
1.1.1.7 root 188:
1.1.1.8 ! root 189: { OPT_HEADER, NULL, NULL, NULL, "ST/STE specific display" },
! 190: { OPT_BORDERS, NULL, "--borders",
! 191: "<bool>", "Show screen borders (for overscan demos etc)" },
! 192: { OPT_SPEC512, NULL, "--spec512",
! 193: "<x>", "Spec512 palette threshold (0 <= x <= 512, 0=disable)" },
! 194: { OPT_ZOOM, "-z", "--zoom",
! 195: "<x>", "Double small resolutions (1=no, 2=yes)" },
! 196:
! 197: { OPT_HEADER, NULL, NULL, NULL, "Falcon/TT specific display" },
! 198: { OPT_RESOLUTION, NULL, "--desktop",
! 199: "<bool>", "Keep desktop resolution on fullscreen" },
! 200: { OPT_MAXWIDTH, NULL, "--max-width",
! 201: "<x>", "Maximum window width for zooming" },
! 202: { OPT_MAXHEIGHT, NULL, "--max-height",
! 203: "<x>", "Maximum window height for zooming" },
! 204: { OPT_ASPECT, NULL, "--aspect",
! 205: "<bool>", "Monitor aspect ratio correction" },
! 206:
1.1.1.2 root 207: { OPT_HEADER, NULL, NULL, NULL, "VDI" },
1.1.1.4 root 208: { OPT_VDI, NULL, "--vdi",
209: "<bool>", "Whether to use VDI screen mode" },
1.1.1.2 root 210: { OPT_VDI_PLANES,NULL, "--vdi-planes",
1.1.1.4 root 211: "<x>", "VDI mode bit-depth (x = 1/2/4)" },
1.1.1.2 root 212: { OPT_VDI_WIDTH, NULL, "--vdi-width",
1.1.1.7 root 213: "<w>", "VDI mode width (320 < w <= 1280)" },
1.1.1.2 root 214: { OPT_VDI_HEIGHT, NULL, "--vdi-height",
1.1.1.7 root 215: "<h>", "VDI mode height (200 < h <= 960)" },
216:
1.1.1.8 ! root 217: { OPT_HEADER, NULL, NULL, NULL, "Screen capture" },
! 218: { OPT_SCREEN_CROP, NULL, "--crop",
! 219: "<bool>", "Remove statusbar from screen capture" },
1.1.1.7 root 220: { OPT_AVIRECORD, NULL, "--avirecord",
221: NULL, "Start AVI recording" },
222: { OPT_AVIRECORD_VCODEC, NULL, "--avi-vcodec",
223: "<x>", "Select avi video codec (x = bmp/png)" },
224: { OPT_AVIRECORD_FPS, NULL, "--avi-fps",
225: "<x>", "Force avi frame rate (x = 50/60/71/...)" },
226: { OPT_AVIRECORD_FILE, NULL, "--avi-file",
227: "<file>", "Use <file> to record avi" },
228:
1.1.1.2 root 229: { OPT_HEADER, NULL, NULL, NULL, "Devices" },
1.1 root 230: { OPT_JOYSTICK, "-j", "--joystick",
1.1.1.2 root 231: "<port>", "Emulate joystick with cursor keys in given port (0-5)" },
1.1.1.4 root 232: /* these have to be exactly the same as I'm relying compiler giving
233: * them the same same string pointer when strings are identical
1.1.1.7 root 234: * (Opt_ShowHelpSection() skips successive options with same help
235: * pointer).
1.1.1.4 root 236: */
237: { OPT_JOYSTICK0, NULL, "--joy<port>",
238: "<type>", "Set joystick type (none/keys/real) for given port" },
239: { OPT_JOYSTICK1, NULL, "--joy<port>",
240: "<type>", "Set joystick type (none/keys/real) for given port" },
241: { OPT_JOYSTICK2, NULL, "--joy<port>",
242: "<type>", "Set joystick type (none/keys/real) for given port" },
243: { OPT_JOYSTICK3, NULL, "--joy<port>",
244: "<type>", "Set joystick type (none/keys/real) for given port" },
245: { OPT_JOYSTICK4, NULL, "--joy<port>",
246: "<type>", "Set joystick type (none/keys/real) for given port" },
247: { OPT_JOYSTICK5, NULL, "--joy<port>",
248: "<type>", "Set joystick type (none/keys/real) for given port" },
1.1 root 249: { OPT_PRINTER, NULL, "--printer",
1.1.1.2 root 250: "<file>", "Enable printer support and write data to <file>" },
1.1.1.5 root 251: { OPT_MIDI_IN, NULL, "--midi-in",
252: "<file>", "Enable MIDI and use <file> as the input device" },
253: { OPT_MIDI_OUT, NULL, "--midi-out",
254: "<file>", "Enable MIDI and use <file> as the output device" },
255: { OPT_RS232_IN, NULL, "--rs232-in",
256: "<file>", "Enable serial port and use <file> as the input device" },
257: { OPT_RS232_OUT, NULL, "--rs232-out",
258: "<file>", "Enable serial port and use <file> as the output device" },
1.1.1.2 root 259:
260: { OPT_HEADER, NULL, NULL, NULL, "Disk" },
1.1.1.4 root 261: { OPT_DISKA, NULL, "--disk-a",
262: "<file>", "Set disk image for floppy drive A" },
263: { OPT_DISKB, NULL, "--disk-b",
264: "<file>", "Set disk image for floppy drive B" },
1.1.1.6 root 265: { OPT_SLOWFLOPPY, NULL, "--slowfdc",
266: "<bool>", "Slow down floppy disk access emulation" },
1.1.1.7 root 267: { OPT_WRITEPROT_FLOPPY, NULL, "--protect-floppy",
268: "<x>", "Write protect floppy image contents (on/off/auto)" },
269: { OPT_WRITEPROT_HD, NULL, "--protect-hd",
270: "<x>", "Write protect harddrive <dir> contents (on/off/auto)" },
1.1 root 271: { OPT_HARDDRIVE, "-d", "--harddrive",
1.1.1.7 root 272: "<dir>", "Emulate harddrive partition(s) with <dir> contents" },
1.1.1.2 root 273: { OPT_ACSIHDIMAGE, NULL, "--acsi",
274: "<file>", "Emulate an ACSI harddrive with an image <file>" },
1.1.1.7 root 275: { OPT_IDEMASTERHDIMAGE, NULL, "--ide-master",
276: "<file>", "Emulate an IDE master harddrive with an image <file>" },
277: { OPT_IDESLAVEHDIMAGE, NULL, "--ide-slave",
278: "<file>", "Emulate an IDE slave harddrive with an image <file>" },
1.1.1.2 root 279:
280: { OPT_HEADER, NULL, NULL, NULL, "Memory" },
281: { OPT_MEMSIZE, "-s", "--memsize",
1.1.1.4 root 282: "<x>", "ST RAM size (x = size in MiB from 0 to 14, 0 = 512KiB)" },
1.1 root 283: { OPT_TOS, "-t", "--tos",
284: "<file>", "Use TOS image <file>" },
285: { OPT_CARTRIDGE, NULL, "--cartridge",
286: "<file>", "Use ROM cartridge image <file>" },
1.1.1.2 root 287: { OPT_MEMSTATE, NULL, "--memstate",
288: "<file>", "Load memory snap-shot <file>" },
289:
290: { OPT_HEADER, NULL, NULL, NULL, "CPU" },
1.1 root 291: { OPT_CPULEVEL, NULL, "--cpulevel",
1.1.1.2 root 292: "<x>", "Set the CPU type (x => 680x0) (EmuTOS/TOS 2.06 only!)" },
293: { OPT_CPUCLOCK, NULL, "--cpuclock",
1.1.1.4 root 294: "<x>", "Set the CPU clock (x = 8/16/32)" },
295: { OPT_COMPATIBLE, NULL, "--compatible",
1.1.1.2 root 296: "<bool>", "Use a more compatible (but slower) 68000 CPU mode" },
1.1.1.8 ! root 297:
! 298: #if ENABLE_WINUAE_CPU
! 299: { OPT_HEADER, NULL, NULL, NULL, "WinUAE CPU/FPU/bus" },
! 300: { OPT_CPU_CYCLE_EXACT, NULL, "--cpu-exact",
! 301: "<bool>", "Use cycle exact CPU emulation" },
! 302: { OPT_CPU_ADDR24, NULL, "--addr24",
! 303: "<bool>", "Use 24-bit instead of 32-bit addressing mode" },
! 304: { OPT_FPU_TYPE, NULL, "--fpu-type",
! 305: "<x>", "FPU type (x=none/68881/68882/internal)" },
! 306: { OPT_FPU_COMPATIBLE, NULL, "--fpu-compatible",
! 307: "<bool>", "Use more compatible, but slower FPU emulation" },
! 308: { OPT_MMU, NULL, "--mmu",
! 309: "<bool>", "Use MMU emulation" },
! 310: #endif
! 311:
1.1.1.2 root 312: { OPT_HEADER, NULL, NULL, NULL, "Misc system" },
313: { OPT_MACHINE, NULL, "--machine",
314: "<x>", "Select machine type (x = st/ste/tt/falcon)" },
1.1 root 315: { OPT_BLITTER, NULL, "--blitter",
1.1.1.2 root 316: "<bool>", "Use blitter emulation (ST only)" },
317: { OPT_DSP, NULL, "--dsp",
1.1.1.4 root 318: "<x>", "DSP emulation (x = none/dummy/emu, Falcon only)" },
1.1.1.8 ! root 319: { OPT_MICROPHONE, NULL, "--mic",
! 320: "<bool>", "Enable/disable (Falcon only) microphone" },
1.1.1.2 root 321: { OPT_SOUND, NULL, "--sound",
1.1.1.6 root 322: "<x>", "Sound frequency (x=off/6000-50066, off=fastest)" },
1.1.1.7 root 323: { OPT_SOUNDBUFFERSIZE, NULL, "--sound-buffer-size",
1.1.1.8 ! root 324: "<x>", "Sound buffer size for SDL in ms (x=0/10-100, 0=default)" },
! 325: { OPT_YM_MIXING, NULL, "--ym-mixing",
! 326: "<x>", "YM sound mixing method (x=linear/table)" },
! 327: { OPT_TIMERD, NULL, "--timer-d",
! 328: "<bool>", "Patch Timer-D (about doubles ST emulation speed)" },
! 329: { OPT_RTC, NULL, "--rtc",
! 330: "<bool>", "Enable real-time clock" },
! 331:
1.1.1.2 root 332: { OPT_HEADER, NULL, NULL, NULL, "Debug" },
333: { OPT_DEBUG, "-D", "--debug",
1.1.1.6 root 334: NULL, "Toggle whether CPU exceptions invoke debugger" },
1.1.1.4 root 335: { OPT_BIOSINTERCEPT, NULL, "--bios-intercept",
1.1.1.8 ! root 336: NULL, "Toggle X/Bios interception & CON: redirection" },
1.1.1.2 root 337: { OPT_TRACE, NULL, "--trace",
1.1.1.4 root 338: "<trace1,...>", "Activate emulation tracing, see '--trace help'" },
339: { OPT_TRACEFILE, NULL, "--trace-file",
340: "<file>", "Save trace output to <file> (default=stderr)" },
1.1.1.7 root 341: { OPT_PARSE, NULL, "--parse",
342: "<file>", "Parse/execute debugger commands from <file>" },
343: { OPT_SAVECONFIG, NULL, "--saveconfig",
344: NULL, "Save current Hatari configuration and exit" },
345: { OPT_PARACHUTE, NULL, "--no-parachute",
346: NULL, "Disable SDL parachute to get Hatari core dumps" },
1.1.1.4 root 347: #if HAVE_UNIX_DOMAIN_SOCKETS
348: { OPT_CONTROLSOCKET, NULL, "--control-socket",
349: "<file>", "Hatari reads options from given socket at run-time" },
350: #endif
351: { OPT_LOGFILE, NULL, "--log-file",
352: "<file>", "Save log output to <file> (default=stderr)" },
353: { OPT_LOGLEVEL, NULL, "--log-level",
354: "<x>", "Log output level (x=debug/todo/info/warn/error/fatal)" },
355: { OPT_ALERTLEVEL, NULL, "--alert-level",
356: "<x>", "Show dialog for log messages above given level" },
1.1.1.6 root 357: { OPT_RUNVBLS, NULL, "--run-vbls",
358: "<x>", "Exit after x VBLs" },
1.1.1.4 root 359:
360: { OPT_ERROR, NULL, NULL, NULL, NULL }
1.1 root 361: };
362:
1.1.1.2 root 363:
364: /**
365: * Show version string and license.
1.1 root 366: */
1.1.1.2 root 367: static void Opt_ShowVersion(void)
368: {
1.1.1.4 root 369: printf("\n" PROG_NAME
370: " - the Atari ST, STE, TT and Falcon emulator.\n\n");
1.1.1.2 root 371: printf("Hatari is free software licensed under the GNU General"
372: " Public License.\n\n");
373: }
374:
375:
376: /**
377: * Calculate option + value len
378: */
379: static unsigned int Opt_OptionLen(const opt_t *opt)
380: {
381: unsigned int len;
382: len = strlen(opt->str);
383: if (opt->arg)
384: {
385: len += strlen(opt->arg);
386: len += 1;
387: /* with arg, short options go to another line */
388: }
389: else
390: {
391: if (opt->chr)
392: {
393: /* ' or -c' */
394: len += 6;
395: }
396: }
397: return len;
398: }
399:
400:
401: /**
402: * Show single option
403: */
404: static void Opt_ShowOption(const opt_t *opt, unsigned int maxlen)
1.1 root 405: {
406: char buf[64];
1.1.1.2 root 407: if (!maxlen)
408: {
409: maxlen = Opt_OptionLen(opt);
410: }
411: assert(maxlen < sizeof(buf));
412: if (opt->arg)
413: {
414: sprintf(buf, "%s %s", opt->str, opt->arg);
415: printf(" %-*s %s\n", maxlen, buf, opt->desc);
416: if (opt->chr)
417: {
418: printf(" or %s %s\n", opt->chr, opt->arg);
419: }
420: }
421: else
422: {
423: if (opt->chr)
424: {
425: sprintf(buf, "%s or %s", opt->str, opt->chr);
426: printf(" %-*s %s\n", maxlen, buf, opt->desc);
1.1 root 427: }
1.1.1.2 root 428: else
429: {
430: printf(" %-*s %s\n", maxlen, opt->str, opt->desc);
431: }
432: }
433: }
434:
435: /**
436: * Show options for section starting from 'start_opt',
437: * return next option after this section.
438: */
439: static const opt_t *Opt_ShowHelpSection(const opt_t *start_opt)
440: {
441: const opt_t *opt, *last;
442: unsigned int len, maxlen = 0;
1.1.1.4 root 443: const char *previous = NULL;
1.1.1.2 root 444:
445: /* find longest option name and check option IDs */
1.1.1.4 root 446: for (opt = start_opt; opt->id != OPT_HEADER && opt->id != OPT_ERROR; opt++)
1.1.1.2 root 447: {
448: len = Opt_OptionLen(opt);
449: if (len > maxlen)
450: {
1.1 root 451: maxlen = len;
452: }
453: }
1.1.1.2 root 454: last = opt;
1.1 root 455:
456: /* output all options */
1.1.1.2 root 457: for (opt = start_opt; opt != last; opt++)
458: {
1.1.1.4 root 459: if (previous != opt->str)
460: {
461: Opt_ShowOption(opt, maxlen);
462: }
463: previous = opt->str;
1.1.1.2 root 464: }
465: return last;
466: }
467:
468:
469: /**
470: * Show help text.
471: */
472: static void Opt_ShowHelp(void)
473: {
474: const opt_t *opt = HatariOptions;
475:
476: Opt_ShowVersion();
1.1.1.8 ! root 477: printf("Usage:\n hatari [options] [directory|disk image|Atari program]\n");
1.1.1.2 root 478:
1.1.1.4 root 479: while(opt->id != OPT_ERROR)
1.1.1.2 root 480: {
481: if (opt->id == OPT_HEADER)
482: {
483: assert(opt->desc);
484: printf("\n%s options:\n", opt->desc);
485: opt++;
1.1 root 486: }
1.1.1.2 root 487: opt = Opt_ShowHelpSection(opt);
1.1 root 488: }
1.1.1.2 root 489: printf("\nSpecial option values:\n");
490: printf("<bool>\tDisable by using 'n', 'no', 'off', 'false', or '0'\n");
491: printf("\tEnable by using 'y', 'yes', 'on', 'true' or '1'\n");
492: printf("<file>\tDevices accept also special 'stdout' and 'stderr' file names\n");
493: printf("\t(if you use stdout for midi or printer, set log to stderr).\n");
494: printf("\tSetting the file to 'none', disables given device or disk\n");
495: }
496:
497:
498: /**
1.1.1.4 root 499: * Show Hatari version and usage.
1.1.1.2 root 500: * If 'error' given, show that error message.
1.1.1.4 root 501: * If 'optid' != OPT_ERROR, tells for which option the error is,
1.1.1.2 root 502: * otherwise 'value' is show as the option user gave.
1.1.1.6 root 503: * Return false if error string was given, otherwise true
1.1.1.2 root 504: */
1.1.1.4 root 505: static bool Opt_ShowError(unsigned int optid, const char *value, const char *error)
1.1.1.2 root 506: {
507: const opt_t *opt;
508:
509: Opt_ShowVersion();
510: printf("Usage:\n hatari [options] [disk image name]\n\n"
511: "Try option \"-h\" or \"--help\" to display more information.\n");
512:
513: if (error)
514: {
1.1.1.4 root 515: if (optid == OPT_ERROR)
1.1.1.2 root 516: {
1.1 root 517: fprintf(stderr, "\nError: %s (%s)\n", error, value);
518: }
1.1.1.2 root 519: else
520: {
1.1.1.4 root 521: for (opt = HatariOptions; opt->id != OPT_ERROR; opt++)
1.1.1.2 root 522: {
523: if (optid == opt->id)
524: break;
525: }
526: if (value != NULL)
527: {
1.1.1.6 root 528: fprintf(stderr,
529: "\nError while parsing argument \"%s\" for option \"%s\":\n"
530: " %s\n", value, opt->str, error);
1.1.1.2 root 531: }
532: else
533: {
534: fprintf(stderr, "\nError (%s): %s\n", opt->str, error);
535: }
1.1.1.6 root 536: fprintf(stderr, "\nOption usage:\n");
1.1.1.2 root 537: Opt_ShowOption(opt, 0);
538: }
1.1.1.6 root 539: return false;
1.1 root 540: }
1.1.1.6 root 541: return true;
1.1 root 542: }
543:
1.1.1.2 root 544:
545: /**
1.1.1.4 root 546: * If 'conf' given, set it:
1.1.1.6 root 547: * - true if given option 'arg' is y/yes/on/true/1
548: * - false if given option 'arg' is n/no/off/false/0
549: * Return false for any other value, otherwise true
1.1.1.2 root 550: */
1.1.1.4 root 551: static bool Opt_Bool(const char *arg, int optid, bool *conf)
1.1.1.2 root 552: {
553: const char *enablers[] = { "y", "yes", "on", "true", "1", NULL };
554: const char *disablers[] = { "n", "no", "off", "false", "0", NULL };
555: const char **bool_str, *orig = arg;
556: char *input, *str;
557:
558: input = strdup(arg);
559: str = input;
560: while (*str)
561: {
562: *str++ = tolower(*arg++);
563: }
564: for (bool_str = enablers; *bool_str; bool_str++)
565: {
566: if (strcmp(input, *bool_str) == 0)
567: {
568: free(input);
1.1.1.4 root 569: if (conf)
570: {
1.1.1.6 root 571: *conf = true;
1.1.1.4 root 572: }
1.1.1.6 root 573: return true;
1.1.1.2 root 574: }
575: }
576: for (bool_str = disablers; *bool_str; bool_str++)
577: {
578: if (strcmp(input, *bool_str) == 0)
579: {
580: free(input);
1.1.1.4 root 581: if (conf)
582: {
1.1.1.6 root 583: *conf = false;
1.1.1.4 root 584: }
1.1.1.6 root 585: return true;
1.1.1.2 root 586: }
587: }
588: free(input);
1.1.1.4 root 589: return Opt_ShowError(optid, orig, "Not a <bool> value");
590: }
591:
592:
593: /**
594: * checks str argument agaist options of type "--option<digit>".
595: * If match is found, returns ID for that, otherwise OPT_CONTINUE
596: * and OPT_ERROR for errors.
597: */
598: static int Opt_CheckBracketValue(const opt_t *opt, const char *str)
599: {
600: const char *bracket, *optstr;
601: size_t offset;
602: int digit, i;
603:
604: if (!opt->str)
605: {
606: return OPT_CONTINUE;
607: }
608: bracket = strchr(opt->str, '<');
609: if (!bracket)
610: {
611: return OPT_CONTINUE;
612: }
613: offset = bracket - opt->str;
1.1.1.7 root 614: if (strncmp(opt->str, str, offset) != 0)
1.1.1.4 root 615: {
616: return OPT_CONTINUE;
617: }
618: digit = str[offset] - '0';
619: if (digit < 0 || digit > 9)
620: {
621: return OPT_CONTINUE;
622: }
623: optstr = opt->str;
624: for (i = 0; opt->str == optstr; opt++, i++)
625: {
626: if (i == digit)
627: {
628: return opt->id;
629: }
630: }
631: /* fprintf(stderr, "opt: %s (%d), str: %s (%d), digit: %d\n",
632: opt->str, offset+1, str, strlen(str), digit);
633: */
634: return OPT_ERROR;
1.1.1.2 root 635: }
636:
637:
638: /**
1.1 root 639: * matches string under given index in the argv against all Hatari
640: * short and long options. If match is found, returns ID for that,
1.1.1.4 root 641: * otherwise shows help and returns OPT_ERROR.
1.1 root 642: *
643: * Checks also that if option is supposed to have argument,
644: * whether there's one.
645: */
1.1.1.8 ! root 646: static int Opt_WhichOption(int argc, const char * const argv[], int idx)
1.1 root 647: {
648: const opt_t *opt;
649: const char *str = argv[idx];
1.1.1.4 root 650: int id;
1.1 root 651:
1.1.1.4 root 652: for (opt = HatariOptions; opt->id != OPT_ERROR; opt++)
1.1.1.2 root 653: {
1.1.1.7 root 654: /* exact option name matches? */
655: if (!((opt->str && !strcmp(str, opt->str)) ||
656: (opt->chr && !strcmp(str, opt->chr))))
1.1.1.2 root 657: {
1.1.1.7 root 658: /* no, maybe name<digit> matches? */
659: id = Opt_CheckBracketValue(opt, str);
660: if (id == OPT_CONTINUE)
661: {
662: continue;
663: }
664: if (id == OPT_ERROR)
665: {
666: break;
667: }
668: }
669: /* matched, check args */
670: if (opt->arg)
671: {
672: if (idx+1 >= argc)
673: {
674: Opt_ShowError(opt->id, NULL, "Missing argument");
675: return OPT_ERROR;
676: }
677: /* early check for bools */
678: if (strcmp(opt->arg, "<bool>") == 0)
1.1.1.2 root 679: {
1.1.1.7 root 680: if (!Opt_Bool(argv[idx+1], opt->id, NULL))
1.1.1.2 root 681: {
1.1.1.4 root 682: return OPT_ERROR;
1.1.1.2 root 683: }
1.1 root 684: }
1.1.1.4 root 685: }
1.1.1.7 root 686: return opt->id;
1.1 root 687: }
1.1.1.4 root 688: Opt_ShowError(OPT_ERROR, argv[idx], "Unrecognized option");
689: return OPT_ERROR;
1.1 root 690: }
691:
1.1.1.2 root 692:
693: /**
1.1.1.6 root 694: * If 'checkexits' is true, assume 'src' is a file and check whether it
1.1.1.4 root 695: * exists before copying 'src' to 'dst'. Otherwise just copy option src
696: * string to dst.
1.1.1.6 root 697: * If a pointer to (bool) 'option' is given, set that option to true.
698: * - However, if src is "none", leave dst unmodified & set option to false.
1.1.1.4 root 699: * ("none" is used to disable options related to file arguments)
1.1.1.6 root 700: * Return false if there were errors, otherwise true
1.1.1.2 root 701: */
1.1.1.4 root 702: static bool Opt_StrCpy(int optid, bool checkexist, char *dst, const char *src, size_t dstlen, bool *option)
1.1.1.2 root 703: {
1.1.1.7 root 704: if (option)
705: {
706: *option = false;
707: if(strcasecmp(src, "none") == 0)
708: {
709: return true;
710: }
711: }
1.1.1.4 root 712: if (strlen(src) >= dstlen)
713: {
714: return Opt_ShowError(optid, src, "File name too long!");
715: }
716: if (checkexist && !File_Exists(src))
717: {
718: return Opt_ShowError(optid, src, "Given file doesn't exist (or has wrong file permissions)!");
719: }
1.1.1.2 root 720: if (option)
721: {
1.1.1.7 root 722: *option = true;
1.1.1.2 root 723: }
1.1.1.4 root 724: strcpy(dst, src);
1.1.1.6 root 725: return true;
1.1.1.2 root 726: }
727:
728:
729: /**
1.1.1.7 root 730: * Return SDL_INIT_NOPARACHUTE flag if user requested SDL parachute
731: * to be disabled to get proper Hatari core dumps. By default returns
732: * zero so that SDL parachute will be used to restore video mode on
733: * unclean Hatari termination.
734: */
735: Uint32 Opt_GetNoParachuteFlag(void)
736: {
737: if (bNoSDLParachute) {
738: return SDL_INIT_NOPARACHUTE;
739: }
740: return 0;
741: }
742:
743:
744: /**
1.1.1.8 ! root 745: * Handle last (non-option) argument. It can be a path or filename.
! 746: * Filename can be a disk image or Atari program.
! 747: * Return false if it's none of these.
! 748: */
! 749: static bool Opt_HandleArgument(const char *path)
! 750: {
! 751: char *dir = NULL;
! 752: Uint8 test[2];
! 753: FILE *fp;
! 754:
! 755: /* Atari program? */
! 756: if (File_Exists(path) && (fp = fopen(path, "rb"))) {
! 757:
! 758: /* file starts with GEMDOS magic? */
! 759: if (fread(test, 1, 2, fp) == 2 &&
! 760: test[0] == 0x60 && test[1] == 0x1A) {
! 761:
! 762: const char *prgname = strrchr(path, PATHSEP);
! 763: if (prgname) {
! 764: dir = strdup(path);
! 765: dir[prgname-path] = '\0';
! 766: prgname++;
! 767: } else {
! 768: dir = strdup(Paths_GetWorkingDir());
! 769: prgname = path;
! 770: }
! 771: /* after above, dir should point to valid dir,
! 772: * then make sure that given program from that
! 773: * dir will be started.
! 774: */
! 775: TOS_AutoStart(prgname);
! 776: }
! 777: fclose(fp);
! 778: }
! 779: if (dir) {
! 780: path = dir;
! 781: }
! 782:
! 783: /* GEMDOS HDD directory (as argument, or for the Atari program)? */
! 784: if (File_DirExists(path)) {
! 785: if (Opt_StrCpy(OPT_HARDDRIVE, false, ConfigureParams.HardDisk.szHardDiskDirectories[0],
! 786: path, sizeof(ConfigureParams.HardDisk.szHardDiskDirectories[0]),
! 787: &ConfigureParams.HardDisk.bUseHardDiskDirectories)
! 788: && ConfigureParams.HardDisk.bUseHardDiskDirectories)
! 789: {
! 790: ConfigureParams.HardDisk.bBootFromHardDisk = true;
! 791: }
! 792: bLoadAutoSave = false;
! 793: if (dir) {
! 794: free(dir);
! 795: }
! 796: return true;
! 797: } else {
! 798: if (dir) {
! 799: /* if dir is set, it should be valid... */
! 800: Log_Printf(LOG_ERROR, "Given atari program path '%s' doesn't exist (anymore?)!\n", dir);
! 801: free(dir);
! 802: exit(1);
! 803: }
! 804: }
! 805:
! 806: /* disk image? */
! 807: if (Floppy_SetDiskFileName(0, path, NULL))
! 808: {
! 809: ConfigureParams.HardDisk.bBootFromHardDisk = false;
! 810: bLoadAutoSave = false;
! 811: return true;
! 812: }
! 813:
! 814: return Opt_ShowError(OPT_ERROR, path, "Not a disk image, Atari program or directory");
! 815: }
! 816:
! 817: /**
1.1.1.4 root 818: * parse all Hatari command line options and set Hatari state accordingly.
1.1.1.6 root 819: * Returns true if everything was OK, false otherwise.
1.1.1.2 root 820: */
1.1.1.8 ! root 821: bool Opt_ParseParameters(int argc, const char * const argv[])
1.1 root 822: {
1.1.1.7 root 823: int ncpu, skips, zoom, planes, cpuclock, threshold, memsize, port, freq, temp;
1.1.1.4 root 824: const char *errstr;
1.1.1.6 root 825: int i, ok = true;
1.1.1.7 root 826: int val;
1.1.1.2 root 827:
828: /* Defaults for loading initial memory snap-shots */
1.1.1.6 root 829: bLoadMemorySave = false;
1.1.1.2 root 830: bLoadAutoSave = ConfigureParams.Memory.bAutoSave;
831:
832: for(i = 1; i < argc; i++)
1.1.1.4 root 833: {
1.1.1.8 ! root 834: /* last argument can be a non-option */
! 835: if (argv[i][0] != '-' && i+1 == argc)
! 836: return Opt_HandleArgument(argv[i]);
1.1 root 837:
838: /* WhichOption() checks also that there is an argument,
839: * so we don't need to check that below
840: */
1.1.1.2 root 841: switch(Opt_WhichOption(argc, argv, i))
842: {
843:
844: /* general options */
1.1 root 845: case OPT_HELP:
1.1.1.2 root 846: Opt_ShowHelp();
1.1.1.6 root 847: return false;
1.1 root 848:
849: case OPT_VERSION:
1.1.1.2 root 850: Opt_ShowVersion();
1.1.1.6 root 851: return false;
1.1.1.2 root 852:
853: case OPT_CONFIRMQUIT:
1.1.1.4 root 854: ok = Opt_Bool(argv[++i], OPT_CONFIRMQUIT, &ConfigureParams.Log.bConfirmQuit);
855: break;
856:
857: case OPT_FASTFORWARD:
858: ok = Opt_Bool(argv[++i], OPT_FASTFORWARD, &ConfigureParams.System.bFastForward);
1.1 root 859: break;
860:
1.1.1.2 root 861: case OPT_CONFIGFILE:
862: i += 1;
1.1.1.7 root 863: /* true -> file needs to exist */
1.1.1.6 root 864: ok = Opt_StrCpy(OPT_CONFIGFILE, true, sConfigFileName,
1.1.1.4 root 865: argv[i], sizeof(sConfigFileName), NULL);
866: if (ok)
867: {
868: Configuration_Load(NULL);
869: bLoadAutoSave = ConfigureParams.Memory.bAutoSave;
870: }
1.1.1.2 root 871: break;
872:
1.1.1.8 ! root 873: /* common display options */
1.1 root 874: case OPT_MONO:
1.1.1.4 root 875: ConfigureParams.Screen.nMonitorType = MONITOR_TYPE_MONO;
1.1.1.6 root 876: bLoadAutoSave = false;
1.1.1.2 root 877: break;
878:
879: case OPT_MONITOR:
880: i += 1;
881: if (strcasecmp(argv[i], "mono") == 0)
882: {
1.1.1.4 root 883: ConfigureParams.Screen.nMonitorType = MONITOR_TYPE_MONO;
1.1.1.2 root 884: }
885: else if (strcasecmp(argv[i], "rgb") == 0)
886: {
1.1.1.4 root 887: ConfigureParams.Screen.nMonitorType = MONITOR_TYPE_RGB;
1.1.1.2 root 888: }
889: else if (strcasecmp(argv[i], "vga") == 0)
890: {
1.1.1.4 root 891: ConfigureParams.Screen.nMonitorType = MONITOR_TYPE_VGA;
1.1.1.2 root 892: }
893: else if (strcasecmp(argv[i], "tv") == 0)
894: {
1.1.1.4 root 895: ConfigureParams.Screen.nMonitorType = MONITOR_TYPE_TV;
1.1.1.2 root 896: }
897: else
898: {
1.1.1.4 root 899: return Opt_ShowError(OPT_MONITOR, argv[i], "Unknown monitor type");
1.1.1.2 root 900: }
1.1.1.6 root 901: bLoadAutoSave = false;
1.1 root 902: break;
903:
904: case OPT_FULLSCREEN:
1.1.1.6 root 905: ConfigureParams.Screen.bFullScreen = true;
1.1 root 906: break;
907:
908: case OPT_WINDOW:
1.1.1.6 root 909: ConfigureParams.Screen.bFullScreen = false;
910: break;
911:
912: case OPT_GRAB:
913: bGrabMouse = true;
1.1 root 914: break;
1.1.1.7 root 915:
1.1.1.2 root 916: case OPT_FRAMESKIPS:
917: skips = atoi(argv[++i]);
1.1.1.6 root 918: if (skips < 0)
1.1.1.2 root 919: {
1.1.1.4 root 920: return Opt_ShowError(OPT_FRAMESKIPS, argv[i],
921: "Invalid frame skip value");
1.1.1.2 root 922: }
1.1.1.6 root 923: else if (skips > 8)
924: {
925: Log_Printf(LOG_WARN, "Extravagant frame skip value %d!\n", skips);
926: }
1.1.1.4 root 927: ConfigureParams.Screen.nFrameSkips = skips;
1.1 root 928: break;
929:
1.1.1.4 root 930: case OPT_STATUSBAR:
931: ok = Opt_Bool(argv[++i], OPT_STATUSBAR, &ConfigureParams.Screen.bShowStatusbar);
932: break;
933:
934: case OPT_DRIVE_LED:
935: ok = Opt_Bool(argv[++i], OPT_DRIVE_LED, &ConfigureParams.Screen.bShowDriveLed);
1.1 root 936: break;
937:
1.1.1.2 root 938: case OPT_FORCEBPP:
939: planes = atoi(argv[++i]);
1.1.1.3 root 940: switch(planes)
1.1.1.2 root 941: {
1.1.1.3 root 942: case 32:
943: case 16:
944: case 15:
945: case 8:
946: break; /* supported */
947: case 24:
948: planes = 32; /* We do not support 24 bpp (yet) */
949: break;
950: default:
1.1.1.4 root 951: return Opt_ShowError(OPT_FORCEBPP, argv[i], "Invalid bit depth");
1.1.1.2 root 952: }
953: ConfigureParams.Screen.nForceBpp = planes;
954: break;
1.1.1.8 ! root 955:
! 956: /* ST/STE display options */
! 957: case OPT_BORDERS:
! 958: ok = Opt_Bool(argv[++i], OPT_BORDERS, &ConfigureParams.Screen.bAllowOverscan);
! 959: break;
! 960:
! 961: case OPT_SPEC512:
! 962: threshold = atoi(argv[++i]);
! 963: if (threshold < 0 || threshold > 512)
! 964: {
! 965: return Opt_ShowError(OPT_SPEC512, argv[i],
! 966: "Invalid palette writes per line threshold for Spec512");
! 967: }
! 968: ConfigureParams.Screen.nSpec512Threshold = threshold;
! 969: break;
! 970:
! 971: case OPT_ZOOM:
! 972: zoom = atoi(argv[++i]);
! 973: if (zoom < 1)
! 974: {
! 975: return Opt_ShowError(OPT_ZOOM, argv[i], "Invalid zoom value");
! 976: }
! 977: if (zoom > 1)
! 978: {
! 979: ConfigureParams.Screen.nMaxWidth = 2*(48+320+48);
! 980: ConfigureParams.Screen.nMaxHeight = 2*NUM_VISIBLE_LINES+24;
! 981: }
! 982: else
! 983: {
! 984: ConfigureParams.Screen.nMaxWidth = 320;
! 985: ConfigureParams.Screen.nMaxHeight = 200;
! 986: }
! 987: break;
! 988:
! 989: /* Falcon/TT display options */
! 990: case OPT_RESOLUTION:
! 991: ok = Opt_Bool(argv[++i], OPT_RESOLUTION, &ConfigureParams.Screen.bKeepResolution);
! 992: break;
! 993:
! 994: case OPT_MAXWIDTH:
! 995: ConfigureParams.Screen.nMaxWidth = atoi(argv[++i]);
! 996: break;
! 997:
! 998: case OPT_MAXHEIGHT:
! 999: ConfigureParams.Screen.nMaxHeight = atoi(argv[++i]);
! 1000: break;
! 1001:
! 1002: case OPT_ASPECT:
! 1003: ok = Opt_Bool(argv[++i], OPT_ASPECT, &ConfigureParams.Screen.bAspectCorrect);
! 1004: break;
! 1005:
! 1006: /* screen capture options */
! 1007: case OPT_SCREEN_CROP:
! 1008: ok = Opt_Bool(argv[++i], OPT_SCREEN_CROP, &ConfigureParams.Screen.bCrop);
! 1009: break;
1.1.1.2 root 1010:
1.1.1.7 root 1011: case OPT_AVIRECORD:
1012: AviRecordOnStartup = true;
1013: break;
1014:
1015: case OPT_AVIRECORD_VCODEC:
1016: i += 1;
1017: if (strcasecmp(argv[i], "bmp") == 0)
1018: {
1.1.1.8 ! root 1019: ConfigureParams.Video.AviRecordVcodec = AVI_RECORD_VIDEO_CODEC_BMP;
1.1.1.7 root 1020: }
1021: else if (strcasecmp(argv[i], "png") == 0)
1022: {
1.1.1.8 ! root 1023: ConfigureParams.Video.AviRecordVcodec = AVI_RECORD_VIDEO_CODEC_PNG;
1.1.1.7 root 1024: }
1025: else
1026: {
1027: return Opt_ShowError(OPT_AVIRECORD_VCODEC, argv[i], "Unknown video codec");
1028: }
1029: break;
1030:
1031: case OPT_AVIRECORD_FPS:
1032: val = atoi(argv[++i]);
1033: if (val < 0 || val > 100)
1034: {
1035: return Opt_ShowError(OPT_AVIRECORD_FPS, argv[i],
1036: "Invalid frame rate for avi recording");
1037: }
1.1.1.8 ! root 1038: ConfigureParams.Video.AviRecordFps = val;
1.1.1.7 root 1039: break;
1040:
1041: case OPT_AVIRECORD_FILE:
1042: i += 1;
1043: /* false -> file is created if it doesn't exist */
1.1.1.8 ! root 1044: ok = Opt_StrCpy(OPT_AVIRECORD_FILE, false, ConfigureParams.Video.AviRecordFile,
! 1045: argv[i], sizeof(ConfigureParams.Video.AviRecordFile), NULL);
1.1.1.7 root 1046: break;
1047:
1.1.1.4 root 1048: /* VDI options */
1049: case OPT_VDI:
1050: ok = Opt_Bool(argv[++i], OPT_VDI, &ConfigureParams.Screen.bUseExtVdiResolutions);
1051: if (ok)
1052: {
1.1.1.6 root 1053: bLoadAutoSave = false;
1.1.1.4 root 1054: }
1055: break;
1056:
1.1.1.2 root 1057: case OPT_VDI_PLANES:
1058: planes = atoi(argv[++i]);
1059: switch(planes)
1060: {
1061: case 1:
1062: ConfigureParams.Screen.nVdiColors = GEMCOLOR_2;
1063: break;
1064: case 2:
1065: ConfigureParams.Screen.nVdiColors = GEMCOLOR_4;
1066: break;
1067: case 4:
1068: ConfigureParams.Screen.nVdiColors = GEMCOLOR_16;
1069: break;
1070: default:
1.1.1.4 root 1071: return Opt_ShowError(OPT_VDI_PLANES, argv[i], "Unsupported VDI bit-depth");
1.1.1.2 root 1072: }
1.1.1.6 root 1073: ConfigureParams.Screen.bUseExtVdiResolutions = true;
1074: bLoadAutoSave = false;
1.1.1.2 root 1075: break;
1076:
1077: case OPT_VDI_WIDTH:
1078: ConfigureParams.Screen.nVdiWidth = atoi(argv[++i]);
1.1.1.6 root 1079: ConfigureParams.Screen.bUseExtVdiResolutions = true;
1080: bLoadAutoSave = false;
1.1.1.2 root 1081: break;
1082:
1083: case OPT_VDI_HEIGHT:
1084: ConfigureParams.Screen.nVdiHeight = atoi(argv[++i]);
1.1.1.6 root 1085: ConfigureParams.Screen.bUseExtVdiResolutions = true;
1086: bLoadAutoSave = false;
1.1.1.2 root 1087: break;
1.1.1.7 root 1088:
1.1.1.2 root 1089: /* devices options */
1090: case OPT_JOYSTICK:
1091: i++;
1092: if (strlen(argv[i]) != 1 ||
1093: !Joy_SetCursorEmulation(argv[i][0] - '0'))
1094: {
1.1.1.4 root 1095: return Opt_ShowError(OPT_JOYSTICK, argv[i], "Invalid joystick port");
1096: }
1097: break;
1098:
1099: case OPT_JOYSTICK0:
1100: case OPT_JOYSTICK1:
1101: case OPT_JOYSTICK2:
1102: case OPT_JOYSTICK3:
1103: case OPT_JOYSTICK4:
1104: case OPT_JOYSTICK5:
1105: port = argv[i][strlen(argv[i])-1] - '0';
1106: assert(port >= 0 && port < JOYSTICK_COUNT);
1107: i += 1;
1108: if (strcasecmp(argv[i], "none") == 0)
1109: {
1110: ConfigureParams.Joysticks.Joy[port].nJoystickMode = JOYSTICK_DISABLED;
1111: }
1112: else if (strcasecmp(argv[i], "keys") == 0)
1113: {
1114: ConfigureParams.Joysticks.Joy[port].nJoystickMode = JOYSTICK_KEYBOARD;
1115: }
1116: else if (strcasecmp(argv[i], "real") == 0)
1117: {
1118: ConfigureParams.Joysticks.Joy[port].nJoystickMode = JOYSTICK_REALSTICK;
1119: }
1120: else
1121: {
1122: return Opt_ShowError(OPT_JOYSTICK0+port, argv[i], "Invalid joystick type");
1.1.1.2 root 1123: }
1.1 root 1124: break;
1125:
1126: case OPT_PRINTER:
1.1.1.2 root 1127: i += 1;
1.1.1.7 root 1128: /* "none" can be used to disable printer */
1.1.1.6 root 1129: ok = Opt_StrCpy(OPT_PRINTER, false, ConfigureParams.Printer.szPrintToFileName,
1.1.1.4 root 1130: argv[i], sizeof(ConfigureParams.Printer.szPrintToFileName),
1131: &ConfigureParams.Printer.bEnablePrinting);
1.1 root 1132: break;
1133:
1.1.1.5 root 1134: case OPT_MIDI_IN:
1135: i += 1;
1.1.1.7 root 1136: ok = Opt_StrCpy(OPT_MIDI_IN, true, ConfigureParams.Midi.sMidiInFileName,
1.1.1.5 root 1137: argv[i], sizeof(ConfigureParams.Midi.sMidiInFileName),
1138: &ConfigureParams.Midi.bEnableMidi);
1139: break;
1140:
1141: case OPT_MIDI_OUT:
1.1 root 1142: i += 1;
1.1.1.7 root 1143: ok = Opt_StrCpy(OPT_MIDI_OUT, false, ConfigureParams.Midi.sMidiOutFileName,
1.1.1.5 root 1144: argv[i], sizeof(ConfigureParams.Midi.sMidiOutFileName),
1.1.1.4 root 1145: &ConfigureParams.Midi.bEnableMidi);
1.1 root 1146: break;
1147:
1.1.1.5 root 1148: case OPT_RS232_IN:
1.1 root 1149: i += 1;
1.1.1.6 root 1150: ok = Opt_StrCpy(OPT_RS232_IN, true, ConfigureParams.RS232.szInFileName,
1.1.1.4 root 1151: argv[i], sizeof(ConfigureParams.RS232.szInFileName),
1152: &ConfigureParams.RS232.bEnableRS232);
1.1.1.5 root 1153: break;
1154:
1155: case OPT_RS232_OUT:
1156: i += 1;
1.1.1.7 root 1157: ok = Opt_StrCpy(OPT_RS232_OUT, false, ConfigureParams.RS232.szOutFileName,
1.1.1.5 root 1158: argv[i], sizeof(ConfigureParams.RS232.szOutFileName),
1159: &ConfigureParams.RS232.bEnableRS232);
1.1 root 1160: break;
1.1.1.2 root 1161:
1162: /* disk options */
1.1.1.4 root 1163: case OPT_DISKA:
1164: i += 1;
1165: if (Floppy_SetDiskFileName(0, argv[i], NULL))
1166: {
1.1.1.6 root 1167: ConfigureParams.HardDisk.bBootFromHardDisk = false;
1168: bLoadAutoSave = false;
1.1.1.4 root 1169: }
1170: else
1171: return Opt_ShowError(OPT_ERROR, argv[i], "Not a disk image");
1172: break;
1173:
1174: case OPT_DISKB:
1175: i += 1;
1176: if (Floppy_SetDiskFileName(1, argv[i], NULL))
1.1.1.6 root 1177: bLoadAutoSave = false;
1.1.1.4 root 1178: else
1179: return Opt_ShowError(OPT_ERROR, argv[i], "Not a disk image");
1180: break;
1181:
1.1.1.7 root 1182: case OPT_SLOWFLOPPY:
1183: ok = Opt_Bool(argv[++i], OPT_SLOWFLOPPY, &ConfigureParams.DiskImage.bSlowFloppy);
1184: break;
1185:
1186: case OPT_WRITEPROT_FLOPPY:
1187: i += 1;
1188: if (strcasecmp(argv[i], "off") == 0)
1189: ConfigureParams.DiskImage.nWriteProtection = WRITEPROT_OFF;
1190: else if (strcasecmp(argv[i], "on") == 0)
1191: ConfigureParams.DiskImage.nWriteProtection = WRITEPROT_ON;
1192: else if (strcasecmp(argv[i], "auto") == 0)
1193: ConfigureParams.DiskImage.nWriteProtection = WRITEPROT_AUTO;
1194: else
1195: return Opt_ShowError(OPT_WRITEPROT_FLOPPY, argv[i], "Unknown option value");
1196: break;
1197:
1198: case OPT_WRITEPROT_HD:
1199: i += 1;
1200: if (strcasecmp(argv[i], "off") == 0)
1201: ConfigureParams.HardDisk.nWriteProtection = WRITEPROT_OFF;
1202: else if (strcasecmp(argv[i], "on") == 0)
1203: ConfigureParams.HardDisk.nWriteProtection = WRITEPROT_ON;
1204: else if (strcasecmp(argv[i], "auto") == 0)
1205: ConfigureParams.HardDisk.nWriteProtection = WRITEPROT_AUTO;
1206: else
1207: return Opt_ShowError(OPT_WRITEPROT_HD, argv[i], "Unknown option value");
1208: break;
1209:
1.1 root 1210: case OPT_HARDDRIVE:
1211: i += 1;
1.1.1.6 root 1212: ok = Opt_StrCpy(OPT_HARDDRIVE, false, ConfigureParams.HardDisk.szHardDiskDirectories[0],
1.1.1.4 root 1213: argv[i], sizeof(ConfigureParams.HardDisk.szHardDiskDirectories[0]),
1214: &ConfigureParams.HardDisk.bUseHardDiskDirectories);
1215: if (ok && ConfigureParams.HardDisk.bUseHardDiskDirectories)
1.1.1.2 root 1216: {
1.1.1.6 root 1217: ConfigureParams.HardDisk.bBootFromHardDisk = true;
1.1 root 1218: }
1.1.1.6 root 1219: bLoadAutoSave = false;
1.1.1.2 root 1220: break;
1221:
1222: case OPT_ACSIHDIMAGE:
1223: i += 1;
1.1.1.6 root 1224: ok = Opt_StrCpy(OPT_ACSIHDIMAGE, true, ConfigureParams.HardDisk.szHardDiskImage,
1.1.1.4 root 1225: argv[i], sizeof(ConfigureParams.HardDisk.szHardDiskImage),
1226: &ConfigureParams.HardDisk.bUseHardDiskImage);
1227: if (ok)
1228: {
1.1.1.6 root 1229: bLoadAutoSave = false;
1.1.1.4 root 1230: }
1.1 root 1231: break;
1232:
1.1.1.7 root 1233: case OPT_IDEMASTERHDIMAGE:
1.1 root 1234: i += 1;
1.1.1.7 root 1235: ok = Opt_StrCpy(OPT_IDEMASTERHDIMAGE, true, ConfigureParams.HardDisk.szIdeMasterHardDiskImage,
1236: argv[i], sizeof(ConfigureParams.HardDisk.szIdeMasterHardDiskImage),
1237: &ConfigureParams.HardDisk.bUseIdeMasterHardDiskImage);
1.1.1.4 root 1238: if (ok)
1239: {
1.1.1.6 root 1240: bLoadAutoSave = false;
1.1.1.4 root 1241: }
1.1.1.2 root 1242: break;
1.1.1.6 root 1243:
1.1.1.7 root 1244: case OPT_IDESLAVEHDIMAGE:
1245: i += 1;
1246: ok = Opt_StrCpy(OPT_IDESLAVEHDIMAGE, true, ConfigureParams.HardDisk.szIdeSlaveHardDiskImage,
1247: argv[i], sizeof(ConfigureParams.HardDisk.szIdeSlaveHardDiskImage),
1248: &ConfigureParams.HardDisk.bUseIdeSlaveHardDiskImage);
1249: if (ok)
1250: {
1251: bLoadAutoSave = false;
1252: }
1.1.1.2 root 1253: break;
1254:
1255: /* Memory options */
1256: case OPT_MEMSIZE:
1.1.1.4 root 1257: memsize = atoi(argv[++i]);
1258: if (memsize < 0 || memsize > 14)
1.1.1.2 root 1259: {
1.1.1.4 root 1260: return Opt_ShowError(OPT_MEMSIZE, argv[i], "Invalid memory size");
1.1 root 1261: }
1.1.1.4 root 1262: ConfigureParams.Memory.nMemorySize = memsize;
1.1.1.6 root 1263: bLoadAutoSave = false;
1.1 root 1264: break;
1265:
1.1.1.2 root 1266: case OPT_TOS:
1267: i += 1;
1.1.1.6 root 1268: ok = Opt_StrCpy(OPT_TOS, true, ConfigureParams.Rom.szTosImageFileName,
1.1.1.4 root 1269: argv[i], sizeof(ConfigureParams.Rom.szTosImageFileName),
1270: NULL);
1271: if (ok)
1272: {
1.1.1.6 root 1273: bLoadAutoSave = false;
1.1.1.4 root 1274: }
1.1.1.2 root 1275: break;
1276:
1.1 root 1277: case OPT_CARTRIDGE:
1278: i += 1;
1.1.1.6 root 1279: ok = Opt_StrCpy(OPT_CARTRIDGE, true, ConfigureParams.Rom.szCartridgeImageFileName,
1.1.1.4 root 1280: argv[i], sizeof(ConfigureParams.Rom.szCartridgeImageFileName),
1281: NULL);
1282: if (ok)
1283: {
1.1.1.6 root 1284: bLoadAutoSave = false;
1.1.1.4 root 1285: }
1.1.1.2 root 1286: break;
1287:
1288: case OPT_MEMSTATE:
1289: i += 1;
1.1.1.6 root 1290: ok = Opt_StrCpy(OPT_MEMSTATE, true, ConfigureParams.Memory.szMemoryCaptureFileName,
1.1.1.4 root 1291: argv[i], sizeof(ConfigureParams.Memory.szMemoryCaptureFileName),
1292: NULL);
1293: if (ok)
1294: {
1.1.1.6 root 1295: bLoadMemorySave = true;
1296: bLoadAutoSave = false;
1.1.1.4 root 1297: }
1.1 root 1298: break;
1299:
1.1.1.2 root 1300: /* CPU options */
1.1 root 1301: case OPT_CPULEVEL:
1302: /* UAE core uses cpu_level variable */
1.1.1.2 root 1303: ncpu = atoi(argv[++i]);
1304: if(ncpu < 0 || ncpu > 4)
1305: {
1.1.1.4 root 1306: return Opt_ShowError(OPT_CPULEVEL, argv[i], "Invalid CPU level");
1.1.1.2 root 1307: }
1308: ConfigureParams.System.nCpuLevel = ncpu;
1.1.1.6 root 1309: bLoadAutoSave = false;
1.1.1.2 root 1310: break;
1311:
1312: case OPT_CPUCLOCK:
1313: cpuclock = atoi(argv[++i]);
1314: if(cpuclock != 8 && cpuclock != 16 && cpuclock != 32)
1315: {
1.1.1.4 root 1316: return Opt_ShowError(OPT_CPUCLOCK, argv[i], "Invalid CPU clock");
1.1 root 1317: }
1.1.1.2 root 1318: ConfigureParams.System.nCpuFreq = cpuclock;
1.1.1.6 root 1319: bLoadAutoSave = false;
1.1 root 1320: break;
1321:
1322: case OPT_COMPATIBLE:
1.1.1.4 root 1323: ok = Opt_Bool(argv[++i], OPT_COMPATIBLE, &ConfigureParams.System.bCompatibleCpu);
1324: if (ok)
1325: {
1.1.1.6 root 1326: bLoadAutoSave = false;
1.1.1.4 root 1327: }
1.1 root 1328: break;
1.1.1.2 root 1329:
1330: /* system options */
1331: case OPT_MACHINE:
1332: i += 1;
1333: if (strcasecmp(argv[i], "st") == 0)
1334: {
1335: ConfigureParams.System.nMachineType = MACHINE_ST;
1336: ConfigureParams.System.nCpuLevel = 0;
1337: ConfigureParams.System.nCpuFreq = 8;
1338: }
1339: else if (strcasecmp(argv[i], "ste") == 0)
1340: {
1341: ConfigureParams.System.nMachineType = MACHINE_STE;
1342: ConfigureParams.System.nCpuLevel = 0;
1343: ConfigureParams.System.nCpuFreq = 8;
1344: }
1345: else if (strcasecmp(argv[i], "tt") == 0)
1346: {
1347: ConfigureParams.System.nMachineType = MACHINE_TT;
1348: ConfigureParams.System.nCpuLevel = 3;
1349: ConfigureParams.System.nCpuFreq = 32;
1350: }
1351: else if (strcasecmp(argv[i], "falcon") == 0)
1352: {
1.1.1.8 ! root 1353: #if ENABLE_DSP_EMU
! 1354: ConfigureParams.System.nDSPType = DSP_TYPE_EMU;
! 1355: #endif
1.1.1.2 root 1356: ConfigureParams.System.nMachineType = MACHINE_FALCON;
1357: ConfigureParams.System.nCpuLevel = 3;
1358: ConfigureParams.System.nCpuFreq = 16;
1359: }
1360: else
1361: {
1.1.1.4 root 1362: return Opt_ShowError(OPT_MACHINE, argv[i], "Unknown machine type");
1.1.1.2 root 1363: }
1.1.1.6 root 1364: bLoadAutoSave = false;
1.1 root 1365: break;
1366:
1.1.1.2 root 1367: case OPT_BLITTER:
1.1.1.4 root 1368: ok = Opt_Bool(argv[++i], OPT_BLITTER, &ConfigureParams.System.bBlitter);
1369: if (ok)
1370: {
1.1.1.6 root 1371: bLoadAutoSave = false;
1.1.1.4 root 1372: }
1.1.1.2 root 1373: break;
1.1.1.6 root 1374:
1375: case OPT_TIMERD:
1376: ok = Opt_Bool(argv[++i], OPT_TIMERD, &ConfigureParams.System.bPatchTimerD);
1377: break;
1.1.1.8 ! root 1378:
! 1379: case OPT_RTC:
! 1380: ok = Opt_Bool(argv[++i], OPT_RTC, &ConfigureParams.System.bRealTimeClock);
! 1381: break;
1.1.1.2 root 1382:
1383: case OPT_DSP:
1384: i += 1;
1385: if (strcasecmp(argv[i], "none") == 0)
1386: {
1387: ConfigureParams.System.nDSPType = DSP_TYPE_NONE;
1388: }
1389: else if (strcasecmp(argv[i], "dummy") == 0)
1390: {
1391: ConfigureParams.System.nDSPType = DSP_TYPE_DUMMY;
1392: }
1393: else if (strcasecmp(argv[i], "emu") == 0)
1394: {
1395: #if ENABLE_DSP_EMU
1396: ConfigureParams.System.nDSPType = DSP_TYPE_EMU;
1397: #else
1.1.1.4 root 1398: return Opt_ShowError(OPT_DSP, argv[i], "DSP type 'emu' support not compiled in");
1.1.1.2 root 1399: #endif
1400: }
1401: else
1402: {
1.1.1.4 root 1403: return Opt_ShowError(OPT_DSP, argv[i], "Unknown DSP type");
1.1 root 1404: }
1.1.1.6 root 1405: bLoadAutoSave = false;
1.1 root 1406: break;
1.1.1.8 ! root 1407:
! 1408: #if ENABLE_WINUAE_CPU
! 1409: case OPT_CPU_ADDR24:
! 1410: ok = Opt_Bool(argv[++i], OPT_CPU_ADDR24, &ConfigureParams.System.bAddressSpace24);
! 1411: bLoadAutoSave = false;
! 1412: break;
! 1413:
! 1414: case OPT_CPU_CYCLE_EXACT:
! 1415: ok = Opt_Bool(argv[++i], OPT_CPU_CYCLE_EXACT, &ConfigureParams.System.bCycleExactCpu);
! 1416: bLoadAutoSave = false;
! 1417: break;
! 1418:
! 1419: case OPT_FPU_TYPE:
! 1420: i += 1;
! 1421: if (strcasecmp(argv[i], "none") == 0)
! 1422: {
! 1423: ConfigureParams.System.n_FPUType = FPU_NONE;
! 1424: }
! 1425: else if (strcasecmp(argv[i], "68881") == 0)
! 1426: {
! 1427: ConfigureParams.System.n_FPUType = FPU_68881;
! 1428: }
! 1429: else if (strcasecmp(argv[i], "68882") == 0)
! 1430: {
! 1431: ConfigureParams.System.n_FPUType = FPU_68882;
! 1432: }
! 1433: else if (strcasecmp(argv[i], "internal") == 0)
! 1434: {
! 1435: ConfigureParams.System.n_FPUType = FPU_CPU;
! 1436: }
! 1437: else
! 1438: {
! 1439: return Opt_ShowError(OPT_FPU_TYPE, argv[i], "Unknown FPU type");
! 1440: }
! 1441: bLoadAutoSave = false;
! 1442: break;
! 1443:
! 1444: case OPT_FPU_COMPATIBLE:
! 1445: ok = Opt_Bool(argv[++i], OPT_FPU_COMPATIBLE, &ConfigureParams.System.bCompatibleFPU);
! 1446: break;
! 1447:
! 1448: case OPT_MMU:
! 1449: ok = Opt_Bool(argv[++i], OPT_MMU, &ConfigureParams.System.bMMU);
! 1450: bLoadAutoSave = false;
! 1451: break;
! 1452: #endif
! 1453: case OPT_YM_MIXING:
! 1454: i += 1;
! 1455: if (strcasecmp(argv[i], "linear") == 0)
! 1456: {
! 1457: ConfigureParams.Sound.YmVolumeMixing = YM_LINEAR_MIXING;
! 1458: }
! 1459: else if (strcasecmp(argv[i], "table") == 0)
! 1460: {
! 1461: ConfigureParams.Sound.YmVolumeMixing = YM_TABLE_MIXING;
! 1462: }
! 1463: else
! 1464: {
! 1465: return Opt_ShowError(OPT_YM_MIXING, argv[i], "Unknown YM mixing method");
! 1466: }
! 1467: break;
! 1468:
1.1.1.2 root 1469: case OPT_SOUND:
1.1 root 1470: i += 1;
1.1.1.2 root 1471: if (strcasecmp(argv[i], "off") == 0)
1472: {
1.1.1.6 root 1473: ConfigureParams.Sound.bEnableSound = false;
1.1.1.2 root 1474: }
1475: else
1476: {
1.1.1.6 root 1477: freq = atoi(argv[i]);
1478: if (freq < 6000 || freq > 50066)
1479: {
1480: return Opt_ShowError(OPT_SOUND, argv[i], "Unsupported sound frequency");
1481: }
1482: ConfigureParams.Sound.nPlaybackFreq = freq;
1483: ConfigureParams.Sound.bEnableSound = true;
1.1 root 1484: }
1485: break;
1.1.1.2 root 1486:
1.1.1.7 root 1487: case OPT_SOUNDBUFFERSIZE:
1488: i += 1;
1489: temp = atoi(argv[i]);
1490: if ( temp == 0 ) /* use default setting for SDL */
1491: ;
1492: else if (temp < 10 || temp > 100)
1493: {
1494: return Opt_ShowError(OPT_SOUNDBUFFERSIZE, argv[i], "Unsupported sound buffer size");
1495: }
1496: ConfigureParams.Sound.SdlAudioBufferSize = temp;
1497: break;
1.1.1.8 ! root 1498:
! 1499: case OPT_MICROPHONE:
! 1500: ok = Opt_Bool(argv[++i], OPT_MICROPHONE, &ConfigureParams.Sound.bEnableMicrophone);
! 1501: break;
1.1.1.7 root 1502:
1.1 root 1503: case OPT_KEYMAPFILE:
1504: i += 1;
1.1.1.6 root 1505: ok = Opt_StrCpy(OPT_KEYMAPFILE, true, ConfigureParams.Keyboard.szMappingFileName,
1.1.1.4 root 1506: argv[i], sizeof(ConfigureParams.Keyboard.szMappingFileName),
1507: NULL);
1508: if (ok)
1509: {
1510: ConfigureParams.Keyboard.nKeymapType = KEYMAP_LOADED;
1511: }
1.1 root 1512: break;
1513:
1.1.1.2 root 1514: /* debug options */
1515: case OPT_DEBUG:
1.1.1.6 root 1516: if (bExceptionDebugging)
1.1.1.4 root 1517: {
1.1.1.6 root 1518: fprintf(stderr, "Exception debugging disabled.\n");
1519: bExceptionDebugging = false;
1.1.1.4 root 1520: }
1521: else
1522: {
1.1.1.6 root 1523: fprintf(stderr, "Exception debugging enabled.\n");
1524: bExceptionDebugging = true;
1.1.1.4 root 1525: }
1.1.1.2 root 1526: break;
1.1.1.4 root 1527:
1.1.1.8 ! root 1528: case OPT_BIOSINTERCEPT:
! 1529: if (bBiosIntercept)
! 1530: {
! 1531: fprintf(stderr, "X/Bios interception disabled.\n");
! 1532: bBiosIntercept = false;
! 1533: }
! 1534: else
! 1535: {
! 1536: fprintf(stderr, "X/Bios interception enabled.\n");
! 1537: bBiosIntercept = true;
! 1538: }
1.1.1.7 root 1539: break;
1540:
1.1.1.8 ! root 1541: case OPT_PARACHUTE:
! 1542: bNoSDLParachute = true;
1.1 root 1543: break;
1544:
1.1.1.2 root 1545: case OPT_TRACE:
1546: i += 1;
1.1.1.6 root 1547: errstr = Log_SetTraceOptions(argv[i]);
1548: if (errstr)
1.1.1.4 root 1549: {
1.1.1.7 root 1550: if (!errstr[0]) {
1551: /* silent parsing termination */
1552: return false;
1553: }
1.1.1.6 root 1554: return Opt_ShowError(OPT_TRACE, argv[i], errstr);
1.1.1.4 root 1555: }
1556: break;
1557:
1558: case OPT_TRACEFILE:
1559: i += 1;
1.1.1.6 root 1560: ok = Opt_StrCpy(OPT_TRACEFILE, false, ConfigureParams.Log.sTraceFileName,
1.1.1.4 root 1561: argv[i], sizeof(ConfigureParams.Log.sTraceFileName),
1562: NULL);
1563: break;
1564:
1565: case OPT_CONTROLSOCKET:
1566: i += 1;
1567: errstr = Control_SetSocket(argv[i]);
1568: if (errstr)
1.1.1.2 root 1569: {
1.1.1.4 root 1570: return Opt_ShowError(OPT_CONTROLSOCKET, argv[i], errstr);
1.1.1.2 root 1571: }
1572: break;
1573:
1.1.1.4 root 1574: case OPT_LOGFILE:
1575: i += 1;
1.1.1.6 root 1576: ok = Opt_StrCpy(OPT_LOGFILE, false, ConfigureParams.Log.sLogFileName,
1.1.1.4 root 1577: argv[i], sizeof(ConfigureParams.Log.sLogFileName),
1578: NULL);
1579: break;
1580:
1.1.1.7 root 1581: case OPT_PARSE:
1582: i += 1;
1583: ok = DebugUI_SetParseFile(argv[i]);
1584: break;
1585:
1586: case OPT_SAVECONFIG:
1587: /* Hatari-UI needs Hatari config to start */
1588: Configuration_Save();
1589: exit(0);
1590: break;
1591:
1.1.1.4 root 1592: case OPT_LOGLEVEL:
1593: i += 1;
1594: ConfigureParams.Log.nTextLogLevel = Log_ParseOptions(argv[i]);
1595: if (ConfigureParams.Log.nTextLogLevel == LOG_NONE)
1596: {
1597: return Opt_ShowError(OPT_LOGLEVEL, argv[i], "Unknown log level!");
1598: }
1599: break;
1600:
1601: case OPT_ALERTLEVEL:
1602: i += 1;
1603: ConfigureParams.Log.nAlertDlgLogLevel = Log_ParseOptions(argv[i]);
1604: if (ConfigureParams.Log.nAlertDlgLogLevel == LOG_NONE)
1605: {
1606: return Opt_ShowError(OPT_ALERTLEVEL, argv[i], "Unknown alert level!");
1607: }
1608: break;
1.1.1.6 root 1609:
1610: case OPT_RUNVBLS:
1.1.1.8 ! root 1611: Main_SetRunVBLs(atol(argv[++i]));
1.1.1.6 root 1612: break;
1.1.1.4 root 1613:
1614: case OPT_ERROR:
1615: /* unknown option or missing option parameter */
1.1.1.6 root 1616: return false;
1.1.1.4 root 1617:
1.1 root 1618: default:
1.1.1.4 root 1619: return Opt_ShowError(OPT_ERROR, argv[i], "Internal Hatari error, unhandled option");
1620: }
1621: if (!ok)
1622: {
1623: /* Opt_Bool() or Opt_StrCpy() failed */
1.1.1.6 root 1624: return false;
1.1 root 1625: }
1626: }
1.1.1.4 root 1627:
1.1.1.6 root 1628: return true;
1.1 root 1629: }
1.1.1.7 root 1630:
1631: /**
1632: * Readline match callback for option name completion.
1633: * STATE = 0 -> different text from previous one.
1634: * Return next match or NULL if no matches.
1635: */
1636: char *Opt_MatchOption(const char *text, int state)
1637: {
1638: static int i, len;
1639: const char *name;
1640:
1641: if (!state) {
1642: /* first match */
1643: len = strlen(text);
1644: i = 0;
1645: }
1646: /* next match */
1647: while (i < ARRAYSIZE(HatariOptions)) {
1648: name = HatariOptions[i++].str;
1649: if (name && strncasecmp(name, text, len) == 0)
1650: return (strdup(name));
1651: }
1652: return NULL;
1653: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.