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

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

unix.superglobalmegacorp.com

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