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