Example #1
0
/**
 * If 'checkexits' is true, assume 'src' is a file and check whether it
 * exists before copying 'src' to 'dst'. Otherwise just copy option src
 * string to dst.
 * If a pointer to (bool) 'option' is given, set that option to true.
 * - However, if src is "none", leave dst unmodified & set option to false.
 *   ("none" is used to disable options related to file arguments)
 * Return false if there were errors, otherwise true
 */
static bool Opt_StrCpy(int optid, bool checkexist, char *dst, const char *src, size_t dstlen, bool *option)
{
	if (option)
	{
		*option = false;
		if(strcasecmp(src, "none") == 0)
		{
			return true;
		}
	}
	if (strlen(src) >= dstlen)
	{
		return Opt_ShowError(optid, src, "File name too long!");
	}
	if (checkexist && !File_Exists(src))
	{
		return Opt_ShowError(optid, src, "Given file doesn't exist (or has wrong file permissions)!");
	}
	if (option)
	{
		*option = true;
	}
	strcpy(dst, src);
	return true;
}
Example #2
0
/**
 * matches string under given index in the argv against all Hatari
 * short and long options. If match is found, returns ID for that,
 * otherwise shows help and returns OPT_ERROR.
 * 
 * Checks also that if option is supposed to have argument,
 * whether there's one.
 */
static int Opt_WhichOption(int argc, const char * const argv[], int idx)
{
	const opt_t *opt;
	const char *str = argv[idx];
	int id;

	for (opt = HatariOptions; opt->id != OPT_ERROR; opt++)
	{	
		/* exact option name matches? */
		if (!((opt->str && !strcmp(str, opt->str)) ||
		      (opt->chr && !strcmp(str, opt->chr))))
		{
			/* no, maybe name<digit> matches? */
			id = Opt_CheckBracketValue(opt, str);
			if (id == OPT_CONTINUE)
			{
				continue;
			}
			if (id == OPT_ERROR)
			{
				break;
			}
		}
		/* matched, check args */
		if (opt->arg)
		{
			if (idx+1 >= argc)
			{
				Opt_ShowError(opt->id, NULL, "Missing argument");
				return OPT_ERROR;
			}
			/* early check for bools */
			if (strcmp(opt->arg, "<bool>") == 0)
			{
				if (!Opt_Bool(argv[idx+1], opt->id, NULL))
				{
					return OPT_ERROR;
				}
			}
		}
		return opt->id;
	}
	Opt_ShowError(OPT_ERROR, argv[idx], "Unrecognized option");
	return OPT_ERROR;
}
Example #3
0
/**
 * If 'conf' given, set it:
 * - true if given option 'arg' is y/yes/on/true/1
 * - false if given option 'arg' is n/no/off/false/0
 * Return false for any other value, otherwise true
 */
static bool Opt_Bool(const char *arg, int optid, bool *conf)
{
	const char *enablers[] = { "y", "yes", "on", "true", "1", NULL };
	const char *disablers[] = { "n", "no", "off", "false", "0", NULL };
	const char **bool_str, *orig = arg;
	char *input, *str;

	input = strdup(arg);
	str = input;
	while (*str)
	{
		*str++ = tolower(*arg++);
	}
	for (bool_str = enablers; *bool_str; bool_str++)
	{
		if (strcmp(input, *bool_str) == 0)
		{
			free(input);
			if (conf)
			{
				*conf = true;
			}
			return true;
		}
	}
	for (bool_str = disablers; *bool_str; bool_str++)
	{
		if (strcmp(input, *bool_str) == 0)
		{
			free(input);
			if (conf)
			{
				*conf = false;
			}
			return true;
		}
	}
	free(input);
	return Opt_ShowError(optid, orig, "Not a <bool> value");
}
Example #4
0
/**
 * parse all Hatari command line options and set Hatari state accordingly.
 * Returns true if everything was OK, false otherwise.
 */
bool Opt_ParseParameters(int argc, const char * const argv[])
{
	int ncpu, skips, zoom, planes, cpuclock, threshold, memsize, port, freq, temp;
	const char *errstr;
	int i, ok = true;
	int val;

	/* Defaults for loading initial memory snap-shots */
	bLoadMemorySave = false;
	bLoadAutoSave = ConfigureParams.Memory.bAutoSave;

	for(i = 1; i < argc; i++)
	{
		/* last argument can be a non-option */
		if (argv[i][0] != '-' && i+1 == argc)
			return Opt_HandleArgument(argv[i]);

		/* WhichOption() checks also that there is an argument,
		 * so we don't need to check that below
		 */
		switch(Opt_WhichOption(argc, argv, i))
		{

			/* general options */
		case OPT_HELP:
			Opt_ShowHelp();
			return false;

		case OPT_VERSION:
			Opt_ShowVersion();
			return false;

		case OPT_CONFIRMQUIT:
			ok = Opt_Bool(argv[++i], OPT_CONFIRMQUIT, &ConfigureParams.Log.bConfirmQuit);
			break;

		case OPT_FASTFORWARD:
			ok = Opt_Bool(argv[++i], OPT_FASTFORWARD, &ConfigureParams.System.bFastForward);
			break;

		case OPT_CONFIGFILE:
			i += 1;
			/* true -> file needs to exist */
			ok = Opt_StrCpy(OPT_CONFIGFILE, true, sConfigFileName,
					argv[i], sizeof(sConfigFileName), NULL);
			if (ok)
			{
				Configuration_Load(NULL);
				bLoadAutoSave = ConfigureParams.Memory.bAutoSave;
			}
			break;

			/* common display options */
		case OPT_MONO:
			ConfigureParams.Screen.nMonitorType = MONITOR_TYPE_MONO;
			bLoadAutoSave = false;
			break;

		case OPT_MONITOR:
			i += 1;
			if (strcasecmp(argv[i], "mono") == 0)
			{
				ConfigureParams.Screen.nMonitorType = MONITOR_TYPE_MONO;
			}
			else if (strcasecmp(argv[i], "rgb") == 0)
			{
				ConfigureParams.Screen.nMonitorType = MONITOR_TYPE_RGB;
			}
			else if (strcasecmp(argv[i], "vga") == 0)
			{
				ConfigureParams.Screen.nMonitorType = MONITOR_TYPE_VGA;
			}
			else if (strcasecmp(argv[i], "tv") == 0)
			{
				ConfigureParams.Screen.nMonitorType = MONITOR_TYPE_TV;
			}
			else
			{
				return Opt_ShowError(OPT_MONITOR, argv[i], "Unknown monitor type");
			}
			bLoadAutoSave = false;
			break;

		case OPT_FULLSCREEN:
			ConfigureParams.Screen.bFullScreen = true;
			break;

		case OPT_WINDOW:
			ConfigureParams.Screen.bFullScreen = false;
			break;

		case OPT_GRAB:
			bGrabMouse = true;
			break;

		case OPT_FRAMESKIPS:
			skips = atoi(argv[++i]);
			if (skips < 0)
			{
				return Opt_ShowError(OPT_FRAMESKIPS, argv[i],
						     "Invalid frame skip value");
			}
			else if (skips > 8)
			{
				Log_Printf(LOG_WARN, "Extravagant frame skip value %d!\n", skips);
			}
			ConfigureParams.Screen.nFrameSkips = skips;
			break;

		case OPT_STATUSBAR:
			ok = Opt_Bool(argv[++i], OPT_STATUSBAR, &ConfigureParams.Screen.bShowStatusbar);
			break;

		case OPT_DRIVE_LED:
			ok = Opt_Bool(argv[++i], OPT_DRIVE_LED, &ConfigureParams.Screen.bShowDriveLed);
			break;

		case OPT_FORCEBPP:
			planes = atoi(argv[++i]);
			switch(planes)
			{
			case 32:
			case 16:
			case 15:
			case 8:
				break;       /* supported */
			case 24:
				planes = 32; /* We do not support 24 bpp (yet) */
				break;
			default:
				return Opt_ShowError(OPT_FORCEBPP, argv[i], "Invalid bit depth");
			}
			fprintf(stderr, "Hatari window BPP = %d.\n", planes);
			ConfigureParams.Screen.nForceBpp = planes;
			break;

			/* ST/STE display options */
		case OPT_BORDERS:
			ok = Opt_Bool(argv[++i], OPT_BORDERS, &ConfigureParams.Screen.bAllowOverscan);
			break;

		case OPT_RESOLUTION_ST:
			ok = Opt_Bool(argv[++i], OPT_RESOLUTION_ST, &ConfigureParams.Screen.bKeepResolutionST);
			break;
			
		case OPT_SPEC512:
			threshold = atoi(argv[++i]);
			if (threshold < 0 || threshold > 512)
			{
				return Opt_ShowError(OPT_SPEC512, argv[i],
						     "Invalid palette writes per line threshold for Spec512");
			}
			fprintf(stderr, "Spec512 threshold = %d palette writes per line.\n", threshold);
			ConfigureParams.Screen.nSpec512Threshold = threshold;
			break;

		case OPT_ZOOM:
			zoom = atoi(argv[++i]);
			if (zoom < 1)
			{
				return Opt_ShowError(OPT_ZOOM, argv[i], "Invalid zoom value");
			}
			if (zoom > 1)
			{
				ConfigureParams.Screen.nMaxWidth = 2*(48+320+48);
				ConfigureParams.Screen.nMaxHeight = 2*NUM_VISIBLE_LINES+24;
			}
			else
			{
				ConfigureParams.Screen.nMaxWidth = 1*(48+320+48);
				ConfigureParams.Screen.nMaxHeight = 1*NUM_VISIBLE_LINES+12;
			}
			break;

			/* Falcon/TT display options */
		case OPT_RESOLUTION:
			ok = Opt_Bool(argv[++i], OPT_RESOLUTION, &ConfigureParams.Screen.bKeepResolution);
			break;
			
		case OPT_MAXWIDTH:
			ConfigureParams.Screen.nMaxWidth = atoi(argv[++i]);
			break;

		case OPT_MAXHEIGHT:
			ConfigureParams.Screen.nMaxHeight = atoi(argv[++i]);
			break;

		case OPT_FORCE_MAX:
			ok = Opt_Bool(argv[++i], OPT_FORCE_MAX, &ConfigureParams.Screen.bForceMax);
			break;
			
		case OPT_ASPECT:
			ok = Opt_Bool(argv[++i], OPT_ASPECT, &ConfigureParams.Screen.bAspectCorrect);
			break;

			/* screen capture options */
		case OPT_SCREEN_CROP:
			ok = Opt_Bool(argv[++i], OPT_SCREEN_CROP, &ConfigureParams.Screen.bCrop);
			break;

		case OPT_AVIRECORD:
			AviRecordOnStartup = true;
			break;

		case OPT_AVIRECORD_VCODEC:
			i += 1;
			if (strcasecmp(argv[i], "bmp") == 0)
			{
				ConfigureParams.Video.AviRecordVcodec = AVI_RECORD_VIDEO_CODEC_BMP;
			}
			else if (strcasecmp(argv[i], "png") == 0)
			{
				ConfigureParams.Video.AviRecordVcodec = AVI_RECORD_VIDEO_CODEC_PNG;
			}
			else
			{
				return Opt_ShowError(OPT_AVIRECORD_VCODEC, argv[i], "Unknown video codec");
			}
			break;

		case OPT_AVIRECORD_FPS:
			val = atoi(argv[++i]);
			if (val < 0 || val > 100)
			{
				return Opt_ShowError(OPT_AVIRECORD_FPS, argv[i],
							"Invalid frame rate for avi recording");
			}
			fprintf(stderr, "AVI recording FPS = %d.\n", val);
			ConfigureParams.Video.AviRecordFps = val;
			break;

		case OPT_AVIRECORD_FILE:
			i += 1;
			/* false -> file is created if it doesn't exist */
			ok = Opt_StrCpy(OPT_AVIRECORD_FILE, false, ConfigureParams.Video.AviRecordFile,
					argv[i], sizeof(ConfigureParams.Video.AviRecordFile), NULL);
			break;

			/* VDI options */
		case OPT_VDI:
			ok = Opt_Bool(argv[++i], OPT_VDI, &ConfigureParams.Screen.bUseExtVdiResolutions);
			if (ok)
			{
				bLoadAutoSave = false;
			}
			break;

		case OPT_VDI_PLANES:
			planes = atoi(argv[++i]);
			switch(planes)
			{
			 case 1:
				ConfigureParams.Screen.nVdiColors = GEMCOLOR_2;
				break;
			 case 2:
				ConfigureParams.Screen.nVdiColors = GEMCOLOR_4;
				break;
			 case 4:
				ConfigureParams.Screen.nVdiColors = GEMCOLOR_16;
				break;
			 default:
				return Opt_ShowError(OPT_VDI_PLANES, argv[i], "Unsupported VDI bit-depth");
			}
			ConfigureParams.Screen.bUseExtVdiResolutions = true;
			bLoadAutoSave = false;
			break;

		case OPT_VDI_WIDTH:
			ConfigureParams.Screen.nVdiWidth = atoi(argv[++i]);
			ConfigureParams.Screen.bUseExtVdiResolutions = true;
			bLoadAutoSave = false;
			break;

		case OPT_VDI_HEIGHT:
			ConfigureParams.Screen.nVdiHeight = atoi(argv[++i]);
			ConfigureParams.Screen.bUseExtVdiResolutions = true;
			bLoadAutoSave = false;
			break;

			/* devices options */
		case OPT_JOYSTICK:
			i++;
			if (strlen(argv[i]) != 1 ||
			    !Joy_SetCursorEmulation(argv[i][0] - '0'))
			{
				return Opt_ShowError(OPT_JOYSTICK, argv[i], "Invalid joystick port");
			}
			break;

		case OPT_JOYSTICK0:
		case OPT_JOYSTICK1:
		case OPT_JOYSTICK2:
		case OPT_JOYSTICK3:
		case OPT_JOYSTICK4:
		case OPT_JOYSTICK5:
			port = argv[i][strlen(argv[i])-1] - '0';
			assert(port >= 0 && port < JOYSTICK_COUNT);
			i += 1;
			if (strcasecmp(argv[i], "none") == 0)
			{
				ConfigureParams.Joysticks.Joy[port].nJoystickMode = JOYSTICK_DISABLED;
			}
			else if (strcasecmp(argv[i], "keys") == 0)
			{
				ConfigureParams.Joysticks.Joy[port].nJoystickMode = JOYSTICK_KEYBOARD;
			}
			else if (strcasecmp(argv[i], "real") == 0)
			{
				ConfigureParams.Joysticks.Joy[port].nJoystickMode = JOYSTICK_REALSTICK;
			}
			else
			{
				return Opt_ShowError(OPT_JOYSTICK0+port, argv[i], "Invalid joystick type");
			}
			break;

		case OPT_PRINTER:
			i += 1;
			/* "none" can be used to disable printer */
			ok = Opt_StrCpy(OPT_PRINTER, false, ConfigureParams.Printer.szPrintToFileName,
					argv[i], sizeof(ConfigureParams.Printer.szPrintToFileName),
					&ConfigureParams.Printer.bEnablePrinting);
			break;

		case OPT_MIDI_IN:
			i += 1;
			ok = Opt_StrCpy(OPT_MIDI_IN, true, ConfigureParams.Midi.sMidiInFileName,
					argv[i], sizeof(ConfigureParams.Midi.sMidiInFileName),
					&ConfigureParams.Midi.bEnableMidi);
			break;
			
		case OPT_MIDI_OUT:
			i += 1;
			ok = Opt_StrCpy(OPT_MIDI_OUT, false, ConfigureParams.Midi.sMidiOutFileName,
					argv[i], sizeof(ConfigureParams.Midi.sMidiOutFileName),
					&ConfigureParams.Midi.bEnableMidi);
			break;
      
		case OPT_RS232_IN:
			i += 1;
			ok = Opt_StrCpy(OPT_RS232_IN, true, ConfigureParams.RS232.szInFileName,
					argv[i], sizeof(ConfigureParams.RS232.szInFileName),
					&ConfigureParams.RS232.bEnableRS232);
			break;
      
		case OPT_RS232_OUT:
			i += 1;
			ok = Opt_StrCpy(OPT_RS232_OUT, false, ConfigureParams.RS232.szOutFileName,
					argv[i], sizeof(ConfigureParams.RS232.szOutFileName),
					&ConfigureParams.RS232.bEnableRS232);
			break;

			/* disk options */
		case OPT_DRIVEA:
			ok = Opt_Bool(argv[++i], OPT_DRIVEA, &ConfigureParams.DiskImage.EnableDriveA);
			break;

		case OPT_DRIVEB:
			ok = Opt_Bool(argv[++i], OPT_DRIVEB, &ConfigureParams.DiskImage.EnableDriveB);
			break;

		case OPT_DISKA:
			i += 1;
			if (Floppy_SetDiskFileName(0, argv[i], NULL))
			{
				ConfigureParams.HardDisk.bBootFromHardDisk = false;
				bLoadAutoSave = false;
			}
			else
				return Opt_ShowError(OPT_ERROR, argv[i], "Not a disk image");
			break;

		case OPT_DISKB:
			i += 1;
			if (Floppy_SetDiskFileName(1, argv[i], NULL))
				bLoadAutoSave = false;
			else
				return Opt_ShowError(OPT_ERROR, argv[i], "Not a disk image");
			break;

		case OPT_SLOWFLOPPY:
			i++;
			fprintf(stderr, "\nWarning: --slowfdc is not supported anymore, use --fastfdc\n\n");
			break;

		case OPT_FASTFLOPPY:
			ok = Opt_Bool(argv[++i], OPT_FASTFLOPPY, &ConfigureParams.DiskImage.FastFloppy);
			break;

		case OPT_WRITEPROT_FLOPPY:
			i += 1;
			if (strcasecmp(argv[i], "off") == 0)
				ConfigureParams.DiskImage.nWriteProtection = WRITEPROT_OFF;
			else if (strcasecmp(argv[i], "on") == 0)
				ConfigureParams.DiskImage.nWriteProtection = WRITEPROT_ON;
			else if (strcasecmp(argv[i], "auto") == 0)
				ConfigureParams.DiskImage.nWriteProtection = WRITEPROT_AUTO;
			else
				return Opt_ShowError(OPT_WRITEPROT_FLOPPY, argv[i], "Unknown option value");
			break;

		case OPT_WRITEPROT_HD:
			i += 1;
			if (strcasecmp(argv[i], "off") == 0)
				ConfigureParams.HardDisk.nWriteProtection = WRITEPROT_OFF;
			else if (strcasecmp(argv[i], "on") == 0)
				ConfigureParams.HardDisk.nWriteProtection = WRITEPROT_ON;
			else if (strcasecmp(argv[i], "auto") == 0)
				ConfigureParams.HardDisk.nWriteProtection = WRITEPROT_AUTO;
			else
				return Opt_ShowError(OPT_WRITEPROT_HD, argv[i], "Unknown option value");
			break;

		case OPT_GEMDOS_CASE:
			i += 1;
			if (strcasecmp(argv[i], "off") == 0)
				ConfigureParams.HardDisk.nGemdosCase = GEMDOS_NOP;
			else if (strcasecmp(argv[i], "upper") == 0)
				ConfigureParams.HardDisk.nGemdosCase = GEMDOS_UPPER;
			else if (strcasecmp(argv[i], "lower") == 0)
				ConfigureParams.HardDisk.nGemdosCase = GEMDOS_LOWER;
			else
				return Opt_ShowError(OPT_GEMDOS_CASE, argv[i], "Unknown option value");
			break;

		case OPT_HARDDRIVE:
			i += 1;
			ok = Opt_StrCpy(OPT_HARDDRIVE, false, ConfigureParams.HardDisk.szHardDiskDirectories[0],
					argv[i], sizeof(ConfigureParams.HardDisk.szHardDiskDirectories[0]),
					&ConfigureParams.HardDisk.bUseHardDiskDirectories);
			if (ok && ConfigureParams.HardDisk.bUseHardDiskDirectories &&
			    ConfigureParams.HardDisk.szHardDiskDirectories[0][0])
			{
				ConfigureParams.HardDisk.bBootFromHardDisk = true;
			}
			else
			{
				ConfigureParams.HardDisk.bUseHardDiskDirectories = false;
				ConfigureParams.HardDisk.bBootFromHardDisk = false;
			}
			bLoadAutoSave = false;
			break;

		case OPT_ACSIHDIMAGE:
			i += 1;
			ok = Opt_StrCpy(OPT_ACSIHDIMAGE, true, ConfigureParams.Acsi[0].sDeviceFile,
					argv[i], sizeof(ConfigureParams.Acsi[0].sDeviceFile),
					&ConfigureParams.Acsi[0].bUseDevice);
			if (ok)
			{
				bLoadAutoSave = false;
			}
			break;

		case OPT_IDEMASTERHDIMAGE:
			i += 1;
			ok = Opt_StrCpy(OPT_IDEMASTERHDIMAGE, true, ConfigureParams.HardDisk.szIdeMasterHardDiskImage,
					argv[i], sizeof(ConfigureParams.HardDisk.szIdeMasterHardDiskImage),
					&ConfigureParams.HardDisk.bUseIdeMasterHardDiskImage);
			if (ok)
			{
				bLoadAutoSave = false;
			}
			break;

		case OPT_IDESLAVEHDIMAGE:
			i += 1;
			ok = Opt_StrCpy(OPT_IDESLAVEHDIMAGE, true, ConfigureParams.HardDisk.szIdeSlaveHardDiskImage,
					argv[i], sizeof(ConfigureParams.HardDisk.szIdeSlaveHardDiskImage),
					&ConfigureParams.HardDisk.bUseIdeSlaveHardDiskImage);
			if (ok)
			{
				bLoadAutoSave = false;
			}
			break;

			/* Memory options */
		case OPT_MEMSIZE:
			memsize = atoi(argv[++i]);
			if (memsize < 0 || memsize > 14)
			{
				return Opt_ShowError(OPT_MEMSIZE, argv[i], "Invalid memory size");
			}
			ConfigureParams.Memory.nMemorySize = memsize;
			bLoadAutoSave = false;
			break;

		case OPT_TOS:
			i += 1;
			ok = Opt_StrCpy(OPT_TOS, true, ConfigureParams.Rom.szTosImageFileName,
					argv[i], sizeof(ConfigureParams.Rom.szTosImageFileName),
					NULL);
			if (ok)
			{
				bLoadAutoSave = false;
			}
			break;

		case OPT_PATCHTOS:
			ok = Opt_Bool(argv[++i], OPT_PATCHTOS, &ConfigureParams.Rom.bPatchTos);
			break;

		case OPT_CARTRIDGE:
			i += 1;
			ok = Opt_StrCpy(OPT_CARTRIDGE, true, ConfigureParams.Rom.szCartridgeImageFileName,
					argv[i], sizeof(ConfigureParams.Rom.szCartridgeImageFileName),
					NULL);
			if (ok)
			{
				bLoadAutoSave = false;
			}
			break;

		case OPT_MEMSTATE:
			i += 1;
			ok = Opt_StrCpy(OPT_MEMSTATE, true, ConfigureParams.Memory.szMemoryCaptureFileName,
					argv[i], sizeof(ConfigureParams.Memory.szMemoryCaptureFileName),
					NULL);
			if (ok)
			{
				bLoadMemorySave = true;
				bLoadAutoSave = false;
			}
			break;

			/* CPU options */
		case OPT_CPULEVEL:
			/* UAE core uses cpu_level variable */
			ncpu = atoi(argv[++i]);
			if(ncpu < 0 || ncpu > 4)
			{
				return Opt_ShowError(OPT_CPULEVEL, argv[i], "Invalid CPU level");
			}
			ConfigureParams.System.nCpuLevel = ncpu;
			bLoadAutoSave = false;
			break;

		case OPT_CPUCLOCK:
			cpuclock = atoi(argv[++i]);
			if(cpuclock != 8 && cpuclock != 16 && cpuclock != 32)
			{
				return Opt_ShowError(OPT_CPUCLOCK, argv[i], "Invalid CPU clock");
			}
			ConfigureParams.System.nCpuFreq = cpuclock;
			bLoadAutoSave = false;
			break;

		case OPT_COMPATIBLE:
			ok = Opt_Bool(argv[++i], OPT_COMPATIBLE, &ConfigureParams.System.bCompatibleCpu);
			if (ok)
			{
				bLoadAutoSave = false;
			}
			break;
#if ENABLE_WINUAE_CPU
		case OPT_CPU_ADDR24:
			ok = Opt_Bool(argv[++i], OPT_CPU_ADDR24, &ConfigureParams.System.bAddressSpace24);
			bLoadAutoSave = false;
			break;

		case OPT_CPU_CYCLE_EXACT:
			ok = Opt_Bool(argv[++i], OPT_CPU_CYCLE_EXACT, &ConfigureParams.System.bCycleExactCpu);
			bLoadAutoSave = false;
			break;

		case OPT_FPU_TYPE:
			i += 1;
			if (strcasecmp(argv[i], "none") == 0)
			{
				ConfigureParams.System.n_FPUType = FPU_NONE;
			}
			else if (strcasecmp(argv[i], "68881") == 0)
			{
				ConfigureParams.System.n_FPUType = FPU_68881;
			}
			else if (strcasecmp(argv[i], "68882") == 0)
			{
				ConfigureParams.System.n_FPUType = FPU_68882;
			}
			else if (strcasecmp(argv[i], "internal") == 0)
			{
				ConfigureParams.System.n_FPUType = FPU_CPU;
			}
			else
			{
				return Opt_ShowError(OPT_FPU_TYPE, argv[i], "Unknown FPU type");
			}
			bLoadAutoSave = false;
			break;

		case OPT_FPU_COMPATIBLE:
			ok = Opt_Bool(argv[++i], OPT_FPU_COMPATIBLE, &ConfigureParams.System.bCompatibleFPU);
			break;

		case OPT_MMU:
			ok = Opt_Bool(argv[++i], OPT_MMU, &ConfigureParams.System.bMMU);
			bLoadAutoSave = false;
			break;
#endif

			/* system options */
		case OPT_MACHINE:
			i += 1;
			if (strcasecmp(argv[i], "st") == 0)
			{
				ConfigureParams.System.nMachineType = MACHINE_ST;
				ConfigureParams.System.nCpuLevel = 0;
				ConfigureParams.System.nCpuFreq = 8;
			}
			else if (strcasecmp(argv[i], "ste") == 0)
			{
				ConfigureParams.System.nMachineType = MACHINE_STE;
				ConfigureParams.System.nCpuLevel = 0;
				ConfigureParams.System.nCpuFreq = 8;
			}
			else if (strcasecmp(argv[i], "tt") == 0)
			{
				ConfigureParams.System.nMachineType = MACHINE_TT;
				ConfigureParams.System.nCpuLevel = 3;
				ConfigureParams.System.nCpuFreq = 32;
			}
			else if (strcasecmp(argv[i], "falcon") == 0)
			{
#if ENABLE_DSP_EMU
				ConfigureParams.System.nDSPType = DSP_TYPE_EMU;
#endif
				ConfigureParams.System.nMachineType = MACHINE_FALCON;
				ConfigureParams.System.nCpuLevel = 3;
				ConfigureParams.System.nCpuFreq = 16;
			}
			else
			{
				return Opt_ShowError(OPT_MACHINE, argv[i], "Unknown machine type");
			}
#if ENABLE_WINUAE_CPU
			if (ConfigureParams.System.nMachineType == MACHINE_ST ||
			    ConfigureParams.System.nMachineType == MACHINE_STE)
			{
				ConfigureParams.System.bMMU = false;
				ConfigureParams.System.bAddressSpace24 = true;
			}
			if (ConfigureParams.System.nMachineType == MACHINE_TT)
			{
				ConfigureParams.System.bCompatibleFPU = true;
				ConfigureParams.System.n_FPUType = FPU_68882;
			} else {
				ConfigureParams.System.n_FPUType = FPU_NONE;	/* TODO: or leave it as-is? */
			}
#endif
			bLoadAutoSave = false;
			break;

		case OPT_BLITTER:
			ok = Opt_Bool(argv[++i], OPT_BLITTER, &ConfigureParams.System.bBlitter);
			if (ok)
			{
				bLoadAutoSave = false;
			}
			break;

		case OPT_TIMERD:
			ok = Opt_Bool(argv[++i], OPT_TIMERD, &ConfigureParams.System.bPatchTimerD);
			break;
		case OPT_FASTBOOT:
			ok = Opt_Bool(argv[++i], OPT_FASTBOOT, &ConfigureParams.System.bFastBoot);
			break;

		case OPT_RTC:
			ok = Opt_Bool(argv[++i], OPT_RTC, &ConfigureParams.System.bRealTimeClock);
			break;

		case OPT_DSP:
			i += 1;
			if (strcasecmp(argv[i], "none") == 0)
			{
				ConfigureParams.System.nDSPType = DSP_TYPE_NONE;
			}
			else if (strcasecmp(argv[i], "dummy") == 0)
			{
				ConfigureParams.System.nDSPType = DSP_TYPE_DUMMY;
			}
			else if (strcasecmp(argv[i], "emu") == 0)
			{
#if ENABLE_DSP_EMU
				ConfigureParams.System.nDSPType = DSP_TYPE_EMU;
#else
				return Opt_ShowError(OPT_DSP, argv[i], "DSP type 'emu' support not compiled in");
#endif
			}
			else
			{
				return Opt_ShowError(OPT_DSP, argv[i], "Unknown DSP type");
			}
			bLoadAutoSave = false;
			break;

			/* sound options */
		case OPT_YM_MIXING:
			i += 1;
			if (strcasecmp(argv[i], "linear") == 0)
			{
				ConfigureParams.Sound.YmVolumeMixing = YM_LINEAR_MIXING;
			}
			else if (strcasecmp(argv[i], "table") == 0)
			{
				ConfigureParams.Sound.YmVolumeMixing = YM_TABLE_MIXING;
			}
			else if (strcasecmp(argv[i], "model") == 0)
			{
				ConfigureParams.Sound.YmVolumeMixing = YM_MODEL_MIXING;
			}
			else
			{
				return Opt_ShowError(OPT_YM_MIXING, argv[i], "Unknown YM mixing method");
			}
			break;

		case OPT_SOUND:
			i += 1;
			if (strcasecmp(argv[i], "off") == 0)
			{
				ConfigureParams.Sound.bEnableSound = false;
			}
			else
			{
				freq = atoi(argv[i]);
				if (freq < 6000 || freq > 50066)
				{
					return Opt_ShowError(OPT_SOUND, argv[i], "Unsupported sound frequency");
				}
				ConfigureParams.Sound.nPlaybackFreq = freq;
				ConfigureParams.Sound.bEnableSound = true;
			}
			fprintf(stderr, "Sound %s, frequency = %d.\n", ConfigureParams.Sound.bEnableSound ? "ON" : "OFF", ConfigureParams.Sound.nPlaybackFreq);
			break;

		case OPT_SOUNDBUFFERSIZE:
			i += 1;
			temp = atoi(argv[i]);
			if ( temp == 0 )			/* use default setting for SDL */
				;
			else if (temp < 10 || temp > 100)
				{
					return Opt_ShowError(OPT_SOUNDBUFFERSIZE, argv[i], "Unsupported sound buffer size");
				}
			fprintf(stderr, "SDL sound buffer size = %d ms.\n", temp);
			ConfigureParams.Sound.SdlAudioBufferSize = temp;
			break;

		case OPT_SOUNDSYNC:
			ok = Opt_Bool(argv[++i], OPT_SOUNDSYNC, &ConfigureParams.Sound.bEnableSoundSync);
			break;
			
		case OPT_MICROPHONE:
			ok = Opt_Bool(argv[++i], OPT_MICROPHONE, &ConfigureParams.Sound.bEnableMicrophone);
			break;

		case OPT_KEYMAPFILE:
			i += 1;
			ok = Opt_StrCpy(OPT_KEYMAPFILE, true, ConfigureParams.Keyboard.szMappingFileName,
					argv[i], sizeof(ConfigureParams.Keyboard.szMappingFileName),
					NULL);
			if (ok)
			{
				ConfigureParams.Keyboard.nKeymapType = KEYMAP_LOADED;
			}
			break;
			
			/* debug options */
#ifdef WIN32
		case OPT_WINCON:
			ConfigureParams.Log.bConsoleWindow = true;
			break;
#endif
		case OPT_DEBUG:
			if (ExceptionDebugMask)
			{
				fprintf(stderr, "Exception debugging disabled.\n");
				ExceptionDebugMask = EXCEPT_NONE;
			}
			else
			{
				ExceptionDebugMask = ConfigureParams.Log.nExceptionDebugMask;
				fprintf(stderr, "Exception debugging enabled (0x%x).\n", ExceptionDebugMask);
			}
			break;

		case OPT_EXCEPTIONS:
			i += 1;
			/* sets ConfigureParams.Log.nExceptionDebugMask */
			errstr = Log_SetExceptionDebugMask(argv[i]);
			if (errstr)
			{
				if (!errstr[0]) {
					/* silent parsing termination */
					return false;
				}
				return Opt_ShowError(OPT_EXCEPTIONS, argv[i], errstr);
			}
			if (ExceptionDebugMask)
			{
				/* already enabled, change run-time config */
				int oldmask = ExceptionDebugMask;
				ExceptionDebugMask = ConfigureParams.Log.nExceptionDebugMask;
				fprintf(stderr, "Exception debugging changed (0x%x -> 0x%x).\n",
					oldmask, ExceptionDebugMask);
			}
			break;

		case OPT_BIOSINTERCEPT:
			if (bBiosIntercept)
			{
				fprintf(stderr, "X/Bios interception disabled.\n");
				bBiosIntercept = false;
			}
			else
			{
				fprintf(stderr, "X/Bios interception enabled.\n");
				bBiosIntercept = true;
			}
			break;

		case OPT_CONOUT:
			i += 1;
			ConOutDevice = atoi(argv[i]);
			if (ConOutDevice < 0 || ConOutDevice > 7)
			{
				return Opt_ShowError(OPT_CONOUT, argv[i], "Invalid console device vector number");
			}
			fprintf(stderr, "Xcounout device %d vector redirection enabled.\n", ConOutDevice);
			break;

		case OPT_NATFEATS:
			ok = Opt_Bool(argv[++i], OPT_NATFEATS, &ConfigureParams.Log.bNatFeats);
			fprintf(stderr, "Native Features %s.\n", ConfigureParams.Log.bNatFeats ? "enabled" : "disabled");
			break;

		case OPT_PARACHUTE:
			bNoSDLParachute = true;
			break;

		case OPT_DISASM:
			i += 1;
			errstr = Disasm_ParseOption(argv[i]);
			if (errstr)
			{
				if (!errstr[0]) {
					/* silent parsing termination */
					return false;
				}
				return Opt_ShowError(OPT_DISASM, argv[i], errstr);
			}
			break;
			
		case OPT_TRACE:
			i += 1;
			errstr = Log_SetTraceOptions(argv[i]);
			if (errstr)
			{
				if (!errstr[0]) {
					/* silent parsing termination */
					return false;
				}
				return Opt_ShowError(OPT_TRACE, argv[i], errstr);
			}
			break;

		case OPT_TRACEFILE:
			i += 1;
			ok = Opt_StrCpy(OPT_TRACEFILE, false, ConfigureParams.Log.sTraceFileName,
					argv[i], sizeof(ConfigureParams.Log.sTraceFileName),
					NULL);
			break;

		case OPT_CONTROLSOCKET:
			i += 1;
			errstr = Control_SetSocket(argv[i]);
			if (errstr)
			{
				return Opt_ShowError(OPT_CONTROLSOCKET, argv[i], errstr);
			}
			break;

		case OPT_LOGFILE:
			i += 1;
			ok = Opt_StrCpy(OPT_LOGFILE, false, ConfigureParams.Log.sLogFileName,
					argv[i], sizeof(ConfigureParams.Log.sLogFileName),
					NULL);
			break;

		case OPT_PARSE:
			i += 1;
			ok = DebugUI_SetParseFile(argv[i]);
			break;

		case OPT_SAVECONFIG:
			/* Hatari-UI needs Hatari config to start */
			Configuration_Save();
			exit(0);
			break;

		case OPT_LOGLEVEL:
			i += 1;
			ConfigureParams.Log.nTextLogLevel = Log_ParseOptions(argv[i]);
			if (ConfigureParams.Log.nTextLogLevel == LOG_NONE)
			{
				return Opt_ShowError(OPT_LOGLEVEL, argv[i], "Unknown log level!");
			}
			break;

		case OPT_ALERTLEVEL:
			i += 1;
			ConfigureParams.Log.nAlertDlgLogLevel = Log_ParseOptions(argv[i]);
			if (ConfigureParams.Log.nAlertDlgLogLevel == LOG_NONE)
			{
				return Opt_ShowError(OPT_ALERTLEVEL, argv[i], "Unknown alert level!");
			}
			break;

		case OPT_RUNVBLS:
			Main_SetRunVBLs(atol(argv[++i]));
			break;
		       
		case OPT_ERROR:
			/* unknown option or missing option parameter */
			return false;

		default:
			return Opt_ShowError(OPT_ERROR, argv[i], "Internal Hatari error, unhandled option");
		}
		if (!ok)
		{
			/* Opt_Bool() or Opt_StrCpy() failed */
			return false;
		}
	}

	return true;
}
Example #5
0
/**
 * Handle last (non-option) argument.  It can be a path or filename.
 * Filename can be a disk image or Atari program.
 * Return false if it's none of these.
 */
static bool Opt_HandleArgument(const char *path)
{
	char *dir = NULL;
	Uint8 test[2];
	FILE *fp;

	/* Atari program? */
	if (File_Exists(path) && (fp = fopen(path, "rb"))) {

		/* file starts with GEMDOS magic? */
		if (fread(test, 1, 2, fp) == 2 &&
		    test[0] == 0x60 && test[1] == 0x1A) {

			const char *prgname = strrchr(path, PATHSEP);
			if (prgname) {
				dir = strdup(path);
				dir[prgname-path] = '\0';
				prgname++;
			} else {
				dir = strdup(Paths_GetWorkingDir());
				prgname = path;
			}
			/* after above, dir should point to valid dir,
			 * then make sure that given program from that
			 * dir will be started.
			 */
			TOS_AutoStart(prgname);
		}
		fclose(fp);
	}
	if (dir) {
		path = dir;
	}

	/* GEMDOS HDD directory (as argument, or for the Atari program)? */
	if (File_DirExists(path)) {
		if (Opt_StrCpy(OPT_HARDDRIVE, false, ConfigureParams.HardDisk.szHardDiskDirectories[0],
			       path, sizeof(ConfigureParams.HardDisk.szHardDiskDirectories[0]),
			       &ConfigureParams.HardDisk.bUseHardDiskDirectories)
		    && ConfigureParams.HardDisk.bUseHardDiskDirectories)
		{
			ConfigureParams.HardDisk.bBootFromHardDisk = true;
		}
		bLoadAutoSave = false;
		if (dir) {
			free(dir);
		}
		return true;
	} else {
		if (dir) {
			/* if dir is set, it should be valid... */
			Log_Printf(LOG_ERROR, "Given atari program path '%s' doesn't exist (anymore?)!\n", dir);
			free(dir);
			exit(1);
		}
	}

	/* disk image? */
	if (Floppy_SetDiskFileName(0, path, NULL))
	{
		ConfigureParams.HardDisk.bBootFromHardDisk = false;
		bLoadAutoSave = false;
		return true;
	}

	return Opt_ShowError(OPT_ERROR, path, "Not a disk image, Atari program or directory");
}
Example #6
0
/**
 * parse all Hatari command line options and set Hatari state accordingly.
 * Returns TRUE if everything was OK, FALSE otherwise.
 */
bool Opt_ParseParameters(int argc, const char *argv[])
{
	int ncpu, skips, zoom, planes, cpuclock, threshold, memsize, port;
	const char *errstr;
	int i, ok = TRUE;

	/* Defaults for loading initial memory snap-shots */
	bLoadMemorySave = FALSE;
	bLoadAutoSave = ConfigureParams.Memory.bAutoSave;

	for(i = 1; i < argc; i++)
	{
		if (argv[i][0] != '-')
		{
			if (Floppy_SetDiskFileName(0, argv[i], NULL))
			{
				ConfigureParams.HardDisk.bBootFromHardDisk = FALSE;
				bLoadAutoSave = FALSE;
			}
			else
				return Opt_ShowError(OPT_ERROR, argv[i], "Not an option nor disk image");
			continue;
		}
    
		/* WhichOption() checks also that there is an argument,
		 * so we don't need to check that below
		 */
		switch(Opt_WhichOption(argc, argv, i))
		{
		
			/* general options */
		case OPT_HELP:
			Opt_ShowHelp();
			return FALSE;
			
		case OPT_VERSION:
			Opt_ShowVersion();
			return FALSE;

		case OPT_CONFIRMQUIT:
			ok = Opt_Bool(argv[++i], OPT_CONFIRMQUIT, &ConfigureParams.Log.bConfirmQuit);
			break;

		case OPT_FASTFORWARD:
			ok = Opt_Bool(argv[++i], OPT_FASTFORWARD, &ConfigureParams.System.bFastForward);
			break;
			
		case OPT_CONFIGFILE:
			i += 1;
			ok = Opt_StrCpy(OPT_CONFIGFILE, TRUE, sConfigFileName,
					argv[i], sizeof(sConfigFileName), NULL);
			if (ok)
			{
				Configuration_Load(NULL);
				bLoadAutoSave = ConfigureParams.Memory.bAutoSave;
			}
			break;
		
			/* display options */
		case OPT_MONO:
			ConfigureParams.Screen.nMonitorType = MONITOR_TYPE_MONO;
			bLoadAutoSave = FALSE;
			break;

		case OPT_MONITOR:
			i += 1;
			if (strcasecmp(argv[i], "mono") == 0)
			{
				ConfigureParams.Screen.nMonitorType = MONITOR_TYPE_MONO;
			}
			else if (strcasecmp(argv[i], "rgb") == 0)
			{
				ConfigureParams.Screen.nMonitorType = MONITOR_TYPE_RGB;
			}
			else if (strcasecmp(argv[i], "vga") == 0)
			{
				ConfigureParams.Screen.nMonitorType = MONITOR_TYPE_VGA;
			}
			else if (strcasecmp(argv[i], "tv") == 0)
			{
				ConfigureParams.Screen.nMonitorType = MONITOR_TYPE_TV;
			}
			else
			{
				return Opt_ShowError(OPT_MONITOR, argv[i], "Unknown monitor type");
			}
			bLoadAutoSave = FALSE;
			break;
			
		case OPT_FULLSCREEN:
			ConfigureParams.Screen.bFullScreen = TRUE;
			break;
			
		case OPT_WINDOW:
			ConfigureParams.Screen.bFullScreen = FALSE;
			break;
			
		case OPT_ZOOM:
			zoom = atoi(argv[++i]);
			if (zoom < 1)
			{
				return Opt_ShowError(OPT_ZOOM, argv[i], "Invalid zoom value");
			}
			if (zoom > 1)
			{
				/* TODO: only doubling supported for now */
				ConfigureParams.Screen.bZoomLowRes = TRUE;
			}
			else
			{
				ConfigureParams.Screen.bZoomLowRes = FALSE;
			}
			break;
			
		case OPT_FRAMESKIPS:
			skips = atoi(argv[++i]);
			if (skips < 0)
			{
				return Opt_ShowError(OPT_FRAMESKIPS, argv[i],
						     "Invalid frame skip value");
			}
			else if (skips > 8)
			{
				Log_Printf(LOG_WARN, "Extravagant frame skip value %d!\n", skips);
			}
			ConfigureParams.Screen.nFrameSkips = skips;
			break;
			
		case OPT_BORDERS:
			ok = Opt_Bool(argv[++i], OPT_BORDERS, &ConfigureParams.Screen.bAllowOverscan);
			break;
			
		case OPT_STATUSBAR:
			ok = Opt_Bool(argv[++i], OPT_STATUSBAR, &ConfigureParams.Screen.bShowStatusbar);
			break;
			
		case OPT_DRIVE_LED:
			ok = Opt_Bool(argv[++i], OPT_DRIVE_LED, &ConfigureParams.Screen.bShowDriveLed);
			break;
			
		case OPT_SPEC512:
			threshold = atoi(argv[++i]);
			if (threshold < 0 || threshold > 512)
			{
				return Opt_ShowError(OPT_SPEC512, argv[i],
						     "Invalid palette writes per line threshold for Spec512");
			}
			ConfigureParams.Screen.nSpec512Threshold = threshold;
			break;
			
		case OPT_FORCEBPP:
			planes = atoi(argv[++i]);
			switch(planes)
			{
			case 32:
			case 16:
			case 15:
			case 8:
				break;       /* supported */
			case 24:
				planes = 32; /* We do not support 24 bpp (yet) */
				break;
			default:
				return Opt_ShowError(OPT_FORCEBPP, argv[i], "Invalid bit depth");
			}
			ConfigureParams.Screen.nForceBpp = planes;
			break;

			/* VDI options */
		case OPT_VDI:
			ok = Opt_Bool(argv[++i], OPT_VDI, &ConfigureParams.Screen.bUseExtVdiResolutions);
			if (ok)
			{
				bLoadAutoSave = FALSE;
			}
			break;

		case OPT_VDI_PLANES:
			planes = atoi(argv[++i]);
			switch(planes)
			{
			 case 1:
				ConfigureParams.Screen.nVdiColors = GEMCOLOR_2;
				break;
			 case 2:
				ConfigureParams.Screen.nVdiColors = GEMCOLOR_4;
				break;
			 case 4:
				ConfigureParams.Screen.nVdiColors = GEMCOLOR_16;
				break;
			 default:
				return Opt_ShowError(OPT_VDI_PLANES, argv[i], "Unsupported VDI bit-depth");
			}
			ConfigureParams.Screen.bUseExtVdiResolutions = TRUE;
			bLoadAutoSave = FALSE;
			break;

		case OPT_VDI_WIDTH:
			ConfigureParams.Screen.nVdiWidth = atoi(argv[++i]);
			ConfigureParams.Screen.bUseExtVdiResolutions = TRUE;
			bLoadAutoSave = FALSE;
			break;

		case OPT_VDI_HEIGHT:
			ConfigureParams.Screen.nVdiHeight = atoi(argv[++i]);
			ConfigureParams.Screen.bUseExtVdiResolutions = TRUE;
			bLoadAutoSave = FALSE;
			break;
		
			/* devices options */
		case OPT_JOYSTICK:
			i++;
			if (strlen(argv[i]) != 1 ||
			    !Joy_SetCursorEmulation(argv[i][0] - '0'))
			{
				return Opt_ShowError(OPT_JOYSTICK, argv[i], "Invalid joystick port");
			}
			break;

		case OPT_JOYSTICK0:
		case OPT_JOYSTICK1:
		case OPT_JOYSTICK2:
		case OPT_JOYSTICK3:
		case OPT_JOYSTICK4:
		case OPT_JOYSTICK5:
			port = argv[i][strlen(argv[i])-1] - '0';
			assert(port >= 0 && port < JOYSTICK_COUNT);
			i += 1;
			if (strcasecmp(argv[i], "none") == 0)
			{
				ConfigureParams.Joysticks.Joy[port].nJoystickMode = JOYSTICK_DISABLED;
			}
			else if (strcasecmp(argv[i], "keys") == 0)
			{
				ConfigureParams.Joysticks.Joy[port].nJoystickMode = JOYSTICK_KEYBOARD;
			}
			else if (strcasecmp(argv[i], "real") == 0)
			{
				ConfigureParams.Joysticks.Joy[port].nJoystickMode = JOYSTICK_REALSTICK;
			}
			else
			{
				return Opt_ShowError(OPT_JOYSTICK0+port, argv[i], "Invalid joystick type");
			}
			break;
			
		case OPT_PRINTER:
			i += 1;
			ok = Opt_StrCpy(OPT_PRINTER, FALSE, ConfigureParams.Printer.szPrintToFileName,
					argv[i], sizeof(ConfigureParams.Printer.szPrintToFileName),
					&ConfigureParams.Printer.bEnablePrinting);
			break;
			
		case OPT_MIDI_IN:
			i += 1;
			/* FALSE: "" can be used to disable midi input */
			ok = Opt_StrCpy(OPT_MIDI_IN, FALSE, ConfigureParams.Midi.sMidiInFileName,
					argv[i], sizeof(ConfigureParams.Midi.sMidiInFileName),
					&ConfigureParams.Midi.bEnableMidi);
			break;
			
		case OPT_MIDI_OUT:
			i += 1;
			ok = Opt_StrCpy(OPT_MIDI_OUT, TRUE, ConfigureParams.Midi.sMidiOutFileName,
					argv[i], sizeof(ConfigureParams.Midi.sMidiOutFileName),
					&ConfigureParams.Midi.bEnableMidi);
			break;
      
		case OPT_RS232_IN:
			i += 1;
			ok = Opt_StrCpy(OPT_RS232_IN, TRUE, ConfigureParams.RS232.szInFileName,
					argv[i], sizeof(ConfigureParams.RS232.szInFileName),
					&ConfigureParams.RS232.bEnableRS232);
			break;
      
		case OPT_RS232_OUT:
			i += 1;
			ok = Opt_StrCpy(OPT_RS232_OUT, TRUE, ConfigureParams.RS232.szOutFileName,
					argv[i], sizeof(ConfigureParams.RS232.szOutFileName),
					&ConfigureParams.RS232.bEnableRS232);
			break;

			/* disk options */
		case OPT_DISKA:
			i += 1;
			if (Floppy_SetDiskFileName(0, argv[i], NULL))
			{
				ConfigureParams.HardDisk.bBootFromHardDisk = FALSE;
				bLoadAutoSave = FALSE;
			}
			else
				return Opt_ShowError(OPT_ERROR, argv[i], "Not a disk image");
			break;

		case OPT_DISKB:
			i += 1;
			if (Floppy_SetDiskFileName(1, argv[i], NULL))
				bLoadAutoSave = FALSE;
			else
				return Opt_ShowError(OPT_ERROR, argv[i], "Not a disk image");
			break;

		case OPT_HARDDRIVE:
			i += 1;
			ok = Opt_StrCpy(OPT_HARDDRIVE, FALSE, ConfigureParams.HardDisk.szHardDiskDirectories[0],
					argv[i], sizeof(ConfigureParams.HardDisk.szHardDiskDirectories[0]),
					&ConfigureParams.HardDisk.bUseHardDiskDirectories);
			if (ok && ConfigureParams.HardDisk.bUseHardDiskDirectories)
			{
				ConfigureParams.HardDisk.bBootFromHardDisk = TRUE;
			}
			bLoadAutoSave = FALSE;
			break;

		case OPT_ACSIHDIMAGE:
			i += 1;
			ok = Opt_StrCpy(OPT_ACSIHDIMAGE, TRUE, ConfigureParams.HardDisk.szHardDiskImage,
					argv[i], sizeof(ConfigureParams.HardDisk.szHardDiskImage),
					&ConfigureParams.HardDisk.bUseHardDiskImage);
			if (ok)
			{
				bLoadAutoSave = FALSE;
			}
			break;
			
		case OPT_IDEHDIMAGE:
			i += 1;
			ok = Opt_StrCpy(OPT_IDEHDIMAGE, TRUE, ConfigureParams.HardDisk.szIdeHardDiskImage,
					argv[i], sizeof(ConfigureParams.HardDisk.szIdeHardDiskImage),
					&ConfigureParams.HardDisk.bUseIdeHardDiskImage);
			if (ok)
			{
				bLoadAutoSave = FALSE;
			}
			break;
			
		case OPT_SLOWFLOPPY:
			ok = Opt_Bool(argv[++i], OPT_SLOWFLOPPY, &ConfigureParams.DiskImage.bSlowFloppy);
			if (ok)
			{
				bLoadAutoSave = FALSE;
			}
			break;
			
			/* Memory options */
		case OPT_MEMSIZE:
			memsize = atoi(argv[++i]);
			if (memsize < 0 || memsize > 14)
			{
				return Opt_ShowError(OPT_MEMSIZE, argv[i], "Invalid memory size");
			}
			ConfigureParams.Memory.nMemorySize = memsize;
			bLoadAutoSave = FALSE;
			break;
      
		case OPT_TOS:
			i += 1;
			ok = Opt_StrCpy(OPT_TOS, TRUE, ConfigureParams.Rom.szTosImageFileName,
					argv[i], sizeof(ConfigureParams.Rom.szTosImageFileName),
					NULL);
			if (ok)
			{
				bLoadAutoSave = FALSE;
			}
			break;
			
		case OPT_CARTRIDGE:
			i += 1;
			ok = Opt_StrCpy(OPT_CARTRIDGE, TRUE, ConfigureParams.Rom.szCartridgeImageFileName,
					argv[i], sizeof(ConfigureParams.Rom.szCartridgeImageFileName),
					NULL);
			if (ok)
			{
				bLoadAutoSave = FALSE;
			}
			break;

		case OPT_MEMSTATE:
			i += 1;
			ok = Opt_StrCpy(OPT_MEMSTATE, TRUE, ConfigureParams.Memory.szMemoryCaptureFileName,
					argv[i], sizeof(ConfigureParams.Memory.szMemoryCaptureFileName),
					NULL);
			if (ok)
			{
				bLoadMemorySave = TRUE;
				bLoadAutoSave = FALSE;
			}
			break;
			
			/* CPU options */
		case OPT_CPULEVEL:
			/* UAE core uses cpu_level variable */
			ncpu = atoi(argv[++i]);
			if(ncpu < 0 || ncpu > 4)
			{
				return Opt_ShowError(OPT_CPULEVEL, argv[i], "Invalid CPU level");
			}
			ConfigureParams.System.nCpuLevel = ncpu;
			bLoadAutoSave = FALSE;
			break;
			
		case OPT_CPUCLOCK:
			cpuclock = atoi(argv[++i]);
			if(cpuclock != 8 && cpuclock != 16 && cpuclock != 32)
			{
				return Opt_ShowError(OPT_CPUCLOCK, argv[i], "Invalid CPU clock");
			}
			ConfigureParams.System.nCpuFreq = cpuclock;
			bLoadAutoSave = FALSE;
			break;
			
		case OPT_COMPATIBLE:
			ok = Opt_Bool(argv[++i], OPT_COMPATIBLE, &ConfigureParams.System.bCompatibleCpu);
			if (ok)
			{
				bLoadAutoSave = FALSE;
			}
			break;

			/* system options */
		case OPT_MACHINE:
			i += 1;
			if (strcasecmp(argv[i], "st") == 0)
			{
				ConfigureParams.System.nMachineType = MACHINE_ST;
				ConfigureParams.System.nCpuLevel = 0;
				ConfigureParams.System.nCpuFreq = 8;
			}
			else if (strcasecmp(argv[i], "ste") == 0)
			{
				ConfigureParams.System.nMachineType = MACHINE_STE;
				ConfigureParams.System.nCpuLevel = 0;
				ConfigureParams.System.nCpuFreq = 8;
			}
			else if (strcasecmp(argv[i], "tt") == 0)
			{
				ConfigureParams.System.nMachineType = MACHINE_TT;
				ConfigureParams.System.nCpuLevel = 3;
				ConfigureParams.System.nCpuFreq = 32;
			}
			else if (strcasecmp(argv[i], "falcon") == 0)
			{
				ConfigureParams.System.nMachineType = MACHINE_FALCON;
				ConfigureParams.System.nCpuLevel = 3;
				ConfigureParams.System.nCpuFreq = 16;
			}
			else
			{
				return Opt_ShowError(OPT_MACHINE, argv[i], "Unknown machine type");
			}
			bLoadAutoSave = FALSE;
			break;
			
		case OPT_BLITTER:
			ok = Opt_Bool(argv[++i], OPT_BLITTER, &ConfigureParams.System.bBlitter);
			if (ok)
			{
				bLoadAutoSave = FALSE;
			}
			break;			

		case OPT_DSP:
			i += 1;
			if (strcasecmp(argv[i], "none") == 0)
			{
				ConfigureParams.System.nDSPType = DSP_TYPE_NONE;
			}
			else if (strcasecmp(argv[i], "dummy") == 0)
			{
				ConfigureParams.System.nDSPType = DSP_TYPE_DUMMY;
			}
			else if (strcasecmp(argv[i], "emu") == 0)
			{
#if ENABLE_DSP_EMU
				ConfigureParams.System.nDSPType = DSP_TYPE_EMU;
#else
				return Opt_ShowError(OPT_DSP, argv[i], "DSP type 'emu' support not compiled in");
#endif
			}
			else
			{
				return Opt_ShowError(OPT_DSP, argv[i], "Unknown DSP type");
			}
			bLoadAutoSave = FALSE;
			break;
			
		case OPT_SOUND:
			i += 1;
			if (strcasecmp(argv[i], "off") == 0)
			{
				ConfigureParams.Sound.bEnableSound = FALSE;
			}
			else if (strcasecmp(argv[i], "low") == 0)
			{
				ConfigureParams.Sound.nPlaybackFreq = 11025;
				ConfigureParams.Sound.bEnableSound = TRUE;
			}
			else if (strcasecmp(argv[i], "med") == 0)
			{
				ConfigureParams.Sound.nPlaybackFreq = 22050;
				ConfigureParams.Sound.bEnableSound = TRUE;
			}
			else if (strcasecmp(argv[i], "hi") == 0)
			{
				ConfigureParams.Sound.nPlaybackFreq = 44100;
				ConfigureParams.Sound.bEnableSound = TRUE;
			}
			else
			{
				return Opt_ShowError(OPT_SOUND, argv[i], "Unsupported sound quality");
			}
			break;

		case OPT_KEYMAPFILE:
			i += 1;
			ok = Opt_StrCpy(OPT_KEYMAPFILE, TRUE, ConfigureParams.Keyboard.szMappingFileName,
					argv[i], sizeof(ConfigureParams.Keyboard.szMappingFileName),
					NULL);
			if (ok)
			{
				ConfigureParams.Keyboard.nKeymapType = KEYMAP_LOADED;
			}
			break;
			
			/* debug options */
		case OPT_DEBUG:
			if (bEnableDebug)
			{
				/* called at run time (e.g. from debugger) */
				fprintf(stderr, "Debug mode disabled.\n");
				bEnableDebug = FALSE;
			}
			else
			{
				bEnableDebug = TRUE;
			}
			break;

		case OPT_BIOSINTERCEPT:
			bBiosIntercept = TRUE;
			break;
			
		case OPT_TRACE:
			i += 1;
			if (Log_SetTraceOptions(argv[i]) == 0)
			{
				return Opt_ShowError(OPT_TRACE, argv[i], "Error parsing trace options (use --trace help for available list)!");
			}
			break;

		case OPT_TRACEFILE:
			i += 1;
			ok = Opt_StrCpy(OPT_TRACEFILE, FALSE, ConfigureParams.Log.sTraceFileName,
					argv[i], sizeof(ConfigureParams.Log.sTraceFileName),
					NULL);
			break;

		case OPT_CONTROLSOCKET:
			i += 1;
			errstr = Control_SetSocket(argv[i]);
			if (errstr)
			{
				return Opt_ShowError(OPT_CONTROLSOCKET, argv[i], errstr);
			}
			break;

		case OPT_LOGFILE:
			i += 1;
			ok = Opt_StrCpy(OPT_LOGFILE, FALSE, ConfigureParams.Log.sLogFileName,
					argv[i], sizeof(ConfigureParams.Log.sLogFileName),
					NULL);
			break;

		case OPT_LOGLEVEL:
			i += 1;
			ConfigureParams.Log.nTextLogLevel = Log_ParseOptions(argv[i]);
			if (ConfigureParams.Log.nTextLogLevel == LOG_NONE)
			{
				return Opt_ShowError(OPT_LOGLEVEL, argv[i], "Unknown log level!");
			}
			break;

		case OPT_ALERTLEVEL:
			i += 1;
			ConfigureParams.Log.nAlertDlgLogLevel = Log_ParseOptions(argv[i]);
			if (ConfigureParams.Log.nAlertDlgLogLevel == LOG_NONE)
			{
				return Opt_ShowError(OPT_ALERTLEVEL, argv[i], "Unknown alert level!");
			}
			break;

		case OPT_RUNVBLS:
			nRunVBLs = atol(argv[++i]);
			break;
		       
		case OPT_ERROR:
			/* unknown option or missing option parameter */
			return FALSE;

		default:
			return Opt_ShowError(OPT_ERROR, argv[i], "Internal Hatari error, unhandled option");
		}
		if (!ok)
		{
			/* Opt_Bool() or Opt_StrCpy() failed */
			return FALSE;
		}
	}

	return TRUE;
}