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

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()
1.1.1.2   root       13: 
                     14:   2007-09-27   [NP]    Add parsing for the '--trace' option.
                     15:   2008-03-01   [ET]    Add option sections and <bool> support.
1.1.1.4 ! root       16:   2008-04-07   [ET]    Add bios/xbios intercept support
        !            17:   2008-04-16   [ET]    Return FALSE instead of exiting on errors
        !            18:   2008-06-08   [ET]    Add disk image options and refactor their handling
        !            19:   2008-06-10   [ET]    Add --vdi and joystick<port> <type> options
        !            20:   2008-07-30   [ET]    Shorter & more consistent option descriptions
        !            21:   2008-08-19   [ET]    Add --statusbar and --drive-led options
1.1       root       22: */
                     23: 
1.1.1.4 ! root       24: const char Opt_rcsid[] = "Hatari $Id: options.c,v 1.72 2008/09/20 12:01:08 thothy Exp $";
1.1.1.2   root       25: 
                     26: #include <ctype.h>
1.1       root       27: #include <stdio.h>
                     28: #include <stdlib.h>
                     29: #include <string.h>
                     30: #include <assert.h>
                     31: 
                     32: #include "main.h"
                     33: #include "options.h"
                     34: #include "configuration.h"
1.1.1.4 ! root       35: #include "control.h"
1.1       root       36: #include "file.h"
1.1.1.4 ! root       37: #include "floppy.h"
1.1       root       38: #include "screen.h"
                     39: #include "video.h"
                     40: #include "vdi.h"
                     41: #include "joy.h"
1.1.1.4 ! root       42: #include "log.h"
1.1.1.2   root       43: 
                     44: #include "hatari-glue.h"
                     45: 
1.1       root       46: 
1.1.1.4 ! root       47: bool bLoadAutoSave;        /* Load autosave memory snapshot at startup */
        !            48: bool bLoadMemorySave;      /* Load memory snapshot provided via option at startup */
        !            49: bool bBiosIntercept;       /* whether UAE should intercept Bios & XBios calls */
1.1       root       50: 
                     51: 
                     52: /*  List of supported options. */
                     53: enum {
1.1.1.2   root       54:        OPT_HEADER,     /* options section header */
                     55:        OPT_HELP,               /* general options */
1.1       root       56:        OPT_VERSION,
1.1.1.2   root       57:        OPT_CONFIRMQUIT,
                     58:        OPT_CONFIGFILE,
1.1.1.4 ! root       59:        OPT_FASTFORWARD,
1.1.1.2   root       60:        OPT_MONO,               /* display options */
                     61:        OPT_MONITOR,
1.1       root       62:        OPT_FULLSCREEN,
                     63:        OPT_WINDOW,
1.1.1.2   root       64:        OPT_ZOOM,
                     65:        OPT_FRAMESKIPS,
                     66:        OPT_BORDERS,
1.1.1.4 ! root       67:        OPT_STATUSBAR,
        !            68:        OPT_DRIVE_LED,
1.1.1.2   root       69:        OPT_SPEC512,
                     70:        OPT_FORCEBPP,
1.1.1.4 ! root       71:        OPT_VDI,                /* VDI options */
        !            72:        OPT_VDI_PLANES,
1.1.1.2   root       73:        OPT_VDI_WIDTH,
                     74:        OPT_VDI_HEIGHT,
                     75:        OPT_JOYSTICK,           /* device options */
1.1.1.4 ! root       76:        OPT_JOYSTICK0,
        !            77:        OPT_JOYSTICK1,
        !            78:        OPT_JOYSTICK2,
        !            79:        OPT_JOYSTICK3,
        !            80:        OPT_JOYSTICK4,
        !            81:        OPT_JOYSTICK5,
1.1       root       82:        OPT_PRINTER,
                     83:        OPT_MIDI,
                     84:        OPT_RS232,
1.1.1.4 ! root       85:        OPT_DISKA,              /* disk options */
        !            86:        OPT_DISKB,
        !            87:        OPT_HARDDRIVE,
1.1.1.2   root       88:        OPT_ACSIHDIMAGE,
                     89:        OPT_IDEHDIMAGE,
                     90:        OPT_SLOWFDC,
                     91:        OPT_MEMSIZE,            /* memory options */
1.1       root       92:        OPT_TOS,
                     93:        OPT_CARTRIDGE,
1.1.1.2   root       94:        OPT_MEMSTATE,
                     95:        OPT_CPULEVEL,           /* CPU options */
                     96:        OPT_CPUCLOCK,
1.1       root       97:        OPT_COMPATIBLE,
1.1.1.2   root       98:        OPT_MACHINE,            /* system options */
1.1       root       99:        OPT_BLITTER,
1.1.1.2   root      100:        OPT_DSP,
                    101:        OPT_SOUND,
1.1       root      102:        OPT_KEYMAPFILE,
1.1.1.2   root      103:        OPT_DEBUG,              /* debug options */
1.1.1.4 ! root      104:        OPT_BIOSINTERCEPT,
1.1.1.2   root      105:        OPT_TRACE,
1.1.1.4 ! root      106:        OPT_TRACEFILE,
        !           107:        OPT_CONTROLSOCKET,
        !           108:        OPT_LOGFILE,
        !           109:        OPT_LOGLEVEL,
        !           110:        OPT_ALERTLEVEL,
        !           111:        OPT_ERROR,
        !           112:        OPT_CONTINUE
1.1       root      113: };
                    114: 
                    115: typedef struct {
                    116:        unsigned int id;        /* option ID */
                    117:        const char *chr;        /* short option */
                    118:        const char *str;        /* long option */
1.1.1.2   root      119:        const char *arg;        /* type name for argument, if any */
1.1       root      120:        const char *desc;       /* option description */
                    121: } opt_t;
                    122: 
1.1.1.2   root      123: /* it's easier to edit these if they are kept in the same order as the enums */
1.1       root      124: static const opt_t HatariOptions[] = {
1.1.1.2   root      125:        
                    126:        { OPT_HEADER, NULL, NULL, NULL, "General" },
1.1       root      127:        { OPT_HELP,      "-h", "--help",
                    128:          NULL, "Print this help text and exit" },
                    129:        { OPT_VERSION,   "-v", "--version",
1.1.1.2   root      130:          NULL, "Print version number and exit" },
1.1.1.4 ! root      131:        { OPT_CONFIRMQUIT, NULL, "--confirm-quit",
1.1.1.2   root      132:          "<bool>", "Whether Hatari confirms quit" },
1.1.1.4 ! root      133:        { OPT_CONFIGFILE, "-c", "--configfile",
        !           134:          "<file>", "Use <file> instead of the default hatari config file" },
        !           135:        { OPT_FASTFORWARD, NULL, "--fast-forward",
        !           136:          "<bool>", "Help skipping stuff on fast machine" },
        !           137: 
1.1.1.2   root      138:        { OPT_HEADER, NULL, NULL, NULL, "Display" },
1.1       root      139:        { OPT_MONO,      "-m", "--mono",
                    140:          NULL, "Start in monochrome mode instead of color" },
1.1.1.2   root      141:        { OPT_MONITOR,      NULL, "--monitor",
                    142:          "<x>", "Select monitor type (x = mono/rgb/vga/tv)" },
1.1       root      143:        { OPT_FULLSCREEN,"-f", "--fullscreen",
                    144:          NULL, "Start emulator in fullscreen mode" },
                    145:        { OPT_WINDOW,    "-w", "--window",
                    146:          NULL, "Start emulator in window mode" },
1.1.1.2   root      147:        { OPT_ZOOM, "-z", "--zoom",
                    148:          "<x>", "Double ST low resolution (1=no, 2=yes)" },
                    149:        { OPT_FRAMESKIPS, NULL, "--frameskips",
1.1.1.4 ! root      150:          "<x>", "Skip <x> frames after each shown frame (0=off, >4=auto/max)" },
1.1.1.2   root      151:        { OPT_BORDERS, NULL, "--borders",
                    152:          "<bool>", "Show screen borders (for overscan demos etc)" },
1.1.1.4 ! root      153:        { OPT_STATUSBAR, NULL, "--statusbar",
        !           154:          "<bool>", "Show statusbar (floppy leds etc)" },
        !           155:        { OPT_DRIVE_LED,   NULL, "--drive-led",
        !           156:          "<bool>", "Show overlay drive led when statusbar isn't shown" },
1.1.1.2   root      157:        { OPT_SPEC512, NULL, "--spec512",
                    158:          "<x>", "Spec512 palette threshold (0 <= x <= 512, 0=disable)" },
                    159:        { OPT_FORCEBPP, NULL, "--bpp",
1.1.1.4 ! root      160:          "<x>", "Force internal bitdepth (x = 8/15/16/32, 0=disable)" },
1.1.1.2   root      161:        
                    162:        { OPT_HEADER, NULL, NULL, NULL, "VDI" },
1.1.1.4 ! root      163:        { OPT_VDI,      NULL, "--vdi",
        !           164:          "<bool>", "Whether to use VDI screen mode" },
1.1.1.2   root      165:        { OPT_VDI_PLANES,NULL, "--vdi-planes",
1.1.1.4 ! root      166:          "<x>", "VDI mode bit-depth (x = 1/2/4)" },
1.1.1.2   root      167:        { OPT_VDI_WIDTH,     NULL, "--vdi-width",
1.1.1.4 ! root      168:          "<w>", "VDI mode width (320 < w <= 1024)" },
1.1.1.2   root      169:        { OPT_VDI_HEIGHT,     NULL, "--vdi-height",
1.1.1.4 ! root      170:          "<h>", "VDI mode height (200 < h <= 768)" },
1.1.1.2   root      171:        
                    172:        { OPT_HEADER, NULL, NULL, NULL, "Devices" },
1.1       root      173:        { OPT_JOYSTICK,  "-j", "--joystick",
1.1.1.2   root      174:          "<port>", "Emulate joystick with cursor keys in given port (0-5)" },
1.1.1.4 ! root      175:        /* these have to be exactly the same as I'm relying compiler giving
        !           176:         * them the same same string pointer when strings are identical
        !           177:         */
        !           178:        { OPT_JOYSTICK0, NULL, "--joy<port>",
        !           179:          "<type>", "Set joystick type (none/keys/real) for given port" },
        !           180:        { OPT_JOYSTICK1, NULL, "--joy<port>",
        !           181:          "<type>", "Set joystick type (none/keys/real) for given port" },
        !           182:        { OPT_JOYSTICK2, NULL, "--joy<port>",
        !           183:          "<type>", "Set joystick type (none/keys/real) for given port" },
        !           184:        { OPT_JOYSTICK3, NULL, "--joy<port>",
        !           185:          "<type>", "Set joystick type (none/keys/real) for given port" },
        !           186:        { OPT_JOYSTICK4, NULL, "--joy<port>",
        !           187:          "<type>", "Set joystick type (none/keys/real) for given port" },
        !           188:        { OPT_JOYSTICK5, NULL, "--joy<port>",
        !           189:          "<type>", "Set joystick type (none/keys/real) for given port" },
1.1       root      190:        { OPT_PRINTER,   NULL, "--printer",
1.1.1.2   root      191:          "<file>", "Enable printer support and write data to <file>" },
1.1       root      192:        { OPT_MIDI,      NULL, "--midi",
                    193:          "<file>", "Enable midi support and write midi data to <file>" },
                    194:        { OPT_RS232,     NULL, "--rs232",
1.1.1.2   root      195:          "<file>", "Enable serial port support and use <file> as the device" },
                    196:        
                    197:        { OPT_HEADER, NULL, NULL, NULL, "Disk" },
1.1.1.4 ! root      198:        { OPT_DISKA, NULL, "--disk-a",
        !           199:          "<file>", "Set disk image for floppy drive A" },
        !           200:        { OPT_DISKB, NULL, "--disk-b",
        !           201:          "<file>", "Set disk image for floppy drive B" },
1.1       root      202:        { OPT_HARDDRIVE, "-d", "--harddrive",
                    203:          "<dir>", "Emulate an ST harddrive (<dir> = root directory)" },
1.1.1.2   root      204:        { OPT_ACSIHDIMAGE,   NULL, "--acsi",
                    205:          "<file>", "Emulate an ACSI harddrive with an image <file>" },
                    206:        { OPT_IDEHDIMAGE,   NULL, "--ide",
                    207:          "<file>", "Emulate an IDE harddrive using <file> (not working yet)" },
                    208:        { OPT_SLOWFDC,   NULL, "--slowfdc",
                    209:          "<bool>", "Slow down FDC emulation (deprecated)" },
                    210:        
                    211:        { OPT_HEADER, NULL, NULL, NULL, "Memory" },
                    212:        { OPT_MEMSIZE,   "-s", "--memsize",
1.1.1.4 ! root      213:          "<x>", "ST RAM size (x = size in MiB from 0 to 14, 0 = 512KiB)" },
1.1       root      214:        { OPT_TOS,       "-t", "--tos",
                    215:          "<file>", "Use TOS image <file>" },
                    216:        { OPT_CARTRIDGE, NULL, "--cartridge",
                    217:          "<file>", "Use ROM cartridge image <file>" },
1.1.1.2   root      218:        { OPT_MEMSTATE,   NULL, "--memstate",
                    219:          "<file>", "Load memory snap-shot <file>" },
                    220:        
                    221:        { OPT_HEADER, NULL, NULL, NULL, "CPU" },
1.1       root      222:        { OPT_CPULEVEL,  NULL, "--cpulevel",
1.1.1.2   root      223:          "<x>", "Set the CPU type (x => 680x0) (EmuTOS/TOS 2.06 only!)" },
                    224:        { OPT_CPUCLOCK,  NULL, "--cpuclock",
1.1.1.4 ! root      225:          "<x>", "Set the CPU clock (x = 8/16/32)" },
        !           226:        { OPT_COMPATIBLE, NULL, "--compatible",
1.1.1.2   root      227:          "<bool>", "Use a more compatible (but slower) 68000 CPU mode" },
                    228:        
                    229:        { OPT_HEADER, NULL, NULL, NULL, "Misc system" },
                    230:        { OPT_MACHINE,   NULL, "--machine",
                    231:          "<x>", "Select machine type (x = st/ste/tt/falcon)" },
1.1       root      232:        { OPT_BLITTER,   NULL, "--blitter",
1.1.1.2   root      233:          "<bool>", "Use blitter emulation (ST only)" },
                    234:        { OPT_DSP,       NULL, "--dsp",
1.1.1.4 ! root      235:          "<x>", "DSP emulation (x = none/dummy/emu, Falcon only)" },
1.1.1.2   root      236:        { OPT_SOUND,   NULL, "--sound",
1.1.1.4 ! root      237:          "<x>", "Sound quality (x = off/low/med/hi, off=faster)" },
        !           238:        { OPT_KEYMAPFILE, "-k", "--keymap",
1.1       root      239:          "<file>", "Read (additional) keyboard mappings from <file>" },
1.1.1.2   root      240:        
                    241:        { OPT_HEADER, NULL, NULL, NULL, "Debug" },
                    242:        { OPT_DEBUG,     "-D", "--debug",
1.1.1.4 ! root      243:          NULL, "Enable Hatari debugger console interface" },
        !           244:        { OPT_BIOSINTERCEPT, NULL, "--bios-intercept",
        !           245:          NULL, "Enable Bios/XBios interception (experimental)" },
1.1.1.2   root      246:        { OPT_TRACE,   NULL, "--trace",
1.1.1.4 ! root      247:          "<trace1,...>", "Activate emulation tracing, see '--trace help'" },
        !           248:        { OPT_TRACEFILE, NULL, "--trace-file",
        !           249:          "<file>", "Save trace output to <file> (default=stderr)" },
        !           250: #if HAVE_UNIX_DOMAIN_SOCKETS
        !           251:        { OPT_CONTROLSOCKET, NULL, "--control-socket",
        !           252:          "<file>", "Hatari reads options from given socket at run-time" },
        !           253: #endif
        !           254:        { OPT_LOGFILE, NULL, "--log-file",
        !           255:          "<file>", "Save log output to <file> (default=stderr)" },
        !           256:        { OPT_LOGLEVEL, NULL, "--log-level",
        !           257:          "<x>", "Log output level (x=debug/todo/info/warn/error/fatal)" },
        !           258:        { OPT_ALERTLEVEL, NULL, "--alert-level",
        !           259:          "<x>", "Show dialog for log messages above given level" },
        !           260: 
        !           261:        { OPT_ERROR, NULL, NULL, NULL, NULL }
1.1       root      262: };
                    263: 
1.1.1.2   root      264: 
                    265: /**
                    266:  * Show version string and license.
1.1       root      267:  */
1.1.1.2   root      268: static void Opt_ShowVersion(void)
                    269: {
1.1.1.4 ! root      270:        printf("\n" PROG_NAME
        !           271:               " - the Atari ST, STE, TT and Falcon emulator.\n\n");
1.1.1.2   root      272:        printf("Hatari is free software licensed under the GNU General"
                    273:               " Public License.\n\n");
                    274: }
                    275: 
                    276: 
                    277: /**
                    278:  * Calculate option + value len
                    279:  */
                    280: static unsigned int Opt_OptionLen(const opt_t *opt)
                    281: {
                    282:        unsigned int len;
                    283:        len = strlen(opt->str);
                    284:        if (opt->arg)
                    285:        {
                    286:                len += strlen(opt->arg);
                    287:                len += 1;
                    288:                /* with arg, short options go to another line */
                    289:        }
                    290:        else
                    291:        {
                    292:                if (opt->chr)
                    293:                {
                    294:                        /* ' or -c' */
                    295:                        len += 6;
                    296:                }
                    297:        }
                    298:        return len;
                    299: }
                    300: 
                    301: 
                    302: /**
                    303:  * Show single option
                    304:  */
                    305: static void Opt_ShowOption(const opt_t *opt, unsigned int maxlen)
1.1       root      306: {
                    307:        char buf[64];
1.1.1.2   root      308:        if (!maxlen)
                    309:        {
                    310:                maxlen = Opt_OptionLen(opt);
                    311:        }
                    312:        assert(maxlen < sizeof(buf));
                    313:        if (opt->arg)
                    314:        {
                    315:                sprintf(buf, "%s %s", opt->str, opt->arg);
                    316:                printf("  %-*s %s\n", maxlen, buf, opt->desc);
                    317:                if (opt->chr)
                    318:                {
                    319:                        printf("    or %s %s\n", opt->chr, opt->arg);
                    320:                }
                    321:        }
                    322:        else
                    323:        {
                    324:                if (opt->chr)
                    325:                {
                    326:                        sprintf(buf, "%s or %s", opt->str, opt->chr);
                    327:                        printf("  %-*s %s\n", maxlen, buf, opt->desc);
1.1       root      328:                }
1.1.1.2   root      329:                else
                    330:                {
                    331:                        printf("  %-*s %s\n", maxlen, opt->str, opt->desc);
                    332:                }
                    333:        }
                    334: }
                    335: 
                    336: /**
                    337:  * Show options for section starting from 'start_opt',
                    338:  * return next option after this section.
                    339:  */
                    340: static const opt_t *Opt_ShowHelpSection(const opt_t *start_opt)
                    341: {
                    342:        const opt_t *opt, *last;
                    343:        unsigned int len, maxlen = 0;
1.1.1.4 ! root      344:        const char *previous = NULL;
1.1.1.2   root      345: 
                    346:        /* find longest option name and check option IDs */
1.1.1.4 ! root      347:        for (opt = start_opt; opt->id != OPT_HEADER && opt->id != OPT_ERROR; opt++)
1.1.1.2   root      348:        {
                    349:                len = Opt_OptionLen(opt);
                    350:                if (len > maxlen)
                    351:                {
1.1       root      352:                        maxlen = len;
                    353:                }
                    354:        }
1.1.1.2   root      355:        last = opt;
1.1       root      356:        
                    357:        /* output all options */
1.1.1.2   root      358:        for (opt = start_opt; opt != last; opt++)
                    359:        {
1.1.1.4 ! root      360:                if (previous != opt->str)
        !           361:                {
        !           362:                        Opt_ShowOption(opt, maxlen);
        !           363:                }
        !           364:                previous = opt->str;
1.1.1.2   root      365:        }
                    366:        return last;
                    367: }
                    368: 
                    369: 
                    370: /**
                    371:  * Show help text.
                    372:  */
                    373: static void Opt_ShowHelp(void)
                    374: {
                    375:        const opt_t *opt = HatariOptions;
                    376: 
                    377:        Opt_ShowVersion();
                    378:        printf("Usage:\n hatari [options] [disk image name]\n");
                    379: 
1.1.1.4 ! root      380:        while(opt->id != OPT_ERROR)
1.1.1.2   root      381:        {
                    382:                if (opt->id == OPT_HEADER)
                    383:                {
                    384:                        assert(opt->desc);
                    385:                        printf("\n%s options:\n", opt->desc);
                    386:                        opt++;
1.1       root      387:                }
1.1.1.2   root      388:                opt = Opt_ShowHelpSection(opt);
1.1       root      389:        }
1.1.1.2   root      390:        printf("\nSpecial option values:\n");
                    391:        printf("<bool>\tDisable by using 'n', 'no', 'off', 'false', or '0'\n");
                    392:        printf("\tEnable by using 'y', 'yes', 'on', 'true' or '1'\n");
                    393:        printf("<file>\tDevices accept also special 'stdout' and 'stderr' file names\n");
                    394:        printf("\t(if you use stdout for midi or printer, set log to stderr).\n");
                    395:        printf("\tSetting the file to 'none', disables given device or disk\n");
                    396: }
                    397: 
                    398: 
                    399: /**
1.1.1.4 ! root      400:  * Show Hatari version and usage.
1.1.1.2   root      401:  * If 'error' given, show that error message.
1.1.1.4 ! root      402:  * If 'optid' != OPT_ERROR, tells for which option the error is,
1.1.1.2   root      403:  * otherwise 'value' is show as the option user gave.
1.1.1.4 ! root      404:  * Return FALSE if error string was given, otherwise TRUE
1.1.1.2   root      405:  */
1.1.1.4 ! root      406: static bool Opt_ShowError(unsigned int optid, const char *value, const char *error)
1.1.1.2   root      407: {
                    408:        const opt_t *opt;
                    409: 
                    410:        Opt_ShowVersion();
                    411:        printf("Usage:\n hatari [options] [disk image name]\n\n"
                    412:               "Try option \"-h\" or \"--help\" to display more information.\n");
                    413: 
                    414:        if (error)
                    415:        {
1.1.1.4 ! root      416:                if (optid == OPT_ERROR)
1.1.1.2   root      417:                {
1.1       root      418:                        fprintf(stderr, "\nError: %s (%s)\n", error, value);
                    419:                }
1.1.1.2   root      420:                else
                    421:                {
1.1.1.4 ! root      422:                        for (opt = HatariOptions; opt->id != OPT_ERROR; opt++)
1.1.1.2   root      423:                        {
                    424:                                if (optid == opt->id)
                    425:                                        break;
                    426:                        }
                    427:                        if (value != NULL)
                    428:                        {
                    429:                                fprintf(stderr, "\nError while parsing parameter for %s:\n"
                    430:                                        " %s (%s)\n", opt->str, error, value);
                    431:                        }
                    432:                        else
                    433:                        {
                    434:                                fprintf(stderr, "\nError (%s): %s\n", opt->str, error);
                    435:                        }
                    436:                        Opt_ShowOption(opt, 0);
                    437:                }
1.1.1.4 ! root      438:                return FALSE;
1.1       root      439:        }
1.1.1.4 ! root      440:        return TRUE;
1.1       root      441: }
                    442: 
1.1.1.2   root      443: 
                    444: /**
1.1.1.4 ! root      445:  * If 'conf' given, set it:
        !           446:  * - TRUE if given option 'arg' is y/yes/on/true/1
        !           447:  * - FALSE if given option 'arg' is n/no/off/false/0
        !           448:  * Return FALSE for any other value, otherwise TRUE
1.1.1.2   root      449:  */
1.1.1.4 ! root      450: static bool Opt_Bool(const char *arg, int optid, bool *conf)
1.1.1.2   root      451: {
                    452:        const char *enablers[] = { "y", "yes", "on", "true", "1", NULL };
                    453:        const char *disablers[] = { "n", "no", "off", "false", "0", NULL };
                    454:        const char **bool_str, *orig = arg;
                    455:        char *input, *str;
                    456: 
                    457:        input = strdup(arg);
                    458:        str = input;
                    459:        while (*str)
                    460:        {
                    461:                *str++ = tolower(*arg++);
                    462:        }
                    463:        for (bool_str = enablers; *bool_str; bool_str++)
                    464:        {
                    465:                if (strcmp(input, *bool_str) == 0)
                    466:                {
                    467:                        free(input);
1.1.1.4 ! root      468:                        if (conf)
        !           469:                        {
        !           470:                                *conf = TRUE;
        !           471:                        }
1.1.1.2   root      472:                        return TRUE;
                    473:                }
                    474:        }
                    475:        for (bool_str = disablers; *bool_str; bool_str++)
                    476:        {
                    477:                if (strcmp(input, *bool_str) == 0)
                    478:                {
                    479:                        free(input);
1.1.1.4 ! root      480:                        if (conf)
        !           481:                        {
        !           482:                                *conf = FALSE;
        !           483:                        }
        !           484:                        return TRUE;
1.1.1.2   root      485:                }
                    486:        }
                    487:        free(input);
1.1.1.4 ! root      488:        return Opt_ShowError(optid, orig, "Not a <bool> value");
        !           489: }
        !           490: 
        !           491: 
        !           492: /**
        !           493:  * checks str argument agaist options of type "--option<digit>".
        !           494:  * If match is found, returns ID for that, otherwise OPT_CONTINUE
        !           495:  * and OPT_ERROR for errors.
        !           496:  */
        !           497: static int Opt_CheckBracketValue(const opt_t *opt, const char *str)
        !           498: {
        !           499:        const char *bracket, *optstr;
        !           500:        size_t offset;
        !           501:        int digit, i;
        !           502: 
        !           503:        if (!opt->str)
        !           504:        {
        !           505:                return OPT_CONTINUE;
        !           506:        }
        !           507:        bracket = strchr(opt->str, '<');
        !           508:        if (!bracket)
        !           509:        {
        !           510:                return OPT_CONTINUE;
        !           511:        }
        !           512:        offset = bracket - opt->str;
        !           513:        if (strlen(str) != offset + 1)
        !           514:        {
        !           515:                return OPT_CONTINUE;
        !           516:        }
        !           517:        digit = str[offset] - '0';
        !           518:        if (digit < 0 || digit > 9)
        !           519:        {
        !           520:                return OPT_CONTINUE;
        !           521:        }
        !           522:        optstr = opt->str;
        !           523:        for (i = 0; opt->str == optstr; opt++, i++)
        !           524:        {
        !           525:                if (i == digit)
        !           526:                {
        !           527:                        return opt->id;
        !           528:                }
        !           529:        }
        !           530:        /* fprintf(stderr, "opt: %s (%d), str: %s (%d), digit: %d\n",
        !           531:                opt->str, offset+1, str, strlen(str), digit);
        !           532:         */
        !           533:        return OPT_ERROR;
1.1.1.2   root      534: }
                    535: 
                    536: 
                    537: /**
1.1       root      538:  * matches string under given index in the argv against all Hatari
                    539:  * short and long options. If match is found, returns ID for that,
1.1.1.4 ! root      540:  * otherwise shows help and returns OPT_ERROR.
1.1       root      541:  * 
                    542:  * Checks also that if option is supposed to have argument,
                    543:  * whether there's one.
                    544:  */
1.1.1.4 ! root      545: static int Opt_WhichOption(int argc, const char *argv[], int idx)
1.1       root      546: {
                    547:        const opt_t *opt;
                    548:        const char *str = argv[idx];
1.1.1.4 ! root      549:        int id;
1.1       root      550: 
1.1.1.4 ! root      551:        for (opt = HatariOptions; opt->id != OPT_ERROR; opt++)
1.1.1.2   root      552:        {       
                    553:                if ((opt->str && !strcmp(str, opt->str)) ||
                    554:                    (opt->chr && !strcmp(str, opt->chr)))
                    555:                {
                    556:                        
                    557:                        if (opt->arg)
                    558:                        {
                    559:                                if (idx+1 >= argc)
                    560:                                {
1.1.1.4 ! root      561:                                        Opt_ShowError(opt->id, NULL, "Missing argument");
        !           562:                                        return OPT_ERROR;
1.1.1.2   root      563:                                }
                    564:                                /* early check for bools */
                    565:                                if (strcmp(opt->arg, "<bool>") == 0)
                    566:                                {
1.1.1.4 ! root      567:                                        if (!Opt_Bool(argv[idx+1], opt->id, NULL))
        !           568:                                        {
        !           569:                                                return OPT_ERROR;
        !           570:                                        }
1.1.1.2   root      571:                                }
1.1       root      572:                        }
                    573:                        return opt->id;
                    574:                }
1.1.1.4 ! root      575:                id = Opt_CheckBracketValue(opt, str);
        !           576:                if (id == OPT_ERROR)
        !           577:                {
        !           578:                        break;
        !           579:                }
        !           580:                if (id != OPT_CONTINUE)
        !           581:                {
        !           582:                        return id;
        !           583:                }
1.1       root      584:        }
1.1.1.4 ! root      585:        Opt_ShowError(OPT_ERROR, argv[idx], "Unrecognized option");
        !           586:        return OPT_ERROR;
1.1       root      587: }
                    588: 
1.1.1.2   root      589: 
                    590: /**
1.1.1.4 ! root      591:  * If 'checkexits' is TRUE, assume 'src' is a file and check whether it
        !           592:  * exists before copying 'src' to 'dst'. Otherwise just copy option src
        !           593:  * string to dst.
        !           594:  * If a pointer to (bool) 'option' is given, set that option to TRUE.
        !           595:  * - However, if src is "none", leave dst unmodified & set option to FALSE.
        !           596:  *   ("none" is used to disable options related to file arguments)
        !           597:  * Return FALSE if there were errors, otherwise TRUE
1.1.1.2   root      598:  */
1.1.1.4 ! root      599: static bool Opt_StrCpy(int optid, bool checkexist, char *dst, const char *src, size_t dstlen, bool *option)
1.1.1.2   root      600: {
1.1.1.4 ! root      601:        if (strlen(src) >= dstlen)
        !           602:        {
        !           603:                return Opt_ShowError(optid, src, "File name too long!");
        !           604:        }
        !           605:        if (checkexist && !File_Exists(src))
        !           606:        {
        !           607:                return Opt_ShowError(optid, src, "Given file doesn't exist (or has wrong file permissions)!");
        !           608:        }
1.1.1.2   root      609:        if (option)
                    610:        {
                    611:                if(strcmp(src, "none") == 0)
                    612:                {
                    613:                        *option = FALSE;
1.1.1.4 ! root      614:                        return TRUE;
1.1.1.2   root      615:                }
                    616:                else
                    617:                {
                    618:                        *option = TRUE;
                    619:                }
                    620:        }
1.1.1.4 ! root      621:        strcpy(dst, src);
        !           622:        return TRUE;
1.1.1.2   root      623: }
                    624: 
                    625: 
                    626: /**
1.1.1.4 ! root      627:  * parse all Hatari command line options and set Hatari state accordingly.
        !           628:  * Returns TRUE if everything was OK, FALSE otherwise.
1.1.1.2   root      629:  */
1.1.1.4 ! root      630: bool Opt_ParseParameters(int argc, const char *argv[])
1.1       root      631: {
1.1.1.4 ! root      632:        int ncpu, skips, zoom, planes, cpuclock, threshold, memsize, port;
        !           633:        const char *errstr;
        !           634:        int i, ok = TRUE;
1.1.1.2   root      635: 
                    636:        /* Defaults for loading initial memory snap-shots */
                    637:        bLoadMemorySave = FALSE;
                    638:        bLoadAutoSave = ConfigureParams.Memory.bAutoSave;
                    639: 
                    640:        for(i = 1; i < argc; i++)
1.1.1.4 ! root      641:        {
1.1.1.2   root      642:                if (argv[i][0] != '-')
                    643:                {
1.1.1.4 ! root      644:                        if (Floppy_SetDiskFileName(0, argv[i], NULL))
1.1.1.2   root      645:                        {
1.1.1.4 ! root      646:                                ConfigureParams.HardDisk.bBootFromHardDisk = FALSE;
1.1.1.2   root      647:                                bLoadAutoSave = FALSE;
                    648:                        }
                    649:                        else
1.1.1.4 ! root      650:                                return Opt_ShowError(OPT_ERROR, argv[i], "Not an option nor disk image");
1.1       root      651:                        continue;
                    652:                }
                    653:     
                    654:                /* WhichOption() checks also that there is an argument,
                    655:                 * so we don't need to check that below
                    656:                 */
1.1.1.2   root      657:                switch(Opt_WhichOption(argc, argv, i))
                    658:                {
                    659:                
                    660:                        /* general options */
1.1       root      661:                case OPT_HELP:
1.1.1.2   root      662:                        Opt_ShowHelp();
1.1.1.4 ! root      663:                        return FALSE;
1.1       root      664:                        
                    665:                case OPT_VERSION:
1.1.1.2   root      666:                        Opt_ShowVersion();
1.1.1.4 ! root      667:                        return FALSE;
1.1.1.2   root      668: 
                    669:                case OPT_CONFIRMQUIT:
1.1.1.4 ! root      670:                        ok = Opt_Bool(argv[++i], OPT_CONFIRMQUIT, &ConfigureParams.Log.bConfirmQuit);
        !           671:                        break;
        !           672: 
        !           673:                case OPT_FASTFORWARD:
        !           674:                        ok = Opt_Bool(argv[++i], OPT_FASTFORWARD, &ConfigureParams.System.bFastForward);
1.1       root      675:                        break;
                    676:                        
1.1.1.2   root      677:                case OPT_CONFIGFILE:
                    678:                        i += 1;
1.1.1.4 ! root      679:                        ok = Opt_StrCpy(OPT_CONFIGFILE, TRUE, sConfigFileName,
        !           680:                                        argv[i], sizeof(sConfigFileName), NULL);
        !           681:                        if (ok)
        !           682:                        {
        !           683:                                Configuration_Load(NULL);
        !           684:                                bLoadAutoSave = ConfigureParams.Memory.bAutoSave;
        !           685:                        }
1.1.1.2   root      686:                        break;
                    687:                
                    688:                        /* display options */
1.1       root      689:                case OPT_MONO:
1.1.1.4 ! root      690:                        ConfigureParams.Screen.nMonitorType = MONITOR_TYPE_MONO;
1.1.1.2   root      691:                        bLoadAutoSave = FALSE;
                    692:                        break;
                    693: 
                    694:                case OPT_MONITOR:
                    695:                        i += 1;
                    696:                        if (strcasecmp(argv[i], "mono") == 0)
                    697:                        {
1.1.1.4 ! root      698:                                ConfigureParams.Screen.nMonitorType = MONITOR_TYPE_MONO;
1.1.1.2   root      699:                        }
                    700:                        else if (strcasecmp(argv[i], "rgb") == 0)
                    701:                        {
1.1.1.4 ! root      702:                                ConfigureParams.Screen.nMonitorType = MONITOR_TYPE_RGB;
1.1.1.2   root      703:                        }
                    704:                        else if (strcasecmp(argv[i], "vga") == 0)
                    705:                        {
1.1.1.4 ! root      706:                                ConfigureParams.Screen.nMonitorType = MONITOR_TYPE_VGA;
1.1.1.2   root      707:                        }
                    708:                        else if (strcasecmp(argv[i], "tv") == 0)
                    709:                        {
1.1.1.4 ! root      710:                                ConfigureParams.Screen.nMonitorType = MONITOR_TYPE_TV;
1.1.1.2   root      711:                        }
                    712:                        else
                    713:                        {
1.1.1.4 ! root      714:                                return Opt_ShowError(OPT_MONITOR, argv[i], "Unknown monitor type");
1.1.1.2   root      715:                        }
                    716:                        bLoadAutoSave = FALSE;
1.1       root      717:                        break;
                    718:                        
                    719:                case OPT_FULLSCREEN:
                    720:                        ConfigureParams.Screen.bFullScreen = TRUE;
                    721:                        break;
                    722:                        
                    723:                case OPT_WINDOW:
                    724:                        ConfigureParams.Screen.bFullScreen = FALSE;
                    725:                        break;
                    726:                        
1.1.1.2   root      727:                case OPT_ZOOM:
                    728:                        zoom = atoi(argv[++i]);
                    729:                        if (zoom < 1)
                    730:                        {
1.1.1.4 ! root      731:                                return Opt_ShowError(OPT_ZOOM, argv[i], "Invalid zoom value");
1.1.1.2   root      732:                        }
                    733:                        if (zoom > 1)
                    734:                        {
                    735:                                /* TODO: only doubling supported for now */
                    736:                                ConfigureParams.Screen.bZoomLowRes = TRUE;
                    737:                        }
                    738:                        else
                    739:                        {
                    740:                                ConfigureParams.Screen.bZoomLowRes = FALSE;
1.1       root      741:                        }
                    742:                        break;
                    743:                        
1.1.1.2   root      744:                case OPT_FRAMESKIPS:
                    745:                        skips = atoi(argv[++i]);
                    746:                        if (skips < 0 || skips > 8)
                    747:                        {
1.1.1.4 ! root      748:                                return Opt_ShowError(OPT_FRAMESKIPS, argv[i],
        !           749:                                                     "Invalid frame skip value");
1.1.1.2   root      750:                        }
1.1.1.4 ! root      751:                        ConfigureParams.Screen.nFrameSkips = skips;
1.1       root      752:                        break;
                    753:                        
1.1.1.2   root      754:                case OPT_BORDERS:
1.1.1.4 ! root      755:                        ok = Opt_Bool(argv[++i], OPT_BORDERS, &ConfigureParams.Screen.bAllowOverscan);
        !           756:                        break;
        !           757:                        
        !           758:                case OPT_STATUSBAR:
        !           759:                        ok = Opt_Bool(argv[++i], OPT_STATUSBAR, &ConfigureParams.Screen.bShowStatusbar);
        !           760:                        break;
        !           761:                        
        !           762:                case OPT_DRIVE_LED:
        !           763:                        ok = Opt_Bool(argv[++i], OPT_DRIVE_LED, &ConfigureParams.Screen.bShowDriveLed);
1.1       root      764:                        break;
                    765:                        
1.1.1.2   root      766:                case OPT_SPEC512:
                    767:                        threshold = atoi(argv[++i]);
                    768:                        if (threshold < 0 || threshold > 512)
                    769:                        {
1.1.1.4 ! root      770:                                return Opt_ShowError(OPT_SPEC512, argv[i],
        !           771:                                                     "Invalid palette writes per line threshold for Spec512");
1.1.1.2   root      772:                        }
                    773:                        ConfigureParams.Screen.nSpec512Threshold = threshold;
                    774:                        break;
                    775:                        
                    776:                case OPT_FORCEBPP:
                    777:                        planes = atoi(argv[++i]);
1.1.1.3   root      778:                        switch(planes)
1.1.1.2   root      779:                        {
1.1.1.3   root      780:                        case 32:
                    781:                        case 16:
                    782:                        case 15:
                    783:                        case 8:
                    784:                                break;       /* supported */
                    785:                        case 24:
                    786:                                planes = 32; /* We do not support 24 bpp (yet) */
                    787:                                break;
                    788:                        default:
1.1.1.4 ! root      789:                                return Opt_ShowError(OPT_FORCEBPP, argv[i], "Invalid bit depth");
1.1.1.2   root      790:                        }
                    791:                        ConfigureParams.Screen.nForceBpp = planes;
                    792:                        break;
                    793: 
1.1.1.4 ! root      794:                        /* VDI options */
        !           795:                case OPT_VDI:
        !           796:                        ok = Opt_Bool(argv[++i], OPT_VDI, &ConfigureParams.Screen.bUseExtVdiResolutions);
        !           797:                        if (ok)
        !           798:                        {
        !           799:                                bLoadAutoSave = FALSE;
        !           800:                        }
        !           801:                        break;
        !           802: 
1.1.1.2   root      803:                case OPT_VDI_PLANES:
                    804:                        planes = atoi(argv[++i]);
                    805:                        switch(planes)
                    806:                        {
                    807:                         case 1:
                    808:                                ConfigureParams.Screen.nVdiColors = GEMCOLOR_2;
                    809:                                break;
                    810:                         case 2:
                    811:                                ConfigureParams.Screen.nVdiColors = GEMCOLOR_4;
                    812:                                break;
                    813:                         case 4:
                    814:                                ConfigureParams.Screen.nVdiColors = GEMCOLOR_16;
                    815:                                break;
                    816:                         default:
1.1.1.4 ! root      817:                                return Opt_ShowError(OPT_VDI_PLANES, argv[i], "Unsupported VDI bit-depth");
1.1.1.2   root      818:                        }
                    819:                        ConfigureParams.Screen.bUseExtVdiResolutions = TRUE;
                    820:                        bLoadAutoSave = FALSE;
                    821:                        break;
                    822: 
                    823:                case OPT_VDI_WIDTH:
                    824:                        ConfigureParams.Screen.nVdiWidth = atoi(argv[++i]);
                    825:                        ConfigureParams.Screen.bUseExtVdiResolutions = TRUE;
                    826:                        bLoadAutoSave = FALSE;
                    827:                        break;
                    828: 
                    829:                case OPT_VDI_HEIGHT:
                    830:                        ConfigureParams.Screen.nVdiHeight = atoi(argv[++i]);
                    831:                        ConfigureParams.Screen.bUseExtVdiResolutions = TRUE;
                    832:                        bLoadAutoSave = FALSE;
                    833:                        break;
                    834:                
                    835:                        /* devices options */
                    836:                case OPT_JOYSTICK:
                    837:                        i++;
                    838:                        if (strlen(argv[i]) != 1 ||
                    839:                            !Joy_SetCursorEmulation(argv[i][0] - '0'))
                    840:                        {
1.1.1.4 ! root      841:                                return Opt_ShowError(OPT_JOYSTICK, argv[i], "Invalid joystick port");
        !           842:                        }
        !           843:                        break;
        !           844: 
        !           845:                case OPT_JOYSTICK0:
        !           846:                case OPT_JOYSTICK1:
        !           847:                case OPT_JOYSTICK2:
        !           848:                case OPT_JOYSTICK3:
        !           849:                case OPT_JOYSTICK4:
        !           850:                case OPT_JOYSTICK5:
        !           851:                        port = argv[i][strlen(argv[i])-1] - '0';
        !           852:                        assert(port >= 0 && port < JOYSTICK_COUNT);
        !           853:                        i += 1;
        !           854:                        if (strcasecmp(argv[i], "none") == 0)
        !           855:                        {
        !           856:                                ConfigureParams.Joysticks.Joy[port].nJoystickMode = JOYSTICK_DISABLED;
        !           857:                        }
        !           858:                        else if (strcasecmp(argv[i], "keys") == 0)
        !           859:                        {
        !           860:                                ConfigureParams.Joysticks.Joy[port].nJoystickMode = JOYSTICK_KEYBOARD;
        !           861:                        }
        !           862:                        else if (strcasecmp(argv[i], "real") == 0)
        !           863:                        {
        !           864:                                ConfigureParams.Joysticks.Joy[port].nJoystickMode = JOYSTICK_REALSTICK;
        !           865:                        }
        !           866:                        else
        !           867:                        {
        !           868:                                return Opt_ShowError(OPT_JOYSTICK0+port, argv[i], "Invalid joystick type");
1.1.1.2   root      869:                        }
1.1       root      870:                        break;
                    871:                        
                    872:                case OPT_PRINTER:
1.1.1.2   root      873:                        i += 1;
1.1.1.4 ! root      874:                        ok = Opt_StrCpy(OPT_PRINTER, FALSE, ConfigureParams.Printer.szPrintToFileName,
        !           875:                                        argv[i], sizeof(ConfigureParams.Printer.szPrintToFileName),
        !           876:                                        &ConfigureParams.Printer.bEnablePrinting);
1.1       root      877:                        break;
                    878:                        
                    879:                case OPT_MIDI:
                    880:                        i += 1;
1.1.1.4 ! root      881:                        ok = Opt_StrCpy(OPT_MIDI, FALSE, ConfigureParams.Midi.szMidiOutFileName,
        !           882:                                        argv[i], sizeof(ConfigureParams.Midi.szMidiOutFileName),
        !           883:                                        &ConfigureParams.Midi.bEnableMidi);
1.1       root      884:                        break;
                    885:       
                    886:                case OPT_RS232:
                    887:                        i += 1;
1.1.1.4 ! root      888:                        ok = Opt_StrCpy(OPT_RS232, TRUE, ConfigureParams.RS232.szInFileName,
        !           889:                                        argv[i], sizeof(ConfigureParams.RS232.szInFileName),
        !           890:                                        &ConfigureParams.RS232.bEnableRS232);
        !           891:                        if (ok && ConfigureParams.RS232.bEnableRS232)
1.1.1.2   root      892:                        {
                    893:                                strncpy(ConfigureParams.RS232.szOutFileName, argv[i],
                    894:                                        sizeof(ConfigureParams.RS232.szOutFileName));
1.1       root      895:                        }
                    896:                        break;
1.1.1.2   root      897: 
                    898:                        /* disk options */
1.1.1.4 ! root      899:                case OPT_DISKA:
        !           900:                        i += 1;
        !           901:                        if (Floppy_SetDiskFileName(0, argv[i], NULL))
        !           902:                        {
        !           903:                                ConfigureParams.HardDisk.bBootFromHardDisk = FALSE;
        !           904:                                bLoadAutoSave = FALSE;
        !           905:                        }
        !           906:                        else
        !           907:                                return Opt_ShowError(OPT_ERROR, argv[i], "Not a disk image");
        !           908:                        break;
        !           909: 
        !           910:                case OPT_DISKB:
        !           911:                        i += 1;
        !           912:                        if (Floppy_SetDiskFileName(1, argv[i], NULL))
        !           913:                                bLoadAutoSave = FALSE;
        !           914:                        else
        !           915:                                return Opt_ShowError(OPT_ERROR, argv[i], "Not a disk image");
        !           916:                        break;
        !           917: 
1.1       root      918:                case OPT_HARDDRIVE:
                    919:                        i += 1;
1.1.1.4 ! root      920:                        ok = Opt_StrCpy(OPT_HARDDRIVE, FALSE, ConfigureParams.HardDisk.szHardDiskDirectories[0],
        !           921:                                        argv[i], sizeof(ConfigureParams.HardDisk.szHardDiskDirectories[0]),
        !           922:                                        &ConfigureParams.HardDisk.bUseHardDiskDirectories);
        !           923:                        if (ok && ConfigureParams.HardDisk.bUseHardDiskDirectories)
1.1.1.2   root      924:                        {
1.1       root      925:                                ConfigureParams.HardDisk.bBootFromHardDisk = TRUE;
                    926:                        }
1.1.1.2   root      927:                        bLoadAutoSave = FALSE;
                    928:                        break;
                    929: 
                    930:                case OPT_ACSIHDIMAGE:
                    931:                        i += 1;
1.1.1.4 ! root      932:                        ok = Opt_StrCpy(OPT_ACSIHDIMAGE, TRUE, ConfigureParams.HardDisk.szHardDiskImage,
        !           933:                                        argv[i], sizeof(ConfigureParams.HardDisk.szHardDiskImage),
        !           934:                                        &ConfigureParams.HardDisk.bUseHardDiskImage);
        !           935:                        if (ok)
        !           936:                        {
        !           937:                                bLoadAutoSave = FALSE;
        !           938:                        }
1.1       root      939:                        break;
                    940:                        
1.1.1.2   root      941:                case OPT_IDEHDIMAGE:
1.1       root      942:                        i += 1;
1.1.1.4 ! root      943:                        ok = Opt_StrCpy(OPT_IDEHDIMAGE, TRUE, ConfigureParams.HardDisk.szIdeHardDiskImage,
        !           944:                                        argv[i], sizeof(ConfigureParams.HardDisk.szIdeHardDiskImage),
        !           945:                                        &ConfigureParams.HardDisk.bUseIdeHardDiskImage);
        !           946:                        if (ok)
        !           947:                        {
        !           948:                                bLoadAutoSave = FALSE;
        !           949:                        }
1.1.1.2   root      950:                        break;
                    951:                        
                    952:                case OPT_SLOWFDC:
1.1.1.4 ! root      953:                        ok = Opt_Bool(argv[++i], OPT_SLOWFDC, &ConfigureParams.System.bSlowFDC);
        !           954:                        if (ok)
        !           955:                        {
        !           956:                                bLoadAutoSave = FALSE;
        !           957:                        }
1.1.1.2   root      958:                        break;
                    959:                        
                    960:                        /* Memory options */
                    961:                case OPT_MEMSIZE:
1.1.1.4 ! root      962:                        memsize = atoi(argv[++i]);
        !           963:                        if (memsize < 0 || memsize > 14)
1.1.1.2   root      964:                        {
1.1.1.4 ! root      965:                                return Opt_ShowError(OPT_MEMSIZE, argv[i], "Invalid memory size");
1.1       root      966:                        }
1.1.1.4 ! root      967:                        ConfigureParams.Memory.nMemorySize = memsize;
1.1.1.2   root      968:                        bLoadAutoSave = FALSE;
1.1       root      969:                        break;
                    970:       
1.1.1.2   root      971:                case OPT_TOS:
                    972:                        i += 1;
1.1.1.4 ! root      973:                        ok = Opt_StrCpy(OPT_TOS, TRUE, ConfigureParams.Rom.szTosImageFileName,
        !           974:                                        argv[i], sizeof(ConfigureParams.Rom.szTosImageFileName),
        !           975:                                        NULL);
        !           976:                        if (ok)
        !           977:                        {
        !           978:                                bLoadAutoSave = FALSE;
        !           979:                        }
1.1.1.2   root      980:                        break;
                    981:                        
1.1       root      982:                case OPT_CARTRIDGE:
                    983:                        i += 1;
1.1.1.4 ! root      984:                        ok = Opt_StrCpy(OPT_CARTRIDGE, TRUE, ConfigureParams.Rom.szCartridgeImageFileName,
        !           985:                                        argv[i], sizeof(ConfigureParams.Rom.szCartridgeImageFileName),
        !           986:                                        NULL);
        !           987:                        if (ok)
        !           988:                        {
        !           989:                                bLoadAutoSave = FALSE;
        !           990:                        }
1.1.1.2   root      991:                        break;
                    992: 
                    993:                case OPT_MEMSTATE:
                    994:                        i += 1;
1.1.1.4 ! root      995:                        ok = Opt_StrCpy(OPT_MEMSTATE, TRUE, ConfigureParams.Memory.szMemoryCaptureFileName,
        !           996:                                        argv[i], sizeof(ConfigureParams.Memory.szMemoryCaptureFileName),
        !           997:                                        NULL);
        !           998:                        if (ok)
        !           999:                        {
        !          1000:                                bLoadMemorySave = TRUE;
        !          1001:                                bLoadAutoSave = FALSE;
        !          1002:                        }
1.1       root     1003:                        break;
                   1004:                        
1.1.1.2   root     1005:                        /* CPU options */
1.1       root     1006:                case OPT_CPULEVEL:
                   1007:                        /* UAE core uses cpu_level variable */
1.1.1.2   root     1008:                        ncpu = atoi(argv[++i]);
                   1009:                        if(ncpu < 0 || ncpu > 4)
                   1010:                        {
1.1.1.4 ! root     1011:                                return Opt_ShowError(OPT_CPULEVEL, argv[i], "Invalid CPU level");
1.1.1.2   root     1012:                        }
                   1013:                        ConfigureParams.System.nCpuLevel = ncpu;
                   1014:                        bLoadAutoSave = FALSE;
                   1015:                        break;
                   1016:                        
                   1017:                case OPT_CPUCLOCK:
                   1018:                        cpuclock = atoi(argv[++i]);
                   1019:                        if(cpuclock != 8 && cpuclock != 16 && cpuclock != 32)
                   1020:                        {
1.1.1.4 ! root     1021:                                return Opt_ShowError(OPT_CPUCLOCK, argv[i], "Invalid CPU clock");
1.1       root     1022:                        }
1.1.1.2   root     1023:                        ConfigureParams.System.nCpuFreq = cpuclock;
                   1024:                        bLoadAutoSave = FALSE;
1.1       root     1025:                        break;
                   1026:                        
                   1027:                case OPT_COMPATIBLE:
1.1.1.4 ! root     1028:                        ok = Opt_Bool(argv[++i], OPT_COMPATIBLE, &ConfigureParams.System.bCompatibleCpu);
        !          1029:                        if (ok)
        !          1030:                        {
        !          1031:                                bLoadAutoSave = FALSE;
        !          1032:                        }
1.1       root     1033:                        break;
1.1.1.2   root     1034: 
                   1035:                        /* system options */
                   1036:                case OPT_MACHINE:
                   1037:                        i += 1;
                   1038:                        if (strcasecmp(argv[i], "st") == 0)
                   1039:                        {
                   1040:                                ConfigureParams.System.nMachineType = MACHINE_ST;
                   1041:                                ConfigureParams.System.nCpuLevel = 0;
                   1042:                                ConfigureParams.System.nCpuFreq = 8;
                   1043:                        }
                   1044:                        else if (strcasecmp(argv[i], "ste") == 0)
                   1045:                        {
                   1046:                                ConfigureParams.System.nMachineType = MACHINE_STE;
                   1047:                                ConfigureParams.System.nCpuLevel = 0;
                   1048:                                ConfigureParams.System.nCpuFreq = 8;
                   1049:                        }
                   1050:                        else if (strcasecmp(argv[i], "tt") == 0)
                   1051:                        {
                   1052:                                ConfigureParams.System.nMachineType = MACHINE_TT;
                   1053:                                ConfigureParams.System.nCpuLevel = 3;
                   1054:                                ConfigureParams.System.nCpuFreq = 32;
                   1055:                        }
                   1056:                        else if (strcasecmp(argv[i], "falcon") == 0)
                   1057:                        {
                   1058:                                ConfigureParams.System.nMachineType = MACHINE_FALCON;
                   1059:                                ConfigureParams.System.nCpuLevel = 3;
                   1060:                                ConfigureParams.System.nCpuFreq = 16;
                   1061:                        }
                   1062:                        else
                   1063:                        {
1.1.1.4 ! root     1064:                                return Opt_ShowError(OPT_MACHINE, argv[i], "Unknown machine type");
1.1.1.2   root     1065:                        }
                   1066:                        bLoadAutoSave = FALSE;
1.1       root     1067:                        break;
                   1068:                        
1.1.1.2   root     1069:                case OPT_BLITTER:
1.1.1.4 ! root     1070:                        ok = Opt_Bool(argv[++i], OPT_BLITTER, &ConfigureParams.System.bBlitter);
        !          1071:                        if (ok)
        !          1072:                        {
        !          1073:                                bLoadAutoSave = FALSE;
        !          1074:                        }
1.1.1.2   root     1075:                        break;                  
                   1076: 
                   1077:                case OPT_DSP:
                   1078:                        i += 1;
                   1079:                        if (strcasecmp(argv[i], "none") == 0)
                   1080:                        {
                   1081:                                ConfigureParams.System.nDSPType = DSP_TYPE_NONE;
                   1082:                        }
                   1083:                        else if (strcasecmp(argv[i], "dummy") == 0)
                   1084:                        {
                   1085:                                ConfigureParams.System.nDSPType = DSP_TYPE_DUMMY;
                   1086:                        }
                   1087:                        else if (strcasecmp(argv[i], "emu") == 0)
                   1088:                        {
                   1089: #if ENABLE_DSP_EMU
                   1090:                                ConfigureParams.System.nDSPType = DSP_TYPE_EMU;
                   1091: #else
1.1.1.4 ! root     1092:                                return Opt_ShowError(OPT_DSP, argv[i], "DSP type 'emu' support not compiled in");
1.1.1.2   root     1093: #endif
                   1094:                        }
                   1095:                        else
                   1096:                        {
1.1.1.4 ! root     1097:                                return Opt_ShowError(OPT_DSP, argv[i], "Unknown DSP type");
1.1       root     1098:                        }
1.1.1.2   root     1099:                        bLoadAutoSave = FALSE;
1.1       root     1100:                        break;
                   1101:                        
1.1.1.2   root     1102:                case OPT_SOUND:
1.1       root     1103:                        i += 1;
1.1.1.2   root     1104:                        if (strcasecmp(argv[i], "off") == 0)
                   1105:                        {
                   1106:                                ConfigureParams.Sound.bEnableSound = FALSE;
                   1107:                        }
                   1108:                        else if (strcasecmp(argv[i], "low") == 0)
                   1109:                        {
                   1110:                                ConfigureParams.Sound.nPlaybackQuality = PLAYBACK_LOW;
                   1111:                                ConfigureParams.Sound.bEnableSound = TRUE;
                   1112:                        }
                   1113:                        else if (strcasecmp(argv[i], "med") == 0)
                   1114:                        {
                   1115:                                ConfigureParams.Sound.nPlaybackQuality = PLAYBACK_MEDIUM;
                   1116:                                ConfigureParams.Sound.bEnableSound = TRUE;
                   1117:                        }
                   1118:                        else if (strcasecmp(argv[i], "hi") == 0)
                   1119:                        {
                   1120:                                ConfigureParams.Sound.nPlaybackQuality = PLAYBACK_HIGH;
                   1121:                                ConfigureParams.Sound.bEnableSound = TRUE;
                   1122:                        }
                   1123:                        else
                   1124:                        {
1.1.1.4 ! root     1125:                                return Opt_ShowError(OPT_SOUND, argv[i], "Unsupported sound quality");
1.1       root     1126:                        }
                   1127:                        break;
1.1.1.2   root     1128: 
1.1       root     1129:                case OPT_KEYMAPFILE:
                   1130:                        i += 1;
1.1.1.4 ! root     1131:                        ok = Opt_StrCpy(OPT_KEYMAPFILE, TRUE, ConfigureParams.Keyboard.szMappingFileName,
        !          1132:                                        argv[i], sizeof(ConfigureParams.Keyboard.szMappingFileName),
        !          1133:                                        NULL);
        !          1134:                        if (ok)
        !          1135:                        {
        !          1136:                                ConfigureParams.Keyboard.nKeymapType = KEYMAP_LOADED;
        !          1137:                        }
1.1       root     1138:                        break;
                   1139:                        
1.1.1.2   root     1140:                        /* debug options */
                   1141:                case OPT_DEBUG:
1.1.1.4 ! root     1142:                        if (bEnableDebug)
        !          1143:                        {
        !          1144:                                /* called at run time (e.g. from debugger) */
        !          1145:                                fprintf(stderr, "Debug mode disabled.\n");
        !          1146:                                bEnableDebug = FALSE;
        !          1147:                        }
        !          1148:                        else
        !          1149:                        {
        !          1150:                                bEnableDebug = TRUE;
        !          1151:                        }
1.1.1.2   root     1152:                        break;
1.1.1.4 ! root     1153: 
        !          1154:                case OPT_BIOSINTERCEPT:
        !          1155:                        bBiosIntercept = TRUE;
1.1       root     1156:                        break;
                   1157:                        
1.1.1.2   root     1158:                case OPT_TRACE:
                   1159:                        i += 1;
1.1.1.4 ! root     1160:                        if (Log_SetTraceOptions(argv[i]) == 0)
        !          1161:                        {
        !          1162:                                return Opt_ShowError(OPT_TRACE, argv[i], "Error parsing trace options (use --trace help for available list)!");
        !          1163:                        }
        !          1164:                        break;
        !          1165: 
        !          1166:                case OPT_TRACEFILE:
        !          1167:                        i += 1;
        !          1168:                        ok = Opt_StrCpy(OPT_TRACEFILE, FALSE, ConfigureParams.Log.sTraceFileName,
        !          1169:                                        argv[i], sizeof(ConfigureParams.Log.sTraceFileName),
        !          1170:                                        NULL);
        !          1171:                        break;
        !          1172: 
        !          1173:                case OPT_CONTROLSOCKET:
        !          1174:                        i += 1;
        !          1175:                        errstr = Control_SetSocket(argv[i]);
        !          1176:                        if (errstr)
1.1.1.2   root     1177:                        {
1.1.1.4 ! root     1178:                                return Opt_ShowError(OPT_CONTROLSOCKET, argv[i], errstr);
1.1.1.2   root     1179:                        }
                   1180:                        break;
                   1181: 
1.1.1.4 ! root     1182:                case OPT_LOGFILE:
        !          1183:                        i += 1;
        !          1184:                        ok = Opt_StrCpy(OPT_LOGFILE, FALSE, ConfigureParams.Log.sLogFileName,
        !          1185:                                        argv[i], sizeof(ConfigureParams.Log.sLogFileName),
        !          1186:                                        NULL);
        !          1187:                        break;
        !          1188: 
        !          1189:                case OPT_LOGLEVEL:
        !          1190:                        i += 1;
        !          1191:                        ConfigureParams.Log.nTextLogLevel = Log_ParseOptions(argv[i]);
        !          1192:                        if (ConfigureParams.Log.nTextLogLevel == LOG_NONE)
        !          1193:                        {
        !          1194:                                return Opt_ShowError(OPT_LOGLEVEL, argv[i], "Unknown log level!");
        !          1195:                        }
        !          1196:                        break;
        !          1197: 
        !          1198:                case OPT_ALERTLEVEL:
        !          1199:                        i += 1;
        !          1200:                        ConfigureParams.Log.nAlertDlgLogLevel = Log_ParseOptions(argv[i]);
        !          1201:                        if (ConfigureParams.Log.nAlertDlgLogLevel == LOG_NONE)
        !          1202:                        {
        !          1203:                                return Opt_ShowError(OPT_ALERTLEVEL, argv[i], "Unknown alert level!");
        !          1204:                        }
        !          1205:                        break;
        !          1206:                       
        !          1207:                case OPT_ERROR:
        !          1208:                        /* unknown option or missing option parameter */
        !          1209:                        return FALSE;
        !          1210: 
1.1       root     1211:                default:
1.1.1.4 ! root     1212:                        return Opt_ShowError(OPT_ERROR, argv[i], "Internal Hatari error, unhandled option");
        !          1213:                }
        !          1214:                if (!ok)
        !          1215:                {
        !          1216:                        /* Opt_Bool() or Opt_StrCpy() failed */
        !          1217:                        return FALSE;
1.1       root     1218:                }
                   1219:        }
1.1.1.4 ! root     1220: 
        !          1221:        return TRUE;
1.1       root     1222: }

unix.superglobalmegacorp.com

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