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