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