|
|
1.1 root 1: /*
2: Hatari - change.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: 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"
22: #include "gemdos.h"
23: #include "hdc.h"
1.1.1.3 ! root 24: #include "ide.h"
1.1 root 25: #include "ioMem.h"
26: #include "joy.h"
27: #include "keymap.h"
28: #include "m68000.h"
1.1.1.2 root 29: #include "midi.h"
1.1 root 30: #include "options.h"
31: #include "printer.h"
32: #include "reset.h"
33: #include "rs232.h"
34: #include "screen.h"
35: #include "sound.h"
36: #include "statusbar.h"
37: #include "tos.h"
38: #include "vdi.h"
39: #include "video.h"
40: #include "hatari-glue.h"
41: #if ENABLE_DSP_EMU
42: # include "falcon/dsp.h"
43: #endif
44:
45:
46: /*-----------------------------------------------------------------------*/
47: /**
48: * Check if user needs to be warned that changes will take place after reset.
1.1.1.3 ! root 49: * Return true if wants to reset.
1.1 root 50: */
51: bool Change_DoNeedReset(CNF_PARAMS *current, CNF_PARAMS *changed)
52: {
53: /* Did we change monitor type? If so, must reset */
54: if (current->Screen.nMonitorType != changed->Screen.nMonitorType
55: && (changed->System.nMachineType == MACHINE_FALCON
56: || current->Screen.nMonitorType == MONITOR_TYPE_MONO
57: || changed->Screen.nMonitorType == MONITOR_TYPE_MONO))
1.1.1.3 ! root 58: return true;
1.1 root 59:
60: /* Did change to GEM VDI display? */
61: if (current->Screen.bUseExtVdiResolutions != changed->Screen.bUseExtVdiResolutions)
1.1.1.3 ! root 62: return true;
1.1 root 63:
64: /* Did change GEM resolution or color depth? */
65: if (changed->Screen.bUseExtVdiResolutions &&
66: (current->Screen.nVdiWidth != changed->Screen.nVdiWidth
67: || current->Screen.nVdiHeight != changed->Screen.nVdiHeight
68: || current->Screen.nVdiColors != changed->Screen.nVdiColors))
1.1.1.3 ! root 69: return true;
1.1 root 70:
71: /* Did change TOS ROM image? */
72: if (strcmp(changed->Rom.szTosImageFileName, current->Rom.szTosImageFileName))
1.1.1.3 ! root 73: return true;
1.1 root 74:
1.1.1.3 ! root 75: /* Did change ACSI hard disk image? */
1.1 root 76: if (changed->HardDisk.bUseHardDiskImage != current->HardDisk.bUseHardDiskImage
77: || (strcmp(changed->HardDisk.szHardDiskImage, current->HardDisk.szHardDiskImage)
78: && changed->HardDisk.bUseHardDiskImage))
1.1.1.3 ! root 79: return true;
! 80:
! 81: /* Did change IDE hard disk image? */
! 82: if (changed->HardDisk.bUseIdeHardDiskImage != current->HardDisk.bUseIdeHardDiskImage
! 83: || strcmp(changed->HardDisk.szIdeHardDiskImage, current->HardDisk.szIdeHardDiskImage))
! 84: return true;
1.1 root 85:
86: /* Did change GEMDOS drive? */
87: if (changed->HardDisk.bUseHardDiskDirectories != current->HardDisk.bUseHardDiskDirectories
88: || (strcmp(changed->HardDisk.szHardDiskDirectories[0], current->HardDisk.szHardDiskDirectories[0])
89: && changed->HardDisk.bUseHardDiskDirectories))
1.1.1.3 ! root 90: return true;
1.1 root 91:
92: /* Did change machine type? */
93: if (changed->System.nMachineType != current->System.nMachineType)
1.1.1.3 ! root 94: return true;
1.1 root 95:
96: /* Did change size of memory? */
97: if (current->Memory.nMemorySize != changed->Memory.nMemorySize)
1.1.1.3 ! root 98: return true;
1.1 root 99:
1.1.1.3 ! root 100: return false;
1.1 root 101: }
102:
103:
104: /*-----------------------------------------------------------------------*/
105: /**
106: * Copy details back to configuration and perform reset.
107: */
108: void Change_CopyChangedParamsToConfiguration(CNF_PARAMS *current, CNF_PARAMS *changed, bool bForceReset)
109: {
110: bool NeedReset;
1.1.1.3 ! root 111: bool bReInitGemdosDrive = false;
! 112: bool bReInitAcsiEmu = false;
! 113: bool bReInitIDEEmu = false;
! 114: bool bReInitIoMem = false;
! 115: bool bScreenModeChange = false;
! 116: bool bReInitMidi = false;
1.1 root 117: bool bFloppyInsert[MAX_FLOPPYDRIVES];
118: int i;
119:
120: /* Do we need to warn user that changes will only take effect after reset? */
121: if (bForceReset)
122: NeedReset = bForceReset;
123: else
124: NeedReset = Change_DoNeedReset(current, changed);
125:
126: /* Do need to change resolution? Need if change display/overscan settings
127: * (if switch between Colour/Mono cause reset later) or toggle statusbar
128: */
129: if (!NeedReset &&
130: (changed->Screen.nForceBpp != current->Screen.nForceBpp
131: || changed->Screen.bZoomLowRes != current->Screen.bZoomLowRes
132: || changed->Screen.bAllowOverscan != current->Screen.bAllowOverscan
133: || changed->Screen.bShowStatusbar != current->Screen.bShowStatusbar))
134: {
1.1.1.3 ! root 135: bScreenModeChange = true;
1.1 root 136: }
137:
138: /* Did set new printer parameters? */
139: if (changed->Printer.bEnablePrinting != current->Printer.bEnablePrinting
140: || changed->Printer.bPrintToFile != current->Printer.bPrintToFile
141: || strcmp(changed->Printer.szPrintToFileName,current->Printer.szPrintToFileName))
142: {
143: Printer_CloseAllConnections();
144: }
145:
146: /* Did set new RS232 parameters? */
147: if (changed->RS232.bEnableRS232 != current->RS232.bEnableRS232
148: || strcmp(changed->RS232.szOutFileName, current->RS232.szOutFileName)
149: || strcmp(changed->RS232.szInFileName, current->RS232.szInFileName))
150: {
151: RS232_UnInit();
152: }
153:
154: /* Did stop sound? Or change playback Hz. If so, also stop sound recording */
1.1.1.3 ! root 155: if (!changed->Sound.bEnableSound || changed->Sound.nPlaybackFreq != current->Sound.nPlaybackFreq)
1.1 root 156: {
157: if (Sound_AreWeRecording())
158: Sound_EndRecording();
159: Audio_UnInit();
160: }
161:
162: /* Did change floppy (images)? */
163: for (i = 0; i < MAX_FLOPPYDRIVES; i++)
164: {
165: /*
166: Log_Printf(LOG_DEBUG, "Old and new disk %c:\n\t%s\n\t%s", 'A'+i,
167: current->DiskImage.szDiskFileName[i],
168: changed->DiskImage.szDiskFileName[i]);
169: */
170: if (strcmp(changed->DiskImage.szDiskFileName[i],
171: current->DiskImage.szDiskFileName[i])
172: || strcmp(changed->DiskImage.szDiskZipPath[i],
173: current->DiskImage.szDiskZipPath[i]))
1.1.1.3 ! root 174: bFloppyInsert[i] = true;
1.1 root 175: else
1.1.1.3 ! root 176: bFloppyInsert[i] = false;
1.1 root 177: }
178:
179: /* Did change GEMDOS drive? */
180: if (changed->HardDisk.bUseHardDiskDirectories != current->HardDisk.bUseHardDiskDirectories
181: || (strcmp(changed->HardDisk.szHardDiskDirectories[0], current->HardDisk.szHardDiskDirectories[0])
182: && changed->HardDisk.bUseHardDiskDirectories))
183: {
184: GemDOS_UnInitDrives();
1.1.1.3 ! root 185: bReInitGemdosDrive = true;
1.1 root 186: }
187:
188: /* Did change HD image? */
189: if (changed->HardDisk.bUseHardDiskImage != current->HardDisk.bUseHardDiskImage
190: || (strcmp(changed->HardDisk.szHardDiskImage, current->HardDisk.szHardDiskImage)
191: && changed->HardDisk.bUseHardDiskImage))
192: {
193: HDC_UnInit();
1.1.1.3 ! root 194: bReInitAcsiEmu = true;
! 195: }
! 196:
! 197: /* Did change IDE HD image? */
! 198: if (changed->HardDisk.bUseIdeHardDiskImage != current->HardDisk.bUseIdeHardDiskImage
! 199: || (strcmp(changed->HardDisk.szIdeHardDiskImage, current->HardDisk.szIdeHardDiskImage)
! 200: && changed->HardDisk.bUseIdeHardDiskImage))
! 201: {
! 202: Ide_UnInit();
! 203: bReInitIDEEmu = true;
1.1 root 204: }
205:
206: /* Did change blitter, rtc or system type? */
207: if (changed->System.bBlitter != current->System.bBlitter
208: #if ENABLE_DSP_EMU
209: || changed->System.nDSPType != current->System.nDSPType
210: #endif
211: || changed->System.bRealTimeClock != current->System.bRealTimeClock
212: || changed->System.nMachineType != current->System.nMachineType)
213: {
214: IoMem_UnInit();
1.1.1.3 ! root 215: bReInitIoMem = true;
1.1 root 216: }
217:
218: #if ENABLE_DSP_EMU
219: /* Disabled DSP? */
1.1.1.3 ! root 220: if (current->System.nDSPType == DSP_TYPE_EMU &&
! 221: changed->System.nDSPType != DSP_TYPE_EMU)
1.1 root 222: {
223: DSP_UnInit();
224: }
225: #endif
226:
1.1.1.2 root 227: /* Did change MIDI settings? */
228: if (current->Midi.bEnableMidi != changed->Midi.bEnableMidi
229: || ((strcmp(changed->Midi.sMidiOutFileName, current->Midi.sMidiOutFileName)
230: || strcmp(changed->Midi.sMidiInFileName, current->Midi.sMidiInFileName))
231: && changed->Midi.bEnableMidi))
232: {
233: Midi_UnInit();
234: bReInitMidi = true;
235: }
236:
1.1 root 237: /* Copy details to configuration,
238: * so it can be saved out or set on reset
239: */
240: if (changed != &ConfigureParams)
241: {
242: ConfigureParams = *changed;
243: }
244:
245: /* Copy details to global, if we reset copy them all */
246: Configuration_Apply(NeedReset);
247:
248: #if ENABLE_DSP_EMU
1.1.1.3 ! root 249: if (current->System.nDSPType != DSP_TYPE_EMU &&
! 250: changed->System.nDSPType == DSP_TYPE_EMU)
1.1 root 251: {
252: DSP_Init();
253: }
254: #endif
255:
256: /* Set keyboard remap file */
257: if (ConfigureParams.Keyboard.nKeymapType == KEYMAP_LOADED)
258: Keymap_LoadRemapFile(ConfigureParams.Keyboard.szMappingFileName);
259:
260: /* Mount a new HD image: */
261: if (bReInitAcsiEmu && ConfigureParams.HardDisk.bUseHardDiskImage)
262: {
263: HDC_Init(ConfigureParams.HardDisk.szHardDiskImage);
264: }
265:
1.1.1.3 ! root 266: /* Mount a new IDE HD image: */
! 267: if (bReInitIDEEmu && ConfigureParams.HardDisk.bUseIdeHardDiskImage)
! 268: {
! 269: Ide_Init();
! 270: }
! 271:
1.1 root 272: /* Insert floppies? */
273: for (i = 0; i < MAX_FLOPPYDRIVES; i++)
274: {
275: if (bFloppyInsert[i])
276: Floppy_InsertDiskIntoDrive(i);
277: }
278:
279: /* Mount a new GEMDOS drive? */
280: if (bReInitGemdosDrive && ConfigureParams.HardDisk.bUseHardDiskDirectories)
281: {
282: GemDOS_InitDrives();
283: }
284:
285: /* Restart audio sub system if necessary: */
286: if (ConfigureParams.Sound.bEnableSound && !bSoundWorking)
287: {
288: Audio_Init();
289: }
290:
291: /* Re-initialize the RS232 emulation: */
292: if (ConfigureParams.RS232.bEnableRS232 && !bConnectedRS232)
293: {
294: RS232_Init();
295: }
296:
297: /* Re-init IO memory map? */
298: if (bReInitIoMem)
299: {
300: IoMem_Init();
301: }
302:
1.1.1.2 root 303: /* Re-init MIDI emulation? */
304: if (bReInitMidi)
305: {
306: Midi_Init();
307: }
308:
1.1 root 309: /* Force things associated with screen change */
310: if (bScreenModeChange)
311: {
312: Screen_ModeChanged();
313: }
314:
315: /* Do we need to perform reset? */
316: if (NeedReset)
317: {
318: Reset_Cold();
319: /* reset needing changes may affect also info shown in statusbar */
320: Statusbar_UpdateInfo();
321: }
322:
323: /* Go into/return from full screen if flagged */
324: if (!bInFullScreen && ConfigureParams.Screen.bFullScreen)
325: Screen_EnterFullScreen();
326: else if (bInFullScreen && !ConfigureParams.Screen.bFullScreen)
327: Screen_ReturnFromFullScreen();
328: }
329:
330:
331: /*-----------------------------------------------------------------------*/
332: /**
333: * Change given Hatari options
1.1.1.3 ! root 334: * Return false if parsing failed, true otherwise
1.1 root 335: */
336: static bool Change_Options(int argc, const char *argv[])
337: {
338: bool bOK;
339: CNF_PARAMS current;
340:
1.1.1.3 ! root 341: Main_PauseEmulation(false);
1.1 root 342:
343: /* get configuration changes */
344: current = ConfigureParams;
345: ConfigureParams.Screen.bFullScreen = bInFullScreen;
346: bOK = Opt_ParseParameters(argc, argv);
347:
348: /* Check if reset is required and ask user if he really wants to continue */
349: if (bOK && Change_DoNeedReset(¤t, &ConfigureParams)
350: && current.Log.nAlertDlgLogLevel >= LOG_WARN) {
351: bOK = DlgAlert_Query("The emulated system must be "
352: "reset to apply these changes. "
353: "Apply changes now and reset "
354: "the emulator?");
355: }
356: /* Copy details to configuration */
357: if (bOK) {
1.1.1.3 ! root 358: Change_CopyChangedParamsToConfiguration(¤t, &ConfigureParams, false);
1.1 root 359: } else {
360: ConfigureParams = current;
361: }
362:
363: Main_UnPauseEmulation();
364: return bOK;
365: }
366:
367:
368: /*-----------------------------------------------------------------------*/
369: /**
370: * Parse given command line and change Hatari options accordingly
1.1.1.3 ! root 371: * Return false if parsing failed or there were no args, true otherwise
1.1 root 372: */
373: bool Change_ApplyCommandline(char *cmdline)
374: {
375: int i, argc, inarg;
376: const char **argv;
377: bool ret;
378:
379: /* count args */
380: inarg = argc = 0;
381: for (i = 0; cmdline[i]; i++)
382: {
383: if (isspace(cmdline[i]))
384: {
385: inarg = 0;
386: continue;
387: }
388: if (!inarg)
389: {
390: inarg++;
391: argc++;
392: }
393: }
394: if (!argc)
395: {
1.1.1.3 ! root 396: return false;
1.1 root 397: }
398: /* 2 = "hatari" + NULL */
399: argv = malloc((argc+2) * sizeof(char*));
400: if (!argv)
401: {
402: perror("command line alloc");
1.1.1.3 ! root 403: return false;
1.1 root 404: }
405:
406: /* parse them to array */
407: fprintf(stderr, "Command line with '%d' arguments:\n", argc);
408: inarg = argc = 0;
409: argv[argc++] = "hatari";
410: for (i = 0; cmdline[i]; i++)
411: {
412: if (isspace(cmdline[i]))
413: {
414: cmdline[i] = '\0';
415: if (inarg)
416: {
417: fprintf(stderr, "- '%s'\n", argv[argc-1]);
418: }
419: inarg = 0;
420: continue;
421: }
422: if (!inarg)
423: {
424: argv[argc++] = &(cmdline[i]);
425: inarg++;
426: }
427: }
428: if (inarg)
429: {
430: fprintf(stderr, "- '%s'\n", argv[argc-1]);
431: }
432: argv[argc] = NULL;
433:
434: /* do args */
435: ret = Change_Options(argc, argv);
1.1.1.3 ! root 436: free((void *)argv);
1.1 root 437: return ret;
438: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.