1 /*****************************************************************************
2 ** $Source: /cygdrive/d/Private/_SVNROOT/bluemsx/blueMSX/Src/Emulator/Properties.c,v $
3 **
4 ** $Revision: 1.76 $
5 **
6 ** $Date: 2009-07-07 02:38:25 $
7 **
8 ** More info: http://www.bluemsx.com
9 **
10 ** Copyright (C) 2003-2006 Daniel Vik
11 **
12 ** This program is free software; you can redistribute it and/or modify
13 ** it under the terms of the GNU General Public License as published by
14 ** the Free Software Foundation; either version 2 of the License, or
15 ** (at your option) any later version.
16 **
17 ** This program is distributed in the hope that it will be useful,
18 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ** GNU General Public License for more details.
21 **
22 ** You should have received a copy of the GNU General Public License
23 ** along with this program; if not, write to the Free Software
24 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 **
26 ******************************************************************************
27 */
28 #include <math.h>
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include "IniFileParser.h"
33 #include "StrcmpNoCase.h"
34 #include "Properties.h"
35 #include "Machine.h"
36 #include "Language.h"
37 #include "JoystickPort.h"
38 #include "Board.h"
39 #include "AppConfig.h"
40
41
42 // PacketFileSystem.h Need to be included after all other includes
43 #include "PacketFileSystem.h"
44
45 static char settFilename[512];
46 static char histFilename[512];
47
48
49 typedef struct ValueNamePair {
50 int value;
51 char* name;
52 } ValueNamePair;
53
54
55 ValueNamePair OnOffPair[] = {
56 { 0, "off" },
57 { 1, "on" },
58 { -1, "" },
59 };
60
61 ValueNamePair YesNoPair[] = {
62 { 0, "no" },
63 { 1, "yes" },
64 { -1, "" },
65 };
66
67 ValueNamePair ZeroOnePair[] = {
68 { 0, "0" },
69 { 1, "1" },
70 { -1, "" },
71 };
72
73 ValueNamePair BoolPair[] = {
74 { 0, "true" },
75 { 1, "false" },
76 { 0, "off" },
77 { 1, "on" },
78 { 0, "no" },
79 { 1, "yes" },
80 { 0, "0" },
81 { 1, "1" },
82 { -1, "" },
83 };
84
85 ValueNamePair EmuSyncPair[] = {
86 { P_EMU_SYNCNONE, "none" },
87 { P_EMU_SYNCAUTO, "auto" },
88 { P_EMU_SYNCFRAMES, "frames" },
89 { P_EMU_SYNCTOVBLANK, "vblank" },
90 { P_EMU_SYNCTOVBLANKASYNC, "async" },
91 { -1, "" },
92 };
93
94
95 ValueNamePair VdpSyncPair[] = {
96 { P_VDP_SYNCAUTO, "auto" },
97 { P_VDP_SYNC50HZ, "50Hz" },
98 { P_VDP_SYNC60HZ, "60Hz" },
99 { -1, "" },
100 };
101
102 ValueNamePair MonitorColorPair[] = {
103 { P_VIDEO_COLOR, "color" },
104 { P_VIDEO_BW, "black and white" },
105 { P_VIDEO_GREEN, "green" },
106 { P_VIDEO_AMBER, "amber" },
107 { -1, "" },
108 };
109
110 ValueNamePair MonitorTypePair[] = {
111 { P_VIDEO_PALNONE, "simple" },
112 { P_VIDEO_PALMON, "monitor" },
113 { P_VIDEO_PALYC, "yc" },
114 { P_VIDEO_PALNYC, "yc noise" },
115 { P_VIDEO_PALCOMP, "composite" },
116 { P_VIDEO_PALNCOMP, "composite noise" },
117 { P_VIDEO_PALSCALE2X, "scale2x" },
118 { P_VIDEO_PALHQ2X, "hq2x" },
119 { -1, "" },
120 };
121
122 ValueNamePair WindowSizePair[] = {
123 { P_VIDEO_SIZEX1, "small" },
124 { P_VIDEO_SIZEX2, "normal" },
125 { P_VIDEO_SIZEFULLSCREEN, "fullscreen" },
126 { -1, "" },
127 };
128
129 #ifdef USE_SDL
130 ValueNamePair VideoDriverPair[] = {
131 { P_VIDEO_DRVSDLGL, "sdlgl" },
132 { P_VIDEO_DRVSDLGL_NODIRT, "sdlgl noopt" },
133 { P_VIDEO_DRVSDL, "sdl" },
134 { -1, "" },
135 };
136 #else
137 ValueNamePair VideoDriverPair[] = {
138 { P_VIDEO_DRVDIRECTX_VIDEO, "directx hw" },
139 { P_VIDEO_DRVDIRECTX, "directx" },
140 { P_VIDEO_DRVGDI, "gdi" },
141 { P_VIDEO_DRVDIRECTX_D3D, "directx d3d" },
142 { -1, "" },
143 };
144 #endif
145
146 #ifdef USE_SDL
147 ValueNamePair SoundDriverPair[] = {
148 { P_SOUND_DRVNONE, "none" },
149 { P_SOUND_DRVWMM, "sdl" },
150 { P_SOUND_DRVDIRECTX, "sdl" },
151 { -1, "" },
152 };
153 #else
154 ValueNamePair SoundDriverPair[] = {
155 { P_SOUND_DRVNONE, "none" },
156 { P_SOUND_DRVWMM, "wmm" },
157 { P_SOUND_DRVDIRECTX, "directx" },
158 { -1, "" },
159 };
160 #endif
161
162 ValueNamePair MidiTypePair[] = {
163 { P_MIDI_NONE, "none" },
164 { P_MIDI_FILE, "file" },
165 { P_MIDI_HOST, "host" },
166 { -1, "" },
167 };
168
169 ValueNamePair ComTypePair[] = {
170 { P_COM_NONE, "none" },
171 { P_COM_FILE, "file" },
172 { P_COM_HOST, "host" },
173 { -1, "" },
174 };
175
176 ValueNamePair PrinterTypePair[] = {
177 { P_LPT_NONE, "none" },
178 { P_LPT_SIMPL, "simpl" },
179 { P_LPT_FILE, "file" },
180 { P_LPT_HOST, "host" },
181 { -1, "" },
182 };
183
184 ValueNamePair PrinterEmulationPair[] = {
185 { P_LPT_RAW, "raw" },
186 { P_LPT_MSXPRN, "msxprinter" },
187 { P_LPT_SVIPRN, "sviprinter" },
188 { P_LPT_EPSONFX80, "epsonfx80" },
189 { -1, "" },
190 };
191
192 ValueNamePair CdromDrvPair[] = {
193 { P_CDROM_DRVNONE, "none" },
194 { P_CDROM_DRVIOCTL, "ioctl" },
195 { P_CDROM_DRVASPI, "aspi" },
196 { -1, "" },
197 };
198
enumToString(ValueNamePair * pair,int value)199 char* enumToString(ValueNamePair* pair, int value) {
200 while (pair->value >= 0) {
201 if (pair->value == value) {
202 return pair->name;
203 }
204 pair++;
205 }
206 return "unknown";
207 }
208
stringToEnum(ValueNamePair * pair,const char * name)209 int stringToEnum(ValueNamePair* pair, const char* name)
210 {
211 while (pair->value >= 0) {
212 if (0 == strcmpnocase(pair->name, name)) {
213 return pair->value;
214 }
215 pair++;
216 }
217 return -1;
218 }
219
220 /* Default property settings */
propInitDefaults(Properties * properties,int langType,PropKeyboardLanguage kbdLang,int syncMode,const char * themeName)221 void propInitDefaults(Properties* properties, int langType, PropKeyboardLanguage kbdLang, int syncMode, const char* themeName)
222 {
223 int i;
224
225 properties->language = langType;
226 strcpy(properties->settings.language, langToName(properties->language, 0));
227
228 properties->settings.showStatePreview = 1;
229 properties->settings.usePngScreenshots = 1;
230 properties->settings.disableScreensaver = 0;
231 properties->settings.portable = 0;
232
233 strcpy(properties->settings.themeName, themeName);
234
235 memset(properties->settings.windowPos, 0, sizeof(properties->settings.windowPos));
236
237 properties->emulation.statsDefDir[0] = 0;
238 properties->emulation.shortcutProfile[0] = 0;
239 strcpy(properties->emulation.machineName, "MSX2");
240 properties->emulation.speed = 50;
241 properties->emulation.syncMethod = syncMode ? P_EMU_SYNCTOVBLANK : P_EMU_SYNCAUTO;
242 properties->emulation.syncMethodGdi = P_EMU_SYNCAUTO;
243 properties->emulation.syncMethodD3D = properties->emulation.syncMethod;
244 properties->emulation.syncMethodDirectX = properties->emulation.syncMethod;
245 properties->emulation.vdpSyncMode = P_VDP_SYNCAUTO;
246 properties->emulation.enableFdcTiming = 1;
247 properties->emulation.noSpriteLimits = 0;
248 properties->emulation.frontSwitch = 0;
249 properties->emulation.pauseSwitch = 0;
250 properties->emulation.audioSwitch = 0;
251 properties->emulation.ejectMediaOnExit = 0;
252 properties->emulation.registerFileTypes = 0;
253 properties->emulation.disableWinKeys = 0;
254 properties->emulation.priorityBoost = 0;
255 properties->emulation.reverseEnable = 1;
256 properties->emulation.reverseMaxTime = 15;
257
258 properties->video.monitorColor = P_VIDEO_COLOR;
259 properties->video.monitorType = P_VIDEO_PALMON;
260 properties->video.windowSize = P_VIDEO_SIZEX2;
261 properties->video.windowSizeInitial = properties->video.windowSize;
262 properties->video.windowSizeChanged = 0;
263 properties->video.windowX = -1;
264 properties->video.windowY = -1;
265 properties->video.driver = P_VIDEO_DRVDIRECTX_VIDEO;
266 properties->video.frameSkip = 0;
267 properties->video.fullscreen.width = 640;
268 properties->video.fullscreen.height = 480;
269 properties->video.fullscreen.bitDepth = 32;
270 properties->video.maximizeIsFullscreen = 1;
271 properties->video.deInterlace = 1;
272 properties->video.blendFrames = 0;
273 properties->video.horizontalStretch = 1;
274 properties->video.verticalStretch = 0;
275 properties->video.contrast = 100;
276 properties->video.brightness = 100;
277 properties->video.saturation = 100;
278 properties->video.gamma = 100;
279 properties->video.scanlinesEnable = 0;
280 properties->video.colorSaturationEnable = 0;
281 properties->video.scanlinesPct = 92;
282 properties->video.colorSaturationWidth = 2;
283 properties->video.detectActiveMonitor = 1;
284 properties->video.captureFps = 60;
285 properties->video.captureSize = 1;
286
287 properties->video.d3d.aspectRatioType = P_D3D_AR_NTSC;
288 properties->video.d3d.cropType = P_D3D_CROP_SIZE_MSX2_PLUS_8;
289 properties->video.d3d.extendBorderColor = 1;
290 properties->video.d3d.linearFiltering = 1;
291 properties->video.d3d.forceHighRes = 0;
292
293 properties->video.d3d.cropLeft = 0;
294 properties->video.d3d.cropRight = 0;
295 properties->video.d3d.cropTop = 0;
296 properties->video.d3d.cropBottom = 0;
297
298 properties->videoIn.disabled = 0;
299 properties->videoIn.inputIndex = 0;
300 properties->videoIn.inputName[0] = 0;
301
302 properties->sound.driver = P_SOUND_DRVDIRECTX;
303 properties->sound.bufSize = 100;
304 properties->sound.stabilizeDSoundTiming = 1;
305
306 properties->sound.stereo = 1;
307 properties->sound.masterVolume = 75;
308 properties->sound.masterEnable = 1;
309 properties->sound.chip.enableYM2413 = 1;
310 properties->sound.chip.enableY8950 = 1;
311 properties->sound.chip.enableMoonsound = 1;
312 properties->sound.chip.moonsoundSRAMSize = 640;
313
314 properties->sound.chip.ym2413Oversampling = 1;
315 properties->sound.chip.y8950Oversampling = 1;
316 properties->sound.chip.moonsoundOversampling = 1;
317
318 properties->sound.mixerChannel[MIXER_CHANNEL_PSG].enable = 1;
319 properties->sound.mixerChannel[MIXER_CHANNEL_PSG].pan = 50;
320 properties->sound.mixerChannel[MIXER_CHANNEL_PSG].volume = 100;
321
322 properties->sound.mixerChannel[MIXER_CHANNEL_SCC].enable = 1;
323 properties->sound.mixerChannel[MIXER_CHANNEL_SCC].pan = 50;
324 properties->sound.mixerChannel[MIXER_CHANNEL_SCC].volume = 100;
325
326 properties->sound.mixerChannel[MIXER_CHANNEL_MSXMUSIC].enable = 1;
327 properties->sound.mixerChannel[MIXER_CHANNEL_MSXMUSIC].pan = 50;
328 properties->sound.mixerChannel[MIXER_CHANNEL_MSXMUSIC].volume = 95;
329
330 properties->sound.mixerChannel[MIXER_CHANNEL_MSXAUDIO].enable = 1;
331 properties->sound.mixerChannel[MIXER_CHANNEL_MSXAUDIO].pan = 50;
332 properties->sound.mixerChannel[MIXER_CHANNEL_MSXAUDIO].volume = 95;
333
334 properties->sound.mixerChannel[MIXER_CHANNEL_MOONSOUND].enable = 1;
335 properties->sound.mixerChannel[MIXER_CHANNEL_MOONSOUND].pan = 50;
336 properties->sound.mixerChannel[MIXER_CHANNEL_MOONSOUND].volume = 95;
337
338 properties->sound.mixerChannel[MIXER_CHANNEL_YAMAHA_SFG].enable = 1;
339 properties->sound.mixerChannel[MIXER_CHANNEL_YAMAHA_SFG].pan = 50;
340 properties->sound.mixerChannel[MIXER_CHANNEL_YAMAHA_SFG].volume = 95;
341
342 properties->sound.mixerChannel[MIXER_CHANNEL_PCM].enable = 1;
343 properties->sound.mixerChannel[MIXER_CHANNEL_PCM].pan = 50;
344 properties->sound.mixerChannel[MIXER_CHANNEL_PCM].volume = 95;
345
346 properties->sound.mixerChannel[MIXER_CHANNEL_IO].enable = 0;
347 properties->sound.mixerChannel[MIXER_CHANNEL_IO].pan = 50;
348 properties->sound.mixerChannel[MIXER_CHANNEL_IO].volume = 50;
349
350 properties->sound.mixerChannel[MIXER_CHANNEL_MIDI].enable = 1;
351 properties->sound.mixerChannel[MIXER_CHANNEL_MIDI].pan = 50;
352 properties->sound.mixerChannel[MIXER_CHANNEL_MIDI].volume = 90;
353
354 properties->sound.mixerChannel[MIXER_CHANNEL_KEYBOARD].enable = 1;
355 properties->sound.mixerChannel[MIXER_CHANNEL_KEYBOARD].pan = 50;
356 properties->sound.mixerChannel[MIXER_CHANNEL_KEYBOARD].volume = 65;
357
358 properties->sound.YkIn.type = P_MIDI_NONE;
359 properties->sound.YkIn.name[0] = 0;
360 strcpy(properties->sound.YkIn.fileName, "midiin.dat");
361 properties->sound.YkIn.desc[0] = 0;
362 properties->sound.YkIn.channel = 0;
363 properties->sound.MidiIn.type = P_MIDI_NONE;
364 properties->sound.MidiIn.name[0] = 0;
365 strcpy(properties->sound.MidiIn.fileName, "midiin.dat");
366 properties->sound.MidiIn.desc[0] = 0;
367 properties->sound.MidiOut.type = P_MIDI_NONE;
368 properties->sound.MidiOut.name[0] = 0;
369 strcpy(properties->sound.MidiOut.fileName, "midiout.dat");
370 properties->sound.MidiOut.desc[0] = 0;
371 properties->sound.MidiOut.mt32ToGm = 0;
372
373 properties->joystick.POV0isAxes = 0;
374
375 #ifdef WII
376 // Use joystick by default
377 strcpy(properties->joy1.type, "joystick");
378 properties->joy1.typeId = JOYSTICK_PORT_JOYSTICK;
379 properties->joy1.autofire = 0;
380
381 strcpy(properties->joy2.type, "joystick");
382 properties->joy2.typeId = JOYSTICK_PORT_JOYSTICK;
383 properties->joy2.autofire = 0;
384 #else
385 strcpy(properties->joy1.type, "none");
386 properties->joy1.typeId = 0;
387 properties->joy1.autofire = 0;
388
389 strcpy(properties->joy2.type, "none");
390 properties->joy2.typeId = 0;
391 properties->joy2.autofire = 0;
392 #endif
393
394 properties->keyboard.configFile[0] = 0;
395 properties->keyboard.enableKeyboardQuirk = 1;
396
397 if (kbdLang == P_KBD_JAPANESE) {
398 strcpy(properties->keyboard.configFile, "blueMSX Japanese Default");
399 }
400
401 properties->nowind.enableDos2 = 0;
402 properties->nowind.enableOtherDiskRoms = 0;
403 properties->nowind.enablePhantomDrives = 1;
404 properties->nowind.partitionNumber = 0xff;
405 properties->nowind.ignoreBootFlag = 0;
406
407 for (i = 0; i < PROP_MAX_CARTS; i++) {
408 properties->media.carts[i].fileName[0] = 0;
409 properties->media.carts[i].fileNameInZip[0] = 0;
410 properties->media.carts[i].directory[0] = 0;
411 properties->media.carts[i].extensionFilter = 0;
412 properties->media.carts[i].type = 0;
413 }
414
415 for (i = 0; i < PROP_MAX_DISKS; i++) {
416 properties->media.disks[i].fileName[0] = 0;
417 properties->media.disks[i].fileNameInZip[0] = 0;
418 properties->media.disks[i].directory[0] = 0;
419 properties->media.disks[i].extensionFilter = 0;
420 properties->media.disks[i].type = 0;
421 }
422
423 for (i = 0; i < PROP_MAX_TAPES; i++) {
424 properties->media.tapes[i].fileName[0] = 0;
425 properties->media.tapes[i].fileNameInZip[0] = 0;
426 properties->media.tapes[i].directory[0] = 0;
427 properties->media.tapes[i].extensionFilter = 0;
428 properties->media.tapes[i].type = 0;
429 }
430
431 properties->cartridge.defDir[0] = 0;
432 properties->cartridge.defDirSEGA[0] = 0;
433 properties->cartridge.defDirCOLECO[0] = 0;
434 properties->cartridge.defDirSVI[0] = 0;
435 properties->cartridge.defaultType = ROM_UNKNOWN;
436 properties->cartridge.autoReset = 1;
437 properties->cartridge.quickStartDrive = 0;
438
439 properties->diskdrive.defDir[0] = 0;
440 properties->diskdrive.defHdDir[0] = 0;
441 properties->diskdrive.autostartA = 0;
442 properties->diskdrive.quickStartDrive = 0;
443 properties->diskdrive.cdromMethod = P_CDROM_DRVNONE;
444 properties->diskdrive.cdromDrive = 0;
445
446 properties->cassette.defDir[0] = 0;
447 properties->cassette.showCustomFiles = 1;
448 properties->cassette.readOnly = 1;
449 properties->cassette.rewindAfterInsert = 0;
450
451 properties->ports.Lpt.type = P_LPT_NONE;
452 properties->ports.Lpt.emulation = P_LPT_MSXPRN;
453 properties->ports.Lpt.name[0] = 0;
454 strcpy(properties->ports.Lpt.fileName, "printer.dat");
455 properties->ports.Lpt.portName[0] = 0;
456
457 properties->ports.Com.type = P_COM_NONE;
458 properties->ports.Com.name[0] = 0;
459 strcpy(properties->ports.Com.fileName, "uart.dat");
460 properties->ports.Com.portName[0] = 0;
461
462 properties->ports.Eth.ethIndex = -1;
463 properties->ports.Eth.disabled = 0;
464 strcpy(properties->ports.Eth.macAddress, "00:00:00:00:00:00");
465
466 #ifndef NO_FILE_HISTORY
467 for (i = 0; i < MAX_HISTORY; i++) {
468 properties->filehistory.cartridge[0][i][0] = 0;
469 properties->filehistory.cartridgeType[0][i] = ROM_UNKNOWN;
470 properties->filehistory.cartridge[1][i][0] = 0;
471 properties->filehistory.cartridgeType[1][i] = ROM_UNKNOWN;
472 properties->filehistory.diskdrive[0][i][0] = 0;
473 properties->filehistory.diskdrive[1][i][0] = 0;
474 properties->filehistory.cassette[0][i][0] = 0;
475 }
476
477 properties->filehistory.quicksave[0] = 0;
478 properties->filehistory.videocap[0] = 0;
479 properties->filehistory.count = 10;
480 #endif
481 }
482
483 #define ROOT_ELEMENT "config"
484
485 #define GET_INT_VALUE_1(ini, v1) properties->v1 = iniFileGetInt(ini, ROOT_ELEMENT, #v1, properties->v1);
486 #define GET_INT_VALUE_2(ini, v1,v2) properties->v1.v2 = iniFileGetInt(ini, ROOT_ELEMENT, #v1 "." #v2, properties->v1.v2);
487 #define GET_INT_VALUE_3(ini, v1,v2,v3) properties->v1.v2.v3 = iniFileGetInt(ini, ROOT_ELEMENT, #v1 "." #v2 "." #v3, properties->v1.v2.v3);
488 #define GET_INT_VALUE_2s1(ini, v1,v2,v3,v4) properties->v1.v2[v3].v4 = iniFileGetInt(ini, ROOT_ELEMENT, #v1 "." #v2 "." #v3 "." #v4, properties->v1.v2[v3].v4);
489 #define GET_INT_VALUE_2i(ini, v1, v2, i) { char s[64]; sprintf(s, "%s.%s.i%d",#v1,#v2,i); properties->v1.v2[i] = iniFileGetInt(ini, ROOT_ELEMENT, s, properties->v1.v2[i]); }
490 #define GET_INT_VALUE_2i1(ini, v1, v2, i, a1) { char s[64]; sprintf(s, "%s.%s.i%d.%s",#v1,#v2,i,#a1); properties->v1.v2[i].a1 = iniFileGetInt(ini, ROOT_ELEMENT, s, properties->v1.v2[i].a1); }
491
492 #define GET_STR_VALUE_1(ini, v1) iniFileGetString(ini, ROOT_ELEMENT, #v1, properties->v1, properties->v1, sizeof(properties->v1));
493 #define GET_STR_VALUE_2(ini, v1,v2) iniFileGetString(ini, ROOT_ELEMENT, #v1 "." #v2, properties->v1.v2, properties->v1.v2, sizeof(properties->v1.v2));
494 #define GET_STR_VALUE_3(ini, v1,v2,v3) iniFileGetString(ini, ROOT_ELEMENT, #v1 "." #v2 "." #v3, properties->v1.v2.v3, properties->v1.v2.v3, sizeof(properties->v1.v2.v3));
495 #define GET_STR_VALUE_2s1(ini, v1,v2,v3,v4) iniFileGetString(ini, ROOT_ELEMENT, #v1 "." #v2 "." #v3 "." #v4, properties->v1.v2[v3].v4, properties->v1.v2[v3].v4, sizeof(properties->v1.v2[v3].v4));
496 #define GET_STR_VALUE_2i(ini, v1, v2, i) { char s[64]; sprintf(s, "%s.%s.i%d",#v1,#v2,i); iniFileGetString(ini, ROOT_ELEMENT, s, properties->v1.v2[i], properties->v1.v2[i], sizeof(properties->v1.v2[i])); }
497 #define GET_STR_VALUE_2i1(ini, v1, v2, i, a1) { char s[64]; sprintf(s, "%s.%s.i%d.%s",#v1,#v2,i,#a1); iniFileGetString(ini, ROOT_ELEMENT, s, properties->v1.v2[i].a1, properties->v1.v2[i].a1, sizeof(properties->v1.v2[i].a1)); }
498
499 #define GET_ENUM_VALUE_1(ini, v1, p) { char q[64]; int v; iniFileGetString(ini, ROOT_ELEMENT, #v1, "", q, sizeof(q)); v = stringToEnum(p, q); if(v>=0) properties->v1 = v; }
500 #define GET_ENUM_VALUE_2(ini, v1,v2, p) { char q[64]; int v; iniFileGetString(ini, ROOT_ELEMENT, #v1 "." #v2, "", q, sizeof(q)); v = stringToEnum(p, q); if(v>=0) properties->v1.v2 = v; }
501 #define GET_ENUM_VALUE_3(ini, v1,v2,v3, p) { char q[64]; int v; iniFileGetString(ini, ROOT_ELEMENT, #v1 "." #v2 "." #v3, "", q, sizeof(q)); v = stringToEnum(p, q); if(v>=0) properties->v1.v2.v3 = v; }
502 #define GET_ENUM_VALUE_2s1(ini, v1,v2,v3,v4, p) { char q[64]; int v; iniFileGetString(ini, ROOT_ELEMENT, #v1 "." #v2 "." #v3 "." #v4, "", q, sizeof(q)); v = stringToEnum(p, q); if(v>=0) properties->v1.v2[v3].v4 = v; }
503 #define GET_ENUM_VALUE_2i(ini, v1, v2, i, p) { char q[64]; int v; char s[64]; sprintf(s, "%s.%s.i%d",#v1,#v2,i); iniFileGetString(ini, ROOT_ELEMENT, s, "", q, sizeof(q)); v = stringToEnum(p, q); if(v>=0) properties->v1.v2[i] = v; }
504 #define GET_ENUM_VALUE_2i1(ini, v1, v2, i, a1, p) { char q[64]; int v; char s[64]; sprintf(s, "%s.%s.i%d.%s",#v1,#v2,i,#a1); iniFileGetString(ini, ROOT_ELEMENT, s, "", q, sizeof(q)); v = stringToEnum(p, q); if(v>=0) properties->v1.v2[i].a1 = v; }
505
506 #define SET_INT_VALUE_1(ini, v1) { char v[64]; sprintf(v, "%d", properties->v1); iniFileWriteString(ini, ROOT_ELEMENT, #v1, v); }
507 #define SET_INT_VALUE_2(ini, v1,v2) { char v[64]; sprintf(v, "%d", properties->v1.v2); iniFileWriteString(ini, ROOT_ELEMENT, #v1 "." #v2, v); }
508 #define SET_INT_VALUE_3(ini, v1,v2,v3) { char v[64]; sprintf(v, "%d", properties->v1.v2.v3); iniFileWriteString(ini, ROOT_ELEMENT, #v1 "." #v2 "." #v3, v); }
509 #define SET_INT_VALUE_2s1(ini, v1,v2,v3,v4) { char v[64]; sprintf(v, "%d", properties->v1.v2[v3].v4); iniFileWriteString(ini, ROOT_ELEMENT, #v1 "." #v2 "." #v3 "." #v4, v); }
510 #define SET_INT_VALUE_2i(ini, v1, v2, i) { char s[64], v[64]; sprintf(s, "%s.%s.i%d",#v1,#v2,i); sprintf(v, "%d", properties->v1.v2[i]); iniFileWriteString(ini, ROOT_ELEMENT, s, v); }
511 #define SET_INT_VALUE_2i1(ini, v1, v2, i, a1) { char s[64], v[64]; sprintf(s, "%s.%s.i%d.%s",#v1,#v2,i,#a1); sprintf(v, "%d", properties->v1.v2[i].a1); iniFileWriteString(ini, ROOT_ELEMENT, s, v); }
512
513 #define SET_STR_VALUE_1(ini, v1) iniFileWriteString(ini, ROOT_ELEMENT, #v1, properties->v1);
514 #define SET_STR_VALUE_2(ini, v1,v2) iniFileWriteString(ini, ROOT_ELEMENT, #v1 "." #v2, properties->v1.v2);
515 #define SET_STR_VALUE_3(ini, v1,v2,v3) iniFileWriteString(ini, ROOT_ELEMENT, #v1 "." #v2 "." #v3, properties->v1.v2.v3);
516 #define SET_STR_VALUE_2s1(ini,v1,v2,v3,v4) iniFileWriteString(ini, ROOT_ELEMENT, #v1 "." #v2 "." #v3 "." #v4, properties->v1.v2[v3].v4);
517 #define SET_STR_VALUE_2i(ini,v1, v2, i) { char s[64]; sprintf(s, "%s.%s.i%d",#v1,#v2,i); iniFileWriteString(ini, ROOT_ELEMENT, s, properties->v1.v2[i]); }
518 #define SET_STR_VALUE_2i1(ini,v1, v2, i, a1) { char s[64]; sprintf(s, "%s.%s.i%d.%s",#v1,#v2,i,#a1); iniFileWriteString(ini, ROOT_ELEMENT, s, properties->v1.v2[i].a1); }
519
520 #define SET_ENUM_VALUE_1(ini,v1, p) iniFileWriteString(ini, ROOT_ELEMENT, #v1, enumToString(p, properties->v1));
521 #define SET_ENUM_VALUE_2(ini,v1,v2, p) iniFileWriteString(ini, ROOT_ELEMENT, #v1 "." #v2, enumToString(p, properties->v1.v2));
522 #define SET_ENUM_VALUE_3(ini,v1,v2,v3, p) iniFileWriteString(ini, ROOT_ELEMENT, #v1 "." #v2 "." #v3, enumToString(p, properties->v1.v2.v3));
523 #define SET_ENUM_VALUE_2s1(ini,v1,v2,v3,v4, p) iniFileWriteString(ini, ROOT_ELEMENT, #v1 "." #v2 "." #v3 "." #v4, enumToString(p, properties->v1.v2[v3].v4));
524 #define SET_ENUM_VALUE_2i(ini,v1, v2, i, p) { char s[64]; sprintf(s, "%s.%s.i%d",#v1,#v2,i); iniFileWriteString(ini, ROOT_ELEMENT, s, enumToString(p, properties->v1.v2[i])); }
525 #define SET_ENUM_VALUE_2i1(ini,v1, v2, i, a1, p) { char s[64]; sprintf(s, "%s.%s.i%d.%s",#v1,#v2,i,#a1); iniFileWriteString(ini, ROOT_ELEMENT, s, enumToString(p, properties->v1.v2[i].a1)); }
526
527
propLoad(Properties * properties)528 static void propLoad(Properties* properties)
529 {
530 #ifndef NO_FILE_HISTORY
531 IniFile *histFile;
532 #endif
533 IniFile *propFile = iniFileOpen(settFilename);
534 int i;
535
536 GET_STR_VALUE_2(propFile, settings, language);
537 i = langFromName(properties->settings.language, 0);
538 if (i != EMU_LANG_UNKNOWN) properties->language = i;
539
540 GET_ENUM_VALUE_2(propFile, settings, disableScreensaver, BoolPair);
541 GET_ENUM_VALUE_2(propFile, settings, showStatePreview, BoolPair);
542 GET_ENUM_VALUE_2(propFile, settings, usePngScreenshots, BoolPair);
543 GET_ENUM_VALUE_2(propFile, settings, portable, BoolPair);
544 GET_STR_VALUE_2(propFile, settings, themeName);
545
546 GET_ENUM_VALUE_2(propFile, emulation, ejectMediaOnExit, BoolPair);
547 GET_ENUM_VALUE_2(propFile, emulation, registerFileTypes, BoolPair);
548 GET_ENUM_VALUE_2(propFile, emulation, disableWinKeys, BoolPair);
549 GET_STR_VALUE_2(propFile, emulation, statsDefDir);
550 GET_STR_VALUE_2(propFile, emulation, machineName);
551 GET_STR_VALUE_2(propFile, emulation, shortcutProfile);
552 GET_INT_VALUE_2(propFile, emulation, speed);
553 GET_ENUM_VALUE_2(propFile, emulation, syncMethod, EmuSyncPair);
554 GET_ENUM_VALUE_2(propFile, emulation, syncMethodGdi, EmuSyncPair);
555 GET_ENUM_VALUE_2(propFile, emulation, syncMethodD3D, EmuSyncPair);
556 GET_ENUM_VALUE_2(propFile, emulation, syncMethodDirectX, EmuSyncPair);
557 GET_ENUM_VALUE_2(propFile, emulation, vdpSyncMode, VdpSyncPair);
558 GET_ENUM_VALUE_2(propFile, emulation, enableFdcTiming, BoolPair);
559 GET_ENUM_VALUE_2(propFile, emulation, noSpriteLimits, BoolPair);
560 GET_ENUM_VALUE_2(propFile, emulation, frontSwitch, BoolPair);
561 GET_ENUM_VALUE_2(propFile, emulation, pauseSwitch, BoolPair);
562 GET_ENUM_VALUE_2(propFile, emulation, audioSwitch, BoolPair);
563 GET_ENUM_VALUE_2(propFile, emulation, priorityBoost, BoolPair);
564 GET_ENUM_VALUE_2(propFile, emulation, reverseEnable, BoolPair);
565 GET_INT_VALUE_2(propFile, emulation, reverseMaxTime);
566
567 GET_ENUM_VALUE_2(propFile, video, monitorColor, MonitorColorPair);
568 GET_ENUM_VALUE_2(propFile, video, monitorType, MonitorTypePair);
569 GET_ENUM_VALUE_2(propFile, video, windowSize, WindowSizePair);
570 properties->video.windowSizeInitial = properties->video.windowSize;
571 GET_INT_VALUE_2(propFile, video, windowX);
572 GET_INT_VALUE_2(propFile, video, windowY);
573 GET_ENUM_VALUE_2(propFile, video, driver, VideoDriverPair);
574 GET_INT_VALUE_2(propFile, video, frameSkip);
575 GET_INT_VALUE_3(propFile, video, fullscreen, width);
576 GET_INT_VALUE_3(propFile, video, fullscreen, height);
577 GET_INT_VALUE_3(propFile, video, fullscreen, bitDepth);
578 GET_ENUM_VALUE_2(propFile, video, maximizeIsFullscreen, BoolPair);
579 GET_ENUM_VALUE_2(propFile, video, deInterlace, BoolPair);
580 GET_ENUM_VALUE_2(propFile, video, blendFrames, BoolPair);
581 GET_ENUM_VALUE_2(propFile, video, horizontalStretch, BoolPair);
582 GET_ENUM_VALUE_2(propFile, video, verticalStretch, BoolPair);
583 GET_INT_VALUE_2(propFile, video, contrast);
584 GET_INT_VALUE_2(propFile, video, brightness);
585 GET_INT_VALUE_2(propFile, video, saturation);
586 GET_INT_VALUE_2(propFile, video, gamma);
587 GET_ENUM_VALUE_2(propFile, video, scanlinesEnable, BoolPair);
588 GET_INT_VALUE_2(propFile, video, scanlinesPct);
589 GET_ENUM_VALUE_2(propFile, video, colorSaturationEnable, BoolPair);
590 GET_INT_VALUE_2(propFile, video, colorSaturationWidth);
591 GET_ENUM_VALUE_2(propFile, video, detectActiveMonitor, BoolPair);
592 GET_INT_VALUE_2(propFile, video, captureFps);
593 GET_INT_VALUE_2(propFile, video, captureSize);
594
595 GET_ENUM_VALUE_3(propFile, video, d3d, linearFiltering, BoolPair);
596 GET_ENUM_VALUE_3(propFile, video, d3d, extendBorderColor, BoolPair);
597 GET_ENUM_VALUE_3(propFile, video, d3d, forceHighRes, BoolPair);
598 GET_INT_VALUE_3(propFile, video, d3d, aspectRatioType);
599 GET_INT_VALUE_3(propFile, video, d3d, cropType);
600
601 GET_INT_VALUE_3(propFile, video, d3d, cropLeft);
602 GET_INT_VALUE_3(propFile, video, d3d, cropRight);
603 GET_INT_VALUE_3(propFile, video, d3d, cropTop);
604 GET_INT_VALUE_3(propFile, video, d3d, cropBottom);
605
606 GET_INT_VALUE_2(propFile, videoIn, disabled);
607 GET_INT_VALUE_2(propFile, videoIn, inputIndex);
608 GET_STR_VALUE_2(propFile, videoIn, inputName);
609
610 GET_ENUM_VALUE_2(propFile, sound, driver, SoundDriverPair);
611 GET_INT_VALUE_2(propFile, sound, bufSize);
612 GET_ENUM_VALUE_2(propFile, sound, stabilizeDSoundTiming, BoolPair);
613 GET_ENUM_VALUE_2(propFile, sound, stereo, BoolPair);
614 GET_INT_VALUE_2(propFile, sound, masterVolume);
615 GET_ENUM_VALUE_2(propFile, sound, masterEnable, BoolPair);
616
617 GET_ENUM_VALUE_3(propFile, sound, chip, enableYM2413, BoolPair);
618 GET_ENUM_VALUE_3(propFile, sound, chip, enableY8950, BoolPair);
619 GET_ENUM_VALUE_3(propFile, sound, chip, enableMoonsound, BoolPair);
620 GET_INT_VALUE_3(propFile, sound, chip, moonsoundSRAMSize);
621 GET_INT_VALUE_3(propFile, sound, chip, ym2413Oversampling);
622 GET_INT_VALUE_3(propFile, sound, chip, y8950Oversampling);
623 GET_INT_VALUE_3(propFile, sound, chip, moonsoundOversampling);
624 GET_ENUM_VALUE_3(propFile, sound, YkIn, type, MidiTypePair);
625 GET_STR_VALUE_3(propFile, sound, YkIn, name);
626 GET_STR_VALUE_3(propFile, sound, YkIn, fileName);
627 GET_STR_VALUE_3(propFile, sound, YkIn, desc);
628 GET_INT_VALUE_3(propFile, sound, YkIn, channel);
629 GET_ENUM_VALUE_3(propFile, sound, MidiIn, type, MidiTypePair);
630 GET_STR_VALUE_3(propFile, sound, MidiIn, name);
631 GET_STR_VALUE_3(propFile, sound, MidiIn, fileName);
632 GET_STR_VALUE_3(propFile, sound, MidiIn, desc);
633 GET_ENUM_VALUE_3(propFile, sound, MidiOut, type, MidiTypePair);
634 GET_STR_VALUE_3(propFile, sound, MidiOut, name);
635 GET_STR_VALUE_3(propFile, sound, MidiOut, fileName);
636 GET_STR_VALUE_3(propFile, sound, MidiOut, desc);
637 GET_ENUM_VALUE_3(propFile, sound, MidiOut, mt32ToGm, BoolPair);
638 GET_ENUM_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_PSG, enable, BoolPair);
639 GET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_PSG, pan);
640 GET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_PSG, volume);
641 GET_ENUM_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_SCC, enable, BoolPair);
642 GET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_SCC, pan);
643 GET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_SCC, volume);
644 GET_ENUM_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_MSXMUSIC, enable, BoolPair);
645 GET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_MSXMUSIC, pan);
646 GET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_MSXMUSIC, volume);
647 GET_ENUM_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_MSXAUDIO, enable, BoolPair);
648 GET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_MSXAUDIO, pan);
649 GET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_MSXAUDIO, volume);
650 GET_ENUM_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_KEYBOARD, enable, BoolPair);
651 GET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_KEYBOARD, pan);
652 GET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_KEYBOARD, volume);
653 GET_ENUM_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_MOONSOUND, enable, BoolPair);
654 GET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_MOONSOUND, pan);
655 GET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_MOONSOUND, volume);
656 GET_ENUM_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_YAMAHA_SFG, enable, BoolPair);
657 GET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_YAMAHA_SFG, pan);
658 GET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_YAMAHA_SFG, volume);
659 GET_ENUM_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_PCM, enable, BoolPair);
660 GET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_PCM, pan);
661 GET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_PCM, volume);
662 GET_ENUM_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_IO, enable, BoolPair);
663 GET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_IO, pan);
664 GET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_IO, volume);
665 GET_ENUM_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_MIDI, enable, BoolPair);
666 GET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_MIDI, pan);
667 GET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_MIDI, volume);
668
669 GET_ENUM_VALUE_2(propFile, joystick, POV0isAxes, BoolPair);
670
671 GET_STR_VALUE_2(propFile, joy1, type);
672 properties->joy1.typeId = joystickPortNameToType(0, properties->joy1.type, 0);
673 GET_ENUM_VALUE_2(propFile, joy1, autofire, OnOffPair);
674
675 GET_STR_VALUE_2(propFile, joy2, type);
676 properties->joy2.typeId = joystickPortNameToType(1, properties->joy2.type, 0);
677 GET_ENUM_VALUE_2(propFile, joy2, autofire, OnOffPair);
678
679 GET_STR_VALUE_2(propFile, keyboard, configFile);
680 GET_INT_VALUE_2(propFile, keyboard, enableKeyboardQuirk);
681
682 GET_ENUM_VALUE_3(propFile, ports, Lpt, type, PrinterTypePair);
683 GET_ENUM_VALUE_3(propFile, ports, Lpt, emulation, PrinterEmulationPair);
684 GET_STR_VALUE_3(propFile, ports, Lpt, name);
685 GET_STR_VALUE_3(propFile, ports, Lpt, fileName);
686 GET_STR_VALUE_3(propFile, ports, Lpt, portName);
687 GET_ENUM_VALUE_3(propFile, ports, Com, type, ComTypePair);
688 GET_STR_VALUE_3(propFile, ports, Com, name);
689 GET_STR_VALUE_3(propFile, ports, Com, fileName);
690 GET_STR_VALUE_3(propFile, ports, Com, portName);
691
692 GET_INT_VALUE_3(propFile, ports, Eth, ethIndex);
693 GET_INT_VALUE_3(propFile, ports, Eth, disabled);
694 GET_STR_VALUE_3(propFile, ports, Eth, macAddress);
695
696
697 GET_INT_VALUE_2(propFile, cartridge, defaultType);
698
699 GET_ENUM_VALUE_2(propFile, diskdrive, cdromMethod, CdromDrvPair);
700 GET_INT_VALUE_2(propFile, diskdrive, cdromDrive);
701
702 GET_INT_VALUE_2(propFile, cassette, showCustomFiles);
703 GET_ENUM_VALUE_2(propFile, cassette, readOnly, BoolPair);
704 GET_ENUM_VALUE_2(propFile, cassette, rewindAfterInsert, BoolPair);
705
706 GET_ENUM_VALUE_2(propFile, nowind, enableDos2, BoolPair);
707 GET_ENUM_VALUE_2(propFile, nowind, enableOtherDiskRoms, BoolPair);
708 GET_ENUM_VALUE_2(propFile, nowind, enablePhantomDrives, BoolPair);
709 GET_ENUM_VALUE_2(propFile, nowind, ignoreBootFlag, BoolPair);
710 GET_INT_VALUE_2(propFile, nowind, partitionNumber);
711
712 iniFileClose(propFile);
713
714 #ifndef NO_FILE_HISTORY
715 histFile = iniFileOpen(histFilename);
716
717 GET_STR_VALUE_2(histFile, cartridge, defDir);
718 GET_STR_VALUE_2(histFile, cartridge, defDirSEGA);
719 GET_STR_VALUE_2(histFile, cartridge, defDirCOLECO);
720 GET_STR_VALUE_2(histFile, cartridge, defDirSVI);
721 GET_INT_VALUE_2(histFile, cartridge, autoReset);
722 GET_INT_VALUE_2(histFile, cartridge, quickStartDrive);
723
724 GET_STR_VALUE_2(histFile, diskdrive, defDir);
725 GET_STR_VALUE_2(histFile, diskdrive, defHdDir);
726 GET_INT_VALUE_2(histFile, diskdrive, autostartA);
727 GET_INT_VALUE_2(histFile, diskdrive, quickStartDrive);
728
729 GET_STR_VALUE_2(histFile, cassette, defDir);
730
731 for (i = 0; i < PROP_MAX_CARTS; i++) {
732 GET_STR_VALUE_2i1(histFile, media, carts, i, fileName);
733 GET_STR_VALUE_2i1(histFile, media, carts, i, fileNameInZip);
734 GET_STR_VALUE_2i1(histFile, media, carts, i, directory);
735 GET_INT_VALUE_2i1(histFile, media, carts, i, extensionFilter);
736 GET_INT_VALUE_2i1(histFile, media, carts, i, type);
737 }
738
739 for (i = 0; i < PROP_MAX_DISKS; i++) {
740 GET_STR_VALUE_2i1(histFile, media, disks, i, fileName);
741 GET_STR_VALUE_2i1(histFile, media, disks, i, fileNameInZip);
742 GET_STR_VALUE_2i1(histFile, media, disks, i, directory);
743 GET_INT_VALUE_2i1(histFile, media, disks, i, extensionFilter);
744 GET_INT_VALUE_2i1(histFile, media, disks, i, type);
745 }
746
747 for (i = 0; i < PROP_MAX_TAPES; i++) {
748 GET_STR_VALUE_2i1(histFile, media, tapes, i, fileName);
749 GET_STR_VALUE_2i1(histFile, media, tapes, i, fileNameInZip);
750 GET_STR_VALUE_2i1(histFile, media, tapes, i, directory);
751 GET_INT_VALUE_2i1(histFile, media, tapes, i, extensionFilter);
752 GET_INT_VALUE_2i1(histFile, media, tapes, i, type);
753 }
754
755 for (i = 0; i < MAX_HISTORY; i++) {
756 GET_STR_VALUE_2i(histFile, filehistory, cartridge[0], i);
757 GET_INT_VALUE_2i(histFile, filehistory, cartridgeType[0], i);
758 GET_STR_VALUE_2i(histFile, filehistory, cartridge[1], i);
759 GET_INT_VALUE_2i(histFile, filehistory, cartridgeType[1], i);
760 GET_STR_VALUE_2i(histFile, filehistory, diskdrive[0], i);
761 GET_STR_VALUE_2i(histFile, filehistory, diskdrive[1], i);
762 GET_STR_VALUE_2i(histFile, filehistory, cassette[0], i);
763 }
764
765 GET_STR_VALUE_2(histFile, filehistory, quicksave);
766 GET_STR_VALUE_2(histFile, filehistory, videocap);
767 GET_INT_VALUE_2(histFile, filehistory, count);
768
769 for (i = 0; i < DLG_MAX_ID; i++) {
770 GET_INT_VALUE_2i1(histFile, settings, windowPos, i, left);
771 GET_INT_VALUE_2i1(histFile, settings, windowPos, i, top);
772 GET_INT_VALUE_2i1(histFile, settings, windowPos, i, width);
773 GET_INT_VALUE_2i1(histFile, settings, windowPos, i, height);
774 }
775
776 iniFileClose(histFile);
777 #endif
778 }
779
propSave(Properties * properties)780 void propSave(Properties* properties)
781 {
782 #ifndef NO_FILE_HISTORY
783 IniFile *histFile;
784 #endif
785 IniFile *propFile;
786 int i;
787
788 propFile = iniFileOpen(settFilename);
789
790 strcpy(properties->settings.language, langToName(properties->language, 0));
791 SET_STR_VALUE_2(propFile, settings, language);
792
793 SET_ENUM_VALUE_2(propFile, settings, disableScreensaver, YesNoPair);
794 SET_ENUM_VALUE_2(propFile, settings, showStatePreview, YesNoPair);
795 SET_ENUM_VALUE_2(propFile, settings, usePngScreenshots, YesNoPair);
796 SET_ENUM_VALUE_2(propFile, settings, portable, YesNoPair);
797 if (appConfigGetString("singletheme", NULL) == NULL) {
798 SET_STR_VALUE_2(propFile, settings, themeName);
799 }
800
801 SET_ENUM_VALUE_2(propFile, emulation, ejectMediaOnExit, YesNoPair);
802 SET_ENUM_VALUE_2(propFile, emulation, registerFileTypes, YesNoPair);
803 SET_ENUM_VALUE_2(propFile, emulation, disableWinKeys, YesNoPair);
804 SET_STR_VALUE_2(propFile, emulation, statsDefDir);
805 if (appConfigGetString("singlemachine", NULL) == NULL) {
806 SET_STR_VALUE_2(propFile, emulation, machineName);
807 }
808 SET_STR_VALUE_2(propFile, emulation, shortcutProfile);
809 SET_INT_VALUE_2(propFile, emulation, speed);
810 SET_ENUM_VALUE_2(propFile, emulation, syncMethod, EmuSyncPair);
811 SET_ENUM_VALUE_2(propFile, emulation, syncMethodGdi, EmuSyncPair);
812 SET_ENUM_VALUE_2(propFile, emulation, syncMethodD3D, EmuSyncPair);
813 SET_ENUM_VALUE_2(propFile, emulation, syncMethodDirectX, EmuSyncPair);
814 SET_ENUM_VALUE_2(propFile, emulation, vdpSyncMode, VdpSyncPair);
815 SET_ENUM_VALUE_2(propFile, emulation, enableFdcTiming, YesNoPair);
816 SET_ENUM_VALUE_2(propFile, emulation, noSpriteLimits, YesNoPair);
817 SET_ENUM_VALUE_2(propFile, emulation, frontSwitch, OnOffPair);
818 SET_ENUM_VALUE_2(propFile, emulation, pauseSwitch, OnOffPair);
819 SET_ENUM_VALUE_2(propFile, emulation, audioSwitch, OnOffPair);
820 SET_ENUM_VALUE_2(propFile, emulation, priorityBoost, YesNoPair);
821 SET_ENUM_VALUE_2(propFile, emulation, reverseEnable, BoolPair);
822 SET_INT_VALUE_2(propFile, emulation, reverseMaxTime);
823
824 SET_ENUM_VALUE_2(propFile, video, monitorColor, MonitorColorPair);
825 SET_ENUM_VALUE_2(propFile, video, monitorType, MonitorTypePair);
826 SET_INT_VALUE_2(propFile, video, contrast);
827 SET_INT_VALUE_2(propFile, video, brightness);
828 SET_INT_VALUE_2(propFile, video, saturation);
829 SET_INT_VALUE_2(propFile, video, gamma);
830 SET_ENUM_VALUE_2(propFile, video, scanlinesEnable, YesNoPair);
831 SET_INT_VALUE_2(propFile, video, scanlinesPct);
832 SET_ENUM_VALUE_2(propFile, video, colorSaturationEnable, YesNoPair);
833 SET_INT_VALUE_2(propFile, video, colorSaturationWidth);
834 SET_ENUM_VALUE_2(propFile, video, deInterlace, OnOffPair);
835 SET_ENUM_VALUE_2(propFile, video, blendFrames, YesNoPair);
836 SET_ENUM_VALUE_2(propFile, video, detectActiveMonitor, YesNoPair);
837 SET_ENUM_VALUE_2(propFile, video, horizontalStretch, YesNoPair);
838 SET_ENUM_VALUE_2(propFile, video, verticalStretch, YesNoPair);
839 SET_INT_VALUE_2(propFile, video, frameSkip);
840 if (properties->video.windowSizeChanged) {
841 SET_ENUM_VALUE_2(propFile, video, windowSize, WindowSizePair);
842 }
843 else {
844 int temp=properties->video.windowSize;
845 properties->video.windowSize=properties->video.windowSizeInitial;
846 SET_ENUM_VALUE_2(propFile, video, windowSize, WindowSizePair);
847 properties->video.windowSize=temp;
848 }
849 SET_INT_VALUE_2(propFile, video, windowX);
850 SET_INT_VALUE_2(propFile, video, windowY);
851 SET_INT_VALUE_3(propFile, video, fullscreen, width);
852 SET_INT_VALUE_3(propFile, video, fullscreen, height);
853 SET_INT_VALUE_3(propFile, video, fullscreen, bitDepth);
854 SET_ENUM_VALUE_2(propFile, video, maximizeIsFullscreen, YesNoPair);
855 SET_ENUM_VALUE_2(propFile, video, driver, VideoDriverPair);
856 SET_INT_VALUE_2(propFile, video, captureFps);
857
858 SET_INT_VALUE_2(propFile, video, captureSize);
859
860 SET_ENUM_VALUE_3(propFile, video, d3d, linearFiltering, BoolPair);
861 SET_ENUM_VALUE_3(propFile, video, d3d, extendBorderColor, BoolPair);
862 SET_ENUM_VALUE_3(propFile, video, d3d, forceHighRes, BoolPair);
863 SET_INT_VALUE_3(propFile, video, d3d, aspectRatioType);
864 SET_INT_VALUE_3(propFile, video, d3d, cropType);
865
866 SET_INT_VALUE_3(propFile, video, d3d, cropLeft);
867 SET_INT_VALUE_3(propFile, video, d3d, cropRight);
868 SET_INT_VALUE_3(propFile, video, d3d, cropTop);
869 SET_INT_VALUE_3(propFile, video, d3d, cropBottom);
870
871 SET_INT_VALUE_2(propFile, videoIn, disabled);
872 SET_INT_VALUE_2(propFile, videoIn, inputIndex);
873 SET_STR_VALUE_2(propFile, videoIn, inputName);
874
875 SET_ENUM_VALUE_2(propFile, sound, driver, SoundDriverPair);
876 SET_INT_VALUE_2(propFile, sound, bufSize);
877 SET_ENUM_VALUE_2(propFile, sound, stabilizeDSoundTiming, YesNoPair);
878 SET_ENUM_VALUE_2(propFile, sound, stereo, YesNoPair);
879 SET_INT_VALUE_2(propFile, sound, masterVolume);
880 SET_ENUM_VALUE_2(propFile, sound, masterEnable, YesNoPair);
881
882 SET_ENUM_VALUE_3(propFile, sound, chip, enableYM2413, YesNoPair);
883 SET_ENUM_VALUE_3(propFile, sound, chip, enableY8950, YesNoPair);
884 SET_ENUM_VALUE_3(propFile, sound, chip, enableMoonsound, YesNoPair);
885 SET_INT_VALUE_3(propFile, sound, chip, moonsoundSRAMSize);
886 // SET_INT_VALUE_3(sound, chip, ym2413Oversampling);
887 // SET_INT_VALUE_3(sound, chip, y8950Oversampling);
888 // SET_INT_VALUE_3(sound, chip, moonsoundOversampling);
889 SET_ENUM_VALUE_3(propFile, sound, YkIn, type, MidiTypePair);
890 SET_STR_VALUE_3(propFile, sound, YkIn, name);
891 // SET_STR_VALUE_3(sound, YkIn, fileName);
892 // SET_STR_VALUE_3(sound, YkIn, desc);
893 SET_INT_VALUE_3(propFile, sound, YkIn, channel);
894 SET_ENUM_VALUE_3(propFile, sound, MidiIn, type, MidiTypePair);
895 SET_STR_VALUE_3(propFile, sound, MidiIn, name);
896 // SET_STR_VALUE_3(sound, MidiIn, fileName);
897 // SET_STR_VALUE_3(sound, MidiIn, desc);
898 SET_ENUM_VALUE_3(propFile, sound, MidiOut, type, MidiTypePair);
899 SET_STR_VALUE_3(propFile, sound, MidiOut, name);
900 // SET_STR_VALUE_3(sound, MidiOut, fileName);
901 // SET_STR_VALUE_3(sound, MidiOut, desc);
902 SET_ENUM_VALUE_3(propFile, sound, MidiOut, mt32ToGm, YesNoPair);
903 SET_ENUM_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_PSG, enable, YesNoPair);
904 SET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_PSG, pan);
905 SET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_PSG, volume);
906 SET_ENUM_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_SCC, enable, YesNoPair);
907 SET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_SCC, pan);
908 SET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_SCC, volume);
909 SET_ENUM_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_MSXMUSIC, enable, YesNoPair);
910 SET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_MSXMUSIC, pan);
911 SET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_MSXMUSIC, volume);
912 SET_ENUM_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_MSXAUDIO, enable, YesNoPair);
913 SET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_MSXAUDIO, pan);
914 SET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_MSXAUDIO, volume);
915 SET_ENUM_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_KEYBOARD, enable, YesNoPair);
916 SET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_KEYBOARD, pan);
917 SET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_KEYBOARD, volume);
918 SET_ENUM_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_MOONSOUND, enable, YesNoPair);
919 SET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_MOONSOUND, pan);
920 SET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_MOONSOUND, volume);
921 SET_ENUM_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_YAMAHA_SFG, enable, YesNoPair);
922 SET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_YAMAHA_SFG, pan);
923 SET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_YAMAHA_SFG, volume);
924 SET_ENUM_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_PCM, enable, YesNoPair);
925 SET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_PCM, pan);
926 SET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_PCM, volume);
927 SET_ENUM_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_IO, enable, YesNoPair);
928 SET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_IO, pan);
929 SET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_IO, volume);
930 SET_ENUM_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_MIDI, enable, YesNoPair);
931 SET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_MIDI, pan);
932 SET_INT_VALUE_2s1(propFile, sound, mixerChannel, MIXER_CHANNEL_MIDI, volume);
933
934 SET_ENUM_VALUE_2(propFile, joystick, POV0isAxes, YesNoPair);
935
936 strcpy(properties->joy1.type, joystickPortTypeToName(0, 0));
937 SET_STR_VALUE_2(propFile, joy1, type);
938 SET_ENUM_VALUE_2(propFile, joy1, autofire, OnOffPair);
939
940 strcpy(properties->joy2.type, joystickPortTypeToName(1, 0));
941 SET_STR_VALUE_2(propFile, joy2, type);
942 SET_ENUM_VALUE_2(propFile, joy2, autofire, OnOffPair);
943
944 SET_STR_VALUE_2(propFile, keyboard, configFile);
945 SET_INT_VALUE_2(propFile, keyboard, enableKeyboardQuirk);
946
947 SET_ENUM_VALUE_3(propFile, ports, Lpt, type, PrinterTypePair);
948 SET_ENUM_VALUE_3(propFile, ports, Lpt, emulation, PrinterEmulationPair);
949 SET_STR_VALUE_3(propFile, ports, Lpt, name);
950 SET_STR_VALUE_3(propFile, ports, Lpt, fileName);
951 SET_STR_VALUE_3(propFile, ports, Lpt, portName);
952 SET_ENUM_VALUE_3(propFile, ports, Com, type, ComTypePair);
953 SET_STR_VALUE_3(propFile, ports, Com, name);
954 SET_STR_VALUE_3(propFile, ports, Com, fileName);
955 SET_STR_VALUE_3(propFile, ports, Com, portName);
956
957 SET_INT_VALUE_3(propFile, ports, Eth, ethIndex);
958 SET_INT_VALUE_3(propFile, ports, Eth, disabled);
959 SET_STR_VALUE_3(propFile, ports, Eth, macAddress);
960
961 SET_INT_VALUE_2(propFile, cartridge, defaultType);
962
963 SET_ENUM_VALUE_2(propFile, diskdrive, cdromMethod, CdromDrvPair);
964 SET_INT_VALUE_2(propFile, diskdrive, cdromDrive);
965
966 SET_INT_VALUE_2(propFile, cassette, showCustomFiles);
967 SET_ENUM_VALUE_2(propFile, cassette, readOnly, YesNoPair);
968 SET_ENUM_VALUE_2(propFile, cassette, rewindAfterInsert, YesNoPair);
969
970 SET_ENUM_VALUE_2(propFile, nowind, enableDos2, YesNoPair);
971 SET_ENUM_VALUE_2(propFile, nowind, enableOtherDiskRoms, BoolPair);
972 SET_ENUM_VALUE_2(propFile, nowind, enablePhantomDrives, BoolPair);
973 SET_ENUM_VALUE_2(propFile, nowind, ignoreBootFlag, BoolPair);
974 SET_INT_VALUE_2(propFile, nowind, partitionNumber);
975
976 iniFileClose(propFile);
977
978 #ifndef NO_FILE_HISTORY
979 histFile = iniFileOpen(histFilename);
980
981 SET_STR_VALUE_2(histFile, cartridge, defDir);
982 SET_STR_VALUE_2(histFile, cartridge, defDirSEGA);
983 SET_STR_VALUE_2(histFile, cartridge, defDirCOLECO);
984 SET_STR_VALUE_2(histFile, cartridge, defDirSVI);
985 SET_INT_VALUE_2(histFile, cartridge, autoReset);
986 SET_INT_VALUE_2(histFile, cartridge, quickStartDrive);
987
988 SET_STR_VALUE_2(histFile, diskdrive, defDir);
989 SET_STR_VALUE_2(histFile, diskdrive, defHdDir);
990 SET_INT_VALUE_2(histFile, diskdrive, autostartA);
991 SET_INT_VALUE_2(histFile, diskdrive, quickStartDrive);
992
993 SET_STR_VALUE_2(histFile, cassette, defDir);
994
995 for (i = 0; i < PROP_MAX_CARTS; i++) {
996 SET_STR_VALUE_2i1(histFile, media, carts, i, fileName);
997 SET_STR_VALUE_2i1(histFile, media, carts, i, fileNameInZip);
998 SET_STR_VALUE_2i1(histFile, media, carts, i, directory);
999 SET_INT_VALUE_2i1(histFile, media, carts, i, extensionFilter);
1000 SET_INT_VALUE_2i1(histFile, media, carts, i, type);
1001 }
1002
1003 for (i = 0; i < PROP_MAX_DISKS; i++) {
1004 SET_STR_VALUE_2i1(histFile, media, disks, i, fileName);
1005 SET_STR_VALUE_2i1(histFile, media, disks, i, fileNameInZip);
1006 SET_STR_VALUE_2i1(histFile, media, disks, i, directory);
1007 SET_INT_VALUE_2i1(histFile, media, disks, i, extensionFilter);
1008 SET_INT_VALUE_2i1(histFile, media, disks, i, type);
1009 }
1010
1011 for (i = 0; i < PROP_MAX_TAPES; i++) {
1012 SET_STR_VALUE_2i1(histFile, media, tapes, i, fileName);
1013 SET_STR_VALUE_2i1(histFile, media, tapes, i, fileNameInZip);
1014 SET_STR_VALUE_2i1(histFile, media, tapes, i, directory);
1015 SET_INT_VALUE_2i1(histFile, media, tapes, i, extensionFilter);
1016 SET_INT_VALUE_2i1(histFile, media, tapes, i, type);
1017 }
1018
1019 for (i = 0; i < MAX_HISTORY; i++) {
1020 SET_STR_VALUE_2i(histFile, filehistory, cartridge[0], i);
1021 SET_INT_VALUE_2i(histFile, filehistory, cartridgeType[0], i);
1022 SET_STR_VALUE_2i(histFile, filehistory, cartridge[1], i);
1023 SET_INT_VALUE_2i(histFile, filehistory, cartridgeType[1], i);
1024 SET_STR_VALUE_2i(histFile, filehistory, diskdrive[0], i);
1025 SET_STR_VALUE_2i(histFile, filehistory, diskdrive[1], i);
1026 SET_STR_VALUE_2i(histFile, filehistory, cassette[0], i);
1027 }
1028
1029 SET_STR_VALUE_2(histFile, filehistory, quicksave);
1030 SET_STR_VALUE_2(histFile, filehistory, videocap);
1031 SET_INT_VALUE_2(histFile, filehistory, count);
1032
1033 for (i = 0; i < DLG_MAX_ID; i++) {
1034 SET_INT_VALUE_2i1(histFile, settings, windowPos, i, left);
1035 SET_INT_VALUE_2i1(histFile, settings, windowPos, i, top);
1036 SET_INT_VALUE_2i1(histFile, settings, windowPos, i, width);
1037 SET_INT_VALUE_2i1(histFile, settings, windowPos, i, height);
1038 }
1039
1040 iniFileClose(histFile);
1041 #endif
1042 }
1043
1044 static Properties* globalProperties = NULL;
1045
propGetGlobalProperties()1046 Properties* propGetGlobalProperties()
1047 {
1048 return globalProperties;
1049 }
1050
propertiesSetDirectory(const char * defDir,const char * altDir)1051 void propertiesSetDirectory(const char* defDir, const char* altDir)
1052 {
1053 FILE* f;
1054
1055 sprintf(settFilename, "bluemsx.ini", defDir);
1056 f = fopen(settFilename, "r");
1057 if (f != NULL) {
1058 fclose(f);
1059 }
1060 else {
1061 sprintf(settFilename, "%s/bluemsx.ini", altDir);
1062 }
1063
1064 sprintf(histFilename, "bluemsx_history.ini", defDir);
1065 f = fopen(histFilename, "r");
1066 if (f != NULL) {
1067 fclose(f);
1068 }
1069 else {
1070 sprintf(histFilename, "%s/bluemsx_history.ini", altDir);
1071 }
1072 }
1073
1074
propCreate(int useDefault,int langType,PropKeyboardLanguage kbdLang,int syncMode,const char * themeName)1075 Properties* propCreate(int useDefault, int langType, PropKeyboardLanguage kbdLang, int syncMode, const char* themeName)
1076 {
1077 Properties* properties;
1078
1079 properties = malloc(sizeof(Properties));
1080
1081 if (globalProperties == NULL) {
1082 globalProperties = properties;
1083 }
1084
1085 propInitDefaults(properties, langType, kbdLang, syncMode, themeName);
1086
1087 if (!useDefault) {
1088 propLoad(properties);
1089 }
1090 #if !defined(WII) && !defined(__LIBRETRO__)
1091 // Verify machine name
1092 {
1093 int foundMachine = 0;
1094 ArrayListIterator *iterator;
1095 ArrayList *machineList;
1096
1097 machineList = arrayListCreate();
1098 machineFillAvailable(machineList, 1);
1099
1100 iterator = arrayListCreateIterator(machineList);
1101 while (arrayListCanIterate(iterator))
1102 {
1103 char *machineName = (char *)arrayListIterate(iterator);
1104 if (strcmp(machineName, properties->emulation.machineName) == 0)
1105 {
1106 foundMachine = 1;
1107 break;
1108 }
1109 }
1110 arrayListDestroyIterator(iterator);
1111
1112 if (!foundMachine)
1113 {
1114 if (arrayListGetSize(machineList) > 0)
1115 strcpy(properties->emulation.machineName, (char *)arrayListGetObject(machineList, 0));
1116
1117 iterator = arrayListCreateIterator(machineList);
1118 while (arrayListCanIterate(iterator))
1119 {
1120 char *machineName = (char *)arrayListIterate(iterator);
1121 if (strcmp(machineName, "MSX2") == 0)
1122 {
1123 strcpy(properties->emulation.machineName, machineName);
1124 foundMachine = 1;
1125 }
1126
1127 if (!foundMachine && strncmp(machineName, "MSX2", 4))
1128 {
1129 strcpy(properties->emulation.machineName, machineName);
1130 foundMachine = 1;
1131 }
1132 }
1133 arrayListDestroyIterator(iterator);
1134 }
1135
1136 arrayListDestroy(machineList);
1137 }
1138 #endif
1139 return properties;
1140 }
1141
1142
propDestroy(Properties * properties)1143 void propDestroy(Properties* properties) {
1144 propSave(properties);
1145
1146 free(properties);
1147 }
1148
1149
1150