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