Annotation of hatari/src/options.c, revision 1.1.1.13

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.