|
|
1.1 root 1: /*
2: Hatari - change.c
3:
1.1.1.8 root 4: This file is distributed under the GNU General Public License, version 2
5: or at your option any later version. Read the file gpl.txt for details.
1.1 root 6:
7: This code handles run-time configuration changes. We keep all our
8: configuration details in a structure called 'ConfigureParams'. Before
9: doing he changes, a backup copy is done of this structure. When
10: the changes are done, these are compared to see whether emulator
1.1.1.2 root 11: needs to be rebooted
1.1 root 12: */
1.1.1.2 root 13: const char Change_fileid[] = "Hatari change.c : " __DATE__ " " __TIME__;
1.1 root 14:
15: #include <ctype.h>
16: #include "main.h"
17: #include "configuration.h"
18: #include "audio.h"
19: #include "change.h"
20: #include "dialog.h"
21: #include "floppy.h"
1.1.1.9 root 22: #include "fdc.h"
1.1 root 23: #include "gemdos.h"
24: #include "hdc.h"
1.1.1.3 root 25: #include "ide.h"
1.1 root 26: #include "ioMem.h"
27: #include "joy.h"
28: #include "keymap.h"
29: #include "m68000.h"
1.1.1.2 root 30: #include "midi.h"
1.1 root 31: #include "options.h"
32: #include "printer.h"
33: #include "reset.h"
34: #include "rs232.h"
1.1.1.13! root 35: #include "scc.h"
1.1 root 36: #include "screen.h"
37: #include "sound.h"
38: #include "statusbar.h"
39: #include "tos.h"
40: #include "vdi.h"
41: #include "video.h"
42: #include "hatari-glue.h"
43: #if ENABLE_DSP_EMU
44: # include "falcon/dsp.h"
45: #endif
46:
1.1.1.5 root 47: #define DEBUG 0
48: #if DEBUG
1.1.1.11 root 49: #define Dprintf(...) printf(__VA_ARGS__)
1.1.1.5 root 50: #else
1.1.1.11 root 51: #define Dprintf(...)
1.1.1.5 root 52: #endif
1.1 root 53:
54: /*-----------------------------------------------------------------------*/
55: /**
56: * Check if user needs to be warned that changes will take place after reset.
1.1.1.3 root 57: * Return true if wants to reset.
1.1 root 58: */
59: bool Change_DoNeedReset(CNF_PARAMS *current, CNF_PARAMS *changed)
60: {
1.1.1.9 root 61: int i;
62:
1.1 root 63: /* Did we change monitor type? If so, must reset */
64: if (current->Screen.nMonitorType != changed->Screen.nMonitorType
65: && (changed->System.nMachineType == MACHINE_FALCON
66: || current->Screen.nMonitorType == MONITOR_TYPE_MONO
67: || changed->Screen.nMonitorType == MONITOR_TYPE_MONO))
1.1.1.3 root 68: return true;
1.1 root 69:
70: /* Did change to GEM VDI display? */
71: if (current->Screen.bUseExtVdiResolutions != changed->Screen.bUseExtVdiResolutions)
1.1.1.3 root 72: return true;
1.1 root 73:
74: /* Did change GEM resolution or color depth? */
75: if (changed->Screen.bUseExtVdiResolutions &&
76: (current->Screen.nVdiWidth != changed->Screen.nVdiWidth
77: || current->Screen.nVdiHeight != changed->Screen.nVdiHeight
78: || current->Screen.nVdiColors != changed->Screen.nVdiColors))
1.1.1.3 root 79: return true;
1.1 root 80:
81: /* Did change TOS ROM image? */
82: if (strcmp(changed->Rom.szTosImageFileName, current->Rom.szTosImageFileName))
1.1.1.3 root 83: return true;
1.1 root 84:
1.1.1.3 root 85: /* Did change ACSI hard disk image? */
1.1.1.9 root 86: for (i = 0; i < MAX_ACSI_DEVS; i++)
87: {
88: if (changed->Acsi[i].bUseDevice != current->Acsi[i].bUseDevice
89: || (strcmp(changed->Acsi[i].sDeviceFile, current->Acsi[i].sDeviceFile)
90: && changed->Acsi[i].bUseDevice))
91: return true;
92: }
1.1.1.3 root 93:
1.1.1.13! root 94: /* Did change SCSI hard disk image? */
! 95: for (i = 0; i < MAX_SCSI_DEVS; i++)
! 96: {
! 97: if (changed->Scsi[i].bUseDevice != current->Scsi[i].bUseDevice
! 98: || (strcmp(changed->Scsi[i].sDeviceFile, current->Scsi[i].sDeviceFile)
! 99: && changed->Scsi[i].bUseDevice))
! 100: return true;
! 101: }
1.1.1.4 root 102:
1.1.1.13! root 103: /* Did change IDE hard disk image? */
! 104: for (i = 0; i < MAX_IDE_DEVS; i++)
! 105: {
! 106: if (changed->Ide[i].bUseDevice != current->Ide[i].bUseDevice
! 107: || changed->Ide[i].nByteSwap != current->Ide[i].nByteSwap
! 108: || (strcmp(changed->Ide[i].sDeviceFile, current->Ide[i].sDeviceFile)
! 109: && changed->Ide[i].bUseDevice))
! 110: return true;
! 111: }
1.1 root 112:
1.1.1.10 root 113: /* Did change GEMDOS drive Atari/host location or enabling? */
114: if (changed->HardDisk.nGemdosDrive != current->HardDisk.nGemdosDrive
115: || changed->HardDisk.bUseHardDiskDirectories != current->HardDisk.bUseHardDiskDirectories
1.1 root 116: || (strcmp(changed->HardDisk.szHardDiskDirectories[0], current->HardDisk.szHardDiskDirectories[0])
117: && changed->HardDisk.bUseHardDiskDirectories))
1.1.1.3 root 118: return true;
1.1 root 119:
120: /* Did change machine type? */
121: if (changed->System.nMachineType != current->System.nMachineType)
1.1.1.3 root 122: return true;
1.1.1.8 root 123: /* did change ST Blitter? */
124: else if (current->System.nMachineType == MACHINE_ST &&
125: current->System.bBlitter != changed->System.bBlitter)
126: return true;
1.1 root 127:
1.1.1.5 root 128: #if ENABLE_DSP_EMU
129: /* enabling DSP needs reset (disabling it not) */
130: if (current->System.nDSPType != DSP_TYPE_EMU &&
131: changed->System.nDSPType == DSP_TYPE_EMU)
132: return true;
133: #endif
134:
1.1.1.8 root 135: /* did change CPU type? */
136: if (changed->System.nCpuLevel != current->System.nCpuLevel)
137: return true;
138:
1.1.1.5 root 139: #if ENABLE_WINUAE_CPU
1.1.1.6 root 140: /* Did change CPU address mode? */
141: if (changed->System.bAddressSpace24 != current->System.bAddressSpace24)
142: return true;
143:
1.1.1.5 root 144: /* Did change CPU prefetch mode? */
145: if (changed->System.bCompatibleCpu != current->System.bCompatibleCpu)
146: return true;
147:
148: /* Did change CPU cycle exact? */
149: if (changed->System.bCycleExactCpu != current->System.bCycleExactCpu)
150: return true;
151:
152: /* Did change MMU? */
153: if (changed->System.bMMU != current->System.bMMU)
154: return true;
1.1.1.7 root 155:
156: /* Did change FPU? */
157: if (changed->System.n_FPUType != current->System.n_FPUType)
158: return true;
1.1.1.10 root 159:
160: /* Did change size of TT-RAM? */
1.1.1.12 root 161: if (current->Memory.TTRamSize_KB != changed->Memory.TTRamSize_KB)
1.1.1.10 root 162: return true;
1.1.1.5 root 163: #endif
164:
1.1 root 165: /* Did change size of memory? */
1.1.1.12 root 166: if (current->Memory.STRamSize_KB != changed->Memory.STRamSize_KB)
1.1.1.3 root 167: return true;
1.1 root 168:
1.1.1.8 root 169: /* MIDI related IRQs start/stop needs reset */
170: if (current->Midi.bEnableMidi != changed->Midi.bEnableMidi)
171: return true;
172:
1.1.1.3 root 173: return false;
1.1 root 174: }
175:
176:
177: /*-----------------------------------------------------------------------*/
178: /**
179: * Copy details back to configuration and perform reset.
180: */
181: void Change_CopyChangedParamsToConfiguration(CNF_PARAMS *current, CNF_PARAMS *changed, bool bForceReset)
182: {
183: bool NeedReset;
1.1.1.3 root 184: bool bReInitGemdosDrive = false;
1.1.1.13! root 185: bool bReInitHdcEmu = false;
1.1.1.3 root 186: bool bReInitIDEEmu = false;
187: bool bReInitIoMem = false;
188: bool bScreenModeChange = false;
189: bool bReInitMidi = false;
1.1.1.7 root 190: bool bReInitPrinter = false;
1.1 root 191: bool bFloppyInsert[MAX_FLOPPYDRIVES];
192: int i;
193:
1.1.1.5 root 194: Dprintf("Changes for:\n");
1.1 root 195: /* Do we need to warn user that changes will only take effect after reset? */
196: if (bForceReset)
197: NeedReset = bForceReset;
198: else
199: NeedReset = Change_DoNeedReset(current, changed);
200:
201: /* Do need to change resolution? Need if change display/overscan settings
202: * (if switch between Colour/Mono cause reset later) or toggle statusbar
203: */
204: if (!NeedReset &&
205: (changed->Screen.nForceBpp != current->Screen.nForceBpp
1.1.1.4 root 206: || changed->Screen.bAspectCorrect != current->Screen.bAspectCorrect
207: || changed->Screen.nMaxWidth != current->Screen.nMaxWidth
208: || changed->Screen.nMaxHeight != current->Screen.nMaxHeight
1.1 root 209: || changed->Screen.bAllowOverscan != current->Screen.bAllowOverscan
1.1.1.10 root 210: || changed->Screen.bShowStatusbar != current->Screen.bShowStatusbar
211: #if WITH_SDL2
212: || changed->Screen.nRenderScaleQuality != current->Screen.nRenderScaleQuality
1.1.1.12 root 213: || changed->Screen.bResizable != current->Screen.bResizable
1.1.1.10 root 214: || changed->Screen.bUseVsync != current->Screen.bUseVsync
215: #endif
216: ))
1.1 root 217: {
1.1.1.5 root 218: Dprintf("- screenmode>\n");
1.1.1.3 root 219: bScreenModeChange = true;
1.1 root 220: }
221:
222: /* Did set new printer parameters? */
223: if (changed->Printer.bEnablePrinting != current->Printer.bEnablePrinting
224: || strcmp(changed->Printer.szPrintToFileName,current->Printer.szPrintToFileName))
225: {
1.1.1.5 root 226: Dprintf("- printer>\n");
1.1.1.7 root 227: Printer_UnInit();
228: bReInitPrinter = true;
1.1 root 229: }
230:
231: /* Did set new RS232 parameters? */
232: if (changed->RS232.bEnableRS232 != current->RS232.bEnableRS232
233: || strcmp(changed->RS232.szOutFileName, current->RS232.szOutFileName)
234: || strcmp(changed->RS232.szInFileName, current->RS232.szInFileName))
235: {
1.1.1.5 root 236: Dprintf("- RS-232>\n");
1.1 root 237: RS232_UnInit();
238: }
239:
1.1.1.13! root 240: /* Did set new SCC parameters? */
! 241: if (changed->RS232.bEnableSccB != current->RS232.bEnableSccB
! 242: || strcmp(changed->RS232.sSccBInFileName, current->RS232.sSccBInFileName)
! 243: || strcmp(changed->RS232.sSccBOutFileName, current->RS232.sSccBOutFileName)
! 244: || (SCC_IsAvailable(current) && !SCC_IsAvailable(changed)))
! 245: {
! 246: Dprintf("- SCC>\n");
! 247: SCC_UnInit();
! 248: }
! 249:
1.1 root 250: /* Did stop sound? Or change playback Hz. If so, also stop sound recording */
1.1.1.3 root 251: if (!changed->Sound.bEnableSound || changed->Sound.nPlaybackFreq != current->Sound.nPlaybackFreq)
1.1 root 252: {
1.1.1.5 root 253: Dprintf("- sound>\n");
1.1 root 254: if (Sound_AreWeRecording())
255: Sound_EndRecording();
256: Audio_UnInit();
257: }
258:
259: /* Did change floppy (images)? */
260: for (i = 0; i < MAX_FLOPPYDRIVES; i++)
261: {
262: /*
263: Log_Printf(LOG_DEBUG, "Old and new disk %c:\n\t%s\n\t%s", 'A'+i,
264: current->DiskImage.szDiskFileName[i],
265: changed->DiskImage.szDiskFileName[i]);
266: */
267: if (strcmp(changed->DiskImage.szDiskFileName[i],
268: current->DiskImage.szDiskFileName[i])
269: || strcmp(changed->DiskImage.szDiskZipPath[i],
270: current->DiskImage.szDiskZipPath[i]))
1.1.1.3 root 271: bFloppyInsert[i] = true;
1.1 root 272: else
1.1.1.3 root 273: bFloppyInsert[i] = false;
1.1 root 274: }
275:
1.1.1.9 root 276: if ( changed->DiskImage.EnableDriveA != current->DiskImage.EnableDriveA )
277: FDC_Drive_Set_Enable ( 0 , changed->DiskImage.EnableDriveA );
278: if ( changed->DiskImage.EnableDriveB != current->DiskImage.EnableDriveB )
279: FDC_Drive_Set_Enable ( 1 , changed->DiskImage.EnableDriveB );
280:
281: if ( changed->DiskImage.DriveA_NumberOfHeads != current->DiskImage.DriveA_NumberOfHeads )
282: FDC_Drive_Set_NumberOfHeads ( 0 , changed->DiskImage.DriveA_NumberOfHeads );
283: if ( changed->DiskImage.DriveB_NumberOfHeads != current->DiskImage.DriveB_NumberOfHeads )
284: FDC_Drive_Set_NumberOfHeads ( 1 , changed->DiskImage.DriveB_NumberOfHeads );
285:
1.1.1.10 root 286: /* Did change GEMDOS drive Atari/host location or enabling? */
287: if (changed->HardDisk.nGemdosDrive != current->HardDisk.nGemdosDrive
288: || changed->HardDisk.bUseHardDiskDirectories != current->HardDisk.bUseHardDiskDirectories
1.1 root 289: || (strcmp(changed->HardDisk.szHardDiskDirectories[0], current->HardDisk.szHardDiskDirectories[0])
290: && changed->HardDisk.bUseHardDiskDirectories))
291: {
1.1.1.5 root 292: Dprintf("- gemdos HD>\n");
1.1 root 293: GemDOS_UnInitDrives();
1.1.1.3 root 294: bReInitGemdosDrive = true;
1.1 root 295: }
296:
1.1.1.9 root 297: /* Did change ACSI image? */
298: for (i = 0; i < MAX_ACSI_DEVS; i++)
1.1 root 299: {
1.1.1.9 root 300: if (changed->Acsi[i].bUseDevice != current->Acsi[i].bUseDevice
301: || (strcmp(changed->Acsi[i].sDeviceFile, current->Acsi[i].sDeviceFile)
302: && changed->Acsi[i].bUseDevice))
303: {
304: Dprintf("- ACSI image %i>\n", i);
1.1.1.13! root 305: bReInitHdcEmu = true;
1.1.1.9 root 306: }
1.1.1.3 root 307: }
1.1.1.13! root 308: /* Did change SCSI image? */
! 309: for (i = 0; i < MAX_SCSI_DEVS; i++)
1.1.1.4 root 310: {
1.1.1.13! root 311: if (changed->Scsi[i].bUseDevice != current->Scsi[i].bUseDevice
! 312: || (strcmp(changed->Scsi[i].sDeviceFile, current->Scsi[i].sDeviceFile)
! 313: && changed->Scsi[i].bUseDevice))
! 314: {
! 315: Dprintf("- SCSI image %i>\n", i);
! 316: bReInitHdcEmu = true;
! 317: }
1.1.1.4 root 318: }
1.1.1.13! root 319: if (bReInitHdcEmu)
! 320: HDC_UnInit();
1.1.1.4 root 321:
1.1.1.13! root 322: /* Did change IDE HD image? */
! 323: for (i = 0; i < MAX_IDE_DEVS; i++)
1.1.1.3 root 324: {
1.1.1.13! root 325: if (changed->Ide[i].bUseDevice != current->Ide[i].bUseDevice
! 326: || (strcmp(changed->Ide[i].sDeviceFile, current->Ide[i].sDeviceFile)
! 327: && changed->Ide[i].bUseDevice))
! 328: {
! 329: Dprintf("- IDE image %i>\n", i);
! 330: bReInitIDEEmu = true;
! 331: }
1.1 root 332: }
1.1.1.13! root 333: if (bReInitIDEEmu)
! 334: Ide_UnInit();
1.1 root 335:
1.1.1.11 root 336: /* Did change blitter, DSP or system type? */
1.1 root 337: if (changed->System.bBlitter != current->System.bBlitter
338: #if ENABLE_DSP_EMU
339: || changed->System.nDSPType != current->System.nDSPType
340: #endif
341: || changed->System.nMachineType != current->System.nMachineType)
342: {
1.1.1.11 root 343: Dprintf("- blitter/dsp/machine>\n");
1.1 root 344: IoMem_UnInit();
1.1.1.3 root 345: bReInitIoMem = true;
1.1 root 346: }
347:
348: #if ENABLE_DSP_EMU
349: /* Disabled DSP? */
1.1.1.3 root 350: if (current->System.nDSPType == DSP_TYPE_EMU &&
351: changed->System.nDSPType != DSP_TYPE_EMU)
1.1 root 352: {
1.1.1.5 root 353: Dprintf("- DSP>\n");
1.1.1.10 root 354: DSP_Disable();
1.1 root 355: }
356: #endif
357:
1.1.1.2 root 358: /* Did change MIDI settings? */
359: if (current->Midi.bEnableMidi != changed->Midi.bEnableMidi
1.1.1.12 root 360: #ifdef HAVE_PORTMIDI
361: || strcmp(changed->Midi.sMidiOutPortName, current->Midi.sMidiOutPortName)
362: || strcmp(changed->Midi.sMidiInPortName, current->Midi.sMidiInPortName)
363: #else
364: || strcmp(changed->Midi.sMidiOutFileName, current->Midi.sMidiOutFileName)
365: || strcmp(changed->Midi.sMidiInFileName, current->Midi.sMidiInFileName)
366: #endif
367: )
1.1.1.2 root 368: {
1.1.1.5 root 369: Dprintf("- midi>\n");
1.1.1.2 root 370: Midi_UnInit();
371: bReInitMidi = true;
372: }
373:
1.1 root 374: /* Copy details to configuration,
375: * so it can be saved out or set on reset
376: */
377: if (changed != &ConfigureParams)
378: {
379: ConfigureParams = *changed;
380: }
381:
382: /* Copy details to global, if we reset copy them all */
383: Configuration_Apply(NeedReset);
384:
385: #if ENABLE_DSP_EMU
1.1.1.3 root 386: if (current->System.nDSPType != DSP_TYPE_EMU &&
387: changed->System.nDSPType == DSP_TYPE_EMU)
1.1 root 388: {
1.1.1.5 root 389: Dprintf("- DSP<\n");
1.1.1.10 root 390: DSP_Enable();
1.1 root 391: }
392: #endif
393:
394: /* Set keyboard remap file */
395: if (ConfigureParams.Keyboard.nKeymapType == KEYMAP_LOADED)
1.1.1.5 root 396: {
397: Dprintf("- keymap<\n");
1.1 root 398: Keymap_LoadRemapFile(ConfigureParams.Keyboard.szMappingFileName);
1.1.1.5 root 399: }
1.1 root 400:
1.1.1.13! root 401: /* Mount a new ACSI/SCSI HD images: */
! 402: if (bReInitHdcEmu)
1.1 root 403: {
1.1.1.5 root 404: Dprintf("- HD<\n");
1.1.1.4 root 405: HDC_Init();
1.1 root 406: }
407:
1.1.1.13! root 408: /* Mount a new IDE HD images: */
! 409: if (bReInitIDEEmu && (ConfigureParams.Ide[0].bUseDevice || ConfigureParams.Ide[1].bUseDevice))
1.1.1.3 root 410: {
1.1.1.5 root 411: Dprintf("- IDE<\n");
1.1.1.3 root 412: Ide_Init();
413: }
414:
1.1 root 415: /* Insert floppies? */
416: for (i = 0; i < MAX_FLOPPYDRIVES; i++)
417: {
418: if (bFloppyInsert[i])
1.1.1.5 root 419: {
420: Dprintf("- floppy<\n");
1.1 root 421: Floppy_InsertDiskIntoDrive(i);
1.1.1.5 root 422: }
1.1 root 423: }
424:
425: /* Mount a new GEMDOS drive? */
426: if (bReInitGemdosDrive && ConfigureParams.HardDisk.bUseHardDiskDirectories)
427: {
1.1.1.5 root 428: Dprintf("- gemdos HD<\n");
1.1 root 429: GemDOS_InitDrives();
430: }
431:
432: /* Restart audio sub system if necessary: */
433: if (ConfigureParams.Sound.bEnableSound && !bSoundWorking)
434: {
1.1.1.5 root 435: Dprintf("- audio<\n");
1.1 root 436: Audio_Init();
437: }
438:
439: /* Re-initialize the RS232 emulation: */
1.1.1.7 root 440: if (ConfigureParams.RS232.bEnableRS232)
1.1 root 441: {
1.1.1.5 root 442: Dprintf("- RS-232<\n");
1.1 root 443: RS232_Init();
444: }
445:
1.1.1.13! root 446: /* Re-initialize the SCC emulation: */
! 447: if (ConfigureParams.RS232.bEnableSccB)
! 448: {
! 449: Dprintf("- SCC<\n");
! 450: SCC_Init();
! 451: }
! 452:
1.1 root 453: /* Re-init IO memory map? */
454: if (bReInitIoMem)
455: {
1.1.1.5 root 456: Dprintf("- IO mem<\n");
1.1 root 457: IoMem_Init();
458: }
459:
1.1.1.7 root 460: /* Re-init Printer emulation? */
461: if (bReInitPrinter)
462: {
463: Dprintf("- printer<\n");
464: Printer_Init();
465: }
466:
1.1.1.2 root 467: /* Re-init MIDI emulation? */
468: if (bReInitMidi)
469: {
1.1.1.5 root 470: Dprintf("- midi<\n");
1.1.1.2 root 471: Midi_Init();
472: }
473:
1.1 root 474: /* Force things associated with screen change */
475: if (bScreenModeChange)
476: {
1.1.1.5 root 477: Dprintf("- screenmode<\n");
1.1.1.10 root 478: Screen_ModeChanged(true);
1.1 root 479: }
480:
481: /* Do we need to perform reset? */
482: if (NeedReset)
483: {
1.1.1.5 root 484: Dprintf("- reset\n");
1.1 root 485: Reset_Cold();
486: }
487:
488: /* Go into/return from full screen if flagged */
489: if (!bInFullScreen && ConfigureParams.Screen.bFullScreen)
490: Screen_EnterFullScreen();
491: else if (bInFullScreen && !ConfigureParams.Screen.bFullScreen)
492: Screen_ReturnFromFullScreen();
1.1.1.4 root 493:
494: /* update statusbar info (CPU, MHz, mem etc) */
495: Statusbar_UpdateInfo();
1.1.1.5 root 496: Dprintf("done.\n");
1.1 root 497: }
498:
499:
500: /*-----------------------------------------------------------------------*/
501: /**
502: * Change given Hatari options
1.1.1.3 root 503: * Return false if parsing failed, true otherwise
1.1 root 504: */
505: static bool Change_Options(int argc, const char *argv[])
506: {
507: bool bOK;
508: CNF_PARAMS current;
509:
1.1.1.3 root 510: Main_PauseEmulation(false);
1.1 root 511:
512: /* get configuration changes */
513: current = ConfigureParams;
514: ConfigureParams.Screen.bFullScreen = bInFullScreen;
515: bOK = Opt_ParseParameters(argc, argv);
516:
517: /* Check if reset is required and ask user if he really wants to continue */
518: if (bOK && Change_DoNeedReset(¤t, &ConfigureParams)
1.1.1.5 root 519: && current.Log.nAlertDlgLogLevel > LOG_FATAL) {
1.1 root 520: bOK = DlgAlert_Query("The emulated system must be "
521: "reset to apply these changes. "
522: "Apply changes now and reset "
523: "the emulator?");
524: }
525: /* Copy details to configuration */
526: if (bOK) {
1.1.1.3 root 527: Change_CopyChangedParamsToConfiguration(¤t, &ConfigureParams, false);
1.1 root 528: } else {
529: ConfigureParams = current;
530: }
531:
532: Main_UnPauseEmulation();
533: return bOK;
534: }
535:
536:
537: /*-----------------------------------------------------------------------*/
538: /**
1.1.1.7 root 539: * Parse given command line and change Hatari options accordingly.
540: * Given string must be stripped and not empty.
1.1.1.3 root 541: * Return false if parsing failed or there were no args, true otherwise
1.1 root 542: */
543: bool Change_ApplyCommandline(char *cmdline)
544: {
545: int i, argc, inarg;
546: const char **argv;
547: bool ret;
548:
549: /* count args */
550: inarg = argc = 0;
551: for (i = 0; cmdline[i]; i++)
552: {
1.1.1.9 root 553: if (isspace((unsigned char)cmdline[i]) && cmdline[i-1] != '\\')
1.1 root 554: {
555: inarg = 0;
556: continue;
557: }
558: if (!inarg)
559: {
560: inarg++;
561: argc++;
562: }
563: }
564: if (!argc)
565: {
1.1.1.3 root 566: return false;
1.1 root 567: }
568: /* 2 = "hatari" + NULL */
569: argv = malloc((argc+2) * sizeof(char*));
570: if (!argv)
571: {
572: perror("command line alloc");
1.1.1.3 root 573: return false;
1.1 root 574: }
575:
576: /* parse them to array */
577: fprintf(stderr, "Command line with '%d' arguments:\n", argc);
578: inarg = argc = 0;
579: argv[argc++] = "hatari";
580: for (i = 0; cmdline[i]; i++)
581: {
1.1.1.9 root 582: if (isspace((unsigned char)cmdline[i]))
1.1 root 583: {
1.1.1.7 root 584: if (cmdline[i-1] != '\\')
1.1 root 585: {
1.1.1.7 root 586: cmdline[i] = '\0';
587: if (inarg)
588: {
589: fprintf(stderr, "- '%s'\n", argv[argc-1]);
590: }
591: inarg = 0;
592: continue;
593: }
594: else
595: {
596: /* remove quote for space */
597: memcpy(cmdline+i-1, cmdline+i, strlen(cmdline+i)+1);
598: i--;
1.1 root 599: }
600: }
601: if (!inarg)
602: {
603: argv[argc++] = &(cmdline[i]);
604: inarg++;
605: }
606: }
607: if (inarg)
608: {
609: fprintf(stderr, "- '%s'\n", argv[argc-1]);
610: }
611: argv[argc] = NULL;
612:
613: /* do args */
614: ret = Change_Options(argc, argv);
1.1.1.3 root 615: free((void *)argv);
1.1 root 616: return ret;
617: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.