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