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