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