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

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

unix.superglobalmegacorp.com

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