Annotation of previous/src/options.c, revision 1.1

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

unix.superglobalmegacorp.com

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